src/views/business/inspectionView/index.vue
@@ -45,7 +45,7 @@
          <el-input v-model="currentSample.sample" clearable disabled placeholder="请输入" size="small"></el-input>
        </el-form-item>
        <el-form-item label="样品数量:">
          <el-input v-model="sampleProduct.length" clearable disabled placeholder="请输入" size="small"></el-input>
          <el-input v-model="insOrder.testQuantity" clearable disabled placeholder="请输入" size="small"></el-input>
        </el-form-item>
        <el-form-item label="样品型号:">
          <el-input v-model="currentSample.model" clearable disabled placeholder="请输入" size="small"></el-input>
@@ -73,6 +73,12 @@
          <el-input v-model="insOrder.remark" :disabled="state != 1" clearable placeholder="请输入" size="small"
                    @blur="subOtherForm(insOrder.remark, 'remark')"></el-input>
          <!-- <el-tag v-if="currentKey">{{ insOrder.remark }}</el-tag> -->
        </el-form-item>
        <el-form-item label="检验结论:">
          <el-radio-group v-model="reviewInsResult" :disabled="state != 2">
            <el-radio :label="1">合格</el-radio>
            <el-radio :label="0">不合格</el-radio>
          </el-radio-group>
        </el-form-item>
      </el-form>
    </div>
@@ -205,8 +211,8 @@
                          " />
                    <span v-else-if="getInspectionValueType(n.i) == 4"
                          :style="`font-family:${n.v.ff} !important;`">/</span>
                  </template>
                  <template v-else-if="
                    </template>
                    <template v-else-if="
                      n.v.ps != undefined && n.v.ps.value === '设备名称'
                    ">
                    <el-select v-model="n.v.v" :disabled="state > 1" class="table_input" filterable multiple
@@ -334,17 +340,6 @@
          <el-select v-model="verifyUser" clearable filterable placeholder="请选择" size="small" style="width: 100%">
            <el-option v-for="(item, i) in personList" :key="i" :label="item.label" :value="item.value">
            </el-option>
          </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>
@@ -486,6 +481,7 @@
  checkSubmitPlan,
  submitPlan,
  saveInsContext,
  saveTemplateContext,
  selectUserCondition,
  downFile,
  getFileList,
@@ -546,6 +542,8 @@
      ps: {},
      param: {},
      saveQueue: null,
      calculationRevision: 0,
      completedCalculationRevision: 0,
      currentKey: 1,
      currentKey0: 1,
      currentKey1: 1,
@@ -556,13 +554,13 @@
      reviewLoading: false,
      reviewDia: false,
      noReason: "",
      reviewInsResult: null,
      tableWidth: 1000,
      currentTable: null,
      tableLists: [],
      widthList: [],
      addVerifyDia: false,
      verifyUser: null,
      reportType: null,
      personList: [],
      enumList: [],
      tableLoading: false,
@@ -875,13 +873,15 @@
      this.checkUser = "";
    },
    // 刷新页面
    refreshView() {
    async refreshView() {
      await this.waitForPendingSaves();
      this.loading = true;
      doInsOrder({
        id: this.id,
        laboratory: this.sonLaboratory,
      }).then(async (res) => {
        this.insOrder = res.data.insOrder;
        this.reviewInsResult = this.insOrder.insResult;
        this.supplierDensity = res.data.supplierDensity;
        this.getList()
        this.urgentList.forEach((m) => {
@@ -1802,6 +1802,7 @@
        }
      }
      try {
        const revision = ++this.calculationRevision;
        // 向 Worker 发送消息,开始处理逻辑
        this.worker.postMessage(
          JSON.stringify({
@@ -1816,6 +1817,7 @@
            getDataTypeId: this.getDataTypeId,
            modelType: this.sampleProduct[0].model,
            currentInsItem: n,
            revision: revision,
          })
        );
        // 先保存主线程中已经输入的原始值。Worker 完成计算后会再次入队保存计算结果。
@@ -1830,6 +1832,9 @@
      // 监听 Worker 返回的结果
      this.worker.onmessage = (event) => {
        const workerResult = JSON.parse(event.data);
        if (workerResult.revision != null && workerResult.revision < this.calculationRevision) {
          return;
        }
        this.result = workerResult;
        switch (workerResult.method) {
          case "saveInsContext":
@@ -1842,6 +1847,10 @@
              );
              this.param = resultValue.param;
              this.saveInsContext();
              this.completedCalculationRevision = Math.max(
                this.completedCalculationRevision,
                workerResult.revision || 0
              );
            });
            break;
          case "tableList":
@@ -1961,6 +1970,10 @@
    upInsReview(e) {
      if (e == 1) {
        // 通过
        if (this.reviewInsResult !== 0 && this.reviewInsResult !== 1) {
          this.$message.error("请选择检验结论");
          return;
        }
        this.reviewLoading = true;
        verifyPlan({
          orderId: this.orderId,
@@ -1968,6 +1981,7 @@
          laboratory: this.sonLaboratory,
          tell: null,
          userId: this.checkUser,
          insResult: this.reviewInsResult,
        }).then((res) => {
          if (res.code === 200) {
            this.$message.success("操作成功");
@@ -2013,16 +2027,11 @@
      this.$refs.viewManHourDia.showDialog(this.id, 99);
    },
    openAddVerifyDia() {
      this.reportType = null;
      this.addVerifyDia = true;
    },
    submit() {
    async 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) {
@@ -2033,11 +2042,11 @@
        this.$message.error("请输入温度");
        return;
      }
      await this.waitForPendingSaves();
      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) {
@@ -2047,8 +2056,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("操作成功");
@@ -2101,7 +2109,6 @@
                  laboratory: this.sonLaboratory,
                  verifyUser: this.verifyUser,
                  registerInsResults: false,
                  reportType: this.reportType,
                }).then((res) => {
                  if (res.code === 200) {
                    this.$message.success("操作成功");
@@ -2130,7 +2137,17 @@
      const param = {};
      this.tableList.forEach((a) => {
        param[a.templateId] = {};
        a.template.forEach((cell) => {
        // Worker 回传后 arr 是页面上的最新对象,template 仍可能保留计算前的旧值。
        const cells = a.arr && a.arr.length
          ? a.arr.reduce((all, row) => all.concat(row), [])
          : a.template;
        const resultHeader = cells.find((cell) =>
          cell.v && String(cell.v.v || "").trim() === "检验结果"
        );
        const exportRows = new Set(cells.filter((cell) =>
          cell.v && cell.v.ps && cell.v.ps.value === "导出值"
        ).map((cell) => cell.r));
        cells.forEach((cell) => {
          const isEditable =
            cell.v.ps != undefined &&
            typeof cell.v.ps.value === "string" &&
@@ -2138,10 +2155,12 @@
              cell.v.ps.value === "计算值" ||
              cell.v.ps.value === "最终值" ||
              cell.v.ps.value === "设备名称");
          if (!isEditable) {
          const isExportResult = resultHeader && exportRows.has(cell.r) && cell.c === resultHeader.c;
          if (!isEditable && !isExportResult) {
            return;
          }
          if (
            isEditable &&
            cell.v.ps.value.includes("检验值") &&
            (cell.v.v === "" || cell.v.v === null || cell.v.v === undefined)
          ) {
@@ -2187,7 +2206,14 @@
        const previousSave = this.saveQueue || Promise.resolve();
        this.saveQueue = previousSave
          .catch(() => undefined)
          .then(() => saveInsContext(payload))
          .then(() => this.isDirectTemplateOrder()
            ? saveTemplateContext({
                orderId: this.orderId,
                sampleId: this.currentSample.id,
                templateId: this.currentTable,
                values: param[this.currentTable] || {},
              })
            : saveInsContext(payload))
          .then(() => {
            this.$message.success("已保存");
          })
@@ -2230,6 +2256,29 @@
      // 选择、移除、清空均由 change 事件触发,立即保存。
      this.saveInsContext();
    },
    isDirectTemplateOrder() {
      return this.sonLaboratory === "新聚" && this.currentSample &&
        (this.currentSample.insProduct || []).some((product) => product.templateRowIndex != null);
    },
    async waitForPendingSaves() {
      const targetRevision = this.calculationRevision;
      if (this.completedCalculationRevision < targetRevision) {
        await new Promise((resolve) => {
          const startedAt = Date.now();
          const waitWorker = () => {
            if (this.completedCalculationRevision >= targetRevision || Date.now() - startedAt > 5000) {
              resolve();
              return;
            }
            setTimeout(waitWorker, 20);
          };
          waitWorker();
        });
      }
      if (this.saveQueue) {
        await this.saveQueue;
      }
    },
    getAuthorizedPerson() {
      selectUserCondition({ type: 1 }).then((res) => {
        let data = [];