hookehuyr

feat(FileUploaderField): 为只读模式文件上传字段添加图片预览功能

新增图片缩略图展示,集成van-image-preview全屏预览组件,新增文件扩展名过滤逻辑识别可预览图片,完善只读场景交互体验
......@@ -55,17 +55,22 @@
<van-divider />
</div>
<div v-else style="padding: 1rem;">
<!-- <a
v-for="(item, index) in default_file" :key="index"
:href="item.url"
:download="item.name"
style="color: #000; font-size: 0.9rem; text-decoration: underline; margin-right: 0.5rem;"
>
{{ item.name }}
</a> -->
<div v-if="previewImageList.length" class="readonly-image-list">
<van-image
v-for="(item, index) in previewImageList"
:key="item.url || index"
width="80"
height="80"
fit="contain"
position="center"
:src="item.url"
style="margin-right: 0.5rem; margin-block-end: 0.25rem; border: 1px solid #eee; padding: 0.5rem;"
@click="onPreviewImage(index)"
/>
</div>
<a
@click="downloadFile(item)"
v-for="(item, index) in default_file" :key="index"
v-for="(item, index) in readonlyFileList" :key="`${item.url || item.name}-${index}`"
style="color: #000; font-size: 0.9rem; text-decoration: underline; margin-right: 0.5rem; cursor:pointer;"
>
{{ item.name }}
......@@ -79,6 +84,15 @@
<van-loading vertical color="#FFFFFF">上传中...</van-loading>
</div>
</van-overlay>
<van-image-preview
v-model:show="showImagePreview"
:images="previewImageUrls"
:start-position="previewImageIndex"
@change="onImagePreviewChange"
>
<template #index>第{{ previewImageIndex + 1 }}张</template>
</van-image-preview>
</template>
<script setup>
......@@ -112,6 +126,38 @@ const ReadonlyShow = computed(() => {
const emit = defineEmits(["active"]);
const show_empty = ref(false);
const default_file = ref(props.item.component_props.default);
const previewImageIndex = ref(0);
const showImagePreview = ref(false);
// TAG:详情态兼容历史文件数据,只靠文件名或链接后缀判断是否可按图片预览
const imageExtensionList = ["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg", "tif", "tiff"];
const getFileExtension = (value = "") => {
const cleanValue = value.split("?")[0].split("#")[0];
const extension = cleanValue.split(".").pop();
return extension ? extension.toLowerCase() : "";
};
const isImageFile = (file = {}) => {
const nameExtension = getFileExtension(file.name || "");
const urlExtension = getFileExtension(file.url || "");
return imageExtensionList.includes(nameExtension) || imageExtensionList.includes(urlExtension);
};
const readonlyFileList = computed(() => {
if (!Array.isArray(default_file.value)) {
return [];
}
return default_file.value.filter((item) => item?.url);
});
const previewImageList = computed(() => {
return readonlyFileList.value.filter((item) => isImageFile(item));
});
const previewImageUrls = computed(() => {
return previewImageList.value.map((item) => item.url);
});
onMounted(() => {
// 非只读模式并且有默认值时
......@@ -154,6 +200,15 @@ const downloadFile = (item) => {
}
}
const onPreviewImage = (index) => {
previewImageIndex.value = index;
showImagePreview.value = true;
};
const onImagePreviewChange = (index) => {
previewImageIndex.value = index;
};
// TAG: 文件下载操作
/**
* 数据流下载
......