From 104e8697fe21359cc1bd4db2785bea6a7232f308 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Wed, 6 May 2026 17:18:21 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AE=BE=E8=AE=A1:=20=E5=91=98=E5=B7=A5?= =?UTF-8?q?=E8=B5=84=E4=BA=A7=E5=AF=BC=E5=85=A5=E4=B8=8E=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E5=BA=93=E8=87=AA=E5=8A=A8=E8=A1=A5=E5=85=A5=E4=BF=AE=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...port-and-enterprise-autofill-fix-design.md | 325 ++++++++++++++++++ 1 file changed, 325 insertions(+) create mode 100644 docs/design/2026-05-06-staff-asset-import-and-enterprise-autofill-fix-design.md diff --git a/docs/design/2026-05-06-staff-asset-import-and-enterprise-autofill-fix-design.md b/docs/design/2026-05-06-staff-asset-import-and-enterprise-autofill-fix-design.md new file mode 100644 index 00000000..f95f3d2a --- /dev/null +++ b/docs/design/2026-05-06-staff-asset-import-and-enterprise-autofill-fix-design.md @@ -0,0 +1,325 @@ +# 员工资产导入与实体库自动补入修复设计 + +## 1. 背景 + +本设计用于修复以下后端问题: + +1. 【员工信息维护】双 Sheet 导入时,`员工资产信息` Sheet 只能通过数据库已有员工反查归属,不能识别同一个导入文件中刚成功导入的员工。 +2. 【员工亲属关系维护】双 Sheet 导入时,`亲属资产信息` Sheet 只能通过数据库已有亲属关系反查归属,不能识别同一个导入文件中刚成功导入的亲属关系。 +3. 关联业务自动补入实体库能力在当前主工作区未完整接回,员工亲属、信贷客户、中介、供应商四类业务成功关联后,缺失企业需要统一补入 `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` 和 `List`。 +- 员工亲属关系维护提交方法接收 `List` 和 `List`。 + +提交方法按实际存在的 Sheet 初始化对应任务状态,并启动一个后台编排任务。编排任务内部按顺序执行: + +1. 主 Sheet 校验与插入。 +2. 收集本轮主 Sheet 成功上下文。 +3. 资产 Sheet 校验与插入。 + +### 4.2 实体库自动补入 + +新增或恢复统一内部服务: + +`ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/support/EnterpriseAutoFillService.java` + +该服务是关联业务补入实体库的唯一后端入口。四类业务在业务校验通过、业务记录落库前调用: + +- 员工亲属实体关联:`EMP_RELATION` +- 信贷客户实体关联:`CREDIT_CUSTOMER` +- 中介实体关联:`INTERMEDIARY` +- 招投标供应商:`SUPPLIER` + +实体库缺失时最小插入;已存在时不更新。 + +## 5. 员工信息维护双 Sheet 导入设计 + +### 5.1 当前问题 + +当前 `/ccdi/baseStaff/importData` 分别读取 `员工信息` 和 `员工资产信息`,然后分别调用: + +- `baseStaffService.importBaseStaff(staffList)` +- `baseStaffAssetImportService.importAssetInfo(assetList)` + +两个任务互相独立。员工资产导入只通过数据库 `ccdi_base_staff.id_card` 查找归属,无法稳定看到同一文件中刚导入成功的员工。 + +### 5.2 设计方案 + +新增员工信息维护双 Sheet 后端编排能力。 + +提交阶段: + +1. Controller 读取两个 Sheet。 +2. 若两个 Sheet 都无数据,仍返回“至少需要一条数据”。 +3. 若存在员工 Sheet,生成并初始化 `staffTaskId`。 +4. 若存在员工资产 Sheet,生成并初始化 `assetTaskId`。 +5. 返回当前前端兼容的 `BaseStaffImportSubmitResultVO`。 +6. 后台启动一个编排任务。 + +编排阶段: + +1. 先执行员工主数据导入。 +2. 沿用现有员工必填、身份证号、部门、员工 ID、身份证号重复校验。 +3. 批量插入员工成功记录。 +4. 收集本轮成功员工的 `idCard`。 +5. 更新员工任务状态和失败记录。 +6. 再执行员工资产导入。 +7. 员工资产归属候选来源为: + - 数据库已有 `ccdi_base_staff.id_card` + - 本轮员工 Sheet 成功导入的 `idCard` +8. 员工资产落库继续保持: + - `family_id = 员工身份证号` + - `person_id = 员工身份证号` +9. 员工资产继续保持重复校验:`personId + assetMainType + assetSubType + assetName`。 + +### 5.3 任务状态 + +- 只填员工 Sheet:只返回 `staffTaskId`。 +- 只填员工资产 Sheet:只返回 `assetTaskId`,只按数据库已有员工校验。 +- 两个 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 后端编排能力。 + +提交阶段: + +1. Controller 读取两个 Sheet。 +2. 若两个 Sheet 都无数据,仍返回“至少需要一条数据”。 +3. 若存在亲属关系 Sheet,生成并初始化 `relationTaskId`。 +4. 若存在亲属资产 Sheet,生成并初始化 `assetTaskId`。 +5. 返回当前前端兼容的 `StaffFmyRelationImportSubmitResultVO`。 +6. 后台启动一个编排任务。 + +编排阶段: + +1. 先执行亲属关系导入。 +2. 沿用现有亲属关系必填、员工身份证号存在性、关系人证件号、重复组合校验。 +3. 批量插入亲属关系成功记录。 +4. 收集本轮成功亲属关系映射: + - `relationCertNo` 作为资产 Sheet 的 `personId` + - `personId` 作为资产落库的 `familyId` +5. 更新亲属关系任务状态和失败记录。 +6. 再执行亲属资产导入。 +7. 亲属资产归属候选来源为: + - 数据库已有有效员工亲属关系 + - 本轮亲属关系 Sheet 成功导入的有效员工亲属关系 +8. 亲属资产落库继续保持: + - `family_id = 员工身份证号` + - `person_id = 亲属身份证号` + +### 6.3 任务状态 + +- 只填亲属关系 Sheet:只返回 `relationTaskId`。 +- 只填亲属资产 Sheet:只返回 `assetTaskId`,只按数据库已有有效亲属关系校验。 +- 两个 Sheet 都填:返回 `relationTaskId` 和 `assetTaskId`,后台保证亲属关系先处理、资产后处理。 +- 亲属关系主 Sheet 部分成功时,亲属资产只能使用成功亲属关系上下文。 +- 亲属关系主 Sheet 全部失败时,亲属资产仍执行,但只能命中数据库已有有效亲属关系。 + +## 7. 实体库自动补入设计 + +### 7.1 服务职责 + +`EnterpriseAutoFillService` 只负责一件事:对关联业务成功记录中的企业,确保实体库存在对应统一社会信用代码。 + +服务接口: + +- `ensureExists(EnterpriseFillItem item)` +- `ensureExistsBatch(List items)` + +`EnterpriseFillItem` 字段: + +- `socialCreditCode` +- `enterpriseName` +- `entSource` +- `dataSource` +- `userName` + +### 7.2 插入规则 + +1. 按 `socialCreditCode` 去重,同批次同一统一社会信用代码只处理一次。 +2. 批量查询 `ccdi_enterprise_base_info` 已存在记录。 +3. 已存在实体不更新。 +4. 缺失实体最小插入: + - `social_credit_code = 统一社会信用代码` + - `enterprise_name = 企业名称` + - `ent_source = 来源` + - `data_source = MANUAL 或 IMPORT` + - `risk_level = 来源规则值` + - `create_by/update_by = 当前用户` +5. 中介来源 `INTERMEDIARY` 写 `risk_level = 1`。 +6. 员工亲属、信贷客户、供应商来源写 `risk_level = NULL`。 +7. 并发导致主键重复时,按“已存在实体”处理。 +8. 其他数据库异常抛出,让当前业务事务失败。 + +### 7.3 四类业务接入点 + +员工亲属实体关联: + +- 手工新增:校验有效亲属和组合不重复后、插入关联表前补入。 +- 导入:只对校验成功并即将插入的记录批量补入。 +- 来源:`EMP_RELATION` +- 数据来源:手工新增为 `MANUAL`,导入为 `IMPORT` +- 风险等级:`NULL` + +信贷客户实体关联: + +- 手工新增:校验通过后、插入关联表前补入。 +- 导入:只对校验成功并即将插入的记录批量补入。 +- 来源:`CREDIT_CUSTOMER` +- 数据来源:手工新增为 `MANUAL`,导入为 `IMPORT` +- 风险等级:`NULL` + +中介实体关联: + +- 手工新增:校验通过后、插入关联关系前补入实体库。 +- 导入:只对校验成功并即将插入的记录批量补入。 +- 来源:`INTERMEDIARY` +- 数据来源:手工新增为 `MANUAL`,导入为 `IMPORT` +- 风险等级:`1` + +招投标供应商: + +- 手工新增或保存招投标主信息时,只对有效供应商数据补入。 +- 导入:只对成功采购事项中的供应商批量补入,失败采购事项不补入。 +- 来源:`SUPPLIER` +- 数据来源:手工新增为 `MANUAL`,导入为 `IMPORT` +- 风险等级:`NULL` + +## 8. 错误处理与边界 + +### 8.1 双 Sheet 导入边界 + +- 主 Sheet 失败行不能进入资产归属候选。 +- 主 Sheet 文件内重复行不能进入资产归属候选。 +- 主 Sheet 数据库重复行不能进入资产归属候选。 +- 资产 Sheet 仍按自身失败记录任务记录 `sheetName`、`rowNum`、`errorMessage`。 +- 员工资产找不到员工时继续报“员工资产导入仅支持员工本人证件号”。 +- 亲属资产找不到归属时继续报“未找到亲属资产归属员工”。 +- 亲属资产命中多个归属时继续报“亲属资产归属员工不唯一”。 + +### 8.2 自动补入边界 + +- 只处理业务校验成功、即将落库的记录。 +- 失败业务行不能产生实体库记录。 +- 已存在实体不更新,避免覆盖人工维护数据。 +- 不增加默认企业名称、默认来源、默认风险等级等兜底逻辑。 +- 不改变实体库导入的严格新增规则。 + +## 9. 测试设计 + +### 9.1 单元测试 + +员工信息维护双 Sheet: + +- 同一模板中新员工和员工资产同时导入,资产引用新员工身份证号,资产成功。 +- 员工 Sheet 行校验失败,资产引用该身份证号且数据库不存在,资产失败。 +- 只导员工资产,数据库已有员工时成功。 +- 只导员工资产,数据库无员工时失败。 +- 资产重复命中数据库或当前文件重复时失败。 + +员工亲属关系维护双 Sheet: + +- 同一模板中新亲属关系和亲属资产同时导入,资产引用新亲属证件号,资产成功。 +- 亲属关系 Sheet 行校验失败,资产引用该亲属证件号且数据库不存在,资产失败。 +- 只导亲属资产,数据库已有唯一有效亲属关系时成功。 +- 只导亲属资产,数据库不存在亲属关系时失败。 +- 同一亲属证件号命中多个员工归属时失败。 + +实体库自动补入: + +- 已存在实体不插入、不更新。 +- 缺失实体插入最小记录。 +- 同批多个成功行引用同一统一社会信用代码,只补入一次。 +- 中介来源写 `riskLevel=1`。 +- 员工亲属、信贷客户、供应商来源写 `riskLevel=null`。 +- 并发重复主键按已存在处理。 + +四类业务接入: + +- 手工新增成功时调用自动补入。 +- 导入成功行进入自动补入集合。 +- 导入失败行不进入自动补入集合。 + +### 9.2 接口验证 + +1. 下载真实 `/ccdi/baseStaff/importTemplate` 模板,构造 `员工信息` + `员工资产信息` 同文件导入,上传 `/ccdi/baseStaff/importData`,轮询两个任务并查询员工、资产落库。 +2. 下载真实 `/ccdi/staffFmyRelation/importTemplate` 模板,构造 `员工亲属关系信息` + `亲属资产信息` 同文件导入,上传 `/ccdi/staffFmyRelation/importData`,轮询两个任务并查询亲属关系、资产落库。 +3. 分别调用员工亲属、信贷客户、中介、供应商新增或导入接口,验证实体库自动补入来源、数据来源和风险等级。 +4. 涉及中文清理 SQL 或验证 SQL 时使用 `bin/mysql_utf8_exec.sh`。 + +### 9.3 页面验证 + +完成后必须进入真实业务页面验证,不打开 prototype: + +1. 【员工信息维护】下载模板,填写员工和员工资产,上传后检查任务状态、失败记录、列表和详情资产。 +2. 【员工亲属关系维护】下载模板,填写亲属关系和亲属资产,上传后检查任务状态、失败记录、详情资产。 +3. 四类实体自动补入完成后,进入【实体库管理】按统一社会信用代码查询。 +4. 测试结束后清理本轮新增员工、亲属关系、资产、实体关联和自动补入实体库数据。 +5. 测试结束后关闭测试过程中启动的前后端进程。 + +## 10. 实施顺序 + +1. 提炼员工主数据导入执行方法,返回成功员工上下文和失败记录。 +2. 提炼员工资产导入执行方法,支持额外员工归属上下文。 +3. 新增员工信息维护双 Sheet 编排方法并接入 Controller。 +4. 提炼亲属关系导入执行方法,返回成功亲属关系上下文和失败记录。 +5. 提炼亲属资产导入执行方法,支持额外亲属关系归属上下文。 +6. 新增员工亲属关系维护双 Sheet 编排方法并接入 Controller。 +7. 恢复或新增 `EnterpriseAutoFillService`。 +8. 接入员工亲属、信贷客户、中介、供应商四类自动补入。 +9. 补充单元测试。 +10. 执行接口验证和真实页面验证。 +11. 新增实施记录到 `docs/reports/implementation/`。 + +## 11. 风险与控制 + +- 不能继续由 Controller 分别提交两个独立异步任务,否则资产任务执行顺序仍不确定。 +- 不能把主 Sheet 失败行放入资产归属上下文,否则会产生脏资产。 +- 不能更新已存在实体库记录,否则会覆盖人工维护的企业名称、风险等级和来源。 +- 自动补入必须在业务记录落库前执行,并与业务事务保持一致。 +- 四类自动补入必须只处理成功业务行,失败行不能污染实体库。