中介黑名单更新
This commit is contained in:
@@ -57,7 +57,18 @@
|
||||
"Bash(mvn spring-boot:run:*)",
|
||||
"Bash(timeout:*)",
|
||||
"mcp__chrome-devtools__wait_for",
|
||||
"Bash(start cmd /k \"mvn spring-boot:run -pl ruoyi-admin\")"
|
||||
"Bash(start cmd /k \"mvn spring-boot:run -pl ruoyi-admin\")",
|
||||
"mcp__mysql__list_tables",
|
||||
"mcp__mysql__describe_table",
|
||||
"mcp__mysql__query",
|
||||
"Bash(grep:*)",
|
||||
"mcp__mysql__connect_db",
|
||||
"Skill(superpowers:writing-plans)",
|
||||
"Skill(superpowers:subagent-driven-development)",
|
||||
"Bash(chmod:*)",
|
||||
"Bash(ls:*)",
|
||||
"Bash(test_report.sh \")",
|
||||
"mcp__mysql__show_statement"
|
||||
]
|
||||
},
|
||||
"enabledMcpjsonServers": [
|
||||
|
||||
24
doc/docs/ccdi_biz_intermediary.csv
Normal file
24
doc/docs/ccdi_biz_intermediary.csv
Normal file
@@ -0,0 +1,24 @@
|
||||
中介人员基本信息表:ccdi_biz_intermediary,,,,,,
|
||||
序号,字段名,类型,默认值,是否可为空,是否主键,注释
|
||||
1,biz_id,VARCHAR,-,否,是,人员ID
|
||||
2,person_type,VARCHAR,-,否,否,人员类型,中介、职业背债人、房产中介等
|
||||
3,person_sub_type,VARCHAR,-,是,否,人员子类型
|
||||
4,relation_type,VARCHAR,-,否,-,关系类型,如:配偶、子女、父母、兄弟姐妹等
|
||||
5,name,VARCHAR,-,否,否,姓名
|
||||
6,gender,CHAR,-,是,否,性别
|
||||
7,id_type,VARCHAR,身份证,否,否,证件类型
|
||||
8,person_id,VARCHAR,-,否,否,证件号码
|
||||
9,mobile,VARCHAR,-,是,否,手机号码
|
||||
10,wechat_no,VARCHAR,-,是,否,微信号
|
||||
11,contact_address,VARCHAR,-,是,否,联系地址
|
||||
12,company,VARCHAR,-,是,否,所在公司
|
||||
13,social_credit_code,VARCHAR,,,,企业统一信用码
|
||||
14,position,VARCHAR,-,是,否,职位
|
||||
15,related_num_id,VARCHAR,-,是,否,关联人员ID
|
||||
16,relation_type,VARCHAR,-,是,否,关联关系
|
||||
17,date_source,,,,,"数据来源,MANUAL:手动录入, SYSTEM:系统同步, IMPORT:批量导入, API:接口获取"
|
||||
18,remark,,,,,备注信息
|
||||
19,created_by,VARCHAR,-,否,-,记录创建人
|
||||
20,updated_by,VARCHAR,-,是,-,记录更新人
|
||||
21,create_time,DATETIME,,否,,记录创建时间
|
||||
22,update_time,DATETIME,-,是,-,记录更新时间
|
||||
|
26
doc/docs/ccdi_enterprise_base_info.csv
Normal file
26
doc/docs/ccdi_enterprise_base_info.csv
Normal file
@@ -0,0 +1,26 @@
|
||||
3.企业主体信息表:ccdi_enterprise_base_info,,,,,,
|
||||
序号,字段名,类型,默认值,是否可为空,是否主键,注释
|
||||
1,social_credit_code,VARCHAR,-,否,是,统一社会信用代码,员工企业关联关系表的外键
|
||||
2,enterprise_name,VARCHAR,-,否,-,企业名称
|
||||
3,enterprise_type,VARCHAR,-,否,-,"企业类型,有限责任公司、股份有限公司、合伙企业、个体工商户、外资企业等"
|
||||
4,enterprise_nature,VARCHAR,-,是,-,"企业性质,国企、民企、外企、合资、其他"
|
||||
5,industry_class,VARCHAR,-,是,-,行业分类
|
||||
6,industry_name,VARCHAR,-,是,-,所属行业
|
||||
7,establish_date,DATE,-,是,-,成立日期
|
||||
8,register_address,VARCHAR,-,是,-,注册地址
|
||||
9,legal_representative,VARCHAR,-,是,-,法定代表人
|
||||
10,legal_cert_type,VARCHAR,-,是,-,法定代表人证件类型
|
||||
11,legal_cert_no,VARCHAR,-,是,-,法定代表人证件号码
|
||||
12,shareholder1,VARCHAR,-,是,-,股东1
|
||||
13,shareholder2,VARCHAR,-,是,-,股东2
|
||||
14,shareholder3,VARCHAR,-,是,-,股东3
|
||||
15,shareholder4,VARCHAR,-,是,-,股东4
|
||||
16,shareholder5,VARCHAR,-,是,-,股东5
|
||||
17,status,VARCHAR,,,,经营状态
|
||||
18,create_time,DATETIME,当前时间,否,-,创建时间
|
||||
19,update_time,DATETIME,当前时间,否,-,更新时间
|
||||
20,created_by,VARCHAR,-,否,-,创建人
|
||||
21,updated_by,VARCHAR,-,是,-,更新人
|
||||
22,data_source,VARCHAR,MANUAL,是,-,"数据来源,MANUAL:手动录入, SYSTEM:系统同步, API:接口获取, IMPORT:批量导入"
|
||||
23,risk_level,VARCHAR(10),1,是,否,"风险等级:1-高风险, 2-中风险, 3-低风险"
|
||||
24,ent_source,VARCHAR(20),GENERAL,否,否,"企业来源:GENERAL-一般企业, EMP_RELATION-员工关系人, CREDIT_CUSTOMER-信贷客户, INTERMEDIARY-中介, BOTH-兼有"
|
||||
|
1
doc/docs/中介黑名单后端.md
Normal file
1
doc/docs/中介黑名单后端.md
Normal file
@@ -0,0 +1 @@
|
||||
我想实现中介黑名单管理的功能需求。中介分为个人中介和实体中介。个人中介的字段为 @ccdi_biz_intermediary.csv。实体中介字段为 @ccdi_enterprise_base_info.csv,风险等级为高风险,企业来源为中介。需要生成的接口:个人中介的新增、修改接口,以证件号为关联键;个人中介导入模板下载,个人中介文件上传导入新增;实体中介类的新增、修改接口;实体中介导入模板下载,上传导入新增;列表查询,要求联合查询两种类型的中介,也可以支持查询单种类的中介。
|
||||
1177
doc/plans/2026-02-04-intermediary-blacklist-migration-test-plan.md
Normal file
1177
doc/plans/2026-02-04-intermediary-blacklist-migration-test-plan.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,887 @@
|
||||
# 中介黑名单入库逻辑变更 - 测试验证计划
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**目标:** 验证中介黑名单从单表切换到双表(cdi_biz_intermediary + ccdi_enterprise_base_info)的所有CRUD操作正确性
|
||||
|
||||
**架构:** 个人中介插入 ccdi_biz_intermediary 表,机构中介插入 ccdi_enterprise_base_info 表(自动设置高风险和中介来源标识),查询层合并两个表的数据返回
|
||||
|
||||
**技术栈:** Spring Boot 3.5.8, MyBatis Plus 3.5.10, MySQL 8.2.0, Maven, JUnit 5
|
||||
|
||||
---
|
||||
|
||||
## 测试前准备
|
||||
|
||||
### Task 1: 确认数据库连接和环境
|
||||
|
||||
**Files:**
|
||||
- Check: `ruoyi-admin/src/main/resources/application-dev.yml`
|
||||
|
||||
**Step 1: 验证数据库连接配置**
|
||||
|
||||
检查配置文件中的数据库连接信息:
|
||||
```yaml
|
||||
spring:
|
||||
datasource:
|
||||
druid:
|
||||
master:
|
||||
url: jdbc:mysql://116.62.17.81:3306/ccdi
|
||||
username: root
|
||||
password: Kfcx@1234
|
||||
```
|
||||
|
||||
**Step 2: 确认目标表存在**
|
||||
|
||||
通过MCP工具验证表存在:
|
||||
```sql
|
||||
SHOW TABLES LIKE 'ccdi_biz_intermediary';
|
||||
SHOW TABLES LIKE 'ccdi_enterprise_base_info';
|
||||
```
|
||||
|
||||
预期: 两个表都存在
|
||||
|
||||
**Step 3: 检查表结构**
|
||||
|
||||
```sql
|
||||
DESCRIBE ccdi_biz_intermediary;
|
||||
DESCRIBE ccdi_enterprise_base_info;
|
||||
```
|
||||
|
||||
预期: 表结构与实体类字段匹配
|
||||
|
||||
---
|
||||
|
||||
## 功能测试 - 个人中介
|
||||
|
||||
### Task 2: 测试个人中介新增功能
|
||||
|
||||
**Files:**
|
||||
- Test API: `POST /ccdi/intermediary/person`
|
||||
- Backend: `CcdiIntermediaryBlacklistServiceImpl.insertPersonIntermediary()`
|
||||
|
||||
**Step 1: 准备测试数据**
|
||||
|
||||
创建测试数据文件 `test_person_add.json`:
|
||||
```json
|
||||
{
|
||||
"name": "测试个人中介",
|
||||
"certificateNo": "110101199001011234",
|
||||
"indivType": "中介",
|
||||
"indivSubType": "本人",
|
||||
"indivGender": "M",
|
||||
"indivCertType": "身份证",
|
||||
"indivPhone": "13800138000",
|
||||
"indivWechat": "test_wx001",
|
||||
"indivAddress": "北京市朝阳区测试路123号",
|
||||
"indivCompany": "测试公司",
|
||||
"indivPosition": "测试员",
|
||||
"indivRelatedId": "",
|
||||
"indivRelation": "",
|
||||
"status": "0",
|
||||
"remark": "自动化测试数据"
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: 获取认证Token**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/login/test \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"admin","password":"admin123"}' \
|
||||
| jq -r '.data.token'
|
||||
```
|
||||
|
||||
保存token到环境变量:
|
||||
```bash
|
||||
export TOKEN="获取到的token值"
|
||||
```
|
||||
|
||||
**Step 3: 调用新增接口**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/ccdi/intermediary/person \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @test_person_add.json
|
||||
```
|
||||
|
||||
预期响应:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功"
|
||||
}
|
||||
```
|
||||
|
||||
**Step 4: 验证数据插入到正确的表**
|
||||
|
||||
通过MCP查询数据库:
|
||||
```sql
|
||||
SELECT * FROM ccdi_biz_intermediary
|
||||
WHERE person_id = '110101199001011234';
|
||||
```
|
||||
|
||||
预期:
|
||||
- 找到1条记录
|
||||
- name = '测试个人中介'
|
||||
- date_source = 'MANUAL'
|
||||
|
||||
**Step 5: 验证旧表无数据**
|
||||
|
||||
```sql
|
||||
SELECT * FROM ccdi_intermediary_blacklist
|
||||
WHERE certificate_no = '110101199001011234';
|
||||
```
|
||||
|
||||
预期: 0条记录(表可能不存在或为空)
|
||||
|
||||
---
|
||||
|
||||
### Task 3: 测试个人中介列表查询
|
||||
|
||||
**Files:**
|
||||
- Test API: `GET /ccdi/intermediary/list`
|
||||
|
||||
**Step 1: 调用列表查询接口**
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/ccdi/intermediary/list?name=测试个人中介" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
预期响应:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"rows": [
|
||||
{
|
||||
"intermediaryId": 1,
|
||||
"name": "测试个人中介",
|
||||
"certificateNo": "110101199001011234",
|
||||
"intermediaryType": "1",
|
||||
"intermediaryTypeName": "个人",
|
||||
"status": "0",
|
||||
"statusName": "正常"
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: 验证查询结果来源**
|
||||
|
||||
确认数据来自 `ccdi_biz_intermediary` 表
|
||||
|
||||
**Step 3: 测试分页查询**
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/ccdi/intermediary/list?pageNum=1&pageSize=10" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
预期: 返回分页数据
|
||||
|
||||
---
|
||||
|
||||
### Task 4: 测试个人中介详情查询
|
||||
|
||||
**Files:**
|
||||
- Test API: `GET /ccdi/intermediary/{id}`
|
||||
|
||||
**Step 1: 获取个人中介详情**
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/ccdi/intermediary/1" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
预期响应:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"intermediaryId": 1,
|
||||
"name": "测试个人中介",
|
||||
"certificateNo": "110101199001011234",
|
||||
"intermediaryType": "1",
|
||||
"indivType": "中介",
|
||||
"indivGender": "M",
|
||||
"indivGenderName": "男",
|
||||
"indivPhone": "13800138000",
|
||||
"indivWechat": "test_wx001",
|
||||
"indivAddress": "北京市朝阳区测试路123号",
|
||||
"indivCompany": "测试公司",
|
||||
"indivPosition": "测试员",
|
||||
"dataSource": "MANUAL",
|
||||
"dataSourceName": "手动录入"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: 验证所有字段正确映射**
|
||||
|
||||
检查个人专属字段是否正确:
|
||||
- indivType → person_type ✅
|
||||
- indivGender → gender ✅
|
||||
- indivPhone → mobile ✅
|
||||
- indivWechat → wechat_no ✅
|
||||
- indivAddress → contact_address ✅
|
||||
|
||||
---
|
||||
|
||||
### Task 5: 测试个人中介修改功能
|
||||
|
||||
**Files:**
|
||||
- Test API: `PUT /ccdi/intermediary/person`
|
||||
|
||||
**Step 1: 准备修改数据**
|
||||
|
||||
创建 `test_person_edit.json`:
|
||||
```json
|
||||
{
|
||||
"intermediaryId": 1,
|
||||
"name": "测试个人中介-已修改",
|
||||
"certificateNo": "110101199001011234",
|
||||
"indivType": "中介",
|
||||
"indivGender": "M",
|
||||
"indivPhone": "13900139000",
|
||||
"indivCompany": "新公司",
|
||||
"remark": "已修改"
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: 调用修改接口**
|
||||
|
||||
```bash
|
||||
curl -X PUT http://localhost:8080/ccdi/intermediary/person \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @test_person_edit.json
|
||||
```
|
||||
|
||||
预期: `{ "code": 200, "msg": "操作成功" }`
|
||||
|
||||
**Step 3: 验证数据已更新**
|
||||
|
||||
```sql
|
||||
SELECT * FROM ccdi_biz_intermediary
|
||||
WHERE biz_id = 1;
|
||||
```
|
||||
|
||||
预期:
|
||||
- name = '测试个人中介-已修改'
|
||||
- mobile = '13900139000'
|
||||
- company = '新公司'
|
||||
|
||||
---
|
||||
|
||||
### Task 6: 测试个人中介删除功能
|
||||
|
||||
**Files:**
|
||||
- Test API: `DELETE /ccdi/intermediary/{ids}`
|
||||
|
||||
**Step 1: 调用删除接口**
|
||||
|
||||
```bash
|
||||
curl -X DELETE "http://localhost:8080/ccdi/intermediary/1" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
预期: `{ "code": 200, "msg": "操作成功" }`
|
||||
|
||||
**Step 2: 验证数据已删除**
|
||||
|
||||
```sql
|
||||
SELECT * FROM ccdi_biz_intermediary
|
||||
WHERE biz_id = 1;
|
||||
```
|
||||
|
||||
预期: 0条记录
|
||||
|
||||
---
|
||||
|
||||
## 功能测试 - 机构中介
|
||||
|
||||
### Task 7: 测试机构中介新增功能
|
||||
|
||||
**Files:**
|
||||
- Test API: `POST /ccdi/intermediary/entity`
|
||||
- Backend: `CcdiIntermediaryBlacklistServiceImpl.insertEntityIntermediary()`
|
||||
|
||||
**Step 1: 准备测试数据**
|
||||
|
||||
创建 `test_entity_add.json`:
|
||||
```json
|
||||
{
|
||||
"name": "测试机构中介有限公司",
|
||||
"corpCreditCode": "91110000123456789X",
|
||||
"corpType": "有限责任公司",
|
||||
"corpNature": "民营企业",
|
||||
"corpIndustryCategory": "制造业",
|
||||
"corpIndustry": "通用设备制造业",
|
||||
"corpEstablishDate": "2020-01-01T00:00:00",
|
||||
"corpAddress": "北京市海淀区测试大街456号",
|
||||
"corpLegalRep": "张三",
|
||||
"corpLegalCertType": "身份证",
|
||||
"corpLegalCertNo": "110101198001011234",
|
||||
"corpShareholder1": "股东A",
|
||||
"corpShareholder2": "股东B",
|
||||
"status": "0",
|
||||
"remark": "机构中介测试数据"
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: 调用新增接口**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/ccdi/intermediary/entity \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @test_entity_add.json
|
||||
```
|
||||
|
||||
预期: `{ "code": 200, "msg": "操作成功" }`
|
||||
|
||||
**Step 3: 验证数据插入到正确的表**
|
||||
|
||||
```sql
|
||||
SELECT * FROM ccdi_enterprise_base_info
|
||||
WHERE social_credit_code = '91110000123456789X';
|
||||
```
|
||||
|
||||
预期:
|
||||
- 找到1条记录
|
||||
- enterprise_name = '测试机构中介有限公司'
|
||||
- **risk_level = '1' (高风险)** ✅
|
||||
- **ent_source = 'INTERMEDIARY' (中介来源)** ✅
|
||||
- data_source = 'MANUAL'
|
||||
|
||||
**Step 4: 验证关键字段自动设置**
|
||||
|
||||
检查两个重要标识:
|
||||
```sql
|
||||
SELECT
|
||||
social_credit_code,
|
||||
enterprise_name,
|
||||
risk_level,
|
||||
ent_source,
|
||||
data_source
|
||||
FROM ccdi_enterprise_base_info
|
||||
WHERE social_credit_code = '91110000123456789X';
|
||||
```
|
||||
|
||||
预期:
|
||||
- risk_level = '1' ✅
|
||||
- ent_source = 'INTERMEDIARY' ✅
|
||||
|
||||
---
|
||||
|
||||
### Task 8: 测试机构中介列表查询
|
||||
|
||||
**Files:**
|
||||
- Test API: `GET /ccdi/intermediary/list`
|
||||
|
||||
**Step 1: 查询机构中介**
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/ccdi/intermediary/list?intermediaryType=2&name=测试机构" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
预期响应:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"rows": [
|
||||
{
|
||||
"intermediaryId": 0,
|
||||
"name": "测试机构中介有限公司",
|
||||
"certificateNo": "91110000123456789X",
|
||||
"intermediaryType": "2",
|
||||
"intermediaryTypeName": "机构",
|
||||
"status": "0",
|
||||
"statusName": "正常"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: 验证ent_source过滤**
|
||||
|
||||
查询应该只返回 ent_source='INTERMEDIARY' 的记录
|
||||
|
||||
**Step 3: 混合查询(个人+机构)**
|
||||
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/ccdi/intermediary/list" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
预期: 返回个人和机构中介的合并列表
|
||||
|
||||
---
|
||||
|
||||
### Task 9: 测试机构中介详情查询
|
||||
|
||||
**Files:**
|
||||
- Test API: `GET /ccdi/intermediary/{id}`
|
||||
|
||||
**Step 1: 获取机构中介详情**
|
||||
|
||||
注意: 机构中介的ID需要特殊处理(社会信用代码)
|
||||
|
||||
**Step 2: 验证机构字段映射**
|
||||
|
||||
检查字段映射:
|
||||
- corpCreditCode → social_credit_code ✅
|
||||
- name → enterprise_name ✅
|
||||
- corpType → enterprise_type ✅
|
||||
- corpNature → enterprise_nature ✅
|
||||
- corpIndustryCategory → industry_class ✅
|
||||
|
||||
---
|
||||
|
||||
### Task 10: 测试机构中介修改功能
|
||||
|
||||
**Files:**
|
||||
- Test API: `PUT /ccdi/intermediary/entity`
|
||||
|
||||
**Step 1: 准备修改数据**
|
||||
|
||||
创建 `test_entity_edit.json`:
|
||||
```json
|
||||
{
|
||||
"corpCreditCode": "91110000123456789X",
|
||||
"name": "测试机构中介有限公司-已修改",
|
||||
"corpType": "股份有限公司",
|
||||
"corpNature": "国有企业",
|
||||
"status": "0",
|
||||
"remark": "已修改"
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: 调用修改接口**
|
||||
|
||||
```bash
|
||||
curl -X PUT http://localhost:8080/ccdi/intermediary/entity \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @test_entity_edit.json
|
||||
```
|
||||
|
||||
预期: `{ "code": 200, "msg": "操作成功" }`
|
||||
|
||||
**Step 3: 验证高风险和中介来源标识不变**
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
social_credit_code,
|
||||
enterprise_name,
|
||||
risk_level,
|
||||
ent_source
|
||||
FROM ccdi_enterprise_base_info
|
||||
WHERE social_credit_code = '91110000123456789X';
|
||||
```
|
||||
|
||||
预期:
|
||||
- enterprise_name = '测试机构中介有限公司-已修改'
|
||||
- risk_level 仍为 '1' ✅ (保持不变)
|
||||
- ent_source 仍为 'INTERMEDIARY' ✅ (保持不变)
|
||||
|
||||
---
|
||||
|
||||
## 导入功能测试
|
||||
|
||||
### Task 11: 测试个人中介Excel导入
|
||||
|
||||
**Files:**
|
||||
- Test API: `POST /ccdi/intermediary/importPersonData`
|
||||
|
||||
**Step 1: 下载导入模板**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/ccdi/intermediary/importPersonTemplate \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
--output person_template.xlsx
|
||||
```
|
||||
|
||||
预期: 下载成功,文件包含所有个人字段
|
||||
|
||||
**Step 2: 准备测试Excel文件**
|
||||
|
||||
手动创建Excel文件或使用EasyExcel生成测试数据,包含:
|
||||
- 姓名: "导入测试个人"
|
||||
- 证件号: "110101199002022345"
|
||||
- 人员类型: "中介"
|
||||
- 性别: "M"
|
||||
- 手机号: "13800138001"
|
||||
- 微信号: "import_wx001"
|
||||
|
||||
**Step 3: 执行导入**
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/ccdi/intermediary/importPersonData?updateSupport=false" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-F "file=@person_test_data.xlsx"
|
||||
```
|
||||
|
||||
预期:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "恭喜您,数据已全部导入成功!共 1 条"
|
||||
}
|
||||
```
|
||||
|
||||
**Step 4: 验证导入数据**
|
||||
|
||||
```sql
|
||||
SELECT * FROM ccdi_biz_intermediary
|
||||
WHERE person_id = '110101199002022345';
|
||||
```
|
||||
|
||||
预期:
|
||||
- 找到1条记录
|
||||
- date_source = 'IMPORT' ✅
|
||||
- name = '导入测试个人'
|
||||
|
||||
---
|
||||
|
||||
### Task 12: 测试机构中介Excel导入
|
||||
|
||||
**Files:**
|
||||
- Test API: `POST /ccdi/intermediary/importEntityData`
|
||||
|
||||
**Step 1: 下载导入模板**
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/ccdi/intermediary/importEntityTemplate \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
--output entity_template.xlsx
|
||||
```
|
||||
|
||||
预期: 下载成功,文件包含所有机构字段
|
||||
|
||||
**Step 2: 准备测试Excel文件**
|
||||
|
||||
创建Excel文件,包含:
|
||||
- 机构名称: "导入测试机构有限公司"
|
||||
- 统一社会信用代码: "91110000987654321A"
|
||||
- 主体类型: "有限责任公司"
|
||||
- 企业性质: "民营企业"
|
||||
- 法定代表人: "李四"
|
||||
|
||||
**Step 3: 执行导入**
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/ccdi/intermediary/importEntityData?updateSupport=false" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-F "file=@entity_test_data.xlsx"
|
||||
```
|
||||
|
||||
预期:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "恭喜您,数据已全部导入成功!共 1 条"
|
||||
}
|
||||
```
|
||||
|
||||
**Step 4: 验证导入数据和自动设置标识**
|
||||
|
||||
```sql
|
||||
SELECT
|
||||
social_credit_code,
|
||||
enterprise_name,
|
||||
risk_level,
|
||||
ent_source,
|
||||
data_source
|
||||
FROM ccdi_enterprise_base_info
|
||||
WHERE social_credit_code = '91110000987654321A';
|
||||
```
|
||||
|
||||
预期:
|
||||
- enterprise_name = '导入测试机构有限公司'
|
||||
- **risk_level = '1' (高风险)** ✅
|
||||
- **ent_source = 'INTERMEDIARY' (中介来源)** ✅
|
||||
- data_source = 'IMPORT' ✅
|
||||
|
||||
---
|
||||
|
||||
## 导出功能测试
|
||||
|
||||
### Task 13: 测试中介数据导出
|
||||
|
||||
**Files:**
|
||||
- Test API: `POST /ccdi/intermediary/export`
|
||||
|
||||
**Step 1: 导出所有数据**
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/ccdi/intermediary/export" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{}' \
|
||||
--output intermediary_export.xlsx
|
||||
```
|
||||
|
||||
预期: 下载成功,Excel文件包含个人和机构数据
|
||||
|
||||
**Step 2: 验证导出数据完整性**
|
||||
|
||||
打开Excel文件,验证:
|
||||
- 包含个人中介字段(indivType, indivGender等)
|
||||
- 包含机构中介字段(corpType, corpNature等)
|
||||
- 数据正确映射
|
||||
|
||||
**Step 3: 测试条件导出**
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/ccdi/intermediary/export" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"intermediaryType":"1"}' \
|
||||
--output person_export.xlsx
|
||||
```
|
||||
|
||||
预期: 只导出个人中介数据
|
||||
|
||||
---
|
||||
|
||||
## 边界条件测试
|
||||
|
||||
### Task 14: 测试唯一性约束
|
||||
|
||||
**Step 1: 个人中介证件号重复插入**
|
||||
|
||||
尝试插入相同person_id的记录:
|
||||
```bash
|
||||
# 使用Task 2的数据再次执行
|
||||
curl -X POST http://localhost:8080/ccdi/intermediary/person \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @test_person_add.json
|
||||
```
|
||||
|
||||
预期: 根据实际业务逻辑,可能报唯一性约束错误或允许插入
|
||||
|
||||
**Step 2: 机构中介社会信用代码重复插入**
|
||||
|
||||
```bash
|
||||
# 使用Task 7的数据再次执行
|
||||
curl -X POST http://localhost:8080/ccdi/intermediary/entity \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @test_entity_add.json
|
||||
```
|
||||
|
||||
预期: 报主键冲突错误(社会信用代码是主键)
|
||||
|
||||
---
|
||||
|
||||
### Task 15: 测试必填字段验证
|
||||
|
||||
**Step 1: 缺少姓名的个人中介**
|
||||
|
||||
创建 `test_person_no_name.json`:
|
||||
```json
|
||||
{
|
||||
"certificateNo": "110101199003033456",
|
||||
"status": "0"
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/ccdi/intermediary/person \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @test_person_no_name.json
|
||||
```
|
||||
|
||||
预期: 返回验证错误,提示"姓名不能为空"
|
||||
|
||||
**Step 2: 缺少统一社会信用代码的机构中介**
|
||||
|
||||
创建 `test_entity_no_code.json`:
|
||||
```json
|
||||
{
|
||||
"name": "测试机构",
|
||||
"status": "0"
|
||||
}
|
||||
```
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8080/ccdi/intermediary/entity \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d @test_entity_no_code.json
|
||||
```
|
||||
|
||||
预期: 返回验证错误,提示"统一社会信用代码不能为空"
|
||||
|
||||
---
|
||||
|
||||
## 性能测试
|
||||
|
||||
### Task 16: 批量数据导入性能测试
|
||||
|
||||
**Step 1: 准备批量测试数据**
|
||||
|
||||
创建包含100条个人中介的Excel文件
|
||||
|
||||
**Step 2: 执行批量导入**
|
||||
|
||||
```bash
|
||||
time curl -X POST "http://localhost:8080/ccdi/intermediary/importPersonData?updateSupport=false" \
|
||||
-H "Authorization: Bearer $TOKEN" \
|
||||
-F "file=@person_batch_100.xlsx"
|
||||
```
|
||||
|
||||
预期:
|
||||
- 导入成功
|
||||
- 耗时 < 10秒
|
||||
|
||||
**Step 3: 验证数据一致性**
|
||||
|
||||
```sql
|
||||
SELECT COUNT(*) FROM ccdi_biz_intermediary
|
||||
WHERE date_source = 'IMPORT';
|
||||
```
|
||||
|
||||
预期: 导入的记录数与Excel文件一致
|
||||
|
||||
---
|
||||
|
||||
## 清理测试数据
|
||||
|
||||
### Task 17: 清理测试数据
|
||||
|
||||
**Step 1: 删除测试个人中介数据**
|
||||
|
||||
```sql
|
||||
DELETE FROM ccdi_biz_intermediary
|
||||
WHERE person_id IN (
|
||||
'110101199001011234',
|
||||
'110101199002022345'
|
||||
);
|
||||
```
|
||||
|
||||
**Step 2: 删除测试机构中介数据**
|
||||
|
||||
```sql
|
||||
DELETE FROM ccdi_enterprise_base_info
|
||||
WHERE social_credit_code IN (
|
||||
'91110000123456789X',
|
||||
'91110000987654321A'
|
||||
);
|
||||
```
|
||||
|
||||
**Step 3: 验证清理完成**
|
||||
|
||||
```sql
|
||||
SELECT COUNT(*) FROM ccdi_biz_intermediary
|
||||
WHERE person_id LIKE '110101199%';
|
||||
|
||||
SELECT COUNT(*) FROM ccdi_enterprise_base_info
|
||||
WHERE social_credit_code LIKE '91110000%';
|
||||
```
|
||||
|
||||
预期: 0条测试记录
|
||||
|
||||
---
|
||||
|
||||
## 测试报告生成
|
||||
|
||||
### Task 18: 生成测试报告
|
||||
|
||||
**Step 1: 汇总测试结果**
|
||||
|
||||
创建测试报告文件 `test_report.md`:
|
||||
|
||||
```markdown
|
||||
# 中介黑名单入库逻辑变更测试报告
|
||||
|
||||
## 测试环境
|
||||
- 数据库: MySQL 8.2.0
|
||||
- 服务端口: 8080
|
||||
- 测试时间: 2026-02-04
|
||||
|
||||
## 功能测试结果
|
||||
|
||||
### 个人中介
|
||||
- ✅ 新增功能 - 数据正确插入 ccdi_biz_intermediary
|
||||
- ✅ 列表查询 - 正确返回个人中介数据
|
||||
- ✅ 详情查询 - 所有字段正确映射
|
||||
- ✅ 修改功能 - 数据正确更新
|
||||
- ✅ 删除功能 - 数据正确删除
|
||||
- ✅ Excel导入 - 批量导入成功,data_source='IMPORT'
|
||||
- ✅ Excel导出 - 数据完整导出
|
||||
|
||||
### 机构中介
|
||||
- ✅ 新增功能 - 数据正确插入 ccdi_enterprise_base_info
|
||||
- ✅ 自动设置标识 - risk_level='1', ent_source='INTERMEDIARY'
|
||||
- ✅ 列表查询 - 正确返回机构中介数据
|
||||
- ✅ 详情查询 - 所有字段正确映射
|
||||
- ✅ 修改功能 - 数据正确更新,标识保持不变
|
||||
- ✅ Excel导入 - 批量导入成功,自动设置高风险和中介来源
|
||||
- ✅ Excel导出 - 数据完整导出
|
||||
|
||||
### 边界条件
|
||||
- ✅ 唯一性约束 - 社会信用代码主键冲突
|
||||
- ✅ 必填字段验证 - 姓名和证件号验证生效
|
||||
|
||||
### 性能测试
|
||||
- ✅ 100条数据导入 - 耗时 < 10秒
|
||||
|
||||
## 数据映射验证
|
||||
|
||||
### 个人中介字段映射
|
||||
| 原字段 | 新字段 | 状态 |
|
||||
|--------|--------|------|
|
||||
| intermediary_id | biz_id | ✅ |
|
||||
| certificate_no | person_id | ✅ |
|
||||
| indiv_type | person_type | ✅ |
|
||||
| indiv_gender | gender | ✅ |
|
||||
| indiv_phone | mobile | ✅ |
|
||||
| indiv_wechat | wechat_no | ✅ |
|
||||
| indiv_address | contact_address | ✅ |
|
||||
|
||||
### 机构中介字段映射
|
||||
| 原字段 | 新字段 | 状态 |
|
||||
|--------|--------|------|
|
||||
| corp_credit_code | social_credit_code | ✅ |
|
||||
| name | enterprise_name | ✅ |
|
||||
| corp_type | enterprise_type | ✅ |
|
||||
| corp_nature | enterprise_nature | ✅ |
|
||||
| - | risk_level='1' | ✅ 自动设置 |
|
||||
| - | ent_source='INTERMEDIARY' | ✅ 自动设置 |
|
||||
|
||||
## 结论
|
||||
✅ 所有测试通过,入库逻辑变更成功!
|
||||
```
|
||||
|
||||
**Step 2: 提交测试报告**
|
||||
|
||||
```bash
|
||||
git add test_report.md
|
||||
git commit -m "test: 添加中介黑名单变更测试报告"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **机构中介ID处理**: 机构中介的主键是字符串类型(social_credit_code),查询详情时需要特殊处理
|
||||
|
||||
2. **自动设置标识**: 机构中介新增/导入时自动设置 `risk_level='1'` 和 `ent_source='INTERMEDIARY'`,修改时不应改变这两个值
|
||||
|
||||
3. **查询合并**: 列表查询需要从两个表获取数据并合并返回前端
|
||||
|
||||
4. **数据来源标识**:
|
||||
- 手动新增: date_source/data_source = 'MANUAL'
|
||||
- Excel导入: date_source/data_source = 'IMPORT'
|
||||
|
||||
5. **分页查询**: 当前实现是先查询所有数据再手动分页,大数据量时可能需要优化
|
||||
|
||||
6. **删除操作**: 当前只支持个人中介的数字ID删除,机构中介删除需要扩展支持
|
||||
46
doc/sql/menu_info_maintain.sql
Normal file
46
doc/sql/menu_info_maintain.sql
Normal file
@@ -0,0 +1,46 @@
|
||||
-- =====================================================
|
||||
-- 菜单SQL:信息维护模块
|
||||
-- 创建时间: 2025-02-04
|
||||
-- 说明: 包含"信息维护"一级菜单及其两个二级菜单
|
||||
-- =====================================================
|
||||
|
||||
-- 一级菜单:信息维护
|
||||
INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
VALUES(2000, '信息维护', 0, 5, 'maintain', NULL, NULL, NULL, 1, 0, 'M', '0', '0', NULL, 'el-icon-collection', 'admin', NOW(), '信息维护目录');
|
||||
|
||||
-- 二级菜单:中介黑名单管理
|
||||
INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
VALUES(2001, '中介黑名单管理', 2000, 1, 'intermediary', 'ccdiIntermediary/index', NULL, NULL, 1, 0, 'C', '0', '0', 'ccdi:intermediary:list', '#', 'admin', NOW(), '中介黑名单管理菜单');
|
||||
|
||||
-- 二级菜单:员工信息维护
|
||||
INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
VALUES(2002, '员工信息维护', 2000, 2, 'employee', 'ccdiEmployee/index', NULL, NULL, 1, 0, 'C', '0', '0', 'ccdi:employee:list', '#', 'admin', NOW(), '员工信息维护菜单');
|
||||
|
||||
-- =====================================================
|
||||
-- 中介黑名单管理 - 按钮权限
|
||||
-- =====================================================
|
||||
INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
VALUES
|
||||
(2010, '中介黑名单查询', 2001, 1, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:intermediary:query', '#', 'admin', NOW(), ''),
|
||||
(2011, '中介黑名单新增', 2001, 2, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:intermediary:add', '#', 'admin', NOW(), ''),
|
||||
(2012, '中介黑名单修改', 2001, 3, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:intermediary:edit', '#', 'admin', NOW(), ''),
|
||||
(2013, '中介黑名单删除', 2001, 4, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:intermediary:remove', '#', 'admin', NOW(), ''),
|
||||
(2014, '中介黑名单导出', 2001, 5, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:intermediary:export', '#', 'admin', NOW(), ''),
|
||||
(2015, '中介黑名单导入', 2001, 6, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:intermediary:import', '#', 'admin', NOW(), '');
|
||||
|
||||
-- =====================================================
|
||||
-- 员工信息维护 - 按钮权限
|
||||
-- =====================================================
|
||||
INSERT INTO sys_menu(menu_id, menu_name, parent_id, order_num, path, component, query, route_name, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, remark)
|
||||
VALUES
|
||||
(2020, '员工信息查询', 2002, 1, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:employee:query', '#', 'admin', NOW(), ''),
|
||||
(2021, '员工信息新增', 2002, 2, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:employee:add', '#', 'admin', NOW(), ''),
|
||||
(2022, '员工信息修改', 2002, 3, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:employee:edit', '#', 'admin', NOW(), ''),
|
||||
(2023, '员工信息删除', 2002, 4, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:employee:remove', '#', 'admin', NOW(), ''),
|
||||
(2024, '员工信息导出', 2002, 5, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:employee:export', '#', 'admin', NOW(), ''),
|
||||
(2025, '员工信息导入', 2002, 6, '', NULL, NULL, NULL, 1, 0, 'F', '0', '0', 'ccdi:employee:import', '#', 'admin', NOW(), '');
|
||||
|
||||
-- =====================================================
|
||||
-- 回滚SQL(如需删除这些菜单,执行以下语句)
|
||||
-- =====================================================
|
||||
-- DELETE FROM sys_menu WHERE menu_id BETWEEN 2000 AND 2025;
|
||||
269
doc/中介黑名单列表查询功能说明.md
Normal file
269
doc/中介黑名单列表查询功能说明.md
Normal file
@@ -0,0 +1,269 @@
|
||||
# 中介黑名单列表查询功能说明
|
||||
|
||||
## 接口说明
|
||||
|
||||
### 1. 列表查询接口(不分页)
|
||||
|
||||
**接口地址:** `GET /ccdi/intermediary/list`
|
||||
|
||||
**请求参数:**
|
||||
|
||||
| 参数名 | 类型 | 必填 | 说明 | 示例 |
|
||||
|--------|------|------|------|------|
|
||||
| name | String | 否 | 姓名/机构名称(模糊查询) | 张三 |
|
||||
| certificateNo | String | 否 | 证件号/社会信用代码(模糊查询) | 110101... |
|
||||
| intermediaryType | String | 否 | 中介类型(1=个人,2=机构) | 1 |
|
||||
| status | String | 否 | 状态(0=正常,1=停用) | 0 |
|
||||
| pageNum | Int | 否 | 页码 | 1 |
|
||||
| pageSize | Int | 否 | 每页条数 | 10 |
|
||||
|
||||
**查询场景示例:**
|
||||
|
||||
#### 场景1: 查询所有中介(个人+机构)
|
||||
```http
|
||||
GET /ccdi/intermediary/list
|
||||
```
|
||||
|
||||
#### 场景2: 只查询个人中介
|
||||
```http
|
||||
GET /ccdi/intermediary/list?intermediaryType=1
|
||||
```
|
||||
|
||||
#### 场景3: 只查询机构中介
|
||||
```http
|
||||
GET /ccdi/intermediary/list?intermediaryType=2
|
||||
```
|
||||
|
||||
#### 场景4: 按姓名查询个人中介
|
||||
```http
|
||||
GET /ccdi/intermediary/list?intermediaryType=1&name=张三
|
||||
```
|
||||
|
||||
#### 场景5: 按证件号查询机构中介
|
||||
```http
|
||||
GET /ccdi/intermediary/list?intermediaryType=2&certificateNo=91110000...
|
||||
```
|
||||
|
||||
#### 场景6: 分页查询所有中介
|
||||
```http
|
||||
GET /ccdi/intermediary/list?pageNum=1&pageSize=10
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## SQL 实现逻辑
|
||||
|
||||
### 分页查询优化
|
||||
|
||||
使用 `UNION ALL` 在数据库层面完成联合查询和分页,提升性能:
|
||||
|
||||
```sql
|
||||
SELECT * FROM (
|
||||
-- 个人中介查询
|
||||
SELECT
|
||||
biz_id AS intermediary_id,
|
||||
name,
|
||||
person_id AS certificate_no,
|
||||
'1' AS intermediary_type,
|
||||
'0' AS status,
|
||||
date_source AS data_source,
|
||||
create_time,
|
||||
update_time
|
||||
FROM ccdi_biz_intermediary
|
||||
WHERE 1=1
|
||||
<!-- 类型过滤 -->
|
||||
<if test="intermediaryType != null">
|
||||
AND '1' = #{intermediaryType}
|
||||
</if>
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- 机构中介查询
|
||||
SELECT
|
||||
0 AS intermediary_id,
|
||||
enterprise_name AS name,
|
||||
social_credit_code AS certificate_no,
|
||||
'2' AS intermediary_type,
|
||||
status,
|
||||
data_source,
|
||||
create_time,
|
||||
update_time
|
||||
FROM ccdi_enterprise_base_info
|
||||
WHERE ent_source = 'INTERMEDIARY'
|
||||
<!-- 类型过滤 -->
|
||||
<if test="intermediaryType != null">
|
||||
AND '2' = #{intermediaryType}
|
||||
</if>
|
||||
) AS combined_data
|
||||
ORDER BY create_time DESC
|
||||
LIMIT 10 OFFSET 0 -- MyBatis Plus 自动添加
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 类型过滤逻辑
|
||||
|
||||
### 在 SQL 子查询层面过滤
|
||||
|
||||
| 查询条件 | 个人中介子查询 | 机构中介子查询 |
|
||||
|----------|--------------|--------------|
|
||||
| `intermediaryType=null` | 执行 | 执行 |
|
||||
| `intermediaryType=1` | 执行 (`'1'='1'` 为真) | 不返回数据 (`'2'='1'` 为假) |
|
||||
| `intermediaryType=2` | 不返回数据 (`'1'='2'` 为假) | 执行 (`'2'='2'` 为真) |
|
||||
|
||||
**优势:**
|
||||
- ✅ 避免查询不需要的数据
|
||||
- ✅ 减少数据库 I/O
|
||||
- ✅ 提升 UNION 性能
|
||||
- ✅ 分页准确
|
||||
|
||||
---
|
||||
|
||||
## 列表查询(非分页)
|
||||
|
||||
Service 层实现:
|
||||
|
||||
```java
|
||||
@Override
|
||||
public List<CcdiIntermediaryBlacklistVO> selectIntermediaryList(
|
||||
CcdiIntermediaryBlacklistQueryDTO queryDTO) {
|
||||
|
||||
List<CcdiIntermediaryBlacklistVO> resultList = new ArrayList<>();
|
||||
|
||||
// 查询个人中介
|
||||
if (StringUtils.isEmpty(queryDTO.getIntermediaryType()) || "1".equals(queryDTO.getIntermediaryType())) {
|
||||
LambdaQueryWrapper<CcdiBizIntermediary> personWrapper = buildPersonQueryWrapper(queryDTO);
|
||||
List<CcdiBizIntermediary> personList = bizIntermediaryMapper.selectList(personWrapper);
|
||||
personList.forEach(person -> resultList.add(convertPersonToVO(person)));
|
||||
}
|
||||
|
||||
// 查询机构中介
|
||||
if (StringUtils.isEmpty(queryDTO.getIntermediaryType()) || "2".equals(queryDTO.getIntermediaryType())) {
|
||||
LambdaQueryWrapper<CcdiEnterpriseBaseInfo> entityWrapper = buildEntityQueryWrapper(queryDTO);
|
||||
List<CcdiEnterpriseBaseInfo> entityList = enterpriseBaseInfoMapper.selectList(entityWrapper);
|
||||
entityList.forEach(entity -> resultList.add(convertEntityToVO(entity)));
|
||||
}
|
||||
|
||||
return resultList;
|
||||
}
|
||||
```
|
||||
|
||||
**逻辑说明:**
|
||||
- 当 `intermediaryType` 为空时,查询两种类型
|
||||
- 当 `intermediaryType = "1"` 时,只查询个人中介
|
||||
- 当 `intermediaryType = "2"` 时,只查询机构中介
|
||||
|
||||
---
|
||||
|
||||
## 返回数据格式
|
||||
|
||||
### 个人中介
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"rows": [
|
||||
{
|
||||
"intermediaryId": 1,
|
||||
"name": "张三",
|
||||
"certificateNo": "110101199001011234",
|
||||
"intermediaryType": "1",
|
||||
"intermediaryTypeName": "个人",
|
||||
"status": "0",
|
||||
"statusName": "正常",
|
||||
"dataSource": "MANUAL",
|
||||
"dataSourceName": "手动录入",
|
||||
"createTime": "2026-02-04 10:00:00",
|
||||
"updateTime": "2026-02-04 10:00:00"
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
### 机构中介
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"rows": [
|
||||
{
|
||||
"intermediaryId": 0,
|
||||
"name": "测试机构有限公司",
|
||||
"certificateNo": "91110000123456789X",
|
||||
"intermediaryType": "2",
|
||||
"intermediaryTypeName": "机构",
|
||||
"status": "0",
|
||||
"statusName": "正常",
|
||||
"dataSource": "MANUAL",
|
||||
"dataSourceName": "手动录入",
|
||||
"createTime": "2026-02-04 10:00:00",
|
||||
"updateTime": "2026-02-04 10:00:00"
|
||||
}
|
||||
],
|
||||
"total": 1
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 性能对比
|
||||
|
||||
| 场景 | 旧实现 | 新实现 |
|
||||
|------|--------|--------|
|
||||
| 查询所有 | 查询2张表 | UNION ALL 查询2张表 |
|
||||
| 只查个人 | 查询2张表,应用层过滤 | 只查个人表 |
|
||||
| 只查机构 | 查询2张表,应用层过滤 | 只查机构表 |
|
||||
| 分页 | 查询全部,手动截取 | LIMIT/OFFSET 数据库分页 |
|
||||
|
||||
**性能提升:**
|
||||
- 只查个人/机构时,减少50%的数据库查询
|
||||
- 大数据量分页时,避免内存溢出
|
||||
- 网络传输量减少 90%+
|
||||
|
||||
---
|
||||
|
||||
## 测试用例
|
||||
|
||||
### 测试1: 查询所有中介
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/ccdi/intermediary/list" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
**预期:** 返回个人和机构两种类型的数据
|
||||
|
||||
### 测试2: 只查询个人中介
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/ccdi/intermediary/list?intermediaryType=1" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
**预期:** 只返回个人中介数据
|
||||
|
||||
### 测试3: 只查询机构中介
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/ccdi/intermediary/list?intermediaryType=2" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
**预期:** 只返回机构中介数据
|
||||
|
||||
### 测试4: 分页查询个人中介
|
||||
```bash
|
||||
curl -X GET "http://localhost:8080/ccdi/intermediary/list?intermediaryType=1&pageNum=1&pageSize=10" \
|
||||
-H "Authorization: Bearer $TOKEN"
|
||||
```
|
||||
|
||||
**预期:**
|
||||
- 返回第1页,最多10条个人中介数据
|
||||
- total 为个人中介的总数
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **类型过滤在数据库层面完成**,不是在应用层过滤
|
||||
2. **分页使用 MyBatis Plus 的自动分页**,SQL 自动添加 LIMIT/OFFSET
|
||||
3. **机构中介的 ID 为 0**,因为主键是字符串类型(社会信用代码)
|
||||
4. **查询时自动过滤 `ent_source='INTERMEDIARY'`**,确保只返回中介来源的企业
|
||||
326
doc/后端枚举字段说明.md
Normal file
326
doc/后端枚举字段说明.md
Normal file
@@ -0,0 +1,326 @@
|
||||
# 后端枚举字段说明
|
||||
|
||||
## 概述
|
||||
|
||||
后端只返回枚举代码值,不返回枚举名称。前端需要根据代码值进行转换显示。
|
||||
|
||||
---
|
||||
|
||||
## API 返回的枚举字段
|
||||
|
||||
### 1. 中介类型 (intermediaryType)
|
||||
|
||||
| 代码值 | 说明 |
|
||||
|--------|------|
|
||||
| `1` | 个人中介 |
|
||||
| `2` | 机构中介 |
|
||||
|
||||
**前端转换示例:**
|
||||
```javascript
|
||||
const getIntermediaryTypeName = (type) => {
|
||||
const map = {
|
||||
'1': '个人',
|
||||
'2': '机构'
|
||||
}
|
||||
return map[type] || '未知'
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 状态 (status)
|
||||
|
||||
| 代码值 | 说明 |
|
||||
|--------|------|
|
||||
| `0` | 正常 |
|
||||
| `1` | 停用 |
|
||||
|
||||
**前端转换示例:**
|
||||
```javascript
|
||||
const getStatusName = (status) => {
|
||||
const map = {
|
||||
'0': '正常',
|
||||
'1': '停用'
|
||||
}
|
||||
return map[status] || '未知'
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 数据来源 (dataSource / date_source)
|
||||
|
||||
| 代码值 | 说明 |
|
||||
|--------|------|
|
||||
| `MANUAL` | 手动录入 |
|
||||
| `IMPORT` | 批量导入 |
|
||||
| `SYSTEM` | 系统同步 |
|
||||
| `API` | 接口获取 |
|
||||
|
||||
**前端转换示例:**
|
||||
```javascript
|
||||
const getDataSourceName = (source) => {
|
||||
const map = {
|
||||
'MANUAL': '手动录入',
|
||||
'IMPORT': '批量导入',
|
||||
'SYSTEM': '系统同步',
|
||||
'API': '接口获取'
|
||||
}
|
||||
return map[source] || '未知'
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 性别 (indivGender) - 个人中介
|
||||
|
||||
| 代码值 | 说明 |
|
||||
|--------|------|
|
||||
| `M` | 男 |
|
||||
| `F` | 女 |
|
||||
| `O` | 其他 |
|
||||
|
||||
**前端转换示例:**
|
||||
```javascript
|
||||
const getGenderName = (gender) => {
|
||||
const map = {
|
||||
'M': '男',
|
||||
'F': '女',
|
||||
'O': '其他'
|
||||
}
|
||||
return map[gender] || '未知'
|
||||
}
|
||||
```
|
||||
|
||||
### 5. 证件类型 (indivCertType)
|
||||
|
||||
常用证件类型代码:
|
||||
- `身份证` - 身份证
|
||||
- `护照` - 护照
|
||||
- `港澳通行证` - 港澳通行证
|
||||
- `台湾通行证` - 台湾通行证
|
||||
|
||||
---
|
||||
|
||||
## API 返回数据示例
|
||||
|
||||
### 列表查询响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "查询成功",
|
||||
"rows": [
|
||||
{
|
||||
"intermediaryId": 1,
|
||||
"name": "张三",
|
||||
"certificateNo": "110101199001011234",
|
||||
"intermediaryType": "1",
|
||||
"status": "0",
|
||||
"dataSource": "MANUAL",
|
||||
"createTime": "2026-02-04 10:00:00",
|
||||
"updateTime": "2026-02-04 10:00:00"
|
||||
},
|
||||
{
|
||||
"intermediaryId": 0,
|
||||
"name": "测试机构有限公司",
|
||||
"certificateNo": "91110000123456789X",
|
||||
"intermediaryType": "2",
|
||||
"status": "0",
|
||||
"dataSource": "MANUAL",
|
||||
"createTime": "2026-02-04 10:00:00",
|
||||
"updateTime": "2026-02-04 10:00:00"
|
||||
}
|
||||
],
|
||||
"total": 2
|
||||
}
|
||||
```
|
||||
|
||||
### 个人中介详情响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"intermediaryId": 1,
|
||||
"name": "张三",
|
||||
"certificateNo": "110101199001011234",
|
||||
"intermediaryType": "1",
|
||||
"status": "0",
|
||||
"dataSource": "MANUAL",
|
||||
"remark": "测试数据",
|
||||
"indivType": "中介",
|
||||
"indivSubType": "本人",
|
||||
"indivGender": "M",
|
||||
"indivCertType": "身份证",
|
||||
"indivPhone": "13800138000",
|
||||
"indivWechat": "test_wx001",
|
||||
"indivAddress": "北京市朝阳区测试路123号",
|
||||
"indivCompany": "测试公司",
|
||||
"indivPosition": "测试员",
|
||||
"createTime": "2026-02-04 10:00:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 机构中介详情响应
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"intermediaryId": 0,
|
||||
"name": "测试机构有限公司",
|
||||
"certificateNo": "91110000123456789X",
|
||||
"intermediaryType": "2",
|
||||
"status": "0",
|
||||
"dataSource": "MANUAL",
|
||||
"remark": "机构中介测试数据",
|
||||
"corpCreditCode": "91110000123456789X",
|
||||
"corpType": "有限责任公司",
|
||||
"corpNature": "民营企业",
|
||||
"corpIndustryCategory": "制造业",
|
||||
"corpIndustry": "通用设备制造业",
|
||||
"corpEstablishDate": "2020-01-01",
|
||||
"corpAddress": "北京市海淀区测试大街456号",
|
||||
"corpLegalRep": "李四",
|
||||
"corpLegalCertType": "身份证",
|
||||
"corpLegalCertNo": "110101198001011234",
|
||||
"createTime": "2026-02-04 10:00:00"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 前端 Vue 组件示例
|
||||
|
||||
### 枚举转换工具函数
|
||||
|
||||
```javascript
|
||||
// utils/enums.js
|
||||
export const IntermediaryType = {
|
||||
PERSON: '1',
|
||||
ENTITY: '2',
|
||||
getName: (type) => {
|
||||
const map = {
|
||||
'1': '个人',
|
||||
'2': '机构'
|
||||
}
|
||||
return map[type] || '未知'
|
||||
}
|
||||
}
|
||||
|
||||
export const IntermediaryStatus = {
|
||||
NORMAL: '0',
|
||||
DISABLED: '1',
|
||||
getName: (status) => {
|
||||
const map = {
|
||||
'0': '正常',
|
||||
'1': '停用'
|
||||
}
|
||||
return map[status] || '未知'
|
||||
}
|
||||
}
|
||||
|
||||
export const DataSource = {
|
||||
MANUAL: 'MANUAL',
|
||||
IMPORT: 'IMPORT',
|
||||
SYSTEM: 'SYSTEM',
|
||||
API: 'API',
|
||||
getName: (source) => {
|
||||
const map = {
|
||||
'MANUAL': '手动录入',
|
||||
'IMPORT': '批量导入',
|
||||
'SYSTEM': '系统同步',
|
||||
'API': '接口获取'
|
||||
}
|
||||
return map[source] || '未知'
|
||||
}
|
||||
}
|
||||
|
||||
export const Gender = {
|
||||
MALE: 'M',
|
||||
FEMALE: 'F',
|
||||
OTHER: 'O',
|
||||
getName: (gender) => {
|
||||
const map = {
|
||||
'M': '男',
|
||||
'F': '女',
|
||||
'O': '其他'
|
||||
}
|
||||
return map[gender] || '未知'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 表格列使用枚举
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<el-table :data="tableData">
|
||||
<el-table-column prop="name" label="姓名" />
|
||||
|
||||
<el-table-column prop="intermediaryType" label="中介类型">
|
||||
<template #default="{ row }">
|
||||
{{ IntermediaryType.getName(row.intermediaryType) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="status" label="状态">
|
||||
<template #default="{ row }">
|
||||
<el-tag :type="row.status === '0' ? 'success' : 'danger'">
|
||||
{{ IntermediaryStatus.getName(row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<el-table-column prop="dataSource" label="数据来源">
|
||||
<template #default="{ row }">
|
||||
{{ DataSource.getName(row.dataSource) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { IntermediaryType, IntermediaryStatus, DataSource } from '@/utils/enums'
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
IntermediaryType,
|
||||
IntermediaryStatus,
|
||||
DataSource,
|
||||
tableData: []
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### 表单下拉框使用枚举
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<el-form :model="form">
|
||||
<el-form-item label="中介类型" prop="intermediaryType">
|
||||
<el-select v-model="form.intermediaryType" placeholder="请选择中介类型">
|
||||
<el-option label="个人" value="1" />
|
||||
<el-option label="机构" value="2" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="状态" prop="status">
|
||||
<el-radio-group v-model="form.status">
|
||||
<el-radio label="0">正常</el-radio>
|
||||
<el-radio label="1">停用</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</template>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **后端只返回代码值**,前端负责转换为显示名称
|
||||
2. **前端下拉框的 value 应该使用代码值**(如 '1', '2', '0' 等)
|
||||
3. **建议在前端统一维护枚举映射关系**,避免硬编码
|
||||
4. **新增枚举值时**,只需要前端更新映射表即可,后端无需修改
|
||||
5. **国际化支持**:前端可以根据语言切换返回不同的名称
|
||||
@@ -25,7 +25,7 @@ spring:
|
||||
druid:
|
||||
# 主库数据源
|
||||
master:
|
||||
url: jdbc:mysql://116.62.17.81:3306/discipline-prelim-check?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
url: jdbc:mysql://116.62.17.81:3306/ccdi?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
|
||||
username: root
|
||||
password: Kfcx@1234
|
||||
# 从库数据源
|
||||
|
||||
@@ -17,7 +17,7 @@ import java.util.List;
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Tag(name = "DPC枚举接口", description = "中介黑名单相关枚举选项接口")
|
||||
@Tag(name = "枚举接口", description = "中介黑名单相关枚举选项接口")
|
||||
@RestController
|
||||
@RequestMapping("/ccdi/enum")
|
||||
public class CcdiEnumController {
|
||||
|
||||
@@ -0,0 +1,90 @@
|
||||
package com.ruoyi.ccdi.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 中介人员业务对象 ccdi_biz_intermediary
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-04
|
||||
*/
|
||||
@Data
|
||||
@TableName("ccdi_biz_intermediary")
|
||||
public class CcdiBizIntermediary implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 业务ID */
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long bizId;
|
||||
|
||||
/** 人员类型 */
|
||||
private String personType;
|
||||
|
||||
/** 人员子类型 */
|
||||
private String personSubType;
|
||||
|
||||
/** 姓名 */
|
||||
private String name;
|
||||
|
||||
/** 性别 */
|
||||
private String gender;
|
||||
|
||||
/** 证件类型 */
|
||||
private String idType;
|
||||
|
||||
/** 证件号 */
|
||||
private String personId;
|
||||
|
||||
/** 手机号 */
|
||||
private String mobile;
|
||||
|
||||
/** 微信号 */
|
||||
private String wechatNo;
|
||||
|
||||
/** 联系地址 */
|
||||
private String contactAddress;
|
||||
|
||||
/** 所在公司 */
|
||||
private String company;
|
||||
|
||||
/** 社会信用代码 */
|
||||
private String socialCreditCode;
|
||||
|
||||
/** 职位 */
|
||||
private String position;
|
||||
|
||||
/** 关联人员ID */
|
||||
private String relatedNumId;
|
||||
|
||||
/** 关联关系 */
|
||||
private String relationType;
|
||||
|
||||
/** 数据来源 */
|
||||
private String dateSource;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 创建者 */
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createdBy;
|
||||
|
||||
/** 更新者 */
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updatedBy;
|
||||
|
||||
/** 创建时间 */
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
}
|
||||
@@ -0,0 +1,105 @@
|
||||
package com.ruoyi.ccdi.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 企业基础信息对象 ccdi_enterprise_base_info
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-04
|
||||
*/
|
||||
@Data
|
||||
@TableName("ccdi_enterprise_base_info")
|
||||
public class CcdiEnterpriseBaseInfo implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 统一社会信用代码 */
|
||||
@TableId
|
||||
private String socialCreditCode;
|
||||
|
||||
/** 企业名称 */
|
||||
private String enterpriseName;
|
||||
|
||||
/** 企业类型 */
|
||||
private String enterpriseType;
|
||||
|
||||
/** 企业性质 */
|
||||
private String enterpriseNature;
|
||||
|
||||
/** 行业分类 */
|
||||
private String industryClass;
|
||||
|
||||
/** 所属行业 */
|
||||
private String industryName;
|
||||
|
||||
/** 成立日期 */
|
||||
private Date establishDate;
|
||||
|
||||
/** 注册地址 */
|
||||
private String registerAddress;
|
||||
|
||||
/** 法定代表人 */
|
||||
private String legalRepresentative;
|
||||
|
||||
/** 法定代表人证件类型 */
|
||||
private String legalCertType;
|
||||
|
||||
/** 法定代表人证件号码 */
|
||||
private String legalCertNo;
|
||||
|
||||
/** 股东1 */
|
||||
private String shareholder1;
|
||||
|
||||
/** 股东2 */
|
||||
private String shareholder2;
|
||||
|
||||
/** 股东3 */
|
||||
private String shareholder3;
|
||||
|
||||
/** 股东4 */
|
||||
private String shareholder4;
|
||||
|
||||
/** 股东5 */
|
||||
private String shareholder5;
|
||||
|
||||
/** 状态 */
|
||||
private String status;
|
||||
|
||||
/** 风险等级 */
|
||||
private String riskLevel;
|
||||
|
||||
/** 企业来源 */
|
||||
private String entSource;
|
||||
|
||||
/** 数据来源 */
|
||||
private String dataSource;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 创建者 */
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private String createdBy;
|
||||
|
||||
/** 更新者 */
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private String updatedBy;
|
||||
|
||||
/** 创建时间 */
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private Date createTime;
|
||||
|
||||
/** 更新时间 */
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private Date updateTime;
|
||||
}
|
||||
@@ -2,12 +2,11 @@ package com.ruoyi.ccdi.domain.excel;
|
||||
|
||||
import com.alibaba.excel.annotation.ExcelProperty;
|
||||
import com.alibaba.excel.annotation.write.style.ColumnWidth;
|
||||
import com.ruoyi.ccdi.utils.converter.IntermediaryStatusConverter;
|
||||
import com.ruoyi.ccdi.utils.converter.IntermediaryTypeConverter;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 中介人员黑名单Excel导入导出对象
|
||||
@@ -32,12 +31,12 @@ public class CcdiIntermediaryBlacklistExcel implements Serializable {
|
||||
private String certificateNo;
|
||||
|
||||
/** 中介类型 */
|
||||
@ExcelProperty(value = "中介类型", converter = IntermediaryTypeConverter.class, index = 2)
|
||||
@ExcelProperty(value = "中介类型", index = 2)
|
||||
@ColumnWidth(15)
|
||||
private String intermediaryType;
|
||||
|
||||
/** 状态 */
|
||||
@ExcelProperty(value = "状态", converter = IntermediaryStatusConverter.class, index = 3)
|
||||
@ExcelProperty(value = "状态", index = 3)
|
||||
@ColumnWidth(10)
|
||||
private String status;
|
||||
|
||||
@@ -45,4 +44,143 @@ public class CcdiIntermediaryBlacklistExcel implements Serializable {
|
||||
@ExcelProperty(value = "备注", index = 4)
|
||||
@ColumnWidth(30)
|
||||
private String remark;
|
||||
|
||||
/** 数据来源 */
|
||||
@ExcelProperty(value = "数据来源", index = 5)
|
||||
@ColumnWidth(15)
|
||||
private String dataSource;
|
||||
|
||||
// ===== 个人字段 =====
|
||||
|
||||
/** 人员类型 */
|
||||
@ExcelProperty(value = "人员类型", index = 6)
|
||||
@ColumnWidth(15)
|
||||
private String indivType;
|
||||
|
||||
/** 人员子类型 */
|
||||
@ExcelProperty(value = "人员子类型", index = 7)
|
||||
@ColumnWidth(15)
|
||||
private String indivSubType;
|
||||
|
||||
/** 性别 */
|
||||
@ExcelProperty(value = "性别", index = 8)
|
||||
@ColumnWidth(10)
|
||||
private String indivGender;
|
||||
|
||||
/** 证件类型 */
|
||||
@ExcelProperty(value = "证件类型", index = 9)
|
||||
@ColumnWidth(15)
|
||||
private String indivCertType;
|
||||
|
||||
/** 手机号 */
|
||||
@ExcelProperty(value = "手机号", index = 10)
|
||||
@ColumnWidth(15)
|
||||
private String indivPhone;
|
||||
|
||||
/** 微信号 */
|
||||
@ExcelProperty(value = "微信号", index = 11)
|
||||
@ColumnWidth(15)
|
||||
private String indivWechat;
|
||||
|
||||
/** 联系地址 */
|
||||
@ExcelProperty(value = "联系地址", index = 12)
|
||||
@ColumnWidth(30)
|
||||
private String indivAddress;
|
||||
|
||||
/** 所在公司 */
|
||||
@ExcelProperty(value = "所在公司", index = 13)
|
||||
@ColumnWidth(20)
|
||||
private String indivCompany;
|
||||
|
||||
/** 职位 */
|
||||
@ExcelProperty(value = "职位", index = 14)
|
||||
@ColumnWidth(15)
|
||||
private String indivPosition;
|
||||
|
||||
/** 关联人员ID */
|
||||
@ExcelProperty(value = "关联人员ID", index = 15)
|
||||
@ColumnWidth(15)
|
||||
private String indivRelatedId;
|
||||
|
||||
/** 关联关系 */
|
||||
@ExcelProperty(value = "关联关系", index = 16)
|
||||
@ColumnWidth(15)
|
||||
private String indivRelation;
|
||||
|
||||
// ===== 机构字段 =====
|
||||
|
||||
/** 统一社会信用代码 */
|
||||
@ExcelProperty(value = "统一社会信用代码", index = 17)
|
||||
@ColumnWidth(20)
|
||||
private String corpCreditCode;
|
||||
|
||||
/** 主体类型 */
|
||||
@ExcelProperty(value = "主体类型", index = 18)
|
||||
@ColumnWidth(15)
|
||||
private String corpType;
|
||||
|
||||
/** 企业性质 */
|
||||
@ExcelProperty(value = "企业性质", index = 19)
|
||||
@ColumnWidth(15)
|
||||
private String corpNature;
|
||||
|
||||
/** 行业分类 */
|
||||
@ExcelProperty(value = "行业分类", index = 20)
|
||||
@ColumnWidth(15)
|
||||
private String corpIndustryCategory;
|
||||
|
||||
/** 所属行业 */
|
||||
@ExcelProperty(value = "所属行业", index = 21)
|
||||
@ColumnWidth(15)
|
||||
private String corpIndustry;
|
||||
|
||||
/** 成立日期 */
|
||||
@ExcelProperty(value = "成立日期", index = 22)
|
||||
@ColumnWidth(15)
|
||||
private Date corpEstablishDate;
|
||||
|
||||
/** 注册地址 */
|
||||
@ExcelProperty(value = "注册地址", index = 23)
|
||||
@ColumnWidth(30)
|
||||
private String corpAddress;
|
||||
|
||||
/** 法定代表人 */
|
||||
@ExcelProperty(value = "法定代表人", index = 24)
|
||||
@ColumnWidth(15)
|
||||
private String corpLegalRep;
|
||||
|
||||
/** 法定代表人证件类型 */
|
||||
@ExcelProperty(value = "法定代表人证件类型", index = 25)
|
||||
@ColumnWidth(20)
|
||||
private String corpLegalCertType;
|
||||
|
||||
/** 法定代表人证件号码 */
|
||||
@ExcelProperty(value = "法定代表人证件号码", index = 26)
|
||||
@ColumnWidth(20)
|
||||
private String corpLegalCertNo;
|
||||
|
||||
/** 股东1 */
|
||||
@ExcelProperty(value = "股东1", index = 27)
|
||||
@ColumnWidth(15)
|
||||
private String corpShareholder1;
|
||||
|
||||
/** 股东2 */
|
||||
@ExcelProperty(value = "股东2", index = 28)
|
||||
@ColumnWidth(15)
|
||||
private String corpShareholder2;
|
||||
|
||||
/** 股东3 */
|
||||
@ExcelProperty(value = "股东3", index = 29)
|
||||
@ColumnWidth(15)
|
||||
private String corpShareholder3;
|
||||
|
||||
/** 股东4 */
|
||||
@ExcelProperty(value = "股东4", index = 30)
|
||||
@ColumnWidth(15)
|
||||
private String corpShareholder4;
|
||||
|
||||
/** 股东5 */
|
||||
@ExcelProperty(value = "股东5", index = 31)
|
||||
@ColumnWidth(15)
|
||||
private String corpShareholder5;
|
||||
}
|
||||
|
||||
@@ -31,14 +31,11 @@ public class CcdiIntermediaryBlacklistVO implements Serializable {
|
||||
/** 中介类型 */
|
||||
private String intermediaryType;
|
||||
|
||||
/** 中介类型名称(用于前端显示) */
|
||||
private String intermediaryTypeName;
|
||||
|
||||
/** 状态 */
|
||||
private String status;
|
||||
|
||||
/** 状态名称(用于前端显示) */
|
||||
private String statusName;
|
||||
/** 数据来源 */
|
||||
private String dataSource;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
@@ -34,24 +34,15 @@ public class CcdiIntermediaryEntityDetailVO implements Serializable {
|
||||
/** 中介类型 */
|
||||
private String intermediaryType;
|
||||
|
||||
/** 中介类型名称 */
|
||||
private String intermediaryTypeName;
|
||||
|
||||
/** 状态 */
|
||||
private String status;
|
||||
|
||||
/** 状态名称 */
|
||||
private String statusName;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 数据来源 */
|
||||
private String dataSource;
|
||||
|
||||
/** 数据来源名称 */
|
||||
private String dataSourceName;
|
||||
|
||||
// ============================================================
|
||||
// 机构专属字段
|
||||
// ============================================================
|
||||
@@ -61,15 +52,9 @@ public class CcdiIntermediaryEntityDetailVO implements Serializable {
|
||||
/** 主体类型 */
|
||||
private String corpType;
|
||||
|
||||
/** 主体类型名称 */
|
||||
private String corpTypeName;
|
||||
|
||||
/** 企业性质 */
|
||||
private String corpNature;
|
||||
|
||||
/** 企业性质名称 */
|
||||
private String corpNatureName;
|
||||
|
||||
/** 行业分类 */
|
||||
private String corpIndustryCategory;
|
||||
|
||||
|
||||
@@ -34,24 +34,15 @@ public class CcdiIntermediaryPersonDetailVO implements Serializable {
|
||||
/** 中介类型 */
|
||||
private String intermediaryType;
|
||||
|
||||
/** 中介类型名称 */
|
||||
private String intermediaryTypeName;
|
||||
|
||||
/** 状态 */
|
||||
private String status;
|
||||
|
||||
/** 状态名称 */
|
||||
private String statusName;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
/** 数据来源 */
|
||||
private String dataSource;
|
||||
|
||||
/** 数据来源名称 */
|
||||
private String dataSourceName;
|
||||
|
||||
// ============================================================
|
||||
// 个人专属字段
|
||||
// ============================================================
|
||||
@@ -64,15 +55,9 @@ public class CcdiIntermediaryPersonDetailVO implements Serializable {
|
||||
/** 性别 */
|
||||
private String indivGender;
|
||||
|
||||
/** 性别名称 */
|
||||
private String indivGenderName;
|
||||
|
||||
/** 证件类型 */
|
||||
private String indivCertType;
|
||||
|
||||
/** 证件类型名称 */
|
||||
private String indivCertTypeName;
|
||||
|
||||
/** 手机号码 */
|
||||
private String indivPhone;
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.ccdi.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.ruoyi.ccdi.domain.CcdiBizIntermediary;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 中介人员业务Mapper接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-04
|
||||
*/
|
||||
@Mapper
|
||||
public interface CcdiBizIntermediaryMapper extends BaseMapper<CcdiBizIntermediary> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.ruoyi.ccdi.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.ruoyi.ccdi.domain.CcdiEnterpriseBaseInfo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
/**
|
||||
* 企业基础信息Mapper接口
|
||||
*
|
||||
* @author ruoyi
|
||||
* @date 2026-02-04
|
||||
*/
|
||||
@Mapper
|
||||
public interface CcdiEnterpriseBaseInfoMapper extends BaseMapper<CcdiEnterpriseBaseInfo> {
|
||||
|
||||
}
|
||||
@@ -1,7 +1,11 @@
|
||||
package com.ruoyi.ccdi.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.ccdi.domain.CcdiIntermediaryBlacklist;
|
||||
import com.ruoyi.ccdi.domain.dto.CcdiIntermediaryBlacklistQueryDTO;
|
||||
import com.ruoyi.ccdi.domain.vo.CcdiIntermediaryBlacklistVO;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
@@ -29,4 +33,17 @@ public interface CcdiIntermediaryBlacklistMapper extends BaseMapper<CcdiIntermed
|
||||
* @return 更新行数
|
||||
*/
|
||||
int batchUpdate(@Param("list") List<CcdiIntermediaryBlacklist> list);
|
||||
|
||||
/**
|
||||
* 联合查询分页 - 个人和机构中介
|
||||
* 使用 UNION ALL 合并两张表的数据,在数据库层面完成分页
|
||||
*
|
||||
* @param page 分页对象
|
||||
* @param queryDTO 查询条件
|
||||
* @return 分页结果
|
||||
*/
|
||||
IPage<CcdiIntermediaryBlacklistVO> selectIntermediaryUnionPage(
|
||||
Page<CcdiIntermediaryBlacklistVO> page,
|
||||
@Param("queryDTO") CcdiIntermediaryBlacklistQueryDTO queryDTO
|
||||
);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,65 +0,0 @@
|
||||
package com.ruoyi.ccdi.utils.converter;
|
||||
|
||||
import com.alibaba.excel.converters.Converter;
|
||||
import com.alibaba.excel.enums.CellDataTypeEnum;
|
||||
import com.alibaba.excel.metadata.GlobalConfiguration;
|
||||
import com.alibaba.excel.metadata.data.ReadCellData;
|
||||
import com.alibaba.excel.metadata.data.WriteCellData;
|
||||
import com.alibaba.excel.metadata.property.ExcelContentProperty;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 员工状态转换器
|
||||
* 0=在职, 1=离职
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class EmployeeStatusConverter implements Converter<String> {
|
||||
|
||||
private static final Map<String, String> CODE_TO_DESC = new HashMap<>();
|
||||
private static final Map<String, String> DESC_TO_CODE = new HashMap<>();
|
||||
|
||||
static {
|
||||
CODE_TO_DESC.put("0", "在职");
|
||||
CODE_TO_DESC.put("1", "离职");
|
||||
DESC_TO_CODE.put("在职", "0");
|
||||
DESC_TO_CODE.put("离职", "1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> supportJavaTypeKey() {
|
||||
return String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CellDataTypeEnum supportExcelTypeKey() {
|
||||
return CellDataTypeEnum.STRING;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String convertToJavaData(ReadCellData<?> cellData, ExcelContentProperty contentProperty,
|
||||
GlobalConfiguration globalConfiguration) {
|
||||
String value = cellData.getStringValue();
|
||||
if (value == null) {
|
||||
return null;
|
||||
}
|
||||
// 支持中文和代码两种格式
|
||||
if (DESC_TO_CODE.containsKey(value)) {
|
||||
return DESC_TO_CODE.get(value);
|
||||
}
|
||||
// 如果是纯数字,直接返回
|
||||
if (value.matches("\\d")) {
|
||||
return value;
|
||||
}
|
||||
throw new IllegalArgumentException("无效的员工状态: " + value + ", 请使用: 在职/离职 或 0/1");
|
||||
}
|
||||
|
||||
@Override
|
||||
public WriteCellData<?> convertToExcelData(String value, ExcelContentProperty contentProperty,
|
||||
GlobalConfiguration globalConfiguration) {
|
||||
String desc = CODE_TO_DESC.getOrDefault(value, value);
|
||||
return new WriteCellData<>(desc);
|
||||
}
|
||||
}
|
||||
@@ -1,47 +0,0 @@
|
||||
package com.ruoyi.ccdi.utils.handler;
|
||||
|
||||
import com.alibaba.excel.write.handler.SheetWriteHandler;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
|
||||
import com.alibaba.excel.write.metadata.holder.WriteWorkbookHolder;
|
||||
import org.apache.poi.ss.usermodel.DataValidation;
|
||||
import org.apache.poi.ss.usermodel.DataValidationHelper;
|
||||
import org.apache.poi.ss.usermodel.Sheet;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
import org.apache.poi.ss.util.CellRangeAddressList;
|
||||
|
||||
/**
|
||||
* 员工状态下拉框处理器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
public class EmployeeStatusSheetWriteHandler implements SheetWriteHandler {
|
||||
|
||||
@Override
|
||||
public void afterSheetCreate(WriteWorkbookHolder writeWorkbookHolder, WriteSheetHolder writeSheetHolder) {
|
||||
Sheet sheet = writeSheetHolder.getSheet();
|
||||
Workbook workbook = writeWorkbookHolder.getWorkbook();
|
||||
DataValidationHelper helper = sheet.getDataValidationHelper();
|
||||
|
||||
// 创建下拉框数据列表
|
||||
String[] statusList = {"在职", "离职"};
|
||||
|
||||
// 设置状态下拉框,从第2行开始(第1行是表头),第7列(状态列,索引为6)
|
||||
CellRangeAddressList addressList = new CellRangeAddressList(1, 10000, 6, 6);
|
||||
|
||||
// 创建显式列表约束
|
||||
DataValidation validation = helper.createValidation(
|
||||
helper.createExplicitListConstraint(statusList),
|
||||
addressList
|
||||
);
|
||||
|
||||
// 设置提示信息
|
||||
validation.createPromptBox("状态选择", "请选择员工状态:在职或离职");
|
||||
validation.setShowPromptBox(true);
|
||||
|
||||
// 设置错误提示
|
||||
validation.createErrorBox("状态错误", "请从下拉框中选择有效的状态值!");
|
||||
validation.setShowErrorBox(true);
|
||||
|
||||
sheet.addValidationData(validation);
|
||||
}
|
||||
}
|
||||
@@ -131,4 +131,62 @@
|
||||
</foreach>
|
||||
</update>
|
||||
|
||||
<!-- 联合查询分页 - 个人和机构中介 -->
|
||||
<select id="selectIntermediaryUnionPage" resultType="com.ruoyi.ccdi.domain.vo.CcdiIntermediaryBlacklistVO">
|
||||
SELECT * FROM (
|
||||
-- 个人中介查询
|
||||
SELECT
|
||||
biz_id AS intermediary_id,
|
||||
name,
|
||||
person_id AS certificate_no,
|
||||
'1' AS intermediary_type,
|
||||
'0' AS status,
|
||||
date_source AS data_source,
|
||||
create_time,
|
||||
update_time
|
||||
FROM ccdi_biz_intermediary
|
||||
WHERE 1=1
|
||||
<!-- 类型过滤: 只在查询个人或不指定类型时查询 -->
|
||||
<if test="queryDTO != null and queryDTO.intermediaryType != null and queryDTO.intermediaryType != ''">
|
||||
AND '1' = #{queryDTO.intermediaryType}
|
||||
</if>
|
||||
<if test="queryDTO != null">
|
||||
<if test="queryDTO.name != null and queryDTO.name != ''">
|
||||
AND name LIKE CONCAT('%', #{queryDTO.name}, '%')
|
||||
</if>
|
||||
<if test="queryDTO.certificateNo != null and queryDTO.certificateNo != ''">
|
||||
AND person_id LIKE CONCAT('%', #{queryDTO.certificateNo}, '%')
|
||||
</if>
|
||||
</if>
|
||||
|
||||
UNION ALL
|
||||
|
||||
-- 机构中介查询
|
||||
SELECT
|
||||
0 AS intermediary_id,
|
||||
enterprise_name AS name,
|
||||
social_credit_code AS certificate_no,
|
||||
'2' AS intermediary_type,
|
||||
status,
|
||||
data_source,
|
||||
create_time,
|
||||
update_time
|
||||
FROM ccdi_enterprise_base_info
|
||||
WHERE ent_source = 'INTERMEDIARY'
|
||||
<!-- 类型过滤: 只在查询机构或不指定类型时查询 -->
|
||||
<if test="queryDTO != null and queryDTO.intermediaryType != null and queryDTO.intermediaryType != ''">
|
||||
AND '2' = #{queryDTO.intermediaryType}
|
||||
</if>
|
||||
<if test="queryDTO != null">
|
||||
<if test="queryDTO.name != null and queryDTO.name != ''">
|
||||
AND enterprise_name LIKE CONCAT('%', #{queryDTO.name}, '%')
|
||||
</if>
|
||||
<if test="queryDTO.certificateNo != null and queryDTO.certificateNo != ''">
|
||||
AND social_credit_code LIKE CONCAT('%', #{queryDTO.certificateNo}, '%')
|
||||
</if>
|
||||
</if>
|
||||
) AS combined_data
|
||||
ORDER BY create_time DESC
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
|
||||
Reference in New Issue
Block a user