Commit 7e972199 authored by trumansdo's avatar trumansdo
Browse files

添加hibernate-validator逻辑,并对service层进行验证

parent e24b97ee
......@@ -5,9 +5,11 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@EnableCaching
@EnableAspectJAutoProxy
public class ConsoleApplication extends SpringBootServletInitializer {
@Override
......
package com.ibeetl.admin.console.web;
import javax.validation.constraints.NotNull;
import lombok.Builder;
import lombok.Builder.Default;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
public class PageParams {
@NotNull Integer page = 1;
@NotNull Integer limit = 10;
}
package com.ibeetl.admin.console.web;
import com.ibeetl.admin.console.util.VOUtil;
import com.ibeetl.admin.core.entity.CoreRoute;
import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.service.CoreUserService;
import com.ibeetl.admin.core.web.JsonResult;
import java.util.List;
import java.util.Map;
import javax.validation.constraints.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@Validated
@RestController
public class UserElController {
......@@ -22,7 +24,7 @@ public class UserElController {
}
@GetMapping("/users")
public JsonResult<List<CoreUser>> users(Integer page, Integer limit) {
public JsonResult<List<CoreUser>> users(@NotNull Integer page, @NotNull Integer limit) {
List<CoreUser> allUsers = coreUserService.getAllUsers(page, limit);
return JsonResult.success(allUsers);
}
......
......@@ -20,9 +20,9 @@ spring.datasource.baseDataSource.driver-class-name=com.mysql.cj.jdbc.Driver
#html\u89C6\u56FE\u4EA4\u7ED9beetl\u6E32\u67D3
beetl.suffix=html
beetlsql.ds.baseDataSource.basePackage=com
beetlsql.ds.baseDataSource.basePackage=com.ibeetl.admin
beetlsql.ds.baseDataSource.daoSuffix=Dao
beetlsql.ds.baseDataSource.dbStyle=org.beetl.sql.core.db.MySqlStyle
#beetlsql.basePackage=com.ibeetl,com.xxx.yourpackage
#\u6709\u4E00\u4E2A\u6570\u636E\u6E90\u547D\u540D\u4E3AbaseDataSource,\u4F60\u53EF\u4EE5\u6DFB\u52A0\u591A\u6570\u636E\u6E90
beetlsql.mutiple.datasource=baseDataSource
......
package com.ibeetl.admin.core.conf;
import static cn.hutool.system.SystemUtil.LINE_SEPRATOR;
import static java.lang.String.format;
import cn.hutool.core.util.StrUtil;
import cn.hutool.setting.dialect.Props;
import cn.hutool.system.SystemUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ibeetl.admin.core.util.FormFieldException;
import com.ibeetl.admin.core.util.PlatformException;
......@@ -44,11 +50,11 @@ public class CustomErrorController extends AbstractErrorController {
@RequestMapping(ERROR_PATH)
public ModelAndView getErrorPath(HttpServletRequest request, HttpServletResponse response) {
Map<String, Object> model = Collections.unmodifiableMap(getErrorAttributes(request, false));
Throwable cause = getCause(request);
int status = (Integer) model.get("status");
// 错误信息
String message = (String) model.get("message");
// String message = (String) model.get("message");
// 友好提示
String errorMessage = getErrorMessage(cause);
String requestPath = (String) model.get("path");
......@@ -56,8 +62,7 @@ public class CustomErrorController extends AbstractErrorController {
List<FieldError> filedErrors = this.getFieldError(model, cause);
// 后台打印日志信息方方便查错
logger.error("{} : {} {} {}", status, message, filedErrors, cause);
logger.error("requestPath : {}", requestPath);
prettyLog(model, cause, filedErrors);
response.setStatus(status);
if (!isJsonRequest(request)) {
......@@ -78,11 +83,28 @@ public class CustomErrorController extends AbstractErrorController {
} else {
writeJson(response, JsonResult.fail(this.wrapFieldErrors(filedErrors)));
}
return null;
}
}
protected void prettyLog(Map model, Throwable cause, List<FieldError> filedErrors) {
Object path = model.get("path");
Object status = model.get("status");
Object message = model.get("message");
StringBuilder log = new StringBuilder();
log.append(SystemUtil.get(LINE_SEPRATOR))
.append(StrUtil.format("┏━━━━ response status: <{}> ━━━━", status))
.append(SystemUtil.get(LINE_SEPRATOR))
.append(StrUtil.format("┣━━━━ error message: <{}> ━━━━", message))
.append(SystemUtil.get(LINE_SEPRATOR))
.append(StrUtil.format("┣━━━━ error fileds: <{}> ━━━━", filedErrors))
.append(SystemUtil.get(LINE_SEPRATOR))
.append(StrUtil.format("┗━━━━ error cause: <{}> ━━━━", cause))
.append(SystemUtil.get(LINE_SEPRATOR))
.append(StrUtil.format("┗━━━━ request path <{}> error log.━━━━", path));
logger.error(log.toString());
}
protected List<FieldError> getFieldError(Map<String, Object> model, Throwable cause) {
List<FieldError> filedErrors = (List<FieldError>) model.get("errors");
if (filedErrors != null) {
......@@ -133,6 +155,7 @@ public class CustomErrorController extends AbstractErrorController {
}
protected String getErrorMessage(Throwable ex) {
if (ex instanceof PlatformException) {
return ex.getMessage();
} else {
......@@ -152,7 +175,6 @@ public class CustomErrorController extends AbstractErrorController {
@Override
public String getErrorPath() {
// TODO Auto-generated method stub
return null;
return ERROR_PATH;
}
}
......@@ -100,6 +100,9 @@ class CustomJsonResultSerializer extends JsonSerializer<JsonResult> {
CustomJsonResultSerializer() {}
/**
* 处理 JsonResult 返回结果。自动分离分页信息,不需要手动在controller中分离
*/
@Override
public void serialize(JsonResult value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
......
package com.ibeetl.admin.core.conf;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;
import org.hibernate.validator.HibernateValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
@Configuration
public class SpringConfiguration {
/**
* 配置验证器
*
* @return validator
*/
@Bean
public Validator validator() {
ValidatorFactory validatorFactory =
Validation.byProvider(HibernateValidator.class)
.configure()
// 快速失败模式
.failFast(true)
// .addProperty( "hibernate.validator.fail_fast", "true" )
.buildValidatorFactory();
Validator validator = validatorFactory.getValidator();
return validator;
}
/**
* 设置SpringMVC Controller方法参数验证器。 必须在controller类上使用 {@link
* org.springframework.validation.annotation.Validated} 注解
*/
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor(
@Autowired Validator validator) {
MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
postProcessor.setValidator(validator);
return postProcessor;
}
}
package com.ibeetl.admin.core.conf;
import static com.ibeetl.admin.core.util.HttpRequestLocal.ACCESS_CURRENT_USER;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ClassUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
......@@ -13,9 +10,6 @@ import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ibeetl.admin.core.annotation.RequestBodyPlus;
import com.ibeetl.admin.core.entity.CoreOrg;
import com.ibeetl.admin.core.entity.CoreUser;
import com.ibeetl.admin.core.service.CorePlatformService;
import com.ibeetl.admin.core.service.CoreUserService;
import com.ibeetl.admin.core.util.HttpRequestLocal;
import com.ibeetl.admin.core.util.JoseJwtUtil;
......@@ -26,7 +20,6 @@ import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.beetl.core.GroupTemplate;
import org.beetl.ext.spring.BeetlGroupUtilConfiguration;
import org.springframework.beans.factory.InitializingBean;
......@@ -41,6 +34,7 @@ import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
......@@ -55,7 +49,7 @@ import org.springframework.web.servlet.mvc.method.annotation.AbstractMessageConv
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
@Configuration
public class MVCConf implements WebMvcConfigurer, InitializingBean {
public class SpringWebMvcConfigurer implements WebMvcConfigurer, InitializingBean {
public static final String DEFAULT_APP_NAME = "开发平台";
......@@ -75,19 +69,32 @@ public class MVCConf implements WebMvcConfigurer, InitializingBean {
@Autowired private RequestMappingHandlerAdapter adapter;
/**
* 添加拦截器
*
* @param registry 拦截器的注册器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry
.addInterceptor(new SessionInterceptor(userService))
.addPathPatterns("/**");
registry.addInterceptor(new SessionInterceptor(userService)).addPathPatterns("/**");
// super.addInterceptors(registry);
}
/**
* 增加跨域映射
*
* @param registry 跨域映射注册器
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**");
}
/**
* SpringMVC的请求响应消息的转换格式器
*
* @param registry
*/
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
......@@ -123,10 +130,10 @@ class SessionInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(
HttpServletRequest request, HttpServletResponse response, Object handler) {
HttpRequestLocal.set(request);
HttpRequestLocal.set(request);
if (StrUtil.containsAny(request.getRequestURI(), "/login", "/error", "/logout")) {
return true;
}
return true;
}
String token = HttpRequestLocal.getAuthorization();
Map<String, Object> payload = JoseJwtUtil.parsePayload(token);
......
package com.ibeetl.admin.core.conf.aop;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.ibeetl.admin.core.util.ValidateUtils;
import java.lang.reflect.Method;
import java.util.Optional;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
@Aspect
@Component
public class ServiceValidationAop {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Pointcut("@target(org.springframework.stereotype.Service)")
public void service() {}
@Pointcut("@annotation(org.springframework.validation.annotation.Validated)")
public void validated() {}
@Pointcut("@annotation(javax.validation.Valid)")
public void valid() {}
@Around("service() && (valid() || validated())")
public Object doValidation(ProceedingJoinPoint point) throws Throwable {
Object returnValue;
/*被代理对象、目标对象*/
Object target = point.getTarget();
/*代理对象*/
/*Object pointThis = point.getThis();*/
/*获取代理方法签名*/
Signature signature = point.getSignature();
MethodSignature methodSignature = (MethodSignature) signature;
/*通过方法签名获取到的method是代理对象中的,不具有目标method的方法信息*/
Method targetMethod = methodSignature.getMethod();
/*只能通过反射获取原目标方法的方法信息*/
Method realMethod =
target.getClass().getDeclaredMethod(signature.getName(), targetMethod.getParameterTypes());
Object[] args = point.getArgs();
/*获取验证组*/
Class[] groups;
groups =
Optional.ofNullable(realMethod.getAnnotation(Validated.class))
.map(Validated::value)
.orElse(new Class[0]);
/*使用hibernate-validator验证*/
Set<ConstraintViolation<Object>> constraintViolations =
ValidateUtils.validateMethod(target, realMethod, args, groups);
if (CollUtil.isEmpty(constraintViolations)) {
returnValue = point.proceed(args);
} else {
/*向上抛出验证失败的异常,交由统一异常管理处理*/
throw new ConstraintViolationException(
StrUtil.format("Service [{}] method parameter unvalidate", signature.getName()),
constraintViolations);
}
return returnValue;
}
}
package com.ibeetl.admin.core.dao;
import org.beetl.sql.core.mapper.BaseMapper;
/**
* 只是作为专门获取数据源的SQLmanager的接口,避免多数据源中,每次使用名称指定注入SQLmanager。
* 泛型不可少
* */
public interface SQLManagerBaseDao extends BaseMapper<Object> {}
package com.ibeetl.admin.core.service;
import com.ibeetl.admin.core.dao.SQLManagerBaseDao;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import org.beetl.sql.core.SQLManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
......@@ -27,7 +30,7 @@ public class CoreUserService {
@Autowired PasswordEncryptService passwordEncryptService;
@Autowired SQLManager sqlManager;
@Autowired SQLManagerBaseDao sqlManagerBaseDao;
public UserLoginInfo login(String userName, String password) {
CoreUser query = new CoreUser();
......@@ -72,8 +75,9 @@ public class CoreUserService {
return userDao.getUserByRole(role);
}
public List<CoreUser> getAllUsers(Integer page, Integer limit) {
return sqlManager.lambdaQuery(CoreUser.class).page(page, limit).getList();
@Valid
public List<CoreUser> getAllUsers(@NotNull Integer page, @NotNull Integer limit) {
return sqlManagerBaseDao.getSQLManager().lambdaQuery(CoreUser.class).page(page, limit).getList();
}
public CoreUser getUserByCode(String userName) {
......
package com.ibeetl.admin.core.util;
import javax.servlet.http.HttpSession;
import com.ibeetl.admin.core.conf.SpringWebMvcConfigurer;
/**
* 用户Controller对应的功能 {@link com.ibeetl.admin.core.conf.MVCConf}
* 用户Controller对应的功能 {@link SpringWebMvcConfigurer}
*
* @author lijiazhi
*/
......
......@@ -9,9 +9,7 @@ import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.stream.Stream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
......@@ -19,10 +17,10 @@ import javax.servlet.http.HttpSession;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import com.ibeetl.admin.core.conf.MVCConf;
import com.ibeetl.admin.core.conf.SpringWebMvcConfigurer;
/**
* 保留用户会话,以方便在业务代码任何地方调用 {@link MVCConf}
* 保留用户会话,以方便在业务代码任何地方调用 {@link SpringWebMvcConfigurer}
*
* @author lijiazhi
*/
......
package com.ibeetl.admin.core.util;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Assert;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.executable.ExecutableValidator;
import org.hibernate.validator.HibernateValidator;
public class ValidateUtils {
private static final Validator VALIDATOR =
Validation.byProvider(HibernateValidator.class)
.configure()
.failFast(true)
.buildValidatorFactory()
.getValidator();
/**
* 验证bean
*
* @param <T> 被验证bean的类型
* @param bean 被验证的bean
* @param groups 验证组
* @return
*/
public static <T> Set<ConstraintViolation<T>> validateBean(T bean, Class<?>... groups) {
Assert.notNull(groups, "groups can't null. Instead of empty groups" );
Set<ConstraintViolation<T>> constraintViolations = VALIDATOR.validate(bean, groups);
return constraintViolations;
}
/**
* 验证方法入参
*
* @param <T> 所属对象的类型
* @param object 方法所属对象
* @param method 方法
* @param parameterValues 方法入参值
* @param groups 校验组
* @return
*/
public static <T> Set<ConstraintViolation<T>> validateMethod(
T object, Method method, Object[] parameterValues, Class<?>... groups) {
Assert.notNull(groups, "groups can't null. Instead of empty groups" );
ExecutableValidator executableValidator = VALIDATOR.forExecutables();
Set<ConstraintViolation<T>> constraintViolations =
executableValidator.validateParameters(object, method, parameterValues, groups);
return constraintViolations;
}
public static <T> List wrapConstraintViolations(
Set<ConstraintViolation<T>> constraintViolations) {
List errorMsgs = CollUtil.newArrayList();
constraintViolations.stream()
.forEach(
violation -> {
errorMsgs.add(violation.getMessage());
});
return errorMsgs;
}
}
......@@ -11,8 +11,19 @@ import java.util.Map;
*/
public class JsonResult<T> {
/**
* 建议标准http响应码
* */
private String code;
/**
* 自定义信息
* */
private String message;
/**
* 携带数据
* */
private T data;
public String getCode() {
......
/*
* @Author: 一日看尽长安花
* @since: 2019-09-04 20:55:14
* @LastEditTime: 2019-10-29 23:17:53
* @LastEditors: 一日看尽长安花
* @Description:
*/
module.exports = {
root: true,
env: {
browser: true,
node: true,
es6: true,
es6: true
},
parserOptions: {
parser: 'babel-eslint',
parser: 'babel-eslint'
},
overrides: [
{
files: ['**/__tests__/*.{j,t}s?(x)'],
env: {
jest: true,
},
},
jest: true
}
}
],
extends: [
'plugin:vue/recommended',
'plugin:prettier/recommended',
'@vue/prettier',
'@vue/prettier'
],
plugins: ['vue'],
......@@ -42,21 +49,22 @@ module.exports = {
trailingComma: 'none',
bracketSpacing: true,
jsxBracketSameLine: false,
arrowParens: 'avoid',
},
arrowParens: 'avoid'
}
],
'no-console': 'off',
'no-debugger': 'off',
'no-unused-vars': 'off',
'vue/no-unused-vars': 'off',
'no-useless-escape': 'off',
'vue/require-component-is': 'off',
quotes: [
2,
'single',
{
avoidEscape: true,
allowTemplateLiterals: true,
},
allowTemplateLiterals: true
}
],
'jsx-quotes': [2, 'prefer-single'],
// 缩进为2个空格
......@@ -66,8 +74,8 @@ module.exports = {
{
attribute: 1,
alignAttributesVertically: true,
ignores: [],
},
ignores: []
}
],
'vue/max-attributes-per-line': [
2,
......@@ -75,9 +83,9 @@ module.exports = {
singleline: 10,
multiline: {
max: 1,
allowFirstLine: false,
},
},
allowFirstLine: false
}
}
],
'vue/html-self-closing': 'off',
'vue/name-property-casing': ['error', 'PascalCase'],
......@@ -99,6 +107,6 @@ module.exports = {
'no-multiple-empty-lines': 'off',
// 关闭模板字符串检测
'no-template-curly-in-string': 'off',
'no-console': 'off',
},
}
'no-console': 'off'
}
};
<!--
* @Author: 一日看尽长安花
* @since: 2019-09-04 20:55:14
* @LastEditTime: 2019-10-30 19:53:28
* @LastEditors: 一日看尽长安花
* @Description:
-->
<template>
<!-- eslint-disable vue/require-component-is -->
<component :is="linkProps(to)">
<!-- 该is特性不要使用官网的v-bind:is -->
<component v-bind="linkProps(to)">
<slot />
</component>
</template>
......@@ -12,8 +20,8 @@ export default {
props: {
to: {
type: String,
required: true,
},
required: true
}
},
methods: {
linkProps(url) {
......@@ -22,14 +30,14 @@ export default {
is: 'a',
href: url,
target: '_blank',
rel: 'noopener',
rel: 'noopener'
};
}
return {
is: 'router-link',
to: url,
to: url
};
},
},
}
}
};
</script>
<!--
* @Author: 一日看尽长安花
* @since: 2019-09-04 20:55:14
* @LastEditTime: 2019-10-29 22:02:14
* @LastEditors: 一日看尽长安花
* @Description:
-->
<template>
<div v-if="!item.hidden" class="menu-wrapper">
<template v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow">
<template
v-if="
hasOneShowingChild(item.children, item) &&
(!onlyOneChild.children || onlyOneChild.noShowingChildren) &&
!item.alwaysShow
"
>
<app-link v-if="onlyOneChild.meta" :to="resolvePath(onlyOneChild.path)">
<el-menu-item :index="resolvePath(onlyOneChild.path)" :class="{'submenu-title-noDropdown':!isNest}">
<item :icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)" :title="onlyOneChild.meta.title" />
<el-menu-item
:index="resolvePath(onlyOneChild.path)"
:class="{ 'submenu-title-noDropdown': !isNest }"
>
<item
:icon="onlyOneChild.meta.icon || (item.meta && item.meta.icon)"
:title="onlyOneChild.meta.title"
/>
</el-menu-item>
</app-link>
</template>
<el-submenu v-else ref="subMenu" :index="resolvePath(item.path)" popper-append-to-body>
<el-submenu
v-else
ref="subMenu"
:index="resolvePath(item.path)"
popper-append-to-body
>
<template slot="title">
<item v-if="item.meta" :icon="item.meta && item.meta.icon" :title="item.meta.title" />
<item
v-if="item.meta"
:icon="item.meta && item.meta.icon"
:title="item.meta.title"
/>
</template>
<sidebar-item
v-for="child in item.children"
......@@ -25,11 +53,11 @@
</template>
<script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'
import path from 'path';
import { isExternal } from '@/utils/validate';
import Item from './Item';
import AppLink from './Link';
import FixiOSBug from './FixiOSBug';
export default {
name: 'SidebarItem',
......@@ -53,43 +81,43 @@ export default {
data() {
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
// TODO: refactor with render function
this.onlyOneChild = null
return {}
this.onlyOneChild = null;
return {};
},
methods: {
hasOneShowingChild(children = [], parent) {
const showingChildren = children.filter(item => {
if (item.hidden) {
return false
return false;
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
this.onlyOneChild = item;
return true;
}
})
});
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
return true;
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
return true
this.onlyOneChild = { ...parent, path: '', noShowingChildren: true };
return true;
}
return false
return false;
},
resolvePath(routePath) {
if (isExternal(routePath)) {
return routePath
return routePath;
}
if (isExternal(this.basePath)) {
return this.basePath
return this.basePath;
}
return path.resolve(this.basePath, routePath)
return path.resolve(this.basePath, routePath);
}
}
}
};
</script>
<!--
* @Author: 一日看尽长安花
* @since: 2019-09-04 20:55:14
* @LastEditTime: 2019-10-29 21:41:31
* @LastEditors: 一日看尽长安花
* @Description:
-->
<template>
<div :class="{'has-logo':showLogo}">
<div :class="{ 'has-logo': showLogo }">
<logo v-if="showLogo" :collapse="isCollapse" />
<el-scrollbar wrap-class="scrollbar-wrapper">
<el-menu
......@@ -12,43 +19,45 @@
:collapse-transition="false"
mode="vertical"
>
<sidebar-item v-for="route in permission_routes" :key="route.path" :item="route" :base-path="route.path" />
<sidebar-item
v-for="route in permission_routes"
:key="route.path"
:item="route"
:base-path="route.path"
/>
</el-menu>
</el-scrollbar>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Logo from './Logo'
import SidebarItem from './SidebarItem'
import variables from '@/styles/variables.scss'
import { mapGetters } from 'vuex';
import Logo from './Logo';
import SidebarItem from './SidebarItem';
import variables from '@/styles/variables.scss';
export default {
components: { SidebarItem, Logo },
computed: {
...mapGetters([
'permission_routes',
'sidebar'
]),
...mapGetters(['permission_routes', 'sidebar']),
activeMenu() {
const route = this.$route
const { meta, path } = route
const route = this.$route;
const { meta, path } = route;
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu
return meta.activeMenu;
}
return path
return path;
},
showLogo() {
return this.$store.state.settings.sidebarLogo
return this.$store.state.settings.sidebarLogo;
},
variables() {
return variables
return variables;
},
isCollapse() {
return !this.sidebar.opened
return !this.sidebar.opened;
}
}
}
};
</script>
/*
* @Author: 一日看尽长安花
* @since: 2019-09-04 20:55:14
* @LastEditTime: 2019-10-27 00:28:33
* @LastEditTime: 2019-10-29 21:52:51
* @LastEditors: 一日看尽长安花
* @Description:
*/
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment