Merge remote-tracking branch 'origin/dev' into 4.X

This commit is contained in:
疯狂的狮子li 2022-09-13 16:33:41 +08:00
commit d2774d3706
84 changed files with 687 additions and 616 deletions

View File

@ -10,7 +10,7 @@ end_of_line = lf
trim_trailing_whitespace = true trim_trailing_whitespace = true
insert_final_newline = true insert_final_newline = true
[*.{json,yml}] [*.{json,yml,yaml}]
indent_size = 2 indent_size = 2
[*.md] [*.md]

12
.run/ruoyi-admin.run.xml Normal file
View File

@ -0,0 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ruoyi-server" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile">
<settings>
<option name="imageTag" value="ruoyi/ruoyi-server:4.3.0" />
<option name="buildOnly" value="true" />
<option name="sourceFilePath" value="ruoyi-admin/Dockerfile" />
</settings>
</deployment>
<method v="2" />
</configuration>
</component>

View File

@ -0,0 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ruoyi-monitor-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile">
<settings>
<option name="imageTag" value="ruoyi/ruoyi-monitor-admin:4.3.0" />
<option name="buildOnly" value="true" />
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-monitor-admin/Dockerfile" />
</settings>
</deployment>
<method v="2" />
</configuration>
</component>

View File

@ -0,0 +1,12 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="ruoyi-xxl-job-admin" type="docker-deploy" factoryName="dockerfile" server-name="Docker">
<deployment type="dockerfile">
<settings>
<option name="imageTag" value="ruoyi/ruoyi-xxl-job-admin:4.3.0" />
<option name="buildOnly" value="true" />
<option name="sourceFilePath" value="ruoyi-extend/ruoyi-xxl-job-admin/Dockerfile" />
</settings>
</deployment>
<method v="2" />
</configuration>
</component>

View File

@ -4,7 +4,7 @@
[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE) [![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE)
[![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus) [![使用IntelliJ IDEA开发维护](https://img.shields.io/badge/IntelliJ%20IDEA-提供支持-blue.svg)](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
<br> <br>
[![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-4.3.0_beta2-success.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus) [![RuoYi-Vue-Plus](https://img.shields.io/badge/RuoYi_Vue_Plus-4.3.0-success.svg)](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
[![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.7-blue.svg)]() [![Spring Boot](https://img.shields.io/badge/Spring%20Boot-2.7-blue.svg)]()
[![JDK-8+](https://img.shields.io/badge/JDK-8-green.svg)]() [![JDK-8+](https://img.shields.io/badge/JDK-8-green.svg)]()
[![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]() [![JDK-11](https://img.shields.io/badge/JDK-11-green.svg)]()

40
pom.xml
View File

@ -6,34 +6,34 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
<name>RuoYi-Vue-Plus</name> <name>RuoYi-Vue-Plus</name>
<url>https://gitee.com/JavaLionLi/RuoYi-Vue-Plus</url> <url>https://gitee.com/JavaLionLi/RuoYi-Vue-Plus</url>
<description>RuoYi-Vue-Plus后台管理系统</description> <description>RuoYi-Vue-Plus后台管理系统</description>
<properties> <properties>
<ruoyi-vue-plus.version>4.3.0-beta2</ruoyi-vue-plus.version> <ruoyi-vue-plus.version>4.3.0</ruoyi-vue-plus.version>
<spring-boot.version>2.7.2</spring-boot.version> <spring-boot.version>2.7.3</spring-boot.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.2.2</maven-jar-plugin.version> <maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
<spring-boot.mybatis>2.2.2</spring-boot.mybatis> <spring-boot.mybatis>2.2.2</spring-boot.mybatis>
<druid.version>1.2.11</druid.version> <druid.version>1.2.12</druid.version>
<springdoc.version>1.6.9</springdoc.version> <springdoc.version>1.6.11</springdoc.version>
<poi.version>5.2.2</poi.version> <poi.version>5.2.2</poi.version>
<easyexcel.version>3.1.1</easyexcel.version> <easyexcel.version>3.1.1</easyexcel.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
<satoken.version>1.30.0</satoken.version> <satoken.version>1.30.0</satoken.version>
<mybatis-plus.version>3.5.2</mybatis-plus.version> <mybatis-plus.version>3.5.2</mybatis-plus.version>
<p6spy.version>3.9.1</p6spy.version> <p6spy.version>3.9.1</p6spy.version>
<hutool.version>5.8.5</hutool.version> <hutool.version>5.8.6</hutool.version>
<okhttp.version>4.10.0</okhttp.version> <okhttp.version>4.10.0</okhttp.version>
<spring-boot-admin.version>2.7.3</spring-boot-admin.version> <spring-boot-admin.version>2.7.4</spring-boot-admin.version>
<redisson.version>3.17.5</redisson.version> <redisson.version>3.17.6</redisson.version>
<lock4j.version>2.2.2</lock4j.version> <lock4j.version>2.2.2</lock4j.version>
<dynamic-ds.version>3.5.1</dynamic-ds.version> <dynamic-ds.version>3.5.2</dynamic-ds.version>
<tlog.version>1.4.3</tlog.version> <tlog.version>1.4.3</tlog.version>
<xxl-job.version>2.3.1</xxl-job.version> <xxl-job.version>2.3.1</xxl-job.version>
<lombok.version>1.18.24</lombok.version> <lombok.version>1.18.24</lombok.version>
@ -42,17 +42,10 @@
<guava.version>31.1-jre</guava.version> <guava.version>31.1-jre</guava.version>
<!-- OSS 配置 --> <!-- OSS 配置 -->
<aws-java-sdk-s3.version>1.12.264</aws-java-sdk-s3.version> <aws-java-sdk-s3.version>1.12.300</aws-java-sdk-s3.version>
<!-- SMS 配置 --> <!-- SMS 配置 -->
<aliyun.sms.version>2.0.16</aliyun.sms.version> <aliyun.sms.version>2.0.18</aliyun.sms.version>
<tencent.sms.version>3.1.555</tencent.sms.version> <tencent.sms.version>3.1.591</tencent.sms.version>
<!-- docker 配置 -->
<docker.registry.url>localhost</docker.registry.url>
<docker.registry.host>http://${docker.registry.url}:2375</docker.registry.host>
<docker.namespace>ruoyi</docker.namespace>
<docker.plugin.version>1.2.2</docker.plugin.version>
</properties> </properties>
<!-- 依赖声明 --> <!-- 依赖声明 -->
@ -142,6 +135,12 @@
<groupId>cn.dev33</groupId> <groupId>cn.dev33</groupId>
<artifactId>sa-token-jwt</artifactId> <artifactId>sa-token-jwt</artifactId>
<version>${satoken.version}</version> <version>${satoken.version}</version>
<exclusions>
<exclusion>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</exclusion>
</exclusions>
</dependency> </dependency>
<!-- dynamic-datasource 多数据源--> <!-- dynamic-datasource 多数据源-->
@ -342,7 +341,7 @@
<path> <path>
<groupId>com.github.therapi</groupId> <groupId>com.github.therapi</groupId>
<artifactId>therapi-runtime-javadoc-scribe</artifactId> <artifactId>therapi-runtime-javadoc-scribe</artifactId>
<version>0.13.0</version> <version>0.15.0</version>
</path> </path>
<path> <path>
<groupId>org.projectlombok</groupId> <groupId>org.projectlombok</groupId>
@ -434,3 +433,4 @@
</profiles> </profiles>
</project> </project>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -107,25 +107,6 @@
<warName>${project.artifactId}</warName> <warName>${project.artifactId}</warName>
</configuration> </configuration>
</plugin> </plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker.plugin.version}</version>
<configuration>
<imageName>${docker.namespace}/ruoyi-server:${project.version}</imageName>
<dockerDirectory>${project.basedir}</dockerDirectory>
<dockerHost>${docker.registry.host}</dockerHost>
<registryUrl>${docker.registry.url}</registryUrl>
<serverId>${docker.registry.url}</serverId>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@ -34,7 +34,7 @@ public class CacheController {
static { static {
CACHES.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息")); CACHES.add(new SysCache(CacheConstants.LOGIN_TOKEN_KEY, "用户信息"));
CACHES.add(new SysCache(CacheNames.ONLINE_TOKEN, "在线用户")); CACHES.add(new SysCache(CacheConstants.ONLINE_TOKEN_KEY, "在线用户"));
CACHES.add(new SysCache(CacheNames.SYS_CONFIG, "配置信息")); CACHES.add(new SysCache(CacheNames.SYS_CONFIG, "配置信息"));
CACHES.add(new SysCache(CacheNames.SYS_DICT, "数据字典")); CACHES.add(new SysCache(CacheNames.SYS_DICT, "数据字典"));
CACHES.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码")); CACHES.add(new SysCache(CacheConstants.CAPTCHA_CODE_KEY, "验证码"));

View File

@ -6,7 +6,6 @@ import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.CacheConstants; import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.constant.CacheNames;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.dto.UserOnlineDTO; import com.ruoyi.common.core.domain.dto.UserOnlineDTO;
@ -14,7 +13,7 @@ import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.enums.BusinessType; import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.StreamUtils; import com.ruoyi.common.utils.StreamUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.redis.CacheUtils; import com.ruoyi.common.utils.redis.RedisUtils;
import com.ruoyi.system.domain.SysUserOnline; import com.ruoyi.system.domain.SysUserOnline;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -51,8 +50,7 @@ public class SysUserOnlineController extends BaseController {
if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < 0) { if (StpUtil.stpLogic.getTokenActivityTimeoutByToken(token) < 0) {
continue; continue;
} }
UserOnlineDTO dto = CacheUtils.get(CacheNames.ONLINE_TOKEN, token); userOnlineDTOList.add(RedisUtils.getCacheObject(CacheConstants.ONLINE_TOKEN_KEY + token));
userOnlineDTOList.add(dto);
} }
if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) { if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName)) {
userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline -> userOnlineDTOList = StreamUtils.filter(userOnlineDTOList, userOnline ->

View File

@ -1,7 +1,6 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.constant.UserConstants;
@ -15,9 +14,7 @@ import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 部门信息 * 部门信息
@ -68,29 +65,6 @@ public class SysDeptController extends BaseController {
return R.ok(deptService.selectDeptById(deptId)); return R.ok(deptService.selectDeptById(deptId));
} }
/**
* 获取部门下拉树列表
*/
@GetMapping("/treeselect")
public R<List<Tree<Long>>> treeselect(SysDept dept) {
List<SysDept> depts = deptService.selectDeptList(dept);
return R.ok(deptService.buildDeptTreeSelect(depts));
}
/**
* 加载对应角色部门列表树
*
* @param roleId 角色ID
*/
@GetMapping(value = "/roleDeptTreeselect/{roleId}")
public R<Map<String, Object>> roleDeptTreeselect(@PathVariable("roleId") Long roleId) {
List<SysDept> depts = deptService.selectDeptList(new SysDept());
Map<String, Object> ajax = new HashMap<>();
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
ajax.put("depts", deptService.buildDeptTreeSelect(depts));
return R.ok(ajax);
}
/** /**
* 新增部门 * 新增部门
*/ */

View File

@ -68,6 +68,8 @@ public class SysProfileController extends BaseController {
user.setUserId(getUserId()); user.setUserId(getUserId());
user.setUserName(null); user.setUserName(null);
user.setPassword(null); user.setPassword(null);
user.setAvatar(null);
user.setDeptId(null);
if (userService.updateUserProfile(user) > 0) { if (userService.updateUserProfile(user) > 0) {
return R.ok(); return R.ok();
} }

View File

@ -7,6 +7,7 @@ import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.PageQuery; import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R; import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysRole; import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
@ -15,6 +16,7 @@ import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.poi.ExcelUtil; import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.SysUserRole; import com.ruoyi.system.domain.SysUserRole;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
import com.ruoyi.system.service.SysPermissionService; import com.ruoyi.system.service.SysPermissionService;
@ -23,7 +25,9 @@ import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* 角色信息 * 角色信息
@ -38,6 +42,7 @@ public class SysRoleController extends BaseController {
private final ISysRoleService roleService; private final ISysRoleService roleService;
private final ISysUserService userService; private final ISysUserService userService;
private final ISysDeptService deptService;
private final SysPermissionService permissionService; private final SysPermissionService permissionService;
/** /**
@ -215,4 +220,18 @@ public class SysRoleController extends BaseController {
roleService.checkRoleDataScope(roleId); roleService.checkRoleDataScope(roleId);
return toAjax(roleService.insertAuthUsers(roleId, userIds)); return toAjax(roleService.insertAuthUsers(roleId, userIds));
} }
/**
* 获取对应角色部门树列表
*
* @param roleId 角色ID
*/
@SaCheckPermission("system:role:list")
@GetMapping(value = "/deptTree/{roleId}")
public R<Map<String, Object>> roleDeptTreeselect(@PathVariable("roleId") Long roleId) {
Map<String, Object> ajax = new HashMap<>();
ajax.put("checkedKeys", deptService.selectDeptListByRoleId(roleId));
ajax.put("depts", deptService.selectDeptTreeList(new SysDept()));
return R.ok(ajax);
}
} }

View File

@ -3,6 +3,7 @@ package com.ruoyi.web.controller.system;
import cn.dev33.satoken.annotation.SaCheckPermission; import cn.dev33.satoken.annotation.SaCheckPermission;
import cn.dev33.satoken.secure.BCrypt; import cn.dev33.satoken.secure.BCrypt;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.ArrayUtil; import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
@ -23,6 +24,7 @@ import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.system.domain.vo.SysUserExportVo; import com.ruoyi.system.domain.vo.SysUserExportVo;
import com.ruoyi.system.domain.vo.SysUserImportVo; import com.ruoyi.system.domain.vo.SysUserImportVo;
import com.ruoyi.system.listener.SysUserImportListener; import com.ruoyi.system.listener.SysUserImportListener;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysPostService; import com.ruoyi.system.service.ISysPostService;
import com.ruoyi.system.service.ISysRoleService; import com.ruoyi.system.service.ISysRoleService;
import com.ruoyi.system.service.ISysUserService; import com.ruoyi.system.service.ISysUserService;
@ -52,6 +54,7 @@ public class SysUserController extends BaseController {
private final ISysUserService userService; private final ISysUserService userService;
private final ISysRoleService roleService; private final ISysRoleService roleService;
private final ISysPostService postService; private final ISysPostService postService;
private final ISysDeptService deptService;
/** /**
* 获取用户列表 * 获取用户列表
@ -235,4 +238,14 @@ public class SysUserController extends BaseController {
userService.insertUserAuth(userId, roleIds); userService.insertUserAuth(userId, roleIds);
return R.ok(); return R.ok();
} }
/**
* 获取部门树列表
*/
@SaCheckPermission("system:user:list")
@GetMapping("/deptTree")
public R<List<Tree<Long>>> deptTree(SysDept dept) {
return R.ok(deptService.selectDeptTreeList(dept));
}
} }

View File

@ -237,7 +237,7 @@ thread-pool:
lock4j: lock4j:
# 获取分布式锁超时时间,默认为 3000 毫秒 # 获取分布式锁超时时间,默认为 3000 毫秒
acquire-timeout: 3000 acquire-timeout: 3000
# 分布式锁的超时时间,默认为 30 # 分布式锁的超时时间,默认为 30
expire: 30000 expire: 30000
--- # Actuator 监控端点的配置项 --- # Actuator 监控端点的配置项

View File

@ -1,45 +1,45 @@
#\u9519\u8BEF\u6D88\u606F #错误消息
not.null=* \u5FC5\u987B\u586B\u5199 not.null=* 必须填写
user.jcaptcha.error=\u9A8C\u8BC1\u7801\u9519\u8BEF user.jcaptcha.error=验证码错误
user.jcaptcha.expire=\u9A8C\u8BC1\u7801\u5DF2\u5931\u6548 user.jcaptcha.expire=验证码已失效
user.not.exists=\u5BF9\u4E0D\u8D77, \u60A8\u7684\u8D26\u53F7\uFF1A{0} \u4E0D\u5B58\u5728. user.not.exists=对不起, 您的账号:{0} 不存在.
user.password.not.match=\u7528\u6237\u4E0D\u5B58\u5728/\u5BC6\u7801\u9519\u8BEF user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=\u5BC6\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21 user.password.retry.limit.count=密码输入错误{0}次
user.password.retry.limit.exceed=\u5BC6\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21\uFF0C\u5E10\u6237\u9501\u5B9A{1}\u5206\u949F user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
user.password.delete=\u5BF9\u4E0D\u8D77\uFF0C\u60A8\u7684\u8D26\u53F7\uFF1A{0} \u5DF2\u88AB\u5220\u9664 user.password.delete=对不起,您的账号:{0} 已被删除
user.blocked=\u5BF9\u4E0D\u8D77\uFF0C\u60A8\u7684\u8D26\u53F7\uFF1A{0} \u5DF2\u7981\u7528\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458 user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员
role.blocked=\u89D2\u8272\u5DF2\u5C01\u7981\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458 role.blocked=角色已封禁,请联系管理员
user.logout.success=\u9000\u51FA\u6210\u529F user.logout.success=退出成功
length.not.valid=\u957F\u5EA6\u5FC5\u987B\u5728{min}\u5230{max}\u4E2A\u5B57\u7B26\u4E4B\u95F4 length.not.valid=长度必须在{min}到{max}个字符之间
user.username.not.blank=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A user.username.not.blank=用户名不能为空
user.username.not.valid=* 2\u523020\u4E2A\u6C49\u5B57\u3001\u5B57\u6BCD\u3001\u6570\u5B57\u6216\u4E0B\u5212\u7EBF\u7EC4\u6210\uFF0C\u4E14\u5FC5\u987B\u4EE5\u975E\u6570\u5B57\u5F00\u5934 user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成且必须以非数字开头
user.username.length.valid=\u8D26\u6237\u957F\u5EA6\u5FC5\u987B\u5728{min}\u5230{max}\u4E2A\u5B57\u7B26\u4E4B\u95F4 user.username.length.valid=账户长度必须在{min}到{max}个字符之间
user.password.not.blank=\u7528\u6237\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A user.password.not.blank=用户密码不能为空
user.password.length.valid=\u7528\u6237\u5BC6\u7801\u957F\u5EA6\u5FC5\u987B\u5728{min}\u5230{max}\u4E2A\u5B57\u7B26\u4E4B\u95F4 user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
user.password.not.valid=* 5-50\u4E2A\u5B57\u7B26 user.password.not.valid=* 5-50个字符
user.email.not.valid=\u90AE\u7BB1\u683C\u5F0F\u9519\u8BEF user.email.not.valid=邮箱格式错误
user.phonenumber.not.blank=\u7528\u6237\u624B\u673A\u53F7\u4E0D\u80FD\u4E3A\u7A7A user.phonenumber.not.blank=用户手机号不能为空
user.mobile.phone.number.not.valid=\u624B\u673A\u53F7\u683C\u5F0F\u9519\u8BEF user.mobile.phone.number.not.valid=手机号格式错误
user.login.success=\u767B\u5F55\u6210\u529F user.login.success=登录成功
user.register.success=\u6CE8\u518C\u6210\u529F user.register.success=注册成功
user.register.save.error=\u4FDD\u5B58\u7528\u6237 {0} \u5931\u8D25\uFF0C\u6CE8\u518C\u8D26\u53F7\u5DF2\u5B58\u5728 user.register.save.error=保存用户 {0} 失败,注册账号已存在
user.register.error=\u6CE8\u518C\u5931\u8D25\uFF0C\u8BF7\u8054\u7CFB\u7CFB\u7EDF\u7BA1\u7406\u4EBA\u5458 user.register.error=注册失败,请联系系统管理人员
user.notfound=\u8BF7\u91CD\u65B0\u767B\u5F55 user.notfound=请重新登录
user.forcelogout=\u7BA1\u7406\u5458\u5F3A\u5236\u9000\u51FA\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55 user.forcelogout=管理员强制退出,请重新登录
user.unknown.error=\u672A\u77E5\u9519\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55 user.unknown.error=未知错误,请重新登录
##\u6587\u4EF6\u4E0A\u4F20\u6D88\u606F ##文件上传消息
upload.exceed.maxSize=\u4E0A\u4F20\u7684\u6587\u4EF6\u5927\u5C0F\u8D85\u51FA\u9650\u5236\u7684\u6587\u4EF6\u5927\u5C0F\uFF01<br/>\u5141\u8BB8\u7684\u6587\u4EF6\u6700\u5927\u5927\u5C0F\u662F\uFF1A{0}MB\uFF01 upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB
upload.filename.exceed.length=\u4E0A\u4F20\u7684\u6587\u4EF6\u540D\u6700\u957F{0}\u4E2A\u5B57\u7B26 upload.filename.exceed.length=上传的文件名最长{0}个字符
##\u6743\u9650 ##权限
no.permission=\u60A8\u6CA1\u6709\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
no.create.permission=\u60A8\u6CA1\u6709\u521B\u5EFA\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
no.update.permission=\u60A8\u6CA1\u6709\u4FEE\u6539\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
no.delete.permission=\u60A8\u6CA1\u6709\u5220\u9664\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
no.export.permission=\u60A8\u6CA1\u6709\u5BFC\u51FA\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
no.view.permission=\u60A8\u6CA1\u6709\u67E5\u770B\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
repeat.submit.message=\u4E0D\u5141\u8BB8\u91CD\u590D\u63D0\u4EA4\uFF0C\u8BF7\u7A0D\u5019\u518D\u8BD5 repeat.submit.message=不允许重复提交,请稍候再试
rate.limiter.message=\u8BBF\u95EE\u8FC7\u4E8E\u9891\u7E41\uFF0C\u8BF7\u7A0D\u5019\u518D\u8BD5 rate.limiter.message=访问过于频繁,请稍候再试
sms.code.not.blank=\u77ED\u4FE1\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A sms.code.not.blank=短信验证码不能为空
sms.code.retry.limit.count=\u77ED\u4FE1\u9A8C\u8BC1\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21 sms.code.retry.limit.count=短信验证码输入错误{0}次
sms.code.retry.limit.exceed=\u77ED\u4FE1\u9A8C\u8BC1\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21\uFF0C\u5E10\u6237\u9501\u5B9A{0}\u5206\u949F sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{0}分钟
xcx.code.not.blank=\u5C0F\u7A0B\u5E8Fcode\u4E0D\u80FD\u4E3A\u7A7A xcx.code.not.blank=小程序code不能为空

View File

@ -1,4 +1,4 @@
#\u9519\u8BEF\u6D88\u606F #错误消息
not.null=* Required fill in not.null=* Required fill in
user.jcaptcha.error=Captcha error user.jcaptcha.error=Captcha error
user.jcaptcha.expire=Captcha invalid user.jcaptcha.expire=Captcha invalid
@ -6,9 +6,9 @@ user.not.exists=Sorry, your account: {0} does not exist
user.password.not.match=User does not exist/Password error user.password.not.match=User does not exist/Password error
user.password.retry.limit.count=Password input error {0} times user.password.retry.limit.count=Password input error {0} times
user.password.retry.limit.exceed=Password input error {0} times, account locked for {1} minutes user.password.retry.limit.exceed=Password input error {0} times, account locked for {1} minutes
user.password.delete=Sorry, your account\uFF1A{0} has been deleted user.password.delete=Sorry, your account{0} has been deleted
user.blocked=Sorry, your account: {0} has been disabled. Please contact the administrator user.blocked=Sorry, your account: {0} has been disabled. Please contact the administrator
role.blocked=Role disabled\uFF0Cplease contact administrators role.blocked=Role disabledplease contact administrators
user.logout.success=Exit successful user.logout.success=Exit successful
length.not.valid=The length must be between {min} and {max} characters length.not.valid=The length must be between {min} and {max} characters
user.username.not.blank=Username cannot be blank user.username.not.blank=Username cannot be blank
@ -25,18 +25,18 @@ user.register.success=Register successful
user.register.save.error=Failed to save user {0}, The registered account already exists user.register.save.error=Failed to save user {0}, The registered account already exists
user.register.error=Register failed, please contact system administrator user.register.error=Register failed, please contact system administrator
user.notfound=Please login again user.notfound=Please login again
user.forcelogout=The administrator is forced to exit\uFF0Cplease login again user.forcelogout=The administrator is forced to exitplease login again
user.unknown.error=Unknown error, please login again user.unknown.error=Unknown error, please login again
##\u6587\u4EF6\u4E0A\u4F20\u6D88\u606F ##文件上传消息
upload.exceed.maxSize=The uploaded file size exceeds the limit file size\uFF01<br/>the maximum allowed file size is\uFF1A{0}MB\uFF01 upload.exceed.maxSize=The uploaded file size exceeds the limit file size<br/>the maximum allowed file size is{0}MB
upload.filename.exceed.length=The maximum length of uploaded file name is {0} characters upload.filename.exceed.length=The maximum length of uploaded file name is {0} characters
##\u6743\u9650 ##权限
no.permission=You do not have permission to the data\uFF0Cplease contact your administrator to add permissions [{0}] no.permission=You do not have permission to the dataplease contact your administrator to add permissions [{0}]
no.create.permission=You do not have permission to create data\uFF0Cplease contact your administrator to add permissions [{0}] no.create.permission=You do not have permission to create dataplease contact your administrator to add permissions [{0}]
no.update.permission=You do not have permission to modify data\uFF0Cplease contact your administrator to add permissions [{0}] no.update.permission=You do not have permission to modify dataplease contact your administrator to add permissions [{0}]
no.delete.permission=You do not have permission to delete data\uFF0Cplease contact your administrator to add permissions [{0}] no.delete.permission=You do not have permission to delete dataplease contact your administrator to add permissions [{0}]
no.export.permission=You do not have permission to export data\uFF0Cplease contact your administrator to add permissions [{0}] no.export.permission=You do not have permission to export dataplease contact your administrator to add permissions [{0}]
no.view.permission=You do not have permission to view data\uFF0Cplease contact your administrator to add permissions [{0}] no.view.permission=You do not have permission to view dataplease contact your administrator to add permissions [{0}]
repeat.submit.message=Repeat submit is not allowed, please try again later repeat.submit.message=Repeat submit is not allowed, please try again later
rate.limiter.message=Visit too frequently, please try again later rate.limiter.message=Visit too frequently, please try again later
sms.code.not.blank=Sms code cannot be blank sms.code.not.blank=Sms code cannot be blank

View File

@ -1,45 +1,45 @@
#\u9519\u8BEF\u6D88\u606F #错误消息
not.null=* \u5FC5\u987B\u586B\u5199 not.null=* 必须填写
user.jcaptcha.error=\u9A8C\u8BC1\u7801\u9519\u8BEF user.jcaptcha.error=验证码错误
user.jcaptcha.expire=\u9A8C\u8BC1\u7801\u5DF2\u5931\u6548 user.jcaptcha.expire=验证码已失效
user.not.exists=\u5BF9\u4E0D\u8D77, \u60A8\u7684\u8D26\u53F7\uFF1A{0} \u4E0D\u5B58\u5728. user.not.exists=对不起, 您的账号:{0} 不存在.
user.password.not.match=\u7528\u6237\u4E0D\u5B58\u5728/\u5BC6\u7801\u9519\u8BEF user.password.not.match=用户不存在/密码错误
user.password.retry.limit.count=\u5BC6\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21 user.password.retry.limit.count=密码输入错误{0}次
user.password.retry.limit.exceed=\u5BC6\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21\uFF0C\u5E10\u6237\u9501\u5B9A{1}\u5206\u949F user.password.retry.limit.exceed=密码输入错误{0}次,帐户锁定{1}分钟
user.password.delete=\u5BF9\u4E0D\u8D77\uFF0C\u60A8\u7684\u8D26\u53F7\uFF1A{0} \u5DF2\u88AB\u5220\u9664 user.password.delete=对不起,您的账号:{0} 已被删除
user.blocked=\u5BF9\u4E0D\u8D77\uFF0C\u60A8\u7684\u8D26\u53F7\uFF1A{0} \u5DF2\u7981\u7528\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458 user.blocked=对不起,您的账号:{0} 已禁用,请联系管理员
role.blocked=\u89D2\u8272\u5DF2\u5C01\u7981\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458 role.blocked=角色已封禁,请联系管理员
user.logout.success=\u9000\u51FA\u6210\u529F user.logout.success=退出成功
length.not.valid=\u957F\u5EA6\u5FC5\u987B\u5728{min}\u5230{max}\u4E2A\u5B57\u7B26\u4E4B\u95F4 length.not.valid=长度必须在{min}到{max}个字符之间
user.username.not.blank=\u7528\u6237\u540D\u4E0D\u80FD\u4E3A\u7A7A user.username.not.blank=用户名不能为空
user.username.not.valid=* 2\u523020\u4E2A\u6C49\u5B57\u3001\u5B57\u6BCD\u3001\u6570\u5B57\u6216\u4E0B\u5212\u7EBF\u7EC4\u6210\uFF0C\u4E14\u5FC5\u987B\u4EE5\u975E\u6570\u5B57\u5F00\u5934 user.username.not.valid=* 2到20个汉字、字母、数字或下划线组成且必须以非数字开头
user.username.length.valid=\u8D26\u6237\u957F\u5EA6\u5FC5\u987B\u5728{min}\u5230{max}\u4E2A\u5B57\u7B26\u4E4B\u95F4 user.username.length.valid=账户长度必须在{min}到{max}个字符之间
user.password.not.blank=\u7528\u6237\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A user.password.not.blank=用户密码不能为空
user.password.length.valid=\u7528\u6237\u5BC6\u7801\u957F\u5EA6\u5FC5\u987B\u5728{min}\u5230{max}\u4E2A\u5B57\u7B26\u4E4B\u95F4 user.password.length.valid=用户密码长度必须在{min}到{max}个字符之间
user.password.not.valid=* 5-50\u4E2A\u5B57\u7B26 user.password.not.valid=* 5-50个字符
user.email.not.valid=\u90AE\u7BB1\u683C\u5F0F\u9519\u8BEF user.email.not.valid=邮箱格式错误
user.phonenumber.not.blank=\u7528\u6237\u624B\u673A\u53F7\u4E0D\u80FD\u4E3A\u7A7A user.phonenumber.not.blank=用户手机号不能为空
user.mobile.phone.number.not.valid=\u624B\u673A\u53F7\u683C\u5F0F\u9519\u8BEF user.mobile.phone.number.not.valid=手机号格式错误
user.login.success=\u767B\u5F55\u6210\u529F user.login.success=登录成功
user.register.success=\u6CE8\u518C\u6210\u529F user.register.success=注册成功
user.register.save.error=\u4FDD\u5B58\u7528\u6237 {0} \u5931\u8D25\uFF0C\u6CE8\u518C\u8D26\u53F7\u5DF2\u5B58\u5728 user.register.save.error=保存用户 {0} 失败,注册账号已存在
user.register.error=\u6CE8\u518C\u5931\u8D25\uFF0C\u8BF7\u8054\u7CFB\u7CFB\u7EDF\u7BA1\u7406\u4EBA\u5458 user.register.error=注册失败,请联系系统管理人员
user.notfound=\u8BF7\u91CD\u65B0\u767B\u5F55 user.notfound=请重新登录
user.forcelogout=\u7BA1\u7406\u5458\u5F3A\u5236\u9000\u51FA\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55 user.forcelogout=管理员强制退出,请重新登录
user.unknown.error=\u672A\u77E5\u9519\u8BEF\uFF0C\u8BF7\u91CD\u65B0\u767B\u5F55 user.unknown.error=未知错误,请重新登录
##\u6587\u4EF6\u4E0A\u4F20\u6D88\u606F ##文件上传消息
upload.exceed.maxSize=\u4E0A\u4F20\u7684\u6587\u4EF6\u5927\u5C0F\u8D85\u51FA\u9650\u5236\u7684\u6587\u4EF6\u5927\u5C0F\uFF01<br/>\u5141\u8BB8\u7684\u6587\u4EF6\u6700\u5927\u5927\u5C0F\u662F\uFF1A{0}MB\uFF01 upload.exceed.maxSize=上传的文件大小超出限制的文件大小!<br/>允许的文件最大大小是:{0}MB
upload.filename.exceed.length=\u4E0A\u4F20\u7684\u6587\u4EF6\u540D\u6700\u957F{0}\u4E2A\u5B57\u7B26 upload.filename.exceed.length=上传的文件名最长{0}个字符
##\u6743\u9650 ##权限
no.permission=\u60A8\u6CA1\u6709\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.permission=您没有数据的权限,请联系管理员添加权限 [{0}]
no.create.permission=\u60A8\u6CA1\u6709\u521B\u5EFA\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.create.permission=您没有创建数据的权限,请联系管理员添加权限 [{0}]
no.update.permission=\u60A8\u6CA1\u6709\u4FEE\u6539\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.update.permission=您没有修改数据的权限,请联系管理员添加权限 [{0}]
no.delete.permission=\u60A8\u6CA1\u6709\u5220\u9664\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.delete.permission=您没有删除数据的权限,请联系管理员添加权限 [{0}]
no.export.permission=\u60A8\u6CA1\u6709\u5BFC\u51FA\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.export.permission=您没有导出数据的权限,请联系管理员添加权限 [{0}]
no.view.permission=\u60A8\u6CA1\u6709\u67E5\u770B\u6570\u636E\u7684\u6743\u9650\uFF0C\u8BF7\u8054\u7CFB\u7BA1\u7406\u5458\u6DFB\u52A0\u6743\u9650 [{0}] no.view.permission=您没有查看数据的权限,请联系管理员添加权限 [{0}]
repeat.submit.message=\u4E0D\u5141\u8BB8\u91CD\u590D\u63D0\u4EA4\uFF0C\u8BF7\u7A0D\u5019\u518D\u8BD5 repeat.submit.message=不允许重复提交,请稍候再试
rate.limiter.message=\u8BBF\u95EE\u8FC7\u4E8E\u9891\u7E41\uFF0C\u8BF7\u7A0D\u5019\u518D\u8BD5 rate.limiter.message=访问过于频繁,请稍候再试
sms.code.not.blank=\u77ED\u4FE1\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A sms.code.not.blank=短信验证码不能为空
sms.code.retry.limit.count=\u77ED\u4FE1\u9A8C\u8BC1\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21 sms.code.retry.limit.count=短信验证码输入错误{0}次
sms.code.retry.limit.exceed=\u77ED\u4FE1\u9A8C\u8BC1\u7801\u8F93\u5165\u9519\u8BEF{0}\u6B21\uFF0C\u5E10\u6237\u9501\u5B9A{0}\u5206\u949F sms.code.retry.limit.exceed=短信验证码输入错误{0}次,帐户锁定{0}分钟
xcx.code.not.blank=\u5C0F\u7A0B\u5E8Fcode\u4E0D\u80FD\u4E3A\u7A7A xcx.code.not.blank=小程序code不能为空

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -17,6 +17,11 @@ public interface Constants {
*/ */
String GBK = "GBK"; String GBK = "GBK";
/**
* www主域
*/
String WWW = "www.";
/** /**
* http请求 * http请求
*/ */

View File

@ -75,4 +75,11 @@ public class R<T> implements Serializable {
return r; return r;
} }
public Boolean isError() {
return !isSuccess();
}
public Boolean isSuccess() {
return R.SUCCESS == getCode();
}
} }

View File

@ -80,7 +80,7 @@ public class SysMenu extends TreeEntity<SysMenu> {
private String visible; private String visible;
/** /**
* 菜单状态0显示 1隐藏 * 菜单状态0正常 1停用
*/ */
private String status; private String status;

View File

@ -17,6 +17,7 @@ import lombok.NoArgsConstructor;
import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import java.util.Set;
/** /**
* 角色表 sys_role * 角色表 sys_role
@ -82,7 +83,7 @@ public class SysRole extends BaseEntity {
* 角色状态0正常 1停用 * 角色状态0正常 1停用
*/ */
@ExcelProperty(value = "角色状态", converter = ExcelDictConvert.class) @ExcelProperty(value = "角色状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_common_status") @ExcelDictFormat(dictType = "sys_normal_disable")
private String status; private String status;
/** /**
@ -114,6 +115,12 @@ public class SysRole extends BaseEntity {
@TableField(exist = false) @TableField(exist = false)
private Long[] deptIds; private Long[] deptIds;
/**
* 角色菜单权限
*/
@TableField(exist = false)
private Set<String> permissions;
public SysRole(Long roleId) { public SysRole(Long roleId) {
this.roleId = roleId; this.roleId = roleId;
} }

View File

@ -5,7 +5,6 @@ import lombok.AccessLevel;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.redisson.api.*; import org.redisson.api.*;
import java.util.Comparator;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Consumer; import java.util.function.Consumer;
@ -30,6 +29,43 @@ public class QueueUtils {
return CLIENT; return CLIENT;
} }
/**
* 添加普通队列数据
*
* @param queueName 队列名
* @param data 数据
*/
public static <T> boolean addQueueObject(String queueName, T data) {
RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
return queue.offer(data);
}
/**
* 通用获取一个队列数据 没有数据返回 null(不支持延迟队列)
*
* @param queueName 队列名
*/
public static <T> T getQueueObject(String queueName) {
RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
return queue.poll();
}
/**
* 通用删除队列数据(不支持延迟队列)
*/
public static <T> boolean removeQueueObject(String queueName, T data) {
RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
return queue.remove(data);
}
/**
* 通用销毁队列 所有阻塞监听 报错(不支持延迟队列)
*/
public static <T> boolean destroyQueue(String queueName) {
RBlockingQueue<T> queue = CLIENT.getBlockingQueue(queueName);
return queue.delete();
}
/** /**
* 添加延迟队列数据 默认毫秒 * 添加延迟队列数据 默认毫秒
* *
@ -84,32 +120,6 @@ public class QueueUtils {
delayedQueue.destroy(); delayedQueue.destroy();
} }
/**
* 尝试设置 优先队列比较器 用于排序优先级
*
* @param queueName 队列名
* @param comparator 比较器
*/
public static <T> boolean trySetPriorityQueueComparator(String queueName, Comparator<T> comparator) {
RPriorityBlockingQueue<T> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
return priorityBlockingQueue.trySetComparator(comparator);
}
/**
* 尝试设置 优先队列比较器 用于排序优先级
*
* @param queueName 队列名
* @param comparator 比较器
* @param destroy 已存在是否销毁
*/
public static <T> boolean trySetPriorityQueueComparator(String queueName, Comparator<T> comparator, boolean destroy) {
RPriorityBlockingQueue<T> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
if (priorityBlockingQueue.isExists() && destroy) {
destroyPriorityQueueObject(queueName);
}
return priorityBlockingQueue.trySetComparator(comparator);
}
/** /**
* 添加优先队列数据 * 添加优先队列数据
* *
@ -121,32 +131,6 @@ public class QueueUtils {
return priorityBlockingQueue.offer(data); return priorityBlockingQueue.offer(data);
} }
/**
* 获取一个优先队列数据 没有数据返回 null
*
* @param queueName 队列名
*/
public static <T> T getPriorityQueueObject(String queueName) {
RPriorityBlockingQueue<T> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
return priorityBlockingQueue.poll();
}
/**
* 删除优先队列数据
*/
public static <T> boolean removePriorityQueueObject(String queueName, T data) {
RPriorityBlockingQueue<T> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
return priorityBlockingQueue.remove(data);
}
/**
* 销毁优先队列
*/
public static boolean destroyPriorityQueueObject(String queueName) {
RPriorityBlockingQueue<?> priorityBlockingQueue = CLIENT.getPriorityBlockingQueue(queueName);
return priorityBlockingQueue.delete();
}
/** /**
* 尝试设置 有界队列 容量 用于限制数量 * 尝试设置 有界队列 容量 用于限制数量
* *
@ -168,7 +152,7 @@ public class QueueUtils {
public static <T> boolean trySetBoundedQueueCapacity(String queueName, int capacity, boolean destroy) { public static <T> boolean trySetBoundedQueueCapacity(String queueName, int capacity, boolean destroy) {
RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName); RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
if (boundedBlockingQueue.isExists() && destroy) { if (boundedBlockingQueue.isExists() && destroy) {
destroyBoundedQueueObject(queueName); destroyQueue(queueName);
} }
return boundedBlockingQueue.trySetCapacity(capacity); return boundedBlockingQueue.trySetCapacity(capacity);
} }
@ -185,32 +169,6 @@ public class QueueUtils {
return boundedBlockingQueue.offer(data); return boundedBlockingQueue.offer(data);
} }
/**
* 获取一个有界队列数据 没有数据返回 null
*
* @param queueName 队列名
*/
public static <T> T getBoundedQueueObject(String queueName) {
RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
return boundedBlockingQueue.poll();
}
/**
* 删除有界队列数据
*/
public static <T> boolean removeBoundedQueueObject(String queueName, T data) {
RBoundedBlockingQueue<T> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
return boundedBlockingQueue.remove(data);
}
/**
* 销毁有界队列
*/
public static boolean destroyBoundedQueueObject(String queueName) {
RBoundedBlockingQueue<?> boundedBlockingQueue = CLIENT.getBoundedBlockingQueue(queueName);
return boundedBlockingQueue.delete();
}
/** /**
* 订阅阻塞队列(可订阅所有实现类 例如: 延迟 优先 有界 ) * 订阅阻塞队列(可订阅所有实现类 例如: 延迟 优先 有界 )
*/ */

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -35,7 +35,7 @@ public class BoundedQueueController {
@GetMapping("/add") @GetMapping("/add")
public R<Void> add(String queueName, int capacity) { public R<Void> add(String queueName, int capacity) {
// 用完了一定要销毁 否则会一直存在 // 用完了一定要销毁 否则会一直存在
boolean b = QueueUtils.destroyBoundedQueueObject(queueName); boolean b = QueueUtils.destroyQueue(queueName);
log.info("通道: {} , 删除: {}", queueName, b); log.info("通道: {} , 删除: {}", queueName, b);
// 初始化设置一次即可 // 初始化设置一次即可
if (QueueUtils.trySetBoundedQueueCapacity(queueName, capacity)) { if (QueueUtils.trySetBoundedQueueCapacity(queueName, capacity)) {
@ -64,7 +64,7 @@ public class BoundedQueueController {
@GetMapping("/remove") @GetMapping("/remove")
public R<Void> remove(String queueName) { public R<Void> remove(String queueName) {
String data = "data-" + 5; String data = "data-" + 5;
if (QueueUtils.removeBoundedQueueObject(queueName, data)) { if (QueueUtils.removeQueueObject(queueName, data)) {
log.info("通道: {} , 删除数据: {}", queueName, data); log.info("通道: {} , 删除数据: {}", queueName, data);
} else { } else {
return R.fail("操作失败"); return R.fail("操作失败");
@ -81,7 +81,7 @@ public class BoundedQueueController {
public R<Void> get(String queueName) { public R<Void> get(String queueName) {
String data; String data;
do { do {
data = QueueUtils.getBoundedQueueObject(queueName); data = QueueUtils.getQueueObject(queueName);
log.info("通道: {} , 获取数据: {}", queueName, data); log.info("通道: {} , 获取数据: {}", queueName, data);
} while (data != null); } while (data != null);
return R.ok("操作成功"); return R.ok("操作成功");

View File

@ -2,6 +2,7 @@ package com.ruoyi.demo.controller.queue;
import lombok.Data; import lombok.Data;
import lombok.NoArgsConstructor; import lombok.NoArgsConstructor;
import org.jetbrains.annotations.NotNull;
/** /**
* 实体类 注意不允许使用内部类 否则会找不到类 * 实体类 注意不允许使用内部类 否则会找不到类
@ -11,7 +12,12 @@ import lombok.NoArgsConstructor;
*/ */
@Data @Data
@NoArgsConstructor @NoArgsConstructor
public class PriorityDemo { public class PriorityDemo implements Comparable<PriorityDemo> {
private String name; private String name;
private Integer orderNum; private Integer orderNum;
@Override
public int compareTo(@NotNull PriorityDemo other) {
return Integer.compare(getOrderNum(), other.getOrderNum());
}
} }

View File

@ -1,16 +0,0 @@
package com.ruoyi.demo.controller.queue;
import java.util.Comparator;
/**
* 比较器 注意不允许使用 内部类或匿名类或lambda表达式 会找不到类
*
* @author Lion Li
* @version 3.6.0
*/
public class PriorityDemoComparator implements Comparator<PriorityDemo> {
@Override
public int compare(PriorityDemo pd1, PriorityDemo pd2) {
return Integer.compare(pd1.getOrderNum(), pd2.getOrderNum());
}
}

View File

@ -34,16 +34,9 @@ public class PriorityQueueController {
@GetMapping("/add") @GetMapping("/add")
public R<Void> add(String queueName) { public R<Void> add(String queueName) {
// 用完了一定要销毁 否则会一直存在 // 用完了一定要销毁 否则会一直存在
boolean b = QueueUtils.destroyPriorityQueueObject(queueName); boolean b = QueueUtils.destroyQueue(queueName);
log.info("通道: {} , 删除: {}", queueName, b); log.info("通道: {} , 删除: {}", queueName, b);
// 初始化设置一次即可 此处注意 不允许用内部类或匿名类
boolean flag = QueueUtils.trySetPriorityQueueComparator(queueName, new PriorityDemoComparator());
if (flag) {
log.info("通道: {} , 设置比较器成功", queueName);
} else {
log.info("通道: {} , 设置比较器失败", queueName);
return R.fail("操作失败");
}
for (int i = 0; i < 10; i++) { for (int i = 0; i < 10; i++) {
int randomNum = RandomUtil.randomInt(10); int randomNum = RandomUtil.randomInt(10);
PriorityDemo data = new PriorityDemo(); PriorityDemo data = new PriorityDemo();
@ -70,7 +63,7 @@ public class PriorityQueueController {
PriorityDemo data = new PriorityDemo(); PriorityDemo data = new PriorityDemo();
data.setName(name); data.setName(name);
data.setOrderNum(orderNum); data.setOrderNum(orderNum);
if (QueueUtils.removePriorityQueueObject(queueName, data)) { if (QueueUtils.removeQueueObject(queueName, data)) {
log.info("通道: {} , 删除数据: {}", queueName, data); log.info("通道: {} , 删除数据: {}", queueName, data);
} else { } else {
return R.fail("操作失败"); return R.fail("操作失败");
@ -87,7 +80,7 @@ public class PriorityQueueController {
public R<Void> get(String queueName) { public R<Void> get(String queueName) {
PriorityDemo data; PriorityDemo data;
do { do {
data = QueueUtils.getPriorityQueueObject(queueName); data = QueueUtils.getQueueObject(queueName);
log.info("通道: {} , 获取数据: {}", queueName, data); log.info("通道: {} , 获取数据: {}", queueName, data);
} while (data != null); } while (data != null);
return R.ok("操作成功"); return R.ok("操作成功");

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<artifactId>ruoyi-extend</artifactId> <artifactId>ruoyi-extend</artifactId>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-extend</artifactId> <artifactId>ruoyi-extend</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -59,25 +59,6 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker.plugin.version}</version>
<configuration>
<imageName>${docker.namespace}/${project.artifactId}:${project.version}</imageName>
<dockerDirectory>${project.basedir}</dockerDirectory>
<dockerHost>${docker.registry.host}</dockerHost>
<registryUrl>${docker.registry.url}</registryUrl>
<serverId>${docker.registry.url}</serverId>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@ -4,7 +4,7 @@
<parent> <parent>
<artifactId>ruoyi-extend</artifactId> <artifactId>ruoyi-extend</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<artifactId>ruoyi-xxl-job-admin</artifactId> <artifactId>ruoyi-xxl-job-admin</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
@ -96,27 +96,6 @@
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<!-- docker -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>${docker.plugin.version}</version>
<configuration>
<!-- made of '[a-z0-9-_.]' -->
<imageName>${docker.namespace}/${project.artifactId}:${project.version}</imageName>
<dockerDirectory>${project.basedir}</dockerDirectory>
<dockerHost>${docker.registry.host}</dockerHost>
<registryUrl>${docker.registry.url}</registryUrl>
<serverId>${docker.registry.url}</serverId>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -1,5 +1,7 @@
package com.ruoyi.framework.aspectj; package com.ruoyi.framework.aspectj;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.ObjectUtil;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.domain.dto.OperLogDTO; import com.ruoyi.common.core.domain.dto.OperLogDTO;
@ -36,6 +38,11 @@ import java.util.Map;
@Component @Component
public class LogAspect { public class LogAspect {
/**
* 排除敏感属性字段
*/
public static final String[] EXCLUDE_PROPERTIES = { "password", "oldPassword", "newPassword", "confirmPassword" };
/** /**
* 处理完请求后执行 * 处理完请求后执行
* *
@ -66,7 +73,7 @@ public class LogAspect {
// 请求的地址 // 请求的地址
String ip = ServletUtils.getClientIP(); String ip = ServletUtils.getClientIP();
operLog.setOperIp(ip); operLog.setOperIp(ip);
operLog.setOperUrl(ServletUtils.getRequest().getRequestURI()); operLog.setOperUrl(StringUtils.substring(ServletUtils.getRequest().getRequestURI(), 0, 255));
operLog.setOperName(LoginHelper.getUsername()); operLog.setOperName(LoginHelper.getUsername());
if (e != null) { if (e != null) {
@ -142,7 +149,13 @@ public class LogAspect {
for (Object o : paramsArray) { for (Object o : paramsArray) {
if (ObjectUtil.isNotNull(o) && !isFilterObject(o)) { if (ObjectUtil.isNotNull(o) && !isFilterObject(o)) {
try { try {
params.append(JsonUtils.toJsonString(o)).append(" "); String str = JsonUtils.toJsonString(o);
Dict dict = JsonUtils.parseMap(str);
if (MapUtil.isNotEmpty(dict)) {
MapUtil.removeAny(dict, EXCLUDE_PROPERTIES);
str = JsonUtils.toJsonString(dict);
}
params.append(str).append(" ");
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }

View File

@ -95,10 +95,25 @@ public class SwaggerConfig {
// 对所有路径增加前置上下文路径 // 对所有路径增加前置上下文路径
return openApi -> { return openApi -> {
Paths oldPaths = openApi.getPaths(); Paths oldPaths = openApi.getPaths();
Paths newPaths = new Paths(); if (oldPaths instanceof PlusPaths) {
return;
}
PlusPaths newPaths = new PlusPaths();
oldPaths.forEach((k,v) -> newPaths.addPathItem(finalContextPath + k, v)); oldPaths.forEach((k,v) -> newPaths.addPathItem(finalContextPath + k, v));
openApi.setPaths(newPaths); openApi.setPaths(newPaths);
}; };
} }
/**
* 单独使用一个类便于判断 解决springdoc路径拼接重复问题
*
* @author Lion Li
*/
static class PlusPaths extends Paths {
public PlusPaths() {
super();
}
}
} }

View File

@ -5,18 +5,20 @@ import cn.dev33.satoken.listener.SaTokenListener;
import cn.dev33.satoken.stp.SaLoginModel; import cn.dev33.satoken.stp.SaLoginModel;
import cn.hutool.http.useragent.UserAgent; import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentUtil; import cn.hutool.http.useragent.UserAgentUtil;
import com.ruoyi.common.constant.CacheNames; import com.ruoyi.common.constant.CacheConstants;
import com.ruoyi.common.core.domain.dto.UserOnlineDTO; import com.ruoyi.common.core.domain.dto.UserOnlineDTO;
import com.ruoyi.common.core.domain.model.LoginUser; import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.enums.UserType; import com.ruoyi.common.enums.UserType;
import com.ruoyi.common.helper.LoginHelper; import com.ruoyi.common.helper.LoginHelper;
import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.redis.CacheUtils;
import com.ruoyi.common.utils.ip.AddressUtils; import com.ruoyi.common.utils.ip.AddressUtils;
import com.ruoyi.common.utils.redis.RedisUtils;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.time.Duration;
/** /**
* 用户行为 侦听器的实现 * 用户行为 侦听器的实现
* *
@ -48,12 +50,7 @@ public class UserActionListener implements SaTokenListener {
dto.setTokenId(tokenValue); dto.setTokenId(tokenValue);
dto.setUserName(user.getUsername()); dto.setUserName(user.getUsername());
dto.setDeptName(user.getDeptName()); dto.setDeptName(user.getDeptName());
String cacheNames = CacheNames.ONLINE_TOKEN; RedisUtils.setCacheObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue, dto, Duration.ofSeconds(tokenConfig.getTimeout()));
if (tokenConfig.getTimeout() > 0) {
// 增加 ttl 过期时间 单位秒
cacheNames = CacheNames.ONLINE_TOKEN + "#" + tokenConfig.getTimeout() + "s";
}
CacheUtils.put(cacheNames, tokenValue, dto);
log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue); log.info("user doLogin, userId:{}, token:{}", loginId, tokenValue);
} else if (userType == UserType.APP_USER) { } else if (userType == UserType.APP_USER) {
// app端 自行根据业务编写 // app端 自行根据业务编写
@ -65,7 +62,7 @@ public class UserActionListener implements SaTokenListener {
*/ */
@Override @Override
public void doLogout(String loginType, Object loginId, String tokenValue) { public void doLogout(String loginType, Object loginId, String tokenValue) {
CacheUtils.evict(CacheNames.ONLINE_TOKEN, tokenValue); RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue); log.info("user doLogout, userId:{}, token:{}", loginId, tokenValue);
} }
@ -74,7 +71,7 @@ public class UserActionListener implements SaTokenListener {
*/ */
@Override @Override
public void doKickout(String loginType, Object loginId, String tokenValue) { public void doKickout(String loginType, Object loginId, String tokenValue) {
CacheUtils.evict(CacheNames.ONLINE_TOKEN, tokenValue); RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
log.info("user doLogoutByLoginId, userId:{}, token:{}", loginId, tokenValue); log.info("user doLogoutByLoginId, userId:{}, token:{}", loginId, tokenValue);
} }
@ -83,7 +80,7 @@ public class UserActionListener implements SaTokenListener {
*/ */
@Override @Override
public void doReplaced(String loginType, Object loginId, String tokenValue) { public void doReplaced(String loginType, Object loginId, String tokenValue) {
CacheUtils.evict(CacheNames.ONLINE_TOKEN, tokenValue); RedisUtils.deleteObject(CacheConstants.ONLINE_TOKEN_KEY + tokenValue);
log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue); log.info("user doReplaced, userId:{}, token:{}", loginId, tokenValue);
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -504,6 +504,7 @@ export default {
this.loading = false; this.loading = false;
this.getList(); this.getList();
this.#[[$modal]]#.msgSuccess("删除成功"); this.#[[$modal]]#.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => { }).finally(() => {
this.loading = false; this.loading = false;
}); });

View File

@ -561,6 +561,7 @@ export default {
this.loading = false; this.loading = false;
this.getList(); this.getList();
this.#[[$modal]]#.msgSuccess("删除成功"); this.#[[$modal]]#.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => { }).finally(() => {
this.loading = false; this.loading = false;
}); });

View File

@ -487,6 +487,7 @@ function handleDelete(row) {
loading.value = false; loading.value = false;
getList(); getList();
proxy.#[[$modal]]#.msgSuccess("删除成功"); proxy.#[[$modal]]#.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => { }).finally(() => {
loading.value = false; loading.value = false;
}); });

View File

@ -553,6 +553,7 @@ function handleDelete(row) {
loading.value = true; loading.value = true;
getList(); getList();
proxy.#[[$modal]]#.msgSuccess("删除成功"); proxy.#[[$modal]]#.msgSuccess("删除成功");
}).catch(() => {
}).finally(() => { }).finally(() => {
loading.value = false; loading.value = false;
}); });

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging> <packaging>jar</packaging>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -23,7 +23,7 @@ public interface OssConstant {
/** /**
* 系统数据ids * 系统数据ids
*/ */
List<Integer> SYSTEM_DATA_IDS = Arrays.asList(1, 2, 3, 4); List<Long> SYSTEM_DATA_IDS = Arrays.asList(1L, 2L, 3L, 4L);
/** /**
* 云服务商 * 云服务商

View File

@ -10,6 +10,7 @@ import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder; import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3; import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client; import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*; import com.amazonaws.services.s3.model.*;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.StringUtils;
@ -51,12 +52,16 @@ public class OssClient {
} else { } else {
clientConfig.setProtocol(Protocol.HTTP); clientConfig.setProtocol(Protocol.HTTP);
} }
this.client = AmazonS3Client.builder() AmazonS3ClientBuilder build = AmazonS3Client.builder()
.withEndpointConfiguration(endpointConfig) .withEndpointConfiguration(endpointConfig)
.withClientConfiguration(clientConfig) .withClientConfiguration(clientConfig)
.withCredentials(credentialsProvider) .withCredentials(credentialsProvider)
.disableChunkedEncoding() .disableChunkedEncoding();
.build(); if (!StringUtils.containsAny(properties.getEndpoint(), OssConstant.CLOUD_SERVICE)){
// minio 使用https限制使用域名访问 需要此配置 站点填域名
build.enablePathStyleAccess();
}
this.client = build.build();
createBucket(); createBucket();
} catch (Exception e) { } catch (Exception e) {

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi-vue-plus</artifactId> <artifactId>ruoyi-vue-plus</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>4.3.0-beta2</version> <version>4.3.0</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

View File

@ -61,7 +61,7 @@ public class SysPost extends BaseEntity {
* 状态0正常 1停用 * 状态0正常 1停用
*/ */
@ExcelProperty(value = "状态", converter = ExcelDictConvert.class) @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
@ExcelDictFormat(dictType = "sys_common_status") @ExcelDictFormat(dictType = "sys_normal_disable")
private String status; private String status;
/** /**

View File

@ -40,6 +40,14 @@ public interface SysMenuMapper extends BaseMapperPlus<SysMenuMapper, SysMenu, Sy
*/ */
List<String> selectMenuPermsByUserId(Long userId); List<String> selectMenuPermsByUserId(Long userId);
/**
* 根据角色ID查询权限
*
* @param roleId 角色ID
* @return 权限列表
*/
List<String> selectMenuPermsByRoleId(Long roleId);
/** /**
* 根据用户ID查询菜单 * 根据用户ID查询菜单
* *

View File

@ -19,6 +19,14 @@ public interface ISysDeptService {
*/ */
List<SysDept> selectDeptList(SysDept dept); List<SysDept> selectDeptList(SysDept dept);
/**
* 查询部门树结构信息
*
* @param dept 部门信息
* @return 部门树信息集合
*/
List<Tree<Long>> selectDeptTreeList(SysDept dept);
/** /**
* 构建前端所需要下拉树结构 * 构建前端所需要下拉树结构
* *

View File

@ -39,6 +39,14 @@ public interface ISysMenuService {
*/ */
Set<String> selectMenuPermsByUserId(Long userId); Set<String> selectMenuPermsByUserId(Long userId);
/**
* 根据角色ID查询权限
*
* @param roleId 角色ID
* @return 权限列表
*/
Set<String> selectMenuPermsByRoleId(Long roleId);
/** /**
* 根据用户ID查询菜单树信息 * 根据用户ID查询菜单树信息
* *

View File

@ -1,10 +1,12 @@
package com.ruoyi.system.service; package com.ruoyi.system.service;
import com.ruoyi.common.core.domain.entity.SysRole;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
@ -47,9 +49,19 @@ public class SysPermissionService {
// 管理员拥有所有权限 // 管理员拥有所有权限
if (user.isAdmin()) { if (user.isAdmin()) {
perms.add("*:*:*"); perms.add("*:*:*");
} else {
List<SysRole> roles = user.getRoles();
if (!roles.isEmpty() && roles.size() > 1) {
// 多角色设置permissions属性以便数据权限匹配权限
for (SysRole role : roles) {
Set<String> rolePerms = menuService.selectMenuPermsByRoleId(role.getRoleId());
role.setPermissions(rolePerms);
perms.addAll(rolePerms);
}
} else { } else {
perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId())); perms.addAll(menuService.selectMenuPermsByUserId(user.getUserId()));
} }
}
return perms; return perms;
} }
} }

View File

@ -58,6 +58,18 @@ public class SysDeptServiceImpl implements ISysDeptService {
return baseMapper.selectDeptList(lqw); return baseMapper.selectDeptList(lqw);
} }
/**
* 查询部门树结构信息
*
* @param dept 部门信息
* @return 部门树信息集合
*/
@Override
public List<Tree<Long>> selectDeptTreeList(SysDept dept) {
List<SysDept> depts = this.selectDeptList(dept);
return buildDeptTreeSelect(depts);
}
/** /**
* 构建前端所需要下拉树结构 * 构建前端所需要下拉树结构
* *
@ -96,7 +108,11 @@ public class SysDeptServiceImpl implements ISysDeptService {
*/ */
@Override @Override
public SysDept selectDeptById(Long deptId) { public SysDept selectDeptById(Long deptId) {
return baseMapper.selectById(deptId); SysDept dept = baseMapper.selectById(deptId);
SysDept parentDept = baseMapper.selectOne(new LambdaQueryWrapper<SysDept>()
.select(SysDept::getDeptName).eq(SysDept::getDeptId, dept.getParentId()));
dept.setParentName(ObjectUtil.isNotNull(parentDept) ? parentDept.getDeptName() : null);
return dept;
} }
/** /**

View File

@ -97,6 +97,24 @@ public class SysMenuServiceImpl implements ISysMenuService {
return permsSet; return permsSet;
} }
/**
* 根据角色ID查询权限
*
* @param roleId 角色ID
* @return 权限列表
*/
@Override
public Set<String> selectMenuPermsByRoleId(Long roleId) {
List<String> perms = baseMapper.selectMenuPermsByRoleId(roleId);
Set<String> permsSet = new HashSet<>();
for (String perm : perms) {
if (StringUtils.isNotEmpty(perm)) {
permsSet.addAll(Arrays.asList(perm.trim().split(",")));
}
}
return permsSet;
}
/** /**
* 根据用户ID查询菜单 * 根据用户ID查询菜单
* *
@ -429,7 +447,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
* @return * @return
*/ */
public String innerLinkReplaceEach(String path) { public String innerLinkReplaceEach(String path) {
return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS}, return StringUtils.replaceEach(path, new String[]{Constants.HTTP, Constants.HTTPS, Constants.WWW, "." },
new String[]{"", ""}); new String[]{"", ""});
} }
} }

View File

@ -95,4 +95,11 @@
and sur.user_id = #{userId} and sur.user_id = #{userId}
</select> </select>
<select id="selectMenuPermsByRoleId" parameterType="Long" resultType="String">
select distinct m.perms
from sys_menu m
left join sys_role_menu rm on m.menu_id = rm.menu_id
where m.status = '0' and rm.role_id = #{roleId}
</select>
</mapper> </mapper>

View File

@ -1,6 +1,6 @@
{ {
"name": "ruoyi-vue-plus", "name": "ruoyi-vue-plus",
"version": "4.3.0-beta2", "version": "4.3.0",
"description": "RuoYi-Vue-Plus后台管理系统", "description": "RuoYi-Vue-Plus后台管理系统",
"author": "LionLi", "author": "LionLi",
"license": "MIT", "license": "MIT",

View File

@ -25,22 +25,6 @@ export function getDept(deptId) {
}) })
} }
// 查询部门下拉树结构
export function treeselect() {
return request({
url: '/system/dept/treeselect',
method: 'get'
})
}
// 根据角色ID查询部门树结构
export function roleDeptTreeselect(roleId) {
return request({
url: '/system/dept/roleDeptTreeselect/' + roleId,
method: 'get'
})
}
// 新增部门 // 新增部门
export function addDept(data) { export function addDept(data) {
return request({ return request({

View File

@ -43,7 +43,7 @@ export function delOssConfig(ossConfigId) {
}) })
} }
// 用户状态修改 // 对象存储状态修改
export function changeOssConfigStatus(ossConfigId, status, configKey) { export function changeOssConfigStatus(ossConfigId, status, configKey) {
const data = { const data = {
ossConfigId, ossConfigId,

View File

@ -109,3 +109,11 @@ export function authUserSelectAll(data) {
params: data params: data
}) })
} }
// 根据角色ID查询部门树结构
export function deptTreeSelect(roleId) {
return request({
url: '/system/role/deptTree/' + roleId,
method: 'get'
})
}

View File

@ -125,3 +125,11 @@ export function updateAuthRole(data) {
params: data params: data
}) })
} }
// 查询部门下拉树结构
export function deptTreeSelect() {
return request({
url: '/system/user/deptTree',
method: 'get'
})
}

View File

@ -12,11 +12,16 @@
} }
/* fade-transform */ /* fade-transform */
.fade-transform--move,
.fade-transform-leave-active, .fade-transform-leave-active,
.fade-transform-enter-active { .fade-transform-enter-active {
transition: all .5s; transition: all .5s;
} }
.fade-transform-leave-active {
position: absolute;
}
.fade-transform-enter { .fade-transform-enter {
opacity: 0; opacity: 0;
transform: translateX(-30px); transform: translateX(-30px);

View File

@ -12,7 +12,7 @@
:show-file-list="false" :show-file-list="false"
:headers="headers" :headers="headers"
class="upload-file-uploader" class="upload-file-uploader"
ref="upload" ref="fileUpload"
> >
<!-- 上传按钮 --> <!-- 上传按钮 -->
<el-button size="mini" type="primary">选取文件</el-button> <el-button size="mini" type="primary">选取文件</el-button>
@ -157,22 +157,19 @@ export default {
// //
handleUploadError(err) { handleUploadError(err) {
this.$modal.msgError("上传图片失败,请重试"); this.$modal.msgError("上传图片失败,请重试");
this.$modal.closeLoading() this.$modal.closeLoading();
}, },
// //
handleUploadSuccess(res, file) { handleUploadSuccess(res, file) {
if (res.code === 200) { if (res.code === 200) {
this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId }); this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
if (this.uploadList.length === this.number) { this.uploadedSuccessfully();
this.fileList = this.fileList.concat(this.uploadList);
this.uploadList = [];
this.number = 0;
this.$emit("input", this.listToString(this.fileList));
this.$modal.closeLoading();
}
} else { } else {
this.$modal.msgError(res.msg); this.number--;
this.$modal.closeLoading(); this.$modal.closeLoading();
this.$modal.msgError(res.msg);
this.$refs.fileUpload.handleRemove(file);
this.uploadedSuccessfully();
} }
}, },
// //
@ -182,6 +179,16 @@ export default {
this.fileList.splice(index, 1); this.fileList.splice(index, 1);
this.$emit("input", this.listToString(this.fileList)); this.$emit("input", this.listToString(this.fileList));
}, },
//
uploadedSuccessfully() {
if (this.number > 0 && this.uploadList.length === this.number) {
this.fileList = this.fileList.concat(this.uploadList);
this.uploadList = [];
this.number = 0;
this.$emit("input", this.listToString(this.fileList));
this.$modal.closeLoading();
}
},
// //
getFileName(name) { getFileName(name) {
// url // url

View File

@ -18,7 +18,7 @@ export default {
props: { props: {
src: { src: {
type: String, type: String,
required: true default: ""
}, },
width: { width: {
type: [Number, String], type: [Number, String],
@ -31,10 +31,16 @@ export default {
}, },
computed: { computed: {
realSrc() { realSrc() {
if (!this.src) {
return;
}
let real_src = this.src.split(",")[0]; let real_src = this.src.split(",")[0];
return real_src; return real_src;
}, },
realSrcList() { realSrcList() {
if (!this.src) {
return;
}
let real_src_list = this.src.split(","); let real_src_list = this.src.split(",");
let srcList = []; let srcList = [];
real_src_list.forEach(item => { real_src_list.forEach(item => {

View File

@ -9,8 +9,8 @@
:limit="limit" :limit="limit"
:on-error="handleUploadError" :on-error="handleUploadError"
:on-exceed="handleExceed" :on-exceed="handleExceed"
name="file" ref="imageUpload"
:on-remove="handleRemove" :on-remove="handleDelete"
:show-file-list="true" :show-file-list="true"
:headers="headers" :headers="headers"
:file-list="fileList" :file-list="fileList"
@ -120,32 +120,6 @@ export default {
}, },
}, },
methods: { methods: {
//
handleRemove(file, fileList) {
const findex = this.fileList.map(f => f.name).indexOf(file.name);
if(findex > -1) {
let ossId = this.fileList[findex].ossId;
delOss(ossId);
this.fileList.splice(findex, 1);
this.$emit("input", this.listToString(this.fileList));
}
},
//
handleUploadSuccess(res) {
if (res.code == 200) {
this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
if (this.uploadList.length === this.number) {
this.fileList = this.fileList.concat(this.uploadList);
this.uploadList = [];
this.number = 0;
this.$emit("input", this.listToString(this.fileList));
this.$modal.closeLoading();
}
} else {
this.$modal.msgError(res.msg);
this.$modal.closeLoading();
}
},
// loading // loading
handleBeforeUpload(file) { handleBeforeUpload(file) {
let isImg = false; let isImg = false;
@ -181,11 +155,44 @@ export default {
handleExceed() { handleExceed() {
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`); this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
}, },
//
handleUploadSuccess(res, file) {
if (res.code === 200) {
this.uploadList.push({ name: res.data.fileName, url: res.data.url, ossId: res.data.ossId });
this.uploadedSuccessfully();
} else {
this.number--;
this.$modal.closeLoading();
this.$modal.msgError(res.msg);
this.$refs.imageUpload.handleRemove(file);
this.uploadedSuccessfully();
}
},
//
handleDelete(file) {
const findex = this.fileList.map(f => f.name).indexOf(file.name);
if(findex > -1) {
let ossId = this.fileList[findex].ossId;
delOss(ossId);
this.fileList.splice(findex, 1);
this.$emit("input", this.listToString(this.fileList));
}
},
// //
handleUploadError(res) { handleUploadError(res) {
this.$modal.msgError("上传图片失败,请重试"); this.$modal.msgError("上传图片失败,请重试");
this.$modal.closeLoading(); this.$modal.closeLoading();
}, },
//
uploadedSuccessfully() {
if (this.number > 0 && this.uploadList.length === this.number) {
this.fileList = this.fileList.concat(this.uploadList);
this.uploadList = [];
this.number = 0;
this.$emit("input", this.listToString(this.fileList));
this.$modal.closeLoading();
}
},
// //
handlePictureCardPreview(file) { handlePictureCardPreview(file) {
this.dialogImageUrl = file.url; this.dialogImageUrl = file.url;
@ -196,10 +203,12 @@ export default {
let strs = ""; let strs = "";
separator = separator || ","; separator = separator || ",";
for (let i in list) { for (let i in list) {
if (list[i].ossId) {
strs += list[i].ossId + separator; strs += list[i].ossId + separator;
} }
}
return strs != "" ? strs.substr(0, strs.length - 1) : ""; return strs != "" ? strs.substr(0, strs.length - 1) : "";
}, }
} }
}; };
</script> </script>

View File

@ -2,15 +2,19 @@
<section class="app-main"> <section class="app-main">
<transition name="fade-transform" mode="out-in"> <transition name="fade-transform" mode="out-in">
<keep-alive :include="cachedViews"> <keep-alive :include="cachedViews">
<router-view :key="key" /> <router-view v-if="!$route.meta.link" :key="key" />
</keep-alive> </keep-alive>
</transition> </transition>
<iframe-toggle />
</section> </section>
</template> </template>
<script> <script>
import iframeToggle from "./IframeToggle/index"
export default { export default {
name: 'AppMain', name: 'AppMain',
components: { iframeToggle },
computed: { computed: {
cachedViews() { cachedViews() {
return this.$store.state.tagsView.cachedViews return this.$store.state.tagsView.cachedViews
@ -31,7 +35,7 @@ export default {
overflow: hidden; overflow: hidden;
} }
.fixed-header+.app-main { .fixed-header + .app-main {
padding-top: 50px; padding-top: 50px;
} }
@ -41,7 +45,7 @@ export default {
min-height: calc(100vh - 84px); min-height: calc(100vh - 84px);
} }
.fixed-header+.app-main { .fixed-header + .app-main {
padding-top: 84px; padding-top: 84px;
} }
} }

View File

@ -0,0 +1,24 @@
<template>
<transition-group name="fade-transform" mode="out-in">
<inner-link
v-for="(item, index) in iframeViews"
:key="item.path"
:iframeId="'iframe' + index"
v-show="$route.path === item.path"
:src="item.meta.link"
></inner-link>
</transition-group>
</template>
<script>
import InnerLink from "../InnerLink/index"
export default {
components: { InnerLink },
computed: {
iframeViews() {
return this.$store.state.tagsView.iframeViews
}
}
}
</script>

View File

@ -1,27 +1,47 @@
<script> <template>
export default { <div :style="'height:' + height" v-loading="loading" element-loading-text="正在加载页面,请稍候!">
data() {
return {};
},
render() {
const { $route: { meta: { link } }, } = this;
if ({ link }.link === "") {
return "404";
}
let url = { link }.link;
const height = document.documentElement.clientHeight - 94.5 + "px";
const style = { height: height };
return (
<div style={style}>
<iframe <iframe
src={url} :id="iframeId"
frameborder="no"
style="width: 100%; height: 100%" style="width: 100%; height: 100%"
scrolling="auto" :src="src"
frameborder="no"
></iframe> ></iframe>
</div> </div>
); </template>
<script>
export default {
props: {
src: {
type: String,
default: "/"
}, },
iframeId: {
type: String
}
},
data() {
return {
loading: false,
height: document.documentElement.clientHeight - 94.5 + "px;"
};
},
mounted() {
var _this = this;
const iframeId = ("#" + this.iframeId).replace(/\//g, "\\/");
const iframe = document.querySelector(iframeId);
// iframeloading
if (iframe.attachEvent) {
this.loading = true;
iframe.attachEvent("onload", function () {
_this.loading = false;
});
} else {
this.loading = true;
iframe.onload = function () {
_this.loading = false;
};
}
}
}; };
</script> </script>

View File

@ -133,6 +133,9 @@ export default {
const { name } = this.$route const { name } = this.$route
if (name) { if (name) {
this.$store.dispatch('tagsView/addView', this.$route) this.$store.dispatch('tagsView/addView', this.$route)
if (this.$route.meta.link) {
this.$store.dispatch('tagsView/addIframeView', this.$route)
}
} }
return false return false
}, },
@ -153,6 +156,9 @@ export default {
}, },
refreshSelectedTag(view) { refreshSelectedTag(view) {
this.$tab.refreshPage(view); this.$tab.refreshPage(view);
if (this.$route.meta.link) {
this.$store.dispatch('tagsView/delIframeView', this.$route)
}
}, },
closeSelectedTag(view) { closeSelectedTag(view) {
this.$tab.closePage(view).then(({ visitedViews }) => { this.$tab.closePage(view).then(({ visitedViews }) => {

View File

@ -1,9 +1,18 @@
const state = { const state = {
visitedViews: [], visitedViews: [],
cachedViews: [] cachedViews: [],
iframeViews: []
} }
const mutations = { const mutations = {
ADD_IFRAME_VIEW: (state, view) => {
if (state.iframeViews.some(v => v.path === view.path)) return
state.iframeViews.push(
Object.assign({}, view, {
title: view.meta.title || 'no-name'
})
)
},
ADD_VISITED_VIEW: (state, view) => { ADD_VISITED_VIEW: (state, view) => {
if (state.visitedViews.some(v => v.path === view.path)) return if (state.visitedViews.some(v => v.path === view.path)) return
state.visitedViews.push( state.visitedViews.push(
@ -18,7 +27,6 @@ const mutations = {
state.cachedViews.push(view.name) state.cachedViews.push(view.name)
} }
}, },
DEL_VISITED_VIEW: (state, view) => { DEL_VISITED_VIEW: (state, view) => {
for (const [i, v] of state.visitedViews.entries()) { for (const [i, v] of state.visitedViews.entries()) {
if (v.path === view.path) { if (v.path === view.path) {
@ -26,6 +34,10 @@ const mutations = {
break break
} }
} }
state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
},
DEL_IFRAME_VIEW: (state, view) => {
state.iframeViews = state.iframeViews.filter(item => item.path !== view.path)
}, },
DEL_CACHED_VIEW: (state, view) => { DEL_CACHED_VIEW: (state, view) => {
const index = state.cachedViews.indexOf(view.name) const index = state.cachedViews.indexOf(view.name)
@ -36,6 +48,7 @@ const mutations = {
state.visitedViews = state.visitedViews.filter(v => { state.visitedViews = state.visitedViews.filter(v => {
return v.meta.affix || v.path === view.path return v.meta.affix || v.path === view.path
}) })
state.iframeViews = state.iframeViews.filter(item => item.path === view.path)
}, },
DEL_OTHERS_CACHED_VIEWS: (state, view) => { DEL_OTHERS_CACHED_VIEWS: (state, view) => {
const index = state.cachedViews.indexOf(view.name) const index = state.cachedViews.indexOf(view.name)
@ -45,16 +58,15 @@ const mutations = {
state.cachedViews = [] state.cachedViews = []
} }
}, },
DEL_ALL_VISITED_VIEWS: state => { DEL_ALL_VISITED_VIEWS: state => {
// keep affix tags // keep affix tags
const affixTags = state.visitedViews.filter(tag => tag.meta.affix) const affixTags = state.visitedViews.filter(tag => tag.meta.affix)
state.visitedViews = affixTags state.visitedViews = affixTags
state.iframeViews = []
}, },
DEL_ALL_CACHED_VIEWS: state => { DEL_ALL_CACHED_VIEWS: state => {
state.cachedViews = [] state.cachedViews = []
}, },
UPDATE_VISITED_VIEW: (state, view) => { UPDATE_VISITED_VIEW: (state, view) => {
for (let v of state.visitedViews) { for (let v of state.visitedViews) {
if (v.path === view.path) { if (v.path === view.path) {
@ -63,7 +75,6 @@ const mutations = {
} }
} }
}, },
DEL_RIGHT_VIEWS: (state, view) => { DEL_RIGHT_VIEWS: (state, view) => {
const index = state.visitedViews.findIndex(v => v.path === view.path) const index = state.visitedViews.findIndex(v => v.path === view.path)
if (index === -1) { if (index === -1) {
@ -77,10 +88,13 @@ const mutations = {
if (i > -1) { if (i > -1) {
state.cachedViews.splice(i, 1) state.cachedViews.splice(i, 1)
} }
if(item.meta.link) {
const fi = state.iframeViews.findIndex(v => v.path === item.path)
state.iframeViews.splice(fi, 1)
}
return false return false
}) })
}, },
DEL_LEFT_VIEWS: (state, view) => { DEL_LEFT_VIEWS: (state, view) => {
const index = state.visitedViews.findIndex(v => v.path === view.path) const index = state.visitedViews.findIndex(v => v.path === view.path)
if (index === -1) { if (index === -1) {
@ -94,6 +108,10 @@ const mutations = {
if (i > -1) { if (i > -1) {
state.cachedViews.splice(i, 1) state.cachedViews.splice(i, 1)
} }
if(item.meta.link) {
const fi = state.iframeViews.findIndex(v => v.path === item.path)
state.iframeViews.splice(fi, 1)
}
return false return false
}) })
} }
@ -104,13 +122,15 @@ const actions = {
dispatch('addVisitedView', view) dispatch('addVisitedView', view)
dispatch('addCachedView', view) dispatch('addCachedView', view)
}, },
addIframeView({ commit }, view) {
commit('ADD_IFRAME_VIEW', view)
},
addVisitedView({ commit }, view) { addVisitedView({ commit }, view) {
commit('ADD_VISITED_VIEW', view) commit('ADD_VISITED_VIEW', view)
}, },
addCachedView({ commit }, view) { addCachedView({ commit }, view) {
commit('ADD_CACHED_VIEW', view) commit('ADD_CACHED_VIEW', view)
}, },
delView({ dispatch, state }, view) { delView({ dispatch, state }, view) {
return new Promise(resolve => { return new Promise(resolve => {
dispatch('delVisitedView', view) dispatch('delVisitedView', view)
@ -127,13 +147,18 @@ const actions = {
resolve([...state.visitedViews]) resolve([...state.visitedViews])
}) })
}, },
delIframeView({ commit, state }, view) {
return new Promise(resolve => {
commit('DEL_IFRAME_VIEW', view)
resolve([...state.iframeViews])
})
},
delCachedView({ commit, state }, view) { delCachedView({ commit, state }, view) {
return new Promise(resolve => { return new Promise(resolve => {
commit('DEL_CACHED_VIEW', view) commit('DEL_CACHED_VIEW', view)
resolve([...state.cachedViews]) resolve([...state.cachedViews])
}) })
}, },
delOthersViews({ dispatch, state }, view) { delOthersViews({ dispatch, state }, view) {
return new Promise(resolve => { return new Promise(resolve => {
dispatch('delOthersVisitedViews', view) dispatch('delOthersVisitedViews', view)
@ -156,7 +181,6 @@ const actions = {
resolve([...state.cachedViews]) resolve([...state.cachedViews])
}) })
}, },
delAllViews({ dispatch, state }, view) { delAllViews({ dispatch, state }, view) {
return new Promise(resolve => { return new Promise(resolve => {
dispatch('delAllVisitedViews', view) dispatch('delAllVisitedViews', view)
@ -179,18 +203,15 @@ const actions = {
resolve([...state.cachedViews]) resolve([...state.cachedViews])
}) })
}, },
updateVisitedView({ commit }, view) { updateVisitedView({ commit }, view) {
commit('UPDATE_VISITED_VIEW', view) commit('UPDATE_VISITED_VIEW', view)
}, },
delRightTags({ commit }, view) { delRightTags({ commit }, view) {
return new Promise(resolve => { return new Promise(resolve => {
commit('DEL_RIGHT_VIEWS', view) commit('DEL_RIGHT_VIEWS', view)
resolve([...state.visitedViews]) resolve([...state.visitedViews])
}) })
}, },
delLeftTags({ commit }, view) { delLeftTags({ commit }, view) {
return new Promise(resolve => { return new Promise(resolve => {
commit('DEL_LEFT_VIEWS', view) commit('DEL_LEFT_VIEWS', view)

View File

@ -114,7 +114,7 @@ export default {
data() { data() {
return { return {
// //
version: "4.3.0-beta2", version: "4.3.0",
}; };
}, },
methods: { methods: {

View File

@ -297,9 +297,13 @@ export default {
this.form = response.data; this.form = response.data;
this.open = true; this.open = true;
this.title = "修改部门"; this.title = "修改部门";
});
listDeptExcludeChild(row.deptId).then(response => { listDeptExcludeChild(row.deptId).then(response => {
this.deptOptions = this.handleTree(response.data, "deptId"); this.deptOptions = this.handleTree(response.data, "deptId");
if (this.deptOptions.length == 0) {
const noResultsOptions = { deptId: this.form.parentId, deptName: this.form.parentName, children: [] };
this.deptOptions.push(noResultsOptions);
}
});
}); });
}, },
/** 提交按钮 */ /** 提交按钮 */

View File

@ -107,7 +107,7 @@
<el-form ref="form" :model="form" :rules="rules" label-width="100px"> <el-form ref="form" :model="form" :rules="rules" label-width="100px">
<el-row> <el-row>
<el-col :span="24"> <el-col :span="24">
<el-form-item label="上级菜单"> <el-form-item label="上级菜单" prop="parentId">
<treeselect <treeselect
v-model="form.parentId" v-model="form.parentId"
:options="menuOptions" :options="menuOptions"
@ -159,7 +159,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="form.menuType != 'F'"> <el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item> <el-form-item prop="isFrame">
<span slot="label"> <span slot="label">
<el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top"> <el-tooltip content="选择是外链则路由地址需要以`http(s)://`开头" placement="top">
<i class="el-icon-question"></i> <i class="el-icon-question"></i>
@ -195,7 +195,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="form.menuType != 'M'"> <el-col :span="12" v-if="form.menuType != 'M'">
<el-form-item> <el-form-item prop="perms">
<el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" /> <el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" />
<span slot="label"> <span slot="label">
<el-tooltip content="控制器中定义的权限字符,如:@SaCheckPermission('system:user:list')" placement="top"> <el-tooltip content="控制器中定义的权限字符,如:@SaCheckPermission('system:user:list')" placement="top">
@ -206,7 +206,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="form.menuType == 'C'"> <el-col :span="12" v-if="form.menuType == 'C'">
<el-form-item> <el-form-item prop="queryParam">
<el-input v-model="form.queryParam" placeholder="请输入路由参数" maxlength="255" /> <el-input v-model="form.queryParam" placeholder="请输入路由参数" maxlength="255" />
<span slot="label"> <span slot="label">
<el-tooltip content='访问路由的默认传递参数,如:`{"id": 1, "name": "ry"}`' placement="top"> <el-tooltip content='访问路由的默认传递参数,如:`{"id": 1, "name": "ry"}`' placement="top">
@ -217,7 +217,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="form.menuType == 'C'"> <el-col :span="12" v-if="form.menuType == 'C'">
<el-form-item> <el-form-item prop="isCache">
<span slot="label"> <span slot="label">
<el-tooltip content="选择是则会被`keep-alive`缓存,需要匹配组件的`name`和地址保持一致" placement="top"> <el-tooltip content="选择是则会被`keep-alive`缓存,需要匹配组件的`name`和地址保持一致" placement="top">
<i class="el-icon-question"></i> <i class="el-icon-question"></i>
@ -231,7 +231,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="form.menuType != 'F'"> <el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item> <el-form-item prop="visible">
<span slot="label"> <span slot="label">
<el-tooltip content="选择隐藏则路由将不会出现在侧边栏,但仍然可以访问" placement="top"> <el-tooltip content="选择隐藏则路由将不会出现在侧边栏,但仍然可以访问" placement="top">
<i class="el-icon-question"></i> <i class="el-icon-question"></i>
@ -248,7 +248,7 @@
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="form.menuType != 'F'"> <el-col :span="12" v-if="form.menuType != 'F'">
<el-form-item> <el-form-item prop="status">
<span slot="label"> <span slot="label">
<el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top"> <el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top">
<i class="el-icon-question"></i> <i class="el-icon-question"></i>

View File

@ -254,9 +254,8 @@
</template> </template>
<script> <script>
import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus } from "@/api/system/role"; import { listRole, getRole, delRole, addRole, updateRole, dataScope, changeRoleStatus, deptTreeSelect } from "@/api/system/role";
import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu"; import { treeselect as menuTreeselect, roleMenuTreeselect } from "@/api/system/menu";
import { treeselect as deptTreeselect, roleDeptTreeselect } from "@/api/system/dept";
export default { export default {
name: "Role", name: "Role",
@ -364,12 +363,6 @@ export default {
this.menuOptions = response.data; this.menuOptions = response.data;
}); });
}, },
/** 查询部门树结构 */
getDeptTreeselect() {
deptTreeselect().then(response => {
this.deptOptions = response.data;
});
},
// //
getMenuAllCheckedKeys() { getMenuAllCheckedKeys() {
// //
@ -396,8 +389,8 @@ export default {
}); });
}, },
/** 根据角色ID查询部门树结构 */ /** 根据角色ID查询部门树结构 */
getRoleDeptTreeselect(roleId) { getDeptTree(roleId) {
return roleDeptTreeselect(roleId).then(response => { return deptTreeSelect(roleId).then(response => {
this.deptOptions = response.data.depts; this.deptOptions = response.data.depts;
return response; return response;
}); });
@ -543,12 +536,12 @@ export default {
/** 分配数据权限操作 */ /** 分配数据权限操作 */
handleDataScope(row) { handleDataScope(row) {
this.reset(); this.reset();
const roleDeptTreeselect = this.getRoleDeptTreeselect(row.roleId); const deptTreeSelect = this.getDeptTree(row.roleId);
getRole(row.roleId).then(response => { getRole(row.roleId).then(response => {
this.form = response.data; this.form = response.data;
this.openDataScope = true; this.openDataScope = true;
this.$nextTick(() => { this.$nextTick(() => {
roleDeptTreeselect.then(res => { deptTreeSelect.then(res => {
this.$refs.dept.setCheckedKeys(res.data.checkedKeys); this.$refs.dept.setCheckedKeys(res.data.checkedKeys);
}); });
}); });
@ -612,3 +605,4 @@ export default {
} }
}; };
</script> </script>

View File

@ -342,9 +342,8 @@
</template> </template>
<script> <script>
import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus } from "@/api/system/user"; import { listUser, getUser, delUser, addUser, updateUser, resetUserPwd, changeUserStatus, deptTreeSelect } from "@/api/system/user";
import { getToken } from "@/utils/auth"; import { getToken } from "@/utils/auth";
import { treeselect } from "@/api/system/dept";
import Treeselect from "@riophae/vue-treeselect"; import Treeselect from "@riophae/vue-treeselect";
import "@riophae/vue-treeselect/dist/vue-treeselect.css"; import "@riophae/vue-treeselect/dist/vue-treeselect.css";
@ -462,7 +461,7 @@ export default {
}, },
created() { created() {
this.getList(); this.getList();
this.getTreeselect(); this.getDeptTree();
this.getConfigKey("sys.user.initPassword").then(response => { this.getConfigKey("sys.user.initPassword").then(response => {
this.initPassword = response.msg; this.initPassword = response.msg;
}); });
@ -479,8 +478,8 @@ export default {
); );
}, },
/** 查询部门下拉树结构 */ /** 查询部门下拉树结构 */
getTreeselect() { getDeptTree() {
treeselect().then(response => { deptTreeSelect().then(response => {
this.deptOptions = response.data; this.deptOptions = response.data;
}); });
}, },
@ -561,7 +560,6 @@ export default {
/** 新增按钮操作 */ /** 新增按钮操作 */
handleAdd() { handleAdd() {
this.reset(); this.reset();
this.getTreeselect();
getUser().then(response => { getUser().then(response => {
this.postOptions = response.data.posts; this.postOptions = response.data.posts;
this.roleOptions = response.data.roles; this.roleOptions = response.data.roles;
@ -573,7 +571,6 @@ export default {
/** 修改按钮操作 */ /** 修改按钮操作 */
handleUpdate(row) { handleUpdate(row) {
this.reset(); this.reset();
this.getTreeselect();
const userId = row.userId || this.ids; const userId = row.userId || this.ids;
getUser(userId).then(response => { getUser(userId).then(response => {
this.form = response.data.user; this.form = response.data.user;

View File

@ -49,7 +49,7 @@
<userInfo :user="user" /> <userInfo :user="user" />
</el-tab-pane> </el-tab-pane>
<el-tab-pane label="修改密码" name="resetPwd"> <el-tab-pane label="修改密码" name="resetPwd">
<resetPwd :user="user" /> <resetPwd />
</el-tab-pane> </el-tab-pane>
</el-tabs> </el-tabs>
</el-card> </el-card>

View File

@ -1,109 +0,0 @@
#!/bin/bash
#使用说明,用来提示输入参数
usage() {
echo "Usage: sh 执行脚本.sh [port|mount|monitor|base|start|stop|stopall|rm|rmiNoneTag]"
exit 1
}
#开启所需端口(生产环境不推荐开启)
port(){
# mysql 端口
firewall-cmd --add-port=3306/tcp --permanent
# redis 端口
firewall-cmd --add-port=6379/tcp --permanent
# minio api 端口
firewall-cmd --add-port=9000/tcp --permanent
# minio 控制台端口
firewall-cmd --add-port=9001/tcp --permanent
# 监控中心端口
firewall-cmd --add-port=9090/tcp --permanent
# 任务调度中心端口
firewall-cmd --add-port=9100/tcp --permanent
# 重启防火墙
service firewalld restart
}
##放置挂载文件
mount(){
#挂载 nginx 配置文件
if test ! -f "/docker/nginx/" ;then
mkdir -p /docker/nginx/
cp -r nginx/* /docker/nginx/
fi
#挂载 redis 配置文件
if test ! -f "/docker/redis/" ;then
mkdir -p /docker/redis/
cp -r redis/* /docker/redis/
fi
chmod -R 777 /docker
}
#启动基础模块
base(){
docker-compose up -d mysql nginx-web redis minio
}
#启动监控模块
monitor(){
docker-compose up -d ruoyi-monitor-admin
}
#启动程序模块
start(){
docker-compose up -d ruoyi-xxl-job-admin ruoyi-server1 ruoyi-server2
}
#停止程序模块
stop(){
docker-compose stop ruoyi-xxl-job-admin ruoyi-server1 ruoyi-server2
}
#关闭所有模块
stopall(){
docker-compose stop
}
#删除所有模块
rm(){
docker-compose rm
}
#删除Tag为空的镜像
rmiNoneTag(){
docker images|grep none|awk '{print $3}'|xargs docker rmi -f
}
#根据输入参数,选择执行对应方法,不输入则执行使用说明
case "$1" in
"port")
port
;;
"mount")
mount
;;
"base")
base
;;
"monitor")
monitor
;;
"start")
start
;;
"stop")
stop
;;
"stopall")
stopall
;;
"rm")
rm
;;
"rmiNoneTag")
rmiNoneTag
;;
*)
usage
;;
esac

View File

@ -82,7 +82,8 @@ services:
# 管理后台密码最小8个字符 # 管理后台密码最小8个字符
MINIO_SECRET_KEY: ruoyi123 MINIO_SECRET_KEY: ruoyi123
# https需要指定域名 # https需要指定域名
MINIO_SERVER_URL: "" #MINIO_SERVER_URL: "https://xxx.com:9000"
#MINIO_BROWSER_REDIRECT_URL: "https://xxx.com:9001"
# 开启压缩 on 开启 off 关闭 # 开启压缩 on 开启 off 关闭
MINIO_COMPRESS: "off" MINIO_COMPRESS: "off"
# 扩展名 .pdf,.doc 为空 所有类型均压缩 # 扩展名 .pdf,.doc 为空 所有类型均压缩
@ -99,7 +100,7 @@ services:
network_mode: "host" network_mode: "host"
ruoyi-server1: ruoyi-server1:
image: ruoyi/ruoyi-server:4.3.0-beta2 image: ruoyi/ruoyi-server:4.3.0
container_name: ruoyi-server1 container_name: ruoyi-server1
environment: environment:
# 时区上海 # 时区上海
@ -112,7 +113,7 @@ services:
network_mode: "host" network_mode: "host"
ruoyi-server2: ruoyi-server2:
image: "ruoyi/ruoyi-server:4.3.0-beta2" image: "ruoyi/ruoyi-server:4.3.0"
container_name: ruoyi-server2 container_name: ruoyi-server2
environment: environment:
# 时区上海 # 时区上海
@ -125,7 +126,7 @@ services:
network_mode: "host" network_mode: "host"
ruoyi-monitor-admin: ruoyi-monitor-admin:
image: ruoyi/ruoyi-monitor-admin:4.3.0-beta2 image: ruoyi/ruoyi-monitor-admin:4.3.0
container_name: ruoyi-monitor-admin container_name: ruoyi-monitor-admin
environment: environment:
# 时区上海 # 时区上海
@ -137,7 +138,7 @@ services:
network_mode: "host" network_mode: "host"
ruoyi-xxl-job-admin: ruoyi-xxl-job-admin:
image: ruoyi/ruoyi-xxl-job-admin:4.3.0-beta2 image: ruoyi/ruoyi-xxl-job-admin:4.3.0
container_name: ruoyi-xxl-job-admin container_name: ruoyi-xxl-job-admin
environment: environment:
# 时区上海 # 时区上海

View File

@ -228,7 +228,7 @@ comment on column sys_menu.query_param is '路由参数';
comment on column sys_menu.is_frame is '是否为外链0是 1否'; comment on column sys_menu.is_frame is '是否为外链0是 1否';
comment on column sys_menu.is_cache is '是否缓存0缓存 1不缓存'; comment on column sys_menu.is_cache is '是否缓存0缓存 1不缓存';
comment on column sys_menu.menu_type is '菜单类型M目录 C菜单 F按钮'; comment on column sys_menu.menu_type is '菜单类型M目录 C菜单 F按钮';
comment on column sys_menu.visible is '菜单状态0显示 1隐藏'; comment on column sys_menu.visible is '显示状态0显示 1隐藏';
comment on column sys_menu.status is '菜单状态0正常 1停用'; comment on column sys_menu.status is '菜单状态0正常 1停用';
comment on column sys_menu.perms is '权限标识'; comment on column sys_menu.perms is '权限标识';
comment on column sys_menu.icon is '菜单图标'; comment on column sys_menu.icon is '菜单图标';
@ -642,6 +642,7 @@ insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_ty
insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate, '', null, '公告'); insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate, '', null, '公告');
insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '正常状态'); insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate, '', null, '正常状态');
insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '关闭状态'); insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '关闭状态');
insert into sys_dict_data values(29, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate, '', null, '其他操作');
insert into sys_dict_data values(18, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate, '', null, '新增操作'); insert into sys_dict_data values(18, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate, '', null, '新增操作');
insert into sys_dict_data values(19, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate, '', null, '修改操作'); insert into sys_dict_data values(19, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate, '', null, '修改操作');
insert into sys_dict_data values(20, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '删除操作'); insert into sys_dict_data values(20, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate, '', null, '删除操作');
@ -873,7 +874,7 @@ create table sys_oss (
original_name varchar(255) not null, original_name varchar(255) not null,
file_suffix varchar(10) not null, file_suffix varchar(10) not null,
url varchar(500) not null, url varchar(500) not null,
service varchar(10) default 'minio' not null, service varchar(20) default 'minio' not null,
create_by varchar(64) default '', create_by varchar(64) default '',
create_time date, create_time date,
update_by varchar(64) default '', update_by varchar(64) default '',
@ -900,7 +901,7 @@ comment on column sys_oss.update_by is '更新者';
-- ---------------------------- -- ----------------------------
create table sys_oss_config ( create table sys_oss_config (
oss_config_id number(20) not null, oss_config_id number(20) not null,
config_key varchar(255) not null, config_key varchar(20) not null,
access_key varchar(255) default '', access_key varchar(255) default '',
secret_key varchar(255) default '', secret_key varchar(255) default '',
bucket_name varchar(255) default '', bucket_name varchar(255) default '',

View File

@ -231,7 +231,7 @@ comment on column sys_menu.query_param is '路由参数';
comment on column sys_menu.is_frame is '是否为外链0是 1否'; comment on column sys_menu.is_frame is '是否为外链0是 1否';
comment on column sys_menu.is_cache is '是否缓存0缓存 1不缓存'; comment on column sys_menu.is_cache is '是否缓存0缓存 1不缓存';
comment on column sys_menu.menu_type is '菜单类型M目录 C菜单 F按钮'; comment on column sys_menu.menu_type is '菜单类型M目录 C菜单 F按钮';
comment on column sys_menu.visible is '菜单状态0显示 1隐藏'; comment on column sys_menu.visible is '显示状态0显示 1隐藏';
comment on column sys_menu.status is '菜单状态0正常 1停用'; comment on column sys_menu.status is '菜单状态0正常 1停用';
comment on column sys_menu.perms is '权限标识'; comment on column sys_menu.perms is '权限标识';
comment on column sys_menu.icon is '菜单图标'; comment on column sys_menu.icon is '菜单图标';
@ -650,6 +650,7 @@ insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_ty
insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', now(), '', null, '公告'); insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', now(), '', null, '公告');
insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', now(), '', null, '正常状态'); insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', now(), '', null, '正常状态');
insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', now(), '', null, '关闭状态'); insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', now(), '', null, '关闭状态');
insert into sys_dict_data values(29, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', now(), '', null, '其他操作');
insert into sys_dict_data values(18, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', now(), '', null, '新增操作'); insert into sys_dict_data values(18, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', now(), '', null, '新增操作');
insert into sys_dict_data values(19, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', now(), '', null, '修改操作'); insert into sys_dict_data values(19, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', now(), '', null, '修改操作');
insert into sys_dict_data values(20, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', now(), '', null, '删除操作'); insert into sys_dict_data values(20, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', now(), '', null, '删除操作');
@ -890,7 +891,7 @@ create table if not exists sys_oss
create_time timestamp, create_time timestamp,
update_by varchar(64) default ''::varchar, update_by varchar(64) default ''::varchar,
update_time timestamp, update_time timestamp,
service varchar(10) default 'minio'::varchar, service varchar(20) default 'minio'::varchar,
constraint sys_oss_pk primary key (oss_id) constraint sys_oss_pk primary key (oss_id)
); );
@ -913,7 +914,7 @@ drop table if exists sys_oss_config;
create table if not exists sys_oss_config create table if not exists sys_oss_config
( (
oss_config_id int8, oss_config_id int8,
config_key varchar(255) default ''::varchar not null, config_key varchar(20) default ''::varchar not null,
access_key varchar(255) default ''::varchar, access_key varchar(255) default ''::varchar,
secret_key varchar(255) default ''::varchar, secret_key varchar(255) default ''::varchar,
bucket_name varchar(255) default ''::varchar, bucket_name varchar(255) default ''::varchar,
@ -957,3 +958,9 @@ insert into sys_oss_config values (3, 'aliyun', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXX
insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'cos.ap-beijing.myqcloud.com', '','N', 'ap-beijing', '1', '', 'admin', now(), 'admin', now(), null); insert into sys_oss_config values (4, 'qcloud', 'XXXXXXXXXXXXXXX', 'XXXXXXXXXXXXXXX', 'ruoyi-1250000000', '', 'cos.ap-beijing.myqcloud.com', '','N', 'ap-beijing', '1', '', 'admin', now(), 'admin', now(), null);
insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', '','N', '', '1', '', 'admin', now(), 'admin', now(), NULL); insert into sys_oss_config values (5, 'image', 'ruoyi', 'ruoyi123', 'ruoyi', 'image', '127.0.0.1:9000', '','N', '', '1', '', 'admin', now(), 'admin', now(), NULL);
-- 字符串自动转时间 避免框架时间查询报错问题
create or replace function cast_varchar_to_timestamp(varchar) returns timestamptz as $$
select to_timestamp($1, 'yyyy-mm-dd hh24:mi:ss');
$$ language sql strict ;
create cast (varchar as timestamptz) with function cast_varchar_to_timestamp as IMPLICIT;

View File

@ -141,7 +141,7 @@ create table sys_menu (
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按钮',
visible char(1) default 0 comment '菜单状态0显示 1隐藏', visible char(1) default 0 comment '显示状态0显示 1隐藏',
status char(1) default 0 comment '菜单状态0正常 1停用', status char(1) default 0 comment '菜单状态0正常 1停用',
perms varchar(100) default null comment '权限标识', perms varchar(100) default null comment '权限标识',
icon varchar(100) default '#' comment '菜单图标', icon varchar(100) default '#' comment '菜单图标',
@ -499,6 +499,7 @@ insert into sys_dict_data values(14, 1, '通知', '1', 'sys_notice_ty
insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '公告'); insert into sys_dict_data values(15, 2, '公告', '2', 'sys_notice_type', '', 'success', 'N', '0', 'admin', sysdate(), '', null, '公告');
insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态'); insert into sys_dict_data values(16, 1, '正常', '0', 'sys_notice_status', '', 'primary', 'Y', '0', 'admin', sysdate(), '', null, '正常状态');
insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '关闭状态'); insert into sys_dict_data values(17, 2, '关闭', '1', 'sys_notice_status', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '关闭状态');
insert into sys_dict_data values(29, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '其他操作');
insert into sys_dict_data values(18, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '新增操作'); insert into sys_dict_data values(18, 1, '新增', '1', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '新增操作');
insert into sys_dict_data values(19, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '修改操作'); insert into sys_dict_data values(19, 2, '修改', '2', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '修改操作');
insert into sys_dict_data values(20, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '删除操作'); insert into sys_dict_data values(20, 3, '删除', '3', 'sys_oper_type', '', 'danger', 'N', '0', 'admin', sysdate(), '', null, '删除操作');
@ -654,7 +655,7 @@ create table sys_oss (
create_by varchar(64) default '' comment '上传人', create_by varchar(64) default '' comment '上传人',
update_time datetime default null comment '更新时间', update_time datetime default null comment '更新时间',
update_by varchar(64) default '' comment '更新人', update_by varchar(64) default '' comment '更新人',
service varchar(10) not null default 'minio' comment '服务商', service varchar(20) not null default 'minio' comment '服务商',
primary key (oss_id) primary key (oss_id)
) engine=innodb comment ='OSS对象存储表'; ) engine=innodb comment ='OSS对象存储表';
@ -664,7 +665,7 @@ create table sys_oss (
drop table if exists sys_oss_config; drop table if exists sys_oss_config;
create table sys_oss_config ( create table sys_oss_config (
oss_config_id bigint(20) not null comment '主建', oss_config_id bigint(20) not null comment '主建',
config_key varchar(255) not null default '' comment '配置key', config_key varchar(20) not null default '' comment '配置key',
access_key varchar(255) default '' comment 'accessKey', access_key varchar(255) default '' comment 'accessKey',
secret_key varchar(255) default '' comment '秘钥', secret_key varchar(255) default '' comment '秘钥',
bucket_name varchar(255) default '' comment '桶名称', bucket_name varchar(255) default '' comment '桶名称',

View File

@ -702,6 +702,8 @@ INSERT [sys_dict_data] ([dict_code], [dict_sort], [dict_label], [dict_value], [d
GO GO
INSERT [sys_dict_data] ([dict_code], [dict_sort], [dict_label], [dict_value], [dict_type], [css_class], [list_class], [is_default], [status], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (17, 2, N'关闭', N'1', N'sys_notice_status', N'', N'danger', N'N', N'0', N'admin', getdate(), N'', NULL, N'关闭状态') INSERT [sys_dict_data] ([dict_code], [dict_sort], [dict_label], [dict_value], [dict_type], [css_class], [list_class], [is_default], [status], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (17, 2, N'关闭', N'1', N'sys_notice_status', N'', N'danger', N'N', N'0', N'admin', getdate(), N'', NULL, N'关闭状态')
GO GO
INSERT [sys_dict_data] ([dict_code], [dict_sort], [dict_label], [dict_value], [dict_type], [css_class], [list_class], [is_default], [status], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (29, 99, N'其他', N'0', N'sys_oper_type', N'', N'info', N'N', N'0', N'admin', getdate(), N'', NULL, N'其他操作');
GO
INSERT [sys_dict_data] ([dict_code], [dict_sort], [dict_label], [dict_value], [dict_type], [css_class], [list_class], [is_default], [status], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (18, 1, N'新增', N'1', N'sys_oper_type', N'', N'info', N'N', N'0', N'admin', getdate(), N'', NULL, N'新增操作') INSERT [sys_dict_data] ([dict_code], [dict_sort], [dict_label], [dict_value], [dict_type], [css_class], [list_class], [is_default], [status], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (18, 1, N'新增', N'1', N'sys_oper_type', N'', N'info', N'N', N'0', N'admin', getdate(), N'', NULL, N'新增操作')
GO GO
INSERT [sys_dict_data] ([dict_code], [dict_sort], [dict_label], [dict_value], [dict_type], [css_class], [list_class], [is_default], [status], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (19, 2, N'修改', N'2', N'sys_oper_type', N'', N'info', N'N', N'0', N'admin', getdate(), N'', NULL, N'修改操作') INSERT [sys_dict_data] ([dict_code], [dict_sort], [dict_label], [dict_value], [dict_type], [css_class], [list_class], [is_default], [status], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (19, 2, N'修改', N'2', N'sys_oper_type', N'', N'info', N'N', N'0', N'admin', getdate(), N'', NULL, N'修改操作')
@ -991,7 +993,7 @@ EXEC sys.sp_addextendedproperty
'COLUMN', N'menu_type' 'COLUMN', N'menu_type'
GO GO
EXEC sys.sp_addextendedproperty EXEC sys.sp_addextendedproperty
'MS_Description', N'菜单状态0显示 1隐藏' , 'MS_Description', N'显示状态0显示 1隐藏' ,
'SCHEMA', N'dbo', 'SCHEMA', N'dbo',
'TABLE', N'sys_menu', 'TABLE', N'sys_menu',
'COLUMN', N'visible' 'COLUMN', N'visible'
@ -2114,7 +2116,7 @@ CREATE TABLE [sys_oss]
[create_by] nvarchar(64) DEFAULT '' NULL, [create_by] nvarchar(64) DEFAULT '' NULL,
[update_time] datetime2(7) NULL, [update_time] datetime2(7) NULL,
[update_by] nvarchar(64) DEFAULT '' NULL, [update_by] nvarchar(64) DEFAULT '' NULL,
[service] nvarchar(10) DEFAULT ('minio') NOT NULL, [service] nvarchar(20) DEFAULT ('minio') NOT NULL,
CONSTRAINT [PK__sys_oss__91241EA442389F0D] PRIMARY KEY CLUSTERED ([oss_id]) CONSTRAINT [PK__sys_oss__91241EA442389F0D] PRIMARY KEY CLUSTERED ([oss_id])
WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY] ON [PRIMARY]
@ -2191,7 +2193,7 @@ GO
CREATE TABLE [sys_oss_config] CREATE TABLE [sys_oss_config]
( (
[oss_config_id] bigint NOT NULL, [oss_config_id] bigint NOT NULL,
[config_key] nvarchar(255) DEFAULT '' NOT NULL, [config_key] nvarchar(20) DEFAULT '' NOT NULL,
[access_key] nvarchar(255) DEFAULT '' NULL, [access_key] nvarchar(255) DEFAULT '' NULL,
[secret_key] nvarchar(255) DEFAULT '' NULL, [secret_key] nvarchar(255) DEFAULT '' NULL,
[bucket_name] nvarchar(255) DEFAULT '' NULL, [bucket_name] nvarchar(255) DEFAULT '' NULL,

View File

@ -7,3 +7,5 @@ update sys_config set config_key = 'sys.account.captchaEnabled' where config_id
insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate, '', null, ''); insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate, '', null, '');
insert into sys_role_menu values ('2', '1050'); insert into sys_role_menu values ('2', '1050');
insert into sys_dict_data values(29, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate, '', null, '其他操作');

View File

@ -7,3 +7,13 @@ update sys_config set config_key = 'sys.account.captchaEnabled' where config_id
insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', now(), '', null, ''); insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', '1', '0', 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', now(), '', null, '');
insert into sys_role_menu values ('2', '1050'); insert into sys_role_menu values ('2', '1050');
-- 字符串自动转时间 避免框架时间查询报错问题
create or replace function cast_varchar_to_timestamp(varchar) returns timestamptz as $$
select to_timestamp($1, 'yyyy-mm-dd hh24:mi:ss');
$$ language sql strict ;
create cast (varchar as timestamptz) with function cast_varchar_to_timestamp as IMPLICIT;
insert into sys_dict_data values(29, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', now(), '', null, '其他操作');

View File

@ -12,3 +12,6 @@ GO
INSERT [sys_role_menu] ([role_id], [menu_id]) VALUES (2, 1050) INSERT [sys_role_menu] ([role_id], [menu_id]) VALUES (2, 1050)
GO GO
INSERT [sys_dict_data] ([dict_code], [dict_sort], [dict_label], [dict_value], [dict_type], [css_class], [list_class], [is_default], [status], [create_by], [create_time], [update_by], [update_time], [remark]) VALUES (29, 99, N'其他', N'0', N'sys_oper_type', N'', N'info', N'N', N'0', N'admin', getdate(), N'', NULL, N'其他操作');
GO

View File

@ -7,3 +7,5 @@ update sys_config set config_key = 'sys.account.captchaEnabled' where config_id
insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate(), '', null, ''); insert into sys_menu values('1050', '账户解锁', '501', '4', '#', '', '', 1, 0, 'F', '0', '0', 'monitor:logininfor:unlock', '#', 'admin', sysdate(), '', null, '');
insert into sys_role_menu values ('2', '1050'); insert into sys_role_menu values ('2', '1050');
insert into sys_dict_data values(29, 99, '其他', '0', 'sys_oper_type', '', 'info', 'N', '0', 'admin', sysdate(), '', null, '其他操作');