1. 修复 databus 在多层嵌套的 json 报文,签名存在异常的 bug
This commit is contained in:
@@ -76,4 +76,7 @@ public class DeptSaveReqVO {
|
|||||||
@Schema(description = "部门来源类型", example = "1")
|
@Schema(description = "部门来源类型", example = "1")
|
||||||
private Integer deptSource;
|
private Integer deptSource;
|
||||||
|
|
||||||
|
@Schema(description = "内部使用:延迟生成部门编码", hidden = true)
|
||||||
|
private Boolean delayCodeGeneration;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,8 +94,9 @@ public class UserController {
|
|||||||
|
|
||||||
@GetMapping({"/list-all-simple", "/simple-list"})
|
@GetMapping({"/list-all-simple", "/simple-list"})
|
||||||
@Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项")
|
@Operation(summary = "获取用户精简信息列表", description = "只包含被开启的用户,主要用于前端的下拉选项")
|
||||||
public CommonResult<List<UserSimpleRespVO>> getSimpleUserList() {
|
public CommonResult<List<UserSimpleRespVO>> getSimpleUserList(
|
||||||
List<AdminUserDO> list = userService.getUserListByStatus(CommonStatusEnum.ENABLE.getStatus(), SIMPLE_LIST_LIMIT);
|
@RequestParam(value = "keyword", required = false) String keyword) {
|
||||||
|
List<AdminUserDO> list = userService.getUserListByStatus(CommonStatusEnum.ENABLE.getStatus(), SIMPLE_LIST_LIMIT, keyword);
|
||||||
return success(UserConvert.INSTANCE.convertSimpleList(list));
|
return success(UserConvert.INSTANCE.convertSimpleList(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ public class UserPageReqVO extends PageParam {
|
|||||||
@Schema(description = "用户账号,模糊匹配", example = "zt")
|
@Schema(description = "用户账号,模糊匹配", example = "zt")
|
||||||
private String username;
|
private String username;
|
||||||
|
|
||||||
|
@Schema(description = "用户昵称,模糊匹配", example = "张三")
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
@Schema(description = "工号,模糊匹配", example = "A00123")
|
@Schema(description = "工号,模糊匹配", example = "A00123")
|
||||||
private String workcode;
|
private String workcode;
|
||||||
|
|
||||||
|
|||||||
@@ -114,12 +114,15 @@ public interface DeptMapper extends BaseMapperX<DeptDO> {
|
|||||||
* @param parentId 父部门ID
|
* @param parentId 父部门ID
|
||||||
* @return 编码最大的子部门
|
* @return 编码最大的子部门
|
||||||
*/
|
*/
|
||||||
default DeptDO selectLastChildByCode(Long parentId) {
|
default DeptDO selectLastChildByCode(Long parentId, String prefix) {
|
||||||
return selectOne(new LambdaQueryWrapper<DeptDO>()
|
LambdaQueryWrapper<DeptDO> wrapper = new LambdaQueryWrapper<DeptDO>()
|
||||||
.eq(DeptDO::getParentId, parentId)
|
.eq(DeptDO::getParentId, parentId)
|
||||||
.isNotNull(DeptDO::getCode)
|
.isNotNull(DeptDO::getCode);
|
||||||
.orderByDesc(DeptDO::getCode)
|
if (StrUtil.isNotBlank(prefix)) {
|
||||||
.last("LIMIT 1"));
|
wrapper.likeRight(DeptDO::getCode, prefix);
|
||||||
|
}
|
||||||
|
wrapper.orderByDesc(DeptDO::getCode).last("LIMIT 1");
|
||||||
|
return selectOne(wrapper);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
|
|||||||
MPJLambdaWrapperX<AdminUserDO> query = new MPJLambdaWrapperX<>();
|
MPJLambdaWrapperX<AdminUserDO> query = new MPJLambdaWrapperX<>();
|
||||||
query.leftJoin(UserDeptDO.class, UserDeptDO::getUserId, AdminUserDO::getId);
|
query.leftJoin(UserDeptDO.class, UserDeptDO::getUserId, AdminUserDO::getId);
|
||||||
query.likeIfPresent(AdminUserDO::getUsername, reqVO.getUsername());
|
query.likeIfPresent(AdminUserDO::getUsername, reqVO.getUsername());
|
||||||
|
query.likeIfPresent(AdminUserDO::getNickname, reqVO.getNickname());
|
||||||
query.likeIfPresent(AdminUserDO::getWorkcode, reqVO.getWorkcode());
|
query.likeIfPresent(AdminUserDO::getWorkcode, reqVO.getWorkcode());
|
||||||
query.likeIfPresent(AdminUserDO::getMobile, reqVO.getMobile());
|
query.likeIfPresent(AdminUserDO::getMobile, reqVO.getMobile());
|
||||||
query.eqIfPresent(AdminUserDO::getStatus, reqVO.getStatus());
|
query.eqIfPresent(AdminUserDO::getStatus, reqVO.getStatus());
|
||||||
@@ -70,9 +71,16 @@ public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {
|
|||||||
return selectList(new LambdaQueryWrapperX<AdminUserDO>().like(AdminUserDO::getNickname, nickname));
|
return selectList(new LambdaQueryWrapperX<AdminUserDO>().like(AdminUserDO::getNickname, nickname));
|
||||||
}
|
}
|
||||||
|
|
||||||
default List<AdminUserDO> selectListByStatus(Integer status, Integer limit) {
|
default List<AdminUserDO> selectListByStatus(Integer status, Integer limit, String keyword) {
|
||||||
LambdaQueryWrapperX<AdminUserDO> query = new LambdaQueryWrapperX<AdminUserDO>()
|
LambdaQueryWrapperX<AdminUserDO> query = new LambdaQueryWrapperX<AdminUserDO>()
|
||||||
.eq(AdminUserDO::getStatus, status);
|
.eq(AdminUserDO::getStatus, status);
|
||||||
|
if (StrUtil.isNotBlank(keyword)) {
|
||||||
|
String trimmed = keyword.trim();
|
||||||
|
query.and(w -> w.like(AdminUserDO::getNickname, trimmed)
|
||||||
|
.or().like(AdminUserDO::getUsername, trimmed)
|
||||||
|
.or().like(AdminUserDO::getMobile, trimmed)
|
||||||
|
.or().like(AdminUserDO::getWorkcode, trimmed));
|
||||||
|
}
|
||||||
if (limit != null && limit > 0) {
|
if (limit != null && limit > 0) {
|
||||||
query.last("LIMIT " + limit);
|
query.last("LIMIT " + limit);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import cn.hutool.core.collection.CollUtil;
|
|||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import com.google.common.annotations.VisibleForTesting;
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
import com.zt.plat.framework.common.biz.system.permission.dto.DeptDataPermissionRespDTO;
|
||||||
import com.zt.plat.framework.common.enums.CommonStatusEnum;
|
import com.zt.plat.framework.common.enums.CommonStatusEnum;
|
||||||
import com.zt.plat.framework.common.pojo.CompanyDeptInfo;
|
import com.zt.plat.framework.common.pojo.CompanyDeptInfo;
|
||||||
import com.zt.plat.framework.common.util.object.BeanUtils;
|
import com.zt.plat.framework.common.util.object.BeanUtils;
|
||||||
@@ -11,18 +12,13 @@ import com.zt.plat.framework.datapermission.core.annotation.DataPermission;
|
|||||||
import com.zt.plat.framework.tenant.core.aop.TenantIgnore;
|
import com.zt.plat.framework.tenant.core.aop.TenantIgnore;
|
||||||
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
||||||
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
|
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
|
||||||
import com.zt.plat.module.system.controller.admin.dict.vo.data.DictDataSaveReqVO;
|
|
||||||
import com.zt.plat.module.system.controller.admin.dict.vo.type.DictTypeSaveReqVO;
|
|
||||||
import com.zt.plat.module.system.dal.dataobject.dept.DeptDO;
|
import com.zt.plat.module.system.dal.dataobject.dept.DeptDO;
|
||||||
import com.zt.plat.module.system.dal.dataobject.dict.DictTypeDO;
|
|
||||||
import com.zt.plat.module.system.dal.dataobject.userdept.UserDeptDO;
|
import com.zt.plat.module.system.dal.dataobject.userdept.UserDeptDO;
|
||||||
import com.zt.plat.module.system.dal.mysql.dept.DeptMapper;
|
import com.zt.plat.module.system.dal.mysql.dept.DeptMapper;
|
||||||
import com.zt.plat.module.system.dal.mysql.userdept.UserDeptMapper;
|
import com.zt.plat.module.system.dal.mysql.userdept.UserDeptMapper;
|
||||||
import com.zt.plat.module.system.dal.redis.RedisKeyConstants;
|
import com.zt.plat.module.system.dal.redis.RedisKeyConstants;
|
||||||
import com.zt.plat.module.system.enums.dept.DeptSourceEnum;
|
import com.zt.plat.module.system.enums.dept.DeptSourceEnum;
|
||||||
import com.zt.plat.module.system.enums.DictTypeConstants;
|
import com.zt.plat.module.system.service.permission.PermissionService;
|
||||||
import com.zt.plat.module.system.service.dict.DictDataService;
|
|
||||||
import com.zt.plat.module.system.service.dict.DictTypeService;
|
|
||||||
import org.apache.seata.spring.annotation.GlobalTransactional;
|
import org.apache.seata.spring.annotation.GlobalTransactional;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
@@ -57,17 +53,15 @@ public class DeptServiceImpl implements DeptService {
|
|||||||
@Resource
|
@Resource
|
||||||
private UserDeptMapper userDeptMapper;
|
private UserDeptMapper userDeptMapper;
|
||||||
@Resource
|
@Resource
|
||||||
|
private PermissionService permissionService;
|
||||||
|
@Resource
|
||||||
private com.zt.plat.module.system.mq.producer.databus.DatabusChangeProducer databusChangeProducer;
|
private com.zt.plat.module.system.mq.producer.databus.DatabusChangeProducer databusChangeProducer;
|
||||||
@Resource
|
|
||||||
private DeptExternalCodeService deptExternalCodeService;
|
|
||||||
@Resource
|
|
||||||
private DictTypeService dictTypeService;
|
|
||||||
@Resource
|
|
||||||
private DictDataService dictDataService;
|
|
||||||
|
|
||||||
private static final String ROOT_CODE_PREFIX = "ZT";
|
private static final String ROOT_CODE_PREFIX = "ZT";
|
||||||
|
private static final String EXTERNAL_CODE_PREFIX = "CU";
|
||||||
private static final int CODE_SEGMENT_LENGTH = 3;
|
private static final int CODE_SEGMENT_LENGTH = 3;
|
||||||
private static final int MAX_SEQUENCE = 999;
|
private static final int MAX_SEQUENCE = 999;
|
||||||
|
private static final int BATCH_SIZE = 1000;
|
||||||
private static final Comparator<DeptDO> DEPT_COMPARATOR = Comparator
|
private static final Comparator<DeptDO> DEPT_COMPARATOR = Comparator
|
||||||
.comparing(DeptDO::getSort, Comparator.nullsLast(Comparator.naturalOrder()))
|
.comparing(DeptDO::getSort, Comparator.nullsLast(Comparator.naturalOrder()))
|
||||||
.thenComparing(DeptDO::getId, Comparator.nullsLast(Comparator.naturalOrder()));
|
.thenComparing(DeptDO::getId, Comparator.nullsLast(Comparator.naturalOrder()));
|
||||||
@@ -82,27 +76,38 @@ public class DeptServiceImpl implements DeptService {
|
|||||||
createReqVO.setParentId(normalizeParentId(createReqVO.getParentId()));
|
createReqVO.setParentId(normalizeParentId(createReqVO.getParentId()));
|
||||||
// 创建时默认有效
|
// 创建时默认有效
|
||||||
createReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
createReqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
// 默认部门来源:未指定时视为外部部门
|
||||||
|
if (createReqVO.getDeptSource() == null) {
|
||||||
|
createReqVO.setDeptSource(DeptSourceEnum.EXTERNAL.getSource());
|
||||||
|
}
|
||||||
// 校验父部门的有效性
|
// 校验父部门的有效性
|
||||||
validateParentDept(null, createReqVO.getParentId());
|
validateParentDept(null, createReqVO.getParentId());
|
||||||
// 校验部门名的唯一性
|
// 校验部门名的唯一性
|
||||||
validateDeptNameUnique(null, createReqVO.getParentId(), createReqVO.getName());
|
validateDeptNameUnique(null, createReqVO.getParentId(), createReqVO.getName());
|
||||||
// 生成并校验部门编码
|
// 生成并校验部门编码
|
||||||
Long effectiveParentId = normalizeParentId(createReqVO.getParentId());
|
boolean isIWorkSource = Objects.equals(createReqVO.getDeptSource(), DeptSourceEnum.IWORK.getSource());
|
||||||
String resolvedCode = generateDeptCode(effectiveParentId);
|
if (isIWorkSource) {
|
||||||
validateDeptCodeUnique(null, resolvedCode);
|
// iWork 来源直接使用提供的编码,不再生成
|
||||||
createReqVO.setCode(resolvedCode);
|
String providedCode = StrUtil.blankToDefault(createReqVO.getCode(), null);
|
||||||
|
createReqVO.setCode(providedCode);
|
||||||
|
} else {
|
||||||
|
if (Boolean.TRUE.equals(createReqVO.getDelayCodeGeneration())) {
|
||||||
|
createReqVO.setCode(null);
|
||||||
|
} else {
|
||||||
|
String resolvedCode = generateDeptCode(createReqVO.getParentId(), createReqVO.getDeptSource());
|
||||||
|
validateDeptCodeUnique(null, resolvedCode);
|
||||||
|
createReqVO.setCode(resolvedCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 插入部门
|
// 插入部门
|
||||||
DeptDO dept = BeanUtils.toBean(createReqVO, DeptDO.class);
|
DeptDO dept = BeanUtils.toBean(createReqVO, DeptDO.class);
|
||||||
// 设置部门来源:如果未指定,默认为外部部门
|
// 设置部门来源(前置已默认化,此处兜底)
|
||||||
if (dept.getDeptSource() == null) {
|
if (dept.getDeptSource() == null) {
|
||||||
dept.setDeptSource(DeptSourceEnum.EXTERNAL.getSource());
|
dept.setDeptSource(DeptSourceEnum.EXTERNAL.getSource());
|
||||||
}
|
}
|
||||||
deptMapper.insert(dept);
|
deptMapper.insert(dept);
|
||||||
|
|
||||||
// 维护外部系统编码映射(若有传入)
|
|
||||||
upsertExternalCodeMapping(createReqVO, dept.getId());
|
|
||||||
|
|
||||||
// 发布部门创建事件
|
// 发布部门创建事件
|
||||||
databusChangeProducer.sendDeptCreatedMessage(dept);
|
databusChangeProducer.sendDeptCreatedMessage(dept);
|
||||||
|
|
||||||
@@ -122,17 +127,29 @@ public class DeptServiceImpl implements DeptService {
|
|||||||
validateParentDept(updateReqVO.getId(), updateReqVO.getParentId());
|
validateParentDept(updateReqVO.getId(), updateReqVO.getParentId());
|
||||||
// 校验部门名的唯一性
|
// 校验部门名的唯一性
|
||||||
validateDeptNameUnique(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName());
|
validateDeptNameUnique(updateReqVO.getId(), updateReqVO.getParentId(), updateReqVO.getName());
|
||||||
Long newParentId = normalizeParentId(updateReqVO.getParentId());
|
boolean isIWorkSource = Objects.equals(originalDept.getDeptSource(), DeptSourceEnum.IWORK.getSource());
|
||||||
Long oldParentId = normalizeParentId(originalDept.getParentId());
|
if (isIWorkSource) {
|
||||||
boolean parentChanged = !Objects.equals(newParentId, oldParentId);
|
// iWork 来源直接使用提供的编码,不再生成
|
||||||
String existingCode = originalDept.getCode();
|
String providedCode = StrUtil.blankToDefault(updateReqVO.getCode(), originalDept.getCode());
|
||||||
boolean needRegenerateCode = StrUtil.isBlank(existingCode);
|
updateReqVO.setCode(providedCode);
|
||||||
String resolvedCode = existingCode;
|
} else {
|
||||||
if (needRegenerateCode) {
|
Integer source = ObjectUtil.defaultIfNull(updateReqVO.getDeptSource(), originalDept.getDeptSource());
|
||||||
resolvedCode = generateDeptCode(newParentId);
|
if (source == null) {
|
||||||
validateDeptCodeUnique(updateReqVO.getId(), resolvedCode);
|
source = DeptSourceEnum.EXTERNAL.getSource();
|
||||||
|
}
|
||||||
|
String existingCode = originalDept.getCode();
|
||||||
|
if (StrUtil.isBlank(existingCode)) {
|
||||||
|
if (Boolean.TRUE.equals(updateReqVO.getDelayCodeGeneration())) {
|
||||||
|
updateReqVO.setCode(null);
|
||||||
|
} else {
|
||||||
|
String newCode = generateDeptCode(updateReqVO.getParentId(), source);
|
||||||
|
validateDeptCodeUnique(updateReqVO.getId(), newCode);
|
||||||
|
updateReqVO.setCode(newCode);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
updateReqVO.setCode(existingCode);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
updateReqVO.setCode(resolvedCode);
|
|
||||||
|
|
||||||
// 更新部门
|
// 更新部门
|
||||||
DeptDO updateObj = BeanUtils.toBean(updateReqVO, DeptDO.class);
|
DeptDO updateObj = BeanUtils.toBean(updateReqVO, DeptDO.class);
|
||||||
@@ -144,12 +161,6 @@ public class DeptServiceImpl implements DeptService {
|
|||||||
databusChangeProducer.sendDeptUpdatedMessage(updatedDept);
|
databusChangeProducer.sendDeptUpdatedMessage(updatedDept);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (needRegenerateCode) {
|
|
||||||
refreshChildCodesRecursively(updateObj.getId(), updateReqVO.getCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 维护外部系统编码映射(若有传入)
|
|
||||||
upsertExternalCodeMapping(updateReqVO, updateReqVO.getId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -167,9 +178,6 @@ public class DeptServiceImpl implements DeptService {
|
|||||||
DeptDO dept = deptMapper.selectById(id);
|
DeptDO dept = deptMapper.selectById(id);
|
||||||
Long tenantId = (dept != null) ? dept.getTenantId() : null;
|
Long tenantId = (dept != null) ? dept.getTenantId() : null;
|
||||||
|
|
||||||
// 级联删除外部编码映射并清理缓存
|
|
||||||
deptExternalCodeService.deleteDeptExternalCodesByDeptId(id);
|
|
||||||
|
|
||||||
// 删除部门
|
// 删除部门
|
||||||
deptMapper.deleteById(id);
|
deptMapper.deleteById(id);
|
||||||
|
|
||||||
@@ -268,26 +276,16 @@ public class DeptServiceImpl implements DeptService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String generateDeptCode(Long parentId) {
|
private String generateDeptCode(Long parentId, Integer deptSource) {
|
||||||
Long effectiveParentId = normalizeParentId(parentId);
|
Long effectiveParentId = normalizeParentId(parentId);
|
||||||
Long codeParentId = effectiveParentId;
|
String prefix = resolveCodePrefix(effectiveParentId, deptSource);
|
||||||
String prefix = ROOT_CODE_PREFIX;
|
int nextSequence = determineNextSequence(effectiveParentId, prefix);
|
||||||
if (!DeptDO.PARENT_ID_ROOT.equals(effectiveParentId)) {
|
|
||||||
DeptDO parentDept = deptMapper.selectById(effectiveParentId);
|
|
||||||
if (parentDept == null || StrUtil.isBlank(parentDept.getCode())) {
|
|
||||||
codeParentId = DeptDO.PARENT_ID_ROOT;
|
|
||||||
} else {
|
|
||||||
prefix = parentDept.getCode();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int nextSequence = determineNextSequence(codeParentId, prefix);
|
|
||||||
assertSequenceRange(nextSequence);
|
assertSequenceRange(nextSequence);
|
||||||
return prefix + formatSequence(nextSequence);
|
return prefix + formatSequence(nextSequence);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int determineNextSequence(Long parentId, String prefix) {
|
private int determineNextSequence(Long parentId, String prefix) {
|
||||||
DeptDO lastChild = deptMapper.selectLastChildByCode(parentId);
|
DeptDO lastChild = deptMapper.selectLastChildByCode(parentId, prefix);
|
||||||
Integer sequence = parseSequence(lastChild != null ? lastChild.getCode() : null, prefix);
|
Integer sequence = parseSequence(lastChild != null ? lastChild.getCode() : null, prefix);
|
||||||
if (sequence != null) {
|
if (sequence != null) {
|
||||||
return sequence + 1;
|
return sequence + 1;
|
||||||
@@ -365,12 +363,36 @@ public class DeptServiceImpl implements DeptService {
|
|||||||
candidate = candidate.trim();
|
candidate = candidate.trim();
|
||||||
}
|
}
|
||||||
if (StrUtil.isBlank(candidate)) {
|
if (StrUtil.isBlank(candidate)) {
|
||||||
candidate = generateDeptCode(DeptDO.PARENT_ID_ROOT);
|
candidate = generateDeptCode(DeptDO.PARENT_ID_ROOT, DeptSourceEnum.EXTERNAL.getSource());
|
||||||
}
|
}
|
||||||
validateDeptCodeUnique(currentDeptId, candidate);
|
validateDeptCodeUnique(currentDeptId, candidate);
|
||||||
return candidate;
|
return candidate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String resolveCodePrefix(Long parentId, Integer deptSource) {
|
||||||
|
boolean isExternal = Objects.equals(deptSource, DeptSourceEnum.EXTERNAL.getSource());
|
||||||
|
if (DeptDO.PARENT_ID_ROOT.equals(parentId)) {
|
||||||
|
return isExternal ? EXTERNAL_CODE_PREFIX : ROOT_CODE_PREFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeptDO parentDept = deptMapper.selectById(parentId);
|
||||||
|
if (parentDept == null || StrUtil.isBlank(parentDept.getCode())) {
|
||||||
|
return isExternal ? EXTERNAL_CODE_PREFIX : ROOT_CODE_PREFIX;
|
||||||
|
}
|
||||||
|
|
||||||
|
String parentCode = parentDept.getCode();
|
||||||
|
if (isExternal) {
|
||||||
|
if (parentCode.startsWith(EXTERNAL_CODE_PREFIX)) {
|
||||||
|
return parentCode;
|
||||||
|
}
|
||||||
|
if (parentCode.startsWith(ROOT_CODE_PREFIX)) {
|
||||||
|
return EXTERNAL_CODE_PREFIX + parentCode.substring(ROOT_CODE_PREFIX.length());
|
||||||
|
}
|
||||||
|
return EXTERNAL_CODE_PREFIX;
|
||||||
|
}
|
||||||
|
return parentCode;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DeptDO getDept(Long id) {
|
public DeptDO getDept(Long id) {
|
||||||
return deptMapper.selectById(id);
|
return deptMapper.selectById(id);
|
||||||
@@ -558,37 +580,59 @@ public class DeptServiceImpl implements DeptService {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<DeptDO> getTopLevelDeptList() {
|
public List<DeptDO> getTopLevelDeptList() {
|
||||||
// 获取当前用户所属的部门列表
|
Long loginUserId = getLoginUserId();
|
||||||
Set<Long> deptIds = userDeptMapper.selectValidListByUserIds(singleton(getLoginUserId()))
|
|
||||||
.stream()
|
// 当前用户所属部门
|
||||||
.map(UserDeptDO::getDeptId)
|
Set<Long> userDeptIds = Optional.ofNullable(userDeptMapper.selectValidListByUserIds(singleton(loginUserId)))
|
||||||
.collect(Collectors.toSet());
|
.orElseGet(Collections::emptyList)
|
||||||
|
.stream()
|
||||||
|
.map(UserDeptDO::getDeptId)
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
// 数据权限部门
|
||||||
|
DeptDataPermissionRespDTO dataPerm = permissionService.getDeptDataPermission(loginUserId);
|
||||||
|
Set<Long> permDeptIds = Optional.ofNullable(dataPerm)
|
||||||
|
.map(DeptDataPermissionRespDTO::getDeptIds)
|
||||||
|
.orElse(Collections.emptySet());
|
||||||
|
|
||||||
|
// all=true 直接返回根级启用部门
|
||||||
|
if (dataPerm != null && Boolean.TRUE.equals(dataPerm.getAll())) {
|
||||||
|
List<DeptDO> roots = deptMapper.selectListByParentId(DeptDO.PARENT_ID_ROOT, CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
roots.sort(DEPT_COMPARATOR);
|
||||||
|
return roots;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 合并两类部门 ID,仅在并集为空时返回空
|
||||||
|
Set<Long> deptIds = new HashSet<>();
|
||||||
|
deptIds.addAll(userDeptIds);
|
||||||
|
deptIds.addAll(Optional.ofNullable(permDeptIds).orElse(Collections.emptySet()));
|
||||||
|
|
||||||
if (CollUtil.isEmpty(deptIds)) {
|
if (CollUtil.isEmpty(deptIds)) {
|
||||||
// 如果用户没有关联任何部门,返回空列表
|
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 获取用户所属部门的最顶层祖先部门
|
// 缓存已加载的部门,避免重复 IO
|
||||||
Set<Long> topLevelDeptIds = new HashSet<>();
|
Map<Long, DeptDO> deptCache = new HashMap<>();
|
||||||
for (Long deptId : deptIds) {
|
|
||||||
DeptDO dept = getDept(deptId);
|
// 批量解析最顶层祖先(到 ROOT 或上级禁用即停),减少循环 IO
|
||||||
if (dept != null && CommonStatusEnum.ENABLE.getStatus().equals(dept.getStatus())) {
|
Map<Long, Long> topLevelMap = findTopLevelAncestorIdsBatch(deptIds, deptCache);
|
||||||
// 找到该部门的最顶层祖先
|
|
||||||
DeptDO topLevelDept = findTopLevelAncestor(dept);
|
// 汇总顶层部门 ID 并取实体(使用缓存避免再查)
|
||||||
if (topLevelDept != null) {
|
Set<Long> topLevelDeptIds = topLevelMap.values().stream()
|
||||||
topLevelDeptIds.add(topLevelDept.getId());
|
.filter(Objects::nonNull)
|
||||||
}
|
.collect(Collectors.toSet());
|
||||||
}
|
|
||||||
}
|
List<DeptDO> topLevelDepts = topLevelDeptIds.stream()
|
||||||
|
.map(id -> deptCache.computeIfAbsent(id, this::getDept))
|
||||||
// 根据顶层部门ID获取部门详情
|
.filter(Objects::nonNull)
|
||||||
return topLevelDeptIds.stream()
|
.filter(dept -> CommonStatusEnum.ENABLE.getStatus().equals(dept.getStatus()))
|
||||||
.map(this::getDept)
|
.distinct()
|
||||||
.filter(Objects::nonNull)
|
.collect(Collectors.toList());
|
||||||
.filter(dept -> CommonStatusEnum.ENABLE.getStatus().equals(dept.getStatus()))
|
|
||||||
.distinct()
|
// 按 sort(nullsLast)再按 id 排序
|
||||||
.collect(Collectors.toList());
|
topLevelDepts.sort(DEPT_COMPARATOR);
|
||||||
|
return topLevelDepts;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -741,64 +785,111 @@ public class DeptServiceImpl implements DeptService {
|
|||||||
return dept;
|
return dept;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void upsertExternalCodeMapping(DeptSaveReqVO reqVO, Long deptId) {
|
/**
|
||||||
if (reqVO == null || deptId == null) {
|
* 批量查找部门的最顶层祖先(到 ROOT 或遇到禁用/缺失的父部门即停止)
|
||||||
return;
|
* 使用 1000 条分片批量查询,减少循环 IO
|
||||||
|
*
|
||||||
|
* @param deptIds 待解析的部门 ID 集合
|
||||||
|
* @param deptCache 部门缓存(可复用外部缓存)
|
||||||
|
* @return 原始部门 ID -> 顶层祖先部门 ID 映射(若未找到则为 null)
|
||||||
|
*/
|
||||||
|
private Map<Long, Long> findTopLevelAncestorIdsBatch(Set<Long> deptIds, Map<Long, DeptDO> deptCache) {
|
||||||
|
Map<Long, Long> result = new HashMap<>();
|
||||||
|
if (CollUtil.isEmpty(deptIds)) {
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
String systemCode = StrUtil.trimToNull(reqVO.getExternalSystemCode());
|
|
||||||
String externalCode = StrUtil.trimToNull(reqVO.getExternalDeptCode());
|
// 当前指针:原始部门 -> 当前向上追溯的部门 ID
|
||||||
if (StrUtil.isBlank(systemCode) || StrUtil.isBlank(externalCode)) {
|
Map<Long, Long> cursorMap = new HashMap<>();
|
||||||
return;
|
for (Long id : deptIds) {
|
||||||
|
cursorMap.put(id, id);
|
||||||
}
|
}
|
||||||
// 缺失的外部系统字典类型或数据会自动补齐
|
|
||||||
ensureExternalSystemDict(systemCode);
|
// 预先加载首批部门
|
||||||
deptExternalCodeService.saveOrUpdateDeptExternalCode(
|
loadDeptBatch(cursorMap.values(), deptCache);
|
||||||
deptId,
|
|
||||||
systemCode,
|
int safety = 0;
|
||||||
externalCode,
|
while (!cursorMap.isEmpty() && safety++ < Short.MAX_VALUE) {
|
||||||
reqVO.getExternalDeptName(),
|
// 收集本轮需要加载的父部门 ID(避免重复加载)
|
||||||
CommonStatusEnum.ENABLE.getStatus());
|
Set<Long> parentIdsToLoad = new HashSet<>();
|
||||||
|
for (Long currentId : cursorMap.values()) {
|
||||||
|
DeptDO current = deptCache.get(currentId);
|
||||||
|
if (current == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Long parentId = current.getParentId();
|
||||||
|
if (parentId != null && !DeptDO.PARENT_ID_ROOT.equals(parentId) && !deptCache.containsKey(parentId)) {
|
||||||
|
parentIdsToLoad.add(parentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
loadDeptBatch(parentIdsToLoad, deptCache);
|
||||||
|
|
||||||
|
// 遍历当前指针,决定是否上卷或结束
|
||||||
|
Iterator<Map.Entry<Long, Long>> iterator = cursorMap.entrySet().iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
Map.Entry<Long, Long> entry = iterator.next();
|
||||||
|
Long originalId = entry.getKey();
|
||||||
|
Long currentId = entry.getValue();
|
||||||
|
DeptDO current = deptCache.get(currentId);
|
||||||
|
|
||||||
|
if (current == null) {
|
||||||
|
result.put(originalId, null);
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Long parentId = current.getParentId();
|
||||||
|
if (parentId == null || DeptDO.PARENT_ID_ROOT.equals(parentId)) {
|
||||||
|
// 已到达 ROOT(顶层)
|
||||||
|
result.put(originalId, current.getId());
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
DeptDO parent = deptCache.get(parentId);
|
||||||
|
if (parent == null || !CommonStatusEnum.ENABLE.getStatus().equals(parent.getStatus())) {
|
||||||
|
// 父部门缺失或禁用,则当前部门视为顶层
|
||||||
|
result.put(originalId, current.getId());
|
||||||
|
iterator.remove();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 向上继续追溯
|
||||||
|
entry.setValue(parentId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 确保外部系统字典存在(含字典类型与对应值),若缺失则自动创建
|
* 将给定的部门 ID 集合按批次加载到缓存
|
||||||
*/
|
*/
|
||||||
private void ensureExternalSystemDict(String systemCode) {
|
private void loadDeptBatch(Collection<Long> ids, Map<Long, DeptDO> deptCache) {
|
||||||
String normalizedCode = StrUtil.trimToNull(systemCode);
|
if (CollUtil.isEmpty(ids)) {
|
||||||
if (normalizedCode == null) {
|
return;
|
||||||
|
}
|
||||||
|
List<Long> toLoad = ids.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.filter(id -> !deptCache.containsKey(id))
|
||||||
|
.distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (CollUtil.isEmpty(toLoad)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
DictTypeDO dictType = dictTypeService.getDictType(DictTypeConstants.DEPT_EXTERNAL_SYSTEM);
|
|
||||||
if (dictType == null) {
|
|
||||||
DictTypeSaveReqVO typeReq = new DictTypeSaveReqVO();
|
|
||||||
typeReq.setName("部门外部系统标识");
|
|
||||||
typeReq.setType(DictTypeConstants.DEPT_EXTERNAL_SYSTEM);
|
|
||||||
typeReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
|
||||||
typeReq.setRemark("外部组织同步自动创建");
|
|
||||||
dictTypeService.createDictType(typeReq);
|
|
||||||
} else if (!CommonStatusEnum.ENABLE.getStatus().equals(dictType.getStatus())) {
|
|
||||||
DictTypeSaveReqVO updateReq = new DictTypeSaveReqVO();
|
|
||||||
updateReq.setId(dictType.getId());
|
|
||||||
updateReq.setName(dictType.getName());
|
|
||||||
updateReq.setType(dictType.getType());
|
|
||||||
updateReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
|
||||||
updateReq.setRemark(dictType.getRemark());
|
|
||||||
dictTypeService.updateDictType(updateReq);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dictDataService.getDictData(DictTypeConstants.DEPT_EXTERNAL_SYSTEM, normalizedCode) == null) {
|
for (int i = 0; i < toLoad.size(); i += BATCH_SIZE) {
|
||||||
DictDataSaveReqVO dataReq = new DictDataSaveReqVO();
|
int end = Math.min(i + BATCH_SIZE, toLoad.size());
|
||||||
dataReq.setDictType(DictTypeConstants.DEPT_EXTERNAL_SYSTEM);
|
List<Long> batch = toLoad.subList(i, end);
|
||||||
dataReq.setLabel(normalizedCode);
|
List<DeptDO> depts = getDeptList(batch);
|
||||||
dataReq.setValue(normalizedCode);
|
if (CollUtil.isEmpty(depts)) {
|
||||||
dataReq.setSort(0);
|
continue;
|
||||||
dataReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
}
|
||||||
dataReq.setRemark("外部组织同步自动创建");
|
for (DeptDO dept : depts) {
|
||||||
dictDataService.createDictData(dataReq);
|
if (dept != null && dept.getId() != null) {
|
||||||
|
deptCache.putIfAbsent(dept.getId(), dept);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
|
||||||
log.warn("[Dept] Ensure external system dict failed, systemCode={}", normalizedCode, ex);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
|||||||
}
|
}
|
||||||
result.increasePulled(records.size());
|
result.increasePulled(records.size());
|
||||||
List<IWorkHrSubcompanyPageRespVO.Subcompany> queue = new ArrayList<>(records);
|
List<IWorkHrSubcompanyPageRespVO.Subcompany> queue = new ArrayList<>(records);
|
||||||
|
Set<Long> readyParentIds = new HashSet<>();
|
||||||
int guard = 0;
|
int guard = 0;
|
||||||
int maxPasses = Math.max(1, queue.size() * 2);
|
int maxPasses = Math.max(1, queue.size() * 2);
|
||||||
while (!queue.isEmpty() && guard++ < maxPasses) {
|
while (!queue.isEmpty() && guard++ < maxPasses) {
|
||||||
@@ -79,6 +80,9 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
|||||||
}
|
}
|
||||||
Long deptId = externalId.longValue();
|
Long deptId = externalId.longValue();
|
||||||
ParentHolder parentHolder = resolveSubcompanyParent(sub.getSupsubcomid());
|
ParentHolder parentHolder = resolveSubcompanyParent(sub.getSupsubcomid());
|
||||||
|
if (!isParentReady(parentHolder.parentId(), readyParentIds)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
boolean canceled = isCanceledFlag(sub.getCanceled());
|
boolean canceled = isCanceledFlag(sub.getCanceled());
|
||||||
DeptSaveReqVO saveReq = buildSubcompanySaveReq(sub, deptId, parentHolder.parentId(), canceled);
|
DeptSaveReqVO saveReq = buildSubcompanySaveReq(sub, deptId, parentHolder.parentId(), canceled);
|
||||||
try {
|
try {
|
||||||
@@ -87,6 +91,9 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
|||||||
canceled,
|
canceled,
|
||||||
options);
|
options);
|
||||||
applyDeptOutcome(result, outcome, "分部", sub.getSubcompanyname());
|
applyDeptOutcome(result, outcome, "分部", sub.getSubcompanyname());
|
||||||
|
if (outcome.deptId() != null) {
|
||||||
|
readyParentIds.add(outcome.deptId());
|
||||||
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.error("[iWork] 同步分部失败: id={} name={}", sub.getId(), sub.getSubcompanyname(), ex);
|
log.error("[iWork] 同步分部失败: id={} name={}", sub.getId(), sub.getSubcompanyname(), ex);
|
||||||
result.increaseFailed();
|
result.increaseFailed();
|
||||||
@@ -101,8 +108,19 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
|||||||
}
|
}
|
||||||
if (!queue.isEmpty()) {
|
if (!queue.isEmpty()) {
|
||||||
for (IWorkHrSubcompanyPageRespVO.Subcompany remaining : queue) {
|
for (IWorkHrSubcompanyPageRespVO.Subcompany remaining : queue) {
|
||||||
log.warn("[iWork] 分部因父级缺失未同步: id={} name={}", remaining.getId(), remaining.getSubcompanyname());
|
log.warn("[iWork] 分部父级缺失,延迟生成编码插入占位: id={} name={}", remaining.getId(), remaining.getSubcompanyname());
|
||||||
result.increaseFailed();
|
DeptSaveReqVO saveReq = buildSubcompanySaveReq(remaining,
|
||||||
|
remaining.getId() == null ? null : remaining.getId().longValue(),
|
||||||
|
resolveSubcompanyParent(remaining.getSupsubcomid()).parentId(),
|
||||||
|
isCanceledFlag(remaining.getCanceled()));
|
||||||
|
saveReq.setDelayCodeGeneration(true);
|
||||||
|
try {
|
||||||
|
DeptSyncOutcome outcome = upsertDept(saveReq.getId(), saveReq, isCanceledFlag(remaining.getCanceled()), options);
|
||||||
|
applyDeptOutcome(result, outcome, "分部", remaining.getSubcompanyname());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("[iWork] 分部占位插入失败: id={} name={}", remaining.getId(), remaining.getSubcompanyname(), ex);
|
||||||
|
result.increaseFailed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -117,6 +135,7 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
|||||||
}
|
}
|
||||||
result.increasePulled(records.size());
|
result.increasePulled(records.size());
|
||||||
List<IWorkHrDepartmentPageRespVO.Department> queue = new ArrayList<>(records);
|
List<IWorkHrDepartmentPageRespVO.Department> queue = new ArrayList<>(records);
|
||||||
|
Set<Long> readyParentIds = new HashSet<>();
|
||||||
int guard = 0;
|
int guard = 0;
|
||||||
int maxPasses = Math.max(1, queue.size() * 2);
|
int maxPasses = Math.max(1, queue.size() * 2);
|
||||||
while (!queue.isEmpty() && guard++ < maxPasses) {
|
while (!queue.isEmpty() && guard++ < maxPasses) {
|
||||||
@@ -139,6 +158,9 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
|||||||
}
|
}
|
||||||
Long deptId = externalId.longValue();
|
Long deptId = externalId.longValue();
|
||||||
ParentHolder parentHolder = resolveDepartmentParent(dept);
|
ParentHolder parentHolder = resolveDepartmentParent(dept);
|
||||||
|
if (!isParentReady(parentHolder.parentId(), readyParentIds)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
boolean canceled = isCanceledFlag(dept.getCanceled());
|
boolean canceled = isCanceledFlag(dept.getCanceled());
|
||||||
DeptSaveReqVO saveReq = buildDepartmentSaveReq(dept, deptId, parentHolder.parentId(), canceled);
|
DeptSaveReqVO saveReq = buildDepartmentSaveReq(dept, deptId, parentHolder.parentId(), canceled);
|
||||||
try {
|
try {
|
||||||
@@ -147,6 +169,9 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
|||||||
canceled,
|
canceled,
|
||||||
options);
|
options);
|
||||||
applyDeptOutcome(result, outcome, "部门", dept.getDepartmentname());
|
applyDeptOutcome(result, outcome, "部门", dept.getDepartmentname());
|
||||||
|
if (outcome.deptId() != null) {
|
||||||
|
readyParentIds.add(outcome.deptId());
|
||||||
|
}
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
log.error("[iWork] 同步部门失败: id={} name={}", dept.getId(), dept.getDepartmentname(), ex);
|
log.error("[iWork] 同步部门失败: id={} name={}", dept.getId(), dept.getDepartmentname(), ex);
|
||||||
result.increaseFailed();
|
result.increaseFailed();
|
||||||
@@ -161,8 +186,19 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
|||||||
}
|
}
|
||||||
if (!queue.isEmpty()) {
|
if (!queue.isEmpty()) {
|
||||||
for (IWorkHrDepartmentPageRespVO.Department remaining : queue) {
|
for (IWorkHrDepartmentPageRespVO.Department remaining : queue) {
|
||||||
log.warn("[iWork] 部门因父级缺失未同步: id={} name={}", remaining.getId(), remaining.getDepartmentname());
|
log.warn("[iWork] 部门父级缺失,延迟生成编码插入占位: id={} name={}", remaining.getId(), remaining.getDepartmentname());
|
||||||
result.increaseFailed();
|
DeptSaveReqVO saveReq = buildDepartmentSaveReq(remaining,
|
||||||
|
remaining.getId() == null ? null : remaining.getId().longValue(),
|
||||||
|
resolveDepartmentParent(remaining).parentId(),
|
||||||
|
isCanceledFlag(remaining.getCanceled()));
|
||||||
|
saveReq.setDelayCodeGeneration(true);
|
||||||
|
try {
|
||||||
|
DeptSyncOutcome outcome = upsertDept(saveReq.getId(), saveReq, isCanceledFlag(remaining.getCanceled()), options);
|
||||||
|
applyDeptOutcome(result, outcome, "部门", remaining.getDepartmentname());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("[iWork] 部门占位插入失败: id={} name={}", remaining.getId(), remaining.getDepartmentname(), ex);
|
||||||
|
result.increaseFailed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@@ -493,6 +529,16 @@ public class IWorkSyncProcessorImpl implements IWorkSyncProcessor {
|
|||||||
return new ParentHolder(DeptDO.PARENT_ID_ROOT);
|
return new ParentHolder(DeptDO.PARENT_ID_ROOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean isParentReady(Long parentId, Set<Long> readyParentIds) {
|
||||||
|
if (parentId == null || DeptDO.PARENT_ID_ROOT.equals(parentId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (readyParentIds.contains(parentId)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return deptService.getDept(parentId) != null;
|
||||||
|
}
|
||||||
|
|
||||||
private PostDO resolvePostByCode(String code) {
|
private PostDO resolvePostByCode(String code) {
|
||||||
String key = buildPostCacheKey(code);
|
String key = buildPostCacheKey(code);
|
||||||
PostDO cached = postCache.get(key);
|
PostDO cached = postCache.get(key);
|
||||||
|
|||||||
@@ -193,10 +193,14 @@ public interface AdminUserService {
|
|||||||
* @param status 状态
|
* @param status 状态
|
||||||
* @return 用户们
|
* @return 用户们
|
||||||
*/
|
*/
|
||||||
List<AdminUserDO> getUserListByStatus(Integer status, Integer limit);
|
List<AdminUserDO> getUserListByStatus(Integer status, Integer limit, String keyword);
|
||||||
|
|
||||||
|
default List<AdminUserDO> getUserListByStatus(Integer status, Integer limit) {
|
||||||
|
return getUserListByStatus(status, limit, null);
|
||||||
|
}
|
||||||
|
|
||||||
default List<AdminUserDO> getUserListByStatus(Integer status) {
|
default List<AdminUserDO> getUserListByStatus(Integer status) {
|
||||||
return getUserListByStatus(status, null);
|
return getUserListByStatus(status, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -664,8 +664,8 @@ public class AdminUserServiceImpl implements AdminUserService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<AdminUserDO> getUserListByStatus(Integer status, Integer limit) {
|
public List<AdminUserDO> getUserListByStatus(Integer status, Integer limit, String keyword) {
|
||||||
List<AdminUserDO> users = userMapper.selectListByStatus(status, limit);
|
List<AdminUserDO> users = userMapper.selectListByStatus(status, limit, keyword);
|
||||||
fillUserDeptInfo(users);
|
fillUserDeptInfo(users);
|
||||||
return users;
|
return users;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,23 +3,23 @@ package com.zt.plat.module.system.service.dept;
|
|||||||
import com.zt.plat.framework.common.enums.CommonStatusEnum;
|
import com.zt.plat.framework.common.enums.CommonStatusEnum;
|
||||||
import com.zt.plat.framework.common.util.object.ObjectUtils;
|
import com.zt.plat.framework.common.util.object.ObjectUtils;
|
||||||
import com.zt.plat.framework.test.core.ut.BaseDbUnitTest;
|
import com.zt.plat.framework.test.core.ut.BaseDbUnitTest;
|
||||||
|
import com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode.DeptExternalCodeSaveReqVO;
|
||||||
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptListReqVO;
|
||||||
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
|
import com.zt.plat.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
|
||||||
import com.zt.plat.module.system.controller.admin.dept.vo.depexternalcode.DeptExternalCodeSaveReqVO;
|
|
||||||
import com.zt.plat.module.system.dal.dataobject.dept.DeptDO;
|
import com.zt.plat.module.system.dal.dataobject.dept.DeptDO;
|
||||||
import com.zt.plat.module.system.dal.dataobject.dept.DeptExternalCodeDO;
|
import com.zt.plat.module.system.dal.dataobject.dept.DeptExternalCodeDO;
|
||||||
import com.zt.plat.module.system.dal.mysql.dept.DeptExternalCodeMapper;
|
import com.zt.plat.module.system.dal.mysql.dept.DeptExternalCodeMapper;
|
||||||
import com.zt.plat.module.system.dal.mysql.dept.DeptMapper;
|
import com.zt.plat.module.system.dal.mysql.dept.DeptMapper;
|
||||||
import com.zt.plat.module.system.service.dept.DeptExternalCodeServiceImpl;
|
|
||||||
import com.zt.plat.module.system.dal.redis.RedisKeyConstants;
|
import com.zt.plat.module.system.dal.redis.RedisKeyConstants;
|
||||||
|
import com.zt.plat.module.system.enums.dept.DeptSourceEnum;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.context.annotation.Import;
|
|
||||||
import org.springframework.cache.CacheManager;
|
|
||||||
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
|
||||||
import org.springframework.boot.test.context.TestConfiguration;
|
import org.springframework.boot.test.context.TestConfiguration;
|
||||||
|
import org.springframework.cache.CacheManager;
|
||||||
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
|
import org.springframework.cache.concurrent.ConcurrentMapCacheManager;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -69,7 +69,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
reqVO.setName(name);
|
reqVO.setName(name);
|
||||||
reqVO.setSort(sort);
|
reqVO.setSort(sort);
|
||||||
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
reqVO.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
reqVO.setDeptSource(1);
|
reqVO.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
reqVO.setIsCompany(false);
|
reqVO.setIsCompany(false);
|
||||||
reqVO.setIsGroup(false);
|
reqVO.setIsGroup(false);
|
||||||
return deptService.createDept(reqVO);
|
return deptService.createDept(reqVO);
|
||||||
@@ -83,7 +83,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
o.setParentId(DeptDO.PARENT_ID_ROOT);
|
o.setParentId(DeptDO.PARENT_ID_ROOT);
|
||||||
o.setStatus(randomCommonStatus());
|
o.setStatus(randomCommonStatus());
|
||||||
o.setCode(null);
|
o.setCode(null);
|
||||||
}).setDeptSource(1);
|
}).setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
Long deptId = deptService.createDept(reqVO);
|
Long deptId = deptService.createDept(reqVO);
|
||||||
@@ -119,7 +119,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
topLevelReq.setName("总部");
|
topLevelReq.setName("总部");
|
||||||
topLevelReq.setSort(1);
|
topLevelReq.setSort(1);
|
||||||
topLevelReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
topLevelReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
topLevelReq.setDeptSource(1);
|
topLevelReq.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
Long topLevelId = deptService.createDept(topLevelReq);
|
Long topLevelId = deptService.createDept(topLevelReq);
|
||||||
DeptDO firstTop = deptMapper.selectById(topLevelId);
|
DeptDO firstTop = deptMapper.selectById(topLevelId);
|
||||||
assertEquals("ZT001", firstTop.getCode());
|
assertEquals("ZT001", firstTop.getCode());
|
||||||
@@ -129,12 +129,117 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
secondTopLevelReq.setName("总部");
|
secondTopLevelReq.setName("总部");
|
||||||
secondTopLevelReq.setSort(2);
|
secondTopLevelReq.setSort(2);
|
||||||
secondTopLevelReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
secondTopLevelReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
secondTopLevelReq.setDeptSource(1);
|
secondTopLevelReq.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
Long secondTopId = deptService.createDept(secondTopLevelReq);
|
Long secondTopId = deptService.createDept(secondTopLevelReq);
|
||||||
DeptDO secondTop = deptMapper.selectById(secondTopId);
|
DeptDO secondTop = deptMapper.selectById(secondTopId);
|
||||||
assertEquals("ZT002", secondTop.getCode());
|
assertEquals("ZT002", secondTop.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateDept_externalUsesCuPrefixAndIndependentSequence() {
|
||||||
|
// 自建 EXTERNAL 顶级生成 CU001,且不受 ZT 序列影响
|
||||||
|
DeptSaveReqVO externalTop = new DeptSaveReqVO();
|
||||||
|
externalTop.setParentId(DeptDO.PARENT_ID_ROOT);
|
||||||
|
externalTop.setName("自建总部");
|
||||||
|
externalTop.setSort(1);
|
||||||
|
externalTop.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
externalTop.setDeptSource(DeptSourceEnum.EXTERNAL.getSource());
|
||||||
|
Long cuTopId = deptService.createDept(externalTop);
|
||||||
|
DeptDO cuTop = deptMapper.selectById(cuTopId);
|
||||||
|
assertEquals("CU001", cuTop.getCode());
|
||||||
|
|
||||||
|
// 同时创建同步来源(非 EXTERNAL),仍使用 ZT 序列
|
||||||
|
DeptSaveReqVO syncTop = new DeptSaveReqVO();
|
||||||
|
syncTop.setParentId(DeptDO.PARENT_ID_ROOT);
|
||||||
|
syncTop.setName("同步总部");
|
||||||
|
syncTop.setSort(2);
|
||||||
|
syncTop.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
syncTop.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
|
Long ztTopId = deptService.createDept(syncTop);
|
||||||
|
DeptDO ztTop = deptMapper.selectById(ztTopId);
|
||||||
|
assertEquals("ZT001", ztTop.getCode());
|
||||||
|
|
||||||
|
// 再创建一个自建顶级,应独立递增为 CU002
|
||||||
|
DeptSaveReqVO externalTop2 = new DeptSaveReqVO();
|
||||||
|
externalTop2.setParentId(DeptDO.PARENT_ID_ROOT);
|
||||||
|
externalTop2.setName("自建二部");
|
||||||
|
externalTop2.setSort(3);
|
||||||
|
externalTop2.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
externalTop2.setDeptSource(DeptSourceEnum.EXTERNAL.getSource());
|
||||||
|
Long cuTop2Id = deptService.createDept(externalTop2);
|
||||||
|
DeptDO cuTop2 = deptMapper.selectById(cuTop2Id);
|
||||||
|
assertEquals("CU002", cuTop2.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateDept_externalChildFollowsCuPrefix() {
|
||||||
|
DeptSaveReqVO externalTop = new DeptSaveReqVO();
|
||||||
|
externalTop.setParentId(DeptDO.PARENT_ID_ROOT);
|
||||||
|
externalTop.setName("自建根");
|
||||||
|
externalTop.setSort(1);
|
||||||
|
externalTop.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
externalTop.setDeptSource(DeptSourceEnum.EXTERNAL.getSource());
|
||||||
|
Long topId = deptService.createDept(externalTop);
|
||||||
|
DeptDO top = deptMapper.selectById(topId);
|
||||||
|
assertEquals("CU001", top.getCode());
|
||||||
|
|
||||||
|
DeptSaveReqVO childReq = new DeptSaveReqVO();
|
||||||
|
childReq.setParentId(topId);
|
||||||
|
childReq.setName("自建子");
|
||||||
|
childReq.setSort(1);
|
||||||
|
childReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
childReq.setDeptSource(DeptSourceEnum.EXTERNAL.getSource());
|
||||||
|
Long childId = deptService.createDept(childReq);
|
||||||
|
DeptDO child = deptMapper.selectById(childId);
|
||||||
|
assertEquals("CU001001", child.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateDept_externalChildUnderSyncParentUsesCuPrefix() {
|
||||||
|
// 同步来源父级,使用 ZT 序列
|
||||||
|
DeptSaveReqVO syncTop = new DeptSaveReqVO();
|
||||||
|
syncTop.setParentId(DeptDO.PARENT_ID_ROOT);
|
||||||
|
syncTop.setName("同步父");
|
||||||
|
syncTop.setSort(1);
|
||||||
|
syncTop.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
syncTop.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
|
Long syncTopId = deptService.createDept(syncTop);
|
||||||
|
DeptDO syncTopDept = deptMapper.selectById(syncTopId);
|
||||||
|
assertEquals("ZT001", syncTopDept.getCode());
|
||||||
|
|
||||||
|
// 在同步父级下新增外部子部门,前缀替换为 CU,序列与 ZT 独立
|
||||||
|
DeptSaveReqVO externalChild1 = new DeptSaveReqVO();
|
||||||
|
externalChild1.setParentId(syncTopId);
|
||||||
|
externalChild1.setName("外部子1");
|
||||||
|
externalChild1.setSort(1);
|
||||||
|
externalChild1.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
externalChild1.setDeptSource(DeptSourceEnum.EXTERNAL.getSource());
|
||||||
|
Long child1Id = deptService.createDept(externalChild1);
|
||||||
|
DeptDO child1 = deptMapper.selectById(child1Id);
|
||||||
|
assertEquals("CU001001", child1.getCode());
|
||||||
|
|
||||||
|
DeptSaveReqVO externalChild2 = new DeptSaveReqVO();
|
||||||
|
externalChild2.setParentId(syncTopId);
|
||||||
|
externalChild2.setName("外部子2");
|
||||||
|
externalChild2.setSort(2);
|
||||||
|
externalChild2.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
externalChild2.setDeptSource(DeptSourceEnum.EXTERNAL.getSource());
|
||||||
|
Long child2Id = deptService.createDept(externalChild2);
|
||||||
|
DeptDO child2 = deptMapper.selectById(child2Id);
|
||||||
|
assertEquals("CU001002", child2.getCode());
|
||||||
|
|
||||||
|
// 同步子部门仍使用 ZT 序列,不受 CU 序列影响
|
||||||
|
DeptSaveReqVO syncChild = new DeptSaveReqVO();
|
||||||
|
syncChild.setParentId(syncTopId);
|
||||||
|
syncChild.setName("同步子");
|
||||||
|
syncChild.setSort(3);
|
||||||
|
syncChild.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
syncChild.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
|
Long syncChildId = deptService.createDept(syncChild);
|
||||||
|
DeptDO syncChildDept = deptMapper.selectById(syncChildId);
|
||||||
|
assertEquals("ZT001001", syncChildDept.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCreateDept_topLevelAutoCode_ignoreCustomInput() {
|
public void testCreateDept_topLevelAutoCode_ignoreCustomInput() {
|
||||||
String customCode = "ROOT-001";
|
String customCode = "ROOT-001";
|
||||||
@@ -143,7 +248,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
topLevelReq.setName("集团");
|
topLevelReq.setName("集团");
|
||||||
topLevelReq.setSort(1);
|
topLevelReq.setSort(1);
|
||||||
topLevelReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
topLevelReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
topLevelReq.setDeptSource(1);
|
topLevelReq.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
topLevelReq.setCode(customCode);
|
topLevelReq.setCode(customCode);
|
||||||
|
|
||||||
Long deptId = deptService.createDept(topLevelReq);
|
Long deptId = deptService.createDept(topLevelReq);
|
||||||
@@ -166,7 +271,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
o.setParentId(DeptDO.PARENT_ID_ROOT);
|
o.setParentId(DeptDO.PARENT_ID_ROOT);
|
||||||
o.setId(dbDeptDO.getId());
|
o.setId(dbDeptDO.getId());
|
||||||
o.setStatus(randomCommonStatus());
|
o.setStatus(randomCommonStatus());
|
||||||
}).setDeptSource(1);
|
}).setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
reqVO.setCode(dbDeptDO.getCode());
|
reqVO.setCode(dbDeptDO.getCode());
|
||||||
|
|
||||||
// 调用
|
// 调用
|
||||||
@@ -195,7 +300,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
updateReq.setParentId(parentBId);
|
updateReq.setParentId(parentBId);
|
||||||
updateReq.setSort(1);
|
updateReq.setSort(1);
|
||||||
updateReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
updateReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
updateReq.setDeptSource(1);
|
updateReq.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
deptService.updateDept(updateReq);
|
deptService.updateDept(updateReq);
|
||||||
|
|
||||||
DeptDO updatedChild = deptMapper.selectById(childId);
|
DeptDO updatedChild = deptMapper.selectById(childId);
|
||||||
@@ -223,7 +328,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
updateReq1.setName("多系统部门");
|
updateReq1.setName("多系统部门");
|
||||||
updateReq1.setSort(1);
|
updateReq1.setSort(1);
|
||||||
updateReq1.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
updateReq1.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
updateReq1.setDeptSource(1);
|
updateReq1.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
updateReq1.setExternalSystemCode("ERP");
|
updateReq1.setExternalSystemCode("ERP");
|
||||||
updateReq1.setExternalDeptCode("ERP-100");
|
updateReq1.setExternalDeptCode("ERP-100");
|
||||||
deptService.updateDept(updateReq1);
|
deptService.updateDept(updateReq1);
|
||||||
@@ -235,7 +340,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
updateReq2.setName("多系统部门");
|
updateReq2.setName("多系统部门");
|
||||||
updateReq2.setSort(1);
|
updateReq2.setSort(1);
|
||||||
updateReq2.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
updateReq2.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
updateReq2.setDeptSource(1);
|
updateReq2.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
updateReq2.setExternalSystemCode("OA");
|
updateReq2.setExternalSystemCode("OA");
|
||||||
updateReq2.setExternalDeptCode("OA-100");
|
updateReq2.setExternalDeptCode("OA-100");
|
||||||
deptService.updateDept(updateReq2);
|
deptService.updateDept(updateReq2);
|
||||||
@@ -257,7 +362,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
createA.setName("iWork-A");
|
createA.setName("iWork-A");
|
||||||
createA.setSort(1);
|
createA.setSort(1);
|
||||||
createA.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
createA.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
createA.setDeptSource(1);
|
createA.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
createA.setExternalSystemCode("IWORK");
|
createA.setExternalSystemCode("IWORK");
|
||||||
createA.setExternalDeptCode("IW-001");
|
createA.setExternalDeptCode("IW-001");
|
||||||
Long deptAId = deptService.createDept(createA);
|
Long deptAId = deptService.createDept(createA);
|
||||||
@@ -272,7 +377,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
createB.setName("iWork-B");
|
createB.setName("iWork-B");
|
||||||
createB.setSort(2);
|
createB.setSort(2);
|
||||||
createB.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
createB.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
createB.setDeptSource(1);
|
createB.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
createB.setExternalSystemCode("IWORK");
|
createB.setExternalSystemCode("IWORK");
|
||||||
createB.setExternalDeptCode("IW-001");
|
createB.setExternalDeptCode("IW-001");
|
||||||
Long deptBId = deptService.createDept(createB);
|
Long deptBId = deptService.createDept(createB);
|
||||||
@@ -300,7 +405,7 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
updateReq.setName("子-更新");
|
updateReq.setName("子-更新");
|
||||||
updateReq.setSort(1);
|
updateReq.setSort(1);
|
||||||
updateReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
updateReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
updateReq.setDeptSource(1);
|
updateReq.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
updateReq.setExternalSystemCode("IWORK");
|
updateReq.setExternalSystemCode("IWORK");
|
||||||
updateReq.setExternalDeptCode("IW-CHILD");
|
updateReq.setExternalDeptCode("IW-CHILD");
|
||||||
|
|
||||||
@@ -689,4 +794,48 @@ public class DeptServiceImplTest extends BaseDbUnitTest {
|
|||||||
assertEquals("ZT001002", updatedChild2.getCode());
|
assertEquals("ZT001002", updatedChild2.getCode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCreateDept_delayCodeGeneration_thenGenerateWhenParentReady() {
|
||||||
|
Long missingParentId = 900L;
|
||||||
|
|
||||||
|
DeptSaveReqVO childReq = new DeptSaveReqVO();
|
||||||
|
childReq.setParentId(missingParentId);
|
||||||
|
childReq.setName("延迟子部门");
|
||||||
|
childReq.setSort(1);
|
||||||
|
childReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
childReq.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
|
childReq.setDelayCodeGeneration(true);
|
||||||
|
|
||||||
|
Long childId = deptService.createDept(childReq);
|
||||||
|
DeptDO child = deptMapper.selectById(childId);
|
||||||
|
assertNotNull(childId);
|
||||||
|
assertNull(child.getCode());
|
||||||
|
|
||||||
|
// 后补父级并赋予编码
|
||||||
|
DeptDO parent = new DeptDO();
|
||||||
|
parent.setId(missingParentId);
|
||||||
|
parent.setParentId(DeptDO.PARENT_ID_ROOT);
|
||||||
|
parent.setName("后补父级");
|
||||||
|
parent.setCode("ZT900");
|
||||||
|
parent.setSort(1);
|
||||||
|
parent.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
parent.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
|
deptMapper.insert(parent);
|
||||||
|
|
||||||
|
// 触发子部门生成编码
|
||||||
|
DeptSaveReqVO updateReq = new DeptSaveReqVO();
|
||||||
|
updateReq.setId(childId);
|
||||||
|
updateReq.setParentId(missingParentId);
|
||||||
|
updateReq.setName("延迟子部门");
|
||||||
|
updateReq.setSort(1);
|
||||||
|
updateReq.setStatus(CommonStatusEnum.ENABLE.getStatus());
|
||||||
|
updateReq.setDeptSource(DeptSourceEnum.SYNC.getSource());
|
||||||
|
updateReq.setDelayCodeGeneration(false);
|
||||||
|
|
||||||
|
deptService.updateDept(updateReq);
|
||||||
|
|
||||||
|
DeptDO updatedChild = deptMapper.selectById(childId);
|
||||||
|
assertEquals(parent.getCode() + "001", updatedChild.getCode());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user