文件夹整理
This commit is contained in:
915
doc/requirements/plans/2026-02-05-导入逻辑优化实施计划.md
Normal file
915
doc/requirements/plans/2026-02-05-导入逻辑优化实施计划.md
Normal file
@@ -0,0 +1,915 @@
|
||||
# 导入逻辑优化实施计划
|
||||
|
||||
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
||||
|
||||
**目标:** 优化员工信息、中介库(个人/实体)、招聘信息的导入功能,从"存在则更新"改为"先删除后插入"策略。
|
||||
|
||||
**架构:** 三阶段流程:数据验证 → 批量删除 → 批量插入。所有操作在一个 @Transactional 事务中执行。
|
||||
|
||||
**技术栈:** Spring Boot 3.5.8, MyBatis Plus 3.5.10, MySQL 8.2.0
|
||||
|
||||
---
|
||||
|
||||
## 模块 1:员工信息管理(验证方案)
|
||||
|
||||
此模块用于验证新逻辑的正确性,成功后应用到其他模块。
|
||||
|
||||
### Task 1.1:添加批量删除方法到 Mapper 接口
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiEmployeeMapper.java`
|
||||
|
||||
**Step 1: 在 Mapper 接口中添加方法声明**
|
||||
|
||||
在 `CcdiEmployeeMapper.java` 的接口中添加新方法(在现有方法后面,`insertBatch` 方法之后):
|
||||
|
||||
```java
|
||||
/**
|
||||
* 根据身份证号批量删除员工数据
|
||||
*
|
||||
* @param idCards 身份证号列表
|
||||
* @return 删除行数
|
||||
*/
|
||||
int deleteBatchByIdCard(@Param("list") List<String> idCards);
|
||||
```
|
||||
|
||||
**Step 2: 保存文件**
|
||||
|
||||
无需测试,这是接口声明。
|
||||
|
||||
**Step 3: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiEmployeeMapper.java
|
||||
git commit -m "feat(employee): 添加批量删除方法声明"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 1.2:在 Mapper XML 中实现批量删除 SQL
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiEmployeeMapper.xml`
|
||||
|
||||
**Step 1: 在 XML 文件中添加删除 SQL**
|
||||
|
||||
在 `CcdiEmployeeMapper.xml` 中,在 `insertBatch` 方法之后添加:
|
||||
|
||||
```xml
|
||||
<!-- 根据身份证号批量删除员工数据 -->
|
||||
<delete id="deleteBatchByIdCard">
|
||||
DELETE FROM ccdi_employee
|
||||
WHERE id_card IN
|
||||
<foreach collection="list" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</delete>
|
||||
```
|
||||
|
||||
**Step 2: 保存文件**
|
||||
|
||||
无需测试,SQL 配置。
|
||||
|
||||
**Step 3: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiEmployeeMapper.xml
|
||||
git commit -m "feat(employee): 实现批量删除SQL"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 1.3:重构员工导入方法(先删后插逻辑)
|
||||
|
||||
- [x] **已完成** (commit: ebe4fd7)
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiEmployeeServiceImpl.java`
|
||||
- 目标方法:`importEmployee` (第 172-311 行)
|
||||
|
||||
**Step 1: 备份原方法**
|
||||
|
||||
先注释掉原有的 `importEmployee` 方法(保留参考)。
|
||||
|
||||
**Step 2: 实现新的导入逻辑**
|
||||
|
||||
将整个 `importEmployee` 方法替换为:
|
||||
|
||||
```java
|
||||
/**
|
||||
* 导入员工数据(先删后插模式)
|
||||
*
|
||||
* @param excelList Excel实体列表
|
||||
* @param isUpdateSupport 是否更新支持(参数保留以保持兼容性,不再使用)
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String importEmployee(List<CcdiEmployeeExcel> excelList, Boolean isUpdateSupport) {
|
||||
if (StringUtils.isNull(excelList) || excelList.isEmpty()) {
|
||||
return "至少需要一条数据";
|
||||
}
|
||||
|
||||
// 第一阶段:数据验证和收集
|
||||
List<CcdiEmployee> validEmployees = new ArrayList<>();
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
Set<String> idCards = new HashSet<>();
|
||||
|
||||
for (CcdiEmployeeExcel excel : excelList) {
|
||||
try {
|
||||
// 转换为AddDTO
|
||||
CcdiEmployeeAddDTO addDTO = new CcdiEmployeeAddDTO();
|
||||
BeanUtils.copyProperties(excel, addDTO);
|
||||
|
||||
// 验证必填字段和数据格式
|
||||
validateEmployeeDataBasic(addDTO);
|
||||
|
||||
// 检查导入数据内部是否重复
|
||||
if (!idCards.add(addDTO.getIdCard())) {
|
||||
throw new RuntimeException("导入文件中该身份证号重复");
|
||||
}
|
||||
|
||||
// 转换为实体,设置审计字段
|
||||
CcdiEmployee employee = new CcdiEmployee();
|
||||
BeanUtils.copyProperties(addDTO, employee);
|
||||
employee.setCreateBy("导入");
|
||||
employee.setUpdateBy("导入");
|
||||
|
||||
validEmployees.add(employee);
|
||||
|
||||
} catch (Exception e) {
|
||||
errorMessages.add(String.format("%s 导入失败:%s",
|
||||
excel.getName(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
// 第二阶段:批量删除已存在的记录
|
||||
if (!validEmployees.isEmpty()) {
|
||||
employeeMapper.deleteBatchByIdCard(new ArrayList<>(idCards));
|
||||
}
|
||||
|
||||
// 第三阶段:批量插入所有数据
|
||||
if (!validEmployees.isEmpty()) {
|
||||
employeeMapper.insertBatch(validEmployees);
|
||||
}
|
||||
|
||||
// 第四阶段:返回结果
|
||||
if (!errorMessages.isEmpty()) {
|
||||
StringBuilder failureMsg = new StringBuilder();
|
||||
failureMsg.append("很抱歉,导入完成!成功 ")
|
||||
.append(validEmployees.size())
|
||||
.append(" 条,失败 ")
|
||||
.append(errorMessages.size())
|
||||
.append(" 条,错误如下:");
|
||||
|
||||
for (int i = 0; i < errorMessages.size(); i++) {
|
||||
failureMsg.append("<br/>")
|
||||
.append(i + 1)
|
||||
.append("、")
|
||||
.append(errorMessages.get(i));
|
||||
}
|
||||
|
||||
throw new RuntimeException(failureMsg.toString());
|
||||
}
|
||||
|
||||
return "恭喜您,数据已全部导入成功!共 " + validEmployees.size() + " 条";
|
||||
}
|
||||
```
|
||||
|
||||
**Step 2: 保存文件**
|
||||
|
||||
无需测试,代码修改。
|
||||
|
||||
**Step 3: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiEmployeeServiceImpl.java
|
||||
git commit -m "refactor(employee): 重构导入方法为先删后插模式"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 1.4:生成员工模块测试脚本
|
||||
|
||||
**文件:**
|
||||
- 创建:`test/test_employee_import_delete.ps1`
|
||||
|
||||
**Step 1: 创建测试脚本**
|
||||
|
||||
创建 PowerShell 测试脚本:
|
||||
|
||||
```powershell
|
||||
# 员工导入功能测试脚本(先删后插模式)
|
||||
# 目的:验证新的导入逻辑是否正常工作
|
||||
|
||||
# 配置
|
||||
$BaseUrl = "http://localhost:8080"
|
||||
$LoginUrl = "$BaseUrl/login/test"
|
||||
$ImportUrl = "$BaseUrl/ccdi/employee/importData"
|
||||
|
||||
# 测试账号
|
||||
$Username = "admin"
|
||||
$Password = "admin123"
|
||||
|
||||
# 日志文件
|
||||
$LogFile = "test/employee_import_test_$(Get-Date -Format 'yyyyMMdd_HHmmss').txt"
|
||||
|
||||
# 开始记录日志
|
||||
function Write-Log {
|
||||
param([string]$Message)
|
||||
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
|
||||
$logMessage = "[$timestamp] $Message"
|
||||
Write-Host $logMessage
|
||||
Add-Content -Path $LogFile -Value $logMessage
|
||||
}
|
||||
|
||||
Write-Log "=========================================="
|
||||
Write-Log "员工导入功能测试(先删后插模式)"
|
||||
Write-Log "=========================================="
|
||||
Write-Log ""
|
||||
|
||||
# 步骤1:登录获取Token
|
||||
Write-Log "步骤1:登录获取Token..."
|
||||
try {
|
||||
$loginBody = @{
|
||||
username = $Username
|
||||
password = $Password
|
||||
} | ConvertTo-Json
|
||||
|
||||
$loginResponse = Invoke-RestMethod -Uri $LoginUrl -Method Post -Body $loginBody -ContentType "application/json"
|
||||
|
||||
if ($loginResponse.code -eq 200) {
|
||||
$Token = $loginResponse.token
|
||||
Write-Log "✓ 登录成功"
|
||||
} else {
|
||||
Write-Log "✗ 登录失败: $($loginResponse.msg)"
|
||||
exit 1
|
||||
}
|
||||
} catch {
|
||||
Write-Log "✗ 登录请求失败: $_"
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Log ""
|
||||
|
||||
# 步骤2:准备测试数据
|
||||
Write-Log "步骤2:准备测试数据..."
|
||||
|
||||
$testData = @{
|
||||
list = @(
|
||||
@{
|
||||
employeeId = 1001
|
||||
name = "测试用户A"
|
||||
deptId = 103
|
||||
idCard = "110101199001011234"
|
||||
phone = "13800138001"
|
||||
hireDate = "2020-01-01"
|
||||
status = "0"
|
||||
},
|
||||
@{
|
||||
employeeId = 1002
|
||||
name = "测试用户B"
|
||||
deptId = 103
|
||||
idCard = "110101199001022345"
|
||||
phone = "13800138002"
|
||||
hireDate = "2020-01-02"
|
||||
status = "0"
|
||||
}
|
||||
)
|
||||
} | ConvertTo-Json -Depth 10
|
||||
|
||||
Write-Log "测试数据准备完成(2条记录)"
|
||||
Write-Log ""
|
||||
|
||||
# 步骤3:执行导入
|
||||
Write-Log "步骤3:执行导入..."
|
||||
|
||||
try {
|
||||
$headers = @{
|
||||
"Authorization" = "Bearer $Token"
|
||||
}
|
||||
|
||||
$importResponse = Invoke-RestMethod -Uri $ImportUrl -Method Post -Headers $headers -Body $testData -ContentType "application/json"
|
||||
|
||||
Write-Log ""
|
||||
Write-Log "=========================================="
|
||||
Write-Log "导入结果:"
|
||||
Write-Log "=========================================="
|
||||
Write-Log "响应代码: $($importResponse.code)"
|
||||
Write-Log "响应消息: $($importResponse.msg)"
|
||||
|
||||
if ($importResponse.code -eq 200) {
|
||||
Write-Log ""
|
||||
Write-Log "✓ 导入测试成功!"
|
||||
} else {
|
||||
Write-Log ""
|
||||
Write-Log "✗ 导入测试失败!"
|
||||
}
|
||||
|
||||
} catch {
|
||||
Write-Log ""
|
||||
Write-Log "✗ 导入请求失败:"
|
||||
Write-Log "错误信息: $_"
|
||||
}
|
||||
|
||||
Write-Log ""
|
||||
Write-Log "=========================================="
|
||||
Write-Log "测试完成"
|
||||
Write-Log "详细日志: $LogFile"
|
||||
Write-Log "=========================================="
|
||||
```
|
||||
|
||||
**Step 2: 保存文件**
|
||||
|
||||
**Step 3: 提交**
|
||||
|
||||
```bash
|
||||
git add test/test_employee_import_delete.ps1
|
||||
git commit -m "test(employee): 添加导入功能测试脚本"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 1.5:测试员工模块导入功能
|
||||
|
||||
**Step 1: 启动后端服务**
|
||||
|
||||
如果后端服务未启动,先启动:
|
||||
|
||||
```bash
|
||||
mvn spring-boot:run
|
||||
```
|
||||
|
||||
**Step 2: 在新终端运行测试脚本**
|
||||
|
||||
```powershell
|
||||
cd D:\ccdi\ccdi
|
||||
.\test\test_employee_import_delete.ps1
|
||||
```
|
||||
|
||||
**Step 3: 验证结果**
|
||||
|
||||
检查:
|
||||
- ✅ 测试脚本显示 "导入测试成功"
|
||||
- ✅ 日志文件显示响应代码 200
|
||||
- ✅ 数据库中数据正确插入
|
||||
|
||||
**Step 4: 如果测试通过,提交工作**
|
||||
|
||||
```bash
|
||||
# 所有改动已提交,无需额外操作
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 模块 2:中介库个人管理
|
||||
|
||||
### Task 2.1:添加批量删除方法到 Mapper 接口
|
||||
|
||||
- [x] **已完成** (commit: ba8eedc)
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiBizIntermediaryMapper.java`
|
||||
|
||||
**Step 1: 在 Mapper 接口中添加方法声明**
|
||||
|
||||
```java
|
||||
/**
|
||||
* 根据个人证件号批量删除中介库个人数据
|
||||
*
|
||||
* @param personIds 个人证件号列表
|
||||
* @return 删除行数
|
||||
*/
|
||||
int deleteBatchByPersonId(@Param("list") List<String> personIds);
|
||||
```
|
||||
|
||||
**Step 2: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiBizIntermediaryMapper.java
|
||||
git commit -m "feat(intermediary): 添加个人批量删除方法声明"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2.2:在 Mapper XML 中实现批量删除 SQL
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiBizIntermediaryMapper.xml`
|
||||
|
||||
**Step 1: 在 XML 文件中添加删除 SQL**
|
||||
|
||||
```xml
|
||||
<!-- 根据个人证件号批量删除中介库个人数据 -->
|
||||
<delete id="deleteBatchByPersonId">
|
||||
DELETE FROM ccdi_biz_intermediary
|
||||
WHERE person_id IN
|
||||
<foreach collection="list" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</delete>
|
||||
```
|
||||
|
||||
**Step 2: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiBizIntermediaryMapper.xml
|
||||
git commit -m "feat(intermediary): 实现个人批量删除SQL"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 2.3:重构中介库个人导入方法
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiIntermediaryServiceImpl.java`
|
||||
- 目标方法:`importIntermediaryPerson`
|
||||
|
||||
**Step 1: 找到 `importIntermediaryPerson` 方法**
|
||||
|
||||
在 `CcdiIntermediaryServiceImpl.java` 中定位方法。
|
||||
|
||||
**Step 2: 重构方法逻辑**
|
||||
|
||||
参考员工模块的模式,重构为先删后插:
|
||||
|
||||
```java
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String importIntermediaryPerson(List<CcdiIntermediaryPersonExcel> excelList, Boolean isUpdateSupport) {
|
||||
if (StringUtils.isNull(excelList) || excelList.isEmpty()) {
|
||||
return "至少需要一条数据";
|
||||
}
|
||||
|
||||
// 第一阶段:数据验证和收集
|
||||
List<CcdiBizIntermediary> validList = new ArrayList<>();
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
Set<String> personIds = new HashSet<>();
|
||||
|
||||
for (CcdiIntermediaryPersonExcel excel : excelList) {
|
||||
try {
|
||||
// 转换并验证
|
||||
CcdiIntermediaryPersonAddDTO addDTO = new CcdiIntermediaryPersonAddDTO();
|
||||
BeanUtils.copyProperties(excel, addDTO);
|
||||
// 调用验证方法(需要根据实际情况调整)
|
||||
// validateIntermediaryPersonDataBasic(addDTO);
|
||||
|
||||
// 检查导入数据内部是否重复
|
||||
if (!personIds.add(addDTO.getPersonId())) {
|
||||
throw new RuntimeException("导入文件中该个人证件号重复");
|
||||
}
|
||||
|
||||
// 转换为实体,设置审计字段
|
||||
CcdiBizIntermediary entity = new CcdiBizIntermediary();
|
||||
BeanUtils.copyProperties(addDTO, entity);
|
||||
entity.setCreateBy("导入");
|
||||
entity.setUpdateBy("导入");
|
||||
|
||||
validList.add(entity);
|
||||
|
||||
} catch (Exception e) {
|
||||
errorMessages.add(String.format("%s 导入失败:%s",
|
||||
excel.getName(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
// 第二阶段:批量删除已存在的记录
|
||||
if (!validList.isEmpty()) {
|
||||
ccdiBizIntermediaryMapper.deleteBatchByPersonId(new ArrayList<>(personIds));
|
||||
}
|
||||
|
||||
// 第三阶段:批量插入所有数据
|
||||
if (!validList.isEmpty()) {
|
||||
ccdiBizIntermediaryMapper.insertBatch(validList);
|
||||
}
|
||||
|
||||
// 第四阶段:返回结果
|
||||
if (!errorMessages.isEmpty()) {
|
||||
StringBuilder failureMsg = new StringBuilder();
|
||||
failureMsg.append("很抱歉,导入完成!成功 ")
|
||||
.append(validList.size())
|
||||
.append(" 条,失败 ")
|
||||
.append(errorMessages.size())
|
||||
.append(" 条,错误如下:");
|
||||
|
||||
for (int i = 0; i < errorMessages.size(); i++) {
|
||||
failureMsg.append("<br/>")
|
||||
.append(i + 1)
|
||||
.append("、")
|
||||
.append(errorMessages.get(i));
|
||||
}
|
||||
|
||||
throw new RuntimeException(failureMsg.toString());
|
||||
}
|
||||
|
||||
return "恭喜您,数据已全部导入成功!共 " + validList.size() + " 条";
|
||||
}
|
||||
```
|
||||
|
||||
**注意**:需要根据实际的 DTO 类名、验证方法名、Mapper 注入名进行调整。
|
||||
|
||||
**Step 3: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiIntermediaryServiceImpl.java
|
||||
git commit -m "refactor(intermediary): 重构个人导入方法为先删后插模式"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 模块 3:中介库实体管理
|
||||
|
||||
### Task 3.1:添加批量删除方法到 Mapper 接口
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiEnterpriseBaseInfoMapper.java`
|
||||
|
||||
**Step 1: 在 Mapper 接口中添加方法声明**
|
||||
|
||||
```java
|
||||
/**
|
||||
* 根据统一社会信用代码批量删除中介库实体数据
|
||||
*
|
||||
* @param socialCreditCodes 统一社会信用代码列表
|
||||
* @return 删除行数
|
||||
*/
|
||||
int deleteBatchBySocialCreditCode(@Param("list") List<String> socialCreditCodes);
|
||||
```
|
||||
|
||||
**Step 2: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiEnterpriseBaseInfoMapper.java
|
||||
git commit -m "feat(intermediary): 添加实体批量删除方法声明"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3.2:在 Mapper XML 中实现批量删除 SQL
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiEnterpriseBaseInfoMapper.xml`
|
||||
|
||||
**Step 1: 在 XML 文件中添加删除 SQL**
|
||||
|
||||
```xml
|
||||
<!-- 根据统一社会信用代码批量删除中介库实体数据 -->
|
||||
<delete id="deleteBatchBySocialCreditCode">
|
||||
DELETE FROM ccdi_enterprise_base_info
|
||||
WHERE social_credit_code IN
|
||||
<foreach collection="list" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</delete>
|
||||
```
|
||||
|
||||
**Step 2: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiEnterpriseBaseInfoMapper.xml
|
||||
git commit -m "feat(intermediary): 实现实体批量删除SQL"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 3.3:重构中介库实体导入方法
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiIntermediaryServiceImpl.java`
|
||||
- 目标方法:`importIntermediaryEntity`
|
||||
|
||||
**Step 1: 找到 `importIntermediaryEntity` 方法**
|
||||
|
||||
在 `CcdiIntermediaryServiceImpl.java` 中定位方法。
|
||||
|
||||
**Step 2: 重构方法逻辑**
|
||||
|
||||
参考个人模块的模式,重构为先删后插:
|
||||
|
||||
```java
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String importIntermediaryEntity(List<CcdiIntermediaryEntityExcel> excelList, Boolean isUpdateSupport) {
|
||||
if (StringUtils.isNull(excelList) || excelList.isEmpty()) {
|
||||
return "至少需要一条数据";
|
||||
}
|
||||
|
||||
// 第一阶段:数据验证和收集
|
||||
List<CcdiEnterpriseBaseInfo> validList = new ArrayList<>();
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
Set<String> socialCreditCodes = new HashSet<>();
|
||||
|
||||
for (CcdiIntermediaryEntityExcel excel : excelList) {
|
||||
try {
|
||||
// 转换并验证
|
||||
CcdiIntermediaryEntityAddDTO addDTO = new CcdiIntermediaryEntityAddDTO();
|
||||
BeanUtils.copyProperties(excel, addDTO);
|
||||
// 调用验证方法(需要根据实际情况调整)
|
||||
// validateIntermediaryEntityDataBasic(addDTO);
|
||||
|
||||
// 检查导入数据内部是否重复
|
||||
if (!socialCreditCodes.add(addDTO.getSocialCreditCode())) {
|
||||
throw new RuntimeException("导入文件中该统一社会信用代码重复");
|
||||
}
|
||||
|
||||
// 转换为实体,设置审计字段
|
||||
CcdiEnterpriseBaseInfo entity = new CcdiEnterpriseBaseInfo();
|
||||
BeanUtils.copyProperties(addDTO, entity);
|
||||
entity.setCreateBy("导入");
|
||||
entity.setUpdateBy("导入");
|
||||
|
||||
validList.add(entity);
|
||||
|
||||
} catch (Exception e) {
|
||||
errorMessages.add(String.format("%s 导入失败:%s",
|
||||
excel.getEnterpriseName(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
// 第二阶段:批量删除已存在的记录
|
||||
if (!validList.isEmpty()) {
|
||||
ccdiEnterpriseBaseInfoMapper.deleteBatchBySocialCreditCode(new ArrayList<>(socialCreditCodes));
|
||||
}
|
||||
|
||||
// 第三阶段:批量插入所有数据
|
||||
if (!validList.isEmpty()) {
|
||||
ccdiEnterpriseBaseInfoMapper.insertBatch(validList);
|
||||
}
|
||||
|
||||
// 第四阶段:返回结果
|
||||
if (!errorMessages.isEmpty()) {
|
||||
StringBuilder failureMsg = new StringBuilder();
|
||||
failureMsg.append("很抱歉,导入完成!成功 ")
|
||||
.append(validList.size())
|
||||
.append(" 条,失败 ")
|
||||
.append(errorMessages.size())
|
||||
.append(" 条,错误如下:");
|
||||
|
||||
for (int i = 0; i < errorMessages.size(); i++) {
|
||||
failureMsg.append("<br/>")
|
||||
.append(i + 1)
|
||||
.append("、")
|
||||
.append(errorMessages.get(i));
|
||||
}
|
||||
|
||||
throw new RuntimeException(failureMsg.toString());
|
||||
}
|
||||
|
||||
return "恭喜您,数据已全部导入成功!共 " + validList.size() + " 条";
|
||||
}
|
||||
```
|
||||
|
||||
**注意**:需要根据实际的 DTO 类名、验证方法名、Mapper 注入名进行调整。
|
||||
|
||||
**Step 3: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiIntermediaryServiceImpl.java
|
||||
git commit -m "refactor(intermediary): 重构实体导入方法为先删后插模式"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 模块 4:员工招聘信息管理
|
||||
|
||||
### Task 4.1:添加批量删除方法到 Mapper 接口
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiStaffRecruitmentMapper.java`
|
||||
|
||||
**Step 1: 在 Mapper 接口中添加方法声明**
|
||||
|
||||
```java
|
||||
/**
|
||||
* 根据招聘项目编号批量删除招聘信息数据
|
||||
*
|
||||
* @param recruitIds 招聘项目编号列表
|
||||
* @return 删除行数
|
||||
*/
|
||||
int deleteBatchByRecruitId(@Param("list") List<String> recruitIds);
|
||||
```
|
||||
|
||||
**Step 2: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/mapper/CcdiStaffRecruitmentMapper.java
|
||||
git commit -m "feat(recruitment): 添加批量删除方法声明"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4.2:在 Mapper XML 中实现批量删除 SQL
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiStaffRecruitmentMapper.xml`
|
||||
|
||||
**Step 1: 在 XML 文件中添加删除 SQL**
|
||||
|
||||
```xml
|
||||
<!-- 根据招聘项目编号批量删除招聘信息数据 -->
|
||||
<delete id="deleteBatchByRecruitId">
|
||||
DELETE FROM ccdi_staff_recruitment
|
||||
WHERE recruit_id IN
|
||||
<foreach collection="list" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
</delete>
|
||||
```
|
||||
|
||||
**Step 2: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/resources/mapper/ccdi/CcdiStaffRecruitmentMapper.xml
|
||||
git commit -m "feat(recruitment): 实现批量删除SQL"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 4.3:重构招聘信息导入方法
|
||||
|
||||
**文件:**
|
||||
- 修改:`ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiStaffRecruitmentServiceImpl.java`
|
||||
- 目标方法:`importRecruitment`
|
||||
|
||||
**Step 1: 找到 `importRecruitment` 方法**
|
||||
|
||||
在 `CcdiStaffRecruitmentServiceImpl.java` 中定位方法。
|
||||
|
||||
**Step 2: 重构方法逻辑**
|
||||
|
||||
参考员工模块的模式,重构为先删后插:
|
||||
|
||||
```java
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public String importRecruitment(List<CcdiStaffRecruitmentExcel> excelList, Boolean isUpdateSupport) {
|
||||
if (StringUtils.isNull(excelList) || excelList.isEmpty()) {
|
||||
return "至少需要一条数据";
|
||||
}
|
||||
|
||||
// 第一阶段:数据验证和收集
|
||||
List<CcdiStaffRecruitment> validList = new ArrayList<>();
|
||||
List<String> errorMessages = new ArrayList<>();
|
||||
Set<String> recruitIds = new HashSet<>();
|
||||
|
||||
for (CcdiStaffRecruitmentExcel excel : excelList) {
|
||||
try {
|
||||
// 转换并验证
|
||||
CcdiStaffRecruitmentAddDTO addDTO = new CcdiStaffRecruitmentAddDTO();
|
||||
BeanUtils.copyProperties(excel, addDTO);
|
||||
// 调用验证方法(需要根据实际情况调整)
|
||||
// validateRecruitmentDataBasic(addDTO);
|
||||
|
||||
// 检查导入数据内部是否重复
|
||||
if (!recruitIds.add(addDTO.getRecruitId())) {
|
||||
throw new RuntimeException("导入文件中该招聘项目编号重复");
|
||||
}
|
||||
|
||||
// 转换为实体,设置审计字段
|
||||
CcdiStaffRecruitment entity = new CcdiStaffRecruitment();
|
||||
BeanUtils.copyProperties(addDTO, entity);
|
||||
entity.setCreateBy("导入");
|
||||
entity.setUpdateBy("导入");
|
||||
|
||||
validList.add(entity);
|
||||
|
||||
} catch (Exception e) {
|
||||
errorMessages.add(String.format("%s 导入失败:%s",
|
||||
excel.getRecruitName(), e.getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
// 第二阶段:批量删除已存在的记录
|
||||
if (!validList.isEmpty()) {
|
||||
ccdiStaffRecruitmentMapper.deleteBatchByRecruitId(new ArrayList<>(recruitIds));
|
||||
}
|
||||
|
||||
// 第三阶段:批量插入所有数据
|
||||
if (!validList.isEmpty()) {
|
||||
ccdiStaffRecruitmentMapper.insertBatch(validList);
|
||||
}
|
||||
|
||||
// 第四阶段:返回结果
|
||||
if (!errorMessages.isEmpty()) {
|
||||
StringBuilder failureMsg = new StringBuilder();
|
||||
failureMsg.append("很抱歉,导入完成!成功 ")
|
||||
.append(validList.size())
|
||||
.append(" 条,失败 ")
|
||||
.append(errorMessages.size())
|
||||
.append(" 条,错误如下:");
|
||||
|
||||
for (int i = 0; i < errorMessages.size(); i++) {
|
||||
failureMsg.append("<br/>")
|
||||
.append(i + 1)
|
||||
.append("、")
|
||||
.append(errorMessages.get(i));
|
||||
}
|
||||
|
||||
throw new RuntimeException(failureMsg.toString());
|
||||
}
|
||||
|
||||
return "恭喜您,数据已全部导入成功!共 " + validList.size() + " 条";
|
||||
}
|
||||
```
|
||||
|
||||
**注意**:需要根据实际的 DTO 类名、验证方法名、Mapper 注入名进行调整。
|
||||
|
||||
**Step 3: 提交**
|
||||
|
||||
```bash
|
||||
git add ruoyi-ccdi/src/main/java/com/ruoyi/ccdi/service/impl/CcdiStaffRecruitmentServiceImpl.java
|
||||
git commit -m "refactor(recruitment): 重构导入方法为先删后插模式"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 模块 5:清理和文档
|
||||
|
||||
### Task 5.1:移除不再使用的批量更新方法(如果存在)
|
||||
|
||||
**文件:**
|
||||
- 检查:各模块的 Mapper XML 和 Mapper 接口
|
||||
|
||||
**Step 1: 检查是否存在 updateBatch 方法**
|
||||
|
||||
在以下文件中搜索 `updateBatch`:
|
||||
- `CcdiEmployeeMapper.xml`
|
||||
- `CcdiBizIntermediaryMapper.xml`
|
||||
- `CcdiEnterpriseBaseInfoMapper.xml`
|
||||
- `CcdiStaffRecruitmentMapper.xml`
|
||||
|
||||
**Step 2: 如果存在,删除 updateBatch 方法**
|
||||
|
||||
删除不再使用的批量更新 SQL 和接口声明。
|
||||
|
||||
**Step 3: 提交**
|
||||
|
||||
```bash
|
||||
git commit -am "refactor: 移除不再使用的批量更新方法"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Task 5.2:更新 API 文档
|
||||
|
||||
**文件:**
|
||||
- 修改:`doc/api/ccdi_staff_recruitment_api.md`(如果存在)
|
||||
|
||||
**Step 1: 更新导入接口文档**
|
||||
|
||||
在 API 文档中说明新的导入逻辑:
|
||||
- 采用"先删除后插入"策略
|
||||
- `isUpdateSupport` 参数保留以保持兼容性,但不再使用
|
||||
- 所有审计字段(create_time, update_time 等)会被重置为当前时间
|
||||
|
||||
**Step 2: 提交**
|
||||
|
||||
```bash
|
||||
git add doc/api/
|
||||
git commit -m "docs: 更新导入接口文档说明"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 完成检查清单
|
||||
|
||||
在完成所有任务后,确认以下事项:
|
||||
|
||||
- [ ] 员工信息模块测试通过
|
||||
- [ ] 中介库个人模块功能正常
|
||||
- [ ] 中介库实体模块功能正常
|
||||
- [ ] 招聘信息模块功能正常
|
||||
- [ ] 所有代码已提交(不少于 11 个 commits)
|
||||
- [ ] API 文档已更新
|
||||
- [ ] 设计文档已归档到 `doc/plans/`
|
||||
|
||||
---
|
||||
|
||||
## 测试指南
|
||||
|
||||
### 完整功能测试
|
||||
|
||||
1. **启动后端服务**
|
||||
|
||||
```bash
|
||||
mvn spring-boot:run
|
||||
```
|
||||
|
||||
2. **测试各模块导入功能**
|
||||
|
||||
为每个模块运行相应的测试(参考员工模块测试脚本)。
|
||||
|
||||
3. **验证数据库**
|
||||
|
||||
检查导入的数据是否正确,旧数据是否被删除。
|
||||
|
||||
### 性能测试
|
||||
|
||||
测试不同数据量的导入性能:
|
||||
- 小数据量:10 条
|
||||
- 中数据量:100 条
|
||||
- 大数据量:1000 条
|
||||
|
||||
---
|
||||
|
||||
**实施计划完成**
|
||||
Reference in New Issue
Block a user