src/pages/procurementManagement/procurementLedger/detail.vue
@@ -204,6 +204,14 @@
                        :disabled="!canEditProducts"
                        @click="openSpecificationPicker(idx)" />
              <template #right>
                <view v-if="canEditProducts"
                      class="scan-entry"
                      @click.stop="scanBarcode(idx)">
                  <up-icon name="scan"
                           size="18"
                           color="#3c9cff"></up-icon>
                  <text class="scan-entry-text">扫码</text>
                </view>
                <up-icon name="arrow-right"
                         v-if="canEditProducts"
                         @click="openSpecificationPicker(idx)"></up-icon>
@@ -338,7 +346,11 @@
<script setup>
  import { onMounted, ref, computed } from "vue";
  import { modelList, productTreeList } from "@/api/basicData/product.js";
  import {
    modelList,
    productTreeList,
    modelByBarcode,
  } from "@/api/basicData/product.js";
  import useUserStore from "@/store/modules/user";
  import { calculateTaxExclusiveTotalPrice } from "@/utils/summarizeTable";
  import { formatDateToYMD } from "@/utils/ruoyi";
@@ -447,6 +459,7 @@
      name: model.text,
      value: model.value,
      unit: model.unit,
      subname: model.barcode ? `条码:${model.barcode}` : "",
    }));
  });
@@ -670,14 +683,48 @@
    showCategoryPicker.value = false;
  };
  // 获取规格型号
  // 获取规格型号(返回 Promise,便于扫码后顺序回填)
  const getModels = value => {
    modelList({ id: value }).then(res => {
      modelOptions.value = res.map(user => ({
    return modelList({ id: value }).then(res => {
      const list = res?.data || res || [];
      modelOptions.value = list.map(user => ({
        text: user.model,
        value: user.id,
        unit: user.unit,
        barcode: user.barcode,
      }));
    });
  };
  // 扫码按条码精确回填产品大类+规格型号
  const scanBarcode = idx => {
    if (!canEditProducts.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) {
            currentProductIndex.value = idx;
            // 先加载该产品下的规格列表,保证与手动选择时的 UI 状态一致
            await getModels(info.productId);
            const row = productData.value[idx];
            row.productCategory = info.productName || row.productCategory;
            row.specificationModel = info.model || "";
            row.productModelId = info.id || "";
            row.unit = info.unit || "";
          }
          uni.hideLoading();
          uni.showToast({ title: "已匹配规格", icon: "success" });
        } catch (e) {
          // 未匹配等错误已有全局 toast,这里只恢复 loading
          uni.hideLoading();
        }
      },
    });
  };
@@ -1119,6 +1166,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;
    }
  }
  .approval-process {
    background: #fff;
    margin: 16px;