Merge remote-tracking branch 'origin/master'

# Conflicts:
#	pom.xml
This commit is contained in:
yjb 2021-10-23 23:09:05 +08:00
commit 7acb128111
21 changed files with 290 additions and 183 deletions

16
pom.xml
View File

@ -18,15 +18,15 @@
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version> <java.version>1.8</java.version>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version> <maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<druid.version>1.2.6</druid.version> <druid.version>1.2.8</druid.version>
<bitwalker.version>1.21</bitwalker.version> <bitwalker.version>1.21</bitwalker.version>
<swagger.version>3.0.0</swagger.version> <swagger.version>3.0.0</swagger.version>
<kaptcha.version>2.3.2</kaptcha.version> <kaptcha.version>2.3.2</kaptcha.version>
<mybatis-spring-boot.version>2.1.4</mybatis-spring-boot.version> <mybatis-spring-boot.version>2.2.0</mybatis-spring-boot.version>
<pagehelper.boot.version>1.3.1</pagehelper.boot.version> <pagehelper.boot.version>1.4.0</pagehelper.boot.version>
<fastjson.version>1.2.78</fastjson.version> <fastjson.version>1.2.78</fastjson.version>
<oshi.version>5.8.0</oshi.version> <oshi.version>5.8.2</oshi.version>
<jna.version>5.8.0</jna.version> <jna.version>5.9.0</jna.version>
<commons.io.version>2.11.0</commons.io.version> <commons.io.version>2.11.0</commons.io.version>
<commons.fileupload.version>1.4</commons.fileupload.version> <commons.fileupload.version>1.4</commons.fileupload.version>
<commons.collections.version>3.2.2</commons.collections.version> <commons.collections.version>3.2.2</commons.collections.version>
@ -43,7 +43,7 @@
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId> <artifactId>spring-boot-dependencies</artifactId>
<version>2.2.13.RELEASE</version> <version>2.5.5</version>
<type>pom</type> <type>pom</type>
<scope>import</scope> <scope>import</scope>
</dependency> </dependency>
@ -242,7 +242,7 @@
<repository> <repository>
<id>public</id> <id>public</id>
<name>aliyun nexus</name> <name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url> <url>https://maven.aliyun.com/repository/public</url>
<releases> <releases>
<enabled>true</enabled> <enabled>true</enabled>
</releases> </releases>
@ -253,7 +253,7 @@
<pluginRepository> <pluginRepository>
<id>public</id> <id>public</id>
<name>aliyun nexus</name> <name>aliyun nexus</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url> <url>https://maven.aliyun.com/repository/public</url>
<releases> <releases>
<enabled>true</enabled> <enabled>true</enabled>
</releases> </releases>

View File

@ -1,13 +1,13 @@
package com.ruoyi.web.controller.system; package com.ruoyi.web.controller.system;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.model.RegisterBody; import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.SysRegisterService; import com.ruoyi.framework.web.service.SysRegisterService;
import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysConfigService;

View File

@ -145,4 +145,18 @@ public class AjaxResult extends HashMap<String, Object>
{ {
return new AjaxResult(code, msg, null); return new AjaxResult(code, msg, null);
} }
/**
* 方便链式调用
*
* @param key
* @param value
* @return 数据对象
*/
@Override
public AjaxResult put(String key, Object value)
{
super.put(key, value);
return this;
}
} }

View File

@ -4,7 +4,7 @@ import java.util.Collection;
import java.util.Set; import java.util.Set;
import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.alibaba.fastjson.annotation.JSONField;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
/** /**
@ -119,7 +119,7 @@ public class LoginUser implements UserDetails
this.permissions = permissions; this.permissions = permissions;
} }
@JsonIgnore @JSONField(serialize = false)
@Override @Override
public String getPassword() public String getPassword()
{ {
@ -135,7 +135,7 @@ public class LoginUser implements UserDetails
/** /**
* 账户是否未过期,过期无法验证 * 账户是否未过期,过期无法验证
*/ */
@JsonIgnore @JSONField(serialize = false)
@Override @Override
public boolean isAccountNonExpired() public boolean isAccountNonExpired()
{ {
@ -147,7 +147,7 @@ public class LoginUser implements UserDetails
* *
* @return * @return
*/ */
@JsonIgnore @JSONField(serialize = false)
@Override @Override
public boolean isAccountNonLocked() public boolean isAccountNonLocked()
{ {
@ -159,7 +159,7 @@ public class LoginUser implements UserDetails
* *
* @return * @return
*/ */
@JsonIgnore @JSONField(serialize = false)
@Override @Override
public boolean isCredentialsNonExpired() public boolean isCredentialsNonExpired()
{ {
@ -171,7 +171,7 @@ public class LoginUser implements UserDetails
* *
* @return * @return
*/ */
@JsonIgnore @JSONField(serialize = false)
@Override @Override
public boolean isEnabled() public boolean isEnabled()
{ {

View File

@ -19,6 +19,7 @@ import javax.net.ssl.X509TrustManager;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.StringUtils;
/** /**
* 通用http发送方法 * 通用http发送方法
@ -55,7 +56,7 @@ public class HttpUtils
BufferedReader in = null; BufferedReader in = null;
try try
{ {
String urlNameString = url + "?" + param; String urlNameString = StringUtils.isNotBlank(param) ? url + "?" + param : url;
log.info("sendGet - {}", urlNameString); log.info("sendGet - {}", urlNameString);
URL realUrl = new URL(urlNameString); URL realUrl = new URL(urlNameString);
URLConnection connection = realUrl.openConnection(); URLConnection connection = realUrl.openConnection();

View File

@ -268,22 +268,15 @@ public class ExcelUtil<T>
} }
} }
// 有数据时才处理 得到类的所有field. // 有数据时才处理 得到类的所有field.
Field[] allFields = clazz.getDeclaredFields(); List<Object[]> fields = this.getFields();
// 定义一个map用于存放列的序号和field. Map<Integer, Object[]> fieldsMap = new HashMap<Integer, Object[]>();
Map<Integer, Field> fieldsMap = new HashMap<Integer, Field>(); for (Object[] objects : fields)
for (int col = 0; col < allFields.length; col++)
{ {
Field field = allFields[col]; Excel attr = (Excel) objects[1];
Excel attr = field.getAnnotation(Excel.class); Integer column = cellMap.get(attr.name());
if (attr != null && (attr.type() == Type.ALL || attr.type() == type)) if (column != null)
{ {
// 设置类的私有字段属性可访问. fieldsMap.put(column, objects);
field.setAccessible(true);
Integer column = cellMap.get(attr.name());
if (column != null)
{
fieldsMap.put(column, field);
}
} }
} }
for (int i = titleNum + 1; i <= rows; i++) for (int i = titleNum + 1; i <= rows; i++)
@ -296,14 +289,15 @@ public class ExcelUtil<T>
continue; continue;
} }
T entity = null; T entity = null;
for (Map.Entry<Integer, Field> entry : fieldsMap.entrySet()) for (Map.Entry<Integer, Object[]> entry : fieldsMap.entrySet())
{ {
Object val = this.getCellValue(row, entry.getKey()); Object val = this.getCellValue(row, entry.getKey());
// 如果不存在实例则新建. // 如果不存在实例则新建.
entity = (entity == null ? clazz.newInstance() : entity); entity = (entity == null ? clazz.newInstance() : entity);
// 从map中得到对应列的field. // 从map中得到对应列的field.
Field field = fieldsMap.get(entry.getKey()); Field field = (Field) entry.getValue()[0];
Excel attr = (Excel) entry.getValue()[1];
// 取得类型,并根据对象类型设置值. // 取得类型,并根据对象类型设置值.
Class<?> fieldType = field.getType(); Class<?> fieldType = field.getType();
if (String.class == fieldType) if (String.class == fieldType)
@ -363,7 +357,6 @@ public class ExcelUtil<T>
} }
if (StringUtils.isNotNull(fieldType)) if (StringUtils.isNotNull(fieldType))
{ {
Excel attr = field.getAnnotation(Excel.class);
String propertyName = field.getName(); String propertyName = field.getName();
if (StringUtils.isNotEmpty(attr.targetAttr())) if (StringUtils.isNotEmpty(attr.targetAttr()))
{ {
@ -493,7 +486,7 @@ public class ExcelUtil<T>
*/ */
public void importTemplateExcel(HttpServletResponse response, String sheetName) throws IOException public void importTemplateExcel(HttpServletResponse response, String sheetName) throws IOException
{ {
importTemplateExcel(response, sheetName); importTemplateExcel(response, sheetName, StringUtils.EMPTY);
} }
/** /**
@ -610,8 +603,6 @@ public class ExcelUtil<T>
{ {
Field field = (Field) os[0]; Field field = (Field) os[0];
Excel excel = (Excel) os[1]; Excel excel = (Excel) os[1];
// 设置实体类私有属性可访问
field.setAccessible(true);
this.addCell(excel, row, vo, field, column++); this.addCell(excel, row, vo, field, column++);
} }
} }
@ -1164,7 +1155,17 @@ public class ExcelUtil<T>
*/ */
private void createExcelField() private void createExcelField()
{ {
this.fields = new ArrayList<Object[]>(); this.fields = getFields();
this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList());
this.maxHeight = getRowHeight();
}
/**
* 获取字段注解信息
*/
public List<Object[]> getFields()
{
List<Object[]> fields = new ArrayList<Object[]>();
List<Field> tempFields = new ArrayList<>(); List<Field> tempFields = new ArrayList<>();
tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields())); tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields())); tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
@ -1173,7 +1174,12 @@ public class ExcelUtil<T>
// 单注解 // 单注解
if (field.isAnnotationPresent(Excel.class)) if (field.isAnnotationPresent(Excel.class))
{ {
putToField(field, field.getAnnotation(Excel.class)); Excel attr = field.getAnnotation(Excel.class);
if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
{
field.setAccessible(true);
fields.add(new Object[] { field, attr });
}
} }
// 多注解 // 多注解
@ -1181,14 +1187,17 @@ public class ExcelUtil<T>
{ {
Excels attrs = field.getAnnotation(Excels.class); Excels attrs = field.getAnnotation(Excels.class);
Excel[] excels = attrs.value(); Excel[] excels = attrs.value();
for (Excel excel : excels) for (Excel attr : excels)
{ {
putToField(field, excel); if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
{
field.setAccessible(true);
fields.add(new Object[] { field, attr });
}
} }
} }
} }
this.fields = this.fields.stream().sorted(Comparator.comparing(objects -> ((Excel) objects[1]).sort())).collect(Collectors.toList()); return fields;
this.maxHeight = getRowHeight();
} }
/** /**
@ -1205,17 +1214,6 @@ public class ExcelUtil<T>
return (short) (maxHeight * 20); return (short) (maxHeight * 20);
} }
/**
* 放到字段集合中
*/
private void putToField(Field field, Excel attr)
{
if (attr != null && (attr.type() == Type.ALL || attr.type() == type))
{
this.fields.add(new Object[] { field, attr });
}
}
/** /**
* 创建一个工作簿 * 创建一个工作簿
*/ */

View File

@ -28,10 +28,12 @@ public class ResourcesConfig implements WebMvcConfigurer
public void addResourceHandlers(ResourceHandlerRegistry registry) public void addResourceHandlers(ResourceHandlerRegistry registry)
{ {
/** 本地文件上传路径 */ /** 本地文件上传路径 */
registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**").addResourceLocations("file:" + RuoYiConfig.getProfile() + "/"); registry.addResourceHandler(Constants.RESOURCE_PREFIX + "/**")
.addResourceLocations("file:" + RuoYiConfig.getProfile() + "/");
/** swagger配置 */ /** swagger配置 */
registry.addResourceHandler("/swagger-ui/**").addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/"); registry.addResourceHandler("/swagger-ui/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/springfox-swagger-ui/");
} }
/** /**
@ -49,17 +51,20 @@ public class ResourcesConfig implements WebMvcConfigurer
@Bean @Bean
public CorsFilter corsFilter() public CorsFilter corsFilter()
{ {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration(); CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true); config.setAllowCredentials(true);
// 设置访问源地址 // 设置访问源地址
config.addAllowedOrigin("*"); config.addAllowedOriginPattern("*");
// 设置访问源请求头 // 设置访问源请求头
config.addAllowedHeader("*"); config.addAllowedHeader("*");
// 设置访问源请求方法 // 设置访问源请求方法
config.addAllowedMethod("*"); config.addAllowedMethod("*");
// 对接口配置跨域设置 // 有效期 1800秒
config.setMaxAge(1800L);
// 添加映射路径拦截一切请求
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", config); source.registerCorsConfiguration("/**", config);
// 返回新的CorsFilter
return new CorsFilter(source); return new CorsFilter(source);
} }
} }

View File

@ -5,7 +5,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod; import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; import org.springframework.web.servlet.HandlerInterceptor;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.ruoyi.common.annotation.RepeatSubmit; import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.domain.AjaxResult; import com.ruoyi.common.core.domain.AjaxResult;
@ -17,7 +17,7 @@ import com.ruoyi.common.utils.ServletUtils;
* @author ruoyi * @author ruoyi
*/ */
@Component @Component
public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter public abstract class RepeatSubmitInterceptor implements HandlerInterceptor
{ {
@Override @Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
@ -40,7 +40,7 @@ public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter
} }
else else
{ {
return super.preHandle(request, response, handler); return true;
} }
} }

View File

@ -2,7 +2,6 @@ package com.ruoyi.framework.web.service;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import com.ruoyi.common.constant.Constants; import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.constant.UserConstants; import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.domain.entity.SysUser; import com.ruoyi.common.core.domain.entity.SysUser;
@ -12,6 +11,7 @@ import com.ruoyi.common.exception.user.CaptchaException;
import com.ruoyi.common.exception.user.CaptchaExpireException; import com.ruoyi.common.exception.user.CaptchaExpireException;
import com.ruoyi.common.utils.MessageUtils; import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.common.utils.SecurityUtils; import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.manager.AsyncManager; import com.ruoyi.framework.manager.AsyncManager;
import com.ruoyi.framework.manager.factory.AsyncFactory; import com.ruoyi.framework.manager.factory.AsyncFactory;
import com.ruoyi.system.service.ISysConfigService; import com.ruoyi.system.service.ISysConfigService;

View File

@ -39,7 +39,7 @@ public interface SysRoleMapper
* @param userId 用户ID * @param userId 用户ID
* @return 选中角色ID列表 * @return 选中角色ID列表
*/ */
public List<Integer> selectRoleListByUserId(Long userId); public List<Long> selectRoleListByUserId(Long userId);
/** /**
* 通过角色ID查询角色 * 通过角色ID查询角色

View File

@ -49,7 +49,7 @@ public interface ISysRoleService
* @param userId 用户ID * @param userId 用户ID
* @return 选中角色ID列表 * @return 选中角色ID列表
*/ */
public List<Integer> selectRoleListByUserId(Long userId); public List<Long> selectRoleListByUserId(Long userId);
/** /**
* 通过角色ID查询角色 * 通过角色ID查询角色

View File

@ -122,7 +122,7 @@ public class SysRoleServiceImpl implements ISysRoleService
* @return 选中角色ID列表 * @return 选中角色ID列表
*/ */
@Override @Override
public List<Integer> selectRoleListByUserId(Long userId) public List<Long> selectRoleListByUserId(Long userId)
{ {
return roleMapper.selectRoleListByUserId(userId); return roleMapper.selectRoleListByUserId(userId);
} }

View File

@ -65,7 +65,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectRoleVo"/> <include refid="selectRoleVo"/>
</select> </select>
<select id="selectRoleListByUserId" parameterType="Long" resultType="Integer"> <select id="selectRoleListByUserId" parameterType="Long" resultType="Long">
select r.role_id select r.role_id
from sys_role r from sys_role r
left join sys_user_role ur on ur.role_id = r.role_id left join sys_user_role ur on ur.role_id = r.role_id

View File

@ -0,0 +1,60 @@
import store from '@/store'
function authPermission(permission) {
const all_permission = "*:*:*";
const permissions = store.getters && store.getters.permissions
if (permission && permission.length > 0) {
return permissions.some(v => {
return all_permission === v || v === permission
})
} else {
return false
}
}
function authRole(role) {
const super_admin = "admin";
const roles = store.getters && store.getters.roles
if (role && role.length > 0) {
return roles.some(v => {
return super_admin === v || v === role
})
} else {
return false
}
}
export default {
// 验证用户是否具备某权限
hasPermi(permission) {
return authPermission(permission);
},
// 验证用户是否含有指定权限,只需包含其中一个
hasPermiOr(permissions) {
return permissions.some(item => {
return authPermission(item)
})
},
// 验证用户是否含有指定权限,必须全部拥有
hasPermiAnd(permissions) {
return permissions.every(item => {
return authPermission(item)
})
},
// 验证用户是否具备某角色
hasRole(role) {
return authRole(role);
},
// 验证用户是否含有指定角色,只需包含其中一个
hasRoleOr(roles) {
return roles.some(item => {
return authRole(item)
})
},
// 验证用户是否含有指定角色,必须全部拥有
hasRoleAnd(roles) {
return roles.every(item => {
return authRole(item)
})
}
}

View File

@ -1,6 +1,7 @@
import { saveAs } from 'file-saver' import { saveAs } from 'file-saver'
import axios from 'axios' import axios from 'axios'
import { getToken } from '@/utils/auth' import { getToken } from '@/utils/auth'
import { Message } from 'element-ui'
const baseURL = process.env.VUE_APP_BASE_API const baseURL = process.env.VUE_APP_BASE_API
@ -12,9 +13,14 @@ export default {
url: url, url: url,
responseType: 'blob', responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() } headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => { }).then(async (res) => {
const blob = new Blob([res.data]) const isLogin = await this.blobValidate(res.data);
this.saveAs(blob, decodeURI(res.headers['download-filename'])) if (isLogin) {
const blob = new Blob([res.data])
this.saveAs(blob, decodeURI(res.headers['download-filename']))
} else {
Message.error('无效的会话,或者会话已过期,请重新登录。');
}
}) })
}, },
resource(resource) { resource(resource) {
@ -24,9 +30,14 @@ export default {
url: url, url: url,
responseType: 'blob', responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() } headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => { }).then(async (res) => {
const blob = new Blob([res.data]) const isLogin = await this.blobValidate(res.data);
this.saveAs(blob, decodeURI(res.headers['download-filename'])) if (isLogin) {
const blob = new Blob([res.data])
this.saveAs(blob, decodeURI(res.headers['download-filename']))
} else {
Message.error('无效的会话,或者会话已过期,请重新登录。');
}
}) })
}, },
zip(url, name) { zip(url, name) {
@ -36,13 +47,27 @@ export default {
url: url, url: url,
responseType: 'blob', responseType: 'blob',
headers: { 'Authorization': 'Bearer ' + getToken() } headers: { 'Authorization': 'Bearer ' + getToken() }
}).then(res => { }).then(async (res) => {
const blob = new Blob([res.data], { type: 'application/zip' }) const isLogin = await this.blobValidate(res.data);
this.saveAs(blob, name) if (isLogin) {
const blob = new Blob([res.data], { type: 'application/zip' })
this.saveAs(blob, name)
} else {
Message.error('无效的会话,或者会话已过期,请重新登录。');
}
}) })
}, },
saveAs(text, name, opts) { saveAs(text, name, opts) {
saveAs(text, name, opts); saveAs(text, name, opts);
} },
async blobValidate(data) {
try {
const text = await data.text();
JSON.parse(text);
return false;
} catch (error) {
return true;
}
},
} }

View File

@ -1,9 +1,12 @@
import auth from './auth'
import cache from './cache' import cache from './cache'
import modal from './modal' import modal from './modal'
import download from './download' import download from './download'
export default { export default {
install(Vue) { install(Vue) {
// 认证对象
Vue.prototype.$auth = auth
// 缓存对象 // 缓存对象
Vue.prototype.$cache = cache Vue.prototype.$cache = cache
// 模态框对象 // 模态框对象

View File

@ -86,7 +86,7 @@ function filterChildren(childrenMap, lastRouter = false) {
var children = [] var children = []
childrenMap.forEach((el, index) => { childrenMap.forEach((el, index) => {
if (el.children && el.children.length) { if (el.children && el.children.length) {
if (el.component === 'ParentView') { if (el.component === 'ParentView' && !lastRouter) {
el.children.forEach(c => { el.children.forEach(c => {
c.path = el.path + '/' + c.path c.path = el.path + '/' + c.path
if (c.children && c.children.length) { if (c.children && c.children.length) {
@ -106,8 +106,13 @@ function filterChildren(childrenMap, lastRouter = false) {
return children return children
} }
export const loadView = (view) => { // 路由懒加载 export const loadView = (view) => {
return (resolve) => require([`@/views/${view}`], resolve) if (process.env.NODE_ENV === 'development') {
return (resolve) => require([`@/views/${view}`], resolve)
} else {
// 使用 import 实现生产环境的路由懒加载
return () => import(`@/views/${view}`)
}
} }
export default permission export default permission

View File

@ -8,34 +8,34 @@
<table cellspacing="0" style="width: 100%"> <table cellspacing="0" style="width: 100%">
<tbody> <tbody>
<tr> <tr>
<td><div class="cell">Redis版本</div></td> <td class="el-table__cell is-leaf"><div class="cell">Redis版本</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.redis_version }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.redis_version }}</div></td>
<td><div class="cell">运行模式</div></td> <td class="el-table__cell is-leaf"><div class="cell">运行模式</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.redis_mode == "standalone" ? "单机" : "集群" }}</div></td>
<td><div class="cell">端口</div></td> <td class="el-table__cell is-leaf"><div class="cell">端口</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.tcp_port }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.tcp_port }}</div></td>
<td><div class="cell">客户端数</div></td> <td class="el-table__cell is-leaf"><div class="cell">客户端数</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.connected_clients }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.connected_clients }}</div></td>
</tr> </tr>
<tr> <tr>
<td><div class="cell">运行时间()</div></td> <td class="el-table__cell is-leaf"><div class="cell">运行时间()</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.uptime_in_days }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.uptime_in_days }}</div></td>
<td><div class="cell">使用内存</div></td> <td class="el-table__cell is-leaf"><div class="cell">使用内存</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.used_memory_human }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.used_memory_human }}</div></td>
<td><div class="cell">使用CPU</div></td> <td class="el-table__cell is-leaf"><div class="cell">使用CPU</div></td>
<td><div class="cell" v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ parseFloat(cache.info.used_cpu_user_children).toFixed(2) }}</div></td>
<td><div class="cell">内存配置</div></td> <td class="el-table__cell is-leaf"><div class="cell">内存配置</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.maxmemory_human }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.maxmemory_human }}</div></td>
</tr> </tr>
<tr> <tr>
<td><div class="cell">AOF是否开启</div></td> <td class="el-table__cell is-leaf"><div class="cell">AOF是否开启</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.aof_enabled == "0" ? "否" : "是" }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.aof_enabled == "0" ? "否" : "是" }}</div></td>
<td><div class="cell">RDB是否成功</div></td> <td class="el-table__cell is-leaf"><div class="cell">RDB是否成功</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.rdb_last_bgsave_status }}</div></td>
<td><div class="cell">Key数量</div></td> <td class="el-table__cell is-leaf"><div class="cell">Key数量</div></td>
<td><div class="cell" v-if="cache.dbSize">{{ cache.dbSize }} </div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.dbSize">{{ cache.dbSize }} </div></td>
<td><div class="cell">网络入口/出口</div></td> <td class="el-table__cell is-leaf"><div class="cell">网络入口/出口</div></td>
<td><div class="cell" v-if="cache.info">{{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="cache.info">{{ cache.info.instantaneous_input_kbps }}kps/{{cache.info.instantaneous_output_kbps}}kps</div></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

View File

@ -8,26 +8,26 @@
<table cellspacing="0" style="width: 100%;"> <table cellspacing="0" style="width: 100%;">
<thead> <thead>
<tr> <tr>
<th class="is-leaf"><div class="cell">属性</div></th> <th class="el-table__cell is-leaf"><div class="cell">属性</div></th>
<th class="is-leaf"><div class="cell"></div></th> <th class="el-table__cell is-leaf"><div class="cell"></div></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td><div class="cell">核心数</div></td> <td class="el-table__cell is-leaf"><div class="cell">核心数</div></td>
<td><div class="cell" v-if="server.cpu">{{ server.cpu.cpuNum }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.cpuNum }}</div></td>
</tr> </tr>
<tr> <tr>
<td><div class="cell">用户使用率</div></td> <td class="el-table__cell is-leaf"><div class="cell">用户使用率</div></td>
<td><div class="cell" v-if="server.cpu">{{ server.cpu.used }}%</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.used }}%</div></td>
</tr> </tr>
<tr> <tr>
<td><div class="cell">系统使用率</div></td> <td class="el-table__cell is-leaf"><div class="cell">系统使用率</div></td>
<td><div class="cell" v-if="server.cpu">{{ server.cpu.sys }}%</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.sys }}%</div></td>
</tr> </tr>
<tr> <tr>
<td><div class="cell">当前空闲率</div></td> <td class="el-table__cell is-leaf"><div class="cell">当前空闲率</div></td>
<td><div class="cell" v-if="server.cpu">{{ server.cpu.free }}%</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.cpu">{{ server.cpu.free }}%</div></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -42,31 +42,31 @@
<table cellspacing="0" style="width: 100%;"> <table cellspacing="0" style="width: 100%;">
<thead> <thead>
<tr> <tr>
<th class="is-leaf"><div class="cell">属性</div></th> <th class="el-table__cell is-leaf"><div class="cell">属性</div></th>
<th class="is-leaf"><div class="cell">内存</div></th> <th class="el-table__cell is-leaf"><div class="cell">内存</div></th>
<th class="is-leaf"><div class="cell">JVM</div></th> <th class="el-table__cell is-leaf"><div class="cell">JVM</div></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td><div class="cell">总内存</div></td> <td class="el-table__cell is-leaf"><div class="cell">总内存</div></td>
<td><div class="cell" v-if="server.mem">{{ server.mem.total }}G</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.total }}G</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.total }}M</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.total }}M</div></td>
</tr> </tr>
<tr> <tr>
<td><div class="cell">已用内存</div></td> <td class="el-table__cell is-leaf"><div class="cell">已用内存</div></td>
<td><div class="cell" v-if="server.mem">{{ server.mem.used}}G</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.used}}G</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.used}}M</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.used}}M</div></td>
</tr> </tr>
<tr> <tr>
<td><div class="cell">剩余内存</div></td> <td class="el-table__cell is-leaf"><div class="cell">剩余内存</div></td>
<td><div class="cell" v-if="server.mem">{{ server.mem.free }}G</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem">{{ server.mem.free }}G</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.free }}M</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.free }}M</div></td>
</tr> </tr>
<tr> <tr>
<td><div class="cell">使用率</div></td> <td class="el-table__cell is-leaf"><div class="cell">使用率</div></td>
<td><div class="cell" v-if="server.mem" :class="{'text-danger': server.mem.usage > 80}">{{ server.mem.usage }}%</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.mem" :class="{'text-danger': server.mem.usage > 80}">{{ server.mem.usage }}%</div></td>
<td><div class="cell" v-if="server.jvm" :class="{'text-danger': server.jvm.usage > 80}">{{ server.jvm.usage }}%</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm" :class="{'text-danger': server.jvm.usage > 80}">{{ server.jvm.usage }}%</div></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -83,16 +83,16 @@
<table cellspacing="0" style="width: 100%;"> <table cellspacing="0" style="width: 100%;">
<tbody> <tbody>
<tr> <tr>
<td><div class="cell">服务器名称</div></td> <td class="el-table__cell is-leaf"><div class="cell">服务器名称</div></td>
<td><div class="cell" v-if="server.sys">{{ server.sys.computerName }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.computerName }}</div></td>
<td><div class="cell">操作系统</div></td> <td class="el-table__cell is-leaf"><div class="cell">操作系统</div></td>
<td><div class="cell" v-if="server.sys">{{ server.sys.osName }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.osName }}</div></td>
</tr> </tr>
<tr> <tr>
<td><div class="cell">服务器IP</div></td> <td class="el-table__cell is-leaf"><div class="cell">服务器IP</div></td>
<td><div class="cell" v-if="server.sys">{{ server.sys.computerIp }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.computerIp }}</div></td>
<td><div class="cell">系统架构</div></td> <td class="el-table__cell is-leaf"><div class="cell">系统架构</div></td>
<td><div class="cell" v-if="server.sys">{{ server.sys.osArch }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.osArch }}</div></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -109,24 +109,24 @@
<table cellspacing="0" style="width: 100%;"> <table cellspacing="0" style="width: 100%;">
<tbody> <tbody>
<tr> <tr>
<td><div class="cell">Java名称</div></td> <td class="el-table__cell is-leaf"><div class="cell">Java名称</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.name }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.name }}</div></td>
<td><div class="cell">Java版本</div></td> <td class="el-table__cell is-leaf"><div class="cell">Java版本</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.version }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.version }}</div></td>
</tr> </tr>
<tr> <tr>
<td><div class="cell">启动时间</div></td> <td class="el-table__cell is-leaf"><div class="cell">启动时间</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.startTime }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.startTime }}</div></td>
<td><div class="cell">运行时长</div></td> <td class="el-table__cell is-leaf"><div class="cell">运行时长</div></td>
<td><div class="cell" v-if="server.jvm">{{ server.jvm.runTime }}</div></td> <td class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.runTime }}</div></td>
</tr> </tr>
<tr> <tr>
<td colspan="1"><div class="cell">安装路径</div></td> <td colspan="1" class="el-table__cell is-leaf"><div class="cell">安装路径</div></td>
<td colspan="3"><div class="cell" v-if="server.jvm">{{ server.jvm.home }}</div></td> <td colspan="3" class="el-table__cell is-leaf"><div class="cell" v-if="server.jvm">{{ server.jvm.home }}</div></td>
</tr> </tr>
<tr> <tr>
<td colspan="1"><div class="cell">项目路径</div></td> <td colspan="1" class="el-table__cell is-leaf"><div class="cell">项目路径</div></td>
<td colspan="3"><div class="cell" v-if="server.sys">{{ server.sys.userDir }}</div></td> <td colspan="3" class="el-table__cell is-leaf"><div class="cell" v-if="server.sys">{{ server.sys.userDir }}</div></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
@ -143,24 +143,24 @@
<table cellspacing="0" style="width: 100%;"> <table cellspacing="0" style="width: 100%;">
<thead> <thead>
<tr> <tr>
<th class="is-leaf"><div class="cell">盘符路径</div></th> <th class="el-table__cell el-table__cell is-leaf"><div class="cell">盘符路径</div></th>
<th class="is-leaf"><div class="cell">文件系统</div></th> <th class="el-table__cell is-leaf"><div class="cell">文件系统</div></th>
<th class="is-leaf"><div class="cell">盘符类型</div></th> <th class="el-table__cell is-leaf"><div class="cell">盘符类型</div></th>
<th class="is-leaf"><div class="cell">总大小</div></th> <th class="el-table__cell is-leaf"><div class="cell">总大小</div></th>
<th class="is-leaf"><div class="cell">可用大小</div></th> <th class="el-table__cell is-leaf"><div class="cell">可用大小</div></th>
<th class="is-leaf"><div class="cell">已用大小</div></th> <th class="el-table__cell is-leaf"><div class="cell">已用大小</div></th>
<th class="is-leaf"><div class="cell">已用百分比</div></th> <th class="el-table__cell is-leaf"><div class="cell">已用百分比</div></th>
</tr> </tr>
</thead> </thead>
<tbody v-if="server.sysFiles"> <tbody v-if="server.sysFiles">
<tr v-for="(sysFile, index) in server.sysFiles" :key="index"> <tr v-for="(sysFile, index) in server.sysFiles" :key="index">
<td><div class="cell">{{ sysFile.dirName }}</div></td> <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.dirName }}</div></td>
<td><div class="cell">{{ sysFile.sysTypeName }}</div></td> <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.sysTypeName }}</div></td>
<td><div class="cell">{{ sysFile.typeName }}</div></td> <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.typeName }}</div></td>
<td><div class="cell">{{ sysFile.total }}</div></td> <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.total }}</div></td>
<td><div class="cell">{{ sysFile.free }}</div></td> <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.free }}</div></td>
<td><div class="cell">{{ sysFile.used }}</div></td> <td class="el-table__cell is-leaf"><div class="cell">{{ sysFile.used }}</div></td>
<td><div class="cell" :class="{'text-danger': sysFile.usage > 80}">{{ sysFile.usage }}%</div></td> <td class="el-table__cell is-leaf"><div class="cell" :class="{'text-danger': sysFile.usage > 80}">{{ sysFile.usage }}%</div></td>
</tr> </tr>
</tbody> </tbody>
</table> </table>

26
ry.bat
View File

@ -4,36 +4,36 @@ rem jarƽ
set AppName=ruoyi-admin.jar set AppName=ruoyi-admin.jar
rem JVM参数 rem JVM参数
set JVM_OPTS="-Dname=%AppName% -Duser.timezone=Asia/Shanghai -Xms512M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" set JVM_OPTS="-Dname=%AppName% -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
ECHO. ECHO.
ECHO. [1] 启动%AppName% ECHO. [1] 启动%AppName%
ECHO. [2] 关闭%AppName% ECHO. [2] 关闭%AppName%
ECHO. [3] 重启%AppName% ECHO. [3] 重启%AppName%
ECHO. [4] 启动状态 %AppName% ECHO. [4] 启动状态 %AppName%
ECHO. [5] ÍË ³ö ECHO. [5] ÍË ³ö
ECHO. ECHO.
ECHO.请输入选择项目的序号: ECHO.请输入选择项目的序号:
set /p ID= set /p ID=
IF "%id%"=="1" GOTO start IF "%id%"=="1" GOTO start
IF "%id%"=="2" GOTO stop IF "%id%"=="2" GOTO stop
IF "%id%"=="3" GOTO restart IF "%id%"=="3" GOTO restart
IF "%id%"=="4" GOTO status IF "%id%"=="4" GOTO status
IF "%id%"=="5" EXIT IF "%id%"=="5" EXIT
PAUSE PAUSE
:start :start
for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do ( for /f "usebackq tokens=1-2" %%a in (`jps -l ^| findstr %AppName%`) do (
set pid=%%a set pid=%%a
set image_name=%%b set image_name=%%b
) )
if defined pid ( if defined pid (
echo %%is running echo %%is running
PAUSE PAUSE
) )
start javaw -jar %JAVA_OPTS% ruoyi-admin.jar start javaw %JAVA_OPTS% -jar %AppName%
echo starting…… echo starting……
echo Start %AppName% success... echo Start %AppName% success...
@ -64,4 +64,4 @@ goto:eof
if not defined pid (echo process %AppName% is dead ) else ( if not defined pid (echo process %AppName% is dead ) else (
echo %image_name% is running echo %image_name% is running
) )
goto:eof goto:eof

12
ry.sh
View File

@ -1,13 +1,9 @@
#!/bin/sh #!/bin/sh
# author ruoyi # ./ry.sh start 启动 stop 停止 restart 重启 status 状态
# ./ry.sh start 启动
# ./ry.sh stop 停止
# ./ry.sh restart 重启
# ./ry.sh status 状态
AppName=ruoyi-admin.jar AppName=ruoyi-admin.jar
# JVM参数 # JVM参数
JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512M -Xmx512M -XX:PermSize=256M -XX:MaxPermSize=512M -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC" JVM_OPTS="-Dname=$AppName -Duser.timezone=Asia/Shanghai -Xms512m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NewRatio=1 -XX:SurvivorRatio=30 -XX:+UseParallelGC -XX:+UseParallelOldGC"
APP_HOME=`pwd` APP_HOME=`pwd`
LOG_PATH=$APP_HOME/logs/$AppName.log LOG_PATH=$APP_HOME/logs/$AppName.log
@ -30,7 +26,7 @@ function start()
if [ x"$PID" != x"" ]; then if [ x"$PID" != x"" ]; then
echo "$AppName is running..." echo "$AppName is running..."
else else
nohup java -jar $JVM_OPTS target/$AppName > /dev/null 2>&1 & nohup java $JVM_OPTS -jar $AppName > /dev/null 2>&1 &
echo "Start $AppName success..." echo "Start $AppName success..."
fi fi
} }
@ -38,7 +34,7 @@ function start()
function stop() function stop()
{ {
echo "Stop $AppName" echo "Stop $AppName"
PID="" PID=""
query(){ query(){
PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'` PID=`ps -ef |grep java|grep $AppName|grep -v grep|awk '{print $2}'`