|
|
@@ -0,0 +1,319 @@
|
|
|
+package org.dromara.server.base.service.user;
|
|
|
+
|
|
|
+import cn.dev33.satoken.secure.BCrypt;
|
|
|
+import cn.hutool.core.bean.BeanUtil;
|
|
|
+import cn.hutool.core.date.DateUtil;
|
|
|
+import cn.hutool.core.util.ObjectUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
+import org.dromara.common.core.domain.R;
|
|
|
+import org.dromara.common.redis.utils.RedisUtils;
|
|
|
+import org.dromara.server.base.util.EncryptorUtil;
|
|
|
+import org.dromara.server.common.constant.DefaultConstants;
|
|
|
+import org.dromara.server.common.domain.bo.ResourcePerson;
|
|
|
+import org.dromara.server.common.domain.bo.ResourcePersonDept;
|
|
|
+import org.dromara.system.api.RemoteDeptService;
|
|
|
+import org.dromara.system.api.RemotePostService;
|
|
|
+import org.dromara.system.api.RemoteUserService;
|
|
|
+import org.dromara.system.api.domain.bo.RemoteUserBo;
|
|
|
+import org.dromara.system.api.domain.bo.RemoteUserDeptBo;
|
|
|
+import org.dromara.system.api.domain.vo.RemoteDeptVo;
|
|
|
+import org.dromara.system.api.domain.vo.RemotePostVo;
|
|
|
+import org.dromara.system.api.domain.vo.RemoteUserVo;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+
|
|
|
+import java.time.Duration;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+
|
|
|
+/**
|
|
|
+ * name: ConvertUserService
|
|
|
+ * package: org.dromara.server.base.user.service
|
|
|
+ * description: 人员同步处理服务,调用远程服务将同步的人员信息入库
|
|
|
+ * date: 2024-10-23 10:52:40 10:52
|
|
|
+ *
|
|
|
+ * @author luoyibo
|
|
|
+ * @version 0.1
|
|
|
+ * @since JDK 1.8
|
|
|
+ */
|
|
|
+@Service
|
|
|
+@Slf4j
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class SyncRemoteUserService {
|
|
|
+ @DubboReference
|
|
|
+ private final RemoteUserService remoteUserService;
|
|
|
+ @DubboReference
|
|
|
+ private final RemoteDeptService remoteDeptService;
|
|
|
+ @DubboReference
|
|
|
+ private final RemotePostService remotePostService;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 单个人员同步处理
|
|
|
+ *
|
|
|
+ * @param person 人员
|
|
|
+ * @return 结果
|
|
|
+ */
|
|
|
+ public R<RemoteUserVo> syncPeron(ResourcePerson person) {
|
|
|
+ try {
|
|
|
+ String otherId = person.getUserId();
|
|
|
+ //获取人员在一卡通系统中的数据
|
|
|
+ RemoteUserVo remoteUserVo = remoteUserService.selectUserVoByOtherId(otherId);
|
|
|
+ //组装入库的人员业务对象
|
|
|
+ R<RemoteUserBo> result = setUserInfo(person, remoteUserVo);
|
|
|
+ if (result.getCode() == R.SUCCESS) {
|
|
|
+ if (ObjectUtil.isEmpty(remoteUserVo)) {
|
|
|
+ //不存在此人员,增加
|
|
|
+ return remoteUserService.insertUser(result.getData());
|
|
|
+ } else {
|
|
|
+ //存在此人员,修改
|
|
|
+ return remoteUserService.updateUser(result.getData());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return R.fail(result.getMsg());
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ return R.fail(e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取租户配置的岗位清单
|
|
|
+ *
|
|
|
+ * @param tenantId 租户
|
|
|
+ * @return 岗位清单
|
|
|
+ */
|
|
|
+ public List<RemotePostVo> selectPostVoByTenantId(String tenantId) {
|
|
|
+ String cacheKey = tenantId + "_post:";
|
|
|
+ List<RemotePostVo> postVos = RedisUtils.getCacheObject(cacheKey);
|
|
|
+ if (ObjectUtil.isEmpty(postVos)) {
|
|
|
+ postVos = remotePostService.selectPostVo(tenantId);
|
|
|
+ RedisUtils.setCacheObject(cacheKey, postVos, Duration.ofHours(4));
|
|
|
+ }
|
|
|
+ return postVos;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 组装入库的人员业务对象
|
|
|
+ *
|
|
|
+ * @param person 源人员信息
|
|
|
+ * @param remoteUserVo 一卡通对应信息
|
|
|
+ * @return 组装结果
|
|
|
+ */
|
|
|
+ private R<RemoteUserBo> setUserInfo(ResourcePerson person, RemoteUserVo remoteUserVo) {
|
|
|
+ String tenantId = person.getTenantId();
|
|
|
+ if (StrUtil.isEmpty(tenantId)) {
|
|
|
+ tenantId = DefaultConstants.TENANT_ID;
|
|
|
+ person.setTenantId(tenantId);
|
|
|
+ }
|
|
|
+ //获取人员对应的部门信息
|
|
|
+ RemoteDeptVo remoteDeptVo = remoteDeptService.selectDeptByOtherId(person.getDeptId(), tenantId);
|
|
|
+ if (remoteDeptVo == null) {
|
|
|
+ return R.fail("没有找到对应的部门信息");
|
|
|
+ }
|
|
|
+ RemoteUserBo remoteUserBo;
|
|
|
+ if (ObjectUtil.isEmpty(remoteUserVo)) {
|
|
|
+ String userName = getUserName(person);
|
|
|
+ remoteUserBo = new RemoteUserBo();
|
|
|
+ remoteUserBo.setUserType("sys_user");
|
|
|
+ remoteUserBo.setPassword(BCrypt.hashpw(DefaultConstants.LOGIN_PASSWORD));
|
|
|
+ remoteUserBo.setUserName(userName);
|
|
|
+ remoteUserBo.setUserNumb(userName);
|
|
|
+ remoteUserBo.setRoleIds(getUserRole(person));
|
|
|
+ } else {
|
|
|
+ remoteUserBo = BeanUtil.copyProperties(remoteUserVo, RemoteUserBo.class);
|
|
|
+ }
|
|
|
+
|
|
|
+ remoteUserBo.setRealName(person.getRealName());
|
|
|
+ remoteUserBo.setNickName(person.getRealName());
|
|
|
+ remoteUserBo.setCategory(person.getCategory());
|
|
|
+ remoteUserBo.setOtherId(person.getUserId());
|
|
|
+ remoteUserBo.setSex(person.getSex());
|
|
|
+ remoteUserBo.setRemark(person.getRemark());
|
|
|
+ remoteUserBo.setUserState(person.getUserState());
|
|
|
+ remoteUserBo.setPhone(person.getPhone());
|
|
|
+ remoteUserBo.setDeptId(remoteDeptVo.getDeptId());
|
|
|
+ remoteUserBo.setPostId(getUserPostId(person.getPostCode(), tenantId));
|
|
|
+ remoteUserBo.setCardType(getUserCardType(person));
|
|
|
+ remoteUserBo.setLifespan(getUserLifespan(person, remoteDeptVo));
|
|
|
+ remoteUserBo.setTenantId(tenantId);
|
|
|
+ //身份证
|
|
|
+ String idNumber = person.getIdNumber();
|
|
|
+ if (StrUtil.isNotEmpty(idNumber)) {
|
|
|
+ remoteUserBo.setIdNumber(getUserIdNumber(idNumber));
|
|
|
+ }
|
|
|
+ remoteUserBo.setUserDeptList(getUserDept(person));
|
|
|
+ return R.ok(remoteUserBo);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取人员的卡类,如果同步数据有卡类则为同步数据的卡类,否则要根据规则获取
|
|
|
+ * 人员类型
|
|
|
+ * 教职工 category=1
|
|
|
+ * userState=在职(on) 返回 cardType=1
|
|
|
+ * userState=离校(quit) 返回 cardType=5
|
|
|
+ * userState=退休(retire) 返回 cardType=1
|
|
|
+ * userState=去世(die) 返回 cardType=6
|
|
|
+ * 学员 category=2 返回 cardType=2
|
|
|
+ * 研究生 category=3 返回 cardType=3
|
|
|
+ *
|
|
|
+ * @param person 源人员信息
|
|
|
+ * @return 卡类
|
|
|
+ */
|
|
|
+ private Long getUserCardType(ResourcePerson person) {
|
|
|
+ if (StrUtil.isNotEmpty(person.getCardType())) {
|
|
|
+ return Long.valueOf(person.getCardType());
|
|
|
+ }
|
|
|
+ //默认卡类
|
|
|
+ String cardType = "1";
|
|
|
+ String category = person.getCategory();
|
|
|
+ String userState = person.getUserState();
|
|
|
+ cardType = switch (category) {
|
|
|
+ case "1" -> switch (userState) {
|
|
|
+ case "on", "retire" -> "1";
|
|
|
+ case "quit" -> "5";
|
|
|
+ case "die" -> "6";
|
|
|
+ default -> cardType;
|
|
|
+ };
|
|
|
+ case "2" -> "2";
|
|
|
+ case "3" -> "3";
|
|
|
+ default -> cardType;
|
|
|
+ };
|
|
|
+ return Long.valueOf(cardType);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取人员的有效期
|
|
|
+ * 如果同步的有有效基体则返回此有效期,否则再检查人员所在的部门是否有结束日期,如有则返回结束日期,否则返回
|
|
|
+ * 默认2050-12-31 23:59:59
|
|
|
+ *
|
|
|
+ * @param person 源人员信息
|
|
|
+ * @param remoteDeptVo 所在部门信息
|
|
|
+ * @return 有效期
|
|
|
+ */
|
|
|
+ private Date getUserLifespan(ResourcePerson person, RemoteDeptVo remoteDeptVo) {
|
|
|
+ if (ObjectUtil.isNotEmpty(person.getLifespan())) {
|
|
|
+ return person.getLifespan();
|
|
|
+ }
|
|
|
+ Date endDate = remoteDeptVo.getEndDate();
|
|
|
+ if (ObjectUtil.isEmpty(endDate)) {
|
|
|
+ return DateUtil.parse("2050-12-31 23:59:59");
|
|
|
+ } else {
|
|
|
+ return endDate;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 解密人员身份证
|
|
|
+ *
|
|
|
+ * @param sourceIdNumb 待解密身份号
|
|
|
+ * @return 解密后身份证号
|
|
|
+ */
|
|
|
+ private String getUserIdNumber(String sourceIdNumb) {
|
|
|
+ return ObjectUtil.isEmpty(sourceIdNumb) ? null : EncryptorUtil.decode(sourceIdNumb);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取人员对应的岗位Id
|
|
|
+ *
|
|
|
+ * @param postCode 岗位编码
|
|
|
+ * @param tenantId 租户Id
|
|
|
+ * @return 岗位Id
|
|
|
+ */
|
|
|
+ private Long getUserPostId(String postCode, String tenantId) {
|
|
|
+ List<RemotePostVo> postVos = selectPostVoByTenantId(tenantId);
|
|
|
+ List<Long> postIds = postVos.stream().filter(post -> postCode.equals(post.getPostCode()))
|
|
|
+ .map(RemotePostVo::getPostId).toList();
|
|
|
+ if (postIds.isEmpty()) {
|
|
|
+ return DefaultConstants.POST_ID;
|
|
|
+ }
|
|
|
+ return postIds.get(0);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取同步人员的登录账号
|
|
|
+ *
|
|
|
+ * @param person 源人员
|
|
|
+ * @return 登录账号
|
|
|
+ */
|
|
|
+ private String getUserName(ResourcePerson person) {
|
|
|
+ String userName = person.getUserName();
|
|
|
+ //如果同步的有登录账号,返回同步的登录账号
|
|
|
+ if (StrUtil.isNotEmpty(userName)) {
|
|
|
+ return userName;
|
|
|
+ }
|
|
|
+ String phone = person.getPhone();
|
|
|
+ //如果同步没有登录账号,但同步有手机号,则将手机号作为登录账号
|
|
|
+ if (StrUtil.isNotEmpty(phone)) {
|
|
|
+ return phone;
|
|
|
+ }
|
|
|
+ //如果都没有,则要自动生成一个
|
|
|
+ String temp = DateUtil.format(new Date(), "yyyyMMdd");
|
|
|
+ String cacheKey = person.getTenantId() + "_day_number:";
|
|
|
+ Integer count = RedisUtils.getCacheObject(cacheKey);
|
|
|
+ if (ObjectUtil.isEmpty(count)) {
|
|
|
+ count = 1;
|
|
|
+ } else {
|
|
|
+ count++;
|
|
|
+ }
|
|
|
+ RedisUtils.setCacheObject(cacheKey, count, Duration.ofDays(1));
|
|
|
+ return temp + StrUtil.padPre(count.toString(), 4, '0');
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取同步人员的默认角色
|
|
|
+ *
|
|
|
+ * @param person 源人员
|
|
|
+ * @return 角色
|
|
|
+ */
|
|
|
+ private Long[] getUserRole(ResourcePerson person) {
|
|
|
+ String category = person.getCategory();
|
|
|
+ Long[] roleIds = new Long[1];
|
|
|
+ switch (category) {
|
|
|
+ //教职工
|
|
|
+ case "1":
|
|
|
+ roleIds[0] = DefaultConstants.TEACHER_ROLE_ID;
|
|
|
+ break;
|
|
|
+ //学员
|
|
|
+ case "2":
|
|
|
+ roleIds[0] = DefaultConstants.TRAIN_ROLE_ID;
|
|
|
+ break;
|
|
|
+ //研究生
|
|
|
+ case "3":
|
|
|
+ roleIds[0] = DefaultConstants.GRADUATE_ROLE_ID;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ return roleIds;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取同步人员的部门
|
|
|
+ *
|
|
|
+ * @param person 源人员
|
|
|
+ * @return 人员部门
|
|
|
+ */
|
|
|
+ private List<RemoteUserDeptBo> getUserDept(ResourcePerson person) {
|
|
|
+ List<ResourcePersonDept> resourcePersonDeptList = person.getUserDeptList();
|
|
|
+ if (ObjectUtil.isEmpty(resourcePersonDeptList)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ List<RemoteUserDeptBo> remoteUserDeptBos = new ArrayList<>();
|
|
|
+ resourcePersonDeptList.forEach(resourcePersonDept -> {
|
|
|
+ RemoteUserDeptBo remoteUserDeptBo = new RemoteUserDeptBo();
|
|
|
+ RemoteDeptVo remoteDeptVo = remoteDeptService.selectDeptByOtherId(resourcePersonDept.getDeptId(), person.getTenantId());
|
|
|
+ if (ObjectUtil.isNotEmpty(remoteDeptVo)) {
|
|
|
+ remoteUserDeptBo.setDeptId(remoteDeptVo.getDeptId());
|
|
|
+ remoteUserDeptBo.setPostId(getUserPostId(resourcePersonDept.getPostCode(), person.getTenantId()));
|
|
|
+ remoteUserDeptBo.setMainDept(resourcePersonDept.getMainDept());
|
|
|
+ remoteUserDeptBo.setDelFlag(resourcePersonDept.getDelFlag());
|
|
|
+
|
|
|
+ remoteUserDeptBos.add(remoteUserDeptBo);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return remoteUserDeptBos;
|
|
|
+ }
|
|
|
+}
|