feat: markdown 渲染

This commit is contained in:
2026-06-04 16:45:21 +08:00
parent 7b514d7dcc
commit c9b55917ce
3 changed files with 38 additions and 42 deletions

View File

@@ -130,9 +130,11 @@
<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"> <ChatMarkdown
{{ entry.value }} v-if="entry.type === 'text'"
</view> class="content-body-markdown"
:text="entry.value"
/>
<view v-else-if="entry.type === 'image'" class="content-body-image-card"> <view v-else-if="entry.type === 'image'" class="content-body-image-card">
<image class="content-body-image" :src="entry.value.image_id" mode="widthFix" <image class="content-body-image" :src="entry.value.image_id" mode="widthFix"
@@ -144,11 +146,14 @@
<view v-else-if="entry.type === 'list'" class="content-body-list-card" :style="contentBodyListCardStyle"> <view v-else-if="entry.type === 'list'" class="content-body-list-card" :style="contentBodyListCardStyle">
<view v-for="(item, index) in entry.value" :key="index" class="content-body-list-item"> <view v-for="(item, index) in entry.value" :key="index" class="content-body-list-item">
<view v-if="entry.value.length > 1" class="content-body-list-marker" :style="contentBodyListTextStyle"> <view class="content-body-list-text">
{{ formatListMarker(index) }} <ChatMarkdown
</view> class="content-body-markdown"
<view class="content-body-list-text" :style="contentBodyListTextStyle"> :text="formatLeafValue(item)"
{{ formatLeafValue(item) }} :theme-color="contentBodyMarkdownColor"
:font-color="contentBodyMarkdownColor"
:font-sub-color="contentBodyMarkdownColor"
/>
</view> </view>
</view> </view>
</view> </view>
@@ -163,6 +168,7 @@ import { SEND_MESSAGE_CONTENT_TEXT } from "@/constant/constant";
import { getAccessToken } from "@/constant/token"; import { getAccessToken } from "@/constant/token";
import { navigateTo } from "@/router"; import { navigateTo } from "@/router";
import { getRandomTagToneStyle } from "@/utils/tagTone"; import { getRandomTagToneStyle } from "@/utils/tagTone";
import ChatMarkdown from "../ChatMarkdown/index.vue";
import { import {
LONG_TEXT_KEYS, LONG_TEXT_KEYS,
formatLongTextDisplayValue, formatLongTextDisplayValue,
@@ -186,9 +192,7 @@ const contentBodyListCardStyle = computed(() => ({
borderLeft: contentBodyListToneStyle.value.border, borderLeft: contentBodyListToneStyle.value.border,
background: contentBodyListToneStyle.value.background, background: contentBodyListToneStyle.value.background,
})); }));
const contentBodyListTextStyle = computed(() => ({ const contentBodyMarkdownColor = computed(() => contentBodyListToneStyle.value.color);
color: contentBodyListToneStyle.value.color,
}));
const IGNORED_FIELD_KEYS = ["container_type", "content", "components"]; const IGNORED_FIELD_KEYS = ["container_type", "content", "components"];
@@ -211,17 +215,6 @@ const formatLeafValue = (value) => {
return formatLongTextDisplayValue(value, IGNORED_FIELD_KEYS); return formatLongTextDisplayValue(value, IGNORED_FIELD_KEYS);
}; };
const LIST_MARKERS = [
"", "", "", "", "",
"", "", "", "", "",
"", "", "", "", "",
"", "", "", "", "",
];
const formatListMarker = (index) => {
return LIST_MARKERS[index] || `${index + 1}.`;
};
const toTrimmedText = (value) => { const toTrimmedText = (value) => {
if (value === undefined || value === null) return ""; if (value === undefined || value === null) return "";
return String(value).trim(); return String(value).trim();

View File

@@ -3,11 +3,8 @@
flex-direction: column; flex-direction: column;
} }
.content-body-text { .content-body-markdown {
color: #111827; width: 100%;
font-size: 15px;
font-weight: 400;
line-height: 20px;
} }
.content-body-image-card { .content-body-image-card {
@@ -38,10 +35,8 @@
.content-body-list-card { .content-body-list-card {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 4px; padding: 12px 16px 12px 0;
padding: 12px;
border-radius: 12px; border-radius: 12px;
margin-bottom: 8px;
} }
.content-body-list-item { .content-body-list-item {
@@ -49,19 +44,9 @@
align-items: flex-start; align-items: flex-start;
} }
.content-body-list-marker {
width: 22px;
flex-shrink: 0;
font-size: 15px;
font-weight: 800;
line-height: 20px;
}
.content-body-list-text { .content-body-list-text {
flex: 1; flex: 1;
font-size: 15px; min-width: 0;
font-weight: 400;
line-height: 20px;
} }
.detail-action-zone { .detail-action-zone {

View File

@@ -1,6 +1,12 @@
<template> <template>
<view class="container"> <view class="container">
<zero-markdown-view :markdown="text" :aiMode="true"></zero-markdown-view> <zero-markdown-view
:markdown="text"
:aiMode="true"
:theme-color="themeColor"
:font-color="fontColor"
:font-sub-color="fontSubColor"
></zero-markdown-view>
</view> </view>
</template> </template>
@@ -12,6 +18,18 @@ defineProps({
type: String, type: String,
default: "", default: "",
}, },
themeColor: {
type: String,
default: "#181B25",
},
fontColor: {
type: String,
default: "#181B25",
},
fontSubColor: {
type: String,
default: "#717784",
},
}); });
</script> </script>