From b9858c758e813abb8418f4dae52f9b7bacc63363 Mon Sep 17 00:00:00 2001 From: lzq <2495532633@qq.com> Date: Thu, 11 Dec 2025 17:59:05 +0800 Subject: [PATCH] 1 --- .../njzscloud-common-cache/pom.xml | 1 + .../config/WebSecurityAutoConfiguration.java | 31 +++- .../config/WebSecurityProperties.java | 4 + .../common/security/contant/ClientCode.java | 41 ++++- .../common/security/contant/Constants.java | 1 + .../controller/PermissionController.java | 23 +++ .../permission/DefaultPermissionLoader.java | 14 ++ .../permission/DefaultPermissionManager.java | 24 --- .../security/permission/PermissionLoader.java | 7 + .../permission/PermissionManager.java | 55 ++++-- .../PermissionSecurityMetaDataSource.java | 43 ----- .../security/permission/PermissionVoter.java | 18 +- .../security/permission/RolePermission.java | 3 + .../AbstractAuthenticationProvider.java | 3 +- .../common/security/support/IAuthService.java | 2 +- .../common/security/support/UserDetail.java | 1 + njzscloud-svr/pom.xml | 9 +- .../cst/org/pojo/entity/OrgEntity.java | 9 +- .../sys/auth/controller/AuthController.java | 10 +- .../dispose/sys/auth/mapper/AuthMapper.java | 5 +- .../auth/pojo/result/EndpointResource.java | 3 +- .../sys/auth/pojo/result/IdentityInfo.java | 165 ++++++++++++++++++ .../sys/auth/pojo/result/MyResult.java | 1 + .../dispose/sys/auth/service/AuthService.java | 15 +- .../sys/endpoint/contant/RequestMethod.java | 8 + .../controller/EndpointController.java | 74 +++++++- .../sys/endpoint/service/EndpointService.java | 26 +++ .../sys/menu/pojo/entity/MenuEntity.java | 4 + .../sys/menu/pojo/param/MenuAddParam.java | 5 + .../sys/menu/pojo/param/MenuModifyParam.java | 2 + .../sys/menu/pojo/param/MenuSearchParam.java | 1 + .../menu/pojo/result/MenuDetailResult.java | 3 + .../dispose/sys/menu/service/MenuService.java | 12 +- .../sys/resource/mapper/ResourceMapper.java | 4 + .../pojo/result/ControllerMappingResult.java | 29 +++ .../sys/resource/service/ResourceService.java | 10 +- .../user/pojo/param/UserRegisterParam.java | 16 +- .../src/main/resources/application-dev.yml | 3 +- .../mapper/cst/customer/CustomerMapper.xml | 2 +- .../resources/mapper/sys/auth/AuthMapper.xml | 38 +++- .../mapper/sys/resource/ResourceMapper.xml | 11 ++ pom.xml | 5 + z-doc/pdma/njzscloud-dispose.pdma | 99 +++++++++-- 43 files changed, 683 insertions(+), 157 deletions(-) create mode 100644 njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/controller/PermissionController.java create mode 100644 njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/DefaultPermissionLoader.java delete mode 100644 njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/DefaultPermissionManager.java create mode 100644 njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionLoader.java delete mode 100644 njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionSecurityMetaDataSource.java create mode 100644 njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/IdentityInfo.java create mode 100644 njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/pojo/result/ControllerMappingResult.java diff --git a/njzscloud-common/njzscloud-common-cache/pom.xml b/njzscloud-common/njzscloud-common-cache/pom.xml index e1a2f1e..34956ab 100644 --- a/njzscloud-common/njzscloud-common-cache/pom.xml +++ b/njzscloud-common/njzscloud-common-cache/pom.xml @@ -28,6 +28,7 @@ com.njzscloud njzscloud-common-redis + provided diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/config/WebSecurityAutoConfiguration.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/config/WebSecurityAutoConfiguration.java index db2acc0..6f12a7f 100644 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/config/WebSecurityAutoConfiguration.java +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/config/WebSecurityAutoConfiguration.java @@ -2,6 +2,7 @@ package com.njzscloud.common.security.config; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.util.ArrayUtil; +import com.njzscloud.common.security.controller.PermissionController; import com.njzscloud.common.security.handler.AccessDeniedExceptionHandler; import com.njzscloud.common.security.handler.AuthExceptionHandler; import com.njzscloud.common.security.handler.LogoutPostHandler; @@ -11,10 +12,12 @@ import com.njzscloud.common.security.module.password.PasswordAuthenticationProvi import com.njzscloud.common.security.module.password.PasswordLoginPreparer; import com.njzscloud.common.security.module.wechat.mini.WechatMiniAuthenticationProvider; import com.njzscloud.common.security.module.wechat.mini.WechatMiniLoginPreparer; -import com.njzscloud.common.security.permission.DefaultPermissionManager; +import com.njzscloud.common.security.permission.DefaultPermissionLoader; +import com.njzscloud.common.security.permission.PermissionLoader; import com.njzscloud.common.security.permission.PermissionManager; import com.njzscloud.common.security.support.*; import com.njzscloud.common.security.support.controller.VerificationCodeController; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.ObjectProvider; @@ -54,9 +57,19 @@ public class WebSecurityAutoConfiguration { } @Bean - @ConditionalOnMissingBean(PermissionManager.class) - public PermissionManager permissionManager() { - return new DefaultPermissionManager(); + @ConditionalOnMissingBean(PermissionLoader.class) + public PermissionLoader permissionLoader() { + return new DefaultPermissionLoader(); + } + + @Bean + public PermissionController permissionController(PermissionManager permissionManager) { + return new PermissionController(permissionManager); + } + + @Bean + public PermissionManager permissionManager(PermissionLoader permissionLoader) { + return new PermissionManager(permissionLoader); } @Bean @@ -135,7 +148,7 @@ public class WebSecurityAutoConfiguration { List loginPreparers = loginPreparerObjectProvider.orderedStream().collect(Collectors.toList()); List authenticationProviders = abstractAuthenticationProviderObjectProvider.orderedStream().collect(Collectors.toList()); ProviderManager providerManager = new ProviderManager(authenticationProviders); - + String[] authAllows = webSecurityProperties.getAuthAllows().toArray(new String[0]); LogoutPostHandler logoutPostHandler = new LogoutPostHandler(); return http @@ -146,15 +159,17 @@ public class WebSecurityAutoConfiguration { .securityContext(it -> it.securityContextRepository(new TokenSecurityContextRepository())) .authorizeHttpRequests(it -> it + .requestMatchers(authAllows).permitAll() .anyRequest() .access((AuthorizationManager) (authentication, object) -> { // 获取当前请求路径 - String requestPath = object.getRequest().getRequestURI(); + HttpServletRequest request = object.getRequest(); // 获取当前认证用户 Authentication auth = authentication.get(); + int vote = permissionManager.vote(auth, request); - return new AuthorizationDecision(true); + return new AuthorizationDecision(vote >= 0); }) ) // .addFilter(securityInterceptor) @@ -181,7 +196,7 @@ public class WebSecurityAutoConfiguration { if (CollUtil.isNotEmpty(authIgnore)) { ignoring.requestMatchers(ArrayUtil.toArray(authIgnore, String.class)); } - ignoring.requestMatchers("/error"); + // ignoring.requestMatchers("/error"); }; } } diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/config/WebSecurityProperties.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/config/WebSecurityProperties.java index b36d348..fed22db 100644 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/config/WebSecurityProperties.java +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/config/WebSecurityProperties.java @@ -20,5 +20,9 @@ public class WebSecurityProperties { * 不进行认证校验的路径, 按 Ant 格式匹配 */ private Set authIgnores = CollUtil.empty(Set.class); + /** + * 允许匿名访问 + */ + private Set authAllows = CollUtil.empty(Set.class); } diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/contant/ClientCode.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/contant/ClientCode.java index 012055d..3c2e700 100644 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/contant/ClientCode.java +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/contant/ClientCode.java @@ -1,9 +1,14 @@ package com.njzscloud.common.security.contant; +import cn.hutool.core.collection.CollUtil; import com.njzscloud.common.core.ienum.DictInt; import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + /** * 字典代码:client_code * 字典名称:客户端代码 @@ -11,21 +16,43 @@ import lombok.RequiredArgsConstructor; @Getter @RequiredArgsConstructor public enum ClientCode implements DictInt { - PC(0, "电脑端"), - WX_MINI_APP(1, "微信小程序"), + PC(1, "电脑端"), + WX_MINI_APP(2, "微信小程序"), ; private final Integer val; private final String txt; + public static int getClientCode(List clients) { + if (CollUtil.isEmpty(clients)) return 0; + var clientCode = 0; + for (var client : clients) { + clientCode |= client; + } + return clientCode; + } + + public static List getClients(int clientCode) { + return Arrays.stream(ClientCode.class.getEnumConstants()).filter(it -> it.hasClient(clientCode)).toList(); + } + + public static boolean valid(int clientCode) { + + Optional max = Arrays.stream(ClientCode.class.getEnumConstants()) + .map(ClientCode::getVal) + .reduce((a, b) -> a | b); + return max.orElse(0) >= clientCode; + } + + public static Optional getClient(int clientCode) { + return Arrays.stream(ClientCode.class.getEnumConstants()).filter(it -> it.hasClient(clientCode)).findFirst(); + } + /** * 检查是否有登录权限 */ - public boolean hasPermission(int clientCode) { - var mask = 1 << this.val; - return (clientCode & mask) == 0; + public boolean hasClient(int clientCode) { + return (this.val & clientCode) != 0; } } - - diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/contant/Constants.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/contant/Constants.java index 0687f90..b4d8694 100644 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/contant/Constants.java +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/contant/Constants.java @@ -13,6 +13,7 @@ public final class Constants { public static final String ROLE_AUTHENTICATED = "ROLE_AUTHENTICATED"; public static final String ROLE_ANONYMOUS = "ROLE_ANONYMOUS"; public static final String ROLE_ADMIN = "ROLE_ADMIN"; + public static final String ROLE_NONE = "ROLE_NONE"; // Redis 订阅频道 权限更新 public static final String REDIS_TOPIC_PERMISSION_UPDATE = "permission_update"; diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/controller/PermissionController.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/controller/PermissionController.java new file mode 100644 index 0000000..a862a89 --- /dev/null +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/controller/PermissionController.java @@ -0,0 +1,23 @@ +package com.njzscloud.common.security.controller; + +import com.njzscloud.common.core.utils.R; +import com.njzscloud.common.security.permission.PermissionManager; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@Slf4j +@RestController +@RequestMapping("/permission") +@RequiredArgsConstructor +public class PermissionController { + private final PermissionManager permissionManager; + + @GetMapping("/refresh_cache") + public R refresh() { + permissionManager.refresh(); + return R.success(); + } +} diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/DefaultPermissionLoader.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/DefaultPermissionLoader.java new file mode 100644 index 0000000..752ff29 --- /dev/null +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/DefaultPermissionLoader.java @@ -0,0 +1,14 @@ +package com.njzscloud.common.security.permission; + +import java.util.List; + +/** + * 默认权限管理器
+ * 所有接口都必须登录后才能访问 + */ +public class DefaultPermissionLoader implements PermissionLoader { + @Override + public List load() { + return null; + } +} diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/DefaultPermissionManager.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/DefaultPermissionManager.java deleted file mode 100644 index 1b56dea..0000000 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/DefaultPermissionManager.java +++ /dev/null @@ -1,24 +0,0 @@ -package com.njzscloud.common.security.permission; - -import com.njzscloud.common.security.contant.EndpointAccessModel; - -import java.util.Collections; -import java.util.List; - -/** - * 默认权限管理器
- * 所有接口都必须登录后才能访问 - */ -public class DefaultPermissionManager extends PermissionManager { - - private final List DEFAULT_ROLE_PERMISSIONS = Collections.singletonList( - new RolePermission() - .setEndpoint("/**") - .setAccessModel(EndpointAccessModel.LOGINED) - ); - - @Override - protected List load() { - return DEFAULT_ROLE_PERMISSIONS; - } -} diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionLoader.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionLoader.java new file mode 100644 index 0000000..a217719 --- /dev/null +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionLoader.java @@ -0,0 +1,7 @@ +package com.njzscloud.common.security.permission; + +import java.util.List; + +public interface PermissionLoader { + List load(); +} diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionManager.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionManager.java index 67bd9f7..a7b9e58 100644 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionManager.java +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionManager.java @@ -1,14 +1,19 @@ package com.njzscloud.common.security.permission; import cn.hutool.core.collection.CollUtil; +import cn.hutool.core.lang.Assert; import cn.hutool.core.map.MapUtil; import cn.hutool.core.util.StrUtil; import com.njzscloud.common.security.contant.Constants; import com.njzscloud.common.security.contant.EndpointAccessModel; import com.njzscloud.common.security.ex.ForbiddenAccessException; +import com.njzscloud.common.security.ex.MissingPermissionException; import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpMethod; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher; import java.util.*; @@ -18,7 +23,9 @@ import java.util.concurrent.locks.ReentrantLock; * 权限管理器 */ @Slf4j -public abstract class PermissionManager { +@RequiredArgsConstructor +public class PermissionManager { + private static final int ACCESS_GRANTED = 1; private static final ReentrantLock PERMISSION_CACHE_LOCK = new ReentrantLock(); /** @@ -27,6 +34,27 @@ public abstract class PermissionManager { private Map> PERMISSION_CACHE; private Set FORBIDDEN_CACHE; + private static final int ACCESS_ABSTAIN = 0; + private static final int ACCESS_DENIED = -1; + private final PermissionLoader permissionLoader; + + public int vote(Authentication authentication, HttpServletRequest request) { + Collection attributes = extractAuthorities(request); + if (authentication == null) { + return ACCESS_DENIED; + } + int result = ACCESS_ABSTAIN; + Collection authorities = authentication.getAuthorities(); + for (String attribute : attributes) { + result = ACCESS_DENIED; + for (GrantedAuthority authority : authorities) { + if (attribute.equals(authority.getAuthority())) { + return ACCESS_GRANTED; + } + } + } + return result; + } /** * 刷新本地权限缓存 @@ -68,9 +96,10 @@ public abstract class PermissionManager { private void load0() { // if (log.isDebugEnabled()) log.debug("开始加载权限"); - List rolePermissions = load(); + List rolePermissions = permissionLoader.load(); + if (rolePermissions == null) rolePermissions = new ArrayList<>(); - if (rolePermissions == null) rolePermissions = Collections.emptyList(); + rolePermissions.add(RolePermission.DEFAULT); Map> permissionMap = new LinkedHashMap<>(); @@ -80,7 +109,7 @@ public abstract class PermissionManager { String endpoint = rolePermission.getEndpoint(); String method = rolePermission.getMethod(); EndpointAccessModel accessModel = rolePermission.getAccessModel(); - HttpMethod httpMethod = HttpMethod.valueOf(method); + HttpMethod httpMethod = method == null ? null : HttpMethod.valueOf(method); PathPatternRequestMatcher pathRequestMatcher = PathPatternRequestMatcher.withDefaults().matcher(httpMethod, endpoint); if (accessModel == EndpointAccessModel.FORBIDDEN) { forbiddenSet.add(pathRequestMatcher); @@ -97,6 +126,7 @@ public abstract class PermissionManager { } else if (accessModel == EndpointAccessModel.AUTHENTICATED) { String role = rolePermission.getRole(); if (StrUtil.isNotBlank(role)) configAttributes.add(role); + else configAttributes.add(Constants.ROLE_NONE); } } @@ -106,13 +136,6 @@ public abstract class PermissionManager { // if (log.isDebugEnabled()) log.debug("本地权限缓存已加载:\n{}", Jackson.toJsonStr(this.getAllRelation())); } - /** - * 加载权限 - * - * @return List<RolePermission> - */ - abstract protected List load(); - /** * 获取当前请求所需要的角色 * @@ -138,6 +161,16 @@ public abstract class PermissionManager { return CollUtil.empty(Set.class); } + public Collection getAttributes(HttpServletRequest request) { + Collection permission = this.extractAuthorities(request); + String requestURI = request.getRequestURI(); + String method = request.getMethod(); + String endpoint = method.toUpperCase() + " " + requestURI; + + Assert.notEmpty(permission, () -> new MissingPermissionException(StrUtil.format("请求: 【{}】 未指定权限", endpoint))); + return permission; + } + /** * 获取所有角色 * diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionSecurityMetaDataSource.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionSecurityMetaDataSource.java deleted file mode 100644 index ec3b923..0000000 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionSecurityMetaDataSource.java +++ /dev/null @@ -1,43 +0,0 @@ -package com.njzscloud.common.security.permission; - -import cn.hutool.core.lang.Assert; -import cn.hutool.core.util.StrUtil; -import com.njzscloud.common.security.ex.MissingPermissionException; -import jakarta.servlet.http.HttpServletRequest; -import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; -import org.springframework.security.web.FilterInvocation; - -import java.util.Collection; - -@Slf4j -@RequiredArgsConstructor -public class PermissionSecurityMetaDataSource { - - // org.springframework.security.config.annotation.web.configurers.UrlAuthorizationConfigurer - // org.springframework.security.access.vote.RoleVoter PermissionAuthorizationConfigurer - - private final PermissionManager permissionManager; - // private final boolean rejectPublicInvocations; - - - public Collection getAttributes(Object object) throws IllegalArgumentException { - HttpServletRequest request = ((FilterInvocation) object).getRequest(); - Collection permission = permissionManager.extractAuthorities(request); - String requestURI = request.getRequestURI(); - String method = request.getMethod(); - String endpoint = method.toUpperCase() + " " + requestURI; - - Assert.notEmpty(permission, () -> new MissingPermissionException(StrUtil.format("请求: 【{}】 未指定权限", endpoint))); - // if (log.isDebugEnabled()) log.debug("允许访问接口:【{}】的角色:【{}】", endpoint, permission); - return permission; - } - - public Collection getAllConfigAttributes() { - return permissionManager.getAll(); - } - - public boolean supports(Class clazz) { - return FilterInvocation.class.isAssignableFrom(clazz); - } -} diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionVoter.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionVoter.java index 2215062..d0c2472 100644 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionVoter.java +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/PermissionVoter.java @@ -23,23 +23,13 @@ public class PermissionVoter { int result = ACCESS_ABSTAIN; Collection authorities = authentication.getAuthorities(); for (String attribute : attributes) { - if (this.supports(attribute)) { - result = ACCESS_DENIED; - for (GrantedAuthority authority : authorities) { - if (attribute.equals(authority.getAuthority())) { - return ACCESS_GRANTED; - } + result = ACCESS_DENIED; + for (GrantedAuthority authority : authorities) { + if (attribute.equals(authority.getAuthority())) { + return ACCESS_GRANTED; } } } return result; } - - public boolean supports(String attribute) { - return true; - } - - public boolean supports(Class clazz) { - return true; - } } diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/RolePermission.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/RolePermission.java index be7c374..c99e794 100644 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/RolePermission.java +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/permission/RolePermission.java @@ -12,6 +12,9 @@ import lombok.experimental.Accessors; @Setter @Accessors(chain = true) public class RolePermission { + public static RolePermission DEFAULT = new RolePermission() + .setEndpoint("/**") + .setAccessModel(EndpointAccessModel.LOGINED); /** * 请求方法 diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/AbstractAuthenticationProvider.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/AbstractAuthenticationProvider.java index 7d13dcf..2ed09ce 100644 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/AbstractAuthenticationProvider.java +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/AbstractAuthenticationProvider.java @@ -116,7 +116,8 @@ public abstract class AbstractAuthenticationProvider implements AuthenticationPr Assert.isFalse(userDetail.getDisabled(), () -> new UserLoginException(ExceptionMsg.CLI_ERR_MSG, "用户已被禁用")); ClientCode clientCode = loginForm.getClientCode(); Integer code = userDetail.getClientCode(); - Assert.isTrue(clientCode.hasPermission(code), () -> new UserLoginException(ExceptionMsg.CLI_ERR_MSG, "当前用户无权使用:" + clientCode.getTxt())); + userDetail.setClient(clientCode.getVal()); + Assert.isTrue(clientCode.hasClient(code), () -> new UserLoginException(ExceptionMsg.CLI_ERR_MSG, "当前用户无权使用:" + clientCode.getTxt())); } /** diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/IAuthService.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/IAuthService.java index 7a6c162..a135b00 100644 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/IAuthService.java +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/IAuthService.java @@ -23,7 +23,7 @@ public interface IAuthService { return null; } - default UserDetail my(Long userId) { + default UserDetail my(Long userId, Integer client) { return null; } } diff --git a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/UserDetail.java b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/UserDetail.java index a3444d4..eafa11d 100644 --- a/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/UserDetail.java +++ b/njzscloud-common/njzscloud-common-security/src/main/java/com/njzscloud/common/security/support/UserDetail.java @@ -44,6 +44,7 @@ public class UserDetail implements CredentialsContainer, Principal { private Long accountId; private Long tenantId; private Integer clientCode; + private Integer client; private String tenantName; /** * 登录方式 diff --git a/njzscloud-svr/pom.xml b/njzscloud-svr/pom.xml index ec55a18..f71e53e 100644 --- a/njzscloud-svr/pom.xml +++ b/njzscloud-svr/pom.xml @@ -54,10 +54,15 @@ com.njzscloud njzscloud-common-ws - + com.njzscloud njzscloud-common-security diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/cst/org/pojo/entity/OrgEntity.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/cst/org/pojo/entity/OrgEntity.java index 867117f..6a1c075 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/cst/org/pojo/entity/OrgEntity.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/cst/org/pojo/entity/OrgEntity.java @@ -7,6 +7,7 @@ import lombok.Setter; import lombok.ToString; import lombok.experimental.Accessors; +import java.time.LocalDate; import java.time.LocalDateTime; /** @@ -48,12 +49,12 @@ public class OrgEntity { /** * 营业执照有效期 */ - private LocalDateTime licenseStartTime; + private LocalDate licenseStartTime; /** * 营业执照有效期 */ - private LocalDateTime licenseEndTime; + private LocalDate licenseEndTime; /** * 法人名称 @@ -68,12 +69,12 @@ public class OrgEntity { /** * 法人身份证有效期 */ - private LocalDateTime idcardStartTime; + private LocalDate idcardStartTime; /** * 法人身份证有效期 */ - private LocalDateTime idcardEndTime; + private LocalDate idcardEndTime; /** * 法人身份证正面 diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/controller/AuthController.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/controller/AuthController.java index c158cbb..42f4437 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/controller/AuthController.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/controller/AuthController.java @@ -1,5 +1,7 @@ package com.njzscloud.dispose.sys.auth.controller; +import cn.hutool.core.lang.Assert; +import com.njzscloud.common.core.ex.Exceptions; import com.njzscloud.common.core.utils.R; import com.njzscloud.common.security.support.UserDetail; import com.njzscloud.common.security.util.SecurityUtil; @@ -25,8 +27,12 @@ public class AuthController { */ @GetMapping("/my") public R my() { - Long userId = SecurityUtil.currentUserId(); + UserDetail userDetail = SecurityUtil.loginUser(); + Long userId = userDetail.getUserId(); + Integer client = userDetail.getClient(); - return R.success(authService.my(userId)); + Assert.notNull(client, () -> Exceptions.exception("客户端信息错误")); + + return R.success(authService.my(userId, client)); } } diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/mapper/AuthMapper.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/mapper/AuthMapper.java index 353c2db..b2c7acb 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/mapper/AuthMapper.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/mapper/AuthMapper.java @@ -2,6 +2,7 @@ package com.njzscloud.dispose.sys.auth.mapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.njzscloud.dispose.sys.auth.pojo.result.EndpointResource; +import com.njzscloud.dispose.sys.auth.pojo.result.IdentityInfo; import com.njzscloud.dispose.sys.auth.pojo.result.MenuResource; import com.njzscloud.dispose.sys.auth.pojo.result.MyResult; import org.apache.ibatis.annotations.Mapper; @@ -17,7 +18,9 @@ public interface AuthMapper { Set selectRole(@Param("userId") Long userId); - List selectUserMenu(@Param("userId") Long userId); + List selectUserMenu(@Param("userId") Long userId, @Param("client") Integer client); List selectUserEndpoint(@Param("userId") Long userId); + + List selectUserIdentity(@Param("userId") Long userId); } diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/EndpointResource.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/EndpointResource.java index a44bcfc..794cd0b 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/EndpointResource.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/EndpointResource.java @@ -1,5 +1,6 @@ package com.njzscloud.dispose.sys.auth.pojo.result; +import com.njzscloud.common.security.contant.EndpointAccessModel; import lombok.Getter; import lombok.Setter; import lombok.ToString; @@ -37,7 +38,7 @@ public class EndpointResource { /** * 接口访问模式; 字典代码:endpoint_access_model */ - private String accessModel; + private EndpointAccessModel accessModel; /** * 备注 diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/IdentityInfo.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/IdentityInfo.java new file mode 100644 index 0000000..a2b3d53 --- /dev/null +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/IdentityInfo.java @@ -0,0 +1,165 @@ +package com.njzscloud.dispose.sys.auth.pojo.result; + +import com.njzscloud.dispose.cst.customer.constant.IdentityCategory; +import com.njzscloud.dispose.cst.customer.constant.SettlementWay; +import com.njzscloud.dispose.cst.org.constant.OrgCategory; +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +import java.time.LocalDate; + +@Getter +@Setter +@ToString +@Accessors(chain = true) +public class IdentityInfo { + /** + * 身份类型;多个身份多条数据,PingTai-->平台、ChanFei-->产废方、QingYun-->清运方、XiaoNa-->消纳方、CaiGou-->采购方 + */ + private IdentityCategory identityCategory; + + private Long customerId; + + /** + * 组织信息 Id;cst_org.id + */ + private Long orgId; + + /** + * 客户姓名 + */ + private String customerName; + + /** + * 客户联系电话 + */ + private String phone; + + /** + * 结算方式,YueJie-->月结、YuE-->余额、XianFu-->现付 + */ + private SettlementWay settlementWay; + + /** + * 是否管理员;是否为当前的组织管理员,0-->否、1-->是 + */ + private Boolean manager; + + + /** + * 主体类型,GeTiHu-->个体户、QiYe-->企业 + */ + private OrgCategory orgCategory; + + /** + * 统一社会信用代码 + */ + private String uscc; + + /** + * 组织名称 + */ + private String orgName; + + /** + * 营业执照 + */ + private String businessLicense; + + /** + * 营业执照有效期 + */ + private LocalDate licenseStartTime; + + /** + * 营业执照有效期 + */ + private LocalDate licenseEndTime; + + /** + * 法人名称 + */ + private String legalRepresentative; + + /** + * 法人身份证号 + */ + private String idcard; + + /** + * 法人身份证有效期 + */ + private LocalDate idcardStartTime; + + /** + * 法人身份证有效期 + */ + private LocalDate idcardEndTime; + + /** + * 法人身份证正面 + */ + private String idcardFront; + + /** + * 法人身份证反面 + */ + private String idcardBack; + + /** + * 省;代码 + */ + private String province; + + /** + * 市;代码 + */ + private String city; + + /** + * 区县;代码 + */ + private String area; + + /** + * 乡镇街道;代码 + */ + private String town; + + /** + * 省;名称 + */ + private String provinceName; + + /** + * 市;名称 + */ + private String cityName; + + /** + * 区县;名称 + */ + private String areaName; + + /** + * 乡镇街道;名称 + */ + private String townName; + + /** + * 详细地址 + */ + private String address; + + /** + * 经度 + */ + private Double lng; + + /** + * 纬度 + */ + private Double lat; +} diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/MyResult.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/MyResult.java index cd95fb2..765a76f 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/MyResult.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/pojo/result/MyResult.java @@ -16,6 +16,7 @@ public class MyResult extends UserDetail { private List menus; private List endpoints; + private List identities; private List> setting; diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/service/AuthService.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/service/AuthService.java index 7795644..a8795b7 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/service/AuthService.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/auth/service/AuthService.java @@ -1,14 +1,17 @@ package com.njzscloud.dispose.sys.auth.service; import cn.hutool.core.bean.BeanUtil; +import cn.hutool.core.lang.Assert; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; +import com.njzscloud.common.core.ex.Exceptions; import com.njzscloud.common.security.module.password.PasswordLoginForm; import com.njzscloud.common.security.module.wechat.mini.WechatMiniLoginForm; import com.njzscloud.common.security.support.IAuthService; import com.njzscloud.common.security.support.UserDetail; import com.njzscloud.dispose.sys.auth.mapper.AuthMapper; import com.njzscloud.dispose.sys.auth.pojo.result.EndpointResource; +import com.njzscloud.dispose.sys.auth.pojo.result.IdentityInfo; import com.njzscloud.dispose.sys.auth.pojo.result.MenuResource; import com.njzscloud.dispose.sys.auth.pojo.result.MyResult; import lombok.RequiredArgsConstructor; @@ -22,6 +25,9 @@ import java.util.Set; import static com.njzscloud.common.security.contant.Constants.ROLE_ANONYMOUS; import static com.njzscloud.common.security.contant.Constants.ROLE_AUTHENTICATED; +/** + * 登录 + */ @Slf4j @Service @RequiredArgsConstructor @@ -53,14 +59,17 @@ public class AuthService implements IAuthService { * 获取当前登录人信息 */ @Override - public UserDetail my(Long userId) { - UserDetail userDetail = authMapper.selectUser(Wrappers.query().eq("a.id", userId).eq("a.deleted", 0)); - List menuResources = authMapper.selectUserMenu(userId); + public UserDetail my(Long userId, Integer client) { + UserDetail userDetail = authMapper.selectUser(Wrappers.query().eq("b.id", userId).eq("a.deleted", 0)); + Assert.notNull(userDetail, () -> Exceptions.exception("未查询到用户信息")); + List menuResources = authMapper.selectUserMenu(userId, client); List endpointResources = authMapper.selectUserEndpoint(userId); + List identityInfoList = authMapper.selectUserIdentity(userId); Set roles = authMapper.selectRole(userId); roles.add(ROLE_AUTHENTICATED); roles.add(ROLE_ANONYMOUS); return BeanUtil.copyProperties(userDetail, MyResult.class) + .setIdentities(identityInfoList) .setMenus(menuResources) .setEndpoints(endpointResources) .setRoles(roles) diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/contant/RequestMethod.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/contant/RequestMethod.java index 0572f8b..a1184bd 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/contant/RequestMethod.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/contant/RequestMethod.java @@ -4,6 +4,9 @@ import com.njzscloud.common.core.ienum.DictStr; import lombok.Getter; import lombok.RequiredArgsConstructor; +import java.util.Arrays; +import java.util.Optional; + /** * 字典代码:request_method * 字典名称:HTTP 请求方式 @@ -18,4 +21,9 @@ public enum RequestMethod implements DictStr { private final String val; private final String txt; + + public static RequestMethod resolve(String name) { + Optional first = Arrays.stream(RequestMethod.class.getEnumConstants()).filter(it -> it.val.equals(name)).findFirst(); + return first.orElse(null); + } } diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/controller/EndpointController.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/controller/EndpointController.java index bf52215..cde1e60 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/controller/EndpointController.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/controller/EndpointController.java @@ -5,11 +5,16 @@ import com.njzscloud.dispose.sys.endpoint.pojo.entity.EndpointEntity; import com.njzscloud.dispose.sys.endpoint.pojo.param.EndpointSearchParam; import com.njzscloud.dispose.sys.endpoint.pojo.result.EndpointDetailResult; import com.njzscloud.dispose.sys.endpoint.service.EndpointService; +import com.njzscloud.dispose.sys.resource.pojo.result.ControllerMappingResult; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.mvc.condition.RequestMethodsRequestCondition; +import org.springframework.web.servlet.mvc.method.RequestMappingInfo; +import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import java.util.List; +import java.util.*; /** * 端点信息表 @@ -21,6 +26,64 @@ import java.util.List; public class EndpointController { private final EndpointService endpointService; + private final RequestMappingHandlerMapping requestMappingHandlerMapping; + + public List scanAllControllerMappings() { + List result = new ArrayList<>(); + + // 1. 获取所有RequestMappingInfo(包含映射规则)和对应的HandlerMethod + Map handlerMethods = requestMappingHandlerMapping.getHandlerMethods(); + + // 2. 遍历解析每个映射规则 + for (Map.Entry entry : handlerMethods.entrySet()) { + RequestMappingInfo requestMappingInfo = entry.getKey(); + HandlerMethod handlerMethod = entry.getValue(); + + // 封装DTO + ControllerMappingResult dto = new ControllerMappingResult(); + + // === 解析控制器类信息 === + Class controllerClass = handlerMethod.getBeanType(); + dto.setControllerClassName(controllerClass.getCanonicalName()); + + // === 解析类级@RequestMapping路径 === + RequestMapping classRequestMapping = controllerClass.getAnnotation(RequestMapping.class); + String classPath = ""; + if (classRequestMapping != null && classRequestMapping.value().length > 0) { + classPath = classRequestMapping.value()[0]; // 取第一个路径(支持数组,通常只用一个) + // 处理路径格式:确保以/开头,避免拼接错误(如类路径是endpoint → 补为/endpoint) + if (!classPath.startsWith("/")) { + classPath = "/" + classPath; + } + } + + // === 解析方法级路径 === + Set methodPatterns = requestMappingInfo.getPatternValues(); + + // 方法路径通常只有一个,取第一个即可 + String methodPath = methodPatterns.iterator().next(); + + // === 拼接完整URL === + String fullUrl = classPath + methodPath; + // 处理重复的/(如类路径/endpoint + 方法路径/add → /endpoint/add;类路径/endpoint/ + 方法路径/add → /endpoint/add) + fullUrl = fullUrl.replaceAll("//+", "/"); + dto.setFullUrl(fullUrl); + + // === 解析请求方法(GET/POST等) === + RequestMethodsRequestCondition methodsCondition = requestMappingInfo.getMethodsCondition(); + Set methods = methodsCondition.getMethods(); + Optional first = methods.stream().findFirst(); + Optional s = first.map(Enum::name); + dto.setHttpMethods(s.orElse("")); + + // === 解析方法名 === + dto.setMethodName(handlerMethod.getMethod().getName()); + + result.add(dto); + } + + return result; + } /** * 新增 @@ -65,4 +128,13 @@ public class EndpointController { return R.success(endpointService.listAll(endpointSearchParam)); } + /** + * 重新加载资源 + */ + @GetMapping("/reload") + public R reload() { + endpointService.saveAll(scanAllControllerMappings()); + return R.success(); + } + } diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/service/EndpointService.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/service/EndpointService.java index a03c785..ff2c2d2 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/service/EndpointService.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/endpoint/service/EndpointService.java @@ -5,15 +5,21 @@ import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.njzscloud.common.core.utils.GroupUtil; +import com.njzscloud.common.security.contant.EndpointAccessModel; +import com.njzscloud.dispose.sys.endpoint.contant.RequestMethod; import com.njzscloud.dispose.sys.endpoint.mapper.EndpointMapper; import com.njzscloud.dispose.sys.endpoint.pojo.entity.EndpointEntity; import com.njzscloud.dispose.sys.endpoint.pojo.param.EndpointSearchParam; import com.njzscloud.dispose.sys.endpoint.pojo.result.EndpointDetailResult; +import com.njzscloud.dispose.sys.resource.pojo.result.ControllerMappingResult; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; +import java.util.Map; +import java.util.Set; import java.util.stream.Collectors; /** @@ -64,4 +70,24 @@ public class EndpointService extends ServiceImpl .map(it -> BeanUtil.copyProperties(it, EndpointDetailResult.class)) .collect(Collectors.toList()); } + + @Transactional(rollbackFor = Exception.class) + public void saveAll(List controllerMappingResults) { + List oldEndpoints = this.list(); + Map map = GroupUtil.k_o(oldEndpoints, it -> it.getRequestMethod() + it.getEndpointPath()); + Set endpointPaths = map.keySet(); + + List list = controllerMappingResults + .stream() + .filter(it -> it.getControllerClassName().startsWith("com.njzscloud") && !endpointPaths.contains(it.getHttpMethods() + it.getFullUrl())) + .map(it -> new EndpointEntity() + .setEndpointPath(it.getFullUrl()) + .setRoutingPath("") + .setMemo("") + .setAccessModel(EndpointAccessModel.LOGINED) + .setRequestMethod(RequestMethod.resolve(it.getHttpMethods()))) + .toList(); + + this.saveBatch(list); + } } diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/entity/MenuEntity.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/entity/MenuEntity.java index 2457a1d..75d9bd7 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/entity/MenuEntity.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/entity/MenuEntity.java @@ -2,6 +2,7 @@ package com.njzscloud.dispose.sys.menu.pojo.entity; import com.baomidou.mybatisplus.annotation.*; import com.njzscloud.common.mp.support.handler.j.JsonTypeHandler; +import com.njzscloud.common.security.contant.ClientCode; import com.njzscloud.dispose.sys.menu.contant.MenuCategory; import lombok.Getter; import lombok.Setter; @@ -26,6 +27,9 @@ public class MenuEntity { private Long id; private String sn; + + private ClientCode clientCode; + /** * 上级 Id; 层级为 1 的节点值为 0 */ diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuAddParam.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuAddParam.java index 7c415c0..f58d49e 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuAddParam.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuAddParam.java @@ -4,8 +4,10 @@ import cn.hutool.core.util.StrUtil; import com.njzscloud.common.mvc.validator.Constrained; import com.njzscloud.common.mvc.validator.Constraint; import com.njzscloud.common.mvc.validator.ValidRule; +import com.njzscloud.common.security.contant.ClientCode; import com.njzscloud.dispose.sys.menu.contant.MenuCategory; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Getter; import lombok.Setter; @@ -16,6 +18,9 @@ import lombok.Setter; @Setter @Constraint public class MenuAddParam implements Constrained { + @NotNull + private ClientCode clientCode; + /** * 上级 Id; 层级为 1 的节点值为 0 */ diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuModifyParam.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuModifyParam.java index 6c47779..19121f3 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuModifyParam.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuModifyParam.java @@ -3,6 +3,7 @@ package com.njzscloud.dispose.sys.menu.pojo.param; import com.njzscloud.common.mvc.validator.Constrained; import com.njzscloud.common.mvc.validator.Constraint; import com.njzscloud.common.mvc.validator.ValidRule; +import com.njzscloud.common.security.contant.ClientCode; import lombok.Getter; import lombok.Setter; import lombok.experimental.Accessors; @@ -20,6 +21,7 @@ public class MenuModifyParam implements Constrained { * Id */ private Long id; + private ClientCode clientCode; /** * 上级 Id; 层级为 1 的节点值为 0 diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuSearchParam.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuSearchParam.java index abd636a..9766e88 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuSearchParam.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/param/MenuSearchParam.java @@ -16,6 +16,7 @@ public class MenuSearchParam { private Long pid; + private Integer clientCode; /** * 菜单名称 diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/result/MenuDetailResult.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/result/MenuDetailResult.java index 50739f6..049bb6b 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/result/MenuDetailResult.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/pojo/result/MenuDetailResult.java @@ -1,5 +1,6 @@ package com.njzscloud.dispose.sys.menu.pojo.result; +import com.njzscloud.common.security.contant.ClientCode; import com.njzscloud.dispose.sys.menu.contant.MenuCategory; import lombok.EqualsAndHashCode; import lombok.Getter; @@ -22,6 +23,8 @@ public class MenuDetailResult { */ private Long id; private String sn; + private ClientCode clientCode; + /** * 上级 Id; 层级为 1 的节点值为 0 */ diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/service/MenuService.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/service/MenuService.java index eef7098..750198e 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/service/MenuService.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/menu/service/MenuService.java @@ -195,11 +195,13 @@ public class MenuService extends ServiceImpl implements Long pid = menuSearchParam.getPid(); String title = menuSearchParam.getTitle(); String routeName = menuSearchParam.getRouteName(); - return this.list(Wrappers.lambdaQuery() - .eq(pid != null, MenuEntity::getPid, pid) - .like(StrUtil.isNotBlank(title), MenuEntity::getTitle, title) - .like(StrUtil.isNotBlank(routeName), MenuEntity::getRouteName, routeName) - .orderByAsc(Arrays.asList(MenuEntity::getTier, MenuEntity::getSort, MenuEntity::getId))) + Integer clientCode = menuSearchParam.getClientCode(); + return this.list(Wrappers.query() + .eq(pid != null, "pid", pid) + .and(clientCode != null && clientCode >= 0, it -> it.ne("clientCode & " + clientCode, 0)) + .like(StrUtil.isNotBlank(title), "title", title) + .like(StrUtil.isNotBlank(routeName), "route_name", routeName) + .orderByAsc(Arrays.asList("tier", "sort", "id"))) .stream() .map(it -> BeanUtil.copyProperties(it, MenuDetailResult.class)) .collect(Collectors.toList()); diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/mapper/ResourceMapper.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/mapper/ResourceMapper.java index 01b04af..c2cf1bd 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/mapper/ResourceMapper.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/mapper/ResourceMapper.java @@ -3,6 +3,7 @@ package com.njzscloud.dispose.sys.resource.mapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.toolkit.Constants; +import com.njzscloud.common.security.permission.RolePermission; import com.njzscloud.dispose.sys.resource.pojo.entity.ResourceEntity; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; @@ -17,4 +18,7 @@ public interface ResourceMapper extends BaseMapper { List occupied(@Param(Constants.WRAPPER) QueryWrapper ew); List listRoleRes(@Param("roleId") String roleId); + + List loadPermission(); + } diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/pojo/result/ControllerMappingResult.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/pojo/result/ControllerMappingResult.java new file mode 100644 index 0000000..60fdc35 --- /dev/null +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/pojo/result/ControllerMappingResult.java @@ -0,0 +1,29 @@ +package com.njzscloud.dispose.sys.resource.pojo.result; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; +import lombok.experimental.Accessors; + +@Getter +@Setter +@ToString +@Accessors(chain = true) +public class ControllerMappingResult { + /** + * 控制器类全名(如com.xxx.controller.EndpointController) + */ + private String controllerClassName; + /** + * 方法名(如add) + */ + private String methodName; + /** + * 完整请求路径(如/endpoint/add) + */ + private String fullUrl; + /** + * 请求方法(GET/POST/PUT/DELETE等) + */ + private String httpMethods; +} diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/service/ResourceService.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/service/ResourceService.java index e27c2be..4569631 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/service/ResourceService.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/resource/service/ResourceService.java @@ -3,6 +3,8 @@ package com.njzscloud.dispose.sys.resource.service; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; +import com.njzscloud.common.security.permission.PermissionLoader; +import com.njzscloud.common.security.permission.RolePermission; import com.njzscloud.dispose.sys.resource.contant.ResourceOrigin; import com.njzscloud.dispose.sys.resource.mapper.ResourceMapper; import com.njzscloud.dispose.sys.resource.pojo.entity.ResourceEntity; @@ -19,8 +21,7 @@ import java.util.List; @Slf4j @Service @RequiredArgsConstructor -public class ResourceService extends ServiceImpl implements IService { - +public class ResourceService extends ServiceImpl implements PermissionLoader, IService { /** * 删除 */ @@ -45,4 +46,9 @@ public class ResourceService extends ServiceImpl public List listRoleRes(String roleId) { return baseMapper.listRoleRes(roleId); } + + @Override + public List load() { + return baseMapper.loadPermission(); + } } diff --git a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/user/pojo/param/UserRegisterParam.java b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/user/pojo/param/UserRegisterParam.java index 38673f6..029958b 100644 --- a/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/user/pojo/param/UserRegisterParam.java +++ b/njzscloud-svr/src/main/java/com/njzscloud/dispose/sys/user/pojo/param/UserRegisterParam.java @@ -17,7 +17,7 @@ import lombok.Setter; import lombok.ToString; import lombok.experimental.Accessors; -import java.time.LocalDateTime; +import java.time.LocalDate; import java.util.List; @Getter @@ -106,7 +106,7 @@ public class UserRegisterParam implements Constrained { /** * 允许登录的客户端; 字典代码:client_code */ - private ClientCode clientCode; + private Integer clientCode; @Override public ValidRule[] rules() { @@ -115,9 +115,9 @@ public class UserRegisterParam implements Constrained { || (StrUtil.isNotBlank(phone) && StrUtil.isNotBlank(secret)) || StrUtil.isNotBlank(wechatCode), "账号信息不能为空"), ValidRule.of(() -> clientCode != null, "客户端信息不能为空"), + ValidRule.of(() -> clientCode > 0 && ClientCode.valid(clientCode), "客户端信息无效"), }; } - } @Getter @@ -194,12 +194,12 @@ public class UserRegisterParam implements Constrained { /** * 营业执照有效期 */ - private LocalDateTime licenseStartTime; + private LocalDate licenseStartTime; /** * 营业执照有效期 */ - private LocalDateTime licenseEndTime; + private LocalDate licenseEndTime; /** * 法人名称 @@ -214,12 +214,14 @@ public class UserRegisterParam implements Constrained { /** * 法人身份证有效期 */ - private LocalDateTime idcardStartTime; + @NotNull(message = "法人身份证有效期不能为空") + private LocalDate idcardStartTime; /** * 法人身份证有效期 */ - private LocalDateTime idcardEndTime; + @NotNull(message = "法人身份证有效期不能为空") + private LocalDate idcardEndTime; /** * 法人身份证正面 diff --git a/njzscloud-svr/src/main/resources/application-dev.yml b/njzscloud-svr/src/main/resources/application-dev.yml index cacde46..41aa0e4 100644 --- a/njzscloud-svr/src/main/resources/application-dev.yml +++ b/njzscloud-svr/src/main/resources/application-dev.yml @@ -4,8 +4,9 @@ spring: username: root password: admin888999 security: - auth-ignores: + auth-allows: - /oss/** + - /endpoint/reload oss: type: ali diff --git a/njzscloud-svr/src/main/resources/mapper/cst/customer/CustomerMapper.xml b/njzscloud-svr/src/main/resources/mapper/cst/customer/CustomerMapper.xml index f6f26d4..598dc2d 100644 --- a/njzscloud-svr/src/main/resources/mapper/cst/customer/CustomerMapper.xml +++ b/njzscloud-svr/src/main/resources/mapper/cst/customer/CustomerMapper.xml @@ -1,4 +1,4 @@ - + diff --git a/njzscloud-svr/src/main/resources/mapper/sys/auth/AuthMapper.xml b/njzscloud-svr/src/main/resources/mapper/sys/auth/AuthMapper.xml index 1d91b3a..ac272c4 100644 --- a/njzscloud-svr/src/main/resources/mapper/sys/auth/AuthMapper.xml +++ b/njzscloud-svr/src/main/resources/mapper/sys/auth/AuthMapper.xml @@ -13,7 +13,6 @@ + diff --git a/njzscloud-svr/src/main/resources/mapper/sys/resource/ResourceMapper.xml b/njzscloud-svr/src/main/resources/mapper/sys/resource/ResourceMapper.xml index 9dce139..fcf90ab 100644 --- a/njzscloud-svr/src/main/resources/mapper/sys/resource/ResourceMapper.xml +++ b/njzscloud-svr/src/main/resources/mapper/sys/resource/ResourceMapper.xml @@ -21,4 +21,15 @@ INNER JOIN sys_role_resource b ON b.res_id = a.id WHERE b.role_id = ${roleId} + diff --git a/pom.xml b/pom.xml index 78265b4..b76e753 100644 --- a/pom.xml +++ b/pom.xml @@ -81,6 +81,11 @@ njzscloud-common-mvc 0.0.1 + + com.njzscloud + njzscloud-common-cache + 0.0.1 + com.njzscloud njzscloud-common-redis diff --git a/z-doc/pdma/njzscloud-dispose.pdma b/z-doc/pdma/njzscloud-dispose.pdma index 3326c3b..a3571f5 100644 --- a/z-doc/pdma/njzscloud-dispose.pdma +++ b/z-doc/pdma/njzscloud-dispose.pdma @@ -5899,6 +5899,71 @@ "attr20": "", "origin": "IMPORT" }, + { + "id": "7D98C996-2848-4BDB-9A41-27A1E3A209FD", + "defKey": "client_code", + "defName": "客户端", + "intro": "位权码", + "baseDataType": "INT", + "bizDomainType": "", + "dbDataType": "INT", + "dataLen": "", + "numScale": "", + "primaryKey": 0, + "notNull": 1, + "autoIncrement": 0, + "defaultValue": "0", + "stndDictId": "", + "stndFieldId": "", + "stndDictKey": "client_code", + "stndFieldKey": "", + "stndComplianceLevel": "", + "stndComplianceType": "", + "dictFrom": "Manual", + "dictItems": [ + { + "itemKey": "0", + "itemName": "WEB 后台", + "intro": "第 0 位", + "id": "68123977-C53D-4AAA-9B8E-44CCFFF96518" + }, + { + "itemKey": "1", + "itemName": "微信小程序", + "intro": "第 1 位", + "id": "0AB3C4CB-01C5-40E7-8C3C-C5EF71BC4BAC" + }, + { + "itemKey": "2", + "itemName": "手机 APP", + "intro": "第 2 位", + "id": "22B26C48-0C87-442F-ABDC-D9E9D2D2DB9D" + } + ], + "fieldTier": "", + "mark": null, + "attr1": "", + "attr2": "", + "attr3": "", + "attr4": "", + "attr5": "", + "attr6": "", + "attr7": "", + "attr8": "", + "attr9": "", + "attr10": "", + "attr11": "", + "attr12": "", + "attr13": "", + "attr14": "", + "attr15": "", + "attr16": "", + "attr17": "", + "attr18": "PDManer", + "attr19": "68EE2E5E-F775-458D-8686-B8834995C062", + "attr20": "", + "origin": "UI" + }, { "id": "887EF609-A47C-45A4-942C-8AA5DA81AD76", "defKey": "sn", @@ -6240,9 +6305,9 @@ "dataLen": 1, "numScale": "", "primaryKey": 0, - "notNull": 0, + "notNull": 1, "autoIncrement": 0, - "defaultValue": "", + "defaultValue": "0", "stndDictId": "", "stndDictKey": "", "stndFieldId": "", @@ -6324,9 +6389,9 @@ "dataLen": 128, "numScale": "", "primaryKey": 0, - "notNull": 0, + "notNull": 1, "autoIncrement": 0, - "defaultValue": "", + "defaultValue": "''", "stndDictId": "", "stndDictKey": "", "stndFieldId": "", @@ -6366,9 +6431,9 @@ "dataLen": 255, "numScale": "", "primaryKey": 0, - "notNull": 0, + "notNull": 1, "autoIncrement": 0, - "defaultValue": "", + "defaultValue": "''", "stndDictId": "", "stndFieldId": "", "stndDictKey": "", @@ -22933,9 +22998,9 @@ "defKey": "license_start_time", "defName": "营业执照有效期", "intro": null, - "baseDataType": "DATETIME", + "baseDataType": "DATE", "bizDomainType": "", - "dbDataType": "DATETIME", + "dbDataType": "DATE", "dataLen": null, "numScale": null, "primaryKey": 0, @@ -22979,9 +23044,9 @@ "defKey": "license_end_time", "defName": "营业执照有效期", "intro": null, - "baseDataType": "DATETIME", + "baseDataType": "DATE", "bizDomainType": "", - "dbDataType": "DATETIME", + "dbDataType": "DATE", "dataLen": null, "numScale": null, "primaryKey": 0, @@ -23117,9 +23182,9 @@ "defKey": "idcard_start_time", "defName": "法人身份证有效期", "intro": null, - "baseDataType": "DATETIME", + "baseDataType": "DATE", "bizDomainType": "", - "dbDataType": "DATETIME", + "dbDataType": "DATE", "dataLen": "", "numScale": null, "primaryKey": 0, @@ -23163,9 +23228,9 @@ "defKey": "idcard_end_time", "defName": "法人身份证有效期", "intro": null, - "baseDataType": "DATETIME", + "baseDataType": "DATE", "bizDomainType": "", - "dbDataType": "DATETIME", + "dbDataType": "DATE", "dataLen": "", "numScale": null, "primaryKey": 0, @@ -42968,7 +43033,7 @@ "readonly": false, "allowWs": false }, - "updateTime": 1765359635412, - "signature": "e1b11ecff62865e7eb000c6c88e1e638", + "updateTime": 1765434816305, + "signature": "f39d1018f0ed556230f3489a43a16da7", "branchId": "1111" -} +} \ No newline at end of file