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

开票与回款关联(先开票后回款) - 前端联调方案

本次调整(最新):回款创建表单的【关联开票】与【回款期数】由必填改为**选填**,支持「未关联开票 / 未关联回款计划」直接录入回款。
后端已放开(invoiceId 不再强制),前端需去掉这两个字段的必填校验,详见文末「本次调整」章节。

涉及页面

  • 回款管理列表页
  • 回款创建 / 编辑表单
  • 回款详情页
  • 开票管理列表页、开票详情页(**前端目前缺失,需新建**)
  • 合同管理列表页、合同详情页(上个任务已接入"已开票金额/未开票金额",本次不涉及)

业务流程与数据带入

  1. 开票 → 回款:开票单审批通过 + 上传发票附件后,才会出现在回款创建表单的"关联开票"下拉中。
  2. 回款创建:选择客户 → 选择合同 → 选择关联开票(自动带入客户、合同)→(可选)选择回款计划 → 填回款金额(可预填为该开票的剩余可回款金额)。
  3. 合同下拉(simple-list):已返回 totalInvoicePrice(已开票金额,含审批中),用于展示合同剩余可开额度。
  4. 开票下拉(simple-list):返回 remainingInvoicePrice(该开票剩余可回款金额),用于创建回款时预填金额。

API

1. 新增接口:按合同查询可选开票

方法 路径 说明
GET /crm/invoice/simple-list?contractId= 回款创建时选择关联开票,只返回合格开票

筛选规则(后端已实现):审批通过 + 已上传发票附件 + 剩余可回款金额 > 0。

响应示例:

{
  "code": 0,
  "data": [
    {
      "id": 1,
      "no": "KP20260810000001",
      "invoiceNo": "02564178",
      "invoiceTitle": "XX科技有限公司",
      "price": 1090.00,
      "customerId": 1,
      "contractId": 31,
      "auditStatus": 20,
      "hasAttachment": true,
      "remainingInvoicePrice": 1090.00
    }
  ]
}

2. 变更接口:回款创建 / 更新

方法 路径 说明
POST /crm/receivable/create 请求体新增 invoiceId(**选填**)
PUT /crm/receivable/update 请求体新增 invoiceId(可修改)

请求参数新增:

参数 类型 必填 说明
invoiceId Long 否 关联的开票编号。填写时必须为审批通过且已上传附件的开票;不填表示该笔回款暂不关联开票
planId Long 否 关联的回款计划编号。不填表示不占用回款计划期数

3. 变更接口:回款查询(响应新增字段)

方法 路径 新增响应字段
GET /crm/receivable/page invoiceId、invoice(嵌套对象)
GET /crm/receivable/get invoiceId、invoice(嵌套对象)
GET /crm/receivable/page-by-customer invoiceId、invoice(嵌套对象)

invoice 嵌套对象关键字段: id、no(开票编号)、invoiceNo(发票号码)、invoiceTitle(发票抬头)、price(开票金额)。

4. 变更接口:开票查询(响应新增字段)

方法 路径 新增响应字段
GET /crm/invoice/page hasAttachment、remainingInvoicePrice
GET /crm/invoice/get hasAttachment、remainingInvoicePrice

说明:
- hasAttachment(Boolean):是否已上传发票附件,用于列表快速判断哪些开票可被回款关联。
- remainingInvoicePrice(BigDecimal):剩余可回款金额 = 开票金额 - 该开票已回款金额(统计草稿 + 审批中 + 审批通过的回款)。

字段展示规则

字段 展示位置 说明
关联开票 回款列表列、回款详情页 展示 invoice.no / invoice.invoiceNo / invoice.price
关联开票选择器 回款创建/编辑表单 选择后带入客户、合同、预填回款金额为 remainingInvoicePrice
剩余可回款金额 开票列表列、开票详情页 开票金额 - 该开票已回款金额
是否已上传附件 开票列表列 辅助判断开票是否可回款(需审批通过 + 已上传附件)

本次调整(【关联开票】【回款期数】改为选填)

变更点

项 调整前 调整后
关联开票(invoiceId) 必填,不选无法保存 选填;不选即录入一笔不关联开票的回款
回款期数(planId) 必填,不选无法保存 选填;不选即不占用回款计划期数
合同(contractId) 必填 仍为必填(金额上限校验依赖合同)
回款金额、回款日期 必填 仍为必填

前端的改动点(去必填)

  • 回款创建/编辑表单的【关联开票】【回款期数】两个字段,去掉必填校验规则即可,其余联动逻辑(选合同后加载开票/期数选项、选中后带入客户与金额)保持不变。
  • 建议取消必填后,字段提示文案相应改为「可不选」类表述,避免用户误以为漏填。

不填时的后端行为

场景 行为
不选关联开票 跳过「开票是否审批通过 / 是否已上传附件 / 是否与合同一致」及「不超过该开票剩余可回款金额」两组校验
不选关联开票时的金额上限 仍受**合同级**校验约束:累计回款不得超过合同总金额
不选回款期数 不更新任何回款计划的已回款标记,回款计划列表中该期仍显示未回款
编辑既有回款 未提交 invoiceId 时保留原关联关系(不会因漏传而被清空);如需解除关联,需显式清空该字段(当前前端编辑态该字段为禁用,如需支持解除需另行开放)

业务规则说明

场景 规则
审批中的开票 不可选为回款依据(后端拦截:关联开票不是审批通过状态)
未上传发票附件的开票 不可选为回款依据(后端拦截:关联开票未上传发票附件)
已全部回款的开票 从"关联开票"下拉过滤(剩余可回款 ≤ 0)
回款金额超限 后端拦截:回款金额超出该开票剩余可回款金额
开票与合同不匹配 后端拦截:所选开票与回款合同不一致
编辑回款时改开票 草稿/审批中状态可修改关联开票,改后重新按新开票校验金额

前端缺口(需新建)

后端开票模块已完整(含审批流程、附件上传),但前端尚无开票页面与 API,需前端新建。

  1. 开票管理页:views/crm/invoice/(列表、创建/编辑、审批提交、发票附件上传与展示)。
  2. 开票 API:api/crm/invoice/(page / get / create / update / delete / submit / audit-count / export-excel / simple-list)。
  3. 回款表单开票选择器:选合同后调用 /crm/invoice/simple-list?contractId=,展示"开票编号 / 发票号码 / 开票金额 / 剩余可回款",选中后预填金额。
  4. 菜单:已由后端 SQL 配置完成(营销管理 -> 开票管理,component = crm/invoice/index),前端建好页面后菜单即可用。

注意事项

  • invoiceId、planId 均为**选填**;填了开票就按开票校验,不填只受合同金额上限约束。
  • invoice、remainingInvoicePrice、hasAttachment 均为后端计算的只读字段,前端**不要**提交。
  • 回款金额建议在选中开票后预填为 remainingInvoicePrice,避免超限被后端拦截。
  • 存量回款数据若未关联开票(invoiceId 为空),编辑保存时不再被要求补选开票。
  • 开票列表展示"剩余可回款金额"时,文案建议用"剩余可回款金额(含审批中)"避免歧义,与合同"已开票金额(含审批中)"口径一致。