45 Commits

Author SHA1 Message Date
99e66bf11c 若依 3.8.8 2024-06-30 08:02:22 +08:00
a96d4bf2ed 菜单管理新增路由名称 2024-06-29 19:08:09 +08:00
8264b8fb31 删除多余的依赖 2024-06-27 11:08:31 +08:00
4ec32367fd 升级core-js到最新版本3.37.1 2024-06-27 10:22:55 +08:00
9e8aa14348 优化查表特殊字符使用反斜杠进行转义 2024-06-27 10:22:38 +08:00
10f68b97af 升级spring-security到安全版本,防止漏洞风险 2024-06-26 17:43:14 +08:00
8eff83e2b4 优化代码 2024-06-26 17:40:01 +08:00
7b064d84bb 升级druid到最新版本1.2.23 2024-06-25 12:29:13 +08:00
88560a7aa5 升级oshi到最新版本6.6.1 2024-06-25 12:28:50 +08:00
e14f40670a 优化代码 2024-06-25 12:27:21 +08:00
5b98495067 cron生成的表达式hour优化 2024-06-25 12:02:23 +08:00
259dc67728 优化数据权限代码 2024-06-05 12:30:43 +08:00
bc7a607033 Excel注解新增属性comboReadDict 2024-06-02 19:29:11 +08:00
161cd2b1ea 优化代码生成主子表关联查询方式 2024-06-02 19:28:40 +08:00
7480fb4020 优化导入Excel时设置dictType属性重复查缓存问题 2024-05-30 13:35:43 +08:00
906c3a68b8 添加新群号:151450850 2024-05-29 14:48:56 +08:00
084bab3494 update sql 2024-05-29 14:48:40 +08:00
cc0efa3330 优化代码 2024-05-29 14:48:23 +08:00
f46b1bbebd 限制用户操作数据权限范围 2024-05-29 14:48:03 +08:00
e5f30b1a19 升级spring-framework到安全版本,防止漏洞风险 2024-04-11 16:43:48 +08:00
1140a6c333 新增数据脱敏过滤注解 2024-04-08 13:16:27 +08:00
86ca404dbf 设置表格头单元格文本形式 2024-03-22 16:44:54 +08:00
11320b2e13 Excel注解ColumnType类型新增文本 2024-03-22 16:23:19 +08:00
905c08fb2c 升级oshi到最新版本6.5.0 2024-03-19 16:38:37 +08:00
9386645150 定义Locale默认国际化配置 2024-03-19 16:38:03 +08:00
bf3e2115e3 update vue.config.js 2024-03-18 14:28:28 +08:00
61eb54e4a1 更新compressionPlugin到6.1.2以兼容node18+ 2024-03-18 14:11:26 +08:00
d93e2b9df0 定时任务白名单配置范围缩小 2024-03-11 11:07:29 +08:00
50339c6f73 update copyright 2024 2024-03-11 10:47:55 +08:00
b83f2ff60b 添加新群号:138988063 2024-03-11 10:47:40 +08:00
66128f140f joblog order by 2024-03-11 09:42:15 +08:00
8c990ae9fc 用户密码新增非法字符验证 2024-03-01 21:53:57 +08:00
8836d31d77 升级oshi到最新版本6.4.13 2024-03-01 14:33:56 +08:00
2f624ab5f4 代码生成新增创建表结构功能 2024-03-01 14:33:09 +08:00
80f96b4915 升级oshi到最新版本6.4.11 2024-01-25 11:41:57 +08:00
7e9d050432 update http user-agent 2024-01-25 11:41:20 +08:00
649cfe8652 优化匹配方式 2024-01-25 11:34:25 +08:00
e9ae7ae5f3 !825 update: 修改退出处理类的日志记录和返回内容
Merge pull request !825 from 致远/master
2024-01-05 05:01:24 +00:00
3cc6fb5535 update: 修改退出处理类的日志记录和返回内容 2024-01-04 21:11:13 +08:00
a7bfd3b2d6 !822 删除未生效代码
Merge pull request !822 from mrzxc/fixbug/unuseCodeDelete
2024-01-02 02:20:43 +00:00
08d0326718 fix: delete unuse code 2023-12-25 10:22:05 +08:00
3f4ac65a31 remove packages 2023-12-13 11:51:17 +08:00
94d5c174aa 添加新群号:161281055 2023-12-13 11:47:35 +08:00
e719ac8cff !817 密码输入错误时,登录日志重复
Merge pull request !817 from 也曾为你像超人/N/A
2023-12-13 03:46:20 +00:00
a9bcfc66c3 密码输入错误时,登录日志重复
Signed-off-by: 也曾为你像超人 <1553592282@qq.com>
2023-12-10 14:18:35 +00:00
61 changed files with 993 additions and 334 deletions

View File

@ -1,11 +1,11 @@
<p align="center"> <p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png"> <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
</p> </p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.7</h1> <h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.8</h1>
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4> <h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
<p align="center"> <p align="center">
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a> <a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.7-brightgreen.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.8-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p> </p>
@ -93,4 +93,4 @@
## 若依前后端分离交流群 ## 若依前后端分离交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/已满-136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [![加入QQ群](https://img.shields.io/badge/已满-143961921-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [![加入QQ群](https://img.shields.io/badge/174951577-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) 点击按钮入群。 QQ群 [![加入QQ群](https://img.shields.io/badge/已满-937441-blue.svg)](https://jq.qq.com/?_wv=1027&k=5bVB1og) [![加入QQ群](https://img.shields.io/badge/已满-887144332-blue.svg)](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [![加入QQ群](https://img.shields.io/badge/已满-180251782-blue.svg)](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [![加入QQ群](https://img.shields.io/badge/已满-104180207-blue.svg)](https://jq.qq.com/?_wv=1027&k=51G72yr) [![加入QQ群](https://img.shields.io/badge/已满-186866453-blue.svg)](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [![加入QQ群](https://img.shields.io/badge/已满-201396349-blue.svg)](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [![加入QQ群](https://img.shields.io/badge/已满-101456076-blue.svg)](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [![加入QQ群](https://img.shields.io/badge/已满-101539465-blue.svg)](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [![加入QQ群](https://img.shields.io/badge/已满-264312783-blue.svg)](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [![加入QQ群](https://img.shields.io/badge/已满-167385320-blue.svg)](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [![加入QQ群](https://img.shields.io/badge/已满-104748341-blue.svg)](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [![加入QQ群](https://img.shields.io/badge/已满-160110482-blue.svg)](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [![加入QQ群](https://img.shields.io/badge/已满-170801498-blue.svg)](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [![加入QQ群](https://img.shields.io/badge/已满-108482800-blue.svg)](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [![加入QQ群](https://img.shields.io/badge/已满-101046199-blue.svg)](https://jq.qq.com/?_wv=1027&k=SpyH2875) [![加入QQ群](https://img.shields.io/badge/已满-136919097-blue.svg)](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [![加入QQ群](https://img.shields.io/badge/已满-143961921-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [![加入QQ群](https://img.shields.io/badge/已满-174951577-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) [![加入QQ群](https://img.shields.io/badge/已满-161281055-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=Fn2aF5IHpwsy8j6VlalNJK6qbwFLFHat&authKey=uyIT%2B97x2AXj3odyXpsSpVaPMC%2Bidw0LxG5MAtEqlrcBcWJUA%2FeS43rsF1Tg7IRJ&noverify=0&group_code=161281055) [![加入QQ群](https://img.shields.io/badge/已满-138988063-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=XIzkm_mV2xTsUtFxo63bmicYoDBA6Ifm&authKey=dDW%2F4qsmw3x9govoZY9w%2FoWAoC4wbHqGal%2BbqLzoS6VBarU8EBptIgPKN%2FviyC8j&noverify=0&group_code=138988063) [![加入QQ群](https://img.shields.io/badge/151450850-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=DkugnCg68PevlycJSKSwjhFqfIgrWWwR&authKey=pR1Pa5lPIeGF%2FFtIk6d%2FGB5qFi0EdvyErtpQXULzo03zbhopBHLWcuqdpwY241R%2F&noverify=0&group_code=151450850) 点击按钮入群。

36
pom.xml
View File

@ -6,27 +6,28 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.8.7</version> <version>3.8.8</version>
<name>ruoyi</name> <name>ruoyi</name>
<url>http://www.ruoyi.vip</url> <url>http://www.ruoyi.vip</url>
<description>若依管理系统</description> <description>若依管理系统</description>
<properties> <properties>
<ruoyi.version>3.8.7</ruoyi.version> <ruoyi.version>3.8.8</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>1.8</java.version> <java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<druid.version>1.2.20</druid.version> <spring-framework.version>5.3.33</spring-framework.version>
<spring-security.version>5.7.12</spring-security.version>
<druid.version>1.2.23</druid.version>
<bitwalker.version>1.21</bitwalker.version> <bitwalker.version>1.21</bitwalker.version>
<swagger.version>3.0.0</swagger.version> <swagger.version>3.0.0</swagger.version>
<kaptcha.version>2.3.3</kaptcha.version> <kaptcha.version>2.3.3</kaptcha.version>
<pagehelper.boot.version>1.4.7</pagehelper.boot.version> <pagehelper.boot.version>1.4.7</pagehelper.boot.version>
<fastjson.version>2.0.43</fastjson.version> <fastjson.version>2.0.43</fastjson.version>
<oshi.version>6.4.8</oshi.version> <oshi.version>6.6.1</oshi.version>
<commons.io.version>2.13.0</commons.io.version> <commons.io.version>2.13.0</commons.io.version>
<commons.collections.version>3.2.2</commons.collections.version>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
<jwt.version>0.9.1</jwt.version> <jwt.version>0.9.1</jwt.version>
@ -36,6 +37,24 @@
<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>
<!-- SpringSecurity的依赖配置-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-bom</artifactId>
<version>${spring-security.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- SpringBoot的依赖配置--> <!-- SpringBoot的依赖配置-->
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
@ -107,13 +126,6 @@
<version>${velocity.version}</version> <version>${velocity.version}</version>
</dependency> </dependency>
<!-- collections工具类 -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>${commons.collections.version}</version>
</dependency>
<!-- 阿里JSON解析器 --> <!-- 阿里JSON解析器 -->
<dependency> <dependency>
<groupId>com.alibaba.fastjson2</groupId> <groupId>com.alibaba.fastjson2</groupId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.7</version> <version>3.8.8</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>

View File

@ -7,6 +7,7 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Properties; import java.util.Properties;
import java.util.Set; import java.util.Set;
import java.util.TreeSet;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.RedisTemplate;
@ -80,7 +81,7 @@ public class CacheController
public AjaxResult getCacheKeys(@PathVariable String cacheName) public AjaxResult getCacheKeys(@PathVariable String cacheName)
{ {
Set<String> cacheKeys = redisTemplate.keys(cacheName + "*"); Set<String> cacheKeys = redisTemplate.keys(cacheName + "*");
return AjaxResult.success(cacheKeys); return AjaxResult.success(new TreeSet<>(cacheKeys));
} }
@PreAuthorize("@ss.hasPermi('monitor:cache:list')") @PreAuthorize("@ss.hasPermi('monitor:cache:list')")

View File

@ -124,6 +124,8 @@ public class SysUserController extends BaseController
@PostMapping @PostMapping
public AjaxResult add(@Validated @RequestBody SysUser user) public AjaxResult add(@Validated @RequestBody SysUser user)
{ {
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user)) if (!userService.checkUserNameUnique(user))
{ {
return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在"); return error("新增用户'" + user.getUserName() + "'失败,登录账号已存在");
@ -151,6 +153,8 @@ public class SysUserController extends BaseController
{ {
userService.checkUserAllowed(user); userService.checkUserAllowed(user);
userService.checkUserDataScope(user.getUserId()); userService.checkUserDataScope(user.getUserId());
deptService.checkDeptDataScope(user.getDeptId());
roleService.checkRoleDataScope(user.getRoleIds());
if (!userService.checkUserNameUnique(user)) if (!userService.checkUserNameUnique(user))
{ {
return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在"); return error("修改用户'" + user.getUserName() + "'失败,登录账号已存在");
@ -235,6 +239,7 @@ public class SysUserController extends BaseController
public AjaxResult insertAuthRole(Long userId, Long[] roleIds) public AjaxResult insertAuthRole(Long userId, Long[] roleIds)
{ {
userService.checkUserDataScope(userId); userService.checkUserDataScope(userId);
roleService.checkRoleDataScope(roleIds);
userService.insertUserAuth(userId, roleIds); userService.insertUserAuth(userId, roleIds);
return success(); return success();
} }

View File

@ -3,9 +3,9 @@ ruoyi:
# 名称 # 名称
name: RuoYi name: RuoYi
# 版本 # 版本
version: 3.8.7 version: 3.8.8
# 版权年份 # 版权年份
copyrightYear: 2023 copyrightYear: 2024
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath # 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
profile: D:/ruoyi/uploadPath profile: D:/ruoyi/uploadPath
# 获取ip地址开关 # 获取ip地址开关

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.7</version> <version>3.8.8</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -59,13 +59,6 @@
<artifactId>jackson-databind</artifactId> <artifactId>jackson-databind</artifactId>
</dependency> </dependency>
<!-- 动态数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!-- 阿里JSON解析器 --> <!-- 阿里JSON解析器 -->
<dependency> <dependency>
<groupId>com.alibaba.fastjson2</groupId> <groupId>com.alibaba.fastjson2</groupId>

View File

@ -88,6 +88,11 @@ public @interface Excel
*/ */
public String[] combo() default {}; public String[] combo() default {};
/**
* 是否从字典读数据到combo,默认不读取,如读取需要设置dictType注解.
*/
public boolean comboReadDict() default false;
/** /**
* 是否需要纵向合并单元格,应对需求:含有list集合单元格) * 是否需要纵向合并单元格,应对需求:含有list集合单元格)
*/ */
@ -171,7 +176,7 @@ public @interface Excel
public enum ColumnType public enum ColumnType
{ {
NUMERIC(0), STRING(1), IMAGE(2); NUMERIC(0), STRING(1), IMAGE(2), TEXT(3);
private final int value; private final int value;
ColumnType(int value) ColumnType(int value)

View File

@ -0,0 +1,24 @@
package com.ruoyi.common.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import com.fasterxml.jackson.annotation.JacksonAnnotationsInside;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.ruoyi.common.config.serializer.SensitiveJsonSerializer;
import com.ruoyi.common.enums.DesensitizedType;
/**
* 数据脱敏注解
*
* @author ruoyi
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@JacksonAnnotationsInside
@JsonSerialize(using = SensitiveJsonSerializer.class)
public @interface Sensitive
{
DesensitizedType desensitizedType();
}

View File

@ -0,0 +1,67 @@
package com.ruoyi.common.config.serializer;
import java.io.IOException;
import java.util.Objects;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.BeanProperty;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.ContextualSerializer;
import com.ruoyi.common.annotation.Sensitive;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.DesensitizedType;
import com.ruoyi.common.utils.SecurityUtils;
/**
* 数据脱敏序列化过滤
*
* @author ruoyi
*/
public class SensitiveJsonSerializer extends JsonSerializer<String> implements ContextualSerializer
{
private DesensitizedType desensitizedType;
@Override
public void serialize(String value, JsonGenerator gen, SerializerProvider serializers) throws IOException
{
if (desensitization())
{
gen.writeString(desensitizedType.desensitizer().apply(value));
}
else
{
gen.writeString(value);
}
}
@Override
public JsonSerializer<?> createContextual(SerializerProvider prov, BeanProperty property)
throws JsonMappingException
{
Sensitive annotation = property.getAnnotation(Sensitive.class);
if (Objects.nonNull(annotation) && Objects.equals(String.class, property.getType().getRawClass()))
{
this.desensitizedType = annotation.desensitizedType();
return this;
}
return prov.findValueSerializer(property.getType(), property);
}
/**
* 是否需要脱敏处理
*/
private boolean desensitization()
{
try
{
LoginUser securityUser = SecurityUtils.getLoginUser();
// 管理员不脱敏
return !securityUser.getUser().isAdmin();
}
catch (Exception e)
{
return true;
}
}
}

View File

@ -1,5 +1,6 @@
package com.ruoyi.common.constant; package com.ruoyi.common.constant;
import java.util.Locale;
import io.jsonwebtoken.Claims; import io.jsonwebtoken.Claims;
/** /**
@ -19,6 +20,11 @@ public class Constants
*/ */
public static final String GBK = "GBK"; public static final String GBK = "GBK";
/**
* 系统语言
*/
public static final Locale DEFAULT_LOCALE = Locale.SIMPLIFIED_CHINESE;
/** /**
* www主域 * www主域
*/ */
@ -157,11 +163,11 @@ public class Constants
/** /**
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加) * 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
*/ */
public static final String[] JOB_WHITELIST_STR = { "com.ruoyi" }; public static final String[] JOB_WHITELIST_STR = { "com.ruoyi.quartz.task" };
/** /**
* 定时任务违规的字符 * 定时任务违规的字符
*/ */
public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml", public static final String[] JOB_ERROR_STR = { "java.net.URL", "javax.naming.InitialContext", "org.yaml.snakeyaml",
"org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config" }; "org.springframework", "org.apache", "com.ruoyi.common.utils.file", "com.ruoyi.common.config", "com.ruoyi.generator" };
} }

View File

@ -42,6 +42,9 @@ public class SysMenu extends BaseEntity
/** 路由参数 */ /** 路由参数 */
private String query; private String query;
/** 路由名称默认和路由地址相同的驼峰格式注意因为vue3版本的router会删除名称相同路由为避免名字的冲突特殊情况可以自定义 */
private String routeName;
/** 是否为外链0是 1否 */ /** 是否为外链0是 1否 */
private String isFrame; private String isFrame;
@ -151,6 +154,16 @@ public class SysMenu extends BaseEntity
this.query = query; this.query = query;
} }
public String getRouteName()
{
return routeName;
}
public void setRouteName(String routeName)
{
this.routeName = routeName;
}
public String getIsFrame() public String getIsFrame()
{ {
return isFrame; return isFrame;
@ -242,6 +255,8 @@ public class SysMenu extends BaseEntity
.append("orderNum", getOrderNum()) .append("orderNum", getOrderNum())
.append("path", getPath()) .append("path", getPath())
.append("component", getComponent()) .append("component", getComponent())
.append("query", getQuery())
.append("routeName", getRouteName())
.append("isFrame", getIsFrame()) .append("isFrame", getIsFrame())
.append("IsCache", getIsCache()) .append("IsCache", getIsCache())
.append("menuType", getMenuType()) .append("menuType", getMenuType())

View File

@ -22,7 +22,7 @@ public class SysUser extends BaseEntity
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
/** 用户ID */ /** 用户ID */
@Excel(name = "用户序号", cellType = ColumnType.NUMERIC, prompt = "用户编号") @Excel(name = "用户序号", type = Type.EXPORT, cellType = ColumnType.NUMERIC, prompt = "用户编号")
private Long userId; private Long userId;
/** 部门ID */ /** 部门ID */
@ -42,7 +42,7 @@ public class SysUser extends BaseEntity
private String email; private String email;
/** 手机号码 */ /** 手机号码 */
@Excel(name = "手机号码") @Excel(name = "手机号码", cellType = ColumnType.TEXT)
private String phonenumber; private String phonenumber;
/** 用户性别 */ /** 用户性别 */

View File

@ -365,6 +365,10 @@ public class Convert
*/ */
public static String[] toStrArray(String str) public static String[] toStrArray(String str)
{ {
if (StringUtils.isEmpty(str))
{
return new String[] {};
}
return toStrArray(",", str); return toStrArray(",", str);
} }

View File

@ -0,0 +1,59 @@
package com.ruoyi.common.enums;
import java.util.function.Function;
import com.ruoyi.common.utils.DesensitizedUtil;
/**
* 脱敏类型
*
* @author ruoyi
*/
public enum DesensitizedType
{
/**
* 姓名第2位星号替换
*/
USERNAME(s -> s.replaceAll("(\\S)\\S(\\S*)", "$1*$2")),
/**
* 密码,全部字符都用*代替
*/
PASSWORD(DesensitizedUtil::password),
/**
* 身份证中间10位星号替换
*/
ID_CARD(s -> s.replaceAll("(\\d{4})\\d{10}(\\d{4})", "$1** **** ****$2")),
/**
* 手机号中间4位星号替换
*/
PHONE(s -> s.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2")),
/**
* 电子邮箱,仅显示第一个字母和@后面的地址显示,其他星号替换
*/
EMAIL(s -> s.replaceAll("(^.)[^@]*(@.*$)", "$1****$2")),
/**
* 银行卡号保留最后4位其他星号替换
*/
BANK_CARD(s -> s.replaceAll("\\d{15}(\\d{3})", "**** **** **** **** $1")),
/**
* 车牌号码,包含普通车辆、新能源车辆
*/
CAR_LICENSE(DesensitizedUtil::carLicense);
private final Function<String, String> desensitizer;
DesensitizedType(Function<String, String> desensitizer)
{
this.desensitizer = desensitizer;
}
public Function<String, String> desensitizer()
{
return desensitizer;
}
}

View File

@ -32,10 +32,10 @@ public class XssFilter implements Filter
String tempExcludes = filterConfig.getInitParameter("excludes"); String tempExcludes = filterConfig.getInitParameter("excludes");
if (StringUtils.isNotEmpty(tempExcludes)) if (StringUtils.isNotEmpty(tempExcludes))
{ {
String[] url = tempExcludes.split(","); String[] urls = tempExcludes.split(",");
for (int i = 0; url != null && i < url.length; i++) for (String url : urls)
{ {
excludes.add(url[i]); excludes.add(url);
} }
} }
} }

View File

@ -0,0 +1,49 @@
package com.ruoyi.common.utils;
/**
* 脱敏工具类
*
* @author ruoyi
*/
public class DesensitizedUtil
{
/**
* 密码的全部字符都用*代替,比如:******
*
* @param password 密码
* @return 脱敏后的密码
*/
public static String password(String password)
{
if (StringUtils.isBlank(password))
{
return StringUtils.EMPTY;
}
return StringUtils.repeat('*', password.length());
}
/**
* 车牌中间用*代替,如果是错误的车牌,不处理
*
* @param carLicense 完整的车牌号
* @return 脱敏后的车牌
*/
public static String carLicense(String carLicense)
{
if (StringUtils.isBlank(carLicense))
{
return StringUtils.EMPTY;
}
// 普通车牌
if (carLicense.length() == 7)
{
carLicense = StringUtils.hide(carLicense, 3, 6);
}
else if (carLicense.length() == 8)
{
// 新能源车牌
carLicense = StringUtils.hide(carLicense, 3, 7);
}
return carLicense;
}
}

View File

@ -56,6 +56,10 @@ public class DictUtils
*/ */
public static String getDictLabel(String dictType, String dictValue) public static String getDictLabel(String dictType, String dictValue)
{ {
if (StringUtils.isEmpty(dictValue))
{
return StringUtils.EMPTY;
}
return getDictLabel(dictType, dictValue, SEPARATOR); return getDictLabel(dictType, dictValue, SEPARATOR);
} }
@ -68,6 +72,10 @@ public class DictUtils
*/ */
public static String getDictValue(String dictType, String dictLabel) public static String getDictValue(String dictType, String dictLabel)
{ {
if (StringUtils.isEmpty(dictLabel))
{
return StringUtils.EMPTY;
}
return getDictValue(dictType, dictLabel, SEPARATOR); return getDictValue(dictType, dictLabel, SEPARATOR);
} }
@ -83,31 +91,31 @@ public class DictUtils
{ {
StringBuilder propertyString = new StringBuilder(); StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = getDictCache(dictType); List<SysDictData> datas = getDictCache(dictType);
if (StringUtils.isNull(datas))
if (StringUtils.isNotNull(datas))
{ {
if (StringUtils.containsAny(separator, dictValue)) return StringUtils.EMPTY;
}
if (StringUtils.containsAny(separator, dictValue))
{
for (SysDictData dict : datas)
{ {
for (SysDictData dict : datas) for (String value : dictValue.split(separator))
{ {
for (String value : dictValue.split(separator)) if (value.equals(dict.getDictValue()))
{ {
if (value.equals(dict.getDictValue())) propertyString.append(dict.getDictLabel()).append(separator);
{ break;
propertyString.append(dict.getDictLabel()).append(separator);
break;
}
} }
} }
} }
else }
else
{
for (SysDictData dict : datas)
{ {
for (SysDictData dict : datas) if (dictValue.equals(dict.getDictValue()))
{ {
if (dictValue.equals(dict.getDictValue())) return dict.getDictLabel();
{
return dict.getDictLabel();
}
} }
} }
} }
@ -126,8 +134,11 @@ public class DictUtils
{ {
StringBuilder propertyString = new StringBuilder(); StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = getDictCache(dictType); List<SysDictData> datas = getDictCache(dictType);
if (StringUtils.isNull(datas))
if (StringUtils.containsAny(separator, dictLabel) && StringUtils.isNotEmpty(datas)) {
return StringUtils.EMPTY;
}
if (StringUtils.containsAny(separator, dictLabel))
{ {
for (SysDictData dict : datas) for (SysDictData dict : datas)
{ {
@ -154,6 +165,48 @@ public class DictUtils
return StringUtils.stripEnd(propertyString.toString(), separator); return StringUtils.stripEnd(propertyString.toString(), separator);
} }
/**
* 根据字典类型获取字典所有值
*
* @param dictType 字典类型
* @return 字典值
*/
public static String getDictValues(String dictType)
{
StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = getDictCache(dictType);
if (StringUtils.isNull(datas))
{
return StringUtils.EMPTY;
}
for (SysDictData dict : datas)
{
propertyString.append(dict.getDictValue()).append(SEPARATOR);
}
return StringUtils.stripEnd(propertyString.toString(), SEPARATOR);
}
/**
* 根据字典类型获取字典所有标签
*
* @param dictType 字典类型
* @return 字典值
*/
public static String getDictLabels(String dictType)
{
StringBuilder propertyString = new StringBuilder();
List<SysDictData> datas = getDictCache(dictType);
if (StringUtils.isNull(datas))
{
return StringUtils.EMPTY;
}
for (SysDictData dict : datas)
{
propertyString.append(dict.getDictLabel()).append(SEPARATOR);
}
return StringUtils.stripEnd(propertyString.toString(), SEPARATOR);
}
/** /**
* 删除指定字典缓存 * 删除指定字典缓存
* *

View File

@ -23,6 +23,9 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
/** 下划线 */ /** 下划线 */
private static final char SEPARATOR = '_'; private static final char SEPARATOR = '_';
/** 星号 */
private static final char ASTERISK = '*';
/** /**
* 获取参数不为空值 * 获取参数不为空值
* *
@ -163,6 +166,49 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
return (str == null ? "" : str.trim()); return (str == null ? "" : str.trim());
} }
/**
* 替换指定字符串的指定区间内字符为"*"
*
* @param str 字符串
* @param startInclude 开始位置(包含)
* @param endExclude 结束位置(不包含)
* @return 替换后的字符串
*/
public static String hide(CharSequence str, int startInclude, int endExclude)
{
if (isEmpty(str))
{
return NULLSTR;
}
final int strLength = str.length();
if (startInclude > strLength)
{
return NULLSTR;
}
if (endExclude > strLength)
{
endExclude = strLength;
}
if (startInclude > endExclude)
{
// 如果起始位置大于结束位置,不替换
return NULLSTR;
}
final char[] chars = new char[strLength];
for (int i = 0; i < strLength; i++)
{
if (i >= startInclude && i < endExclude)
{
chars[i] = ASTERISK;
}
else
{
chars[i] = str.charAt(i);
}
}
return new String(chars);
}
/** /**
* 截取字符串 * 截取字符串
* *

View File

@ -25,7 +25,7 @@ public class FileUploadUtils
/** /**
* 默认大小 50M * 默认大小 50M
*/ */
public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024; public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024L;
/** /**
* 默认的文件名最大长度 100 * 默认的文件名最大长度 100

View File

@ -74,7 +74,7 @@ public class HttpUtils
URLConnection connection = realUrl.openConnection(); URLConnection connection = realUrl.openConnection();
connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("accept", "*/*");
connection.setRequestProperty("connection", "Keep-Alive"); connection.setRequestProperty("connection", "Keep-Alive");
connection.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); connection.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
connection.connect(); connection.connect();
in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType)); in = new BufferedReader(new InputStreamReader(connection.getInputStream(), contentType));
String line; String line;
@ -136,7 +136,7 @@ public class HttpUtils
URLConnection conn = realUrl.openConnection(); URLConnection conn = realUrl.openConnection();
conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
conn.setRequestProperty("Accept-Charset", "utf-8"); conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8"); conn.setRequestProperty("contentType", "utf-8");
conn.setDoOutput(true); conn.setDoOutput(true);
@ -202,7 +202,7 @@ public class HttpUtils
HttpsURLConnection conn = (HttpsURLConnection) console.openConnection(); HttpsURLConnection conn = (HttpsURLConnection) console.openConnection();
conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("accept", "*/*");
conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("connection", "Keep-Alive");
conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); conn.setRequestProperty("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)");
conn.setRequestProperty("Accept-Charset", "utf-8"); conn.setRequestProperty("Accept-Charset", "utf-8");
conn.setRequestProperty("contentType", "utf-8"); conn.setRequestProperty("contentType", "utf-8");
conn.setDoOutput(true); conn.setDoOutput(true);

View File

@ -39,6 +39,7 @@ import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle; import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.ClientAnchor; import org.apache.poi.ss.usermodel.ClientAnchor;
import org.apache.poi.ss.usermodel.DataFormat;
import org.apache.poi.ss.usermodel.DataValidation; import org.apache.poi.ss.usermodel.DataValidation;
import org.apache.poi.ss.usermodel.DataValidationConstraint; import org.apache.poi.ss.usermodel.DataValidationConstraint;
import org.apache.poi.ss.usermodel.DataValidationHelper; import org.apache.poi.ss.usermodel.DataValidationHelper;
@ -470,7 +471,12 @@ public class ExcelUtil<T>
} }
else if (StringUtils.isNotEmpty(attr.dictType())) else if (StringUtils.isNotEmpty(attr.dictType()))
{ {
val = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator()); if (!sysDictMap.containsKey(attr.dictType() + val))
{
String dictValue = reverseDictByExp(Convert.toStr(val), attr.dictType(), attr.separator());
sysDictMap.put(attr.dictType() + val, dictValue);
}
val = sysDictMap.get(attr.dictType() + val);
} }
else if (!attr.handler().equals(ExcelHandlerAdapter.class)) else if (!attr.handler().equals(ExcelHandlerAdapter.class))
{ {
@ -783,6 +789,8 @@ public class ExcelUtil<T>
titleFont.setFontHeightInPoints((short) 16); titleFont.setFontHeightInPoints((short) 16);
titleFont.setBold(true); titleFont.setBold(true);
style.setFont(titleFont); style.setFont(titleFont);
DataFormat dataFormat = wb.createDataFormat();
style.setDataFormat(dataFormat.getFormat("@"));
styles.put("title", style); styles.put("title", style);
style = wb.createCellStyle(); style = wb.createCellStyle();
@ -845,6 +853,9 @@ public class ExcelUtil<T>
headerFont.setBold(true); headerFont.setBold(true);
headerFont.setColor(excel.headerColor().index); headerFont.setColor(excel.headerColor().index);
style.setFont(headerFont); style.setFont(headerFont);
// 设置表格头单元格文本形式
DataFormat dataFormat = wb.createDataFormat();
style.setDataFormat(dataFormat.getFormat("@"));
headerStyles.put(key, style); headerStyles.put(key, style);
} }
} }
@ -862,34 +873,66 @@ public class ExcelUtil<T>
Map<String, CellStyle> styles = new HashMap<String, CellStyle>(); Map<String, CellStyle> styles = new HashMap<String, CellStyle>();
for (Object[] os : fields) for (Object[] os : fields)
{ {
Field field = (Field) os[0];
Excel excel = (Excel) os[1]; Excel excel = (Excel) os[1];
String key = StringUtils.format("data_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor()); if (Collection.class.isAssignableFrom(field.getType()))
if (!styles.containsKey(key))
{ {
CellStyle style = wb.createCellStyle(); ParameterizedType pt = (ParameterizedType) field.getGenericType();
style.setAlignment(excel.align()); Class<?> subClass = (Class<?>) pt.getActualTypeArguments()[0];
style.setVerticalAlignment(VerticalAlignment.CENTER); List<Field> subFields = FieldUtils.getFieldsListWithAnnotation(subClass, Excel.class);
style.setBorderRight(BorderStyle.THIN); for (Field subField : subFields)
style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); {
style.setBorderLeft(BorderStyle.THIN); Excel subExcel = subField.getAnnotation(Excel.class);
style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); annotationDataStyles(styles, subField, subExcel);
style.setBorderTop(BorderStyle.THIN); }
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); }
style.setBorderBottom(BorderStyle.THIN); else
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex()); {
style.setFillPattern(FillPatternType.SOLID_FOREGROUND); annotationDataStyles(styles, field, excel);
style.setFillForegroundColor(excel.backgroundColor().getIndex());
Font dataFont = wb.createFont();
dataFont.setFontName("Arial");
dataFont.setFontHeightInPoints((short) 10);
dataFont.setColor(excel.color().index);
style.setFont(dataFont);
styles.put(key, style);
} }
} }
return styles; return styles;
} }
/**
* 根据Excel注解创建表格列样式
*
* @param styles 自定义样式列表
* @param field 属性列信息
* @param excel 注解信息
*/
public void annotationDataStyles(Map<String, CellStyle> styles, Field field, Excel excel)
{
String key = StringUtils.format("data_{}_{}_{}_{}", excel.align(), excel.color(), excel.backgroundColor(), excel.cellType());
if (!styles.containsKey(key))
{
CellStyle style = wb.createCellStyle();
style.setAlignment(excel.align());
style.setVerticalAlignment(VerticalAlignment.CENTER);
style.setBorderRight(BorderStyle.THIN);
style.setRightBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderLeft(BorderStyle.THIN);
style.setLeftBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderTop(BorderStyle.THIN);
style.setTopBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setBorderBottom(BorderStyle.THIN);
style.setBottomBorderColor(IndexedColors.GREY_50_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
style.setFillForegroundColor(excel.backgroundColor().getIndex());
Font dataFont = wb.createFont();
dataFont.setFontName("Arial");
dataFont.setFontHeightInPoints((short) 10);
dataFont.setColor(excel.color().index);
style.setFont(dataFont);
if (ColumnType.TEXT == excel.cellType())
{
DataFormat dataFormat = wb.createDataFormat();
style.setDataFormat(dataFormat.getFormat("@"));
}
styles.put(key, style);
}
}
/** /**
* 创建单元格 * 创建单元格
*/ */
@ -904,7 +947,7 @@ public class ExcelUtil<T>
if (isSubList()) if (isSubList())
{ {
// 填充默认样式,防止合并单元格样式失效 // 填充默认样式,防止合并单元格样式失效
sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor()))); sheet.setDefaultColumnStyle(column, styles.get(StringUtils.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType())));
if (attr.needMerge()) if (attr.needMerge())
{ {
sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column)); sheet.addMergedRegion(new CellRangeAddress(rownum - 1, rownum, column, column));
@ -922,7 +965,7 @@ public class ExcelUtil<T>
*/ */
public void setCellVo(Object value, Excel attr, Cell cell) public void setCellVo(Object value, Excel attr, Cell cell)
{ {
if (ColumnType.STRING == attr.cellType()) if (ColumnType.STRING == attr.cellType() || ColumnType.TEXT == attr.cellType())
{ {
String cellValue = Convert.toStr(value); String cellValue = Convert.toStr(value);
// 对于任何以表达式触发字符 =-+@开头的单元格直接使用tab字符作为前缀防止CSV注入。 // 对于任何以表达式触发字符 =-+@开头的单元格直接使用tab字符作为前缀防止CSV注入。
@ -999,17 +1042,28 @@ public class ExcelUtil<T>
// 设置列宽 // 设置列宽
sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256)); sheet.setColumnWidth(column, (int) ((attr.width() + 0.72) * 256));
} }
if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0) if (StringUtils.isNotEmpty(attr.prompt()) || attr.combo().length > 0 || attr.comboReadDict())
{ {
if (attr.combo().length > 15 || StringUtils.join(attr.combo()).length() > 255) String[] comboArray = attr.combo();
if (attr.comboReadDict())
{
if (!sysDictMap.containsKey("combo_" + attr.dictType()))
{
String labels = DictUtils.getDictLabels(attr.dictType());
sysDictMap.put("combo_" + attr.dictType(), labels);
}
String val = sysDictMap.get("combo_" + attr.dictType());
comboArray = StringUtils.split(val, DictUtils.SEPARATOR);
}
if (comboArray.length > 15 || StringUtils.join(comboArray).length() > 255)
{ {
// 如果下拉数大于15或字符串长度大于255则使用一个新sheet存储避免生成的模板下拉值获取不到 // 如果下拉数大于15或字符串长度大于255则使用一个新sheet存储避免生成的模板下拉值获取不到
setXSSFValidationWithHidden(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); setXSSFValidationWithHidden(sheet, comboArray, attr.prompt(), 1, 100, column, column);
} }
else else
{ {
// 提示信息或只能选择不能输入的列内容. // 提示信息或只能选择不能输入的列内容.
setPromptOrValidation(sheet, attr.combo(), attr.prompt(), 1, 100, column, column); setPromptOrValidation(sheet, comboArray, attr.prompt(), 1, 100, column, column);
} }
} }
} }
@ -1034,7 +1088,7 @@ public class ExcelUtil<T>
CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column); CellRangeAddress cellAddress = new CellRangeAddress(subMergedFirstRowNum, subMergedLastRowNum, column, column);
sheet.addMergedRegion(cellAddress); sheet.addMergedRegion(cellAddress);
} }
cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor()))); cell.setCellStyle(styles.get(StringUtils.format("data_{}_{}_{}_{}", attr.align(), attr.color(), attr.backgroundColor(), attr.cellType())));
// 用于读取对象中的属性 // 用于读取对象中的属性
Object value = getTargetValue(vo, field, attr); Object value = getTargetValue(vo, field, attr);

View File

@ -27,8 +27,13 @@ public class XssValidator implements ConstraintValidator<Xss, String>
public static boolean containsHtml(String value) public static boolean containsHtml(String value)
{ {
StringBuilder sHtml = new StringBuilder();
Pattern pattern = Pattern.compile(HTML_PATTERN); Pattern pattern = Pattern.compile(HTML_PATTERN);
Matcher matcher = pattern.matcher(value); Matcher matcher = pattern.matcher(value);
return matcher.matches(); while (matcher.find())
{
sHtml.append(matcher.group());
}
return pattern.matcher(sHtml).matches();
} }
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.7</version> <version>3.8.8</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -92,16 +92,22 @@ public class DataScopeAspect
{ {
StringBuilder sqlString = new StringBuilder(); StringBuilder sqlString = new StringBuilder();
List<String> conditions = new ArrayList<String>(); List<String> conditions = new ArrayList<String>();
List<String> scopeCustomIds = new ArrayList<String>();
user.getRoles().forEach(role -> {
if (DATA_SCOPE_CUSTOM.equals(role.getDataScope()) && StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
{
scopeCustomIds.add(Convert.toStr(role.getRoleId()));
}
});
for (SysRole role : user.getRoles()) for (SysRole role : user.getRoles())
{ {
String dataScope = role.getDataScope(); String dataScope = role.getDataScope();
if (!DATA_SCOPE_CUSTOM.equals(dataScope) && conditions.contains(dataScope)) if (conditions.contains(dataScope))
{ {
continue; continue;
} }
if (StringUtils.isNotEmpty(permission) && StringUtils.isNotEmpty(role.getPermissions()) if (!StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
&& !StringUtils.containsAny(role.getPermissions(), Convert.toStrArray(permission)))
{ {
continue; continue;
} }
@ -113,9 +119,15 @@ public class DataScopeAspect
} }
else if (DATA_SCOPE_CUSTOM.equals(dataScope)) else if (DATA_SCOPE_CUSTOM.equals(dataScope))
{ {
sqlString.append(StringUtils.format( if (scopeCustomIds.size() > 1)
" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, {
role.getRoleId())); // 多个自定数据权限使用in查询避免多次拼接。
sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id in ({}) ) ", deptAlias, String.join(",", scopeCustomIds)));
}
else
{
sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias, role.getRoleId()));
}
} }
else if (DATA_SCOPE_DEPT.equals(dataScope)) else if (DATA_SCOPE_DEPT.equals(dataScope))
{ {
@ -123,9 +135,7 @@ public class DataScopeAspect
} }
else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope)) else if (DATA_SCOPE_DEPT_AND_CHILD.equals(dataScope))
{ {
sqlString.append(StringUtils.format( sqlString.append(StringUtils.format(" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )", deptAlias, user.getDeptId(), user.getDeptId()));
" OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
deptAlias, user.getDeptId(), user.getDeptId()));
} }
else if (DATA_SCOPE_SELF.equals(dataScope)) else if (DATA_SCOPE_SELF.equals(dataScope))
{ {
@ -142,7 +152,7 @@ public class DataScopeAspect
conditions.add(dataScope); conditions.add(dataScope);
} }
// 多角色情况下,所有角色都不包含传递过来的权限字符这个时候sqlString也会为空所以要限制一下,不查询任何数据 // 角色都不包含传递过来的权限字符这个时候sqlString也会为空所以要限制一下,不查询任何数据
if (StringUtils.isEmpty(conditions)) if (StringUtils.isEmpty(conditions))
{ {
sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias)); sqlString.append(StringUtils.format(" OR {}.dept_id = 0 ", deptAlias));

View File

@ -0,0 +1,43 @@
package com.ruoyi.framework.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.LocaleResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import com.ruoyi.common.constant.Constants;
/**
* 资源文件配置加载
*
* @author ruoyi
*/
@Configuration
public class I18nConfig implements WebMvcConfigurer
{
@Bean
public LocaleResolver localeResolver()
{
SessionLocaleResolver slr = new SessionLocaleResolver();
// 默认语言
slr.setDefaultLocale(Constants.DEFAULT_LOCALE);
return slr;
}
@Bean
public LocaleChangeInterceptor localeChangeInterceptor()
{
LocaleChangeInterceptor lci = new LocaleChangeInterceptor();
// 参数名
lci.setParamName("lang");
return lci;
}
@Override
public void addInterceptors(InterceptorRegistry registry)
{
registry.addInterceptor(localeChangeInterceptor());
}
}

View File

@ -2,16 +2,17 @@ package com.ruoyi.framework.config;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod; import org.springframework.http.HttpMethod;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder; import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity; import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.annotation.web.configurers.ExpressionUrlAuthorizationConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy; import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.core.userdetails.UserDetailsService; import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.logout.LogoutFilter; import org.springframework.security.web.authentication.logout.LogoutFilter;
import org.springframework.web.filter.CorsFilter; import org.springframework.web.filter.CorsFilter;
@ -25,8 +26,9 @@ import com.ruoyi.framework.security.handle.LogoutSuccessHandlerImpl;
* *
* @author ruoyi * @author ruoyi
*/ */
@EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true) @EnableMethodSecurity(prePostEnabled = true, securedEnabled = true)
public class SecurityConfig extends WebSecurityConfigurerAdapter @Configuration
public class SecurityConfig
{ {
/** /**
* 自定义用户认证逻辑 * 自定义用户认证逻辑
@ -65,16 +67,15 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
private PermitAllUrlProperties permitAllUrl; private PermitAllUrlProperties permitAllUrl;
/** /**
* 解决 无法直接注入 AuthenticationManager * 身份验证实现
*
* @return
* @throws Exception
*/ */
@Bean @Bean
@Override public AuthenticationManager authenticationManager()
public AuthenticationManager authenticationManagerBean() throws Exception
{ {
return super.authenticationManagerBean(); DaoAuthenticationProvider daoAuthenticationProvider = new DaoAuthenticationProvider();
daoAuthenticationProvider.setUserDetailsService(userDetailsService);
daoAuthenticationProvider.setPasswordEncoder(bCryptPasswordEncoder());
return new ProviderManager(daoAuthenticationProvider);
} }
/** /**
@ -92,40 +93,39 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
* rememberMe | 允许通过remember-me登录的用户访问 * rememberMe | 允许通过remember-me登录的用户访问
* authenticated | 用户登录后可访问 * authenticated | 用户登录后可访问
*/ */
@Override @Bean
protected void configure(HttpSecurity httpSecurity) throws Exception protected SecurityFilterChain filterChain(HttpSecurity httpSecurity) throws Exception
{ {
// 注解标记允许匿名访问的url return httpSecurity
ExpressionUrlAuthorizationConfigurer<HttpSecurity>.ExpressionInterceptUrlRegistry registry = httpSecurity.authorizeRequests(); // CSRF禁用因为不使用session
permitAllUrl.getUrls().forEach(url -> registry.antMatchers(url).permitAll()); .csrf(csrf -> csrf.disable())
// 禁用HTTP响应标头
httpSecurity .headers((headersCustomizer) -> {
// CSRF禁用因为不使用session headersCustomizer.cacheControl(cache -> cache.disable()).frameOptions(options -> options.sameOrigin());
.csrf().disable() })
// 禁用HTTP响应标头 // 认证失败处理类
.headers().cacheControl().disable().and() .exceptionHandling(exception -> exception.authenticationEntryPoint(unauthorizedHandler))
// 认证失败处理类 // 基于token所以不需要session
.exceptionHandling().authenticationEntryPoint(unauthorizedHandler).and() .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
// 基于token所以不需要session // 注解标记允许匿名访问的url
.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS).and() .authorizeHttpRequests((requests) -> {
// 过滤请求 permitAllUrl.getUrls().forEach(url -> requests.antMatchers(url).permitAll());
.authorizeRequests()
// 对于登录login 注册register 验证码captchaImage 允许匿名访问 // 对于登录login 注册register 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/register", "/captchaImage").permitAll() requests.antMatchers("/login", "/register", "/captchaImage").permitAll()
// 静态资源,可匿名访问 // 静态资源,可匿名访问
.antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll() .antMatchers(HttpMethod.GET, "/", "/*.html", "/**/*.html", "/**/*.css", "/**/*.js", "/profile/**").permitAll()
.antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll() .antMatchers("/swagger-ui.html", "/swagger-resources/**", "/webjars/**", "/*/api-docs", "/druid/**").permitAll()
// 除上面外的所有请求全部需要鉴权认证 // 除上面外的所有请求全部需要鉴权认证
.anyRequest().authenticated() .anyRequest().authenticated();
.and() })
.headers().frameOptions().disable(); // 添加Logout filter
// 添加Logout filter .logout(logout -> logout.logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler))
httpSecurity.logout().logoutUrl("/logout").logoutSuccessHandler(logoutSuccessHandler); // 添加JWT filter
// 添加JWT filter .addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class)
httpSecurity.addFilterBefore(authenticationTokenFilter, UsernamePasswordAuthenticationFilter.class); // 添加CORS filter
// 添加CORS filter .addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class)
httpSecurity.addFilterBefore(corsFilter, JwtAuthenticationTokenFilter.class); .addFilterBefore(corsFilter, LogoutFilter.class)
httpSecurity.addFilterBefore(corsFilter, LogoutFilter.class); .build();
} }
/** /**
@ -136,13 +136,4 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
{ {
return new BCryptPasswordEncoder(); return new BCryptPasswordEncoder();
} }
/**
* 身份认证接口
*/
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception
{
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
} }

View File

@ -12,6 +12,7 @@ import com.alibaba.fastjson2.JSON;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.AsyncManager;
@ -45,8 +46,8 @@ public class LogoutSuccessHandlerImpl implements LogoutSuccessHandler
// 删除用户缓存记录 // 删除用户缓存记录
tokenService.delLoginUser(loginUser.getToken()); tokenService.delLoginUser(loginUser.getToken());
// 记录用户退出日志 // 记录用户退出日志
AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, "退出成功")); AsyncManager.me().execute(AsyncFactory.recordLogininfor(userName, Constants.LOGOUT, MessageUtils.message("user.logout.success")));
} }
ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success("退出成功"))); ServletUtils.renderString(response, JSON.toJSONString(AjaxResult.success(MessageUtils.message("user.logout.success"))));
} }
} }

View File

@ -13,9 +13,11 @@ import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException; import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import com.ruoyi.common.constant.HttpStatus; import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.exception.DemoModeException; import com.ruoyi.common.exception.DemoModeException;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.html.EscapeUtil;
/** /**
* 全局异常处理器 * 全局异常处理器
@ -79,8 +81,13 @@ public class GlobalExceptionHandler
public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request) public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request)
{ {
String requestURI = request.getRequestURI(); String requestURI = request.getRequestURI();
String value = Convert.toStr(e.getValue());
if (StringUtils.isNotEmpty(value))
{
value = EscapeUtil.clean(value);
}
log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e); log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);
return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), e.getValue())); return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), value));
} }
/** /**

View File

@ -115,12 +115,12 @@ public class SysLoginService
{ {
String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); String verifyKey = CacheConstants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, "");
String captcha = redisCache.getCacheObject(verifyKey); String captcha = redisCache.getCacheObject(verifyKey);
redisCache.deleteObject(verifyKey);
if (captcha == null) if (captcha == null)
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.expire")));
throw new CaptchaExpireException(); throw new CaptchaExpireException();
} }
redisCache.deleteObject(verifyKey);
if (!code.equalsIgnoreCase(captcha)) if (!code.equalsIgnoreCase(captcha))
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error"))); AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL, MessageUtils.message("user.jcaptcha.error")));

View File

@ -6,15 +6,11 @@ import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.redis.RedisCache; import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.exception.user.UserPasswordNotMatchException; import com.ruoyi.common.exception.user.UserPasswordNotMatchException;
import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException; import com.ruoyi.common.exception.user.UserPasswordRetryLimitExceedException;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.framework.security.context.AuthenticationContextHolder; import com.ruoyi.framework.security.context.AuthenticationContextHolder;
/** /**
@ -60,16 +56,12 @@ public class SysPasswordService
if (retryCount >= Integer.valueOf(maxRetryCount).intValue()) if (retryCount >= Integer.valueOf(maxRetryCount).intValue())
{ {
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
MessageUtils.message("user.password.retry.limit.exceed", maxRetryCount, lockTime)));
throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime); throw new UserPasswordRetryLimitExceedException(maxRetryCount, lockTime);
} }
if (!matches(user, password)) if (!matches(user, password))
{ {
retryCount = retryCount + 1; retryCount = retryCount + 1;
AsyncManager.me().execute(AsyncFactory.recordLogininfor(username, Constants.LOGIN_FAIL,
MessageUtils.message("user.password.retry.limit.count", retryCount)));
redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES); redisCache.setCacheObject(getCacheKey(username), retryCount, lockTime, TimeUnit.MINUTES);
throw new UserPasswordNotMatchException(); throw new UserPasswordNotMatchException();
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.7</version> <version>3.8.8</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -17,24 +17,24 @@
<dependencies> <dependencies>
<!--velocity代码生成使用模板 --> <!-- velocity代码生成使用模板 -->
<dependency> <dependency>
<groupId>org.apache.velocity</groupId> <groupId>org.apache.velocity</groupId>
<artifactId>velocity-engine-core</artifactId> <artifactId>velocity-engine-core</artifactId>
</dependency> </dependency>
<!-- collections工具类 -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</dependency>
<!-- 通用工具--> <!-- 通用工具-->
<dependency> <dependency>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
</dependency> </dependency>
<!-- 阿里数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -1,6 +1,7 @@
package com.ruoyi.generator.controller; package com.ruoyi.generator.controller;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -17,12 +18,18 @@ import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.alibaba.druid.DbType;
import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlCreateTableStatement;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo; import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.sql.SqlUtil;
import com.ruoyi.generator.domain.GenTable; import com.ruoyi.generator.domain.GenTable;
import com.ruoyi.generator.domain.GenTableColumn; import com.ruoyi.generator.domain.GenTableColumn;
import com.ruoyi.generator.service.IGenTableColumnService; import com.ruoyi.generator.service.IGenTableColumnService;
@ -109,10 +116,47 @@ public class GenController extends BaseController
String[] tableNames = Convert.toStrArray(tables); String[] tableNames = Convert.toStrArray(tables);
// 查询表信息 // 查询表信息
List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames); List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames);
genTableService.importGenTable(tableList); genTableService.importGenTable(tableList, SecurityUtils.getUsername());
return success(); return success();
} }
/**
* 创建表结构(保存)
*/
@PreAuthorize("@ss.hasRole('admin')")
@Log(title = "创建表", businessType = BusinessType.OTHER)
@PostMapping("/createTable")
public AjaxResult createTableSave(String sql)
{
try
{
SqlUtil.filterKeyword(sql);
List<SQLStatement> sqlStatements = SQLUtils.parseStatements(sql, DbType.mysql);
List<String> tableNames = new ArrayList<>();
for (SQLStatement sqlStatement : sqlStatements)
{
if (sqlStatement instanceof MySqlCreateTableStatement)
{
MySqlCreateTableStatement createTableStatement = (MySqlCreateTableStatement) sqlStatement;
if (genTableService.createTable(createTableStatement.toString()))
{
String tableName = createTableStatement.getTableName().replaceAll("`", "");
tableNames.add(tableName);
}
}
}
List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames.toArray(new String[tableNames.size()]));
String operName = SecurityUtils.getUsername();
genTableService.importGenTable(tableList, operName);
return AjaxResult.success();
}
catch (Exception e)
{
logger.error(e.getMessage(), e);
return AjaxResult.error("创建表结构异常");
}
}
/** /**
* 修改保存代码生成业务 * 修改保存代码生成业务
*/ */

View File

@ -80,4 +80,12 @@ public interface GenTableMapper
* @return 结果 * @return 结果
*/ */
public int deleteGenTableByIds(Long[] ids); public int deleteGenTableByIds(Long[] ids);
/**
* 创建表
*
* @param sql 表结构
* @return 结果
*/
public int createTable(String sql);
} }

View File

@ -27,7 +27,6 @@ import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.GenConstants; import com.ruoyi.common.constant.GenConstants;
import com.ruoyi.common.core.text.CharsetKit; import com.ruoyi.common.core.text.CharsetKit;
import com.ruoyi.common.exception.ServiceException; import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.generator.domain.GenTable; import com.ruoyi.generator.domain.GenTable;
import com.ruoyi.generator.domain.GenTableColumn; import com.ruoyi.generator.domain.GenTableColumn;
@ -150,6 +149,18 @@ public class GenTableServiceImpl implements IGenTableService
genTableColumnMapper.deleteGenTableColumnByIds(tableIds); genTableColumnMapper.deleteGenTableColumnByIds(tableIds);
} }
/**
* 创建表
*
* @param sql 创建表语句
* @return 结果
*/
@Override
public boolean createTable(String sql)
{
return genTableMapper.createTable(sql) == 0;
}
/** /**
* 导入表结构 * 导入表结构
* *
@ -157,9 +168,8 @@ public class GenTableServiceImpl implements IGenTableService
*/ */
@Override @Override
@Transactional @Transactional
public void importGenTable(List<GenTable> tableList) public void importGenTable(List<GenTable> tableList, String operName)
{ {
String operName = SecurityUtils.getUsername();
try try
{ {
for (GenTable table : tableList) for (GenTable table : tableList)

View File

@ -66,12 +66,21 @@ public interface IGenTableService
*/ */
public void deleteGenTableByIds(Long[] tableIds); public void deleteGenTableByIds(Long[] tableIds);
/**
* 创建表
*
* @param sql 创建表语句
* @return 结果
*/
public boolean createTable(String sql);
/** /**
* 导入表结构 * 导入表结构
* *
* @param tableList 导入表列表 * @param tableList 导入表列表
* @param operName 操作人员
*/ */
public void importGenTable(List<GenTable> tableList); public void importGenTable(List<GenTable> tableList, String operName);
/** /**
* 预览代码 * 预览代码

View File

@ -26,7 +26,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<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" />
<collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" /> <collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" />
</resultMap> </resultMap>
<resultMap type="GenTableColumn" id="GenTableColumnResult"> <resultMap type="GenTableColumn" id="GenTableColumnResult">
@ -79,7 +79,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectDbTableList" parameterType="GenTable" resultMap="GenTableResult"> <select id="selectDbTableList" parameterType="GenTable" resultMap="GenTableResult">
select table_name, table_comment, create_time, update_time from information_schema.tables select table_name, table_comment, create_time, update_time from information_schema.tables
where table_schema = (select database()) where table_schema = (select database())
AND table_name NOT LIKE 'qrtz_%' AND table_name NOT LIKE 'gen_%' AND table_name NOT LIKE 'qrtz\_%' AND table_name NOT LIKE 'gen\_%'
AND table_name NOT IN (select table_name from gen_table) AND table_name NOT IN (select table_name from gen_table)
<if test="tableName != null and tableName != ''"> <if test="tableName != null and tableName != ''">
AND lower(table_name) like lower(concat('%', #{tableName}, '%')) AND lower(table_name) like lower(concat('%', #{tableName}, '%'))
@ -98,7 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectDbTableListByNames" resultMap="GenTableResult"> <select id="selectDbTableListByNames" resultMap="GenTableResult">
select table_name, table_comment, create_time, update_time from information_schema.tables select table_name, table_comment, create_time, update_time from information_schema.tables
where table_name NOT LIKE 'qrtz_%' and table_name NOT LIKE 'gen_%' and table_schema = (select database()) where table_name NOT LIKE 'qrtz\_%' and table_name NOT LIKE 'gen\_%' and table_schema = (select database())
and table_name in and table_name in
<foreach collection="array" item="name" open="(" separator="," close=")"> <foreach collection="array" item="name" open="(" separator="," close=")">
#{name} #{name}
@ -171,6 +171,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
) )
</insert> </insert>
<update id="createTable">
${sql}
</update>
<update id="updateGenTable" parameterType="GenTable"> <update id="updateGenTable" parameterType="GenTable">
update gen_table update gen_table
<set> <set>

View File

@ -12,12 +12,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
#if($table.sub) #if($table.sub)
<resultMap id="${ClassName}${subClassName}Result" type="${ClassName}" extends="${ClassName}Result"> <resultMap id="${ClassName}${subClassName}Result" type="${ClassName}" extends="${ClassName}Result">
<collection property="${subclassName}List" notNullColumn="sub_${subTable.pkColumn.columnName}" javaType="java.util.List" resultMap="${subClassName}Result" /> <collection property="${subclassName}List" ofType="${subClassName}" column="${pkColumn.columnName}" select="select${subClassName}List" />
</resultMap> </resultMap>
<resultMap type="${subClassName}" id="${subClassName}Result"> <resultMap type="${subClassName}" id="${subClassName}Result">
#foreach ($column in $subTable.columns) #foreach ($column in $subTable.columns)
<result property="${column.javaField}" column="sub_${column.columnName}" /> <result property="${column.javaField}" column="${column.columnName}" />
#end #end
</resultMap> </resultMap>
#end #end
@ -63,14 +63,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="select${ClassName}Vo"/> <include refid="select${ClassName}Vo"/>
where ${pkColumn.columnName} = #{${pkColumn.javaField}} where ${pkColumn.columnName} = #{${pkColumn.javaField}}
#elseif($table.sub) #elseif($table.sub)
select#foreach($column in $columns) a.$column.columnName#if($foreach.count != $columns.size()),#end#end, select#foreach($column in $columns) $column.columnName#if($foreach.count != $columns.size()),#end#end
#foreach($column in $subTable.columns) b.$column.columnName as sub_$column.columnName#if($foreach.count != $subTable.columns.size()),#end#end from ${tableName}
where ${pkColumn.columnName} = #{${pkColumn.javaField}}
from ${tableName} a
left join ${subTableName} b on b.${subTableFkName} = a.${pkColumn.columnName}
where a.${pkColumn.columnName} = #{${pkColumn.javaField}}
#end #end
</select> </select>
#if($table.sub)
<select id="select${subClassName}List" resultType="${subClassName}" resultMap="${subClassName}Result">
select#foreach ($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end
from ${subTableName}
where ${subTableFkName} = #{${subTableFkName}}
</select>
#end
<insert id="insert${ClassName}" parameterType="${ClassName}"#if($pkColumn.increment) useGeneratedKeys="true" keyProperty="$pkColumn.javaField"#end> <insert id="insert${ClassName}" parameterType="${ClassName}"#if($pkColumn.increment) useGeneratedKeys="true" keyProperty="$pkColumn.javaField"#end>
insert into ${tableName} insert into ${tableName}
@ -127,7 +132,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<insert id="batch${subClassName}"> <insert id="batch${subClassName}">
insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values insert into ${subTableName}(#foreach($column in $subTable.columns) $column.columnName#if($foreach.count != $subTable.columns.size()),#end#end) values
<foreach item="item" index="index" collection="list" separator=","> <foreach item="item" index="index" collection="list" separator=",">
(#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end) (#foreach($column in $subTable.columns) #{item.$column.javaField}#if($foreach.count != $subTable.columns.size()),#end#end)
</foreach> </foreach>
</insert> </insert>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.7</version> <version>3.8.8</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -42,6 +42,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
and date_format(create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d') and date_format(create_time,'%y%m%d') &lt;= date_format(#{params.endTime},'%y%m%d')
</if> </if>
</where> </where>
order by create_time desc
</select> </select>
<select id="selectJobLogAll" resultMap="SysJobLogResult"> <select id="selectJobLogAll" resultMap="SysJobLogResult">

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.8.7</version> <version>3.8.8</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -85,9 +85,9 @@ public interface ISysRoleService
/** /**
* 校验角色是否有数据权限 * 校验角色是否有数据权限
* *
* @param roleId 角色id * @param roleIds 角色id
*/ */
public void checkRoleDataScope(Long roleId); public void checkRoleDataScope(Long... roleIds);
/** /**
* 通过角色ID查询角色使用数量 * 通过角色ID查询角色使用数量

View File

@ -190,7 +190,7 @@ public class SysDeptServiceImpl implements ISysDeptService
@Override @Override
public void checkDeptDataScope(Long deptId) public void checkDeptDataScope(Long deptId)
{ {
if (!SysUser.isAdmin(SecurityUtils.getUserId())) if (!SysUser.isAdmin(SecurityUtils.getUserId()) && StringUtils.isNotNull(deptId))
{ {
SysDept dept = new SysDept(); SysDept dept = new SysDept();
dept.setDeptId(deptId); dept.setDeptId(deptId);

View File

@ -188,7 +188,7 @@ public class SysMenuServiceImpl implements ISysMenuService
RouterVo children = new RouterVo(); RouterVo children = new RouterVo();
children.setPath(menu.getPath()); children.setPath(menu.getPath());
children.setComponent(menu.getComponent()); children.setComponent(menu.getComponent());
children.setName(StringUtils.capitalize(menu.getPath())); children.setName(getRouteName(menu.getRouteName(), menu.getPath()));
children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath())); children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), StringUtils.equals("1", menu.getIsCache()), menu.getPath()));
children.setQuery(menu.getQuery()); children.setQuery(menu.getQuery());
childrenList.add(children); childrenList.add(children);
@ -203,7 +203,7 @@ public class SysMenuServiceImpl implements ISysMenuService
String routerPath = innerLinkReplaceEach(menu.getPath()); String routerPath = innerLinkReplaceEach(menu.getPath());
children.setPath(routerPath); children.setPath(routerPath);
children.setComponent(UserConstants.INNER_LINK); children.setComponent(UserConstants.INNER_LINK);
children.setName(StringUtils.capitalize(routerPath)); children.setName(getRouteName(menu.getRouteName(), routerPath));
children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath())); children.setMeta(new MetaVo(menu.getMenuName(), menu.getIcon(), menu.getPath()));
childrenList.add(children); childrenList.add(children);
router.setChildren(childrenList); router.setChildren(childrenList);
@ -354,13 +354,25 @@ public class SysMenuServiceImpl implements ISysMenuService
*/ */
public String getRouteName(SysMenu menu) public String getRouteName(SysMenu menu)
{ {
String routerName = StringUtils.capitalize(menu.getPath());
// 非外链并且是一级目录(类型为目录) // 非外链并且是一级目录(类型为目录)
if (isMenuFrame(menu)) if (isMenuFrame(menu))
{ {
routerName = StringUtils.EMPTY; return StringUtils.EMPTY;
} }
return routerName; return getRouteName(menu.getRouteName(), menu.getPath());
}
/**
* 获取路由名称,如没有配置路由名称则取路由地址
*
* @param routerName 路由名称
* @param path 路由地址
* @return 路由名称(驼峰格式)
*/
public String getRouteName(String name, String path)
{
String routerName = StringUtils.isNotEmpty(name) ? name : path;
return StringUtils.capitalize(routerName);
} }
/** /**

View File

@ -192,19 +192,22 @@ public class SysRoleServiceImpl implements ISysRoleService
/** /**
* 校验角色是否有数据权限 * 校验角色是否有数据权限
* *
* @param roleId 角色id * @param roleIds 角色id
*/ */
@Override @Override
public void checkRoleDataScope(Long roleId) public void checkRoleDataScope(Long... roleIds)
{ {
if (!SysUser.isAdmin(SecurityUtils.getUserId())) if (!SysUser.isAdmin(SecurityUtils.getUserId()))
{ {
SysRole role = new SysRole(); for (Long roleId : roleIds)
role.setRoleId(roleId);
List<SysRole> roles = SpringUtils.getAopProxy(this).selectRoleList(role);
if (StringUtils.isEmpty(roles))
{ {
throw new ServiceException("没有权限访问角色数据!"); SysRole role = new SysRole();
role.setRoleId(roleId);
List<SysRole> roles = SpringUtils.getAopProxy(this).selectRoleList(role);
if (StringUtils.isEmpty(roles))
{
throw new ServiceException("没有权限访问角色数据!");
}
} }
} }
} }

View File

@ -28,6 +28,7 @@ import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.mapper.SysUserPostMapper; import com.ruoyi.system.mapper.SysUserPostMapper;
import com.ruoyi.system.mapper.SysUserRoleMapper; import com.ruoyi.system.mapper.SysUserRoleMapper;
import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysConfigService;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
/** /**
@ -58,6 +59,9 @@ public class SysUserServiceImpl implements ISysUserService
@Autowired @Autowired
private ISysConfigService configService; private ISysConfigService configService;
@Autowired
private ISysDeptService deptService;
@Autowired @Autowired
protected Validator validator; protected Validator validator;
@ -489,7 +493,6 @@ public class SysUserServiceImpl implements ISysUserService
int failureNum = 0; int failureNum = 0;
StringBuilder successMsg = new StringBuilder(); StringBuilder successMsg = new StringBuilder();
StringBuilder failureMsg = new StringBuilder(); StringBuilder failureMsg = new StringBuilder();
String password = configService.selectConfigByKey("sys.user.initPassword");
for (SysUser user : userList) for (SysUser user : userList)
{ {
try try
@ -499,6 +502,8 @@ public class SysUserServiceImpl implements ISysUserService
if (StringUtils.isNull(u)) if (StringUtils.isNull(u))
{ {
BeanValidators.validateWithException(validator, user); BeanValidators.validateWithException(validator, user);
deptService.checkDeptDataScope(user.getDeptId());
String password = configService.selectConfigByKey("sys.user.initPassword");
user.setPassword(SecurityUtils.encryptPassword(password)); user.setPassword(SecurityUtils.encryptPassword(password));
user.setCreateBy(operName); user.setCreateBy(operName);
userMapper.insertUser(user); userMapper.insertUser(user);
@ -510,6 +515,7 @@ public class SysUserServiceImpl implements ISysUserService
BeanValidators.validateWithException(validator, user); BeanValidators.validateWithException(validator, user);
checkUserAllowed(u); checkUserAllowed(u);
checkUserDataScope(u.getUserId()); checkUserDataScope(u.getUserId());
deptService.checkDeptDataScope(user.getDeptId());
user.setUserId(u.getUserId()); user.setUserId(u.getUserId());
user.setUpdateBy(operName); user.setUpdateBy(operName);
userMapper.updateUser(user); userMapper.updateUser(user);

View File

@ -41,7 +41,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
order by dict_sort asc order by dict_sort asc
</select> </select>
<select id="selectDictDataByType" parameterType="SysDictData" resultMap="SysDictDataResult"> <select id="selectDictDataByType" parameterType="String" resultMap="SysDictDataResult">
<include refid="selectDictDataVo"/> <include refid="selectDictDataVo"/>
where status = '0' and dict_type = #{dictType} order by dict_sort asc where status = '0' and dict_type = #{dictType} order by dict_sort asc
</select> </select>

View File

@ -13,6 +13,7 @@
<result property="path" column="path" /> <result property="path" column="path" />
<result property="component" column="component" /> <result property="component" column="component" />
<result property="query" column="query" /> <result property="query" column="query" />
<result property="routeName" column="route_name" />
<result property="isFrame" column="is_frame" /> <result property="isFrame" column="is_frame" />
<result property="isCache" column="is_cache" /> <result property="isCache" column="is_cache" />
<result property="menuType" column="menu_type" /> <result property="menuType" column="menu_type" />
@ -28,7 +29,7 @@
</resultMap> </resultMap>
<sql id="selectMenuVo"> <sql id="selectMenuVo">
select menu_id, menu_name, parent_id, order_num, path, component, `query`, is_frame, is_cache, menu_type, visible, status, ifnull(perms,'') as perms, icon, create_time select menu_id, menu_name, parent_id, order_num, path, component, `query`, route_name, is_frame, is_cache, menu_type, visible, status, ifnull(perms,'') as perms, icon, create_time
from sys_menu from sys_menu
</sql> </sql>
@ -49,13 +50,13 @@
</select> </select>
<select id="selectMenuTreeAll" resultMap="SysMenuResult"> <select id="selectMenuTreeAll" resultMap="SysMenuResult">
select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.`query`, m.visible, m.status, ifnull(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.`query`, m.route_name, m.visible, m.status, ifnull(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time
from sys_menu m where m.menu_type in ('M', 'C') and m.status = 0 from sys_menu m where m.menu_type in ('M', 'C') and m.status = 0
order by m.parent_id, m.order_num order by m.parent_id, m.order_num
</select> </select>
<select id="selectMenuListByUserId" parameterType="SysMenu" resultMap="SysMenuResult"> <select id="selectMenuListByUserId" parameterType="SysMenu" resultMap="SysMenuResult">
select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.`query`, m.visible, m.status, ifnull(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.`query`, m.route_name, m.visible, m.status, ifnull(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time
from sys_menu m from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id left join sys_role_menu rm on m.menu_id = rm.menu_id
left join sys_user_role ur on rm.role_id = ur.role_id left join sys_user_role ur on rm.role_id = ur.role_id
@ -74,7 +75,7 @@
</select> </select>
<select id="selectMenuTreeByUserId" parameterType="Long" resultMap="SysMenuResult"> <select id="selectMenuTreeByUserId" parameterType="Long" resultMap="SysMenuResult">
select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.`query`, m.visible, m.status, ifnull(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time select distinct m.menu_id, m.parent_id, m.menu_name, m.path, m.component, m.`query`, m.route_name, m.visible, m.status, ifnull(m.perms,'') as perms, m.is_frame, m.is_cache, m.menu_type, m.icon, m.order_num, m.create_time
from sys_menu m from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id left join sys_role_menu rm on m.menu_id = rm.menu_id
left join sys_user_role ur on rm.role_id = ur.role_id left join sys_user_role ur on rm.role_id = ur.role_id
@ -141,6 +142,7 @@
<if test="path != null and path != ''">path = #{path},</if> <if test="path != null and path != ''">path = #{path},</if>
<if test="component != null">component = #{component},</if> <if test="component != null">component = #{component},</if>
<if test="query != null">`query` = #{query},</if> <if test="query != null">`query` = #{query},</if>
<if test="routeName != null">route_name = #{routeName},</if>
<if test="isFrame != null and isFrame != ''">is_frame = #{isFrame},</if> <if test="isFrame != null and isFrame != ''">is_frame = #{isFrame},</if>
<if test="isCache != null and isCache != ''">is_cache = #{isCache},</if> <if test="isCache != null and isCache != ''">is_cache = #{isCache},</if>
<if test="menuType != null and menuType != ''">menu_type = #{menuType},</if> <if test="menuType != null and menuType != ''">menu_type = #{menuType},</if>
@ -164,6 +166,7 @@
<if test="path != null and path != ''">path,</if> <if test="path != null and path != ''">path,</if>
<if test="component != null and component != ''">component,</if> <if test="component != null and component != ''">component,</if>
<if test="query != null and query != ''">`query`,</if> <if test="query != null and query != ''">`query`,</if>
<if test="routeName != null">route_name,</if>
<if test="isFrame != null and isFrame != ''">is_frame,</if> <if test="isFrame != null and isFrame != ''">is_frame,</if>
<if test="isCache != null and isCache != ''">is_cache,</if> <if test="isCache != null and isCache != ''">is_cache,</if>
<if test="menuType != null and menuType != ''">menu_type,</if> <if test="menuType != null and menuType != ''">menu_type,</if>
@ -182,6 +185,7 @@
<if test="path != null and path != ''">#{path},</if> <if test="path != null and path != ''">#{path},</if>
<if test="component != null and component != ''">#{component},</if> <if test="component != null and component != ''">#{component},</if>
<if test="query != null and query != ''">#{query},</if> <if test="query != null and query != ''">#{query},</if>
<if test="routeName != null">#{routeName},</if>
<if test="isFrame != null and isFrame != ''">#{isFrame},</if> <if test="isFrame != null and isFrame != ''">#{isFrame},</if>
<if test="isCache != null and isCache != ''">#{isCache},</if> <if test="isCache != null and isCache != ''">#{isCache},</if>
<if test="menuType != null and menuType != ''">#{menuType},</if> <if test="menuType != null and menuType != ''">#{menuType},</if>

View File

@ -1,6 +1,6 @@
{ {
"name": "ruoyi", "name": "ruoyi",
"version": "3.8.7", "version": "3.8.8",
"description": "若依管理系统", "description": "若依管理系统",
"author": "若依", "author": "若依",
"license": "MIT", "license": "MIT",
@ -39,7 +39,7 @@
"@riophae/vue-treeselect": "0.4.0", "@riophae/vue-treeselect": "0.4.0",
"axios": "0.24.0", "axios": "0.24.0",
"clipboard": "2.0.8", "clipboard": "2.0.8",
"core-js": "3.25.3", "core-js": "3.37.1",
"echarts": "5.4.0", "echarts": "5.4.0",
"element-ui": "2.15.14", "element-ui": "2.15.14",
"file-saver": "2.0.5", "file-saver": "2.0.5",
@ -67,7 +67,7 @@
"babel-eslint": "10.1.0", "babel-eslint": "10.1.0",
"babel-plugin-dynamic-import-node": "2.3.3", "babel-plugin-dynamic-import-node": "2.3.3",
"chalk": "4.1.0", "chalk": "4.1.0",
"compression-webpack-plugin": "5.0.2", "compression-webpack-plugin": "6.1.2",
"connect": "3.6.6", "connect": "3.6.6",
"eslint": "7.15.0", "eslint": "7.15.0",
"eslint-plugin-vue": "7.2.0", "eslint-plugin-vue": "7.2.0",

View File

@ -43,6 +43,15 @@ export function importTable(data) {
}) })
} }
// 创建表
export function createTable(data) {
return request({
url: '/tool/gen/createTable',
method: 'post',
params: data
})
}
// 预览生成代码 // 预览生成代码
export function previewTable(tableId) { export function previewTable(tableId) {
return request({ return request({

View File

@ -51,10 +51,16 @@ export default {
methods: { methods: {
// 单选按钮值变化时 // 单选按钮值变化时
radioChange() { radioChange() {
if (this.cron.min === '*') {
this.$emit('update', 'min', '0', 'hour');
}
if (this.cron.second === '*') {
this.$emit('update', 'second', '0', 'hour');
}
switch (this.radioValue) { switch (this.radioValue) {
case 1: case 1:
this.$emit('update', 'hour', '*') this.$emit('update', 'hour', '*')
break; break;
case 2: case 2:
this.$emit('update', 'hour', this.cycleTotal); this.$emit('update', 'hour', this.cycleTotal);
break; break;

View File

@ -122,7 +122,8 @@
<s> 满180251782 </s> <s> 满104180207 </s> <s> 满186866453 </s> <s> 满201396349 </s> <s> 满180251782 </s> <s> 满104180207 </s> <s> 满186866453 </s> <s> 满201396349 </s>
<s> 满101456076 </s> <s> 满101539465 </s> <s> 满264312783 </s> <s> 满167385320 </s> <s> 满101456076 </s> <s> 满101539465 </s> <s> 满264312783 </s> <s> 满167385320 </s>
<s> 满104748341 </s> <s> 满160110482 </s> <s> 满170801498 </s> <s> 满108482800 </s> <s> 满104748341 </s> <s> 满160110482 </s> <s> 满170801498 </s> <s> 满108482800 </s>
<s> 满101046199 </s> <s> 满136919097 </s> <s> 满143961921 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=1HmEGh7zKA_CKI2E-pGInPTlC5jS9mc_&authKey=XaiUf1wfbSTEecm4lDMtIMsc6g%2BoETxjBm1BbZPr6IfuMGRj7oG4GEeu7jtzNaw%2F&noverify=0&group_code=174951577" target="_blank">174951577</a> <s> 满101046199 </s> <s> 满136919097 </s> <s> 满143961921 </s> <s> 174951577 </s>
<s> 满161281055 </s> <s> 满138988063 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=SUc-msaypcqB2UTFif4eqGlBHkKcvMNP&authKey=JdQBouY2PG%2BS%2BCzAfIgbCGNgxyahpfh24IW%2F03rPxGilhqVbisLma%2FFFnt79DHNh&noverify=0&group_code=151450850" target="_blank">151450850</a>
</p> </p>
<p> <p>
<i class="el-icon-chat-dot-round"></i> 微信<a <i class="el-icon-chat-dot-round"></i> 微信<a
@ -146,6 +147,36 @@
<span>更新日志</span> <span>更新日志</span>
</div> </div>
<el-collapse accordion> <el-collapse accordion>
<el-collapse-item title="v3.8.8 - 2024-06-30">
<ol>
<li>菜单管理新增路由名称</li>
<li>新增数据脱敏过滤注解</li>
<li>用户密码新增非法字符验证</li>
<li>限制用户操作数据权限范围</li>
<li>代码生成新增创建表结构功能</li>
<li>定时任务白名单配置范围缩小</li>
<li>优化代码生成主子表关联查询方式</li>
<li>Excel注解新增属性comboReadDict</li>
<li>Excel注解ColumnType类型新增文本</li>
<li>新增国际化资源文件配置</li>
<li>升级oshi到最新版本6.6.1</li>
<li>升级druid到最新版本1.2.23</li>
<li>升级core-js到最新版本3.37.1</li>
<li>更新HttpUtils中的User-Agent</li>
<li>更新compressionPlugin到6.1.2以兼容node18+</li>
<li>升级spring-security到安全版本防止漏洞风险</li>
<li>升级spring-framework到安全版本防止漏洞风险</li>
<li>优化自定义XSS注解匹配方式</li>
<li>优化缓存监控键名列表排序显示</li>
<li>优化定时任务日志默认按时间排序</li>
<li>优化默认文件大小超过2G无效的问题</li>
<li>优化查表特殊字符使用反斜杠进行转义</li>
<li>优化定时任务cron表达式小时配置显示错误问题</li>
<li>优化多个自定数据权限使用in查询,避免多次拼接</li>
<li>优化导入Excel时设置dictType属性重复查缓存问题</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.8.7 - 2023-12-08"> <el-collapse-item title="v3.8.7 - 2023-12-08">
<ol> <ol>
<li>操作日志记录部门名称</li> <li>操作日志记录部门名称</li>
@ -989,7 +1020,7 @@ export default {
data() { data() {
return { return {
// 版本号 // 版本号
version: "3.8.7" version: "3.8.8"
}; };
}, },
methods: { methods: {

View File

@ -56,7 +56,7 @@
</el-form> </el-form>
<!-- 底部 --> <!-- 底部 -->
<div class="el-login-footer"> <div class="el-login-footer">
<span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span> <span>Copyright © 2018-2024 ruoyi.vip All Rights Reserved.</span>
</div> </div>
</div> </div>
</template> </template>

View File

@ -61,7 +61,7 @@
</el-form> </el-form>
<!-- 底部 --> <!-- 底部 -->
<div class="el-register-footer"> <div class="el-register-footer">
<span>Copyright © 2018-2023 ruoyi.vip All Rights Reserved.</span> <span>Copyright © 2018-2024 ruoyi.vip All Rights Reserved.</span>
</div> </div>
</div> </div>
</template> </template>
@ -95,7 +95,8 @@ export default {
], ],
password: [ password: [
{ required: true, trigger: "blur", message: "请输入您的密码" }, { required: true, trigger: "blur", message: "请输入您的密码" },
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' } { min: 5, max: 20, message: "用户密码长度必须介于 5 和 20 之间", trigger: "blur" },
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
], ],
confirmPassword: [ confirmPassword: [
{ required: true, trigger: "blur", message: "请再次输入您的密码" }, { required: true, trigger: "blur", message: "请再次输入您的密码" },

View File

@ -127,10 +127,8 @@ export default {
} }
authUserSelectAll({ roleId: roleId, userIds: userIds }).then(res => { authUserSelectAll({ roleId: roleId, userIds: userIds }).then(res => {
this.$modal.msgSuccess(res.msg); this.$modal.msgSuccess(res.msg);
if (res.code === 200) { this.visible = false;
this.visible = false; this.$emit("ok");
this.$emit("ok");
}
}); });
} }
} }

View File

@ -433,7 +433,8 @@ export default {
], ],
password: [ password: [
{ required: true, message: "用户密码不能为空", trigger: "blur" }, { required: true, message: "用户密码不能为空", trigger: "blur" },
{ min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' } { min: 5, max: 20, message: '用户密码长度必须介于 5 和 20 之间', trigger: 'blur' },
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
], ],
email: [ email: [
{ {
@ -591,7 +592,12 @@ export default {
cancelButtonText: "取消", cancelButtonText: "取消",
closeOnClickModal: false, closeOnClickModal: false,
inputPattern: /^.{5,20}$/, inputPattern: /^.{5,20}$/,
inputErrorMessage: "用户密码长度必须介于 5 和 20 之间" inputErrorMessage: "用户密码长度必须介于 5 和 20 之间",
inputValidator: (value) => {
if (/<|>|"|'|\||\\/.test(value)) {
return "不能包含非法字符:< > \" ' \\\ |"
}
},
}).then(({ value }) => { }).then(({ value }) => {
resetUserPwd(row.userId, value).then(response => { resetUserPwd(row.userId, value).then(response => {
this.$modal.msgSuccess("修改成功,新密码是:" + value); this.$modal.msgSuccess("修改成功,新密码是:" + value);

View File

@ -41,7 +41,8 @@ export default {
], ],
newPassword: [ newPassword: [
{ required: true, message: "新密码不能为空", trigger: "blur" }, { required: true, message: "新密码不能为空", trigger: "blur" },
{ min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" } { min: 6, max: 20, message: "长度在 6 到 20 个字符", trigger: "blur" },
{ pattern: /^[^<>"'|\\]+$/, message: "不能包含非法字符:< > \" ' \\\ |", trigger: "blur" }
], ],
confirmPassword: [ confirmPassword: [
{ required: true, message: "确认密码不能为空", trigger: "blur" }, { required: true, message: "确认密码不能为空", trigger: "blur" },

View File

@ -0,0 +1,45 @@
<template>
<!-- 创建表 -->
<el-dialog title="创建表" :visible.sync="visible" width="800px" top="5vh" append-to-body>
<span>创建表语句(支持多个建表语句)</span>
<el-input type="textarea" :rows="10" placeholder="请输入文本" v-model="content"></el-input>
<div slot="footer" class="dialog-footer">
<el-button type="primary" @click="handleCreateTable"> </el-button>
<el-button @click="visible = false"> </el-button>
</div>
</el-dialog>
</template>
<script>
import { createTable } from "@/api/tool/gen";
export default {
data() {
return {
// 遮罩层
visible: false,
// 文本内容
content: ""
};
},
methods: {
// 显示弹框
show() {
this.visible = true;
},
/** 创建按钮操作 */
handleCreateTable() {
if (this.content === "") {
this.$modal.msgError("请输入建表语句");
return;
}
createTable({ sql: this.content }).then(res => {
this.$modal.msgSuccess(res.msg);
if (res.code === 200) {
this.visible = false;
this.$emit("ok");
}
});
}
}
};
</script>

View File

@ -41,10 +41,21 @@
plain plain
icon="el-icon-download" icon="el-icon-download"
size="mini" size="mini"
:disabled="multiple"
@click="handleGenTable" @click="handleGenTable"
v-hasPermi="['tool:gen:code']" v-hasPermi="['tool:gen:code']"
>生成</el-button> >生成</el-button>
</el-col> </el-col>
<el-col :span="1.5">
<el-button
type="primary"
plain
icon="el-icon-plus"
size="mini"
@click="openCreateTable"
v-hasRole="['admin']"
>创建</el-button>
</el-col>
<el-col :span="1.5"> <el-col :span="1.5">
<el-button <el-button
type="info" type="info"
@ -172,12 +183,14 @@
</el-tabs> </el-tabs>
</el-dialog> </el-dialog>
<import-table ref="import" @ok="handleQuery" /> <import-table ref="import" @ok="handleQuery" />
<create-table ref="create" @ok="handleQuery" />
</div> </div>
</template> </template>
<script> <script>
import { listTable, previewTable, delTable, genCode, synchDb } from "@/api/tool/gen"; import { listTable, previewTable, delTable, genCode, synchDb } from "@/api/tool/gen";
import importTable from "./importTable"; import importTable from "./importTable";
import createTable from "./createTable";
import hljs from "highlight.js/lib/highlight"; import hljs from "highlight.js/lib/highlight";
import "highlight.js/styles/github-gist.css"; import "highlight.js/styles/github-gist.css";
hljs.registerLanguage("java", require("highlight.js/lib/languages/java")); hljs.registerLanguage("java", require("highlight.js/lib/languages/java"));
@ -189,7 +202,7 @@ hljs.registerLanguage("sql", require("highlight.js/lib/languages/sql"));
export default { export default {
name: "Gen", name: "Gen",
components: { importTable }, components: { importTable, createTable },
data() { data() {
return { return {
// 遮罩层 // 遮罩层
@ -283,6 +296,10 @@ export default {
openImportTable() { openImportTable() {
this.$refs.import.show(); this.$refs.import.show();
}, },
/** 打开创建表弹窗 */
openCreateTable() {
this.$refs.create.show();
},
/** 重置按钮操作 */ /** 重置按钮操作 */
resetQuery() { resetQuery() {
this.dateRange = []; this.dateRange = [];

View File

@ -61,11 +61,12 @@ module.exports = {
plugins: [ plugins: [
// http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件 // http://doc.ruoyi.vip/ruoyi-vue/other/faq.html#使用gzip解压缩静态文件
new CompressionPlugin({ new CompressionPlugin({
cache: false, // 不启用文件缓存 cache: false, // 不启用文件缓存
test: /\.(js|css|html)?$/i, // 压缩文件格式 test: /\.(js|css|html|jpe?g|png|gif|svg)?$/i, // 压缩文件格式
filename: '[path].gz[query]', // 压缩后的文件名 filename: '[path][base].gz[query]', // 压缩后的文件名
algorithm: 'gzip', // 使用gzip压缩 algorithm: 'gzip', // 使用gzip压缩
minRatio: 0.8 // 压缩率小于1才会压缩 minRatio: 0.8, // 压缩比例,小于 80% 的文件不会被压缩
deleteOriginalAssets: false // 压缩后删除原文件
}) })
], ],
}, },
@ -123,12 +124,7 @@ module.exports = {
} }
} }
}) })
config.optimization.runtimeChunk('single')
config.optimization.runtimeChunk('single'),
{
from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
to: './' //到根目录下
}
}) })
} }
} }

View File

@ -138,6 +138,7 @@ create table sys_menu (
path varchar(200) default '' comment '路由地址', path varchar(200) default '' comment '路由地址',
component varchar(255) default null comment '组件路径', component varchar(255) default null comment '组件路径',
query varchar(255) default null comment '路由参数', query varchar(255) default null comment '路由参数',
route_name varchar(50) default '' comment '路由名称',
is_frame int(1) default 1 comment '是否为外链0是 1否', is_frame int(1) default 1 comment '是否为外链0是 1否',
is_cache int(1) default 0 comment '是否缓存0缓存 1不缓存', is_cache int(1) default 0 comment '是否缓存0缓存 1不缓存',
menu_type char(1) default '' comment '菜单类型M目录 C菜单 F按钮', menu_type char(1) default '' comment '菜单类型M目录 C菜单 F按钮',
@ -157,106 +158,106 @@ create table sys_menu (
-- 初始化-菜单信息表数据 -- 初始化-菜单信息表数据
-- ---------------------------- -- ----------------------------
-- 一级菜单 -- 一级菜单
insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录'); insert into sys_menu values('1', '系统管理', '0', '1', 'system', null, '', '', 1, 0, 'M', '0', '0', '', 'system', 'admin', sysdate(), '', null, '系统管理目录');
insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录'); insert into sys_menu values('2', '系统监控', '0', '2', 'monitor', null, '', '', 1, 0, 'M', '0', '0', '', 'monitor', 'admin', sysdate(), '', null, '系统监控目录');
insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录'); insert into sys_menu values('3', '系统工具', '0', '3', 'tool', null, '', '', 1, 0, 'M', '0', '0', '', 'tool', 'admin', sysdate(), '', null, '系统工具目录');
insert into sys_menu values('4', '若依官网', '0', '4', 'http://ruoyi.vip', null, '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, '若依官网地址'); insert into sys_menu values('4', '若依官网', '0', '4', 'http://ruoyi.vip', null, '', '', 0, 0, 'M', '0', '0', '', 'guide', 'admin', sysdate(), '', null, '若依官网地址');
-- 二级菜单 -- 二级菜单
insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单'); insert into sys_menu values('100', '用户管理', '1', '1', 'user', 'system/user/index', '', '', 1, 0, 'C', '0', '0', 'system:user:list', 'user', 'admin', sysdate(), '', null, '用户管理菜单');
insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单'); insert into sys_menu values('101', '角色管理', '1', '2', 'role', 'system/role/index', '', '', 1, 0, 'C', '0', '0', 'system:role:list', 'peoples', 'admin', sysdate(), '', null, '角色管理菜单');
insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', sysdate(), '', null, '菜单管理菜单'); insert into sys_menu values('102', '菜单管理', '1', '3', 'menu', 'system/menu/index', '', '', 1, 0, 'C', '0', '0', 'system:menu:list', 'tree-table', 'admin', sysdate(), '', null, '菜单管理菜单');
insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', sysdate(), '', null, '部门管理菜单'); insert into sys_menu values('103', '部门管理', '1', '4', 'dept', 'system/dept/index', '', '', 1, 0, 'C', '0', '0', 'system:dept:list', 'tree', 'admin', sysdate(), '', null, '部门管理菜单');
insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', sysdate(), '', null, '岗位管理菜单'); insert into sys_menu values('104', '岗位管理', '1', '5', 'post', 'system/post/index', '', '', 1, 0, 'C', '0', '0', 'system:post:list', 'post', 'admin', sysdate(), '', null, '岗位管理菜单');
insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单'); insert into sys_menu values('105', '字典管理', '1', '6', 'dict', 'system/dict/index', '', '', 1, 0, 'C', '0', '0', 'system:dict:list', 'dict', 'admin', sysdate(), '', null, '字典管理菜单');
insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单'); insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', '', '', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', sysdate(), '', null, '参数设置菜单');
insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单'); insert into sys_menu values('107', '通知公告', '1', '8', 'notice', 'system/notice/index', '', '', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', sysdate(), '', null, '通知公告菜单');
insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单'); insert into sys_menu values('108', '日志管理', '1', '9', 'log', '', '', '', 1, 0, 'M', '0', '0', '', 'log', 'admin', sysdate(), '', null, '日志管理菜单');
insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单'); insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', '', '', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', sysdate(), '', null, '在线用户菜单');
insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单'); insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', '', '', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', sysdate(), '', null, '定时任务菜单');
insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单'); insert into sys_menu values('111', '数据监控', '2', '3', 'druid', 'monitor/druid/index', '', '', 1, 0, 'C', '0', '0', 'monitor:druid:list', 'druid', 'admin', sysdate(), '', null, '数据监控菜单');
insert into sys_menu values('112', '服务监控', '2', '4', 'server', 'monitor/server/index', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', sysdate(), '', null, '服务监控菜单'); insert into sys_menu values('112', '服务监控', '2', '4', 'server', 'monitor/server/index', '', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', sysdate(), '', null, '服务监控菜单');
insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', sysdate(), '', null, '缓存监控菜单'); insert into sys_menu values('113', '缓存监控', '2', '5', 'cache', 'monitor/cache/index', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis', 'admin', sysdate(), '', null, '缓存监控菜单');
insert into sys_menu values('114', '缓存列表', '2', '6', 'cacheList', 'monitor/cache/list', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', sysdate(), '', null, '缓存列表菜单'); insert into sys_menu values('114', '缓存列表', '2', '6', 'cacheList', 'monitor/cache/list', '', '', 1, 0, 'C', '0', '0', 'monitor:cache:list', 'redis-list', 'admin', sysdate(), '', null, '缓存列表菜单');
insert into sys_menu values('115', '表单构建', '3', '1', 'build', 'tool/build/index', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单'); insert into sys_menu values('115', '表单构建', '3', '1', 'build', 'tool/build/index', '', '', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', sysdate(), '', null, '表单构建菜单');
insert into sys_menu values('116', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单'); insert into sys_menu values('116', '代码生成', '3', '2', 'gen', 'tool/gen/index', '', '', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', sysdate(), '', null, '代码生成菜单');
insert into sys_menu values('117', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单'); insert into sys_menu values('117', '系统接口', '3', '3', 'swagger', 'tool/swagger/index', '', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', sysdate(), '', null, '系统接口菜单');
-- 三级菜单 -- 三级菜单
insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单'); insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'monitor/operlog/index', '', '', 1, 0, 'C', '0', '0', 'monitor:operlog:list', 'form', 'admin', sysdate(), '', null, '操作日志菜单');
insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单'); insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'monitor/logininfor/index', '', '', 1, 0, 'C', '0', '0', 'monitor:logininfor:list', 'logininfor', 'admin', sysdate(), '', null, '登录日志菜单');
-- 用户管理按钮 -- 用户管理按钮
insert into sys_menu values('1000', '用户查询', '100', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1000', '用户查询', '100', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1001', '用户新增', '100', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1001', '用户新增', '100', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1002', '用户修改', '100', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1002', '用户修改', '100', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1003', '用户删除', '100', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1003', '用户删除', '100', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1004', '用户导出', '100', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1004', '用户导出', '100', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1005', '用户导入', '100', '6', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1005', '用户导入', '100', '6', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:import', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1006', '重置密码', '100', '7', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1006', '重置密码', '100', '7', '', '', '', '', 1, 0, 'F', '0', '0', 'system:user:resetPwd', '#', 'admin', sysdate(), '', null, '');
-- 角色管理按钮 -- 角色管理按钮
insert into sys_menu values('1007', '角色查询', '101', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1007', '角色查询', '101', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1008', '角色新增', '101', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1008', '角色新增', '101', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1009', '角色修改', '101', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1009', '角色修改', '101', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1010', '角色删除', '101', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1010', '角色删除', '101', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1011', '角色导出', '101', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1011', '角色导出', '101', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:role:export', '#', 'admin', sysdate(), '', null, '');
-- 菜单管理按钮 -- 菜单管理按钮
insert into sys_menu values('1012', '菜单查询', '102', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1012', '菜单查询', '102', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1013', '菜单新增', '102', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1013', '菜单新增', '102', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1014', '菜单修改', '102', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1014', '菜单修改', '102', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1015', '菜单删除', '102', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1015', '菜单删除', '102', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:menu:remove', '#', 'admin', sysdate(), '', null, '');
-- 部门管理按钮 -- 部门管理按钮
insert into sys_menu values('1016', '部门查询', '103', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1016', '部门查询', '103', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1017', '部门新增', '103', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1017', '部门新增', '103', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1018', '部门修改', '103', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1018', '部门修改', '103', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1019', '部门删除', '103', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1019', '部门删除', '103', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:dept:remove', '#', 'admin', sysdate(), '', null, '');
-- 岗位管理按钮 -- 岗位管理按钮
insert into sys_menu values('1020', '岗位查询', '104', '1', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1020', '岗位查询', '104', '1', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1021', '岗位新增', '104', '2', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1021', '岗位新增', '104', '2', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1022', '岗位修改', '104', '3', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1022', '岗位修改', '104', '3', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1023', '岗位删除', '104', '4', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1023', '岗位删除', '104', '4', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1024', '岗位导出', '104', '5', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1024', '岗位导出', '104', '5', '', '', '', '', 1, 0, 'F', '0', '0', 'system:post:export', '#', 'admin', sysdate(), '', null, '');
-- 字典管理按钮 -- 字典管理按钮
insert into sys_menu values('1025', '字典查询', '105', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1025', '字典查询', '105', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1026', '字典新增', '105', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1026', '字典新增', '105', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1027', '字典修改', '105', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1027', '字典修改', '105', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1028', '字典删除', '105', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1028', '字典删除', '105', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1029', '字典导出', '105', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1029', '字典导出', '105', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:dict:export', '#', 'admin', sysdate(), '', null, '');
-- 参数设置按钮 -- 参数设置按钮
insert into sys_menu values('1030', '参数查询', '106', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1030', '参数查询', '106', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1031', '参数新增', '106', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1031', '参数新增', '106', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1032', '参数修改', '106', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1032', '参数修改', '106', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1033', '参数删除', '106', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1033', '参数删除', '106', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1034', '参数导出', '106', '5', '#', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1034', '参数导出', '106', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:config:export', '#', 'admin', sysdate(), '', null, '');
-- 通知公告按钮 -- 通知公告按钮
insert into sys_menu values('1035', '公告查询', '107', '1', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1035', '公告查询', '107', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1036', '公告新增', '107', '2', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1036', '公告新增', '107', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1037', '公告修改', '107', '3', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1037', '公告修改', '107', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1038', '公告删除', '107', '4', '#', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1038', '公告删除', '107', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'system:notice:remove', '#', 'admin', sysdate(), '', null, '');
-- 操作日志按钮 -- 操作日志按钮
insert into sys_menu values('1039', '操作查询', '500', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1039', '操作查询', '500', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1040', '操作删除', '500', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1040', '操作删除', '500', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1041', '日志导出', '500', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1041', '日志导出', '500', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:operlog:export', '#', 'admin', sysdate(), '', null, '');
-- 登录日志按钮 -- 登录日志按钮
insert into sys_menu values('1042', '登录查询', '501', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1042', '登录查询', '501', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1043', '登录删除', '501', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1043', '登录删除', '501', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1044', '日志导出', '501', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1044', '日志导出', '501', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1045', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1045', '账户解锁', '501', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate(), '', null, '');
-- 在线用户按钮 -- 在线用户按钮
insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1046', '在线查询', '109', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1047', '批量强退', '109', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1048', '单条强退', '109', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', sysdate(), '', null, '');
-- 定时任务按钮 -- 定时任务按钮
insert into sys_menu values('1049', '任务查询', '110', '1', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1049', '任务查询', '110', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1050', '任务新增', '110', '2', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1050', '任务新增', '110', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1051', '任务修改', '110', '3', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1051', '任务修改', '110', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1052', '任务删除', '110', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1052', '任务删除', '110', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1053', '状态修改', '110', '5', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1053', '状态修改', '110', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1054', '任务导出', '110', '6', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1054', '任务导出', '110', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', sysdate(), '', null, '');
-- 代码生成按钮 -- 代码生成按钮
insert into sys_menu values('1055', '生成查询', '116', '1', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1055', '生成查询', '116', '1', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1056', '生成修改', '116', '2', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1056', '生成修改', '116', '2', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1057', '生成删除', '116', '3', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1057', '生成删除', '116', '3', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1058', '导入代码', '116', '4', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1058', '导入代码', '116', '4', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1059', '预览代码', '116', '5', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1059', '预览代码', '116', '5', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu values('1060', '生成代码', '116', '6', '#', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1060', '生成代码', '116', '6', '#', '', '', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', sysdate(), '', null, '');
-- ---------------------------- -- ----------------------------
@ -419,7 +420,7 @@ create table sys_oper_log (
oper_id bigint(20) not null auto_increment comment '日志主键', oper_id bigint(20) not null auto_increment comment '日志主键',
title varchar(50) default '' comment '模块标题', title varchar(50) default '' comment '模块标题',
business_type int(2) default 0 comment '业务类型0其它 1新增 2修改 3删除', business_type int(2) default 0 comment '业务类型0其它 1新增 2修改 3删除',
method varchar(100) default '' comment '方法名称', method varchar(200) default '' comment '方法名称',
request_method varchar(10) default '' comment '请求方式', request_method varchar(10) default '' comment '请求方式',
operator_type int(1) default 0 comment '操作类别0其它 1后台用户 2手机端用户', operator_type int(1) default 0 comment '操作类别0其它 1后台用户 2手机端用户',
oper_name varchar(50) default '' comment '操作人员', oper_name varchar(50) default '' comment '操作人员',