feat: 对图片的兼容处理

This commit is contained in:
2026-05-22 15:36:08 +08:00
parent 932783af2c
commit 02ce413fd9

View File

@@ -4,6 +4,17 @@
<view v-if="entry.type === 'text'" class="content-body-text">
{{ entry.value }}
</view>
<view v-else-if="entry.type === 'image'" class="content-body-image-card">
<image
class="content-body-image"
:src="entry.value.image_id"
mode="widthFix"
@click="handlePreviewClick(entry.value.image_id)"
/>
<view v-if="entry.value.caption" class="content-body-image-caption">
{{ entry.value.caption }}
</view>
</view>
<view v-else-if="entry.type === 'list'" class="content-body-list-card">
<view
v-for="(item, index) in entry.value"
@@ -41,18 +52,33 @@ const isObjectValue = (value) => {
return value !== null && typeof value === "object" && !Array.isArray(value);
};
const sanitizeValue = (value) => {
if (isArrayValue(value)) {
return value.map((item) => sanitizeValue(item));
const parseJsonStringValue = (value) => {
if (typeof value !== "string") return value;
const text = value.trim();
if (!/^[\[{]/.test(text)) return value;
try {
return JSON.parse(text);
} catch (e) {
return value;
}
if (isObjectValue(value)) {
return Object.keys(value).reduce((result, key) => {
};
const sanitizeValue = (value) => {
const parsedValue = parseJsonStringValue(value);
if (isArrayValue(parsedValue)) {
return parsedValue.map((item) => sanitizeValue(item));
}
if (isObjectValue(parsedValue)) {
return Object.keys(parsedValue).reduce((result, key) => {
if (IGNORED_FIELD_KEYS.includes(key)) return result;
result[key] = sanitizeValue(value[key]);
result[key] = sanitizeValue(parsedValue[key]);
return result;
}, {});
}
return value;
return parsedValue;
};
const hasDisplayValue = (value) => {
@@ -79,10 +105,27 @@ const formatLeafValue = (value) => {
return String(value);
};
const isImageValue = (value) => {
return isObjectValue(value) && hasDisplayValue(value.image_id);
};
const createImageEntry = (key, value) => ({
key,
type: "image",
value: {
image_id: formatLeafValue(value.image_id).trim(),
caption: hasDisplayValue(value.caption) ? formatLeafValue(value.caption) : "",
},
});
const renderFieldEntries = computed(() => {
if (isIgnoredField.value || !hasDisplayValue(props.value)) return [];
const value = sanitizeValue(props.value);
if (isImageValue(value)) {
return [createImageEntry(props.fieldKey, value)];
}
if (isArrayValue(value)) {
return [{
key: props.fieldKey,
@@ -96,6 +139,9 @@ const renderFieldEntries = computed(() => {
.filter((key) => hasDisplayValue(value[key]))
.map((key) => {
const entryValue = value[key];
if (isImageValue(entryValue)) {
return createImageEntry(key, entryValue);
}
if (isArrayValue(entryValue)) {
return {
key,
@@ -120,6 +166,14 @@ const renderFieldEntries = computed(() => {
const isIgnoredField = computed(() => IGNORED_FIELD_KEYS.includes(props.fieldKey));
const shouldRenderField = computed(() => renderFieldEntries.value.length > 0);
const handlePreviewClick = (imageUrl) => {
uni.previewImage({
current: imageUrl,
urls: [imageUrl],
});
};
</script>
<style scoped lang="scss">
@@ -136,6 +190,26 @@ const shouldRenderField = computed(() => renderFieldEntries.value.length > 0);
line-height: 20px;
}
.content-body-image-card {
display: flex;
flex-direction: column;
gap: 6px;
}
.content-body-image {
width: 100%;
display: block;
border-radius: 8px;
background: #f3f4f6;
}
.content-body-image-caption {
color: #6b7280;
font-size: 12px;
font-weight: 400;
line-height: 18px;
}
.content-body-list-card {
display: flex;
flex-direction: column;