mirror of
https://github.com/dromara/RuoYi-Vue-Plus.git
synced 2025-09-22 03:06:38 +08:00
Merge remote-tracking branch 'origin/dev' into 4.X
This commit is contained in:
commit
ca085b9aaa
@ -4,7 +4,7 @@
|
||||
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus/blob/master/LICENSE)
|
||||
[](https://www.jetbrains.com/?from=RuoYi-Vue-Plus)
|
||||
<br>
|
||||
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
|
||||
[](https://gitee.com/JavaLionLi/RuoYi-Vue-Plus)
|
||||
[]()
|
||||
[]()
|
||||
[]()
|
||||
@ -84,7 +84,7 @@
|
||||
|
||||
## 捐献作者
|
||||
作者为兼职做开源,平时还需要工作,如果帮到了您可以请作者吃个盒饭
|
||||
<img src="https://images.gitee.com/uploads/images/2021/0525/101654_451e4523_1766278.jpeg" width="300px" height="450px" />
|
||||
<img src="https://images.gitee.com/uploads/images/2022/0218/213734_b1b8197f_1766278.jpeg" width="300px" height="450px" />
|
||||
<img src="https://images.gitee.com/uploads/images/2021/0525/101713_3d18b119_1766278.jpeg" width="300px" height="450px" />
|
||||
|
||||
## 业务功能
|
||||
|
12
pom.xml
12
pom.xml
@ -6,15 +6,15 @@
|
||||
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
|
||||
<name>RuoYi-Vue-Plus</name>
|
||||
<url>https://gitee.com/JavaLionLi/RuoYi-Vue-Plus</url>
|
||||
<description>RuoYi-Vue-Plus后台管理系统</description>
|
||||
|
||||
<properties>
|
||||
<ruoyi-vue-plus.version>4.0.0</ruoyi-vue-plus.version>
|
||||
<spring-boot.version>2.6.3</spring-boot.version>
|
||||
<ruoyi-vue-plus.version>4.0.1</ruoyi-vue-plus.version>
|
||||
<spring-boot.version>2.6.4</spring-boot.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
@ -29,7 +29,7 @@
|
||||
<satoken.version>1.29.0</satoken.version>
|
||||
<mybatis-plus.version>3.5.1</mybatis-plus.version>
|
||||
<p6spy.version>3.9.1</p6spy.version>
|
||||
<hutool.version>5.7.20</hutool.version>
|
||||
<hutool.version>5.7.21</hutool.version>
|
||||
<okhttp.version>4.9.2</okhttp.version>
|
||||
<spring-boot-admin.version>2.6.2</spring-boot-admin.version>
|
||||
<redisson.version>3.16.8</redisson.version>
|
||||
@ -42,10 +42,10 @@
|
||||
<jaxb.version>3.0.1</jaxb.version>
|
||||
|
||||
<!-- OSS 配置 -->
|
||||
<qiniu.version>7.9.2</qiniu.version>
|
||||
<qiniu.version>7.9.3</qiniu.version>
|
||||
<aliyun.oss.version>3.14.0</aliyun.oss.version>
|
||||
<qcloud.cos.version>5.6.68</qcloud.cos.version>
|
||||
<minio.version>8.3.5</minio.version>
|
||||
<minio.version>8.3.7</minio.version>
|
||||
|
||||
<!-- docker 配置 -->
|
||||
<docker.registry.url>localhost</docker.registry.url>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
|
@ -65,6 +65,7 @@ public class SysLoginController {
|
||||
public R<Void> logout() {
|
||||
try {
|
||||
StpUtil.logout();
|
||||
loginService.logout(LoginHelper.getUsername());
|
||||
} catch (NotLoginException e) {
|
||||
}
|
||||
return R.ok("退出成功");
|
||||
|
@ -7,7 +7,6 @@ import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.http.HttpException;
|
||||
import cn.hutool.http.HttpUtil;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.annotation.RepeatSubmit;
|
||||
import com.ruoyi.common.core.controller.BaseController;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.domain.R;
|
||||
@ -70,7 +69,6 @@ public class SysOssController extends BaseController {
|
||||
})
|
||||
@SaCheckPermission("system:oss:upload")
|
||||
@Log(title = "OSS对象存储", businessType = BusinessType.INSERT)
|
||||
@RepeatSubmit
|
||||
@PostMapping("/upload")
|
||||
public R<Map<String, String>> upload(@RequestPart("file") MultipartFile file) {
|
||||
if (ObjectUtil.isNull(file)) {
|
||||
|
@ -16,6 +16,7 @@ import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.enums.BusinessType;
|
||||
import com.ruoyi.common.excel.ExcelResult;
|
||||
import com.ruoyi.common.helper.LoginHelper;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.poi.ExcelUtil;
|
||||
import com.ruoyi.system.domain.vo.SysUserExportVo;
|
||||
@ -109,7 +110,7 @@ public class SysUserController extends BaseController {
|
||||
userService.checkUserDataScope(userId);
|
||||
Map<String, Object> ajax = new HashMap<>();
|
||||
List<SysRole> roles = roleService.selectRoleAll();
|
||||
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
||||
ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
||||
ajax.put("posts", postService.selectPostAll());
|
||||
if (ObjectUtil.isNotNull(userId)) {
|
||||
SysUser sysUser = userService.selectUserById(userId);
|
||||
@ -213,7 +214,7 @@ public class SysUserController extends BaseController {
|
||||
List<SysRole> roles = roleService.selectRolesByUserId(userId);
|
||||
Map<String, Object> ajax = new HashMap<>();
|
||||
ajax.put("user", user);
|
||||
ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
||||
ajax.put("roles", LoginHelper.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
|
||||
return R.ok(ajax);
|
||||
}
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -41,14 +41,14 @@ public class UnsignedMathGenerator implements CodeGenerator {
|
||||
@Override
|
||||
public String generate() {
|
||||
final int limit = getLimit();
|
||||
int min = RandomUtil.randomInt(limit);
|
||||
int max = RandomUtil.randomInt(min, limit);
|
||||
String number1 = Integer.toString(max);
|
||||
String number2 = Integer.toString(min);
|
||||
number1 = StringUtils.rightPad(number1, this.numberLength, CharUtil.SPACE);
|
||||
number2 = StringUtils.rightPad(number2, this.numberLength, CharUtil.SPACE);
|
||||
int a = RandomUtil.randomInt(limit);
|
||||
int b = RandomUtil.randomInt(limit);
|
||||
String max = Integer.toString(Math.max(a,b));
|
||||
String min = Integer.toString(Math.min(a,b));
|
||||
max = StringUtils.rightPad(max, this.numberLength, CharUtil.SPACE);
|
||||
min = StringUtils.rightPad(min, this.numberLength, CharUtil.SPACE);
|
||||
|
||||
return number1 + RandomUtil.randomChar(OPERATORS) + number2 + '=';
|
||||
return max + RandomUtil.randomChar(OPERATORS) + min + '=';
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -109,4 +109,10 @@ public interface UserConstants {
|
||||
*/
|
||||
int PASSWORD_MIN_LENGTH = 5;
|
||||
int PASSWORD_MAX_LENGTH = 20;
|
||||
|
||||
/**
|
||||
* 管理员ID
|
||||
*/
|
||||
Long ADMIN_ID = 1L;
|
||||
|
||||
}
|
||||
|
@ -38,11 +38,11 @@ public class R<T> implements Serializable {
|
||||
private T data;
|
||||
|
||||
public static <T> R<T> ok() {
|
||||
return restResult(null, SUCCESS, null);
|
||||
return restResult(null, SUCCESS, "操作成功");
|
||||
}
|
||||
|
||||
public static <T> R<T> ok(T data) {
|
||||
return restResult(data, SUCCESS, null);
|
||||
return restResult(data, SUCCESS, "操作成功");
|
||||
}
|
||||
|
||||
public static <T> R<T> ok(String msg) {
|
||||
@ -54,7 +54,7 @@ public class R<T> implements Serializable {
|
||||
}
|
||||
|
||||
public static <T> R<T> fail() {
|
||||
return restResult(null, FAIL, null);
|
||||
return restResult(null, FAIL, "操作失败");
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(String msg) {
|
||||
@ -62,7 +62,7 @@ public class R<T> implements Serializable {
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(T data) {
|
||||
return restResult(data, FAIL, null);
|
||||
return restResult(data, FAIL, "操作失败");
|
||||
}
|
||||
|
||||
public static <T> R<T> fail(String msg, T data) {
|
||||
|
@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableLogic;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.ruoyi.common.annotation.ExcelDictFormat;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.convert.ExcelDictConvert;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
@ -132,11 +133,7 @@ public class SysRole extends BaseEntity {
|
||||
|
||||
@ApiModelProperty(value = "是否管理员")
|
||||
public boolean isAdmin() {
|
||||
return isAdmin(this.roleId);
|
||||
}
|
||||
|
||||
public static boolean isAdmin(Long roleId) {
|
||||
return roleId != null && 1L == roleId;
|
||||
return UserConstants.ADMIN_ID.equals(this.roleId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import com.ruoyi.common.annotation.Sensitive;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import com.ruoyi.common.enums.SensitiveStrategy;
|
||||
import com.ruoyi.common.xss.Xss;
|
||||
@ -185,11 +186,7 @@ public class SysUser extends BaseEntity {
|
||||
|
||||
@ApiModelProperty(value = "是否管理员")
|
||||
public boolean isAdmin() {
|
||||
return isAdmin(this.userId);
|
||||
}
|
||||
|
||||
public static boolean isAdmin(Long userId) {
|
||||
return userId != null && 1L == userId;
|
||||
return UserConstants.ADMIN_ID.equals(this.userId);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package com.ruoyi.common.helper;
|
||||
|
||||
import cn.dev33.satoken.stp.StpUtil;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.enums.DeviceType;
|
||||
import com.ruoyi.common.enums.UserType;
|
||||
@ -130,12 +131,11 @@ public class LoginHelper {
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean isAdmin(Long userId) {
|
||||
return userId != null && 1L == userId;
|
||||
return UserConstants.ADMIN_ID.equals(userId);
|
||||
}
|
||||
|
||||
public static boolean isAdmin() {
|
||||
Long userId = getUserId();
|
||||
return userId != null && 1L == userId;
|
||||
return isAdmin(getUserId());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,6 +7,11 @@ import org.apache.commons.lang3.time.DateFormatUtils;
|
||||
import java.lang.management.ManagementFactory;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.time.LocalDate;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.LocalTime;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
|
||||
/**
|
||||
@ -116,6 +121,14 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
|
||||
return new Date(time);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算相差天数
|
||||
*/
|
||||
public static int differentDaysByMillisecond(Date date1, Date date2)
|
||||
{
|
||||
return Math.abs((int) ((date2.getTime() - date1.getTime()) / (1000 * 3600 * 24)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算两个时间差
|
||||
*/
|
||||
@ -136,4 +149,21 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils {
|
||||
// long sec = diff % nd % nh % nm / ns;
|
||||
return day + "天" + hour + "小时" + min + "分钟";
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加 LocalDateTime ==> Date
|
||||
*/
|
||||
public static Date toDate(LocalDateTime temporalAccessor) {
|
||||
ZonedDateTime zdt = temporalAccessor.atZone(ZoneId.systemDefault());
|
||||
return Date.from(zdt.toInstant());
|
||||
}
|
||||
|
||||
/**
|
||||
* 增加 LocalDate ==> Date
|
||||
*/
|
||||
public static Date toDate(LocalDate temporalAccessor) {
|
||||
LocalDateTime localDateTime = LocalDateTime.of(temporalAccessor, LocalTime.of(0, 0, 0));
|
||||
ZonedDateTime zdt = localDateTime.atZone(ZoneId.systemDefault());
|
||||
return Date.from(zdt.toInstant());
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
* 如果想输出 {} 使用 \\转义 { 即可,如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
|
||||
* 例:<br>
|
||||
* 通常使用:format("this is {} for {}", "a", "b") -> this is a for b<br>
|
||||
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
|
||||
* 转义{}: format("this is \\{} for {}", "a", "b") -> this is {} for a<br>
|
||||
* 转义\: format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
|
||||
*
|
||||
* @param template 文本模板,被替换的部分用 {} 表示
|
||||
@ -231,4 +231,43 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils {
|
||||
return matcher.match(pattern, url);
|
||||
}
|
||||
|
||||
/**
|
||||
* 数字左边补齐0,使之达到指定长度。注意,如果数字转换为字符串后,长度大于size,则只保留 最后size个字符。
|
||||
*
|
||||
* @param num 数字对象
|
||||
* @param size 字符串指定长度
|
||||
* @return 返回数字的字符串格式,该字符串为指定长度。
|
||||
*/
|
||||
public static final String padl(final Number num, final int size) {
|
||||
return padl(num.toString(), size, '0');
|
||||
}
|
||||
|
||||
/**
|
||||
* 字符串左补齐。如果原始字符串s长度大于size,则只保留最后size个字符。
|
||||
*
|
||||
* @param s 原始字符串
|
||||
* @param size 字符串指定长度
|
||||
* @param c 用于补齐的字符
|
||||
* @return 返回指定长度的字符串,由原字符串左补齐或截取得到。
|
||||
*/
|
||||
public static final String padl(final String s, final int size, final char c) {
|
||||
final StringBuilder sb = new StringBuilder(size);
|
||||
if (s != null) {
|
||||
final int len = s.length();
|
||||
if (s.length() <= size) {
|
||||
for (int i = size - len; i > 0; i--) {
|
||||
sb.append(c);
|
||||
}
|
||||
sb.append(s);
|
||||
} else {
|
||||
return s.substring(len - size, len);
|
||||
}
|
||||
} else {
|
||||
for (int i = size; i > 0; i--) {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -22,7 +22,6 @@ public class FileUtils extends FileUtil {
|
||||
*
|
||||
* @param response 响应对象
|
||||
* @param realFileName 真实文件名
|
||||
* @return
|
||||
*/
|
||||
public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException {
|
||||
String percentEncodedFileName = percentEncode(realFileName);
|
||||
@ -35,7 +34,6 @@ public class FileUtils extends FileUtil {
|
||||
.append("utf-8''")
|
||||
.append(percentEncodedFileName);
|
||||
|
||||
response.addHeader("Access-Control-Allow-Origin", "*");
|
||||
response.addHeader("Access-Control-Expose-Headers", "Content-Disposition,download-filename");
|
||||
response.setHeader("Content-disposition", contentDispositionValue.toString());
|
||||
response.setHeader("download-filename", percentEncodedFileName);
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>ruoyi-extend</artifactId>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-extend</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
|
@ -4,7 +4,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-extend</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
<artifactId>ruoyi-xxl-job-admin</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -0,0 +1,54 @@
|
||||
package com.ruoyi.framework.config;
|
||||
|
||||
import cn.hutool.core.util.ArrayUtil;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.scheduling.annotation.AsyncConfigurerSupport;
|
||||
import org.springframework.scheduling.annotation.EnableAsync;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.concurrent.Executor;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
|
||||
/**
|
||||
* 异步配置
|
||||
*
|
||||
* @author Lion Li
|
||||
*/
|
||||
@EnableAsync
|
||||
@Configuration
|
||||
public class AsyncConfig extends AsyncConfigurerSupport {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("scheduledExecutorService")
|
||||
private ScheduledExecutorService scheduledExecutorService;
|
||||
|
||||
/**
|
||||
* 自定义 @Async 注解使用系统线程池
|
||||
*/
|
||||
@Override
|
||||
public Executor getAsyncExecutor() {
|
||||
return scheduledExecutorService;
|
||||
}
|
||||
|
||||
/**
|
||||
* 异步执行异常处理
|
||||
*/
|
||||
@Override
|
||||
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
|
||||
return (throwable, method, objects) -> {
|
||||
throwable.printStackTrace();
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("Exception message - ").append(throwable.getMessage())
|
||||
.append(", Method name - ").append(method.getName());
|
||||
if (ArrayUtil.isNotEmpty(objects)) {
|
||||
sb.append(", Parameter value - ").append(Arrays.toString(objects));
|
||||
}
|
||||
throw new ServiceException(sb.toString());
|
||||
};
|
||||
}
|
||||
|
||||
}
|
@ -79,7 +79,7 @@ public class PlusDataPermissionHandler {
|
||||
DataPermissionHelper.setVariable("user", currentUser);
|
||||
}
|
||||
// 如果是超级管理员,则不过滤数据
|
||||
if (ObjectUtil.isNull(currentUser) || LoginHelper.isAdmin(currentUser.getUserId())) {
|
||||
if (LoginHelper.isAdmin()) {
|
||||
return where;
|
||||
}
|
||||
String dataFilterSql = buildDataFilter(dataColumns, isSelect);
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package com.ruoyi.generator.domain;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.ruoyi.common.constant.GenConstants;
|
||||
import com.ruoyi.common.core.domain.BaseEntity;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
@ -102,6 +100,7 @@ public class GenTable extends BaseEntity {
|
||||
/**
|
||||
* 生成路径(不填默认项目路径)
|
||||
*/
|
||||
@TableField(updateStrategy = FieldStrategy.NOT_EMPTY)
|
||||
private String genPath;
|
||||
|
||||
/**
|
||||
|
@ -244,14 +244,28 @@ public class VelocityUtils {
|
||||
public static String getDicts(GenTable genTable) {
|
||||
List<GenTableColumn> columns = genTable.getColumns();
|
||||
Set<String> dicts = new HashSet<String>();
|
||||
addDicts(dicts, columns);
|
||||
if (ObjectUtil.isNotNull(genTable.getSubTable())) {
|
||||
List<GenTableColumn> subColumns = genTable.getSubTable().getColumns();
|
||||
addDicts(dicts, subColumns);
|
||||
}
|
||||
return StringUtils.join(dicts, ", ");
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加字典列表
|
||||
*
|
||||
* @param dicts 字典列表
|
||||
* @param columns 列集合
|
||||
*/
|
||||
public static void addDicts(Set<String> dicts, List<GenTableColumn> columns) {
|
||||
for (GenTableColumn column : columns) {
|
||||
if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
|
||||
column.getHtmlType(),
|
||||
new String[]{GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX})) {
|
||||
new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) {
|
||||
dicts.add("'" + column.getDictType() + "'");
|
||||
}
|
||||
}
|
||||
return StringUtils.join(dicts, ", ");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -48,7 +48,7 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
/**
|
||||
* 查询${functionName}列表
|
||||
*
|
||||
* @param ${className} ${functionName}
|
||||
* @param bo ${functionName}
|
||||
* @return ${functionName}
|
||||
*/
|
||||
@Override
|
||||
@ -62,7 +62,7 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
/**
|
||||
* 查询${functionName}列表
|
||||
*
|
||||
* @param ${className} ${functionName}
|
||||
* @param bo ${functionName}
|
||||
* @return ${functionName}
|
||||
*/
|
||||
@Override
|
||||
@ -101,7 +101,7 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
/**
|
||||
* 新增${functionName}
|
||||
*
|
||||
* @param ${className} ${functionName}
|
||||
* @param bo ${functionName}
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
@ -119,7 +119,7 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
/**
|
||||
* 修改${functionName}
|
||||
*
|
||||
* @param ${className} ${functionName}
|
||||
* @param bo ${functionName}
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
|
@ -306,7 +306,7 @@ export default {
|
||||
queryParams: {
|
||||
#foreach ($column in $columns)
|
||||
#if($column.query)
|
||||
$column.javaField: null#if($foreach.count != $columns.size()),#end
|
||||
$column.javaField: undefined#if($foreach.count != $columns.size()),#end
|
||||
#end
|
||||
#end
|
||||
},
|
||||
|
@ -44,7 +44,7 @@
|
||||
v-model="queryParams.${column.javaField}"
|
||||
type="date"
|
||||
value-format="yyyy-MM-dd"
|
||||
placeholder="选择${comment}">
|
||||
placeholder="请选择${comment}">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||
@ -268,7 +268,7 @@
|
||||
v-model="form.${field}"
|
||||
type="datetime"
|
||||
value-format="yyyy-MM-dd HH:mm:ss"
|
||||
placeholder="选择${comment}">
|
||||
placeholder="请选择${comment}">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")
|
||||
@ -300,12 +300,39 @@
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
#if($column.pk || $javaField == ${subTableFkclassName})
|
||||
#elseif($column.list && "" != $javaField)
|
||||
<el-table-column label="$comment" prop="${javaField}">
|
||||
#elseif($column.list && $column.htmlType == "input")
|
||||
<el-table-column label="$comment" prop="${javaField}" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-input v-model="scope.row.$javaField" placeholder="请输入$comment" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && $column.htmlType == "datetime")
|
||||
<el-table-column label="$comment" prop="${javaField}" width="240">
|
||||
<template slot-scope="scope">
|
||||
<el-date-picker clearable v-model="scope.row.$javaField" type="date" value-format="yyyy-MM-dd" placeholder="请选择$comment" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" != $column.dictType)
|
||||
<el-table-column label="$comment" prop="${javaField}" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.$javaField" placeholder="请选择$comment">
|
||||
<el-option
|
||||
v-for="dict in dict.type.$column.dictType"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" == $column.dictType)
|
||||
<el-table-column label="$comment" prop="${javaField}" width="150">
|
||||
<template slot-scope="scope">
|
||||
<el-select v-model="scope.row.$javaField" placeholder="请选择$comment">
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#end
|
||||
</el-table>
|
||||
|
@ -43,7 +43,7 @@
|
||||
v-model="queryParams.${column.javaField}"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="选择${comment}">
|
||||
placeholder="请选择${comment}">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN")
|
||||
@ -259,7 +259,7 @@
|
||||
v-model="form.${field}"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="选择${comment}">
|
||||
placeholder="请选择${comment}">
|
||||
</el-date-picker>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "textarea")
|
||||
@ -291,12 +291,44 @@
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
#if($column.pk || $javaField == ${subTableFkclassName})
|
||||
#elseif($column.list && "" != $javaField)
|
||||
<el-table-column label="$comment" prop="${javaField}">
|
||||
#elseif($column.list && $column.htmlType == "input")
|
||||
<el-table-column label="$comment" prop="${javaField}" width="150">
|
||||
<template #default="scope">
|
||||
<el-input v-model="scope.row.$javaField" placeholder="请输入$comment" />
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && $column.htmlType == "datetime")
|
||||
<el-table-column label="$comment" prop="${javaField}" width="240">
|
||||
<template #default="scope">
|
||||
<el-date-picker clearable
|
||||
v-model="scope.row.$javaField"
|
||||
type="date"
|
||||
value-format="YYYY-MM-DD"
|
||||
placeholder="请选择$comment">
|
||||
</el-date-picker>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" != $column.dictType)
|
||||
<el-table-column label="$comment" prop="${javaField}" width="150">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.$javaField" placeholder="请选择$comment">
|
||||
<el-option
|
||||
v-for="dict in $column.dictType"
|
||||
:key="dict.value"
|
||||
:label="dict.label"
|
||||
:value="dict.value"
|
||||
></el-option>
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" == $column.dictType)
|
||||
<el-table-column label="$comment" prop="${javaField}" width="150">
|
||||
<template #default="scope">
|
||||
<el-select v-model="scope.row.$javaField" placeholder="请选择$comment">
|
||||
<el-option label="请选择字典生成" value="" />
|
||||
</el-select>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#end
|
||||
</el-table>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi-vue-plus</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>4.0.0</version>
|
||||
<version>4.0.1</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@ -87,16 +87,19 @@ public class SysLoginService {
|
||||
|
||||
// 登录成功 清空错误次数
|
||||
RedisUtils.deleteObject(Constants.LOGIN_ERROR + username);
|
||||
asyncService.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"), request);
|
||||
recordLoginInfo(user.getUserId(), username);
|
||||
|
||||
LoginUser loginUser = buildLoginUser(user);
|
||||
|
||||
// 生成token
|
||||
LoginHelper.loginByDevice(loginUser, DeviceType.PC);
|
||||
|
||||
asyncService.recordLogininfor(username, Constants.LOGIN_SUCCESS, MessageUtils.message("user.login.success"), request);
|
||||
recordLoginInfo(user.getUserId(), username);
|
||||
return StpUtil.getTokenValue();
|
||||
}
|
||||
|
||||
public void logout(String loginName) {
|
||||
asyncService.recordLogininfor(loginName, Constants.LOGOUT, MessageUtils.message("user.logout.success"), ServletUtils.getRequest());
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验验证码
|
||||
*
|
||||
|
@ -152,7 +152,7 @@ public class SysDeptServiceImpl implements ISysDeptService {
|
||||
*/
|
||||
@Override
|
||||
public void checkDeptDataScope(Long deptId) {
|
||||
if (!SysUser.isAdmin(LoginHelper.getUserId())) {
|
||||
if (!LoginHelper.isAdmin()) {
|
||||
SysDept dept = new SysDept();
|
||||
dept.setDeptId(deptId);
|
||||
List<SysDept> depts = SpringUtils.getAopProxy(this).selectDeptList(dept);
|
||||
|
@ -8,7 +8,6 @@ import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.core.domain.entity.SysMenu;
|
||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.helper.LoginHelper;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.common.utils.TreeBuildUtils;
|
||||
@ -58,7 +57,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
|
||||
public List<SysMenu> selectMenuList(SysMenu menu, Long userId) {
|
||||
List<SysMenu> menuList = null;
|
||||
// 管理员显示所有菜单信息
|
||||
if (SysUser.isAdmin(userId)) {
|
||||
if (LoginHelper.isAdmin(userId)) {
|
||||
menuList = baseMapper.selectList(new LambdaQueryWrapper<SysMenu>()
|
||||
.like(StringUtils.isNotBlank(menu.getMenuName()), SysMenu::getMenuName, menu.getMenuName())
|
||||
.eq(StringUtils.isNotBlank(menu.getVisible()), SysMenu::getVisible, menu.getVisible())
|
||||
|
@ -7,7 +7,6 @@ import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.ruoyi.common.constant.UserConstants;
|
||||
import com.ruoyi.common.core.domain.PageQuery;
|
||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.page.TableDataInfo;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.helper.LoginHelper;
|
||||
@ -181,7 +180,7 @@ public class SysRoleServiceImpl implements ISysRoleService {
|
||||
*/
|
||||
@Override
|
||||
public void checkRoleDataScope(Long roleId) {
|
||||
if (!SysUser.isAdmin(LoginHelper.getUserId())) {
|
||||
if (!LoginHelper.isAdmin()) {
|
||||
SysRole role = new SysRole();
|
||||
role.setRoleId(roleId);
|
||||
List<SysRole> roles = SpringUtils.getAopProxy(this).selectRoleList(role);
|
||||
|
@ -206,7 +206,7 @@ public class SysUserServiceImpl implements ISysUserService {
|
||||
*/
|
||||
@Override
|
||||
public void checkUserDataScope(Long userId) {
|
||||
if (!SysUser.isAdmin(LoginHelper.getUserId())) {
|
||||
if (!LoginHelper.isAdmin()) {
|
||||
SysUser user = new SysUser();
|
||||
user.setUserId(userId);
|
||||
List<SysUser> users = SpringUtils.getAopProxy(this).selectUserList(user);
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ruoyi-vue-plus",
|
||||
"version": "4.0.0",
|
||||
"version": "4.0.1",
|
||||
"description": "RuoYi-Vue-Plus后台管理系统",
|
||||
"author": "LionLi",
|
||||
"license": "MIT",
|
||||
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="upload-file">
|
||||
<el-upload
|
||||
multiple
|
||||
:action="uploadFileUrl"
|
||||
:before-upload="handleBeforeUpload"
|
||||
:file-list="fileList"
|
||||
@ -69,6 +70,8 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
number: 0,
|
||||
uploadList: [],
|
||||
baseUrl: process.env.VUE_APP_BASE_API,
|
||||
uploadFileUrl: process.env.VUE_APP_BASE_API + "/system/oss/upload", // 上传的图片服务器地址
|
||||
headers: {
|
||||
@ -122,7 +125,7 @@ export default {
|
||||
return false;
|
||||
});
|
||||
if (!isTypeOk) {
|
||||
this.$message.error(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
|
||||
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}格式文件!`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -130,29 +133,37 @@ export default {
|
||||
if (this.fileSize) {
|
||||
const isLt = file.size / 1024 / 1024 < this.fileSize;
|
||||
if (!isLt) {
|
||||
this.$message.error(`上传文件大小不能超过 ${this.fileSize} MB!`);
|
||||
this.$modal.msgError(`上传文件大小不能超过 ${this.fileSize} MB!`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.$modal.loading("正在上传文件,请稍候...");
|
||||
this.number++;
|
||||
return true;
|
||||
},
|
||||
// 文件个数超出
|
||||
handleExceed() {
|
||||
this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
|
||||
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
|
||||
},
|
||||
// 上传失败
|
||||
handleUploadError(err) {
|
||||
this.$message.error("上传失败, 请重试");
|
||||
this.$modal.msgError("上传图片失败,请重试");
|
||||
this.$modal.closeLoading()
|
||||
},
|
||||
// 上传成功回调
|
||||
handleUploadSuccess(res, file) {
|
||||
if (res.code === 200) {
|
||||
this.$message.success("上传成功");
|
||||
this.fileList.push({ name: res.data.fileName, url: res.data.url });
|
||||
this.$emit("input", this.listToString(this.fileList));
|
||||
this.uploadList.push({ name: res.data.fileName, url: res.data.url });
|
||||
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.$message.error(res.msg);
|
||||
this.loading.close();
|
||||
this.$modal.msgError(res.msg);
|
||||
this.$modal.closeLoading();
|
||||
}
|
||||
},
|
||||
// 删除文件
|
||||
@ -163,7 +174,7 @@ export default {
|
||||
// 获取文件名称
|
||||
getFileName(name) {
|
||||
if (name.lastIndexOf("/") > -1) {
|
||||
return name.slice(name.lastIndexOf("/") + 1).toLowerCase();
|
||||
return name.slice(name.lastIndexOf("/") + 1);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="component-upload-image">
|
||||
<el-upload
|
||||
multiple
|
||||
:action="uploadImgUrl"
|
||||
list-type="picture-card"
|
||||
:on-success="handleUploadSuccess"
|
||||
@ -18,7 +19,7 @@
|
||||
>
|
||||
<i class="el-icon-plus"></i>
|
||||
</el-upload>
|
||||
|
||||
|
||||
<!-- 上传提示 -->
|
||||
<div class="el-upload__tip" slot="tip" v-if="showTip">
|
||||
请上传
|
||||
@ -70,6 +71,8 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
number: 0,
|
||||
uploadList: [],
|
||||
dialogImageUrl: "",
|
||||
dialogVisible: false,
|
||||
hideUpload: false,
|
||||
@ -121,12 +124,17 @@ export default {
|
||||
// 上传成功回调
|
||||
handleUploadSuccess(res) {
|
||||
if (res.code == 200) {
|
||||
this.fileList.push({ name: res.data.fileName, url: res.data.url });
|
||||
this.$emit("input", this.listToString(this.fileList));
|
||||
this.loading.close();
|
||||
this.uploadList.push({ name: res.data.fileName, url: res.data.url });
|
||||
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.$message.error(res.msg);
|
||||
this.loading.close();
|
||||
this.$modal.msgError(res.msg);
|
||||
this.$modal.closeLoading();
|
||||
}
|
||||
},
|
||||
// 上传前loading加载
|
||||
@ -147,35 +155,27 @@ export default {
|
||||
}
|
||||
|
||||
if (!isImg) {
|
||||
this.$message.error(
|
||||
`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`
|
||||
);
|
||||
this.$modal.msgError(`文件格式不正确, 请上传${this.fileType.join("/")}图片格式文件!`);
|
||||
return false;
|
||||
}
|
||||
if (this.fileSize) {
|
||||
const isLt = file.size / 1024 / 1024 < this.fileSize;
|
||||
if (!isLt) {
|
||||
this.$message.error(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
|
||||
this.$modal.msgError(`上传头像图片大小不能超过 ${this.fileSize} MB!`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
this.loading = this.$loading({
|
||||
lock: true,
|
||||
text: "上传中",
|
||||
background: "rgba(0, 0, 0, 0.7)",
|
||||
});
|
||||
this.$modal.loading("正在上传图片,请稍候...");
|
||||
this.number++;
|
||||
},
|
||||
// 文件个数超出
|
||||
handleExceed() {
|
||||
this.$message.error(`上传文件数量不能超过 ${this.limit} 个!`);
|
||||
this.$modal.msgError(`上传文件数量不能超过 ${this.limit} 个!`);
|
||||
},
|
||||
// 上传失败
|
||||
handleUploadError(res) {
|
||||
this.$message({
|
||||
type: "error",
|
||||
message: "上传失败",
|
||||
});
|
||||
this.loading.close();
|
||||
this.$modal.msgError("上传图片失败,请重试");
|
||||
this.$modal.closeLoading();
|
||||
},
|
||||
// 预览
|
||||
handlePictureCardPreview(file) {
|
||||
|
@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<div :class="{'hidden':hidden}" class="pagination-container">
|
||||
<el-pagination
|
||||
v-if="pageShow"
|
||||
:background="background"
|
||||
:current-page.sync="currentPage"
|
||||
:page-size.sync="pageSize"
|
||||
@ -64,7 +63,6 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
pageShow: true
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@ -88,10 +86,7 @@ export default {
|
||||
methods: {
|
||||
handleSizeChange(val) {
|
||||
if (this.currentPage * val > this.total) {
|
||||
this.pageShow = false;
|
||||
this.$nextTick(() => {
|
||||
this.pageShow = true
|
||||
})
|
||||
this.currentPage = 1
|
||||
}
|
||||
this.$emit('pagination', { page: this.currentPage, limit: val })
|
||||
if (this.autoScroll) {
|
||||
|
@ -4,6 +4,7 @@ import { Message } from 'element-ui'
|
||||
import NProgress from 'nprogress'
|
||||
import 'nprogress/nprogress.css'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import { isRelogin } from '@/utils/request'
|
||||
|
||||
NProgress.configure({ showSpinner: false })
|
||||
|
||||
@ -19,8 +20,10 @@ router.beforeEach((to, from, next) => {
|
||||
NProgress.done()
|
||||
} else {
|
||||
if (store.getters.roles.length === 0) {
|
||||
isRelogin.show = true
|
||||
// 判断当前用户是否已拉取完user_info信息
|
||||
store.dispatch('GetInfo').then(() => {
|
||||
isRelogin.show = false
|
||||
store.dispatch('GenerateRoutes').then(accessRoutes => {
|
||||
// 根据roles权限生成可访问的路由表
|
||||
router.addRoutes(accessRoutes) // 动态添加可访问路由表
|
||||
|
@ -9,7 +9,7 @@ import { saveAs } from 'file-saver'
|
||||
|
||||
let downloadLoadingInstance;
|
||||
// 是否显示重新登录
|
||||
let isReloginShow;
|
||||
export let isRelogin = { show: false };
|
||||
|
||||
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
|
||||
// 对应国际化资源文件后缀
|
||||
@ -78,23 +78,20 @@ service.interceptors.response.use(res => {
|
||||
return res.data
|
||||
}
|
||||
if (code === 401) {
|
||||
if (!isReloginShow) {
|
||||
isReloginShow = true;
|
||||
if (!isRelogin.show) {
|
||||
isRelogin.show = true;
|
||||
MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', {
|
||||
confirmButtonText: '重新登录',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}
|
||||
).then(() => {
|
||||
isReloginShow = false;
|
||||
isRelogin.show = false;
|
||||
store.dispatch('LogOut').then(() => {
|
||||
// 如果是登录页面不需要重新加载
|
||||
if (window.location.hash.indexOf("#/login") != 0) {
|
||||
location.href = process.env.VUE_APP_CONTEXT_PATH + "index";
|
||||
}
|
||||
location.href = process.env.VUE_APP_CONTEXT_PATH + "index";
|
||||
})
|
||||
}).catch(() => {
|
||||
isReloginShow = false;
|
||||
isRelogin.show = false;
|
||||
});
|
||||
}
|
||||
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
|
||||
|
@ -70,6 +70,9 @@ export function addDateRange(params, dateRange, propName) {
|
||||
|
||||
// 回显数据字典
|
||||
export function selectDictLabel(datas, value) {
|
||||
if (value === undefined) {
|
||||
return "";
|
||||
}
|
||||
var actions = [];
|
||||
Object.keys(datas).some((key) => {
|
||||
if (datas[key].value == ('' + value)) {
|
||||
@ -77,23 +80,31 @@ export function selectDictLabel(datas, value) {
|
||||
return true;
|
||||
}
|
||||
})
|
||||
if (actions.length === 0) {
|
||||
actions.push(value);
|
||||
}
|
||||
return actions.join('');
|
||||
}
|
||||
|
||||
// 回显数据字典(字符串数组)
|
||||
export function selectDictLabels(datas, value, separator) {
|
||||
if(value === undefined) {
|
||||
if (value === undefined) {
|
||||
return "";
|
||||
}
|
||||
var actions = [];
|
||||
var currentSeparator = undefined === separator ? "," : separator;
|
||||
var temp = value.split(currentSeparator);
|
||||
Object.keys(value.split(currentSeparator)).some((val) => {
|
||||
var match = false;
|
||||
Object.keys(datas).some((key) => {
|
||||
if (datas[key].value == ('' + temp[val])) {
|
||||
actions.push(datas[key].label + currentSeparator);
|
||||
match = true;
|
||||
}
|
||||
})
|
||||
if (!match) {
|
||||
actions.push(temp[val] + currentSeparator);
|
||||
}
|
||||
})
|
||||
return actions.join('').substring(0, actions.join('').length - 1);
|
||||
}
|
||||
|
@ -101,6 +101,29 @@
|
||||
<span>更新日志</span>
|
||||
</div>
|
||||
<el-collapse accordion>
|
||||
<el-collapse-item title="v4.0.1 - 2022-03-01">
|
||||
<ol>
|
||||
<li>update 图片上传 文件上传 支持并发上传</li>
|
||||
<li>update 组件ImageUpload支持多图同时选择上传</li>
|
||||
<li>udpate 组件fileUpload支持多文件同时选择上传</li>
|
||||
<li>update springboot 2.6.3 => 2.6.4</li>
|
||||
<li>update hutool 5.7.20 => 5.7.21</li>
|
||||
<li>update qiniu 7.9.2 => 7.9.3</li>
|
||||
<li>update minio 8.3.5 => 8.3.7</li>
|
||||
<li>update 优化 R 默认返回 msg</li>
|
||||
<li>update 增加 用户注册 用户类型默认值</li>
|
||||
<li>update 增加用户登出日志</li>
|
||||
<li>update 更新 多用户多设备的注释说明</li>
|
||||
<li>update 优化 是否为管理员的判断</li>
|
||||
<li>update 优化 页面若未匹配到字典标签则返回原字典值</li>
|
||||
<li>update 调整用户登录 将日志调整到最后 防止获取不到用户警告</li>
|
||||
<li>update 优化随机数生成方式 避免容易生成两个相同随机数的问题</li>
|
||||
<li>fix 修复代码生成 基于路径生成 路径为空问题</li>
|
||||
<li>fix 恢复误删 @Async 注解线程池配置类</li>
|
||||
<li>fix 修复 minio 适配 https 导致的问题</li>
|
||||
<li>fix 修复分页组件请求两次问题</li>
|
||||
</ol>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="v4.0.0 - 2022-02-18">
|
||||
<ol>
|
||||
<li>[重大更新] 重写项目整体结构 数据处理下沉至Mapper符合MVC规范 减少循环依赖</li>
|
||||
@ -708,7 +731,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
// 版本号
|
||||
version: "4.0.0",
|
||||
version: "4.0.1",
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
@ -86,7 +86,8 @@ export default {
|
||||
password: "",
|
||||
confirmPassword: "",
|
||||
code: "",
|
||||
uuid: ""
|
||||
uuid: "",
|
||||
user_type: "sys_user"
|
||||
},
|
||||
registerRules: {
|
||||
username: [
|
||||
|
@ -206,7 +206,7 @@ export default {
|
||||
email: [
|
||||
{
|
||||
type: "email",
|
||||
message: "'请输入正确的邮箱地址",
|
||||
message: "请输入正确的邮箱地址",
|
||||
trigger: ["blur", "change"]
|
||||
}
|
||||
],
|
||||
|
@ -78,7 +78,7 @@
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
<el-button
|
||||
size="mini"
|
||||
type="text"
|
||||
icon="el-icon-edit"
|
||||
@ -199,7 +199,7 @@
|
||||
<el-form-item>
|
||||
<el-input v-model="form.perms" placeholder="请输入权限标识" maxlength="100" />
|
||||
<span slot="label">
|
||||
<el-tooltip content="控制器中定义的权限字符,如:@PreAuthorize(`@ss.hasPermi('system:user:list')`)" placement="top">
|
||||
<el-tooltip content="控制器中定义的权限字符,如:@SaCheckPermission('system:user:list')" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
权限字符
|
||||
|
@ -135,7 +135,7 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="公告类型" prop="noticeType">
|
||||
<el-select v-model="form.noticeType" placeholder="请选择">
|
||||
<el-select v-model="form.noticeType" placeholder="请选择公告类型">
|
||||
<el-option
|
||||
v-for="dict in dict.type.sys_notice_type"
|
||||
:key="dict.value"
|
||||
|
@ -248,7 +248,7 @@
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="用户性别">
|
||||
<el-select v-model="form.sex" placeholder="请选择">
|
||||
<el-select v-model="form.sex" placeholder="请选择性别">
|
||||
<el-option
|
||||
v-for="dict in dict.type.sys_user_sex"
|
||||
:key="dict.value"
|
||||
@ -273,7 +273,7 @@
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="岗位">
|
||||
<el-select v-model="form.postIds" multiple placeholder="请选择">
|
||||
<el-select v-model="form.postIds" multiple placeholder="请选择岗位">
|
||||
<el-option
|
||||
v-for="item in postOptions"
|
||||
:key="item.postId"
|
||||
@ -286,7 +286,7 @@
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="角色">
|
||||
<el-select v-model="form.roleIds" multiple placeholder="请选择">
|
||||
<el-select v-model="form.roleIds" multiple placeholder="请选择角色">
|
||||
<el-option
|
||||
v-for="item in roleOptions"
|
||||
:key="item.roleId"
|
||||
@ -443,7 +443,7 @@ export default {
|
||||
email: [
|
||||
{
|
||||
type: "email",
|
||||
message: "'请输入正确的邮箱地址",
|
||||
message: "请输入正确的邮箱地址",
|
||||
trigger: ["blur", "change"]
|
||||
}
|
||||
],
|
||||
|
@ -42,7 +42,7 @@ export default {
|
||||
{ required: true, message: "邮箱地址不能为空", trigger: "blur" },
|
||||
{
|
||||
type: "email",
|
||||
message: "'请输入正确的邮箱地址",
|
||||
message: "请输入正确的邮箱地址",
|
||||
trigger: ["blur", "change"]
|
||||
}
|
||||
],
|
||||
|
@ -89,12 +89,14 @@ services:
|
||||
MINIO_ACCESS_KEY: ruoyi
|
||||
# 管理后台密码,最小8个字符
|
||||
MINIO_SECRET_KEY: ruoyi123
|
||||
# https需要指定域名
|
||||
MINIO_SERVER_URL: ""
|
||||
volumes:
|
||||
# 映射当前目录下的data目录至容器内/data目录
|
||||
- /docker/minio/data:/data
|
||||
# 映射配置目录
|
||||
- /docker/minio/config:/root/.minio/
|
||||
command: server --console-address ':9001' /data # 指定容器中的目录 /data
|
||||
command: server --address ':9000' --console-address ':9001' /data # 指定容器中的目录 /data
|
||||
privileged: true
|
||||
restart: always
|
||||
networks:
|
||||
@ -102,7 +104,7 @@ services:
|
||||
ipv4_address: 172.30.0.54
|
||||
|
||||
ruoyi-server1:
|
||||
image: ruoyi/ruoyi-server:4.0.0
|
||||
image: ruoyi/ruoyi-server:4.0.1
|
||||
container_name: ruoyi-server1
|
||||
environment:
|
||||
# 时区上海
|
||||
@ -117,7 +119,7 @@ services:
|
||||
ipv4_address: 172.30.0.60
|
||||
|
||||
ruoyi-server2:
|
||||
image: "ruoyi/ruoyi-server:4.0.0"
|
||||
image: "ruoyi/ruoyi-server:4.0.1"
|
||||
container_name: ruoyi-server2
|
||||
environment:
|
||||
# 时区上海
|
||||
@ -132,7 +134,7 @@ services:
|
||||
ipv4_address: 172.30.0.61
|
||||
|
||||
ruoyi-monitor-admin:
|
||||
image: ruoyi/ruoyi-monitor-admin:4.0.0
|
||||
image: ruoyi/ruoyi-monitor-admin:4.0.1
|
||||
container_name: ruoyi-monitor-admin
|
||||
environment:
|
||||
# 时区上海
|
||||
@ -147,7 +149,7 @@ services:
|
||||
ipv4_address: 172.30.0.90
|
||||
|
||||
ruoyi-xxl-job-admin:
|
||||
image: ruoyi/ruoyi-xxl-job-admin:4.0.0
|
||||
image: ruoyi/ruoyi-xxl-job-admin:4.0.1
|
||||
container_name: ruoyi-xxl-job-admin
|
||||
environment:
|
||||
# 时区上海
|
||||
|
@ -66,7 +66,7 @@ create table sys_user (
|
||||
-- 初始化-用户信息表数据
|
||||
-- ----------------------------
|
||||
insert into sys_user values(1, 103, 'admin', '疯狂的狮子Li', 'sys_user', 'crazyLionLi@163.com', '15888888888', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '管理员');
|
||||
insert into sys_user values(2, 105, 'lionli', '疯狂的狮子Li', 'sys_user', 'crazyLionLi@163.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '测试员');
|
||||
insert into sys_user values(2, 105, 'lionli', '疯狂的狮子Li', 'sys_user', 'crazyLionLi@qq.com', '15666666666', '1', '', '$2a$10$7JB720yubVSZvUI0rEqK/.VqGOZTH.ulu33dHOiBE8ByOhJIrdAu2', '0', '0', '127.0.0.1', sysdate(), 'admin', sysdate(), '', null, '测试员');
|
||||
|
||||
|
||||
-- ----------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user