gaoluyang
2026-08-03 75242bbba28ae8902ddf86d33febb497d79e5fc3
src/views/crm/saleQuotation/modules/form.vue
@@ -1,4 +1,5 @@
<script lang="ts" setup>
import type { CrmSaleQuotationAiApi } from '#/api/crm/saleQuotation/ai';
import type { CrmSaleQuotationApi } from '#/api/crm/saleQuotation';
import { computed, ref, watch } from 'vue';
@@ -6,7 +7,7 @@
import { useVbenModal } from '#/packages/effects/common-ui/src';
import { erpPriceMultiply } from '#/packages/utils/src';
import { message } from 'ant-design-vue';
import { message, Alert } from 'ant-design-vue';
import { useVbenForm } from '#/adapter/form';
import {
@@ -22,6 +23,7 @@
const emit = defineEmits(['success']);
const formData = ref<CrmSaleQuotationApi.SaleQuotation>();
const itemFormRef = ref();
const ocrCustomerName = ref('');
const getTitle = computed(() => {
  return formData.value?.id
@@ -85,14 +87,52 @@
  async onOpenChange(isOpen: boolean) {
    if (!isOpen) {
      formData.value = undefined;
      ocrCustomerName.value = '';
      return;
    }
    const data = modalApi.getData<CrmSaleQuotationApi.SaleQuotation>();
    const data = modalApi.getData<CrmSaleQuotationApi.SaleQuotation & { ocrData?: CrmSaleQuotationAiApi.OcrResultVO }>();
    if (!data || !data.id) {
      formData.value = {} as CrmSaleQuotationApi.SaleQuotation;
      await formApi.resetForm();
      // 新增时,重置并添加一行空数据
      itemFormRef.value?.resetData();
      // OCR 识别数据预填
      if (data?.ocrData) {
        const ocr = data.ocrData;
        await formApi.setValues({
          name: ocr.name,
          quotationTime: ocr.quotationTime,
          validUntil: ocr.validUntil,
          taxRate: ocr.taxRate,
          discountPercent: ocr.discountPercent,
          remark: ocr.remark,
        });
        if (ocr.items?.length) {
          itemFormRef.value?.setData(ocr.items.map((item) => ({
            id: undefined as unknown as number,
            itemId: undefined as unknown as number,
            itemName: item.itemName || '',
            itemCode: '',
            itemBarCode: undefined,
            itemSpecification: item.itemSpec || '',
            itemUnitName: '',
            itemUnitName2: undefined,
            itemUnitName3: undefined,
            itemPrice: undefined as unknown as number,
            quotationPrice: item.quotationPrice || 0,
            count: item.count || 1,
            totalPrice: erpPriceMultiply(item.quotationPrice || 0, item.count || 1) ?? 0,
            taxPercent: undefined,
            taxPrice: undefined,
            remark: undefined,
          })));
        } else {
          itemFormRef.value?.resetData();
        }
        // 存储 OCR 识别的客户名称,用于界面提示
        ocrCustomerName.value = ocr.customerName || '';
      } else {
        // 新增时,重置并添加一行空数据
        itemFormRef.value?.resetData();
      }
      return;
    }
    modalApi.lock();
@@ -110,6 +150,14 @@
<template>
  <Modal :title="getTitle" class="w-[80%]">
    <Alert
      v-if="ocrCustomerName"
      type="info"
      show-icon
      class="mx-4 mb-4"
      message="AI 识别到客户名称,请在客户选择器中手动匹配 CRM 客户"
      :description="`识别结果:${ocrCustomerName}`"
    />
    <Form class="mx-4">
      <template #items>
        <ItemForm