chejianzheng 3 mesiacov pred
rodič
commit
d4028420c1
15 zmenil súbory, kde vykonal 574 pridanie a 312 odobranie
  1. 29 5
      portal-service-application/src/main/java/com/hfln/portal/application/controller/admin/AdminLoginController.java
  2. 5 1
      portal-service-common/src/main/java/com/hfln/portal/common/constant/redis/RedisCacheConstant.java
  3. 22 0
      portal-service-common/src/main/java/com/hfln/portal/common/request/admin/AdminAddParam.java
  4. 4 0
      portal-service-domain/src/main/java/com/hfln/portal/domain/gateway/AdminGateway.java
  5. 15 15
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/SaTokenConfigProperties.java
  6. 167 167
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/SaTokenConfigure.java
  7. 108 108
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/StpInterfaceImpl.java
  8. 162 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/UserAuthService.java
  9. 26 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/AdminGatewayImpl.java
  10. 1 1
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/AdminUserInfo.java
  11. 1 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/AdminUserService.java
  12. 2 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/RoleService.java
  13. 9 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/AdminUserServiceImpl.java
  14. 8 0
      portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/RoleServiceImpl.java
  15. 15 15
      portal-service-server/src/main/resources/bootstrap.yml

+ 29 - 5
portal-service-application/src/main/java/com/hfln/portal/application/controller/admin/AdminLoginController.java

@@ -2,20 +2,21 @@
 package com.hfln.portal.application.controller.admin;
 
 
+import cn.dev33.satoken.stp.StpUtil;
 import cn.hfln.framework.catchlog.CatchAndLog;
 import cn.hfln.framework.dto.ApiResult;
+import com.hfln.portal.common.request.admin.AdminAddParam;
 import com.hfln.portal.common.request.admin.AdminLoginParam;
 import com.hfln.portal.common.request.admin.AdminResetParam;
 import com.hfln.portal.common.response.admin.AdminLoginRes;
+import com.hfln.portal.common.response.user.UserTokenInfo;
+import com.hfln.portal.domain.customer.util.CopyUtils;
 import com.hfln.portal.domain.gateway.AdminGateway;
 import io.swagger.v3.oas.annotations.Operation;
 import io.swagger.v3.oas.annotations.tags.Tag;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
 
 import javax.validation.Valid;
 
@@ -41,7 +42,22 @@ public class AdminLoginController {
         return ApiResult.success(adminGateway.login(param));
     }
 
-    @PostMapping("/sendCode")
+    @GetMapping("/getTokenInfo")
+    @Operation(summary = "获取当前token信息")
+    public ApiResult<UserTokenInfo> getTokenInfo() {
+
+        return ApiResult.success(CopyUtils.copy(StpUtil.getTokenInfo(), UserTokenInfo.class));
+    }
+
+    @GetMapping("/logout")
+    @Operation(summary = "退出登录")
+    public ApiResult<Void> logout() {
+
+        StpUtil.logout(StpUtil.getLoginId(), StpUtil.getLoginDeviceType());
+        return ApiResult.success();
+    }
+
+    @GetMapping("/sendCode")
     @Operation(summary = "忘记密码,发送验证码")
     public ApiResult<Void> sendCode() {
 
@@ -57,4 +73,12 @@ public class AdminLoginController {
         adminGateway.reset(param);
         return ApiResult.success();
     }
+
+    @PostMapping("/add")
+    @Operation(summary = "创建b端用户密码")
+    public ApiResult<Void> add(@Valid @RequestBody AdminAddParam param) {
+
+        adminGateway.add(param);
+        return ApiResult.success();
+    }
 }

+ 5 - 1
portal-service-common/src/main/java/com/hfln/portal/common/constant/redis/RedisCacheConstant.java

@@ -16,5 +16,9 @@ public interface RedisCacheConstant {
     String SMS_SEND_RESET_TIME = "sms:signup:frequency:";
 
 
-
+    /**
+     * 用户权限缓存
+     */
+    String ROLE_PERM_KEY_PRE = "hfln:perm:";
+    String USER_ROLE_KEY_PRE = "hfln:role:";
 }

+ 22 - 0
portal-service-common/src/main/java/com/hfln/portal/common/request/admin/AdminAddParam.java

@@ -0,0 +1,22 @@
+package com.hfln.portal.common.request.admin;
+
+import io.swagger.v3.oas.annotations.media.Schema;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+
+@Data
+public class AdminAddParam {
+
+    @Schema(description = "账号")
+    @NotBlank(message = "账号不能为空")
+    private String account;
+
+    @Schema(description = "密码")
+    @NotBlank(message = "密码不能为空")
+    private String password;
+
+    @Schema(description = "电话号码")
+    private String phone;
+}

+ 4 - 0
portal-service-domain/src/main/java/com/hfln/portal/domain/gateway/AdminGateway.java

@@ -1,6 +1,7 @@
 package com.hfln.portal.domain.gateway;
 
 import com.hfln.portal.common.dto.data.device.DeviceDTO;
+import com.hfln.portal.common.request.admin.AdminAddParam;
 import com.hfln.portal.common.request.admin.AdminLoginParam;
 import com.hfln.portal.common.request.admin.AdminResetParam;
 import com.hfln.portal.common.request.admin.DeviceAddParam;
@@ -10,6 +11,7 @@ import com.hfln.portal.common.vo.PageRecord;
 import com.hfln.portal.common.vo.UploadRes;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.validation.Valid;
 import java.io.IOException;
 
 public interface AdminGateway {
@@ -25,4 +27,6 @@ public interface AdminGateway {
     void sendCode();
 
     void reset(AdminResetParam param);
+
+    void add(@Valid AdminAddParam param);
 }

+ 15 - 15
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/SaTokenConfigProperties.java

@@ -1,15 +1,15 @@
-package com.hfln.portal.infrastructure.config;
-
-import lombok.Data;
-import org.springframework.boot.context.properties.ConfigurationProperties;
-import org.springframework.stereotype.Component;
-
-import java.util.List;
-
-@Data
-@Component
-@ConfigurationProperties(prefix = "sa-token.config")
-public class SaTokenConfigProperties {
-
-    private List<String> ignoreUrls;
-}
+//package com.hfln.portal.infrastructure.config;
+//
+//import lombok.Data;
+//import org.springframework.boot.context.properties.ConfigurationProperties;
+//import org.springframework.stereotype.Component;
+//
+//import java.util.List;
+//
+//@Data
+//@Component
+//@ConfigurationProperties(prefix = "sa-token.config")
+//public class SaTokenConfigProperties {
+//
+//    private List<String> ignoreUrls;
+//}

+ 167 - 167
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/SaTokenConfigure.java

@@ -1,173 +1,173 @@
-package com.hfln.portal.infrastructure.config;
-
-import cn.dev33.satoken.filter.SaServletFilter;
-import cn.dev33.satoken.interceptor.SaInterceptor;
-import cn.dev33.satoken.router.SaRouter;
-import cn.dev33.satoken.stp.StpUtil;
-import cn.dev33.satoken.util.SaResult;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
-import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
-import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
-
-
-/**
- * [Sa-Token 权限认证] 配置类
- * @author click33
- *
- */
-@Slf4j
-@Configuration
-public class SaTokenConfigure implements WebMvcConfigurer {
-
-	@Autowired
-	private SaTokenConfigProperties saTokenConfigProperties;
-
-	/**
-	 * 注册 Sa-Token 拦截器打开注解鉴权功能
-	 */
-	@Override
-	public void addInterceptors(InterceptorRegistry registry) {
-		// 注册 Sa-Token 拦截器打开注解鉴权功能
-		registry.addInterceptor(new SaInterceptor(handle -> {
-			// SaManager.getLog().debug("----- 请求path={}  提交token={}", SaHolder.getRequest().getRequestPath(), StpUtil.getTokenValue());
-
-			// 指定一条 match 规则
-//            SaRouter
-//                .match("/user/**")    // 拦截的 path 列表,可以写多个
-//                .notMatch("/user/doLogin", "/user/doLogin2")     // 排除掉的 path 列表,可以写多个
-//                .check(r -> StpUtil.checkLogin());        // 要执行的校验动作,可以写完整的 lambda 表达式
-//
-//            // 权限校验 -- 不同模块认证不同权限
-//            SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
-//            SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
-//            SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
-//            SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
-//            SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
-//
-//			// 甚至你可以随意的写一个打印语句
-//			SaRouter.match("/router/print", r -> System.out.println("----啦啦啦----"));
-//
-//			// 写一个完整的 lambda
-//			SaRouter.match("/router/print2", r -> {
-//				System.out.println("----啦啦啦2----");
-//				// ... 其它代码
-//			});
-
-			SaRouter
-					.match("/**")
-					.notMatch(saTokenConfigProperties.getIgnoreUrls())
-					.check(r -> StpUtil.checkLogin());
-
-			SaRouter.match("/admin/**", r -> StpUtil.checkRole("admin"));
-
-
-			/*
-			 * 相关路由都定义在 com.pj.cases.use.RouterCheckController 中
-			 */
-
-		}))
-		.addPathPatterns("/**")
-		.excludePathPatterns("/error");
-
-
-	}
-
-	/**
-     * 注册 [Sa-Token 全局过滤器]
-     */
-    @Bean
-    public SaServletFilter getSaServletFilter() {
-        return new SaServletFilter()
-
-        		// 指定 [拦截路由] 与 [放行路由]
-        		.addInclude("/**")//
-				.setExcludeList(saTokenConfigProperties.getIgnoreUrls())
-//				.addExclude("/favicon.ico")
-
-
-        		// 认证函数: 每次请求执行
-//        		.setAuth(obj -> {
-//        			// System.out.println("---------- sa全局认证 " + SaHolder.getRequest().getRequestPath());
-//        			// SaManager.getLog().debug("----- 请求path={}  提交token={}", SaHolder.getRequest().getRequestPath(), StpUtil.getTokenValue());
-//
-//                    // 权限校验 -- 不同模块认证不同权限
-//        			//		这里你可以写和拦截器鉴权同样的代码,不同点在于:
-//        			// 		校验失败后不会进入全局异常组件,而是进入下面的 .setError 函数
-//                    SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
-//                    SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
-//                    SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
-//                    SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
-//                    SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
-//        		})
-
-        		// 异常处理函数:每次认证函数发生异常时执行此函数
-        		.setError(e -> {
-//        			System.out.println("---------- sa全局异常 ");
-					log.error("saServletFilter认证异常:", e);
-        			return SaResult.error(e.getMessage());
-        		})
-
-        		// 前置函数:在每次认证函数之前执行(BeforeAuth 不受 includeList 与 excludeList 的限制,所有请求都会进入)
-//        		.setBeforeAuth(r -> {
-//        			// ---------- 设置一些安全响应头 ----------
-//        			SaHolder.getResponse()
-//        			// 服务器名称
-//        			.setServer("sa-server")
-//        			// 是否可以在iframe显示视图: DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以
-//        			.setHeader("X-Frame-Options", "SAMEORIGIN")
-//        			// 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面
-//        			.setHeader("X-XSS-Protection", "1; mode=block")
-//        			// 禁用浏览器内容嗅探
-//        			.setHeader("X-Content-Type-Options", "nosniff")
-//        			;
-//        		})
-        		;
-    }
-
+//package com.hfln.portal.infrastructure.config;
+//
+//import cn.dev33.satoken.filter.SaServletFilter;
+//import cn.dev33.satoken.interceptor.SaInterceptor;
+//import cn.dev33.satoken.router.SaRouter;
+//import cn.dev33.satoken.stp.StpUtil;
+//import cn.dev33.satoken.util.SaResult;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.context.annotation.Bean;
+//import org.springframework.context.annotation.Configuration;
+//import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
+//import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+//
+//
+///**
+// * [Sa-Token 权限认证] 配置类
+// * @author click33
+// *
+// */
+//@Slf4j
+//@Configuration
+//public class SaTokenConfigure implements WebMvcConfigurer {
+//
+//	@Autowired
+//	private SaTokenConfigProperties saTokenConfigProperties;
+//
 //	/**
-//	 * CORS 跨域处理
+//	 * 注册 Sa-Token 拦截器打开注解鉴权功能
 //	 */
-//	@Bean
-//	public SaCorsHandleFunction corsHandle() {
-//		return (req, res, sto) -> {
-//			res.
-//					// 允许指定域访问跨域资源
-//							setHeader("Access-Control-Allow-Origin", "*")
-//					// 允许所有请求方式
-//					.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
-//					// 有效时间
-//					.setHeader("Access-Control-Max-Age", "3600")
-//					// 允许的header参数
-//					.setHeader("Access-Control-Allow-Headers", "*");
-//
-//			// 如果是预检请求,则立即返回到前端
-//			SaRouter.match(SaHttpMethod.OPTIONS)
-//					.free(r -> System.out.println("--------OPTIONS预检请求,不做处理"))
-//					.back();
-//		};
+//	@Override
+//	public void addInterceptors(InterceptorRegistry registry) {
+//		// 注册 Sa-Token 拦截器打开注解鉴权功能
+//		registry.addInterceptor(new SaInterceptor(handle -> {
+//			// SaManager.getLog().debug("----- 请求path={}  提交token={}", SaHolder.getRequest().getRequestPath(), StpUtil.getTokenValue());
+//
+//			// 指定一条 match 规则
+////            SaRouter
+////                .match("/user/**")    // 拦截的 path 列表,可以写多个
+////                .notMatch("/user/doLogin", "/user/doLogin2")     // 排除掉的 path 列表,可以写多个
+////                .check(r -> StpUtil.checkLogin());        // 要执行的校验动作,可以写完整的 lambda 表达式
+////
+////            // 权限校验 -- 不同模块认证不同权限
+////            SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
+////            SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
+////            SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
+////            SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
+////            SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
+////
+////			// 甚至你可以随意的写一个打印语句
+////			SaRouter.match("/router/print", r -> System.out.println("----啦啦啦----"));
+////
+////			// 写一个完整的 lambda
+////			SaRouter.match("/router/print2", r -> {
+////				System.out.println("----啦啦啦2----");
+////				// ... 其它代码
+////			});
+//
+//			SaRouter
+//					.match("/**")
+//					.notMatch(saTokenConfigProperties.getIgnoreUrls())
+//					.check(r -> StpUtil.checkLogin());
+//
+//			SaRouter.match("/admin/**", r -> StpUtil.checkRole("admin"));
+//
+//
+//			/*
+//			 * 相关路由都定义在 com.pj.cases.use.RouterCheckController 中
+//			 */
+//
+//		}))
+//		.addPathPatterns("/**")
+//		.excludePathPatterns("/error");
+//
+//
 //	}
-
+//
 //	/**
-//     * 重写 Sa-Token 框架内部算法策略
+//     * 注册 [Sa-Token 全局过滤器]
 //     */
-//    @PostConstruct
-//    public void rewriteSaStrategy() {
-//    	// 重写Sa-Token的注解处理器,增加注解合并功能
-//    	SaAnnotationStrategy.instance.getAnnotation = (element, annotationClass) -> {
-//    		return AnnotatedElementUtils.getMergedAnnotation(element, annotationClass);
-//    	};
-//
-//		// 重写 SaCheckELRootMap 扩展函数,增加注解鉴权 EL 表达式可使用的根对象
-//		SaAnnotationStrategy.instance.checkELRootMapExtendFunction = rootMap -> {
-//			System.out.println("--------- 执行 SaCheckELRootMap 增强,目前已包含的的跟对象包括:" + rootMap.keySet());
-//			// 新增 stpUser 根对象,使之可以在表达式中通过 stpUser.checkLogin() 方式进行多账号体系鉴权
-//			rootMap.put("stpUser", StpUserUtil.getStpLogic());
-//		};
+//    @Bean
+//    public SaServletFilter getSaServletFilter() {
+//        return new SaServletFilter()
+//
+//        		// 指定 [拦截路由] 与 [放行路由]
+//        		.addInclude("/**")//
+//				.setExcludeList(saTokenConfigProperties.getIgnoreUrls())
+////				.addExclude("/favicon.ico")
+//
+//
+//        		// 认证函数: 每次请求执行
+////        		.setAuth(obj -> {
+////        			// System.out.println("---------- sa全局认证 " + SaHolder.getRequest().getRequestPath());
+////        			// SaManager.getLog().debug("----- 请求path={}  提交token={}", SaHolder.getRequest().getRequestPath(), StpUtil.getTokenValue());
+////
+////                    // 权限校验 -- 不同模块认证不同权限
+////        			//		这里你可以写和拦截器鉴权同样的代码,不同点在于:
+////        			// 		校验失败后不会进入全局异常组件,而是进入下面的 .setError 函数
+////                    SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
+////                    SaRouter.match("/goods/**", r -> StpUtil.checkPermission("goods"));
+////                    SaRouter.match("/orders/**", r -> StpUtil.checkPermission("orders"));
+////                    SaRouter.match("/notice/**", r -> StpUtil.checkPermission("notice"));
+////                    SaRouter.match("/comment/**", r -> StpUtil.checkPermission("comment"));
+////        		})
+//
+//        		// 异常处理函数:每次认证函数发生异常时执行此函数
+//        		.setError(e -> {
+////        			System.out.println("---------- sa全局异常 ");
+//					log.error("saServletFilter认证异常:", e);
+//        			return SaResult.error(e.getMessage());
+//        		})
+//
+//        		// 前置函数:在每次认证函数之前执行(BeforeAuth 不受 includeList 与 excludeList 的限制,所有请求都会进入)
+////        		.setBeforeAuth(r -> {
+////        			// ---------- 设置一些安全响应头 ----------
+////        			SaHolder.getResponse()
+////        			// 服务器名称
+////        			.setServer("sa-server")
+////        			// 是否可以在iframe显示视图: DENY=不可以 | SAMEORIGIN=同域下可以 | ALLOW-FROM uri=指定域名下可以
+////        			.setHeader("X-Frame-Options", "SAMEORIGIN")
+////        			// 是否启用浏览器默认XSS防护: 0=禁用 | 1=启用 | 1; mode=block 启用, 并在检查到XSS攻击时,停止渲染页面
+////        			.setHeader("X-XSS-Protection", "1; mode=block")
+////        			// 禁用浏览器内容嗅探
+////        			.setHeader("X-Content-Type-Options", "nosniff")
+////        			;
+////        		})
+//        		;
 //    }
-
-
-
-}
+//
+////	/**
+////	 * CORS 跨域处理
+////	 */
+////	@Bean
+////	public SaCorsHandleFunction corsHandle() {
+////		return (req, res, sto) -> {
+////			res.
+////					// 允许指定域访问跨域资源
+////							setHeader("Access-Control-Allow-Origin", "*")
+////					// 允许所有请求方式
+////					.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE")
+////					// 有效时间
+////					.setHeader("Access-Control-Max-Age", "3600")
+////					// 允许的header参数
+////					.setHeader("Access-Control-Allow-Headers", "*");
+////
+////			// 如果是预检请求,则立即返回到前端
+////			SaRouter.match(SaHttpMethod.OPTIONS)
+////					.free(r -> System.out.println("--------OPTIONS预检请求,不做处理"))
+////					.back();
+////		};
+////	}
+//
+////	/**
+////     * 重写 Sa-Token 框架内部算法策略
+////     */
+////    @PostConstruct
+////    public void rewriteSaStrategy() {
+////    	// 重写Sa-Token的注解处理器,增加注解合并功能
+////    	SaAnnotationStrategy.instance.getAnnotation = (element, annotationClass) -> {
+////    		return AnnotatedElementUtils.getMergedAnnotation(element, annotationClass);
+////    	};
+////
+////		// 重写 SaCheckELRootMap 扩展函数,增加注解鉴权 EL 表达式可使用的根对象
+////		SaAnnotationStrategy.instance.checkELRootMapExtendFunction = rootMap -> {
+////			System.out.println("--------- 执行 SaCheckELRootMap 增强,目前已包含的的跟对象包括:" + rootMap.keySet());
+////			// 新增 stpUser 根对象,使之可以在表达式中通过 stpUser.checkLogin() 方式进行多账号体系鉴权
+////			rootMap.put("stpUser", StpUserUtil.getStpLogic());
+////		};
+////    }
+//
+//
+//
+//}

+ 108 - 108
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/StpInterfaceImpl.java

@@ -1,108 +1,108 @@
-package com.hfln.portal.infrastructure.config;
-
-import cn.dev33.satoken.stp.StpInterface;
-import com.hfln.portal.infrastructure.po.TblPermission;
-import com.hfln.portal.infrastructure.po.TblRole;
-import com.hfln.portal.infrastructure.po.TblRolePermission;
-import com.hfln.portal.infrastructure.po.TblUserRole;
-import com.hfln.portal.infrastructure.service.PermissionService;
-import com.hfln.portal.infrastructure.service.RolePermissionService;
-import com.hfln.portal.infrastructure.service.RoleService;
-import com.hfln.portal.infrastructure.service.UserRoleService;
-import lombok.extern.slf4j.Slf4j;
-import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.stereotype.Component;
-import org.springframework.util.CollectionUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-import java.util.stream.Collectors;
-
-/**
- * 自定义权限认证接口扩展,Sa-Token 将从此实现类获取每个账号拥有的权限码 
- * 
- * @author click33
- * @since 2022-10-13
- */
-@Slf4j
-@Component    // 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展
-public class StpInterfaceImpl implements StpInterface {
-
-
-	@Autowired
-	private RoleService roleService;
-
-	@Autowired
-	private RolePermissionService rolePermissionService;
-
-	@Autowired
-	private PermissionService permissionService;
-
-	@Autowired
-	private UserRoleService userRoleService;
-
-	/**
-	 * 返回一个账号所拥有的权限码集合 
-	 */
-	@Override
-	public List<String> getPermissionList(Object loginIdObj, String loginType) {
-
-		List<String> list = new ArrayList<String>();
-		// todo 后期接口调用次数大的话,可以放redis ,再加更新操作
-		long loginId = Long.parseLong(String.valueOf(loginIdObj));
-
-		List<TblUserRole> userRoles = userRoleService.findByUserId((long)loginId);
-		if (CollectionUtils.isEmpty(userRoles)) {
-			log.info("当前用户没有配置角色,userId:{}", loginId);
-			return list;
-		}
-
-		List<Long> userIds = userRoles.stream().map(TblUserRole::getRoleId).collect(Collectors.toList());
-		List<TblRole> roles = roleService.findAvailableByIds(userIds);
-		if (CollectionUtils.isEmpty(roles)) {
-			log.info("角色配置异常, userIds :{}", roles);
-			return list;
-		}
-
-		List<Long> roleIds = roles.stream().map(TblRole::getRoleId).collect(Collectors.toList());
-		List<TblRolePermission> rolePermissions = rolePermissionService.findByRoleIds(roleIds);
-		if (CollectionUtils.isEmpty(rolePermissions)) {
-			log.info("当前角色没有配置权限,roleIds:{}", roleIds);
-			return list;
-		}
-
-		List<Long> permIds = rolePermissions.stream().map(TblRolePermission::getPermId).collect(Collectors.toList());
-		List<TblPermission> permissionList = permissionService.findAvailableByIds(permIds);
-		if (CollectionUtils.isEmpty(permissionList)) {
-			log.info("权限配置异常, permIds :{}", permIds);
-			return list;
-		}
-
-		list.addAll(permissionList.stream().map(TblPermission::getPermCode).collect(Collectors.toList()));
-		return list;
-	}
-
-	/**
-	 * 返回一个账号所拥有的角色标识集合 
-	 */
-	@Override
-	public List<String> getRoleList(Object loginIdObj, String loginType) {
-
-		List<String> list = new ArrayList<String>();
-		long loginId = Long.parseLong(String.valueOf(loginIdObj));
-		List<TblUserRole> userRoles = userRoleService.findByUserId(loginId);
-		if (CollectionUtils.isEmpty(userRoles)) {
-			log.info("当前用户没有配置角色,userId:{}", loginId);
-			return list;
-		}
-
-		List<Long> userIds = userRoles.stream().map(TblUserRole::getRoleId).collect(Collectors.toList());
-		List<TblRole> roles = roleService.findAvailableByIds(userIds);
-		if (CollectionUtils.isEmpty(roles)) {
-			log.info("角色配置异常, userIds :{}", roles);
-			return list;
-		}
-		list.addAll(roles.stream().map(TblRole::getRoleCode).collect(Collectors.toList()));
-		return list;
-	}
-}
+//package com.hfln.portal.infrastructure.config;
+//
+//import cn.dev33.satoken.stp.StpInterface;
+//import com.hfln.portal.infrastructure.po.TblPermission;
+//import com.hfln.portal.infrastructure.po.TblRole;
+//import com.hfln.portal.infrastructure.po.TblRolePermission;
+//import com.hfln.portal.infrastructure.po.TblUserRole;
+//import com.hfln.portal.infrastructure.service.PermissionService;
+//import com.hfln.portal.infrastructure.service.RolePermissionService;
+//import com.hfln.portal.infrastructure.service.RoleService;
+//import com.hfln.portal.infrastructure.service.UserRoleService;
+//import lombok.extern.slf4j.Slf4j;
+//import org.springframework.beans.factory.annotation.Autowired;
+//import org.springframework.stereotype.Component;
+//import org.springframework.util.CollectionUtils;
+//
+//import java.util.ArrayList;
+//import java.util.List;
+//import java.util.stream.Collectors;
+//
+///**
+// * 自定义权限认证接口扩展,Sa-Token 将从此实现类获取每个账号拥有的权限码
+// *
+// * @author click33
+// * @since 2022-10-13
+// */
+//@Slf4j
+//@Component    // 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展
+//public class StpInterfaceImpl implements StpInterface {
+//
+//
+//	@Autowired
+//	private RoleService roleService;
+//
+//	@Autowired
+//	private RolePermissionService rolePermissionService;
+//
+//	@Autowired
+//	private PermissionService permissionService;
+//
+//	@Autowired
+//	private UserRoleService userRoleService;
+//
+//	/**
+//	 * 返回一个账号所拥有的权限码集合
+//	 */
+//	@Override
+//	public List<String> getPermissionList(Object loginIdObj, String loginType) {
+//
+//		List<String> list = new ArrayList<String>();
+//		// todo 后期接口调用次数大的话,可以放redis ,再加更新操作
+//		long loginId = Long.parseLong(String.valueOf(loginIdObj));
+//
+//		List<TblUserRole> userRoles = userRoleService.findByUserId((long)loginId);
+//		if (CollectionUtils.isEmpty(userRoles)) {
+//			log.info("当前用户没有配置角色,userId:{}", loginId);
+//			return list;
+//		}
+//
+//		List<Long> userIds = userRoles.stream().map(TblUserRole::getRoleId).collect(Collectors.toList());
+//		List<TblRole> roles = roleService.findAvailableByIds(userIds);
+//		if (CollectionUtils.isEmpty(roles)) {
+//			log.info("角色配置异常, userIds :{}", roles);
+//			return list;
+//		}
+//
+//		List<Long> roleIds = roles.stream().map(TblRole::getRoleId).collect(Collectors.toList());
+//		List<TblRolePermission> rolePermissions = rolePermissionService.findByRoleIds(roleIds);
+//		if (CollectionUtils.isEmpty(rolePermissions)) {
+//			log.info("当前角色没有配置权限,roleIds:{}", roleIds);
+//			return list;
+//		}
+//
+//		List<Long> permIds = rolePermissions.stream().map(TblRolePermission::getPermId).collect(Collectors.toList());
+//		List<TblPermission> permissionList = permissionService.findAvailableByIds(permIds);
+//		if (CollectionUtils.isEmpty(permissionList)) {
+//			log.info("权限配置异常, permIds :{}", permIds);
+//			return list;
+//		}
+//
+//		list.addAll(permissionList.stream().map(TblPermission::getPermCode).collect(Collectors.toList()));
+//		return list;
+//	}
+//
+//	/**
+//	 * 返回一个账号所拥有的角色标识集合
+//	 */
+//	@Override
+//	public List<String> getRoleList(Object loginIdObj, String loginType) {
+//
+//		List<String> list = new ArrayList<String>();
+//		long loginId = Long.parseLong(String.valueOf(loginIdObj));
+//		List<TblUserRole> userRoles = userRoleService.findByUserId(loginId);
+//		if (CollectionUtils.isEmpty(userRoles)) {
+//			log.info("当前用户没有配置角色,userId:{}", loginId);
+//			return list;
+//		}
+//
+//		List<Long> userIds = userRoles.stream().map(TblUserRole::getRoleId).collect(Collectors.toList());
+//		List<TblRole> roles = roleService.findAvailableByIds(userIds);
+//		if (CollectionUtils.isEmpty(roles)) {
+//			log.info("角色配置异常, userIds :{}", roles);
+//			return list;
+//		}
+//		list.addAll(roles.stream().map(TblRole::getRoleCode).collect(Collectors.toList()));
+//		return list;
+//	}
+//}

+ 162 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/config/UserAuthService.java

@@ -0,0 +1,162 @@
+package com.hfln.portal.infrastructure.config;
+
+import cn.dev33.satoken.stp.StpUtil;
+import cn.hfln.framework.common.redis.service.RedisService;
+import com.hfln.portal.common.constant.redis.RedisCacheConstant;
+import com.hfln.portal.infrastructure.po.TblPermission;
+import com.hfln.portal.infrastructure.po.TblRole;
+import com.hfln.portal.infrastructure.po.TblRolePermission;
+import com.hfln.portal.infrastructure.po.TblUserRole;
+import com.hfln.portal.infrastructure.service.PermissionService;
+import com.hfln.portal.infrastructure.service.RolePermissionService;
+import com.hfln.portal.infrastructure.service.RoleService;
+import com.hfln.portal.infrastructure.service.UserRoleService;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.springframework.util.CollectionUtils;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 自定义权限认证接口扩展,Sa-Token 将从此实现类获取每个账号拥有的权限码
+ *
+ * @author click33
+ * @since 2022-10-13
+ */
+@Slf4j
+@Component    // 打开此注解,保证此类被springboot扫描,即可完成sa-token的自定义权限验证扩展
+public class UserAuthService {
+
+
+	@Autowired
+	private RoleService roleService;
+
+	@Autowired
+	private RolePermissionService rolePermissionService;
+
+	@Autowired
+	private PermissionService permissionService;
+
+	@Autowired
+	private UserRoleService userRoleService;
+
+	@Autowired
+	private RedisService redisService;
+
+	public void cacheRolesAndPermissions() {
+
+		Set<String> roleCodeSet = this.getRoleCodeSet(StpUtil.getLoginId(), StpUtil.getLoginType());
+		if (!CollectionUtils.isEmpty(roleCodeSet)) {
+			// 登录缓存角色 防止用户角色有变更,登录前先删除之前的缓存
+			if (!redisService.hasKey(RedisCacheConstant.USER_ROLE_KEY_PRE+StpUtil.getLoginId())) {
+				// 这里从更改用户角色的地方修改最好
+//				redisService.deleteObject(RedisCacheConstant.USER_ROLE_KEY_PRE+StpUtil.getLoginId());
+				redisService.setCacheSet(RedisCacheConstant.USER_ROLE_KEY_PRE+ StpUtil.getLoginId(), roleCodeSet);
+			}
+			for (String roleCode : roleCodeSet) {
+				if (!redisService.hasKey(RedisCacheConstant.ROLE_PERM_KEY_PRE+roleCode)) {
+					// 这里从更改角色权限的地方修改最好
+					// redisService.deleteObject(RedisCacheConstant.ROLE_PERM_KEY_PRE+roleCode);
+					Set<String> permCodeSet = this.getPermCodeSet(roleCode);
+					redisService.setCacheSet(RedisCacheConstant.ROLE_PERM_KEY_PRE+roleCode, permCodeSet);
+				}
+			}
+		}
+		// 每次修改用户角色,应该注销用户登录信息,让用户重新登录
+	}
+
+	/**
+	 * 返回一个账号所拥有的权限码集合
+	 */
+	public Set<String> getPermCodeSet(Object loginIdObj, String loginType) {
+
+		Set<String> set = new HashSet<>();
+		// 后期接口调用次数大的话,可以放redis ,再加更新操作
+		long loginId = Long.parseLong(String.valueOf(loginIdObj));
+
+		List<TblUserRole> userRoles = userRoleService.findByUserId((long)loginId);
+		if (CollectionUtils.isEmpty(userRoles)) {
+			log.info("当前用户没有配置角色,userId:{}", loginId);
+			return set;
+		}
+
+		List<Long> userIds = userRoles.stream().map(TblUserRole::getRoleId).collect(Collectors.toList());
+		List<TblRole> roles = roleService.findAvailableByIds(userIds);
+		if (CollectionUtils.isEmpty(roles)) {
+			log.info("角色配置异常, userIds :{}", roles);
+			return set;
+		}
+
+		List<Long> roleIds = roles.stream().map(TblRole::getRoleId).collect(Collectors.toList());
+		List<TblRolePermission> rolePermissions = rolePermissionService.findByRoleIds(roleIds);
+		if (CollectionUtils.isEmpty(rolePermissions)) {
+			log.info("当前角色没有配置权限,roleIds:{}", roleIds);
+			return set;
+		}
+
+		List<Long> permIds = rolePermissions.stream().map(TblRolePermission::getPermId).collect(Collectors.toList());
+		List<TblPermission> permissionList = permissionService.findAvailableByIds(permIds);
+		if (CollectionUtils.isEmpty(permissionList)) {
+			log.info("权限配置异常, permIds :{}", permIds);
+			return set;
+		}
+
+		set.addAll(permissionList.stream().map(TblPermission::getPermCode).collect(Collectors.toSet()));
+		return set;
+	}
+
+	/**
+	 * 返回一个账号所拥有的角色标识集合
+	 */
+	public Set<String> getRoleCodeSet(Object loginIdObj, String loginType) {
+
+		Set<String> set = new HashSet<>();
+		long loginId = Long.parseLong(String.valueOf(loginIdObj));
+		List<TblUserRole> userRoles = userRoleService.findByUserId(loginId);
+		if (CollectionUtils.isEmpty(userRoles)) {
+			log.info("当前用户没有配置角色,userId:{}", loginId);
+			return set;
+		}
+
+		List<Long> userIds = userRoles.stream().map(TblUserRole::getRoleId).collect(Collectors.toList());
+		List<TblRole> roles = roleService.findAvailableByIds(userIds);
+		if (CollectionUtils.isEmpty(roles)) {
+			log.info("角色配置异常, userIds :{}", roles);
+			return set;
+		}
+		set.addAll(roles.stream().map(TblRole::getRoleCode).collect(Collectors.toSet()));
+		return set;
+	}
+
+    /**
+     * 返回当前角色所拥有的权限码集合
+     */
+    public Set<String> getPermCodeSet(String roleCode) {
+
+        Set<String> set = new HashSet<>();
+
+        TblRole role = roleService.findAvailableByCode(roleCode);
+        if (role == null) {
+            log.info("角色配置异常, userIds :{}", role);
+            return set;
+        }
+
+        List<TblRolePermission> rolePermissions = rolePermissionService.findByRoleIds(Arrays.asList(role.getRoleId()));
+        if (CollectionUtils.isEmpty(rolePermissions)) {
+            log.info("当前角色没有配置权限,roleCode:{}", roleCode);
+            return set;
+        }
+
+        List<Long> permIds = rolePermissions.stream().map(TblRolePermission::getPermId).collect(Collectors.toList());
+        List<TblPermission> permissionList = permissionService.findAvailableByIds(permIds);
+        if (CollectionUtils.isEmpty(permissionList)) {
+            log.info("权限配置异常, permIds :{}", permIds);
+            return set;
+        }
+
+        set.addAll(permissionList.stream().map(TblPermission::getPermCode).collect(Collectors.toSet()));
+        return set;
+    }
+}

+ 26 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/gateway/impl/AdminGatewayImpl.java

@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.hfln.portal.common.constant.redis.RedisCacheConstant;
 import com.hfln.portal.common.dto.DevInfoImportDto;
 import com.hfln.portal.common.dto.data.device.DeviceDTO;
+import com.hfln.portal.common.request.admin.AdminAddParam;
 import com.hfln.portal.common.request.admin.AdminLoginParam;
 import com.hfln.portal.common.request.admin.AdminResetParam;
 import com.hfln.portal.common.request.admin.DeviceAddParam;
@@ -22,6 +23,7 @@ import com.hfln.portal.domain.customer.util.PasswordUtil;
 import com.hfln.portal.domain.exception.ErrorEnum;
 import com.hfln.portal.domain.gateway.AdminGateway;
 import com.hfln.portal.domain.gateway.sms.SmsGateway;
+import com.hfln.portal.infrastructure.config.UserAuthService;
 import com.hfln.portal.infrastructure.po.AdminUserInfo;
 import com.hfln.portal.infrastructure.po.BasePO;
 import com.hfln.portal.infrastructure.po.DevInfo;
@@ -57,6 +59,10 @@ public class AdminGatewayImpl implements AdminGateway {
     @Autowired
     private SmsGateway smsGateway;
 
+    @Autowired
+    private UserAuthService userAuthService;
+
+
     @Override
     public UploadRes uploadDev(MultipartFile file) throws IOException {
 
@@ -141,11 +147,18 @@ public class AdminGatewayImpl implements AdminGateway {
             throw new BizException(ErrorEnum.USERNAME_OR_PASSWORD_ERROR.getErrorCode(), ErrorEnum.USERNAME_OR_PASSWORD_ERROR.getErrorMessage());
         }
 
+        // 清除之前登录信息
+        StpUtil.logout(adminUser.getUserId(), DeviceType.WEB.getCode());
         //  这里如果使用 多账号体系,需要新建一个类似 SptUtil 的 SptAdminUtil , 且在 gateway 校验的逻辑中,需要加上 对 SptAdminUtil 的判断
         // 1 需要保证 userId 和 adminUserId 不能一样
         // 2 可以在 stputil.login 的 loginId 参数前加前缀 user_ or admin_
         // 3 添加 SptAdminUtil,不过在不同地方,需要注意对 stputil sptadminutil 的不同引用
         StpUtil.login(adminUser.getUserId(), DeviceType.WEB.getCode());
+
+
+        // 当前用户登录后,需要将当前用户的权限保存到redis,用于网关校验权限
+        userAuthService.cacheRolesAndPermissions();
+
         SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
         AdminLoginRes res = CopyUtils.copy(tokenInfo, AdminLoginRes.class);
         BeanUtils.copyProperties(adminUser, res);
@@ -199,4 +212,17 @@ public class AdminGatewayImpl implements AdminGateway {
         adminUser.setPassword(PasswordUtil.encrypt(request.getPassword()));
         adminUserService.updateById(adminUser);
     }
+
+    @Override
+    public void add(AdminAddParam param) {
+
+        AdminUserInfo exist = adminUserService.queryByAccount(param.getAccount());
+        if (Objects.nonNull(exist)) {
+            throw new BizException(ErrorEnum.USER_ALREADY_EXISTS.getErrorCode(), ErrorEnum.USER_ALREADY_EXISTS.getErrorMessage());
+        }
+
+        AdminUserInfo adminUserInfo = CopyUtils.copy(param, AdminUserInfo.class);
+        adminUserInfo.setPassword(PasswordUtil.encrypt(param.getPassword()));
+        adminUserService.save(adminUserInfo);
+    }
 }

+ 1 - 1
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/po/AdminUserInfo.java

@@ -7,7 +7,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 
 /**
- * 用户信息表
+ * 管理用户信息表
  */
 @Data
 @EqualsAndHashCode(callSuper = true)

+ 1 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/AdminUserService.java

@@ -9,4 +9,5 @@ public interface AdminUserService extends IService<AdminUserInfo> {
 
     AdminUserInfo queryByPhone(String phone);
 
+    AdminUserInfo queryByAccount(String account);
 }

+ 2 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/RoleService.java

@@ -9,4 +9,6 @@ public interface RoleService extends IService<TblRole> {
 
 
     List<TblRole> findAvailableByIds(List<Long> roleIds);
+
+    TblRole findAvailableByCode(String roleCode);
 }

+ 9 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/AdminUserServiceImpl.java

@@ -38,4 +38,13 @@ public class AdminUserServiceImpl extends ServiceImpl<AdminUserInfoMapper, Admin
         AdminUserInfo userInfo = this.baseMapper.selectOne(queryWrapper);
         return userInfo;
     }
+
+    @Override
+    public AdminUserInfo queryByAccount(String account) {
+        LambdaQueryWrapper<AdminUserInfo> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(AdminUserInfo::getAccount, account);
+        queryWrapper.eq(AdminUserInfo::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED);
+        AdminUserInfo userInfo = this.baseMapper.selectOne(queryWrapper);
+        return userInfo;
+    }
 }

+ 8 - 0
portal-service-infrastructure/src/main/java/com/hfln/portal/infrastructure/service/impl/RoleServiceImpl.java

@@ -23,4 +23,12 @@ public class RoleServiceImpl extends ServiceImpl<TblRoleMapper, TblRole> impleme
         queryWrapper.eq(TblRole::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED);
         return this.baseMapper.selectList(queryWrapper);
     }
+
+    @Override
+    public TblRole findAvailableByCode(String roleCode) {
+        LambdaQueryWrapper<TblRole> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.in(TblRole::getRoleCode, roleCode);
+        queryWrapper.eq(TblRole::getIsDeleted, BasePO.DeleteFlag.NOT_DELETED);
+        return this.baseMapper.selectOne(queryWrapper);
+    }
 }

+ 15 - 15
portal-service-server/src/main/resources/bootstrap.yml

@@ -5,7 +5,7 @@ spring:
     pathmatch:
       matching-strategy: ANT_PATH_MATCHER
   profiles:
-    active: test
+    active: local
   application:
     name: portal-service-server
 
@@ -26,20 +26,20 @@ mybatis-plus:
       logic-delete-value: 1
       logic-not-delete-value: 0
 
-sa-token:
-  config:
-    ignoreUrls:
-      - /wap/user/**
-      - /v2/**
-      - /doc.html
-      - /swagger-resources/**
-      - /webjars/**
-      - /swagger-ui/**
-      - /swagger-ui.html
-      - /v3/**
-      - /api-docs
-      - /api/doc.html
-      - /knife4j/**
+#sa-token:
+#  config:
+#    ignoreUrls:
+#      - /wap/user/**
+#      - /v2/**
+#      - /doc.html
+#      - /swagger-resources/**
+#      - /webjars/**
+#      - /swagger-ui/**
+#      - /swagger-ui.html
+#      - /v3/**
+#      - /api-docs
+#      - /api/doc.html
+#      - /knife4j/**
 
 # Knife4j 文档配置
 lnxx: