Files
ccdi/doc/requirements/plans/2026-02-09-remove-import-update-support-design.md
2026-02-09 14:28:25 +08:00

14 KiB

移除招聘信和采购交易导入更新支持功能设计文档

日期: 2026-02-09 模块: 招聘信息管理、采购交易管理 类型: 功能简化

1. 需求概述

1.1 背景

当前招聘信息和采购交易信息模块的导入功能支持"导入更新"模式,允许用户通过导入文件来更新已存在的数据。但实际业务场景中,这两个模块不应该支持导入更新操作。

1.2 目标

  • 完全移除招聘信和采购交易的导入更新功能
  • 简化代码逻辑,降低维护成本
  • 导入时遇到已存在的数据直接报错,避免意外覆盖

1.3 处理策略

  • 遇到已存在数据: 跳过该条数据,记录到失败列表
  • 错误提示: 显示具体重复的数据ID(招聘项目编号/采购事项ID)
  • 其他数据: 继续正常导入

2. 技术方案

2.1 后端修改

2.1.1 招聘信模块

Controller层: CcdiStaffRecruitmentController.java

// 修改前
@PostMapping("/import")
public AjaxResult importRecruitment(@RequestParam("file") MultipartFile file,
                                     @RequestParam Boolean isUpdateSupport) throws Exception {
    // ...
    importService.importRecruitmentAsync(excelList, isUpdateSupport, taskId, username);
    // ...
}

// 修改后
@PostMapping("/import")
public AjaxResult importRecruitment(@RequestParam("file") MultipartFile file) throws Exception {
    // ...
    importService.importRecruitmentAsync(excelList, taskId, username);
    // ...
}

Service接口: ICcdiStaffRecruitmentImportService.java

// 修改前
void importRecruitmentAsync(List<CcdiStaffRecruitmentExcel> excelList,
                            Boolean isUpdateSupport,
                            String taskId,
                            String userName);

// 修改后
void importRecruitmentAsync(List<CcdiStaffRecruitmentExcel> excelList,
                            String taskId,
                            String userName);

Service实现: CcdiStaffRecruitmentImportServiceImpl.java

主要修改点:

  1. 移除方法参数 Boolean isUpdateSupport
  2. 移除 List<CcdiStaffRecruitment> updateRecords 变量
  3. 简化数据分类逻辑(第73-92行)
  4. 移除批量更新逻辑(第107-110行)
  5. 修改错误提示信息
// 修改后的数据分类逻辑
for (CcdiStaffRecruitmentExcel excel : excelList) {
    try {
        // 验证数据(不再需要isUpdateSupport参数)
        validateRecruitmentData(excel, existingRecruitIds);

        CcdiStaffRecruitment recruitment = new CcdiStaffRecruitment();
        BeanUtils.copyProperties(excel, recruitment);

        if (existingRecruitIds.contains(excel.getRecruitId())) {
            // 直接抛出异常,记录为失败
            throw new RuntimeException(
                String.format("招聘项目编号[%s]已存在,请勿重复导入", excel.getRecruitId())
            );
        } else {
            recruitment.setCreatedBy(userName);
            recruitment.setUpdatedBy(userName);
            newRecords.add(recruitment);
        }
    } catch (Exception e) {
        RecruitmentImportFailureVO failure = new RecruitmentImportFailureVO();
        BeanUtils.copyProperties(excel, failure);
        failure.setErrorMessage(e.getMessage());
        failures.add(failure);
    }
}

// 移除批量更新代码
// 删除以下代码:
// if (!updateRecords.isEmpty() && isUpdateSupport) {
//     recruitmentMapper.updateBatch(updateRecords);
// }

验证方法简化:

// 修改前
private void validateRecruitmentData(CcdiStaffRecruitmentExcel excel,
                                    Boolean isUpdateSupport,
                                    Set<String> existingRecruitIds)

// 修改后
private void validateRecruitmentData(CcdiStaffRecruitmentExcel excel,
                                    Set<String> existingRecruitIds)

2.1.2 采购交易模块

Controller层: CcdiPurchaseTransactionController.java

// 修改前
@PostMapping("/import")
public AjaxResult importTransaction(@RequestParam("file") MultipartFile file,
                                     @RequestParam Boolean isUpdateSupport) throws Exception {
    // ...
    importService.importTransactionAsync(excelList, isUpdateSupport, taskId, username);
    // ...
}

// 修改后
@PostMapping("/import")
public AjaxResult importTransaction(@RequestParam("file") MultipartFile file) throws Exception {
    // ...
    importService.importTransactionAsync(excelList, taskId, username);
    // ...
}

Service接口: ICcdiPurchaseTransactionImportService.java

// 修改前
void importTransactionAsync(List<CcdiPurchaseTransactionExcel> excelList,
                            Boolean isUpdateSupport,
                            String taskId,
                            String userName);

// 修改后
void importTransactionAsync(List<CcdiPurchaseTransactionExcel> excelList,
                            String taskId,
                            String userName);

Service实现: CcdiPurchaseTransactionImportServiceImpl.java

主要修改点:

  1. 移除方法参数 Boolean isUpdateSupport
  2. 移除 List<CcdiPurchaseTransaction> updateRecords 变量
  3. 简化数据分类逻辑(第54-88行)
  4. 移除批量更新逻辑(第95-98行)
  5. 修改错误提示信息
// 修改后的数据分类逻辑
for (int i = 0; i < excelList.size(); i++) {
    CcdiPurchaseTransactionExcel excel = excelList.get(i);

    try {
        // 转换为AddDTO进行验证
        CcdiPurchaseTransactionAddDTO addDTO = new CcdiPurchaseTransactionAddDTO();
        BeanUtils.copyProperties(excel, addDTO);

        // 验证数据(不再需要isUpdateSupport参数)
        validateTransactionData(addDTO, existingIds);

        CcdiPurchaseTransaction transaction = new CcdiPurchaseTransaction();
        BeanUtils.copyProperties(excel, transaction);

        if (existingIds.contains(excel.getPurchaseId())) {
            // 直接抛出异常,记录为失败
            throw new RuntimeException(
                String.format("采购事项ID[%s]已存在,请勿重复导入", excel.getPurchaseId())
            );
        } else {
            transaction.setCreatedBy(userName);
            transaction.setUpdatedBy(userName);
            newRecords.add(transaction);
        }
    } catch (Exception e) {
        PurchaseTransactionImportFailureVO failure = new PurchaseTransactionImportFailureVO();
        BeanUtils.copyProperties(excel, failure);
        failure.setErrorMessage(e.getMessage());
        failures.add(failure);
    }
}

// 移除批量更新代码
// 删除以下代码:
// if (!updateRecords.isEmpty() && isUpdateSupport) {
//     transactionMapper.insertOrUpdateBatch(updateRecords);
// }

验证方法简化:

// 修改前
private void validateTransactionData(CcdiPurchaseTransactionAddDTO addDTO,
                                    Boolean isUpdateSupport,
                                    Set<String> existingIds)

// 修改后
private void validateTransactionData(CcdiPurchaseTransactionAddDTO addDTO,
                                    Set<String> existingIds)

2.2 前端修改

2.2.1 招聘信模块

文件: ruoyi-ui/src/views/ccdiStaffRecruitment/index.vue

修改1: 移除 upload 对象中的 updateSupport 字段

// 修改前 (约第461行)
upload: {
  // 是否显示弹出层
  open: false,
  // 弹出层标题
  title: "",
  // 是否禁用上传
  isUploading: false,
  // 是否更新已经存在的招聘信息数据
  updateSupport: 0,
  // 设置上传的请求头部
  headers: { Authorization: "Bearer " + getToken() },
  // 上传的地址
  url: process.env.VUE_APP_BASE_API + "/ccdi/staffRecruitment/import"
}

// 修改后
upload: {
  // 是否显示弹出层
  open: false,
  // 弹出层标题
  title: "",
  // 是否禁用上传
  isUploading: false,
  // 设置上传的请求头部
  headers: { Authorization: "Bearer " + getToken() },
  // 上传的地址
  url: process.env.VUE_APP_BASE_API + "/ccdi/staffRecruitment/import"
}

修改2: 移除导入对话框中的"是否更新"复选框 (约第327行)

<!-- 删除此行 -->
<el-checkbox v-model="upload.updateSupport" />是否更新已经存在的招聘信息数据

修改3: 移除URL中的updateSupport参数 (约第317行)

<!-- 修改前 -->
<el-upload
  :action="upload.url + '?updateSupport=' + upload.updateSupport"
  ...
>
</el-upload>

<!-- 修改后 -->
<el-upload
  :action="upload.url"
  ...
>
</el-upload>

2.2.2 采购交易模块

文件: ruoyi-ui/src/views/ccdiPurchaseTransaction/index.vue

修改1: 移除 upload 对象中的 updateSupport 字段

// 修改前 (约第719行)
upload: {
  // 是否显示弹出层
  open: false,
  // 弹出层标题
  title: "",
  // 是否禁用上传
  isUploading: false,
  // 是否更新已经存在的采购交易数据
  updateSupport: 0,
  // 设置上传的请求头部
  headers: { Authorization: "Bearer " + getToken() },
  // 上传的地址
  url: process.env.VUE_APP_BASE_API + "/ccdi/purchaseTransaction/import"
}

// 修改后
upload: {
  // 是否显示弹出层
  open: false,
  // 弹出层标题
  title: "",
  // 是否禁用上传
  isUploading: false,
  // 设置上传的请求头部
  headers: { Authorization: "Bearer " + getToken() },
  // 上传的地址
  url: process.env.VUE_APP_BASE_API + "/ccdi/purchaseTransaction/import"
}

修改2: 移除导入对话框中的"是否更新"复选框 (约第513行)

<!-- 删除此行 -->
<el-checkbox v-model="upload.updateSupport" />是否更新已经存在的采购交易数据

修改3: 移除URL中的updateSupport参数 (约第503行)

<!-- 修改前 -->
<el-upload
  :action="upload.url + '?updateSupport=' + upload.updateSupport"
  ...
>
</el-upload>

<!-- 修改后 -->
<el-upload
  :action="upload.url"
  ...
>
</el-upload>

3. 数据流变化

3.1 修改前

用户上传文件
  → 前端传递 isUpdateSupport 参数
    → 后端检查数据是否存在
      → 存在且 isUpdateSupport=true: 更新数据
      → 存在且 isUpdateSupport=false: 报错
      → 不存在: 新增数据

3.2 修改后

用户上传文件
  → 后端检查数据是否存在
    → 存在: 报错(显示重复ID),记录为失败
    → 不存在: 新增数据

4. 代码变更统计

4.1 后端变更

模块 文件 变更类型 变更行数(预估)
招聘信 CcdiStaffRecruitmentController.java 修改 ~5行
招聘信 ICcdiStaffRecruitmentImportService.java 修改 ~3行
招聘信 CcdiStaffRecruitmentImportServiceImpl.java 修改/删除 ~30行
采购交易 CcdiPurchaseTransactionController.java 修改 ~5行
采购交易 ICcdiPurchaseTransactionImportService.java 修改 ~3行
采购交易 CcdiPurchaseTransactionImportServiceImpl.java 修改/删除 ~30行

总计: 约76行

4.2 前端变更

模块 文件 变更类型 变更行数(预估)
招聘信 index.vue 修改/删除 ~10行
采购交易 index.vue 修改/删除 ~10行

总计: 约20行

5. 测试计划

5.1 功能测试

测试场景1: 导入全新数据

  • 输入: 导入文件中的所有数据都不存在于数据库
  • 预期: 全部导入成功,成功数=总数

测试场景2: 导入部分重复数据

  • 输入: 导入文件中包含部分已存在的招聘项目编号/采购事项ID
  • 预期:
    • 已存在的数据记录为失败
    • 失败信息显示具体的重复ID
    • 其他数据正常导入

测试场景3: 导入全部重复数据

  • 输入: 导入文件中的所有数据都已存在
  • 预期: 全部导入失败,失败数=总数

测试场景4: 前端UI验证

  • 检查导入对话框中不再显示"是否更新"复选框
  • 检查上传请求URL中不包含updateSupport参数

5.2 接口测试

使用测试脚本验证后端接口:

  1. 不传递isUpdateSupport参数,接口应正常工作
  2. 验证重复数据的错误提示信息格式

6. 风险评估

6.1 兼容性风险

  • 风险: 旧版前端可能会传递isUpdateSupport参数
  • 影响: 后端接口会报参数错误
  • 缓解: 确保前后端同时部署,或后端暂时兼容接收该参数但不处理

6.2 用户体验风险

  • 风险: 用户习惯使用"导入更新"功能
  • 影响: 需要先删除旧数据再导入新数据
  • 缓解: 在失败提示中明确告知数据ID,方便用户删除

6.3 数据一致性风险

  • 风险: 低风险,因为只是移除更新功能
  • 影响:
  • 缓解: 无需特殊处理

7. 部署建议

7.1 部署顺序

  1. 先部署后端代码
  2. 再部署前端代码
  3. 前后端必须同时上线,避免调用失败

7.2 数据库变更

  • 无需数据库变更

7.3 配置变更

  • 无需配置变更

8. 回滚方案

如果需要回滚,可以:

  1. 恢复后端代码,恢复isUpdateSupport参数处理逻辑
  2. 恢复前端代码,恢复"是否更新"复选框

9. 附录

9.1 相关文档

  • 招聘信息导入功能设计: doc/plans/2026-02-06-recruitment-async-import-design.md
  • 采购交易导入功能设计: doc/plans/2026-02-08-purchase-transaction-import-design.md

9.2 相关API文档

  • 招聘信息API: doc/api/ccdi_staff_recruitment_api.md
  • 采购交易API: doc/api/ccdi_purchase_transaction_api.md

审批记录

角色 姓名 日期 状态
开发 - 2026-02-09 待审批
审批 - - 待审批