feat: 移除招聘信和采购交易的导入更新支持功能

## 变更内容
- 移除招聘信和采购交易导入功能中的isUpdateSupport参数
- 遇到已存在的数据直接报错,不再支持更新操作
- 前端移除"是否更新"复选框

## 后端修改
- CcdiStaffRecruitmentController: 移除updateSupport参数
- ICcdiStaffRecruitmentService: 移除updateSupport参数
- CcdiStaffRecruitmentServiceImpl: 简化导入逻辑,移除更新支持
- CcdiPurchaseTransactionController: 移除updateSupport参数
- ICcdiPurchaseTransactionService: 移除updateSupport参数
- ICcdiPurchaseTransactionImportService: 移除updateSupport参数
- CcdiPurchaseTransactionServiceImpl: 移除updateSupport参数
- CcdiPurchaseTransactionImportServiceImpl: 简化导入逻辑,移除更新支持

## 前端修改
- ccdiStaffRecruitment/index.vue: 移除"是否更新"复选框和相关参数
- ccdiPurchaseTransaction/index.vue: 移除"是否更新"复选框和相关参数

## 影响范围
- 导入时遇到已存在的招聘项目编号或采购事项ID将直接报错
- 错误提示显示具体的重复ID
- 不再支持通过导入文件更新已存在的数据
This commit is contained in:
wkc
2026-02-09 01:12:22 +08:00
parent 26a225298a
commit f96d10d2e8
10 changed files with 33 additions and 79 deletions

View File

@@ -134,12 +134,10 @@ public class CcdiPurchaseTransactionController extends BaseController {
*/ */
@Operation(summary = "异步导入采购交易") @Operation(summary = "异步导入采购交易")
@Parameter(name = "file", description = "导入文件", required = true) @Parameter(name = "file", description = "导入文件", required = true)
@Parameter(name = "updateSupport", description = "是否更新支持true-存在则更新false-存在则跳过", required = true)
@PreAuthorize("@ss.hasPermi('ccdi:purchaseTransaction:import')") @PreAuthorize("@ss.hasPermi('ccdi:purchaseTransaction:import')")
@Log(title = "采购交易信息", businessType = BusinessType.IMPORT) @Log(title = "采购交易信息", businessType = BusinessType.IMPORT)
@PostMapping("/importData") @PostMapping("/importData")
public AjaxResult importData(@Parameter(description = "导入文件") MultipartFile file, public AjaxResult importData(@Parameter(description = "导入文件") MultipartFile file) throws Exception {
@Parameter(description = "是否更新支持") boolean updateSupport) throws Exception {
List<CcdiPurchaseTransactionExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), CcdiPurchaseTransactionExcel.class); List<CcdiPurchaseTransactionExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), CcdiPurchaseTransactionExcel.class);
if (list == null || list.isEmpty()) { if (list == null || list.isEmpty()) {
@@ -147,7 +145,7 @@ public class CcdiPurchaseTransactionController extends BaseController {
} }
// 提交异步任务 // 提交异步任务
String taskId = transactionService.importTransaction(list, updateSupport); String taskId = transactionService.importTransaction(list);
// 立即返回,不等待后台任务完成 // 立即返回,不等待后台任务完成
ImportResultVO result = new ImportResultVO(); ImportResultVO result = new ImportResultVO();

View File

@@ -126,9 +126,9 @@ public class CcdiStaffRecruitmentController extends BaseController {
@PreAuthorize("@ss.hasPermi('ccdi:staffRecruitment:import')") @PreAuthorize("@ss.hasPermi('ccdi:staffRecruitment:import')")
@Log(title = "员工招聘信息", businessType = BusinessType.IMPORT) @Log(title = "员工招聘信息", businessType = BusinessType.IMPORT)
@PostMapping("/importData") @PostMapping("/importData")
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception { public AjaxResult importData(MultipartFile file) throws Exception {
List<CcdiStaffRecruitmentExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), CcdiStaffRecruitmentExcel.class); List<CcdiStaffRecruitmentExcel> list = EasyExcelUtil.importExcel(file.getInputStream(), CcdiStaffRecruitmentExcel.class);
String message = recruitmentService.importRecruitment(list, updateSupport); String message = recruitmentService.importRecruitment(list);
return success(message); return success(message);
} }
} }

View File

@@ -18,11 +18,10 @@ public interface ICcdiPurchaseTransactionImportService {
* 异步导入采购交易数据 * 异步导入采购交易数据
* *
* @param excelList Excel数据列表 * @param excelList Excel数据列表
* @param isUpdateSupport 是否更新已存在的数据
* @param taskId 任务ID * @param taskId 任务ID
* @param userName 当前用户名 * @param userName 当前用户名
*/ */
void importTransactionAsync(List<CcdiPurchaseTransactionExcel> excelList, Boolean isUpdateSupport, String taskId, String userName); void importTransactionAsync(List<CcdiPurchaseTransactionExcel> excelList, String taskId, String userName);
/** /**
* 查询导入状态 * 查询导入状态

View File

@@ -78,8 +78,7 @@ public interface ICcdiPurchaseTransactionService {
* 导入采购交易数据(异步) * 导入采购交易数据(异步)
* *
* @param excelList Excel实体列表 * @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持
* @return 任务ID * @return 任务ID
*/ */
String importTransaction(List<CcdiPurchaseTransactionExcel> excelList, Boolean isUpdateSupport); String importTransaction(List<CcdiPurchaseTransactionExcel> excelList);
} }

View File

@@ -78,8 +78,7 @@ public interface ICcdiStaffRecruitmentService {
* 导入招聘信息数据 * 导入招聘信息数据
* *
* @param excelList Excel实体列表 * @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持
* @return 结果 * @return 结果
*/ */
String importRecruitment(List<CcdiStaffRecruitmentExcel> excelList, Boolean isUpdateSupport); String importRecruitment(List<CcdiStaffRecruitmentExcel> excelList);
} }

View File

@@ -43,9 +43,8 @@ public class CcdiPurchaseTransactionImportServiceImpl implements ICcdiPurchaseTr
@Override @Override
@Async @Async
@Transactional @Transactional
public void importTransactionAsync(List<CcdiPurchaseTransactionExcel> excelList, Boolean isUpdateSupport, String taskId, String userName) { public void importTransactionAsync(List<CcdiPurchaseTransactionExcel> excelList, String taskId, String userName) {
List<CcdiPurchaseTransaction> newRecords = new ArrayList<>(); List<CcdiPurchaseTransaction> newRecords = new ArrayList<>();
List<CcdiPurchaseTransaction> updateRecords = new ArrayList<>();
List<PurchaseTransactionImportFailureVO> failures = new ArrayList<>(); List<PurchaseTransactionImportFailureVO> failures = new ArrayList<>();
// 批量查询已存在的采购事项ID // 批量查询已存在的采购事项ID
@@ -60,19 +59,15 @@ public class CcdiPurchaseTransactionImportServiceImpl implements ICcdiPurchaseTr
CcdiPurchaseTransactionAddDTO addDTO = new CcdiPurchaseTransactionAddDTO(); CcdiPurchaseTransactionAddDTO addDTO = new CcdiPurchaseTransactionAddDTO();
BeanUtils.copyProperties(excel, addDTO); BeanUtils.copyProperties(excel, addDTO);
// 验证数据(支持更新模式) // 验证数据
validateTransactionData(addDTO, isUpdateSupport, existingIds); validateTransactionData(addDTO, existingIds);
CcdiPurchaseTransaction transaction = new CcdiPurchaseTransaction(); CcdiPurchaseTransaction transaction = new CcdiPurchaseTransaction();
BeanUtils.copyProperties(excel, transaction); BeanUtils.copyProperties(excel, transaction);
if (existingIds.contains(excel.getPurchaseId())) { if (existingIds.contains(excel.getPurchaseId())) {
if (isUpdateSupport) { // 采购事项ID已存在直接报错
transaction.setUpdatedBy(userName); throw new RuntimeException(String.format("采购事项ID[%s]已存在,请勿重复导入", excel.getPurchaseId()));
updateRecords.add(transaction);
} else {
throw new RuntimeException("采购事项ID已存在且未启用更新支持");
}
} else { } else {
transaction.setCreatedBy(userName); transaction.setCreatedBy(userName);
transaction.setUpdatedBy(userName); transaction.setUpdatedBy(userName);
@@ -92,11 +87,6 @@ public class CcdiPurchaseTransactionImportServiceImpl implements ICcdiPurchaseTr
saveBatch(newRecords, 500); saveBatch(newRecords, 500);
} }
// 批量更新已有数据(先删除再插入)
if (!updateRecords.isEmpty() && isUpdateSupport) {
transactionMapper.insertOrUpdateBatch(updateRecords);
}
// 保存失败记录到Redis // 保存失败记录到Redis
if (!failures.isEmpty()) { if (!failures.isEmpty()) {
String failuresKey = "import:purchaseTransaction:" + taskId + ":failures"; String failuresKey = "import:purchaseTransaction:" + taskId + ":failures";
@@ -105,7 +95,7 @@ public class CcdiPurchaseTransactionImportServiceImpl implements ICcdiPurchaseTr
ImportResult result = new ImportResult(); ImportResult result = new ImportResult();
result.setTotalCount(excelList.size()); result.setTotalCount(excelList.size());
result.setSuccessCount(newRecords.size() + updateRecords.size()); result.setSuccessCount(newRecords.size());
result.setFailureCount(failures.size()); result.setFailureCount(failures.size());
// 更新最终状态 // 更新最终状态
@@ -218,10 +208,9 @@ public class CcdiPurchaseTransactionImportServiceImpl implements ICcdiPurchaseTr
* 验证采购交易数据 * 验证采购交易数据
* *
* @param addDTO 新增DTO * @param addDTO 新增DTO
* @param isUpdateSupport 是否支持更新
* @param existingIds 已存在的采购事项ID集合 * @param existingIds 已存在的采购事项ID集合
*/ */
private void validateTransactionData(CcdiPurchaseTransactionAddDTO addDTO, Boolean isUpdateSupport, Set<String> existingIds) { private void validateTransactionData(CcdiPurchaseTransactionAddDTO addDTO, Set<String> existingIds) {
// 验证必填字段 // 验证必填字段
if (StringUtils.isEmpty(addDTO.getPurchaseId())) { if (StringUtils.isEmpty(addDTO.getPurchaseId())) {
throw new RuntimeException("采购事项ID不能为空"); throw new RuntimeException("采购事项ID不能为空");

View File

@@ -149,12 +149,11 @@ public class CcdiPurchaseTransactionServiceImpl implements ICcdiPurchaseTransact
* 导入采购交易数据(异步) * 导入采购交易数据(异步)
* *
* @param excelList Excel实体列表 * @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持true-存在则更新false-存在则跳过
* @return 任务ID * @return 任务ID
*/ */
@Override @Override
@Transactional @Transactional
public String importTransaction(java.util.List<CcdiPurchaseTransactionExcel> excelList, Boolean isUpdateSupport) { public String importTransaction(java.util.List<CcdiPurchaseTransactionExcel> excelList) {
if (StringUtils.isNull(excelList) || excelList.isEmpty()) { if (StringUtils.isNull(excelList) || excelList.isEmpty()) {
throw new RuntimeException("至少需要一条数据"); throw new RuntimeException("至少需要一条数据");
} }
@@ -182,7 +181,7 @@ public class CcdiPurchaseTransactionServiceImpl implements ICcdiPurchaseTransact
redisTemplate.expire(statusKey, 7, TimeUnit.DAYS); redisTemplate.expire(statusKey, 7, TimeUnit.DAYS);
// 调用异步导入服务 // 调用异步导入服务
transactionImportService.importTransactionAsync(excelList, isUpdateSupport, taskId, userName); transactionImportService.importTransactionAsync(excelList, taskId, userName);
return taskId; return taskId;
} }

View File

@@ -154,12 +154,11 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
* 导入招聘信息数据(批量优化版本) * 导入招聘信息数据(批量优化版本)
* *
* @param excelList Excel实体列表 * @param excelList Excel实体列表
* @param isUpdateSupport 是否更新支持true-存在则更新false-存在则跳过
* @return 结果 * @return 结果
*/ */
@Override @Override
@Transactional @Transactional
public String importRecruitment(List<CcdiStaffRecruitmentExcel> excelList, Boolean isUpdateSupport) { public String importRecruitment(List<CcdiStaffRecruitmentExcel> excelList) {
if (StringUtils.isNull(excelList) || excelList.isEmpty()) { if (StringUtils.isNull(excelList) || excelList.isEmpty()) {
return "至少需要一条数据"; return "至少需要一条数据";
} }
@@ -171,7 +170,6 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
// 第一阶段:数据验证和分类 // 第一阶段:数据验证和分类
List<CcdiStaffRecruitment> toInsertList = new ArrayList<>(); List<CcdiStaffRecruitment> toInsertList = new ArrayList<>();
List<CcdiStaffRecruitment> toUpdateList = new ArrayList<>();
// 批量收集所有招聘项目编号 // 批量收集所有招聘项目编号
List<String> recruitIds = new ArrayList<>(); List<String> recruitIds = new ArrayList<>();
@@ -205,17 +203,10 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
// 检查是否已存在 // 检查是否已存在
CcdiStaffRecruitment existingRecruitment = existingRecruitmentMap.get(excel.getRecruitId()); CcdiStaffRecruitment existingRecruitment = existingRecruitmentMap.get(excel.getRecruitId());
// 判断数据状态和操作类型 // 判断数据状态
if (existingRecruitment != null) { if (existingRecruitment != null) {
// 招聘项目编号已存在 // 招聘项目编号已存在,直接报错
if (isUpdateSupport) { throw new RuntimeException(String.format("招聘项目编号[%s]已存在,请勿重复导入", excel.getRecruitId()));
// 支持更新,添加到更新列表
recruitment.setUpdatedBy("导入");
toUpdateList.add(recruitment);
} else {
// 不支持更新,跳过或报错
throw new RuntimeException("该招聘项目编号已存在");
}
} else { } else {
// 招聘项目编号不存在,新增数据 // 招聘项目编号不存在,新增数据
recruitment.setCreatedBy("导入"); recruitment.setCreatedBy("导入");
@@ -236,27 +227,13 @@ public class CcdiStaffRecruitmentServiceImpl implements ICcdiStaffRecruitmentSer
successNum += toInsertList.size(); successNum += toInsertList.size();
} }
if (!toUpdateList.isEmpty()) {
// 使用自定义批量更新方法
recruitmentMapper.updateBatch(toUpdateList);
successNum += toUpdateList.size();
}
// 第四阶段:返回结果(只返回错误信息) // 第四阶段:返回结果(只返回错误信息)
if (failureNum > 0) { if (failureNum > 0) {
failureMsg.insert(0, "很抱歉,导入完成!成功 " + successNum + " 条,失败 " + failureNum + " 条,错误如下:"); failureMsg.insert(0, "很抱歉,导入完成!成功 " + successNum + " 条,失败 " + failureNum + " 条,错误如下:");
throw new RuntimeException(failureMsg.toString()); throw new RuntimeException(failureMsg.toString());
} else { } else {
successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据类型:"); successMsg.insert(0, "恭喜您,数据已全部导入成功!共 " + successNum + " 条,数据类型:新增 ");
if (!toInsertList.isEmpty()) { successMsg.append(toInsertList.size()).append("");
successMsg.append("新增 ").append(toInsertList.size()).append("");
}
if (!toUpdateList.isEmpty()) {
if (!toInsertList.isEmpty()) {
successMsg.append("");
}
successMsg.append("更新 ").append(toUpdateList.size()).append("");
}
return successMsg.toString(); return successMsg.toString();
} }
} }

View File

@@ -500,7 +500,7 @@
:limit="1" :limit="1"
accept=".xlsx, .xls" accept=".xlsx, .xls"
:headers="upload.headers" :headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport" :action="upload.url"
:disabled="upload.isUploading" :disabled="upload.isUploading"
:on-progress="handleFileUploadProgress" :on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess" :on-success="handleFileSuccess"
@@ -510,7 +510,6 @@
<i class="el-icon-upload"></i> <i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div> <div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip"> <div class="el-upload__tip" slot="tip">
<el-checkbox v-model="upload.updateSupport" />是否更新已经存在的采购交易数据
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline;" @click="importTemplate">下载模板</el-link> <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div> </div>
<div class="el-upload__tip" slot="tip"> <div class="el-upload__tip" slot="tip">
@@ -715,8 +714,6 @@ export default {
title: "", title: "",
// 是否禁用上传 // 是否禁用上传
isUploading: false, isUploading: false,
// 是否更新已经存在的数据
updateSupport: 0,
// 设置上传的请求头部 // 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() }, headers: { Authorization: "Bearer " + getToken() },
// 上传的地址 // 上传的地址

View File

@@ -314,7 +314,7 @@
:limit="1" :limit="1"
accept=".xlsx, .xls" accept=".xlsx, .xls"
:headers="upload.headers" :headers="upload.headers"
:action="upload.url + '?updateSupport=' + upload.updateSupport" :action="upload.url"
:disabled="upload.isUploading" :disabled="upload.isUploading"
:on-progress="handleFileUploadProgress" :on-progress="handleFileUploadProgress"
:on-success="handleFileSuccess" :on-success="handleFileSuccess"
@@ -324,7 +324,6 @@
<i class="el-icon-upload"></i> <i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处<em>点击上传</em></div> <div class="el-upload__text">将文件拖到此处<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip"> <div class="el-upload__tip" slot="tip">
<el-checkbox v-model="upload.updateSupport" />是否更新已经存在的招聘信息数据
<el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline;" @click="importTemplate">下载模板</el-link> <el-link type="primary" :underline="false" style="font-size: 12px; vertical-align: baseline;" @click="importTemplate">下载模板</el-link>
</div> </div>
<div class="el-upload__tip" slot="tip"> <div class="el-upload__tip" slot="tip">
@@ -457,8 +456,6 @@ export default {
title: "", title: "",
// 是否禁用上传 // 是否禁用上传
isUploading: false, isUploading: false,
// 是否更新已经存在的数据
updateSupport: 0,
// 设置上传的请求头部 // 设置上传的请求头部
headers: { Authorization: "Bearer " + getToken() }, headers: { Authorization: "Bearer " + getToken() },
// 上传的地址 // 上传的地址