From d4d34a9b730ac328068f936598d4138ac2635e57 Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期四, 15 十月 2026 11:21:08 +0800
Subject: [PATCH] 质量监督计划:新增计划下发(列表下发状态列与下发按钮,仅已批准未下发的可下发),导出弹窗改卡片式并拦截导出错误响应避免下载损坏文件,日常监督检查记录单按纸质表重做(受监督人多选、监督员下拉、监督内容多选、监督记录、存在问题、整改意见),各表单人员列表改为全实验室不按部门筛选;方法验证:表单新增数据处理、质量控制方法、方法结果验证、验证结论及评审、审批意见字段并新增详情入口,迁移原标准方法变更的设备、检测记录、校准文件、工作证等查看组件,标准方法变更模块下线;设备档案、设备管理编辑弹窗改版为图片与基本信息左右布局、表单行式排列

---
 src/views/CNAS/process/ensureResults/qualityControlPlan/index.vue |  186 +++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 164 insertions(+), 22 deletions(-)

diff --git a/src/views/CNAS/process/ensureResults/qualityControlPlan/index.vue b/src/views/CNAS/process/ensureResults/qualityControlPlan/index.vue
index 41565fe..6df53e6 100644
--- a/src/views/CNAS/process/ensureResults/qualityControlPlan/index.vue
+++ b/src/views/CNAS/process/ensureResults/qualityControlPlan/index.vue
@@ -74,12 +74,43 @@
         <el-button :loading="ratifyLoading" type="primary" @click="handleRatify(1)">鎵� 鍑�</el-button>
       </span></template>
     </el-dialog>
-    <el-dialog v-model="downloadDialog" title="瀵煎嚭" width="600px">
-      <span>
-        <el-button plain type="primary" :disabled="download.recordStatus !== 3" @click="controlDown">璁板綍鍗曞鍑�</el-button>
-        <el-button plain type="primary" :disabled="download.accordingStatus !== 3" @click="processingDown">澶勭悊鍗曞鍑�</el-button>
-        <el-button plain type="primary" :disabled="download.correctStatus !== 3" @click="supervisoryDown">绾犳鍗曞鍑�</el-button>
-      </span>
+    <el-dialog v-model="downloadDialog" title="瀵煎嚭" width="640px">
+      <div class="doc-card">
+        <div class="doc-card-head">
+          <span class="doc-card-name">鏃ュ父鐩戠潱妫�鏌ヨ褰曡〃锛堣褰曞崟锛�</span>
+          <el-tag :type="download.recordStatus === 3 ? 'success' : 'info'" size="small">
+            {{ download.recordStatus === 3 ? '宸叉壒鍑�' : '鏈壒鍑�' }}
+          </el-tag>
+        </div>
+        <div class="doc-card-foot">
+          <el-button type="primary" :disabled="download.recordStatus !== 3" @click="controlDown">瀵� 鍑�</el-button>
+        </div>
+      </div>
+      <div class="doc-card">
+        <div class="doc-card-head">
+          <span class="doc-card-name">涓嶇鍚堝伐浣滄帶鍒跺崟锛堝鐞嗗崟锛�</span>
+          <el-tag :type="download.accordingStatus === 3 ? 'success' : 'info'" size="small">
+            {{ download.accordingStatus === 3 ? '宸叉壒鍑�' : '鏈壒鍑�' }}
+          </el-tag>
+        </div>
+        <div class="doc-card-foot">
+          <el-button type="primary" :disabled="download.accordingStatus !== 3" @click="processingDown">瀵� 鍑�</el-button>
+        </div>
+      </div>
+      <div class="doc-card">
+        <div class="doc-card-head">
+          <span class="doc-card-name">绾犳鎺柦澶勭悊鍗曪紙绾犳鍗曪級</span>
+          <el-tag :type="download.correctStatus === 3 ? 'success' : 'info'" size="small">
+            {{ download.correctStatus === 3 ? '宸叉壒鍑�' : '鏈壒鍑�' }}
+          </el-tag>
+        </div>
+        <div class="doc-card-foot">
+          <el-button type="primary" :disabled="download.correctStatus !== 3" @click="supervisoryDown">瀵� 鍑�</el-button>
+        </div>
+      </div>
+      <div class="down-tip">
+        浠�"宸叉壒鍑�"鐨勮〃鍗曞彲瀵煎嚭锛岀伆鑹茶〃绀哄搴旇〃鍗曞皻鏈壒鍑嗘垨鏆傛棤鏁版嵁
+      </div>
       <template #footer><span  class="dialog-footer">
         <el-button @click="downloadDialog = false">鍙� 娑�</el-button>
       </span></template>
@@ -131,7 +162,7 @@
 import limsTable from "@/components/Table/lims-table.vue";
 import {
   delQualitySupervise, delQualitySuperviseDetail,
-  exportQualitySupervise, exportSuperviseDetailRecord,
+  exportQualitySupervise, exportSuperviseDetailRecord, issueQualitySupervise,
   pageQualitySupervise, pageQualitySuperviseDetail,
   ratifyQualitySupervise, superviseDetailAccordingExport,
   exportSuperviseDetaillCorrect
@@ -200,6 +231,25 @@
           prop: 'ratifyTime',
           width: '160'
         }, {
+          dataType: 'tag',
+          label: '涓嬪彂鐘舵��',
+          prop: 'issueStatus',
+          width: '100',
+          formatData: (params) => {
+            if (params === 1) {
+              return '宸蹭笅鍙�';
+            } else {
+              return '鏈笅鍙�';
+            }
+          },
+          formatType: (params) => {
+            if (params === 1) {
+              return 'success';
+            } else {
+              return 'info';
+            }
+          }
+        }, {
           dataType: 'action',
           label: '鎿嶄綔',
           operation: [
@@ -215,6 +265,20 @@
               },
               clickFun: (row) => {
                 this.approvalPlan(row)
+              }
+            },
+            {
+              name: '涓嬪彂',
+              type: 'text',
+              disabled: (row) => {
+                if (row.ratifyStatus !== 1 || row.issueStatus === 1) {
+                  return true
+                } else {
+                  return false
+                }
+              },
+              clickFun: (row) => {
+                this.issuePlan(row)
               }
             },
             {
@@ -389,6 +453,13 @@
               type: 'text',
               clickFun: (row) => {
                 this.records(row)
+              },
+              disabled: () => {
+                if (this.currentPlan.issueStatus !== 1) {
+                  return true
+                } else {
+                  return false
+                }
               }
             },
             {
@@ -446,6 +517,7 @@
       },
       currentScrollPosition: 0,
       superviseId: '',
+      currentPlan: {},
       formDia: false,
       recordsDia: false,
       processingDia: false,
@@ -562,8 +634,9 @@
       this.getUserList()
     },
     getUserList() {
-      selectUserCondition({ type: 2 }).then((res) => {
-        this.userList = res.data;
+      // 璐ㄩ噺鐩戠潱闈㈠悜鍏ㄥ疄楠屽, 浜哄憳鍒楄〃涓嶆寜閮ㄩ棬绛涢��
+      selectUserCondition({ type: 1 }).then((res) => {
+        this.userList = res.data || [];
       })
     },
     // 鎵瑰噯
@@ -592,14 +665,29 @@
     // 瀵煎嚭
     handleDown(row) {
       exportQualitySupervise({ superviseId: row.superviseId }).then(res => {
-        try {
-          this.outLoading = false
-          const blob = new Blob([res], { type: 'application/msword' });
-          this.$download.saveAs(blob, row.superviseName + '.docx')
-        } catch (error) {
-          console.error('鍒涘缓Blob瀵硅薄鏃跺嚭閿�:', error);
-        }
+        this.outLoading = false
+        this.saveDocx(res, row.superviseName + '.docx')
+      }).catch(err => {
+        console.log('err---', err);
       })
+    },
+    // 淇濆瓨瀵煎嚭鏂囦欢: 鍚庣瀵煎嚭澶辫触鏃朵細杩斿洖閿欒JSON, 姝ゆ椂寮规彁绀鸿�屼笉鏄瓨鎴愭崯鍧忕殑docx
+    saveDocx(res, filename) {
+      const reader = new FileReader();
+      reader.readAsText(res, 'utf-8');
+      reader.onload = () => {
+        const text = (reader.result || '').trim();
+        if (text.startsWith('{') || text.startsWith('[')) {
+          let msg = '瀵煎嚭澶辫触';
+          try { msg = JSON.parse(text).msg || msg; } catch (e) { }
+          this.$message.error(msg);
+        } else {
+          this.$download.saveAs(new Blob([res], { type: 'application/msword' }), filename);
+        }
+      };
+      reader.onerror = () => {
+        this.$download.saveAs(new Blob([res], { type: 'application/msword' }), filename);
+      };
     },
     // 鍒犻櫎杩涘害璁″垝琛�
     delPlan(row) {
@@ -627,7 +715,31 @@
     // 骞村害璁″垝琛ㄦ牸锛岀偣鍑昏鏁版嵁鍚庡埛鏂拌鎯�
     rowClick(row) {
       this.superviseId = row.superviseId
+      this.currentPlan = row
       this.getYearDetailPlan()
+    },
+    // 涓嬪彂璁″垝
+    issuePlan(row) {
+      this.$confirm('涓嬪彂鍚庣洃鐫e憳涓庣浉鍏虫娴嬩汉鍛樺皢鏀跺埌閫氱煡, 鏄惁缁х画?', '鎻愮ず', {
+        confirmButtonText: '纭畾',
+        cancelButtonText: '鍙栨秷',
+        type: 'warning'
+      }).then(() => {
+        this.yearLoading = true
+        issueQualitySupervise({ superviseId: row.superviseId }).then(res => {
+          this.yearLoading = false
+          this.$message.success('涓嬪彂鎴愬姛')
+          this.getYearPlanList()
+        }).catch(err => {
+          this.yearLoading = false
+          console.log('err---', err);
+        })
+      }).catch(() => {
+        this.$message({
+          type: 'info',
+          message: '宸插彇娑堜笅鍙�'
+        });
+      });
     },
     getYearDetailPlan () {
       this.yearDetailPage.current = 1
@@ -715,8 +827,7 @@
     // 瀵煎嚭璁板綍
     controlDown() {
       exportSuperviseDetailRecord({ superviseDetailsId: this.download.superviseDetailsId }).then(res => {
-        const blob = new Blob([res], { type: 'application/msword' });
-        this.$download.saveAs(blob, '璁板綍瀵煎嚭.docx')
+        this.saveDocx(res, '璁板綍瀵煎嚭.docx')
       }).catch(err => {
         console.log('err---', err);
       })
@@ -724,8 +835,7 @@
     // 澶勭悊鍗曞鍑�
     processingDown() {
       superviseDetailAccordingExport({ superviseDetailsId: this.download.superviseDetailsId }).then(res => {
-        const blob = new Blob([res], { type: 'application/msword' });
-        this.$download.saveAs(blob, '涓嶇鍚堥」瀵煎嚭.docx')
+        this.saveDocx(res, '涓嶇鍚堥」瀵煎嚭.docx')
       }).catch(err => {
         console.log('err---', err);
       })
@@ -733,8 +843,9 @@
     // 绾犳鍗曞鍑�
     supervisoryDown() {
       exportSuperviseDetaillCorrect({ superviseDetailsCorrectId: this.download.superviseDetailsCorrectId }).then(res => {
-        const blob = new Blob([res], { type: 'application/msword' });
-        this.$download.saveAs(blob, '鐩戠潱绾犳鎺柦.docx')
+        this.saveDocx(res, '鐩戠潱绾犳鎺柦.docx')
+      }).catch(err => {
+        console.log('err---', err);
       })
     },
     // 鍒犻櫎骞村害璇︽儏鍒楄〃
@@ -793,6 +904,37 @@
   margin: 0 5px;
 }
 
+.doc-card {
+  padding: 12px 16px;
+  margin-bottom: 12px;
+  background-color: #f7f8fa;
+  border: 1px solid #ebeef5;
+  border-radius: 6px;
+}
+
+.doc-card-head {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+}
+
+.doc-card-name {
+  font-size: 14px;
+  color: var(--lims-text-2, #303133);
+}
+
+.doc-card-foot {
+  display: flex;
+  justify-content: flex-end;
+  margin-top: 10px;
+}
+
+.down-tip {
+  margin-top: 10px;
+  color: #909399;
+  font-size: 12px;
+}
+
 .search {
   width: 150px;
   padding: 0 16px;

--
Gitblit v1.9.3