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,存在value代表为三级
         // 存在value代表选中了设备,由设备详情展示处理
         if (!clickNodeVal.value) {
            this.list = [];
            this.queryParams.laboratoryName = null
            this.queryParams.storagePoint = null
            // 等于1代表为树的一级,label为部门
            if (clickNodeVal.label == '其他') {
               this.laboratoryNameIsNull = true
               this.refreshTable('page')
               return
            }
            if (clickNodeVal.level == 1) {
               this.queryParams.laboratoryName = clickNodeVal.label
               // 等于二级。label为存储地点
            } 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')
         }
      },