# 实体库管理设计文档

## 1. 背景

当前仓库已经存在企业主体表 `ccdi_enterprise_base_info`，并且“中介管理”中的实体中介部分已经在复用该表完成部分新增、编辑、详情和导入能力。

本次需求不是新建表，也不是扩展复杂关联能力，而是基于现有企业主体表，单独建设一个“实体库管理”页面，并严格参照“员工信息维护”的实现方式交付完整的新增、查看、编辑、删除、导入能力。

## 2. 目标

建设一套独立的“实体库管理”模块，满足以下要求：

- 页面名称固定为“实体库管理”
- 数据表固定为 `ccdi_enterprise_base_info`
- 功能范围仅包含单表维护，不引入子表或聚合编辑
- 支持新建、查看、编辑、删除、导入
- 页面交互、接口组织、异步导入、失败记录查看方式整体对齐员工信息维护
- `riskLevel`、`entSource` 允许维护，不写死
- 导入时若统一社会信用代码已存在，一律按失败处理，不覆盖更新

## 3. 非目标

- 不改造“中介管理”现有混合页面
- 不在本次中引入企业附属信息子表
- 不在本次中引入员工企业关系、客户企业关系、中介关系联动维护
- 不设计兼容性补丁式方案，不保留中介实体 DTO 命名给新模块复用

## 4. 现状分析

### 4.1 已有基础

仓库中已经存在以下可复用基础：

- 实体表对应领域对象：`CcdiEnterpriseBaseInfo`
- 实体表 Mapper：`CcdiEnterpriseBaseInfoMapper`
- 中介模块中的实体新增、编辑、详情、导入能力
- 员工信息维护的完整单表维护范式：
  - 独立 Controller
  - 独立 DTO / VO / Excel / ImportFailureVO
  - 独立前端页面与 API
  - 异步导入状态轮询
  - 失败记录分页查看

### 4.2 已有问题

当前实体企业数据虽然已经能在中介模块中被部分维护，但存在以下问题：

- 业务语义属于“中介管理”，不等于“实体库管理”
- DTO / VO / Excel 命名与字段口径绑定在 `IntermediaryEntity` 语义上
- 现有实体中介字段未完整覆盖本次需要维护的 `status`、`riskLevel`、`entSource`、`dataSource`
- 页面是中介混合模式，不符合“完全按照员工信息维护方式实现”的要求

因此本次应建设独立模块，而不是继续把“实体库管理”能力挂靠在中介模块之下。

## 5. 方案比较

### 5.1 方案一：新建独立实体库管理模块

做法：

- 新建独立的后端 Controller / Service / DTO / VO / Excel / 导入服务
- 新建独立前端页面、独立 API、独立菜单和权限
- 底层复用 `ccdi_enterprise_base_info`

优点：

- 与“员工信息维护”模式最一致
- 业务语义清晰，后续维护成本最低
- 不会把“实体库管理”和“中介管理”概念揉在一起

缺点：

- 开发量略高于直接复用中介实体代码

### 5.2 方案二：直接复用中介管理中的实体部分

做法：

- 将中介管理中的“实体中介”能力直接暴露为实体库入口

优点：

- 改动少

缺点：

- 模块语义错误
- DTO / VO / 页面命名与业务不一致
- 后续权限、菜单、字段扩展容易混乱

### 5.3 方案三：页面独立，后端继续复用中介实体 DTO / 导入类

做法：

- 页面新建
- 后端尽量套用 `IntermediaryEntity` 的类和导入逻辑

优点：

- 开发速度较快

缺点：

- 代码命名混乱
- 字段口径不完整
- 后续扩展时会继续带来语义污染

### 5.4 结论

采用方案一：新建独立“实体库管理”模块，底层复用 `ccdi_enterprise_base_info`，实现方式全面对齐员工信息维护。

## 6. 总体设计

### 6.1 模块边界

本次实体库管理模块只负责维护 `ccdi_enterprise_base_info` 单表数据，不承担其他关系表维护职责。

### 6.2 后端结构

新增独立链路：

- `CcdiEnterpriseBaseInfoController`
- `ICcdiEnterpriseBaseInfoService`
- `CcdiEnterpriseBaseInfoServiceImpl`
- `CcdiEnterpriseBaseInfoQueryDTO`
- `CcdiEnterpriseBaseInfoAddDTO`
- `CcdiEnterpriseBaseInfoEditDTO`
- `CcdiEnterpriseBaseInfoVO`
- `CcdiEnterpriseBaseInfoExcel`
- `EnterpriseBaseInfoImportFailureVO`
- `ICcdiEnterpriseBaseInfoImportService`
- `CcdiEnterpriseBaseInfoImportServiceImpl`

Mapper 层优先复用现有 `CcdiEnterpriseBaseInfoMapper`，若分页查询或批量导入需要独立 SQL，则在现有 Mapper 基础上补充对应方法。

### 6.3 前端结构

新增独立页面与 API：

- `ruoyi-ui/src/views/ccdiEnterpriseBaseInfo/index.vue`
- `ruoyi-ui/src/api/ccdiEnterpriseBaseInfo.js`

页面交互模式整体对齐员工信息维护：

- 查询表单
- 工具栏按钮
- 数据表格
- 新增/编辑弹窗
- 详情弹窗
- 导入弹窗
- 导入失败记录查看

## 7. 数据口径设计

### 7.1 主键

主键固定为 `socialCreditCode`。

规则如下：

- 新增时必填
- 编辑时不可修改
- 详情、删除、导入去重均以该字段为准

### 7.2 维护字段

本次页面维护字段覆盖 `ccdi_enterprise_base_info` 核心单表字段：

- `socialCreditCode`
- `enterpriseName`
- `enterpriseType`
- `enterpriseNature`
- `industryClass`
- `industryName`
- `establishDate`
- `registerAddress`
- `legalRepresentative`
- `legalCertType`
- `legalCertNo`
- `shareholder1`
- `shareholder2`
- `shareholder3`
- `shareholder4`
- `shareholder5`
- `status`
- `riskLevel`
- `entSource`
- `dataSource`

### 7.3 字段策略

- `riskLevel` 允许查询、展示、编辑、导入
- `entSource` 允许查询、展示、编辑、导入
- `dataSource` 允许查询、展示、编辑、导入
- 不新增动态股东列表，继续保持 `shareholder1-5` 固定字段结构

## 8. 页面设计

### 8.1 查询区

查询条件按员工信息维护的密度设计，包含：

- 企业名称
- 统一社会信用代码
- 企业类型
- 企业性质
- 行业分类
- 经营状态
- 风险等级
- 企业来源

### 8.2 列表区

建议展示列：

- 企业名称
- 统一社会信用代码
- 企业类型
- 企业性质
- 行业分类
- 所属行业
- 法定代表人
- 经营状态
- 风险等级
- 企业来源
- 数据来源
- 创建时间
- 操作

操作列固定为：

- 详情
- 编辑
- 删除

### 8.3 新增/编辑弹窗

交互方式对齐员工信息维护，采用整页弹窗表单。

表单项包含：

- 统一社会信用代码
- 企业名称
- 企业类型
- 企业性质
- 行业分类
- 所属行业
- 成立日期
- 注册地址
- 法定代表人
- 法定代表人证件类型
- 法定代表人证件号码
- 股东1
- 股东2
- 股东3
- 股东4
- 股东5
- 经营状态
- 风险等级
- 企业来源
- 数据来源

其中：

- 新增时 `socialCreditCode` 可填写
- 编辑时 `socialCreditCode` 禁止修改

### 8.4 详情弹窗

详情展示字段与编辑表单保持同口径，采用只读方式展示。

### 8.5 导入交互

导入流程完全对齐员工信息维护：

- 下载模板
- 上传 Excel
- 提交异步导入任务
- 轮询导入状态
- 本地缓存最近一次任务信息
- 导入失败时展示“查看导入失败记录”按钮
- 失败记录支持分页查看

## 9. 接口设计

接口前缀建议统一为 `/ccdi/enterpriseBaseInfo`。

### 9.1 列表查询

- `GET /ccdi/enterpriseBaseInfo/list`

入参为查询 DTO，返回分页表格结构。

### 9.2 详情查询

- `GET /ccdi/enterpriseBaseInfo/{socialCreditCode}`

### 9.3 新增

- `POST /ccdi/enterpriseBaseInfo`

### 9.4 编辑

- `PUT /ccdi/enterpriseBaseInfo`

### 9.5 删除

- `DELETE /ccdi/enterpriseBaseInfo/{socialCreditCodes}`

支持批量删除。

### 9.6 导入模板

- `POST /ccdi/enterpriseBaseInfo/importTemplate`

### 9.7 导入数据

- `POST /ccdi/enterpriseBaseInfo/importData`

### 9.8 查询导入状态

- `GET /ccdi/enterpriseBaseInfo/importStatus/{taskId}`

### 9.9 查询导入失败记录

- `GET /ccdi/enterpriseBaseInfo/importFailures/{taskId}`

## 10. 权限与菜单设计

新增菜单名称固定为“实体库管理”。

建议菜单与权限如下：

- 菜单路径：`enterpriseBaseInfo`
- 组件路径：`ccdiEnterpriseBaseInfo/index`
- 列表权限：`ccdi:enterpriseBaseInfo:list`
- 查询权限：`ccdi:enterpriseBaseInfo:query`
- 新增权限：`ccdi:enterpriseBaseInfo:add`
- 修改权限：`ccdi:enterpriseBaseInfo:edit`
- 删除权限：`ccdi:enterpriseBaseInfo:remove`
- 导入权限：`ccdi:enterpriseBaseInfo:import`

菜单应挂到“信息维护”目录下，方式与员工信息维护等现有业务菜单一致。

## 11. 校验规则

### 11.1 新增/编辑校验

- 企业名称不能为空
- 统一社会信用代码不能为空
- 统一社会信用代码必须符合 18 位社会信用代码格式
- 新增时若数据库中已存在相同统一社会信用代码，则报错
- 编辑时若记录不存在，则报错
- `status`、`riskLevel`、`entSource`、`dataSource` 必须在允许值内
- 其他字段按长度、日期格式做基础校验

### 11.2 导入校验

- Excel 至少包含一条数据
- 企业名称不能为空
- 统一社会信用代码不能为空
- 统一社会信用代码格式必须正确
- 同一导入文件中若统一社会信用代码重复，则该重复记录失败
- 数据库中若已存在相同统一社会信用代码，则该记录失败

## 12. 导入策略

本次导入采用“严格新增”策略，不支持覆盖更新。

即：

- 不提供 `updateSupport` 覆盖更新能力
- 已存在统一社会信用代码的记录直接记为失败
- Excel 内重复记录直接记为失败
- 成功记录批量插入
- 失败记录落 Redis，保留最近任务失败明细查询能力

导入状态结构与员工信息维护保持一致：

- `PROCESSING`
- `SUCCESS`
- `PARTIAL_SUCCESS`

## 13. 错误处理

错误处理遵循现有员工维护风格，使用直接明确的业务提示：

- “该统一社会信用代码已存在”
- “实体信息不存在”
- “至少需要一条数据”
- “任务不存在或已过期”

不引入额外异常框架或复杂回退逻辑。

## 14. 测试设计

### 14.1 后端测试重点

- 列表分页和多条件查询正确
- 详情返回正确
- 新增成功，主键重复时报错
- 编辑成功，编辑不存在记录时报错
- 删除成功
- 导入成功、部分成功、失败状态正确
- 导入失败记录查询正确

### 14.2 前端测试重点

- 查询、重置、分页交互正常
- 新增、详情、编辑、删除链路正常
- 编辑态主键不可修改
- 导入弹窗、状态轮询、失败记录查看正常
- 最近一次导入任务缓存与失败按钮显示逻辑正常
- 权限按钮显示与菜单路由正确

## 15. 实施文档要求

由于本次需求涉及前后端改动，后续实施阶段需按仓库规范输出两份实施计划：

- 后端实施计划：`docs/plans/backend/`
- 前端实施计划：`docs/plans/frontend/`

## 16. 最终结论

本次采用“独立实体库管理模块 + 复用现有企业主体表”的实现方式，以最短路径满足业务目标，同时保证：

- 业务语义清晰
- 代码结构与员工信息维护一致
- `riskLevel`、`entSource`、`dataSource` 均可维护
- 导入严格新增，重复统一社会信用代码直接失败
- 不引入超出需求范围的扩展能力
