feat: 根据token分页查询用户日志和用户信息
This commit is contained in:
parent
fd63363101
commit
e2fb65cc29
91
ReadMe.md
91
ReadMe.md
|
@ -1,4 +1,62 @@
|
||||||
# 搭建后端运行环境
|
# 接口说明
|
||||||
|
|
||||||
|
## 请求接口
|
||||||
|
|
||||||
|
请求接口都是`/admin`前缀,部分接口会被忽略,忽略接口看下面。
|
||||||
|
|
||||||
|
所有分页请求内容都是通过路径传参方式
|
||||||
|
|
||||||
|
请求时需要带有token,只要前端在请求头中添加`token:内容`即可
|
||||||
|
|
||||||
|
采用SpringSecurity验证
|
||||||
|
|
||||||
|
## 接口忽略
|
||||||
|
|
||||||
|
### SpringSecurity接口忽略
|
||||||
|
|
||||||
|
这是相关拦截请求内容,如果要访问接口必须携带token,但是有些接口是不需要token的,不需要token就配置在这里。但是放在这里后,如果用户请求的地址是被忽略的,那么也就拿不到token也就拿不到登录相关信息。
|
||||||
|
|
||||||
|
获取用户自身的登录请求是不需要携带用户Id,只要有token去解析即可。
|
||||||
|
|
||||||
|
```java
|
||||||
|
// 排出鉴定路径
|
||||||
|
@Bean
|
||||||
|
public WebSecurityCustomizer webSecurityCustomizer() {
|
||||||
|
String[] annotations = {
|
||||||
|
"/", "/ws/**",
|
||||||
|
"/*/*/noAuth/**", "/*/noAuth/**", "/noAuth/**",
|
||||||
|
"/media.ico", "/favicon.ico", "*.html", "/webjars/**", "/v3/api-docs/**", "swagger-ui/**",
|
||||||
|
"/*/files/**",
|
||||||
|
"/error", "/*/i18n/getI18n",
|
||||||
|
};
|
||||||
|
return web -> web.ignoring().requestMatchers(annotations)
|
||||||
|
.requestMatchers(RegexRequestMatcher.regexMatcher(".*\\.(css|js)$"));
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
有些会被忽略的接口,凡是带有`noAuth`都是不需要验证的,但是要注意一点,不需要验证但是后端需要拿到登录相关信息是拿不到的。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
我是将用户相关请求使用SpringSecurity进行拦截,如果有相关匹配路径那么就会被拦截,此时接口参数中会带有token内容,拿到token进行解析,之后取出相关用户信息,比如用户Id、username等。
|
||||||
|
|
||||||
|
将这些信息拿出来后放到ThreadLocal中,存储在线程中,如果微服务中需要需要放在请求头中,因为微服务不在同一个线程中。这个操作适合单体或者是微服务中不需要请求其它微服务的方式。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
### 不需要管理接口
|
||||||
|
|
||||||
|
请求是会有不需要登录就能访问的接口,也需要不要被管理的接口
|
||||||
|
|
||||||
|
## 验证码验证忽略
|
||||||
|
|
||||||
|
为了公网上的展示,如果需要获取验证码比较的麻烦,如果你的需求和我一样那么可以在这里放开这些注释
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
# 搭建后端环境
|
||||||
|
|
||||||
1. 需要JDK17
|
1. 需要JDK17
|
||||||
2. MySQL
|
2. MySQL
|
||||||
|
@ -42,6 +100,7 @@ docker rm slave_3304
|
||||||
docker run --name slave_3304 -p 3304:3306 \
|
docker run --name slave_3304 -p 3304:3306 \
|
||||||
-v /bunny/docker_data/mysql/slave_3304/etc/my.cnf:/etc/my.cnf \
|
-v /bunny/docker_data/mysql/slave_3304/etc/my.cnf:/etc/my.cnf \
|
||||||
-v /bunny/docker_data/mysql/slave_3304/data:/var/lib/mysql \
|
-v /bunny/docker_data/mysql/slave_3304/data:/var/lib/mysql \
|
||||||
|
-v /bunny/docker_data/mysql/slave_3304/backup:\
|
||||||
--restart=always --privileged=true \
|
--restart=always --privileged=true \
|
||||||
-e MYSQL_ROOT_PASSWORD=02120212 \
|
-e MYSQL_ROOT_PASSWORD=02120212 \
|
||||||
-e TZ=Asia/Shanghai \
|
-e TZ=Asia/Shanghai \
|
||||||
|
@ -62,11 +121,10 @@ FLUSH PRIVILEGES;
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
[mysqld]
|
[mysqld]
|
||||||
datadir=/var/lib/mysql
|
|
||||||
socket=/var/lib/mysql/mysql.sock
|
|
||||||
skip-host-cache
|
skip-host-cache
|
||||||
skip-name-resolve
|
skip-name-resolve
|
||||||
secure-file-priv=/var/lib/mysql-files
|
secure-file-priv=/var/lib/mysql-files
|
||||||
|
user=mysql
|
||||||
|
|
||||||
# 设置字符集
|
# 设置字符集
|
||||||
character-set-server=utf8mb4
|
character-set-server=utf8mb4
|
||||||
|
@ -80,9 +138,6 @@ log-bin=mysql-bin
|
||||||
|
|
||||||
# 设置表名不区分大小写
|
# 设置表名不区分大小写
|
||||||
lower_case_table_names = 1
|
lower_case_table_names = 1
|
||||||
|
|
||||||
[client]
|
|
||||||
socket=/var/run/mysqld/mysqld.sock
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 安装Redis
|
## 安装Redis
|
||||||
|
@ -119,6 +174,30 @@ docker run -d \
|
||||||
minio/minio server /data --console-address ":9090"
|
minio/minio server /data --console-address ":9090"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
# 动态定时任务
|
||||||
|
|
||||||
|
使用`Quartz `数据存储在数据库中持久化存储.
|
||||||
|
|
||||||
|
所有的Quartz内容都放在这个目录中,因为前端需要知道有哪些定时任务,这时候又不能将数据添加到数据库中,如果以后需要更多的定时任务那么需要再数据库中添加,这样做很麻烦。
|
||||||
|
|
||||||
|
我们可以通过反射只要约定好内容,通过反射扫描的方式来获取这些可以使用的定时任务,反射的注解是这个:`@QuartzSchedulers(type = "test", description = "JobHello任务内容")`
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 注解说明
|
||||||
|
|
||||||
|
扫描注解包,可以通过依赖注入的方式使用
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
类型注解存放位置在下面。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
获取所有可用定时任务
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
# Quartz 方法
|
# Quartz 方法
|
||||||
|
|
||||||
## TriggerBuilder
|
## TriggerBuilder
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 173 KiB |
Binary file not shown.
After Width: | Height: | Size: 118 KiB |
Binary file not shown.
After Width: | Height: | Size: 239 KiB |
Binary file not shown.
After Width: | Height: | Size: 218 KiB |
|
@ -19,12 +19,18 @@ public class AnnotationScanner {
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Set<Class<?>> getClassesWithAnnotation(Class<?> annotation) {
|
public Set<Class<?>> getClassesWithAnnotation(Class<?> annotation) {
|
||||||
|
// 设置是否延迟初始化
|
||||||
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
|
ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
|
||||||
|
// 只需要带有 Annotation 注解类的内容
|
||||||
scanner.addIncludeFilter(new AnnotationTypeFilter((Class<? extends Annotation>) annotation));
|
scanner.addIncludeFilter(new AnnotationTypeFilter((Class<? extends Annotation>) annotation));
|
||||||
|
|
||||||
|
// 扫描到的内容,排除重复的内容
|
||||||
Set<Class<?>> classes = new HashSet<>();
|
Set<Class<?>> classes = new HashSet<>();
|
||||||
|
|
||||||
|
// 只要 cn.bunny.services 包下面的全部内容
|
||||||
for (BeanDefinition bd : scanner.findCandidateComponents("cn.bunny.services")) {
|
for (BeanDefinition bd : scanner.findCandidateComponents("cn.bunny.services")) {
|
||||||
try {
|
try {
|
||||||
|
// 通过反射加载类,并将类名转换为 Class 对象
|
||||||
Class<?> clazz = Class.forName(bd.getBeanClassName());
|
Class<?> clazz = Class.forName(bd.getBeanClassName());
|
||||||
classes.add(clazz);
|
classes.add(clazz);
|
||||||
} catch (ClassNotFoundException e) {
|
} catch (ClassNotFoundException e) {
|
||||||
|
|
|
@ -52,7 +52,7 @@ public class EmailUsersController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "获取所有邮箱配置用户", description = "获取所有邮箱配置用户")
|
@Operation(summary = "获取所有邮箱配置用户", description = "获取所有邮箱配置用户")
|
||||||
@GetMapping("getAllMailboxConfigurationUsers")
|
@GetMapping("noManage/getAllMailboxConfigurationUsers")
|
||||||
public Mono<Result<List<Map<String, String>>>> getAllMailboxConfigurationUsers() {
|
public Mono<Result<List<Map<String, String>>>> getAllMailboxConfigurationUsers() {
|
||||||
List<Map<String, String>> list = emailUsersService.getAllMailboxConfigurationUsers();
|
List<Map<String, String>> list = emailUsersService.getAllMailboxConfigurationUsers();
|
||||||
return Mono.just(Result.success(list));
|
return Mono.just(Result.success(list));
|
||||||
|
|
|
@ -62,14 +62,14 @@ public class FilesController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "获取所有文件类型", description = "获取所有文件类型")
|
@Operation(summary = "获取所有文件类型", description = "获取所有文件类型")
|
||||||
@GetMapping("getAllMediaTypes")
|
@GetMapping("noManage/getAllMediaTypes")
|
||||||
public Mono<Result<Set<String>>> getAllMediaTypes() {
|
public Mono<Result<Set<String>>> getAllMediaTypes() {
|
||||||
Set<String> list = filesService.getAllMediaTypes();
|
Set<String> list = filesService.getAllMediaTypes();
|
||||||
return Mono.just(Result.success(list));
|
return Mono.just(Result.success(list));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "获取所有文件存储基础路径", description = "获取所有文件存储基础路径")
|
@Operation(summary = "获取所有文件存储基础路径", description = "获取所有文件存储基础路径")
|
||||||
@GetMapping("getAllFilesStoragePath")
|
@GetMapping("noManage/getAllFilesStoragePath")
|
||||||
public Mono<Result<List<String>>> getAllFilesStoragePath() {
|
public Mono<Result<List<String>>> getAllFilesStoragePath() {
|
||||||
Map<String, String> typeMap = MinioConstant.typeMap;
|
Map<String, String> typeMap = MinioConstant.typeMap;
|
||||||
List<String> list = typeMap.keySet().stream().toList();
|
List<String> list = typeMap.keySet().stream().toList();
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class MenuIconController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "获取查询图标名称列", description = "获取查询图标名称列")
|
@Operation(summary = "获取查询图标名称列", description = "获取查询图标名称列")
|
||||||
@GetMapping("getIconNameList")
|
@GetMapping("noManage/getIconNameList")
|
||||||
public Mono<Result<List<MenuIconVo>>> getIconNameList(String iconName) {
|
public Mono<Result<List<MenuIconVo>>> getIconNameList(String iconName) {
|
||||||
List<MenuIconVo> voList = menuIconService.getIconNameList(iconName);
|
List<MenuIconVo> voList = menuIconService.getIconNameList(iconName);
|
||||||
return Mono.just(Result.success(voList));
|
return Mono.just(Result.success(voList));
|
||||||
|
|
|
@ -50,7 +50,7 @@ public class RoleController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "获取所有角色", description = "获取所有角色")
|
@Operation(summary = "获取所有角色", description = "获取所有角色")
|
||||||
@GetMapping("getAllRoles")
|
@GetMapping("noManage/getAllRoles")
|
||||||
public Mono<Result<List<RoleVo>>> getAllRoles() {
|
public Mono<Result<List<RoleVo>>> getAllRoles() {
|
||||||
List<RoleVo> roleVoList = roleService.getAllRoles();
|
List<RoleVo> roleVoList = roleService.getAllRoles();
|
||||||
return Mono.just(Result.success(roleVoList));
|
return Mono.just(Result.success(roleVoList));
|
||||||
|
|
|
@ -29,7 +29,7 @@ public class RolePowerController {
|
||||||
private RolePowerService rolePowerService;
|
private RolePowerService rolePowerService;
|
||||||
|
|
||||||
@Operation(summary = "根据角色id获取权限内容", description = "角色列获取已选择的权限")
|
@Operation(summary = "根据角色id获取权限内容", description = "角色列获取已选择的权限")
|
||||||
@GetMapping("getPowerListByRoleId")
|
@GetMapping("noManage/getPowerListByRoleId")
|
||||||
public Mono<Result<List<String>>> getPowerListByRoleId(Long id) {
|
public Mono<Result<List<String>>> getPowerListByRoleId(Long id) {
|
||||||
List<String> voList = rolePowerService.getPowerListByRoleId(id);
|
List<String> voList = rolePowerService.getPowerListByRoleId(id);
|
||||||
return Mono.just(Result.success(voList));
|
return Mono.just(Result.success(voList));
|
||||||
|
|
|
@ -39,7 +39,7 @@ public class RouterController {
|
||||||
private RouterService routerService;
|
private RouterService routerService;
|
||||||
|
|
||||||
@Operation(summary = "获取用户菜单", description = "获取用户菜单")
|
@Operation(summary = "获取用户菜单", description = "获取用户菜单")
|
||||||
@GetMapping("getRouterAsync")
|
@GetMapping("noManage/getRouterAsync")
|
||||||
public Mono<Result<List<UserRouterVo>>> getRouterAsync() {
|
public Mono<Result<List<UserRouterVo>>> getRouterAsync() {
|
||||||
List<UserRouterVo> voList = routerService.getRouterAsync();
|
List<UserRouterVo> voList = routerService.getRouterAsync();
|
||||||
return Mono.just(Result.success(voList));
|
return Mono.just(Result.success(voList));
|
||||||
|
|
|
@ -51,7 +51,7 @@ public class SchedulersController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "获取所有可用调度任务", description = "获取所有可用调度任务")
|
@Operation(summary = "获取所有可用调度任务", description = "获取所有可用调度任务")
|
||||||
@GetMapping("getAllScheduleJobList")
|
@GetMapping("noManage/getAllScheduleJobList")
|
||||||
public Mono<Result<List<Map<String, String>>>> getAllScheduleJobList() {
|
public Mono<Result<List<Map<String, String>>>> getAllScheduleJobList() {
|
||||||
List<Map<String, String>> mapList = schedulersService.getAllScheduleJobList();
|
List<Map<String, String>> mapList = schedulersService.getAllScheduleJobList();
|
||||||
return Mono.just(Result.success(mapList));
|
return Mono.just(Result.success(mapList));
|
||||||
|
|
|
@ -42,6 +42,13 @@ public class UserController {
|
||||||
return Mono.just(Result.success(pageResult));
|
return Mono.just(Result.success(pageResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取本地登录用户信息", description = "获取本地登录用户信息")
|
||||||
|
@GetMapping("noManage/getUserinfo")
|
||||||
|
public Mono<Result<UserVo>> getUserinfo() {
|
||||||
|
UserVo vo = userService.getUserinfo();
|
||||||
|
return Mono.just(Result.success(vo));
|
||||||
|
}
|
||||||
|
|
||||||
@Operation(summary = "获取用户信息", description = "获取用户信息")
|
@Operation(summary = "获取用户信息", description = "获取用户信息")
|
||||||
@GetMapping("getUserinfoById")
|
@GetMapping("getUserinfoById")
|
||||||
public Mono<Result<UserVo>> getUserinfoById(Long id) {
|
public Mono<Result<UserVo>> getUserinfoById(Long id) {
|
||||||
|
@ -50,7 +57,7 @@ public class UserController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "多条件查询用户", description = "多条件查询用户")
|
@Operation(summary = "多条件查询用户", description = "多条件查询用户")
|
||||||
@GetMapping("queryUser")
|
@GetMapping("noManage/queryUser")
|
||||||
public Mono<Result<List<AdminUserVo>>> queryUser(String keyword) {
|
public Mono<Result<List<AdminUserVo>>> queryUser(String keyword) {
|
||||||
List<AdminUserVo> voList = userService.queryUser(keyword);
|
List<AdminUserVo> voList = userService.queryUser(keyword);
|
||||||
return Mono.just(Result.success(voList));
|
return Mono.just(Result.success(voList));
|
||||||
|
@ -113,7 +120,7 @@ public class UserController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "退出登录", description = "退出登录")
|
@Operation(summary = "退出登录", description = "退出登录")
|
||||||
@PostMapping("logout")
|
@PostMapping("noManage/logout")
|
||||||
public Result<String> logout() {
|
public Result<String> logout() {
|
||||||
userService.logout();
|
userService.logout();
|
||||||
return Result.success(ResultCodeEnum.LOGOUT_SUCCESS);
|
return Result.success(ResultCodeEnum.LOGOUT_SUCCESS);
|
||||||
|
|
|
@ -46,6 +46,18 @@ public class UserLoginLogController {
|
||||||
return Mono.just(Result.success(pageResult));
|
return Mono.just(Result.success(pageResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "获取本地用户登录日志", description = "获取本地用户登录日志")
|
||||||
|
@GetMapping("noManage/getUserLoginLogListByLocalUser/{page}/{limit}")
|
||||||
|
public Mono<Result<PageResult<UserLoginLogVo>>> getUserLoginLogListByLocalUser(
|
||||||
|
@Parameter(name = "page", description = "当前页", required = true)
|
||||||
|
@PathVariable("page") Integer page,
|
||||||
|
@Parameter(name = "limit", description = "每页记录数", required = true)
|
||||||
|
@PathVariable("limit") Integer limit) {
|
||||||
|
Page<UserLoginLog> pageParams = new Page<>(page, limit);
|
||||||
|
PageResult<UserLoginLogVo> voPageResult = userLoginLogService.getUserLoginLogListByLocalUser(pageParams);
|
||||||
|
return Mono.just(Result.success(voPageResult));
|
||||||
|
}
|
||||||
|
|
||||||
@Operation(summary = "删除用户登录日志", description = "删除用户登录日志")
|
@Operation(summary = "删除用户登录日志", description = "删除用户登录日志")
|
||||||
@DeleteMapping("deleteUserLoginLog")
|
@DeleteMapping("deleteUserLoginLog")
|
||||||
public Mono<Result<String>> deleteUserLoginLog(@RequestBody List<Long> ids) {
|
public Mono<Result<String>> deleteUserLoginLog(@RequestBody List<Long> ids) {
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
package cn.bunny.services.factory;
|
||||||
|
|
||||||
|
import cn.bunny.dao.entity.log.UserLoginLog;
|
||||||
|
import cn.bunny.dao.pojo.result.PageResult;
|
||||||
|
import cn.bunny.dao.vo.log.UserLoginLogVo;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class UserLoginLogFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户登录日志分页查询通用方法
|
||||||
|
*
|
||||||
|
* @param page 分页结果
|
||||||
|
* @return 分页用户登录日志
|
||||||
|
*/
|
||||||
|
public PageResult<UserLoginLogVo> getUserLoginLogVoPageResult(IPage<UserLoginLog> page) {
|
||||||
|
List<UserLoginLogVo> voList = page.getRecords().stream().map(userLoginLog -> {
|
||||||
|
UserLoginLogVo userLoginLogVo = new UserLoginLogVo();
|
||||||
|
BeanUtils.copyProperties(userLoginLog, userLoginLogVo);
|
||||||
|
return userLoginLogVo;
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
return PageResult.<UserLoginLogVo>builder()
|
||||||
|
.list(voList)
|
||||||
|
.pageNo(page.getCurrent())
|
||||||
|
.pageSize(page.getSize())
|
||||||
|
.total(page.getTotal())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -36,4 +36,12 @@ public interface UserLoginLogMapper extends BaseMapper<UserLoginLog> {
|
||||||
* @param ids 删除 id 列表
|
* @param ids 删除 id 列表
|
||||||
*/
|
*/
|
||||||
void deleteBatchIdsWithPhysics(List<Long> ids);
|
void deleteBatchIdsWithPhysics(List<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 分页查询根据用户Id用户登录日志内容
|
||||||
|
*
|
||||||
|
* @param pageParams 分页查询内容
|
||||||
|
* @return 用户登录日志返回列表
|
||||||
|
*/
|
||||||
|
IPage<UserLoginLog> selectListByPageWithLocalUser(Page<UserLoginLog> pageParams, Long id);
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,14 +55,17 @@ public class CustomAuthorizationManagerServiceImpl implements AuthorizationManag
|
||||||
boolean checkedAdmin = CustomCheckIsAdmin.checkAdmin(roleCodeList, loginVo);
|
boolean checkedAdmin = CustomCheckIsAdmin.checkAdmin(roleCodeList, loginVo);
|
||||||
if (checkedAdmin) return true;
|
if (checkedAdmin) return true;
|
||||||
|
|
||||||
// 不是 admin,查询角色权限关系表
|
// 判断请求地址是否是 noManage 不需要被验证的
|
||||||
List<String> powerCodes = loginVo.getPermissions();
|
String requestURI = request.getRequestURI();
|
||||||
|
if (requestURI.contains("noManage")) return true;
|
||||||
|
|
||||||
// 根据权限码查询可以访问URL
|
// 不是 admin,查询角色权限关系表,根据权限码查询可以访问URL
|
||||||
|
List<String> powerCodes = loginVo.getPermissions();
|
||||||
List<Power> powerList = powerMapper.selectListByPowerCodes(powerCodes);
|
List<Power> powerList = powerMapper.selectListByPowerCodes(powerCodes);
|
||||||
|
|
||||||
// 判断是否与请求路径匹配
|
// 判断是否与请求路径匹配
|
||||||
return powerList.stream().anyMatch(power -> AntPathRequestMatcher.antMatcher(power.getRequestUrl()).matches(request) ||
|
return powerList.stream()
|
||||||
request.getRequestURI().matches(power.getRequestUrl()));
|
.anyMatch(power -> AntPathRequestMatcher.antMatcher(power.getRequestUrl()).matches(request) ||
|
||||||
|
requestURI.matches(power.getRequestUrl()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,4 +32,12 @@ public interface UserLoginLogService extends IService<UserLoginLog> {
|
||||||
* @param ids 删除id列表
|
* @param ids 删除id列表
|
||||||
*/
|
*/
|
||||||
void deleteUserLoginLog(List<Long> ids);
|
void deleteUserLoginLog(List<Long> ids);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 获取本地用户登录日志
|
||||||
|
*
|
||||||
|
* @param pageParams 分页查询内容
|
||||||
|
* @return 用户登录日志返回列表
|
||||||
|
*/
|
||||||
|
PageResult<UserLoginLogVo> getUserLoginLogListByLocalUser(Page<UserLoginLog> pageParams);
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,4 +115,11 @@ public interface UserService extends IService<AdminUser> {
|
||||||
* @param dto 管理员用户修改密码
|
* @param dto 管理员用户修改密码
|
||||||
*/
|
*/
|
||||||
void updateUserStatusByAdmin(AdminUserUpdateUserStatusDto dto);
|
void updateUserStatusByAdmin(AdminUserUpdateUserStatusDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 获取本地登录用户信息
|
||||||
|
*
|
||||||
|
* @return 用户信息
|
||||||
|
*/
|
||||||
|
UserVo getUserinfo();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,17 @@
|
||||||
package cn.bunny.services.service.impl;
|
package cn.bunny.services.service.impl;
|
||||||
|
|
||||||
|
import cn.bunny.common.service.context.BaseContext;
|
||||||
import cn.bunny.dao.dto.log.UserLoginLogDto;
|
import cn.bunny.dao.dto.log.UserLoginLogDto;
|
||||||
import cn.bunny.dao.entity.log.UserLoginLog;
|
import cn.bunny.dao.entity.log.UserLoginLog;
|
||||||
import cn.bunny.dao.pojo.result.PageResult;
|
import cn.bunny.dao.pojo.result.PageResult;
|
||||||
import cn.bunny.dao.vo.log.UserLoginLogVo;
|
import cn.bunny.dao.vo.log.UserLoginLogVo;
|
||||||
|
import cn.bunny.services.factory.UserLoginLogFactory;
|
||||||
import cn.bunny.services.mapper.UserLoginLogMapper;
|
import cn.bunny.services.mapper.UserLoginLogMapper;
|
||||||
import cn.bunny.services.service.UserLoginLogService;
|
import cn.bunny.services.service.UserLoginLogService;
|
||||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
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 org.springframework.beans.BeanUtils;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -25,6 +27,9 @@ import java.util.List;
|
||||||
@Service
|
@Service
|
||||||
public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, UserLoginLog> implements UserLoginLogService {
|
public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, UserLoginLog> implements UserLoginLogService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private UserLoginLogFactory factory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 用户登录日志 服务实现类
|
* * 用户登录日志 服务实现类
|
||||||
*
|
*
|
||||||
|
@ -37,18 +42,7 @@ public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, Use
|
||||||
// 分页查询菜单图标
|
// 分页查询菜单图标
|
||||||
IPage<UserLoginLog> page = baseMapper.selectListByPage(pageParams, dto);
|
IPage<UserLoginLog> page = baseMapper.selectListByPage(pageParams, dto);
|
||||||
|
|
||||||
List<UserLoginLogVo> voList = page.getRecords().stream().map(userLoginLog -> {
|
return factory.getUserLoginLogVoPageResult(page);
|
||||||
UserLoginLogVo userLoginLogVo = new UserLoginLogVo();
|
|
||||||
BeanUtils.copyProperties(userLoginLog, userLoginLogVo);
|
|
||||||
return userLoginLogVo;
|
|
||||||
}).toList();
|
|
||||||
|
|
||||||
return PageResult.<UserLoginLogVo>builder()
|
|
||||||
.list(voList)
|
|
||||||
.pageNo(page.getCurrent())
|
|
||||||
.pageSize(page.getSize())
|
|
||||||
.total(page.getTotal())
|
|
||||||
.build();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -60,4 +54,18 @@ public class UserLoginLogServiceImpl extends ServiceImpl<UserLoginLogMapper, Use
|
||||||
public void deleteUserLoginLog(List<Long> ids) {
|
public void deleteUserLoginLog(List<Long> ids) {
|
||||||
baseMapper.deleteBatchIdsWithPhysics(ids);
|
baseMapper.deleteBatchIdsWithPhysics(ids);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 获取本地用户登录日志
|
||||||
|
*
|
||||||
|
* @param pageParams 分页查询内容
|
||||||
|
* @return 用户登录日志返回列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public PageResult<UserLoginLogVo> getUserLoginLogListByLocalUser(Page<UserLoginLog> pageParams) {
|
||||||
|
Long userId = BaseContext.getUserId();
|
||||||
|
IPage<UserLoginLog> page = baseMapper.selectListByPageWithLocalUser(pageParams, userId);
|
||||||
|
|
||||||
|
return factory.getUserLoginLogVoPageResult(page);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -301,6 +301,27 @@ public class UserServiceImpl extends ServiceImpl<UserMapper, AdminUser> implemen
|
||||||
updateById(adminUser);
|
updateById(adminUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 获取本地登录用户信息
|
||||||
|
*
|
||||||
|
* @return 用户信息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public UserVo getUserinfo() {
|
||||||
|
// 查询当前用户信息
|
||||||
|
Long userId = BaseContext.getUserId();
|
||||||
|
AdminUser adminUser = getOne(Wrappers.<AdminUser>lambdaQuery().eq(AdminUser::getId, userId));
|
||||||
|
|
||||||
|
// 赋值对象
|
||||||
|
UserVo userVo = new UserVo();
|
||||||
|
BeanUtils.copyProperties(adminUser, userVo);
|
||||||
|
|
||||||
|
// 设置用户头像内容
|
||||||
|
String avatar = adminUser.getAvatar();
|
||||||
|
if (StringUtils.hasText(avatar)) userVo.setAvatar(minioUtil.getObjectNameFullPath(avatar));
|
||||||
|
return userVo;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* * 用户信息 服务实现类
|
* * 用户信息 服务实现类
|
||||||
*
|
*
|
||||||
|
|
|
@ -70,6 +70,13 @@
|
||||||
</where>
|
</where>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 分页查询根据用户Id用户登录日志内容 -->
|
||||||
|
<select id="selectListByPageWithLocalUser" resultType="cn.bunny.dao.entity.log.UserLoginLog">
|
||||||
|
select
|
||||||
|
<include refid="Base_Column_List"/>
|
||||||
|
from log_user_login where user_id = #{id} order by create_time desc
|
||||||
|
</select>
|
||||||
|
|
||||||
<!-- 物理删除用户登录日志 -->
|
<!-- 物理删除用户登录日志 -->
|
||||||
<delete id="deleteBatchIdsWithPhysics">
|
<delete id="deleteBatchIdsWithPhysics">
|
||||||
delete
|
delete
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
{
|
||||||
|
"Version": "5.8.0",
|
||||||
|
"Title": "BunnyAdmin",
|
||||||
|
"Copyright": "Copyright © 2020-present",
|
||||||
|
"FixedHeader": true,
|
||||||
|
"HiddenSideBar": false,
|
||||||
|
"MultiTagsCache": false,
|
||||||
|
"KeepAlive": true,
|
||||||
|
"Locale": "zh",
|
||||||
|
"Layout": "vertical",
|
||||||
|
"Theme": "light",
|
||||||
|
"DarkMode": false,
|
||||||
|
"OverallStyle": "light",
|
||||||
|
"Grey": false,
|
||||||
|
"Weak": false,
|
||||||
|
"HideTabs": false,
|
||||||
|
"HideFooter": false,
|
||||||
|
"Stretch": false,
|
||||||
|
"SidebarStatus": true,
|
||||||
|
"EpThemeColor": "#409EFF",
|
||||||
|
"ShowLogo": true,
|
||||||
|
"ShowModel": "smart",
|
||||||
|
"MenuArrowIconNoTransition": false,
|
||||||
|
"CachingAsyncRoutes": false,
|
||||||
|
"TooltipEffect": "light",
|
||||||
|
"ResponsiveStorageNameSpace": "responsive-",
|
||||||
|
"MenuSearchHistory": 6
|
||||||
|
}
|
|
@ -1,45 +0,0 @@
|
||||||
<body style="margin: 0; padding: 0; background-color: #f5f5f5;">
|
|
||||||
<div style="max-width: 600px; margin: 0 auto;">
|
|
||||||
<table style="width: 100%; border-collapse: collapse; background-color: #ffffff; font-family: Arial, sans-serif;">
|
|
||||||
<tr>
|
|
||||||
<th style="height: 60px; padding: 20px; background-color: #0074d3; border-radius: 5px 5px 0 0;"
|
|
||||||
valign="middle">
|
|
||||||
<h1 style="margin: 0; color: #ffffff; font-size: 24px;">BunnyBBS邮箱验证码</h1>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style="padding: 20px;">
|
|
||||||
<div style="background-color: #ffffff; padding: 25px;">
|
|
||||||
<h2 style="margin: 10px 0; font-size: 18px; color: #333333;">
|
|
||||||
尊敬的用户,
|
|
||||||
</h2>
|
|
||||||
<p style="margin: 10px 0; font-size: 16px; color: #333333;">
|
|
||||||
感谢您注册我们的产品. 您的账号正在进行电子邮件验证.
|
|
||||||
</p>
|
|
||||||
<p style="margin: 10px 0; font-size: 16px; color: #333333;">
|
|
||||||
验证码为: <span class="button" style="color: #1100ff;">${verifyCode}</span>
|
|
||||||
</p>
|
|
||||||
<p style="margin: 10px 0; font-size: 16px; color: #333333;">
|
|
||||||
验证码的有效期只有一分钟,请抓紧时间进行验证吧!
|
|
||||||
</p>
|
|
||||||
<p style="margin: 10px 0; font-size: 16px; color: #dc1818;">
|
|
||||||
如果非本人操作,请忽略此邮件
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td style="text-align: center; padding: 20px; background-color: #f5f5f5;">
|
|
||||||
<p style="margin: 0; font-size: 12px; color: #747474;">
|
|
||||||
XXXXX<br>
|
|
||||||
Contact us: XXXXXXX@qq.com
|
|
||||||
</p>
|
|
||||||
<p style="margin: 10px 0; font-size: 12px; color: #747474;">
|
|
||||||
This is an automated email, please do not reply.<br>
|
|
||||||
© Company Name
|
|
||||||
</p>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
|
@ -26,7 +26,9 @@ public class TestPath {
|
||||||
// 执行后读取内容
|
// 执行后读取内容
|
||||||
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
|
||||||
String line;
|
String line;
|
||||||
while ((line = reader.readLine()) != null) {System.out.println(line);}
|
while ((line = reader.readLine()) != null) {
|
||||||
|
System.out.println(line);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@SneakyThrows
|
@SneakyThrows
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
package cn.bunny.services.security.service.impl;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
class CustomAuthorizationManagerServiceImplTest {
|
||||||
|
@Test
|
||||||
|
void testRequestUrl() {
|
||||||
|
String requestURI = "http://localhost:7000/api/user/noManage/getAdminUserList";
|
||||||
|
System.out.println(requestURI.contains("noManage"));
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue