接口调整
This commit is contained in:
@@ -0,0 +1,101 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.dept;
|
||||
|
||||
import com.njcn.rdms.framework.common.pojo.CommonResult;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.dept.vo.orgleader.OrgLeaderRelationRespVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.dept.vo.orgleader.OrgLeaderRelationSaveReqVO;
|
||||
import com.njcn.rdms.module.system.controller.admin.user.vo.user.UserSimpleRespVO;
|
||||
import com.njcn.rdms.module.system.convert.user.UserConvert;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.dept.DeptDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.dept.OrgLeaderRelationDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.njcn.rdms.module.system.service.dept.DeptService;
|
||||
import com.njcn.rdms.module.system.service.dept.OrgLeaderRelationService;
|
||||
import com.njcn.rdms.module.system.service.user.AdminUserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import jakarta.validation.Valid;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
|
||||
import static com.njcn.rdms.framework.common.util.collection.CollectionUtils.convertList;
|
||||
|
||||
@Tag(name = "管理后台 - 组织负责人关系")
|
||||
@RestController
|
||||
@RequestMapping("/system/org-leader")
|
||||
@Validated
|
||||
public class OrgLeaderRelationController {
|
||||
|
||||
@Resource
|
||||
private OrgLeaderRelationService orgLeaderRelationService;
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
@Resource
|
||||
private AdminUserService adminUserService;
|
||||
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "创建组织负责人关系")
|
||||
@PreAuthorize("@ss.hasPermission('system:org-leader:create')")
|
||||
public CommonResult<Long> createOrgLeaderRelation(@Valid @RequestBody OrgLeaderRelationSaveReqVO createReqVO) {
|
||||
return success(orgLeaderRelationService.createOrgLeaderRelation(createReqVO));
|
||||
}
|
||||
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "修改组织负责人关系")
|
||||
@PreAuthorize("@ss.hasPermission('system:org-leader:update')")
|
||||
public CommonResult<Boolean> updateOrgLeaderRelation(@Valid @RequestBody OrgLeaderRelationSaveReqVO updateReqVO) {
|
||||
orgLeaderRelationService.updateOrgLeaderRelation(updateReqVO);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "删除组织负责人关系")
|
||||
@Parameter(name = "id", description = "负责人关系编号", required = true, example = "1024")
|
||||
@PreAuthorize("@ss.hasPermission('system:org-leader:delete')")
|
||||
public CommonResult<Boolean> deleteOrgLeaderRelation(@RequestParam("id") Long id) {
|
||||
orgLeaderRelationService.deleteOrgLeaderRelation(id);
|
||||
return success(true);
|
||||
}
|
||||
|
||||
@GetMapping("/list-by-dept")
|
||||
@Operation(summary = "查询组织下的负责人关系列表")
|
||||
@Parameter(name = "deptId", description = "组织节点 ID", required = true, example = "100")
|
||||
@PreAuthorize("@ss.hasPermission('system:org-leader:query')")
|
||||
public CommonResult<List<OrgLeaderRelationRespVO>> getOrgLeaderRelationListByDept(@RequestParam("deptId") Long deptId) {
|
||||
List<OrgLeaderRelationDO> relations = orgLeaderRelationService.getOrgLeaderRelationListByDeptId(deptId);
|
||||
List<OrgLeaderRelationRespVO> respList = BeanUtils.toBean(relations, OrgLeaderRelationRespVO.class);
|
||||
Map<Long, AdminUserDO> userMap = adminUserService.getUserMap(convertList(relations, OrgLeaderRelationDO::getUserId));
|
||||
respList.forEach(respVO -> {
|
||||
AdminUserDO user = userMap.get(respVO.getUserId());
|
||||
if (user != null) {
|
||||
respVO.setUserNickname(user.getNickname());
|
||||
}
|
||||
});
|
||||
return success(respList);
|
||||
}
|
||||
|
||||
@GetMapping("/candidate-users")
|
||||
@Operation(summary = "查询组织负责人候选用户列表")
|
||||
@Parameter(name = "deptId", description = "组织节点 ID", required = true, example = "100")
|
||||
@PreAuthorize("@ss.hasPermission('system:org-leader:query')")
|
||||
public CommonResult<List<UserSimpleRespVO>> getCandidateUsers(@RequestParam("deptId") Long deptId) {
|
||||
List<AdminUserDO> users = orgLeaderRelationService.getCandidateUsersByDeptId(deptId);
|
||||
Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertList(users, AdminUserDO::getDeptId));
|
||||
return success(UserConvert.INSTANCE.convertSimpleList(users, deptMap));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.dept.vo.orgleader;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 组织负责人关系 Response VO")
|
||||
@Data
|
||||
public class OrgLeaderRelationRespVO {
|
||||
|
||||
@Schema(description = "负责人关系编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "组织节点 ID", example = "100")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "负责人用户 ID", example = "1")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "负责人用户昵称", example = "管理员")
|
||||
private String userNickname;
|
||||
|
||||
@Schema(description = "生效开始时间")
|
||||
private LocalDateTime effectiveFrom;
|
||||
|
||||
@Schema(description = "生效结束时间")
|
||||
private LocalDateTime effectiveUntil;
|
||||
|
||||
@Schema(description = "备注", example = "部门负责人")
|
||||
private String remark;
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(description = "更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.njcn.rdms.module.system.controller.admin.dept.vo.orgleader;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import jakarta.validation.constraints.Size;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Schema(description = "管理后台 - 组织负责人关系创建/修改 Request VO")
|
||||
@Data
|
||||
public class OrgLeaderRelationSaveReqVO {
|
||||
|
||||
@Schema(description = "负责人关系编号", example = "1024")
|
||||
private Long id;
|
||||
|
||||
@Schema(description = "组织节点 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "100")
|
||||
@NotNull(message = "组织节点不能为空")
|
||||
private Long deptId;
|
||||
|
||||
@Schema(description = "负责人用户 ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "1")
|
||||
@NotNull(message = "负责人用户不能为空")
|
||||
private Long userId;
|
||||
|
||||
@Schema(description = "生效开始时间")
|
||||
private LocalDateTime effectiveFrom;
|
||||
|
||||
@Schema(description = "生效结束时间")
|
||||
private LocalDateTime effectiveUntil;
|
||||
|
||||
@Schema(description = "备注", example = "部门负责人")
|
||||
@Size(max = 500, message = "备注长度不能超过 500 个字符")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.njcn.rdms.module.system.dal.dataobject.dept;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.njcn.rdms.framework.mybatis.core.dataobject.BaseDO;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 组织负责人关系 DO
|
||||
*/
|
||||
@TableName("system_org_leader_relation")
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class OrgLeaderRelationDO extends BaseDO {
|
||||
|
||||
@TableId
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 组织节点 ID
|
||||
*/
|
||||
private Long deptId;
|
||||
|
||||
/**
|
||||
* 负责人用户 ID
|
||||
*/
|
||||
private Long userId;
|
||||
|
||||
/**
|
||||
* 生效开始时间
|
||||
*/
|
||||
private LocalDateTime effectiveFrom;
|
||||
|
||||
/**
|
||||
* 生效结束时间
|
||||
*/
|
||||
private LocalDateTime effectiveUntil;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String remark;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.njcn.rdms.module.system.dal.mysql.dept;
|
||||
|
||||
import com.njcn.rdms.framework.mybatis.core.mapper.BaseMapperX;
|
||||
import com.njcn.rdms.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.dept.OrgLeaderRelationDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Mapper
|
||||
public interface OrgLeaderRelationMapper extends BaseMapperX<OrgLeaderRelationDO> {
|
||||
|
||||
default List<OrgLeaderRelationDO> selectListByDeptId(Long deptId) {
|
||||
return selectList(new LambdaQueryWrapperX<OrgLeaderRelationDO>()
|
||||
.eq(OrgLeaderRelationDO::getDeptId, deptId)
|
||||
.orderByDesc(OrgLeaderRelationDO::getId));
|
||||
}
|
||||
|
||||
default List<OrgLeaderRelationDO> selectListByDeptIdAndUserId(Long deptId, Long userId) {
|
||||
return selectList(new LambdaQueryWrapperX<OrgLeaderRelationDO>()
|
||||
.eq(OrgLeaderRelationDO::getDeptId, deptId)
|
||||
.eq(OrgLeaderRelationDO::getUserId, userId)
|
||||
.orderByDesc(OrgLeaderRelationDO::getId));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.njcn.rdms.module.system.service.dept;
|
||||
|
||||
import com.njcn.rdms.module.system.controller.admin.dept.vo.orgleader.OrgLeaderRelationSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.dept.OrgLeaderRelationDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.user.AdminUserDO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 组织负责人关系 Service
|
||||
*/
|
||||
public interface OrgLeaderRelationService {
|
||||
|
||||
/**
|
||||
* 创建组织负责人关系
|
||||
*
|
||||
* @param createReqVO 创建请求
|
||||
* @return 负责人关系 ID
|
||||
*/
|
||||
Long createOrgLeaderRelation(OrgLeaderRelationSaveReqVO createReqVO);
|
||||
|
||||
/**
|
||||
* 更新组织负责人关系
|
||||
*
|
||||
* @param updateReqVO 更新请求
|
||||
*/
|
||||
void updateOrgLeaderRelation(OrgLeaderRelationSaveReqVO updateReqVO);
|
||||
|
||||
/**
|
||||
* 删除组织负责人关系
|
||||
*
|
||||
* @param id 关系 ID
|
||||
*/
|
||||
void deleteOrgLeaderRelation(Long id);
|
||||
|
||||
/**
|
||||
* 查询指定组织下的负责人关系列表
|
||||
*
|
||||
* @param deptId 组织 ID
|
||||
* @return 负责人关系列表
|
||||
*/
|
||||
List<OrgLeaderRelationDO> getOrgLeaderRelationListByDeptId(Long deptId);
|
||||
|
||||
/**
|
||||
* 查询组织负责人候选用户
|
||||
*
|
||||
* @param deptId 组织 ID
|
||||
* @return 候选用户列表
|
||||
*/
|
||||
List<AdminUserDO> getCandidateUsersByDeptId(Long deptId);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
package com.njcn.rdms.module.system.service.dept;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.njcn.rdms.framework.common.util.object.BeanUtils;
|
||||
import com.njcn.rdms.module.system.controller.admin.dept.vo.orgleader.OrgLeaderRelationSaveReqVO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.dept.DeptDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.dept.OrgLeaderRelationDO;
|
||||
import com.njcn.rdms.module.system.dal.dataobject.user.AdminUserDO;
|
||||
import com.njcn.rdms.module.system.dal.mysql.dept.OrgLeaderRelationMapper;
|
||||
import com.njcn.rdms.module.system.service.user.AdminUserService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
|
||||
import static com.njcn.rdms.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||
import static com.njcn.rdms.module.system.enums.ErrorCodeConstants.*;
|
||||
import static java.util.Collections.singleton;
|
||||
|
||||
/**
|
||||
* 组织负责人关系 Service 实现类
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
public class OrgLeaderRelationServiceImpl implements OrgLeaderRelationService {
|
||||
|
||||
@Resource
|
||||
private OrgLeaderRelationMapper orgLeaderRelationMapper;
|
||||
@Resource
|
||||
private DeptService deptService;
|
||||
@Resource
|
||||
private AdminUserService adminUserService;
|
||||
|
||||
@Override
|
||||
public Long createOrgLeaderRelation(OrgLeaderRelationSaveReqVO createReqVO) {
|
||||
validateOrgLeaderRelationForCreateOrUpdate(null, createReqVO);
|
||||
OrgLeaderRelationDO relation = BeanUtils.toBean(createReqVO, OrgLeaderRelationDO.class);
|
||||
orgLeaderRelationMapper.insert(relation);
|
||||
return relation.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateOrgLeaderRelation(OrgLeaderRelationSaveReqVO updateReqVO) {
|
||||
if (updateReqVO.getId() == null) {
|
||||
throw exception(ORG_LEADER_RELATION_NOT_FOUND);
|
||||
}
|
||||
validateOrgLeaderRelationForCreateOrUpdate(updateReqVO.getId(), updateReqVO);
|
||||
OrgLeaderRelationDO relation = BeanUtils.toBean(updateReqVO, OrgLeaderRelationDO.class);
|
||||
orgLeaderRelationMapper.updateById(relation);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteOrgLeaderRelation(Long id) {
|
||||
validateOrgLeaderRelationExists(id);
|
||||
orgLeaderRelationMapper.deleteById(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<OrgLeaderRelationDO> getOrgLeaderRelationListByDeptId(Long deptId) {
|
||||
validateDeptExists(deptId);
|
||||
return orgLeaderRelationMapper.selectListByDeptId(deptId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<AdminUserDO> getCandidateUsersByDeptId(Long deptId) {
|
||||
validateDeptExists(deptId);
|
||||
Set<Long> deptScope = new HashSet<>(deptService.getChildDeptIdListFromCache(deptId));
|
||||
deptScope.add(deptId);
|
||||
List<AdminUserDO> users = adminUserService.getUserListByDeptIds(deptScope);
|
||||
users.removeIf(user -> !adminUserService.isUserAvailable(user));
|
||||
users.sort(Comparator.comparing(AdminUserDO::getDeptId)
|
||||
.thenComparing(AdminUserDO::getNickname)
|
||||
.thenComparing(AdminUserDO::getId));
|
||||
return users;
|
||||
}
|
||||
|
||||
private void validateOrgLeaderRelationForCreateOrUpdate(Long id, OrgLeaderRelationSaveReqVO reqVO) {
|
||||
validateOrgLeaderRelationExists(id);
|
||||
deptService.validateDeptList(singleton(reqVO.getDeptId()));
|
||||
adminUserService.validateUserList(singleton(reqVO.getUserId()));
|
||||
validateEffectiveRange(reqVO.getEffectiveFrom(), reqVO.getEffectiveUntil());
|
||||
validateUserInDeptScope(reqVO.getDeptId(), reqVO.getUserId());
|
||||
validateRelationOverlap(id, reqVO.getDeptId(), reqVO.getUserId(),
|
||||
reqVO.getEffectiveFrom(), reqVO.getEffectiveUntil());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateEffectiveRange(LocalDateTime effectiveFrom, LocalDateTime effectiveUntil) {
|
||||
if (effectiveFrom != null && effectiveUntil != null && effectiveFrom.isAfter(effectiveUntil)) {
|
||||
throw exception(ORG_LEADER_EFFECTIVE_RANGE_INVALID);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateUserInDeptScope(Long deptId, Long userId) {
|
||||
AdminUserDO user = adminUserService.getUser(userId);
|
||||
if (user == null) {
|
||||
throw exception(USER_NOT_EXISTS);
|
||||
}
|
||||
Set<Long> deptScope = new HashSet<>(deptService.getChildDeptIdListFromCache(deptId));
|
||||
deptScope.add(deptId);
|
||||
if (!deptScope.contains(user.getDeptId())) {
|
||||
throw exception(ORG_LEADER_USER_NOT_IN_DEPT, user.getNickname());
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
void validateRelationOverlap(Long id, Long deptId, Long userId,
|
||||
LocalDateTime effectiveFrom, LocalDateTime effectiveUntil) {
|
||||
List<OrgLeaderRelationDO> relations = orgLeaderRelationMapper.selectListByDeptIdAndUserId(deptId, userId);
|
||||
if (CollUtil.isEmpty(relations)) {
|
||||
return;
|
||||
}
|
||||
for (OrgLeaderRelationDO relation : relations) {
|
||||
if (Objects.equals(relation.getId(), id)) {
|
||||
continue;
|
||||
}
|
||||
if (isTimeRangeOverlap(effectiveFrom, effectiveUntil,
|
||||
relation.getEffectiveFrom(), relation.getEffectiveUntil())) {
|
||||
throw exception(ORG_LEADER_RELATION_OVERLAP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isTimeRangeOverlap(LocalDateTime start1, LocalDateTime end1,
|
||||
LocalDateTime start2, LocalDateTime end2) {
|
||||
return !isAfter(start1, end2) && !isAfter(start2, end1);
|
||||
}
|
||||
|
||||
private boolean isAfter(LocalDateTime start, LocalDateTime end) {
|
||||
return start != null && end != null && start.isAfter(end);
|
||||
}
|
||||
|
||||
private OrgLeaderRelationDO validateOrgLeaderRelationExists(Long id) {
|
||||
if (id == null) {
|
||||
return null;
|
||||
}
|
||||
OrgLeaderRelationDO relation = orgLeaderRelationMapper.selectById(id);
|
||||
if (relation == null) {
|
||||
throw exception(ORG_LEADER_RELATION_NOT_FOUND);
|
||||
}
|
||||
return relation;
|
||||
}
|
||||
|
||||
private DeptDO validateDeptExists(Long deptId) {
|
||||
DeptDO dept = deptService.getDept(deptId);
|
||||
if (dept == null) {
|
||||
throw exception(DEPT_NOT_FOUND);
|
||||
}
|
||||
return dept;
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user