gaoluyang
3 小时以前 e449a5408265e4bd1f6c66f5be28a42efac444ee
src/pages/qualityManagement/finalInspection/add.vue
@@ -125,7 +125,13 @@
      <view class="inspection-items-container">
        <view class="steps-header">
          <text class="steps-title">检验项目</text>
          <text class="steps-count">共 {{ tableData.length }} 个项目</text>
          <view class="steps-header-right">
            <text class="steps-count">共 {{ tableData.length }} 个项目</text>
            <up-button type="primary"
                       size="mini"
                       text="追加检测项"
                       @click="addTempItem" />
          </view>
        </view>
        <view class="steps-list">
          <view v-for="(item, index) in tableData"
@@ -137,28 +143,106 @@
            <view class="step-content">
              <view class="step-row">
                <text class="step-label">指标:</text>
                <text class="step-value">{{ item.parameterItem }}</text>
                <up-input v-if="item.isTemp"
                          v-model="item.parameterItem"
                          placeholder="请输入指标名称"
                          border-bottom
                          class="step-input" />
                <text v-else
                      class="step-value">{{ item.parameterItem }}</text>
              </view>
              <view class="step-row">
                <text class="step-label">参数类型:</text>
                <view v-if="item.isTemp"
                      class="type-switch">
                  <text class="type-option"
                        :class="{ active: item.parameterType === TEXT_TYPE }"
                        @click="setTempType(item, TEXT_TYPE)">文字</text>
                  <text class="type-option"
                        :class="{ active: item.parameterType === NUMERIC_TYPE }"
                        @click="setTempType(item, NUMERIC_TYPE)">数字</text>
                </view>
                <text v-else
                      class="step-value">{{ isNumeric(item) ? "数字" : "文字" }}</text>
              </view>
              <!-- 数字型按上下限判定,把上下限摆出来才看得懂自动判定的依据 -->
              <template v-if="isNumeric(item)">
                <view class="step-row">
                  <text class="step-label">最大值:</text>
                  <up-input v-if="item.isTemp"
                            v-model="item.maxValue"
                            type="number"
                            placeholder="请输入最大值"
                            border-bottom
                            class="step-input" />
                  <text v-else
                        class="step-value">{{ item.maxValue }}</text>
                </view>
                <view class="step-row">
                  <text class="step-label">最小值:</text>
                  <up-input v-if="item.isTemp"
                            v-model="item.minValue"
                            type="number"
                            placeholder="请输入最小值"
                            border-bottom
                            class="step-input" />
                  <text v-else
                        class="step-value">{{ item.minValue }}</text>
                </view>
              </template>
              <view class="step-row">
                <text class="step-label">单位:</text>
                <text class="step-value">{{ item.unit }}</text>
                <up-input v-if="item.isTemp"
                          v-model="item.unit"
                          placeholder="请输入单位"
                          border-bottom
                          class="step-input" />
                <text v-else
                      class="step-value">{{ item.unit }}</text>
              </view>
              <view class="step-row">
                <text class="step-label">标准值:</text>
                <text class="step-value">{{ item.standardValue }}</text>
                <up-input v-if="item.isTemp"
                          v-model="item.standardValue"
                          placeholder="请输入标准值"
                          border-bottom
                          class="step-input" />
                <text v-else
                      class="step-value">{{ item.standardValue }}</text>
              </view>
              <view class="step-row">
                <text class="step-label">内控值:</text>
                <text class="step-value">{{ item.controlValue }}</text>
                <up-input v-if="item.isTemp"
                          v-model="item.controlValue"
                          placeholder="请输入内控值"
                          border-bottom
                          class="step-input" />
                <text v-else
                      class="step-value">{{ item.controlValue }}</text>
              </view>
              <view class="step-row">
                <text class="step-label">检验值:</text>
                <up-input v-model="item.testValue"
                          :type="isNumeric(item) ? 'number' : 'text'"
                          placeholder="请输入检验值"
                          clearable
                          border-bottom
                          class="step-input" />
              </view>
              <view class="step-row">
                <text class="step-label">判定:</text>
                <text class="step-value judge-text"
                      :class="itemPassClass(item)">
                  {{ judgeText(item) }}
                </text>
              </view>
            </view>
            <view v-if="item.isTemp"
                  class="delete-btn"
                  @click="removeTempItem(index)">
              <up-icon name="close"
                       size="14"
                       color="#ffffff" />
            </view>
          </view>
          <view v-if="tableData.length === 0"
@@ -302,7 +386,7 @@
</template>
<script setup>
  import { ref, computed, onMounted, nextTick } from "vue";
  import { ref, computed, onMounted, nextTick, watch } from "vue";
  import { onShow, onLoad } from "@dcloudio/uni-app";
  import PageHeader from "@/components/PageHeader.vue";
  import dayjs from "dayjs";
@@ -317,6 +401,13 @@
    list,
  } from "@/api/qualityManagement/materialInspection.js";
  import { userListNoPage } from "@/api/system/user.js";
  import {
    NUMERIC_TYPE,
    TEXT_TYPE,
    createTempItem,
    isItemPass,
    judgeInspectionResult,
  } from "./_utils/inspection";
  // 显示提示信息
  const showToast = message => {
@@ -671,6 +762,54 @@
    });
  };
  // 数字型才有最大/最小值,判定也按上下限走
  const isNumeric = item => item?.parameterType === NUMERIC_TYPE;
  const judgeText = item => {
    const val = item?.testValue;
    if (val === null || val === undefined || val === "") return "-";
    return isItemPass(item) ? "合格" : "不合格";
  };
  const itemPassClass = item => {
    const val = item?.testValue;
    if (val === null || val === undefined || val === "") return "";
    return isItemPass(item) ? "pass" : "fail";
  };
  // 需求九.3:检验值一变就自动判定,口径见 _utils/inspection.js。
  // 与管理端一致,这里无条件覆盖 form.checkResult —— 手工选的检测结果
  // 只是临时兜底,下次改动检验项时会被重新判定覆盖。
  watch(
    tableData,
    rows => {
      const result = judgeInspectionResult(rows);
      if (result) form.value.checkResult = result;
    },
    { deep: true }
  );
  // 需求九.2:临时追加检测项
  const addTempItem = () => {
    tableData.value.push(createTempItem());
  };
  const removeTempItem = index => {
    tableData.value.splice(index, 1);
  };
  // 切类型时清掉不再适用的值,避免文字型残留上下限、数字型残留标准值
  const setTempType = (item, type) => {
    if (item.parameterType === type) return;
    item.parameterType = type;
    if (type === NUMERIC_TYPE) {
      item.standardValue = "";
    } else {
      item.maxValue = null;
      item.minValue = null;
    }
  };
  // 提交表单
  const submitForm = async () => {
    console.log("submitForm", form.value, tableData.value);
@@ -700,10 +839,19 @@
        showToast("请选择检测结果");
        return;
      }
      const missingTemp = tableData.value.find(
        item => item.isTemp && !item.parameterItem
      );
      if (missingTemp) {
        showToast("请填写追加检测项的指标名称");
        return;
      }
      loading.value = true;
      form.value.inspectType = 2;
      // isTemp 只是前端的行标记,不能提交给后端
      tableData.value = tableData.value.map(({ isTemp, ...rest }) => rest);
      if (!isEdit.value) {
        tableData.value.forEach(item => {
          delete item.id;
@@ -931,6 +1079,40 @@
    color: #909399;
  }
  .steps-header-right {
    display: flex;
    align-items: center;
    gap: 10px;
  }
  // 临时追加行的参数类型切换
  .type-switch {
    display: flex;
    align-items: center;
    gap: 8px;
  }
  .type-option {
    padding: 4px 14px;
    font-size: 13px;
    color: #606266;
    background: #f4f4f5;
    border-radius: 12px;
  }
  .type-option.active {
    color: #409eff;
    background: #ecf5ff;
  }
  .judge-text.pass {
    color: #67c23a;
  }
  .judge-text.fail {
    color: #f56c6c;
  }
  .steps-list {
    margin-bottom: 20px;
  }