feat: 对图片的兼容处理
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user