feat: aigc 组件对接字段

This commit is contained in:
2026-08-07 17:00:36 +08:00
parent 7cfdd27bbc
commit 581734cedc
2 changed files with 22 additions and 66 deletions

View File

@@ -1,18 +1,7 @@
<template>
<view class="discovery-photo-tool-card" hover-class="is-pressed" hover-stay-time="80" @tap="handleSelect">
<view class="discovery-photo-tool-card" hover-class="is-pressed" hover-stay-time="80" @tap="handleJump">
<view class="photo-visual w-[88px] min-w-0">
<view class="camera-illustration">
<view class="camera-top" />
<view class="camera-flash" />
<view class="camera-body">
<view class="camera-lens">
<view class="camera-lens-inner" />
</view>
<view class="camera-dot is-large" />
<view class="camera-dot is-small" />
</view>
</view>
<text class="photo-badge w-[calc(100%_-_18px)] truncate">{{ normalizedItem.badge }}</text>
<image v-if="normalizedItem.coverUrl" class="block h-full w-full" :src="normalizedItem.coverUrl" mode="aspectFill" />
</view>
<view class="photo-content min-w-0 flex-1">
@@ -20,13 +9,12 @@
<text class="photo-subtitle block w-full truncate">{{ normalizedItem.subTitle }}</text>
<view class="photo-options">
<view v-for="(option, index) in normalizedItem.options" :key="getOptionKey(option, index)" class="photo-option min-w-0 flex-1"
hover-class="is-option-pressed" hover-stay-time="80" @tap.stop="handleOptionSelect(option, index)">
<view v-for="(photo, index) in normalizedItem.options" :key="getPhotoKey(photo, index)" class="photo-option min-w-0 flex-1"
hover-class="is-option-pressed" hover-stay-time="80" @tap.stop="handleJump">
<view class="photo-option-thumb">
<image v-if="option.coverImage" class="photo-option-image" :src="option.coverImage" mode="aspectFill" />
<view v-else class="photo-option-placeholder" :class="`is-${index}`" />
<image v-if="photo?.photoUrl" class="photo-option-image" :src="photo.photoUrl" mode="aspectFill" />
</view>
<text class="photo-option-label block w-[76px] truncate">{{ option.label }}</text>
<text class="photo-option-label block w-[76px] truncate">{{ photo?.title }}</text>
</view>
</view>
</view>
@@ -35,20 +23,7 @@
<script setup>
import { computed } from "vue";
const DEFAULT_OPTIONS = [
{ id: "check-in", label: "景点打卡" },
{ id: "companion", label: "小七陪伴" },
{ id: "memory", label: "风格纪念" },
];
const DEFAULT_ITEM = {
id: "travel-photo",
title: "在卧龙潭和小七合影",
subTitle: "生成你在卧龙潭的专属纪念照",
badge: "旅行纪念照",
options: DEFAULT_OPTIONS,
};
import { navigateTo } from "@/router";
const props = defineProps({
item: {
@@ -57,37 +32,27 @@ const props = defineProps({
},
});
const emit = defineEmits(["didSelectItem", "didSelectOption"]);
const normalizeOption = (option, index) => ({
raw: option,
id: option.id ?? option.tabContentId ?? index,
label: option.label || option.title || DEFAULT_OPTIONS[index]?.label || "",
coverImage: option.coverImage || option.image || option.url || "",
});
const normalizedItem = computed(() => {
const source = Object.keys(props.item).length > 0 ? props.item : DEFAULT_ITEM;
const options = source.options || source.children || source.items || DEFAULT_OPTIONS;
const resource = props.item?.resource;
const summary = resource?.summary;
const componentParams = resource?.payload?.componentParams;
return {
raw: source,
id: source.id ?? source.tabContentId ?? DEFAULT_ITEM.id,
title: source.title || DEFAULT_ITEM.title,
subTitle: source.subTitle || source.desc || DEFAULT_ITEM.subTitle,
badge: source.badge || source.tag || DEFAULT_ITEM.badge,
options: options.slice(0, 3).map(normalizeOption),
title: summary?.title,
subTitle: summary?.subtitle,
coverUrl: summary?.coverUrl,
jumpUrl: componentParams?.jumpUrl,
options: Array.isArray(componentParams?.photoList)
? componentParams.photoList.slice(0, 3)
: [],
};
});
const getOptionKey = (option, index) => option.id ?? option.label ?? index;
const getPhotoKey = (photo, index) => photo?.photoUrl ?? photo?.title ?? index;
const handleSelect = () => {
emit("didSelectItem", normalizedItem.value.raw);
};
const handleOptionSelect = (option, index) => {
emit("didSelectOption", option.raw, normalizedItem.value.raw, index);
const handleJump = () => {
if (!normalizedItem.value.jumpUrl) return;
navigateTo(normalizedItem.value.jumpUrl);
};
</script>

View File

@@ -27,8 +27,7 @@
<CardSwiper v-if="discoveryCards.length > 0" :list="discoveryCards" @didSelectItem="handleCardClick" />
<ExploreCards v-if="exploreCards.length > 0" :list="exploreCards" @didSelectItem="handleCardClick" />
<DiscoveryPhotoToolCard v-if="discoveryPhotoToolData" :item="discoveryPhotoToolData"
@didSelectItem="handleToolCardClick" @didSelectOption="handleToolOptionClick" />
<DiscoveryPhotoToolCard v-if="discoveryPhotoToolData" :item="discoveryPhotoToolData" />
<DiscoveryAudioToolCard v-if="discoveryAudioToolData" :item="discoveryAudioToolData"
:active="props.active" @didSelectItem="handleToolCardClick" />
<DiscoveryGuideMapToolCard v-if="discoveryGuideMapToolData" :item="discoveryGuideMapToolData" />
@@ -250,14 +249,6 @@ const handleToolCardClick = (item) => {
}
};
const handleToolOptionClick = (option, parentItem) => {
if (option?.jumpType !== undefined) {
handleClick(option);
} else {
handleToolCardClick(parentItem);
}
};
const handleClick = async (item) => {
console.log(`执行点击事件: ${item.jumpType},参数:${JSON.stringify(item.jumpContent)}`);
/// 商品