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