添加员工管理自动导入能力,修复了部门,岗位未显示
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
package com.ruoyi.oa.task;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.hrm.domain.HrmEmployee;
|
||||
import com.ruoyi.hrm.mapper.HrmEmployeeMapper;
|
||||
import com.ruoyi.system.mapper.SysUserMapper;
|
||||
import com.xxl.job.core.context.XxlJobHelper;
|
||||
import com.xxl.job.core.handler.annotation.XxlJob;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 每日自动把员工挂到对应的 sys_user。
|
||||
*
|
||||
* 匹配规则(保守,宁可漏挂不错挂):
|
||||
* 1. hrm_employee.user_id 已指向存在的 sys_user 且 nick_name/user_name 与 emp_name 一致 → 跳过
|
||||
* 2. 否则按 emp_name 找候选:先看 nick_name,再看 user_name
|
||||
* 3. 候选唯一 + 手机号也对上 → 自动写 user_id(含孤儿修复)
|
||||
* 4. 其余情况打日志报告,交人工处理
|
||||
*
|
||||
* xxl-job 调度中心 JobHandler 名称:{@code employeeUserLinkJob}
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class EmployeeUserLinkJob {
|
||||
|
||||
private final HrmEmployeeMapper employeeMapper;
|
||||
private final SysUserMapper userMapper;
|
||||
|
||||
@XxlJob("employeeUserLinkJob")
|
||||
public void run() {
|
||||
List<HrmEmployee> emps = employeeMapper.selectList(Wrappers.<HrmEmployee>lambdaQuery()
|
||||
.eq(HrmEmployee::getDelFlag, 0));
|
||||
List<SysUser> users = userMapper.selectList(Wrappers.<SysUser>lambdaQuery()
|
||||
.eq(SysUser::getDelFlag, "0"));
|
||||
|
||||
Map<Long, SysUser> byUid = users.stream()
|
||||
.collect(Collectors.toMap(SysUser::getUserId, u -> u, (a, b) -> a));
|
||||
|
||||
// 姓名 → 候选。同名可能多人,用 List 装
|
||||
Map<String, List<SysUser>> byNick = new HashMap<>();
|
||||
Map<String, List<SysUser>> byUname = new HashMap<>();
|
||||
for (SysUser u : users) {
|
||||
if (u.getNickName() != null) {
|
||||
byNick.computeIfAbsent(u.getNickName().trim(), k -> new java.util.ArrayList<>()).add(u);
|
||||
}
|
||||
if (u.getUserName() != null) {
|
||||
byUname.computeIfAbsent(u.getUserName().trim(), k -> new java.util.ArrayList<>()).add(u);
|
||||
}
|
||||
}
|
||||
|
||||
int skip = 0, autoFix = 0, needManual = 0;
|
||||
for (HrmEmployee e : emps) {
|
||||
SysUser current = e.getUserId() == null ? null : byUid.get(e.getUserId());
|
||||
if (current != null && nameMatches(current, e.getEmpName())) {
|
||||
skip++;
|
||||
continue;
|
||||
}
|
||||
|
||||
List<SysUser> candidates = byNick.getOrDefault(e.getEmpName().trim(), java.util.Collections.emptyList());
|
||||
if (candidates.isEmpty()) {
|
||||
candidates = byUname.getOrDefault(e.getEmpName().trim(), java.util.Collections.emptyList());
|
||||
}
|
||||
|
||||
SysUser picked = pickByPhone(candidates, e.getMobile());
|
||||
if (picked == null) {
|
||||
XxlJobHelper.log("[需人工] emp_id={} emp_name={} current_user_id={} 候选={} —— " +
|
||||
"候选唯一且手机匹配才能自动挂",
|
||||
e.getEmpId(), e.getEmpName(), e.getUserId(),
|
||||
candidates.stream().map(SysUser::getUserId).collect(Collectors.toList()));
|
||||
needManual++;
|
||||
continue;
|
||||
}
|
||||
if (Objects.equals(picked.getUserId(), e.getUserId())) {
|
||||
// 姓名判定失败但 user_id 恰好指向匹配用户;一致跳过
|
||||
skip++;
|
||||
continue;
|
||||
}
|
||||
|
||||
HrmEmployee update = new HrmEmployee();
|
||||
update.setEmpId(e.getEmpId());
|
||||
update.setUserId(picked.getUserId());
|
||||
employeeMapper.updateById(update);
|
||||
XxlJobHelper.log("[已挂] emp_id={} emp_name={} user_id: {} → {} ({} / {})",
|
||||
e.getEmpId(), e.getEmpName(), e.getUserId(), picked.getUserId(),
|
||||
picked.getNickName(), picked.getUserName());
|
||||
autoFix++;
|
||||
}
|
||||
|
||||
String msg = String.format("员工-用户关联体检完成:总数=%d,跳过=%d,自动修=%d,需人工=%d",
|
||||
emps.size(), skip, autoFix, needManual);
|
||||
XxlJobHelper.log(msg);
|
||||
log.info(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* 姓名判定:sys_user.nick_name 或 user_name 与员工 emp_name 完全一致
|
||||
*/
|
||||
private static boolean nameMatches(SysUser u, String empName) {
|
||||
if (empName == null) return false;
|
||||
String t = empName.trim();
|
||||
return t.equals(safeTrim(u.getNickName())) || t.equals(safeTrim(u.getUserName()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 候选里挑一个:唯一 + 手机号匹配。其余场景返回 null,交人工。
|
||||
*/
|
||||
private static SysUser pickByPhone(List<SysUser> candidates, String mobile) {
|
||||
if (candidates == null || candidates.isEmpty()) return null;
|
||||
if (mobile == null || mobile.trim().isEmpty()) {
|
||||
// 无手机号无法二次确认,只允许候选唯一时挂
|
||||
return candidates.size() == 1 ? candidates.get(0) : null;
|
||||
}
|
||||
String m = mobile.trim();
|
||||
List<SysUser> phoneHits = candidates.stream()
|
||||
.filter(u -> m.equals(safeTrim(u.getPhonenumber())))
|
||||
.collect(Collectors.toList());
|
||||
if (phoneHits.size() == 1) return phoneHits.get(0);
|
||||
// 手机号没能唯一定位:若候选只有一个且姓名对上,也允许挂(无手机号情况)
|
||||
if (phoneHits.isEmpty() && candidates.size() == 1) return candidates.get(0);
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String safeTrim(String s) {
|
||||
return s == null ? "" : s.trim();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user