feat: aigc 组件
This commit is contained in:
@@ -44,6 +44,7 @@ const requiredStrictRenderingSnippets = [
|
|||||||
"LONG_TEXT_KEYS.sceneImage",
|
"LONG_TEXT_KEYS.sceneImage",
|
||||||
"LONG_TEXT_KEYS.commodityList",
|
"LONG_TEXT_KEYS.commodityList",
|
||||||
"LONG_TEXT_KEYS.photoList",
|
"LONG_TEXT_KEYS.photoList",
|
||||||
|
"LONG_TEXT_KEYS.aigcComponet",
|
||||||
"commodity.commodity_id",
|
"commodity.commodity_id",
|
||||||
"commodity.commodity_name",
|
"commodity.commodity_name",
|
||||||
"commodity.commodity_price",
|
"commodity.commodity_price",
|
||||||
@@ -54,6 +55,13 @@ const requiredStrictRenderingSnippets = [
|
|||||||
"photo.photo_name",
|
"photo.photo_name",
|
||||||
"photo.photo_description",
|
"photo.photo_description",
|
||||||
"photo.photo_url",
|
"photo.photo_url",
|
||||||
|
"aigc.background",
|
||||||
|
"aigc.title",
|
||||||
|
"aigc.description",
|
||||||
|
"aigc.jumpUrl",
|
||||||
|
"jumpAigcClick",
|
||||||
|
"getAccessToken",
|
||||||
|
"navigateTo",
|
||||||
"content-body-list-marker",
|
"content-body-list-marker",
|
||||||
"entry.value.length > 1",
|
"entry.value.length > 1",
|
||||||
"formatListMarker(index)",
|
"formatListMarker(index)",
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ const expectedNewKeys = {
|
|||||||
phoneSectionTitle: "phone_section_title",
|
phoneSectionTitle: "phone_section_title",
|
||||||
phoneSectionItems: "phone_section_items",
|
phoneSectionItems: "phone_section_items",
|
||||||
photoList: "photo_list",
|
photoList: "photo_list",
|
||||||
|
aigcComponet: "aigc_componet",
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const [keyName, keyValue] of Object.entries(expectedNewKeys)) {
|
for (const [keyName, keyValue] of Object.entries(expectedNewKeys)) {
|
||||||
|
|||||||
@@ -99,6 +99,35 @@
|
|||||||
</view>
|
</view>
|
||||||
</template>
|
</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-else>
|
||||||
<template v-for="entry in renderFieldEntries" :key="entry.key">
|
<template v-for="entry in renderFieldEntries" :key="entry.key">
|
||||||
<view v-if="entry.type === 'text'" class="content-body-text">
|
<view v-if="entry.type === 'text'" class="content-body-text">
|
||||||
@@ -131,6 +160,8 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { computed, defineProps, ref } from "vue";
|
import { computed, defineProps, ref } from "vue";
|
||||||
import { SEND_MESSAGE_CONTENT_TEXT } from "@/constant/constant";
|
import { SEND_MESSAGE_CONTENT_TEXT } from "@/constant/constant";
|
||||||
|
import { getAccessToken } from "@/constant/token";
|
||||||
|
import { navigateTo } from "@/router";
|
||||||
import { getRandomTagToneStyle } from "@/utils/tagTone";
|
import { getRandomTagToneStyle } from "@/utils/tagTone";
|
||||||
import {
|
import {
|
||||||
LONG_TEXT_KEYS,
|
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 isQuestionSuggestField = computed(() => props.fieldKey === LONG_TEXT_KEYS.questionSuggest);
|
||||||
const isCommodityListField = computed(() => props.fieldKey === LONG_TEXT_KEYS.commodityList);
|
const isCommodityListField = computed(() => props.fieldKey === LONG_TEXT_KEYS.commodityList);
|
||||||
const isPhotoListField = computed(() => props.fieldKey === LONG_TEXT_KEYS.photoList);
|
const isPhotoListField = computed(() => props.fieldKey === LONG_TEXT_KEYS.photoList);
|
||||||
|
const isAigcComponetField = computed(() => props.fieldKey === LONG_TEXT_KEYS.aigcComponet);
|
||||||
|
|
||||||
const displayValue = computed(() => sanitizeValue(props.value));
|
const displayValue = computed(() => sanitizeValue(props.value));
|
||||||
|
|
||||||
@@ -281,6 +313,17 @@ const photoItems = computed(() => {
|
|||||||
.filter((photo) => !!photo.photo_url);
|
.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(() => {
|
const shouldRenderContentImage = computed(() => {
|
||||||
return isContentImageField.value && !!contentImageUrl.value;
|
return isContentImageField.value && !!contentImageUrl.value;
|
||||||
});
|
});
|
||||||
@@ -301,6 +344,10 @@ const shouldRenderPhotoList = computed(() => {
|
|||||||
return isPhotoListField.value && photoItems.value.length > 0;
|
return isPhotoListField.value && photoItems.value.length > 0;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const shouldRenderAigcComponet = computed(() => {
|
||||||
|
return isAigcComponetField.value && hasDisplayValue(aigcComponetValue.value);
|
||||||
|
});
|
||||||
|
|
||||||
/// 其他字段走通用渲染逻辑
|
/// 其他字段走通用渲染逻辑
|
||||||
const renderFieldEntries = computed(() => {
|
const renderFieldEntries = computed(() => {
|
||||||
if (isIgnoredField.value || !hasDisplayValue(props.value)) return [];
|
if (isIgnoredField.value || !hasDisplayValue(props.value)) return [];
|
||||||
@@ -356,7 +403,8 @@ const shouldRenderField = computed(() => {
|
|||||||
shouldRenderSpotLocate.value ||
|
shouldRenderSpotLocate.value ||
|
||||||
shouldRenderQuestionSuggest.value ||
|
shouldRenderQuestionSuggest.value ||
|
||||||
shouldRenderCommodityList.value ||
|
shouldRenderCommodityList.value ||
|
||||||
shouldRenderPhotoList.value
|
shouldRenderPhotoList.value ||
|
||||||
|
shouldRenderAigcComponet.value
|
||||||
) {
|
) {
|
||||||
return true;
|
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) => {
|
const handlePreviewClick = (imageUrl, imageUrls) => {
|
||||||
uni.previewImage({
|
uni.previewImage({
|
||||||
current: imageUrl,
|
current: imageUrl,
|
||||||
|
|||||||
@@ -14,11 +14,11 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: 6px;
|
gap: 6px;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-body-image-bottom {
|
.content-body-image-bottom {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.content-body-image {
|
.content-body-image {
|
||||||
@@ -69,6 +69,11 @@
|
|||||||
border-top: 1px solid rgba(15, 23, 42, 0.06);
|
border-top: 1px solid rgba(15, 23, 42, 0.06);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.detail-action-zone-no-divider {
|
||||||
|
margin-top: 0;
|
||||||
|
border-top: none;
|
||||||
|
}
|
||||||
|
|
||||||
.detail-action-label {
|
.detail-action-label {
|
||||||
padding: 0 0 10px;
|
padding: 0 0 10px;
|
||||||
color: #94a3b8;
|
color: #94a3b8;
|
||||||
@@ -284,6 +289,52 @@
|
|||||||
text-align: center;
|
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 {
|
.detail-faq-wrap {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ export const LONG_TEXT_KEYS = {
|
|||||||
phoneSectionTitle: "phone_section_title",
|
phoneSectionTitle: "phone_section_title",
|
||||||
phoneSectionItems: "phone_section_items",
|
phoneSectionItems: "phone_section_items",
|
||||||
photoList: "photo_list",
|
photoList: "photo_list",
|
||||||
|
aigcComponet: "aigc_componet",
|
||||||
preparationSectionTitle: "preparation_section_title",
|
preparationSectionTitle: "preparation_section_title",
|
||||||
preparationSectionItems: "preparation_section_items",
|
preparationSectionItems: "preparation_section_items",
|
||||||
sectionSuggestionTitle: "section_suggestion_title",
|
sectionSuggestionTitle: "section_suggestion_title",
|
||||||
@@ -74,6 +75,7 @@ export const LONG_TEXT_FIELD_CONFIG = [
|
|||||||
{ key: LONG_TEXT_KEYS.phoneSectionTitle },
|
{ key: LONG_TEXT_KEYS.phoneSectionTitle },
|
||||||
{ key: LONG_TEXT_KEYS.phoneSectionItems },
|
{ key: LONG_TEXT_KEYS.phoneSectionItems },
|
||||||
{ key: LONG_TEXT_KEYS.photoList },
|
{ key: LONG_TEXT_KEYS.photoList },
|
||||||
|
{ key: LONG_TEXT_KEYS.aigcComponet },
|
||||||
{ key: LONG_TEXT_KEYS.preparationSectionTitle },
|
{ key: LONG_TEXT_KEYS.preparationSectionTitle },
|
||||||
{ key: LONG_TEXT_KEYS.preparationSectionItems },
|
{ key: LONG_TEXT_KEYS.preparationSectionItems },
|
||||||
{ key: LONG_TEXT_KEYS.sectionSuggestionTitle },
|
{ key: LONG_TEXT_KEYS.sectionSuggestionTitle },
|
||||||
|
|||||||
Reference in New Issue
Block a user