yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/dal/mysql/salary/HrmSalaryPaymentDetailMapper.java
@@ -1,5 +1,6 @@ package cn.iocoder.yudao.module.hrm.dal.mysql.salary; import cn.hutool.core.collection.CollUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; @@ -7,6 +8,8 @@ import cn.iocoder.yudao.module.hrm.dal.dataobject.salary.HrmSalaryPaymentDetailDO; import org.apache.ibatis.annotations.Mapper; import java.util.Collection; import java.util.Collections; import java.util.List; /** @@ -40,4 +43,17 @@ return selectOne(HrmSalaryPaymentDetailDO::getCalculationId, calculationId); } /** * 批量查询:哪些核算单已被工资发放明细引用 * * 用于删除核算单前做引用保护,避免发放明细变成孤儿数据。 */ default List<HrmSalaryPaymentDetailDO> selectListByCalculationIds(Collection<Long> calculationIds) { if (CollUtil.isEmpty(calculationIds)) { return Collections.emptyList(); } return selectList(new LambdaQueryWrapperX<HrmSalaryPaymentDetailDO>() .in(HrmSalaryPaymentDetailDO::getCalculationId, calculationIds)); } } yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/salary/HrmSalaryCalculationServiceImpl.java
@@ -881,8 +881,12 @@ /** * 批量删除核算记录(全选后一键删除) * * 说明:按业务要求,批量删除不限制状态,勾选即删。 * 不存在的 ID 直接跳过,不报错(避免前端勾选列表与库不一致时整体失败)。 * 说明: * 1. 按业务要求,批量删除不限制核算单状态,勾选即删; * 2. 不存在的 ID 直接跳过,不报错(避免前端勾选列表与库不一致时整体失败); * 3. 已被「工资发放明细」引用的记录会跳过不删,避免发放明细变成孤儿数据。 * * @return 实际删除的条数(可能小于传入条数) */ @Override public Integer deleteSalaryCalculationList(List<Long> ids) { @@ -895,8 +899,19 @@ if (CollUtil.isEmpty(existIds)) { return 0; } salaryCalculationMapper.deleteByIds(existIds); return existIds.size(); // 引用保护:已进入工资发放流程的核算单不允许删除 Set<Long> referencedIds = salaryPaymentDetailMapper.selectListByCalculationIds(existIds).stream() .map(HrmSalaryPaymentDetailDO::getCalculationId) .filter(Objects::nonNull) .collect(Collectors.toSet()); List<Long> deletableIds = existIds.stream() .filter(id -> !referencedIds.contains(id)) .collect(Collectors.toList()); if (CollUtil.isEmpty(deletableIds)) { return 0; } salaryCalculationMapper.deleteByIds(deletableIds); return deletableIds.size(); } }