feat: 增加权限标识;添加数据库文件;为生成权限增加注释;

This commit is contained in:
bunny 2025-05-09 20:04:13 +08:00
parent 42b3a6d150
commit ddc069e8f7
41 changed files with 3758 additions and 8316 deletions

View File

@ -2,13 +2,11 @@
> [!IMPORTANT] > [!IMPORTANT]
> >
> 前端项目整体都由此模板开发 > 开源权限模板[Pure-admin](https://pure-admin.github.io/vue-pure-admin/)
>
> 项目由[小铭](https://github.com/xiaoxian521)开源权限模板[Pure-admin](https://pure-admin.github.io/vue-pure-admin/)
> >
> **Pure-admin文档**https://pure-admin.github.io/pure-admin-doc > **Pure-admin文档**https://pure-admin.github.io/pure-admin-doc
>
> [!TIP] > **默认凭证**
> >
> 项目中有一个默认管理员,数据库中用户`id`是`1` > 项目中有一个默认管理员,数据库中用户`id`是`1`
> >
@ -24,7 +22,9 @@
> >
> `$2a$10$h5BUwmMaVcEuu7Bz0TPPy.PQV8JP6CFJlbHTgT78G1s0YPIu2kfXe` > `$2a$10$h5BUwmMaVcEuu7Bz0TPPy.PQV8JP6CFJlbHTgT78G1s0YPIu2kfXe`
## 视频说明地址 可粗可细的权限控制,多平台文件上传。
## 📽️视频说明地址
**介绍视频视频** **介绍视频视频**
@ -51,10 +51,24 @@
一个基于 Spring Security 6 的现代化动态权限控制系统,提供完整的 RBAC 权限管理解决方案。支持前后端分离架构,可灵活配置细粒度权限控制。 一个基于 Spring Security 6 的现代化动态权限控制系统,提供完整的 RBAC 权限管理解决方案。支持前后端分离架构,可灵活配置细粒度权限控制。
## ✨ v4.0.0 重大更新 ## 😋控制器上注解说明
整个项目是基于URL方便定义权限接口即使项目中接口不存在通过URL的方式增删权限。
比如项目需要为`dept`分配了角色,这个角色可以访问`dept`下所有的接口,那么就可以写成`api/dept/**`,如果需要`dept`下某个接口,`/api/dept/aaa/bbb`,这种形式。
如果针对分页查询分页参数写在URL上的可以这样做`/api/dept/*/*`这样就可以做到灵活的权限控制。
但是在部分场景下接口就是我们的权限这时如果手动一个一个添加URL很麻烦所以使用的swagger自带的注解和`PermissionTag`,自定义的注解的方式,如果这时的项目需求是,为整个接口添加权限,就可以用反射的方式添加。
使用放射的方式已经放在controller的目录下看`ReadMe`文档即可。
## ✨重大更新
### 核心改进 ### 核心改进
**v4.0.0**
- **全面重构**后端接口、实体类等重构前端重构部分j+优化操作体验 - **全面重构**后端接口、实体类等重构前端重构部分j+优化操作体验
- **批量操作支持** - **批量操作支持**
- ✅菜单管理:完善属性内容 - ✅菜单管理:完善属性内容
@ -62,27 +76,13 @@
- ✅ 角色管理:支持 Excel 批量更新 - ✅ 角色管理:支持 Excel 批量更新
- ✅ 多语言配置:支持 JSON/Excel 更新(全量替换模式) - ✅ 多语言配置:支持 JSON/Excel 更新(全量替换模式)
### 技术亮点 **v4.0.1**
- **注解扫描**:通过 `AnnotationScanner.java` 自动扫描想要的注解 - 文件系统支持多平台,只需要手动配置即可。
- 有需要参考文档https://x-file-storage.xuyanwu.cn/#/
- 文件删除和下载等需要实现对应接口`FileRecorder `,目前以实现,对应代码和控制器都在文件夹`file`下如有需要修改可以参考【x-file-storage】文档修改。
```java ## 🧠用法提示
// 示例:扫描特定注解的类
public static Set<Class<?>> getClassesWithAnnotation(Class<?> annotation) {
// 实现细节...
}
```
- **应用场景**
- 定时任务配置
- 权限接口发现
### 界面优化
![权限管理界面](./images/image-20250428223816172.png)
![角色管理界面](./images/image-20250428223843974.png)
## :tipping_hand_man:用法提示
> [!TIP] > [!TIP]
> >
@ -124,16 +124,15 @@ http.authorizeHttpRequests(auth -> auth
### Maven工程结构 ### Maven工程结构
```mermaid ```
graph TD bunny-auth/
├── auth-api # 接口定义层
父工程 -->|主项目| auth-api ├── auth-core # 核心模块
auth-api -->|启动项、控制器| service │ ├── config # 安全配置
service -->|mapper| dao │ └── domain # domain
service -->|包含domain、配置等| auth-core │ └── ...... # 还要很多...
dao -->|包含domain、配置等| auth-core ├── service # 业务实现
└── dao # 数据持久层
``` ```
## 🛠️ 应用场景 ## 🛠️ 应用场景
@ -163,10 +162,12 @@ dao -->|包含domain、配置等| auth-core
```java ```java
@Tag(name = "系统权限") @Tag(name = "系统权限")
@PermissionTag(permission = "permission::*")
@RestController @RestController
@RequestMapping("api/permission") @RequestMapping("api/permission")
public class PermissionController { public class PermissionController {
@Operation(summary = "分页查询", tags = {"permission::page"}) @Operation(summary = "分页查询")
@PermissionTag(permission = "permission::query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<PermissionVo>> getPermissionPage( public Result<PageResult<PermissionVo>> getPermissionPage(
@PathVariable Integer page, @PathVariable Integer page,
@ -195,20 +196,20 @@ AntPath详情https://juejin.cn/spost/7498247273660743732
## 🧰 技术栈 ## 🧰 技术栈
### 前端 ### 😄前端
- Vue 3 + PureAdmin 模板 - Vue 3 + PureAdmin 模板
- 自定义权限组件 - 自定义权限组件
- 国际化支持 - 国际化支持
### 后端 ### 😃后端
- Spring Boot 3 + Spring Security 6 - Spring Boot 3 + Spring Security 6
- JDK 17 - JDK 17
- MySQL + Redis + MinIO - MySQL + Redis + MinIO
- Swagger + Knife4j 文档 - Swagger + Knife4j 文档
### 开发环境 ### 😀开发环境
根据不同docker 启动方式不一样 根据不同docker 启动方式不一样
@ -253,19 +254,11 @@ docker compose up -d
## 📈 后续规划 ## 📈 后续规划
- [x] 权限级别拖拽 暂无
- [x] 权限树型结构动态添加、更新、删除
- [ ] 用户设置持久化存储到数据库
- [x] 权限弹窗页面优化
- [x] 后端文档注释完善
- [x] 系统监控后端返回403停止请求
- [x] 优化用户配置权限逻辑,配置后热更新逻辑等
- [x] 完善后端注释有需要添加ReadMe文档
- [x] 获取Redis中活跃用户
## 前后端接口规范 ## 📏前后端接口规范
### 前端示例规范 ### 🌐前端示例规范
| **操作** | **API 层** | **Pinia 层** | | **操作** | **API 层** | **Pinia 层** |
| :------- | :------------ | :-------------- | | :------- | :------------ | :-------------- |
@ -276,7 +269,7 @@ docker compose up -d
| 更新数据 | `updateUser` | `editUser` | | 更新数据 | `updateUser` | `editUser` |
| 删除数据 | `deleteUser` | `removeUser` | | 删除数据 | `deleteUser` | `removeUser` |
### 后端接口示例规范 ### 🛟后端接口示例规范
遵循Restful 遵循Restful

View File

@ -35,18 +35,6 @@ dromara:
## 生成系统需要的权限 ## 生成系统需要的权限
```java ```java
import cn.bunny.services.AuthServiceApplication;
import cn.bunny.services.aop.scanner.ControllerApiPermissionScanner;
import cn.bunny.services.domain.common.model.dto.scanner.ScannerControllerInfoVo;
import cn.bunny.services.domain.system.system.entity.Permission;
import cn.bunny.services.service.system.PermissionService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
import java.util.Objects;
@SpringBootTest(classes = AuthServiceApplication.class, properties = "spring.profiles.active=dev") @SpringBootTest(classes = AuthServiceApplication.class, properties = "spring.profiles.active=dev")
public class BuildPermissionApiTest { public class BuildPermissionApiTest {
@ -55,12 +43,14 @@ public class BuildPermissionApiTest {
@Test @Test
void test() { void test() {
List<ScannerControllerInfoVo> list = ControllerApiPermissionScanner.getSystemApiInfoList(); List<ScannerControllerInfoVo> list = ControllerApiPermissionScanner.scanControllerInfo();
ScannerControllerInfoVo actuatorParent = ScannerControllerInfoVo.builder().powerCodes(List.of("admin::actuator")).summary("actuator端点访问").build();
// 添加【Springboot端点】在服务监控中会用到
ScannerControllerInfoVo actuatorParent = ScannerControllerInfoVo.builder().powerCode("admin:actuator").summary("actuator端点访问").build();
ScannerControllerInfoVo actuatorChild = ScannerControllerInfoVo.builder().path("/api/actuator/**") ScannerControllerInfoVo actuatorChild = ScannerControllerInfoVo.builder().path("/api/actuator/**")
.summary("Springboot端点全部可以访问") .summary("Springboot端点全部可以访问")
.description("系统监控使用") .description("系统监控使用")
.powerCodes(List.of("actuator::all")) .powerCode("actuator:all")
.build(); .build();
actuatorParent.setChildren(List.of(actuatorChild)); actuatorParent.setChildren(List.of(actuatorChild));
list.add(actuatorParent); list.add(actuatorParent);
@ -69,11 +59,11 @@ public class BuildPermissionApiTest {
String summary = parent.getSummary(); String summary = parent.getSummary();
String path = parent.getPath(); String path = parent.getPath();
String httpMethod = parent.getHttpMethod(); String httpMethod = parent.getHttpMethod();
List<String> powerCodes = parent.getPowerCodes(); String powerCodes = parent.getPowerCode();
String description = parent.getDescription(); String description = parent.getDescription();
// 设置 powerCode // 设置 powerCode
String powerCode = Objects.isNull(powerCodes) ? "" : powerCodes.get(0); String powerCode = Objects.isNull(powerCodes) ? "" : powerCodes;
Permission permission = new Permission(); Permission permission = new Permission();
permission.setParentId(0L); permission.setParentId(0L);
@ -92,10 +82,10 @@ public class BuildPermissionApiTest {
String childrenSummary = children.getSummary(); String childrenSummary = children.getSummary();
String childrenPath = children.getPath(); String childrenPath = children.getPath();
String childrenHttpMethod = children.getHttpMethod(); String childrenHttpMethod = children.getHttpMethod();
List<String> childrenPowerCodes = children.getPowerCodes(); String childrenPowerCodes = children.getPowerCode();
// 设置 powerCode // 设置 powerCode
String childrenPowerCode = Objects.isNull(childrenPowerCodes) ? "" : childrenPowerCodes.get(0); String childrenPowerCode = Objects.isNull(childrenPowerCodes) ? "" : childrenPowerCodes;
Permission childPermission = new Permission(); Permission childPermission = new Permission();
childPermission.setParentId(permissionId); childPermission.setParentId(permissionId);
@ -115,6 +105,10 @@ public class BuildPermissionApiTest {
## MInio权限设置 ## MInio权限设置
因为minio如果第一次创建桶想要访问必须将桶设置为public如果想智能一点可以用下面的方法判断桶是否存在如果存在就将桶设置为公开访问。
问什么要设置公开访问,如果不设置,上传后的图片即使上传好了用户也无法访问。
如果其他平台也需要,根据自己需求进行添加,不需要可以删除这个文件。 如果其他平台也需要,根据自己需求进行添加,不需要可以删除这个文件。
```java ```java

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.configuration; package cn.bunny.services.controller.configuration;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
import cn.bunny.services.domain.system.configuration.dto.WebConfigurationDto; import cn.bunny.services.domain.system.configuration.dto.WebConfigurationDto;
@ -12,6 +13,7 @@ import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@Tag(name = "web配置文件", description = "web配置相关接口") @Tag(name = "web配置文件", description = "web配置相关接口")
@PermissionTag(permission = "config:*")
@RestController @RestController
@RequestMapping("/api/config") @RequestMapping("/api/config")
public class ConfigurationController { public class ConfigurationController {
@ -25,7 +27,8 @@ public class ConfigurationController {
return configurationService.webConfig(); return configurationService.webConfig();
} }
@Operation(summary = "更新web配置文件", description = "更新web配置文件重启应用失效", tags = "config::update") @Operation(summary = "更新web配置文件", description = "更新web配置文件重启应用失效")
@PermissionTag(permission = "config::update")
@PutMapping() @PutMapping()
public Result<Object> updateWebConfiguration(@Valid @RequestBody WebConfigurationDto dto) { public Result<Object> updateWebConfiguration(@Valid @RequestBody WebConfigurationDto dto) {
configurationService.updateWebConfiguration(dto); configurationService.updateWebConfiguration(dto);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.configuration; package cn.bunny.services.controller.configuration;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -29,6 +30,7 @@ import java.util.Map;
* @since 2024-10-10 21:24:08 * @since 2024-10-10 21:24:08
*/ */
@Tag(name = "邮件模板", description = "邮件模板相关接口") @Tag(name = "邮件模板", description = "邮件模板相关接口")
@PermissionTag(permission = "emailTemplate:*")
@RestController @RestController
@RequestMapping("api/emailTemplate") @RequestMapping("api/emailTemplate")
public class EmailTemplateController { public class EmailTemplateController {
@ -36,7 +38,8 @@ public class EmailTemplateController {
@Resource @Resource
private EmailTemplateService emailTemplateService; private EmailTemplateService emailTemplateService;
@Operation(summary = "分页查询邮件模板", description = "分页查询邮件模板", tags = "emailTemplate::query") @Operation(summary = "分页查询邮件模板", description = "分页查询邮件模板")
@PermissionTag(permission = "emailTemplate:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<EmailTemplateVo>> getEmailTemplatePage( public Result<PageResult<EmailTemplateVo>> getEmailTemplatePage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -49,28 +52,31 @@ public class EmailTemplateController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加邮件模板", description = "添加邮件模板", tags = "emailTemplate::add") @Operation(summary = "添加邮件模板", description = "添加邮件模板")
@PermissionTag(permission = "emailTemplate:add")
@PostMapping() @PostMapping()
public Result<String> addEmailTemplate(@Valid @RequestBody EmailTemplateAddDto dto) { public Result<String> addEmailTemplate(@Valid @RequestBody EmailTemplateAddDto dto) {
emailTemplateService.addEmailTemplate(dto); emailTemplateService.addEmailTemplate(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新邮件模板", description = "更新邮件模板", tags = "emailTemplate::update") @Operation(summary = "更新邮件模板", description = "更新邮件模板")
@PermissionTag(permission = "emailTemplate:update")
@PutMapping() @PutMapping()
public Result<String> updateEmailTemplate(@Valid @RequestBody EmailTemplateUpdateDto dto) { public Result<String> updateEmailTemplate(@Valid @RequestBody EmailTemplateUpdateDto dto) {
emailTemplateService.updateEmailTemplate(dto); emailTemplateService.updateEmailTemplate(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除邮件模板", description = "删除邮件模板", tags = "emailTemplate::delete") @Operation(summary = "删除邮件模板", description = "删除邮件模板")
@PermissionTag(permission = "emailTemplate:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteEmailTemplate(@RequestBody List<Long> ids) { public Result<String> deleteEmailTemplate(@RequestBody List<Long> ids) {
emailTemplateService.deleteEmailTemplate(ids); emailTemplateService.deleteEmailTemplate(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "全部邮件类型列表", description = "获取全部邮件类型列表", tags = "emailTemplate::query") @Operation(summary = "全部邮件类型列表", description = "获取全部邮件类型列表")
@GetMapping("private") @GetMapping("private")
public Result<List<Map<String, String>>> getEmailTypeList() { public Result<List<Map<String, String>>> getEmailTypeList() {
List<Map<String, String>> list = emailTemplateService.getEmailTypeList(); List<Map<String, String>> list = emailTemplateService.getEmailTypeList();

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.configuration; package cn.bunny.services.controller.configuration;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -29,6 +30,7 @@ import java.util.Map;
* @since 2024-10-10 15:19:22 * @since 2024-10-10 15:19:22
*/ */
@Tag(name = "邮箱用户配置", description = "邮箱用户发送配置相关接口") @Tag(name = "邮箱用户配置", description = "邮箱用户发送配置相关接口")
@PermissionTag(permission = "emailUsers:*")
@RestController @RestController
@RequestMapping("api/emailUsers") @RequestMapping("api/emailUsers")
public class EmailUsersController { public class EmailUsersController {
@ -36,7 +38,8 @@ public class EmailUsersController {
@Resource @Resource
private EmailUsersService emailUsersService; private EmailUsersService emailUsersService;
@Operation(summary = "分页查询邮箱用户配置", description = "分页查询邮箱用户配置", tags = "emailUsers::query") @Operation(summary = "分页查询邮箱用户配置", description = "分页查询邮箱用户配置")
@PermissionTag(permission = "emailUsers:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<EmailUsersVo>> getEmailUserPage( public Result<PageResult<EmailUsersVo>> getEmailUserPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -49,28 +52,31 @@ public class EmailUsersController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加邮箱用户配置", description = "添加邮箱用户配置", tags = "emailUsers::add") @Operation(summary = "添加邮箱用户配置", description = "添加邮箱用户配置")
@PermissionTag(permission = "emailUsers:add")
@PostMapping() @PostMapping()
public Result<String> addEmailUsers(@Valid @RequestBody EmailUsersAddDto dto) { public Result<String> addEmailUsers(@Valid @RequestBody EmailUsersAddDto dto) {
emailUsersService.addEmailUsers(dto); emailUsersService.addEmailUsers(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新邮箱用户配置", description = "更新邮箱用户配置", tags = "emailUsers::update") @Operation(summary = "更新邮箱用户配置", description = "更新邮箱用户配置")
@PermissionTag(permission = "emailUsers:update")
@PutMapping() @PutMapping()
public Result<String> updateEmailUsers(@Valid @RequestBody EmailUsersUpdateDto dto) { public Result<String> updateEmailUsers(@Valid @RequestBody EmailUsersUpdateDto dto) {
emailUsersService.updateEmailUsers(dto); emailUsersService.updateEmailUsers(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除邮箱用户配置", description = "删除邮箱用户配置", tags = "emailUsers::delete") @Operation(summary = "删除邮箱用户配置", description = "删除邮箱用户配置")
@PermissionTag(permission = "emailUsers:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteEmailUsers(@RequestBody List<Long> ids) { public Result<String> deleteEmailUsers(@RequestBody List<Long> ids) {
emailUsersService.deleteEmailUsers(ids); emailUsersService.deleteEmailUsers(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "全部邮箱用户配置", description = "获取全部邮箱用户配置", tags = "emailUsers::query") @Operation(summary = "全部邮箱用户配置", description = "获取全部邮箱用户配置")
@GetMapping("private") @GetMapping("private")
public Result<List<Map<String, String>>> getEmailUserList() { public Result<List<Map<String, String>>> getEmailUserList() {
List<Map<String, String>> list = emailUsersService.getAllMailboxConfigurationUsers(); List<Map<String, String>> list = emailUsersService.getAllMailboxConfigurationUsers();

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.configuration; package cn.bunny.services.controller.configuration;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -31,6 +32,7 @@ import java.util.Map;
* @since 2024-09-28 * @since 2024-09-28
*/ */
@Tag(name = "多语言", description = "i18n多语言相关接口") @Tag(name = "多语言", description = "i18n多语言相关接口")
@PermissionTag(permission = "i18n:*")
@RestController @RestController
@RequestMapping("api/i18n") @RequestMapping("api/i18n")
public class I18nController { public class I18nController {
@ -38,7 +40,8 @@ public class I18nController {
@Resource @Resource
private I18nService i18nService; private I18nService i18nService;
@Operation(summary = "分页查询多语言", description = "分页查询多语言", tags = "i18n::query") @Operation(summary = "分页查询多语言", description = "分页查询多语言")
@PermissionTag(permission = "i18n:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<I18nVo>> getI18nPage( public Result<PageResult<I18nVo>> getI18nPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -51,41 +54,46 @@ public class I18nController {
return Result.success(vo); return Result.success(vo);
} }
@Operation(summary = "更新多语言", description = "更新多语言", tags = "i18n::update") @Operation(summary = "更新多语言", description = "更新多语言")
@PermissionTag(permission = "i18n:update")
@PutMapping() @PutMapping()
public Result<String> updateI18n(@Valid @RequestBody I18nUpdateDto dto) { public Result<String> updateI18n(@Valid @RequestBody I18nUpdateDto dto) {
i18nService.updateI18n(dto); i18nService.updateI18n(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "添加多语言", description = "添加多语言", tags = "i18n::add") @Operation(summary = "添加多语言", description = "添加多语言")
@PermissionTag(permission = "i18n:add")
@PostMapping() @PostMapping()
public Result<String> addI18n(@Valid @RequestBody I18nAddDto dto) { public Result<String> addI18n(@Valid @RequestBody I18nAddDto dto) {
i18nService.addI18n(dto); i18nService.addI18n(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "删除多语言", description = "删除多语言", tags = "i18n::delete") @Operation(summary = "删除多语言", description = "删除多语言")
@PermissionTag(permission = "i18n:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteI18n(@RequestBody List<Long> ids) { public Result<String> deleteI18n(@RequestBody List<Long> ids) {
i18nService.deleteI18n(ids); i18nService.deleteI18n(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "web获取全部多语言", description = "web获取全部多语言", tags = "i18n::query") @Operation(summary = "web获取全部多语言", description = "web获取全部多语言")
@GetMapping("public") @GetMapping("public")
public Result<Map<String, Object>> getI18nMap() { public Result<Map<String, Object>> getI18nMap() {
Map<String, Object> vo = i18nService.getI18nMap(); Map<String, Object> vo = i18nService.getI18nMap();
return Result.success(vo); return Result.success(vo);
} }
@Operation(summary = "文件导出多语言", description = "文件导出并下载多语言", tags = "i18n::update") @Operation(summary = "文件导出多语言", description = "文件导出并下载多语言")
@PermissionTag(permission = "i18n:update")
@GetMapping("file") @GetMapping("file")
public ResponseEntity<byte[]> downloadI18n(String type) { public ResponseEntity<byte[]> downloadI18n(String type) {
return i18nService.downloadI18n(type); return i18nService.downloadI18n(type);
} }
@Operation(summary = "文件导入多语言", description = "文件更新多语言可以是JSON、Excel", tags = "i18n::update") @Operation(summary = "文件导入多语言", description = "文件更新多语言可以是JSON、Excel")
@PermissionTag(permission = "i18n:update")
@PutMapping("file") @PutMapping("file")
public Result<String> uploadI18nFile(@Valid I18nUpdateByFileDto dto) { public Result<String> uploadI18nFile(@Valid I18nUpdateByFileDto dto) {
i18nService.uploadI18nFile(dto); i18nService.uploadI18nFile(dto);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.configuration; package cn.bunny.services.controller.configuration;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
import cn.bunny.services.domain.system.i18n.dto.I18nTypeAddDto; import cn.bunny.services.domain.system.i18n.dto.I18nTypeAddDto;
@ -24,6 +25,7 @@ import java.util.List;
* @since 2024-09-28 * @since 2024-09-28
*/ */
@Tag(name = "多语言类型", description = "多语言类型相关接口") @Tag(name = "多语言类型", description = "多语言类型相关接口")
@PermissionTag(permission = "i18n:*")
@RestController @RestController
@RequestMapping("api/i18nType") @RequestMapping("api/i18nType")
public class I18nTypeController { public class I18nTypeController {
@ -31,28 +33,31 @@ public class I18nTypeController {
@Resource @Resource
private I18nTypeService i18nTypeService; private I18nTypeService i18nTypeService;
@Operation(summary = "添加多语言类型", description = "添加多语言类型", tags = "i18nType::query") @Operation(summary = "添加多语言类型", description = "添加多语言类型")
@PermissionTag(permission = "i18n:query")
@PostMapping() @PostMapping()
public Result<String> addI18nType(@Valid @RequestBody I18nTypeAddDto dto) { public Result<String> addI18nType(@Valid @RequestBody I18nTypeAddDto dto) {
i18nTypeService.addI18nType(dto); i18nTypeService.addI18nType(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新多语言类型", description = "更新多语言类型", tags = "i18nType::update") @Operation(summary = "更新多语言类型", description = "更新多语言类型")
@PermissionTag(permission = "i18n:update")
@PutMapping() @PutMapping()
public Result<String> updateI18nType(@Valid @RequestBody I18nTypeUpdateDto dto) { public Result<String> updateI18nType(@Valid @RequestBody I18nTypeUpdateDto dto) {
i18nTypeService.updateI18nType(dto); i18nTypeService.updateI18nType(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除多语言类型", description = "删除多语言类型", tags = "i18nType::delete") @Operation(summary = "删除多语言类型", description = "删除多语言类型")
@PermissionTag(permission = "i18n:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteI18nType(@RequestBody List<Long> ids) { public Result<String> deleteI18nType(@RequestBody List<Long> ids) {
i18nTypeService.deleteI18nType(ids); i18nTypeService.deleteI18nType(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "全部多语言类型列表", description = "获取全部多语言类型列表", tags = "i18nType::query") @Operation(summary = "全部多语言类型列表", description = "获取全部多语言类型列表")
@GetMapping("/public") @GetMapping("/public")
public Result<List<I18nTypeVo>> getI18nTypeList(I18nTypeDto dto) { public Result<List<I18nTypeVo>> getI18nTypeList(I18nTypeDto dto) {
List<I18nTypeVo> voList = i18nTypeService.getI18nTypeList(dto); List<I18nTypeVo> voList = i18nTypeService.getI18nTypeList(dto);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.configuration; package cn.bunny.services.controller.configuration;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -28,6 +29,7 @@ import java.util.List;
* @since 2024-10-02 12:18:29 * @since 2024-10-02 12:18:29
*/ */
@Tag(name = "菜单图标", description = "菜单图标相关接口") @Tag(name = "菜单图标", description = "菜单图标相关接口")
@PermissionTag(permission = "menuIcon:*")
@RestController @RestController
@RequestMapping("api/menuIcon") @RequestMapping("api/menuIcon")
public class MenuIconController { public class MenuIconController {
@ -35,7 +37,8 @@ public class MenuIconController {
@Resource @Resource
private MenuIconService menuIconService; private MenuIconService menuIconService;
@Operation(summary = "分页查询菜单图标", description = "分页查询系统菜单图标", tags = "menuIcon::query") @Operation(summary = "分页查询菜单图标", description = "分页查询系统菜单图标")
@PermissionTag(permission = "menuIcon:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<MenuIconVo>> getMenuIconPage( public Result<PageResult<MenuIconVo>> getMenuIconPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -48,28 +51,31 @@ public class MenuIconController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加菜单图标", description = "添加系统菜单图标", tags = "menuIcon::add") @Operation(summary = "添加菜单图标", description = "添加系统菜单图标")
@PermissionTag(permission = "menuIcon:add")
@PostMapping() @PostMapping()
public Result<String> addMenuIcon(@Valid @RequestBody MenuIconAddDto dto) { public Result<String> addMenuIcon(@Valid @RequestBody MenuIconAddDto dto) {
menuIconService.addMenuIcon(dto); menuIconService.addMenuIcon(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新菜单图标", description = "更新系统菜单图标", tags = "menuIcon::update") @Operation(summary = "更新菜单图标", description = "更新系统菜单图标")
@PermissionTag(permission = "menuIcon:update")
@PutMapping() @PutMapping()
public Result<String> updateMenuIcon(@Valid @RequestBody MenuIconUpdateDto dto) { public Result<String> updateMenuIcon(@Valid @RequestBody MenuIconUpdateDto dto) {
menuIconService.updateMenuIcon(dto); menuIconService.updateMenuIcon(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除菜单图标", description = "删除系统菜单图标", tags = "menuIcon::delete") @Operation(summary = "删除菜单图标", description = "删除系统菜单图标")
@PermissionTag(permission = "menuIcon:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteMenuIcon(@RequestBody List<Long> ids) { public Result<String> deleteMenuIcon(@RequestBody List<Long> ids) {
menuIconService.deleteMenuIcon(ids); menuIconService.deleteMenuIcon(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "搜索图标", description = "根据名称搜索图标", tags = "menuIcon::query") @Operation(summary = "搜索图标", description = "根据名称搜索图标")
@GetMapping("public") @GetMapping("public")
public Result<List<MenuIconVo>> getIconNameListByIconName(String iconName) { public Result<List<MenuIconVo>> getIconNameListByIconName(String iconName) {
List<MenuIconVo> voList = menuIconService.getIconNameListByIconName(iconName); List<MenuIconVo> voList = menuIconService.getIconNameListByIconName(iconName);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.file; package cn.bunny.services.controller.file;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.constant.FileStorageConstant; import cn.bunny.services.domain.common.constant.FileStorageConstant;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
@ -32,6 +33,7 @@ import java.util.Map;
* @since 2024-10-09 16:28:01 * @since 2024-10-09 16:28:01
*/ */
@Tag(name = "文件", description = "系统文件相关接口") @Tag(name = "文件", description = "系统文件相关接口")
@PermissionTag(permission = "files:*")
@RestController @RestController
@RequestMapping("api/files") @RequestMapping("api/files")
public class FilesController { public class FilesController {
@ -39,7 +41,8 @@ public class FilesController {
@Resource @Resource
private FilesService filesService; private FilesService filesService;
@Operation(summary = "分页查询文件", description = "分页查询系统文件", tags = "files::query") @Operation(summary = "分页查询文件", description = "分页查询系统文件")
@PermissionTag(permission = "files:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<FilesVo>> getFilesPage( public Result<PageResult<FilesVo>> getFilesPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -52,34 +55,38 @@ public class FilesController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "更新文件", description = "更新系统文件", tags = "files::update") @Operation(summary = "更新文件", description = "更新系统文件")
@PermissionTag(permission = "files:update")
@PutMapping() @PutMapping()
public Result<String> updateFiles(@Valid FilesAddOrUpdateDto dto) { public Result<String> updateFiles(@Valid FilesAddOrUpdateDto dto) {
filesService.updateFiles(dto); filesService.updateFiles(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "添加文件", description = "添加系统文件", tags = "files::add") @Operation(summary = "添加文件", description = "添加系统文件")
@PermissionTag(permission = "files:add")
@PostMapping() @PostMapping()
public Result<Object> addFiles(@Valid FilesAddOrUpdateDto dto) { public Result<Object> addFiles(@Valid FilesAddOrUpdateDto dto) {
filesService.addFiles(dto); filesService.addFiles(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "删除文件", description = "删除系统文件", tags = "files::delete") @Operation(summary = "删除文件", description = "删除系统文件")
@PermissionTag(permission = "files:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteFiles(@RequestBody List<Long> ids) { public Result<String> deleteFiles(@RequestBody List<Long> ids) {
filesService.deleteFiles(ids); filesService.deleteFiles(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "下载文件", description = "根据文件id下载文件", tags = "files::query") @Operation(summary = "下载文件", description = "根据文件id下载文件")
@PermissionTag(permission = "files:query")
@GetMapping("file/{fileId}") @GetMapping("file/{fileId}")
public ResponseEntity<byte[]> downloadFilesByFileId(@PathVariable Long fileId) { public ResponseEntity<byte[]> downloadFilesByFileId(@PathVariable Long fileId) {
return filesService.downloadFilesByFileId(fileId); return filesService.downloadFilesByFileId(fileId);
} }
@Operation(summary = "获取所有文件存储基础路径", description = "获取所有文件存储基础路径", tags = "files::query") @Operation(summary = "获取所有文件存储基础路径", description = "获取所有文件存储基础路径")
@GetMapping("private/getAllFilesStoragePath") @GetMapping("private/getAllFilesStoragePath")
public Result<List<String>> getAllFilesStoragePath() { public Result<List<String>> getAllFilesStoragePath() {
Map<String, String> typeMap = FileStorageConstant.typeMap; Map<String, String> typeMap = FileStorageConstant.typeMap;
@ -88,10 +95,17 @@ public class FilesController {
return Result.success(list); return Result.success(list);
} }
@Operation(summary = "上传文件", description = "上传文件", tags = "files::add") @Operation(summary = "上传文件", description = "上传文件")
@PostMapping("private/upload") @PostMapping("private/upload")
public Result<FileInfoVo> upload(FileUploadDto dto) { public Result<FileInfoVo> upload(FileUploadDto dto) {
FileInfoVo vo = filesService.upload(dto); FileInfoVo vo = filesService.upload(dto);
return Result.success(vo, ResultCodeEnum.SUCCESS_UPLOAD); return Result.success(vo, ResultCodeEnum.SUCCESS_UPLOAD);
} }
@Operation(summary = "上传图片文件", description = "上传图片文件")
@PostMapping("private/uploadImage")
public Result<FileInfoVo> uploadImage(FileUploadDto dto) {
FileInfoVo vo = filesService.uploadFileByThumbnail(dto);
return Result.success(vo, ResultCodeEnum.SUCCESS_UPLOAD);
}
} }

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.file; package cn.bunny.services.controller.file;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -26,6 +27,7 @@ import java.util.List;
* @since 2025-05-08 23:01:19 * @since 2025-05-08 23:01:19
*/ */
@Tag(name = "文件分片信息表,仅在手动分片上传时使用", description = "文件分片信息表,仅在手动分片上传时使用相关接口") @Tag(name = "文件分片信息表,仅在手动分片上传时使用", description = "文件分片信息表,仅在手动分片上传时使用相关接口")
@PermissionTag(permission = "filesParDetail:*")
@RestController @RestController
@RequestMapping("/api/filesParDetail") @RequestMapping("/api/filesParDetail")
public class FilesParDetailController { public class FilesParDetailController {
@ -33,7 +35,8 @@ public class FilesParDetailController {
@Resource @Resource
private FilesParDetailService filesPardetailService; private FilesParDetailService filesPardetailService;
@Operation(summary = "分页查询文件分片信息表,仅在手动分片上传时使用", description = "分页文件分片信息表,仅在手动分片上传时使用", tags = "filesParDetail::query") @Operation(summary = "分页查询文件分片信息表,仅在手动分片上传时使用", description = "分页文件分片信息表,仅在手动分片上传时使用")
@PermissionTag(permission = "filesParDetail:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<FilesParDetailVo>> getFilesParDetailPage( public Result<PageResult<FilesParDetailVo>> getFilesParDetailPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -46,21 +49,24 @@ public class FilesParDetailController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加文件分片信息表,仅在手动分片上传时使用", description = "添加文件分片信息表,仅在手动分片上传时使用", tags = "filesParDetail::add") @Operation(summary = "添加文件分片信息表,仅在手动分片上传时使用", description = "添加文件分片信息表,仅在手动分片上传时使用")
@PermissionTag(permission = "filesParDetail:add")
@PostMapping() @PostMapping()
public Result<String> addFilesParDetail(@Valid @RequestBody FilesParDetailDto dto) { public Result<String> addFilesParDetail(@Valid @RequestBody FilesParDetailDto dto) {
filesPardetailService.addFilesParDetail(dto); filesPardetailService.addFilesParDetail(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新文件分片信息表,仅在手动分片上传时使用", description = "更新文件分片信息表,仅在手动分片上传时使用", tags = "filesParDetail::update") @Operation(summary = "更新文件分片信息表,仅在手动分片上传时使用", description = "更新文件分片信息表,仅在手动分片上传时使用")
@PermissionTag(permission = "filesParDetail:update")
@PutMapping() @PutMapping()
public Result<String> updateFilesParDetail(@Valid @RequestBody FilesParDetailDto dto) { public Result<String> updateFilesParDetail(@Valid @RequestBody FilesParDetailDto dto) {
filesPardetailService.updateFilesParDetail(dto); filesPardetailService.updateFilesParDetail(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除文件分片信息表,仅在手动分片上传时使用", description = "删除文件分片信息表,仅在手动分片上传时使用", tags = "filesParDetail::delete") @Operation(summary = "删除文件分片信息表,仅在手动分片上传时使用", description = "删除文件分片信息表,仅在手动分片上传时使用")
@PermissionTag(permission = "filesParDetail:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteFilesParDetail(@RequestBody List<Long> ids) { public Result<String> deleteFilesParDetail(@RequestBody List<Long> ids) {
filesPardetailService.deleteFilesParDetail(ids); filesPardetailService.deleteFilesParDetail(ids);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.log; package cn.bunny.services.controller.log;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -25,6 +26,7 @@ import java.util.List;
* @since 2024-10-18 12:56:39 * @since 2024-10-18 12:56:39
*/ */
@Tag(name = "任务调度执行日志", description = "调度任务执行日志相关接口") @Tag(name = "任务调度执行日志", description = "调度任务执行日志相关接口")
@PermissionTag(permission = "scheduleExecuteLog:*")
@RestController @RestController
@RequestMapping("api/scheduleExecuteLog") @RequestMapping("api/scheduleExecuteLog")
public class ScheduleExecuteLogController { public class ScheduleExecuteLogController {
@ -32,7 +34,8 @@ public class ScheduleExecuteLogController {
@Resource @Resource
private ScheduleExecuteLogService scheduleExecuteLogService; private ScheduleExecuteLogService scheduleExecuteLogService;
@Operation(summary = "分页查询任务调度执行日志", description = "分页查询调度任务执行日志", tags = "scheduleExecuteLog::query") @Operation(summary = "分页查询任务调度执行日志", description = "分页查询调度任务执行日志")
@PermissionTag(permission = "scheduleExecuteLog:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<ScheduleExecuteLogVo>> getScheduleExecuteLogPage( public Result<PageResult<ScheduleExecuteLogVo>> getScheduleExecuteLogPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -45,7 +48,8 @@ public class ScheduleExecuteLogController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "删除任务调度执行日志", description = "删除调度任务执行日志", tags = "scheduleExecuteLog::delete") @Operation(summary = "删除任务调度执行日志", description = "删除调度任务执行日志")
@PermissionTag(permission = "scheduleExecuteLog:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteScheduleExecuteLog(@RequestBody List<Long> ids) { public Result<String> deleteScheduleExecuteLog(@RequestBody List<Long> ids) {
scheduleExecuteLogService.deleteScheduleExecuteLog(ids); scheduleExecuteLogService.deleteScheduleExecuteLog(ids);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.log; package cn.bunny.services.controller.log;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -26,6 +27,7 @@ import java.util.List;
* @since 2024-10-19 01:01:01 * @since 2024-10-19 01:01:01
*/ */
@Tag(name = "用户登录日志", description = "用户登录日志相关接口") @Tag(name = "用户登录日志", description = "用户登录日志相关接口")
@PermissionTag(permission = "userLoginLog:*")
@RestController @RestController
@RequestMapping("api/userLoginLog") @RequestMapping("api/userLoginLog")
public class UserLoginLogController { public class UserLoginLogController {
@ -33,7 +35,8 @@ public class UserLoginLogController {
@Resource @Resource
private UserLoginLogService userLoginLogService; private UserLoginLogService userLoginLogService;
@Operation(summary = "分页查询用户登录日志", description = "分页查询用户登录日志", tags = "userLoginLog::query") @Operation(summary = "分页查询用户登录日志", description = "分页查询用户登录日志")
@PermissionTag(permission = "userLoginLog:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<UserLoginLogVo>> getUserLoginLogPage( public Result<PageResult<UserLoginLogVo>> getUserLoginLogPage(
@Parameter(name = "page", description = "当前页", required = true) @PathVariable("page") Integer page, @Parameter(name = "page", description = "当前页", required = true) @PathVariable("page") Integer page,
@ -44,14 +47,15 @@ public class UserLoginLogController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "删除用户登录日志", description = "删除用户登录日志", tags = "userLoginLog::delete") @Operation(summary = "删除用户登录日志", description = "删除用户登录日志")
@PermissionTag(permission = "userLoginLog:delete")
@DeleteMapping() @DeleteMapping()
public Result<Object> deleteUserLoginLog(@RequestBody List<Long> ids) { public Result<Object> deleteUserLoginLog(@RequestBody List<Long> ids) {
userLoginLogService.deleteUserLoginLog(ids); userLoginLogService.deleteUserLoginLog(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "分页查询当前用户登录日志", description = "分页查询本地用户登录日志", tags = "userLoginLog::query") @Operation(summary = "分页查询当前用户登录日志", description = "分页查询本地用户登录日志")
@GetMapping("private/{page}/{limit}") @GetMapping("private/{page}/{limit}")
public Result<PageResult<UserLoginLogLocalVo>> getUserLoginLogPageByUser( public Result<PageResult<UserLoginLogLocalVo>> getUserLoginLogPageByUser(
@Parameter(name = "page", description = "当前页", required = true) @PathVariable("page") Integer page, @Parameter(name = "page", description = "当前页", required = true) @PathVariable("page") Integer page,

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.message; package cn.bunny.services.controller.message;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -30,6 +31,7 @@ import java.util.List;
* @since 2024-10-30 15:19:56 * @since 2024-10-30 15:19:56
*/ */
@Tag(name = "系统消息", description = "系统消息相关接口") @Tag(name = "系统消息", description = "系统消息相关接口")
@PermissionTag(permission = "message:*")
@RestController @RestController
@RequestMapping("api/message") @RequestMapping("api/message")
public class MessageController { public class MessageController {
@ -37,7 +39,8 @@ public class MessageController {
@Resource @Resource
private MessageService messageService; private MessageService messageService;
@Operation(summary = "分页查询系统消息", description = "分页查询发送消息", tags = "message::query") @Operation(summary = "分页查询系统消息", description = "分页查询发送消息")
@PermissionTag(permission = "message:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<MessageVo>> getMessagePage( public Result<PageResult<MessageVo>> getMessagePage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -50,35 +53,35 @@ public class MessageController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加系统消息", description = "添加系统消息", tags = "message::add") @Operation(summary = "添加系统消息", description = "添加系统消息")
@PostMapping() @PostMapping()
public Result<String> addMessage(@Valid @RequestBody MessageAddDto dto) { public Result<String> addMessage(@Valid @RequestBody MessageAddDto dto) {
messageService.addMessage(dto); messageService.addMessage(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更系统消息", description = "更新系统消息", tags = "message::update") @Operation(summary = "更系统消息", description = "更新系统消息")
@PutMapping() @PutMapping()
public Result<String> updateMessage(@Valid @RequestBody MessageUpdateDto dto) { public Result<String> updateMessage(@Valid @RequestBody MessageUpdateDto dto) {
messageService.updateMessage(dto); messageService.updateMessage(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除系统消息", description = "删除系统消息", tags = "message::delete") @Operation(summary = "删除系统消息", description = "删除系统消息")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteMessage(@RequestBody List<Long> ids) { public Result<String> deleteMessage(@RequestBody List<Long> ids) {
messageService.deleteMessage(ids); messageService.deleteMessage(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "根据消息id查询消息详情", description = "根据消息id查询消息详情", tags = "message::query") @Operation(summary = "根据消息id查询消息详情", description = "根据消息id查询消息详情")
@GetMapping("private/getMessageDetailById") @GetMapping("private/getMessageDetailById")
public Result<MessageDetailVo> getMessageDetailById(Long id) { public Result<MessageDetailVo> getMessageDetailById(Long id) {
MessageDetailVo vo = messageService.getMessageDetailById(id); MessageDetailVo vo = messageService.getMessageDetailById(id);
return Result.success(vo); return Result.success(vo);
} }
@Operation(summary = "根据消息id获取接收人信息", description = "根据消息id获取接收人信息", tags = "message::query") @Operation(summary = "根据消息id获取接收人信息", description = "根据消息id获取接收人信息")
@GetMapping("private/getReceivedUserinfoByMessageId") @GetMapping("private/getReceivedUserinfoByMessageId")
public Result<List<MessageReceivedWithUserVo>> getReceivedUserinfoByMessageId(Long messageId) { public Result<List<MessageReceivedWithUserVo>> getReceivedUserinfoByMessageId(Long messageId) {
List<MessageReceivedWithUserVo> voList = messageService.getReceivedUserinfoByMessageId(messageId); List<MessageReceivedWithUserVo> voList = messageService.getReceivedUserinfoByMessageId(messageId);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.message; package cn.bunny.services.controller.message;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -29,6 +30,7 @@ import java.util.List;
* @since 2024-10-31 * @since 2024-10-31
*/ */
@Tag(name = "消息接收(用户消息)", description = "消息接收(用户消息)相关接口") @Tag(name = "消息接收(用户消息)", description = "消息接收(用户消息)相关接口")
@PermissionTag(permission = "messageReceived:*")
@RestController @RestController
@RequestMapping("/api/messageReceived") @RequestMapping("/api/messageReceived")
public class MessageReceivedController { public class MessageReceivedController {
@ -36,7 +38,8 @@ public class MessageReceivedController {
@Resource @Resource
private MessageReceivedService messageReceivedService; private MessageReceivedService messageReceivedService;
@Operation(summary = "分页查询消息接收", description = "管理员分页查询用户消息", tags = "messageReceived::query") @Operation(summary = "分页查询消息接收", description = "管理员分页查询用户消息")
@PermissionTag(permission = "messageReceived:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<MessageReceivedWithMessageVo>> getMessageReceivedPage( public Result<PageResult<MessageReceivedWithMessageVo>> getMessageReceivedPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -49,21 +52,23 @@ public class MessageReceivedController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "更新消息接收", description = "管理员将用户消息标为已读", tags = "messageReceived::update") @Operation(summary = "更新消息接收", description = "管理员将用户消息标为已读")
@PermissionTag(permission = "messageReceived:update")
@PutMapping() @PutMapping()
public Result<String> updateMarkMessageReceived(@Valid @RequestBody MessageReceivedUpdateDto dto) { public Result<String> updateMarkMessageReceived(@Valid @RequestBody MessageReceivedUpdateDto dto) {
messageReceivedService.updateMarkMessageReceived(dto); messageReceivedService.updateMarkMessageReceived(dto);
return Result.success(); return Result.success();
} }
@Operation(summary = "删除消息接收", description = "管理删除用户消息", tags = "messageReceived::delete") @Operation(summary = "删除消息接收", description = "管理删除用户消息")
@PermissionTag(permission = "messageReceived:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteMessageReceived(@RequestBody List<Long> ids) { public Result<String> deleteMessageReceived(@RequestBody List<Long> ids) {
messageReceivedService.deleteMessageReceived(ids); messageReceivedService.deleteMessageReceived(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "分页查询消息接收", description = "分页查询用户消息", tags = "messageReceived::query") @Operation(summary = "分页查询消息接收", description = "分页查询用户消息")
@GetMapping("private/{page}/{limit}") @GetMapping("private/{page}/{limit}")
public Result<PageResult<MessageUserVo>> getMessagePageByUser( public Result<PageResult<MessageUserVo>> getMessagePageByUser(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -76,14 +81,14 @@ public class MessageReceivedController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "用户将消息标为已读", description = "用户将消息标为已读", tags = "messageReceived::update") @Operation(summary = "用户将消息标为已读", description = "用户将消息标为已读")
@PutMapping("private/markAsRead") @PutMapping("private/markAsRead")
public Result<String> markAsReadByUser(@Valid @RequestBody List<Long> ids) { public Result<String> markAsReadByUser(@Valid @RequestBody List<Long> ids) {
messageReceivedService.markAsReadByUser(ids); messageReceivedService.markAsReadByUser(ids);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "用户删除消息", description = "用户删除消息", tags = "messageReceived::delete") @Operation(summary = "用户删除消息", description = "用户删除消息")
@DeleteMapping("private/deleteMessage") @DeleteMapping("private/deleteMessage")
public Result<String> deleteMessageByUser(@RequestBody List<Long> ids) { public Result<String> deleteMessageByUser(@RequestBody List<Long> ids) {
messageReceivedService.deleteMessageByUser(ids); messageReceivedService.deleteMessageByUser(ids);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.message; package cn.bunny.services.controller.message;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -28,6 +29,7 @@ import java.util.List;
* @since 2024-10-30 13:19:33 * @since 2024-10-30 13:19:33
*/ */
@Tag(name = "消息类型", description = "系统消息类型相关接口") @Tag(name = "消息类型", description = "系统消息类型相关接口")
@PermissionTag(permission = "messageType:*")
@RestController @RestController
@RequestMapping("api/messageType") @RequestMapping("api/messageType")
public class MessageTypeController { public class MessageTypeController {
@ -35,7 +37,8 @@ public class MessageTypeController {
@Resource @Resource
private MessageTypeService messageTypeService; private MessageTypeService messageTypeService;
@Operation(summary = "分页查询消息类型", description = "分页查询系统消息类型", tags = "messageType::query") @Operation(summary = "分页查询消息类型", description = "分页查询系统消息类型")
@PermissionTag(permission = "messageType:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<MessageTypeVo>> getMessageTypePage( public Result<PageResult<MessageTypeVo>> getMessageTypePage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -48,28 +51,31 @@ public class MessageTypeController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加消息类型", description = "添加系统消息类型", tags = "messageType::add") @Operation(summary = "添加消息类型", description = "添加系统消息类型")
@PermissionTag(permission = "messageType:add")
@PostMapping() @PostMapping()
public Result<String> addMessageType(@Valid @RequestBody MessageTypeAddDto dto) { public Result<String> addMessageType(@Valid @RequestBody MessageTypeAddDto dto) {
messageTypeService.addMessageType(dto); messageTypeService.addMessageType(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新消息类型", description = "更新系统消息类型", tags = "messageType::update") @Operation(summary = "更新消息类型", description = "更新系统消息类型")
@PermissionTag(permission = "messageType:update")
@PutMapping() @PutMapping()
public Result<String> updateMessageType(@Valid @RequestBody MessageTypeUpdateDto dto) { public Result<String> updateMessageType(@Valid @RequestBody MessageTypeUpdateDto dto) {
messageTypeService.updateMessageType(dto); messageTypeService.updateMessageType(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除消息类型", description = "删除系统消息类型", tags = "messageType::delete") @Operation(summary = "删除消息类型", description = "删除系统消息类型")
@PermissionTag(permission = "messageType:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteMessageType(@RequestBody List<Long> ids) { public Result<String> deleteMessageType(@RequestBody List<Long> ids) {
messageTypeService.deleteMessageType(ids); messageTypeService.deleteMessageType(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "所有消息列表", description = "获取所有消息列表", tags = "messageType::query") @Operation(summary = "所有消息列表", description = "获取所有消息列表")
@GetMapping("private/getMessageList") @GetMapping("private/getMessageList")
public Result<List<MessageTypeVo>> getMessageList() { public Result<List<MessageTypeVo>> getMessageList() {
List<MessageTypeVo> voList = messageTypeService.getMessageList(); List<MessageTypeVo> voList = messageTypeService.getMessageList();

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.schedule; package cn.bunny.services.controller.schedule;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.aop.scanner.QuartzSchedulersScanner; import cn.bunny.services.aop.scanner.QuartzSchedulersScanner;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
@ -30,6 +31,7 @@ import java.util.Map;
* @since 2024-10-15 16:35:10 * @since 2024-10-15 16:35:10
*/ */
@Tag(name = "任务调度", description = "调度任务相关接口") @Tag(name = "任务调度", description = "调度任务相关接口")
@PermissionTag(permission = "schedulers:*")
@RestController @RestController
@RequestMapping("api/schedulers") @RequestMapping("api/schedulers")
public class SchedulersController { public class SchedulersController {
@ -37,7 +39,8 @@ public class SchedulersController {
@Resource @Resource
private SchedulersService schedulersService; private SchedulersService schedulersService;
@Operation(summary = "分页查询任务调度", description = "分页查询任务执行", tags = "schedulers::query") @Operation(summary = "分页查询任务调度", description = "分页查询任务执行")
@PermissionTag(permission = "schedulers:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<SchedulersVo>> getSchedulersPage( public Result<PageResult<SchedulersVo>> getSchedulersPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -50,42 +53,47 @@ public class SchedulersController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加任务调度", description = "添加任务", tags = "schedulers::add") @Operation(summary = "添加任务调度", description = "添加任务")
@PermissionTag(permission = "schedulers:add")
@PostMapping() @PostMapping()
public Result<Object> addSchedulers(@Valid @RequestBody SchedulersAddDto dto) { public Result<Object> addSchedulers(@Valid @RequestBody SchedulersAddDto dto) {
schedulersService.addSchedulers(dto); schedulersService.addSchedulers(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新任务调度", description = "更新任务", tags = "schedulers::update") @Operation(summary = "更新任务调度", description = "更新任务")
@PermissionTag(permission = "schedulers:update")
@PutMapping() @PutMapping()
public Result<String> updateSchedulers(@Valid @RequestBody SchedulersUpdateDto dto) { public Result<String> updateSchedulers(@Valid @RequestBody SchedulersUpdateDto dto) {
schedulersService.updateSchedulers(dto); schedulersService.updateSchedulers(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "暂停任务调度", description = "暂停任务", tags = "schedulers::update") @Operation(summary = "暂停任务调度", description = "暂停任务")
@PermissionTag(permission = "schedulers:update")
@PutMapping("pause") @PutMapping("pause")
public Result<String> pause(@RequestBody SchedulersUpdateDto dto) { public Result<String> pause(@RequestBody SchedulersUpdateDto dto) {
schedulersService.pauseScheduler(dto); schedulersService.pauseScheduler(dto);
return Result.success(); return Result.success();
} }
@Operation(summary = "恢复任务调度", description = "恢复任务", tags = "schedulers::update") @Operation(summary = "恢复任务调度", description = "恢复任务")
@PermissionTag(permission = "schedulers:update")
@PutMapping("resume") @PutMapping("resume")
public Result<String> resume(@RequestBody SchedulersUpdateDto dto) { public Result<String> resume(@RequestBody SchedulersUpdateDto dto) {
schedulersService.resumeScheduler(dto); schedulersService.resumeScheduler(dto);
return Result.success(); return Result.success();
} }
@Operation(summary = "删除任务调度", description = "删除任务", tags = "schedulers::delete") @Operation(summary = "删除任务调度", description = "删除任务")
@PermissionTag(permission = "schedulers:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteSchedulers(@RequestBody SchedulersUpdateDto dto) { public Result<String> deleteSchedulers(@RequestBody SchedulersUpdateDto dto) {
schedulersService.deleteSchedulers(dto); schedulersService.deleteSchedulers(dto);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "获取所有可用调度任务", description = "获取所有可用调度任务", tags = "schedulers::query") @Operation(summary = "获取所有可用调度任务", description = "获取所有可用调度任务")
@GetMapping("private") @GetMapping("private")
public Result<List<Map<String, String>>> getScheduleJobList() { public Result<List<Map<String, String>>> getScheduleJobList() {
List<Map<String, String>> mapList = QuartzSchedulersScanner.getScheduleJobList(); List<Map<String, String>> mapList = QuartzSchedulersScanner.getScheduleJobList();

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.schedule; package cn.bunny.services.controller.schedule;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -28,6 +29,7 @@ import java.util.List;
* @since 2024-10-15 20:26:32 * @since 2024-10-15 20:26:32
*/ */
@Tag(name = "任务调度分组", description = "任务调度分组相关接口") @Tag(name = "任务调度分组", description = "任务调度分组相关接口")
@PermissionTag(permission = "schedulersGroup:*")
@RestController @RestController
@RequestMapping("api/schedulersGroup") @RequestMapping("api/schedulersGroup")
public class SchedulersGroupController { public class SchedulersGroupController {
@ -35,7 +37,8 @@ public class SchedulersGroupController {
@Resource @Resource
private SchedulersGroupService schedulersGroupService; private SchedulersGroupService schedulersGroupService;
@Operation(summary = "分页查询任务调度分组", description = "分页查询任务调度分组", tags = "schedulersGroup::query") @Operation(summary = "分页查询任务调度分组", description = "分页查询任务调度分组")
@PermissionTag(permission = "schedulersGroup:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<SchedulersGroupVo>> getSchedulersGroupPage( public Result<PageResult<SchedulersGroupVo>> getSchedulersGroupPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -48,28 +51,32 @@ public class SchedulersGroupController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加任务调度分组", description = "添加任务调度分组", tags = "schedulersGroup::add") @Operation(summary = "添加任务调度分组", description = "添加任务调度分组")
@PermissionTag(permission = "schedulersGroup:add")
@PostMapping() @PostMapping()
public Result<String> addSchedulersGroup(@Valid @RequestBody SchedulersGroupAddDto dto) { public Result<String> addSchedulersGroup(@Valid @RequestBody SchedulersGroupAddDto dto) {
schedulersGroupService.addSchedulersGroup(dto); schedulersGroupService.addSchedulersGroup(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新任务调度分组", description = "更新任务调度分组", tags = "schedulersGroup::update") @Operation(summary = "更新任务调度分组", description = "更新任务调度分组")
@PermissionTag(permission = "schedulersGroup:update")
@PutMapping() @PutMapping()
public Result<String> updateSchedulersGroup(@Valid @RequestBody SchedulersGroupUpdateDto dto) { public Result<String> updateSchedulersGroup(@Valid @RequestBody SchedulersGroupUpdateDto dto) {
schedulersGroupService.updateSchedulersGroup(dto); schedulersGroupService.updateSchedulersGroup(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除任务调度分组", description = "删除任务调度分组", tags = "schedulersGroup::delete") @Operation(summary = "删除任务调度分组", description = "删除任务调度分组")
@PermissionTag(permission = "schedulersGroup:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteSchedulersGroup(@RequestBody List<Long> ids) { public Result<String> deleteSchedulersGroup(@RequestBody List<Long> ids) {
schedulersGroupService.deleteSchedulersGroup(ids); schedulersGroupService.deleteSchedulersGroup(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "获取所有任务调度分组", description = "获取所有任务调度分组", tags = "schedulersGroup::query") @Operation(summary = "获取所有任务调度分组", description = "获取所有任务调度分组")
@PermissionTag(permission = "schedulersGroup:query")
@GetMapping("getSchedulersGroupList") @GetMapping("getSchedulersGroupList")
public Result<List<SchedulersGroupVo>> getSchedulersGroupList() { public Result<List<SchedulersGroupVo>> getSchedulersGroupList() {
List<SchedulersGroupVo> voList = schedulersGroupService.getSchedulersGroupList(); List<SchedulersGroupVo> voList = schedulersGroupService.getSchedulersGroupList();

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.system; package cn.bunny.services.controller.system;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -28,6 +29,7 @@ import java.util.List;
* @since 2024-10-04 10:39:08 * @since 2024-10-04 10:39:08
*/ */
@Tag(name = "部门", description = "部门相关接口") @Tag(name = "部门", description = "部门相关接口")
@PermissionTag(permission = "dept:*")
@RestController @RestController
@RequestMapping("/api/dept") @RequestMapping("/api/dept")
public class DeptController { public class DeptController {
@ -35,7 +37,8 @@ public class DeptController {
@Resource @Resource
private DeptService deptService; private DeptService deptService;
@Operation(summary = "分页查询部门", description = "分页查询部门", tags = "dept::query") @Operation(summary = "分页查询部门", description = "分页查询部门")
@PermissionTag(permission = "dept:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<DeptVo>> getDeptPage( public Result<PageResult<DeptVo>> getDeptPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -48,28 +51,31 @@ public class DeptController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加部门", description = "添加部门", tags = "dept::add") @Operation(summary = "添加部门", description = "添加部门")
@PermissionTag(permission = "dept:add")
@PostMapping() @PostMapping()
public Result<String> addDept(@Valid @RequestBody DeptAddDto dto) { public Result<String> addDept(@Valid @RequestBody DeptAddDto dto) {
deptService.addDept(dto); deptService.addDept(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新部门", description = "更新部门", tags = "dept::update") @Operation(summary = "更新部门", description = "更新部门")
@PermissionTag(permission = "dept:update")
@PutMapping() @PutMapping()
public Result<String> updateDept(@Valid @RequestBody DeptUpdateDto dto) { public Result<String> updateDept(@Valid @RequestBody DeptUpdateDto dto) {
deptService.updateDept(dto); deptService.updateDept(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除部门", description = "删除部门", tags = "dept::delete") @Operation(summary = "删除部门", description = "删除部门")
@PermissionTag(permission = "dept:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deleteDept(@RequestBody List<Long> ids) { public Result<String> deleteDept(@RequestBody List<Long> ids) {
deptService.deleteDept(ids); deptService.deleteDept(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "获取所有部门", description = "获取所有部门", tags = "dept::query") @Operation(summary = "获取所有部门", description = "获取所有部门")
@GetMapping("private/getDeptList") @GetMapping("private/getDeptList")
public Result<List<DeptVo>> getDeptPage() { public Result<List<DeptVo>> getDeptPage() {
List<DeptVo> voList = deptService.getDeptPage(); List<DeptVo> voList = deptService.getDeptPage();

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.system; package cn.bunny.services.controller.system;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.aop.scanner.ControllerApiPermissionScanner; import cn.bunny.services.aop.scanner.ControllerApiPermissionScanner;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.dto.scanner.ScannerControllerInfoVo; import cn.bunny.services.domain.common.model.dto.scanner.ScannerControllerInfoVo;
@ -33,6 +34,7 @@ import java.util.List;
* @since 2024-10-03 16:00:52 * @since 2024-10-03 16:00:52
*/ */
@Tag(name = "权限", description = "权限相关接口") @Tag(name = "权限", description = "权限相关接口")
@PermissionTag(permission = "permission::all")
@RestController @RestController
@RequestMapping("api/permission") @RequestMapping("api/permission")
public class PermissionController { public class PermissionController {
@ -40,7 +42,8 @@ public class PermissionController {
@Resource @Resource
private PermissionService permissionService; private PermissionService permissionService;
@Operation(summary = "分页查询权限", description = "分页查询权限", tags = {"permission::page", "permission::queryPage"}) @Operation(summary = "分页查询权限", description = "分页查询权限")
@PermissionTag(permission = "permission::page")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<PermissionVo>> getPermissionPage( public Result<PageResult<PermissionVo>> getPermissionPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -53,62 +56,69 @@ public class PermissionController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加权限", description = "添加权限", tags = "permission::add") @Operation(summary = "添加权限", description = "添加权限")
@PermissionTag(permission = "permission::add")
@PostMapping() @PostMapping()
public Result<String> addPermission(@Valid @RequestBody PermissionAddDto dto) { public Result<String> addPermission(@Valid @RequestBody PermissionAddDto dto) {
permissionService.addPermission(dto); permissionService.addPermission(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新权限", description = "更新权限", tags = "permission::update") @Operation(summary = "更新权限", description = "更新权限")
@PermissionTag(permission = "permission::update")
@PutMapping() @PutMapping()
public Result<String> updatePermission(@Valid @RequestBody PermissionUpdateDto dto) { public Result<String> updatePermission(@Valid @RequestBody PermissionUpdateDto dto) {
permissionService.updatePermission(dto); permissionService.updatePermission(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除权限", description = "删除权限", tags = "permission::delete") @Operation(summary = "删除权限", description = "删除权限")
@PermissionTag(permission = "permission::delete")
@DeleteMapping() @DeleteMapping()
public Result<Object> deletePermission(@RequestBody List<Long> ids) { public Result<Object> deletePermission(@RequestBody List<Long> ids) {
permissionService.deletePermission(ids); permissionService.deletePermission(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "导出权限", description = "导出权限为Excel", tags = "permission::update") @Operation(summary = "导出权限", description = "导出权限为Excel")
@PermissionTag(permission = "permission::update")
@GetMapping("file/export") @GetMapping("file/export")
public ResponseEntity<byte[]> exportPermission(String type) { public ResponseEntity<byte[]> exportPermission(String type) {
return permissionService.exportPermission(type); return permissionService.exportPermission(type);
} }
@Operation(summary = "导入权限", description = "导入权限", tags = "permission::update") @Operation(summary = "导入权限", description = "导入权限")
@PermissionTag(permission = "permission::update")
@PutMapping("file/import") @PutMapping("file/import")
public Result<String> importPermission(@RequestParam(value = "file") MultipartFile file, String type) { public Result<String> importPermission(@RequestParam(value = "file") MultipartFile file, String type) {
permissionService.importPermission(file, type); permissionService.importPermission(file, type);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "获取所有权限", description = "获取所有权限", tags = {"permission::query"}) @Operation(summary = "获取所有权限", description = "获取所有权限")
@GetMapping("private/getPermissionList") @GetMapping("private/getPermissionList")
public Result<List<PermissionVo>> getPermissionList() { public Result<List<PermissionVo>> getPermissionList() {
List<PermissionVo> voList = permissionService.getPermissionList(); List<PermissionVo> voList = permissionService.getPermissionList();
return Result.success(voList); return Result.success(voList);
} }
@Operation(summary = "获取系统API信息列表", description = "系统接口API信息列表", tags = "permission::query") @Operation(summary = "获取系统API信息列表", description = "系统接口API信息列表")
@GetMapping("private/getSystemApiInfoList") @GetMapping("private/getSystemApiInfoList")
public Result<List<ScannerControllerInfoVo>> getSystemApiInfoList() { public Result<List<ScannerControllerInfoVo>> getSystemApiInfoList() {
List<ScannerControllerInfoVo> list = ControllerApiPermissionScanner.getSystemApiInfoList(); List<ScannerControllerInfoVo> list = ControllerApiPermissionScanner.scanControllerInfo();
return Result.success(list); return Result.success(list);
} }
@Operation(summary = "批量修改权限父级", description = "批量修改权限父级", tags = "permission::update") @Operation(summary = "批量修改权限父级", description = "批量修改权限父级")
@PermissionTag(permission = "permission::update")
@PatchMapping("update/permissionListByParentId") @PatchMapping("update/permissionListByParentId")
public Result<String> updatePermissionListByParentId(@RequestBody @Valid PermissionUpdateBatchByParentIdDto dto) { public Result<String> updatePermissionListByParentId(@RequestBody @Valid PermissionUpdateBatchByParentIdDto dto) {
permissionService.updatePermissionListByParentId(dto); permissionService.updatePermissionListByParentId(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "批量修改权", description = "批量修改权", tags = "permission::update") @Operation(summary = "批量修改权", description = "批量修改权")
@PermissionTag(permission = "permission::update")
@PatchMapping("update/permissionBatch") @PatchMapping("update/permissionBatch")
public Result<String> updatePermissionBatch(@RequestBody List<PermissionUpdateDto> list) { public Result<String> updatePermissionBatch(@RequestBody List<PermissionUpdateDto> list) {
permissionService.updatePermissionBatch(list); permissionService.updatePermissionBatch(list);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.system; package cn.bunny.services.controller.system;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -30,6 +31,7 @@ import java.util.List;
* @since 2024-10-03 14:26:24 * @since 2024-10-03 14:26:24
*/ */
@Tag(name = "角色", description = "角色相关接口") @Tag(name = "角色", description = "角色相关接口")
@PermissionTag(permission = "role:*")
@RestController @RestController
@RequestMapping("api/role") @RequestMapping("api/role")
public class RoleController { public class RoleController {
@ -37,7 +39,8 @@ public class RoleController {
@Resource @Resource
private RoleService roleService; private RoleService roleService;
@Operation(summary = "分页查询角色", description = "分页查询角色", tags = "role::query") @Operation(summary = "分页查询角色", description = "分页查询角色")
@PermissionTag(permission = "role:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<RoleVo>> getRolePage( public Result<PageResult<RoleVo>> getRolePage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -50,41 +53,46 @@ public class RoleController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加角色", description = "添加角色", tags = "role::add") @Operation(summary = "添加角色", description = "添加角色")
@PermissionTag(permission = "role:add")
@PostMapping() @PostMapping()
public Result<Object> addRole(@Valid @RequestBody RoleAddDto dto) { public Result<Object> addRole(@Valid @RequestBody RoleAddDto dto) {
roleService.addRole(dto); roleService.addRole(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新角色", description = "更新角色", tags = "role::update") @Operation(summary = "更新角色", description = "更新角色")
@PermissionTag(permission = "role:update")
@PutMapping() @PutMapping()
public Result<Object> updateRole(@Valid @RequestBody RoleUpdateDto dto) { public Result<Object> updateRole(@Valid @RequestBody RoleUpdateDto dto) {
roleService.updateRole(dto); roleService.updateRole(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除角色", description = "删除角色", tags = "role::delete") @Operation(summary = "删除角色", description = "删除角色")
@PermissionTag(permission = "role:delete")
@DeleteMapping() @DeleteMapping()
public Result<Object> deleteRole(@RequestBody List<Long> ids) { public Result<Object> deleteRole(@RequestBody List<Long> ids) {
roleService.deleteRole(ids); roleService.deleteRole(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "获取所有角色", description = "获取所有角色", tags = "role::query") @Operation(summary = "获取所有角色", description = "获取所有角色")
@GetMapping("private/roleList") @GetMapping("private/roleList")
public Result<List<RoleVo>> roleList() { public Result<List<RoleVo>> roleList() {
List<RoleVo> roleVoList = roleService.roleList(); List<RoleVo> roleVoList = roleService.roleList();
return Result.success(roleVoList); return Result.success(roleVoList);
} }
@Operation(summary = "导出角色列表", description = "使用Excel导出导出角色列表", tags = "role::update") @Operation(summary = "导出角色列表", description = "使用Excel导出导出角色列表")
@PermissionTag(permission = "role:update")
@GetMapping("file/export") @GetMapping("file/export")
public ResponseEntity<byte[]> exportByExcel() { public ResponseEntity<byte[]> exportByExcel() {
return roleService.exportByExcel(); return roleService.exportByExcel();
} }
@Operation(summary = "更新角色列表", description = "使用Excel更新角色列表", tags = "role::update") @Operation(summary = "更新角色列表", description = "使用Excel更新角色列表")
@PermissionTag(permission = "role:update")
@PutMapping("file/import") @PutMapping("file/import")
public Result<String> updateRoleByFile(MultipartFile file) { public Result<String> updateRoleByFile(MultipartFile file) {
roleService.updateRoleByFile(file); roleService.updateRoleByFile(file);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.system; package cn.bunny.services.controller.system;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
import cn.bunny.services.domain.system.system.dto.AssignPowersToRoleDto; import cn.bunny.services.domain.system.system.dto.AssignPowersToRoleDto;
import cn.bunny.services.service.system.RolePermissionService; import cn.bunny.services.service.system.RolePermissionService;
@ -20,6 +21,7 @@ import java.util.List;
* @since 2024-09-26 * @since 2024-09-26
*/ */
@Tag(name = "角色和权限", description = "角色和权限相关接口") @Tag(name = "角色和权限", description = "角色和权限相关接口")
@PermissionTag(permission = "rolePermission:*")
@RestController @RestController
@RequestMapping("api/rolePermission") @RequestMapping("api/rolePermission")
public class RolePermissionController { public class RolePermissionController {
@ -27,14 +29,15 @@ public class RolePermissionController {
@Resource @Resource
private RolePermissionService rolePermissionService; private RolePermissionService rolePermissionService;
@Operation(summary = "根据角色id获取权限内容", description = "根据角色id获取权限内容", tags = "rolePermission::query") @Operation(summary = "根据角色id获取权限内容", description = "根据角色id获取权限内容")
@GetMapping("private/getPermissionListByRoleId") @GetMapping("private/getPermissionListByRoleId")
public Result<List<String>> getPermissionListByRoleId(Long id) { public Result<List<String>> getPermissionListByRoleId(Long id) {
List<String> voList = rolePermissionService.getPermissionListByRoleId(id); List<String> voList = rolePermissionService.getPermissionListByRoleId(id);
return Result.success(voList); return Result.success(voList);
} }
@Operation(summary = "为角色分配权限", description = "为角色分配权限", tags = "rolePermission::update") @Operation(summary = "为角色分配权限", description = "为角色分配权限")
@PermissionTag(permission = "rolePermission:update")
@PostMapping() @PostMapping()
public Result<String> addRolPermission(@Valid @RequestBody AssignPowersToRoleDto dto) { public Result<String> addRolPermission(@Valid @RequestBody AssignPowersToRoleDto dto) {
rolePermissionService.addRolPermission(dto); rolePermissionService.addRolPermission(dto);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.system; package cn.bunny.services.controller.system;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
import cn.bunny.services.domain.system.system.dto.router.RouterAddDto; import cn.bunny.services.domain.system.system.dto.router.RouterAddDto;
@ -24,6 +25,7 @@ import java.util.List;
* @since 2024-09-26 * @since 2024-09-26
*/ */
@Tag(name = "路由菜单", description = "系统路由相关接口") @Tag(name = "路由菜单", description = "系统路由相关接口")
@PermissionTag(permission = "router:*")
@RestController @RestController
@RequestMapping("api/router") @RequestMapping("api/router")
public class RouterController { public class RouterController {
@ -31,35 +33,40 @@ public class RouterController {
@Resource @Resource
private RouterService routerService; private RouterService routerService;
@Operation(summary = "获取用户菜单", description = "获取用户菜单", tags = "router::query") @Operation(summary = "获取用户菜单", description = "获取用户菜单")
@PermissionTag(permission = "router:query")
@GetMapping("private/routerAsync") @GetMapping("private/routerAsync")
public Result<List<WebUserRouterVo>> routerAsync() { public Result<List<WebUserRouterVo>> routerAsync() {
List<WebUserRouterVo> voList = routerService.routerAsync(); List<WebUserRouterVo> voList = routerService.routerAsync();
return Result.success(voList); return Result.success(voList);
} }
@Operation(summary = "查询管理路由菜单", description = "查询管理菜单列表", tags = "router::query") @Operation(summary = "查询管理路由菜单", description = "查询管理菜单列表")
@PermissionTag(permission = "router:query")
@GetMapping("routerList") @GetMapping("routerList")
public Result<List<RouterManageVo>> routerList() { public Result<List<RouterManageVo>> routerList() {
List<RouterManageVo> voPageResult = routerService.routerList(); List<RouterManageVo> voPageResult = routerService.routerList();
return Result.success(voPageResult); return Result.success(voPageResult);
} }
@Operation(summary = "添加路由菜单", description = "添加路由菜单", tags = "router::add") @Operation(summary = "添加路由菜单", description = "添加路由菜单")
@PermissionTag(permission = "router:add")
@PostMapping() @PostMapping()
public Result<String> addRouter(@Valid @RequestBody RouterAddDto dto) { public Result<String> addRouter(@Valid @RequestBody RouterAddDto dto) {
routerService.addRouter(dto); routerService.addRouter(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新路由菜单", description = "更新路由菜单", tags = "router::update") @Operation(summary = "更新路由菜单", description = "更新路由菜单")
@PermissionTag(permission = "router:update")
@PutMapping() @PutMapping()
public Result<String> updateRouter(@Valid @RequestBody RouterUpdateDto dto) { public Result<String> updateRouter(@Valid @RequestBody RouterUpdateDto dto) {
routerService.updateRouter(dto); routerService.updateRouter(dto);
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除路由菜单", description = "删除路由菜单", tags = "router::delete") @Operation(summary = "删除路由菜单", description = "删除路由菜单")
@PermissionTag(permission = "router:delete")
@DeleteMapping() @DeleteMapping()
public Result<String> deletedRouterByIds(@RequestBody List<Long> ids) { public Result<String> deletedRouterByIds(@RequestBody List<Long> ids) {
routerService.deletedRouterByIds(ids); routerService.deletedRouterByIds(ids);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.system; package cn.bunny.services.controller.system;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
import cn.bunny.services.service.system.RouterRoleService; import cn.bunny.services.service.system.RouterRoleService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -18,6 +19,7 @@ import java.util.List;
* @since 2024-09-26 * @since 2024-09-26
*/ */
@Tag(name = "路由菜单和角色", description = "路由和角色相关接口") @Tag(name = "路由菜单和角色", description = "路由和角色相关接口")
@PermissionTag(permission = "routerRole:*")
@RestController @RestController
@RequestMapping("api/routerRole") @RequestMapping("api/routerRole")
public class RouterRoleController { public class RouterRoleController {
@ -25,14 +27,15 @@ public class RouterRoleController {
@Resource @Resource
private RouterRoleService routerRoleService; private RouterRoleService routerRoleService;
@Operation(summary = "根据菜单id获取所有角色", description = "根据菜单id获取所有角色", tags = "routerRole::query") @Operation(summary = "根据菜单id获取所有角色", description = "根据菜单id获取所有角色")
@GetMapping("private/getRoleListByRouterId") @GetMapping("private/getRoleListByRouterId")
public Result<List<String>> getRoleListByRouterId(Long routerId) { public Result<List<String>> getRoleListByRouterId(Long routerId) {
List<String> roleListByRouterId = routerRoleService.getRoleListByRouterId(routerId); List<String> roleListByRouterId = routerRoleService.getRoleListByRouterId(routerId);
return Result.success(roleListByRouterId); return Result.success(roleListByRouterId);
} }
@Operation(summary = "清除选中菜单所有角色", description = "清除选中菜单所有角色", tags = "routerRole::delete") @Operation(summary = "清除选中菜单所有角色", description = "清除选中菜单所有角色")
@PermissionTag(permission = "routerRole:delete")
@DeleteMapping("clearRouterRole") @DeleteMapping("clearRouterRole")
public Result<String> clearRouterRole(@RequestBody List<Long> routerIds) { public Result<String> clearRouterRole(@RequestBody List<Long> routerIds) {
routerRoleService.clearRouterRole(routerIds); routerRoleService.clearRouterRole(routerIds);

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.system; package cn.bunny.services.controller.system;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.enums.ResultCodeEnum; import cn.bunny.services.domain.common.enums.ResultCodeEnum;
import cn.bunny.services.domain.common.model.vo.result.PageResult; import cn.bunny.services.domain.common.model.vo.result.PageResult;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
@ -23,6 +24,7 @@ import java.util.List;
@Tag(name = "用户", description = "用户信息相关接口") @Tag(name = "用户", description = "用户信息相关接口")
@PermissionTag(permission = "user:*")
@RestController @RestController
@RequestMapping("/api/user") @RequestMapping("/api/user")
public class UserController { public class UserController {
@ -30,7 +32,8 @@ public class UserController {
@Resource @Resource
private UserService userService; private UserService userService;
@Operation(summary = "分页查询用户", description = "分页查询用户信息", tags = "user::query") @Operation(summary = "分页查询用户", description = "分页查询用户信息")
@PermissionTag(permission = "user:query")
@GetMapping("{page}/{limit}") @GetMapping("{page}/{limit}")
public Result<PageResult<AdminUserVo>> getUserPageByAdmin( public Result<PageResult<AdminUserVo>> getUserPageByAdmin(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)
@ -43,14 +46,16 @@ public class UserController {
return Result.success(pageResult); return Result.success(pageResult);
} }
@Operation(summary = "添加用户", description = "添加用户信息", tags = "user::add") @Operation(summary = "添加用户", description = "添加用户信息")
@PermissionTag(permission = "user:add")
@PostMapping() @PostMapping()
public Result<Object> addUserByAdmin(@Valid @RequestBody AdminUserAddDto dto) { public Result<Object> addUserByAdmin(@Valid @RequestBody AdminUserAddDto dto) {
userService.addUserByAdmin(dto); userService.addUserByAdmin(dto);
return Result.success(ResultCodeEnum.ADD_SUCCESS); return Result.success(ResultCodeEnum.ADD_SUCCESS);
} }
@Operation(summary = "更新用户", description = "更新用户信息需要更新Redis中的内容", tags = "user::update") @Operation(summary = "更新用户", description = "更新用户信息需要更新Redis中的内容")
@PermissionTag(permission = "user:update")
@PutMapping() @PutMapping()
public Result<String> updateUserByAdmin(@Valid AdminUserUpdateDto dto, public Result<String> updateUserByAdmin(@Valid AdminUserUpdateDto dto,
@RequestPart(value = "avatar", required = false) MultipartFile avatar) { @RequestPart(value = "avatar", required = false) MultipartFile avatar) {
@ -60,35 +65,38 @@ public class UserController {
return Result.success(ResultCodeEnum.UPDATE_SUCCESS); return Result.success(ResultCodeEnum.UPDATE_SUCCESS);
} }
@Operation(summary = "删除用户", description = "删除用户", tags = "user::delete") @Operation(summary = "删除用户", description = "删除用户")
@PermissionTag(permission = "user:delete")
@DeleteMapping() @DeleteMapping()
public Result<Object> deleteUserByAdmin(@RequestBody List<Long> ids) { public Result<Object> deleteUserByAdmin(@RequestBody List<Long> ids) {
userService.deleteUserByAdmin(ids); userService.deleteUserByAdmin(ids);
return Result.success(ResultCodeEnum.DELETE_SUCCESS); return Result.success(ResultCodeEnum.DELETE_SUCCESS);
} }
@Operation(summary = "根据用户id查询用户", description = "根据用户ID获取用户信息不包含Redis中的信息", tags = "user::query") @Operation(summary = "根据用户id查询用户", description = "根据用户ID获取用户信息不包含Redis中的信息")
@GetMapping("private/getUserinfoById") @GetMapping("private/getUserinfoById")
public Result<UserVo> getUserinfoById(Long id) { public Result<UserVo> getUserinfoById(Long id) {
UserVo vo = userService.getUserinfoById(id); UserVo vo = userService.getUserinfoById(id);
return Result.success(vo); return Result.success(vo);
} }
@Operation(summary = "根据关键字查询用户", description = "根据用户名查询用户列表", tags = "user::query") @Operation(summary = "根据关键字查询用户", description = "根据用户名查询用户列表")
@GetMapping("private/getUserListByKeyword") @GetMapping("private/getUserListByKeyword")
public Result<List<UserVo>> getUserListByKeyword(String keyword) { public Result<List<UserVo>> getUserListByKeyword(String keyword) {
List<UserVo> voList = userService.getUserListByKeyword(keyword); List<UserVo> voList = userService.getUserListByKeyword(keyword);
return Result.success(voList); return Result.success(voList);
} }
@Operation(summary = "强制退出用户", description = "强制退出", tags = "user::update") @Operation(summary = "强制退出用户", description = "强制退出")
@PermissionTag(permission = "user:update")
@PutMapping("forcedOffline") @PutMapping("forcedOffline")
public Result<String> forcedOfflineByAdmin(@RequestBody Long id) { public Result<String> forcedOfflineByAdmin(@RequestBody Long id) {
userService.forcedOfflineByAdmin(id); userService.forcedOfflineByAdmin(id);
return Result.success(); return Result.success();
} }
@Operation(summary = "已登录用户", description = "查询缓存中已登录用户", tags = "user::query") @Operation(summary = "已登录用户", description = "查询缓存中已登录用户")
@PermissionTag(permission = "user:query")
@GetMapping("getCacheUserPage/{page}/{limit}") @GetMapping("getCacheUserPage/{page}/{limit}")
public Result<PageResult<UserVo>> getCacheUserPage( public Result<PageResult<UserVo>> getCacheUserPage(
@Parameter(name = "page", description = "当前页", required = true) @Parameter(name = "page", description = "当前页", required = true)

View File

@ -1,5 +1,6 @@
package cn.bunny.services.controller.system; package cn.bunny.services.controller.system;
import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.model.vo.result.Result; import cn.bunny.services.domain.common.model.vo.result.Result;
import cn.bunny.services.domain.system.system.dto.user.AssignRolesToUsersDto; import cn.bunny.services.domain.system.system.dto.user.AssignRolesToUsersDto;
import cn.bunny.services.service.system.UserRoleService; import cn.bunny.services.service.system.UserRoleService;
@ -19,6 +20,7 @@ import java.util.List;
* @since 2024-09-26 * @since 2024-09-26
*/ */
@Tag(name = "用户和角色", description = "用户和角色相关接口") @Tag(name = "用户和角色", description = "用户和角色相关接口")
@PermissionTag(permission = "userRole:*")
@RestController @RestController
@RequestMapping("api/userRole") @RequestMapping("api/userRole")
public class UserRoleController { public class UserRoleController {
@ -33,7 +35,8 @@ public class UserRoleController {
return Result.success(roleVoList); return Result.success(roleVoList);
} }
@Operation(summary = "为用户分配角色", description = "为用户分配角色", tags = "user::add") @Operation(summary = "为用户分配角色", description = "为用户分配角色")
@PermissionTag(permission = "userRole:add")
@PostMapping() @PostMapping()
public Result<String> addUserRole(@RequestBody AssignRolesToUsersDto dto) { public Result<String> addUserRole(@RequestBody AssignRolesToUsersDto dto) {
userRoleService.addUserRole(dto); userRoleService.addUserRole(dto);

View File

@ -20,12 +20,14 @@ public class BuildPermissionApiTest {
@Test @Test
void test() { void test() {
List<ScannerControllerInfoVo> list = ControllerApiPermissionScanner.getSystemApiInfoList(); List<ScannerControllerInfoVo> list = ControllerApiPermissionScanner.scanControllerInfo();
ScannerControllerInfoVo actuatorParent = ScannerControllerInfoVo.builder().powerCodes(List.of("admin::actuator")).summary("actuator端点访问").build();
// 添加Springboot端点在服务监控中会用到
ScannerControllerInfoVo actuatorParent = ScannerControllerInfoVo.builder().powerCode("admin:actuator").summary("actuator端点访问").build();
ScannerControllerInfoVo actuatorChild = ScannerControllerInfoVo.builder().path("/api/actuator/**") ScannerControllerInfoVo actuatorChild = ScannerControllerInfoVo.builder().path("/api/actuator/**")
.summary("Springboot端点全部可以访问") .summary("Springboot端点全部可以访问")
.description("系统监控使用") .description("系统监控使用")
.powerCodes(List.of("actuator::all")) .powerCode("actuator:all")
.build(); .build();
actuatorParent.setChildren(List.of(actuatorChild)); actuatorParent.setChildren(List.of(actuatorChild));
list.add(actuatorParent); list.add(actuatorParent);
@ -34,11 +36,11 @@ public class BuildPermissionApiTest {
String summary = parent.getSummary(); String summary = parent.getSummary();
String path = parent.getPath(); String path = parent.getPath();
String httpMethod = parent.getHttpMethod(); String httpMethod = parent.getHttpMethod();
List<String> powerCodes = parent.getPowerCodes(); String powerCodes = parent.getPowerCode();
String description = parent.getDescription(); String description = parent.getDescription();
// 设置 powerCode // 设置 powerCode
String powerCode = Objects.isNull(powerCodes) ? "" : powerCodes.get(0); String powerCode = Objects.isNull(powerCodes) ? "" : powerCodes;
Permission permission = new Permission(); Permission permission = new Permission();
permission.setParentId(0L); permission.setParentId(0L);
@ -57,10 +59,10 @@ public class BuildPermissionApiTest {
String childrenSummary = children.getSummary(); String childrenSummary = children.getSummary();
String childrenPath = children.getPath(); String childrenPath = children.getPath();
String childrenHttpMethod = children.getHttpMethod(); String childrenHttpMethod = children.getHttpMethod();
List<String> childrenPowerCodes = children.getPowerCodes(); String childrenPowerCodes = children.getPowerCode();
// 设置 powerCode // 设置 powerCode
String childrenPowerCode = Objects.isNull(childrenPowerCodes) ? "" : childrenPowerCodes.get(0); String childrenPowerCode = Objects.isNull(childrenPowerCodes) ? "" : childrenPowerCodes;
Permission childPermission = new Permission(); Permission childPermission = new Permission();
childPermission.setParentId(permissionId); childPermission.setParentId(permissionId);

View File

@ -0,0 +1,29 @@
package impl;
import cn.bunny.services.aop.scanner.ControllerApiPermissionScanner;
import cn.bunny.services.domain.common.model.dto.scanner.ScannerControllerInfoVo;
import com.alibaba.fastjson2.JSON;
import org.junit.jupiter.api.Test;
import java.util.List;
public class ControllerScannerTest {
@Test
void test() {
List<ScannerControllerInfoVo> list = ControllerApiPermissionScanner.scanControllerInfo();
// 添加Springboot端点在服务监控中会用到
ScannerControllerInfoVo actuatorParent = ScannerControllerInfoVo.builder().powerCode("admin:actuator").summary("actuator端点访问").build();
ScannerControllerInfoVo actuatorChild = ScannerControllerInfoVo.builder().path("/api/actuator/**")
.summary("Springboot端点全部可以访问")
.description("系统监控使用")
.powerCode("actuator:all")
.build();
actuatorParent.setChildren(List.of(actuatorChild));
list.add(actuatorParent);
String jsonString = JSON.toJSONString(list);
System.out.println(jsonString);
}
}

View File

@ -1,38 +0,0 @@
package impl;
import cn.bunny.services.AuthServiceApplication;
import cn.bunny.services.core.template.PermissionTreeProcessor;
import cn.bunny.services.domain.common.model.dto.excel.PermissionExcel;
import cn.bunny.services.domain.system.system.entity.Permission;
import cn.bunny.services.mapper.system.PermissionMapper;
import com.alibaba.fastjson2.JSON;
import org.junit.jupiter.api.Test;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.List;
@SpringBootTest(classes = AuthServiceApplication.class)
class PermissionServiceImplTest {
@Autowired
private PermissionMapper permissionMapper;
@Test
void exportPermission() {
List<Permission> permissionList = permissionMapper.selectList(null);
List<PermissionExcel> permissionExcelList = permissionList.stream().map(permission -> {
PermissionExcel permissionExcel = new PermissionExcel();
BeanUtils.copyProperties(permission, permissionExcel);
return permissionExcel;
}).toList();
PermissionTreeProcessor permissionTreeProcessor = new PermissionTreeProcessor();
List<PermissionExcel> buildTree = permissionTreeProcessor.process(permissionExcelList);
System.out.println(JSON.toJSONString(buildTree));
}
}

View File

@ -28,6 +28,9 @@ public class ControllerInfo {
@Schema(name = "basePath", title = "基础请求路径RequestMapping中的") @Schema(name = "basePath", title = "基础请求路径RequestMapping中的")
private String basePath; private String basePath;
@Schema(name = "permission", title = "权限标识")
private String permission;
@Schema(name = "methods", title = "控制器啊中所有方法") @Schema(name = "methods", title = "控制器啊中所有方法")
private List<MethodInfo> methods; private List<MethodInfo> methods;

View File

@ -24,6 +24,9 @@ public class MethodInfo {
@Schema(name = "summary", title = "请求方法简介") @Schema(name = "summary", title = "请求方法简介")
private String summary; private String summary;
@Schema(name = "permission", title = "权限标识")
private String permission;
@Schema(name = "description", title = "请求方法详情") @Schema(name = "description", title = "请求方法详情")
private String description; private String description;

View File

@ -27,8 +27,8 @@ public class ScannerControllerInfoVo {
@Schema(name = "description", title = "详情") @Schema(name = "description", title = "详情")
private String description; private String description;
@Schema(name = "powerCodes", title = "权限码") @Schema(name = "powerCode", title = "权限码")
private List<String> powerCodes; private String powerCode;
@Schema(name = "description", title = "标签") @Schema(name = "description", title = "标签")
private List<ScannerControllerInfoVo> children; private List<ScannerControllerInfoVo> children;

View File

@ -26,11 +26,4 @@ public class UploadThumbnail {
@Schema(name = "saveThFilename", title = "保存文件名称,不包含扩展名") @Schema(name = "saveThFilename", title = "保存文件名称,不包含扩展名")
String saveThFilename; String saveThFilename;
@Schema(name = "thumbnailWidth", title = "宽度")
Integer thumbnailWidth;
@Schema(name = "thumbnailHeight", title = "高度")
Integer thumbnailHeight;
} }

View File

@ -15,20 +15,41 @@ import lombok.*;
@Schema(name = "FileInfoVo对象", title = "管理端返回文件信息", description = "管理端返回文件信息") @Schema(name = "FileInfoVo对象", title = "管理端返回文件信息", description = "管理端返回文件信息")
public class FileInfoVo extends BaseVo { public class FileInfoVo extends BaseVo {
@Schema(name = "thSize", title = "缩略图大小,单位字节") @Schema(name = "filename", title = "文件名称")
private Long thSize; private String filename;
@Schema(name = "thFilename", title = "缩略图名称")
private String thFilename;
@Schema(name = "filepath", title = "存储路径")
private String filepath;
@Schema(name = "thUrl", title = "缩略图访问路径")
private String thUrl;
@Schema(name = "url", title = "文件访问地址")
private String url;
@Schema(name = "size", title = "文件大小,单位字节") @Schema(name = "size", title = "文件大小,单位字节")
private Long size; private Long size;
@Schema(name = "thSize", title = "缩略图大小,单位字节")
private Long thSize;
@Schema(name = "fileSizeStr", title = "文件大小(字符串)") @Schema(name = "fileSizeStr", title = "文件大小(字符串)")
private String fileSizeStr; private String fileSizeStr;
@Schema(name = "uploadStatus", title = "上传状态仅在手动分片上传时使用1初始化完成2上传完成") @Schema(name = "metadata", title = "文件元数据")
private Integer uploadStatus; private String metadata;
@Schema(name = "filename", title = "文件名称") @Schema(name = "thMetadata", title = "缩略图元数据")
private String filename; private String thMetadata;
@Schema(name = "thUserMetadata", title = "缩略图用户元数据")
private String thUserMetadata;
@Schema(name = "userMetadata", title = "文件用户元数据")
private String userMetadata;
@Schema(name = "objectType", title = "文件所属对象类型,例如用户头像,评价图片") @Schema(name = "objectType", title = "文件所属对象类型,例如用户头像,评价图片")
private String objectType; private String objectType;
@ -36,36 +57,6 @@ public class FileInfoVo extends BaseVo {
@Schema(name = "hashInfo", title = "哈希信息") @Schema(name = "hashInfo", title = "哈希信息")
private String hashInfo; private String hashInfo;
@Schema(name = "platform", title = "存储平台")
private String platform;
@Schema(name = "thMetadata", title = "缩略图元数据")
private String thMetadata;
@Schema(name = "thUrl", title = "缩略图访问路径")
private String thUrl;
@Schema(name = "thUserMetadata", title = "缩略图用户元数据")
private String thUserMetadata;
@Schema(name = "uploadId", title = "上传ID仅在手动分片上传时使用")
private String uploadId;
@Schema(name = "fileAcl", title = "文件ACL")
private String fileAcl;
@Schema(name = "url", title = "文件访问地址")
private String url;
@Schema(name = "thFilename", title = "缩略图名称")
private String thFilename;
@Schema(name = "userMetadata", title = "文件用户元数据")
private String userMetadata;
@Schema(name = "filepath", title = "存储路径")
private String filepath;
@Schema(name = "attr", title = "附加属性") @Schema(name = "attr", title = "附加属性")
private String attr; private String attr;
@ -75,25 +66,5 @@ public class FileInfoVo extends BaseVo {
@Schema(name = "thContentType", title = "缩略图MIME类型") @Schema(name = "thContentType", title = "缩略图MIME类型")
private String thContentType; private String thContentType;
@Schema(name = "metadata", title = "文件元数据")
private String metadata;
@Schema(name = "objectId", title = "文件所属对象id")
private String objectId;
@Schema(name = "downloadCount", title = "下载数量")
private Integer downloadCount;
@Schema(name = "thFileAcl", title = "缩略图文件ACL")
private String thFileAcl;
@Schema(name = "originalFilename", title = "原始文件名")
private String originalFilename;
@Schema(name = "contentType", title = "MIME类型")
private String contentType;
@Schema(name = "basePath", title = "基础存储路径")
private String basePath;
} }

View File

@ -12,19 +12,85 @@ import lombok.*;
@Schema(name = "FilesVo对象", title = "系统文件", description = "管理端系统文件返回信息") @Schema(name = "FilesVo对象", title = "系统文件", description = "管理端系统文件返回信息")
public class FilesVo extends BaseUserVo { public class FilesVo extends BaseUserVo {
@Schema(name = "filename", title = "文件的名称") @Schema(name = "thSize", title = "缩略图大小,单位字节")
private Long thSize;
@Schema(name = "size", title = "文件大小,单位字节")
private Long size;
@Schema(name = "fileSizeStr", title = "文件大小(字符串)")
private String fileSizeStr;
@Schema(name = "uploadStatus", title = "上传状态仅在手动分片上传时使用1初始化完成2上传完成")
private Integer uploadStatus;
@Schema(name = "filename", title = "文件名称")
private String filename; private String filename;
@Schema(name = "filepath", title = "文件在服务器上的存储路径") @Schema(name = "objectType", title = "文件所属对象类型,例如用户头像,评价图片")
private String objectType;
@Schema(name = "hashInfo", title = "哈希信息")
private String hashInfo;
@Schema(name = "platform", title = "存储平台")
private String platform;
@Schema(name = "thMetadata", title = "缩略图元数据")
private String thMetadata;
@Schema(name = "thUrl", title = "缩略图访问路径")
private String thUrl;
@Schema(name = "thUserMetadata", title = "缩略图用户元数据")
private String thUserMetadata;
@Schema(name = "uploadId", title = "上传ID仅在手动分片上传时使用")
private String uploadId;
@Schema(name = "fileAcl", title = "文件ACL")
private String fileAcl;
@Schema(name = "url", title = "文件访问地址")
private String url;
@Schema(name = "thFilename", title = "缩略图名称")
private String thFilename;
@Schema(name = "userMetadata", title = "文件用户元数据")
private String userMetadata;
@Schema(name = "filepath", title = "存储路径")
private String filepath; private String filepath;
@Schema(name = "fileSize", title = "文件的大小,以字节为单位") @Schema(name = "attr", title = "附加属性")
private Long fileSize; private String attr;
@Schema(name = "fileType", title = "文件的MIME类型") @Schema(name = "ext", title = "文件扩展名")
private String fileType; private String ext;
@Schema(name = "thContentType", title = "缩略图MIME类型")
private String thContentType;
@Schema(name = "metadata", title = "文件元数据")
private String metadata;
@Schema(name = "objectId", title = "文件所属对象id")
private String objectId;
@Schema(name = "downloadCount", title = "下载数量") @Schema(name = "downloadCount", title = "下载数量")
private Integer downloadCount; private Integer downloadCount;
@Schema(name = "thFileAcl", title = "缩略图文件ACL")
private String thFileAcl;
@Schema(name = "originalFilename", title = "原始文件名")
private String originalFilename;
@Schema(name = "contentType", title = "MIME类型")
private String contentType;
@Schema(name = "basePath", title = "基础存储路径")
private String basePath;
} }

File diff suppressed because it is too large Load Diff

3091
bunny_test.sql Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,21 @@
package cn.bunny.services.aop.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 这个可加可不加只是在系统初始化的时候会方便一点
* 如果要批量添加接口可以这样做
*/
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface PermissionTag {
/* 权限标识 */
String permission() default "";
/* 详情 */
String description() default "";
}

View File

@ -1,7 +1,6 @@
package cn.bunny.services.aop.scanner; package cn.bunny.services.aop.scanner;
import cn.bunny.services.domain.common.model.dto.scanner.ControllerInfo; import cn.bunny.services.aop.annotation.PermissionTag;
import cn.bunny.services.domain.common.model.dto.scanner.MethodInfo;
import cn.bunny.services.domain.common.model.dto.scanner.ScannerControllerInfoVo; import cn.bunny.services.domain.common.model.dto.scanner.ScannerControllerInfoVo;
import cn.bunny.services.security.config.WebSecurityConfig; import cn.bunny.services.security.config.WebSecurityConfig;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -11,10 +10,8 @@ import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.ArrayList; import java.util.*;
import java.util.Arrays; import java.util.stream.Collectors;
import java.util.List;
import java.util.Set;
/** /**
* 控制器扫描APi注解包含控制器类上的注解 {@link Tag}) {@link Operation} * 控制器扫描APi注解包含控制器类上的注解 {@link Tag}) {@link Operation}
@ -22,72 +19,175 @@ import java.util.Set;
*/ */
public class ControllerApiPermissionScanner extends AbstractAnnotationScanner { public class ControllerApiPermissionScanner extends AbstractAnnotationScanner {
// Ant风格的路径匹配器
private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher(); private static final AntPathMatcher PATH_MATCHER = new AntPathMatcher();
// 路径变量正则表达式用于匹配如{id}这样的路径参数
private static final String PATH_VARIABLE_REGEX = "\\{[^}]*\\}";
// 路径变量的替换字符串
private static final String PATH_VARIABLE_REPLACEMENT = "*";
/** /**
* 获取所有带有@Tag注解的控制器类信息 * 扫描所有带有@RestController注解的类并处理其中的API信息
* *
* @return 包含控制器信息和接口方法的列表 * @return 控制器信息列表
*/ */
public static List<ControllerInfo> scanControllerInfo() { public static List<ScannerControllerInfoVo> scanControllerInfo() {
// 获取所有带有@RestController注解的类
Set<Class<?>> controllerClasses = getClassesWithAnnotation(RestController.class); Set<Class<?>> controllerClasses = getClassesWithAnnotation(RestController.class);
List<ControllerInfo> controllerInfos = new ArrayList<>(); // 处理每个控制器类并收集结果
return controllerClasses.stream()
.map(ControllerApiPermissionScanner::processControllerClass)
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
for (Class<?> clazz : controllerClasses) { /**
ControllerInfo controllerInfo = new ControllerInfo(); * 处理单个控制器类
*
// 获取类上的Tag注解 * @param clazz 控制器类
Tag tag = clazz.getAnnotation(Tag.class); * @return 控制器信息对象如果路径未授权则返回null
if (tag != null) { */
controllerInfo.setTagName(tag.name()); private static ScannerControllerInfoVo processControllerClass(Class<?> clazz) {
controllerInfo.setTagDescription(tag.description()); // 从类注解创建基础控制器信息
} ScannerControllerInfoVo controllerInfo = createControllerInfoFromClass(clazz);
// 检查路径是否已授权
// 获取类上的RequestMapping注解 if (isPathAuthorized(controllerInfo.getPath())) {
RequestMapping requestMapping = clazz.getAnnotation(RequestMapping.class); return null;
if (requestMapping != null && requestMapping.value().length > 0) {
controllerInfo.setBasePath(requestMapping.value()[0]);
}
// 获取方法上的注解信息
List<MethodInfo> methodInfos = new ArrayList<>();
for (Method method : clazz.getDeclaredMethods()) {
MethodInfo methodInfo = new MethodInfo();
// 获取Operation注解
Operation operation = method.getAnnotation(Operation.class);
if (operation != null) {
methodInfo.setSummary(operation.summary());
methodInfo.setDescription(operation.description());
methodInfo.setTags(Arrays.stream(operation.tags()).toList());
}
// 获取请求路径和方法的组合路径
String methodPath = getMethodPath(method);
if (methodPath != null) {
methodInfo.setPath(methodPath);
}
// 获取请求方法类型
String httpMethod = getHttpMethod(method);
if (httpMethod != null) {
methodInfo.setHttpMethod(httpMethod);
}
if (operation != null || methodPath != null) {
methodInfos.add(methodInfo);
}
}
controllerInfo.setMethods(methodInfos);
controllerInfos.add(controllerInfo);
} }
return controllerInfos; // 处理控制器中的所有方法
List<ScannerControllerInfoVo> methodInfos = processControllerMethods(clazz, controllerInfo.getPath());
controllerInfo.setChildren(methodInfos);
return controllerInfo;
}
/**
* 从类注解创建控制器信息
*
* @param clazz 控制器类
* @return 控制器信息对象
*/
private static ScannerControllerInfoVo createControllerInfoFromClass(Class<?> clazz) {
ScannerControllerInfoVo info = new ScannerControllerInfoVo();
// 处理类上的Tag注解
Optional.ofNullable(clazz.getAnnotation(Tag.class))
.ifPresent(tag -> {
info.setSummary(tag.name());
info.setDescription(tag.description());
});
// 处理RequestMapping注解获取路径
processRequestMapping(clazz, info);
// 处理PermissionTag注解获取权限码
Optional.ofNullable(clazz.getAnnotation(PermissionTag.class))
.ifPresent(tag -> {
if (StringUtils.hasText(tag.permission())) {
info.setPowerCode(tag.permission());
}
});
return info;
}
/**
* 处理类上的RequestMapping注解
*
* @param clazz 控制器类
* @param info 控制器信息对象
*/
private static void processRequestMapping(Class<?> clazz, ScannerControllerInfoVo info) {
Optional.ofNullable(clazz.getAnnotation(RequestMapping.class))
.filter(mapping -> mapping.value().length > 0)
.map(mapping -> mapping.value()[0])
.map(path -> {
// 确保路径以/开头且不以/结尾
if (!path.startsWith("/")) path = "/" + path;
return path.endsWith("/") ? path.substring(1) : path;
})
.ifPresent(info::setPath);
}
/**
* 处理控制器类中的所有方法
*
* @param clazz 控制器类
* @param basePath 控制器基础路径
* @return 方法信息列表
*/
private static List<ScannerControllerInfoVo> processControllerMethods(Class<?> clazz, String basePath) {
return Arrays.stream(clazz.getDeclaredMethods())
.map(method -> createMethodInfo(method, basePath))
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
/**
* 创建方法信息对象
*
* @param method 控制器方法
* @param basePath 控制器基础路径
* @return 方法信息对象如果路径未授权则返回null
*/
private static ScannerControllerInfoVo createMethodInfo(Method method, String basePath) {
ScannerControllerInfoVo methodInfo = new ScannerControllerInfoVo();
// 处理Operation注解获取方法摘要和描述
Optional.ofNullable(method.getAnnotation(Operation.class))
.ifPresent(operation -> {
methodInfo.setSummary(operation.summary());
methodInfo.setDescription(operation.description());
});
// 构建完整方法路径
String methodPath = buildMethodPath(method, basePath);
methodInfo.setPath(methodPath);
// 检查路径是否已授权
if (isPathAuthorized(methodPath)) {
return null;
}
// 处理HTTP方法类型
Optional.ofNullable(getHttpMethod(method))
.ifPresent(methodInfo::setHttpMethod);
// 处理PermissionTag注解获取权限码
Optional.ofNullable(method.getAnnotation(PermissionTag.class))
.ifPresent(tag -> methodInfo.setPowerCode(tag.permission()));
return methodInfo;
}
/**
* 构建方法的完整路径
*
* @param method 控制器方法
* @param basePath 控制器基础路径
* @return 完整路径将路径变量替换为*
*/
private static String buildMethodPath(Method method, String basePath) {
String methodPath = getMethodPath(method);
if (methodPath == null) {
return basePath;
}
// 确保路径格式正确
if (!methodPath.startsWith("/")) methodPath = "/" + methodPath;
if (methodPath.endsWith("/")) {
methodPath = methodPath.substring(1);
}
// 合并基础路径和方法路径并替换路径变量
return basePath + methodPath.replaceAll(PATH_VARIABLE_REGEX, PATH_VARIABLE_REPLACEMENT);
} }
/** /**
* 获取HTTP方法类型 * 获取HTTP方法类型
*
* @param method 控制器方法
* @return HTTP方法类型字符串GET/POST/PUT/DELETE/PATCH
*/ */
private static String getHttpMethod(Method method) { private static String getHttpMethod(Method method) {
if (method.getAnnotation(GetMapping.class) != null) return "GET"; if (method.getAnnotation(GetMapping.class) != null) return "GET";
@ -96,6 +196,7 @@ public class ControllerApiPermissionScanner extends AbstractAnnotationScanner {
if (method.getAnnotation(DeleteMapping.class) != null) return "DELETE"; if (method.getAnnotation(DeleteMapping.class) != null) return "DELETE";
if (method.getAnnotation(PatchMapping.class) != null) return "PATCH"; if (method.getAnnotation(PatchMapping.class) != null) return "PATCH";
// 处理RequestMapping注解中的method属性
RequestMapping requestMapping = method.getAnnotation(RequestMapping.class); RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
if (requestMapping != null && requestMapping.method().length > 0) { if (requestMapping != null && requestMapping.method().length > 0) {
return requestMapping.method()[0].name(); return requestMapping.method()[0].name();
@ -104,7 +205,10 @@ public class ControllerApiPermissionScanner extends AbstractAnnotationScanner {
} }
/** /**
* 获取方法上的路径注解值 * 获取方法上的路径值
*
* @param method 控制器方法
* @return 方法路径
*/ */
private static String getMethodPath(Method method) { private static String getMethodPath(Method method) {
// 检查所有可能的路径注解 // 检查所有可能的路径注解
@ -142,104 +246,35 @@ public class ControllerApiPermissionScanner extends AbstractAnnotationScanner {
} }
/** /**
* 当前路径是否有权限被添加 * 检查路径是否已被授权不需要权限控制
* *
* @param path 请求路径 * @param path 请求路径
* @return boolean * @return 如果路径已授权返回true否则返回false
*/ */
public static boolean isPathAuthorized(String path) { public static boolean isPathAuthorized(String path) {
if (!StringUtils.hasText(path)) { if (!StringUtils.hasText(path)) {
return true;
}
// 需要登录的路径模式检查
if (path.equals("login")) {
return false; return false;
} }
// 需要登录之后才访问的不需要添加到要被监视的权限中 // 登录路径特殊处理
if (path.equals("login")) {
return true;
}
// 检查用户认证路径
for (String userAuth : WebSecurityConfig.userAuths) { for (String userAuth : WebSecurityConfig.userAuths) {
if (path.contains(userAuth)) { if (path.contains(userAuth)) {
return false; return true;
} }
} }
// WebSecurityConfig 默认配置的不需要权限的路径不添加 // 检查不需要权限的注解路径
for (String annotation : WebSecurityConfig.annotations) { for (String annotation : WebSecurityConfig.annotations) {
if (PATH_MATCHER.match(annotation, path) || PATH_MATCHER.match(annotation, "/" + path)) { if (PATH_MATCHER.match(annotation, path) || PATH_MATCHER.match(annotation, "/" + path)) {
return false; return true;
} }
} }
return true; return false;
} }
}
/**
* 得到所有控制器下的接口路径
* 其中已经被过滤掉不需要验证的 WebSecurityConfig 配置的 annotations
* 其中已经过滤掉不需要验证的 WebSecurityConfig userAuths
* WebSecurityConfig配置的不会被添加权限中
*
* @return 扫描到且可以被验证的权限
*/
public static List<ScannerControllerInfoVo> getSystemApiInfoList() {
// 路径中包含 {xxx} 替换成 *
String regex = "\\{[^}]*\\}"; // 匹配 {xxx} 格式
String replacement = "*"; // 替换为 *
// 控制器中所有的方法路径等
List<ControllerInfo> controllerInfos = ControllerApiPermissionScanner.scanControllerInfo();
List<ScannerControllerInfoVo> resultList = new ArrayList<>();
List<ControllerInfo> controllerInfoList1 = controllerInfos.stream()
.filter(controllerInfo -> isPathAuthorized(controllerInfo.getBasePath()))
.toList();
// 父级RequestMapping中的内容
for (ControllerInfo controllerInfo : controllerInfoList1) {
// 处理RequestMapping上开头路径
String basePath = controllerInfo.getBasePath();
// 在请求方法前加 /
if (!basePath.startsWith("/")) basePath = "/" + basePath;
// 在请求方法路径后加 /
if (basePath.endsWith("/")) {
basePath = basePath.substring(1);
}
ScannerControllerInfoVo parentVo = ScannerControllerInfoVo.builder()
.path(basePath + "/**")
.summary(controllerInfo.getTagName())
.description(controllerInfo.getTagDescription())
.build();
// 子级 控制器下请求方法
List<MethodInfo> methods = controllerInfo.getMethods();
final String finalBasePath = basePath;
List<ScannerControllerInfoVo> children = methods.stream()
.filter(methodInfo -> isPathAuthorized(methodInfo.getPath()))
.map(methodInfo -> {
String methodInfoPath = methodInfo.getPath();
// 为路径添加 /
if (StringUtils.hasText(methodInfoPath) && !methodInfoPath.startsWith("/")) {
methodInfoPath = finalBasePath + "/" + methodInfoPath;
// 路径包含 {xxx} 替换成 *
methodInfoPath = methodInfoPath.replaceAll(regex, replacement);
} else {
methodInfoPath = finalBasePath;
}
return ScannerControllerInfoVo.builder()
.path(methodInfoPath)
.httpMethod(methodInfo.getHttpMethod())
.summary(methodInfo.getSummary())
.description(methodInfo.getDescription())
.powerCodes(methodInfo.getTags())
.build();
}).toList();
parentVo.setChildren(children);
resultList.add(parentVo);
}
return resultList;
}
}

View File

@ -17,8 +17,8 @@ public class RoleHelper {
* <p> * <p>
* 权限控制说明 * 权限控制说明
* - 管理员权限用于前端按钮级权限控制支持以下通配符格式 * - 管理员权限用于前端按钮级权限控制支持以下通配符格式
* - "*::*::*"全部模块的全部操作权限 * - "*:*:*"全部模块的全部操作权限
* - "*::*" 指定模块的全部操作权限 * - "*:*" 指定模块的全部操作权限
* - "*" 基础通配权限 * - "*" 基础通配权限
* - 若无细粒度按钮控制需求可不设置具体权限 * - 若无细粒度按钮控制需求可不设置具体权限
* 详细查看 * 详细查看
@ -40,8 +40,8 @@ public class RoleHelper {
if (isIdAdmin || isAdmin) { if (isIdAdmin || isAdmin) {
roleList.add("admin"); roleList.add("admin");
permissions.add("*"); permissions.add("*");
permissions.add("*::*"); permissions.add("*:*");
permissions.add("*::*::*"); permissions.add("*:*:*");
return true; return true;
} }

View File

@ -78,7 +78,7 @@ public interface FilesService extends IService<Files> {
* *
* @param uploadThumbnail 上传文件 {@link UploadThumbnail} * @param uploadThumbnail 上传文件 {@link UploadThumbnail}
*/ */
FileInfoVo uploadFileByThumbnail(UploadThumbnail uploadThumbnail); FileInfoVo uploadFileByThumbnail(FileUploadDto uploadThumbnail);
/** /**
* 列举当前文件路径所有的文件 * 列举当前文件路径所有的文件

View File

@ -33,7 +33,6 @@ import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity; import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList; import java.util.ArrayList;
@ -208,38 +207,22 @@ public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements
* 上传文件文档 * 上传文件文档
* </a> * </a>
* *
* @param uploadThumbnail 上传文件 {@link UploadThumbnail} * @param dto 上传文件 {@link UploadThumbnail}
*/ */
@Override @Override
public FileInfoVo uploadFileByThumbnail(UploadThumbnail uploadThumbnail) { public FileInfoVo uploadFileByThumbnail(FileUploadDto dto) {
MultipartFile file = uploadThumbnail.getFile(); MultipartFile file = dto.getFile();
String preType = uploadThumbnail.getPreType(); String preType = dto.getType();
String type = FileStorageConstant.getType(preType); String type = FileStorageConstant.getType(preType);
if (file == null) return null; if (file == null) return null;
// 上传文件构造参数 // 上传文件构造参数
String filepath = type + DateUtil.format(new Date(), "yyyy-MM-dd") + "/"; String filepath = type + DateUtil.format(new Date(), "yyyy-MM-dd") + "/";
UploadPretreatment uploadPretreatment = fileStorageService.of(file).setPath(filepath); UploadPretreatment uploadPretreatment = fileStorageService.of(file)
// 指定缩略图后缀必须是 thumbnailator 支持的图片格式默认使用全局的
// 缩略图后缀 // .setThumbnailSuffix(".jpg")
String thumbnailSuffix = uploadThumbnail.getThumbnailSuffix(); .setPath(filepath)
if (StringUtils.hasText(thumbnailSuffix)) { .thumbnail(200, 200);
uploadPretreatment.setThumbnailSuffix(thumbnailSuffix);
}
// 保存文件名称
String saveThFilename = uploadThumbnail.getSaveThFilename();
if (StringUtils.hasText(saveThFilename)) {
uploadPretreatment.setSaveThFilename(saveThFilename);
}
// 缩略图大小不为空
Integer thumbnailWidth = uploadThumbnail.getThumbnailWidth();
Integer thumbnailHeight = uploadThumbnail.getThumbnailHeight();
if (thumbnailWidth != null && thumbnailHeight != null) {
uploadPretreatment.thumbnail(uploadThumbnail.getThumbnailWidth(), uploadThumbnail.getThumbnailHeight());
}
FileInfo fileInfo = uploadPretreatment.upload(); FileInfo fileInfo = uploadPretreatment.upload();
// 返回信息内容化 // 返回信息内容化