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

CRM 开票导入 - 前端联调方案

需求:开票管理列表增加「导入」按钮(位于「新增开票申请」与「导出」之间),用于按模板批量导入开票记录。
参考实现:合同列表的导入弹窗(views/crm/contract/modules/import-form.vue),开票导入与其交互一致。

涉及页面

  • 修改:views/crm/invoice/index.vue(开票列表工具栏)
  • 新增:导入弹窗组件(建议 views/crm/invoice/modules/import-form.vue)
  • 修改:src/api/crm/invoice/index.ts(新增 2 个接口)

业务流程与数据带入

  1. 合同(已审核通过)-> 开票导入:模板中填写「合同编号」,后端按编号匹配合同,**客户自动取合同所属客户**,无需在模板中填写客户
  2. 导入成功 -> 开票列表:新增的开票为「未提交」状态,可在列表中继续编辑、上传发票附件、提交审批
  3. 导入的负责人 = 当前登录用户(同合同导入),导入后当前用户即可在「我负责的」下看到

API

方法 路径 说明
GET /crm/invoice/get-import-template 下载导入模板(返回 xls 文件流)
POST /crm/invoice/import 导入开票(multipart 上传 Excel)

权限码: 两个接口均要求 crm:invoice:import(菜单已新增:营销管理 -> 开票管理 -> 开票导入,并已授予开票管理现有角色)。

请求参数(POST /crm/invoice/import):

参数 类型 必填 说明
file MultipartFile 是 仅支持 xls、xlsx

模板列(下载的模板已含表头与一行示例):

列名 必填 说明
开票编号 否 留空则系统自动生成(KP+日期+6位序号);填写时不可与系统中已有开票编号重复
合同编号 是 需与系统中**已审核通过**的合同编号一致,客户由合同自动带入
发票类型 是 填写字典 crm_invoice_type 的名称:增值税专用发票 / 增值税普通发票 / 电子发票
发票号码 否 发票票面号码
发票抬头 否 发票抬头
开票金额(元) 是 需大于 0,且不超过该合同剩余可开票金额
开票日期 否 格式 2026-01-01 10:00:00 或 2026-01-01;留空取当前时间
备注 否 备注

响应:

{
  "code": 0,
  "data": {
    "createList": ["KP20260924000001", "KP20260924000002"],
    "failureList": {
      "第 4 行": "合同编号不存在:HT9999。请先在「CRM 合同管理」中创建或导入该合同(编号需与模板完全一致),或修改模板中的合同编号后重新导入"
    }
  }
}
字段 类型 说明
createList String[] 导入成功的开票编号数组
failureList Map 导入失败集合:key 为「发票号码 xxx」或「第 N 行」(N 为 Excel 行号,含表头),value 为失败原因

字段展示规则

字段 展示位置 说明
导入按钮 开票列表工具栏 位置在「新增开票申请」与「导出」之间;权限码 crm:invoice:import
下载导入模板按钮 导入弹窗左下角 同合同导入弹窗的 prepend-footer 位置
新增条数 导入弹窗结果区 取 createList.length,文案如「新增:N 条」
失败明细 导入弹窗结果区 遍历 failureList,逐条展示「key:value」,可滚动
导入模板说明 导入弹窗内灰色提示区 必填列:合同编号、发票类型、开票金额;合同必须为「审核通过」;负责人 = 当前登录用户;状态为「未提交」

业务规则说明

场景 规则
合同状态 只有「审核通过」的合同才能导入开票;未提交/审批中/不通过的合同该行导入失败
开票金额上限 单行金额不得超过「合同金额 − 已开票(审批中 + 审核通过)」的剩余额度,超出则该行失败
重复编号 模板中填写的开票编号在系统中已存在时该行失败
部分成功 逐行导入,失败行不影响成功行(同一文件内不会整体回滚)
数据权限 导入的开票负责人 = 当前登录用户,自动创建数据权限,无需前端处理
与「新建开票申请」的差异 导入不产生附件;导入的开票默认「未提交」,需在列表中编辑上传发票附件后再提交审批

注意事项

  • 模板「发票类型」填**名称**(如 增值税专用发票),也兼容填数字(1/2/3);填错时失败原因会列出可选项
  • 导入弹窗的进度条/结果区交互可直接复用合同导入的实现(import-form.vue)
  • 前端按钮的 auth 需使用新的权限码 crm:invoice:import;该菜单权限已授予角色 2/155/160/161/162,其余自建角色需在「角色管理」中勾选「开票导入」后再使用
  • 空行会被自动跳过,不算失败