From e3686634452289d43e750a44f30f72b0e7754866 Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期六, 07 十一月 2026 00:26:56 +0800
Subject: [PATCH] 修复人员管理模块各标签页问题并完善设备、文件受控页面

---
 src/views/CNAS/systemManagement/documentControl/components/ControlledFileApplication.vue |  195 ++++++++++++++++++++++++++++++------------------
 1 files changed, 123 insertions(+), 72 deletions(-)

diff --git a/src/views/CNAS/systemManagement/documentControl/components/ControlledFileApplication.vue b/src/views/CNAS/systemManagement/documentControl/components/ControlledFileApplication.vue
index 01408d9..814c062 100644
--- a/src/views/CNAS/systemManagement/documentControl/components/ControlledFileApplication.vue
+++ b/src/views/CNAS/systemManagement/documentControl/components/ControlledFileApplication.vue
@@ -4,7 +4,7 @@
     <div style="display: flex;justify-content: space-between">
       <div style="display: flex;">
         <div style="margin-bottom: 18px;margin-right: 10px;display: flex;align-items: center;line-height: 32px;">
-          <span style="width: 128px;font-size: 14px;font-weight: 700;color: #606266;">鐢宠鏂囦欢缂栧彿</span>
+          <span style="width: 128px;font-size: 14px;font-weight: 700;color: var(--lims-text-2);">鐢宠鏂囦欢缂栧彿</span>
           <el-input size="small" placeholder="璇疯緭鍏�" clearable v-model="queryParams.documentCode"
                     @keyup.enter="refreshTable()"></el-input>
         </div>
@@ -14,8 +14,9 @@
         </div>
       </div>
       <div style="line-height: 30px;">
+        <el-button size="small" @click="$refs.importDialog.open()">瀵� 鍏�</el-button>
         <el-button size="small" type="primary" :icon="$icon('el-icon-plus')"
-                   @click="addDialogVisible = true, addInfo = {}, file = null">鏂囦欢鍙楁帶鐢宠</el-button>
+                   @click="addDialogVisible = true, addInfo = {}, file = null, fileList = []">鏂囦欢鍙楁帶鐢宠</el-button>
       </div>
     </div>
     <div class="table">
@@ -71,7 +72,9 @@
           <div class="search_thing">
             <div class="search_label">涓婁紶闄勪欢锛�</div>
             <div class="search_input"><el-upload style="margin: 8px 0 0px 50px;" action="#" :auto-upload="false"
-                :multiple="false" accept='.pdf' :on-change="handleChangeUpload" v-if="addDialogVisible">
+                :multiple="false" accept='.pdf,.doc,.docx,.xls,.xlsx,.ppt,.pptx,.wps,.et,.dps,.txt,.jpg,.jpeg,.png'
+                :file-list="fileList" :on-change="handleChangeUpload" :on-remove="handleRemoveUpload"
+                :before-remove="beforeRemoveUpload" :on-preview="handlePreviewUpload" v-if="addDialogVisible">
                 <el-button size="small" type="primary">涓婁紶闄勪欢</el-button>
               </el-upload></div>
           </div>
@@ -90,15 +93,25 @@
         </el-col>
         <el-col :span="12" style="margin-bottom: 16px;">
           <div class="search_thing">
-            <div class="search_label">鎻愪氦鏃ユ湡锛�</div>
+            <div class="search_label">鍙戝竷鏃ユ湡锛�</div>
             <div class="search_input">
-              <el-date-picker v-model="addInfo.submitDate" type="date" size="small" placeholder="閫夋嫨鏃ユ湡"
+              <el-date-picker v-model="addInfo.publishDate" type="date" size="small" placeholder="閫夋嫨鏃ユ湡"
                 format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 100%;">
               </el-date-picker>
             </div>
           </div>
         </el-col>
         <el-col :span="12" style="margin-bottom: 16px;">
+          <div class="search_thing">
+            <div class="search_label">瀹炴柦鏃ユ湡锛�</div>
+            <div class="search_input">
+              <el-date-picker v-model="addInfo.implementDate" type="date" size="small" placeholder="閫夋嫨鏃ユ湡"
+                format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width: 100%;">
+              </el-date-picker>
+            </div>
+          </div>
+        </el-col>
+        <el-col :span="24" style="margin-bottom: 16px;">
           <div class="search_thing">
             <div class="search_label">璇存槑锛�</div>
             <div class="search_input"><el-input size="small" placeholder="璇疯緭鍏�" clearable v-model="addInfo.instructions"
@@ -116,7 +129,7 @@
         style="height: 90vh;overflow-y: auto;" />
     </el-dialog>
     <el-dialog title="瀹℃牳" v-model="checkDialogVisible" width="1000px" top="5vh">
-      <UpPdfStamp ref="UpPdfStamp" v-if="checkDialogVisible" @uploadPDF="uploadPDF" :isUpFile="false"></UpPdfStamp>
+      <UpPdfStamp ref="UpPdfStamp" v-if="checkDialogVisible" @uploadPDF="uploadPDF" @uploadPDFErr="handlePdfError" :isUpFile="false"></UpPdfStamp>
       <template #footer><span  class="dialog-footer">
         <el-button @click="handleCheckSub('涓嶉�氳繃')" :loading="noCheckLoading">涓嶉�氳繃</el-button>
         <el-button type="primary" @click="handleCheckSub('閫氳繃')" :loading="checkLoading">閫� 杩�</el-button>
@@ -133,6 +146,16 @@
         <el-button type="primary" @click="handleCheck0(currentInfo)">纭� 瀹�</el-button>
       </span></template>
     </el-dialog>
+    <import-dialog
+      ref="importDialog"
+      title="瀵煎叆鏂囦欢鍙楁帶鐢宠"
+      :action="importAction"
+      accept=".xls,.xlsx"
+      template-url="/import-templates/鏂囦欢鍙楁帶鐢宠瀵煎叆妯℃澘.xlsx?v=1"
+      template-name="鏂囦欢鍙楁帶鐢宠瀵煎叆妯℃澘.xlsx"
+      :tips="['琛ㄥご蹇呴』涓庢ā鏉垮畬鍏ㄤ竴鑷达紝涓嶈兘澧炲垹鍒楁垨淇敼鍒楀悕', '鍙戝竷鏃ユ湡銆佸疄鏂芥棩鏈熸牸寮忥細YYYY-MM-DD', '瀵煎叆鍚庣姸鎬佷负鑽夌锛岀敵璇蜂汉涓虹┖锛屽彲鍦ㄩ〉闈笂缂栬緫']"
+      @success="refreshTable"
+    />
   </div>
 </template>
 
@@ -140,6 +163,7 @@
 import UpPdfStamp from '@/components/UpPdfStamp/index.vue'
 import filePreview from '@/components/Preview/filePreview.vue'
 import limsTable from "@/components/Table/lims-table.vue";
+import ImportDialog from '@/components/ImportDialog/index.vue'
 import {
   selectUserCondition,
 } from "@/api/business/inspectionTask.js";
@@ -159,10 +183,14 @@
   components: {
     filePreview,
     UpPdfStamp,
-    limsTable
+    limsTable,
+    ImportDialog
   },
   computed: {
     ...mapGetters(["nickName"]),
+    importAction() {
+      return this.javaApi + '/manageDocumentControlled/importManageDocumentControlled'
+    }
   },
   data() {
     return {
@@ -177,6 +205,7 @@
       personList: [],
       fileType: [],
       file: null,
+      fileList: [],
       currentInfo: {},
       checkLoading: false,
       noCheckLoading: false,
@@ -204,13 +233,16 @@
             }
           },
         },
+        { label: "鏂囦欢鍚嶇О", prop: "name", minWidth: "160" },
+        { label: "鏂囦欢鐗堟湰", prop: "version", width: "100px" },
+        { label: "鍙戝竷鏃ユ湡", prop: "publishDate", width: "110px" },
+        { label: "瀹炴柦鏃ユ湡", prop: "implementDate", width: "110px" },
         {
           label: "鐢宠浜�",
           prop: "createUserName",
         },
         { label: "鐢宠鏃堕棿", prop: "createTime" },
         { label: "璇存槑", prop: "instructions" },
-        { label: "鎻愪氦鏃ユ湡", prop: "submitDate" },
         { label: "璐d换浜�", prop: "dutyUserName" },
         {
           label: "鐢宠鐘舵��", prop: "state", dataType: "tag",
@@ -247,8 +279,11 @@
                 this.handleCheck(row);
               },
               disabled: (row) => {
+                if (row.state == '閫氳繃') {
+                  return true
+                }
                 if(row.dutyUserName != null && row.dutyUserName != "") {
-                  return !row.dutyUserName.includes(this.nickName) || row.state == '閫氳繃'
+                  return !row.dutyUserName.includes(this.nickName)
                 }else {
                   return false
                 }
@@ -286,7 +321,7 @@
       page: {
         total: 0,
         size: 10,
-        current: 0,
+        current: 1,
       },
       tableLoading: false,
     }
@@ -350,76 +385,79 @@
       });
     },
     // 鎻愪氦
+    buildFormData() {
+      const fd = new FormData()
+      // 鏂囦欢淇℃伅涓� raw 鎵嶆槸鐪熺殑鏂囦欢
+      if (this.file) {
+        fd.append("file", this.file.raw)
+      }
+      const fields = ['id', 'documentCode', 'dutyUser', 'type', 'name', 'version', 'writer',
+        'publishDate', 'implementDate', 'instructions']
+      fields.forEach((key) => {
+        const value = this.addInfo[key]
+        // 绌烘棩鏈�/绌轰笅鎷変笉浼狅紝閬垮厤鍚庣鏃ユ湡鎴栨暟瀛楀瓧娈佃В鏋愬け璐�
+        if (value !== undefined && value !== null && value !== '') {
+          fd.append(key, value)
+        }
+      })
+      return fd
+    },
     handleAdd() {
       if (!this.addInfo.documentCode) return this.$message({ type: 'error', message: "璇疯緭鍏ョ紪鍙�" })
-      if (!this.addInfo.id) {
-        // 鏂板
-        let fd = new FormData();
-        //鏂囦欢淇℃伅涓璻aw鎵嶆槸鐪熺殑鏂囦欢
-        if (this.file) {
-          fd.append("file", this.file.raw);
+      const isEdit = !!this.addInfo.id
+      const request = isEdit ? doManageDocumentControlled : addManageDocumentControlled
+      this.addLoading = true
+      request(this.buildFormData()).then(res => {
+        this.addLoading = false
+        if (res.code == 200) {
+          this.$message({
+            type: 'success',
+            message: isEdit ? '淇敼鎴愬姛' : '娣诲姞鎴愬姛'
+          })
+          this.refreshTable()
+          this.addDialogVisible = false
+        } else {
+          this.$message({
+            type: 'error',
+            message: isEdit ? '淇敼澶辫触' : '娣诲姞澶辫触'
+          })
         }
-        for (let m in this.addInfo) {
-          fd.append(m, this.addInfo[m])
-        }
-        this.addLoading = true
-        addManageDocumentControlled(fd).then(res => {
-          this.addLoading = false
-          if (res.code == 200) {
-            this.$message({
-              type: 'success',
-              message: '娣诲姞鎴愬姛'
-            })
-            this.refreshTable()
-            this.addDialogVisible = false
-          } else {
-            this.$message({
-              type: 'error',
-              message: '娣诲姞澶辫触'
-            })
-          }
-        })
-      } else {
-        // 淇敼
-        let { id, documentCode, dutyUser, type, name, version, writer, submitDate, instructions } = this.addInfo
-        let fd = new FormData();
-        //鏂囦欢淇℃伅涓璻aw鎵嶆槸鐪熺殑鏂囦欢
-        if (this.file) {
-          fd.append("file", this.file.raw);
-        }
-        fd.append("id", id);
-        fd.append("documentCode", documentCode);
-        fd.append("dutyUser", dutyUser);
-        fd.append("type", type);
-        fd.append("name", name);
-        fd.append("version", version);
-        fd.append("writer", writer);
-        fd.append("submitDate", submitDate);
-        fd.append("instructions", instructions);
-        this.addLoading = true
-        doManageDocumentControlled(fd).then(res => {
-          this.addLoading = false
-          if (res.code == 200) {
-            this.refreshTable()
-            this.addDialogVisible = false
-          } else {
-            this.$message({
-              type: 'error',
-              message: '娣诲姞澶辫触'
-            })
-          }
-        })
-      }
+      }).catch(() => {
+        this.addLoading = false
+      })
     },
     handleChangeUpload(file, fileLists) {
       this.file = file
       this.addInfo['name'] = file.name
+    },
+    // 绉婚櫎鏂伴�夌殑闄勪欢鍚庝笉鍐嶄笂浼狅紱鍘熸湁闄勪欢涓嶅厑璁稿湪杩欓噷鍒犻櫎锛屽彧鑳介�夋嫨鏂伴檮浠舵浛鎹�
+    handleRemoveUpload() {
+      this.file = null
+    },
+    beforeRemoveUpload(file) {
+      if (file && !file.raw) {
+        this.$message.warning('閫夋嫨鏂伴檮浠朵繚瀛樺悗浼氳嚜鍔ㄦ浛鎹㈠師闄勪欢')
+        return false
+      }
+      return true
+    },
+    handlePreviewUpload(file) {
+      if (file && file.url) {
+        this.$download.saveAs(file.url, file.name)
+      }
+    },
+    fileNameFromUrl(url) {
+      return (url || '').replace(/^[0-9a-fA-F-]{36}_/, '')
     },
     // 缂栬緫
     handleUpdate(row) {
       this.title = '鏂囦欢鍙樻洿鐢宠'
       this.addInfo = this.HaveJson(row)
       this.file = null
+      // 鍥炴樉宸蹭笂浼犵殑闄勪欢锛屼繚瀛樻椂鏈噸鏂伴�夋嫨鍒欎繚鐣欏師闄勪欢
+      this.fileList = row.url
+        ? [{ name: this.fileNameFromUrl(row.url), url: this.javaApi + '/word/' + row.url }]
+        : []
       this.addDialogVisible = true
     },
     // 鏌ョ湅闄勪欢
@@ -437,21 +475,30 @@
     handleCheck0(row) {
       this.checkStampDialogVisible = false
       this.checkDialogVisible = true
-      checkManageDocumentControlledPdf({ id: row.id }).then(res => {
-        const blob = new Blob([res]);
+      checkManageDocumentControlledPdf({ id: row.id }).then(async res => {
+        // 鍚庣杞� PDF 澶辫触鏃朵細杩斿洖 JSON 閿欒锛宐lob 閲屽氨涓嶆槸 PDF
+        if (res.type && res.type.includes('json')) {
+          const data = JSON.parse(await res.text())
+          this.$message.error(data.msg || '闄勪欢杞崲棰勮澶辫触')
+          this.checkDialogVisible = false
+          return
+        }
+        const blob = new Blob([res], { type: 'application/pdf' });
         const file = new File([blob], row.name, { type: 'application/pdf' })
         this.$refs.UpPdfStamp.lookFile(file, this.currentStamp)
       }).catch(err => {
+        this.checkDialogVisible = false
         console.log(err)
       })
     },
     handleDown(row) {
       if (!row.url) return this.$message.warning('鏂囦欢鏈笂浼�')
-      this.$download.saveAs(row.url, row.url);
+      const fileName = row.url.replace(/^[0-9a-fA-F-]{36}_/, '')
+      this.$download.saveAs(this.javaApi + '/word/' + row.url, fileName);
     },
     async uploadPDF(pdfBlob) {
       const formData = new FormData();
-      formData.append('file', pdfBlob, this.fileName + '.pdf'); // 鏂囦欢瀛楁
+      formData.append('file', pdfBlob, (this.currentInfo.name || 'controlled') + '.pdf'); // 鏂囦欢瀛楁
       formData.append('id', this.currentInfo.id); // 鏂囦欢鍚嶅瓧娈�
       formData.append('state', this.type); // 鏂囦欢鍚嶅瓧娈�
       formData.append('writer', this.currentInfo.writer); // 鏂囦欢鍚嶅瓧娈�
@@ -483,9 +530,13 @@
       } else {
         this.noCheckLoading = true
       }
-      this.addLoading = true
       this.$refs['UpPdfStamp'].generatePDF()
     },
+    // 棰勮澶辫触鎴栨病閫夋枃浠舵椂澶嶄綅鎸夐挳锛岄伩鍏嶁�滈�氳繃鈥濅竴鐩磋浆鍦�
+    handlePdfError() {
+      this.checkLoading = false
+      this.noCheckLoading = false
+    },
     handleDelete(row) {
       this.$confirm("鏄惁鍒犻櫎璇ユ潯鏁版嵁?", "鎻愮ず", {
         confirmButtonText: "纭畾",

--
Gitblit v1.9.3