中介类型修改

This commit is contained in:
wkc
2026-01-29 13:39:47 +08:00
parent 2c146c026a
commit 1b043fa2d6
36 changed files with 4373 additions and 145 deletions

View File

@@ -0,0 +1,700 @@
# Design: 增强中介黑名单字段并实现类型化模板导入
## 数据库设计
### 表扩展dpc_intermediary_blacklist
在现有表基础上添加以下字段:
```sql
-- ============================================================
-- 个人类型字段 (以 indiv_ 前缀标识individual 缩写)
-- ============================================================
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `indiv_type` VARCHAR(30) DEFAULT NULL COMMENT '人员类型(中介、职业背债人、房产中介等)';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `indiv_sub_type` VARCHAR(50) DEFAULT NULL COMMENT '人员子类型(本人、配偶等)';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `indiv_gender` CHAR(1) DEFAULT NULL COMMENT '性别M男 F女 O其他';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `indiv_cert_type` VARCHAR(30) DEFAULT '身份证' COMMENT '证件类型';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `indiv_phone` VARCHAR(20) DEFAULT NULL COMMENT '手机号码(加密存储)';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `indiv_wechat` VARCHAR(50) DEFAULT NULL COMMENT '微信号';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `indiv_address` VARCHAR(200) DEFAULT NULL COMMENT '联系地址';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `indiv_company` VARCHAR(100) DEFAULT NULL COMMENT '所在公司';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `indiv_position` VARCHAR(100) DEFAULT NULL COMMENT '职位/职务';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `indiv_related_id` VARCHAR(20) DEFAULT NULL COMMENT '关联人员ID';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `indiv_relation` VARCHAR(50) DEFAULT NULL COMMENT '关联关系';
-- ============================================================
-- 机构类型字段 (以 corp_ 前缀标识corporation 缩写)
-- ============================================================
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_credit_code` VARCHAR(18) DEFAULT NULL COMMENT '统一社会信用代码';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_type` VARCHAR(50) DEFAULT NULL COMMENT '主体类型(有限责任公司、股份有限公司等)';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_nature` VARCHAR(50) DEFAULT NULL COMMENT '企业性质(国企、民企、外企等)';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_industry_category` VARCHAR(100) DEFAULT NULL COMMENT '行业分类';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_industry` VARCHAR(100) DEFAULT NULL COMMENT '所属行业';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_establish_date` DATE DEFAULT NULL COMMENT '成立日期';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_address` VARCHAR(500) DEFAULT NULL COMMENT '注册地址';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_legal_rep` VARCHAR(50) DEFAULT NULL COMMENT '法定代表人';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_legal_cert_type` VARCHAR(30) DEFAULT NULL COMMENT '法定代表人证件类型';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_legal_cert_no` VARCHAR(30) DEFAULT NULL COMMENT '法定代表人证件号码';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_shareholder_1` VARCHAR(30) DEFAULT NULL COMMENT '股东1';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_shareholder_2` VARCHAR(30) DEFAULT NULL COMMENT '股东2';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_shareholder_3` VARCHAR(30) DEFAULT NULL COMMENT '股东3';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_shareholder_4` VARCHAR(30) DEFAULT NULL COMMENT '股东4';
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `corp_shareholder_5` VARCHAR(30) DEFAULT NULL COMMENT '股东5';
-- ============================================================
-- 通用字段
-- ============================================================
ALTER TABLE dpc_intermediary_blacklist ADD COLUMN `data_source` VARCHAR(30) DEFAULT 'MANUAL' COMMENT '数据来源MANUAL手动录入 SYSTEM系统同步 IMPORT批量导入 API接口获取';
```
### 完整表结构
```sql
CREATE TABLE `dpc_intermediary_blacklist` (
`intermediary_id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '中介ID',
-- ============================================================
-- 核心字段(原有)
-- ============================================================
`name` VARCHAR(100) NOT NULL COMMENT '姓名/机构名称',
`certificate_no` VARCHAR(50) DEFAULT NULL COMMENT '证件号',
`intermediary_type` CHAR(1) NOT NULL DEFAULT '1' COMMENT '中介类型1个人 2机构',
`status` CHAR(1) NOT NULL DEFAULT '0' COMMENT '状态0正常 1停用',
`remark` VARCHAR(500) DEFAULT NULL COMMENT '备注',
-- ============================================================
-- 个人类型字段(新增,以 indiv_ 前缀标识)
-- ============================================================
`indiv_type` VARCHAR(30) DEFAULT NULL COMMENT '人员类型',
`indiv_sub_type` VARCHAR(50) DEFAULT NULL COMMENT '人员子类型',
`indiv_gender` CHAR(1) DEFAULT NULL COMMENT '性别M男 F女 O其他',
`indiv_cert_type` VARCHAR(30) DEFAULT '身份证' COMMENT '证件类型',
`indiv_phone` VARCHAR(20) DEFAULT NULL COMMENT '手机号码',
`indiv_wechat` VARCHAR(50) DEFAULT NULL COMMENT '微信号',
`indiv_address` VARCHAR(200) DEFAULT NULL COMMENT '联系地址',
`indiv_company` VARCHAR(100) DEFAULT NULL COMMENT '所在公司',
`indiv_position` VARCHAR(100) DEFAULT NULL COMMENT '职位/职务',
`indiv_related_id` VARCHAR(20) DEFAULT NULL COMMENT '关联人员ID',
`indiv_relation` VARCHAR(50) DEFAULT NULL COMMENT '关联关系',
-- ============================================================
-- 机构类型字段(新增,以 corp_ 前缀标识)
-- ============================================================
`corp_credit_code` VARCHAR(18) DEFAULT NULL COMMENT '统一社会信用代码',
`corp_type` VARCHAR(50) DEFAULT NULL COMMENT '主体类型',
`corp_nature` VARCHAR(50) DEFAULT NULL COMMENT '企业性质',
`corp_industry_category` VARCHAR(100) DEFAULT NULL COMMENT '行业分类',
`corp_industry` VARCHAR(100) DEFAULT NULL COMMENT '所属行业',
`corp_establish_date` DATE DEFAULT NULL COMMENT '成立日期',
`corp_address` VARCHAR(500) DEFAULT NULL COMMENT '注册地址',
`corp_legal_rep` VARCHAR(50) DEFAULT NULL COMMENT '法定代表人',
`corp_legal_cert_type` VARCHAR(30) DEFAULT NULL COMMENT '法定代表人证件类型',
`corp_legal_cert_no` VARCHAR(30) DEFAULT NULL COMMENT '法定代表人证件号码',
`corp_shareholder_1` VARCHAR(30) DEFAULT NULL COMMENT '股东1',
`corp_shareholder_2` VARCHAR(30) DEFAULT NULL COMMENT '股东2',
`corp_shareholder_3` VARCHAR(30) DEFAULT NULL COMMENT '股东3',
`corp_shareholder_4` VARCHAR(30) DEFAULT NULL COMMENT '股东4',
`corp_shareholder_5` VARCHAR(30) DEFAULT NULL COMMENT '股东5',
-- ============================================================
-- 通用字段(新增)
-- ============================================================
`data_source` VARCHAR(30) DEFAULT 'MANUAL' COMMENT '数据来源',
-- ============================================================
-- 审计字段(原有)
-- ============================================================
`create_by` VARCHAR(64) DEFAULT '' COMMENT '创建者',
`create_time` DATETIME DEFAULT NULL COMMENT '创建时间',
`update_by` VARCHAR(64) DEFAULT '' COMMENT '更新者',
`update_time` DATETIME DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`intermediary_id`),
KEY `idx_name` (`name`),
KEY `idx_certificate_no` (`certificate_no`),
KEY `idx_intermediary_type` (`intermediary_type`),
KEY `idx_corp_credit_code` (`corp_credit_code`),
KEY `idx_indiv_phone` (`indiv_phone`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='中介人员黑名单表';
```
### 新增字段说明
| 字段名 | 类型 | 说明 | 适用类型 | 必填 | 默认值 |
|-------|------|------|---------|-----|-------|
| indiv_type | VARCHAR(30) | 人员类型(中介、职业背债人等) | 个人 | 否 | NULL |
| indiv_sub_type | VARCHAR(50) | 人员子类型(本人、配偶等) | 个人 | 否 | NULL |
| indiv_gender | CHAR(1) | 性别M男 F女 O其他 | 个人 | 否 | NULL |
| indiv_cert_type | VARCHAR(30) | 证件类型 | 个人 | 否 | 身份证 |
| indiv_phone | VARCHAR(20) | 手机号码 | 个人 | 否 | NULL |
| indiv_wechat | VARCHAR(50) | 微信号 | 个人 | 否 | NULL |
| indiv_address | VARCHAR(200) | 联系地址 | 个人 | 否 | NULL |
| indiv_company | VARCHAR(100) | 所在公司 | 个人 | 否 | NULL |
| indiv_position | VARCHAR(100) | 职位/职务 | 个人 | 否 | NULL |
| indiv_related_id | VARCHAR(20) | 关联人员ID | 个人 | 否 | NULL |
| indiv_relation | VARCHAR(50) | 关联关系 | 个人 | 否 | NULL |
| corp_credit_code | VARCHAR(18) | 统一社会信用代码 | 机构 | 否 | NULL |
| corp_type | VARCHAR(50) | 主体类型 | 机构 | 否 | NULL |
| corp_nature | VARCHAR(50) | 企业性质 | 机构 | 否 | NULL |
| corp_industry_category | VARCHAR(100) | 行业分类 | 机构 | 否 | NULL |
| corp_industry | VARCHAR(100) | 所属行业 | 机构 | 否 | NULL |
| corp_establish_date | DATE | 成立日期 | 机构 | 否 | NULL |
| corp_address | VARCHAR(500) | 注册地址 | 机构 | 否 | NULL |
| corp_legal_rep | VARCHAR(50) | 法定代表人 | 机构 | 否 | NULL |
| corp_legal_cert_type | VARCHAR(30) | 法定代表人证件类型 | 机构 | 否 | NULL |
| corp_legal_cert_no | VARCHAR(30) | 法定代表人证件号码 | 机构 | 否 | NULL |
| corp_shareholder_1 | VARCHAR(30) | 股东1 | 机构 | 否 | NULL |
| corp_shareholder_2 | VARCHAR(30) | 股东2 | 机构 | 否 | NULL |
| corp_shareholder_3 | VARCHAR(30) | 股东3 | 机构 | 否 | NULL |
| corp_shareholder_4 | VARCHAR(30) | 股东4 | 机构 | 否 | NULL |
| corp_shareholder_5 | VARCHAR(30) | 股东5 | 机构 | 否 | NULL |
| data_source | VARCHAR(30) | 数据来源 | 全部 | 否 | MANUAL |
**字段命名规则:**
- **个人字段**:统一使用 `indiv_` 前缀individual 缩写),便于快速识别
- **机构字段**:统一使用 `corp_` 前缀corporation 缩写),便于快速识别
- **通用字段**:无前缀,适用于所有类型
## 后端设计
### 模块结构
```
ruoyi-dpc/
├── src/main/java/com/ruoyi/dpc/
│ ├── controller/
│ │ └── DpcIntermediaryBlacklistController.java (修改)
│ ├── domain/
│ │ ├── DpcIntermediaryBlacklist.java (修改 - 添加新字段)
│ │ ├── dto/
│ │ │ ├── DpcIntermediaryBlacklistAddDTO.java (保留 - 兼容)
│ │ │ ├── DpcIntermediaryBlacklistEditDTO.java (保留 - 兼容)
│ │ │ ├── DpcIntermediaryBlacklistQueryDTO.java (保留)
│ │ │ ├── DpcIntermediaryPersonAddDTO.java (新增)
│ │ │ └── DpcIntermediaryEntityAddDTO.java (新增)
│ │ ├── vo/
│ │ │ ├── DpcIntermediaryBlacklistVO.java (保留 - 列表用)
│ │ │ ├── DpcIntermediaryPersonDetailVO.java (新增)
│ │ │ └── DpcIntermediaryEntityDetailVO.java (新增)
│ │ └── excel/
│ │ ├── DpcIntermediaryBlacklistExcel.java (保留 - 通用模板)
│ │ ├── DpcIntermediaryPersonExcel.java (新增)
│ │ └── DpcIntermediaryEntityExcel.java (新增)
│ ├── mapper/
│ │ └── DpcIntermediaryBlacklistMapper.java
│ └── service/
│ ├── IDpcIntermediaryBlacklistService.java (修改接口)
│ └── impl/
│ └── DpcIntermediaryBlacklistServiceImpl.java (修改实现)
└── src/main/resources/mapper/dpc/
└── DpcIntermediaryBlacklistMapper.xml
```
### Controller 层设计
**新增接口:**
```java
@RestController
@RequestMapping("/dpc/intermediary")
public class DpcIntermediaryBlacklistController extends BaseController {
// ... 现有接口保持不变 ...
/**
* 下载个人中介导入模板(带字典下拉框)
*/
@Operation(summary = "下载个人中介导入模板")
@PostMapping("/importPersonTemplate")
public void importPersonTemplate(HttpServletResponse response) {
EasyExcelUtil.importTemplateWithDictDropdown(
response,
DpcIntermediaryPersonExcel.class,
"个人中介黑名单"
);
}
/**
* 下载机构中介导入模板(带字典下拉框)
*/
@Operation(summary = "下载机构中介导入模板")
@PostMapping("/importEntityTemplate")
public void importEntityTemplate(HttpServletResponse response) {
EasyExcelUtil.importTemplateWithDictDropdown(
response,
DpcIntermediaryEntityExcel.class,
"机构中介黑名单"
);
}
/**
* 导入个人中介黑名单
*/
@Operation(summary = "导入个人中介黑名单")
@PreAuthorize("@ss.hasPermi('dpc:intermediary:import')")
@Log(title = "中介黑名单", businessType = BusinessType.IMPORT)
@PostMapping("/importPersonData")
public AjaxResult importPersonData(MultipartFile file, boolean updateSupport) throws Exception {
List<DpcIntermediaryPersonExcel> list = EasyExcelUtil.importExcel(
file.getInputStream(), DpcIntermediaryPersonExcel.class);
String message = intermediaryService.importPersonIntermediary(list, updateSupport);
return success(message);
}
/**
* 导入机构中介黑名单
*/
@Operation(summary = "导入机构中介黑名单")
@PreAuthorize("@ss.hasPermi('dpc:intermediary:import')")
@Log(title = "中介黑名单", businessType = BusinessType.IMPORT)
@PostMapping("/importEntityData")
public AjaxResult importEntityData(MultipartFile file, boolean updateSupport) throws Exception {
List<DpcIntermediaryEntityExcel> list = EasyExcelUtil.importExcel(
file.getInputStream(), DpcIntermediaryEntityExcel.class);
String message = intermediaryService.importEntityIntermediary(list, updateSupport);
return success(message);
}
}
```
### Service 层设计
**接口扩展:**
```java
public interface IDpcIntermediaryBlacklistService {
// ... 现有方法保持不变 ...
/**
* 根据中介类型获取详情(返回不同类型)
*/
Object selectIntermediaryDetailById(Long intermediaryId);
/**
* 导入个人中介数据
*/
String importPersonIntermediary(List<DpcIntermediaryPersonExcel> list, boolean isUpdateSupport);
/**
* 导入机构中介数据
*/
String importEntityIntermediary(List<DpcIntermediaryEntityExcel> list, boolean isUpdateSupport);
}
```
### Excel 类设计
**使用 @DictDropdown 注解实现字典下拉框**
项目已有现成的字典下拉框功能,详见:[doc/EasyExcel字典下拉框使用说明.md](../../../doc/EasyExcel字典下拉框使用说明.md)
**个人中介 Excel 类:**
```java
@Data
public class DpcIntermediaryPersonExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@ExcelProperty(value = "姓名", index = 0)
@ColumnWidth(15)
private String name;
@ExcelProperty(value = "人员类型", index = 1)
@ColumnWidth(15)
private String indivType; // 对应 indiv_type
@ExcelProperty(value = "人员子类型", index = 2)
@ColumnWidth(15)
private String indivSubType; // 对应 indiv_sub_type
@ExcelProperty(value = "性别", index = 3)
@ColumnWidth(10)
@DictDropdown(dictType = "dpc_indiv_gender")
private String indivGender; // 对应 indiv_gender字典下拉框男/女/其他
@ExcelProperty(value = "证件类型", index = 4)
@ColumnWidth(15)
@DictDropdown(dictType = "dpc_certificate_type")
private String indivCertType; // 对应 indiv_cert_type字典下拉框身份证/护照/港澳通行证/台胞证/军官证
@ExcelProperty(value = "证件号码", index = 5)
@ColumnWidth(20)
private String certificateNo;
@ExcelProperty(value = "手机号码", index = 6)
@ColumnWidth(15)
private String indivPhone; // 对应 indiv_phone
@ExcelProperty(value = "微信号", index = 7)
@ColumnWidth(15)
private String indivWechat; // 对应 indiv_wechat
@ExcelProperty(value = "联系地址", index = 8)
@ColumnWidth(30)
private String indivAddress; // 对应 indiv_address
@ExcelProperty(value = "所在公司", index = 9)
@ColumnWidth(20)
private String indivCompany; // 对应 indiv_company
@ExcelProperty(value = "职位", index = 10)
@ColumnWidth(15)
private String indivPosition; // 对应 indiv_position
@ExcelProperty(value = "关联人员ID", index = 11)
@ColumnWidth(15)
private String indivRelatedId; // 对应 indiv_related_id
@ExcelProperty(value = "关联关系", index = 12)
@ColumnWidth(15)
private String indivRelation; // 对应 indiv_relation
@ExcelProperty(value = "备注", index = 13)
@ColumnWidth(30)
private String remark;
// 以下字段不在 Excel 中显示,由系统自动设置
// private String status; // 默认正常0
// private String dataSource; // 默认批量导入IMPORT
}
```
**机构中介 Excel 类:**
```java
@Data
public class DpcIntermediaryEntityExcel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
@ExcelProperty(value = "机构名称", index = 0)
@ColumnWidth(25)
private String name;
@ExcelProperty(value = "统一社会信用代码", index = 1)
@ColumnWidth(20)
private String corpCreditCode; // 对应 corp_credit_code
@ExcelProperty(value = "主体类型", index = 2)
@ColumnWidth(20)
@DictDropdown(dictType = "dpc_entity_type")
private String corpType; // 对应 corp_type字典下拉框有限责任公司/股份有限公司/合伙企业/个体工商户/外资企业
@ExcelProperty(value = "企业性质", index = 3)
@ColumnWidth(15)
@DictDropdown(dictType = "dpc_enterprise_nature")
private String corpNature; // 对应 corp_nature字典下拉框国企/民企/外企/合资/其他
@ExcelProperty(value = "行业分类", index = 4)
@ColumnWidth(15)
private String corpIndustryCategory; // 对应 corp_industry_category
@ExcelProperty(value = "所属行业", index = 5)
@ColumnWidth(15)
private String corpIndustry; // 对应 corp_industry
@ExcelProperty(value = "成立日期", index = 6)
@ColumnWidth(15)
private String corpEstablishDate; // 对应 corp_establish_date
@ExcelProperty(value = "注册地址", index = 7)
@ColumnWidth(40)
private String corpAddress; // 对应 corp_address
@ExcelProperty(value = "法定代表人", index = 8)
@ColumnWidth(15)
private String corpLegalRep; // 对应 corp_legal_rep
@ExcelProperty(value = "法定代表人证件类型", index = 9)
@ColumnWidth(20)
private String corpLegalCertType; // 对应 corp_legal_cert_type
@ExcelProperty(value = "法定代表人证件号码", index = 10)
@ColumnWidth(20)
private String corpLegalCertNo; // 对应 corp_legal_cert_no
@ExcelProperty(value = "股东1", index = 11)
@ColumnWidth(15)
private String corpShareholder1; // 对应 corp_shareholder_1
@ExcelProperty(value = "股东2", index = 12)
@ColumnWidth(15)
private String corpShareholder2; // 对应 corp_shareholder_2
@ExcelProperty(value = "股东3", index = 13)
@ColumnWidth(15)
private String corpShareholder3; // 对应 corp_shareholder_3
@ExcelProperty(value = "股东4", index = 14)
@ColumnWidth(15)
private String corpShareholder4; // 对应 corp_shareholder_4
@ExcelProperty(value = "股东5", index = 15)
@ColumnWidth(15)
private String corpShareholder5; // 对应 corp_shareholder_5
@ExcelProperty(value = "备注", index = 16)
@ColumnWidth(30)
private String remark;
// 以下字段不在 Excel 中显示,由系统自动设置
// private String status; // 默认正常0
// private String dataSource; // 默认批量导入IMPORT
}
```
### VO 设计
**个人详情 VO**
```java
@Data
public class DpcIntermediaryPersonDetailVO implements Serializable {
// 核心字段
private Long intermediaryId;
private String name;
private String certificateNo;
private String intermediaryType;
private String intermediaryTypeName;
private String status;
private String statusName;
private String remark;
private String dataSource;
// 个人专属字段(使用 indiv_ 前缀)
private String indivType; // 人员类型
private String indivSubType; // 人员子类型
private String indivGender; // 性别
private String indivGenderName; // 性别名称
private String indivCertType; // 证件类型
private String indivPhone; // 手机号码
private String indivWechat; // 微信号
private String indivAddress; // 联系地址
private String indivCompany; // 所在公司
private String indivPosition; // 职位/职务
private String indivRelatedId; // 关联人员ID
private String indivRelation; // 关联关系
// 审计字段
private String createBy;
private Date createTime;
private String updateBy;
private Date updateTime;
}
```
**机构详情 VO**
```java
@Data
public class DpcIntermediaryEntityDetailVO implements Serializable {
// 核心字段
private Long intermediaryId;
private String name;
private String certificateNo;
private String intermediaryType;
private String intermediaryTypeName;
private String status;
private String statusName;
private String remark;
private String dataSource;
// 机构专属字段(使用 corp_ 前缀)
private String corpCreditCode; // 统一社会信用代码
private String corpType; // 主体类型
private String corpNature; // 企业性质
private String corpIndustryCategory; // 行业分类
private String corpIndustry; // 所属行业
private String corpEstablishDate; // 成立日期
private String corpAddress; // 注册地址
private String corpLegalRep; // 法定代表人
private String corpLegalCertType; // 法定代表人证件类型
private String corpLegalCertNo; // 法定代表人证件号码
private String corpShareholder1; // 股东1
private String corpShareholder2; // 股东2
private String corpShareholder3; // 股东3
private String corpShareholder4; // 股东4
private String corpShareholder5; // 股东5
// 审计字段
private String createBy;
private Date createTime;
private String updateBy;
private Date updateTime;
}
```
## Excel 导入导出设计
### Excel 下拉框配置
为提高数据录入的准确性和一致性,以下字段在 Excel 模板中配置下拉框验证:
#### 个人中介模板下拉框
| 列名 | 下拉框选项 | 说明 |
|------|-----------|------|
| 性别 | 男, 女, 其他 | 对应值M, F, O |
| 证件类型 | 身份证, 护照, 港澳通行证, 台胞证, 军官证 | 从字典 dpc_certificate_type 加载 |
#### 机构中介模板下拉框
| 列名 | 下拉框选项 | 说明 |
|------|-----------|------|
| 主体类型 | 有限责任公司, 股份有限公司, 合伙企业, 个体工商户, 外资企业 | 从字典 dpc_entity_type 加载 |
| 企业性质 | 国企, 民企, 外企, 合资, 其他 | 从字典 dpc_enterprise_nature 加载 |
**注意**
- **状态字段**:不在 Excel 模板中显示,导入时默认设置为"正常"0
- **数据来源字段**:不在 Excel 模板中显示,导入时默认设置为"批量导入"IMPORT
#### 下拉框实现方式
使用项目现有的 `@DictDropdown` 注解功能,详见:[doc/EasyExcel字典下拉框使用说明.md](../../../doc/EasyExcel字典下拉框使用说明.md)
**核心组件:**
- `@DictDropdown` 注解:`com.ruoyi.common.annotation.DictDropdown`
- `DictDropdownWriteHandler` 处理器:`com.ruoyi.dpc.handler.DictDropdownWriteHandler`
- `EasyExcelUtil.importTemplateWithDictDropdown()``com.ruoyi.dpc.utils.EasyExcelUtil`
**实现步骤:**
1. 在 Excel 类的对应字段上添加 `@DictDropdown(dictType = "字典类型")` 注解
2. 在若依系统中配置对应的字典数据
3. 使用 `EasyExcelUtil.importTemplateWithDictDropdown()` 生成模板
4. 系统自动从 Redis 缓存读取字典数据并生成下拉框
**优势:**
- 无需手动编写下拉框处理器代码
- 字典数据统一管理,维护方便
- 支持大量下拉选项(自动使用隐藏 Sheet
- 下拉选项可动态更新
### 个人中介模板格式
| 姓名 | 人员类型 | 人员子类型 | 性别▼ | 证件类型▼ | 证件号码 | 手机号码 | 微信号 | 联系地址 | 所在公司 | 职位 | 关联人员ID | 关联关系 | 备注 |
|------|---------|-----------|-------|-----------|---------|---------|--------|---------|---------|-----|-----------|---------|------|
| 张三 | 中介 | 本人 | 男 | 身份证 | 110101199001011234 | 13800138000 | zhangsan | 北京市朝阳区 | XX公司 | 经纪人 | - | - | 测试 |
**注:带 ▼ 标记的列包含下拉框;状态默认为"正常",数据来源默认为"批量导入"**
### 机构中介模板格式
| 机构名称 | 统一社会信用代码 | 主体类型▼ | 企业性质▼ | 行业分类 | 所属行业 | 成立日期 | 注册地址 | 法定代表人 | 法定代表人证件类型 | 法定代表人证件号码 | 股东1 | 股东2 | 股东3 | 股东4 | 股东5 | 备注 |
|---------|-----------------|-----------|-----------|---------|---------|---------|---------|-----------|-------------------|-------------------|-------|-------|-------|-------|-------|------|
| XX中介公司 | 91110000XXXXXXXXXX | 有限责任公司 | 民企 | 房地产 | 房地产业 | 2020-01-01 | 北京市朝阳区 | 张三 | 身份证 | 110101199001011234 | 李四 | 王五 | - | - | - | - |
**注:带 ▼ 标记的列包含下拉框;状态默认为"正常",数据来源默认为"批量导入"**
### 导入数据验证规则
**个人中介验证规则:**
1. **姓名**:必填,长度 1-50 字符
2. **证件号码**:必填,长度不超过 30 字符
3. **证件类型**:选填,默认"身份证"
4. **其他字段**:选填,按长度限制验证
5. **状态**:系统默认设置为"正常"0
6. **数据来源**:系统默认设置为"批量导入"IMPORT
**机构中介验证规则:**
1. **机构名称**:必填,长度 1-200 字符
2. **统一社会信用代码**选填18 位
3. **其他字段**:选填,按长度限制验证
4. **状态**:系统默认设置为"正常"0
5. **数据来源**:系统默认设置为"批量导入"IMPORT
## 字典数据设计
### 人员类型dpc_person_type
| 字典值 | 字典标签 | 排序 | 状态 |
|-------|---------|-----|------|
| 中介 | 中介 | 1 | 正常 |
| 职业背债人 | 职业背债人 | 2 | 正常 |
| 房产中介 | 房产中介 | 3 | 正常 |
### 人员子类型dpc_person_sub_type
| 字典值 | 字典标签 | 排序 | 状态 |
|-------|---------|-----|------|
| 本人 | 本人 | 1 | 正常 |
| 配偶 | 配偶 | 2 | 正常 |
| 子女 | 子女 | 3 | 正常 |
| 其他 | 其他 | 9 | 正常 |
### 证件类型dpc_certificate_type
| 字典值 | 字典标签 | 排序 | 状态 |
|-------|---------|-----|------|
| 身份证 | 身份证 | 1 | 正常 |
| 护照 | 护照 | 2 | 正常 |
| 港澳通行证 | 港澳通行证 | 3 | 正常 |
| 台胞证 | 台胞证 | 4 | 正常 |
| 军官证 | 军官证 | 5 | 正常 |
### 主体类型dpc_entity_type
| 字典值 | 字典标签 | 排序 | 状态 |
|-------|---------|-----|------|
| 有限责任公司 | 有限责任公司 | 1 | 正常 |
| 股份有限公司 | 股份有限公司 | 2 | 正常 |
| 合伙企业 | 合伙企业 | 3 | 正常 |
| 个体工商户 | 个体工商户 | 4 | 正常 |
| 外资企业 | 外资企业 | 5 | 正常 |
### 企业性质dpc_enterprise_nature
| 字典值 | 字典标签 | 排序 | 状态 |
|-------|---------|-----|------|
| 国企 | 国企 | 1 | 正常 |
| 民企 | 民企 | 2 | 正常 |
| 外企 | 外企 | 3 | 正常 |
| 合资 | 合资 | 4 | 正常 |
| 其他 | 其他 | 9 | 正常 |
### 数据来源dpc_data_source
| 字典值 | 字典标签 | 排序 | 状态 |
|-------|---------|-----|------|
| MANUAL | 手动录入 | 1 | 正常 |
| SYSTEM | 系统同步 | 2 | 正常 |
| IMPORT | 批量导入 | 3 | 正常 |
| API | 接口获取 | 4 | 正常 |
## 技术约束
1. **后端框架**Spring Boot 3.5.8
2. **ORM 框架**MyBatis Plus 3.5.10
3. **Excel 处理**EasyExcel
4. **数据库**MySQL 8.2.0
5. **字符编码**UTF-8utf8mb4
6. **向后兼容**:保持现有接口和数据结构不变
## 工具类使用
### EasyExcelUtil 现有方法
项目已有 `EasyExcelUtil.importTemplateWithDictDropdown()` 方法,可直接使用:
```java
// 生成个人中介模板(带字典下拉框)
EasyExcelUtil.importTemplateWithDictDropdown(
response,
DpcIntermediaryPersonExcel.class,
"个人中介黑名单"
);
// 生成机构中介模板(带字典下拉框)
EasyExcelUtil.importTemplateWithDictDropdown(
response,
DpcIntermediaryEntityExcel.class,
"机构中介黑名单"
);
```
**参考文档:** [doc/EasyExcel字典下拉框使用说明.md](../../../doc/EasyExcel字典下拉框使用说明.md)

View File

@@ -0,0 +1,144 @@
# Proposal: 增强中介黑名单字段并实现类型化模板导入
## Change ID
`enhance-intermediary-with-detailed-fields`
## Summary
增强中介黑名单功能,添加个人和机构类型的详细字段,实现类型化的模板下载和导入功能,并添加详情展示接口,根据中介类型展示不同的字段信息。
## Motivation
目前中介黑名单功能存在以下问题:
1. 字段过于简单,只有基础的姓名/机构名称、证件号、中介类型、状态、备注
2. 无法区分个人和机构的不同信息需求
3. 只有一个通用的导入模板,无法满足不同类型的详细数据录入
4. 缺少详情展示接口,无法查看完整的个人或机构信息
业务需求:
1. 个人中介需要记录:人员类型、性别、证件类型、手机号码、微信号、联系地址、所在公司、职位、关联关系等详细信息
2. 机构中介需要记录:统一社会信用代码、主体类型、企业性质、行业分类、成立日期、注册地址、法定代表人、股东等详细信息
3. 需要分开的个人和机构导入模板,便于用户分别录入不同类型的数据
4. 需要详情接口展示完整的个人或机构信息
## Scope
本提案实现以下功能:
### 包含的功能
- **1.1 数据库字段扩展**
- 为个人类型添加详细字段(人员类型、性别、证件类型、手机号码、微信号等)
- 为机构类型添加详细字段(统一社会信用代码、主体类型、企业性质、法定代表人、股东等)
- 保持现有字段的向后兼容性
- **1.2 模板下载功能增强**
- 个人中介模板下载(包含个人专属字段)
- 机构中介模板下载(包含机构专属字段)
- **1.3 导入功能增强**
- 支持个人中介批量导入
- 支持机构中介批量导入
- 根据模板类型自动识别中介类型
- **1.4 详情展示接口**
- 根据中介类型返回不同的字段信息
- 个人类型返回个人详细字段
- 机构类型返回机构详细字段
- **1.5 列表接口优化**
- 保持列表接口简洁,只显示核心字段
- 支持按新增字段进行筛选
### 明确排除
- 前端页面的修改(后续独立变更)
- 数据迁移脚本(旧数据保持原样,新字段可为空)
## Proposed Design
详见 [design.md](./design.md)
## Alternatives Considered
### 选项1分表存储个人表和机构表分离
**优点**
- 字段分离清晰
- 查询性能可能更好(表更小)
**缺点**
- 需要维护多个表和关联关系
- 列表查询需要联合查询
- 导入导出逻辑复杂化
- 不符合现有设计思路
**决定**:不采用。单表设计更简洁,通过中介类型区分即可满足需求。
### 选项2使用 JSON 字段存储扩展信息
**优点**
- 灵活性高,易于扩展
- 不需要修改表结构
**缺点**
- 不利于按扩展字段查询和筛选
- 不利于数据验证和约束
- 导入导出逻辑复杂
**决定**:不采用。使用独立的字段更有利于数据管理和查询。
### 选项3在现有基础上添加字段
**优点**
- 保持向后兼容
- 实现简单直接
**缺点**
- 表会有很多字段约40+个)
- 个人和机构字段混在一起
**决定**:采用。这是最直接的方案,通过业务逻辑区分使用哪些字段,数据库层面允许字段为空。
## Impact
### 后端影响
- **数据库**:扩展 `dpc_intermediary_blacklist`添加约30个新字段
- **实体类**`DpcIntermediaryBlacklist` 添加新字段属性
- **DTO**:创建 `DpcIntermediaryPersonAddDTO``DpcIntermediaryEntityAddDTO`
- **VO**:创建 `DpcIntermediaryPersonDetailVO``DpcIntermediaryEntityDetailVO`
- **Excel**:创建 `DpcIntermediaryPersonExcel``DpcIntermediaryEntityExcel`
- **Controller**:添加两个模板下载接口,修改详情接口
- **Service**:扩展导入逻辑,支持不同类型的模板
### 前端影响
- API 接口变更:需要调用新的模板下载接口和详情接口
- 详情页面需要根据类型显示不同字段
### 数据库影响
- 扩展现有表,添加新字段(默认允许 NULL保持向后兼容
## Dependencies
- 依赖现有 `dpc_intermediary_blacklist` 表和基础功能
- 依赖 EasyExcel 进行 Excel 导入导出
## Related Changes
- `add-intermediary-blacklist` - 基础中介黑名单功能
## Open Questions
1. **旧数据处理**
- 现有数据如何处理?
- 建议:保持不变,新字段为空,用户可后续编辑补充
2. **必填字段**
- 新增字段哪些设为必填?
- 建议:除核心字段外,新字段都设为可选,便于分阶段完善数据
3. **详情接口设计**
- 是分开的两个接口还是一个接口根据类型返回不同 VO
- 建议:一个接口,根据中介类型返回不同的 VO 结构
## Success Criteria
- [ ] 数据库表扩展完成,添加个人和机构的详细字段
- [ ] 可以下载个人中介专用导入模板
- [ ] 可以下载机构中介专用导入模板
- [ ] 可以使用个人模板批量导入个人中介数据
- [ ] 可以使用机构模板批量导入机构中介数据
- [ ] 详情接口根据类型返回完整的字段信息
- [ ] 现有功能保持正常运行,向后兼容
## References
- [doc/中介人员信息表.csv](../../../doc/中介人员信息表.csv)
- [doc/中介主体信息表.csv](../../../doc/中介主体信息表.csv)
- [现有中介黑名单设计](../add-intermediary-blacklist/design.md)

View File

@@ -0,0 +1,181 @@
# Spec: 中介黑名单详细字段与类型化导入
## ADDED Requirements
### Requirement: 支持个人和机构类型的不同字段存储
系统必须能够为个人和机构类型的中介存储不同的字段信息,所有新增字段默认为可选,以保持向后兼容性。
#### Scenario: 个人中介存储详细信息
**Given** 用户创建或编辑个人类型的中介
**When** 填写个人专属字段(人员类型、性别、证件类型、手机号码等)
**Then** 系统应将这些字段保存到数据库
**And** 个人专属字段应与机构专属字段分开存储在同一表中
#### Scenario: 机构中介存储详细信息
**Given** 用户创建或编辑机构类型的中介
**When** 填写机构专属字段(统一社会信用代码、主体类型、法定代表人等)
**Then** 系统应将这些字段保存到数据库
**And** 机构专属字段应与个人专属字段分开存储在同一表中
#### Scenario: 向后兼容性保持
**Given** 系统中存在旧的中介数据(只有基础字段)
**When** 查询或编辑这些旧数据
**Then** 系统应正常工作
**And** 新增字段应允许为空
### Requirement: 支持个人和机构分离的模板下载
系统必须提供独立的个人和机构中介导入模板下载功能。
#### Scenario: 下载个人中介模板
**Given** 用户在中介黑名单管理页面
**When** 点击"下载个人模板"按钮
**Then** 系统应生成包含个人专属字段的 Excel 模板
**And** 模板应包含姓名、人员类型、人员子类型、性别、证件类型、证件号码、手机号码、微信号、联系地址、所在公司、职位、关联人员ID、关联关系、状态、备注
**And** 模板应包含示例数据便于用户理解
#### Scenario: 下载机构中介模板
**Given** 用户在中介黑名单管理页面
**When** 点击"下载机构模板"按钮
**Then** 系统应生成包含机构专属字段的 Excel 模板
**And** 模板应包含机构名称、统一社会信用代码、主体类型、企业性质、行业分类、所属行业、成立日期、注册地址、法定代表人、法定代表人证件类型、法定代表人证件号码、股东1-5、状态、备注
**And** 模板应包含示例数据便于用户理解
### Requirement: 支持个人和机构分离的批量导入
系统必须支持使用个人和机构专用模板进行批量导入,并根据模板类型自动设置中介类型。
#### Scenario: 使用个人模板导入个人中介
**Given** 用户准备了一个包含个人中介数据的 Excel 文件
**When** 用户通过"导入个人数据"接口上传文件
**Then** 系统应解析 Excel 数据
**And** 自动设置中介类型为"个人"1
**And** 验证必填字段(姓名、证件号码、状态)
**And** 验证可选字段的长度限制
**And** 将数据保存到数据库
**And** 返回导入结果统计(成功数、失败数)
#### Scenario: 使用机构模板导入机构中介
**Given** 用户准备了一个包含机构中介数据的 Excel 文件
**When** 用户通过"导入机构数据"接口上传文件
**Then** 系统应解析 Excel 数据
**And** 自动设置中介类型为"机构"2
**And** 验证必填字段(机构名称、状态)
**And** 验证可选字段的长度限制
**And** 将数据保存到数据库
**And** 返回导入结果统计(成功数、失败数)
#### Scenario: 导入数据验证与错误提示
**Given** 用户上传的 Excel 文件包含验证失败的数据
**When** 系统执行导入
**Then** 系统应记录每一行的验证错误
**And** 失败数据不应写入数据库
**And** 返回详细的错误信息,包括行号和错误原因
#### Scenario: 支持更新模式导入
**Given** 用户选择"更新支持"模式
**And** Excel 中包含已存在的中介(通过证件号或统一社会信用代码判断)
**When** 执行导入
**Then** 系统应更新现有记录而不是创建新记录
### Requirement: 支持类型化的详情展示
系统必须提供详情接口,根据中介类型返回包含不同字段的详情信息。
#### Scenario: 查询个人中介详情
**Given** 数据库中存在个人类型的中介记录
**When** 用户调用详情接口查询该记录
**Then** 系统应返回包含个人专属字段的详情 VO
**And** 详情应包含:核心字段 + 个人专属字段(人员类型、性别、证件类型、手机号码、微信号、联系地址、所在公司、职位、关联关系等)
**And** 机构专属字段应不返回或为 null
#### Scenario: 查询机构中介详情
**Given** 数据库中存在机构类型的中介记录
**When** 用户调用详情接口查询该记录
**Then** 系统应返回包含机构专属字段的详情 VO
**And** 详情应包含:核心字段 + 机构专属字段(统一社会信用代码、主体类型、企业性质、法定代表人、股东等)
**And** 个人专属字段应不返回或为 null
#### Scenario: 详情接口返回类型自动识别
**Given** 用户调用详情接口只提供中介ID
**When** 系统查询到该中介记录
**Then** 系统应根据中介类型自动返回对应类型的 VO
**And** 个人类型返回 DpcIntermediaryPersonDetailVO
**And** 机构类型返回 DpcIntermediaryEntityDetailVO
### Requirement: 保持现有功能兼容性
所有新增功能必须保持现有接口和功能的正常运行。
#### Scenario: 列表接口保持简洁
**Given** 用户调用中介黑名单列表接口
**When** 系统返回列表数据
**Then** 应保持现有的简洁字段结构
**And** 列表 VO 应只包含中介ID、姓名/机构名称、证件号、中介类型、状态、创建时间等核心字段
**And** 不应包含新增的详细字段
#### Scenario: 现有导入接口保持可用
**Given** 用户使用原有的通用导入模板和接口
**When** 执行导入操作
**Then** 系统应正常处理
**And** 兼容只有基础字段的数据
#### Scenario: 现有新增/编辑接口保持可用
**Given** 用户使用现有的新增/编辑接口
**When** 只填写基础字段
**Then** 系统应正常保存
**And** 新增详细字段应保持为空或默认值
### Requirement: 支持按新增字段进行筛选
列表查询接口应支持按新增字段进行筛选。
#### Scenario: 按人员类型筛选个人中介
**Given** 用户在列表页面
**When** 选择人员类型筛选条件(如"中介"
**Then** 系统应返回匹配该人员类型的个人中介记录
#### Scenario: 按企业性质筛选机构中介
**Given** 用户在列表页面
**When** 选择企业性质筛选条件(如"民企"
**Then** 系统应返回匹配该企业性质的机构中介记录
#### Scenario: 按数据来源筛选
**Given** 用户在列表页面
**When** 选择数据来源筛选条件(如"批量导入"
**Then** 系统应返回匹配该数据来源的所有中介记录
### Requirement: 字段加密存储
敏感字段必须进行加密存储。
#### Scenario: 手机号码加密
**Given** 用户输入或导入手机号码
**When** 数据保存到数据库
**Then** 手机号码应加密存储
**And** 查询时解密返回
#### Scenario: 证件号码加密
**Given** 用户输入或导入证件号码(个人或法定代表人)
**When** 数据保存到数据库
**Then** 证件号码应加密存储
**And** 查询时解密返回
## MODIFIED Requirements
无。本提案为纯新增功能,不修改现有需求。
## REMOVED Requirements
无。本提案不删除任何现有功能。
## Cross-References
### Related Capabilities
- `intermediary-blacklist-management` (基础中介黑名单管理功能)
- `excel-import-export` (Excel 导入导出基础功能)
### Dependencies
- 依赖现有 `dpc_intermediary_blacklist` 表结构
- 依赖 EasyExcel 工具类
- 依赖现有权限控制体系
### Sequencing
1. 首先完成数据库表扩展
2. 然后更新实体类和 DTO/VO
3. 实现 Excel 类和导入导出逻辑
4. 最后更新 Controller 和 Service 层

View File

@@ -0,0 +1,358 @@
# Tasks: 增强中介黑名单字段并实现类型化模板导入
## 任务概述
本任务列表将指导完成中介黑名单功能的增强,包括添加个人和机构类型的详细字段、实现类型化的模板下载和导入功能,以及添加详情展示接口。
## 任务清单
### 阶段一:数据库扩展
#### 任务 1.1:生成数据库变更 SQL 脚本
- [ ] 编写 ALTER TABLE 语句添加个人类型字段11个字段
- [ ] 编写 ALTER TABLE 语句添加机构类型字段15个字段
- [ ] 编写 ALTER TABLE 语句添加通用字段1个字段data_source
- [ ] 添加必要的索引idx_credit_code, idx_phone_number
- [ ] 将 SQL 脚本保存到 `sql/` 目录,命名格式:`dpc_intermediary_enhance_YYYYMMDD.sql`
**验证方式**SQL 语法检查,确保所有字段正确添加
**依赖**:无
---
#### 任务 1.2:执行数据库变更
- [ ] 在开发环境执行 SQL 脚本
- [ ] 验证表结构变更成功
- [ ] 确认所有字段添加成功且类型正确
- [ ] 确认索引创建成功
**验证方式**DESCRIBE dpc_intermediary_blacklist; SHOW INDEX FROM dpc_intermediary_blacklist;
**依赖**:任务 1.1
---
### 阶段二:后端实体类和 DTO/VO 更新
#### 任务 2.1:更新实体类 DpcIntermediaryBlacklist
- [ ] 添加个人类型字段属性11个
- [ ] 添加机构类型字段属性15个
- [ ] 添加通用字段属性1个dataSource
- [ ] 保持现有字段不变,确保向后兼容
- [ ] 使用 Lombok @Data 注解
**验证方式**:编译通过,无语法错误
**依赖**:任务 1.2
---
#### 任务 2.2:创建个人中介 DTO
- [ ] 创建 `DpcIntermediaryPersonAddDTO.java`
- [ ] 添加个人专属字段
- [ ] 添加适当的验证注解(@NotBlank, @Size 等)
- [ ] 实现 Serializable 接口
**验证方式**编译通过DTO 字段完整
**依赖**:任务 2.1
---
#### 任务 2.3:创建机构中介 DTO
- [ ] 创建 `DpcIntermediaryEntityAddDTO.java`
- [ ] 添加机构专属字段
- [ ] 添加适当的验证注解
- [ ] 实现 Serializable 接口
**验证方式**编译通过DTO 字段完整
**依赖**:任务 2.1
---
#### 任务 2.4:创建个人详情 VO
- [ ] 创建 `DpcIntermediaryPersonDetailVO.java`
- [ ] 包含核心字段 + 个人专属字段
- [ ] 添加关联字段名称(如 genderName, certificateTypeName
- [ ] 添加审计字段
- [ ] 使用 @JsonFormat 注解格式化日期
**验证方式**编译通过VO 字段完整
**依赖**:任务 2.2
---
#### 任务 2.5:创建机构详情 VO
- [ ] 创建 `DpcIntermediaryEntityDetailVO.java`
- [ ] 包含核心字段 + 机构专属字段
- [ ] 添加关联字段名称
- [ ] 添加审计字段
- [ ] 使用 @JsonFormat 注解格式化日期
**验证方式**编译通过VO 字段完整
**依赖**:任务 2.3
---
### 阶段三Excel 类创建
#### 任务 3.1:创建个人中介 Excel 类
- [ ] 创建 `DpcIntermediaryPersonExcel.java`
- [ ] 使用 @ExcelProperty 注解定义 Excel 列
- [ ] 使用 @ColumnWidth 注解设置列宽
- [ ] 字段顺序:姓名 -> 人员类型 -> ... -> 备注共14列
- [ ] **不在模板中显示**:状态、数据来源字段(由系统自动设置)
- [ ] **添加字典下拉框注解**
- `@DictDropdown(dictType = "dpc_indiv_gender")` - 性别字段
- `@DictDropdown(dictType = "dpc_certificate_type")` - 证件类型字段
**验证方式**编译通过Excel 注解正确
**依赖**:任务 2.2
---
#### 任务 3.2:创建机构中介 Excel 类
- [ ] 创建 `DpcIntermediaryEntityExcel.java`
- [ ] 使用 @ExcelProperty 注解定义 Excel 列
- [ ] 使用 @ColumnWidth 注解设置列宽
- [ ] 字段顺序:机构名称 -> 统一社会信用代码 -> ... -> 备注共17列
- [ ] **不在模板中显示**:状态、数据来源字段(由系统自动设置)
- [ ] **添加字典下拉框注解**
- `@DictDropdown(dictType = "dpc_entity_type")` - 主体类型字段
- `@DictDropdown(dictType = "dpc_enterprise_nature")` - 企业性质字段
**验证方式**编译通过Excel 注解正确
**依赖**:任务 2.3
---
### 阶段四Service 层实现
#### 任务 4.1:扩展 Service 接口
- [ ]`IDpcIntermediaryBlacklistService` 中添加新方法:
- `Object selectIntermediaryDetailById(Long intermediaryId)`
- `String importPersonIntermediary(List<DpcIntermediaryPersonExcel> list, boolean isUpdateSupport)`
- `String importEntityIntermediary(List<DpcIntermediaryEntityExcel> list, boolean isUpdateSupport)`
**验证方式**:编译通过,接口方法签名正确
**依赖**:任务 2.4, 2.5, 3.1, 3.2
---
#### 任务 4.2:实现详情查询方法
- [ ]`DpcIntermediaryBlacklistServiceImpl` 中实现 `selectIntermediaryDetailById`
- [ ] 根据中介类型返回不同的 VO
- [ ] 个人类型返回 `DpcIntermediaryPersonDetailVO`
- [ ] 机构类型返回 `DpcIntermediaryEntityDetailVO`
- [ ] 填充关联字段名称(字典转换)
**验证方式**:单元测试验证不同类型返回正确的 VO
**依赖**:任务 4.1
---
#### 任务 4.3:实现个人中介导入方法
- [ ] 实现 `importPersonIntermediary` 方法
- [ ] 验证必填字段(姓名、证件号码、状态)
- [ ] 验证字段长度限制
- [ ] 设置中介类型为"1"(个人)
- [ ] 支持更新模式(通过证件号判断是否已存在)
- [ ] 返回导入结果统计
**验证方式**:单元测试验证导入逻辑和错误处理
**依赖**:任务 4.1
---
#### 任务 4.4:实现机构中介导入方法
- [ ] 实现 `importEntityIntermediary` 方法
- [ ] 验证必填字段(机构名称、状态)
- [ ] 验证字段长度限制
- [ ] 设置中介类型为"2"(机构)
- [ ] 支持更新模式(通过统一社会信用代码判断是否已存在)
- [ ] 返回导入结果统计
**验证方式**:单元测试验证导入逻辑和错误处理
**依赖**:任务 4.1
---
### 阶段五Controller 层实现
#### 任务 5.1:添加模板下载接口(支持字典下拉框)
- [ ] 添加 `POST /dpc/intermediary/importPersonTemplate` 接口
- [ ] 添加 `POST /dpc/intermediary/importEntityTemplate` 接口
- [ ] 使用 `EasyExcelUtil.importTemplateWithDictDropdown()` 生成模板
- [ ] 添加 @Operation 注解用于 Swagger 文档
- [ ] 不需要权限控制(模板下载公开)
**验证方式**
- 通过 Swagger UI 或 Postman 测试接口
- 下载模板后验证字典下拉框功能是否正常
- 验证下拉选项是否与字典数据一致
**依赖**:任务 3.1, 3.2, 6.1(确保字典数据已配置)
---
#### 任务 5.2:添加类型化导入接口
- [ ] 添加 `POST /dpc/intermediary/importPersonData` 接口
- [ ] 添加 `POST /dpc/intermediary/importEntityData` 接口
- [ ] 添加 updateSupport 参数支持更新模式
- [ ] 添加 @PreAuthorize 权限注解
- [ ] 添加 @Log 注解记录操作日志
- [ ] 添加 @Operation 注解用于 Swagger 文档
**验证方式**:通过 Swagger UI 或 Postman 测试接口
**依赖**:任务 4.3, 4.4
---
#### 任务 5.3:修改详情接口
- [ ] 修改 `GET /dpc/intermediary/{intermediaryId}` 接口
- [ ] 返回类型改为 Object根据实际类型返回不同 VO
- [ ] 调用新的 `selectIntermediaryDetailById` 方法
- [ ] 确保前端能够根据类型正确解析响应
**验证方式**:通过 Swagger UI 或 Postman 测试接口,验证不同类型返回不同结构
**依赖**:任务 4.2
---
### 阶段六:字典数据配置
#### 任务 6.1:创建字典数据 SQL 脚本
- [ ] 添加人员类型字典dpc_person_type
- [ ] 添加人员子类型字典dpc_person_sub_type
- [ ] **添加性别字典dpc_indiv_gender** - 用于个人中介下拉框
- [ ] **添加证件类型字典dpc_certificate_type** - 用于个人中介下拉框
- [ ] **添加主体类型字典dpc_entity_type** - 用于机构中介下拉框
- [ ] **添加企业性质字典dpc_enterprise_nature** - 用于机构中介下拉框
- [ ] 添加数据来源字典dpc_data_source
- [ ] 将 SQL 脚本保存到 `sql/` 目录
**验证方式**SQL 语法检查
**依赖**:无
---
#### 任务 6.2:执行字典数据 SQL 并预热缓存
- [ ] 在开发环境执行字典数据 SQL
- [ ] 通过系统管理 > 字典管理验证字典数据
- [ ] **重要**:在每个字典类型页面点击"刷新缓存"按钮,确保字典数据加载到 Redis
- [ ] 验证字典缓存是否生效(可通过测试模板下载确认下拉框是否显示)
**验证方式**
- 在系统界面中查看字典数据
- 下载模板验证下拉框功能
- 检查 Redis 缓存中的字典数据(`sys_dict_cache:*`
**依赖**:任务 6.1
---
### 阶段七:测试
#### 任务 7.1:编写单元测试
- [ ] 测试详情查询方法(个人和机构)
- [ ] 测试个人中介导入方法
- [ ] 测试机构中介导入方法
- [ ] 测试数据验证逻辑
- [ ] 测试更新模式
**验证方式**:所有单元测试通过
**依赖**:任务 4.2, 4.3, 4.4
---
#### 任务 7.2:接口集成测试
- [ ] 测试模板下载接口(个人和机构)
- [ ] 测试数据导入接口(个人和机构)
- [ ] 测试详情查询接口
- [ ] 测试列表接口(确保不受影响)
- [ ] 测试现有新增/编辑接口(确保不受影响)
**验证方式**:生成测试脚本并执行,记录测试结果
**依赖**:任务 5.1, 5.2, 5.3
---
#### 任务 7.3:生成测试报告
- [ ] 生成可执行的测试脚本
- [ ] 执行测试并保存所有接口输出
- [ ] 生成测试用例报告Markdown 格式)
- [ ] 报告保存到 `doc/` 目录
**验证方式**:测试报告完整,所有测试用例通过
**依赖**:任务 7.2
---
### 阶段八:文档更新
#### 任务 8.1:更新 API 文档
- [ ] 更新 `doc/中介黑名单API文档.md`
- [ ] 添加新增接口的文档:
- 个人模板下载接口
- 机构模板下载接口
- 个人数据导入接口
- 机构数据导入接口
- 详情接口(说明返回类型变化)
- [ ] 更新数据模型说明
**验证方式**:文档与实际接口一致
**依赖**:任务 5.1, 5.2, 5.3
---
#### 任务 8.2:更新数据库设计文档
- [ ] 更新表结构说明
- [ ] 添加新字段说明
- [ ] 更新索引说明
**验证方式**:文档与实际表结构一致
**依赖**:任务 1.2
---
## 任务执行顺序建议
1. **第一周**:完成阶段一(数据库扩展)和阶段二(实体类和 DTO/VO
2. **第二周**完成阶段三Excel 类和阶段四Service 层)
3. **第三周**完成阶段五Controller 层)和阶段六(字典数据)
4. **第四周**:完成阶段七(测试)和阶段八(文档更新)
## 并行化建议
- 任务 2.2 和 2.3 可以并行开发
- 任务 2.4 和 2.5 可以并行开发
- 任务 3.1 和 3.2 可以并行开发
- 任务 4.3 和 4.4 可以并行开发
- 任务 5.1 和 5.2 可以并行开发
## 关键里程碑
1. **里程碑 1**:数据库扩展完成(任务 1.2
2. **里程碑 2**:后端实体类和 DTO/VO 完成(任务 2.5
3. **里程碑 3**Excel 类创建完成(任务 3.2
4. **里程碑 4**Service 层实现完成(任务 4.4
5. **里程碑 5**Controller 层实现完成(任务 5.3
6. **里程碑 6**:测试通过,文档更新完成(任务 8.2