mirror of
https://github.com/yangzongzhuan/RuoYi-Vue.git
synced 2025-10-19 08:57:41 +00:00
Compare commits
68 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
36b900cef8 | ||
![]() |
ac9302e2a2 | ||
![]() |
0f7e3a744e | ||
![]() |
45656b271a | ||
![]() |
323e3b7371 | ||
![]() |
bfbaa9e7b5 | ||
![]() |
2253a146b3 | ||
![]() |
2070a9252a | ||
![]() |
e231d78469 | ||
![]() |
f74454b61a | ||
![]() |
d71ee5dba1 | ||
![]() |
78b1ac4a60 | ||
![]() |
966a17123f | ||
![]() |
42bb8f6445 | ||
![]() |
72e4cd9fb3 | ||
![]() |
1525bd8b54 | ||
![]() |
b8e2eeaaf8 | ||
![]() |
cbcfabee2a | ||
![]() |
e6d0599b25 | ||
![]() |
b224cebab7 | ||
![]() |
f880dee7a4 | ||
![]() |
f16875c9af | ||
![]() |
a90355eb5e | ||
![]() |
386f32a3b7 | ||
![]() |
4ca30f08d6 | ||
![]() |
73f881c7d3 | ||
![]() |
b357aedaa3 | ||
![]() |
8cf8c8acd0 | ||
![]() |
fbab383bd7 | ||
![]() |
d8255edf84 | ||
![]() |
eff42d8b0f | ||
![]() |
1f753e3d84 | ||
![]() |
72d4069537 | ||
![]() |
76205588f0 | ||
![]() |
7b4ba0146b | ||
![]() |
3963e86537 | ||
![]() |
7098acc968 | ||
![]() |
079ac841f3 | ||
![]() |
0434b4ca7a | ||
![]() |
8873dc9b64 | ||
![]() |
078a3aad5a | ||
![]() |
207a9ce855 | ||
![]() |
9ced1e9766 | ||
![]() |
1926840204 | ||
![]() |
006d46ad07 | ||
![]() |
f5a1b0c550 | ||
![]() |
4a78fe116d | ||
![]() |
3e95dd21f2 | ||
![]() |
491b0f3db8 | ||
![]() |
16d8b71e21 | ||
![]() |
90260ce2f9 | ||
![]() |
d58942c506 | ||
![]() |
6a742e1d1b | ||
![]() |
5b61aea064 | ||
![]() |
45ef542687 | ||
![]() |
4ac7a1aa1f | ||
![]() |
c5e4459bb8 | ||
![]() |
8f67bf416b | ||
![]() |
ab99a72b65 | ||
![]() |
7c9423657e | ||
![]() |
128b186b8e | ||
![]() |
68ac40eda9 | ||
![]() |
5557433235 | ||
![]() |
2517e9dddb | ||
![]() |
a0595711ca | ||
![]() |
1ffb6379f7 | ||
![]() |
4d5c204b9a | ||
![]() |
8ee740ef49 |
@@ -1,11 +1,11 @@
|
||||
<p align="center">
|
||||
<img alt="logo" src="https://oscimg.oschina.net/oscnet/up-d3d0a9303e11d522a06cd263f3079027715.png">
|
||||
</p>
|
||||
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.6</h1>
|
||||
<h1 align="center" style="margin: 30px 0 30px; font-weight: bold;">RuoYi v3.8.7</h1>
|
||||
<h4 align="center">基于SpringBoot+Vue前后端分离的Java快速开发框架</h4>
|
||||
<p align="center">
|
||||
<a href="https://gitee.com/y_project/RuoYi-Vue/stargazers"><img src="https://gitee.com/y_project/RuoYi-Vue/badge/star.svg?theme=dark"></a>
|
||||
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.6-brightgreen.svg"></a>
|
||||
<a href="https://gitee.com/y_project/RuoYi-Vue"><img src="https://img.shields.io/badge/RuoYi-v3.8.7-brightgreen.svg"></a>
|
||||
<a href="https://gitee.com/y_project/RuoYi-Vue/blob/master/LICENSE"><img src="https://img.shields.io/github/license/mashape/apistatus.svg"></a>
|
||||
</p>
|
||||
|
||||
@@ -93,4 +93,4 @@
|
||||
|
||||
## 若依前后端分离交流群
|
||||
|
||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=5bVB1og) [](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [](https://jq.qq.com/?_wv=1027&k=51G72yr) [](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [](https://jq.qq.com/?_wv=1027&k=SpyH2875) [](https://jq.qq.com/?_wv=1027&k=tKEt51dz) 点击按钮入群。
|
||||
QQ群: [](https://jq.qq.com/?_wv=1027&k=5bVB1og) [](https://jq.qq.com/?_wv=1027&k=5eiA4DH) [](https://jq.qq.com/?_wv=1027&k=5AxMKlC) [](https://jq.qq.com/?_wv=1027&k=51G72yr) [](https://jq.qq.com/?_wv=1027&k=VvjN2nvu) [](https://jq.qq.com/?_wv=1027&k=5vYAqA05) [](https://jq.qq.com/?_wv=1027&k=kOIINEb5) [](https://jq.qq.com/?_wv=1027&k=UKtX5jhs) [](https://jq.qq.com/?_wv=1027&k=EI9an8lJ) [](https://jq.qq.com/?_wv=1027&k=SWCtLnMz) [](https://jq.qq.com/?_wv=1027&k=96Dkdq0k) [](https://jq.qq.com/?_wv=1027&k=0fsNiYZt) [](https://jq.qq.com/?_wv=1027&k=7xw4xUG1) [](https://jq.qq.com/?_wv=1027&k=eCx8eyoJ) [](https://jq.qq.com/?_wv=1027&k=SpyH2875) [](https://jq.qq.com/?_wv=1027&k=tKEt51dz) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=0vBbSb0ztbBgVtn3kJS-Q4HUNYwip89G&authKey=8irq5PhutrZmWIvsUsklBxhj57l%2F1nOZqjzigkXZVoZE451GG4JHPOqW7AW6cf0T&noverify=0&group_code=143961921) [](http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=ZFAPAbp09S2ltvwrJzp7wGlbopsc0rwi&authKey=HB2cxpxP2yspk%2Bo3WKTBfktRCccVkU26cgi5B16u0KcAYrVu7sBaE7XSEqmMdFQp&noverify=0&group_code=174951577) 点击按钮入群。
|
16
pom.xml
16
pom.xml
@@ -6,32 +6,32 @@
|
||||
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<version>3.8.6</version>
|
||||
<version>3.8.7</version>
|
||||
|
||||
<name>ruoyi</name>
|
||||
<url>http://www.ruoyi.vip</url>
|
||||
<description>若依管理系统</description>
|
||||
|
||||
<properties>
|
||||
<ruoyi.version>3.8.6</ruoyi.version>
|
||||
<ruoyi.version>3.8.7</ruoyi.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<java.version>1.8</java.version>
|
||||
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
|
||||
<druid.version>1.2.16</druid.version>
|
||||
<druid.version>1.2.20</druid.version>
|
||||
<bitwalker.version>1.21</bitwalker.version>
|
||||
<swagger.version>3.0.0</swagger.version>
|
||||
<kaptcha.version>2.3.3</kaptcha.version>
|
||||
<pagehelper.boot.version>1.4.6</pagehelper.boot.version>
|
||||
<fastjson.version>2.0.34</fastjson.version>
|
||||
<oshi.version>6.4.3</oshi.version>
|
||||
<commons.io.version>2.11.0</commons.io.version>
|
||||
<pagehelper.boot.version>1.4.7</pagehelper.boot.version>
|
||||
<fastjson.version>2.0.43</fastjson.version>
|
||||
<oshi.version>6.4.8</oshi.version>
|
||||
<commons.io.version>2.13.0</commons.io.version>
|
||||
<commons.collections.version>3.2.2</commons.collections.version>
|
||||
<poi.version>4.1.2</poi.version>
|
||||
<velocity.version>2.3</velocity.version>
|
||||
<jwt.version>0.9.1</jwt.version>
|
||||
</properties>
|
||||
|
||||
|
||||
<!-- 依赖声明 -->
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.6</version>
|
||||
<version>3.8.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<packaging>jar</packaging>
|
||||
@@ -68,7 +68,7 @@
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>2.1.1.RELEASE</version>
|
||||
<version>2.5.15</version>
|
||||
<configuration>
|
||||
<fork>true</fork> <!-- 如果没有该配置,devtools不会生效 -->
|
||||
</configuration>
|
||||
|
@@ -60,27 +60,22 @@ public class SysProfileController extends BaseController
|
||||
public AjaxResult updateProfile(@RequestBody SysUser user)
|
||||
{
|
||||
LoginUser loginUser = getLoginUser();
|
||||
SysUser sysUser = loginUser.getUser();
|
||||
user.setUserName(sysUser.getUserName());
|
||||
if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user))
|
||||
SysUser currentUser = loginUser.getUser();
|
||||
currentUser.setNickName(user.getNickName());
|
||||
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("修改用户'" + loginUser.getUsername() + "'失败,手机号码已存在");
|
||||
}
|
||||
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user))
|
||||
if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(currentUser))
|
||||
{
|
||||
return error("修改用户'" + user.getUserName() + "'失败,邮箱账号已存在");
|
||||
return error("修改用户'" + loginUser.getUsername() + "'失败,邮箱账号已存在");
|
||||
}
|
||||
user.setUserId(sysUser.getUserId());
|
||||
user.setPassword(null);
|
||||
user.setAvatar(null);
|
||||
user.setDeptId(null);
|
||||
if (userService.updateUserProfile(user) > 0)
|
||||
if (userService.updateUserProfile(currentUser) > 0)
|
||||
{
|
||||
// 更新缓存用户信息
|
||||
sysUser.setNickName(user.getNickName());
|
||||
sysUser.setPhonenumber(user.getPhonenumber());
|
||||
sysUser.setEmail(user.getEmail());
|
||||
sysUser.setSex(user.getSex());
|
||||
tokenService.setLoginUser(loginUser);
|
||||
return success();
|
||||
}
|
||||
@@ -105,10 +100,11 @@ public class SysProfileController extends BaseController
|
||||
{
|
||||
return error("新密码不能与旧密码相同");
|
||||
}
|
||||
if (userService.resetUserPwd(userName, SecurityUtils.encryptPassword(newPassword)) > 0)
|
||||
newPassword = SecurityUtils.encryptPassword(newPassword);
|
||||
if (userService.resetUserPwd(userName, newPassword) > 0)
|
||||
{
|
||||
// 更新缓存用户密码
|
||||
loginUser.getUser().setPassword(SecurityUtils.encryptPassword(newPassword));
|
||||
loginUser.getUser().setPassword(newPassword);
|
||||
tokenService.setLoginUser(loginUser);
|
||||
return success();
|
||||
}
|
||||
|
@@ -1 +1 @@
|
||||
restart.include.json=/com.alibaba.fastjson.*.jar
|
||||
restart.include.json=/com.alibaba.fastjson2.*.jar
|
@@ -3,11 +3,9 @@ ruoyi:
|
||||
# 名称
|
||||
name: RuoYi
|
||||
# 版本
|
||||
version: 3.8.6
|
||||
version: 3.8.7
|
||||
# 版权年份
|
||||
copyrightYear: 2023
|
||||
# 实例演示开关
|
||||
demoEnabled: true
|
||||
# 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
|
||||
profile: D:/ruoyi/uploadPath
|
||||
# 获取ip地址开关
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.6</version>
|
||||
<version>3.8.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@@ -21,9 +21,6 @@ public class RuoYiConfig
|
||||
/** 版权年份 */
|
||||
private String copyrightYear;
|
||||
|
||||
/** 实例演示开关 */
|
||||
private boolean demoEnabled;
|
||||
|
||||
/** 上传路径 */
|
||||
private static String profile;
|
||||
|
||||
@@ -63,16 +60,6 @@ public class RuoYiConfig
|
||||
this.copyrightYear = copyrightYear;
|
||||
}
|
||||
|
||||
public boolean isDemoEnabled()
|
||||
{
|
||||
return demoEnabled;
|
||||
}
|
||||
|
||||
public void setDemoEnabled(boolean demoEnabled)
|
||||
{
|
||||
this.demoEnabled = demoEnabled;
|
||||
}
|
||||
|
||||
public static String getProfile()
|
||||
{
|
||||
return profile;
|
||||
|
@@ -63,7 +63,27 @@ public class Constants
|
||||
* 登录失败
|
||||
*/
|
||||
public static final String LOGIN_FAIL = "Error";
|
||||
|
||||
|
||||
/**
|
||||
* 所有权限标识
|
||||
*/
|
||||
public static final String ALL_PERMISSION = "*:*:*";
|
||||
|
||||
/**
|
||||
* 管理员角色权限标识
|
||||
*/
|
||||
public static final String SUPER_ADMIN = "admin";
|
||||
|
||||
/**
|
||||
* 角色权限分隔符
|
||||
*/
|
||||
public static final String ROLE_DELIMETER = ",";
|
||||
|
||||
/**
|
||||
* 权限标识分隔符
|
||||
*/
|
||||
public static final String PERMISSION_DELIMETER = ",";
|
||||
|
||||
/**
|
||||
* 验证码有效期(分钟)
|
||||
*/
|
||||
@@ -129,6 +149,11 @@ public class Constants
|
||||
*/
|
||||
public static final String LOOKUP_LDAPS = "ldaps:";
|
||||
|
||||
/**
|
||||
* 自动识别json对象白名单配置(仅允许解析的包名,范围越小越安全)
|
||||
*/
|
||||
public static final String[] JSON_WHITELIST_STR = { "org.springframework", "com.ruoyi" };
|
||||
|
||||
/**
|
||||
* 定时任务白名单配置(仅允许访问的包名,如其他需要可以自行添加)
|
||||
*/
|
||||
|
@@ -2,6 +2,7 @@ package com.ruoyi.common.core.text;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.math.BigInteger;
|
||||
import java.math.RoundingMode;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.charset.Charset;
|
||||
import java.text.NumberFormat;
|
||||
@@ -977,7 +978,12 @@ public class Convert
|
||||
String s = "";
|
||||
for (int i = 0; i < fraction.length; i++)
|
||||
{
|
||||
s += (digit[(int) (Math.floor(n * 10 * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
|
||||
// 优化double计算精度丢失问题
|
||||
BigDecimal nNum = new BigDecimal(n);
|
||||
BigDecimal decimal = new BigDecimal(10);
|
||||
BigDecimal scale = nNum.multiply(decimal).setScale(2, RoundingMode.HALF_EVEN);
|
||||
double d = scale.doubleValue();
|
||||
s += (digit[(int) (Math.floor(d * Math.pow(10, i)) % 10)] + fraction[i]).replaceAll("(零.)+", "");
|
||||
}
|
||||
if (s.length() < 1)
|
||||
{
|
||||
|
@@ -147,7 +147,7 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
|
||||
/**
|
||||
* 计算时间差
|
||||
*
|
||||
* @param endTime 最后时间
|
||||
* @param endDate 最后时间
|
||||
* @param startTime 开始时间
|
||||
* @return 时间差(天/小时/分钟)
|
||||
*/
|
||||
|
@@ -1,9 +1,15 @@
|
||||
package com.ruoyi.common.utils;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
|
||||
import org.springframework.util.PatternMatchUtils;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
|
||||
@@ -14,6 +20,7 @@ import com.ruoyi.common.exception.ServiceException;
|
||||
*/
|
||||
public class SecurityUtils
|
||||
{
|
||||
|
||||
/**
|
||||
* 用户ID
|
||||
**/
|
||||
@@ -43,7 +50,7 @@ public class SecurityUtils
|
||||
throw new ServiceException("获取部门ID异常", HttpStatus.UNAUTHORIZED);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 获取用户账户
|
||||
**/
|
||||
@@ -117,4 +124,55 @@ public class SecurityUtils
|
||||
{
|
||||
return userId != null && 1L == userId;
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证用户是否具备某权限
|
||||
*
|
||||
* @param permission 权限字符串
|
||||
* @return 用户是否具备某权限
|
||||
*/
|
||||
public static boolean hasPermi(String permission)
|
||||
{
|
||||
return hasPermi(getLoginUser().getPermissions(), permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否包含权限
|
||||
*
|
||||
* @param authorities 权限列表
|
||||
* @param permission 权限字符串
|
||||
* @return 用户是否具备某权限
|
||||
*/
|
||||
public static boolean hasPermi(Collection<String> authorities, String permission)
|
||||
{
|
||||
return authorities.stream().filter(StringUtils::hasText)
|
||||
.anyMatch(x -> Constants.ALL_PERMISSION.equals(x) || PatternMatchUtils.simpleMatch(x, permission));
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证用户是否拥有某个角色
|
||||
*
|
||||
* @param role 角色标识
|
||||
* @return 用户是否具备某角色
|
||||
*/
|
||||
public static boolean hasRole(String role)
|
||||
{
|
||||
List<SysRole> roleList = getLoginUser().getUser().getRoles();
|
||||
Collection<String> roles = roleList.stream().map(SysRole::getRoleKey).collect(Collectors.toSet());
|
||||
return hasRole(roles, role);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否包含角色
|
||||
*
|
||||
* @param roles 角色列表
|
||||
* @param role 角色
|
||||
* @return 用户是否具备某角色权限
|
||||
*/
|
||||
public static boolean hasRole(Collection<String> roles, String role)
|
||||
{
|
||||
return roles.stream().filter(StringUtils::hasText)
|
||||
.anyMatch(x -> Constants.SUPER_ADMIN.equals(x) || PatternMatchUtils.simpleMatch(x, role));
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -240,6 +240,30 @@ public class StringUtils extends org.apache.commons.lang3.StringUtils
|
||||
return str.substring(start, end);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为空,并且不是空白字符
|
||||
*
|
||||
* @param str 要判断的value
|
||||
* @return 结果
|
||||
*/
|
||||
public static boolean hasText(String str)
|
||||
{
|
||||
return (str != null && !str.isEmpty() && containsText(str));
|
||||
}
|
||||
|
||||
private static boolean containsText(CharSequence str)
|
||||
{
|
||||
int strLen = str.length();
|
||||
for (int i = 0; i < strLen; i++)
|
||||
{
|
||||
if (!Character.isWhitespace(str.charAt(i)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化文本, {} 表示占位符<br>
|
||||
* 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
|
||||
|
@@ -1,5 +1,8 @@
|
||||
package com.ruoyi.common.utils.poi;
|
||||
|
||||
import org.apache.poi.ss.usermodel.Cell;
|
||||
import org.apache.poi.ss.usermodel.Workbook;
|
||||
|
||||
/**
|
||||
* Excel数据格式处理适配器
|
||||
*
|
||||
@@ -12,8 +15,10 @@ public interface ExcelHandlerAdapter
|
||||
*
|
||||
* @param value 单元格数据值
|
||||
* @param args excel注解args参数组
|
||||
* @param cell 单元格对象
|
||||
* @param wb 工作簿对象
|
||||
*
|
||||
* @return 处理后的值
|
||||
*/
|
||||
Object format(Object value, String[] args);
|
||||
Object format(Object value, String[] args, Cell cell, Workbook wb);
|
||||
}
|
||||
|
@@ -288,9 +288,23 @@ public class ExcelUtil<T>
|
||||
* @param is 输入流
|
||||
* @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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -336,7 +350,6 @@ public class ExcelUtil<T>
|
||||
}
|
||||
// 获取最后一个非空行的行下标,比如总行数为n,则返回的为n-1
|
||||
int rows = sheet.getLastRowNum();
|
||||
|
||||
if (rows > 0)
|
||||
{
|
||||
// 定义一个map用于存放excel列的序号和field.
|
||||
@@ -451,7 +464,7 @@ public class ExcelUtil<T>
|
||||
{
|
||||
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());
|
||||
}
|
||||
@@ -461,7 +474,7 @@ public class ExcelUtil<T>
|
||||
}
|
||||
else if (!attr.handler().equals(ExcelHandlerAdapter.class))
|
||||
{
|
||||
val = dataFormatHandlerAdapter(val, attr);
|
||||
val = dataFormatHandlerAdapter(val, attr, null);
|
||||
}
|
||||
else if (ColumnType.IMAGE == attr.cellType() && StringUtils.isNotEmpty(pictures))
|
||||
{
|
||||
@@ -1052,7 +1065,7 @@ public class ExcelUtil<T>
|
||||
}
|
||||
else if (!attr.handler().equals(ExcelHandlerAdapter.class))
|
||||
{
|
||||
cell.setCellValue(dataFormatHandlerAdapter(value, attr));
|
||||
cell.setCellValue(dataFormatHandlerAdapter(value, attr, cell));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1265,13 +1278,13 @@ public class ExcelUtil<T>
|
||||
* @param excel 数据注解
|
||||
* @return
|
||||
*/
|
||||
public String dataFormatHandlerAdapter(Object value, Excel excel)
|
||||
public String dataFormatHandlerAdapter(Object value, Excel excel, Cell cell)
|
||||
{
|
||||
try
|
||||
{
|
||||
Object instance = excel.handler().newInstance();
|
||||
Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class });
|
||||
value = formatMethod.invoke(instance, value, excel.args());
|
||||
Method formatMethod = excel.handler().getMethod("format", new Class[] { Object.class, String[].class, Cell.class, Workbook.class });
|
||||
value = formatMethod.invoke(instance, value, excel.args(), cell, this.wb);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@@ -20,6 +20,11 @@ public class SqlUtil
|
||||
*/
|
||||
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("参数不符合规范,不能进行查询");
|
||||
}
|
||||
if (StringUtils.length(value) > ORDER_BY_MAX_LENGTH)
|
||||
{
|
||||
throw new UtilException("参数已超过最大限制,不能进行查询");
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.6</version>
|
||||
<version>3.8.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@@ -18,6 +18,7 @@ import org.springframework.validation.BindingResult;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.ruoyi.common.annotation.Log;
|
||||
import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.enums.BusinessStatus;
|
||||
import com.ruoyi.common.enums.HttpMethod;
|
||||
@@ -96,6 +97,11 @@ public class LogAspect
|
||||
if (loginUser != null)
|
||||
{
|
||||
operLog.setOperName(loginUser.getUsername());
|
||||
SysUser currentUser = loginUser.getUser();
|
||||
if (StringUtils.isNotNull(currentUser) && StringUtils.isNotNull(currentUser.getDept()))
|
||||
{
|
||||
operLog.setDeptName(currentUser.getDept().getDeptName());
|
||||
}
|
||||
}
|
||||
|
||||
if (e != null)
|
||||
|
@@ -6,6 +6,8 @@ import org.springframework.data.redis.serializer.SerializationException;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.alibaba.fastjson2.JSONReader;
|
||||
import com.alibaba.fastjson2.JSONWriter;
|
||||
import com.alibaba.fastjson2.filter.Filter;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
|
||||
/**
|
||||
* Redis使用FastJson序列化
|
||||
@@ -16,6 +18,8 @@ public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
|
||||
{
|
||||
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
static final Filter AUTO_TYPE_FILTER = JSONReader.autoTypeFilter(Constants.JSON_WHITELIST_STR);
|
||||
|
||||
private Class<T> clazz;
|
||||
|
||||
public FastJson2JsonRedisSerializer(Class<T> clazz)
|
||||
@@ -43,6 +47,6 @@ public class FastJson2JsonRedisSerializer<T> implements RedisSerializer<T>
|
||||
}
|
||||
String str = new String(bytes, DEFAULT_CHARSET);
|
||||
|
||||
return JSON.parseObject(str, clazz, JSONReader.Feature.SupportAutoType);
|
||||
return JSON.parseObject(str, clazz, AUTO_TYPE_FILTER);
|
||||
}
|
||||
}
|
||||
|
@@ -47,8 +47,9 @@ public abstract class RepeatSubmitInterceptor implements HandlerInterceptor
|
||||
/**
|
||||
* 验证是否重复提交由子类实现具体的防重复提交的规则
|
||||
*
|
||||
* @param request
|
||||
* @return
|
||||
* @param request 请求信息
|
||||
* @param annotation 防重复注解参数
|
||||
* @return 结果
|
||||
* @throws Exception
|
||||
*/
|
||||
public abstract boolean isRepeatSubmit(HttpServletRequest request, RepeatSubmit annotation);
|
||||
|
@@ -7,8 +7,10 @@ import org.springframework.security.access.AccessDeniedException;
|
||||
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 com.ruoyi.common.constant.HttpStatus;
|
||||
import com.ruoyi.common.core.domain.AjaxResult;
|
||||
import com.ruoyi.common.exception.DemoModeException;
|
||||
@@ -59,6 +61,28 @@ public class GlobalExceptionHandler
|
||||
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()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 拦截未知的运行时异常
|
||||
*/
|
||||
|
@@ -3,6 +3,7 @@ package com.ruoyi.framework.web.service;
|
||||
import java.util.Set;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import com.ruoyi.common.constant.Constants;
|
||||
import com.ruoyi.common.core.domain.entity.SysRole;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.utils.SecurityUtils;
|
||||
@@ -17,16 +18,6 @@ import com.ruoyi.framework.security.context.PermissionContextHolder;
|
||||
@Service("ss")
|
||||
public class PermissionService
|
||||
{
|
||||
/** 所有权限标识 */
|
||||
private static final String ALL_PERMISSION = "*:*:*";
|
||||
|
||||
/** 管理员角色权限标识 */
|
||||
private static final String SUPER_ADMIN = "admin";
|
||||
|
||||
private static final String ROLE_DELIMETER = ",";
|
||||
|
||||
private static final String PERMISSION_DELIMETER = ",";
|
||||
|
||||
/**
|
||||
* 验证用户是否具备某权限
|
||||
*
|
||||
@@ -78,7 +69,7 @@ public class PermissionService
|
||||
}
|
||||
PermissionContextHolder.setContext(permissions);
|
||||
Set<String> authorities = loginUser.getPermissions();
|
||||
for (String permission : permissions.split(PERMISSION_DELIMETER))
|
||||
for (String permission : permissions.split(Constants.PERMISSION_DELIMETER))
|
||||
{
|
||||
if (permission != null && hasPermissions(authorities, permission))
|
||||
{
|
||||
@@ -108,7 +99,7 @@ public class PermissionService
|
||||
for (SysRole sysRole : loginUser.getUser().getRoles())
|
||||
{
|
||||
String roleKey = sysRole.getRoleKey();
|
||||
if (SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role)))
|
||||
if (Constants.SUPER_ADMIN.equals(roleKey) || roleKey.equals(StringUtils.trim(role)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@@ -144,7 +135,7 @@ public class PermissionService
|
||||
{
|
||||
return false;
|
||||
}
|
||||
for (String role : roles.split(ROLE_DELIMETER))
|
||||
for (String role : roles.split(Constants.ROLE_DELIMETER))
|
||||
{
|
||||
if (hasRole(role))
|
||||
{
|
||||
@@ -163,6 +154,6 @@ public class PermissionService
|
||||
*/
|
||||
private boolean hasPermissions(Set<String> permissions, String permission)
|
||||
{
|
||||
return permissions.contains(ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
|
||||
return permissions.contains(Constants.ALL_PERMISSION) || permissions.contains(StringUtils.trim(permission));
|
||||
}
|
||||
}
|
||||
|
@@ -4,6 +4,8 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
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.Value;
|
||||
import org.springframework.stereotype.Component;
|
||||
@@ -29,6 +31,8 @@ import io.jsonwebtoken.SignatureAlgorithm;
|
||||
@Component
|
||||
public class TokenService
|
||||
{
|
||||
private static final Logger log = LoggerFactory.getLogger(TokenService.class);
|
||||
|
||||
// 令牌自定义标识
|
||||
@Value("${token.header}")
|
||||
private String header;
|
||||
@@ -72,6 +76,7 @@ public class TokenService
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
log.error("获取用户信息异常'{}'", e.getMessage());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@@ -11,6 +11,7 @@ import com.ruoyi.common.core.domain.entity.SysUser;
|
||||
import com.ruoyi.common.core.domain.model.LoginUser;
|
||||
import com.ruoyi.common.enums.UserStatus;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.common.utils.MessageUtils;
|
||||
import com.ruoyi.common.utils.StringUtils;
|
||||
import com.ruoyi.system.service.ISysUserService;
|
||||
|
||||
@@ -40,17 +41,17 @@ public class UserDetailsServiceImpl implements UserDetailsService
|
||||
if (StringUtils.isNull(user))
|
||||
{
|
||||
log.info("登录用户:{} 不存在.", username);
|
||||
throw new ServiceException("登录用户:" + username + " 不存在");
|
||||
throw new ServiceException(MessageUtils.message("user.not.exists"));
|
||||
}
|
||||
else if (UserStatus.DELETED.getCode().equals(user.getDelFlag()))
|
||||
{
|
||||
log.info("登录用户:{} 已被删除.", username);
|
||||
throw new ServiceException("对不起,您的账号:" + username + " 已被删除");
|
||||
throw new ServiceException(MessageUtils.message("user.password.delete"));
|
||||
}
|
||||
else if (UserStatus.DISABLE.getCode().equals(user.getStatus()))
|
||||
{
|
||||
log.info("登录用户:{} 已被停用.", username);
|
||||
throw new ServiceException("对不起,您的账号:" + username + " 已停用");
|
||||
throw new ServiceException(MessageUtils.message("user.blocked"));
|
||||
}
|
||||
|
||||
passwordService.validate(user);
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.6</version>
|
||||
<version>3.8.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@@ -41,6 +41,9 @@ public class GenTable extends BaseEntity
|
||||
/** 使用的模板(crud单表操作 tree树表操作 sub主子表操作) */
|
||||
private String tplCategory;
|
||||
|
||||
/** 前端类型(element-ui模版 element-plus模版) */
|
||||
private String tplWebType;
|
||||
|
||||
/** 生成包路径 */
|
||||
@NotBlank(message = "生成包路径不能为空")
|
||||
private String packageName;
|
||||
@@ -165,6 +168,16 @@ public class GenTable extends BaseEntity
|
||||
this.tplCategory = tplCategory;
|
||||
}
|
||||
|
||||
public String getTplWebType()
|
||||
{
|
||||
return tplWebType;
|
||||
}
|
||||
|
||||
public void setTplWebType(String tplWebType)
|
||||
{
|
||||
this.tplWebType = tplWebType;
|
||||
}
|
||||
|
||||
public String getPackageName()
|
||||
{
|
||||
return packageName;
|
||||
|
@@ -206,7 +206,7 @@ public class GenTableServiceImpl implements IGenTableService
|
||||
VelocityContext context = VelocityUtils.prepareContext(table);
|
||||
|
||||
// 获取模板列表
|
||||
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
|
||||
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType());
|
||||
for (String template : templates)
|
||||
{
|
||||
// 渲染模板
|
||||
@@ -254,7 +254,7 @@ public class GenTableServiceImpl implements IGenTableService
|
||||
VelocityContext context = VelocityUtils.prepareContext(table);
|
||||
|
||||
// 获取模板列表
|
||||
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
|
||||
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType());
|
||||
for (String template : templates)
|
||||
{
|
||||
if (!StringUtils.containsAny(template, "sql.vm", "api.js.vm", "index.vue.vm", "index-tree.vue.vm"))
|
||||
@@ -367,7 +367,7 @@ public class GenTableServiceImpl implements IGenTableService
|
||||
VelocityContext context = VelocityUtils.prepareContext(table);
|
||||
|
||||
// 获取模板列表
|
||||
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory());
|
||||
List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory(), table.getTplWebType());
|
||||
for (String template : templates)
|
||||
{
|
||||
// 渲染模板
|
||||
|
@@ -123,11 +123,17 @@ public class VelocityUtils
|
||||
|
||||
/**
|
||||
* 获取模板信息
|
||||
*
|
||||
* @param tplCategory 生成的模板
|
||||
* @param tplWebType 前端类型
|
||||
* @return 模板列表
|
||||
*/
|
||||
public static List<String> getTemplateList(String tplCategory)
|
||||
public static List<String> getTemplateList(String tplCategory, String tplWebType)
|
||||
{
|
||||
String useWebType = "vm/vue";
|
||||
if ("element-plus".equals(tplWebType))
|
||||
{
|
||||
useWebType = "vm/vue/v3";
|
||||
}
|
||||
List<String> templates = new ArrayList<String>();
|
||||
templates.add("vm/java/domain.java.vm");
|
||||
templates.add("vm/java/mapper.java.vm");
|
||||
@@ -139,15 +145,15 @@ public class VelocityUtils
|
||||
templates.add("vm/js/api.js.vm");
|
||||
if (GenConstants.TPL_CRUD.equals(tplCategory))
|
||||
{
|
||||
templates.add("vm/vue/index.vue.vm");
|
||||
templates.add(useWebType + "/index.vue.vm");
|
||||
}
|
||||
else if (GenConstants.TPL_TREE.equals(tplCategory))
|
||||
{
|
||||
templates.add("vm/vue/index-tree.vue.vm");
|
||||
templates.add(useWebType + "/index-tree.vue.vm");
|
||||
}
|
||||
else if (GenConstants.TPL_SUB.equals(tplCategory))
|
||||
{
|
||||
templates.add("vm/vue/index.vue.vm");
|
||||
templates.add(useWebType + "/index.vue.vm");
|
||||
templates.add("vm/java/sub-domain.java.vm");
|
||||
}
|
||||
return templates;
|
||||
|
@@ -40,7 +40,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</select>
|
||||
|
||||
<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 '0' 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})
|
||||
order by ordinal_position
|
||||
</select>
|
||||
|
@@ -12,6 +12,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="subTableFkName" column="sub_table_fk_name" />
|
||||
<result property="className" column="class_name" />
|
||||
<result property="tplCategory" column="tpl_category" />
|
||||
<result property="tplWebType" column="tpl_web_type" />
|
||||
<result property="packageName" column="package_name" />
|
||||
<result property="moduleName" column="module_name" />
|
||||
<result property="businessName" column="business_name" />
|
||||
@@ -54,7 +55,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectGenTableVo">
|
||||
select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table
|
||||
select table_id, table_name, table_comment, sub_table_name, sub_table_fk_name, class_name, tpl_category, tpl_web_type, package_name, module_name, business_name, function_name, function_author, gen_type, gen_path, options, create_by, create_time, update_by, update_time, remark from gen_table
|
||||
</sql>
|
||||
|
||||
<select id="selectGenTableList" parameterType="GenTable" resultMap="GenTableResult">
|
||||
@@ -111,7 +112,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</select>
|
||||
|
||||
<select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult">
|
||||
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
||||
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.tpl_web_type, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
||||
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
||||
FROM gen_table t
|
||||
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
||||
@@ -119,7 +120,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</select>
|
||||
|
||||
<select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult">
|
||||
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
||||
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.tpl_web_type, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark,
|
||||
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
||||
FROM gen_table t
|
||||
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
||||
@@ -127,7 +128,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</select>
|
||||
|
||||
<select id="selectGenTableAll" parameterType="String" resultMap="GenTableResult">
|
||||
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark,
|
||||
SELECT t.table_id, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.tpl_web_type, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.options, t.remark,
|
||||
c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort
|
||||
FROM gen_table t
|
||||
LEFT JOIN gen_table_column c ON t.table_id = c.table_id
|
||||
@@ -140,6 +141,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="tableComment != null and tableComment != ''">table_comment,</if>
|
||||
<if test="className != null and className != ''">class_name,</if>
|
||||
<if test="tplCategory != null and tplCategory != ''">tpl_category,</if>
|
||||
<if test="tplWebType != null and tplWebType != ''">tpl_web_type,</if>
|
||||
<if test="packageName != null and packageName != ''">package_name,</if>
|
||||
<if test="moduleName != null and moduleName != ''">module_name,</if>
|
||||
<if test="businessName != null and businessName != ''">business_name,</if>
|
||||
@@ -155,6 +157,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="tableComment != null and tableComment != ''">#{tableComment},</if>
|
||||
<if test="className != null and className != ''">#{className},</if>
|
||||
<if test="tplCategory != null and tplCategory != ''">#{tplCategory},</if>
|
||||
<if test="tplWebType != null and tplWebType != ''">#{tplWebType},</if>
|
||||
<if test="packageName != null and packageName != ''">#{packageName},</if>
|
||||
<if test="moduleName != null and moduleName != ''">#{moduleName},</if>
|
||||
<if test="businessName != null and businessName != ''">#{businessName},</if>
|
||||
@@ -180,6 +183,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<if test="genType != null and genType != ''">gen_type = #{genType},</if>
|
||||
<if test="genPath != null and genPath != ''">gen_path = #{genPath},</if>
|
||||
<if test="tplCategory != null and tplCategory != ''">tpl_category = #{tplCategory},</if>
|
||||
<if test="tplWebType != null and tplWebType != ''">tpl_web_type = #{tplWebType},</if>
|
||||
<if test="packageName != null and packageName != ''">package_name = #{packageName},</if>
|
||||
<if test="moduleName != null and moduleName != ''">module_name = #{moduleName},</if>
|
||||
<if test="businessName != null and businessName != ''">business_name = #{businessName},</if>
|
||||
|
@@ -453,7 +453,7 @@ export default {
|
||||
this.reset();
|
||||
this.getTreeselect();
|
||||
if (row != null) {
|
||||
this.form.${treeParentCode} = row.${treeCode};
|
||||
this.form.${treeParentCode} = row.${treeParentCode};
|
||||
}
|
||||
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
|
||||
this.form = response.data;
|
||||
|
@@ -420,7 +420,7 @@ async function handleUpdate(row) {
|
||||
reset();
|
||||
await getTreeselect();
|
||||
if (row != null) {
|
||||
form.value.${treeParentCode} = row.${treeCode};
|
||||
form.value.${treeParentCode} = row.${treeParentCode};
|
||||
}
|
||||
get${BusinessName}(row.${pkColumn.javaField}).then(response => {
|
||||
form.value = response.data;
|
||||
|
@@ -1 +0,0 @@
|
||||
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD>õ<EFBFBD><EFBFBD><EFBFBD>RuoYi-Vue3ǰ<33>ˣ<EFBFBD><CBA3><EFBFBD>ô<EFBFBD><C3B4>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>һ<EFBFBD>´<EFBFBD>Ŀ¼<C4BF><C2BC>ģ<EFBFBD><C4A3>index.vue.vm<76><6D>index-tree.vue.vm<76>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ϼ<EFBFBD>vueĿ¼<C4BF><C2BC>
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.6</version>
|
||||
<version>3.8.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@@ -33,7 +33,7 @@
|
||||
// // 集群配置
|
||||
// prop.put("org.quartz.jobStore.isClustered", "true");
|
||||
// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000");
|
||||
// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1");
|
||||
// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "10");
|
||||
// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true");
|
||||
//
|
||||
// // sqlserver 启用
|
||||
|
@@ -5,7 +5,7 @@
|
||||
<parent>
|
||||
<artifactId>ruoyi</artifactId>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<version>3.8.6</version>
|
||||
<version>3.8.7</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
|
@@ -37,7 +37,7 @@ public interface SysUserPostMapper
|
||||
/**
|
||||
* 批量新增用户岗位信息
|
||||
*
|
||||
* @param userPostList 用户角色列表
|
||||
* @param userPostList 用户岗位列表
|
||||
* @return 结果
|
||||
*/
|
||||
public int batchUserPost(List<SysUserPost> userPostList);
|
||||
|
@@ -525,7 +525,7 @@ public class SysMenuServiceImpl implements ISysMenuService
|
||||
*/
|
||||
public String innerLinkReplaceEach(String path)
|
||||
{
|
||||
return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, "." },
|
||||
new String[] { "", "", "", "/" });
|
||||
return StringUtils.replaceEach(path, new String[] { Constants.HTTP, Constants.HTTPS, Constants.WWW, ".", ":" },
|
||||
new String[] { "", "", "", "/", "/" });
|
||||
}
|
||||
}
|
||||
|
@@ -37,6 +37,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<select id="selectOperLogList" parameterType="SysOperLog" resultMap="SysOperLogResult">
|
||||
<include refid="selectOperLogVo"/>
|
||||
<where>
|
||||
<if test="operIp != null and operIp != ''">
|
||||
AND oper_ip like concat('%', #{operIp}, '%')
|
||||
</if>
|
||||
<if test="title != null and title != ''">
|
||||
AND title like concat('%', #{title}, '%')
|
||||
</if>
|
||||
|
@@ -23,8 +23,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="updateBy" column="update_by" />
|
||||
<result property="updateTime" column="update_time" />
|
||||
<result property="remark" column="remark" />
|
||||
<association property="dept" column="dept_id" javaType="SysDept" resultMap="deptResult" />
|
||||
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
|
||||
<association property="dept" javaType="SysDept" resultMap="deptResult" />
|
||||
<collection property="roles" javaType="java.util.List" resultMap="RoleResult" />
|
||||
</resultMap>
|
||||
|
||||
<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="roleKey" column="role_key" />
|
||||
<result property="roleSort" column="role_sort" />
|
||||
<result property="dataScope" column="data_scope" />
|
||||
<result property="dataScope" column="data_scope" />
|
||||
<result property="status" column="role_status" />
|
||||
</resultMap>
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "ruoyi",
|
||||
"version": "3.8.6",
|
||||
"version": "3.8.7",
|
||||
"description": "若依管理系统",
|
||||
"author": "若依",
|
||||
"license": "MIT",
|
||||
@@ -41,7 +41,7 @@
|
||||
"clipboard": "2.0.8",
|
||||
"core-js": "3.25.3",
|
||||
"echarts": "5.4.0",
|
||||
"element-ui": "2.15.13",
|
||||
"element-ui": "2.15.14",
|
||||
"file-saver": "2.0.5",
|
||||
"fuse.js": "6.4.3",
|
||||
"highlight.js": "9.18.5",
|
||||
|
@@ -11,14 +11,14 @@ import ThemePicker from "@/components/ThemePicker";
|
||||
export default {
|
||||
name: "App",
|
||||
components: { ThemePicker },
|
||||
metaInfo() {
|
||||
return {
|
||||
title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
|
||||
titleTemplate: title => {
|
||||
return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
|
||||
}
|
||||
}
|
||||
metaInfo() {
|
||||
return {
|
||||
title: this.$store.state.settings.dynamicTitle && this.$store.state.settings.title,
|
||||
titleTemplate: title => {
|
||||
return title ? `${title} - ${process.env.VUE_APP_TITLE}` : process.env.VUE_APP_TITLE
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
|
@@ -11,7 +11,8 @@ export function login(username, password, code, uuid) {
|
||||
return request({
|
||||
url: '/login',
|
||||
headers: {
|
||||
isToken: false
|
||||
isToken: false,
|
||||
repeatSubmit: false
|
||||
},
|
||||
method: 'post',
|
||||
data: data
|
||||
|
@@ -1,129 +1,143 @@
|
||||
/**
|
||||
* 通用css样式布局处理
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
/**
|
||||
* 通用css样式布局处理
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
|
||||
/** 基础通用 **/
|
||||
/** 基础通用 **/
|
||||
.pt5 {
|
||||
padding-top: 5px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.pr5 {
|
||||
padding-right: 5px;
|
||||
padding-right: 5px;
|
||||
}
|
||||
|
||||
.pb5 {
|
||||
padding-bottom: 5px;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
|
||||
.mt5 {
|
||||
margin-top: 5px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.mr5 {
|
||||
margin-right: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.mb5 {
|
||||
margin-bottom: 5px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.mb8 {
|
||||
margin-bottom: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.ml5 {
|
||||
margin-left: 5px;
|
||||
margin-left: 5px;
|
||||
}
|
||||
|
||||
.mt10 {
|
||||
margin-top: 10px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.mr10 {
|
||||
margin-right: 10px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.mb10 {
|
||||
margin-bottom: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.ml10 {
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
.mt20 {
|
||||
margin-top: 20px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.mr20 {
|
||||
margin-right: 20px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.mb20 {
|
||||
margin-bottom: 20px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
.ml20 {
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.h1, .h2, .h3, .h4, .h5, .h6, h1, h2, h3, h4, h5, h6 {
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
color: inherit;
|
||||
font-family: inherit;
|
||||
font-weight: 500;
|
||||
line-height: 1.1;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.el-message-box__status + .el-message-box__message{
|
||||
word-break: break-word;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
.el-dialog:not(.is-fullscreen) {
|
||||
margin-top: 6vh !important;
|
||||
margin-top: 6vh !important;
|
||||
}
|
||||
|
||||
.el-dialog__wrapper.scrollbar .el-dialog .el-dialog__body {
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
max-height: 70vh;
|
||||
padding: 10px 20px 0;
|
||||
overflow: auto;
|
||||
overflow-x: hidden;
|
||||
max-height: 70vh;
|
||||
padding: 10px 20px 0;
|
||||
}
|
||||
|
||||
.el-table {
|
||||
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
||||
th {
|
||||
word-break: break-word;
|
||||
background-color: #f8f8f9;
|
||||
color: #515a6e;
|
||||
height: 40px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
.el-table__body-wrapper {
|
||||
.el-button [class*="el-icon-"] + span {
|
||||
margin-left: 1px;
|
||||
}
|
||||
}
|
||||
.el-table__header-wrapper, .el-table__fixed-header-wrapper {
|
||||
th {
|
||||
word-break: break-word;
|
||||
background-color: #f8f8f9;
|
||||
color: #515a6e;
|
||||
height: 40px;
|
||||
font-size: 13px;
|
||||
}
|
||||
}
|
||||
|
||||
.el-table__body-wrapper {
|
||||
.el-button [class*="el-icon-"] + span {
|
||||
margin-left: 1px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 表单布局 **/
|
||||
.form-header {
|
||||
font-size:15px;
|
||||
color:#6379bb;
|
||||
border-bottom:1px solid #ddd;
|
||||
margin:8px 10px 25px 10px;
|
||||
padding-bottom:5px
|
||||
font-size: 15px;
|
||||
color: #6379bb;
|
||||
border-bottom: 1px solid #ddd;
|
||||
margin: 8px 10px 25px 10px;
|
||||
padding-bottom: 5px
|
||||
}
|
||||
|
||||
/** 表格布局 **/
|
||||
.pagination-container {
|
||||
position: relative;
|
||||
height: 25px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 15px;
|
||||
padding: 10px 20px !important;
|
||||
position: relative;
|
||||
height: 25px;
|
||||
margin-bottom: 10px;
|
||||
margin-top: 15px;
|
||||
padding: 10px 20px !important;
|
||||
}
|
||||
|
||||
/* tree border */
|
||||
.tree-border {
|
||||
margin-top: 5px;
|
||||
border: 1px solid #e5e6e7;
|
||||
background: #FFFFFF none;
|
||||
border-radius:4px;
|
||||
margin-top: 5px;
|
||||
border: 1px solid #e5e6e7;
|
||||
background: #FFFFFF none;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.pagination-container .el-pagination {
|
||||
right: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
@media ( max-width : 768px) {
|
||||
@media (max-width: 768px) {
|
||||
.pagination-container .el-pagination > .el-pagination__jump {
|
||||
display: none !important;
|
||||
}
|
||||
@@ -133,9 +147,9 @@
|
||||
}
|
||||
|
||||
.el-table .fixed-width .el-button--mini {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
width: inherit;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
width: inherit;
|
||||
}
|
||||
|
||||
/** 表格更多操作下拉样式 */
|
||||
@@ -145,51 +159,51 @@
|
||||
}
|
||||
|
||||
.el-table .el-dropdown, .el-icon-arrow-down {
|
||||
font-size: 12px;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.el-tree-node__content > .el-checkbox {
|
||||
margin-right: 8px;
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.list-group-striped > .list-group-item {
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-radius: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-radius: 0;
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
.list-group {
|
||||
padding-left: 0px;
|
||||
list-style: none;
|
||||
padding-left: 0px;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.list-group-item {
|
||||
border-bottom: 1px solid #e7eaec;
|
||||
border-top: 1px solid #e7eaec;
|
||||
margin-bottom: -1px;
|
||||
padding: 11px 0px;
|
||||
font-size: 13px;
|
||||
border-bottom: 1px solid #e7eaec;
|
||||
border-top: 1px solid #e7eaec;
|
||||
margin-bottom: -1px;
|
||||
padding: 11px 0px;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.pull-right {
|
||||
float: right !important;
|
||||
float: right !important;
|
||||
}
|
||||
|
||||
.el-card__header {
|
||||
padding: 14px 15px 7px;
|
||||
min-height: 40px;
|
||||
padding: 14px 15px 7px;
|
||||
min-height: 40px;
|
||||
}
|
||||
|
||||
.el-card__body {
|
||||
padding: 15px 20px 20px 20px;
|
||||
padding: 15px 20px 20px 20px;
|
||||
}
|
||||
|
||||
.card-box {
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
margin-bottom: 10px;
|
||||
padding-right: 15px;
|
||||
padding-left: 15px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
/* button color */
|
||||
@@ -215,63 +229,63 @@
|
||||
|
||||
/* text color */
|
||||
.text-navy {
|
||||
color: #1ab394;
|
||||
color: #1ab394;
|
||||
}
|
||||
|
||||
.text-primary {
|
||||
color: inherit;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.text-success {
|
||||
color: #1c84c6;
|
||||
color: #1c84c6;
|
||||
}
|
||||
|
||||
.text-info {
|
||||
color: #23c6c8;
|
||||
color: #23c6c8;
|
||||
}
|
||||
|
||||
.text-warning {
|
||||
color: #f8ac59;
|
||||
color: #f8ac59;
|
||||
}
|
||||
|
||||
.text-danger {
|
||||
color: #ed5565;
|
||||
color: #ed5565;
|
||||
}
|
||||
|
||||
.text-muted {
|
||||
color: #888888;
|
||||
color: #888888;
|
||||
}
|
||||
|
||||
/* image */
|
||||
.img-circle {
|
||||
border-radius: 50%;
|
||||
border-radius: 50%;
|
||||
}
|
||||
|
||||
.img-lg {
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
width: 120px;
|
||||
height: 120px;
|
||||
}
|
||||
|
||||
.avatar-upload-preview {
|
||||
position: relative;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
width: 200px;
|
||||
height: 200px;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 拖拽列样式 */
|
||||
.sortable-ghost{
|
||||
opacity: .8;
|
||||
color: #fff!important;
|
||||
background: #42b983!important;
|
||||
.sortable-ghost {
|
||||
opacity: .8;
|
||||
color: #fff !important;
|
||||
background: #42b983 !important;
|
||||
}
|
||||
|
||||
.top-right-btn {
|
||||
position: relative;
|
||||
float: right;
|
||||
position: relative;
|
||||
float: right;
|
||||
}
|
||||
|
@@ -3,11 +3,11 @@
|
||||
<template v-for="(item, index) in options">
|
||||
<template v-if="values.includes(item.value)">
|
||||
<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"
|
||||
:index="index"
|
||||
:class="item.raw.cssClass"
|
||||
>{{ item.label + " " }}</span
|
||||
>{{ item.label + ' ' }}</span
|
||||
>
|
||||
<el-tag
|
||||
v-else
|
||||
@@ -17,7 +17,7 @@
|
||||
:type="item.raw.listClass == 'primary' ? '' : item.raw.listClass"
|
||||
:class="item.raw.cssClass"
|
||||
>
|
||||
{{ item.label + " " }}
|
||||
{{ item.label + ' ' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</template>
|
||||
@@ -40,6 +40,10 @@ export default {
|
||||
showValue: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
separator: {
|
||||
type: String,
|
||||
default: ","
|
||||
}
|
||||
},
|
||||
data() {
|
||||
@@ -49,39 +53,32 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
values() {
|
||||
if (this.value !== null && typeof this.value !== "undefined") {
|
||||
return Array.isArray(this.value) ? this.value : [String(this.value)];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
if (this.value === null || typeof this.value === 'undefined' || this.value === '') return []
|
||||
return Array.isArray(this.value) ? this.value.map(item => '' + item) : String(this.value).split(this.separator)
|
||||
},
|
||||
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;
|
||||
}
|
||||
this.unmatchArray = []
|
||||
// 没有value不显示
|
||||
return false;
|
||||
if (this.value === null || typeof this.value === 'undefined' || this.value === '' || this.options.length === 0) return false
|
||||
// 传入值为数组
|
||||
let unmatch = false // 添加一个标志来判断是否有未匹配项
|
||||
this.values.forEach(item => {
|
||||
if (!this.options.some(v => v.value === item)) {
|
||||
this.unmatchArray.push(item)
|
||||
unmatch = true // 如果有未匹配项,将标志设置为true
|
||||
}
|
||||
})
|
||||
return unmatch // 返回标志的值
|
||||
},
|
||||
|
||||
},
|
||||
filters: {
|
||||
handleArray(array) {
|
||||
if (array.length === 0) return "";
|
||||
if (array.length === 0) return '';
|
||||
return array.reduce((pre, cur) => {
|
||||
return pre + " " + cur;
|
||||
return pre + ' ' + cur;
|
||||
})
|
||||
}
|
||||
},
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
@@ -47,7 +47,7 @@ export default {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
// 上传文件大小限制(MB)
|
||||
/* 上传文件大小限制(MB) */
|
||||
fileSize: {
|
||||
type: Number,
|
||||
default: 5,
|
||||
@@ -129,7 +129,6 @@ export default {
|
||||
if (this.type == 'url') {
|
||||
let toolbar = this.Quill.getModule("toolbar");
|
||||
toolbar.addHandler("image", (value) => {
|
||||
this.uploadType = "image";
|
||||
if (value) {
|
||||
this.$refs.upload.$children[0].$refs.input.click();
|
||||
} else {
|
||||
@@ -158,6 +157,13 @@ export default {
|
||||
},
|
||||
// 上传前校检格式和大小
|
||||
handleBeforeUpload(file) {
|
||||
const type = ["image/jpeg", "image/jpg", "image/png", "image/svg"];
|
||||
const isJPG = type.includes(file.type);
|
||||
// 检验文件格式
|
||||
if (!isJPG) {
|
||||
this.$message.error(`图片格式错误!`);
|
||||
return false;
|
||||
}
|
||||
// 校检文件大小
|
||||
if (this.fileSize) {
|
||||
const isLt = file.size / 1024 / 1024 < this.fileSize;
|
||||
@@ -169,10 +175,10 @@ export default {
|
||||
return true;
|
||||
},
|
||||
handleUploadSuccess(res, file) {
|
||||
// 获取富文本组件实例
|
||||
let quill = this.Quill;
|
||||
// 如果上传成功
|
||||
if (res.code == 200) {
|
||||
// 获取富文本组件实例
|
||||
let quill = this.Quill;
|
||||
// 获取光标所在位置
|
||||
let length = quill.getSelection().index;
|
||||
// 插入图片 res.url为服务器返回的图片地址
|
||||
@@ -206,11 +212,9 @@ export default {
|
||||
content: "保存";
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.ql-snow .ql-tooltip[data-mode="video"]::before {
|
||||
content: "请输入视频地址:";
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-label::before,
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
|
||||
content: "14px";
|
||||
@@ -227,7 +231,6 @@ export default {
|
||||
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
|
||||
content: "32px";
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-label::before,
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
|
||||
content: "文本";
|
||||
@@ -256,7 +259,6 @@ export default {
|
||||
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
|
||||
content: "标题6";
|
||||
}
|
||||
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-label::before,
|
||||
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
|
||||
content: "标准字体";
|
||||
|
@@ -142,7 +142,7 @@ export default {
|
||||
// 上传失败
|
||||
handleUploadError(err) {
|
||||
this.$modal.msgError("上传文件失败,请重试");
|
||||
this.$modal.closeLoading()
|
||||
this.$modal.closeLoading();
|
||||
},
|
||||
// 上传成功回调
|
||||
handleUploadSuccess(res, file) {
|
||||
@@ -174,10 +174,11 @@ export default {
|
||||
},
|
||||
// 获取文件名称
|
||||
getFileName(name) {
|
||||
// 如果是url那么取最后的名字 如果不是直接返回
|
||||
if (name.lastIndexOf("/") > -1) {
|
||||
return name.slice(name.lastIndexOf("/") + 1);
|
||||
} else {
|
||||
return "";
|
||||
return name;
|
||||
}
|
||||
},
|
||||
// 对象转成指定字符串分隔
|
||||
|
@@ -71,12 +71,17 @@ export default {
|
||||
},
|
||||
change(val) {
|
||||
const path = val.path;
|
||||
const query = val.query;
|
||||
if(this.ishttp(val.path)) {
|
||||
// http(s):// 路径新窗口打开
|
||||
const pindex = path.indexOf("http");
|
||||
window.open(path.substr(pindex, path.length), "_blank");
|
||||
} else {
|
||||
this.$router.push(val.path)
|
||||
if (query) {
|
||||
this.$router.push({ path: path, query: JSON.parse(query) });
|
||||
} else {
|
||||
this.$router.push(path)
|
||||
}
|
||||
}
|
||||
this.search = ''
|
||||
this.options = []
|
||||
@@ -124,6 +129,10 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
if (router.query) {
|
||||
data.query = router.query
|
||||
}
|
||||
|
||||
// recursive child routes
|
||||
if (router.children) {
|
||||
const tempRoutes = this.generateRoutes(router.children, data.path, data.title)
|
||||
|
@@ -19,7 +19,7 @@
|
||||
>
|
||||
<i class="el-icon-plus"></i>
|
||||
</el-upload>
|
||||
|
||||
|
||||
<!-- 上传提示 -->
|
||||
<div class="el-upload__tip" slot="tip" v-if="showTip">
|
||||
请上传
|
||||
@@ -168,7 +168,7 @@ export default {
|
||||
// 删除图片
|
||||
handleDelete(file) {
|
||||
const findex = this.fileList.map(f => f.name).indexOf(file.name);
|
||||
if(findex > -1) {
|
||||
if (findex > -1) {
|
||||
this.fileList.splice(findex, 1);
|
||||
this.$emit("input", this.listToString(this.fileList));
|
||||
}
|
||||
@@ -219,8 +219,8 @@ export default {
|
||||
}
|
||||
|
||||
::v-deep .el-list-enter, .el-list-leave-active {
|
||||
opacity: 0;
|
||||
transform: translateY(0);
|
||||
opacity: 0;
|
||||
transform: translateY(0);
|
||||
}
|
||||
</style>
|
||||
|
||||
|
@@ -8,7 +8,17 @@
|
||||
<el-button size="mini" circle icon="el-icon-refresh" @click="refresh()" />
|
||||
</el-tooltip>
|
||||
<el-tooltip class="item" effect="dark" content="显隐列" placement="top" v-if="columns">
|
||||
<el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" />
|
||||
<el-button size="mini" circle icon="el-icon-menu" @click="showColumn()" v-if="showColumnsType == 'transfer'"/>
|
||||
<el-dropdown trigger="click" :hide-on-click="false" style="padding-left: 12px" v-if="showColumnsType == 'checkbox'">
|
||||
<el-button size="mini" circle icon="el-icon-menu" />
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<template v-for="item in columns">
|
||||
<el-dropdown-item :key="item.key">
|
||||
<el-checkbox :checked="item.visible" @change="checkboxChange($event, item.label)" :label="item.label" />
|
||||
</el-dropdown-item>
|
||||
</template>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</el-tooltip>
|
||||
</el-row>
|
||||
<el-dialog :title="title" :visible.sync="open" append-to-body>
|
||||
@@ -35,17 +45,26 @@ export default {
|
||||
};
|
||||
},
|
||||
props: {
|
||||
/* 是否显示检索条件 */
|
||||
showSearch: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/* 显隐列信息 */
|
||||
columns: {
|
||||
type: Array,
|
||||
},
|
||||
/* 是否显示检索图标 */
|
||||
search: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
/* 显隐列类型(transfer穿梭框、checkbox复选框) */
|
||||
showColumnsType: {
|
||||
type: String,
|
||||
default: "checkbox",
|
||||
},
|
||||
/* 右外边距 */
|
||||
gutter: {
|
||||
type: Number,
|
||||
default: 10,
|
||||
@@ -61,10 +80,12 @@ export default {
|
||||
}
|
||||
},
|
||||
created() {
|
||||
// 显隐列初始默认隐藏列
|
||||
for (let item in this.columns) {
|
||||
if (this.columns[item].visible === false) {
|
||||
this.value.push(parseInt(item));
|
||||
if (this.showColumnsType == 'transfer') {
|
||||
// 显隐列初始默认隐藏列
|
||||
for (let item in this.columns) {
|
||||
if (this.columns[item].visible === false) {
|
||||
this.value.push(parseInt(item));
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -88,6 +109,10 @@ export default {
|
||||
showColumn() {
|
||||
this.open = true;
|
||||
},
|
||||
// 勾选
|
||||
checkboxChange(event, label) {
|
||||
this.columns.filter(item => item.label == label)[0].visible = event;
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@@ -5,10 +5,12 @@
|
||||
@select="handleSelect"
|
||||
>
|
||||
<template v-for="(item, index) in topMenus">
|
||||
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber"
|
||||
><svg-icon :icon-class="item.meta.icon" />
|
||||
{{ item.meta.title }}</el-menu-item
|
||||
>
|
||||
<el-menu-item :style="{'--theme': theme}" :index="item.path" :key="index" v-if="index < visibleNumber">
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
{{ item.meta.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
|
||||
<!-- 顶部菜单超出数量折叠 -->
|
||||
@@ -18,10 +20,12 @@
|
||||
<el-menu-item
|
||||
:index="item.path"
|
||||
:key="index"
|
||||
v-if="index >= visibleNumber"
|
||||
><svg-icon :icon-class="item.meta.icon" />
|
||||
{{ item.meta.title }}</el-menu-item
|
||||
>
|
||||
v-if="index >= visibleNumber">
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"/>
|
||||
{{ item.meta.title }}
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</el-submenu>
|
||||
</el-menu>
|
||||
@@ -53,9 +57,9 @@ export default {
|
||||
if (menu.hidden !== true) {
|
||||
// 兼容顶部栏一级菜单内部跳转
|
||||
if (menu.path === "/") {
|
||||
topMenus.push(menu.children[0]);
|
||||
topMenus.push(menu.children[0]);
|
||||
} else {
|
||||
topMenus.push(menu);
|
||||
topMenus.push(menu);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@@ -1,34 +1,34 @@
|
||||
/**
|
||||
* v-dialogDragWidth 可拖动弹窗高度(右下角)
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
* v-dialogDragWidth 可拖动弹窗高度(右下角)
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
|
||||
export default {
|
||||
bind(el) {
|
||||
const dragDom = el.querySelector('.el-dialog');
|
||||
const lineEl = document.createElement('div');
|
||||
lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;';
|
||||
lineEl.addEventListener('mousedown',
|
||||
function(e) {
|
||||
// 鼠标按下,计算当前元素距离可视区的距离
|
||||
const disX = e.clientX - el.offsetLeft;
|
||||
const disY = e.clientY - el.offsetTop;
|
||||
// 当前宽度 高度
|
||||
const curWidth = dragDom.offsetWidth;
|
||||
const curHeight = dragDom.offsetHeight;
|
||||
document.onmousemove = function(e) {
|
||||
e.preventDefault(); // 移动时禁用默认事件
|
||||
// 通过事件委托,计算移动的距离
|
||||
const xl = e.clientX - disX;
|
||||
const yl = e.clientY - disY
|
||||
dragDom.style.width = `${curWidth + xl}px`;
|
||||
dragDom.style.height = `${curHeight + yl}px`;
|
||||
};
|
||||
document.onmouseup = function(e) {
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
};
|
||||
}, false);
|
||||
dragDom.appendChild(lineEl);
|
||||
}
|
||||
}
|
||||
bind(el) {
|
||||
const dragDom = el.querySelector('.el-dialog');
|
||||
const lineEl = document.createElement('div');
|
||||
lineEl.style = 'width: 6px; background: inherit; height: 10px; position: absolute; right: 0; bottom: 0; margin: auto; z-index: 1; cursor: nwse-resize;';
|
||||
lineEl.addEventListener('mousedown',
|
||||
function(e) {
|
||||
// 鼠标按下,计算当前元素距离可视区的距离
|
||||
const disX = e.clientX - el.offsetLeft;
|
||||
const disY = e.clientY - el.offsetTop;
|
||||
// 当前宽度 高度
|
||||
const curWidth = dragDom.offsetWidth;
|
||||
const curHeight = dragDom.offsetHeight;
|
||||
document.onmousemove = function(e) {
|
||||
e.preventDefault(); // 移动时禁用默认事件
|
||||
// 通过事件委托,计算移动的距离
|
||||
const xl = e.clientX - disX;
|
||||
const yl = e.clientY - disY
|
||||
dragDom.style.width = `${curWidth + xl}px`;
|
||||
dragDom.style.height = `${curHeight + yl}px`;
|
||||
};
|
||||
document.onmouseup = function(e) {
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
};
|
||||
}, false);
|
||||
dragDom.appendChild(lineEl);
|
||||
}
|
||||
}
|
||||
|
@@ -1,30 +1,30 @@
|
||||
/**
|
||||
* v-dialogDragWidth 可拖动弹窗宽度(右侧边)
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
* v-dialogDragWidth 可拖动弹窗宽度(右侧边)
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
|
||||
export default {
|
||||
bind(el) {
|
||||
const dragDom = el.querySelector('.el-dialog');
|
||||
const lineEl = document.createElement('div');
|
||||
lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;';
|
||||
lineEl.addEventListener('mousedown',
|
||||
function (e) {
|
||||
// 鼠标按下,计算当前元素距离可视区的距离
|
||||
const disX = e.clientX - el.offsetLeft;
|
||||
// 当前宽度
|
||||
const curWidth = dragDom.offsetWidth;
|
||||
document.onmousemove = function (e) {
|
||||
e.preventDefault(); // 移动时禁用默认事件
|
||||
// 通过事件委托,计算移动的距离
|
||||
const l = e.clientX - disX;
|
||||
dragDom.style.width = `${curWidth + l}px`;
|
||||
};
|
||||
document.onmouseup = function (e) {
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
};
|
||||
}, false);
|
||||
dragDom.appendChild(lineEl);
|
||||
}
|
||||
}
|
||||
bind(el) {
|
||||
const dragDom = el.querySelector('.el-dialog');
|
||||
const lineEl = document.createElement('div');
|
||||
lineEl.style = 'width: 5px; background: inherit; height: 80%; position: absolute; right: 0; top: 0; bottom: 0; margin: auto; z-index: 1; cursor: w-resize;';
|
||||
lineEl.addEventListener('mousedown',
|
||||
function (e) {
|
||||
// 鼠标按下,计算当前元素距离可视区的距离
|
||||
const disX = e.clientX - el.offsetLeft;
|
||||
// 当前宽度
|
||||
const curWidth = dragDom.offsetWidth;
|
||||
document.onmousemove = function (e) {
|
||||
e.preventDefault(); // 移动时禁用默认事件
|
||||
// 通过事件委托,计算移动的距离
|
||||
const l = e.clientX - disX;
|
||||
dragDom.style.width = `${curWidth + l}px`;
|
||||
};
|
||||
document.onmouseup = function (e) {
|
||||
document.onmousemove = null;
|
||||
document.onmouseup = null;
|
||||
};
|
||||
}, false);
|
||||
dragDom.appendChild(lineEl);
|
||||
}
|
||||
}
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* v-hasPermi 操作权限处理
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
|
||||
|
||||
import store from '@/store'
|
||||
|
||||
export default {
|
||||
|
@@ -2,7 +2,7 @@
|
||||
* v-hasRole 角色权限处理
|
||||
* Copyright (c) 2019 ruoyi
|
||||
*/
|
||||
|
||||
|
||||
import store from '@/store'
|
||||
|
||||
export default {
|
||||
|
@@ -5,19 +5,28 @@
|
||||
:key="item.path"
|
||||
:iframeId="'iframe' + index"
|
||||
v-show="$route.path === item.path"
|
||||
:src="item.meta.link"
|
||||
:src="iframeUrl(item.meta.link, item.query)"
|
||||
></inner-link>
|
||||
</transition-group>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import InnerLink from "../InnerLink/index"
|
||||
import InnerLink from "../InnerLink/index";
|
||||
|
||||
export default {
|
||||
components: { InnerLink },
|
||||
computed: {
|
||||
iframeViews() {
|
||||
return this.$store.state.tagsView.iframeViews
|
||||
return this.$store.state.tagsView.iframeViews;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
iframeUrl(url, query) {
|
||||
if (Object.keys(query).length > 0) {
|
||||
let params = Object.keys(query).map((key) => key + "=" + query[key]).join("&");
|
||||
return url + "?" + params;
|
||||
}
|
||||
return url;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<div class="right-menu">
|
||||
<template v-if="device!=='mobile'">
|
||||
<search id="header-search" class="right-menu-item" />
|
||||
|
||||
|
||||
<el-tooltip content="源码地址" effect="dark" placement="bottom">
|
||||
<ruo-yi-git id="ruoyi-git" class="right-menu-item hover-effect" />
|
||||
</el-tooltip>
|
||||
|
@@ -38,7 +38,7 @@
|
||||
<el-divider/>
|
||||
|
||||
<h3 class="drawer-title">系统布局配置</h3>
|
||||
|
||||
|
||||
<div class="drawer-item">
|
||||
<span>开启 TopNav</span>
|
||||
<el-switch v-model="topNav" class="drawer-switch" />
|
||||
|
@@ -13,8 +13,8 @@
|
||||
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
|
||||
</template>
|
||||
<sidebar-item
|
||||
v-for="child in item.children"
|
||||
:key="child.path"
|
||||
v-for="(child, index) in item.children"
|
||||
:key="child.path + index"
|
||||
:is-nest="true"
|
||||
:item="child"
|
||||
:base-path="resolvePath(child.path)"
|
||||
|
@@ -87,7 +87,7 @@ export default {
|
||||
bottom: 0px;
|
||||
}
|
||||
.el-scrollbar__wrap {
|
||||
height: 39px;
|
||||
height: 49px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -18,6 +18,8 @@ router.beforeEach((to, from, next) => {
|
||||
if (to.path === '/login') {
|
||||
next({ path: '/' })
|
||||
NProgress.done()
|
||||
} else if (whiteList.indexOf(to.path) !== -1) {
|
||||
next()
|
||||
} else {
|
||||
if (store.getters.roles.length === 0) {
|
||||
isRelogin.show = true
|
||||
@@ -45,7 +47,7 @@ router.beforeEach((to, from, next) => {
|
||||
// 在免登录白名单,直接进入
|
||||
next()
|
||||
} else {
|
||||
next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
|
||||
next(`/login?redirect=${encodeURIComponent(to.fullPath)}`) // 否则全部重定向到登录页
|
||||
NProgress.done()
|
||||
}
|
||||
}
|
||||
|
@@ -1,11 +1,12 @@
|
||||
import axios from 'axios'
|
||||
import { Message } from 'element-ui'
|
||||
import {Loading, Message} from 'element-ui'
|
||||
import { saveAs } from 'file-saver'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import errorCode from '@/utils/errorCode'
|
||||
import { blobValidate } from "@/utils/ruoyi";
|
||||
|
||||
const baseURL = process.env.VUE_APP_BASE_API
|
||||
let downloadLoadingInstance;
|
||||
|
||||
export default {
|
||||
name(name, isDelete = true) {
|
||||
@@ -44,6 +45,7 @@ export default {
|
||||
},
|
||||
zip(url, name) {
|
||||
var url = baseURL + url
|
||||
downloadLoadingInstance = Loading.service({ text: "正在下载数据,请稍候", spinner: "el-icon-loading", background: "rgba(0, 0, 0, 0.7)", })
|
||||
axios({
|
||||
method: 'get',
|
||||
url: url,
|
||||
@@ -57,6 +59,11 @@ export default {
|
||||
} else {
|
||||
this.printErrMsg(res.data);
|
||||
}
|
||||
downloadLoadingInstance.close();
|
||||
}).catch((r) => {
|
||||
console.error(r)
|
||||
Message.error('下载文件出现错误,请联系管理员!')
|
||||
downloadLoadingInstance.close();
|
||||
})
|
||||
},
|
||||
saveAs(text, name, opts) {
|
||||
|
@@ -35,7 +35,7 @@ export default {
|
||||
return store.dispatch('tagsView/delView', router.currentRoute).then(({ visitedViews }) => {
|
||||
const latestView = visitedViews.slice(-1)[0]
|
||||
if (latestView) {
|
||||
return router.push(latestView.fullPath)
|
||||
return router.push(latestView.fullPath)
|
||||
}
|
||||
return router.push('/');
|
||||
});
|
||||
@@ -60,7 +60,7 @@ export default {
|
||||
},
|
||||
// 添加tab页签
|
||||
openPage(title, url, params) {
|
||||
var obj = { path: url, meta: { title: title } }
|
||||
const obj = { path: url, meta: { title: title } }
|
||||
store.dispatch('tagsView/addView', obj);
|
||||
return router.push({ path: url, query: params });
|
||||
},
|
||||
|
@@ -14,7 +14,7 @@ const mutations = {
|
||||
try {
|
||||
for (let i = 0; i < state.dict.length; i++) {
|
||||
if (state.dict[i].key == key) {
|
||||
state.dict.splice(i, i)
|
||||
state.dict.splice(i, 1)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
@@ -98,6 +98,10 @@ function filterChildren(childrenMap, lastRouter = false) {
|
||||
}
|
||||
if (lastRouter) {
|
||||
el.path = lastRouter.path + '/' + el.path
|
||||
if (el.children && el.children.length) {
|
||||
children = children.concat(filterChildren(el.children, el))
|
||||
return
|
||||
}
|
||||
}
|
||||
children = children.concat(el)
|
||||
})
|
||||
|
@@ -4,6 +4,7 @@ import { getToken, setToken, removeToken } from '@/utils/auth'
|
||||
const user = {
|
||||
state: {
|
||||
token: getToken(),
|
||||
id: '',
|
||||
name: '',
|
||||
avatar: '',
|
||||
roles: [],
|
||||
@@ -14,6 +15,9 @@ const user = {
|
||||
SET_TOKEN: (state, token) => {
|
||||
state.token = token
|
||||
},
|
||||
SET_ID: (state, id) => {
|
||||
state.id = id
|
||||
},
|
||||
SET_NAME: (state, name) => {
|
||||
state.name = name
|
||||
},
|
||||
@@ -58,6 +62,7 @@ const user = {
|
||||
} else {
|
||||
commit('SET_ROLES', ['ROLE_DEFAULT'])
|
||||
}
|
||||
commit('SET_ID', user.userId)
|
||||
commit('SET_NAME', user.userName)
|
||||
commit('SET_AVATAR', avatar)
|
||||
resolve(res)
|
||||
|
@@ -5,12 +5,12 @@ import { parseTime } from './ruoyi'
|
||||
*/
|
||||
export function formatDate(cellValue) {
|
||||
if (cellValue == null || cellValue == "") return "";
|
||||
var date = new Date(cellValue)
|
||||
var date = new Date(cellValue)
|
||||
var year = date.getFullYear()
|
||||
var month = date.getMonth() + 1 < 10 ? '0' + (date.getMonth() + 1) : date.getMonth() + 1
|
||||
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
|
||||
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
|
||||
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
|
||||
var day = date.getDate() < 10 ? '0' + date.getDate() : date.getDate()
|
||||
var hours = date.getHours() < 10 ? '0' + date.getHours() : date.getHours()
|
||||
var minutes = date.getMinutes() < 10 ? '0' + date.getMinutes() : date.getMinutes()
|
||||
var seconds = date.getSeconds() < 10 ? '0' + date.getSeconds() : date.getSeconds()
|
||||
return year + '-' + month + '-' + day + ' ' + hours + ':' + minutes + ':' + seconds
|
||||
}
|
||||
@@ -330,7 +330,7 @@ export function makeMap(str, expectsLowerCase) {
|
||||
? val => map[val.toLowerCase()]
|
||||
: val => map[val]
|
||||
}
|
||||
|
||||
|
||||
export const exportDefault = 'export default '
|
||||
|
||||
export const beautifierConf = {
|
||||
@@ -387,4 +387,4 @@ export function camelCase(str) {
|
||||
export function isNumberStr(str) {
|
||||
return /^[+-]?(0|([1-9]\d*))(\.\d+)?$/g.test(str)
|
||||
}
|
||||
|
||||
|
||||
|
@@ -15,10 +15,8 @@ export function checkPermi(value) {
|
||||
return all_permission === permission || permissionDatas.includes(permission)
|
||||
})
|
||||
|
||||
if (!hasPermission) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return hasPermission;
|
||||
|
||||
} else {
|
||||
console.error(`need roles! Like checkPermi="['system:user:add','system:user:edit']"`)
|
||||
return false
|
||||
@@ -40,10 +38,8 @@ export function checkRole(value) {
|
||||
return super_admin === role || permissionRoles.includes(role)
|
||||
})
|
||||
|
||||
if (!hasRole) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
return hasRole;
|
||||
|
||||
} else {
|
||||
console.error(`need roles! Like checkRole="['admin','editor']"`)
|
||||
return false
|
||||
|
@@ -42,6 +42,12 @@ service.interceptors.request.use(config => {
|
||||
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
|
||||
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')
|
||||
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
|
||||
cache.session.setJSON('sessionObj', requestObj)
|
||||
|
@@ -65,10 +65,7 @@ export function validEmail(email) {
|
||||
* @returns {Boolean}
|
||||
*/
|
||||
export function isString(str) {
|
||||
if (typeof str === 'string' || str instanceof String) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return typeof str === 'string' || str instanceof String;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -1,3 +0,0 @@
|
||||
const elementIcons = ['platform-eleme', 'eleme', 'delete-solid', 'delete', 's-tools', 'setting', 'user-solid', 'user', 'phone', 'phone-outline', 'more', 'more-outline', 'star-on', 'star-off', 's-goods', 'goods', 'warning', 'warning-outline', 'question', 'info', 'remove', 'circle-plus', 'success', 'error', 'zoom-in', 'zoom-out', 'remove-outline', 'circle-plus-outline', 'circle-check', 'circle-close', 's-help', 'help', 'minus', 'plus', 'check', 'close', 'picture', 'picture-outline', 'picture-outline-round', 'upload', 'upload2', 'download', 'camera-solid', 'camera', 'video-camera-solid', 'video-camera', 'message-solid', 'bell', 's-cooperation', 's-order', 's-platform', 's-fold', 's-unfold', 's-operation', 's-promotion', 's-home', 's-release', 's-ticket', 's-management', 's-open', 's-shop', 's-marketing', 's-flag', 's-comment', 's-finance', 's-claim', 's-custom', 's-opportunity', 's-data', 's-check', 's-grid', 'menu', 'share', 'd-caret', 'caret-left', 'caret-right', 'caret-bottom', 'caret-top', 'bottom-left', 'bottom-right', 'back', 'right', 'bottom', 'top', 'top-left', 'top-right', 'arrow-left', 'arrow-right', 'arrow-down', 'arrow-up', 'd-arrow-left', 'd-arrow-right', 'video-pause', 'video-play', 'refresh', 'refresh-right', 'refresh-left', 'finished', 'sort', 'sort-up', 'sort-down', 'rank', 'loading', 'view', 'c-scale-to-original', 'date', 'edit', 'edit-outline', 'folder', 'folder-opened', 'folder-add', 'folder-remove', 'folder-delete', 'folder-checked', 'tickets', 'document-remove', 'document-delete', 'document-copy', 'document-checked', 'document', 'document-add', 'printer', 'paperclip', 'takeaway-box', 'search', 'monitor', 'attract', 'mobile', 'scissors', 'umbrella', 'headset', 'brush', 'mouse', 'coordinate', 'magic-stick', 'reading', 'data-line', 'data-board', 'pie-chart', 'data-analysis', 'collection-tag', 'film', 'suitcase', 'suitcase-1', 'receiving', 'collection', 'files', 'notebook-1', 'notebook-2', 'toilet-paper', 'office-building', 'school', 'table-lamp', 'house', 'no-smoking', 'smoking', 'shopping-cart-full', 'shopping-cart-1', 'shopping-cart-2', 'shopping-bag-1', 'shopping-bag-2', 'sold-out', 'sell', 'present', 'box', 'bank-card', 'money', 'coin', 'wallet', 'discount', 'price-tag', 'news', 'guide', 'male', 'female', 'thumb', 'cpu', 'link', 'connection', 'open', 'turn-off', 'set-up', 'chat-round', 'chat-line-round', 'chat-square', 'chat-dot-round', 'chat-dot-square', 'chat-line-square', 'message', 'postcard', 'position', 'turn-off-microphone', 'microphone', 'close-notification', 'bangzhu', 'time', 'odometer', 'crop', 'aim', 'switch-button', 'full-screen', 'copy-document', 'mic', 'stopwatch', 'medal-1', 'medal', 'trophy', 'trophy-1', 'first-aid-kit', 'discover', 'place', 'location', 'location-outline', 'location-information', 'add-location', 'delete-location', 'map-location', 'alarm-clock', 'timer', 'watch-1', 'watch', 'lock', 'unlock', 'key', 'service', 'mobile-phone', 'bicycle', 'truck', 'ship', 'basketball', 'football', 'soccer', 'baseball', 'wind-power', 'light-rain', 'lightning', 'heavy-rain', 'sunrise', 'sunrise-1', 'sunset', 'sunny', 'cloudy', 'partly-cloudy', 'cloudy-and-sunny', 'moon', 'moon-night', 'dish', 'dish-1', 'food', 'chicken', 'fork-spoon', 'knife-fork', 'burger', 'tableware', 'sugar', 'dessert', 'ice-cream', 'hot-water', 'water-cup', 'coffee-cup', 'cold-drink', 'goblet', 'goblet-full', 'goblet-square', 'goblet-square-full', 'refrigerator', 'grape', 'watermelon', 'cherry', 'apple', 'pear', 'orange', 'coffee', 'ice-tea', 'ice-drink', 'milk-tea', 'potato-strips', 'lollipop', 'ice-cream-square', 'ice-cream-round']
|
||||
|
||||
export default elementIcons
|
@@ -1,87 +0,0 @@
|
||||
<template>
|
||||
<div class="icons-container">
|
||||
<aside>
|
||||
<a href="#" target="_blank">Add and use
|
||||
</a>
|
||||
</aside>
|
||||
<el-tabs type="border-card">
|
||||
<el-tab-pane label="Icons">
|
||||
<div v-for="item of svgIcons" :key="item">
|
||||
<el-tooltip placement="top">
|
||||
<div slot="content">
|
||||
{{ generateIconCode(item) }}
|
||||
</div>
|
||||
<div class="icon-item">
|
||||
<svg-icon :icon-class="item" class-name="disabled" />
|
||||
<span>{{ item }}</span>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane label="Element-UI Icons">
|
||||
<div v-for="item of elementIcons" :key="item">
|
||||
<el-tooltip placement="top">
|
||||
<div slot="content">
|
||||
{{ generateElementIconCode(item) }}
|
||||
</div>
|
||||
<div class="icon-item">
|
||||
<i :class="'el-icon-' + item" />
|
||||
<span>{{ item }}</span>
|
||||
</div>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import svgIcons from './svg-icons'
|
||||
import elementIcons from './element-icons'
|
||||
|
||||
export default {
|
||||
name: 'Icons',
|
||||
data() {
|
||||
return {
|
||||
svgIcons,
|
||||
elementIcons
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
generateIconCode(symbol) {
|
||||
return `<svg-icon icon-class="${symbol}" />`
|
||||
},
|
||||
generateElementIconCode(symbol) {
|
||||
return `<i class="el-icon-${symbol}" />`
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.icons-container {
|
||||
margin: 10px 20px 0;
|
||||
overflow: hidden;
|
||||
|
||||
.icon-item {
|
||||
margin: 20px;
|
||||
height: 85px;
|
||||
text-align: center;
|
||||
width: 100px;
|
||||
float: left;
|
||||
font-size: 30px;
|
||||
color: #24292e;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
span {
|
||||
display: block;
|
||||
font-size: 16px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
}
|
||||
</style>
|
@@ -1,10 +0,0 @@
|
||||
const req = require.context('../../../assets/icons/svg', false, /\.svg$/)
|
||||
const requireAll = requireContext => requireContext.keys()
|
||||
|
||||
const re = /\.\/(.*)\.svg/
|
||||
|
||||
const svgIcons = requireAll(req).map(i => {
|
||||
return i.match(re)[1]
|
||||
})
|
||||
|
||||
export default svgIcons
|
@@ -3,7 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from './mixins/resize'
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from './mixins/resize'
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from './mixins/resize'
|
||||
|
||||
|
@@ -3,7 +3,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
import * as echarts from 'echarts'
|
||||
require('echarts/theme/macarons') // echarts theme
|
||||
import resize from './mixins/resize'
|
||||
|
||||
|
@@ -122,7 +122,7 @@
|
||||
<s> 满180251782 </s> <s> 满104180207 </s> <s> 满186866453 </s> <s> 满201396349 </s>
|
||||
<s> 满101456076 </s> <s> 满101539465 </s> <s> 满264312783 </s> <s> 满167385320 </s>
|
||||
<s> 满104748341 </s> <s> 满160110482 </s> <s> 满170801498 </s> <s> 满108482800 </s>
|
||||
<s> 满101046199 </s> <a href="https://jq.qq.com/?_wv=1027&k=tKEt51dz" target="_blank">136919097</a>
|
||||
<s> 满101046199 </s> <s> 满136919097 </s> <s> 满143961921 </s> <a href="http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=1HmEGh7zKA_CKI2E-pGInPTlC5jS9mc_&authKey=XaiUf1wfbSTEecm4lDMtIMsc6g%2BoETxjBm1BbZPr6IfuMGRj7oG4GEeu7jtzNaw%2F&noverify=0&group_code=174951577" target="_blank">174951577</a>
|
||||
</p>
|
||||
<p>
|
||||
<i class="el-icon-chat-dot-round"></i> 微信:<a
|
||||
@@ -146,6 +146,49 @@
|
||||
<span>更新日志</span>
|
||||
</div>
|
||||
<el-collapse accordion>
|
||||
<el-collapse-item title="v3.8.7 - 2023-12-08">
|
||||
<ol>
|
||||
<li>操作日志记录部门名称</li>
|
||||
<li>全局数据存储用户编号</li>
|
||||
<li>新增编程式判断资源访问权限</li>
|
||||
<li>操作日志列表新增IP地址查询</li>
|
||||
<li>定时任务新增页去除状态选项</li>
|
||||
<li>代码生成支持选择前端模板类型</li>
|
||||
<li>显隐列组件支持复选框弹出类型</li>
|
||||
<li>通用排序属性orderBy参数限制长度</li>
|
||||
<li>Excel自定义数据处理器增加单元格/工作簿对象</li>
|
||||
<li>升级oshi到最新版本6.4.8</li>
|
||||
<li>升级druid到最新版本1.2.20</li>
|
||||
<li>升级fastjson到最新版2.0.43</li>
|
||||
<li>升级pagehelper到最新版1.4.7</li>
|
||||
<li>升级commons.io到最新版本2.13.0</li>
|
||||
<li>升级element-ui到最新版本2.15.14</li>
|
||||
<li>修复五级路由缓存无效问题</li>
|
||||
<li>修复外链带端口出现的异常</li>
|
||||
<li>修复树模板父级编码变量错误</li>
|
||||
<li>修复字典表详情页面搜索问题</li>
|
||||
<li>修复内链iframe没有传递参数问题</li>
|
||||
<li>修复自定义字典样式不生效的问题</li>
|
||||
<li>修复字典缓存删除方法参数错误问题</li>
|
||||
<li>修复Excel导入数据临时文件无法删除问题</li>
|
||||
<li>修复未登录带参数访问成功后参数丢失问题</li>
|
||||
<li>修复HeaderSearch组件跳转query参数丢失问题</li>
|
||||
<li>修复代码生成导入后必填项与数据库不匹配问题</li>
|
||||
<li>修复Excels导入时无法获取到dictType字典值问题</li>
|
||||
<li>优化下载zip方法新增遮罩层</li>
|
||||
<li>优化头像上传参数新增文件名称</li>
|
||||
<li>优化字典标签支持自定义分隔符</li>
|
||||
<li>优化菜单管理类型为按钮状态可选</li>
|
||||
<li>优化前端防重复提交数据大小限制</li>
|
||||
<li>优化TopNav菜单没有图标svg不显示</li>
|
||||
<li>优化数字金额大写转换精度丢失问题</li>
|
||||
<li>优化富文本Editor组件检验图片格式</li>
|
||||
<li>优化页签在Firefox浏览器被遮挡的问题</li>
|
||||
<li>优化个人中心/基本资料修改时数据显示问题</li>
|
||||
<li>优化缓存监控图表支持跟随屏幕大小自适应调整</li>
|
||||
<li>其他细节优化</li>
|
||||
</ol>
|
||||
</el-collapse-item>
|
||||
<el-collapse-item title="v3.8.6 - 2023-06-30">
|
||||
<ol>
|
||||
<li>支持登录IP黑名单限制</li>
|
||||
@@ -946,7 +989,7 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
// 版本号
|
||||
version: "3.8.6"
|
||||
version: "3.8.7"
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
|
4
ruoyi-ui/src/views/monitor/cache/index.vue
vendored
4
ruoyi-ui/src/views/monitor/cache/index.vue
vendored
@@ -133,6 +133,10 @@ export default {
|
||||
}
|
||||
]
|
||||
});
|
||||
window.addEventListener("resize", () => {
|
||||
this.commandstats.resize();
|
||||
this.usedmemory.resize();
|
||||
});
|
||||
});
|
||||
},
|
||||
// 打开加载层
|
||||
|
@@ -200,7 +200,18 @@
|
||||
</el-input>
|
||||
</el-form-item>
|
||||
</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-radio-group v-model="form.misfirePolicy" size="small">
|
||||
<el-radio-button label="1">立即执行</el-radio-button>
|
||||
@@ -217,17 +228,6 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</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-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
@@ -264,7 +264,7 @@
|
||||
<el-col :span="12">
|
||||
<el-form-item label="任务状态:">
|
||||
<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-col>
|
||||
<el-col :span="12">
|
||||
|
@@ -1,6 +1,15 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
|
||||
<el-form-item label="操作地址" prop="operIp">
|
||||
<el-input
|
||||
v-model="queryParams.operIp"
|
||||
placeholder="请输入操作地址"
|
||||
clearable
|
||||
style="width: 240px;"
|
||||
@keyup.enter.native="handleQuery"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="系统模块" prop="title">
|
||||
<el-input
|
||||
v-model="queryParams.title"
|
||||
@@ -151,7 +160,7 @@
|
||||
/>
|
||||
|
||||
<!-- 操作日志详细 -->
|
||||
<el-dialog title="操作日志详细" :visible.sync="open" width="700px" append-to-body>
|
||||
<el-dialog title="操作日志详细" :visible.sync="open" width="800px" append-to-body>
|
||||
<el-form ref="form" :model="form" label-width="100px" size="mini">
|
||||
<el-row>
|
||||
<el-col :span="12">
|
||||
@@ -173,7 +182,7 @@
|
||||
<el-col :span="24">
|
||||
<el-form-item label="返回参数:">{{ form.jsonResult }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="操作状态:">
|
||||
<div v-if="form.status === 0">正常</div>
|
||||
<div v-else-if="form.status === 1">失败</div>
|
||||
@@ -182,7 +191,7 @@
|
||||
<el-col :span="8">
|
||||
<el-form-item label="消耗时间:">{{ form.costTime }}毫秒</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="10">
|
||||
<el-col :span="8">
|
||||
<el-form-item label="操作时间:">{{ parseTime(form.operTime) }}</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="24">
|
||||
@@ -229,6 +238,7 @@ export default {
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
operIp: undefined,
|
||||
title: undefined,
|
||||
operName: undefined,
|
||||
businessType: undefined,
|
||||
|
@@ -95,8 +95,8 @@
|
||||
<el-table-column label="字典编码" align="center" prop="dictCode" />
|
||||
<el-table-column label="字典标签" align="center" prop="dictLabel">
|
||||
<template slot-scope="scope">
|
||||
<span v-if="scope.row.listClass == '' || scope.row.listClass == 'default'">{{scope.row.dictLabel}}</span>
|
||||
<el-tag v-else :type="scope.row.listClass == 'primary' ? '' : scope.row.listClass">{{scope.row.dictLabel}}</el-tag>
|
||||
<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" :class="scope.row.cssClass">{{ scope.row.dictLabel }}</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="字典键值" align="center" prop="dictValue" />
|
||||
@@ -251,8 +251,8 @@ export default {
|
||||
queryParams: {
|
||||
pageNum: 1,
|
||||
pageSize: 10,
|
||||
dictName: undefined,
|
||||
dictType: undefined,
|
||||
dictLabel: undefined,
|
||||
status: undefined
|
||||
},
|
||||
// 表单参数
|
||||
|
@@ -246,7 +246,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12" v-if="form.menuType != 'F'">
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="status">
|
||||
<span slot="label">
|
||||
<el-tooltip content="选择停用则路由将不会出现在侧边栏,也不能被访问" placement="top">
|
||||
|
@@ -33,7 +33,7 @@
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
|
||||
<pagination v-show="total>0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" />
|
||||
|
||||
<el-form label-width="100px">
|
||||
|
@@ -8,7 +8,7 @@
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-center">
|
||||
<userAvatar :user="user" />
|
||||
<userAvatar />
|
||||
</div>
|
||||
<ul class="list-group list-group-striped">
|
||||
<li class="list-group-item">
|
||||
|
@@ -61,11 +61,6 @@ import { debounce } from '@/utils'
|
||||
|
||||
export default {
|
||||
components: { VueCropper },
|
||||
props: {
|
||||
user: {
|
||||
type: Object
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 是否显示弹出层
|
||||
@@ -75,12 +70,13 @@ export default {
|
||||
// 弹出层标题
|
||||
title: "修改头像",
|
||||
options: {
|
||||
img: store.getters.avatar, //裁剪图片的地址
|
||||
autoCrop: true, // 是否默认生成截图框
|
||||
autoCropWidth: 200, // 默认生成截图框宽度
|
||||
autoCropHeight: 200, // 默认生成截图框高度
|
||||
fixedBox: true, // 固定截图框大小 不允许改变
|
||||
outputType:"png" // 默认生成截图为PNG格式
|
||||
img: store.getters.avatar, //裁剪图片的地址
|
||||
autoCrop: true, // 是否默认生成截图框
|
||||
autoCropWidth: 200, // 默认生成截图框宽度
|
||||
autoCropHeight: 200, // 默认生成截图框高度
|
||||
fixedBox: true, // 固定截图框大小 不允许改变
|
||||
outputType:"png", // 默认生成截图为PNG格式
|
||||
filename: 'avatar' // 文件名称
|
||||
},
|
||||
previews: {},
|
||||
resizeHandler: null
|
||||
@@ -130,6 +126,7 @@ export default {
|
||||
reader.readAsDataURL(file);
|
||||
reader.onload = () => {
|
||||
this.options.img = reader.result;
|
||||
this.options.filename = file.name;
|
||||
};
|
||||
}
|
||||
},
|
||||
@@ -137,7 +134,7 @@ export default {
|
||||
uploadImg() {
|
||||
this.$refs.cropper.getCropBlob(data => {
|
||||
let formData = new FormData();
|
||||
formData.append("avatarfile", data);
|
||||
formData.append("avatarfile", data, this.options.filename);
|
||||
uploadAvatar(formData).then(response => {
|
||||
this.open = false;
|
||||
this.options.img = process.env.VUE_APP_BASE_API + response.imgUrl;
|
||||
|
@@ -1,16 +1,16 @@
|
||||
<template>
|
||||
<el-form ref="form" :model="user" :rules="rules" label-width="80px">
|
||||
<el-form ref="form" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="用户昵称" prop="nickName">
|
||||
<el-input v-model="user.nickName" maxlength="30" />
|
||||
<el-input v-model="form.nickName" maxlength="30" />
|
||||
</el-form-item>
|
||||
<el-form-item label="手机号码" prop="phonenumber">
|
||||
<el-input v-model="user.phonenumber" maxlength="11" />
|
||||
<el-input v-model="form.phonenumber" maxlength="11" />
|
||||
</el-form-item>
|
||||
<el-form-item label="邮箱" prop="email">
|
||||
<el-input v-model="user.email" maxlength="50" />
|
||||
<el-input v-model="form.email" maxlength="50" />
|
||||
</el-form-item>
|
||||
<el-form-item label="性别">
|
||||
<el-radio-group v-model="user.sex">
|
||||
<el-radio-group v-model="form.sex">
|
||||
<el-radio label="0">男</el-radio>
|
||||
<el-radio label="1">女</el-radio>
|
||||
</el-radio-group>
|
||||
@@ -33,6 +33,7 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
form: {},
|
||||
// 表单校验
|
||||
rules: {
|
||||
nickName: [
|
||||
@@ -57,12 +58,24 @@ export default {
|
||||
}
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
user: {
|
||||
handler(user) {
|
||||
if (user) {
|
||||
this.form = { nickName: user.nickName, phonenumber: user.phonenumber, email: user.email, sex: user.sex };
|
||||
}
|
||||
},
|
||||
immediate: true
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit() {
|
||||
this.$refs["form"].validate(valid => {
|
||||
if (valid) {
|
||||
updateUserProfile(this.user).then(response => {
|
||||
updateUserProfile(this.form).then(response => {
|
||||
this.$modal.msgSuccess("修改成功");
|
||||
this.user.phonenumber = this.form.phonenumber;
|
||||
this.user.email = this.form.email;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@@ -11,6 +11,15 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="tplWebType">
|
||||
<span slot="label">前端类型</span>
|
||||
<el-select v-model="info.tplWebType">
|
||||
<el-option label="Vue2 Element UI 模版" value="element-ui" />
|
||||
<el-option label="Vue3 Element Plus 模版" value="element-plus" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="packageName">
|
||||
<span slot="label">
|
||||
@@ -59,6 +68,19 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="genType">
|
||||
<span slot="label">
|
||||
生成代码方式
|
||||
<el-tooltip content="默认为zip压缩包下载,也可以自定义生成路径" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-radio v-model="info.genType" label="0">zip压缩包</el-radio>
|
||||
<el-radio v-model="info.genType" label="1">自定义路径</el-radio>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item>
|
||||
<span slot="label">
|
||||
@@ -78,19 +100,6 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="12">
|
||||
<el-form-item prop="genType">
|
||||
<span slot="label">
|
||||
生成代码方式
|
||||
<el-tooltip content="默认为zip压缩包下载,也可以自定义生成路径" placement="top">
|
||||
<i class="el-icon-question"></i>
|
||||
</el-tooltip>
|
||||
</span>
|
||||
<el-radio v-model="info.genType" label="0">zip压缩包</el-radio>
|
||||
<el-radio v-model="info.genType" label="1">自定义路径</el-radio>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24" v-if="info.genType == '1'">
|
||||
<el-form-item prop="genPath">
|
||||
<span slot="label">
|
||||
@@ -255,10 +264,14 @@ export default {
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {},
|
||||
watch: {
|
||||
'info.subTableName': function(val) {
|
||||
this.setSubTableColumns(val);
|
||||
},
|
||||
'info.tplWebType': function(val) {
|
||||
if (val === '') {
|
||||
this.info.tplWebType = "element-ui";
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@@ -112,7 +112,7 @@ module.exports = {
|
||||
elementUI: {
|
||||
name: 'chunk-elementUI', // split elementUI into a single package
|
||||
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
|
||||
priority: 20 // the weight needs to be larger than libs and app or it will be packaged into libs or app
|
||||
},
|
||||
commons: {
|
||||
name: 'chunk-commons',
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user