From 9c97b774a069a08a0a5823285e219aaa38cc573d Mon Sep 17 00:00:00 2001 From: none Date: Sun, 19 Feb 2023 12:15:57 +0800 Subject: [PATCH] =?UTF-8?q?=E9=83=A8=E9=97=A8=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/xyz/playedu/api/bus/AppBus.java | 22 ++++ .../xyz/playedu/api/bus/DepartmentBus.java | 32 +++++ .../xyz/playedu/api/config/PlayEduConfig.java | 11 +- .../playedu/api/constant/SystemConstant.java | 4 + .../api/controller/ExceptionController.java | 14 ++- .../backend/DepartmentController.java | 84 +++++++++++++ .../xyz/playedu/api/domain/Department.java | 117 ++++++++++++++++++ .../api/exception/NotFoundException.java | 27 ++++ .../playedu/api/mapper/DepartmentMapper.java | 20 +++ .../api/middleware/AdminAuthMiddleware.java | 7 ++ .../request/backend/DepartmentRequest.java | 33 +++++ .../api/service/DepartmentService.java | 24 ++++ .../service/impl/DepartmentServiceImpl.java | 99 +++++++++++++++ .../java/xyz/playedu/api/util/RedisUtil.java | 3 +- .../resources/mapper/DepartmentMapper.xml | 23 ++++ 15 files changed, 514 insertions(+), 6 deletions(-) create mode 100644 src/main/java/xyz/playedu/api/bus/AppBus.java create mode 100644 src/main/java/xyz/playedu/api/bus/DepartmentBus.java create mode 100644 src/main/java/xyz/playedu/api/controller/backend/DepartmentController.java create mode 100644 src/main/java/xyz/playedu/api/domain/Department.java create mode 100644 src/main/java/xyz/playedu/api/exception/NotFoundException.java create mode 100644 src/main/java/xyz/playedu/api/mapper/DepartmentMapper.java create mode 100644 src/main/java/xyz/playedu/api/request/backend/DepartmentRequest.java create mode 100644 src/main/java/xyz/playedu/api/service/DepartmentService.java create mode 100644 src/main/java/xyz/playedu/api/service/impl/DepartmentServiceImpl.java create mode 100644 src/main/resources/mapper/DepartmentMapper.xml diff --git a/src/main/java/xyz/playedu/api/bus/AppBus.java b/src/main/java/xyz/playedu/api/bus/AppBus.java new file mode 100644 index 0000000..5b1ac1e --- /dev/null +++ b/src/main/java/xyz/playedu/api/bus/AppBus.java @@ -0,0 +1,22 @@ +package xyz.playedu.api.bus; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import xyz.playedu.api.config.PlayEduConfig; +import xyz.playedu.api.constant.SystemConstant; + +/** + * @Author 杭州白书科技有限公司 + * @create 2023/2/19 12:06 + */ +@Component +public class AppBus { + + @Autowired + private PlayEduConfig playEduConfig; + + public boolean isDev() { + return !playEduConfig.getEnv().equals(SystemConstant.ENV_PROD); + } + +} diff --git a/src/main/java/xyz/playedu/api/bus/DepartmentBus.java b/src/main/java/xyz/playedu/api/bus/DepartmentBus.java new file mode 100644 index 0000000..2f87f6f --- /dev/null +++ b/src/main/java/xyz/playedu/api/bus/DepartmentBus.java @@ -0,0 +1,32 @@ +package xyz.playedu.api.bus; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import xyz.playedu.api.domain.Department; +import xyz.playedu.api.exception.NotFoundException; +import xyz.playedu.api.service.DepartmentService; + +/** + * @Author 杭州白书科技有限公司 + * @create 2023/2/19 11:02 + */ + +@Component +public class DepartmentBus { + + @Autowired + private DepartmentService departmentService; + + public String compParentChain(Integer parentId) throws NotFoundException { + String parentChain = ""; + if (parentId != 0) { + Department parentDepartment = departmentService.getById(parentId); + if (parentDepartment == null) { + throw new NotFoundException("父级部门不存在"); + } + parentChain = parentDepartment.getParentChain() + "," + parentId; + } + return parentChain; + } + +} diff --git a/src/main/java/xyz/playedu/api/config/PlayEduConfig.java b/src/main/java/xyz/playedu/api/config/PlayEduConfig.java index 3f891fb..dd1572e 100644 --- a/src/main/java/xyz/playedu/api/config/PlayEduConfig.java +++ b/src/main/java/xyz/playedu/api/config/PlayEduConfig.java @@ -1,5 +1,14 @@ package xyz.playedu.api.config; +import lombok.Data; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +@Component +@Data public class PlayEduConfig { - public static String REDIS_PREFIX = "playedu:"; + + @Value("${spring.profiles.active}") + private String env; + } diff --git a/src/main/java/xyz/playedu/api/constant/SystemConstant.java b/src/main/java/xyz/playedu/api/constant/SystemConstant.java index 67a1b37..b271a30 100644 --- a/src/main/java/xyz/playedu/api/constant/SystemConstant.java +++ b/src/main/java/xyz/playedu/api/constant/SystemConstant.java @@ -2,6 +2,10 @@ package xyz.playedu.api.constant; public class SystemConstant { + public final static String ENV_PROD = "prod"; + + public static String REDIS_PREFIX = "playedu:"; + public final static String JWT_PRV_ADMIN_USER = "dc14511e97e7eb725fb2976bc939b375"; } diff --git a/src/main/java/xyz/playedu/api/controller/ExceptionController.java b/src/main/java/xyz/playedu/api/controller/ExceptionController.java index f097eb9..b58d106 100644 --- a/src/main/java/xyz/playedu/api/controller/ExceptionController.java +++ b/src/main/java/xyz/playedu/api/controller/ExceptionController.java @@ -6,6 +6,7 @@ import org.springframework.web.HttpRequestMethodNotSupportedException; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import xyz.playedu.api.exception.NotFoundException; import xyz.playedu.api.exception.ServiceException; import xyz.playedu.api.types.JsonResponse; @@ -14,10 +15,10 @@ import java.util.List; @RestControllerAdvice public class ExceptionController { -// @ExceptionHandler(Exception.class) -// public JsonResponse exceptionHandler(Exception e) { -// return JsonResponse.error("系统错误", 500); -// } + @ExceptionHandler(Exception.class) + public JsonResponse exceptionHandler(Exception e) { + return JsonResponse.error("系统错误", 500); + } @ExceptionHandler(ServiceException.class) public JsonResponse serviceExceptionHandler(ServiceException e) { @@ -45,4 +46,9 @@ public class ExceptionController { return JsonResponse.error("请求method错误", 400); } + @ExceptionHandler(NotFoundException.class) + public JsonResponse serviceExceptionHandler(NotFoundException e) { + return JsonResponse.error(e.getMessage(), 404); + } + } diff --git a/src/main/java/xyz/playedu/api/controller/backend/DepartmentController.java b/src/main/java/xyz/playedu/api/controller/backend/DepartmentController.java new file mode 100644 index 0000000..f5da6d6 --- /dev/null +++ b/src/main/java/xyz/playedu/api/controller/backend/DepartmentController.java @@ -0,0 +1,84 @@ +package xyz.playedu.api.controller.backend; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.bind.annotation.*; +import xyz.playedu.api.bus.DepartmentBus; +import xyz.playedu.api.domain.Department; +import xyz.playedu.api.exception.NotFoundException; +import xyz.playedu.api.request.backend.DepartmentRequest; +import xyz.playedu.api.service.DepartmentService; +import xyz.playedu.api.types.JsonResponse; + +import java.util.Date; +import java.util.List; + +/** + * @Author 杭州白书科技有限公司 + * @create 2023/2/19 10:33 + */ +@RestController +@Slf4j +@RequestMapping("/backend/v1/department") +public class DepartmentController { + + @Autowired + private DepartmentService departmentService; + + @Autowired + private DepartmentBus departmentBus; + + @GetMapping("/index") + public JsonResponse index() { + List data = departmentService.list(); + return JsonResponse.data(data); + } + + @GetMapping("/create") + public JsonResponse create(@RequestParam(name = "parent_id", defaultValue = "0") Integer parentId) { + List data = departmentService.listByParentId(parentId); + return JsonResponse.data(data); + } + + @PostMapping("/create") + public JsonResponse store(@RequestBody DepartmentRequest request) throws NotFoundException { + String parentChain = ""; + if (request.getParentId() != 0) { + parentChain = departmentBus.compParentChain(request.getParentId()); + } + + Department department = new Department(); + department.setName(request.getName()); + department.setParentId(request.getParentId()); + department.setParentChain(parentChain); + department.setSort(request.getSort()); + department.setCreatedAt(new Date()); + department.setUpdatedAt(new Date()); + + departmentService.save(department); + + return JsonResponse.success(); + } + + @GetMapping("/{id}") + public JsonResponse edit(@PathVariable Integer id) throws NotFoundException { + Department department = departmentService.findOrFail(id); + return JsonResponse.data(department); + } + + @PutMapping("/{id}") + public JsonResponse update(@PathVariable Integer id, @RequestBody DepartmentRequest request) throws NotFoundException { + Department department = departmentService.findOrFail(id); + departmentService.update(department, request.getName(), request.getParentId(), request.getSort()); + return JsonResponse.success(); + } + + @DeleteMapping("/{id}") + public JsonResponse destroy(@PathVariable Integer id) throws NotFoundException { + Department department = departmentService.findOrFail(id); + departmentService.deleteById(department.getId()); + return JsonResponse.success(); + } + +} diff --git a/src/main/java/xyz/playedu/api/domain/Department.java b/src/main/java/xyz/playedu/api/domain/Department.java new file mode 100644 index 0000000..59363ff --- /dev/null +++ b/src/main/java/xyz/playedu/api/domain/Department.java @@ -0,0 +1,117 @@ +package xyz.playedu.api.domain; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +import com.baomidou.mybatisplus.annotation.TableId; +import com.baomidou.mybatisplus.annotation.TableName; +import java.io.Serializable; +import java.util.Date; +import lombok.Data; + +/** + * + * @TableName departments + */ +@TableName(value ="departments") +@Data +public class Department implements Serializable { + /** + * + */ + @TableId(type = IdType.AUTO) + private Integer id; + + /** + * 部门名 + */ + private String name; + + /** + * 父id + */ + private Integer parentId; + + /** + * 父链 + */ + private String parentChain; + + /** + * 升序 + */ + private Integer sort; + + /** + * + */ + private Date createdAt; + + /** + * + */ + private Date updatedAt; + + /** + * + */ + private Date deletedAt; + + @TableField(exist = false) + private static final long serialVersionUID = 1L; + + @Override + public boolean equals(Object that) { + if (this == that) { + return true; + } + if (that == null) { + return false; + } + if (getClass() != that.getClass()) { + return false; + } + Department other = (Department) that; + return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId())) + && (this.getName() == null ? other.getName() == null : this.getName().equals(other.getName())) + && (this.getParentId() == null ? other.getParentId() == null : this.getParentId().equals(other.getParentId())) + && (this.getParentChain() == null ? other.getParentChain() == null : this.getParentChain().equals(other.getParentChain())) + && (this.getSort() == null ? other.getSort() == null : this.getSort().equals(other.getSort())) + && (this.getCreatedAt() == null ? other.getCreatedAt() == null : this.getCreatedAt().equals(other.getCreatedAt())) + && (this.getUpdatedAt() == null ? other.getUpdatedAt() == null : this.getUpdatedAt().equals(other.getUpdatedAt())) + && (this.getDeletedAt() == null ? other.getDeletedAt() == null : this.getDeletedAt().equals(other.getDeletedAt())); + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((getId() == null) ? 0 : getId().hashCode()); + result = prime * result + ((getName() == null) ? 0 : getName().hashCode()); + result = prime * result + ((getParentId() == null) ? 0 : getParentId().hashCode()); + result = prime * result + ((getParentChain() == null) ? 0 : getParentChain().hashCode()); + result = prime * result + ((getSort() == null) ? 0 : getSort().hashCode()); + result = prime * result + ((getCreatedAt() == null) ? 0 : getCreatedAt().hashCode()); + result = prime * result + ((getUpdatedAt() == null) ? 0 : getUpdatedAt().hashCode()); + result = prime * result + ((getDeletedAt() == null) ? 0 : getDeletedAt().hashCode()); + return result; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append(getClass().getSimpleName()); + sb.append(" ["); + sb.append("Hash = ").append(hashCode()); + sb.append(", id=").append(id); + sb.append(", name=").append(name); + sb.append(", parentId=").append(parentId); + sb.append(", parentChain=").append(parentChain); + sb.append(", sort=").append(sort); + sb.append(", createdAt=").append(createdAt); + sb.append(", updatedAt=").append(updatedAt); + sb.append(", deletedAt=").append(deletedAt); + sb.append(", serialVersionUID=").append(serialVersionUID); + sb.append("]"); + return sb.toString(); + } +} \ No newline at end of file diff --git a/src/main/java/xyz/playedu/api/exception/NotFoundException.java b/src/main/java/xyz/playedu/api/exception/NotFoundException.java new file mode 100644 index 0000000..66911a5 --- /dev/null +++ b/src/main/java/xyz/playedu/api/exception/NotFoundException.java @@ -0,0 +1,27 @@ +package xyz.playedu.api.exception; + +/** + * @Author 杭州白书科技有限公司 + * @create 2023/2/19 11:04 + */ +public class NotFoundException extends Exception { + public NotFoundException() { + super(); + } + + public NotFoundException(String message) { + super(message); + } + + public NotFoundException(String message, Throwable cause) { + super(message, cause); + } + + public NotFoundException(Throwable cause) { + super(cause); + } + + protected NotFoundException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { + super(message, cause, enableSuppression, writableStackTrace); + } +} diff --git a/src/main/java/xyz/playedu/api/mapper/DepartmentMapper.java b/src/main/java/xyz/playedu/api/mapper/DepartmentMapper.java new file mode 100644 index 0000000..b77f936 --- /dev/null +++ b/src/main/java/xyz/playedu/api/mapper/DepartmentMapper.java @@ -0,0 +1,20 @@ +package xyz.playedu.api.mapper; + +import org.apache.ibatis.annotations.Mapper; +import xyz.playedu.api.domain.Department; +import com.baomidou.mybatisplus.core.mapper.BaseMapper; + +/** +* @author tengteng +* @description 针对表【departments】的数据库操作Mapper +* @createDate 2023-02-19 10:39:57 +* @Entity xyz.playedu.api.domain.Department +*/ +@Mapper +public interface DepartmentMapper extends BaseMapper { + +} + + + + diff --git a/src/main/java/xyz/playedu/api/middleware/AdminAuthMiddleware.java b/src/main/java/xyz/playedu/api/middleware/AdminAuthMiddleware.java index c21b627..cbb7ef8 100644 --- a/src/main/java/xyz/playedu/api/middleware/AdminAuthMiddleware.java +++ b/src/main/java/xyz/playedu/api/middleware/AdminAuthMiddleware.java @@ -8,6 +8,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.web.servlet.HandlerInterceptor; import xyz.playedu.api.PlayEduThreadLocal; +import xyz.playedu.api.bus.AppBus; import xyz.playedu.api.bus.BackendBus; import xyz.playedu.api.constant.SystemConstant; import xyz.playedu.api.domain.AdminUser; @@ -29,6 +30,9 @@ public class AdminAuthMiddleware implements HandlerInterceptor { @Autowired private AdminUserService adminUserService; + @Autowired + private AppBus appBus; + @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { if (BackendBus.inUnAuthWhitelist(request.getRequestURI())) { @@ -56,6 +60,9 @@ public class AdminAuthMiddleware implements HandlerInterceptor { return HandlerInterceptor.super.preHandle(request, response, handler); } catch (Exception e) { + if (appBus.isDev()) { + log.debug("jwt解析失败:" + e.getMessage()); + } responseTransform(response, 401, "请重新登录"); return false; } diff --git a/src/main/java/xyz/playedu/api/request/backend/DepartmentRequest.java b/src/main/java/xyz/playedu/api/request/backend/DepartmentRequest.java new file mode 100644 index 0000000..e518bb1 --- /dev/null +++ b/src/main/java/xyz/playedu/api/request/backend/DepartmentRequest.java @@ -0,0 +1,33 @@ +package xyz.playedu.api.request.backend; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotNull; +import lombok.Data; +import org.hibernate.validator.constraints.Length; +import org.springframework.validation.annotation.Validated; + +import java.io.Serial; +import java.io.Serializable; + +/** + * @Author 杭州白书科技有限公司 + * @create 2023/2/19 10:42 + */ +@Validated +@Data +public class DepartmentRequest implements Serializable { + @Serial + private static final long serialVersionUID = 1L; + + @NotNull(message = "请输入部门名称") + @Length(min = 1, max = 20, message = "部门名称长度在1-20个字符之间") + private String name; + + @NotNull(message = "请选择部门上级") + private Integer parentId; + + @NotNull(message = "请输入排序值") + @Min(value = 0, message = "排序值不能小于0") + private Integer sort; + +} diff --git a/src/main/java/xyz/playedu/api/service/DepartmentService.java b/src/main/java/xyz/playedu/api/service/DepartmentService.java new file mode 100644 index 0000000..1c4610f --- /dev/null +++ b/src/main/java/xyz/playedu/api/service/DepartmentService.java @@ -0,0 +1,24 @@ +package xyz.playedu.api.service; + +import xyz.playedu.api.domain.Department; +import com.baomidou.mybatisplus.extension.service.IService; +import xyz.playedu.api.exception.NotFoundException; + +import java.util.List; + +/** + * @author tengteng + * @description 针对表【departments】的数据库操作Service + * @createDate 2023-02-19 10:39:57 + */ +public interface DepartmentService extends IService { + + List listByParentId(Integer id); + + Department findOrFail(Integer id) throws NotFoundException; + + void deleteById(Integer id) throws NotFoundException; + + void update(Department department, String name, Integer parentId, Integer sort) throws NotFoundException; + +} diff --git a/src/main/java/xyz/playedu/api/service/impl/DepartmentServiceImpl.java b/src/main/java/xyz/playedu/api/service/impl/DepartmentServiceImpl.java new file mode 100644 index 0000000..9a92f67 --- /dev/null +++ b/src/main/java/xyz/playedu/api/service/impl/DepartmentServiceImpl.java @@ -0,0 +1,99 @@ +package xyz.playedu.api.service.impl; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import lombok.extern.slf4j.Slf4j; +import org.springframework.transaction.annotation.Transactional; +import xyz.playedu.api.domain.Department; +import xyz.playedu.api.exception.NotFoundException; +import xyz.playedu.api.service.DepartmentService; +import xyz.playedu.api.mapper.DepartmentMapper; +import org.springframework.stereotype.Service; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * @author tengteng + * @description 针对表【departments】的数据库操作Service实现 + * @createDate 2023-02-19 10:39:57 + */ +@Service +@Slf4j +public class DepartmentServiceImpl extends ServiceImpl implements DepartmentService { + @Override + public List listByParentId(Integer id) { + return this.getBaseMapper().selectList(query().eq("parent_id", id)); + } + + @Override + public Department findOrFail(Integer id) throws NotFoundException { + Department department = this.getBaseMapper().selectById(id); + if (department == null) { + throw new NotFoundException("部门不存在"); + } + return department; + } + + @Override + @Transactional + public void deleteById(Integer id) throws NotFoundException { + Department department = findOrFail(id); + updateParentChain(department); + removeById(department.getId()); + } + + @Override + @Transactional + public void update(Department department, String name, Integer parentId, Integer sort) throws NotFoundException { + Department data = new Department(); + if (!department.getName().equals(name)) { + data.setName(name); + } + if (!department.getParentId().equals(parentId)) { + data.setParentId(parentId); + Department parent = findOrFail(parentId); + data.setParentChain(parent.getParentChain() + "," + parent.getId()); + } + if (!department.getSort().equals(sort)) { + data.setSort(sort); + } + save(data); + + department = getById(department.getId()); + updateParentChain(department); + } + + private void updateParentChain(Department department) { + if (department.getParentId().equals(0)) { + return; + } + + //需要重置chain的子部门 + List children = list(query().like("parent_chain", "%" + department.getParentChain())); + if (children.size() == 0) { + return; + } + + // 计算新的parentChain前缀 + String[] chainIds = department.getParentChain().split(","); + String newChainPrefix = String.join(",", Arrays.copyOfRange(chainIds, 0, chainIds.length - 1)); + + log.info("新的前缀:" + newChainPrefix); + + ArrayList updateRows = new ArrayList<>(); + for (Department tmpDepartment : children) { + Department tmpUpdateDepartment = new Department(); + tmpUpdateDepartment.setId(tmpDepartment.getId()); + tmpUpdateDepartment.setParentChain(tmpDepartment.getParentChain().replaceFirst(department.getParentChain(), newChainPrefix)); + + updateRows.add(tmpUpdateDepartment); + } + updateBatchById(updateRows); + } +} + + + + diff --git a/src/main/java/xyz/playedu/api/util/RedisUtil.java b/src/main/java/xyz/playedu/api/util/RedisUtil.java index 641a486..35286c4 100644 --- a/src/main/java/xyz/playedu/api/util/RedisUtil.java +++ b/src/main/java/xyz/playedu/api/util/RedisUtil.java @@ -9,6 +9,7 @@ import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.stereotype.Component; import org.springframework.util.CollectionUtils; import xyz.playedu.api.config.PlayEduConfig; +import xyz.playedu.api.constant.SystemConstant; import java.util.*; import java.util.concurrent.TimeUnit; @@ -17,7 +18,7 @@ import java.util.concurrent.TimeUnit; public class RedisUtil { private static RedisTemplate redisTemplate; - private static final String redisPrefix = PlayEduConfig.REDIS_PREFIX; + private static final String redisPrefix = SystemConstant.REDIS_PREFIX; /** * 注入Redis diff --git a/src/main/resources/mapper/DepartmentMapper.xml b/src/main/resources/mapper/DepartmentMapper.xml new file mode 100644 index 0000000..fc8436e --- /dev/null +++ b/src/main/resources/mapper/DepartmentMapper.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + id,name,parent_id, + parent_chain,sort,created_at, + updated_at,deleted_at + +