Преглед изворни кода

fix: 图片上传和代金券隐藏

sgc пре 3 недеља
родитељ
комит
7bdfc1f6e1
2 измењених фајлова са 87 додато и 7 уклоњено
  1. 2 2
      src/views/businessData/overview.vue
  2. 85 5
      src/views/priceList/edit.vue

+ 2 - 2
src/views/businessData/overview.vue

@@ -39,9 +39,9 @@
         <el-tab-pane label="优惠券" name="coupon">
           <StatCardList :items="couponStats" />
         </el-tab-pane>
-        <el-tab-pane label="代金券" name="voucher">
+        <!-- <el-tab-pane label="代金券" name="voucher">
           <StatCardList :items="voucherStats" />
-        </el-tab-pane>
+        </el-tab-pane> -->
         <el-tab-pane label="服务质量" name="service">
           <StatCardList :items="serviceStats" />
         </el-tab-pane>

+ 85 - 5
src/views/priceList/edit.vue

@@ -43,9 +43,11 @@
             <div class="image-upload-wrap">
               <UploadImgs
                 v-model:file-list="imageFileList"
-                :api="uploadImgStore"
+                :api="handleCustomImageUpload"
                 :limit="9"
                 :file-size="5"
+                :width="'100px'"
+                :height="'100px'"
                 :disabled="viewMode"
                 class="price-list-upload"
                 @update:file-list="onImageListChange"
@@ -241,6 +243,8 @@
                 :api="uploadImgStore"
                 :limit="9"
                 :file-size="5"
+                :width="'100px'"
+                :height="'100px'"
                 :disabled="viewMode"
                 class="price-list-upload"
                 @update:file-list="onDetailImageListChange"
@@ -355,7 +359,7 @@
 </template>
 
 <script setup lang="ts" name="priceListEdit">
-import { ref, reactive, computed, onMounted, watch } from "vue";
+import { ref, reactive, computed, onMounted, watch, nextTick } from "vue";
 import { ElMessage } from "element-plus";
 import { useRoute, useRouter } from "vue-router";
 import type { FormInstance, UploadUserFile } from "element-plus";
@@ -545,9 +549,75 @@ function calcRecommendedPrice() {
   }
 }
 
+// 自定义上传函数,正确处理响应格式(参考 personnelConfig/index.vue)
+const handleCustomImageUpload = async (formData: FormData): Promise<any> => {
+  try {
+    const response: any = await uploadImgStore(formData);
+
+    // API 返回格式: { code: 200, success: true, data: ["https://..."], msg: "操作成功" }
+    // 需要提取 response.data[0] 作为图片 URL
+    let imageUrl = "";
+
+    if (response && (response.code === 200 || response.code === "200")) {
+      if (Array.isArray(response.data) && response.data.length > 0) {
+        imageUrl = response.data[0];
+      } else if (typeof response.data === "string") {
+        imageUrl = response.data;
+      } else if (response.data?.fileUrl) {
+        imageUrl = response.data.fileUrl;
+      } else if (response.fileUrl) {
+        imageUrl = response.fileUrl;
+      }
+    }
+
+    if (!imageUrl) {
+      throw new Error("无法提取图片URL");
+    }
+
+    // 返回格式需要兼容 Imgs.vue 组件的处理逻辑
+    // 返回一个对象,其中 fileUrl 是图片URL,这样 uploadSuccess 会使用 response.fileUrl
+    const result = {
+      fileUrl: imageUrl, // 供 uploadSuccess 使用(会设置 uploadFile.url = response.fileUrl)
+      data: [imageUrl], // 备用
+      code: response.code,
+      msg: response.msg,
+      success: response.success
+    };
+
+    return result;
+  } catch (error) {
+    console.error("自定义上传函数 - 上传失败:", error);
+    throw error;
+  }
+};
+
+// 统一处理文件列表变化,更新 formModel.images(用逗号拼接)
+// 注意:这是多选,最后要用逗号拼接在一起
 function onImageListChange(list: UploadUserFile[]) {
-  const urls = list.map(f => (typeof f.url === "string" ? f.url : "")).filter(Boolean);
+  // 过滤掉 blob URL,只保留服务器 URL,然后用逗号拼接
+  const urls = list
+    .filter(f => {
+      const url = f.url;
+      if (!url || typeof url !== "string") return false;
+      // 排除 blob URL(临时预览 URL)
+      return !url.startsWith("blob:");
+    })
+    .map(f => {
+      const url = f.url;
+      if (url && typeof url === "string") {
+        return url.trim();
+      }
+      return "";
+    })
+    .filter(Boolean);
+
+  // 用逗号拼接所有 URL
   formModel.images = urls.join(",");
+
+  // 触发表单验证
+  if (ruleFormRef.value) {
+    ruleFormRef.value.validateField("images");
+  }
 }
 
 function onDetailImageListChange(list: UploadUserFile[]) {
@@ -558,10 +628,20 @@ function onDetailImageListChange(list: UploadUserFile[]) {
 function syncImageFileListFromModel() {
   const str = formModel.images || "";
   const urls = str ? str.split(",").filter(Boolean) : [];
-  imageFileList.value = urls.map((url, i) => ({ uid: i, name: `img-${i}`, url }));
+  imageFileList.value = urls.map((url, i) => ({
+    uid: Date.now() + i,
+    name: `img-${i}`,
+    url: url.trim(),
+    status: "success" as const
+  }));
   const detailStr = formModel.imageContent || "";
   const detailUrls = detailStr ? detailStr.split(",").filter(Boolean) : [];
-  detailImageFileList.value = detailUrls.map((url, i) => ({ uid: 1000 + i, name: `detail-${i}`, url }));
+  detailImageFileList.value = detailUrls.map((url, i) => ({
+    uid: Date.now() + 1000 + i,
+    name: `detail-${i}`,
+    url: url.trim(),
+    status: "success" as const
+  }));
 }
 
 // 详情接口返回转表单(美食接口返回 data.data.data 结构,cuisineType 1=菜品 2=套餐;非美食仅通用字段)