From 75cb8967da55528d2f2d42c21f2f71d8f839a338 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Wed, 6 May 2026 23:31:43 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9B=9E=E6=B5=8B=E5=9B=9B=E7=B1=BB=E5=AF=BC?= =?UTF-8?q?=E5=85=A5=E8=87=AA=E5=8A=A8=E8=A1=A5=E5=85=A5=E5=AE=9E=E4=BD=93?= =?UTF-8?q?=E5=BA=93?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...terpriseRelationImportServiceImplTest.java | 46 ++++---- ...terprise-autofill-four-source-retrotest.md | 83 ++++++++++++++ ...06-enterprise-autofill-import-retrotest.md | 102 ++++++++++++++++++ 3 files changed, 209 insertions(+), 22 deletions(-) create mode 100644 docs/reports/implementation/2026-05-06-enterprise-autofill-four-source-retrotest.md create mode 100644 docs/reports/implementation/2026-05-06-enterprise-autofill-import-retrotest.md diff --git a/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiIntermediaryEnterpriseRelationImportServiceImplTest.java b/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiIntermediaryEnterpriseRelationImportServiceImplTest.java index d4eff2f9..f69dee32 100644 --- a/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiIntermediaryEnterpriseRelationImportServiceImplTest.java +++ b/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiIntermediaryEnterpriseRelationImportServiceImplTest.java @@ -1,14 +1,13 @@ package com.ruoyi.info.collection.service; import com.ruoyi.info.collection.domain.CcdiBizIntermediary; -import com.ruoyi.info.collection.domain.CcdiEnterpriseBaseInfo; import com.ruoyi.info.collection.domain.CcdiIntermediaryEnterpriseRelation; import com.ruoyi.info.collection.domain.excel.CcdiIntermediaryEnterpriseRelationExcel; import com.ruoyi.info.collection.domain.vo.IntermediaryEnterpriseRelationImportFailureVO; import com.ruoyi.info.collection.mapper.CcdiBizIntermediaryMapper; -import com.ruoyi.info.collection.mapper.CcdiEnterpriseBaseInfoMapper; import com.ruoyi.info.collection.mapper.CcdiIntermediaryEnterpriseRelationMapper; import com.ruoyi.info.collection.service.impl.CcdiIntermediaryEnterpriseRelationImportServiceImpl; +import com.ruoyi.info.collection.service.support.EnterpriseAutoFillService; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; import org.mockito.ArgumentCaptor; @@ -23,6 +22,7 @@ import java.util.List; import java.util.concurrent.TimeUnit; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; @@ -42,7 +42,7 @@ class CcdiIntermediaryEnterpriseRelationImportServiceImplTest { private CcdiBizIntermediaryMapper intermediaryMapper; @Mock - private CcdiEnterpriseBaseInfoMapper enterpriseBaseInfoMapper; + private EnterpriseAutoFillService enterpriseAutoFillService; @Mock private RedisTemplate redisTemplate; @@ -58,11 +58,11 @@ class CcdiIntermediaryEnterpriseRelationImportServiceImplTest { CcdiIntermediaryEnterpriseRelationExcel excel = buildExcel("320101199001010014", "91330100MA27X12345"); prepareFailureRedisMocks(); when(intermediaryMapper.selectList(any())).thenReturn(List.of()); - when(enterpriseBaseInfoMapper.selectList(any())).thenReturn(List.of(enterprise("91330100MA27X12345"))); service.importAsync(List.of(excel), "task-owner-miss", "tester"); verify(relationMapper, never()).insertBatch(any()); + verify(enterpriseAutoFillService, never()).ensureExistsBatch(any()); IntermediaryEnterpriseRelationImportFailureVO failure = firstFailure("import:intermediary-enterprise-relation:task-owner-miss:failures"); assertEquals("320101199001010014", failure.getOwnerPersonId()); @@ -70,20 +70,20 @@ class CcdiIntermediaryEnterpriseRelationImportServiceImplTest { } @Test - void importEnterpriseRelationAsync_shouldFailWhenEnterpriseDoesNotExist() { + void importEnterpriseRelationAsync_shouldAutoFillWhenEnterpriseDoesNotExist() { CcdiIntermediaryEnterpriseRelationExcel excel = buildExcel("320101199001010014", "91330100MA27X12345"); - prepareFailureRedisMocks(); + prepareStatusRedisMock(); when(intermediaryMapper.selectList(any())).thenReturn(List.of(owner("owner-biz", "320101199001010014"))); - when(enterpriseBaseInfoMapper.selectList(any())).thenReturn(List.of()); when(relationMapper.batchExistsByCombinations(any())).thenReturn(List.of()); service.importAsync(List.of(excel), "task-ent-miss", "tester"); - verify(relationMapper, never()).insertBatch(any()); - IntermediaryEnterpriseRelationImportFailureVO failure = - firstFailure("import:intermediary-enterprise-relation:task-ent-miss:failures"); - assertEquals("91330100MA27X12345", failure.getSocialCreditCode()); - assertTrue(failure.getErrorMessage().contains("机构表")); + ArgumentCaptor> relationCaptor = ArgumentCaptor.forClass(List.class); + verify(relationMapper).insertBatch(relationCaptor.capture()); + assertEquals(1, relationCaptor.getValue().size()); + assertEquals("owner-biz", relationCaptor.getValue().get(0).getIntermediaryBizId()); + assertEquals("91330100MA27X12345", relationCaptor.getValue().get(0).getSocialCreditCode()); + assertIntermediaryAutoFill("91330100MA27X12345"); } @Test @@ -96,10 +96,6 @@ class CcdiIntermediaryEnterpriseRelationImportServiceImplTest { owner("owner-biz-1", "320101199001010014"), owner("owner-biz-2", "320101199003030035") )); - when(enterpriseBaseInfoMapper.selectList(any())).thenReturn(List.of( - enterprise("91330100MA27X12345"), - enterprise("91330100MA27X12346") - )); when(relationMapper.batchExistsByCombinations(any())).thenReturn(List.of("owner-biz-1|91330100MA27X12345")); service.importAsync(List.of(duplicateInDb, duplicateInFile1, duplicateInFile2), "task-duplicate", "tester"); @@ -108,6 +104,7 @@ class CcdiIntermediaryEnterpriseRelationImportServiceImplTest { verify(relationMapper).insertBatch(captor.capture()); assertEquals(1, captor.getValue().size()); assertEquals("owner-biz-2", captor.getValue().get(0).getIntermediaryBizId()); + assertIntermediaryAutoFill("91330100MA27X12346"); IntermediaryEnterpriseRelationImportFailureVO failure = firstFailure("import:intermediary-enterprise-relation:task-duplicate:failures"); assertTrue(failure.getErrorMessage().contains("重复") || failure.getErrorMessage().contains("已存在")); @@ -118,7 +115,6 @@ class CcdiIntermediaryEnterpriseRelationImportServiceImplTest { CcdiIntermediaryEnterpriseRelationExcel excel = buildExcel("320101199001010014", "91330100MA27X12345"); prepareStatusRedisMock(); when(intermediaryMapper.selectList(any())).thenReturn(List.of(owner("owner-biz", "320101199001010014"))); - when(enterpriseBaseInfoMapper.selectList(any())).thenReturn(List.of(enterprise("91330100MA27X12345"))); when(relationMapper.batchExistsByCombinations(any())).thenReturn(List.of()); service.importAsync(List.of(excel), "task-success", "tester"); @@ -127,6 +123,7 @@ class CcdiIntermediaryEnterpriseRelationImportServiceImplTest { verify(relationMapper).insertBatch(captor.capture()); assertEquals(1, captor.getValue().size()); assertEquals("owner-biz", captor.getValue().get(0).getIntermediaryBizId()); + assertIntermediaryAutoFill("91330100MA27X12345"); verify(valueOperations, never()).set(any(), any(), any(Long.class), any(TimeUnit.class)); } @@ -163,10 +160,15 @@ class CcdiIntermediaryEnterpriseRelationImportServiceImplTest { return owner; } - private CcdiEnterpriseBaseInfo enterprise(String socialCreditCode) { - CcdiEnterpriseBaseInfo enterprise = new CcdiEnterpriseBaseInfo(); - enterprise.setSocialCreditCode(socialCreditCode); - enterprise.setEnterpriseName("机构" + socialCreditCode.substring(socialCreditCode.length() - 2)); - return enterprise; + private void assertIntermediaryAutoFill(String socialCreditCode) { + ArgumentCaptor> captor = ArgumentCaptor.forClass(List.class); + verify(enterpriseAutoFillService).ensureExistsBatch(captor.capture()); + assertEquals(1, captor.getValue().size()); + EnterpriseAutoFillService.EnterpriseFillItem item = captor.getValue().get(0); + assertEquals(socialCreditCode, item.socialCreditCode()); + assertNull(item.enterpriseName()); + assertEquals("INTERMEDIARY", item.entSource()); + assertEquals("IMPORT", item.dataSource()); + assertEquals("tester", item.userName()); } } diff --git a/docs/reports/implementation/2026-05-06-enterprise-autofill-four-source-retrotest.md b/docs/reports/implementation/2026-05-06-enterprise-autofill-four-source-retrotest.md new file mode 100644 index 00000000..0f144a5a --- /dev/null +++ b/docs/reports/implementation/2026-05-06-enterprise-autofill-four-source-retrotest.md @@ -0,0 +1,83 @@ +# 四类关联业务自动补入实体库回测记录 + +## 保存路径确认 + +- 本次实施记录保存于 `docs/reports/implementation/`。 + +## 回测范围 + +- 员工亲属实体关联自动补入实体库。 +- 信贷客户实体关联自动补入实体库。 +- 中介关联机构自动补入实体库。 +- 招投标供应商自动补入实体库。 + +## 本次调整 + +- 修正中介实体关联导入单元测试的旧断言:实体库缺失时不再失败,成功行应调用 `EnterpriseAutoFillService` 自动补入,失败行不补入。 +- 修正本地供应商契约测试在 Maven 模块目录下读取仓库根 SQL 的路径口径。 +- 业务代码未调整。 + +## 单元回归 + +执行命令: + +```bash +mvn -pl ccdi-info-collection -am -Dtest=CcdiStaffEnterpriseRelationServiceImplTest,CcdiStaffEnterpriseRelationImportServiceImplTest,CcdiIntermediaryEnterpriseRelationImportServiceImplTest,CcdiIntermediaryServiceImplTest,CcdiPurchaseTransactionFeatureContractTest,CcdiEnterpriseBaseInfoImportServiceImplTest -Dsurefire.failIfNoSpecifiedTests=false test +``` + +执行结果: + +- `Tests run: 24, Failures: 0, Errors: 0, Skipped: 0` +- `BUILD SUCCESS` + +## 真实接口回测 + +后端启动: + +```bash +sh bin/restart_java_backend.sh restart +``` + +本轮使用测试前缀 `RT20260506`,先通过 `bin/mysql_utf8_exec.sh` 写入员工亲属、信贷客户关系人、中介本人三类前置数据,再调用真实后端接口: + +| 来源 | 接口 | 统一社会信用代码 | 接口结果 | +| --- | --- | --- | --- | +| 员工亲属 | `POST /ccdi/staffEnterpriseRelation` | `91330100RT20260501` | 操作成功 | +| 信贷客户 | `POST /ccdi/custEnterpriseRelation` | `91330100RT20260502` | 操作成功 | +| 中介 | `POST /ccdi/intermediary/RT20260506IM001/enterprise-relation` | `91330100RT20260503` | 操作成功 | +| 供应商 | `POST /ccdi/purchaseTransaction` | `91330100RT20260504` | 操作成功 | + +## 数据库回查 + +实体库回查结果: + +| social_credit_code | enterprise_name | ent_source | data_source | risk_level | created_by | +| --- | --- | --- | --- | --- | --- | +| `91330100RT20260501` | 回测员工亲属自动补入企业 | `EMP_RELATION` | `MANUAL` | `NULL` | `admin` | +| `91330100RT20260502` | 回测信贷客户自动补入企业 | `CREDIT_CUSTOMER` | `MANUAL` | `NULL` | `admin` | +| `91330100RT20260503` | `NULL` | `INTERMEDIARY` | `MANUAL` | `1` | `admin` | +| `91330100RT20260504` | 回测供应商自动补入企业 | `SUPPLIER` | `MANUAL` | `NULL` | `admin` | + +关系表回查: + +- `ccdi_staff_enterprise_relation`:1 条 +- `ccdi_cust_enterprise_relation`:1 条 +- `ccdi_intermediary_enterprise_relation`:1 条 +- `ccdi_purchase_transaction_supplier`:1 条 + +## 清理结果 + +执行 `bin/mysql_utf8_exec.sh output/sql/2026-05-06-enterprise-autofill-retrotest-cleanup.sql` 后回查: + +- `enterprise_rows=0` +- `staff_relation_rows=0` +- `cust_relation_rows=0` +- `intermediary_relation_rows=0` +- `purchase_rows=0` +- `supplier_rows=0` + +## 结论 + +- 四类来源均可通过真实接口自动补入 `ccdi_enterprise_base_info`。 +- 来源映射符合预期:员工亲属 `EMP_RELATION`、信贷客户 `CREDIT_CUSTOMER`、中介 `INTERMEDIARY`、供应商 `SUPPLIER`。 +- 中介来源风险等级自动落为 `1`,其余三类风险等级为空,符合既定规则。 diff --git a/docs/reports/implementation/2026-05-06-enterprise-autofill-import-retrotest.md b/docs/reports/implementation/2026-05-06-enterprise-autofill-import-retrotest.md new file mode 100644 index 00000000..fd391652 --- /dev/null +++ b/docs/reports/implementation/2026-05-06-enterprise-autofill-import-retrotest.md @@ -0,0 +1,102 @@ +# 关联业务导入接口自动补入实体库回测记录 + +## 基本信息 + +- 回测日期:2026-05-06 +- 回测范围:员工亲属实体关联、信贷客户实体关联、中介实体关联、招投标供应商四个导入接口 +- 文档保存路径:`docs/reports/implementation/2026-05-06-enterprise-autofill-import-retrotest.md` +- 测试文件目录:`output/spreadsheet/import-retrotest/` +- SQL 文件目录:`output/sql/` + +## 回测准备 + +1. 使用 `sh bin/restart_java_backend.sh restart` 启动后端,后端运行端口为 `62318`。 +2. 使用 `bin/mysql_utf8_exec.sh output/sql/2026-05-06-enterprise-autofill-import-retrotest-seed.sql` 写入前置数据。 +3. 通过 `/login/test` 获取 `admin` 登录态。 +4. 从真实后端接口下载当前导入模板,并基于模板填充第 2 行测试数据: + - `/ccdi/staffEnterpriseRelation/importTemplate` + - `/ccdi/custEnterpriseRelation/importTemplate` + - `/ccdi/intermediary/importEnterpriseRelationTemplate` + - `/ccdi/purchaseTransaction/importTemplate` + +## 导入接口回测结果 + +| 类型 | 导入接口 | 任务 ID | 状态 | 成功数 | 失败数 | +| --- | --- | --- | --- | --- | --- | +| 员工亲属 | `/ccdi/staffEnterpriseRelation/importData` | `934cf8b8-de56-4478-be9c-e2261652c993` | `SUCCESS` | 1 | 0 | +| 信贷客户 | `/ccdi/custEnterpriseRelation/importData` | `5f21cd94-307e-4681-9659-64f3d270ef0a` | `SUCCESS` | 1 | 0 | +| 中介 | `/ccdi/intermediary/importEnterpriseRelationData` | `9738837f-d657-4078-9d1d-6269ac35ecdc` | `SUCCESS` | 1 | 0 | +| 供应商 | `/ccdi/purchaseTransaction/importData` | `0cc37465-98b6-4c98-88be-8b28cbe0f8db` | `SUCCESS` | 1 | 0 | + +四个接口均使用 multipart `file` 参数上传基于真实模板生成的 Excel 文件,并轮询对应 `importStatus` 接口至最终状态。 + +## 实体库回查结果 + +使用 `bin/mysql_utf8_exec.sh output/sql/2026-05-06-enterprise-autofill-import-retrotest-verify.sql` 回查实体库与业务表。 + +| 统一社会信用代码 | 企业名称 | 企业来源 | 数据来源 | 风险等级 | 创建人 | +| --- | --- | --- | --- | --- | --- | +| `91330100RT20260601` | 导入回测员工亲属自动补入企业 | `EMP_RELATION` | `IMPORT` | `NULL` | `admin` | +| `91330100RT20260602` | 导入回测信贷客户自动补入企业 | `CREDIT_CUSTOMER` | `IMPORT` | `NULL` | `admin` | +| `91330100RT20260603` | `NULL` | `INTERMEDIARY` | `IMPORT` | `1` | `admin` | +| `91330100RT20260604` | 导入回测供应商自动补入企业 | `SUPPLIER` | `IMPORT` | `NULL` | `admin` | + +业务表回查结果: + +| 检查项 | 记录数 | +| --- | --- | +| `staff_relation` | 1 | +| `cust_relation` | 1 | +| `intermediary_relation` | 1 | +| `purchase_supplier` | 1 | + +## 清理结果 + +使用 `bin/mysql_utf8_exec.sh output/sql/2026-05-06-enterprise-autofill-import-retrotest-cleanup.sql` 删除本轮导入数据、实体库补入数据和测试前置数据。 + +| 检查项 | 剩余记录数 | +| --- | --- | +| `enterprise_base_info` | 0 | +| `staff_relation` | 0 | +| `cust_relation` | 0 | +| `intermediary_relation` | 0 | +| `purchase_supplier` | 0 | +| `purchase_transaction` | 0 | +| `staff_family_seed` | 0 | +| `intermediary_seed` | 0 | + +## 保留导入数据复测 + +按用户要求保留导入 Excel 模板文件与导入数据后,重新执行一轮导入。本轮没有执行清理 SQL。 + +1. 确认 `output/spreadsheet/import-retrotest/` 下模板文件和导入文件均保留。 +2. 使用 `bin/mysql_utf8_exec.sh output/sql/2026-05-06-enterprise-autofill-import-retrotest-seed-keep-data.sql` 仅补充导入所需前置数据,该脚本不包含删除语句。 +3. 复用已保留的四个导入 Excel 文件上传导入接口。 +4. 使用 `bin/mysql_utf8_exec.sh output/sql/2026-05-06-enterprise-autofill-import-retrotest-verify.sql` 回查实体库与业务表,确认导入数据保留。 + +| 类型 | 导入接口 | 任务 ID | 状态 | 成功数 | 失败数 | +| --- | --- | --- | --- | --- | --- | +| 员工亲属 | `/ccdi/staffEnterpriseRelation/importData` | `da75f851-bc25-4930-8e0f-81dbfeb7e658` | `SUCCESS` | 1 | 0 | +| 信贷客户 | `/ccdi/custEnterpriseRelation/importData` | `7eaa18da-aa69-41f6-90f5-acb74d63d1e6` | `SUCCESS` | 1 | 0 | +| 中介 | `/ccdi/intermediary/importEnterpriseRelationData` | `ed9931f2-950e-4778-bf5d-d57d702015b8` | `SUCCESS` | 1 | 0 | +| 供应商 | `/ccdi/purchaseTransaction/importData` | `0582c091-785c-4c71-af24-9f03375b86ea` | `SUCCESS` | 1 | 0 | + +当前保留数据回查结果: + +| 统一社会信用代码 | 企业名称 | 企业来源 | 数据来源 | 风险等级 | 创建人 | +| --- | --- | --- | --- | --- | --- | +| `91330100RT20260601` | 导入回测员工亲属自动补入企业 | `EMP_RELATION` | `IMPORT` | `NULL` | `admin` | +| `91330100RT20260602` | 导入回测信贷客户自动补入企业 | `CREDIT_CUSTOMER` | `IMPORT` | `NULL` | `admin` | +| `91330100RT20260603` | `NULL` | `INTERMEDIARY` | `IMPORT` | `1` | `admin` | +| `91330100RT20260604` | 导入回测供应商自动补入企业 | `SUPPLIER` | `IMPORT` | `NULL` | `admin` | + +| 检查项 | 当前记录数 | +| --- | --- | +| `staff_relation` | 1 | +| `cust_relation` | 1 | +| `intermediary_relation` | 1 | +| `purchase_supplier` | 1 | + +## 结论 + +员工亲属、信贷客户、中介、供应商四个导入接口均可以正常触发实体库自动补入。实体库来源、数据来源和风险等级与当前实现一致。按最新要求,导入 Excel 模板文件与导入数据已保留。