🎉 step-3-前后端分离
This commit is contained in:
parent
075925687c
commit
a317acdb63
|
@ -21,6 +21,7 @@
|
|||
<module>official</module>
|
||||
<module>step-1</module>
|
||||
<module>step-2</module>
|
||||
<module>step-3</module>
|
||||
</modules>
|
||||
|
||||
<properties>
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>com.mall</groupId>
|
||||
<artifactId>spring-security</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>step-3</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>step-3</name>
|
||||
<description>step-3-前后端分离</description>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>17</maven.compiler.source>
|
||||
<maven.compiler.target>17</maven.compiler.target>
|
||||
<java.version>17</java.version>
|
||||
<jwt.version>0.12.6</jwt.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!--jjwt-->
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
<version>${jwt.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jetbrains</groupId>
|
||||
<artifactId>annotations</artifactId>
|
||||
<version>13.0</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -0,0 +1,11 @@
|
|||
package com.spring.step3;
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class SpringSecurityStep3Application {
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(SpringSecurityStep3Application.class, args);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.spring.step3.config;
|
||||
|
||||
import io.swagger.v3.oas.models.ExternalDocumentation;
|
||||
import io.swagger.v3.oas.models.OpenAPI;
|
||||
import io.swagger.v3.oas.models.info.Contact;
|
||||
import io.swagger.v3.oas.models.info.Info;
|
||||
import io.swagger.v3.oas.models.info.License;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springdoc.core.models.GroupedOpenApi;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
@Slf4j
|
||||
public class Knife4jConfig {
|
||||
|
||||
@Value("${server.port}")
|
||||
private String port;
|
||||
|
||||
@Bean
|
||||
public OpenAPI openAPI() {
|
||||
String url = "http://localhost:" + port;
|
||||
|
||||
// 作者等信息
|
||||
Contact contact = new Contact().name("Bunny").email("1319900154@qq.com").url(url);
|
||||
// 使用协议
|
||||
License license = new License().name("MIT").url("https://mit-license.org");
|
||||
// 相关信息
|
||||
Info info = new Info().title("Bunny-Admin")
|
||||
.contact(contact).license(license)
|
||||
.description("Bunny代码生成器")
|
||||
.summary("Bunny的代码生成器")
|
||||
.termsOfService(url)
|
||||
.version("v1.0.0");
|
||||
|
||||
return new OpenAPI().info(info).externalDocs(new ExternalDocumentation());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GroupedOpenApi all() {
|
||||
return GroupedOpenApi.builder().group("全部请求接口").pathsToMatch("/api/**").build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public GroupedOpenApi security() {
|
||||
return GroupedOpenApi.builder().group("security接口").pathsToMatch("/api/security/**").build();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
package com.spring.step3.config;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
|
||||
import com.spring.step3.config.context.BaseContext;
|
||||
import org.apache.ibatis.reflection.MetaObject;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
/**
|
||||
* 配置MP在修改和新增时的操作
|
||||
*/
|
||||
@Component
|
||||
public class MyBatisPlusFieldConfig implements MetaObjectHandler {
|
||||
|
||||
/**
|
||||
* 使用mp做添加操作时候,这个方法执行
|
||||
*/
|
||||
@Override
|
||||
public void insertFill(MetaObject metaObject) {
|
||||
// 设置属性值
|
||||
this.strictInsertFill(metaObject, "isDeleted", Integer.class, 0);
|
||||
this.setFieldValByName("createTime", LocalDateTime.now(), metaObject);
|
||||
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
|
||||
if (BaseContext.getUsername() != null) {
|
||||
this.setFieldValByName("createUser", BaseContext.getUserId(), metaObject);
|
||||
this.setFieldValByName("updateUser", BaseContext.getUserId(), metaObject);
|
||||
} else {
|
||||
this.setFieldValByName("createUser", 0L, metaObject);
|
||||
this.setFieldValByName("updateUser", BaseContext.getUserId(), metaObject);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用mp做修改操作时候,这个方法执行
|
||||
*/
|
||||
@Override
|
||||
public void updateFill(MetaObject metaObject) {
|
||||
if (BaseContext.getUserId() != null) {
|
||||
this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject);
|
||||
this.setFieldValByName("updateUser", BaseContext.getUserId(), metaObject);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
package com.spring.step3.config;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.DbType;
|
||||
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
|
||||
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||
|
||||
@EnableTransactionManagement
|
||||
@Configuration
|
||||
public class MybatisPlusConfig {
|
||||
|
||||
@Bean
|
||||
public MybatisPlusInterceptor mybatisPlusInterceptor() {
|
||||
// 拦截器
|
||||
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
|
||||
|
||||
// 使用分页插件
|
||||
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor();
|
||||
paginationInnerInterceptor.setDbType(DbType.MYSQL);
|
||||
paginationInnerInterceptor.setMaxLimit(600L);
|
||||
interceptor.addInnerInterceptor(paginationInnerInterceptor);
|
||||
|
||||
// 乐观锁
|
||||
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
|
||||
|
||||
// 防止全表删除
|
||||
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
|
||||
|
||||
return interceptor;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package com.spring.step3.config.context;
|
||||
|
||||
|
||||
public class BaseContext {
|
||||
private static final ThreadLocal<Long> userId = new ThreadLocal<>();
|
||||
private static final ThreadLocal<String> username = new ThreadLocal<>();
|
||||
|
||||
// 用户id相关
|
||||
public static Long getUserId() {
|
||||
return userId.get();
|
||||
}
|
||||
|
||||
public static void setUserId(Long _userId) {
|
||||
userId.set(_userId);
|
||||
}
|
||||
|
||||
public static String getUsername() {
|
||||
return username.get();
|
||||
}
|
||||
|
||||
public static void setUsername(String _username) {
|
||||
username.set(_username);
|
||||
}
|
||||
|
||||
public static void removeUser() {
|
||||
username.remove();
|
||||
userId.remove();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.spring.step3.config.web;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonParser;
|
||||
import com.fasterxml.jackson.databind.DeserializationContext;
|
||||
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
|
||||
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
|
||||
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.web.bind.WebDataBinder;
|
||||
import org.springframework.web.bind.annotation.ControllerAdvice;
|
||||
import org.springframework.web.bind.annotation.InitBinder;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* 去除前端传递的空格
|
||||
*/
|
||||
@ControllerAdvice
|
||||
public class ControllerStringParamTrimConfig {
|
||||
|
||||
/**
|
||||
* 创建 String trim 编辑器
|
||||
* 构造方法中 boolean 参数含义为如果是空白字符串,是否转换为null
|
||||
* 即如果为true,那么 " " 会被转换为 null,否者为 ""
|
||||
*/
|
||||
@InitBinder
|
||||
public void initBinder(WebDataBinder binder) {
|
||||
StringTrimmerEditor propertyEditor = new StringTrimmerEditor(false);
|
||||
// 为 String 类对象注册编辑器
|
||||
binder.registerCustomEditor(String.class, propertyEditor);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
|
||||
return jacksonObjectMapperBuilder -> {
|
||||
// 为 String 类型自定义反序列化操作
|
||||
jacksonObjectMapperBuilder
|
||||
.deserializerByType(String.class, new StdScalarDeserializer<String>(String.class) {
|
||||
@Override
|
||||
public String deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
|
||||
// // 去除全部空格
|
||||
// return StringUtils.trimAllWhitespace(jsonParser.getValueAsString());
|
||||
|
||||
// 仅去除前后空格
|
||||
return jsonParser.getValueAsString().trim();
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package com.spring.step3.config.web;
|
||||
|
||||
|
||||
import com.spring.step3.config.context.BaseContext;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
|
||||
@Configuration
|
||||
public class ThreadLocalCleanupInterceptor implements HandlerInterceptor {
|
||||
|
||||
@Override
|
||||
public boolean preHandle(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterCompletion(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, @NotNull Object handler, Exception ex) {
|
||||
BaseContext.removeUser();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package com.spring.step3.config.web;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
|
||||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||
|
||||
@Configuration
|
||||
@RequiredArgsConstructor
|
||||
public class WebConfig implements WebMvcConfigurer {
|
||||
|
||||
private final ThreadLocalCleanupInterceptor threadLocalCleanupInterceptor;
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(threadLocalCleanupInterceptor);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RestTemplate restTemplate() {
|
||||
return new RestTemplate();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
package com.spring.step2.controller;
|
||||
package com.spring.step3.controller;
|
||||
|
||||
import com.spring.step2.domain.dto.LoginDto;
|
||||
import com.spring.step2.domain.vo.LoginVo;
|
||||
import com.spring.step2.domain.vo.result.Result;
|
||||
import com.spring.step2.service.user.LoginService;
|
||||
import com.spring.step3.domain.dto.LoginDto;
|
||||
import com.spring.step3.domain.vo.LoginVo;
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.service.user.LoginService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.RequiredArgsConstructor;
|
|
@ -0,0 +1,77 @@
|
|||
package com.spring.step3.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.spring.step3.domain.dto.permission.PermissionDto;
|
||||
import com.spring.step3.domain.entity.PermissionEntity;
|
||||
import com.spring.step3.domain.vo.PermissionVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step3.service.roles.PermissionService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统权限表 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@Tag(name = "系统权限表", description = "系统权限表相关接口")
|
||||
@RestController
|
||||
@RequestMapping(value = "/api/permission")
|
||||
@RequiredArgsConstructor
|
||||
public class PermissionController {
|
||||
|
||||
private final PermissionService permissionService;
|
||||
|
||||
@Operation(summary = "分页查询系统权限表", description = "分页系统权限表")
|
||||
@GetMapping("{page}/{limit}")
|
||||
public Result<PageResult<PermissionVo>> getPermissionPage(
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@PathVariable("page") Integer page,
|
||||
@Parameter(name = "limit", description = "每页记录数", required = true)
|
||||
@PathVariable("limit") Integer limit,
|
||||
PermissionDto dto) {
|
||||
Page<PermissionEntity> pageParams = new Page<>(page, limit);
|
||||
PageResult<PermissionVo> pageResult = permissionService.getPermissionPage(pageParams, dto);
|
||||
return Result.success(pageResult);
|
||||
}
|
||||
|
||||
@Operation(summary = "所有的权限列表", description = "获取所有的权限列表")
|
||||
@GetMapping("all")
|
||||
public Result<List<PermissionVo>> getAllPermission() {
|
||||
List<PermissionVo> voList = permissionService.getAllPermission();
|
||||
return Result.success(voList);
|
||||
}
|
||||
|
||||
@Operation(summary = "添加系统权限表", description = "添加系统权限表")
|
||||
@PostMapping()
|
||||
public Result<String> addPermission(@Valid @RequestBody PermissionDto dto) {
|
||||
permissionService.addPermission(dto);
|
||||
return Result.success(ResultCodeEnum.ADD_SUCCESS);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新系统权限表", description = "更新系统权限表")
|
||||
@PutMapping()
|
||||
public Result<String> updatePermission(@Valid @RequestBody PermissionDto dto) {
|
||||
permissionService.updatePermission(dto);
|
||||
return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除系统权限表", description = "删除系统权限表")
|
||||
@DeleteMapping()
|
||||
public Result<String> deletePermission(@RequestBody List<Long> ids) {
|
||||
permissionService.deletePermission(ids);
|
||||
return Result.success(ResultCodeEnum.DELETE_SUCCESS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,79 @@
|
|||
package com.spring.step3.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.spring.step3.domain.dto.role.RoleDto;
|
||||
import com.spring.step3.domain.entity.RoleEntity;
|
||||
import com.spring.step3.domain.vo.RoleVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step3.service.roles.RoleService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.annotation.security.PermitAll;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统角色表 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@Tag(name = "系统角色表", description = "系统角色表相关接口")
|
||||
@RestController
|
||||
@RequestMapping("/api/role")
|
||||
@RequiredArgsConstructor
|
||||
|
||||
public class RoleController {
|
||||
|
||||
private final RoleService roleService;
|
||||
|
||||
@Operation(summary = "分页查询系统角色表", description = "分页系统角色表")
|
||||
@GetMapping("{page}/{limit}")
|
||||
public Result<PageResult<RoleVo>> getRolePage(
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@PathVariable("page") Integer page,
|
||||
@Parameter(name = "limit", description = "每页记录数", required = true)
|
||||
@PathVariable("limit") Integer limit,
|
||||
RoleDto dto) {
|
||||
Page<RoleEntity> pageParams = new Page<>(page, limit);
|
||||
PageResult<RoleVo> pageResult = roleService.getRolePage(pageParams, dto);
|
||||
return Result.success(pageResult);
|
||||
}
|
||||
|
||||
@PermitAll
|
||||
@Operation(summary = "获取全部角色列表", description = "获取全部角色列表")
|
||||
@GetMapping("all")
|
||||
public Result<List<RoleVo>> getRoleList() {
|
||||
List<RoleVo> roleVoList = roleService.getRoleList();
|
||||
return Result.success(roleVoList);
|
||||
}
|
||||
|
||||
@Operation(summary = "添加系统角色表", description = "添加系统角色表")
|
||||
@PostMapping()
|
||||
public Result<String> addRole(@Valid @RequestBody RoleDto dto) {
|
||||
roleService.addRole(dto);
|
||||
return Result.success(ResultCodeEnum.ADD_SUCCESS);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新系统角色表", description = "更新系统角色表")
|
||||
@PutMapping()
|
||||
public Result<String> updateRole(@Valid @RequestBody RoleDto dto) {
|
||||
roleService.updateRole(dto);
|
||||
return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除系统角色表", description = "删除系统角色表")
|
||||
@DeleteMapping()
|
||||
public Result<String> deleteRole(@RequestBody List<Long> ids) {
|
||||
roleService.deleteRole(ids);
|
||||
return Result.success(ResultCodeEnum.DELETE_SUCCESS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
package com.spring.step3.controller;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.spring.step3.domain.dto.role.AssignRolePermissionDto;
|
||||
import com.spring.step3.domain.dto.role.RolePermissionDto;
|
||||
import com.spring.step3.domain.entity.RolePermissionEntity;
|
||||
import com.spring.step3.domain.vo.RolePermissionVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step3.service.roles.RolePermissionService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 角色权限关联表 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@Tag(name = "角色权限关联表", description = "角色权限关联表相关接口")
|
||||
@RestController
|
||||
@RequestMapping("/api/role-permission")
|
||||
@RequiredArgsConstructor
|
||||
public class RolePermissionController {
|
||||
|
||||
private final RolePermissionService rolePermissionService;
|
||||
|
||||
@Operation(summary = "分页查询角色权限关联表", description = "分页角色权限关联表")
|
||||
@GetMapping("{page}/{limit}")
|
||||
public Result<PageResult<RolePermissionVo>> getRolePermissionPage(
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@PathVariable("page") Integer page,
|
||||
@Parameter(name = "limit", description = "每页记录数", required = true)
|
||||
@PathVariable("limit") Integer limit,
|
||||
RolePermissionDto dto) {
|
||||
Page<RolePermissionEntity> pageParams = new Page<>(page, limit);
|
||||
PageResult<RolePermissionVo> pageResult = rolePermissionService.getRolePermissionPage(pageParams, dto);
|
||||
return Result.success(pageResult);
|
||||
}
|
||||
|
||||
@GetMapping("permissions")
|
||||
@Operation(summary = "根据角色id获取权限内容", description = "根据角色id获取权限内容")
|
||||
public Result<List<RolePermissionVo>> getRolePermissionById(Long permissionId) {
|
||||
List<RolePermissionVo> voList = rolePermissionService.getRolePermissionById(permissionId);
|
||||
return Result.success(voList);
|
||||
}
|
||||
|
||||
@Operation(summary = "添加角色权限关联表", description = "添加角色权限关联表")
|
||||
@PostMapping()
|
||||
public Result<String> addRolePermission(@Valid @RequestBody RolePermissionDto dto) {
|
||||
rolePermissionService.addRolePermission(dto);
|
||||
return Result.success(ResultCodeEnum.ADD_SUCCESS);
|
||||
}
|
||||
|
||||
@Operation(summary = "为角色分配权限", description = "根据角色id分配权限")
|
||||
@PostMapping("assign-permission")
|
||||
public Result<String> assignRolePermission(@Valid @RequestBody AssignRolePermissionDto dto) {
|
||||
rolePermissionService.assignRolePermission(dto);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "更新角色权限关联表", description = "更新角色权限关联表")
|
||||
@PutMapping()
|
||||
public Result<String> updateRolePermission(@Valid @RequestBody RolePermissionDto dto) {
|
||||
rolePermissionService.updateRolePermission(dto);
|
||||
return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除角色权限关联表", description = "删除角色权限关联表")
|
||||
@DeleteMapping()
|
||||
public Result<String> deleteRolePermission(@RequestBody List<Long> ids) {
|
||||
rolePermissionService.deleteRolePermission(ids);
|
||||
return Result.success(ResultCodeEnum.DELETE_SUCCESS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
package com.spring.step3.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.spring.step3.domain.dto.user.UserDto;
|
||||
import com.spring.step3.domain.entity.UserEntity;
|
||||
import com.spring.step3.domain.vo.UserVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step3.service.user.UserService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户基本信息表 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@Tag(name = "用户基本信息表", description = "用户基本信息表相关接口")
|
||||
@RestController
|
||||
@RequestMapping("/api/user")
|
||||
@RequiredArgsConstructor
|
||||
public class UserController {
|
||||
|
||||
private final UserService userService;
|
||||
|
||||
@Operation(summary = "分页查询用户基本信息表", description = "分页用户基本信息表")
|
||||
@GetMapping("{page}/{limit}")
|
||||
public Result<PageResult<UserVo>> getUserPage(
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@PathVariable("page") Integer page,
|
||||
@Parameter(name = "limit", description = "每页记录数", required = true)
|
||||
@PathVariable("limit") Integer limit,
|
||||
UserDto dto) {
|
||||
Page<UserEntity> pageParams = new Page<>(page, limit);
|
||||
PageResult<UserVo> pageResult = userService.getUserPage(pageParams, dto);
|
||||
return Result.success(pageResult, ResultCodeEnum.LOAD_FINISHED);
|
||||
}
|
||||
|
||||
@Operation(summary = "添加用户基本信息表", description = "添加用户基本信息表")
|
||||
@PostMapping()
|
||||
public Result<String> addUser(@Valid @RequestBody UserDto dto) {
|
||||
userService.addUser(dto);
|
||||
return Result.success(ResultCodeEnum.ADD_SUCCESS);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新用户基本信息表", description = "更新用户基本信息表")
|
||||
@PutMapping()
|
||||
public Result<String> updateUser(@Valid @RequestBody UserDto dto) {
|
||||
userService.updateUser(dto);
|
||||
return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除用户基本信息表", description = "删除用户基本信息表")
|
||||
@DeleteMapping()
|
||||
public Result<String> deleteUser(@RequestBody List<Long> ids) {
|
||||
userService.deleteUser(ids);
|
||||
return Result.success(ResultCodeEnum.DELETE_SUCCESS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,84 @@
|
|||
package com.spring.step3.controller;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.spring.step3.domain.dto.user.AssignUserRoleDto;
|
||||
import com.spring.step3.domain.dto.user.UserRoleDto;
|
||||
import com.spring.step3.domain.entity.UserRoleEntity;
|
||||
import com.spring.step3.domain.vo.UserRoleVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step3.service.user.UserRoleService;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.validation.Valid;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户角色关联表 前端控制器
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@Tag(name = "用户角色关联表", description = "用户角色关联表相关接口")
|
||||
@RestController
|
||||
@RequestMapping("/api/user-role")
|
||||
@RequiredArgsConstructor
|
||||
public class UserRoleController {
|
||||
|
||||
private final UserRoleService userRoleService;
|
||||
|
||||
@Operation(summary = "分页查询用户角色关联表", description = "分页用户角色关联表")
|
||||
@GetMapping("{page}/{limit}")
|
||||
public Result<PageResult<UserRoleVo>> getUserRolePage(
|
||||
@Parameter(name = "page", description = "当前页", required = true)
|
||||
@PathVariable("page") Integer page,
|
||||
@Parameter(name = "limit", description = "每页记录数", required = true)
|
||||
@PathVariable("limit") Integer limit,
|
||||
UserRoleDto dto) {
|
||||
Page<UserRoleEntity> pageParams = new Page<>(page, limit);
|
||||
PageResult<UserRoleVo> pageResult = userRoleService.getUserRolePage(pageParams, dto);
|
||||
return Result.success(pageResult);
|
||||
}
|
||||
|
||||
@Operation(summary = "根据用户id获取当前用户角色列表", description = "根据用户id获取当前用户角色列表")
|
||||
@GetMapping("roles")
|
||||
public Result<List<UserRoleVo>> getRoleListByUserId(Long userId) {
|
||||
List<UserRoleVo> voList = userRoleService.getRoleListByUserId(userId);
|
||||
return Result.success(voList);
|
||||
}
|
||||
|
||||
@Operation(summary = "添加用户角色关联表", description = "添加用户角色关联表")
|
||||
@PostMapping()
|
||||
public Result<String> addUserRole(@Valid @RequestBody UserRoleDto dto) {
|
||||
userRoleService.addUserRole(dto);
|
||||
return Result.success(ResultCodeEnum.ADD_SUCCESS);
|
||||
}
|
||||
|
||||
@Operation(summary = "为用户分配角色id", description = "根据用户id分配用户角色")
|
||||
@PostMapping("assign-role")
|
||||
public Result<String> assignUserRole(@Valid @RequestBody AssignUserRoleDto dto) {
|
||||
userRoleService.assignUserRole(dto);
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@Operation(summary = "更新用户角色关联表", description = "更新用户角色关联表")
|
||||
@PutMapping()
|
||||
public Result<String> updateUserRole(@Valid @RequestBody UserRoleDto dto) {
|
||||
userRoleService.updateUserRole(dto);
|
||||
return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除用户角色关联表", description = "删除用户角色关联表")
|
||||
@DeleteMapping()
|
||||
public Result<String> deleteUserRole(@RequestBody List<Long> ids) {
|
||||
userRoleService.deleteUserRole(ids);
|
||||
return Result.success(ResultCodeEnum.DELETE_SUCCESS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package com.spring.step3.controller;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
|
||||
@Controller
|
||||
public class WebController {
|
||||
|
||||
@GetMapping("")
|
||||
public String indexPage() {
|
||||
return "index";
|
||||
}
|
||||
|
||||
@GetMapping("/login")
|
||||
public String showLoginPage() {
|
||||
return "loginPage";
|
||||
}
|
||||
|
||||
@GetMapping("/user")
|
||||
public String showUserPage() {
|
||||
return "userPage";
|
||||
}
|
||||
|
||||
@GetMapping("/role")
|
||||
public String showRolePage() {
|
||||
return "rolePage";
|
||||
}
|
||||
|
||||
@GetMapping("/permission")
|
||||
public String showPermissionPage() {
|
||||
return "permissionPage";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.spring.step3.controller.test;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "检查接口", description = "检查当前用户的权限信息")
|
||||
@RestController
|
||||
@RequestMapping("/api/security")
|
||||
public class CheckController {
|
||||
|
||||
@Operation(summary = "当前用户的信息", description = "当前用户的信息")
|
||||
@GetMapping("/current-user")
|
||||
public Authentication getCurrentUser() {
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
System.out.println("Current user: " + auth.getName());
|
||||
System.out.println("Authorities: " + auth.getAuthorities());
|
||||
return auth;
|
||||
}
|
||||
|
||||
@Operation(summary = "获取用户详情", description = "获取用户详情")
|
||||
@GetMapping("user-detail")
|
||||
public UserDetails getCurrentUserDetail() {
|
||||
Authentication auth = SecurityContextHolder.getContext().getAuthentication();
|
||||
Object principal = auth.getPrincipal();
|
||||
|
||||
if (principal instanceof UserDetails) {
|
||||
return (UserDetails) principal;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.spring.step3.controller.test;
|
||||
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.security.annotation.IsAdmin;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "ADMIN接口", description = "只要包含 Admin 角色都可以访问")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/security/admin")
|
||||
public class SecurityAdminController {
|
||||
|
||||
@IsAdmin
|
||||
@Operation(summary = "拥有 IsAdmin 的角色可以访问", description = "当前用户拥有 IsAdmin 角色可以访问这个接口")
|
||||
@GetMapping("role-user")
|
||||
public Result<String> roleUser() {
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@IsAdmin
|
||||
@Operation(summary = "拥有 IsAdmin 的角色可以访问", description = "当前用户拥有 IsAdmin 角色可以访问这个接口")
|
||||
@GetMapping("upper-user")
|
||||
public Result<String> upperUser() {
|
||||
String data = "是区分大小写的";
|
||||
return Result.success(data);
|
||||
}
|
||||
|
||||
@IsAdmin
|
||||
@Operation(summary = "拥有 IsAdmin 的角色可以访问", description = "当前用户拥有 IsAdmin 角色可以访问这个接口")
|
||||
@GetMapping("lower-user")
|
||||
public Result<String> lowerUser() {
|
||||
String data = "如果是大写,但是在这里是小写无法访问";
|
||||
return Result.success(data);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.spring.step3.controller.test;
|
||||
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PostAuthorize;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "NORMAl接口", description = "测试用的NORMAl接口")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/security/normal")
|
||||
public class SecurityController {
|
||||
|
||||
@PreAuthorize("hasAuthority('role::read')")
|
||||
@Operation(summary = "拥有 role:read 的角色可以访问", description = "当前用户拥有 role:read 角色可以访问这个接口")
|
||||
@GetMapping("role-user")
|
||||
public Result<String> roleUser() {
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('USER')")
|
||||
@Operation(summary = "拥有 USER 的角色可以访问", description = "当前用户拥有 USER 角色可以访问这个接口")
|
||||
@GetMapping("upper-user")
|
||||
public Result<String> upperUser() {
|
||||
String data = "是区分大小写的";
|
||||
return Result.success(data);
|
||||
}
|
||||
|
||||
@PreAuthorize("hasAuthority('user')")
|
||||
@Operation(summary = "拥有 USER 的角色可以访问", description = "当前用户拥有 USER 角色可以访问这个接口")
|
||||
@GetMapping("lower-user")
|
||||
public Result<String> lowerUser() {
|
||||
String data = "如果是大写,但是在这里是小写无法访问";
|
||||
return Result.success(data);
|
||||
}
|
||||
|
||||
@PostAuthorize("returnObject.data == authentication.name")
|
||||
@Operation(summary = "测试使用返回参数判断权限", description = "测试使用返回参数判断权限 用户拥有 role::read 可以访问这个接口")
|
||||
@GetMapping("test-post-authorize")
|
||||
public Result<String> testPostAuthorize() {
|
||||
log.info("方法内容已经执行。。。");
|
||||
String data = "Bunny";
|
||||
return Result.success(data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
package com.spring.step3.controller.test;
|
||||
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.security.annotation.HasAnyAuthority;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "ANY ROLES", description = "只要包含 ANY 角色都可以访问")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/security/any")
|
||||
public class SecurityHasAnyAuthorityController {
|
||||
|
||||
@HasAnyAuthority(auth = {"'USER'", "'ADMIN'"})
|
||||
@Operation(summary = "拥有 HasAnyXXX 的角色可以访问", description = "当前用户拥有 HasAnyXXX 角色可以访问这个接口")
|
||||
@GetMapping("role-user")
|
||||
public Result<String> roleUser() {
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@HasAnyAuthority(auth = {"'USER'", "'ADMIN'"})
|
||||
@Operation(summary = "拥有 HasAnyXXX 的角色可以访问", description = "当前用户拥有 HasAnyXXX 角色可以访问这个接口")
|
||||
@GetMapping("upper-user")
|
||||
public Result<String> upperUser() {
|
||||
String data = "是区分大小写的";
|
||||
return Result.success(data);
|
||||
}
|
||||
|
||||
@HasAnyAuthority(auth = {"'USER'", "'ADMIN'"})
|
||||
@Operation(summary = "拥有 HasAnyXXX 的角色可以访问", description = "当前用户拥有 HasAnyXXX 角色可以访问这个接口")
|
||||
@GetMapping("lower-user")
|
||||
public Result<String> lowerUser() {
|
||||
String data = "如果是大写,但是在这里是小写无法访问";
|
||||
return Result.success(data);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.spring.step3.controller.test;
|
||||
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "Programmatically", description = "只要包含 Programmatically 角色都可以访问")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/security/programmatically")
|
||||
public class SecurityProgrammaticallyController {
|
||||
|
||||
@Operation(summary = "拥有 USER 的角色可以访问", description = "当前用户拥有 USER 角色可以访问这个接口")
|
||||
@GetMapping("upper-user")
|
||||
public Result<String> upperUser() {
|
||||
String data = "是区分大小写的";
|
||||
return Result.success(data);
|
||||
}
|
||||
|
||||
@PreAuthorize("@auth.decide(#name)")
|
||||
@Operation(summary = "拥有 USER 的角色可以访问", description = "当前用户拥有 USER 角色可以访问这个接口")
|
||||
@GetMapping("lower-user")
|
||||
public Result<String> lowerUser(String name) {
|
||||
return Result.success(name);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.spring.step3.controller.test;
|
||||
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.security.annotation.HasUSERAuthorize;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
@Tag(name = "USER测试", description = "只要包含 USER 角色都可以访问")
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/api/security/user")
|
||||
public class SecurityUserController {
|
||||
|
||||
@HasUSERAuthorize("role:read")
|
||||
@Operation(summary = "拥有 role:read 的角色可以访问", description = "当前用户拥有 role:read 角色可以访问这个接口")
|
||||
@GetMapping("role-user")
|
||||
public Result<String> roleUser() {
|
||||
return Result.success();
|
||||
}
|
||||
|
||||
@HasUSERAuthorize("USER")
|
||||
@Operation(summary = "拥有 USER 的角色可以访问", description = "当前用户拥有 USER 角色可以访问这个接口")
|
||||
@GetMapping("upper-user")
|
||||
public Result<String> upperUser() {
|
||||
String data = "是区分大小写的";
|
||||
return Result.success(data);
|
||||
}
|
||||
|
||||
@HasUSERAuthorize("user")
|
||||
@Operation(summary = "拥有 USER 的角色可以访问", description = "当前用户拥有 USER 角色可以访问这个接口")
|
||||
@GetMapping("lower-user")
|
||||
public Result<String> lowerUser() {
|
||||
String data = "如果是大写,但是在这里是小写无法访问";
|
||||
return Result.success(data);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package com.spring.step3.domain.dto;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@Schema(name = "LoginRequest", title = "LoginRequest登录参数", description = "登录请求参数")
|
||||
public class LoginDto {
|
||||
|
||||
@Schema(name = "type", description = "登录类型")
|
||||
private String type = "default";
|
||||
|
||||
@Schema(name = "username", title = "用户名")
|
||||
private String username;
|
||||
|
||||
@Schema(name = "password", description = "密码")
|
||||
private String password;
|
||||
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
package com.spring.step3.domain.dto.permission;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "PermissionDTO对象", title = "系统权限表", description = "系统权限表的DTO对象")
|
||||
public class PermissionDto {
|
||||
|
||||
@Schema(name = "id", title = "主键ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "permissionCode", title = "权限编码")
|
||||
private String permissionCode;
|
||||
|
||||
@Schema(name = "url", description = "URL")
|
||||
private String url;
|
||||
|
||||
@Schema(name = "method", description = "请求方法类型")
|
||||
private String method;
|
||||
|
||||
@Schema(name = "description", title = "权限描述")
|
||||
private String description;
|
||||
|
||||
@Schema(name = "remark", title = "备注信息")
|
||||
private String remark;
|
||||
|
||||
@Schema(name = "createTime", title = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(name = "updateTime", title = "更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(name = "createUser", title = "创建用户ID")
|
||||
private Long createUser;
|
||||
|
||||
@Schema(name = "updateUser", title = "更新用户ID")
|
||||
private Long updateUser;
|
||||
|
||||
@Schema(name = "isDeleted", title = "是否删除:0-未删除,1-已删除")
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.spring.step3.domain.dto.role;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "AssignRolePermissionDTO对象", title = "角色分配权限DTO", description = "根据角色id分配权限")
|
||||
public class AssignRolePermissionDto {
|
||||
|
||||
@Schema(name = "roleId", title = "角色ID")
|
||||
@NotNull(message = "角色id为空")
|
||||
private Long roleId;
|
||||
|
||||
@Schema(name = "permissionId", title = "权限ID")
|
||||
@NotEmpty(message = "权限id为空")
|
||||
private List<Long> permissionIds;
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.spring.step3.domain.dto.role;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "RoleDTO对象", title = "系统角色表", description = "系统角色表的DTO对象")
|
||||
public class RoleDto {
|
||||
|
||||
@Schema(name = "id", title = "主键ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "roleCode", title = "角色码")
|
||||
@NotBlank(message = "角色码不能为空")
|
||||
private String roleCode;
|
||||
|
||||
@Schema(name = "description", title = "角色描述")
|
||||
@NotBlank(message = "角色描述不能为空")
|
||||
private String description;
|
||||
|
||||
@Schema(name = "remark", title = "备注信息")
|
||||
@NotBlank(message = "备注信息不能为空")
|
||||
private String remark;
|
||||
|
||||
@Schema(name = "createTime", title = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(name = "updateTime", title = "更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(name = "createUser", title = "创建用户ID")
|
||||
private Long createUser;
|
||||
|
||||
@Schema(name = "updateUser", title = "更新用户ID")
|
||||
private Long updateUser;
|
||||
|
||||
@Schema(name = "isDeleted", title = "是否删除:0-未删除,1-已删除")
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.spring.step3.domain.dto.role;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "RolePermissionDTO对象", title = "角色权限关联表", description = "角色权限关联表的DTO对象")
|
||||
public class RolePermissionDto {
|
||||
|
||||
@Schema(name = "id", title = "主键ID")
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "roleId", title = "角色ID")
|
||||
private Long roleId;
|
||||
|
||||
@Schema(name = "permissionId", title = "权限ID")
|
||||
private Long permissionId;
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.spring.step3.domain.dto.user;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotEmpty;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "AssignUserRoleDTO对象", title = "用户分配角色DTO", description = "根据用户id分配用户角色")
|
||||
public class AssignUserRoleDto {
|
||||
|
||||
@Schema(name = "userId", title = "用户ID")
|
||||
@NotNull(message = "用户id为空")
|
||||
private Long userId;
|
||||
|
||||
@Schema(name = "roleId", title = "角色ID")
|
||||
@NotEmpty(message = "角色ID为空")
|
||||
private List<Long> roleIds;
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.spring.step3.domain.dto.user;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "UserDTO对象", title = "用户", description = "用户的DTO对象")
|
||||
public class UserDto {
|
||||
|
||||
@Schema(name = "id", title = "主键")
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "username", title = "用户名")
|
||||
@NotBlank(message = "用户名不能为空")
|
||||
private String username;
|
||||
|
||||
@Schema(name = "password", title = "密码")
|
||||
private String password;
|
||||
|
||||
@Schema(name = "email", title = "邮箱")
|
||||
@NotBlank(message = "邮箱不能为空")
|
||||
private String email;
|
||||
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.spring.step3.domain.dto.user;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "UserRoleDTO对象", title = "用户角色关联表", description = "用户角色关联表的DTO对象")
|
||||
public class UserRoleDto {
|
||||
|
||||
@Schema(name = "id", title = "主键")
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "roleId", title = "角色ID")
|
||||
private Long roleId;
|
||||
|
||||
@Schema(name = "userId", title = "用户ID")
|
||||
private Long userId;
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.spring.step3.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.spring.step3.domain.entity.base.BaseEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
@TableName("t_permission")
|
||||
@Schema(name = "Permission对象", title = "系统权限表", description = "系统权限表的实体类对象")
|
||||
public class PermissionEntity extends BaseEntity {
|
||||
|
||||
@Schema(name = "permissionCode", title = "权限编码")
|
||||
private String permissionCode;
|
||||
|
||||
@Schema(name = "url", description = "URL")
|
||||
private String url;
|
||||
|
||||
@Schema(name = "method", description = "请求方法类型")
|
||||
private String method;
|
||||
|
||||
@Schema(name = "description", title = "权限描述")
|
||||
private String description;
|
||||
|
||||
@Schema(name = "remark", title = "备注信息")
|
||||
private String remark;
|
||||
|
||||
@Schema(name = "isDeleted", title = "是否删除:0-未删除,1-已删除")
|
||||
@TableField(exist = false)
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
package com.spring.step3.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.spring.step3.domain.entity.base.BaseEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
@TableName("t_role")
|
||||
@Schema(name = "Role对象", title = "系统角色表", description = "系统角色表的实体类对象")
|
||||
public class RoleEntity extends BaseEntity {
|
||||
|
||||
@Schema(name = "roleCode", title = "角色码")
|
||||
private String roleCode;
|
||||
|
||||
@Schema(name = "description", title = "角色描述")
|
||||
private String description;
|
||||
|
||||
@Schema(name = "remark", title = "备注信息")
|
||||
private String remark;
|
||||
|
||||
@Schema(name = "isDeleted", title = "是否删除:0-未删除,1-已删除")
|
||||
@TableField(exist = false)
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.spring.step3.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.spring.step3.domain.entity.base.BaseEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
@TableName("t_role_permission")
|
||||
@Schema(name = "RolePermission对象", title = "角色权限关联表", description = "角色权限关联表的实体类对象")
|
||||
public class RolePermissionEntity extends BaseEntity {
|
||||
|
||||
@Schema(name = "roleId", title = "角色ID")
|
||||
private Long roleId;
|
||||
|
||||
@Schema(name = "permissionId", title = "权限ID")
|
||||
private Long permissionId;
|
||||
|
||||
@Schema(name = "isDeleted", title = "是否删除:0-未删除,1-已删除")
|
||||
@TableField(exist = false)
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
package com.spring.step3.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.springframework.security.core.CredentialsContainer;
|
||||
import org.springframework.security.core.GrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.Set;
|
||||
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@TableName("t_user")
|
||||
@Schema(name = "User对象", title = "用户", description = "用户的实体类对象")
|
||||
public class UserEntity implements UserDetails, CredentialsContainer {
|
||||
|
||||
@Schema(name = "id", title = "唯一标识")
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "username", title = "用户名")
|
||||
private String username;
|
||||
|
||||
@Schema(name = "password", title = "密码")
|
||||
private String password;
|
||||
|
||||
@Schema(name = "email", title = "邮箱")
|
||||
private String email;
|
||||
|
||||
@Schema(name = "createTime", title = "创建时间")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(name = "updateTime", title = "更新时间")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(name = "createUser", title = "创建用户")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long createUser;
|
||||
|
||||
@Schema(name = "updateUser", title = "操作用户")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long updateUser;
|
||||
|
||||
@Schema(name = "isDeleted", title = "是否被删除")
|
||||
@TableField(exist = false)
|
||||
private Boolean isDeleted;
|
||||
|
||||
@TableField(exist = false)
|
||||
private Set<? extends GrantedAuthority> authorities;
|
||||
|
||||
@Override
|
||||
public void eraseCredentials() {
|
||||
this.password = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<? extends GrantedAuthority> getAuthorities() {
|
||||
return this.authorities;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
package com.spring.step3.domain.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.spring.step3.domain.entity.base.BaseEntity;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.Accessors;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Accessors(chain = true)
|
||||
@TableName("t_user_role")
|
||||
@Schema(name = "UserRole对象", title = "用户角色关联表", description = "用户角色关联表的实体类对象")
|
||||
public class UserRoleEntity extends BaseEntity {
|
||||
|
||||
@Schema(name = "roleId", title = "角色ID")
|
||||
private Long roleId;
|
||||
|
||||
@Schema(name = "userId", title = "用户ID")
|
||||
private Long userId;
|
||||
|
||||
@Schema(name = "isDeleted", title = "是否删除:0-未删除,1-已删除")
|
||||
@TableField(exist = false)
|
||||
private Boolean isDeleted;
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.spring.step3.domain.entity.base;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldFill;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
@Schema(name = "BaseEntity", title = "基础信息字段", description = "基础信息字段")
|
||||
public class BaseEntity implements Serializable {
|
||||
|
||||
@Schema(name = "id", title = "唯一标识")
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "createTime", title = "创建时间")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(name = "updateTime", title = "更新时间")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(name = "createUser", title = "创建用户")
|
||||
@TableField(fill = FieldFill.INSERT)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long createUser;
|
||||
|
||||
@Schema(name = "updateUser", title = "操作用户")
|
||||
@TableField(fill = FieldFill.INSERT_UPDATE)
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long updateUser;
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
package com.spring.step3.domain.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
public enum LoginEnums {
|
||||
// 邮箱登录请求
|
||||
EMAIL_STRATEGY("email"),
|
||||
// 默认登录请求
|
||||
default_STRATEGY("default"),
|
||||
;
|
||||
|
||||
private final String value;
|
||||
|
||||
LoginEnums(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
package com.spring.step3.domain.vo;
|
||||
|
||||
|
||||
import com.spring.step3.domain.vo.base.BaseVo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* 用户登录返回内容
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Schema(name = "LoginVo对象", title = "登录成功返回内容", description = "登录成功返回内容")
|
||||
public class LoginVo extends BaseVo {
|
||||
|
||||
@Schema(name = "nickname", title = "昵称")
|
||||
private String nickname;
|
||||
|
||||
@Schema(name = "username", title = "用户名")
|
||||
private String username;
|
||||
|
||||
@Schema(name = "email", title = "邮箱")
|
||||
private String email;
|
||||
|
||||
@Schema(name = "token", title = "令牌")
|
||||
private String token;
|
||||
|
||||
@Schema(name = "expires", title = "过期时间")
|
||||
private String expires;
|
||||
|
||||
@Schema(name = "readMeDay", title = "记住我多久")
|
||||
private Long readMeDay;
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package com.spring.step3.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.spring.step3.domain.vo.base.BaseVo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Schema(name = "PermissionVO对象", title = "系统权限表", description = "系统权限表的VO对象")
|
||||
public class PermissionVo extends BaseVo {
|
||||
|
||||
@Schema(name = "id", title = "主键ID")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "permissionCode", title = "权限编码")
|
||||
private String permissionCode;
|
||||
|
||||
@Schema(name = "url", description = "URL")
|
||||
private String url;
|
||||
|
||||
@Schema(name = "method", description = "请求方法类型")
|
||||
private String method;
|
||||
|
||||
@Schema(name = "description", title = "权限描述")
|
||||
private String description;
|
||||
|
||||
@Schema(name = "remark", title = "备注信息")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
package com.spring.step3.domain.vo;
|
||||
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.spring.step3.domain.vo.base.BaseVo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Schema(name = "RolePermissionVO对象", title = "角色权限关联表", description = "角色权限关联表的VO对象")
|
||||
public class RolePermissionVo extends BaseVo {
|
||||
|
||||
@Schema(name = "id", title = "主键ID")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "roleId", title = "角色ID")
|
||||
private Long roleId;
|
||||
|
||||
@Schema(name = "permissionId", title = "权限ID")
|
||||
private Long permissionId;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
package com.spring.step3.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.spring.step3.domain.vo.base.BaseVo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Schema(name = "RoleVO对象", title = "系统角色表", description = "系统角色表的VO对象")
|
||||
public class RoleVo extends BaseVo {
|
||||
|
||||
@Schema(name = "id", title = "主键ID")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "roleCode", title = "角色名称")
|
||||
private String roleCode;
|
||||
|
||||
@Schema(name = "description", title = "角色描述")
|
||||
private String description;
|
||||
|
||||
@Schema(name = "remark", title = "备注信息")
|
||||
private String remark;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
package com.spring.step3.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.spring.step3.domain.vo.base.BaseVo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Schema(name = "UserRoleVO对象", title = "用户角色关联表", description = "用户角色关联表的VO对象")
|
||||
public class UserRoleVo extends BaseVo {
|
||||
|
||||
@Schema(name = "id", title = "主键")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "roleId", title = "角色ID")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long roleId;
|
||||
|
||||
@Schema(name = "userId", title = "用户ID")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long userId;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
package com.spring.step3.domain.vo;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
|
||||
import com.spring.step3.domain.vo.base.BaseVo;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Schema(name = "UserVO对象", title = "用户基本信息表", description = "用户基本信息表的VO对象")
|
||||
public class UserVo extends BaseVo {
|
||||
|
||||
@Schema(name = "id", title = "主键")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING)
|
||||
@JsonSerialize(using = ToStringSerializer.class)
|
||||
private Long id;
|
||||
|
||||
@Schema(name = "username", title = "用户名")
|
||||
private String username;
|
||||
|
||||
@Schema(name = "email", title = "邮箱")
|
||||
private String email;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
package com.spring.step3.domain.vo.base;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.Data;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
|
||||
@Data
|
||||
public class BaseVo {
|
||||
|
||||
@Schema(name = "createTime", title = "创建时间")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
@Schema(name = "updateTime", title = "更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@Schema(name = "createUser", title = "创建用户ID")
|
||||
private Long createUser;
|
||||
|
||||
@Schema(name = "updateUser", title = "更新用户ID")
|
||||
private Long updateUser;
|
||||
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
package com.spring.step3.domain.vo.result;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 封装分页查询结果
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "PageResult 对象", title = "分页返回结果", description = "分页返回结果")
|
||||
public class PageResult<T> implements Serializable {
|
||||
|
||||
@Schema(name = "pageNo", title = "当前页")
|
||||
private Long pageNo;
|
||||
|
||||
@Schema(name = "pageSize", title = "每页记录数")
|
||||
private Long pageSize;
|
||||
|
||||
@Schema(name = "pages", title = "总分页数")
|
||||
private Long pages;
|
||||
|
||||
@Schema(name = "total", title = "总记录数")
|
||||
private Long total;
|
||||
|
||||
@Schema(name = "list", title = "当前页数据集合")
|
||||
private List<T> list;
|
||||
|
||||
}
|
|
@ -0,0 +1,174 @@
|
|||
package com.spring.step3.domain.vo.result;
|
||||
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class Result<T> {
|
||||
// 状态码
|
||||
private Integer code;
|
||||
// 返回消息
|
||||
private String message;
|
||||
// 返回数据
|
||||
private T data;
|
||||
|
||||
/**
|
||||
* * 自定义返回体
|
||||
*
|
||||
* @param data 返回体
|
||||
* @return Result<T>
|
||||
*/
|
||||
protected static <T> Result<T> build(T data) {
|
||||
Result<T> result = new Result<>();
|
||||
result.setData(data);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* * 自定义返回体,使用ResultCodeEnum构建
|
||||
*
|
||||
* @param body 返回体
|
||||
* @param codeEnum 返回状态码
|
||||
* @return Result<T>
|
||||
*/
|
||||
public static <T> Result<T> build(T body, ResultCodeEnum codeEnum) {
|
||||
Result<T> result = build(body);
|
||||
result.setCode(codeEnum.getCode());
|
||||
result.setMessage(codeEnum.getMessage());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* * 自定义返回体
|
||||
*
|
||||
* @param body 返回体
|
||||
* @param code 返回状态码
|
||||
* @param message 返回消息
|
||||
* @return Result<T>
|
||||
*/
|
||||
public static <T> Result<T> build(T body, Integer code, String message) {
|
||||
Result<T> result = build(body);
|
||||
result.setCode(code);
|
||||
result.setMessage(message);
|
||||
result.setData(null);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作成功
|
||||
*
|
||||
* @return Result<T>
|
||||
*/
|
||||
public static <T> Result<T> success() {
|
||||
return success(null, ResultCodeEnum.SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作成功
|
||||
*
|
||||
* @param data baseCategory1List
|
||||
*/
|
||||
public static <T> Result<T> success(T data) {
|
||||
return build(data, ResultCodeEnum.SUCCESS);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作成功-状态码
|
||||
*
|
||||
* @param codeEnum 状态码
|
||||
*/
|
||||
public static <T> Result<T> success(ResultCodeEnum codeEnum) {
|
||||
return success(null, codeEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作成功-自定义返回数据和状态码
|
||||
*
|
||||
* @param data 返回体
|
||||
* @param codeEnum 状态码
|
||||
*/
|
||||
public static <T> Result<T> success(T data, ResultCodeEnum codeEnum) {
|
||||
return build(data, codeEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败-自定义返回数据和状态码
|
||||
*
|
||||
* @param data 返回体
|
||||
* @param message 错误信息
|
||||
*/
|
||||
public static <T> Result<T> success(T data, String message) {
|
||||
return build(data, 200, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败-自定义返回数据和状态码
|
||||
*
|
||||
* @param data 返回体
|
||||
* @param code 状态码
|
||||
* @param message 错误信息
|
||||
*/
|
||||
public static <T> Result<T> success(T data, Integer code, String message) {
|
||||
return build(data, code, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败
|
||||
*/
|
||||
public static <T> Result<T> error() {
|
||||
return Result.build(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败-自定义返回数据
|
||||
*
|
||||
* @param data 返回体
|
||||
*/
|
||||
public static <T> Result<T> error(T data) {
|
||||
return build(data, ResultCodeEnum.FAIL);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败-状态码
|
||||
*
|
||||
* @param codeEnum 状态码
|
||||
*/
|
||||
public static <T> Result<T> error(ResultCodeEnum codeEnum) {
|
||||
return build(null, codeEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败-自定义返回数据和状态码
|
||||
*
|
||||
* @param data 返回体
|
||||
* @param codeEnum 状态码
|
||||
*/
|
||||
public static <T> Result<T> error(T data, ResultCodeEnum codeEnum) {
|
||||
return build(data, codeEnum);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败-自定义返回数据和状态码
|
||||
*
|
||||
* @param data 返回体
|
||||
* @param code 状态码
|
||||
* @param message 错误信息
|
||||
*/
|
||||
public static <T> Result<T> error(T data, Integer code, String message) {
|
||||
return build(data, code, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 操作失败-自定义返回数据和状态码
|
||||
*
|
||||
* @param data 返回体
|
||||
* @param message 错误信息
|
||||
*/
|
||||
public static <T> Result<T> error(T data, String message) {
|
||||
return build(null, 500, message);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
package com.spring.step3.domain.vo.result;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* 统一返回结果状态信息类
|
||||
*/
|
||||
@Getter
|
||||
public enum ResultCodeEnum {
|
||||
// 成功操作 200
|
||||
SUCCESS(200, "操作成功"),
|
||||
LOAD_FINISHED(200, "加载完成"),
|
||||
ADD_SUCCESS(200, "添加成功"),
|
||||
UPDATE_SUCCESS(200, "修改成功"),
|
||||
DELETE_SUCCESS(200, "删除成功"),
|
||||
ASSIGN_SUCCESS(200, "排序成功"),
|
||||
SUCCESS_UPLOAD(200, "上传成功"),
|
||||
SUCCESS_LOGOUT(200, "退出成功"),
|
||||
EMAIL_CODE_REFRESH(200, "邮箱验证码已刷新"),
|
||||
EMAIL_CODE_SEND_SUCCESS(200, "邮箱验证码已发送"),
|
||||
|
||||
// 验证错误 201
|
||||
USERNAME_OR_PASSWORD_NOT_EMPTY(201, "用户名或密码不能为空"),
|
||||
EMAIL_CODE_NOT_EMPTY(201, "邮箱验证码不能为空"),
|
||||
SEND_EMAIL_CODE_NOT_EMPTY(201, "请先发送邮箱验证码"),
|
||||
EMAIL_CODE_NOT_MATCHING(201, "邮箱验证码不匹配"),
|
||||
LOGIN_ERROR(500, "账号或密码错误"),
|
||||
LOGIN_ERROR_USERNAME_PASSWORD_NOT_EMPTY(201, "登录信息不能为空"),
|
||||
GET_BUCKET_EXCEPTION(201, "获取文件信息失败"),
|
||||
SEND_MAIL_CODE_ERROR(201, "邮件发送失败"),
|
||||
EMAIL_CODE_EMPTY(201, "邮箱验证码过期或不存在"),
|
||||
EMAIL_EXIST(201, "邮箱已存在"),
|
||||
REQUEST_IS_EMPTY(201, "请求数据为空"),
|
||||
DATA_TOO_LARGE(201, "请求数据为空"),
|
||||
UPDATE_NEW_PASSWORD_SAME_AS_OLD_PASSWORD(201, "新密码与密码相同"),
|
||||
|
||||
// 数据相关 206
|
||||
ILLEGAL_REQUEST(206, "非法请求"),
|
||||
REPEAT_SUBMIT(206, "重复提交"),
|
||||
DATA_ERROR(206, "数据异常"),
|
||||
EMAIL_USER_TEMPLATE_IS_EMPTY(206, "邮件模板为空"),
|
||||
EMAIL_TEMPLATE_IS_EMPTY(206, "邮件模板为空"),
|
||||
EMAIL_USER_IS_EMPTY(206, "关联邮件用户配置为空"),
|
||||
DATA_EXIST(206, "数据已存在"),
|
||||
DATA_NOT_EXIST(206, "数据不存在"),
|
||||
ALREADY_USER_EXCEPTION(206, "用户已存在"),
|
||||
USER_IS_EMPTY(206, "用户不存在"),
|
||||
FILE_NOT_EXIST(206, "文件不存在"),
|
||||
NEW_PASSWORD_SAME_OLD_PASSWORD(206, "新密码不能和旧密码相同"),
|
||||
MISSING_TEMPLATE_FILES(206, "缺少模板文件"),
|
||||
|
||||
// 身份过期 208
|
||||
LOGIN_AUTH(208, "请先登陆"),
|
||||
AUTHENTICATION_EXPIRED(208, "身份验证过期"),
|
||||
SESSION_EXPIRATION(208, "会话过期"),
|
||||
|
||||
// 209
|
||||
THE_SAME_USER_HAS_LOGGED_IN(209, "相同用户已登录"),
|
||||
|
||||
// 提示错误
|
||||
UPDATE_ERROR(216, "修改失败"),
|
||||
URL_ENCODE_ERROR(216, "URL编码失败"),
|
||||
ILLEGAL_CALLBACK_REQUEST_ERROR(217, "非法回调请求"),
|
||||
FETCH_USERINFO_ERROR(219, "获取用户信息失败"),
|
||||
ILLEGAL_DATA_REQUEST(219, "非法数据请求"),
|
||||
CLASS_NOT_FOUND(219, "类名不存在"),
|
||||
ADMIN_ROLE_CAN_NOT_DELETED(219, "无法删除admin角色"),
|
||||
ROUTER_RANK_NEED_LARGER_THAN_THE_PARENT(219, "设置路由等级需要大于或等于父级的路由等级"),
|
||||
|
||||
// 无权访问 403
|
||||
FAIL_NO_ACCESS_DENIED(403, "无权访问"),
|
||||
FAIL_NO_ACCESS_DENIED_USER_OFFLINE(403, "用户强制下线"),
|
||||
TOKEN_PARSING_FAILED(403, "token解析失败"),
|
||||
FAIL_NO_ACCESS_DENIED_USER_LOCKED(403, "该账户已封禁"),
|
||||
|
||||
// 系统错误 500
|
||||
UNKNOWN_EXCEPTION(500, "服务异常"),
|
||||
SERVICE_ERROR(500, "服务异常"),
|
||||
UPLOAD_ERROR(500, "上传失败"),
|
||||
FAIL(500, "失败"),
|
||||
;
|
||||
|
||||
private final Integer code;
|
||||
private final String message;
|
||||
|
||||
ResultCodeEnum(Integer code, String message) {
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
package com.spring.step3.exception;
|
||||
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.ToString;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@NoArgsConstructor
|
||||
@Getter
|
||||
@ToString
|
||||
@Slf4j
|
||||
public class AuthenticSecurityException extends RuntimeException {
|
||||
// 状态码
|
||||
Integer code;
|
||||
|
||||
// 描述信息
|
||||
String message = "服务异常";
|
||||
|
||||
// 返回结果状态
|
||||
ResultCodeEnum resultCodeEnum;
|
||||
|
||||
public AuthenticSecurityException(Integer code, String message) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public AuthenticSecurityException(String message) {
|
||||
super(message);
|
||||
this.message = message;
|
||||
}
|
||||
|
||||
public AuthenticSecurityException(ResultCodeEnum codeEnum) {
|
||||
super(codeEnum.getMessage());
|
||||
this.code = codeEnum.getCode();
|
||||
this.message = codeEnum.getMessage();
|
||||
this.resultCodeEnum = codeEnum;
|
||||
}
|
||||
|
||||
public AuthenticSecurityException(String message, Exception exception) {
|
||||
super(message);
|
||||
this.message = message;
|
||||
log.error(message, exception);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
package com.spring.step3.exception;
|
||||
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.context.support.DefaultMessageSourceResolvable;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.web.bind.MethodArgumentNotValidException;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestControllerAdvice;
|
||||
|
||||
import java.sql.SQLIntegrityConstraintViolationException;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 全局异常拦截器
|
||||
*/
|
||||
@RestControllerAdvice
|
||||
@Slf4j
|
||||
public class GlobalExceptionHandler {
|
||||
// 自定义异常信息
|
||||
@ExceptionHandler(AuthenticSecurityException.class)
|
||||
@ResponseBody
|
||||
public Result<Object> exceptionHandler(AuthenticSecurityException exception) {
|
||||
Integer code = exception.getCode() != null ? exception.getCode() : 500;
|
||||
return Result.error(null, code, exception.getMessage());
|
||||
}
|
||||
|
||||
// 运行时异常信息
|
||||
@ExceptionHandler(RuntimeException.class)
|
||||
@ResponseBody
|
||||
public Result<Object> exceptionHandler(RuntimeException exception) {
|
||||
String message = exception.getMessage();
|
||||
message = StringUtils.hasText(message) ? message : "服务器异常";
|
||||
exception.printStackTrace();
|
||||
|
||||
// 解析异常
|
||||
String jsonParseError = "JSON parse error (.*)";
|
||||
Matcher jsonParseErrorMatcher = Pattern.compile(jsonParseError).matcher(message);
|
||||
if (jsonParseErrorMatcher.find()) {
|
||||
return Result.error(null, 500, "JSON解析异常 " + jsonParseErrorMatcher.group(1));
|
||||
}
|
||||
|
||||
// 数据过大
|
||||
String dataTooLongError = "Data too long for column (.*?) at row 1";
|
||||
Matcher dataTooLongErrorMatcher = Pattern.compile(dataTooLongError).matcher(message);
|
||||
if (dataTooLongErrorMatcher.find()) {
|
||||
return Result.error(null, 500, dataTooLongErrorMatcher.group(1) + " 字段数据过大");
|
||||
}
|
||||
|
||||
// 主键冲突
|
||||
String primaryKeyError = "Duplicate entry '(.*?)' for key .*";
|
||||
Matcher primaryKeyErrorMatcher = Pattern.compile(primaryKeyError).matcher(message);
|
||||
if (primaryKeyErrorMatcher.find()) {
|
||||
return Result.error(null, 500, "[" + primaryKeyErrorMatcher.group(1) + "]已存在");
|
||||
}
|
||||
|
||||
// corn表达式错误
|
||||
String cronExpression = "CronExpression '(.*?)' is invalid";
|
||||
Matcher cronExpressionMatcher = Pattern.compile(cronExpression).matcher(message);
|
||||
if (cronExpressionMatcher.find()) {
|
||||
return Result.error(null, 500, "表达式 " + cronExpressionMatcher.group(1) + " 不合法");
|
||||
}
|
||||
|
||||
log.error("GlobalExceptionHandler===>运行时异常信息:{}", message);
|
||||
return Result.error(null, 500, message);
|
||||
}
|
||||
|
||||
// 表单验证字段
|
||||
@ExceptionHandler(MethodArgumentNotValidException.class)
|
||||
public Result<String> handleValidationExceptions(MethodArgumentNotValidException ex) {
|
||||
String errorMessage = ex.getBindingResult().getFieldErrors().stream()
|
||||
.map(DefaultMessageSourceResolvable::getDefaultMessage)
|
||||
.distinct()
|
||||
.collect(Collectors.joining(", "));
|
||||
return Result.error(null, 201, errorMessage);
|
||||
}
|
||||
|
||||
// 特定异常处理
|
||||
@ExceptionHandler(ArithmeticException.class)
|
||||
@ResponseBody
|
||||
public Result<Object> error(ArithmeticException exception) {
|
||||
log.error("GlobalExceptionHandler===>特定异常信息:{}", exception.getMessage());
|
||||
|
||||
return Result.error(null, 500, exception.getMessage());
|
||||
}
|
||||
|
||||
// 处理SQL异常
|
||||
@ExceptionHandler(SQLIntegrityConstraintViolationException.class)
|
||||
@ResponseBody
|
||||
public Result<String> exceptionHandler(SQLIntegrityConstraintViolationException exception) {
|
||||
log.error("GlobalExceptionHandler===>处理SQL异常:{}", exception.getMessage());
|
||||
|
||||
String message = exception.getMessage();
|
||||
if (message.contains("Duplicate entry")) {
|
||||
// 错误信息
|
||||
return Result.error(ResultCodeEnum.USER_IS_EMPTY);
|
||||
} else {
|
||||
return Result.error(ResultCodeEnum.UNKNOWN_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
// 处理无权访问异常
|
||||
@ExceptionHandler(AccessDeniedException.class)
|
||||
public Result<String> handleAccessDenied(AccessDeniedException exception) {
|
||||
return Result.error(exception.getMessage(), ResultCodeEnum.FAIL_NO_ACCESS_DENIED);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.spring.step3.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.spring.step3.domain.dto.permission.PermissionDto;
|
||||
import com.spring.step3.domain.entity.PermissionEntity;
|
||||
import com.spring.step3.domain.vo.PermissionVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统权限表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@Mapper
|
||||
public interface PermissionMapper extends BaseMapper<PermissionEntity> {
|
||||
|
||||
/**
|
||||
* * 分页查询系统权限表内容
|
||||
*
|
||||
* @param pageParams 系统权限表分页参数
|
||||
* @param dto 系统权限表查询表单
|
||||
* @return 系统权限表分页结果
|
||||
*/
|
||||
IPage<PermissionVo> selectListByPage(@Param("page") Page<PermissionEntity> pageParams, @Param("dto") PermissionDto dto);
|
||||
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
package com.spring.step3.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.spring.step3.domain.dto.role.RoleDto;
|
||||
import com.spring.step3.domain.entity.RoleEntity;
|
||||
import com.spring.step3.domain.vo.RoleVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统角色表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@Mapper
|
||||
public interface RoleMapper extends BaseMapper<RoleEntity> {
|
||||
|
||||
/**
|
||||
* * 分页查询系统角色表内容
|
||||
*
|
||||
* @param pageParams 系统角色表分页参数
|
||||
* @param dto 系统角色表查询表单
|
||||
* @return 系统角色表分页结果
|
||||
*/
|
||||
IPage<RoleVo> selectListByPage(@Param("page") Page<RoleEntity> pageParams, @Param("dto") RoleDto dto);
|
||||
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.spring.step3.mapper;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.spring.step3.domain.dto.role.RolePermissionDto;
|
||||
import com.spring.step3.domain.entity.RolePermissionEntity;
|
||||
import com.spring.step3.domain.vo.RolePermissionVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 角色权限关联表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@Mapper
|
||||
public interface RolePermissionMapper extends BaseMapper<RolePermissionEntity> {
|
||||
|
||||
/**
|
||||
* * 分页查询角色权限关联表内容
|
||||
*
|
||||
* @param pageParams 角色权限关联表分页参数
|
||||
* @param dto 角色权限关联表查询表单
|
||||
* @return 角色权限关联表分页结果
|
||||
*/
|
||||
IPage<RolePermissionVo> selectListByPage(@Param("page") Page<RolePermissionEntity> pageParams, @Param("dto") RolePermissionDto dto);
|
||||
|
||||
/**
|
||||
* 根据角色id获取权限内容
|
||||
*
|
||||
* @param permissionId 权限id
|
||||
* @return 角色权限列表
|
||||
*/
|
||||
List<RolePermissionEntity> selectListByPermissionId(Long permissionId);
|
||||
|
||||
/**
|
||||
* 先删除当前已经分配的角色权限内容
|
||||
*
|
||||
* @param roleId 角色id
|
||||
*/
|
||||
void deleteByRoleId(Long roleId);
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.spring.step3.mapper;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.spring.step3.domain.dto.user.UserDto;
|
||||
import com.spring.step3.domain.entity.PermissionEntity;
|
||||
import com.spring.step3.domain.entity.RoleEntity;
|
||||
import com.spring.step3.domain.entity.UserEntity;
|
||||
import com.spring.step3.domain.vo.UserVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户基本信息表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserMapper extends BaseMapper<UserEntity> {
|
||||
|
||||
/**
|
||||
* * 分页查询用户基本信息表内容
|
||||
*
|
||||
* @param pageParams 用户基本信息表分页参数
|
||||
* @param dto 用户基本信息表查询表单
|
||||
* @return 用户基本信息表分页结果
|
||||
*/
|
||||
IPage<UserVo> selectListByPage(@Param("page") Page<UserEntity> pageParams, @Param("dto") UserDto dto);
|
||||
|
||||
/**
|
||||
* 根据用户id查找当前用户的权限
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 权限列表
|
||||
*/
|
||||
List<PermissionEntity> selectPermissionByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据用户名查询当前用户
|
||||
*
|
||||
* @param username 用户名
|
||||
* @return 用户 {@link UserEntity}
|
||||
*/
|
||||
UserEntity selectByUsername(String username);
|
||||
|
||||
/**
|
||||
* 根据用户id查找该用户的角色内容
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 当前用户的角色信息
|
||||
*/
|
||||
List<RoleEntity> selectRolesByUserId(Long userId);
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.spring.step3.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.spring.step3.domain.dto.user.UserRoleDto;
|
||||
import com.spring.step3.domain.entity.UserRoleEntity;
|
||||
import com.spring.step3.domain.vo.UserRoleVo;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户角色关联表 Mapper 接口
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@Mapper
|
||||
public interface UserRoleMapper extends BaseMapper<UserRoleEntity> {
|
||||
|
||||
/**
|
||||
* * 分页查询用户角色关联表内容
|
||||
*
|
||||
* @param pageParams 用户角色关联表分页参数
|
||||
* @param dto 用户角色关联表查询表单
|
||||
* @return 用户角色关联表分页结果
|
||||
*/
|
||||
IPage<UserRoleVo> selectListByPage(@Param("page") Page<UserRoleEntity> pageParams, @Param("dto") UserRoleDto dto);
|
||||
|
||||
/**
|
||||
* 根据用户id获取当前用户角色列表
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 用户和角色列表
|
||||
*/
|
||||
List<UserRoleEntity> getRoleListByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据用户id删除用户相关分配角色
|
||||
*
|
||||
* @param userId 用户id
|
||||
*/
|
||||
void deleteByUserId(Long userId);
|
||||
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.spring.step3.security.annotation;
|
||||
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@PreAuthorize("hasAnyAuthority({auth})")
|
||||
public @interface HasAnyAuthority {
|
||||
String[] auth();
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package com.spring.step3.security.annotation;
|
||||
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@PreAuthorize("hasAuthority('USER') || hasAuthority('{value}')")
|
||||
public @interface HasUSERAuthorize {
|
||||
String value();
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
package com.spring.step3.security.annotation;
|
||||
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 判断当前是否是Admin用户
|
||||
*/
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@PreAuthorize("hasAuthority('ADMIN')")
|
||||
public @interface IsAdmin {
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package com.spring.step3.security.annotation.programmatically;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component("auth")
|
||||
public class AuthorizationLogic {
|
||||
|
||||
public boolean decide(String name) {
|
||||
System.out.println(name);
|
||||
// 直接使用name的实现
|
||||
return name.equalsIgnoreCase("user");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.spring.step3.security.config;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration
|
||||
// @EnableMethodSecurity(prePostEnabled = false)
|
||||
public class AuthorizationManagerConfiguration {
|
||||
|
||||
// @Bean
|
||||
// @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
// Advisor preAuthorize(PreAuthorizationManager manager) {
|
||||
// return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager);
|
||||
// }
|
||||
//
|
||||
// @Bean
|
||||
// @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
// Advisor postAuthorize(PostAuthorizationManager manager) {
|
||||
// return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager);
|
||||
// }
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
package com.spring.step3.security.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.authorization.method.PrePostTemplateDefaults;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
|
||||
@Configuration
|
||||
public class SecurityConfiguration {
|
||||
|
||||
/**
|
||||
* 注册一个用于Spring Security预授权/后授权的模板元注解默认配置Bean。
|
||||
*
|
||||
* <p>该Bean提供了基于SpEL表达式的权限校验模板,可用于自定义组合注解。</p>
|
||||
*
|
||||
* <h3>典型用法</h3>
|
||||
* <p>通过此配置可以简化自定义权限注解的定义,例如:</p>
|
||||
* <pre>{@code
|
||||
* @Target({ElementType.METHOD, ElementType.TYPE})
|
||||
* @Retention(RetentionPolicy.RUNTIME)
|
||||
* @PreAuthorize("hasAnyAuthority( // 使用模板提供的表达式语法
|
||||
* public @interface HasAnyAuthority {
|
||||
* String[] auth(); // 接收权限列表参数
|
||||
* }
|
||||
* }</pre>
|
||||
*
|
||||
* <h3>注意事项</h3>
|
||||
* <ul>
|
||||
* <li>需要确保Spring Security的预授权功能已启用</li>
|
||||
* <li>模板表达式应符合SpEL语法规范</li>
|
||||
* </ul>
|
||||
*
|
||||
* @return PrePostTemplateDefaults 实例,用于预/后授权注解的默认配置
|
||||
* @see org.springframework.security.access.prepost.PreAuthorize
|
||||
* @see org.springframework.security.access.prepost.PostAuthorize
|
||||
*/
|
||||
@Bean
|
||||
PrePostTemplateDefaults prePostTemplateDefaults() {
|
||||
return new PrePostTemplateDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* 配置密码编码器Bean
|
||||
*
|
||||
* <p>Spring Security提供了多种密码编码器实现,推荐使用BCryptPasswordEncoder作为默认选择。</p>
|
||||
*
|
||||
* <p>特点:</p>
|
||||
* <ul>
|
||||
* <li>BCryptPasswordEncoder - 使用bcrypt强哈希算法,自动加盐,是当前最推荐的密码编码器</li>
|
||||
* <li>Argon2PasswordEncoder - 使用Argon2算法,抗GPU/ASIC攻击,但需要更多内存</li>
|
||||
* <li>SCryptPasswordEncoder - 使用scrypt算法,内存密集型,抗硬件攻击</li>
|
||||
* <li>Pbkdf2PasswordEncoder - 使用PBKDF2算法,较老但广泛支持</li>
|
||||
* </ul>
|
||||
*
|
||||
* <p>注意:不推荐使用MD5等弱哈希算法,Spring官方也不推荐自定义弱密码编码器。</p>
|
||||
*
|
||||
* @return PasswordEncoder 密码编码器实例
|
||||
* @see BCryptPasswordEncoder
|
||||
*/
|
||||
@Bean
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
// 其他编码器示例(根据需求选择一种):
|
||||
// return new Argon2PasswordEncoder(16, 32, 1, 1 << 14, 2);
|
||||
// return new SCryptPasswordEncoder();
|
||||
// return new Pbkdf2PasswordEncoder("secret", 185000, 256);
|
||||
|
||||
// 实际项目中只需返回一个密码编码器
|
||||
return new BCryptPasswordEncoder();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,106 @@
|
|||
package com.spring.step3.security.config;
|
||||
|
||||
import com.spring.step3.security.filter.JwtAuthenticationFilter;
|
||||
import com.spring.step3.security.handler.SecurityAccessDeniedHandler;
|
||||
import com.spring.step3.security.handler.SecurityAuthenticationEntryPoint;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
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.configuration.EnableWebSecurity;
|
||||
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
|
||||
import org.springframework.security.config.http.SessionCreationPolicy;
|
||||
import org.springframework.security.web.SecurityFilterChain;
|
||||
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
|
||||
|
||||
@Configuration
|
||||
@EnableWebSecurity
|
||||
@EnableMethodSecurity(jsr250Enabled = true)
|
||||
@RequiredArgsConstructor
|
||||
public class SecurityWebConfiguration {
|
||||
|
||||
private final JwtAuthenticationFilter jwtAuthenticationFilter;
|
||||
|
||||
// @Bean
|
||||
// SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
// http.authorizeHttpRequests(authorizeRequests ->
|
||||
// // 访问路径为 /api 时需要进行认证
|
||||
// authorizeRequests
|
||||
// // 只认证 /api/** 下的所有接口
|
||||
// .requestMatchers("/api/**").authenticated()
|
||||
// // 其余请求都放行
|
||||
// .anyRequest().permitAll()
|
||||
// )
|
||||
// .formLogin(loginPage -> loginPage
|
||||
// // 自定义登录页路径
|
||||
// .loginPage("/login-page")
|
||||
// // 处理登录的URL(默认就是/login)
|
||||
// .loginProcessingUrl("/login")
|
||||
// // 登录成功跳转
|
||||
// .defaultSuccessUrl("/")
|
||||
// // 登录失败跳转
|
||||
// .failureUrl("/login-page?error=true")
|
||||
// .permitAll()
|
||||
// )
|
||||
// // 使用默认的登录
|
||||
// // .formLogin(Customizer.withDefaults())
|
||||
// // 禁用表单登录
|
||||
// // .formLogin(AbstractHttpConfigurer::disable)
|
||||
// .logout(logout -> logout
|
||||
// .logoutSuccessUrl("/login-page?logout=true")
|
||||
// .permitAll()
|
||||
// )
|
||||
// .csrf(AbstractHttpConfigurer::disable)
|
||||
// .exceptionHandling(exception -> {
|
||||
// // 请求未授权接口
|
||||
// exception.authenticationEntryPoint(new SecurityAuthenticationEntryPoint());
|
||||
// // 没有权限访问
|
||||
// exception.accessDeniedHandler(new SecurityAccessDeniedHandler());
|
||||
// })
|
||||
// ;
|
||||
//
|
||||
// return http.build();
|
||||
// }
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
// 前端段分离不需要---禁用明文验证
|
||||
.httpBasic(AbstractHttpConfigurer::disable)
|
||||
// 前端段分离不需要---禁用默认登录页
|
||||
.formLogin(AbstractHttpConfigurer::disable)
|
||||
// 前端段分离不需要---禁用退出页
|
||||
.logout(AbstractHttpConfigurer::disable)
|
||||
// 前端段分离不需要---csrf攻击
|
||||
.csrf(AbstractHttpConfigurer::disable)
|
||||
// 跨域访问权限,如果需要可以关闭后自己配置跨域访问
|
||||
.cors(AbstractHttpConfigurer::disable)
|
||||
// 前后端分离不需要---因为是无状态的
|
||||
// .sessionManagement(AbstractHttpConfigurer::disable)
|
||||
.sessionManagement(session ->
|
||||
session.sessionCreationPolicy(SessionCreationPolicy.STATELESS)
|
||||
)
|
||||
.authorizeHttpRequests(authorizeRequests ->
|
||||
// 访问路径为 /api 时需要进行认证
|
||||
authorizeRequests
|
||||
// 不认证登录接口
|
||||
.requestMatchers("/*/login", "/api/security/**").permitAll()
|
||||
// 只认证 /api/** 下的所有接口
|
||||
.requestMatchers("/api/**").authenticated()
|
||||
// 其余请求都放行
|
||||
.anyRequest().permitAll()
|
||||
)
|
||||
.exceptionHandling(exception -> {
|
||||
// 请求未授权接口
|
||||
exception.authenticationEntryPoint(new SecurityAuthenticationEntryPoint());
|
||||
// 没有权限访问
|
||||
exception.accessDeniedHandler(new SecurityAccessDeniedHandler());
|
||||
})
|
||||
.addFilterBefore(jwtAuthenticationFilter, UsernamePasswordAuthenticationFilter.class)
|
||||
.addFilter(jwtAuthenticationFilter)
|
||||
;
|
||||
|
||||
return http.build();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package com.spring.step3.security.event;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.security.authorization.AuthorizationDecision;
|
||||
import org.springframework.security.authorization.event.AuthorizationDeniedEvent;
|
||||
import org.springframework.security.authorization.event.AuthorizationGrantedEvent;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
@Slf4j
|
||||
@Component
|
||||
public class AuthenticationEvents {
|
||||
|
||||
/**
|
||||
* 监听拒绝授权内容
|
||||
*
|
||||
* @param failure 授权失败
|
||||
*/
|
||||
@EventListener
|
||||
public void onFailure(AuthorizationDeniedEvent<MethodInvocation> failure) {
|
||||
try {
|
||||
// getSource 和 getObject意思一样,一种是传入泛型自动转换一种是要手动转换
|
||||
Object source = failure.getSource();
|
||||
|
||||
// 直接获取泛型对象
|
||||
MethodInvocation methodInvocation = failure.getObject();
|
||||
Method method = methodInvocation.getMethod();
|
||||
Object[] args = methodInvocation.getArguments();
|
||||
|
||||
log.warn("方法调用被拒绝: {}.{}, 参数: {}",
|
||||
method.getDeclaringClass().getSimpleName(),
|
||||
method.getName(),
|
||||
Arrays.toString(args));
|
||||
|
||||
// 这里面的信息,和接口 /api/security/current-user 内容一样
|
||||
Authentication authentication = failure.getAuthentication().get();
|
||||
|
||||
AuthorizationDecision authorizationDecision = failure.getAuthorizationDecision();
|
||||
// ExpressionAuthorizationDecision [granted=false, expressionAttribute=hasAuthority('ADMIN')]
|
||||
System.out.println(authorizationDecision);
|
||||
|
||||
log.warn("授权失败 - 用户: {}, 权限: {}", authentication.getName(), authorizationDecision);
|
||||
} catch (Exception e) {
|
||||
log.info(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 监听授权的内容
|
||||
* 如果要监听授权成功的内容,这个内容可能相当的多,毕竟正常情况授权成功的内容还是比较多的。
|
||||
* 既然内容很多又要监听,如果真的需要,一定要处理好业务逻辑,不要被成功的消息淹没。
|
||||
*
|
||||
* @param success 授权成功
|
||||
*/
|
||||
@EventListener
|
||||
public void onSuccess(AuthorizationGrantedEvent<MethodInvocation> success) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package com.spring.step3.security.event;
|
||||
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.security.authorization.AuthorizationEventPublisher;
|
||||
import org.springframework.security.authorization.SpringAuthorizationEventPublisher;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 如果要监听授权和拒绝的授权需要发布一个像下面这样的事件
|
||||
* 之后使用 Spring 的 @EventListener
|
||||
*/
|
||||
@Component
|
||||
public class SecurityAuthorizationPublisher {
|
||||
|
||||
@Bean
|
||||
public AuthorizationEventPublisher authorizationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
|
||||
return new SpringAuthorizationEventPublisher(applicationEventPublisher);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,10 +1,10 @@
|
|||
package com.spring.step2.security.filter;
|
||||
package com.spring.step3.security.filter;
|
||||
|
||||
import com.spring.step2.config.context.BaseContext;
|
||||
import com.spring.step2.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step2.exception.SecurityException;
|
||||
import com.spring.step2.security.service.DbUserDetailService;
|
||||
import com.spring.step2.security.service.JwtBearTokenService;
|
||||
import com.spring.step3.config.context.BaseContext;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step3.exception.AuthenticSecurityException;
|
||||
import com.spring.step3.security.service.DbUserDetailService;
|
||||
import com.spring.step3.security.service.JwtBearTokenService;
|
||||
import jakarta.servlet.FilterChain;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
|
@ -47,7 +47,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter {
|
|||
|
||||
// 检查当前Token是否过期
|
||||
if (jwtBearTokenService.isTokenValid(jwtToken)) {
|
||||
throw new SecurityException(ResultCodeEnum.AUTHENTICATION_EXPIRED);
|
||||
throw new AuthenticSecurityException(ResultCodeEnum.AUTHENTICATION_EXPIRED);
|
||||
}
|
||||
|
||||
// 解析当前Token中的用户名
|
|
@ -1,9 +1,9 @@
|
|||
package com.spring.step2.security.handler;
|
||||
package com.spring.step3.security.handler;
|
||||
|
||||
import com.spring.step2.domain.vo.result.Result;
|
||||
import com.spring.step2.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step2.security.service.JwtBearTokenService;
|
||||
import com.spring.step2.utils.ResponseUtil;
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step3.security.service.JwtBearTokenService;
|
||||
import com.spring.step3.utils.ResponseUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.RequiredArgsConstructor;
|
|
@ -0,0 +1,26 @@
|
|||
package com.spring.step3.security.handler;
|
||||
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step3.utils.ResponseUtil;
|
||||
import jakarta.servlet.ServletException;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.AccessDeniedException;
|
||||
import org.springframework.security.web.access.AccessDeniedHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Slf4j
|
||||
public class SecurityAccessDeniedHandler implements AccessDeniedHandler {
|
||||
|
||||
@Override
|
||||
public void handle(HttpServletRequest request, HttpServletResponse response, AccessDeniedException accessDeniedException) throws IOException, ServletException {
|
||||
log.error("SecurityAccessDeniedHandler:{}", accessDeniedException.getLocalizedMessage());
|
||||
|
||||
// 无权访问接口
|
||||
Result<Object> result = Result.error(accessDeniedException.getMessage(), ResultCodeEnum.LOGIN_AUTH);
|
||||
ResponseUtil.out(response, result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package com.spring.step3.security.handler;
|
||||
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step3.utils.ResponseUtil;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.core.AuthenticationException;
|
||||
import org.springframework.security.web.AuthenticationEntryPoint;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@Slf4j
|
||||
public class SecurityAuthenticationEntryPoint implements AuthenticationEntryPoint {
|
||||
|
||||
@Override
|
||||
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException authException) throws IOException {
|
||||
log.error("SecurityAuthenticationEntryPoint:{}", authException.getLocalizedMessage());
|
||||
|
||||
// 未认证---未登录
|
||||
Result<Object> result = Result.error(authException.getMessage(), ResultCodeEnum.LOGIN_AUTH);
|
||||
ResponseUtil.out(response, result);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package com.spring.step3.security.manger;
|
||||
|
||||
/**
|
||||
* 处理方法调用后的授权检查
|
||||
* check()方法接收的是MethodInvocationResult对象,包含已执行方法的结果
|
||||
* 用于决定是否允许返回某个方法的结果(后置过滤)
|
||||
* 这是Spring Security较新的"后置授权"功能
|
||||
*/
|
||||
// @Component
|
||||
// public class PostAuthorizationManager implements AuthorizationManager<MethodInvocationResult> {
|
||||
//
|
||||
// /**
|
||||
// * 这里两个实现方法按照Security官方要求进行实现
|
||||
// * <h4>类说明:</h4>
|
||||
// * 下面的实现是对方法执行前进行权限校验的判断
|
||||
// * <pre>
|
||||
// * <code>AuthorizationManager <MethodInvocation></code>
|
||||
// * </pre>
|
||||
// * 下面的这个是对方法执行后对权限的判断
|
||||
// * <pre>
|
||||
// * <code>AuthorizationManager <MethodInvocationResult></code>
|
||||
// * </pre>
|
||||
// *
|
||||
// * <h4>注意事项:</h4>
|
||||
// * 将上述两个方法按照自定义的方式进行实现后,还需要禁用默认的。
|
||||
// * <pre>
|
||||
// * @Configuration
|
||||
// * @EnableMethodSecurity(prePostEnabled = false)
|
||||
// * class MethodSecurityConfig {
|
||||
// * @Bean
|
||||
// * @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
// * Advisor preAuthorize(MyAuthorizationManager manager) {
|
||||
// * return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager);
|
||||
// * }
|
||||
// *
|
||||
// * @Bean
|
||||
// * @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
// * Advisor postAuthorize(MyAuthorizationManager manager) {
|
||||
// * return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager);
|
||||
// * }
|
||||
// * }
|
||||
// * </pre>
|
||||
// */
|
||||
// @Override
|
||||
// public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocationResult invocation) {
|
||||
// return new AuthorizationDecision(true);
|
||||
// }
|
||||
// }
|
|
@ -0,0 +1,49 @@
|
|||
package com.spring.step3.security.manger;
|
||||
|
||||
/**
|
||||
* 处理方法调用前的授权检查
|
||||
* check()方法接收的是MethodInvocation对象,包含即将执行的方法调用信息
|
||||
* 用于决定是否允许执行某个方法
|
||||
* 这是传统的"前置授权"模式
|
||||
*/
|
||||
// @Component
|
||||
// public class PreAuthorizationManager implements AuthorizationManager<MethodInvocation> {
|
||||
//
|
||||
// /**
|
||||
// * 这里两个实现方法按照Security官方要求进行实现
|
||||
// * <h4>类说明:</h4>
|
||||
// * 下面的实现是对方法执行前进行权限校验的判断
|
||||
// * <pre>
|
||||
// * <code>AuthorizationManager <MethodInvocation></code>
|
||||
// * </pre>
|
||||
// * 下面的这个是对方法执行后对权限的判断
|
||||
// * <pre>
|
||||
// * <code>AuthorizationManager <MethodInvocationResult></code>
|
||||
// * </pre>
|
||||
// *
|
||||
// * <h4>注意事项:</h4>
|
||||
// * 将上述两个方法按照自定义的方式进行实现后,还需要禁用默认的。
|
||||
// * <pre>
|
||||
// * @Configuration
|
||||
// * @EnableMethodSecurity(prePostEnabled = false)
|
||||
// * class MethodSecurityConfig {
|
||||
// * @Bean
|
||||
// * @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
// * Advisor preAuthorize(MyAuthorizationManager manager) {
|
||||
// * return AuthorizationManagerBeforeMethodInterceptor.preAuthorize(manager);
|
||||
// * }
|
||||
// *
|
||||
// * @Bean
|
||||
// * @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
|
||||
// * Advisor postAuthorize(MyAuthorizationManager manager) {
|
||||
// * return AuthorizationManagerAfterMethodInterceptor.postAuthorize(manager);
|
||||
// * }
|
||||
// * }
|
||||
// * </pre>
|
||||
// */
|
||||
// @Override
|
||||
// public AuthorizationDecision check(Supplier<Authentication> authentication, MethodInvocation invocation) {
|
||||
// return new AuthorizationDecision(true);
|
||||
// }
|
||||
//
|
||||
// }
|
|
@ -0,0 +1 @@
|
|||
如果需要重写验证逻辑(自定义)使用这里面的类,并在配置类`AuthorizationManagerConfiguration`解开注释,
|
|
@ -0,0 +1,52 @@
|
|||
package com.spring.step3.security.password;
|
||||
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.util.DigestUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.HexFormat;
|
||||
|
||||
/**
|
||||
* <h1>MD5密码编码器实现</h1>
|
||||
*
|
||||
* <strong>安全警告:</strong>此类使用MD5算法进行密码哈希,已不再安全,不推荐用于生产环境。
|
||||
*
|
||||
* <p>MD5算法因其计算速度快且易受彩虹表攻击而被认为不安全。即使密码哈希本身是单向的,
|
||||
* 但现代计算能力使得暴力破解和预先计算的彩虹表攻击变得可行。</p>
|
||||
*
|
||||
* <p>Spring Security推荐使用BCrypt、PBKDF2、Argon2或Scrypt等自适应单向函数替代MD5。</p>
|
||||
*
|
||||
* @see PasswordEncoder
|
||||
* 一般仅用于遗留系统兼容,新系统应使用更安全的密码编码器
|
||||
*/
|
||||
public class MD5PasswordEncoder implements PasswordEncoder {
|
||||
|
||||
@Override
|
||||
public String encode(CharSequence rawPassword) {
|
||||
if (rawPassword == null) {
|
||||
throw new IllegalArgumentException("原始密码不能为null");
|
||||
}
|
||||
|
||||
byte[] md5Digest = DigestUtils.md5Digest(rawPassword.toString().getBytes());
|
||||
return HexFormat.of().formatHex(md5Digest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(CharSequence rawPassword, String encodedPassword) {
|
||||
if (rawPassword == null) {
|
||||
throw new IllegalArgumentException("原始密码不能为null");
|
||||
}
|
||||
|
||||
if (!StringUtils.hasText(encodedPassword)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return encodedPassword.equalsIgnoreCase(encode(rawPassword));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean upgradeEncoding(String encodedPassword) {
|
||||
// MD5已不安全,始终返回true建议升级到更安全的算法
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
package com.spring.step3.security.service;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.spring.step3.domain.entity.PermissionEntity;
|
||||
import com.spring.step3.domain.entity.RoleEntity;
|
||||
import com.spring.step3.domain.entity.UserEntity;
|
||||
import com.spring.step3.mapper.UserMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.security.core.userdetails.UserDetailsService;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@DS("testJwt")
|
||||
@Service
|
||||
@Transactional
|
||||
@RequiredArgsConstructor
|
||||
public class DbUserDetailService implements UserDetailsService {
|
||||
|
||||
private final UserMapper userMapper;
|
||||
|
||||
@Override
|
||||
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
// 查询当前用户
|
||||
UserEntity userEntity = userMapper.selectByUsername(username);
|
||||
|
||||
// 判断当前用户是否存在
|
||||
if (userEntity == null) {
|
||||
throw new UsernameNotFoundException("用户不存在");
|
||||
}
|
||||
|
||||
Long userId = userEntity.getId();
|
||||
|
||||
List<String> list = new ArrayList<>();
|
||||
// 设置用户角色
|
||||
List<String> roles = findUserRolesByUserId(userId);
|
||||
// 设置用户权限
|
||||
List<String> permissions = findPermissionByUserId(userId);
|
||||
list.addAll(roles);
|
||||
list.addAll(permissions);
|
||||
|
||||
Set<SimpleGrantedAuthority> authorities = list.stream().map(SimpleGrantedAuthority::new)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// 设置用户权限
|
||||
userEntity.setAuthorities(authorities);
|
||||
// 返回时将用户密码置为空
|
||||
userEntity.setPassword(null);
|
||||
return userEntity;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id查找该用户的角色内容
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 当前用户的角色信息
|
||||
*/
|
||||
public List<String> findUserRolesByUserId(Long userId) {
|
||||
List<RoleEntity> roleList = userMapper.selectRolesByUserId(userId);
|
||||
return roleList.stream().map(RoleEntity::getRoleCode).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id查找该用户的权限内容
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 当前用户的权限信息
|
||||
*/
|
||||
public List<String> findPermissionByUserId(Long userId) {
|
||||
List<PermissionEntity> permissionList = userMapper.selectPermissionByUserId(userId);
|
||||
return permissionList.stream().map(PermissionEntity::getPermissionCode).toList();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
package com.spring.step3.security.service;
|
||||
|
||||
// @Service
|
||||
// @RequiredArgsConstructor
|
||||
// public class InMemoryUserDetailsService implements UserDetailsService {
|
||||
//
|
||||
// private final PasswordEncoder passwordEncoder;
|
||||
//
|
||||
// @Override
|
||||
// public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
|
||||
// // 1. 这里应该根据username从数据库或其他存储中查询用户信息
|
||||
// // 以下是模拟数据,实际应用中应从数据库查询
|
||||
//
|
||||
// // 2. 如果用户不存在,抛出UsernameNotFoundException
|
||||
// if (!"bunny".equalsIgnoreCase(username)) {
|
||||
// throw new UsernameNotFoundException("User not found: " + username);
|
||||
// }
|
||||
//
|
||||
// // 3. 构建UserDetails对象返回
|
||||
// return User.builder()
|
||||
// .username(username) // 使用传入的用户名
|
||||
// .password(passwordEncoder.encode("123456")) // 密码应该已经加密存储,这里仅为示例
|
||||
// .roles("USER") // 角色会自动添加ROLE_前缀
|
||||
// .authorities("read", "write") // 添加具体权限
|
||||
// .build();
|
||||
// }
|
||||
// }
|
|
@ -1,6 +1,6 @@
|
|||
package com.spring.step2.security.service;
|
||||
package com.spring.step3.security.service;
|
||||
|
||||
import com.spring.step2.utils.JwtTokenUtil;
|
||||
import com.spring.step3.utils.JwtTokenUtil;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Configuration;
|
|
@ -0,0 +1,58 @@
|
|||
package com.spring.step3.service.roles;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.spring.step3.domain.dto.permission.PermissionDto;
|
||||
import com.spring.step3.domain.entity.PermissionEntity;
|
||||
import com.spring.step3.domain.vo.PermissionVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统权限表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
public interface PermissionService extends IService<PermissionEntity> {
|
||||
|
||||
/**
|
||||
* 分页查询系统权限表
|
||||
*
|
||||
* @return {@link PermissionVo}
|
||||
*/
|
||||
PageResult<PermissionVo> getPermissionPage(Page<PermissionEntity> pageParams, PermissionDto dto);
|
||||
|
||||
/**
|
||||
* 添加系统权限表
|
||||
*
|
||||
* @param dto {@link PermissionDto} 添加表单
|
||||
*/
|
||||
void addPermission(PermissionDto dto);
|
||||
|
||||
/**
|
||||
* 更新系统权限表
|
||||
*
|
||||
* @param dto {@link PermissionDto} 更新表单
|
||||
*/
|
||||
void updatePermission(PermissionDto dto);
|
||||
|
||||
/**
|
||||
* 删除|批量删除系统权限表类型
|
||||
*
|
||||
* @param ids 删除id列表
|
||||
*/
|
||||
void deletePermission(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获取所有的权限列表
|
||||
*
|
||||
* @return 所有权限列表
|
||||
*/
|
||||
List<PermissionVo> getAllPermission();
|
||||
|
||||
}
|
|
@ -0,0 +1,67 @@
|
|||
package com.spring.step3.service.roles;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.spring.step3.domain.dto.role.AssignRolePermissionDto;
|
||||
import com.spring.step3.domain.dto.role.RolePermissionDto;
|
||||
import com.spring.step3.domain.entity.RolePermissionEntity;
|
||||
import com.spring.step3.domain.vo.RolePermissionVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 角色权限关联表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
public interface RolePermissionService extends IService<RolePermissionEntity> {
|
||||
|
||||
/**
|
||||
* 分页查询角色权限关联表
|
||||
*
|
||||
* @return {@link RolePermissionVo}
|
||||
*/
|
||||
PageResult<RolePermissionVo> getRolePermissionPage(Page<RolePermissionEntity> pageParams, RolePermissionDto dto);
|
||||
|
||||
/**
|
||||
* 添加角色权限关联表
|
||||
*
|
||||
* @param dto {@link RolePermissionDto} 添加表单
|
||||
*/
|
||||
void addRolePermission(RolePermissionDto dto);
|
||||
|
||||
/**
|
||||
* 更新角色权限关联表
|
||||
*
|
||||
* @param dto {@link RolePermissionDto} 更新表单
|
||||
*/
|
||||
void updateRolePermission(RolePermissionDto dto);
|
||||
|
||||
/**
|
||||
* 删除|批量删除角色权限关联表类型
|
||||
*
|
||||
* @param ids 删除id列表
|
||||
*/
|
||||
void deleteRolePermission(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 根据角色id获取权限内容
|
||||
*
|
||||
* @param permissionId 权限id
|
||||
* @return 角色权限列表
|
||||
*/
|
||||
List<RolePermissionVo> getRolePermissionById(Long permissionId);
|
||||
|
||||
/**
|
||||
* 根据角色id分配权限
|
||||
*
|
||||
* @param dto 为角色分配权限 {@link AssignRolePermissionDto}
|
||||
*/
|
||||
void assignRolePermission(@Valid AssignRolePermissionDto dto);
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
package com.spring.step3.service.roles;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.spring.step3.domain.dto.role.RoleDto;
|
||||
import com.spring.step3.domain.entity.RoleEntity;
|
||||
import com.spring.step3.domain.vo.RoleVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统角色表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
public interface RoleService extends IService<RoleEntity> {
|
||||
|
||||
/**
|
||||
* 分页查询系统角色表
|
||||
*
|
||||
* @return {@link RoleVo}
|
||||
*/
|
||||
PageResult<RoleVo> getRolePage(Page<RoleEntity> pageParams, RoleDto dto);
|
||||
|
||||
/**
|
||||
* 添加系统角色表
|
||||
*
|
||||
* @param dto {@link RoleDto} 添加表单
|
||||
*/
|
||||
void addRole(RoleDto dto);
|
||||
|
||||
/**
|
||||
* 更新系统角色表
|
||||
*
|
||||
* @param dto {@link RoleDto} 更新表单
|
||||
*/
|
||||
void updateRole(RoleDto dto);
|
||||
|
||||
/**
|
||||
* 删除|批量删除系统角色表类型
|
||||
*
|
||||
* @param ids 删除id列表
|
||||
*/
|
||||
void deleteRole(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 获取全部角色列表
|
||||
*
|
||||
* @return 角色列表
|
||||
*/
|
||||
List<RoleVo> getRoleList();
|
||||
|
||||
}
|
|
@ -0,0 +1,102 @@
|
|||
package com.spring.step3.service.roles.impl;
|
||||
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.spring.step3.domain.dto.permission.PermissionDto;
|
||||
import com.spring.step3.domain.entity.PermissionEntity;
|
||||
import com.spring.step3.domain.vo.PermissionVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import com.spring.step3.mapper.PermissionMapper;
|
||||
import com.spring.step3.service.roles.PermissionService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统权限表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@DS("testJwt")
|
||||
@Service
|
||||
@Transactional
|
||||
@RequiredArgsConstructor
|
||||
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, PermissionEntity> implements PermissionService {
|
||||
|
||||
/**
|
||||
* * 系统权限表 服务实现类
|
||||
*
|
||||
* @param pageParams 系统权限表分页查询page对象
|
||||
* @param dto 系统权限表分页查询对象
|
||||
* @return 查询分页系统权限表返回对象
|
||||
*/
|
||||
@Override
|
||||
public PageResult<PermissionVo> getPermissionPage(Page<PermissionEntity> pageParams, PermissionDto dto) {
|
||||
IPage<PermissionVo> page = baseMapper.selectListByPage(pageParams, dto);
|
||||
|
||||
return PageResult.<PermissionVo>builder()
|
||||
.list(page.getRecords())
|
||||
.pageNo(page.getCurrent())
|
||||
.pageSize(page.getSize())
|
||||
.pages(page.getPages())
|
||||
.total(page.getTotal())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加系统权限表
|
||||
*
|
||||
* @param dto 系统权限表添加
|
||||
*/
|
||||
@Override
|
||||
public void addPermission(PermissionDto dto) {
|
||||
PermissionEntity permission = new PermissionEntity();
|
||||
BeanUtils.copyProperties(dto, permission);
|
||||
save(permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新系统权限表
|
||||
*
|
||||
* @param dto 系统权限表更新
|
||||
*/
|
||||
@Override
|
||||
public void updatePermission(PermissionDto dto) {
|
||||
PermissionEntity permission = new PermissionEntity();
|
||||
BeanUtils.copyProperties(dto, permission);
|
||||
updateById(permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除|批量删除系统权限表
|
||||
*
|
||||
* @param ids 删除id列表
|
||||
*/
|
||||
@Override
|
||||
public void deletePermission(List<Long> ids) {
|
||||
removeByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有的权限列表
|
||||
*
|
||||
* @return 所有权限列表
|
||||
*/
|
||||
@Override
|
||||
public List<PermissionVo> getAllPermission() {
|
||||
return list().stream().map(permissionEntity -> {
|
||||
PermissionVo permissionVo = new PermissionVo();
|
||||
BeanUtils.copyProperties(permissionEntity, permissionVo);
|
||||
return permissionVo;
|
||||
}).toList();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
package com.spring.step3.service.roles.impl;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.spring.step3.domain.dto.role.AssignRolePermissionDto;
|
||||
import com.spring.step3.domain.dto.role.RolePermissionDto;
|
||||
import com.spring.step3.domain.entity.RolePermissionEntity;
|
||||
import com.spring.step3.domain.vo.RolePermissionVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import com.spring.step3.mapper.RolePermissionMapper;
|
||||
import com.spring.step3.service.roles.RolePermissionService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 角色权限关联表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@DS("testJwt")
|
||||
@Service
|
||||
@Transactional
|
||||
@RequiredArgsConstructor
|
||||
public class RolePermissionServiceImpl extends ServiceImpl<RolePermissionMapper, RolePermissionEntity> implements RolePermissionService {
|
||||
|
||||
/**
|
||||
* * 角色权限关联表 服务实现类
|
||||
*
|
||||
* @param pageParams 角色权限关联表分页查询page对象
|
||||
* @param dto 角色权限关联表分页查询对象
|
||||
* @return 查询分页角色权限关联表返回对象
|
||||
*/
|
||||
@Override
|
||||
public PageResult<RolePermissionVo> getRolePermissionPage(Page<RolePermissionEntity> pageParams, RolePermissionDto dto) {
|
||||
IPage<RolePermissionVo> page = baseMapper.selectListByPage(pageParams, dto);
|
||||
|
||||
return PageResult.<RolePermissionVo>builder()
|
||||
.list(page.getRecords())
|
||||
.pageNo(page.getCurrent())
|
||||
.pageSize(page.getSize())
|
||||
.pages(page.getPages())
|
||||
.total(page.getTotal())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加角色权限关联表
|
||||
*
|
||||
* @param dto 角色权限关联表添加
|
||||
*/
|
||||
@Override
|
||||
public void addRolePermission(RolePermissionDto dto) {
|
||||
RolePermissionEntity rolePermission = new RolePermissionEntity();
|
||||
BeanUtils.copyProperties(dto, rolePermission);
|
||||
save(rolePermission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新角色权限关联表
|
||||
*
|
||||
* @param dto 角色权限关联表更新
|
||||
*/
|
||||
@Override
|
||||
public void updateRolePermission(RolePermissionDto dto) {
|
||||
RolePermissionEntity rolePermission = new RolePermissionEntity();
|
||||
BeanUtils.copyProperties(dto, rolePermission);
|
||||
updateById(rolePermission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除|批量删除角色权限关联表
|
||||
*
|
||||
* @param ids 删除id列表
|
||||
*/
|
||||
@Override
|
||||
public void deleteRolePermission(List<Long> ids) {
|
||||
removeByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色id获取权限内容
|
||||
*
|
||||
* @param permissionId 权限id
|
||||
* @return 角色权限列表
|
||||
*/
|
||||
@Override
|
||||
public List<RolePermissionVo> getRolePermissionById(Long permissionId) {
|
||||
List<RolePermissionEntity> list = baseMapper.selectListByPermissionId(permissionId);
|
||||
|
||||
return list.stream().map(rolePermissionEntity -> {
|
||||
RolePermissionVo rolePermissionVo = new RolePermissionVo();
|
||||
BeanUtils.copyProperties(rolePermissionEntity, rolePermissionVo);
|
||||
return rolePermissionVo;
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据角色id分配权限
|
||||
*
|
||||
* @param dto 为角色分配权限 {@link AssignRolePermissionDto}
|
||||
*/
|
||||
@Override
|
||||
public void assignRolePermission(AssignRolePermissionDto dto) {
|
||||
Long roleId = dto.getRoleId();
|
||||
List<Long> permissionIds = dto.getPermissionIds();
|
||||
|
||||
// 先删除当前已经分配的角色权限内容
|
||||
baseMapper.deleteByRoleId(roleId);
|
||||
|
||||
List<RolePermissionEntity> rolePermissionEntityList = permissionIds.stream().map(permissionId -> {
|
||||
RolePermissionEntity rolePermissionEntity = new RolePermissionEntity();
|
||||
rolePermissionEntity.setRoleId(roleId);
|
||||
rolePermissionEntity.setPermissionId(permissionId);
|
||||
return rolePermissionEntity;
|
||||
}).toList();
|
||||
|
||||
saveBatch(rolePermissionEntityList);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,104 @@
|
|||
package com.spring.step3.service.roles.impl;
|
||||
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.spring.step3.domain.dto.role.RoleDto;
|
||||
import com.spring.step3.domain.entity.RoleEntity;
|
||||
import com.spring.step3.domain.vo.RoleVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import com.spring.step3.mapper.RoleMapper;
|
||||
import com.spring.step3.service.roles.RoleService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 系统角色表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@DS("testJwt")
|
||||
@Service
|
||||
@Transactional
|
||||
@RequiredArgsConstructor
|
||||
public class RoleServiceImpl extends ServiceImpl<RoleMapper, RoleEntity> implements RoleService {
|
||||
|
||||
/**
|
||||
* * 系统角色表 服务实现类
|
||||
*
|
||||
* @param pageParams 系统角色表分页查询page对象
|
||||
* @param dto 系统角色表分页查询对象
|
||||
* @return 查询分页系统角色表返回对象
|
||||
*/
|
||||
@Override
|
||||
public PageResult<RoleVo> getRolePage(Page<RoleEntity> pageParams, RoleDto dto) {
|
||||
IPage<RoleVo> page = baseMapper.selectListByPage(pageParams, dto);
|
||||
|
||||
return PageResult.<RoleVo>builder()
|
||||
.list(page.getRecords())
|
||||
.pageNo(page.getCurrent())
|
||||
.pageSize(page.getSize())
|
||||
.pages(page.getPages())
|
||||
.total(page.getTotal())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加系统角色表
|
||||
*
|
||||
* @param dto 系统角色表添加
|
||||
*/
|
||||
@Override
|
||||
public void addRole(RoleDto dto) {
|
||||
RoleEntity role = new RoleEntity();
|
||||
BeanUtils.copyProperties(dto, role);
|
||||
save(role);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新系统角色表
|
||||
*
|
||||
* @param dto 系统角色表更新
|
||||
*/
|
||||
@Override
|
||||
public void updateRole(RoleDto dto) {
|
||||
RoleEntity role = new RoleEntity();
|
||||
BeanUtils.copyProperties(dto, role);
|
||||
updateById(role);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除|批量删除系统角色表
|
||||
*
|
||||
* @param ids 删除id列表
|
||||
*/
|
||||
@Override
|
||||
public void deleteRole(List<Long> ids) {
|
||||
removeByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全部角色列表
|
||||
*
|
||||
* @return 角色列表
|
||||
*/
|
||||
@Override
|
||||
public List<RoleVo> getRoleList() {
|
||||
return list().stream()
|
||||
.map(roleEntity -> {
|
||||
RoleVo roleVo = new RoleVo();
|
||||
BeanUtils.copyProperties(roleEntity, roleVo);
|
||||
return roleVo;
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
package com.spring.step2.service.user;
|
||||
package com.spring.step3.service.user;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.spring.step2.domain.dto.LoginDto;
|
||||
import com.spring.step2.domain.entity.UserEntity;
|
||||
import com.spring.step2.domain.vo.LoginVo;
|
||||
import com.spring.step3.domain.dto.LoginDto;
|
||||
import com.spring.step3.domain.entity.UserEntity;
|
||||
import com.spring.step3.domain.vo.LoginVo;
|
||||
|
||||
public interface LoginService extends IService<UserEntity> {
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
package com.spring.step3.service.user;
|
||||
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.spring.step3.domain.dto.user.AssignUserRoleDto;
|
||||
import com.spring.step3.domain.dto.user.UserRoleDto;
|
||||
import com.spring.step3.domain.entity.UserRoleEntity;
|
||||
import com.spring.step3.domain.vo.UserRoleVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import jakarta.validation.Valid;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户角色关联表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
public interface UserRoleService extends IService<UserRoleEntity> {
|
||||
|
||||
/**
|
||||
* 分页查询用户角色关联表
|
||||
*
|
||||
* @return {@link UserRoleVo}
|
||||
*/
|
||||
PageResult<UserRoleVo> getUserRolePage(Page<UserRoleEntity> pageParams, UserRoleDto dto);
|
||||
|
||||
/**
|
||||
* 添加用户角色关联表
|
||||
*
|
||||
* @param dto {@link UserRoleDto} 添加表单
|
||||
*/
|
||||
void addUserRole(UserRoleDto dto);
|
||||
|
||||
/**
|
||||
* 更新用户角色关联表
|
||||
*
|
||||
* @param dto {@link UserRoleDto} 更新表单
|
||||
*/
|
||||
void updateUserRole(UserRoleDto dto);
|
||||
|
||||
/**
|
||||
* 删除|批量删除用户角色关联表类型
|
||||
*
|
||||
* @param ids 删除id列表
|
||||
*/
|
||||
void deleteUserRole(List<Long> ids);
|
||||
|
||||
/**
|
||||
* 根据用户id获取当前用户角色列表
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 用户和角色列表
|
||||
*/
|
||||
List<UserRoleVo> getRoleListByUserId(Long userId);
|
||||
|
||||
/**
|
||||
* 根据用户id分配用户角色
|
||||
*
|
||||
* @param dto 用户分配角色DTO {@link AssignUserRoleDto}
|
||||
*/
|
||||
void assignUserRole(@Valid AssignUserRoleDto dto);
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
package com.spring.step3.service.user;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.IService;
|
||||
import com.spring.step3.domain.dto.user.UserDto;
|
||||
import com.spring.step3.domain.entity.UserEntity;
|
||||
import com.spring.step3.domain.vo.UserVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户基本信息表 服务类
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
public interface UserService extends IService<UserEntity> {
|
||||
|
||||
/**
|
||||
* 分页查询用户基本信息表
|
||||
*
|
||||
* @return {@link UserVo}
|
||||
*/
|
||||
PageResult<UserVo> getUserPage(Page<UserEntity> pageParams, UserDto dto);
|
||||
|
||||
/**
|
||||
* 添加用户基本信息表
|
||||
*
|
||||
* @param dto {@link UserDto} 添加表单
|
||||
*/
|
||||
void addUser(UserDto dto);
|
||||
|
||||
/**
|
||||
* 更新用户基本信息表
|
||||
*
|
||||
* @param dto {@link UserDto} 更新表单
|
||||
*/
|
||||
void updateUser(UserDto dto);
|
||||
|
||||
/**
|
||||
* 删除|批量删除用户基本信息表类型
|
||||
*
|
||||
* @param ids 删除id列表
|
||||
*/
|
||||
void deleteUser(List<Long> ids);
|
||||
}
|
|
@ -1,19 +1,19 @@
|
|||
package com.spring.step2.service.user.impl;
|
||||
package com.spring.step3.service.user.impl;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.spring.step2.domain.dto.LoginDto;
|
||||
import com.spring.step2.domain.entity.UserEntity;
|
||||
import com.spring.step2.domain.enums.LoginEnums;
|
||||
import com.spring.step2.domain.vo.LoginVo;
|
||||
import com.spring.step2.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step2.mapper.UserMapper;
|
||||
import com.spring.step2.security.service.DbUserDetailService;
|
||||
import com.spring.step2.security.service.JwtBearTokenService;
|
||||
import com.spring.step2.service.user.LoginService;
|
||||
import com.spring.step2.service.user.strategy.DefaultLoginStrategy;
|
||||
import com.spring.step2.service.user.strategy.LoginContext;
|
||||
import com.spring.step2.service.user.strategy.LoginStrategy;
|
||||
import com.spring.step3.domain.dto.LoginDto;
|
||||
import com.spring.step3.domain.entity.UserEntity;
|
||||
import com.spring.step3.domain.enums.LoginEnums;
|
||||
import com.spring.step3.domain.vo.LoginVo;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step3.mapper.UserMapper;
|
||||
import com.spring.step3.security.service.DbUserDetailService;
|
||||
import com.spring.step3.security.service.JwtBearTokenService;
|
||||
import com.spring.step3.service.user.LoginService;
|
||||
import com.spring.step3.service.user.strategy.DefaultLoginStrategy;
|
||||
import com.spring.step3.service.user.strategy.LoginContext;
|
||||
import com.spring.step3.service.user.strategy.LoginStrategy;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
|
@ -0,0 +1,128 @@
|
|||
package com.spring.step3.service.user.impl;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.spring.step3.domain.dto.user.AssignUserRoleDto;
|
||||
import com.spring.step3.domain.dto.user.UserRoleDto;
|
||||
import com.spring.step3.domain.entity.UserRoleEntity;
|
||||
import com.spring.step3.domain.vo.UserRoleVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import com.spring.step3.mapper.UserRoleMapper;
|
||||
import com.spring.step3.service.user.UserRoleService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户角色关联表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@DS("testJwt")
|
||||
@Service
|
||||
@Transactional
|
||||
@RequiredArgsConstructor
|
||||
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRoleEntity> implements UserRoleService {
|
||||
|
||||
/**
|
||||
* * 用户角色关联表 服务实现类
|
||||
*
|
||||
* @param pageParams 用户角色关联表分页查询page对象
|
||||
* @param dto 用户角色关联表分页查询对象
|
||||
* @return 查询分页用户角色关联表返回对象
|
||||
*/
|
||||
@Override
|
||||
public PageResult<UserRoleVo> getUserRolePage(Page<UserRoleEntity> pageParams, UserRoleDto dto) {
|
||||
IPage<UserRoleVo> page = baseMapper.selectListByPage(pageParams, dto);
|
||||
|
||||
return PageResult.<UserRoleVo>builder()
|
||||
.list(page.getRecords())
|
||||
.pageNo(page.getCurrent())
|
||||
.pageSize(page.getSize())
|
||||
.pages(page.getPages())
|
||||
.total(page.getTotal())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户角色关联表
|
||||
*
|
||||
* @param dto 用户角色关联表添加
|
||||
*/
|
||||
@Override
|
||||
public void addUserRole(UserRoleDto dto) {
|
||||
UserRoleEntity userRole = new UserRoleEntity();
|
||||
BeanUtils.copyProperties(dto, userRole);
|
||||
save(userRole);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户角色关联表
|
||||
*
|
||||
* @param dto 用户角色关联表更新
|
||||
*/
|
||||
@Override
|
||||
public void updateUserRole(UserRoleDto dto) {
|
||||
UserRoleEntity userRole = new UserRoleEntity();
|
||||
BeanUtils.copyProperties(dto, userRole);
|
||||
updateById(userRole);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除|批量删除用户角色关联表
|
||||
*
|
||||
* @param ids 删除id列表
|
||||
*/
|
||||
@Override
|
||||
public void deleteUserRole(List<Long> ids) {
|
||||
removeByIds(ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id获取当前用户角色列表
|
||||
*
|
||||
* @param userId 用户id
|
||||
* @return 用户和角色列表
|
||||
*/
|
||||
@Override
|
||||
public List<UserRoleVo> getRoleListByUserId(Long userId) {
|
||||
List<UserRoleEntity> userRoleEntityList = baseMapper.getRoleListByUserId(userId);
|
||||
return userRoleEntityList.stream().map(userRoleEntity -> {
|
||||
UserRoleVo userRoleVo = new UserRoleVo();
|
||||
BeanUtils.copyProperties(userRoleEntity, userRoleVo);
|
||||
return userRoleVo;
|
||||
})
|
||||
.toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据用户id分配用户角色
|
||||
*
|
||||
* @param dto 用户分配角色DTO {@link AssignUserRoleDto}
|
||||
*/
|
||||
@Override
|
||||
public void assignUserRole(AssignUserRoleDto dto) {
|
||||
Long userId = dto.getUserId();
|
||||
List<Long> roleIds = dto.getRoleIds();
|
||||
|
||||
// 先删除已经分配的角色
|
||||
baseMapper.deleteByUserId(userId);
|
||||
|
||||
// 为用户分配角色
|
||||
List<UserRoleEntity> entityList = roleIds.stream().map(roleId -> {
|
||||
UserRoleEntity userRoleEntity = new UserRoleEntity();
|
||||
userRoleEntity.setUserId(userId);
|
||||
userRoleEntity.setRoleId(roleId);
|
||||
return userRoleEntity;
|
||||
}).toList();
|
||||
saveBatch(entityList);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
package com.spring.step3.service.user.impl;
|
||||
|
||||
import com.baomidou.dynamic.datasource.annotation.DS;
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.spring.step3.domain.dto.user.UserDto;
|
||||
import com.spring.step3.domain.entity.UserEntity;
|
||||
import com.spring.step3.domain.vo.UserVo;
|
||||
import com.spring.step3.domain.vo.result.PageResult;
|
||||
import com.spring.step3.mapper.UserMapper;
|
||||
import com.spring.step3.service.user.UserService;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* 用户基本信息表 服务实现类
|
||||
* </p>
|
||||
*
|
||||
* @author Bunny
|
||||
* @since 2025-07-11 22:36:53
|
||||
*/
|
||||
@DS("testJwt")
|
||||
@Service
|
||||
@Transactional
|
||||
@RequiredArgsConstructor
|
||||
public class UserServiceImpl extends ServiceImpl<UserMapper, UserEntity> implements UserService {
|
||||
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
/**
|
||||
* * 用户基本信息表 服务实现类
|
||||
*
|
||||
* @param pageParams 用户基本信息表分页查询page对象
|
||||
* @param dto 用户基本信息表分页查询对象
|
||||
* @return 查询分页用户基本信息表返回对象
|
||||
*/
|
||||
@Override
|
||||
public PageResult<UserVo> getUserPage(Page<UserEntity> pageParams, UserDto dto) {
|
||||
IPage<UserVo> page = baseMapper.selectListByPage(pageParams, dto);
|
||||
|
||||
|
||||
return PageResult.<UserVo>builder()
|
||||
.list(page.getRecords())
|
||||
.pageNo(page.getCurrent())
|
||||
.pageSize(page.getSize())
|
||||
.pages(page.getPages())
|
||||
.total(page.getTotal())
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加用户基本信息表
|
||||
*
|
||||
* @param dto 用户基本信息表添加
|
||||
*/
|
||||
@Override
|
||||
public void addUser(UserDto dto) {
|
||||
UserEntity user = new UserEntity();
|
||||
BeanUtils.copyProperties(dto, user);
|
||||
|
||||
// 用户密码是否为空,为空设置默认密码
|
||||
String password = user.getPassword();
|
||||
password = StringUtils.hasText(password) ? password : "123456";
|
||||
|
||||
// 设置用户密码
|
||||
String encodePassword = passwordEncoder.encode(password);
|
||||
user.setPassword(encodePassword);
|
||||
|
||||
save(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新用户基本信息表
|
||||
*
|
||||
* @param dto 用户基本信息表更新
|
||||
*/
|
||||
@Override
|
||||
public void updateUser(UserDto dto) {
|
||||
UserEntity user = new UserEntity();
|
||||
BeanUtils.copyProperties(dto, user);
|
||||
|
||||
// 设置用户密码
|
||||
String password = user.getPassword();
|
||||
if (StringUtils.hasText(password)) {
|
||||
String encodePassword = passwordEncoder.encode(password);
|
||||
user.setPassword(encodePassword);
|
||||
}
|
||||
|
||||
updateById(user);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除|批量删除用户基本信息表
|
||||
*
|
||||
* @param ids 删除id列表
|
||||
*/
|
||||
@Override
|
||||
public void deleteUser(List<Long> ids) {
|
||||
removeByIds(ids);
|
||||
}
|
||||
}
|
|
@ -1,9 +1,9 @@
|
|||
package com.spring.step2.service.user.strategy;
|
||||
package com.spring.step3.service.user.strategy;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.spring.step2.domain.dto.LoginDto;
|
||||
import com.spring.step2.domain.entity.UserEntity;
|
||||
import com.spring.step2.mapper.UserMapper;
|
||||
import com.spring.step3.domain.dto.LoginDto;
|
||||
import com.spring.step3.domain.entity.UserEntity;
|
||||
import com.spring.step3.mapper.UserMapper;
|
||||
|
||||
/**
|
||||
* 使用用户名登录
|
|
@ -1,7 +1,8 @@
|
|||
package com.spring.step2.service.user.strategy;
|
||||
package com.spring.step3.service.user.strategy;
|
||||
|
||||
import com.spring.step2.domain.dto.LoginDto;
|
||||
import com.spring.step2.domain.entity.UserEntity;
|
||||
|
||||
import com.spring.step3.domain.dto.LoginDto;
|
||||
import com.spring.step3.domain.entity.UserEntity;
|
||||
import org.springframework.security.core.userdetails.UsernameNotFoundException;
|
||||
|
||||
import java.util.Map;
|
|
@ -1,8 +1,7 @@
|
|||
package com.spring.step2.service.user.strategy;
|
||||
package com.spring.step3.service.user.strategy;
|
||||
|
||||
|
||||
import com.spring.step2.domain.dto.LoginDto;
|
||||
import com.spring.step2.domain.entity.UserEntity;
|
||||
import com.spring.step3.domain.dto.LoginDto;
|
||||
import com.spring.step3.domain.entity.UserEntity;
|
||||
|
||||
/**
|
||||
* 登录策略
|
|
@ -1,12 +1,10 @@
|
|||
package com.spring.step2.utils;
|
||||
package com.spring.step3.utils;
|
||||
|
||||
|
||||
import com.spring.step2.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step2.exception.SecurityException;
|
||||
import com.spring.step3.domain.vo.result.ResultCodeEnum;
|
||||
import com.spring.step3.exception.AuthenticSecurityException;
|
||||
import io.jsonwebtoken.Claims;
|
||||
import io.jsonwebtoken.Jws;
|
||||
import io.jsonwebtoken.Jwts;
|
||||
import io.micrometer.common.lang.Nullable;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
|
@ -123,26 +121,27 @@ public class JwtTokenUtil {
|
|||
*/
|
||||
public static Map<String, Object> getMapByToken(String token, SecretKey key) {
|
||||
try {
|
||||
if (!StringUtils.hasText(token)) throw new SecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
if (!StringUtils.hasText(token))
|
||||
throw new AuthenticSecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
// 将 body 值转为map
|
||||
return Jwts.parser().verifyWith(key).build().parseSignedClaims(token).getPayload();
|
||||
|
||||
} catch (Exception exception) {
|
||||
throw new SecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
throw new AuthenticSecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getSubjectByTokenHandler(String token, SecretKey key) {
|
||||
try {
|
||||
if (!StringUtils.hasText(token)) throw new SecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
if (!StringUtils.hasText(token))
|
||||
throw new AuthenticSecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
Jws<Claims> claimsJws = Jwts.parser().verifyWith(key).build().parseSignedClaims(token);
|
||||
Claims body = claimsJws.getPayload();
|
||||
|
||||
return body.getSubject();
|
||||
|
||||
} catch (Exception exception) {
|
||||
throw new SecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
throw new AuthenticSecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,14 +163,14 @@ public class JwtTokenUtil {
|
|||
*/
|
||||
public static Long getUserId(String token, SecretKey key) {
|
||||
try {
|
||||
if (!StringUtils.hasText(token)) throw new SecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
if (!StringUtils.hasText(token)) throw new AuthenticSecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
|
||||
Jws<Claims> claimsJws = Jwts.parser().verifyWith(key).build().parseSignedClaims(token);
|
||||
Claims claims = claimsJws.getPayload();
|
||||
|
||||
return Long.valueOf(String.valueOf(claims.get("userId")));
|
||||
} catch (Exception exception) {
|
||||
throw new SecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
throw new AuthenticSecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,27 +188,17 @@ public class JwtTokenUtil {
|
|||
Claims claims = claimsJws.getPayload();
|
||||
return (String) claims.get("username");
|
||||
} catch (Exception exception) {
|
||||
throw new SecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
throw new AuthenticSecurityException(ResultCodeEnum.TOKEN_PARSING_FAILED);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断token是否过期
|
||||
*
|
||||
* @param token token
|
||||
* @return 是否过期
|
||||
*/
|
||||
public static boolean isExpired(String token, SecretKey key) {
|
||||
return isExpiredUtil(token, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否过期
|
||||
*
|
||||
* @param token token
|
||||
* @return 是否过期
|
||||
*/
|
||||
private static boolean isExpiredUtil(String token, SecretKey key) {
|
||||
public static boolean isExpired(String token, SecretKey key) {
|
||||
try {
|
||||
Jws<Claims> claimsJws = Jwts.parser().verifyWith(key).build().parseSignedClaims(token);
|
||||
Date expiration = claimsJws.getPayload().getExpiration();
|
|
@ -0,0 +1,26 @@
|
|||
package com.spring.step3.utils;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
|
||||
import com.spring.step3.domain.vo.result.Result;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.springframework.http.HttpStatus;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class ResponseUtil {
|
||||
|
||||
public static void out(HttpServletResponse response, Result<Object> result) {
|
||||
try {
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
|
||||
// 注册JavaTimeModule模块
|
||||
mapper.registerModule(new JavaTimeModule());
|
||||
response.setContentType("application/json;charset=UTF-8");
|
||||
response.setStatus(HttpStatus.OK.value());
|
||||
mapper.writeValue(response.getWriter(), result);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
bunny:
|
||||
master:
|
||||
host: rm-bp12z6hlv46vi6g8mro.mysql.rds.aliyuncs.com
|
||||
port: 3306
|
||||
database: bunny_test
|
||||
username: bunny_test
|
||||
password: "Test1234"
|
||||
testJwt:
|
||||
host: rm-bp12z6hlv46vi6g8mro.mysql.rds.aliyuncs.com
|
||||
port: 3306
|
||||
database: test_jwt
|
||||
username: bunny_test
|
||||
password: "Test1234"
|
|
@ -0,0 +1,57 @@
|
|||
server:
|
||||
port: 8772
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: spring-security
|
||||
profiles:
|
||||
active: dev
|
||||
devtools:
|
||||
livereload:
|
||||
port: 0
|
||||
|
||||
datasource:
|
||||
dynamic:
|
||||
primary: master
|
||||
datasource:
|
||||
master:
|
||||
type: com.zaxxer.hikari.HikariDataSource
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://${bunny.master.host}:${bunny.master.port}/${bunny.master.database}?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true
|
||||
username: ${bunny.master.username}
|
||||
password: ${bunny.master.password}
|
||||
testJwt:
|
||||
type: com.zaxxer.hikari.HikariDataSource
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
url: jdbc:mysql://${bunny.testJwt.host}:${bunny.testJwt.port}/${bunny.testJwt.database}?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true
|
||||
username: ${bunny.testJwt.username}
|
||||
password: ${bunny.testJwt.password}
|
||||
hikari:
|
||||
maximum-pool-size: 20
|
||||
connection-timeout: 30000
|
||||
|
||||
jackson:
|
||||
date-format: yyyy-MM-dd HH:mm:ss
|
||||
|
||||
mybatis-plus:
|
||||
mapper-locations: classpath:/mapper/*.xml
|
||||
global-config:
|
||||
db-config:
|
||||
id-type: assign_id
|
||||
logic-delete-value: 1
|
||||
logic-not-delete-value: 0
|
||||
logic-delete-field: isDeleted
|
||||
|
||||
logging:
|
||||
level:
|
||||
root: info
|
||||
com.spring: debug
|
||||
org.springframework.security: debug
|
||||
|
||||
jwtToken:
|
||||
# 密钥
|
||||
secret: aVeryLongAndSecureRandomStringWithAtLeast32Characters
|
||||
# 主题
|
||||
subject: SecurityBunny
|
||||
# 过期事件 7天
|
||||
expired: 604800
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
____ ____ _ _
|
||||
| __ ) _ _ _ __ _ __ _ _ / ___|| |_ _ _ __| |_ _
|
||||
| _ \| | | | '_ \| '_ \| | | | \___ \| __| | | |/ _` | | | |
|
||||
| |_) | |_| | | | | | | | |_| | ___) | |_| |_| | (_| | |_| |
|
||||
|____/ \__,_|_| |_|_| |_|\__, | |____/ \__|\__,_|\__,_|\__, |
|
||||
|___/ |___/
|
||||
|
||||
Service Name${spring.application.name}
|
||||
SpringBoot Version: ${spring-boot.version}${spring-boot.formatted-version}
|
||||
Spring Active:${spring.profiles.active}
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<contextName>logback</contextName>
|
||||
|
||||
<!-- 格式化 年-月-日 输出 -->
|
||||
<timestamp key="datetime" datePattern="yyyy-MM-dd"/>
|
||||
<!-- 引入Spring属性 -->
|
||||
<springProperty name="APP_NAME" source="spring.application.name" defaultValue="application"/>
|
||||
|
||||
<!--编码-->
|
||||
<property name="ENCODING" value="UTF-8"/>
|
||||
|
||||
<!-- 控制台日志 -->
|
||||
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
|
||||
<!-- 临界值过滤器 -->
|
||||
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
|
||||
<level>DEBUG</level>
|
||||
</filter>
|
||||
<encoder>
|
||||
<pattern>
|
||||
%cyan([%thread %d{yyyy-MM-dd HH:mm:ss}]) %yellow(%-5level) %green(%logger{100}).%boldRed(%method)-%boldMagenta(%line)-%blue(%msg%n)
|
||||
</pattern>
|
||||
<charset>${ENCODING}</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 文件日志 -->
|
||||
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
|
||||
<file>logs/${APP_NAME}/${datetime}.log</file>
|
||||
<append>true</append>
|
||||
<encoder>
|
||||
<pattern>%date{yyyy-MM-dd HH:mm:ss} [%-5level] %thread %file:%line %logger %msg%n</pattern>
|
||||
<charset>${ENCODING}</charset>
|
||||
</encoder>
|
||||
</appender>
|
||||
|
||||
<!-- 让SpringBoot内部日志ERROR级别 减少日志输出 -->
|
||||
<logger name="org.springframework" level="ERROR" additivity="false">
|
||||
<appender-ref ref="STOUT"/>
|
||||
</logger>
|
||||
|
||||
<!-- 让mybatis整合包日志ERROR 减少日志输出 -->
|
||||
<logger name="org.mybatis" level="ERROR" additivity="false">
|
||||
<appender-ref ref="STOUT"/>
|
||||
</logger>
|
||||
|
||||
<!-- 让ibatis 日志ERROR 减少日志输出 -->
|
||||
<logger name="org.apache.ibatis" level="ERROR" additivity="false">
|
||||
<appender-ref ref="STOUT"/>
|
||||
</logger>
|
||||
|
||||
<!-- 让 tomcat包打印日志 日志ERROR 减少日志输出 -->
|
||||
<logger name="org.apache" level="ERROR" additivity="false">
|
||||
<appender-ref ref="STOUT"/>
|
||||
</logger>
|
||||
|
||||
<!-- 我们自己开发的程序为DEBUG -->
|
||||
<logger name="cn.bunny" level="DEBUG" additivity="false">
|
||||
<appender-ref ref="STOUT"/>
|
||||
</logger>
|
||||
|
||||
<logger name="com.baomidou" level="ERROR" additivity="false">
|
||||
<appender-ref ref="STOUT"/>
|
||||
</logger>
|
||||
|
||||
<!-- 根日志记录器:INFO级别 -->
|
||||
<root level="DEBUG">
|
||||
<appender-ref ref="CONSOLE"/>
|
||||
<appender-ref ref="FILE"/>
|
||||
</root>
|
||||
|
||||
</configuration>
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.spring.step3.mapper.PermissionMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="com.spring.step3.domain.entity.PermissionEntity">
|
||||
<id column="id" property="id"/>
|
||||
<id column="permission_code" property="permissionCode"/>
|
||||
<id column="url" property="url"/>
|
||||
<id column="method" property="method"/>
|
||||
<id column="description" property="description"/>
|
||||
<id column="remark" property="remark"/>
|
||||
<id column="create_time" property="createTime"/>
|
||||
<id column="update_time" property="updateTime"/>
|
||||
<id column="create_user" property="createUser"/>
|
||||
<id column="update_user" property="updateUser"/>
|
||||
<id column="is_deleted" property="isDeleted"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
id,permission_code,url,method,description,remark,create_time,update_time,create_user,update_user,is_deleted
|
||||
</sql>
|
||||
|
||||
<!-- 分页查询系统权限表内容 -->
|
||||
<select id="selectListByPage" resultType="com.spring.step3.domain.vo.PermissionVo">
|
||||
select
|
||||
<include refid="Base_Column_List"/>
|
||||
from t_permission
|
||||
<where>
|
||||
is_deleted = 0
|
||||
<if test="dto.permissionCode != null and dto.permissionCode != ''">
|
||||
and permission_code like CONCAT('%',#{dto.permissionCode},'%')
|
||||
</if>
|
||||
<if test="dto.url != null and dto.url != ''">
|
||||
and url like CONCAT('%',#{dto.url},'%')
|
||||
</if>
|
||||
<if test="dto.method != null and dto.method != ''">
|
||||
and method like CONCAT('%',#{dto.method},'%')
|
||||
</if>
|
||||
<if test="dto.description != null and dto.description != ''">
|
||||
and description like CONCAT('%',#{dto.description},'%')
|
||||
</if>
|
||||
<if test="dto.remark != null and dto.remark != ''">
|
||||
and remark like CONCAT('%',#{dto.remark},'%')
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.spring.step3.mapper.RoleMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="com.spring.step3.domain.entity.RoleEntity">
|
||||
<id column="id" property="id"/>
|
||||
<id column="role_name" property="roleCode"/>
|
||||
<id column="description" property="description"/>
|
||||
<id column="remark" property="remark"/>
|
||||
<id column="create_time" property="createTime"/>
|
||||
<id column="update_time" property="updateTime"/>
|
||||
<id column="create_user" property="createUser"/>
|
||||
<id column="update_user" property="updateUser"/>
|
||||
<id column="is_deleted" property="isDeleted"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
id,role_name,description,remark,create_time,update_time,create_user,update_user,is_deleted
|
||||
</sql>
|
||||
|
||||
<!-- 分页查询系统角色表内容 -->
|
||||
<select id="selectListByPage" resultType="com.spring.step3.domain.vo.RoleVo">
|
||||
select
|
||||
*
|
||||
from t_role
|
||||
<where>
|
||||
is_deleted = 0
|
||||
<if test="dto.id != null and dto.id != ''">
|
||||
and id like CONCAT('%',#{dto.id},'%')
|
||||
</if>
|
||||
<if test="dto.roleCode != null and dto.roleCode != ''">
|
||||
and role_code like CONCAT('%',#{dto.roleCode},'%')
|
||||
</if>
|
||||
<if test="dto.description != null and dto.description != ''">
|
||||
and description like CONCAT('%',#{dto.description},'%')
|
||||
</if>
|
||||
<if test="dto.remark != null and dto.remark != ''">
|
||||
and remark like CONCAT('%',#{dto.remark},'%')
|
||||
</if>
|
||||
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.spring.step3.mapper.RolePermissionMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="com.spring.step3.domain.entity.RolePermissionEntity">
|
||||
<id column="id" property="id"/>
|
||||
<id column="role_id" property="roleId"/>
|
||||
<id column="permission_id" property="permissionId"/>
|
||||
<id column="create_time" property="createTime"/>
|
||||
<id column="update_time" property="updateTime"/>
|
||||
<id column="create_user" property="createUser"/>
|
||||
<id column="update_user" property="updateUser"/>
|
||||
<id column="is_deleted" property="isDeleted"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
id,role_id,permission_id,create_time,update_time,create_user,update_user,is_deleted
|
||||
</sql>
|
||||
|
||||
<!-- 先删除当前已经分配的角色权限内容 -->
|
||||
<delete id="deleteByRoleId">
|
||||
delete
|
||||
from t_role_permission
|
||||
where role_id = #{roleId}
|
||||
</delete>
|
||||
|
||||
<!-- 分页查询角色权限关联表内容 -->
|
||||
<select id="selectListByPage" resultType="com.spring.step3.domain.vo.RolePermissionVo">
|
||||
select
|
||||
<include refid="Base_Column_List"/>
|
||||
from t_role_permission
|
||||
<where>
|
||||
base.is_deleted = 0
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 根据角色id获取权限内容 -->
|
||||
<select id="selectListByPermissionId" resultType="com.spring.step3.domain.entity.RolePermissionEntity">
|
||||
select *
|
||||
from t_role_permission
|
||||
<where>
|
||||
<if test="permissionId != null">
|
||||
permission_id = #{permissionId}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
|
@ -0,0 +1,72 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.spring.step3.mapper.UserMapper">
|
||||
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="com.spring.step3.domain.entity.UserEntity">
|
||||
<id column="id" property="id"/>
|
||||
<id column="username" property="username"/>
|
||||
<id column="password" property="password"/>
|
||||
<id column="email" property="email"/>
|
||||
<id column="create_time" property="createTime"/>
|
||||
<id column="update_time" property="updateTime"/>
|
||||
<id column="create_user" property="createUser"/>
|
||||
<id column="update_user" property="updateUser"/>
|
||||
<id column="is_deleted" property="isDeleted"/>
|
||||
</resultMap>
|
||||
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
id,username,password,email,create_time,update_time,create_user,update_user,is_deleted
|
||||
</sql>
|
||||
|
||||
<!-- 分页查询用户内容 -->
|
||||
<select id="selectListByPage" resultType="com.spring.step3.domain.vo.UserVo">
|
||||
select
|
||||
<include refid="Base_Column_List"/>
|
||||
from t_user
|
||||
<where>
|
||||
is_deleted = 0
|
||||
<if test="dto.username != null and dto.username != ''">
|
||||
and username like CONCAT('%',#{dto.username},'%')
|
||||
</if>
|
||||
<if test="dto.email != null and dto.email != ''">
|
||||
and email like CONCAT('%',#{dto.email},'%')
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 根据用户id查找当前用户的权限 -->
|
||||
<select id="selectPermissionByUserId" resultType="com.spring.step3.domain.entity.PermissionEntity">
|
||||
SELECT DISTINCT p.*
|
||||
FROM t_permission p
|
||||
JOIN t_role_permission rp ON p.id = rp.permission_id
|
||||
JOIN t_user_role ur ON rp.role_id = ur.role_id
|
||||
WHERE ur.user_id = #{userId}
|
||||
</select>
|
||||
|
||||
<!-- 根据用户名查询当前用户 -->
|
||||
<select id="selectByUsername" resultType="com.spring.step3.domain.entity.UserEntity">
|
||||
select
|
||||
<include refid="Base_Column_List"/>
|
||||
from t_user
|
||||
<where>
|
||||
<if test="username != null and username != null">
|
||||
username = #{username}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
<!-- 根据用户id查找该用户的角色内容 -->
|
||||
<select id="selectRolesByUserId" resultType="com.spring.step3.domain.entity.RoleEntity">
|
||||
SELECT tr.*
|
||||
FROM t_user_role tur
|
||||
JOIN t_role tr ON tur.role_id = tr.id
|
||||
<where>
|
||||
<if test="userId != null">
|
||||
tur.user_id = #{userId}
|
||||
</if>
|
||||
</where>
|
||||
</select>
|
||||
|
||||
</mapper>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue