Selaa lähdekoodia

门店头图多图模式问题

zhuli 2 kuukautta sitten
vanhempi
commit
05baec6e06

+ 54 - 4
src/components/Upload/Imgs.vue

@@ -13,6 +13,7 @@
       :on-exceed="handleExceed"
       :on-success="showSuccessNotification ? uploadSuccess : undefined"
       :on-error="uploadError"
+      :on-change="handleFileListChange"
       :drag="drag"
       :accept="fileType.join(',')"
     >
@@ -55,7 +56,7 @@
 </template>
 
 <script setup lang="ts" name="UploadImgs">
-import { ref, computed, inject, watch } from "vue";
+import { ref, computed, inject, watch, nextTick } from "vue";
 import { Plus, Picture } from "@element-plus/icons-vue";
 import { uploadImg } from "@/api/modules/upload";
 import type { UploadProps, UploadFile, UploadUserFile, UploadRequestOptions } from "element-plus";
@@ -106,14 +107,38 @@ const self_disabled = computed(() => {
 
 const _fileList = ref<UploadUserFile[]>(props.fileList);
 
+// 标记是否正在从 props 同步,避免循环更新
+let isSyncingFromProps = false;
+
 // 监听 props.fileList 列表默认值改变
 watch(
   () => props.fileList,
   (n: UploadUserFile[]) => {
+    isSyncingFromProps = true;
     _fileList.value = n;
+    nextTick(() => {
+      isSyncingFromProps = false;
+    });
   }
 );
 
+// 监听 _fileList 的变化,自动同步到父组件(排除从 props 同步的情况)
+// 注意:on-change 事件已经处理了大部分情况,这个 watch 作为备用
+watch(
+  () => _fileList.value,
+  (newList, oldList) => {
+    if (!isSyncingFromProps && newList !== oldList) {
+      // 延迟执行,避免与 on-change 重复
+      nextTick(() => {
+        if (!isSyncingFromProps) {
+          emit("update:fileList", [...newList]);
+        }
+      });
+    }
+  },
+  { deep: true, immediate: false }
+);
+
 // 记录正在上传的文件数量(使用 Set 跟踪文件 UID,更可靠)
 const uploadingFiles = new Set<string | number>();
 // 标记是否已经显示过成功提示,防止重复提示
@@ -170,11 +195,24 @@ const handleHttpUpload = async (options: UploadRequestOptions) => {
   try {
     const api = props.api ?? uploadImg;
     const { data } = await api(formData);
-    // 调用成功回调(如果提供了的话)
+    // 先调用 el-upload 的成功回调,确保文件列表更新
+    options.onSuccess(data);
+    // 然后调用自定义成功回调(如果提供了的话),即使回调失败也不影响文件列表
     if (props.onSuccess) {
-      props.onSuccess(data.fileUrl ? data.fileUrl : data[0]);
+      try {
+        const result = props.onSuccess(data.fileUrl ? data.fileUrl : data[0]);
+        // 如果回调返回 Promise,等待它完成(但不影响上传成功状态)
+        if (result && typeof result.then === "function") {
+          result.catch((callbackError: any) => {
+            // 回调失败不影响上传成功状态,只记录错误
+            console.error("onSuccess callback error:", callbackError);
+          });
+        }
+      } catch (callbackError) {
+        // 回调失败不影响上传成功状态,只记录错误
+        console.error("onSuccess callback error:", callbackError);
+      }
     }
-    options.onSuccess(data);
   } catch (error) {
     // 上传失败,移除文件 UID
     uploadingFiles.delete(fileUid);
@@ -224,6 +262,18 @@ const uploadSuccess = (response: { fileUrl: string } | string | string[] | undef
 };
 
 /**
+ * @description 文件列表变化处理
+ * @param uploadFile 变化的文件
+ * @param uploadFiles 当前文件列表
+ */
+const handleFileListChange: UploadProps["onChange"] = (uploadFile, uploadFiles) => {
+  // 当文件列表变化时,同步到父组件
+  if (!isSyncingFromProps) {
+    emit("update:fileList", uploadFiles as UploadUserFile[]);
+  }
+};
+
+/**
  * @description 删除图片
  * @param file 删除的文件
  * */

+ 4 - 2
src/views/storeDecoration/storeHeadMap/index.vue

@@ -96,7 +96,7 @@
               :show-success-notification="false"
             >
               <template #tip>
-                <div class="upload-tip">上传图片 ({{ formData.singleImage ? "1" : "0" }}/1)</div>
+                <div class="upload-tip">{{ formData }} ({{ formData.singleImage ? "1" : "0" }}/1)</div>
               </template>
             </UploadImg>
           </el-form-item>
@@ -119,7 +119,9 @@
                 :show-success-notification="false"
               >
                 <template #tip>
-                  <div class="upload-tip">上传图片 ({{ formData.multipleImages.length }}/6)</div>
+                  <div class="upload-tip">
+                    上传图片{{ formData.multipleImages.length }} ({{ formData.multipleImages.length }}/6)
+                  </div>
                 </template>
               </UploadImgs>
             </div>