浏览代码

Merge branch 'development' of http://8.152.195.41:3000/alien/group_web_merchant into development

zhuli 3 周之前
父节点
当前提交
3dc652ed15
共有 2 个文件被更改,包括 60 次插入19 次删除
  1. 40 6
      src/views/storeDecoration/officialPhotoAlbum/index.vue
  2. 20 13
      src/views/ticketManagement/newCoupon.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;
   }
 };
 

+ 20 - 13
src/views/ticketManagement/newCoupon.vue

@@ -38,7 +38,7 @@
             />
           </el-form-item>
           <!-- 有效期 -->
-          <el-form-item label="有效期" prop="specifiedDay">
+          <el-form-item label="有效期(天)" prop="specifiedDay">
             <el-input v-model="couponModel.specifiedDay" maxlength="15" placeholder="请输入" clearable />
           </el-form-item>
           <!-- 库存 -->
@@ -173,6 +173,7 @@ const rules = reactive({
     }
   ],
   minimumSpendingAmount: [
+    { required: true, message: "请输入最低消费金额" },
     {
       validator: (rule: any, value: any, callback: any) => {
         if (couponModel.value.hasMinimumSpend === 1) {
@@ -180,6 +181,12 @@ const rules = reactive({
             callback(new Error("请输入最低消费金额"));
             return;
           }
+          const strValue = value.toString().trim();
+          // 检查是否有前导零(除了单独的"0"或"0."开头的小数)
+          if (strValue.length > 1 && strValue.startsWith("0") && strValue !== "0" && !strValue.startsWith("0.")) {
+            callback(new Error("最低消费金额必须为正数"));
+            return;
+          }
           validatePositiveNumber("最低消费金额必须为正数")(rule, value, callback);
         } else {
           callback();
@@ -288,18 +295,18 @@ watch(
  * 监听最低消费金额变化
  * 当最低消费金额大于0时,自动设置为"是",否则设置为"否"
  */
-watch(
-  () => couponModel.value.minimumSpendingAmount,
-  newVal => {
-    if (isInitializing.value) return;
-    const amount = Number(newVal);
-    if (!isNaN(amount) && amount > 0) {
-      couponModel.value.hasMinimumSpend = 1;
-    } else {
-      couponModel.value.hasMinimumSpend = 0;
-    }
-  }
-);
+// watch(
+//   () => couponModel.value.minimumSpendingAmount,
+//   newVal => {
+//     if (isInitializing.value) return;
+//     const amount = Number(newVal);
+//     if (!isNaN(amount) && amount > 0) {
+//       couponModel.value.hasMinimumSpend = 1;
+//     } else {
+//       couponModel.value.hasMinimumSpend = 0;
+//     }
+//   }
+// );
 
 // ==================== 事件处理函数 ====================
 /**