Jelajahi Sumber

feat(storeDecoration): 优化官方相册图片加载与保存逻辑

- 引入 nextTick 和 isLoadingAlbumImages 状态优化图片加载控制
- 新增 isLoadingAlbumImages 标志避免加载时触发不必要的 watch 回调
- 图片保存逻辑改为批量并发处理,提升上传效率
- 增强图片保存过滤条件,确保仅处理有效且未保存的图片
- 优化异常处理,保存失败时自动移除标记以支持重试
- 使用 nextTick 延迟重置加载状态,防止状态竞争问题
spy 3 minggu lalu
induk
melakukan
044d5f1fbb
1 mengubah file dengan 40 tambahan dan 6 penghapusan
  1. 40 6
      src/views/storeDecoration/officialPhotoAlbum/index.vue

+ 40 - 6
src/views/storeDecoration/officialPhotoAlbum/index.vue

@@ -101,7 +101,7 @@
 </template>
 
 <script setup lang="ts">
-import { ref, reactive, computed, onMounted, watch } from "vue";
+import { ref, reactive, computed, onMounted, watch, nextTick } from "vue";
 import { ElMessage, ElMessageBox } from "element-plus";
 import type { FormInstance, FormRules } from "element-plus";
 import type { UploadUserFile } from "element-plus";
@@ -146,6 +146,8 @@ const editId = ref<string | number | null>(null);
 const savingImages = ref<Set<string>>(new Set());
 // 已处理过的图片URL集合,防止重复处理
 const processedImages = ref<Set<string>>(new Set());
+// 是否正在加载相册图片(用于跳过watch触发)
+const isLoadingAlbumImages = ref(false);
 
 // 相册列表
 const albumList = ref<Album[]>([]);
@@ -521,6 +523,11 @@ watch(
   async (newImages, oldImages) => {
     updatePagination();
 
+    // 如果正在加载相册图片(从服务器加载),跳过处理,避免重复保存
+    if (isLoadingAlbumImages.value) {
+      return;
+    }
+
     // 如果没有相册ID,不处理
     if (!currentAlbum.value.id) {
       return;
@@ -534,12 +541,33 @@ watch(
     const addedUrls = Array.from(newUrls).filter(url => !oldUrls.has(url));
 
     // 处理新增的图片:没有imgId、有url、且未处理过、且不在保存中的图片
-    for (const url of addedUrls) {
-      const image = newImages.find((img: AlbumImage) => img.url === url);
-      if (image && !image.imgId && url && !savingImages.value.has(url) && !processedImages.value.has(url)) {
+    // 批量处理所有新增的图片
+    const imagesToSave = addedUrls
+      .map(url => newImages.find((img: AlbumImage) => img.url === url))
+      .filter((image): image is AlbumImage => {
+        return (
+          image !== undefined &&
+          !image.imgId &&
+          image.url !== undefined &&
+          image.url !== null &&
+          image.url !== "" &&
+          !savingImages.value.has(image.url) &&
+          !processedImages.value.has(image.url)
+        );
+      });
+
+    // 并发保存所有新上传的图片
+    for (const image of imagesToSave) {
+      const imageUrl = image.url;
+      if (imageUrl) {
         // 标记为已处理,防止重复处理
-        processedImages.value.add(url);
-        await saveImageToServer(url);
+        processedImages.value.add(imageUrl);
+        // 不等待,让所有图片并发上传
+        saveImageToServer(imageUrl).catch(error => {
+          console.error("保存图片失败:", error);
+          // 保存失败时,从已处理集合中移除,允许重试
+          processedImages.value.delete(imageUrl);
+        });
       }
     }
   },
@@ -604,6 +632,8 @@ const getAlbumList = async () => {
 // 加载相册图片列表
 const loadAlbumImages = async (albumId: string) => {
   try {
+    isLoadingAlbumImages.value = true; // 标记正在加载,避免触发watch
+
     const userInfo: any = localGet("geeker-user")?.userInfo || {};
     const storeId = userInfo.storeId;
     if (!storeId || !albumId) {
@@ -656,6 +686,10 @@ const loadAlbumImages = async (albumId: string) => {
       current.images = [];
       updatePagination();
     }
+  } finally {
+    // 使用 nextTick 确保在下一个事件循环中重置标志,避免立即触发 watch
+    await nextTick();
+    isLoadingAlbumImages.value = false;
   }
 };