增加部门

This commit is contained in:
戚辰先生 2024-12-01 14:37:03 +08:00
parent 9c949fe5c7
commit 9975d4508e
12 changed files with 285 additions and 127 deletions

View File

@ -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: 实现导出功能
}
}

View File

@ -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 的方法不需要再声明
}

View File

@ -49,7 +49,14 @@ public enum ResponseCode {
// 角色标签相关错误码 (4300-4399) // 角色标签相关错误码 (4300-4399)
ROLE_TAG_NAME_EXISTS(4300, "role.tag.name.exists"), ROLE_TAG_NAME_EXISTS(4300, "role.tag.name.exists"),
ROLE_TAG_NOT_FOUND(4301, "role.tag.not.found"), 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 int code;
private final String messageKey; // 国际化消息key private final String messageKey; // 国际化消息key

View File

@ -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;
}

View File

@ -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;
}

View File

@ -1,18 +1,15 @@
//package com.qqchen.deploy.backend.service; 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.framework.service.IBaseService;
//import com.qqchen.deploy.backend.entity.Department; import com.qqchen.deploy.backend.model.DepartmentDTO;
//
//import java.util.List; import java.util.List;
//
//public interface IDepartmentService extends IBaseService<Department, Long> { public interface IDepartmentService extends IBaseService<Department, DepartmentDTO, Long> {
//
// List<Department> getTree(); /**
// * 获取部门树
// void validateCode(String code); */
// List<DepartmentDTO> getTree();
// void validateName(String name); }
//
// Integer getNextSort(Long parentId);
//}

View File

@ -1,105 +1,76 @@
//package com.qqchen.deploy.backend.service.impl; package com.qqchen.deploy.backend.service.impl;
//
//import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl; import com.qqchen.deploy.backend.converter.DepartmentConverter;
//import com.qqchen.deploy.backend.entity.Department; import com.qqchen.deploy.backend.entity.Department;
//import com.qqchen.deploy.backend.repository.IDepartmentRepository; import com.qqchen.deploy.backend.framework.enums.ResponseCode;
//import com.qqchen.deploy.backend.service.IDepartmentService; import com.qqchen.deploy.backend.framework.exception.UniqueConstraintException;
//import org.springframework.beans.factory.annotation.Autowired; import com.qqchen.deploy.backend.framework.service.impl.BaseServiceImpl;
//import org.springframework.stereotype.Service; import com.qqchen.deploy.backend.model.DepartmentDTO;
//import jakarta.transaction.Transactional; import com.qqchen.deploy.backend.repository.IDepartmentRepository;
//import java.util.ArrayList; import com.qqchen.deploy.backend.service.IDepartmentService;
//import java.util.List; import com.qqchen.deploy.backend.framework.annotation.ServiceType;
//import java.util.Map; import lombok.extern.slf4j.Slf4j;
//import java.util.stream.Collectors; import org.springframework.stereotype.Service;
// import jakarta.annotation.Resource;
//@Service
//@Transactional import java.util.*;
//public class DepartmentServiceImpl extends BaseServiceImpl<Department, Long> implements IDepartmentService {
// import static com.qqchen.deploy.backend.framework.annotation.ServiceType.Type.DATABASE;
// private final IDepartmentRepository repository;
// @Slf4j
// @Autowired @Service
// public DepartmentServiceImpl(IDepartmentRepository repository) { @ServiceType(DATABASE)
// super(repository); public class DepartmentServiceImpl extends BaseServiceImpl<Department, DepartmentDTO, Long> implements IDepartmentService {
// this.repository = repository;
// } @Resource
// private IDepartmentRepository departmentRepository;
// @Override
// public Department create(Department entity) { @Resource
// validateCode(entity.getCode()); private DepartmentConverter departmentConverter;
// validateName(entity.getName());
// return repository.save(entity); @Override
// } protected void validateUniqueConstraints(DepartmentDTO dto) {
// // 检查部门编码唯一性
// public Department update(Long id, Department entity) { if (departmentRepository.existsByCodeAndDeletedFalse(dto.getCode())) {
// Department existing = repository.findById(id) throw new UniqueConstraintException(ResponseCode.DEPARTMENT_CODE_EXISTS, "code", dto.getCode());
// .orElseThrow(() -> new RuntimeException("部门不存在")); }
//
// entity.setVersion(existing.getVersion()); // 检查部门名称唯一性
// entity.setId(id); if (departmentRepository.existsByNameAndDeletedFalse(dto.getName())) {
// throw new UniqueConstraintException(ResponseCode.DEPARTMENT_NAME_EXISTS, "name", dto.getName());
// if (!existing.getCode().equals(entity.getCode())) { }
// if (repository.existsByCodeAndDeletedFalse(entity.getCode())) { }
// throw new RuntimeException("部门编码已存在");
// } @Override
// } public List<DepartmentDTO> getTree() {
// List<Department> departments = departmentRepository.findByDeletedFalseOrderBySort();
// if (!existing.getName().equals(entity.getName())) { return buildTree(departments);
// if (repository.existsByNameAndDeletedFalse(entity.getName())) { }
// throw new RuntimeException("部门名称已存在");
// } private List<DepartmentDTO> buildTree(List<Department> departments) {
// } Map<Long, DepartmentDTO> dtoMap = new HashMap<>();
// List<DepartmentDTO> roots = new ArrayList<>();
// entity.setCreateTime(existing.getCreateTime());
// entity.setCreateBy(existing.getCreateBy()); // 转换为DTO并建立映射
// entity.setDeleted(existing.getDeleted()); departments.forEach(dept -> {
// DepartmentDTO dto = departmentConverter.toDto(dept);
// return repository.save(entity); dto.setChildren(new ArrayList<>());
// } dtoMap.put(dto.getId(), dto);
// });
// @Override
// public List<Department> getTree() { // 构建树形结构
// List<Department> departments = repository.findByDeletedFalseOrderBySort(); departments.forEach(dept -> {
// return buildTree(departments); DepartmentDTO dto = dtoMap.get(dept.getId());
// } if (dept.getParentId() == null || dept.getParentId() == 0) {
// roots.add(dto);
// @Override } else {
// public void validateCode(String code) { DepartmentDTO parent = dtoMap.get(dept.getParentId());
// if (repository.existsByCodeAndDeletedFalse(code)) { if (parent != null) {
// throw new RuntimeException("部门编码已存在"); parent.getChildren().add(dto);
// } }
// } }
// });
// @Override
// public void validateName(String name) { return roots;
// 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;
// }
//}

View File

@ -175,3 +175,23 @@ CREATE TABLE sys_template_menu (
CONSTRAINT FK_template_menu_menu FOREIGN KEY (menu_id) REFERENCES sys_menu (id) CONSTRAINT FK_template_menu_menu FOREIGN KEY (menu_id) REFERENCES sys_menu (id)
) COMMENT '模板菜单关联表'; ) 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)
);

View File

@ -96,3 +96,28 @@ VALUES
(1, 3), -- 超级管理员 -> 安全标签 (1, 3), -- 超级管理员 -> 安全标签
(2, 1), -- 开发主管 -> 研发标签 (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);

View File

@ -50,3 +50,10 @@ role.admin.cannot.update=\u4E0D\u80FD\u4FEE\u6539\u8D85\u7EA7\u7BA1\u7406\u5458\
role.tag.name.exists=\u6807\u7B7E\u540D\u79F0\u5DF2\u5B58\u5728 role.tag.name.exists=\u6807\u7B7E\u540D\u79F0\u5DF2\u5B58\u5728
role.tag.not.found=\u6807\u7B7E\u4E0D\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=该部门下有子部门,无法删除

View 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

View File

@ -45,3 +45,10 @@ role.admin.cannot.update=\u4E0D\u80FD\u4FEE\u6539\u8D85\u7EA7\u7BA1\u7406\u5458\
role.tag.name.exists=\u6807\u7B7E\u540D\u79F0\u5DF2\u5B58\u5728 role.tag.name.exists=\u6807\u7B7E\u540D\u79F0\u5DF2\u5B58\u5728
role.tag.not.found=\u6807\u7B7E\u4E0D\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=该部门下有子部门,无法删除