Merge remote-tracking branch 'base-version/main' into dev

# Conflicts:
#	pom.xml
#	yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/api/dept/DeptApiImpl.java
#	yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/controller/admin/dept/vo/dept/DeptSaveReqVO.java
#	yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/dal/mysql/dept/DeptMapper.java
#	yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/sync/SyncLogServiceImpl.java
#	yudao-module-system/yudao-module-system-server/src/main/java/cn/iocoder/yudao/module/system/service/sync/UserSyncServiceImpl.java
#	yudao-module-system/yudao-module-system-server/src/test/java/cn/iocoder/yudao/module/system/service/sync/UserSyncServiceImplTest.java
#	yudao-module-template/yudao-module-template-server/src/main/java/cn/iocoder/yudao/module/template/controller/admin/contract/DemoContractController.java
#	yudao-server/pom.xml
This commit is contained in:
chenbowen
2025-09-18 13:55:08 +08:00
15 changed files with 99 additions and 7 deletions

View File

@@ -61,6 +61,8 @@ public interface ErrorCodeConstants {
ErrorCode DEPT_NOT_ENABLE = new ErrorCode(1_002_004_006, "部门({})不处于开启状态,不允许选择");
ErrorCode DEPT_PARENT_IS_CHILD = new ErrorCode(1_002_004_007, "不能设置自己的子部门为父部门");
ErrorCode DEPT_TENANT_RELATION_EXISTS = new ErrorCode(1_002_004_008, "当前租户已经关联组织机构");
ErrorCode DEPT_CODE_NOT_NULL = new ErrorCode(1_002_004_009, "部门编码不能为空");
ErrorCode DEPT_CODE_DUPLICATE = new ErrorCode(1_002_004_010, "已经存在该编码的部门");
// ========== 岗位模块 1-002-005-000 ==========

View File

@@ -9,7 +9,7 @@ import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptListReqV
import cn.iocoder.yudao.module.system.controller.admin.dept.vo.dept.DeptSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;

View File

@@ -15,9 +15,15 @@ public class DeptRespVO {
@Schema(description = "部门编号", example = "1024")
private Long id;
@Schema(description = "部门编码", example = "DEPT_001")
private String code;
@Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String name;
@Schema(description = "部门简称", example = "芋道科技")
private String shortName;
@Schema(description = "父部门 ID", example = "1024")
private Long parentId;

View File

@@ -19,11 +19,20 @@ public class DeptSaveReqVO {
@Schema(description = "部门编号", example = "1024")
private Long id;
@Schema(description = "部门编码", requiredMode = Schema.RequiredMode.REQUIRED, example = "DEPT_001")
@NotBlank(message = "部门编码不能为空")
@Size(max = 50, message = "部门编码长度不能超过 50 个字符")
private String code;
@Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
@NotBlank(message = "部门名称不能为空")
@Size(max = 30, message = "部门名称长度不能超过 30 个字符")
private String name;
@Schema(description = "部门简称", example = "科技")
@Size(max = 20, message = "部门简称长度不能超过 20 个字符")
private String shortName;
@Schema(description = "父部门 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024(顶级部门父级 Id 为 0)")
private Long parentId;

View File

@@ -17,6 +17,9 @@ public class DeptSimpleRespVO {
@Schema(description = "部门编号", requiredMode = Schema.RequiredMode.REQUIRED, example = "1024")
private Long id;
@Schema(description = "部门编码", example = "DEPT_001")
private String code;
@Schema(description = "部门名称", requiredMode = Schema.RequiredMode.REQUIRED, example = "芋道")
private String name;

View File

@@ -30,11 +30,19 @@ public class DeptDO extends TenantBaseDO {
*/
@TableId(type = IdType.ASSIGN_ID)
private Long id;
/**
* 部门编码
*/
private String code;
/**
* 部门名称
*/
@NotEmpty
private String name;
/**
* 部门简称
*/
private String shortName;
/**
* 父部门ID
*

View File

@@ -88,4 +88,14 @@ public interface DeptMapper extends BaseMapperX<DeptDO> {
);
}
/**
* 根据部门编码查询部门
*
* @param code 部门编码
* @return 部门信息
*/
default DeptDO selectByCode(String code) {
return selectOne(DeptDO::getCode, code);
}
}

View File

@@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.service.dept;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.common.pojo.CompanyDeptInfo;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
@@ -31,6 +32,8 @@ import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
import cn.iocoder.yudao.module.system.enums.dept.DeptSourceEnum;
/**
* 部门 Service 实现类
*
@@ -59,6 +62,8 @@ public class DeptServiceImpl implements DeptService {
validateParentDept(null, createReqVO.getParentId());
// 校验部门名的唯一性
validateDeptNameUnique(null, createReqVO.getParentId(), createReqVO.getName());
// 校验部门编码的唯一性
validateDeptCodeUnique(null, createReqVO.getCode());
// 插入部门
DeptDO dept = BeanUtils.toBean(createReqVO, DeptDO.class);
@@ -165,6 +170,24 @@ public class DeptServiceImpl implements DeptService {
}
}
@VisibleForTesting
void validateDeptCodeUnique(Long id, String code) {
if (StrUtil.isBlank(code)) {
throw exception(DEPT_CODE_NOT_NULL);
}
DeptDO dept = deptMapper.selectByCode(code);
if (dept == null) {
return;
}
// 如果 id 为空,说明不用比较是否为相同 id 的部门
if (id == null) {
throw exception(DEPT_CODE_DUPLICATE);
}
if (ObjectUtil.notEqual(dept.getId(), id)) {
throw exception(DEPT_CODE_DUPLICATE);
}
}
@Override
public DeptDO getDept(Long id) {
return deptMapper.selectById(id);

View File

@@ -15,6 +15,7 @@ import cn.iocoder.yudao.module.system.service.dept.PostService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import cn.iocoder.yudao.module.system.service.userdept.UserDeptService;
import cn.iocoder.yudao.module.system.util.sync.SyncVerifyUtil;
import cn.iocoder.yudao.module.system.enums.user.UserSourceEnum;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

View File

@@ -29,6 +29,7 @@ import cn.iocoder.yudao.module.system.service.dept.PostService;
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
import cn.iocoder.yudao.module.system.service.userdept.UserDeptService;
import cn.iocoder.yudao.module.system.enums.user.UserSourceEnum;
import com.google.common.annotations.VisibleForTesting;
import com.mzt.logapi.context.LogRecordContext;
import com.mzt.logapi.service.impl.DiffParseFunction;

View File

@@ -82,7 +82,6 @@ public class UserSyncServiceImplTest extends BaseMockitoUnitTest {
// Arrange
UserDeleteRequestVO requestVO = randomPojo(UserDeleteRequestVO.class);
AdminUserDO existingUser = randomPojo(AdminUserDO.class);
when(adminUserService.getUserByUsername(requestVO.getBimRemoteUser())).thenReturn(existingUser);
// Act
UserDeleteResponseVO response = userSyncService.deleteUser(requestVO);