Merge branch 'master' of http://47.92.168.204:3000/VoRDM/vordm-backend
This commit is contained in:
commit
c69580c329
|
@ -52,5 +52,8 @@ public interface CommonConstant {
|
|||
*/
|
||||
String KN_VORDM_MODULE_NAME = "biz-vordm";
|
||||
|
||||
|
||||
/**
|
||||
* 系统管理模块 application name
|
||||
*/
|
||||
String KN_SYSTEM_MANAGER_MODULE_NAME = "system-manager";
|
||||
}
|
||||
|
|
|
@ -1,90 +0,0 @@
|
|||
package org.springblade.common.enums;
|
||||
|
||||
/**
|
||||
* 事件枚举,报警枚举
|
||||
*/
|
||||
public enum AlarmEnum {
|
||||
// CODE_41 (41,"胁迫报警"),
|
||||
// CODE_42 (42,"合法密码开门"),
|
||||
// CODE_43 (43,"非法密码开门"),
|
||||
// CODE_45 (45,"合法指纹开门"),
|
||||
// CODE_46 (46,"非法指纹开门"),
|
||||
// CODE_48 (48,"远程开门(室内机/平台),"),
|
||||
CODE_51 (51,"合法刷卡"),
|
||||
|
||||
// CODE_52 (52,"非法刷卡"),
|
||||
// CODE_53 (53,"门磁报警"),
|
||||
// CODE_54 (54,"异常开门"),
|
||||
// CODE_55 (55,"异常关门"),
|
||||
// CODE_56 (56,"正常关门"),
|
||||
// CODE_57 (57,"正常开门"),
|
||||
CODE_61 (61,"合法人脸刷门"),
|
||||
// CODE_62 (62,"非法人脸刷门"),
|
||||
// CODE_1420 (1420,"超时门未关"),
|
||||
// CODE_1430 (1430,"非法闯入"),
|
||||
// CODE_1433 (1433,"黑名单报警"),
|
||||
// CODE_1434 (1434,"合法二维码开门"),
|
||||
// CODE_1435 (1435,"非法二维码开门"),
|
||||
// CODE_1436 (1436,"人证合法开门"),
|
||||
// CODE_1437 (1437,"人证非法开门"),
|
||||
// CODE_1438 (1438,"人证和身份证非法开门"),
|
||||
// CODE_1439 (1439,"人证和身份证合法开门"),
|
||||
// CODE_1443 (1443,"外部报警"),
|
||||
// CODE_1448 (1448,"RFID感应报警"),
|
||||
// CODE_1449 (1449,"RFID非法感应报警"),
|
||||
// CODE_1450 (1450,"RFID外部报警"),
|
||||
// CODE_1455 (1455,"先刷卡后密码合法开门"),
|
||||
// CODE_1456 (1456,"先刷卡后密码非法开门"),
|
||||
// CODE_1461 (1461,"刷卡+指纹组合合法开门"),
|
||||
// CODE_1462 (1462,"刷卡+指纹组合非法开门"),
|
||||
// CODE_1463 (1463,"多人合法开门"),
|
||||
// CODE_1464 (1464,"多人非法开门"),
|
||||
// CODE_1467 (1467,"人员编号+密码合法开门"),
|
||||
// CODE_1468 (1468,"人员编号+密码非法开门"),
|
||||
// CODE_1469 (1469,"人脸+密码合法开门"),
|
||||
// CODE_1470 (1470,"人脸+密码非法开门"),
|
||||
// CODE_1471 (1471,"指纹+密码合法开门"),
|
||||
// CODE_1472 (1472,"指纹+密码非法开门"),
|
||||
// CODE_1473 (1473,"指纹+人脸合法开门"),
|
||||
// CODE_1474 (1474,"指纹+人脸非法开门"),
|
||||
// CODE_1475 (1475,"刷卡+人脸合法开门"),
|
||||
// CODE_1476 (1476,"刷卡+人脸非法开门"),
|
||||
// CODE_1487 (1487,"指纹+人脸+密码合法开门"),
|
||||
// CODE_1488 (1488,"指纹+人脸+密码非法开门"),
|
||||
// CODE_1489 (1489,"刷卡+人脸+密码合法开门"),
|
||||
// CODE_1490 (1490,"刷卡+人脸+密码非法开门"),
|
||||
// CODE_1491 (1491,"刷卡+指纹+密码合法开门"),
|
||||
// CODE_1492 (1492,"刷卡+指纹+密码非法开门"),
|
||||
// CODE_1493 (1493,"卡+指纹+人脸合法开门"),
|
||||
// CODE_1494 (1494,"卡+指纹+人脸非法开门"),
|
||||
// CODE_4603 (4603,"卡+指纹+人脸+密码组合合法开门"),
|
||||
// CODE_4604 (4604,"卡+指纹+人脸+密码组合非法开门")
|
||||
CODE_1001005 (1001005 ,"人脸检测"),
|
||||
// CODE_1001006 ( 1001006,"人体识别"),
|
||||
// CODE_1001004 ( 1001004,"访客报警"),
|
||||
// CODE_1001003 (1001003 ,"内部人员报警"),
|
||||
CODE_1001002 (1001002 ,"黑名单库报警"),
|
||||
CODE_1001001 (1001001 ,"白名单库报警"),
|
||||
// CODE_1001000 (1001000 ,"陌生人报警"),
|
||||
// CODE_1003003 (1003003 ,"访客来访信息下级上报"),
|
||||
// CODE_1003002 (1003002 ,"访客区域布控"),
|
||||
CODE_597 (597 ,"离岗报警"),
|
||||
CODE_15670(15670,"睡岗报警"),
|
||||
CODE_16(16,"设备离线"),
|
||||
CODE_15768 (15768 ,"玩手机事件");
|
||||
private int code ;
|
||||
private String msg;
|
||||
AlarmEnum(int code, String msg) {
|
||||
this.code = code ;
|
||||
this.msg = msg;
|
||||
}
|
||||
public static String getValue(int code) {
|
||||
AlarmEnum[] carTypeEnums = values();
|
||||
for (AlarmEnum carTypeEnum : carTypeEnums) {
|
||||
if (carTypeEnum.code==code) {
|
||||
return carTypeEnum.msg;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
package org.springblade.common.enums;
|
||||
|
||||
/**
|
||||
* 业务处理枚举,针对访客机
|
||||
*/
|
||||
public enum BusinessEnum {
|
||||
/**
|
||||
* 1。访客 刷访客机,录入访客信息
|
||||
*/
|
||||
CODE_THIRD_INFO("visitor.thirdInfo","访客审批"),
|
||||
CODE_VISITOR_STATUS("visitor.status","访客信息变更"),
|
||||
CODE_VISITOR("visitor.record","访客信息");
|
||||
private String code ;
|
||||
|
||||
public String getMsg() {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void setMsg(String msg) {
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
private String msg;
|
||||
public String getCode() {
|
||||
return code;
|
||||
}
|
||||
|
||||
public void setCode(String code) {
|
||||
this.code = code;
|
||||
}
|
||||
|
||||
|
||||
BusinessEnum(String code, String msg) {
|
||||
this.code = code ;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
public static String getValue(String code) {
|
||||
BusinessEnum[] carTypeEnums = values();
|
||||
for (BusinessEnum carTypeEnum : carTypeEnums) {
|
||||
if (carTypeEnum.code.equals(code)) {
|
||||
return carTypeEnum.msg;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
FROM bladex/alpine-java:openjdk8-openj9_cn_slim
|
||||
|
||||
LABEL maintainer=whq<460794335@qq.com>
|
||||
|
||||
RUN mkdir -p /kn/auth
|
||||
|
||||
WORKDIR /kn/auth
|
||||
|
||||
EXPOSE 8100
|
||||
|
||||
ADD ./target/kn-sys-manager.jar ./app.jar
|
||||
|
||||
ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "app.jar"]
|
||||
|
||||
CMD ["--spring.profiles.active=test"]
|
|
@ -0,0 +1,159 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>com.kening.platform</groupId>
|
||||
<artifactId>kn-vordm</artifactId>
|
||||
<version>${revision}</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>kn-sys-manager</artifactId>
|
||||
<name>${project.artifactId}</name>
|
||||
<version>${revision}</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.alibaba</groupId>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<version>1.2.83</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.kening.platform</groupId>
|
||||
<artifactId>kn-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.kening.platform</groupId>
|
||||
<artifactId>kn-launcher</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-core-db</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>postgresql</artifactId>
|
||||
<groupId>org.postgresql</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-tenant</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-mybatis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.javassist</groupId>
|
||||
<artifactId>javassist</artifactId>
|
||||
<version>3.25.0-GA</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>io.prometheus</groupId>
|
||||
<artifactId>simpleclient</artifactId>
|
||||
<version>0.9.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-cache</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-core-cloud</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>HdrHistogram</artifactId>
|
||||
<groupId>org.hdrhistogram</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>javassist</artifactId>
|
||||
<groupId>org.javassist</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>simpleclient</artifactId>
|
||||
<groupId>io.prometheus</groupId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<artifactId>fastjson</artifactId>
|
||||
<groupId>com.alibaba</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.hdrhistogram</groupId>
|
||||
<artifactId>HdrHistogram</artifactId>
|
||||
<version>2.1.12</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-metrics</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-redis</artifactId>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>javassist</artifactId>
|
||||
<groupId>org.javassist</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-swagger</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-security</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security.oauth</groupId>
|
||||
<artifactId>spring-security-oauth2</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-redis</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-jwt</artifactId>
|
||||
</dependency>
|
||||
<!-- 验证码 -->
|
||||
<dependency>
|
||||
<groupId>com.github.whvcse</groupId>
|
||||
<artifactId>easy-captcha</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-core-boot</artifactId>
|
||||
</dependency>
|
||||
<!-- 链路追踪、服务监控 -->
|
||||
<!--<dependency>
|
||||
<groupId>org.springblade</groupId>
|
||||
<artifactId>blade-starter-trace</artifactId>
|
||||
</dependency>-->
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>com.spotify</groupId>
|
||||
<artifactId>dockerfile-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>${dockerfile.skip}</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
|
@ -0,0 +1,24 @@
|
|||
package org.springblade.auth;
|
||||
|
||||
|
||||
import org.springblade.common.constant.CommonConstant;
|
||||
import org.springblade.core.cloud.feign.EnableBladeFeign;
|
||||
import org.springblade.core.launch.BladeApplication;
|
||||
import org.springframework.cloud.client.SpringCloudApplication;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
|
||||
/**
|
||||
* 用户认证服务器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@EnableBladeFeign
|
||||
@SpringCloudApplication
|
||||
@ComponentScan({"org.springblade.auth"})
|
||||
public class SystemManagerApplication {
|
||||
|
||||
public static void main(String[] args) {
|
||||
BladeApplication.run(CommonConstant.KN_SYSTEM_MANAGER_MODULE_NAME, SystemManagerApplication.class, args);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
package org.springblade.auth.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springblade.auth.granter.BladeTokenGranter;
|
||||
import org.springblade.auth.service.BladeClientDetailsServiceImpl;
|
||||
import org.springblade.core.redis.cache.BladeRedis;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.core.annotation.Order;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
|
||||
import org.springframework.security.oauth2.provider.TokenGranter;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancerChain;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 认证服务器配置
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Order
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@EnableAuthorizationServer
|
||||
public class BladeAuthorizationServerConfiguration extends AuthorizationServerConfigurerAdapter {
|
||||
|
||||
private final DataSource dataSource;
|
||||
|
||||
private final AuthenticationManager authenticationManager;
|
||||
|
||||
private final UserDetailsService userDetailsService;
|
||||
|
||||
private final TokenStore tokenStore;
|
||||
|
||||
private final TokenEnhancer jwtTokenEnhancer;
|
||||
|
||||
private final JwtAccessTokenConverter jwtAccessTokenConverter;
|
||||
|
||||
private final BladeRedis bladeRedis;
|
||||
|
||||
@Override
|
||||
public void configure(AuthorizationServerEndpointsConfigurer endpoints) {
|
||||
//获取自定义tokenGranter
|
||||
TokenGranter tokenGranter = BladeTokenGranter.getTokenGranter(authenticationManager, endpoints, bladeRedis);
|
||||
|
||||
//配置端点
|
||||
endpoints.tokenStore(tokenStore)
|
||||
.authenticationManager(authenticationManager)
|
||||
.userDetailsService(userDetailsService)
|
||||
.tokenGranter(tokenGranter);
|
||||
|
||||
//扩展token返回结果
|
||||
if (jwtAccessTokenConverter != null && jwtTokenEnhancer != null) {
|
||||
TokenEnhancerChain tokenEnhancerChain = new TokenEnhancerChain();
|
||||
List<TokenEnhancer> enhancerList = new ArrayList<>();
|
||||
enhancerList.add(jwtTokenEnhancer);
|
||||
enhancerList.add(jwtAccessTokenConverter);
|
||||
tokenEnhancerChain.setTokenEnhancers(enhancerList);
|
||||
//jwt增强
|
||||
endpoints.tokenEnhancer(tokenEnhancerChain).accessTokenConverter(jwtAccessTokenConverter);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置客户端信息
|
||||
*/
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void configure(ClientDetailsServiceConfigurer clients) {
|
||||
clients.withClientDetails(new BladeClientDetailsServiceImpl(dataSource));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configure(AuthorizationServerSecurityConfigurer oauthServer) {
|
||||
oauthServer
|
||||
.allowFormAuthenticationForClients()
|
||||
.tokenKeyAccess("permitAll()")
|
||||
.checkTokenAccess("isAuthenticated()");
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
|
||||
|
||||
/**
|
||||
* 自定义登录成功配置
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
@EnableResourceServer
|
||||
public class BladeResourceServerConfiguration extends ResourceServerConfigurerAdapter {
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public void configure(HttpSecurity http) {
|
||||
http.headers().frameOptions().disable();
|
||||
http.formLogin()
|
||||
.and()
|
||||
.authorizeRequests()
|
||||
.antMatchers(
|
||||
"/actuator/**",
|
||||
"/oauth/captcha",
|
||||
"/oauth/logout",
|
||||
"/oauth/mobile",
|
||||
"/oauth/clear-cache",
|
||||
"/oauth/render/**",
|
||||
"/oauth/callback/**",
|
||||
"/oauth/revoke/**",
|
||||
"/oauth/refresh/**",
|
||||
"/token/**",
|
||||
"/user/**",
|
||||
"/role/**",
|
||||
"/menu/**",
|
||||
"/dict-biz/**",
|
||||
"/v2/api-docs").permitAll()
|
||||
.anyRequest().authenticated().and()
|
||||
.csrf().disable();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.config;
|
||||
|
||||
import org.springblade.auth.support.BladeJwtTokenEnhancer;
|
||||
import org.springblade.core.jwt.props.JwtProperties;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
|
||||
import org.springframework.security.oauth2.provider.token.TokenStore;
|
||||
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
|
||||
import org.springframework.security.oauth2.provider.token.store.JwtTokenStore;
|
||||
|
||||
/**
|
||||
* JwtTokenStore
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnProperty(prefix = "blade.security.oauth2", name = "storeType", havingValue = "jwt", matchIfMissing = true)
|
||||
public class JwtTokenStoreConfiguration {
|
||||
|
||||
/**
|
||||
* 使用jwtTokenStore存储token
|
||||
*/
|
||||
@Bean
|
||||
public TokenStore jwtTokenStore(JwtProperties jwtProperties) {
|
||||
return new JwtTokenStore(jwtAccessTokenConverter(jwtProperties));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于生成jwt
|
||||
*/
|
||||
@Bean
|
||||
public JwtAccessTokenConverter jwtAccessTokenConverter(JwtProperties jwtProperties) {
|
||||
JwtAccessTokenConverter accessTokenConverter = new JwtAccessTokenConverter();
|
||||
accessTokenConverter.setSigningKey(jwtProperties.getSignKey());
|
||||
return accessTokenConverter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 用于扩展jwt
|
||||
*/
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(name = "jwtTokenEnhancer")
|
||||
public TokenEnhancer jwtTokenEnhancer(JwtAccessTokenConverter jwtAccessTokenConverter, JwtProperties jwtProperties) {
|
||||
return new BladeJwtTokenEnhancer(jwtAccessTokenConverter, jwtProperties);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.config;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springblade.auth.support.BladePasswordEncoderFactories;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
/**
|
||||
* Security配置
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Configuration
|
||||
@AllArgsConstructor
|
||||
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
|
||||
|
||||
@Bean
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public AuthenticationManager authenticationManagerBean() {
|
||||
return super.authenticationManagerBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return BladePasswordEncoderFactories.createDelegatingPasswordEncoder();
|
||||
}
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
protected void configure(HttpSecurity http) {
|
||||
http.httpBasic().and().csrf().disable().authorizeRequests().anyRequest().fullyAuthenticated();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.constant;
|
||||
|
||||
/**
|
||||
* 授权校验常量
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface AuthConstant {
|
||||
|
||||
/**
|
||||
* 密码加密规则
|
||||
*/
|
||||
String ENCRYPT = "{blade}";
|
||||
|
||||
/**
|
||||
* blade_client表字段
|
||||
*/
|
||||
String CLIENT_FIELDS = "client_id, CONCAT('{noop}',client_secret) as client_secret, resource_ids, scope, authorized_grant_types, " +
|
||||
"web_server_redirect_uri, authorities, access_token_validity, " +
|
||||
"refresh_token_validity, additional_information, autoapprove";
|
||||
|
||||
/**
|
||||
* blade_client查询语句
|
||||
*/
|
||||
String BASE_STATEMENT = "select " + CLIENT_FIELDS + " from blade_client";
|
||||
|
||||
/**
|
||||
* blade_client查询排序
|
||||
*/
|
||||
String DEFAULT_FIND_STATEMENT = BASE_STATEMENT + " order by client_id";
|
||||
|
||||
/**
|
||||
* 查询client_id
|
||||
*/
|
||||
String DEFAULT_SELECT_STATEMENT = BASE_STATEMENT + " where client_id = ?";
|
||||
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package org.springblade.auth.endpoint;
|
||||
|
||||
import com.wf.captcha.SpecCaptcha;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springblade.common.cache.CacheNames;
|
||||
import org.springblade.core.cache.utils.CacheUtil;
|
||||
import org.springblade.core.jwt.JwtUtil;
|
||||
import org.springblade.core.jwt.props.JwtProperties;
|
||||
import org.springblade.core.launch.constant.TokenConstant;
|
||||
import org.springblade.core.redis.cache.BladeRedis;
|
||||
import org.springblade.core.secure.BladeUser;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tenant.annotation.NonDS;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.support.Kv;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.core.tool.utils.WebUtil;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.time.Duration;
|
||||
|
||||
import static org.springblade.core.cache.constant.CacheConstant.*;
|
||||
|
||||
/**
|
||||
* BladeEndPoint
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@NonDS
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
public class BladeTokenEndPoint {
|
||||
|
||||
private final BladeRedis bladeRedis;
|
||||
private final JwtProperties jwtProperties;
|
||||
@Value("${captcha.image.width:130}")
|
||||
private Integer imageWidth;
|
||||
@Value("${captcha.image.height:48}")
|
||||
private Integer imageHeight;
|
||||
@Value("${captcha.image.code.length:5}")
|
||||
private Integer codeLength;
|
||||
@Value("${captcha.image.code.time:30}")
|
||||
private Integer codeValidateTime;
|
||||
|
||||
@GetMapping("/oauth/user-info")
|
||||
public R<Authentication> currentUser(Authentication authentication) {
|
||||
return R.data(authentication);
|
||||
}
|
||||
|
||||
@GetMapping("/oauth/captcha")
|
||||
public Kv captcha() {
|
||||
SpecCaptcha specCaptcha = new SpecCaptcha(imageWidth, imageHeight, codeLength);
|
||||
String verCode = specCaptcha.text().toLowerCase();
|
||||
String key = StringUtil.randomUUID();
|
||||
// 存入redis并设置过期时间为30分钟
|
||||
bladeRedis.setEx(CacheNames.CAPTCHA_KEY + key, verCode, Duration.ofMinutes(codeValidateTime));
|
||||
// 将key和base64返回给前端
|
||||
return Kv.create().set("key", key).set("image", specCaptcha.toBase64());
|
||||
}
|
||||
|
||||
@GetMapping("/oauth/logout")
|
||||
public Kv logout() {
|
||||
BladeUser user = AuthUtil.getUser();
|
||||
if (user != null && jwtProperties.getState()) {
|
||||
String token = JwtUtil.getToken(WebUtil.getRequest().getHeader(TokenConstant.HEADER));
|
||||
JwtUtil.removeAccessToken(user.getTenantId(), String.valueOf(user.getUserId()), token);
|
||||
}
|
||||
return Kv.create().set("success", "true").set("msg", "success");
|
||||
}
|
||||
|
||||
@GetMapping("/oauth/clear-cache")
|
||||
public Kv clearCache() {
|
||||
CacheUtil.clear(BIZ_CACHE);
|
||||
CacheUtil.clear(USER_CACHE);
|
||||
CacheUtil.clear(DICT_CACHE);
|
||||
CacheUtil.clear(FLOW_CACHE);
|
||||
CacheUtil.clear(SYS_CACHE);
|
||||
CacheUtil.clear(PARAM_CACHE);
|
||||
CacheUtil.clear(RESOURCE_CACHE);
|
||||
CacheUtil.clear(MENU_CACHE);
|
||||
CacheUtil.clear(DICT_CACHE, Boolean.FALSE);
|
||||
CacheUtil.clear(MENU_CACHE, Boolean.FALSE);
|
||||
CacheUtil.clear(SYS_CACHE, Boolean.FALSE);
|
||||
CacheUtil.clear(PARAM_CACHE, Boolean.FALSE);
|
||||
return Kv.create().set("success", "true").set("msg", "success");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package org.springblade.auth.granter;
|
||||
|
||||
import org.springblade.core.redis.cache.BladeRedis;
|
||||
import org.springframework.security.authentication.AuthenticationManager;
|
||||
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
|
||||
import org.springframework.security.oauth2.provider.CompositeTokenGranter;
|
||||
import org.springframework.security.oauth2.provider.TokenGranter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 自定义拓展TokenGranter
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class BladeTokenGranter {
|
||||
|
||||
/**
|
||||
* 自定义tokenGranter
|
||||
*/
|
||||
public static TokenGranter getTokenGranter(final AuthenticationManager authenticationManager,
|
||||
final AuthorizationServerEndpointsConfigurer endpoints,
|
||||
BladeRedis bladeRedis) {
|
||||
// 默认tokenGranter集合
|
||||
List<TokenGranter> granters = new ArrayList<>(Collections.singletonList(endpoints.getTokenGranter()));
|
||||
// 增加验证码模式
|
||||
granters.add(new CaptchaTokenGranter(authenticationManager, endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), bladeRedis));
|
||||
return new CompositeTokenGranter(granters);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package org.springblade.auth.granter;
|
||||
|
||||
import org.springblade.auth.utils.TokenUtil;
|
||||
import org.springblade.common.cache.CacheNames;
|
||||
import org.springblade.core.redis.cache.BladeRedis;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.core.tool.utils.WebUtil;
|
||||
import org.springframework.security.authentication.*;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.oauth2.common.exceptions.InvalidGrantException;
|
||||
import org.springframework.security.oauth2.common.exceptions.UserDeniedAuthorizationException;
|
||||
import org.springframework.security.oauth2.provider.*;
|
||||
import org.springframework.security.oauth2.provider.token.AbstractTokenGranter;
|
||||
import org.springframework.security.oauth2.provider.token.AuthorizationServerTokenServices;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 验证码TokenGranter
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class CaptchaTokenGranter extends AbstractTokenGranter {
|
||||
|
||||
private static final String GRANT_TYPE = "captcha";
|
||||
|
||||
private final AuthenticationManager authenticationManager;
|
||||
|
||||
private BladeRedis bladeRedis;
|
||||
|
||||
public CaptchaTokenGranter(AuthenticationManager authenticationManager,
|
||||
AuthorizationServerTokenServices tokenServices, ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, BladeRedis bladeRedis) {
|
||||
this(authenticationManager, tokenServices, clientDetailsService, requestFactory, GRANT_TYPE);
|
||||
this.bladeRedis = bladeRedis;
|
||||
}
|
||||
|
||||
protected CaptchaTokenGranter(AuthenticationManager authenticationManager, AuthorizationServerTokenServices tokenServices,
|
||||
ClientDetailsService clientDetailsService, OAuth2RequestFactory requestFactory, String grantType) {
|
||||
super(tokenServices, clientDetailsService, requestFactory, grantType);
|
||||
this.authenticationManager = authenticationManager;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OAuth2Authentication getOAuth2Authentication(ClientDetails client, TokenRequest tokenRequest) {
|
||||
HttpServletRequest request = WebUtil.getRequest();
|
||||
// 增加验证码判断
|
||||
String key = request.getHeader(TokenUtil.CAPTCHA_HEADER_KEY);
|
||||
String code = request.getHeader(TokenUtil.CAPTCHA_HEADER_CODE);
|
||||
// 获取验证码
|
||||
String redisCode = bladeRedis.get(CacheNames.CAPTCHA_KEY + key);
|
||||
// 判断验证码
|
||||
if (code == null || !StringUtil.equalsIgnoreCase(redisCode, code)) {
|
||||
throw new UserDeniedAuthorizationException(TokenUtil.CAPTCHA_NOT_CORRECT);
|
||||
}
|
||||
|
||||
Map<String, String> parameters = new LinkedHashMap<>(tokenRequest.getRequestParameters());
|
||||
String username = parameters.get("username");
|
||||
String password = parameters.get("password");
|
||||
// Protect from downstream leaks of password
|
||||
parameters.remove("password");
|
||||
|
||||
Authentication userAuth = new UsernamePasswordAuthenticationToken(username, password);
|
||||
((AbstractAuthenticationToken) userAuth).setDetails(parameters);
|
||||
try {
|
||||
userAuth = authenticationManager.authenticate(userAuth);
|
||||
}
|
||||
catch (AccountStatusException | BadCredentialsException ase) {
|
||||
//covers expired, locked, disabled cases (mentioned in section 5.2, draft 31)
|
||||
throw new InvalidGrantException(ase.getMessage());
|
||||
}
|
||||
// If the username/password are wrong the spec says we should send 400/invalid grant
|
||||
|
||||
if (userAuth == null || !userAuth.isAuthenticated()) {
|
||||
throw new InvalidGrantException("Could not authenticate user: " + username);
|
||||
}
|
||||
|
||||
OAuth2Request storedOAuth2Request = getRequestFactory().createOAuth2Request(client, tokenRequest);
|
||||
return new OAuth2Authentication(storedOAuth2Request, userAuth);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.service;
|
||||
|
||||
import org.springblade.auth.constant.AuthConstant;
|
||||
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||
import org.springframework.security.oauth2.provider.client.JdbcClientDetailsService;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
/**
|
||||
* 客户端信息
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Component
|
||||
public class BladeClientDetailsServiceImpl extends JdbcClientDetailsService {
|
||||
|
||||
public BladeClientDetailsServiceImpl(DataSource dataSource) {
|
||||
super(dataSource);
|
||||
setSelectClientDetailsSql(AuthConstant.DEFAULT_SELECT_STATEMENT);
|
||||
setFindClientDetailsSql(AuthConstant.DEFAULT_FIND_STATEMENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 缓存客户端信息
|
||||
*
|
||||
* @param clientId 客户端id
|
||||
*/
|
||||
@Override
|
||||
public ClientDetails loadClientByClientId(String clientId) {
|
||||
try {
|
||||
return super.loadClientByClientId(clientId);
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package org.springblade.auth.service;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.springblade.core.tool.support.Kv;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.User;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* 用户信息拓展
|
||||
*
|
||||
* @author whq
|
||||
*/
|
||||
@Getter
|
||||
public class BladeUserDetails extends User {
|
||||
|
||||
/**
|
||||
* 用户id
|
||||
*/
|
||||
private final Long userId;
|
||||
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private final String email;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
private final String tenantId;
|
||||
|
||||
/**
|
||||
* 第三方认证ID
|
||||
*/
|
||||
private final String oauthId;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* 真名
|
||||
*/
|
||||
private final String realName;
|
||||
/**
|
||||
* 账号
|
||||
*/
|
||||
private final String account;
|
||||
/**
|
||||
* 角色id
|
||||
*/
|
||||
private final String roleId;
|
||||
/**
|
||||
* 角色名
|
||||
*/
|
||||
private final String roleName;
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private final String avatar;
|
||||
/**
|
||||
* 用户详情
|
||||
*/
|
||||
private final Kv detail;
|
||||
|
||||
public BladeUserDetails(Long userId, String email,
|
||||
String tenantId, String oauthId, String name,
|
||||
String realName, String roleId,
|
||||
String roleName, String avatar, String username, String password, Kv detail,
|
||||
boolean enabled, boolean accountNonExpired, boolean credentialsNonExpired,
|
||||
boolean accountNonLocked, Collection<? extends GrantedAuthority> authorities) {
|
||||
super(username, password, enabled, accountNonExpired, credentialsNonExpired, accountNonLocked, authorities);
|
||||
this.userId = userId;
|
||||
this.email = email;
|
||||
this.tenantId = tenantId;
|
||||
this.oauthId = oauthId;
|
||||
this.name = name;
|
||||
this.realName = realName;
|
||||
this.account = username;
|
||||
this.roleId = roleId;
|
||||
this.roleName = roleName;
|
||||
this.avatar = avatar;
|
||||
this.detail = detail;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
package org.springblade.auth.service;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import org.apache.commons.lang.StringUtils;
|
||||
import org.springblade.auth.constant.AuthConstant;
|
||||
import org.springblade.auth.system.cache.SysCache;
|
||||
import org.springblade.auth.system.cache.UserCache;
|
||||
import org.springblade.auth.system.entity.User;
|
||||
import org.springblade.auth.system.entity.UserInfo;
|
||||
import org.springblade.auth.utils.TokenUtil;
|
||||
import org.springblade.common.cache.CacheNames;
|
||||
import org.springblade.core.redis.cache.BladeRedis;
|
||||
import org.springblade.core.tool.utils.DigestUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.core.tool.utils.StringPool;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springblade.core.tool.utils.WebUtil;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.security.oauth2.common.exceptions.UserDeniedAuthorizationException;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*
|
||||
* @author whq
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class BladeUserDetailsServiceImpl implements UserDetailsService {
|
||||
|
||||
public static final Integer FAIL_COUNT = 5;
|
||||
|
||||
private final BladeRedis bladeRedis;
|
||||
|
||||
@Override
|
||||
@SneakyThrows
|
||||
public BladeUserDetails loadUserByUsername(String username) {
|
||||
HttpServletRequest request = WebUtil.getRequest();
|
||||
// 获取用户绑定ID
|
||||
//String headerDept = request.getHeader(TokenUtil.DEPT_HEADER_KEY);
|
||||
String headerRole = request.getHeader(TokenUtil.ROLE_HEADER_KEY);
|
||||
// 获取租户ID
|
||||
String headerTenant = request.getHeader(TokenUtil.TENANT_HEADER_KEY);
|
||||
String paramTenant = request.getParameter(TokenUtil.TENANT_PARAM_KEY);
|
||||
String password = request.getParameter(TokenUtil.PASSWORD_KEY);
|
||||
String grantType = request.getParameter(TokenUtil.GRANT_TYPE_KEY);
|
||||
if (StringUtil.isAllBlank(headerTenant, paramTenant)) {
|
||||
throw new UserDeniedAuthorizationException(TokenUtil.TENANT_NOT_FOUND);
|
||||
}
|
||||
String tenantId = StringUtils.isBlank(headerTenant) ? paramTenant : headerTenant;
|
||||
|
||||
// 判断登录是否锁定
|
||||
// 新版本将增加:1.参数管理读取配置 2.用户管理增加解封按钮
|
||||
int count = getFailCount(tenantId, username);
|
||||
if (count >= FAIL_COUNT) {
|
||||
throw new UserDeniedAuthorizationException(TokenUtil.USER_HAS_TOO_MANY_FAILS);
|
||||
}
|
||||
|
||||
// 获取用户类型
|
||||
//String userType = Func.toStr(request.getHeader(TokenUtil.USER_TYPE_HEADER_KEY), TokenUtil.DEFAULT_USER_TYPE);
|
||||
|
||||
// 远程调用返回数据
|
||||
UserInfo userInfo = UserCache.getUser(tenantId, username);
|
||||
User user = userInfo.getUser();
|
||||
// 判断返回信息
|
||||
// 用户不存在,但提示用户名与密码错误并锁定账号
|
||||
if (user == null || user.getId() == null) {
|
||||
setFailCount(tenantId, username, count);
|
||||
throw new UsernameNotFoundException(TokenUtil.USER_NOT_FOUND);
|
||||
}
|
||||
// 用户存在但密码错误,超过次数则锁定账号
|
||||
if (!grantType.equals(TokenUtil.REFRESH_TOKEN_KEY) && !user.getPassword().equals(DigestUtil.hex(password))) {
|
||||
setFailCount(tenantId, username, count);
|
||||
throw new UsernameNotFoundException(TokenUtil.USER_NOT_FOUND);
|
||||
}
|
||||
// 用户角色不存在
|
||||
if (Func.isEmpty(userInfo.getRoles())) {
|
||||
throw new UserDeniedAuthorizationException(TokenUtil.USER_HAS_NO_ROLE);
|
||||
}
|
||||
// 多角色情况下指定单角色
|
||||
if (Func.isNotEmpty(headerRole) && user.getRoleId().contains(headerRole)) {
|
||||
List<String> roleResult = SysCache.getRoleAliases(headerRole);
|
||||
userInfo.setRoles(roleResult);
|
||||
user.setRoleId(headerRole);
|
||||
}
|
||||
return new BladeUserDetails(user.getId(), user.getEmail(),
|
||||
user.getTenantId(), StringPool.EMPTY, user.getName(), user.getRealName(), user.getRoleId(), Func.join(userInfo.getRoles()), Func.toStr(user.getAvatar(), TokenUtil.DEFAULT_AVATAR),
|
||||
username, AuthConstant.ENCRYPT + user.getPassword(), userInfo.getDetail(), true, true, true, true,
|
||||
AuthorityUtils.commaSeparatedStringToAuthorityList(Func.join(userInfo.getRoles())));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取账号错误次数
|
||||
*
|
||||
* @param tenantId 租户id
|
||||
* @param username 账号
|
||||
* @return int
|
||||
*/
|
||||
private int getFailCount(String tenantId, String username) {
|
||||
return Func.toInt(bladeRedis.get(CacheNames.tenantKey(tenantId, CacheNames.USER_FAIL_KEY, username)), 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置账号错误次数
|
||||
*
|
||||
* @param tenantId 租户id
|
||||
* @param username 账号
|
||||
* @param count 次数
|
||||
*/
|
||||
private void setFailCount(String tenantId, String username, int count) {
|
||||
bladeRedis.setEx(CacheNames.tenantKey(tenantId, CacheNames.USER_FAIL_KEY, username), count + 1, Duration.ofMinutes(30));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package org.springblade.auth.support;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springblade.auth.service.BladeUserDetails;
|
||||
import org.springblade.auth.utils.TokenUtil;
|
||||
import org.springblade.core.jwt.JwtUtil;
|
||||
import org.springblade.core.jwt.props.JwtProperties;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||
import org.springframework.security.oauth2.provider.OAuth2Authentication;
|
||||
import org.springframework.security.oauth2.provider.token.TokenEnhancer;
|
||||
import org.springframework.security.oauth2.provider.token.store.JwtAccessTokenConverter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* jwt返回参数增强
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
public class BladeJwtTokenEnhancer implements TokenEnhancer {
|
||||
|
||||
private final JwtAccessTokenConverter jwtAccessTokenConverter;
|
||||
private final JwtProperties jwtProperties;
|
||||
|
||||
@Override
|
||||
public OAuth2AccessToken enhance(OAuth2AccessToken accessToken, OAuth2Authentication authentication) {
|
||||
BladeUserDetails principal = (BladeUserDetails) authentication.getUserAuthentication().getPrincipal();
|
||||
//token参数增强
|
||||
Map<String, Object> info = new HashMap<>(16);
|
||||
info.put(TokenUtil.CLIENT_ID, TokenUtil.getClientIdFromHeader());
|
||||
info.put(TokenUtil.USER_ID, Func.toStr(principal.getUserId()));
|
||||
// info.put(TokenUtil.DEPT_ID, Func.toStr(principal.getDeptId()));
|
||||
//info.put(TokenUtil.POST_ID, Func.toStr(principal.getPostId()));
|
||||
info.put(TokenUtil.ROLE_ID, Func.toStr(principal.getRoleId()));
|
||||
info.put(TokenUtil.TENANT_ID, principal.getTenantId());
|
||||
info.put(TokenUtil.EMAIL, principal.getEmail());
|
||||
//info.put(TokenUtil.OAUTH_ID, principal.getOauthId());
|
||||
info.put(TokenUtil.ACCOUNT, principal.getAccount());
|
||||
info.put(TokenUtil.USER_NAME, principal.getUsername());
|
||||
info.put(TokenUtil.NICK_NAME, principal.getName());
|
||||
info.put(TokenUtil.REAL_NAME, principal.getRealName());
|
||||
info.put(TokenUtil.ROLE_NAME, principal.getRoleName());
|
||||
info.put(TokenUtil.AVATAR, principal.getAvatar());
|
||||
info.put(TokenUtil.DETAIL, principal.getDetail());
|
||||
((DefaultOAuth2AccessToken) accessToken).setAdditionalInformation(info);
|
||||
//token状态设置, 有状态,默认无状态
|
||||
if (jwtProperties.getState()) {
|
||||
OAuth2AccessToken oAuth2AccessToken = jwtAccessTokenConverter.enhance(accessToken, authentication);
|
||||
String tokenValue = oAuth2AccessToken.getValue();
|
||||
String tenantId = principal.getTenantId();
|
||||
String userId = Func.toStr(principal.getUserId());
|
||||
JwtUtil.addAccessToken(tenantId, userId, tokenValue, accessToken.getExpiresIn());
|
||||
}
|
||||
return accessToken;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.support;
|
||||
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
/**
|
||||
* 无密码加密
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class BladeNoOpPasswordEncoder implements PasswordEncoder {
|
||||
|
||||
@Override
|
||||
public String encode(CharSequence rawPassword) {
|
||||
return rawPassword.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(CharSequence rawPassword, String encodedPassword) {
|
||||
return rawPassword.toString().equals(encodedPassword);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the singleton {@link BladeNoOpPasswordEncoder}.
|
||||
*/
|
||||
public static PasswordEncoder getInstance() {
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private static final PasswordEncoder INSTANCE = new BladeNoOpPasswordEncoder();
|
||||
|
||||
private BladeNoOpPasswordEncoder() {
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.support;
|
||||
|
||||
import org.springblade.core.tool.utils.DigestUtil;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
/**
|
||||
* 自定义密码加密
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class BladePasswordEncoder implements PasswordEncoder {
|
||||
|
||||
@Override
|
||||
public String encode(CharSequence rawPassword) {
|
||||
return DigestUtil.hex((String) rawPassword);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(CharSequence rawPassword, String encodedPassword) {
|
||||
return encodedPassword.equals(encode(rawPassword));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright 2002-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.springblade.auth.support;
|
||||
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.DelegatingPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.security.crypto.password.Pbkdf2PasswordEncoder;
|
||||
import org.springframework.security.crypto.scrypt.SCryptPasswordEncoder;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 自定义密码工厂
|
||||
*
|
||||
* @author Rob Winch, Chill
|
||||
* @since 5.0
|
||||
*/
|
||||
public class BladePasswordEncoderFactories {
|
||||
|
||||
/**
|
||||
* Creates a {@link DelegatingPasswordEncoder} with default mappings. Additional
|
||||
* mappings may be added and the encoding will be updated to conform with best
|
||||
* practices. However, due to the nature of {@link DelegatingPasswordEncoder} the
|
||||
* updates should not impact users. The mappings current are:
|
||||
*
|
||||
* <ul>
|
||||
* <li>blade - {@link BladePasswordEncoder} (sha1(md5("password")))</li>
|
||||
* <li>bcrypt - {@link BCryptPasswordEncoder} (Also used for encoding)</li>
|
||||
* <li>noop - {@link BladeNoOpPasswordEncoder}</li>
|
||||
* <li>pbkdf2 - {@link Pbkdf2PasswordEncoder}</li>
|
||||
* <li>scrypt - {@link SCryptPasswordEncoder}</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return the {@link PasswordEncoder} to use
|
||||
*/
|
||||
public static PasswordEncoder createDelegatingPasswordEncoder() {
|
||||
String encodingId = "blade";
|
||||
Map<String, PasswordEncoder> encoders = new HashMap<>(16);
|
||||
encoders.put(encodingId, new BladePasswordEncoder());
|
||||
encoders.put("bcrypt", new BCryptPasswordEncoder());
|
||||
encoders.put("noop", BladeNoOpPasswordEncoder.getInstance());
|
||||
encoders.put("pbkdf2", new Pbkdf2PasswordEncoder());
|
||||
encoders.put("scrypt", new SCryptPasswordEncoder());
|
||||
|
||||
return new DelegatingPasswordEncoder(encodingId, encoders);
|
||||
}
|
||||
|
||||
private BladePasswordEncoderFactories() {
|
||||
}
|
||||
|
||||
}
|
89
kn-sys-manager/src/main/java/org/springblade/auth/system/cache/DictBizCache.java
vendored
Normal file
89
kn-sys-manager/src/main/java/org/springblade/auth/system/cache/DictBizCache.java
vendored
Normal file
|
@ -0,0 +1,89 @@
|
|||
package org.springblade.auth.system.cache;
|
||||
|
||||
import org.springblade.auth.system.service.IDictBizService;
|
||||
import org.springblade.core.cache.utils.CacheUtil;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tool.utils.SpringUtil;
|
||||
import org.springblade.core.tool.utils.StringPool;
|
||||
import org.springblade.auth.system.entity.DictBiz;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.springblade.core.cache.constant.CacheConstant.DICT_CACHE;
|
||||
|
||||
/**
|
||||
* 业务字典缓存工具类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class DictBizCache {
|
||||
|
||||
private static final String DICT_ID = "dictBiz:id";
|
||||
private static final String DICT_VALUE = "dictBiz:value";
|
||||
private static final String DICT_LIST = "dictBiz:list";
|
||||
|
||||
private static IDictBizService dictClient;
|
||||
|
||||
private static IDictBizService getDictClient() {
|
||||
if (dictClient == null) {
|
||||
dictClient = SpringUtil.getBean(IDictBizService.class);
|
||||
}
|
||||
return dictClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典实体
|
||||
*
|
||||
* @param id 主键
|
||||
* @return DictBiz
|
||||
*/
|
||||
public static DictBiz getById(Long id) {
|
||||
String keyPrefix = DICT_ID.concat(StringPool.DASH).concat(AuthUtil.getTenantId()).concat(StringPool.COLON);
|
||||
return CacheUtil.get(DICT_CACHE, keyPrefix, id, () -> {
|
||||
return getDictClient().getById(id);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取字典值
|
||||
*
|
||||
* @param code 字典编号
|
||||
* @param dictKey Integer型字典键
|
||||
* @return String
|
||||
*/
|
||||
public static String getValue(String code, Integer dictKey) {
|
||||
String keyPrefix = DICT_VALUE.concat(StringPool.DASH).concat(AuthUtil.getTenantId()).concat(StringPool.COLON);
|
||||
return CacheUtil.get(DICT_CACHE, keyPrefix + code + StringPool.COLON, String.valueOf(dictKey), () -> {
|
||||
return getDictClient().getValue(code, String.valueOf(dictKey));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典值
|
||||
*
|
||||
* @param code 字典编号
|
||||
* @param dictKey String型字典键
|
||||
* @return String
|
||||
*/
|
||||
public static String getValue(String code, String dictKey) {
|
||||
String keyPrefix = DICT_VALUE.concat(StringPool.DASH).concat(AuthUtil.getTenantId()).concat(StringPool.COLON);
|
||||
return CacheUtil.get(DICT_CACHE, keyPrefix + code + StringPool.COLON, dictKey, () -> {
|
||||
return getDictClient().getValue(code, dictKey);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典集合
|
||||
*
|
||||
* @param code 字典编号
|
||||
* @return List<DictBiz>
|
||||
*/
|
||||
public static List<DictBiz> getList(String code) {
|
||||
String keyPrefix = DICT_LIST.concat(StringPool.DASH).concat(AuthUtil.getTenantId()).concat(StringPool.COLON);
|
||||
return CacheUtil.get(DICT_CACHE, keyPrefix, code, () -> {
|
||||
return getDictClient().getList(code);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
116
kn-sys-manager/src/main/java/org/springblade/auth/system/cache/SysCache.java
vendored
Normal file
116
kn-sys-manager/src/main/java/org/springblade/auth/system/cache/SysCache.java
vendored
Normal file
|
@ -0,0 +1,116 @@
|
|||
package org.springblade.auth.system.cache;
|
||||
|
||||
import org.springblade.auth.system.entity.Menu;
|
||||
import org.springblade.auth.system.entity.Role;
|
||||
import org.springblade.auth.system.service.IMenuService;
|
||||
import org.springblade.auth.system.service.IRoleService;
|
||||
import org.springblade.core.cache.utils.CacheUtil;
|
||||
import org.springblade.core.tool.utils.SpringUtil;
|
||||
import org.springblade.core.tool.utils.StringPool;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE;
|
||||
|
||||
/**
|
||||
* 系统缓存
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class SysCache {
|
||||
private static final String MENU_ID = "menu:id:";
|
||||
private static final String ROLE_ID = "role:id:";
|
||||
private static final String ROLE_NAME = "role:name:";
|
||||
private static final String ROLE_NAME_ID = "roleName:id:";
|
||||
private static final String ROLE_NAMES_ID = "roleNames:id:";
|
||||
private static final String ROLE_ALIAS_ID = "roleAlias:id:";
|
||||
private static final String ROLE_ALIASES_ID = "roleAliases:id:";
|
||||
|
||||
private static IMenuService menuService;
|
||||
private static IRoleService roleService;
|
||||
|
||||
private static IMenuService getSysClient() {
|
||||
if (menuService == null) {
|
||||
menuService = SpringUtil.getBean(IMenuService.class);
|
||||
}
|
||||
return menuService;
|
||||
}
|
||||
|
||||
private static IRoleService getRoleClient() {
|
||||
if (roleService == null) {
|
||||
roleService = SpringUtil.getBean(IRoleService.class);
|
||||
}
|
||||
return roleService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 菜单
|
||||
*/
|
||||
public static Menu getMenu(Long id) {
|
||||
return CacheUtil.get(SYS_CACHE, MENU_ID, id, () -> getSysClient().getById(id));
|
||||
}
|
||||
/**
|
||||
* 获取角色
|
||||
*
|
||||
* @param id 主键
|
||||
* @return Role
|
||||
*/
|
||||
public static Role getRole(Long id) {
|
||||
return CacheUtil.get(SYS_CACHE, ROLE_ID, id, () -> getRoleClient().getById(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色id
|
||||
*
|
||||
* @param tenantId 租户id
|
||||
* @param roleNames 角色名
|
||||
* @return
|
||||
*/
|
||||
public static String getRoleIds(String tenantId, String roleNames) {
|
||||
return CacheUtil.get(SYS_CACHE, ROLE_NAME, tenantId + StringPool.DASH + roleNames, () -> getRoleClient().getRoleIds(tenantId, roleNames));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色名
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 角色名
|
||||
*/
|
||||
public static String getRoleName(Long id) {
|
||||
return CacheUtil.get(SYS_CACHE, ROLE_NAME_ID, id, () -> getRoleClient().getById(id).getRoleName());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色别名
|
||||
*
|
||||
* @param id 主键
|
||||
* @return 角色别名
|
||||
*/
|
||||
public static String getRoleAlias(Long id) {
|
||||
return CacheUtil.get(SYS_CACHE, ROLE_ALIAS_ID, id, () -> getRoleClient().getById(id).getRoleAlias());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色名集合
|
||||
*
|
||||
* @param roleIds 主键集合
|
||||
* @return 角色名
|
||||
*/
|
||||
public static List<String> getRoleNames(String roleIds) {
|
||||
return CacheUtil.get(SYS_CACHE, ROLE_NAMES_ID, roleIds, () -> getRoleClient().getRoleNames(roleIds));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色别名集合
|
||||
*
|
||||
* @param roleIds 主键集合
|
||||
* @return 角色别名
|
||||
*/
|
||||
public static List<String> getRoleAliases(String roleIds) {
|
||||
return CacheUtil.get(SYS_CACHE, ROLE_ALIASES_ID, roleIds, () -> getRoleClient().getRoleAliases(roleIds));
|
||||
}
|
||||
|
||||
}
|
65
kn-sys-manager/src/main/java/org/springblade/auth/system/cache/UserCache.java
vendored
Normal file
65
kn-sys-manager/src/main/java/org/springblade/auth/system/cache/UserCache.java
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
package org.springblade.auth.system.cache;
|
||||
|
||||
import org.springblade.auth.system.entity.User;
|
||||
import org.springblade.auth.system.entity.UserInfo;
|
||||
import org.springblade.auth.system.service.IUserService;
|
||||
import org.springblade.core.cache.utils.CacheUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.core.tool.utils.SpringUtil;
|
||||
import org.springblade.core.tool.utils.StringPool;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
|
||||
import static org.springblade.core.cache.constant.CacheConstant.USER_CACHE;
|
||||
import static org.springblade.core.launch.constant.FlowConstant.TASK_USR_PREFIX;
|
||||
|
||||
/**
|
||||
* 系统缓存
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class UserCache {
|
||||
private static final String USER_CACHE_ID = "user:id:";
|
||||
private static final String USER_CACHE_ACCOUNT = "user:account:";
|
||||
|
||||
private static IUserService userClient;
|
||||
|
||||
private static IUserService getUserClient() {
|
||||
if (userClient == null) {
|
||||
userClient = SpringUtil.getBean(IUserService.class);
|
||||
}
|
||||
return userClient;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据任务用户id获取用户信息
|
||||
*
|
||||
* @param taskUserId 任务用户id
|
||||
* @return
|
||||
*/
|
||||
public static User getUserByTaskUser(String taskUserId) {
|
||||
Long userId = Func.toLong(StringUtil.removePrefix(taskUserId, TASK_USR_PREFIX));
|
||||
return getUser(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return
|
||||
*/
|
||||
public static User getUser(Long userId) {
|
||||
return CacheUtil.get(USER_CACHE, USER_CACHE_ID, userId, () -> getUserClient().getById(userId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取用户
|
||||
*
|
||||
* @param tenantId 租户id
|
||||
* @param account 账号名
|
||||
* @return
|
||||
*/
|
||||
public static UserInfo getUser(String tenantId, String account) {
|
||||
return CacheUtil.get(USER_CACHE, USER_CACHE_ACCOUNT, tenantId + StringPool.DASH + account, () -> getUserClient().userInfo(tenantId, account));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,171 @@
|
|||
package org.springblade.auth.system.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.auth.system.entity.DictBiz;
|
||||
import org.springblade.auth.system.service.IDictBizService;
|
||||
import org.springblade.auth.system.vo.DictBizVO;
|
||||
import org.springblade.auth.system.wrapper.DictBizWrapper;
|
||||
import org.springblade.core.cache.utils.CacheUtil;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.core.tenant.annotation.NonDS;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.springblade.core.cache.constant.CacheConstant.DICT_CACHE;
|
||||
|
||||
/**
|
||||
* 控制器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@NonDS
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/dict-biz")
|
||||
@Api(value = "业务字典", tags = "业务字典")
|
||||
public class DictBizController {
|
||||
|
||||
private final IDictBizService dictService;
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
@GetMapping("/detail")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation(value = "详情", notes = "传入dict")
|
||||
public R<DictBizVO> detail(DictBiz dict) {
|
||||
DictBiz detail = dictService.getOne(Condition.getQueryWrapper(dict));
|
||||
return R.data(DictBizWrapper.build().entityVO(detail));
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "code", value = "字典编号", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "dictValue", value = "字典名称", paramType = "query", dataType = "string")
|
||||
})
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation(value = "列表", notes = "传入dict")
|
||||
public R<List<DictBizVO>> list(@ApiIgnore @RequestParam Map<String, Object> dict) {
|
||||
List<DictBiz> list = dictService.list(Condition.getQueryWrapper(dict, DictBiz.class).lambda().orderByAsc(DictBiz::getSort));
|
||||
return R.data(DictBizWrapper.build().listNodeVO(list));
|
||||
}
|
||||
|
||||
/**
|
||||
* 顶级列表
|
||||
*/
|
||||
@GetMapping("/parent-list")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "code", value = "字典编号", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "dictValue", value = "字典名称", paramType = "query", dataType = "string")
|
||||
})
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation(value = "列表", notes = "传入dict")
|
||||
public R<IPage<DictBizVO>> parentList(@ApiIgnore @RequestParam Map<String, Object> dict, Query query) {
|
||||
return R.data(dictService.parentList(dict, query));
|
||||
}
|
||||
|
||||
/**
|
||||
* 子列表
|
||||
*/
|
||||
@GetMapping("/child-list")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "code", value = "字典编号", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "dictValue", value = "字典名称", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "parentId", value = "字典名称", paramType = "query", dataType = "string")
|
||||
})
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperation(value = "列表", notes = "传入dict")
|
||||
public R<List<DictBizVO>> childList(@ApiIgnore @RequestParam Map<String, Object> dict, @RequestParam(required = false, defaultValue = "-1") Long parentId) {
|
||||
return R.data(dictService.childList(dict, parentId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典树形结构
|
||||
*/
|
||||
@GetMapping("/tree")
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation(value = "树形结构", notes = "树形结构")
|
||||
public R<List<DictBizVO>> tree() {
|
||||
List<DictBizVO> tree = dictService.tree();
|
||||
return R.data(tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典树形结构
|
||||
*/
|
||||
@GetMapping("/parent-tree")
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation(value = "树形结构", notes = "树形结构")
|
||||
public R<List<DictBizVO>> parentTree() {
|
||||
List<DictBizVO> tree = dictService.parentTree();
|
||||
return R.data(tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增或修改
|
||||
*/
|
||||
@PostMapping("/submit")
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperation(value = "新增或修改", notes = "传入dict")
|
||||
public R submit(@Valid @RequestBody DictBiz dict) {
|
||||
CacheUtil.clear(DICT_CACHE);
|
||||
return R.status(dictService.submit(dict));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/remove")
|
||||
@ApiOperationSupport(order = 7)
|
||||
@ApiOperation(value = "删除", notes = "传入ids")
|
||||
public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
|
||||
CacheUtil.clear(DICT_CACHE);
|
||||
return R.status(dictService.removeDict(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典
|
||||
*/
|
||||
@GetMapping("/dictionary")
|
||||
@ApiOperationSupport(order = 8)
|
||||
@ApiOperation(value = "获取字典", notes = "获取字典")
|
||||
public R<List<DictBiz>> dictionary(String code) {
|
||||
List<DictBiz> tree = dictService.getList(code);
|
||||
return R.data(tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字典树
|
||||
*/
|
||||
@GetMapping("/dictionary-tree")
|
||||
@ApiOperationSupport(order = 9)
|
||||
@ApiOperation(value = "获取字典树", notes = "获取字典树")
|
||||
public R<List<DictBizVO>> dictionaryTree(String code) {
|
||||
List<DictBiz> tree = dictService.getList(code);
|
||||
return R.data(DictBizWrapper.build().listNodeVO(tree));
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,206 @@
|
|||
package org.springblade.auth.system.controller;
|
||||
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.auth.system.entity.Menu;
|
||||
import org.springblade.auth.system.service.IMenuService;
|
||||
import org.springblade.auth.system.vo.MenuVO;
|
||||
import org.springblade.auth.system.wrapper.MenuWrapper;
|
||||
import org.springblade.core.boot.ctrl.BladeController;
|
||||
import org.springblade.core.cache.utils.CacheUtil;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.secure.BladeUser;
|
||||
import org.springblade.core.secure.annotation.PreAuth;
|
||||
import org.springblade.core.tenant.annotation.NonDS;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.constant.RoleConstant;
|
||||
import org.springblade.core.tool.support.Kv;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.springblade.core.cache.constant.CacheConstant.MENU_CACHE;
|
||||
|
||||
|
||||
/**
|
||||
* 控制器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@NonDS
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/menu")
|
||||
@Api(value = "菜单", tags = "菜单")
|
||||
public class MenuController extends BladeController {
|
||||
|
||||
private final IMenuService menuService;
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
@GetMapping("/detail")
|
||||
@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation(value = "详情", notes = "传入menu")
|
||||
public R<MenuVO> detail(Menu menu) {
|
||||
Menu detail = menuService.getOne(Condition.getQueryWrapper(menu));
|
||||
return R.data(MenuWrapper.build().entityVO(detail));
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "code", value = "菜单编号", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "name", value = "菜单名称", paramType = "query", dataType = "string")
|
||||
})
|
||||
@PreAuth(RoleConstant.HAS_ROLE_ADMINISTRATOR)
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation(value = "列表", notes = "传入menu")
|
||||
public R<List<MenuVO>> list(@ApiIgnore @RequestParam Map<String, Object> menu) {
|
||||
List<Menu> list = menuService.list(Condition.getQueryWrapper(menu, Menu.class).lambda().orderByAsc(Menu::getSort));
|
||||
return R.data(MenuWrapper.build().listNodeVO(list));
|
||||
}
|
||||
|
||||
/**
|
||||
* 懒加载列表
|
||||
*/
|
||||
@GetMapping("/lazy-list")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "code", value = "菜单编号", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "name", value = "菜单名称", paramType = "query", dataType = "string")
|
||||
})
|
||||
@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation(value = "懒加载列表", notes = "传入menu")
|
||||
public R<List<MenuVO>> lazyList(Long parentId, @ApiIgnore @RequestParam Map<String, Object> menu) {
|
||||
List<MenuVO> list = menuService.lazyList(parentId, menu);
|
||||
return R.data(MenuWrapper.build().listNodeLazyVO(list));
|
||||
}
|
||||
|
||||
/**
|
||||
* 菜单列表
|
||||
*/
|
||||
@GetMapping("/menu-list")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "code", value = "菜单编号", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "name", value = "菜单名称", paramType = "query", dataType = "string")
|
||||
})
|
||||
@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperation(value = "菜单列表", notes = "传入menu")
|
||||
public R<List<MenuVO>> menuList(@ApiIgnore @RequestParam Map<String, Object> menu) {
|
||||
List<Menu> list = menuService.list(Condition.getQueryWrapper(menu, Menu.class).lambda().eq(Menu::getCategory, 1).orderByAsc(Menu::getSort));
|
||||
return R.data(MenuWrapper.build().listNodeVO(list));
|
||||
}
|
||||
|
||||
/**
|
||||
* 懒加载菜单列表
|
||||
*/
|
||||
@GetMapping("/lazy-menu-list")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "code", value = "菜单编号", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "name", value = "菜单名称", paramType = "query", dataType = "string")
|
||||
})
|
||||
@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation(value = "懒加载菜单列表", notes = "传入menu")
|
||||
public R<List<MenuVO>> lazyMenuList(Long parentId, @ApiIgnore @RequestParam Map<String, Object> menu) {
|
||||
List<MenuVO> list = menuService.lazyMenuList(parentId, menu);
|
||||
return R.data(MenuWrapper.build().listNodeLazyVO(list));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增或修改
|
||||
*/
|
||||
@PostMapping("/submit")
|
||||
@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperation(value = "新增或修改", notes = "传入menu")
|
||||
public R<Kv> submit(@Valid @RequestBody Menu menu) {
|
||||
if (menuService.submit(menu)) {
|
||||
CacheUtil.clear(MENU_CACHE);
|
||||
CacheUtil.clear(MENU_CACHE, Boolean.FALSE);
|
||||
// 返回懒加载树更新节点所需字段
|
||||
Kv kv = Kv.create().set("id", String.valueOf(menu.getId()));
|
||||
return R.data(kv);
|
||||
}
|
||||
return R.fail("操作失败");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/remove")
|
||||
@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
|
||||
@ApiOperationSupport(order = 7)
|
||||
@ApiOperation(value = "删除", notes = "传入ids")
|
||||
public R<Boolean> remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
|
||||
CacheUtil.clear(MENU_CACHE);
|
||||
CacheUtil.clear(MENU_CACHE, Boolean.FALSE);
|
||||
return R.status(menuService.removeMenu(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 前端菜单数据
|
||||
*/
|
||||
@GetMapping("/routes")
|
||||
@ApiOperationSupport(order = 8)
|
||||
@ApiOperation(value = "前端菜单数据", notes = "前端菜单数据")
|
||||
public R<List<MenuVO>> routes(BladeUser user, Long topMenuId) {
|
||||
List<MenuVO> list = menuService.routes((user == null) ? null : user.getRoleId(), topMenuId);
|
||||
return R.data(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 前端按钮数据
|
||||
*/
|
||||
@GetMapping("/buttons")
|
||||
@ApiOperationSupport(order = 10)
|
||||
@ApiOperation(value = "前端按钮数据", notes = "前端按钮数据")
|
||||
public R<List<MenuVO>> buttons(BladeUser user) {
|
||||
List<MenuVO> list = menuService.buttons(user.getRoleId());
|
||||
return R.data(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取菜单树形结构
|
||||
*/
|
||||
@GetMapping("/tree")
|
||||
@ApiOperationSupport(order = 11)
|
||||
@ApiOperation(value = "树形结构", notes = "树形结构")
|
||||
public R<List<MenuVO>> tree() {
|
||||
List<MenuVO> tree = menuService.tree();
|
||||
return R.data(tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取配置的角色权限
|
||||
*/
|
||||
@GetMapping("auth-routes")
|
||||
@ApiOperationSupport(order = 17)
|
||||
@ApiOperation(value = "菜单的角色权限")
|
||||
public R<List<Kv>> authRoutes(BladeUser user) {
|
||||
if (Func.isEmpty(user)) {
|
||||
return null;
|
||||
}
|
||||
return R.data(menuService.authRoutes(user));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,160 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.Api;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.auth.system.service.IRoleService;
|
||||
import org.springblade.core.boot.ctrl.BladeController;
|
||||
import org.springblade.core.cache.utils.CacheUtil;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.secure.BladeUser;
|
||||
import org.springblade.core.secure.annotation.PreAuth;
|
||||
import org.springblade.core.secure.constant.AuthConstant;
|
||||
import org.springblade.core.tenant.annotation.NonDS;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.constant.RoleConstant;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.auth.system.cache.SysCache;
|
||||
import org.springblade.auth.system.entity.Role;
|
||||
import org.springblade.auth.system.vo.RoleVO;
|
||||
import org.springblade.auth.system.wrapper.RoleWrapper;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.springblade.core.cache.constant.CacheConstant.SYS_CACHE;
|
||||
|
||||
/**
|
||||
* 控制器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@NonDS
|
||||
@RestController
|
||||
@AllArgsConstructor
|
||||
@RequestMapping("/role")
|
||||
@Api(value = "角色", tags = "角色")
|
||||
@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
|
||||
public class RoleController extends BladeController {
|
||||
|
||||
private final IRoleService roleService;
|
||||
|
||||
/**
|
||||
* 详情
|
||||
*/
|
||||
@GetMapping("/detail")
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation(value = "详情", notes = "传入role")
|
||||
public R<RoleVO> detail(Role role) {
|
||||
Role detail = roleService.getOne(Condition.getQueryWrapper(role));
|
||||
return R.data(RoleWrapper.build().entityVO(detail));
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "roleName", value = "参数名称", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "roleAlias", value = "角色别名", paramType = "query", dataType = "string")
|
||||
})
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation(value = "列表", notes = "传入role")
|
||||
public R<List<RoleVO>> list(@ApiIgnore @RequestParam Map<String, Object> role, BladeUser bladeUser) {
|
||||
QueryWrapper<Role> queryWrapper = Condition.getQueryWrapper(role, Role.class);
|
||||
List<Role> list = roleService.list((!bladeUser.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID)) ? queryWrapper.lambda().eq(Role::getTenantId, bladeUser.getTenantId()) : queryWrapper);
|
||||
return R.data(RoleWrapper.build().listNodeVO(list));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取角色树形结构
|
||||
*/
|
||||
@GetMapping("/tree")
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation(value = "树形结构", notes = "树形结构")
|
||||
public R<List<RoleVO>> tree(String tenantId, BladeUser bladeUser) {
|
||||
List<RoleVO> tree = roleService.tree(Func.toStrWithEmpty(tenantId, bladeUser.getTenantId()));
|
||||
return R.data(tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定角色树形结构
|
||||
*/
|
||||
@GetMapping("/tree-by-id")
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperation(value = "树形结构", notes = "树形结构")
|
||||
public R<List<RoleVO>> treeById(Long roleId, BladeUser bladeUser) {
|
||||
Role role = SysCache.getRole(roleId);
|
||||
List<RoleVO> tree = roleService.tree(Func.notNull(role) ? role.getTenantId() : bladeUser.getTenantId());
|
||||
return R.data(tree);
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增或修改
|
||||
*/
|
||||
@PostMapping("/submit")
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation(value = "新增或修改", notes = "传入role")
|
||||
public R submit(@Valid @RequestBody Role role) {
|
||||
CacheUtil.clear(SYS_CACHE);
|
||||
CacheUtil.clear(SYS_CACHE, Boolean.FALSE);
|
||||
return R.status(roleService.submit(role));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/remove")
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperation(value = "删除", notes = "传入ids")
|
||||
public R remove(@ApiParam(value = "主键集合", required = true) @RequestParam String ids) {
|
||||
CacheUtil.clear(SYS_CACHE);
|
||||
CacheUtil.clear(SYS_CACHE, Boolean.FALSE);
|
||||
return R.status(roleService.removeByIds(Func.toLongList(ids)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 下拉数据源
|
||||
*/
|
||||
@PreAuth(AuthConstant.PERMIT_ALL)
|
||||
@GetMapping("/select")
|
||||
@ApiOperationSupport(order = 8)
|
||||
@ApiOperation(value = "下拉数据源", notes = "传入id集合")
|
||||
public R<List<Role>> select(String roleId) {
|
||||
List<Role> list = roleService.list(Wrappers.<Role>lambdaQuery().in(Role::getId, Func.toLongList(roleId)));
|
||||
return R.data(list);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
package org.springblade.auth.system.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import io.swagger.annotations.ApiParam;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.auth.system.entity.User;
|
||||
import org.springblade.auth.system.service.IUserService;
|
||||
import org.springblade.auth.system.vo.UserVO;
|
||||
import org.springblade.auth.system.wrapper.UserWrapper;
|
||||
import org.springblade.core.cache.utils.CacheUtil;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.core.secure.BladeUser;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tenant.annotation.NonDS;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.utils.StringPool;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import javax.validation.Valid;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.springblade.core.cache.constant.CacheConstant.USER_CACHE;
|
||||
|
||||
/**
|
||||
* 控制器
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@NonDS
|
||||
@RestController
|
||||
@RequestMapping("/user")
|
||||
@AllArgsConstructor
|
||||
public class UserController {
|
||||
|
||||
private final IUserService userService;
|
||||
|
||||
/**
|
||||
* 查询单条
|
||||
*/
|
||||
@ApiOperationSupport(order = 1)
|
||||
@ApiOperation(value = "查看详情", notes = "传入id")
|
||||
@GetMapping("/detail")
|
||||
public R<UserVO> detail(User user) {
|
||||
User detail = userService.getOne(Condition.getQueryWrapper(user));
|
||||
return R.data(UserWrapper.build().entityVO(detail));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询单条
|
||||
*/
|
||||
@ApiOperationSupport(order = 2)
|
||||
@ApiOperation(value = "查看详情", notes = "传入id")
|
||||
@GetMapping("/info")
|
||||
public R<UserVO> info(BladeUser user) {
|
||||
User detail = userService.getById(user.getUserId());
|
||||
return R.data(UserWrapper.build().entityVO(detail));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户列表
|
||||
*/
|
||||
@GetMapping("/list")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "account", value = "账号名", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "realName", value = "姓名", paramType = "query", dataType = "string")
|
||||
})
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation(value = "列表", notes = "传入account和realName")
|
||||
public R<IPage<UserVO>> list(@ApiIgnore @RequestParam Map<String, Object> user, Query query, BladeUser bladeUser) {
|
||||
QueryWrapper<User> queryWrapper = Condition.getQueryWrapper(user, User.class);
|
||||
IPage<User> pages = userService.page(Condition.getPage(query), (!bladeUser.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID)) ? queryWrapper.lambda().eq(User::getTenantId, bladeUser.getTenantId()) : queryWrapper);
|
||||
return R.data(UserWrapper.build().pageVO(pages));
|
||||
}
|
||||
|
||||
/**
|
||||
* 自定义用户列表
|
||||
*/
|
||||
@GetMapping("/page")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "account", value = "账号名", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "realName", value = "姓名", paramType = "query", dataType = "string")
|
||||
})
|
||||
@ApiOperationSupport(order = 3)
|
||||
@ApiOperation(value = "列表", notes = "传入account和realName")
|
||||
//@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
|
||||
//添加组长可以查询人员的权限
|
||||
//@PreAuth("hasAnyRole('" + RoleConstant.ADMINISTRATOR + "', '" + RoleConstant.ADMIN + "','" + RoleConstant.USER + "')")
|
||||
public R<IPage<UserVO>> page(@ApiIgnore User user, Query query, Long deptId, BladeUser bladeUser) {
|
||||
IPage<User> pages = userService.selectUserPage(Condition.getPage(query), user, deptId, (bladeUser.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? StringPool.EMPTY : bladeUser.getTenantId()));
|
||||
return R.data(UserWrapper.build().pageVO(pages));
|
||||
}
|
||||
|
||||
/**
|
||||
* 新增或修改
|
||||
*/
|
||||
@PostMapping("/submit")
|
||||
@ApiOperationSupport(order = 4)
|
||||
@ApiOperation(value = "新增或修改", notes = "传入User")
|
||||
public R submit(@Valid @RequestBody User user) {
|
||||
CacheUtil.clear(USER_CACHE);
|
||||
return R.status(userService.submit(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*/
|
||||
@PostMapping("/update")
|
||||
@ApiOperationSupport(order = 5)
|
||||
@ApiOperation(value = "修改", notes = "传入User")
|
||||
public R update(@Valid @RequestBody User user) {
|
||||
CacheUtil.clear(USER_CACHE);
|
||||
return R.status(userService.updateUser(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除
|
||||
*/
|
||||
@PostMapping("/remove")
|
||||
@ApiOperationSupport(order = 6)
|
||||
@ApiOperation(value = "删除", notes = "传入id集合")
|
||||
public R remove(@RequestParam String ids) {
|
||||
CacheUtil.clear(USER_CACHE);
|
||||
return R.status(userService.removeUser(ids));
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置菜单权限
|
||||
*/
|
||||
@PostMapping("/grant")
|
||||
@ApiOperationSupport(order = 7)
|
||||
@ApiOperation(value = "权限设置", notes = "传入roleId集合以及menuId集合")
|
||||
public R grant(@ApiParam(value = "userId集合", required = true) @RequestParam String userIds,
|
||||
@ApiParam(value = "roleId集合", required = true) @RequestParam String roleIds) {
|
||||
boolean temp = userService.grant(userIds, roleIds);
|
||||
return R.status(temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码重制
|
||||
*/
|
||||
@PostMapping("/reset-password")
|
||||
@ApiOperationSupport(order = 8)
|
||||
@ApiOperation(value = "初始化密码", notes = "传入userId集合")
|
||||
public R resetPassword(@ApiParam(value = "userId集合", required = true) @RequestParam String userIds) {
|
||||
boolean temp = userService.resetPassword(userIds);
|
||||
return R.status(temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
*/
|
||||
@PostMapping("/update-password")
|
||||
@ApiOperationSupport(order = 9)
|
||||
@ApiOperation(value = "修改密码", notes = "传入密码")
|
||||
public R updatePassword(BladeUser user, @ApiParam(value = "旧密码", required = true) @RequestParam String oldPassword,
|
||||
@ApiParam(value = "新密码", required = true) @RequestParam String newPassword,
|
||||
@ApiParam(value = "新密码", required = true) @RequestParam String newPassword1) {
|
||||
boolean temp = userService.updatePassword(user.getUserId(), oldPassword, newPassword, newPassword1);
|
||||
return R.status(temp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改基本信息
|
||||
*/
|
||||
@PostMapping("/update-info")
|
||||
@ApiOperationSupport(order = 10)
|
||||
@ApiOperation(value = "修改基本信息", notes = "传入User")
|
||||
public R updateInfo(@Valid @RequestBody User user) {
|
||||
CacheUtil.clear(USER_CACHE);
|
||||
return R.status(userService.updateUserInfo(user));
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户列表
|
||||
*/
|
||||
@GetMapping("/user-list")
|
||||
@ApiOperationSupport(order = 11)
|
||||
@ApiOperation(value = "用户列表", notes = "传入user")
|
||||
public R<List<User>> userList(User user, BladeUser bladeUser) {
|
||||
QueryWrapper<User> queryWrapper = Condition.getQueryWrapper(user);
|
||||
List<User> list = userService.list((!AuthUtil.isAdministrator()) ? queryWrapper.lambda().eq(User::getTenantId, bladeUser.getTenantId()) : queryWrapper);
|
||||
return R.data(list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 用户列表查询
|
||||
*/
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "name", value = "人员姓名", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "deptName", value = "部门名称", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "postName", value = "职位名称", paramType = "query", dataType = "string"),
|
||||
@ApiImplicitParam(name = "current", value = "当前页数", paramType = "query", dataType = "int"),
|
||||
@ApiImplicitParam(name = "size", value = "每页数量", paramType = "query", dataType = "int")
|
||||
})
|
||||
@ApiOperationSupport(order = 18)
|
||||
@ApiOperation(value = "用户列表查询", notes = "用户列表查询")
|
||||
@GetMapping("/search/user")
|
||||
public R<IPage<UserVO>> userSearch(@ApiIgnore UserVO user, @ApiIgnore Query query) {
|
||||
return R.data(userService.selectUserSearch(user, query));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.springblade.auth.system.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 数据传输对象实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
public class MenuDTO implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
private String alias;
|
||||
private String path;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.springblade.auth.system.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.auth.system.entity.Role;
|
||||
|
||||
/**
|
||||
* 数据传输对象实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class RoleDTO extends Role {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.springblade.auth.system.dto;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.auth.system.entity.RoleMenu;
|
||||
|
||||
/**
|
||||
* 数据传输对象实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class RoleMenuDTO extends RoleMenu {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package org.springblade.auth.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@TableName("blade_dict_biz")
|
||||
@ApiModel(value = "DictBiz对象", description = "DictBiz对象")
|
||||
public class DictBiz implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
@ApiModelProperty(value = "主键")
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@ApiModelProperty(value = "租户ID")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 父主键
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
@ApiModelProperty(value = "父主键")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 字典码
|
||||
*/
|
||||
@ApiModelProperty(value = "字典码")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 字典值
|
||||
*/
|
||||
@ApiModelProperty(value = "字典值")
|
||||
private String dictKey;
|
||||
|
||||
/**
|
||||
* 字典名称
|
||||
*/
|
||||
@ApiModelProperty(value = "字典名称")
|
||||
private String dictValue;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@ApiModelProperty(value = "排序")
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 字典备注
|
||||
*/
|
||||
@ApiModelProperty(value = "字典备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 是否已封存
|
||||
*/
|
||||
@ApiModelProperty(value = "是否已封存")
|
||||
private Integer isSealed;
|
||||
|
||||
/**
|
||||
* 是否已删除
|
||||
*/
|
||||
@TableLogic
|
||||
@ApiModelProperty(value = "是否已删除")
|
||||
private Integer isDeleted;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@TableName("blade_menu")
|
||||
@ApiModel(value = "Menu对象", description = "Menu对象")
|
||||
public class Menu implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
@ApiModelProperty(value = "主键")
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 菜单父主键
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
@ApiModelProperty(value = "菜单父主键")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 菜单编号
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单编号")
|
||||
private String code;
|
||||
|
||||
/**
|
||||
* 菜单名称
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单名称")
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* 菜单别名
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单别名")
|
||||
private String alias;
|
||||
|
||||
/**
|
||||
* 请求地址
|
||||
*/
|
||||
@ApiModelProperty(value = "请求地址")
|
||||
private String path;
|
||||
|
||||
/**
|
||||
* 菜单资源
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单资源")
|
||||
private String source;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@ApiModelProperty(value = "排序")
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 菜单类型
|
||||
*/
|
||||
@ApiModelProperty(value = "菜单类型")
|
||||
private Integer category;
|
||||
|
||||
/**
|
||||
* 操作按钮类型
|
||||
*/
|
||||
@ApiModelProperty(value = "操作按钮类型")
|
||||
private Integer action;
|
||||
|
||||
/**
|
||||
* 是否打开新页面
|
||||
*/
|
||||
@ApiModelProperty(value = "是否打开新页面")
|
||||
private Integer isOpen;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ApiModelProperty(value = "备注")
|
||||
private String remark;
|
||||
|
||||
/**
|
||||
* 是否已删除
|
||||
*/
|
||||
@TableLogic
|
||||
@ApiModelProperty(value = "是否已删除")
|
||||
private Integer isDeleted;
|
||||
|
||||
/**
|
||||
* 是否隐藏
|
||||
*/
|
||||
@ApiModelProperty(value = "是否隐藏")
|
||||
private Integer isHidden;
|
||||
/**
|
||||
* 手动添加的隐藏的set方法
|
||||
*/
|
||||
public void setIsHidden(Integer isHidden) {
|
||||
this.isHidden = isHidden;
|
||||
}
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj) {
|
||||
return true;
|
||||
}
|
||||
if (obj == null) {
|
||||
return false;
|
||||
}
|
||||
Menu other = (Menu) obj;
|
||||
if (Func.equals(this.getId(), other.getId())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, parentId, code);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@TableName("blade_role")
|
||||
@ApiModel(value = "Role对象", description = "Role对象")
|
||||
public class Role implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
@ApiModelProperty(value = "主键")
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 租户ID
|
||||
*/
|
||||
@ApiModelProperty(value = "租户ID")
|
||||
private String tenantId;
|
||||
|
||||
/**
|
||||
* 父主键
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
@ApiModelProperty(value = "父主键")
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 角色名
|
||||
*/
|
||||
@ApiModelProperty(value = "角色名")
|
||||
private String roleName;
|
||||
|
||||
/**
|
||||
* 排序
|
||||
*/
|
||||
@ApiModelProperty(value = "排序")
|
||||
private Integer sort;
|
||||
|
||||
/**
|
||||
* 角色别名
|
||||
*/
|
||||
@ApiModelProperty(value = "角色别名")
|
||||
private String roleAlias;
|
||||
|
||||
/**
|
||||
* 是否已删除
|
||||
*/
|
||||
@TableLogic
|
||||
@ApiModelProperty(value = "是否已删除")
|
||||
private Integer isDeleted;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@TableName("blade_role_menu")
|
||||
@ApiModel(value = "RoleMenu对象", description = "RoleMenu对象")
|
||||
public class RoleMenu implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
@ApiModelProperty(value = "主键")
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 菜单id
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
@ApiModelProperty(value = "菜单id")
|
||||
private Long menuId;
|
||||
|
||||
/**
|
||||
* 角色id
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
@ApiModelProperty(value = "角色id")
|
||||
private Long roleId;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tenant.mp.TenantEntity;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
* 实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@TableName("blade_user")
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class User extends TenantEntity {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 用户编号
|
||||
*/
|
||||
private String code;
|
||||
/**
|
||||
* 用户平台
|
||||
*/
|
||||
private Integer userType;
|
||||
/**
|
||||
* 账号
|
||||
*/
|
||||
private String account;
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
private String password;
|
||||
/**
|
||||
* 昵称
|
||||
*/
|
||||
private String name;
|
||||
/**
|
||||
* 真名
|
||||
*/
|
||||
private String realName;
|
||||
|
||||
/**
|
||||
* 用户组织机构
|
||||
*/
|
||||
private String organization;
|
||||
|
||||
/**
|
||||
* 头像
|
||||
*/
|
||||
private String avatar;
|
||||
/**
|
||||
* 邮箱
|
||||
*/
|
||||
private String email;
|
||||
/**
|
||||
* 手机
|
||||
*/
|
||||
private String phone;
|
||||
/**
|
||||
* 角色id
|
||||
*/
|
||||
private String roleId;
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.entity;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.Data;
|
||||
import org.springblade.core.tool.support.Kv;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@ApiModel(description = "用户信息")
|
||||
public class UserInfo implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 第三方授权id
|
||||
*/
|
||||
@ApiModelProperty(value = "第三方授权id")
|
||||
private String oauthId;
|
||||
|
||||
/**
|
||||
* 用户基础信息
|
||||
*/
|
||||
@ApiModelProperty(value = "用户")
|
||||
private User user;
|
||||
|
||||
/**
|
||||
* 拓展信息
|
||||
*/
|
||||
@ApiModelProperty(value = "拓展信息")
|
||||
private Kv detail;
|
||||
|
||||
/**
|
||||
* 权限标识集合
|
||||
*/
|
||||
@ApiModelProperty(value = "权限集合")
|
||||
private List<String> permissions;
|
||||
|
||||
/**
|
||||
* 角色集合
|
||||
*/
|
||||
@ApiModelProperty(value = "角色集合")
|
||||
private List<String> roles;
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.enums;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 用户类型枚举
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum UserEnum {
|
||||
|
||||
/**
|
||||
* web
|
||||
*/
|
||||
WEB("web", 1),
|
||||
|
||||
/**
|
||||
* app
|
||||
*/
|
||||
APP("app", 2),
|
||||
|
||||
/**
|
||||
* other
|
||||
*/
|
||||
OTHER("other", 3),
|
||||
;
|
||||
|
||||
final String name;
|
||||
final int category;
|
||||
|
||||
/**
|
||||
* 匹配枚举值
|
||||
*
|
||||
* @param name 名称
|
||||
* @return BladeUserEnum
|
||||
*/
|
||||
public static UserEnum of(String name) {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
UserEnum[] values = UserEnum.values();
|
||||
for (UserEnum smsEnum : values) {
|
||||
if (smsEnum.name.equals(name)) {
|
||||
return smsEnum;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package org.springblade.auth.system.mapper;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springblade.auth.system.entity.DictBiz;
|
||||
import org.springblade.auth.system.vo.DictBizVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Mapper 接口
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface DictBizMapper extends BaseMapper<DictBiz> {
|
||||
|
||||
/**
|
||||
* 获取字典表对应中文
|
||||
*
|
||||
* @param code 字典编号
|
||||
* @param dictKey 字典序号
|
||||
* @return
|
||||
*/
|
||||
String getValue(String code, String dictKey);
|
||||
|
||||
/**
|
||||
* 获取字典表
|
||||
*
|
||||
* @param code 字典编号
|
||||
* @return
|
||||
*/
|
||||
List<DictBiz> getList(String code);
|
||||
|
||||
/**
|
||||
* 获取树形节点
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<DictBizVO> tree();
|
||||
|
||||
/**
|
||||
* 获取树形节点
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<DictBizVO> parentTree();
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.springblade.auth.system.mapper.DictBizMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="dictResultMap" type="org.springblade.auth.system.entity.DictBiz">
|
||||
<id column="id" property="id"/>
|
||||
<result column="tenant_id" property="tenantId"/>
|
||||
<result column="parent_id" property="parentId"/>
|
||||
<result column="code" property="code"/>
|
||||
<result column="dict_key" property="dictKey"/>
|
||||
<result column="dict_value" property="dictValue"/>
|
||||
<result column="sort" property="sort"/>
|
||||
<result column="remark" property="remark"/>
|
||||
<result column="is_deleted" property="isDeleted"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="treeNodeResultMap" type="org.springblade.core.tool.node.TreeNode">
|
||||
<id column="id" property="id"/>
|
||||
<result column="parent_id" property="parentId"/>
|
||||
<result column="title" property="title"/>
|
||||
<result column="value" property="value"/>
|
||||
<result column="key" property="key"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="getValue" resultType="java.lang.String">
|
||||
select
|
||||
dict_value
|
||||
from blade_dict_biz where code = #{param1} and dict_key = #{param2} and is_deleted = 0
|
||||
</select>
|
||||
|
||||
<!-- oracle 版本 -->
|
||||
<!--<select id="getValue" resultType="java.lang.String">
|
||||
select
|
||||
dict_value
|
||||
from blade_dict_biz where code = #{param1, jdbcType=VARCHAR} and dict_key = #{param2} and dict_key >= 0 rownum 1
|
||||
</select>-->
|
||||
|
||||
<select id="getList" resultMap="dictResultMap">
|
||||
select id, parent_id, code, dict_key, dict_value, sort, remark from blade_dict_biz where code = #{param1} and parent_id > 0 and is_sealed = 0 and is_deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="tree" resultMap="treeNodeResultMap">
|
||||
select id, parent_id, dict_value as title, id as "value", id as "key" from blade_dict_biz where is_deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="parentTree" resultMap="treeNodeResultMap">
|
||||
select id, parent_id, dict_value as title, id as "value", id as "key" from blade_dict_biz where is_deleted = 0 and parent_id = 0
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.springblade.auth.system.dto.MenuDTO;
|
||||
import org.springblade.auth.system.entity.Menu;
|
||||
import org.springblade.auth.system.vo.MenuVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
/**
|
||||
* MenuMapper 接口
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface MenuMapper extends BaseMapper<Menu> {
|
||||
|
||||
/**
|
||||
* 懒加载列表
|
||||
*
|
||||
* @param parentId
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> lazyList(Long parentId, Map<String, Object> param);
|
||||
|
||||
/**
|
||||
* 懒加载菜单列表
|
||||
*
|
||||
* @param parentId
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> lazyMenuList(Long parentId, Map<String, Object> param);
|
||||
|
||||
/**
|
||||
* 树形结构
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> tree();
|
||||
|
||||
/**
|
||||
* 授权树形结构
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> grantTree();
|
||||
|
||||
/**
|
||||
* 授权树形结构
|
||||
*
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> grantTreeByRole(List<Long> roleId);
|
||||
|
||||
/**
|
||||
* 顶部菜单树形结构
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> grantTopTree();
|
||||
|
||||
/**
|
||||
* 顶部菜单树形结构
|
||||
*
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> grantTopTreeByRole(List<Long> roleId);
|
||||
|
||||
/**
|
||||
* 数据权限授权树形结构
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> grantDataScopeTree();
|
||||
|
||||
/**
|
||||
* 接口权限授权树形结构
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> grantApiScopeTree();
|
||||
|
||||
/**
|
||||
* 数据权限授权树形结构
|
||||
*
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> grantDataScopeTreeByRole(List<Long> roleId);
|
||||
|
||||
/**
|
||||
* 接口权限授权树形结构
|
||||
*
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> grantApiScopeTreeByRole(List<Long> roleId);
|
||||
|
||||
/**
|
||||
* 所有菜单
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Menu> allMenu();
|
||||
|
||||
/**
|
||||
* 权限配置菜单
|
||||
*
|
||||
* @param roleId
|
||||
* @param topMenuId
|
||||
* @return
|
||||
*/
|
||||
List<Menu> roleMenu(List<Long> roleId, Long topMenuId);
|
||||
|
||||
/**
|
||||
* 权限配置菜单
|
||||
*
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<Menu> roleMenuByRoleId(List<Long> roleId);
|
||||
|
||||
/**
|
||||
* 权限配置菜单
|
||||
*
|
||||
* @param topMenuId
|
||||
* @return
|
||||
*/
|
||||
List<Menu> roleMenuByTopMenuId(Long topMenuId);
|
||||
|
||||
/**
|
||||
* 菜单树形结构
|
||||
*
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<Menu> routes(List<Long> roleId);
|
||||
|
||||
/**
|
||||
* 按钮树形结构
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<Menu> allButtons();
|
||||
|
||||
/**
|
||||
* 按钮树形结构
|
||||
*
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<Menu> buttons(List<Long> roleId);
|
||||
|
||||
/**
|
||||
* 获取配置的角色权限
|
||||
*
|
||||
* @param roleIds
|
||||
* @return
|
||||
*/
|
||||
List<MenuDTO> authRoutes(List<Long> roleIds);
|
||||
}
|
|
@ -0,0 +1,478 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.springblade.auth.system.mapper.MenuMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="menuResultMap" type="org.springblade.auth.system.entity.Menu">
|
||||
<id column="id" property="id"/>
|
||||
<result column="code" property="code"/>
|
||||
<result column="parent_id" property="parentId"/>
|
||||
<result column="name" property="name"/>
|
||||
<result column="alias" property="alias"/>
|
||||
<result column="path" property="path"/>
|
||||
<result column="source" property="source"/>
|
||||
<result column="sort" property="sort"/>
|
||||
<result column="category" property="category"/>
|
||||
<result column="action" property="action"/>
|
||||
<result column="is_open" property="isOpen"/>
|
||||
<result column="remark" property="remark"/>
|
||||
<result column="is_deleted" property="isDeleted"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="menuVOResultMap" type="org.springblade.auth.system.vo.MenuVO">
|
||||
<id column="id" property="id"/>
|
||||
<result column="code" property="code"/>
|
||||
<result column="parent_id" property="parentId"/>
|
||||
<result column="name" property="name"/>
|
||||
<result column="alias" property="alias"/>
|
||||
<result column="path" property="path"/>
|
||||
<result column="source" property="source"/>
|
||||
<result column="sort" property="sort"/>
|
||||
<result column="category" property="category"/>
|
||||
<result column="action" property="action"/>
|
||||
<result column="is_open" property="isOpen"/>
|
||||
<result column="remark" property="remark"/>
|
||||
<result column="is_deleted" property="isDeleted"/>
|
||||
<result column="has_children" property="hasChildren"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="treeNodeResultMap" type="org.springblade.core.tool.node.TreeNode">
|
||||
<id column="id" property="id"/>
|
||||
<result column="parent_id" property="parentId"/>
|
||||
<result column="title" property="title"/>
|
||||
<result column="value" property="value"/>
|
||||
<result column="key" property="key"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="lazyList" resultMap="menuVOResultMap">
|
||||
SELECT
|
||||
menu.*,
|
||||
(
|
||||
SELECT
|
||||
CASE WHEN count( 1 ) > 0 THEN 1 ELSE 0 END
|
||||
FROM
|
||||
blade_menu
|
||||
WHERE
|
||||
parent_id = menu.id AND is_deleted = 0
|
||||
) AS "has_children"
|
||||
FROM
|
||||
blade_menu menu
|
||||
WHERE menu.is_deleted = 0
|
||||
<if test="param1!=null">
|
||||
and menu.parent_id = #{param1}
|
||||
</if>
|
||||
<if test="param2.name!=null and param2.name!=''">
|
||||
and menu.name like concat(concat('%', #{param2.name}),'%')
|
||||
</if>
|
||||
<if test="param2.code!=null and param2.code!=''">
|
||||
and menu.code like concat(concat('%', #{param2.code}),'%')
|
||||
</if>
|
||||
<if test="param2.alias!=null and param2.alias!=''">
|
||||
and menu.alias like concat(concat('%', #{param2.alias}),'%')
|
||||
</if>
|
||||
ORDER BY menu.sort
|
||||
</select>
|
||||
|
||||
<select id="lazyMenuList" resultMap="menuVOResultMap">
|
||||
SELECT
|
||||
menu.*,
|
||||
(
|
||||
SELECT
|
||||
CASE WHEN count( 1 ) > 0 THEN 1 ELSE 0 END
|
||||
FROM
|
||||
blade_menu
|
||||
WHERE
|
||||
parent_id = menu.id AND is_deleted = 0 AND category = 1
|
||||
) AS "has_children"
|
||||
FROM
|
||||
blade_menu menu
|
||||
WHERE menu.is_deleted = 0 AND menu.category = 1
|
||||
<if test="param1!=null">
|
||||
and menu.parent_id = #{param1}
|
||||
</if>
|
||||
<if test="param2.name!=null and param2.name!=''">
|
||||
and menu.name like concat(concat('%', #{param2.name}),'%')
|
||||
</if>
|
||||
<if test="param2.code!=null and param2.code!=''">
|
||||
and menu.code like concat(concat('%', #{param2.code}),'%')
|
||||
</if>
|
||||
<if test="param2.alias!=null and param2.alias!=''">
|
||||
and menu.alias like concat(concat('%', #{param2.alias}),'%')
|
||||
</if>
|
||||
ORDER BY menu.sort
|
||||
</select>
|
||||
|
||||
<select id="tree" resultMap="treeNodeResultMap">
|
||||
select id, parent_id, name as title, id as "value", id as "key" from blade_menu where is_deleted = 0 and category = 1
|
||||
</select>
|
||||
|
||||
<select id="allMenu" resultMap="menuResultMap">
|
||||
select * from blade_menu where is_deleted = 0 and category = 1
|
||||
</select>
|
||||
|
||||
<select id="roleMenu" resultMap="menuResultMap">
|
||||
select * from blade_menu where is_deleted = 0 and id IN
|
||||
( SELECT menu_id FROM blade_role_menu WHERE role_id IN
|
||||
<foreach collection="param1" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
)
|
||||
<if test="param2!=null and param2>0">
|
||||
AND id IN
|
||||
(
|
||||
SELECT menu_id FROM blade_top_menu_setting WHERE top_menu_id = #{param2}
|
||||
)
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="roleMenuByRoleId" resultMap="menuResultMap">
|
||||
select * from blade_menu where is_deleted = 0 and id IN
|
||||
( SELECT menu_id FROM blade_role_menu WHERE role_id IN
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
)
|
||||
</select>
|
||||
|
||||
<select id="roleMenuByTopMenuId" resultMap="menuResultMap">
|
||||
select * from blade_menu where is_deleted = 0 and id IN
|
||||
(
|
||||
SELECT menu_id FROM blade_top_menu_setting WHERE top_menu_id = #{param1}
|
||||
)
|
||||
</select>
|
||||
|
||||
<select id="routes" resultMap="menuResultMap">
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
blade_menu
|
||||
WHERE
|
||||
is_deleted = 0 and category = 1
|
||||
and id IN ( SELECT menu_id FROM blade_role_menu WHERE role_id IN
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach> )
|
||||
</select>
|
||||
|
||||
<select id="allButtons" resultMap="menuResultMap">
|
||||
SELECT
|
||||
id,
|
||||
parent_id,
|
||||
CODE,
|
||||
NAME,
|
||||
alias,
|
||||
path,
|
||||
source,
|
||||
action,
|
||||
sort
|
||||
FROM
|
||||
blade_menu
|
||||
WHERE
|
||||
(
|
||||
category = 2 OR id IN ( SELECT parent_id FROM blade_menu WHERE is_deleted = 0 AND category = 2 )
|
||||
)
|
||||
AND is_deleted = 0
|
||||
ORDER BY sort
|
||||
</select>
|
||||
|
||||
<select id="buttons" resultMap="menuResultMap">
|
||||
SELECT * FROM (
|
||||
SELECT
|
||||
id,
|
||||
parent_id,
|
||||
code,
|
||||
name,
|
||||
alias,
|
||||
path,
|
||||
source,
|
||||
action,
|
||||
sort
|
||||
FROM
|
||||
blade_menu
|
||||
WHERE
|
||||
is_deleted = 0 and id IN (
|
||||
SELECT parent_id FROM blade_menu
|
||||
WHERE ( category = 2 AND id IN ( SELECT menu_id FROM blade_role_menu WHERE role_id IN
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
) ) )
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
id,
|
||||
parent_id,
|
||||
code,
|
||||
name,
|
||||
alias,
|
||||
path,
|
||||
source,
|
||||
action,
|
||||
sort
|
||||
FROM
|
||||
blade_menu
|
||||
WHERE
|
||||
is_deleted = 0 and category = 2 AND id IN ( SELECT menu_id FROM blade_role_menu WHERE role_id IN
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>)
|
||||
) menu ORDER BY sort
|
||||
</select>
|
||||
|
||||
<select id="grantTree" resultMap="treeNodeResultMap">
|
||||
select id, parent_id, name as title, id as "value", id as "key" from blade_menu where is_deleted = 0 order by sort
|
||||
</select>
|
||||
|
||||
<select id="grantTreeByRole" resultMap="treeNodeResultMap">
|
||||
select id, parent_id, name as title, id as "value", id as "key" from blade_menu where is_deleted = 0
|
||||
and id in ( select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach> )
|
||||
or id in (
|
||||
select parent_id from blade_menu where is_deleted = 0
|
||||
and id in ( select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach> )
|
||||
)
|
||||
order by sort
|
||||
</select>
|
||||
|
||||
<select id="grantTopTree" resultMap="treeNodeResultMap">
|
||||
select id, parent_id, name as title, id as "value", id as "key" from blade_menu where category = 1 and is_deleted = 0 order by sort
|
||||
</select>
|
||||
|
||||
<select id="grantTopTreeByRole" resultMap="treeNodeResultMap">
|
||||
select id, parent_id, name as title, id as "value", id as "key" from blade_menu where category = 1 and is_deleted = 0
|
||||
and id in ( select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach> )
|
||||
or id in (
|
||||
select parent_id from blade_menu where is_deleted = 0
|
||||
and id in ( select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach> )
|
||||
)
|
||||
order by sort
|
||||
</select>
|
||||
|
||||
<select id="grantDataScopeTree" resultMap="treeNodeResultMap">
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
id,
|
||||
parent_id,
|
||||
NAME AS title,
|
||||
id AS "value",
|
||||
id AS "key"
|
||||
FROM
|
||||
blade_menu
|
||||
WHERE
|
||||
category = 1
|
||||
AND is_deleted = 0
|
||||
AND id IN ( SELECT menu_id FROM blade_scope_data WHERE is_deleted = 0 AND menu_id IS NOT NULL )
|
||||
) menu
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
id,
|
||||
menu_id AS parent_id,
|
||||
scope_name AS title,
|
||||
id AS "value",
|
||||
id AS "key"
|
||||
FROM
|
||||
blade_scope_data
|
||||
WHERE
|
||||
is_deleted = 0
|
||||
AND menu_id IS NOT NULL
|
||||
</select>
|
||||
|
||||
<select id="grantApiScopeTree" resultMap="treeNodeResultMap">
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
id,
|
||||
parent_id,
|
||||
NAME AS title,
|
||||
id AS "value",
|
||||
id AS "key"
|
||||
FROM
|
||||
blade_menu
|
||||
WHERE
|
||||
category = 1
|
||||
AND is_deleted = 0
|
||||
AND id IN ( SELECT menu_id FROM blade_scope_api WHERE is_deleted = 0 AND menu_id IS NOT NULL )
|
||||
) menu
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
id,
|
||||
menu_id AS parent_id,
|
||||
scope_name AS title,
|
||||
id AS "value",
|
||||
id AS "key"
|
||||
FROM
|
||||
blade_scope_api
|
||||
WHERE
|
||||
is_deleted = 0
|
||||
AND menu_id IS NOT NULL
|
||||
</select>
|
||||
|
||||
<select id="grantDataScopeTreeByRole" resultMap="treeNodeResultMap">
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
id,
|
||||
parent_id,
|
||||
NAME AS title,
|
||||
id AS "value",
|
||||
id AS "key"
|
||||
FROM
|
||||
blade_menu
|
||||
WHERE
|
||||
category = 1
|
||||
AND is_deleted = 0
|
||||
AND id IN ( SELECT menu_id FROM blade_scope_data WHERE is_deleted = 0 AND menu_id IS NOT NULL )
|
||||
AND (
|
||||
id IN (
|
||||
select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
)
|
||||
OR id IN (
|
||||
select parent_id from blade_menu where is_deleted = 0
|
||||
and id in ( select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach> )
|
||||
)
|
||||
)
|
||||
) menu
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
id,
|
||||
menu_id AS parent_id,
|
||||
scope_name AS title,
|
||||
id AS "value",
|
||||
id AS "key"
|
||||
FROM
|
||||
blade_scope_data
|
||||
WHERE
|
||||
is_deleted = 0
|
||||
AND (
|
||||
menu_id IN (
|
||||
select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
)
|
||||
OR menu_id IN (
|
||||
select parent_id from blade_menu where is_deleted = 0
|
||||
and id in ( select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach> )
|
||||
)
|
||||
)
|
||||
AND menu_id IS NOT NULL
|
||||
</select>
|
||||
|
||||
<select id="grantApiScopeTreeByRole" resultMap="treeNodeResultMap">
|
||||
SELECT
|
||||
*
|
||||
FROM
|
||||
(
|
||||
SELECT
|
||||
id,
|
||||
parent_id,
|
||||
NAME AS title,
|
||||
id AS "value",
|
||||
id AS "key"
|
||||
FROM
|
||||
blade_menu
|
||||
WHERE
|
||||
category = 1
|
||||
AND is_deleted = 0
|
||||
AND id IN ( SELECT menu_id FROM blade_scope_api WHERE is_deleted = 0 AND menu_id IS NOT NULL )
|
||||
AND (
|
||||
id IN (
|
||||
select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
)
|
||||
OR id IN (
|
||||
select parent_id from blade_menu where is_deleted = 0
|
||||
and id in (
|
||||
select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach> )
|
||||
)
|
||||
)
|
||||
) menu
|
||||
|
||||
UNION ALL
|
||||
|
||||
SELECT
|
||||
id,
|
||||
menu_id AS parent_id,
|
||||
scope_name AS title,
|
||||
id AS "value",
|
||||
id AS "key"
|
||||
FROM
|
||||
blade_scope_api
|
||||
WHERE
|
||||
is_deleted = 0
|
||||
AND
|
||||
(
|
||||
menu_id IN (
|
||||
select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
)
|
||||
OR menu_id IN (
|
||||
select parent_id from blade_menu where is_deleted = 0
|
||||
and id in ( select menu_id from blade_role_menu where role_id in
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach> )
|
||||
)
|
||||
)
|
||||
AND menu_id IS NOT NULL
|
||||
</select>
|
||||
|
||||
<select id="authRoutes" resultType="org.springblade.auth.system.dto.MenuDTO">
|
||||
SELECT
|
||||
GROUP_CONCAT(r.role_alias) as alias,
|
||||
m.path
|
||||
FROM
|
||||
blade_role_menu rm
|
||||
LEFT JOIN blade_menu m ON rm.menu_id = m.id
|
||||
LEFT JOIN blade_role r ON rm.role_id = r.id
|
||||
WHERE
|
||||
rm.role_id IN
|
||||
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
AND m.path IS NOT NULL and m.is_deleted = 0
|
||||
GROUP BY m.path
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,51 @@
|
|||
package org.springblade.auth.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.auth.system.entity.Role;
|
||||
import org.springblade.auth.system.vo.RoleVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Mapper 接口
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface RoleMapper extends BaseMapper<Role> {
|
||||
|
||||
/**
|
||||
* 自定义分页
|
||||
*
|
||||
* @param page
|
||||
* @param role
|
||||
* @return
|
||||
*/
|
||||
List<RoleVO> selectRolePage(IPage page, RoleVO role);
|
||||
|
||||
/**
|
||||
* 获取树形节点
|
||||
*
|
||||
* @param tenantId
|
||||
* @param excludeRole
|
||||
* @return
|
||||
*/
|
||||
List<RoleVO> tree(String tenantId, String excludeRole);
|
||||
|
||||
/**
|
||||
* 获取角色名
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
List<String> getRoleNames(Long[] ids);
|
||||
|
||||
/**
|
||||
* 获取角色名
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
List<String> getRoleAliases(Long[] ids);
|
||||
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.springblade.auth.system.mapper.RoleMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="roleResultMap" type="org.springblade.auth.system.entity.Role">
|
||||
<id column="id" property="id"/>
|
||||
<result column="parent_id" property="parentId"/>
|
||||
<result column="role_name" property="roleName"/>
|
||||
<result column="sort" property="sort"/>
|
||||
<result column="role_alias" property="roleAlias"/>
|
||||
<result column="is_deleted" property="isDeleted"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="treeNodeResultMap" type="org.springblade.core.tool.node.TreeNode">
|
||||
<id column="id" property="id"/>
|
||||
<result column="parent_id" property="parentId"/>
|
||||
<result column="title" property="title"/>
|
||||
<result column="value" property="value"/>
|
||||
<result column="key" property="key"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectRolePage" resultMap="roleResultMap">
|
||||
select * from blade_role where is_deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="tree" resultMap="treeNodeResultMap">
|
||||
select id, parent_id, role_name as title, id as "value", id as "key" from blade_role where is_deleted = 0
|
||||
<if test="param1!=null">
|
||||
and tenant_id = #{param1}
|
||||
</if>
|
||||
<if test="param2!=null">
|
||||
and role_alias <> #{param2}
|
||||
</if>
|
||||
</select>
|
||||
|
||||
<select id="getRoleNames" resultType="java.lang.String">
|
||||
SELECT
|
||||
role_name
|
||||
FROM
|
||||
blade_role
|
||||
WHERE
|
||||
id IN
|
||||
<foreach collection="array" item="ids" index="index" open="(" close=")" separator=",">
|
||||
#{ids}
|
||||
</foreach>
|
||||
and is_deleted = 0
|
||||
</select>
|
||||
|
||||
<select id="getRoleAliases" resultType="java.lang.String">
|
||||
SELECT
|
||||
role_alias
|
||||
FROM
|
||||
blade_role
|
||||
WHERE
|
||||
id IN
|
||||
<foreach collection="array" item="ids" index="index" open="(" close=")" separator=",">
|
||||
#{ids}
|
||||
</foreach>
|
||||
and is_deleted = 0
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,25 @@
|
|||
package org.springblade.auth.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.auth.system.entity.RoleMenu;
|
||||
import org.springblade.auth.system.vo.RoleMenuVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Mapper 接口
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface RoleMenuMapper extends BaseMapper<RoleMenu> {
|
||||
|
||||
/**
|
||||
* 自定义分页
|
||||
* @param page
|
||||
* @param roleMenu
|
||||
* @return
|
||||
*/
|
||||
List<RoleMenuVO> selectRoleMenuPage(IPage page, RoleMenuVO roleMenu);
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.springblade.auth.system.mapper.RoleMenuMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="roleMenuResultMap" type="org.springblade.auth.system.entity.RoleMenu">
|
||||
<id column="id" property="id"/>
|
||||
<result column="menu_id" property="menuId"/>
|
||||
<result column="role_id" property="roleId"/>
|
||||
</resultMap>
|
||||
|
||||
<select id="selectRoleMenuPage" resultMap="roleMenuResultMap">
|
||||
select * from blade_role_menu where is_deleted = 0
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,37 @@
|
|||
package org.springblade.auth.system.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springblade.auth.system.entity.User;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Mapper 接口
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface UserMapper extends BaseMapper<User> {
|
||||
|
||||
/**
|
||||
* 自定义分页
|
||||
*
|
||||
* @param page
|
||||
* @param user
|
||||
* @param deptIdList
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
List<User> selectUserPage(IPage<User> page, @Param("user") User user, @Param("deptIdList") List<Long> deptIdList, @Param("tenantId") String tenantId);
|
||||
|
||||
/**
|
||||
* 获取用户
|
||||
*
|
||||
* @param tenantId
|
||||
* @param account
|
||||
* @return
|
||||
*/
|
||||
User getUser(String tenantId, String account);
|
||||
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="org.springblade.auth.system.mapper.UserMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="userResultMap" type="org.springblade.auth.system.entity.User">
|
||||
<result column="id" property="id"/>
|
||||
<result column="tenant_id" property="tenantId"/>
|
||||
<result column="create_user" property="createUser"/>
|
||||
<result column="create_time" property="createTime"/>
|
||||
<result column="update_user" property="updateUser"/>
|
||||
<result column="update_time" property="updateTime"/>
|
||||
<result column="status" property="status"/>
|
||||
<result column="is_deleted" property="isDeleted"/>
|
||||
<result column="code" property="code"/>
|
||||
<result column="user_type" property="userType"/>
|
||||
<result column="organization" property="organization"/>
|
||||
<result column="account" property="account"/>
|
||||
<result column="password" property="password"/>
|
||||
<result column="name" property="name"/>
|
||||
<result column="real_name" property="realName"/>
|
||||
<result column="email" property="email"/>
|
||||
<result column="phone" property="phone"/>
|
||||
<result column="role_id" property="roleId"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="Base_Column_List">
|
||||
id,tenant_id,code,user_type,organization,account,password,name,real_name,email,phone,role_id,
|
||||
create_user,create_dept,create_time,update_user,update_time,status,is_deleted
|
||||
</sql>
|
||||
|
||||
<select id="selectUserPage" resultMap="userResultMap">
|
||||
select
|
||||
<include refid="Base_Column_List"></include>
|
||||
from blade_user where is_deleted = 0
|
||||
<if test="tenantId!=null and tenantId != ''">
|
||||
and tenant_id = #{tenantId}
|
||||
</if>
|
||||
<if test="user.tenantId!=null and user.tenantId != ''">
|
||||
and tenant_id = #{user.tenantId}
|
||||
</if>
|
||||
<if test="user.account!=null and user.account != ''">
|
||||
and account = #{user.account}
|
||||
</if>
|
||||
<if test="user.realName!=null and user.realName != ''">
|
||||
and real_name = #{user.realName}
|
||||
</if>
|
||||
<if test="user.userType!=null and user.userType != ''">
|
||||
and user_type = #{user.userType}
|
||||
</if>
|
||||
<if test="user.postId!=null and user.postId != ''">
|
||||
and post_id like CONCAT('%',#{user.postId},'%')
|
||||
</if>
|
||||
<if test="user.notPostId!=null and user.notPostId != ''">
|
||||
and post_id not like CONCAT('%',#{user.notPostId},'%')
|
||||
</if>
|
||||
<if test="deptIdList!=null and deptIdList.size>0">
|
||||
and id in (
|
||||
SELECT
|
||||
user_id
|
||||
FROM
|
||||
blade_user_dept
|
||||
WHERE
|
||||
dept_id IN
|
||||
<foreach collection="deptIdList" index="index" item="item" open="(" separator="," close=")">
|
||||
#{item}
|
||||
</foreach>
|
||||
)
|
||||
</if>
|
||||
ORDER BY id
|
||||
</select>
|
||||
|
||||
<select id="getUser" resultMap="userResultMap">
|
||||
SELECT
|
||||
<include refid="Base_Column_List"></include>
|
||||
FROM
|
||||
blade_user
|
||||
WHERE
|
||||
tenant_id = #{param1} and (account = #{param2} or email = #{param2} or phone = #{param2}) and is_deleted = 0
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,85 @@
|
|||
package org.springblade.auth.system.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.auth.system.entity.DictBiz;
|
||||
import org.springblade.auth.system.vo.DictBizVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 服务类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface IDictBizService extends IService<DictBiz> {
|
||||
|
||||
/**
|
||||
* 树形结构
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<DictBizVO> tree();
|
||||
|
||||
/**
|
||||
* 树形结构
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<DictBizVO> parentTree();
|
||||
|
||||
/**
|
||||
* 获取字典表对应中文
|
||||
*
|
||||
* @param code 字典编号
|
||||
* @param dictKey 字典序号
|
||||
* @return
|
||||
*/
|
||||
String getValue(String code, String dictKey);
|
||||
|
||||
/**
|
||||
* 获取字典表
|
||||
*
|
||||
* @param code 字典编号
|
||||
* @return
|
||||
*/
|
||||
List<DictBiz> getList(String code);
|
||||
|
||||
/**
|
||||
* 新增或修改
|
||||
*
|
||||
* @param dict
|
||||
* @return
|
||||
*/
|
||||
boolean submit(DictBiz dict);
|
||||
|
||||
/**
|
||||
* 删除字典
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
boolean removeDict(String ids);
|
||||
|
||||
/**
|
||||
* 顶级列表
|
||||
*
|
||||
* @param dict
|
||||
* @param query
|
||||
* @return
|
||||
*/
|
||||
IPage<DictBizVO> parentList(Map<String, Object> dict, Query query);
|
||||
|
||||
/**
|
||||
* 子列表
|
||||
*
|
||||
* @param dict
|
||||
* @param parentId
|
||||
* @return
|
||||
*/
|
||||
List<DictBizVO> childList(Map<String, Object> dict, Long parentId);
|
||||
|
||||
}
|
|
@ -0,0 +1,101 @@
|
|||
package org.springblade.auth.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.springblade.core.secure.BladeUser;
|
||||
import org.springblade.core.tool.support.Kv;
|
||||
import org.springblade.auth.system.entity.Menu;
|
||||
import org.springblade.auth.system.vo.MenuVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 服务类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface IMenuService extends IService<Menu> {
|
||||
|
||||
/**
|
||||
* 懒加载列表
|
||||
*
|
||||
* @param parentId
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> lazyList(Long parentId, Map<String, Object> param);
|
||||
|
||||
/**
|
||||
* 懒加载菜单列表
|
||||
*
|
||||
* @param parentId
|
||||
* @param param
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> lazyMenuList(Long parentId, Map<String, Object> param);
|
||||
|
||||
/**
|
||||
* 菜单树形结构
|
||||
*
|
||||
* @param roleId
|
||||
* @param topMenuId
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> routes(String roleId, Long topMenuId);
|
||||
|
||||
/**
|
||||
* 按钮树形结构
|
||||
*
|
||||
* @param roleId
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> buttons(String roleId);
|
||||
|
||||
/**
|
||||
* 树形结构
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> tree();
|
||||
|
||||
/**
|
||||
* 授权树形结构
|
||||
*
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
List<MenuVO> grantTree(BladeUser user);
|
||||
|
||||
/**
|
||||
* 默认选中节点
|
||||
*
|
||||
* @param roleIds
|
||||
* @return
|
||||
*/
|
||||
List<String> roleTreeKeys(String roleIds);
|
||||
|
||||
/**
|
||||
* 获取配置的角色权限
|
||||
*
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
List<Kv> authRoutes(BladeUser user);
|
||||
|
||||
/**
|
||||
* 删除菜单
|
||||
*
|
||||
* @param ids
|
||||
* @return
|
||||
*/
|
||||
boolean removeMenu(String ids);
|
||||
|
||||
/**
|
||||
* 提交
|
||||
*
|
||||
* @param menu
|
||||
* @return
|
||||
*/
|
||||
boolean submit(Menu menu);
|
||||
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package org.springblade.auth.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.springblade.auth.system.entity.RoleMenu;
|
||||
|
||||
/**
|
||||
* 服务类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface IRoleMenuService extends IService<RoleMenu> {
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package org.springblade.auth.system.service;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import org.springblade.auth.system.entity.Role;
|
||||
import org.springblade.auth.system.vo.RoleVO;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服务类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface IRoleService extends IService<Role> {
|
||||
|
||||
/**
|
||||
* 自定义分页
|
||||
*
|
||||
* @param page
|
||||
* @param role
|
||||
* @return
|
||||
*/
|
||||
IPage<RoleVO> selectRolePage(IPage<RoleVO> page, RoleVO role);
|
||||
|
||||
/**
|
||||
* 树形结构
|
||||
*
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
List<RoleVO> tree(String tenantId);
|
||||
|
||||
/**
|
||||
* 获取角色ID
|
||||
*
|
||||
* @param tenantId
|
||||
* @param roleNames
|
||||
* @return
|
||||
*/
|
||||
String getRoleIds(String tenantId, String roleNames);
|
||||
|
||||
/**
|
||||
* 获取角色名
|
||||
*
|
||||
* @param roleIds
|
||||
* @return
|
||||
*/
|
||||
List<String> getRoleNames(String roleIds);
|
||||
|
||||
/**
|
||||
* 获取角色名
|
||||
*
|
||||
* @param roleIds
|
||||
* @return
|
||||
*/
|
||||
List<String> getRoleAliases(String roleIds);
|
||||
|
||||
/**
|
||||
* 提交
|
||||
*
|
||||
* @param role
|
||||
* @return
|
||||
*/
|
||||
boolean submit(Role role);
|
||||
|
||||
/**
|
||||
* 角色信息查询
|
||||
*
|
||||
* @param roleName
|
||||
* @param parentId
|
||||
* @return
|
||||
*/
|
||||
List<RoleVO> search(String roleName, Long parentId);
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
package org.springblade.auth.system.service;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import org.springblade.auth.system.entity.User;
|
||||
import org.springblade.auth.system.entity.UserInfo;
|
||||
import org.springblade.auth.system.vo.UserVO;
|
||||
import org.springblade.core.mp.base.BaseService;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
|
||||
/**
|
||||
* 服务类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public interface IUserService extends BaseService<User> {
|
||||
|
||||
/**
|
||||
* 新增用户
|
||||
*
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
boolean submit(User user);
|
||||
|
||||
/**
|
||||
* 修改用户
|
||||
*
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
boolean updateUser(User user);
|
||||
|
||||
/**
|
||||
* 修改用户基本信息
|
||||
*
|
||||
* @param user
|
||||
* @return
|
||||
*/
|
||||
boolean updateUserInfo(User user);
|
||||
|
||||
/**
|
||||
* 自定义分页
|
||||
*
|
||||
* @param page
|
||||
* @param user
|
||||
* @param deptId
|
||||
* @param tenantId
|
||||
* @return
|
||||
*/
|
||||
IPage<User> selectUserPage(IPage<User> page, User user, Long deptId, String tenantId);
|
||||
|
||||
/**
|
||||
* 自定义分页
|
||||
*
|
||||
* @param user
|
||||
* @param query
|
||||
* @return
|
||||
*/
|
||||
IPage<UserVO> selectUserSearch(UserVO user, Query query);
|
||||
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*
|
||||
* @param userId
|
||||
* @return
|
||||
*/
|
||||
UserInfo userInfo(Long userId);
|
||||
|
||||
/**
|
||||
* 用户信息
|
||||
*
|
||||
* @param tenantId
|
||||
* @param account
|
||||
* @return
|
||||
*/
|
||||
UserInfo userInfo(String tenantId, String account);
|
||||
|
||||
/**
|
||||
* 根据账号获取用户
|
||||
*
|
||||
* @param tenantId
|
||||
* @param account
|
||||
* @return
|
||||
*/
|
||||
User userByAccount(String tenantId, String account);
|
||||
|
||||
/**
|
||||
* 给用户设置角色
|
||||
*
|
||||
* @param userIds
|
||||
* @param roleIds
|
||||
* @return
|
||||
*/
|
||||
boolean grant(String userIds, String roleIds);
|
||||
|
||||
/**
|
||||
* 初始化密码
|
||||
*
|
||||
* @param userIds
|
||||
* @return
|
||||
*/
|
||||
boolean resetPassword(String userIds);
|
||||
|
||||
/**
|
||||
* 修改密码
|
||||
*
|
||||
* @param userId
|
||||
* @param oldPassword
|
||||
* @param newPassword
|
||||
* @param newPassword1
|
||||
* @return
|
||||
*/
|
||||
boolean updatePassword(Long userId, String oldPassword, String newPassword, String newPassword1);
|
||||
|
||||
/**
|
||||
* 删除用户
|
||||
*
|
||||
* @param userIds
|
||||
* @return
|
||||
*/
|
||||
boolean removeUser(String userIds);
|
||||
|
||||
}
|
|
@ -0,0 +1,118 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springblade.common.constant.CommonConstant;
|
||||
import org.springblade.core.cache.utils.CacheUtil;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.node.ForestNodeMerger;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.core.tool.utils.StringPool;
|
||||
import org.springblade.auth.system.cache.DictBizCache;
|
||||
import org.springblade.auth.system.entity.DictBiz;
|
||||
import org.springblade.auth.system.mapper.DictBizMapper;
|
||||
import org.springblade.auth.system.service.IDictBizService;
|
||||
import org.springblade.auth.system.vo.DictBizVO;
|
||||
import org.springblade.auth.system.wrapper.DictBizWrapper;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.springblade.core.cache.constant.CacheConstant.DICT_CACHE;
|
||||
|
||||
/**
|
||||
* 服务实现类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
public class DictBizServiceImpl extends ServiceImpl<DictBizMapper, DictBiz> implements IDictBizService {
|
||||
|
||||
@Override
|
||||
public List<DictBizVO> tree() {
|
||||
return ForestNodeMerger.merge(baseMapper.tree());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictBizVO> parentTree() {
|
||||
return ForestNodeMerger.merge(baseMapper.parentTree());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getValue(String code, String dictKey) {
|
||||
return Func.toStr(baseMapper.getValue(code, dictKey), StringPool.EMPTY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictBiz> getList(String code) {
|
||||
return baseMapper.getList(code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean submit(DictBiz dict) {
|
||||
LambdaQueryWrapper<DictBiz> lqw = Wrappers.<DictBiz>query().lambda().eq(DictBiz::getCode, dict.getCode()).eq(DictBiz::getDictKey, dict.getDictKey());
|
||||
Integer cnt = baseMapper.selectCount((Func.isEmpty(dict.getId())) ? lqw : lqw.notIn(DictBiz::getId, dict.getId()));
|
||||
if (cnt > 0) {
|
||||
throw new RuntimeException("当前字典键值已存在!");
|
||||
}
|
||||
// 修改顶级字典后同步更新下属字典的编号
|
||||
if (Func.isNotEmpty(dict.getId()) && dict.getParentId().longValue() == BladeConstant.TOP_PARENT_ID) {
|
||||
DictBiz parent = DictBizCache.getById(dict.getId());
|
||||
this.update(Wrappers.<DictBiz>update().lambda().set(DictBiz::getCode, dict.getCode()).eq(DictBiz::getCode, parent.getCode()).ne(DictBiz::getParentId, BladeConstant.TOP_PARENT_ID));
|
||||
}
|
||||
if (Func.isEmpty(dict.getParentId())) {
|
||||
dict.setParentId(BladeConstant.TOP_PARENT_ID);
|
||||
}
|
||||
dict.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
||||
CacheUtil.clear(DICT_CACHE);
|
||||
return saveOrUpdate(dict);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeDict(String ids) {
|
||||
Integer cnt = baseMapper.selectCount(Wrappers.<DictBiz>query().lambda().in(DictBiz::getParentId, Func.toLongList(ids)));
|
||||
if (cnt > 0) {
|
||||
throw new RuntimeException("请先删除子节点!");
|
||||
}
|
||||
return removeByIds(Func.toLongList(ids));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<DictBizVO> parentList(Map<String, Object> dict, Query query) {
|
||||
IPage<DictBiz> page = this.page(Condition.getPage(query), Condition.getQueryWrapper(dict, DictBiz.class).lambda().eq(DictBiz::getParentId, CommonConstant.TOP_PARENT_ID).orderByAsc(DictBiz::getSort));
|
||||
return DictBizWrapper.build().pageVO(page);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DictBizVO> childList(Map<String, Object> dict, Long parentId) {
|
||||
if (parentId < 0) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
dict.remove("parentId");
|
||||
DictBiz parentDict = DictBizCache.getById(parentId);
|
||||
List<DictBiz> list = this.list(Condition.getQueryWrapper(dict, DictBiz.class).lambda().ne(DictBiz::getId, parentId).eq(DictBiz::getCode, parentDict.getCode()).orderByAsc(DictBiz::getSort));
|
||||
return DictBizWrapper.build().listNodeVO(list);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,187 @@
|
|||
package org.springblade.auth.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.auth.system.dto.MenuDTO;
|
||||
import org.springblade.auth.system.entity.Menu;
|
||||
import org.springblade.auth.system.entity.RoleMenu;
|
||||
import org.springblade.auth.system.mapper.MenuMapper;
|
||||
import org.springblade.auth.system.service.IMenuService;
|
||||
import org.springblade.auth.system.service.IRoleMenuService;
|
||||
import org.springblade.auth.system.vo.MenuVO;
|
||||
import org.springblade.auth.system.wrapper.MenuWrapper;
|
||||
import org.springblade.core.secure.BladeUser;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.node.ForestNodeMerger;
|
||||
import org.springblade.core.tool.support.Kv;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springframework.cache.annotation.Cacheable;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static org.springblade.core.cache.constant.CacheConstant.MENU_CACHE;
|
||||
|
||||
/**
|
||||
* 服务实现类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
@AllArgsConstructor
|
||||
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements IMenuService {
|
||||
|
||||
private final IRoleMenuService roleMenuService;
|
||||
private final static String PARENT_ID = "parentId";
|
||||
private final static Integer MENU_CATEGORY = 1;
|
||||
|
||||
@Override
|
||||
public List<MenuVO> lazyList(Long parentId, Map<String, Object> param) {
|
||||
if (Func.isEmpty(Func.toStr(param.get(PARENT_ID)))) {
|
||||
parentId = null;
|
||||
}
|
||||
return baseMapper.lazyList(parentId, param);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuVO> lazyMenuList(Long parentId, Map<String, Object> param) {
|
||||
if (Func.isEmpty(Func.toStr(param.get(PARENT_ID)))) {
|
||||
parentId = null;
|
||||
}
|
||||
return baseMapper.lazyMenuList(parentId, param);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<MenuVO> routes(String roleId, Long topMenuId) {
|
||||
if (StringUtil.isBlank(roleId)) {
|
||||
return null;
|
||||
}
|
||||
List<Menu> allMenus = baseMapper.allMenu();
|
||||
List<Menu> roleMenus;
|
||||
// 超级管理员并且不是顶部菜单请求则返回全部菜单
|
||||
if (AuthUtil.isAdministrator() && Func.isEmpty(topMenuId)) {
|
||||
roleMenus = allMenus;
|
||||
}
|
||||
// 非超级管理员并且不是顶部菜单请求则返回对应角色权限菜单
|
||||
else if (!AuthUtil.isAdministrator() && Func.isEmpty(topMenuId)) {
|
||||
roleMenus = baseMapper.roleMenuByRoleId(Func.toLongList(roleId));
|
||||
}
|
||||
// 顶部菜单请求返回对应角色权限菜单
|
||||
else {
|
||||
// 角色配置对应菜单
|
||||
List<Menu> roleIdMenus = baseMapper.roleMenuByRoleId(Func.toLongList(roleId));
|
||||
// 反向递归角色菜单所有父级
|
||||
List<Menu> routes = new LinkedList<>(roleIdMenus);
|
||||
roleIdMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu));
|
||||
// 顶部配置对应菜单
|
||||
List<Menu> topIdMenus = baseMapper.roleMenuByTopMenuId(topMenuId);
|
||||
// 筛选匹配角色对应的权限菜单
|
||||
roleMenus = topIdMenus.stream().filter(x ->
|
||||
routes.stream().anyMatch(route -> route.getId().longValue() == x.getId().longValue())
|
||||
).collect(Collectors.toList());
|
||||
}
|
||||
return buildRoutes(allMenus, roleMenus);
|
||||
}
|
||||
|
||||
private List<MenuVO> buildRoutes(List<Menu> allMenus, List<Menu> roleMenus) {
|
||||
List<Menu> routes = new LinkedList<>(roleMenus);
|
||||
roleMenus.forEach(roleMenu -> recursion(allMenus, routes, roleMenu));
|
||||
routes.sort(Comparator.comparing(Menu::getSort));
|
||||
MenuWrapper menuWrapper = new MenuWrapper();
|
||||
List<Menu> collect = routes.stream().filter(x -> Func.equals(x.getCategory(), 1)).collect(Collectors.toList());
|
||||
return menuWrapper.listNodeVO(collect);
|
||||
}
|
||||
|
||||
private void recursion(List<Menu> allMenus, List<Menu> routes, Menu roleMenu) {
|
||||
Optional<Menu> menu = allMenus.stream().filter(x -> Func.equals(x.getId(), roleMenu.getParentId())).findFirst();
|
||||
if (menu.isPresent() && !routes.contains(menu.get())) {
|
||||
routes.add(menu.get());
|
||||
recursion(allMenus, routes, menu.get());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuVO> buttons(String roleId) {
|
||||
List<Menu> buttons = (AuthUtil.isAdministrator()) ? baseMapper.allButtons() : baseMapper.buttons(Func.toLongList(roleId));
|
||||
MenuWrapper menuWrapper = new MenuWrapper();
|
||||
return menuWrapper.listNodeVO(buttons);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuVO> tree() {
|
||||
return ForestNodeMerger.merge(baseMapper.tree());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<MenuVO> grantTree(BladeUser user) {
|
||||
return ForestNodeMerger.merge(user.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID) ? baseMapper.grantTree() : baseMapper.grantTreeByRole(Func.toLongList(user.getRoleId())));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> roleTreeKeys(String roleIds) {
|
||||
List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.<RoleMenu>query().lambda().in(RoleMenu::getRoleId, Func.toLongList(roleIds)));
|
||||
return roleMenus.stream().map(roleMenu -> Func.toStr(roleMenu.getMenuId())).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
@Cacheable(cacheNames = MENU_CACHE, key = "'auth:routes:' + #user.roleId")
|
||||
public List<Kv> authRoutes(BladeUser user) {
|
||||
List<MenuDTO> routes = baseMapper.authRoutes(Func.toLongList(user.getRoleId()));
|
||||
List<Kv> list = new ArrayList<>();
|
||||
routes.forEach(route -> list.add(Kv.create().set(route.getPath(), Kv.create().set("authority", Func.toStrArray(route.getAlias())))));
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeMenu(String ids) {
|
||||
Integer cnt = baseMapper.selectCount(Wrappers.<Menu>query().lambda().in(Menu::getParentId, Func.toLongList(ids)));
|
||||
if (cnt > 0) {
|
||||
throw new RuntimeException("请先删除子节点!");
|
||||
}
|
||||
return removeByIds(Func.toLongList(ids));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean submit(Menu menu) {
|
||||
LambdaQueryWrapper<Menu> menuQueryWrapper = Wrappers.lambdaQuery();
|
||||
if (menu.getId() == null) {
|
||||
menuQueryWrapper.eq(Menu::getCode, menu.getCode()).or(
|
||||
wrapper -> wrapper.eq(Menu::getName, menu.getName()).eq(Menu::getCategory, MENU_CATEGORY)
|
||||
);
|
||||
} else {
|
||||
menuQueryWrapper.ne(Menu::getId, menu.getId()).and(
|
||||
wrapper -> wrapper.eq(Menu::getCode, menu.getCode()).or(
|
||||
o -> o.eq(Menu::getName, menu.getName()).eq(Menu::getCategory, MENU_CATEGORY)
|
||||
)
|
||||
);
|
||||
}
|
||||
Integer cnt = baseMapper.selectCount(menuQueryWrapper);
|
||||
if (cnt > 0) {
|
||||
throw new RuntimeException("菜单名或编号已存在!");
|
||||
}
|
||||
if (menu.getParentId() == null && menu.getId() == null) {
|
||||
menu.setParentId(BladeConstant.TOP_PARENT_ID);
|
||||
}
|
||||
if (menu.getParentId() != null && menu.getId() == null) {
|
||||
Menu parentMenu = baseMapper.selectById(menu.getParentId());
|
||||
if (parentMenu != null && parentMenu.getCategory() != 1) {
|
||||
throw new RuntimeException("父节点只可选择菜单类型!");
|
||||
}
|
||||
}
|
||||
menu.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
||||
return saveOrUpdate(menu);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package org.springblade.auth.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springblade.auth.system.entity.RoleMenu;
|
||||
import org.springblade.auth.system.mapper.RoleMenuMapper;
|
||||
import org.springblade.auth.system.service.IRoleMenuService;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
/**
|
||||
* 服务实现类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements IRoleMenuService {
|
||||
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
package org.springblade.auth.system.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import lombok.AllArgsConstructor;
|
||||
import org.springblade.auth.system.entity.Role;
|
||||
import org.springblade.auth.system.entity.RoleMenu;
|
||||
import org.springblade.auth.system.mapper.RoleMapper;
|
||||
import org.springblade.auth.system.service.IRoleMenuService;
|
||||
import org.springblade.auth.system.service.IRoleService;
|
||||
import org.springblade.auth.system.vo.RoleVO;
|
||||
import org.springblade.auth.system.wrapper.RoleWrapper;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.constant.RoleConstant;
|
||||
import org.springblade.core.tool.node.ForestNodeMerger;
|
||||
import org.springblade.core.tool.utils.CollectionUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 服务实现类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
@Validated
|
||||
@AllArgsConstructor
|
||||
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {
|
||||
|
||||
private final IRoleMenuService roleMenuService;
|
||||
|
||||
@Override
|
||||
public IPage<RoleVO> selectRolePage(IPage<RoleVO> page, RoleVO role) {
|
||||
return page.setRecords(baseMapper.selectRolePage(page, role));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleVO> tree(String tenantId) {
|
||||
String userRole = AuthUtil.getUserRole();
|
||||
String excludeRole = null;
|
||||
if (!CollectionUtil.contains(Func.toStrArray(userRole), RoleConstant.ADMIN) && !CollectionUtil.contains(Func.toStrArray(userRole), RoleConstant.ADMINISTRATOR)) {
|
||||
excludeRole = RoleConstant.ADMINISTRATOR;
|
||||
}
|
||||
return ForestNodeMerger.merge(baseMapper.tree(tenantId, excludeRole));
|
||||
}
|
||||
|
||||
private boolean grantRoleMenu(List<Long> roleIds, List<Long> menuIds) {
|
||||
// 防止越权配置超管角色
|
||||
int administratorCount = baseMapper.selectCount(Wrappers.<Role>query().lambda().eq(Role::getRoleAlias, RoleConstant.ADMINISTRATOR).in(Role::getId, roleIds));
|
||||
if (!AuthUtil.isAdministrator() && administratorCount > 0) {
|
||||
throw new RuntimeException("无权配置超管角色!");
|
||||
}
|
||||
// 防止越权配置管理员角色
|
||||
//int adminCount = baseMapper.selectCount(Wrappers.<Role>query().lambda().eq(Role::getRoleAlias, RoleConstant.ADMIN).in(Role::getId, roleIds));
|
||||
//if (!AuthUtil.isAdmin() && adminCount > 0) {
|
||||
// throw new ServiceException("无权配置管理员角色!");
|
||||
// }
|
||||
// 删除角色配置的菜单集合
|
||||
roleMenuService.remove(Wrappers.<RoleMenu>update().lambda().in(RoleMenu::getRoleId, roleIds));
|
||||
// 组装配置
|
||||
List<RoleMenu> roleMenus = new ArrayList<>();
|
||||
roleIds.forEach(roleId -> menuIds.forEach(menuId -> {
|
||||
RoleMenu roleMenu = new RoleMenu();
|
||||
roleMenu.setRoleId(roleId);
|
||||
roleMenu.setMenuId(menuId);
|
||||
roleMenus.add(roleMenu);
|
||||
}));
|
||||
// 新增配置
|
||||
roleMenuService.saveBatch(roleMenus);
|
||||
// 递归设置下属角色菜单集合
|
||||
recursionRoleMenu(roleIds, menuIds);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void recursionRoleMenu(List<Long> roleIds, List<Long> menuIds) {
|
||||
roleIds.forEach(roleId -> baseMapper.selectList(Wrappers.<Role>query().lambda().eq(Role::getParentId, roleId)).forEach(role -> {
|
||||
List<RoleMenu> roleMenuList = roleMenuService.list(Wrappers.<RoleMenu>query().lambda().eq(RoleMenu::getRoleId, role.getId()));
|
||||
// 子节点过滤出父节点删除的菜单集合
|
||||
List<Long> collectRoleMenuIds = roleMenuList.stream().map(RoleMenu::getMenuId).filter(menuId -> !menuIds.contains(menuId)).collect(Collectors.toList());
|
||||
if (collectRoleMenuIds.size() > 0) {
|
||||
// 删除子节点权限外的菜单集合
|
||||
roleMenuService.remove(Wrappers.<RoleMenu>update().lambda().eq(RoleMenu::getRoleId, role.getId()).in(RoleMenu::getMenuId, collectRoleMenuIds));
|
||||
// 递归设置下属角色菜单集合
|
||||
recursionRoleMenu(Collections.singletonList(role.getId()), menuIds);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getRoleIds(String tenantId, String roleNames) {
|
||||
List<Role> roleList = baseMapper.selectList(Wrappers.<Role>query().lambda().eq(Role::getTenantId, tenantId).in(Role::getRoleName, Func.toStrList(roleNames)));
|
||||
if (roleList != null && roleList.size() > 0) {
|
||||
return roleList.stream().map(role -> Func.toStr(role.getId())).distinct().collect(Collectors.joining(","));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRoleNames(String roleIds) {
|
||||
return baseMapper.getRoleNames(Func.toLongArray(roleIds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getRoleAliases(String roleIds) {
|
||||
return baseMapper.getRoleAliases(Func.toLongArray(roleIds));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean submit(Role role) {
|
||||
if (!AuthUtil.isAdministrator()) {
|
||||
if (Func.toStr(role.getRoleAlias()).equals(RoleConstant.ADMINISTRATOR)) {
|
||||
throw new RuntimeException("无权限创建超管角色!");
|
||||
}
|
||||
}
|
||||
if (Func.isEmpty(role.getParentId())) {
|
||||
role.setTenantId(AuthUtil.getTenantId());
|
||||
role.setParentId(BladeConstant.TOP_PARENT_ID);
|
||||
}
|
||||
if (role.getParentId() > 0) {
|
||||
Role parent = getById(role.getParentId());
|
||||
if (Func.toLong(role.getParentId()) == Func.toLong(role.getId())) {
|
||||
throw new RuntimeException("父节点不可选择自身!");
|
||||
}
|
||||
role.setTenantId(parent.getTenantId());
|
||||
}
|
||||
role.setIsDeleted(BladeConstant.DB_NOT_DELETED);
|
||||
return saveOrUpdate(role);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RoleVO> search(String roleName, Long parentId) {
|
||||
LambdaQueryWrapper<Role> queryWrapper = Wrappers.<Role>query().lambda();
|
||||
if (Func.isNotEmpty(roleName)) {
|
||||
queryWrapper.like(Role::getRoleName, roleName);
|
||||
}
|
||||
if (Func.isNotEmpty(parentId) && parentId > 0L) {
|
||||
queryWrapper.eq(Role::getParentId, parentId);
|
||||
}
|
||||
List<Role> roleList = baseMapper.selectList(queryWrapper);
|
||||
return RoleWrapper.build().listNodeVO(roleList);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,159 @@
|
|||
package org.springblade.auth.system.service.impl;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springblade.auth.system.cache.SysCache;
|
||||
import org.springblade.auth.system.entity.User;
|
||||
import org.springblade.auth.system.entity.UserInfo;
|
||||
import org.springblade.auth.system.mapper.UserMapper;
|
||||
import org.springblade.auth.system.service.IRoleService;
|
||||
import org.springblade.auth.system.service.IUserService;
|
||||
import org.springblade.auth.system.vo.UserVO;
|
||||
import org.springblade.auth.system.wrapper.UserWrapper;
|
||||
import org.springblade.common.constant.CommonConstant;
|
||||
import org.springblade.core.mp.base.BaseServiceImpl;
|
||||
import org.springblade.core.mp.support.Condition;
|
||||
import org.springblade.core.mp.support.Query;
|
||||
import org.springblade.core.secure.utils.AuthUtil;
|
||||
import org.springblade.core.tenant.BladeTenantProperties;
|
||||
import org.springblade.core.tool.api.R;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.support.Kv;
|
||||
import org.springblade.core.tool.utils.DateUtil;
|
||||
import org.springblade.core.tool.utils.DigestUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.core.tool.utils.StringUtil;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 服务实现类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implements IUserService {
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean submit(User user) {
|
||||
if (StringUtil.isBlank(user.getTenantId())) {
|
||||
user.setTenantId(BladeConstant.ADMIN_TENANT_ID);
|
||||
}
|
||||
if (Func.isNotEmpty(user.getPassword())) {
|
||||
user.setPassword(DigestUtil.encrypt(user.getPassword()));
|
||||
}
|
||||
Integer userCount = baseMapper.selectCount(Wrappers.<User>query().lambda().eq(User::getTenantId, user.getTenantId()).eq(User::getAccount, user.getAccount()));
|
||||
if (userCount > 0 && Func.isEmpty(user.getId())) {
|
||||
throw new RuntimeException(StringUtil.format("当前用户 [{}] 已存在!", user.getAccount()));
|
||||
}
|
||||
return save(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public boolean updateUser(User user) {
|
||||
String tenantId = user.getTenantId();
|
||||
Integer userCount = baseMapper.selectCount(
|
||||
Wrappers.<User>query().lambda()
|
||||
.eq(User::getTenantId, tenantId)
|
||||
.eq(User::getAccount, user.getAccount())
|
||||
.notIn(User::getId, user.getId())
|
||||
);
|
||||
if (userCount > 0) {
|
||||
throw new RuntimeException(StringUtil.format("当前用户 [{}] 已存在!", user.getAccount()));
|
||||
}
|
||||
return updateUserInfo(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateUserInfo(User user) {
|
||||
user.setPassword(null);
|
||||
return updateById(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<User> selectUserPage(IPage<User> page, User user, Long deptId, String tenantId) {
|
||||
return page.setRecords(baseMapper.selectUserPage(page, user, null, tenantId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public IPage<UserVO> selectUserSearch(UserVO user, Query query) {
|
||||
LambdaQueryWrapper<User> queryWrapper = Wrappers.<User>query().lambda();
|
||||
if (StringUtil.isNotBlank(user.getName())) {
|
||||
queryWrapper.like(User::getName, user.getName());
|
||||
}
|
||||
IPage<User> pages = this.page(Condition.getPage(query), queryWrapper);
|
||||
return UserWrapper.build().pageVO(pages);
|
||||
}
|
||||
|
||||
@Override
|
||||
public User userByAccount(String tenantId, String account) {
|
||||
return baseMapper.selectOne(Wrappers.<User>query().lambda().eq(User::getTenantId, tenantId).eq(User::getAccount, account).eq(User::getIsDeleted, BladeConstant.DB_NOT_DELETED));
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserInfo userInfo(Long userId) {
|
||||
User user = baseMapper.selectById(userId);
|
||||
return buildUserInfo(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserInfo userInfo(String tenantId, String account) {
|
||||
User user = baseMapper.getUser(tenantId, account);
|
||||
return buildUserInfo(user);
|
||||
}
|
||||
|
||||
private UserInfo buildUserInfo(User user) {
|
||||
UserInfo userInfo = new UserInfo();
|
||||
userInfo.setUser(user);
|
||||
if (Func.isNotEmpty(user)) {
|
||||
userInfo.setRoles(SysCache.getRoleAliases(user.getRoleId()));
|
||||
}
|
||||
userInfo.setDetail(Kv.create().set("type", "web"));
|
||||
return userInfo;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean grant(String userIds, String roleIds) {
|
||||
User user = new User();
|
||||
user.setRoleId(roleIds);
|
||||
return this.update(user, Wrappers.<User>update().lambda().in(User::getId, Func.toLongList(userIds)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean resetPassword(String userIds) {
|
||||
User user = new User();
|
||||
user.setPassword(DigestUtil.encrypt(CommonConstant.DEFAULT_PASSWORD));
|
||||
user.setUpdateTime(DateUtil.now());
|
||||
return this.update(user, Wrappers.<User>update().lambda().in(User::getId, Func.toLongList(userIds)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updatePassword(Long userId, String oldPassword, String newPassword, String newPassword1) {
|
||||
User user = getById(userId);
|
||||
if (!newPassword.equals(newPassword1)) {
|
||||
throw new RuntimeException("请输入正确的确认密码!");
|
||||
}
|
||||
if (!user.getPassword().equals(DigestUtil.hex(oldPassword))) {
|
||||
throw new RuntimeException("原密码不正确!");
|
||||
}
|
||||
return this.update(Wrappers.<User>update().lambda().set(User::getPassword, DigestUtil.hex(newPassword)).eq(User::getId, userId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeUser(String userIds) {
|
||||
if (Func.contains(Func.toLongArray(userIds), AuthUtil.getUserId())) {
|
||||
throw new RuntimeException("不能删除本账号!");
|
||||
}
|
||||
return deleteLogic(Func.toLongList(userIds));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.springblade.auth.system.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tool.node.INode;
|
||||
import org.springblade.auth.system.entity.DictBiz;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 视图实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel(value = "DictBizVO对象", description = "DictBizVO对象")
|
||||
public class DictBizVO extends DictBiz implements INode<DictBizVO> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 父节点ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 子孙节点
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private List<DictBizVO> children;
|
||||
|
||||
@Override
|
||||
public List<DictBizVO> getChildren() {
|
||||
if (this.children == null) {
|
||||
this.children = new ArrayList<>();
|
||||
}
|
||||
return this.children;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上级字典
|
||||
*/
|
||||
private String parentName;
|
||||
}
|
|
@ -0,0 +1,62 @@
|
|||
package org.springblade.auth.system.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tool.node.INode;
|
||||
import org.springblade.auth.system.entity.Menu;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 视图实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel(value = "MenuVO对象", description = "MenuVO对象")
|
||||
public class MenuVO extends Menu implements INode<MenuVO> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
/**
|
||||
* 子孙节点
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private List<MenuVO> children;
|
||||
|
||||
/**
|
||||
* 是否有子孙节点
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private Boolean hasChildren;
|
||||
|
||||
@Override
|
||||
public List<MenuVO> getChildren() {
|
||||
if (this.children == null) {
|
||||
this.children = new ArrayList<>();
|
||||
}
|
||||
return this.children;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上级菜单
|
||||
*/
|
||||
private String parentName;
|
||||
|
||||
/**
|
||||
* 菜单类型
|
||||
*/
|
||||
private String categoryName;
|
||||
|
||||
/**
|
||||
* 按钮功能
|
||||
*/
|
||||
private String actionName;
|
||||
|
||||
/**
|
||||
* 是否新窗口打开
|
||||
*/
|
||||
private String isOpenName;
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.springblade.auth.system.vo;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.auth.system.entity.RoleMenu;
|
||||
|
||||
/**
|
||||
* 视图实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel(value = "RoleMenuVO对象", description = "RoleMenuVO对象")
|
||||
public class RoleMenuVO extends RoleMenu {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.core.tool.node.INode;
|
||||
import org.springblade.auth.system.entity.Role;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 视图实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel(value = "RoleVO对象", description = "RoleVO对象")
|
||||
public class RoleVO extends Role implements INode<RoleVO> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 父节点ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long parentId;
|
||||
|
||||
/**
|
||||
* 子孙节点
|
||||
*/
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY)
|
||||
private List<RoleVO> children;
|
||||
|
||||
@Override
|
||||
public List<RoleVO> getChildren() {
|
||||
if (this.children == null) {
|
||||
this.children = new ArrayList<>();
|
||||
}
|
||||
return this.children;
|
||||
}
|
||||
|
||||
/**
|
||||
* 上级角色
|
||||
*/
|
||||
private String parentName;
|
||||
}
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import org.springblade.auth.system.entity.User;
|
||||
|
||||
/**
|
||||
* 视图实体类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@ApiModel(value = "UserVO对象", description = "UserVO对象")
|
||||
public class UserVO extends User {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* 主键ID
|
||||
*/
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@JsonIgnore
|
||||
private String password;
|
||||
|
||||
/**
|
||||
* 租户名
|
||||
*/
|
||||
private String tenantName;
|
||||
|
||||
/**
|
||||
* 角色名
|
||||
*/
|
||||
private String roleName;
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package org.springblade.auth.system.wrapper;
|
||||
|
||||
import org.springblade.core.mp.support.BaseEntityWrapper;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.node.ForestNodeMerger;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.auth.system.cache.DictBizCache;
|
||||
import org.springblade.auth.system.entity.DictBiz;
|
||||
import org.springblade.auth.system.vo.DictBizVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
||||
/**
|
||||
* 包装类,返回视图层所需的字段
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class DictBizWrapper extends BaseEntityWrapper<DictBiz, DictBizVO> {
|
||||
|
||||
public static DictBizWrapper build() {
|
||||
return new DictBizWrapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DictBizVO entityVO(DictBiz dict) {
|
||||
DictBizVO dictVO = Objects.requireNonNull(BeanUtil.copy(dict, DictBizVO.class));
|
||||
if (Func.equals(dict.getParentId(), BladeConstant.TOP_PARENT_ID)) {
|
||||
dictVO.setParentName(BladeConstant.TOP_PARENT_NAME);
|
||||
} else {
|
||||
DictBiz parent = DictBizCache.getById(dict.getParentId());
|
||||
dictVO.setParentName(parent.getDictValue());
|
||||
}
|
||||
return dictVO;
|
||||
}
|
||||
|
||||
public List<DictBizVO> listNodeVO(List<DictBiz> list) {
|
||||
List<DictBizVO> collect = list.stream().map(dict -> BeanUtil.copy(dict, DictBizVO.class)).collect(Collectors.toList());
|
||||
return ForestNodeMerger.merge(collect);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.system.wrapper;
|
||||
|
||||
import org.springblade.core.mp.support.BaseEntityWrapper;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.node.ForestNodeMerger;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.auth.system.cache.SysCache;
|
||||
import org.springblade.auth.system.entity.Menu;
|
||||
import org.springblade.auth.system.vo.MenuVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 包装类,返回视图层所需的字段
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class MenuWrapper extends BaseEntityWrapper<Menu, MenuVO> {
|
||||
|
||||
public static MenuWrapper build() {
|
||||
return new MenuWrapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MenuVO entityVO(Menu menu) {
|
||||
MenuVO menuVO = Objects.requireNonNull(BeanUtil.copy(menu, MenuVO.class));
|
||||
if (Func.equals(menu.getParentId(), BladeConstant.TOP_PARENT_ID)) {
|
||||
menuVO.setParentName(BladeConstant.TOP_PARENT_NAME);
|
||||
} else {
|
||||
Menu parent = SysCache.getMenu(menu.getParentId());
|
||||
menuVO.setParentName(parent.getName());
|
||||
}
|
||||
return menuVO;
|
||||
}
|
||||
|
||||
public List<MenuVO> listNodeVO(List<Menu> list) {
|
||||
List<MenuVO> collect = list.stream().map(menu -> BeanUtil.copy(menu, MenuVO.class)).collect(Collectors.toList());
|
||||
return ForestNodeMerger.merge(collect);
|
||||
}
|
||||
|
||||
public List<MenuVO> listNodeLazyVO(List<MenuVO> list) {
|
||||
return ForestNodeMerger.merge(list);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package org.springblade.auth.system.wrapper;
|
||||
|
||||
import org.springblade.core.mp.support.BaseEntityWrapper;
|
||||
import org.springblade.core.tool.constant.BladeConstant;
|
||||
import org.springblade.core.tool.node.ForestNodeMerger;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.auth.system.cache.SysCache;
|
||||
import org.springblade.auth.system.entity.Role;
|
||||
import org.springblade.auth.system.vo.RoleVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 包装类,返回视图层所需的字段
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class RoleWrapper extends BaseEntityWrapper<Role, RoleVO> {
|
||||
|
||||
public static RoleWrapper build() {
|
||||
return new RoleWrapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public RoleVO entityVO(Role role) {
|
||||
RoleVO roleVO = Objects.requireNonNull(BeanUtil.copy(role, RoleVO.class));
|
||||
if (Func.equals(role.getParentId(), BladeConstant.TOP_PARENT_ID)) {
|
||||
roleVO.setParentName(BladeConstant.TOP_PARENT_NAME);
|
||||
} else {
|
||||
Role parent = SysCache.getRole(role.getParentId());
|
||||
roleVO.setParentName(parent.getRoleName());
|
||||
}
|
||||
return roleVO;
|
||||
}
|
||||
|
||||
|
||||
public List<RoleVO> listNodeVO(List<Role> list) {
|
||||
List<RoleVO> collect = list.stream().map(this::entityVO).collect(Collectors.toList());
|
||||
return ForestNodeMerger.merge(collect);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package org.springblade.auth.system.wrapper;
|
||||
|
||||
import org.springblade.core.mp.support.BaseEntityWrapper;
|
||||
import org.springblade.core.tool.utils.BeanUtil;
|
||||
import org.springblade.core.tool.utils.Func;
|
||||
import org.springblade.auth.system.cache.SysCache;
|
||||
import org.springblade.auth.system.entity.User;
|
||||
import org.springblade.auth.system.vo.UserVO;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* 包装类,返回视图层所需的字段
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class UserWrapper extends BaseEntityWrapper<User, UserVO> {
|
||||
|
||||
public static UserWrapper build() {
|
||||
return new UserWrapper();
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserVO entityVO(User user) {
|
||||
UserVO userVO = Objects.requireNonNull(BeanUtil.copy(user, UserVO.class));
|
||||
List<String> roleName = SysCache.getRoleNames(user.getRoleId());
|
||||
userVO.setRoleName(Func.join(roleName));
|
||||
return userVO;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright (c) 2018-2028, Chill Zhuang All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
* this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the dreamlu.net developer nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Author: Chill 庄骞 (smallchill@163.com)
|
||||
*/
|
||||
package org.springblade.auth.utils;
|
||||
|
||||
import lombok.SneakyThrows;
|
||||
import org.springblade.core.launch.constant.TokenConstant;
|
||||
import org.springblade.core.tenant.BladeTenantProperties;
|
||||
import org.springblade.core.tool.utils.Charsets;
|
||||
import org.springblade.core.tool.utils.SpringUtil;
|
||||
import org.springblade.core.tool.utils.StringPool;
|
||||
import org.springblade.core.tool.utils.WebUtil;
|
||||
import org.springframework.security.authentication.BadCredentialsException;
|
||||
import org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException;
|
||||
|
||||
import java.util.Base64;
|
||||
import java.util.Calendar;
|
||||
|
||||
/**
|
||||
* 认证工具类
|
||||
*
|
||||
* @author Chill
|
||||
*/
|
||||
public class TokenUtil {
|
||||
|
||||
public final static String AVATAR = TokenConstant.AVATAR;
|
||||
public final static String ACCOUNT = TokenConstant.ACCOUNT;
|
||||
public final static String USER_NAME = TokenConstant.USER_NAME;
|
||||
public final static String NICK_NAME = TokenConstant.NICK_NAME;
|
||||
public final static String REAL_NAME = TokenConstant.REAL_NAME;
|
||||
public final static String USER_ID = TokenConstant.USER_ID;
|
||||
public final static String DEPT_ID = TokenConstant.DEPT_ID;
|
||||
public final static String POST_ID = TokenConstant.POST_ID;
|
||||
public final static String ROLE_ID = TokenConstant.ROLE_ID;
|
||||
public final static String ROLE_NAME = TokenConstant.ROLE_NAME;
|
||||
public final static String TENANT_ID = TokenConstant.TENANT_ID;
|
||||
public final static String OAUTH_ID = TokenConstant.OAUTH_ID;
|
||||
public final static String CLIENT_ID = TokenConstant.CLIENT_ID;
|
||||
public final static String DETAIL = TokenConstant.DETAIL;
|
||||
public final static String EMAIL = "email";
|
||||
public final static String DEPT_HEADER_KEY = "Dept-Id";
|
||||
public final static String ROLE_HEADER_KEY = "Role-Id";
|
||||
public final static String MOBILE_HEADER_KEY = "Mobile-Key";
|
||||
public final static String MOBILE_HEADER_CODE = "Mobile-Code";
|
||||
public final static String CAPTCHA_HEADER_KEY = "Captcha-Key";
|
||||
public final static String CAPTCHA_HEADER_CODE = "Captcha-Code";
|
||||
public final static String CAPTCHA_NOT_CORRECT = "Incorrect verification code";
|
||||
public final static String TENANT_HEADER_KEY = "Tenant-Id";
|
||||
public final static String TENANT_PARAM_KEY = "tenant_id";
|
||||
public final static String DEFAULT_TENANT_ID = "000000";
|
||||
public final static String TENANT_NOT_FOUND = "租户ID未找到";
|
||||
public final static String USER_TYPE_HEADER_KEY = "User-Type";
|
||||
public final static String DEFAULT_USER_TYPE = "web";
|
||||
public final static String USER_NOT_FOUND = "Incorrect username or password";
|
||||
public final static String USER_HAS_NO_ROLE = "Unable to obtain user's role information";
|
||||
public final static String USER_HAS_NO_TENANT = "未获得用户的租户信息";
|
||||
public final static String USER_HAS_NO_TENANT_PERMISSION = "租户授权已过期,请联系管理员";
|
||||
public final static String USER_HAS_TOO_MANY_FAILS = "Too many login errors. Please try again later";
|
||||
public final static String HEADER_KEY = "Authorization";
|
||||
public final static String HEADER_PREFIX = "Basic ";
|
||||
public final static String DEFAULT_AVATAR = "";
|
||||
public final static String PASSWORD_KEY = "password";
|
||||
public final static String GRANT_TYPE_KEY = "grant_type";
|
||||
public final static String REFRESH_TOKEN_KEY = "refresh_token";
|
||||
public final static String LICENSE_NAME = "KeNing";
|
||||
private static BladeTenantProperties tenantProperties;
|
||||
|
||||
/**
|
||||
* 获取租户配置
|
||||
*
|
||||
* @return tenantProperties
|
||||
*/
|
||||
private static BladeTenantProperties getTenantProperties() {
|
||||
if (tenantProperties == null) {
|
||||
tenantProperties = SpringUtil.getBean(BladeTenantProperties.class);
|
||||
}
|
||||
return tenantProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* 解码
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static String[] extractAndDecodeHeader() {
|
||||
String header = WebUtil.getRequest().getHeader(TokenUtil.HEADER_KEY);
|
||||
if (header == null || !header.startsWith(TokenUtil.HEADER_PREFIX)) {
|
||||
throw new UnapprovedClientAuthenticationException("请求头中无client信息");
|
||||
}
|
||||
|
||||
byte[] base64Token = header.substring(6).getBytes(Charsets.UTF_8_NAME);
|
||||
|
||||
byte[] decoded;
|
||||
try {
|
||||
decoded = Base64.getDecoder().decode(base64Token);
|
||||
} catch (IllegalArgumentException var7) {
|
||||
throw new BadCredentialsException("Failed to decode basic authentication token");
|
||||
}
|
||||
|
||||
String token = new String(decoded, Charsets.UTF_8_NAME);
|
||||
int index = token.indexOf(StringPool.COLON);
|
||||
if (index == -1) {
|
||||
throw new BadCredentialsException("Invalid basic authentication token");
|
||||
} else {
|
||||
return new String[]{token.substring(0, index), token.substring(index + 1)};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取请求头中的客户端id
|
||||
*/
|
||||
public static String getClientIdFromHeader() {
|
||||
String[] tokens = extractAndDecodeHeader();
|
||||
return tokens[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取token过期时间(次日凌晨3点)
|
||||
*
|
||||
* @return expire
|
||||
*/
|
||||
public static int getTokenValiditySecond() {
|
||||
Calendar cal = Calendar.getInstance();
|
||||
cal.add(Calendar.DAY_OF_YEAR, 1);
|
||||
cal.set(Calendar.HOUR_OF_DAY, 3);
|
||||
cal.set(Calendar.SECOND, 0);
|
||||
cal.set(Calendar.MINUTE, 0);
|
||||
cal.set(Calendar.MILLISECOND, 0);
|
||||
return (int) (cal.getTimeInMillis() - System.currentTimeMillis()) / 1000;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取refreshToken过期时间
|
||||
*
|
||||
* @return expire
|
||||
*/
|
||||
public static int getRefreshTokenValiditySeconds() {
|
||||
return 60 * 60 * 24 * 15;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
#服务器端口
|
||||
server:
|
||||
port: 8100
|
||||
|
||||
#数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
url: ${blade.datasource.dev.url}
|
||||
username: ${blade.datasource.dev.username}
|
||||
password: ${blade.datasource.dev.password}
|
||||
|
||||
#第三方登陆
|
||||
social:
|
||||
enabled: true
|
||||
domain: http://127.0.0.1:1888
|
||||
|
||||
|
||||
mobile:
|
||||
enabled: true
|
|
@ -0,0 +1,18 @@
|
|||
#服务器端口
|
||||
server:
|
||||
port: 8100
|
||||
|
||||
#数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
url: ${blade.datasource.prod.url}
|
||||
username: ${blade.datasource.prod.username}
|
||||
password: ${blade.datasource.prod.password}
|
||||
|
||||
#第三方登陆
|
||||
social:
|
||||
enabled: true
|
||||
domain: http://127.0.0.1:1888
|
||||
|
||||
mobile:
|
||||
enabled: true
|
|
@ -0,0 +1,18 @@
|
|||
#服务器端口
|
||||
server:
|
||||
port: 8100
|
||||
|
||||
#数据源配置
|
||||
spring:
|
||||
datasource:
|
||||
url: ${blade.datasource.test.url}
|
||||
username: ${blade.datasource.test.username}
|
||||
password: ${blade.datasource.test.password}
|
||||
|
||||
#第三方登陆
|
||||
social:
|
||||
enabled: true
|
||||
domain: http://127.0.0.1:1888
|
||||
|
||||
mobile:
|
||||
enabled: true
|
|
@ -0,0 +1,34 @@
|
|||
# 在使用Spring默认数据源Hikari的情况下配置以下配置项
|
||||
spring:
|
||||
datasource:
|
||||
hikari:
|
||||
# 自动提交从池中返回的连接
|
||||
auto-commit: true
|
||||
# 连接池中维护的最小空闲连接数
|
||||
minimum-idle: 10
|
||||
# 连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count)
|
||||
maximum-pool-size: 60
|
||||
# 空闲连接超时时间,默认值600000(10分钟),大于等于max-lifetime且max-lifetime>0,会被重置为0;不等于0且小于10秒,会被重置为10秒。
|
||||
# 只有空闲连接数大于最大连接数且空闲时间超过该值,才会被释放
|
||||
idle-timeout: 30000
|
||||
# 连接最大存活时间.不等于0且小于30秒,会被重置为默认值30分钟.设置应该比mysql设置的超时时间短
|
||||
max-lifetime: 1800000
|
||||
# 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 缺省:30秒
|
||||
connection-timeout: 30000
|
||||
# 连接测试查询
|
||||
connection-test-query: select 1
|
||||
#connection-test-query: select 1 from dual
|
||||
|
||||
#swagger文档
|
||||
swagger:
|
||||
base-packages:
|
||||
- org.springblade
|
||||
- org.springframework.security.oauth2.provider.endpoint
|
||||
|
||||
#第三方登陆
|
||||
social:
|
||||
oauth:
|
||||
WECHAT_OPEN:
|
||||
client-id: 233************
|
||||
client-secret: 233************************************
|
||||
redirect-uri: ${social.domain}/oauth/redirect/wechat
|
6
pom.xml
6
pom.xml
|
@ -35,6 +35,7 @@
|
|||
<module>kn-launcher</module>
|
||||
<module>kn-service</module>
|
||||
<module>kn-service-api</module>
|
||||
<module>kn-sys-manager</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
|
@ -82,6 +83,11 @@
|
|||
<artifactId>easyexcel</artifactId>
|
||||
<version>${easyexcel.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.kening.platform</groupId>
|
||||
<artifactId>kn-common</artifactId>
|
||||
<version>${revision}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
|
|
Loading…
Reference in New Issue