增加部门
This commit is contained in:
parent
9c949fe5c7
commit
9975d4508e
@ -0,0 +1,36 @@
|
||||
package com.qqchen.deploy.backend.api;
|
||||
|
||||
import com.qqchen.deploy.backend.entity.Department;
|
||||
import com.qqchen.deploy.backend.framework.api.Response;
|
||||
import com.qqchen.deploy.backend.framework.controller.BaseController;
|
||||
import com.qqchen.deploy.backend.model.DepartmentDTO;
|
||||
import com.qqchen.deploy.backend.model.query.DepartmentQuery;
|
||||
import com.qqchen.deploy.backend.service.IDepartmentService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Tag(name = "部门管理")
|
||||
@RestController
|
||||
@RequestMapping("/api/v1/department")
|
||||
public class DepartmentApiController extends BaseController<Department, DepartmentDTO, Long, DepartmentQuery> {
|
||||
|
||||
@Resource
|
||||
private IDepartmentService departmentService;
|
||||
|
||||
@Operation(summary = "获取部门树")
|
||||
@GetMapping("/tree")
|
||||
public Response<List<DepartmentDTO>> getTree() {
|
||||
return Response.success(departmentService.getTree());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void exportData(jakarta.servlet.http.HttpServletResponse response, List<DepartmentDTO> data) {
|
||||
// TODO: 实现导出功能
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
package com.qqchen.deploy.backend.converter;
|
||||
|
||||
import com.qqchen.deploy.backend.entity.Department;
|
||||
import com.qqchen.deploy.backend.framework.converter.BaseConverter;
|
||||
import com.qqchen.deploy.backend.model.DepartmentDTO;
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.ReportingPolicy;
|
||||
|
||||
@Mapper(componentModel = "spring", unmappedTargetPolicy = ReportingPolicy.IGNORE)
|
||||
public interface DepartmentConverter extends BaseConverter<Department, DepartmentDTO> {
|
||||
// 继承了 BaseConverter 的方法,不需要再声明
|
||||
}
|
||||
@ -49,7 +49,14 @@ public enum ResponseCode {
|
||||
// 角色标签相关错误码 (4300-4399)
|
||||
ROLE_TAG_NAME_EXISTS(4300, "role.tag.name.exists"),
|
||||
ROLE_TAG_NOT_FOUND(4301, "role.tag.not.found"),
|
||||
ROLE_TAG_IN_USE(4302, "role.tag.in.use");
|
||||
ROLE_TAG_IN_USE(4302, "role.tag.in.use"),
|
||||
|
||||
// 部门相关错误码 (2300-2399)
|
||||
DEPARTMENT_NOT_FOUND(2300, "department.not.found"),
|
||||
DEPARTMENT_CODE_EXISTS(2301, "department.code.exists"),
|
||||
DEPARTMENT_NAME_EXISTS(2302, "department.name.exists"),
|
||||
DEPARTMENT_PARENT_NOT_FOUND(2303, "department.parent.not.found"),
|
||||
DEPARTMENT_HAS_CHILDREN(2304, "department.has.children");
|
||||
|
||||
private final int code;
|
||||
private final String messageKey; // 国际化消息key
|
||||
|
||||
@ -0,0 +1,30 @@
|
||||
package com.qqchen.deploy.backend.model;
|
||||
|
||||
import com.qqchen.deploy.backend.framework.dto.BaseDTO;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DepartmentDTO extends BaseDTO {
|
||||
|
||||
private String code;
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
private Boolean enabled;
|
||||
|
||||
private Long leaderId;
|
||||
|
||||
private String leaderName;
|
||||
|
||||
private Long parentId;
|
||||
|
||||
private Integer sort;
|
||||
|
||||
private List<DepartmentDTO> children;
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
package com.qqchen.deploy.backend.model.query;
|
||||
|
||||
import com.qqchen.deploy.backend.framework.query.BaseQuery;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class DepartmentQuery extends BaseQuery {
|
||||
|
||||
/**
|
||||
* 部门编码
|
||||
*/
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 部门名称
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 上级部门ID
|
||||
*/
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 是否启用
|
||||
*/
|
||||
private Boolean enabled;
|
||||
|
||||
/**
|
||||
* 部门负责人ID
|
||||
*/
|
||||
private Long leaderId;
|
||||
|
||||
/**
|
||||
* 部门负责人姓名
|
||||
*/
|
||||
private String leaderName;
|
||||
}
|
||||
@ -1,18 +1,15 @@
|
||||
//package com.qqchen.deploy.backend.service;
|
||||
//
|
||||
//
|
||||
//import com.qqchen.deploy.backend.framework.service.IBaseService;
|
||||
//import com.qqchen.deploy.backend.entity.Department;
|
||||
//
|
||||
//import java.util.List;
|
||||
//
|
||||
//public interface IDepartmentService extends IBaseService<Department, Long> {
|
||||
//
|
||||
// List<Department> getTree();
|
||||
//
|
||||
// void validateCode(String code);
|
||||
//
|
||||
// void validateName(String name);
|
||||
//
|
||||
// Integer getNextSort(Long parentId);
|
||||
//}
|
||||
package com.qqchen.deploy.backend.service;
|
||||
|
||||
import com.qqchen.deploy.backend.entity.Department;
|
||||
import com.qqchen.deploy.backend.framework.service.IBaseService;
|
||||
import com.qqchen.deploy.backend.model.DepartmentDTO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface IDepartmentService extends IBaseService<Department, DepartmentDTO, Long> {
|
||||
|
||||
/**
|
||||
* 获取部门树
|
||||
*/
|
||||
List<DepartmentDTO> getTree();
|
||||
}
|
||||
@ -1,105 +1,76 @@
|
||||
//package com.qqchen.deploy.backend.service.impl;
|
||||
//
|
||||
//import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
||||
//import com.qqchen.deploy.backend.entity.Department;
|
||||
//import com.qqchen.deploy.backend.repository.IDepartmentRepository;
|
||||
//import com.qqchen.deploy.backend.service.IDepartmentService;
|
||||
//import org.springframework.beans.factory.annotation.Autowired;
|
||||
//import org.springframework.stereotype.Service;
|
||||
//import jakarta.transaction.Transactional;
|
||||
//import java.util.ArrayList;
|
||||
//import java.util.List;
|
||||
//import java.util.Map;
|
||||
//import java.util.stream.Collectors;
|
||||
//
|
||||
//@Service
|
||||
//@Transactional
|
||||
//public class DepartmentServiceImpl extends BaseServiceImpl<Department, Long> implements IDepartmentService {
|
||||
//
|
||||
// private final IDepartmentRepository repository;
|
||||
//
|
||||
// @Autowired
|
||||
// public DepartmentServiceImpl(IDepartmentRepository repository) {
|
||||
// super(repository);
|
||||
// this.repository = repository;
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Department create(Department entity) {
|
||||
// validateCode(entity.getCode());
|
||||
// validateName(entity.getName());
|
||||
// return repository.save(entity);
|
||||
// }
|
||||
//
|
||||
// public Department update(Long id, Department entity) {
|
||||
// Department existing = repository.findById(id)
|
||||
// .orElseThrow(() -> new RuntimeException("部门不存在"));
|
||||
//
|
||||
// entity.setVersion(existing.getVersion());
|
||||
// entity.setId(id);
|
||||
//
|
||||
// if (!existing.getCode().equals(entity.getCode())) {
|
||||
// if (repository.existsByCodeAndDeletedFalse(entity.getCode())) {
|
||||
// throw new RuntimeException("部门编码已存在");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// if (!existing.getName().equals(entity.getName())) {
|
||||
// if (repository.existsByNameAndDeletedFalse(entity.getName())) {
|
||||
// throw new RuntimeException("部门名称已存在");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// entity.setCreateTime(existing.getCreateTime());
|
||||
// entity.setCreateBy(existing.getCreateBy());
|
||||
// entity.setDeleted(existing.getDeleted());
|
||||
//
|
||||
// return repository.save(entity);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public List<Department> getTree() {
|
||||
// List<Department> departments = repository.findByDeletedFalseOrderBySort();
|
||||
// return buildTree(departments);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void validateCode(String code) {
|
||||
// if (repository.existsByCodeAndDeletedFalse(code)) {
|
||||
// throw new RuntimeException("部门编码已存在");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void validateName(String name) {
|
||||
// if (repository.existsByNameAndDeletedFalse(name)) {
|
||||
// throw new RuntimeException("部门名称已存在");
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public Integer getNextSort(Long parentId) {
|
||||
// return repository.findMaxSortByParentId(parentId) + 1;
|
||||
// }
|
||||
//
|
||||
// private List<Department> buildTree(List<Department> departments) {
|
||||
// Map<Long, List<Department>> parentIdMap = departments.stream()
|
||||
// .collect(Collectors.groupingBy(d -> d.getParentId() == null ? 0L : d.getParentId()));
|
||||
//
|
||||
// return buildTreeNodes(0L, parentIdMap);
|
||||
// }
|
||||
//
|
||||
// private List<Department> buildTreeNodes(Long parentId, Map<Long, List<Department>> parentIdMap) {
|
||||
// List<Department> nodes = new ArrayList<>();
|
||||
//
|
||||
// List<Department> children = parentIdMap.get(parentId);
|
||||
// if (children != null) {
|
||||
// for (Department child : children) {
|
||||
//// child.setChildren(buildTreeNodes(child.getId(), parentIdMap));
|
||||
//// nodes.add(child);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return nodes;
|
||||
// }
|
||||
//}
|
||||
package com.qqchen.deploy.backend.service.impl;
|
||||
|
||||
import com.qqchen.deploy.backend.converter.DepartmentConverter;
|
||||
import com.qqchen.deploy.backend.entity.Department;
|
||||
import com.qqchen.deploy.backend.framework.enums.ResponseCode;
|
||||
import com.qqchen.deploy.backend.framework.exception.UniqueConstraintException;
|
||||
import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
|
||||
import com.qqchen.deploy.backend.model.DepartmentDTO;
|
||||
import com.qqchen.deploy.backend.repository.IDepartmentRepository;
|
||||
import com.qqchen.deploy.backend.service.IDepartmentService;
|
||||
import com.qqchen.deploy.backend.framework.annotation.ServiceType;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import jakarta.annotation.Resource;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static com.qqchen.deploy.backend.framework.annotation.ServiceType.Type.DATABASE;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
@ServiceType(DATABASE)
|
||||
public class DepartmentServiceImpl extends BaseServiceImpl<Department, DepartmentDTO, Long> implements IDepartmentService {
|
||||
|
||||
@Resource
|
||||
private IDepartmentRepository departmentRepository;
|
||||
|
||||
@Resource
|
||||
private DepartmentConverter departmentConverter;
|
||||
|
||||
@Override
|
||||
protected void validateUniqueConstraints(DepartmentDTO dto) {
|
||||
// 检查部门编码唯一性
|
||||
if (departmentRepository.existsByCodeAndDeletedFalse(dto.getCode())) {
|
||||
throw new UniqueConstraintException(ResponseCode.DEPARTMENT_CODE_EXISTS, "code", dto.getCode());
|
||||
}
|
||||
|
||||
// 检查部门名称唯一性
|
||||
if (departmentRepository.existsByNameAndDeletedFalse(dto.getName())) {
|
||||
throw new UniqueConstraintException(ResponseCode.DEPARTMENT_NAME_EXISTS, "name", dto.getName());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DepartmentDTO> getTree() {
|
||||
List<Department> departments = departmentRepository.findByDeletedFalseOrderBySort();
|
||||
return buildTree(departments);
|
||||
}
|
||||
|
||||
private List<DepartmentDTO> buildTree(List<Department> departments) {
|
||||
Map<Long, DepartmentDTO> dtoMap = new HashMap<>();
|
||||
List<DepartmentDTO> roots = new ArrayList<>();
|
||||
|
||||
// 转换为DTO并建立映射
|
||||
departments.forEach(dept -> {
|
||||
DepartmentDTO dto = departmentConverter.toDto(dept);
|
||||
dto.setChildren(new ArrayList<>());
|
||||
dtoMap.put(dto.getId(), dto);
|
||||
});
|
||||
|
||||
// 构建树形结构
|
||||
departments.forEach(dept -> {
|
||||
DepartmentDTO dto = dtoMap.get(dept.getId());
|
||||
if (dept.getParentId() == null || dept.getParentId() == 0) {
|
||||
roots.add(dto);
|
||||
} else {
|
||||
DepartmentDTO parent = dtoMap.get(dept.getParentId());
|
||||
if (parent != null) {
|
||||
parent.getChildren().add(dto);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return roots;
|
||||
}
|
||||
}
|
||||
@ -174,4 +174,24 @@ CREATE TABLE sys_template_menu (
|
||||
CONSTRAINT FK_template_menu_template FOREIGN KEY (template_id) REFERENCES sys_permission_template (id),
|
||||
CONSTRAINT FK_template_menu_menu FOREIGN KEY (menu_id) REFERENCES sys_menu (id)
|
||||
) COMMENT '模板菜单关联表';
|
||||
|
||||
-- 创建部门表
|
||||
CREATE TABLE sys_department (
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
create_by VARCHAR(255) NULL,
|
||||
create_time DATETIME(6) NULL,
|
||||
deleted BIT NOT NULL DEFAULT 0,
|
||||
update_by VARCHAR(255) NULL,
|
||||
update_time DATETIME(6) NULL,
|
||||
version INT NOT NULL DEFAULT 0,
|
||||
code VARCHAR(255) NOT NULL,
|
||||
description VARCHAR(255) NULL,
|
||||
enabled BIT NOT NULL DEFAULT 1,
|
||||
leader_id BIGINT NULL,
|
||||
leader_name VARCHAR(255) NULL,
|
||||
name VARCHAR(255) NOT NULL,
|
||||
parent_id BIGINT NULL,
|
||||
sort INT NOT NULL DEFAULT 0,
|
||||
CONSTRAINT UK_mho5hjhq35wmm63mswah975ic UNIQUE (code)
|
||||
);
|
||||
|
||||
@ -95,4 +95,29 @@ INSERT INTO sys_role_tag_relation (role_id, tag_id)
|
||||
VALUES
|
||||
(1, 3), -- 超级管理员 -> 安全标签
|
||||
(2, 1), -- 开发主管 -> 研发标签
|
||||
(3, 2); -- 运维主管 -> 运维标签
|
||||
(3, 2); -- 运维主管 -> 运维标签
|
||||
|
||||
-- 初始化部门数据
|
||||
INSERT INTO sys_department (id, create_time, update_time, deleted, version, code, name, description, parent_id, sort, enabled, leader_id, leader_name)
|
||||
VALUES
|
||||
-- 总公司
|
||||
(1, NOW(), NOW(), false, 1, 'HQ', '总公司', '公司总部', null, 1, true, null, null),
|
||||
|
||||
-- 一级部门
|
||||
(2, NOW(), NOW(), false, 1, 'TECH', '技术部', '负责公司技术研发', 1, 1, true, null, null),
|
||||
(3, NOW(), NOW(), false, 1, 'HR', '人力资源部', '负责人力资源管理', 1, 2, true, null, null),
|
||||
(4, NOW(), NOW(), false, 1, 'FIN', '财务部', '负责公司财务管理', 1, 3, true, null, null),
|
||||
(5, NOW(), NOW(), false, 1, 'MKT', '市场部', '负责市场营销', 1, 4, true, null, null),
|
||||
|
||||
-- 技术部下属部门
|
||||
(6, NOW(), NOW(), false, 1, 'DEV', '研发部', '负责产品研发', 2, 1, true, null, null),
|
||||
(7, NOW(), NOW(), false, 1, 'TEST', '测试部', '负责产品测试', 2, 2, true, null, null),
|
||||
(8, NOW(), NOW(), false, 1, 'OPS', '运维部', '负责系统运维', 2, 3, true, null, null),
|
||||
|
||||
-- 人力资源部下属部门
|
||||
(9, NOW(), NOW(), false, 1, 'REC', '招聘部', '负责人员招聘', 3, 1, true, null, null),
|
||||
(10, NOW(), NOW(), false, 1, 'TRAIN', '培训部', '负责员工培训', 3, 2, true, null, null),
|
||||
|
||||
-- 市场部下属部门
|
||||
(11, NOW(), NOW(), false, 1, 'SALES', '销售部', '负责产品销售', 5, 1, true, null, null),
|
||||
(12, NOW(), NOW(), false, 1, 'PR', '公关部', '负责公共关系', 5, 2, true, null, null);
|
||||
@ -49,4 +49,11 @@ role.admin.cannot.delete=\u4E0D\u80FD\u5220\u9664\u8D85\u7EA7\u7BA1\u7406\u5458\
|
||||
role.admin.cannot.update=\u4E0D\u80FD\u4FEE\u6539\u8D85\u7EA7\u7BA1\u7406\u5458\u89D2\u8272
|
||||
role.tag.name.exists=\u6807\u7B7E\u540D\u79F0\u5DF2\u5B58\u5728
|
||||
role.tag.not.found=\u6807\u7B7E\u4E0D\u5B58\u5728
|
||||
role.tag.in.use=\u6807\u7B7E\u6B63\u5728\u4F7F\u7528\u4E2D\uFF0C\u65E0\u6CD5\u5220\u9664
|
||||
role.tag.in.use=\u6807\u7B7E\u6B63\u5728\u4F7F\u7528\u4E2D\uFF0C\u65E0\u6CD5\u5220\u9664
|
||||
|
||||
# 部门相关
|
||||
department.not.found=部门不存在
|
||||
department.code.exists=部门编码已存在
|
||||
department.name.exists=部门名称已存在
|
||||
department.parent.not.found=上级部门不存在
|
||||
department.has.children=该部门下有子部门,无法删除
|
||||
6
backend/src/main/resources/messages_en_US.properties
Normal file
6
backend/src/main/resources/messages_en_US.properties
Normal file
@ -0,0 +1,6 @@
|
||||
# Department
|
||||
department.not.found=Department not found
|
||||
department.code.exists=Department code already exists
|
||||
department.name.exists=Department name already exists
|
||||
department.parent.not.found=Parent department not found
|
||||
department.has.children=Cannot delete department with children
|
||||
@ -44,4 +44,11 @@ role.admin.cannot.delete=\u4E0D\u80FD\u5220\u9664\u8D85\u7EA7\u7BA1\u7406\u5458\
|
||||
role.admin.cannot.update=\u4E0D\u80FD\u4FEE\u6539\u8D85\u7EA7\u7BA1\u7406\u5458\u89D2\u8272
|
||||
role.tag.name.exists=\u6807\u7B7E\u540D\u79F0\u5DF2\u5B58\u5728
|
||||
role.tag.not.found=\u6807\u7B7E\u4E0D\u5B58\u5728
|
||||
role.tag.in.use=\u6807\u7B7E\u6B63\u5728\u4F7F\u7528\u4E2D\uFF0C\u65E0\u6CD5\u5220\u9664
|
||||
role.tag.in.use=\u6807\u7B7E\u6B63\u5728\u4F7F\u7528\u4E2D\uFF0C\u65E0\u6CD5\u5220\u9664
|
||||
|
||||
# 部门相关
|
||||
department.not.found=部门不存在
|
||||
department.code.exists=部门编码已存在
|
||||
department.name.exists=部门名称已存在
|
||||
department.parent.not.found=上级部门不存在
|
||||
department.has.children=该部门下有子部门,无法删除
|
||||
Loading…
Reference in New Issue
Block a user