设备模块调整:档案修订新增保养、核查日期与周期并自动计算下次日期,列表新增核查、保养相关列且到期前一个月标红;设备校准的服务机构改为合格供应商下拉,使用授权的被授权人改为检测员下拉;设备树改为全部/设备/计量器具分类;保养计划明细新增计划保养时间;移除量值溯源计划页签
已修改8个文件
416 ■■■■■ 文件已修改
src/views/CNAS/resourceDemand/device/component/calibration.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/resourceDemand/device/component/deviceOverview.vue 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/resourceDemand/device/component/equipmentMaintenance.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/resourceDemand/device/component/equipmentMaintenancePlan.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/resourceDemand/device/component/files.vue 112 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/resourceDemand/device/component/management.vue 217 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/resourceDemand/device/component/usageAuthorization.vue 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/CNAS/resourceDemand/device/index.vue 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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)
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的展示,默认为true
      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,存在value代表为三级
      // 存在value代表选中了设备,由设备详情展示处理
      if (!clickNodeVal.value) {
        this.finishLoding = false;
        this.keyMap = {};
        this.currentPage = 1;
        this.list = [];
        this.entity.laboratoryName = null
        this.entity.storagePoint = null
        // 等于1代表为树的一级,label为部门
        if (clickNodeVal.label == '其他') {
          this.laboratoryNameIsNull = true
          this.refreshTable();
          return
        }
        if (clickNodeVal.level == 1) {
          this.entity.laboratoryName = clickNodeVal.label
          // 等于二级。label为存储地点
        } 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();
      }
    }
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 {
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>
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,Vue3 已移除 filters 选项,改为方法调用
    formaterDateTime(dateTime) {
      if (dateTime === undefined || dateTime === null || dateTime === '') {
@@ -602,8 +632,6 @@
    openFileRevisionDialog() {
      // 获取档案修订负责人下拉框数据
      this.selectDevicePrincipal()
      // 获取档案修订所属部门下拉框数据
      this.obtainItemParameterList()
      // 获取档案修订设备状态下拉框数据
      this.selectEnumByCategory()
      // 获取档案修订检验项目级联弹框数据
@@ -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
      }
    },
    //修订档案
    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() {
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')
            }
        },
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: {
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,