src/views/business/inspectionTask/components/InspectionWord.vue
@@ -26,6 +26,38 @@
            </el-select>
          </div>
        </div>
        <div class="template-panel">
          <el-form :inline="true" :model="currentOtherForm" class="form-inline" size="small" label-width="84px">
            <el-form-item label="温度:">
              <el-input v-model="currentOtherForm.temperature" :disabled="state > 1" placeholder="" size="small"
                style="width: 90px" @change="m => subOtherForm(m, 'temperature')"></el-input>
              <span class="template-panel__unit">℃</span>
            </el-form-item>
            <el-form-item label="湿度:">
              <el-input v-model="currentOtherForm.humidity" :disabled="state > 1" placeholder="" size="small"
                style="width: 90px" @change="m => subOtherForm(m, 'humidity')"></el-input>
              <span class="template-panel__unit">%RH</span>
            </el-form-item>
            <el-form-item label="检测时间:">
              <el-date-picker v-model="currentOtherForm.detectionTime" :disabled="state > 1" type="date"
                value-format="yyyy-MM-dd" placeholder="请选择日期" size="small" style="width: 160px"
                @change="m => subOtherForm(m, 'detectionTime')"></el-date-picker>
            </el-form-item>
            <el-form-item label="检测地点:">
              <el-input v-model="currentOtherForm.detectionPlace" :disabled="state > 1" clearable
                placeholder="请输入检测地点" size="small" style="width: 200px"
                @change="m => subOtherForm(m, 'detectionPlace')"></el-input>
            </el-form-item>
            <el-form-item v-if="isDirectTemplateOrder()" label="设备:">
              <el-select v-model="currentOtherForm.deviceIds" :disabled="state != 1" multiple filterable clearable
                size="small" placeholder="请选择设备" style="width: 360px"
                @change="m => subOtherForm(m, 'deviceIds')">
                <el-option v-for="device in deviceOptions" :key="device.id" :label="device.label"
                  :value="device.id" />
              </el-select>
            </el-form-item>
          </el-form>
        </div>
        <!-- 常规检验原始记录 -->
        <div id="tableBox" v-loading="tableLoading" class="center-box">
          <table v-for="(item, index) in tableList" :key="index + currentTable + currentSample.id" border="1"
@@ -149,15 +181,6 @@
            </el-select>
          </div>
        </div>
        <div class="body" style="display: flex;padding: 10px;align-items: center;">
          <div class="search_label" style="width: 150px;"><span class="required-span">*</span>报告类型</div>
          <div class="search_input" style="width: 100%;">
            <el-select v-model="reportType" clearable placeholder="请选择" size="small" style="width: 100%;">
              <el-option label="检测报告" :value="0"></el-option>
              <el-option label="检验报告" :value="1"></el-option>
            </el-select>
          </div>
        </div>
        <span slot="footer" class="dialog-footer">
          <el-button @click="addVerifyDia = false">取 消</el-button>
          <el-button :loading="submitLoading" type="primary" @click="submit()">确 定</el-button>
@@ -229,7 +252,8 @@
  getInsProductUnqualifiedRetest,
  search, selectUserCondition,
  submitPlan,
  verifyPlan
  verifyPlan,
  write
} from "@/api/business/inspectionTask";
import { getUserNow, saveUnqualifiedContext } from "@/api/business/rawMaterialOrder";
import InspectionWorker from '@/workers/InspectionWorker.worker';
@@ -335,7 +359,6 @@
      widthList: [],
      addVerifyDia: false,
      verifyUser: null,
      reportType: null,
      personList: [],
      enumList: [],
      tableLoading: false,
@@ -350,10 +373,9 @@
      numOptions: [],
      temperatureOptions: [],
      wareTableData: [],
      otherForm: {
        humidity: null,
        temperature: null,
      },
      // 检测条件按模板 id 分组:{ [templateId]: { temperature, humidity, detectionTime, detectionPlace, deviceIds } }
      otherForm: {},
      deviceOptions: [],
      equipForm: {
        value0: null,
        code0: null,
@@ -428,6 +450,16 @@
    },
    action() {
      return this.javaApi + "/insOrderPlan/uploadFile";
    },
    // 当前模板对应的检测条件
    currentOtherForm() {
      return this.otherForm[this.currentTable] || {
        temperature: null,
        humidity: null,
        detectionTime: null,
        detectionPlace: null,
        deviceIds: []
      }
    }
  },
  created() {
@@ -463,15 +495,25 @@
        this.sampleProduct = res.data.sampleProduct
        this.currentSample = this.HaveJson(this.sampleProduct[0])
        let insProduct = this.HaveJson(this.currentSample.insProduct)
        // 温度、湿度赋值
        this.otherForm = {
          temperature: this.insOrder.temperature ? this.insOrder.temperature : null,
          humidity: this.insOrder.humidity ? this.insOrder.humidity : null,
        }
        // 检测条件赋值:按模板 id 分组回显
        this.otherForm = {}
        const conditionList = this.insOrder.templateConditions || []
        conditionList.forEach(item => {
          this.$set(this.otherForm, item.templateId, {
            temperature: item.temperature != null ? item.temperature : null,
            humidity: item.humidity != null ? item.humidity : null,
            detectionTime: item.detectionTime != null ? item.detectionTime : null,
            detectionPlace: item.detectionPlace != null ? item.detectionPlace : null,
            deviceIds: Array.isArray(item.deviceIds) ? [...item.deviceIds] : []
          })
        })
        if (this.typeSource == '1') {
          this.retestTag = '1'
        }
        this.getEquipOptions(1)
        if (this.sonLaboratory === '新聚') {
          this.loadDeviceOptions()
        }
        // 获取当前样品的检验项
        let list = await this.getCurrentProduct(this.currentSample.id, 0)
        if (list === undefined) {
@@ -525,6 +567,8 @@
            if (this.tableLists && this.tableLists.length > 0) {
              this.tableList = null;
              this.tableList = this.tableLists.filter(m => m.templateId == val1)
              // 模板集合可能变化,补齐温度、湿度槽位
              this.tableLists.forEach(m => this.ensureOtherForm(m.templateId))
              // 对模板进行处理
              this.handleTableData()
            }
@@ -856,6 +900,8 @@
        this.tableList = null;
        this.tableList = [this.tableLists[0]]
        this.currentTable = this.tableLists[0].templateId;
        // 补齐每个模板的温度、湿度槽位
        this.tableLists.forEach(m => this.ensureOtherForm(m.templateId))
        // 处理页面列表数据
        this.handleTableData()
      }
@@ -885,6 +931,8 @@
        this.tableList = [this.tableLists[0]]
        this.currentTable = this.tableLists[0].templateId;
        this.currentSample.insProduct = this.HaveJson(list)
        // 补齐每个模板的温度、湿度槽位
        this.tableLists.forEach(m => this.ensureOtherForm(m.templateId))
        // 处理页面列表数据
        this.handleTableData()
      }
@@ -1220,15 +1268,24 @@
    // 对输入值进行格式校验
    handleInput(n) {
      try {
        n.v.v = n.v.v.replace(/[^\d.^e>\-/+]/g, '');
        n.v.v = n.v.v.replace(/\.{2,}/g, "."); //只保留第一个. 清除多余的
        n.v.v = n.v.v.replace(".", "$#$").replace(/\./g, "").replace("$#$", ".");
        n.v.v = n.v.v.replace(/\/{2,}/g, "/"); //只保留第一个/清除多余的
        n.v.v = n.v.v.replace("/", "$#$").replace(/\//g, "").replace("$#$", "/");
        const v = n.v.v;
        // 能力范围已废弃,检验值类型不再作为判断依据。整串只由算式字符组成时才规范化格式,
        // 出现中文等其它字符即按文本处理原样保留,否则文字会被逐字删掉
        if (typeof v !== "string" || /[^\d.^e>>≥≤<<断裂脆化\-/+]/.test(v)) {
          return;
        }
        n.v.v = v
          .replace(/\.{2,}/g, ".") //只保留第一个. 清除多余的
          .replace(".", "$#$")
          .replace(/\./g, "")
          .replace("$#$", ".")
          .replace(/\/{2,}/g, "/") //只保留第一个/清除多余的
          .replace("/", "$#$")
          .replace(/\//g, "")
          .replace("$#$", "/");
      } catch (error) {
        console.log(error);
      }
    },
    getInspectionItemType(id) {
      for (var a in this.currentSample.insProduct) {
@@ -1288,6 +1345,21 @@
        })
      }
    },
    // 新聚直接绑定模板的单据,设备按模板选择
    isDirectTemplateOrder() {
      return this.sonLaboratory === '新聚' && this.currentSample &&
        (this.currentSample.insProduct || []).some(product => product.templateRowIndex != null)
    },
    loadDeviceOptions() {
      search({ status: 0 }).then(res => {
        this.deviceOptions = (res.data || []).map(device => ({
          id: device.id,
          label: `${device.deviceName}--${device.managementNumber}`
        }))
      }).catch(error => {
        console.error(error)
      })
    },
    getUserInfo() {
      getUserNow().then(res => {
        this.userId = res.data.id
@@ -1342,28 +1414,60 @@
        this.$message.error('未输入不通过原因')
      }
    },
    // 保证模板的检测条件槽位存在
    ensureOtherForm(templateId) {
      if (templateId == null) return
      if (!this.otherForm[templateId]) {
        this.$set(this.otherForm, templateId, {
          temperature: null,
          humidity: null,
          detectionTime: null,
          detectionPlace: null,
          deviceIds: []
        })
      }
    },
    // 保存当前模板的检测条件
    subOtherForm(m, type) {
      const payload = {
        id: this.insOrder.id,
        templateId: this.currentTable
      }
      if (type === 'deviceIds') {
        payload.deviceIds = Array.isArray(m) ? [...m] : []
      } else if (type === 'detectionTime' || type === 'detectionPlace') {
        payload[type] = m === '' || m == null ? null : m
      } else {
        payload[type] = Number(m)
      }
      write(payload).then(res => {
        this.$message.success("保存成功")
      })
    },
    submit() {
      if (this.verifyUser === null || this.verifyUser === '') {
        this.$message.error("请指定复核人员")
        return
      }
      if (this.reportType === null || this.reportType === '') {
        this.$message.error("请选择报告类型")
        return
      }
      if (!this.otherForm.humidity) {
        this.$message.error("请输入湿度")
        return
      }
      if (!this.otherForm.temperature) {
        this.$message.error("请输入温度")
      const missing = []
      this.tableLists.forEach(m => {
        const form = this.otherForm[m.templateId] || {}
        if (!form.temperature) missing.push(`请填写「${m.templateName}」的温度`)
        if (!form.humidity) missing.push(`请填写「${m.templateName}」的湿度`)
        if (!form.detectionTime) missing.push(`请选择「${m.templateName}」的检测时间`)
        if (!form.detectionPlace) missing.push(`请填写「${m.templateName}」的检测地点`)
        if (this.isDirectTemplateOrder() && (!form.deviceIds || form.deviceIds.length === 0)) {
          missing.push(`请选择「${m.templateName}」的设备`)
        }
      })
      if (missing.length > 0) {
        this.$message.error(missing[0])
        return
      }
      this.submitLoading = true;
      checkSubmitPlan({
        orderId: this.orderId,
        laboratory: this.sonLaboratory,
        reportType: this.reportType,
      }).then(res => {
        if (res.code === 200) {
          if (!res.data || res.data.errorMsg.length == 0) {
@@ -1373,8 +1477,7 @@
              laboratory: this.sonLaboratory,
              verifyUser: this.verifyUser,
              entrustCode: this.insOrder.entrustCode,
              registerInsResults: this.reportType === 1,
              reportType: this.reportType
              registerInsResults: false,
            }).then(res => {
              if (res.code === 200) {
                this.$message.success("操作成功")
@@ -1410,7 +1513,6 @@
                laboratory: this.sonLaboratory,
                verifyUser: this.verifyUser,
                registerInsResults: false,
                reportType: this.reportType
              }).then(res => {
                if (res.code === 200) {
                  this.$message.success("操作成功")
@@ -1689,6 +1791,32 @@
  text-align: left;
}
/* 当前检验模板的检测条件 */
.template-panel {
  background-color: #f8f9fb;
  border: 1px solid #ebeef5;
  border-radius: 3px;
  padding: 16px 16px 4px;
  margin-top: 12px;
  text-align: left;
}
/* form-item 用 inline-flex 保证 label 与控件同行,不依赖行盒宽度推算 */
.template-panel>>>.el-form-item {
  display: inline-flex;
  align-items: center;
  margin-bottom: 12px;
}
.template-panel>>>.el-form-item__label {
  flex: none;
}
.template-panel__unit {
  margin-left: 4px;
  color: #606266;
}
.center {
  width: calc(100% - 40px);
  /* max-height: 580px; */