Compare commits
2 Commits
Author | SHA1 | Date |
---|---|---|
|
8035c8b56a | |
|
a3b118aef8 |
|
@ -25,39 +25,9 @@ public class Knife4jConfig {
|
||||||
return new OpenAPI().info(info).externalDocs(new ExternalDocumentation());
|
return new OpenAPI().info(info).externalDocs(new ExternalDocumentation());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 管理员相关分类接口
|
||||||
@Bean
|
@Bean
|
||||||
public GroupedOpenApi all() {
|
public GroupedOpenApi groupedOpenAdminApi() {
|
||||||
return GroupedOpenApi.builder().group("全部请求接口").pathsToMatch("/api/**").build();
|
return GroupedOpenApi.builder().group("默认请求接口").pathsToMatch("/admin/**").build();
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public GroupedOpenApi i18n() {
|
|
||||||
return GroupedOpenApi.builder().group("多语言").pathsToMatch("/api/i18n/**", "/api/i18nType/**").build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public GroupedOpenApi config() {
|
|
||||||
return GroupedOpenApi.builder().group("配置")
|
|
||||||
.pathsToMatch("/api/config/**", "/api/emailTemplate/**", "/api/emailUsers/**",
|
|
||||||
"/api/message/**", "/api/messageReceived/**", "/api/messageType/**",
|
|
||||||
"/api/menuIcon/**", "/api/schedulers/**", "/api/schedulersGroup/**"
|
|
||||||
)
|
|
||||||
.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public GroupedOpenApi system() {
|
|
||||||
return GroupedOpenApi.builder().group("系统")
|
|
||||||
.pathsToMatch("/api/dept/**", "/api/files/**", "/api/power/**",
|
|
||||||
"/api/rolePower/**", "/api/role/**", "/api/router/**",
|
|
||||||
"/api/routerRole/**", "/api/user/**", "/api/userRole/**"
|
|
||||||
).build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public GroupedOpenApi log() {
|
|
||||||
return GroupedOpenApi.builder().group("日志")
|
|
||||||
.pathsToMatch("/api/userLoginLog/**", "/api/quartzExecuteLog/**"
|
|
||||||
).build();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ public class AuthCustomerException extends RuntimeException {
|
||||||
Integer code;
|
Integer code;
|
||||||
|
|
||||||
// 描述信息
|
// 描述信息
|
||||||
String message = "服务异常";
|
String message;
|
||||||
|
|
||||||
// 返回结果状态
|
// 返回结果状态
|
||||||
ResultCodeEnum resultCodeEnum;
|
ResultCodeEnum resultCodeEnum;
|
||||||
|
|
|
@ -6,7 +6,6 @@ import cn.bunny.dao.vo.result.Result;
|
||||||
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
@ -37,7 +36,6 @@ public class GlobalExceptionHandler {
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public Result<Object> exceptionHandler(RuntimeException exception) {
|
public Result<Object> exceptionHandler(RuntimeException exception) {
|
||||||
String message = exception.getMessage();
|
String message = exception.getMessage();
|
||||||
message = StringUtils.hasText(message) ? message : "服务器异常";
|
|
||||||
|
|
||||||
// 解析异常
|
// 解析异常
|
||||||
String jsonParseError = "JSON parse error (.*)";
|
String jsonParseError = "JSON parse error (.*)";
|
||||||
|
@ -69,7 +67,7 @@ public class GlobalExceptionHandler {
|
||||||
|
|
||||||
log.error("GlobalExceptionHandler===>运行时异常信息:{}", message);
|
log.error("GlobalExceptionHandler===>运行时异常信息:{}", message);
|
||||||
exception.printStackTrace();
|
exception.printStackTrace();
|
||||||
return Result.error(null, 500, message);
|
return Result.error(null, 500, "服务器异常");
|
||||||
}
|
}
|
||||||
|
|
||||||
// 捕获系统异常
|
// 捕获系统异常
|
||||||
|
|
|
@ -0,0 +1,206 @@
|
||||||
|
package cn.bunny.common.service.utils;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.http.HttpResponse;
|
||||||
|
import org.apache.http.NameValuePair;
|
||||||
|
import org.apache.http.client.HttpClient;
|
||||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.HttpDelete;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.HttpPut;
|
||||||
|
import org.apache.http.conn.ClientConnectionManager;
|
||||||
|
import org.apache.http.conn.scheme.Scheme;
|
||||||
|
import org.apache.http.conn.scheme.SchemeRegistry;
|
||||||
|
import org.apache.http.conn.ssl.SSLSocketFactory;
|
||||||
|
import org.apache.http.entity.ByteArrayEntity;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.DefaultHttpClient;
|
||||||
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.TrustManager;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
import java.io.UnsupportedEncodingException;
|
||||||
|
import java.net.URLEncoder;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class HttpUtil {
|
||||||
|
public static HttpResponse doGet(String host, String path, String method, Map<String, String> headers, Map<String, String> querys) throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpGet request = new HttpGet(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HttpResponse doPost(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, Map<String, String> bodys) throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpPost request = new HttpPost(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bodys != null) {
|
||||||
|
List<NameValuePair> nameValuePairList = new ArrayList<NameValuePair>();
|
||||||
|
|
||||||
|
for (String key : bodys.keySet()) {
|
||||||
|
nameValuePairList.add(new BasicNameValuePair(key, bodys.get(key)));
|
||||||
|
}
|
||||||
|
UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(nameValuePairList, "utf-8");
|
||||||
|
formEntity.setContentType("application/x-www-form-urlencoded; charset=UTF-8");
|
||||||
|
request.setEntity(formEntity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static HttpResponse doPost(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, String body) throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpPost request = new HttpPost(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(body)) {
|
||||||
|
request.setEntity(new StringEntity(body, "utf-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static HttpResponse doPost(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, byte[] body) throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpPost request = new HttpPost(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body != null) {
|
||||||
|
request.setEntity(new ByteArrayEntity(body));
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static HttpResponse doPut(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, String body) throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpPut request = new HttpPut(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (StringUtils.isNotBlank(body)) {
|
||||||
|
request.setEntity(new StringEntity(body, "utf-8"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static HttpResponse doPut(String host, String path, String method, Map<String, String> headers, Map<String, String> querys, byte[] body) throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpPut request = new HttpPut(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (body != null) {
|
||||||
|
request.setEntity(new ByteArrayEntity(body));
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static HttpResponse doDelete(String host, String path, String method, Map<String, String> headers, Map<String, String> querys) throws Exception {
|
||||||
|
HttpClient httpClient = wrapClient(host);
|
||||||
|
|
||||||
|
HttpDelete request = new HttpDelete(buildUrl(host, path, querys));
|
||||||
|
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||||
|
request.addHeader(e.getKey(), e.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient.execute(request);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String buildUrl(String host, String path, Map<String, String> querys) throws UnsupportedEncodingException {
|
||||||
|
StringBuilder sbUrl = new StringBuilder();
|
||||||
|
sbUrl.append(host);
|
||||||
|
if (!StringUtils.isBlank(path)) {
|
||||||
|
sbUrl.append(path);
|
||||||
|
}
|
||||||
|
if (null != querys) {
|
||||||
|
StringBuilder sbQuery = new StringBuilder();
|
||||||
|
for (Map.Entry<String, String> query : querys.entrySet()) {
|
||||||
|
if (!sbQuery.isEmpty()) {
|
||||||
|
sbQuery.append("&");
|
||||||
|
}
|
||||||
|
if (StringUtils.isBlank(query.getKey()) && !StringUtils.isBlank(query.getValue())) {
|
||||||
|
sbQuery.append(query.getValue());
|
||||||
|
}
|
||||||
|
if (!StringUtils.isBlank(query.getKey())) {
|
||||||
|
sbQuery.append(query.getKey());
|
||||||
|
if (!StringUtils.isBlank(query.getValue())) {
|
||||||
|
sbQuery.append("=");
|
||||||
|
sbQuery.append(URLEncoder.encode(query.getValue(), StandardCharsets.UTF_8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!sbQuery.isEmpty()) {
|
||||||
|
sbUrl.append("?").append(sbQuery);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return sbUrl.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HttpClient wrapClient(String host) {
|
||||||
|
HttpClient httpClient = new DefaultHttpClient();
|
||||||
|
if (host.startsWith("https://")) {
|
||||||
|
sslClient(httpClient);
|
||||||
|
}
|
||||||
|
|
||||||
|
return httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void sslClient(HttpClient httpClient) {
|
||||||
|
try {
|
||||||
|
SSLContext ctx = SSLContext.getInstance("TLS");
|
||||||
|
X509TrustManager tm = new X509TrustManager() {
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkClientTrusted(X509Certificate[] xcs, String str) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void checkServerTrusted(X509Certificate[] xcs, String str) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ctx.init(null, new TrustManager[]{tm}, null);
|
||||||
|
SSLSocketFactory ssf = new SSLSocketFactory(ctx);
|
||||||
|
ssf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
|
||||||
|
ClientConnectionManager ccm = httpClient.getConnectionManager();
|
||||||
|
SchemeRegistry registry = ccm.getSchemeRegistry();
|
||||||
|
registry.register(new Scheme("https", 443, ssf));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
throw new RuntimeException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,13 +11,13 @@ import java.io.IOException;
|
||||||
public class ResponseUtil {
|
public class ResponseUtil {
|
||||||
|
|
||||||
public static void out(HttpServletResponse response, Result<Object> result) {
|
public static void out(HttpServletResponse response, Result<Object> result) {
|
||||||
try {
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
ObjectMapper mapper = new ObjectMapper();
|
|
||||||
|
|
||||||
// 注册JavaTimeModule模块
|
// 注册JavaTimeModule模块
|
||||||
mapper.registerModule(new JavaTimeModule());
|
mapper.registerModule(new JavaTimeModule());
|
||||||
response.setContentType("application/json;charset=UTF-8");
|
response.setContentType("application/json;charset=UTF-8");
|
||||||
response.setStatus(HttpStatus.OK.value());
|
response.setStatus(HttpStatus.OK.value());
|
||||||
|
try {
|
||||||
mapper.writeValue(response.getWriter(), result);
|
mapper.writeValue(response.getWriter(), result);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
|
|
@ -13,9 +13,6 @@ import java.util.Objects;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
public class MailSenderUtil {
|
public class MailSenderUtil {
|
||||||
private MailSenderUtil() {
|
|
||||||
// 私有化构造器
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 如果启用SSL需要配置以下
|
* 如果启用SSL需要配置以下
|
||||||
|
@ -26,8 +23,8 @@ public class MailSenderUtil {
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
// 开启认证
|
// 开启认证
|
||||||
properties.setProperty("mail.smtp.auth", "true");
|
properties.setProperty("mail.smtp.auth", "true");
|
||||||
// 是否启用调试---会输出发送邮件调试内容
|
// 启用调试
|
||||||
properties.setProperty("mail.debug", "false");
|
properties.setProperty("mail.debug", "true");
|
||||||
// 设置链接超时
|
// 设置链接超时
|
||||||
properties.setProperty("mail.smtp.timeout", "200000");
|
properties.setProperty("mail.smtp.timeout", "200000");
|
||||||
// 设置端口
|
// 设置端口
|
||||||
|
|
|
@ -23,11 +23,6 @@
|
||||||
<groupId>org.projectlombok</groupId>
|
<groupId>org.projectlombok</groupId>
|
||||||
<artifactId>lombok</artifactId>
|
<artifactId>lombok</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- spring-security -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-security</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<!-- mybatis-plus -->
|
<!-- mybatis-plus -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.baomidou</groupId>
|
<groupId>com.baomidou</groupId>
|
||||||
|
|
|
@ -37,7 +37,7 @@ public class LoginDto {
|
||||||
@Schema(name = "type", title = "登录类型")
|
@Schema(name = "type", title = "登录类型")
|
||||||
@NotBlank(message = "登录类型不能为空")
|
@NotBlank(message = "登录类型不能为空")
|
||||||
@NotNull(message = "登录类型能为空")
|
@NotNull(message = "登录类型能为空")
|
||||||
private String type = "default";
|
private String type;
|
||||||
|
|
||||||
@Schema(name = "readMeDay", title = "记住我的天数")
|
@Schema(name = "readMeDay", title = "记住我的天数")
|
||||||
private Long readMeDay = 1L;
|
private Long readMeDay = 1L;
|
||||||
|
|
|
@ -6,11 +6,6 @@ import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import lombok.EqualsAndHashCode;
|
import lombok.EqualsAndHashCode;
|
||||||
import lombok.experimental.Accessors;
|
import lombok.experimental.Accessors;
|
||||||
import org.springframework.security.core.GrantedAuthority;
|
|
||||||
import org.springframework.security.core.userdetails.UserDetails;
|
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -25,7 +20,7 @@ import java.util.List;
|
||||||
@Accessors(chain = true)
|
@Accessors(chain = true)
|
||||||
@TableName("sys_user")
|
@TableName("sys_user")
|
||||||
@Schema(name = "AdminUser对象", title = "用户信息", description = "用户信息")
|
@Schema(name = "AdminUser对象", title = "用户信息", description = "用户信息")
|
||||||
public class AdminUser extends BaseEntity implements UserDetails {
|
public class AdminUser extends BaseEntity {
|
||||||
|
|
||||||
@Schema(name = "username", title = "用户名")
|
@Schema(name = "username", title = "用户名")
|
||||||
private String username;
|
private String username;
|
||||||
|
@ -60,9 +55,5 @@ public class AdminUser extends BaseEntity implements UserDetails {
|
||||||
@Schema(name = "status", title = "状态", description = "1:禁用 0:正常")
|
@Schema(name = "status", title = "状态", description = "1:禁用 0:正常")
|
||||||
private Boolean status;
|
private Boolean status;
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<? extends GrantedAuthority> getAuthorities() {
|
|
||||||
return List.of();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
package cn.bunny.dao.enums;
|
|
||||||
|
|
||||||
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
@Getter
|
|
||||||
public enum LoginEnums {
|
|
||||||
// 邮箱登录请求
|
|
||||||
EMAIL_STRATEGY("email"),
|
|
||||||
// 默认登录请求
|
|
||||||
default_STRATEGY("default"),
|
|
||||||
// 登良路请求API
|
|
||||||
LOGIN_REQUEST_API("/api/login"),
|
|
||||||
;
|
|
||||||
|
|
||||||
private final String value;
|
|
||||||
|
|
||||||
LoginEnums(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,7 +24,7 @@ public enum ResultCodeEnum {
|
||||||
EMAIL_CODE_NOT_EMPTY(201, "邮箱验证码不能为空"),
|
EMAIL_CODE_NOT_EMPTY(201, "邮箱验证码不能为空"),
|
||||||
SEND_EMAIL_CODE_NOT_EMPTY(201, "请先发送邮箱验证码"),
|
SEND_EMAIL_CODE_NOT_EMPTY(201, "请先发送邮箱验证码"),
|
||||||
EMAIL_CODE_NOT_MATCHING(201, "邮箱验证码不匹配"),
|
EMAIL_CODE_NOT_MATCHING(201, "邮箱验证码不匹配"),
|
||||||
LOGIN_ERROR(500, "账号或密码错误"),
|
LOGIN_ERROR(201, "账号或密码错误"),
|
||||||
LOGIN_ERROR_USERNAME_PASSWORD_NOT_EMPTY(201, "登录信息不能为空"),
|
LOGIN_ERROR_USERNAME_PASSWORD_NOT_EMPTY(201, "登录信息不能为空"),
|
||||||
GET_BUCKET_EXCEPTION(201, "获取文件信息失败"),
|
GET_BUCKET_EXCEPTION(201, "获取文件信息失败"),
|
||||||
SEND_MAIL_CODE_ERROR(201, "邮件发送失败"),
|
SEND_MAIL_CODE_ERROR(201, "邮件发送失败"),
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
name: auth-compose # 定义该配置的名称为 auth-dependence
|
|
||||||
services: # 定义服务列表
|
|
||||||
|
|
||||||
# 安装MySQL
|
|
||||||
mysql: # 定义 MySQL 服务
|
|
||||||
container_name: mysql_master # 容器名称为 mysql_master
|
|
||||||
image: mysql:8.0.33 # 使用 MySQL 8.0.33 版本的镜像
|
|
||||||
ports:
|
|
||||||
- "3306:3306" # 将宿主机的 3306 端口映射到容器的 3306 端口
|
|
||||||
environment:
|
|
||||||
- MYSQL_ROOT_PASSWORD=123456 # 设置 MySQL 的 root 用户密码为 123456
|
|
||||||
- TZ=Asia/Shanghai # 设置时区为亚洲/上海
|
|
||||||
volumes:
|
|
||||||
# - ~/docker/docker_data/mysql/mysql_master/etc/my.cnf:/etc/my.cnf # 如果需要创建配置文件
|
|
||||||
- ~/docker/docker_data/mysql/mysql_master/etc/mysql:/etc/mysql/conf.d # 挂载 MySQL 配置文件目录
|
|
||||||
- ~/docker/docker_data/mysql/mysql_master/data:/var/lib/mysql # 挂载 MySQL 数据目录
|
|
||||||
- ~/docker/docker_data/mysql/mysql_master/backup:/backup # 挂载备份目录
|
|
||||||
command:
|
|
||||||
- "--log-bin=mysql-bin" # 启用二进制日志
|
|
||||||
- "--server-id=1" # 设置服务器 ID 为 1
|
|
||||||
- "--collation-server=utf8mb4_unicode_ci" # 设置默认的排序规则为 utf8mb4_unicode_ci
|
|
||||||
- "--character-set-server=utf8mb4" # 设置默认的字符集为 utf8mb4
|
|
||||||
- "--lower-case-table-names=1" # 设置表名存储为小写
|
|
||||||
restart: always # 设置容器总是自动重启
|
|
||||||
privileged: true # 赋予容器特权模式
|
|
||||||
networks:
|
|
||||||
- auth # 将 MySQL 服务加入到 auth 网络
|
|
||||||
|
|
||||||
# 安装Redis
|
|
||||||
redis: # 定义 Redis 服务
|
|
||||||
container_name: redis_master # 容器名称为 redis_master
|
|
||||||
image: redis:7.0.10 # 使用 Redis 7.0.10 版本的镜像
|
|
||||||
ports:
|
|
||||||
- "6379:6379" # 将宿主机的 6379 端口映射到容器的 6379 端口
|
|
||||||
volumes:
|
|
||||||
# - ~/docker/docker_data/redis_master/redis.conf:/etc/redis/redis.conf # 需要创建配置文件
|
|
||||||
- ~/docker/docker_data/redis_master:/etc/redis # 挂载 Redis 配置文件目录
|
|
||||||
- ~/docker/docker_data/redis_master/data:/data # 挂载 Redis 数据目录
|
|
||||||
command:
|
|
||||||
- "--appendonly yes" # 启用 AOF 持久化
|
|
||||||
- "--daemonize no" # 不以守护进程方式运行
|
|
||||||
- "--requirepass 123456" # 设置 Redis 访问密码为 123456
|
|
||||||
- "--tcp-keepalive 300" # 设置 TCP keepalive 时间为 300 秒
|
|
||||||
restart: always # 设置容器总是自动重启
|
|
||||||
networks:
|
|
||||||
- auth # 将 MySQL 服务加入到 auth 网络
|
|
||||||
|
|
||||||
# 安装 Minio
|
|
||||||
minio: # 定义 Minio 服务
|
|
||||||
image: minio/minio # 使用 Minio 官方镜像
|
|
||||||
container_name: minio_master # 容器名称为 minio_master
|
|
||||||
ports:
|
|
||||||
- "9000:9000" # 将宿主机的 9000 端口映射到容器的 9000 端口
|
|
||||||
- "9090:9090" # 将宿主机的 9090 端口映射到容器的 9090 端口
|
|
||||||
volumes:
|
|
||||||
- ~/docker/docker_data/minio/data:/data # 挂载 Minio 数据目录
|
|
||||||
environment:
|
|
||||||
- MINIO_ROOT_USER=bunny # 设置 Minio 的 root 用户名为 bunny
|
|
||||||
- MINIO_ROOT_PASSWORD=12345678 # 设置 Minio 的 root 用户密码为 123456
|
|
||||||
command: "server /data --console-address :9090" # 启动 Minio 服务并指定控制台地址
|
|
||||||
restart: always # 设置容器总是自动重启
|
|
||||||
networks:
|
|
||||||
- auth # 将 MySQL 服务加入到 auth 网络
|
|
||||||
|
|
||||||
networks: # 定义网络
|
|
||||||
auth: # 定义名为 auth 的网络
|
|
||||||
name: auth # 网络名称为 auth
|
|
||||||
driver: bridge # 使用 bridge 驱动(默认)
|
|
2
pom.xml
2
pom.xml
|
@ -5,7 +5,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
<artifactId>spring-boot-starter-parent</artifactId>
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
<version>3.3.2</version>
|
<version>3.2.3</version>
|
||||||
<relativePath/> <!-- lookup parent from repository -->
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>cn.bunny</groupId>
|
<groupId>cn.bunny</groupId>
|
||||||
|
|
|
@ -14,7 +14,7 @@ WORKDIR /home/server
|
||||||
# 复制jar包
|
# 复制jar包
|
||||||
COPY target/*.jar /home/server/app.jar
|
COPY target/*.jar /home/server/app.jar
|
||||||
|
|
||||||
# 程序内部挂在目录,看情况是否需要操作本地docker
|
# 程序内部挂在目录
|
||||||
VOLUME /usr/bin/docker
|
VOLUME /usr/bin/docker
|
||||||
VOLUME ["/var/run/docker.sock"]
|
VOLUME ["/var/run/docker.sock"]
|
||||||
VOLUME /etc/docker/daemon.json
|
VOLUME /etc/docker/daemon.json
|
||||||
|
|
|
@ -25,13 +25,6 @@
|
||||||
<artifactId>service-utils</artifactId>
|
<artifactId>service-utils</artifactId>
|
||||||
<version>0.0.1-SNAPSHOT</version>
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- devtools -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-devtools</artifactId>
|
|
||||||
<scope>runtime</scope>
|
|
||||||
<optional>true</optional>
|
|
||||||
</dependency>
|
|
||||||
<!-- spring-security -->
|
<!-- spring-security -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
package cn.bunny.services;
|
package cn.bunny.services;
|
||||||
|
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.mybatis.spring.annotation.MapperScan;
|
import org.mybatis.spring.annotation.MapperScan;
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
import org.springframework.cache.annotation.EnableCaching;
|
import org.springframework.cache.annotation.EnableCaching;
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.ComponentScan;
|
import org.springframework.context.annotation.ComponentScan;
|
||||||
import org.springframework.scheduling.annotation.EnableScheduling;
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
||||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
@MapperScan("cn.bunny.services.mapper")
|
@MapperScan("cn.bunny.services.mapper")
|
||||||
|
@ -16,14 +14,10 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
@EnableScheduling
|
@EnableScheduling
|
||||||
@EnableCaching
|
@EnableCaching
|
||||||
@EnableTransactionManagement
|
@EnableTransactionManagement
|
||||||
|
@Slf4j
|
||||||
@SpringBootApplication
|
@SpringBootApplication
|
||||||
public class ServiceApplication {
|
public class ServiceApplication {
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
SpringApplication.run(ServiceApplication.class, args);
|
SpringApplication.run(ServiceApplication.class, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
|
||||||
public PasswordEncoder passwordEncoder() {
|
|
||||||
return new BCryptPasswordEncoder();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
@Tag(name = "系统配置", description = "系统配置相关接口")
|
@Tag(name = "系统配置", description = "系统配置相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/config")
|
@RequestMapping("/admin/config")
|
||||||
public class ConfigurationController {
|
public class ConfigurationController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -30,7 +30,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "系统部门", description = "部门相关接口")
|
@Tag(name = "系统部门", description = "部门相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/dept")
|
@RequestMapping("/admin/dept")
|
||||||
public class DeptController {
|
public class DeptController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -31,7 +31,7 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "邮件模板", description = "邮件模板相关接口")
|
@Tag(name = "邮件模板", description = "邮件模板相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/emailTemplate")
|
@RequestMapping("admin/emailTemplate")
|
||||||
public class EmailTemplateController {
|
public class EmailTemplateController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -32,7 +32,7 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "邮箱用户发送配置", description = "邮箱用户发送配置相关接口")
|
@Tag(name = "邮箱用户发送配置", description = "邮箱用户发送配置相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/emailUsers")
|
@RequestMapping("admin/emailUsers")
|
||||||
public class EmailUsersController {
|
public class EmailUsersController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -36,7 +36,7 @@ import java.util.Set;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "系统文件表", description = "系统文件相关接口")
|
@Tag(name = "系统文件表", description = "系统文件相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/files")
|
@RequestMapping("admin/files")
|
||||||
public class FilesController {
|
public class FilesController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -31,7 +31,7 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "多语言", description = "多语言相关接口")
|
@Tag(name = "多语言", description = "多语言相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/i18n")
|
@RequestMapping("admin/i18n")
|
||||||
public class I18nController {
|
public class I18nController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -26,7 +26,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "多语言类型", description = "多语言类型相关接口")
|
@Tag(name = "多语言类型", description = "多语言类型相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/i18nType")
|
@RequestMapping("admin/i18nType")
|
||||||
public class I18nTypeController {
|
public class I18nTypeController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -30,7 +30,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "系统菜单图标", description = "系统菜单图标相关接口")
|
@Tag(name = "系统菜单图标", description = "系统菜单图标相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/menuIcon")
|
@RequestMapping("admin/menuIcon")
|
||||||
public class MenuIconController {
|
public class MenuIconController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -32,7 +32,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "系统消息", description = "系统消息相关接口")
|
@Tag(name = "系统消息", description = "系统消息相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/message")
|
@RequestMapping("admin/message")
|
||||||
public class MessageController {
|
public class MessageController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -31,7 +31,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "消息接收(用户消息)", description = "消息接收(用户消息)相关接口")
|
@Tag(name = "消息接收(用户消息)", description = "消息接收(用户消息)相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/messageReceived")
|
@RequestMapping("/admin/messageReceived")
|
||||||
public class MessageReceivedController {
|
public class MessageReceivedController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -30,7 +30,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "系统消息类型", description = "系统消息类型相关接口")
|
@Tag(name = "系统消息类型", description = "系统消息类型相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/messageType")
|
@RequestMapping("admin/messageType")
|
||||||
public class MessageTypeController {
|
public class MessageTypeController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -31,7 +31,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "权限", description = "权限相关接口")
|
@Tag(name = "权限", description = "权限相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/power")
|
@RequestMapping("admin/power")
|
||||||
public class PowerController {
|
public class PowerController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -30,7 +30,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "角色", description = "角色相关接口")
|
@Tag(name = "角色", description = "角色相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/role")
|
@RequestMapping("admin/role")
|
||||||
public class RoleController {
|
public class RoleController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -22,7 +22,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "角色和权限", description = "角色和权限相关接口")
|
@Tag(name = "角色和权限", description = "角色和权限相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/rolePower")
|
@RequestMapping("admin/rolePower")
|
||||||
public class RolePowerController {
|
public class RolePowerController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -32,7 +32,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "系统路由", description = "系统路由相关接口")
|
@Tag(name = "系统路由", description = "系统路由相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/router")
|
@RequestMapping("admin/router")
|
||||||
public class RouterController {
|
public class RouterController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -21,7 +21,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "路由和角色", description = "路由和角色相关接口")
|
@Tag(name = "路由和角色", description = "路由和角色相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/routerRole")
|
@RequestMapping("admin/routerRole")
|
||||||
public class RouterRoleController {
|
public class RouterRoleController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -27,7 +27,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "调度任务执行日志", description = "调度任务执行日志相关接口")
|
@Tag(name = "调度任务执行日志", description = "调度任务执行日志相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/quartzExecuteLog")
|
@RequestMapping("admin/quartzExecuteLog")
|
||||||
public class ScheduleExecuteLogController {
|
public class ScheduleExecuteLogController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -32,7 +32,7 @@ import java.util.Map;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "调度任务", description = "调度任务相关接口")
|
@Tag(name = "调度任务", description = "调度任务相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/schedulers")
|
@RequestMapping("admin/schedulers")
|
||||||
public class SchedulersController {
|
public class SchedulersController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -30,7 +30,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "任务调度分组", description = "任务调度分组相关接口")
|
@Tag(name = "任务调度分组", description = "任务调度分组相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/schedulersGroup")
|
@RequestMapping("admin/schedulersGroup")
|
||||||
public class SchedulersGroupController {
|
public class SchedulersGroupController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -21,7 +21,7 @@ import java.util.List;
|
||||||
|
|
||||||
@Tag(name = "用户信息", description = "用户信息相关接口")
|
@Tag(name = "用户信息", description = "用户信息相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/user")
|
@RequestMapping("/admin/user")
|
||||||
public class UserController {
|
public class UserController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -28,7 +28,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "用户登录日志", description = "用户登录日志相关接口")
|
@Tag(name = "用户登录日志", description = "用户登录日志相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/userLoginLog")
|
@RequestMapping("admin/userLoginLog")
|
||||||
public class UserLoginLogController {
|
public class UserLoginLogController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -21,7 +21,7 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
@Tag(name = "用户和角色", description = "用户和角色相关接口")
|
@Tag(name = "用户和角色", description = "用户和角色相关接口")
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("api/userRole")
|
@RequestMapping("admin/userRole")
|
||||||
public class UserRoleController {
|
public class UserRoleController {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.services.utils.email;
|
package cn.bunny.services.factory;
|
||||||
|
|
||||||
import cn.bunny.common.service.exception.AuthCustomerException;
|
import cn.bunny.common.service.exception.AuthCustomerException;
|
||||||
import cn.bunny.common.service.utils.mail.MailSenderUtil;
|
import cn.bunny.common.service.utils.mail.MailSenderUtil;
|
||||||
|
@ -7,6 +7,7 @@ import cn.bunny.dao.entity.system.EmailUsers;
|
||||||
import cn.bunny.dao.model.email.EmailSend;
|
import cn.bunny.dao.model.email.EmailSend;
|
||||||
import cn.bunny.dao.model.email.EmailSendInit;
|
import cn.bunny.dao.model.email.EmailSendInit;
|
||||||
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
||||||
|
import cn.bunny.services.mapper.EmailTemplateMapper;
|
||||||
import cn.bunny.services.mapper.EmailUsersMapper;
|
import cn.bunny.services.mapper.EmailUsersMapper;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import jakarta.mail.MessagingException;
|
import jakarta.mail.MessagingException;
|
||||||
|
@ -18,19 +19,19 @@ import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public abstract class AbstractSenderEmailTemplate {
|
public class EmailFactory {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmailTemplateMapper emailTemplateMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private EmailUsersMapper emailUsersMapper;
|
private EmailUsersMapper emailUsersMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基本邮件发送模板
|
* * 发送邮件模板
|
||||||
*
|
* 根据已存在的邮件模板发送邮件
|
||||||
* @param email 邮箱
|
|
||||||
* @param emailTemplate 邮箱模板
|
|
||||||
* @param params 传入的参数
|
|
||||||
*/
|
*/
|
||||||
public void sendEmail(String email, EmailTemplate emailTemplate, HashMap<String, Object> params) {
|
public void sendEmailTemplate(String email, EmailTemplate emailTemplate, HashMap<String, Object> params) {
|
||||||
// 判断邮件模板是否为空
|
// 判断邮件模板是否为空
|
||||||
if (emailTemplate == null) throw new AuthCustomerException(ResultCodeEnum.EMAIL_TEMPLATE_IS_EMPTY);
|
if (emailTemplate == null) throw new AuthCustomerException(ResultCodeEnum.EMAIL_TEMPLATE_IS_EMPTY);
|
||||||
|
|
||||||
|
@ -68,4 +69,27 @@ public abstract class AbstractSenderEmailTemplate {
|
||||||
throw new AuthCustomerException(ResultCodeEnum.SEND_MAIL_CODE_ERROR);
|
throw new AuthCustomerException(ResultCodeEnum.SEND_MAIL_CODE_ERROR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 发送邮件模板
|
||||||
|
* 根据邮件模板发送邮件
|
||||||
|
*/
|
||||||
|
public void sendEmailTemplate(String email, Long emailTemplateId, HashMap<String, Object> params) {
|
||||||
|
EmailTemplate emailTemplate = emailTemplateMapper.selectOne(Wrappers.<EmailTemplate>lambdaQuery().eq(EmailTemplate::getId, emailTemplateId));
|
||||||
|
sendEmailTemplate(email, emailTemplate, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断邮箱是否添加
|
||||||
|
*
|
||||||
|
* @param isDefault 邮箱是否为默认
|
||||||
|
*/
|
||||||
|
public void updateEmailUserDefault(Boolean isDefault) {
|
||||||
|
EmailUsers emailUsers = new EmailUsers();
|
||||||
|
// 判断状态,如果是默认将所有的内容都设为false
|
||||||
|
if (isDefault) {
|
||||||
|
emailUsers.setIsDefault(false);
|
||||||
|
emailUsersMapper.update(emailUsers, Wrappers.<EmailUsers>lambdaUpdate().eq(EmailUsers::getIsDefault, true));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,25 @@
|
||||||
|
package cn.bunny.services.factory;
|
||||||
|
|
||||||
|
import cn.bunny.dao.vo.system.rolePower.PowerVo;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class PowerFactory {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 构建权限树形结构
|
||||||
|
*
|
||||||
|
* @param id 节点ID
|
||||||
|
* @param powerVoList 节点列表
|
||||||
|
* @return 树形列表
|
||||||
|
*/
|
||||||
|
public List<PowerVo> handlePowerVoChildren(Long id, List<PowerVo> powerVoList) {
|
||||||
|
return powerVoList.stream()
|
||||||
|
.filter(powerVo -> powerVo.getParentId().equals(id))
|
||||||
|
.peek(powerVo -> powerVo.setChildren(handlePowerVoChildren(powerVo.getId(), powerVoList)))
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
package cn.bunny.services.factory;
|
||||||
|
|
||||||
|
import cn.bunny.dao.constant.RedisUserConstant;
|
||||||
|
import cn.bunny.dao.entity.system.AdminUser;
|
||||||
|
import cn.bunny.services.mapper.UserMapper;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class RoleFactory {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserMapper userMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserFactory userFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量更新Redis中用户信息
|
||||||
|
*
|
||||||
|
* @param userIds 用户Id列表
|
||||||
|
*/
|
||||||
|
public void updateUserRedisInfo(List<Long> userIds) {
|
||||||
|
// 根据Id查找所有用户
|
||||||
|
List<AdminUser> adminUsers = userMapper.selectList(Wrappers.<AdminUser>lambdaQuery().in(AdminUser::getId, userIds));
|
||||||
|
|
||||||
|
// 用户为空时不更新Redis的key
|
||||||
|
if (adminUsers.isEmpty()) return;
|
||||||
|
|
||||||
|
// 更新Redis中用户信息
|
||||||
|
adminUsers.stream().filter(user -> {
|
||||||
|
String adminLoginInfoPrefix = RedisUserConstant.getAdminLoginInfoPrefix(user.getUsername());
|
||||||
|
Object object = redisTemplate.opsForValue().get(adminLoginInfoPrefix);
|
||||||
|
return object != null;
|
||||||
|
}).forEach(user -> userFactory.buildUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.services.utils;
|
package cn.bunny.services.factory;
|
||||||
|
|
||||||
import cn.bunny.dao.vo.system.router.UserRouterVo;
|
import cn.bunny.dao.vo.system.router.UserRouterVo;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
@ -8,7 +8,7 @@ import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class RouterServiceUtil {
|
public class RouterServiceFactory {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 递归调用设置子路由
|
* * 递归调用设置子路由
|
|
@ -1,6 +1,5 @@
|
||||||
package cn.bunny.services.utils;
|
package cn.bunny.services.factory;
|
||||||
|
|
||||||
import cn.bunny.common.service.exception.AuthCustomerException;
|
|
||||||
import cn.bunny.common.service.utils.JwtHelper;
|
import cn.bunny.common.service.utils.JwtHelper;
|
||||||
import cn.bunny.common.service.utils.ip.IpUtil;
|
import cn.bunny.common.service.utils.ip.IpUtil;
|
||||||
import cn.bunny.common.service.utils.minio.MinioUtil;
|
import cn.bunny.common.service.utils.minio.MinioUtil;
|
||||||
|
@ -16,6 +15,7 @@ import cn.bunny.services.mapper.PowerMapper;
|
||||||
import cn.bunny.services.mapper.RoleMapper;
|
import cn.bunny.services.mapper.RoleMapper;
|
||||||
import cn.bunny.services.mapper.UserLoginLogMapper;
|
import cn.bunny.services.mapper.UserLoginLogMapper;
|
||||||
import cn.bunny.services.mapper.UserMapper;
|
import cn.bunny.services.mapper.UserMapper;
|
||||||
|
import cn.bunny.services.security.custom.CustomCheckIsAdmin;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -35,7 +35,7 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
public class UserUtil {
|
public class UserFactory {
|
||||||
@Autowired
|
@Autowired
|
||||||
private PowerMapper powerMapper;
|
private PowerMapper powerMapper;
|
||||||
|
|
||||||
|
@ -54,14 +54,7 @@ public class UserUtil {
|
||||||
@Autowired
|
@Autowired
|
||||||
private MinioUtil minioUtil;
|
private MinioUtil minioUtil;
|
||||||
|
|
||||||
/**
|
@Transactional
|
||||||
* 构建登录用户返回对象
|
|
||||||
*
|
|
||||||
* @param user 用户
|
|
||||||
* @param readMeDay 保存登录信息时间
|
|
||||||
* @return 登录信息
|
|
||||||
*/
|
|
||||||
@Transactional(rollbackFor = AuthCustomerException.class)
|
|
||||||
public LoginVo buildLoginUserVo(AdminUser user, long readMeDay) {
|
public LoginVo buildLoginUserVo(AdminUser user, long readMeDay) {
|
||||||
Long userId = user.getId();
|
Long userId = user.getId();
|
||||||
String email = user.getEmail();
|
String email = user.getEmail();
|
||||||
|
@ -131,7 +124,7 @@ public class UserUtil {
|
||||||
List<String> permissions = new ArrayList<>();
|
List<String> permissions = new ArrayList<>();
|
||||||
|
|
||||||
// 判断是否是 admin 如果是admin 赋予所有权限
|
// 判断是否是 admin 如果是admin 赋予所有权限
|
||||||
boolean isAdmin = RoleUtil.checkAdmin(roles, permissions, user);
|
boolean isAdmin = CustomCheckIsAdmin.checkAdmin(roles, permissions, user);
|
||||||
if (!isAdmin) {
|
if (!isAdmin) {
|
||||||
permissions = powerMapper.selectListByUserId(userId).stream().map(Power::getPowerCode).toList();
|
permissions = powerMapper.selectListByUserId(userId).stream().map(Power::getPowerCode).toList();
|
||||||
}
|
}
|
|
@ -1,24 +1,20 @@
|
||||||
package cn.bunny.services.security.config;
|
package cn.bunny.services.security.config;
|
||||||
|
|
||||||
import cn.bunny.dao.entity.system.AdminUser;
|
import cn.bunny.services.security.custom.CustomPasswordEncoder;
|
||||||
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
|
||||||
import cn.bunny.services.mapper.UserMapper;
|
|
||||||
import cn.bunny.services.security.custom.CustomAuthorizationManagerServiceImpl;
|
|
||||||
import cn.bunny.services.security.filter.TokenLoginFilterService;
|
import cn.bunny.services.security.filter.TokenLoginFilterService;
|
||||||
import cn.bunny.services.security.handelr.SecurityAccessDeniedHandler;
|
import cn.bunny.services.security.handelr.SecurityAccessDeniedHandler;
|
||||||
import cn.bunny.services.security.handelr.SecurityAuthenticationEntryPoint;
|
import cn.bunny.services.security.handelr.SecurityAuthenticationEntryPoint;
|
||||||
import cn.bunny.services.service.UserService;
|
import cn.bunny.services.security.service.CustomUserDetailsService;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import cn.bunny.services.security.service.impl.CustomAuthorizationManagerServiceImpl;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.security.web.SecurityFilterChain;
|
import org.springframework.security.web.SecurityFilterChain;
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
|
import org.springframework.security.web.util.matcher.RegexRequestMatcher;
|
||||||
|
@ -28,7 +24,6 @@ import org.springframework.security.web.util.matcher.RegexRequestMatcher;
|
||||||
@EnableMethodSecurity
|
@EnableMethodSecurity
|
||||||
public class WebSecurityConfig {
|
public class WebSecurityConfig {
|
||||||
|
|
||||||
// 需要排出的无需验证的请求路径
|
|
||||||
public static String[] annotations = {
|
public static String[] annotations = {
|
||||||
"/", "/ws/**",
|
"/", "/ws/**",
|
||||||
"/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**",
|
"/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**",
|
||||||
|
@ -37,7 +32,13 @@ public class WebSecurityConfig {
|
||||||
};
|
};
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserService userService;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CustomUserDetailsService customUserDetailsService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private CustomPasswordEncoder customPasswordEncoder;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CustomAuthorizationManagerServiceImpl customAuthorizationManagerService;
|
private CustomAuthorizationManagerServiceImpl customAuthorizationManagerService;
|
||||||
|
@ -72,31 +73,10 @@ public class WebSecurityConfig {
|
||||||
exception.accessDeniedHandler(new SecurityAccessDeniedHandler());
|
exception.accessDeniedHandler(new SecurityAccessDeniedHandler());
|
||||||
})
|
})
|
||||||
// 登录验证过滤器
|
// 登录验证过滤器
|
||||||
.addFilterBefore(new TokenLoginFilterService(authenticationConfiguration, userService), UsernamePasswordAuthenticationFilter.class);
|
.addFilterBefore(new TokenLoginFilterService(authenticationConfiguration, redisTemplate, customUserDetailsService), UsernamePasswordAuthenticationFilter.class)
|
||||||
|
// 自定义密码加密器和用户登录
|
||||||
|
.passwordManagement(customPasswordEncoder).userDetailsService(customUserDetailsService);
|
||||||
|
|
||||||
return httpSecurity.build();
|
return httpSecurity.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用数据库方式
|
|
||||||
* 登录方式:邮箱+用户名
|
|
||||||
*
|
|
||||||
* @param userMapper 获取用户数据
|
|
||||||
* @return 数据库的用户
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
public UserDetailsService userDetailsService(UserMapper userMapper) {
|
|
||||||
return username -> {
|
|
||||||
// 查询用户相关内容
|
|
||||||
LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<AdminUser>()
|
|
||||||
.eq(AdminUser::getEmail, username)
|
|
||||||
.or()
|
|
||||||
.eq(AdminUser::getUsername, username);
|
|
||||||
|
|
||||||
// 根据邮箱查询用户名
|
|
||||||
AdminUser adminUser = userMapper.selectOne(queryWrapper);
|
|
||||||
if (adminUser == null) throw new UsernameNotFoundException(ResultCodeEnum.USER_IS_EMPTY.getMessage());
|
|
||||||
|
|
||||||
return adminUser;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,11 +13,10 @@ import org.springframework.security.core.AuthenticationException;
|
||||||
@ToString
|
@ToString
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class CustomAuthenticationException extends AuthenticationException {
|
public class CustomAuthenticationException extends AuthenticationException {
|
||||||
String message;
|
|
||||||
ResultCodeEnum resultCodeEnum;
|
ResultCodeEnum resultCodeEnum;
|
||||||
|
|
||||||
public CustomAuthenticationException(String message) {
|
public CustomAuthenticationException(ResultCodeEnum codeEnum) {
|
||||||
super(message);
|
super(codeEnum.getMessage());
|
||||||
this.message = message;
|
this.resultCodeEnum = codeEnum;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,51 @@
|
||||||
|
package cn.bunny.services.security.custom;
|
||||||
|
|
||||||
|
import cn.bunny.common.service.context.BaseContext;
|
||||||
|
import cn.bunny.dao.entity.system.AdminUser;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查是否是管理员
|
||||||
|
*/
|
||||||
|
public class CustomCheckIsAdmin {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是管理员
|
||||||
|
*
|
||||||
|
* @param roleList 角色代码列表
|
||||||
|
* @return 是否是管理员
|
||||||
|
*/
|
||||||
|
public static boolean checkAdmin(List<String> roleList) {
|
||||||
|
// 判断是否是超级管理员
|
||||||
|
if (BaseContext.getUserId().equals(1L)) return true;
|
||||||
|
|
||||||
|
// 判断是否是 admin
|
||||||
|
return roleList.stream().anyMatch(role -> role.equals("admin"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否是管理员
|
||||||
|
*
|
||||||
|
* @param roleList 角色代码列表
|
||||||
|
* @param permissions 权限列表
|
||||||
|
* @param adminUser 用户信息
|
||||||
|
* @return 是否是管理员
|
||||||
|
*/
|
||||||
|
public static boolean checkAdmin(List<String> roleList, List<String> permissions, AdminUser adminUser) {
|
||||||
|
// 判断是否是超级管理员
|
||||||
|
boolean isIdAdmin = adminUser.getId().equals(1L);
|
||||||
|
boolean isAdmin = roleList.stream().anyMatch(role -> role.equals("admin"));
|
||||||
|
|
||||||
|
// 判断是否是 admin
|
||||||
|
if (isIdAdmin || isAdmin) {
|
||||||
|
roleList.add("admin");
|
||||||
|
permissions.add("*");
|
||||||
|
permissions.add("*::*");
|
||||||
|
permissions.add("*::*::*");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package cn.bunny.services.security.custom;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.security.config.Customizer;
|
||||||
|
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||||
|
import org.springframework.security.config.annotation.web.configurers.PasswordManagementConfigurer;
|
||||||
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.util.DigestUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义密码加密比对
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class CustomPasswordEncoder implements PasswordEncoder, Customizer<PasswordManagementConfigurer<HttpSecurity>> {
|
||||||
|
@Override
|
||||||
|
public String encode(CharSequence rawPassword) {
|
||||||
|
return DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matches(CharSequence rawPassword, String encodedPassword) {
|
||||||
|
return encodedPassword.matches(DigestUtils.md5DigestAsHex(rawPassword.toString().getBytes()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void customize(PasswordManagementConfigurer<HttpSecurity> httpSecurityPasswordManagementConfigurer) {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
package cn.bunny.services.security.custom;
|
||||||
|
|
||||||
|
import cn.bunny.dao.entity.system.AdminUser;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.userdetails.User;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 重写自带的User
|
||||||
|
*/
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
public class CustomUser extends User {
|
||||||
|
private AdminUser user;
|
||||||
|
|
||||||
|
public CustomUser(AdminUser user, Collection<? extends GrantedAuthority> authorities) {
|
||||||
|
super(user.getUsername(), user.getPassword(), authorities);
|
||||||
|
this.user = user;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,44 +1,52 @@
|
||||||
package cn.bunny.services.security.filter;
|
package cn.bunny.services.security.filter;
|
||||||
|
|
||||||
|
|
||||||
import cn.bunny.common.service.utils.ResponseUtil;
|
import cn.bunny.dao.constant.RedisUserConstant;
|
||||||
import cn.bunny.dao.dto.system.user.LoginDto;
|
import cn.bunny.dao.dto.system.user.LoginDto;
|
||||||
import cn.bunny.dao.enums.LoginEnums;
|
|
||||||
import cn.bunny.dao.vo.result.Result;
|
import cn.bunny.dao.vo.result.Result;
|
||||||
|
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.dao.vo.system.user.LoginVo;
|
import cn.bunny.dao.vo.system.user.LoginVo;
|
||||||
import cn.bunny.services.security.handelr.SecurityAuthenticationFailureHandler;
|
import cn.bunny.services.security.handelr.SecurityAuthenticationFailureHandler;
|
||||||
import cn.bunny.services.security.handelr.SecurityAuthenticationSuccessHandler;
|
import cn.bunny.services.security.handelr.SecurityAuthenticationSuccessHandler;
|
||||||
import cn.bunny.services.service.UserService;
|
import cn.bunny.services.security.service.CustomUserDetailsService;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
import jakarta.servlet.FilterChain;
|
import jakarta.servlet.FilterChain;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.http.HttpMethod;
|
import org.springframework.http.HttpMethod;
|
||||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import static cn.bunny.common.service.utils.ResponseUtil.out;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义登录
|
* * UsernamePasswordAuthenticationFilter
|
||||||
* 自定义登录路径和自定义登录返回数据
|
* * 也可以在这里添加验证码、短信等的验证
|
||||||
|
* 由于SpringSecurity的登录只能是表单形式 并且用户名密码需要时username、password,可以通过继承 UsernamePasswordAuthenticationFilter 获取登录请求的参数
|
||||||
|
* 再去设置到 UsernamePasswordAuthenticationToken 中 来改变请求传参方式、参数名等 或者也可以在登录的时候加入其他参数等等
|
||||||
*/
|
*/
|
||||||
public class TokenLoginFilterService extends UsernamePasswordAuthenticationFilter {
|
public class TokenLoginFilterService extends UsernamePasswordAuthenticationFilter {
|
||||||
private final UserService userService;
|
|
||||||
LoginDto loginDto;
|
|
||||||
|
|
||||||
public TokenLoginFilterService(AuthenticationConfiguration authenticationConfiguration, UserService customUserDetailsService) throws Exception {
|
private final RedisTemplate<String, Object> redisTemplate;
|
||||||
|
private final CustomUserDetailsService customUserDetailsService;
|
||||||
|
private LoginDto loginDto;
|
||||||
|
|
||||||
|
public TokenLoginFilterService(AuthenticationConfiguration authenticationConfiguration, RedisTemplate<String, Object> redisTemplate, CustomUserDetailsService customUserDetailsService) throws Exception {
|
||||||
this.setAuthenticationSuccessHandler(new SecurityAuthenticationSuccessHandler());
|
this.setAuthenticationSuccessHandler(new SecurityAuthenticationSuccessHandler());
|
||||||
this.setAuthenticationFailureHandler(new SecurityAuthenticationFailureHandler());
|
this.setAuthenticationFailureHandler(new SecurityAuthenticationFailureHandler());
|
||||||
this.setPostOnly(false);
|
this.setPostOnly(false);
|
||||||
// 自定义登录路径,自定义登录请求类型
|
this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher("/admin/login", HttpMethod.POST.name()));
|
||||||
this.setRequiresAuthenticationRequestMatcher(new AntPathRequestMatcher(LoginEnums.LOGIN_REQUEST_API.getValue(), HttpMethod.POST.name()));
|
|
||||||
this.setAuthenticationManager(authenticationConfiguration.getAuthenticationManager());
|
this.setAuthenticationManager(authenticationConfiguration.getAuthenticationManager());
|
||||||
this.userService = customUserDetailsService;
|
this.redisTemplate = redisTemplate;
|
||||||
|
this.customUserDetailsService = customUserDetailsService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -50,22 +58,61 @@ public class TokenLoginFilterService extends UsernamePasswordAuthenticationFilte
|
||||||
ObjectMapper objectMapper = new ObjectMapper();
|
ObjectMapper objectMapper = new ObjectMapper();
|
||||||
try {
|
try {
|
||||||
loginDto = objectMapper.readValue(request.getInputStream(), LoginDto.class);
|
loginDto = objectMapper.readValue(request.getInputStream(), LoginDto.class);
|
||||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(loginDto.getUsername(), loginDto.getPassword());
|
|
||||||
return getAuthenticationManager().authenticate(authentication);
|
// type不能为空
|
||||||
} catch (Exception exception) {
|
String type = loginDto.getType();
|
||||||
throw new UsernameNotFoundException(exception.getMessage());
|
if (!StringUtils.hasText(type)) {
|
||||||
|
out(response, Result.error(ResultCodeEnum.REQUEST_IS_EMPTY));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String emailCode = loginDto.getEmailCode();
|
||||||
|
String username = loginDto.getUsername();
|
||||||
|
String password = loginDto.getPassword();
|
||||||
|
|
||||||
|
// 如果有邮箱验证码,表示是邮箱登录
|
||||||
|
if (type.equals("email")) {
|
||||||
|
emailCode = emailCode.toLowerCase();
|
||||||
|
Object redisEmailCode = redisTemplate.opsForValue().get(RedisUserConstant.getAdminUserEmailCodePrefix(username));
|
||||||
|
// --------TODO 线上取消注释这个
|
||||||
|
// ----测试
|
||||||
|
// --------线上取消注释这个
|
||||||
|
// if (redisEmailCode == null) {
|
||||||
|
// out(response, Result.error(ResultCodeEnum.EMAIL_CODE_EMPTY));
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// // 判断用户邮箱验证码是否和Redis中发送的验证码
|
||||||
|
// if (!emailCode.equals(redisEmailCode.toString().toLowerCase())) {
|
||||||
|
// out(response, Result.error(ResultCodeEnum.EMAIL_CODE_NOT_MATCHING));
|
||||||
|
// return null;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
Authentication authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
|
||||||
|
return getAuthenticationManager().authenticate(authenticationToken);
|
||||||
|
} catch (IOException e) {
|
||||||
|
out(response, Result.error(ResultCodeEnum.ILLEGAL_DATA_REQUEST));
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 验证成功
|
* 验证成功
|
||||||
* 在这里用户的账号和密码是对的
|
|
||||||
* 此时不要再去解析/转换 request.getInputStream() 因为流已经关闭
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication auth) {
|
protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication auth) {
|
||||||
LoginVo loginVo = userService.login(loginDto, response);
|
// 获取登录返回信息
|
||||||
ResponseUtil.out(response, Result.success(loginVo));
|
LoginVo loginVo = customUserDetailsService.login(loginDto, response);
|
||||||
|
if (loginVo == null) return;
|
||||||
|
|
||||||
|
// 判断用户是否禁用
|
||||||
|
if (loginVo.getStatus()) {
|
||||||
|
out(response, Result.error(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
out(response, Result.success(loginVo));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -73,6 +120,12 @@ public class TokenLoginFilterService extends UsernamePasswordAuthenticationFilte
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) {
|
protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) {
|
||||||
ResponseUtil.out(response, Result.error(null, failed.getMessage()));
|
String password = loginDto.getPassword();
|
||||||
|
String username = loginDto.getUsername();
|
||||||
|
|
||||||
|
if (!StringUtils.hasText(password) || !StringUtils.hasText(username))
|
||||||
|
out(response, Result.error(ResultCodeEnum.USERNAME_OR_PASSWORD_NOT_EMPTY));
|
||||||
|
else
|
||||||
|
out(response, Result.error(null, ResultCodeEnum.LOGIN_ERROR));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -7,12 +7,11 @@ import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.springframework.security.access.AccessDeniedException;
|
import org.springframework.security.access.AccessDeniedException;
|
||||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 没有权限访问
|
* 没有权限访问
|
||||||
*/
|
*/
|
||||||
public class SecurityAccessDeniedHandler implements AccessDeniedHandler {
|
public class SecurityAccessDeniedHandler implements org.springframework.security.web.access.AccessDeniedHandler {
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
@Override
|
@Override
|
||||||
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) {
|
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) {
|
||||||
|
|
|
@ -5,11 +5,10 @@ import com.alibaba.fastjson2.JSON;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
import org.springframework.security.core.AuthenticationException;
|
import org.springframework.security.core.AuthenticationException;
|
||||||
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
public class SecurityAuthenticationFailureHandler implements AuthenticationFailureHandler {
|
public class SecurityAuthenticationFailureHandler implements org.springframework.security.web.authentication.AuthenticationFailureHandler {
|
||||||
@Override
|
@Override
|
||||||
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {
|
public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException {
|
||||||
// 错误消息
|
// 错误消息
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
package cn.bunny.services.security.service;
|
||||||
|
|
||||||
|
import cn.bunny.dao.dto.system.user.LoginDto;
|
||||||
|
import cn.bunny.dao.vo.system.user.LoginVo;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
|
||||||
|
public interface CustomUserDetailsService extends UserDetailsService {
|
||||||
|
/**
|
||||||
|
* 根据用户名获取用户对象(获取不到直接抛异常)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
UserDetails loadUserByUsername(String username) throws UsernameNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前台用户登录接口
|
||||||
|
*
|
||||||
|
* @param loginDto 登录参数
|
||||||
|
* @return 登录后结果返回
|
||||||
|
*/
|
||||||
|
LoginVo login(LoginDto loginDto, HttpServletResponse response);
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.bunny.services.security.custom;
|
package cn.bunny.services.security.service.impl;
|
||||||
|
|
||||||
import cn.bunny.common.service.context.BaseContext;
|
import cn.bunny.common.service.context.BaseContext;
|
||||||
import cn.bunny.common.service.utils.JwtHelper;
|
import cn.bunny.common.service.utils.JwtHelper;
|
||||||
|
@ -9,7 +9,8 @@ import cn.bunny.dao.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.dao.vo.system.user.LoginVo;
|
import cn.bunny.dao.vo.system.user.LoginVo;
|
||||||
import cn.bunny.services.mapper.PowerMapper;
|
import cn.bunny.services.mapper.PowerMapper;
|
||||||
import cn.bunny.services.mapper.RoleMapper;
|
import cn.bunny.services.mapper.RoleMapper;
|
||||||
import cn.bunny.services.utils.RoleUtil;
|
import cn.bunny.services.security.custom.CustomAuthenticationException;
|
||||||
|
import cn.bunny.services.security.custom.CustomCheckIsAdmin;
|
||||||
import com.alibaba.fastjson2.JSON;
|
import com.alibaba.fastjson2.JSON;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
@ -18,7 +19,6 @@ import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.security.authorization.AuthorizationDecision;
|
import org.springframework.security.authorization.AuthorizationDecision;
|
||||||
import org.springframework.security.authorization.AuthorizationManager;
|
import org.springframework.security.authorization.AuthorizationManager;
|
||||||
import org.springframework.security.core.Authentication;
|
import org.springframework.security.core.Authentication;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
|
import org.springframework.security.web.access.intercept.RequestAuthorizationContext;
|
||||||
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
@ -54,12 +54,12 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag
|
||||||
// 判断是否有 token
|
// 判断是否有 token
|
||||||
String token = request.getHeader("token");
|
String token = request.getHeader("token");
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
throw new UsernameNotFoundException(ResultCodeEnum.LOGIN_AUTH.getMessage());
|
throw new CustomAuthenticationException(ResultCodeEnum.LOGIN_AUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断 token 是否过期
|
// 判断 token 是否过期
|
||||||
if (JwtHelper.isExpired(token)) {
|
if (JwtHelper.isExpired(token)) {
|
||||||
throw new UsernameNotFoundException(ResultCodeEnum.AUTHENTICATION_EXPIRED.getMessage());
|
throw new CustomAuthenticationException(ResultCodeEnum.AUTHENTICATION_EXPIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 解析JWT中的用户名
|
// 解析JWT中的用户名
|
||||||
|
@ -72,12 +72,12 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag
|
||||||
|
|
||||||
// 登录信息为空
|
// 登录信息为空
|
||||||
if (loginVo == null) {
|
if (loginVo == null) {
|
||||||
throw new UsernameNotFoundException(ResultCodeEnum.LOGIN_AUTH.getMessage());
|
throw new CustomAuthenticationException(ResultCodeEnum.LOGIN_AUTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 判断用户是否禁用
|
// 判断用户是否禁用
|
||||||
if (loginVo.getStatus()) {
|
if (loginVo.getStatus()) {
|
||||||
throw new UsernameNotFoundException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED.getMessage());
|
throw new CustomAuthenticationException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置用户信息
|
// 设置用户信息
|
||||||
|
@ -103,7 +103,7 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag
|
||||||
List<String> roleCodeList = roleList.stream().map(Role::getRoleCode).toList();
|
List<String> roleCodeList = roleList.stream().map(Role::getRoleCode).toList();
|
||||||
|
|
||||||
// 判断是否是管理员用户
|
// 判断是否是管理员用户
|
||||||
boolean checkedAdmin = RoleUtil.checkAdmin(roleCodeList);
|
boolean checkedAdmin = CustomCheckIsAdmin.checkAdmin(roleCodeList);
|
||||||
if (checkedAdmin) return true;
|
if (checkedAdmin) return true;
|
||||||
|
|
||||||
// 判断请求地址是否是 noManage 不需要被验证的
|
// 判断请求地址是否是 noManage 不需要被验证的
|
|
@ -0,0 +1,85 @@
|
||||||
|
package cn.bunny.services.security.service.impl;
|
||||||
|
|
||||||
|
import cn.bunny.common.service.exception.AuthCustomerException;
|
||||||
|
import cn.bunny.dao.dto.system.user.LoginDto;
|
||||||
|
import cn.bunny.dao.entity.system.AdminUser;
|
||||||
|
import cn.bunny.dao.vo.result.Result;
|
||||||
|
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
||||||
|
import cn.bunny.dao.vo.system.user.LoginVo;
|
||||||
|
import cn.bunny.services.factory.UserFactory;
|
||||||
|
import cn.bunny.services.mapper.UserMapper;
|
||||||
|
import cn.bunny.services.security.custom.CustomUser;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
import jakarta.servlet.http.HttpServletResponse;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.core.authority.AuthorityUtils;
|
||||||
|
import org.springframework.security.core.userdetails.UserDetails;
|
||||||
|
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.util.DigestUtils;
|
||||||
|
|
||||||
|
import static cn.bunny.common.service.utils.ResponseUtil.out;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class CustomUserDetailsServiceImpl implements cn.bunny.services.security.service.CustomUserDetailsService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserMapper userMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserFactory userFactory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户名获取用户对象(获取不到直接抛异常)
|
||||||
|
*
|
||||||
|
* @param username 用户名
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||||
|
// 查询用户相关内容
|
||||||
|
LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<AdminUser>()
|
||||||
|
.eq(AdminUser::getEmail, username)
|
||||||
|
.or()
|
||||||
|
.eq(AdminUser::getUsername, username);
|
||||||
|
|
||||||
|
// 根据邮箱查询用户名
|
||||||
|
AdminUser adminUser = userMapper.selectOne(queryWrapper);
|
||||||
|
if (adminUser == null) throw new UsernameNotFoundException(ResultCodeEnum.USER_IS_EMPTY.getMessage());
|
||||||
|
|
||||||
|
return new CustomUser(adminUser, AuthorityUtils.createAuthorityList());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 前台用户登录接口
|
||||||
|
*
|
||||||
|
* @param loginDto 登录参数
|
||||||
|
* @return 登录后结果返回
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public LoginVo login(LoginDto loginDto, HttpServletResponse response) {
|
||||||
|
String username = loginDto.getUsername();
|
||||||
|
String password = loginDto.getPassword();
|
||||||
|
Long readMeDay = loginDto.getReadMeDay();
|
||||||
|
|
||||||
|
// 查询用户相关内容
|
||||||
|
LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<>();
|
||||||
|
if (loginDto.getType().equals("email")) {
|
||||||
|
queryWrapper.eq(AdminUser::getEmail, username);
|
||||||
|
} else {
|
||||||
|
queryWrapper.eq(AdminUser::getUsername, username);
|
||||||
|
}
|
||||||
|
AdminUser user = userMapper.selectOne(queryWrapper);
|
||||||
|
|
||||||
|
// 判断用户是否为空
|
||||||
|
if (user == null) {
|
||||||
|
out(response, Result.error(ResultCodeEnum.LOGIN_ERROR));
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 对登录密码进行md5加密判断,是否与数据库中一致
|
||||||
|
String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
|
||||||
|
if (!user.getPassword().equals(md5Password)) throw new AuthCustomerException(ResultCodeEnum.LOGIN_ERROR);
|
||||||
|
|
||||||
|
return userFactory.buildLoginUserVo(user, readMeDay);
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,7 +6,6 @@ import cn.bunny.dao.vo.result.PageResult;
|
||||||
import cn.bunny.dao.vo.system.user.*;
|
import cn.bunny.dao.vo.system.user.*;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.IService;
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
@ -22,14 +21,6 @@ import java.util.List;
|
||||||
*/
|
*/
|
||||||
public interface UserService extends IService<AdminUser> {
|
public interface UserService extends IService<AdminUser> {
|
||||||
|
|
||||||
/**
|
|
||||||
* 前台用户登录接口
|
|
||||||
*
|
|
||||||
* @param loginDto 登录参数
|
|
||||||
* @return 登录后结果返回
|
|
||||||
*/
|
|
||||||
LoginVo login(LoginDto loginDto, HttpServletResponse response);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 获取用户信息列表
|
* * 获取用户信息列表
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,10 +9,10 @@ import cn.bunny.dao.entity.system.EmailUsers;
|
||||||
import cn.bunny.dao.vo.result.PageResult;
|
import cn.bunny.dao.vo.result.PageResult;
|
||||||
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.dao.vo.system.email.EmailUsersVo;
|
import cn.bunny.dao.vo.system.email.EmailUsersVo;
|
||||||
|
import cn.bunny.services.factory.EmailFactory;
|
||||||
import cn.bunny.services.mapper.EmailUsersMapper;
|
import cn.bunny.services.mapper.EmailUsersMapper;
|
||||||
import cn.bunny.services.service.EmailUsersService;
|
import cn.bunny.services.service.EmailUsersService;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
|
@ -38,7 +38,7 @@ import java.util.Map;
|
||||||
public class EmailUsersServiceImpl extends ServiceImpl<EmailUsersMapper, EmailUsers> implements EmailUsersService {
|
public class EmailUsersServiceImpl extends ServiceImpl<EmailUsersMapper, EmailUsers> implements EmailUsersService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private EmailUsersMapper emailUsersMapper;
|
private EmailFactory emailFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 邮箱用户发送配置 服务实现类
|
* * 邮箱用户发送配置 服务实现类
|
||||||
|
@ -67,7 +67,7 @@ public class EmailUsersServiceImpl extends ServiceImpl<EmailUsersMapper, EmailUs
|
||||||
@Override
|
@Override
|
||||||
public void addEmailUsers(EmailUsersAddDto dto) {
|
public void addEmailUsers(EmailUsersAddDto dto) {
|
||||||
// 更新邮箱默认状态
|
// 更新邮箱默认状态
|
||||||
updateEmailUserDefault(dto.getIsDefault());
|
emailFactory.updateEmailUserDefault(dto.getIsDefault());
|
||||||
|
|
||||||
// 保存数据
|
// 保存数据
|
||||||
EmailUsers emailUsers = new EmailUsers();
|
EmailUsers emailUsers = new EmailUsers();
|
||||||
|
@ -84,7 +84,7 @@ public class EmailUsersServiceImpl extends ServiceImpl<EmailUsersMapper, EmailUs
|
||||||
@Override
|
@Override
|
||||||
public void updateEmailUsers(@Valid EmailUsersUpdateDto dto) {
|
public void updateEmailUsers(@Valid EmailUsersUpdateDto dto) {
|
||||||
// 更新邮箱默认状态
|
// 更新邮箱默认状态
|
||||||
updateEmailUserDefault(dto.getIsDefault());
|
emailFactory.updateEmailUserDefault(dto.getIsDefault());
|
||||||
|
|
||||||
// 更新内容
|
// 更新内容
|
||||||
EmailUsers emailUsers = new EmailUsers();
|
EmailUsers emailUsers = new EmailUsers();
|
||||||
|
@ -113,7 +113,7 @@ public class EmailUsersServiceImpl extends ServiceImpl<EmailUsersMapper, EmailUs
|
||||||
@Override
|
@Override
|
||||||
public void updateEmailUserStatus(EmailUserUpdateStatusDto dto) {
|
public void updateEmailUserStatus(EmailUserUpdateStatusDto dto) {
|
||||||
// 更新邮箱默认状态
|
// 更新邮箱默认状态
|
||||||
updateEmailUserDefault(dto.getIsDefault());
|
emailFactory.updateEmailUserDefault(dto.getIsDefault());
|
||||||
|
|
||||||
EmailUsers emailUsers = new EmailUsers();
|
EmailUsers emailUsers = new EmailUsers();
|
||||||
BeanUtils.copyProperties(dto, emailUsers);
|
BeanUtils.copyProperties(dto, emailUsers);
|
||||||
|
@ -134,18 +134,4 @@ public class EmailUsersServiceImpl extends ServiceImpl<EmailUsersMapper, EmailUs
|
||||||
return map;
|
return map;
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断邮箱是否添加
|
|
||||||
*
|
|
||||||
* @param isDefault 邮箱是否为默认
|
|
||||||
*/
|
|
||||||
public void updateEmailUserDefault(Boolean isDefault) {
|
|
||||||
EmailUsers emailUsers = new EmailUsers();
|
|
||||||
// 判断状态,如果是默认将所有的内容都设为false
|
|
||||||
if (isDefault) {
|
|
||||||
emailUsers.setIsDefault(false);
|
|
||||||
emailUsersMapper.update(emailUsers, Wrappers.<EmailUsers>lambdaUpdate().eq(EmailUsers::getIsDefault, true));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,9 +11,9 @@ import cn.bunny.dao.vo.result.PageResult;
|
||||||
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.dao.vo.system.message.MessageReceivedWithMessageVo;
|
import cn.bunny.dao.vo.system.message.MessageReceivedWithMessageVo;
|
||||||
import cn.bunny.dao.vo.system.message.MessageUserVo;
|
import cn.bunny.dao.vo.system.message.MessageUserVo;
|
||||||
|
import cn.bunny.services.factory.UserFactory;
|
||||||
import cn.bunny.services.mapper.MessageReceivedMapper;
|
import cn.bunny.services.mapper.MessageReceivedMapper;
|
||||||
import cn.bunny.services.service.MessageReceivedService;
|
import cn.bunny.services.service.MessageReceivedService;
|
||||||
import cn.bunny.services.utils.UserUtil;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
@ -39,7 +39,7 @@ import java.util.List;
|
||||||
public class MessageReceivedServiceImpl extends ServiceImpl<MessageReceivedMapper, MessageReceived> implements MessageReceivedService {
|
public class MessageReceivedServiceImpl extends ServiceImpl<MessageReceivedMapper, MessageReceived> implements MessageReceivedService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserUtil userUtil;
|
private UserFactory userFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 管理员管理用户消息接收分页查询
|
* 管理员管理用户消息接收分页查询
|
||||||
|
@ -58,7 +58,7 @@ public class MessageReceivedServiceImpl extends ServiceImpl<MessageReceivedMappe
|
||||||
|
|
||||||
// 设置封面返回内容
|
// 设置封面返回内容
|
||||||
String cover = vo.getCover();
|
String cover = vo.getCover();
|
||||||
cover = userUtil.checkGetUserAvatar(cover);
|
cover = userFactory.checkGetUserAvatar(cover);
|
||||||
vo.setCover(cover);
|
vo.setCover(cover);
|
||||||
return vo;
|
return vo;
|
||||||
}).toList();
|
}).toList();
|
||||||
|
@ -113,7 +113,7 @@ public class MessageReceivedServiceImpl extends ServiceImpl<MessageReceivedMappe
|
||||||
|
|
||||||
// 设置封面返回内容
|
// 设置封面返回内容
|
||||||
String cover = vo.getCover();
|
String cover = vo.getCover();
|
||||||
cover = userUtil.checkGetUserAvatar(cover);
|
cover = userFactory.checkGetUserAvatar(cover);
|
||||||
vo.setCover(cover);
|
vo.setCover(cover);
|
||||||
return vo;
|
return vo;
|
||||||
}).toList();
|
}).toList();
|
||||||
|
|
|
@ -14,12 +14,12 @@ import cn.bunny.dao.vo.system.message.MessageDetailVo;
|
||||||
import cn.bunny.dao.vo.system.message.MessageReceivedWithMessageVo;
|
import cn.bunny.dao.vo.system.message.MessageReceivedWithMessageVo;
|
||||||
import cn.bunny.dao.vo.system.message.MessageReceivedWithUserVo;
|
import cn.bunny.dao.vo.system.message.MessageReceivedWithUserVo;
|
||||||
import cn.bunny.dao.vo.system.message.MessageVo;
|
import cn.bunny.dao.vo.system.message.MessageVo;
|
||||||
|
import cn.bunny.services.factory.UserFactory;
|
||||||
import cn.bunny.services.mapper.MessageMapper;
|
import cn.bunny.services.mapper.MessageMapper;
|
||||||
import cn.bunny.services.mapper.MessageReceivedMapper;
|
import cn.bunny.services.mapper.MessageReceivedMapper;
|
||||||
import cn.bunny.services.mapper.UserMapper;
|
import cn.bunny.services.mapper.UserMapper;
|
||||||
import cn.bunny.services.service.MessageReceivedService;
|
import cn.bunny.services.service.MessageReceivedService;
|
||||||
import cn.bunny.services.service.MessageService;
|
import cn.bunny.services.service.MessageService;
|
||||||
import cn.bunny.services.utils.UserUtil;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
|
@ -48,7 +48,7 @@ import java.util.stream.Collectors;
|
||||||
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements MessageService {
|
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements MessageService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserUtil userUtil;
|
private UserFactory userFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private MessageReceivedMapper messageReceivedMapper;
|
private MessageReceivedMapper messageReceivedMapper;
|
||||||
|
@ -152,7 +152,7 @@ public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> impl
|
||||||
|
|
||||||
// 设置封面返回内容
|
// 设置封面返回内容
|
||||||
String cover = dto.getCover();
|
String cover = dto.getCover();
|
||||||
dto.setCover(userUtil.checkGetUserAvatar(cover));
|
dto.setCover(userFactory.checkGetUserAvatar(cover));
|
||||||
|
|
||||||
// 先保存消息数据,之后拿到保存消息的id
|
// 先保存消息数据,之后拿到保存消息的id
|
||||||
Message message = new Message();
|
Message message = new Message();
|
||||||
|
@ -198,7 +198,7 @@ public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> impl
|
||||||
|
|
||||||
// 设置封面返回内容
|
// 设置封面返回内容
|
||||||
String cover = dto.getCover();
|
String cover = dto.getCover();
|
||||||
dto.setCover(userUtil.checkGetUserAvatar(cover));
|
dto.setCover(userFactory.checkGetUserAvatar(cover));
|
||||||
|
|
||||||
// 更新内容
|
// 更新内容
|
||||||
Message message = new Message();
|
Message message = new Message();
|
||||||
|
|
|
@ -4,11 +4,11 @@ import cn.bunny.dao.dto.system.rolePower.AssignPowersToRoleDto;
|
||||||
import cn.bunny.dao.entity.system.AdminUser;
|
import cn.bunny.dao.entity.system.AdminUser;
|
||||||
import cn.bunny.dao.entity.system.RolePower;
|
import cn.bunny.dao.entity.system.RolePower;
|
||||||
import cn.bunny.dao.entity.system.UserRole;
|
import cn.bunny.dao.entity.system.UserRole;
|
||||||
|
import cn.bunny.services.factory.RoleFactory;
|
||||||
import cn.bunny.services.mapper.RolePowerMapper;
|
import cn.bunny.services.mapper.RolePowerMapper;
|
||||||
import cn.bunny.services.mapper.UserMapper;
|
import cn.bunny.services.mapper.UserMapper;
|
||||||
import cn.bunny.services.mapper.UserRoleMapper;
|
import cn.bunny.services.mapper.UserRoleMapper;
|
||||||
import cn.bunny.services.service.RolePowerService;
|
import cn.bunny.services.service.RolePowerService;
|
||||||
import cn.bunny.services.utils.RoleUtil;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -33,7 +33,7 @@ public class RolePowerServiceImpl extends ServiceImpl<RolePowerMapper, RolePower
|
||||||
private UserMapper userMapper;
|
private UserMapper userMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RoleUtil roleUtil;
|
private RoleFactory roleFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRoleMapper userRoleMapper;
|
private UserRoleMapper userRoleMapper;
|
||||||
|
@ -84,6 +84,6 @@ public class RolePowerServiceImpl extends ServiceImpl<RolePowerMapper, RolePower
|
||||||
|
|
||||||
// 更新Redis中用户信息
|
// 更新Redis中用户信息
|
||||||
List<Long> userIds = adminUsers.stream().map(AdminUser::getId).toList();
|
List<Long> userIds = adminUsers.stream().map(AdminUser::getId).toList();
|
||||||
roleUtil.updateUserRedisInfo(userIds);
|
roleFactory.updateUserRedisInfo(userIds);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,12 @@ import cn.bunny.dao.entity.system.UserRole;
|
||||||
import cn.bunny.dao.vo.result.PageResult;
|
import cn.bunny.dao.vo.result.PageResult;
|
||||||
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.dao.vo.system.rolePower.RoleVo;
|
import cn.bunny.dao.vo.system.rolePower.RoleVo;
|
||||||
|
import cn.bunny.services.factory.RoleFactory;
|
||||||
import cn.bunny.services.mapper.RoleMapper;
|
import cn.bunny.services.mapper.RoleMapper;
|
||||||
import cn.bunny.services.mapper.RolePowerMapper;
|
import cn.bunny.services.mapper.RolePowerMapper;
|
||||||
import cn.bunny.services.mapper.RouterRoleMapper;
|
import cn.bunny.services.mapper.RouterRoleMapper;
|
||||||
import cn.bunny.services.mapper.UserRoleMapper;
|
import cn.bunny.services.mapper.UserRoleMapper;
|
||||||
import cn.bunny.services.service.RoleService;
|
import cn.bunny.services.service.RoleService;
|
||||||
import cn.bunny.services.utils.RoleUtil;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
@ -49,7 +49,7 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
|
||||||
private RouterRoleMapper routerRoleMapper;
|
private RouterRoleMapper routerRoleMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RoleUtil roleUtil;
|
private RoleFactory roleFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 角色 服务实现类
|
* * 角色 服务实现类
|
||||||
|
@ -118,7 +118,7 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements Ro
|
||||||
// 找到所有和当前更新角色相同的用户,并更新Redis中用户信息
|
// 找到所有和当前更新角色相同的用户,并更新Redis中用户信息
|
||||||
List<Long> userIds = userRoleMapper.selectList(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getRoleId, dto.getId()))
|
List<Long> userIds = userRoleMapper.selectList(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getRoleId, dto.getId()))
|
||||||
.stream().map(UserRole::getUserId).toList();
|
.stream().map(UserRole::getUserId).toList();
|
||||||
roleUtil.updateUserRedisInfo(userIds);
|
roleFactory.updateUserRedisInfo(userIds);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,13 +15,13 @@ import cn.bunny.dao.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.dao.vo.system.router.RouterManageVo;
|
import cn.bunny.dao.vo.system.router.RouterManageVo;
|
||||||
import cn.bunny.dao.vo.system.router.RouterMeta;
|
import cn.bunny.dao.vo.system.router.RouterMeta;
|
||||||
import cn.bunny.dao.vo.system.router.UserRouterVo;
|
import cn.bunny.dao.vo.system.router.UserRouterVo;
|
||||||
|
import cn.bunny.services.factory.RouterServiceFactory;
|
||||||
import cn.bunny.services.mapper.RoleMapper;
|
import cn.bunny.services.mapper.RoleMapper;
|
||||||
import cn.bunny.services.mapper.RolePowerMapper;
|
import cn.bunny.services.mapper.RolePowerMapper;
|
||||||
import cn.bunny.services.mapper.RouterMapper;
|
import cn.bunny.services.mapper.RouterMapper;
|
||||||
import cn.bunny.services.mapper.RouterRoleMapper;
|
import cn.bunny.services.mapper.RouterRoleMapper;
|
||||||
|
import cn.bunny.services.security.custom.CustomCheckIsAdmin;
|
||||||
import cn.bunny.services.service.RouterService;
|
import cn.bunny.services.service.RouterService;
|
||||||
import cn.bunny.services.utils.RoleUtil;
|
|
||||||
import cn.bunny.services.utils.RouterServiceUtil;
|
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
@ -46,7 +46,7 @@ import java.util.stream.Collectors;
|
||||||
@Transactional
|
@Transactional
|
||||||
public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> implements RouterService {
|
public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> implements RouterService {
|
||||||
@Autowired
|
@Autowired
|
||||||
private RouterServiceUtil routerServiceUtil;
|
private RouterServiceFactory routerServiceFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RoleMapper roleMapper;
|
private RoleMapper roleMapper;
|
||||||
|
@ -84,7 +84,7 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
|
||||||
List<UserRouterVo> list = new ArrayList<>();
|
List<UserRouterVo> list = new ArrayList<>();
|
||||||
|
|
||||||
// 查询用户角色,判断是否是管理员角色
|
// 查询用户角色,判断是否是管理员角色
|
||||||
boolean isAdmin = RoleUtil.checkAdmin(userRoleCodeList);
|
boolean isAdmin = CustomCheckIsAdmin.checkAdmin(userRoleCodeList);
|
||||||
|
|
||||||
// 查询路由和角色对应关系
|
// 查询路由和角色对应关系
|
||||||
List<ViewRouterRole> routerRoleList = routerRoleMapper.viewRouterRolesWithAll();
|
List<ViewRouterRole> routerRoleList = routerRoleMapper.viewRouterRolesWithAll();
|
||||||
|
@ -151,7 +151,7 @@ public class RouterServiceImpl extends ServiceImpl<RouterMapper, Router> impleme
|
||||||
// 构建树形结构
|
// 构建树形结构
|
||||||
routerVoList.forEach(routerVo -> {
|
routerVoList.forEach(routerVo -> {
|
||||||
if (routerVo.getParentId() == 0) {
|
if (routerVo.getParentId() == 0) {
|
||||||
routerVo.setChildren(routerServiceUtil.handleGetChildrenWIthRouter(routerVo.getId(), routerVoList));
|
routerVo.setChildren(routerServiceFactory.handleGetChildrenWIthRouter(routerVo.getId(), routerVoList));
|
||||||
list.add(routerVo);
|
list.add(routerVo);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -8,10 +8,10 @@ import cn.bunny.dao.entity.system.AdminUser;
|
||||||
import cn.bunny.dao.entity.system.UserRole;
|
import cn.bunny.dao.entity.system.UserRole;
|
||||||
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.dao.vo.system.user.LoginVo;
|
import cn.bunny.dao.vo.system.user.LoginVo;
|
||||||
|
import cn.bunny.services.factory.UserFactory;
|
||||||
import cn.bunny.services.mapper.UserMapper;
|
import cn.bunny.services.mapper.UserMapper;
|
||||||
import cn.bunny.services.mapper.UserRoleMapper;
|
import cn.bunny.services.mapper.UserRoleMapper;
|
||||||
import cn.bunny.services.service.UserRoleService;
|
import cn.bunny.services.service.UserRoleService;
|
||||||
import cn.bunny.services.utils.UserUtil;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -38,7 +38,7 @@ public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> i
|
||||||
private UserRoleMapper userRoleMapper;
|
private UserRoleMapper userRoleMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserUtil userUtil;
|
private UserFactory userFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserMapper userMapper;
|
private UserMapper userMapper;
|
||||||
|
@ -94,7 +94,7 @@ public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> i
|
||||||
|
|
||||||
// 重新设置Redis中的用户存储信息vo对象
|
// 重新设置Redis中的用户存储信息vo对象
|
||||||
String username = adminUser.getUsername();
|
String username = adminUser.getUsername();
|
||||||
loginVo = userUtil.buildLoginUserVo(adminUser, readMeDay);
|
loginVo = userFactory.buildLoginUserVo(adminUser, readMeDay);
|
||||||
redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(username), loginVo, readMeDay, TimeUnit.DAYS);
|
redisTemplate.opsForValue().set(RedisUserConstant.getAdminLoginInfoPrefix(username), loginVo, readMeDay, TimeUnit.DAYS);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,24 +10,20 @@ import cn.bunny.dao.dto.system.files.FileUploadDto;
|
||||||
import cn.bunny.dao.dto.system.user.*;
|
import cn.bunny.dao.dto.system.user.*;
|
||||||
import cn.bunny.dao.entity.log.UserLoginLog;
|
import cn.bunny.dao.entity.log.UserLoginLog;
|
||||||
import cn.bunny.dao.entity.system.AdminUser;
|
import cn.bunny.dao.entity.system.AdminUser;
|
||||||
|
import cn.bunny.dao.entity.system.EmailTemplate;
|
||||||
import cn.bunny.dao.entity.system.Role;
|
import cn.bunny.dao.entity.system.Role;
|
||||||
import cn.bunny.dao.entity.system.UserDept;
|
import cn.bunny.dao.entity.system.UserDept;
|
||||||
import cn.bunny.dao.enums.EmailTemplateEnums;
|
import cn.bunny.dao.enums.EmailTemplateEnums;
|
||||||
import cn.bunny.dao.enums.LoginEnums;
|
|
||||||
import cn.bunny.dao.views.ViewUserDept;
|
import cn.bunny.dao.views.ViewUserDept;
|
||||||
import cn.bunny.dao.vo.result.PageResult;
|
import cn.bunny.dao.vo.result.PageResult;
|
||||||
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
||||||
import cn.bunny.dao.vo.system.files.FileInfoVo;
|
import cn.bunny.dao.vo.system.files.FileInfoVo;
|
||||||
import cn.bunny.dao.vo.system.user.*;
|
import cn.bunny.dao.vo.system.user.*;
|
||||||
|
import cn.bunny.services.factory.EmailFactory;
|
||||||
|
import cn.bunny.services.factory.UserFactory;
|
||||||
import cn.bunny.services.mapper.*;
|
import cn.bunny.services.mapper.*;
|
||||||
import cn.bunny.services.service.FilesService;
|
import cn.bunny.services.service.FilesService;
|
||||||
import cn.bunny.services.service.UserService;
|
import cn.bunny.services.service.UserService;
|
||||||
import cn.bunny.services.utils.UserUtil;
|
|
||||||
import cn.bunny.services.utils.email.ConcreteSenderEmailTemplate;
|
|
||||||
import cn.bunny.services.utils.login.DefaultLoginStrategy;
|
|
||||||
import cn.bunny.services.utils.login.EmailLoginStrategy;
|
|
||||||
import cn.bunny.services.utils.login.LoginContext;
|
|
||||||
import cn.bunny.services.utils.login.LoginStrategy;
|
|
||||||
import cn.hutool.captcha.CaptchaUtil;
|
import cn.hutool.captcha.CaptchaUtil;
|
||||||
import cn.hutool.captcha.CircleCaptcha;
|
import cn.hutool.captcha.CircleCaptcha;
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
|
@ -35,17 +31,15 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
|
||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.springframework.beans.BeanUtils;
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
import org.springframework.util.DigestUtils;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.multipart.MultipartFile;
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
@ -65,58 +59,31 @@ import java.util.concurrent.TimeUnit;
|
||||||
public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implements UserService {
|
public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implements UserService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserUtil userUtil;
|
private UserFactory userFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ConcreteSenderEmailTemplate concreteSenderEmailTemplate;
|
private EmailFactory emailFactory;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
private RedisTemplate<String, Object> redisTemplate;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private FilesService filesService;
|
private FilesService filesService;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserDeptMapper userDeptMapper;
|
private UserDeptMapper userDeptMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRoleMapper userRoleMapper;
|
private UserRoleMapper userRoleMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserLoginLogMapper userLoginLogMapper;
|
private UserLoginLogMapper userLoginLogMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private EmailTemplateMapper emailTemplateMapper;
|
private EmailTemplateMapper emailTemplateMapper;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RoleMapper roleMapper;
|
private RoleMapper roleMapper;
|
||||||
@Autowired
|
|
||||||
private UserMapper userMapper;
|
|
||||||
@Autowired
|
|
||||||
private PasswordEncoder passwordEncoder;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 前台用户登录接口
|
|
||||||
* 这里不用判断用户是否为空,因为在登录时已经校验过了
|
|
||||||
* <p>
|
|
||||||
* 抛出异常使用自带的 UsernameNotFoundException 或者自己封装<br/>
|
|
||||||
* 但是这两个效果传入参数都是一样的,所以全部使用 UsernameNotFoundException
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param loginDto 登录参数
|
|
||||||
* @return 登录后结果返回
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public LoginVo login(LoginDto loginDto, HttpServletResponse response) {
|
|
||||||
Long readMeDay = loginDto.getReadMeDay();
|
|
||||||
|
|
||||||
// 初始化登录策略,如果有需要添加策略放在这里
|
|
||||||
HashMap<String, LoginStrategy> loginStrategyHashMap = new HashMap<>();
|
|
||||||
loginStrategyHashMap.put(LoginEnums.EMAIL_STRATEGY.getValue(), new EmailLoginStrategy(redisTemplate, userMapper));
|
|
||||||
loginStrategyHashMap.put(LoginEnums.default_STRATEGY.getValue(), new DefaultLoginStrategy(userMapper));
|
|
||||||
|
|
||||||
// 使用登录上下文调用登录策略
|
|
||||||
LoginContext loginContext = new LoginContext(loginStrategyHashMap);
|
|
||||||
AdminUser user = loginContext.executeStrategy(loginDto);
|
|
||||||
|
|
||||||
// 判断用户是否禁用
|
|
||||||
if (user.getStatus()) {
|
|
||||||
throw new UsernameNotFoundException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED.getMessage());
|
|
||||||
}
|
|
||||||
return userUtil.buildLoginUserVo(user, readMeDay);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录发送邮件验证码
|
* 登录发送邮件验证码
|
||||||
|
@ -126,10 +93,10 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
@Override
|
@Override
|
||||||
public void sendLoginEmail(@NotNull String email) {
|
public void sendLoginEmail(@NotNull String email) {
|
||||||
// 查询验证码邮件模板
|
// 查询验证码邮件模板
|
||||||
LambdaQueryWrapper<cn.bunny.dao.entity.system.EmailTemplate> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
LambdaQueryWrapper<EmailTemplate> lambdaQueryWrapper = new LambdaQueryWrapper<>();
|
||||||
lambdaQueryWrapper.eq(cn.bunny.dao.entity.system.EmailTemplate::getIsDefault, true);
|
lambdaQueryWrapper.eq(EmailTemplate::getIsDefault, true);
|
||||||
lambdaQueryWrapper.eq(cn.bunny.dao.entity.system.EmailTemplate::getType, EmailTemplateEnums.VERIFICATION_CODE.getType());
|
lambdaQueryWrapper.eq(EmailTemplate::getType, EmailTemplateEnums.VERIFICATION_CODE.getType());
|
||||||
cn.bunny.dao.entity.system.EmailTemplate emailTemplate = emailTemplateMapper.selectOne(lambdaQueryWrapper);
|
EmailTemplate emailTemplate = emailTemplateMapper.selectOne(lambdaQueryWrapper);
|
||||||
|
|
||||||
// 生成验证码
|
// 生成验证码
|
||||||
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(150, 48, 4, 2);
|
CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(150, 48, 4, 2);
|
||||||
|
@ -144,7 +111,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
hashMap.put("#companyName#", "BunnyAdmin");
|
hashMap.put("#companyName#", "BunnyAdmin");
|
||||||
|
|
||||||
// 发送邮件
|
// 发送邮件
|
||||||
concreteSenderEmailTemplate.sendEmail(email, emailTemplate, hashMap);
|
emailFactory.sendEmailTemplate(email, emailTemplate, hashMap);
|
||||||
|
|
||||||
// 在Redis中存储验证码
|
// 在Redis中存储验证码
|
||||||
redisTemplate.opsForValue().set(RedisUserConstant.getAdminUserEmailCodePrefix(email), emailCode, RedisUserConstant.REDIS_EXPIRATION_TIME, TimeUnit.MINUTES);
|
redisTemplate.opsForValue().set(RedisUserConstant.getAdminUserEmailCodePrefix(email), emailCode, RedisUserConstant.REDIS_EXPIRATION_TIME, TimeUnit.MINUTES);
|
||||||
|
@ -165,7 +132,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
if (adminUser == null) throw new AuthCustomerException(ResultCodeEnum.USER_IS_EMPTY);
|
if (adminUser == null) throw new AuthCustomerException(ResultCodeEnum.USER_IS_EMPTY);
|
||||||
if (adminUser.getStatus()) throw new AuthCustomerException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED);
|
if (adminUser.getStatus()) throw new AuthCustomerException(ResultCodeEnum.FAIL_NO_ACCESS_DENIED_USER_LOCKED);
|
||||||
|
|
||||||
LoginVo buildUserVo = userUtil.buildLoginUserVo(adminUser, dto.getReadMeDay());
|
LoginVo buildUserVo = userFactory.buildLoginUserVo(adminUser, dto.getReadMeDay());
|
||||||
RefreshTokenVo refreshTokenVo = new RefreshTokenVo();
|
RefreshTokenVo refreshTokenVo = new RefreshTokenVo();
|
||||||
BeanUtils.copyProperties(buildUserVo, refreshTokenVo);
|
BeanUtils.copyProperties(buildUserVo, refreshTokenVo);
|
||||||
|
|
||||||
|
@ -188,7 +155,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
|
|
||||||
// 查询用户信息
|
// 查询用户信息
|
||||||
AdminUser adminUser = getOne(Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getId, userId));
|
AdminUser adminUser = getOne(Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getId, userId));
|
||||||
UserLoginLog userLoginLog = userUtil.setUserLoginLog(adminUser, token, ipAddr, ipRegion, "logout");
|
UserLoginLog userLoginLog = userFactory.setUserLoginLog(adminUser, token, ipAddr, ipRegion, "logout");
|
||||||
userLoginLogMapper.insert(userLoginLog);
|
userLoginLogMapper.insert(userLoginLog);
|
||||||
|
|
||||||
// 删除Redis中用户信息
|
// 删除Redis中用户信息
|
||||||
|
@ -215,7 +182,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
UserVo userVo = new UserVo();
|
UserVo userVo = new UserVo();
|
||||||
BeanUtils.copyProperties(user, userVo);
|
BeanUtils.copyProperties(user, userVo);
|
||||||
|
|
||||||
userVo.setAvatar(userUtil.checkGetUserAvatar(avatar));
|
userVo.setAvatar(userFactory.checkGetUserAvatar(avatar));
|
||||||
return userVo;
|
return userVo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,19 +197,19 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
String password = dto.getPassword();
|
String password = dto.getPassword();
|
||||||
|
|
||||||
// 对密码加密
|
// 对密码加密
|
||||||
String encode = passwordEncoder.encode(password);
|
String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
|
||||||
AdminUser adminUser = getOne(Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getId, userId));
|
AdminUser adminUser = getOne(Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getId, userId));
|
||||||
|
|
||||||
// 判断是否存在这个用户
|
// 判断是否存在这个用户
|
||||||
if (adminUser == null) throw new AuthCustomerException(ResultCodeEnum.USER_IS_EMPTY);
|
if (adminUser == null) throw new AuthCustomerException(ResultCodeEnum.USER_IS_EMPTY);
|
||||||
|
|
||||||
// 判断新密码是否与旧密码相同
|
// 判断新密码是否与旧密码相同
|
||||||
if (adminUser.getPassword().equals(encode))
|
if (adminUser.getPassword().equals(md5Password))
|
||||||
throw new AuthCustomerException(ResultCodeEnum.UPDATE_NEW_PASSWORD_SAME_AS_OLD_PASSWORD);
|
throw new AuthCustomerException(ResultCodeEnum.UPDATE_NEW_PASSWORD_SAME_AS_OLD_PASSWORD);
|
||||||
|
|
||||||
// 更新用户密码
|
// 更新用户密码
|
||||||
adminUser = new AdminUser();
|
adminUser = new AdminUser();
|
||||||
adminUser.setPassword(encode);
|
adminUser.setPassword(md5Password);
|
||||||
adminUser.setId(userId);
|
adminUser.setId(userId);
|
||||||
updateById(adminUser);
|
updateById(adminUser);
|
||||||
|
|
||||||
|
@ -277,7 +244,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
|
|
||||||
// 重新生成用户信息到Redis中
|
// 重新生成用户信息到Redis中
|
||||||
user.setAvatar(adminUser.getAvatar());
|
user.setAvatar(adminUser.getAvatar());
|
||||||
userUtil.buildUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME);
|
userFactory.buildUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -376,7 +343,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
if (user == null) throw new AuthCustomerException(ResultCodeEnum.USER_IS_EMPTY);
|
if (user == null) throw new AuthCustomerException(ResultCodeEnum.USER_IS_EMPTY);
|
||||||
|
|
||||||
// 检查用户头像
|
// 检查用户头像
|
||||||
dto.setAvatar(userUtil.checkPostUserAvatar(dto.getAvatar()));
|
dto.setAvatar(userFactory.checkPostUserAvatar(dto.getAvatar()));
|
||||||
|
|
||||||
// 更新用户
|
// 更新用户
|
||||||
AdminUser adminUser = new AdminUser();
|
AdminUser adminUser = new AdminUser();
|
||||||
|
@ -386,7 +353,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
|
|
||||||
// 重新生成用户信息到Redis中
|
// 重新生成用户信息到Redis中
|
||||||
BeanUtils.copyProperties(dto, user);
|
BeanUtils.copyProperties(dto, user);
|
||||||
userUtil.buildUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME);
|
userFactory.buildUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -405,7 +372,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
|
|
||||||
// 数据库中的密码
|
// 数据库中的密码
|
||||||
String dbPassword = adminUser.getPassword();
|
String dbPassword = adminUser.getPassword();
|
||||||
password = passwordEncoder.encode(password);
|
password = DigestUtils.md5DigestAsHex(password.getBytes());
|
||||||
|
|
||||||
// 判断数据库中密码是否和更新用户密码相同
|
// 判断数据库中密码是否和更新用户密码相同
|
||||||
if (dbPassword.equals(password)) throw new AuthCustomerException(ResultCodeEnum.NEW_PASSWORD_SAME_OLD_PASSWORD);
|
if (dbPassword.equals(password)) throw new AuthCustomerException(ResultCodeEnum.NEW_PASSWORD_SAME_OLD_PASSWORD);
|
||||||
|
@ -434,7 +401,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
List<AdminUserVo> voList = page.getRecords().stream()
|
List<AdminUserVo> voList = page.getRecords().stream()
|
||||||
.map(adminUser -> {
|
.map(adminUser -> {
|
||||||
// 如果存在用户头像,则设置用户头像
|
// 如果存在用户头像,则设置用户头像
|
||||||
String avatar = userUtil.checkGetUserAvatar(adminUser.getAvatar());
|
String avatar = userFactory.checkGetUserAvatar(adminUser.getAvatar());
|
||||||
|
|
||||||
AdminUserVo adminUserVo = new AdminUserVo();
|
AdminUserVo adminUserVo = new AdminUserVo();
|
||||||
BeanUtils.copyProperties(adminUser, adminUserVo);
|
BeanUtils.copyProperties(adminUser, adminUserVo);
|
||||||
|
@ -462,12 +429,12 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
@Override
|
@Override
|
||||||
public void addAdminUser(@Valid AdminUserAddDto dto) {
|
public void addAdminUser(@Valid AdminUserAddDto dto) {
|
||||||
// 对密码加密
|
// 对密码加密
|
||||||
String encode = passwordEncoder.encode(dto.getPassword());
|
String md5Password = DigestUtils.md5DigestAsHex(dto.getPassword().getBytes());
|
||||||
|
|
||||||
// 保存数据
|
// 保存数据
|
||||||
AdminUser adminUser = new AdminUser();
|
AdminUser adminUser = new AdminUser();
|
||||||
BeanUtils.copyProperties(dto, adminUser);
|
BeanUtils.copyProperties(dto, adminUser);
|
||||||
adminUser.setPassword(encode);
|
adminUser.setPassword(md5Password);
|
||||||
save(adminUser);
|
save(adminUser);
|
||||||
|
|
||||||
// 插入用户部门关系表
|
// 插入用户部门关系表
|
||||||
|
@ -521,7 +488,7 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
|
|
||||||
// 重新生成用户信息到Redis中
|
// 重新生成用户信息到Redis中
|
||||||
BeanUtils.copyProperties(dto, adminUser);
|
BeanUtils.copyProperties(dto, adminUser);
|
||||||
userUtil.buildUserVo(adminUser, RedisUserConstant.REDIS_EXPIRATION_TIME);
|
userFactory.buildUserVo(adminUser, RedisUserConstant.REDIS_EXPIRATION_TIME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,84 +0,0 @@
|
||||||
package cn.bunny.services.utils;
|
|
||||||
|
|
||||||
import cn.bunny.common.service.context.BaseContext;
|
|
||||||
import cn.bunny.dao.constant.RedisUserConstant;
|
|
||||||
import cn.bunny.dao.entity.system.AdminUser;
|
|
||||||
import cn.bunny.services.mapper.UserMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class RoleUtil {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private RedisTemplate<String, Object> redisTemplate;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserMapper userMapper;
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private UserUtil userUtil;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否是管理员
|
|
||||||
*
|
|
||||||
* @param roleList 角色代码列表
|
|
||||||
* @param permissions 权限列表
|
|
||||||
* @param adminUser 用户信息
|
|
||||||
* @return 是否是管理员
|
|
||||||
*/
|
|
||||||
public static boolean checkAdmin(List<String> roleList, List<String> permissions, AdminUser adminUser) {
|
|
||||||
// 判断是否是超级管理员
|
|
||||||
boolean isIdAdmin = adminUser.getId().equals(1L);
|
|
||||||
boolean isAdmin = roleList.stream().anyMatch(role -> role.equals("admin"));
|
|
||||||
|
|
||||||
// 判断是否是 admin
|
|
||||||
if (isIdAdmin || isAdmin) {
|
|
||||||
roleList.add("admin");
|
|
||||||
permissions.add("*");
|
|
||||||
permissions.add("*::*");
|
|
||||||
permissions.add("*::*::*");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否是管理员
|
|
||||||
*
|
|
||||||
* @param roleList 角色代码列表
|
|
||||||
* @return 是否是管理员
|
|
||||||
*/
|
|
||||||
public static boolean checkAdmin(List<String> roleList) {
|
|
||||||
// 判断是否是超级管理员
|
|
||||||
if (BaseContext.getUserId().equals(1L)) return true;
|
|
||||||
|
|
||||||
// 判断是否是 admin
|
|
||||||
return roleList.stream().anyMatch(role -> role.equals("admin"));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 批量更新Redis中用户信息
|
|
||||||
*
|
|
||||||
* @param userIds 用户Id列表
|
|
||||||
*/
|
|
||||||
public void updateUserRedisInfo(List<Long> userIds) {
|
|
||||||
// 根据Id查找所有用户
|
|
||||||
List<AdminUser> adminUsers = userMapper.selectList(Wrappers.<AdminUser>lambdaQuery().in(AdminUser::getId, userIds));
|
|
||||||
|
|
||||||
// 用户为空时不更新Redis的key
|
|
||||||
if (adminUsers.isEmpty()) return;
|
|
||||||
|
|
||||||
// 更新Redis中用户信息
|
|
||||||
adminUsers.stream().filter(user -> {
|
|
||||||
String adminLoginInfoPrefix = RedisUserConstant.getAdminLoginInfoPrefix(user.getUsername());
|
|
||||||
Object object = redisTemplate.opsForValue().get(adminLoginInfoPrefix);
|
|
||||||
return object != null;
|
|
||||||
}).forEach(user -> userUtil.buildUserVo(user, RedisUserConstant.REDIS_EXPIRATION_TIME));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,28 +0,0 @@
|
||||||
package cn.bunny.services.utils.email;
|
|
||||||
|
|
||||||
import cn.bunny.dao.entity.system.EmailTemplate;
|
|
||||||
import cn.bunny.services.mapper.EmailTemplateMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public class ConcreteSenderEmailTemplate extends AbstractSenderEmailTemplate {
|
|
||||||
@Autowired
|
|
||||||
private EmailTemplateMapper emailTemplateMapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 发送邮件模板
|
|
||||||
* 根据邮件模板发送邮件
|
|
||||||
*
|
|
||||||
* @param email 邮件
|
|
||||||
* @param emailTemplateId 模板Id
|
|
||||||
* @param params 替换参数
|
|
||||||
*/
|
|
||||||
public void sendEmailTemplate(String email, Long emailTemplateId, HashMap<String, Object> params) {
|
|
||||||
EmailTemplate emailTemplate = emailTemplateMapper.selectOne(Wrappers.<EmailTemplate>lambdaQuery().eq(EmailTemplate::getId, emailTemplateId));
|
|
||||||
sendEmail(email, emailTemplate, params);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package cn.bunny.services.utils.login;
|
|
||||||
|
|
||||||
import cn.bunny.dao.dto.system.user.LoginDto;
|
|
||||||
import cn.bunny.dao.entity.system.AdminUser;
|
|
||||||
import cn.bunny.services.mapper.UserMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用用户名登录
|
|
||||||
*/
|
|
||||||
public class DefaultLoginStrategy implements LoginStrategy {
|
|
||||||
private final UserMapper userMapper;
|
|
||||||
|
|
||||||
public DefaultLoginStrategy(UserMapper userMapper) {
|
|
||||||
this.userMapper = userMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录鉴定方法
|
|
||||||
* 默认登录方式,使用用户名查询用户
|
|
||||||
*
|
|
||||||
* @param loginDto 登录参数
|
|
||||||
* @return 鉴定身份验证
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public AdminUser authenticate(LoginDto loginDto) {
|
|
||||||
String username = loginDto.getUsername();
|
|
||||||
|
|
||||||
// 查询用户相关内容
|
|
||||||
LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(AdminUser::getUsername, username);
|
|
||||||
return userMapper.selectOne(queryWrapper);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
package cn.bunny.services.utils.login;
|
|
||||||
|
|
||||||
import cn.bunny.dao.constant.RedisUserConstant;
|
|
||||||
import cn.bunny.dao.dto.system.user.LoginDto;
|
|
||||||
import cn.bunny.dao.entity.system.AdminUser;
|
|
||||||
import cn.bunny.dao.vo.result.ResultCodeEnum;
|
|
||||||
import cn.bunny.services.mapper.UserMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 邮箱登录策略
|
|
||||||
*/
|
|
||||||
public class EmailLoginStrategy implements LoginStrategy {
|
|
||||||
private final RedisTemplate<String, Object> redisTemplate;
|
|
||||||
private final UserMapper userMapper;
|
|
||||||
|
|
||||||
public EmailLoginStrategy(RedisTemplate<String, Object> redisTemplate, UserMapper userMapper) {
|
|
||||||
this.redisTemplate = redisTemplate;
|
|
||||||
this.userMapper = userMapper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录鉴定方法
|
|
||||||
* 只要判断邮箱验证码是否相等,在前面已经验证过用户密码
|
|
||||||
* <p>
|
|
||||||
* 抛出异常类型 UsernameNotFoundException 如果要自定义状态码需要使用 HttpServletResponse
|
|
||||||
* 有封装好的 ResponseUtil.out() 方法
|
|
||||||
* </p>
|
|
||||||
*
|
|
||||||
* @param loginDto 登录参数
|
|
||||||
* @return 鉴定身份验证
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public AdminUser authenticate(LoginDto loginDto) {
|
|
||||||
String username = loginDto.getUsername();
|
|
||||||
String emailCode = loginDto.getEmailCode().toLowerCase();
|
|
||||||
|
|
||||||
// 查找Redis中的验证码
|
|
||||||
Object redisEmailCode = redisTemplate.opsForValue().get(RedisUserConstant.getAdminUserEmailCodePrefix(username));
|
|
||||||
if (redisEmailCode == null) {
|
|
||||||
throw new UsernameNotFoundException(ResultCodeEnum.EMAIL_CODE_EMPTY.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 判断用户邮箱验证码是否和Redis中发送的验证码
|
|
||||||
if (!emailCode.equals(redisEmailCode.toString().toLowerCase())) {
|
|
||||||
throw new UsernameNotFoundException(ResultCodeEnum.EMAIL_CODE_NOT_MATCHING.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 查询用户相关内容
|
|
||||||
LambdaQueryWrapper<AdminUser> queryWrapper = new LambdaQueryWrapper<>();
|
|
||||||
queryWrapper.eq(AdminUser::getEmail, username);
|
|
||||||
return userMapper.selectOne(queryWrapper);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
package cn.bunny.services.utils.login;
|
|
||||||
|
|
||||||
import cn.bunny.dao.dto.system.user.LoginDto;
|
|
||||||
import cn.bunny.dao.entity.system.AdminUser;
|
|
||||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录策略上下文
|
|
||||||
*/
|
|
||||||
public class LoginContext {
|
|
||||||
private final Map<String, LoginStrategy> strategies;
|
|
||||||
|
|
||||||
public LoginContext(Map<String, LoginStrategy> strategies) {
|
|
||||||
this.strategies = strategies;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 执行登录策略
|
|
||||||
* 根据情况判断 type 是否为空
|
|
||||||
*
|
|
||||||
* @param loginDto 登录参数
|
|
||||||
* @return 用户
|
|
||||||
*/
|
|
||||||
public AdminUser executeStrategy(LoginDto loginDto) {
|
|
||||||
String type = loginDto.getType();
|
|
||||||
LoginStrategy strategy = strategies.get(type);
|
|
||||||
if (strategy == null) {
|
|
||||||
throw new UsernameNotFoundException("不支持登录类型: " + type);
|
|
||||||
}
|
|
||||||
return strategy.authenticate(loginDto);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,18 +0,0 @@
|
||||||
package cn.bunny.services.utils.login;
|
|
||||||
|
|
||||||
import cn.bunny.dao.dto.system.user.LoginDto;
|
|
||||||
import cn.bunny.dao.entity.system.AdminUser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录策略
|
|
||||||
*/
|
|
||||||
public interface LoginStrategy {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 登录鉴定方法
|
|
||||||
*
|
|
||||||
* @param loginDto 登录参数
|
|
||||||
* @return 鉴定身份验证
|
|
||||||
*/
|
|
||||||
AdminUser authenticate(LoginDto loginDto);
|
|
||||||
}
|
|
|
@ -1,10 +1,10 @@
|
||||||
|
|
||||||
_ _
|
_ _
|
||||||
| |__ _ _ _ __ _ __ _ _ (_) __ ___ ____ _
|
| |__ _ _ _ __ _ __ _ _ (_) __ ___ ____ _
|
||||||
| '_ \| | | | '_ \| '_ \| | | | | |/ _` \ \ / / _` |
|
| '_ \| | | | '_ \| '_ \| | | | | |/ _` \ \ / / _` |
|
||||||
| |_) | |_| | | | | | | | |_| | | | (_| |\ V | (_| |
|
| |_) | |_| | | | | | | | |_| | | | (_| |\ V | (_| |
|
||||||
|_.__/ \__,_|_| |_|_| |_|\__, | _/ |\__,_| \_/ \__,_|
|
|_.__/ \__,_|_| |_|_| |_|\__, | _/ |\__,_| \_/ \__,_|
|
||||||
|___/ |__/
|
|___/ |__/
|
||||||
|
${AnsiColor.BRIGHT_GREEN}
|
||||||
${spring-boot.formatted-version}
|
|
||||||
${application.title}
|
|
||||||
SpringBoot Version: ${spring-boot.version}${spring-boot.formatted-version}
|
SpringBoot Version: ${spring-boot.version}${spring-boot.formatted-version}
|
||||||
|
${AnsiColor.BLACK}
|
|
@ -1,19 +0,0 @@
|
||||||
package cn.bunny.services.service.impl;
|
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
|
||||||
|
|
||||||
@SpringBootTest
|
|
||||||
class UserServiceImplTest {
|
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private PasswordEncoder passwordEncoder;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void updateUserPasswordByAdmin() {
|
|
||||||
String encode = passwordEncoder.encode("123456");
|
|
||||||
System.out.println(encode);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,22 +0,0 @@
|
||||||
package cn.bunny.services.utils.email;
|
|
||||||
|
|
||||||
import cn.bunny.dao.entity.system.EmailTemplate;
|
|
||||||
import cn.bunny.services.mapper.EmailTemplateMapper;
|
|
||||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
|
||||||
|
|
||||||
import java.util.HashMap;
|
|
||||||
|
|
||||||
@SpringBootTest
|
|
||||||
class ConcreteSenderEmailTemplateTest extends AbstractSenderEmailTemplate {
|
|
||||||
@Autowired
|
|
||||||
private EmailTemplateMapper emailTemplateMapper;
|
|
||||||
|
|
||||||
@Test
|
|
||||||
void sendEmailTemplate() {
|
|
||||||
EmailTemplate emailTemplate = emailTemplateMapper.selectOne(Wrappers.<EmailTemplate>lambdaQuery().eq(EmailTemplate::getId, 1791870020197625858L));
|
|
||||||
sendEmail("1319900154@qq.com", emailTemplate, new HashMap<>());
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue