gaoluyang
4 天以前 617dcdcba6b5134fbd6b7cdf77c459556d19cc9a
feat(crm): 开票管理新增销售订单选择,开票金额带出订单未开票金额

- 开票单新增「销售订单」下拉(仅已审核订单),选定后带出客户、合同、发票抬头
- 开票金额默认带出该订单剩余可开票金额,并按上限校验
- 列表新增销售订单号列

Co-Authored-By: Claude Code <noreply@anthropic.com>
已修改2个文件
57 ■■■■■ 文件已修改
src/api/crm/invoice/index.ts 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/crm/invoice/data.ts 46 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/crm/invoice/index.ts
@@ -23,6 +23,10 @@
    no?: string;
    contractId?: number;
    contract?: Contract;
    /** 销售订单编号,关联 ERP 销售订单;开票金额按该订单金额校验 */
    saleOrderId?: number;
    /** 销售订单号(冗余展示) */
    saleOrderNo?: string;
    customerId?: number;
    customerName?: string;
    invoiceType?: number;
@@ -84,6 +88,13 @@
  );
}
/** 查询销售订单剩余可开票金额(审批通过 + 审批中占用额度) */
export function getSaleOrderRemainPrice(saleOrderId: number) {
  return requestClient.get<number>('/crm/invoice/sale-order-remain-price', {
    params: { saleOrderId },
  });
}
/** 新增开票 */
export function createInvoice(data: CrmInvoiceApi.Invoice) {
  return requestClient.post('/crm/invoice/create', data);
src/views/crm/invoice/data.ts
@@ -6,8 +6,10 @@
import { useUserStore } from '@vben/stores';
import { getContractSimpleList } from '#/api/crm/contract';
import { getSaleOrderRemainPrice } from '#/api/crm/invoice';
import { getSimpleUserList } from '#/api/system/user';
import CrmCustomerSelect from '#/components/crm-customer-select.vue';
import { ErpSaleOrderSelect } from '#/views/erp/sale/order/components';
import { markRaw } from 'vue';
@@ -56,6 +58,34 @@
      defaultValue: userStore.userInfo?.id,
    },
    {
      fieldName: 'saleOrderId',
      label: '销售订单',
      component: markRaw(ErpSaleOrderSelect),
      dependencies: {
        triggerFields: ['id'],
        disabled: (values) => !!values.id,
      },
      componentProps: (_values, form) => ({
        placeholder: '请选择销售订单(可不选)',
        allowClear: true,
        // 只允许选择审核通过的销售订单(ErpAuditStatus.APPROVE = 20)
        status: 20,
        onChange: async (item: any) => {
          if (!item) {
            form.setFieldValue('price', undefined);
            return;
          }
          // 客户、合同、抬头随销售订单带出
          form.setFieldValue('customerId', item.customerId);
          form.setFieldValue('contractId', item.contractId);
          form.setFieldValue('invoiceTitle', item.customerName);
          // 开票金额默认带出该订单的未开票金额
          const remainPrice = await getSaleOrderRemainPrice(item.id);
          form.setFieldValue('price', remainPrice > 0 ? remainPrice : 0);
        },
      }),
    },
    {
      fieldName: 'customerId',
      label: '客户名称',
      component: markRaw(CrmCustomerSelect),
@@ -68,8 +98,9 @@
        },
      }),
      dependencies: {
        triggerFields: ['id'],
        disabled: (values) => !!values.id,
        triggerFields: ['id', 'saleOrderId'],
        // 选了销售订单时客户由订单确定,不可改
        disabled: (values) => !!values.id || !!values.saleOrderId,
      },
    },
    {
@@ -77,8 +108,10 @@
      label: '合同名称',
      component: 'Select',
      dependencies: {
        triggerFields: ['customerId'],
        disabled: (values) => !values.customerId || !!values.id,
        triggerFields: ['customerId', 'saleOrderId'],
        // 选了销售订单时合同由订单带出,不可改
        disabled: (values) =>
          !values.customerId || !!values.id || !!values.saleOrderId,
        async componentProps(values, form) {
          if (!values.customerId) {
            return {
@@ -233,6 +266,11 @@
      slots: { default: 'contractNo' },
    },
    {
      title: '销售订单号',
      field: 'saleOrderNo',
      minWidth: 160,
    },
    {
      title: '发票类型',
      field: 'invoiceType',
      minWidth: 120,