# 导入逻辑优化实施计划

> **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-info-collection/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-info-collection/src/main/java/com/ruoyi/ccdi/mapper/CcdiEmployeeMapper.java
git commit -m "feat(employee): 添加批量删除方法声明"
```

---

### Task 1.2：在 Mapper XML 中实现批量删除 SQL

**文件：**

- 修改：`ruoyi-info-collection/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-info-collection/src/main/resources/mapper/ccdi/CcdiEmployeeMapper.xml
git commit -m "feat(employee): 实现批量删除SQL"
```

---

### Task 1.3：重构员工导入方法（先删后插逻辑）

- [x] **已完成** (commit: ebe4fd7)

**文件：**

- 修改：`ruoyi-info-collection/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-info-collection/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-info-collection/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-info-collection/src/main/java/com/ruoyi/ccdi/mapper/CcdiBizIntermediaryMapper.java
git commit -m "feat(intermediary): 添加个人批量删除方法声明"
```

---

### Task 2.2：在 Mapper XML 中实现批量删除 SQL

**文件：**

- 修改：`ruoyi-info-collection/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-info-collection/src/main/resources/mapper/ccdi/CcdiBizIntermediaryMapper.xml
git commit -m "feat(intermediary): 实现个人批量删除SQL"
```

---

### Task 2.3：重构中介库个人导入方法

**文件：**

- 修改：`ruoyi-info-collection/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-info-collection/src/main/java/com/ruoyi/ccdi/service/impl/CcdiIntermediaryServiceImpl.java
git commit -m "refactor(intermediary): 重构个人导入方法为先删后插模式"
```

---

## 模块 3：中介库实体管理

### Task 3.1：添加批量删除方法到 Mapper 接口

**文件：**

- 修改：`ruoyi-info-collection/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-info-collection/src/main/java/com/ruoyi/ccdi/mapper/CcdiEnterpriseBaseInfoMapper.java
git commit -m "feat(intermediary): 添加实体批量删除方法声明"
```

---

### Task 3.2：在 Mapper XML 中实现批量删除 SQL

**文件：**

- 修改：`ruoyi-info-collection/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-info-collection/src/main/resources/mapper/ccdi/CcdiEnterpriseBaseInfoMapper.xml
git commit -m "feat(intermediary): 实现实体批量删除SQL"
```

---

### Task 3.3：重构中介库实体导入方法

**文件：**

- 修改：`ruoyi-info-collection/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-info-collection/src/main/java/com/ruoyi/ccdi/service/impl/CcdiIntermediaryServiceImpl.java
git commit -m "refactor(intermediary): 重构实体导入方法为先删后插模式"
```

---

## 模块 4：员工招聘信息管理

### Task 4.1：添加批量删除方法到 Mapper 接口

**文件：**

- 修改：`ruoyi-info-collection/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-info-collection/src/main/java/com/ruoyi/ccdi/mapper/CcdiStaffRecruitmentMapper.java
git commit -m "feat(recruitment): 添加批量删除方法声明"
```

---

### Task 4.2：在 Mapper XML 中实现批量删除 SQL

**文件：**

- 修改：`ruoyi-info-collection/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-info-collection/src/main/resources/mapper/ccdi/CcdiStaffRecruitmentMapper.xml
git commit -m "feat(recruitment): 实现批量删除SQL"
```

---

### Task 4.3：重构招聘信息导入方法

**文件：**

- 修改：`ruoyi-info-collection/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-info-collection/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 条

---

**实施计划完成**
