Files
ccdi/docs/plans/backend/2026-04-17-intermediary-library-refactor-backend-implementation.md

541 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 中介库主从结构改造后端实施计划
> **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** 将中介库后端从“个人中介 / 机构中介并列维护”改造为“中介本人主记录 + 中介亲属子记录 + 中介机构关系子记录”,并提供统一首页查询、详情维护和级联删除能力。
**Architecture:** 继续以 `CcdiIntermediaryController``ccdi_biz_intermediary` 为主线,保留中介本人主资源;亲属仍落同表,通过 `person_sub_type``related_num_id` 表达主从关系;新增 `ccdi_intermediary_enterprise_relation` 作为中介与机构的关系表。首页 `/ccdi/intermediary/list` 改为三路联合查询,返回统一展示字段与 `recordType` 供前端分流。
**Tech Stack:** Java 21, Spring Boot 3, MyBatis Plus, MySQL, JUnit 5, Maven, Markdown
---
## 文件结构与职责
**设计与参考**
- `docs/design/2026-04-17-intermediary-library-refactor-design.md`
本次改造的设计基线,实施时不得偏离文档确认的字段、接口与删除规则。
**数据库与 SQL**
- `sql/migration/2026-04-17-create-intermediary-enterprise-relation.sql`
创建 `ccdi_intermediary_enterprise_relation`,补索引和唯一约束。
- `sql/migration/2026-04-17-fix-intermediary-person-sub-type-dict.sql`
如需补齐 `person_sub_type` 固定值“本人/配偶/子女/父母/兄弟姐妹/其他”,在此脚本中补充字典数据。
**中介主链路**
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiIntermediaryController.java`
继续作为中介模块统一入口,补亲属与机构关系子资源接口。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiIntermediaryService.java`
增加亲属列表、亲属 CRUD、机构关系列表、机构关系 CRUD、统一联合查询新口径方法。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiIntermediaryServiceImpl.java`
承接中介本人、亲属、机构关系、联合查询和级联删除逻辑。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiIntermediaryMapper.java`
保留首页联合查询入口,参数口径调整。
- `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiIntermediaryMapper.xml`
将首页联合查询改为“本人 + 亲属 + 机构关系”三路 `UNION ALL`
**亲属与中介本人 DTO / VO**
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryQueryDTO.java`
改成新首页查询条件。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryPersonAddDTO.java`
收敛为“中介本人新增”入参,不再承担亲属语义。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryPersonEditDTO.java`
收敛为“中介本人编辑”入参。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryRelativeAddDTO.java`
新增中介亲属新增入参。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryRelativeEditDTO.java`
新增中介亲属编辑入参。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiIntermediaryVO.java`
改为首页统一列表 VO。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiIntermediaryPersonDetailVO.java`
改为中介本人详情 VO。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiIntermediaryRelativeVO.java`
新增亲属列表 / 详情返回。
**中介机构关系链路**
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/CcdiIntermediaryEnterpriseRelation.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/dto/CcdiIntermediaryEnterpriseRelationEditDTO.java`
新增中介机构关系编辑入参。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiIntermediaryEnterpriseRelationVO.java`
新增关系列表 / 详情返回。
- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiIntermediaryEnterpriseRelationMapper.java`
新增关系表 Mapper。
- `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiIntermediaryEnterpriseRelationMapper.xml`
新增关系表查询 SQL。
**测试**
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiIntermediaryServiceImplTest.java`
补中介本人、亲属、机构关系和级联删除测试。
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiIntermediaryMapperTest.java`
补首页联合查询 SQL 测试。
- `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiIntermediaryControllerTest.java`
补新增接口和子资源接口测试。
## 实施任务
### Task 1: 建立关系表和固定口径 SQL
**Files:**
- Create: `sql/migration/2026-04-17-create-intermediary-enterprise-relation.sql`
- Create: `sql/migration/2026-04-17-fix-intermediary-person-sub-type-dict.sql`
- Reference: `sql/ccdi_staff_fmy_relation.sql`
- Reference: `sql/menu-intermediary.sql`
- [ ] **Step 1: 梳理当前 `ccdi_biz_intermediary` 对 `person_sub_type` 的实际使用口径**
Run: `rg -n "personSubType|person_sub_type" ccdi-info-collection ruoyi-ui sql -S`
Expected: 能定位现有中介与前端表单对该字段的读写位置。
- [ ] **Step 2: 编写关系表建表 SQL**
`sql/migration/2026-04-17-create-intermediary-enterprise-relation.sql` 中创建:
```sql
CREATE TABLE IF NOT EXISTS `ccdi_intermediary_enterprise_relation` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`intermediary_biz_id` VARCHAR(64) NOT NULL COMMENT '所属中介biz_id',
`social_credit_code` VARCHAR(18) NOT NULL COMMENT '统一社会信用代码',
`relation_person_post` VARCHAR(100) DEFAULT NULL COMMENT '关联角色/职务',
`remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
`created_by` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updated_by` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_intermediary_enterprise` (`intermediary_biz_id`, `social_credit_code`),
KEY `idx_intermediary_biz_id` (`intermediary_biz_id`),
KEY `idx_social_credit_code` (`social_credit_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='中介关联机构关系表';
```
- [ ] **Step 3: 编写 `person_sub_type` 固定值脚本**
`sql/migration/2026-04-17-fix-intermediary-person-sub-type-dict.sql` 中补齐:
```sql
-- 根据实际字典表结构插入 本人 / 配偶 / 子女 / 父母 / 兄弟姐妹 / 其他
```
Expected: 后端和前端都能使用一致的固定值。
- [ ] **Step 4: 人工校对 SQL 字段注释与唯一约束**
Expected: 能明确表达“只删关系,不删机构主档”的边界。
- [ ] **Step 5: 提交 SQL 与计划中的字段口径**
```bash
git add sql/migration/2026-04-17-create-intermediary-enterprise-relation.sql sql/migration/2026-04-17-fix-intermediary-person-sub-type-dict.sql
git commit -m "feat: 新增中介机构关系表脚本"
```
### Task 2: 收敛中介本人与亲属 DTO / VO
**Files:**
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryQueryDTO.java`
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryPersonAddDTO.java`
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryPersonEditDTO.java`
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryRelativeAddDTO.java`
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryRelativeEditDTO.java`
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiIntermediaryVO.java`
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiIntermediaryPersonDetailVO.java`
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiIntermediaryRelativeVO.java`
- [ ] **Step 1: 修改首页查询 DTO**
`CcdiIntermediaryQueryDTO` 调整为:
```java
private String name;
private String certificateNo;
private String recordType;
private String relatedIntermediaryKeyword;
```
- [ ] **Step 2: 收敛中介本人新增 DTO**
`CcdiIntermediaryPersonAddDTO` 仅保留中介本人字段,并在服务层固定写入:
```java
personSubType = "本人";
relatedNumId = null;
```
- [ ] **Step 3: 新增亲属新增 / 编辑 DTO**
亲属 DTO 需要明确:
```java
@NotBlank(message = "亲属关系不能为空")
private String personSubType;
```
并在实现中拒绝 `"本人"`
- [ ] **Step 4: 改造首页统一列表 VO**
`CcdiIntermediaryVO` 收敛为:
```java
private String recordType;
private String recordId;
private String name;
private String certificateNo;
private String relatedIntermediaryName;
private String relationText;
private Date createTime;
```
- [ ] **Step 5: 新增亲属 VO 并整理详情返回**
Expected: 前后端不再复用旧“个人 / 机构并列”字段集合。
- [ ] **Step 6: 提交 DTO / VO 重构**
```bash
git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo
git commit -m "feat: 调整中介本人亲属传输对象"
```
### Task 3: 新增中介机构关系实体与 Mapper
**Files:**
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/CcdiIntermediaryEnterpriseRelation.java`
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryEnterpriseRelationAddDTO.java`
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiIntermediaryEnterpriseRelationEditDTO.java`
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiIntermediaryEnterpriseRelationVO.java`
- Create: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiIntermediaryEnterpriseRelationMapper.java`
- Create: `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiIntermediaryEnterpriseRelationMapper.xml`
- Reference: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/CcdiCustEnterpriseRelation.java`
- Reference: `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiCustEnterpriseRelationMapper.xml`
- [ ] **Step 1: 新建关系实体**
```java
@TableName("ccdi_intermediary_enterprise_relation")
public class CcdiIntermediaryEnterpriseRelation implements Serializable {
@TableId(type = IdType.AUTO)
private Long id;
private String intermediaryBizId;
private String socialCreditCode;
private String relationPersonPost;
private String remark;
}
```
- [ ] **Step 2: 新建关系新增 / 编辑 DTO**
新增 DTO 需要校验:
```java
@NotBlank(message = "统一社会信用代码不能为空")
private String socialCreditCode;
```
- [ ] **Step 3: 新建关系 VO**
VO 需要联查展示:
```java
private Long id;
private String intermediaryBizId;
private String intermediaryName;
private String intermediaryPersonId;
private String socialCreditCode;
private String enterpriseName;
private String relationPersonPost;
private String remark;
private Date createTime;
```
- [ ] **Step 4: 新建 Mapper 与 XML**
需要提供:
```xml
<select id="selectByIntermediaryBizId" ... />
<select id="selectDetailById" ... />
<select id="existsByIntermediaryBizIdAndSocialCreditCode" ... />
```
- [ ] **Step 5: 运行编译验证新链路能被 Spring 扫描**
Run: `mvn -pl ccdi-info-collection -am -DskipTests compile`
Expected: `BUILD SUCCESS`
- [ ] **Step 6: 提交关系表 Java 链路**
```bash
git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/CcdiIntermediaryEnterpriseRelation.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/dto/CcdiIntermediaryEnterpriseRelationEditDTO.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiIntermediaryEnterpriseRelationVO.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiIntermediaryEnterpriseRelationMapper.java ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiIntermediaryEnterpriseRelationMapper.xml
git commit -m "feat: 新增中介机构关系后端链路"
```
### Task 4: 重写首页三类记录联合查询
**Files:**
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiIntermediaryMapper.java`
- Modify: `ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiIntermediaryMapper.xml`
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/vo/CcdiIntermediaryVO.java`
- [ ] **Step 1: 先写 Mapper 测试,锁定三类记录口径**
`CcdiIntermediaryMapperTest` 中至少覆盖:
```java
assertThat(records).extracting("recordType")
.contains("INTERMEDIARY", "RELATIVE", "ENTERPRISE_RELATION");
```
- [ ] **Step 2: 运行测试确认旧 SQL 不满足新断言**
Run: `mvn -pl ccdi-info-collection -am -Dtest=CcdiIntermediaryMapperTest test`
Expected: FAIL原因是旧 SQL 只返回个人 / 机构并列记录。
- [ ] **Step 3: 改写 `CcdiIntermediaryMapper.xml`**
三段 SQL 分别返回统一字段:
```sql
'INTERMEDIARY' AS record_type
'RELATIVE' AS record_type
'ENTERPRISE_RELATION' AS record_type
```
并统一别名为:
```sql
record_id, name, certificate_no, related_intermediary_name, relation_text, create_time
```
- [ ] **Step 4: 加入首页搜索条件**
`relatedIntermediaryKeyword` 同时匹配:
```sql
related_name LIKE ...
OR related_person_id LIKE ...
```
- [ ] **Step 5: 运行测试确认联合查询通过**
Run: `mvn -pl ccdi-info-collection -am -Dtest=CcdiIntermediaryMapperTest test`
Expected: PASS
- [ ] **Step 6: 提交首页联合查询改造**
```bash
git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/mapper/CcdiIntermediaryMapper.java ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiIntermediaryMapper.xml ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiIntermediaryMapperTest.java
git commit -m "feat: 改造中介首页联合查询口径"
```
### Task 5: 实现中介本人、亲属、机构关系服务逻辑
**Files:**
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiIntermediaryService.java`
- 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/domain/CcdiBizIntermediary.java`
- Reference: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiCustEnterpriseRelationServiceImpl.java`
- [ ] **Step 1: 先写服务测试,锁定关键规则**
测试覆盖:
```java
// 新增中介本人固定 personSubType=本人
// 新增亲属时禁止 personSubType=本人
// 删除中介本人会同时删除亲属和机构关系
```
- [ ] **Step 2: 运行服务测试确认旧实现失败**
Run: `mvn -pl ccdi-info-collection -am -Dtest=CcdiIntermediaryServiceImplTest test`
Expected: FAIL原因是旧服务不支持亲属和关系表链路。
- [ ] **Step 3: 扩展服务接口**
新增方法:
```java
List<CcdiIntermediaryRelativeVO> selectRelativeList(String bizId);
int insertRelative(String bizId, CcdiIntermediaryRelativeAddDTO addDTO);
int updateRelative(CcdiIntermediaryRelativeEditDTO editDTO);
int deleteRelativeById(String relativeBizId);
List<CcdiIntermediaryEnterpriseRelationVO> selectEnterpriseRelationList(String bizId);
int insertEnterpriseRelation(String bizId, CcdiIntermediaryEnterpriseRelationAddDTO addDTO);
int updateEnterpriseRelation(CcdiIntermediaryEnterpriseRelationEditDTO editDTO);
int deleteEnterpriseRelationById(Long id);
```
- [ ] **Step 4: 实现中介本人固定口径**
```java
person.setPersonSubType("本人");
person.setRelatedNumId(null);
```
- [ ] **Step 5: 实现亲属校验**
亲属新增 / 编辑时:
```java
if ("本人".equals(addDTO.getPersonSubType())) {
throw new RuntimeException("亲属关系不能为本人");
}
```
- [ ] **Step 6: 实现机构关系校验**
校验:
```java
enterpriseBaseInfoMapper.selectById(socialCreditCode) != null
```
并拦截同一中介重复关系。
- [ ] **Step 7: 实现中介本人级联删除**
```java
bizIntermediaryMapper.deleteById(bizId);
bizIntermediaryMapper.delete(new LambdaQueryWrapper<CcdiBizIntermediary>()
.eq(CcdiBizIntermediary::getRelatedNumId, bizId));
enterpriseRelationMapper.delete(new LambdaQueryWrapper<CcdiIntermediaryEnterpriseRelation>()
.eq(CcdiIntermediaryEnterpriseRelation::getIntermediaryBizId, bizId));
```
- [ ] **Step 8: 运行服务测试确认通过**
Run: `mvn -pl ccdi-info-collection -am -Dtest=CcdiIntermediaryServiceImplTest test`
Expected: PASS
- [ ] **Step 9: 提交服务层改造**
```bash
git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/ICcdiIntermediaryService.java ccdi-info-collection/src/main/java/com/ruoyi/info/collection/service/impl/CcdiIntermediaryServiceImpl.java ccdi-info-collection/src/test/java/com/ruoyi/info/collection/service/CcdiIntermediaryServiceImplTest.java
git commit -m "feat: 实现中介主从结构服务逻辑"
```
### Task 6: 暴露控制器子资源接口
**Files:**
- Modify: `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiIntermediaryController.java`
- Create: `ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiIntermediaryControllerTest.java`
- [ ] **Step 1: 先写控制器测试**
至少覆盖:
```java
GET /ccdi/intermediary/{bizId}/relatives
POST /ccdi/intermediary/{bizId}/relative
GET /ccdi/intermediary/{bizId}/enterprise-relations
POST /ccdi/intermediary/{bizId}/enterprise-relation
```
- [ ] **Step 2: 运行测试确认接口未实现时失败**
Run: `mvn -pl ccdi-info-collection -am -Dtest=CcdiIntermediaryControllerTest test`
Expected: FAIL
- [ ] **Step 3: 补亲属子资源接口**
```java
@GetMapping("/{bizId}/relatives")
@PostMapping("/{bizId}/relative")
@GetMapping("/relative/{relativeBizId}")
@PutMapping("/relative")
@DeleteMapping("/relative/{relativeBizId}")
```
- [ ] **Step 4: 补机构关系子资源接口**
```java
@GetMapping("/{bizId}/enterprise-relations")
@PostMapping("/{bizId}/enterprise-relation")
@GetMapping("/enterprise-relation/{id}")
@PutMapping("/enterprise-relation")
@DeleteMapping("/enterprise-relation/{id}")
```
- [ ] **Step 5: 调整原有中介本人接口注释与语义**
Expected: Swagger 注释不再出现“机构中介新增 / 编辑”旧语义。
- [ ] **Step 6: 运行控制器测试确认通过**
Run: `mvn -pl ccdi-info-collection -am -Dtest=CcdiIntermediaryControllerTest test`
Expected: PASS
- [ ] **Step 7: 提交控制器改造**
```bash
git add ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiIntermediaryController.java ccdi-info-collection/src/test/java/com/ruoyi/info/collection/controller/CcdiIntermediaryControllerTest.java
git commit -m "feat: 新增中介亲属和机构关系接口"
```
### Task 7: 完成整体回归验证
**Files:**
- Modify: `docs/plans/backend/2026-04-17-intermediary-library-refactor-backend-implementation.md`
执行阶段补充真实验证结果。
- [ ] **Step 1: 运行中介模块定向测试**
Run: `mvn -pl ccdi-info-collection -am -Dtest=CcdiIntermediaryServiceImplTest,CcdiIntermediaryMapperTest,CcdiIntermediaryControllerTest test`
Expected: `BUILD SUCCESS`
- [ ] **Step 2: 运行模块编译**
Run: `mvn -pl ccdi-info-collection -am -DskipTests compile`
Expected: `BUILD SUCCESS`
- [ ] **Step 3: 如需验证 SQL使用 UTF-8 脚本执行**
Run: `bin/mysql_utf8_exec.sh sql/migration/2026-04-17-create-intermediary-enterprise-relation.sql`
Expected: 关系表创建成功,无乱码。
- [ ] **Step 4: 记录真实执行结果**
Expected: 文档中补充实际命令和结果,不写假数据。
- [ ] **Step 5: 汇总并提交**
```bash
git add docs/plans/backend/2026-04-17-intermediary-library-refactor-backend-implementation.md
git commit -m "docs: 更新中介库后端实施计划执行结果"
```
## 验证命令
```bash
mvn -pl ccdi-info-collection -am -Dtest=CcdiIntermediaryServiceImplTest,CcdiIntermediaryMapperTest,CcdiIntermediaryControllerTest test
mvn -pl ccdi-info-collection -am -DskipTests compile
bin/mysql_utf8_exec.sh sql/migration/2026-04-17-create-intermediary-enterprise-relation.sql
```
## 完成标准
- `ccdi_intermediary_enterprise_relation` 表与唯一约束创建完成
- 中介本人固定使用 `person_sub_type=本人`
- 亲属使用 `person_sub_type` 表达关系,并通过 `related_num_id` 关联所属中介
- 首页列表统一返回“中介本人 / 亲属 / 机构关系”三类记录
- 中介本人、亲属、机构关系接口链路完整
- 删除中介本人时会删除亲属和机构关系,但不会删除机构主档
- 后端定向测试、编译与 SQL 验证命令已执行并记录真实结果