修订: 中介实体补入无需机构名称

This commit is contained in:
wkc
2026-05-06 18:30:03 +08:00
parent c64146ac40
commit 928f65dfca
3 changed files with 59 additions and 62 deletions

View File

@@ -190,15 +190,16 @@ Controller 继续负责读取两个 Sheet但不再分别提交两个彼此独
3. 已存在实体不更新。
4. 缺失实体最小插入:
- `social_credit_code = 统一社会信用代码`
- `enterprise_name = 企业名称`
- `enterprise_name = 企业名称;中介实体关联缺失实体时允许为 NULL`
- `ent_source = 来源`
- `data_source = MANUAL 或 IMPORT`
- `risk_level = 来源规则值`
- `created_by/updated_by = 当前用户`
5. 中介来源 `INTERMEDIARY``risk_level = 1`
6. 员工亲属、信贷客户、供应商来源`risk_level = NULL`
7. 并发导致主键重复时,按“已存在实体”处理
8. 其他数据库异常抛出,让当前业务事务失败
5. 中介实体关联缺失实体时不要求提供机构名称,补入实体的 `enterprise_name` 可以为 `NULL`
6. 中介来源 `INTERMEDIARY` `risk_level = 1`
7. 员工亲属、信贷客户、供应商来源写 `risk_level = NULL`
8. 并发导致主键重复时,按“已存在实体”处理
9. 其他数据库异常抛出,让当前业务事务失败。
### 7.3 四类业务接入点
@@ -257,6 +258,7 @@ Controller 继续负责读取两个 Sheet但不再分别提交两个彼此独
- 不增加默认企业名称、默认来源、默认风险等级等兜底逻辑。
- 不改变实体库导入的严格新增规则。
- 中介实体关联的“实体库必须已存在”校验需要被自动补入替换,否则缺失实体无法进入补入链路。
- 中介实体关联不新增机构名称入参;缺失实体补入时允许 `enterprise_name = NULL`
- 供应商自动补入只处理非空统一社会信用代码,空统一社会信用代码不改变原导入保存规则。
## 9. 测试设计

View File

@@ -59,12 +59,6 @@
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiIntermediaryServiceImplTest.java`
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiIntermediaryEnterpriseRelationImportServiceImplTest.java`
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiPurchaseTransactionFeatureContractTest.java`
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryEnterpriseRelationAddDTO.java`
- Add `enterpriseName` for missing-entity auto-fill in manual intermediary relation API.
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEnterpriseRelationExcel.java`
- Add `机构名称` column for missing-entity auto-fill in intermediary relation import.
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/IntermediaryEnterpriseRelationImportFailureVO.java`
- Include `enterpriseName` in failure records if the import VO does not already expose it.
- Modify relation/supplier services:
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffEnterpriseRelationServiceImpl.java`
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiStaffEnterpriseRelationImportServiceImpl.java`
@@ -163,7 +157,7 @@ Add tests for:
- Existing entity returned by `selectBatchIds` is not inserted.
- Duplicate items in same batch insert once.
- `INTERMEDIARY` sets `riskLevel` to `"1"`.
- `INTERMEDIARY` sets `riskLevel` to `"1"` and still inserts when `enterpriseName` is `null`.
- `EMP_RELATION` and `CREDIT_CUSTOMER` keep `riskLevel` null.
- `DuplicateKeyException` from batch insert falls back to per-row `selectById` and treats existing row as success.
@@ -968,20 +962,17 @@ If the customer test files do not exist yet, create them as local verification f
**Files:**
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiIntermediaryServiceImpl.java`
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiIntermediaryEnterpriseRelationImportServiceImpl.java`
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryEnterpriseRelationAddDTO.java`
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEnterpriseRelationExcel.java`
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/IntermediaryEnterpriseRelationImportFailureVO.java`
- Test: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiIntermediaryServiceImplTest.java`
- Test: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiIntermediaryEnterpriseRelationImportServiceImplTest.java`
- [ ] **Step 1: Write failing intermediary enterprise-name contract tests**
- [ ] **Step 1: Write failing intermediary no-name auto-fill contract tests**
Add local tests proving the backend contract:
- `CcdiIntermediaryEnterpriseRelationAddDTO` has `enterpriseName`.
- `CcdiIntermediaryEnterpriseRelationExcel` has `enterpriseName` with Excel header `机构名称`.
- Missing entity + blank `enterpriseName` fails instead of inserting an unnamed entity.
- Existing entity + blank `enterpriseName` still keeps current behavior because no auto-fill insert is needed.
- Do not add `enterpriseName` to `CcdiIntermediaryEnterpriseRelationAddDTO`.
- Do not add `机构名称` to `CcdiIntermediaryEnterpriseRelationExcel`.
- Missing entity + no enterprise name succeeds after auto-fill.
- The auto-filled `EnterpriseFillItem.enterpriseName()` is `null`.
- [ ] **Step 2: Write failing manual relation test**
@@ -999,13 +990,12 @@ void insertIntermediaryEnterpriseRelation_shouldAutoFillMissingEnterpriseBeforeI
when(enterpriseRelationMapper.insert(any())).thenReturn(1);
CcdiIntermediaryEnterpriseRelationAddDTO addDTO = buildEnterpriseRelationAddDto();
addDTO.setEnterpriseName("测试中介机构");
service.insertIntermediaryEnterpriseRelation("owner-biz", addDTO);
verify(enterpriseAutoFillService).ensureExists(argThat(item ->
"INTERMEDIARY".equals(item.entSource())
&& "MANUAL".equals(item.dataSource())
&& "测试中介机构".equals(item.enterpriseName())));
&& item.enterpriseName() == null));
}
```
@@ -1015,9 +1005,9 @@ Change `CcdiIntermediaryEnterpriseRelationImportServiceImplTest#importEnterprise
- Owner exists.
- Entity does not exist.
- Excel row has `enterpriseName`.
- Excel row has no enterprise name column.
- Relation combination does not exist.
- `EnterpriseAutoFillService.ensureExistsBatch` is called with `INTERMEDIARY/IMPORT`.
- `EnterpriseAutoFillService.ensureExistsBatch` is called with `INTERMEDIARY/IMPORT` and `enterpriseName == null`.
- Relation insert succeeds.
- [ ] **Step 4: Run tests and verify failure**
@@ -1030,30 +1020,15 @@ mvn -pl ccdi-info-collection -Dtest=CcdiIntermediaryServiceImplTest,CcdiIntermed
Expected: FAIL because current code requires the enterprise to exist.
- [ ] **Step 5: Add backend enterpriseName fields**
- [ ] **Step 5: Keep intermediary API and Excel contract unchanged**
In `CcdiIntermediaryEnterpriseRelationAddDTO`, add:
Do not modify these files for the intermediary no-name rule:
```java
@Schema(description = "机构名称")
@Size(max = 200, message = "机构名称长度不能超过200个字符")
private String enterpriseName;
```
- `CcdiIntermediaryEnterpriseRelationAddDTO`
- `CcdiIntermediaryEnterpriseRelationExcel`
- `IntermediaryEnterpriseRelationImportFailureVO`
Do not mark it `@NotBlank` at DTO level, because existing-entity relations may still be created by social credit code alone. Missing-entity auto-fill must validate it at service level.
In `CcdiIntermediaryEnterpriseRelationExcel`, add:
```java
/** 机构名称 */
@ExcelProperty(value = "机构名称", index = 2)
@ColumnWidth(30)
private String enterpriseName;
```
Shift `relationPersonPost` to index `3` and `remark` to index `4`.
In `IntermediaryEnterpriseRelationImportFailureVO`, add `enterpriseName` if it is not already present so failed rows show the submitted name.
The intermediary relation only provides `socialCreditCode`; missing entity auto-fill must insert a minimal entity with `enterprise_name = NULL`. The current initialization SQL already defines `ccdi_enterprise_base_info.enterprise_name` as nullable.
- [ ] **Step 6: Replace manual existing-enterprise check**
@@ -1062,19 +1037,16 @@ In `CcdiIntermediaryServiceImpl`:
- Inject `EnterpriseAutoFillService`.
- Split `validateEnterpriseRelation` so it only checks owner and duplicate relation.
- Remove the `enterpriseBaseInfoMapper.selectById(socialCreditCode) == null` failure for insert.
- Add a helper that checks whether the entity exists. If it exists, do not call auto-fill and do not update it. If it does not exist, require `enterpriseName` and call auto-fill before `enterpriseRelationMapper.insert(relation)`:
- Add a helper that checks whether the entity exists. If it exists, do not call auto-fill and do not update it. If it does not exist, call auto-fill with `enterpriseName = null` before `enterpriseRelationMapper.insert(relation)`:
```java
private void ensureIntermediaryEnterpriseExists(CcdiIntermediaryEnterpriseRelationAddDTO addDTO) {
if (enterpriseBaseInfoMapper.selectById(addDTO.getSocialCreditCode()) != null) {
return;
}
if (StringUtils.isEmpty(addDTO.getEnterpriseName())) {
throw new RuntimeException("机构名称不能为空");
}
enterpriseAutoFillService.ensureExists(new EnterpriseAutoFillService.EnterpriseFillItem(
addDTO.getSocialCreditCode(),
addDTO.getEnterpriseName(),
null,
EnterpriseSource.INTERMEDIARY.getCode(),
DataSource.MANUAL.getCode(),
SecurityUtils.getUsername()
@@ -1086,10 +1058,10 @@ private void ensureIntermediaryEnterpriseExists(CcdiIntermediaryEnterpriseRelati
In `CcdiIntermediaryEnterpriseRelationImportServiceImpl`:
- Keep the existing enterprise code query only as `existingEnterpriseCodes` context, not as a missing-entity failure.
- If a row references a missing entity and `excel.getEnterpriseName()` is blank, fail that row with `机构名称不能为空`.
- If a row references an existing entity, do not update that entity and do not require `enterpriseName`.
- Build `EnterpriseFillItem` from successful Excel rows where the entity is missing and `enterpriseName` is present.
- Remove the existing enterprise code query from row failure validation; `EnterpriseAutoFillService` will check existing entities in batch and insert only missing ones.
- If a row references a missing entity, do not fail just because the entity is missing.
- If a row references an existing entity, do not update that entity.
- Build `EnterpriseFillItem` from successful Excel rows with `enterpriseName = null`.
- Call `ensureExistsBatch` before `saveBatch(successRecords, 500)`.
- Keep owner missing, DB duplicate relation, and file duplicate relation failures unchanged.
@@ -1108,10 +1080,7 @@ Expected: PASS.
```bash
git add \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiIntermediaryServiceImpl.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiIntermediaryEnterpriseRelationImportServiceImpl.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryEnterpriseRelationAddDTO.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/excel/CcdiIntermediaryEnterpriseRelationExcel.java \
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/IntermediaryEnterpriseRelationImportFailureVO.java
ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiIntermediaryEnterpriseRelationImportServiceImpl.java
git commit -m "接入中介实体自动补入"
```
@@ -1298,8 +1267,8 @@ Scenarios:
- Staff-family entity relation import inserts missing entity with `ent_source=EMP_RELATION`, `data_source=IMPORT`, `risk_level IS NULL`; failed rows do not auto-fill.
- Manual credit-customer entity relation inserts missing entity with `ent_source=CREDIT_CUSTOMER`, `data_source=MANUAL`, `risk_level IS NULL`.
- Credit-customer entity relation import inserts missing entity with `ent_source=CREDIT_CUSTOMER`, `data_source=IMPORT`, `risk_level IS NULL`; failed rows do not auto-fill.
- Manual intermediary entity relation inserts missing entity when `enterpriseName` is present, with `ent_source=INTERMEDIARY`, `data_source=MANUAL`, `risk_level=1`.
- Intermediary entity relation import inserts missing entity when `机构名称` is present, with `ent_source=INTERMEDIARY`, `data_source=IMPORT`, `risk_level=1`; missing entity + blank `机构名称` fails that row.
- Manual intermediary entity relation inserts missing entity without requiring enterprise name, with `enterprise_name IS NULL`, `ent_source=INTERMEDIARY`, `data_source=MANUAL`, `risk_level=1`.
- Intermediary entity relation import inserts missing entity without requiring enterprise name, with `enterprise_name IS NULL`, `ent_source=INTERMEDIARY`, `data_source=IMPORT`, `risk_level=1`.
- Manual purchase add and edit insert missing supplier entity with `ent_source=SUPPLIER`, `data_source=MANUAL`, `risk_level IS NULL`.
- Purchase import inserts missing supplier entity with `ent_source=SUPPLIER`, `data_source=IMPORT`, `risk_level IS NULL`; failed purchase or invalid supplier rows do not auto-fill.
- Existing entity rows for all four sources are not updated. Verify by seeding an existing `ccdi_enterprise_base_info` row with a sentinel `enterprise_name`, `ent_source`, `data_source`, and `risk_level`, then re-querying the same row after each manual/import path.
@@ -1397,10 +1366,10 @@ Do not use `git add -f` for local `src/test` verification files unless the user
- [ ] Auto-fill does not update existing entities.
- [ ] Staff-family manual add and import insert `ent_source=EMP_RELATION`, `data_source=MANUAL/IMPORT`, `risk_level=NULL`.
- [ ] Credit-customer manual add and import insert `ent_source=CREDIT_CUSTOMER`, `data_source=MANUAL/IMPORT`, `risk_level=NULL`.
- [ ] Intermediary manual add and import insert `ent_source=INTERMEDIARY`, `data_source=MANUAL/IMPORT`, `risk_level=1`.
- [ ] Intermediary manual add and import insert `enterprise_name=NULL`, `ent_source=INTERMEDIARY`, `data_source=MANUAL/IMPORT`, `risk_level=1`.
- [ ] Supplier manual add, manual edit, and import insert `ent_source=SUPPLIER`, `data_source=MANUAL/IMPORT`, `risk_level=NULL`.
- [ ] Failed staff-family, credit-customer, intermediary, and supplier import rows do not auto-fill entities.
- [ ] Intermediary missing entity with blank `enterpriseName` / `机构名称` fails that row.
- [ ] Intermediary missing entity does not require `enterpriseName` / `机构名称`.
- [ ] Intermediary auto-fill inserts `risk_level=1`.
- [ ] Staff-family, credit-customer, and supplier auto-fill insert `risk_level=NULL`.
- [ ] Supplier empty or invalid `supplierUscc` does not auto-fill and does not become a new manual-save failure condition.

View File

@@ -0,0 +1,26 @@
# 中介实体自动补入无需机构名称规则文档修订记录
## 保存路径确认
- 目标目录:`docs/reports/implementation/`
- 文档用途:记录中介实体自动补入业务规则调整
- 路径检查结果:符合仓库实施记录归档规范
## 修改内容
- 修订员工资产导入与实体库自动补入修复设计文档。
- 修订对应后端实施计划。
- 明确中介实体关联缺失实体时不要求提供机构名称。
- 明确中介实体自动补入允许 `ccdi_enterprise_base_info.enterprise_name``NULL`
- 移除后端计划中新增中介 `enterpriseName` DTO 字段、Excel `机构名称` 列、失败记录名称字段的实施要求。
## 影响范围
- 文档范围:设计文档、后端实施计划、实施记录。
- 代码范围:本次未修改源码。
- 业务规则:中介实体关联按统一社会信用代码补入实体库,来源为 `INTERMEDIARY`,风险等级为 `1`,企业名称允许为空。
## 验证情况
- 文档关键字检查:已检查计划中不再要求中介缺实体时填写机构名称。
- 代码验证:本次未修改源码,未执行编译或单元测试。