diff --git a/docs/design/2026-04-17-intermediary-library-refactor-design.md b/docs/design/2026-04-17-intermediary-library-refactor-design.md new file mode 100644 index 00000000..88320030 --- /dev/null +++ b/docs/design/2026-04-17-intermediary-library-refactor-design.md @@ -0,0 +1,574 @@ +# 中介库主从结构改造设计文档 + +**模块**: 中介库管理 +**日期**: 2026-04-17 +**作者**: Codex +**状态**: 已确认 + +## 一、背景 + +当前中介库模块采用“个人中介 / 机构中介”并列维护方式: + +1. 个人中介数据存放于 `ccdi_biz_intermediary` +2. 机构中介数据直接复用 `ccdi_enterprise_base_info` +3. 前端新增弹窗在“个人 / 机构”之间二选一录入 +4. 首页列表通过联合查询同时展示个人中介与机构中介 + +现业务需求已变更为新的主从维护模式: + +1. 用户先录入中介个人信息 +2. 再在该中介名下录入亲属个人信息 +3. 再在该中介名下录入关联机构关系信息 +4. 关联机构信息只维护“中介与机构的关系”,实体主档仍由实体信息维护功能负责 +5. 首页列表需要统一查询“中介本人 / 中介亲属 / 中介关联机构”三类记录 + +本次设计目标是在尽量复用现有中介库模块基础上,将原并列建模改造为“中介本人主记录 + 亲属子记录 + 机构关系子记录”的结构。 + +## 二、目标 + +本次设计目标如下: + +1. 中介库主记录统一为“中介本人” +2. `ccdi_biz_intermediary` 同时承载中介本人和中介亲属 +3. 新增 `ccdi_intermediary_enterprise_relation` 维护中介与机构的关系 +4. 首页统一展示三类记录,并支持统一查询 +5. 新增流程改为“先新增中介本人,再在详情中维护亲属和关联机构” +6. 保持最短路径实现,不引入额外通用关系模型或平行模块 + +## 三、范围 + +### 3.1 本次范围 + +- 调整中介库数据模型 +- 新增中介关联机构关系表 +- 改造中介库首页联合查询 +- 改造中介新增、详情、亲属维护、关联机构维护交互 +- 调整后端中介、亲属、关联机构关系接口 +- 补充设计文档与实施计划 + +### 3.2 不在本次范围 + +- 不负责录入或修改实体机构主档 +- 不新增机构主档补录兜底逻辑 +- 不做通用人员关系平台化抽象 +- 不新增独立一级菜单拆分为三个平行模块 +- 不扩展导入、导出、异步任务链路 +- 不新增兼容性补丁、降级方案或过度设计 + +## 四、现状分析 + +### 4.1 前端现状 + +当前中介库页面位于: + +- `ruoyi-ui/src/views/ccdiIntermediary/index.vue` +- `ruoyi-ui/src/views/ccdiIntermediary/components/EditDialog.vue` + +现有特点: + +1. 首页列表面向“个人中介 / 机构中介”两类并列记录 +2. 新增弹窗先选择类型,再进入不同表单 +3. 个人中介与机构中介使用不同详情接口 +4. 机构中介可直接在中介库模块中新增与修改 + +这与当前需求存在三个核心偏差: + +1. 主记录不是“中介本人”,而是“个人 / 机构”并列 +2. 没有中介详情下的亲属子列表与机构关系子列表 +3. 首页列表未按“本人 / 亲属 / 机构关系”统一口径展示 + +### 4.2 后端现状 + +当前中介控制器位于: + +- `ccdi-info-collection/src/main/java/com/ruoyi/info/collection/controller/CcdiIntermediaryController.java` + +现有后端特点: + +1. `POST /ccdi/intermediary/person` 新增个人中介 +2. `POST /ccdi/intermediary/entity` 新增机构中介 +3. `GET /ccdi/intermediary/list` 联合查询个人中介与机构中介 +4. 机构中介直接写入 `ccdi_enterprise_base_info` + +这与新需求的偏差在于: + +1. 机构不应再作为中介库主记录新增 +2. 亲属未形成独立子资源模型 +3. 中介与机构之间缺少独立关系表 + +### 4.3 现有可复用基础 + +仓库中已存在以下可参考实现: + +1. `ccdi_staff_fmy_relation` 员工亲属关系维护 +2. `ccdi_staff_enterprise_relation` 员工关联企业维护 +3. `ccdi_cust_enterprise_relation` 客户关联企业维护 + +可复用的思路主要是: + +1. 子资源独立 CRUD +2. 统一列表查询 + 独立编辑弹窗 +3. 关系表联查企业主档展示企业名称 + +但本次不直接照搬上述模块,而是在中介库现有主页面中完成收口。 + +## 五、方案对比 + +### 5.1 方案 A:中介本人为主记录,亲属与机构关系作为子记录 + +做法: + +1. `ccdi_biz_intermediary` 统一存中介本人和中介亲属 +2. 新增 `ccdi_intermediary_enterprise_relation` +3. 首页列表联合查询三类记录 +4. 首页新增只允许新增中介本人 +5. 详情页维护亲属与关联机构 + +优点: + +1. 最贴合当前业务口径 +2. 最大程度复用现有中介库菜单、权限与主页面 +3. 后端改造边界清晰 +4. 前端操作路径与“先建中介,再维护子信息”一致 + +缺点: + +1. 需要重写现有“个人 / 机构并列”的列表语义 +2. 需要补一张新的机构关系表 + +### 5.2 方案 B:拆成中介本人、亲属、机构关系三个平行页面 + +做法: + +1. 中介本人独立页面 +2. 中介亲属独立页面 +3. 中介关联机构独立页面 + +问题: + +1. 与“先建中介,再在下面维护”不一致 +2. 页面、菜单、权限改动面更大 +3. 首页聚合查询与跳转链路更复杂 + +### 5.3 方案 C:抽象统一关系模型 + +做法: + +1. 抽象统一的人员关系与机构关系模型 +2. 中介、员工、客户共用一套关系平台 + +问题: + +1. 抽象过重 +2. 明显超出当前需求 +3. 会引入额外改造面,不符合最短路径原则 + +### 5.4 结论 + +采用 **方案 A:中介本人为主记录,亲属与机构关系作为子记录**。 + +## 六、总体设计 + +### 6.1 设计原则 + +本次设计遵循以下原则: + +1. 中介库只维护中介本人、亲属和中介机构关系 +2. 机构主档继续归实体信息维护功能负责 +3. 不新增无必要的身份字段,优先复用现有字段表达业务含义 +4. 首页统一查询,编辑入口按记录类型分流 +5. 删除中介本人时同时清理亲属与机构关系 + +### 6.2 数据流 + +新增中介链路: + +1. 首页点击新增 +2. 打开中介本人新增弹窗 +3. 保存中介本人到 `ccdi_biz_intermediary` +4. 自动进入中介详情 +5. 在详情中新增亲属与关联机构关系 + +首页查询链路: + +1. 前端调用 `GET /ccdi/intermediary/list` +2. 后端联合查询: + - `ccdi_biz_intermediary` 中 `person_sub_type = 本人` + - `ccdi_biz_intermediary` 中 `person_sub_type != 本人` + - `ccdi_intermediary_enterprise_relation` 联查 `ccdi_enterprise_base_info` +3. 统一返回前端展示字段与 `recordType` + +删除中介链路: + +1. 删除中介本人 +2. 删除本人记录 +3. 删除名下亲属记录 +4. 删除名下关联机构关系记录 +5. 不删除企业主档 + +## 七、数据模型设计 + +### 7.1 `ccdi_biz_intermediary` 使用方式调整 + +`ccdi_biz_intermediary` 继续作为人员表,不新增新的身份字段,直接复用: + +- `person_sub_type` +- `related_num_id` + +字段口径调整如下: + +1. 中介本人 + - `person_sub_type = 本人` + - `related_num_id` 为空 + +2. 中介亲属 + - `person_sub_type = 配偶 / 子女 / 父母 / 兄弟姐妹 / 其他` + - `related_num_id = 所属中介本人的 biz_id` + +因此: + +- `person_sub_type` 负责表达“本人 / 亲属关系” +- `related_num_id` 负责表达“归属到哪个中介本人” + +### 7.2 新增 `ccdi_intermediary_enterprise_relation` + +新增表:`ccdi_intermediary_enterprise_relation` + +建议字段: + +1. `id` BIGINT 主键 +2. `intermediary_biz_id` VARCHAR(64) + 关联中介本人 `biz_id` +3. `social_credit_code` VARCHAR(18) + 关联机构统一社会信用代码 +4. `relation_person_post` VARCHAR(100) + 中介在该机构的关联角色/职务 +5. `remark` VARCHAR(500) +6. `created_by` +7. `create_time` +8. `updated_by` +9. `update_time` + +唯一性约束建议: + +- `uk_intermediary_enterprise (intermediary_biz_id, social_credit_code)` + +说明: + +1. 只维护关系,不维护企业主档 +2. 企业名称通过联查 `ccdi_enterprise_base_info.enterprise_name` 获取 +3. 删除关系时只删该表记录 + +### 7.3 删除规则 + +删除中介本人时: + +1. 删除 `ccdi_biz_intermediary` 中本人记录 +2. 删除 `ccdi_biz_intermediary` 中 `related_num_id = 本人 biz_id` 的亲属记录 +3. 删除 `ccdi_intermediary_enterprise_relation` 中 `intermediary_biz_id = 本人 biz_id` 的全部关系记录 +4. 不删除 `ccdi_enterprise_base_info` + +## 八、首页列表与查询口径 + +### 8.1 列表展示字段 + +首页列表统一展示以下字段: + +1. 名称 +2. 证件号 +3. 关联中介姓名 +4. 关联关系 +5. 创建时间 + +### 8.2 三类记录展示映射 + +1. 中介本人 + - 名称:`name` + - 证件号:`person_id` + - 关联中介姓名:本人姓名 + - 关联关系:`本人` + +2. 中介亲属 + - 名称:`name` + - 证件号:`person_id` + - 关联中介姓名:所属中介本人姓名 + - 关联关系:`person_sub_type` + +3. 关联机构 + - 名称:机构名称 + - 证件号:统一社会信用代码 + - 关联中介姓名:所属中介本人姓名 + - 关联关系:`relation_person_post` + +### 8.3 搜索字段 + +首页搜索字段固定为: + +1. 名称 +2. 证件号 +3. 记录类型 +4. 关联中介信息 + +其中“关联中介信息”为一个合并输入框,同时支持: + +1. 按关联中介姓名查询 +2. 按关联中介证件号查询 + +### 8.4 记录类型 + +联合查询结果中增加派生字段 `recordType`,仅用于前端分流,不落库: + +1. `INTERMEDIARY` +2. `RELATIVE` +3. `ENTERPRISE_RELATION` + +## 九、接口设计 + +### 9.1 中介本人接口 + +保留现有中介主线接口,语义调整为“中介本人”: + +1. `POST /ccdi/intermediary/person` + - 新增中介本人 + - 固定写入: + - `person_sub_type = 本人` + - `related_num_id = null` + +2. `PUT /ccdi/intermediary/person` + - 修改中介本人 + +3. `GET /ccdi/intermediary/person/{bizId}` + - 查询中介本人详情 + +### 9.2 中介亲属接口 + +新增中介名下亲属接口,仍然落 `ccdi_biz_intermediary`: + +1. `GET /ccdi/intermediary/{bizId}/relatives` + - 查询某中介名下亲属列表 + +2. `POST /ccdi/intermediary/{bizId}/relative` + - 新增亲属 + - 固定写入: + - `related_num_id = bizId` + - `person_sub_type != 本人` + +3. `GET /ccdi/intermediary/relative/{relativeBizId}` + - 查询亲属详情 + +4. `PUT /ccdi/intermediary/relative` + - 修改亲属 + +5. `DELETE /ccdi/intermediary/relative/{relativeBizId}` + - 删除亲属 + +### 9.3 中介关联机构关系接口 + +新增关系表对应接口: + +1. `GET /ccdi/intermediary/{bizId}/enterprise-relations` + - 查询某中介名下关联机构列表 + +2. `POST /ccdi/intermediary/{bizId}/enterprise-relation` + - 新增关联机构关系 + +3. `GET /ccdi/intermediary/enterprise-relation/{id}` + - 查询单条机构关系详情 + +4. `PUT /ccdi/intermediary/enterprise-relation` + - 修改机构关系 + +5. `DELETE /ccdi/intermediary/enterprise-relation/{id}` + - 删除机构关系 + +### 9.4 首页联合查询接口 + +保留: + +- `GET /ccdi/intermediary/list` + +返回统一字段: + +1. `recordType` +2. `recordId` +3. `name` +4. `certificateNo` +5. `relatedIntermediaryName` +6. `relationText` +7. `createTime` + +查询条件: + +1. `name` +2. `certificateNo` +3. `recordType` +4. `relatedIntermediaryKeyword` + +其中 `relatedIntermediaryKeyword` 同时匹配: + +1. 关联中介姓名 +2. 关联中介证件号 + +### 9.5 删除接口行为 + +1. 删除中介本人: + - 继续使用中介主删除接口 + - 服务层执行本人、亲属、机构关系级联清理 + +2. 删除亲属: + - 走亲属删除接口 + +3. 删除关联机构: + - 走关联机构关系删除接口 + +## 十、前端页面设计 + +### 10.1 首页页面 + +保留页面: + +- `ruoyi-ui/src/views/ccdiIntermediary/index.vue` + +页面语义调整为“中介综合库”。 + +改造内容: + +1. 搜索区改为新搜索字段 +2. 列表改为三类记录混合展示 +3. 新增按钮只允许新增中介本人 + +### 10.2 列表操作行为 + +1. `recordType = INTERMEDIARY` + - 详情 + - 修改 + - 删除 + +2. `recordType = RELATIVE` + - 详情 / 编辑亲属 + - 删除亲属 + +3. `recordType = ENTERPRISE_RELATION` + - 详情 / 编辑关联机构关系 + - 删除关联关系 + +### 10.3 新增流程 + +首页新增流程固定为: + +1. 点击新增 +2. 打开中介本人新增弹窗 +3. 保存成功 +4. 自动进入该中介详情 +5. 在详情中继续维护亲属与关联机构 + +### 10.4 中介详情页 + +中介本人详情建议改为“大弹窗详情维护页”,包含三个区域: + +1. 中介基本信息 +2. 亲属信息列表 +3. 关联机构信息列表 + +支持在详情中: + +1. 编辑中介本人 +2. 新增 / 编辑 / 删除亲属 +3. 新增 / 编辑 / 删除关联机构关系 + +### 10.5 子记录编辑 + +首页点到亲属或关联机构时: + +1. 直接打开对应编辑弹窗 +2. 弹窗中展示所属中介姓名,只读 +3. 保存成功后刷新首页列表 +4. 如当前已打开中介详情,同时刷新详情内子列表 + +### 10.6 弹窗拆分建议 + +当前 `EditDialog.vue` 同时承担个人和机构两套表单,本次建议拆分为: + +1. 中介本人编辑弹窗 +2. 亲属编辑弹窗 +3. 关联机构关系编辑弹窗 + +如果实现时考虑最短路径,也允许在现有组件上拆成三个分支表单,但从设计上仍以三类用途明确的编辑组件为目标。 + +## 十一、校验与业务规则 + +### 11.1 中介本人 + +1. 新增时固定 `person_sub_type = 本人` +2. `related_num_id` 必须为空 +3. 证件号仍需保持唯一性校验 + +### 11.2 中介亲属 + +1. `person_sub_type` 禁止保存为 `本人` +2. `related_num_id` 必须指向所属中介本人 +3. 首页展示关联关系时直接取 `person_sub_type` + +### 11.3 关联机构关系 + +1. `social_credit_code` 必须存在于实体信息库 +2. 同一中介下不允许重复关联同一统一社会信用代码 +3. 不允许通过中介模块新增机构主档 + +## 十二、数据库与代码改动清单 + +### 12.1 后端 + +预计改动: + +1. `CcdiIntermediaryController` +2. `ICcdiIntermediaryService` +3. `CcdiIntermediaryServiceImpl` +4. 中介相关 DTO / VO +5. 新增中介关联机构关系 domain / DTO / VO / mapper / service / controller +6. `CcdiIntermediaryMapper.xml` +7. 新增机构关系 Mapper XML + +### 12.2 前端 + +预计改动: + +1. `ruoyi-ui/src/views/ccdiIntermediary/index.vue` +2. `SearchForm.vue` +3. `DataTable.vue` +4. `DetailDialog.vue` +5. `EditDialog.vue` 或拆分后的三个编辑组件 +6. `ruoyi-ui/src/api/ccdiIntermediary.js` +7. 新增关联机构关系 API + +### 12.3 SQL + +预计新增: + +1. `ccdi_intermediary_enterprise_relation` 建表脚本 +2. 如需字典补充,再新增对应迁移脚本 + +## 十三、测试要点 + +1. 新增中介本人成功,自动进入详情 +2. 在详情中新增亲属成功,首页能查到亲属记录 +3. 在详情中新增关联机构关系成功,首页能查到关联机构记录 +4. 首页支持按名称、证件号、记录类型、关联中介信息查询 +5. 首页点击亲属记录可直接编辑 +6. 首页点击关联机构记录可直接编辑 +7. 删除中介本人后,亲属记录一并删除 +8. 删除中介本人后,关联机构关系一并删除 +9. 删除中介本人后,机构主档仍保留 +10. 同一中介重复关联同一机构时正确拦截 + +## 十四、结论 + +本次中介库改造采用“中介本人主记录 + 亲属子记录 + 关联机构关系子记录”的主从结构: + +1. `ccdi_biz_intermediary` 负责维护中介本人和亲属 +2. `ccdi_intermediary_enterprise_relation` 负责维护中介与机构的关系 +3. 首页以统一列表展示三类记录 +4. 新增流程固定为“先建中介本人,再维护子信息” +5. 机构主档继续由实体信息维护功能独立负责 + +该方案满足当前需求,并保持了最短路径实现与清晰的前后端边界。