新增物联:完成Java 21与IoT融合架构及安全门禁基线归档

This commit is contained in:
wangzhibiao committed 2026-10-13 21:17:39 +08:00
1 parent 9a62ac8536
commit 373921447f
905 files changed
+127387 -95251

No files matched your search

+4
View File
@@ -20,6 +20,10 @@ node_modules/
.npm-cache/ .npm-cache/
*.class *.class
**/*.class **/*.class
*.jar
**/*.jar
*.dmp
**/*.dmp
# Local authorized Kingbase JDBC vendor binary; provision via scripts/bootstrap/ # Local authorized Kingbase JDBC vendor binary; provision via scripts/bootstrap/
/RuoYi-Vue/lib/kingbase8-8.6.0.jar /RuoYi-Vue/lib/kingbase8-8.6.0.jar
+4 -4
View File
@@ -15,8 +15,8 @@ build_backend:
tags: tags:
- railway-deploy - railway-deploy
rules: rules:
- if: '$CI_COMMIT_BRANCH' - if: '$CI_COMMIT_BRANCH == "feat/cicd-pipeline"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - when: never
script: script:
- echo "=== 开始编译后端 RuoYi-Vue ===" - echo "=== 开始编译后端 RuoYi-Vue ==="
- export JAVA_HOME=/data2/wzb/tools/jdk8 - export JAVA_HOME=/data2/wzb/tools/jdk8
@@ -39,8 +39,8 @@ build_frontend:
tags: tags:
- railway-deploy - railway-deploy
rules: rules:
- if: '$CI_COMMIT_BRANCH' - if: '$CI_COMMIT_BRANCH == "feat/cicd-pipeline"'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - when: never
script: script:
- echo "=== 开始编译前端 build_ui ===" - echo "=== 开始编译前端 build_ui ==="
- export NODE_OPTIONS="--openssl-legacy-provider --dns-result-order=ipv4first" - export NODE_OPTIONS="--openssl-legacy-provider --dns-result-order=ipv4first"
+153
View File
@@ -0,0 +1,153 @@
# SYFJGYD学员管理系统(融合演示版)— Clean Demo Candidate 运行与演示说明书
## 一、系统概况
本工程为 **SYFJGYD学员管理系统** 的隔离融合演示候选版本(Clean Demo Candidate),集成了 **Java 21 + Spring Boot 4** 架构升级、培训管理业务(学员、班级、住宿全周期)与智能门锁 IoT 协同授权中枢。
### 核心演示原则
- **数据源隔离**:严格运行于独立研发 QA 数据库(`railwaysystem_fusion_qa_20261013`),采用最小权限应用账号连接,与共享试用库(`training`)及生产环境完全隔离。
- **仿真受控运行**:IoT 底层采用仿真受控模式,物理 MQTT 硬件与实体门锁处于安全隔离状态,防止误触发真实硬件动作。
- **真实完整业务闭环**:前端 UI、后端业务逻辑、Kingbase 事务状态流转均为 100% 真实执行。
---
## 二、系统访问与前置准备
### 1. 访问地址
- **前端 Web 控制台**:`http://127.0.0.1:8088`
- **默认演示账号**:`admin` / `admin123`
- **后端 API 服务**:`http://127.0.0.1:8096`(由前端通过 `/prod-api` 自动反向代理)
### 2. 演示前服务状态核验
在启动系统前,请确保研发数据库 SSH 隧道处于连通状态:
- **隧道端口**:`127.0.0.1:14321`
- **若隧道未连通**,请在终端执行:
```bash
ssh -N -L 127.0.0.1:14321:192.168.139.218:4321 -o ServerAliveInterval=15 wzbmatebook
```
- **安全凭据文件**:系统启动依赖受限目录下的环境变量配置(`~/.railwaysystem-qa.env`),密码由启动脚本安全注入,无需人工输入。
---
## 三、一键启停操作指南
系统提供了平滑、健壮的一键管理脚本,支持自动端口清理与就绪健康探测:
### 1. 启动系统
在工程根目录下执行:
```bash
./start_demo.sh
```
**启动脚本自动完成:**
1. 校验环境变量与凭据完整性;
2. 探测数据库 SSH 隧道连通性(未连通时给出明确操作指引并安全终止);
3. 自动释放 8096 与 8088 端口历史旧进程;
4. 启动 Spring Boot 4 后端,轮询 `/captchaImage` 验证就绪(约 4~6 秒);
5. 启动前端反向代理服务并验证 HTTP 200 就绪;
6. 打印就绪提示与访问入口。
### 2. 停止系统
在演示结束或需要重置时执行:
```bash
./stop_demo.sh
```
**停止脚本自动完成:**
1. 优雅停止前端反向代理进程(释放端口 8088);
2. 优雅停止后端 Spring Boot 进程(释放端口 8096);
3. 清理 Headless Chrome 测试残留进程;
4. 确认所有演示端口已完全释放。
---
## 四、建议的五分钟核心业务演示路线
建议按照培训学员入宿、门锁授权、调宿换锁、退宿撤权的标准业务生命周期进行演示:
```
[1. 管理员登录]
↓
[2. 住宿管理:查询预分配学员] ──> 点击【入住】办理 ──> 状态流转为【在住】
↓
[3. 智能门锁:授权管理] ──> 查看自动生成的人脸授权意图 (待下发/待回执)
↓
[4. 仿真回执确认] ──> 受控驱动网关与门锁回执 ──> 页面刷新为【已生效/下发成功】
↓
[5. 住宿管理:办理调房] ──> 选择新宿舍 (致远楼 102) 提交 ──> 触发新门锁建权与旧门锁撤权
↓
[6. 住宿管理:办理退宿] ──> 点击【退宿】确认 ──> 状态更新为【已退宿】,授权彻底清除
↓
[7. 履历与流水核查] ──> 查看【住宿履历】对话框 & 【命令记录】指令流水
```
### 步骤详解:
1. **登录系统**:
- 打开浏览器访问 `http://127.0.0.1:8088`,输入账号 `admin`,密码 `admin123`,点击登录,进入系统仪表盘首页。
2. **查询并办理入住**:
- 点击左侧菜单【培训管理】->【住宿安排】(或访问 `/train/accommodation`);
- 在学号输入框输入演示学员学号(例如 `S_DEMO_20261013`),点击【搜索】;
- 找到处于“预分配”状态的学员记录,点击操作列的【入住】按钮;
- 在弹出的确认对话框中点击【确定】;
- 页面提示“入住办理成功”,学员住宿状态实时刷新为绿色的【在住】标签。
3. **核查门锁授权意图**:
- 点击左侧菜单【门禁管理】->【授权管理】(或访问 `/iot/auth`);
- 看到系统已根据学员的人脸特征与所分配的宿舍房间(致远楼 101),自动建立门锁授权意图记录。
4. **演示仿真回执确认生效**:
- 在仿真环境下,系统调用受控 Mock 回执端点驱动状态;
- 在授权管理页面点击【搜索】刷新,授权同步状态变更为【已生效】(或【下发成功】),展示端到端联动效果。
5. **办理学员调房**:
- 返回【住宿安排】页面,点击学员右侧的【调房】按钮;
- 在弹出的【办理学员调房】对话框中,目标宿舍选择“致远楼 102”,输入床位号“2号床”,点击【确认调房】;
- 系统执行调房事务:原宿舍记录流转为“已退宿”,新宿舍记录建立并流转为“在住”;
- 后台自动向旧门锁下发撤权指令,向新门锁下发建权指令。
6. **办理退宿**:
- 在【住宿安排】页面中,点击学员所在行的【退宿】按钮,在确认框中点击【确定】;
- 提示“退宿办理成功”,住宿状态更新为红色的【已退宿】标签。
7. **查看历史履历与指令流水**:
- 点击该行操作列的【住宿履历】按钮,弹出【学员历史住宿记录】对话框,清晰展示从预分配、调房退宿到最终退宿的完整时间轴;
- 点击左侧菜单【门禁管理】->【命令记录】(或访问 `/iot/command`),查看全流程自动生成的授权下发(0011)与清除授权(0012)指令流水,证明全链路具备完整审计溯源能力。
---
## 五、真实业务流程 vs 仿真(Mock)环节说明
为了确保演示的真实性与合规性,系统严格区分业务逻辑与硬件模拟:
| 业务环节 | 实现方式 | 状态说明 |
| :--- | :--- | :--- |
| **管理员鉴权与 RBAC 权限** | 真实数据库与 Spring Security | 100% 真实执行 |
| **学员基本信息与班级档案** | 真实 Kingbase QA 数据库表 | 100% 真实执行 |
| **住宿全生命周期状态机** | 真实业务 Service 与事务 | 100% 真实执行(预分配/在住/退宿) |
| **住宿调房多阶段事务** | 真实业务 Service | 100% 真实执行(旧记退宿 + 新建在住) |
| **门锁授权意图关联生成** | 真实 IoT 业务桥接器 | 100% 真实执行(自动解析人脸与房间锁映射) |
| **指令流水与审计日志** | 真实 Kingbase `iot_command` 表 | 100% 真实执行,全链路持久化 |
| **前端交互与响应** | 真实 Vue SPA 页面与 Element UI | 100% 真实执行,无静态伪造 |
| **MQTT 指令双端回执** | Mock 仿真驱动(`iot.mqtt.mock=true`) | 仿真模拟网关与门锁硬件回执,隔绝物理设备 |
| **人脸识别特征提取** | 仿真服务 | 仿真特征向量映射,未连接物理人脸终端 |
| **实体门锁物理开锁/状态** | 物理隔离(未接入) | **BLOCKED / HARDWARE_PENDING** |
---
## 六、常见问题排查与快速恢复
### 1. 启动脚本提示 `[BLOCKED] 数据库 SSH 隧道未连接`
- **原因**:本地 14321 端口无法连接到 Kingbase 研发服务器。
- **排查方法**:
1. 检查 SSH 隧道进程:`ps aux | grep 14321`;
2. 重新建立隧道:`ssh -N -L 127.0.0.1:14321:192.168.139.218:4321 wzbmatebook`;
3. 验证端口连通:`nc -z 127.0.0.1 14321`。
### 2. 页面访问提示 502 Bad Gateway
- **原因**:后端 Spring Boot 正在启动中或由于数据库超时启动失败。
- **排查方法**:
1. 查看后端日志:`tail -n 50 backend.log`;
2. 检查是否有 Druid 数据源连接超时异常;
3. 确认后执行 `./stop_demo.sh && ./start_demo.sh` 重启。
### 3. 演示过程中需要重置测试数据
- **方法**:
可直接在工程根目录下执行演示数据预置脚本:
```bash
java -cp RuoYi-Vue-master/ruoyi-admin/target/test-classes:RuoYi-Vue-master/ruoyi-admin/target/ruoyi-admin.jar com.ruoyi.train.PrepareDemoData
```
该命令将自动重置学员 `S_DEMO_20261013` 为初始的“预分配”住宿状态,并清理门锁历史旧授权,无需重启系统即可开始下一轮完整演示。
+47 -47
View File
@@ -1,47 +1,47 @@
###################################################################### ######################################################################
# Build Tools # Build Tools
.gradle .gradle
/build/ /build/
!gradle/wrapper/gradle-wrapper.jar !gradle/wrapper/gradle-wrapper.jar
target/ target/
!.mvn/wrapper/maven-wrapper.jar !.mvn/wrapper/maven-wrapper.jar
###################################################################### ######################################################################
# IDE # IDE
### STS ### ### STS ###
.apt_generated .apt_generated
.classpath .classpath
.factorypath .factorypath
.project .project
.settings .settings
.springBeans .springBeans
### IntelliJ IDEA ### ### IntelliJ IDEA ###
.idea .idea
*.iws *.iws
*.iml *.iml
*.ipr *.ipr
### JRebel ### ### JRebel ###
rebel.xml rebel.xml
### NetBeans ### ### NetBeans ###
nbproject/private/ nbproject/private/
build/* build/*
nbbuild/ nbbuild/
dist/ dist/
nbdist/ nbdist/
.nb-gradle/ .nb-gradle/
###################################################################### ######################################################################
# Others # Others
*.log *.log
*.xml.versionsBackup *.xml.versionsBackup
*.swp *.swp
!*/build/*.java !*/build/*.java
!*/build/*.html !*/build/*.html
!*/build/*.xml !*/build/*.xml
+30 -24
View File
@@ -1,11 +1,11 @@
<p align="center"> <p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png"> <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
</p> </p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.9.1</h1> <h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.9.2</h1>
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4> <h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
<p align="center"> <p align="center">
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a> <a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.9.1-brightgreen.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.9.2-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p> </p>
@@ -13,15 +13,36 @@
若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。 若依是一套全部开源的快速开发平台,毫无保留给个人及企业免费使用。
* 前端采用Vue、Element UI。 * 前端采用Vue、Element(提供 Vue2/Vue3/TS 多版本)。
* 后端采用Spring Boot、Spring Security、Redis & Jwt。 * 后端采用Spring Boot、Spring Security、Redis & Jwt。
* 权限认证使用Jwt,支持多终端认证系统。 * 基于Jwt的Token认证,支持多终端(Web、App、小程序)无缝接入。
* 支持加载动态权限菜单,多方式轻松权限控制。 * 支持加载动态权限菜单,多方式轻松权限控制,细粒度到按钮级别。
* 高效率开发,使用代码生成器可以一键生成前后端代码。 * 内置强大代码生成器,一键生成前后端代码(java、vue、xml、sql),支持 CRUD 下载。
* 提供了技术栈(Vue3 Element Plus Vite)的 [RuoYi-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Vue3)版本,以及技术栈(TypeScript)的 [RuoYi-Vue3-TypeScript](https://gitcode.com/yangzongzhuan/RuoYi-Vue3/tree/typescript)版本,两者保持同步更新。
* 提供了适配 Spring Boot 3 的版本分支 [RuoYi-Vue (springboot3)](https://gitee.com/y_project/RuoYi-Vue/tree/springboot3),以及特定需求的 单应用版本 [RuoYi-Vue-fast](https://gitcode.com/yangzongzhuan/RuoYi-Vue-fast) 与 Oracle数据库版本 [RuoYi-Vue-Oracle](https://gitcode.com/yangzongzhuan/RuoYi-Vue-Oracle),均保持同步更新。
* 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp; * 阿里云折扣场:[点我进入](http://aly.ruoyi.vip),腾讯云秒杀场:[点我进入](http://txy.ruoyi.vip)&nbsp;&nbsp;
# 版本分支
RuoYi-Vue 后端项目提供 Spring Boot 2.x / 3.x / 4.x 多版本分支的并行维护
| 名称 | 说明 | 地址 |
| :---------------- | :------------------------ | :------------------------------------------------------ |
| master 默认分支 | Spring Boot 4.x (JDK 17+) | https://gitee.com/y_project/RuoYi-Vue |
| springboot3 分支 | Spring Boot 3.x (JDK 17+) | https://gitee.com/y_project/RuoYi-Vue/tree/springboot3 |
| springboot2 分支 | Spring Boot 2.x (JDK 8+) | https://gitee.com/y_project/RuoYi-Vue/tree/springboot2 |
RuoYi-Vue 前端项目提供 Vue 2.x / 3.x / JavaScript / TypeScript 版本,均可混用搭配
| 项目名称 | **RuoYi-Vue2** | **RuoYi-Vue3** | **RuoYi-Vue3-TypeScript** |
| :--- | :--- | :--- | :--- |
| **前端框架** | Vue 2 | Vue 3 | Vue 3 |
| **脚本语言** | JavaScript | JavaScript | TypeScript |
| **构建工具** | Vue CLI | Vite | Vite |
| **UI 组件库** | Element UI | Element Plus | Element Plus |
| **状态管理** | Vuex | Pinia | Pinia |
| **路由管理** | Vue Router 3 | Vue Router 4 | Vue Router 4 |
| **核心特点** | 1. 技术栈经典稳定<br>2. 社区资料丰富<br>3. 当前维护重心已转移 | 1. 现代前端技术栈<br>2. 开发体验与性能更优<br>3. 官方主推的活跃版本 | 1. 类型加持,减少沟通成本<br>2. 开发时有提示,效率更高<br>3. 多人协作企业级开发项目 |
| **仓库地址** | [RuoYi-Vue2](https://gitcode.com/yangzongzhuan/RuoYi-Vue2) | [RuoYi-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Vue3) | [RuoYi-Vue3-TypeScript](https://gitcode.com/yangzongzhuan/RuoYi-Vue3/tree/typescript) |
## 内置功能 ## 内置功能
1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。 1. 用户管理:用户是系统操作者,该功能主要完成系统用户配置。
@@ -43,21 +64,6 @@
17. 在线构建器:拖动表单元素生成相应的HTML代码。 17. 在线构建器:拖动表单元素生成相应的HTML代码。
18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。 18. 连接池监视:监视当前系统数据库连接池状态,可进行分析SQL找出系统性能瓶颈。
# 版本对比
RuoYi-Vue 前端项目的三个主要演进版本,方便你直观对比其技术栈差异(并行开发维护)。
| 项目名称 | **RuoYi-Vue** | **RuoYi-Vue3** | **RuoYi-Vue3-TypeScript** |
| :--- | :--- | :--- | :--- |
| **前端框架** | Vue 2 | Vue 3 | Vue 3 |
| **脚本语言** | JavaScript | JavaScript | TypeScript |
| **构建工具** | Vue CLI | Vite | Vite |
| **UI 组件库** | Element UI | Element Plus | Element Plus |
| **状态管理** | Vuex | Pinia | Pinia |
| **路由管理** | Vue Router 3 | Vue Router 4 | Vue Router 4 |
| **核心特点** | 1. 技术栈经典稳定<br>2. 社区资料丰富<br>3. 当前维护重心已转移 | 1. 现代前端技术栈<br>2. 开发体验与性能更优<br>3. 官方主推的活跃版本 | 1. 类型加持,减少沟通成本<br>2. 开发时有提示,效率更高<br>3. 多人协作企业级开发项目 |
| **仓库地址** | [RuoYi-Vue](https://gitee.com/y_project/RuoYi-Vue) | [RuoYi-Vue3](https://gitcode.com/yangzongzhuan/RuoYi-Vue3) | [RuoYi-Vue3-TypeScript](https://gitcode.com/yangzongzhuan/RuoYi-Vue3/tree/typescript) |
## 在线体验 ## 在线体验
- admin/admin123 - admin/admin123
@@ -106,4 +112,4 @@ RuoYi-Vue 前端项目的三个主要演进版本,方便你直观对比其技
## 若依前后端分离交流群 ## 若依前后端分离交流群
QQ群: [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/已满-136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [![加入QQ群](https://img.shields.io/badge/已满-143961921-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [![加入QQ群](https://img.shields.io/badge/已满-174951577-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [![加入QQ群](https://img.shields.io/badge/已满-161281055-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [![加入QQ群](https://img.shields.io/badge/已满-138988063-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [![加入QQ群](https://img.shields.io/badge/已满-151450850-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) [![加入QQ群](https://img.shields.io/badge/已满-224622315-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=F58bgRa-Dp-rsQJThiJqIYv8t4-lWfXh&authKey=UmUs4CVG5OPA1whvsa4uSespOvyd8%2FAr9olEGaWAfdLmfKQk%2FVBp2YU3u2xXXt76&noverify=0&group_code=224622315) [![加入QQ群](https://img.shields.io/badge/已满-287842588-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Nxb2EQ5qozWa218Wbs7zgBnjLSNk_tVT&authKey=obBKXj6SBKgrFTJZx0AqQnIYbNOvBB2kmgwWvGhzxR67RoRr84%2Bus5OadzMcdJl5&noverify=0&group_code=287842588) [![加入QQ群](https://img.shields.io/badge/已满-187944233-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=numtK1M_I4eVd2Gvg8qtbuL8JgX42qNh&authKey=giV9XWMaFZTY%2FqPlmWbkB9g3fi0Ev5CwEtT9Tgei0oUlFFCQLDp4ozWRiVIzubIm&noverify=0&group_code=187944233) [![加入QQ群](https://img.shields.io/badge/已满-228578329-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G6r5KGCaa3pqdbUSXNIgYloyb8e0_L0D&authKey=4w8tF1eGW7%2FedWn%2FHAypQksdrML%2BDHolQSx7094Agm7Luakj9EbfPnSTxSi2T1LQ&noverify=0&group_code=228578329) [![加入QQ群](https://img.shields.io/badge/已满-191164766-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GsOo-OLz53J8y_9TPoO6XXSGNRTgbFxA&authKey=R7Uy%2Feq%2BZsoKNqHvRKhiXpypW7DAogoWapOawUGHokJSBIBIre2%2FoiAZeZBSLuBc&noverify=0&group_code=191164766) [![加入QQ群](https://img.shields.io/badge/已满-174569686-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=PmYavuzsOthVqfdAPbo4uAeIbu7Ttjgc&authKey=p52l8%2FXa4PS1JcEmS3VccKSwOPJUZ1ZfQ69MEKzbrooNUljRtlKjvsXf04bxNp3G&noverify=0&group_code=174569686) [![加入QQ群](https://img.shields.io/badge/127358632-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=M9y5NjAl44lAL_Vh2crmEehZU_PMU6KS&authKey=ZSDz8hEREWSaPuxQV3gEwqGIaGjfRNnkB4rJjf0IvXhrSUGSGwQFmBA%2Boe8HFxyl&noverify=0&group_code=127358632) 点击按钮入群。 QQ群: [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/已满-136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [![加入QQ群](https://img.shields.io/badge/已满-143961921-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [![加入QQ群](https://img.shields.io/badge/已满-174951577-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [![加入QQ群](https://img.shields.io/badge/已满-161281055-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [![加入QQ群](https://img.shields.io/badge/已满-138988063-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [![加入QQ群](https://img.shields.io/badge/已满-151450850-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) [![加入QQ群](https://img.shields.io/badge/已满-224622315-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=F58bgRa-Dp-rsQJThiJqIYv8t4-lWfXh&authKey=UmUs4CVG5OPA1whvsa4uSespOvyd8%2FAr9olEGaWAfdLmfKQk%2FVBp2YU3u2xXXt76&noverify=0&group_code=224622315) [![加入QQ群](https://img.shields.io/badge/已满-287842588-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Nxb2EQ5qozWa218Wbs7zgBnjLSNk_tVT&authKey=obBKXj6SBKgrFTJZx0AqQnIYbNOvBB2kmgwWvGhzxR67RoRr84%2Bus5OadzMcdJl5&noverify=0&group_code=287842588) [![加入QQ群](https://img.shields.io/badge/已满-187944233-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=numtK1M_I4eVd2Gvg8qtbuL8JgX42qNh&authKey=giV9XWMaFZTY%2FqPlmWbkB9g3fi0Ev5CwEtT9Tgei0oUlFFCQLDp4ozWRiVIzubIm&noverify=0&group_code=187944233) [![加入QQ群](https://img.shields.io/badge/已满-228578329-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G6r5KGCaa3pqdbUSXNIgYloyb8e0_L0D&authKey=4w8tF1eGW7%2FedWn%2FHAypQksdrML%2BDHolQSx7094Agm7Luakj9EbfPnSTxSi2T1LQ&noverify=0&group_code=228578329) [![加入QQ群](https://img.shields.io/badge/已满-191164766-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GsOo-OLz53J8y_9TPoO6XXSGNRTgbFxA&authKey=R7Uy%2Feq%2BZsoKNqHvRKhiXpypW7DAogoWapOawUGHokJSBIBIre2%2FoiAZeZBSLuBc&noverify=0&group_code=191164766) [![加入QQ群](https://img.shields.io/badge/已满-174569686-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=PmYavuzsOthVqfdAPbo4uAeIbu7Ttjgc&authKey=p52l8%2FXa4PS1JcEmS3VccKSwOPJUZ1ZfQ69MEKzbrooNUljRtlKjvsXf04bxNp3G&noverify=0&group_code=174569686) [![加入QQ群](https://img.shields.io/badge/已满-127358632-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=M9y5NjAl44lAL_Vh2crmEehZU_PMU6KS&authKey=ZSDz8hEREWSaPuxQV3gEwqGIaGjfRNnkB4rJjf0IvXhrSUGSGwQFmBA%2Boe8HFxyl&noverify=0&group_code=127358632) [![加入QQ群](https://img.shields.io/badge/113071109-blue.svg)](http://qm.qq.com/cgi-bin/qmLine truncated
+11 -11
View File
@@ -1,12 +1,12 @@
@echo off @echo off
echo. echo.
echo [信息] 清理工程target生成路径。 echo [信息] 清理工程target生成路径。
echo. echo.
%~d0 %~d0
cd %~dp0 cd %~dp0
cd .. cd ..
call mvn clean call mvn clean
pause pause
+11 -11
View File
@@ -1,12 +1,12 @@
@echo off @echo off
echo. echo.
echo [信息] 打包Web工程,生成war/jar包文件。 echo [信息] 打包Web工程,生成war/jar包文件。
echo. echo.
%~d0 %~d0
cd %~dp0 cd %~dp0
cd .. cd ..
call mvn clean package -Dmaven.test.skip=true call mvn clean package -Dmaven.test.skip=true
pause pause
+13 -13
View File
@@ -1,14 +1,14 @@
@echo off @echo off
echo. echo.
echo [信息] 使用Jar命令运行Web工程。 echo [信息] 使用Jar命令运行Web工程。
echo. echo.
cd %~dp0 cd %~dp0
cd ../ruoyi-admin/target cd ../ruoyi-admin/target
set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
java -jar %JAVA_OPTS% ruoyi-admin.jar java -jar %JAVA_OPTS% ruoyi-admin.jar
cd bin cd bin
pause pause
+264 -355
View File
@@ -1,356 +1,265 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.9.1</version> <version>3.9.2</version>
<name>ruoyi</name> <name>ruoyi</name>
<url>http://www.ruoyi.vip</url> <url>http://www.ruoyi.vip</url>
<description>若依管理系统</description> <description>若依管理系统</description>
<properties> <properties>
<ruoyi.version>3.9.1</ruoyi.version> <ruoyi.version>3.9.2</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<maven.compiler.encoding>UTF-8</maven.compiler.encoding> <java.version>17</java.version>
<java.version>1.8</java.version> <spring-boot.version>4.1.0</spring-boot.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> <mybatis-spring-boot.version>4.1.0</mybatis-spring-boot.version>
<spring-boot.version>2.5.15</spring-boot.version> <druid.version>1.2.28</druid.version>
<druid.version>1.2.27</druid.version> <yauaa.version>8.2.0</yauaa.version>
<yauaa.version>7.32.0</yauaa.version> <kaptcha.version>2.3.3</kaptcha.version>
<swagger.version>3.0.0</swagger.version> <pagehelper.boot.version>4.1.1</pagehelper.boot.version>
<kaptcha.version>2.3.3</kaptcha.version> <fastjson.version>2.0.64</fastjson.version>
<pagehelper.boot.version>1.4.7</pagehelper.boot.version> <oshi.version>7.4.4</oshi.version>
<fastjson.version>2.0.60</fastjson.version> <commons.io.version>2.22.0</commons.io.version>
<oshi.version>6.9.1</oshi.version> <poi.version>5.5.1</poi.version>
<commons.io.version>2.21.0</commons.io.version> <velocity.version>2.3</velocity.version>
<poi.version>4.1.2</poi.version> <jwt.version>0.9.1</jwt.version>
<velocity.version>2.3</velocity.version> <jaxb-api.version>2.3.1</jaxb-api.version>
<jwt.version>0.9.1</jwt.version> <springdoc.version>3.1.0</springdoc.version>
<!-- override dependency version --> <kingbase.version>9.0.0</kingbase.version>
<tomcat.version>9.0.112</tomcat.version> <paho.version>1.2.5</paho.version>
<logback.version>1.2.13</logback.version> </properties>
<spring-security.version>5.7.14</spring-security.version>
<spring-framework.version>5.3.39</spring-framework.version> <!-- 依赖声明 -->
</properties> <dependencyManagement>
<dependencies>
<!-- 依赖声明 -->
<dependencyManagement> <!-- SpringBoot的依赖配置 -->
<dependencies> <dependency>
<groupId>org.springframework.boot</groupId>
<!-- 覆盖SpringFramework的依赖配置--> <artifactId>spring-boot-dependencies</artifactId>
<dependency> <version>${spring-boot.version}</version>
<groupId>org.springframework</groupId> <type>pom</type>
<artifactId>spring-framework-bom</artifactId> <scope>import</scope>
<version>${spring-framework.version}</version> </dependency>
<type>pom</type>
<scope>import</scope> <!-- 阿里数据库连接池 -->
</dependency> <dependency>
<groupId>com.alibaba</groupId>
<!-- 覆盖SpringSecurity的依赖配置--> <artifactId>druid-spring-boot-4-starter</artifactId>
<dependency> <version>${druid.version}</version>
<groupId>org.springframework.security</groupId> </dependency>
<artifactId>spring-security-bom</artifactId>
<version>${spring-security.version}</version> <!-- 解析客户端操作系统、浏览器等 -->
<type>pom</type> <dependency>
<scope>import</scope> <groupId>nl.basjes.parse.useragent</groupId>
</dependency> <artifactId>yauaa</artifactId>
<version>${yauaa.version}</version>
<!-- SpringBoot的依赖配置--> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId> <!-- pagehelper 分页插件 -->
<artifactId>spring-boot-dependencies</artifactId> <dependency>
<version>${spring-boot.version}</version> <groupId>com.github.pagehelper</groupId>
<type>pom</type> <artifactId>pagehelper-spring-boot-starter</artifactId>
<scope>import</scope> <version>${pagehelper.boot.version}</version>
</dependency> </dependency>
<!-- 覆盖logback的依赖配置--> <dependency>
<dependency> <groupId>org.mybatis.spring.boot</groupId>
<groupId>ch.qos.logback</groupId> <artifactId>mybatis-spring-boot-starter</artifactId>
<artifactId>logback-core</artifactId> <version>${mybatis-spring-boot.version}</version>
<version>${logback.version}</version> </dependency>
</dependency>
<dependency>
<dependency> <groupId>javax.xml.bind</groupId>
<groupId>ch.qos.logback</groupId> <artifactId>jaxb-api</artifactId>
<artifactId>logback-classic</artifactId> <version>${jaxb-api.version}</version>
<version>${logback.version}</version> </dependency>
</dependency>
<!-- 获取系统信息 -->
<!-- 覆盖tomcat的依赖配置--> <dependency>
<dependency> <groupId>com.github.oshi</groupId>
<groupId>org.apache.tomcat.embed</groupId> <artifactId>oshi-core</artifactId>
<artifactId>tomcat-embed-core</artifactId> <version>${oshi.version}</version>
<version>${tomcat.version}</version> </dependency>
</dependency>
<!-- spring-doc -->
<dependency> <dependency>
<groupId>org.apache.tomcat.embed</groupId> <groupId>org.springdoc</groupId>
<artifactId>tomcat-embed-el</artifactId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${tomcat.version}</version> <version>${springdoc.version}</version>
</dependency> </dependency>
<dependency> <!-- io常用工具类 -->
<groupId>org.apache.tomcat.embed</groupId> <dependency>
<artifactId>tomcat-embed-websocket</artifactId> <groupId>commons-io</groupId>
<version>${tomcat.version}</version> <artifactId>commons-io</artifactId>
</dependency> <version>${commons.io.version}</version>
</dependency>
<!-- 阿里数据库连接池 -->
<dependency> <!-- excel工具 -->
<groupId>com.alibaba</groupId> <dependency>
<artifactId>druid-spring-boot-starter</artifactId> <groupId>org.apache.poi</groupId>
<version>${druid.version}</version> <artifactId>poi-ooxml</artifactId>
</dependency> <version>${poi.version}</version>
</dependency>
<!-- 解析客户端操作系统、浏览器等 -->
<dependency> <!-- velocity代码生成使用模板 -->
<groupId>nl.basjes.parse.useragent</groupId> <dependency>
<artifactId>yauaa</artifactId> <groupId>org.apache.velocity</groupId>
<version>${yauaa.version}</version> <artifactId>velocity-engine-core</artifactId>
</dependency> <version>${velocity.version}</version>
</dependency>
<!-- pagehelper 分页插件 -->
<dependency> <!-- 阿里JSON解析器 -->
<groupId>com.github.pagehelper</groupId> <dependency>
<artifactId>pagehelper-spring-boot-starter</artifactId> <groupId>com.alibaba.fastjson2</groupId>
<version>${pagehelper.boot.version}</version> <artifactId>fastjson2</artifactId>
</dependency> <version>${fastjson.version}</version>
</dependency>
<!-- 获取系统信息 -->
<dependency> <!-- Token生成与解析-->
<groupId>com.github.oshi</groupId> <dependency>
<artifactId>oshi-core</artifactId> <groupId>io.jsonwebtoken</groupId>
<version>${oshi.version}</version> <artifactId>jjwt</artifactId>
</dependency> <version>${jwt.version}</version>
</dependency>
<!-- Swagger3依赖 -->
<dependency> <!-- 验证码 -->
<groupId>io.springfox</groupId> <dependency>
<artifactId>springfox-boot-starter</artifactId> <groupId>pro.fessional</groupId>
<version>${swagger.version}</version> <artifactId>kaptcha</artifactId>
<exclusions> <version>${kaptcha.version}</version>
<exclusion> </dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-models</artifactId> <!-- KingbaseES(人大金仓)驱动:官方未提供公网 Maven 仓库,驱动包直接放置在
</exclusion> ruoyi-admin/lib 目录,由 ruoyi-admin 模块的 kingbase profile 以 system scope 引入。
</exclusions> 若 jar 文件名或版本变更,请同步修改 kingbase.version 属性及 ruoyi-admin 中的 systemPath。 -->
</dependency> <dependency>
<groupId>cn.com.kingbase</groupId>
<!-- io常用工具类 --> <artifactId>kingbase8</artifactId>
<dependency> <version>${kingbase.version}</version>
<groupId>commons-io</groupId> </dependency>
<artifactId>commons-io</artifactId>
<version>${commons.io.version}</version> <!-- Eclipse Paho MQTT客户端 -->
</dependency> <dependency>
<groupId>org.eclipse.paho</groupId>
<!-- excel工具 --> <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
<dependency> <version>${paho.version}</version>
<groupId>org.apache.poi</groupId> </dependency>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version> <!-- 定时任务-->
</dependency> <dependency>
<groupId>com.ruoyi</groupId>
<!-- velocity代码生成使用模板 --> <artifactId>ruoyi-quartz</artifactId>
<dependency> <version>${ruoyi.version}</version>
<groupId>org.apache.velocity</groupId> </dependency>
<artifactId>velocity-engine-core</artifactId>
<version>${velocity.version}</version> <!-- 代码生成-->
</dependency> <dependency>
<groupId>com.ruoyi</groupId>
<!-- 阿里JSON解析器 --> <artifactId>ruoyi-generator</artifactId>
<dependency> <version>${ruoyi.version}</version>
<groupId>com.alibaba.fastjson2</groupId> </dependency>
<artifactId>fastjson2</artifactId>
<version>${fastjson.version}</version> <!-- 核心模块-->
</dependency> <dependency>
<groupId>com.ruoyi</groupId>
<!-- Token生成与解析--> <artifactId>ruoyi-framework</artifactId>
<dependency> <version>${ruoyi.version}</version>
<groupId>io.jsonwebtoken</groupId> </dependency>
<artifactId>jjwt</artifactId>
<version>${jwt.version}</version> <!-- 系统模块-->
</dependency> <dependency>
<groupId>com.ruoyi</groupId>
<dependency> <artifactId>ruoyi-system</artifactId>
<groupId>org.apache.logging.log4j</groupId> <version>${ruoyi.version}</version>
<artifactId>log4j-api</artifactId> </dependency>
<version>2.15.0</version>
</dependency> <!-- IOT设备接入-->
<dependency> <dependency>
<groupId>org.apache.logging.log4j</groupId> <groupId>com.ruoyi</groupId>
<artifactId>log4j-to-slf4j</artifactId> <artifactId>ruoyi-iot</artifactId>
<version>2.15.0</version> <version>${ruoyi.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.kingbase</groupId> <groupId>com.ruoyi</groupId>
<artifactId>kingbase8</artifactId> <artifactId>ruoyi-train</artifactId>
<version>8.6.0</version> <version>${ruoyi.version}</version>
</dependency> </dependency>
<dependency> <!-- 通用工具-->
<groupId>org.springframework.boot</groupId> <dependency>
<artifactId>spring-boot-devtools</artifactId> <groupId>com.ruoyi</groupId>
<version>2.2.13.RELEASE</version> <artifactId>ruoyi-common</artifactId>
<scope>runtime</scope> <version>${ruoyi.version}</version>
<optional>true</optional> </dependency>
</dependency>
</dependencies>
<!-- 验证码 --> </dependencyManagement>
<dependency>
<groupId>pro.fessional</groupId> <modules>
<artifactId>kaptcha</artifactId> <module>ruoyi-admin</module>
<version>${kaptcha.version}</version> <module>ruoyi-framework</module>
</dependency> <module>ruoyi-system</module>
<module>ruoyi-quartz</module>
<!-- 定时任务--> <module>ruoyi-generator</module>
<dependency> <module>ruoyi-common</module>
<groupId>com.ruoyi</groupId> <module>ruoyi-iot</module>
<artifactId>ruoyi-quartz</artifactId> <module>ruoyi-train</module>
<version>${ruoyi.version}</version> </modules>
</dependency> <packaging>pom</packaging>
<!-- 代码生成--> <build>
<dependency> <plugins>
<groupId>com.ruoyi</groupId> <plugin>
<artifactId>ruoyi-generator</artifactId> <groupId>org.apache.maven.plugins</groupId>
<version>${ruoyi.version}</version> <artifactId>maven-compiler-plugin</artifactId>
</dependency> <version>3.13.0</version>
<configuration>
<!-- 核心模块--> <parameters>true</parameters>
<dependency> <source>${java.version}</source>
<groupId>com.ruoyi</groupId> <target>${java.version}</target>
<artifactId>ruoyi-framework</artifactId> <encoding>${project.build.sourceEncoding}</encoding>
<version>${ruoyi.version}</version> </configuration>
</dependency> </plugin>
<plugin>
<!-- 系统模块--> <groupId>org.springframework.boot</groupId>
<dependency> <artifactId>spring-boot-maven-plugin</artifactId>
<groupId>com.ruoyi</groupId> <version>${spring-boot.version}</version>
<artifactId>ruoyi-system</artifactId> </plugin>
<version>${ruoyi.version}</version> </plugins>
</dependency> </build>
<!-- 通用工具--> <repositories>
<dependency> <repository>
<groupId>com.ruoyi</groupId> <id>public</id>
<artifactId>ruoyi-common</artifactId> <name>aliyun nexus</name>
<version>${ruoyi.version}</version> <url>https://maven.aliyun.com/repository/public</url>
</dependency> <releases>
<enabled>true</enabled>
<!-- 业务模块--> </releases>
<dependency> </repository>
<groupId>com.ruoyi</groupId> </repositories>
<artifactId>ruoyi-train</artifactId>
<version>${ruoyi.version}</version> <pluginRepositories>
</dependency> <pluginRepository>
<id>public</id>
</dependencies> <name>aliyun nexus</name>
</dependencyManagement> <url>https://maven.aliyun.com/repository/public</url>
<releases>
<modules> <enabled>true</enabled>
<module>ruoyi-admin</module> </releases>
<module>ruoyi-framework</module> <snapshots>
<module>ruoyi-system</module> <enabled>false</enabled>
<module>ruoyi-quartz</module> </snapshots>
<module>ruoyi-generator</module> </pluginRepository>
<module>ruoyi-common</module> </pluginRepositories>
<module>ruoyi-train</module>
</modules>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- 输出目录 -->
<outputDirectory>D:\maven_repository\com\kingbase\kingbase8\8.6.0</outputDirectory>
<!-- 包含运行时依赖 -->
<includeScope>runtime</includeScope>
<!-- 包含编译时依赖 -->
<includeScope>compile</includeScope>
<!-- 可选:包含指定的 groupId -->
<includeGroupIds>com.kingbase</includeGroupIds>
<!-- 可选:包含指定的 artifactId -->
<includeArtifactIds>kingbase8</includeArtifactIds>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.yml</include>
<include>**/*.vm</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.yml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
<repositories>
<repository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>public</id>
<name>aliyun nexus</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</project> </project>
+166 -140
View File
@@ -1,140 +1,166 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.9.1</version> <version>3.9.2</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>
<artifactId>ruoyi-admin</artifactId> <artifactId>ruoyi-admin</artifactId>
<description> <description>
web服务入口 web服务入口
</description> </description>
<dependencies> <dependencies>
<!-- spring-boot-devtools --> <!-- spring-boot-devtools -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId> <artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 --> <optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency> </dependency>
<!-- swagger3--> <!-- spring-doc -->
<dependency> <dependency>
<groupId>io.springfox</groupId> <groupId>org.springdoc</groupId>
<artifactId>springfox-boot-starter</artifactId> <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency> </dependency>
<!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 --> <!-- 核心模块-->
<dependency> <dependency>
<groupId>io.swagger</groupId> <groupId>com.ruoyi</groupId>
<artifactId>swagger-models</artifactId> <artifactId>ruoyi-framework</artifactId>
<version>1.6.2</version> </dependency>
</dependency>
<!-- 定时任务-->
<dependency> <dependency>
<groupId>com.kingbase</groupId> <groupId>com.ruoyi</groupId>
<artifactId>kingbase8</artifactId> <artifactId>ruoyi-quartz</artifactId>
<version>8.6.0</version> </dependency>
</dependency>
<!-- 代码生成-->
<!-- Mysql驱动包 --> <dependency>
<dependency> <groupId>com.ruoyi</groupId>
<groupId>mysql</groupId> <artifactId>ruoyi-generator</artifactId>
<artifactId>mysql-connector-java</artifactId> </dependency>
</dependency>
<!-- IOT设备接入-->
<!-- 核心模块--> <dependency>
<dependency> <groupId>com.ruoyi</groupId>
<groupId>com.ruoyi</groupId> <artifactId>ruoyi-iot</artifactId>
<artifactId>ruoyi-framework</artifactId> <version>3.9.2</version>
</dependency> </dependency>
<!-- 定时任务--> <dependency>
<dependency> <groupId>com.ruoyi</groupId>
<groupId>com.ruoyi</groupId> <artifactId>ruoyi-train</artifactId>
<artifactId>ruoyi-quartz</artifactId> <version>3.9.2</version>
</dependency> </dependency>
<!-- 代码生成--> <dependency>
<dependency> <groupId>org.springframework.boot</groupId>
<groupId>com.ruoyi</groupId> <artifactId>spring-boot-starter-test</artifactId>
<artifactId>ruoyi-generator</artifactId> <scope>test</scope>
</dependency> </dependency>
<!-- 业务模块--> <dependency>
<dependency> <groupId>junit</groupId>
<groupId>com.ruoyi</groupId> <artifactId>junit</artifactId>
<artifactId>ruoyi-train</artifactId> <version>4.13.2</version>
</dependency> <scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId> <dependency>
<artifactId>junit</artifactId> <groupId>org.junit.vintage</groupId>
<version>4.13.2</version> <artifactId>junit-vintage-engine</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
</dependencies> </dependencies>
<build> <!-- 默认使用 KingbaseES,切换到 MySQL 时使用:mvn -P mysql -->
<plugins> <profiles>
<plugin> <profile>
<groupId>org.springframework.boot</groupId> <id>mysql</id>
<artifactId>spring-boot-maven-plugin</artifactId> <dependencies>
<version>2.5.15</version> <dependency>
<configuration> <groupId>com.mysql</groupId>
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 --> <artifactId>mysql-connector-j</artifactId>
</configuration> </dependency>
<executions> </dependencies>
<execution> </profile>
<goals>
<goal>repackage</goal> <!-- KingbaseES(人大金仓):驱动包置于 ruoyi-admin/lib 目录,直接按文件路径引入 -->
</goals> <profile>
</execution> <id>kingbase</id>
</executions> <activation>
</plugin> <activeByDefault>true</activeByDefault>
<plugin> </activation>
<groupId>org.apache.maven.plugins</groupId> <dependencies>
<artifactId>maven-war-plugin</artifactId> <dependency>
<version>3.1.0</version> <groupId>cn.com.kingbase</groupId>
<configuration> <artifactId>kingbase8</artifactId>
<failOnMissingWebXml>false</failOnMissingWebXml> <scope>system</scope>
<warName>${project.artifactId}</warName> <systemPath>${project.basedir}/lib/kingbase8-${kingbase.version}.jar</systemPath>
</configuration> </dependency>
</plugin> </dependencies>
<plugin> <build>
<groupId>org.apache.maven.plugins</groupId> <plugins>
<artifactId>maven-dependency-plugin</artifactId> <plugin>
<executions> <groupId>org.apache.maven.plugins</groupId>
<execution> <artifactId>maven-war-plugin</artifactId>
<id>copy-dependencies</id> <configuration>
<phase>package</phase> <!-- 打 war 包时把外部驱动一起放进 WEB-INF/lib -->
<goals> <webResources>
<goal>copy-dependencies</goal> <resource>
</goals> <directory>${project.basedir}/lib</directory>
<configuration> <targetPath>WEB-INF/lib</targetPath>
<!-- 输出目录 --> <filtering>false</filtering>
<outputDirectory>D:\maven_repository\com\kingbase\kingbase8\8.6.0</outputDirectory> <includes>
<!-- 包含运行时依赖 --> <include>kingbase8-${kingbase.version}.jar</include>
<includeScope>runtime</includeScope> </includes>
<!-- 包含编译时依赖 --> </resource>
<includeScope>compile</includeScope> </webResources>
<!-- 可选:包含指定的 groupId --> </configuration>
<includeGroupIds>com.kingbase</includeGroupIds> </plugin>
<!-- 可选:包含指定的 artifactId --> </plugins>
<includeArtifactIds>kingbase8</includeArtifactIds> </build>
</configuration> </profile>
</execution> </profiles>
</executions>
</plugin> <build>
</plugins> <plugins>
<finalName>${project.artifactId}</finalName> <plugin>
</build> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</project> <configuration>
<addResources>true</addResources>
<!-- KingbaseES 等 system scope 驱动需要打进可执行 jar -->
<includeSystemScope>true</includeSystemScope>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
<warName>${project.artifactId}</warName>
</configuration>
</plugin>
</plugins>
<finalName>${project.artifactId}</finalName>
</build>
</project>
@@ -1,30 +1,30 @@
package com.ruoyi; package com.ruoyi;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.jdbc.autoconfigure.DataSourceAutoConfiguration;
/** /**
* 启动程序 * 启动程序
* *
* @author ruoyi * @author ruoyi
*/ */
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class RuoYiApplication public class RuoYiApplication
{ {
public static void main(String[] args) public static void main(String[] args)
{ {
// System.setProperty("spring.devtools.restart.enabled", "false"); // System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(RuoYiApplication.class, args); SpringApplication.run(RuoYiApplication.class, args);
System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" + System.out.println("(♥◠‿◠)ノ゙ 若依启动成功 ლ(´ڡ`ლ)゙ \n" +
" .-------. ____ __ \n" + " .-------. ____ __ \n" +
" | _ _ \\ \\ \\ / / \n" + " | _ _ \\ \\ \\ / / \n" +
" | ( ' ) | \\ _. / ' \n" + " | ( ' ) | \\ _. / ' \n" +
" |(_ o _) / _( )_ .' \n" + " |(_ o _) / _( )_ .' \n" +
" | (_,_).' __ ___(_ o _)' \n" + " | (_,_).' __ ___(_ o _)' \n" +
" | |\\ \\ | || |(_,_)' \n" + " | |\\ \\ | || |(_,_)' \n" +
" | | \\ `' /| `-' / \n" + " | | \\ `' /| `-' / \n" +
" | | \\ / \\ / \n" + " | | \\ / \\ / \n" +
" ''-' `'-' `-..-' "); " ''-' `'-' `-..-' ");
} }
} }
@@ -1,18 +1,18 @@
package com.ruoyi; package com.ruoyi;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
/** /**
* web容器中进行部署 * web容器中进行部署
* *
* @author ruoyi * @author ruoyi
*/ */
public class RuoYiServletInitializer extends SpringBootServletInitializer public class RuoYiServletInitializer extends SpringBootServletInitializer
{ {
@Override @Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) protected SpringApplicationBuilder configure(SpringApplicationBuilder application)
{ {
return application.sources(RuoYiApplication.class); return application.sources(RuoYiApplication.class);
} }
} }
@@ -1,94 +1,94 @@
package com.ruoyi.web.controller.common; package com.ruoyi.web.controller.common;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.annotation.Resource; import jakarta.annotation.Resource;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FastByteArrayOutputStream; import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.google.code.kaptcha.Producer; import com.google.code.kaptcha.Producer;
import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.sign.Base64; import com.ruoyi.common.utils.sign.Base64;
import com.ruoyi.common.utils.uuid.IdUtils; import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysConfigService;
/** /**
* 验证码操作处理 * 验证码操作处理
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
public class CaptchaController public class CaptchaController
{ {
@Resource(name = "captchaProducer") @Resource(name = "captchaProducer")
private Producer captchaProducer; private Producer captchaProducer;
@Resource(name = "captchaProducerMath") @Resource(name = "captchaProducerMath")
private Producer captchaProducerMath; private Producer captchaProducerMath;
@Autowired @Autowired
private RedisCache redisCache; private RedisCache redisCache;
@Autowired @Autowired
private ISysConfigService configService; private ISysConfigService configService;
/** /**
* 生成验证码 * 生成验证码
*/ */
@GetMapping("/captchaImage") @GetMapping("/captchaImage")
public AjaxResult getCode(HttpServletResponse response) throws IOException public AjaxResult getCode(HttpServletResponse response) throws IOException
{ {
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
boolean captchaEnabled = configService.selectCaptchaEnabled(); boolean captchaEnabled = configService.selectCaptchaEnabled();
ajax.put("captchaEnabled", captchaEnabled); ajax.put("captchaEnabled", captchaEnabled);
if (!captchaEnabled) if (!captchaEnabled)
{ {
return ajax; return ajax;
} }
// 保存验证码信息 // 保存验证码信息
String uuid = IdUtils.simpleUUID(); String uuid = IdUtils.simpleUUID();
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid; String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + uuid;
String capStr = null, code = null; String capStr = null, code = null;
BufferedImage image = null; BufferedImage image = null;
// 生成验证码 // 生成验证码
String captchaType = RuoYiConfig.getCaptchaType(); String captchaType = RuoYiConfig.getCaptchaType();
if ("math".equals(captchaType)) if ("math".equals(captchaType))
{ {
String capText = captchaProducerMath.createText(); String capText = captchaProducerMath.createText();
capStr = capText.substring(0, capText.lastIndexOf("@")); capStr = capText.substring(0, capText.lastIndexOf("@"));
code = capText.substring(capText.lastIndexOf("@") + 1); code = capText.substring(capText.lastIndexOf("@") + 1);
image = captchaProducerMath.createImage(capStr); image = captchaProducerMath.createImage(capStr);
} }
else if ("char".equals(captchaType)) else if ("char".equals(captchaType))
{ {
capStr = code = captchaProducer.createText(); capStr = code = captchaProducer.createText();
image = captchaProducer.createImage(capStr); image = captchaProducer.createImage(capStr);
} }
redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES); redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
// 转换流信息写出 // 转换流信息写出
FastByteArrayOutputStream os = new FastByteArrayOutputStream(); FastByteArrayOutputStream os = new FastByteArrayOutputStream();
try try
{ {
ImageIO.write(image, "jpg", os); ImageIO.write(image, "jpg", os);
} }
catch (IOException e) catch (IOException e)
{ {
return AjaxResult.error(e.getMessage()); return AjaxResult.error(e.getMessage());
} }
ajax.put("uuid", uuid); ajax.put("uuid", uuid);
ajax.put("img", Base64.encode(os.toByteArray())); ajax.put("img", Base64.encode(os.toByteArray()));
return ajax; return ajax;
} }
} }
@@ -1,162 +1,162 @@
package com.ruoyi.web.controller.common; package com.ruoyi.web.controller.common;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils; import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils; import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.framework.config.ServerConfig; import com.ruoyi.framework.config.ServerConfig;
/** /**
* 通用请求处理 * 通用请求处理
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/common") @RequestMapping("/common")
public class CommonController public class CommonController
{ {
private static final Logger log = LoggerFactory.getLogger(CommonController.class); private static final Logger log = LoggerFactory.getLogger(CommonController.class);
@Autowired @Autowired
private ServerConfig serverConfig; private ServerConfig serverConfig;
private static final String FILE_DELIMITER = ","; private static final String FILE_DELIMITER = ",";
/** /**
* 通用下载请求 * 通用下载请求
* *
* @param fileName 文件名称 * @param fileName 文件名称
* @param delete 是否删除 * @param delete 是否删除
*/ */
@GetMapping("/download") @GetMapping("/download")
public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request) public void fileDownload(String fileName, Boolean delete, HttpServletResponse response, HttpServletRequest request)
{ {
try try
{ {
if (!FileUtils.checkAllowDownload(fileName)) if (!FileUtils.checkAllowDownload(fileName))
{ {
throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName)); throw new Exception(StringUtils.format("文件名称({})非法,不允许下载。 ", fileName));
} }
String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1); String realFileName = System.currentTimeMillis() + fileName.substring(fileName.indexOf("_") + 1);
String filePath = RuoYiConfig.getDownloadPath() + fileName; String filePath = RuoYiConfig.getDownloadPath() + fileName;
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, realFileName); FileUtils.setAttachmentResponseHeader(response, realFileName);
FileUtils.writeBytes(filePath, response.getOutputStream()); FileUtils.writeBytes(filePath, response.getOutputStream());
if (delete) if (delete)
{ {
FileUtils.deleteFile(filePath); FileUtils.deleteFile(filePath);
} }
} }
catch (Exception e) catch (Exception e)
{ {
log.error("下载文件失败", e); log.error("下载文件失败", e);
} }
} }
/** /**
* 通用上传请求(单个) * 通用上传请求(单个)
*/ */
@PostMapping("/upload") @PostMapping("/upload")
public AjaxResult uploadFile(MultipartFile file) throws Exception public AjaxResult uploadFile(MultipartFile file) throws Exception
{ {
try try
{ {
// 上传文件路径 // 上传文件路径
String filePath = RuoYiConfig.getUploadPath(); String filePath = RuoYiConfig.getUploadPath();
// 上传并返回新文件名称 // 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file); String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName; String url = serverConfig.getUrl() + fileName;
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
ajax.put("url", url); ajax.put("url", url);
ajax.put("fileName", fileName); ajax.put("fileName", fileName);
ajax.put("newFileName", FileUtils.getName(fileName)); ajax.put("newFileName", FileUtils.getName(fileName));
ajax.put("originalFilename", file.getOriginalFilename()); ajax.put("originalFilename", file.getOriginalFilename());
return ajax; return ajax;
} }
catch (Exception e) catch (Exception e)
{ {
return AjaxResult.error(e.getMessage()); return AjaxResult.error(e.getMessage());
} }
} }
/** /**
* 通用上传请求(多个) * 通用上传请求(多个)
*/ */
@PostMapping("/uploads") @PostMapping("/uploads")
public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception public AjaxResult uploadFiles(List<MultipartFile> files) throws Exception
{ {
try try
{ {
// 上传文件路径 // 上传文件路径
String filePath = RuoYiConfig.getUploadPath(); String filePath = RuoYiConfig.getUploadPath();
List<String> urls = new ArrayList<String>(); List<String> urls = new ArrayList<String>();
List<String> fileNames = new ArrayList<String>(); List<String> fileNames = new ArrayList<String>();
List<String> newFileNames = new ArrayList<String>(); List<String> newFileNames = new ArrayList<String>();
List<String> originalFilenames = new ArrayList<String>(); List<String> originalFilenames = new ArrayList<String>();
for (MultipartFile file : files) for (MultipartFile file : files)
{ {
// 上传并返回新文件名称 // 上传并返回新文件名称
String fileName = FileUploadUtils.upload(filePath, file); String fileName = FileUploadUtils.upload(filePath, file);
String url = serverConfig.getUrl() + fileName; String url = serverConfig.getUrl() + fileName;
urls.add(url); urls.add(url);
fileNames.add(fileName); fileNames.add(fileName);
newFileNames.add(FileUtils.getName(fileName)); newFileNames.add(FileUtils.getName(fileName));
originalFilenames.add(file.getOriginalFilename()); originalFilenames.add(file.getOriginalFilename());
} }
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
ajax.put("urls", StringUtils.join(urls, FILE_DELIMITER)); ajax.put("urls", StringUtils.join(urls, FILE_DELIMITER));
ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMITER)); ajax.put("fileNames", StringUtils.join(fileNames, FILE_DELIMITER));
ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMITER)); ajax.put("newFileNames", StringUtils.join(newFileNames, FILE_DELIMITER));
ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMITER)); ajax.put("originalFilenames", StringUtils.join(originalFilenames, FILE_DELIMITER));
return ajax; return ajax;
} }
catch (Exception e) catch (Exception e)
{ {
return AjaxResult.error(e.getMessage()); return AjaxResult.error(e.getMessage());
} }
} }
/** /**
* 本地资源通用下载 * 本地资源通用下载
*/ */
@GetMapping("/download/resource") @GetMapping("/download/resource")
public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response) public void resourceDownload(String resource, HttpServletRequest request, HttpServletResponse response)
throws Exception throws Exception
{ {
try try
{ {
if (!FileUtils.checkAllowDownload(resource)) if (!FileUtils.checkAllowDownload(resource))
{ {
throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource)); throw new Exception(StringUtils.format("资源文件({})非法,不允许下载。 ", resource));
} }
// 本地资源路径 // 本地资源路径
String localPath = RuoYiConfig.getProfile(); String localPath = RuoYiConfig.getProfile();
// 数据库资源地址 // 数据库资源地址
String downloadPath = localPath + FileUtils.stripPrefix(resource); String downloadPath = localPath + FileUtils.stripPrefix(resource);
// 下载名称 // 下载名称
String downloadName = StringUtils.substringAfterLast(downloadPath, "/"); String downloadName = StringUtils.substringAfterLast(downloadPath, "/");
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE); response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
FileUtils.setAttachmentResponseHeader(response, downloadName); FileUtils.setAttachmentResponseHeader(response, downloadName);
FileUtils.writeBytes(downloadPath, response.getOutputStream()); FileUtils.writeBytes(downloadPath, response.getOutputStream());
} }
catch (Exception e) catch (Exception e)
{ {
log.error("下载文件失败", e); log.error("下载文件失败", e);
} }
} }
} }
@@ -1,121 +1,122 @@
package com.ruoyi.web.controller.monitor; package com.ruoyi.web.controller.monitor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.TreeSet; import java.util.TreeSet;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysCache; import com.ruoyi.system.domain.SysCache;
/** /**
* 缓存监控 * 缓存监控
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/monitor/cache") @RequestMapping("/monitor/cache")
public class CacheController public class CacheController
{ {
@Autowired @Autowired
private RedisTemplate<String, String> redisTemplate; private RedisTemplate<String, String> redisTemplate;
private final static List<SysCache> caches = new ArrayList<SysCache>(); private final static List<SysCache> caches = new ArrayList<SysCache>();
{ {
caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息")); caches.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息"));
caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息")); caches.add(new SysCache(CacheConstants.SYS_CONFIG_KEY, "配置信息"));
caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典")); caches.add(new SysCache(CacheConstants.SYS_DICT_KEY, "数据字典"));
caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); caches.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码"));
caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交")); caches.add(new SysCache(CacheConstants.REPEAT_SUBMIT_KEY, "防重提交"));
caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理")); caches.add(new SysCache(CacheConstants.RATE_LIMIT_KEY, "限流处理"));
caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数")); caches.add(new SysCache(CacheConstants.PWD_ERR_CNT_KEY, "密码错误次数"));
} }
@PreAuthorize("@ss.hasPermi('monitor:cache:list')") @SuppressWarnings("deprecation")
@GetMapping() @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
public AjaxResult getInfo() throws Exception @GetMapping()
{ public AjaxResult getInfo() throws Exception
Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info()); {
Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats")); Properties info = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info());
Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize()); Properties commandStats = (Properties) redisTemplate.execute((RedisCallback<Object>) connection -> connection.info("commandstats"));
Object dbSize = redisTemplate.execute((RedisCallback<Object>) connection -> connection.dbSize());
Map<String, Object> result = new HashMap<>(3);
result.put("info", info); Map<String, Object> result = new HashMap<>(3);
result.put("dbSize", dbSize); result.put("info", info);
result.put("dbSize", dbSize);
List<Map<String, String>> pieList = new ArrayList<>();
commandStats.stringPropertyNames().forEach(key -> { List<Map<String, String>> pieList = new ArrayList<>();
Map<String, String> data = new HashMap<>(2); commandStats.stringPropertyNames().forEach(key -> {
String property = commandStats.getProperty(key); Map<String, String> data = new HashMap<>(2);
data.put("name", StringUtils.removeStart(key, "cmdstat_")); String property = commandStats.getProperty(key);
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec")); data.put("name", StringUtils.removeStart(key, "cmdstat_"));
pieList.add(data); data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
}); pieList.add(data);
result.put("commandStats", pieList); });
return AjaxResult.success(result); result.put("commandStats", pieList);
} return AjaxResult.success(result);
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getNames") @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
public AjaxResult cache() @GetMapping("/getNames")
{ public AjaxResult cache()
return AjaxResult.success(caches); {
} return AjaxResult.success(caches);
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getKeys/{cacheName}") @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
public AjaxResult getCacheKeys(@PathVariable String cacheName) @GetMapping("/getKeys/{cacheName}")
{ public AjaxResult getCacheKeys(@PathVariable String cacheName)
Set<String> cacheKeys = redisTemplate.keys(cacheName + "*"); {
return AjaxResult.success(new TreeSet<>(cacheKeys)); Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
} return AjaxResult.success(new TreeSet<>(cacheKeys));
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@GetMapping("/getValue/{cacheName}/{cacheKey}") @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey) @GetMapping("/getValue/{cacheName}/{cacheKey}")
{ public AjaxResult getCacheValue(@PathVariable String cacheName, @PathVariable String cacheKey)
String cacheValue = redisTemplate.opsForValue().get(cacheKey); {
SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue); String cacheValue = redisTemplate.opsForValue().get(cacheKey);
return AjaxResult.success(sysCache); SysCache sysCache = new SysCache(cacheName, cacheKey, cacheValue);
} return AjaxResult.success(sysCache);
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheName/{cacheName}") @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
public AjaxResult clearCacheName(@PathVariable String cacheName) @DeleteMapping("/clearCacheName/{cacheName}")
{ public AjaxResult clearCacheName(@PathVariable String cacheName)
Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*"); {
redisTemplate.delete(cacheKeys); Collection<String> cacheKeys = redisTemplate.keys(cacheName + "*");
return AjaxResult.success(); redisTemplate.delete(cacheKeys);
} return AjaxResult.success();
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheKey/{cacheKey}") @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
public AjaxResult clearCacheKey(@PathVariable String cacheKey) @DeleteMapping("/clearCacheKey/{cacheKey}")
{ public AjaxResult clearCacheKey(@PathVariable String cacheKey)
redisTemplate.delete(cacheKey); {
return AjaxResult.success(); redisTemplate.delete(cacheKey);
} return AjaxResult.success();
}
@PreAuthorize("@ss.hasPermi('monitor:cache:list')")
@DeleteMapping("/clearCacheAll") @PreAuthorize("@ss.hasPermi('monitor:cache:list')")
public AjaxResult clearCacheAll() @DeleteMapping("/clearCacheAll")
{ public AjaxResult clearCacheAll()
Collection<String> cacheKeys = redisTemplate.keys("*"); {
redisTemplate.delete(cacheKeys); Collection<String> cacheKeys = redisTemplate.keys("*");
return AjaxResult.success(); redisTemplate.delete(cacheKeys);
} return AjaxResult.success();
} }
}
@@ -1,27 +1,27 @@
package com.ruoyi.web.controller.monitor; package com.ruoyi.web.controller.monitor;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.framework.web.domain.Server; import com.ruoyi.framework.web.domain.Server;
/** /**
* 服务器监控 * 服务器监控
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/monitor/server") @RequestMapping("/monitor/server")
public class ServerController public class ServerController
{ {
@PreAuthorize("@ss.hasPermi('monitor:server:list')") @PreAuthorize("@ss.hasPermi('monitor:server:list')")
@GetMapping() @GetMapping()
public AjaxResult getInfo() throws Exception public AjaxResult getInfo() throws Exception
{ {
Server server = new Server(); Server server = new Server();
server.copyTo(); server.copyTo();
return AjaxResult.success(server); return AjaxResult.success(server);
} }
} }
@@ -1,82 +1,82 @@
package com.ruoyi.web.controller.monitor; package com.ruoyi.web.controller.monitor;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.service.SysPasswordService; import com.ruoyi.framework.web.service.SysPasswordService;
import com.ruoyi.system.domain.SysLogininfor; import com.ruoyi.system.domain.SysLogininfor;
import com.ruoyi.system.service.ISysLogininforService; import com.ruoyi.system.service.ISysLogininforService;
/** /**
* 系统访问记录 * 系统访问记录
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/monitor/logininfor") @RequestMapping("/monitor/logininfor")
public class SysLogininforController extends BaseController public class SysLogininforController extends BaseController
{ {
@Autowired @Autowired
private ISysLogininforService logininforService; private ISysLogininforService logininforService;
@Autowired @Autowired
private SysPasswordService passwordService; private SysPasswordService passwordService;
@PreAuthorize("@ss.hasPermi('monitor:logininfor:list')") @PreAuthorize("@ss.hasPermi('monitor:logininfor:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysLogininfor logininfor) public TableDataInfo list(SysLogininfor logininfor)
{ {
startPage(); startPage();
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor); List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
return getDataTable(list); return getDataTable(list);
} }
@Log(title = "登录日志", businessType = BusinessType.EXPORT) @Log(title = "登录日志", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('monitor:logininfor:export')") @PreAuthorize("@ss.hasPermi('monitor:logininfor:export')")
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, SysLogininfor logininfor) public void export(HttpServletResponse response, SysLogininfor logininfor)
{ {
List<SysLogininfor> list = logininforService.selectLogininforList(logininfor); List<SysLogininfor> list = logininforService.selectLogininforList(logininfor);
ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class); ExcelUtil<SysLogininfor> util = new ExcelUtil<SysLogininfor>(SysLogininfor.class);
util.exportExcel(response, list, "登录日志"); util.exportExcel(response, list, "登录日志");
} }
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
@Log(title = "登录日志", businessType = BusinessType.DELETE) @Log(title = "登录日志", businessType = BusinessType.DELETE)
@DeleteMapping("/{infoIds}") @DeleteMapping("/{infoIds}")
public AjaxResult remove(@PathVariable Long[] infoIds) public AjaxResult remove(@PathVariable Long[] infoIds)
{ {
return toAjax(logininforService.deleteLogininforByIds(infoIds)); return toAjax(logininforService.deleteLogininforByIds(infoIds));
} }
@PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')") @PreAuthorize("@ss.hasPermi('monitor:logininfor:remove')")
@Log(title = "登录日志", businessType = BusinessType.CLEAN) @Log(title = "登录日志", businessType = BusinessType.CLEAN)
@DeleteMapping("/clean") @DeleteMapping("/clean")
public AjaxResult clean() public AjaxResult clean()
{ {
logininforService.cleanLogininfor(); logininforService.cleanLogininfor();
return success(); return success();
} }
@PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')") @PreAuthorize("@ss.hasPermi('monitor:logininfor:unlock')")
@Log(title = "账户解锁", businessType = BusinessType.OTHER) @Log(title = "账户解锁", businessType = BusinessType.OTHER)
@GetMapping("/unlock/{userName}") @GetMapping("/unlock/{userName}")
public AjaxResult unlock(@PathVariable("userName") String userName) public AjaxResult unlock(@PathVariable("userName") String userName)
{ {
passwordService.clearLoginRecordCache(userName); passwordService.clearLoginRecordCache(userName);
return success(); return success();
} }
} }
@@ -1,69 +1,69 @@
package com.ruoyi.web.controller.monitor; package com.ruoyi.web.controller.monitor;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysOperLog; import com.ruoyi.system.domain.SysOperLog;
import com.ruoyi.system.service.ISysOperLogService; import com.ruoyi.system.service.ISysOperLogService;
/** /**
* 操作日志记录 * 操作日志记录
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/monitor/operlog") @RequestMapping("/monitor/operlog")
public class SysOperlogController extends BaseController public class SysOperlogController extends BaseController
{ {
@Autowired @Autowired
private ISysOperLogService operLogService; private ISysOperLogService operLogService;
@PreAuthorize("@ss.hasPermi('monitor:operlog:list')") @PreAuthorize("@ss.hasPermi('monitor:operlog:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysOperLog operLog) public TableDataInfo list(SysOperLog operLog)
{ {
startPage(); startPage();
List<SysOperLog> list = operLogService.selectOperLogList(operLog); List<SysOperLog> list = operLogService.selectOperLogList(operLog);
return getDataTable(list); return getDataTable(list);
} }
@Log(title = "操作日志", businessType = BusinessType.EXPORT) @Log(title = "操作日志", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('monitor:operlog:export')") @PreAuthorize("@ss.hasPermi('monitor:operlog:export')")
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, SysOperLog operLog) public void export(HttpServletResponse response, SysOperLog operLog)
{ {
List<SysOperLog> list = operLogService.selectOperLogList(operLog); List<SysOperLog> list = operLogService.selectOperLogList(operLog);
ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class); ExcelUtil<SysOperLog> util = new ExcelUtil<SysOperLog>(SysOperLog.class);
util.exportExcel(response, list, "操作日志"); util.exportExcel(response, list, "操作日志");
} }
@Log(title = "操作日志", businessType = BusinessType.DELETE) @Log(title = "操作日志", businessType = BusinessType.DELETE)
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
@DeleteMapping("/{operIds}") @DeleteMapping("/{operIds}")
public AjaxResult remove(@PathVariable Long[] operIds) public AjaxResult remove(@PathVariable Long[] operIds)
{ {
return toAjax(operLogService.deleteOperLogByIds(operIds)); return toAjax(operLogService.deleteOperLogByIds(operIds));
} }
@Log(title = "操作日志", businessType = BusinessType.CLEAN) @Log(title = "操作日志", businessType = BusinessType.CLEAN)
@PreAuthorize("@ss.hasPermi('monitor:operlog:remove')") @PreAuthorize("@ss.hasPermi('monitor:operlog:remove')")
@DeleteMapping("/clean") @DeleteMapping("/clean")
public AjaxResult clean() public AjaxResult clean()
{ {
operLogService.cleanOperLog(); operLogService.cleanOperLog();
return success(); return success();
} }
} }
@@ -1,83 +1,83 @@
package com.ruoyi.web.controller.monitor; package com.ruoyi.web.controller.monitor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.domain.SysUserOnline; import com.ruoyi.system.domain.SysUserOnline;
import com.ruoyi.system.service.ISysUserOnlineService; import com.ruoyi.system.service.ISysUserOnlineService;
/** /**
* 在线用户监控 * 在线用户监控
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/monitor/online") @RequestMapping("/monitor/online")
public class SysUserOnlineController extends BaseController public class SysUserOnlineController extends BaseController
{ {
@Autowired @Autowired
private ISysUserOnlineService userOnlineService; private ISysUserOnlineService userOnlineService;
@Autowired @Autowired
private RedisCache redisCache; private RedisCache redisCache;
@PreAuthorize("@ss.hasPermi('monitor:online:list')") @PreAuthorize("@ss.hasPermi('monitor:online:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(String ipaddr, String userName) public TableDataInfo list(String ipaddr, String userName)
{ {
Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*"); Collection<String> keys = redisCache.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>(); List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
for (String key : keys) for (String key : keys)
{ {
LoginUser user = redisCache.getCacheObject(key); LoginUser user = redisCache.getCacheObject(key);
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
{ {
userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user)); userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
} }
else if (StringUtils.isNotEmpty(ipaddr)) else if (StringUtils.isNotEmpty(ipaddr))
{ {
userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user)); userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
} }
else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser())) else if (StringUtils.isNotEmpty(userName) && StringUtils.isNotNull(user.getUser()))
{ {
userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user)); userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
} }
else else
{ {
userOnlineList.add(userOnlineService.loginUserToUserOnline(user)); userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
} }
} }
Collections.reverse(userOnlineList); Collections.reverse(userOnlineList);
userOnlineList.removeAll(Collections.singleton(null)); userOnlineList.removeAll(Collections.singleton(null));
return getDataTable(userOnlineList); return getDataTable(userOnlineList);
} }
/** /**
* 强退用户 * 强退用户
*/ */
@PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')") @PreAuthorize("@ss.hasPermi('monitor:online:forceLogout')")
@Log(title = "在线用户", businessType = BusinessType.FORCE) @Log(title = "在线用户", businessType = BusinessType.FORCE)
@DeleteMapping("/{tokenId}") @DeleteMapping("/{tokenId}")
public AjaxResult forceLogout(@PathVariable String tokenId) public AjaxResult forceLogout(@PathVariable String tokenId)
{ {
redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId); redisCache.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
return success(); return success();
} }
} }
@@ -1,133 +1,133 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysConfig; import com.ruoyi.system.domain.SysConfig;
import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysConfigService;
/** /**
* 参数配置 信息操作处理 * 参数配置 信息操作处理
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/system/config") @RequestMapping("/system/config")
public class SysConfigController extends BaseController public class SysConfigController extends BaseController
{ {
@Autowired @Autowired
private ISysConfigService configService; private ISysConfigService configService;
/** /**
* 获取参数配置列表 * 获取参数配置列表
*/ */
@PreAuthorize("@ss.hasPermi('system:config:list')") @PreAuthorize("@ss.hasPermi('system:config:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysConfig config) public TableDataInfo list(SysConfig config)
{ {
startPage(); startPage();
List<SysConfig> list = configService.selectConfigList(config); List<SysConfig> list = configService.selectConfigList(config);
return getDataTable(list); return getDataTable(list);
} }
@Log(title = "参数管理", businessType = BusinessType.EXPORT) @Log(title = "参数管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:config:export')") @PreAuthorize("@ss.hasPermi('system:config:export')")
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, SysConfig config) public void export(HttpServletResponse response, SysConfig config)
{ {
List<SysConfig> list = configService.selectConfigList(config); List<SysConfig> list = configService.selectConfigList(config);
ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class); ExcelUtil<SysConfig> util = new ExcelUtil<SysConfig>(SysConfig.class);
util.exportExcel(response, list, "参数数据"); util.exportExcel(response, list, "参数数据");
} }
/** /**
* 根据参数编号获取详细信息 * 根据参数编号获取详细信息
*/ */
@PreAuthorize("@ss.hasPermi('system:config:query')") @PreAuthorize("@ss.hasPermi('system:config:query')")
@GetMapping(value = "/{configId}") @GetMapping(value = "/{configId}")
public AjaxResult getInfo(@PathVariable Long configId) public AjaxResult getInfo(@PathVariable Long configId)
{ {
return success(configService.selectConfigById(configId)); return success(configService.selectConfigById(configId));
} }
/** /**
* 根据参数键名查询参数值 * 根据参数键名查询参数值
*/ */
@GetMapping(value = "/configKey/{configKey}") @GetMapping(value = "/configKey/{configKey}")
public AjaxResult getConfigKey(@PathVariable String configKey) public AjaxResult getConfigKey(@PathVariable String configKey)
{ {
return success(configService.selectConfigByKey(configKey)); return success(configService.selectConfigByKey(configKey));
} }
/** /**
* 新增参数配置 * 新增参数配置
*/ */
@PreAuthorize("@ss.hasPermi('system:config:add')") @PreAuthorize("@ss.hasPermi('system:config:add')")
@Log(title = "参数管理", businessType = BusinessType.INSERT) @Log(title = "参数管理", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
public AjaxResult add(@Validated @RequestBody SysConfig config) public AjaxResult add(@Validated @RequestBody SysConfig config)
{ {
if (!configService.checkConfigKeyUnique(config)) if (!configService.checkConfigKeyUnique(config))
{ {
return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在"); return error("新增参数'" + config.getConfigName() + "'失败,参数键名已存在");
} }
config.setCreateBy(getUsername()); config.setCreateBy(getUsername());
return toAjax(configService.insertConfig(config)); return toAjax(configService.insertConfig(config));
} }
/** /**
* 修改参数配置 * 修改参数配置
*/ */
@PreAuthorize("@ss.hasPermi('system:config:edit')") @PreAuthorize("@ss.hasPermi('system:config:edit')")
@Log(title = "参数管理", businessType = BusinessType.UPDATE) @Log(title = "参数管理", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@Validated @RequestBody SysConfig config) public AjaxResult edit(@Validated @RequestBody SysConfig config)
{ {
if (!configService.checkConfigKeyUnique(config)) if (!configService.checkConfigKeyUnique(config))
{ {
return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在"); return error("修改参数'" + config.getConfigName() + "'失败,参数键名已存在");
} }
config.setUpdateBy(getUsername()); config.setUpdateBy(getUsername());
return toAjax(configService.updateConfig(config)); return toAjax(configService.updateConfig(config));
} }
/** /**
* 删除参数配置 * 删除参数配置
*/ */
@PreAuthorize("@ss.hasPermi('system:config:remove')") @PreAuthorize("@ss.hasPermi('system:config:remove')")
@Log(title = "参数管理", businessType = BusinessType.DELETE) @Log(title = "参数管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{configIds}") @DeleteMapping("/{configIds}")
public AjaxResult remove(@PathVariable Long[] configIds) public AjaxResult remove(@PathVariable Long[] configIds)
{ {
configService.deleteConfigByIds(configIds); configService.deleteConfigByIds(configIds);
return success(); return success();
} }
/** /**
* 刷新参数缓存 * 刷新参数缓存
*/ */
@PreAuthorize("@ss.hasPermi('system:config:remove')") @PreAuthorize("@ss.hasPermi('system:config:remove')")
@Log(title = "参数管理", businessType = BusinessType.CLEAN) @Log(title = "参数管理", businessType = BusinessType.CLEAN)
@DeleteMapping("/refreshCache") @DeleteMapping("/refreshCache")
public AjaxResult refreshCache() public AjaxResult refreshCache()
{ {
configService.resetConfigCache(); configService.resetConfigCache();
return success(); return success();
} }
} }
@@ -1,132 +1,147 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.List; import java.util.List;
import org.apache.commons.lang3.ArrayUtils; import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.apache.commons.lang3.ArrayUtils;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.annotation.Log; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.service.ISysDeptService; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysDeptService;
/**
* 部门信息 /**
* * 部门信息
* @author ruoyi *
*/ * @author ruoyi
@RestController */
@RequestMapping("/system/dept") @RestController
public class SysDeptController extends BaseController @RequestMapping("/system/dept")
{ public class SysDeptController extends BaseController
@Autowired {
private ISysDeptService deptService; @Autowired
private ISysDeptService deptService;
/**
* 获取部门列表 /**
*/ * 获取部门列表
@PreAuthorize("@ss.hasPermi('system:dept:list')") */
@GetMapping("/list") @PreAuthorize("@ss.hasPermi('system:dept:list')")
public AjaxResult list(SysDept dept) @GetMapping("/list")
{ public AjaxResult list(SysDept dept)
List<SysDept> depts = deptService.selectDeptList(dept); {
return success(depts); List<SysDept> depts = deptService.selectDeptList(dept);
} return success(depts);
}
/**
* 查询部门列表(排除节点) /**
*/ * 查询部门列表(排除节点)
@PreAuthorize("@ss.hasPermi('system:dept:list')") */
@GetMapping("/list/exclude/{deptId}") @PreAuthorize("@ss.hasPermi('system:dept:list')")
public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) @GetMapping("/list/exclude/{deptId}")
{ public AjaxResult excludeChild(@PathVariable(value = "deptId", required = false) Long deptId)
List<SysDept> depts = deptService.selectDeptList(new SysDept()); {
depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + "")); List<SysDept> depts = deptService.selectDeptList(new SysDept());
return success(depts); depts.removeIf(d -> d.getDeptId().intValue() == deptId || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), deptId + ""));
} return success(depts);
}
/**
* 根据部门编号获取详细信息 /**
*/ * 根据部门编号获取详细信息
@PreAuthorize("@ss.hasPermi('system:dept:query')") */
@GetMapping(value = "/{deptId}") @PreAuthorize("@ss.hasPermi('system:dept:query')")
public AjaxResult getInfo(@PathVariable Long deptId) @GetMapping(value = "/{deptId}")
{ public AjaxResult getInfo(@PathVariable Long deptId)
deptService.checkDeptDataScope(deptId); {
return success(deptService.selectDeptById(deptId)); deptService.checkDeptDataScope(deptId);
} return success(deptService.selectDeptById(deptId));
}
/**
* 新增部门 /**
*/ * 新增部门
@PreAuthorize("@ss.hasPermi('system:dept:add')") */
@Log(title = "部门管理", businessType = BusinessType.INSERT) @PreAuthorize("@ss.hasPermi('system:dept:add')")
@PostMapping @Log(title = "部门管理", businessType = BusinessType.INSERT)
public AjaxResult add(@Validated @RequestBody SysDept dept) @PostMapping
{ public AjaxResult add(@Validated @RequestBody SysDept dept)
if (!deptService.checkDeptNameUnique(dept)) {
{ if (!deptService.checkDeptNameUnique(dept))
return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在"); {
} return error("新增部门'" + dept.getDeptName() + "'失败,部门名称已存在");
dept.setCreateBy(getUsername()); }
return toAjax(deptService.insertDept(dept)); dept.setCreateBy(getUsername());
} return toAjax(deptService.insertDept(dept));
}
/**
* 修改部门 /**
*/ * 修改部门
@PreAuthorize("@ss.hasPermi('system:dept:edit')") */
@Log(title = "部门管理", businessType = BusinessType.UPDATE) @PreAuthorize("@ss.hasPermi('system:dept:edit')")
@PutMapping @Log(title = "部门管理", businessType = BusinessType.UPDATE)
public AjaxResult edit(@Validated @RequestBody SysDept dept) @PutMapping
{ public AjaxResult edit(@Validated @RequestBody SysDept dept)
Long deptId = dept.getDeptId(); {
deptService.checkDeptDataScope(deptId); Long deptId = dept.getDeptId();
if (!deptService.checkDeptNameUnique(dept)) deptService.checkDeptDataScope(deptId);
{ if (!deptService.checkDeptNameUnique(dept))
return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在"); {
} return error("修改部门'" + dept.getDeptName() + "'失败,部门名称已存在");
else if (dept.getParentId().equals(deptId)) }
{ else if (dept.getParentId().equals(deptId))
return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己"); {
} return error("修改部门'" + dept.getDeptName() + "'失败,上级部门不能是自己");
else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0) }
{ else if (StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()) && deptService.selectNormalChildrenDeptById(deptId) > 0)
return error("该部门包含未停用的子部门!"); {
} return error("该部门包含未停用的子部门!");
dept.setUpdateBy(getUsername()); }
return toAjax(deptService.updateDept(dept)); dept.setUpdateBy(getUsername());
} return toAjax(deptService.updateDept(dept));
}
/**
* 删除部门 /**
*/ * 保存部门排序
@PreAuthorize("@ss.hasPermi('system:dept:remove')") */
@Log(title = "部门管理", businessType = BusinessType.DELETE) @PreAuthorize("@ss.hasPermi('system:dept:edit')")
@DeleteMapping("/{deptId}") @Log(title = "保存部门排序", businessType = BusinessType.UPDATE)
public AjaxResult remove(@PathVariable Long deptId) @PutMapping("/updateSort")
{ public AjaxResult updateSort(@RequestBody Map<String, String> params)
if (deptService.hasChildByDeptId(deptId)) {
{ String[] deptIds = params.get("deptIds").split(",");
return warn("存在下级部门,不允许删除"); String[] orderNums = params.get("orderNums").split(",");
} deptService.updateDeptSort(deptIds, orderNums);
if (deptService.checkDeptExistUser(deptId)) return success();
{ }
return warn("部门存在用户,不允许删除");
} /**
deptService.checkDeptDataScope(deptId); * 删除部门
return toAjax(deptService.deleteDeptById(deptId)); */
} @PreAuthorize("@ss.hasPermi('system:dept:remove')")
} @Log(title = "部门管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{deptId}")
public AjaxResult remove(@PathVariable Long deptId)
{
if (deptService.hasChildByDeptId(deptId))
{
return warn("存在下级部门,不允许删除");
}
if (deptService.checkDeptExistUser(deptId))
{
return warn("部门存在用户,不允许删除");
}
deptService.checkDeptDataScope(deptId);
return toAjax(deptService.deleteDeptById(deptId));
}
}
@@ -1,121 +1,121 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictData; import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDictDataService; import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService; import com.ruoyi.system.service.ISysDictTypeService;
/** /**
* 数据字典信息 * 数据字典信息
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/system/dict/data") @RequestMapping("/system/dict/data")
public class SysDictDataController extends BaseController public class SysDictDataController extends BaseController
{ {
@Autowired @Autowired
private ISysDictDataService dictDataService; private ISysDictDataService dictDataService;
@Autowired @Autowired
private ISysDictTypeService dictTypeService; private ISysDictTypeService dictTypeService;
@PreAuthorize("@ss.hasPermi('system:dict:list')") @PreAuthorize("@ss.hasPermi('system:dict:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysDictData dictData) public TableDataInfo list(SysDictData dictData)
{ {
startPage(); startPage();
List<SysDictData> list = dictDataService.selectDictDataList(dictData); List<SysDictData> list = dictDataService.selectDictDataList(dictData);
return getDataTable(list); return getDataTable(list);
} }
@Log(title = "字典数据", businessType = BusinessType.EXPORT) @Log(title = "字典数据", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:dict:export')") @PreAuthorize("@ss.hasPermi('system:dict:export')")
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, SysDictData dictData) public void export(HttpServletResponse response, SysDictData dictData)
{ {
List<SysDictData> list = dictDataService.selectDictDataList(dictData); List<SysDictData> list = dictDataService.selectDictDataList(dictData);
ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class); ExcelUtil<SysDictData> util = new ExcelUtil<SysDictData>(SysDictData.class);
util.exportExcel(response, list, "字典数据"); util.exportExcel(response, list, "字典数据");
} }
/** /**
* 查询字典数据详细 * 查询字典数据详细
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:query')") @PreAuthorize("@ss.hasPermi('system:dict:query')")
@GetMapping(value = "/{dictCode}") @GetMapping(value = "/{dictCode}")
public AjaxResult getInfo(@PathVariable Long dictCode) public AjaxResult getInfo(@PathVariable Long dictCode)
{ {
return success(dictDataService.selectDictDataById(dictCode)); return success(dictDataService.selectDictDataById(dictCode));
} }
/** /**
* 根据字典类型查询字典数据信息 * 根据字典类型查询字典数据信息
*/ */
@GetMapping(value = "/type/{dictType}") @GetMapping(value = "/type/{dictType}")
public AjaxResult dictType(@PathVariable String dictType) public AjaxResult dictType(@PathVariable String dictType)
{ {
List<SysDictData> data = dictTypeService.selectDictDataByType(dictType); List<SysDictData> data = dictTypeService.selectDictDataByType(dictType);
if (StringUtils.isNull(data)) if (StringUtils.isNull(data))
{ {
data = new ArrayList<SysDictData>(); data = new ArrayList<SysDictData>();
} }
return success(data); return success(data);
} }
/** /**
* 新增字典类型 * 新增字典类型
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:add')") @PreAuthorize("@ss.hasPermi('system:dict:add')")
@Log(title = "字典数据", businessType = BusinessType.INSERT) @Log(title = "字典数据", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
public AjaxResult add(@Validated @RequestBody SysDictData dict) public AjaxResult add(@Validated @RequestBody SysDictData dict)
{ {
dict.setCreateBy(getUsername()); dict.setCreateBy(getUsername());
return toAjax(dictDataService.insertDictData(dict)); return toAjax(dictDataService.insertDictData(dict));
} }
/** /**
* 修改保存字典类型 * 修改保存字典类型
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:edit')") @PreAuthorize("@ss.hasPermi('system:dict:edit')")
@Log(title = "字典数据", businessType = BusinessType.UPDATE) @Log(title = "字典数据", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@Validated @RequestBody SysDictData dict) public AjaxResult edit(@Validated @RequestBody SysDictData dict)
{ {
dict.setUpdateBy(getUsername()); dict.setUpdateBy(getUsername());
return toAjax(dictDataService.updateDictData(dict)); return toAjax(dictDataService.updateDictData(dict));
} }
/** /**
* 删除字典类型 * 删除字典类型
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:remove')") @PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.DELETE) @Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictCodes}") @DeleteMapping("/{dictCodes}")
public AjaxResult remove(@PathVariable Long[] dictCodes) public AjaxResult remove(@PathVariable Long[] dictCodes)
{ {
dictDataService.deleteDictDataByIds(dictCodes); dictDataService.deleteDictDataByIds(dictCodes);
return success(); return success();
} }
} }
@@ -1,131 +1,131 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDictType; import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDictTypeService; import com.ruoyi.system.service.ISysDictTypeService;
/** /**
* 数据字典信息 * 数据字典信息
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/system/dict/type") @RequestMapping("/system/dict/type")
public class SysDictTypeController extends BaseController public class SysDictTypeController extends BaseController
{ {
@Autowired @Autowired
private ISysDictTypeService dictTypeService; private ISysDictTypeService dictTypeService;
@PreAuthorize("@ss.hasPermi('system:dict:list')") @PreAuthorize("@ss.hasPermi('system:dict:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysDictType dictType) public TableDataInfo list(SysDictType dictType)
{ {
startPage(); startPage();
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType); List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
return getDataTable(list); return getDataTable(list);
} }
@Log(title = "字典类型", businessType = BusinessType.EXPORT) @Log(title = "字典类型", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:dict:export')") @PreAuthorize("@ss.hasPermi('system:dict:export')")
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, SysDictType dictType) public void export(HttpServletResponse response, SysDictType dictType)
{ {
List<SysDictType> list = dictTypeService.selectDictTypeList(dictType); List<SysDictType> list = dictTypeService.selectDictTypeList(dictType);
ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class); ExcelUtil<SysDictType> util = new ExcelUtil<SysDictType>(SysDictType.class);
util.exportExcel(response, list, "字典类型"); util.exportExcel(response, list, "字典类型");
} }
/** /**
* 查询字典类型详细 * 查询字典类型详细
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:query')") @PreAuthorize("@ss.hasPermi('system:dict:query')")
@GetMapping(value = "/{dictId}") @GetMapping(value = "/{dictId}")
public AjaxResult getInfo(@PathVariable Long dictId) public AjaxResult getInfo(@PathVariable Long dictId)
{ {
return success(dictTypeService.selectDictTypeById(dictId)); return success(dictTypeService.selectDictTypeById(dictId));
} }
/** /**
* 新增字典类型 * 新增字典类型
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:add')") @PreAuthorize("@ss.hasPermi('system:dict:add')")
@Log(title = "字典类型", businessType = BusinessType.INSERT) @Log(title = "字典类型", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
public AjaxResult add(@Validated @RequestBody SysDictType dict) public AjaxResult add(@Validated @RequestBody SysDictType dict)
{ {
if (!dictTypeService.checkDictTypeUnique(dict)) if (!dictTypeService.checkDictTypeUnique(dict))
{ {
return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在"); return error("新增字典'" + dict.getDictName() + "'失败,字典类型已存在");
} }
dict.setCreateBy(getUsername()); dict.setCreateBy(getUsername());
return toAjax(dictTypeService.insertDictType(dict)); return toAjax(dictTypeService.insertDictType(dict));
} }
/** /**
* 修改字典类型 * 修改字典类型
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:edit')") @PreAuthorize("@ss.hasPermi('system:dict:edit')")
@Log(title = "字典类型", businessType = BusinessType.UPDATE) @Log(title = "字典类型", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@Validated @RequestBody SysDictType dict) public AjaxResult edit(@Validated @RequestBody SysDictType dict)
{ {
if (!dictTypeService.checkDictTypeUnique(dict)) if (!dictTypeService.checkDictTypeUnique(dict))
{ {
return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在"); return error("修改字典'" + dict.getDictName() + "'失败,字典类型已存在");
} }
dict.setUpdateBy(getUsername()); dict.setUpdateBy(getUsername());
return toAjax(dictTypeService.updateDictType(dict)); return toAjax(dictTypeService.updateDictType(dict));
} }
/** /**
* 删除字典类型 * 删除字典类型
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:remove')") @PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.DELETE) @Log(title = "字典类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{dictIds}") @DeleteMapping("/{dictIds}")
public AjaxResult remove(@PathVariable Long[] dictIds) public AjaxResult remove(@PathVariable Long[] dictIds)
{ {
dictTypeService.deleteDictTypeByIds(dictIds); dictTypeService.deleteDictTypeByIds(dictIds);
return success(); return success();
} }
/** /**
* 刷新字典缓存 * 刷新字典缓存
*/ */
@PreAuthorize("@ss.hasPermi('system:dict:remove')") @PreAuthorize("@ss.hasPermi('system:dict:remove')")
@Log(title = "字典类型", businessType = BusinessType.CLEAN) @Log(title = "字典类型", businessType = BusinessType.CLEAN)
@DeleteMapping("/refreshCache") @DeleteMapping("/refreshCache")
public AjaxResult refreshCache() public AjaxResult refreshCache()
{ {
dictTypeService.resetDictCache(); dictTypeService.resetDictCache();
return success(); return success();
} }
/** /**
* 获取字典选择框列表 * 获取字典选择框列表
*/ */
@GetMapping("/optionselect") @GetMapping("/optionselect")
public AjaxResult optionselect() public AjaxResult optionselect()
{ {
List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll(); List<SysDictType> dictTypes = dictTypeService.selectDictTypeAll();
return success(dictTypes); return success(dictTypes);
} }
} }
@@ -1,29 +1,64 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import org.springframework.beans.factory.annotation.Autowired; import java.util.Map;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.PostMapping;
import com.ruoyi.common.config.RuoYiConfig; import org.springframework.web.bind.annotation.RequestBody;
import com.ruoyi.common.utils.StringUtils; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/** import com.ruoyi.common.config.RuoYiConfig;
* 首页 import com.ruoyi.common.core.domain.AjaxResult;
* import com.ruoyi.common.core.domain.entity.SysUser;
* @author ruoyi import com.ruoyi.common.utils.SecurityUtils;
*/ import com.ruoyi.common.utils.StringUtils;
@RestController import com.ruoyi.system.service.ISysUserService;
public class SysIndexController
{ /**
/** 系统基础配置 */ * 首页
@Autowired *
private RuoYiConfig ruoyiConfig; * @author ruoyi
*/
/** @RestController
* 访问首页,提示语 public class SysIndexController
*/ {
@RequestMapping("/") /** 系统基础配置 */
public String index() @Autowired
{ private RuoYiConfig ruoyiConfig;
return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion());
} @Autowired
} private ISysUserService userService;
/**
* 访问首页,提示语
*/
@RequestMapping("/")
public String index()
{
return StringUtils.format("欢迎使用{}后台管理框架,当前版本:v{},请通过前端地址访问。", ruoyiConfig.getName(), ruoyiConfig.getVersion());
}
/**
* 解锁屏幕
*/
@PostMapping("/unlockscreen")
public AjaxResult unlockScreen(@RequestBody Map<String, String> body)
{
String password = body.get("password");
if (StringUtils.isEmpty(password))
{
return AjaxResult.error("密码不能为空");
}
String username = SecurityUtils.getUsername();
SysUser user = userService.selectUserByUserName(username);
if (user == null)
{
return AjaxResult.error("服务器超时,请重新登录");
}
if (!SecurityUtils.matchesPassword(password, user.getPassword()))
{
return AjaxResult.error("密码错误,请重新输入");
}
return AjaxResult.success("解锁成功");
}
}
@@ -1,150 +1,165 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import java.util.Map;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping;
import com.ruoyi.common.annotation.Log; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.service.ISysMenuService; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.system.service.ISysMenuService;
/**
* 菜单信息 /**
* * 菜单信息
* @author ruoyi *
*/ * @author ruoyi
@RestController */
@RequestMapping("/system/menu") @RestController
public class SysMenuController extends BaseController @RequestMapping("/system/menu")
{ public class SysMenuController extends BaseController
@Autowired {
private ISysMenuService menuService; @Autowired
private ISysMenuService menuService;
/**
* 获取菜单列表 /**
*/ * 获取菜单列表
@PreAuthorize("@ss.hasPermi('system:menu:list')") */
@GetMapping("/list") @PreAuthorize("@ss.hasPermi('system:menu:list')")
public AjaxResult list(SysMenu menu) @GetMapping("/list")
{ public AjaxResult list(SysMenu menu)
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId()); {
return success(menus); List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
} return success(menus);
}
/**
* 根据菜单编号获取详细信息 /**
*/ * 根据菜单编号获取详细信息
@PreAuthorize("@ss.hasPermi('system:menu:query')") */
@GetMapping(value = "/{menuId}") @PreAuthorize("@ss.hasPermi('system:menu:query')")
public AjaxResult getInfo(@PathVariable Long menuId) @GetMapping(value = "/{menuId}")
{ public AjaxResult getInfo(@PathVariable Long menuId)
return success(menuService.selectMenuById(menuId)); {
} return success(menuService.selectMenuById(menuId));
}
/**
* 获取菜单下拉树列表 /**
*/ * 获取菜单下拉树列表
@GetMapping("/treeselect") */
public AjaxResult treeselect(SysMenu menu) @GetMapping("/treeselect")
{ public AjaxResult treeselect(SysMenu menu)
List<SysMenu> menus = menuService.selectMenuList(menu, getUserId()); {
return success(menuService.buildMenuTreeSelect(menus)); List<SysMenu> menus = menuService.selectMenuList(menu, getUserId());
} return success(menuService.buildMenuTreeSelect(menus));
}
/**
* 加载对应角色菜单列表树 /**
*/ * 加载对应角色菜单列表树
@GetMapping(value = "/roleMenuTreeselect/{roleId}") */
public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId) @GetMapping(value = "/roleMenuTreeselect/{roleId}")
{ public AjaxResult roleMenuTreeselect(@PathVariable("roleId") Long roleId)
List<SysMenu> menus = menuService.selectMenuList(getUserId()); {
AjaxResult ajax = AjaxResult.success(); List<SysMenu> menus = menuService.selectMenuList(getUserId());
ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId)); AjaxResult ajax = AjaxResult.success();
ajax.put("menus", menuService.buildMenuTreeSelect(menus)); ajax.put("checkedKeys", menuService.selectMenuListByRoleId(roleId));
return ajax; ajax.put("menus", menuService.buildMenuTreeSelect(menus));
} return ajax;
}
/**
* 新增菜单 /**
*/ * 新增菜单
@PreAuthorize("@ss.hasPermi('system:menu:add')") */
@Log(title = "菜单管理", businessType = BusinessType.INSERT) @PreAuthorize("@ss.hasPermi('system:menu:add')")
@PostMapping @Log(title = "菜单管理", businessType = BusinessType.INSERT)
public AjaxResult add(@Validated @RequestBody SysMenu menu) @PostMapping
{ public AjaxResult add(@Validated @RequestBody SysMenu menu)
if (!menuService.checkMenuNameUnique(menu)) {
{ if (!menuService.checkMenuNameUnique(menu))
return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); {
} return error("新增菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) }
{ else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); {
} return error("新增菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
else if (!menuService.checkRouteConfigUnique(menu)) }
{ else if (!menuService.checkRouteConfigUnique(menu))
return error("新增菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在"); {
} return error("新增菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
menu.setCreateBy(getUsername()); }
return toAjax(menuService.insertMenu(menu)); menu.setCreateBy(getUsername());
} return toAjax(menuService.insertMenu(menu));
}
/**
* 修改菜单 /**
*/ * 修改菜单
@PreAuthorize("@ss.hasPermi('system:menu:edit')") */
@Log(title = "菜单管理", businessType = BusinessType.UPDATE) @PreAuthorize("@ss.hasPermi('system:menu:edit')")
@PutMapping @Log(title = "菜单管理", businessType = BusinessType.UPDATE)
public AjaxResult edit(@Validated @RequestBody SysMenu menu) @PutMapping
{ public AjaxResult edit(@Validated @RequestBody SysMenu menu)
if (!menuService.checkMenuNameUnique(menu)) {
{ if (!menuService.checkMenuNameUnique(menu))
return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在"); {
} return error("修改菜单'" + menu.getMenuName() + "'失败,菜单名称已存在");
else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath())) }
{ else if (UserConstants.YES_FRAME.equals(menu.getIsFrame()) && !StringUtils.ishttp(menu.getPath()))
return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头"); {
} return error("修改菜单'" + menu.getMenuName() + "'失败,地址必须以http(s)://开头");
else if (menu.getMenuId().equals(menu.getParentId())) }
{ else if (menu.getMenuId().equals(menu.getParentId()))
return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己"); {
} return error("修改菜单'" + menu.getMenuName() + "'失败,上级菜单不能选择自己");
else if (!menuService.checkRouteConfigUnique(menu)) }
{ else if (!menuService.checkRouteConfigUnique(menu))
return error("修改菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在"); {
} return error("修改菜单'" + menu.getMenuName() + "'失败,路由名称或地址已存在");
menu.setUpdateBy(getUsername()); }
return toAjax(menuService.updateMenu(menu)); menu.setUpdateBy(getUsername());
} return toAjax(menuService.updateMenu(menu));
}
/**
* 删除菜单 /**
*/ * 保存菜单排序
@PreAuthorize("@ss.hasPermi('system:menu:remove')") */
@Log(title = "菜单管理", businessType = BusinessType.DELETE) @PreAuthorize("@ss.hasPermi('system:menu:edit')")
@DeleteMapping("/{menuId}") @Log(title = "保存菜单排序", businessType = BusinessType.UPDATE)
public AjaxResult remove(@PathVariable("menuId") Long menuId) @PutMapping("/updateSort")
{ public AjaxResult updateSort(@RequestBody Map<String, String> params)
if (menuService.hasChildByMenuId(menuId)) {
{ String[] menuIds = params.get("menuIds").split(",");
return warn("存在子菜单,不允许删除"); String[] orderNums = params.get("orderNums").split(",");
} menuService.updateMenuSort(menuIds, orderNums);
if (menuService.checkMenuExistRole(menuId)) return success();
{ }
return warn("菜单已分配,不允许删除");
} /**
return toAjax(menuService.deleteMenuById(menuId)); * 删除菜单
} */
@PreAuthorize("@ss.hasPermi('system:menu:remove')")
@Log(title = "菜单管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{menuId}")
public AjaxResult remove(@PathVariable("menuId") Long menuId)
{
if (menuService.hasChildByMenuId(menuId))
{
return warn("存在子菜单,不允许删除");
}
if (menuService.checkMenuExistRole(menuId))
{
return warn("菜单已分配,不允许删除");
}
return toAjax(menuService.deleteMenuById(menuId));
}
} }
@@ -1,91 +1,150 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.List; import java.util.List;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.ResponseBody;
import com.ruoyi.common.annotation.Log; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.system.domain.SysNotice; import com.ruoyi.common.core.text.Convert;
import com.ruoyi.system.service.ISysNoticeService; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.system.domain.SysNotice;
/** import com.ruoyi.system.service.ISysNoticeReadService;
* 公告 信息操作处理 import com.ruoyi.system.service.ISysNoticeService;
*
* @author ruoyi /**
*/ * 公告 信息操作处理
@RestController *
@RequestMapping("/system/notice") * @author ruoyi
public class SysNoticeController extends BaseController */
{ @RestController
@Autowired @RequestMapping("/system/notice")
private ISysNoticeService noticeService; public class SysNoticeController extends BaseController
{
/** @Autowired
* 获取通知公告列表 private ISysNoticeService noticeService;
*/
@PreAuthorize("@ss.hasPermi('system:notice:list')") @Autowired
@GetMapping("/list") private ISysNoticeReadService noticeReadService;
public TableDataInfo list(SysNotice notice)
{ /**
startPage(); * 获取通知公告列表
List<SysNotice> list = noticeService.selectNoticeList(notice); */
return getDataTable(list); @PreAuthorize("@ss.hasPermi('system:notice:list')")
} @GetMapping("/list")
public TableDataInfo list(SysNotice notice)
/** {
* 根据通知公告编号获取详细信息 startPage();
*/ List<SysNotice> list = noticeService.selectNoticeList(notice);
@PreAuthorize("@ss.hasPermi('system:notice:query')") return getDataTable(list);
@GetMapping(value = "/{noticeId}") }
public AjaxResult getInfo(@PathVariable Long noticeId)
{ /**
return success(noticeService.selectNoticeById(noticeId)); * 根据通知公告编号获取详细信息
} */
@GetMapping(value = "/{noticeId}")
/** public AjaxResult getInfo(@PathVariable Long noticeId)
* 新增通知公告 {
*/ return success(noticeService.selectNoticeById(noticeId));
@PreAuthorize("@ss.hasPermi('system:notice:add')") }
@Log(title = "通知公告", businessType = BusinessType.INSERT)
@PostMapping /**
public AjaxResult add(@Validated @RequestBody SysNotice notice) * 新增通知公告
{ */
notice.setCreateBy(getUsername()); @PreAuthorize("@ss.hasPermi('system:notice:add')")
return toAjax(noticeService.insertNotice(notice)); @Log(title = "通知公告", businessType = BusinessType.INSERT)
} @PostMapping
public AjaxResult add(@Validated @RequestBody SysNotice notice)
/** {
* 修改通知公告 notice.setCreateBy(getUsername());
*/ return toAjax(noticeService.insertNotice(notice));
@PreAuthorize("@ss.hasPermi('system:notice:edit')") }
@Log(title = "通知公告", businessType = BusinessType.UPDATE)
@PutMapping /**
public AjaxResult edit(@Validated @RequestBody SysNotice notice) * 修改通知公告
{ */
notice.setUpdateBy(getUsername()); @PreAuthorize("@ss.hasPermi('system:notice:edit')")
return toAjax(noticeService.updateNotice(notice)); @Log(title = "通知公告", businessType = BusinessType.UPDATE)
} @PutMapping
public AjaxResult edit(@Validated @RequestBody SysNotice notice)
/** {
* 删除通知公告 notice.setUpdateBy(getUsername());
*/ return toAjax(noticeService.updateNotice(notice));
@PreAuthorize("@ss.hasPermi('system:notice:remove')") }
@Log(title = "通知公告", businessType = BusinessType.DELETE)
@DeleteMapping("/{noticeIds}") /**
public AjaxResult remove(@PathVariable Long[] noticeIds) * 首页顶部公告列表(返回全部正常公告,带当前用户已读标记,最多5条)
{ */
return toAjax(noticeService.deleteNoticeByIds(noticeIds)); @GetMapping("/listTop")
} @ResponseBody
} public AjaxResult listTop()
{
Long userId = getUserId();
List<SysNotice> list = noticeReadService.selectNoticeListWithReadStatus(userId, 5);
long unreadCount = list.stream().filter(n -> !n.getIsRead()).count();
AjaxResult result = AjaxResult.success(list);
result.put("unreadCount", unreadCount);
return result;
}
/**
* 标记公告已读
*/
@PostMapping("/markRead")
@ResponseBody
public AjaxResult markRead(Long noticeId)
{
Long userId = getUserId();
noticeReadService.markRead(noticeId, userId);
return success();
}
/**
* 批量标记已读
*/
@PostMapping("/markReadAll")
@ResponseBody
public AjaxResult markReadAll(String ids)
{
Long userId = getUserId();
Long[] noticeIds = Convert.toLongArray(ids);
noticeReadService.markReadBatch(userId, noticeIds);
return success();
}
/**
* 已读用户列表数据
*/
@PreAuthorize("@ss.hasPermi('system:notice:list')")
@GetMapping("/readUsers/list")
@ResponseBody
public TableDataInfo readUsersList(Long noticeId, String searchValue)
{
startPage();
List<?> list = noticeReadService.selectReadUsersByNoticeId(noticeId, searchValue);
return getDataTable(list);
}
/**
* 删除通知公告
*/
@PreAuthorize("@ss.hasPermi('system:notice:remove')")
@Log(title = "通知公告", businessType = BusinessType.DELETE)
@DeleteMapping("/{noticeIds}")
public AjaxResult remove(@PathVariable Long[] noticeIds)
{
noticeReadService.deleteByNoticeIds(noticeIds);
return toAjax(noticeService.deleteNoticeByIds(noticeIds));
}
}
@@ -1,129 +1,129 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysPost; import com.ruoyi.system.domain.SysPost;
import com.ruoyi.system.service.ISysPostService; import com.ruoyi.system.service.ISysPostService;
/** /**
* 岗位信息操作处理 * 岗位信息操作处理
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/system/post") @RequestMapping("/system/post")
public class SysPostController extends BaseController public class SysPostController extends BaseController
{ {
@Autowired @Autowired
private ISysPostService postService; private ISysPostService postService;
/** /**
* 获取岗位列表 * 获取岗位列表
*/ */
@PreAuthorize("@ss.hasPermi('system:post:list')") @PreAuthorize("@ss.hasPermi('system:post:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysPost post) public TableDataInfo list(SysPost post)
{ {
startPage(); startPage();
List<SysPost> list = postService.selectPostList(post); List<SysPost> list = postService.selectPostList(post);
return getDataTable(list); return getDataTable(list);
} }
@Log(title = "岗位管理", businessType = BusinessType.EXPORT) @Log(title = "岗位管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:post:export')") @PreAuthorize("@ss.hasPermi('system:post:export')")
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, SysPost post) public void export(HttpServletResponse response, SysPost post)
{ {
List<SysPost> list = postService.selectPostList(post); List<SysPost> list = postService.selectPostList(post);
ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class); ExcelUtil<SysPost> util = new ExcelUtil<SysPost>(SysPost.class);
util.exportExcel(response, list, "岗位数据"); util.exportExcel(response, list, "岗位数据");
} }
/** /**
* 根据岗位编号获取详细信息 * 根据岗位编号获取详细信息
*/ */
@PreAuthorize("@ss.hasPermi('system:post:query')") @PreAuthorize("@ss.hasPermi('system:post:query')")
@GetMapping(value = "/{postId}") @GetMapping(value = "/{postId}")
public AjaxResult getInfo(@PathVariable Long postId) public AjaxResult getInfo(@PathVariable Long postId)
{ {
return success(postService.selectPostById(postId)); return success(postService.selectPostById(postId));
} }
/** /**
* 新增岗位 * 新增岗位
*/ */
@PreAuthorize("@ss.hasPermi('system:post:add')") @PreAuthorize("@ss.hasPermi('system:post:add')")
@Log(title = "岗位管理", businessType = BusinessType.INSERT) @Log(title = "岗位管理", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
public AjaxResult add(@Validated @RequestBody SysPost post) public AjaxResult add(@Validated @RequestBody SysPost post)
{ {
if (!postService.checkPostNameUnique(post)) if (!postService.checkPostNameUnique(post))
{ {
return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在"); return error("新增岗位'" + post.getPostName() + "'失败,岗位名称已存在");
} }
else if (!postService.checkPostCodeUnique(post)) else if (!postService.checkPostCodeUnique(post))
{ {
return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在"); return error("新增岗位'" + post.getPostName() + "'失败,岗位编码已存在");
} }
post.setCreateBy(getUsername()); post.setCreateBy(getUsername());
return toAjax(postService.insertPost(post)); return toAjax(postService.insertPost(post));
} }
/** /**
* 修改岗位 * 修改岗位
*/ */
@PreAuthorize("@ss.hasPermi('system:post:edit')") @PreAuthorize("@ss.hasPermi('system:post:edit')")
@Log(title = "岗位管理", businessType = BusinessType.UPDATE) @Log(title = "岗位管理", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@Validated @RequestBody SysPost post) public AjaxResult edit(@Validated @RequestBody SysPost post)
{ {
if (!postService.checkPostNameUnique(post)) if (!postService.checkPostNameUnique(post))
{ {
return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在"); return error("修改岗位'" + post.getPostName() + "'失败,岗位名称已存在");
} }
else if (!postService.checkPostCodeUnique(post)) else if (!postService.checkPostCodeUnique(post))
{ {
return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在"); return error("修改岗位'" + post.getPostName() + "'失败,岗位编码已存在");
} }
post.setUpdateBy(getUsername()); post.setUpdateBy(getUsername());
return toAjax(postService.updatePost(post)); return toAjax(postService.updatePost(post));
} }
/** /**
* 删除岗位 * 删除岗位
*/ */
@PreAuthorize("@ss.hasPermi('system:post:remove')") @PreAuthorize("@ss.hasPermi('system:post:remove')")
@Log(title = "岗位管理", businessType = BusinessType.DELETE) @Log(title = "岗位管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{postIds}") @DeleteMapping("/{postIds}")
public AjaxResult remove(@PathVariable Long[] postIds) public AjaxResult remove(@PathVariable Long[] postIds)
{ {
return toAjax(postService.deletePostByIds(postIds)); return toAjax(postService.deletePostByIds(postIds));
} }
/** /**
* 获取岗位选择框列表 * 获取岗位选择框列表
*/ */
@GetMapping("/optionselect") @GetMapping("/optionselect")
public AjaxResult optionselect() public AjaxResult optionselect()
{ {
List<SysPost> posts = postService.selectPostAll(); List<SysPost> posts = postService.selectPostAll();
return success(posts); return success(posts);
} }
} }
@@ -1,149 +1,149 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.Map; import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils; import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.file.FileUtils; import com.ruoyi.common.utils.file.FileUtils;
import com.ruoyi.common.utils.file.MimeTypeUtils; import com.ruoyi.common.utils.file.MimeTypeUtils;
import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
/** /**
* 个人信息 业务处理 * 个人信息 业务处理
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/system/user/profile") @RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController public class SysProfileController extends BaseController
{ {
@Autowired @Autowired
private ISysUserService userService; private ISysUserService userService;
@Autowired @Autowired
private TokenService tokenService; private TokenService tokenService;
/** /**
* 个人信息 * 个人信息
*/ */
@GetMapping @GetMapping
public AjaxResult profile() public AjaxResult profile()
{ {
LoginUser loginUser = getLoginUser(); LoginUser loginUser = getLoginUser();
SysUser user = loginUser.getUser(); SysUser user = loginUser.getUser();
AjaxResult ajax = AjaxResult.success(user); AjaxResult ajax = AjaxResult.success(user);
ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername())); ajax.put("roleGroup", userService.selectUserRoleGroup(loginUser.getUsername()));
ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername())); ajax.put("postGroup", userService.selectUserPostGroup(loginUser.getUsername()));
return ajax; return ajax;
} }
/** /**
* 修改用户 * 修改用户
*/ */
@Log(title = "个人信息", businessType = BusinessType.UPDATE) @Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult updateProfile(@RequestBody SysUser user) public AjaxResult updateProfile(@RequestBody SysUser user)
{ {
LoginUser loginUser = getLoginUser(); LoginUser loginUser = getLoginUser();
SysUser currentUser = loginUser.getUser(); SysUser currentUser = loginUser.getUser();
currentUser.setNickName(user.getNickName()); currentUser.setNickName(user.getNickName());
currentUser.setEmail(user.getEmail()); currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber()); currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex()); currentUser.setSex(user.getSex());
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser)) if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
{ {
return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在"); return error("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在");
} }
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser)) if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
{ {
return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在"); return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在");
} }
if (userService.updateUserProfile(currentUser) > 0) if (userService.updateUserProfile(currentUser) > 0)
{ {
// 更新缓存用户信息 // 更新缓存用户信息
tokenService.setLoginUser(loginUser); tokenService.setLoginUser(loginUser);
return success(); return success();
} }
return error("修改个人信息异常,请联系管理员"); return error("修改个人信息异常,请联系管理员");
} }
/** /**
* 重置密码 * 重置密码
*/ */
@Log(title = "个人信息", businessType = BusinessType.UPDATE) @Log(title = "个人信息", businessType = BusinessType.UPDATE)
@PutMapping("/updatePwd") @PutMapping("/updatePwd")
public AjaxResult updatePwd(@RequestBody Map<String, String> params) public AjaxResult updatePwd(@RequestBody Map<String, String> params)
{ {
String oldPassword = params.get("oldPassword"); String oldPassword = params.get("oldPassword");
String newPassword = params.get("newPassword"); String newPassword = params.get("newPassword");
LoginUser loginUser = getLoginUser(); LoginUser loginUser = getLoginUser();
Long userId = loginUser.getUserId(); Long userId = loginUser.getUserId();
SysUser user = userService.selectUserById(userId); SysUser user = userService.selectUserById(userId);
String password = user.getPassword(); String password = user.getPassword();
if (!SecurityUtils.matchesPassword(oldPassword, password)) if (!SecurityUtils.matchesPassword(oldPassword, password))
{ {
return error("修改密码失败,旧密码错误"); return error("修改密码失败,旧密码错误");
} }
if (SecurityUtils.matchesPassword(newPassword, password)) if (SecurityUtils.matchesPassword(newPassword, password))
{ {
return error("新密码不能与旧密码相同"); return error("新密码不能与旧密码相同");
} }
newPassword = SecurityUtils.encryptPassword(newPassword); newPassword = SecurityUtils.encryptPassword(newPassword);
if (userService.resetUserPwd(userId, newPassword) > 0) if (userService.resetUserPwd(userId, newPassword) > 0)
{ {
// 更新缓存用户密码&密码最后更新时间 // 更新缓存用户密码&密码最后更新时间
loginUser.getUser().setPwdUpdateDate(DateUtils.getNowDate()); loginUser.getUser().setPwdUpdateDate(DateUtils.getNowDate());
loginUser.getUser().setPassword(newPassword); loginUser.getUser().setPassword(newPassword);
tokenService.setLoginUser(loginUser); tokenService.setLoginUser(loginUser);
return success(); return success();
} }
return error("修改密码异常,请联系管理员"); return error("修改密码异常,请联系管理员");
} }
/** /**
* 头像上传 * 头像上传
*/ */
@Log(title = "用户头像", businessType = BusinessType.UPDATE) @Log(title = "用户头像", businessType = BusinessType.UPDATE)
@PostMapping("/avatar") @PostMapping("/avatar")
public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception
{ {
if (!file.isEmpty()) if (!file.isEmpty())
{ {
LoginUser loginUser = getLoginUser(); LoginUser loginUser = getLoginUser();
String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION, true); String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION, true);
if (userService.updateUserAvatar(loginUser.getUserId(), avatar)) if (userService.updateUserAvatar(loginUser.getUserId(), avatar))
{ {
String oldAvatar = loginUser.getUser().getAvatar(); String oldAvatar = loginUser.getUser().getAvatar();
if (StringUtils.isNotEmpty(oldAvatar)) if (StringUtils.isNotEmpty(oldAvatar))
{ {
FileUtils.deleteFile(RuoYiConfig.getProfile() + FileUtils.stripPrefix(oldAvatar)); FileUtils.deleteFile(RuoYiConfig.getProfile() + FileUtils.stripPrefix(oldAvatar));
} }
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
ajax.put("imgUrl", avatar); ajax.put("imgUrl", avatar);
// 更新缓存用户头像 // 更新缓存用户头像
loginUser.getUser().setAvatar(avatar); loginUser.getUser().setAvatar(avatar);
tokenService.setLoginUser(loginUser); tokenService.setLoginUser(loginUser);
return ajax; return ajax;
} }
} }
return error("上传图片异常,请联系管理员"); return error("上传图片异常,请联系管理员");
} }
} }
@@ -1,38 +1,38 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.RegisterBody; import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.SysRegisterService; import com.ruoyi.framework.web.service.SysRegisterService;
import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysConfigService;
/** /**
* 注册验证 * 注册验证
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
public class SysRegisterController extends BaseController public class SysRegisterController extends BaseController
{ {
@Autowired @Autowired
private SysRegisterService registerService; private SysRegisterService registerService;
@Autowired @Autowired
private ISysConfigService configService; private ISysConfigService configService;
@PostMapping("/register") @PostMapping("/register")
public AjaxResult register(@RequestBody RegisterBody user) public AjaxResult register(@RequestBody RegisterBody user)
{ {
if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser")))) if (!("true".equals(configService.selectConfigByKey("sys.account.registerUser"))))
{ {
return error("当前系统没有开启注册功能!"); return error("当前系统没有开启注册功能!");
} }
String msg = registerService.register(user); String msg = registerService.register(user);
return StringUtils.isEmpty(msg) ? success() : error(msg); return StringUtils.isEmpty(msg) ? success() : error(msg);
} }
} }
@@ -1,262 +1,254 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.framework.web.service.SysPermissionService;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.framework.web.service.TokenService;
import com.ruoyi.framework.web.service.SysPermissionService; import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.framework.web.service.TokenService; import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.domain.SysUserRole; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysDeptService; import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; /**
* 角色信息
/** *
* 角色信息 * @author ruoyi
* */
* @author ruoyi @RestController
*/ @RequestMapping("/system/role")
@RestController public class SysRoleController extends BaseController
@RequestMapping("/system/role") {
public class SysRoleController extends BaseController @Autowired
{ private ISysRoleService roleService;
@Autowired
private ISysRoleService roleService; @Autowired
private TokenService tokenService;
@Autowired
private TokenService tokenService; @Autowired
private SysPermissionService permissionService;
@Autowired
private SysPermissionService permissionService; @Autowired
private ISysUserService userService;
@Autowired
private ISysUserService userService; @Autowired
private ISysDeptService deptService;
@Autowired
private ISysDeptService deptService; @PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/list")
@PreAuthorize("@ss.hasPermi('system:role:list')") public TableDataInfo list(SysRole role)
@GetMapping("/list") {
public TableDataInfo list(SysRole role) startPage();
{ List<SysRole> list = roleService.selectRoleList(role);
startPage(); return getDataTable(list);
List<SysRole> list = roleService.selectRoleList(role); }
return getDataTable(list);
} @Log(title = "角色管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:role:export')")
@Log(title = "角色管理", businessType = BusinessType.EXPORT) @PostMapping("/export")
@PreAuthorize("@ss.hasPermi('system:role:export')") public void export(HttpServletResponse response, SysRole role)
@PostMapping("/export") {
public void export(HttpServletResponse response, SysRole role) List<SysRole> list = roleService.selectRoleList(role);
{ ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class);
List<SysRole> list = roleService.selectRoleList(role); util.exportExcel(response, list, "角色数据");
ExcelUtil<SysRole> util = new ExcelUtil<SysRole>(SysRole.class); }
util.exportExcel(response, list, "角色数据");
} /**
* 根据角色编号获取详细信息
/** */
* 根据角色编号获取详细信息 @PreAuthorize("@ss.hasPermi('system:role:query')")
*/ @GetMapping(value = "/{roleId}")
@PreAuthorize("@ss.hasPermi('system:role:query')") public AjaxResult getInfo(@PathVariable Long roleId)
@GetMapping(value = "/{roleId}") {
public AjaxResult getInfo(@PathVariable Long roleId) roleService.checkRoleDataScope(roleId);
{ return success(roleService.selectRoleById(roleId));
roleService.checkRoleDataScope(roleId); }
return success(roleService.selectRoleById(roleId));
} /**
* 新增角色
/** */
* 新增角色 @PreAuthorize("@ss.hasPermi('system:role:add')")
*/ @Log(title = "角色管理", businessType = BusinessType.INSERT)
@PreAuthorize("@ss.hasPermi('system:role:add')") @PostMapping
@Log(title = "角色管理", businessType = BusinessType.INSERT) public AjaxResult add(@Validated @RequestBody SysRole role)
@PostMapping {
public AjaxResult add(@Validated @RequestBody SysRole role) if (!roleService.checkRoleNameUnique(role))
{ {
if (!roleService.checkRoleNameUnique(role)) return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在");
{ }
return error("新增角色'" + role.getRoleName() + "'失败,角色名称已存在"); else if (!roleService.checkRoleKeyUnique(role))
} {
else if (!roleService.checkRoleKeyUnique(role)) return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在");
{ }
return error("新增角色'" + role.getRoleName() + "'失败,角色权限已存在"); role.setCreateBy(getUsername());
} return toAjax(roleService.insertRole(role));
role.setCreateBy(getUsername());
return toAjax(roleService.insertRole(role)); }
} /**
* 修改保存角色
/** */
* 修改保存角色 @PreAuthorize("@ss.hasPermi('system:role:edit')")
*/ @Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PreAuthorize("@ss.hasPermi('system:role:edit')") @PutMapping
@Log(title = "角色管理", businessType = BusinessType.UPDATE) public AjaxResult edit(@Validated @RequestBody SysRole role)
@PutMapping {
public AjaxResult edit(@Validated @RequestBody SysRole role) roleService.checkRoleAllowed(role);
{ roleService.checkRoleDataScope(role.getRoleId());
roleService.checkRoleAllowed(role); if (!roleService.checkRoleNameUnique(role))
roleService.checkRoleDataScope(role.getRoleId()); {
if (!roleService.checkRoleNameUnique(role)) return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在");
{ }
return error("修改角色'" + role.getRoleName() + "'失败,角色名称已存在"); else if (!roleService.checkRoleKeyUnique(role))
} {
else if (!roleService.checkRoleKeyUnique(role)) return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在");
{ }
return error("修改角色'" + role.getRoleName() + "'失败,角色权限已存在"); role.setUpdateBy(getUsername());
}
role.setUpdateBy(getUsername()); if (roleService.updateRole(role) > 0)
{
if (roleService.updateRole(role) > 0) // 刷新所有持有该角色的在线用户权限
{ tokenService.refreshPermissionByRoleId(role.getRoleId(), permissionService);
// 更新缓存用户权限 return success();
LoginUser loginUser = getLoginUser(); }
if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员");
{ }
loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser())); /**
tokenService.setLoginUser(loginUser); * 修改保存数据权限
} */
return success(); @PreAuthorize("@ss.hasPermi('system:role:edit')")
} @Log(title = "角色管理", businessType = BusinessType.UPDATE)
return error("修改角色'" + role.getRoleName() + "'失败,请联系管理员"); @PutMapping("/dataScope")
} public AjaxResult dataScope(@RequestBody SysRole role)
{
/** roleService.checkRoleAllowed(role);
* 修改保存数据权限 roleService.checkRoleDataScope(role.getRoleId());
*/ return toAjax(roleService.authDataScope(role));
@PreAuthorize("@ss.hasPermi('system:role:edit')") }
@Log(title = "角色管理", businessType = BusinessType.UPDATE)
@PutMapping("/dataScope") /**
public AjaxResult dataScope(@RequestBody SysRole role) * 状态修改
{ */
roleService.checkRoleAllowed(role); @PreAuthorize("@ss.hasPermi('system:role:edit')")
roleService.checkRoleDataScope(role.getRoleId()); @Log(title = "角色管理", businessType = BusinessType.UPDATE)
return toAjax(roleService.authDataScope(role)); @PutMapping("/changeStatus")
} public AjaxResult changeStatus(@RequestBody SysRole role)
{
/** roleService.checkRoleAllowed(role);
* 状态修改 roleService.checkRoleDataScope(role.getRoleId());
*/ role.setUpdateBy(getUsername());
@PreAuthorize("@ss.hasPermi('system:role:edit')") return toAjax(roleService.updateRoleStatus(role));
@Log(title = "角色管理", businessType = BusinessType.UPDATE) }
@PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody SysRole role) /**
{ * 删除角色
roleService.checkRoleAllowed(role); */
roleService.checkRoleDataScope(role.getRoleId()); @PreAuthorize("@ss.hasPermi('system:role:remove')")
role.setUpdateBy(getUsername()); @Log(title = "角色管理", businessType = BusinessType.DELETE)
return toAjax(roleService.updateRoleStatus(role)); @DeleteMapping("/{roleIds}")
} public AjaxResult remove(@PathVariable Long[] roleIds)
{
/** return toAjax(roleService.deleteRoleByIds(roleIds));
* 删除角色 }
*/
@PreAuthorize("@ss.hasPermi('system:role:remove')") /**
@Log(title = "角色管理", businessType = BusinessType.DELETE) * 获取角色选择框列表
@DeleteMapping("/{roleIds}") */
public AjaxResult remove(@PathVariable Long[] roleIds) @PreAuthorize("@ss.hasPermi('system:role:query')")
{ @GetMapping("/optionselect")
return toAjax(roleService.deleteRoleByIds(roleIds)); public AjaxResult optionselect()
} {
return success(roleService.selectRoleAll());
/** }
* 获取角色选择框列表
*/ /**
@PreAuthorize("@ss.hasPermi('system:role:query')") * 查询已分配用户角色列表
@GetMapping("/optionselect") */
public AjaxResult optionselect() @PreAuthorize("@ss.hasPermi('system:role:list')")
{ @GetMapping("/authUser/allocatedList")
return success(roleService.selectRoleAll()); public TableDataInfo allocatedList(SysUser user)
} {
startPage();
/** List<SysUser> list = userService.selectAllocatedList(user);
* 查询已分配用户角色列表 return getDataTable(list);
*/ }
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/authUser/allocatedList") /**
public TableDataInfo allocatedList(SysUser user) * 查询未分配用户角色列表
{ */
startPage(); @PreAuthorize("@ss.hasPermi('system:role:list')")
List<SysUser> list = userService.selectAllocatedList(user); @GetMapping("/authUser/unallocatedList")
return getDataTable(list); public TableDataInfo unallocatedList(SysUser user)
} {
startPage();
/** List<SysUser> list = userService.selectUnallocatedList(user);
* 查询未分配用户角色列表 return getDataTable(list);
*/ }
@PreAuthorize("@ss.hasPermi('system:role:list')")
@GetMapping("/authUser/unallocatedList") /**
public TableDataInfo unallocatedList(SysUser user) * 取消授权用户
{ */
startPage(); @PreAuthorize("@ss.hasPermi('system:role:edit')")
List<SysUser> list = userService.selectUnallocatedList(user); @Log(title = "角色管理", businessType = BusinessType.GRANT)
return getDataTable(list); @PutMapping("/authUser/cancel")
} public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole)
{
/** return toAjax(roleService.deleteAuthUser(userRole));
* 取消授权用户 }
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')") /**
@Log(title = "角色管理", businessType = BusinessType.GRANT) * 批量取消授权用户
@PutMapping("/authUser/cancel") */
public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) @PreAuthorize("@ss.hasPermi('system:role:edit')")
{ @Log(title = "角色管理", businessType = BusinessType.GRANT)
return toAjax(roleService.deleteAuthUser(userRole)); @PutMapping("/authUser/cancelAll")
} public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds)
{
/** return toAjax(roleService.deleteAuthUsers(roleId, userIds));
* 批量取消授权用户 }
*/
@PreAuthorize("@ss.hasPermi('system:role:edit')") /**
@Log(title = "角色管理", businessType = BusinessType.GRANT) * 批量选择用户授权
@PutMapping("/authUser/cancelAll") */
public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) @PreAuthorize("@ss.hasPermi('system:role:edit')")
{ @Log(title = "角色管理", businessType = BusinessType.GRANT)
return toAjax(roleService.deleteAuthUsers(roleId, userIds)); @PutMapping("/authUser/selectAll")
} public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds)
{
/** roleService.checkRoleDataScope(roleId);
* 批量选择用户授权 return toAjax(roleService.insertAuthUsers(roleId, userIds));
*/ }
@PreAuthorize("@ss.hasPermi('system:role:edit')")
@Log(title = "角色管理", businessType = BusinessType.GRANT) /**
@PutMapping("/authUser/selectAll") * 获取对应角色部门树列表
public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) */
{ @PreAuthorize("@ss.hasPermi('system:role:query')")
roleService.checkRoleDataScope(roleId); @GetMapping(value = "/deptTree/{roleId}")
return toAjax(roleService.insertAuthUsers(roleId, userIds)); public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
} {
AjaxResult ajax = AjaxResult.success();
/** ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
* 获取对应角色部门树列表 ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
*/ return ajax;
@PreAuthorize("@ss.hasPermi('system:role:query')") }
@GetMapping(value = "/deptTree/{roleId}") }
public AjaxResult deptTree(@PathVariable("roleId") Long roleId)
{
AjaxResult ajax = AjaxResult.success();
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
return ajax;
}
}
@@ -1,256 +1,256 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.service.ISysDeptService; import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService; import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
/** /**
* 用户信息 * 用户信息
* *
* @author ruoyi * @author ruoyi
*/ */
@RestController @RestController
@RequestMapping("/system/user") @RequestMapping("/system/user")
public class SysUserController extends BaseController public class SysUserController extends BaseController
{ {
@Autowired @Autowired
private ISysUserService userService; private ISysUserService userService;
@Autowired @Autowired
private ISysRoleService roleService; private ISysRoleService roleService;
@Autowired @Autowired
private ISysDeptService deptService; private ISysDeptService deptService;
@Autowired @Autowired
private ISysPostService postService; private ISysPostService postService;
/** /**
* 获取用户列表 * 获取用户列表
*/ */
@PreAuthorize("@ss.hasPermi('system:user:list')") @PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/list") @GetMapping("/list")
public TableDataInfo list(SysUser user) public TableDataInfo list(SysUser user)
{ {
startPage(); startPage();
List<SysUser> list = userService.selectUserList(user); List<SysUser> list = userService.selectUserList(user);
return getDataTable(list); return getDataTable(list);
} }
@Log(title = "用户管理", businessType = BusinessType.EXPORT) @Log(title = "用户管理", businessType = BusinessType.EXPORT)
@PreAuthorize("@ss.hasPermi('system:user:export')") @PreAuthorize("@ss.hasPermi('system:user:export')")
@PostMapping("/export") @PostMapping("/export")
public void export(HttpServletResponse response, SysUser user) public void export(HttpServletResponse response, SysUser user)
{ {
List<SysUser> list = userService.selectUserList(user); List<SysUser> list = userService.selectUserList(user);
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
util.exportExcel(response, list, "用户数据"); util.exportExcel(response, list, "用户数据");
} }
@Log(title = "用户管理", businessType = BusinessType.IMPORT) @Log(title = "用户管理", businessType = BusinessType.IMPORT)
@PreAuthorize("@ss.hasPermi('system:user:import')") @PreAuthorize("@ss.hasPermi('system:user:import')")
@PostMapping("/importData") @PostMapping("/importData")
public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception
{ {
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
List<SysUser> userList = util.importExcel(file.getInputStream()); List<SysUser> userList = util.importExcel(file.getInputStream());
String operName = getUsername(); String operName = getUsername();
String message = userService.importUser(userList, updateSupport, operName); String message = userService.importUser(userList, updateSupport, operName);
return success(message); return success(message);
} }
@PostMapping("/importTemplate") @PostMapping("/importTemplate")
public void importTemplate(HttpServletResponse response) public void importTemplate(HttpServletResponse response)
{ {
ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class); ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
util.importTemplateExcel(response, "用户数据"); util.importTemplateExcel(response, "用户数据");
} }
/** /**
* 根据用户编号获取详细信息 * 根据用户编号获取详细信息
*/ */
@PreAuthorize("@ss.hasPermi('system:user:query')") @PreAuthorize("@ss.hasPermi('system:user:query')")
@GetMapping(value = { "/", "/{userId}" }) @GetMapping(value = { "/", "/{userId}" })
public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId)
{ {
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
if (StringUtils.isNotNull(userId)) if (StringUtils.isNotNull(userId))
{ {
userService.checkUserDataScope(userId); userService.checkUserDataScope(userId);
SysUser sysUser = userService.selectUserById(userId); SysUser sysUser = userService.selectUserById(userId);
ajax.put(AjaxResult.DATA_TAG, sysUser); ajax.put(AjaxResult.DATA_TAG, sysUser);
ajax.put("postIds", postService.selectPostListByUserId(userId)); ajax.put("postIds", postService.selectPostListByUserId(userId));
ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList())); ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
} }
List<SysRole> roles = roleService.selectRoleAll(); List<SysRole> roles = roleService.selectRoleAll();
ajax.put("roles", SecurityUtils.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); ajax.put("roles", SecurityUtils.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
ajax.put("posts", postService.selectPostAll()); ajax.put("posts", postService.selectPostAll());
return ajax; return ajax;
} }
/** /**
* 新增用户 * 新增用户
*/ */
@PreAuthorize("@ss.hasPermi('system:user:add')") @PreAuthorize("@ss.hasPermi('system:user:add')")
@Log(title = "用户管理", businessType = BusinessType.INSERT) @Log(title = "用户管理", businessType = BusinessType.INSERT)
@PostMapping @PostMapping
public AjaxResult add(@Validated @RequestBody SysUser user) public AjaxResult add(@Validated @RequestBody SysUser user)
{ {
deptService.checkDeptDataScope(user.getDeptId()); deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds()); roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user)) if (!userService.checkUserNameUnique(user))
{ {
return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
} }
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{ {
return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在"); return error("新增用户'" + user.getUserName() + "'失败,手机号码已存在");
} }
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{ {
return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在"); return error("新增用户'" + user.getUserName() + "'失败,邮箱账号已存在");
} }
user.setCreateBy(getUsername()); user.setCreateBy(getUsername());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
return toAjax(userService.insertUser(user)); return toAjax(userService.insertUser(user));
} }
/** /**
* 修改用户 * 修改用户
*/ */
@PreAuthorize("@ss.hasPermi('system:user:edit')") @PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE) @Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping @PutMapping
public AjaxResult edit(@Validated @RequestBody SysUser user) public AjaxResult edit(@Validated @RequestBody SysUser user)
{ {
userService.checkUserAllowed(user); userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId()); userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId()); deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds()); roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user)) if (!userService.checkUserNameUnique(user))
{ {
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
} }
else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
{ {
return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
} }
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
{ {
return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
} }
user.setUpdateBy(getUsername()); user.setUpdateBy(getUsername());
return toAjax(userService.updateUser(user)); return toAjax(userService.updateUser(user));
} }
/** /**
* 删除用户 * 删除用户
*/ */
@PreAuthorize("@ss.hasPermi('system:user:remove')") @PreAuthorize("@ss.hasPermi('system:user:remove')")
@Log(title = "用户管理", businessType = BusinessType.DELETE) @Log(title = "用户管理", businessType = BusinessType.DELETE)
@DeleteMapping("/{userIds}") @DeleteMapping("/{userIds}")
public AjaxResult remove(@PathVariable Long[] userIds) public AjaxResult remove(@PathVariable Long[] userIds)
{ {
if (ArrayUtils.contains(userIds, getUserId())) if (ArrayUtils.contains(userIds, getUserId()))
{ {
return error("当前用户不能删除"); return error("当前用户不能删除");
} }
return toAjax(userService.deleteUserByIds(userIds)); return toAjax(userService.deleteUserByIds(userIds));
} }
/** /**
* 重置密码 * 重置密码
*/ */
@PreAuthorize("@ss.hasPermi('system:user:resetPwd')") @PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE) @Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/resetPwd") @PutMapping("/resetPwd")
public AjaxResult resetPwd(@RequestBody SysUser user) public AjaxResult resetPwd(@RequestBody SysUser user)
{ {
userService.checkUserAllowed(user); userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId()); userService.checkUserDataScope(user.getUserId());
user.setPassword(SecurityUtils.encryptPassword(user.getPassword())); user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
user.setUpdateBy(getUsername()); user.setUpdateBy(getUsername());
return toAjax(userService.resetPwd(user)); return toAjax(userService.resetPwd(user));
} }
/** /**
* 状态修改 * 状态修改
*/ */
@PreAuthorize("@ss.hasPermi('system:user:edit')") @PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.UPDATE) @Log(title = "用户管理", businessType = BusinessType.UPDATE)
@PutMapping("/changeStatus") @PutMapping("/changeStatus")
public AjaxResult changeStatus(@RequestBody SysUser user) public AjaxResult changeStatus(@RequestBody SysUser user)
{ {
userService.checkUserAllowed(user); userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId()); userService.checkUserDataScope(user.getUserId());
user.setUpdateBy(getUsername()); user.setUpdateBy(getUsername());
return toAjax(userService.updateUserStatus(user)); return toAjax(userService.updateUserStatus(user));
} }
/** /**
* 根据用户编号获取授权角色 * 根据用户编号获取授权角色
*/ */
@PreAuthorize("@ss.hasPermi('system:user:query')") @PreAuthorize("@ss.hasPermi('system:user:query')")
@GetMapping("/authRole/{userId}") @GetMapping("/authRole/{userId}")
public AjaxResult authRole(@PathVariable("userId") Long userId) public AjaxResult authRole(@PathVariable("userId") Long userId)
{ {
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
SysUser user = userService.selectUserById(userId); SysUser user = userService.selectUserById(userId);
List<SysRole> roles = roleService.selectRolesByUserId(userId); List<SysRole> roles = roleService.selectRolesByUserId(userId);
ajax.put("user", user); ajax.put("user", user);
ajax.put("roles", SecurityUtils.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList())); ajax.put("roles", SecurityUtils.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
return ajax; return ajax;
} }
/** /**
* 用户授权角色 * 用户授权角色
*/ */
@PreAuthorize("@ss.hasPermi('system:user:edit')") @PreAuthorize("@ss.hasPermi('system:user:edit')")
@Log(title = "用户管理", businessType = BusinessType.GRANT) @Log(title = "用户管理", businessType = BusinessType.GRANT)
@PutMapping("/authRole") @PutMapping("/authRole")
public AjaxResult insertAuthRole(Long userId, Long[] roleIds) public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
{ {
userService.checkUserDataScope(userId); userService.checkUserDataScope(userId);
roleService.checkRoleDataScope(roleIds); roleService.checkRoleDataScope(roleIds);
userService.insertUserAuth(userId, roleIds); userService.insertUserAuth(userId, roleIds);
return success(); return success();
} }
/** /**
* 获取部门树列表 * 获取部门树列表
*/ */
@PreAuthorize("@ss.hasPermi('system:user:list')") @PreAuthorize("@ss.hasPermi('system:user:list')")
@GetMapping("/deptTree") @GetMapping("/deptTree")
public AjaxResult deptTree(SysDept dept) public AjaxResult deptTree(SysDept dept)
{ {
return success(deptService.selectDeptTreeList(dept)); return success(deptService.selectDeptTreeList(dept));
} }
} }
@@ -0,0 +1,103 @@
package com.ruoyi.web.controller.tool;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.security.access.prepost.PreAuthorize;
import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.iot.domain.MqttMessageDTO;
import com.ruoyi.iot.lock.protocol.YdlinkFrameDTO;
import com.ruoyi.iot.service.IMqttService;
/**
* 独立 QA 测试环境专属:Mock MQTT 消息检查与设备回执驱动 Controller
* 仅在配置 train.iot.mock-mode=true 时加载,且必须经过管理员权限校验,禁止生产泄露与匿名调用
*/
@RestController
@RequestMapping("/qa/mock")
@ConditionalOnProperty(name = "iot.mqtt.mock", havingValue = "true")
@PreAuthorize("@ss.hasRole('admin') or @ss.hasPermi('iot:command:edit')")
public class QaMockMqttApiController
{
@Autowired
private IMqttService mqttService;
/**
* 获取所有拦截到的下行指令
*/
@GetMapping("/published")
public AjaxResult getPublishedMessages()
{
return AjaxResult.success(mqttService.getMockPublishedMessages());
}
/**
* 清空已拦截的下行指令
*/
@PostMapping("/clear")
public AjaxResult clearPublishedMessages()
{
mqttService.getMockPublishedMessages().clear();
return AjaxResult.success("已清空");
}
/**
* 模拟注入网关与门锁回执报文
*
* @param body 参数字典包含:
* groupCode: 分组编号 (如 GRP_FUSION_TEST)
* commandNo: 命令流水号 seq
* deviceSn: 门锁SN (如 LOCK-ZY-101)
* op: 操作类型 (add / delete)
* code: 结果码 (0=门锁成功, 10=网关已接收, 20=门锁执行失败)
* msg: 说明消息
*/
@PostMapping("/send-ack")
public AjaxResult sendAck(@RequestBody Map<String, Object> body)
{
String groupCode = (String) body.getOrDefault("groupCode", "GRP_FUSION_TEST");
String commandNo = (String) body.get("commandNo");
String deviceSn = (String) body.getOrDefault("deviceSn", "LOCK-ZY-101");
String op = (String) body.getOrDefault("op", "add");
String code = String.valueOf(body.getOrDefault("code", "0"));
String msg = (String) body.getOrDefault("msg", "mock execution ok");
if (commandNo == null || commandNo.isEmpty())
{
return AjaxResult.error("commandNo (seq) 不能为空");
}
String topic = "ydlink/" + groupCode + "/thing/data/batch_report";
YdlinkFrameDTO frame = new YdlinkFrameDTO();
frame.setDevId(groupCode);
frame.setSeq(commandNo);
frame.setOp(op);
frame.setAt(String.valueOf(System.currentTimeMillis() / 1000L));
List<Object> records = new ArrayList<>();
records.add(Arrays.asList(op, deviceSn, code, "person_mock", msg));
frame.setParams(records);
String payload = JSON.toJSONString(frame);
mqttService.mockReceive(topic, payload);
return AjaxResult.success("Mock 回执注入成功", Map.of(
"topic", topic,
"seq", commandNo,
"code", code,
"payload", payload
));
}
}
@@ -1,183 +1,175 @@
package com.ruoyi.web.controller.tool; package com.ruoyi.web.controller.tool;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import io.swagger.annotations.Api; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.annotations.ApiImplicitParam; import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.annotations.ApiImplicitParams; import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty; /**
import io.swagger.annotations.ApiOperation; * swagger 用户测试方法
*
/** * @author ruoyi
* swagger 用户测试方法 */
* @Tag(name = "用户信息管理")
* @author ruoyi @RestController
*/ @RequestMapping("/test/user")
@Api("用户信息管理") public class TestController extends BaseController
@RestController {
@RequestMapping("/test/user") private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>();
public class TestController extends BaseController {
{ users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
private final static Map<Integer, UserEntity> users = new LinkedHashMap<Integer, UserEntity>(); users.put(2, new UserEntity(2, "ry", "admin123", "15666666666"));
{ }
users.put(1, new UserEntity(1, "admin", "admin123", "15888888888"));
users.put(2, new UserEntity(2, "ry", "admin123", "15666666666")); @Operation(summary = "获取用户列表")
} @GetMapping("/list")
public R<List<UserEntity>> userList()
@ApiOperation("获取用户列表") {
@GetMapping("/list") List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
public R<List<UserEntity>> userList() return R.ok(userList);
{ }
List<UserEntity> userList = new ArrayList<UserEntity>(users.values());
return R.ok(userList); @Operation(summary = "获取用户详细")
} @GetMapping("/{userId}")
public R<UserEntity> getUser(@PathVariable(name = "userId")
@ApiOperation("获取用户详细") Integer userId)
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) {
@GetMapping("/{userId}") if (!users.isEmpty() && users.containsKey(userId))
public R<UserEntity> getUser(@PathVariable Integer userId) {
{ return R.ok(users.get(userId));
if (!users.isEmpty() && users.containsKey(userId)) }
{ else
return R.ok(users.get(userId)); {
} return R.fail("用户不存在");
else }
{ }
return R.fail("用户不存在");
} @Operation(summary = "新增用户")
} @PostMapping("/save")
public R<String> save(UserEntity user)
@ApiOperation("新增用户") {
@ApiImplicitParams({ if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
@ApiImplicitParam(name = "userId", value = "用户id", dataType = "Integer", dataTypeClass = Integer.class), {
@ApiImplicitParam(name = "username", value = "用户名称", dataType = "String", dataTypeClass = String.class), return R.fail("用户ID不能为空");
@ApiImplicitParam(name = "password", value = "用户密码", dataType = "String", dataTypeClass = String.class), }
@ApiImplicitParam(name = "mobile", value = "用户手机", dataType = "String", dataTypeClass = String.class) users.put(user.getUserId(), user);
}) return R.ok();
@PostMapping("/save") }
public R<String> save(UserEntity user)
{ @Operation(summary = "更新用户")
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) @PutMapping("/update")
{ public R<String> update(@RequestBody
return R.fail("用户ID不能为空"); UserEntity user)
} {
users.put(user.getUserId(), user); if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId()))
return R.ok(); {
} return R.fail("用户ID不能为空");
}
@ApiOperation("更新用户") if (users.isEmpty() || !users.containsKey(user.getUserId()))
@PutMapping("/update") {
public R<String> update(@RequestBody UserEntity user) return R.fail("用户不存在");
{ }
if (StringUtils.isNull(user) || StringUtils.isNull(user.getUserId())) users.remove(user.getUserId());
{ users.put(user.getUserId(), user);
return R.fail("用户ID不能为空"); return R.ok();
} }
if (users.isEmpty() || !users.containsKey(user.getUserId()))
{ @Operation(summary = "删除用户信息")
return R.fail("用户不存在"); @DeleteMapping("/{userId}")
} public R<String> delete(@PathVariable(name = "userId")
users.remove(user.getUserId()); Integer userId)
users.put(user.getUserId(), user); {
return R.ok(); if (!users.isEmpty() && users.containsKey(userId))
} {
users.remove(userId);
@ApiOperation("删除用户信息") return R.ok();
@ApiImplicitParam(name = "userId", value = "用户ID", required = true, dataType = "int", paramType = "path", dataTypeClass = Integer.class) }
@DeleteMapping("/{userId}") else
public R<String> delete(@PathVariable Integer userId) {
{ return R.fail("用户不存在");
if (!users.isEmpty() && users.containsKey(userId)) }
{ }
users.remove(userId); }
return R.ok();
} @Schema(description = "用户实体")
else class UserEntity
{ {
return R.fail("用户不存在"); @Schema(title = "用户ID")
} private Integer userId;
}
} @Schema(title = "用户名称")
private String username;
@ApiModel(value = "UserEntity", description = "用户实体")
class UserEntity @Schema(title = "用户密码")
{ private String password;
@ApiModelProperty("用户ID")
private Integer userId; @Schema(title = "用户手机")
private String mobile;
@ApiModelProperty("用户名称")
private String username; public UserEntity()
{
@ApiModelProperty("用户密码")
private String password; }
@ApiModelProperty("用户手机") public UserEntity(Integer userId, String username, String password, String mobile)
private String mobile; {
this.userId = userId;
public UserEntity() this.username = username;
{ this.password = password;
this.mobile = mobile;
} }
public UserEntity(Integer userId, String username, String password, String mobile) public Integer getUserId()
{ {
this.userId = userId; return userId;
this.username = username; }
this.password = password;
this.mobile = mobile; public void setUserId(Integer userId)
} {
this.userId = userId;
public Integer getUserId() }
{
return userId; public String getUsername()
} {
return username;
public void setUserId(Integer userId) }
{
this.userId = userId; public void setUsername(String username)
} {
this.username = username;
public String getUsername() }
{
return username; public String getPassword()
} {
return password;
public void setUsername(String username) }
{
this.username = username; public void setPassword(String password)
} {
this.password = password;
public String getPassword() }
{
return password; public String getMobile()
} {
return mobile;
public void setPassword(String password) }
{
this.password = password; public void setMobile(String mobile)
} {
this.mobile = mobile;
public String getMobile() }
{ }
return mobile;
}
public void setMobile(String mobile)
{
this.mobile = mobile;
}
}
@@ -1,7 +1,7 @@
package com.ruoyi.web.controller.train; package com.ruoyi.web.controller.train;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -1,7 +1,7 @@
package com.ruoyi.web.controller.train; package com.ruoyi.web.controller.train;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -1,7 +1,7 @@
package com.ruoyi.web.controller.train; package com.ruoyi.web.controller.train;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -1,7 +1,7 @@
package com.ruoyi.web.controller.train; package com.ruoyi.web.controller.train;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -2,7 +2,7 @@ package com.ruoyi.web.controller.train;
import java.util.List; import java.util.List;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import javax.validation.Valid; import jakarta.validation.Valid;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
@@ -1,7 +1,7 @@
package com.ruoyi.web.controller.train; package com.ruoyi.web.controller.train;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -1,7 +1,7 @@
package com.ruoyi.web.controller.train; package com.ruoyi.web.controller.train;
import java.util.List; import java.util.List;
import javax.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@@ -1,125 +1,64 @@
package com.ruoyi.web.core.config; package com.ruoyi.web.core.config;
import java.util.ArrayList; import org.springframework.beans.factory.annotation.Autowired;
import java.util.List; import org.springframework.context.annotation.Bean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Configuration;
import org.springframework.beans.factory.annotation.Value; import com.ruoyi.common.config.RuoYiConfig;
import org.springframework.context.annotation.Bean; import io.swagger.v3.oas.models.Components;
import org.springframework.context.annotation.Configuration; import io.swagger.v3.oas.models.OpenAPI;
import com.ruoyi.common.config.RuoYiConfig; import io.swagger.v3.oas.models.info.Contact;
import io.swagger.annotations.ApiOperation; import io.swagger.v3.oas.models.info.Info;
import io.swagger.models.auth.In; import io.swagger.v3.oas.models.security.SecurityRequirement;
import springfox.documentation.builders.ApiInfoBuilder; import io.swagger.v3.oas.models.security.SecurityScheme;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors; /**
import springfox.documentation.service.ApiInfo; * Swagger2的接口配置
import springfox.documentation.service.ApiKey; *
import springfox.documentation.service.AuthorizationScope; * @author ruoyi
import springfox.documentation.service.Contact; */
import springfox.documentation.service.SecurityReference; @Configuration
import springfox.documentation.service.SecurityScheme; public class SwaggerConfig
import springfox.documentation.spi.DocumentationType; {
import springfox.documentation.spi.service.contexts.SecurityContext; /** 系统基础配置 */
import springfox.documentation.spring.web.plugins.Docket; @Autowired
private RuoYiConfig ruoyiConfig;
/**
* Swagger2的接口配置 /**
* * 自定义的 OpenAPI 对象
* @author ruoyi */
*/ @Bean
@Configuration public OpenAPI customOpenApi()
public class SwaggerConfig {
{ return new OpenAPI().components(new Components()
/** 系统基础配置 */ // 设置认证的请求头
@Autowired .addSecuritySchemes("apikey", securityScheme()))
private RuoYiConfig ruoyiConfig; .addSecurityItem(new SecurityRequirement().addList("apikey"))
.info(getApiInfo());
/** 是否开启swagger */ }
@Value("${swagger.enabled}")
private boolean enabled; @Bean
public SecurityScheme securityScheme()
/** 设置请求的统一前缀 */ {
@Value("${swagger.pathMapping}") return new SecurityScheme()
private String pathMapping; .type(SecurityScheme.Type.APIKEY)
.name("Authorization")
/** .in(SecurityScheme.In.HEADER)
* 创建API .scheme("Bearer");
*/ }
@Bean
public Docket createRestApi() /**
{ * 添加摘要信息
return new Docket(DocumentationType.OAS_30) */
// 是否启用Swagger public Info getApiInfo()
.enable(enabled) {
// 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息) return new Info()
.apiInfo(apiInfo()) // 设置标题
// 设置哪些接口暴露给Swagger展示 .title("标题:若依管理系统_接口文档")
.select() // 描述
// 扫描所有有注解的api,用这种方式更灵活 .description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
.apis(RequestHandlerSelectors.withMethodAnnotation(ApiOperation.class)) // 作者信息
// 扫描指定包中的swagger注解 .contact(new Contact().name(ruoyiConfig.getName()))
// .apis(RequestHandlerSelectors.basePackage("com.ruoyi.project.tool.swagger")) // 版本
// 扫描所有 .apis(RequestHandlerSelectors.any()) .version("版本号:" + ruoyiConfig.getVersion());
.paths(PathSelectors.any()) }
.build() }
/* 设置安全模式,swagger可以设置访问token */
.securitySchemes(securitySchemes())
.securityContexts(securityContexts())
.pathMapping(pathMapping);
}
/**
* 安全模式,这里指定token通过Authorization头请求头传递
*/
private List<SecurityScheme> securitySchemes()
{
List<SecurityScheme> apiKeyList = new ArrayList<SecurityScheme>();
apiKeyList.add(new ApiKey("Authorization", "Authorization", In.HEADER.toValue()));
return apiKeyList;
}
/**
* 安全上下文
*/
private List<SecurityContext> securityContexts()
{
List<SecurityContext> securityContexts = new ArrayList<>();
securityContexts.add(
SecurityContext.builder()
.securityReferences(defaultAuth())
.operationSelector(o -> o.requestMappingPattern().matches("/.*"))
.build());
return securityContexts;
}
/**
* 默认的安全上引用
*/
private List<SecurityReference> defaultAuth()
{
AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
authorizationScopes[0] = authorizationScope;
List<SecurityReference> securityReferences = new ArrayList<>();
securityReferences.add(new SecurityReference("Authorization", authorizationScopes));
return securityReferences;
}
/**
* 添加摘要信息
*/
private ApiInfo apiInfo()
{
// 用ApiInfoBuilder进行定制
return new ApiInfoBuilder()
// 设置标题
.title("标题:若依管理系统_接口文档")
// 描述
.description("描述:用于管理集团旗下公司的人员信息,具体包括XXX,XXX模块...")
// 作者信息
.contact(new Contact(ruoyiConfig.getName(), null, null))
// 版本
.version("版本号:" + ruoyiConfig.getVersion())
.build();
}
}
@@ -1,460 +1,451 @@
package com.ruoyi.web.service.train; package com.ruoyi.web.service.train;
import java.util.ArrayList; import com.ruoyi.common.core.domain.entity.SysRole;
import java.util.Collections; import com.ruoyi.common.core.domain.entity.SysUser;
import java.util.HashSet; import com.ruoyi.common.exception.ServiceException;
import java.util.List; import com.ruoyi.common.utils.StringUtils;
import java.util.Map; import com.ruoyi.common.utils.bean.BeanUtils;
import java.util.Objects; import com.ruoyi.system.service.ISysRoleService;
import java.util.Set; import com.ruoyi.system.service.ISysUserService;
import java.util.stream.Collectors; import com.ruoyi.train.domain.TrainStudent;
import org.springframework.stereotype.Service; import com.ruoyi.train.domain.TrainTeacher;
import org.springframework.transaction.annotation.Transactional; import com.ruoyi.train.domain.vo.*;
import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.train.mapper.TrainStudentMapper;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.train.mapper.TrainTeacherMapper;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.train.service.ITrainingIdentityService;
import com.ruoyi.common.utils.StringUtils; import org.springframework.stereotype.Service;
import com.ruoyi.common.utils.bean.BeanUtils; import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import java.util.*;
import com.ruoyi.train.domain.TrainStudent; import java.util.stream.Collectors;
import com.ruoyi.train.domain.TrainTeacher;
import com.ruoyi.train.domain.vo.BindableUserVO; /**
import com.ruoyi.train.domain.vo.StudentAdminVO; * 管理员端业务身份账号绑定编排服务。
import com.ruoyi.train.domain.vo.StudentDetailVO; *
import com.ruoyi.train.domain.vo.StudentItemVO; * <p>提供受控候选系统用户检索、角色校验、防静默覆盖保护,
import com.ruoyi.train.domain.vo.TeacherAdminVO; * 并复用底层 {@link ITrainingIdentityService} 执行跨表互斥与并发锁绑定。</p>
import com.ruoyi.train.mapper.TrainStudentMapper; *
import com.ruoyi.train.mapper.TrainTeacherMapper; * @author ruoyi
import com.ruoyi.train.service.ITrainingIdentityService; */
@Service
/** public class TrainAccountBindingAdminService
* 管理员端业务身份账号绑定编排服务。 {
* private final ITrainingIdentityService identityService;
* <p>提供受控候选系统用户检索、角色校验、防静默覆盖保护, private final ISysUserService userService;
* 并复用底层 {@link ITrainingIdentityService} 执行跨表互斥与并发锁绑定。</p> private final ISysRoleService roleService;
* private final TrainTeacherMapper teacherMapper;
* @author ruoyi private final TrainStudentMapper studentMapper;
*/
@Service public TrainAccountBindingAdminService(ITrainingIdentityService identityService,
public class TrainAccountBindingAdminService ISysUserService userService,
{ ISysRoleService roleService,
private final ITrainingIdentityService identityService; TrainTeacherMapper teacherMapper,
private final ISysUserService userService; TrainStudentMapper studentMapper)
private final ISysRoleService roleService; {
private final TrainTeacherMapper teacherMapper; this.identityService = identityService;
private final TrainStudentMapper studentMapper; this.userService = userService;
this.roleService = roleService;
public TrainAccountBindingAdminService(ITrainingIdentityService identityService, this.teacherMapper = teacherMapper;
ISysUserService userService, this.studentMapper = studentMapper;
ISysRoleService roleService, }
TrainTeacherMapper teacherMapper,
TrainStudentMapper studentMapper) /**
{ * 查询候选可绑定系统用户列表 (最小受控字段)
this.identityService = identityService; *
this.userService = userService; * @param targetType 目标身份类型 ("TEACHER" / "STUDENT")
this.roleService = roleService; * @param keyword 模糊搜索关键字 (匹配 userName 或 nickName)
this.teacherMapper = teacherMapper; * @return 候选用户视图列表
this.studentMapper = studentMapper; */
} public List<BindableUserVO> selectBindableUsers(String targetType, String keyword)
{
/** String expectedRoleKey = "TEACHER".equalsIgnoreCase(targetType) ? "train_teacher" : "train_student";
* 查询候选可绑定系统用户列表 (最小受控字段) SysUser queryUser = new SysUser();
* queryUser.setDelFlag("0");
* @param targetType 目标身份类型 ("TEACHER" / "STUDENT") if (StringUtils.isNotEmpty(keyword))
* @param keyword 模糊搜索关键字 (匹配 userName 或 nickName) {
* @return 候选用户视图列表 queryUser.setUserName(keyword.trim());
*/ }
public List<BindableUserVO> selectBindableUsers(String targetType, String keyword) List<SysUser> userList = userService.selectUserList(queryUser);
{ List<BindableUserVO> result = new ArrayList<>();
String expectedRoleKey = "TEACHER".equalsIgnoreCase(targetType) ? "train_teacher" : "train_student";
SysUser queryUser = new SysUser(); for (SysUser user : userList)
queryUser.setDelFlag("0"); {
if (StringUtils.isNotEmpty(keyword)) // 如果搜索关键字不匹配用户名也不匹配用户昵称,则跳过
{ if (StringUtils.isNotEmpty(keyword))
queryUser.setUserName(keyword.trim()); {
} String kw = keyword.trim().toLowerCase();
List<SysUser> userList = userService.selectUserList(queryUser); boolean matchName = user.getUserName() != null && user.getUserName().toLowerCase().contains(kw);
List<BindableUserVO> result = new ArrayList<>(); boolean matchNick = user.getNickName() != null && user.getNickName().toLowerCase().contains(kw);
if (!matchName && !matchNick)
for (SysUser user : userList) {
{ continue;
// 如果搜索关键字不匹配用户名也不匹配用户昵称,则跳过 }
if (StringUtils.isNotEmpty(keyword)) }
{
String kw = keyword.trim().toLowerCase(); BindableUserVO vo = new BindableUserVO();
boolean matchName = user.getUserName() != null && user.getUserName().toLowerCase().contains(kw); vo.setUserId(user.getUserId());
boolean matchNick = user.getNickName() != null && user.getNickName().toLowerCase().contains(kw); vo.setUserName(user.getUserName());
if (!matchName && !matchNick) vo.setNickName(user.getNickName());
{ vo.setStatus(user.getStatus());
continue;
} List<SysRole> roles = roleService.selectRolesByUserId(user.getUserId());
} List<String> roleKeys = roles != null
? roles.stream().map(SysRole::getRoleKey).collect(Collectors.toList())
BindableUserVO vo = new BindableUserVO(); : new ArrayList<>();
vo.setUserId(user.getUserId()); vo.setRoleKeys(roleKeys);
vo.setUserName(user.getUserName());
vo.setNickName(user.getNickName()); boolean hasTargetRole = roleKeys.contains(expectedRoleKey);
vo.setStatus(user.getStatus()); vo.setHasRole(hasTargetRole);
List<SysRole> roles = roleService.selectRolesByUserId(user.getUserId()); // 检查当前用户是否已被绑定
List<String> roleKeys = roles != null TrainTeacher boundTeacher = teacherMapper.selectTrainTeacherByUserId(user.getUserId());
? roles.stream().map(SysRole::getRoleKey).collect(Collectors.toList()) TrainStudent boundStudent = studentMapper.selectTrainStudentByUserId(user.getUserId());
: new ArrayList<>();
vo.setRoleKeys(roleKeys); boolean canBind = true;
String reason = "";
boolean hasTargetRole = roleKeys.contains(expectedRoleKey);
vo.setHasRole(hasTargetRole); if (!"0".equals(user.getStatus()))
{
// 检查当前用户是否已被绑定 canBind = false;
TrainTeacher boundTeacher = teacherMapper.selectTrainTeacherByUserId(user.getUserId()); reason = "账号已被停用";
TrainStudent boundStudent = studentMapper.selectTrainStudentByUserId(user.getUserId()); }
else if (!hasTargetRole)
boolean canBind = true; {
String reason = ""; canBind = false;
reason = "TEACHER".equalsIgnoreCase(targetType)
if (!"0".equals(user.getStatus())) ? "未分配教师角色(train_teacher)"
{ : "未分配学员角色(train_student)";
canBind = false; }
reason = "账号已被停用"; else if (boundTeacher != null)
} {
else if (!hasTargetRole) vo.setBoundType("TEACHER");
{ vo.setBoundBusinessId(boundTeacher.gettId());
canBind = false; canBind = false;
reason = "TEACHER".equalsIgnoreCase(targetType) reason = "已被教师(" + boundTeacher.gettName() + " / " + boundTeacher.gettId() + ")绑定";
? "未分配教师角色(train_teacher)" }
: "未分配学员角色(train_student)"; else if (boundStudent != null)
} {
else if (boundTeacher != null) vo.setBoundType("STUDENT");
{ vo.setBoundBusinessId(boundStudent.getsId());
vo.setBoundType("TEACHER"); canBind = false;
vo.setBoundBusinessId(boundTeacher.gettId()); reason = "已被学员(" + boundStudent.getsName() + " / " + boundStudent.getsId() + ")绑定";
canBind = false; }
reason = "已被教师(" + boundTeacher.gettName() + " / " + boundTeacher.gettId() + ")绑定";
} vo.setCanBind(canBind);
else if (boundStudent != null) vo.setReason(reason);
{ result.add(vo);
vo.setBoundType("STUDENT"); }
vo.setBoundBusinessId(boundStudent.getsId());
canBind = false; return result;
reason = "已被学员(" + boundStudent.getsName() + " / " + boundStudent.getsId() + ")绑定"; }
}
/**
vo.setCanBind(canBind); * 管理员为教师绑定系统用户 (防静默覆盖、严格校验角色与账号状态)
vo.setReason(reason); */
result.add(vo); @Transactional(rollbackFor = Exception.class)
} public void bindTeacherAccount(String tId, Long userId)
{
return result; if (userId == null)
} {
throw new ServiceException("绑定的系统用户ID不能为空");
/** }
* 管理员为教师绑定系统用户 (防静默覆盖、严格校验角色与账号状态) TrainTeacher teacher = teacherMapper.selectTrainTeacherByTId(tId);
*/ if (teacher == null)
@Transactional(rollbackFor = Exception.class) {
public void bindTeacherAccount(String tId, Long userId) throw new ServiceException("教师业务档案不存在");
{ }
if (userId == null) if (teacher.getUserId() != null)
{ {
throw new ServiceException("绑定的系统用户ID不能为空"); if (teacher.getUserId().equals(userId))
} {
TrainTeacher teacher = teacherMapper.selectTrainTeacherByTId(tId); return; // 幂等支持
if (teacher == null) }
{ throw new ServiceException("该教师档案已关联系统账号(userId=" + teacher.getUserId() + "),请先解除关联后再绑定新账号");
throw new ServiceException("教师业务档案不存在"); }
}
if (teacher.getUserId() != null) // 严格校验目标用户有效性与 train_teacher 角色
{ validateUserRole(userId, "train_teacher", "教师");
if (teacher.getUserId().equals(userId))
{ // 复用底层原子互斥绑定
return; // 幂等支持 identityService.bindTeacherUser(tId, userId);
} }
throw new ServiceException("该教师档案已关联系统账号(userId=" + teacher.getUserId() + "),请先解除关联后再绑定新账号");
} /**
* 管理员为教师解绑系统用户
// 严格校验目标用户有效性与 train_teacher 角色 */
validateUserRole(userId, "train_teacher", "教师"); @Transactional(rollbackFor = Exception.class)
public void unbindTeacherAccount(String tId)
// 复用底层原子互斥绑定 {
identityService.bindTeacherUser(tId, userId); TrainTeacher teacher = teacherMapper.selectTrainTeacherByTId(tId);
} if (teacher == null)
{
/** throw new ServiceException("教师业务档案不存在");
* 管理员为教师解绑系统用户 }
*/ if (teacher.getUserId() == null)
@Transactional(rollbackFor = Exception.class) {
public void unbindTeacherAccount(String tId) return; // 幂等支持
{ }
TrainTeacher teacher = teacherMapper.selectTrainTeacherByTId(tId); identityService.unbindTeacherUser(tId);
if (teacher == null) }
{
throw new ServiceException("教师业务档案不存在"); /**
} * 管理员为学员绑定系统用户 (防静默覆盖、严格校验角色与账号状态)
if (teacher.getUserId() == null) */
{ @Transactional(rollbackFor = Exception.class)
return; // 幂等支持 public void bindStudentAccount(String sId, Long userId)
} {
identityService.unbindTeacherUser(tId); if (userId == null)
} {
throw new ServiceException("绑定的系统用户ID不能为空");
/** }
* 管理员为学员绑定系统用户 (防静默覆盖、严格校验角色与账号状态) TrainStudent student = studentMapper.selectTrainStudentBySId(sId);
*/ if (student == null)
@Transactional(rollbackFor = Exception.class) {
public void bindStudentAccount(String sId, Long userId) throw new ServiceException("学员业务档案不存在");
{ }
if (userId == null) if (student.getUserId() != null)
{ {
throw new ServiceException("绑定的系统用户ID不能为空"); if (student.getUserId().equals(userId))
} {
TrainStudent student = studentMapper.selectTrainStudentBySId(sId); return; // 幂等支持
if (student == null) }
{ throw new ServiceException("该学员档案已关联系统账号(userId=" + student.getUserId() + "),请先解除关联后再绑定新账号");
throw new ServiceException("学员业务档案不存在"); }
}
if (student.getUserId() != null) // 严格校验目标用户有效性与 train_student 角色
{ validateUserRole(userId, "train_student", "学员");
if (student.getUserId().equals(userId))
{ // 复用底层原子互斥绑定
return; // 幂等支持 identityService.bindStudentUser(sId, userId);
} }
throw new ServiceException("该学员档案已关联系统账号(userId=" + student.getUserId() + "),请先解除关联后再绑定新账号");
} /**
* 管理员为学员解绑系统用户
// 严格校验目标用户有效性与 train_student 角色 */
validateUserRole(userId, "train_student", "学员"); @Transactional(rollbackFor = Exception.class)
public void unbindStudentAccount(String sId)
// 复用底层原子互斥绑定 {
identityService.bindStudentUser(sId, userId); TrainStudent student = studentMapper.selectTrainStudentBySId(sId);
} if (student == null)
{
/** throw new ServiceException("学员业务档案不存在");
* 管理员为学员解绑系统用户 }
*/ if (student.getUserId() == null)
@Transactional(rollbackFor = Exception.class) {
public void unbindStudentAccount(String sId) return; // 幂等支持
{ }
TrainStudent student = studentMapper.selectTrainStudentBySId(sId); identityService.unbindStudentUser(sId);
if (student == null) }
{
throw new ServiceException("学员业务档案不存在"); /**
} * 批量为教师列表装配账号绑定管理视图 (单次批量查询 + 内存映射,杜绝 N+1)
if (student.getUserId() == null) *
{ * @param list 原始教师列表
return; // 幂等支持 * @return 管理端教师视图列表
} */
identityService.unbindStudentUser(sId); public List<TeacherAdminVO> toTeacherAdminList(List<TrainTeacher> list)
} {
if (list == null || list.isEmpty())
/** {
* 批量为教师列表装配账号绑定管理视图 (单次批量查询 + 内存映射,杜绝 N+1) return new ArrayList<>();
* }
* @param list 原始教师列表
* @return 管理端教师视图列表 // 1. 批量收集非空 userId
*/ Set<Long> userIds = list.stream()
public List<TeacherAdminVO> toTeacherAdminList(List<TrainTeacher> list) .map(TrainTeacher::getUserId)
{ .filter(Objects::nonNull)
if (list == null || list.isEmpty()) .collect(Collectors.toSet());
{
return new ArrayList<>(); // 2. 单次批量查询系统用户并构建映射 Map
} Map<Long, SysUser> userMap;
if (!userIds.isEmpty())
// 1. 批量收集非空 userId {
Set<Long> userIds = list.stream() List<SysUser> users = userService.selectUserByUserIds(userIds);
.map(TrainTeacher::getUserId) userMap = users.stream().collect(Collectors.toMap(SysUser::getUserId, u -> u, (k1, k2) -> k1));
.filter(Objects::nonNull) }
.collect(Collectors.toSet()); else
{
// 2. 单次批量查询系统用户并构建映射 Map userMap = Collections.emptyMap();
Map<Long, SysUser> userMap; }
if (!userIds.isEmpty())
{ // 3. 内存 O(1) 组装
List<SysUser> users = userService.selectUserByUserIds(userIds); List<TeacherAdminVO> result = new ArrayList<>(list.size());
userMap = users.stream().collect(Collectors.toMap(SysUser::getUserId, u -> u, (k1, k2) -> k1)); for (TrainTeacher teacher : list)
} {
else TeacherAdminVO vo = new TeacherAdminVO();
{ BeanUtils.copyBeanProp(vo, teacher);
userMap = Collections.emptyMap(); if (teacher.getUserId() != null)
} {
vo.setAccountBindingStatus(1);
// 3. 内存 O(1) 组装 SysUser user = userMap.get(teacher.getUserId());
List<TeacherAdminVO> result = new ArrayList<>(list.size()); if (user != null)
for (TrainTeacher teacher : list) {
{ vo.setUserName(user.getUserName());
TeacherAdminVO vo = new TeacherAdminVO(); vo.setNickName(user.getNickName());
BeanUtils.copyBeanProp(vo, teacher); }
if (teacher.getUserId() != null) }
{ else
vo.setAccountBindingStatus(1); {
SysUser user = userMap.get(teacher.getUserId()); vo.setAccountBindingStatus(0);
if (user != null) }
{ result.add(vo);
vo.setUserName(user.getUserName()); }
vo.setNickName(user.getNickName()); return result;
} }
}
else /**
{ * 为单个教师对象装配账号绑定管理视图
vo.setAccountBindingStatus(0); *
} * @param teacher 原始教师对象
result.add(vo); * @return 管理端教师视图对象
} */
return result; public TeacherAdminVO toTeacherAdminVO(TrainTeacher teacher)
} {
if (teacher == null)
/** {
* 为单个教师对象装配账号绑定管理视图 return null;
* }
* @param teacher 原始教师对象 TeacherAdminVO vo = new TeacherAdminVO();
* @return 管理端教师视图对象 BeanUtils.copyBeanProp(vo, teacher);
*/ if (teacher.getUserId() != null)
public TeacherAdminVO toTeacherAdminVO(TrainTeacher teacher) {
{ vo.setAccountBindingStatus(1);
if (teacher == null) SysUser user = userService.selectUserById(teacher.getUserId());
{ if (user != null)
return null; {
} vo.setUserName(user.getUserName());
TeacherAdminVO vo = new TeacherAdminVO(); vo.setNickName(user.getNickName());
BeanUtils.copyBeanProp(vo, teacher); }
if (teacher.getUserId() != null) }
{ else
vo.setAccountBindingStatus(1); {
SysUser user = userService.selectUserById(teacher.getUserId()); vo.setAccountBindingStatus(0);
if (user != null) }
{ return vo;
vo.setUserName(user.getUserName()); }
vo.setNickName(user.getNickName());
} /**
} * 批量为学员列表装配账号绑定管理视图 (单次批量查询 + 内存映射,杜绝 N+1)
else *
{ * @param list 原始学员列表
vo.setAccountBindingStatus(0); * @return 管理端学员视图列表
} */
return vo; public List<StudentAdminVO> toStudentAdminList(List<StudentItemVO> list)
} {
if (list == null || list.isEmpty())
/** {
* 批量为学员列表装配账号绑定管理视图 (单次批量查询 + 内存映射,杜绝 N+1) return new ArrayList<>();
* }
* @param list 原始学员列表
* @return 管理端学员视图列表 // 1. 批量收集 sId
*/ Set<String> sIds = list.stream()
public List<StudentAdminVO> toStudentAdminList(List<StudentItemVO> list) .map(StudentItemVO::getsId)
{ .filter(Objects::nonNull)
if (list == null || list.isEmpty()) .collect(Collectors.toSet());
{
return new ArrayList<>(); // 2. 单次批量查询学员的关联 userId 映射
} Map<String, Long> studentUserMap;
if (!sIds.isEmpty())
// 1. 批量收集 sId {
Set<String> sIds = list.stream() List<TrainStudent> students = studentMapper.selectTrainStudentsBySIds(sIds);
.map(StudentItemVO::getsId) studentUserMap = students.stream()
.filter(Objects::nonNull) .filter(s -> s.getUserId() != null)
.collect(Collectors.toSet()); .collect(Collectors.toMap(TrainStudent::getsId, TrainStudent::getUserId, (k1, k2) -> k1));
}
// 2. 单次批量查询学员的关联 userId 映射 else
Map<String, Long> studentUserMap; {
if (!sIds.isEmpty()) studentUserMap = Collections.emptyMap();
{ }
List<TrainStudent> students = studentMapper.selectTrainStudentsBySIds(sIds);
studentUserMap = students.stream() // 3. 批量查询关联的系统用户
.filter(s -> s.getUserId() != null) Set<Long> userIds = new HashSet<>(studentUserMap.values());
.collect(Collectors.toMap(TrainStudent::getsId, TrainStudent::getUserId, (k1, k2) -> k1)); Map<Long, SysUser> userMap;
} if (!userIds.isEmpty())
else {
{ List<SysUser> users = userService.selectUserByUserIds(userIds);
studentUserMap = Collections.emptyMap(); userMap = users.stream().collect(Collectors.toMap(SysUser::getUserId, u -> u, (k1, k2) -> k1));
} }
else
// 3. 批量查询关联的系统用户 {
Set<Long> userIds = new HashSet<>(studentUserMap.values()); userMap = Collections.emptyMap();
Map<Long, SysUser> userMap; }
if (!userIds.isEmpty())
{ // 4. 内存 O(1) 组装
List<SysUser> users = userService.selectUserByUserIds(userIds); List<StudentAdminVO> result = new ArrayList<>(list.size());
userMap = users.stream().collect(Collectors.toMap(SysUser::getUserId, u -> u, (k1, k2) -> k1)); for (StudentItemVO item : list)
} {
else StudentAdminVO vo = new StudentAdminVO();
{ BeanUtils.copyBeanProp(vo, item);
userMap = Collections.emptyMap(); Long uid = studentUserMap.get(item.getsId());
} if (uid != null)
{
// 4. 内存 O(1) 组装 vo.setUserId(uid);
List<StudentAdminVO> result = new ArrayList<>(list.size()); vo.setAccountBindingStatus(1);
for (StudentItemVO item : list) SysUser user = userMap.get(uid);
{ if (user != null)
StudentAdminVO vo = new StudentAdminVO(); {
BeanUtils.copyBeanProp(vo, item); vo.setUserName(user.getUserName());
Long uid = studentUserMap.get(item.getsId()); vo.setNickName(user.getNickName());
if (uid != null) }
{ }
vo.setUserId(uid); else
vo.setAccountBindingStatus(1); {
SysUser user = userMap.get(uid); vo.setAccountBindingStatus(0);
if (user != null) }
{ result.add(vo);
vo.setUserName(user.getUserName()); }
vo.setNickName(user.getNickName()); return result;
} }
}
else /**
{ * 为单个学员详情装配账号绑定管理视图
vo.setAccountBindingStatus(0); *
} * @param detail 学员详情对象
result.add(vo); * @return 管理端学员视图对象
} */
return result; public StudentAdminVO toStudentAdminVO(StudentDetailVO detail)
} {
if (detail == null)
/** {
* 为单个学员详情装配账号绑定管理视图 return null;
* }
* @param detail 学员详情对象 StudentAdminVO vo = new StudentAdminVO();
* @return 管理端学员视图对象 BeanUtils.copyBeanProp(vo, detail);
*/ TrainStudent student = studentMapper.selectTrainStudentBySId(detail.getsId());
public StudentAdminVO toStudentAdminVO(StudentDetailVO detail) if (student != null && student.getUserId() != null)
{ {
if (detail == null) vo.setUserId(student.getUserId());
{ vo.setAccountBindingStatus(1);
return null; SysUser user = userService.selectUserById(student.getUserId());
} if (user != null)
StudentAdminVO vo = new StudentAdminVO(); {
BeanUtils.copyBeanProp(vo, detail); vo.setUserName(user.getUserName());
TrainStudent student = studentMapper.selectTrainStudentBySId(detail.getsId()); vo.setNickName(user.getNickName());
if (student != null && student.getUserId() != null) }
{ }
vo.setUserId(student.getUserId()); else
vo.setAccountBindingStatus(1); {
SysUser user = userService.selectUserById(student.getUserId()); vo.setAccountBindingStatus(0);
if (user != null) }
{ return vo;
vo.setUserName(user.getUserName()); }
vo.setNickName(user.getNickName());
} private void validateUserRole(Long userId, String requiredRoleKey, String roleLabel)
} {
else SysUser user = userService.selectUserById(userId);
{ if (user == null || "2".equals(user.getDelFlag()))
vo.setAccountBindingStatus(0); {
} throw new ServiceException("指定的系统用户不存在或已删除");
return vo; }
} if (!"0".equals(user.getStatus()))
{
private void validateUserRole(Long userId, String requiredRoleKey, String roleLabel) throw new ServiceException("指定的系统用户已被停用,禁止关联业务身份");
{ }
SysUser user = userService.selectUserById(userId); List<SysRole> roles = roleService.selectRolesByUserId(userId);
if (user == null || "2".equals(user.getDelFlag())) boolean hasRole = roles != null && roles.stream().anyMatch(r -> requiredRoleKey.equals(r.getRoleKey()));
{ if (!hasRole)
throw new ServiceException("指定的系统用户不存在或已删除"); {
} throw new ServiceException("所选系统账号(" + user.getUserName() + ")未分配" + roleLabel + "角色(" + requiredRoleKey + "),请先在用户管理中分配对应角色");
if (!"0".equals(user.getStatus())) }
{ }
throw new ServiceException("指定的系统用户已被停用,禁止关联业务身份"); }
}
List<SysRole> roles = roleService.selectRolesByUserId(userId);
boolean hasRole = roles != null && roles.stream().anyMatch(r -> requiredRoleKey.equals(r.getRoleKey()));
if (!hasRole)
{
throw new ServiceException("所选系统账号(" + user.getUserName() + ")未分配" + roleLabel + "角色(" + requiredRoleKey + "),请先在用户管理中分配对应角色");
}
}
}
@@ -1,82 +1,69 @@
# 数据源配置 # 数据源配置
spring: spring:
datasource: datasource:
type: com.alibaba.druid.pool.DruidDataSource type: com.alibaba.druid.pool.DruidDataSource
#driverClassName: com.mysql.cj.jdbc.Driver # KingbaseES 使用 com.kingbase8.Driver;切回 MySQL 使用 com.mysql.cj.jdbc.Driver
driverClassName: com.kingbase8.Driver driverClassName: com.kingbase8.Driver
druid: druid:
# 主库数据源 # 主库数据源
master: master:
#url: jdbc:mysql://192.168.43.110:3306/gy_gb?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8 url: ${SPRING_DATASOURCE_DRUID_MASTER_URL:jdbc:kingbase8://${DB_HOST:127.0.0.1}:${DB_PORT:54321}/${DB_NAME:railwaysystem_fusion}?useUnicode=true&characterEncoding=utf8}
# username: root username: ${SPRING_DATASOURCE_DRUID_MASTER_USERNAME:${QA_DB_USER:fusion_app}}
# password: rootdev password: ${SPRING_DATASOURCE_DRUID_MASTER_PASSWORD:${FUSION_QA_APP_PASSWORD:}}
# 192.168.125.228 # 多模式透明路由与系统视图隔离
#url: jdbc:mysql://192.168.125.228:3306/judge?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8 connectionInitSqls:
#url: jdbc:mysql://127.0.0.1:3306/s_builder?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8 - set search_path to iotlocks, public, pg_catalog, sys_catalog
#url: jdbc:mysql://120.53.244.187:3306/sict_builder?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8 # 从库数据源
#url: jdbc:mysql://83.102.67.232:3306/judge?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8 slave:
#url: jdbc:mysql://127.0.0.1:3306/s_builder_kj?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8 # 从数据源开关/默认关闭
# Environment driven production-safe database config (defaults to shared trial training database): enabled: false
url: ${SPRING_DATASOURCE_DRUID_MASTER_URL:jdbc:kingbase8://192.168.139.218:4321/training?currentSchema=public,sys_catalog&useUnicode=true&characterEncoding=utf8} url:
username: ${SPRING_DATASOURCE_DRUID_MASTER_USERNAME:kingbase} username:
password: ${SPRING_DATASOURCE_DRUID_MASTER_PASSWORD:sict123456} password:
connectionInitSqls: ["SET search_path TO public, sys_catalog"] connectionInitSqls:
- set search_path to public, pg_catalog, sys_catalog
# prod env kingbase: # 初始连接数
#url: jdbc:kingbase8://localhost:54321/graph?currentSchema=public&useUnicode=true&characterEncoding=utf8 initialSize: 5
#username: graph # 最小连接池数量
#password: psw.db7898 minIdle: 10
# 最大连接池数量
#password: Psw.s10@7898 maxActive: 20
#driver-class-name: com.kingbase8.Driver # 配置获取连接等待超时的时间
#password: Ldtc@123123! maxWait: 60000
# 从库数据源 # 配置连接超时时间
# slave: connectTimeout: 30000
# # 从数据源开关/默认关闭 # 配置网络超时时间
# enabled: false socketTimeout: 60000
# url: bolt://192.168.125.228:7687/ # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
# username: neo4j timeBetweenEvictionRunsMillis: 60000
# password: Sipsys12345, # 配置一个连接在池中最小生存的时间,单位是毫秒
# 初始连接数 minEvictableIdleTimeMillis: 300000
initialSize: 5 # 配置一个连接在池中最大生存的时间,单位是毫秒
# 最小连接池数量 maxEvictableIdleTimeMillis: 900000
minIdle: 10 # 配置检测连接是否有效(SELECT 1 为 MySQL 与 KingbaseES 通用写法)
# 最大连接池数量 validationQuery: SELECT 1
maxActive: 20 testWhileIdle: true
# 配置获取连接等待超时的时间 testOnBorrow: false
maxWait: 60000 testOnReturn: false
# 配置连接超时时间 webStatFilter:
connectTimeout: 30000 enabled: true
# 配置网络超时时间 statViewServlet:
socketTimeout: 60000 enabled: true
# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 # 设置白名单,不填则允许所有访问
timeBetweenEvictionRunsMillis: 60000 allow:
# 配置一个连接在池中最小生存的时间,单位是毫秒 url-pattern: /druid/*
minEvictableIdleTimeMillis: 300000 # 控制台管理用户名和密码
# 配置一个连接在池中最大生存的时间,单位是毫秒 login-username: ruoyi
maxEvictableIdleTimeMillis: 900000 login-password: 123456
# 配置检测连接是否有效 filter:
validationQuery: SELECT 1 FROM DUAL stat:
testWhileIdle: true enabled: true
testOnBorrow: true # 慢SQL记录
testOnReturn: false log-slow-sql: true
webStatFilter: slow-sql-millis: 1000
enabled: true merge-sql: true
statViewServlet: wall:
enabled: true # 若 Druid 无法自动识别 KingbaseES,取消下一行注释显式指定数据库类型
# 设置白名单,不填则允许所有访问 # db-type: kingbase
allow: config:
url-pattern: /druid/*
# 控制台管理用户名和密码
login-username: ruoyi
login-password: 123456
filter:
stat:
enabled: true
# 慢SQL记录
log-slow-sql: true
slow-sql-millis: 1000
merge-sql: true
wall:
config:
multi-statement-allow: true multi-statement-allow: true
@@ -1,148 +1,221 @@
# 项目相关配置 # 项目相关配置
ruoyi: ruoyi:
# 名称 # 名称
name: RuoYi name: RuoYi
# 版本 # 版本
version: 3.9.1 version: 3.9.2
# 版权年份 # 版权年份
copyrightYear: 2026 copyrightYear: 2026
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath) # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
profile: ./uploadPath profile: ./uploadPath
# 获取ip地址开关 # 获取ip地址开关
addressEnabled: false addressEnabled: false
# 验证码类型 math 数字计算 char 字符验证 # 验证码类型 math 数字计算 char 字符验证
captchaType: math captchaType: math
# 开发环境配置 # 开发环境配置
server: server:
# 服务器的HTTP端口,默认为8080 # 服务器的HTTP端口,默认为8080
port: 8090 port: 8096
servlet: servlet:
# 应用的访问路径 # 应用的访问路径
context-path: / context-path: /
tomcat: tomcat:
# tomcat的URI编码 # tomcat的URI编码
uri-encoding: UTF-8 uri-encoding: UTF-8
# 连接数满后的排队数,默认为100 # 连接数满后的排队数,默认为100
accept-count: 1000 accept-count: 1000
threads: threads:
# tomcat最大线程数,默认为200 # tomcat最大线程数,默认为200
max: 800 max: 800
# Tomcat启动初始化的线程数,默认值10 # Tomcat启动初始化的线程数,默认值10
min-spare: 100 min-spare: 100
# 日志配置 # 日志配置
logging: logging:
level: level:
com.ruoyi: debug com.ruoyi: debug
org.springframework: warn org.springframework: warn
# 用户配置 # 用户配置
user: user:
password: password:
# 密码最大错误次数 # 密码最大错误次数
maxRetryCount: 5 maxRetryCount: 5
# 密码锁定时间(默认10分钟) # 密码锁定时间(默认10分钟)
lockTime: 10 lockTime: 10
# Spring配置 # Spring配置
spring: spring:
# 资源信息 # 资源信息
messages: messages:
# 国际化资源文件路径 # 国际化资源文件路径
basename: i18n/messages basename: i18n/messages
profiles: profiles:
active: druid active: druid
# 文件上传 # 文件上传
servlet: servlet:
multipart: multipart:
# 单个文件大小 # 单个文件大小
max-file-size: 10MB max-file-size: 10MB
# 设置总上传的文件大小 # 设置总上传的文件大小
max-request-size: 20MB max-request-size: 20MB
# 服务模块 jackson:
devtools: time-zone: GMT+8
restart: date-format: yyyy-MM-dd HH:mm:ss
# 热部署开关 # 服务模块
enabled: true devtools:
# redis 配置 restart:
redis: # 热部署开关
# 地址 enabled: true
host: localhost data:
# 端口,默认为6379 # redis 配置
port: 6379 redis:
# 数据库索引 # 地址
database: 0 host: localhost
# 密码 # 端口,默认为6379
password: port: 6379
# 连接超时时间 # 数据库索引 (独立 QA 测试隔离使用 14 库)
timeout: 10s database: 14
lettuce: # 密码
pool: password:
# 连接池中的最小空闲连接 # 连接超时时间
min-idle: 0 timeout: 10s
# 连接池中的最大空闲连接 lettuce:
max-idle: 8 pool:
# 连接池的最大数据库连接数 # 连接池中的最小空闲连接
max-active: 8 min-idle: 0
# #连接池最大阻塞等待时间(使用负值表示没有限制) # 连接池中的最大空闲连接
max-wait: -1ms max-idle: 8
# 连接池的最大数据库连接数
# 学员身份证安全配置只接受外部注入;仓库内不得保存实际密钥。 max-active: 8
train: # #连接池最大阻塞等待时间(使用负值表示没有限制)
student: max-wait: -1ms
identity:
encryption-key: ${TRAIN_STUDENT_IDENTITY_ENCRYPTION_KEY:} # 培训与门禁业务配置
hash-key: ${TRAIN_STUDENT_IDENTITY_HASH_KEY:} train:
mock: # QA 环境业务桥接引擎配置:显式使用自主 iot 门锁授权桥接
device: lock:
# 模拟设备打卡接口开关 (生产环境与公共配置必须默认关闭,仅允许在测试环境显式开启) auth-engine: ${TRAIN_LOCK_AUTH_ENGINE:iot}
enabled: ${TRAIN_MOCK_DEVICE_ENABLED:false} student:
identity:
# token配置 encryption-key: ${TRAIN_STUDENT_IDENTITY_ENCRYPTION_KEY:}
token: hash-key: ${TRAIN_STUDENT_IDENTITY_HASH_KEY:}
# 令牌自定义标识
header: Authorization # token配置
# 令牌密钥 token:
secret: abcdefghijklmnopqrstuvwxyz # 令牌自定义标识
# 令牌有效期(默认30分钟) header: Authorization
expireTime: 30 # 令牌密钥
secret: abcdefghijklmnopqrstuvwxyz
# MyBatis配置 # 令牌有效期(默认30分钟)
mybatis: expireTime: 30
# 搜索指定包别名
typeAliasesPackage: com.ruoyi.**.domain # MyBatis配置
# 配置mapper的扫描,找到所有的mapper.xml映射文件 mybatis:
mapperLocations: classpath*:mapper/**/*Mapper.xml # 搜索指定包别名
# 加载全局的配置文件 typeAliasesPackage: com.ruoyi.**.domain
configLocation: classpath:mybatis/mybatis-config.xml # 配置mapper的扫描,找到所有的mapper.xml映射文件
mapperLocations: classpath*:mapper/**/*Mapper.xml
# PageHelper分页插件 # 加载全局的配置文件
pagehelper: configLocation: classpath:mybatis/mybatis-config.xml
helperDialect: mysql
supportMethodsArguments: true # PageHelper分页插件
params: count=countSql pagehelper:
# 方言由 PageHelper 根据数据源自动识别(已内置 MySQL 与 KingbaseES)
# Swagger配置 # 如需强制指定,MySQL 填写 mysql,KingbaseES 填写 kingbase
swagger: supportMethodsArguments: true
# 是否开启swagger params: count=countSql
enabled: true
# 请求前缀 # Springdoc配置
pathMapping: /dev-api springdoc:
api-docs:
# 防盗链配置 path: /v3/api-docs
referer: swagger-ui:
# 防盗链开关 enabled: true
enabled: false path: /swagger-ui.html
# 允许的域名列表 tags-sorter: alpha
allowed-domains: localhost,127.0.0.1,ruoyi.vip,www.ruoyi.vip group-configs:
- group: 'default'
# 防止XSS攻击 display-name: '测试模块'
xss: paths-to-match: '/**'
# 过滤开关 packages-to-scan: com.ruoyi.web.controller.tool
enabled: true
# 排除链接(多个用逗号分隔) # 防盗链配置
excludes: /system/notice referer:
# 匹配链接 # 防盗链开关
urlPatterns: /system/*,/monitor/*,/tool/* enabled: false
# 允许的域名列表
allowed-domains: localhost,127.0.0.1,ruoyi.vip,www.ruoyi.vip
# 防止XSS攻击
xss:
# 过滤开关
enabled: true
# 排除链接(多个用逗号分隔)
excludes: /system/notice
# 匹配链接
urlPatterns: /system/*,/monitor/*,/tool/*
# IOT设备接入(Mock 模式,拦截外部真实硬件)
iot:
# 人脸特征提取服务 (Mock 拦截,绝不向外部真实接口发请求)
face:
endpoint: mock://face-feature-extract
mock: true
timeout: 3000
# 第三方开放接口:关闭时接口返回 404;启用后调用方需带请求头 X-API-Key
openapi:
enabled: true
api-key: qa-fusion-test-api-key
path-prefix: /openapi/iot
mqtt:
# 彻底禁用真实 MQTT 连接,启用 Mock 替身模式
enabled: false
mock: true
# 真实硬件下行控制写入总开关(硬性安全门禁,默认为 false,严禁向真实硬件发控制指令)
real-device-write-enabled: false
# 真实设备 SN 白名单(归档配置默认值为空列表,联调时由环境配置或控制台注入)
device-whitelist: []
# 历史指令防重放保护(禁止向真实硬件重放系统启动前遗留的历史待发送指令)
replay-protection-enabled: true
# 定时补偿任务开关
retry-task-enabled: true
broker-url: ${IOT_MQTT_BROKER_URL:tcp://127.0.0.1:1883}
# 客户端ID,同一服务器下必须唯一;为空时自动生成
client-id:
username: ${IOT_MQTT_USERNAME:admin}
password: ${IOT_MQTT_PASSWORD:}
# false 时服务端保留离线消息,需配合固定 client-id
clean-session: true
connection-timeout: 30
keep-alive-interval: 60
# 断线自动重连
automatic-reconnect: true
max-reconnect-delay: 30000
# 连接健康检查周期(毫秒),0 表示不做定时重连
health-check-interval: 30000
# 发布消息等待服务端确认时间(毫秒),0 表示不等待
publish-timeout: 3000
# 消息持久化目录,为空使用内存
persistence-directory:
default-qos: 1
default-retained: false
# 只订阅上行主题(下行由平台发布,不消费自己发出的指令)
topics:
- topic: ydlink/+/thing/onoff_line # 网关上下线
qos: 1
- topic: ydlink/+/thing/property/set_response # 属性设置响应
qos: 1
- topic: ydlink/+/thing/action/execute_response # 远程开关锁响应
qos: 1
- topic: ydlink/+/thing/data/batch_report # 授权下发结果
qos: 1
- topic: ydlink/+/thing/event/trigger # 开门记录上报
qos: 1
# 遗嘱消息:无法区分主动断开与异常掉线,门禁场景建议关闭(离线由 GatewayOfflineCheckTask 判定)
# will:
# topic: ydlink/status
# payload: offline
# qos: 1
# retained: true
@@ -1,24 +1,24 @@
Application Version: ${ruoyi.version} Application Version: ${ruoyi.version}
Spring Boot Version: ${spring-boot.version} Spring Boot Version: ${spring-boot.version}
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
// _ooOoo_ // // _ooOoo_ //
// o8888888o // // o8888888o //
// 88" . "88 // // 88" . "88 //
// (| ^_^ |) // // (| ^_^ |) //
// O\ = /O // // O\ = /O //
// ____/`---'\____ // // ____/`---'\____ //
// .' \\| |// `. // // .' \\| |// `. //
// / \\||| : |||// \ // // / \\||| : |||// \ //
// / _||||| -:- |||||- \ // // / _||||| -:- |||||- \ //
// | | \\\ - /// | | // // | | \\\ - /// | | //
// | \_| ''\---/'' | | // // | \_| ''\---/'' | | //
// \ .-\__ `-` ___/-. / // // \ .-\__ `-` ___/-. / //
// ___`. .' /--.--\ `. . ___ // // ___`. .' /--.--\ `. . ___ //
// ."" '< `.___\_<|>_/___.' >'"". // // ."" '< `.___\_<|>_/___.' >'"". //
// | | : `- \`.;`\ _ /`;.`/ - ` : | | // // | | : `- \`.;`\ _ /`;.`/ - ` : | | //
// \ \ `-. \_ __\ /__ _/ .-` / / // // \ \ `-. \_ __\ /__ _/ .-` / / //
// ========`-.____`-.___\_____/___.-`____.-'======== // // ========`-.____`-.___\_____/___.-`____.-'======== //
// `=---=' // // `=---=' //
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ // // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ //
// 佛祖保佑 永不宕机 永无BUG // // 佛祖保佑 永不宕机 永无BUG //
//////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////
@@ -1,38 +1,38 @@
#错误消息 #错误消息
not.null=* 必须填写 not.null=* 必须填写
user.jcaptcha.error=验证码错误 user.jcaptcha.error=验证码错误
user.jcaptcha.expire=验证码已失效 user.jcaptcha.expire=验证码已失效
user.not.exists=用户不存在/密码错误 user.not.exists=用户不存在/密码错误
user.password.not.match=用户不存在/密码错误 user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=密码输入错误{0}次 user.password.retry.limit.count=密码输入错误{0}次
user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟 user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
user.password.delete=对不起,您的账号已被删除 user.password.delete=对不起,您的账号已被删除
user.blocked=用户已封禁,请联系管理员 user.blocked=用户已封禁,请联系管理员
role.blocked=角色已封禁,请联系管理员 role.blocked=角色已封禁,请联系管理员
login.blocked=很遗憾,访问IP已被列入系统黑名单 login.blocked=很遗憾,访问IP已被列入系统黑名单
user.logout.success=退出成功 user.logout.success=退出成功
length.not.valid=长度必须在{min}到{max}个字符之间 length.not.valid=长度必须在{min}到{max}个字符之间
user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头 user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成,且必须以非数字开头
user.password.not.valid=* 5-50个字符 user.password.not.valid=* 5-50个字符
user.email.not.valid=邮箱格式错误 user.email.not.valid=邮箱格式错误
user.mobile.phone.number.not.valid=手机号格式错误 user.mobile.phone.number.not.valid=手机号格式错误
user.login.success=登录成功 user.login.success=登录成功
user.register.success=注册成功 user.register.success=注册成功
user.notfound=请重新登录 user.notfound=请重新登录
user.forcelogout=管理员强制退出,请重新登录 user.forcelogout=管理员强制退出,请重新登录
user.unknown.error=未知错误,请重新登录 user.unknown.error=未知错误,请重新登录
##文件上传消息 ##文件上传消息
upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB! upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB!
upload.filename.exceed.length=上传的文件名最长{0}个字符 upload.filename.exceed.length=上传的文件名最长{0}个字符
##权限 ##权限
no.permission=您没有数据的权限,请联系管理员添加权限 [{0}] no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}] no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}] no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}] no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}] no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}] no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
@@ -1,93 +1,93 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<configuration> <configuration>
<!-- 日志存放路径 --> <!-- 日志存放路径 -->
<property name="log.path" value="./logs" /> <property name="log.path" value="C:/Users/zfjia/work/projects/ruoyi/logs" />
<!-- 日志输出格式 --> <!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" /> <property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
<!-- 控制台输出 --> <!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender"> <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder> <encoder>
<pattern>${log.pattern}</pattern> <pattern>${log.pattern}</pattern>
</encoder> </encoder>
</appender> </appender>
<!-- 系统日志输出 --> <!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file> <file>${log.path}/sys-info.log</file>
<!-- 循环政策:基于时间创建日志文件 --> <!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 --> <!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern> <fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 --> <!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory> <maxHistory>60</maxHistory>
</rollingPolicy> </rollingPolicy>
<encoder> <encoder>
<pattern>${log.pattern}</pattern> <pattern>${log.pattern}</pattern>
</encoder> </encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"> <filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 --> <!-- 过滤的级别 -->
<level>INFO</level> <level>INFO</level>
<!-- 匹配时的操作:接收(记录) --> <!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch> <onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) --> <!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch> <onMismatch>DENY</onMismatch>
</filter> </filter>
</appender> </appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file> <file>${log.path}/sys-error.log</file>
<!-- 循环政策:基于时间创建日志文件 --> <!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 --> <!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern> <fileNamePattern>${log.path}/sys-error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 --> <!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory> <maxHistory>60</maxHistory>
</rollingPolicy> </rollingPolicy>
<encoder> <encoder>
<pattern>${log.pattern}</pattern> <pattern>${log.pattern}</pattern>
</encoder> </encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"> <filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 --> <!-- 过滤的级别 -->
<level>ERROR</level> <level>ERROR</level>
<!-- 匹配时的操作:接收(记录) --> <!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch> <onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) --> <!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch> <onMismatch>DENY</onMismatch>
</filter> </filter>
</appender> </appender>
<!-- 用户访问日志输出 --> <!-- 用户访问日志输出 -->
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender"> <appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-user.log</file> <file>${log.path}/sys-user.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滚 daily --> <!-- 按天回滚 daily -->
<fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern> <fileNamePattern>${log.path}/sys-user.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 --> <!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory> <maxHistory>60</maxHistory>
</rollingPolicy> </rollingPolicy>
<encoder> <encoder>
<pattern>${log.pattern}</pattern> <pattern>${log.pattern}</pattern>
</encoder> </encoder>
</appender> </appender>
<!-- 系统模块日志级别控制 --> <!-- 系统模块日志级别控制 -->
<logger name="com.ruoyi" level="info" /> <logger name="com.ruoyi" level="info" />
<!-- Spring日志级别控制 --> <!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn" /> <logger name="org.springframework" level="warn" />
<root level="info"> <root level="info">
<appender-ref ref="console" /> <appender-ref ref="console" />
</root> </root>
<!--系统操作日志--> <!--系统操作日志-->
<root level="info"> <root level="info">
<appender-ref ref="file_info" /> <appender-ref ref="file_info" />
<appender-ref ref="file_error" /> <appender-ref ref="file_error" />
</root> </root>
<!--系统用户操作日志--> <!--系统用户操作日志-->
<logger name="sys-user" level="info"> <logger name="sys-user" level="info">
<appender-ref ref="sys-user"/> <appender-ref ref="sys-user"/>
</logger> </logger>
</configuration> </configuration>
@@ -1,20 +1,20 @@
<?xml version="1.0" encoding="UTF-8" ?> <?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration <!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd"> "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration> <configuration>
<!-- 全局参数 --> <!-- 全局参数 -->
<settings> <settings>
<!-- 使全局的映射器启用或禁用缓存 --> <!-- 使全局的映射器启用或禁用缓存 -->
<setting name="cacheEnabled" value="true" /> <setting name="cacheEnabled" value="true" />
<!-- 允许JDBC 支持自动生成主键 --> <!-- 允许JDBC 支持自动生成主键 -->
<setting name="useGeneratedKeys" value="true" /> <setting name="useGeneratedKeys" value="true" />
<!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 --> <!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
<setting name="defaultExecutorType" value="SIMPLE" /> <setting name="defaultExecutorType" value="SIMPLE" />
<!-- 指定 MyBatis 所用日志的具体实现 --> <!-- 指定 MyBatis 所用日志的具体实现 -->
<setting name="logImpl" value="SLF4J" /> <setting name="logImpl" value="SLF4J" />
<!-- 使用驼峰命名法转换字段 --> <!-- 使用驼峰命名法转换字段 -->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/> --> <!-- <setting name="mapUnderscoreToCamelCase" value="true"/> -->
</settings> </settings>
</configuration> </configuration>
@@ -262,9 +262,9 @@ public class RbacHttpAndAuthorizationSemanticsTest
{ {
// 模拟 Spring Security 权限不足异常 // 模拟 Spring Security 权限不足异常
AccessDeniedException ex = new AccessDeniedException("Access is denied"); AccessDeniedException ex = new AccessDeniedException("Access is denied");
javax.servlet.http.HttpServletRequest request = (javax.servlet.http.HttpServletRequest) Proxy.newProxyInstance( jakarta.servlet.http.HttpServletRequest request = (jakarta.servlet.http.HttpServletRequest) Proxy.newProxyInstance(
getClass().getClassLoader(), getClass().getClassLoader(),
new Class<?>[]{javax.servlet.http.HttpServletRequest.class}, new Class<?>[]{jakarta.servlet.http.HttpServletRequest.class},
(proxy, method, args) -> { (proxy, method, args) -> {
if ("getRequestURI".equals(method.getName())) return "/train/me/teacher"; if ("getRequestURI".equals(method.getName())) return "/train/me/teacher";
return null; return null;
+134 -117
View File
@@ -1,118 +1,135 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" <project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.9.1</version> <version>3.9.2</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <build>
<plugins>
<artifactId>ruoyi-common</artifactId> <plugin>
<groupId>org.apache.maven.plugins</groupId>
<description> <artifactId>maven-compiler-plugin</artifactId>
common通用工具 <configuration>
</description> <source>9</source>
<target>9</target>
<dependencies> </configuration>
</plugin>
<!-- Spring框架基本的核心工具 --> </plugins>
<dependency> </build>
<groupId>org.springframework</groupId> <modelVersion>4.0.0</modelVersion>
<artifactId>spring-context-support</artifactId>
</dependency> <artifactId>ruoyi-common</artifactId>
<!-- SpringWeb模块 --> <description>
<dependency> common通用工具
<groupId>org.springframework</groupId> </description>
<artifactId>spring-web</artifactId>
</dependency> <dependencies>
<!-- spring security 安全认证 --> <!-- Spring框架基本的核心工具 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework</groupId>
<artifactId>spring-boot-starter-security</artifactId> <artifactId>spring-context-support</artifactId>
</dependency> </dependency>
<!-- pagehelper 分页插件 --> <!-- SpringWeb模块 -->
<dependency> <dependency>
<groupId>com.github.pagehelper</groupId> <groupId>org.springframework</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId> <artifactId>spring-web</artifactId>
</dependency> </dependency>
<!-- 自定义验证注解 --> <!-- spring security 安全认证 -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId> <artifactId>spring-boot-starter-security</artifactId>
</dependency> </dependency>
<!--常用工具类 --> <!-- pagehelper 分页插件 -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>com.github.pagehelper</groupId>
<artifactId>commons-lang3</artifactId> <artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency> </dependency>
<!-- JSON工具类 --> <!-- 自定义验证注解 -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>jackson-databind</artifactId> <artifactId>spring-boot-starter-validation</artifactId>
</dependency> </dependency>
<!-- 阿里JSON解析器 --> <!--常用工具类 -->
<dependency> <dependency>
<groupId>com.alibaba.fastjson2</groupId> <groupId>org.apache.commons</groupId>
<artifactId>fastjson2</artifactId> <artifactId>commons-lang3</artifactId>
</dependency> </dependency>
<!-- io常用工具类 --> <!-- JSON工具类 -->
<dependency> <dependency>
<groupId>commons-io</groupId> <groupId>tools.jackson.core</groupId>
<artifactId>commons-io</artifactId> <artifactId>jackson-databind</artifactId>
</dependency> </dependency>
<!-- excel工具 --> <!-- 阿里JSON解析器 -->
<dependency> <dependency>
<groupId>org.apache.poi</groupId> <groupId>com.alibaba.fastjson2</groupId>
<artifactId>poi-ooxml</artifactId> <artifactId>fastjson2</artifactId>
</dependency> </dependency>
<!-- Token生成与解析--> <!-- io常用工具类 -->
<dependency> <dependency>
<groupId>io.jsonwebtoken</groupId> <groupId>commons-io</groupId>
<artifactId>jjwt</artifactId> <artifactId>commons-io</artifactId>
</dependency> </dependency>
<!-- Jaxb --> <!-- excel工具 -->
<dependency> <dependency>
<groupId>javax.xml.bind</groupId> <groupId>org.apache.poi</groupId>
<artifactId>jaxb-api</artifactId> <artifactId>poi-ooxml</artifactId>
</dependency> </dependency>
<!-- redis 缓存操作 --> <!-- Token生成与解析-->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>io.jsonwebtoken</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId> <artifactId>jjwt</artifactId>
</dependency> </dependency>
<!-- pool 对象池 --> <!-- Jaxb -->
<dependency> <dependency>
<groupId>org.apache.commons</groupId> <groupId>javax.xml.bind</groupId>
<artifactId>commons-pool2</artifactId> <artifactId>jaxb-api</artifactId>
</dependency> </dependency>
<!-- 解析客户端操作系统、浏览器等 --> <!-- redis 缓存操作 -->
<dependency> <dependency>
<groupId>nl.basjes.parse.useragent</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>yauaa</artifactId> <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency> </dependency>
<!-- servlet包 --> <dependency>
<dependency> <groupId>org.springframework.boot</groupId>
<groupId>javax.servlet</groupId> <artifactId>spring-boot-starter-cache</artifactId>
<artifactId>javax.servlet-api</artifactId> </dependency>
</dependency>
<!-- pool 对象池 -->
</dependencies> <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- 解析客户端操作系统、浏览器等 -->
<dependency>
<groupId>nl.basjes.parse.useragent</groupId>
<artifactId>yauaa</artifactId>
</dependency>
<!-- servlet包 -->
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
</dependency>
</dependencies>
</project> </project>
@@ -1,19 +1,19 @@
package com.ruoyi.common.annotation; package com.ruoyi.common.annotation;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* 匿名访问不鉴权注解 * 匿名访问不鉴权注解
* *
* @author ruoyi * @author ruoyi
*/ */
@Target({ ElementType.METHOD, ElementType.TYPE }) @Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface Anonymous public @interface Anonymous
{ {
} }
@@ -1,33 +1,43 @@
package com.ruoyi.common.annotation; package com.ruoyi.common.annotation;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* 数据权限过滤注解 * 数据权限过滤注解
* *
* @author ruoyi * @author ruoyi
*/ */
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface DataScope public @interface DataScope
{ {
/** /**
* 部门表的别名 * 用户表的别名
*/ */
public String deptAlias() default ""; public String userAlias() default "";
/** /**
* 用户表的别名 * 部门表的别名
*/ */
public String userAlias() default ""; public String deptAlias() default "";
/** /**
* 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来 * 用户字段名
*/ */
public String permission() default ""; public String userField() default "user_id";
}
/**
* 部门字段名
*/
public String deptField() default "dept_id";
/**
* 权限字符(用于多个角色匹配符合要求的权限)默认根据权限注解@ss获取,多个权限用逗号分隔开来
*/
public String permission() default "";
}
@@ -1,28 +1,28 @@
package com.ruoyi.common.annotation; package com.ruoyi.common.annotation;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited; import java.lang.annotation.Inherited;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import com.ruoyi.common.enums.DataSourceType; import com.ruoyi.common.enums.DataSourceType;
/** /**
* 自定义多数据源切换注解 * 自定义多数据源切换注解
* *
* 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准 * 优先级:先方法,后类,如果方法覆盖了类上的数据源类型,以方法的为准,否则以类上的为准
* *
* @author ruoyi * @author ruoyi
*/ */
@Target({ ElementType.METHOD, ElementType.TYPE }) @Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
@Inherited @Inherited
public @interface DataSource public @interface DataSource
{ {
/** /**
* 切换数据源名称 * 切换数据源名称
*/ */
public DataSourceType value() default DataSourceType.MASTER; public DataSourceType value() default DataSourceType.MASTER;
} }
@@ -1,197 +1,198 @@
package com.ruoyi.common.annotation; package com.ruoyi.common.annotation;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import java.math.BigDecimal; import java.math.BigDecimal;
import org.apache.poi.ss.usermodel.HorizontalAlignment; import org.apache.poi.ss.usermodel.HorizontalAlignment;
import org.apache.poi.ss.usermodel.IndexedColors; import org.apache.poi.ss.usermodel.IndexedColors;
import com.ruoyi.common.utils.poi.ExcelHandlerAdapter; import com.ruoyi.common.utils.poi.ExcelHandlerAdapter;
/** /**
* 自定义导出Excel数据注解 * 自定义导出Excel数据注解
* *
* @author ruoyi * @author ruoyi
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
public @interface Excel public @interface Excel
{ {
/** /**
* 导出时在excel中排序 * 导出时在excel中排序
*/ */
public int sort() default Integer.MAX_VALUE; public int sort() default Integer.MAX_VALUE;
/** /**
* 导出到Excel中的名字. * 导出到Excel中的名字.
*/ */
public String name() default ""; public String name() default "";
/** /**
* 日期格式, 如: yyyy-MM-dd * 日期格式, 如: yyyy-MM-dd
*/ */
public String dateFormat() default ""; public String dateFormat() default "";
/** /**
* 如果是字典类型,请设置字典的type值 (如: sys_user_sex) * 如果是字典类型,请设置字典的type值 (如: sys_user_sex)
*/ */
public String dictType() default ""; public String dictType() default "";
/** /**
* 读取内容转表达式 (如: 0=男,1=女,2=未知) * 读取内容转表达式 (如: 0=男,1=女,2=未知)
*/ */
public String readConverterExp() default ""; public String readConverterExp() default "";
/** /**
* 分隔符,读取字符串组内容 * 分隔符,读取字符串组内容
*/ */
public String separator() default ","; public String separator() default ",";
/** /**
* BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化) * BigDecimal 精度 默认:-1(默认不开启BigDecimal格式化)
*/ */
public int scale() default -1; public int scale() default -1;
/** /**
* BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
*/ */
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; @SuppressWarnings("deprecation")
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
/**
* 导出时在excel中每个列的高度 /**
*/ * 导出时在excel中每个列的高度
public double height() default 14; */
public double height() default 14;
/**
* 导出时在excel中每个列的宽度 /**
*/ * 导出时在excel中每个列的宽度
public double width() default 16; */
public double width() default 16;
/**
* 文字后缀,如% 90 变成90% /**
*/ * 文字后缀,如% 90 变成90%
public String suffix() default ""; */
public String suffix() default "";
/**
* 当值为空时,字段的默认值 /**
*/ * 当值为空时,字段的默认值
public String defaultValue() default ""; */
public String defaultValue() default "";
/**
* 提示信息 /**
*/ * 提示信息
public String prompt() default ""; */
public String prompt() default "";
/**
* 是否允许内容换行 /**
*/ * 是否允许内容换行
public boolean wrapText() default false; */
public boolean wrapText() default false;
/**
* 设置只能选择不能输入的列内容. /**
*/ * 设置只能选择不能输入的列内容.
public String[] combo() default {}; */
public String[] combo() default {};
/**
* 是否从字典读数据到combo,默认不读取,如读取需要设置dictType注解. /**
*/ * 是否从字典读数据到combo,默认不读取,如读取需要设置dictType注解.
public boolean comboReadDict() default false; */
public boolean comboReadDict() default false;
/**
* 是否需要纵向合并单元格,应对需求:含有list集合单元格) /**
*/ * 是否需要纵向合并单元格,应对需求:含有list集合单元格)
public boolean needMerge() default false; */
public boolean needMerge() default false;
/**
* 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写. /**
*/ * 是否导出数据,应对需求:有时我们需要导出一份模板,这是标题需要但内容需要用户手工填写.
public boolean isExport() default true; */
public boolean isExport() default true;
/**
* 另一个类中的属性名称,支持多级获取,以小数点隔开 /**
*/ * 另一个类中的属性名称,支持多级获取,以小数点隔开
public String targetAttr() default ""; */
public String targetAttr() default "";
/**
* 是否自动统计数据,在最后追加一行统计数据总和 /**
*/ * 是否自动统计数据,在最后追加一行统计数据总和
public boolean isStatistics() default false; */
public boolean isStatistics() default false;
/**
* 导出类型(0数字 1字符串 2图片) /**
*/ * 导出类型(0数字 1字符串 2图片)
public ColumnType cellType() default ColumnType.STRING; */
public ColumnType cellType() default ColumnType.STRING;
/**
* 导出列头背景颜色 /**
*/ * 导出列头背景颜色
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT; */
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
/**
* 导出列头字体颜色 /**
*/ * 导出列头字体颜色
public IndexedColors headerColor() default IndexedColors.WHITE; */
public IndexedColors headerColor() default IndexedColors.WHITE;
/**
* 导出单元格背景颜色 /**
*/ * 导出单元格背景颜色
public IndexedColors backgroundColor() default IndexedColors.WHITE; */
public IndexedColors backgroundColor() default IndexedColors.WHITE;
/**
* 导出单元格字体颜色 /**
*/ * 导出单元格字体颜色
public IndexedColors color() default IndexedColors.BLACK; */
public IndexedColors color() default IndexedColors.BLACK;
/**
* 导出字段对齐方式 /**
*/ * 导出字段对齐方式
public HorizontalAlignment align() default HorizontalAlignment.CENTER; */
public HorizontalAlignment align() default HorizontalAlignment.CENTER;
/**
* 自定义数据处理器 /**
*/ * 自定义数据处理器
public Class<?> handler() default ExcelHandlerAdapter.class; */
public Class<?> handler() default ExcelHandlerAdapter.class;
/**
* 自定义数据处理器参数 /**
*/ * 自定义数据处理器参数
public String[] args() default {}; */
public String[] args() default {};
/**
* 字段类型(0:导出导入;1:仅导出;2:仅导入) /**
*/ * 字段类型(0:导出导入;1:仅导出;2:仅导入)
Type type() default Type.ALL; */
Type type() default Type.ALL;
public enum Type
{ public enum Type
ALL(0), EXPORT(1), IMPORT(2); {
private final int value; ALL(0), EXPORT(1), IMPORT(2);
private final int value;
Type(int value)
{ Type(int value)
this.value = value; {
} this.value = value;
}
public int value()
{ public int value()
return this.value; {
} return this.value;
} }
}
public enum ColumnType
{ public enum ColumnType
NUMERIC(0), STRING(1), IMAGE(2), TEXT(3); {
private final int value; NUMERIC(0), STRING(1), IMAGE(2), TEXT(3);
private final int value;
ColumnType(int value)
{ ColumnType(int value)
this.value = value; {
} this.value = value;
}
public int value()
{ public int value()
return this.value; {
} return this.value;
} }
}
} }
@@ -1,18 +1,18 @@
package com.ruoyi.common.annotation; package com.ruoyi.common.annotation;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* Excel注解集 * Excel注解集
* *
* @author ruoyi * @author ruoyi
*/ */
@Target(ElementType.FIELD) @Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
public @interface Excels public @interface Excels
{ {
public Excel[] value(); public Excel[] value();
} }
@@ -1,51 +1,51 @@
package com.ruoyi.common.annotation; package com.ruoyi.common.annotation;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.enums.OperatorType; import com.ruoyi.common.enums.OperatorType;
/** /**
* 自定义操作日志记录注解 * 自定义操作日志记录注解
* *
* @author ruoyi * @author ruoyi
* *
*/ */
@Target({ ElementType.PARAMETER, ElementType.METHOD }) @Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface Log public @interface Log
{ {
/** /**
* 模块 * 模块
*/ */
public String title() default ""; public String title() default "";
/** /**
* 功能 * 功能
*/ */
public BusinessType businessType() default BusinessType.OTHER; public BusinessType businessType() default BusinessType.OTHER;
/** /**
* 操作人类别 * 操作人类别
*/ */
public OperatorType operatorType() default OperatorType.MANAGE; public OperatorType operatorType() default OperatorType.MANAGE;
/** /**
* 是否保存请求的参数 * 是否保存请求的参数
*/ */
public boolean isSaveRequestData() default true; public boolean isSaveRequestData() default true;
/** /**
* 是否保存响应的参数 * 是否保存响应的参数
*/ */
public boolean isSaveResponseData() default true; public boolean isSaveResponseData() default true;
/** /**
* 排除指定的请求参数 * 排除指定的请求参数
*/ */
public String[] excludeParamNames() default {}; public String[] excludeParamNames() default {};
} }
@@ -1,40 +1,40 @@
package com.ruoyi.common.annotation; package com.ruoyi.common.annotation;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.enums.LimitType; import com.ruoyi.common.enums.LimitType;
/** /**
* 限流注解 * 限流注解
* *
* @author ruoyi * @author ruoyi
*/ */
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface RateLimiter public @interface RateLimiter
{ {
/** /**
* 限流key * 限流key
*/ */
public String key() default CacheConstants.RATE_LIMIT_KEY; public String key() default CacheConstants.RATE_LIMIT_KEY;
/** /**
* 限流时间,单位秒 * 限流时间,单位秒
*/ */
public int time() default 60; public int time() default 60;
/** /**
* 限流次数 * 限流次数
*/ */
public int count() default 100; public int count() default 100;
/** /**
* 限流类型 * 限流类型
*/ */
public LimitType limitType() default LimitType.DEFAULT; public LimitType limitType() default LimitType.DEFAULT;
} }
@@ -1,31 +1,31 @@
package com.ruoyi.common.annotation; package com.ruoyi.common.annotation;
import java.lang.annotation.Documented; import java.lang.annotation.Documented;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited; import java.lang.annotation.Inherited;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
/** /**
* 自定义注解防止表单重复提交 * 自定义注解防止表单重复提交
* *
* @author ruoyi * @author ruoyi
* *
*/ */
@Inherited @Inherited
@Target(ElementType.METHOD) @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Documented @Documented
public @interface RepeatSubmit public @interface RepeatSubmit
{ {
/** /**
* 间隔时间(ms),小于此时间视为重复提交 * 间隔时间(ms),小于此时间视为重复提交
*/ */
public int interval() default 5000; public int interval() default 5000;
/** /**
* 提示消息 * 提示消息
*/ */
public String message() default "不允许重复提交,请稍候再试"; public String message() default "不允许重复提交,请稍候再试";
} }
@@ -5,7 +5,7 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy; import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; import java.lang.annotation.Target;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside; import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize; import tools.jackson.databind.annotation.JsonSerialize;
import com.ruoyi.common.config.serializer.SensitiveJsonSerializer; import com.ruoyi.common.config.serializer.SensitiveJsonSerializer;
import com.ruoyi.common.enums.DesensitizedType; import com.ruoyi.common.enums.DesensitizedType;
@@ -15,7 +15,7 @@ import com.ruoyi.common.enums.DesensitizedType;
* @author ruoyi * @author ruoyi
*/ */
@Retention(RetentionPolicy.RUNTIME) @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD) @Target({ ElementType.FIELD, ElementType.METHOD })
@JacksonAnnotationsInside @JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class) @JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive public @interface Sensitive
@@ -1,122 +1,122 @@
package com.ruoyi.common.config; package com.ruoyi.common.config;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
/** /**
* 读取项目相关配置 * 读取项目相关配置
* *
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
@ConfigurationProperties(prefix = "ruoyi") @ConfigurationProperties(prefix = "ruoyi")
public class RuoYiConfig public class RuoYiConfig
{ {
/** 项目名称 */ /** 项目名称 */
private String name; private String name;
/** 版本 */ /** 版本 */
private String version; private String version;
/** 版权年份 */ /** 版权年份 */
private String copyrightYear; private String copyrightYear;
/** 上传路径 */ /** 上传路径 */
private static String profile; private static String profile;
/** 获取地址开关 */ /** 获取地址开关 */
private static boolean addressEnabled; private static boolean addressEnabled;
/** 验证码类型 */ /** 验证码类型 */
private static String captchaType; private static String captchaType;
public String getName() public String getName()
{ {
return name; return name;
} }
public void setName(String name) public void setName(String name)
{ {
this.name = name; this.name = name;
} }
public String getVersion() public String getVersion()
{ {
return version; return version;
} }
public void setVersion(String version) public void setVersion(String version)
{ {
this.version = version; this.version = version;
} }
public String getCopyrightYear() public String getCopyrightYear()
{ {
return copyrightYear; return copyrightYear;
} }
public void setCopyrightYear(String copyrightYear) public void setCopyrightYear(String copyrightYear)
{ {
this.copyrightYear = copyrightYear; this.copyrightYear = copyrightYear;
} }
public static String getProfile() public static String getProfile()
{ {
return profile; return profile;
} }
public void setProfile(String profile) public void setProfile(String profile)
{ {
RuoYiConfig.profile = profile; RuoYiConfig.profile = profile;
} }
public static boolean isAddressEnabled() public static boolean isAddressEnabled()
{ {
return addressEnabled; return addressEnabled;
} }
public void setAddressEnabled(boolean addressEnabled) public void setAddressEnabled(boolean addressEnabled)
{ {
RuoYiConfig.addressEnabled = addressEnabled; RuoYiConfig.addressEnabled = addressEnabled;
} }
public static String getCaptchaType() { public static String getCaptchaType() {
return captchaType; return captchaType;
} }
public void setCaptchaType(String captchaType) { public void setCaptchaType(String captchaType) {
RuoYiConfig.captchaType = captchaType; RuoYiConfig.captchaType = captchaType;
} }
/** /**
* 获取导入上传路径 * 获取导入上传路径
*/ */
public static String getImportPath() public static String getImportPath()
{ {
return getProfile() + "/import"; return getProfile() + "/import";
} }
/** /**
* 获取头像上传路径 * 获取头像上传路径
*/ */
public static String getAvatarPath() public static String getAvatarPath()
{ {
return getProfile() + "/avatar"; return getProfile() + "/avatar";
} }
/** /**
* 获取下载路径 * 获取下载路径
*/ */
public static String getDownloadPath() public static String getDownloadPath()
{ {
return getProfile() + "/download/"; return getProfile() + "/download/";
} }
/** /**
* 获取上传路径 * 获取上传路径
*/ */
public static String getUploadPath() public static String getUploadPath()
{ {
return getProfile() + "/upload"; return getProfile() + "/upload";
} }
} }
@@ -1,13 +1,13 @@
package com.ruoyi.common.config.serializer; package com.ruoyi.common.config.serializer;
import java.io.IOException;
import java.util.Objects; import java.util.Objects;
import com.fasterxml.jackson.core.JsonGenerator; import tools.jackson.core.JacksonException;
import com.fasterxml.jackson.databind.BeanProperty; import tools.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonMappingException; import tools.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonSerializer; import tools.jackson.databind.DatabindException;
import com.fasterxml.jackson.databind.SerializerProvider; import tools.jackson.databind.SerializationContext;
import com.fasterxml.jackson.databind.ser.ContextualSerializer; import tools.jackson.databind.ValueSerializer;
import tools.jackson.databind.ser.std.StdSerializer;
import com.ruoyi.common.annotation.Sensitive; import com.ruoyi.common.annotation.Sensitive;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.DesensitizedType; import com.ruoyi.common.enums.DesensitizedType;
@@ -18,14 +18,26 @@ import com.ruoyi.common.utils.SecurityUtils;
* *
* @author ruoyi * @author ruoyi
*/ */
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer public class SensitiveJsonSerializer extends StdSerializer<String>
{ {
private DesensitizedType desensitizedType; private final DesensitizedType desensitizedType;
public SensitiveJsonSerializer()
{
super(String.class);
this.desensitizedType = null;
}
public SensitiveJsonSerializer(DesensitizedType desensitizedType)
{
super(String.class);
this.desensitizedType = desensitizedType;
}
@Override @Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException public void serialize(String value, JsonGenerator gen, SerializationContext ctxt) throws JacksonException
{ {
if (desensitization()) if (desensitizedType != null && desensitization())
{ {
gen.writeString(desensitizedType.desensitizer().apply(value)); gen.writeString(desensitizedType.desensitizer().apply(value));
} }
@@ -36,16 +48,14 @@ public class SensitiveJsonSerializer extends JsonSerializer<String> implements C
} }
@Override @Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property) public ValueSerializer<?> createContextual(SerializationContext ctxt, BeanProperty property) throws DatabindException
throws JsonMappingException
{ {
Sensitive annotation = property.getAnnotation(Sensitive.class); Sensitive annotation = property.getAnnotation(Sensitive.class);
if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass())) if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass()))
{ {
this.desensitizedType = annotation.desensitizedType(); return new SensitiveJsonSerializer(annotation.desensitizedType());
return this;
} }
return prov.findValueSerializer(property.getType(), property); return ctxt.findValueSerializer(property.getType());
} }
/** /**
@@ -1,44 +1,44 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
/** /**
* 缓存的key 常量 * 缓存的key 常量
* *
* @author ruoyi * @author ruoyi
*/ */
public class CacheConstants public class CacheConstants
{ {
/** /**
* 登录用户 redis key * 登录用户 redis key
*/ */
public static final String LOGIN_TOKEN_KEY = "login_tokens:"; public static final String LOGIN_TOKEN_KEY = "login_tokens:";
/** /**
* 验证码 redis key * 验证码 redis key
*/ */
public static final String CAPTCHA_CODE_KEY = "captcha_codes:"; public static final String CAPTCHA_CODE_KEY = "captcha_codes:";
/** /**
* 参数管理 cache key * 参数管理 cache key
*/ */
public static final String SYS_CONFIG_KEY = "sys_config:"; public static final String SYS_CONFIG_KEY = "sys_config:";
/** /**
* 字典管理 cache key * 字典管理 cache key
*/ */
public static final String SYS_DICT_KEY = "sys_dict:"; public static final String SYS_DICT_KEY = "sys_dict:";
/** /**
* 防重提交 redis key * 防重提交 redis key
*/ */
public static final String REPEAT_SUBMIT_KEY = "repeat_submit:"; public static final String REPEAT_SUBMIT_KEY = "repeat_submit:";
/** /**
* 限流 redis key * 限流 redis key
*/ */
public static final String RATE_LIMIT_KEY = "rate_limit:"; public static final String RATE_LIMIT_KEY = "rate_limit:";
/** /**
* 登录账户密码错误次数 redis key * 登录账户密码错误次数 redis key
*/ */
public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:"; public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
} }
@@ -1,173 +1,204 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
import java.util.Locale; import java.util.Locale;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
/** /**
* 通用常量信息 * 通用常量信息
* *
* @author ruoyi * @author ruoyi
*/ */
public class Constants public class Constants
{ {
/** /**
* UTF-8 字符集 * UTF-8 字符集
*/ */
public static final String UTF8 = "UTF-8"; public static final String UTF8 = "UTF-8";
/** /**
* GBK 字符集 * GBK 字符集
*/ */
public static final String GBK = "GBK"; public static final String GBK = "GBK";
/** /**
* 系统语言 * 系统语言
*/ */
public static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE; public static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;
/** /**
* www主域 * www主域
*/ */
public static final String WWW = "www."; public static final String WWW = "www.";
/** /**
* http请求 * http请求
*/ */
public static final String HTTP = "http://"; public static final String HTTP = "http://";
/** /**
* https请求 * https请求
*/ */
public static final String HTTPS = "https://"; public static final String HTTPS = "https://";
/** /**
* 通用成功标识 * 通用成功标识
*/ */
public static final String SUCCESS = "0"; public static final String SUCCESS = "0";
/** /**
* 通用失败标识 * 通用失败标识
*/ */
public static final String FAIL = "1"; public static final String FAIL = "1";
/** /**
* 登录成功 * 登录成功
*/ */
public static final String LOGIN_SUCCESS = "Success"; public static final String LOGIN_SUCCESS = "Success";
/** /**
* 注销 * 注销
*/ */
public static final String LOGOUT = "Logout"; public static final String LOGOUT = "Logout";
/** /**
* 注册 * 注册
*/ */
public static final String REGISTER = "Register"; public static final String REGISTER = "Register";
/** /**
* 登录失败 * 登录失败
*/ */
public static final String LOGIN_FAIL = "Error"; public static final String LOGIN_FAIL = "Error";
/** /**
* 所有权限标识 * 所有权限标识
*/ */
public static final String ALL_PERMISSION = "*:*:*"; public static final String ALL_PERMISSION = "*:*:*";
/** /**
* 管理员角色权限标识 * 管理员角色权限标识
*/ */
public static final String SUPER_ADMIN = "admin"; public static final String SUPER_ADMIN = "admin";
/** /**
* 角色权限分隔符 * 角色权限分隔符
*/ */
public static final String ROLE_DELIMITER = ","; public static final String ROLE_DELIMITER = ",";
/** /**
* 权限标识分隔符 * 权限标识分隔符
*/ */
public static final String PERMISSION_DELIMITER = ","; public static final String PERMISSION_DELIMITER = ",";
/** /**
* 验证码有效期(分钟) * 验证码有效期(分钟)
*/ */
public static final Integer CAPTCHA_EXPIRATION = 2; public static final Integer CAPTCHA_EXPIRATION = 2;
/** /**
* 令牌 * 令牌
*/ */
public static final String TOKEN = "token"; public static final String TOKEN = "token";
/** /**
* 令牌前缀 * 令牌前缀
*/ */
public static final String TOKEN_PREFIX = "Bearer "; public static final String TOKEN_PREFIX = "Bearer ";
/** /**
* 令牌前缀 * 令牌前缀
*/ */
public static final String LOGIN_USER_KEY = "login_user_key"; public static final String LOGIN_USER_KEY = "login_user_key";
/** /**
* 用户ID * 用户ID
*/ */
public static final String JWT_USERID = "userid"; public static final String JWT_USERID = "userid";
/** /**
* 用户名称 * 用户名称
*/ */
public static final String JWT_USERNAME = Claims.SUBJECT; public static final String JWT_USERNAME = Claims.SUBJECT;
/** /**
* 用户头像 * 用户头像
*/ */
public static final String JWT_AVATAR = "avatar"; public static final String JWT_AVATAR = "avatar";
/** /**
* 创建时间 * 创建时间
*/ */
public static final String JWT_CREATED = "created"; public static final String JWT_CREATED = "created";
/** /**
* 用户权限 * 用户权限
*/ */
public static final String JWT_AUTHORITIES = "authorities"; public static final String JWT_AUTHORITIES = "authorities";
/** /**
* 资源映射路径 前缀 * 资源映射路径 前缀
*/ */
public static final String RESOURCE_PREFIX = "/profile"; public static final String RESOURCE_PREFIX = "/profile";
/** /**
* RMI 远程方法调用 * RMI 远程方法调用
*/ */
public static final String LOOKUP_RMI = "rmi:"; public static final String LOOKUP_RMI = "rmi:";
/** /**
* LDAP 远程方法调用 * LDAP 远程方法调用
*/ */
public static final String LOOKUP_LDAP = "ldap:"; public static final String LOOKUP_LDAP = "ldap:";
/** /**
* LDAPS 远程方法调用 * LDAPS 远程方法调用
*/ */
public static final String LOOKUP_LDAPS = "ldaps:"; public static final String LOOKUP_LDAPS = "ldaps:";
/** /**
* 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全) * 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
*/ */
public static final String[] JSON_WHITELIST_STR = { "com.ruoyi" }; public static final String[] JSON_WHITELIST_STR = { "com.ruoyi" };
/** /**
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
*/ */
public static final String[] JOB_WHITELIST_STR = { "com.ruoyi.quartz.task" }; public static final String[] JOB_WHITELIST_STR = { "com.ruoyi.quartz.task" };
/** /**
* 定时任务违规的字符 * 定时任务违规的字符
*/ */
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config", "com.ruoyi.generator" }; "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config", "com.ruoyi.generator" };
}
/**
* 部门相关常量
*/
public static class Dept
{
/**
* 全部数据权限
*/
public static final String DATA_SCOPE_ALL = "1";
/**
* 自定数据权限
*/
public static final String DATA_SCOPE_CUSTOM = "2";
/**
* 部门数据权限
*/
public static final String DATA_SCOPE_DEPT = "3";
/**
* 部门及以下数据权限
*/
public static final String DATA_SCOPE_DEPT_AND_CHILD = "4";
/**
* 仅本人数据权限
*/
public static final String DATA_SCOPE_SELF = "5";
}
}
@@ -1,117 +1,120 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
/** /**
* 代码生成通用常量 * 代码生成通用常量
* *
* @author ruoyi * @author ruoyi
*/ */
public class GenConstants public class GenConstants
{ {
/** 单表(增删改查) */ /** 单表(增删改查) */
public static final String TPL_CRUD = "crud"; public static final String TPL_CRUD = "crud";
/** 树表(增删改查) */ /** 树表(增删改查) */
public static final String TPL_TREE = "tree"; public static final String TPL_TREE = "tree";
/** 主子表(增删改查) */ /** 主子表(增删改查) */
public static final String TPL_SUB = "sub"; public static final String TPL_SUB = "sub";
/** 树编码字段 */ /** 树编码字段 */
public static final String TREE_CODE = "treeCode"; public static final String TREE_CODE = "treeCode";
/** 树父编码字段 */ /** 树父编码字段 */
public static final String TREE_PARENT_CODE = "treeParentCode"; public static final String TREE_PARENT_CODE = "treeParentCode";
/** 树名称字段 */ /** 树名称字段 */
public static final String TREE_NAME = "treeName"; public static final String TREE_NAME = "treeName";
/** 上级菜单ID字段 */ /** 上级菜单ID字段 */
public static final String PARENT_MENU_ID = "parentMenuId"; public static final String PARENT_MENU_ID = "parentMenuId";
/** 上级菜单名称字段 */ /** 上级菜单名称字段 */
public static final String PARENT_MENU_NAME = "parentMenuName"; public static final String PARENT_MENU_NAME = "parentMenuName";
/** 数据库字符串类型 */ /** 生成详情页开关 */
public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2", "character varying" }; public static final String GEN_VIEW = "genView";
/** 数据库文本类型 */ /** 数据库字符串类型 */
public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" }; public static final String[] COLUMNTYPE_STR = { "char", "varchar", "nvarchar", "varchar2" };
/** 数据库时间类型 */ /** 数据库文本类型 */
public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" }; public static final String[] COLUMNTYPE_TEXT = { "tinytext", "text", "mediumtext", "longtext" };
/** 数据库数字类型 */ /** 数据库时间类型 */
public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer", public static final String[] COLUMNTYPE_TIME = { "datetime", "time", "date", "timestamp" };
"bit", "bigint", "float", "double", "decimal", "numeric" };
/** 数据库数字类型 */
/** 页面不需要编辑字段 */ public static final String[] COLUMNTYPE_NUMBER = { "tinyint", "smallint", "mediumint", "int", "number", "integer",
public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" }; "bit", "bigint", "float", "double", "decimal" };
/** 页面不需要显示的列表字段 */ /** 页面不需要编辑字段 */
public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by", public static final String[] COLUMNNAME_NOT_EDIT = { "id", "create_by", "create_time", "del_flag" };
"update_time" };
/** 页面不需要显示的列表字段 */
/** 页面不需要查询字段 */ public static final String[] COLUMNNAME_NOT_LIST = { "id", "create_by", "create_time", "del_flag", "update_by",
public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by", "update_time" };
"update_time", "remark" };
/** 页面不需要查询字段 */
/** Entity基类字段 */ public static final String[] COLUMNNAME_NOT_QUERY = { "id", "create_by", "create_time", "del_flag", "update_by",
public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" }; "update_time", "remark" };
/** Tree基类字段 */ /** Entity基类字段 */
public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" }; public static final String[] BASE_ENTITY = { "createBy", "createTime", "updateBy", "updateTime", "remark" };
/** 文本框 */ /** Tree基类字段 */
public static final String HTML_INPUT = "input"; public static final String[] TREE_ENTITY = { "parentName", "parentId", "orderNum", "ancestors", "children" };
/** 文本域 */ /** 文本框 */
public static final String HTML_TEXTAREA = "textarea"; public static final String HTML_INPUT = "input";
/** 下拉框 */ /** 文本域 */
public static final String HTML_SELECT = "select"; public static final String HTML_TEXTAREA = "textarea";
/** 单选框 */ /** 下拉框 */
public static final String HTML_RADIO = "radio"; public static final String HTML_SELECT = "select";
/** 复选框 */ /** 单选框 */
public static final String HTML_CHECKBOX = "checkbox"; public static final String HTML_RADIO = "radio";
/** 日期控件 */ /** 复选框 */
public static final String HTML_DATETIME = "datetime"; public static final String HTML_CHECKBOX = "checkbox";
/** 图片上传控件 */ /** 日期控件 */
public static final String HTML_IMAGE_UPLOAD = "imageUpload"; public static final String HTML_DATETIME = "datetime";
/** 文件上传控件 */ /** 图片上传控件 */
public static final String HTML_FILE_UPLOAD = "fileUpload"; public static final String HTML_IMAGE_UPLOAD = "imageUpload";
/** 富文本控件 */ /** 文件上传控件 */
public static final String HTML_EDITOR = "editor"; public static final String HTML_FILE_UPLOAD = "fileUpload";
/** 字符串类型 */ /** 富文本控件 */
public static final String TYPE_STRING = "String"; public static final String HTML_EDITOR = "editor";
/** 整型 */ /** 字符串类型 */
public static final String TYPE_INTEGER = "Integer"; public static final String TYPE_STRING = "String";
/** 长整型 */ /** 整型 */
public static final String TYPE_LONG = "Long"; public static final String TYPE_INTEGER = "Integer";
/** 浮点型 */ /** 长整型 */
public static final String TYPE_DOUBLE = "Double"; public static final String TYPE_LONG = "Long";
/** 高精度计算类型 */ /** 浮点型 */
public static final String TYPE_BIGDECIMAL = "BigDecimal"; public static final String TYPE_DOUBLE = "Double";
/** 时间类型 */ /** 高精度计算类型 */
public static final String TYPE_DATE = "Date"; public static final String TYPE_BIGDECIMAL = "BigDecimal";
/** 模糊查询 */ /** 时间类型 */
public static final String QUERY_LIKE = "LIKE"; public static final String TYPE_DATE = "Date";
/** 相等查询 */ /** 模糊查询 */
public static final String QUERY_EQ = "EQ"; public static final String QUERY_LIKE = "LIKE";
/** 需要 */ /** 相等查询 */
public static final String REQUIRE = "1"; public static final String QUERY_EQ = "EQ";
}
/** 需要 */
public static final String REQUIRE = "1";
}
@@ -1,94 +1,94 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
/** /**
* 返回状态码 * 返回状态码
* *
* @author ruoyi * @author ruoyi
*/ */
public class HttpStatus public class HttpStatus
{ {
/** /**
* 操作成功 * 操作成功
*/ */
public static final int SUCCESS = 200; public static final int SUCCESS = 200;
/** /**
* 对象创建成功 * 对象创建成功
*/ */
public static final int CREATED = 201; public static final int CREATED = 201;
/** /**
* 请求已经被接受 * 请求已经被接受
*/ */
public static final int ACCEPTED = 202; public static final int ACCEPTED = 202;
/** /**
* 操作已经执行成功,但是没有返回数据 * 操作已经执行成功,但是没有返回数据
*/ */
public static final int NO_CONTENT = 204; public static final int NO_CONTENT = 204;
/** /**
* 资源已被移除 * 资源已被移除
*/ */
public static final int MOVED_PERM = 301; public static final int MOVED_PERM = 301;
/** /**
* 重定向 * 重定向
*/ */
public static final int SEE_OTHER = 303; public static final int SEE_OTHER = 303;
/** /**
* 资源没有被修改 * 资源没有被修改
*/ */
public static final int NOT_MODIFIED = 304; public static final int NOT_MODIFIED = 304;
/** /**
* 参数列表错误(缺少,格式不匹配) * 参数列表错误(缺少,格式不匹配)
*/ */
public static final int BAD_REQUEST = 400; public static final int BAD_REQUEST = 400;
/** /**
* 未授权 * 未授权
*/ */
public static final int UNAUTHORIZED = 401; public static final int UNAUTHORIZED = 401;
/** /**
* 访问受限,授权过期 * 访问受限,授权过期
*/ */
public static final int FORBIDDEN = 403; public static final int FORBIDDEN = 403;
/** /**
* 资源,服务未找到 * 资源,服务未找到
*/ */
public static final int NOT_FOUND = 404; public static final int NOT_FOUND = 404;
/** /**
* 不允许的http方法 * 不允许的http方法
*/ */
public static final int BAD_METHOD = 405; public static final int BAD_METHOD = 405;
/** /**
* 资源冲突,或者资源被锁 * 资源冲突,或者资源被锁
*/ */
public static final int CONFLICT = 409; public static final int CONFLICT = 409;
/** /**
* 不支持的数据,媒体类型 * 不支持的数据,媒体类型
*/ */
public static final int UNSUPPORTED_TYPE = 415; public static final int UNSUPPORTED_TYPE = 415;
/** /**
* 系统内部错误 * 系统内部错误
*/ */
public static final int ERROR = 500; public static final int ERROR = 500;
/** /**
* 接口未实现 * 接口未实现
*/ */
public static final int NOT_IMPLEMENTED = 501; public static final int NOT_IMPLEMENTED = 501;
/** /**
* 系统警告消息 * 系统警告消息
*/ */
public static final int WARN = 601; public static final int WARN = 601;
} }
@@ -1,50 +1,50 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
/** /**
* 任务调度通用常量 * 任务调度通用常量
* *
* @author ruoyi * @author ruoyi
*/ */
public class ScheduleConstants public class ScheduleConstants
{ {
public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME"; public static final String TASK_CLASS_NAME = "TASK_CLASS_NAME";
/** 执行目标key */ /** 执行目标key */
public static final String TASK_PROPERTIES = "TASK_PROPERTIES"; public static final String TASK_PROPERTIES = "TASK_PROPERTIES";
/** 默认 */ /** 默认 */
public static final String MISFIRE_DEFAULT = "0"; public static final String MISFIRE_DEFAULT = "0";
/** 立即触发执行 */ /** 立即触发执行 */
public static final String MISFIRE_IGNORE_MISFIRES = "1"; public static final String MISFIRE_IGNORE_MISFIRES = "1";
/** 触发一次执行 */ /** 触发一次执行 */
public static final String MISFIRE_FIRE_AND_PROCEED = "2"; public static final String MISFIRE_FIRE_AND_PROCEED = "2";
/** 不触发立即执行 */ /** 不触发立即执行 */
public static final String MISFIRE_DO_NOTHING = "3"; public static final String MISFIRE_DO_NOTHING = "3";
public enum Status public enum Status
{ {
/** /**
* 正常 * 正常
*/ */
NORMAL("0"), NORMAL("0"),
/** /**
* 暂停 * 暂停
*/ */
PAUSE("1"); PAUSE("1");
private String value; private String value;
private Status(String value) private Status(String value)
{ {
this.value = value; this.value = value;
} }
public String getValue() public String getValue()
{ {
return value; return value;
} }
} }
} }
@@ -1,81 +1,81 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
/** /**
* 用户常量信息 * 用户常量信息
* *
* @author ruoyi * @author ruoyi
*/ */
public class UserConstants public class UserConstants
{ {
/** /**
* 平台内系统用户的唯一标志 * 平台内系统用户的唯一标志
*/ */
public static final String SYS_USER = "SYS_USER"; public static final String SYS_USER = "SYS_USER";
/** 正常状态 */ /** 正常状态 */
public static final String NORMAL = "0"; public static final String NORMAL = "0";
/** 异常状态 */ /** 异常状态 */
public static final String EXCEPTION = "1"; public static final String EXCEPTION = "1";
/** 用户封禁状态 */ /** 用户封禁状态 */
public static final String USER_DISABLE = "1"; public static final String USER_DISABLE = "1";
/** 角色正常状态 */ /** 角色正常状态 */
public static final String ROLE_NORMAL = "0"; public static final String ROLE_NORMAL = "0";
/** 角色封禁状态 */ /** 角色封禁状态 */
public static final String ROLE_DISABLE = "1"; public static final String ROLE_DISABLE = "1";
/** 部门正常状态 */ /** 部门正常状态 */
public static final String DEPT_NORMAL = "0"; public static final String DEPT_NORMAL = "0";
/** 部门停用状态 */ /** 部门停用状态 */
public static final String DEPT_DISABLE = "1"; public static final String DEPT_DISABLE = "1";
/** 字典正常状态 */ /** 字典正常状态 */
public static final String DICT_NORMAL = "0"; public static final String DICT_NORMAL = "0";
/** 是否为系统默认(是) */ /** 是否为系统默认(是) */
public static final String YES = "Y"; public static final String YES = "Y";
/** 是否菜单外链(是) */ /** 是否菜单外链(是) */
public static final String YES_FRAME = "0"; public static final String YES_FRAME = "0";
/** 是否菜单外链(否) */ /** 是否菜单外链(否) */
public static final String NO_FRAME = "1"; public static final String NO_FRAME = "1";
/** 菜单类型(目录) */ /** 菜单类型(目录) */
public static final String TYPE_DIR = "M"; public static final String TYPE_DIR = "M";
/** 菜单类型(菜单) */ /** 菜单类型(菜单) */
public static final String TYPE_MENU = "C"; public static final String TYPE_MENU = "C";
/** 菜单类型(按钮) */ /** 菜单类型(按钮) */
public static final String TYPE_BUTTON = "F"; public static final String TYPE_BUTTON = "F";
/** Layout组件标识 */ /** Layout组件标识 */
public final static String LAYOUT = "Layout"; public final static String LAYOUT = "Layout";
/** ParentView组件标识 */ /** ParentView组件标识 */
public final static String PARENT_VIEW = "ParentView"; public final static String PARENT_VIEW = "ParentView";
/** InnerLink组件标识 */ /** InnerLink组件标识 */
public final static String INNER_LINK = "InnerLink"; public final static String INNER_LINK = "InnerLink";
/** 校验是否唯一的返回标识 */ /** 校验是否唯一的返回标识 */
public final static boolean UNIQUE = true; public final static boolean UNIQUE = true;
public final static boolean NOT_UNIQUE = false; public final static boolean NOT_UNIQUE = false;
/** /**
* 用户名长度限制 * 用户名长度限制
*/ */
public static final int USERNAME_MIN_LENGTH = 2; public static final int USERNAME_MIN_LENGTH = 2;
public static final int USERNAME_MAX_LENGTH = 20; public static final int USERNAME_MAX_LENGTH = 20;
/** /**
* 密码长度限制 * 密码长度限制
*/ */
public static final int PASSWORD_MIN_LENGTH = 5; public static final int PASSWORD_MIN_LENGTH = 5;
public static final int PASSWORD_MAX_LENGTH = 20; public static final int PASSWORD_MAX_LENGTH = 20;
} }
@@ -1,202 +1,202 @@
package com.ruoyi.common.core.controller; package com.ruoyi.common.core.controller;
import java.beans.PropertyEditorSupport; import java.beans.PropertyEditorSupport;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.web.bind.WebDataBinder; import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.InitBinder;
import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.core.page.PageDomain; import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.page.TableSupport; import com.ruoyi.common.core.page.TableSupport;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.PageUtils; import com.ruoyi.common.utils.PageUtils;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.sql.SqlUtil; import com.ruoyi.common.utils.sql.SqlUtil;
/** /**
* web层通用数据处理 * web层通用数据处理
* *
* @author ruoyi * @author ruoyi
*/ */
public class BaseController public class BaseController
{ {
protected final Logger logger = LoggerFactory.getLogger(this.getClass()); protected final Logger logger = LoggerFactory.getLogger(this.getClass());
/** /**
* 将前台传递过来的日期格式的字符串,自动转化为Date类型 * 将前台传递过来的日期格式的字符串,自动转化为Date类型
*/ */
@InitBinder @InitBinder
public void initBinder(WebDataBinder binder) public void initBinder(WebDataBinder binder)
{ {
// Date 类型转换 // Date 类型转换
binder.registerCustomEditor(Date.class, new PropertyEditorSupport() binder.registerCustomEditor(Date.class, new PropertyEditorSupport()
{ {
@Override @Override
public void setAsText(String text) public void setAsText(String text)
{ {
setValue(DateUtils.parseDate(text)); setValue(DateUtils.parseDate(text));
} }
}); });
} }
/** /**
* 设置请求分页数据 * 设置请求分页数据
*/ */
protected void startPage() protected void startPage()
{ {
PageUtils.startPage(); PageUtils.startPage();
} }
/** /**
* 设置请求排序数据 * 设置请求排序数据
*/ */
protected void startOrderBy() protected void startOrderBy()
{ {
PageDomain pageDomain = TableSupport.buildPageRequest(); PageDomain pageDomain = TableSupport.buildPageRequest();
if (StringUtils.isNotEmpty(pageDomain.getOrderBy())) if (StringUtils.isNotEmpty(pageDomain.getOrderBy()))
{ {
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy()); String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
PageHelper.orderBy(orderBy); PageHelper.orderBy(orderBy);
} }
} }
/** /**
* 清理分页的线程变量 * 清理分页的线程变量
*/ */
protected void clearPage() protected void clearPage()
{ {
PageUtils.clearPage(); PageUtils.clearPage();
} }
/** /**
* 响应请求分页数据 * 响应请求分页数据
*/ */
@SuppressWarnings({ "rawtypes", "unchecked" }) @SuppressWarnings({ "rawtypes", "unchecked" })
protected TableDataInfo getDataTable(List<?> list) protected TableDataInfo getDataTable(List<?> list)
{ {
TableDataInfo rspData = new TableDataInfo(); TableDataInfo rspData = new TableDataInfo();
rspData.setCode(HttpStatus.SUCCESS); rspData.setCode(HttpStatus.SUCCESS);
rspData.setMsg("查询成功"); rspData.setMsg("查询成功");
rspData.setRows(list); rspData.setRows(list);
rspData.setTotal(new PageInfo(list).getTotal()); rspData.setTotal(new PageInfo(list).getTotal());
return rspData; return rspData;
} }
/** /**
* 返回成功 * 返回成功
*/ */
public AjaxResult success() public AjaxResult success()
{ {
return AjaxResult.success(); return AjaxResult.success();
} }
/** /**
* 返回失败消息 * 返回失败消息
*/ */
public AjaxResult error() public AjaxResult error()
{ {
return AjaxResult.error(); return AjaxResult.error();
} }
/** /**
* 返回成功消息 * 返回成功消息
*/ */
public AjaxResult success(String message) public AjaxResult success(String message)
{ {
return AjaxResult.success(message); return AjaxResult.success(message);
} }
/** /**
* 返回成功消息 * 返回成功消息
*/ */
public AjaxResult success(Object data) public AjaxResult success(Object data)
{ {
return AjaxResult.success(data); return AjaxResult.success(data);
} }
/** /**
* 返回失败消息 * 返回失败消息
*/ */
public AjaxResult error(String message) public AjaxResult error(String message)
{ {
return AjaxResult.error(message); return AjaxResult.error(message);
} }
/** /**
* 返回警告消息 * 返回警告消息
*/ */
public AjaxResult warn(String message) public AjaxResult warn(String message)
{ {
return AjaxResult.warn(message); return AjaxResult.warn(message);
} }
/** /**
* 响应返回结果 * 响应返回结果
* *
* @param rows 影响行数 * @param rows 影响行数
* @return 操作结果 * @return 操作结果
*/ */
protected AjaxResult toAjax(int rows) protected AjaxResult toAjax(int rows)
{ {
return rows > 0 ? AjaxResult.success() : AjaxResult.error(); return rows > 0 ? AjaxResult.success() : AjaxResult.error();
} }
/** /**
* 响应返回结果 * 响应返回结果
* *
* @param result 结果 * @param result 结果
* @return 操作结果 * @return 操作结果
*/ */
protected AjaxResult toAjax(boolean result) protected AjaxResult toAjax(boolean result)
{ {
return result ? success() : error(); return result ? success() : error();
} }
/** /**
* 页面跳转 * 页面跳转
*/ */
public String redirect(String url) public String redirect(String url)
{ {
return StringUtils.format("redirect:{}", url); return StringUtils.format("redirect:{}", url);
} }
/** /**
* 获取用户缓存信息 * 获取用户缓存信息
*/ */
public LoginUser getLoginUser() public LoginUser getLoginUser()
{ {
return SecurityUtils.getLoginUser(); return SecurityUtils.getLoginUser();
} }
/** /**
* 获取登录用户id * 获取登录用户id
*/ */
public Long getUserId() public Long getUserId()
{ {
return getLoginUser().getUserId(); return getLoginUser().getUserId();
} }
/** /**
* 获取登录部门id * 获取登录部门id
*/ */
public Long getDeptId() public Long getDeptId()
{ {
return getLoginUser().getDeptId(); return getLoginUser().getDeptId();
} }
/** /**
* 获取登录用户名 * 获取登录用户名
*/ */
public String getUsername() public String getUsername()
{ {
return getLoginUser().getUsername(); return getLoginUser().getUsername();
} }
} }
@@ -1,216 +1,216 @@
package com.ruoyi.common.core.domain; package com.ruoyi.common.core.domain;
import java.util.HashMap; import java.util.HashMap;
import java.util.Objects; import java.util.Objects;
import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* 操作消息提醒 * 操作消息提醒
* *
* @author ruoyi * @author ruoyi
*/ */
public class AjaxResult extends HashMap<String, Object> public class AjaxResult extends HashMap<String, Object>
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 状态码 */ /** 状态码 */
public static final String CODE_TAG = "code"; public static final String CODE_TAG = "code";
/** 返回内容 */ /** 返回内容 */
public static final String MSG_TAG = "msg"; public static final String MSG_TAG = "msg";
/** 数据对象 */ /** 数据对象 */
public static final String DATA_TAG = "data"; public static final String DATA_TAG = "data";
/** /**
* 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。 * 初始化一个新创建的 AjaxResult 对象,使其表示一个空消息。
*/ */
public AjaxResult() public AjaxResult()
{ {
} }
/** /**
* 初始化一个新创建的 AjaxResult 对象 * 初始化一个新创建的 AjaxResult 对象
* *
* @param code 状态码 * @param code 状态码
* @param msg 返回内容 * @param msg 返回内容
*/ */
public AjaxResult(int code, String msg) public AjaxResult(int code, String msg)
{ {
super.put(CODE_TAG, code); super.put(CODE_TAG, code);
super.put(MSG_TAG, msg); super.put(MSG_TAG, msg);
} }
/** /**
* 初始化一个新创建的 AjaxResult 对象 * 初始化一个新创建的 AjaxResult 对象
* *
* @param code 状态码 * @param code 状态码
* @param msg 返回内容 * @param msg 返回内容
* @param data 数据对象 * @param data 数据对象
*/ */
public AjaxResult(int code, String msg, Object data) public AjaxResult(int code, String msg, Object data)
{ {
super.put(CODE_TAG, code); super.put(CODE_TAG, code);
super.put(MSG_TAG, msg); super.put(MSG_TAG, msg);
if (StringUtils.isNotNull(data)) if (StringUtils.isNotNull(data))
{ {
super.put(DATA_TAG, data); super.put(DATA_TAG, data);
} }
} }
/** /**
* 返回成功消息 * 返回成功消息
* *
* @return 成功消息 * @return 成功消息
*/ */
public static AjaxResult success() public static AjaxResult success()
{ {
return AjaxResult.success("操作成功"); return AjaxResult.success("操作成功");
} }
/** /**
* 返回成功数据 * 返回成功数据
* *
* @return 成功消息 * @return 成功消息
*/ */
public static AjaxResult success(Object data) public static AjaxResult success(Object data)
{ {
return AjaxResult.success("操作成功", data); return AjaxResult.success("操作成功", data);
} }
/** /**
* 返回成功消息 * 返回成功消息
* *
* @param msg 返回内容 * @param msg 返回内容
* @return 成功消息 * @return 成功消息
*/ */
public static AjaxResult success(String msg) public static AjaxResult success(String msg)
{ {
return AjaxResult.success(msg, null); return AjaxResult.success(msg, null);
} }
/** /**
* 返回成功消息 * 返回成功消息
* *
* @param msg 返回内容 * @param msg 返回内容
* @param data 数据对象 * @param data 数据对象
* @return 成功消息 * @return 成功消息
*/ */
public static AjaxResult success(String msg, Object data) public static AjaxResult success(String msg, Object data)
{ {
return new AjaxResult(HttpStatus.SUCCESS, msg, data); return new AjaxResult(HttpStatus.SUCCESS, msg, data);
} }
/** /**
* 返回警告消息 * 返回警告消息
* *
* @param msg 返回内容 * @param msg 返回内容
* @return 警告消息 * @return 警告消息
*/ */
public static AjaxResult warn(String msg) public static AjaxResult warn(String msg)
{ {
return AjaxResult.warn(msg, null); return AjaxResult.warn(msg, null);
} }
/** /**
* 返回警告消息 * 返回警告消息
* *
* @param msg 返回内容 * @param msg 返回内容
* @param data 数据对象 * @param data 数据对象
* @return 警告消息 * @return 警告消息
*/ */
public static AjaxResult warn(String msg, Object data) public static AjaxResult warn(String msg, Object data)
{ {
return new AjaxResult(HttpStatus.WARN, msg, data); return new AjaxResult(HttpStatus.WARN, msg, data);
} }
/** /**
* 返回错误消息 * 返回错误消息
* *
* @return 错误消息 * @return 错误消息
*/ */
public static AjaxResult error() public static AjaxResult error()
{ {
return AjaxResult.error("操作失败"); return AjaxResult.error("操作失败");
} }
/** /**
* 返回错误消息 * 返回错误消息
* *
* @param msg 返回内容 * @param msg 返回内容
* @return 错误消息 * @return 错误消息
*/ */
public static AjaxResult error(String msg) public static AjaxResult error(String msg)
{ {
return AjaxResult.error(msg, null); return AjaxResult.error(msg, null);
} }
/** /**
* 返回错误消息 * 返回错误消息
* *
* @param msg 返回内容 * @param msg 返回内容
* @param data 数据对象 * @param data 数据对象
* @return 错误消息 * @return 错误消息
*/ */
public static AjaxResult error(String msg, Object data) public static AjaxResult error(String msg, Object data)
{ {
return new AjaxResult(HttpStatus.ERROR, msg, data); return new AjaxResult(HttpStatus.ERROR, msg, data);
} }
/** /**
* 返回错误消息 * 返回错误消息
* *
* @param code 状态码 * @param code 状态码
* @param msg 返回内容 * @param msg 返回内容
* @return 错误消息 * @return 错误消息
*/ */
public static AjaxResult error(int code, String msg) public static AjaxResult error(int code, String msg)
{ {
return new AjaxResult(code, msg, null); return new AjaxResult(code, msg, null);
} }
/** /**
* 是否为成功消息 * 是否为成功消息
* *
* @return 结果 * @return 结果
*/ */
public boolean isSuccess() public boolean isSuccess()
{ {
return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG)); return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
} }
/** /**
* 是否为警告消息 * 是否为警告消息
* *
* @return 结果 * @return 结果
*/ */
public boolean isWarn() public boolean isWarn()
{ {
return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG)); return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
} }
/** /**
* 是否为错误消息 * 是否为错误消息
* *
* @return 结果 * @return 结果
*/ */
public boolean isError() public boolean isError()
{ {
return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG)); return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
} }
/** /**
* 方便链式调用 * 方便链式调用
* *
* @param key 键 * @param key 键
* @param value 值 * @param value 值
* @return 数据对象 * @return 数据对象
*/ */
@Override @Override
public AjaxResult put(String key, Object value) public AjaxResult put(String key, Object value)
{ {
super.put(key, value); super.put(key, value);
return this; return this;
} }
} }
@@ -1,118 +1,118 @@
package com.ruoyi.common.core.domain; package com.ruoyi.common.core.domain;
import java.io.Serializable; import java.io.Serializable;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
/** /**
* Entity基类 * Entity基类
* *
* @author ruoyi * @author ruoyi
*/ */
public class BaseEntity implements Serializable public class BaseEntity implements Serializable
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 搜索值 */ /** 搜索值 */
@JsonIgnore @JsonIgnore
private String searchValue; private String searchValue;
/** 创建者 */ /** 创建者 */
private String createBy; private String createBy;
/** 创建时间 */ /** 创建时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createTime; private Date createTime;
/** 更新者 */ /** 更新者 */
private String updateBy; private String updateBy;
/** 更新时间 */ /** 更新时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss") @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date updateTime; private Date updateTime;
/** 备注 */ /** 备注 */
private String remark; private String remark;
/** 请求参数 */ /** 请求参数 */
@JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonInclude(JsonInclude.Include.NON_EMPTY)
private Map<String, Object> params; private Map<String, Object> params;
public String getSearchValue() public String getSearchValue()
{ {
return searchValue; return searchValue;
} }
public void setSearchValue(String searchValue) public void setSearchValue(String searchValue)
{ {
this.searchValue = searchValue; this.searchValue = searchValue;
} }
public String getCreateBy() public String getCreateBy()
{ {
return createBy; return createBy;
} }
public void setCreateBy(String createBy) public void setCreateBy(String createBy)
{ {
this.createBy = createBy; this.createBy = createBy;
} }
public Date getCreateTime() public Date getCreateTime()
{ {
return createTime; return createTime;
} }
public void setCreateTime(Date createTime) public void setCreateTime(Date createTime)
{ {
this.createTime = createTime; this.createTime = createTime;
} }
public String getUpdateBy() public String getUpdateBy()
{ {
return updateBy; return updateBy;
} }
public void setUpdateBy(String updateBy) public void setUpdateBy(String updateBy)
{ {
this.updateBy = updateBy; this.updateBy = updateBy;
} }
public Date getUpdateTime() public Date getUpdateTime()
{ {
return updateTime; return updateTime;
} }
public void setUpdateTime(Date updateTime) public void setUpdateTime(Date updateTime)
{ {
this.updateTime = updateTime; this.updateTime = updateTime;
} }
public String getRemark() public String getRemark()
{ {
return remark; return remark;
} }
public void setRemark(String remark) public void setRemark(String remark)
{ {
this.remark = remark; this.remark = remark;
} }
public Map<String, Object> getParams() public Map<String, Object> getParams()
{ {
if (params == null) if (params == null)
{ {
params = new HashMap<>(); params = new HashMap<>();
} }
return params; return params;
} }
public void setParams(Map<String, Object> params) public void setParams(Map<String, Object> params)
{ {
this.params = params; this.params = params;
} }
} }
@@ -1,79 +1,79 @@
package com.ruoyi.common.core.domain; package com.ruoyi.common.core.domain;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/** /**
* Tree基类 * Tree基类
* *
* @author ruoyi * @author ruoyi
*/ */
public class TreeEntity extends BaseEntity public class TreeEntity extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 父菜单名称 */ /** 父菜单名称 */
private String parentName; private String parentName;
/** 父菜单ID */ /** 父菜单ID */
private Long parentId; private Long parentId;
/** 显示顺序 */ /** 显示顺序 */
private Integer orderNum; private Integer orderNum;
/** 祖级列表 */ /** 祖级列表 */
private String ancestors; private String ancestors;
/** 子部门 */ /** 子部门 */
private List<?> children = new ArrayList<>(); private List<?> children = new ArrayList<>();
public String getParentName() public String getParentName()
{ {
return parentName; return parentName;
} }
public void setParentName(String parentName) public void setParentName(String parentName)
{ {
this.parentName = parentName; this.parentName = parentName;
} }
public Long getParentId() public Long getParentId()
{ {
return parentId; return parentId;
} }
public void setParentId(Long parentId) public void setParentId(Long parentId)
{ {
this.parentId = parentId; this.parentId = parentId;
} }
public Integer getOrderNum() public Integer getOrderNum()
{ {
return orderNum; return orderNum;
} }
public void setOrderNum(Integer orderNum) public void setOrderNum(Integer orderNum)
{ {
this.orderNum = orderNum; this.orderNum = orderNum;
} }
public String getAncestors() public String getAncestors()
{ {
return ancestors; return ancestors;
} }
public void setAncestors(String ancestors) public void setAncestors(String ancestors)
{ {
this.ancestors = ancestors; this.ancestors = ancestors;
} }
public List<?> getChildren() public List<?> getChildren()
{ {
return children; return children;
} }
public void setChildren(List<?> children) public void setChildren(List<?> children)
{ {
this.children = children; this.children = children;
} }
} }
@@ -1,93 +1,93 @@
package com.ruoyi.common.core.domain; package com.ruoyi.common.core.domain;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude;
import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysDept; import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysMenu; import com.ruoyi.common.core.domain.entity.SysMenu;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* Treeselect树结构实体类 * Treeselect树结构实体类
* *
* @author ruoyi * @author ruoyi
*/ */
public class TreeSelect implements Serializable public class TreeSelect implements Serializable
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 节点ID */ /** 节点ID */
private Long id; private Long id;
/** 节点名称 */ /** 节点名称 */
private String label; private String label;
/** 节点禁用 */ /** 节点禁用 */
private boolean disabled = false; private boolean disabled = false;
/** 子节点 */ /** 子节点 */
@JsonInclude(JsonInclude.Include.NON_EMPTY) @JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<TreeSelect> children; private List<TreeSelect> children;
public TreeSelect() public TreeSelect()
{ {
} }
public TreeSelect(SysDept dept) public TreeSelect(SysDept dept)
{ {
this.id = dept.getDeptId(); this.id = dept.getDeptId();
this.label = dept.getDeptName(); this.label = dept.getDeptName();
this.disabled = StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus()); this.disabled = StringUtils.equals(UserConstants.DEPT_DISABLE, dept.getStatus());
this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); this.children = dept.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
} }
public TreeSelect(SysMenu menu) public TreeSelect(SysMenu menu)
{ {
this.id = menu.getMenuId(); this.id = menu.getMenuId();
this.label = menu.getMenuName(); this.label = menu.getMenuName();
this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList()); this.children = menu.getChildren().stream().map(TreeSelect::new).collect(Collectors.toList());
} }
public Long getId() public Long getId()
{ {
return id; return id;
} }
public void setId(Long id) public void setId(Long id)
{ {
this.id = id; this.id = id;
} }
public String getLabel() public String getLabel()
{ {
return label; return label;
} }
public void setLabel(String label) public void setLabel(String label)
{ {
this.label = label; this.label = label;
} }
public boolean isDisabled() public boolean isDisabled()
{ {
return disabled; return disabled;
} }
public void setDisabled(boolean disabled) public void setDisabled(boolean disabled)
{ {
this.disabled = disabled; this.disabled = disabled;
} }
public List<TreeSelect> getChildren() public List<TreeSelect> getChildren()
{ {
return children; return children;
} }
public void setChildren(List<TreeSelect> children) public void setChildren(List<TreeSelect> children)
{ {
this.children = children; this.children = children;
} }
} }
@@ -1,203 +1,203 @@
package com.ruoyi.common.core.domain.entity; package com.ruoyi.common.core.domain.entity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.validation.constraints.Email; import jakarta.validation.constraints.Email;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import javax.validation.constraints.Size; import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
/** /**
* 部门表 sys_dept * 部门表 sys_dept
* *
* @author ruoyi * @author ruoyi
*/ */
public class SysDept extends BaseEntity public class SysDept extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 部门ID */ /** 部门ID */
private Long deptId; private Long deptId;
/** 父部门ID */ /** 父部门ID */
private Long parentId; private Long parentId;
/** 祖级列表 */ /** 祖级列表 */
private String ancestors; private String ancestors;
/** 部门名称 */ /** 部门名称 */
private String deptName; private String deptName;
/** 显示顺序 */ /** 显示顺序 */
private Integer orderNum; private Integer orderNum;
/** 负责人 */ /** 负责人 */
private String leader; private String leader;
/** 联系电话 */ /** 联系电话 */
private String phone; private String phone;
/** 邮箱 */ /** 邮箱 */
private String email; private String email;
/** 部门状态:0正常,1停用 */ /** 部门状态:0正常,1停用 */
private String status; private String status;
/** 删除标志(0代表存在 2代表删除) */ /** 删除标志(0代表存在 2代表删除) */
private String delFlag; private String delFlag;
/** 父部门名称 */ /** 父部门名称 */
private String parentName; private String parentName;
/** 子部门 */ /** 子部门 */
private List<SysDept> children = new ArrayList<SysDept>(); private List<SysDept> children = new ArrayList<SysDept>();
public Long getDeptId() public Long getDeptId()
{ {
return deptId; return deptId;
} }
public void setDeptId(Long deptId) public void setDeptId(Long deptId)
{ {
this.deptId = deptId; this.deptId = deptId;
} }
public Long getParentId() public Long getParentId()
{ {
return parentId; return parentId;
} }
public void setParentId(Long parentId) public void setParentId(Long parentId)
{ {
this.parentId = parentId; this.parentId = parentId;
} }
public String getAncestors() public String getAncestors()
{ {
return ancestors; return ancestors;
} }
public void setAncestors(String ancestors) public void setAncestors(String ancestors)
{ {
this.ancestors = ancestors; this.ancestors = ancestors;
} }
@NotBlank(message = "部门名称不能为空") @NotBlank(message = "部门名称不能为空")
@Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符") @Size(min = 0, max = 30, message = "部门名称长度不能超过30个字符")
public String getDeptName() public String getDeptName()
{ {
return deptName; return deptName;
} }
public void setDeptName(String deptName) public void setDeptName(String deptName)
{ {
this.deptName = deptName; this.deptName = deptName;
} }
@NotNull(message = "显示顺序不能为空") @NotNull(message = "显示顺序不能为空")
public Integer getOrderNum() public Integer getOrderNum()
{ {
return orderNum; return orderNum;
} }
public void setOrderNum(Integer orderNum) public void setOrderNum(Integer orderNum)
{ {
this.orderNum = orderNum; this.orderNum = orderNum;
} }
public String getLeader() public String getLeader()
{ {
return leader; return leader;
} }
public void setLeader(String leader) public void setLeader(String leader)
{ {
this.leader = leader; this.leader = leader;
} }
@Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符") @Size(min = 0, max = 11, message = "联系电话长度不能超过11个字符")
public String getPhone() public String getPhone()
{ {
return phone; return phone;
} }
public void setPhone(String phone) public void setPhone(String phone)
{ {
this.phone = phone; this.phone = phone;
} }
@Email(message = "邮箱格式不正确") @Email(message = "邮箱格式不正确")
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符") @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail() public String getEmail()
{ {
return email; return email;
} }
public void setEmail(String email) public void setEmail(String email)
{ {
this.email = email; this.email = email;
} }
public String getStatus() public String getStatus()
{ {
return status; return status;
} }
public void setStatus(String status) public void setStatus(String status)
{ {
this.status = status; this.status = status;
} }
public String getDelFlag() public String getDelFlag()
{ {
return delFlag; return delFlag;
} }
public void setDelFlag(String delFlag) public void setDelFlag(String delFlag)
{ {
this.delFlag = delFlag; this.delFlag = delFlag;
} }
public String getParentName() public String getParentName()
{ {
return parentName; return parentName;
} }
public void setParentName(String parentName) public void setParentName(String parentName)
{ {
this.parentName = parentName; this.parentName = parentName;
} }
public List<SysDept> getChildren() public List<SysDept> getChildren()
{ {
return children; return children;
} }
public void setChildren(List<SysDept> children) public void setChildren(List<SysDept> children)
{ {
this.children = children; this.children = children;
} }
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("deptId", getDeptId()) .append("deptId", getDeptId())
.append("parentId", getParentId()) .append("parentId", getParentId())
.append("ancestors", getAncestors()) .append("ancestors", getAncestors())
.append("deptName", getDeptName()) .append("deptName", getDeptName())
.append("orderNum", getOrderNum()) .append("orderNum", getOrderNum())
.append("leader", getLeader()) .append("leader", getLeader())
.append("phone", getPhone()) .append("phone", getPhone())
.append("email", getEmail()) .append("email", getEmail())
.append("status", getStatus()) .append("status", getStatus())
.append("delFlag", getDelFlag()) .append("delFlag", getDelFlag())
.append("createBy", getCreateBy()) .append("createBy", getCreateBy())
.append("createTime", getCreateTime()) .append("createTime", getCreateTime())
.append("updateBy", getUpdateBy()) .append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime()) .append("updateTime", getUpdateTime())
.toString(); .toString();
} }
} }
@@ -1,176 +1,176 @@
package com.ruoyi.common.core.domain.entity; package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.Size; import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType; import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
/** /**
* 字典数据表 sys_dict_data * 字典数据表 sys_dict_data
* *
* @author ruoyi * @author ruoyi
*/ */
public class SysDictData extends BaseEntity public class SysDictData extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 字典编码 */ /** 字典编码 */
@Excel(name = "字典编码", cellType = ColumnType.NUMERIC) @Excel(name = "字典编码", cellType = ColumnType.NUMERIC)
private Long dictCode; private Long dictCode;
/** 字典排序 */ /** 字典排序 */
@Excel(name = "字典排序", cellType = ColumnType.NUMERIC) @Excel(name = "字典排序", cellType = ColumnType.NUMERIC)
private Long dictSort; private Long dictSort;
/** 字典标签 */ /** 字典标签 */
@Excel(name = "字典标签") @Excel(name = "字典标签")
private String dictLabel; private String dictLabel;
/** 字典键值 */ /** 字典键值 */
@Excel(name = "字典键值") @Excel(name = "字典键值")
private String dictValue; private String dictValue;
/** 字典类型 */ /** 字典类型 */
@Excel(name = "字典类型") @Excel(name = "字典类型")
private String dictType; private String dictType;
/** 样式属性(其他样式扩展) */ /** 样式属性(其他样式扩展) */
private String cssClass; private String cssClass;
/** 表格字典样式 */ /** 表格字典样式 */
private String listClass; private String listClass;
/** 是否默认(Y是 N否) */ /** 是否默认(Y是 N否) */
@Excel(name = "是否默认", readConverterExp = "Y=是,N=否") @Excel(name = "是否默认", readConverterExp = "Y=是,N=否")
private String isDefault; private String isDefault;
/** 状态(0正常 1停用) */ /** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用") @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status; private String status;
public Long getDictCode() public Long getDictCode()
{ {
return dictCode; return dictCode;
} }
public void setDictCode(Long dictCode) public void setDictCode(Long dictCode)
{ {
this.dictCode = dictCode; this.dictCode = dictCode;
} }
public Long getDictSort() public Long getDictSort()
{ {
return dictSort; return dictSort;
} }
public void setDictSort(Long dictSort) public void setDictSort(Long dictSort)
{ {
this.dictSort = dictSort; this.dictSort = dictSort;
} }
@NotBlank(message = "字典标签不能为空") @NotBlank(message = "字典标签不能为空")
@Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符") @Size(min = 0, max = 100, message = "字典标签长度不能超过100个字符")
public String getDictLabel() public String getDictLabel()
{ {
return dictLabel; return dictLabel;
} }
public void setDictLabel(String dictLabel) public void setDictLabel(String dictLabel)
{ {
this.dictLabel = dictLabel; this.dictLabel = dictLabel;
} }
@NotBlank(message = "字典键值不能为空") @NotBlank(message = "字典键值不能为空")
@Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符") @Size(min = 0, max = 100, message = "字典键值长度不能超过100个字符")
public String getDictValue() public String getDictValue()
{ {
return dictValue; return dictValue;
} }
public void setDictValue(String dictValue) public void setDictValue(String dictValue)
{ {
this.dictValue = dictValue; this.dictValue = dictValue;
} }
@NotBlank(message = "字典类型不能为空") @NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符") @Size(min = 0, max = 100, message = "字典类型长度不能超过100个字符")
public String getDictType() public String getDictType()
{ {
return dictType; return dictType;
} }
public void setDictType(String dictType) public void setDictType(String dictType)
{ {
this.dictType = dictType; this.dictType = dictType;
} }
@Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符") @Size(min = 0, max = 100, message = "样式属性长度不能超过100个字符")
public String getCssClass() public String getCssClass()
{ {
return cssClass; return cssClass;
} }
public void setCssClass(String cssClass) public void setCssClass(String cssClass)
{ {
this.cssClass = cssClass; this.cssClass = cssClass;
} }
public String getListClass() public String getListClass()
{ {
return listClass; return listClass;
} }
public void setListClass(String listClass) public void setListClass(String listClass)
{ {
this.listClass = listClass; this.listClass = listClass;
} }
public boolean getDefault() public boolean getDefault()
{ {
return UserConstants.YES.equals(this.isDefault); return UserConstants.YES.equals(this.isDefault);
} }
public String getIsDefault() public String getIsDefault()
{ {
return isDefault; return isDefault;
} }
public void setIsDefault(String isDefault) public void setIsDefault(String isDefault)
{ {
this.isDefault = isDefault; this.isDefault = isDefault;
} }
public String getStatus() public String getStatus()
{ {
return status; return status;
} }
public void setStatus(String status) public void setStatus(String status)
{ {
this.status = status; this.status = status;
} }
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictCode", getDictCode()) .append("dictCode", getDictCode())
.append("dictSort", getDictSort()) .append("dictSort", getDictSort())
.append("dictLabel", getDictLabel()) .append("dictLabel", getDictLabel())
.append("dictValue", getDictValue()) .append("dictValue", getDictValue())
.append("dictType", getDictType()) .append("dictType", getDictType())
.append("cssClass", getCssClass()) .append("cssClass", getCssClass())
.append("listClass", getListClass()) .append("listClass", getListClass())
.append("isDefault", getIsDefault()) .append("isDefault", getIsDefault())
.append("status", getStatus()) .append("status", getStatus())
.append("createBy", getCreateBy()) .append("createBy", getCreateBy())
.append("createTime", getCreateTime()) .append("createTime", getCreateTime())
.append("updateBy", getUpdateBy()) .append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime()) .append("updateTime", getUpdateTime())
.append("remark", getRemark()) .append("remark", getRemark())
.toString(); .toString();
} }
} }
@@ -1,96 +1,96 @@
package com.ruoyi.common.core.domain.entity; package com.ruoyi.common.core.domain.entity;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.Pattern; import jakarta.validation.constraints.Pattern;
import javax.validation.constraints.Size; import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType; import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
/** /**
* 字典类型表 sys_dict_type * 字典类型表 sys_dict_type
* *
* @author ruoyi * @author ruoyi
*/ */
public class SysDictType extends BaseEntity public class SysDictType extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 字典主键 */ /** 字典主键 */
@Excel(name = "字典主键", cellType = ColumnType.NUMERIC) @Excel(name = "字典主键", cellType = ColumnType.NUMERIC)
private Long dictId; private Long dictId;
/** 字典名称 */ /** 字典名称 */
@Excel(name = "字典名称") @Excel(name = "字典名称")
private String dictName; private String dictName;
/** 字典类型 */ /** 字典类型 */
@Excel(name = "字典类型") @Excel(name = "字典类型")
private String dictType; private String dictType;
/** 状态(0正常 1停用) */ /** 状态(0正常 1停用) */
@Excel(name = "状态", readConverterExp = "0=正常,1=停用") @Excel(name = "状态", readConverterExp = "0=正常,1=停用")
private String status; private String status;
public Long getDictId() public Long getDictId()
{ {
return dictId; return dictId;
} }
public void setDictId(Long dictId) public void setDictId(Long dictId)
{ {
this.dictId = dictId; this.dictId = dictId;
} }
@NotBlank(message = "字典名称不能为空") @NotBlank(message = "字典名称不能为空")
@Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符") @Size(min = 0, max = 100, message = "字典类型名称长度不能超过100个字符")
public String getDictName() public String getDictName()
{ {
return dictName; return dictName;
} }
public void setDictName(String dictName) public void setDictName(String dictName)
{ {
this.dictName = dictName; this.dictName = dictName;
} }
@NotBlank(message = "字典类型不能为空") @NotBlank(message = "字典类型不能为空")
@Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符") @Size(min = 0, max = 100, message = "字典类型类型长度不能超过100个字符")
@Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)") @Pattern(regexp = "^[a-z][a-z0-9_]*$", message = "字典类型必须以字母开头,且只能为(小写字母,数字,下滑线)")
public String getDictType() public String getDictType()
{ {
return dictType; return dictType;
} }
public void setDictType(String dictType) public void setDictType(String dictType)
{ {
this.dictType = dictType; this.dictType = dictType;
} }
public String getStatus() public String getStatus()
{ {
return status; return status;
} }
public void setStatus(String status) public void setStatus(String status)
{ {
this.status = status; this.status = status;
} }
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("dictId", getDictId()) .append("dictId", getDictId())
.append("dictName", getDictName()) .append("dictName", getDictName())
.append("dictType", getDictType()) .append("dictType", getDictType())
.append("status", getStatus()) .append("status", getStatus())
.append("createBy", getCreateBy()) .append("createBy", getCreateBy())
.append("createTime", getCreateTime()) .append("createTime", getCreateTime())
.append("updateBy", getUpdateBy()) .append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime()) .append("updateTime", getUpdateTime())
.append("remark", getRemark()) .append("remark", getRemark())
.toString(); .toString();
} }
} }
@@ -1,274 +1,274 @@
package com.ruoyi.common.core.domain.entity; package com.ruoyi.common.core.domain.entity;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import javax.validation.constraints.Size; import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
/** /**
* 菜单权限表 sys_menu * 菜单权限表 sys_menu
* *
* @author ruoyi * @author ruoyi
*/ */
public class SysMenu extends BaseEntity public class SysMenu extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 菜单ID */ /** 菜单ID */
private Long menuId; private Long menuId;
/** 菜单名称 */ /** 菜单名称 */
private String menuName; private String menuName;
/** 父菜单名称 */ /** 父菜单名称 */
private String parentName; private String parentName;
/** 父菜单ID */ /** 父菜单ID */
private Long parentId; private Long parentId;
/** 显示顺序 */ /** 显示顺序 */
private Integer orderNum; private Integer orderNum;
/** 路由地址 */ /** 路由地址 */
private String path; private String path;
/** 组件路径 */ /** 组件路径 */
private String component; private String component;
/** 路由参数 */ /** 路由参数 */
private String query; private String query;
/** 路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义) */ /** 路由名称,默认和路由地址相同的驼峰格式(注意:因为vue3版本的router会删除名称相同路由,为避免名字的冲突,特殊情况可以自定义) */
private String routeName; private String routeName;
/** 是否为外链(0是 1否) */ /** 是否为外链(0是 1否) */
private String isFrame; private String isFrame;
/** 是否缓存(0缓存 1不缓存) */ /** 是否缓存(0缓存 1不缓存) */
private String isCache; private String isCache;
/** 类型(M目录 C菜单 F按钮) */ /** 类型(M目录 C菜单 F按钮) */
private String menuType; private String menuType;
/** 显示状态(0显示 1隐藏) */ /** 显示状态(0显示 1隐藏) */
private String visible; private String visible;
/** 菜单状态(0正常 1停用) */ /** 菜单状态(0正常 1停用) */
private String status; private String status;
/** 权限字符串 */ /** 权限字符串 */
private String perms; private String perms;
/** 菜单图标 */ /** 菜单图标 */
private String icon; private String icon;
/** 子菜单 */ /** 子菜单 */
private List<SysMenu> children = new ArrayList<SysMenu>(); private List<SysMenu> children = new ArrayList<SysMenu>();
public Long getMenuId() public Long getMenuId()
{ {
return menuId; return menuId;
} }
public void setMenuId(Long menuId) public void setMenuId(Long menuId)
{ {
this.menuId = menuId; this.menuId = menuId;
} }
@NotBlank(message = "菜单名称不能为空") @NotBlank(message = "菜单名称不能为空")
@Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符") @Size(min = 0, max = 50, message = "菜单名称长度不能超过50个字符")
public String getMenuName() public String getMenuName()
{ {
return menuName; return menuName;
} }
public void setMenuName(String menuName) public void setMenuName(String menuName)
{ {
this.menuName = menuName; this.menuName = menuName;
} }
public String getParentName() public String getParentName()
{ {
return parentName; return parentName;
} }
public void setParentName(String parentName) public void setParentName(String parentName)
{ {
this.parentName = parentName; this.parentName = parentName;
} }
public Long getParentId() public Long getParentId()
{ {
return parentId; return parentId;
} }
public void setParentId(Long parentId) public void setParentId(Long parentId)
{ {
this.parentId = parentId; this.parentId = parentId;
} }
@NotNull(message = "显示顺序不能为空") @NotNull(message = "显示顺序不能为空")
public Integer getOrderNum() public Integer getOrderNum()
{ {
return orderNum; return orderNum;
} }
public void setOrderNum(Integer orderNum) public void setOrderNum(Integer orderNum)
{ {
this.orderNum = orderNum; this.orderNum = orderNum;
} }
@Size(min = 0, max = 200, message = "路由地址不能超过200个字符") @Size(min = 0, max = 200, message = "路由地址不能超过200个字符")
public String getPath() public String getPath()
{ {
return path; return path;
} }
public void setPath(String path) public void setPath(String path)
{ {
this.path = path; this.path = path;
} }
@Size(min = 0, max = 200, message = "组件路径不能超过255个字符") @Size(min = 0, max = 200, message = "组件路径不能超过255个字符")
public String getComponent() public String getComponent()
{ {
return component; return component;
} }
public void setComponent(String component) public void setComponent(String component)
{ {
this.component = component; this.component = component;
} }
public String getQuery() public String getQuery()
{ {
return query; return query;
} }
public void setQuery(String query) public void setQuery(String query)
{ {
this.query = query; this.query = query;
} }
public String getRouteName() public String getRouteName()
{ {
return routeName; return routeName;
} }
public void setRouteName(String routeName) public void setRouteName(String routeName)
{ {
this.routeName = routeName; this.routeName = routeName;
} }
public String getIsFrame() public String getIsFrame()
{ {
return isFrame; return isFrame;
} }
public void setIsFrame(String isFrame) public void setIsFrame(String isFrame)
{ {
this.isFrame = isFrame; this.isFrame = isFrame;
} }
public String getIsCache() public String getIsCache()
{ {
return isCache; return isCache;
} }
public void setIsCache(String isCache) public void setIsCache(String isCache)
{ {
this.isCache = isCache; this.isCache = isCache;
} }
@NotBlank(message = "菜单类型不能为空") @NotBlank(message = "菜单类型不能为空")
public String getMenuType() public String getMenuType()
{ {
return menuType; return menuType;
} }
public void setMenuType(String menuType) public void setMenuType(String menuType)
{ {
this.menuType = menuType; this.menuType = menuType;
} }
public String getVisible() public String getVisible()
{ {
return visible; return visible;
} }
public void setVisible(String visible) public void setVisible(String visible)
{ {
this.visible = visible; this.visible = visible;
} }
public String getStatus() public String getStatus()
{ {
return status; return status;
} }
public void setStatus(String status) public void setStatus(String status)
{ {
this.status = status; this.status = status;
} }
@Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符") @Size(min = 0, max = 100, message = "权限标识长度不能超过100个字符")
public String getPerms() public String getPerms()
{ {
return perms; return perms;
} }
public void setPerms(String perms) public void setPerms(String perms)
{ {
this.perms = perms; this.perms = perms;
} }
public String getIcon() public String getIcon()
{ {
return icon; return icon;
} }
public void setIcon(String icon) public void setIcon(String icon)
{ {
this.icon = icon; this.icon = icon;
} }
public List<SysMenu> getChildren() public List<SysMenu> getChildren()
{ {
return children; return children;
} }
public void setChildren(List<SysMenu> children) public void setChildren(List<SysMenu> children)
{ {
this.children = children; this.children = children;
} }
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("menuId", getMenuId()) .append("menuId", getMenuId())
.append("menuName", getMenuName()) .append("menuName", getMenuName())
.append("parentId", getParentId()) .append("parentId", getParentId())
.append("orderNum", getOrderNum()) .append("orderNum", getOrderNum())
.append("path", getPath()) .append("path", getPath())
.append("component", getComponent()) .append("component", getComponent())
.append("query", getQuery()) .append("query", getQuery())
.append("routeName", getRouteName()) .append("routeName", getRouteName())
.append("isFrame", getIsFrame()) .append("isFrame", getIsFrame())
.append("IsCache", getIsCache()) .append("IsCache", getIsCache())
.append("menuType", getMenuType()) .append("menuType", getMenuType())
.append("visible", getVisible()) .append("visible", getVisible())
.append("status ", getStatus()) .append("status ", getStatus())
.append("perms", getPerms()) .append("perms", getPerms())
.append("icon", getIcon()) .append("icon", getIcon())
.append("createBy", getCreateBy()) .append("createBy", getCreateBy())
.append("createTime", getCreateTime()) .append("createTime", getCreateTime())
.append("updateBy", getUpdateBy()) .append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime()) .append("updateTime", getUpdateTime())
.append("remark", getRemark()) .append("remark", getRemark())
.toString(); .toString();
} }
} }
@@ -1,241 +1,241 @@
package com.ruoyi.common.core.domain.entity; package com.ruoyi.common.core.domain.entity;
import java.util.Set; import java.util.Set;
import javax.validation.constraints.NotBlank; import jakarta.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import javax.validation.constraints.Size; import jakarta.validation.constraints.Size;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.ruoyi.common.annotation.Excel; import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.ColumnType; import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.core.domain.BaseEntity;
/** /**
* 角色表 sys_role * 角色表 sys_role
* *
* @author ruoyi * @author ruoyi
*/ */
public class SysRole extends BaseEntity public class SysRole extends BaseEntity
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 角色ID */ /** 角色ID */
@Excel(name = "角色序号", cellType = ColumnType.NUMERIC) @Excel(name = "角色序号", cellType = ColumnType.NUMERIC)
private Long roleId; private Long roleId;
/** 角色名称 */ /** 角色名称 */
@Excel(name = "角色名称") @Excel(name = "角色名称")
private String roleName; private String roleName;
/** 角色权限 */ /** 角色权限 */
@Excel(name = "角色权限") @Excel(name = "角色权限")
private String roleKey; private String roleKey;
/** 角色排序 */ /** 角色排序 */
@Excel(name = "角色排序") @Excel(name = "角色排序")
private Integer roleSort; private Integer roleSort;
/** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */ /** 数据范围(1:所有数据权限;2:自定义数据权限;3:本部门数据权限;4:本部门及以下数据权限;5:仅本人数据权限) */
@Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限") @Excel(name = "数据范围", readConverterExp = "1=所有数据权限,2=自定义数据权限,3=本部门数据权限,4=本部门及以下数据权限,5=仅本人数据权限")
private String dataScope; private String dataScope;
/** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */ /** 菜单树选择项是否关联显示( 0:父子不互相关联显示 1:父子互相关联显示) */
private boolean menuCheckStrictly; private boolean menuCheckStrictly;
/** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */ /** 部门树选择项是否关联显示(0:父子不互相关联显示 1:父子互相关联显示 ) */
private boolean deptCheckStrictly; private boolean deptCheckStrictly;
/** 角色状态(0正常 1停用) */ /** 角色状态(0正常 1停用) */
@Excel(name = "角色状态", readConverterExp = "0=正常,1=停用") @Excel(name = "角色状态", readConverterExp = "0=正常,1=停用")
private String status; private String status;
/** 删除标志(0代表存在 2代表删除) */ /** 删除标志(0代表存在 2代表删除) */
private String delFlag; private String delFlag;
/** 用户是否存在此角色标识 默认不存在 */ /** 用户是否存在此角色标识 默认不存在 */
private boolean flag = false; private boolean flag = false;
/** 菜单组 */ /** 菜单组 */
private Long[] menuIds; private Long[] menuIds;
/** 部门组(数据权限) */ /** 部门组(数据权限) */
private Long[] deptIds; private Long[] deptIds;
/** 角色菜单权限 */ /** 角色菜单权限 */
private Set<String> permissions; private Set<String> permissions;
public SysRole() public SysRole()
{ {
} }
public SysRole(Long roleId) public SysRole(Long roleId)
{ {
this.roleId = roleId; this.roleId = roleId;
} }
public Long getRoleId() public Long getRoleId()
{ {
return roleId; return roleId;
} }
public void setRoleId(Long roleId) public void setRoleId(Long roleId)
{ {
this.roleId = roleId; this.roleId = roleId;
} }
public boolean isAdmin() public boolean isAdmin()
{ {
return isAdmin(this.roleId); return isAdmin(this.roleId);
} }
public static boolean isAdmin(Long roleId) public static boolean isAdmin(Long roleId)
{ {
return roleId != null && 1L == roleId; return roleId != null && 1L == roleId;
} }
@NotBlank(message = "角色名称不能为空") @NotBlank(message = "角色名称不能为空")
@Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符") @Size(min = 0, max = 30, message = "角色名称长度不能超过30个字符")
public String getRoleName() public String getRoleName()
{ {
return roleName; return roleName;
} }
public void setRoleName(String roleName) public void setRoleName(String roleName)
{ {
this.roleName = roleName; this.roleName = roleName;
} }
@NotBlank(message = "权限字符不能为空") @NotBlank(message = "权限字符不能为空")
@Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符") @Size(min = 0, max = 100, message = "权限字符长度不能超过100个字符")
public String getRoleKey() public String getRoleKey()
{ {
return roleKey; return roleKey;
} }
public void setRoleKey(String roleKey) public void setRoleKey(String roleKey)
{ {
this.roleKey = roleKey; this.roleKey = roleKey;
} }
@NotNull(message = "显示顺序不能为空") @NotNull(message = "显示顺序不能为空")
public Integer getRoleSort() public Integer getRoleSort()
{ {
return roleSort; return roleSort;
} }
public void setRoleSort(Integer roleSort) public void setRoleSort(Integer roleSort)
{ {
this.roleSort = roleSort; this.roleSort = roleSort;
} }
public String getDataScope() public String getDataScope()
{ {
return dataScope; return dataScope;
} }
public void setDataScope(String dataScope) public void setDataScope(String dataScope)
{ {
this.dataScope = dataScope; this.dataScope = dataScope;
} }
public boolean isMenuCheckStrictly() public boolean isMenuCheckStrictly()
{ {
return menuCheckStrictly; return menuCheckStrictly;
} }
public void setMenuCheckStrictly(boolean menuCheckStrictly) public void setMenuCheckStrictly(boolean menuCheckStrictly)
{ {
this.menuCheckStrictly = menuCheckStrictly; this.menuCheckStrictly = menuCheckStrictly;
} }
public boolean isDeptCheckStrictly() public boolean isDeptCheckStrictly()
{ {
return deptCheckStrictly; return deptCheckStrictly;
} }
public void setDeptCheckStrictly(boolean deptCheckStrictly) public void setDeptCheckStrictly(boolean deptCheckStrictly)
{ {
this.deptCheckStrictly = deptCheckStrictly; this.deptCheckStrictly = deptCheckStrictly;
} }
public String getStatus() public String getStatus()
{ {
return status; return status;
} }
public void setStatus(String status) public void setStatus(String status)
{ {
this.status = status; this.status = status;
} }
public String getDelFlag() public String getDelFlag()
{ {
return delFlag; return delFlag;
} }
public void setDelFlag(String delFlag) public void setDelFlag(String delFlag)
{ {
this.delFlag = delFlag; this.delFlag = delFlag;
} }
public boolean isFlag() public boolean isFlag()
{ {
return flag; return flag;
} }
public void setFlag(boolean flag) public void setFlag(boolean flag)
{ {
this.flag = flag; this.flag = flag;
} }
public Long[] getMenuIds() public Long[] getMenuIds()
{ {
return menuIds; return menuIds;
} }
public void setMenuIds(Long[] menuIds) public void setMenuIds(Long[] menuIds)
{ {
this.menuIds = menuIds; this.menuIds = menuIds;
} }
public Long[] getDeptIds() public Long[] getDeptIds()
{ {
return deptIds; return deptIds;
} }
public void setDeptIds(Long[] deptIds) public void setDeptIds(Long[] deptIds)
{ {
this.deptIds = deptIds; this.deptIds = deptIds;
} }
public Set<String> getPermissions() public Set<String> getPermissions()
{ {
return permissions; return permissions;
} }
public void setPermissions(Set<String> permissions) public void setPermissions(Set<String> permissions)
{ {
this.permissions = permissions; this.permissions = permissions;
} }
@Override @Override
public String toString() { public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("roleId", getRoleId()) .append("roleId", getRoleId())
.append("roleName", getRoleName()) .append("roleName", getRoleName())
.append("roleKey", getRoleKey()) .append("roleKey", getRoleKey())
.append("roleSort", getRoleSort()) .append("roleSort", getRoleSort())
.append("dataScope", getDataScope()) .append("dataScope", getDataScope())
.append("menuCheckStrictly", isMenuCheckStrictly()) .append("menuCheckStrictly", isMenuCheckStrictly())
.append("deptCheckStrictly", isDeptCheckStrictly()) .append("deptCheckStrictly", isDeptCheckStrictly())
.append("status", getStatus()) .append("status", getStatus())
.append("delFlag", getDelFlag()) .append("delFlag", getDelFlag())
.append("createBy", getCreateBy()) .append("createBy", getCreateBy())
.append("createTime", getCreateTime()) .append("createTime", getCreateTime())
.append("updateBy", getUpdateBy()) .append("updateBy", getUpdateBy())
.append("updateTime", getUpdateTime()) .append("updateTime", getUpdateTime())
.append("remark", getRemark()) .append("remark", getRemark())
.toString(); .toString();
} }
} }
@@ -1,336 +1,338 @@
package com.ruoyi.common.core.domain.entity; package com.ruoyi.common.core.domain.entity;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import javax.validation.constraints.*; import jakarta.validation.constraints.*;
import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.builder.ToStringStyle;
import com.fasterxml.jackson.annotation.JsonProperty; import com.fasterxml.jackson.annotation.JsonFormat;
import com.ruoyi.common.annotation.Excel; import com.fasterxml.jackson.annotation.JsonProperty;
import com.ruoyi.common.annotation.Excel.ColumnType; import com.ruoyi.common.annotation.Excel;
import com.ruoyi.common.annotation.Excel.Type; import com.ruoyi.common.annotation.Excel.ColumnType;
import com.ruoyi.common.annotation.Excels; import com.ruoyi.common.annotation.Excel.Type;
import com.ruoyi.common.core.domain.BaseEntity; import com.ruoyi.common.annotation.Excels;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.core.domain.BaseEntity;
import com.ruoyi.common.xss.Xss; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.xss.Xss;
/**
* 用户对象 sys_user /**
* * 用户对象 sys_user
* @author ruoyi *
*/ * @author ruoyi
public class SysUser extends BaseEntity */
{ public class SysUser extends BaseEntity
private static final long serialVersionUID = 1L; {
private static final long serialVersionUID = 1L;
/** 用户ID */
@Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号") /** 用户ID */
private Long userId; @Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号")
private Long userId;
/** 部门ID */
@Excel(name = "部门编号", type = Type.IMPORT) /** 部门ID */
private Long deptId; @Excel(name = "部门编号", type = Type.IMPORT)
private Long deptId;
/** 用户账号 */
@Excel(name = "登录名称") /** 用户账号 */
private String userName; @Excel(name = "登录名称")
private String userName;
/** 用户昵称 */
@Excel(name = "用户名称") /** 用户昵称 */
private String nickName; @Excel(name = "用户名称")
private String nickName;
/** 用户邮箱 */
@Excel(name = "用户邮箱") /** 用户邮箱 */
private String email; @Excel(name = "用户邮箱")
private String email;
/** 手机号码 */
@Excel(name = "手机号码", cellType = ColumnType.TEXT) /** 手机号码 */
private String phonenumber; @Excel(name = "手机号码", cellType = ColumnType.TEXT)
private String phonenumber;
/** 用户性别 */
@Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知") /** 用户性别 */
private String sex; @Excel(name = "用户性别", readConverterExp = "0=男,1=女,2=未知")
private String sex;
/** 用户头像 */
private String avatar; /** 用户头像 */
private String avatar;
/** 密码 */
private String password; /** 密码 */
private String password;
/** 账号状态(0正常 1停用) */
@Excel(name = "账号状态", readConverterExp = "0=正常,1=停用") /** 账号状态(0正常 1停用) */
private String status; @Excel(name = "账号状态", readConverterExp = "0=正常,1=停用")
private String status;
/** 删除标志(0代表存在 2代表删除) */
private String delFlag; /** 删除标志(0代表存在 2代表删除) */
private String delFlag;
/** 最后登录IP */
@Excel(name = "最后登录IP", type = Type.EXPORT) /** 最后登录IP */
private String loginIp; @Excel(name = "最后登录IP", type = Type.EXPORT)
private String loginIp;
/** 最后登录时间 */
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT) /** 最后登录时间 */
private Date loginDate; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Excel(name = "最后登录时间", width = 30, dateFormat = "yyyy-MM-dd HH:mm:ss", type = Type.EXPORT)
/** 密码最后更新时间 */ private Date loginDate;
private Date pwdUpdateDate;
/** 密码最后更新时间 */
/** 部门对象 */ private Date pwdUpdateDate;
@Excels({
@Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT), /** 部门对象 */
@Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT) @Excels({
}) @Excel(name = "部门名称", targetAttr = "deptName", type = Type.EXPORT),
private SysDept dept; @Excel(name = "部门负责人", targetAttr = "leader", type = Type.EXPORT)
})
/** 角色对象 */ private SysDept dept;
private List<SysRole> roles;
/** 角色对象 */
/** 角色组 */ private List<SysRole> roles;
private Long[] roleIds;
/** 角色组 */
/** 岗位组 */ private Long[] roleIds;
private Long[] postIds;
/** 岗位组 */
/** 角色ID */ private Long[] postIds;
private Long roleId;
/** 角色ID */
public SysUser() private Long roleId;
{
public SysUser()
} {
public SysUser(Long userId) }
{
this.userId = userId; public SysUser(Long userId)
} {
this.userId = userId;
public Long getUserId() }
{
return userId; public Long getUserId()
} {
return userId;
public void setUserId(Long userId) }
{
this.userId = userId; public void setUserId(Long userId)
} {
this.userId = userId;
public boolean isAdmin() }
{
return SecurityUtils.isAdmin(this.userId); public boolean isAdmin()
} {
return SecurityUtils.isAdmin(this.userId);
public Long getDeptId() }
{
return deptId; public Long getDeptId()
} {
return deptId;
public void setDeptId(Long deptId) }
{
this.deptId = deptId; public void setDeptId(Long deptId)
} {
this.deptId = deptId;
@Xss(message = "用户昵称不能包含脚本字符") }
@Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
public String getNickName() @Xss(message = "用户昵称不能包含脚本字符")
{ @Size(min = 0, max = 30, message = "用户昵称长度不能超过30个字符")
return nickName; public String getNickName()
} {
return nickName;
public void setNickName(String nickName) }
{
this.nickName = nickName; public void setNickName(String nickName)
} {
this.nickName = nickName;
@Xss(message = "用户账号不能包含脚本字符") }
@NotBlank(message = "用户账号不能为空")
@Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符") @Xss(message = "用户账号不能包含脚本字符")
public String getUserName() @NotBlank(message = "用户账号不能为空")
{ @Size(min = 0, max = 30, message = "用户账号长度不能超过30个字符")
return userName; public String getUserName()
} {
return userName;
public void setUserName(String userName) }
{
this.userName = userName; public void setUserName(String userName)
} {
this.userName = userName;
@Email(message = "邮箱格式不正确") }
@Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
public String getEmail() @Email(message = "邮箱格式不正确")
{ @Size(min = 0, max = 50, message = "邮箱长度不能超过50个字符")
return email; public String getEmail()
} {
return email;
public void setEmail(String email) }
{
this.email = email; public void setEmail(String email)
} {
this.email = email;
@Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符") }
public String getPhonenumber()
{ @Size(min = 0, max = 11, message = "手机号码长度不能超过11个字符")
return phonenumber; public String getPhonenumber()
} {
return phonenumber;
public void setPhonenumber(String phonenumber) }
{
this.phonenumber = phonenumber; public void setPhonenumber(String phonenumber)
} {
this.phonenumber = phonenumber;
public String getSex() }
{
return sex; public String getSex()
} {
return sex;
public void setSex(String sex) }
{
this.sex = sex; public void setSex(String sex)
} {
this.sex = sex;
public String getAvatar() }
{
return avatar; public String getAvatar()
} {
return avatar;
public void setAvatar(String avatar) }
{
this.avatar = avatar; public void setAvatar(String avatar)
} {
this.avatar = avatar;
@JsonProperty(access = JsonProperty.Access.WRITE_ONLY) }
public String getPassword()
{ @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
return password; public String getPassword()
} {
return password;
public void setPassword(String password) }
{
this.password = password; public void setPassword(String password)
} {
this.password = password;
public String getStatus() }
{
return status; public String getStatus()
} {
return status;
public void setStatus(String status) }
{
this.status = status; public void setStatus(String status)
} {
this.status = status;
public String getDelFlag() }
{
return delFlag; public String getDelFlag()
} {
return delFlag;
public void setDelFlag(String delFlag) }
{
this.delFlag = delFlag; public void setDelFlag(String delFlag)
} {
this.delFlag = delFlag;
public String getLoginIp() }
{
return loginIp; public String getLoginIp()
} {
return loginIp;
public void setLoginIp(String loginIp) }
{
this.loginIp = loginIp; public void setLoginIp(String loginIp)
} {
this.loginIp = loginIp;
public Date getLoginDate() }
{
return loginDate; public Date getLoginDate()
} {
return loginDate;
public void setLoginDate(Date loginDate) }
{
this.loginDate = loginDate; public void setLoginDate(Date loginDate)
} {
this.loginDate = loginDate;
public Date getPwdUpdateDate() }
{
return pwdUpdateDate; public Date getPwdUpdateDate()
} {
return pwdUpdateDate;
public void setPwdUpdateDate(Date pwdUpdateDate) }
{
this.pwdUpdateDate = pwdUpdateDate; public void setPwdUpdateDate(Date pwdUpdateDate)
} {
this.pwdUpdateDate = pwdUpdateDate;
public SysDept getDept() }
{
return dept; public SysDept getDept()
} {
return dept;
public void setDept(SysDept dept) }
{
this.dept = dept; public void setDept(SysDept dept)
} {
this.dept = dept;
public List<SysRole> getRoles() }
{
return roles; public List<SysRole> getRoles()
} {
return roles;
public void setRoles(List<SysRole> roles) }
{
this.roles = roles; public void setRoles(List<SysRole> roles)
} {
this.roles = roles;
public Long[] getRoleIds() }
{
return roleIds; public Long[] getRoleIds()
} {
return roleIds;
public void setRoleIds(Long[] roleIds) }
{
this.roleIds = roleIds; public void setRoleIds(Long[] roleIds)
} {
this.roleIds = roleIds;
public Long[] getPostIds() }
{
return postIds; public Long[] getPostIds()
} {
return postIds;
public void setPostIds(Long[] postIds) }
{
this.postIds = postIds; public void setPostIds(Long[] postIds)
} {
this.postIds = postIds;
public Long getRoleId() }
{
return roleId; public Long getRoleId()
} {
return roleId;
public void setRoleId(Long roleId) }
{
this.roleId = roleId; public void setRoleId(Long roleId)
} {
this.roleId = roleId;
@Override }
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) @Override
.append("userId", getUserId()) public String toString() {
.append("deptId", getDeptId()) return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("userName", getUserName()) .append("userId", getUserId())
.append("nickName", getNickName()) .append("deptId", getDeptId())
.append("email", getEmail()) .append("userName", getUserName())
.append("phonenumber", getPhonenumber()) .append("nickName", getNickName())
.append("sex", getSex()) .append("email", getEmail())
.append("avatar", getAvatar()) .append("phonenumber", getPhonenumber())
.append("password", getPassword()) .append("sex", getSex())
.append("status", getStatus()) .append("avatar", getAvatar())
.append("delFlag", getDelFlag()) .append("password", getPassword())
.append("loginIp", getLoginIp()) .append("status", getStatus())
.append("loginDate", getLoginDate()) .append("delFlag", getDelFlag())
.append("pwdUpdateDate", getPwdUpdateDate()) .append("loginIp", getLoginIp())
.append("createBy", getCreateBy()) .append("loginDate", getLoginDate())
.append("createTime", getCreateTime()) .append("pwdUpdateDate", getPwdUpdateDate())
.append("updateBy", getUpdateBy()) .append("createBy", getCreateBy())
.append("updateTime", getUpdateTime()) .append("createTime", getCreateTime())
.append("remark", getRemark()) .append("updateBy", getUpdateBy())
.append("dept", getDept()) .append("updateTime", getUpdateTime())
.toString(); .append("remark", getRemark())
} .append("dept", getDept())
} .toString();
}
}
@@ -1,69 +1,69 @@
package com.ruoyi.common.core.domain.model; package com.ruoyi.common.core.domain.model;
/** /**
* 用户登录对象 * 用户登录对象
* *
* @author ruoyi * @author ruoyi
*/ */
public class LoginBody public class LoginBody
{ {
/** /**
* 用户名 * 用户名
*/ */
private String username; private String username;
/** /**
* 用户密码 * 用户密码
*/ */
private String password; private String password;
/** /**
* 验证码 * 验证码
*/ */
private String code; private String code;
/** /**
* 唯一标识 * 唯一标识
*/ */
private String uuid; private String uuid;
public String getUsername() public String getUsername()
{ {
return username; return username;
} }
public void setUsername(String username) public void setUsername(String username)
{ {
this.username = username; this.username = username;
} }
public String getPassword() public String getPassword()
{ {
return password; return password;
} }
public void setPassword(String password) public void setPassword(String password)
{ {
this.password = password; this.password = password;
} }
public String getCode() public String getCode()
{ {
return code; return code;
} }
public void setCode(String code) public void setCode(String code)
{ {
this.code = code; this.code = code;
} }
public String getUuid() public String getUuid()
{ {
return uuid; return uuid;
} }
public void setUuid(String uuid) public void setUuid(String uuid)
{ {
this.uuid = uuid; this.uuid = uuid;
} }
} }
@@ -1,266 +1,278 @@
package com.ruoyi.common.core.domain.model; package com.ruoyi.common.core.domain.model;
import com.alibaba.fastjson2.annotation.JSONField; import java.util.Collection;
import com.ruoyi.common.core.domain.entity.SysUser; import java.util.Collections;
import org.springframework.security.core.GrantedAuthority; import java.util.Objects;
import org.springframework.security.core.userdetails.UserDetails; import java.util.Set;
import java.util.Collection; import java.util.stream.Collectors;
import java.util.Set; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
/** import org.springframework.security.core.userdetails.UserDetails;
* 登录用户身份权限 import com.alibaba.fastjson2.annotation.JSONField;
* import com.ruoyi.common.core.domain.entity.SysUser;
* @author ruoyi
*/ /**
public class LoginUser implements UserDetails * 登录用户身份权限
{ *
private static final long serialVersionUID = 1L; * @author ruoyi
*/
/** public class LoginUser implements UserDetails
* 用户ID {
*/ private static final long serialVersionUID = 1L;
private Long userId;
/**
/** * 用户ID
* 部门ID */
*/ private Long userId;
private Long deptId;
/**
/** * 部门ID
* 用户唯一标识 */
*/ private Long deptId;
private String token;
/**
/** * 用户唯一标识
* 登录时间 */
*/ private String token;
private Long loginTime;
/**
/** * 登录时间
* 过期时间 */
*/ private Long loginTime;
private Long expireTime;
/**
/** * 过期时间
* 登录IP地址 */
*/ private Long expireTime;
private String ipaddr;
/**
/** * 登录IP地址
* 登录地点 */
*/ private String ipaddr;
private String loginLocation;
/**
/** * 登录地点
* 浏览器类型 */
*/ private String loginLocation;
private String browser;
/**
/** * 浏览器类型
* 操作系统 */
*/ private String browser;
private String os;
/**
/** * 操作系统
* 权限列表 */
*/ private String os;
private Set<String> permissions;
/**
/** * 权限列表
* 用户信息 */
*/ private Set<String> permissions;
private SysUser user;
/**
public LoginUser() * 用户信息
{ */
} private SysUser user;
public LoginUser(SysUser user, Set<String> permissions) public LoginUser()
{ {
this.user = user; }
this.permissions = permissions;
} public LoginUser(SysUser user, Set<String> permissions)
{
public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions) this.user = user;
{ this.permissions = permissions;
this.userId = userId; }
this.deptId = deptId;
this.user = user; public LoginUser(Long userId, Long deptId, SysUser user, Set<String> permissions)
this.permissions = permissions; {
} this.userId = userId;
this.deptId = deptId;
public Long getUserId() this.user = user;
{ this.permissions = permissions;
return userId; }
}
public Long getUserId()
public void setUserId(Long userId) {
{ return userId;
this.userId = userId; }
}
public void setUserId(Long userId)
public Long getDeptId() {
{ this.userId = userId;
return deptId; }
}
public Long getDeptId()
public void setDeptId(Long deptId) {
{ return deptId;
this.deptId = deptId; }
}
public void setDeptId(Long deptId)
public String getToken() {
{ this.deptId = deptId;
return token; }
}
public String getToken()
public void setToken(String token) {
{ return token;
this.token = token; }
}
public void setToken(String token)
@JSONField(serialize = false) {
@Override this.token = token;
public String getPassword() }
{
return user.getPassword(); @JSONField(serialize = false)
} @Override
public String getPassword()
@Override {
public String getUsername() return user.getPassword();
{ }
return user.getUserName();
} @Override
public String getUsername()
/** {
* 账户是否未过期,过期无法验证 return user.getUserName();
*/ }
@JSONField(serialize = false)
@Override /**
public boolean isAccountNonExpired() * 账户是否未过期,过期无法验证
{ */
return true; @JSONField(serialize = false)
} @Override
public boolean isAccountNonExpired()
/** {
* 指定用户是否解锁,锁定的用户无法进行身份验证 return true;
* }
* @return
*/ /**
@JSONField(serialize = false) * 指定用户是否解锁,锁定的用户无法进行身份验证
@Override *
public boolean isAccountNonLocked() * @return
{ */
return true; @JSONField(serialize = false)
} @Override
public boolean isAccountNonLocked()
/** {
* 指示是否已过期的用户的凭据(密码),过期的凭据防止认证 return true;
* }
* @return
*/ /**
@JSONField(serialize = false) * 指示是否已过期的用户的凭据(密码),过期的凭据防止认证
@Override *
public boolean isCredentialsNonExpired() * @return
{ */
return true; @JSONField(serialize = false)
} @Override
public boolean isCredentialsNonExpired()
/** {
* 是否可用 ,禁用的用户不能身份验证 return true;
* }
* @return
*/ /**
@JSONField(serialize = false) * 是否可用 ,禁用的用户不能身份验证
@Override *
public boolean isEnabled() * @return
{ */
return true; @JSONField(serialize = false)
} @Override
public boolean isEnabled()
public Long getLoginTime() {
{ return true;
return loginTime; }
}
public Long getLoginTime()
public void setLoginTime(Long loginTime) {
{ return loginTime;
this.loginTime = loginTime; }
}
public void setLoginTime(Long loginTime)
public String getIpaddr() {
{ this.loginTime = loginTime;
return ipaddr; }
}
public String getIpaddr()
public void setIpaddr(String ipaddr) {
{ return ipaddr;
this.ipaddr = ipaddr; }
}
public void setIpaddr(String ipaddr)
public String getLoginLocation() {
{ this.ipaddr = ipaddr;
return loginLocation; }
}
public String getLoginLocation()
public void setLoginLocation(String loginLocation) {
{ return loginLocation;
this.loginLocation = loginLocation; }
}
public void setLoginLocation(String loginLocation)
public String getBrowser() {
{ this.loginLocation = loginLocation;
return browser; }
}
public String getBrowser()
public void setBrowser(String browser) {
{ return browser;
this.browser = browser; }
}
public void setBrowser(String browser)
public String getOs() {
{ this.browser = browser;
return os; }
}
public String getOs()
public void setOs(String os) {
{ return os;
this.os = os; }
}
public void setOs(String os)
public Long getExpireTime() {
{ this.os = os;
return expireTime; }
}
public Long getExpireTime()
public void setExpireTime(Long expireTime) {
{ return expireTime;
this.expireTime = expireTime; }
}
public void setExpireTime(Long expireTime)
public Set<String> getPermissions() {
{ this.expireTime = expireTime;
return permissions; }
}
public Set<String> getPermissions()
public void setPermissions(Set<String> permissions) {
{ return permissions;
this.permissions = permissions; }
}
public void setPermissions(Set<String> permissions)
public SysUser getUser() {
{ this.permissions = permissions;
return user; }
}
public SysUser getUser()
public void setUser(SysUser user) {
{ return user;
this.user = user; }
}
public void setUser(SysUser user)
@Override {
public Collection<? extends GrantedAuthority> getAuthorities() this.user = user;
{ }
return null;
} @Override
} @JSONField(serialize = false)
public Collection<? extends GrantedAuthority> getAuthorities()
{
if (permissions == null || permissions.isEmpty())
{
return Collections.emptyList();
}
return permissions.stream()
.filter(Objects::nonNull)
.map(SimpleGrantedAuthority::new)
.collect(Collectors.toList());
}
}
@@ -1,11 +1,11 @@
package com.ruoyi.common.core.domain.model; package com.ruoyi.common.core.domain.model;
/** /**
* 用户注册对象 * 用户注册对象
* *
* @author ruoyi * @author ruoyi
*/ */
public class RegisterBody extends LoginBody public class RegisterBody extends LoginBody
{ {
} }
@@ -1,85 +1,85 @@
package com.ruoyi.common.core.page; package com.ruoyi.common.core.page;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
/** /**
* 表格分页数据对象 * 表格分页数据对象
* *
* @author ruoyi * @author ruoyi
*/ */
public class TableDataInfo implements Serializable public class TableDataInfo implements Serializable
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 总记录数 */ /** 总记录数 */
private long total; private long total;
/** 列表数据 */ /** 列表数据 */
private List<?> rows; private List<?> rows;
/** 消息状态码 */ /** 消息状态码 */
private int code; private int code;
/** 消息内容 */ /** 消息内容 */
private String msg; private String msg;
/** /**
* 表格数据对象 * 表格数据对象
*/ */
public TableDataInfo() public TableDataInfo()
{ {
} }
/** /**
* 分页 * 分页
* *
* @param list 列表数据 * @param list 列表数据
* @param total 总记录数 * @param total 总记录数
*/ */
public TableDataInfo(List<?> list, long total) public TableDataInfo(List<?> list, long total)
{ {
this.rows = list; this.rows = list;
this.total = total; this.total = total;
} }
public long getTotal() public long getTotal()
{ {
return total; return total;
} }
public void setTotal(long total) public void setTotal(long total)
{ {
this.total = total; this.total = total;
} }
public List<?> getRows() public List<?> getRows()
{ {
return rows; return rows;
} }
public void setRows(List<?> rows) public void setRows(List<?> rows)
{ {
this.rows = rows; this.rows = rows;
} }
public int getCode() public int getCode()
{ {
return code; return code;
} }
public void setCode(int code) public void setCode(int code)
{ {
this.code = code; this.code = code;
} }
public String getMsg() public String getMsg()
{ {
return msg; return msg;
} }
public void setMsg(String msg) public void setMsg(String msg)
{ {
this.msg = msg; this.msg = msg;
} }
} }
@@ -1,56 +1,56 @@
package com.ruoyi.common.core.page; package com.ruoyi.common.core.page;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
/** /**
* 表格数据处理 * 表格数据处理
* *
* @author ruoyi * @author ruoyi
*/ */
public class TableSupport public class TableSupport
{ {
/** /**
* 当前记录起始索引 * 当前记录起始索引
*/ */
public static final String PAGE_NUM = "pageNum"; public static final String PAGE_NUM = "pageNum";
/** /**
* 每页显示记录数 * 每页显示记录数
*/ */
public static final String PAGE_SIZE = "pageSize"; public static final String PAGE_SIZE = "pageSize";
/** /**
* 排序列 * 排序列
*/ */
public static final String ORDER_BY_COLUMN = "orderByColumn"; public static final String ORDER_BY_COLUMN = "orderByColumn";
/** /**
* 排序的方向 "desc" 或者 "asc". * 排序的方向 "desc" 或者 "asc".
*/ */
public static final String IS_ASC = "isAsc"; public static final String IS_ASC = "isAsc";
/** /**
* 分页参数合理化 * 分页参数合理化
*/ */
public static final String REASONABLE = "reasonable"; public static final String REASONABLE = "reasonable";
/** /**
* 封装分页对象 * 封装分页对象
*/ */
public static PageDomain getPageDomain() public static PageDomain getPageDomain()
{ {
PageDomain pageDomain = new PageDomain(); PageDomain pageDomain = new PageDomain();
pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1)); pageDomain.setPageNum(Convert.toInt(ServletUtils.getParameter(PAGE_NUM), 1));
pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10)); pageDomain.setPageSize(Convert.toInt(ServletUtils.getParameter(PAGE_SIZE), 10));
pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN)); pageDomain.setOrderByColumn(ServletUtils.getParameter(ORDER_BY_COLUMN));
pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC)); pageDomain.setIsAsc(ServletUtils.getParameter(IS_ASC));
pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE)); pageDomain.setReasonable(ServletUtils.getParameterToBool(REASONABLE));
return pageDomain; return pageDomain;
} }
public static PageDomain buildPageRequest() public static PageDomain buildPageRequest()
{ {
return getPageDomain(); return getPageDomain();
} }
} }
@@ -1,268 +1,269 @@
package com.ruoyi.common.core.redis; package com.ruoyi.common.core.redis;
import java.util.Collection; import java.time.Duration;
import java.util.Iterator; import java.util.Collection;
import java.util.List; import java.util.Iterator;
import java.util.Map; import java.util.List;
import java.util.Set; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import java.util.concurrent.TimeUnit;
import org.springframework.data.redis.core.BoundSetOperations; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.HashOperations; import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ValueOperations; import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component; import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
/**
* spring redis 工具类 /**
* * spring redis 工具类
* @author ruoyi *
**/ * @author ruoyi
@SuppressWarnings(value = { "unchecked", "rawtypes" }) **/
@Component @SuppressWarnings(value = { "unchecked", "rawtypes" })
public class RedisCache @Component
{ public class RedisCache
@Autowired {
public RedisTemplate redisTemplate; @Autowired
public RedisTemplate redisTemplate;
/**
* 缓存基本的对象,Integer、String、实体类等 /**
* * 缓存基本的对象,Integer、String、实体类等
* @param key 缓存的键值 *
* @param value 缓存的值 * @param key 缓存的键值
*/ * @param value 缓存的值
public <T> void setCacheObject(final String key, final T value) */
{ public <T> void setCacheObject(final String key, final T value)
redisTemplate.opsForValue().set(key, value); {
} redisTemplate.opsForValue().set(key, value);
}
/**
* 缓存基本的对象,Integer、String、实体类等 /**
* * 缓存基本的对象,Integer、String、实体类等
* @param key 缓存的键值 *
* @param value 缓存的值 * @param key 缓存的键值
* @param timeout 时间 * @param value 缓存的值
* @param timeUnit 时间颗粒度 * @param timeout 时间
*/ * @param timeUnit 时间颗粒度
public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit) */
{ public <T> void setCacheObject(final String key, final T value, final Integer timeout, final TimeUnit timeUnit)
redisTemplate.opsForValue().set(key, value, timeout, timeUnit); {
} redisTemplate.opsForValue().set(key, value, Duration.of(timeout, timeUnit.toChronoUnit()));
}
/**
* 设置有效时间 /**
* * 设置有效时间
* @param key Redis键 *
* @param timeout 超时时间 * @param key Redis键
* @return true=设置成功;false=设置失败 * @param timeout 超时时间
*/ * @return true=设置成功;false=设置失败
public boolean expire(final String key, final long timeout) */
{ public boolean expire(final String key, final long timeout)
return expire(key, timeout, TimeUnit.SECONDS); {
} return expire(key, timeout, TimeUnit.SECONDS);
}
/**
* 设置有效时间 /**
* * 设置有效时间
* @param key Redis键 *
* @param timeout 超时时间 * @param key Redis键
* @param unit 时间单位 * @param timeout 超时时间
* @return true=设置成功;false=设置失败 * @param unit 时间单位
*/ * @return true=设置成功;false=设置失败
public boolean expire(final String key, final long timeout, final TimeUnit unit) */
{ public boolean expire(final String key, final long timeout, final TimeUnit unit)
return redisTemplate.expire(key, timeout, unit); {
} return redisTemplate.expire(key, Duration.of(timeout, unit.toChronoUnit()));
}
/**
* 获取有效时间 /**
* * 获取有效时间
* @param key Redis键 *
* @return 有效时间 * @param key Redis键
*/ * @return 有效时间
public long getExpire(final String key) */
{ public long getExpire(final String key)
return redisTemplate.getExpire(key); {
} return redisTemplate.getExpire(key);
}
/**
* 判断 key是否存在 /**
* * 判断 key是否存在
* @param key 键 *
* @return true 存在 false不存在 * @param key 键
*/ * @return true 存在 false不存在
public Boolean hasKey(String key) */
{ public Boolean hasKey(String key)
return redisTemplate.hasKey(key); {
} return redisTemplate.hasKey(key);
}
/**
* 获得缓存的基本对象。 /**
* * 获得缓存的基本对象。
* @param key 缓存键值 *
* @return 缓存键值对应的数据 * @param key 缓存键值
*/ * @return 缓存键值对应的数据
public <T> T getCacheObject(final String key) */
{ public <T> T getCacheObject(final String key)
ValueOperations<String, T> operation = redisTemplate.opsForValue(); {
return operation.get(key); ValueOperations<String, T> operation = redisTemplate.opsForValue();
} return operation.get(key);
}
/**
* 删除单个对象 /**
* * 删除单个对象
* @param key *
*/ * @param key
public boolean deleteObject(final String key) */
{ public boolean deleteObject(final String key)
return redisTemplate.delete(key); {
} return redisTemplate.delete(key);
}
/**
* 删除集合对象 /**
* * 删除集合对象
* @param collection 多个对象 *
* @return * @param collection 多个对象
*/ * @return
public boolean deleteObject(final Collection collection) */
{ public boolean deleteObject(final Collection collection)
return redisTemplate.delete(collection) > 0; {
} return redisTemplate.delete(collection) > 0;
}
/**
* 缓存List数据 /**
* * 缓存List数据
* @param key 缓存的键值 *
* @param dataList 待缓存的List数据 * @param key 缓存的键值
* @return 缓存的对象 * @param dataList 待缓存的List数据
*/ * @return 缓存的对象
public <T> long setCacheList(final String key, final List<T> dataList) */
{ public <T> long setCacheList(final String key, final List<T> dataList)
Long count = redisTemplate.opsForList().rightPushAll(key, dataList); {
return count == null ? 0 : count; Long count = redisTemplate.opsForList().rightPushAll(key, dataList);
} return count == null ? 0 : count;
}
/**
* 获得缓存的list对象 /**
* * 获得缓存的list对象
* @param key 缓存的键值 *
* @return 缓存键值对应的数据 * @param key 缓存的键值
*/ * @return 缓存键值对应的数据
public <T> List<T> getCacheList(final String key) */
{ public <T> List<T> getCacheList(final String key)
return redisTemplate.opsForList().range(key, 0, -1); {
} return redisTemplate.opsForList().range(key, 0, -1);
}
/**
* 缓存Set /**
* * 缓存Set
* @param key 缓存键值 *
* @param dataSet 缓存的数据 * @param key 缓存键值
* @return 缓存数据的对象 * @param dataSet 缓存的数据
*/ * @return 缓存数据的对象
public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet) */
{ public <T> BoundSetOperations<String, T> setCacheSet(final String key, final Set<T> dataSet)
BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key); {
Iterator<T> it = dataSet.iterator(); BoundSetOperations<String, T> setOperation = redisTemplate.boundSetOps(key);
while (it.hasNext()) Iterator<T> it = dataSet.iterator();
{ while (it.hasNext())
setOperation.add(it.next()); {
} setOperation.add(it.next());
return setOperation; }
} return setOperation;
}
/**
* 获得缓存的set /**
* * 获得缓存的set
* @param key *
* @return * @param key
*/ * @return
public <T> Set<T> getCacheSet(final String key) */
{ public <T> Set<T> getCacheSet(final String key)
return redisTemplate.opsForSet().members(key); {
} return redisTemplate.opsForSet().members(key);
}
/**
* 缓存Map /**
* * 缓存Map
* @param key *
* @param dataMap * @param key
*/ * @param dataMap
public <T> void setCacheMap(final String key, final Map<String, T> dataMap) */
{ public <T> void setCacheMap(final String key, final Map<String, T> dataMap)
if (dataMap != null) { {
redisTemplate.opsForHash().putAll(key, dataMap); if (dataMap != null) {
} redisTemplate.opsForHash().putAll(key, dataMap);
} }
}
/**
* 获得缓存的Map /**
* * 获得缓存的Map
* @param key *
* @return * @param key
*/ * @return
public <T> Map<String, T> getCacheMap(final String key) */
{ public <T> Map<String, T> getCacheMap(final String key)
return redisTemplate.opsForHash().entries(key); {
} return redisTemplate.opsForHash().entries(key);
}
/**
* 往Hash中存入数据 /**
* * 往Hash中存入数据
* @param key Redis键 *
* @param hKey Hash键 * @param key Redis键
* @param value 值 * @param hKey Hash键
*/ * @param value 值
public <T> void setCacheMapValue(final String key, final String hKey, final T value) */
{ public <T> void setCacheMapValue(final String key, final String hKey, final T value)
redisTemplate.opsForHash().put(key, hKey, value); {
} redisTemplate.opsForHash().put(key, hKey, value);
}
/**
* 获取Hash中的数据 /**
* * 获取Hash中的数据
* @param key Redis键 *
* @param hKey Hash键 * @param key Redis键
* @return Hash中的对象 * @param hKey Hash键
*/ * @return Hash中的对象
public <T> T getCacheMapValue(final String key, final String hKey) */
{ public <T> T getCacheMapValue(final String key, final String hKey)
HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash(); {
return opsForHash.get(key, hKey); HashOperations<String, String, T> opsForHash = redisTemplate.opsForHash();
} return opsForHash.get(key, hKey);
}
/**
* 获取多个Hash中的数据 /**
* * 获取多个Hash中的数据
* @param key Redis键 *
* @param hKeys Hash键集合 * @param key Redis键
* @return Hash对象集合 * @param hKeys Hash键集合
*/ * @return Hash对象集合
public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys) */
{ public <T> List<T> getMultiCacheMapValue(final String key, final Collection<Object> hKeys)
return redisTemplate.opsForHash().multiGet(key, hKeys); {
} return redisTemplate.opsForHash().multiGet(key, hKeys);
}
/**
* 删除Hash中的某条数据 /**
* * 删除Hash中的某条数据
* @param key Redis键 *
* @param hKey Hash键 * @param key Redis键
* @return 是否成功 * @param hKey Hash键
*/ * @return 是否成功
public boolean deleteCacheMapValue(final String key, final String hKey) */
{ public boolean deleteCacheMapValue(final String key, final String hKey)
return redisTemplate.opsForHash().delete(key, hKey) > 0; {
} return redisTemplate.opsForHash().delete(key, hKey) > 0;
}
/**
* 获得缓存的基本对象列表 /**
* * 获得缓存的基本对象列表
* @param pattern 字符串前缀 *
* @return 对象列表 * @param pattern 字符串前缀
*/ * @return 对象列表
public Collection<String> keys(final String pattern) */
{ public Collection<String> keys(final String pattern)
return redisTemplate.keys(pattern); {
} return redisTemplate.keys(pattern);
} }
}
@@ -1,86 +1,86 @@
package com.ruoyi.common.core.text; package com.ruoyi.common.core.text;
import java.nio.charset.Charset; import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* 字符集工具类 * 字符集工具类
* *
* @author ruoyi * @author ruoyi
*/ */
public class CharsetKit public class CharsetKit
{ {
/** ISO-8859-1 */ /** ISO-8859-1 */
public static final String ISO_8859_1 = "ISO-8859-1"; public static final String ISO_8859_1 = "ISO-8859-1";
/** UTF-8 */ /** UTF-8 */
public static final String UTF_8 = "UTF-8"; public static final String UTF_8 = "UTF-8";
/** GBK */ /** GBK */
public static final String GBK = "GBK"; public static final String GBK = "GBK";
/** ISO-8859-1 */ /** ISO-8859-1 */
public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1); public static final Charset CHARSET_ISO_8859_1 = Charset.forName(ISO_8859_1);
/** UTF-8 */ /** UTF-8 */
public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8); public static final Charset CHARSET_UTF_8 = Charset.forName(UTF_8);
/** GBK */ /** GBK */
public static final Charset CHARSET_GBK = Charset.forName(GBK); public static final Charset CHARSET_GBK = Charset.forName(GBK);
/** /**
* 转换为Charset对象 * 转换为Charset对象
* *
* @param charset 字符集,为空则返回默认字符集 * @param charset 字符集,为空则返回默认字符集
* @return Charset * @return Charset
*/ */
public static Charset charset(String charset) public static Charset charset(String charset)
{ {
return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset); return StringUtils.isEmpty(charset) ? Charset.defaultCharset() : Charset.forName(charset);
} }
/** /**
* 转换字符串的字符集编码 * 转换字符串的字符集编码
* *
* @param source 字符串 * @param source 字符串
* @param srcCharset 源字符集,默认ISO-8859-1 * @param srcCharset 源字符集,默认ISO-8859-1
* @param destCharset 目标字符集,默认UTF-8 * @param destCharset 目标字符集,默认UTF-8
* @return 转换后的字符集 * @return 转换后的字符集
*/ */
public static String convert(String source, String srcCharset, String destCharset) public static String convert(String source, String srcCharset, String destCharset)
{ {
return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset)); return convert(source, Charset.forName(srcCharset), Charset.forName(destCharset));
} }
/** /**
* 转换字符串的字符集编码 * 转换字符串的字符集编码
* *
* @param source 字符串 * @param source 字符串
* @param srcCharset 源字符集,默认ISO-8859-1 * @param srcCharset 源字符集,默认ISO-8859-1
* @param destCharset 目标字符集,默认UTF-8 * @param destCharset 目标字符集,默认UTF-8
* @return 转换后的字符集 * @return 转换后的字符集
*/ */
public static String convert(String source, Charset srcCharset, Charset destCharset) public static String convert(String source, Charset srcCharset, Charset destCharset)
{ {
if (null == srcCharset) if (null == srcCharset)
{ {
srcCharset = StandardCharsets.ISO_8859_1; srcCharset = StandardCharsets.ISO_8859_1;
} }
if (null == destCharset) if (null == destCharset)
{ {
destCharset = StandardCharsets.UTF_8; destCharset = StandardCharsets.UTF_8;
} }
if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset)) if (StringUtils.isEmpty(source) || srcCharset.equals(destCharset))
{ {
return source; return source;
} }
return new String(source.getBytes(srcCharset), destCharset); return new String(source.getBytes(srcCharset), destCharset);
} }
/** /**
* @return 系统字符集编码 * @return 系统字符集编码
*/ */
public static String systemCharset() public static String systemCharset()
{ {
return Charset.defaultCharset().name(); return Charset.defaultCharset().name();
} }
} }
File diff suppressed because it is too large. Load diff
@@ -1,92 +1,92 @@
package com.ruoyi.common.core.text; package com.ruoyi.common.core.text;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* 字符串格式化 * 字符串格式化
* *
* @author ruoyi * @author ruoyi
*/ */
public class StrFormatter public class StrFormatter
{ {
public static final String EMPTY_JSON = "{}"; public static final String EMPTY_JSON = "{}";
public static final char C_BACKSLASH = '\\'; public static final char C_BACKSLASH = '\\';
public static final char C_DELIM_START = '{'; public static final char C_DELIM_START = '{';
public static final char C_DELIM_END = '}'; public static final char C_DELIM_END = '}';
/** /**
* 格式化字符串<br> * 格式化字符串<br>
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br> * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br> * 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
* 例:<br> * 例:<br>
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br> * 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br> * 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br> * 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
* *
* @param strPattern 字符串模板 * @param strPattern 字符串模板
* @param argArray 参数列表 * @param argArray 参数列表
* @return 结果 * @return 结果
*/ */
public static String format(final String strPattern, final Object... argArray) public static String format(final String strPattern, final Object... argArray)
{ {
if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray)) if (StringUtils.isEmpty(strPattern) || StringUtils.isEmpty(argArray))
{ {
return strPattern; return strPattern;
} }
final int strPatternLength = strPattern.length(); final int strPatternLength = strPattern.length();
// 初始化定义好的长度以获得更好的性能 // 初始化定义好的长度以获得更好的性能
StringBuilder sbuf = new StringBuilder(strPatternLength + 50); StringBuilder sbuf = new StringBuilder(strPatternLength + 50);
int handledPosition = 0; int handledPosition = 0;
int delimIndex;// 占位符所在位置 int delimIndex;// 占位符所在位置
for (int argIndex = 0; argIndex < argArray.length; argIndex++) for (int argIndex = 0; argIndex < argArray.length; argIndex++)
{ {
delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition); delimIndex = strPattern.indexOf(EMPTY_JSON, handledPosition);
if (delimIndex == -1) if (delimIndex == -1)
{ {
if (handledPosition == 0) if (handledPosition == 0)
{ {
return strPattern; return strPattern;
} }
else else
{ // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果 { // 字符串模板剩余部分不再包含占位符,加入剩余部分后返回结果
sbuf.append(strPattern, handledPosition, strPatternLength); sbuf.append(strPattern, handledPosition, strPatternLength);
return sbuf.toString(); return sbuf.toString();
} }
} }
else else
{ {
if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH) if (delimIndex > 0 && strPattern.charAt(delimIndex - 1) == C_BACKSLASH)
{ {
if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH) if (delimIndex > 1 && strPattern.charAt(delimIndex - 2) == C_BACKSLASH)
{ {
// 转义符之前还有一个转义符,占位符依旧有效 // 转义符之前还有一个转义符,占位符依旧有效
sbuf.append(strPattern, handledPosition, delimIndex - 1); sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(Convert.utf8Str(argArray[argIndex])); sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2; handledPosition = delimIndex + 2;
} }
else else
{ {
// 占位符被转义 // 占位符被转义
argIndex--; argIndex--;
sbuf.append(strPattern, handledPosition, delimIndex - 1); sbuf.append(strPattern, handledPosition, delimIndex - 1);
sbuf.append(C_DELIM_START); sbuf.append(C_DELIM_START);
handledPosition = delimIndex + 1; handledPosition = delimIndex + 1;
} }
} }
else else
{ {
// 正常占位符 // 正常占位符
sbuf.append(strPattern, handledPosition, delimIndex); sbuf.append(strPattern, handledPosition, delimIndex);
sbuf.append(Convert.utf8Str(argArray[argIndex])); sbuf.append(Convert.utf8Str(argArray[argIndex]));
handledPosition = delimIndex + 2; handledPosition = delimIndex + 2;
} }
} }
} }
// 加入最后一个占位符后所有的字符 // 加入最后一个占位符后所有的字符
sbuf.append(strPattern, handledPosition, strPattern.length()); sbuf.append(strPattern, handledPosition, strPattern.length());
return sbuf.toString(); return sbuf.toString();
} }
} }
@@ -1,20 +1,20 @@
package com.ruoyi.common.enums; package com.ruoyi.common.enums;
/** /**
* 操作状态 * 操作状态
* *
* @author ruoyi * @author ruoyi
* *
*/ */
public enum BusinessStatus public enum BusinessStatus
{ {
/** /**
* 成功 * 成功
*/ */
SUCCESS, SUCCESS,
/** /**
* 失败 * 失败
*/ */
FAIL, FAIL,
} }
@@ -1,59 +1,59 @@
package com.ruoyi.common.enums; package com.ruoyi.common.enums;
/** /**
* 业务操作类型 * 业务操作类型
* *
* @author ruoyi * @author ruoyi
*/ */
public enum BusinessType public enum BusinessType
{ {
/** /**
* 其它 * 其它
*/ */
OTHER, OTHER,
/** /**
* 新增 * 新增
*/ */
INSERT, INSERT,
/** /**
* 修改 * 修改
*/ */
UPDATE, UPDATE,
/** /**
* 删除 * 删除
*/ */
DELETE, DELETE,
/** /**
* 授权 * 授权
*/ */
GRANT, GRANT,
/** /**
* 导出 * 导出
*/ */
EXPORT, EXPORT,
/** /**
* 导入 * 导入
*/ */
IMPORT, IMPORT,
/** /**
* 强退 * 强退
*/ */
FORCE, FORCE,
/** /**
* 生成代码 * 生成代码
*/ */
GENCODE, GENCODE,
/** /**
* 清空数据 * 清空数据
*/ */
CLEAN, CLEAN,
} }
@@ -1,19 +1,19 @@
package com.ruoyi.common.enums; package com.ruoyi.common.enums;
/** /**
* 数据源 * 数据源
* *
* @author ruoyi * @author ruoyi
*/ */
public enum DataSourceType public enum DataSourceType
{ {
/** /**
* 主库 * 主库
*/ */
MASTER, MASTER,
/** /**
* 从库 * 从库
*/ */
SLAVE SLAVE
} }
@@ -1,36 +1,36 @@
package com.ruoyi.common.enums; package com.ruoyi.common.enums;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.springframework.lang.Nullable; import org.jspecify.annotations.Nullable;
/** /**
* 请求方式 * 请求方式
* *
* @author ruoyi * @author ruoyi
*/ */
public enum HttpMethod public enum HttpMethod
{ {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE; GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE;
private static final Map<String, HttpMethod> mappings = new HashMap<>(16); private static final Map<String, HttpMethod> mappings = new HashMap<>(16);
static static
{ {
for (HttpMethod httpMethod : values()) for (HttpMethod httpMethod : values())
{ {
mappings.put(httpMethod.name(), httpMethod); mappings.put(httpMethod.name(), httpMethod);
} }
} }
@Nullable @Nullable
public static HttpMethod resolve(@Nullable String method) public static HttpMethod resolve(@Nullable String method)
{ {
return (method != null ? mappings.get(method) : null); return (method != null ? mappings.get(method) : null);
} }
public boolean matches(String method) public boolean matches(String method)
{ {
return (this == resolve(method)); return (this == resolve(method));
} }
} }
@@ -1,20 +1,20 @@
package com.ruoyi.common.enums; package com.ruoyi.common.enums;
/** /**
* 限流类型 * 限流类型
* *
* @author ruoyi * @author ruoyi
*/ */
public enum LimitType public enum LimitType
{ {
/** /**
* 默认策略全局限流 * 默认策略全局限流
*/ */
DEFAULT, DEFAULT,
/** /**
* 根据请求者IP进行限流 * 根据请求者IP进行限流
*/ */
IP IP
} }
@@ -1,24 +1,24 @@
package com.ruoyi.common.enums; package com.ruoyi.common.enums;
/** /**
* 操作人类别 * 操作人类别
* *
* @author ruoyi * @author ruoyi
*/ */
public enum OperatorType public enum OperatorType
{ {
/** /**
* 其它 * 其它
*/ */
OTHER, OTHER,
/** /**
* 后台用户 * 后台用户
*/ */
MANAGE, MANAGE,
/** /**
* 手机端用户 * 手机端用户
*/ */
MOBILE MOBILE
} }
@@ -1,30 +1,30 @@
package com.ruoyi.common.enums; package com.ruoyi.common.enums;
/** /**
* 用户状态 * 用户状态
* *
* @author ruoyi * @author ruoyi
*/ */
public enum UserStatus public enum UserStatus
{ {
OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除"); OK("0", "正常"), DISABLE("1", "停用"), DELETED("2", "删除");
private final String code; private final String code;
private final String info; private final String info;
UserStatus(String code, String info) UserStatus(String code, String info)
{ {
this.code = code; this.code = code;
this.info = info; this.info = info;
} }
public String getCode() public String getCode()
{ {
return code; return code;
} }
public String getInfo() public String getInfo()
{ {
return info; return info;
} }
} }
@@ -1,15 +1,15 @@
package com.ruoyi.common.exception; package com.ruoyi.common.exception;
/** /**
* 演示模式异常 * 演示模式异常
* *
* @author ruoyi * @author ruoyi
*/ */
public class DemoModeException extends RuntimeException public class DemoModeException extends RuntimeException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public DemoModeException() public DemoModeException()
{ {
} }
} }
@@ -1,58 +1,58 @@
package com.ruoyi.common.exception; package com.ruoyi.common.exception;
/** /**
* 全局异常 * 全局异常
* *
* @author ruoyi * @author ruoyi
*/ */
public class GlobalException extends RuntimeException public class GlobalException extends RuntimeException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* 错误提示 * 错误提示
*/ */
private String message; private String message;
/** /**
* 错误明细,内部调试错误 * 错误明细,内部调试错误
* *
* 和 {@link CommonResult#getDetailMessage()} 一致的设计 * 和 {@link CommonResult#getDetailMessage()} 一致的设计
*/ */
private String detailMessage; private String detailMessage;
/** /**
* 空构造方法,避免反序列化问题 * 空构造方法,避免反序列化问题
*/ */
public GlobalException() public GlobalException()
{ {
} }
public GlobalException(String message) public GlobalException(String message)
{ {
this.message = message; this.message = message;
} }
public String getDetailMessage() public String getDetailMessage()
{ {
return detailMessage; return detailMessage;
} }
public GlobalException setDetailMessage(String detailMessage) public GlobalException setDetailMessage(String detailMessage)
{ {
this.detailMessage = detailMessage; this.detailMessage = detailMessage;
return this; return this;
} }
@Override @Override
public String getMessage() public String getMessage()
{ {
return message; return message;
} }
public GlobalException setMessage(String message) public GlobalException setMessage(String message)
{ {
this.message = message; this.message = message;
return this; return this;
} }
} }
@@ -1,74 +1,74 @@
package com.ruoyi.common.exception; package com.ruoyi.common.exception;
/** /**
* 业务异常 * 业务异常
* *
* @author ruoyi * @author ruoyi
*/ */
public final class ServiceException extends RuntimeException public final class ServiceException extends RuntimeException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* 错误码 * 错误码
*/ */
private Integer code; private Integer code;
/** /**
* 错误提示 * 错误提示
*/ */
private String message; private String message;
/** /**
* 错误明细,内部调试错误 * 错误明细,内部调试错误
* *
* 和 {@link CommonResult#getDetailMessage()} 一致的设计 * 和 {@link CommonResult#getDetailMessage()} 一致的设计
*/ */
private String detailMessage; private String detailMessage;
/** /**
* 空构造方法,避免反序列化问题 * 空构造方法,避免反序列化问题
*/ */
public ServiceException() public ServiceException()
{ {
} }
public ServiceException(String message) public ServiceException(String message)
{ {
this.message = message; this.message = message;
} }
public ServiceException(String message, Integer code) public ServiceException(String message, Integer code)
{ {
this.message = message; this.message = message;
this.code = code; this.code = code;
} }
public String getDetailMessage() public String getDetailMessage()
{ {
return detailMessage; return detailMessage;
} }
@Override @Override
public String getMessage() public String getMessage()
{ {
return message; return message;
} }
public Integer getCode() public Integer getCode()
{ {
return code; return code;
} }
public ServiceException setMessage(String message) public ServiceException setMessage(String message)
{ {
this.message = message; this.message = message;
return this; return this;
} }
public ServiceException setDetailMessage(String detailMessage) public ServiceException setDetailMessage(String detailMessage)
{ {
this.detailMessage = detailMessage; this.detailMessage = detailMessage;
return this; return this;
} }
} }
@@ -1,26 +1,26 @@
package com.ruoyi.common.exception; package com.ruoyi.common.exception;
/** /**
* 工具类异常 * 工具类异常
* *
* @author ruoyi * @author ruoyi
*/ */
public class UtilException extends RuntimeException public class UtilException extends RuntimeException
{ {
private static final long serialVersionUID = 8247610319171014183L; private static final long serialVersionUID = 8247610319171014183L;
public UtilException(Throwable e) public UtilException(Throwable e)
{ {
super(e.getMessage(), e); super(e.getMessage(), e);
} }
public UtilException(String message) public UtilException(String message)
{ {
super(message); super(message);
} }
public UtilException(String message, Throwable throwable) public UtilException(String message, Throwable throwable)
{ {
super(message, throwable); super(message, throwable);
} }
} }
@@ -1,97 +1,97 @@
package com.ruoyi.common.exception.base; package com.ruoyi.common.exception.base;
import com.ruoyi.common.utils.MessageUtils; import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
/** /**
* 基础异常 * 基础异常
* *
* @author ruoyi * @author ruoyi
*/ */
public class BaseException extends RuntimeException public class BaseException extends RuntimeException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** /**
* 所属模块 * 所属模块
*/ */
private String module; private String module;
/** /**
* 错误码 * 错误码
*/ */
private String code; private String code;
/** /**
* 错误码对应的参数 * 错误码对应的参数
*/ */
private Object[] args; private Object[] args;
/** /**
* 错误消息 * 错误消息
*/ */
private String defaultMessage; private String defaultMessage;
public BaseException(String module, String code, Object[] args, String defaultMessage) public BaseException(String module, String code, Object[] args, String defaultMessage)
{ {
this.module = module; this.module = module;
this.code = code; this.code = code;
this.args = args; this.args = args;
this.defaultMessage = defaultMessage; this.defaultMessage = defaultMessage;
} }
public BaseException(String module, String code, Object[] args) public BaseException(String module, String code, Object[] args)
{ {
this(module, code, args, null); this(module, code, args, null);
} }
public BaseException(String module, String defaultMessage) public BaseException(String module, String defaultMessage)
{ {
this(module, null, null, defaultMessage); this(module, null, null, defaultMessage);
} }
public BaseException(String code, Object[] args) public BaseException(String code, Object[] args)
{ {
this(null, code, args, null); this(null, code, args, null);
} }
public BaseException(String defaultMessage) public BaseException(String defaultMessage)
{ {
this(null, null, null, defaultMessage); this(null, null, null, defaultMessage);
} }
@Override @Override
public String getMessage() public String getMessage()
{ {
String message = null; String message = null;
if (!StringUtils.isEmpty(code)) if (!StringUtils.isEmpty(code))
{ {
message = MessageUtils.message(code, args); message = MessageUtils.message(code, args);
} }
if (message == null) if (message == null)
{ {
message = defaultMessage; message = defaultMessage;
} }
return message; return message;
} }
public String getModule() public String getModule()
{ {
return module; return module;
} }
public String getCode() public String getCode()
{ {
return code; return code;
} }
public Object[] getArgs() public Object[] getArgs()
{ {
return args; return args;
} }
public String getDefaultMessage() public String getDefaultMessage()
{ {
return defaultMessage; return defaultMessage;
} }
} }
@@ -1,19 +1,19 @@
package com.ruoyi.common.exception.file; package com.ruoyi.common.exception.file;
import com.ruoyi.common.exception.base.BaseException; import com.ruoyi.common.exception.base.BaseException;
/** /**
* 文件信息异常类 * 文件信息异常类
* *
* @author ruoyi * @author ruoyi
*/ */
public class FileException extends BaseException public class FileException extends BaseException
{ {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
public FileException(String code, Object[] args) public FileException(String code, Object[] args)
{ {
super("file", code, args, null); super("file", code, args, null);
} }
} }
Loaded 100 of 905 files, more files were not shown because too many files have changed in this diff. Show more