feat: aigc 组件

This commit is contained in:
2026-06-04 16:05:07 +08:00
parent 41feba7a8b
commit 7b514d7dcc
5 changed files with 118 additions and 3 deletions

View File

@@ -99,6 +99,35 @@
</view>
</template>
<template v-else-if="shouldRenderAigcComponet">
<view class="detail-action-zone detail-action-zone-no-divider">
<view v-if="aigcComponetValue.title" class="detail-action-label mt-12">
{{ aigcComponetValue.title }}
</view>
<view class="detail-action-card">
<view v-if="aigcComponetValue.background" class="aigc-cover">
<image class="aigc-image" :src="aigcComponetValue.background" mode="aspectFill" />
<view class="aigc-badge">AI 生成</view>
</view>
<view class="aigc-body">
<view v-if="aigcComponetValue.title" class="aigc-title">
{{ aigcComponetValue.title }}
</view>
<view v-if="aigcComponetValue.description" class="aigc-desc">
{{ aigcComponetValue.description }}
</view>
<button
v-if="aigcComponetValue.jumpUrl"
class="detail-solid-button aigc-button"
@click="jumpAigcClick(aigcComponetValue)"
>
生成我的合影
</button>
</view>
</view>
</view>
</template>
<template v-else>
<template v-for="entry in renderFieldEntries" :key="entry.key">
<view v-if="entry.type === 'text'" class="content-body-text">
@@ -131,6 +160,8 @@
<script setup>
import { computed, defineProps, ref } from "vue";
import { SEND_MESSAGE_CONTENT_TEXT } from "@/constant/constant";
import { getAccessToken } from "@/constant/token";
import { navigateTo } from "@/router";
import { getRandomTagToneStyle } from "@/utils/tagTone";
import {
LONG_TEXT_KEYS,
@@ -226,6 +257,7 @@ const isSpotLocateField = computed(() => props.fieldKey === LONG_TEXT_KEYS.spotL
const isQuestionSuggestField = computed(() => props.fieldKey === LONG_TEXT_KEYS.questionSuggest);
const isCommodityListField = computed(() => props.fieldKey === LONG_TEXT_KEYS.commodityList);
const isPhotoListField = computed(() => props.fieldKey === LONG_TEXT_KEYS.photoList);
const isAigcComponetField = computed(() => props.fieldKey === LONG_TEXT_KEYS.aigcComponet);
const displayValue = computed(() => sanitizeValue(props.value));
@@ -281,6 +313,17 @@ const photoItems = computed(() => {
.filter((photo) => !!photo.photo_url);
});
const aigcComponetValue = computed(() => {
const aigc = isObjectValue(displayValue.value) ? displayValue.value : {};
return {
background: toTrimmedText(aigc.background),
title: toTrimmedText(aigc.title),
description: toTrimmedText(aigc.description),
jumpUrl: toTrimmedText(aigc.jumpUrl),
};
});
const shouldRenderContentImage = computed(() => {
return isContentImageField.value && !!contentImageUrl.value;
});
@@ -301,6 +344,10 @@ const shouldRenderPhotoList = computed(() => {
return isPhotoListField.value && photoItems.value.length > 0;
});
const shouldRenderAigcComponet = computed(() => {
return isAigcComponetField.value && hasDisplayValue(aigcComponetValue.value);
});
/// 其他字段走通用渲染逻辑
const renderFieldEntries = computed(() => {
if (isIgnoredField.value || !hasDisplayValue(props.value)) return [];
@@ -356,7 +403,8 @@ const shouldRenderField = computed(() => {
shouldRenderSpotLocate.value ||
shouldRenderQuestionSuggest.value ||
shouldRenderCommodityList.value ||
shouldRenderPhotoList.value
shouldRenderPhotoList.value ||
shouldRenderAigcComponet.value
) {
return true;
}
@@ -402,6 +450,11 @@ const openCommodityDetail = (commodity) => {
});
};
const jumpAigcClick = (aigc) => {
if (!aigc.jumpUrl) return;
navigateTo(aigc.jumpUrl, { token: getAccessToken() });
};
const handlePreviewClick = (imageUrl, imageUrls) => {
uni.previewImage({
current: imageUrl,

View File

@@ -14,11 +14,11 @@
display: flex;
flex-direction: column;
gap: 6px;
margin-bottom: 8px;
margin-bottom: 4px;
}
.content-body-image-bottom {
margin-bottom: 8px;
margin-bottom: 4px;
}
.content-body-image {
@@ -69,6 +69,11 @@
border-top: 1px solid rgba(15, 23, 42, 0.06);
}
.detail-action-zone-no-divider {
margin-top: 0;
border-top: none;
}
.detail-action-label {
padding: 0 0 10px;
color: #94a3b8;
@@ -284,6 +289,52 @@
text-align: center;
}
.aigc-image {
width: 100%;
height: 160px;
background: #f1f5f9;
}
.aigc-cover {
position: relative;
}
.aigc-badge {
position: absolute;
top: 10px;
left: 10px;
padding: 4px 10px;
border-radius: 10px;
color: #fff;
background: linear-gradient(135deg, #8b5cf6, #6366f1);
box-shadow: 0 2px 8px rgba(99, 102, 241, 0.35);
font-size: 10px;
font-weight: 900;
}
.aigc-body {
padding: 12px 14px 14px;
}
.aigc-title {
color: #1e293b;
font-size: 15px;
font-weight: 900;
line-height: 22px;
}
.aigc-desc {
margin: 5px 0 12px;
color: #64748b;
font-size: 11.5px;
font-weight: 700;
line-height: 18px;
}
.aigc-button {
background: linear-gradient(135deg, #8b5cf6, #6366f1);
}
.detail-faq-wrap {
margin: 0;
}

View File

@@ -13,6 +13,7 @@ export const LONG_TEXT_KEYS = {
phoneSectionTitle: "phone_section_title",
phoneSectionItems: "phone_section_items",
photoList: "photo_list",
aigcComponet: "aigc_componet",
preparationSectionTitle: "preparation_section_title",
preparationSectionItems: "preparation_section_items",
sectionSuggestionTitle: "section_suggestion_title",
@@ -74,6 +75,7 @@ export const LONG_TEXT_FIELD_CONFIG = [
{ key: LONG_TEXT_KEYS.phoneSectionTitle },
{ key: LONG_TEXT_KEYS.phoneSectionItems },
{ key: LONG_TEXT_KEYS.photoList },
{ key: LONG_TEXT_KEYS.aigcComponet },
{ key: LONG_TEXT_KEYS.preparationSectionTitle },
{ key: LONG_TEXT_KEYS.preparationSectionItems },
{ key: LONG_TEXT_KEYS.sectionSuggestionTitle },