Files
ccdi/doc/plans/2026-02-04-intermediary-blacklist-table-migration-test.md
2026-02-04 18:36:20 +08:00

19 KiB

中介黑名单入库逻辑变更 - 测试验证计划

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: 验证数据库连接配置

检查配置文件中的数据库连接信息:

spring:
  datasource:
    druid:
      master:
        url: jdbc:mysql://116.62.17.81:3306/ccdi
        username: root
        password: Kfcx@1234

Step 2: 确认目标表存在

通过MCP工具验证表存在:

SHOW TABLES LIKE 'ccdi_biz_intermediary';
SHOW TABLES LIKE 'ccdi_enterprise_base_info';

预期: 两个表都存在

Step 3: 检查表结构

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:

{
  "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

curl -X POST http://localhost:8080/login/test \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"admin123"}' \
  | jq -r '.data.token'

保存token到环境变量:

export TOKEN="获取到的token值"

Step 3: 调用新增接口

curl -X POST http://localhost:8080/ccdi/intermediary/person \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d @test_person_add.json

预期响应:

{
  "code": 200,
  "msg": "操作成功"
}

Step 4: 验证数据插入到正确的表

通过MCP查询数据库:

SELECT * FROM ccdi_biz_intermediary
WHERE person_id = '110101199001011234';

预期:

  • 找到1条记录
  • name = '测试个人中介'
  • date_source = 'MANUAL'

Step 5: 验证旧表无数据

SELECT * FROM ccdi_intermediary_blacklist
WHERE certificate_no = '110101199001011234';

预期: 0条记录(表可能不存在或为空)


Task 3: 测试个人中介列表查询

Files:

  • Test API: GET /ccdi/intermediary/list

Step 1: 调用列表查询接口

curl -X GET "http://localhost:8080/ccdi/intermediary/list?name=测试个人中介" \
  -H "Authorization: Bearer $TOKEN"

预期响应:

{
  "code": 200,
  "msg": "查询成功",
  "rows": [
    {
      "intermediaryId": 1,
      "name": "测试个人中介",
      "certificateNo": "110101199001011234",
      "intermediaryType": "1",
      "intermediaryTypeName": "个人",
      "status": "0",
      "statusName": "正常"
    }
  ],
  "total": 1
}

Step 2: 验证查询结果来源

确认数据来自 ccdi_biz_intermediary

Step 3: 测试分页查询

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: 获取个人中介详情

curl -X GET "http://localhost:8080/ccdi/intermediary/1" \
  -H "Authorization: Bearer $TOKEN"

预期响应:

{
  "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:

{
  "intermediaryId": 1,
  "name": "测试个人中介-已修改",
  "certificateNo": "110101199001011234",
  "indivType": "中介",
  "indivGender": "M",
  "indivPhone": "13900139000",
  "indivCompany": "新公司",
  "remark": "已修改"
}

Step 2: 调用修改接口

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: 验证数据已更新

SELECT * FROM ccdi_biz_intermediary
WHERE biz_id = 1;

预期:

  • name = '测试个人中介-已修改'
  • mobile = '13900139000'
  • company = '新公司'

Task 6: 测试个人中介删除功能

Files:

  • Test API: DELETE /ccdi/intermediary/{ids}

Step 1: 调用删除接口

curl -X DELETE "http://localhost:8080/ccdi/intermediary/1" \
  -H "Authorization: Bearer $TOKEN"

预期: { "code": 200, "msg": "操作成功" }

Step 2: 验证数据已删除

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:

{
  "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: 调用新增接口

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: 验证数据插入到正确的表

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: 验证关键字段自动设置

检查两个重要标识:

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: 查询机构中介

curl -X GET "http://localhost:8080/ccdi/intermediary/list?intermediaryType=2&name=测试机构" \
  -H "Authorization: Bearer $TOKEN"

预期响应:

{
  "code": 200,
  "rows": [
    {
      "intermediaryId": 0,
      "name": "测试机构中介有限公司",
      "certificateNo": "91110000123456789X",
      "intermediaryType": "2",
      "intermediaryTypeName": "机构",
      "status": "0",
      "statusName": "正常"
    }
  ]
}

Step 2: 验证ent_source过滤

查询应该只返回 ent_source='INTERMEDIARY' 的记录

Step 3: 混合查询(个人+机构)

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:

{
  "corpCreditCode": "91110000123456789X",
  "name": "测试机构中介有限公司-已修改",
  "corpType": "股份有限公司",
  "corpNature": "国有企业",
  "status": "0",
  "remark": "已修改"
}

Step 2: 调用修改接口

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: 验证高风险和中介来源标识不变

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: 下载导入模板

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: 执行导入

curl -X POST "http://localhost:8080/ccdi/intermediary/importPersonData?updateSupport=false" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@person_test_data.xlsx"

预期:

{
  "code": 200,
  "msg": "恭喜您,数据已全部导入成功!共 1 条"
}

Step 4: 验证导入数据

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: 下载导入模板

curl -X POST http://localhost:8080/ccdi/intermediary/importEntityTemplate \
  -H "Authorization: Bearer $TOKEN" \
  --output entity_template.xlsx

预期: 下载成功,文件包含所有机构字段

Step 2: 准备测试Excel文件

创建Excel文件,包含:

  • 机构名称: "导入测试机构有限公司"
  • 统一社会信用代码: "91110000987654321A"
  • 主体类型: "有限责任公司"
  • 企业性质: "民营企业"
  • 法定代表人: "李四"

Step 3: 执行导入

curl -X POST "http://localhost:8080/ccdi/intermediary/importEntityData?updateSupport=false" \
  -H "Authorization: Bearer $TOKEN" \
  -F "file=@entity_test_data.xlsx"

预期:

{
  "code": 200,
  "msg": "恭喜您,数据已全部导入成功!共 1 条"
}

Step 4: 验证导入数据和自动设置标识

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: 导出所有数据

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: 测试条件导出

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的记录:

# 使用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: 机构中介社会信用代码重复插入

# 使用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:

{
  "certificateNo": "110101199003033456",
  "status": "0"
}
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:

{
  "name": "测试机构",
  "status": "0"
}
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: 执行批量导入

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: 验证数据一致性

SELECT COUNT(*) FROM ccdi_biz_intermediary
WHERE date_source = 'IMPORT';

预期: 导入的记录数与Excel文件一致


清理测试数据

Task 17: 清理测试数据

Step 1: 删除测试个人中介数据

DELETE FROM ccdi_biz_intermediary
WHERE person_id IN (
  '110101199001011234',
  '110101199002022345'
);

Step 2: 删除测试机构中介数据

DELETE FROM ccdi_enterprise_base_info
WHERE social_credit_code IN (
  '91110000123456789X',
  '91110000987654321A'
);

Step 3: 验证清理完成

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:

# 中介黑名单入库逻辑变更测试报告

## 测试环境
- 数据库: 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: 提交测试报告

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删除,机构中介删除需要扩展支持