hookehuyr

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

新增图片缩略图展示,集成van-image-preview全屏预览组件,新增文件扩展名过滤逻辑识别可预览图片,完善只读场景交互体验
...@@ -55,17 +55,22 @@ ...@@ -55,17 +55,22 @@
55 <van-divider /> 55 <van-divider />
56 </div> 56 </div>
57 <div v-else style="padding: 1rem;"> 57 <div v-else style="padding: 1rem;">
58 - <!-- <a 58 + <div v-if="previewImageList.length" class="readonly-image-list">
59 - v-for="(item, index) in default_file" :key="index" 59 + <van-image
60 - :href="item.url" 60 + v-for="(item, index) in previewImageList"
61 - :download="item.name" 61 + :key="item.url || index"
62 - style="color: #000; font-size: 0.9rem; text-decoration: underline; margin-right: 0.5rem;" 62 + width="80"
63 - > 63 + height="80"
64 - {{ item.name }} 64 + fit="contain"
65 - </a> --> 65 + position="center"
66 + :src="item.url"
67 + style="margin-right: 0.5rem; margin-block-end: 0.25rem; border: 1px solid #eee; padding: 0.5rem;"
68 + @click="onPreviewImage(index)"
69 + />
70 + </div>
66 <a 71 <a
67 @click="downloadFile(item)" 72 @click="downloadFile(item)"
68 - v-for="(item, index) in default_file" :key="index" 73 + v-for="(item, index) in readonlyFileList" :key="`${item.url || item.name}-${index}`"
69 style="color: #000; font-size: 0.9rem; text-decoration: underline; margin-right: 0.5rem; cursor:pointer;" 74 style="color: #000; font-size: 0.9rem; text-decoration: underline; margin-right: 0.5rem; cursor:pointer;"
70 > 75 >
71 {{ item.name }} 76 {{ item.name }}
...@@ -79,6 +84,15 @@ ...@@ -79,6 +84,15 @@
79 <van-loading vertical color="#FFFFFF">上传中...</van-loading> 84 <van-loading vertical color="#FFFFFF">上传中...</van-loading>
80 </div> 85 </div>
81 </van-overlay> 86 </van-overlay>
87 +
88 + <van-image-preview
89 + v-model:show="showImagePreview"
90 + :images="previewImageUrls"
91 + :start-position="previewImageIndex"
92 + @change="onImagePreviewChange"
93 + >
94 + <template #index>第{{ previewImageIndex + 1 }}张</template>
95 + </van-image-preview>
82 </template> 96 </template>
83 97
84 <script setup> 98 <script setup>
...@@ -112,6 +126,38 @@ const ReadonlyShow = computed(() => { ...@@ -112,6 +126,38 @@ const ReadonlyShow = computed(() => {
112 const emit = defineEmits(["active"]); 126 const emit = defineEmits(["active"]);
113 const show_empty = ref(false); 127 const show_empty = ref(false);
114 const default_file = ref(props.item.component_props.default); 128 const default_file = ref(props.item.component_props.default);
129 +const previewImageIndex = ref(0);
130 +const showImagePreview = ref(false);
131 +
132 +// TAG:详情态兼容历史文件数据,只靠文件名或链接后缀判断是否可按图片预览
133 +const imageExtensionList = ["jpg", "jpeg", "png", "gif", "bmp", "webp", "svg", "tif", "tiff"];
134 +
135 +const getFileExtension = (value = "") => {
136 + const cleanValue = value.split("?")[0].split("#")[0];
137 + const extension = cleanValue.split(".").pop();
138 + return extension ? extension.toLowerCase() : "";
139 +};
140 +
141 +const isImageFile = (file = {}) => {
142 + const nameExtension = getFileExtension(file.name || "");
143 + const urlExtension = getFileExtension(file.url || "");
144 + return imageExtensionList.includes(nameExtension) || imageExtensionList.includes(urlExtension);
145 +};
146 +
147 +const readonlyFileList = computed(() => {
148 + if (!Array.isArray(default_file.value)) {
149 + return [];
150 + }
151 + return default_file.value.filter((item) => item?.url);
152 +});
153 +
154 +const previewImageList = computed(() => {
155 + return readonlyFileList.value.filter((item) => isImageFile(item));
156 +});
157 +
158 +const previewImageUrls = computed(() => {
159 + return previewImageList.value.map((item) => item.url);
160 +});
115 161
116 onMounted(() => { 162 onMounted(() => {
117 // 非只读模式并且有默认值时 163 // 非只读模式并且有默认值时
...@@ -154,6 +200,15 @@ const downloadFile = (item) => { ...@@ -154,6 +200,15 @@ const downloadFile = (item) => {
154 } 200 }
155 } 201 }
156 202
203 +const onPreviewImage = (index) => {
204 + previewImageIndex.value = index;
205 + showImagePreview.value = true;
206 +};
207 +
208 +const onImagePreviewChange = (index) => {
209 + previewImageIndex.value = index;
210 +};
211 +
157 // TAG: 文件下载操作 212 // TAG: 文件下载操作
158 /** 213 /**
159 * 数据流下载 214 * 数据流下载
......