From 2dfc2dfa627d413dfbfe0276d51332680afa5eff Mon Sep 17 00:00:00 2001
From: huangzhen <867217663@qq.com>
Date: 星期四, 07 九月 2023 16:31:07 +0800
Subject: [PATCH] 增加全局异常;区划缓存
---
ruoyi-system/src/main/java/com/ruoyi/system/domain/resp/DistrictTreeRespDTO.java | 27 +++
ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java | 35 +++
ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java | 5
ruoyi-common/src/main/java/com/ruoyi/common/exception/BusinessException.java | 74 ++++++++
ruoyi-common/src/main/java/com/ruoyi/common/exception/ExceptionInfo.java | 46 +++++
ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDistrictMapper.java | 15 +
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDistrictServiceImpl.java | 126 ++++++++++++++
ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDistrict.java | 25 ++
ruoyi-system/src/main/java/com/ruoyi/system/service/SysDistrictService.java | 35 +++
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDistrictController.java | 48 +++++
ruoyi-common/src/main/java/com/ruoyi/common/constant/ResultConstants.java | 88 +++++++++
11 files changed, 524 insertions(+), 0 deletions(-)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDistrictController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDistrictController.java
new file mode 100644
index 0000000..f2c2312
--- /dev/null
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysDistrictController.java
@@ -0,0 +1,48 @@
+package com.ruoyi.web.controller.system;
+
+
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.system.domain.SysDistrict;
+import com.ruoyi.system.domain.resp.DistrictTreeRespDTO;
+import com.ruoyi.system.service.SysDistrictService;
+import org.springframework.web.bind.annotation.*;
+import javax.annotation.Resource;
+import java.io.Serializable;
+import java.util.List;
+
+import static com.ruoyi.common.core.domain.AjaxResult.success;
+
+/**
+ * @author hz
+ * @since 2023-09-07 13:13:47
+ */
+@RestController
+@RequestMapping("/system/sysDistrict/")
+public class SysDistrictController {
+ /**
+ * 获取所有
+ */
+ @Resource
+ private SysDistrictService sysDistrictService;
+
+ @GetMapping("/list")
+ public AjaxResult selectAll() {
+ List<SysDistrict> sysDistricts = sysDistrictService.selectAll();
+ return AjaxResult.success(sysDistricts);
+ }
+
+ /**
+ * 树状返回
+ *
+ */
+ @GetMapping("/tree")
+ public AjaxResult selectAllByTree() {
+ List<DistrictTreeRespDTO> sysDistricts = sysDistrictService.selectAllByTree();
+ return AjaxResult.success(sysDistricts);
+ }
+
+}
+
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
index 0080343..7c06bcf 100644
--- a/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/CacheConstants.java
@@ -27,6 +27,11 @@
*/
public static final String SYS_DICT_KEY = "sys_dict:";
+
+ public static final String SYS_DISTRICT_LIST_KEY = "sys_district_list";
+
+ public static final String SYS_DISTRICT_TREE_KEY = "sys_district_tree";
+
/**
* 防重提交 redis key
*/
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/constant/ResultConstants.java b/ruoyi-common/src/main/java/com/ruoyi/common/constant/ResultConstants.java
new file mode 100644
index 0000000..bb680d9
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/constant/ResultConstants.java
@@ -0,0 +1,88 @@
+package com.ruoyi.common.constant;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public enum ResultConstants {
+
+ //正常
+ OK(200,"成功"),
+
+ NOT_OK(500,"错误"),
+
+ //参数错误
+ PARAM_ERROR(300,"参数错误"),
+ PARAM_ERROR_NULL(301,"参数不能为空"),
+ PARAM_ERROR_ILLEGAL(301,"参数格式错误"),
+ PARAM_ERROR_OUT_OF_RANGE(302,"参数超出限制"),
+
+
+
+ //业务错误
+ BUSINESS_ERROR(400,"业务错误"),
+ BUSINESS_ERROR_ACCOUNT_NOT_EXIST(401,"用户不存在"),
+ BUSINESS_ERROR_ACCOUNT_STATU_ABNORMAL(402,"账号异常"),
+ BUSINESS_ERROR_ACCOUNT_OFFLINE(403,"用户未登录"),
+ BUSINESS_ERROR_PERMISSION_DENIALED(405,"操作未授权"),
+ BUSINESS_ERROR_OUT_OF_TIME(406,"业务超时"),
+ BUSINESS_ERROR_OBJECT_NOT_EXIST(407,"业务单元不存在"),
+ BUSINESS_ERROR_NOT_ALLOWED(408,"业务不允许"),
+ BUSINESS_ERROR_HTTP_METHOD_NOT_SUPPORT(409,"HTTP请求方法不支持"),
+ BUSINESS_ERROR_DATA_NOT_EXISIST(410,"数据不存在"),
+
+
+
+ //系统错误
+ SYSTEM_ERROR(500,"系统出错"),
+ SYSTEM_ERROR_API_FAIL(501,"接口错误"),
+ SYSTEM_ERROR_API_OUT_OF_TIME(502,"接口超时"),
+ SYSTEM_ERROR_DATABASE_FAIL(503,"数据库错误"),
+ SYSTEM_ERROR_SERIALIZA_FAIL(504,"序列化错误"),
+ //文件
+ FILE_NOT_EXISIST(600,"文件不存在"),
+ PATH_NOT_EXISIST(601,"文件路径不存在"),
+ MODULE_NOT_EXISIST(602,"模块不存在"),
+ FILE_UPLOAD_FAIL(603,"文件上传失败"),
+ FILE_DOWNLOAD_FAIL(604,"文件下载失败"),
+ FILE_DOWNLOAD_EXPERTION(605,"文件下载异常"),
+ ;
+
+
+
+ ResultConstants(Integer code, String desc) {
+ this.code = code;
+ this.desc = desc;
+ }
+
+ private Integer code;
+ private String desc;
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+ public String getDesc() {
+ return desc;
+ }
+
+ public void setDesc(String desc) {
+ this.desc = desc;
+ }
+
+ static Map<Integer,ResultConstants> map;
+
+ static {
+ map = new HashMap<>();
+ for(ResultConstants rc : ResultConstants.values()){
+ map.put(rc.getCode(),rc);
+ }
+ }
+
+ public static ResultConstants prase(Integer code){
+ return map.get(code);
+ }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/BusinessException.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/BusinessException.java
new file mode 100644
index 0000000..6b46590
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/BusinessException.java
@@ -0,0 +1,74 @@
+package com.ruoyi.common.exception;
+
+import com.ruoyi.common.constant.ResultConstants;
+
+public class BusinessException extends RuntimeException {
+
+ private Class causeClass;
+
+ private Integer code;
+
+ private String message;
+
+// public BusinessException(ResultCode error) {
+// super(error.getDesc());
+// this.code = error.getCode();
+// this.message = error.getDesc();
+// }
+
+ public BusinessException(Class causeClass, ResultConstants error) {
+ super(error.getDesc());
+ this.causeClass = causeClass;
+ this.code = error.getCode();
+ this.message = error.getDesc();
+ }
+
+ public BusinessException(Class causeClass, ResultConstants error, String message) {
+ super(error.getDesc());
+ this.causeClass = causeClass;
+ this.code = error.getCode();
+ if(message != null && !message.isEmpty()){
+ this.message = message;
+ }else {
+ this.message = error.getDesc();
+ }
+ }
+
+// public BusinessException(Integer code, String message) {
+// super(message);
+// this.code = code;
+// this.message = message;
+// }
+
+ public BusinessException(Class causeClass, Integer code, String message) {
+ super(message);
+ this.causeClass = causeClass;
+ this.code = code;
+ this.message = message;
+ }
+
+ public Class getCauseClass() {
+ return causeClass;
+ }
+
+ public void setCauseClass(Class causeClass) {
+ this.causeClass = causeClass;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+ @Override
+ public String getMessage() {
+ return message;
+ }
+
+ public void setMessage(String message) {
+ this.message = message;
+ }
+}
diff --git a/ruoyi-common/src/main/java/com/ruoyi/common/exception/ExceptionInfo.java b/ruoyi-common/src/main/java/com/ruoyi/common/exception/ExceptionInfo.java
new file mode 100644
index 0000000..2d980b5
--- /dev/null
+++ b/ruoyi-common/src/main/java/com/ruoyi/common/exception/ExceptionInfo.java
@@ -0,0 +1,46 @@
+package com.ruoyi.common.exception;
+
+import java.time.LocalDateTime;
+
+public class ExceptionInfo {
+
+ private Class causeClass;
+
+ private LocalDateTime time;
+
+ private Integer code;
+
+ private String msg;
+
+ public Class getCauseClass() {
+ return causeClass;
+ }
+
+ public void setCauseClass(Class causeClass) {
+ this.causeClass = causeClass;
+ }
+
+ public LocalDateTime getTime() {
+ return time;
+ }
+
+ public void setTime(LocalDateTime time) {
+ this.time = time;
+ }
+
+ public Integer getCode() {
+ return code;
+ }
+
+ public void setCode(Integer code) {
+ this.code = code;
+ }
+
+ public String getMsg() {
+ return msg;
+ }
+
+ public void setMsg(String msg) {
+ this.msg = msg;
+ }
+}
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
index a3ec182..1d6d9e5 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/exception/GlobalExceptionHandler.java
@@ -1,14 +1,22 @@
package com.ruoyi.framework.web.exception;
import javax.servlet.http.HttpServletRequest;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ruoyi.common.constant.ResultConstants;
+import com.ruoyi.common.exception.BusinessException;
+import com.ruoyi.common.exception.ExceptionInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
+import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import com.ruoyi.common.constant.HttpStatus;
@@ -16,6 +24,8 @@
import com.ruoyi.common.exception.DemoModeException;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
+
+import java.time.LocalDateTime;
/**
* 全局异常处理器
@@ -27,6 +37,31 @@
{
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ /**
+ * 通用异常
+ */
+ @ResponseBody
+ @ExceptionHandler(value = BusinessException.class)
+ public AjaxResult businessExceptionHandler(BusinessException e) throws JsonProcessingException {
+ ExceptionInfo exceptionInfo = new ExceptionInfo();
+ exceptionInfo.setTime(LocalDateTime.now());
+ exceptionInfo.setCode(e.getCode());
+ exceptionInfo.setMsg(e.getMessage());
+ exceptionInfo.setCauseClass(e.getCauseClass());
+ log.error(objectMapper.writeValueAsString(exceptionInfo));
+ if(e.getMessage() == null || e.getMessage().isEmpty()){
+ ResultConstants code = ResultConstants.prase(e.getCode());
+ if(code != null)
+ return AjaxResult.error(e.getCode(),code.getDesc());
+ }else {
+ return AjaxResult.error(e.getCode(),e.getMessage());
+ }
+ return AjaxResult.error();
+ }
+
/**
* 权限校验异常
*/
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDistrict.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDistrict.java
new file mode 100644
index 0000000..ccb8924
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysDistrict.java
@@ -0,0 +1,25 @@
+package com.ruoyi.system.domain;
+
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * @author hz
+ * @since 2023-09-07 13:13:57
+ */
+@Data
+public class SysDistrict implements Serializable {
+
+ private Long id;
+
+ private String code;
+
+ private String name;
+
+ private String parentcode;
+
+ private Byte type;
+}
+
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/domain/resp/DistrictTreeRespDTO.java b/ruoyi-system/src/main/java/com/ruoyi/system/domain/resp/DistrictTreeRespDTO.java
new file mode 100644
index 0000000..70c74c8
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/domain/resp/DistrictTreeRespDTO.java
@@ -0,0 +1,27 @@
+package com.ruoyi.system.domain.resp;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * @author Mr.huang
+ * @decription
+ * @date 2023/9/7 15:22
+ */
+@Data
+public class DistrictTreeRespDTO implements Serializable {
+
+ private Long id;
+
+ private String code;
+
+ private String name;
+
+ private String parentcode;
+
+ private Byte type;
+
+ private List<DistrictTreeRespDTO> children;
+}
\ No newline at end of file
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDistrictMapper.java b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDistrictMapper.java
new file mode 100644
index 0000000..43bc28d
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/mapper/SysDistrictMapper.java
@@ -0,0 +1,15 @@
+package com.ruoyi.system.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.system.domain.SysDistrict;
+import org.springframework.stereotype.Repository;
+
+/**
+ * @author hz
+ * @since 2023-09-07 13:13:52
+ */
+@Repository
+public interface SysDistrictMapper extends BaseMapper<SysDistrict> {
+
+}
+
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/SysDistrictService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysDistrictService.java
new file mode 100644
index 0000000..aa48dd1
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/SysDistrictService.java
@@ -0,0 +1,35 @@
+package com.ruoyi.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.system.domain.SysDistrict;
+import com.ruoyi.system.domain.resp.DistrictTreeRespDTO;
+
+import java.util.List;
+
+/**
+ * @author hz
+ * @since 2023-09-07 13:13:57
+ */
+public interface SysDistrictService extends IService<SysDistrict> {
+
+ List<SysDistrict> selectAll();
+
+ /**
+ * 加载字典缓存数据
+ */
+ public void loadingDistrictCache();
+
+ /**
+ * 清空字典缓存数据
+ */
+ public void clearDistrictCache();
+
+ /**
+ * 重置字典缓存数据
+ */
+ public void resetDistrictCache();
+
+ List<DistrictTreeRespDTO> selectAllByTree();
+}
+
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDistrictServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDistrictServiceImpl.java
new file mode 100644
index 0000000..6e04e05
--- /dev/null
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysDistrictServiceImpl.java
@@ -0,0 +1,126 @@
+package com.ruoyi.system.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.constant.CacheConstants;
+import com.ruoyi.common.constant.ResultConstants;
+import com.ruoyi.common.core.domain.AjaxResult;
+import com.ruoyi.common.core.domain.entity.SysDictData;
+import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.exception.BusinessException;
+import com.ruoyi.common.utils.DictUtils;
+import com.ruoyi.common.utils.spring.SpringUtils;
+import com.ruoyi.system.domain.resp.DistrictTreeRespDTO;
+import com.ruoyi.system.mapper.SysDistrictMapper;
+import com.ruoyi.system.domain.SysDistrict;
+import com.ruoyi.system.service.SysDistrictService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.util.CollectionUtils;
+
+import javax.annotation.PostConstruct;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.ruoyi.common.utils.DictUtils.clearDictCache;
+
+/**
+ * @author hz
+ * @since 2023-09-07 13:13:58
+ */
+@Service("sysDistrictService")
+public class SysDistrictServiceImpl extends ServiceImpl<SysDistrictMapper, SysDistrict> implements SysDistrictService {
+
+ @PostConstruct
+ public void init()
+ {
+ loadingDistrictCache();
+ }
+
+ @Override
+ public List<SysDistrict> selectAll() {
+ if (SpringUtils.getBean(RedisCache.class).hasKey(CacheConstants.SYS_DISTRICT_LIST_KEY)){
+ List<SysDistrict> sysDistricts = SpringUtils.getBean(RedisCache.class).getCacheObject(CacheConstants.SYS_DISTRICT_LIST_KEY);
+ return sysDistricts;
+ }
+ List<SysDistrict> list = this.list();
+ SpringUtils.getBean(RedisCache.class).setCacheObject(CacheConstants.SYS_DISTRICT_LIST_KEY, list);
+ return list;
+ }
+
+ @Override
+ public void loadingDistrictCache()
+ {
+ List<SysDistrict> list = this.list();
+ if (!CollectionUtils.isEmpty(list)) {
+ SpringUtils.getBean(RedisCache.class).setCacheObject(CacheConstants.SYS_DISTRICT_LIST_KEY, list);
+ }
+ List<DistrictTreeRespDTO> treeRespDTOS = this.selectAllByTree();
+ if (!CollectionUtils.isEmpty(treeRespDTOS)) {
+ SpringUtils.getBean(RedisCache.class).setCacheObject(CacheConstants.SYS_DISTRICT_TREE_KEY, list);
+ }
+ }
+
+
+ @Override
+ public void clearDistrictCache()
+ {
+ if (SpringUtils.getBean(RedisCache.class).hasKey(CacheConstants.SYS_DISTRICT_LIST_KEY)){
+ SpringUtils.getBean(RedisCache.class).deleteObject(CacheConstants.SYS_DISTRICT_LIST_KEY);
+ }
+ if (SpringUtils.getBean(RedisCache.class).hasKey(CacheConstants.SYS_DISTRICT_TREE_KEY)){
+ SpringUtils.getBean(RedisCache.class).deleteObject(CacheConstants.SYS_DISTRICT_TREE_KEY);
+ }
+ }
+
+ /**
+ * 重置区划缓存数据
+ */
+ @Override
+ public void resetDistrictCache()
+ {
+ clearDistrictCache();
+ loadingDistrictCache();
+ }
+
+ @Override
+ public List<DistrictTreeRespDTO> selectAllByTree() {
+ if (SpringUtils.getBean(RedisCache.class).hasKey(CacheConstants.SYS_DISTRICT_TREE_KEY)){
+ List<DistrictTreeRespDTO> sysDistrictTree = SpringUtils.getBean(RedisCache.class).getCacheObject(CacheConstants.SYS_DISTRICT_TREE_KEY);
+ return sysDistrictTree;
+ }
+ List<SysDistrict> districts = this.selectAll();
+ if (CollectionUtils.isEmpty(districts)){
+ throw new BusinessException(this.getClass(), ResultConstants.SYSTEM_ERROR_DATABASE_FAIL,"区划信息获取失败");
+ }
+ //获取父节点,0表示父节点,让此次递归有个开头
+ List<DistrictTreeRespDTO> collect = districts.stream()
+ //父节点的id = 0,根据它开始进行实现。
+ .filter(e -> e.getParentcode().equals("0"))
+ .map(e ->{
+ DistrictTreeRespDTO dto = new DistrictTreeRespDTO();
+ BeanUtils.copyProperties(e,dto);
+ //将过滤之后的数据来进行方法调用,拿到他的所有的子节点信息并进行封装
+ dto.setChildren(getchildrens(dto, districts));
+ return dto;
+ }).collect(Collectors.toList());
+ SpringUtils.getBean(RedisCache.class).setCacheObject(CacheConstants.SYS_DISTRICT_TREE_KEY, collect);
+ return collect;
+ }
+
+ private List<DistrictTreeRespDTO> getchildrens(DistrictTreeRespDTO root,List<SysDistrict> districts){
+ //root为每次最新的传递过来的数据,也就是上面过滤之后的 e ;
+ List<DistrictTreeRespDTO> collect = districts.stream()
+ //根据传递过来的 e ,拿到他的id,来查询出他的子节点id 这里有个特点 e.id = 子节点的父节点id
+ .filter(e -> Objects.equals(e.getParentcode(), root.getCode()))
+ .map(e -> {
+ DistrictTreeRespDTO dto = new DistrictTreeRespDTO();
+ BeanUtils.copyProperties(e,dto);
+ dto.setChildren(getchildrens(dto, districts));
+ //递归找到他的子节点,直到找到最后一个子节点为止,饼进行封装。
+ return dto;
+ }).collect(Collectors.toList());
+ return collect;
+ }
+
+}
+
--
Gitblit v1.9.2