From 1d372d5e4916eaecf9b773e52e0d887d4fd0e47a Mon Sep 17 00:00:00 2001
From: tuqin <tuqin@tuqin.cn>
Date: 星期四, 05 十一月 2026 15:02:27 +0800
Subject: [PATCH] fix(hrm): 社保扣款在员工未加社保时误扣、两方案扣款相同
---
yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java | 135 ++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 128 insertions(+), 7 deletions(-)
diff --git a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java
index 54cc87d..f32091d 100644
--- a/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java
+++ b/yudao-module-hrm/src/main/java/cn/iocoder/yudao/module/hrm/service/employee/HrmEmployeeServiceImpl.java
@@ -40,6 +40,7 @@
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserCreateReqDTO;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserUpdateReqDTO;
import jakarta.annotation.Resource;
+import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -48,6 +49,7 @@
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -68,7 +70,11 @@
*/
@Service
@Validated
+@Slf4j
public class HrmEmployeeServiceImpl implements HrmEmployeeService {
+
+ /** 鍛樺伐鐘舵�侊細绂昏亴锛�1-鍦ㄨ亴锛�2-璇曠敤锛�3-绂昏亴锛� */
+ private static final Integer EMPLOYEE_STATUS_RESIGNED = 3;
@Resource
private HrmEmployeeMapper employeeMapper;
@@ -103,9 +109,15 @@
deptApi.validateDeptList(Collections.singleton(createReqVO.getDeptId()));
// 2. 鏍¢獙宀椾綅
postApi.validPostList(createReqVO.getPostIds());
- // 3. 鏍¢獙鎵嬫満鍙锋槸鍚﹀凡瀛樺湪
- if (employeeMapper.selectByPhone(createReqVO.getPhone()) != null) {
- throw exception(EMPLOYEE_PHONE_EXISTS);
+ // 3. 鏍¢獙鎵嬫満鍙锋槸鍚﹀凡瀛樺湪锛�**鍖呭惈宸插垹闄ゆ。妗�**锛歶k_phone 鍞竴绱㈠紩涓嶅尯鍒� deleted锛�
+ // 鍙煡鏈垹闄よ褰曚細婕忓垽锛屽鑷村啓搴撴椂鎶涘敮涓�绾︽潫寮傚父锛屽墠绔樉绀衡�滅郴缁熷紓甯糕�濓級
+ if (createReqVO.getPhone() != null) {
+ HrmEmployeeDO existPhone = employeeMapper.selectByPhoneIgnoreDeleted(createReqVO.getPhone());
+ if (existPhone != null) {
+ throw existPhone.getDeleted() != null && existPhone.getDeleted()
+ ? exception(EMPLOYEE_PHONE_OCCUPIED_BY_DELETED, createReqVO.getPhone())
+ : exception(EMPLOYEE_PHONE_EXISTS);
+ }
}
// 4. 鍚屾鍒涘缓绯荤粺鐢ㄦ埛
AdminUserCreateReqDTO userCreateReqDTO = new AdminUserCreateReqDTO();
@@ -185,10 +197,14 @@
deptApi.validateDeptList(Collections.singleton(updateReqVO.getDeptId()));
// 鏍¢獙宀椾綅
postApi.validPostList(updateReqVO.getPostIds());
- // 鏍¢獙鎵嬫満鍙锋槸鍚﹀凡瀛樺湪锛堝鏋滄墜鏈哄彿鏈夊彉鏇达級
- if (!Objects.equals(employee.getPhone(), updateReqVO.getPhone())
- && employeeMapper.selectByPhone(updateReqVO.getPhone()) != null) {
- throw exception(EMPLOYEE_PHONE_EXISTS);
+ // 鏍¢獙鎵嬫満鍙锋槸鍚﹀凡瀛樺湪锛堝鏋滄墜鏈哄彿鏈夊彉鏇达紱**鍖呭惈宸插垹闄ゆ。妗�**锛屽師鍥犺 createEmployee锛�
+ if (!Objects.equals(employee.getPhone(), updateReqVO.getPhone()) && updateReqVO.getPhone() != null) {
+ HrmEmployeeDO existPhone = employeeMapper.selectByPhoneIgnoreDeleted(updateReqVO.getPhone());
+ if (existPhone != null && !Objects.equals(existPhone.getId(), updateReqVO.getId())) {
+ throw existPhone.getDeleted() != null && existPhone.getDeleted()
+ ? exception(EMPLOYEE_PHONE_OCCUPIED_BY_DELETED, updateReqVO.getPhone())
+ : exception(EMPLOYEE_PHONE_EXISTS);
+ }
}
// 鏇存柊鍛樺伐涓昏〃
HrmEmployeeDO updateObj = BeanUtils.toBean(updateReqVO, HrmEmployeeDO.class);
@@ -358,7 +374,63 @@
@Override
public List<HrmEmployeeDO> getEmployeeList(Collection<Long> ids) {
+ // 闃插尽锛歁yBatis-Plus 鐨� selectByIds(null) 浼氭姏
+ // BuilderException: The expression 'coll' evaluated to a null value
+ if (CollUtil.isEmpty(ids)) {
+ return new ArrayList<>();
+ }
return employeeMapper.selectByIds(ids);
+ }
+
+ @Override
+ public List<HrmEmployeeDO> getEmployeeListByStatus(Integer employeeStatus) {
+ return employeeMapper.selectListByStatus(employeeStatus);
+ }
+
+ @Override
+ public void syncEmployeeTransfer(Long employeeId, Long targetDeptId, Long targetPostId) {
+ if (employeeId == null) {
+ return;
+ }
+ HrmEmployeeDO employee = employeeMapper.selectById(employeeId);
+ if (employee == null) {
+ log.warn("[syncEmployeeTransfer][鍛樺伐({}) 涓嶅瓨鍦紝璺宠繃璋冨矖鍚屾]", employeeId);
+ return;
+ }
+ if (targetDeptId == null && targetPostId == null) {
+ return;
+ }
+ HrmEmployeeDO updateObj = new HrmEmployeeDO();
+ updateObj.setId(employeeId);
+ if (targetDeptId != null) {
+ updateObj.setDeptId(targetDeptId);
+ }
+ if (targetPostId != null) {
+ // hrm_employee.post_ids 瀛� JSON 鏁扮粍瀛楃涓诧紝濡� [38]
+ updateObj.setPostIds(JSONUtil.toJsonStr(java.util.List.of(targetPostId)));
+ }
+ employeeMapper.updateById(updateObj);
+ log.info("[syncEmployeeTransfer][鍛樺伐({}) 璋冨矖鐢熸晥锛氶儴闂� {} -> {}锛屽矖浣� -> {}]",
+ employeeId, employee.getDeptId(), targetDeptId, targetPostId);
+ }
+
+ @Override
+ public void syncEmployeeResignation(Long systemUserId, java.time.LocalDate leaveDate) {
+ if (systemUserId == null) {
+ return;
+ }
+ HrmEmployeeDO employee = employeeMapper.selectByUserId(systemUserId);
+ if (employee == null) {
+ log.warn("[syncEmployeeResignation][绯荤粺鐢ㄦ埛({}) 娌℃湁瀵瑰簲鍛樺伐妗f锛岃烦杩囩鑱屽悓姝", systemUserId);
+ return;
+ }
+ employeeMapper.updateById(HrmEmployeeDO.builder()
+ .id(employee.getId())
+ .employeeStatus(EMPLOYEE_STATUS_RESIGNED)
+ .leaveDate(leaveDate != null ? leaveDate : java.time.LocalDate.now())
+ .build());
+ log.info("[syncEmployeeResignation][鍛樺伐({}) 绂昏亴鐢熸晥锛岀姸鎬� {} -> {}]",
+ employee.getId(), employee.getEmployeeStatus(), EMPLOYEE_STATUS_RESIGNED);
}
@Override
@@ -370,19 +442,68 @@
.filter(Objects::nonNull)
.collect(Collectors.toSet());
Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(deptIds);
+ // 瑙f瀽宀椾綅ID锛坧ost_ids 瀛樼殑鏄� JSON 鏁扮粍瀛楃涓诧紝濡� [38]锛夛紝骞舵壒閲忓姞杞藉矖浣嶅悕绉�
+ Map<Long, List<Long>> empPostIdsMap = new LinkedHashMap<>();
+ Set<Long> allPostIds = new LinkedHashSet<>();
+ for (HrmEmployeeDO emp : list) {
+ List<Long> postIdList = parseEmployeePostIds(emp.getPostIds());
+ empPostIdsMap.put(emp.getId(), postIdList);
+ allPostIds.addAll(postIdList);
+ }
+ Map<Long, PostRespDTO> postMap = CollUtil.isEmpty(allPostIds)
+ ? Collections.emptyMap() : postApi.getPostMap(allPostIds);
return list.stream().map(emp -> {
HrmEmployeeSimpleRespVO vo = new HrmEmployeeSimpleRespVO();
vo.setId(emp.getId());
vo.setEmployeeNo(emp.getEmployeeNo());
vo.setName(emp.getName());
vo.setEmployeeStatus(emp.getEmployeeStatus());
+ vo.setDeptId(emp.getDeptId());
if (emp.getDeptId() != null && deptMap.containsKey(emp.getDeptId())) {
vo.setDeptName(deptMap.get(emp.getDeptId()).getName());
+ }
+ // 宀椾綅淇℃伅锛堢敤浜庤皟宀楃瓑鍦烘櫙鑷姩甯﹀嚭鍘熷矖浣嶏級
+ List<Long> postIdList = empPostIdsMap.getOrDefault(emp.getId(), Collections.emptyList());
+ vo.setPostIds(postIdList);
+ if (CollUtil.isNotEmpty(postIdList)) {
+ vo.setPostName(postIdList.stream()
+ .map(postMap::get)
+ .filter(Objects::nonNull)
+ .map(PostRespDTO::getName)
+ .collect(Collectors.joining(",")));
}
return vo;
}).collect(Collectors.toList());
}
+ /**
+ * 瑙f瀽鍛樺伐鐨勫矖浣岻D瀛楃涓诧紙JSON 鏁扮粍鏍煎紡锛屽 [38] 鎴� [1,2]锛�
+ */
+
+ /**
+ * 瑙f瀽鍛樺伐宀椾綅ID瀛楃涓诧紙post_ids 瀛� JSON 鏁扮粍锛屽 [38] 鎴� [1,2]锛�
+ */
+ private java.util.List<Long> parseEmployeePostIds(String postIds) {
+ if (StrUtil.isBlank(postIds)) {
+ return Collections.emptyList();
+ }
+
+ // post_ids 褰㈠ "[38]" 鎴� "[1,2]"锛氬幓鎺変腑鎷彿鍚庢寜閫楀彿瑙f瀽
+ return Arrays.stream(postIds.replace("[", "").replace("]", "").split(","))
+ .map(String::trim)
+ .filter(StrUtil::isNotBlank)
+ .map(s -> {
+ try {
+ return Long.valueOf(s);
+ } catch (NumberFormatException ex) {
+ return null;
+ }
+ })
+ .filter(Objects::nonNull)
+ .collect(Collectors.toList());
+ }
+
+
@Override
public HrmEmployeeDO getEmployeeByUserId(Long userId) {
return employeeMapper.selectByUserId(userId);
--
Gitblit v1.9.3