Merge branch 'master' of gitee.com:y_project/RuoYi-Cloud into master

Signed-off-by: 零〇°度 <990130556@qq.com>
pull/316/head
零〇°度 2 years ago committed by Gitee
commit 7848c1d7d0

@ -1,11 +1,11 @@
<p align="center"> <p align="center">
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-b99b286755aef70355a7084753f89cdb7c9.png"> <img alt="logo" src="https://oscimg.oschina.net/oscnet/up-b99b286755aef70355a7084753f89cdb7c9.png">
</p> </p>
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.6.2</h1> <h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.6.3</h1>
<h4 align="center">基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构</h4> <h4 align="center">基于 Vue/Element UI 和 Spring Boot/Spring Cloud & Alibaba 前后端分离的分布式微服务架构</h4>
<p align="center"> <p align="center">
<a href="https://gitee.com/y_project/RuoYi-Cloud/stargazers"><img src="https://gitee.com/y_project/RuoYi-Cloud/badge/star.svg?theme=dark"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud/stargazers"><img src="https://gitee.com/y_project/RuoYi-Cloud/badge/star.svg?theme=dark"></a>
<a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.6.2-brightgreen.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud"><img src="https://img.shields.io/badge/RuoYi-v3.6.3-brightgreen.svg"></a>
<a href="https://gitee.com/y_project/RuoYi-Cloud/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a> <a href="https://gitee.com/y_project/RuoYi-Cloud/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
</p> </p>
@ -128,4 +128,4 @@ com.ruoyi
## 若依微服务交流群 ## 若依微服务交流群
QQ群 [![加入QQ群](https://img.shields.io/badge/已满-42799195-blue.svg)](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [![加入QQ群](https://img.shields.io/badge/已满-170157040-blue.svg)](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [![加入QQ群](https://img.shields.io/badge/已满-130643120-blue.svg)](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [![加入QQ群](https://img.shields.io/badge/已满-225920371-blue.svg)](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [![加入QQ群](https://img.shields.io/badge/已满-201705537-blue.svg)](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [![加入QQ群](https://img.shields.io/badge/已满-236543183-blue.svg)](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) [![加入QQ群](https://img.shields.io/badge/已满-213618602-blue.svg)](https://jq.qq.com/?_wv=1027&k=nw3OiyXs) [![加入QQ群](https://img.shields.io/badge/已满-148794840-blue.svg)](https://jq.qq.com/?_wv=1027&k=kiU5WDls) [![加入QQ群](https://img.shields.io/badge/已满-118752664-blue.svg)](https://jq.qq.com/?_wv=1027&k=MtBy6YfT) [![加入QQ群](https://img.shields.io/badge/101038945-blue.svg)](https://jq.qq.com/?_wv=1027&k=FqImHgH2) 点击按钮入群。 QQ群 [![加入QQ群](https://img.shields.io/badge/已满-42799195-blue.svg)](https://jq.qq.com/?_wv=1027&k=yqInfq0S) [![加入QQ群](https://img.shields.io/badge/已满-170157040-blue.svg)](https://jq.qq.com/?_wv=1027&k=Oy1mb3p8) [![加入QQ群](https://img.shields.io/badge/已满-130643120-blue.svg)](https://jq.qq.com/?_wv=1027&k=rvxkJtXK) [![加入QQ群](https://img.shields.io/badge/已满-225920371-blue.svg)](https://jq.qq.com/?_wv=1027&k=0Ck3PvTe) [![加入QQ群](https://img.shields.io/badge/已满-201705537-blue.svg)](https://jq.qq.com/?_wv=1027&k=FnHHP4TT) [![加入QQ群](https://img.shields.io/badge/已满-236543183-blue.svg)](https://jq.qq.com/?_wv=1027&k=qdT1Ojpz) [![加入QQ群](https://img.shields.io/badge/已满-213618602-blue.svg)](https://jq.qq.com/?_wv=1027&k=nw3OiyXs) [![加入QQ群](https://img.shields.io/badge/已满-148794840-blue.svg)](https://jq.qq.com/?_wv=1027&k=kiU5WDls) [![加入QQ群](https://img.shields.io/badge/已满-118752664-blue.svg)](https://jq.qq.com/?_wv=1027&k=MtBy6YfT) [![加入QQ群](https://img.shields.io/badge/已满-101038945-blue.svg)](https://jq.qq.com/?_wv=1027&k=FqImHgH2) [![加入QQ群](https://img.shields.io/badge/128355254-blue.svg)](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=G4jZ4EtdT50PhnMBudTnEwgonxkXOscJ&authKey=FkGHYfoTKlGE6wHdKdjH9bVoOgQjtLP9WM%2Fj7pqGY1msoqw9uxDiBo39E2mLgzYg&noverify=0&group_code=128355254) 点击按钮入群。

@ -9,8 +9,8 @@ usage() {
# copy sql # copy sql
echo "begin copy sql " echo "begin copy sql "
cp ../sql/ry_20220814.sql ./mysql/db cp ../sql/ry_20230706.sql ./mysql/db
cp ../sql/ry_config_20220510.sql ./mysql/db cp ../sql/ry_config_20220929.sql ./mysql/db
# copy html # copy html
echo "begin copy html " echo "begin copy html "

@ -14,23 +14,28 @@ http {
listen 80; listen 80;
server_name localhost; server_name localhost;
location / { location / {
root /home/ruoyi/projects/ruoyi-ui; root /home/ruoyi/projects/ruoyi-ui;
try_files $uri $uri/ /index.html; try_files $uri $uri/ /index.html;
index index.html index.htm; index index.html index.htm;
} }
location /prod-api/{ location /prod-api/{
proxy_set_header Host $http_host; proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://ruoyi-gateway:8080/; proxy_pass http://ruoyi-gateway:8080/;
} }
# 避免actuator暴露
if ($request_uri ~ "/actuator") {
return 403;
}
error_page 500 502 503 504 /50x.html; error_page 500 502 503 504 /50x.html;
location = /50x.html { location = /50x.html {
root html; root html;
} }
} }
}# requirepass 123456 }

@ -6,35 +6,35 @@
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
<name>ruoyi</name> <name>ruoyi</name>
<url>http://www.ruoyi.vip</url> <url>http://www.ruoyi.vip</url>
<description>若依微服务系统</description> <description>若依微服务系统</description>
<properties> <properties>
<ruoyi.version>3.6.2</ruoyi.version> <ruoyi.version>3.6.3</ruoyi.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<spring-boot.version>2.7.7</spring-boot.version> <spring-boot.version>2.7.13</spring-boot.version>
<spring-cloud.version>2021.0.5</spring-cloud.version> <spring-cloud.version>2021.0.8</spring-cloud.version>
<spring-cloud-alibaba.version>2021.0.4.0</spring-cloud-alibaba.version> <spring-cloud-alibaba.version>2021.0.5.0</spring-cloud-alibaba.version>
<spring-boot-admin.version>2.7.10</spring-boot-admin.version> <spring-boot-admin.version>2.7.10</spring-boot-admin.version>
<swagger.fox.version>3.0.0</swagger.fox.version> <swagger.fox.version>3.0.0</swagger.fox.version>
<swagger.core.version>1.6.2</swagger.core.version> <swagger.core.version>1.6.2</swagger.core.version>
<tobato.version>1.27.2</tobato.version> <tobato.version>1.27.2</tobato.version>
<kaptcha.version>2.3.3</kaptcha.version> <kaptcha.version>2.3.3</kaptcha.version>
<pagehelper.boot.version>1.4.6</pagehelper.boot.version> <pagehelper.boot.version>1.4.7</pagehelper.boot.version>
<druid.version>1.2.16</druid.version> <druid.version>1.2.16</druid.version>
<dynamic-ds.version>3.6.1</dynamic-ds.version> <dynamic-ds.version>3.6.1</dynamic-ds.version>
<commons.io.version>2.11.0</commons.io.version> <commons.io.version>2.13.0</commons.io.version>
<velocity.version>2.3</velocity.version> <velocity.version>2.3</velocity.version>
<fastjson.version>2.0.25</fastjson.version> <fastjson.version>2.0.39</fastjson.version>
<jjwt.version>0.9.1</jjwt.version> <jjwt.version>0.9.1</jjwt.version>
<minio.version>8.2.2</minio.version> <minio.version>8.2.2</minio.version>
<poi.version>4.1.2</poi.version> <poi.version>4.1.2</poi.version>
<transmittable-thread-local.version>2.14.2</transmittable-thread-local.version> <transmittable-thread-local.version>2.14.3</transmittable-thread-local.version>
</properties> </properties>
<!-- 依赖声明 --> <!-- 依赖声明 -->

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-api</artifactId> <artifactId>ruoyi-api</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -28,13 +28,13 @@ public class RemoteLogFallbackFactory implements FallbackFactory<RemoteLogServic
@Override @Override
public R<Boolean> saveLog(SysOperLog sysOperLog, String source) public R<Boolean> saveLog(SysOperLog sysOperLog, String source)
{ {
return null; return R.fail("保存操作日志失败:" + throwable.getMessage());
} }
@Override @Override
public R<Boolean> saveLogininfor(SysLogininfor sysLogininfor, String source) public R<Boolean> saveLogininfor(SysLogininfor sysLogininfor, String source)
{ {
return null; return R.fail("保存登录日志失败:" + throwable.getMessage());
} }
}; };

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -54,12 +54,12 @@ public @interface Excel
public int roundingMode() default BigDecimal.ROUND_HALF_EVEN; public int roundingMode() default BigDecimal.ROUND_HALF_EVEN;
/** /**
* excel * excel
*/ */
public double height() default 14; public double height() default 14;
/** /**
* excel * excel
*/ */
public double width() default 16; public double width() default 16;
@ -109,7 +109,7 @@ public @interface Excel
public ColumnType cellType() default ColumnType.STRING; public ColumnType cellType() default ColumnType.STRING;
/** /**
* *
*/ */
public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT; public IndexedColors headerBackgroundColor() default IndexedColors.GREY_50_PERCENT;
@ -119,7 +119,7 @@ public @interface Excel
public IndexedColors headerColor() default IndexedColors.WHITE; public IndexedColors headerColor() default IndexedColors.WHITE;
/** /**
* *
*/ */
public IndexedColors backgroundColor() default IndexedColors.WHITE; public IndexedColors backgroundColor() default IndexedColors.WHITE;

@ -117,6 +117,11 @@ public class Constants
*/ */
public static final String RESOURCE_PREFIX = "/profile"; public static final String RESOURCE_PREFIX = "/profile";
/**
* json
*/
public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi" };
/** /**
* 访 * 访
*/ */

@ -139,7 +139,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
/** /**
* *
* *
* @param endTime * @param endDate
* @param startTime * @param startTime
* @return // * @return //
*/ */

@ -295,9 +295,9 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
} }
/** /**
* setarray arrayvalue * collectionarray arrayvalue
* *
* @param set * @param collection
* @param array * @param array
* @return boolean * @return boolean
*/ */

@ -126,15 +126,8 @@ public class FileUtils
{ {
return false; return false;
} }
// 判断是否在允许下载的文件规则内
// 检查允许下载的文件规则 return ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource));
if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
{
return true;
}
// 不在允许下载的文件规则
return false;
} }
/** /**

@ -1,5 +1,8 @@
package com.ruoyi.common.core.utils.poi; package com.ruoyi.common.core.utils.poi;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Workbook;
/** /**
* Excel * Excel
* *
@ -12,8 +15,10 @@ public interface ExcelHandlerAdapter
* *
* @param value * @param value
* @param args excelargs * @param args excelargs
* @param cell
* @param wb 簿
* *
* @return * @return
*/ */
Object format(Object value, String[] args); Object format(Object value, String[] args, Cell cell, Workbook wb);
} }

@ -55,6 +55,7 @@ import com.ruoyi.common.core.annotation.Excel;
import com.ruoyi.common.core.annotation.Excel.ColumnType; import com.ruoyi.common.core.annotation.Excel.ColumnType;
import com.ruoyi.common.core.annotation.Excel.Type; import com.ruoyi.common.core.annotation.Excel.Type;
import com.ruoyi.common.core.annotation.Excels; import com.ruoyi.common.core.annotation.Excels;
import com.ruoyi.common.core.exception.UtilException;
import com.ruoyi.common.core.text.Convert; import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.core.utils.DateUtils; import com.ruoyi.common.core.utils.DateUtils;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
@ -260,9 +261,23 @@ public class ExcelUtil<T>
* @param is * @param is
* @return * @return
*/ */
public List<T> importExcel(InputStream is) throws Exception public List<T> importExcel(InputStream is)
{ {
return importExcel(is, 0); List<T> list = null;
try
{
list = importExcel(is, 0);
}
catch (Exception e)
{
log.error("导入Excel异常{}", e.getMessage());
throw new UtilException(e.getMessage());
}
finally
{
IOUtils.closeQuietly(is);
}
return list;
} }
/** /**
@ -299,7 +314,6 @@ public class ExcelUtil<T>
// 获取最后一个非空行的行下标比如总行数为n则返回的为n-1 // 获取最后一个非空行的行下标比如总行数为n则返回的为n-1
int rows = sheet.getLastRowNum(); int rows = sheet.getLastRowNum();
if (rows > 0) if (rows > 0)
{ {
// 定义一个map用于存放excel列的序号和field. // 定义一个map用于存放excel列的序号和field.
@ -414,13 +428,13 @@ public class ExcelUtil<T>
{ {
propertyName = field.getName() + "." + attr.targetAttr(); propertyName = field.getName() + "." + attr.targetAttr();
} }
else if (StringUtils.isNotEmpty(attr.readConverterExp())) if (StringUtils.isNotEmpty(attr.readConverterExp()))
{ {
val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator()); val = reverseByExp(Convert.toStr(val), attr.readConverterExp(), attr.separator());
} }
else if (!attr.handler().equals(ExcelHandlerAdapter.class)) else if (!attr.handler().equals(ExcelHandlerAdapter.class))
{ {
val = dataFormatHandlerAdapter(val, attr); val = dataFormatHandlerAdapter(val, attr, null);
} }
ReflectUtils.invokeSetter(entity, propertyName, val); ReflectUtils.invokeSetter(entity, propertyName, val);
} }
@ -910,7 +924,7 @@ public class ExcelUtil<T>
} }
else if (!attr.handler().equals(ExcelHandlerAdapter.class)) else if (!attr.handler().equals(ExcelHandlerAdapter.class))
{ {
cell.setCellValue(dataFormatHandlerAdapter(value, attr)); cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell));
} }
else else
{ {
@ -1097,13 +1111,13 @@ public class ExcelUtil<T>
* @param excel * @param excel
* @return * @return
*/ */
public String dataFormatHandlerAdapter(Object value, Excel excel) public String dataFormatHandlerAdapter(Object value, Excel excel, Cell cell)
{ {
try try
{ {
Object instance = excel.handler().newInstance(); Object instance = excel.handler().newInstance();
Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class }); Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class });
value = formatMethod.invoke(instance, value, excel.args()); value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb);
} }
catch (Exception e) catch (Exception e)
{ {

@ -20,6 +20,11 @@ public class SqlUtil
*/ */
public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+"; public static String SQL_PATTERN = "[a-zA-Z0-9_\\ \\,\\.]+";
/**
* orderBy
*/
private static final int ORDER_BY_MAX_LENGTH = 500;
/** /**
* *
*/ */
@ -29,6 +34,10 @@ public class SqlUtil
{ {
throw new UtilException("参数不符合规范,不能进行查询"); throw new UtilException("参数不符合规范,不能进行查询");
} }
if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH)
{
throw new UtilException("参数已超过最大限制,不能进行查询");
}
return value; return value;
} }

@ -66,7 +66,7 @@ public final class UUID implements java.io.Serializable, Comparable<UUID>
} }
/** /**
* 4UUID 使线 UUID * 4UUID
* *
* @return {@code UUID} * @return {@code UUID}
*/ */

@ -180,6 +180,16 @@ public class AjaxResult extends HashMap<String, Object>
return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG)); return Objects.equals(HttpStatus.SUCCESS, this.get(CODE_TAG));
} }
/**
*
*
* @return
*/
public boolean isWarn()
{
return Objects.equals(HttpStatus.WARN, this.get(CODE_TAG));
}
/** /**
* *
* *
@ -187,7 +197,7 @@ public class AjaxResult extends HashMap<String, Object>
*/ */
public boolean isError() public boolean isError()
{ {
return !isSuccess(); return Objects.equals(HttpStatus.ERROR, this.get(CODE_TAG));
} }
/** /**

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -6,6 +6,8 @@ import org.springframework.data.redis.serializer.SerializationException;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONReader; import com.alibaba.fastjson2.JSONReader;
import com.alibaba.fastjson2.JSONWriter; import com.alibaba.fastjson2.JSONWriter;
import com.alibaba.fastjson2.filter.Filter;
import com.ruoyi.common.core.constant.Constants;
/** /**
* Redis使FastJson * Redis使FastJson
@ -16,8 +18,9 @@ public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
{ {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class<T> clazz; static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constants.JSON_WHITELIST_STR);
private Class<T> clazz;
public FastJson2JsonRedisSerializer(Class<T> clazz) public FastJson2JsonRedisSerializer(Class<T> clazz)
{ {
@ -44,6 +47,6 @@ public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
} }
String str = new String(bytes, DEFAULT_CHARSET); String str = new String(bytes, DEFAULT_CHARSET);
return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType); return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER);
} }
} }

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -1,13 +1,5 @@
package com.ruoyi.common.security.handler; package com.ruoyi.common.security.handler;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.ruoyi.common.core.constant.HttpStatus; import com.ruoyi.common.core.constant.HttpStatus;
import com.ruoyi.common.core.exception.DemoModeException; import com.ruoyi.common.core.exception.DemoModeException;
import com.ruoyi.common.core.exception.InnerAuthException; import com.ruoyi.common.core.exception.InnerAuthException;
@ -16,10 +8,20 @@ import com.ruoyi.common.core.exception.auth.NotPermissionException;
import com.ruoyi.common.core.exception.auth.NotRoleException; import com.ruoyi.common.core.exception.auth.NotRoleException;
import com.ruoyi.common.core.utils.StringUtils; import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.core.web.domain.AjaxResult; import com.ruoyi.common.core.web.domain.AjaxResult;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.BindException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;
import javax.servlet.http.HttpServletRequest;
/** /**
* *
* *
* @author ruoyi * @author ruoyi
*/ */
@RestControllerAdvice @RestControllerAdvice
@ -53,8 +55,7 @@ public class GlobalExceptionHandler
* *
*/ */
@ExceptionHandler(HttpRequestMethodNotSupportedException.class) @ExceptionHandler(HttpRequestMethodNotSupportedException.class)
public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, public AjaxResult handleHttpRequestMethodNotSupported(HttpRequestMethodNotSupportedException e, HttpServletRequest request)
HttpServletRequest request)
{ {
String requestURI = request.getRequestURI(); String requestURI = request.getRequestURI();
log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod()); log.error("请求地址'{}',不支持'{}'请求", requestURI, e.getMethod());
@ -72,6 +73,28 @@ public class GlobalExceptionHandler
return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage()); return StringUtils.isNotNull(code) ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
} }
/**
*
*/
@ExceptionHandler(MissingPathVariableException.class)
public AjaxResult handleMissingPathVariableException(MissingPathVariableException e, HttpServletRequest request)
{
String requestURI = request.getRequestURI();
log.error("请求路径中缺少必需的路径变量'{}',发生系统异常.", requestURI, e);
return AjaxResult.error(String.format("请求路径中缺少必需的路径变量[%s]", e.getVariableName()));
}
/**
*
*/
@ExceptionHandler(MethodArgumentTypeMismatchException.class)
public AjaxResult handleMethodArgumentTypeMismatchException(MethodArgumentTypeMismatchException e, HttpServletRequest request)
{
String requestURI = request.getRequestURI();
log.error("请求参数类型不匹配'{}',发生系统异常.", requestURI, e);
return AjaxResult.error(String.format("请求参数类型不匹配,参数[%s]要求类型为:'%s',但输入值为:'%s'", e.getName(), e.getRequiredType().getName(), e.getValue()));
}
/** /**
* *
*/ */

@ -4,6 +4,8 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import com.ruoyi.common.core.constant.CacheConstants; import com.ruoyi.common.core.constant.CacheConstants;
@ -25,6 +27,8 @@ import com.ruoyi.system.api.model.LoginUser;
@Component @Component
public class TokenService public class TokenService
{ {
private static final Logger log = LoggerFactory.getLogger(TokenService.class);
@Autowired @Autowired
private RedisService redisService; private RedisService redisService;
@ -106,6 +110,7 @@ public class TokenService
} }
catch (Exception e) catch (Exception e)
{ {
log.error("获取用户信息异常'{}'", e.getMessage());
} }
return user; return user;
} }

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-common</artifactId> <artifactId>ruoyi-common</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -87,7 +87,7 @@ public class XssFilter implements GlobalFilter, Ordered
// 防xss攻击过滤 // 防xss攻击过滤
bodyStr = EscapeUtil.clean(bodyStr); bodyStr = EscapeUtil.clean(bodyStr);
// 转成字节 // 转成字节
byte[] bytes = bodyStr.getBytes(); byte[] bytes = bodyStr.getBytes(StandardCharsets.UTF_8);
NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT); NettyDataBufferFactory nettyDataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);
DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length); DataBuffer buffer = nettyDataBufferFactory.allocateBuffer(bytes.length);
buffer.write(bytes); buffer.write(bytes);

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -1,6 +1,7 @@
package com.ruoyi.file.service; package com.ruoyi.file.service;
import java.io.InputStream; import java.io.InputStream;
import com.alibaba.nacos.common.utils.IoUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
@ -39,7 +40,7 @@ public class FastDfsSysFileServiceImpl implements ISysFileService
InputStream inputStream = file.getInputStream(); InputStream inputStream = file.getInputStream();
StorePath storePath = storageClient.uploadFile(inputStream, file.getSize(), StorePath storePath = storageClient.uploadFile(inputStream, file.getSize(),
FileTypeUtils.getExtension(file), null); FileTypeUtils.getExtension(file), null);
inputStream.close(); IoUtils.closeQuietly(inputStream);
return domain + "/" + storePath.getFullPath(); return domain + "/" + storePath.getFullPath();
} }
} }

@ -4,6 +4,7 @@ import java.io.InputStream;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import com.alibaba.nacos.common.utils.IoUtils;
import com.ruoyi.file.config.MinioConfig; import com.ruoyi.file.config.MinioConfig;
import com.ruoyi.file.utils.FileUploadUtils; import com.ruoyi.file.utils.FileUploadUtils;
import io.minio.MinioClient; import io.minio.MinioClient;
@ -42,7 +43,7 @@ public class MinioSysFileServiceImpl implements ISysFileService
.contentType(file.getContentType()) .contentType(file.getContentType())
.build(); .build();
client.putObject(args); client.putObject(args);
inputStream.close(); IoUtils.closeQuietly(inputStream);
return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName; return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
} }
} }

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -56,8 +56,8 @@
<!-- Mysql Connector --> <!-- Mysql Connector -->
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>com.mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-j</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Log --> <!-- RuoYi Common Log -->

@ -12,7 +12,7 @@ import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
* @author ruoyi * @author ruoyi
*/ */
@EnableCustomConfig @EnableCustomConfig
@EnableCustomSwagger2 @EnableCustomSwagger2
@EnableRyFeignClients @EnableRyFeignClients
@SpringBootApplication @SpringBootApplication
public class RuoYiGenApplication public class RuoYiGenApplication

@ -3,7 +3,7 @@
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ruoyi.gen.mapper.GenTableColumnMapper"> <mapper namespace="com.ruoyi.gen.mapper.GenTableColumnMapper">
<resultMap type="GenTableColumn" id="GenTableColumnResult"> <resultMap type="GenTableColumn" id="GenTableColumnResult">
<id property="columnId" column="column_id" /> <id property="columnId" column="column_id" />
<result property="tableId" column="table_id" /> <result property="tableId" column="table_id" />
@ -28,23 +28,23 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateBy" column="update_by" /> <result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" /> <result property="updateTime" column="update_time" />
</resultMap> </resultMap>
<sql id="selectGenTableColumnVo"> <sql id="selectGenTableColumnVo">
select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column select column_id, table_id, column_name, column_comment, column_type, java_type, java_field, is_pk, is_increment, is_required, is_insert, is_edit, is_list, is_query, query_type, html_type, dict_type, sort, create_by, create_time, update_by, update_time from gen_table_column
</sql> </sql>
<select id="selectGenTableColumnListByTableId" parameterType="GenTableColumn" resultMap="GenTableColumnResult"> <select id="selectGenTableColumnListByTableId" parameterType="GenTableColumn" resultMap="GenTableColumnResult">
<include refid="selectGenTableColumnVo"/> <include refid="selectGenTableColumnVo"/>
where table_id = #{tableId} where table_id = #{tableId}
order by sort order by sort
</select> </select>
<select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult"> <select id="selectDbTableColumnsByName" parameterType="String" resultMap="GenTableColumnResult">
select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type select column_name, (case when (is_nullable = 'no' <![CDATA[ && ]]> column_key != 'PRI') then '1' else null end) as is_required, (case when column_key = 'PRI' then '1' else '0' end) as is_pk, ordinal_position as sort, column_comment, (case when extra = 'auto_increment' then '1' else '0' end) as is_increment, column_type
from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName}) from information_schema.columns where table_schema = (select database()) and table_name = (#{tableName})
order by ordinal_position order by ordinal_position
</select> </select>
<insert id="insertGenTableColumn" parameterType="GenTableColumn" useGeneratedKeys="true" keyProperty="columnId"> <insert id="insertGenTableColumn" parameterType="GenTableColumn" useGeneratedKeys="true" keyProperty="columnId">
insert into gen_table_column ( insert into gen_table_column (
<if test="tableId != null and tableId != ''">table_id,</if> <if test="tableId != null and tableId != ''">table_id,</if>
@ -88,7 +88,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
sysdate() sysdate()
) )
</insert> </insert>
<update id="updateGenTableColumn" parameterType="GenTableColumn"> <update id="updateGenTableColumn" parameterType="GenTableColumn">
update gen_table_column update gen_table_column
<set> <set>
@ -111,14 +111,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</update> </update>
<delete id="deleteGenTableColumnByIds" parameterType="Long"> <delete id="deleteGenTableColumnByIds" parameterType="Long">
delete from gen_table_column where table_id in delete from gen_table_column where table_id in
<foreach collection="array" item="tableId" open="(" separator="," close=")"> <foreach collection="array" item="tableId" open="(" separator="," close=")">
#{tableId} #{tableId}
</foreach> </foreach>
</delete> </delete>
<delete id="deleteGenTableColumns"> <delete id="deleteGenTableColumns">
delete from gen_table_column where column_id in delete from gen_table_column where column_id in
<foreach collection="list" item="item" open="(" separator="," close=")"> <foreach collection="list" item="item" open="(" separator="," close=")">
#{item.columnId} #{item.columnId}
</foreach> </foreach>

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -62,8 +62,8 @@
<!-- Mysql Connector --> <!-- Mysql Connector -->
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>com.mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-j</artifactId>
</dependency> </dependency>
<!-- RuoYi Common Log --> <!-- RuoYi Common Log -->

@ -12,8 +12,8 @@ import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
* @author ruoyi * @author ruoyi
*/ */
@EnableCustomConfig @EnableCustomConfig
@EnableCustomSwagger2 @EnableCustomSwagger2
@EnableRyFeignClients @EnableRyFeignClients
@SpringBootApplication @SpringBootApplication
public class RuoYiJobApplication public class RuoYiJobApplication
{ {

@ -34,7 +34,7 @@ public class JobInvokeUtil
} }
else else
{ {
Object bean = Class.forName(beanName).newInstance(); Object bean = Class.forName(beanName).getDeclaredConstructor().newInstance();
invokeMethod(bean, methodName, methodParams); invokeMethod(bean, methodName, methodParams);
} }
} }

@ -134,6 +134,8 @@ public class ScheduleUtils
return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR); return StringUtils.containsAnyIgnoreCase(invokeTarget, Constants.JOB_WHITELIST_STR);
} }
Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]); Object obj = SpringUtils.getBean(StringUtils.split(invokeTarget, ".")[0]);
return StringUtils.containsAnyIgnoreCase(obj.getClass().getPackage().getName(), Constants.JOB_WHITELIST_STR); String beanPackageName = obj.getClass().getPackage().getName();
return StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_WHITELIST_STR)
&& !StringUtils.containsAnyIgnoreCase(beanPackageName, Constants.JOB_ERROR_STR);
} }
} }

@ -5,7 +5,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-modules</artifactId> <artifactId>ruoyi-modules</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -50,8 +50,8 @@
<!-- Mysql Connector --> <!-- Mysql Connector -->
<dependency> <dependency>
<groupId>mysql</groupId> <groupId>com.mysql</groupId>
<artifactId>mysql-connector-java</artifactId> <artifactId>mysql-connector-j</artifactId>
</dependency> </dependency>
<!-- RuoYi Common DataSource --> <!-- RuoYi Common DataSource -->

@ -66,27 +66,22 @@ public class SysProfileController extends BaseController
public AjaxResult updateProfile(@RequestBody SysUser user) public AjaxResult updateProfile(@RequestBody SysUser user)
{ {
LoginUser loginUser = SecurityUtils.getLoginUser(); LoginUser loginUser = SecurityUtils.getLoginUser();
SysUser sysUser = loginUser.getSysUser(); SysUser currentUser = loginUser.getSysUser();
user.setUserName(sysUser.getUserName()); currentUser.setNickName(user.getNickName());
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) currentUser.setEmail(user.getEmail());
currentUser.setPhonenumber(user.getPhonenumber());
currentUser.setSex(user.getSex());
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(currentUser))
{ {
return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在"); return error("修改用户'" + user.getUserName() + "'失败,手机号码已存在");
} }
else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
{ {
return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在"); return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
} }
user.setUserId(sysUser.getUserId()); if (userService.updateUserProfile(currentUser) > 0)
user.setPassword(null);
user.setAvatar(null);
user.setDeptId(null);
if (userService.updateUserProfile(user) > 0)
{ {
// 更新缓存用户信息 // 更新缓存用户信息
loginUser.getSysUser().setNickName(user.getNickName());
loginUser.getSysUser().setPhonenumber(user.getPhonenumber());
loginUser.getSysUser().setEmail(user.getEmail());
loginUser.getSysUser().setSex(user.getSex());
tokenService.setLoginUser(loginUser); tokenService.setLoginUser(loginUser);
return success(); return success();
} }

@ -5,6 +5,7 @@ import java.util.List;
import java.util.Set; import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import com.ruoyi.system.api.domain.SysRole; import com.ruoyi.system.api.domain.SysRole;
import com.ruoyi.system.api.domain.SysUser; import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.service.ISysMenuService; import com.ruoyi.system.service.ISysMenuService;
@ -65,7 +66,7 @@ public class SysPermissionServiceImpl implements ISysPermissionService
else else
{ {
List<SysRole> roles = user.getRoles(); List<SysRole> roles = user.getRoles();
if (!roles.isEmpty() && roles.size() > 1) if (!CollectionUtils.isEmpty(roles))
{ {
// 多角色设置permissions属性以便数据权限匹配权限 // 多角色设置permissions属性以便数据权限匹配权限
for (SysRole role : roles) for (SysRole role : roles)

@ -501,17 +501,18 @@ public class SysUserServiceImpl implements ISysUserService
BeanValidators.validateWithException(validator, user); BeanValidators.validateWithException(validator, user);
user.setPassword(SecurityUtils.encryptPassword(password)); user.setPassword(SecurityUtils.encryptPassword(password));
user.setCreateBy(operName); user.setCreateBy(operName);
this.insertUser(user); userMapper.insertUser(user);
successNum++; successNum++;
successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 导入成功"); successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 导入成功");
} }
else if (isUpdateSupport) else if (isUpdateSupport)
{ {
BeanValidators.validateWithException(validator, user); BeanValidators.validateWithException(validator, user);
checkUserAllowed(user); checkUserAllowed(u);
checkUserDataScope(user.getUserId()); checkUserDataScope(u.getUserId());
user.setUserId(u.getUserId());
user.setUpdateBy(operName); user.setUpdateBy(operName);
this.updateUser(user); userMapper.updateUser(user);
successNum++; successNum++;
successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 更新成功"); successMsg.append("<br/>" + successNum + "、账号 " + user.getUserName() + " 更新成功");
} }

@ -23,8 +23,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="updateBy" column="update_by" /> <result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" /> <result property="updateTime" column="update_time" />
<result property="remark" column="remark" /> <result property="remark" column="remark" />
<association property="dept" column="dept_id" javaType="SysDept" resultMap="deptResult" /> <association property="dept" javaType="SysDept" resultMap="deptResult" />
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" /> <collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
</resultMap> </resultMap>
<resultMap id="deptResult" type="SysDept"> <resultMap id="deptResult" type="SysDept">
@ -42,7 +42,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="roleName" column="role_name" /> <result property="roleName" column="role_name" />
<result property="roleKey" column="role_key" /> <result property="roleKey" column="role_key" />
<result property="roleSort" column="role_sort" /> <result property="roleSort" column="role_sort" />
<result property="dataScope" column="data_scope" /> <result property="dataScope" column="data_scope" />
<result property="status" column="role_status" /> <result property="status" column="role_status" />
</resultMap> </resultMap>

@ -1,6 +1,6 @@
{ {
"name": "ruoyi", "name": "ruoyi",
"version": "3.6.2", "version": "3.6.3",
"description": "若依管理系统", "description": "若依管理系统",
"author": "若依", "author": "若依",
"license": "MIT", "license": "MIT",
@ -41,7 +41,7 @@
"clipboard": "2.0.8", "clipboard": "2.0.8",
"core-js": "3.25.3", "core-js": "3.25.3",
"echarts": "5.4.0", "echarts": "5.4.0",
"element-ui": "2.15.12", "element-ui": "2.15.13",
"file-saver": "2.0.5", "file-saver": "2.0.5",
"fuse.js": "6.4.3", "fuse.js": "6.4.3",
"highlight.js": "9.18.5", "highlight.js": "9.18.5",

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

@ -180,12 +180,3 @@ aside {
margin-bottom: 10px; margin-bottom: 10px;
} }
} }
//refine vue-multiselect plugin
.multiselect {
line-height: 16px;
}
.multiselect--active {
z-index: 1000 !important;
}

@ -1,7 +1,7 @@
#app { #app {
.main-container { .main-container {
min-height: 100%; height: 100%;
transition: margin-left .28s; transition: margin-left .28s;
margin-left: $base-sidebar-width; margin-left: $base-sidebar-width;
position: relative; position: relative;

@ -3,11 +3,11 @@
<template v-for="(item, index) in options"> <template v-for="(item, index) in options">
<template v-if="values.includes(item.value)"> <template v-if="values.includes(item.value)">
<span <span
v-if="item.raw.listClass == 'default' || item.raw.listClass == ''" v-if="(item.raw.listClass == 'default' || item.raw.listClass == '') && (item.raw.cssClass == '' || item.raw.cssClass == null)"
:key="item.value" :key="item.value"
:index="index" :index="index"
:class="item.raw.cssClass" :class="item.raw.cssClass"
>{{ item.label }}</span >{{ item.label + " " }}</span
> >
<el-tag <el-tag
v-else v-else
@ -17,10 +17,13 @@
:type="item.raw.listClass == 'primary' ? '' : item.raw.listClass" :type="item.raw.listClass == 'primary' ? '' : item.raw.listClass"
:class="item.raw.cssClass" :class="item.raw.cssClass"
> >
{{ item.label }} {{ item.label + " " }}
</el-tag> </el-tag>
</template> </template>
</template> </template>
<template v-if="unmatch && showValue">
{{ unmatchArray | handleArray }}
</template>
</div> </div>
</template> </template>
@ -33,20 +36,57 @@ export default {
default: null, default: null,
}, },
value: [Number, String, Array], value: [Number, String, Array],
// value
showValue: {
type: Boolean,
default: true,
}
},
data() {
return {
unmatchArray: [], //
}
}, },
computed: { computed: {
values() { values() {
if (this.value !== null && typeof this.value !== 'undefined') { if (this.value !== null && typeof this.value !== "undefined") {
return Array.isArray(this.value) ? this.value : [String(this.value)]; return Array.isArray(this.value) ? this.value : [String(this.value)];
} else { } else {
return []; return [];
} }
}, },
unmatch() {
this.unmatchArray = [];
if (this.value !== null && typeof this.value !== "undefined") {
//
if (!Array.isArray(this.value)) {
if (this.options.some((v) => v.value == this.value)) return false;
this.unmatchArray.push(this.value);
return true;
}
// Array
this.value.forEach((item) => {
if (!this.options.some((v) => v.value == item))
this.unmatchArray.push(item);
});
return true;
}
// value
return false;
},
}, },
filters: {
handleArray(array) {
if (array.length === 0) return "";
return array.reduce((pre, cur) => {
return pre + " " + cur;
})
}
}
}; };
</script> </script>
<style scoped> <style scoped>
.el-tag + .el-tag { .el-tag + .el-tag {
margin-left: 10px; margin-left: 10px;
} }
</style> </style>

@ -1,13 +1,17 @@
<!-- @author zhengjie --> <!-- @author zhengjie -->
<template> <template>
<div class="icon-body"> <div class="icon-body">
<el-input v-model="name" style="position: relative;" clearable placeholder="请输入图标名称" @clear="filterIcons" @input.native="filterIcons"> <el-input v-model="name" class="icon-search" clearable placeholder="请输入图标名称" @clear="filterIcons" @input="filterIcons">
<i slot="suffix" class="el-icon-search el-input__icon" /> <i slot="suffix" class="el-icon-search el-input__icon" />
</el-input> </el-input>
<div class="icon-list"> <div class="icon-list">
<div v-for="(item, index) in iconList" :key="index" @click="selectedIcon(item)"> <div class="list-container">
<svg-icon :icon-class="item" style="height: 30px;width: 16px;" /> <div v-for="(item, index) in iconList" class="icon-item-wrapper" :key="index" @click="selectedIcon(item)">
<span>{{ item }}</span> <div :class="['icon-item', { active: activeIcon === item }]">
<svg-icon :icon-class="item" class-name="icon" style="height: 25px;width: 16px;"/>
<span>{{ item }}</span>
</div>
</div>
</div> </div>
</div> </div>
</div> </div>
@ -17,6 +21,11 @@
import icons from './requireIcons' import icons from './requireIcons'
export default { export default {
name: 'IconSelect', name: 'IconSelect',
props: {
activeIcon: {
type: String
}
},
data() { data() {
return { return {
name: '', name: '',
@ -46,22 +55,49 @@ export default {
.icon-body { .icon-body {
width: 100%; width: 100%;
padding: 10px; padding: 10px;
.icon-search {
position: relative;
margin-bottom: 5px;
}
.icon-list { .icon-list {
height: 200px; height: 200px;
overflow-y: scroll; overflow: auto;
div { .list-container {
height: 30px; display: flex;
line-height: 30px; flex-wrap: wrap;
margin-bottom: -5px; .icon-item-wrapper {
cursor: pointer; width: calc(100% / 3);
width: 33%; height: 25px;
float: left; line-height: 25px;
} cursor: pointer;
span { display: flex;
display: inline-block; .icon-item {
vertical-align: -0.15em; display: flex;
fill: currentColor; max-width: 100%;
overflow: hidden; height: 100%;
padding: 0 5px;
&:hover {
background: #ececec;
border-radius: 5px;
}
.icon {
flex-shrink: 0;
}
span {
display: inline-block;
vertical-align: -0.15em;
fill: currentColor;
padding-left: 2px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
}
.icon-item.active {
background: #ececec;
border-radius: 5px;
}
}
} }
} }
} }

@ -6,7 +6,10 @@
> >
<template v-for="(item, index) in topMenus"> <template v-for="(item, index) in topMenus">
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber" <el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"
><svg-icon :icon-class="item.meta.icon" /> ><svg-icon
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
:icon-class="item.meta.icon"
/>
{{ item.meta.title }}</el-menu-item {{ item.meta.title }}</el-menu-item
> >
</template> </template>
@ -127,7 +130,13 @@ export default {
window.open(key, "_blank"); window.open(key, "_blank");
} else if (!route || !route.children) { } else if (!route || !route.children) {
// //
this.$router.push({ path: key }); const routeMenu = this.childrenMenus.find(item => item.path === key);
if (routeMenu && routeMenu.query) {
let query = JSON.parse(routeMenu.query);
this.$router.push({ path: key, query: query });
} else {
this.$router.push({ path: key });
}
this.$store.dispatch('app/toggleSideBarHide', true); this.$store.dispatch('app/toggleSideBarHide', true);
} else { } else {
// //

@ -50,3 +50,26 @@ export default {
} }
} }
</style> </style>
<style lang="scss">
// fix css style bug in open el-dialog
.el-popup-parent--hidden {
.fixed-header {
padding-right: 6px;
}
}
::-webkit-scrollbar {
width: 6px;
height: 6px;
}
::-webkit-scrollbar-track {
background-color: #f1f1f1;
}
::-webkit-scrollbar-thumb {
background-color: #c0c0c0;
border-radius: 3px;
}
</style>

@ -35,7 +35,7 @@ export default {
}, },
data() { data() {
return { return {
title: '若依管理系统', title: process.env.VUE_APP_TITLE,
logo: logoImg logo: logoImg
} }
} }

@ -182,7 +182,7 @@ export default {
}) })
}, },
closeOthersTags() { closeOthersTags() {
this.$router.push(this.selectedTag).catch(()=>{}); this.$router.push(this.selectedTag.fullPath).catch(()=>{});
this.$tab.closeOtherPage(this.selectedTag).then(() => { this.$tab.closeOtherPage(this.selectedTag).then(() => {
this.moveToCurrentTag() this.moveToCurrentTag()
}) })

@ -1,19 +1,17 @@
<template> <template>
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}"> <div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
<el-scrollbar> <div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/> <sidebar v-if="!sidebar.hide" class="sidebar-container"/>
<sidebar v-if="!sidebar.hide" class="sidebar-container"/> <div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container"> <div :class="{'fixed-header':fixedHeader}">
<div :class="{'fixed-header':fixedHeader}"> <navbar/>
<navbar/> <tags-view v-if="needTagsView"/>
<tags-view v-if="needTagsView"/>
</div>
<app-main/>
<right-panel>
<settings/>
</right-panel>
</div> </div>
</el-scrollbar> <app-main/>
<right-panel>
<settings/>
</right-panel>
</div>
</div> </div>
</template> </template>
@ -74,14 +72,6 @@ export default {
height: 100%; height: 100%;
width: 100%; width: 100%;
.el-scrollbar{
height: 100%;
}
::v-deep .el-scrollbar__wrap {
overflow-x: hidden;
}
&.mobile.openSidebar { &.mobile.openSidebar {
position: fixed; position: fixed;
top: 0; top: 0;

@ -45,7 +45,7 @@ router.beforeEach((to, from, next) => {
// 在免登录白名单,直接进入 // 在免登录白名单,直接进入
next() next()
} else { } else {
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页
NProgress.done() NProgress.done()
} }
} }

@ -166,9 +166,15 @@ export const dynamicRoutes = [
// 防止连续点击多次路由报错 // 防止连续点击多次路由报错
let routerPush = Router.prototype.push; let routerPush = Router.prototype.push;
let routerReplace = Router.prototype.replace;
// push
Router.prototype.push = function push(location) { Router.prototype.push = function push(location) {
return routerPush.call(this, location).catch(err => err) return routerPush.call(this, location).catch(err => err)
} }
// replace
Router.prototype.replace = function push(location) {
return routerReplace.call(this, location).catch(err => err)
}
export default new Router({ export default new Router({
mode: 'history', // 去掉url中的# mode: 'history', // 去掉url中的#

@ -14,7 +14,7 @@ const mutations = {
try { try {
for (let i = 0; i < state.dict.length; i++) { for (let i = 0; i < state.dict.length; i++) {
if (state.dict[i].key == key) { if (state.dict[i].key == key) {
state.dict.splice(i, i) state.dict.splice(i, 1)
return true return true
} }
} }

@ -1,4 +1,3 @@
import { isArray } from 'util'
import { exportDefault, titleCase } from '@/utils/index' import { exportDefault, titleCase } from '@/utils/index'
import { trigger } from './config' import { trigger } from './config'
@ -133,12 +132,12 @@ function buildRules(conf, ruleList) {
const rules = [] const rules = []
if (trigger[conf.tag]) { if (trigger[conf.tag]) {
if (conf.required) { if (conf.required) {
const type = isArray(conf.defaultValue) ? 'type: \'array\',' : '' const type = Array.isArray(conf.defaultValue) ? 'type: \'array\',' : ''
let message = isArray(conf.defaultValue) ? `请至少选择一个${conf.vModel}` : conf.placeholder let message = Array.isArray(conf.defaultValue) ? `请至少选择一个${conf.vModel}` : conf.placeholder
if (message === undefined) message = `${conf.label}不能为空` if (message === undefined) message = `${conf.label}不能为空`
rules.push(`{ required: true, ${type} message: '${message}', trigger: '${trigger[conf.tag]}' }`) rules.push(`{ required: true, ${type} message: '${message}', trigger: '${trigger[conf.tag]}' }`)
} }
if (conf.regList && isArray(conf.regList)) { if (conf.regList && Array.isArray(conf.regList)) {
conf.regList.forEach(item => { conf.regList.forEach(item => {
if (item.pattern) { if (item.pattern) {
rules.push(`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${trigger[conf.tag]}' }`) rules.push(`{ pattern: ${eval(item.pattern)}, message: '${item.message}', trigger: '${trigger[conf.tag]}' }`)

@ -42,6 +42,12 @@ service.interceptors.request.use(config => {
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data, data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime() time: new Date().getTime()
} }
const requestSize = Object.keys(JSON.stringify(requestObj)).length; // 请求数据大小
const limitSize = 5 * 1024 * 1024; // 限制存放数据5M
if (requestSize >= limitSize) {
console.warn(`[${config.url}]: ` + '请求数据大小超出允许的5M限制无法进行防重复提交验证。')
return config;
}
const sessionObj = cache.session.getJSON('sessionObj') const sessionObj = cache.session.getJSON('sessionObj')
if (sessionObj === undefined || sessionObj === null || sessionObj === '') { if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
cache.session.setJSON('sessionObj', requestObj) cache.session.setJSON('sessionObj', requestObj)

@ -118,12 +118,11 @@
> >
</p> </p>
<p> <p>
<i class="el-icon-user-solid"></i> QQ群<s>满42799195</s> <i class="el-icon-user-solid"></i> QQ群 <s> 满42799195 </s> <s> 满170157040 </s>
<s>满170157040</s> <s>满130643120</s> <s>满225920371</s> <s> 满130643120 </s> <s> 满225920371 </s> <s> 满201705537 </s> <s> 满236543183 </s>
<s>满201705537</s> <s>满236543183</s> <s>满213618602</s> <s> 满213618602 </s> <s> 满148794840 </s> <s> 满118752664 </s> <s> 满101038945</s>
<s>满148794840</s> <s>满118752664</s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=pHuELvQ01AXiVC_CH9HNq-hL6qd6EbIb&authKey=k5nCvwTnimKrFBbJpFEfaQabjBHzZhMAbvsZAjAXiOIekreMrmJzjjTVuoMsZgB%2F&noverify=0&group_code=128355254" target="_blank"
<a href="https://jq.qq.com/?_wv=1027&k=FqImHgH2" target="_blank" >128355254</a
>101038945</a
> >
</p> </p>
<p> <p>
@ -148,6 +147,44 @@
<span>更新日志</span> <span>更新日志</span>
</div> </div>
<el-collapse accordion> <el-collapse accordion>
<el-collapse-item title="v3.6.3 - 2023-07-07">
<ol>
<li>支持登录IP黑名单限制</li>
<li>操作日志新增消耗时间属性</li>
<li>屏蔽定时任务bean违规的字符</li>
<li>日志管理使用索引提升查询性能</li>
<li>日志注解支持排除指定的请求参数</li>
<li>支持自定义隐藏属性列过滤子对象</li>
<li>升级spring-boot到最新版本2.7.13</li>
<li>升级spring-cloud到最新版2021.0.8</li>
<li>升级spring-cloud-alibaba到最新版2021.0.5.0</li>
<li>升级druid到最新版本1.2.16</li>
<li>升级fastjson到最新版2.0.34</li>
<li>升级pagehelper到最新版1.4.7</li>
<li>升级transmittable-thread-local到最新版本2.14.3</li>
<li>升级element-ui到最新版本2.15.13</li>
<li>移除apache/commons-fileupload依赖</li>
<li>修复页面切换时布局错乱的问题</li>
<li>修复用户多角色数据权限可能出现权限抬升的情况</li>
<li>修复导入用户时无法更新存在用户数据的问题</li>
<li>修复开启TopNav后一级菜单路由参数设置无效问题</li>
<li>优化文件下载出现的异常</li>
<li>优化选择图标组件高亮回显</li>
<li>优化修改密码日志存储明文问题</li>
<li>优化排序属性orderBy参数限制长度</li>
<li>优化页签栏关闭其他出现的异常问题</li>
<li>优化页签关闭左侧选项排除首页选项</li>
<li>优化关闭当前tab页跳转最右侧tab页</li>
<li>优化文件上传服务关闭InputStream</li>
<li>优化页签在Firefox浏览器被遮挡的问题</li>
<li>优化侧边栏的平台标题与VUE_APP_TITLE保持同步</li>
<li>优化DictTag组件value没有匹配的值时则展示value</li>
<li>优化去除@EnableCustomSwagger注解后会启动失败问题</li>
<li>优化upload接口在文件过大和文件名过长的情况返回提示信息</li>
<li>优化异步保存日志发生报错不进RemoteLogFallbackFactory问题</li>
<li>其他细节优化</li>
</ol>
</el-collapse-item>
<el-collapse-item title="v3.6.2 - 2023-01-16"> <el-collapse-item title="v3.6.2 - 2023-01-16">
<ol> <ol>
<li>重置时取消部门选中</li> <li>重置时取消部门选中</li>
@ -180,7 +217,7 @@
<li>升级echarts到最新版本5.4.0</li> <li>升级echarts到最新版本5.4.0</li>
<li>升级core-js到最新版本3.25.3</li> <li>升级core-js到最新版本3.25.3</li>
<li>升级element-ui到最新版本2.15.12</li> <li>升级element-ui到最新版本2.15.12</li>
<li>移除commons-collections多余的依赖</li> <li>移除commons-collections多余的依赖</li>
<li>优化弹窗内容过多展示不全问题</li> <li>优化弹窗内容过多展示不全问题</li>
<li>优化导出对象的子列表为空会出现[]问题</li> <li>优化导出对象的子列表为空会出现[]问题</li>
<li>优化字符未使用下划线不进行驼峰式处理</li> <li>优化字符未使用下划线不进行驼峰式处理</li>
@ -322,7 +359,7 @@
<li>代码生成新增Java类型Boolean</li> <li>代码生成新增Java类型Boolean</li>
<li>定时任务目标字符串过滤特殊字符</li> <li>定时任务目标字符串过滤特殊字符</li>
<li>定时任务目标字符串验证包名白名单</li> <li>定时任务目标字符串验证包名白名单</li>
<li>升级nacos到最新版2.0.4</li> <li>升级nacos到最新版2.0.4</li>
<li>升级spring-cloud到最新版2021.0.0</li> <li>升级spring-cloud到最新版2021.0.0</li>
<li>升级spring-boot到最新版本2.6.3</li> <li>升级spring-boot到最新版本2.6.3</li>
<li>升级spring-boot-admin到最新版2.6.1</li> <li>升级spring-boot-admin到最新版2.6.1</li>
@ -352,17 +389,17 @@
<li>新增tab对象简化页签操作</li> <li>新增tab对象简化页签操作</li>
<li>修改获取缓存信息方式</li> <li>修改获取缓存信息方式</li>
<li>修改权限认证注解实现</li> <li>修改权限认证注解实现</li>
<li>自定义文字复制剪贴指令</li> <li>自定义文字复制剪贴指令</li>
<li>升级axios到最新版本0.24.0</li> <li>升级axios到最新版本0.24.0</li>
<li>升级core-js到最新版本3.19.1</li> <li>升级core-js到最新版本3.19.1</li>
<li>升级jsencrypt到最新版本3.2.1</li> <li>升级jsencrypt到最新版本3.2.1</li>
<li>升级js-cookie到最新版本3.0.1</li> <li>升级js-cookie到最新版本3.0.1</li>
<li>升级clipboard到最新版本2.0.8</li> <li>升级clipboard到最新版本2.0.8</li>
<li>升级velocity到最新版本2.3</li> <li>升级velocity到最新版本2.3</li>
<li>升级spring-boot到最新版本2.5.6</li> <li>升级spring-boot到最新版本2.5.6</li>
<li>升级spring-boot-admin到最新版2.5.4</li> <li>升级spring-boot-admin到最新版2.5.4</li>
<li>升级dynamic-ds到最新版本3.5.0</li> <li>升级dynamic-ds到最新版本3.5.0</li>
<li>代码生成预览支持复制内容</li> <li>代码生成预览支持复制内容</li>
<li>修复五级以上菜单出现的404问题</li> <li>修复五级以上菜单出现的404问题</li>
<li>生产环境使用路由懒加载提升页面响应速度</li> <li>生产环境使用路由懒加载提升页面响应速度</li>
<li>任务屏蔽违规字符&参数忽略双引号中的逗号</li> <li>任务屏蔽违规字符&参数忽略双引号中的逗号</li>
@ -821,7 +858,7 @@
</div> </div>
<div class="body"> <div class="body">
<img <img
src="https://oscimg.oschina.net/oscnet/up-d6695f82666e5018f715c41cb7ee60d3b73.png" src="@/assets/images/pay.png"
alt="donate" alt="donate"
width="100%" width="100%"
/> />
@ -841,7 +878,7 @@ export default {
data() { data() {
return { return {
// //
version: "3.6.2", version: "3.6.3",
}; };
}, },
methods: { methods: {

@ -200,7 +200,18 @@
</el-input> </el-input>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="24"> <el-col :span="24" v-if="form.jobId !== undefined">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.sys_job_status"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="执行策略" prop="misfirePolicy"> <el-form-item label="执行策略" prop="misfirePolicy">
<el-radio-group v-model="form.misfirePolicy" size="small"> <el-radio-group v-model="form.misfirePolicy" size="small">
<el-radio-button label="1">立即执行</el-radio-button> <el-radio-button label="1">立即执行</el-radio-button>
@ -217,17 +228,6 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12">
<el-form-item label="状态">
<el-radio-group v-model="form.status">
<el-radio
v-for="dict in dict.type.sys_job_status"
:key="dict.value"
:label="dict.value"
>{{dict.label}}</el-radio>
</el-radio-group>
</el-form-item>
</el-col>
</el-row> </el-row>
</el-form> </el-form>
<div slot="footer" class="dialog-footer"> <div slot="footer" class="dialog-footer">
@ -264,7 +264,7 @@
<el-col :span="12"> <el-col :span="12">
<el-form-item label="任务状态:"> <el-form-item label="任务状态:">
<div v-if="form.status == 0"></div> <div v-if="form.status == 0"></div>
<div v-else-if="form.status == 1">失败</div> <div v-else-if="form.status == 1">暂停</div>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12"> <el-col :span="12">

@ -95,8 +95,8 @@
<el-table-column label="字典编码" align="center" prop="dictCode" /> <el-table-column label="字典编码" align="center" prop="dictCode" />
<el-table-column label="字典标签" align="center" prop="dictLabel"> <el-table-column label="字典标签" align="center" prop="dictLabel">
<template slot-scope="scope"> <template slot-scope="scope">
<span v-if="scope.row.listClass == '' || scope.row.listClass == 'default'">{{scope.row.dictLabel}}</span> <span v-if="(scope.row.listClass == '' || scope.row.listClass == 'default') && (scope.row.cssClass == '' || scope.row.cssClass == null)">{{ scope.row.dictLabel }}</span>
<el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass">{{scope.row.dictLabel}}</el-tag> <el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass" :class="scope.row.cssClass">{{ scope.row.dictLabel }}</el-tag>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="字典键值" align="center" prop="dictValue" /> <el-table-column label="字典键值" align="center" prop="dictValue" />

@ -77,7 +77,7 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" class-name="small-padding fixed-width"> <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button <el-button
size="mini" size="mini"
type="text" type="text"
icon="el-icon-edit" icon="el-icon-edit"
@ -134,14 +134,13 @@
trigger="click" trigger="click"
@show="$refs['iconSelect'].reset()" @show="$refs['iconSelect'].reset()"
> >
<IconSelect ref="iconSelect" @selected="selected" /> <IconSelect ref="iconSelect" @selected="selected" :active-icon="form.icon" />
<el-input slot="reference" v-model="form.icon" placeholder="点击选择图标" readonly> <el-input slot="reference" v-model="form.icon" placeholder="点击选择图标" readonly>
<svg-icon <svg-icon
v-if="form.icon" v-if="form.icon"
slot="prefix" slot="prefix"
:icon-class="form.icon" :icon-class="form.icon"
class="el-input__icon" style="width: 25px;"
style="height: 32px;width: 16px;"
/> />
<i v-else slot="prefix" class="el-icon-search el-input__icon" /> <i v-else slot="prefix" class="el-icon-search el-input__icon" />
</el-input> </el-input>
@ -247,7 +246,7 @@
</el-radio-group> </el-radio-group>
</el-form-item> </el-form-item>
</el-col> </el-col>
<el-col :span="12" v-if="form.menuType != 'F'"> <el-col :span="12">
<el-form-item prop="status"> <el-form-item prop="status">
<span slot="label"> <span slot="label">
<el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top"> <el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top">

@ -8,7 +8,7 @@
</div> </div>
<div> <div>
<div class="text-center"> <div class="text-center">
<userAvatar :user="user" /> <userAvatar />
</div> </div>
<ul class="list-group list-group-striped"> <ul class="list-group list-group-striped">
<li class="list-group-item"> <li class="list-group-item">

@ -61,11 +61,6 @@ import { debounce } from '@/utils'
export default { export default {
components: { VueCropper }, components: { VueCropper },
props: {
user: {
type: Object
}
},
data() { data() {
return { return {
// //
@ -140,7 +135,7 @@ export default {
formData.append("avatarfile", data); formData.append("avatarfile", data);
uploadAvatar(formData).then(response => { uploadAvatar(formData).then(response => {
this.open = false; this.open = false;
this.options.img = response.imgUrl; this.options.img = process.env.VUE_APP_BASE_API + response.imgUrl;
store.commit('SET_AVATAR', this.options.img); store.commit('SET_AVATAR', this.options.img);
this.$modal.msgSuccess("修改成功"); this.$modal.msgSuccess("修改成功");
this.visible = false; this.visible = false;

@ -90,9 +90,7 @@ module.exports = {
}) })
.end() .end()
config config.when(process.env.NODE_ENV !== 'development', config => {
.when(process.env.NODE_ENV !== 'development',
config => {
config config
.plugin('ScriptExtHtmlWebpackPlugin') .plugin('ScriptExtHtmlWebpackPlugin')
.after('html') .after('html')
@ -101,36 +99,36 @@ module.exports = {
inline: /runtime\..*\.js$/ inline: /runtime\..*\.js$/
}]) }])
.end() .end()
config
.optimization.splitChunks({ config.optimization.splitChunks({
chunks: 'all', chunks: 'all',
cacheGroups: { cacheGroups: {
libs: { libs: {
name: 'chunk-libs', name: 'chunk-libs',
test: /[\\/]node_modules[\\/]/, test: /[\\/]node_modules[\\/]/,
priority: 10, priority: 10,
chunks: 'initial' // only package third parties that are initially dependent chunks: 'initial' // only package third parties that are initially dependent
}, },
elementUI: { elementUI: {
name: 'chunk-elementUI', // split elementUI into a single package name: 'chunk-elementUI', // split elementUI into a single package
priority: 20, // the weight needs to be larger than libs and app or it will be packaged into libs or app test: /[\\/]node_modules[\\/]_?element-ui(.*)/, // in order to adapt to cnpm
test: /[\\/]node_modules[\\/]_?element-ui(.*)/ // in order to adapt to cnpm priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app
}, },
commons: { commons: {
name: 'chunk-commons', name: 'chunk-commons',
test: resolve('src/components'), // can customize your rules test: resolve('src/components'), // can customize your rules
minChunks: 3, // minimum common number minChunks: 3, // minimum common number
priority: 5, priority: 5,
reuseExistingChunk: true reuseExistingChunk: true
}
} }
}) }
})
config.optimization.runtimeChunk('single'), config.optimization.runtimeChunk('single'),
{ {
from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件 from: path.resolve(__dirname, './public/robots.txt'), //防爬虫文件
to: './' //到根目录下 to: './' //到根目录下
} }
} })
)
} }
} }

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -4,7 +4,7 @@
<parent> <parent>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<artifactId>ruoyi-visual</artifactId> <artifactId>ruoyi-visual</artifactId>
<version>3.6.2</version> <version>3.6.3</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>

@ -670,7 +670,7 @@ create table gen_table (
drop table if exists gen_table_column; drop table if exists gen_table_column;
create table gen_table_column ( create table gen_table_column (
column_id bigint(20) not null auto_increment comment '编号', column_id bigint(20) not null auto_increment comment '编号',
table_id varchar(64) comment '归属表编号', table_id bigint(20) comment '归属表编号',
column_name varchar(200) comment '列名称', column_name varchar(200) comment '列名称',
column_comment varchar(500) comment '列描述', column_comment varchar(500) comment '列描述',
column_type varchar(100) comment '列类型', column_type varchar(100) comment '列类型',
Loading…
Cancel
Save