90 Commits

Author SHA1 Message Date
RuoYi
8aca11c2a2 若依 3.6.6 2025-05-30 08:03:00 +08:00
RuoYi
725033e361 升级fastjson到最新版2.0.57 2025-05-26 11:14:45 +08:00
RuoYi
d29e49e23b 注册账号设置默认密码最后更新时间 2025-05-26 11:14:06 +08:00
RuoYi
706c3bb69b 添加底部版权信息及开关 2025-05-24 14:33:51 +08:00
RuoYi
cd0ee95b9c 添加页签图标显示开关功能 2025-05-23 14:57:49 +08:00
RuoYi
3293e2fb56 账号密码支持自定义更新周期 2025-05-23 10:19:47 +08:00
RuoYi
924ec0eb6e 初始密码支持自定义修改策略 2025-05-23 09:58:23 +08:00
RuoYi
135b1204a9 升级tomcat到最新版本9.0.105 2025-05-15 10:55:18 +08:00
RuoYi
cb566a704b 升级commons.io到最新版本2.19.0 2025-05-15 10:23:50 +08:00
RuoYi
aadba0382e delete vue-meta 2025-05-15 10:23:34 +08:00
RuoYi
a0ce1cf33b delete eslint 2025-05-15 10:22:46 +08:00
RuoYi
3915c77391 优化导航栏显示昵称&设置 2025-05-09 14:02:09 +08:00
RuoYi
b80932ceb4 菜单搜索支持键盘选择&悬浮主题背景 2025-05-07 13:27:13 +08:00
RuoYi
056cf94082 图片上传组件新增disabled属性 2025-05-06 19:14:54 +08:00
RuoYi
0dcd3e6183 add columnName Drag 2025-05-06 14:54:44 +08:00
RuoYi
07be5ceb26 修复上传组件被多次引用拖动仅对第一个有效的问题 2025-05-06 13:46:21 +08:00
RuoYi
cc59502d7c update icon 2025-05-05 11:22:35 +08:00
RuoYi
98738f23ad 上传组件新增拖动排序属性 2025-04-30 10:31:03 +08:00
RuoYi
57fe1c663e 优化Excel匹配数值型.0结尾 2025-04-28 11:20:48 +08:00
RuoYi
7b6fdb3a89 remove all semicolons 2025-04-27 11:56:21 +08:00
RuoYi
79c885decb 使用Gateway CacheRequestBody代替CacheRequestFilter 2025-04-25 15:11:17 +08:00
RuoYi
1a0f37a2dc 富文本复制粘贴图片上传至url 2025-04-24 18:19:16 +08:00
RuoYi
02de344d8c update package.json 2025-04-24 18:18:44 +08:00
RuoYi
189100f74e 优化低版本node无法启动的问题 2025-04-22 12:07:07 +08:00
RuoYi
e29284e687 优化代码 2025-04-22 12:06:59 +08:00
RuoYi
d4af286f41 显隐列组件支持全选/全不选 2025-04-21 15:30:32 +08:00
RuoYi
60e2d55a23 优化菜单搜索查询页 2025-04-21 13:28:32 +08:00
RuoYi
bbd112d5a3 支持文件&图片组件自定义地址&参数 2025-04-18 13:25:28 +08:00
RuoYi
90922844ea 优化角色禁用不允许分配 2025-04-17 15:36:18 +08:00
RuoYi
3a9f56f04b update status name 2025-04-17 15:35:58 +08:00
RuoYi
a1ec1d57d4 remove dev runjs 2025-03-18 16:01:46 +08:00
RuoYi
060959a7c5 登录页和注册页表头使用VUE_APP_TITLE配置值 2025-03-18 16:01:20 +08:00
RuoYi
43e1d8d573 升级tomcat到最新版本9.0.102 2025-03-14 16:12:40 +08:00
RuoYi
67cf51ba77 update handleTree 2025-03-14 16:12:29 +08:00
RuoYi
a256618d5d 优化代码 2025-03-11 12:52:17 +08:00
若依
a6bcebb62b !397 修复actuator暴漏问题
Merge pull request !397 from 威士忌的纯度/N/A
2025-03-10 03:45:34 +00:00
威士忌的纯度
1cb262daa3 修复actuator暴漏问题
Signed-off-by: 威士忌的纯度 <whr888888@vip.qq.com>
2025-03-07 10:22:52 +00:00
RuoYi
8c096cba8d 优化isAdmin方法,避免脱敏模块security依赖 2025-03-07 12:56:31 +08:00
RuoYi
088cec8adf 菜单管理新增路由名称 2025-03-06 11:09:34 +08:00
RuoYi
85ff6a9910 优化顶部菜单搜索栏为多层级显示 2025-03-05 18:14:13 +08:00
RuoYi
cab5beaca7 文件上传组件新增disabled属性&类型 2025-03-05 18:13:40 +08:00
RuoYi
fc8069a250 优化导出Excel日期格式双击离开后与设定的格式不一致问题 2025-03-05 18:13:12 +08:00
RuoYi
924e705dca 代码生成列表支持按时间排序 2025-03-05 18:12:52 +08:00
RuoYi
049ba453d1 优化空指针异常时无法获取错误信息问题 2025-03-05 18:10:56 +08:00
RuoYi
4aa261e8f7 优化定时任务字符包含多个括号导致数据错误 2025-03-05 18:10:12 +08:00
RuoYi
914a6620f5 升级tomcat到最新版本9.0.98 2025-03-05 18:08:29 +08:00
RuoYi
3dcee7057d 优化代码 2025-03-05 18:01:33 +08:00
RuoYi
0467631319 update ry_config.sql 2025-02-24 16:24:36 +08:00
若依
a11df90255 !393 config(nacos):增加nacos2.5.0配置文件sql
Merge pull request !393 from 牟雷/master
2025-02-18 00:33:39 +00:00
牟雷
596e4fe756 config(nacos):增加nacos2.5.0配置文件sql 2025-02-17 20:19:22 +08:00
RuoYi
37219e4ae6 copyright 2025 2025-01-07 10:55:58 +08:00
RuoYi
adaa3e1db8 代码生成新增配置是否允许文件覆盖到本地 2024-12-25 16:30:44 +08:00
RuoYi
88ad5a2c19 优化导入带标题文件关闭清理 2024-12-25 16:24:38 +08:00
RuoYi
b45dc2ec25 update sqlkeyword 2024-12-25 16:24:02 +08:00
RuoYi
67b17da06f 优化特殊字符密码修改失败问题 2024-12-17 14:28:17 +08:00
RuoYi
b25a280ebb 优化TopNav内链菜单点击没有高亮(IB8WHJ) 2024-12-17 11:57:05 +08:00
RuoYi
cc026e75a3 优化菜单管理切换Mini布局错乱问题 2024-12-17 11:25:03 +08:00
RuoYi
7216b56a56 用户管理过滤掉已禁用部门 2024-12-11 11:43:00 +08:00
RuoYi
a326e880a1 修改主题样式本地读取 2024-12-07 17:08:53 +08:00
RuoYi
92c6d21855 优化文件异常输入流未关闭的问题 2024-12-05 14:27:54 +08:00
RuoYi
2335157f6e 白名单支持对通配符路径匹配 2024-12-04 08:52:13 +08:00
RuoYi
6c3b01c3c5 Excel注解支持wrapText是否允许内容换行 2024-12-03 09:07:04 +08:00
RuoYi
8faea60191 修复导出子列表对象只能在最后的问题 2024-12-02 20:37:12 +08:00
RuoYi
28a16d9878 修复默认关闭Tags-Views时,内链页面打不开 2024-11-27 19:49:12 +08:00
RuoYi
dd3cf18e27 修复TopNav无法正确获取active的问题 2024-11-27 09:02:26 +08:00
RuoYi
65d03dc014 优化代码 2024-11-25 22:30:03 +08:00
RuoYi
7912fd81bd 面板兼容移动端显示 2024-11-25 15:41:00 +08:00
RuoYi
e2175e5b9d 参数键值更换为多行文本 2024-11-25 12:15:49 +08:00
RuoYi
c0e119f8e0 菜单面包屑导航支持多层级显示 2024-11-22 20:45:08 +08:00
RuoYi
fa77b2a08c 分栏参数微调 2024-11-22 14:46:59 +08:00
RuoYi
a222c24796 用户管理支持分栏拖动 2024-11-22 13:58:37 +08:00
RuoYi
08f4b877ce 优化代码 2024-11-20 11:13:24 +08:00
RuoYi
aa607d135c update .env.staging 2024-11-20 10:43:07 +08:00
RuoYi
6d34cdb8a3 若依 3.6.5 2024-11-13 08:38:24 +08:00
RuoYi
d47352253e 升级spring-cloud相关组件到最新版 2024-11-12 15:12:01 +08:00
RuoYi
61cbd470e1 update datascope 2024-11-12 15:10:47 +08:00
RuoYi
b3ef4adfed 支持自定义显示Excel属性列 2024-11-07 22:25:48 +08:00
RuoYi
856c471472 优化代码 2024-11-06 10:20:18 +08:00
RuoYi
bec5600f16 优化无用户编号不校验数据权限 2024-11-05 16:30:15 +08:00
RuoYi
5b485e7934 校检文件名是否包含特殊字符 2024-11-05 12:50:12 +08:00
RuoYi
73a752d3ab 优化身份证脱敏正则 2024-10-21 17:16:01 +08:00
RuoYi
1899a832b9 优化权限更新后同步缓存 2024-10-21 17:15:30 +08:00
RuoYi
e6796c0954 操作日志记录DELETE请求参数 2024-10-17 13:17:25 +08:00
RuoYi
4987289a98 升级quill到最新版本2.0.2 2024-10-15 16:21:20 +08:00
RuoYi
18409922a5 修改代码生成上级菜单字段类型 2024-09-27 16:23:36 +08:00
RuoYi
3dca02b306 修复角色禁用权限不失效问题 2024-09-21 12:08:41 +08:00
RuoYi
75f3275e15 修复角色禁用权限不失效问题 2024-09-21 12:01:48 +08:00
RuoYi
b2e4a7046b update ry_config 2024-09-02 20:21:30 +08:00
RuoYi
60618c1da9 优化提示 2024-09-02 20:21:15 +08:00
RuoYi
3b499b1344 使用SpringDoc代替Swagger 2024-08-30 11:26:57 +08:00
92 changed files with 611 additions and 892 deletions

View File

@@ -126,4 +126,4 @@ com.ruoyi
## 若依微服务交流群 ## 若依微服务交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-42799195-blue.svg)](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [![加入QQ群](https://img.shields.io/badge/已满-170157040-blue.svg)](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [![加入QQ群](https://img.shields.io/badge/已满-130643120-blue.svg)](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [![加入QQ群](https://img.shields.io/badge/已满-225920371-blue.svg)](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [![加入QQ群](https://img.shields.io/badge/已满-201705537-blue.svg)](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [![加入QQ群](https://img.shields.io/badge/已满-236543183-blue.svg)](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) [![加入QQ群](https://img.shields.io/badge/已满-213618602-blue.svg)](https://jq.qq.com/?_wv=1027&k=nw3OiyXs) [![加入QQ群](https://img.shields.io/badge/已满-148794840-blue.svg)](https://jq.qq.com/?_wv=1027&k=kiU5WDls) [![加入QQ群](https://img.shields.io/badge/已满-118752664-blue.svg)](https://jq.qq.com/?_wv=1027&k=MtBy6YfT) [![加入QQ群](https://img.shields.io/badge/已满-101038945-blue.svg)](https://jq.qq.com/?_wv=1027&k=FqImHgH2) [![加入QQ群](https://img.shields.io/badge/已满-128355254-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G4jZ4EtdT50PhnMBudTnEwgonxkXOscJ&authKey=FkGHYfoTKlGE6wHdKdjH9bVoOgQjtLP9WM%2Fj7pqGY1msoqw9uxDiBo39E2mLgzYg&noverify=0&group_code=128355254) [![加入QQ群](https://img.shields.io/badge/已满-179219821-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=irnwcXhbLOQEv1g-TwGifjNTA_f4wZiA&authKey=4bpzEwhcUY%2FvsPDHvzYn6xfoS%2FtOArvZ%2BGXzfr7O0%2FEqLfkKA%2BuCDXlzHIFg8t93&noverify=0&group_code=179219821) [![加入QQ群](https://img.shields.io/badge/已满-158753145-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=lx1uEdEDuxeM7rUvF3qmlFdqKqdJ5Z-R&authKey=rgyPW9yhhh4IIURKVFa6NgP3qiqH04WAzrJ0trsgkr3pjzm6sKIOGyA58oOjoj%2FJ&noverify=0&group_code=158753145) [![加入QQ群](https://img.shields.io/badge/112869560-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Kuaw0Xdlw2Nlgn6s8h9elzuquHGxGObD&authKey=cSrQcWQ%2BzQZAFFrwxaR%2BbzcumX4WRduZnd1O6JO1dlclQMiu%2BKwxAy8t2JfNp67V&noverify=0&group_code=112869560) 点击按钮入群。 QQ群 [![加入QQ群](https://img.shields.io/badge/已满-42799195-blue.svg)](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [![加入QQ群](https://img.shields.io/badge/已满-170157040-blue.svg)](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [![加入QQ群](https://img.shields.io/badge/已满-130643120-blue.svg)](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [![加入QQ群](https://img.shields.io/badge/已满-225920371-blue.svg)](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [![加入QQ群](https://img.shields.io/badge/已满-201705537-blue.svg)](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [![加入QQ群](https://img.shields.io/badge/已满-236543183-blue.svg)](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) [![加入QQ群](https://img.shields.io/badge/已满-213618602-blue.svg)](https://jq.qq.com/?_wv=1027&k=nw3OiyXs) [![加入QQ群](https://img.shields.io/badge/已满-148794840-blue.svg)](https://jq.qq.com/?_wv=1027&k=kiU5WDls) [![加入QQ群](https://img.shields.io/badge/已满-118752664-blue.svg)](https://jq.qq.com/?_wv=1027&k=MtBy6YfT) [![加入QQ群](https://img.shields.io/badge/已满-101038945-blue.svg)](https://jq.qq.com/?_wv=1027&k=FqImHgH2) [![加入QQ群](https://img.shields.io/badge/已满-128355254-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G4jZ4EtdT50PhnMBudTnEwgonxkXOscJ&authKey=FkGHYfoTKlGE6wHdKdjH9bVoOgQjtLP9WM%2Fj7pqGY1msoqw9uxDiBo39E2mLgzYg&noverify=0&group_code=128355254) [![加入QQ群](https://img.shields.io/badge/已满-179219821-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=irnwcXhbLOQEv1g-TwGifjNTA_f4wZiA&authKey=4bpzEwhcUY%2FvsPDHvzYn6xfoS%2FtOArvZ%2BGXzfr7O0%2FEqLfkKA%2BuCDXlzHIFg8t93&noverify=0&group_code=179219821) [![加入QQ群](https://img.shields.io/badge/158753145-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=lx1uEdEDuxeM7rUvF3qmlFdqKqdJ5Z-R&authKey=rgyPW9yhhh4IIURKVFa6NgP3qiqH04WAzrJ0trsgkr3pjzm6sKIOGyA58oOjoj%2FJ&noverify=0&group_code=158753145) 点击按钮入群。

View File

@@ -28,9 +28,10 @@ http {
proxy_pass http://ruoyi-gateway:8080/; proxy_pass http://ruoyi-gateway:8080/;
} }
# springdoc proxy # 避免actuator暴露
location~^/v3/api-docs/(.*){ if ($uri ~ "/actuator") {
proxy pass http://localhost:8080/v3/api-docs/$1; return 403;
}
error_page 500 502 503 504 /50x.html; error_page 500 502 503 504 /50x.html;
location = /50x.html { location = /50x.html {

84
pom.xml
View File

@@ -16,14 +16,14 @@
<ruoyi.version>3.6.6</ruoyi.version> <ruoyi.version>3.6.6</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>
<java.version>17</java.version> <java.version>1.8</java.version>
<spring-boot.version>3.3.5</spring-boot.version> <spring-boot.version>2.7.18</spring-boot.version>
<spring-cloud.version>2023.0.3</spring-cloud.version> <spring-cloud.version>2021.0.9</spring-cloud.version>
<spring-cloud-alibaba.version>2023.0.1.2</spring-cloud-alibaba.version> <spring-cloud-alibaba.version>2021.0.6.1</spring-cloud-alibaba.version>
<spring-boot-admin.version>3.3.5</spring-boot-admin.version> <spring-boot-admin.version>2.7.16</spring-boot-admin.version>
<mybatis-spring.version>3.0.3</mybatis-spring.version> <tobato.version>1.27.2</tobato.version>
<kaptcha.version>2.3.3</kaptcha.version> <kaptcha.version>2.3.3</kaptcha.version>
<pagehelper.boot.version>2.1.0</pagehelper.boot.version> <pagehelper.boot.version>2.0.0</pagehelper.boot.version>
<druid.version>1.2.23</druid.version> <druid.version>1.2.23</druid.version>
<dynamic-ds.version>4.3.1</dynamic-ds.version> <dynamic-ds.version>4.3.1</dynamic-ds.version>
<commons.io.version>2.19.0</commons.io.version> <commons.io.version>2.19.0</commons.io.version>
@@ -32,14 +32,27 @@
<jjwt.version>0.9.1</jjwt.version> <jjwt.version>0.9.1</jjwt.version>
<minio.version>8.2.2</minio.version> <minio.version>8.2.2</minio.version>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<springdoc.version>2.6.0</springdoc.version> <springdoc.version>1.6.9</springdoc.version>
<transmittable-thread-local.version>2.14.4</transmittable-thread-local.version> <transmittable-thread-local.version>2.14.4</transmittable-thread-local.version>
<!-- override dependency version -->
<tomcat.version>9.0.105</tomcat.version>
<logback.version>1.2.13</logback.version>
<spring-framework.version>5.3.39</spring-framework.version>
</properties> </properties>
<!-- 依赖声明 --> <!-- 依赖声明 -->
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
<!-- 覆盖SpringFramework的依赖配置-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework-bom</artifactId>
<version>${spring-framework.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringCloud 微服务 --> <!-- SpringCloud 微服务 -->
<dependency> <dependency>
<groupId>org.springframework.cloud</groupId> <groupId>org.springframework.cloud</groupId>
@@ -67,10 +80,49 @@
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
<!-- 覆盖logback的依赖配置-->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- 覆盖tomcat的依赖配置-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-el</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>${tomcat.version}</version>
</dependency>
<!-- FastDFS 分布式文件系统 -->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>${tobato.version}</version>
</dependency>
<!-- Springdoc webmvc 依赖配置 --> <!-- Springdoc webmvc 依赖配置 -->
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <artifactId>springdoc-openapi-ui</artifactId>
<version>${springdoc.version}</version> <version>${springdoc.version}</version>
</dependency> </dependency>
@@ -86,18 +138,6 @@
<groupId>com.github.pagehelper</groupId> <groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId> <artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper.boot.version}</version> <version>${pagehelper.boot.version}</version>
<exclusions>
<exclusion>
<artifactId>mybatis-spring</artifactId>
<groupId>org.mybatis</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency> </dependency>
<!-- io常用工具类 --> <!-- io常用工具类 -->
@@ -238,9 +278,7 @@
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration> <configuration>
<parameters>true</parameters>
<source>${java.version}</source> <source>${java.version}</source>
<target>${java.version}</target> <target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding> <encoding>${project.build.sourceEncoding}</encoding>

View File

@@ -2,9 +2,7 @@ package com.ruoyi.system.api;
import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.constant.ServiceNameConstants; import com.ruoyi.common.core.constant.ServiceNameConstants;
@@ -28,13 +26,4 @@ public interface RemoteFileService
*/ */
@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file); public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file);
/**
* 删除文件
*
* @param fileUrl 文件地址
* @return 结果
*/
@DeleteMapping(value = "/delete", consumes = MediaType.APPLICATION_FORM_URLENCODED_VALUE)
public R<Boolean> delete(@RequestParam("fileUrl") String fileUrl);
} }

View File

@@ -2,10 +2,10 @@ package com.ruoyi.system.api.domain;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import jakarta.validation.constraints.Email; import javax.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import javax.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.web.domain.BaseEntity; import com.ruoyi.common.core.web.domain.BaseEntity;

View File

@@ -1,7 +1,7 @@
package com.ruoyi.system.api.domain; package com.ruoyi.system.api.domain;
import jakarta.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size; import javax.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.annotation.Excel; import com.ruoyi.common.core.annotation.Excel;

View File

@@ -1,8 +1,8 @@
package com.ruoyi.system.api.domain; package com.ruoyi.system.api.domain;
import jakarta.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern; import javax.validation.constraints.Pattern;
import jakarta.validation.constraints.Size; import javax.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.annotation.Excel; import com.ruoyi.common.core.annotation.Excel;

View File

@@ -1,9 +1,9 @@
package com.ruoyi.system.api.domain; package com.ruoyi.system.api.domain;
import java.util.Set; import java.util.Set;
import jakarta.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import javax.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.annotation.Excel; import com.ruoyi.common.core.annotation.Excel;

View File

@@ -2,7 +2,7 @@ package com.ruoyi.system.api.domain;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import jakarta.validation.constraints.*; import javax.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.ruoyi.common.core.annotation.Excel; import com.ruoyi.common.core.annotation.Excel;

View File

@@ -30,12 +30,6 @@ public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileServ
{ {
return R.fail("上传文件失败:" + throwable.getMessage()); return R.fail("上传文件失败:" + throwable.getMessage());
} }
@Override
public R<Boolean> delete(String fileUrl)
{
return R.fail("删除文件失败:" + throwable.getMessage());
}
}; };
} }
} }

View File

@@ -1,6 +1,6 @@
package com.ruoyi.auth.controller; package com.ruoyi.auth.controller;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;

View File

@@ -53,24 +53,12 @@
<artifactId>pagehelper-spring-boot-starter</artifactId> <artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency> </dependency>
<!-- Mybatis Spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
</dependency>
<!-- Hibernate Validator --> <!-- Hibernate Validator -->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId> <artifactId>spring-boot-starter-validation</artifactId>
</dependency> </dependency>
<!-- Spring Aop -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!-- Jackson --> <!-- Jackson -->
<dependency> <dependency>
<groupId>com.fasterxml.jackson.core</groupId> <groupId>com.fasterxml.jackson.core</groupId>
@@ -93,7 +81,6 @@
<dependency> <dependency>
<groupId>javax.xml.bind</groupId> <groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId> <artifactId>jaxb-api</artifactId>
<version>2.3.1</version>
</dependency> </dependency>
<!-- Apache Lang3 --> <!-- Apache Lang3 -->
@@ -116,8 +103,8 @@
<!-- Java Servlet --> <!-- Java Servlet -->
<dependency> <dependency>
<groupId>jakarta.servlet</groupId> <groupId>javax.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId> <artifactId>javax.servlet-api</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -51,8 +51,7 @@ public @interface Excel
/** /**
* BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN * BigDecimal 舍入规则 默认:BigDecimal.ROUND_HALF_EVEN
*/ */
@SuppressWarnings("deprecation") public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
/** /**
* 导出时在excel中每个列的高度 * 导出时在excel中每个列的高度

View File

@@ -87,16 +87,6 @@ public class Constants
*/ */
public static final String LOGIN_FAIL = "Error"; public static final String LOGIN_FAIL = "Error";
/**
* 所有权限标识
*/
public static final String ALL_PERMISSION = "*:*:*";
/**
* 管理员角色权限标识
*/
public static final String SUPER_ADMIN = "admin";
/** /**
* 当前记录起始索引 * 当前记录起始索引
*/ */
@@ -130,7 +120,7 @@ public class Constants
/** /**
* 自动识别json对象白名单配置仅允许解析的包名范围越小越安全 * 自动识别json对象白名单配置仅允许解析的包名范围越小越安全
*/ */
public static final String[] JSON_WHITELIST_STR = { "com.ruoyi" }; public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi" };
/** /**
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)

View File

@@ -8,10 +8,10 @@ import java.util.Collections;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import jakarta.servlet.ServletRequest; import javax.servlet.ServletRequest;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession; import javax.servlet.http.HttpSession;
import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpHeaders; import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus; import org.springframework.http.HttpStatus;

View File

@@ -1,9 +1,9 @@
package com.ruoyi.common.core.utils.bean; package com.ruoyi.common.core.utils.bean;
import java.util.Set; import java.util.Set;
import jakarta.validation.ConstraintViolation; import javax.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException; import javax.validation.ConstraintViolationException;
import jakarta.validation.Validator; import javax.validation.Validator;
/** /**
* bean对象属性验证 * bean对象属性验证

View File

@@ -8,8 +8,8 @@ import java.io.OutputStream;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
@@ -114,20 +114,20 @@ public class FileUtils
} }
/** /**
* 校验文件路径合法性(安全性与扩展名) * 检查文件是否可下载
* *
* @param fileUrl 待校验的文件地址 * @param resource 需要下载的文件
* @return true 正常 false 非法 * @return true 正常 false 非法
*/ */
public static boolean validateFilePath(String fileUrl) public static boolean checkAllowDownload(String resource)
{ {
// 禁止目录上跳级别 // 禁止目录上跳级别
if (StringUtils.contains(fileUrl, "..")) if (StringUtils.contains(resource, ".."))
{ {
return false; return false;
} }
// 判断是否在允许下载的文件规则内 // 判断是否在允许下载的文件规则内
return ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(fileUrl)); return ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource));
} }
/** /**

View File

@@ -2,7 +2,7 @@ package com.ruoyi.common.core.utils.ip;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import com.ruoyi.common.core.utils.ServletUtils; import com.ruoyi.common.core.utils.ServletUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;

View File

@@ -19,7 +19,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.RegExUtils; import org.apache.commons.lang3.RegExUtils;
import org.apache.commons.lang3.reflect.FieldUtils; import org.apache.commons.lang3.reflect.FieldUtils;
@@ -73,8 +73,6 @@ public class ExcelUtil<T>
{ {
private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class); private static final Logger log = LoggerFactory.getLogger(ExcelUtil.class);
public static final String SEPARATOR = ",";
public static final String FORMULA_REGEX_STR = "=|-|\\+|@"; public static final String FORMULA_REGEX_STR = "=|-|\\+|@";
public static final String[] FORMULA_STR = { "=", "-", "+", "@" }; public static final String[] FORMULA_STR = { "=", "-", "+", "@" };
@@ -147,18 +145,23 @@ public class ExcelUtil<T>
/** /**
* 对象的子列表方法 * 对象的子列表方法
*/ */
private Map<String, Method> subMethods; private Method subMethod;
/** /**
* 对象的子列表属性 * 对象的子列表属性
*/ */
private Map<String, List<Field>> subFieldsMap; private List<Field> subFields;
/** /**
* 统计列表 * 统计列表
*/ */
private Map<Integer, Double> statistics = new HashMap<Integer, Double>(); private Map<Integer, Double> statistics = new HashMap<Integer, Double>();
/**
* 数字格式
*/
private static final DecimalFormat DOUBLE_FORMAT = new DecimalFormat("######0.00");
/** /**
* 实体对象 * 实体对象
*/ */
@@ -225,10 +228,7 @@ public class ExcelUtil<T>
int titleLastCol = this.fields.size() - 1; int titleLastCol = this.fields.size() - 1;
if (isSubList()) if (isSubList())
{ {
for (List<Field> currentSubFields : subFieldsMap.values()) titleLastCol = titleLastCol + subFields.size() - 1;
{
titleLastCol = titleLastCol + currentSubFields.size() - 1;
}
} }
Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0); Row titleRow = sheet.createRow(rownum == 0 ? rownum++ : 0);
titleRow.setHeightInPoints(30); titleRow.setHeightInPoints(30);
@@ -248,17 +248,16 @@ public class ExcelUtil<T>
{ {
Row subRow = sheet.createRow(rownum); Row subRow = sheet.createRow(rownum);
int column = 0; int column = 0;
int subFieldSize = subFields != null ? subFields.size() : 0;
for (Object[] objects : fields) for (Object[] objects : fields)
{ {
Field field = (Field) objects[0]; Field field = (Field) objects[0];
Excel attr = (Excel) objects[1]; Excel attr = (Excel) objects[1];
CellStyle cellStyle = styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor()));
if (Collection.class.isAssignableFrom(field.getType())) if (Collection.class.isAssignableFrom(field.getType()))
{ {
Cell cell = subRow.createCell(column); Cell cell = subRow.createCell(column);
cell.setCellValue(attr.name()); cell.setCellValue(attr.name());
cell.setCellStyle(cellStyle); cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
int subFieldSize = subFieldsMap != null ? subFieldsMap.get(field.getName()).size() : 0;
if (subFieldSize > 1) if (subFieldSize > 1)
{ {
CellRangeAddress cellAddress = new CellRangeAddress(rownum, rownum, column, column + subFieldSize - 1); CellRangeAddress cellAddress = new CellRangeAddress(rownum, rownum, column, column + subFieldSize - 1);
@@ -270,7 +269,7 @@ public class ExcelUtil<T>
{ {
Cell cell = subRow.createCell(column++); Cell cell = subRow.createCell(column++);
cell.setCellValue(attr.name()); cell.setCellValue(attr.name());
cell.setCellStyle(cellStyle); cell.setCellStyle(styles.get(StringUtils.format("header_{}_{}", attr.headerColor(), attr.headerBackgroundColor())));
} }
} }
rownum++; rownum++;
@@ -342,11 +341,7 @@ public class ExcelUtil<T>
Map<String, Integer> cellMap = new HashMap<String, Integer>(); Map<String, Integer> cellMap = new HashMap<String, Integer>();
// 获取表头 // 获取表头
Row heard = sheet.getRow(titleNum); Row heard = sheet.getRow(titleNum);
if (heard == null) for (int i = 0; i < heard.getPhysicalNumberOfCells(); i++)
{
throw new UtilException("文件标题行为空请检查Excel文件格式");
}
for (int i = 0; i < heard.getLastCellNum(); i++)
{ {
Cell cell = heard.getCell(i); Cell cell = heard.getCell(i);
if (StringUtils.isNotNull(cell)) if (StringUtils.isNotNull(cell))
@@ -354,6 +349,10 @@ public class ExcelUtil<T>
String value = this.getCellValue(heard, i).toString(); String value = this.getCellValue(heard, i).toString();
cellMap.put(value, i); cellMap.put(value, i);
} }
else
{
cellMap.put(null, i);
}
} }
// 有数据时才处理 得到类的所有field. // 有数据时才处理 得到类的所有field.
List<Object[]> fields = this.getFields(); List<Object[]> fields = this.getFields();
@@ -382,7 +381,7 @@ public class ExcelUtil<T>
Object val = this.getCellValue(row, entry.getKey()); Object val = this.getCellValue(row, entry.getKey());
// 如果不存在实例则新建. // 如果不存在实例则新建.
entity = (entity == null ? clazz.getDeclaredConstructor().newInstance() : entity); entity = (entity == null ? clazz.newInstance() : entity);
// 从map中得到对应列的field. // 从map中得到对应列的field.
Field field = (Field) entry.getValue()[0]; Field field = (Field) entry.getValue()[0];
Excel attr = (Excel) entry.getValue()[1]; Excel attr = (Excel) entry.getValue()[1];
@@ -566,8 +565,7 @@ public class ExcelUtil<T>
Excel excel = (Excel) os[1]; Excel excel = (Excel) os[1];
if (Collection.class.isAssignableFrom(field.getType())) if (Collection.class.isAssignableFrom(field.getType()))
{ {
List<Field> currentSubFields = subFieldsMap.get(field.getName()); for (Field subField : subFields)
for (Field subField : currentSubFields)
{ {
Excel subExcel = subField.getAnnotation(Excel.class); Excel subExcel = subField.getAnnotation(Excel.class);
this.createHeadCell(subExcel, row, column++); this.createHeadCell(subExcel, row, column++);
@@ -580,7 +578,7 @@ public class ExcelUtil<T>
} }
if (Type.EXPORT.equals(type)) if (Type.EXPORT.equals(type))
{ {
fillExcelData(index); fillExcelData(index, row);
addStatisticsRow(); addStatisticsRow();
} }
} }
@@ -590,9 +588,10 @@ public class ExcelUtil<T>
* 填充excel数据 * 填充excel数据
* *
* @param index 序号 * @param index 序号
* @param row 单元格行
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public void fillExcelData(int index) public void fillExcelData(int index, Row row)
{ {
int startNo = index * sheetSize; int startNo = index * sheetSize;
int endNo = Math.min(startNo + sheetSize, list.size()); int endNo = Math.min(startNo + sheetSize, list.size());
@@ -600,7 +599,7 @@ public class ExcelUtil<T>
for (int i = startNo; i < endNo; i++) for (int i = startNo; i < endNo; i++)
{ {
Row row = sheet.createRow(currentRowNum); row = sheet.createRow(currentRowNum);
T vo = (T) list.get(i); T vo = (T) list.get(i);
int column = 0; int column = 0;
int maxSubListSize = getCurrentMaxSubListSize(vo); int maxSubListSize = getCurrentMaxSubListSize(vo);
@@ -613,7 +612,6 @@ public class ExcelUtil<T>
try try
{ {
Collection<?> subList = (Collection<?>) getTargetValue(vo, field, excel); Collection<?> subList = (Collection<?>) getTargetValue(vo, field, excel);
List<Field> currentSubFields = subFieldsMap.get(field.getName());
if (subList != null && !subList.isEmpty()) if (subList != null && !subList.isEmpty())
{ {
int subIndex = 0; int subIndex = 0;
@@ -626,15 +624,15 @@ public class ExcelUtil<T>
} }
int subColumn = column; int subColumn = column;
for (Field subField : currentSubFields) for (Field subField : subFields)
{ {
Excel subExcel = subField.getAnnotation(Excel.class); Excel subExcel = subField.getAnnotation(Excel.class);
addCell(subExcel, subRow, (T) subVo, subField, subColumn++); addCell(subExcel, subRow, (T) subVo, subField, subColumn++);
} }
subIndex++; subIndex++;
} }
column += subFields.size();
} }
column += currentSubFields.size();
} }
catch (Exception e) catch (Exception e)
{ {
@@ -726,7 +724,6 @@ public class ExcelUtil<T>
style = wb.createCellStyle(); style = wb.createCellStyle();
style.setAlignment(HorizontalAlignment.CENTER); style.setAlignment(HorizontalAlignment.CENTER);
style.setVerticalAlignment(VerticalAlignment.CENTER); style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setDataFormat(dataFormat.getFormat("######0.00"));
Font totalFont = wb.createFont(); Font totalFont = wb.createFont();
totalFont.setFontName("Arial"); totalFont.setFontName("Arial");
totalFont.setFontHeightInPoints((short) 10); totalFont.setFontHeightInPoints((short) 10);
@@ -975,8 +972,7 @@ public class ExcelUtil<T>
/** /**
* 添加单元格 * 添加单元格
*/ */
@SuppressWarnings("deprecation") public Cell addCell(Excel attr, Row row, T vo, Field field, int column)
public Cell addCell(Excel attr, Row row, T vo, Field field, int column)
{ {
Cell cell = null; Cell cell = null;
try try
@@ -988,7 +984,7 @@ public class ExcelUtil<T>
{ {
// 创建cell // 创建cell
cell = row.createCell(column); cell = row.createCell(column);
if (isSubListValue(vo) && getListCellValue(vo) > 1 && attr.needMerge()) if (isSubListValue(vo) && getListCellValue(vo).size() > 1 && attr.needMerge())
{ {
if (subMergedLastRowNum >= subMergedFirstRowNum) if (subMergedLastRowNum >= subMergedFirstRowNum)
{ {
@@ -1085,36 +1081,18 @@ public class ExcelUtil<T>
public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol) public void setXSSFValidationWithHidden(Sheet sheet, String[] textlist, String promptContent, int firstRow, int endRow, int firstCol, int endCol)
{ {
String hideSheetName = "combo_" + firstCol + "_" + endCol; String hideSheetName = "combo_" + firstCol + "_" + endCol;
Sheet hideSheet = null; Sheet hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据
String hideSheetDataName = hideSheetName + "_data"; for (int i = 0; i < textlist.length; i++)
Name name = wb.getName(hideSheetDataName);
if (name != null)
{ {
// 名称已存在尝试从名称的引用中找到sheet名称 hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]);
String refersToFormula = name.getRefersToFormula();
if (StringUtils.isNotEmpty(refersToFormula) && refersToFormula.contains("!"))
{
String sheetNameFromFormula = refersToFormula.substring(0, refersToFormula.indexOf("!"));
hideSheet = wb.getSheet(sheetNameFromFormula);
}
} }
// 创建名称,可被其他单元格引用
if (hideSheet == null) Name name = wb.createName();
{ name.setNameName(hideSheetName + "_data");
hideSheet = wb.createSheet(hideSheetName); // 用于存储 下拉菜单数据 name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length);
for (int i = 0; i < textlist.length; i++)
{
hideSheet.createRow(i).createCell(0).setCellValue(textlist[i]);
}
// 创建名称,可被其他单元格引用
name = wb.createName();
name.setNameName(hideSheetDataName);
name.setRefersToFormula(hideSheetName + "!$A$1:$A$" + textlist.length);
}
DataValidationHelper helper = sheet.getDataValidationHelper(); DataValidationHelper helper = sheet.getDataValidationHelper();
// 加载下拉列表内容 // 加载下拉列表内容
DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetDataName); DataValidationConstraint constraint = helper.createFormulaListConstraint(hideSheetName + "_data");
// 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列 // 设置数据有效性加载在哪个单元格上,四个参数分别是:起始行、终止行、起始列、终止列
CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol); CellRangeAddressList regions = new CellRangeAddressList(firstRow, endRow, firstCol, endCol);
// 数据有效性对象 // 数据有效性对象
@@ -1152,7 +1130,7 @@ public class ExcelUtil<T>
public static String convertByExp(String propertyValue, String converterExp, String separator) public static String convertByExp(String propertyValue, String converterExp, String separator)
{ {
StringBuilder propertyString = new StringBuilder(); StringBuilder propertyString = new StringBuilder();
String[] convertSource = converterExp.split(SEPARATOR); String[] convertSource = converterExp.split(",");
for (String item : convertSource) for (String item : convertSource)
{ {
String[] itemArray = item.split("="); String[] itemArray = item.split("=");
@@ -1189,7 +1167,7 @@ public class ExcelUtil<T>
public static String reverseByExp(String propertyValue, String converterExp, String separator) public static String reverseByExp(String propertyValue, String converterExp, String separator)
{ {
StringBuilder propertyString = new StringBuilder(); StringBuilder propertyString = new StringBuilder();
String[] convertSource = converterExp.split(SEPARATOR); String[] convertSource = converterExp.split(",");
for (String item : convertSource) for (String item : convertSource)
{ {
String[] itemArray = item.split("="); String[] itemArray = item.split("=");
@@ -1226,7 +1204,7 @@ public class ExcelUtil<T>
{ {
try try
{ {
Object instance = excel.handler().getDeclaredConstructor().newInstance(); Object instance = excel.handler().newInstance();
Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class }); Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class });
value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb); value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb);
} }
@@ -1277,7 +1255,7 @@ public class ExcelUtil<T>
{ {
cell = row.createCell(key); cell = row.createCell(key);
cell.setCellStyle(styles.get("total")); cell.setCellStyle(styles.get("total"));
cell.setCellValue(statistics.get(key)); cell.setCellValue(DOUBLE_FORMAT.format(statistics.get(key)));
} }
statistics.clear(); statistics.clear();
} }
@@ -1352,8 +1330,6 @@ public class ExcelUtil<T>
{ {
List<Object[]> fields = new ArrayList<Object[]>(); List<Object[]> fields = new ArrayList<Object[]>();
List<Field> tempFields = new ArrayList<>(); List<Field> tempFields = new ArrayList<>();
subFieldsMap = new HashMap<>();
subMethods = new HashMap<>();
tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
if (StringUtils.isNotEmpty(includeFields)) if (StringUtils.isNotEmpty(includeFields))
@@ -1401,11 +1377,10 @@ public class ExcelUtil<T>
} }
if (Collection.class.isAssignableFrom(field.getType())) if (Collection.class.isAssignableFrom(field.getType()))
{ {
String fieldName = field.getName(); subMethod = getSubMethod(field.getName(), clazz);
subMethods.put(fieldName, getSubMethod(fieldName, clazz));
ParameterizedType pt = (ParameterizedType) field.getGenericType(); ParameterizedType pt = (ParameterizedType) field.getGenericType();
Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0]; Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
subFieldsMap.put(fieldName, FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class)); this.subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class);
} }
} }
@@ -1474,8 +1449,7 @@ public class ExcelUtil<T>
{ {
this.sheet = wb.createSheet(); this.sheet = wb.createSheet();
this.createTitle(); this.createTitle();
int actualIndex = wb.getSheetIndex(this.sheet); wb.setSheetName(index, sheetName + index);
wb.setSheetName(actualIndex, sheetName + index);
} }
} }
@@ -1600,7 +1574,7 @@ public class ExcelUtil<T>
*/ */
public boolean isSubList() public boolean isSubList()
{ {
return !StringUtils.isEmpty(subFieldsMap); return StringUtils.isNotNull(subFields) && subFields.size() > 0;
} }
/** /**
@@ -1608,32 +1582,24 @@ public class ExcelUtil<T>
*/ */
public boolean isSubListValue(T vo) public boolean isSubListValue(T vo)
{ {
return !StringUtils.isEmpty(subFieldsMap) && getListCellValue(vo) > 0; return StringUtils.isNotNull(subFields) && subFields.size() > 0 && StringUtils.isNotNull(getListCellValue(vo)) && getListCellValue(vo).size() > 0;
} }
/** /**
* 获取集合的值 * 获取集合的值
*/ */
public int getListCellValue(Object obj) public Collection<?> getListCellValue(Object obj)
{ {
Collection<?> value; Object value;
int max = 0;
try try
{ {
for (String s : subMethods.keySet()) value = subMethod.invoke(obj, new Object[] {});
{
value = (Collection<?>) subMethods.get(s).invoke(obj);
if (value.size() > max)
{
max = value.size();
}
}
} }
catch (Exception e) catch (Exception e)
{ {
return 0; return new ArrayList<Object>();
} }
return max; return (Collection<?>) value;
} }
/** /**

View File

@@ -310,8 +310,7 @@ public class ReflectUtils
/** /**
* 改变private/protected的方法为public尽量不调用实际改动的语句避免JDK的SecurityManager抱怨。 * 改变private/protected的方法为public尽量不调用实际改动的语句避免JDK的SecurityManager抱怨。
*/ */
@SuppressWarnings("deprecation") public static void makeAccessible(Method method)
public static void makeAccessible(Method method)
{ {
if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers())) if ((!Modifier.isPublic(method.getModifiers()) || !Modifier.isPublic(method.getDeclaringClass().getModifiers()))
&& !method.isAccessible()) && !method.isAccessible())
@@ -323,8 +322,7 @@ public class ReflectUtils
/** /**
* 改变private/protected的成员变量为public尽量不调用实际改动的语句避免JDK的SecurityManager抱怨。 * 改变private/protected的成员变量为public尽量不调用实际改动的语句避免JDK的SecurityManager抱怨。
*/ */
@SuppressWarnings("deprecation") public static void makeAccessible(Field field)
public static void makeAccessible(Field field)
{ {
if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers())
|| Modifier.isFinal(field.getModifiers())) && !field.isAccessible()) || Modifier.isFinal(field.getModifiers())) && !field.isAccessible())

View File

@@ -7,12 +7,17 @@ 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.PageInfo; import com.github.pagehelper.PageInfo;
import com.ruoyi.common.core.constant.HttpStatus; import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.utils.DateUtils; import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.PageUtils; import com.ruoyi.common.core.utils.PageUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.sql.SqlUtil;
import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.common.core.web.page.PageDomain;
import com.ruoyi.common.core.web.page.TableDataInfo; import com.ruoyi.common.core.web.page.TableDataInfo;
import com.ruoyi.common.core.web.page.TableSupport;
/** /**
* web层通用数据处理 * web层通用数据处理
@@ -48,6 +53,19 @@ public class BaseController
PageUtils.startPage(); PageUtils.startPage();
} }
/**
* 设置请求排序数据
*/
protected void startOrderBy()
{
PageDomain pageDomain = TableSupport.buildPageRequest();
if (StringUtils.isNotEmpty(pageDomain.getOrderBy()))
{
String orderBy = SqlUtil.escapeOrderBySql(pageDomain.getOrderBy());
PageHelper.orderBy(orderBy);
}
}
/** /**
* 清理分页的线程变量 * 清理分页的线程变量
*/ */

View File

@@ -1,7 +1,7 @@
package com.ruoyi.common.core.xss; package com.ruoyi.common.core.xss;
import jakarta.validation.Constraint; import javax.validation.Constraint;
import jakarta.validation.Payload; import javax.validation.Payload;
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;

View File

@@ -2,8 +2,8 @@ package com.ruoyi.common.core.xss;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import jakarta.validation.ConstraintValidator; import javax.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext; import javax.validation.ConstraintValidatorContext;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
/** /**

View File

@@ -94,7 +94,7 @@ public class DataScopeAspect
List<String> conditions = new ArrayList<String>(); List<String> conditions = new ArrayList<String>();
List<String> scopeCustomIds = new ArrayList<String>(); List<String> scopeCustomIds = new ArrayList<String>();
user.getRoles().forEach(role -> { user.getRoles().forEach(role -> {
if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && (StringUtils.isEmpty(permission) || StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))) if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.equals(role.getStatus(), UserConstants.ROLE_NORMAL) && StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
{ {
scopeCustomIds.add(Convert.toStr(role.getRoleId())); scopeCustomIds.add(Convert.toStr(role.getRoleId()));
} }
@@ -107,7 +107,7 @@ public class DataScopeAspect
{ {
continue; continue;
} }
if (StringUtils.isNotEmpty(permission) && !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission))) if (!StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
{ {
continue; continue;
} }

View File

@@ -20,14 +20,14 @@
<!-- Druid --> <!-- Druid -->
<dependency> <dependency>
<groupId>com.alibaba</groupId> <groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId> <artifactId>druid-spring-boot-starter</artifactId>
<version>${druid.version}</version> <version>${druid.version}</version>
</dependency> </dependency>
<!-- Dynamic DataSource --> <!-- Dynamic DataSource -->
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId> <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>${dynamic-ds.version}</version> <version>${dynamic-ds.version}</version>
</dependency> </dependency>

View File

@@ -2,8 +2,8 @@ package com.ruoyi.common.log.aspect;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import org.aspectj.lang.JoinPoint; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterReturning;
@@ -48,9 +48,6 @@ public class LogAspect
/** 计算操作消耗时间 */ /** 计算操作消耗时间 */
private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time"); private static final ThreadLocal<Long> TIME_THREADLOCAL = new NamedThreadLocal<Long>("Cost Time");
/** 参数最大长度限制 */
private static final int PARAM_MAX_LENGTH = 2000;
@Autowired @Autowired
private AsyncLogService asyncLogService; private AsyncLogService asyncLogService;
@@ -169,16 +166,16 @@ public class LogAspect
*/ */
private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception private void setRequestValue(JoinPoint joinPoint, SysOperLog operLog, String[] excludeParamNames) throws Exception
{ {
String requestMethod = operLog.getRequestMethod();
Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest()); Map<?, ?> paramsMap = ServletUtils.getParamMap(ServletUtils.getRequest());
String requestMethod = operLog.getRequestMethod();
if (StringUtils.isEmpty(paramsMap) && StringUtils.equalsAny(requestMethod, HttpMethod.PUT.name(), HttpMethod.POST.name(), HttpMethod.DELETE.name())) if (StringUtils.isEmpty(paramsMap) && StringUtils.equalsAny(requestMethod, HttpMethod.PUT.name(), HttpMethod.POST.name(), HttpMethod.DELETE.name()))
{ {
String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames); String params = argsArrayToString(joinPoint.getArgs(), excludeParamNames);
operLog.setOperParam(params); operLog.setOperParam(StringUtils.substring(params, 0, 2000));
} }
else else
{ {
operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, PARAM_MAX_LENGTH)); operLog.setOperParam(StringUtils.substring(JSON.toJSONString(paramsMap, excludePropertyPreFilter(excludeParamNames)), 0, 2000));
} }
} }
@@ -187,7 +184,7 @@ public class LogAspect
*/ */
private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames) private String argsArrayToString(Object[] paramsArray, String[] excludeParamNames)
{ {
StringBuilder params = new StringBuilder(); String params = "";
if (paramsArray != null && paramsArray.length > 0) if (paramsArray != null && paramsArray.length > 0)
{ {
for (Object o : paramsArray) for (Object o : paramsArray)
@@ -197,20 +194,15 @@ public class LogAspect
try try
{ {
String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames)); String jsonObj = JSON.toJSONString(o, excludePropertyPreFilter(excludeParamNames));
params.append(jsonObj).append(" "); params += jsonObj.toString() + " ";
if (params.length() >= PARAM_MAX_LENGTH)
{
return StringUtils.substring(params.toString(), 0, PARAM_MAX_LENGTH);
}
} }
catch (Exception e) catch (Exception e)
{ {
log.error("请求参数拼装异常 msg:{}, 参数:{}", e.getMessage(), paramsArray, e);
} }
} }
} }
} }
return params.toString(); return params.trim();
} }
/** /**

View File

@@ -18,7 +18,6 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration @Configuration
@EnableCaching @EnableCaching
@AutoConfigureBefore(RedisAutoConfiguration.class) @AutoConfigureBefore(RedisAutoConfiguration.class)
@SuppressWarnings("deprecation")
public class RedisConfig extends CachingConfigurerSupport public class RedisConfig extends CachingConfigurerSupport
{ {
@Bean @Bean

View File

@@ -1,7 +1,7 @@
package com.ruoyi.common.security.feign; package com.ruoyi.common.security.feign;
import java.util.Map; import java.util.Map;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.utils.ServletUtils; import com.ruoyi.common.core.utils.ServletUtils;

View File

@@ -1,6 +1,6 @@
package com.ruoyi.common.security.handler; package com.ruoyi.common.security.handler;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException; import org.springframework.validation.BindException;

View File

@@ -1,7 +1,7 @@
package com.ruoyi.common.security.interceptor; package com.ruoyi.common.security.interceptor;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.AsyncHandlerInterceptor; import org.springframework.web.servlet.AsyncHandlerInterceptor;
import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.constant.SecurityConstants;

View File

@@ -3,7 +3,7 @@ package com.ruoyi.common.security.service;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
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;

View File

@@ -1,6 +1,6 @@
package com.ruoyi.common.security.utils; package com.ruoyi.common.security.utils;
import jakarta.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.ruoyi.common.core.constant.SecurityConstants; import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.constant.TokenConstants; import com.ruoyi.common.core.constant.TokenConstants;

View File

@@ -26,7 +26,7 @@
<!-- SpringDoc webmvc --> <!-- SpringDoc webmvc -->
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId> <artifactId>springdoc-openapi-ui</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@@ -2,8 +2,6 @@ package com.ruoyi.common.swagger.config;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.springdoc.core.configuration.SpringDocConfiguration;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
@@ -21,7 +19,6 @@ import io.swagger.v3.oas.models.servers.Server;
* *
* @author ruoyi * @author ruoyi
*/ */
@AutoConfiguration(before = SpringDocConfiguration.class)
@EnableConfigurationProperties(SpringDocProperties.class) @EnableConfigurationProperties(SpringDocProperties.class)
@ConditionalOnProperty(name = "springdoc.api-docs.enabled", havingValue = "true", matchIfMissing = true) @ConditionalOnProperty(name = "springdoc.api-docs.enabled", havingValue = "true", matchIfMissing = true)
public class SpringDocAutoConfiguration public class SpringDocAutoConfiguration

View File

@@ -79,7 +79,7 @@
<!-- Springdoc --> <!-- Springdoc -->
<dependency> <dependency>
<groupId>org.springdoc</groupId> <groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webflux-ui</artifactId> <artifactId>springdoc-openapi-webflux-ui</artifactId>
<version>${springdoc.version}</version> <version>${springdoc.version}</version>
</dependency> </dependency>

View File

@@ -2,8 +2,8 @@ package com.ruoyi.gateway.config;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.springdoc.core.properties.AbstractSwaggerUiConfigProperties; import org.springdoc.core.AbstractSwaggerUiConfigProperties;
import org.springdoc.core.properties.SwaggerUiConfigProperties; import org.springdoc.core.SwaggerUiConfigProperties;
import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;

View File

@@ -64,7 +64,6 @@ public class ValidateCodeFilter extends AbstractGatewayFilterFactory<Object>
}; };
} }
@SuppressWarnings("deprecation")
private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest) private String resolveBodyFromRequest(ServerHttpRequest serverHttpRequest)
{ {
// 获取请求体 // 获取请求体

View File

@@ -3,7 +3,7 @@ package com.ruoyi.gateway.service.impl;
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 jakarta.annotation.Resource; import javax.annotation.Resource;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;

View File

@@ -46,6 +46,12 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
</dependency> </dependency>
<!-- FastDFS -->
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
</dependency>
<!-- Minio --> <!-- Minio -->
<dependency> <dependency>

View File

@@ -1,46 +0,0 @@
package com.ruoyi.file.config;
import java.util.HashMap;
import java.util.Map;
import jakarta.servlet.DispatcherType;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.ruoyi.file.filter.RefererFilter;
/**
* Filter配置
*
* @author ruoyi
*/
@Configuration
public class FilterConfig
{
/**
* 资源映射路径 前缀
*/
@Value("${file.prefix}")
public String localFilePrefix;
@Value("${referer.allowed-domains}")
private String allowedDomains;
@SuppressWarnings({"rawtypes", "unchecked"})
@Bean
@ConditionalOnProperty(value = "referer.enabled", havingValue = "true")
public FilterRegistrationBean refererFilterRegistration()
{
FilterRegistrationBean registration = new FilterRegistrationBean();
registration.setDispatcherTypes(DispatcherType.REQUEST);
registration.setFilter(new RefererFilter());
registration.addUrlPatterns(localFilePrefix + "/*");
registration.setName("refererFilter");
registration.setOrder(FilterRegistrationBean.HIGHEST_PRECEDENCE);
Map<String, String> initParameters = new HashMap<String, String>();
initParameters.put("allowedDomains", allowedDomains);
registration.setInitParameters(initParameters);
return registration;
}
}

View File

@@ -3,12 +3,10 @@ package com.ruoyi.file.controller;
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.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
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.core.domain.R; import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.file.FileUtils; import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.file.service.ISysFileService; import com.ruoyi.file.service.ISysFileService;
import com.ruoyi.system.api.domain.SysFile; import com.ruoyi.system.api.domain.SysFile;
@@ -47,26 +45,4 @@ public class SysFileController
return R.fail(e.getMessage()); return R.fail(e.getMessage());
} }
} }
}
/**
* 文件删除请求
*/
@DeleteMapping("delete")
public R<Boolean> delete(String fileUrl)
{
try
{
if (!FileUtils.validateFilePath(fileUrl))
{
throw new Exception(StringUtils.format("资源文件({})非法,不允许删除。 ", fileUrl));
}
sysFileService.deleteFile(fileUrl);
return R.ok();
}
catch (Exception e)
{
log.error("删除文件失败", e);
return R.fail(e.getMessage());
}
}
}

View File

@@ -1,77 +0,0 @@
package com.ruoyi.file.filter;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import jakarta.servlet.Filter;
import jakarta.servlet.FilterChain;
import jakarta.servlet.FilterConfig;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletRequest;
import jakarta.servlet.ServletResponse;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
/**
* 防盗链过滤器
*
* @author ruoyi
*/
public class RefererFilter implements Filter
{
/**
* 允许的域名列表
*/
public List<String> allowedDomains;
@Override
public void init(FilterConfig filterConfig) throws ServletException
{
String domains = filterConfig.getInitParameter("allowedDomains");
this.allowedDomains = Arrays.asList(domains.split(","));
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException
{
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
String referer = req.getHeader("Referer");
// 如果Referer为空拒绝访问
if (referer == null || referer.isEmpty())
{
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied: Referer header is required");
return;
}
// 检查Referer是否在允许的域名列表中
boolean allowed = false;
for (String domain : allowedDomains)
{
if (referer.contains(domain))
{
allowed = true;
break;
}
}
// 根据检查结果决定是否放行
if (allowed)
{
chain.doFilter(request, response);
}
else
{
resp.sendError(HttpServletResponse.SC_FORBIDDEN, "Access denied: Referer '" + referer + "' is not allowed");
}
}
@Override
public void destroy()
{
}
}

View File

@@ -0,0 +1,56 @@
package com.ruoyi.file.service;
import java.io.InputStream;
import com.alibaba.nacos.common.utils.IoUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.ruoyi.common.core.utils.file.FileTypeUtils;
/**
* FastDFS 文件存储
*
* @author ruoyi
*/
@Service
public class FastDfsSysFileServiceImpl implements ISysFileService
{
/**
* 域名或本机访问地址
*/
@Value("${fdfs.domain}")
public String domain;
@Autowired
private FastFileStorageClient storageClient;
/**
* FastDfs文件上传接口
*
* @param file 上传的文件
* @return 访问地址
* @throws Exception
*/
@Override
public String uploadFile(MultipartFile file) throws Exception
{
InputStream inputStream = null;
try
{
inputStream = file.getInputStream();
StorePath storePath = storageClient.uploadFile(inputStream, file.getSize(), FileTypeUtils.getExtension(file), null);
return domain + "/" + storePath.getFullPath();
}
catch (Exception e)
{
throw new RuntimeException("FastDfs Failed to upload file", e);
}
finally
{
IoUtils.closeQuietly(inputStream);
}
}
}

View File

@@ -17,12 +17,4 @@ public interface ISysFileService
* @throws Exception * @throws Exception
*/ */
public String uploadFile(MultipartFile file) throws Exception; public String uploadFile(MultipartFile file) throws Exception;
/**
* 文件删除接口
*
* @param fileUrl 文件访问URL
* @throws Exception
*/
public void deleteFile(String fileUrl) throws Exception;
} }

View File

@@ -4,8 +4,6 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.utils.file.FileUtils;
import com.ruoyi.file.utils.FileUploadUtils; import com.ruoyi.file.utils.FileUploadUtils;
/** /**
@@ -49,17 +47,4 @@ public class LocalSysFileServiceImpl implements ISysFileService
String url = domain + localFilePrefix + name; String url = domain + localFilePrefix + name;
return url; return url;
} }
/**
* 本地文件删除接口
*
* @param fileUrl 文件访问URL
* @throws Exception
*/
@Override
public void deleteFile(String fileUrl) throws Exception
{
String localFile = StringUtils.substringAfter(fileUrl, localFilePrefix);
FileUtils.deleteFile(localFilePath + localFile);
}
} }

View File

@@ -5,12 +5,10 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.alibaba.nacos.common.utils.IoUtils; import com.alibaba.nacos.common.utils.IoUtils;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.file.config.MinioConfig; import com.ruoyi.file.config.MinioConfig;
import com.ruoyi.file.utils.FileUploadUtils; import com.ruoyi.file.utils.FileUploadUtils;
import io.minio.MinioClient; import io.minio.MinioClient;
import io.minio.PutObjectArgs; import io.minio.PutObjectArgs;
import io.minio.RemoveObjectArgs;
/** /**
* Minio 文件存储 * Minio 文件存储
@@ -59,24 +57,4 @@ public class MinioSysFileServiceImpl implements ISysFileService
IoUtils.closeQuietly(inputStream); IoUtils.closeQuietly(inputStream);
} }
} }
/**
* Minio文件删除接口
*
* @param fileUrl 文件访问URL
* @throws Exception
*/
@Override
public void deleteFile(String fileUrl) throws Exception
{
try
{
String minioFile = StringUtils.substringAfter(fileUrl, minioConfig.getBucketName());
client.removeObject(RemoveObjectArgs.builder().bucket(minioConfig.getBucketName()).object(minioFile).build());
}
catch (Exception e)
{
throw new RuntimeException("Minio Failed to delete file", e);
}
}
} }

View File

@@ -4,7 +4,7 @@ import java.io.IOException;
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 jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;

View File

@@ -1,8 +1,8 @@
package com.ruoyi.gen.domain; package com.ruoyi.gen.domain;
import java.util.List; import java.util.List;
import jakarta.validation.Valid; import javax.validation.Valid;
import jakarta.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import org.apache.commons.lang3.ArrayUtils; import org.apache.commons.lang3.ArrayUtils;
import com.ruoyi.common.core.constant.GenConstants; import com.ruoyi.common.core.constant.GenConstants;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;

View File

@@ -1,6 +1,6 @@
package com.ruoyi.gen.domain; package com.ruoyi.gen.domain;
import jakarta.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.BaseEntity; import com.ruoyi.common.core.web.domain.BaseEntity;

View File

@@ -2,7 +2,7 @@ package ${packageName}.controller;
import java.util.List; import java.util.List;
import java.io.IOException; import java.io.IOException;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
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;

View File

@@ -334,7 +334,7 @@ function getList() {
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
if (null != daterange${AttrName}.value && '' != daterange${AttrName}.value) { if (null != daterange${AttrName} && '' != daterange${AttrName}) {
queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0] queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0]
queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1] queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1]
} }

View File

@@ -415,7 +415,7 @@ function getList() {
#foreach ($column in $columns) #foreach ($column in $columns)
#if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
if (null != daterange${AttrName}.value && '' != daterange${AttrName}.value) { if (null != daterange${AttrName} && '' != daterange${AttrName}) {
queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0] queryParams.value.params["begin${AttrName}"] = daterange${AttrName}.value[0]
queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1] queryParams.value.params["end${AttrName}"] = daterange${AttrName}.value[1]
} }

View File

@@ -1,7 +1,7 @@
package com.ruoyi.job.controller; package com.ruoyi.job.controller;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.quartz.SchedulerException; import org.quartz.SchedulerException;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;

View File

@@ -1,7 +1,7 @@
package com.ruoyi.job.controller; package com.ruoyi.job.controller;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
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;

View File

@@ -1,8 +1,8 @@
package com.ruoyi.job.domain; package com.ruoyi.job.domain;
import java.util.Date; import java.util.Date;
import jakarta.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size; import javax.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.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonFormat;

View File

@@ -1,7 +1,7 @@
package com.ruoyi.job.service; package com.ruoyi.job.service;
import java.util.List; import java.util.List;
import jakarta.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.quartz.JobDataMap; import org.quartz.JobDataMap;
import org.quartz.JobKey; import org.quartz.JobKey;
import org.quartz.Scheduler; import org.quartz.Scheduler;

View File

@@ -131,11 +131,11 @@ public class ScheduleUtils
int count = StringUtils.countMatches(packageName, "."); int count = StringUtils.countMatches(packageName, ".");
if (count > 1) if (count > 1)
{ {
return StringUtils.startsWithAny(invokeTarget, Constants.JOB_WHITELIST_STR); return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR);
} }
Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]); Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]);
String beanPackageName = obj.getClass().getPackage().getName(); String beanPackageName = obj.getClass().getPackage().getName();
return StringUtils.startsWithAny(beanPackageName, Constants.JOB_WHITELIST_STR) return StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_WHITELIST_STR)
&& !StringUtils.startsWithAny(beanPackageName, Constants.JOB_ERROR_STR); && !StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_ERROR_STR);
} }
} }

View File

@@ -1,7 +1,7 @@
package com.ruoyi.system.controller; package com.ruoyi.system.controller;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
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;

View File

@@ -2,7 +2,7 @@ package com.ruoyi.system.controller;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
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;

View File

@@ -1,7 +1,7 @@
package com.ruoyi.system.controller; package com.ruoyi.system.controller;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
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;

View File

@@ -1,7 +1,7 @@
package com.ruoyi.system.controller; package com.ruoyi.system.controller;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
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;

View File

@@ -1,7 +1,7 @@
package com.ruoyi.system.controller; package com.ruoyi.system.controller;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
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;

View File

@@ -1,7 +1,7 @@
package com.ruoyi.system.controller; package com.ruoyi.system.controller;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
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;

View File

@@ -100,7 +100,7 @@ public class SysProfileController extends BaseController
String oldPassword = params.get("oldPassword"); String oldPassword = params.get("oldPassword");
String newPassword = params.get("newPassword"); String newPassword = params.get("newPassword");
LoginUser loginUser = SecurityUtils.getLoginUser(); LoginUser loginUser = SecurityUtils.getLoginUser();
Long userId = loginUser.getUserid(); String userName = loginUser.getUsername();
String password = loginUser.getSysUser().getPassword(); String password = loginUser.getSysUser().getPassword();
if (!SecurityUtils.matchesPassword(oldPassword, password)) if (!SecurityUtils.matchesPassword(oldPassword, password))
{ {
@@ -111,7 +111,7 @@ public class SysProfileController extends BaseController
return error("新密码不能与旧密码相同"); return error("新密码不能与旧密码相同");
} }
newPassword = SecurityUtils.encryptPassword(newPassword); newPassword = SecurityUtils.encryptPassword(newPassword);
if (userService.resetUserPwd(userId, newPassword) > 0) if (userService.resetUserPwd(userName, newPassword) > 0)
{ {
// 更新缓存用户密码&密码最后更新时间 // 更新缓存用户密码&密码最后更新时间
loginUser.getSysUser().setPwdUpdateDate(DateUtils.getNowDate()); loginUser.getSysUser().setPwdUpdateDate(DateUtils.getNowDate());
@@ -143,13 +143,8 @@ public class SysProfileController extends BaseController
return error("文件服务异常,请联系管理员"); return error("文件服务异常,请联系管理员");
} }
String url = fileResult.getData().getUrl(); String url = fileResult.getData().getUrl();
if (userService.updateUserAvatar(loginUser.getUserid(), url)) if (userService.updateUserAvatar(loginUser.getUsername(), url))
{ {
String oldAvatarUrl = loginUser.getSysUser().getAvatar();
if (StringUtils.isNotEmpty(oldAvatarUrl))
{
remoteFileService.delete(oldAvatarUrl);
}
AjaxResult ajax = AjaxResult.success(); AjaxResult ajax = AjaxResult.success();
ajax.put("imgUrl", url); ajax.put("imgUrl", url);
// 更新缓存用户头像 // 更新缓存用户头像

View File

@@ -1,7 +1,7 @@
package com.ruoyi.system.controller; package com.ruoyi.system.controller;
import java.util.List; import java.util.List;
import jakarta.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
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;

View File

@@ -5,7 +5,7 @@ import java.util.Date;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.servlet.http.HttpServletResponse; import javax.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.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
@@ -163,7 +163,7 @@ public class SysUserController extends BaseController
@PutMapping("/recordlogin") @PutMapping("/recordlogin")
public R<Boolean> recordlogin(@RequestBody SysUser sysUser) public R<Boolean> recordlogin(@RequestBody SysUser sysUser)
{ {
return R.ok(userService.updateLoginInfo(sysUser)); return R.ok(userService.updateUserProfile(sysUser));
} }
/** /**

View File

@@ -1,7 +1,7 @@
package com.ruoyi.system.domain; package com.ruoyi.system.domain;
import jakarta.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size; import javax.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.annotation.Excel; import com.ruoyi.common.core.annotation.Excel;

View File

@@ -2,9 +2,9 @@ package com.ruoyi.system.domain;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import jakarta.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import javax.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.web.domain.BaseEntity; import com.ruoyi.common.core.web.domain.BaseEntity;

View File

@@ -1,7 +1,7 @@
package com.ruoyi.system.domain; package com.ruoyi.system.domain;
import jakarta.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size; import javax.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.web.domain.BaseEntity; import com.ruoyi.common.core.web.domain.BaseEntity;

View File

@@ -1,8 +1,8 @@
package com.ruoyi.system.domain; package com.ruoyi.system.domain;
import jakarta.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import javax.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.annotation.Excel; import com.ruoyi.common.core.annotation.Excel;

View File

@@ -70,37 +70,20 @@ public interface SysUserMapper
/** /**
* 修改用户头像 * 修改用户头像
* *
* @param userId 用户ID * @param userName 用户
* @param avatar 头像地址 * @param avatar 头像地址
* @return 结果 * @return 结果
*/ */
public int updateUserAvatar(@Param("userId") Long userId, @Param("avatar") String avatar); public int updateUserAvatar(@Param("userName") String userName, @Param("avatar") String avatar);
/**
* 修改用户状态
*
* @param userId 用户ID
* @param status 状态
* @return 结果
*/
public int updateUserStatus(@Param("userId") Long userId, @Param("status") String status);
/**
* 更新用户登录信息IP和登录时间
*
* @param user 用户信息
* @return 结果
*/
public int updateLoginInfo(SysUser user);
/** /**
* 重置用户密码 * 重置用户密码
* *
* @param userId 用户ID * @param userName 用户
* @param password 密码 * @param password 密码
* @return 结果 * @return 结果
*/ */
public int resetUserPwd(@Param("userId") Long userId, @Param("password") String password); public int resetUserPwd(@Param("userName") String userName, @Param("password") String password);
/** /**
* 通过用户ID删除用户 * 通过用户ID删除用户

View File

@@ -155,19 +155,11 @@ public interface ISysUserService
/** /**
* 修改用户头像 * 修改用户头像
* *
* @param userId 用户ID * @param userName 用户
* @param avatar 头像地址 * @param avatar 头像地址
* @return 结果 * @return 结果
*/ */
public boolean updateUserAvatar(Long userId, String avatar); public boolean updateUserAvatar(String userName, String avatar);
/**
* 更新用户登录信息IP和登录时间
*
* @param user 用户信息
* @return 结果
*/
public boolean updateLoginInfo(SysUser user);
/** /**
* 重置用户密码 * 重置用户密码
@@ -180,11 +172,11 @@ public interface ISysUserService
/** /**
* 重置用户密码 * 重置用户密码
* *
* @param userId 用户ID * @param userName 用户
* @param password 密码 * @param password 密码
* @return 结果 * @return 结果
*/ */
public int resetUserPwd(Long userId, String password); public int resetUserPwd(String userName, String password);
/** /**
* 通过用户ID删除用户 * 通过用户ID删除用户

View File

@@ -2,7 +2,7 @@ package com.ruoyi.system.service.impl;
import java.util.Collection; import java.util.Collection;
import java.util.List; import java.util.List;
import jakarta.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.common.core.constant.CacheConstants; import com.ruoyi.common.core.constant.CacheConstants;

View File

@@ -4,7 +4,7 @@ import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.annotation.PostConstruct; import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;

View File

@@ -6,7 +6,6 @@ import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.constant.UserConstants; import com.ruoyi.common.core.constant.UserConstants;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.system.api.domain.SysRole; import com.ruoyi.system.api.domain.SysRole;
@@ -42,7 +41,7 @@ public class SysPermissionServiceImpl implements ISysPermissionService
// 管理员拥有所有权限 // 管理员拥有所有权限
if (user.isAdmin()) if (user.isAdmin())
{ {
roles.add(Constants.SUPER_ADMIN); roles.add("admin");
} }
else else
{ {
@@ -64,7 +63,7 @@ public class SysPermissionServiceImpl implements ISysPermissionService
// 管理员拥有所有权限 // 管理员拥有所有权限
if (user.isAdmin()) if (user.isAdmin())
{ {
perms.add(Constants.ALL_PERMISSION); perms.add("*:*:*");
} }
else else
{ {

View File

@@ -3,7 +3,7 @@ package com.ruoyi.system.service.impl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import jakarta.validation.Validator; import javax.validation.Validator;
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;
@@ -326,7 +326,7 @@ public class SysUserServiceImpl implements ISysUserService
@Override @Override
public int updateUserStatus(SysUser user) public int updateUserStatus(SysUser user)
{ {
return userMapper.updateUserStatus(user.getUserId(), user.getStatus()); return userMapper.updateUser(user);
} }
/** /**
@@ -344,25 +344,14 @@ public class SysUserServiceImpl implements ISysUserService
/** /**
* 修改用户头像 * 修改用户头像
* *
* @param userId 用户ID * @param userName 用户
* @param avatar 头像地址 * @param avatar 头像地址
* @return 结果 * @return 结果
*/ */
@Override @Override
public boolean updateUserAvatar(Long userId, String avatar) public boolean updateUserAvatar(String userName, String avatar)
{ {
return userMapper.updateUserAvatar(userId, avatar) > 0; return userMapper.updateUserAvatar(userName, avatar) > 0;
}
/**
* 更新用户登录信息IP和登录时间
*
* @param user 用户信息
* @return 结果
*/
public boolean updateLoginInfo(SysUser user)
{
return userMapper.updateLoginInfo(user) > 0;
} }
/** /**
@@ -374,20 +363,20 @@ public class SysUserServiceImpl implements ISysUserService
@Override @Override
public int resetPwd(SysUser user) public int resetPwd(SysUser user)
{ {
return userMapper.resetUserPwd(user.getUserId(), user.getPassword()); return userMapper.updateUser(user);
} }
/** /**
* 重置用户密码 * 重置用户密码
* *
* @param userId 用户ID * @param userName 用户
* @param password 密码 * @param password 密码
* @return 结果 * @return 结果
*/ */
@Override @Override
public int resetUserPwd(Long userId, String password) public int resetUserPwd(String userName, String password)
{ {
return userMapper.resetUserPwd(userId, password); return userMapper.resetUserPwd(userName, password);
} }
/** /**
@@ -528,7 +517,6 @@ public class SysUserServiceImpl implements ISysUserService
checkUserDataScope(u.getUserId()); checkUserDataScope(u.getUserId());
deptService.checkDeptDataScope(user.getDeptId()); deptService.checkDeptDataScope(user.getDeptId());
user.setUserId(u.getUserId()); user.setUserId(u.getUserId());
user.setDeptId(u.getDeptId());
user.setUpdateBy(operName); user.setUpdateBy(operName);
userMapper.updateUser(user); userMapper.updateUser(user);
successNum++; successNum++;

View File

@@ -19,13 +19,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="loginIp" column="login_ip" /> <result property="loginIp" column="login_ip" />
<result property="loginDate" column="login_date" /> <result property="loginDate" column="login_date" />
<result property="pwdUpdateDate" column="pwd_update_date" /> <result property="pwdUpdateDate" column="pwd_update_date" />
<result property="createBy" column="create_by" /> <result property="createBy" column="create_by" />
<result property="createTime" column="create_time" /> <result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" /> <result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" /> <result property="updateTime" column="update_time" />
<result property="remark" column="remark" /> <result property="remark" column="remark" />
<association property="dept" javaType="SysDept" resultMap="deptResult" /> <association property="dept" javaType="SysDept" resultMap="deptResult" />
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" /> <collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
</resultMap> </resultMap>
<resultMap id="deptResult" type="SysDept"> <resultMap id="deptResult" type="SysDept">
@@ -180,7 +180,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<update id="updateUser" parameterType="SysUser"> <update id="updateUser" parameterType="SysUser">
update sys_user update sys_user
<set> <set>
<if test="deptId != 0">dept_id = #{deptId},</if> <if test="deptId != null and deptId != 0">dept_id = #{deptId},</if>
<if test="nickName != null and nickName != ''">nick_name = #{nickName},</if> <if test="nickName != null and nickName != ''">nick_name = #{nickName},</if>
<if test="email != null ">email = #{email},</if> <if test="email != null ">email = #{email},</if>
<if test="phonenumber != null ">phonenumber = #{phonenumber},</if> <if test="phonenumber != null ">phonenumber = #{phonenumber},</if>
@@ -198,19 +198,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</update> </update>
<update id="updateUserStatus" parameterType="SysUser"> <update id="updateUserStatus" parameterType="SysUser">
update sys_user set status = #{status}, update_time = sysdate() where user_id = #{userId} update sys_user set status = #{status} where user_id = #{userId}
</update> </update>
<update id="updateUserAvatar" parameterType="SysUser"> <update id="updateUserAvatar" parameterType="SysUser">
update sys_user set avatar = #{avatar}, update_time = sysdate() where user_id = #{userId} update sys_user set avatar = #{avatar} where user_name = #{userName}
</update>
<update id="updateLoginInfo" parameterType="SysUser">
update sys_user set login_ip = #{loginIp}, login_date = #{loginDate} where user_id = #{userId}
</update> </update>
<update id="resetUserPwd" parameterType="SysUser"> <update id="resetUserPwd" parameterType="SysUser">
update sys_user set pwd_update_date = sysdate(), password = #{password}, update_time = sysdate() where user_id = #{userId} update sys_user set pwd_update_date = sysdate(), password = #{password} where user_name = #{userName}
</update> </update>
<delete id="deleteUserById" parameterType="Long"> <delete id="deleteUserById" parameterType="Long">

View File

@@ -7,7 +7,7 @@
<el-tooltip class="item" effect="dark" content="刷新" placement="top"> <el-tooltip class="item" effect="dark" content="刷新" placement="top">
<el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" /> <el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
</el-tooltip> </el-tooltip>
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="Object.keys(columns).length > 0"> <el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
<el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/> <el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/>
<el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'"> <el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'">
<el-button size="mini" circle icon="el-icon-menu" /> <el-button size="mini" circle icon="el-icon-menu" />
@@ -17,9 +17,9 @@
<el-checkbox :indeterminate="isIndeterminate" v-model="isChecked" @change="toggleCheckAll"> 列展示 </el-checkbox> <el-checkbox :indeterminate="isIndeterminate" v-model="isChecked" @change="toggleCheckAll"> 列展示 </el-checkbox>
</el-dropdown-item> </el-dropdown-item>
<div class="check-line"></div> <div class="check-line"></div>
<template v-for="(item, key) in columns"> <template v-for="item in columns">
<el-dropdown-item :key="key"> <el-dropdown-item :key="item.key">
<el-checkbox v-model="item.visible" @change="checkboxChange($event, key)" :label="item.label" /> <el-checkbox v-model="item.visible" @change="checkboxChange($event, item.label)" :label="item.label" />
</el-dropdown-item> </el-dropdown-item>
</template> </template>
</el-dropdown-menu> </el-dropdown-menu>
@@ -30,13 +30,12 @@
<el-transfer <el-transfer
:titles="['显示', '隐藏']" :titles="['显示', '隐藏']"
v-model="value" v-model="value"
:data="transferData" :data="columns"
@change="dataChange" @change="dataChange"
></el-transfer> ></el-transfer>
</el-dialog> </el-dialog>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
name: "RightToolbar", name: "RightToolbar",
@@ -56,10 +55,9 @@ export default {
type: Boolean, type: Boolean,
default: true default: true
}, },
/* 显隐列信息(数组格式、对象格式) */ /* 显隐列信息 */
columns: { columns: {
type: [Array, Object], type: Array
default: () => ({})
}, },
/* 是否显示检索图标 */ /* 是否显示检索图标 */
search: { search: {
@@ -87,36 +85,21 @@ export default {
}, },
isChecked: { isChecked: {
get() { get() {
return Array.isArray(this.columns) ? this.columns.every((col) => col.visible) : Object.values(this.columns).every((col) => col.visible) return this.columns.every((col) => col.visible)
}, },
set() {} set() {}
}, },
isIndeterminate() { isIndeterminate() {
return Array.isArray(this.columns) ? this.columns.some((col) => col.visible) && !this.isChecked : Object.values(this.columns).some((col) => col.visible) && !this.isChecked return this.columns.some((col) => col.visible) && !this.isChecked
},
transferData() {
if (Array.isArray(this.columns)) {
return this.columns.map((item, index) => ({ key: index, label: item.label }))
} else {
return Object.keys(this.columns).map((key, index) => ({ key: index, label: this.columns[key].label }))
}
} }
}, },
created() { created() {
if (this.showColumnsType == 'transfer') { if (this.showColumnsType == 'transfer') {
// transfer穿梭显隐列初始默认隐藏列 // 显隐列初始默认隐藏列
if (Array.isArray(this.columns)) { for (let item in this.columns) {
for (let item in this.columns) { if (this.columns[item].visible === false) {
if (this.columns[item].visible === false) { this.value.push(parseInt(item))
this.value.push(parseInt(item))
}
} }
} else {
Object.keys(this.columns).forEach((key, index) => {
if (this.columns[key].visible === false) {
this.value.push(index)
}
})
} }
} }
}, },
@@ -131,15 +114,9 @@ export default {
}, },
// 右侧列表元素变化 // 右侧列表元素变化
dataChange(data) { dataChange(data) {
if (Array.isArray(this.columns)) { for (let item in this.columns) {
for (let item in this.columns) { const key = this.columns[item].key
const key = this.columns[item].key this.columns[item].visible = !data.includes(key)
this.columns[item].visible = !data.includes(key)
}
} else {
Object.keys(this.columns).forEach((key, index) => {
this.columns[key].visible = !data.includes(index)
})
} }
}, },
// 打开显隐列dialog // 打开显隐列dialog
@@ -147,26 +124,17 @@ export default {
this.open = true this.open = true
}, },
// 单勾选 // 单勾选
checkboxChange(event, key) { checkboxChange(event, label) {
if (Array.isArray(this.columns)) { this.columns.filter(item => item.label == label)[0].visible = event
this.columns.filter(item => item.key == key)[0].visible = event
} else {
this.columns[key].visible = event
}
}, },
// 切换全选/反选 // 切换全选/反选
toggleCheckAll() { toggleCheckAll() {
const newValue = !this.isChecked const newValue = !this.isChecked
if (Array.isArray(this.columns)) { this.columns.forEach((col) => (col.visible = newValue))
this.columns.forEach((col) => (col.visible = newValue))
} else {
Object.values(this.columns).forEach((col) => (col.visible = newValue))
}
} }
}, },
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
::v-deep .el-transfer__button { ::v-deep .el-transfer__button {
border-radius: 50%; border-radius: 50%;

View File

@@ -1,170 +1,170 @@
<template> <template>
<el-color-picker <el-color-picker
v-model="theme" v-model="theme"
:predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]" :predefine="['#409EFF', '#1890ff', '#304156','#212121','#11a983', '#13c2c2', '#6959CD', '#f5222d', ]"
class="theme-picker" class="theme-picker"
popper-class="theme-picker-dropdown" popper-class="theme-picker-dropdown"
/> />
</template> </template>
<script> <script>
const ORIGINAL_THEME = '#409EFF' // default color const ORIGINAL_THEME = '#409EFF' // default color
export default { export default {
data() { data() {
return { return {
chalk: '', // content of theme-chalk css chalk: '', // content of theme-chalk css
theme: '' theme: ''
} }
}, },
computed: { computed: {
defaultTheme() { defaultTheme() {
return this.$store.state.settings.theme return this.$store.state.settings.theme
} }
}, },
watch: { watch: {
defaultTheme: { defaultTheme: {
handler: function(val, oldVal) { handler: function(val, oldVal) {
this.theme = val this.theme = val
}, },
immediate: true immediate: true
}, },
async theme(val) { async theme(val) {
await this.setTheme(val) await this.setTheme(val)
} }
}, },
created() { created() {
if(this.defaultTheme !== ORIGINAL_THEME) { if(this.defaultTheme !== ORIGINAL_THEME) {
this.setTheme(this.defaultTheme) this.setTheme(this.defaultTheme)
} }
}, },
methods: { methods: {
async setTheme(val) { async setTheme(val) {
const oldVal = this.chalk ? this.theme : ORIGINAL_THEME const oldVal = this.chalk ? this.theme : ORIGINAL_THEME
if (typeof val !== 'string') return if (typeof val !== 'string') return
const themeCluster = this.getThemeCluster(val.replace('#', '')) const themeCluster = this.getThemeCluster(val.replace('#', ''))
const originalCluster = this.getThemeCluster(oldVal.replace('#', '')) const originalCluster = this.getThemeCluster(oldVal.replace('#', ''))
const getHandler = (variable, id) => { const getHandler = (variable, id) => {
return () => { return () => {
const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', '')) const originalCluster = this.getThemeCluster(ORIGINAL_THEME.replace('#', ''))
const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster) const newStyle = this.updateStyle(this[variable], originalCluster, themeCluster)
let styleTag = document.getElementById(id) let styleTag = document.getElementById(id)
if (!styleTag) { if (!styleTag) {
styleTag = document.createElement('style') styleTag = document.createElement('style')
styleTag.setAttribute('id', id) styleTag.setAttribute('id', id)
document.head.appendChild(styleTag) document.head.appendChild(styleTag)
} }
styleTag.innerText = newStyle styleTag.innerText = newStyle
} }
} }
if (!this.chalk) { if (!this.chalk) {
const url = `/styles/theme-chalk/index.css` const url = `/styles/theme-chalk/index.css`
await this.getCSSString(url, 'chalk') await this.getCSSString(url, 'chalk')
} }
const chalkHandler = getHandler('chalk', 'chalk-style') const chalkHandler = getHandler('chalk', 'chalk-style')
chalkHandler() chalkHandler()
const styles = [].slice.call(document.querySelectorAll('style')) const styles = [].slice.call(document.querySelectorAll('style'))
.filter(style => { .filter(style => {
const text = style.innerText const text = style.innerText
return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text) return new RegExp(oldVal, 'i').test(text) && !/Chalk Variables/.test(text)
}) })
styles.forEach(style => { styles.forEach(style => {
const { innerText } = style const { innerText } = style
if (typeof innerText !== 'string') return if (typeof innerText !== 'string') return
style.innerText = this.updateStyle(innerText, originalCluster, themeCluster) style.innerText = this.updateStyle(innerText, originalCluster, themeCluster)
}) })
this.$emit('change', val) this.$emit('change', val)
}, },
updateStyle(style, oldCluster, newCluster) { updateStyle(style, oldCluster, newCluster) {
let newStyle = style let newStyle = style
oldCluster.forEach((color, index) => { oldCluster.forEach((color, index) => {
newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index]) newStyle = newStyle.replace(new RegExp(color, 'ig'), newCluster[index])
}) })
return newStyle return newStyle
}, },
getCSSString(url, variable) { getCSSString(url, variable) {
return new Promise(resolve => { return new Promise(resolve => {
const xhr = new XMLHttpRequest() const xhr = new XMLHttpRequest()
xhr.onreadystatechange = () => { xhr.onreadystatechange = () => {
if (xhr.readyState === 4 && xhr.status === 200) { if (xhr.readyState === 4 && xhr.status === 200) {
this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '') this[variable] = xhr.responseText.replace(/@font-face{[^}]+}/, '')
resolve() resolve()
} }
} }
xhr.open('GET', url) xhr.open('GET', url)
xhr.send() xhr.send()
}) })
}, },
getThemeCluster(theme) { getThemeCluster(theme) {
const tintColor = (color, tint) => { const tintColor = (color, tint) => {
let red = parseInt(color.slice(0, 2), 16) let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16) let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16) let blue = parseInt(color.slice(4, 6), 16)
if (tint === 0) { // when primary color is in its rgb space if (tint === 0) { // when primary color is in its rgb space
return [red, green, blue].join(',') return [red, green, blue].join(',')
} else { } else {
red += Math.round(tint * (255 - red)) red += Math.round(tint * (255 - red))
green += Math.round(tint * (255 - green)) green += Math.round(tint * (255 - green))
blue += Math.round(tint * (255 - blue)) blue += Math.round(tint * (255 - blue))
red = red.toString(16) red = red.toString(16)
green = green.toString(16) green = green.toString(16)
blue = blue.toString(16) blue = blue.toString(16)
return `#${red}${green}${blue}` return `#${red}${green}${blue}`
} }
} }
const shadeColor = (color, shade) => { const shadeColor = (color, shade) => {
let red = parseInt(color.slice(0, 2), 16) let red = parseInt(color.slice(0, 2), 16)
let green = parseInt(color.slice(2, 4), 16) let green = parseInt(color.slice(2, 4), 16)
let blue = parseInt(color.slice(4, 6), 16) let blue = parseInt(color.slice(4, 6), 16)
red = Math.round((1 - shade) * red) red = Math.round((1 - shade) * red)
green = Math.round((1 - shade) * green) green = Math.round((1 - shade) * green)
blue = Math.round((1 - shade) * blue) blue = Math.round((1 - shade) * blue)
red = red.toString(16) red = red.toString(16)
green = green.toString(16) green = green.toString(16)
blue = blue.toString(16) blue = blue.toString(16)
return `#${red}${green}${blue}` return `#${red}${green}${blue}`
} }
const clusters = [theme] const clusters = [theme]
for (let i = 0; i <= 9; i++) { for (let i = 0; i <= 9; i++) {
clusters.push(tintColor(theme, Number((i / 10).toFixed(2)))) clusters.push(tintColor(theme, Number((i / 10).toFixed(2))))
} }
clusters.push(shadeColor(theme, 0.1)) clusters.push(shadeColor(theme, 0.1))
return clusters return clusters
} }
} }
} }
</script> </script>
<style> <style>
.theme-message, .theme-message,
.theme-picker-dropdown { .theme-picker-dropdown {
z-index: 99999 !important; z-index: 99999 !important;
} }
.theme-picker .el-color-picker__trigger { .theme-picker .el-color-picker__trigger {
height: 26px !important; height: 26px !important;
width: 26px !important; width: 26px !important;
padding: 2px; padding: 2px;
} }
.theme-picker-dropdown .el-color-dropdown__link-btn { .theme-picker-dropdown .el-color-dropdown__link-btn {
display: none; display: none;
} }
</style> </style>

View File

@@ -53,19 +53,12 @@ export default {
overflow: hidden; overflow: hidden;
} }
.fixed-header + .app-main {
overflow-y: auto;
scrollbar-gutter: auto;
height: calc(100vh - 50px);
min-height: 0px;
}
.app-main:has(.copyright) { .app-main:has(.copyright) {
padding-bottom: 36px; padding-bottom: 36px;
} }
.fixed-header + .app-main { .fixed-header + .app-main {
margin-top: 50px; padding-top: 50px;
} }
.hasTagsView { .hasTagsView {
@@ -75,14 +68,19 @@ export default {
} }
.fixed-header + .app-main { .fixed-header + .app-main {
margin-top: 84px; padding-top: 84px;
height: calc(100vh - 84px);
min-height: 0px;
} }
} }
</style> </style>
<style lang="scss"> <style lang="scss">
// fix css style bug in open el-dialog
.el-popup-parent--hidden {
.fixed-header {
padding-right: 6px;
}
}
::-webkit-scrollbar { ::-webkit-scrollbar {
width: 6px; width: 6px;
height: 6px; height: 6px;

View File

@@ -34,14 +34,15 @@
<router-link to="/user/profile"> <router-link to="/user/profile">
<el-dropdown-item>个人中心</el-dropdown-item> <el-dropdown-item>个人中心</el-dropdown-item>
</router-link> </router-link>
<el-dropdown-item @click.native="setLayout" v-if="setting">
<span>布局设置</span>
</el-dropdown-item>
<el-dropdown-item divided @click.native="logout"> <el-dropdown-item divided @click.native="logout">
<span>退出登录</span> <span>退出登录</span>
</el-dropdown-item> </el-dropdown-item>
</el-dropdown-menu> </el-dropdown-menu>
</el-dropdown> </el-dropdown>
<div class="right-menu-item hover-effect setting" @click="setLayout" v-if="setting">
<svg-icon icon-class="more-up" />
</div>
</div> </div>
</div> </div>
</template> </template>
@@ -177,7 +178,6 @@ export default {
.avatar-wrapper { .avatar-wrapper {
margin-top: 10px; margin-top: 10px;
right: 8px;
position: relative; position: relative;
.user-avatar { .user-avatar {
@@ -190,7 +190,6 @@ export default {
.user-nickname{ .user-nickname{
position: relative; position: relative;
bottom: 10px; bottom: 10px;
left: 2px;
font-size: 14px; font-size: 14px;
font-weight: bold; font-weight: bold;
} }

View File

@@ -77,11 +77,6 @@ export default {
} }
} }
.main-container:has(.fixed-header) {
height: 100vh;
overflow: hidden;
}
.drawer-bg { .drawer-bg {
background: #000; background: #000;
opacity: 0.3; opacity: 0.3;

View File

@@ -23,9 +23,6 @@ const mutations = {
if (state.hasOwnProperty(key)) { if (state.hasOwnProperty(key)) {
state[key] = value state[key] = value
} }
},
SET_TITLE: (state, title) => {
state.title = title
} }
} }
@@ -36,7 +33,7 @@ const actions = {
}, },
// 设置网页标题 // 设置网页标题
setTitle({ commit }, title) { setTitle({ commit }, title) {
commit('SET_TITLE', title) state.title = title
useDynamicTitle() useDynamicTitle()
} }
} }

View File

@@ -1,37 +1,29 @@
export const drawingDefaultValue = [] export default [
{
export function initDrawingDefaultValue() { layout: 'colFormItem',
if (drawingDefaultValue.length === 0) { tagIcon: 'input',
drawingDefaultValue.push({ label: '手机号',
layout: 'colFormItem', vModel: 'mobile',
tagIcon: 'input', formId: 6,
label: '手机号', tag: 'el-input',
vModel: 'mobile', placeholder: '请输入手机号',
formId: 6, defaultValue: '',
tag: 'el-input', span: 24,
placeholder: '请输入手机号', style: { width: '100%' },
defaultValue: '', clearable: true,
span: 24, prepend: '',
style: {width: '100%'}, append: '',
clearable: true, 'prefix-icon': 'el-icon-mobile',
prepend: '', 'suffix-icon': '',
append: '', maxlength: 11,
'prefix-icon': 'el-icon-mobile', 'show-word-limit': true,
'suffix-icon': '', readonly: false,
maxlength: 11, disabled: false,
'show-word-limit': true, required: true,
readonly: false, changeTag: true,
disabled: false, regList: [{
required: true, pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
changeTag: true, message: '手机号格式错误'
regList: [{ }]
pattern: '/^1(3|4|5|7|8|9)\\d{9}$/',
message: '手机号格式错误'
}]
})
} }
} ]
export function cleanDrawingDefaultValue() {
drawingDefaultValue.splice(0, drawingDefaultValue.length)
}

View File

@@ -81,10 +81,10 @@
> >
</p> </p>
<p> <p>
<i class="el-icon-user-solid"></i> QQ群 <s> 满42799195 </s> <s> 满170157040 </s> <i class="el-icon-user-solid"></i> QQ群 <s> 满42799195 </s> <s> 满170157040 </s>
<s> 满130643120 </s> <s> 满225920371 </s> <s> 满201705537 </s> <s> 满236543183 </s> <s> 满130643120 </s> <s> 满225920371 </s> <s> 满201705537 </s> <s> 满236543183 </s>
<s> 满213618602 </s> <s> 满148794840 </s> <s> 满118752664 </s> <s> 满101038945 </s> <s> 满213618602 </s> <s> 满148794840 </s> <s> 满118752664 </s> <s> 满101038945 </s>
<s> 满128355254 </s> <s> 满179219821 </s> <s> 满158753145 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=jR7HqTiLzuLocIH6aNNtTW3LlCV8UQ6d&authKey=GJZj%2Bnwmsvk6j%2FWrX7FKstAaRjgUC1WL%2F%2B8aVTaPbHX5wOimH5q9igaOSXP7cF9L&noverify=0&group_code=112869560" target="_blank">112869560</a> <s> 满128355254 </s> <s> 满179219821 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Z6j1amUmIPBXamuZzxpwjY8GwaP45XB6&authKey=zfSnxECfnScfY1HLCWilSqCq%2BmSVtr%2Bi%2F4oXeBcuQVwlq6XlrAfbZ0awp3%2B4Bdec&noverify=0&group_code=158753145" target="_blank">158753145</a>
</p> </p>
<p> <p>
<i class="el-icon-chat-dot-round"></i> 微信<a <i class="el-icon-chat-dot-round"></i> 微信<a

View File

@@ -56,7 +56,7 @@
</el-form> </el-form>
<!-- 底部 --> <!-- 底部 -->
<div class="el-login-footer"> <div class="el-login-footer">
<span>{{ footerContent }}</span> <span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>
</div> </div>
</div> </div>
</template> </template>
@@ -65,14 +65,12 @@
import { getCodeImg } from "@/api/login" import { getCodeImg } from "@/api/login"
import Cookies from "js-cookie" import Cookies from "js-cookie"
import { encrypt, decrypt } from '@/utils/jsencrypt' import { encrypt, decrypt } from '@/utils/jsencrypt'
import defaultSettings from '@/settings'
export default { export default {
name: "Login", name: "Login",
data() { data() {
return { return {
title: process.env.VUE_APP_TITLE, title: process.env.VUE_APP_TITLE,
footerContent: defaultSettings.footerContent,
codeUrl: "", codeUrl: "",
loginForm: { loginForm: {
username: "admin", username: "admin",
@@ -158,7 +156,7 @@ export default {
} }
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss">
.login { .login {
display: flex; display: flex;
justify-content: center; justify-content: center;

View File

@@ -61,14 +61,13 @@
</el-form> </el-form>
<!-- 底部 --> <!-- 底部 -->
<div class="el-register-footer"> <div class="el-register-footer">
<span>{{ footerContent }}</span> <span>Copyright © 2018-2025 ruoyi.vip All Rights Reserved.</span>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { getCodeImg, register } from "@/api/login" import { getCodeImg, register } from "@/api/login"
import defaultSettings from '@/settings'
export default { export default {
name: "Register", name: "Register",
@@ -82,7 +81,6 @@ export default {
} }
return { return {
title: process.env.VUE_APP_TITLE, title: process.env.VUE_APP_TITLE,
footerContent: defaultSettings.footerContent,
codeUrl: "", codeUrl: "",
registerForm: { registerForm: {
username: "", username: "",
@@ -149,7 +147,7 @@ export default {
} }
</script> </script>
<style rel="stylesheet/scss" lang="scss" scoped> <style rel="stylesheet/scss" lang="scss">
.register { .register {
display: flex; display: flex;
justify-content: center; justify-content: center;

View File

@@ -58,17 +58,17 @@
<el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange"> <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
<el-table-column type="selection" width="50" align="center" /> <el-table-column type="selection" width="50" align="center" />
<el-table-column label="用户编号" align="center" key="userId" prop="userId" v-if="columns.userId.visible" /> <el-table-column label="用户编号" align="center" key="userId" prop="userId" v-if="columns[0].visible" />
<el-table-column label="用户名称" align="center" key="userName" prop="userName" v-if="columns.userName.visible" :show-overflow-tooltip="true" /> <el-table-column label="用户名称" align="center" key="userName" prop="userName" v-if="columns[1].visible" :show-overflow-tooltip="true" />
<el-table-column label="用户昵称" align="center" key="nickName" prop="nickName" v-if="columns.nickName.visible" :show-overflow-tooltip="true" /> <el-table-column label="用户昵称" align="center" key="nickName" prop="nickName" v-if="columns[2].visible" :show-overflow-tooltip="true" />
<el-table-column label="部门" align="center" key="deptName" prop="dept.deptName" v-if="columns.deptName.visible" :show-overflow-tooltip="true" /> <el-table-column label="部门" align="center" key="deptName" prop="dept.deptName" v-if="columns[3].visible" :show-overflow-tooltip="true" />
<el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns.phonenumber.visible" width="120" /> <el-table-column label="手机号码" align="center" key="phonenumber" prop="phonenumber" v-if="columns[4].visible" width="120" />
<el-table-column label="状态" align="center" key="status" v-if="columns.status.visible"> <el-table-column label="状态" align="center" key="status" v-if="columns[5].visible">
<template slot-scope="scope"> <template slot-scope="scope">
<el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch> <el-switch v-model="scope.row.status" active-value="0" inactive-value="1" @change="handleStatusChange(scope.row)"></el-switch>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="创建时间" align="center" prop="createTime" v-if="columns.createTime.visible" width="160"> <el-table-column label="创建时间" align="center" prop="createTime" v-if="columns[6].visible" width="160">
<template slot-scope="scope"> <template slot-scope="scope">
<span>{{ parseTime(scope.row.createTime) }}</span> <span>{{ parseTime(scope.row.createTime) }}</span>
</template> </template>
@@ -277,15 +277,15 @@ export default {
deptId: undefined deptId: undefined
}, },
// 列信息 // 列信息
columns: { columns: [
userId: { label: '用户编号', visible: true }, { key: 0, label: `用户编号`, visible: true },
userName: { label: '用户名称', visible: true }, { key: 1, label: `用户名称`, visible: true },
nickName: { label: '用户昵称', visible: true }, { key: 2, label: `用户昵称`, visible: true },
deptName: { label: '部门', visible: true }, { key: 3, label: `部门`, visible: true },
phonenumber: { label: '手机号码', visible: true }, { key: 4, label: `手机号码`, visible: true },
status: { label: '状态', visible: true }, { key: 5, label: `状态`, visible: true },
createTime: { label: '创建时间', visible: true } { key: 6, label: `创建时间`, visible: true }
}, ],
// 表单校验 // 表单校验
rules: { rules: {
userName: [ userName: [
@@ -546,11 +546,6 @@ export default {
}, },
// 提交上传文件 // 提交上传文件
submitFileForm() { submitFileForm() {
const file = this.$refs.upload.uploadFiles
if (!file || file.length === 0 || !file[0].name.toLowerCase().endsWith('.xls') && !file[0].name.toLowerCase().endsWith('.xlsx')) {
this.$modal.msgError("请选择后缀为 “xls”或“xlsx”的文件。")
return
}
this.$refs.upload.submit() this.$refs.upload.submit()
} }
} }

View File

@@ -146,14 +146,13 @@ import { beautifierConf, titleCase } from '@/utils/index'
import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html' import { makeUpHtml, vueTemplate, vueScript, cssStyle } from '@/utils/generator/html'
import { makeUpJs } from '@/utils/generator/js' import { makeUpJs } from '@/utils/generator/js'
import { makeUpCss } from '@/utils/generator/css' import { makeUpCss } from '@/utils/generator/css'
import { drawingDefaultValue, initDrawingDefaultValue, cleanDrawingDefaultValue } from '@/utils/generator/drawingDefault' import drawingDefault from '@/utils/generator/drawingDefault'
import logo from '@/assets/logo/logo.png' import logo from '@/assets/logo/logo.png'
import CodeTypeDialog from './CodeTypeDialog' import CodeTypeDialog from './CodeTypeDialog'
import DraggableItem from './DraggableItem' import DraggableItem from './DraggableItem'
let oldActiveId let oldActiveId
let tempActiveData let tempActiveData
let clipboard = null
export default { export default {
components: { components: {
@@ -172,20 +171,17 @@ export default {
selectComponents, selectComponents,
layoutComponents, layoutComponents,
labelWidth: 100, labelWidth: 100,
drawingList: drawingDefaultValue, drawingList: drawingDefault,
drawingData: {}, drawingData: {},
activeId: drawingDefaultValue[0].formId, activeId: drawingDefault[0].formId,
drawerVisible: false, drawerVisible: false,
formData: {}, formData: {},
dialogVisible: false, dialogVisible: false,
generateConf: null, generateConf: null,
showFileName: false, showFileName: false,
activeData: drawingDefaultValue[0] activeData: drawingDefault[0]
} }
}, },
beforeCreate() {
initDrawingDefaultValue()
},
created() { created() {
// 防止 firefox 下 拖拽 会新打卡一个选项卡 // 防止 firefox 下 拖拽 会新打卡一个选项卡
document.body.ondrop = event => { document.body.ondrop = event => {
@@ -212,7 +208,7 @@ export default {
} }
}, },
mounted() { mounted() {
clipboard = new ClipboardJS('#copyNode', { const clipboard = new ClipboardJS('#copyNode', {
text: trigger => { text: trigger => {
const codeStr = this.generateCode() const codeStr = this.generateCode()
this.$notify({ this.$notify({
@@ -227,9 +223,6 @@ export default {
this.$message.error('代码复制失败') this.$message.error('代码复制失败')
}) })
}, },
beforeDestroy() {
clipboard.destroy()
},
methods: { methods: {
activeFormItem(element) { activeFormItem(element) {
this.activeData = element this.activeData = element
@@ -291,7 +284,6 @@ export default {
this.$confirm('确定要清空所有组件吗?', '提示', { type: 'warning' }).then( this.$confirm('确定要清空所有组件吗?', '提示', { type: 'warning' }).then(
() => { () => {
this.drawingList = [] this.drawingList = []
cleanDrawingDefaultValue()
} }
) )
}, },

View File

@@ -253,8 +253,7 @@ export default {
this.$modal.msgSuccess("成功生成到自定义路径:" + row.genPath) this.$modal.msgSuccess("成功生成到自定义路径:" + row.genPath)
}) })
} else { } else {
const zipName = Array.isArray(tableNames) ? "ruoyi.zip" : tableNames + ".zip" this.$download.zip("/code/gen/batchGenCode?tables=" + tableNames, "ruoyi.zip")
this.$download.zip("/code/gen/batchGenCode?tables=" + tableNames, zipName)
} }
}, },
/** 同步数据库操作 */ /** 同步数据库操作 */

View File

@@ -2,22 +2,17 @@ package com.ruoyi.modules.monitor.config;
import de.codecentric.boot.admin.server.config.AdminServerProperties; import de.codecentric.boot.admin.server.config.AdminServerProperties;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.annotation.web.configurers.HeadersConfigurer;
import org.springframework.security.web.SecurityFilterChain; import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler; import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler;
/** /**
* 监控权限配置 * 监控权限配置
* *
* @author ruoyi * @author ruoyi
*/ */
@EnableWebSecurity @EnableWebSecurity
@Configuration
public class WebSecurityConfigurer public class WebSecurityConfigurer
{ {
private final String adminContextPath; private final String adminContextPath;
@@ -34,20 +29,23 @@ public class WebSecurityConfigurer
successHandler.setTargetUrlParameter("redirectTo"); successHandler.setTargetUrlParameter("redirectTo");
successHandler.setDefaultTargetUrl(adminContextPath + "/"); successHandler.setDefaultTargetUrl(adminContextPath + "/");
return httpSecurity.headers((header) -> header.frameOptions(HeadersConfigurer.FrameOptionsConfig::disable)) return httpSecurity
.authorizeHttpRequests( .headers().frameOptions().disable()
(authorize) -> authorize .and().authorizeRequests()
.requestMatchers(adminContextPath + "/assets/**", .antMatchers(adminContextPath + "/assets/**"
adminContextPath + "/login", , adminContextPath + "/login"
adminContextPath + "/actuator/**", , adminContextPath + "/actuator/**"
adminContextPath + "/instances/**") , adminContextPath + "/instances/**"
.permitAll() ).permitAll()
.anyRequest() .anyRequest().authenticated()
.authenticated()) .and()
.formLogin((formLogin) -> formLogin.loginPage(adminContextPath + "/login").successHandler(successHandler)) .formLogin().loginPage(adminContextPath + "/login")
.logout((logout) -> logout.logoutUrl(adminContextPath + "/logout")) .successHandler(successHandler).and()
.httpBasic(Customizer.withDefaults()) .logout().logoutUrl(adminContextPath + "/logout")
.csrf(AbstractHttpConfigurer::disable) .and()
.build(); .httpBasic().and()
.csrf()
.disable()
.build();
} }
} }

View File

@@ -34,13 +34,13 @@ CREATE TABLE `config_info` (
insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_modified, src_user, src_ip, app_name, tenant_id, c_desc, c_use, effect, type, c_schema, encrypted_data_key) values insert into config_info(id, data_id, group_id, content, md5, gmt_create, gmt_modified, src_user, src_ip, app_name, tenant_id, c_desc, c_use, effect, type, c_schema, encrypted_data_key) values
(1,'application-dev.yml','DEFAULT_GROUP','spring:\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\n\n# feign 配置\nfeign:\n sentinel:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n min-request-size: 8192\n response:\n enabled: true\n\n# 暴露监控端点\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n','9928f41dfb10386ad38b3254af5692e0','2020-05-20 12:00:00','2024-08-29 12:14:45','nacos','0:0:0:0:0:0:0:1','','','通用配置','null','null','yaml','',''), (1,'application-dev.yml','DEFAULT_GROUP','spring:\n autoconfigure:\n exclude: com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure\n\n# feign 配置\nfeign:\n sentinel:\n enabled: true\n okhttp:\n enabled: true\n httpclient:\n enabled: false\n client:\n config:\n default:\n connectTimeout: 10000\n readTimeout: 10000\n compression:\n request:\n enabled: true\n min-request-size: 8192\n response:\n enabled: true\n\n# 暴露监控端点\nmanagement:\n endpoints:\n web:\n exposure:\n include: \'*\'\n','9928f41dfb10386ad38b3254af5692e0','2020-05-20 12:00:00','2024-08-29 12:14:45','nacos','0:0:0:0:0:0:0:1','','','通用配置','null','null','yaml','',''),
(2,'ruoyi-gateway-dev.yml','DEFAULT_GROUP','spring:\n data:\n redis:\n host: localhost\n port: 6379\n password: \n cloud:\n gateway:\n discovery:\n locator:\n lowerCaseServiceId: true\n enabled: true\n routes:\n # 认证中心\n - id: ruoyi-auth\n uri: lb://ruoyi-auth\n predicates:\n - Path=/auth/**\n filters:\n # 验证码处理\n - CacheRequestBody\n - ValidateCodeFilter\n - StripPrefix=1\n # 代码生成\n - id: ruoyi-gen\n uri: lb://ruoyi-gen\n predicates:\n - Path=/code/**\n filters:\n - StripPrefix=1\n # 定时任务\n - id: ruoyi-job\n uri: lb://ruoyi-job\n predicates:\n - Path=/schedule/**\n filters:\n - StripPrefix=1\n # 系统模块\n - id: ruoyi-system\n uri: lb://ruoyi-system\n predicates:\n - Path=/system/**\n filters:\n - StripPrefix=1\n # 文件服务\n - id: ruoyi-file\n uri: lb://ruoyi-file\n predicates:\n - Path=/file/**\n filters:\n - StripPrefix=1\n\n# 安全配置\nsecurity:\n # 验证码\n captcha:\n enabled: true\n type: math\n # 防止XSS攻击\n xss:\n enabled: true\n excludeUrls:\n - /system/notice\n\n # 不校验白名单\n ignore:\n whites:\n - /auth/logout\n - /auth/login\n - /auth/register\n - /*/v2/api-docs\n - /*/v3/api-docs\n - /csrf\n\n# springdoc配置\nspringdoc:\n webjars:\n # 访问前缀\n prefix:\n','8c27a047f057fc05e5fc223adeb9c685','2020-05-14 14:17:55','2024-09-14 04:49:34','nacos','0:0:0:0:0:0:0:1','','','网关模块','null','null','yaml','',''), (2,'ruoyi-gateway-dev.yml','DEFAULT_GROUP','spring:\n redis:\n host: localhost\n port: 6379\n password: \n cloud:\n gateway:\n discovery:\n locator:\n lowerCaseServiceId: true\n enabled: true\n routes:\n # 认证中心\n - id: ruoyi-auth\n uri: lb://ruoyi-auth\n predicates:\n - Path=/auth/**\n filters:\n # 验证码处理\n - CacheRequestBody\n - ValidateCodeFilter\n - StripPrefix=1\n # 代码生成\n - id: ruoyi-gen\n uri: lb://ruoyi-gen\n predicates:\n - Path=/code/**\n filters:\n - StripPrefix=1\n # 定时任务\n - id: ruoyi-job\n uri: lb://ruoyi-job\n predicates:\n - Path=/schedule/**\n filters:\n - StripPrefix=1\n # 系统模块\n - id: ruoyi-system\n uri: lb://ruoyi-system\n predicates:\n - Path=/system/**\n filters:\n - StripPrefix=1\n # 文件服务\n - id: ruoyi-file\n uri: lb://ruoyi-file\n predicates:\n - Path=/file/**\n filters:\n - StripPrefix=1\n\n# 安全配置\nsecurity:\n # 验证码\n captcha:\n enabled: true\n type: math\n # 防止XSS攻击\n xss:\n enabled: true\n excludeUrls:\n - /system/notice\n\n # 不校验白名单\n ignore:\n whites:\n - /auth/logout\n - /auth/login\n - /auth/register\n - /*/v2/api-docs\n - /*/v3/api-docs\n - /csrf\n\n# springdoc配置\nspringdoc:\n webjars:\n # 访问前缀\n prefix:\n','4d329eb08a941a8dd9d26f542c6ac6c5','2020-05-14 14:17:55','2024-09-02 12:13:50','nacos','0:0:0:0:0:0:0:1','','','网关模块','null','null','yaml','',''),
(3,'ruoyi-auth-dev.yml','DEFAULT_GROUP','spring:\n data:\n redis:\n host: localhost\n port: 6379\n password: \n','72565b1a725e013154ee57c8fd3045c4','2020-11-20 00:00:00','2024-09-14 04:49:42','nacos','0:0:0:0:0:0:0:1','','','认证中心','null','null','yaml','',''), (3,'ruoyi-auth-dev.yml','DEFAULT_GROUP','spring:\n redis:\n host: localhost\n port: 6379\n password: \n','a03e7632a0a74520eeb4fbedd6d82d97','2020-11-20 00:00:00','2024-09-02 12:13:58','nacos','0:0:0:0:0:0:0:1','','','认证中心','null','null','yaml','',''),
(4,'ruoyi-monitor-dev.yml','DEFAULT_GROUP','# spring\nspring:\n security:\n user:\n name: ruoyi\n password: 123456\n boot:\n admin:\n ui:\n title: 若依服务状态监控\n','6f122fd2bfb8d45f858e7d6529a9cd44','2020-11-20 00:00:00','2024-08-29 12:15:11','nacos','0:0:0:0:0:0:0:1','','','监控中心','null','null','yaml','',''), (4,'ruoyi-monitor-dev.yml','DEFAULT_GROUP','# spring\nspring:\n security:\n user:\n name: ruoyi\n password: 123456\n boot:\n admin:\n ui:\n title: 若依服务状态监控\n','6f122fd2bfb8d45f858e7d6529a9cd44','2020-11-20 00:00:00','2024-08-29 12:15:11','nacos','0:0:0:0:0:0:0:1','','','监控中心','null','null','yaml','',''),
(5,'ruoyi-system-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n data:\n redis:\n host: localhost\n port: 6379\n password: \n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: ruoyi\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n connectTimeout: 30000\n socketTimeout: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n # 主库数据源\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n # 从库数据源\n # slave:\n # username: \n # password: \n # url: \n # driver-class-name: \n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.system\n # 配置mapper的扫描找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# springdoc配置\nspringdoc:\n gatewayUrl: http://localhost:8080/${spring.application.name}\n api-docs:\n # 是否开启接口文档\n enabled: true\n info:\n # 标题\n title: \'\'\n # 描述\n description: \'\'\n # 作者信息\n contact:\n name: RuoYi\n url: https://ruoyi.vip\n','a79ae256018abb7f3bbaba923baeb6af','2020-11-20 00:00:00','2024-09-14 04:49:54','nacos','0:0:0:0:0:0:0:1','','','系统模块','null','null','yaml','',''), (5,'ruoyi-system-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n redis:\n host: localhost\n port: 6379\n password: \n datasource:\n druid:\n stat-view-servlet:\n enabled: true\n loginUsername: ruoyi\n loginPassword: 123456\n dynamic:\n druid:\n initial-size: 5\n min-idle: 5\n maxActive: 20\n maxWait: 60000\n connectTimeout: 30000\n socketTimeout: 60000\n timeBetweenEvictionRunsMillis: 60000\n minEvictableIdleTimeMillis: 300000\n validationQuery: SELECT 1 FROM DUAL\n testWhileIdle: true\n testOnBorrow: false\n testOnReturn: false\n poolPreparedStatements: true\n maxPoolPreparedStatementPerConnectionSize: 20\n filters: stat,slf4j\n connectionProperties: druid.stat.mergeSql\\=true;druid.stat.slowSqlMillis\\=5000\n datasource:\n # 主库数据源\n master:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n # 从库数据源\n # slave:\n # username: \n # password: \n # url: \n # driver-class-name: \n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.system\n # 配置mapper的扫描找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# springdoc配置\nspringdoc:\n gatewayUrl: http://localhost:8080/${spring.application.name}\n api-docs:\n # 是否开启接口文档\n enabled: true\n info:\n # 标题\n title: \'\'\n # 描述\n description: \'\'\n # 作者信息\n contact:\n name: RuoYi\n url: https://ruoyi.vip\n','786c7daf4543411fc65c3e48dfb15243','2020-11-20 00:00:00','2024-09-02 12:14:33','nacos','0:0:0:0:0:0:0:1','','','系统模块','null','null','yaml','',''),
(6,'ruoyi-gen-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n data:\n redis:\n host: localhost\n port: 6379\n password: \n datasource:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.gen.domain\n # 配置mapper的扫描找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# springdoc配置\nspringdoc:\n gatewayUrl: http://localhost:8080/${spring.application.name}\n api-docs:\n # 是否开启接口文档\n enabled: true\n info:\n # 标题\n title: \'\'\n # 描述\n description: \'\'\n # 作者信息\n contact:\n name: RuoYi\n url: https://ruoyi.vip\n\n# 代码生成\ngen:\n # 作者\n author: ruoyi\n # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool\n packageName: com.ruoyi.system\n # 自动去除表前缀默认是false\n autoRemovePre: false\n # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)\n tablePrefix: sys_\n # 是否允许生成文件覆盖到本地(自定义路径),默认不允许\n allowOverwrite: false','669b20230daf5b2eddda1c87a1e755d7','2020-11-20 00:00:00','2024-12-25 08:39:25','nacos','0:0:0:0:0:0:0:1','','','代码生成','null','null','yaml','',''), (6,'ruoyi-gen-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n redis:\n host: localhost\n port: 6379\n password: \n datasource:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.gen.domain\n # 配置mapper的扫描找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# springdoc配置\nspringdoc:\n gatewayUrl: http://localhost:8080/${spring.application.name}\n api-docs:\n # 是否开启接口文档\n enabled: true\n info:\n # 标题\n title: \'\'\n # 描述\n description: \'\'\n # 作者信息\n contact:\n name: RuoYi\n url: https://ruoyi.vip\n\n# 代码生成\ngen:\n # 作者\n author: ruoyi\n # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool\n packageName: com.ruoyi.system\n # 自动去除表前缀默认是false\n autoRemovePre: false\n # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)\n tablePrefix: sys_\n # 是否允许生成文件覆盖到本地(自定义路径),默认不允许\n allowOverwrite: false','43d807aa0a4accbb193b6dc7e38ac8a3','2020-11-20 00:00:00','2024-12-25 08:29:33','nacos','0:0:0:0:0:0:0:1','','','代码生成','null','null','yaml','',''),
(7,'ruoyi-job-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n data:\n redis:\n host: localhost\n port: 6379\n password: \n datasource:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.job.domain\n # 配置mapper的扫描找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# springdoc配置\nspringdoc:\n gatewayUrl: http://localhost:8080/${spring.application.name}\n api-docs:\n # 是否开启接口文档\n enabled: true\n info:\n # 标题\n title: \'\'\n # 描述\n description: \'\'\n # 作者信息\n contact:\n name: RuoYi\n url: https://ruoyi.vip\n','225445e638148dbcbadda8d9774ce3fd','2020-11-20 00:00:00','2024-09-14 04:50:12','nacos','0:0:0:0:0:0:0:1','','','定时任务','null','null','yaml','',''), (7,'ruoyi-job-dev.yml','DEFAULT_GROUP','# spring配置\nspring:\n redis:\n host: localhost\n port: 6379\n password: \n datasource:\n driver-class-name: com.mysql.cj.jdbc.Driver\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\n username: root\n password: password\n\n# mybatis配置\nmybatis:\n # 搜索指定包别名\n typeAliasesPackage: com.ruoyi.job.domain\n # 配置mapper的扫描找到所有的mapper.xml映射文件\n mapperLocations: classpath:mapper/**/*.xml\n\n# springdoc配置\nspringdoc:\n gatewayUrl: http://localhost:8080/${spring.application.name}\n api-docs:\n # 是否开启接口文档\n enabled: true\n info:\n # 标题\n title: \'\'\n # 描述\n description: \'\'\n # 作者信息\n contact:\n name: RuoYi\n url: https://ruoyi.vip\n','f78483f845777335b9ed4a9f84758848','2020-11-20 00:00:00','2024-09-02 12:14:56','nacos','0:0:0:0:0:0:0:1','','','定时任务','null','null','yaml','',''),
(8,'ruoyi-file-dev.yml','DEFAULT_GROUP','# 本地文件上传 \nfile:\n domain: http://127.0.0.1:9300\n path: D:/ruoyi/uploadPath\n prefix: /statics\n\n# FastDFS配置\nfdfs:\n domain: http://127.0.0.1\n soTimeout: 3000\n connectTimeout: 2000\n trackerList: 127.0.0.1:22122\n\n# Minio配置\nminio:\n url: http://127.0.0.1:9000\n accessKey: minioadmin\n secretKey: minioadmin\n bucketName: test\n\n # 防盗链配置\nreferer:\n # 防盗链开关\n enabled: false\n # 允许的域名列表\n allowed-domains: localhost,127.0.0.1,ruoyi.vip,www.ruoyi.vip\n','095791a04211d6e3d294359b21357394','2020-11-20 00:00:00','2025-09-02 05:10:11','nacos','0:0:0:0:0:0:0:1','','','文件服务','null','null','yaml','',''), (8,'ruoyi-file-dev.yml','DEFAULT_GROUP','# 本地文件上传 \r\nfile:\r\n domain: http://127.0.0.1:9300\r\n path: D:/ruoyi/uploadPath\r\n prefix: /statics\r\n\r\n# FastDFS配置\r\nfdfs:\r\n domain: http://8.129.231.12\r\n soTimeout: 3000\r\n connectTimeout: 2000\r\n trackerList: 8.129.231.12:22122\r\n\r\n# Minio配置\r\nminio:\r\n url: http://8.129.231.12:9000\r\n accessKey: minioadmin\r\n secretKey: minioadmin\r\n bucketName: test','5382b93f3d8059d6068c0501fdd41195','2020-11-20 00:00:00','2020-12-21 21:01:59',NULL,'0:0:0:0:0:0:0:1','','','文件服务','null','null','yaml',NULL,''),
(9,'sentinel-ruoyi-gateway','DEFAULT_GROUP','[\r\n {\r\n \"resource\": \"ruoyi-auth\",\r\n \"count\": 500,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-system\",\r\n \"count\": 1000,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-gen\",\r\n \"count\": 200,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-job\",\r\n \"count\": 300,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n }\r\n]','9f3a3069261598f74220bc47958ec252','2020-11-20 00:00:00','2020-11-20 00:00:00',NULL,'0:0:0:0:0:0:0:1','','','限流策略','null','null','json',NULL,''); (9,'sentinel-ruoyi-gateway','DEFAULT_GROUP','[\r\n {\r\n \"resource\": \"ruoyi-auth\",\r\n \"count\": 500,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-system\",\r\n \"count\": 1000,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-gen\",\r\n \"count\": 200,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-job\",\r\n \"count\": 300,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n }\r\n]','9f3a3069261598f74220bc47958ec252','2020-11-20 00:00:00','2020-11-20 00:00:00',NULL,'0:0:0:0:0:0:0:1','','','限流策略','null','null','json',NULL,'');