From c3ccabfc59431aea657379c72c2e09c8e1b27d18 Mon Sep 17 00:00:00 2001
From: 董国庆 <364620639@qq.com>
Date: 星期五, 12 九月 2025 15:24:42 +0800
Subject: [PATCH] 图片回显

---
 laboratory/src/components/DynamicComponent/addTableData.vue |  363 ++++++++++++++++++++++++++++++++-------------------
 1 files changed, 224 insertions(+), 139 deletions(-)

diff --git a/laboratory/src/components/DynamicComponent/addTableData.vue b/laboratory/src/components/DynamicComponent/addTableData.vue
index 22fcbb7..de40882 100644
--- a/laboratory/src/components/DynamicComponent/addTableData.vue
+++ b/laboratory/src/components/DynamicComponent/addTableData.vue
@@ -1,6 +1,6 @@
 <template>
   <el-dialog
-    title="添加表数据"
+    :title="isEdit ? '编辑表数据' : '添加表数据'"
     :visible.sync="dialogVisible"
     width="60%"
     :close-on-click-modal="false"
@@ -28,11 +28,23 @@
                 <el-form-item
                   :label="header.name"
                   :prop="header.name"
-                  :rules="{
-                    required: header.required === true || header.required === 'true',
-                    message: header.message || `请输入${header.name}`,
-                    trigger: ['blur', 'change']
-                  }"
+                  :rules="[
+                    {
+                      required: header.required === true || header.required === 'true',
+                      message: header.message || `请输入${header.name}`,
+                      trigger: ['blur', 'change'],
+                    },
+                    {
+                      validator: (rule, value, callback) => {
+                        if ((header.required === true || header.required === 'true') && (!value || value.trim() === '')) {
+                          callback(header.message || `请输入${header.name}`);
+                        } else {
+                          callback();
+                        }
+                      },
+                      trigger: ['blur', 'change'],
+                    }
+                  ]"
                   v-if="header.type == 'text'"
                 >
                   <el-input
@@ -45,33 +57,48 @@
                   :label="header.name"
                   :prop="header.name"
                   :rules="{
-                    required: header.required === true || header.required === 'true',
-                    message: header.message || `请输入${header.name}`,
-                    trigger: ['blur', 'change']
+                    required:
+                      header.required === true || header.required === 'true',
+                    trigger: ['blur', 'change'],
                   }"
+                  class="image-form-item"
                   v-if="header.type == 'image'"
                 >
                   <el-upload
                     class="upload-demo"
-                    action="#"
-                    :file-list="spectrumList"
-                    :auto-upload="false"
+                    :action="uploadUrl"
+                    :headers="uploadHeaders"
+                    :file-list="imageListMap[header.name] || []"
+                    :auto-upload="true"
                     list-type="picture-card"
-                    :on-change="handleSpectrumChange"
-                    :on-remove="handleSpectrumRemove"
+                    :before-upload="beforeImageUpload"
+                    :on-change="(file, fileList) => handleImageChange(file, fileList, header.name)"
+                    :on-remove="(file, fileList) => handleImageRemove(file, fileList, header.name)"
+                    :on-success="(res, file, fileList) => handleImageSuccess(res, file, fileList, header.name)"
+                    :on-preview="handlePreview"
                     :disabled="!checkEditPermission(header)"
+                    multiple
                   >
-                    <i class="el-icon-plus"></i>
-                    <!-- <div slot="tip" class="el-upload__tip">暂未连接服务器,使用默认图片</div> -->
+                    <div
+                      style="
+                        display: flex;
+                        justify-content: center;
+                        flex-direction: column;
+                      "
+                    >
+                      <i class="el-icon-plus"></i>
+                    </div>
+                    <div slot="tip" class="el-upload__tip">只支持.jpg格式</div>
                   </el-upload>
                 </el-form-item>
                 <el-form-item
                   :label="header.name"
                   :prop="header.name"
                   :rules="{
-                    required: header.required === true || header.required === 'true',
+                    required:
+                      header.required === true || header.required === 'true',
                     message: header.message || `请输入${header.name}`,
-                    trigger: ['blur', 'change']
+                    trigger: ['blur', 'change'],
                   }"
                   v-if="header.type == 'date'"
                 >
@@ -82,26 +109,30 @@
                     value-format="yyyy-MM-dd HH:mm:ss"
                     :disabled="!checkEditPermission(header)"
                     :picker-options="{
-                      shortcuts: [{
-                        text: '今天',
-                        onClick(picker) {
-                          picker.$emit('pick', new Date());
-                        }
-                      }, {
-                        text: '昨天',
-                        onClick(picker) {
-                          const date = new Date();
-                          date.setTime(date.getTime() - 3600 * 1000 * 24);
-                          picker.$emit('pick', date);
-                        }
-                      }, {
-                        text: '一周前',
-                        onClick(picker) {
-                          const date = new Date();
-                          date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
-                          picker.$emit('pick', date);
-                        }
-                      }]
+                      shortcuts: [
+                        {
+                          text: '今天',
+                          onClick(picker) {
+                            picker.$emit('pick', new Date());
+                          },
+                        },
+                        {
+                          text: '昨天',
+                          onClick(picker) {
+                            const date = new Date();
+                            date.setTime(date.getTime() - 3600 * 1000 * 24);
+                            picker.$emit('pick', date);
+                          },
+                        },
+                        {
+                          text: '一周前',
+                          onClick(picker) {
+                            const date = new Date();
+                            date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
+                            picker.$emit('pick', date);
+                          },
+                        },
+                      ],
                     }"
                   />
                 </el-form-item>
@@ -109,9 +140,10 @@
                   :label="header.name"
                   :prop="header.name"
                   :rules="{
-                    required: header.required === true || header.required === 'true',
+                    required:
+                      header.required === true || header.required === 'true',
                     message: header.message || `请输入${header.name}`,
-                    trigger: ['blur', 'change']
+                    trigger: ['blur', 'change'],
                   }"
                   v-if="header.type == 'user'"
                 >
@@ -140,11 +172,16 @@
       <el-button @click="handleClose">取 消</el-button>
       <el-button type="primary" @click="handleSubmit">确 定</el-button>
     </div>
+    <el-dialog :visible.sync="imagePreviewVisible" append-to-body>
+      <img width="100%" :src="imagePreviewUrl" alt="" />
+    </el-dialog>
   </el-dialog>
 </template>
-  
+
 <script>
-import { listByRole } from './service';
+import { listByRole } from "./service";
+import { getFullUrl } from "@/utils/utils";
+import apiConfig from "@/utils/baseurl";
 
 export default {
   name: "AddDialog",
@@ -164,18 +201,34 @@
     isEdit: {
       type: Boolean,
       default: false,
-    }
+    },
   },
   data() {
     return {
       isIPad: /iPad/i.test(navigator.userAgent),
-      showHeaderList: [{"name":"sd","type":"text","required":true,"message":"请输入表头名称","role":[]}],
+      showHeaderList: [
+        {
+          name: "sd",
+          type: "text",
+          required: true,
+          message: "请输入表头名称",
+          role: [],
+        },
+      ],
       form: {},
       rules: {},
       photoList: [],
-      spectrumList: [],
-      defaultImageUrl: 'https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg', // 默认图片地址
-      userOptions: []
+      imageList: [],
+      defaultImageUrl:
+        "https://fuss10.elemecdn.com/e/5d/4a731a90594a4af544c0c25941171jpeg.jpeg", // 默认图片地址
+      userOptions: [],
+      imagePreviewVisible: false,
+      imagePreviewUrl: "",
+      uploadUrl: apiConfig.imgUrl,
+      uploadHeaders: {
+        Authorization: sessionStorage.getItem("token") || "",
+      },
+      imageListMap: {},
     };
   },
   computed: {
@@ -188,9 +241,9 @@
       },
     },
     currentUserId() {
-      const userInfo = JSON.parse(sessionStorage.getItem('userInfo') || '{}');
+      const userInfo = JSON.parse(sessionStorage.getItem("userInfo") || "{}");
       return userInfo.userId;
-    }
+    },
   },
   watch: {
     visible: {
@@ -225,18 +278,20 @@
   },
   methods: {
     getUserOptions() {
-      listByRole().then(res => {
-        if (res) {
-          this.userOptions = res.map(user => ({
-            value: user.userId,
-            label: user.nickName || user.userName
-          }));
-        } else {
-          this.$message.error('获取用户列表失败');
-        }
-      }).catch(err => {
-        console.error('获取用户列表失败', err);
-      });
+      listByRole()
+        .then((res) => {
+          if (res) {
+            this.userOptions = res.map((user) => ({
+              value: user.userId,
+              label: user.nickName || user.userName,
+            }));
+          } else {
+            // this.$message.error("获取用户列表失败");
+          }
+        })
+        .catch((err) => {
+          // console.error("获取用户列表失败", err);
+        });
     },
     checkEditPermission(header) {
       if (!header.role || !Array.isArray(header.role)) {
@@ -248,15 +303,18 @@
       // 初始化校验规则
       const rules = {};
       if (this.headerList && this.headerList.length) {
-        this.headerList.forEach(header => {
+        this.headerList.forEach((header) => {
           // 处理required可能是字符串的情况
-          const isRequired = header.required === true || header.required === 'true';
+          const isRequired =
+            header.required === true || header.required === "true";
           if (isRequired) {
-            rules[header.name] = [{
-              required: true,
-              message: header.message || `请输入${header.name}`,
-              trigger: ['blur', 'change']
-            }];
+            rules[header.name] = [
+              {
+                required: true,
+                message: header.message || `请输入${header.name}`,
+                trigger: ["blur", "change"],
+              },
+            ];
           }
         });
       }
@@ -267,20 +325,23 @@
       const formData = {
         updateTime: this.formatDateTime(new Date()),
       };
-      
+
       // 根据headerList初始化表单数据
       if (this.headerList && this.headerList.length) {
-        this.headerList.forEach(header => {
-          if (header.type === 'user') {
+        this.headerList.forEach((header) => {
+          if (header.type === "user") {
             formData[header.name] = [];
+          } else if (header.type === "image") {
+            formData[header.name] = [];
+            this.$set(this.imageListMap, header.name, []);
           } else {
-            formData[header.name] = '';
+            formData[header.name] = "";
           }
         });
       }
-      
+
       // 使用Vue.set确保响应式
-      Object.keys(formData).forEach(key => {
+      Object.keys(formData).forEach((key) => {
         this.$set(this.form, key, formData[key]);
       });
     },
@@ -292,17 +353,20 @@
 
       // 根据headerList设置表单数据
       if (this.headerList && this.headerList.length) {
-        this.headerList.forEach(header => {
-          if (header.type === 'user') {
+        this.headerList.forEach((header) => {
+          if (header.type === "user") {
             formData[header.name] = data[header.name] || [];
+          } else if (header.type === "image") {
+            formData[header.name] = Array.isArray(data[header.name]) ? data[header.name] : (data[header.name] ? [data[header.name]] : []);
+            this.$set(this.imageListMap, header.name, (formData[header.name] || []).map(url => ({ name: "image", url: getFullUrl(url), status: "success" })));
           } else {
-            formData[header.name] = data[header.name] || '';
+            formData[header.name] = data[header.name] || "";
           }
         });
       }
 
       // 使用Vue.set确保响应式
-      Object.keys(formData).forEach(key => {
+      Object.keys(formData).forEach((key) => {
         this.$set(this.form, key, formData[key]);
       });
 
@@ -318,14 +382,15 @@
       }
 
       // 设置图谱列表
-      if (data.spectrums && data.spectrums.length) {
-        this.spectrumList = data.spectrums.map((spectrum) => ({
-          name: spectrum.name,
-          url: spectrum.url,
-          status: "success",
-        }));
-      } else {
-        this.spectrumList = [];
+      this.imageList = [];
+      const imageHeader = this.headerList.find((h) => h.type === "image");
+      if (imageHeader && data[imageHeader.name]) {
+        this.imageList = [
+          {
+            name: "image",
+            url: getFullUrl(data[imageHeader.name]),
+          },
+        ];
       }
 
       // 重置表单校验状态
@@ -335,77 +400,91 @@
     },
     formatDateTime(date) {
       const year = date.getFullYear();
-      const month = String(date.getMonth() + 1).padStart(2, '0');
-      const day = String(date.getDate()).padStart(2, '0');
-      const hours = String(date.getHours()).padStart(2, '0');
-      const minutes = String(date.getMinutes()).padStart(2, '0');
-      const seconds = String(date.getSeconds()).padStart(2, '0');
+      const month = String(date.getMonth() + 1).padStart(2, "0");
+      const day = String(date.getDate()).padStart(2, "0");
+      const hours = String(date.getHours()).padStart(2, "0");
+      const minutes = String(date.getMinutes()).padStart(2, "0");
+      const seconds = String(date.getSeconds()).padStart(2, "0");
       return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
     },
     handleClose() {
       this.dialogVisible = false;
       this.$refs.form?.resetFields();
       this.photoList = [];
-      this.spectrumList = [];
+      this.imageList = [];
       this.initFormData();
     },
     handleSubmit() {
-      
+      console.log('4444444444444')
       this.$refs.form.validate((valid) => {
         if (valid) {
           const submitData = {
             ...this.form,
             photos: this.photoList,
-            spectrums: this.spectrumList,
           };
-          
+
           // 为用户类型字段添加用户完整信息
           if (this.headerList && this.headerList.length) {
-            this.headerList.forEach(header => {
-              if (header.type === 'user' && Array.isArray(submitData[header.name])) {
+            this.headerList.forEach((header) => {
+              if (
+                header.type === "user" &&
+                Array.isArray(submitData[header.name])
+              ) {
                 // 为每个用户类型字段添加userInfo属性,包含用户完整信息
-                submitData[`${header.name}_userInfo`] = submitData[header.name].map(userId => {
-                  const userInfo = this.userOptions.find(user => user.value === userId);
+                submitData[`${header.name}_userInfo`] = submitData[
+                  header.name
+                ].map((userId) => {
+                  const userInfo = this.userOptions.find(
+                    (user) => user.value === userId
+                  );
                   return userInfo ? userInfo : { value: userId, label: userId };
                 });
               }
             });
           }
-          
-          console.log(submitData,'修改的数据')
+
           this.$emit("success", submitData);
           this.handleClose();
         } else {
-          this.$message.error('请填写必填项');
+          this.$message.error("请填写必填项");
         }
       });
     },
-    handlePhotoChange(file, fileList) {
-      this.photoList = fileList;
-      this.$refs.form.validateField("photos");
-    },
-    handleSpectrumChange(file, fileList) {
-      // 使用默认图片替代实际上传
-      this.spectrumList = [{
-        name: '默认图片.jpg',
-        url: this.defaultImageUrl,
-        status: 'success'
-      }];
-      
-      // 同时更新form中对应的字段值以通过表单验证
-      const imageHeader = this.headerList.find(h => h.type === 'image');
-      if (imageHeader && imageHeader.name) {
-        // 保存图片URL,这样在表格中可以直接使用
-        this.$set(this.form, imageHeader.name, this.defaultImageUrl);
-        console.log('设置图片字段:', imageHeader.name, this.defaultImageUrl);
-      }
-      
-      this.$refs.form.validateField("spectrums");
-    },
-    handleSpectrumRemove(file) {
-      this.spectrumList = [];
-    },
+    beforeImageUpload(file) {
+      const isJPG = file.type === "image/jpeg";
+      // const isLt2M = file.size / 1024 / 1024 < 2;
 
+      if (!isJPG) {
+        this.$message.error("上传图片只能是 JPG 格式!");
+        return false;
+      }
+      return true;
+    },
+    handleImageChange(file, fileList, fieldName) {
+      this.$set(this.imageListMap, fieldName, fileList);
+      // 校验
+      this.$refs.form && this.$refs.form.validateField(fieldName);
+    },
+    handleImageSuccess(res, file, fileList, fieldName) {
+      const url = res.msg;
+      file.url = getFullUrl(url);
+      if (!Array.isArray(this.form[fieldName])) {
+        this.$set(this.form, fieldName, []);
+      }
+      // 只保留 fileList 中的 url
+      this.$set(this.form, fieldName, fileList.map(f => f.url ? (f.url.startsWith('http') ? f.url : getFullUrl(f.url)) : ''));
+      this.$set(this.imageListMap, fieldName, fileList);
+      this.$refs.form && this.$refs.form.validateField(fieldName);
+    },
+    handleImageRemove(file, fileList, fieldName) {
+      this.$set(this.form, fieldName, fileList.map(f => f.url ? (f.url.startsWith('http') ? f.url : getFullUrl(f.url)) : ''));
+      this.$set(this.imageListMap, fieldName, fileList);
+    },
+    handlePreview(file) {
+      this.imagePreviewUrl = file.url;
+      this.imagePreviewVisible = true;
+    },
+    getFullUrl,
   },
   mounted() {
     // 获取用户列表数据
@@ -413,7 +492,7 @@
   },
 };
 </script>
-  
+
 <style scoped lang="less">
 ::v-deep .el-dialog__body {
   padding: 0;
@@ -462,7 +541,7 @@
         background: #f5f7fa;
       }
     }
-    .el-form-item::after{
+    .el-form-item::after {
       height: 10px !important;
     }
   }
@@ -488,26 +567,26 @@
       height: 120px;
       line-height: 120px;
     }
-    
+
     .el-upload-list--picture-card {
       display: flex;
       flex-wrap: wrap;
       gap: 8px;
-      
+
       .el-upload-list__item {
         width: 120px;
         height: 120px;
         margin: 0;
       }
     }
-    
+
     // 让上传按钮始终显示在列表最后
     .el-upload--picture-card {
       order: 9999;
       margin: 0;
     }
   }
-  
+
   // 包裹容器也使用flex布局
   display: flex;
   flex-wrap: wrap;
@@ -559,11 +638,17 @@
         background-color: #f5f7fa;
       }
     }
-    .el-upload__tip {
-      color: #909399;
-      font-size: 12px;
-      margin-top: 8px;
-    }
   }
 }
-</style> 
\ No newline at end of file
+.el-upload__tip {
+  color: #909399;
+  font-size: 12px;
+  margin-top: 115px !important;
+  margin-right: -105px !important;
+}
+::v-deep .image-form-item {
+  .el-form-item__error {
+    display: none !important;
+  }
+}
+</style>

--
Gitblit v1.7.1