From 4757a82a4d00198dde15dca7aebb7742f163f52a Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期日, 16 八月 2026 11:20:55 +0800
Subject: [PATCH] fix: 采购台账移除供应商等级

---
 src/views/safeProduction/dangerInvestigation/index.vue |  329 +++++++++++++++++++++++++++++++++++++++++++++++++++---
 1 files changed, 309 insertions(+), 20 deletions(-)

diff --git a/src/views/safeProduction/dangerInvestigation/index.vue b/src/views/safeProduction/dangerInvestigation/index.vue
index a278058..1c74d75 100644
--- a/src/views/safeProduction/dangerInvestigation/index.vue
+++ b/src/views/safeProduction/dangerInvestigation/index.vue
@@ -55,52 +55,82 @@
                          width="60" />
         <el-table-column label="闅愭偅缂栧彿"
                          prop="hiddenCode"
-                         width="180"
-                         show-overflow-tooltip />
+                         width="150"
+                         align="center"
+                         show-overflow-tooltip>
+          <template #default="scope">
+            <el-button class="hidden-code-link"
+                       link
+                       type="primary"
+                       @click="openForm('detail', scope.row)">
+              {{ scope.row.hiddenCode }}
+            </el-button>
+          </template>
+        </el-table-column>
         <el-table-column label="闅愭偅鎻忚堪"
                          prop="hiddenDesc"
+                         width="150"
+                         align="center"
                          show-overflow-tooltip />
         <el-table-column label="闅愭偅鍏蜂綋浣嶇疆"
                          prop="location"
+                         width="150"
+                         align="center"
                          show-overflow-tooltip />
         <el-table-column label="涓婃姤浜�"
                          prop="createUserName"
-                         width="180"
+                         width="150"
+                         align="center"
                          show-overflow-tooltip />
         <el-table-column label="涓婃姤鏃堕棿"
                          prop="createTime"
+                         width="180"
+                         align="center"
                          show-overflow-tooltip />
         <el-table-column label="鏁存敼瀹屾垚鏈熼檺"
                          prop="rectifyTime"
                          width="120"
+                         align="center"
                          show-overflow-tooltip />
         <el-table-column label="鏁存敼璐d换浜�"
                          prop="rectifyUserName"
                          width="120"
+                         align="center"
                          show-overflow-tooltip />
         <el-table-column label="鏁存敼璐d换浜鸿仈绯绘柟寮�"
                          prop="rectifyUserMobile"
-                         width="120"
+                         width="160"
+                         align="center"
                          show-overflow-tooltip />
         <el-table-column label="鏁存敼鍏蜂綋鎺柦"
                          prop="rectifyMeasures"
                          width="120"
+                         align="center"
                          show-overflow-tooltip />
         <el-table-column label="瀹為檯鏁存敼瀹屾垚鏃堕棿"
                          prop="rectifyActualTime"
+                         width="180"
+                         align="center"
+                         show-overflow-tooltip />
+        <el-table-column label="楠屾敹浜�"
+                         prop="verifyUserName"
                          width="120"
+                         align="center"
                          show-overflow-tooltip />
         <el-table-column label="楠屾敹鎰忚"
                          prop="verifyRemark"
                          width="120"
+                         align="center"
                          show-overflow-tooltip />
         <el-table-column label="楠屾敹鏃堕棿"
                          prop="verifyTime"
                          width="120"
+                         align="center"
                          show-overflow-tooltip />
         <el-table-column label="楠屾敹缁撴灉"
                          prop="verifyResult"
                          width="120"
+                         align="center"
                          show-overflow-tooltip>
           <template #default="scope">
             <el-tag v-if="scope.row.verifyResult"
@@ -130,7 +160,7 @@
             <el-button link
                        type="primary"
                        size="small"
-                       :disabled="!scope.row.rectifyActualTime || scope.row.verifyTime"
+                       :disabled="!scope.row.rectifyActualTime || scope.row.verifyTime || scope.row.isVerify"
                        @click="openForm('edit3', scope.row)">楠屾敹</el-button>
           </template>
         </el-table-column>
@@ -160,7 +190,7 @@
             <el-form-item label="闅愭偅缂栧彿锛�"
                           prop="hiddenCode">
               <el-input v-model="form.hiddenCode"
-                        placeholder="淇濆瓨鍚庤嚜鍔ㄧ敓鎴�"
+                        placeholder="鑷姩鐢熸垚"
                         disabled
                         clearable />
             </el-form-item>
@@ -268,11 +298,11 @@
           </el-col>
         </el-row>
       </el-form>
-      <div v-if="operationType === 'edit2' || operationType === 'edit3'"
+      <div v-if="showHiddenDetail"
            class="classtitle">闅愭偅璇︽儏</div>
       <el-descriptions :column="2"
                        style="margin-bottom: 20px;"
-                       v-if="operationType === 'edit2' || operationType === 'edit3'"
+                       v-if="showHiddenDetail"
                        border>
         <el-descriptions-item label="闅愭偅缂栧彿">
           <span class="detail-title">{{ form.hiddenCode }}</span>
@@ -309,11 +339,11 @@
         </el-descriptions-item>
       </el-descriptions>
       <div class="classtitle"
-           v-if="operationType === 'edit3'"
+           v-if="showRectifyDetail"
            style="margin-top: 40px;">鏁存敼璇︽儏</div>
       <el-descriptions :column="2"
                        style="margin-bottom: 20px;"
-                       v-if="operationType === 'edit3'"
+                       v-if="showRectifyDetail"
                        border>
         <el-descriptions-item label="鏁存敼鍏蜂綋鎺柦"
                               :span="2">
@@ -351,6 +381,20 @@
                               type="date"
                               placeholder="璇烽�夋嫨"
                               clearable />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="楠屾敹浜猴細"
+                          prop="verifyUserId">
+              <el-select v-model="form2.verifyUserId"
+                         placeholder="璇烽�夋嫨"
+                         filterable
+                         clearable>
+                <el-option v-for="item in userList"
+                           :key="item.userId"
+                           :label="item.nickName"
+                           :value="item.userId" />
+              </el-select>
             </el-form-item>
           </el-col>
         </el-row>
@@ -402,8 +446,9 @@
             <el-form-item label="楠屾敹浜猴細"
                           prop="verifyUserId">
               <el-select v-model="form3.verifyUserId"
-                         disabled
+                         :disabled="!!form3.verifyUserId"
                          placeholder="璇烽�夋嫨"
+                         filterable
                          clearable>
                 <el-option v-for="item in userList"
                            :key="item.userId"
@@ -414,6 +459,68 @@
           </el-col>
         </el-row>
       </el-form>
+      <div class="classtitle"
+           v-if="showVerifyDetail"
+           style="margin-top: 40px;">楠屾敹璇︽儏</div>
+      <el-descriptions :column="2"
+                       style="margin-bottom: 20px;"
+                       v-if="showVerifyDetail"
+                       border>
+        <el-descriptions-item label="楠屾敹浜�">
+          <span class="detail-title">{{ getVerifyUserName() }}</span>
+        </el-descriptions-item>
+        <el-descriptions-item label="楠屾敹鏃堕棿">
+          <span class="detail-title">{{ form3.verifyTime }}</span>
+        </el-descriptions-item>
+        <el-descriptions-item label="楠屾敹缁撴灉">
+          <el-tag v-if="form3.verifyResult"
+                  :type="form3.verifyResult === '閫氳繃' ? 'success' : 'danger'">
+            {{ form3.verifyResult }}
+          </el-tag>
+        </el-descriptions-item>
+        <el-descriptions-item label="楠屾敹鎰忚"
+                              :span="2">
+          <span class="detail-title">{{ form3.verifyRemark }}</span>
+        </el-descriptions-item>
+      </el-descriptions>
+      <div class="classtitle"
+           v-if="operationType === 'detail'"
+           style="margin-top: 40px;">闄勪欢</div>
+      <div v-if="operationType === 'detail'"
+           v-loading="detailAttachmentLoading"
+           class="detail-attachment-preview-list">
+        <el-empty v-if="!detailAttachmentLoading && detailAttachmentList.length === 0"
+                  description="鏆傛棤闄勪欢"
+                  :image-size="80" />
+        <div v-for="item in detailAttachmentList"
+             :key="item.storageAttachmentId || item.id || getAttachmentPreviewUrl(item)"
+             class="detail-attachment-preview-card">
+          <div class="detail-attachment-header">
+            <span class="detail-attachment-name">{{ getAttachmentName(item) }}</span>
+            <el-button link
+                       type="primary"
+                       size="small"
+                       @click="downloadDetailAttachment(item)">涓嬭浇</el-button>
+          </div>
+          <el-image v-if="isImageAttachment(item)"
+                    class="detail-attachment-image"
+                    :src="getAttachmentPreviewUrl(item)"
+                    :preview-src-list="detailPreviewImageUrls"
+                    :initial-index="getImagePreviewIndex(item)"
+                    fit="contain"
+                    preview-teleported />
+          <iframe v-else-if="isPdfAttachment(item)"
+                  class="detail-attachment-frame"
+                  :src="getAttachmentPreviewUrl(item)" />
+          <div v-else
+               class="detail-attachment-placeholder">
+            <span>璇ユ枃浠剁被鍨嬫殏涓嶆敮鎸佸唴宓岄瑙�</span>
+            <el-button link
+                       type="primary"
+                       @click="downloadDetailAttachment(item)">涓嬭浇鏌ョ湅</el-button>
+          </div>
+        </div>
+      </div>
     </FormDialog>
     <FileListDialog
         v-if="fileListDialogVisible"
@@ -433,6 +540,7 @@
   import { userListNoPage } from "@/api/system/user.js";
   import FormDialog from "@/components/Dialog/FormDialog.vue";
   import { getQuotationList } from "@/api/salesManagement/salesQuotation.js";
+  import { attachmentList } from "@/api/basicData/storageAttachment.js";
   import {
     dangerInvestigationListPage,
     safeHiddenAdd,
@@ -449,6 +557,8 @@
   const selectedRows = ref([]);
   const userList = ref([]);
   const tableLoading = ref(false);
+  const detailAttachmentList = ref([]);
+  const detailAttachmentLoading = ref(false);
   const currentRecordId = ref(0);
   const page = reactive({
     current: 1,
@@ -464,6 +574,8 @@
       return "鏁存敼椤甸潰";
     } else if (type === "edit3") {
       return "楠屾敹椤甸潰";
+    } else if (type === "detail") {
+      return "闅愭偅璇︽儏";
     }
   };
   // 鑾峰彇绫诲瀷鏍囩绫诲瀷
@@ -511,11 +623,13 @@
   const rules2 = {
     rectifyActualTime: [{ required: true, message: "璇烽�夋嫨", trigger: "blur" }],
     rectifyMeasures: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    verifyUserId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
   };
   const rules3 = {
     verifyTime: [{ required: true, message: "璇烽�夋嫨", trigger: "blur" }],
     verifyRemark: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
     verifyResult: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    verifyUserId: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
     acceptDesc: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
   };
   const { hidden_danger_type } = proxy.useDict("hidden_danger_type");
@@ -527,6 +641,7 @@
   const form2 = ref({
     rectifyActualTime: "", // 瀹為檯鏁存敼瀹屾垚鏃堕棿
     rectifyMeasures: "", // 鏁存敼鍏蜂綋鎺柦
+    verifyUserId: "", // 楠屾敹浜�
   });
   const form3 = ref({
     verifyTime: "", // 楠屾敹鏃堕棿
@@ -536,6 +651,21 @@
     verifyUserName: "",
     verifyResult: "", // 楠屾敹缁撴灉
   });
+  const showHiddenDetail = computed(() => ["edit2", "edit3", "detail"].includes(operationType.value));
+  const showRectifyDetail = computed(
+    () =>
+      operationType.value === "edit3" ||
+      (operationType.value === "detail" && (form2.value.rectifyMeasures || form2.value.rectifyActualTime))
+  );
+  const showVerifyDetail = computed(
+    () =>
+      operationType.value === "detail" &&
+      (form3.value.verifyUserId ||
+        form3.value.verifyUserName ||
+        form3.value.verifyRemark ||
+        form3.value.verifyTime ||
+        form3.value.verifyResult)
+  );
   const riskLevelList = ref([
     {
       value: "閲嶅ぇ椋庨櫓",
@@ -572,6 +702,60 @@
       form.value.rectifyUserName = selectedUser.nickName;
       form.value.rectifyUserMobile = selectedUser.phonenumber;
     }
+  };
+
+  const hasUserId = userId => userId !== null && userId !== undefined && userId !== "" && userId !== "null";
+  const normalizeUserId = userId => (hasUserId(userId) ? Number(userId) : "");
+  const getVerifyUserName = () => {
+    if (form3.value.verifyUserName) {
+      return form3.value.verifyUserName;
+    }
+    const selectedUser = userList.value.find(user => Number(user.userId) === Number(form3.value.verifyUserId));
+    return selectedUser?.nickName || selectedUser?.userName || "";
+  };
+  const getAttachmentName = row => row?.originalFilename || row?.fileName || row?.name || "";
+  const getAttachmentPreviewUrl = row => row?.previewURL || row?.previewUrl || row?.url || row?.downloadURL || row?.downloadUrl || "";
+  const getAttachmentDownloadUrl = row => row?.downloadURL || row?.downloadUrl || row?.previewURL || row?.previewUrl || row?.url || "";
+  const getAttachmentTypeText = row => `${getAttachmentName(row)} ${getAttachmentPreviewUrl(row)}`.toLowerCase().split("?")[0];
+  const isImageAttachment = row => /\.(jpg|jpeg|png|gif|bmp|webp|svg)$/.test(getAttachmentTypeText(row));
+  const isPdfAttachment = row => /\.pdf$/.test(getAttachmentTypeText(row));
+  const isRectifiedRecord = row =>
+    !!(row?.rectifyActualTime || row?.rectifyMeasures || row?.verifyTime || row?.verifyResult || row?.verifyRemark);
+  const detailPreviewImageUrls = computed(() =>
+    detailAttachmentList.value
+      .filter(isImageAttachment)
+      .map(getAttachmentPreviewUrl)
+      .filter(Boolean)
+  );
+  const getImagePreviewIndex = row => {
+    const index = detailPreviewImageUrls.value.indexOf(getAttachmentPreviewUrl(row));
+    return index > -1 ? index : 0;
+  };
+  const loadDetailAttachments = recordId => {
+    detailAttachmentLoading.value = true;
+    detailAttachmentList.value = [];
+    return attachmentList({
+      recordType: "safe_hidden",
+      recordId,
+    })
+      .then(res => {
+        detailAttachmentList.value = res?.data || [];
+      })
+      .catch(() => {
+        detailAttachmentList.value = [];
+        ElMessage.error("闄勪欢鍔犺浇澶辫触");
+      })
+      .finally(() => {
+        detailAttachmentLoading.value = false;
+      });
+  };
+  const downloadDetailAttachment = row => {
+    const url = getAttachmentDownloadUrl(row);
+    if (!url) {
+      ElMessage.warning("鏂囦欢鍦板潃鏃犳晥锛屾棤娉曚笅杞�");
+      return;
+    }
+    window.open(url, "_blank");
   };
 
   // 瀵煎叆鐩稿叧
@@ -657,6 +841,7 @@
           } else {
             item.isRectify = false;
           }
+          item.isVerify = hasUserId(item.verifyUserId) && Number(item.verifyUserId) != Number(currentUserId.value);
         });
         return res;
       })
@@ -689,15 +874,18 @@
   const openForm = async (type, row) => {
     console.log("row", row);
     operationType.value = type;
+    detailAttachmentList.value = [];
     form3.value = {
       verifyTime: "", // 楠屾敹鏃堕棿
       verifyRemark: "", // 楠屾敹澶囨敞
       verifyResult: "", // 楠屾敹鎻忚堪
       verifyUserId: "", // 楠屾敹浜�
+      verifyUserName: "",
     };
     form2.value = {
       rectifyActualTime: "", // 瀹為檯鏁存敼瀹屾垚鏃堕棿
       rectifyMeasures: "", // 鏁存敼鍏蜂綋鎺柦
+      verifyUserId: "", // 楠屾敹浜�
     };
     if (type === "add") {
       form.value = {
@@ -749,6 +937,7 @@
       form2.value = {
         rectifyActualTime: row.rectifyActualTime, // 瀹為檯鏁存敼瀹屾垚鏃堕棿
         rectifyMeasures: row.rectifyMeasures, // 鏁存敼鍏蜂綋鎺柦
+        verifyUserId: normalizeUserId(row.verifyUserId), // 楠屾敹浜�
       };
     } else if (type === "edit3") {
       form.value = {
@@ -774,15 +963,41 @@
         verifyTime: row.verifyTime, // 楠屾敹鏃堕棿
         verifyRemark: row.verifyRemark, // 楠屾敹澶囨敞
         verifyResult: row.verifyResult, // 楠屾敹鎻忚堪
-        verifyUserId: row.verifyUserId, // 楠屾敹浜�
+        verifyUserId: normalizeUserId(row.verifyUserId), // 楠屾敹浜�
+        verifyUserName: row.verifyUserName,
       };
-      console.log("form3.value", form3.value);
-      if (!form3.value.verifyUserId || form3.value.verifyUserId === "null") {
-        form3.value.verifyUserId = Number(currentUserId.value); // 楠屾敹浜�
-      }
       if (!form3.value.verifyTime || form3.value.verifyTime === "null") {
         form3.value.verifyTime = dayjs().format("YYYY-MM-DD"); // 楠屾敹鎻忚堪
       }
+    } else if (type === "detail") {
+      form.value = {
+        id: row.id,
+        hiddenCode: row.hiddenCode, // 闅愭偅缂栧彿
+        location: row.location, // 闅愭偅浣嶇疆
+        hiddenDesc: row.hiddenDesc, // 闅愭偅鎻忚堪
+        createUser: row.createUser, // 涓婃姤浜�
+        createUserName: row.createUserName,
+        createTime: row.createTime, // 涓婃姤鏃堕棿
+        rectifyUserId: row.rectifyUserId, // 鏁存敼璐d换浜�
+        rectifyUserName: row.rectifyUserName,
+        rectifyTime: row.rectifyTime, // 鏁存敼瀹屾垚鏈熼檺
+        rectifyUserMobile: row.rectifyUserMobile, // 鏁存敼璐d换浜烘墜鏈哄彿
+        riskLevel: row.riskLevel, // 闅愭偅椋庨櫓绛夌骇
+        type: row.type, // 闅愭偅绫诲瀷
+      };
+      form2.value = {
+        rectifyActualTime: row.rectifyActualTime, // 瀹為檯鏁存敼瀹屾垚鏃堕棿
+        rectifyMeasures: row.rectifyMeasures, // 鏁存敼鍏蜂綋鎺柦
+        verifyUserId: normalizeUserId(row.verifyUserId), // 楠屾敹浜�
+      };
+      form3.value = {
+        verifyTime: row.verifyTime, // 楠屾敹鏃堕棿
+        verifyRemark: row.verifyRemark, // 楠屾敹澶囨敞
+        verifyResult: row.verifyResult, // 楠屾敹鎻忚堪
+        verifyUserId: normalizeUserId(row.verifyUserId), // 楠屾敹浜�
+        verifyUserName: row.verifyUserName,
+      };
+      loadDetailAttachments(row.id);
     }
     dialogFormVisible.value = true;
   };
@@ -845,9 +1060,9 @@
       proxy.$refs["formRef3"].validate(valid => {
         if (valid) {
           safeHiddenUpdate({
-            ...form3.value,
             ...form2.value,
             ...form.value,
+            ...form3.value,
           }).then(res => {
             proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
             closeDia();
@@ -861,6 +1076,9 @@
   const closeDia = () => {
     proxy.resetForm("formRef");
     proxy.resetForm("formRef2");
+    proxy.resetForm("formRef3");
+    detailAttachmentList.value = [];
+    detailAttachmentLoading.value = false;
     dialogFormVisible.value = false;
   };
   // 鍏抽棴浜у搧寮规
@@ -872,12 +1090,18 @@
   const handleDelete = () => {
     let ids = [];
     if (selectedRows.value.length > 0) {
+      const rectifiedRows = selectedRows.value.filter(isRectifiedRecord);
+      if (rectifiedRows.length > 0) {
+        const hiddenCodes = rectifiedRows.map(item => item.hiddenCode).filter(Boolean).join("銆�");
+        proxy.$modal.msgWarning(`宸叉暣鏀圭殑闅愭偅涓嶈兘鍒犻櫎${hiddenCodes ? `锛�${hiddenCodes}` : ""}`);
+        return;
+      }
       ids = selectedRows.value.map(item => item.id);
     } else {
       proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
       return;
     }
-    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "瀵煎嚭", {
+    ElMessageBox.confirm("閫変腑鐨勬湭鏁存敼闅愭偅鍙婂叾闄勪欢灏嗚鍒犻櫎锛屾槸鍚︾‘璁ゅ垹闄わ紵", "鎻愮ず", {
       confirmButtonText: "纭",
       cancelButtonText: "鍙栨秷",
       type: "warning",
@@ -964,8 +1188,8 @@
     return "";
   };
 
-  onMounted(() => {
-    getCurrentFactoryName();
+  onMounted(async () => {
+    await getCurrentFactoryName();
     getList();
     userListNoPage().then(res => {
       userList.value = res.data;
@@ -1003,6 +1227,71 @@
     justify-content: space-between;
     margin-bottom: 10px;
   }
+  .hidden-code-link {
+    height: auto;
+    padding: 0;
+    font-weight: 500;
+  }
+  .detail-attachment-preview-list {
+    min-height: 120px;
+    margin-bottom: 20px;
+    display: grid;
+    grid-template-columns: repeat(auto-fill, minmax(220px, 260px));
+    gap: 12px;
+    align-items: start;
+  }
+  .detail-attachment-preview-card {
+    border: 1px solid #e5eaf3;
+    border-radius: 6px;
+    overflow: hidden;
+    background: #fff;
+  }
+  .detail-attachment-header {
+    min-height: 36px;
+    padding: 6px 12px;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    gap: 12px;
+    border-bottom: 1px solid #e5eaf3;
+    background: #f7f9fc;
+  }
+  .detail-attachment-name {
+    min-width: 0;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    font-weight: 500;
+    color: #303133;
+  }
+  .detail-attachment-image {
+    width: 100%;
+    height: 160px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    background: #fafafa;
+  }
+  .detail-attachment-frame {
+    width: 100%;
+    height: 180px;
+    border: 0;
+    display: block;
+    background: #fafafa;
+  }
+  .detail-attachment-placeholder {
+    min-height: 120px;
+    padding: 12px;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 12px;
+    color: #606266;
+    background: #fafafa;
+  }
+  .detail-attachment-preview-list :deep(.el-empty) {
+    grid-column: 1 / -1;
+  }
   .print-preview-dialog {
     .el-dialog__body {
       padding: 0;

--
Gitblit v1.9.3