Переглянути джерело

增加店铺端食品经营许可证多张上传

Guos 3 тижнів тому
батько
коміт
bb07605951
1 змінених файлів з 256 додано та 27 видалено
  1. 256 27
      src/views/store/storeConfig/userInfo.vue

+ 256 - 27
src/views/store/storeConfig/userInfo.vue

@@ -362,34 +362,37 @@
 
           <el-row>
             <el-col :span="12">
+              <!-- 替换原有的食品经营许可证上传部分 -->
               <el-form-item label="食品经营许可证/备案凭证上传" prop="foodLicense">
-                <el-upload
-                  class="avatar-uploader"
-                  :action="uploadUrl"
-                  :show-file-list="false"
-                  :on-success="(response, file) => handleFileSuccess(response, file, 'foodLicense')"
-                  :before-upload="beforeAvatarUpload">
-                  <div class="avatar-wrapper" v-if="form.foodLicense">
-                    <img :src="form.foodLicense" class="avatar" width="200px">
-<!--                    <div class="delete-mask" @click.stop="handleDelete3">-->
-<!--                      <i class="el-icon-delete"></i>-->
-<!--                    </div>-->
-                    <div class="button-group">
-                      <div class="preview-btn" @click.stop="previewImage(form.foodLicense)">
-                        <i class="el-icon-zoom-in"></i>
-                      </div>
-                      <div v-if="!isViewMode" class="delete-btn" @click.stop="handleDelete3">
-                        <i class="el-icon-delete"></i>
-                      </div>
+                <!-- 显示已上传的图片 -->
+                <div v-if="form.foodLicense && Array.isArray(form.foodLicense) && form.foodLicense.length > 0"
+                     class="uploaded-images-preview">
+                  <div v-for="(url, index) in form.foodLicense" :key="index" class="image-wrapper">
+                    <img :src="url" class="uploaded-image" />
+                    <div class="image-overlay">
+                      <i class="el-icon-zoom-in" @click.stop="previewImage(url)"></i>
+                      <i class="el-icon-delete" @click.stop="handleDeleteFoodLicense(index)" v-if="!isViewMode"></i>
                     </div>
                   </div>
-                  <!-- 未上传图片时显示的默认图标 -->
-                  <div v-else class="no-image-placeholder">
-                    <span v-if="isViewMode">用户未上传</span>
-                    <i v-else class="el-icon-plus avatar-uploader-icon"></i>
-                  </div>
-
-                </el-upload>
+                </div>
+                
+                <!-- 上传控件 - 始终显示 -->
+                <div class="upload-area-wrapper">
+                  <el-upload
+                    class="avatar-uploader small-uploader"
+                    :action="uploadUrl"
+                    :show-file-list="false"
+                    :on-success="handleFoodLicenseSuccess"
+                    :before-upload="beforeAvatarUpload"
+                    :limit="3"
+                    :on-exceed="handleFoodLicenseExceed"
+                    :file-list="foodLicenseFileList">
+                    <div class="no-image-placeholder small-placeholder">
+                      <span v-if="isViewMode">用户未上传</span>
+                      <i v-else class="el-icon-plus avatar-uploader-icon"></i>
+                    </div>
+                  </el-upload>
+                </div>
               </el-form-item>
               <el-form-item label="食品经营许可证/备案凭证编号" prop="foodCode" style="margin-left: 5px">
                 <el-input v-model="form.foodCode" placeholder="请输入食品经营许可证/备案凭证编号" />
@@ -583,6 +586,8 @@ export default {
       }],
       // 表单参数
       form: {},
+      // 食品经营许可证上传文件列表
+      foodLicenseFileList: [],
       uploadUrl: process.env.VUE_APP_BASE_API + '/common/uploadOSS',
       baseUrl: process.env.VUE_APP_BASE_API,
       // 表单校验
@@ -695,6 +700,109 @@ export default {
     });
   },
   methods: {
+    // 处理食品经营许可证上传成功
+    handleFoodLicenseSuccess(response, file) {
+      if (response.code === 200) {
+        // 确保 foodLicense 是数组格式进行处理
+        let currentFiles = [];
+        if (this.form.foodLicense) {
+          if (typeof this.form.foodLicense === 'string') {
+            currentFiles = this.form.foodLicense.split(',').filter(url => url.trim() !== '');
+          } else if (Array.isArray(this.form.foodLicense)) {
+            currentFiles = this.form.foodLicense;
+          }
+        }
+        // 检查是否超过最大上传数量
+        if (currentFiles.length >= 3) {
+          this.$message.warning('最多只能上传3张图片');
+          return;
+        }
+        // 添加新上传的图片URL到数组中
+        currentFiles.push(response.url);
+        // 更新表单数据
+        this.$set(this.form, 'foodLicense', currentFiles);
+        // 更新上传文件列表
+        this.foodLicenseFileList.push(file);
+        // 更新视图
+        this.$forceUpdate();
+      } else {
+        this.msgError(response.msg);
+      }
+    },
+    // 处理超出最大上传数量限制
+    handleFoodLicenseExceed(files, fileList) {
+      // 检查当前实际的图片数量
+      let currentCount = 0;
+      if (this.form.foodLicense) {
+        if (typeof this.form.foodLicense === 'string') {
+          currentCount = this.form.foodLicense.split(',').filter(url => url.trim() !== '').length;
+        } else if (Array.isArray(this.form.foodLicense)) {
+          currentCount = this.form.foodLicense.length;
+        }
+      }
+      
+      // 只有当实际图片数量达到上限时才提示
+      if (currentCount >= 3) {
+        this.$message.warning('最多只能上传3张图片');
+      }
+    },
+    // 获取用于主展示的食品经营许可证图片
+    getFoodLicenseDisplayImage() {
+      let files = [];
+      if (this.form.foodLicense) {
+        if (typeof this.form.foodLicense === 'string') {
+          files = this.form.foodLicense.split(',').filter(url => url.trim() !== '');
+        } else if (Array.isArray(this.form.foodLicense)) {
+          files = this.form.foodLicense;
+        }
+      }
+      return files.length > 0 ? files[0] : '';
+    },
+    // 删除指定索引的食品经营许可证图片
+    handleDeleteFoodLicense(index) {
+      this.$confirm('确定要删除这张图片吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        let files = [];
+        if (typeof this.form.foodLicense === 'string' && this.form.foodLicense) {
+          files = this.form.foodLicense.split(',').filter(url => url.trim() !== '');
+        } else if (Array.isArray(this.form.foodLicense)) {
+          files = this.form.foodLicense;
+        }
+        files.splice(index, 1);
+        this.$set(this.form, 'foodLicense', files);
+        // 重置上传文件列表
+        this.foodLicenseFileList = [];
+        this.$forceUpdate();
+        this.$message.success('图片已删除');
+      }).catch(() => {
+        this.$message.info('已取消删除');
+      });
+    },
+    // 删除所有食品经营许可证图片
+    handleDeleteFoodLicenseAll() {
+      this.$confirm('确定要删除所有图片吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning'
+      }).then(() => {
+        // 确保彻底清空 foodLicense 字段
+        this.$set(this.form, 'foodLicense', []);
+        // 同时处理可能存在的字符串情况
+        if (typeof this.form.foodLicense === 'string') {
+          this.form.foodLicense = [];
+        }
+        // 重置上传文件列表
+        this.foodLicenseFileList = [];
+        this.$forceUpdate();
+        this.$message.success('所有图片已删除');
+      }).catch(() => {
+        this.$message.info('已取消删除');
+      });
+    },
+
     // 添加图片预览方法
     previewImage(url) {
       this.previewImageUrl = url;
@@ -762,6 +870,7 @@ export default {
       this.switchValue = false;
       this.switchMedicalValue=false;
       this.form = {
+        foodLicense: [],               // 食品经营许可证文件,用户要求是多张,这里采用数组
         storeId: null,
         cityIds: null,
         storeName: null,
@@ -807,7 +916,6 @@ export default {
         medicalDevice3: null,         // 三类器械经营许可证文件
         medicalDevice3Expiry: null,       // 三类器械经营许可证有效期
         // 其他许可证相关字段
-        foodLicense: null,               // 食品经营许可证文件
         foodLicenseExpiry: null,             // 食品经营许可证有效期
         medicalLicense: null,  // 医疗机构执业许可证文件
         medicalLicenseExpiry: null, // 医疗机构执业许可证有效期
@@ -864,6 +972,12 @@ export default {
         if (valid) {
           // 处理表单数据
           const formData = Object.assign({}, this.form);
+          // 特别处理 foodLicense 字段,将其转换为逗号分隔的字符串
+          if (Array.isArray(formData.foodLicense)) {
+            formData.foodLicense = formData.foodLicense.join(',');
+          } else if (!formData.foodLicense) {
+            formData.foodLicense = ''; // 确保空值处理
+          }
           // 处理城市ID
           if (formData.cityIds) {
             formData.cityIds = formData.cityIds.toString();
@@ -965,6 +1079,18 @@ export default {
       this.reset()
       getStoreInfo().then(response => {
         this.form = response.data;
+        // 处理食品经营许可证字段,将逗号分隔的字符串转换为数组
+        if (this.form.foodLicense) {
+          if (typeof this.form.foodLicense === 'string') {
+            // 如果是逗号分隔的字符串,转换为数组
+            this.form.foodLicense = this.form.foodLicense.split(',').filter(url => url.trim() !== '');
+          } else if (!Array.isArray(this.form.foodLicense)) {
+            // 如果既不是字符串也不是数组,初始化为空数组
+            this.form.foodLicense = [];
+          }
+        } else {
+          this.form.foodLicense = [];
+        }
         if (this.form.isBusinessLicensePermanent == 1) {
           this.switchValue = true;
         }
@@ -1103,6 +1229,71 @@ export default {
 </script>
 
 <style>
+/* 上传区域包装器样式 */
+.upload-area-wrapper {
+  display: inline-block;
+  margin-top: 10px;
+}
+
+/* 小尺寸上传控件样式 */
+.small-uploader .small-placeholder {
+  width: 100px;
+  height: 100px;
+}
+
+.small-uploader .avatar-uploader-icon {
+  font-size: 28px;
+  line-height: 100px;
+}
+
+/* 已上传图片样式 - 更大尺寸 */
+.uploaded-images-preview {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 15px;
+  margin-top: 10px;
+  margin-bottom: 10px;
+}
+
+.image-wrapper {
+  position: relative;
+  display: inline-block;
+}
+
+.uploaded-image {
+  width: 150px;
+  height: 150px;
+  object-fit: cover;
+  border-radius: 6px;
+  border: 1px solid #ddd;
+}
+
+.image-overlay {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 10px;
+  opacity: 0;
+  transition: opacity 0.3s;
+  border-radius: 6px;
+}
+
+.image-wrapper:hover .image-overlay {
+  opacity: 1;
+}
+
+.image-overlay i {
+  color: white;
+  cursor: pointer;
+  font-size: 20px;
+}
+
 /* LOGO上传区域样式优化 */
 .avatar-wrapper {
   position: relative;
@@ -1195,4 +1386,42 @@ export default {
   border-radius: 4px;
 }
 
-</style>
+.thumbnail-wrapper {
+  position: relative;
+  display: inline-block;
+}
+
+.thumbnail-image {
+  width: 60px;
+  height: 60px;
+  object-fit: cover;
+  border-radius: 4px;
+  border: 1px solid #ddd;
+}
+
+.thumbnail-overlay {
+  position: absolute;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background-color: rgba(0, 0, 0, 0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  gap: 5px;
+  opacity: 0;
+  transition: opacity 0.3s;
+  border-radius: 4px;
+}
+
+.thumbnail-wrapper:hover .thumbnail-overlay {
+  opacity: 1;
+}
+
+.thumbnail-overlay i {
+  color: white;
+  cursor: pointer;
+  font-size: 14px;
+}
+</style>