16 KiB
员工资产导入与实体库自动补入修复设计
1. 背景
本设计用于修复以下后端问题:
- 【员工信息维护】双 Sheet 导入时,
员工资产信息Sheet 只能通过数据库已有员工反查归属,不能识别同一个导入文件中刚成功导入的员工。 - 【员工亲属关系维护】双 Sheet 导入时,
亲属资产信息Sheet 只能通过数据库已有亲属关系反查归属,不能识别同一个导入文件中刚成功导入的亲属关系。 - 关联业务自动补入实体库能力在当前主工作区未完整接回,员工亲属、信贷客户、中介、供应商四类业务成功关联后,缺失企业需要统一补入
ccdi_enterprise_base_info。
本次设计只涉及后端。不调整前端页面结构、上传入口、模板样式和前端轮询字段。
2. 目标
- 双 Sheet 导入时,主 Sheet 与资产 Sheet 在后端按业务依赖顺序执行。
- 资产 Sheet 可关联数据库已有主数据,也可关联同一文件中本轮主 Sheet 成功导入的数据。
- 主 Sheet 失败行不能作为资产归属依据。
- 继续返回当前前端已支持的两个任务 ID:
- 员工信息维护:
staffTaskId、assetTaskId - 员工亲属关系维护:
relationTaskId、assetTaskId
- 员工信息维护:
- 恢复统一
EnterpriseAutoFillService,并接入员工亲属、信贷客户、中介、供应商四类业务。 - 实体库自动补入只插入缺失企业,不更新已存在实体。
3. 不在本次范围
- 不改前端上传入口、轮询逻辑、失败记录展示和模板下载样式。
- 不合并双 Sheet 导入任务 ID。
- 不改变员工、亲属关系、资产、实体关联现有字段校验规则。
- 不改变实体库手工新增、编辑、导入的既有业务规则。
- 不增加兜底来源、降级来源或兼容性分支。
4. 总体架构
本次后端设计分为两条链路。
4.1 双 Sheet 导入编排
/ccdi/baseStaff/importData 和 /ccdi/staffFmyRelation/importData 保持原接口、原模板、原返回字段。
Controller 继续负责读取两个 Sheet,但不再分别提交两个彼此独立的异步任务。服务层新增提交编排方法:
- 员工信息维护提交方法接收
List<CcdiBaseStaffExcel>和List<CcdiBaseStaffAssetInfoExcel>。 - 员工亲属关系维护提交方法接收
List<CcdiStaffFmyRelationExcel>和List<CcdiAssetInfoExcel>。
提交方法按实际存在的 Sheet 初始化对应任务状态,并启动一个后台编排任务。编排任务内部按顺序执行:
- 主 Sheet 校验与插入。
- 收集本轮主 Sheet 成功上下文。
- 资产 Sheet 校验与插入。
4.2 实体库自动补入
新增或恢复统一内部服务:
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/support/EnterpriseAutoFillService.java
该服务是关联业务补入实体库的唯一后端入口。四类业务在业务校验通过、业务记录落库前调用:
- 员工亲属实体关联:
EMP_RELATION - 信贷客户实体关联:
CREDIT_CUSTOMER - 中介实体关联:
INTERMEDIARY - 招投标供应商:
SUPPLIER
实体库缺失时最小插入;已存在时不更新。
供应商来源需要同步新增后端枚举 EnterpriseSource.SUPPLIER("SUPPLIER", "供应商"),并补充 /ccdi/enum/enterpriseSource 枚举接口测试。前端继续通过现有枚举接口展示来源,不需要调整页面结构。
5. 员工信息维护双 Sheet 导入设计
5.1 当前问题
当前 /ccdi/baseStaff/importData 分别读取 员工信息 和 员工资产信息,然后分别调用:
baseStaffService.importBaseStaff(staffList)baseStaffAssetImportService.importAssetInfo(assetList)
两个任务互相独立。员工资产导入只通过数据库 ccdi_base_staff.id_card 查找归属,无法稳定看到同一文件中刚导入成功的员工。
5.2 设计方案
新增员工信息维护双 Sheet 后端编排能力。
提交阶段:
- Controller 读取两个 Sheet。
- 若两个 Sheet 都无数据,仍返回“至少需要一条数据”。
- 若存在员工 Sheet,生成并初始化
staffTaskId。 - 若存在员工资产 Sheet,生成并初始化
assetTaskId。 - 返回当前前端兼容的
BaseStaffImportSubmitResultVO。 - 后台启动一个编排任务。
编排阶段:
- 先执行员工主数据导入。
- 沿用现有员工必填、身份证号、部门、员工 ID、身份证号重复校验。
- 批量插入员工成功记录。
- 收集本轮成功员工的
idCard。 - 更新员工任务状态和失败记录。
- 再执行员工资产导入。
- 员工资产归属候选来源为:
- 数据库已有
ccdi_base_staff.id_card - 本轮员工 Sheet 成功导入的
idCard
- 数据库已有
- 员工资产落库继续保持:
family_id = 员工身份证号person_id = 员工身份证号
- 员工资产继续保持重复校验:
personId + assetMainType + assetSubType + assetName。
5.3 任务状态
- 只填员工 Sheet:只返回
staffTaskId。 - 只填员工资产 Sheet:只返回
assetTaskId,只按数据库已有员工校验。 - 只填员工资产 Sheet 是正常导入场景,不因
员工信息Sheet 为空或未填写而拦截。 - 两个 Sheet 都填:返回
staffTaskId和assetTaskId,后台保证员工先处理、资产后处理。 - 员工主 Sheet 部分成功时,员工资产只能使用成功员工上下文。
- 员工主 Sheet 全部失败时,员工资产仍执行,但只能命中数据库已有员工。
6. 员工亲属关系维护双 Sheet 导入设计
6.1 当前问题
当前 /ccdi/staffFmyRelation/importData 分别读取 员工亲属关系信息 和 亲属资产信息,然后分别调用:
relationService.importRelation(relationList)assetInfoImportService.importAssetInfo(assetList)
两个任务互相独立。亲属资产导入只通过数据库 ccdi_staff_fmy_relation.relation_cert_no 查找归属,无法稳定看到同一文件中刚导入成功的亲属关系。
6.2 设计方案
新增员工亲属关系维护双 Sheet 后端编排能力。
提交阶段:
- Controller 读取两个 Sheet。
- 若两个 Sheet 都无数据,仍返回“至少需要一条数据”。
- 若存在亲属关系 Sheet,生成并初始化
relationTaskId。 - 若存在亲属资产 Sheet,生成并初始化
assetTaskId。 - 返回当前前端兼容的
StaffFmyRelationImportSubmitResultVO。 - 后台启动一个编排任务。
编排阶段:
- 先执行亲属关系导入。
- 沿用现有亲属关系必填、员工身份证号存在性、关系人证件号、重复组合校验。
- 批量插入亲属关系成功记录。
- 收集本轮成功亲属关系映射:
relationCertNo作为资产 Sheet 的personIdpersonId作为资产落库的familyId
- 更新亲属关系任务状态和失败记录。
- 再执行亲属资产导入。
- 亲属资产归属候选来源为:
- 数据库已有员工亲属关系,沿用现有 owner 查询条件
- 本轮亲属关系 Sheet 成功导入的员工亲属关系
- 亲属资产落库继续保持:
family_id = 员工身份证号person_id = 亲属身份证号
6.3 任务状态
- 只填亲属关系 Sheet:只返回
relationTaskId。 - 只填亲属资产 Sheet:只返回
assetTaskId,只按数据库已有员工亲属关系校验,并沿用现有 owner 查询条件。 - 只填亲属资产 Sheet 是正常导入场景,不因
员工亲属关系信息Sheet 为空或未填写而拦截。 - 两个 Sheet 都填:返回
relationTaskId和assetTaskId,后台保证亲属关系先处理、资产后处理。 - 亲属关系主 Sheet 部分成功时,亲属资产只能使用成功亲属关系上下文。
- 亲属关系主 Sheet 全部失败时,亲属资产仍执行,但只能命中数据库已有员工亲属关系。
7. 实体库自动补入设计
7.1 服务职责
EnterpriseAutoFillService 只负责一件事:对关联业务成功记录中的企业,确保实体库存在对应统一社会信用代码。
服务接口:
ensureExists(EnterpriseFillItem item)ensureExistsBatch(List<EnterpriseFillItem> items)
EnterpriseFillItem 字段:
socialCreditCodeenterpriseNameentSourcedataSourceuserName
7.2 插入规则
- 按
socialCreditCode去重,同批次同一统一社会信用代码只处理一次。 - 批量查询
ccdi_enterprise_base_info已存在记录。 - 已存在实体不更新。
- 缺失实体最小插入:
social_credit_code = 统一社会信用代码enterprise_name = 企业名称;中介实体关联缺失实体时允许为 NULLent_source = 来源data_source = MANUAL 或 IMPORTrisk_level = 来源规则值created_by/updated_by = 当前用户
- 中介实体关联缺失实体时不要求提供机构名称,补入实体的
enterprise_name可以为NULL。 - 中介来源
INTERMEDIARY写risk_level = 1。 - 员工亲属、信贷客户、供应商来源写
risk_level = NULL。 - 并发导致主键重复时,按“已存在实体”处理。
- 其他数据库异常抛出,让当前业务事务失败。
7.3 四类业务接入点
员工亲属实体关联:
- 手工新增:校验有效亲属和组合不重复后、插入关联表前补入。
- 导入:只对校验成功并即将插入的记录批量补入。
- 来源:
EMP_RELATION - 数据来源:手工新增为
MANUAL,导入为IMPORT - 风险等级:
NULL
信贷客户实体关联:
- 手工新增:校验通过后、插入关联表前补入。
- 导入:只对校验成功并即将插入的记录批量补入。
- 来源:
CREDIT_CUSTOMER - 数据来源:手工新增为
MANUAL,导入为IMPORT - 风险等级:
NULL
中介实体关联:
- 手工新增:字段校验和重复关系校验通过后,取消或替换“实体库必须已存在”校验,先补入实体库,再插入关联关系。
- 导入:字段校验和重复关系校验通过后,取消或替换“实体库必须已存在”失败条件,只对即将插入的成功记录批量补入。
- 来源:
INTERMEDIARY - 数据来源:手工新增为
MANUAL,导入为IMPORT - 风险等级:
1
招投标供应商:
- 手工新增或保存招投标主信息时,只对
supplierUscc非空且通过现有格式校验的供应商补入。 - 导入:只对成功采购事项中
supplierUscc非空且通过现有格式校验的供应商批量补入,失败采购事项不补入。 - 导入中
supplierUscc为空的供应商保持现有保存规则,但不补入实体库。 - 来源:
SUPPLIER - 数据来源:手工新增为
MANUAL,导入为IMPORT - 风险等级:
NULL
8. 错误处理与边界
8.1 双 Sheet 导入边界
- 主 Sheet 失败行不能进入资产归属候选。
- 主 Sheet 文件内重复行不能进入资产归属候选。
- 主 Sheet 数据库重复行不能进入资产归属候选。
- 主 Sheet 为空但资产 Sheet 有数据时,资产 Sheet 必须按现有独立资产导入规则正常执行。
- 资产 Sheet 仍按自身失败记录任务记录
sheetName、rowNum、errorMessage。 - 员工资产找不到员工时继续报“员工资产导入仅支持员工本人证件号”。
- 亲属资产找不到归属时继续报“未找到亲属资产归属员工”。
- 亲属资产命中多个归属时继续报“亲属资产归属员工不唯一”。
- 亲属资产数据库归属查询条件沿用当前实现,不因本次编排新增额外状态过滤。
8.2 自动补入边界
- 只处理业务校验成功、即将落库的记录。
- 失败业务行不能产生实体库记录。
- 已存在实体不更新,避免覆盖人工维护数据。
- 不增加默认企业名称、默认来源、默认风险等级等兜底逻辑。
- 不改变实体库导入的严格新增规则。
- 中介实体关联的“实体库必须已存在”校验需要被自动补入替换,否则缺失实体无法进入补入链路。
- 中介实体关联不新增机构名称入参;缺失实体补入时允许
enterprise_name = NULL。 - 供应商自动补入只处理非空统一社会信用代码,空统一社会信用代码不改变原导入保存规则。
9. 测试设计
9.1 单元测试
员工信息维护双 Sheet:
- 同一模板中新员工和员工资产同时导入,资产引用新员工身份证号,资产成功。
- 员工 Sheet 行校验失败,资产引用该身份证号且数据库不存在,资产失败。
- 员工信息 Sheet 为空或未填写,员工资产 Sheet 引用数据库已有员工时,资产成功导入。
- 只导员工资产,数据库已有员工时成功。
- 只导员工资产,数据库无员工时失败。
- 资产重复命中数据库或当前文件重复时失败。
员工亲属关系维护双 Sheet:
- 同一模板中新亲属关系和亲属资产同时导入,资产引用新亲属证件号,资产成功。
- 亲属关系 Sheet 行校验失败,资产引用该亲属证件号且数据库不存在,资产失败。
- 员工亲属关系信息 Sheet 为空或未填写,亲属资产 Sheet 引用数据库已有员工亲属关系时,资产成功导入。
- 只导亲属资产,数据库已有唯一员工亲属关系时成功。
- 只导亲属资产,数据库不存在亲属关系时失败。
- 同一亲属证件号命中多个员工归属时失败。
实体库自动补入:
- 已存在实体不插入、不更新。
- 缺失实体插入最小记录。
- 同批多个成功行引用同一统一社会信用代码,只补入一次。
- 中介来源写
riskLevel=1。 - 员工亲属、信贷客户、供应商来源写
riskLevel=null。 - 后端枚举接口返回
SUPPLIER/供应商。 - 并发重复主键按已存在处理。
四类业务接入:
- 手工新增成功时调用自动补入。
- 导入成功行进入自动补入集合。
- 导入失败行不进入自动补入集合。
9.2 接口验证
- 下载真实
/ccdi/baseStaff/importTemplate模板,构造员工信息+员工资产信息同文件导入,上传/ccdi/baseStaff/importData,轮询两个任务并查询员工、资产落库。 - 下载真实
/ccdi/staffFmyRelation/importTemplate模板,构造员工亲属关系信息+亲属资产信息同文件导入,上传/ccdi/staffFmyRelation/importData,轮询两个任务并查询亲属关系、资产落库。 - 分别调用员工亲属、信贷客户、中介、供应商新增或导入接口,验证实体库自动补入来源、数据来源和风险等级。
- 涉及中文清理 SQL 或验证 SQL 时使用
bin/mysql_utf8_exec.sh。
9.3 页面验证
完成后必须进入真实业务页面验证,不打开 prototype:
- 【员工信息维护】下载模板,填写员工和员工资产,上传后检查任务状态、失败记录、列表和详情资产。
- 【员工亲属关系维护】下载模板,填写亲属关系和亲属资产,上传后检查任务状态、失败记录、详情资产。
- 四类实体自动补入完成后,进入【实体库管理】按统一社会信用代码查询。
- 测试结束后清理本轮新增员工、亲属关系、资产、实体关联和自动补入实体库数据。
- 测试结束后关闭测试过程中启动的前后端进程。
10. 实施顺序
- 提炼员工主数据导入执行方法,返回成功员工上下文和失败记录。
- 提炼员工资产导入执行方法,支持额外员工归属上下文。
- 新增员工信息维护双 Sheet 编排方法并接入 Controller。
- 提炼亲属关系导入执行方法,返回成功亲属关系上下文和失败记录。
- 提炼亲属资产导入执行方法,支持额外亲属关系归属上下文。
- 新增员工亲属关系维护双 Sheet 编排方法并接入 Controller。
- 恢复或新增
EnterpriseAutoFillService。 - 接入员工亲属、信贷客户、中介、供应商四类自动补入。
- 补充单元测试。
- 执行接口验证和真实页面验证。
- 新增实施记录到
docs/reports/implementation/。
11. 风险与控制
- 不能继续由 Controller 分别提交两个独立异步任务,否则资产任务执行顺序仍不确定。
- 不能把主 Sheet 失败行放入资产归属上下文,否则会产生脏资产。
- 不能更新已存在实体库记录,否则会覆盖人工维护的企业名称、风险等级和来源。
- 自动补入必须在业务记录落库前执行,并与业务事务保持一致。
- 四类自动补入必须只处理成功业务行,失败行不能污染实体库。