Переглянути джерело

Merge branch 'security'

# Conflicts:
#	src/main/java/com/szwl/controller/TAdminController.java
wuhongshuang 3 роки тому
батько
коміт
8bc8706d31
56 змінених файлів з 1750 додано та 51 видалено
  1. 10 1
      README.md
  2. 11 6
      pom.xml
  3. 52 0
      src/main/java/com/szwl/annotation/Audit.java
  4. 235 0
      src/main/java/com/szwl/aspect/AuditAspect.java
  5. 41 0
      src/main/java/com/szwl/aspect/HeadTokenInterceptor.java
  6. 41 0
      src/main/java/com/szwl/aspect/MyWebMvcConfigurer.java
  7. 49 0
      src/main/java/com/szwl/constant/AuditEnum.java
  8. 10 0
      src/main/java/com/szwl/constant/ConfigConsts.java
  9. 72 0
      src/main/java/com/szwl/constant/MenuEnum.java
  10. 23 0
      src/main/java/com/szwl/controller/DemoController.java
  11. 72 0
      src/main/java/com/szwl/controller/SysRoleMenuController.java
  12. 115 0
      src/main/java/com/szwl/manager/TokenManager.java
  13. 16 0
      src/main/java/com/szwl/mapper/AuditLogMapper.java
  14. 16 0
      src/main/java/com/szwl/mapper/SysRoleMapper.java
  15. 16 0
      src/main/java/com/szwl/mapper/SysUserRoleMapper.java
  16. 23 0
      src/main/java/com/szwl/model/bo/UserDetailBO.java
  17. 16 0
      src/main/java/com/szwl/model/dto/OptionDTO.java
  18. 54 0
      src/main/java/com/szwl/model/entity/AuditLog.java
  19. 41 0
      src/main/java/com/szwl/model/entity/SysRole.java
  20. 40 0
      src/main/java/com/szwl/model/entity/SysUserRole.java
  21. 38 0
      src/main/java/com/szwl/model/param/AddLoginUserParam.java
  22. 26 0
      src/main/java/com/szwl/model/param/AddSysRoleParam.java
  23. 27 0
      src/main/java/com/szwl/model/param/UpdateSysRoleParam.java
  24. 16 0
      src/main/java/com/szwl/service/AuditLogService.java
  25. 27 0
      src/main/java/com/szwl/service/SysRoleService.java
  26. 16 0
      src/main/java/com/szwl/service/SysUserRoleService.java
  27. 2 5
      src/main/java/com/szwl/service/TAdminService.java
  28. 2 2
      src/main/java/com/szwl/service/TAlarmClockItemService.java
  29. 2 1
      src/main/java/com/szwl/service/TAlarmClockService.java
  30. 2 2
      src/main/java/com/szwl/service/TAlarmRecordService.java
  31. 2 2
      src/main/java/com/szwl/service/TAreaService.java
  32. 2 2
      src/main/java/com/szwl/service/TCoinOrderService.java
  33. 2 1
      src/main/java/com/szwl/service/TEquipmentApplyService.java
  34. 2 2
      src/main/java/com/szwl/service/TEquipmentDescService.java
  35. 2 2
      src/main/java/com/szwl/service/TEquipmentService.java
  36. 2 2
      src/main/java/com/szwl/service/TJoinpayMchCheckService.java
  37. 2 3
      src/main/java/com/szwl/service/TJoinpayMchService.java
  38. 2 2
      src/main/java/com/szwl/service/TMessageCodeService.java
  39. 2 2
      src/main/java/com/szwl/service/TOrderService.java
  40. 2 2
      src/main/java/com/szwl/service/TParametersService.java
  41. 2 2
      src/main/java/com/szwl/service/TProductService.java
  42. 2 2
      src/main/java/com/szwl/service/TProportionCheckService.java
  43. 2 2
      src/main/java/com/szwl/service/TProportionService.java
  44. 2 2
      src/main/java/com/szwl/service/TShandeMchCheckService.java
  45. 2 2
      src/main/java/com/szwl/service/TShandeMchService.java
  46. 2 2
      src/main/java/com/szwl/service/TSugarDoService.java
  47. 21 0
      src/main/java/com/szwl/service/base/MyIService.java
  48. 20 0
      src/main/java/com/szwl/service/impl/AuditLogServiceImpl.java
  49. 93 0
      src/main/java/com/szwl/service/impl/SysRoleServiceImpl.java
  50. 26 0
      src/main/java/com/szwl/service/impl/SysUserRoleServiceImpl.java
  51. 227 0
      src/main/java/com/szwl/util/ServletUtil.java
  52. 134 0
      src/main/java/com/szwl/util/SpringUtils.java
  53. 66 0
      src/main/java/com/szwl/util/UrlUtil.java
  54. 2 0
      src/main/resources/application.yml
  55. 17 1
      src/main/resources/bootstrap.yml
  56. 1 1
      src/test/java/com/szwl/AutoGeneratorTests.java

+ 10 - 1
README.md

@@ -1,4 +1,8 @@
 # szwlServer 申泽移动物联
+## 功能设计文档
+UI:https://lanhuapp.com/url/i9MYZ
+文档:https://docs.qq.com/doc/DUEtOTHB3TlpyT1Ri
+UI图:https://lanhuapp.com/url/rk4hO-Av0mUD
 
 ## 注册中心
 http://112.74.63.148:49001/
@@ -38,4 +42,9 @@ ResponseCodesEnum 为错误码,其中 ALL_OK("00000","SUCCESS") 表示成功
 启动命令:/app/appsystem/startSpringCloud.sh  /app/appsystem/springcloud/你的包名.jar
 查看状态:/app/appsystem/checkSpringCloud.sh
 关闭命令:/app/appsystem/stopSpringCloud.sh /app/appsystem/springcloud/你的包名.jar
-查看日志:vi /app/applogs/szwl-server/szwl-server.log
+查看日志:vi /app/applogs/szwl-server/szwl-server.log
+
+## 审计日志
+例:@Audit(type = AuditEnum.QUERY,bizNo = "#returnObj.data.num",content = "#loginUser.userRealName + '调用 测试审计日志功能'")
+参考 DemoController.testAuditLog
+日志内容,支持SPEL,使用 #作为标识符,具体参考com.szwl.annotation.Audit 里面的描述

+ 11 - 6
pom.xml

@@ -52,11 +52,6 @@
 				<artifactId>mybatis-plus-generator</artifactId>
 				<version>${mybatis-plus.version}</version>
 			</dependency>
-<!--			<dependency>-->
-<!--				<groupId>org.mybatis.spring.boot</groupId>-->
-<!--				<artifactId>mybatis-spring-boot-starter</artifactId>-->
-<!--				<version>${mybatis-spring-boot-starter.version}</version>-->
-<!--			</dependency>-->
 		</dependencies>
 	</dependencyManagement>
 
@@ -198,6 +193,16 @@
 			<artifactId>EsBaseServer</artifactId>
 			<version>1.2.10</version>
 		</dependency>
+		<!--redis start-->
+		<dependency>
+			<groupId>org.springframework.boot</groupId>
+			<artifactId>spring-boot-starter-data-redis</artifactId>
+		</dependency>
+		<dependency>
+			<groupId>org.apache.commons</groupId>
+			<artifactId>commons-pool2</artifactId>
+		</dependency>
+		<!--redis end-->
 	</dependencies>
 
 	<build>
@@ -219,7 +224,7 @@
 		</repository>
 		<repository>
 			<id>nexus</id>
-			<url>http://www.redouble.store:1888/repository/maven-public/</url>
+			<url>http://www.redouble.store:1888/repository/crbank-host/</url>
 			<releases>
 				<enabled>true</enabled>
 			</releases>

+ 52 - 0
src/main/java/com/szwl/annotation/Audit.java

@@ -0,0 +1,52 @@
+package com.szwl.annotation;
+
+import com.szwl.constant.AuditEnum;
+
+import java.lang.annotation.*;
+
+/**
+ * 审计日志
+ *
+ * @author wuhs
+ * @date 2022-05-17 11:40
+ */
+@Target({ElementType.METHOD})
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+public @interface Audit {
+
+    /**
+     * 日志内容,支持SPEL,使用 #作为标识符
+     * 使用说明:
+     * 一、获取登录用户:
+     *  1、#loginUser 即可获取登录的DefaultUserDetails对象,如果使用了@IgnoreToken,则获取到一个new DefaultUserDetails()
+     *
+     * 二、获取方法参数:
+     *  1、接口参数为int、String等基本数据类型的,参数名为id,直接使用 #id则可以获取到值
+     *  2、接口参数为对象的,如 #obj.propertyA、#obj.propertyB
+     *
+     *  三、获取方法返回值对象:
+     *  1、#returnObj 为该方法的返回值对象
+     *
+     * 四、引用Bean
+     *  1、使用@beanId可以获取spring中注册了的bean,例如:@sysUserServiceImpl.getById(#loginUser.userId)可以获取到SysUserService对象,使用里面的方法
+     *
+     *  五、综合使用:
+     *  1、@Audit(content = "#loginUser.userRealName + '禁用了用户' + #banUserId")
+     *  解析结果为:测试用户禁用了用户202205180000001
+     *  2、@Audit(content = "#loginUser.userRealName + '给用户组[' + @sysUserGroupServiceImpl.getById(#req.userGroupId).userGroupName + ']添加了用户:' + #req.userIds")
+     *  解析结果为:张三给用户组[测试组]添加了用户:202109151538040291a2d37fb9ef641398
+     */
+    String content();
+
+    /**
+     * 业务编号,支持SPEL
+     */
+    String bizNo() default "";
+
+    /**
+     * 业务类型
+     */
+    AuditEnum type();
+
+}

+ 235 - 0
src/main/java/com/szwl/aspect/AuditAspect.java

@@ -0,0 +1,235 @@
+package com.szwl.aspect;
+
+import com.alibaba.fastjson.JSON;
+import com.szwl.annotation.Audit;
+import com.szwl.manager.TokenManager;
+import com.szwl.model.bo.UserDetailBO;
+import com.szwl.model.entity.AuditLog;
+import com.szwl.service.AuditLogService;
+import com.szwl.util.SpringUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.exception.ExceptionUtils;
+import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.annotation.Around;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.reflect.MethodSignature;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.expression.BeanFactoryResolver;
+import org.springframework.core.DefaultParameterNameDiscoverer;
+import org.springframework.core.ParameterNameDiscoverer;
+import org.springframework.expression.EvaluationContext;
+import org.springframework.expression.Expression;
+import org.springframework.expression.ExpressionParser;
+import org.springframework.expression.spel.standard.SpelExpressionParser;
+import org.springframework.expression.spel.support.StandardEvaluationContext;
+import org.springframework.stereotype.Component;
+
+import java.lang.reflect.Method;
+import java.util.Date;
+import java.util.LinkedHashMap;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author wuhs
+ * @date 2022-05-17 11:45
+ */
+@Aspect
+@Component
+@Slf4j
+public class AuditAspect {
+    @Autowired
+    AuditLogService auditLogService;
+    @Autowired
+    private TokenManager securityManager;
+
+    @Value("${spring.application.name}")
+    private String appName;
+
+    /**
+     * 解析SPEL,例如#obj.name
+     */
+    private final ExpressionParser parser = new SpelExpressionParser();
+    private final String spElFlag = "#";
+    private static final BeanFactoryResolver BEAN_FACTORY_RESOLVER = new BeanFactoryResolver(SpringUtils.getApplicationContext());
+
+    private static final ThreadPoolExecutor EXECUTOR = new ThreadPoolExecutor(4, 8, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(500));
+
+
+    @Around(value = "@annotation(com.szwl.annotation.Audit)")
+    public Object around(ProceedingJoinPoint point) throws Throwable {
+        boolean success = false;
+        Exception exception = null;
+        Object[] reqValue = null;
+        Object respValue = null;
+        try {
+            Object[] args = point.getArgs();
+            reqValue = args;
+            Object result = point.proceed(args);
+            respValue = result;
+            success = true;
+            return result;
+        } catch (Exception e) {
+            exception = e;
+            throw e;
+        } finally {
+            UserDetailBO userDetails;
+            try {
+                userDetails = securityManager.getLoginUserDetails();
+            } catch (Exception e) {
+                userDetails = new UserDetailBO();
+            }
+            EXECUTOR.execute(new AuditThread(userDetails, success, point, exception, reqValue, respValue));
+        }
+    }
+
+    private String getReqValue(Object[] args) {
+        try {
+            return JSON.toJSONString(args);
+        } catch (Exception e) {
+            log.info("--解析请求参数失败:{}", e.getMessage());
+            return null;
+        }
+    }
+
+    private String getRespValue(Object result) {
+        try {
+            return JSON.toJSONString(result);
+        } catch (Exception e) {
+            log.info("--解析响应参数失败:{}", e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * 创建审计日志
+     *
+     * @param userDetails
+     * @param success
+     * @param point
+     * @param exception
+     */
+    private void buildAuditLog(UserDetailBO userDetails, boolean success, ProceedingJoinPoint point, Exception exception, Object[] reqValue, Object respValue) {
+        if(null == userDetails){
+            userDetails = new UserDetailBO();
+            userDetails.setUsername("none");
+            userDetails.setName("none");
+        }
+        MethodSignature signature = (MethodSignature) point.getSignature();
+        Method method = signature.getMethod();
+        Audit audit = method.getAnnotation(Audit.class);
+        if (audit == null) {
+            return;
+        }
+        //求值上下文
+        StandardEvaluationContext context = new StandardEvaluationContext();
+        //设置参数进去
+        context.setVariables(resolveArgs(point));
+        //给定特定的参数
+        context.setVariable("loginUser", userDetails);
+        context.setVariable("returnObj", respValue);
+        context.setBeanResolver(BEAN_FACTORY_RESOLVER);
+        //构建log对象
+        AuditLog logParam = new AuditLog();
+        try {
+            logParam.setBizNo(resolveValue(audit.bizNo(), context));
+        } catch (Exception e) {
+            logParam.setBizNo(String.format("SPEL-ERROR bizNo[%s]失败,原因:%s", audit.bizNo(), e.getMessage()));
+        }
+        try {
+            logParam.setContent(resolveValue(audit.content(), context));
+        } catch (Exception e) {
+            logParam.setContent(String.format("SPEL-ERROR content[%s]失败,原因:%s", audit.content(), e.getMessage()));
+        }
+        logParam.setType(audit.type().getCode());
+        logParam.setCreateTime(new Date());
+        logParam.setMethod(method.getDeclaringClass().getName() + "#" + method.getName());
+        logParam.setSuccess(success);
+        logParam.setException(exception != null && !success ? ExceptionUtils.getStackTrace(exception) : null);
+        logParam.setReqValue(getReqValue(reqValue));
+        logParam.setRespValue(getRespValue(respValue));
+        logParam.setOperatorUserName(userDetails.getUsername());
+        logParam.setOperatorUserRealName(userDetails.getName());
+        logParam.setOperatorIp(userDetails.getCurrentIp());
+        logParam.setOwnerSys(appName);
+        log.info("--生成的审计日志:{}", JSON.toJSONString(logParam));
+        auditLogService.save(logParam);
+    }
+
+    /**
+     * 解析参数
+     *
+     * @param point
+     * @return
+     */
+    private LinkedHashMap<String, Object> resolveArgs(ProceedingJoinPoint point) {
+        MethodSignature signature = (MethodSignature) point.getSignature();
+        Method method = signature.getMethod();
+        Object[] args = point.getArgs();
+        String[] argNames = getArgNames(method);
+        LinkedHashMap<String, Object> params = new LinkedHashMap<>();
+        for (int i = 0; i < args.length; i++) {
+            params.put(argNames[i], args[i]);
+        }
+        return params;
+    }
+
+    /**
+     * 获取参数属性名
+     *
+     * @param method
+     * @return
+     */
+    private String[] getArgNames(Method method) {
+        ParameterNameDiscoverer parameterNameDiscoverer = new DefaultParameterNameDiscoverer();
+        return parameterNameDiscoverer.getParameterNames(method);
+    }
+
+    private String resolveValue(String content, EvaluationContext context) {
+        String value;
+        if (content.contains(spElFlag)) {
+            //解析SPEL
+            value = resolveValueByExpression(content, context);
+        } else {
+            //不处理
+            value = content;
+        }
+        return value;
+    }
+
+    private String resolveValueByExpression(String spElString, EvaluationContext context) {
+        //构建表达式
+        Expression expression = parser.parseExpression(spElString);
+        //解析
+        return expression.getValue(context, String.class);
+    }
+
+    class AuditThread implements Runnable {
+        private UserDetailBO userDetails;
+        private boolean success;
+        private ProceedingJoinPoint point;
+        private Exception exception;
+        private Object[] reqValue;
+        private Object respValue;
+
+        public AuditThread(UserDetailBO userDetails, boolean success, ProceedingJoinPoint point, Exception exception, Object[] reqValue, Object respValue) {
+            this.userDetails = userDetails;
+            this.success = success;
+            this.point = point;
+            this.exception = exception;
+            this.reqValue = reqValue;
+            this.respValue = respValue;
+        }
+
+        @Override
+        public void run() {
+            try {
+                buildAuditLog(userDetails, success, point, exception, reqValue, respValue);
+            } catch (Exception e) {
+                log.info("--审计日志记录失败:", e);
+            }
+        }
+    }
+}

+ 41 - 0
src/main/java/com/szwl/aspect/HeadTokenInterceptor.java

@@ -0,0 +1,41 @@
+package com.szwl.aspect;
+
+import com.szwl.constant.ResponseCodesEnum;
+import com.szwl.exception.BizException;
+import com.szwl.manager.TokenManager;
+import com.szwl.util.UrlUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+import org.springframework.web.servlet.HandlerInterceptor;
+import org.springframework.web.servlet.ModelAndView;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+@Component
+@Slf4j
+public class HeadTokenInterceptor implements HandlerInterceptor {
+    @Autowired
+    private TokenManager tokenManager;
+    //在Controller执行之前调用,如果返回false,controller不执行
+    @Override
+    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
+        String uri = request.getRequestURI();
+        log.info("preHandle uri:{}",uri);
+        if(tokenManager.checkToken(request)){
+            return true;
+        }
+        throw new BizException(ResponseCodesEnum.L0006);
+    }
+    //controller执行之后,且页面渲染之前调用
+    @Override
+    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
+    }
+    //页面渲染之后调用,一般用于资源清理操作
+    @Override
+    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
+        tokenManager.removeThreadLocalUser();
+    }
+}

+ 41 - 0
src/main/java/com/szwl/aspect/MyWebMvcConfigurer.java

@@ -0,0 +1,41 @@
+package com.szwl.aspect;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
+
+@Configuration
+public class MyWebMvcConfigurer extends WebMvcConfigurationSupport {
+    @Value("${swagger.url:[]}")
+    private String[] swaggerExcludes;
+    // 白名单
+    @Value("${permitAll.url:[]}")
+    private String[] permitAll;
+    @Autowired
+    private HeadTokenInterceptor headTokenInterceptor;
+    @Override
+    public void addInterceptors(InterceptorRegistry registry) {
+        // 自定义去除的路径
+        String[] myExcludes= {"/tAdmin/login"};
+        registry.addInterceptor(headTokenInterceptor).addPathPatterns("/**")
+                // swagger
+                .excludePathPatterns(swaggerExcludes)
+                // 白名单
+                .excludePathPatterns(permitAll)
+                .excludePathPatterns(myExcludes);
+        super.addInterceptors(registry);
+    }
+    /**
+     * 添加静态资源
+     * @param registry
+     */
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry) {
+        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
+        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
+    }
+}

+ 49 - 0
src/main/java/com/szwl/constant/AuditEnum.java

@@ -0,0 +1,49 @@
+package com.szwl.constant;
+
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+/**
+ * 审计日志类别
+ *
+ * @author wuhs
+ * @date 2022-05-17 11:29
+ */
+public enum AuditEnum implements IEnum<String> {
+
+    INSERT("INSERT","新增"),
+    QUERY("QUERY","查询"),
+    UPDATE("UPDATE","修改"),
+    DELETE("DELETE","删除"),
+    LOGIN("LOGIN","登录"),
+    PAY_ORDER("PAY_ORDER", "支付订单");
+
+    private String code;
+
+    private String desc;
+
+    AuditEnum(String code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+
+    @Override
+    public String getValue() {
+        return this.code;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}

+ 10 - 0
src/main/java/com/szwl/constant/ConfigConsts.java

@@ -5,4 +5,14 @@ package com.szwl.constant;
  */
 public class ConfigConsts {
     public static final String TEST = "TEST";
+    /**
+     * token
+     * 请求头:Authorization
+     */
+    public static final String AUTHORIZATION = "Authorization";
+
+    /**
+     * token时效性
+     */
+    public static final Integer TOKEN_EXPIRE_MINUTE = 30;
 }

+ 72 - 0
src/main/java/com/szwl/constant/MenuEnum.java

@@ -0,0 +1,72 @@
+package com.szwl.constant;
+
+import com.baomidou.mybatisplus.annotation.IEnum;
+import com.szwl.model.dto.OptionDTO;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * 权限菜单
+ * @author wuhs
+ * @date 2022-05-17 11:29
+ */
+public enum MenuEnum implements IEnum<String> {
+
+    M1("M1","设备管理"),
+    M2("M2","设备查看"),
+    M3("M3","分销设置"),
+    M4("M4","报警历史"),
+    M5("M5","广告管理"),
+    M6("M6","任务消息"),
+    M7("M7", "优惠码"),
+    M8("M8", "账号权限"),
+    M9("M9", "订单导出"),
+    M10("M10", "杉德分账"),
+    M11("M11", "销售排行"),
+    M12("M12", "提现账号"),
+    M13("M13", "备用提现账号"),
+    M14("M14", "数据概览"),
+    M15("M15", "订单数据"),
+    M16("M16", "订单退款")
+    ;
+    private String code;
+
+    private String desc;
+
+    MenuEnum(String code, String desc) {
+        this.code = code;
+        this.desc = desc;
+    }
+    // 普通方法
+    public static List<OptionDTO> enumToOptionList() {
+        List<OptionDTO> list = new ArrayList<>();
+        for (MenuEnum c : MenuEnum.values()) {
+            OptionDTO map = new OptionDTO();
+            map.setValue(c.code);
+            map.setLabel(c.desc);
+            list.add(map);
+        }
+        return list;
+    }
+    @Override
+    public String getValue() {
+        return this.code;
+    }
+
+    public String getCode() {
+        return code;
+    }
+
+    public void setCode(String code) {
+        this.code = code;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public void setDesc(String desc) {
+        this.desc = desc;
+    }
+}

+ 23 - 0
src/main/java/com/szwl/controller/DemoController.java

@@ -6,20 +6,26 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.szwl.annotation.Audit;
+import com.szwl.constant.AuditEnum;
 import com.szwl.constant.ResponseCodesEnum;
 import com.szwl.feign.bean.PayFeign;
+import com.szwl.manager.TokenManager;
 import com.szwl.model.bo.R;
 import com.szwl.model.bo.ResponseModel;
+import com.szwl.model.bo.UserDetailBO;
 import com.szwl.model.entity.TAdmin;
 import com.szwl.model.query.TAdminParam;
 import com.szwl.service.TAdminService;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
+import org.apache.commons.collections.map.HashedMap;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.web.bind.annotation.*;
 
 import java.util.List;
+import java.util.Map;
 
 
 @Api(value = "/test", tags = {"测试接口"})
@@ -32,7 +38,24 @@ public class DemoController {
     TAdminService tAdminService;
     @Autowired
     PayFeign payFeign;
+    @Autowired
+    TokenManager tokenManager;
 
+    @ApiOperation(value = "测试根据token获取用户")
+    @GetMapping("/testGetLogin")
+    public ResponseModel<?> testGetLogin() {
+        UserDetailBO userDetailBO = tokenManager.getLoginUserDetails();
+        return R.ok(userDetailBO);
+    }
+    @ApiOperation(value = "测试审计日志功能")
+    @GetMapping("/testAuditLog")
+    @Audit(type = AuditEnum.QUERY,bizNo = "#returnObj.data.num",
+            content = "#loginUser.userRealName + '调用 测试审计日志功能'")
+    public ResponseModel<?> testAuditLog() {
+        Map reslut = new HashedMap();
+        reslut.put("num","111");
+        return R.ok(reslut);
+    }
     @ApiOperation(value = "调用feign")
     @GetMapping("/testFeign")
     public ResponseModel<?> testPage(String id) {

+ 72 - 0
src/main/java/com/szwl/controller/SysRoleMenuController.java

@@ -0,0 +1,72 @@
+package com.szwl.controller;
+
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.gexin.fastjson.JSON;
+import com.szwl.annotation.Audit;
+import com.szwl.constant.AuditEnum;
+import com.szwl.constant.MenuEnum;
+import com.szwl.constant.ResponseCodesEnum;
+import com.szwl.exception.BizException;
+import com.szwl.model.bo.R;
+import com.szwl.model.bo.ResponseModel;
+import com.szwl.model.dto.OptionDTO;
+import com.szwl.model.entity.SysRole;
+import com.szwl.model.param.AddSysRoleParam;
+import com.szwl.model.param.UpdateSysRoleParam;
+import com.szwl.service.SysRoleService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.validation.Valid;
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+@RestController
+@RequestMapping("/sysRoleMenu")
+@Api(value = "/sysRoleMenu", tags = {"角色权限菜单"})
+public class SysRoleMenuController {
+    @Autowired
+    SysRoleService sysRoleService;
+
+    @GetMapping("/listMenuOption")
+    @ApiOperation("获取所有菜单下拉框")
+    public ResponseModel<List<OptionDTO>> listMenuOption() {
+        List<OptionDTO> list = MenuEnum.enumToOptionList();
+        return R.ok(list);
+    }
+
+    @GetMapping("/listRoleOption")
+    @ApiOperation("获取所有角色下拉框")
+    public ResponseModel<List<OptionDTO>> listRoleOption() {
+        List<OptionDTO> list = sysRoleService.list()
+                .stream()
+                .map(e -> new OptionDTO()
+                        .setLabel(e.getRoleName())
+                        .setValue(e.getRoleId())
+                ).collect(Collectors.toList());
+        return R.ok(list);
+    }
+
+    @PostMapping("/addSysRole")
+    @ApiOperation("新增角色及权限菜单")
+    @Audit(type = AuditEnum.INSERT,content = "#loginUser.name + '新增角色及权限菜单'")
+    public ResponseModel<?> addSysRole(@RequestBody @Valid AddSysRoleParam param) {
+        sysRoleService.addSysRole(param);
+        return R.ok();
+    }
+
+    @PostMapping("/updateSysRole")
+    @ApiOperation("修改角色及权限菜单")
+    @Audit(type = AuditEnum.UPDATE,content = "#loginUser.name + '修改角色及权限菜单'")
+    public ResponseModel<?> updateSysRole(@RequestBody @Valid UpdateSysRoleParam param) {
+        sysRoleService.updateSysRole(param);
+        return R.ok();
+    }
+}
+

+ 115 - 0
src/main/java/com/szwl/manager/TokenManager.java

@@ -0,0 +1,115 @@
+package com.szwl.manager;
+
+import cn.hutool.core.thread.threadlocal.NamedThreadLocal;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSON;
+import com.szwl.constant.ConfigConsts;
+import com.szwl.model.bo.UserDetailBO;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.stereotype.Component;
+
+import javax.servlet.http.HttpServletRequest;
+import java.util.concurrent.TimeUnit;
+@Slf4j
+@Component
+public class TokenManager {
+    private static ThreadLocal<UserDetailBO> threadLocal = new NamedThreadLocal<>("user");
+    @Autowired
+    private RedisTemplate<String, String> redisTemplate;
+
+    /**
+     * 校验token
+     * @param request
+     * @return
+     */
+    public boolean checkToken(HttpServletRequest request){
+        String token = request.getHeader(ConfigConsts.AUTHORIZATION);
+        if(StrUtil.isEmpty(token)){
+            return false;
+        }
+        UserDetailBO details = getUserDetails(token);
+        if (null!= details) {
+            threadLocal.set(details);
+            updateAuthenticationExpire(token);
+            return true;
+        }
+        //登陆凭证已过期或不可用
+        log.info("--token {} is expired", token);
+        return false;
+    }
+
+    /**
+     * 获取登录用户
+     * @return
+     */
+    public UserDetailBO getLoginUserDetails() {
+        return threadLocal.get();
+    }
+
+    /**
+     * 清除 threadLocal
+     */
+    public void removeThreadLocalUser(){
+        threadLocal.remove();
+    }
+    /**
+     * 根据token查找认证信息
+     *
+     * @param token
+     * @return
+     */
+    public UserDetailBO getUserDetails(String token) {
+        String val = redisTemplate.opsForValue().get(token);
+        if (StringUtils.isNotEmpty(val)) {
+            try {
+                UserDetailBO details = JSON.parseObject(val, UserDetailBO.class);
+                return details;
+            } catch (Exception e) {
+                return null;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 保存用户信息
+     *
+     * @param token
+     * @param userDetails
+     */
+    public void saveAuthentication(String token, UserDetailBO userDetails) {
+        saveAuthentication(token, userDetails, ConfigConsts.TOKEN_EXPIRE_MINUTE, TimeUnit.MINUTES);
+    }
+
+    /**
+     * 保存用户信息
+     *
+     * @param token
+     * @param userDetails
+     */
+    public void saveAuthentication(String token, UserDetailBO userDetails, int timeout, TimeUnit timeUnit) {
+        userDetails.setCurrentToken(token);
+        redisTemplate.opsForValue().set(token, JSON.toJSONString(userDetails), timeout, timeUnit);
+    }
+
+    /**
+     * 删除用户认证信息
+     *
+     * @param token
+     */
+    public void deleteAuthentication(String token) {
+        redisTemplate.delete(token);
+    }
+
+    /**
+     * 更新用户认证的时效,防止一直操作但token过期
+     *
+     * @param token
+     */
+    public void updateAuthenticationExpire(String token) {
+        redisTemplate.expire(token, ConfigConsts.TOKEN_EXPIRE_MINUTE, TimeUnit.MINUTES);
+    }
+}

+ 16 - 0
src/main/java/com/szwl/mapper/AuditLogMapper.java

@@ -0,0 +1,16 @@
+package com.szwl.mapper;
+
+import com.szwl.model.entity.AuditLog;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-16
+ */
+public interface AuditLogMapper extends BaseMapper<AuditLog> {
+
+}

+ 16 - 0
src/main/java/com/szwl/mapper/SysRoleMapper.java

@@ -0,0 +1,16 @@
+package com.szwl.mapper;
+
+import com.szwl.model.entity.SysRole;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-17
+ */
+public interface SysRoleMapper extends BaseMapper<SysRole> {
+
+}

+ 16 - 0
src/main/java/com/szwl/mapper/SysUserRoleMapper.java

@@ -0,0 +1,16 @@
+package com.szwl.mapper;
+
+import com.szwl.model.entity.SysUserRole;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+
+/**
+ * <p>
+ *  Mapper 接口
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-17
+ */
+public interface SysUserRoleMapper extends BaseMapper<SysUserRole> {
+
+}

+ 23 - 0
src/main/java/com/szwl/model/bo/UserDetailBO.java

@@ -0,0 +1,23 @@
+package com.szwl.model.bo;
+
+import com.szwl.model.entity.TAdmin;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class UserDetailBO extends TAdmin {
+    /**
+     * 当前IP地址
+     */
+    private String currentIp;
+
+    /**
+     * 当前token
+     */
+    private String currentToken;
+
+    @ApiModelProperty("菜单code list")
+    List<String> menuCodeList;
+}

+ 16 - 0
src/main/java/com/szwl/model/dto/OptionDTO.java

@@ -0,0 +1,16 @@
+package com.szwl.model.dto;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+@ApiModel(value="OptionDTO 对象", description="下拉选项")
+@Data
+@Accessors(chain = true)
+public class OptionDTO {
+    @ApiModelProperty(value = "label")
+    String label;
+    @ApiModelProperty(value = "value")
+    String value;
+}

+ 54 - 0
src/main/java/com/szwl/model/entity/AuditLog.java

@@ -0,0 +1,54 @@
+package com.szwl.model.entity;
+
+import java.util.Date;
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-16
+ */
+@Data
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="AuditLog对象", description="审计日志")
+public class AuditLog implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String id;
+
+    private String content;
+
+    private String bizNo;
+
+    private String type;
+
+    private String operatorUserName;
+
+    private String operatorUserRealName;
+
+    private Date createTime;
+
+    private String operatorIp;
+
+    private String method;
+
+    private String reqValue;
+
+    private String respValue;
+
+    private Boolean success;
+
+    private String exception;
+
+    private String ownerSys;
+
+
+}

+ 41 - 0
src/main/java/com/szwl/model/entity/SysRole.java

@@ -0,0 +1,41 @@
+package com.szwl.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-17
+ */
+@Accessors(chain = true)
+@Data
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="SysRole对象", description="")
+public class SysRole implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "ROLE_ID", type = IdType.ASSIGN_ID)
+    @ApiModelProperty(value = "角色id")
+    private String roleId;
+
+    @ApiModelProperty(value = "角色名称")
+    private String roleName;
+
+    @ApiModelProperty(value = "备注")
+    private String remark;
+
+    @ApiModelProperty(value = "权限菜单json")
+    private String menuCodesJson;
+}

+ 40 - 0
src/main/java/com/szwl/model/entity/SysUserRole.java

@@ -0,0 +1,40 @@
+package com.szwl.model.entity;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableField;
+import java.io.Serializable;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.Accessors;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-17
+ */
+@Accessors(chain = true)
+@Data
+@EqualsAndHashCode(callSuper = false)
+@ApiModel(value="SysUserRole对象", description="")
+public class SysUserRole implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "ID", type = IdType.ASSIGN_ID)
+    @ApiModelProperty(value = "id")
+    private String id;
+
+    @ApiModelProperty(value = "用户id")
+    private String userId;
+
+    @ApiModelProperty(value = "角色id")
+    private String roleId;
+
+
+}

+ 38 - 0
src/main/java/com/szwl/model/param/AddLoginUserParam.java

@@ -0,0 +1,38 @@
+package com.szwl.model.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+import java.util.List;
+
+@Accessors(chain = true)
+@ApiModel(description = "添加账号 参数")
+@Data
+public class AddLoginUserParam {
+    @NotBlank(message = "账号 不能为空")
+    @ApiModelProperty(value = "登录名、账号")
+    private String username;
+
+    @NotBlank(message = "密码 不能为空")
+    @ApiModelProperty("密码")
+    private String password;
+
+    @ApiModelProperty(value = "真实姓名")
+    private String name;
+
+    @ApiModelProperty(value = "邮箱")
+    private String email;
+
+    @NotNull
+    @ApiModelProperty(value = "是否启用")
+    private Boolean isEnabled;
+
+    @NotEmpty(message = "请选择角色")
+    @ApiModelProperty("角色id list")
+    List<String> roleList;
+}

+ 26 - 0
src/main/java/com/szwl/model/param/AddSysRoleParam.java

@@ -0,0 +1,26 @@
+package com.szwl.model.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+@Accessors(chain = true)
+@ApiModel(description = "新增角色权限菜单 参数")
+@Data
+public class AddSysRoleParam {
+    @NotBlank(message = "角色名称 不能为空")
+    @ApiModelProperty(value = "角色名称")
+    private String roleName;
+
+    @ApiModelProperty("角色备注")
+    private String remark;
+
+    @NotEmpty(message = "请选择权限菜单")
+    @ApiModelProperty("菜单code list")
+    List<String> menuCodeList;
+}

+ 27 - 0
src/main/java/com/szwl/model/param/UpdateSysRoleParam.java

@@ -0,0 +1,27 @@
+package com.szwl.model.param;
+
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotEmpty;
+import java.util.List;
+
+@Accessors(chain = true)
+@ApiModel(description = "修改角色权限菜单 参数")
+@Data
+public class UpdateSysRoleParam {
+    @NotBlank
+    @ApiModelProperty(value = "角色id")
+    private String roleId;
+
+    @NotBlank(message = "角色名称 不能为空")
+    @ApiModelProperty(value = "角色名称")
+    private String roleName;
+
+    @NotEmpty(message = "请选择权限菜单")
+    @ApiModelProperty("菜单code list")
+    List<String> menuCodeList;
+}

+ 16 - 0
src/main/java/com/szwl/service/AuditLogService.java

@@ -0,0 +1,16 @@
+package com.szwl.service;
+
+import com.szwl.model.entity.AuditLog;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-16
+ */
+public interface AuditLogService extends IService<AuditLog> {
+
+}

+ 27 - 0
src/main/java/com/szwl/service/SysRoleService.java

@@ -0,0 +1,27 @@
+package com.szwl.service;
+
+import com.szwl.model.bo.ResponseModel;
+import com.szwl.model.entity.SysRole;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.model.param.AddSysRoleParam;
+import com.szwl.model.param.UpdateSysRoleParam;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import javax.validation.Valid;
+import java.util.Set;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-17
+ */
+public interface SysRoleService extends IService<SysRole> {
+    Set<String> listAuthMenuByUserId(Long userId);
+    void addSysRole(AddSysRoleParam param);
+    void updateSysRole(UpdateSysRoleParam param);
+}

+ 16 - 0
src/main/java/com/szwl/service/SysUserRoleService.java

@@ -0,0 +1,16 @@
+package com.szwl.service;
+
+import com.szwl.model.entity.SysUserRole;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+/**
+ * <p>
+ *  服务类
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-17
+ */
+public interface SysUserRoleService extends IService<SysUserRole> {
+
+}

+ 2 - 5
src/main/java/com/szwl/service/TAdminService.java

@@ -1,10 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TAdmin;
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.szwl.model.entity.TArea;
-
-import java.util.List;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -14,6 +11,6 @@ import java.util.List;
  * @author wuhs
  * @since 2022-03-28
  */
-public interface TAdminService extends IService<TAdmin> {
+public interface TAdminService extends MyIService<TAdmin> {
 
 }

+ 2 - 2
src/main/java/com/szwl/service/TAlarmClockItemService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TAlarmClockItem;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-06-02
  */
-public interface TAlarmClockItemService extends IService<TAlarmClockItem> {
+public interface TAlarmClockItemService extends MyIService<TAlarmClockItem> {
 
 }

+ 2 - 1
src/main/java/com/szwl/service/TAlarmClockService.java

@@ -2,6 +2,7 @@ package com.szwl.service;
 
 import com.szwl.model.entity.TAlarmClock;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +12,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-06-02
  */
-public interface TAlarmClockService extends IService<TAlarmClock> {
+public interface TAlarmClockService extends MyIService<TAlarmClock> {
 
 }

+ 2 - 2
src/main/java/com/szwl/service/TAlarmRecordService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TAlarmRecord;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 import java.util.List;
 
@@ -13,7 +13,7 @@ import java.util.List;
  * @author wuhs
  * @since 2022-04-27
  */
-public interface TAlarmRecordService extends IService<TAlarmRecord> {
+public interface TAlarmRecordService extends MyIService<TAlarmRecord> {
 
     public List<TAlarmRecord> getAlarmList(Long adminId);
 

+ 2 - 2
src/main/java/com/szwl/service/TAreaService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TArea;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 import java.util.List;
 
@@ -13,7 +13,7 @@ import java.util.List;
  * @author wuhs
  * @since 2022-04-27
  */
-public interface TAreaService extends IService<TArea> {
+public interface TAreaService extends MyIService<TArea> {
 
     List<TArea> getProvinceList();
 }

+ 2 - 2
src/main/java/com/szwl/service/TCoinOrderService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TCoinOrder;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-04-23
  */
-public interface TCoinOrderService extends IService<TCoinOrder> {
+public interface TCoinOrderService extends MyIService<TCoinOrder> {
 
 }

+ 2 - 1
src/main/java/com/szwl/service/TEquipmentApplyService.java

@@ -2,6 +2,7 @@ package com.szwl.service;
 
 import com.szwl.model.entity.TEquipmentApply;
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +12,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-04-21
  */
-public interface TEquipmentApplyService extends IService<TEquipmentApply> {
+public interface TEquipmentApplyService extends MyIService<TEquipmentApply> {
 
 }

+ 2 - 2
src/main/java/com/szwl/service/TEquipmentDescService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TEquipmentDesc;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-04-23
  */
-public interface TEquipmentDescService extends IService<TEquipmentDesc> {
+public interface TEquipmentDescService extends MyIService<TEquipmentDesc> {
 
 }

+ 2 - 2
src/main/java/com/szwl/service/TEquipmentService.java

@@ -1,8 +1,8 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TEquipment;
-import com.baomidou.mybatisplus.extension.service.IService;
 import com.szwl.model.query.StatisticsParam;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -12,7 +12,7 @@ import com.szwl.model.query.StatisticsParam;
  * @author wuhs
  * @since 2022-04-19
  */
-public interface TEquipmentService extends IService<TEquipment> {
+public interface TEquipmentService extends MyIService<TEquipment> {
     /**
      * 发送信息,1:个推,2:MQ
      */

+ 2 - 2
src/main/java/com/szwl/service/TJoinpayMchCheckService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TJoinpayMchCheck;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-04-29
  */
-public interface TJoinpayMchCheckService extends IService<TJoinpayMchCheck> {
+public interface TJoinpayMchCheckService extends MyIService<TJoinpayMchCheck> {
 
 }

+ 2 - 3
src/main/java/com/szwl/service/TJoinpayMchService.java

@@ -1,8 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TJoinpayMch;
-import com.baomidou.mybatisplus.extension.service.IService;
-import com.szwl.model.entity.TJoinpayMchCheck;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -12,7 +11,7 @@ import com.szwl.model.entity.TJoinpayMchCheck;
  * @author wuhs
  * @since 2022-04-29
  */
-public interface TJoinpayMchService extends IService<TJoinpayMch> {
+public interface TJoinpayMchService extends MyIService<TJoinpayMch> {
 
     String createMch(TJoinpayMch tJoinpayMch);
 

+ 2 - 2
src/main/java/com/szwl/service/TMessageCodeService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TMessageCode;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,7 +11,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-04-14
  */
-public interface TMessageCodeService extends IService<TMessageCode> {
+public interface TMessageCodeService extends MyIService<TMessageCode> {
 
     /*
     * 发送短信验证码

+ 2 - 2
src/main/java/com/szwl/service/TOrderService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TOrder;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 import java.util.Map;
 
@@ -13,7 +13,7 @@ import java.util.Map;
  * @author wuhs
  * @since 2022-04-23
  */
-public interface TOrderService extends IService<TOrder> {
+public interface TOrderService extends MyIService<TOrder> {
 
     Double getAreaPrice(Map<String, Object> params);
 }

+ 2 - 2
src/main/java/com/szwl/service/TParametersService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TParameters;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-04-23
  */
-public interface TParametersService extends IService<TParameters> {
+public interface TParametersService extends MyIService<TParameters> {
 
 }

+ 2 - 2
src/main/java/com/szwl/service/TProductService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TProduct;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-04-23
  */
-public interface TProductService extends IService<TProduct> {
+public interface TProductService extends MyIService<TProduct> {
 
 }

+ 2 - 2
src/main/java/com/szwl/service/TProportionCheckService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TProportionCheck;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-05-10
  */
-public interface TProportionCheckService extends IService<TProportionCheck> {
+public interface TProportionCheckService extends MyIService<TProportionCheck> {
 
 }

+ 2 - 2
src/main/java/com/szwl/service/TProportionService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TProportion;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-05-10
  */
-public interface TProportionService extends IService<TProportion> {
+public interface TProportionService extends MyIService<TProportion> {
 
 }

+ 2 - 2
src/main/java/com/szwl/service/TShandeMchCheckService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TShandeMchCheck;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-04-29
  */
-public interface TShandeMchCheckService extends IService<TShandeMchCheck> {
+public interface TShandeMchCheckService extends MyIService<TShandeMchCheck> {
 
 }

+ 2 - 2
src/main/java/com/szwl/service/TShandeMchService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TShandeMch;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-04-29
  */
-public interface TShandeMchService extends IService<TShandeMch> {
+public interface TShandeMchService extends MyIService<TShandeMch> {
 
 }

+ 2 - 2
src/main/java/com/szwl/service/TSugarDoService.java

@@ -1,7 +1,7 @@
 package com.szwl.service;
 
 import com.szwl.model.entity.TSugarDo;
-import com.baomidou.mybatisplus.extension.service.IService;
+import com.szwl.service.base.MyIService;
 
 /**
  * <p>
@@ -11,6 +11,6 @@ import com.baomidou.mybatisplus.extension.service.IService;
  * @author wuhs
  * @since 2022-06-01
  */
-public interface TSugarDoService extends IService<TSugarDo> {
+public interface TSugarDoService extends MyIService<TSugarDo> {
 
 }

+ 21 - 0
src/main/java/com/szwl/service/base/MyIService.java

@@ -0,0 +1,21 @@
+package com.szwl.service.base;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+public interface MyIService<T> extends IService<T> {
+    /**
+     * 仅有一条数据
+     * @param wrapper
+     * @return
+     */
+    default T getOnly(QueryWrapper<T> wrapper){
+        wrapper.last("limit 1");
+        return this.getOne(wrapper);
+    };
+    default T getOnly(LambdaQueryWrapper<T> wrapper){
+        wrapper.last("limit 1");
+        return this.getOne(wrapper);
+    };
+}

+ 20 - 0
src/main/java/com/szwl/service/impl/AuditLogServiceImpl.java

@@ -0,0 +1,20 @@
+package com.szwl.service.impl;
+
+import com.szwl.model.entity.AuditLog;
+import com.szwl.mapper.AuditLogMapper;
+import com.szwl.service.AuditLogService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-16
+ */
+@Service
+public class AuditLogServiceImpl extends ServiceImpl<AuditLogMapper, AuditLog> implements AuditLogService {
+
+}

+ 93 - 0
src/main/java/com/szwl/service/impl/SysRoleServiceImpl.java

@@ -0,0 +1,93 @@
+package com.szwl.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.gexin.fastjson.JSON;
+import com.gexin.fastjson.JSONArray;
+import com.szwl.constant.ResponseCodesEnum;
+import com.szwl.exception.BizException;
+import com.szwl.model.entity.SysRole;
+import com.szwl.mapper.SysRoleMapper;
+import com.szwl.model.entity.SysUserRole;
+import com.szwl.model.param.AddSysRoleParam;
+import com.szwl.model.param.UpdateSysRoleParam;
+import com.szwl.service.SysRoleService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.szwl.service.SysUserRoleService;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-17
+ */
+@Service
+public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
+    @Autowired
+    SysUserRoleService sysUserRoleService;
+    /**
+     * 获取用户所有有权限的菜单
+     * @param userId
+     * @return
+     */
+    @Override
+    public Set<String> listAuthMenuByUserId(Long userId){
+        Set<String> menuList_final = new HashSet<>();
+        // 查询用户的全部角色
+        LambdaQueryWrapper<SysUserRole> query = Wrappers.lambdaQuery();
+        query.eq(SysUserRole::getUserId,userId);
+        List<String> roleIdList = sysUserRoleService.list(query).stream().map(SysUserRole::getRoleId).collect(Collectors.toList());
+        if(CollUtil.isEmpty(roleIdList)){
+            return menuList_final;
+        }
+        List<SysRole> roleList = listByIds(roleIdList);
+        for (SysRole role:roleList) {
+            List<String> menuList = JSON.parseArray(role.getMenuCodesJson(),String.class);
+            CollUtil.addAll(menuList_final,menuList);
+        }
+        return menuList_final;
+    }
+
+    public void checkRoleName(String roleName){
+        LambdaQueryWrapper<SysRole> query = Wrappers.lambdaQuery();
+        query.eq(SysRole::getRoleName, roleName);
+        int count = this.count(query);
+        if(count>0){
+            throw new BizException(ResponseCodesEnum.B0002,"角色名称已存在");
+        }
+    }
+
+    @Override
+    @Transactional
+    public void addSysRole(AddSysRoleParam param){
+        this.checkRoleName(param.getRoleName());
+        SysRole sysRole = new SysRole()
+                .setRoleName(param.getRoleName())
+                .setMenuCodesJson(JSON.toJSONString(param.getMenuCodeList()))
+                .setRemark(param.getRemark());
+        save(sysRole);
+    }
+    @Override
+    @Transactional
+    public void updateSysRole(UpdateSysRoleParam param){
+        SysRole sysRole = Optional.ofNullable(this.getById(param.getRoleId()))
+                .orElseThrow(() ->new BizException(ResponseCodesEnum.B0005,"无法根据id:"+param.getRoleId()+" 找到角色配置"));
+        if(StrUtil.equals(param.getRoleName(),sysRole.getRoleName())){
+            this.checkRoleName(param.getRoleName());
+        }
+        BeanUtil.copyProperties(param,sysRole);
+        sysRole.setMenuCodesJson(JSON.toJSONString(param.getMenuCodeList()));
+        updateById(sysRole);
+    }
+}

+ 26 - 0
src/main/java/com/szwl/service/impl/SysUserRoleServiceImpl.java

@@ -0,0 +1,26 @@
+package com.szwl.service.impl;
+
+import com.szwl.model.entity.SysUserRole;
+import com.szwl.mapper.SysUserRoleMapper;
+import com.szwl.model.param.AddSysRoleParam;
+import com.szwl.model.param.UpdateSysRoleParam;
+import com.szwl.service.SysUserRoleService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.beans.Transient;
+import java.util.List;
+
+/**
+ * <p>
+ *  服务实现类
+ * </p>
+ *
+ * @author wuhs
+ * @since 2022-06-17
+ */
+@Service
+public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements SysUserRoleService {
+
+}

+ 227 - 0
src/main/java/com/szwl/util/ServletUtil.java

@@ -0,0 +1,227 @@
+package com.szwl.util;
+
+import com.alibaba.fastjson.JSON;
+import org.springframework.http.MediaType;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.net.InetAddress;
+import java.net.URLEncoder;
+import java.net.UnknownHostException;
+import java.nio.charset.StandardCharsets;
+
+/**
+ * @author wuhs
+ * @date 2021-11-01 14:13
+ */
+public class ServletUtil {
+
+    /**
+     * 组装下载文件请求体,防止中文乱码
+     *
+     * @param response
+     * @param fileName
+     * @return
+     * @throws UnsupportedEncodingException
+     */
+    public static HttpServletResponse buildDownloadHeader(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
+        response.reset();
+        response.setCharacterEncoding("UTF-8");
+        response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
+        //防止中文乱码
+        String percentEncodedFileName = percentEncode(fileName);
+        StringBuilder contentDispositionValue = new StringBuilder();
+        contentDispositionValue.append("attachment; filename=")
+                .append(percentEncodedFileName)
+                .append(";")
+                .append("filename*=")
+                .append("utf-8''")
+                .append(percentEncodedFileName);
+        response.setHeader("Content-disposition", contentDispositionValue.toString());
+        return response;
+    }
+
+    /**
+     * 百分号编码工具方法
+     *
+     * @param s 需要百分号编码的字符串
+     * @return 百分号编码后的字符串
+     */
+    private static String percentEncode(String s) throws UnsupportedEncodingException {
+        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
+        return encode.replaceAll("\\+", "%20");
+    }
+
+    /**
+     * 以json方式渲染到前端
+     *
+     * @param response
+     * @param value
+     */
+    public static void renderJSON(HttpServletResponse response, Object value) throws IOException {
+        response.setContentType("application/json;charset=UTF-8");
+        response.getWriter().write(JSON.toJSONString(value));
+        response.getWriter().flush();
+        response.getWriter().close();
+    }
+
+    /**
+     * 获取IP方法
+     *
+     * @author ruoyi
+     */
+    public static String getIpAddr(HttpServletRequest request) {
+        if (request == null) {
+            return "unknown";
+        }
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("X-Forwarded-For");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("X-Real-IP");
+        }
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+
+        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
+    }
+
+    public static boolean internalIp(String ip) {
+        byte[] addr = textToNumericFormatV4(ip);
+        return internalIp(addr) || "127.0.0.1".equals(ip);
+    }
+
+    private static boolean internalIp(byte[] addr) {
+        if (addr == null || addr.length < 2) {
+            return true;
+        }
+        final byte b0 = addr[0];
+        final byte b1 = addr[1];
+        // 10.x.x.x/8
+        final byte SECTION_1 = 0x0A;
+        // 172.16.x.x/12
+        final byte SECTION_2 = (byte) 0xAC;
+        final byte SECTION_3 = (byte) 0x10;
+        final byte SECTION_4 = (byte) 0x1F;
+        // 192.168.x.x/16
+        final byte SECTION_5 = (byte) 0xC0;
+        final byte SECTION_6 = (byte) 0xA8;
+        switch (b0) {
+            case SECTION_1:
+                return true;
+            case SECTION_2:
+                if (b1 >= SECTION_3 && b1 <= SECTION_4) {
+                    return true;
+                }
+            case SECTION_5:
+                switch (b1) {
+                    case SECTION_6:
+                        return true;
+                }
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * 将IPv4地址转换成字节
+     *
+     * @param text IPv4地址
+     * @return byte 字节
+     */
+    public static byte[] textToNumericFormatV4(String text) {
+        if (text.length() == 0) {
+            return null;
+        }
+
+        byte[] bytes = new byte[4];
+        String[] elements = text.split("\\.", -1);
+        try {
+            long l;
+            int i;
+            switch (elements.length) {
+                case 1:
+                    l = Long.parseLong(elements[0]);
+                    if ((l < 0L) || (l > 4294967295L)) {
+                        return null;
+                    }
+                    bytes[0] = (byte) (int) (l >> 24 & 0xFF);
+                    bytes[1] = (byte) (int) ((l & 0xFFFFFF) >> 16 & 0xFF);
+                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
+                    bytes[3] = (byte) (int) (l & 0xFF);
+                    break;
+                case 2:
+                    l = Integer.parseInt(elements[0]);
+                    if ((l < 0L) || (l > 255L)) {
+                        return null;
+                    }
+                    bytes[0] = (byte) (int) (l & 0xFF);
+                    l = Integer.parseInt(elements[1]);
+                    if ((l < 0L) || (l > 16777215L)) {
+                        return null;
+                    }
+                    bytes[1] = (byte) (int) (l >> 16 & 0xFF);
+                    bytes[2] = (byte) (int) ((l & 0xFFFF) >> 8 & 0xFF);
+                    bytes[3] = (byte) (int) (l & 0xFF);
+                    break;
+                case 3:
+                    for (i = 0; i < 2; ++i) {
+                        l = Integer.parseInt(elements[i]);
+                        if ((l < 0L) || (l > 255L)) {
+                            return null;
+                        }
+                        bytes[i] = (byte) (int) (l & 0xFF);
+                    }
+                    l = Integer.parseInt(elements[2]);
+                    if ((l < 0L) || (l > 65535L)) {
+                        return null;
+                    }
+                    bytes[2] = (byte) (int) (l >> 8 & 0xFF);
+                    bytes[3] = (byte) (int) (l & 0xFF);
+                    break;
+                case 4:
+                    for (i = 0; i < 4; ++i) {
+                        l = Integer.parseInt(elements[i]);
+                        if ((l < 0L) || (l > 255L)) {
+                            return null;
+                        }
+                        bytes[i] = (byte) (int) (l & 0xFF);
+                    }
+                    break;
+                default:
+                    return null;
+            }
+        } catch (NumberFormatException e) {
+            return null;
+        }
+        return bytes;
+    }
+
+    public static String getHostIp() {
+        try {
+            return InetAddress.getLocalHost().getHostAddress();
+        } catch (UnknownHostException e) {
+        }
+        return "127.0.0.1";
+    }
+
+    public static String getHostName() {
+        try {
+            return InetAddress.getLocalHost().getHostName();
+        } catch (UnknownHostException e) {
+        }
+        return "未知";
+    }
+
+}

+ 134 - 0
src/main/java/com/szwl/util/SpringUtils.java

@@ -0,0 +1,134 @@
+package com.szwl.util;
+
+import org.springframework.aop.framework.AopContext;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.NoSuchBeanDefinitionException;
+import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
+import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.ApplicationContextAware;
+import org.springframework.stereotype.Component;
+
+/**
+ * spring工具类 方便在非spring管理环境中获取bean
+ *
+ * @author ruoyi
+ */
+@Component
+public final class SpringUtils implements BeanFactoryPostProcessor, ApplicationContextAware {
+    /**
+     * Spring应用上下文环境
+     */
+    private static ConfigurableListableBeanFactory beanFactory;
+
+    private static ApplicationContext applicationContext;
+
+    @Override
+    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
+        SpringUtils.beanFactory = beanFactory;
+    }
+
+    @Override
+    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
+        SpringUtils.applicationContext = applicationContext;
+    }
+
+    public static ApplicationContext getApplicationContext() {
+        return SpringUtils.applicationContext;
+    }
+
+    /**
+     * 获取对象
+     *
+     * @param name
+     * @return Object 一个以所给名字注册的bean的实例
+     * @throws BeansException
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T getBean(String name) throws BeansException {
+        return (T) beanFactory.getBean(name);
+    }
+
+    /**
+     * 获取类型为requiredType的对象
+     *
+     * @param clz
+     * @return
+     * @throws BeansException
+     */
+    public static <T> T getBean(Class<T> clz) throws BeansException {
+        T result = (T) beanFactory.getBean(clz);
+        return result;
+    }
+
+    /**
+     * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
+     *
+     * @param name
+     * @return boolean
+     */
+    public static boolean containsBean(String name) {
+        return beanFactory.containsBean(name);
+    }
+
+    /**
+     * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
+     *
+     * @param name
+     * @return boolean
+     * @throws NoSuchBeanDefinitionException
+     */
+    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
+        return beanFactory.isSingleton(name);
+    }
+
+    /**
+     * @param name
+     * @return Class 注册对象的类型
+     * @throws NoSuchBeanDefinitionException
+     */
+    public static Class<?> getType(String name) throws NoSuchBeanDefinitionException {
+        return beanFactory.getType(name);
+    }
+
+    /**
+     * 如果给定的bean名字在bean定义中有别名,则返回这些别名
+     *
+     * @param name
+     * @return
+     * @throws NoSuchBeanDefinitionException
+     */
+    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
+        return beanFactory.getAliases(name);
+    }
+
+    /**
+     * 获取aop代理对象
+     *
+     * @param invoker
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    public static <T> T getAopProxy(T invoker) {
+        return (T) AopContext.currentProxy();
+    }
+
+    /**
+     * 获取当前的环境配置,无配置返回null
+     *
+     * @return 当前的环境配置
+     */
+    public static String[] getActiveProfiles() {
+        return applicationContext.getEnvironment().getActiveProfiles();
+    }
+
+    /**
+     * 获取当前的环境配置,当有多个环境配置时,只获取第一个
+     *
+     * @return 当前的环境配置
+     */
+    public static String getActiveProfile() {
+        final String[] activeProfiles = getActiveProfiles();
+        return activeProfiles.length > 0 ? activeProfiles[0] : null;
+    }
+}

+ 66 - 0
src/main/java/com/szwl/util/UrlUtil.java

@@ -0,0 +1,66 @@
+package com.szwl.util;
+
+import org.springframework.util.AntPathMatcher;
+import org.springframework.util.CollectionUtils;
+
+import java.util.Collection;
+
+/**
+ * URL工具类
+ *
+ * @author wuhs
+ * @date 2021-11-02 17:58
+ */
+public class UrlUtil {
+
+    /**
+     * url匹配
+     *
+     * @param url
+     * @param patterns
+     * @return
+     */
+    public static boolean matches(String url, Collection<String> patterns) {
+        if (CollectionUtils.isEmpty(patterns)) {
+            return false;
+        }
+        for (String pattern : patterns) {
+            if (matches(url, pattern)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * url匹配
+     *
+     * @param url
+     * @param patterns
+     * @return
+     */
+    public static boolean matches(String url, String[] patterns) {
+        if (patterns == null || patterns.length == 0) {
+            return false;
+        }
+        for (String pattern : patterns) {
+            if (matches(url, pattern)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * url匹配
+     *
+     * @param url
+     * @param pattern
+     * @return
+     */
+    public static boolean matches(String url, String pattern) {
+        AntPathMatcher matcher = new AntPathMatcher();
+        return matcher.match(pattern, url);
+    }
+
+}

+ 2 - 0
src/main/resources/application.yml

@@ -0,0 +1,2 @@
+swagger:
+  url: /v2/api-docs,/swagger-resources,/swagger-resources/**,/configuration/ui,/configuration/security,/swagger-ui.html/**,/webjars/**,/doc.html,/doc.html/**,/*.html,/**.html,/**/*.html,/**/*.css,/**/*.js,/sys/api/list,/sys/user/batch,/sys/org/batch

+ 17 - 1
src/main/resources/bootstrap.yml

@@ -52,6 +52,21 @@ spring:
     max-concurrency: 2000
     listener.simple.concurrency: 1000
     listener.simple.max-concurrency: 2000
+
+  redis:
+    database: 0
+    host: localhost         # Redis服务器地址
+    port: 6379              # Redis服务器连接端口
+    password:               # Redis服务器连接密码(默认为空)
+
+#  redis:
+#    timeout: 5000
+#    cluster:
+#      nodes: 120.78.140.173:7000,120.78.140.173:7001,47.112.127.131:7001,47.112.127.131:7000,112.74.63.148:7001,112.74.63.148:7000
+#      max-attempts: 5
+#      max-redirects: 7
+#      timeout: 12000
+
 elasticSearch:
   host: 120.78.140.173
 #elasticSearch.host: 10.0.0.155
@@ -82,4 +97,5 @@ mybatis-plus:
 
 logging:
   level:
-    com.szwl: debug
+    com.szwl: debug
+

+ 1 - 1
src/test/java/com/szwl/AutoGeneratorTests.java

@@ -47,7 +47,7 @@ class AutoGeneratorTests {
 		strategyConfig
 //				.setCapitalMode(true)//设置全局大写命名
 				.setInclude(new String[]{
-						""
+						"audit_log"
 				})//只会生成该表
 				.setEntityLombokModel(true)//实体类生成之后自动添加lombok注解
 				.setNaming(NamingStrategy.underline_to_camel)//数据库表映射到实体的命名策略