13 KiB
征信维护设计文档
1. 背景
当前仓库已经具备两项征信解析基础能力:
ccdi-lsfx已提供POST /lsfx/credit/parse征信解析联调接口,可接收 HTML 并返回lx_header、lx_debt、lx_publictypelsfx-mock-server已支持从征信 HTML 中解析员工姓名和身份证号,能够稳定返回本地联调 payload
本次需求是在“信息维护”菜单下新增“征信维护”菜单,支持批量导入员工征信 HTML 文件并提交上传。系统需要调用现有征信解析接口完成数据解析,并把返回结果批量落库。页面同时要展示当前已维护的员工征信信息,并支持删除现有征信数据。
2. 已确认约束
- 菜单挂在“信息维护”下,页面为独立菜单,不挂到员工维护弹窗内
- 页面主列表按员工维度展示摘要,一行一个员工
- 批量上传按员工维度原子化处理,一个员工失败不影响其他员工
- 负债明细表名固定为
ccdi_debts_info - 负债信息按照
assets/征信解析/ccdi_debts_info.xlsx设计 - 负面信息按照接口字段单独设计一张表
- 每个员工只保留最新的征信信息
- 列表操作列支持删除现有征信信息
- 不新增征信主表,主列表通过明细表实时聚合
3. 目标
- 在“信息维护”下新增“征信维护”菜单与页面
- 支持一次上传多个
.html/.htm征信文件 - 上传后逐文件调用征信解析接口
- 按员工身份证号归户,并按“最新征信优先”规则覆盖写入
- 在页面展示员工维度的征信摘要列表
- 在详情中展示负债明细和负面信息
- 支持按员工删除当前已维护的征信数据
4. 非目标
- 不改造现有
POST /lsfx/credit/parse的协议语义 - 不新增异步任务、轮询状态页或上传历史模块
- 不保存多版本征信记录
- 不保存原始 HTML 文件或原始 payload JSON
- 不增加说明书之外的补丁性兜底方案
5. 方案对比
5.1 方案 A:三张业务表,增加征信主表
新增征信主表保存员工最新摘要,再配合负债表和负面信息表。
优点:
- 列表查询简单
- 聚合逻辑更少
缺点:
- 引入额外主表,超出本次最短路径
- 同一份摘要数据会与明细形成重复维护
5.2 方案 B:仅保留两张业务表,列表实时聚合
只建设 ccdi_debts_info 与负面信息表,主列表按员工维度实时聚合展示。
优点:
- 满足“负债表固定命名”和“负面信息单独建表”
- 不引入额外主表,路径最短
- 删除和覆盖逻辑仍然清晰,按员工清空两张表即可
缺点:
- 列表查询需要做员工维度聚合
5.3 方案 C:两张业务表加原始 payload 存档
在方案 B 基础上额外保存原始 payload 或原始 HTML。
优点:
- 排查解析问题时信息更全
缺点:
- 增加冗余与维护成本
- 超出当前需求
6. 最终方案
采用方案 B:仅新增 ccdi_debts_info 和 ccdi_credit_negative_info 两张业务表,列表按员工维度实时聚合,不新增征信主表。
选择原因:
- 满足“每个员工只保留最新征信信息”的要求
- 满足“负债信息按 Excel 设计、负面信息单独建表”的要求
- 不额外增加主表,保持最短路径实现
- 删除逻辑直接按员工清理两张业务表,语义明确
7. 总体架构
业务链路如下:
征信维护页面 -> 征信维护业务接口 -> 征信维护服务 -> /lsfx/credit/parse -> 征信解析服务
职责拆分如下:
-
征信维护页面
- 选择多个 HTML 文件并提交上传
- 展示员工维度征信摘要列表
- 打开详情弹窗查看负债明细与负面信息
- 删除员工当前征信数据
-
征信维护业务接口
- 对外提供上传、列表、详情、删除接口
- 不直接把前端耦合到
ccdi-lsfx
-
征信维护服务
- 逐文件调用征信解析接口
- 根据员工身份证号归户
- 校验“是否为最新征信”
- 单员工事务覆盖写入两张业务表
-
ccdi-lsfx- 保持现有征信解析客户端能力
- 继续作为外部征信解析接入边界
8. 数据模型设计
8.1 负债明细表 ccdi_debts_info
一条记录表示一条负债明细,字段按 assets/征信解析/ccdi_debts_info.xlsx 设计:
debt_id:BIGINT主键,自增person_id:VARCHAR(18),员工身份证号person_name:VARCHAR(100),员工姓名query_date:DATE,征信查询日期debt_main_type:VARCHAR(50),负债大类debt_sub_type:VARCHAR(50),负债小类creditor_type:VARCHAR(50),债权人类型debt_name:VARCHAR(100),负债名称principal_balance:DECIMAL(18,2),负债本金余额debt_total_amount:DECIMAL(18,2),负债总额debt_status:VARCHAR(20),负债状态create_by:VARCHAR(64)create_time:DATETIMEupdate_by:VARCHAR(64)update_time:DATETIME
建议索引:
idx_person_id(person_id)idx_query_date(query_date)idx_person_query_date(person_id, query_date)
8.2 负面信息表 ccdi_credit_negative_info
一条记录表示一个员工当前最新征信对应的负面信息汇总:
negative_id:BIGINT主键,自增person_id:VARCHAR(18),员工身份证号person_name:VARCHAR(100),员工姓名query_date:DATE,征信查询日期civil_cnt:INT,民事案件笔数enforce_cnt:INT,强制执行笔数adm_cnt:INT,行政处罚笔数civil_lmt:DECIMAL(18,2),民事案件金额enforce_lmt:DECIMAL(18,2),强制执行金额adm_lmt:DECIMAL(18,2),行政处罚金额create_by:VARCHAR(64)create_time:DATETIMEupdate_by:VARCHAR(64)update_time:DATETIME
建议索引:
uk_person_id(person_id)唯一索引
9. 解析字段映射设计
9.1 归户字段
从解析结果 lx_header 中读取:
query_cert_no-> 员工身份证号person_idquery_cust_name-> 员工姓名person_namereport_time-> 征信查询日期query_date
query_cert_no 作为员工唯一归户标识,并校验该身份证号必须存在于 ccdi_base_staff。
9.2 lx_debt 到 ccdi_debts_info 的映射
lx_debt 当前为 7 组固定字段,每组映射成一条负债明细:
| 接口前缀 | 负债大类 | 负债小类 | 债权人类型 | 负债名称 |
|---|---|---|---|---|
uncle_bank_house |
银行 | 住房贷款 | 银行 | 未结清银行住房贷款 |
uncle_bank_car |
银行 | 汽车贷款 | 银行 | 未结清银行汽车贷款 |
uncle_bank_manage |
银行 | 经营贷款 | 银行 | 未结清银行经营贷款 |
uncle_bank_consume |
银行 | 消费贷款 | 银行 | 未结清银行消费贷款 |
uncle_bank_other |
银行 | 其他贷款 | 银行 | 未结清银行其他贷款 |
uncle_not_bank |
非银 | 非银行贷款 | 非银 | 未结清非银行贷款 |
uncle_credit_cart |
银行 | 信用卡 | 银行 | 未结清信用卡 |
字段映射规则:
*_bal->principal_balance*_lmt->debt_total_amount*_state->debt_status
落库过滤规则:
- 当某组
principal_balance、debt_total_amount都为空或0,且debt_status为空时,不生成明细记录 - 其余情况生成一条明细
9.3 lx_publictype 到 ccdi_credit_negative_info 的映射
按接口字段直接映射:
civil_cnt->civil_cntenforce_cnt->enforce_cntadm_cnt->adm_cntcivil_lmt->civil_lmtenforce_lmt->enforce_lmtadm_lmt->adm_lmt
10. 最新征信判定与覆盖策略
系统只保留员工最新征信,规则如下:
- 以
person_id作为员工唯一标识 - 以
query_date作为征信最新时间判定字段 - 员工上传新文件时:
- 若库中无现有征信数据,直接写入
- 若新
query_date大于等于现有query_date,覆盖旧数据 - 若新
query_date小于现有query_date,该员工本次文件判定为失败,不覆盖
单员工覆盖写入步骤:
- 删除
ccdi_debts_info中该员工旧记录 - 删除
ccdi_credit_negative_info中该员工旧记录 - 插入本次解析后的最新负债明细
- 插入本次解析后的最新负面信息
以上 4 步置于同一事务中,保证员工维度原子化。
11. 页面设计
11.1 菜单
在“信息维护”下新增菜单:
- 菜单名称:
征信维护 - 路由:
creditInfo - 组件:
ccdiCreditInfo/index - 权限前缀:
ccdi:creditInfo:*
11.2 顶部操作区
- 批量上传征信 HTML 按钮
- 查询条件:
- 员工姓名
- 柜员号
- 身份证号
- 是否已维护征信
上传弹窗要求:
- 仅允许选择
.html/.htm - 支持一次选择多个文件
- 提交后调用业务上传接口
- 接口返回后直接展示成功/失败汇总及失败清单
11.3 主列表
主列表按员工一行展示,字段建议:
- 员工姓名
- 柜员号
- 身份证号
- 所属部门
- 最近征信查询日期
- 负债笔数
- 负债总额
- 民事案件笔数
- 强制执行笔数
- 行政处罚笔数
- 操作
聚合规则:
- 基础信息来自
ccdi_base_staff - 最近征信查询日期、负债笔数、负债总额来自
ccdi_debts_info - 三类负面计数来自
ccdi_credit_negative_info - 任一业务表存在数据,即视为“已维护征信”
11.4 详情弹窗
详情弹窗分为两部分:
-
摘要区域
- 员工姓名
- 身份证号
- 征信查询日期
- 负债总额
- 负债笔数
- 民事案件笔数
- 强制执行笔数
- 行政处罚笔数
-
明细区域
- 负债信息表格
- 负面信息汇总卡片
负债表格字段:
- 负债大类
- 负债小类
- 债权人类型
- 负债名称
- 负债本金余额
- 负债总额
- 负债状态
负面信息展示字段:
- 民事案件笔数 / 金额
- 强制执行笔数 / 金额
- 行政处罚笔数 / 金额
11.5 删除交互
列表点击删除时,提示:
确认删除该员工当前已维护的征信信息吗?
确认后删除该员工在两张业务表中的全部数据。
12. 接口设计
新增业务接口,前端不直接调用 /lsfx/credit/parse:
12.1 批量上传
- 方法:
POST - 路径:
/ccdi/creditInfo/upload - 入参:多个 HTML 文件
- 返回:
- 总文件数
- 成功数
- 失败数
- 失败明细列表
失败明细建议字段:
fileNamepersonIdpersonNamereason
12.2 列表分页查询
- 方法:
GET - 路径:
/ccdi/creditInfo/list - 功能:分页查询员工征信摘要列表
12.3 详情查询
- 方法:
GET - 路径:
/ccdi/creditInfo/{personId} - 功能:查询员工征信摘要、负债明细和负面信息
12.4 删除
- 方法:
DELETE - 路径:
/ccdi/creditInfo/{personId} - 功能:删除员工当前征信数据
13. 后端设计
建议改动集中在 ccdi-info-collection 模块,新增独立征信维护资源。
建议新增:
controller/CcdiCreditInfoController.javaservice/ICcdiCreditInfoService.javaservice/impl/CcdiCreditInfoServiceImpl.javadomain/CcdiCreditNegativeInfo.javadomain/dto/CreditInfoUploadResultDTO.javadomain/vo/CreditInfoListVO.javadomain/vo/CreditInfoDetailVO.javamapper/CcdiCreditNegativeInfoMapper.javamapper/CcdiCreditInfoQueryMapper.javaresources/mapper/...
职责说明:
-
CcdiCreditInfoController- 暴露上传、列表、详情、删除接口
-
CcdiCreditInfoService- 协调解析、归户、最新记录校验、覆盖写入
-
CcdiCreditNegativeInfoMapper- 维护负面信息表增删查
-
CcdiCreditInfoQueryMapper- 承担员工维度列表聚合查询和详情聚合查询
14. 异常处理
上传过程中逐文件处理,失败不影响其他员工成功:
- 文件后缀非法:失败原因为“文件格式不支持”
- 解析接口调用失败:失败原因为“征信解析失败”
- 解析成功但身份证号为空:失败原因为“未解析到员工身份证号”
- 身份证号未匹配到员工:失败原因为“未匹配到员工信息”
- 上传征信日期早于当前最新记录:失败原因为“上传征信日期早于当前已维护最新记录”
- 员工覆盖写入事务失败:失败原因为“征信数据保存失败”
删除接口按幂等处理:
- 即使员工当前无征信数据,也返回删除成功
15. 测试方案
15.1 后端测试
-
上传服务测试
- 单文件解析成功后正确写入两张业务表
- 同员工新日期文件覆盖旧数据
- 同员工旧日期文件被拒绝覆盖
- 一个员工失败不影响其他员工成功
- 删除后两张表数据均被清空
-
聚合查询测试
- 只有负债信息
- 只有负面信息
- 两者都有
- 两者都没有
- 分页下聚合字段正确
-
控制器测试
- 批量上传成功
- 混合成功/失败上传
- 详情查询成功/无数据
- 删除接口幂等
15.2 前端验证
- 上传多个 HTML 文件并查看结果提示
- 列表按员工维度展示聚合摘要
- 详情弹窗正确显示负债表和负面信息
- 删除后该员工征信摘要即时消失
- 前端生产构建通过
16. 文档与脚本产出要求
本次实施阶段需同步补充:
- 后端实施计划:
docs/plans/backend/ - 前端实施计划:
docs/plans/frontend/ - SQL 脚本:
sql/或sql/migration/ - 实施记录:
docs/reports/implementation/
文档落点需遵循仓库目录规范,避免写入错误目录。