编辑 | blame | 历史 | 原始文档

CRM 开票功能 - 前端联调方案

涉及页面

  • 新增:views/crm/invoice/index.vue(开票列表)、views/crm/invoice/modules/form.vue(开票表单)、views/crm/invoice/detail/index.vue(开票详情)
  • 新增:src/api/crm/invoice/index.ts(开票接口)
  • 修改:views/crm/receivable/modules/form.vue(回款表单增加「先开票后回款」提示与校验)
  • 修改:回款列表/详情(展示开票情况提示,或跳转开票)

后端菜单已新增「营销管理 -> 开票管理」(component = crm/invoice/index),前端只需创建对应目录与页面组件。

业务流程与数据带入

  1. 合同审批通过 -> 创建开票:开票时选择合同,客户、合同名称从合同带入
  2. 开票提交审批 -> 审批通过:审批通过后开票才生效,才允许参与回款校验
  3. 审批通过 -> 上传发票附件:通过附件机制上传发票扫描件/电子票
  4. 发票已上传附件 -> 创建回款:回款创建时后端校验「合同累计已开票且已上传附件的金额 >= 累计回款金额(含本次)」

API

开票接口

方法 路径 说明
POST /crm/invoice/create 创建开票
PUT /crm/invoice/update 更新开票(仅草稿/审批中)
DELETE /crm/invoice/delete 删除开票(审批通过不可删)
GET /crm/invoice/get 获得开票详情(含附件列表)
GET /crm/invoice/page 获得开票分页
GET /crm/invoice/page-by-customer 基于客户的开票分页
GET /crm/invoice/export-excel 导出开票 Excel
PUT /crm/invoice/submit 提交开票审批
GET /crm/invoice/audit-count 待审核开票数量

创建/更新请求参数:

参数 类型 必填 说明
id Long 更新时必填
contractId Long 合同编号,选择合同后客户自动带入
ownerUserId Long 负责人,默认当前用户
invoiceType Integer 发票类型,字典 crm_invoice_type(1专用 2普通 3电子)
invoiceNo String 发票号码
invoiceTitle String 发票抬头
price BigDecimal 开票金额(元)
invoiceTime LocalDateTime 开票日期
remark String 备注
blobIds Long[] 发票附件 BlobId 列表

响应字段新增:

字段 类型 说明
no String 开票编号(KP+日期+序号,保存时后端生成)
customerId / customerName Long / String 客户
contract CrmContractRespVO 合同信息
ownerUserName / ownerUserDeptName String 负责人/部门
auditStatus Integer 审批状态(字典 crm_audit_status
attachmentList StorageBlobRespDTO[] 发票附件列表
processInstanceId String 工作流编号

响应示例:

{
  "code": 0,
  "data": {
    "id": 1,
    "no": "KP20260810000001",
    "contractId": 100,
    "contract": { "id": 100, "no": "HT2026...", "name": "..." },
    "customerId": 200,
    "customerName": "XX科技",
    "invoiceType": 1,
    "invoiceNo": "02564178",
    "invoiceTitle": "XX科技有限公司",
    "price": 9000.00,
    "invoiceTime": "2026-08-10",
    "auditStatus": 0,
    "attachmentList": [{ "id": 1, "url": "...", "name": "发票.pdf" }]
  }
}

附件接口(沿用 system 模块)

方法 路径 说明
POST /system/storage-blob/upload 上传发票文件,获得 blobId
POST /system/storage-attachment/bind 绑定附件到开票(recordType=crm_invoicerecordId=开票id
GET /system/storage-attachment/list 查询开票附件列表
DELETE /system/storage-attachment/delete 删除附件

上传与保存分离:表单先选文件上传拿到 blobId,随创建/更新接口一起提交 blobIds;后端绑定。详情接口返回的 attachmentList 可直接展示/预览。

字段展示规则

字段 展示位置 说明
no 开票编号 列表、详情 跳转详情
customerName 客户 列表、详情 跳转客户详情
contract 合同 列表、详情 跳转合同详情
invoiceType 发票类型 列表、详情 字典展示

| invoiceNo 发票号码 | 列表、详情 | - |
| price 开票金额 | 列表、详情 | 金额格式化 |
| invoiceTime 开票日期 | 列表、详情 | 日期格式化 |
| auditStatus 审批状态 | 列表、详情 | 字典 crm_audit_status |
| attachmentList 发票附件 | 详情 | 附件列表,可预览/下载 |
| ownerUserName 负责人 | 列表 | - |
| remark 备注 | 列表、详情 | - |

业务规则说明

场景 规则
创建回款 后端校验:同合同「审批通过且已上传发票附件」的累计开票金额 >= 累计回款金额(含本次),否则报错「合同累计开票金额不足,目前可回款 X 元」
开票金额 后端校验:开票金额不能超过合同金额减去已审批通过的开票金额
开票编辑 仅草稿、审批中可编辑;客户、合同、负责人不可修改
开票删除 审批通过后不可删除
开票审批 提交后走 BPM 流程(key=crm-invoice-audit),审批通过才生效
待办 后端 audit-count 可用于待办红点

注意事项

  • 发票类型字典 crm_invoice_type 后端已配置,前端需在常量/字典中注册(1增值税专用 2增值税普通 3电子)
  • 菜单权限:管理员需将新菜单(crm:invoice:*)分配给相应角色
  • 回款表单在用户选择合同后,可提示「请先完成开票并上传发票附件」,若未开票则创建回款会收到后端错误提示
  • 附件必须走 /system/storage-* 接口,recordType 固定为 crm_invoice,禁止在业务表新增文件地址字段
  • 上传的发票文件建议限制图片/PDF 格式