From 951b0558a6c3990e1c0ca792aed332914228508d Mon Sep 17 00:00:00 2001
From: 吴羡 <16976746+Xian-TT3@user.noreply.gitee.com>
Date: 星期二, 13 十月 2026 17:45:08 +0800
Subject: [PATCH] 设备模块调整:档案修订新增保养、核查日期与周期并自动计算下次日期,列表新增核查、保养相关列且到期前一个月标红;设备校准的服务机构改为合格供应商下拉,使用授权的被授权人改为检测员下拉;设备树改为全部/设备/计量器具分类;保养计划明细新增计划保养时间;移除量值溯源计划页签

---
 src/views/CNAS/resourceDemand/device/component/equipmentMaintenance.vue     |    8 
 src/views/CNAS/resourceDemand/device/index.vue                              |    6 
 src/views/CNAS/resourceDemand/device/component/deviceOverview.vue           |   29 ---
 src/views/CNAS/resourceDemand/device/component/files.vue                    |  112 +++++++++++----
 src/views/CNAS/resourceDemand/device/component/management.vue               |  217 +++++++++++++++++++------------
 src/views/CNAS/resourceDemand/device/component/calibration.vue              |   27 +++
 src/views/CNAS/resourceDemand/device/component/usageAuthorization.vue       |   11 +
 src/views/CNAS/resourceDemand/device/component/equipmentMaintenancePlan.vue |    6 
 8 files changed, 261 insertions(+), 155 deletions(-)

diff --git a/src/views/CNAS/resourceDemand/device/component/calibration.vue b/src/views/CNAS/resourceDemand/device/component/calibration.vue
index cf49a8d..5564222 100644
--- a/src/views/CNAS/resourceDemand/device/component/calibration.vue
+++ b/src/views/CNAS/resourceDemand/device/component/calibration.vue
@@ -110,8 +110,10 @@
           <el-row>
             <el-col :span="6">
               <el-form-item label="鏍″噯鏈嶅姟鏈烘瀯:" prop="unitOfMeasure">
-                <el-input v-model="calibrationRecord.unitOfMeasure" :disabled="operationType === 'view'"
-                  size="small"></el-input>
+                <el-select v-model="calibrationRecord.unitOfMeasure" :disabled="operationType === 'view'" clearable filterable
+                  size="small" style="width: 100%">
+                  <el-option v-for="name in calibrationServiceOptions" :key="name" :label="name" :value="name"></el-option>
+                </el-select>
               </el-form-item>
             </el-col>
             <el-col :span="8">
@@ -263,6 +265,7 @@
   addOrUpdateDeviceMetricRecord,
   saveOrUpdateDeviceMetric
 } from '@/api/cnas/resourceDemand/device.js'
+import { selectQualifiedSupplierManagementPage } from '@/api/cnas/externalService/supplierManage/supplierManage'
 import { mapGetters } from "@/utils/store-compat";
 export default {
   props: {
@@ -295,7 +298,7 @@
         fileName: '', //
       },
       formRules: {
-        unitOfMeasure: [{ required: true, message: '璇疯緭鍏ユ牎鍑嗘湇鍔℃満鏋�', trigger: 'blur' }],
+        unitOfMeasure: [{ required: true, message: '璇烽�夋嫨鏍″噯鏈嶅姟鏈烘瀯', trigger: 'change' }],
         calibrationDate: [{ required: true, message: '璇烽�夋嫨鏍″噯鏃ユ湡', trigger: 'change' }],
         calculatingApparatus: [{ required: true, message: '璇疯緭鍏ヨ绠楀櫒鍏�', trigger: 'blur' }],
         standardRange: [{ required: true, message: '璇疯緭鍏ヨ绠楁爣鍑嗛噺绋�', trigger: 'blur' }],
@@ -332,6 +335,7 @@
       addRecordLoading: false,
       upLoading: false,
       operationType: '',
+      qualifiedSupplierNames: [],
       search: {
         size: 20,
         current: 1,
@@ -341,16 +345,33 @@
   },
   // 鐢ㄤ簬涓婁紶鏂囦欢鐨勪俊鎭�
   computed: {
+    // 鏍″噯鏈嶅姟鏈烘瀯涓嬫媺閫夐」锛堝悎鏍间緵搴斿晢 + 褰撳墠鍊煎厹搴曪級
+    calibrationServiceOptions() {
+      const list = this.qualifiedSupplierNames.slice();
+      const value = this.calibrationRecord.unitOfMeasure;
+      if (value && list.indexOf(value) === -1) list.push(value);
+      return list;
+    },
     ...mapGetters(["nickName"]),
     action() {
       return this.javaApi + '/personBasicInfo/saveCNASFile'
     }
   },
   mounted() {
+    this.obtainQualifiedSupplierList()
     //鑾峰彇鎿嶄綔璁板綍淇℃伅
     this.getTableList(this.clickNodeVal.value) // 鑾峰彇璁惧鏍″噯鍒楄〃鏁版嵁
   },
   methods: {
+    // 鎷夊彇鍚堟牸渚涘簲鍟嗗垪琛紙鏍″噯鏈嶅姟鏈烘瀯涓嬫媺閫夐」锛�
+    obtainQualifiedSupplierList() {
+      selectQualifiedSupplierManagementPage({ current: 1, size: 999 }).then(res => {
+        if (res.code === 200) {
+          const rows = (res.data && res.data.records) || [];
+          this.qualifiedSupplierNames = [...new Set(rows.map(r => r.supplierName).filter(Boolean))];
+        }
+      });
+    },
     //鐘舵�佸垽瀹�
     checkRadio() {
       let resultList = this.calibrateParams.map(ele => ele.result)
diff --git a/src/views/CNAS/resourceDemand/device/component/deviceOverview.vue b/src/views/CNAS/resourceDemand/device/component/deviceOverview.vue
index 9a79f1d..c7b4d4e 100644
--- a/src/views/CNAS/resourceDemand/device/component/deviceOverview.vue
+++ b/src/views/CNAS/resourceDemand/device/component/deviceOverview.vue
@@ -116,6 +116,7 @@
       entity: {
         deviceStatus: null,
         deviceName: null,
+        largeCategory: null,
       },
       options: [],
       list: [],
@@ -125,7 +126,6 @@
       loading: true, // 缁勪欢loading鐨勫睍绀�,榛樿涓簍rue
       finishLoding: false, // 鍔犺浇瀹屾垚锛屾樉绀哄凡缁忔病鏈夋洿澶氫簡
       keyMap: {},
-      laboratoryNameIsNull: false,
       importVisible: false,
       importing: false,
       importFiles: [],
@@ -206,7 +206,6 @@
         this.finishLoding = false;
       }
       selectDeviceParameter({
-        laboratoryNameIsNull: this.laboratoryNameIsNull,
         current: this.currentPage,
         size: this.pageSize,
         ...this.entity
@@ -263,6 +262,7 @@
       this.entity = {
         deviceStatus: null,
         deviceName: null,
+        largeCategory: null,
       };
       this.refreshTable()
     },
@@ -275,33 +275,14 @@
     },
     // 鐐瑰嚮渚ц竟鏍忓埛鏂�
     clickSidebar(clickNodeVal) {
-      this.laboratoryNameIsNull = false
-      // 鏄惁瀛樺湪value锛屽瓨鍦╲alue浠h〃涓轰笁绾�
+      // 瀛樺湪value浠h〃閫変腑浜嗚澶囷紝鐢辫澶囪鎯呭睍绀哄鐞�
       if (!clickNodeVal.value) {
         this.finishLoding = false;
         this.keyMap = {};
         this.currentPage = 1;
         this.list = [];
-        this.entity.laboratoryName = null
-        this.entity.storagePoint = null
-        // 绛変簬1浠h〃涓烘爲鐨勪竴绾э紝label涓洪儴闂�
-        if (clickNodeVal.label == '鍏朵粬') {
-          this.laboratoryNameIsNull = true
-          this.refreshTable();
-          return
-        }
-        if (clickNodeVal.level == 1) {
-          this.entity.laboratoryName = clickNodeVal.label
-          // 绛変簬浜岀骇銆俵abel涓哄瓨鍌ㄥ湴鐐�
-        } else if (clickNodeVal.level == 2) {
-          // 鍏朵粬琛ㄧず娌℃湁閰嶇疆瀹為獙瀹わ紝鍙厤缃簡鍦扮偣
-          if (clickNodeVal.parent.label == '鍏朵粬') {
-            this.laboratoryNameIsNull = true
-          } else {
-            this.entity.laboratoryName = clickNodeVal.parent.label
-          }
-          this.entity.storagePoint = clickNodeVal.label
-        }
+        // 鏍戠殑涓�绾т负鍒嗙被锛氬叏閮�/璁惧/璁¢噺鍣ㄥ叿
+        this.entity.largeCategory = clickNodeVal.label === '鍏ㄩ儴' ? null : clickNodeVal.label;
         this.refreshTable();
       }
     }
diff --git a/src/views/CNAS/resourceDemand/device/component/equipmentMaintenance.vue b/src/views/CNAS/resourceDemand/device/component/equipmentMaintenance.vue
index 8c16006..75c1e31 100644
--- a/src/views/CNAS/resourceDemand/device/component/equipmentMaintenance.vue
+++ b/src/views/CNAS/resourceDemand/device/component/equipmentMaintenance.vue
@@ -201,10 +201,14 @@
         '鍒舵牱瀹�': 'sample_maintenance_content',
         '浣庢俯瀹為獙瀹�': 'hypothermia_maintenance_content',
       };
-      // 鑾峰彇褰撳墠鑺傜偣鐨勫疄楠屽鍚嶇О
-      const name = this.clickNodeVal.parent.label;
+      // 鍙栬澶囧瓨鏀剧偣鍚嶇О浣滀负鏄犲皠閿�
+      const name = this.clickNodeVal.storagePoint || '鍏朵粬';
       // 鏍规嵁鏄犲皠鍏崇郴鑾峰彇瀵瑰簲鐨勭被鍨�
       const type = labTypeMapping[name];
+      if (!type) {
+        this.qualificationList = [];
+        return;
+      }
       this.getDicts(type).then((response) => {
         this.qualificationList = response.data.map((m) => {
           return {
diff --git a/src/views/CNAS/resourceDemand/device/component/equipmentMaintenancePlan.vue b/src/views/CNAS/resourceDemand/device/component/equipmentMaintenancePlan.vue
index bce0d25..8605832 100644
--- a/src/views/CNAS/resourceDemand/device/component/equipmentMaintenancePlan.vue
+++ b/src/views/CNAS/resourceDemand/device/component/equipmentMaintenancePlan.vue
@@ -95,6 +95,12 @@
                 size="small"></el-input>
             </template>
           </el-table-column>
+          <el-table-column label="璁″垝淇濆吇鏃堕棿" min-width="140" prop="maintenanceDate">
+            <template #default="scope">
+              <el-date-picker v-model="scope.row.maintenanceDate" :disabled="operationType !== 'edit' && operationType !== 'add'" clearable
+                size="small" type="date" format="YYYY-MM-DD" value-format="YYYY-MM-DD" style="width:100%"></el-date-picker>
+            </template>
+          </el-table-column>
           <el-table-column label="鎿嶄綔" width="80" align="center" v-if="operationType === 'edit' || operationType === 'add'">
             <template #default="scope">
               <el-button link type="danger" @click="deleteRow(scope.$index)">鍒犻櫎</el-button>
diff --git a/src/views/CNAS/resourceDemand/device/component/files.vue b/src/views/CNAS/resourceDemand/device/component/files.vue
index acaad4e..e2ce9f1 100644
--- a/src/views/CNAS/resourceDemand/device/component/files.vue
+++ b/src/views/CNAS/resourceDemand/device/component/files.vue
@@ -40,10 +40,6 @@
             <p>{{ Mdata.managementNumber }}</p>
           </div>
           <div class="form-item">
-            <label>鎵�灞為儴闂�</label>
-            <p>{{ Mdata.laboratoryName }}</p>
-          </div>
-          <div class="form-item">
             <label>鐢熶骇鍘傚</label>
             <!-- <p>{{ Mdata.manufacturer }}</p> -->
             <el-tooltip class="item" :content="Mdata.manufacturer">
@@ -222,7 +218,9 @@
         <el-col :span="7">
           <el-form :model="editData" label-width="116px" ref="rules2" :rules="rules1">
             <el-form-item label="鏍″噯鏈嶅姟鏈烘瀯:">
-              <el-input v-model="editData.calibrationServices" size="small"></el-input>
+              <el-select v-model="editData.calibrationServices" clearable filterable size="small" style="width: 100%">
+                <el-option v-for="name in calibrationServiceOptions" :key="name" :label="name" :value="name"></el-option>
+              </el-select>
             </el-form-item>
             <el-form-item label="璧勪骇缂栫爜:">
               <el-input v-model="editData.assetCode" size="small"></el-input>
@@ -263,14 +261,6 @@
         <!-- 鍙宠竟甯冨眬 -->
         <el-col :span="7">
           <el-form :model="editData" label-width="140px" ref="ruleForm" :rules="rules1">
-            <!-- 瀹為獙瀹ゅ垪琛� -->
-            <el-form-item label="鎵�灞為儴闂�:" prop="subordinateDepartmentsId">
-              <el-select v-model="editData.subordinateDepartmentsId" placeholder="璇烽�夋嫨" size="small" style="width:100%">
-                <el-option v-for="item in subordinateDepartmentsList" :key="item.value" :label="item.label"
-                  :value="item.value">
-                </el-option>
-              </el-select>
-            </el-form-item>
             <el-form-item label="妫�娴嬮」鐩�:">
               <el-cascader v-model="editData.insProductIds" :options="options" :show-all-levels="false" :props="props"
                 placeholder="璇烽�夋嫨" size="small" style="width:100%;" :collapse-tags="true" separator="," filterable
@@ -304,9 +294,35 @@
             <el-form-item label="鏍″噯鍛ㄦ湡锛堟湀锛�:" prop="calibrationDate">
               <el-input v-model="editData.calibrationDate" size="small"></el-input>
             </el-form-item>
+            <el-form-item label="鏈�杩戜繚鍏绘棩鏈�:">
+              <el-date-picker style="width:100%" v-model="editData.lastMaintenanceDate" @change="calcNextDate(editData)"
+                format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
+              </el-date-picker>
+            </el-form-item>
+            <el-form-item label="涓嬫淇濆吇鏃ユ湡:">
+              <el-date-picker :disabled="true" style="width:100%" v-model="editData.nextMaintenanceDate"
+                format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
+              </el-date-picker>
+            </el-form-item>
+            <el-form-item label="淇濆吇鍛ㄦ湡锛堟湀锛�:">
+              <el-input v-model="editData.maintenanceCycle" size="small" @change="calcNextDate(editData)"></el-input>
+            </el-form-item>
+            <el-form-item label="鏈�杩戞牳鏌ユ棩鏈�:">
+              <el-date-picker style="width:100%" v-model="editData.lastExamineDate" @change="calcNextDate(editData)"
+                format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
+              </el-date-picker>
+            </el-form-item>
+            <el-form-item label="涓嬫鏍告煡鏃ユ湡:">
+              <el-date-picker :disabled="true" style="width:100%" v-model="editData.nextExamineDate"
+                format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
+              </el-date-picker>
+            </el-form-item>
+            <el-form-item label="鏍告煡鍛ㄦ湡锛堟湀锛�:">
+              <el-input v-model="editData.examineCycle" size="small" @change="calcNextDate(editData)"></el-input>
+            </el-form-item>
             <el-form-item label="琚巿鏉冧汉:">
               <el-select v-model="editData.authorizedPerson" multiple placeholder="璇烽�夋嫨" size="small" style="width:100%">
-                <el-option v-for="item in responsiblePersonList" :key="item.name" :label="item.name" :value="item.id">
+                <el-option v-for="item in inspectorList" :key="item.name" :label="item.name" :value="item.id">
                 </el-option>
               </el-select>
             </el-form-item>
@@ -446,6 +462,7 @@
 
 <script>
 import { ElMessageBox } from 'element-plus'
+import dayjs from 'dayjs'
 import fileDownload from '@/utils/file'
 // vue-qr 鍙敮鎸� Vue2锛屾崲鎴愬悓 props 鐨勬湰鍦扮粍浠讹紙鍐呴儴鐢� Vue3 鐨� qrcode.vue锛�
 import vueQr from '@/components/QrCode'
@@ -463,9 +480,7 @@
   getInsProduction,
 } from '@/api/cnas/resourceDemand/device.js'
 import { selectUserCondition } from "@/api/business/inspectionTask";
-import {
-  obtainItemParameterList,
-} from '@/api/cnas/resourceDemand/device.js'
+import { selectQualifiedSupplierManagementPage } from '@/api/cnas/externalService/supplierManage/supplierManage'
 export default {
   props: {
     clickNodeVal: {
@@ -499,9 +514,6 @@
         ],
         calibrationDate: [
           { required: true, message: '璇疯緭鍏ユ牎鍑嗗懆鏈�(鏈�)', trigger: 'blur' },
-        ],
-        subordinateDepartmentsId: [
-          { required: true, message: '璇烽�夋嫨鎵�灞為儴闂�', trigger: 'change' },
         ]
       },
       // dateForm: {
@@ -540,7 +552,7 @@
       dialogVisible: false,
       upLoad: false,
       responsiblePersonList: [],
-      subordinateDepartmentsList: [],
+      inspectorList: [],
       options: [],
       equipmentList: [],
       deviceStatusList: [],
@@ -553,9 +565,17 @@
       editData: {
         authorizedPerson: [],
       },
+      qualifiedSupplierNames: [],
     }
   },
   computed: {
+    // 鏍″噯鏈嶅姟鏈烘瀯涓嬫媺閫夐」锛堝悎鏍间緵搴斿晢 + 褰撳墠鍊煎厹搴曪級
+    calibrationServiceOptions() {
+      const list = this.qualifiedSupplierNames.slice();
+      const value = this.editData.calibrationServices;
+      if (value && list.indexOf(value) === -1) list.push(value);
+      return list;
+    },
     action() {
       return this.javaApi + '/deviceScope/uploadFile'
     }
@@ -566,8 +586,18 @@
     // 鑾峰彇鐩稿叧鏂囨。鐨勬暟鎹�
     this.getPage()
     this.timeStamp = Date.now()
+    this.obtainQualifiedSupplierList()
   },
   methods: {
+    // 鎷夊彇鍚堟牸渚涘簲鍟嗗垪琛紙鏍″噯鏈嶅姟鏈烘瀯涓嬫媺閫夐」锛�
+    obtainQualifiedSupplierList() {
+      selectQualifiedSupplierManagementPage({ current: 1, size: 999 }).then(res => {
+        if (res.code === 200) {
+          const rows = (res.data && res.data.records) || [];
+          this.qualifiedSupplierNames = [...new Set(rows.map(r => r.supplierName).filter(Boolean))];
+        }
+      });
+    },
     // 鍘熷厛鐨� Vue2 filter锛孷ue3 宸茬Щ闄� filters 閫夐」锛屾敼涓烘柟娉曡皟鐢�
     formaterDateTime(dateTime) {
       if (dateTime === undefined || dateTime === null || dateTime === '') {
@@ -602,8 +632,6 @@
     openFileRevisionDialog() {
       // 鑾峰彇妗f淇璐熻矗浜轰笅鎷夋鏁版嵁
       this.selectDevicePrincipal()
-      // 鑾峰彇妗f淇鎵�灞為儴闂ㄤ笅鎷夋鏁版嵁
-      this.obtainItemParameterList()
       // 鑾峰彇妗f淇璁惧鐘舵�佷笅鎷夋鏁版嵁
       this.selectEnumByCategory()
       // 鑾峰彇妗f淇妫�楠岄」鐩骇鑱斿脊妗嗘暟鎹�
@@ -736,6 +764,30 @@
         this.dialogVisible = true
       })
     },
+    // 涓嬫鏃ユ湡 = 鏈�杩戞棩鏈� + 鍛ㄦ湡锛堟湀锛夛紝鑷姩璁$畻
+    calcNextDate(data) {
+      const calc = (lastDate, cycle) => {
+        const period = parseInt(cycle)
+        if (!lastDate || !period || period <= 0) {
+          return null
+        }
+        return dayjs(String(lastDate).replace(' ', 'T'))
+          .add(period, 'month')
+          .format('YYYY-MM-DD HH:mm:ss')
+      }
+      const nextCalibrationDate = calc(data.lastCalibrationDate, data.calibrationDate)
+      if (nextCalibrationDate) {
+        data.nextCalibrationDate = nextCalibrationDate
+      }
+      const nextMaintenanceDate = calc(data.lastMaintenanceDate, data.maintenanceCycle)
+      if (nextMaintenanceDate) {
+        data.nextMaintenanceDate = nextMaintenanceDate
+      }
+      const nextExamineDate = calc(data.lastExamineDate, data.examineCycle)
+      if (nextExamineDate) {
+        data.nextExamineDate = nextExamineDate
+      }
+    },
     //淇妗f
     submitForm() {
       let flag = true
@@ -822,17 +874,9 @@
       selectUserCondition().then(res => {
         this.responsiblePersonList = res.data;
       })
-    },
-    obtainItemParameterList() {
-      obtainItemParameterList().then(res => {
-        let data = []
-        res.data.forEach(a => {
-          data.push({
-            label: a.laboratoryName,
-            value: a.id
-          })
-        })
-        this.subordinateDepartmentsList = data
+      // 琚巿鏉冧汉涓嬫媺鍙彇妫�娴嬪憳瑙掕壊浜哄憳
+      selectUserCondition({ type: 3 }).then(res => {
+        this.inspectorList = res.data;
       })
     },
     getInsProductIds() {
diff --git a/src/views/CNAS/resourceDemand/device/component/management.vue b/src/views/CNAS/resourceDemand/device/component/management.vue
index e4b42a1..eb3cbd2 100644
--- a/src/views/CNAS/resourceDemand/device/component/management.vue
+++ b/src/views/CNAS/resourceDemand/device/component/management.vue
@@ -75,7 +75,9 @@
 				<el-col :span="7">
 					<el-form :label-position="labelPosition" :model="formData" label-width="116px">
 						<el-form-item label="鏍″噯鏈嶅姟鏈烘瀯:">
-							<el-input :disabled="isUp" v-model="formData.calibrationServices" size="small"></el-input>
+							<el-select :disabled="isUp" v-model="formData.calibrationServices" clearable filterable size="small" style="width: 100%">
+								<el-option v-for="name in calibrationServiceOptions" :key="name" :label="name" :value="name"></el-option>
+							</el-select>
 						</el-form-item>
 						<el-form-item label="璧勪骇缂栫爜:">
 							<el-input v-model="formData.assetCode" :disabled="isUp" size="small"></el-input>
@@ -119,27 +121,18 @@
 				<!-- 鍙宠竟甯冨眬 -->
 				<el-col :span="7">
 					<el-form :label-position="labelPosition" :model="formData" label-width="140px" ref="ruleForm">
-						<!-- 瀹為獙瀹ゅ垪琛� -->
-						<el-form-item label="鎵�灞為儴闂�:" required>
-							<el-select :disabled="isUp" v-model="formData.subordinateDepartmentsId" placeholder="璇烽�夋嫨" size="small"
-								style="width:100%">
-								<el-option v-for="item in subordinateDepartmentsList" :key="item.value" :label="item.label"
-									:value="item.value">
-								</el-option>
-							</el-select>
-						</el-form-item>
 						<el-form-item label="妫�娴嬮」鐩�:">
 							<el-cascader :disabled="isUp" v-model="formData.insProductIds" :options="options" :show-all-levels="false"
 								:props="props" placeholder="璇烽�夋嫨" size="small" style="width:100%;" :collapse-tags="!isUp" separator=","
 								filterable clearable></el-cascader>
 						</el-form-item>
 						<el-form-item label="鏈�杩戞牎鍑嗘棩鏈�:">
-							<el-date-picker :disabled="isUp" style="width:100%" v-model="formData.lastCalibrationDate"
+							<el-date-picker :disabled="isUp" style="width:100%" v-model="formData.lastCalibrationDate" @change="calcNextDate(formData)"
 								format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
 							</el-date-picker>
 						</el-form-item>
 						<el-form-item label="涓嬫鏍″噯鏃ユ湡:">
-							<el-date-picker :disabled="isUp" style="width:100%" v-model="formData.nextCalibrationDate"
+							<el-date-picker :disabled="true" style="width:100%" v-model="formData.nextCalibrationDate"
 								format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
 							</el-date-picker>
 						</el-form-item>
@@ -161,12 +154,38 @@
 							</el-select>
 						</el-form-item>
 						<el-form-item label="鏍″噯鍛ㄦ湡锛堟湀锛�:" required>
-							<el-input :disabled="isUp" v-model="formData.calibrationDate" size="small"></el-input>
+							<el-input :disabled="isUp" v-model="formData.calibrationDate" size="small" @change="calcNextDate(formData)"></el-input>
+						</el-form-item>
+						<el-form-item label="鏈�杩戜繚鍏绘棩鏈�:">
+							<el-date-picker :disabled="isUp" style="width:100%" v-model="formData.lastMaintenanceDate" @change="calcNextDate(formData)"
+								format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
+							</el-date-picker>
+						</el-form-item>
+						<el-form-item label="涓嬫淇濆吇鏃ユ湡:">
+							<el-date-picker :disabled="true" style="width:100%" v-model="formData.nextMaintenanceDate"
+								format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
+							</el-date-picker>
+						</el-form-item>
+						<el-form-item label="淇濆吇鍛ㄦ湡锛堟湀锛�:">
+							<el-input :disabled="isUp" v-model="formData.maintenanceCycle" size="small" @change="calcNextDate(formData)"></el-input>
+						</el-form-item>
+						<el-form-item label="鏈�杩戞牳鏌ユ棩鏈�:">
+							<el-date-picker :disabled="isUp" style="width:100%" v-model="formData.lastExamineDate" @change="calcNextDate(formData)"
+								format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
+							</el-date-picker>
+						</el-form-item>
+						<el-form-item label="涓嬫鏍告煡鏃ユ湡:">
+							<el-date-picker :disabled="true" style="width:100%" v-model="formData.nextExamineDate"
+								format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
+							</el-date-picker>
+						</el-form-item>
+						<el-form-item label="鏍告煡鍛ㄦ湡锛堟湀锛�:">
+							<el-input :disabled="isUp" v-model="formData.examineCycle" size="small" @change="calcNextDate(formData)"></el-input>
 						</el-form-item>
 						<el-form-item label="琚巿鏉冧汉:">
 							<el-select v-model="formData.authorizedPerson" multiple :disabled="isUp" placeholder="璇烽�夋嫨" size="small"
 								style="width:100%">
-								<el-option v-for="item in responsiblePersonList" :key="item.value" :label="item.label"
+								<el-option v-for="item in inspectorList" :key="item.value" :label="item.label"
 									:value="item.value">
 								</el-option>
 							</el-select>
@@ -186,7 +205,7 @@
 				</el-col>
 			</el-row>
 			<template #footer><span  class="dialog-footer">
-				<el-row v-if="!isUp">
+				<el-row v-if="!isUp" justify="end">
 					<el-button @click="handleClose">鍙� 娑�</el-button>
 					<el-button type="primary" @click="submitForm" :loading="upLoad">纭� 瀹�</el-button>
 				</el-row>
@@ -235,7 +254,9 @@
               <el-input v-model="formData2.factoryNo" size="small"></el-input>
             </el-form-item> -->
 						<el-form-item label="鏍″噯鏈嶅姟鏈烘瀯:">
-							<el-input v-model="formData2.calibrationServices" size="small"></el-input>
+							<el-select v-model="formData2.calibrationServices" clearable filterable size="small" style="width: 100%">
+								<el-option v-for="name in calibrationServiceOptions2" :key="name" :label="name" :value="name"></el-option>
+							</el-select>
 						</el-form-item>
 						<el-form-item label="璧勪骇缂栫爜:">
 							<el-input v-model="formData2.assetCode" size="small"></el-input>
@@ -277,26 +298,18 @@
 				<!-- 鍙宠竟甯冨眬 -->
 				<el-col :span="7">
 					<el-form :label-position="labelPosition" :model="formData2" label-width="120px" ref="ruleForm">
-						<!-- 瀹為獙瀹ゅ垪琛� -->
-						<el-form-item label="鎵�灞為儴闂�:" required>
-							<el-select v-model="formData2.subordinateDepartmentsId" placeholder="璇烽�夋嫨" size="small" style="width:100%">
-								<el-option v-for="item in subordinateDepartmentsList" :key="item.value" :label="item.label"
-									:value="item.value">
-								</el-option>
-							</el-select>
-						</el-form-item>
 						<el-form-item label="妫�娴嬮」鐩�:">
 							<el-cascader v-model="formData2.insProductIds" :options="options" :show-all-levels="false" :props="props"
 								placeholder="璇烽�夋嫨" size="small" style="width:100%" collapse-tags separator="," filterable
 								clearable></el-cascader>
 						</el-form-item>
 						<el-form-item label="鏈�杩戞牎鍑嗘棩鏈�:">
-							<el-date-picker style="width:100%" v-model="formData2.lastCalibrationDate" format="YYYY-MM-DD"
+							<el-date-picker style="width:100%" v-model="formData2.lastCalibrationDate" format="YYYY-MM-DD" @change="calcNextDate(formData2)"
 								value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
 							</el-date-picker>
 						</el-form-item>
 						<el-form-item label="涓嬫鏍″噯鏃ユ湡:">
-							<el-date-picker style="width:100%" v-model="formData2.nextCalibrationDate" format="YYYY-MM-DD"
+							<el-date-picker :disabled="true" style="width:100%" v-model="formData2.nextCalibrationDate" format="YYYY-MM-DD"
 								value-format="YYYY-MM-DD HH:mm:ss" type="date" size="small" placeholder="閫夋嫨鏃ユ湡">
 							</el-date-picker>
 						</el-form-item>
@@ -316,12 +329,12 @@
 							</el-select>
 						</el-form-item>
 						<el-form-item label="鏍″噯鍛ㄦ湡锛堟湀锛�:" required>
-							<el-input v-model="formData2.calibrationDate" size="small"></el-input>
+							<el-input v-model="formData2.calibrationDate" size="small" @change="calcNextDate(formData2)"></el-input>
 						</el-form-item>
 						<el-form-item label="琚巿鏉冧汉:">
 							<el-select v-model="formData2.authorizedPerson" multiple placeholder="璇烽�夋嫨" size="small"
 								style="width:100%">
-								<el-option v-for="item in responsiblePersonList" :key="item.value" :label="item.label"
+								<el-option v-for="item in inspectorList" :key="item.value" :label="item.label"
 									:value="item.value">
 								</el-option>
 							</el-select>
@@ -341,7 +354,7 @@
 				</el-col>
 			</el-row>
 			<template #footer><span  class="dialog-footer">
-				<el-row>
+				<el-row justify="end">
 					<el-button @click="handleClose2">鍙� 娑�</el-button>
 					<el-button type="primary" @click="submitForm2" :loading="upLoad2">纭� 瀹�</el-button>
 				</el-row>
@@ -377,7 +390,7 @@
 				<el-input size="small" placeholder="璇疯緭鍏�" clearable v-model="configForm.formula"></el-input>
 			</div>
 			<template #footer><span  class="dialog-footer">
-				<el-row>
+				<el-row justify="end">
 					<el-button @click="dialogVisible3 = false">鍙� 娑�</el-button>
 					<el-button type="primary" @click="submitForm3" :loading="upLoad3">纭� 瀹�</el-button>
 				</el-row>
@@ -399,8 +412,9 @@
 	getDeviceParameter,
 	delDeviceParameter,
 } from '@/api/cnas/resourceDemand/device.js'
-import { listDept } from '@/api/system/dept'
 import { selectUserCondition } from "@/api/business/inspectionTask";
+import dayjs from 'dayjs'
+import { selectQualifiedSupplierManagementPage } from '@/api/cnas/externalService/supplierManage/supplierManage'
 export default {
 	props: {
 		clickNodeVal: {
@@ -418,6 +432,7 @@
 		return {
 			dateFormat: 'yyyy-MM-dd',
 			deviceId: '',
+			qualifiedSupplierNames: [],
 			fileTypeOptions: [
 				{ label: 'csv', value: '.csv' },
 				{ label: 'db', value: '.db' },
@@ -453,16 +468,15 @@
 			responsiblePersonList: [],
 			// 鎺堟潈浜哄垪琛�
 			authorizerList: [],
+			// 妫�娴嬪憳鍒楄〃锛堣鎺堟潈浜轰笅鎷夛級
+			inspectorList: [],
 			// 褰撳墠鐘舵�佸垪琛�
 			deviceStatusList: [],
-			// 鎵�灞為儴闂�
-			subordinateDepartmentsList: [],
 			upLoad: false,
 			upLoad2: false,
 			dialogVisible3: false,
 			upLoad3: false,
 			configForm: {},
-			laboratoryNameIsNull: false,
 			queryParams: {},
 			tableData: [],
 			column: [
@@ -480,13 +494,14 @@
 				{ label: "鏍″噯鏈夋晥鏈�", prop: "activationDate" },
 				{ label: "绠$悊浜�", prop: "equipmentManagerUser" },
 				{ label: "瀛樻斁鐐�", prop: "storagePoint" },
-				{ label: "鎵�灞為儴闂�", prop: "laboratoryName" },
 				{ label: "妫�楠岄」鐩�", prop: "insProductItem" },
 				{ label: "鏍″噯鏈嶅姟鏈烘瀯", prop: "calibrationServices" },
 				{ label: "鏈�杩戞牎鍑嗘棩鏈�", prop: "lastCalibrationDateTwo" },
-				{ label: "鏈�杩戞牳鏌ユ棩鏈�", prop: "lastCalibrationDate" },
+				{ label: "鏈�杩戞牳鏌ユ棩鏈�", prop: "lastExamineDate" },
 				{ label: "涓嬫鏍″噯鏃ユ湡", prop: "nextCalibrationDateTwo" },
-				{ label: "涓嬫鏍告煡鏃ユ湡", prop: "nextCalibrationDate" },
+				{ label: "涓嬫鏍告煡鏃ユ湡", prop: "nextExamineDate" },
+				{ label: "鏈�杩戜繚鍏绘棩鏈�", prop: "lastMaintenanceDate" },
+				{ label: "涓嬫淇濆吇鏃ユ湡", prop: "nextMaintenanceDate" },
 				{
 					label: "璁惧鍒嗙被", prop: "largeCategory", dataType: "tag",
 					formatData: (params) => {
@@ -515,6 +530,8 @@
 					}
 				},
 				{ label: "鏍″噯鍛ㄦ湡(鏈�)", prop: "calibrationDate" },
+				{ label: "鏍告煡鍛ㄦ湡(鏈�)", prop: "examineCycle" },
+				{ label: "淇濆吇鍛ㄦ湡(鏈�)", prop: "maintenanceCycle" },
 				{
 					dataType: "action",
 					fixed: "right",
@@ -556,6 +573,20 @@
 		}
 	},
 	computed: {
+		// 鏍″噯鏈嶅姟鏈烘瀯涓嬫媺閫夐」锛堝悎鏍间緵搴斿晢 + 褰撳墠鍊煎厹搴曪級
+		calibrationServiceOptions() {
+			const list = this.qualifiedSupplierNames.slice();
+			const value = this.formData.calibrationServices;
+			if (value && list.indexOf(value) === -1) list.push(value);
+			return list;
+		},
+		// 鏂板璁惧寮圭獥鐨勬牎鍑嗘湇鍔℃満鏋勪笅鎷夐�夐」
+		calibrationServiceOptions2() {
+			const list = this.qualifiedSupplierNames.slice();
+			const value = this.formData2.calibrationServices;
+			if (value && list.indexOf(value) === -1) list.push(value);
+			return list;
+		},
 		action() {
 			return this.javaApi + '/deviceScope/uploadFile'
 		}
@@ -563,31 +594,28 @@
 	mounted() {
 		this.selectEnumByCategory()
 		this.selectDevicePrincipal()
-		this.obtainDepartmentList()
 		this.getInsProductIds()
+		this.obtainQualifiedSupplierList()
 		// 鍒濆鍖�
 		this.clickSidebar(this.clickNodeVal)
 	},
 	methods: {
+		// 鎷夊彇鍚堟牸渚涘簲鍟嗗垪琛紙鏍″噯鏈嶅姟鏈烘瀯涓嬫媺閫夐」锛�
+		obtainQualifiedSupplierList() {
+			selectQualifiedSupplierManagementPage({ current: 1, size: 999 }).then(res => {
+				if (res.code === 200) {
+					const rows = (res.data && res.data.records) || [];
+					this.qualifiedSupplierNames = [...new Set(rows.map(r => r.supplierName).filter(Boolean))];
+				}
+			});
+		},
 		//鍒嗙被
 		handleNotification(cate) {
 			this.queryParams.largeCategory = cate
 		},
-		obtainDepartmentList() {
-			listDept({ status: '0' }).then(res => {
-				let data = []
-				res.data.forEach(a => {
-					data.push({
-						label: a.deptName,
-						value: a.deptId
-					})
-				})
-				this.subordinateDepartmentsList = data
-			})
-		},
 		getList() {
 			this.tableLoading = true;
-			let param = { laboratoryNameIsNull: this.laboratoryNameIsNull, ...this.queryParams, ...this.page };
+			let param = { ...this.queryParams, ...this.page };
 			delete param.total;
 			getDeviceParameter({ ...param })
 				.then((res) => {
@@ -607,13 +635,22 @@
 			this.getList();
 		},
     tableRowClassName({ row }) {
-      const today = new Date();
-      const targetDate = new Date(row.activationDate);
-      const fiveDaysBeforeTarget = new Date(targetDate);
-      // 璁$畻鍓嶄簲澶╃殑鏃ユ湡
-      fiveDaysBeforeTarget.setDate(targetDate.getDate() - 5);
-      // 姣旇緝鏃堕渶瑕佺‘淇濇瘮杈冪殑鏄畬鏁寸殑鏃ユ湡鏃堕棿锛屽寘鍚椂鍒嗙
-      if (today > fiveDaysBeforeTarget) {
+      // 鏍″噯鏈夋晥鏈熷埌鏈熷墠涓�涓湀锛堝惈宸茶繃鏈燂級鏍囩孩鎻愰啋
+      const activationDate = row.activationDate ? dayjs(String(row.activationDate).replace(' ', 'T')) : null;
+      if (activationDate && activationDate.isValid() && !dayjs().isBefore(activationDate.subtract(1, 'month'))) {
+        return 'red-row';
+      }
+      // 涓嬫鏍″噯/鏍告煡/淇濆吇鏃ユ湡鎻愬墠涓�涓湀锛堝惈宸茶繃鏈燂級鏍囩孩鎻愰啋
+      const nextCalibration = row.nextCalibrationDate ? dayjs(String(row.nextCalibrationDate).replace(' ', 'T')) : null;
+      if (nextCalibration && nextCalibration.isValid() && !nextCalibration.isAfter(dayjs().add(1, 'month'))) {
+        return 'red-row';
+      }
+      const nextExamine = row.nextExamineDate ? dayjs(String(row.nextExamineDate).replace(' ', 'T')) : null;
+      if (nextExamine && nextExamine.isValid() && !nextExamine.isAfter(dayjs().add(1, 'month'))) {
+        return 'red-row';
+      }
+      const nextMaintenance = row.nextMaintenanceDate ? dayjs(String(row.nextMaintenanceDate).replace(' ', 'T')) : null;
+      if (nextMaintenance && nextMaintenance.isValid() && !nextMaintenance.isAfter(dayjs().add(1, 'month'))) {
         return 'red-row';
       }
       return '';
@@ -659,6 +696,17 @@
 				});
 				this.responsiblePersonList = data
 				this.authorizerList = data
+			})
+			// 琚巿鏉冧汉涓嬫媺鍙彇妫�娴嬪憳瑙掕壊浜哄憳
+			selectUserCondition({ type: 3 }).then(res => {
+				let data = [];
+				res.data.forEach((a) => {
+					data.push({
+						label: a.name,
+						value: a.id,
+					});
+				});
+				this.inspectorList = data
 			})
 		},
 		getInsProductIds() {
@@ -776,6 +824,30 @@
 				})
 			}
 		},
+		// 涓嬫鏃ユ湡 = 鏈�杩戞棩鏈� + 鍛ㄦ湡锛堟湀锛夛紝鑷姩璁$畻
+		calcNextDate(data) {
+			const calc = (lastDate, cycle) => {
+				const period = parseInt(cycle)
+				if (!lastDate || !period || period <= 0) {
+					return null
+				}
+				return dayjs(String(lastDate).replace(' ', 'T'))
+					.add(period, 'month')
+					.format('YYYY-MM-DD HH:mm:ss')
+			}
+			const nextCalibrationDate = calc(data.lastCalibrationDate, data.calibrationDate)
+			if (nextCalibrationDate) {
+				data.nextCalibrationDate = nextCalibrationDate
+			}
+			const nextMaintenanceDate = calc(data.lastMaintenanceDate, data.maintenanceCycle)
+			if (nextMaintenanceDate) {
+				data.nextMaintenanceDate = nextMaintenanceDate
+			}
+			const nextExamineDate = calc(data.lastExamineDate, data.examineCycle)
+			if (nextExamineDate) {
+				data.nextExamineDate = nextExamineDate
+			}
+		},
 		submitForm() {
 			if (!this.formData.deviceName) {
 				this.$message.error('鏈緭鍏ヤ华鍣ㄥ悕绉�')
@@ -791,10 +863,6 @@
 			}
 			if (!this.formData.activationDate) {
 				this.$message.error('鏈緭鍏ユ牎鍑嗘湁鏁堟湡')
-				return
-			}
-			if (!this.formData.subordinateDepartmentsId) {
-				this.$message.error('鏈�夋嫨鎵�灞為儴闂�')
 				return
 			}
 			if (this.formData.deviceStatus === '' || this.formData.deviceStatus === null) {
@@ -941,30 +1009,11 @@
 		},
 		// 鐐瑰嚮渚ц竟鏍忓埛鏂�
 		clickSidebar(clickNodeVal) {
-			this.laboratoryNameIsNull = false
-			// 鏄惁瀛樺湪value锛屽瓨鍦╲alue浠h〃涓轰笁绾�
+			// 瀛樺湪value浠h〃閫変腑浜嗚澶囷紝鐢辫澶囪鎯呭睍绀哄鐞�
 			if (!clickNodeVal.value) {
 				this.list = [];
-				this.queryParams.laboratoryName = null
-				this.queryParams.storagePoint = null
-				// 绛変簬1浠h〃涓烘爲鐨勪竴绾э紝label涓洪儴闂�
-				if (clickNodeVal.label == '鍏朵粬') {
-					this.laboratoryNameIsNull = true
-					this.refreshTable('page')
-					return
-				}
-				if (clickNodeVal.level == 1) {
-					this.queryParams.laboratoryName = clickNodeVal.label
-					// 绛変簬浜岀骇銆俵abel涓哄瓨鍌ㄥ湴鐐�
-				} else if (clickNodeVal.level == 2) {
-					// 鍏朵粬琛ㄧず娌℃湁閰嶇疆瀹為獙瀹わ紝鍙厤缃簡鍦扮偣
-					if (clickNodeVal.parent.label == '鍏朵粬') {
-						this.laboratoryNameIsNull = true
-					} else {
-						this.queryParams.laboratoryName = clickNodeVal.parent.label
-					}
-					this.queryParams.storagePoint = clickNodeVal.label
-				}
+				// 鏍戠殑涓�绾т负鍒嗙被锛氬叏閮�/璁惧/璁¢噺鍣ㄥ叿
+				this.queryParams.largeCategory = clickNodeVal.label === '鍏ㄩ儴' ? null : clickNodeVal.label
 				this.refreshTable('page')
 			}
 		},
diff --git a/src/views/CNAS/resourceDemand/device/component/usageAuthorization.vue b/src/views/CNAS/resourceDemand/device/component/usageAuthorization.vue
index 8db89c6..bcd8062 100644
--- a/src/views/CNAS/resourceDemand/device/component/usageAuthorization.vue
+++ b/src/views/CNAS/resourceDemand/device/component/usageAuthorization.vue
@@ -80,7 +80,7 @@
         <span style="width: 90px;margin-left: 10px">琚巿鏉冧汉锛�</span>
         <el-select v-model="delegatedUser" clearable filterable multiple
                    placeholder="璇烽�夋嫨" size="small" style="width: 100%;">
-          <el-option v-for="item in responsibleOptions" :key="item.name" :label="item.name" :value="item.name">
+          <el-option v-for="item in inspectorOptions" :key="item.name" :label="item.name" :value="item.name">
           </el-option>
         </el-select>
       </div>
@@ -229,6 +229,7 @@
         }
       ],
       responsibleOptions: [],
+      inspectorOptions: [],
       operationType: '',
       usageTableDia: false,
       deviceImpowerDetails: [],
@@ -337,7 +338,7 @@
     // 娣诲姞璁惧
     addTableRow() {
       this.addEquipDia = true
-      this.delegatedUser = this.responsibleOptions.map((item) => item.name);
+      this.delegatedUser = this.inspectorOptions.map((item) => item.name);
       this.getEquipOptions()
     },
     // 鍒犻櫎琛ㄦ牸琛�
@@ -453,6 +454,12 @@
           this.responsibleOptions = res.data
         }
       })
+      // 琚巿鏉冧汉涓嬫媺鍙彇妫�娴嬪憳瑙掕壊浜哄憳
+      selectUserCondition({type: 3}).then(res => {
+        if (res.code == 200) {
+          this.inspectorOptions = res.data
+        }
+      })
     },
   },
   watch: {
diff --git a/src/views/CNAS/resourceDemand/device/index.vue b/src/views/CNAS/resourceDemand/device/index.vue
index 5832178..4bbf1e4 100644
--- a/src/views/CNAS/resourceDemand/device/index.vue
+++ b/src/views/CNAS/resourceDemand/device/index.vue
@@ -53,10 +53,6 @@
             <equipment-maintenance-plan v-if="menuListActiveName == '璁惧淇濆吇璁″垝'"
               :clickNodeVal="clickNodeVal"></equipment-maintenance-plan>
           </el-tab-pane>
-          <el-tab-pane label="閲忓�兼函婧愯鍒�" name="閲忓�兼函婧愯鍒�">
-            <quantity-value-traceability-plan v-if="menuListActiveName == '閲忓�兼函婧愯鍒�'"
-              :clickNodeVal="clickNodeVal"></quantity-value-traceability-plan>
-          </el-tab-pane>
           <el-tab-pane label="璁惧浣跨敤鎺堟潈" name="璁惧浣跨敤鎺堟潈">
             <usage-authorization v-if="menuListActiveName == '璁惧浣跨敤鎺堟潈'"
               :clickNodeVal="clickNodeVal"></usage-authorization>
@@ -135,7 +131,6 @@
 import EquipmentAccident from "./component/equipmentAccident.vue";
 import EquipmentMaintenancePlan from "./component/equipmentMaintenancePlan.vue";
 import EquipmentAcceptance from "./component/equipmentAcceptance.vue";
-import QuantityValueTraceabilityPlan from "./component/quantityValueTraceabilityPlan.vue";
 import equipmentMaintenance from "./component/equipmentMaintenance.vue";
 import usageAuthorization from "./component/usageAuthorization.vue";
 import {
@@ -144,7 +139,6 @@
 export default {
   name: 'Device',
   components: {
-    QuantityValueTraceabilityPlan,
     EquipmentAcceptance,
     EquipmentMaintenancePlan,
     EquipmentAccident,

--
Gitblit v1.9.3