中介类型修改
This commit is contained in:
@@ -22,7 +22,10 @@
|
||||
"mcp__database-server__alter_table",
|
||||
"mcp__database-server__write_query",
|
||||
"Bash(mvn dependency:tree:*)",
|
||||
"Bash(javac:*)"
|
||||
"Bash(javac:*)",
|
||||
"Bash(unzip:*)",
|
||||
"Bash(chcp:*)",
|
||||
"Skill(superpowers:brainstorming)"
|
||||
]
|
||||
},
|
||||
"enabledMcpjsonServers": [
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
|
||||
## 运行
|
||||
- 使用mcp工具进行数据库相关操作
|
||||
- 使用mcp:dpc_intermediary_blacklist进行数据库相关操作
|
||||
- 使用根目录中的ry.bat控制后端的启动,不要自行在命令行中启动后端
|
||||
- 测试方式为生成可执行的测试脚本
|
||||
- 测试脚本在运行完成后需要保存所有接口输出并生成测试用例报告
|
||||
|
||||
226
doc/EasyExcel字典下拉框使用说明.md
Normal file
226
doc/EasyExcel字典下拉框使用说明.md
Normal file
@@ -0,0 +1,226 @@
|
||||
# EasyExcel字典下拉框使用说明
|
||||
|
||||
## 功能概述
|
||||
|
||||
本项目实现了EasyExcel自定义WriteHandler拦截器,可以在生成Excel模板时自动添加基于若依框架字典数据的下拉框。
|
||||
|
||||
## 核心组件
|
||||
|
||||
### 1. @DictDropdown 注解
|
||||
|
||||
位置:`com.ruoyi.common.annotation.DictDropdown`
|
||||
|
||||
用于标注需要添加下拉框的字段。
|
||||
|
||||
**属性说明:**
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|-----|------|--------|------|
|
||||
| dictType | String | 必填 | 字典类型编码,对应若依字典管理中的字典类型 |
|
||||
| displayType | DisplayType | LABEL | 下拉框显示内容类型(LABEL:显示标签,VALUE:显示值) |
|
||||
| strict | boolean | true | 是否仅允许选择下拉框中的值 |
|
||||
| hiddenSheetName | String | "dict_hidden" | 隐藏Sheet名称(用于存储大量下拉选项) |
|
||||
|
||||
### 2. DictDropdownWriteHandler 处理器
|
||||
|
||||
位置:`com.ruoyi.dpc.handler.DictDropdownWriteHandler`
|
||||
|
||||
核心功能:
|
||||
- 解析实体类中的@DictDropdown注解
|
||||
- 从若依字典缓存获取字典数据
|
||||
- 为对应列添加下拉框验证
|
||||
- 自动处理下拉选项超过Excel字符限制的情况(使用隐藏Sheet)
|
||||
|
||||
### 3. EasyExcelUtil 工具类扩展
|
||||
|
||||
位置:`com.ruoyi.dpc.utils.EasyExcelUtil`
|
||||
|
||||
新增方法:
|
||||
- `importTemplateWithDictDropdown()` - 下载带字典下拉框的导入模板
|
||||
- `exportExcelWithDictDropdown()` - 导出带字典下拉框的Excel
|
||||
|
||||
## 使用示例
|
||||
|
||||
### 步骤1:在实体类上添加注解
|
||||
|
||||
```java
|
||||
package com.ruoyi.dpc.domain.excel;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.ruoyi.common.annotation.DictDropdown;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DpcEmployeeExcel {
|
||||
|
||||
@ExcelProperty(value = "姓名", index = 0)
|
||||
@ColumnWidth(15)
|
||||
private String name;
|
||||
|
||||
@ExcelProperty(value = "柜员号", index = 1)
|
||||
@ColumnWidth(15)
|
||||
private String tellerNo;
|
||||
|
||||
// 添加字典下拉框注解
|
||||
@ExcelProperty(value = "状态", index = 6)
|
||||
@ColumnWidth(10)
|
||||
@DictDropdown(dictType = "dpc_employee_status")
|
||||
private String status;
|
||||
}
|
||||
```
|
||||
|
||||
### 步骤2:在Controller中使用
|
||||
|
||||
```java
|
||||
@RestController
|
||||
@RequestMapping("/dpc/employee")
|
||||
public class DpcEmployeeController {
|
||||
|
||||
/**
|
||||
* 下载带字典下拉框的导入模板
|
||||
*/
|
||||
@PostMapping("/importTemplateWithDropdown")
|
||||
public void importTemplateWithDropdown(HttpServletResponse response) {
|
||||
EasyExcelUtil.importTemplateWithDictDropdown(
|
||||
response,
|
||||
DpcEmployeeExcel.class,
|
||||
"员工信息"
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出带字典下拉框的Excel
|
||||
*/
|
||||
@PostMapping("/exportWithDropdown")
|
||||
public void exportWithDropdown(HttpServletResponse response) {
|
||||
List<DpcEmployeeExcel> list = employeeService.selectEmployeeList();
|
||||
EasyExcelUtil.exportExcelWithDictDropdown(
|
||||
response,
|
||||
list,
|
||||
DpcEmployeeExcel.class,
|
||||
"员工信息"
|
||||
);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 高级用法
|
||||
|
||||
### 1. 显示字典键值而非标签
|
||||
|
||||
```java
|
||||
@DictDropdown(dictType = "dpc_employee_status", displayType = DisplayType.VALUE)
|
||||
private String status;
|
||||
```
|
||||
|
||||
### 2. 允许手动输入(非严格模式)
|
||||
|
||||
```java
|
||||
@DictDropdown(dictType = "dpc_employee_status", strict = false)
|
||||
private String status;
|
||||
```
|
||||
|
||||
### 3. 自定义隐藏Sheet名称
|
||||
|
||||
```java
|
||||
@DictDropdown(dictType = "dpc_employee_status", hiddenSheetName = "employee_status_dict")
|
||||
private String status;
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **必须指定@ExcelProperty的index属性**
|
||||
- 字段必须指定@ExcelProperty注解的index值,否则无法正确映射列位置
|
||||
|
||||
2. **字典数据必须预先加载到缓存**
|
||||
- 使用前需要确保字典数据已经加载到Redis缓存中
|
||||
- 可通过若依系统的字典管理功能预热缓存
|
||||
|
||||
3. **下拉选项数量限制**
|
||||
- 当下拉选项总长度超过255字符时,自动使用隐藏Sheet存储
|
||||
- 隐藏Sheet在Excel中不可见,但下拉框功能正常
|
||||
|
||||
4. **字段必须标注@ExcelProperty注解**
|
||||
- 只有同时标注了@ExcelProperty和@DictDropdown的字段才会添加下拉框
|
||||
|
||||
## 测试验证
|
||||
|
||||
### 接口测试
|
||||
|
||||
1. 启动项目后,访问Swagger UI:`http://localhost:8080/swagger-ui/index.html`
|
||||
|
||||
2. 找到员工信息管理相关接口:
|
||||
- `POST /dpc/employee/importTemplateWithDropdown` - 下载带字典下拉框的模板
|
||||
|
||||
3. 调用接口下载模板,检查Excel中的下拉框是否正常
|
||||
|
||||
### 手动验证
|
||||
|
||||
1. 打开下载的Excel模板
|
||||
2. 点击标注了下拉框的列(如"状态"列)
|
||||
3. 检查是否出现下拉箭头和选项列表
|
||||
4. 尝试选择和输入,验证验证规则是否生效
|
||||
|
||||
## 技术实现细节
|
||||
|
||||
### Excel下拉列表限制处理
|
||||
|
||||
Excel对下拉列表的直接字符数有限制(约255字符),本项目采用以下策略:
|
||||
|
||||
1. **选项较少时(<255字符)**
|
||||
- 直接使用 `DataValidationHelper.createExplicitListConstraint()` 创建下拉列表
|
||||
- 下拉选项内联在单元格验证中
|
||||
|
||||
2. **选项较多时(≥255字符)**
|
||||
- 创建隐藏Sheet存储所有选项
|
||||
- 使用 `DataValidationHelper.createFormulaListConstraint()` 通过公式引用
|
||||
- 自动隐藏Sheet(`workbook.setSheetHidden()`)
|
||||
|
||||
### 字典数据获取
|
||||
|
||||
```
|
||||
┌─────────────┐ 缓存查询 ┌─────────────┐
|
||||
│ DictDropdown │ ───────────▶ │ DictUtils │
|
||||
│ 注解 │ │ .getDictCache() │
|
||||
└─────────────┘ └─────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────┐
|
||||
│ Redis缓存 │
|
||||
│ sys_dict:key │
|
||||
└─────────────┘
|
||||
```
|
||||
|
||||
### 列索引映射
|
||||
|
||||
通过反射获取字段的@ExcelProperty注解中的index值,确保下拉框添加到正确的列。
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1:下拉框没有显示?
|
||||
|
||||
**可能原因:**
|
||||
1. 字典数据未加载到缓存
|
||||
2. 字段未指定@ExcelProperty的index值
|
||||
3. 字典类型编码错误
|
||||
|
||||
**解决方法:**
|
||||
1. 在若依系统字典管理中,进入对应字典类型,刷新缓存
|
||||
2. 检查实体类字段注解是否正确
|
||||
3. 确认dictType值与字典管理中的字典类型一致
|
||||
|
||||
### Q2:下拉选项显示不完整?
|
||||
|
||||
**原因:** 选项字符数超过255字符,但隐藏Sheet创建失败
|
||||
|
||||
**解决方法:** 检查日志中的错误信息,确保有权限创建隐藏Sheet
|
||||
|
||||
### Q3:可以手动输入非下拉选项的值吗?
|
||||
|
||||
**答案:** 可以,通过设置 `strict = false` 允许手动输入
|
||||
|
||||
## 更新日志
|
||||
|
||||
| 版本 | 日期 | 说明 |
|
||||
|------|------|------|
|
||||
| 1.0.0 | 2026-01-29 | 初始版本,支持字典下拉框功能 |
|
||||
22
doc/中介主体信息表.csv
Normal file
22
doc/中介主体信息表.csv
Normal file
@@ -0,0 +1,22 @@
|
||||
字段中文名,数据类型,长度/精度,是否为空,默认值,说明
|
||||
统一社会信用代码,VARCHAR,18,是,-,统一社会信用代码
|
||||
主体名称,VARCHAR,200,否,-,企业注册名称
|
||||
主体类型,VARCHAR,50,否,-,企业类型:有限责任公司、股份有限公司、合伙企业、个体工商户、外资企业等
|
||||
企业性质,VARCHAR,50,是,-,国企、民企、外企、合资、其他
|
||||
行业分类,VARCHAR,100,是,-,行业分类代码或名称
|
||||
所属行业,VARCHAR,100,是,-,所属行业
|
||||
成立日期,DATE,-,是,-,企业成立日期
|
||||
注册地址,VARCHAR,500,是,-,工商注册地址
|
||||
法定代表人,VARCHAR,50,是,-,法定代表人姓名
|
||||
法定代表人证件类型,VARCHAR,30,是,-,法定代表人证件类型
|
||||
法定代表人证件号码,VARCHAR,30,是,-,法定代表人证件号码
|
||||
股东1,VARCHAR,30,是,-,股东姓名
|
||||
股东2,VARCHAR,30,是,-,股东姓名
|
||||
股东3,VARCHAR,30,是,-,股东姓名
|
||||
股东4,VARCHAR,30,是,-,股东姓名
|
||||
股东5,VARCHAR,30,是,-,股东姓名
|
||||
创建时间,DATETIME,-,否,当前时间,记录创建时间
|
||||
更新时间,DATETIME,-,否,当前时间,记录更新时间
|
||||
创建人,VARCHAR,50,否,-,记录创建人
|
||||
更新人,VARCHAR,50,是,-,记录更新人
|
||||
数据来源,VARCHAR,30,是,MANUAL,"MANUAL:手动录入, SYSTEM:系统同步, API:接口获取, IMPORT:批量导入"
|
||||
|
20
doc/中介人员信息表.csv
Normal file
20
doc/中介人员信息表.csv
Normal file
@@ -0,0 +1,20 @@
|
||||
字段中文名,数据类型,长度/精度,是否为空,默认值,说明
|
||||
人员ID,VARCHAR,20,否,-,中介、职业背债人、房产中介等
|
||||
人员类型,VARCHAR,30,否,-,中介、职业背债人、房产中介等
|
||||
人员子类型,VARCHAR,50,是,-,如:本人、配偶等
|
||||
姓名,VARCHAR,50,否,-,人员姓名
|
||||
性别,CHAR,1,是,-,"M:男, F:女, O:其他"
|
||||
证件类型,VARCHAR,30,否,身份证,身份证、护照、港澳通行证、台胞证、军官证等
|
||||
证件号码,VARCHAR,30,否,-,证件号码(加密存储)
|
||||
手机号码,VARCHAR,20,是,-,手机号码(加密存储)
|
||||
微信号,VARCHAR,50,是,-,微信号
|
||||
联系地址,VARCHAR,200,是,-,详细联系地址
|
||||
所在公司,VARCHAR,100,是,-,当前就职公司
|
||||
职位,VARCHAR,100,是,-,职位/职务
|
||||
关联人员ID,VARCHAR,20,是,-,关联“人员ID”
|
||||
关联关系,VARCHAR,50,是,-,与关联员工的关系
|
||||
创建时间,DATETIME,-,否,当前时间,记录创建时间
|
||||
更新时间,DATETIME,-,否,当前时间,记录更新时间
|
||||
创建人,VARCHAR,50,否,-,记录创建人
|
||||
更新人,VARCHAR,50,是,-,记录更新人
|
||||
数据来源,VARCHAR,30,是,MANUAL,"MANUAL:手动录入, SYSTEM:系统同步, IMPORT:批量导入, API:接口获取"
|
||||
|
404
doc/中介黑名单管理API文档.md
Normal file
404
doc/中介黑名单管理API文档.md
Normal file
@@ -0,0 +1,404 @@
|
||||
# 中介黑名单管理 API 文档
|
||||
|
||||
## 概述
|
||||
|
||||
中介黑名单管理模块提供个人和机构两类中介信息的增删改查、类型化模板下载和批量导入导出功能。
|
||||
|
||||
**基础路径**: `/dpc/intermediary`
|
||||
|
||||
**权限标识前缀**: `dpc:intermediary`
|
||||
|
||||
---
|
||||
|
||||
## API 接口列表
|
||||
|
||||
### 1. 查询中介黑名单列表
|
||||
|
||||
**接口地址**: `GET /dpc/intermediary/list`
|
||||
|
||||
**权限要求**: `dpc:intermediary:list`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| name | String | 否 | 姓名/机构名称(模糊查询) |
|
||||
| certificateNo | String | 否 | 证件号/统一社会信用代码(精确查询) |
|
||||
| intermediaryType | String | 否 | 中介类型(1=个人, 2=机构) |
|
||||
| status | String | 否 | 状态(0=正常, 1=停用) |
|
||||
| pageNum | Integer | 否 | 页码(默认1) |
|
||||
| pageSize | Integer | 否 | 每页数量(默认10) |
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"rows": [
|
||||
{
|
||||
"intermediaryId": 1,
|
||||
"name": "张三",
|
||||
"certificateNo": "110101199001011234",
|
||||
"intermediaryType": "1",
|
||||
"intermediaryTypeName": "个人",
|
||||
"status": "0",
|
||||
"statusName": "正常",
|
||||
"remark": "测试数据",
|
||||
"createTime": "2026-01-29 10:00:00"
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
**响应字段说明**:
|
||||
|
||||
| 字段名 | 类型 | 说明 |
|
||||
|--------|------|------|
|
||||
| intermediaryId | Long | 中介ID |
|
||||
| name | String | 姓名/机构名称 |
|
||||
| certificateNo | String | 证件号/统一社会信用代码 |
|
||||
| intermediaryType | String | 中介类型(1=个人, 2=机构) |
|
||||
| intermediaryTypeName | String | 中介类型名称 |
|
||||
| status | String | 状态(0=正常, 1=停用) |
|
||||
| statusName | String | 状态名称 |
|
||||
| remark | String | 备注 |
|
||||
| createTime | Date | 创建时间 |
|
||||
|
||||
---
|
||||
|
||||
### 2. 获取中介黑名单详细信息
|
||||
|
||||
**接口地址**: `GET /dpc/intermediary/{intermediaryId}`
|
||||
|
||||
**权限要求**: `dpc:intermediary:query`
|
||||
|
||||
**路径参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| intermediaryId | Long | 是 | 中介ID |
|
||||
|
||||
**功能说明**: 根据中介类型返回不同的详情结构
|
||||
|
||||
**个人类型响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"intermediaryId": 1,
|
||||
"name": "张三",
|
||||
"certificateNo": "110101199001011234",
|
||||
"intermediaryType": "1",
|
||||
"intermediaryTypeName": "个人",
|
||||
"status": "0",
|
||||
"statusName": "正常",
|
||||
"dataSource": "IMPORT",
|
||||
"dataSourceName": "批量导入",
|
||||
"indivType": "中介",
|
||||
"indivGender": "M",
|
||||
"indivGenderName": "男",
|
||||
"indivCertType": "身份证",
|
||||
"indivPhone": "13800138000",
|
||||
"indivCompany": "XX公司",
|
||||
"indivPosition": "经纪人"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**机构类型响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {
|
||||
"intermediaryId": 2,
|
||||
"name": "XX中介公司",
|
||||
"intermediaryType": "2",
|
||||
"intermediaryTypeName": "机构",
|
||||
"status": "0",
|
||||
"statusName": "正常",
|
||||
"dataSource": "MANUAL",
|
||||
"dataSourceName": "手动录入",
|
||||
"corpCreditCode": "91110000XXXXXXXXXX",
|
||||
"corpType": "有限责任公司",
|
||||
"corpNature": "民企",
|
||||
"corpLegalRep": "张三",
|
||||
"corpAddress": "北京市朝阳区"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 3. 新增中介黑名单
|
||||
|
||||
**接口地址**: `POST /dpc/intermediary`
|
||||
|
||||
**权限要求**: `dpc:intermediary:add`
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"name": "张三",
|
||||
"certificateNo": "110101199001011234",
|
||||
"intermediaryType": "1",
|
||||
"status": "0",
|
||||
"remark": "测试数据"
|
||||
}
|
||||
```
|
||||
|
||||
**字段说明**:
|
||||
|
||||
| 字段名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| name | String | 是 | 姓名/机构名称 |
|
||||
| certificateNo | String | 是 | 证件号/统一社会信用代码 |
|
||||
| intermediaryType | String | 是 | 中介类型(1=个人, 2=机构) |
|
||||
| status | String | 是 | 状态(0=正常, 1=停用) |
|
||||
| remark | String | 否 | 备注 |
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. 修改中介黑名单
|
||||
|
||||
**接口地址**: `PUT /dpc/intermediary`
|
||||
|
||||
**权限要求**: `dpc:intermediary:edit`
|
||||
|
||||
**请求体**:
|
||||
```json
|
||||
{
|
||||
"intermediaryId": 1,
|
||||
"name": "张三",
|
||||
"certificateNo": "110101199001011234",
|
||||
"intermediaryType": "1",
|
||||
"status": "0",
|
||||
"remark": "测试数据"
|
||||
}
|
||||
```
|
||||
|
||||
**字段说明**: 与新增接口相同,intermediaryId 为必填项。
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5. 删除中介黑名单
|
||||
|
||||
**接口地址**: `DELETE /dpc/intermediary/{intermediaryIds}`
|
||||
|
||||
**权限要求**: `dpc:intermediary:remove`
|
||||
|
||||
**路径参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| intermediaryIds | Long[] | 是 | 中介ID数组(逗号分隔) |
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 6. 导出中介黑名单
|
||||
|
||||
**接口地址**: `POST /dpc/intermediary/export`
|
||||
|
||||
**权限要求**: `dpc:intermediary:export`
|
||||
|
||||
**请求参数**: 与查询列表接口相同(支持筛选条件)
|
||||
|
||||
**响应**: Excel 文件下载
|
||||
|
||||
---
|
||||
|
||||
### 7. 下载个人中介导入模板(带字典下拉框)
|
||||
|
||||
**接口地址**: `POST /dpc/intermediary/importPersonTemplate`
|
||||
|
||||
**权限要求**: 无
|
||||
|
||||
**功能说明**: 下载的 Excel 模板中,性别、证件类型列会自动添加字典下拉框。
|
||||
|
||||
**响应**: Excel 模板文件下载
|
||||
|
||||
**Excel 格式说明**:
|
||||
|
||||
**Sheet1: 个人中介黑名单**
|
||||
| 姓名 | 人员类型 | 人员子类型 | 性别▼ | 证件类型▼ | 证件号码 | 手机号码 | 微信号 | 联系地址 | 所在公司 | 职位 | 关联人员ID | 关联关系 | 备注 |
|
||||
|------|---------|-----------|-------|-----------|---------|---------|--------|---------|---------|-----|-----------|---------|------|
|
||||
| 张三 | 中介 | 本人 | 男 | 身份证 | 110101199001011234 | 13800138000 | zhangsan | 北京市朝阳区 | XX公司 | 经纪人 | - | - | 测试 |
|
||||
|
||||
**注**:带 ▼ 标记的列包含下拉框,选项来自字典:
|
||||
- 性别:`dpc_indiv_gender`
|
||||
- 证件类型:`dpc_certificate_type`
|
||||
|
||||
---
|
||||
|
||||
### 8. 下载机构中介导入模板(带字典下拉框)
|
||||
|
||||
**接口地址**: `POST /dpc/intermediary/importEntityTemplate`
|
||||
|
||||
**权限要求**: 无
|
||||
|
||||
**功能说明**: 下载的 Excel 模板中,主体类型、企业性质列会自动添加字典下拉框。
|
||||
|
||||
**响应**: Excel 模板文件下载
|
||||
|
||||
**Excel 格式说明**:
|
||||
|
||||
**Sheet1: 机构中介黑名单**
|
||||
| 机构名称 | 统一社会信用代码 | 主体类型▼ | 企业性质▼ | 行业分类 | 所属行业 | 成立日期 | 注册地址 | 法定代表人 | 法定代表人证件类型 | 法定代表人证件号码 | 股东1 | 股东2 | 股东3 | 股东4 | 股东5 | 备注 |
|
||||
|---------|-----------------|-----------|-----------|---------|---------|---------|---------|-----------|-------------------|-------------------|-------|-------|-------|-------|-------|------|
|
||||
| XX公司 | 91110000XXXXXXXXXX | 有限责任公司 | 民企 | 房地产 | 房地产业 | 2020-01-01 | 北京市朝阳区 | 张三 | 身份证 | 110101199001011234 | 李四 | 王五 | - | - | - | - |
|
||||
|
||||
**注**:带 ▼ 标记的列包含下拉框,选项来自字典:
|
||||
- 主体类型:`dpc_entity_type`
|
||||
- 企业性质:`dpc_enterprise_nature`
|
||||
|
||||
---
|
||||
|
||||
### 9. 导入个人中介黑名单
|
||||
|
||||
**接口地址**: `POST /dpc/intermediary/importPersonData`
|
||||
|
||||
**权限要求**: `dpc:intermediary:import`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| file | File | 是 | Excel 文件 |
|
||||
| updateSupport | Boolean | 否 | 是否更新已存在数据(默认false) |
|
||||
|
||||
**Excel 格式**: 参见"下载个人中介导入模板"
|
||||
|
||||
**数据验证规则**:
|
||||
1. **姓名**:必填,长度 1-100 字符
|
||||
2. **证件号码**:必填,长度不超过 50 字符
|
||||
3. **证件类型**:选填,默认"身份证"
|
||||
4. **其他字段**:选填,按长度限制验证
|
||||
5. **状态**:系统默认设置为"正常"(0)
|
||||
6. **数据来源**:系统默认设置为"批量导入"(IMPORT)
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "恭喜您,数据已全部导入成功!共 10 条"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 10. 导入机构中介黑名单
|
||||
|
||||
**接口地址**: `POST /dpc/intermediary/importEntityData`
|
||||
|
||||
**权限要求**: `dpc:intermediary:import`
|
||||
|
||||
**请求参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 |
|
||||
|--------|------|------|------|
|
||||
| file | File | 是 | Excel 文件 |
|
||||
| updateSupport | Boolean | 否 | 是否更新已存在数据(默认false) |
|
||||
|
||||
**Excel 格式**: 参见"下载机构中介导入模板"
|
||||
|
||||
**数据验证规则**:
|
||||
1. **机构名称**:必填,长度 1-200 字符
|
||||
2. **统一社会信用代码**:选填,18 位
|
||||
3. **其他字段**:选填,按长度限制验证
|
||||
4. **状态**:系统默认设置为"正常"(0)
|
||||
5. **数据来源**:系统默认设置为"批量导入"(IMPORT)
|
||||
|
||||
**响应示例**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "恭喜您,数据已全部导入成功!共 10 条"
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 字典数据说明
|
||||
|
||||
导入模板中的下拉框选项来自系统字典管理,相关字典类型:
|
||||
|
||||
### 个人中介字典
|
||||
|
||||
| 字典类型 | 字典名称 | 用途 |
|
||||
|---------|---------|------|
|
||||
| dpc_indiv_gender | 个人中介性别 | 个人中介模板性别下拉框 |
|
||||
| dpc_certificate_type | 证件类型 | 个人中介模板证件类型下拉框 |
|
||||
|
||||
### 机构中介字典
|
||||
|
||||
| 字典类型 | 字典名称 | 用途 |
|
||||
|---------|---------|------|
|
||||
| dpc_entity_type | 主体类型 | 机构中介模板主体类型下拉框 |
|
||||
| dpc_enterprise_nature | 企业性质 | 机构中介模板企业性质下拉框 |
|
||||
|
||||
### 通用字典
|
||||
|
||||
| 字典类型 | 字典名称 | 用途 |
|
||||
|---------|---------|------|
|
||||
| dpc_data_source | 数据来源 | 数据来源字段映射 |
|
||||
|
||||
---
|
||||
|
||||
## 错误码说明
|
||||
|
||||
| 错误码 | 说明 |
|
||||
|--------|------|
|
||||
| 200 | 操作成功 |
|
||||
| 401 | 未授权,请先登录 |
|
||||
| 403 | 无权限访问 |
|
||||
| 500 | 服务器内部错误 |
|
||||
|
||||
## 业务错误信息
|
||||
|
||||
| 错误信息 | 说明 |
|
||||
|----------|------|
|
||||
| 姓名不能为空 | 个人中介导入时姓名为空 |
|
||||
| 机构名称不能为空 | 机构中介导入时机构名称为空 |
|
||||
| 证件号码不能为空 | 个人中介导入时证件号码为空 |
|
||||
| 该证件号已存在 | 新增/导入时证件号重复 |
|
||||
| 该统一社会信用代码已存在 | 新增/导入时信用代码重复 |
|
||||
|
||||
## 测试账号
|
||||
|
||||
- 用户名: `admin`
|
||||
- 密码: `admin123`
|
||||
|
||||
测试前请先调用 `/login/test` 接口获取 Token。
|
||||
|
||||
## 更新日志
|
||||
|
||||
| 版本 | 日期 | 说明 |
|
||||
|------|------|------|
|
||||
| 1.0.0 | 2026-01-29 | 初始版本,支持个人和机构分类管理 |
|
||||
| 1.1.0 | 2026-01-29 | 添加字典下拉框功能,分离个人/机构模板 |
|
||||
@@ -257,14 +257,30 @@ Authorization: Bearer {token}
|
||||
|
||||
---
|
||||
|
||||
### 7. 下载导入模板
|
||||
### 7. 下载导入模板(带字典下拉框)
|
||||
|
||||
**接口地址**: `POST /dpc/employee/importTemplate`
|
||||
|
||||
**权限要求**: 无
|
||||
|
||||
**功能说明**: 下载的 Excel 模板中,"状态"列会自动添加字典下拉框,方便用户选择。
|
||||
|
||||
**响应**: Excel 模板文件下载
|
||||
|
||||
**Excel 格式说明**:
|
||||
|
||||
**Sheet1: 员工信息**
|
||||
| 姓名 | 柜员号 | 所属部门ID | 身份证号 | 电话 | 入职时间 | 状态▼ |
|
||||
|------|--------|------------|----------|------|----------|------|
|
||||
| 张三 | 001 | 100 | 110101199001011234 | 13800138000 | 2020-01-01 | 在职 |
|
||||
|
||||
**注**:带 ▼ 标记的列包含下拉框,选项来自字典 `dpc_employee_status`。
|
||||
|
||||
**使用 @DictDropdown 注解实现**:
|
||||
- 状态字段使用 `@DictDropdown(dictType = "dpc_employee_status")` 注解
|
||||
- 系统自动从 Redis 缓存读取字典数据并生成下拉框
|
||||
- 下拉选项可动态更新,刷新字典缓存后生效
|
||||
|
||||
---
|
||||
|
||||
### 8. 导入员工信息
|
||||
|
||||
@@ -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-8(utf8mb4)
|
||||
6. **向后兼容**:保持现有接口和数据结构不变
|
||||
|
||||
## 工具类使用
|
||||
|
||||
### EasyExcelUtil 现有方法
|
||||
|
||||
项目已有 `EasyExcelUtil.importTemplateWithDictDropdown()` 方法,可直接使用:
|
||||
|
||||
```java
|
||||
// 生成个人中介模板(带字典下拉框)
|
||||
EasyExcelUtil.importTemplateWithDictDropdown(
|
||||
response,
|
||||
DpcIntermediaryPersonExcel.class,
|
||||
"个人中介黑名单"
|
||||
);
|
||||
|
||||
// 生成机构中介模板(带字典下拉框)
|
||||
EasyExcelUtil.importTemplateWithDictDropdown(
|
||||
response,
|
||||
DpcIntermediaryEntityExcel.class,
|
||||
"机构中介黑名单"
|
||||
);
|
||||
```
|
||||
|
||||
**参考文档:** [doc/EasyExcel字典下拉框使用说明.md](../../../doc/EasyExcel字典下拉框使用说明.md)
|
||||
@@ -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)
|
||||
@@ -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 层
|
||||
@@ -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)
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.ruoyi.common.annotation;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* EasyExcel字典下拉框注解
|
||||
* 用于在生成Excel模板时,为字段添加基于若依字典数据的下拉框
|
||||
*
|
||||
* 使用示例:
|
||||
* <pre>
|
||||
* @DictDropdown(dictType = "sys_user_sex")
|
||||
* @ExcelProperty(value = "性别", index = 2)
|
||||
* private String gender;
|
||||
* </pre>
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.FIELD)
|
||||
public @interface DictDropdown {
|
||||
|
||||
/**
|
||||
* 字典类型编码,对应若依框架字典管理中的字典类型
|
||||
* 如:sys_user_sex、sys_normal_disable等
|
||||
*
|
||||
* @return 字典类型编码
|
||||
*/
|
||||
String dictType();
|
||||
|
||||
/**
|
||||
* 下拉框显示内容类型
|
||||
* LABEL: 显示字典标签(如:男、女)
|
||||
* VALUE: 显示字典键值(如:0、1)
|
||||
*
|
||||
* @return 显示类型
|
||||
*/
|
||||
DisplayType displayType() default DisplayType.LABEL;
|
||||
|
||||
/**
|
||||
* 是否仅允许选择下拉框中的值
|
||||
* true: 只能从下拉框中选择
|
||||
* false: 可以手动输入其他值
|
||||
*
|
||||
* @return 是否仅允许选择
|
||||
*/
|
||||
boolean strict() default true;
|
||||
|
||||
/**
|
||||
* 隐藏Sheet的名称(用于存储大量下拉选项)
|
||||
* 当下拉选项超过Excel字符限制时,会创建隐藏Sheet存储选项
|
||||
*
|
||||
* @return 隐藏Sheet名称
|
||||
*/
|
||||
String hiddenSheetName() default "dict_hidden";
|
||||
|
||||
/**
|
||||
* 显示类型枚举
|
||||
*/
|
||||
enum DisplayType {
|
||||
/**
|
||||
* 显示字典标签
|
||||
*/
|
||||
LABEL,
|
||||
|
||||
/**
|
||||
* 显示字典键值
|
||||
*/
|
||||
VALUE
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,6 @@ import com.ruoyi.dpc.domain.excel.DpcEmployeeExcel;
|
||||
import com.ruoyi.dpc.domain.vo.DpcEmployeeVO;
|
||||
import com.ruoyi.dpc.service.IDpcEmployeeService;
|
||||
import com.ruoyi.dpc.utils.EasyExcelUtil;
|
||||
import com.ruoyi.dpc.utils.handler.EmployeeStatusSheetWriteHandler;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
@@ -111,12 +110,13 @@ public class DpcEmployeeController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载导入模板
|
||||
* 下载带字典下拉框的导入模板
|
||||
* 使用@DictDropdown注解自动添加下拉框
|
||||
*/
|
||||
@Operation(summary = "下载导入模板")
|
||||
@PostMapping("/importTemplate")
|
||||
public void importTemplate(HttpServletResponse response) {
|
||||
EasyExcelUtil.importTemplateExcel(response, DpcEmployeeExcel.class, "员工信息", new EmployeeStatusSheetWriteHandler());
|
||||
EasyExcelUtil.importTemplateWithDictDropdown(response, DpcEmployeeExcel.class, "员工信息");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -13,6 +13,8 @@ import com.ruoyi.dpc.domain.dto.DpcIntermediaryBlacklistAddDTO;
|
||||
import com.ruoyi.dpc.domain.dto.DpcIntermediaryBlacklistEditDTO;
|
||||
import com.ruoyi.dpc.domain.dto.DpcIntermediaryBlacklistQueryDTO;
|
||||
import com.ruoyi.dpc.domain.excel.DpcIntermediaryBlacklistExcel;
|
||||
import com.ruoyi.dpc.domain.excel.DpcIntermediaryEntityExcel;
|
||||
import com.ruoyi.dpc.domain.excel.DpcIntermediaryPersonExcel;
|
||||
import com.ruoyi.dpc.domain.vo.DpcIntermediaryBlacklistVO;
|
||||
import com.ruoyi.dpc.service.IDpcIntermediaryBlacklistService;
|
||||
import com.ruoyi.dpc.utils.EasyExcelUtil;
|
||||
@@ -68,13 +70,13 @@ public class DpcIntermediaryBlacklistController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取中介黑名单详细信息
|
||||
* 获取中介黑名单详细信息(根据类型返回不同结构)
|
||||
*/
|
||||
@Operation(summary = "获取中介黑名单详细信息")
|
||||
@PreAuthorize("@ss.hasPermi('dpc:intermediary:query')")
|
||||
@GetMapping(value = "/{intermediaryId}")
|
||||
public AjaxResult getInfo(@PathVariable Long intermediaryId) {
|
||||
return success(intermediaryService.selectIntermediaryById(intermediaryId));
|
||||
return success(intermediaryService.selectIntermediaryDetailById(intermediaryId));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,24 +113,46 @@ public class DpcIntermediaryBlacklistController extends BaseController {
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载导入模板
|
||||
* 下载个人中介导入模板(带字典下拉框)
|
||||
*/
|
||||
@Operation(summary = "下载导入模板")
|
||||
@PostMapping("/importTemplate")
|
||||
public void importTemplate(HttpServletResponse response) {
|
||||
EasyExcelUtil.importTemplateExcel(response, DpcIntermediaryBlacklistExcel.class, "中介黑名单");
|
||||
@Operation(summary = "下载个人中介导入模板")
|
||||
@PostMapping("/importPersonTemplate")
|
||||
public void importPersonTemplate(HttpServletResponse response) {
|
||||
EasyExcelUtil.importTemplateWithDictDropdown(response, DpcIntermediaryPersonExcel.class, "个人中介黑名单");
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入中介黑名单
|
||||
* 下载机构中介导入模板(带字典下拉框)
|
||||
*/
|
||||
@Operation(summary = "导入中介黑名单")
|
||||
@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("/importData")
|
||||
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
|
||||
List<DpcIntermediaryBlacklistExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), DpcIntermediaryBlacklistExcel.class);
|
||||
String message = intermediaryService.importIntermediary(list, updateSupport);
|
||||
@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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,96 @@ public class DpcIntermediaryBlacklist implements Serializable {
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
// ============================================================
|
||||
// 个人类型字段 (以 indiv_ 前缀标识,individual 缩写)
|
||||
// ============================================================
|
||||
/** 人员类型(中介、职业背债人、房产中介等) */
|
||||
private String indivType;
|
||||
|
||||
/** 人员子类型(本人、配偶等) */
|
||||
private String indivSubType;
|
||||
|
||||
/** 性别(M男 F女 O其他) */
|
||||
private String indivGender;
|
||||
|
||||
/** 证件类型 */
|
||||
private String indivCertType;
|
||||
|
||||
/** 手机号码(加密存储) */
|
||||
private String indivPhone;
|
||||
|
||||
/** 微信号 */
|
||||
private String indivWechat;
|
||||
|
||||
/** 联系地址 */
|
||||
private String indivAddress;
|
||||
|
||||
/** 所在公司 */
|
||||
private String indivCompany;
|
||||
|
||||
/** 职位/职务 */
|
||||
private String indivPosition;
|
||||
|
||||
/** 关联人员ID */
|
||||
private String indivRelatedId;
|
||||
|
||||
/** 关联关系 */
|
||||
private String indivRelation;
|
||||
|
||||
// ============================================================
|
||||
// 机构类型字段 (以 corp_ 前缀标识,corporation 缩写)
|
||||
// ============================================================
|
||||
/** 统一社会信用代码 */
|
||||
private String corpCreditCode;
|
||||
|
||||
/** 主体类型(有限责任公司、股份有限公司等) */
|
||||
private String corpType;
|
||||
|
||||
/** 企业性质(国企、民企、外企等) */
|
||||
private String corpNature;
|
||||
|
||||
/** 行业分类 */
|
||||
private String corpIndustryCategory;
|
||||
|
||||
/** 所属行业 */
|
||||
private String corpIndustry;
|
||||
|
||||
/** 成立日期 */
|
||||
private Date corpEstablishDate;
|
||||
|
||||
/** 注册地址 */
|
||||
private String corpAddress;
|
||||
|
||||
/** 法定代表人 */
|
||||
private String corpLegalRep;
|
||||
|
||||
/** 法定代表人证件类型 */
|
||||
private String corpLegalCertType;
|
||||
|
||||
/** 法定代表人证件号码 */
|
||||
private String corpLegalCertNo;
|
||||
|
||||
/** 股东1 */
|
||||
private String corpShareholder1;
|
||||
|
||||
/** 股东2 */
|
||||
private String corpShareholder2;
|
||||
|
||||
/** 股东3 */
|
||||
private String corpShareholder3;
|
||||
|
||||
/** 股东4 */
|
||||
private String corpShareholder4;
|
||||
|
||||
/** 股东5 */
|
||||
private String corpShareholder5;
|
||||
|
||||
// ============================================================
|
||||
// 通用字段
|
||||
// ============================================================
|
||||
/** 数据来源(MANUAL手动录入 SYSTEM系统同步 IMPORT批量导入 API接口获取) */
|
||||
private String dataSource;
|
||||
|
||||
/** 创建者 */
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createBy;
|
||||
|
||||
@@ -0,0 +1,239 @@
|
||||
package com.ruoyi.dpc.domain.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 机构中介黑名单新增 DTO
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-01-29
|
||||
*/
|
||||
public class DpcIntermediaryEntityAddDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 机构名称 */
|
||||
@NotBlank(message = "机构名称不能为空")
|
||||
@Size(min = 1, max = 100, message = "机构名称长度不能超过100个字符")
|
||||
private String name;
|
||||
|
||||
/** 状态 */
|
||||
@NotBlank(message = "状态不能为空")
|
||||
private String status;
|
||||
|
||||
/** 备注 */
|
||||
@Size(max = 500, message = "备注长度不能超过500个字符")
|
||||
private String remark;
|
||||
|
||||
// ============================================================
|
||||
// 机构专属字段
|
||||
// ============================================================
|
||||
/** 统一社会信用代码 */
|
||||
@Size(max = 18, message = "统一社会信用代码长度不能超过18个字符")
|
||||
private String corpCreditCode;
|
||||
|
||||
/** 主体类型 */
|
||||
@Size(max = 50, message = "主体类型长度不能超过50个字符")
|
||||
private String corpType;
|
||||
|
||||
/** 企业性质 */
|
||||
@Size(max = 50, message = "企业性质长度不能超过50个字符")
|
||||
private String corpNature;
|
||||
|
||||
/** 行业分类 */
|
||||
@Size(max = 100, message = "行业分类长度不能超过100个字符")
|
||||
private String corpIndustryCategory;
|
||||
|
||||
/** 所属行业 */
|
||||
@Size(max = 100, message = "所属行业长度不能超过100个字符")
|
||||
private String corpIndustry;
|
||||
|
||||
/** 成立日期 */
|
||||
private Date corpEstablishDate;
|
||||
|
||||
/** 注册地址 */
|
||||
@Size(max = 500, message = "注册地址长度不能超过500个字符")
|
||||
private String corpAddress;
|
||||
|
||||
/** 法定代表人 */
|
||||
@Size(max = 50, message = "法定代表人长度不能超过50个字符")
|
||||
private String corpLegalRep;
|
||||
|
||||
/** 法定代表人证件类型 */
|
||||
@Size(max = 30, message = "法定代表人证件类型长度不能超过30个字符")
|
||||
private String corpLegalCertType;
|
||||
|
||||
/** 法定代表人证件号码 */
|
||||
@Size(max = 30, message = "法定代表人证件号码长度不能超过30个字符")
|
||||
private String corpLegalCertNo;
|
||||
|
||||
/** 股东1 */
|
||||
@Size(max = 30, message = "股东1长度不能超过30个字符")
|
||||
private String corpShareholder1;
|
||||
|
||||
/** 股东2 */
|
||||
@Size(max = 30, message = "股东2长度不能超过30个字符")
|
||||
private String corpShareholder2;
|
||||
|
||||
/** 股东3 */
|
||||
@Size(max = 30, message = "股东3长度不能超过30个字符")
|
||||
private String corpShareholder3;
|
||||
|
||||
/** 股东4 */
|
||||
@Size(max = 30, message = "股东4长度不能超过30个字符")
|
||||
private String corpShareholder4;
|
||||
|
||||
/** 股东5 */
|
||||
@Size(max = 30, message = "股东5长度不能超过30个字符")
|
||||
private String corpShareholder5;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getCorpCreditCode() {
|
||||
return corpCreditCode;
|
||||
}
|
||||
|
||||
public void setCorpCreditCode(String corpCreditCode) {
|
||||
this.corpCreditCode = corpCreditCode;
|
||||
}
|
||||
|
||||
public String getCorpType() {
|
||||
return corpType;
|
||||
}
|
||||
|
||||
public void setCorpType(String corpType) {
|
||||
this.corpType = corpType;
|
||||
}
|
||||
|
||||
public String getCorpNature() {
|
||||
return corpNature;
|
||||
}
|
||||
|
||||
public void setCorpNature(String corpNature) {
|
||||
this.corpNature = corpNature;
|
||||
}
|
||||
|
||||
public String getCorpIndustryCategory() {
|
||||
return corpIndustryCategory;
|
||||
}
|
||||
|
||||
public void setCorpIndustryCategory(String corpIndustryCategory) {
|
||||
this.corpIndustryCategory = corpIndustryCategory;
|
||||
}
|
||||
|
||||
public String getCorpIndustry() {
|
||||
return corpIndustry;
|
||||
}
|
||||
|
||||
public void setCorpIndustry(String corpIndustry) {
|
||||
this.corpIndustry = corpIndustry;
|
||||
}
|
||||
|
||||
public Date getCorpEstablishDate() {
|
||||
return corpEstablishDate;
|
||||
}
|
||||
|
||||
public void setCorpEstablishDate(Date corpEstablishDate) {
|
||||
this.corpEstablishDate = corpEstablishDate;
|
||||
}
|
||||
|
||||
public String getCorpAddress() {
|
||||
return corpAddress;
|
||||
}
|
||||
|
||||
public void setCorpAddress(String corpAddress) {
|
||||
this.corpAddress = corpAddress;
|
||||
}
|
||||
|
||||
public String getCorpLegalRep() {
|
||||
return corpLegalRep;
|
||||
}
|
||||
|
||||
public void setCorpLegalRep(String corpLegalRep) {
|
||||
this.corpLegalRep = corpLegalRep;
|
||||
}
|
||||
|
||||
public String getCorpLegalCertType() {
|
||||
return corpLegalCertType;
|
||||
}
|
||||
|
||||
public void setCorpLegalCertType(String corpLegalCertType) {
|
||||
this.corpLegalCertType = corpLegalCertType;
|
||||
}
|
||||
|
||||
public String getCorpLegalCertNo() {
|
||||
return corpLegalCertNo;
|
||||
}
|
||||
|
||||
public void setCorpLegalCertNo(String corpLegalCertNo) {
|
||||
this.corpLegalCertNo = corpLegalCertNo;
|
||||
}
|
||||
|
||||
public String getCorpShareholder1() {
|
||||
return corpShareholder1;
|
||||
}
|
||||
|
||||
public void setCorpShareholder1(String corpShareholder1) {
|
||||
this.corpShareholder1 = corpShareholder1;
|
||||
}
|
||||
|
||||
public String getCorpShareholder2() {
|
||||
return corpShareholder2;
|
||||
}
|
||||
|
||||
public void setCorpShareholder2(String corpShareholder2) {
|
||||
this.corpShareholder2 = corpShareholder2;
|
||||
}
|
||||
|
||||
public String getCorpShareholder3() {
|
||||
return corpShareholder3;
|
||||
}
|
||||
|
||||
public void setCorpShareholder3(String corpShareholder3) {
|
||||
this.corpShareholder3 = corpShareholder3;
|
||||
}
|
||||
|
||||
public String getCorpShareholder4() {
|
||||
return corpShareholder4;
|
||||
}
|
||||
|
||||
public void setCorpShareholder4(String corpShareholder4) {
|
||||
this.corpShareholder4 = corpShareholder4;
|
||||
}
|
||||
|
||||
public String getCorpShareholder5() {
|
||||
return corpShareholder5;
|
||||
}
|
||||
|
||||
public void setCorpShareholder5(String corpShareholder5) {
|
||||
this.corpShareholder5 = corpShareholder5;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,204 @@
|
||||
package com.ruoyi.dpc.domain.dto;
|
||||
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.Size;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 个人中介黑名单新增 DTO
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-01-29
|
||||
*/
|
||||
public class DpcIntermediaryPersonAddDTO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 姓名 */
|
||||
@NotBlank(message = "姓名不能为空")
|
||||
@Size(min = 1, max = 100, message = "姓名长度不能超过100个字符")
|
||||
private String name;
|
||||
|
||||
/** 证件号码 */
|
||||
@NotBlank(message = "证件号码不能为空")
|
||||
@Size(max = 50, message = "证件号码长度不能超过50个字符")
|
||||
private String certificateNo;
|
||||
|
||||
/** 状态 */
|
||||
@NotBlank(message = "状态不能为空")
|
||||
private String status;
|
||||
|
||||
/** 备注 */
|
||||
@Size(max = 500, message = "备注长度不能超过500个字符")
|
||||
private String remark;
|
||||
|
||||
// ============================================================
|
||||
// 个人专属字段
|
||||
// ============================================================
|
||||
/** 人员类型 */
|
||||
@Size(max = 30, message = "人员类型长度不能超过30个字符")
|
||||
private String indivType;
|
||||
|
||||
/** 人员子类型 */
|
||||
@Size(max = 50, message = "人员子类型长度不能超过50个字符")
|
||||
private String indivSubType;
|
||||
|
||||
/** 性别 */
|
||||
@Size(max = 1, message = "性别长度不能超过1个字符")
|
||||
private String indivGender;
|
||||
|
||||
/** 证件类型 */
|
||||
@Size(max = 30, message = "证件类型长度不能超过30个字符")
|
||||
private String indivCertType;
|
||||
|
||||
/** 手机号码 */
|
||||
@Size(max = 20, message = "手机号码长度不能超过20个字符")
|
||||
private String indivPhone;
|
||||
|
||||
/** 微信号 */
|
||||
@Size(max = 50, message = "微信号长度不能超过50个字符")
|
||||
private String indivWechat;
|
||||
|
||||
/** 联系地址 */
|
||||
@Size(max = 200, message = "联系地址长度不能超过200个字符")
|
||||
private String indivAddress;
|
||||
|
||||
/** 所在公司 */
|
||||
@Size(max = 100, message = "所在公司长度不能超过100个字符")
|
||||
private String indivCompany;
|
||||
|
||||
/** 职位/职务 */
|
||||
@Size(max = 100, message = "职位长度不能超过100个字符")
|
||||
private String indivPosition;
|
||||
|
||||
/** 关联人员ID */
|
||||
@Size(max = 20, message = "关联人员ID长度不能超过20个字符")
|
||||
private String indivRelatedId;
|
||||
|
||||
/** 关联关系 */
|
||||
@Size(max = 50, message = "关联关系长度不能超过50个字符")
|
||||
private String indivRelation;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCertificateNo() {
|
||||
return certificateNo;
|
||||
}
|
||||
|
||||
public void setCertificateNo(String certificateNo) {
|
||||
this.certificateNo = certificateNo;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getIndivType() {
|
||||
return indivType;
|
||||
}
|
||||
|
||||
public void setIndivType(String indivType) {
|
||||
this.indivType = indivType;
|
||||
}
|
||||
|
||||
public String getIndivSubType() {
|
||||
return indivSubType;
|
||||
}
|
||||
|
||||
public void setIndivSubType(String indivSubType) {
|
||||
this.indivSubType = indivSubType;
|
||||
}
|
||||
|
||||
public String getIndivGender() {
|
||||
return indivGender;
|
||||
}
|
||||
|
||||
public void setIndivGender(String indivGender) {
|
||||
this.indivGender = indivGender;
|
||||
}
|
||||
|
||||
public String getIndivCertType() {
|
||||
return indivCertType;
|
||||
}
|
||||
|
||||
public void setIndivCertType(String indivCertType) {
|
||||
this.indivCertType = indivCertType;
|
||||
}
|
||||
|
||||
public String getIndivPhone() {
|
||||
return indivPhone;
|
||||
}
|
||||
|
||||
public void setIndivPhone(String indivPhone) {
|
||||
this.indivPhone = indivPhone;
|
||||
}
|
||||
|
||||
public String getIndivWechat() {
|
||||
return indivWechat;
|
||||
}
|
||||
|
||||
public void setIndivWechat(String indivWechat) {
|
||||
this.indivWechat = indivWechat;
|
||||
}
|
||||
|
||||
public String getIndivAddress() {
|
||||
return indivAddress;
|
||||
}
|
||||
|
||||
public void setIndivAddress(String indivAddress) {
|
||||
this.indivAddress = indivAddress;
|
||||
}
|
||||
|
||||
public String getIndivCompany() {
|
||||
return indivCompany;
|
||||
}
|
||||
|
||||
public void setIndivCompany(String indivCompany) {
|
||||
this.indivCompany = indivCompany;
|
||||
}
|
||||
|
||||
public String getIndivPosition() {
|
||||
return indivPosition;
|
||||
}
|
||||
|
||||
public void setIndivPosition(String indivPosition) {
|
||||
this.indivPosition = indivPosition;
|
||||
}
|
||||
|
||||
public String getIndivRelatedId() {
|
||||
return indivRelatedId;
|
||||
}
|
||||
|
||||
public void setIndivRelatedId(String indivRelatedId) {
|
||||
this.indivRelatedId = indivRelatedId;
|
||||
}
|
||||
|
||||
public String getIndivRelation() {
|
||||
return indivRelation;
|
||||
}
|
||||
|
||||
public void setIndivRelation(String indivRelation) {
|
||||
this.indivRelation = indivRelation;
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@ package com.ruoyi.dpc.domain.excel;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.ruoyi.dpc.utils.converter.EmployeeStatusConverter;
|
||||
import com.ruoyi.common.annotation.DictDropdown;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
@@ -52,7 +52,8 @@ public class DpcEmployeeExcel implements Serializable {
|
||||
private Date hireDate;
|
||||
|
||||
/** 状态 */
|
||||
@ExcelProperty(value = "状态", converter = EmployeeStatusConverter.class, index = 6)
|
||||
@ExcelProperty(value = "状态", index = 6)
|
||||
@ColumnWidth(10)
|
||||
@DictDropdown(dictType = "dpc_employee_status")
|
||||
private String status;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.ruoyi.dpc.domain.excel;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.ruoyi.common.annotation.DictDropdown;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 机构中介黑名单Excel导入对象
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-01-29
|
||||
*/
|
||||
@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;
|
||||
|
||||
@ExcelProperty(value = "主体类型", index = 2)
|
||||
@ColumnWidth(20)
|
||||
@DictDropdown(dictType = "dpc_entity_type")
|
||||
private String corpType;
|
||||
|
||||
@ExcelProperty(value = "企业性质", index = 3)
|
||||
@ColumnWidth(15)
|
||||
@DictDropdown(dictType = "dpc_enterprise_nature")
|
||||
private String corpNature;
|
||||
|
||||
@ExcelProperty(value = "行业分类", index = 4)
|
||||
@ColumnWidth(15)
|
||||
private String corpIndustryCategory;
|
||||
|
||||
@ExcelProperty(value = "所属行业", index = 5)
|
||||
@ColumnWidth(15)
|
||||
private String corpIndustry;
|
||||
|
||||
@ExcelProperty(value = "成立日期", index = 6)
|
||||
@ColumnWidth(15)
|
||||
private String corpEstablishDate;
|
||||
|
||||
@ExcelProperty(value = "注册地址", index = 7)
|
||||
@ColumnWidth(40)
|
||||
private String corpAddress;
|
||||
|
||||
@ExcelProperty(value = "法定代表人", index = 8)
|
||||
@ColumnWidth(15)
|
||||
private String corpLegalRep;
|
||||
|
||||
@ExcelProperty(value = "法定代表人证件类型", index = 9)
|
||||
@ColumnWidth(20)
|
||||
private String corpLegalCertType;
|
||||
|
||||
@ExcelProperty(value = "法定代表人证件号码", index = 10)
|
||||
@ColumnWidth(20)
|
||||
private String corpLegalCertNo;
|
||||
|
||||
@ExcelProperty(value = "股东1", index = 11)
|
||||
@ColumnWidth(15)
|
||||
private String corpShareholder1;
|
||||
|
||||
@ExcelProperty(value = "股东2", index = 12)
|
||||
@ColumnWidth(15)
|
||||
private String corpShareholder2;
|
||||
|
||||
@ExcelProperty(value = "股东3", index = 13)
|
||||
@ColumnWidth(15)
|
||||
private String corpShareholder3;
|
||||
|
||||
@ExcelProperty(value = "股东4", index = 14)
|
||||
@ColumnWidth(15)
|
||||
private String corpShareholder4;
|
||||
|
||||
@ExcelProperty(value = "股东5", index = 15)
|
||||
@ColumnWidth(15)
|
||||
private String corpShareholder5;
|
||||
|
||||
@ExcelProperty(value = "备注", index = 16)
|
||||
@ColumnWidth(30)
|
||||
private String remark;
|
||||
|
||||
// 以下字段不在 Excel 中显示,由系统自动设置
|
||||
// private String status; // 默认:正常(0)
|
||||
// private String dataSource; // 默认:批量导入(IMPORT)
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.ruoyi.dpc.domain.excel;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.ruoyi.common.annotation.DictDropdown;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 个人中介黑名单Excel导入对象
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-01-29
|
||||
*/
|
||||
@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;
|
||||
|
||||
@ExcelProperty(value = "人员子类型", index = 2)
|
||||
@ColumnWidth(15)
|
||||
private String indivSubType;
|
||||
|
||||
@ExcelProperty(value = "性别", index = 3)
|
||||
@ColumnWidth(10)
|
||||
@DictDropdown(dictType = "dpc_indiv_gender")
|
||||
private String indivGender;
|
||||
|
||||
@ExcelProperty(value = "证件类型", index = 4)
|
||||
@ColumnWidth(15)
|
||||
@DictDropdown(dictType = "dpc_certificate_type")
|
||||
private String indivCertType;
|
||||
|
||||
@ExcelProperty(value = "证件号码", index = 5)
|
||||
@ColumnWidth(20)
|
||||
private String certificateNo;
|
||||
|
||||
@ExcelProperty(value = "手机号码", index = 6)
|
||||
@ColumnWidth(15)
|
||||
private String indivPhone;
|
||||
|
||||
@ExcelProperty(value = "微信号", index = 7)
|
||||
@ColumnWidth(15)
|
||||
private String indivWechat;
|
||||
|
||||
@ExcelProperty(value = "联系地址", index = 8)
|
||||
@ColumnWidth(30)
|
||||
private String indivAddress;
|
||||
|
||||
@ExcelProperty(value = "所在公司", index = 9)
|
||||
@ColumnWidth(20)
|
||||
private String indivCompany;
|
||||
|
||||
@ExcelProperty(value = "职位", index = 10)
|
||||
@ColumnWidth(15)
|
||||
private String indivPosition;
|
||||
|
||||
@ExcelProperty(value = "关联人员ID", index = 11)
|
||||
@ColumnWidth(15)
|
||||
private String indivRelatedId;
|
||||
|
||||
@ExcelProperty(value = "关联关系", index = 12)
|
||||
@ColumnWidth(15)
|
||||
private String indivRelation;
|
||||
|
||||
@ExcelProperty(value = "备注", index = 13)
|
||||
@ColumnWidth(30)
|
||||
private String remark;
|
||||
|
||||
// 以下字段不在 Excel 中显示,由系统自动设置
|
||||
// private String status; // 默认:正常(0)
|
||||
// private String dataSource; // 默认:批量导入(IMPORT)
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.ruoyi.dpc.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
@@ -12,6 +13,7 @@ import java.util.Date;
|
||||
* @author ruoyi
|
||||
* @date 2026-01-27
|
||||
*/
|
||||
@Data
|
||||
public class DpcIntermediaryBlacklistVO implements Serializable {
|
||||
|
||||
@Serial
|
||||
@@ -54,100 +56,4 @@ public class DpcIntermediaryBlacklistVO implements Serializable {
|
||||
/** 更新时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
|
||||
public Long getIntermediaryId() {
|
||||
return intermediaryId;
|
||||
}
|
||||
|
||||
public void setIntermediaryId(Long intermediaryId) {
|
||||
this.intermediaryId = intermediaryId;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getCertificateNo() {
|
||||
return certificateNo;
|
||||
}
|
||||
|
||||
public void setCertificateNo(String certificateNo) {
|
||||
this.certificateNo = certificateNo;
|
||||
}
|
||||
|
||||
public String getIntermediaryType() {
|
||||
return intermediaryType;
|
||||
}
|
||||
|
||||
public void setIntermediaryType(String intermediaryType) {
|
||||
this.intermediaryType = intermediaryType;
|
||||
}
|
||||
|
||||
public String getIntermediaryTypeName() {
|
||||
return intermediaryTypeName;
|
||||
}
|
||||
|
||||
public void setIntermediaryTypeName(String intermediaryTypeName) {
|
||||
this.intermediaryTypeName = intermediaryTypeName;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getStatusName() {
|
||||
return statusName;
|
||||
}
|
||||
|
||||
public void setStatusName(String statusName) {
|
||||
this.statusName = statusName;
|
||||
}
|
||||
|
||||
public String getRemark() {
|
||||
return remark;
|
||||
}
|
||||
|
||||
public void setRemark(String remark) {
|
||||
this.remark = remark;
|
||||
}
|
||||
|
||||
public String getCreateBy() {
|
||||
return createBy;
|
||||
}
|
||||
|
||||
public void setCreateBy(String createBy) {
|
||||
this.createBy = createBy;
|
||||
}
|
||||
|
||||
public Date getCreateTime() {
|
||||
return createTime;
|
||||
}
|
||||
|
||||
public void setCreateTime(Date createTime) {
|
||||
this.createTime = createTime;
|
||||
}
|
||||
|
||||
public String getUpdateBy() {
|
||||
return updateBy;
|
||||
}
|
||||
|
||||
public void setUpdateBy(String updateBy) {
|
||||
this.updateBy = updateBy;
|
||||
}
|
||||
|
||||
public Date getUpdateTime() {
|
||||
return updateTime;
|
||||
}
|
||||
|
||||
public void setUpdateTime(Date updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.ruoyi.dpc.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 机构中介黑名单详情 VO
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-01-29
|
||||
*/
|
||||
@Data
|
||||
public class DpcIntermediaryEntityDetailVO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// ============================================================
|
||||
// 核心字段
|
||||
// ============================================================
|
||||
/** 中介ID */
|
||||
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;
|
||||
|
||||
/** 数据来源名称 */
|
||||
private String dataSourceName;
|
||||
|
||||
// ============================================================
|
||||
// 机构专属字段
|
||||
// ============================================================
|
||||
/** 统一社会信用代码 */
|
||||
private String corpCreditCode;
|
||||
|
||||
/** 主体类型 */
|
||||
private String corpType;
|
||||
|
||||
/** 主体类型名称 */
|
||||
private String corpTypeName;
|
||||
|
||||
/** 企业性质 */
|
||||
private String corpNature;
|
||||
|
||||
/** 企业性质名称 */
|
||||
private String corpNatureName;
|
||||
|
||||
/** 行业分类 */
|
||||
private String corpIndustryCategory;
|
||||
|
||||
/** 所属行业 */
|
||||
private String corpIndustry;
|
||||
|
||||
/** 成立日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd")
|
||||
private Date corpEstablishDate;
|
||||
|
||||
/** 注册地址 */
|
||||
private String corpAddress;
|
||||
|
||||
/** 法定代表人 */
|
||||
private String corpLegalRep;
|
||||
|
||||
/** 法定代表人证件类型 */
|
||||
private String corpLegalCertType;
|
||||
|
||||
/** 法定代表人证件号码 */
|
||||
private String corpLegalCertNo;
|
||||
|
||||
/** 股东1 */
|
||||
private String corpShareholder1;
|
||||
|
||||
/** 股东2 */
|
||||
private String corpShareholder2;
|
||||
|
||||
/** 股东3 */
|
||||
private String corpShareholder3;
|
||||
|
||||
/** 股东4 */
|
||||
private String corpShareholder4;
|
||||
|
||||
/** 股东5 */
|
||||
private String corpShareholder5;
|
||||
|
||||
// ============================================================
|
||||
// 审计字段
|
||||
// ============================================================
|
||||
/** 创建者 */
|
||||
private String createBy;
|
||||
|
||||
/** 创建时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/** 更新者 */
|
||||
private String updateBy;
|
||||
|
||||
/** 更新时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
}
|
||||
@@ -0,0 +1,113 @@
|
||||
package com.ruoyi.dpc.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 个人中介黑名单详情 VO
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-01-29
|
||||
*/
|
||||
@Data
|
||||
public class DpcIntermediaryPersonDetailVO implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// ============================================================
|
||||
// 核心字段
|
||||
// ============================================================
|
||||
/** 中介ID */
|
||||
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;
|
||||
|
||||
/** 数据来源名称 */
|
||||
private String dataSourceName;
|
||||
|
||||
// ============================================================
|
||||
// 个人专属字段
|
||||
// ============================================================
|
||||
/** 人员类型 */
|
||||
private String indivType;
|
||||
|
||||
/** 人员子类型 */
|
||||
private String indivSubType;
|
||||
|
||||
/** 性别 */
|
||||
private String indivGender;
|
||||
|
||||
/** 性别名称 */
|
||||
private String indivGenderName;
|
||||
|
||||
/** 证件类型 */
|
||||
private String indivCertType;
|
||||
|
||||
/** 证件类型名称 */
|
||||
private String indivCertTypeName;
|
||||
|
||||
/** 手机号码 */
|
||||
private String indivPhone;
|
||||
|
||||
/** 微信号 */
|
||||
private String indivWechat;
|
||||
|
||||
/** 联系地址 */
|
||||
private String indivAddress;
|
||||
|
||||
/** 所在公司 */
|
||||
private String indivCompany;
|
||||
|
||||
/** 职位/职务 */
|
||||
private String indivPosition;
|
||||
|
||||
/** 关联人员ID */
|
||||
private String indivRelatedId;
|
||||
|
||||
/** 关联关系 */
|
||||
private String indivRelation;
|
||||
|
||||
// ============================================================
|
||||
// 审计字段
|
||||
// ============================================================
|
||||
/** 创建者 */
|
||||
private String createBy;
|
||||
|
||||
/** 创建时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date createTime;
|
||||
|
||||
/** 更新者 */
|
||||
private String updateBy;
|
||||
|
||||
/** 更新时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
|
||||
private Date updateTime;
|
||||
}
|
||||
41
ruoyi-dpc/src/main/java/com/ruoyi/dpc/enums/DataSource.java
Normal file
41
ruoyi-dpc/src/main/java/com/ruoyi/dpc/enums/DataSource.java
Normal file
@@ -0,0 +1,41 @@
|
||||
package com.ruoyi.dpc.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 数据来源枚举
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum DataSource {
|
||||
|
||||
/** 手动录入 */
|
||||
MANUAL("MANUAL", "手动录入"),
|
||||
|
||||
/** 系统同步 */
|
||||
SYSTEM("SYSTEM", "系统同步"),
|
||||
|
||||
/** 批量导入 */
|
||||
IMPORT("IMPORT", "批量导入"),
|
||||
|
||||
/** 接口获取 */
|
||||
API("API", "接口获取");
|
||||
|
||||
private final String code;
|
||||
private final String desc;
|
||||
|
||||
/**
|
||||
* 根据编码获取描述
|
||||
*/
|
||||
public static String getDescByCode(String code) {
|
||||
for (DataSource source : values()) {
|
||||
if (source.getCode().equals(code)) {
|
||||
return source.getDesc();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.ruoyi.dpc.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 员工状态枚举
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum EmployeeStatus {
|
||||
|
||||
/** 在职 */
|
||||
ACTIVE("0", "在职"),
|
||||
|
||||
/** 离职 */
|
||||
INACTIVE("1", "离职");
|
||||
|
||||
private final String code;
|
||||
private final String desc;
|
||||
|
||||
/**
|
||||
* 根据编码获取描述
|
||||
*/
|
||||
public static String getDescByCode(String code) {
|
||||
for (EmployeeStatus status : values()) {
|
||||
if (status.getCode().equals(code)) {
|
||||
return status.getDesc();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
38
ruoyi-dpc/src/main/java/com/ruoyi/dpc/enums/Gender.java
Normal file
38
ruoyi-dpc/src/main/java/com/ruoyi/dpc/enums/Gender.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.ruoyi.dpc.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 性别枚举
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum Gender {
|
||||
|
||||
/** 男 */
|
||||
MALE("M", "男"),
|
||||
|
||||
/** 女 */
|
||||
FEMALE("F", "女"),
|
||||
|
||||
/** 其他 */
|
||||
OTHER("O", "其他");
|
||||
|
||||
private final String code;
|
||||
private final String desc;
|
||||
|
||||
/**
|
||||
* 根据编码获取描述
|
||||
*/
|
||||
public static String getDescByCode(String code) {
|
||||
for (Gender gender : values()) {
|
||||
if (gender.getCode().equals(code)) {
|
||||
return gender.getDesc();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.ruoyi.dpc.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 中介状态枚举
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum IntermediaryStatus {
|
||||
|
||||
/** 正常 */
|
||||
NORMAL("0", "正常"),
|
||||
|
||||
/** 停用 */
|
||||
DISABLED("1", "停用");
|
||||
|
||||
private final String code;
|
||||
private final String desc;
|
||||
|
||||
/**
|
||||
* 根据编码获取描述
|
||||
*/
|
||||
public static String getDescByCode(String code) {
|
||||
for (IntermediaryStatus status : values()) {
|
||||
if (status.getCode().equals(code)) {
|
||||
return status.getDesc();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.ruoyi.dpc.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 中介类型枚举
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum IntermediaryType {
|
||||
|
||||
/** 个人 */
|
||||
PERSON("1", "个人"),
|
||||
|
||||
/** 机构 */
|
||||
ENTITY("2", "机构");
|
||||
|
||||
private final String code;
|
||||
private final String desc;
|
||||
|
||||
/**
|
||||
* 根据编码获取描述
|
||||
*/
|
||||
public static String getDescByCode(String code) {
|
||||
for (IntermediaryType type : values()) {
|
||||
if (type.getCode().equals(code)) {
|
||||
return type.getDesc();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
package com.ruoyi.dpc.handler;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.write.handler.SheetWriteHandler;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
|
||||
import com.ruoyi.common.annotation.DictDropdown;
|
||||
import com.ruoyi.common.core.domain.entity.SysDictData;
|
||||
import com.ruoyi.common.utils.DictUtils;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.poi.ss.usermodel.*;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* EasyExcel字典下拉框写入处理器
|
||||
* 在Excel模板生成时,为标注了@DictDropdown注解的字段添加下拉框
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Slf4j
|
||||
public class DictDropdownWriteHandler implements SheetWriteHandler {
|
||||
|
||||
/**
|
||||
* Excel下拉列表直接写入的最大字符数限制
|
||||
*/
|
||||
private static final int MAX_DIRECT_LENGTH = 255;
|
||||
|
||||
/**
|
||||
* 实体类Class对象
|
||||
*/
|
||||
private final Class<?> modelClass;
|
||||
|
||||
/**
|
||||
* 构造函数
|
||||
*
|
||||
* @param modelClass 实体类Class对象
|
||||
*/
|
||||
public DictDropdownWriteHandler(Class<?> modelClass) {
|
||||
this.modelClass = modelClass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
|
||||
// 获取工作簿和工作表
|
||||
Workbook workbook = writeWorkbookHolder.getWorkbook();
|
||||
Sheet sheet = writeSheetHolder.getSheet();
|
||||
|
||||
// 创建数据验证助手
|
||||
DataValidationHelper validationHelper = sheet.getDataValidationHelper();
|
||||
|
||||
// 解析实体类中的字段及其注解
|
||||
Map<Integer, DictDropdown> dropdownMap = parseDropdownFields();
|
||||
|
||||
// 为每个需要下拉框的字段添加数据验证
|
||||
for (Map.Entry<Integer, DictDropdown> entry : dropdownMap.entrySet()) {
|
||||
Integer columnIndex = entry.getKey();
|
||||
DictDropdown dropdown = entry.getValue();
|
||||
|
||||
try {
|
||||
// 获取字典数据
|
||||
List<SysDictData> dictDataList = getDictData(dropdown.dictType());
|
||||
if (dictDataList == null || dictDataList.isEmpty()) {
|
||||
log.warn("字典类型[{}]没有可用数据,跳过下拉框创建", dropdown.dictType());
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取下拉选项列表
|
||||
String[] dropdownOptions = extractOptions(dictDataList, dropdown.displayType());
|
||||
if (dropdownOptions.length == 0) {
|
||||
log.warn("字典类型[{}]提取选项为空,跳过下拉框创建", dropdown.dictType());
|
||||
continue;
|
||||
}
|
||||
|
||||
// 创建数据验证
|
||||
DataValidation validation = createDataValidation(
|
||||
workbook,
|
||||
sheet,
|
||||
validationHelper,
|
||||
columnIndex,
|
||||
dropdownOptions,
|
||||
dropdown.hiddenSheetName(),
|
||||
dropdown.strict()
|
||||
);
|
||||
|
||||
if (validation != null) {
|
||||
sheet.addValidationData(validation);
|
||||
log.info("成功为列[{}]添加字典[{}]的下拉框,选项数量:{}", columnIndex, dropdown.dictType(), dropdownOptions.length);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("为列[{}]添加字典[{}]下拉框失败:{}", columnIndex, dropdown.dictType(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析实体类中的字段,获取需要添加下拉框的字段及其注解
|
||||
*
|
||||
* @return 字段索引与注解的映射
|
||||
*/
|
||||
private Map<Integer, DictDropdown> parseDropdownFields() {
|
||||
Map<Integer, DictDropdown> result = new HashMap<>();
|
||||
|
||||
// 获取所有字段(包括父类的)
|
||||
List<Field> fields = getAllFields(modelClass);
|
||||
|
||||
for (Field field : fields) {
|
||||
// 检查是否有@DictDropdown注解
|
||||
DictDropdown dropdown = field.getAnnotation(DictDropdown.class);
|
||||
if (dropdown == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 获取列索引
|
||||
Integer columnIndex = getColumnIndex(field);
|
||||
if (columnIndex == null) {
|
||||
log.warn("字段[{}]没有指定@ExcelProperty的index,跳过下拉框创建", field.getName());
|
||||
continue;
|
||||
}
|
||||
|
||||
result.put(columnIndex, dropdown);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取类的所有字段(包括父类的)
|
||||
*
|
||||
* @param clazz 类对象
|
||||
* @return 字段列表
|
||||
*/
|
||||
private List<Field> getAllFields(Class<?> clazz) {
|
||||
List<Field> fields = new ArrayList<>();
|
||||
while (clazz != null && clazz != Object.class) {
|
||||
fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
|
||||
clazz = clazz.getSuperclass();
|
||||
}
|
||||
return fields;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段对应的列索引
|
||||
*
|
||||
* @param field 字段对象
|
||||
* @return 列索引
|
||||
*/
|
||||
private Integer getColumnIndex(Field field) {
|
||||
ExcelProperty excelProperty = field.getAnnotation(ExcelProperty.class);
|
||||
if (excelProperty != null && excelProperty.index() >= 0) {
|
||||
return excelProperty.index();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典数据
|
||||
*
|
||||
* @param dictType 字典类型
|
||||
* @return 字典数据列表
|
||||
*/
|
||||
private List<SysDictData> getDictData(String dictType) {
|
||||
try {
|
||||
// 先从缓存获取
|
||||
List<SysDictData> dictDataList = DictUtils.getDictCache(dictType);
|
||||
|
||||
if (dictDataList == null || dictDataList.isEmpty()) {
|
||||
log.warn("从缓存获取字典[{}]数据为空", dictType);
|
||||
}
|
||||
|
||||
return dictDataList;
|
||||
} catch (Exception e) {
|
||||
log.error("获取字典[{}]数据失败:{}", dictType, e.getMessage(), e);
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从字典数据中提取下拉选项
|
||||
*
|
||||
* @param dictDataList 字典数据列表
|
||||
* @param displayType 显示类型
|
||||
* @return 下拉选项数组
|
||||
*/
|
||||
private String[] extractOptions(List<SysDictData> dictDataList, DictDropdown.DisplayType displayType) {
|
||||
List<String> options = new ArrayList<>();
|
||||
|
||||
for (SysDictData dictData : dictDataList) {
|
||||
String optionValue;
|
||||
if (displayType == DictDropdown.DisplayType.VALUE) {
|
||||
optionValue = dictData.getDictValue();
|
||||
} else {
|
||||
optionValue = dictData.getDictLabel();
|
||||
}
|
||||
|
||||
if (optionValue != null && !optionValue.isEmpty()) {
|
||||
options.add(optionValue);
|
||||
}
|
||||
}
|
||||
|
||||
return options.toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建数据验证
|
||||
*
|
||||
* @param workbook 工作簿
|
||||
* @param sheet 工作表
|
||||
* @param validationHelper 数据验证助手
|
||||
* @param columnIndex 列索引
|
||||
* @param options 下拉选项
|
||||
* @param hiddenSheetName 隐藏Sheet名称
|
||||
* @param strict 是否严格模式
|
||||
* @return 数据验证对象
|
||||
*/
|
||||
private DataValidation createDataValidation(
|
||||
Workbook workbook,
|
||||
Sheet sheet,
|
||||
DataValidationHelper validationHelper,
|
||||
int columnIndex,
|
||||
String[] options,
|
||||
String hiddenSheetName,
|
||||
boolean strict
|
||||
) {
|
||||
// 计算选项字符串总长度
|
||||
int totalLength = Arrays.stream(options)
|
||||
.mapToInt(String::length)
|
||||
.sum() + options.length - 1; // 加上分隔符
|
||||
|
||||
// 设置数据验证的范围(从第2行开始,第1行是表头)
|
||||
int firstRow = 1; // 从第2行开始(0-based索引)
|
||||
int lastRow = sheet.getLastRowNum() + 1000; // 扩展到足够多的行
|
||||
if (lastRow < 100) {
|
||||
lastRow = 100; // 至少100行
|
||||
}
|
||||
CellRangeAddressList addressList = new CellRangeAddressList(firstRow, lastRow, columnIndex, columnIndex);
|
||||
|
||||
// 判断是否需要使用隐藏Sheet
|
||||
if (totalLength > MAX_DIRECT_LENGTH) {
|
||||
// 使用隐藏Sheet存储选项
|
||||
return createHiddenSheetValidation(workbook, sheet, validationHelper, addressList, options, hiddenSheetName, strict);
|
||||
} else {
|
||||
// 直接创建下拉列表
|
||||
return createDirectValidation(validationHelper, addressList, options, strict);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用隐藏Sheet创建数据验证(适用于选项较多的情况)
|
||||
*
|
||||
* @param workbook 工作簿
|
||||
* @param sheet 主工作表
|
||||
* @param validationHelper 数据验证助手
|
||||
* @param addressList 单元格范围
|
||||
* @param options 下拉选项
|
||||
* @param hiddenSheetName 隐藏Sheet名称
|
||||
* @param strict 是否严格模式
|
||||
* @return 数据验证对象
|
||||
*/
|
||||
private DataValidation createHiddenSheetValidation(
|
||||
Workbook workbook,
|
||||
Sheet sheet,
|
||||
DataValidationHelper validationHelper,
|
||||
CellRangeAddressList addressList,
|
||||
String[] options,
|
||||
String hiddenSheetName,
|
||||
boolean strict
|
||||
) {
|
||||
try {
|
||||
// 创建或获取隐藏Sheet
|
||||
Sheet hiddenSheet = workbook.getSheet(hiddenSheetName);
|
||||
if (hiddenSheet == null) {
|
||||
hiddenSheet = workbook.createSheet(hiddenSheetName);
|
||||
}
|
||||
|
||||
// 写入选项到隐藏Sheet
|
||||
Row row = hiddenSheet.createRow(0);
|
||||
for (int i = 0; i < options.length; i++) {
|
||||
Cell cell = row.createCell(i);
|
||||
cell.setCellValue(options[i]);
|
||||
}
|
||||
|
||||
// 构建公式引用
|
||||
String formula = String.format("%s!$A$1:$%s$1", hiddenSheetName,
|
||||
(char) ('A' + options.length - 1));
|
||||
|
||||
// 创建列表验证
|
||||
DataValidationConstraint constraint = validationHelper.createFormulaListConstraint(formula);
|
||||
|
||||
// 设置验证属性
|
||||
DataValidation validation = validationHelper.createValidation(constraint, addressList);
|
||||
validation.setSuppressDropDownArrow(true);
|
||||
validation.setErrorStyle(strict ? DataValidation.ErrorStyle.STOP : DataValidation.ErrorStyle.WARNING);
|
||||
validation.setShowErrorBox(true);
|
||||
|
||||
// 隐藏Sheet(在Excel中无法通过界面隐藏,需要通过代码设置)
|
||||
workbook.setSheetHidden(workbook.getSheetIndex(hiddenSheetName), true);
|
||||
|
||||
return validation;
|
||||
} catch (Exception e) {
|
||||
log.error("创建隐藏Sheet数据验证失败:{}", e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直接创建下拉列表验证(适用于选项较少的情况)
|
||||
*
|
||||
* @param validationHelper 数据验证助手
|
||||
* @param addressList 单元格范围
|
||||
* @param options 下拉选项
|
||||
* @param strict 是否严格模式
|
||||
* @return 数据验证对象
|
||||
*/
|
||||
private DataValidation createDirectValidation(
|
||||
DataValidationHelper validationHelper,
|
||||
CellRangeAddressList addressList,
|
||||
String[] options,
|
||||
boolean strict
|
||||
) {
|
||||
// 创建显式列表验证
|
||||
DataValidationConstraint constraint = validationHelper.createExplicitListConstraint(options);
|
||||
|
||||
// 创建数据验证
|
||||
DataValidation validation = validationHelper.createValidation(constraint, addressList);
|
||||
|
||||
// 设置验证属性
|
||||
validation.setSuppressDropDownArrow(true);
|
||||
validation.setErrorStyle(strict ? DataValidation.ErrorStyle.STOP : DataValidation.ErrorStyle.WARNING);
|
||||
validation.setShowErrorBox(true);
|
||||
|
||||
return validation;
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,8 @@ import com.ruoyi.dpc.domain.dto.DpcIntermediaryBlacklistAddDTO;
|
||||
import com.ruoyi.dpc.domain.dto.DpcIntermediaryBlacklistEditDTO;
|
||||
import com.ruoyi.dpc.domain.dto.DpcIntermediaryBlacklistQueryDTO;
|
||||
import com.ruoyi.dpc.domain.excel.DpcIntermediaryBlacklistExcel;
|
||||
import com.ruoyi.dpc.domain.excel.DpcIntermediaryEntityExcel;
|
||||
import com.ruoyi.dpc.domain.excel.DpcIntermediaryPersonExcel;
|
||||
import com.ruoyi.dpc.domain.vo.DpcIntermediaryBlacklistVO;
|
||||
|
||||
import java.util.List;
|
||||
@@ -83,4 +85,30 @@ public interface IDpcIntermediaryBlacklistService {
|
||||
* @return 结果
|
||||
*/
|
||||
String importIntermediary(List<DpcIntermediaryBlacklistExcel> excelList, Boolean isUpdateSupport);
|
||||
|
||||
/**
|
||||
* 根据中介类型获取详情(返回不同类型)
|
||||
*
|
||||
* @param intermediaryId 中介ID
|
||||
* @return 个人返回 DpcIntermediaryPersonDetailVO,机构返回 DpcIntermediaryEntityDetailVO
|
||||
*/
|
||||
Object selectIntermediaryDetailById(Long intermediaryId);
|
||||
|
||||
/**
|
||||
* 导入个人中介数据
|
||||
*
|
||||
* @param excelList Excel实体列表
|
||||
* @param isUpdateSupport 是否更新支持
|
||||
* @return 结果
|
||||
*/
|
||||
String importPersonIntermediary(List<DpcIntermediaryPersonExcel> excelList, Boolean isUpdateSupport);
|
||||
|
||||
/**
|
||||
* 导入机构中介数据
|
||||
*
|
||||
* @param excelList Excel实体列表
|
||||
* @param isUpdateSupport 是否更新支持
|
||||
* @return 结果
|
||||
*/
|
||||
String importEntityIntermediary(List<DpcIntermediaryEntityExcel> excelList, Boolean isUpdateSupport);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.ruoyi.dpc.domain.dto.DpcEmployeeQueryDTO;
|
||||
import com.ruoyi.dpc.domain.dto.DpcEmployeeRelativeAddDTO;
|
||||
import com.ruoyi.dpc.domain.excel.DpcEmployeeExcel;
|
||||
import com.ruoyi.dpc.domain.vo.DpcEmployeeVO;
|
||||
import com.ruoyi.dpc.enums.EmployeeStatus;
|
||||
import com.ruoyi.dpc.mapper.DpcEmployeeMapper;
|
||||
import com.ruoyi.dpc.mapper.DpcEmployeeRelativeMapper;
|
||||
import com.ruoyi.dpc.service.IDpcEmployeeService;
|
||||
@@ -69,13 +70,9 @@ public class DpcEmployeeServiceImpl implements IDpcEmployeeService {
|
||||
Page<DpcEmployeeVO> resultPage = employeeMapper.selectEmployeePageWithDept(voPage, queryDTO);
|
||||
|
||||
// 设置状态描述
|
||||
resultPage.getRecords().forEach(vo -> {
|
||||
if ("0".equals(vo.getStatus())) {
|
||||
vo.setStatusDesc("在职");
|
||||
} else if ("1".equals(vo.getStatus())) {
|
||||
vo.setStatusDesc("离职");
|
||||
}
|
||||
});
|
||||
resultPage.getRecords().forEach(vo ->
|
||||
vo.setStatusDesc(EmployeeStatus.getDescByCode(vo.getStatus()))
|
||||
);
|
||||
|
||||
return resultPage;
|
||||
}
|
||||
@@ -335,14 +332,7 @@ public class DpcEmployeeServiceImpl implements IDpcEmployeeService {
|
||||
|
||||
DpcEmployeeVO vo = new DpcEmployeeVO();
|
||||
BeanUtils.copyProperties(employee, vo);
|
||||
|
||||
// 设置状态描述
|
||||
if ("0".equals(employee.getStatus())) {
|
||||
vo.setStatusDesc("在职");
|
||||
} else if ("1".equals(employee.getStatus())) {
|
||||
vo.setStatusDesc("离职");
|
||||
}
|
||||
|
||||
vo.setStatusDesc(EmployeeStatus.getDescByCode(employee.getStatus()));
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,22 @@ import com.ruoyi.dpc.domain.dto.DpcIntermediaryBlacklistAddDTO;
|
||||
import com.ruoyi.dpc.domain.dto.DpcIntermediaryBlacklistEditDTO;
|
||||
import com.ruoyi.dpc.domain.dto.DpcIntermediaryBlacklistQueryDTO;
|
||||
import com.ruoyi.dpc.domain.excel.DpcIntermediaryBlacklistExcel;
|
||||
import com.ruoyi.dpc.domain.excel.DpcIntermediaryEntityExcel;
|
||||
import com.ruoyi.dpc.domain.excel.DpcIntermediaryPersonExcel;
|
||||
import com.ruoyi.dpc.domain.vo.DpcIntermediaryBlacklistVO;
|
||||
import com.ruoyi.dpc.domain.vo.DpcIntermediaryEntityDetailVO;
|
||||
import com.ruoyi.dpc.domain.vo.DpcIntermediaryPersonDetailVO;
|
||||
import com.ruoyi.dpc.enums.DataSource;
|
||||
import com.ruoyi.dpc.enums.Gender;
|
||||
import com.ruoyi.dpc.enums.IntermediaryStatus;
|
||||
import com.ruoyi.dpc.enums.IntermediaryType;
|
||||
import com.ruoyi.dpc.mapper.DpcIntermediaryBlacklistMapper;
|
||||
import com.ruoyi.dpc.service.IDpcIntermediaryBlacklistService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -178,6 +187,265 @@ public class DpcIntermediaryBlacklistServiceImpl implements IDpcIntermediaryBlac
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据中介类型获取详情(返回不同类型)
|
||||
*
|
||||
* @param intermediaryId 中介ID
|
||||
* @return 个人返回 DpcIntermediaryPersonDetailVO,机构返回 DpcIntermediaryEntityDetailVO
|
||||
*/
|
||||
@Override
|
||||
public Object selectIntermediaryDetailById(Long intermediaryId) {
|
||||
DpcIntermediaryBlacklist intermediary = intermediaryMapper.selectById(intermediaryId);
|
||||
if (intermediary == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// 根据中介类型返回不同的 VO
|
||||
if ("1".equals(intermediary.getIntermediaryType())) {
|
||||
// 个人类型
|
||||
return convertToPersonDetailVO(intermediary);
|
||||
} else {
|
||||
// 机构类型
|
||||
return convertToEntityDetailVO(intermediary);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入个人中介数据
|
||||
*
|
||||
* @param excelList Excel实体列表
|
||||
* @param isUpdateSupport 是否更新支持
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public String importPersonIntermediary(List<DpcIntermediaryPersonExcel> excelList, Boolean isUpdateSupport) {
|
||||
if (excelList == null || excelList.isEmpty()) {
|
||||
return "至少需要一条数据";
|
||||
}
|
||||
|
||||
int successNum = 0;
|
||||
int failureNum = 0;
|
||||
StringBuilder successMsg = new StringBuilder();
|
||||
StringBuilder failureMsg = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < excelList.size(); i++) {
|
||||
DpcIntermediaryPersonExcel excel = excelList.get(i);
|
||||
try {
|
||||
// 验证数据
|
||||
validatePersonIntermediaryData(excel);
|
||||
|
||||
// 转换为实体
|
||||
DpcIntermediaryBlacklist intermediary = new DpcIntermediaryBlacklist();
|
||||
intermediary.setName(excel.getName());
|
||||
intermediary.setCertificateNo(excel.getCertificateNo());
|
||||
intermediary.setIntermediaryType("1"); // 个人类型
|
||||
intermediary.setStatus("0"); // 默认正常
|
||||
intermediary.setDataSource("IMPORT"); // 批量导入
|
||||
intermediary.setRemark(excel.getRemark());
|
||||
|
||||
// 个人专属字段
|
||||
intermediary.setIndivType(excel.getIndivType());
|
||||
intermediary.setIndivSubType(excel.getIndivSubType());
|
||||
intermediary.setIndivGender(excel.getIndivGender());
|
||||
intermediary.setIndivCertType(excel.getIndivCertType());
|
||||
intermediary.setIndivPhone(excel.getIndivPhone());
|
||||
intermediary.setIndivWechat(excel.getIndivWechat());
|
||||
intermediary.setIndivAddress(excel.getIndivAddress());
|
||||
intermediary.setIndivCompany(excel.getIndivCompany());
|
||||
intermediary.setIndivPosition(excel.getIndivPosition());
|
||||
intermediary.setIndivRelatedId(excel.getIndivRelatedId());
|
||||
intermediary.setIndivRelation(excel.getIndivRelation());
|
||||
|
||||
// 设置默认证件类型
|
||||
if (StringUtils.isEmpty(intermediary.getIndivCertType())) {
|
||||
intermediary.setIndivCertType("身份证");
|
||||
}
|
||||
|
||||
// 检查是否已存在(通过证件号判断)
|
||||
if (isUpdateSupport && StringUtils.isNotEmpty(excel.getCertificateNo())) {
|
||||
LambdaQueryWrapper<DpcIntermediaryBlacklist> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(DpcIntermediaryBlacklist::getCertificateNo, excel.getCertificateNo())
|
||||
.eq(DpcIntermediaryBlacklist::getIntermediaryType, "1");
|
||||
DpcIntermediaryBlacklist existing = intermediaryMapper.selectOne(wrapper);
|
||||
if (existing != null) {
|
||||
intermediary.setIntermediaryId(existing.getIntermediaryId());
|
||||
intermediaryMapper.updateById(intermediary);
|
||||
successNum++;
|
||||
successMsg.append("<br/>").append(successNum).append("、").append(excel.getName()).append(" 更新成功");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
intermediaryMapper.insert(intermediary);
|
||||
successNum++;
|
||||
successMsg.append("<br/>").append(successNum).append("、").append(excel.getName()).append(" 导入成功");
|
||||
} catch (Exception e) {
|
||||
failureNum++;
|
||||
failureMsg.append("<br/>").append(failureNum).append("、第").append(i + 1).append("行导入失败:");
|
||||
failureMsg.append(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (failureNum > 0) {
|
||||
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
|
||||
throw new RuntimeException(failureMsg.toString());
|
||||
} else {
|
||||
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条");
|
||||
return successMsg.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入机构中介数据
|
||||
*
|
||||
* @param excelList Excel实体列表
|
||||
* @param isUpdateSupport 是否更新支持
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public String importEntityIntermediary(List<DpcIntermediaryEntityExcel> excelList, Boolean isUpdateSupport) {
|
||||
if (excelList == null || excelList.isEmpty()) {
|
||||
return "至少需要一条数据";
|
||||
}
|
||||
|
||||
int successNum = 0;
|
||||
int failureNum = 0;
|
||||
StringBuilder successMsg = new StringBuilder();
|
||||
StringBuilder failureMsg = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < excelList.size(); i++) {
|
||||
DpcIntermediaryEntityExcel excel = excelList.get(i);
|
||||
try {
|
||||
// 验证数据
|
||||
validateEntityIntermediaryData(excel);
|
||||
|
||||
// 转换为实体
|
||||
DpcIntermediaryBlacklist intermediary = new DpcIntermediaryBlacklist();
|
||||
intermediary.setName(excel.getName());
|
||||
intermediary.setIntermediaryType("2"); // 机构类型
|
||||
intermediary.setStatus("0"); // 默认正常
|
||||
intermediary.setDataSource("IMPORT"); // 批量导入
|
||||
intermediary.setRemark(excel.getRemark());
|
||||
|
||||
// 机构专属字段
|
||||
intermediary.setCorpCreditCode(excel.getCorpCreditCode());
|
||||
intermediary.setCorpType(excel.getCorpType());
|
||||
intermediary.setCorpNature(excel.getCorpNature());
|
||||
intermediary.setCorpIndustryCategory(excel.getCorpIndustryCategory());
|
||||
intermediary.setCorpIndustry(excel.getCorpIndustry());
|
||||
|
||||
// 解析成立日期
|
||||
if (StringUtils.isNotEmpty(excel.getCorpEstablishDate())) {
|
||||
try {
|
||||
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
|
||||
intermediary.setCorpEstablishDate(sdf.parse(excel.getCorpEstablishDate()));
|
||||
} catch (Exception e) {
|
||||
// 忽略日期解析错误
|
||||
}
|
||||
}
|
||||
|
||||
intermediary.setCorpAddress(excel.getCorpAddress());
|
||||
intermediary.setCorpLegalRep(excel.getCorpLegalRep());
|
||||
intermediary.setCorpLegalCertType(excel.getCorpLegalCertType());
|
||||
intermediary.setCorpLegalCertNo(excel.getCorpLegalCertNo());
|
||||
intermediary.setCorpShareholder1(excel.getCorpShareholder1());
|
||||
intermediary.setCorpShareholder2(excel.getCorpShareholder2());
|
||||
intermediary.setCorpShareholder3(excel.getCorpShareholder3());
|
||||
intermediary.setCorpShareholder4(excel.getCorpShareholder4());
|
||||
intermediary.setCorpShareholder5(excel.getCorpShareholder5());
|
||||
|
||||
// 检查是否已存在(通过统一社会信用代码判断)
|
||||
if (isUpdateSupport && StringUtils.isNotEmpty(excel.getCorpCreditCode())) {
|
||||
LambdaQueryWrapper<DpcIntermediaryBlacklist> wrapper = new LambdaQueryWrapper<>();
|
||||
wrapper.eq(DpcIntermediaryBlacklist::getCorpCreditCode, excel.getCorpCreditCode())
|
||||
.eq(DpcIntermediaryBlacklist::getIntermediaryType, "2");
|
||||
DpcIntermediaryBlacklist existing = intermediaryMapper.selectOne(wrapper);
|
||||
if (existing != null) {
|
||||
intermediary.setIntermediaryId(existing.getIntermediaryId());
|
||||
intermediaryMapper.updateById(intermediary);
|
||||
successNum++;
|
||||
successMsg.append("<br/>").append(successNum).append("、").append(excel.getName()).append(" 更新成功");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
intermediaryMapper.insert(intermediary);
|
||||
successNum++;
|
||||
successMsg.append("<br/>").append(successNum).append("、").append(excel.getName()).append(" 导入成功");
|
||||
} catch (Exception e) {
|
||||
failureNum++;
|
||||
failureMsg.append("<br/>").append(failureNum).append("、第").append(i + 1).append("行导入失败:");
|
||||
failureMsg.append(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (failureNum > 0) {
|
||||
failureMsg.insert(0, "很抱歉,导入失败!共 " + failureNum + " 条数据格式不正确,错误如下:");
|
||||
throw new RuntimeException(failureMsg.toString());
|
||||
} else {
|
||||
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条");
|
||||
return successMsg.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证个人中介数据
|
||||
*/
|
||||
private void validatePersonIntermediaryData(DpcIntermediaryPersonExcel excel) {
|
||||
if (StringUtils.isEmpty(excel.getName())) {
|
||||
throw new RuntimeException("姓名不能为空");
|
||||
}
|
||||
if (StringUtils.isEmpty(excel.getCertificateNo())) {
|
||||
throw new RuntimeException("证件号码不能为空");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证机构中介数据
|
||||
*/
|
||||
private void validateEntityIntermediaryData(DpcIntermediaryEntityExcel excel) {
|
||||
if (StringUtils.isEmpty(excel.getName())) {
|
||||
throw new RuntimeException("机构名称不能为空");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为个人详情 VO
|
||||
*/
|
||||
private DpcIntermediaryPersonDetailVO convertToPersonDetailVO(DpcIntermediaryBlacklist intermediary) {
|
||||
if (intermediary == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DpcIntermediaryPersonDetailVO vo = new DpcIntermediaryPersonDetailVO();
|
||||
BeanUtils.copyProperties(intermediary, vo);
|
||||
|
||||
vo.setIntermediaryTypeName(IntermediaryType.PERSON.getDesc());
|
||||
vo.setStatusName(IntermediaryStatus.getDescByCode(intermediary.getStatus()));
|
||||
vo.setDataSourceName(DataSource.getDescByCode(intermediary.getDataSource()));
|
||||
vo.setIndivGenderName(Gender.getDescByCode(intermediary.getIndivGender()));
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 转换为机构详情 VO
|
||||
*/
|
||||
private DpcIntermediaryEntityDetailVO convertToEntityDetailVO(DpcIntermediaryBlacklist intermediary) {
|
||||
if (intermediary == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
DpcIntermediaryEntityDetailVO vo = new DpcIntermediaryEntityDetailVO();
|
||||
BeanUtils.copyProperties(intermediary, vo);
|
||||
|
||||
vo.setIntermediaryTypeName(IntermediaryType.ENTITY.getDesc());
|
||||
vo.setStatusName(IntermediaryStatus.getDescByCode(intermediary.getStatus()));
|
||||
vo.setDataSourceName(DataSource.getDescByCode(intermediary.getDataSource()));
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询条件
|
||||
*/
|
||||
@@ -228,19 +496,8 @@ public class DpcIntermediaryBlacklistServiceImpl implements IDpcIntermediaryBlac
|
||||
DpcIntermediaryBlacklistVO vo = new DpcIntermediaryBlacklistVO();
|
||||
BeanUtils.copyProperties(intermediary, vo);
|
||||
|
||||
// 设置中介类型名称
|
||||
if ("1".equals(intermediary.getIntermediaryType())) {
|
||||
vo.setIntermediaryTypeName("个人");
|
||||
} else if ("2".equals(intermediary.getIntermediaryType())) {
|
||||
vo.setIntermediaryTypeName("机构");
|
||||
}
|
||||
|
||||
// 设置状态名称
|
||||
if ("0".equals(intermediary.getStatus())) {
|
||||
vo.setStatusName("正常");
|
||||
} else if ("1".equals(intermediary.getStatus())) {
|
||||
vo.setStatusName("停用");
|
||||
}
|
||||
vo.setIntermediaryTypeName(IntermediaryType.getDescByCode(intermediary.getIntermediaryType()));
|
||||
vo.setStatusName(IntermediaryStatus.getDescByCode(intermediary.getStatus()));
|
||||
|
||||
return vo;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.ruoyi.dpc.utils;
|
||||
import com.alibaba.excel.EasyExcel;
|
||||
import com.alibaba.excel.write.handler.WriteHandler;
|
||||
import com.alibaba.excel.write.style.column.LongestMatchColumnWidthStyleStrategy;
|
||||
import com.ruoyi.dpc.handler.DictDropdownWriteHandler;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.NoArgsConstructor;
|
||||
@@ -154,4 +155,99 @@ public class EasyExcelUtil {
|
||||
String encodedFileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8).replaceAll("\\+", "%20");
|
||||
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + encodedFileName + ".xlsx");
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载带字典下拉框的导入模板
|
||||
* 自动解析实体类中的@DictDropdown注解,为对应字段添加下拉框
|
||||
*
|
||||
* @param response 响应对象
|
||||
* @param clazz 实体类
|
||||
* @param sheetName 工作表名称
|
||||
* @param <T> 泛型
|
||||
*/
|
||||
public static <T> void importTemplateWithDictDropdown(HttpServletResponse response, Class<T> clazz, String sheetName) {
|
||||
try {
|
||||
setResponseHeader(response, sheetName + "模板");
|
||||
EasyExcel.write(response.getOutputStream(), clazz)
|
||||
.sheet(sheetName)
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
|
||||
.doWrite(List.of());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("下载带字典下拉框的导入模板失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 下载带字典下拉框的导入模板(指定文件名)
|
||||
* 自动解析实体类中的@DictDropdown注解,为对应字段添加下拉框
|
||||
*
|
||||
* @param response 响应对象
|
||||
* @param clazz 实体类
|
||||
* @param sheetName 工作表名称
|
||||
* @param fileName 文件名称
|
||||
* @param <T> 泛型
|
||||
*/
|
||||
public static <T> void importTemplateWithDictDropdown(HttpServletResponse response, Class<T> clazz,
|
||||
String sheetName, String fileName) {
|
||||
try {
|
||||
setResponseHeader(response, fileName);
|
||||
EasyExcel.write(response.getOutputStream(), clazz)
|
||||
.sheet(sheetName)
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
|
||||
.doWrite(List.of());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("下载带字典下拉框的导入模板失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出Excel(带字典下拉框)
|
||||
* 导出的数据包含实际值,但模板中有下拉框供后续编辑使用
|
||||
*
|
||||
* @param response 响应对象
|
||||
* @param list 数据列表
|
||||
* @param clazz 实体类
|
||||
* @param sheetName 工作表名称
|
||||
* @param <T> 泛型
|
||||
*/
|
||||
public static <T> void exportExcelWithDictDropdown(HttpServletResponse response, List<T> list,
|
||||
Class<T> clazz, String sheetName) {
|
||||
try {
|
||||
setResponseHeader(response, sheetName);
|
||||
EasyExcel.write(response.getOutputStream(), clazz)
|
||||
.sheet(sheetName)
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
|
||||
.doWrite(list);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("导出带字典下拉框的Excel失败", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出Excel(带字典下拉框,指定文件名)
|
||||
* 导出的数据包含实际值,但模板中有下拉框供后续编辑使用
|
||||
*
|
||||
* @param response 响应对象
|
||||
* @param list 数据列表
|
||||
* @param clazz 实体类
|
||||
* @param sheetName 工作表名称
|
||||
* @param fileName 文件名称
|
||||
* @param <T> 泛型
|
||||
*/
|
||||
public static <T> void exportExcelWithDictDropdown(HttpServletResponse response, List<T> list,
|
||||
Class<T> clazz, String sheetName, String fileName) {
|
||||
try {
|
||||
setResponseHeader(response, fileName);
|
||||
EasyExcel.write(response.getOutputStream(), clazz)
|
||||
.sheet(sheetName)
|
||||
.registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
|
||||
.registerWriteHandler(new DictDropdownWriteHandler(clazz))
|
||||
.doWrite(list);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("导出带字典下拉框的Excel失败", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
139
sql/dpc_intermediary_dict_data_20260129.sql
Normal file
139
sql/dpc_intermediary_dict_data_20260129.sql
Normal file
@@ -0,0 +1,139 @@
|
||||
-- ============================================================
|
||||
-- 中介黑名单字典数据脚本
|
||||
-- 功能:创建个人和机构中介所需的字典数据
|
||||
-- 作者:ruoyi
|
||||
-- 日期:2026-01-29
|
||||
-- ============================================================
|
||||
|
||||
-- 设置客户端字符集为 utf8mb4
|
||||
SET NAMES utf8mb4;
|
||||
SET CHARACTER SET utf8mb4;
|
||||
SET character_set_client = utf8mb4;
|
||||
SET character_set_connection = utf8mb4;
|
||||
SET character_set_results = utf8mb4;
|
||||
|
||||
USE `discipline-prelim-check`;
|
||||
|
||||
-- ============================================================
|
||||
-- 人员类型字典(dpc_person_type)
|
||||
-- ============================================================
|
||||
-- 先删除旧数据(如果存在)
|
||||
DELETE FROM sys_dict_data WHERE dict_type = 'dpc_person_type';
|
||||
DELETE FROM sys_dict_type WHERE dict_type = 'dpc_person_type';
|
||||
|
||||
-- 插入字典类型
|
||||
INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark)
|
||||
VALUES ('人员类型', 'dpc_person_type', '0', 'admin', NOW(), '中介黑名单-人员类型');
|
||||
|
||||
-- 插入字典数据
|
||||
INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark)
|
||||
VALUES
|
||||
(1, '中介', '中介', 'dpc_person_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(2, '职业背债人', '职业背债人', 'dpc_person_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(3, '房产中介', '房产中介', 'dpc_person_type', '', 'default', 'N', '0', 'admin', NOW(), NULL);
|
||||
|
||||
-- ============================================================
|
||||
-- 人员子类型字典(dpc_person_sub_type)
|
||||
-- ============================================================
|
||||
DELETE FROM sys_dict_data WHERE dict_type = 'dpc_person_sub_type';
|
||||
DELETE FROM sys_dict_type WHERE dict_type = 'dpc_person_sub_type';
|
||||
|
||||
INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark)
|
||||
VALUES ('人员子类型', 'dpc_person_sub_type', '0', 'admin', NOW(), '中介黑名单-人员子类型');
|
||||
|
||||
INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark)
|
||||
VALUES
|
||||
(1, '本人', '本人', 'dpc_person_sub_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(2, '配偶', '配偶', 'dpc_person_sub_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(3, '子女', '子女', 'dpc_person_sub_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(9, '其他', '其他', 'dpc_person_sub_type', '', 'default', 'N', '0', 'admin', NOW(), NULL);
|
||||
|
||||
-- ============================================================
|
||||
-- 性别字典(dpc_indiv_gender)- 用于个人中介Excel下拉框
|
||||
-- ============================================================
|
||||
DELETE FROM sys_dict_data WHERE dict_type = 'dpc_indiv_gender';
|
||||
DELETE FROM sys_dict_type WHERE dict_type = 'dpc_indiv_gender';
|
||||
|
||||
INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark)
|
||||
VALUES ('个人中介性别', 'dpc_indiv_gender', '0', 'admin', NOW(), '中介黑名单-个人中介性别');
|
||||
|
||||
INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark)
|
||||
VALUES
|
||||
(1, '男', 'M', 'dpc_indiv_gender', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(2, '女', 'F', 'dpc_indiv_gender', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(3, '其他', 'O', 'dpc_indiv_gender', '', 'default', 'N', '0', 'admin', NOW(), NULL);
|
||||
|
||||
-- ============================================================
|
||||
-- 证件类型字典(dpc_certificate_type)- 用于个人中介Excel下拉框
|
||||
-- ============================================================
|
||||
DELETE FROM sys_dict_data WHERE dict_type = 'dpc_certificate_type';
|
||||
DELETE FROM sys_dict_type WHERE dict_type = 'dpc_certificate_type';
|
||||
|
||||
INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark)
|
||||
VALUES ('证件类型', 'dpc_certificate_type', '0', 'admin', NOW(), '中介黑名单-证件类型');
|
||||
|
||||
INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark)
|
||||
VALUES
|
||||
(1, '身份证', '身份证', 'dpc_certificate_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(2, '护照', '护照', 'dpc_certificate_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(3, '港澳通行证', '港澳通行证', 'dpc_certificate_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(4, '台胞证', '台胞证', 'dpc_certificate_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(5, '军官证', '军官证', 'dpc_certificate_type', '', 'default', 'N', '0', 'admin', NOW(), NULL);
|
||||
|
||||
-- ============================================================
|
||||
-- 主体类型字典(dpc_entity_type)- 用于机构中介Excel下拉框
|
||||
-- ============================================================
|
||||
DELETE FROM sys_dict_data WHERE dict_type = 'dpc_entity_type';
|
||||
DELETE FROM sys_dict_type WHERE dict_type = 'dpc_entity_type';
|
||||
|
||||
INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark)
|
||||
VALUES ('主体类型', 'dpc_entity_type', '0', 'admin', NOW(), '中介黑名单-主体类型');
|
||||
|
||||
INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark)
|
||||
VALUES
|
||||
(1, '有限责任公司', '有限责任公司', 'dpc_entity_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(2, '股份有限公司', '股份有限公司', 'dpc_entity_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(3, '合伙企业', '合伙企业', 'dpc_entity_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(4, '个体工商户', '个体工商户', 'dpc_entity_type', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(5, '外资企业', '外资企业', 'dpc_entity_type', '', 'default', 'N', '0', 'admin', NOW(), NULL);
|
||||
|
||||
-- ============================================================
|
||||
-- 企业性质字典(dpc_enterprise_nature)- 用于机构中介Excel下拉框
|
||||
-- ============================================================
|
||||
DELETE FROM sys_dict_data WHERE dict_type = 'dpc_enterprise_nature';
|
||||
DELETE FROM sys_dict_type WHERE dict_type = 'dpc_enterprise_nature';
|
||||
|
||||
INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark)
|
||||
VALUES ('企业性质', 'dpc_enterprise_nature', '0', 'admin', NOW(), '中介黑名单-企业性质');
|
||||
|
||||
INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark)
|
||||
VALUES
|
||||
(1, '国企', '国企', 'dpc_enterprise_nature', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(2, '民企', '民企', 'dpc_enterprise_nature', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(3, '外企', '外企', 'dpc_enterprise_nature', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(4, '合资', '合资', 'dpc_enterprise_nature', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(9, '其他', '其他', 'dpc_enterprise_nature', '', 'default', 'N', '0', 'admin', NOW(), NULL);
|
||||
|
||||
-- ============================================================
|
||||
-- 数据来源字典(dpc_data_source)
|
||||
-- ============================================================
|
||||
DELETE FROM sys_dict_data WHERE dict_type = 'dpc_data_source';
|
||||
DELETE FROM sys_dict_type WHERE dict_type = 'dpc_data_source';
|
||||
|
||||
INSERT INTO sys_dict_type (dict_name, dict_type, status, create_by, create_time, remark)
|
||||
VALUES ('数据来源', 'dpc_data_source', '0', 'admin', NOW(), '中介黑名单-数据来源');
|
||||
|
||||
INSERT INTO sys_dict_data (dict_sort, dict_label, dict_value, dict_type, css_class, list_class, is_default, status, create_by, create_time, remark)
|
||||
VALUES
|
||||
(1, '手动录入', 'MANUAL', 'dpc_data_source', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(2, '系统同步', 'SYSTEM', 'dpc_data_source', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(3, '批量导入', 'IMPORT', 'dpc_data_source', '', 'default', 'N', '0', 'admin', NOW(), NULL),
|
||||
(4, '接口获取', 'API', 'dpc_data_source', '', 'default', 'N', '0', 'admin', NOW(), NULL);
|
||||
|
||||
-- ============================================================
|
||||
-- 执行完成后操作说明
|
||||
-- ============================================================
|
||||
-- 1. 执行完成后,请通过系统管理 > 字典管理验证字典数据
|
||||
-- 2. 重要:在每个字典类型页面点击"刷新缓存"按钮,确保字典数据加载到 Redis
|
||||
-- 3. 验证字典缓存是否生效(可通过测试模板下载确认下拉框是否显示)
|
||||
-- 4. 检查 Redis 缓存中的字典数据(sys_dict_cache:*)
|
||||
63
sql/dpc_intermediary_enhance_20260129.sql
Normal file
63
sql/dpc_intermediary_enhance_20260129.sql
Normal file
@@ -0,0 +1,63 @@
|
||||
-- ============================================================
|
||||
-- 中介黑名单表字段扩展脚本
|
||||
-- 功能:为个人和机构类型中介添加详细字段
|
||||
-- 作者:ruoyi
|
||||
-- 日期:2026-01-29
|
||||
-- ============================================================
|
||||
|
||||
USE `discipline-prelim-check`;
|
||||
|
||||
-- ============================================================
|
||||
-- 个人类型字段 (以 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接口获取)';
|
||||
|
||||
-- ============================================================
|
||||
-- 添加索引
|
||||
-- ============================================================
|
||||
-- 为统一社会信用代码添加索引(用于机构中介去重判断)
|
||||
ALTER TABLE dpc_intermediary_blacklist ADD INDEX `idx_corp_credit_code` (`corp_credit_code`);
|
||||
|
||||
-- 为手机号码添加索引(用于个人中介查询)
|
||||
ALTER TABLE dpc_intermediary_blacklist ADD INDEX `idx_indiv_phone` (`indiv_phone`);
|
||||
|
||||
-- ============================================================
|
||||
-- 验证脚本
|
||||
-- ============================================================
|
||||
-- 执行完成后,请运行以下命令验证表结构变更:
|
||||
-- DESCRIBE dpc_intermediary_blacklist;
|
||||
-- SHOW INDEX FROM dpc_intermediary_blacklist;
|
||||
105
sql/fix_intermediary_comments_20260129.sql
Normal file
105
sql/fix_intermediary_comments_20260129.sql
Normal file
@@ -0,0 +1,105 @@
|
||||
-- ============================================================
|
||||
-- 修复中介黑名单表字段备注乱码
|
||||
-- 功能:将字段备注从乱码修复为正确的中文
|
||||
-- 作者:ruoyi
|
||||
-- 日期:2026-01-29
|
||||
-- ============================================================
|
||||
|
||||
-- 设置客户端字符集为 utf8mb4
|
||||
SET NAMES utf8mb4;
|
||||
SET CHARACTER SET utf8mb4;
|
||||
SET character_set_client = utf8mb4;
|
||||
SET character_set_connection = utf8mb4;
|
||||
SET character_set_results = utf8mb4;
|
||||
|
||||
USE `discipline-prelim-check`;
|
||||
|
||||
-- ============================================================
|
||||
-- 修复个人类型字段备注
|
||||
-- ============================================================
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN indiv_type VARCHAR(30) DEFAULT NULL COMMENT '人员类型(中介、职业背债人、房产中介等)';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN indiv_sub_type VARCHAR(50) DEFAULT NULL COMMENT '人员子类型(本人、配偶等)';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN indiv_gender CHAR(1) DEFAULT NULL COMMENT '性别(M男 F女 O其他)';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN indiv_cert_type VARCHAR(30) DEFAULT '身份证' COMMENT '证件类型';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN indiv_phone VARCHAR(20) DEFAULT NULL COMMENT '手机号码(加密存储)';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN indiv_wechat VARCHAR(50) DEFAULT NULL COMMENT '微信号';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN indiv_address VARCHAR(200) DEFAULT NULL COMMENT '联系地址';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN indiv_company VARCHAR(100) DEFAULT NULL COMMENT '所在公司';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN indiv_position VARCHAR(100) DEFAULT NULL COMMENT '职位/职务';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN indiv_related_id VARCHAR(20) DEFAULT NULL COMMENT '关联人员ID';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN indiv_relation VARCHAR(50) DEFAULT NULL COMMENT '关联关系';
|
||||
|
||||
-- ============================================================
|
||||
-- 修复机构类型字段备注
|
||||
-- ============================================================
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_credit_code VARCHAR(18) DEFAULT NULL COMMENT '统一社会信用代码';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_type VARCHAR(50) DEFAULT NULL COMMENT '主体类型(有限责任公司、股份有限公司等)';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_nature VARCHAR(50) DEFAULT NULL COMMENT '企业性质(国企、民企、外企等)';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_industry_category VARCHAR(100) DEFAULT NULL COMMENT '行业分类';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_industry VARCHAR(100) DEFAULT NULL COMMENT '所属行业';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_establish_date DATE DEFAULT NULL COMMENT '成立日期';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_address VARCHAR(500) DEFAULT NULL COMMENT '注册地址';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_legal_rep VARCHAR(50) DEFAULT NULL COMMENT '法定代表人';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_legal_cert_type VARCHAR(30) DEFAULT NULL COMMENT '法定代表人证件类型';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_legal_cert_no VARCHAR(30) DEFAULT NULL COMMENT '法定代表人证件号码';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_shareholder_1 VARCHAR(30) DEFAULT NULL COMMENT '股东1';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_shareholder_2 VARCHAR(30) DEFAULT NULL COMMENT '股东2';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_shareholder_3 VARCHAR(30) DEFAULT NULL COMMENT '股东3';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_shareholder_4 VARCHAR(30) DEFAULT NULL COMMENT '股东4';
|
||||
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN corp_shareholder_5 VARCHAR(30) DEFAULT NULL COMMENT '股东5';
|
||||
|
||||
-- ============================================================
|
||||
-- 修复通用字段备注
|
||||
-- ============================================================
|
||||
ALTER TABLE dpc_intermediary_blacklist
|
||||
MODIFY COLUMN data_source VARCHAR(30) DEFAULT 'MANUAL' COMMENT '数据来源(MANUAL手动录入 SYSTEM系统同步 IMPORT批量导入 API接口获取)';
|
||||
Reference in New Issue
Block a user