src/views/CNAS/resourceDemand/device/component/files.vue
@@ -180,176 +180,199 @@
    <!-- 修订 -->
    <el-dialog title="档案修订" top="5vh" v-model="dialogVisible" width="70%" @open="openFileRevisionDialog"
      :before-close="handleClose">
      <el-row style="display:flex;justify-content: space-around;max-height: 75vh;overflow-y: auto;">
        <!-- 左边布局 -->
        <el-col :span="7">
          <el-col>
            <!-- 图片 -->
            <el-image class="img" style="width:100%;height: 320px;margin-bottom:16px"
              :src="javaApi + '/img/' + editData.imageUpload">
              <template #error><div  class="image-error" style="width: calc(100% - 2px);
      <div style="max-height: 75vh;overflow-y: auto;">
      <!-- 顶部:图片 + 基本信息 -->
      <el-row>
        <el-col :span="7" style="padding-right: 20px;">
          <!-- 图片 -->
          <el-image class="img" style="width:100%;height: 320px;"
            :src="javaApi + '/img/' + editData.imageUpload">
            <template #error><div  class="image-error" style="width: calc(100% - 2px);
            height: 318px;
            border-radius: 16px;
            display: flex;
            align-items: center;
            justify-content: center;
            border: 1px solid var(--lims-divider);">
                <lims-icon name="el-icon-picture-outline" style="font-size:60px;color:var(--lims-text-2);"></lims-icon>
              </div></template>
            </el-image>
            <!-- 表单 -->
            <el-form :model="editData" label-width="120px" ref="rules1" :rules="rules1">
              <lims-icon name="el-icon-picture-outline" style="font-size:60px;color:var(--lims-text-2);"></lims-icon>
            </div></template>
          </el-image>
          <!-- 图片上传 -->
          <div style="margin-top: 12px;text-align: center;">
            <div v-show="editData.imageName" class="picName">{{ editData.imageName }}</div>
            <el-upload :action="action" :on-success="handleSuccessUpImg2" :show-file-list="false"
              accept='image/jpg,image/jpeg,image/png' :headers="uploadHeader" :on-change="beforeUpload"
              :on-error="onError" ref='upload' class="avatar-uploader">
              <img v-if="editData.imageUpload" :src="javaApi + '/img/' + editData.imageUpload" class="avatar">
              <lims-icon name="el-icon-plus" v-else class="avatar-uploader-icon"></lims-icon>
            </el-upload>
          </div>
        </el-col>
        <el-col :span="17">
          <!-- 基本信息 -->
          <div class="section-title" style="margin-top: 0;">基本信息</div>
          <el-form :model="editData" label-width="120px" ref="rules1" :rules="rules1">
            <div class="form-row">
              <el-form-item label="仪器名称:" prop="deviceName">
                <el-input v-model="editData.deviceName" size="small"></el-input>
              </el-form-item>
              <el-form-item label="仪器名称EN:" prop="enDeviceName">
                <el-input v-model="editData.enDeviceName" size="small"></el-input>
              </el-form-item>
            </div>
            <div class="form-row">
              <el-form-item label="规格型号:" prop="specificationModel">
                <el-input v-model="editData.specificationModel" size="small"></el-input>
              </el-form-item>
              <el-form-item label="生产厂家:">
                <el-input v-model="editData.manufacturer" size="small"></el-input>
              </el-form-item>
            </el-form>
          </el-col>
        </el-col>
        <!-- 中间布局 -->
        <el-col :span="7">
          <el-form :model="editData" label-width="116px" ref="rules2" :rules="rules1">
            <el-form-item label="校准服务机构:">
              <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>
            </el-form-item>
            <el-form-item label="产地:">
              <el-input v-model="editData.origin" size="small"></el-input>
            </el-form-item>
            <el-form-item label="出厂编号:">
              <el-input v-model="editData.factoryNo" size="small"></el-input>
            </el-form-item>
            <el-form-item label="管理编号:" prop="managementNumber">
              <el-input v-model="editData.managementNumber" size="small"></el-input>
            </el-form-item>
            <el-form-item label="购置日期:">
              <el-date-picker style="width:100%" v-model="editData.acquisitionDate" type="date" format="YYYY-MM-DD"
                value-format="YYYY-MM-DD HH:mm:ss" size="small" placeholder="选择日期">
              </el-date-picker>
            </el-form-item>
            <el-form-item label="校准有效期:" prop="activationDate">
              <el-date-picker style="width:100%" v-model="editData.activationDate" type="date" format="YYYY-MM-DD"
                value-format="YYYY-MM-DD HH:mm:ss" size="small" placeholder="选择日期">
              </el-date-picker>
            </el-form-item>
            <el-form-item label="负责人:">
              <el-select v-model="editData.equipmentManager" placeholder="请选择" size="small" style="width:100%">
                <el-option v-for="item in responsiblePersonList" :key="item.name" :label="item.name" :value="item.id">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="存放点:">
              <el-input v-model="editData.storagePoint" size="small"></el-input>
            </el-form-item>
            <el-form-item label="技术指标:">
              <el-input v-model="editData.technicalIndicators" :rows="7" type="textarea" size="small"></el-input>
            </el-form-item>
          </el-form>
        </el-col>
        <!-- 右边布局 -->
        <el-col :span="7">
          <el-form :model="editData" label-width="140px" ref="ruleForm" :rules="rules1">
            <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
                clearable></el-cascader>
            </el-form-item>
            <el-form-item label="最近校准日期:">
              <el-date-picker style="width:100%" v-model="editData.lastCalibrationDate" 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 style="width:100%" v-model="editData.nextCalibrationDate" 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-select v-model="editData.largeCategory" placeholder="请选择" size="small" style="width:100%">
                <el-option v-for="item in equipmentList" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="单价(万元):">
              <el-input v-model="editData.unitPrice" size="small"></el-input>
            </el-form-item>
            <el-form-item label="当前状态:" prop="deviceStatus">
              <el-select v-model="editData.deviceStatus" placeholder="请选择" size="small" style="width:100%">
                <el-option v-for="item in deviceStatusList" :key="item.value" :label="item.label" :value="item.value">
                </el-option>
              </el-select>
            </el-form-item>
            <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 inspectorList" :key="item.name" :label="item.name" :value="item.id">
                </el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="图片:">
              <!-- <div
                style="border: 1px solid var(--el-border-color);border-radius:4px;height:32px;lineHeight:32px;display:flex;justify-content: space-around;font-size: 13px;">
                <div v-show="Mdata.imageName" class="picName">{{ Mdata.imageName }}</div>
                <el-upload :action="action" :on-success="handleSuccessUpImg2" :show-file-list="false"
                  accept='image/jpg,image/jpeg,image/png' :headers="headers" :on-change="beforeUpload"
                  :on-error="onError" ref='upload'>
                  <el-button type="text" style="height:30px;padding-top:8px"><span v-if="Mdata.imageName"></span></el-button>
                </el-upload>
              </div> -->
              <div>
                <div v-show="editData.imageName" class="picName">{{ editData.imageName }}</div>
                <el-upload :action="action" :on-success="handleSuccessUpImg2" :show-file-list="false"
                  accept='image/jpg,image/jpeg,image/png' :headers="uploadHeader" :on-change="beforeUpload"
                  :on-error="onError" ref='upload' class="avatar-uploader">
                  <img v-if="editData.imageUpload" :src="javaApi + '/img/' + editData.imageUpload" class="avatar">
                  <lims-icon name="el-icon-plus" v-else class="avatar-uploader-icon"></lims-icon>
                </el-upload>
              </div>
            </el-form-item>
            </div>
            <div class="form-row">
              <el-form-item label="产地:">
                <el-input v-model="editData.origin" size="small"></el-input>
              </el-form-item>
              <el-form-item label="出厂编号:">
                <el-input v-model="editData.factoryNo" size="small"></el-input>
              </el-form-item>
            </div>
            <div class="form-row">
              <el-form-item label="资产编码:">
                <el-input v-model="editData.assetCode" size="small"></el-input>
              </el-form-item>
              <el-form-item label="管理编号:" prop="managementNumber">
                <el-input v-model="editData.managementNumber" size="small"></el-input>
              </el-form-item>
            </div>
            <div class="form-row">
              <el-form-item label="购置日期:">
                <el-date-picker style="width:100%" v-model="editData.acquisitionDate" type="date" format="YYYY-MM-DD"
                  value-format="YYYY-MM-DD HH:mm:ss" size="small" placeholder="选择日期">
                </el-date-picker>
              </el-form-item>
              <el-form-item label="校准有效期:" prop="activationDate">
                <el-date-picker style="width:100%" v-model="editData.activationDate" type="date" format="YYYY-MM-DD"
                  value-format="YYYY-MM-DD HH:mm:ss" size="small" placeholder="选择日期">
                </el-date-picker>
              </el-form-item>
            </div>
            <div class="form-row">
              <el-form-item label="校准服务机构:">
                <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>
              <div style="flex: 1;"></div>
            </div>
          </el-form>
        </el-col>
      </el-row>
      <!-- 设备管理 -->
      <div class="section-title">设备管理</div>
      <el-form :model="editData" label-width="120px" ref="rules2" :rules="rules1">
        <div class="form-row">
          <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
              clearable></el-cascader>
          </el-form-item>
          <el-form-item label="设备类型:">
            <el-select v-model="editData.largeCategory" placeholder="请选择" size="small" style="width:100%">
              <el-option v-for="item in equipmentList" :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="单价(万元):">
            <el-input v-model="editData.unitPrice" size="small"></el-input>
          </el-form-item>
        </div>
        <div class="form-row">
          <el-form-item label="当前状态:" prop="deviceStatus">
            <el-select v-model="editData.deviceStatus" placeholder="请选择" size="small" style="width:100%">
              <el-option v-for="item in deviceStatusList" :key="item.value" :label="item.label" :value="item.value">
              </el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="负责人:">
            <el-select v-model="editData.equipmentManager" placeholder="请选择" size="small" style="width:100%">
              <el-option v-for="item in responsiblePersonList" :key="item.name" :label="item.name" :value="item.id">
              </el-option>
            </el-select>
          </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 inspectorList" :key="item.name" :label="item.name" :value="item.id">
              </el-option>
            </el-select>
          </el-form-item>
        </div>
        <div class="form-row">
          <el-form-item label="存放点:">
            <el-input v-model="editData.storagePoint" size="small"></el-input>
          </el-form-item>
          <div style="flex: 1;"></div>
        </div>
      </el-form>
      <!-- 校准/保养/核查 周期信息 -->
      <el-form :model="editData" :rules="rules1" ref="cycleForm" label-width="140px"
        style="margin-top: 12px;border-top: 1px solid var(--lims-divider);padding-top: 4px;">
        <div class="cycle-row">
          <span class="cycle-title">校准信息</span>
          <el-form-item label="最近校准日期:" class="cycle-item">
            <el-date-picker style="width:100%" v-model="editData.lastCalibrationDate" 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="下次校准日期:" class="cycle-item">
            <el-date-picker style="width:100%" v-model="editData.nextCalibrationDate" 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="校准周期(月):" prop="calibrationDate" class="cycle-item">
            <el-input v-model="editData.calibrationDate" size="small"></el-input>
          </el-form-item>
        </div>
        <div class="cycle-row">
          <span class="cycle-title">保养信息</span>
          <el-form-item label="最近保养日期:" class="cycle-item">
            <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="下次保养日期:" class="cycle-item">
            <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="保养周期(月):" class="cycle-item">
            <el-input v-model="editData.maintenanceCycle" size="small" @change="calcNextDate(editData)"></el-input>
          </el-form-item>
        </div>
        <div class="cycle-row">
          <span class="cycle-title">核查信息</span>
          <el-form-item label="最近核查日期:" class="cycle-item">
            <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="下次核查日期:" class="cycle-item">
            <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="核查周期(月):" class="cycle-item">
            <el-input v-model="editData.examineCycle" size="small" @change="calcNextDate(editData)"></el-input>
          </el-form-item>
        </div>
      </el-form>
      <!-- 技术指标 -->
      <div class="section-title">技术指标</div>
      <el-form :model="editData" ref="ruleForm" :rules="rules1">
        <el-form-item>
          <el-input v-model="editData.technicalIndicators" :rows="7" type="textarea" size="small"></el-input>
        </el-form-item>
      </el-form>
      </div>
      <template #footer><span  class="dialog-footer">
        <el-row>
          <el-button @click="handleClose">取 消</el-button>
@@ -734,6 +757,27 @@
          this.tableDataA = res.data
      })
    },
    // 被授权人历史值可能是被反复转义的多层 JSON 字符串,逐层解析还原成数组
    normalizeAuthorizedPerson(val) {
      let v = val
      for (let i = 0; i < 10; i++) {
        if (typeof v !== 'string') break
        if (v === '') {
          v = []
          break
        }
        try {
          v = JSON.parse(v)
        } catch (e) {
          v = []
          break
        }
      }
      if (!Array.isArray(v)) {
        v = v === '' || v === null || v === undefined ? [] : [v]
      }
      return v.filter(x => x !== '' && x !== null && x !== undefined)
    },
    // 收集数据
    getList(id) {
      selectDeviceByCode({ id }).then(res => {
@@ -741,9 +785,7 @@
        if (res.code == 200) {
          this.Mdata = res.data;
          this.Mdata.insProductIds = this.Mdata.insProductIds.split(',')
          if (this.Mdata.authorizedPerson) {
            this.Mdata.authorizedPerson = JSON.parse(this.Mdata.authorizedPerson)
          }
          this.Mdata.authorizedPerson = this.normalizeAuthorizedPerson(this.Mdata.authorizedPerson)
        }
      });
    },
@@ -809,6 +851,12 @@
          return false;
        }
      });
      this.$refs['cycleForm'].validate((valid) => {
        if (!valid) {
          flag = false;
          return false;
        }
      });
      if (!flag) {
        return;
      }
@@ -820,11 +868,9 @@
      const formData = this.HaveJson(this.editData)
      formData.userAllow = this.equipmentManager.toString();
      formData.insProductIds = Array.isArray(formData.insProductIds) ? formData.insProductIds.join(',') : '';
      if (formData.authorizedPerson.length === 0) {
        formData.authorizedPerson = ''
      } else {
        formData.authorizedPerson = JSON.stringify(formData.authorizedPerson)
      }
      formData.authorizedPerson = Array.isArray(formData.authorizedPerson) && formData.authorizedPerson.length
        ? JSON.stringify(formData.authorizedPerson)
        : ''
      this.upLoad = true;
      upDeviceParameter(formData).then(res => {
        this.$message.success('修改成功')
@@ -974,6 +1020,57 @@
  width: 100%;
}
.cycle-row {
  display: flex;
  align-items: center;
}
.cycle-title {
  width: 68px;
  flex-shrink: 0;
  font-size: 13px;
  color: var(--lims-text-2, #909399);
}
.cycle-item {
  flex: 1;
  margin-bottom: 6px;
  margin-right: 10px;
}
.cycle-item:last-child {
  margin-right: 0;
}
.form-row {
  display: flex;
  gap: 16px;
}
.form-row > .el-form-item {
  flex: 1;
}
.section-title {
  position: relative;
  padding-left: 10px;
  margin: 14px 0 12px;
  font-size: 13px;
  font-weight: 600;
  color: var(--lims-text-1, #303133);
}
.section-title::before {
  content: "";
  position: absolute;
  left: 0;
  top: 3px;
  bottom: 3px;
  width: 3px;
  border-radius: 2px;
  background: var(--el-color-primary, #409eff);
}
.el-image {
  position: relative;
}