iwork 人员组织同步相关
This commit is contained in:
@@ -119,6 +119,24 @@ public class IWorkIntegrationController {
|
||||
return success(syncService.fullSync(reqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/hr/departments/full-sync")
|
||||
@Operation(summary = "手动触发 iWork 部门全量同步")
|
||||
public CommonResult<IWorkFullSyncRespVO> fullSyncDepartments(@Valid @RequestBody IWorkFullSyncReqVO reqVO) {
|
||||
return success(syncService.fullSyncDepartments(reqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/hr/job-titles/full-sync")
|
||||
@Operation(summary = "手动触发 iWork 岗位全量同步")
|
||||
public CommonResult<IWorkFullSyncRespVO> fullSyncJobTitles(@Valid @RequestBody IWorkFullSyncReqVO reqVO) {
|
||||
return success(syncService.fullSyncJobTitles(reqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/hr/users/full-sync")
|
||||
@Operation(summary = "手动触发 iWork 人员全量同步")
|
||||
public CommonResult<IWorkFullSyncRespVO> fullSyncUsers(@Valid @RequestBody IWorkFullSyncReqVO reqVO) {
|
||||
return success(syncService.fullSyncUsers(reqVO));
|
||||
}
|
||||
|
||||
@PostMapping("/hr/single-sync")
|
||||
@Operation(summary = "按 iWork ID 同步单条组织/人员")
|
||||
public CommonResult<IWorkSingleSyncRespVO> singleSync(@Valid @RequestBody IWorkSingleSyncReqVO reqVO) {
|
||||
|
||||
@@ -84,6 +84,10 @@ public class UserSaveReqVO {
|
||||
@Schema(description = "用户来源类型", example = "1")
|
||||
private Integer userSource;
|
||||
|
||||
@Schema(hidden = true)
|
||||
@JsonIgnore
|
||||
private boolean skipAssociationValidation;
|
||||
|
||||
// ========== 仅【创建】时,需要传递的字段 ==========
|
||||
|
||||
@Schema(description = "密码", requiredMode = Schema.RequiredMode.REQUIRED, example = "123456")
|
||||
|
||||
@@ -15,6 +15,21 @@ public interface IWorkSyncService {
|
||||
*/
|
||||
IWorkFullSyncRespVO fullSync(IWorkFullSyncReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 仅同步部门(会自动包含依赖的分部)
|
||||
*/
|
||||
IWorkFullSyncRespVO fullSyncDepartments(IWorkFullSyncReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 仅同步岗位
|
||||
*/
|
||||
IWorkFullSyncRespVO fullSyncJobTitles(IWorkFullSyncReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 仅同步人员(会自动包含依赖的分部、部门)
|
||||
*/
|
||||
IWorkFullSyncRespVO fullSyncUsers(IWorkFullSyncReqVO reqVO);
|
||||
|
||||
/**
|
||||
* 根据 iWork ID 进行单条同步
|
||||
*/
|
||||
|
||||
@@ -229,17 +229,16 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
||||
}
|
||||
String username = resolveUsername(user);
|
||||
if (StrUtil.isBlank(username)) {
|
||||
log.warn("[iWork] 人员缺少可用账号,跳过:id={} name={}", user.getId(), user.getLastname());
|
||||
log.warn("[iWork] 人员缺少可用账号(工号={}, 登录账号={}),跳过:id={} name={}",
|
||||
user.getWorkcode(), user.getLoginid(), user.getId(), user.getLastname());
|
||||
result.increaseFailed();
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
Long deptId = resolveUserDeptId(user);
|
||||
if (deptId == null) {
|
||||
log.warn("[iWork] 人员未找到匹配部门,跳过:id={} name={} deptId={} subcompany={}",
|
||||
log.warn("[iWork] 人员未找到匹配部门,继续同步:id={} name={} deptId={} subcompany={}",
|
||||
user.getId(), user.getLastname(), user.getDepartmentid(), user.getSubcompanyid1());
|
||||
result.increaseFailed();
|
||||
continue;
|
||||
}
|
||||
Long postId = resolveUserPostId(user);
|
||||
CommonStatusEnum status = inactive ? CommonStatusEnum.DISABLE : CommonStatusEnum.ENABLE;
|
||||
@@ -313,21 +312,26 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
||||
return new JobSyncOutcome(SyncAction.SKIPPED, false, null);
|
||||
}
|
||||
PostSaveReqVO createReq = new PostSaveReqVO();
|
||||
Long desiredId = job.getJobtitleid() == null ? null : job.getJobtitleid().longValue();
|
||||
if (desiredId != null) {
|
||||
createReq.setId(desiredId);
|
||||
}
|
||||
createReq.setCode(code);
|
||||
createReq.setName(name);
|
||||
createReq.setSort(defaultSort(job.getShoworder()));
|
||||
createReq.setStatus(status);
|
||||
createReq.setRemark(StrUtil.blankToDefault(job.getJobfunction(), job.getDescription()));
|
||||
Long postId = postService.createPost(createReq);
|
||||
Long effectivePostId = desiredId != null ? desiredId : postId;
|
||||
PostDO created = new PostDO();
|
||||
created.setId(postId);
|
||||
created.setId(effectivePostId);
|
||||
created.setCode(code);
|
||||
created.setName(createReq.getName());
|
||||
created.setSort(createReq.getSort());
|
||||
created.setStatus(status);
|
||||
created.setRemark(createReq.getRemark());
|
||||
postCache.put(buildPostCacheKey(code), created);
|
||||
return new JobSyncOutcome(SyncAction.CREATED, disabled, postId);
|
||||
return new JobSyncOutcome(SyncAction.CREATED, disabled, effectivePostId);
|
||||
}
|
||||
if (!options.isAllowUpdate()) {
|
||||
return new JobSyncOutcome(SyncAction.SKIPPED, false, existing.getId());
|
||||
@@ -355,10 +359,15 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
||||
Long postId,
|
||||
CommonStatusEnum status) {
|
||||
UserSaveReqVO req = buildUserSaveReq(source, username, deptId, postId, status);
|
||||
Long desiredUserId = source.getId() == null ? null : source.getId().longValue();
|
||||
if (desiredUserId != null) {
|
||||
req.setId(desiredUserId);
|
||||
}
|
||||
req.setPassword(DEFAULT_USER_PASSWORD);
|
||||
req.setUserSource(UserSourceEnum.IWORK.getSource());
|
||||
Long userId = adminUserService.createUser(req);
|
||||
return new UserSyncOutcome(SyncAction.CREATED, CommonStatusEnum.isDisable(req.getStatus()), userId);
|
||||
Long effectiveUserId = desiredUserId != null ? desiredUserId : userId;
|
||||
return new UserSyncOutcome(SyncAction.CREATED, CommonStatusEnum.isDisable(req.getStatus()), effectiveUserId);
|
||||
}
|
||||
|
||||
private UserSyncOutcome updateUser(AdminUserDO existing,
|
||||
@@ -419,7 +428,9 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
||||
req.setUsername(username);
|
||||
req.setNickname(limitLength(StrUtil.blankToDefault(source.getLastname(), username), 30));
|
||||
req.setRemark(buildUserRemark(source));
|
||||
req.setDeptIds(singletonSet(deptId));
|
||||
if (deptId != null) {
|
||||
req.setDeptIds(singletonSet(deptId));
|
||||
}
|
||||
if (postId != null) {
|
||||
req.setPostIds(singletonSet(postId));
|
||||
}
|
||||
@@ -427,6 +438,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
||||
req.setMobile(trimToNull(source.getMobile()));
|
||||
req.setSex(resolveSex(source.getSex()));
|
||||
req.setStatus(status.getStatus());
|
||||
req.setSkipAssociationValidation(true);
|
||||
return req;
|
||||
}
|
||||
|
||||
@@ -590,12 +602,9 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
||||
}
|
||||
|
||||
private String resolveUsername(IWorkHrUserPageRespVO.User user) {
|
||||
String candidate = sanitizeUsername(user.getLoginid());
|
||||
String candidate = sanitizeUsername(user.getWorkcode());
|
||||
if (candidate == null) {
|
||||
candidate = sanitizeUsername(user.getWorkcode());
|
||||
}
|
||||
if (candidate == null && user.getId() != null) {
|
||||
candidate = sanitizeUsername("IWORK" + user.getId());
|
||||
candidate = sanitizeUsername(user.getLoginid());
|
||||
}
|
||||
return candidate;
|
||||
}
|
||||
|
||||
@@ -12,10 +12,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import static com.zt.plat.module.system.service.integration.iwork.IWorkIntegrationErrorCodeConstants.IWORK_ORG_REMOTE_FAILED;
|
||||
|
||||
@@ -32,15 +29,33 @@ public class IWorkSyncServiceImpl implements IWorkSyncService {
|
||||
|
||||
@Override
|
||||
public IWorkFullSyncRespVO fullSync(IWorkFullSyncReqVO reqVO) {
|
||||
return runFullSync(reqVO, reqVO.resolveScopes());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWorkFullSyncRespVO fullSyncDepartments(IWorkFullSyncReqVO reqVO) {
|
||||
return runFullSync(reqVO, EnumSet.of(IWorkSyncEntityTypeEnum.DEPARTMENT));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWorkFullSyncRespVO fullSyncJobTitles(IWorkFullSyncReqVO reqVO) {
|
||||
return runFullSync(reqVO, EnumSet.of(IWorkSyncEntityTypeEnum.JOB_TITLE));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IWorkFullSyncRespVO fullSyncUsers(IWorkFullSyncReqVO reqVO) {
|
||||
return runFullSync(reqVO, EnumSet.of(IWorkSyncEntityTypeEnum.USER));
|
||||
}
|
||||
|
||||
private IWorkFullSyncRespVO runFullSync(IWorkFullSyncReqVO reqVO, Set<IWorkSyncEntityTypeEnum> scopes) {
|
||||
IWorkFullSyncRespVO respVO = new IWorkFullSyncRespVO();
|
||||
respVO.setPageSize(reqVO.getPageSize());
|
||||
List<IWorkSyncBatchStatVO> batchStats = new ArrayList<>();
|
||||
respVO.setBatches(batchStats);
|
||||
|
||||
Set<IWorkSyncEntityTypeEnum> scopes = reqVO.resolveScopes();
|
||||
boolean syncUsers = scopes.contains(IWorkSyncEntityTypeEnum.USER);
|
||||
boolean syncDepartments = scopes.contains(IWorkSyncEntityTypeEnum.DEPARTMENT) || syncUsers;
|
||||
boolean syncSubcompanies = scopes.contains(IWorkSyncEntityTypeEnum.SUBCOMPANY) || syncDepartments;
|
||||
boolean syncDepartments = scopes.contains(IWorkSyncEntityTypeEnum.DEPARTMENT);
|
||||
boolean syncSubcompanies = scopes.contains(IWorkSyncEntityTypeEnum.SUBCOMPANY);
|
||||
int processedPages = 0;
|
||||
IWorkSyncProcessor.SyncOptions options = buildFullSyncOptions(reqVO);
|
||||
if (syncSubcompanies) {
|
||||
|
||||
@@ -108,7 +108,8 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
});
|
||||
// 1.2 校验正确性
|
||||
validateUserForCreateOrUpdate(null, createReqVO.getUsername(),
|
||||
createReqVO.getMobile(), createReqVO.getEmail(), createReqVO.getDeptIds(), createReqVO.getPostIds());
|
||||
createReqVO.getMobile(), createReqVO.getEmail(), createReqVO.getDeptIds(), createReqVO.getPostIds(),
|
||||
createReqVO.isSkipAssociationValidation());
|
||||
// 2.1 插入用户
|
||||
AdminUserDO user = BeanUtils.toBean(createReqVO, AdminUserDO.class);
|
||||
user.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||
@@ -154,7 +155,7 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
}
|
||||
});
|
||||
// 1.3 校验正确性
|
||||
validateUserForCreateOrUpdate(null, registerReqVO.getUsername(), null, null, null, null);
|
||||
validateUserForCreateOrUpdate(null, registerReqVO.getUsername(), null, null, null, null, false);
|
||||
|
||||
// 2. 插入用户
|
||||
AdminUserDO user = BeanUtils.toBean(registerReqVO, AdminUserDO.class);
|
||||
@@ -173,7 +174,8 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
updateReqVO.setPassword(null); // 特殊:此处不更新密码
|
||||
// 1. 校验正确性
|
||||
AdminUserDO oldUser = validateUserForCreateOrUpdate(updateReqVO.getId(), updateReqVO.getUsername(),
|
||||
updateReqVO.getMobile(), updateReqVO.getEmail(), updateReqVO.getDeptIds(), updateReqVO.getPostIds());
|
||||
updateReqVO.getMobile(), updateReqVO.getEmail(), updateReqVO.getDeptIds(),
|
||||
updateReqVO.getPostIds(), updateReqVO.isSkipAssociationValidation());
|
||||
|
||||
// 2.1 只更新非空字段
|
||||
AdminUserDO updateObj = new AdminUserDO();
|
||||
@@ -512,7 +514,7 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
}
|
||||
|
||||
private AdminUserDO validateUserForCreateOrUpdate(Long id, String username, String mobile, String email,
|
||||
Set<Long> deptIds, Set<Long> postIds) {
|
||||
Set<Long> deptIds, Set<Long> postIds, boolean skipAssociationValidation) {
|
||||
// 关闭数据权限,避免因为没有数据权限,查询不到数据,进而导致唯一校验不正确
|
||||
return DataPermissionUtils.executeIgnore(() -> {
|
||||
// 校验用户存在
|
||||
@@ -524,7 +526,9 @@ public class AdminUserServiceImpl implements AdminUserService {
|
||||
// 校验邮箱唯一
|
||||
validateEmailUnique(id, email);
|
||||
// 校验岗位处于开启状态
|
||||
postService.validatePostList(postIds);
|
||||
if (!skipAssociationValidation) {
|
||||
postService.validatePostList(postIds);
|
||||
}
|
||||
return user;
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user