src/pages/qualityManagement/materialInspection/add.vue
@@ -16,9 +16,9 @@
        <up-input v-model="form.supplier"
                  placeholder="请选择供应商"
                  readonly
                  :disabled="supplierQuantityDisabled" />
                  :disabled="supplierQuantityDisabled || isReadonly" />
        <template #right>
          <up-icon @click="showSupplierSheet = true"
          <up-icon @click="!isReadonly && (showSupplierSheet = true)"
                   name="arrow-right" />
        </template>
      </up-form-item>
@@ -29,10 +29,10 @@
        <up-input v-model="form.productName"
                  placeholder="请选择产品"
                  readonly
                  @click="showProductTree = true"
                  :disabled="isEdit" />
                  @click="!isReadonly && (showProductTree = true)"
                  :disabled="isEdit || isReadonly" />
        <template #right>
          <up-icon @click="showProductTree = true"
          <up-icon @click="!isReadonly && (showProductTree = true)"
                   name="arrow-right" />
        </template>
      </up-form-item>
@@ -43,9 +43,17 @@
        <up-input v-model="form.model"
                  placeholder="请选择规格型号"
                  readonly
                  :disabled="isEdit" />
                  :disabled="isEdit || isReadonly" />
        <template #right>
          <up-icon @click="showModelSheet = true"
          <view v-if="!isEdit"
                class="scan-entry"
                @click.stop="scanBarcode">
            <up-icon name="scan"
                     size="18"
                     color="#3c9cff" />
            <text class="scan-entry-text">扫码</text>
          </view>
          <up-icon @click="!isReadonly && (showModelSheet = true)"
                   name="arrow-right" />
        </template>
      </up-form-item>
@@ -55,7 +63,8 @@
                    border-bottom>
        <up-input v-model="testStandardDisplay"
                  placeholder="请选择指标"
                  readonly />
                  readonly
                  :disabled="isReadonly" />
        <template #right>
          <up-icon @click="openTestStandardSheet"
                   name="arrow-right" />
@@ -75,13 +84,14 @@
        <up-input v-model="form.quantity"
                  type="number"
                  placeholder="请输入数量"
                  :disabled="supplierQuantityDisabled" />
                  :disabled="supplierQuantityDisabled || isReadonly" />
      </up-form-item>
      <up-form-item label="检测单位"
                    prop="checkCompany"
                    border-bottom>
        <up-input v-model="form.checkCompany"
                  placeholder="请输入检测单位"
                  :disabled="isReadonly"
                  clearable />
      </up-form-item>
      <up-form-item label="检测结果"
@@ -91,9 +101,10 @@
        <up-input v-model="form.checkResult"
                  placeholder="请选择检测结果"
                  readonly
                  :disabled="isReadonly"
                  @click="showResultSheet" />
        <template #right>
          <up-icon @click="showResultSheet = true"
          <up-icon @click="!isReadonly && (showResultSheet = true)"
                   name="arrow-right" />
        </template>
      </up-form-item>
@@ -103,9 +114,10 @@
        <up-input v-model="form.checkName"
                  placeholder="请选择检验员"
                  readonly
                  :disabled="isReadonly"
                  @click="showInspectorSheet" />
        <template #right>
          <up-icon @click="showInspectorSheet = true"
          <up-icon @click="!isReadonly && (showInspectorSheet = true)"
                   name="arrow-right" />
        </template>
      </up-form-item>
@@ -116,6 +128,7 @@
        <up-input v-model="form.checkTime"
                  placeholder="请选择检测日期"
                  readonly
                  :disabled="isReadonly"
                  @click="showDatePicker" />
        <!-- <template #right>
          <up-icon name="arrow-right"
@@ -163,6 +176,7 @@
                <text class="step-label">检验值:</text>
                <up-input v-model="item.testValue"
                          placeholder="请输入检验值"
                          :disabled="isReadonly"
                          clearable
                          border-bottom
                          class="step-input" />
@@ -182,14 +196,16 @@
                 size="default"
                 @click="goBack"
                 class="bottom-btn">
        取消
        {{ isReadonly ? '返回' : '取消' }}
      </up-button>
      <up-button type="primary"
      <!-- 已提交单据只读,隐藏保存/提交 -->
      <up-button v-if="!isReadonly"
                 type="primary"
                 size="default"
                 @click="submitForm"
                 :loading="loading"
                 class="bottom-btn">
        {{ isEdit ? '保存' : '提交' }}
        保存
      </up-button>
    </view>
    <!-- 日期选择器 -->
@@ -319,7 +335,11 @@
  import PageHeader from "@/components/PageHeader.vue";
  import dayjs from "dayjs";
  import { getOptions } from "@/api/procurementManagement/procurementLedger.js";
  import { modelList, productTreeList } from "@/api/basicData/product.js";
  import {
    modelList,
    productTreeList,
    modelByBarcode,
  } from "@/api/basicData/product.js";
  import {
    qualityInspectAdd,
    qualityInspectUpdate,
@@ -421,6 +441,7 @@
    return modelOptions.value.map(item => ({
      name: item.model,
      value: item.id,
      subname: item.barcode ? `条码:${item.barcode}` : "",
    }));
  });
@@ -477,6 +498,9 @@
    return !!(v.productMainId != null || v.purchaseLedgerId != null);
  });
  // 已提交(inspectState=1)单据整体只读
  const isReadonly = computed(() => Number(form.value?.inspectState) === 1);
  // 返回上一页
  const goBack = () => {
    uni.navigateBack();
@@ -484,6 +508,7 @@
  // 显示日期选择器
  const showDatePicker = () => {
    if (isReadonly.value) return;
    showDate.value = true;
  };
@@ -610,7 +635,7 @@
      });
  };
  const openTestStandardSheet = () => {
    console.log("openTestStandardSheet");
    if (isReadonly.value) return;
    showTestStandardSheet.value = true;
  };
@@ -640,19 +665,51 @@
    }
  };
  // 获取型号列表
  // 获取型号列表(返回 Promise,便于扫码后顺序回填)
  const getModels = value => {
    form.value.productModelId = "";
    form.value.unit = "";
    modelOptions.value = [];
    currentProductId.value = value;
    form.value.productName = findNodeById(productOptions.value, value);
    modelList({ id: value }).then(res => {
      modelOptions.value = res;
    const task = modelList({ id: value }).then(res => {
      modelOptions.value = res?.data || res || [];
    });
    if (currentProductId.value) {
      getList();
    }
    return task;
  };
  // 扫码按条码精确回填产品+规格型号
  const scanBarcode = () => {
    if (isEdit.value) return;
    uni.scanCode({
      scanType: ["barCode", "qrCode"],
      success: async res => {
        const barcode = (res.result || "").trim();
        if (!barcode) return;
        uni.showLoading({ title: "匹配中...", mask: true });
        try {
          const resp = await modelByBarcode({ barcode });
          const info = resp?.data || resp;
          if (info && info.productId) {
            // 先按 productId 联动出产品层,保证 UI 状态与手动选择一致
            await getModels(info.productId);
            form.value.productId = info.productId;
            form.value.productName = info.productName || form.value.productName;
            form.value.productModelId = info.id;
            form.value.model = info.model || "";
            form.value.unit = info.unit || "";
          }
          uni.hideLoading();
          uni.showToast({ title: "已匹配规格", icon: "success" });
        } catch (e) {
          // 未匹配等错误已有全局 toast,这里只恢复 loading
          uni.hideLoading();
        }
      },
    });
  };
  // 获取指标列表
@@ -687,6 +744,11 @@
  // 提交表单
  const submitForm = async () => {
    console.log("submitForm", form.value, tableData.value);
    // 已提交单据禁止保存/提交
    if (isReadonly.value) {
      showToast("检验单已提交,不允许修改");
      return;
    }
    try {
      // await formRef.value.validate();
      if (!form.value.productModelId) {
@@ -726,21 +788,22 @@
      const data = { ...form.value, qualityInspectParams: tableData.value };
      data.quantity = Number(data.quantity);
      if (isEdit.value) {
        const res = await qualityInspectUpdate(data);
        await qualityInspectUpdate(data);
        showToast("保存成功");
        setTimeout(() => {
          uni.navigateBack();
        }, 1500);
      } else {
        const res = await qualityInspectAdd(data);
        showToast("提交成功");
        // 新增仅保存草稿,正式提交在列表页「提交」按钮(会生成入库记录)
        await qualityInspectAdd(data);
        showToast("保存成功");
        setTimeout(() => {
          uni.navigateBack();
        }, 1500);
      }
    } catch (error) {
      console.error("表单验证失败:", error);
      showToast("提交失败,请重试");
      // request.ts 已统一 toast 后端 msg,这里只记录
      console.error("提交失败:", error);
    } finally {
      loading.value = false;
    }
@@ -912,6 +975,19 @@
<style scoped lang="scss">
  @import "@/static/scss/form-common.scss";
  // 规格行扫码入口
  .scan-entry {
    display: flex;
    align-items: center;
    margin-right: 8px;
    .scan-entry-text {
      font-size: 13px;
      color: #3c9cff;
      margin-left: 2px;
    }
  }
  .material-inspection-add {
    min-height: 100vh;
    background: #f8f9fa;