Эх сурвалжийг харах

fix: 3467 3459 3458 3456等门店基础信息

sgc 1 сар өмнө
parent
commit
1ac9665fce

+ 2 - 1
src/api/modules/licenseManagement.ts

@@ -2,6 +2,7 @@ import { ResPage, StoreUser } from "@/api/interface/index";
 import { PORT_NONE } from "@/api/config/servicePort";
 import http from "@/api";
 import http_store from "@/api/indexStore";
+import httpApi from "@/api/indexApi";
 
 // 获取营业执照
 export const getBusinessLicense = params => {
@@ -89,5 +90,5 @@ export const uploadContractImage = (formData: FormData, onProgress?: (progress:
 
 // OCR 二次校验接口
 export const ocrRequestUrl = params => {
-  return http_store.post(PORT_NONE + `/ali/ocrRequestUrl`, params);
+  return httpApi.post(PORT_NONE + `/alienStore/ali/ocrRequestUrl`, params);
 };

+ 22 - 14
src/components/Upload/Imgs.vue

@@ -194,26 +194,34 @@ const handleHttpUpload = async (options: UploadRequestOptions) => {
   formData.append("file", options.file);
   try {
     const api = props.api ?? uploadImg;
-    const { data } = await api(formData);
-    // 无论是否显示成功提示,都先把当前文件的 url 设为服务器地址,否则父组件校验会认为仍是 blob 而报「请上传」
-    const fileUrl =
-      typeof data === "string"
-        ? data
-        : Array.isArray(data) && data.length > 0
-          ? data[0]
-          : (data?.fileUrl ?? (data && (Object.values(data)[0] as string)) ?? "");
+    const response = await api(formData);
+    // 从 response.fileUrl 取值
+    const fileUrl = response?.fileUrl || "";
+
     if (fileUrl) {
-      (options.file as UploadFile).url = fileUrl;
-      (options.file as UploadFile).status = "success";
+      // 更新 options.file(Element Plus 传入的文件对象)
+      (options.file as unknown as UploadFile).url = fileUrl;
+      (options.file as unknown as UploadFile).status = "success";
+      (options.file as unknown as UploadFile).response = response;
+
+      // 同步更新 _fileList 中对应的文件
+      const fileIndex = _fileList.value.findIndex(item => item.uid === fileUid);
+      if (fileIndex !== -1) {
+        _fileList.value[fileIndex].url = fileUrl;
+        _fileList.value[fileIndex].status = "success";
+        (_fileList.value[fileIndex] as any).response = response;
+      }
     }
-    options.onSuccess(data);
+
+    options.onSuccess(response);
+    // 传递更新后的 _fileList 给父组件
     emit("update:fileList", _fileList.value);
     if (props.onSuccess) {
       try {
-        const result = props.onSuccess(data?.fileUrl ? data.fileUrl : (data?.[0] ?? fileUrl));
+        const result = props.onSuccess(fileUrl);
         // 如果回调返回 Promise,等待它完成(但不影响上传成功状态)
-        if (result && typeof result.then === "function") {
-          result.catch((callbackError: any) => {
+        if (result !== undefined && result !== null && typeof result === "object" && typeof (result as any).then === "function") {
+          (result as Promise<any>).catch((callbackError: any) => {
             // 回调失败不影响上传成功状态,只记录错误
             console.error("onSuccess callback error:", callbackError);
           });

+ 1 - 22
src/views/performance/edit.vue

@@ -160,34 +160,13 @@
               </el-form-item>
             </template>
             <template v-if="form.frequency === '每周定时进行'">
-              <el-form-item label="演出日期">
+              <el-form-item label="演出日期" required>
                 <el-checkbox-group v-model="form.weeklyPerformanceWeekdays" :disabled="viewMode">
                   <el-checkbox v-for="day in weekdays" :key="day" :label="day">
                     {{ day }}
                   </el-checkbox>
                 </el-checkbox-group>
               </el-form-item>
-              <el-form-item label="演出日期" required>
-                <div class="date-time-row">
-                  <el-date-picker
-                    v-model="weeklyDateStart"
-                    type="date"
-                    placeholder="年/月/日"
-                    value-format="YYYY-MM-DD"
-                    style="width: 140px"
-                    :disabled="viewMode"
-                  />
-                  <span class="sep">至</span>
-                  <el-date-picker
-                    v-model="weeklyDateEnd"
-                    type="date"
-                    placeholder="年/月/日"
-                    value-format="YYYY-MM-DD"
-                    style="width: 140px"
-                    :disabled="viewMode"
-                  />
-                </div>
-              </el-form-item>
               <el-form-item label="演出时间" required>
                 <div class="date-time-row">
                   <el-time-picker

+ 2 - 2
src/views/performance/index.vue

@@ -156,7 +156,7 @@ const columns: ColumnProps<PerformanceRow>[] = [
   },
   {
     prop: "startCreatedTime",
-    label: "演出开始时间",
+    label: "提交开始时间",
     isShow: false,
     search: {
       el: "date-picker",
@@ -169,7 +169,7 @@ const columns: ColumnProps<PerformanceRow>[] = [
   },
   {
     prop: "endCreatedTime",
-    label: "演出结束时间",
+    label: "提交结束时间",
     isShow: false,
     search: {
       el: "date-picker",

+ 114 - 3
src/views/storeDecoration/basicStoreInformation/index.vue

@@ -159,6 +159,19 @@
               </template>
             </el-input>
           </el-form-item>
+          <!-- 店铺评价 -->
+          <el-form-item label="店铺评价" prop="storeEvaluate">
+            <el-input v-model="storeEvaluate1" type="text" :rows="1" placeholder="请输入评价1" show-word-limit />
+            <el-input
+              style="margin: 10px 0"
+              v-model="storeEvaluate2"
+              type="text"
+              :rows="1"
+              placeholder="请输入评价2"
+              show-word-limit
+            />
+            <el-input v-model="storeEvaluate3" type="text" :rows="1" placeholder="请输入评价3" show-word-limit />
+          </el-form-item>
           <!-- 经营板块 -->
           <el-form-item label="经营板块" prop="businessSection">
             <el-radio-group v-model="formData.businessSection" class="business-section-radio-group">
@@ -170,6 +183,14 @@
             </el-radio-group>
           </el-form-item>
 
+          <!-- 标签选择(仅当经营板块为生活服务时显示) -->
+          <el-form-item v-if="formData.businessSection === 3" label="标签选择" prop="storeTickets" required>
+            <el-radio-group v-model="formData.storeTickets">
+              <el-radio :value="1"> 装修公司 </el-radio>
+              <el-radio :value="0"> 其他 </el-radio>
+            </el-radio-group>
+          </el-form-item>
+
           <!-- 经营种类 -->
           <el-form-item label="经营种类" prop="businessTypeName">
             <el-input v-model="formData.businessTypeName" placeholder="请输入经营种类" clearable maxlength="50" />
@@ -242,6 +263,11 @@ const loading = ref(false);
 // 标记是否正在加载详情数据,用于防止触发 watch
 const isLoadingDetail = ref(false);
 
+// 店铺评价三个输入框的独立变量
+const storeEvaluate1 = ref("");
+const storeEvaluate2 = ref("");
+const storeEvaluate3 = ref("");
+
 // 表单数据
 const formData = reactive({
   id: "",
@@ -255,6 +281,7 @@ const formData = reactive({
   administrativeRegionDistrictAdcode: "",
   storeAddress: "",
   storeBlurb: "",
+  storeEvaluate: "",
   queryAddress: "",
   businessSection: "" as number | "",
   businessSectionName: "",
@@ -265,7 +292,8 @@ const formData = reactive({
   storePosition: "",
   storePositionLongitude: "",
   storePositionLatitude: "",
-  isChain: 0
+  isChain: 0,
+  storeTickets: "" as number | ""
 });
 
 // 经纬度查询
@@ -339,8 +367,38 @@ const rules = reactive<FormRules>({
   administrativeRegionDistrictAdcode: [{ required: true, message: "请选择区", trigger: "change" }],
   storeAddress: [{ required: true, message: "请输入详细地址", trigger: "blur" }],
   storeBlurb: [{ required: true, message: "请输入门店简介", trigger: "blur" }],
+  storeEvaluate: [
+    {
+      required: true,
+      validator: (rule: any, value: any, callback: any) => {
+        if (!storeEvaluate1.value || !storeEvaluate2.value || !storeEvaluate3.value) {
+          callback(new Error("请填写完整的店铺评价(三个评价都需要填写)"));
+        } else {
+          callback();
+        }
+      },
+      trigger: "blur"
+    }
+  ],
   queryAddress: [{ required: true, message: "请输入地址进行经纬度查询", trigger: "blur" }],
   businessSection: [{ required: true, message: "请选择经营板块", trigger: "change" }],
+  storeTickets: [
+    {
+      validator: (rule: any, value: any, callback: any) => {
+        // 仅当经营板块为生活服务(值为3)时,storeTickets为必填
+        if (formData.businessSection === 3) {
+          if (value === "" || value === null || value === undefined) {
+            callback(new Error("请选择标签"));
+          } else {
+            callback();
+          }
+        } else {
+          callback();
+        }
+      },
+      trigger: "change"
+    }
+  ],
   businessTypeName: [{ required: true, message: "请输入经营种类", trigger: "blur" }],
   businessCategoryName: [{ required: true, message: "请输入经营类目", trigger: "blur" }]
 });
@@ -480,6 +538,23 @@ const businessStatusReverseMap: Record<number, string> = {
 const handleSubmit = async () => {
   if (!formRef.value) return;
 
+  // 先验证三个店铺评价字段是否都填写
+  if (!storeEvaluate1.value || !storeEvaluate2.value || !storeEvaluate3.value) {
+    ElMessage.warning("请填写完整的店铺评价(三个评价都需要填写)");
+    // 手动触发验证,显示错误提示
+    formRef.value.validateField("storeEvaluate", () => {});
+    return;
+  }
+
+  // 验证标签选择(当经营板块为生活服务时)
+  if (formData.businessSection === 3) {
+    if (formData.storeTickets === "" || formData.storeTickets === null || formData.storeTickets === undefined) {
+      ElMessage.warning("请选择标签");
+      formRef.value.validateField("storeTickets", () => {});
+      return;
+    }
+  }
+
   await formRef.value.validate(async valid => {
     if (!valid) {
       ElMessage.warning("请完善表单信息");
@@ -504,6 +579,11 @@ const handleSubmit = async () => {
       // 获取经营板块名称
       const selectedSection = businessSectionList.value.find(item => item.dictId === formData.businessSection);
 
+      // 将三个店铺评价用逗号拼接
+      formData.storeEvaluate = [storeEvaluate1.value, storeEvaluate2.value, storeEvaluate3.value]
+        .filter(item => item && item.trim())
+        .join(",");
+
       const submitData = {
         id: formData.id ? Number(formData.id) : undefined,
         isChain: formData.isChain,
@@ -513,6 +593,7 @@ const handleSubmit = async () => {
         storeAddress: formData.storeAddress,
         storeArea: formData.storeArea,
         storeBlurb: formData.storeBlurb,
+        storeEvaluate: formData.storeEvaluate,
         queryAddress: formData.queryAddress,
         administrativeRegionProvinceAdcode: formData.administrativeRegionProvinceAdcode ?? "",
         administrativeRegionCityAdcode: formData.administrativeRegionCityAdcode ?? "",
@@ -525,7 +606,10 @@ const handleSubmit = async () => {
         businessSection: formData.businessSection,
         businessSectionName: selectedSection ? selectedSection.dictDetail : "",
         businessTypeName: formData.businessTypeName,
-        businessCategoryName: formData.businessCategoryName
+        businessCategoryName: formData.businessCategoryName,
+        // 标签选择(仅当经营板块为生活服务时)
+        storeTickets:
+          formData.businessSection === 3 ? (formData.storeTickets !== "" ? formData.storeTickets : undefined) : undefined
       };
 
       let result;
@@ -578,6 +662,19 @@ const getStoreDetailData = async () => {
       formData.businessStatus = storeData.businessStatus ?? "";
       formData.storeAddress = storeData.storeAddress ?? "";
       formData.storeBlurb = storeData.storeBlurb ?? "";
+      // 处理店铺评价:用逗号切割并分别赋值给三个输入框
+      if (storeData.storeEvaluate) {
+        const evaluateArray = storeData.storeEvaluate.split(",");
+        storeEvaluate1.value = evaluateArray[0]?.trim() || "";
+        storeEvaluate2.value = evaluateArray[1]?.trim() || "";
+        storeEvaluate3.value = evaluateArray[2]?.trim() || "";
+        formData.storeEvaluate = storeData.storeEvaluate;
+      } else {
+        storeEvaluate1.value = "";
+        storeEvaluate2.value = "";
+        storeEvaluate3.value = "";
+        formData.storeEvaluate = "";
+      }
       formData.expirationTime = storeData.expirationTime ?? "";
       formData.foodLicenceExpirationTime = storeData.foodLicenceExpirationTime ?? "";
       formData.storePosition = storeData.storePosition ?? "";
@@ -608,6 +705,13 @@ const getStoreDetailData = async () => {
         formData.businessSection = storeData.businessSection;
         formData.businessSectionName = storeData.businessSectionName ?? "";
       }
+      // 设置标签选择(仅当经营板块为生活服务时)
+      if (storeData.businessSection === 3) {
+        formData.storeTickets =
+          storeData.storeTickets !== undefined && storeData.storeTickets !== null ? Number(storeData.storeTickets) : "";
+      } else {
+        formData.storeTickets = "";
+      }
       formData.businessTypeName = storeData.businessTypeName ?? "";
       // 如果 businessCategoryName 是 0,转换为空字符串
       const categoryName = storeData.businessCategoryName;
@@ -635,6 +739,13 @@ watch(
       if (newValue === 3 && formData.businessCategoryName === "0") {
         formData.businessCategoryName = "";
       }
+      // 当切换到非生活服务时,清空标签选择
+      if (newValue !== 3) {
+        formData.storeTickets = "";
+      }
+    } else {
+      // 如果经营板块为空,也清空标签选择
+      formData.storeTickets = "";
     }
   }
 );
@@ -708,7 +819,7 @@ onMounted(async () => {
 }
 
 // 响应式布局
-@media (width <= 1200px) {
+@media (width <=1200px) {
   .store-info-container {
     .store-form {
       .form-content {

+ 2 - 2
src/views/storeDecoration/officialPhotoAlbum/index.vue

@@ -27,7 +27,7 @@
         <div class="upload-item upload-box">
           <UploadImgs
             v-model:file-list="currentAlbum.images"
-            :limit="60"
+            :limit="50"
             :file-size="9999"
             :file-type="['image/jpeg', 'image/png', 'image/gif', 'image/webp']"
             :width="'100%'"
@@ -36,7 +36,7 @@
             :api="customUploadApi"
           >
             <template #tip>
-              <div class="upload-tip-text">上传图片 ({{ currentAlbum.images.length }}/60)</div>
+              <div class="upload-tip-text">上传图片 ({{ currentAlbum.images.length }}/50)</div>
             </template>
           </UploadImgs>
         </div>

+ 24 - 51
src/views/storeDecoration/storeHeadMap/index.vue

@@ -91,12 +91,12 @@
               :file-size="20"
               :file-type="['image/jpeg', 'image/png', 'image/gif', 'image/webp']"
               :border-radius="'8px'"
-              :api="singleImageUploadApi"
+              :api="uploadImageResult"
               :on-success="handleStoreOcrAfterUpload"
               :show-success-notification="false"
             >
               <template #tip>
-                <div class="upload-tip">{{ formData }} ({{ formData.singleImage ? "1" : "0" }}/1)</div>
+                <div class="upload-tip">({{ formData.singleImage ? "1" : "0" }}/1)</div>
               </template>
             </UploadImg>
           </el-form-item>
@@ -114,7 +114,7 @@
                 :width="'200px'"
                 :height="'112px'"
                 :border-radius="'8px'"
-                :api="multipleImageUploadApi"
+                :api="uploadImageResult"
                 :on-success="handleStoreOcrAfterUploadMore"
                 :show-success-notification="false"
               >
@@ -232,56 +232,17 @@ const previewData = reactive({
   reviews: 1853
 });
 
-// 显示的多图预览(最多显示3张)- 始终显示多图数据,不依赖当前模式
+// 显示的多图预览
 const displayImages = computed(() => {
   return formData.multipleImages.slice(0, 3).map(item => item.url || "");
 });
 
-// 单图模式:图片校验函数(已移除尺寸限制)
-const validateSingleImageDimensions = (file: File): Promise<boolean> => {
-  return new Promise((resolve, reject) => {
-    // 直接通过,不进行任何校验
-    resolve(true);
-  });
-};
-
-// 多图模式:图片校验函数(已移除比例限制)
-const validateMultipleImageDimensions = (file: File): Promise<boolean> => {
-  return new Promise((resolve, reject) => {
-    // 直接通过,不进行任何校验
-    resolve(true);
-  });
-};
-
-// 单图模式:自定义上传API
-const singleImageUploadApi = async (formData: FormData): Promise<any> => {
-  // 已移除尺寸校验,直接上传
-
-  // 校验通过后调用实际上传接口
-  const response: any = await uploadImg(formData);
-  // 处理返回格式:{ code, success, data: string[], msg }
-  if (response && response.code === 200 && response.data && Array.isArray(response.data) && response.data.length > 0) {
-    return {
-      data: {
-        fileUrl: response.data[0] // 取数组第一个元素作为图片URL
-      }
-    };
-  }
-  throw new Error(response?.msg || "上传失败");
-};
-
-// 多图模式:自定义上传API
-const multipleImageUploadApi = async (formData: FormData): Promise<any> => {
-  // 已移除比例校验,直接上传
-
-  // 校验通过后调用实际上传接口
+// 处理上传图片
+const uploadImageResult = async (formData: FormData): Promise<any> => {
   const response: any = await uploadImg(formData);
-  // 处理返回格式:{ code, success, data: string[], msg }
-  if (response && response.code === 200 && response.data && Array.isArray(response.data) && response.data.length > 0) {
+  if (response.code == 200) {
     return {
-      data: {
-        fileUrl: response.data[0] // 取数组第一个元素作为图片URL
-      }
+      fileUrl: response.data[0] // 取数组第一个元素作为图片URL,直接返回 fileUrl
     };
   }
   throw new Error(response?.msg || "上传失败");
@@ -385,7 +346,7 @@ const loadHeadImgByMode = async (targetMode: "single" | "multiple") => {
     const imgType = targetMode === "single" ? 20 : 21;
     const res: any = await getStoreHeadImg(storeId, imgType);
 
-    if (res && (res.code === 200 || res.code === "200") && res.data) {
+    if (res.code == 200) {
       const dataAny = res.data as any;
       const imgList = Array.isArray(dataAny) ? dataAny : dataAny.storeImgList || [];
 
@@ -470,15 +431,27 @@ const getStoreHeadImgData = async () => {
       }
     }
 
-    // 根据数据情况设置默认模式:优先单图,如果没有单图则使用多图
-    if (formData.singleImage) {
-      mode.value = "single";
+    // 根据数据情况设置默认模式:优先根据imgModeActive,如果有多图则使用多图模式
+    if (imgModeActive.value !== null && imgModeActive.value !== undefined) {
+      // 如果后端返回了imgMode,优先使用后端返回的值
+      // 0表示单图模式,1表示多图模式
+      mode.value = imgModeActive.value === 0 ? "single" : "multiple";
+      // 如果是多图模式,初始化拖拽排序
+      if (mode.value === "multiple") {
+        nextTick(() => {
+          initDragSort();
+        });
+      }
     } else if (formData.multipleImages.length > 0) {
+      // 如果有多图数据,优先显示多图模式
       mode.value = "multiple";
       // 初始化拖拽排序
       nextTick(() => {
         initDragSort();
       });
+    } else if (formData.singleImage) {
+      // 如果没有多图但有单图,显示单图模式
+      mode.value = "single";
     }
   } catch (error) {
     console.error("获取头图失败:", error);