团财业务承保统计及手续费核对(第一阶段)— 后端接口清单
需求编号: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。
变更记录
| 日期 | 变更 |
|---|---|
| 2026-10-13 | 审批回写补齐关联表(no_car_party / no_car_charge / car_party / car_charge / car_vehicle),见 §2.9 |
| 2026-10-16 | 批改导入改为只写独立批单表 pi_endorse_bill,不回写任何主表;导入接口加 importType(导入/补录);新增批单查询/导出/详情三个接口读 pi_endorse_bill;批单详情改为复用 PolicyDataDetailVo(与保单详情同构),删除 PolicyEndorseDetailVo。见 §1.4、§2.4、§2.9、§2.14 |
| 2026-10-16(承保清单校验) | ①「被保险人与投保人关系=本人」时被保人名称不再必录,后端直接用投保人人员信息填充被保人;②「险种保费(含税)」与「险种保费(不含税)」改为至少录入一项;③批次列表 importType 字段补齐(承保/被保人清单也写入类型值 + 空值兜底)。见 §1 约定 5/6、§1.1、§1.2、§2.4.1、§4.4 |
| 2026-10-16(importType 定稿) | 导入类型收敛为 7 个英文枚举:车/非车承保导入与补录 4 个、被保人清单 1 个、批改 2 个(ENDORSE_IMPORT 当时为默认值 / ENDORSE_SUPPLEMENT)。库存英文、接口出中文,前端直接渲染。承保的「导入/补录」由后端按行合并结果自动改判(整批都是补录行才算补录)。见 §2.4、§2.4.1 |
| 2026-10-19 | 承保清单(车/非车)新增保险公司名称自动补全:只录「保险公司代码」时,按代码回查 base_supplyinsurance(VALIDSTATUS='1',与 /bankReports/getInsures 同源)取名称并自动回填落库;查不到则该行报错「保险公司代码[XXX]在保司表中不存在或未生效…」。见 §1 约定 7、§1.1/§1.2 |
| 2026-10-21(承保导入/补录拆分) | 承保清单导入与补录正式拆分:①三个导入端点新增必传 importType(CAR_POLICY_IMPORT / CAR_POLICY_SUPPLEMENT / NOCAR_POLICY_IMPORT / NOCAR_POLICY_SUPPLEMENT),取消按行自动改判;②补录只以保单号必录,且保单号必须已存在;③补录允许改值并写入新表 pi_policy_supplement_trace 留痕;④合并键由「保单号」改为「保单号+险种代码」,修复同保单多险种串值。见 §2.1、§2.2、§2.2.1、§2.4.1、§4.5 |
| 2026-10-21(批改 importType 必传) | /import/endorse/upload 的 importType 由「选填、不传默认 ENDORSE_IMPORT」改为必传:页面「批改清单导入」按钮传 ENDORSE_IMPORT,页面「批单信息补录」按钮传 ENDORSE_SUPPLEMENT;漏传或传错值返回 000002 并给出可读提示。见 §一 约定 4、§2.4、§2.4.1 |
| 2026-10-26(第 2 批:校验与汇总口径) | ①业务员代码在 prpsagent 查不到 → 该行判为错误行(补录只校验本次录入的代码);②主表保费改为保单汇总(car_main/no_car_main.PREMIUM = 该保单所有险种保费之和),险种明细仍是一行一个险种落在 charge 表;③证件类型字典新增 5-统一社会信用代码,前端 enum.documentType 与后端映射同步(原映射到 2-营业执照,页面显示“其他”的问题彻底解决);④使用性质确认按模板文字原样落库。见 §一 约定 9、10、12 |
| 2026-10-26(归属/名称/明细落库口径) | ①归属机构改由「业务员代码」决定(回查 prpsagent 的 COMCODE/COMNAME),没录业务员就不再兜底成导入人(原逻辑会落 00000000 超级管理员 / 01 总公司);②保险公司名称一律以代码查 getInsures 的结果为准,文件里的名称不采信;③车辆「使用性质」「车主证件类型」、当事人「国籍」、险种「险种大类」以前没落库→详情页空白,现已按字典/原值落库;④证件类型映射修正为1身份证/2营业执照/3许可证/4其他(原先把「统一社会信用代码」映射成 4,页面显示“其他”);⑤同一保单多险种(交强+商业)按「保单号+险种代码」落 car_charge,不再互相覆盖。见 §一 约定 7、9、10、11 |
| 2026-10-29(机构兜底 + 名称清洗 + NPE 修复) | ①没录业务员代码时,省级机构退到上传弹窗选的佰盈分公司(地市级仍为空)——修掉「car_main.COMCODE 为 NULL → 列表页 NullPointerException 500」和「机构权限过滤导致地市级用户查不到这些保单」两个问题,见 §一 约定 9;②机构名称统一清洗(ConvertUtil.cleanOrgName:去主体前缀 + 去「分公司/支公司」后缀),保单查询列表/详情与批次详情共用同一实现,见《产险保单查询_前端联调说明》§6.1.1;③存量补写脚本 团财保单空机构按批次归属补写_BYXM-1891_20261029.sql |
一、导入模板与字段定义(必读)
模板由业务方提供,共 4 份:
| 模板 | 列数 | 表头结构 | 数据起始行 | 落库表 |
|---|---|---|---|---|
| 产险车险承保清单导入模板 | 73 | 第 1 行分组标题(合并单元格)+ 第 2 行字段名 | 第 3 行 | pi_policy_car_stg |
| 产险非车承保清单导入模板 | 62 | 第 1 行分组标题 + 第 2 行字段名 | 第 3 行 | pi_policy_nocar_stg |
| 产险非车被保人清单导入模板 | 6 | 第 1 行字段名 | 第 2 行 | pi_policy_insured_stg(新建) |
| 产险批改清单导入模板 | 15 | 第 1 行分组标题 + 第 2 行字段名 | 第 3 行 | pi_endorse_car_stg / pi_endorse_nocar_stg |
约定:
- 只允许
.xlsx;禁止修改表头,后端会逐列校验表头,不一致直接拒绝整份文件(错误码000002)。 - 表中“必录”= 模板里字体标红的字段,与需求 3.2.1.1.1.2 / 3.2.1.1.1.3 一致。
- 日期一律
yyyy-MM-dd;证件有效止期可填汉字“长期”,后端落9999-12-31。 - 非车保单“被保人类型=团体”时,被保人名称等可不录,改由被保人清单导入。
- 【2026-10-16】“被保险人与投保人关系=本人”时,被保人名称不再必录。 后端会把投保人的人员信息直接复制到被保人:姓名、证件类型、证件号码、证件有效止期、性别、国籍、移动电话、职业、联系地址(投保人该字段有值才复制,为空则保留被保人原值)。被保人类型、与被保人关系不参与复制。
- 【2026-10-16】“险种保费(含税)”与“险种保费(不含税)”至少录入一项(不再单独要求含税必录)。两者都为空时报:
险种保费(含税)、险种保费(不含税)至少录入一项。 - 【2026-10-26 口径变更】保险公司名称一律以「保险公司代码」查出来的为准。“保险公司名称”非必录;只要录了“保险公司代码”,后端就直接调用
/bankReports/getInsures同一套取数逻辑(BankReportsRepo#getInsures,精确匹配;数据源base_supplyinsurance,只认VALIDSTATUS='1')取名称落库,文件里填的名称一律不采信(业务常把全称简写成「中国大地」,落库后详情页/对账口径就不统一了)。- 代码在保司表查不到、但文件填了名称:先用文件名称落库,不阻断导入;
- 代码查不到、名称也没填:该行判为错误行,提示
保险公司代码[XXX]在保司表中不存在或未生效,请核实保险公司代码或补充录入保险公司名称; - 代码、名称都没录:仍按“保险公司代码必录”报错,不会再重复报保司不存在。
- 【2026-10-26】归属机构由「业务员代码」决定,不再默认挂到导入人头上。
- 后端按「归属业务员代码」回查核心业务员表
prpsagent(AGENTCODE),取其COMCODE/COMNAME落到本单的「佰盈地市机构代码 / 名称」,业务员姓名也以核心值为准; - 【2026-10-29 调整】没录业务员代码 → 退到上传弹窗选的佰盈省级分公司:之前这里是“全部为空”,实际跑出两个问题 ——① 列表页
getPage取car_main.COMNAME得到NULL,ConvertUtil.getString(null).replace(...)抛NullPointerException,整个保单查询接口 500(保单012026102900010001);② 列表 SQL 有机构权限过滤and a.comcode like 'BY0164%',COMCODE为NULL的保单对所有地市级用户都查不到,等于数据丢失。现在的口径:省级机构一定有值(取本批次的com_code,即上传时选的分司),地市级仍为空(没有业务员代码就无法确定),缺失必录项照常提示「业务员信息缺失」。 - 业务员代码在
prpsagent里查不到时该行判为错误行,提示业务员代码[XXX]在业务员表(prpsagent)中不存在,请核实业务员代码或先在核心系统维护该业务员(归属机构无法确定,不允许落“有业务员无机构”的脏数据);补录模式例外:只对本次真正录入的业务员代码做校验,历史继承来的老代码不卡补录。
- 后端按「归属业务员代码」回查核心业务员表
- 【2026-10-26】车辆/当事人/险种明细的落库口径(详情页能看到的字段)
- 「使用性质」按模板文字原样落
car_vehicle.USENATURECODE(非营运/营运…),不做代码转换; - 「车主证件类型」「投保人/被保人/受益人证件类型」按详情页字典落码:1-身份证、2-营业执照、3-许可证、4-其他、5-统一社会信用代码;
- 「国籍」落
car_party/no_car_party.COUNTRY; - 「险种大类」取模板
3-机动车辆保险的前缀数字落car_charge/no_car_charge.CLASSBIGCODE,详情页按RISK+代码翻译;base_risk有对应险种时同时回填riskId。
- 【2026-10-26】一张保单多个险种(交强 + 商业)可以并存。 险种明细按「保单号 + 险种代码」维度落
car_charge/no_car_charge,CLASSTYPE按「险种小类」判定(含“交强”→ 2-交强险,其余 → 1-商业险), 详情页分别展示在「交强险信息」「商业险信息」两个区块。 - 【2026-10-26】主表保费 = 保单汇总,险种明细 = charge 表一行一个险种。
car_main.PREMIUM/no_car_main.PREMIUM= 该保单所有险种保费(含税)之和(同一批次内按保单号汇总);- 每个险种一行落在
car_charge/no_car_charge(保单号 + 险种代码),车险详情页按CLASSTYPE分成「商业险信息」(1) 与「交强险信息」(2) 两个区块展示; - 非车详情页的「险种信息」只有一个区块(Vo 是单对象),多险种时展示导入顺序的第一个险种,保费合计看主表;若要按列表展示多个险种,需要前后端一起改(Vo 加 list + 前端循环)。
主表
car_main/no_car_main只有一组险种字段,多险种时RISKCODE/RISKNAME取第一个险种,
保费是保单汇总;险种明细一律以 charge 表为准。
- 【2026-10-21】承保清单「导入」与「补录」已拆分,靠接口必传参数
importType区分(详见 §2.2.1):
- 承保导入(
CAR_POLICY_IMPORT/NOCAR_POLICY_IMPORT):标红必录全量校验,适用于新保单; - 承保补录(
CAR_POLICY_SUPPLEMENT/NOCAR_POLICY_SUPPLEMENT):只有保单号必录,其余字段「录了才校验、不录不报」,保单号必须已存在;允许改值并写入留痕表pi_policy_supplement_trace; - 两者共用同一份模板,前端不需要准备第二套模板。
1.1 车险承保清单(73 列)
表头行 = 第 2 行,数据自第 3 行开始。
下表「必录」是承保导入(*_POLICY_IMPORT)的口径;承保补录(*_POLICY_SUPPLEMENT)只有「保单号」必录,其余字段留空即保持原值(见 §2.2.1)。
| 列号 | 信息分组 | 字段名 | 必录 |
|---|---|---|---|
| 1 | 保单基本信息 | 投保单号 | 否 |
| 2 | 保单基本信息 | 保单号 | 是 |
| 3 | 保单基本信息 | 保单状态 | 否 |
| 4 | 保单基本信息 | 投保日期 (格式:yyyy-MM-dd) | 否 |
| 5 | 保单基本信息 | 承保日期 (格式:yyyy-MM-dd) | 是 |
| 6 | 保单基本信息 | 生效日期 (格式:yyyy-MM-dd) | 否 |
| 7 | 保单基本信息 | 保险公司代码 | 是 |
| 8 | 保单基本信息 | 保险公司名称 | 否(只录代码时按代码自动补全,见 §1 约定 7) |
| 9 | 保单基本信息 | 业务形式 | 是 |
| 10 | 保单基本信息 | 业务属性 | 否 |
| 11 | 业务员信息 | 归属业务员代码 | 否 |
| 12 | 业务员信息 | 归属业务员姓名 | 否 |
| 13 | 车辆信息 | 车牌号码 | 否 |
| 14 | 车辆信息 | 品牌型号 | 否 |
| 15 | 车辆信息 | 车型描述 | 否 |
| 16 | 车辆信息 | 车架号 | 否 |
| 17 | 车辆信息 | 发动机号 | 否 |
| 18 | 车辆信息 | 初次登记日期 | 否 |
| 19 | 车辆信息 | 使用性质 | 否 |
| 20 | 车主信息 | 车主名称 | 否 |
| 21 | 车主信息 | 车主证件类型 | 否 |
| 22 | 车主信息 | 车主证件号码 | 否 |
| 23 | 车主信息 | 移动电话 | 否 |
| 24 | 投保人信息 | 投保人类型 | 是 |
| 25 | 投保人信息 | 投保人名称 | 是 |
| 26 | 投保人信息 | 投保人证件类型 | 否 |
| 27 | 投保人信息 | 投保人证件号码 | 否 |
| 28 | 投保人信息 | 证件有效止期 (格式yyyy-MM-dd,长期录入汉字“长期”) | 否 |
| 29 | 投保人信息 | 性别 (投保人类型为“个人”录入) | 否 |
| 30 | 投保人信息 | 国籍 (投保人类型为“个人”录入) | 否 |
| 31 | 投保人信息 | 移动电话 (投保人类型为“个人”录入) | 否 |
| 32 | 投保人信息 | 职业 (投保人类型为“个人”录入) | 否 |
| 33 | 投保人信息 | 联系地址 (省市区+详细地址) | 否 |
| 34 | 投保人信息 | 经营范围 (投保人类型为“企业”录入) | 否 |
| 35 | 投保人信息 | 法定代表人/负责人名称 (投保人类型为“企业”录入) | 否 |
| 36 | 投保人信息 | 授权业务人员名称 (投保人类型为“企业”录入) | 否 |
| 37 | 投保人信息 | 授权业务人员证件类型 (投保人类型为“企业”录入) | 否 |
| 38 | 投保人信息 | 授权业务人员证件号码 (投保人类型为“企业”录入) | 否 |
| 39 | 投保人信息 | 授权业务人员证件有效止期 (投保人类型为“企业”录入) | 否 |
| 40 | 投保人信息 | 授权业务人员移动电话 (投保人类型为“企业”录入) | 否 |
| 41 | 被保人信息 | 被保人类型 | 否 |
| 42 | 被保人信息 | 被保险人与投保人关系 (“本人”无需录入被保人其他信息) | 否 |
| 43 | 被保人信息 | 被保人名称 | 是(关系=本人 / 类型=团体 时可不录) |
| 44 | 被保人信息 | 被保人证件类型 | 否 |
| 45 | 被保人信息 | 被保人证件号码 | 否 |
| 46 | 被保人信息 | 证件有效止期 (格式yyyy-MM-dd长期录入汉字“长期”) | 否 |
| 47 | 被保人信息 | 性别 (被保人类型为“个人”录入) | 否 |
| 48 | 被保人信息 | 国籍 (被保人类型为“个人”录入) | 否 |
| 49 | 被保人信息 | 移动电话 | 否 |
| 50 | 被保人信息 | 职业 (被保人类型为“个人”录入) | 否 |
| 51 | 被保人信息 | 联系地址 (省市区+详细地址) | 否 |
| 52 | 受益人信息 | 受益人标志 (“法定受益人”无需录入后续受益人信息) | 否 |
| 53 | 受益人信息 | 受益人类型 | 否 |
| 54 | 受益人信息 | 受益人与被保人关系 (“本人”无需录入后续受益人信息) | 否 |
| 55 | 受益人信息 | 受益人名称 | 否 |
| 56 | 受益人信息 | 受益人证件类型 | 否 |
| 57 | 受益人信息 | 受益人证件号码 | 否 |
| 58 | 受益人信息 | 证件有效止期 (格式yyyy-MM-dd长期录入汉字“长期”) | 否 |
| 59 | 受益人信息 | 性别 (受益人类型为“个人”录入) | 否 |
| 60 | 受益人信息 | 国籍 (受益人类型为“个人”录入) | 否 |
| 61 | 受益人信息 | 移动电话 | 否 |
| 62 | 受益人信息 | 职业 (受益人类型为“个人”录入) | 否 |
| 63 | 受益人信息 | 联系地址 (省市区+详细地址) | 否 |
| 64 | 险种信息 | 险种代码 | 是 |
| 65 | 险种信息 | 险种名称 | 是 |
| 66 | 险种信息 | 险种大类 | 否 |
| 67 | 险种信息 | 险种小类 | 否 |
| 68 | 险种信息 | 保险金额 | 否 |
| 69 | 险种信息 | 险种保费(含税) | 含税/不含税至少一项 |
| 70 | 险种信息 | 险种保费(不含税) | 含税/不含税至少一项 |
| 71 | 险种信息 | 保险起期 (格式yyyy-MM-dd) | 否 |
| 72 | 险种信息 | 保险止期 (格式yyyy-MM-dd) | 否 |
| 73 | 险种信息 | 缴费方式 | 否 |
1.2 非车承保清单(62 列)
表头行 = 第 2 行,数据自第 3 行开始。
下表「必录」是承保导入(*_POLICY_IMPORT)的口径;承保补录(*_POLICY_SUPPLEMENT)只有「保单号」必录,其余字段留空即保持原值(见 §2.2.1)。
| 列号 | 信息分组 | 字段名 | 必录 |
|---|---|---|---|
| 1 | 保单基本信息 | 投保单号 | 否 |
| 2 | 保单基本信息 | 保单号 | 是 |
| 3 | 保单基本信息 | 保单状态 | 否 |
| 4 | 保单基本信息 | 投保日期 (格式:yyyy-MM-dd) | 否 |
| 5 | 保单基本信息 | 承保日期 (格式:yyyy-MM-dd) | 是 |
| 6 | 保单基本信息 | 生效日期 (格式:yyyy-MM-dd) | 否 |
| 7 | 保单基本信息 | 保险公司代码 | 是 |
| 8 | 保单基本信息 | 保险公司名称 | 否(只录代码时按代码自动补全,见 §1 约定 7) |
| 9 | 保单基本信息 | 业务形式 | 是 |
| 10 | 保单基本信息 | 业务属性 | 否 |
| 11 | 业务员信息 | 归属业务员代码 | 否 |
| 12 | 业务员信息 | 归属业务员姓名 | 否 |
| 13 | 投保人信息 | 投保人类型 | 是 |
| 14 | 投保人信息 | 投保人名称 | 是 |
| 15 | 投保人信息 | 投保人证件类型 | 否 |
| 16 | 投保人信息 | 投保人证件号码 | 否 |
| 17 | 投保人信息 | 证件有效止期 (格式yyyy-MM-dd,长期录入汉字“长期”) | 否 |
| 18 | 投保人信息 | 性别 (投保人类型为“个人”录入) | 否 |
| 19 | 投保人信息 | 国籍 (投保人类型为“个人”录入) | 否 |
| 20 | 投保人信息 | 移动电话 (投保人类型为“个人”录入) | 否 |
| 21 | 投保人信息 | 职业 (投保人类型为“个人”录入) | 否 |
| 22 | 投保人信息 | 联系地址 (省市区+详细地址) | 否 |
| 23 | 投保人信息 | 经营范围 (投保人类型为“企业”录入) | 否 |
| 24 | 投保人信息 | 法定代表人/负责人名称 (投保人类型为“企业”录入) | 否 |
| 25 | 投保人信息 | 授权业务人员名称 (投保人类型为“企业”录入) | 否 |
| 26 | 投保人信息 | 授权业务人员证件类型 (投保人类型为“企业”录入) | 否 |
| 27 | 投保人信息 | 授权业务人员证件号码 (投保人类型为“企业”录入) | 否 |
| 28 | 投保人信息 | 授权业务人员证件有效止期 (投保人类型为“企业”录入) | 否 |
| 29 | 投保人信息 | 授权业务人员移动电话 (投保人类型为“企业”录入) | 否 |
| 30 | 被保人信息 | 被保人类型 (团体无需录入被保人信息,通过被保人清单导入) | 否 |
| 31 | 被保人信息 | 被保险人与投保人关系 (“本人”无需录入被保人其他信息) | 否 |
| 32 | 被保人信息 | 被保人名称 | 是(关系=本人 / 类型=团体 时可不录) |
| 33 | 被保人信息 | 被保人证件类型 | 否 |
| 34 | 被保人信息 | 被保人证件号码 | 否 |
| 35 | 被保人信息 | 证件有效止期 (格式yyyy-MM-dd长期录入汉字“长期”) | 否 |
| 36 | 被保人信息 | 性别 (被保人类型为“个人”录入) | 否 |
| 37 | 被保人信息 | 国籍 (被保人类型为“个人”录入) | 否 |
| 38 | 被保人信息 | 移动电话 | 否 |
| 39 | 被保人信息 | 职业 (被保人类型为“个人”录入) | 否 |
| 40 | 被保人信息 | 联系地址 (省市区+详细地址) | 否 |
| 41 | 受益人信息 | 受益人标志 (“法定受益人”无需录入后续受益人信息) | 否 |
| 42 | 受益人信息 | 受益人类型 | 否 |
| 43 | 受益人信息 | 受益人与被保人关系 (“本人”无需录入后续受益人信息) | 否 |
| 44 | 受益人信息 | 受益人名称 | 否 |
| 45 | 受益人信息 | 受益人证件类型 | 否 |
| 46 | 受益人信息 | 受益人证件号码 | 否 |
| 47 | 受益人信息 | 证件有效止期 (格式yyyy-MM-dd长期录入汉字“长期”) | 否 |
| 48 | 受益人信息 | 性别 (受益人类型为“个人”录入) | 否 |
| 49 | 受益人信息 | 国籍 (受益人类型为“个人”录入) | 否 |
| 50 | 受益人信息 | 移动电话 | 否 |
| 51 | 受益人信息 | 职业 (受益人类型为“个人”录入) | 否 |
| 52 | 受益人信息 | 联系地址 (省市区+详细地址) | 否 |
| 53 | 险种信息 | 险种代码 | 是 |
| 54 | 险种信息 | 险种名称 | 是 |
| 55 | 险种信息 | 险种大类 | 否 |
| 56 | 险种信息 | 险种小类 | 否 |
| 57 | 险种信息 | 保险金额 | 否 |
| 58 | 险种信息 | 险种保费(含税) | 含税/不含税至少一项 |
| 59 | 险种信息 | 险种保费(不含税) | 含税/不含税至少一项 |
| 60 | 险种信息 | 保险起期 (格式yyyy-MM-dd) | 否 |
| 61 | 险种信息 | 保险止期 (格式yyyy-MM-dd) | 否 |
| 62 | 险种信息 | 缴费方式 | 否 |
1.3 非车被保人清单(6 列)
表头行 = 第 1 行,数据自第 2 行开始;一个保单号可有多行。
| 列号 | 信息分组 | 字段名 | 必录 |
|---|---|---|---|
| 1 | 保单号 | 是 | |
| 2 | 被保人名称 | 否 | |
| 3 | 被保人证件类型 | 是 | |
| 4 | 被保人证件号码 | 是 | |
| 5 | 证件有效止期 (格式yyyy-MM-dd长期录入汉字“长期”) | 否 | |
| 6 | 移动电话 | 否 |
1.4 批改清单(15 列)
表头行 = 第 2 行,数据自第 3 行开始;一个保单号可有多行(一行为一个批单险种)。
| 列号 | 信息分组 | 字段名 | 必录 | 落库字段 |
|---|---|---|---|---|
| 1 | 批单基本信息 | 保单号 | 是 | policy_no |
| 2 | 批单基本信息 | 批单号 | 是 | endorse_no |
| 3 | 批单基本信息 | 批单承保日期 (格式:YYYY-MM-DD) | 是 | accept_date |
| 4 | 批单基本信息 | 批单生效日期 (格式:YYYY-MM-DD) | 否 | generate_date |
| 5 | 批单基本信息 | 归属业务员代码 | 否 | handler_code |
| 6 | 批单基本信息 | 归属业务员姓名 | 否 | handler_name |
| 7 | 批单险种信息 | 险种代码 | 是 | risk_code |
| 8 | 批单险种信息 | 险种名称 | 是 | risk_name |
| 9 | 批单险种信息 | 险种大类 | 否 | risk_class |
| 10 | 批单险种信息 | 批单保险金额 | 否 | sum_insured |
| 11 | 批单险种信息 | 批单险种保费(含税) | 是 | premium |
| 12 | 批单险种信息 | 批单险种保费(不含税) | 否 | risk_premium_no_tax |
| 13 | 批单险种信息 | 保险起期 (格式yyyy-MM-dd) | 否 | start_date |
| 14 | 批单险种信息 | 保险止期 (格式yyyy-MM-dd) | 否 | end_date |
| 15 | 批单险种信息 | 缴费方式 | 否 | pay_type |
批改模板的四条特殊规则(与承保清单不同,务必注意):
模板没有“产险类型”列。 车险 / 非车由后端按「保单号」反查
car_main、no_car_main自动判定,判定结果回填property_type(车险 / 非车),并决定落到pi_endorse_car_stg还是pi_endorse_nocar_stg。前端无需也无法指定。保单号必须已存在于主表(2026-10-16 需求变更,强化)。 两侧主表都查不到时该行记为错误行,错误信息为「保单号[XXX]在车险/非车保单主表中不存在,请先导入承保清单」(带出具体保单号)。因此批改清单必须在对应承保清单导入并审批回写之后才能导入。
批改数据不回写任何主表(2026-10-16 需求变更)。 导入解析落
pi_endorse_car_stg/pi_endorse_nocar_stg,审批通过后落到独立批单表pi_endorse_bill;不会修改car_main/no_car_main,也不会再写pi_endorse_car_main/pi_endorse_nocar_main。批单查询 / 导出 / 详情(§2.14~2.16)全部读pi_endorse_bill。两种导入模式(同一个接口,靠
importType区分,模板字段完全相同,仅必录不同):importType 页面入口 必录字段 前置校验 ENDORSE_IMPORT(必传)批改清单导入 模板标红的 6 列:保单号、批单号、批单承保日期、险种代码、险种名称、批单险种保费(含税) 保单号+批单号+险种代码 在文件内及历史(批单表 + 待审 stg)均不得重复 ENDORSE_SUPPLEMENT(必传)批单信息补录 批单号、险种代码 目标批单(保单号+批单号)必须已导入成功,否则提示「保单号+批单号不存在」;审批时按最新数据 update 批单表
其它校验:日期须为 yyyy-MM-dd;保险止期须 ≥ 保险起期;险种大类枚举「1-企业财产保险 … 14-其他险」共 14 项;缴费方式枚举「趸交 / 按年缴 / 不定期」;金额类字段须为数字且最多 2 位小数;归属业务员代码必须在核心 prpsagent 中存在,业务员姓名以核心值为准(不取用户录入值)。
二、接口清单
所有 POST 请求的 Content-Type:
application/json;charset=utf-8
所有 GET 请求的 Content-Type:URL query string
上传接口(除下载外)的 Content-Type:multipart/form-data
2.1.0 承保清单统一导入(兼容旧前端 新增)
这个端点只是为了兼容旧版打包 JS(旧版统一调
/import/policy/upload)。
新前端请直接用 §2.1/import/car/upload或 §2.2/import/nocar/upload,语义更明确。
2.1 车险承保清单导入 / 补录
落库
pi_policy_car_stg;行级错误写pi_import_error,可用 §2.5/§2.6 查。
表头校验不通过时返回code=000002,msg里会带出具体哪一列被改。
文件没有任何数据行时返回code=000002(未解析到有效数据行),规则见 §2.2.1。⚠️ 2026-10-27 起:只要有 1 行校验失败,整批就是「数据校验失败」
旧行为是「解析完成」一律置
VALIDATED(前端显示待提交审核),错误行被静默丢掉,
用户以为导入成功,对账时才发现少单。新规则:
条件 返回 code 批次 status(前端显示) 暂存表 errorRows = 0000000VALIDATED(待提交审核)正常落库 errorRows > 0(哪怕只有 1 行)000002POST_FAILED(数据校验失败)一行都不落(解析期已写的行会清掉) 无数据行 / 表头错 000002POST_FAILED(数据校验失败)不落库 失败时
msg形如:"数据校验失败:共 11 行,其中 4 行校验未通过,本批次未导入任何数据,请按错误明细修正后重新导入。\n4 行校验失败:第 3 行 保单号必录字段未录入;…"successRows记为0(未落库就不该显示成功行数),原统计写进pi_import_audit_log。POST_FAILED的批次不能提交审核(后端submitBatch只认VALIDATED),只能看错误明细后重新导入。适用范围(2026-10-27 起统一,四个入口完全一致):
① 车险承保清单(/import/policy/car/upload)
② 非车承保清单(/import/policy/nocar/upload,含随附上传的被保人清单,两类行合并统计)
③ 非车被保人清单单独导入(/import/insured/upload)
④ 批改清单导入 / 批单信息补录(/import/endorse/upload)四个入口都遵守:
errorRows = 0→000000+VALIDATED;errorRows > 0(哪怕 1 行)→000002+POST_FAILED+ 清空本批次所有暂存行(含pi_policy_insured_stg、pi_endorse_*_stg)。2026-10-27 新增的三类行级校验
校验 触发条件 错误文案 保险公司代码 代码在保司表(走 getInsures,VALIDSTATUS='1'+ 精确匹配)查不到保险公司代码[xxx]在保司表中不存在或未生效,请核实保险公司代码业务员代码 代码在 prpsagent查不到(没填业务员不报错:省级机构退到上传时选的分司,地市级留空,缺失必录项会提示「业务员信息缺失」)业务员代码[xxx]在业务员表(prpsagent)中不存在,请核实业务员代码或先在核心系统维护该业务员文件内重复 同一份文件里「保单号 + 险种代码」出现两次及以上 保单号[xxx]险种代码[yyy]在本文件中重复录入(第 N 行已存在同一保单同一险种,请删除重复行后重新导入)注意:同一张保单投「交强 + 商业」两个险种是合法的(险种代码不同,不算重复);
同一险种写两行才算重复 —— 两行都落库会让主表保费汇总翻倍、险种明细互相覆盖。2026-10-29 新增:库内已存在校验(仅「承保导入」模式)
校验 触发条件 错误文案 库内已存在 承保导入模式下, car_charge/no_car_charge里已有同一「保单号 + 险种代码」保单号[xxx]险种[yyy]已存在,导入不允许覆盖已有数据,如需修改请改用「承保补录」入口
- 口径:导入按 POLICYNO + RISKCODE 去重,已存在的保单不允许用导入覆盖
(否则险种重复、保费重复计算);承保补录(
*_POLICY_SUPPLEMENT)不做此校验,
补录会按 保单号+险种 先删后插并写pi_policy_supplement_trace留痕。
- 险种代码为空时不判此条(无法定位险种,空值由必录校验兜底)。
- 同一文件里相同的「保单号+险种」只查一次库(进程内缓存),几千行文件不会放大 SQL 次数。
保司代码原先「查不到但文件里手填了名称就放过」,现改为一律报错:
手填名称与代码对不上时,后续结算/对账取的是代码,会整批对不上账。
importType缺失 / 非法 / 与本接口不符的情况(都是code=000002,不产生批次):
- 不传:
importType 不能为空:车险请传 CAR_POLICY_IMPORT(承保导入)或 CAR_POLICY_SUPPLEMENT(承保补录);非车请传 … - 传了
NOCAR_*调本接口:importType[NOCAR_POLICY_IMPORT]与当前导入入口不一致:importType 表明为非车,请勿混用
2.2 非车承保清单导入 / 补录(可同时传被保人清单)
承保清单落
pi_policy_nocar_stg,被保人清单落pi_policy_insured_stg,共用同一个 batchNo,
一次提交、一次审核。需求 3.2.1.1.1.5 第 7 条:被保人类型=团体时必须上传被保人清单。errorRows > 0时msg会带出行号与原因(最多列前 5 行),与 §2.1 格式一致;
被保人清单部分的失败行也会合并进同一条 msg 与errorDetails。
2026-10-27 起:承保清单或被保人清单任一行校验失败,返回code=000002、批次POST_FAILED(数据校验失败),并同时清空pi_policy_nocar_stg与pi_policy_insured_stg
本批次的行,successRows记 0 —— 两类行是一个整体,不会出现「承保落了、被保人没落」。补录模式(
NOCAR_POLICY_SUPPLEMENT)下insuredFiles会被忽略(补录只处理承保字段,
被保人请用 §2.3 单独导入),后端会打一条 warn 日志,不报错。
2.2.1 承保「导入」与「补录」的区别(2026-10-21 重构)
承保清单导入与补录共用同一份模板、同一套解析与落库链路,由调用方传的 importType 显式区分,后端不再按行自动判定(旧逻辑是「历史字段把必录项补齐了就算补」,这会让补录规则名不副实:历史本身缺某个必录字段时,补录一个字段也得先把所有历史缺口补齐)。
| 维度 | 承保导入(*_POLICY_IMPORT) |
承保补录(*_POLICY_SUPPLEMENT) |
|---|---|---|
| 必录字段 | 完整必录清单(标红 8 项 + 保费二选一 + 条件性被保人名称) | 只有保单号 |
| 保单号存在性 | 不校验(可以是新保单) | 必须已存在(历史批次或 car_main/no_car_main),否则该行报错 |
| 字段校验范围 | 全量校验(日期/枚举/金额/证件/联动) | 只校验本次真正录入了值的字段,历史脏值不拖累本次 |
| 与历史值的关系 | 本次有值 → 用本次值;本次为空 → 继承历史值 | 同左(允许改值) |
| 改值留痕 | 不记录 | 记录到 pi_policy_supplement_trace(字段级) |
批次 import_type |
CAR_POLICY_IMPORT / NOCAR_POLICY_IMPORT |
CAR_POLICY_SUPPLEMENT / NOCAR_POLICY_SUPPLEMENT |
合并键 = 保单号 + 险种代码(2026-10-21 起)。此前只按保单号合并,同一张保单下A/B 两个险种各占一行时,后导入的行会把另一险种的保费、起止期当“历史值”继承过来,造成险种串值。现在每个险种各认各的历史行,互不影响。
补录的额外校验
- 保单号在历史批次与主表中都查不到 → 该行报
保单号[XXX]在历史导入批次与保单主表中均不存在,请确认保单号是否正确,或改用「承保清单导入」; - 同一保单号在历史批次里存在多个险种、而本次没录险种代码 → 该行报
保单号[XXX]在历史批次中存在多个险种,请录入险种代码以定位本次补录的险种(否则无法确定要补哪一个险种)。
值合并细则(两种模式一致)
- 历史行里已有有效值的字段:本次录了值 → 以本次为准(补录可改值,变化写入留痕);本次为空 → 继承历史值,不会被置空;
- 历史与本次都为空 → 保持为空;
- 系统/流程列(批次号、Excel 行号、记录类型、解析/审核状态等)只取本次的值,不继承;
- 合并后的行以本次批次号落库,§2.5 批次明细能查到本次这条记录 = 该保单当前的完整视图;
- 同一文件内同一保单同一险种出现多行时,仍各自成行(批次内不做合并)。
改值留痕(pi_policy_supplement_trace)
补录时凡「历史有值 且 本次录入了不同的值」,逐字段写一条记录:batch_no / row_no / policy_no / risk_code / field_name / old_value / new_value / change_type=OVERRIDE / operator_code / operator_name / created_time。纯补缺(历史为空、本次补上)不逐字段记录——本次 stg 行本身就是补缺结果。接口返回的 data.changedFields 为本次留痕条数。
审批回写主表时
car_main/no_car_main的回写改为只写本次有值的列(insert 列清单与on duplicate key update子句都按非空参数动态生成):本次为 null 的列不插入、不更新,主表里已有的值原样保留。因此先审批新批次、后审批老批次也不会把数据冲掉。
空文件防护
- 文件里一条数据行都没有(只有表头/空模板)时,不再返回“导入成功”:返回
code=000002,msg="未解析到有效数据行:请确认模板第 3 行起已填写数据后重新导入",批次状态置为POST_FAILED(仍会出现在批次列表,total=0,便于追溯)。 - 该防护对**被保人清单单独导入(§2.3,提示为“第 2 行起”)与批改清单导入(§2.4)**同样生效。
2.3 非车被保人清单单独导入(补录场景)
落库
pi_policy_insured_stg。适用于非车保单信息补录时单独补充被保人。errorRows > 0时msg同样带“第几行、什么原因”(格式同 §2.1)。
2026-10-27 起:只要有 1 行校验失败,返回code=000002、批次POST_FAILED(数据校验失败),
且清空本批次已写入的pi_policy_insured_stg行,successRows记 0。
2.4 批改清单导入 / 批单信息补录
返回:Result { code, msg, data: { batchNo, totalRows, successRows, errorRows, insuranceScope, errorDetails } }
落库:pi_endorse_car_stg / pi_endorse_nocar_stg(按保单号自动判定,见 §1.4 规则 1);审批通过后落到独立批单表 pi_endorse_bill(唯一键 policy_no + endorse_no + risk_code,upsert)。不写 car_main / no_car_main 任何列。
返回码与其他导入接口一致:表头不符 000002,解析异常 000001,无数据行 000002(未解析到有效数据行);errorRows > 0 时 msg 带“第几行、什么原因”。
2026-10-27 起:只要有 1 行校验失败(业务员代码错、保单号不存在、重复导入、补录目标不存在等),返回 code=000002、批次 POST_FAILED(数据校验失败),清空本批次 pi_endorse_car_stg /pi_endorse_nocar_stg 已写入的行,successRows 记 0。批改数据是链式数据,只落一部分会让后续补录与对账全部对不上,因此不再保留「部分成功」。
importType 必传(2026-10-21 起)——两个按钮调的是同一个接口,靠这个字段区分:
| 页面按钮 | 传值 | 后端行为 |
|---|---|---|
| 批改清单导入 | ENDORSE_IMPORT |
按模板标红 6 列必录校验;保单号+批单号+险种代码 与历史重复则报错 |
| 批单信息补录 | ENDORSE_SUPPLEMENT |
批单号、险种代码必录;目标批单必须已导入成功,审批时 update 批单表 |
漏传返回 000002:importType 不能为空:批改清单导入请传 ENDORSE_IMPORT,批单信息补录请传 ENDORSE_SUPPLEMENT;传了非枚举值返回 000002:importType 取值非法,仅支持 ENDORSE_IMPORT(批改清单导入)/ ENDORSE_SUPPLEMENT(批单信息补录),当前传入[XXX]。
行级错误文案(会出现在 msg 与 errorDetails 里,前端可直接展示):
| 场景 | 文案 |
|---|---|
| 保单号在主表不存在 | 保单号[10578003903350998852]在车险/非车保单主表中不存在,请先导入承保清单 |
| 文件内重复 | 保单号+批单号+险种代码重复 |
| 与历史(批单表/待审 stg)重复 | 保单号+批单号+险种代码已存在,请勿重复导入 |
| 补录时目标批单不存在 | 保单号+批单号不存在 |
| 补录时险种不存在 | 保单号+批单号+险种代码不存在 |
| 业务员代码不在核心 | 归属业务员代码[XXX]在核心系统中不存在 |
| 日期格式 | <字段名>须录入yyyy-MM-dd |
| 金额格式 | <字段名>只能录入数字且最高精确到小数点后2位 |
| 止期 < 起期 | 保险止期不能小于保险起期 |
| 枚举不符 | <字段名>取值不在枚举范围内:xxx |
调用示例:
导入顺序要求:批改是对已有保单的批改,保单号必须在
car_main/no_car_main中存在,
即对应承保清单需先导入并审批回写。查不到的行计入errorRows,
可在 §2.5 批次详情里看到具体行号与错误原因。
2.4.1 批次列表(importType 字段口径,2026-10-16 补充)
businessType(产险类型:车险 / 非车)2026-10-29 新增。
之前后端根本没接这个参数,页面勾了「车险」仍然带出非车批次。现在按pi_import_batch.insurance_scope做等值过滤:
入参 businessType实际过滤条件 CAR/车险insurance_scope = 'CAR'NOCAR/NONCAR/NON_CAR/非车insurance_scope = 'NOCAR'ALL/全部/ 不传 / 空串不过滤(车 + 非车都返回) 入参名
insuranceScope是同义别名,两个都传时以businessType为准。
注意:被保人清单导入(/import/insured/upload)的批次insurance_scope是NOCAR,
勾「车险」时不会出现在列表里。
返回 data 同时挂两套分页别名(content/rows/list/data + totalElements/total/totalRecords),由于历史前端读的是 rows || list || data + total,两种取值方式都能命中。每行字段:
batchNo, bizType, insuranceScope, importType, fileName, uploadUserCode, uploadUserName, uploadTime, status, comCode, comName, totalRows, successRows, errorRows, approveUserCode, approveUserName, approveTime, approveRemark, remark
comCode/comName是「上传时选的佰盈省级分公司」,不是登录人机构(2026-10-29 修正)。
之前后端只认登录人,超级管理员(00000000 / 01 总公司)导入的批次一律显示「总公司」,
与弹窗里选的「浙江分公司」对不上。现在四个上传接口都接收comCode/comName并按它落库、
列表按它回显与筛选。存量批次已由团财批次机构回显订正_BYXM-1891_20261029.sql按暂存行的
业务员归属机构(前 6 位)回填;信息不足(整批业务员都属总公司 / 没落机构)的批次保持原样。
importType 直接返回中文(库里 pi_import_batch.import_type 存英文枚举,接口出中文,前端无需再维护映射):
| 接口返回值 | 库里存的枚举 | 含义 | 由哪个入口写入 |
|---|---|---|---|
车险承保导入 |
CAR_POLICY_IMPORT |
车险承保清单导入 | POST /import/car/upload?importType=CAR_POLICY_IMPORT |
车险承保补录 |
CAR_POLICY_SUPPLEMENT |
车险承保清单补录 | POST /import/car/upload?importType=CAR_POLICY_SUPPLEMENT |
非车承保导入 |
NOCAR_POLICY_IMPORT |
非车承保清单导入 | POST /import/nocar/upload、/import/policy/upload(importType=NOCAR_POLICY_IMPORT) |
非车补录 |
NOCAR_POLICY_SUPPLEMENT |
非车承保清单补录 | 同上(importType=NOCAR_POLICY_SUPPLEMENT) |
被保人清单导入 |
INSURED_IMPORT |
非车被保人清单导入 | POST /import/insured/upload |
批改清单导入 |
ENDORSE_IMPORT |
批改清单导入(必传) | POST /import/endorse/upload(importType=ENDORSE_IMPORT) |
批单信息补录 |
ENDORSE_SUPPLEMENT |
批单信息补录(必传) | POST /import/endorse/upload(importType=ENDORSE_SUPPLEMENT) |
""(空串) |
NULL / 未识别 | 2026-10-16 之前的历史批次 | —(存量数据可跑 §4.4 的回填脚本补齐) |
「导入」与「补录」的判定口径(2026-10-21 变更):承保清单的 import_type 完全由调用方传的 importType 决定,后端不再按行自动改判(旧逻辑是「整批成功行都命中历史保单号才算补录」,会让补录规则名不副实)。批改侧同样是调用方决定,且 2026-10-21 起 importType 必传(不再有默认值):「批改清单导入」传 ENDORSE_IMPORT,「批单信息补录」传 ENDORSE_SUPPLEMENT。
该字段保证在每个元素里出现:后端对空值统一兜底成空串,前端
row.importType不会是undefined。
另:bizType(POLICY/ENDORSE)仍表示批次大类型,与importType是粗细两级维度。
2.5 批次详情(解析明细 + 错误明细)
机构四列(2026-10-29 补,任务详情页「佰盈省级机构代码/名称」「佰盈地市机构代码/名称」)
| 页面列 | JSON 字段 | 取值口径 | 示例(批次 PC202610291401562111CCCC) |
|---|---|---|---|
| 佰盈省级机构代码 | provinceComCode |
地市机构代码前 6 位(与核心系统 SUBSTR(comcode,1,6) 一致) |
BY0164 |
| 佰盈省级机构名称 | provinceComName |
该省级机构简称,去掉主体前缀与「分公司」后缀 | 浙江 |
| 佰盈地市机构代码 | cityComCode |
stg 的 com_code(业务员归属机构) |
BY016431 |
| 佰盈地市机构名称 | cityComName |
该地市机构简称,去掉主体前缀与「分公司」后缀 | 浙江杭州 |
| (兼容别名) | comSubCode / comSubName |
与 cityComCode / cityComName 相同 |
同上 |
名称清洗规则:先去掉
base_company.COMCNAME的公司主体(如“天安佰盈保险销售有限公司”),
再去掉机构后缀(中心支公司 / 分公司 / 支公司 / 营业部 / 有限公司),只留地区部分。com_code本身已是 6 位省级机构时,地市两列为空串;某行没录业务员、查不到归属机构时,四列都是空串(不会回退成别的字段)。
这四列是后端算好返回的,前端不要再用comCode/com_code兜底(原来就是靠兜底才把地市代码显示成省级代码)。
2.6 批次错误明细(仅错误行)
2.6.1 批次审核历史(新增)
action取值:UPLOAD(上传解析)/SUBMIT(提交审核)/APPROVE(审批通过并回写)/REJECT(审批驳回)/POST_FAILED(处理失败)/DELETE(删除批次)。- 写日志的埋点:上传解析完成/失败、提交审核、审批通过(含存在回写失败)、审批驳回、异常兜底、删除。
- 前端表格只需要
operator/auditResult/auditRemark/operateTime四个字段,其余是冗余别名。
2.6.2 删除批次(新增)
- 逻辑删除:只把
pi_import_batch.del_flag置 1,stg 明细与错误明细一律保留,随时可改回 0 恢复。 - 列表查询
POST /import/batch/list已过滤ifnull(del_flag,0)=0,删除后不再出现。 - 状态限制(不满足返回
000001):APPROVING(待审核)→ 「批次处于“待审核”,不允许删除,请先完成审核或驳回」POSTED(已回写主表)→ 「批次已审批通过并回写主表,不允许删除」- 其余状态(
UPLOADED/VALIDATED/POST_FAILED/REJECTED)允许删除。
- 删除动作会写一条
DELETE的审核历史。
2.6.3 任务详情导出(新增)
- 响应:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,文件名任务详情_<batchNo>.xlsx,Body 为 xlsx 二进制。 - 三个 sheet:
批次信息:两列(字段 / 值),字段名与枚举值均为中文(如批次号、批次状态=已校验);导入明细:双行表头与导入模板一致——第 1 行分组标题(合并单元格),第 2 行中文字段名,列顺序按对应模板列序(承保批次按车险 73 列 / 非车 62 列模板,批改批次按批改 15 列模板),前 N 列与用户导入时用的模板逐列一致;模板中没有的系统/扩展字段(出生日期、审核状态、回写快照 JSON 等)统一排在末尾分组;含before_snapshot_json/after_snapshot_json等 JSON 快照列,便于排查回写结果;解析/审核/回写状态字段导出为中文;错误明细:Excel行号 / 列名 / 错误码 / 错误描述 / 原始行数据 / 创建时间。
- 日期统一格式化为
yyyy-MM-dd HH:mm:ss字符串,避免导出成数字。 - 要用
window.location.href或a[download]跳转,不要走 ajax(见 2.7 第 5 条)。 - 出错时返回业务异常
000004(如批次不存在、导出失败),json 形态。
2.7 下载导入模板
templateType 为必填参数,取值:
| templateType | 下载文件名 | 说明 |
|---|---|---|
car |
产险车险承保清单导入模板.xlsx | 73 列,双行表头 |
nocar |
产险非车承保清单导入模板.xlsx | 62 列,双行表头 |
insured |
产险非车被保人清单导入模板.xlsx | 6 列,单行表头 |
endorse |
产险批改清单导入模板.xlsx | 15 列,双行表头 |
响应:
- Content-Type:
application/octet-stream;charset=ISO8859-1 - Content-disposition:
attachment; filename=<上表文件名> - Body: xlsx 二进制
前端调用注意(容易踩):
- 必须带
templateType,且要按用户点击的是哪一类模板动态传值。四个模板对应四个入口,不要用一个固定 URL。 - 漏传参数不再抛框架异常(原来会报
MissingServletRequestParameterException,浏览器只看到 400 白页),而是返回统一业务响应,前端按普通错误提示即可:JSON复制成功{"code": "000004","msg": "缺少模板类型参数 templateType。可选值:car(车险承保清单)/ nocar(非车承保清单)/ insured(非车被保人清单)/ endorse(批改清单)。示例:/tabycore/property_insurance/import/downloadTemplate?templateType=car"} - 传了不支持的值同样返回
000004:模板类型不支持:xxx,可选值:car(车险承保清单)/ ...。 - 参数值大小写与首尾空格后端会自动归一化(
Car、car均可)。 - 下载类接口建议用
window.location.href或a[download]直接跳转,不要用 ajax(二进制流无法走 JSON 解析)。
2.8 提交审核
2.9 审核(通过/不通过)
审批通过时的回写范围(2026-10-13 补充):除主表(
car_main/no_car_main)外,
还会回写保单详情页依赖的关联表,采用「先删后插」保证重复审批幂等:
no_car_party:投保人(PARTYFLAG=1)、被保人(2)、受益人(3,仅「指定受益人」且有姓名时写);
当事人类型 个人→1/企业→2,证件类型 身份证→1/户口本→2/统一社会信用代码→4/出生医学证明→9,
性别 男→1/女→2(「其他」无代码留空),与被保人关系 本人→1/配偶→2/子女→3/父母→4/其他→5;
证件有效期「长期」落 9999-12-31 + LONGFLAG=1
no_car_charge:险种保费(RISKCODE/RISKNAME/AMOUNT/PREMIUM/起止日期)- 车险:
car_party(同口径)、car_charge(CLASSTYPE=1 商业险)、car_vehicle(车辆信息)
注意:同一张保单分多个批次导入时,关联表内容以最后一次审批的批次为准
(该批次的 stg 行即补录合并后的完整视图)。批改批次(biz_type=ENDORSE)不适用上面这段(2026-10-16 变更):审批通过时
只 upsert 独立批单表pi_endorse_bill(唯一键policy_no + endorse_no + risk_code,insert ... on duplicate key update,补录场景即「按最新导入数据更新」),
不写car_main/no_car_main,也不写no_car_party/car_party/*_charge/car_vehicle。
2.10 兼容旧接口(前端如果还没改完,可以继续用)
内部均调用 auditBatch。
2.11 团财保单查询(已存在,保持不变)
2.12 团财保单详情(已存在)
2.13 团财保单导出(已存在)
2.13.1 导出「需要补录的保单」(2026-10-29 新增)
Sheet1 固定 6 列:佰盈省级分公司代码 / 佰盈省级分公司名称 / 佰盈地市级分公司代码 / 佰盈地市级分公司名称 / 保单号 / 保单缺失信息。
- 只导出「存在缺失项」的保单,
missFlag入参被忽略; - 缺失信息 = 字段缺失(
view_car_missmessage/view_nocar_missmessage,与邮件催办同一口径)- 影像缺失(
imageupload缺必需类型;仅对已建档影像的保单生效,产险当前无影像数据 → 暂不命中);
- 影像缺失(
- 缺失信息格式:
段名:字段、字段;段名:字段(中文分号分隔); - 机构名称按 §2.4 同一套规则清洗(去主体前缀 + 去机构后缀)。
详细字段、错误码、前端调用方式见
产险保单缺失项导出_前端对接_BYXM-1891_20261029.md。
2.14 团财批单查询(新增)
数据源:独立批单表
pi_endorse_bill(§2.4 审批后落地)+ 保单主表car_main/no_car_main。
展示口径:批改导入文件里有的字段取批单表(批单号、承保日期、生效日期、业务员代码/姓名),
其余字段取样单主表(保险公司名称、地市级机构名称、投保人名称、被保人名称、产险类型)。
列表维度是「保单号 + 批单号」,一个批单下多个险种只展示一行。
返回:Result,data 是 Spring PageImpl(与保单查询 §2.11 完全同构,读 content + totalElements)
| code | msg | 说明 |
|---|---|---|
| 000000 | 查询成功 | |
| 000003 | 查询条件不能为空 | 未传 body |
| 000003 | 承保日期和保单号、批单号必录其一 | 两个条件都为空 |
| 000003 | 无记录 | 查询结果为空(此时 data 仍为 Page 对象,content 为空数组) |
| 000001 | 系统查询异常! | 后端异常,看服务日志 |
字段说明:
propertyType返回中文「车险 / 非车」(不再是 1/2)。comName返回去掉「天安佰盈保险销售有限公司」前缀的简称(如「上海分公司本部营业部」)。acceptDate/generateDate是Date类型,全站无 jackson 日期配置,序列化为毫秒时间戳(如1785513600000)。前端请自行格式化;直接moment(毫秒数)可用,但不要moment("1785513600000")字符串(会得到 Invalid date)。
调用示例:
2.15 团财批单详情(新增)
返回结构与保单详情(§2.12
policyQuery/detail)完全一致,都是PolicyDataDetailVo,
只是在保单基本信息之外多出两段:endorseBasicInfo(批单基本信息)、endorseRiskInfoList(批单险种信息)。
保单基本信息段直接取车主表/非车主表(与保单详情同逻辑)。
| 参数 | 必填 | 说明 |
|---|---|---|
| policyNo | 是 | 保单号 |
| endorseNo | 否 | 批单号;不传则取该保单下最新审批的一条批单 |
| propertyType | 否 | 已不再用于路由(产险类型由批单表自身判定),保留仅为兼容前端旧调用 |
返回:Result,data 是 PolicyDataDetailVo
| code | msg | 说明 |
|---|---|---|
| 000000 | 查询成功 | |
| 000003 | 保单号不能为空 | |
| 000003 | 未查询到批单详情 | 该保单号下没有已审批的批单(data 为 null) |
| 000001 | 系统查询异常! |
endorseBasicInfo.totalPremiumTax / totalPremiumNoTax= 该批单下所有险种对应保费的合计(后端 SUM)。- 日期字段(
endorseAcceptDate/endorseEffectDate/startDate/endDate)后端已格式化为yyyy-MM-dd字符串,前端可直接渲染。 settleCommissionRate/settleCommissionBasis需求文档有这两列,但批改模板未提供,当前恒为null,前端留空占位即可。
2.16 团财批单导出(新增)
入参、过滤逻辑、排序与 §2.14 完全一致(同一套
PolicyEndorseQueryCondition),只是不分页。
导出列与查询结果 11 列一致,「承保日期和保单号、批单号必录其一」的校验同样生效。
| 导出列顺序 | 表头 | VO 字段 |
|---|---|---|
| 1 | 保单号 | policyNo |
| 2 | 批单号 | endorseNo |
| 3 | 承保日期 | acceptDate |
| 4 | 生效日期 | generateDate |
| 5 | 产险类型 | propertyType |
| 6 | 保险公司名称 | companyName |
| 7 | 地市级机构名称 | comName |
| 8 | 业务员代码 | agentCode |
| 9 | 业务员姓名 | agentName |
| 10 | 投保人名称 | insureName |
| 11 | 被保人名称 | insuredName |
必须走整页跳转(
window.location.href = ...)或responseType: 'blob',不能走普通 ajax,否则拿不到二进制流。
条件不满足时后端抛DataIntegrityViolationException(HTTP 500),前端请先复用 §2.14 的校验规则。
2.17 影像件上传(新增)
本模块完全参考寿险影像件上传(
ImageUploadController)实现,落库沿用同一张表imageupload,
与寿险只有两点差异:①接口名不同;②上传目录由imageUpload/改为propertyimage/。
因此 本次不需要新建任何表(原先准备的pi_policy_image建表 SQL 已作废并删除)。
产险当前业务只要求上传「投保人影像」一类。
落盘路径:
{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 影像件查询(按保单号,新增)
保单号超链接进入影像上传页面时调用,返回该保单下的全部影像件,按影像分类分组。
imageURL就是访问地址,前端预览/下载直接用它。查询失败返回000002。
2.19 影像件删除(新增)
同时删除服务器物理文件与
imageupload表记录。删完由前端重新调用 2.18 刷新。
删除失败返回
000002+ "图片删除失败!"。前端需先弹框确认"是否确定删除?"。
2.20 影像件下载(新增)
三、新增/修改的 VO 字段
PolicyEndorseListVo(产险批单列表 / 导出,11 列)
字段:policyNo, endorseNo, acceptDate(Date), generateDate(Date), propertyType, companyName, comName, agentCode, agentName, insureName, insuredName
propertyType返回中文「车险 / 非车」。comName已去掉「天安佰盈保险销售有限公司」前缀。
EndorseBasicInfo(批单基本信息,新增)
字段:endorseNo, endorseAcceptDate(yyyy-MM-dd), endorseEffectDate(yyyy-MM-dd), totalPremiumTax(BigDecimal), totalPremiumNoTax(BigDecimal), agentCode, agentName
EndorseRiskInfo(批单险种信息,新增)
字段:riskClass, riskCode, riskName, sumInsured(BigDecimal), premiumTax(BigDecimal), premiumNoTax(BigDecimal), startDate(yyyy-MM-dd), endDate(yyyy-MM-dd), payType, settleCommissionRate(BigDecimal, 当前恒 null), settleCommissionBasis(当前恒 null)
PolicyDataDetailVo(产险保单/批单详情,已存在)
原有字段不变:
policyBasicInfo, carInfo, insureInfo, insuredInfoList, syInfoList, agentInfo, tciRiskInfo, vciRiskInfo, noCarRiskInfoMap, noCarRiskInfo本轮新增两段(仅批单详情接口返回,保单详情接口为
null且因@JsonInclude(NON_NULL)不出现在 JSON 里):Java复制成功private EndorseBasicInfo endorseBasicInfo;private List<EndorseRiskInfo> endorseRiskInfoList;
PolicyEndorseDetailVo已于 2026-10-16 删除——批单详情统一复用PolicyDataDetailVo,
与保单详情(§2.12)保持同构,前端可以复用同一套详情渲染组件。
影像件相关 VO(复用寿险已有的类,无新增)
- 入参
ImageUploadVO:影像件模块用到的字段是policyNo(保单号)、imageType(影像类型)、imageNameFromSftp(服务器文件地址/整条URL) - 出参
ImageReturnVO:imageName(文件名)、imageURL(访问地址)
PolicyEndorseQueryCondition
字段:comCode, codeName, comSubCode, comSubName, companyCode, companyName, acceptStartDate, acceptEndDate, policyNo, endorseNo, propertyType(继承自 PageSizeInfo:currentPage、pageSize)
参与过滤的只有:
comCode(前缀)、comSubCode(等值)、companyCode(等值)、acceptStartDate/acceptEndDate、policyNo、endorseNo、propertyType,外加登录人机构权限(按保单主表COMCODE前缀,总部01/00000000看全部)。
四、建表 SQL
4.1 影像件
影像件不需要建表。
产险影像件参照寿险实现,直接复用已有的imageupload表(该表已有policyno / filetype / imagename / imagepathsftp / createtime / updatetime / createby / updateby / imagelocation字段)。
原"团财影像件上传表DDL.sql"(pi_policy_image)方案已废弃,文件已从工程中删除,无需在生产执行。
4.2 承保/批改导入(本轮新增,需在生产执行)
真实导入模板比早期占位模板多了车辆信息、车主信息、企业授权业务人员、受益人信息、险种大类/小类等字段,且非车被保人清单需要独立落表。因此新增一份增量脚本:
团财承保批改_新导入表DDL_增量.sql(工程根目录),包含两段:
| 段落 | 内容 | 适用环境 |
|---|---|---|
| 1 | 新建 pi_policy_insured_stg(非车被保人清单暂存) |
所有环境 |
| 2 | pi_policy_car_stg / pi_policy_nocar_stg 增列:车辆 7 列、车主 4 列、企业经营/授权人 7 列、受益人 12 列、险种大类/小类 2 列 |
仅存量库;全新环境执行 团财承保批改_新导入表DDL.sql 即可(CREATE 已含这些列) |
| 3 | pi_endorse_car_stg / pi_endorse_nocar_stg 增列 6 列:risk_class、sum_insured、risk_premium_no_tax、start_date、end_date、pay_type(批改清单模板 15 列中有 6 列原表没有) |
仅存量库;全新环境执行 团财承保批改_新导入表DDL.sql 即可(CREATE 已含这些列) |
已有表
pi_policy_car_stg / pi_policy_nocar_stg / pi_endorse_car_stg / pi_endorse_nocar_stg / pi_import_batch / pi_import_error / pi_endorse_car_main / pi_endorse_nocar_main通过团财承保批改_新导入表DDL.sql建好,不重复创建。
4.3 批单独立表(2026-10-16 需求变更,需在生产执行)
团财批单表_BYXM-1891_20261016.sql(工程根目录,增量 DDL),三段:
| 段落 | 内容 | 说明 |
|---|---|---|
| 1 | 新建 pi_endorse_bill(25 列,UK uk_endorse_bill(policy_no, endorse_no, risk_code)) |
批改清单导入/补录的唯一落地表;审批通过后写入,批单查询/导出/详情全部读它 |
| 2 | pi_import_batch 增列 import_type |
区分 ENDORSE_IMPORT / ENDORSE_SUPPLEMENT |
| 3 | pi_endorse_car_stg / pi_endorse_nocar_stg 各增列 import_type、up_com_code、up_com_name |
任务详情页按保单号展示佰盈省级机构 |
重要:
pi_endorse_car_main/pi_endorse_nocar_main两张表自本轮起不再被批改导入写入
(导入只落pi_endorse_bill)。如生产上已有历史数据,需要单独评估迁移,代码里已解除依赖。
4.4 批次表 import_type 存量回填(可选,需在生产执行)
团财批次导入类型_存量回填_20261016.sql(工程根目录)。
- 背景:
pi_import_batch.import_type是为批改导入新增的列,改动前承保清单 / 被保人清单调用insertBatch时传的是null,导致存量批次该列全为 NULL —— 批次列表接口返回的importType因此为空(表现为"缺少 importType 字段")。代码侧已修(各类导入都写入明确枚举 +列表接口转中文 + 空值兜底),本脚本用于把历史批次补齐。 - 依据:直接用批次已有的
biz_type + insurance_scope判断,比按批次号前缀猜更可靠:POLICY+CAR→CAR_POLICY_IMPORT;POLICY+NOCAR→NOCAR_POLICY_IMPORT;ENDORSE→ENDORSE_IMPORT。 - 幂等:只更新
NULL/ 空串 / 旧枚举POLICY_IMPORT的行,已正确的枚举不会被覆盖,可重复执行。 - 不执行的后果:仅历史批次的
importType为空串,功能不受影响。 - 存量批次无法区分「导入 / 补录」:历史数据已无从还原(旧逻辑是导入时按行判定),统一按「导入」回填(车险 →
车险承保导入,非车 →非车承保导入)。
4.5 承保补录变更留痕表(2026-10-21 新增,需在生产执行)
团财补录留痕表_BYXM-1891_20261021.sql(工程根目录,CREATE TABLE IF NOT EXISTS,幂等)。
| 对象 | 说明 |
|---|---|
pi_policy_supplement_trace |
补录改值的字段级留痕:batch_no, row_no, policy_no, risk_code, field_name, old_value, new_value, change_type=OVERRIDE, import_type, operator_code, operator_name, created_time |
- 写入时机:补录批次(
*_POLICY_SUPPLEMENT)解析阶段,凡「历史行该字段有值 且 本次录入的值不同」写一条;纯补缺(历史为空、本次补上)不逐字段记录。 - 兜底行为:代码在写入前会先查
information_schema判断表是否存在;若生产还没执行本 DDL,则跳过留痕并打 warn 日志,不影响导入主流程。 - 为什么不 try-catch:事务内 SQL 报错后连接会被标记 rollback-only,捕获异常继续跑会在提交时抛
UnexpectedRollbackException,反而把整个导入废掉,所以必须「先探测再写」。 - 查询方式(无对外接口):Sql复制成功select * from pi_policy_supplement_trace where batch_no = 'PC20261021...' order by id;select * from pi_policy_supplement_trace where policy_no = '...' and risk_code = '...' order by id desc;
五、错误码表
| code | 含义 |
|---|---|
| 000000 | 成功 |
| 000001 | 业务异常(具体信息看 msg) |
| 000002 | 模板表头校验不通过(列数/字段名与系统模板不一致,msg 里带出具体列);importType 缺失/非法/与接口不符;未解析到有效数据行;或前端校验不通过 |
| 000003 | 文件解析失败(非 xlsx / 模板格式错) |
| 000004 | 数据回写失败(详见 msg;通常对应某条具体的 stg 行 id) |
| 000005 | 权限不足(非本公司数据) |
| 000099 | 系统异常 |
承保清单导入/补录(§2.1 / §2.2)常见 code 速查:
| 场景 | code | msg |
|---|---|---|
| 未选文件 | 000001 | 请选择导入文件 |
未传 importType |
000002 | importType 不能为空:车险请传 CAR_POLICY_IMPORT(承保导入)或 CAR_POLICY_SUPPLEMENT(承保补录);非车请传 … |
importType 取值非法 |
000002 | importType 取值非法,仅支持 CAR_POLICY_IMPORT / CAR_POLICY_SUPPLEMENT / NOCAR_POLICY_IMPORT / NOCAR_POLICY_SUPPLEMENT,当前传入[XXX] |
importType 与入口冲突 |
000002 | importType[NOCAR_POLICY_IMPORT]与当前导入入口不一致:importType 表明为非车,请勿混用 |
| 表头被改 | 000002 | 车险承保清单模板表头被修改,请重新下载系统模板:第 N 列应为「XXX」实际为「YYY」 |
| 无数据行 | 000002 | 未解析到有效数据行:请确认模板第 3 行起已填写数据后重新导入 |
| 补录保单号不存在 | 000000 + errorRows>0 | 第 N 行:保单号[XXX]在历史导入批次与保单主表中均不存在,请确认保单号是否正确,或改用「承保清单导入」 |
| 补录未录险种代码(多险种) | 000000 + errorRows>0 | 第 N 行:保单号[XXX]在历史批次中存在多个险种,请录入险种代码以定位本次补录的险种 |
| 导入缺必录 | 000000 + errorRows>0 | 第 N 行:保单号必录字段未录入 / 险种保费(含税)、险种保费(不含税)至少录入一项 |
行级错误不会让整个接口失败:
code仍是000000,错误行计入data.errorRows并写pi_import_error,
其余行照常落库。只有「整份文件不可用」(未选文件 / 表头被改 / 无数据行 / importType 有问题)才直接返回错误码。
批单模块(§2.4 / §2.14~2.16)常见 code 速查:
| 接口 | code | msg |
|---|---|---|
| 2.4 导入 | 000001 | 请选择导入文件 / 解析异常 |
| 2.4 导入 | 000002 | 表头校验不通过(第 N 列应为「XXX」)/ 未解析到有效数据行 |
| 2.4 导入 | 000000 + errorRows>0 | msg 带「第 N 行:保单号[XXX]在车险/非车保单主表中不存在,请先导入承保清单」等 |
| 2.14 查询 | 000003 | 查询条件不能为空 / 承保日期和保单号、批单号必录其一 / 无记录 |
| 2.15 详情 | 000003 | 保单号不能为空 / 未查询到批单详情 |
| 2.16 导出 | 000003 | 导出条件不能为空 / 承保日期和保单号、批单号必录其一 |
| 2.14~2.16 | 000001 | 系统查询异常!/ 系统导出数据异常 |
六、与前端的约定
所有 POST 请求的 body 字段命名沿用驼峰式(与 VO @Data 注解生成的一致)。
导出接口用 GET + queryString;前端如需复杂条件可以用 POST 后端再加。
任何 /upload 接口超时统一 30 秒,前端请用 upload progress 反馈用户。
审核回写是异步的还是同步的?
- 当前实现:审核接口(
/audit、/approve)在事务内同步完成 car_main / no_car_main 的回写;批量 200 行以内 < 5 秒,超过 200 行会返回000004并提示"请分批导入"。 - 后续如果需要异步版本再扩展。
- 当前实现:审核接口(
同一保单号再次导入 → 不会拒绝,按「本次录入值覆盖、本次为空则继承历史值」做字段级合并(合并键 = 保单号 + 险种代码)。只想补几个字段时请用补录模式(
*_POLICY_SUPPLEMENT)。受益人=指定受益人 时,导入校验要求"受益人姓名、证件、份额"三项;前端录入时也应该在校验层把这三项联动起来。
后端会复用
UserInfoUtil.getUserInfo()取 comCode / operatorCode;前端传过来的 comCode 仅作为展示用,不参与过滤(避免越权)。影像件模块(
/property_image_upload/*)与寿险影像件上传(/ImageUpload/*)是两套独立接口、同一张imageupload表,只是存储目录不同(propertyimage/vsimageUpload/)。前端请按产险这套接口对接,不要混用。影像件预览:直接用 2.18 返回的
imageURL打开即可(走oss.domain);如果浏览器需要强制下载,用 2.20 的下载接口。模板必须走下载接口拿(
?templateType=car|nocar|insured|endorse,templateType必填),不要用前端自己存的旧模板。后端会逐列校验表头,任何改名/删列/加列都会直接拒绝整份文件并返回000002,msg 里会说明第几列对不上。车险、非车是两套模板两套接口(73 列 vs 62 列),不能混用;识别方式就是下载时传的
templateType。非车上传页支持一个承保清单 + 多个被保人清单,一起
multipart提交(file+insuredFiles[]),后端合并到同一个batchNo,失败详情里会按文件名+行号定位。补录模式(NOCAR_POLICY_SUPPLEMENT)下insuredFiles会被忽略,被保人请走 §2.3 单独导入。证件有效止期允许填汉字“长期”,后端落
9999-12-31,前端回显时按这个约定处理。13.1 【2026-10-21 必须改】承保清单的三个上传接口新增必传表单字段importType:页面入口 接口 importType 车险承保清单导入 /import/car/uploadCAR_POLICY_IMPORT车险承保清单补录 /import/car/uploadCAR_POLICY_SUPPLEMENT非车承保清单导入 /import/nocar/uploadNOCAR_POLICY_IMPORT非车承保清单补录 /import/nocar/uploadNOCAR_POLICY_SUPPLEMENT兼容端点(不推荐) /import/policy/upload同上四个之一(可替代 insuranceScope)- 不传 →
code=000002,msg直接给出四个合法取值,不产生批次记录; - 传了与接口不匹配的值(如
NOCAR_*调/import/car/upload)→code=000002,提示「与当前导入入口不一致」; - 前端不需要再做「按保单号猜是不是补录」的判断,由页面入口决定 importType,批次列表的
importType会如实反映(车险承保补录/非车补录)。13.2 【2026-10-21】补录的交互提示建议: - 补录只要保单号必录,其余字段留空表示「保持原值」,填了就是「改值」;
- 返回
data.changedFields > 0时可提示「N 个字段已变更,可在留痕表核查」; - 补录时若同一保单有多个险种,需引导用户填险种代码,否则该行会报「保单号[XXX]在历史批次中存在多个险种,请录入险种代码以定位本次补录的险种」。
- 不传 →
批改清单导入(§2.4)模板不带“产险类型”列,前端不要自行加列,也不要让用户选车险/非车——后端按保单号自动判定并在返回的错误明细里说明原因。导入顺序上,需提示用户先导入对应承保清单并完成审批回写,否则批改行会因保单号不存在而失败。14.1 【2026-10-16 变更】批改导入不碰任何主表。 批改数据审批后只落
pi_endorse_bill,car_main/no_car_main的一行都不会改。页面上如果原来有“批改会更新保单”的提示请改掉。14.2 【2026-10-16 新增 / 2026-10-21 改必传】批改导入接口多一个importType表单字段。 页面两个入口共用同一个接口:「批改清单导入」传ENDORSE_IMPORT,「批单信息补录」传ENDORSE_SUPPLEMENT;2026-10-21 起该字段必传,不再有不传即默认的兜底(漏传返回000002并给出可读提示)。两者模板完全相同,差别只在必录项:导入是标红 6 列必录,补录只有批单号 + 险种代码必录。前端改动只有一处:两个上传方法里各fd.append('importType', ...)一行,页面/组件结构不用动。14.3 【2026-10-16 新增】批单查询的三个接口返回结构。- 查询(§2.14):
data是PageImpl,读data.content和data.totalElements(与保单查询一致,不是rows/total)。 - 详情(§2.15):
data是PolicyDataDetailVo,与保单详情同构,可复用保单详情页组件;批单数据在多出来的endorseBasicInfo/endorseRiskInfoList两段里。旧的PolicyEndorseDetailVo已删除,如果前端有引用请改成PolicyDataDetailVo的读法。 - 导出(§2.16):11 列,与查询结果一致,走整页跳转。14.4 批单列表的
propertyType返回中文「车险 / 非车」;comName已去掉公司前缀。acceptDate/generateDate是毫秒时间戳(全站未配 jackson 日期序列化),前端自行格式化。批单详情里的日期后端已格式化成yyyy-MM-dd,两种接口的日期类型不一致是既有现状,不要混用格式化逻辑。
- 查询(§2.14):
旧版前端 JS 里的产险调用已与后端不一致,请按下表更新(仓库
static/dist下打包产物仍含旧调用):旧前端调用 现状 应改为 GET /property_insurance/import/downloadTemplate(无参数)会报缺参数 带 `?templateType=car POST /property_insurance/import/policy/upload已加回兼容端点(见 §2.1.0) 建议改用 /import/car/upload或/import/nocar/upload;不改也能用,但强烈建议加 `insuranceScope=carGET /property_insurance/import/batch/auditHistory后端已实现(见 §2.6.1) 直接调,入参 batchNo,返回数组POST /property_insurance/import/batch/delete后端已实现(见 §2.6.2) 直接调,入参 {batchNo},逻辑删除POST /property_insurance/import/batch/audit保留 也可改用 /batch/approve、/batch/rejectPOST /property_insurance/import/endorse/upload正常 不变 POST /property_insurance/import/batch/list、/detail、/errors、/submit正常 不变 重要:产险导入页的「审核历史 / 删除 / 任务详情导出」三个按钮,前端 api 模块里目前是本地桩,没有发任何请求(
static/dist/icrm/js/67.*.js、69.*.js的Bdmw模块):JavaScript复制成功// 现状:直接 resolve 一个 000004,页面弹出"…接口暂未开放,需后端补充后启用"function h(){ return w.a.resolve({data:{code:"000004",msg:"批次删除接口暂未开放,需后端补充后启用"}}); } // t.a = 删除function v(){ return w.a.resolve({data:{code:"000004",msg:"审核历史接口暂未开放,需后端补充后启用"}}); } // t.d = 审核历史后端接口已经补齐,前端需要把这两处桩换成真实请求(导出按钮
exportTaskDetail同理):JavaScript复制成功// 删除:POST /property_insurance/import/batch/delete,body { batchNo }function h(e){ return o("/property_insurance/import/batch/delete","post",e); }// 审核历史:GET /property_insurance/import/batch/auditHistory?batchNo=xxxfunction v(e){ return Object(y.a)({url:"/property_insurance/import/batch/auditHistory",method:"get",params:{batchNo:e}}); }// 任务详情导出:GET /property_insurance/import/batch/detail/export?batchNo=xxx(必须走跳转,不能走 ajax)function k(e){ return "/tabycore/property_insurance/import/batch/detail/export?batchNo=" + encodeURIComponent(e); }三个方法的调用形态(页面里已确定,后端按此实现):
- 删除:
Object(g.a)({batchNo: row.batchNo}),成功后fetchList()刷新; - 审核历史:
Object(g.d)(row.batchNo),返回数组,逐行normalizeAuditHistoryRow; - 导出:
exportTaskDetail里改为window.location.href = <上面的 k(batchNo)>。
- 删除:
所有写库接口都在事务里执行(
uploadPolicy/uploadCarPolicy/uploadNoCarPolicy/uploadInsuredList/uploadEndorse/submitBatch/auditBatch/approveBatch/rejectBatch均有@Transactional)。stg 表与批次表的写入用的是EntityManager的 native queryexecuteUpdate(),Hibernate 强制要求事务,没有事务会直接抛TransactionRequiredException(全局异常处理器会把它吞成"处理异常,请联系管理员")。新增或修改写库方法时务必带上@Transactional,否则现象就是"接口返回 000001 但日志里是 TransactionRequiredException"。