团财业务承保统计及手续费核对(第一阶段)— 后端接口清单

需求编号:BYXM-1891
范围:3.2.1 团财承保清单导入、3.2.1 团财批改清单导入、3.2.1 团财保单查询(已存在)、3.2.1 团财批单查询(新增)、3.2.1 影像件上传(新增)、3.2.1 团财保费预估表(暂不实现)。
不包含:3.2.2 产险对账单优化(下次上线)。
BasePath:/property_insurance(承保/批改/保单/批单),影像件上传单独一个控制器:/property_image_upload
鉴权:与现有所有 Controller 一致,从 UserInfoUtil.getUserInfo() 取登录信息(无需在入参里传 token)。
响应统一格式:Result(code / msg / data)。成功码 000000,业务异常码 000001 或 000002。


一、Sheet1 导入模板字段(必读)

模板位置(不变):static/templates/property_insurance/property_insurance_import_template.xlsx下载接口见 §2.7。

列号 字段名 是否必填 备注
1 类型 必填 下拉:新保 / 批改
2 保单号 必填 新保、批改都必填
3 批单号 批改必填 新保可不填
4 投保日期 必填 YYYY-MM-DD
5 承保日期 必填 YYYY-MM-DD
6 生效日期 必填 YYYY-MM-DD
7 保险起期 必填 YYYY-MM-DD
8 保险止期 必填 YYYY-MM-DD
9 保单状态 否 枚举:有效/退保/到期终止/理赔终止
10 业务形式 否 枚举(先预留字段)
11 业务属性 否 枚举(先预留字段)
12 产险类型 必填 下拉:非车 / 车险-交强险 / 车险-商业险
13 缴费方式 否 下拉:趸交/年缴/半年缴/季缴/月缴
14 保险公司代码 必填 base_company.code
15 保险公司名称 否 base_company.name
16 业务员代码 否 lifepagent.agentcode
17 业务员姓名 否 lifepagent.name
18 险种大类 必填 枚举(车险/财产险/责任险/意外险/健康险/其他)
19 险种代码 必填 与 18 联动校验
20 险种名称 必填
21 保险金额 必填 数字 ≥ 0
22 险种保费(含税) 必填 数字 ≥ 0
23 险种保费(不含税) 否 数字 ≥ 0
24 结算手续费率(%) 否 0~100
25 手续费结算依据 否 自由文本
26 综合费用率(%) 否 0~100
27 投保人类型 否 枚举:个人/团体
28 投保人姓名 必填
29 投保人证件类型 否 枚举:1=身份证 / 2=户口本 / 9=出生医学证明
30 投保人证件号码 否 与 29 联动
31 投保人证件有效止期 否 YYYY-MM-DD;证件类型=2 或 9 时可不填
32 投保人移动电话 否 11 位手机号
33 投保人国籍 否 3 位字母代码,默认 CN
34 投保人性别 否 枚举:M/F
35 投保人出生日期 否 YYYY-MM-DD
36 投保人职业 否 自由文本
37 投保人单位电话 否
38 投保人单位联系人 否
39 投保人地址 否
40 被保人类型 否 团体可不填以下字段
41 被保险人与投保人关系 否 4=双方 时表示同一自然人
42 被保人姓名 必填
43 被保人证件类型 否 同 29
44 被保人证件号码 否
45 被保人证件有效止期 否
46 被保人移动电话 否
47 被保人国籍 否
48 被保人性别 否
49 被保人出生日期 否
50 被保人职业 否
51 被保人单位电话 否
52 被保人单位联系人 否
53 被保人地址 否
54 受益人标志 否 枚举:法定受益人 / 指定受益人
55 受益人类型 否 枚举:个人/团体
56 受益人与被保人关系 否
57 受益人姓名 否 受益人标志=指定受益人 时必填
58 受益人证件类型 否
59 受益人证件号码 否
60 受益人份额(%) 否 当存在多个受益人时填写,多个时单条行代表一条受益人
61 佰盈省级分公司代码 必填 com_code
62 佰盈省级分公司名称 否 com_name

校验规则要点:

  1. 第 4~8 列任一为空 → "投保/承保/生效/起止期" 4 个日期至少缺 1。
  2. 第 12 列产险类型必须 ∈ {非车, 车险-交强险, 车险-商业险},并决定后续回写 car_main 还是 no_car_main。
  3. 第 21~22 列必须为非负数字且保额 ≤ 1e10、保费 ≤ 1e8。
  4. 同一批次内 同一保单号+批单号 出现 2 次及以上 → 整行标"重复行"。
  5. 同一保单号 + 不同批单号 → 允许,仅要求保单号一致。
  6. 受益人标志=指定受益人 时,第 5760 列必须填写;标志=法定受益人 时第 5760 允许为空。
  7. 受益人份额(%) 在多个受益人时,单个值必须在 (0, 100];同保单多受益人之和应 = 100(软校验,错误仅警告)。

二、接口清单

所有 POST 请求的 Content-Type:application/json;charset=utf-8
所有 GET 请求的 Content-Type:URL query string
上传接口(除下载外)的 Content-Type:multipart/form-data

2.1 团财承保清单导入(新保)

Code
复制成功
POST /property_insurance/import/policy/upload
Content-Type: multipart/form-data
 
form-data:
file: <xlsx> // 必填,仅 Sheet1
 
响应:Result
{
"code": "000000",
"msg": "导入成功,待提交审核",
"data": {
"batchNo": "20260527001BY0130", // 导入批次号,后续审核/回写都靠这个
"totalRow": 200, // 解析总行数(含表头外)
"successRow": 198, // 校验通过的行数
"errorRow": 2, // 校验失败的行数
"errors": [
{ "rowNo": 5, "sheetName": "Sheet1", "errors": ["保单号不能为空", "产险类型不能为空"] },
...
]
}
}
  1. 仅解析 Sheet1,类型=新保 的行;类型=批改 的行会被记为错误:"该 Sheet 仅支持新保,请使用 /import/endorse/upload"。
  2. 解析成功后批量 INSERT 到 pi_policy_car_stg 或 pi_policy_nocar_stg(依据"产险类型"列)。

2.2 团财批改清单导入(批改)

Code
复制成功
POST /property_insurance/import/endorse/upload
Content-Type: multipart/form-data
 
form-data:
file: <xlsx> // 必填,仅 Sheet1
 
响应:与 2.1 相同结构,但解析 Sheet1 中"类型=批改"的行。
  1. 解析成功后批量 INSERT 到 pi_endorse_car_stg 或 pi_endorse_nocar_stg。
  2. 同一保单号/批单号 的批改,要求主表 car_main/no_car_main 已存在;否则报错"原保单不存在"。

2.3 团财承保/批改统一导入(推荐)

Code
复制成功
POST /property_insurance/import/upload
Content-Type: multipart/form-data
 
form-data:
file: <xlsx>
 
响应:Result
{
"code": "000000",
"msg": "导入成功",
"data": {
"batchNo": "...",
"policyCount": 120, // 类型=新保 的成功行数
"endorseCount": 80, // 类型=批改 的成功行数
"errors": [...] // 校验错误明细
}
}

该接口按 Sheet1 的"类型"列分流,落入新保/批改两张临时表。后端统一打 MIXED 业务类型,审批时按行维度回写。

2.4 导入批次分页查询

Code
复制成功
POST /property_insurance/import/batch/list
Content-Type: application/json
 
请求体:
{
"batchNo": "20260527001BY0130", // 可选
"bizType": "POLICY", // 可选 / POLICY/ENDORSE/MIXED
"status": "APPROVING", // 可选 / VALIDATED/APPROVING/POSTED/POST_FAILED/REJECTED
"fileName": "5月清单.xlsx", // 可选 / 模糊匹配
"comCode": "00", // 可选 / 省级分公司代码
"uploadTimeStart": "2026-05-01", // 可选 / YYYY-MM-DD
"uploadTimeEnd": "2026-05-31", // 可选 / YYYY-MM-DD
"currentPage": 1,
"pageSize": 20
}
 
返回:Result
{
"code": "000000",
"data": {
"total": 35,
"rows": [
{
"batchNo": "20260527001BY0130",
"bizType": "MIXED",
"fileName": "5月清单.xlsx",
"status": "APPROVING",
"totalRow": 200,
"successRow": 195,
"errorRow": 5,
"comCode": "00",
"comName": "佰盈总部",
"uploadUserCode": "AGENT001",
"uploadUserName": "张三",
"uploadTime": "2026-05-27 09:30:21"
}
]
}
}

2.5 批次详情(解析明细 + 错误明细)

Code
复制成功
GET /property_insurance/import/batch/detail?batchNo=20260527001BY0130
 
返回:Result
{
"code": "000000",
"data": {
"batch": { ...同 2.4 batchVo 结构 },
"rows": [
{
"rowNo": 3,
"sheetName": "Sheet1",
"recordType": "POLICY", // POLICY/ENDORSE
"policyNo": "...",
"endorseNo": null,
"premiumTaxTotal": 12345.67,
"status": "VALIDATED", // VALIDATED/INVALID
"validationErrors": [] // 本行的校验错误
}
]
}
}

2.6 批次错误明细(仅错误行)

Code
复制成功
GET /property_insurance/import/batch/errors?batchNo=20260527001BY0130
 
返回:Result
{
"code": "000000",
"data": [
{ "rowNo": 5, "sheetName": "Sheet1", "errors": ["保单号不能为空"] }
]
}

2.7 下载导入模板

Code
复制成功
GET /property_insurance/import/downloadTemplate
 
响应:
- Content-Type: application/octet-stream;charset=ISO8859-1
- Content-disposition: attachment; filename=团财承保和批改清单导入模板.xlsx
- Body: xlsx 二进制

2.8 提交审核

Code
复制成功
POST /property_insurance/import/batch/submit
Content-Type: application/json
 
请求体:
{ "batchNo": "20260527001BY0130" }
 
返回:Result { code, msg, data=null }
- 000000 提交成功
- 000001 该批次校验未通过 / 已提交过

2.9 审核(通过/不通过)

Code
复制成功
POST /property_insurance/import/batch/audit
Content-Type: application/json
 
请求体:
{
"batchNo": "20260527001BY0130",
"status": "approved", // approved / reject
"remark": "审核通过"
}
 
返回:Result
{
"code": "000000",
"msg": "审核通过,回写成功",
"data": { "policyWritten": 120, "endorseWritten": 80 }
}

2.10 兼容旧接口(前端如果还没改完,可以继续用)

Code
复制成功
POST /property_insurance/import/batch/approve
请求体:{ "batchNo": "...", "remark": "..." }
 
POST /property_insurance/import/batch/reject
请求体:{ "batchNo": "...", "remark": "..." }

内部均调用 auditBatch。

2.11 团财保单查询(已存在,保持不变)

Code
复制成功
POST /property_insurance/policyQuery
请求体:PolicyQueryCondition
返回:Result<PolicyPageVo>

2.12 团财保单详情(已存在)

Code
复制成功
POST /property_insurance/policyQuery/detail
请求体:{ "policyNo": "...", "queryType": "1" }
返回:Result<PolicyDataDetailVo>

2.13 团财保单导出(已存在)

Code
复制成功
GET /property_insurance/policyData/export?...
query:PolicyQueryCondition 全部字段

2.14 团财批单查询(新增)

Code
复制成功
POST /property_insurance/endorse/query
Content-Type: application/json
 
请求体:PolicyEndorseQueryCondition
{
"comCode": "00", // 省级分公司代码(可选)
"codeName": "佰盈总部", // 省级分公司名称(可选)
"comSubCode": "0001", // 地市级分公司代码(可选)
"comSubName": "北京分公司", // 地市级分公司名称(可选)
"companyCode": "PICC", // 保险公司代码(可选)
"companyName": "人保财险", // 保险公司名称(可选)
"acceptStartDate": "2026-05-01", // 承保开始日期(与 保单号/批单号 二选一)
"acceptEndDate": "2026-05-31", // 承保结束日期
"policyNo": "PICC202605001", // 保单号(可选)
"endorseNo": "E001", // 批单号(可选)
"propertyType": "1", // 1=车险 / 2=非车 / 空=并集
"currentPage": 1,
"pageSize": 20
}
 
返回:Result
{
"code": "000000",
"data": {
"total": 152,
"rows": [
{
"policyNo": "PICC202605001",
"endorseNo": "E001",
"acceptDate": "2026-05-12 00:00:00",
"generateDate": "2026-05-12 00:00:00",
"propertyType": "1",
"companyName": "人保财险",
"comName": "北京分公司",
"agentCode": "AGENT001",
"agentName": "张三",
"insureName": "XX 物流有限公司",
"insuredName": "XX 物流有限公司"
}
]
}
}

前端校验:承保日期、保单号/批单号至少二选一,否则 000002。

2.15 团财批单详情(新增)

Code
复制成功
GET /property_insurance/endorse/detail?policyNo=...&endorseNo=...&propertyType=1
 
返回:Result<PolicyEndorseDetailVo> —— 见 §3 VO 列表。

2.16 团财批单导出(新增)

Code
复制成功
GET /property_insurance/endorse/export?
comCode=&codeName=&comSubCode=&comSubName=&companyCode=&companyName=
acceptStartDate=&acceptEndDate=&policyNo=&endorseNo=&propertyType=
currentPage=&pageSize=
 
响应:application/vnd.ms-excel;文件名"产险批单数据导出.xls"

2.17 影像件上传(新增)

本模块完全参考寿险影像件上传(ImageUploadController)实现,落库沿用同一张表 imageupload,
与寿险只有两点差异:①接口名不同;②上传目录由 imageUpload/ 改为 propertyimage/。
因此 本次不需要新建任何表(原先准备的 pi_policy_image 建表 SQL 已作废并删除)。
产险当前业务只要求上传「投保人影像」一类。

Code
复制成功
POST /property_image_upload/policyImageUpload
Content-Type: multipart/form-data
 
form-data:
file: <jpg/png/pdf> // 必填,仅支持 jpg、png、pdf
policyNo: "PICC202605001" // 必填,保单号
imageType: "5" // 选填,默认 5=投保人影像
// 1=客户告知书 2=保单主页 3=投保单
// 5=投保人影像 6=被保人影像 7=受益人影像
 
返回:Result
{
"code": "000000",
"msg": "上传成功!",
"data": null
}

落盘路径:{oss.upload.dir}/propertyimage/{policyNo}/{影像子目录}/{yyyyMMdd + UUID + 后缀}
影像子目录映射(与寿险一致):
1→notification、2→homepage、3→insurance、5→policyHolderIdCard、6→insuredIdCard、7→beneficiaryIdCard、其他→trouble
访问 URL:https://{oss.domain}/propertyimage/{policyNo}/{影像子目录}/{文件名},即 imageupload.imagepathsftp 的值。
失败返回:000002 + 具体原因("不支持上传此类型文件!可上传类型为:jpg,png,pdf!" / "保单号不能为空" / "系统异常,上传失败")。

2.18 影像件查询(按保单号,新增)

保单号超链接进入影像上传页面时调用,返回该保单下的全部影像件,按影像分类分组。

Code
复制成功
POST /property_image_upload/policyImageQuery
Content-Type: application/json
 
请求体:
{
"policyNo": "PICC202605001" // 必填
}
 
返回:Result
{
"code": "000000",
"msg": "查询成功",
"data": {
"notification": [ { "imageName": "xxx.jpg", "imageURL": "https://{oss.domain}/propertyimage/..." } ],
"homepage": [],
"insurance": [],
"policyHolderIdCard": [ { "imageName": "xxx.jpg", "imageURL": "https://{oss.domain}/propertyimage/..." } ],
"insuredIdCard": [],
"beneficiaryIdCard": []
}
}

imageURL 就是访问地址,前端预览/下载直接用它。查询失败返回 000002。

2.19 影像件删除(新增)

同时删除服务器物理文件与 imageupload 表记录。删完由前端重新调用 2.18 刷新。

Code
复制成功
POST /property_image_upload/policyImageDelete
Content-Type: application/json
 
请求体:
{
"policyNo": "PICC202605001", // 必填
"imageType": "5", // 必填,与上传时一致
"imageNameFromSftp": "https://{oss.domain}/propertyimage/PICC202605001/policyHolderIdCard/xxx.jpg" // 必填,2.18 返回的 imageURL
}
 
返回:Result
{
"code": "000000",
"msg": "图片删除成功!"
}

删除失败返回 000002 + "图片删除失败!"。前端需先弹框确认"是否确定删除?"。

2.20 影像件下载(新增)

Code
复制成功
GET /property_image_upload/policyImageDownload?fileName={urlencoded 完整URL}
 
说明:fileName 传 2.18 返回的 imageURL(或上传接口返回的访问地址),需 URLEncode。
 
响应:
- Content-Type: application/octet-stream;charset=utf-8
- Content-disposition: attachment; filename=<文件名>
- Body: 文件二进制流

三、新增/修改的 VO 字段

PolicyEndorseListVo(产险批单列表)

字段:policyNo, endorseNo, acceptDate, generateDate, propertyType, companyName, comName, agentCode, agentName, insureName, insuredName

PolicyEndorseDetailVo(产险批单详情)

  • 保单基本信息:policyNo, policyStatus, policyAcceptDate, policyGenerateDate, companyCode, companyName, insureName, insuredName, handlerCode, handlerName, comCode, comName, propertyType, bizForm
  • 批单基本信息:endorseNo, endorseAcceptDate, endorseGenerateDate, totalPremiumTax, totalPremiumNoTax, endorseHandlerCode, endorseHandlerName
  • 险种信息:riskClass, riskCode, riskName, sumInsured, riskPremiumTax, riskPremiumNoTax, startDate, endDate, settleCommissionRate, settleCommissionBasis

影像件相关 VO(复用寿险已有的类,无新增)

  • 入参 ImageUploadVO:影像件模块用到的字段是 policyNo(保单号)、imageType(影像类型)、imageNameFromSftp(服务器文件地址/整条URL)
  • 出参 ImageReturnVO:imageName(文件名)、imageURL(访问地址)

PolicyEndorseQueryCondition

字段:comCode, codeName, comSubCode, comSubName, companyCode, companyName, acceptStartDate, acceptEndDate, policyNo, endorseNo, propertyType


四、建表 SQL

本次不需要建表。
产险影像件参照寿险实现,直接复用已有的 imageupload 表(该表已有 policyno / filetype / imagename / imagepathsftp / createtime / updatetime / createby / updateby / imagelocation 字段)。
原"团财影像件上传表DDL.sql"(pi_policy_image)方案已废弃,文件已从工程中删除,无需在生产执行。
已有表 pi_policy_car_stg / pi_policy_nocar_stg / pi_endorse_car_stg / pi_endorse_nocar_stg / pi_import_batch / pi_import_batch_error / pi_policy_car_main / pi_policy_nocar_main / pi_endorse_car_main / pi_endorse_nocar_main 已通过 团财承保批改_新导入表DDL.sql 建好,本次不重复创建。


五、错误码表

code 含义
000000 成功
000001 业务异常(具体信息看 msg)
000002 前端校验不通过(如承保日期+保单号都为空)
000003 文件解析失败(非 xlsx / 模板格式错)
000004 数据回写失败(详见 msg;通常对应某条具体的 stg 行 id)
000005 权限不足(非本公司数据)
000099 系统异常

六、与前端的约定

  1. 所有 POST 请求的 body 字段命名沿用驼峰式(与 VO @Data 注解生成的一致)。
  2. 导出接口用 GET + queryString;前端如需复杂条件可以用 POST 后端再加。
  3. 任何 /upload 接口超时统一 30 秒,前端请用 upload progress 反馈用户。
  4. 审核回写是异步的还是同步的?
    • 当前实现:审核接口(/audit、/approve)在事务内同步完成 car_main / no_car_main 的回写;批量 200 行以内 < 5 秒,超过 200 行会返回 000004 并提示"请分批导入"。
    • 后续如果需要异步版本再扩展。
  5. 同一保单号已存在时再导入 → 后端拒绝并提示"保单已存在",不会覆盖。
  6. 受益人=指定受益人 时,导入校验要求"受益人姓名、证件、份额"三项;前端录入时也应该在校验层把这三项联动起来。
  7. 后端会复用 UserInfoUtil.getUserInfo() 取 comCode / operatorCode;前端传过来的 comCode 仅作为展示用,不参与过滤(避免越权)。
  8. 影像件模块(/property_image_upload/*)与寿险影像件上传(/ImageUpload/*)是两套独立接口、同一张 imageupload 表,只是存储目录不同(propertyimage/ vs imageUpload/)。前端请按产险这套接口对接,不要混用。
  9. 影像件预览:直接用 2.18 返回的 imageURL 打开即可(走 oss.domain);如果浏览器需要强制下载,用 2.20 的下载接口。

本页笔记

加载中…