mirror of https://gitee.com/stylefeng/guns
Merge branch 'master' into group2
# Conflicts: # src/main/webapp/assets/common/js/common.jspull/65/head
commit
bc2500c518
6
pom.xml
6
pom.xml
|
@ -60,12 +60,6 @@
|
||||||
<version>1.0.0</version>
|
<version>1.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.stylefeng.roses</groupId>
|
|
||||||
<artifactId>jwt-spring-boot-starter</artifactId>
|
|
||||||
<version>1.0.0</version>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.stylefeng.roses</groupId>
|
<groupId>cn.stylefeng.roses</groupId>
|
||||||
<artifactId>scanner-spring-boot-starter</artifactId>
|
<artifactId>scanner-spring-boot-starter</artifactId>
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package cn.stylefeng.guns.config.web;
|
package cn.stylefeng.guns.config.web;
|
||||||
|
|
||||||
|
import cn.stylefeng.guns.core.beetl.CustomBeetlGroupUtilConfiguration;
|
||||||
import cn.stylefeng.guns.core.error.CustomErrorAttributes;
|
import cn.stylefeng.guns.core.error.CustomErrorAttributes;
|
||||||
import cn.stylefeng.guns.core.error.CustomErrorView;
|
import cn.stylefeng.guns.core.error.CustomErrorView;
|
||||||
import cn.stylefeng.guns.core.security.AuthJwtTokenSecurityInterceptor;
|
import cn.stylefeng.guns.core.security.AuthJwtTokenSecurityInterceptor;
|
||||||
|
@ -60,8 +61,11 @@ public class SpringMvcConfiguration implements WebMvcConfigurer {
|
||||||
* @date 2020/12/16 15:47
|
* @date 2020/12/16 15:47
|
||||||
*/
|
*/
|
||||||
@Bean("error")
|
@Bean("error")
|
||||||
public CustomErrorView error() {
|
public CustomErrorView error(CustomBeetlGroupUtilConfiguration customBeetlGroupUtilConfiguration) {
|
||||||
return new CustomErrorView();
|
CustomErrorView customErrorView = new CustomErrorView();
|
||||||
|
customErrorView.setUrl("/404.html");
|
||||||
|
customErrorView.setGroupTemplate(customBeetlGroupUtilConfiguration.getGroupTemplate());
|
||||||
|
return customErrorView;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,14 +1,6 @@
|
||||||
package cn.stylefeng.guns.core.error;
|
package cn.stylefeng.guns.core.error;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import org.beetl.ext.spring.BeetlSpringView;
|
||||||
import cn.hutool.core.bean.copier.CopyOptions;
|
|
||||||
import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData;
|
|
||||||
import cn.stylefeng.roses.kernel.rule.util.ResponseRenderUtil;
|
|
||||||
import org.springframework.web.servlet.View;
|
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 错误页面的默认跳转(例如请求404的时候,默认走这个视图解析器)
|
* 错误页面的默认跳转(例如请求404的时候,默认走这个视图解析器)
|
||||||
|
@ -16,17 +8,11 @@ import java.util.Map;
|
||||||
* @author fengshuonan
|
* @author fengshuonan
|
||||||
* @date 2017-05-21 11:34
|
* @date 2017-05-21 11:34
|
||||||
*/
|
*/
|
||||||
public class CustomErrorView implements View {
|
public class CustomErrorView extends BeetlSpringView {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getContentType() {
|
public String getContentType() {
|
||||||
return "text/html";
|
return "text/html;charset=UTF-8";
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void render(Map<String, ?> map, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
|
|
||||||
ErrorResponseData errorResponseData = BeanUtil.mapToBean(map, ErrorResponseData.class, true, CopyOptions.create().ignoreError());
|
|
||||||
ResponseRenderUtil.renderErrorResponse(httpServletResponse, errorResponseData.getCode(), errorResponseData.getMessage(), errorResponseData.getExceptionClazz());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -2,17 +2,21 @@ package cn.stylefeng.guns.core.error;
|
||||||
|
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.stylefeng.roses.kernel.auth.api.exception.AuthException;
|
||||||
|
import cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum;
|
||||||
import cn.stylefeng.roses.kernel.rule.abstracts.AbstractExceptionEnum;
|
import cn.stylefeng.roses.kernel.rule.abstracts.AbstractExceptionEnum;
|
||||||
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
|
import cn.stylefeng.roses.kernel.rule.exception.base.ServiceException;
|
||||||
import cn.stylefeng.roses.kernel.rule.exception.enums.defaults.DefaultBusinessExceptionEnum;
|
import cn.stylefeng.roses.kernel.rule.exception.enums.defaults.DefaultBusinessExceptionEnum;
|
||||||
import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData;
|
import cn.stylefeng.roses.kernel.rule.pojo.response.ErrorResponseData;
|
||||||
import cn.stylefeng.roses.kernel.rule.util.ExceptionUtil;
|
import cn.stylefeng.roses.kernel.rule.util.ExceptionUtil;
|
||||||
|
import cn.stylefeng.roses.kernel.rule.util.ResponseRenderUtil;
|
||||||
import cn.stylefeng.roses.kernel.system.constants.SymbolConstant;
|
import cn.stylefeng.roses.kernel.system.constants.SymbolConstant;
|
||||||
import cn.stylefeng.roses.kernel.validator.exception.ParamValidateException;
|
import cn.stylefeng.roses.kernel.validator.exception.ParamValidateException;
|
||||||
import cn.stylefeng.roses.kernel.validator.exception.enums.ValidatorExceptionEnum;
|
import cn.stylefeng.roses.kernel.validator.exception.enums.ValidatorExceptionEnum;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.http.converter.HttpMessageNotReadableException;
|
import org.springframework.http.converter.HttpMessageNotReadableException;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
import org.springframework.validation.BindException;
|
import org.springframework.validation.BindException;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.validation.ObjectError;
|
import org.springframework.validation.ObjectError;
|
||||||
|
@ -27,6 +31,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
import org.springframework.web.servlet.NoHandlerFoundException;
|
import org.springframework.web.servlet.NoHandlerFoundException;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.validation.ValidationException;
|
import javax.validation.ValidationException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
@ -136,6 +141,7 @@ public class GlobalExceptionHandler {
|
||||||
*/
|
*/
|
||||||
@ExceptionHandler(BindException.class)
|
@ExceptionHandler(BindException.class)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
public ErrorResponseData bindException(BindException e) {
|
public ErrorResponseData bindException(BindException e) {
|
||||||
String bindingResult = getArgNotValidMessage(e.getBindingResult());
|
String bindingResult = getArgNotValidMessage(e.getBindingResult());
|
||||||
return renderJson(ValidatorExceptionEnum.VALIDATED_RESULT_ERROR, bindingResult);
|
return renderJson(ValidatorExceptionEnum.VALIDATED_RESULT_ERROR, bindingResult);
|
||||||
|
@ -149,6 +155,7 @@ public class GlobalExceptionHandler {
|
||||||
*/
|
*/
|
||||||
@ExceptionHandler(ValidationException.class)
|
@ExceptionHandler(ValidationException.class)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
|
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
public ErrorResponseData bindException(ValidationException e) {
|
public ErrorResponseData bindException(ValidationException e) {
|
||||||
if (e.getCause() instanceof ParamValidateException) {
|
if (e.getCause() instanceof ParamValidateException) {
|
||||||
ParamValidateException paramValidateException = (ParamValidateException) e.getCause();
|
ParamValidateException paramValidateException = (ParamValidateException) e.getCause();
|
||||||
|
@ -157,6 +164,44 @@ public class GlobalExceptionHandler {
|
||||||
return renderJson(e);
|
return renderJson(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拦截全校校验一类的异常
|
||||||
|
* <p>
|
||||||
|
* 这里重点做一类特殊处理,也就是对过期登录用用户
|
||||||
|
* <p>
|
||||||
|
* 如果用户登录过期,并且为ajax请求,则response的header增加session-timeout的标识
|
||||||
|
* <p>
|
||||||
|
* 如果用户登录过期,不是ajax请求,则直接跳转到登录页面,并提示会话超时
|
||||||
|
*
|
||||||
|
* @author fengshuonan
|
||||||
|
* @date 2020/12/16 15:11
|
||||||
|
*/
|
||||||
|
@ExceptionHandler(AuthException.class)
|
||||||
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
|
public String authError(AuthException authException, HttpServletRequest request, HttpServletResponse response, Model model) {
|
||||||
|
String errorCode = authException.getErrorCode();
|
||||||
|
if (AuthExceptionEnum.AUTH_EXPIRED_ERROR.getErrorCode().equals(errorCode)) {
|
||||||
|
|
||||||
|
// 如果是普通请求
|
||||||
|
if (request.getContentType() == null
|
||||||
|
|| request.getContentType().toLowerCase().contains("text/html")) {
|
||||||
|
model.addAttribute("tips", AuthExceptionEnum.AUTH_EXPIRED_ERROR.getUserTip());
|
||||||
|
return "/login.html";
|
||||||
|
} else {
|
||||||
|
// 其他请求或者是ajax请求
|
||||||
|
response.setHeader("Guns-Session-Timeout", "true");
|
||||||
|
ErrorResponseData errorResponseData = renderJson(authException);
|
||||||
|
ResponseRenderUtil.renderJsonResponse(response, errorResponseData);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 默认响应前端json
|
||||||
|
ErrorResponseData errorResponseData = renderJson(authException);
|
||||||
|
ResponseRenderUtil.renderJsonResponse(response, errorResponseData);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 拦截业务代码抛出的异常
|
* 拦截业务代码抛出的异常
|
||||||
*
|
*
|
||||||
|
@ -164,6 +209,7 @@ public class GlobalExceptionHandler {
|
||||||
* @date 2020/12/16 15:11
|
* @date 2020/12/16 15:11
|
||||||
*/
|
*/
|
||||||
@ExceptionHandler(ServiceException.class)
|
@ExceptionHandler(ServiceException.class)
|
||||||
|
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public ErrorResponseData businessError(ServiceException e) {
|
public ErrorResponseData businessError(ServiceException e) {
|
||||||
log.error("业务异常,具体信息为:{}", e.getMessage());
|
log.error("业务异常,具体信息为:{}", e.getMessage());
|
||||||
|
|
|
@ -3,7 +3,6 @@ package cn.stylefeng.guns.core.security;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.stylefeng.guns.core.security.base.BaseSecurityInterceptor;
|
import cn.stylefeng.guns.core.security.base.BaseSecurityInterceptor;
|
||||||
import cn.stylefeng.roses.kernel.auth.api.AuthServiceApi;
|
import cn.stylefeng.roses.kernel.auth.api.AuthServiceApi;
|
||||||
import cn.stylefeng.roses.kernel.auth.api.SessionManagerApi;
|
|
||||||
import cn.stylefeng.roses.kernel.auth.api.exception.AuthException;
|
import cn.stylefeng.roses.kernel.auth.api.exception.AuthException;
|
||||||
import cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum;
|
import cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum;
|
||||||
import cn.stylefeng.roses.kernel.resource.api.pojo.resource.ResourceDefinition;
|
import cn.stylefeng.roses.kernel.resource.api.pojo.resource.ResourceDefinition;
|
||||||
|
@ -30,12 +29,6 @@ public class AuthJwtTokenSecurityInterceptor extends BaseSecurityInterceptor {
|
||||||
@Resource
|
@Resource
|
||||||
private AuthServiceApi authServiceApi;
|
private AuthServiceApi authServiceApi;
|
||||||
|
|
||||||
/**
|
|
||||||
* 用户会话管理Api
|
|
||||||
*/
|
|
||||||
@Resource
|
|
||||||
private SessionManagerApi sessionManagerApi;
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void filterAction(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, ResourceDefinition resourceDefinition, String token) {
|
public void filterAction(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, ResourceDefinition resourceDefinition, String token) {
|
||||||
|
|
||||||
|
@ -52,9 +45,6 @@ public class AuthJwtTokenSecurityInterceptor extends BaseSecurityInterceptor {
|
||||||
|
|
||||||
// 3.校验token和用户会话信息是否正确
|
// 3.校验token和用户会话信息是否正确
|
||||||
authServiceApi.checkAuth(token, requestURI);
|
authServiceApi.checkAuth(token, requestURI);
|
||||||
|
|
||||||
// 4.刷新用户的session的过期时间
|
|
||||||
sessionManagerApi.refreshSession(token);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
package cn.stylefeng.guns.core.security.base;
|
package cn.stylefeng.guns.core.security.base;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.StrUtil;
|
||||||
|
import cn.stylefeng.roses.kernel.auth.api.AuthServiceApi;
|
||||||
|
import cn.stylefeng.roses.kernel.auth.api.SessionManagerApi;
|
||||||
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
|
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
|
||||||
|
import cn.stylefeng.roses.kernel.auth.api.exception.AuthException;
|
||||||
|
import cn.stylefeng.roses.kernel.auth.api.exception.enums.AuthExceptionEnum;
|
||||||
import cn.stylefeng.roses.kernel.auth.api.expander.AuthConfigExpander;
|
import cn.stylefeng.roses.kernel.auth.api.expander.AuthConfigExpander;
|
||||||
import cn.stylefeng.roses.kernel.resource.api.pojo.resource.ResourceDefinition;
|
import cn.stylefeng.roses.kernel.resource.api.pojo.resource.ResourceDefinition;
|
||||||
import cn.stylefeng.roses.kernel.resource.api.pojo.resource.ResourceUrlParam;
|
import cn.stylefeng.roses.kernel.resource.api.pojo.resource.ResourceUrlParam;
|
||||||
|
@ -25,6 +30,12 @@ public abstract class BaseSecurityInterceptor implements HandlerInterceptor {
|
||||||
@Resource
|
@Resource
|
||||||
private ResourceServiceApi resourceServiceApi;
|
private ResourceServiceApi resourceServiceApi;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private AuthServiceApi authServiceApi;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SessionManagerApi sessionManagerApi;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
|
||||||
|
|
||||||
|
@ -32,7 +43,7 @@ public abstract class BaseSecurityInterceptor implements HandlerInterceptor {
|
||||||
String requestURI = request.getRequestURI();
|
String requestURI = request.getRequestURI();
|
||||||
|
|
||||||
// 2. 不需要权限过滤的资源,直接放行
|
// 2. 不需要权限过滤的资源,直接放行
|
||||||
Boolean noneSecurityFlag = AntPathMatcherUtil.getAntMatchFLag(requestURI, AuthConfigExpander.getNoneSecurityConfig());
|
Boolean noneSecurityFlag = AntPathMatcherUtil.getAntMatchFLag(requestURI, request.getContextPath(), AuthConfigExpander.getNoneSecurityConfig());
|
||||||
if (noneSecurityFlag) {
|
if (noneSecurityFlag) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -45,17 +56,32 @@ public abstract class BaseSecurityInterceptor implements HandlerInterceptor {
|
||||||
// 不做处理,因为本接口可能是不需要鉴权
|
// 不做处理,因为本接口可能是不需要鉴权
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. 获取ResourceDefinition,可能为null
|
// 4. 如果token不为空,则先判断是否登录过期了,过期了就直接打回,不过期不做处理
|
||||||
|
if (StrUtil.isNotBlank(token)) {
|
||||||
|
try {
|
||||||
|
authServiceApi.validateToken(token);
|
||||||
|
} catch (AuthException authException) {
|
||||||
|
if (AuthExceptionEnum.AUTH_EXPIRED_ERROR.getErrorCode().equals(authException.getErrorCode())) {
|
||||||
|
sessionManagerApi.destroySessionCookie();
|
||||||
|
throw authException;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. 刷新用户的session的过期时间
|
||||||
|
sessionManagerApi.refreshSession(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 获取ResourceDefinition,可能为null
|
||||||
ResourceUrlParam resourceUrlParam = new ResourceUrlParam();
|
ResourceUrlParam resourceUrlParam = new ResourceUrlParam();
|
||||||
resourceUrlParam.setUrl(requestURI);
|
resourceUrlParam.setUrl(requestURI);
|
||||||
ResourceDefinition resourceDefinition = resourceServiceApi.getResourceByUrl(resourceUrlParam);
|
ResourceDefinition resourceDefinition = resourceServiceApi.getResourceByUrl(resourceUrlParam);
|
||||||
|
|
||||||
// 5. 资源找不到,则当前url不被权限控制,直接放行
|
// 7. 资源找不到,则当前url不被权限控制,直接放行
|
||||||
if (resourceDefinition == null) {
|
if (resourceDefinition == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 6.执行真正过滤器业务,如果拦截器执行不成功会抛出异常
|
// 8.执行真正过滤器业务,如果拦截器执行不成功会抛出异常
|
||||||
this.filterAction(request, response, resourceDefinition, token);
|
this.filterAction(request, response, resourceDefinition, token);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package cn.stylefeng.guns.modular.blackboard;
|
package cn.stylefeng.guns.modular.dashboard;
|
||||||
|
|
||||||
import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource;
|
import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource;
|
||||||
import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource;
|
import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource;
|
||||||
|
@ -14,7 +14,7 @@ import org.springframework.stereotype.Controller;
|
||||||
@Controller
|
@Controller
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@ApiResource(name = "工作台和分析页面")
|
@ApiResource(name = "工作台和分析页面")
|
||||||
public class BlackboardViewController {
|
public class DashboardViewController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 工作台
|
* 工作台
|
||||||
|
@ -22,7 +22,7 @@ public class BlackboardViewController {
|
||||||
* @author fengshuonan
|
* @author fengshuonan
|
||||||
* @date 2018/12/24 22:43
|
* @date 2018/12/24 22:43
|
||||||
*/
|
*/
|
||||||
@GetResource(name = "工作台", path = "/blackboard/platform", requiredPermission = false)
|
@GetResource(name = "工作台", path = "/dashboard/workplace", requiredPermission = false)
|
||||||
public String platform() {
|
public String platform() {
|
||||||
return "/modular/blackboard/board_platform.html";
|
return "/modular/blackboard/board_platform.html";
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ public class BlackboardViewController {
|
||||||
* @author fengshuonan
|
* @author fengshuonan
|
||||||
* @date 2020/12/29 21:27
|
* @date 2020/12/29 21:27
|
||||||
*/
|
*/
|
||||||
@GetResource(name = "分析页面", path = "/blackboard/analyse", requiredPermission = false)
|
@GetResource(name = "分析页面", path = "/dashboard/analysis", requiredPermission = false)
|
||||||
public String analyse() {
|
public String analyse() {
|
||||||
return "/modular/blackboard/board_analyse.html";
|
return "/modular/blackboard/board_analyse.html";
|
||||||
}
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package cn.stylefeng.guns.modular.error;
|
||||||
|
|
||||||
|
import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource;
|
||||||
|
import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 错误页面的跳转
|
||||||
|
*
|
||||||
|
* @author fengshuonan
|
||||||
|
* @date 2021/1/1 21:20
|
||||||
|
*/
|
||||||
|
@Controller
|
||||||
|
@ApiResource(name = "错误页面的跳转")
|
||||||
|
public class ErrorViewController {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 跳转到session超时页面
|
||||||
|
*
|
||||||
|
* @author fengshuonan
|
||||||
|
* @date 2021/1/1 21:21
|
||||||
|
*/
|
||||||
|
@GetResource(name = "跳转到session超时页面", path = "/global/sessionError", requiredPermission = false, requiredLogin = false)
|
||||||
|
public String errorPageInfo(Model model) {
|
||||||
|
model.addAttribute("tips", "登陆超时,请您重新登陆!");
|
||||||
|
return "/login.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,24 +1,14 @@
|
||||||
package cn.stylefeng.guns.modular.index.controller;
|
package cn.stylefeng.guns.modular.index.controller;
|
||||||
|
|
||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.stylefeng.guns.modular.index.service.IndexService;
|
||||||
import cn.hutool.core.util.ObjectUtil;
|
|
||||||
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
|
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
|
||||||
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
|
|
||||||
import cn.stylefeng.roses.kernel.auth.api.pojo.login.basic.SimpleRoleInfo;
|
|
||||||
import cn.stylefeng.roses.kernel.auth.api.pojo.login.basic.SimpleUserInfo;
|
|
||||||
import cn.stylefeng.roses.kernel.menu.modular.service.SysMenuService;
|
|
||||||
import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource;
|
import cn.stylefeng.roses.kernel.resource.api.annotation.ApiResource;
|
||||||
import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource;
|
import cn.stylefeng.roses.kernel.resource.api.annotation.GetResource;
|
||||||
import cn.stylefeng.roses.kernel.system.modular.organization.entity.HrOrganization;
|
|
||||||
import cn.stylefeng.roses.kernel.system.modular.organization.service.HrOrganizationService;
|
|
||||||
import cn.stylefeng.roses.kernel.system.modular.user.service.SysUserService;
|
|
||||||
import cn.stylefeng.roses.kernel.system.pojo.menu.layui.LayuiAppIndexMenus;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
import org.springframework.ui.Model;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 首页相关的界面渲染
|
* 首页相关的界面渲染
|
||||||
|
@ -32,13 +22,7 @@ import java.util.List;
|
||||||
public class IndexViewController {
|
public class IndexViewController {
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private SysMenuService sysMenuService;
|
private IndexService indexService;
|
||||||
|
|
||||||
@Resource
|
|
||||||
private SysUserService sysUserService;
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private HrOrganizationService hrOrganizationService;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 首页界面
|
* 首页界面
|
||||||
|
@ -51,20 +35,7 @@ public class IndexViewController {
|
||||||
|
|
||||||
// 当前用户已经登录,跳转到首页
|
// 当前用户已经登录,跳转到首页
|
||||||
if (LoginContext.me().hasLogin()) {
|
if (LoginContext.me().hasLogin()) {
|
||||||
|
model.addAllAttributes(indexService.createIndexRenderAttributes());
|
||||||
LoginUser loginUser = LoginContext.me().getLoginUser();
|
|
||||||
SimpleUserInfo simpleUserInfo = loginUser.getSimpleUserInfo();
|
|
||||||
|
|
||||||
// 渲染首页的菜单
|
|
||||||
List<LayuiAppIndexMenus> layuiAppIndexMenus = sysMenuService.getLayuiIndexMenus();
|
|
||||||
model.addAttribute("layuiAppIndexMenus", layuiAppIndexMenus);
|
|
||||||
|
|
||||||
// 获取首页的头像
|
|
||||||
model.addAttribute("avatar", sysUserService.getUserAvatarUrl(simpleUserInfo.getAvatar()));
|
|
||||||
|
|
||||||
// 获取人员姓名
|
|
||||||
model.addAttribute("name", simpleUserInfo.getRealName());
|
|
||||||
|
|
||||||
return "/index.html";
|
return "/index.html";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,29 +51,7 @@ public class IndexViewController {
|
||||||
*/
|
*/
|
||||||
@GetResource(name = "个人中心界面", path = "/personal", requiredLogin = false)
|
@GetResource(name = "个人中心界面", path = "/personal", requiredLogin = false)
|
||||||
public String personal(Model model) {
|
public String personal(Model model) {
|
||||||
LoginUser loginUser = LoginContext.me().getLoginUser();
|
model.addAllAttributes(indexService.createPersonInfoRenderAttributes());
|
||||||
|
|
||||||
// 用户基本信息
|
|
||||||
SimpleUserInfo simpleUserInfo = loginUser.getSimpleUserInfo();
|
|
||||||
model.addAllAttributes(BeanUtil.beanToMap(simpleUserInfo));
|
|
||||||
|
|
||||||
// 角色名称
|
|
||||||
List<SimpleRoleInfo> simpleRoleInfoList = loginUser.getSimpleRoleInfoList();
|
|
||||||
if (ObjectUtil.isNotEmpty(simpleRoleInfoList)) {
|
|
||||||
String roleName = simpleRoleInfoList.get(0).getRoleName();
|
|
||||||
model.addAttribute("roleName", roleName);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 组织机构名称
|
|
||||||
Long organizationId = loginUser.getOrganizationId();
|
|
||||||
HrOrganization hrOrganization = hrOrganizationService.getById(organizationId);
|
|
||||||
if (hrOrganization != null) {
|
|
||||||
model.addAttribute("orgName", hrOrganization.getOrgName());
|
|
||||||
}
|
|
||||||
|
|
||||||
// 渲染头像的url
|
|
||||||
model.addAttribute("avatar", sysUserService.getUserAvatarUrl(simpleUserInfo.getAvatar()));
|
|
||||||
|
|
||||||
return "/modular/index/personal_info.html";
|
return "/modular/index/personal_info.html";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,23 @@
|
||||||
package cn.stylefeng.guns.modular.index.service;
|
package cn.stylefeng.guns.modular.index.service;
|
||||||
|
|
||||||
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
|
import cn.hutool.core.util.ObjectUtil;
|
||||||
|
import cn.stylefeng.roses.kernel.auth.api.context.LoginContext;
|
||||||
|
import cn.stylefeng.roses.kernel.auth.api.pojo.login.LoginUser;
|
||||||
|
import cn.stylefeng.roses.kernel.auth.api.pojo.login.basic.SimpleRoleInfo;
|
||||||
|
import cn.stylefeng.roses.kernel.auth.api.pojo.login.basic.SimpleUserInfo;
|
||||||
|
import cn.stylefeng.roses.kernel.menu.modular.service.SysMenuService;
|
||||||
|
import cn.stylefeng.roses.kernel.system.modular.organization.entity.HrOrganization;
|
||||||
|
import cn.stylefeng.roses.kernel.system.modular.organization.service.HrOrganizationService;
|
||||||
|
import cn.stylefeng.roses.kernel.system.modular.user.service.SysUserService;
|
||||||
|
import cn.stylefeng.roses.kernel.system.pojo.menu.layui.LayuiAppIndexMenus;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 首页相关数据组装服务
|
* 首页相关数据组装服务
|
||||||
*
|
*
|
||||||
|
@ -11,5 +27,76 @@ import org.springframework.stereotype.Service;
|
||||||
@Service
|
@Service
|
||||||
public class IndexService {
|
public class IndexService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysMenuService sysMenuService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private SysUserService sysUserService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private HrOrganizationService hrOrganizationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取首页需要渲染的参数
|
||||||
|
*
|
||||||
|
* @author fengshuonan
|
||||||
|
* @date 2021/1/1 18:27
|
||||||
|
*/
|
||||||
|
public Map<String, Object> createIndexRenderAttributes() {
|
||||||
|
|
||||||
|
HashMap<String, Object> renderMap = new HashMap<>();
|
||||||
|
|
||||||
|
LoginUser loginUser = LoginContext.me().getLoginUser();
|
||||||
|
SimpleUserInfo simpleUserInfo = loginUser.getSimpleUserInfo();
|
||||||
|
|
||||||
|
// 渲染首页的菜单
|
||||||
|
List<LayuiAppIndexMenus> layuiAppIndexMenus = sysMenuService.getLayuiIndexMenus();
|
||||||
|
renderMap.put("layuiAppIndexMenus", layuiAppIndexMenus);
|
||||||
|
|
||||||
|
// 获取首页的头像
|
||||||
|
renderMap.put("avatar", sysUserService.getUserAvatarUrl(simpleUserInfo.getAvatar()));
|
||||||
|
|
||||||
|
// 获取人员姓名
|
||||||
|
renderMap.put("name", simpleUserInfo.getRealName());
|
||||||
|
|
||||||
|
return renderMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建个人中心页面需要渲染的值
|
||||||
|
*
|
||||||
|
* @author fengshuonan
|
||||||
|
* @date 2021/1/1 18:38
|
||||||
|
*/
|
||||||
|
public Map<String, Object> createPersonInfoRenderAttributes() {
|
||||||
|
|
||||||
|
HashMap<String, Object> renderMap = new HashMap<>();
|
||||||
|
renderMap.put("roleName", "角色空");
|
||||||
|
renderMap.put("orgName", "组织架构空");
|
||||||
|
|
||||||
|
// 添加用户基本信息字段
|
||||||
|
LoginUser loginUser = LoginContext.me().getLoginUser();
|
||||||
|
SimpleUserInfo simpleUserInfo = loginUser.getSimpleUserInfo();
|
||||||
|
renderMap.putAll(BeanUtil.beanToMap(simpleUserInfo));
|
||||||
|
|
||||||
|
// 角色名称
|
||||||
|
List<SimpleRoleInfo> simpleRoleInfoList = loginUser.getSimpleRoleInfoList();
|
||||||
|
if (ObjectUtil.isNotEmpty(simpleRoleInfoList)) {
|
||||||
|
String roleName = simpleRoleInfoList.get(0).getRoleName();
|
||||||
|
renderMap.put("roleName", roleName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 组织机构名称
|
||||||
|
Long organizationId = loginUser.getOrganizationId();
|
||||||
|
HrOrganization hrOrganization = hrOrganizationService.getById(organizationId);
|
||||||
|
if (hrOrganization != null) {
|
||||||
|
renderMap.put("orgName", hrOrganization.getOrgName());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 渲染头像的url
|
||||||
|
renderMap.put("avatar", sysUserService.getUserAvatarUrl(simpleUserInfo.getAvatar()));
|
||||||
|
|
||||||
|
return renderMap;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,16 @@ Feng.success = function (info) {
|
||||||
Feng.error = function (info) {
|
Feng.error = function (info) {
|
||||||
top.layer.msg(info, {icon: 2});
|
top.layer.msg(info, {icon: 2});
|
||||||
};
|
};
|
||||||
|
Feng.dialog = function (info) {
|
||||||
|
top.layer.open({
|
||||||
|
title: '提示', content: info
|
||||||
|
});
|
||||||
|
};
|
||||||
|
Feng.dialog = function (title, info) {
|
||||||
|
top.layer.open({
|
||||||
|
title: title, content: info
|
||||||
|
});
|
||||||
|
};
|
||||||
Feng.confirm = function (tip, ensure) {
|
Feng.confirm = function (tip, ensure) {
|
||||||
top.layer.confirm(tip, {
|
top.layer.confirm(tip, {
|
||||||
skin: 'layui-layer-admin'
|
skin: 'layui-layer-admin'
|
||||||
|
@ -130,9 +140,8 @@ layui.config({
|
||||||
selectPlus: '../../expand/module/selectPlus/selectPlus',
|
selectPlus: '../../expand/module/selectPlus/selectPlus',
|
||||||
iconPicker: '../../expand/module/iconPicker/iconPicker',
|
iconPicker: '../../expand/module/iconPicker/iconPicker',
|
||||||
ztree: '../../expand/module/ztree/ztree-object',
|
ztree: '../../expand/module/ztree/ztree-object',
|
||||||
ax: '../../expand/module/ax/ax',
|
HttpRequest: '../../expand/module/HttpRequest/HttpRequest',
|
||||||
func: '../../expand/module/func/func',
|
func: '../../expand/module/func/func'
|
||||||
ajaxUtil: '../../expand/module/ax/ajaxUtil'
|
|
||||||
}).use(['layer', 'admin'], function () {
|
}).use(['layer', 'admin'], function () {
|
||||||
var $ = layui.jquery;
|
var $ = layui.jquery;
|
||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
|
@ -147,12 +156,10 @@ layui.config({
|
||||||
$.ajaxSetup({
|
$.ajaxSetup({
|
||||||
contentType: "application/x-www-form-urlencoded;charset=utf-8",
|
contentType: "application/x-www-form-urlencoded;charset=utf-8",
|
||||||
complete: function (XMLHttpRequest, textStatus) {
|
complete: function (XMLHttpRequest, textStatus) {
|
||||||
|
|
||||||
//如果超时就处理 ,指定要跳转的页面
|
//如果超时就处理 ,指定要跳转的页面
|
||||||
if (XMLHttpRequest.getResponseHeader("Guns-Session-Timeout") === "true") {
|
if (XMLHttpRequest.getResponseHeader("Guns-Session-Timeout") === "true") {
|
||||||
window.location = Feng.ctxPath + "/global/sessionError";
|
window.location = Feng.ctxPath + "/global/sessionError";
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,164 @@
|
||||||
|
/**
|
||||||
|
* http请求对ajax封装,减少一些重复业务逻辑的编写
|
||||||
|
* @author fengshuonan
|
||||||
|
*/
|
||||||
|
layui.define(['jquery'], function (exports) {
|
||||||
|
var $ = layui.$;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个ajax的请求类
|
||||||
|
*
|
||||||
|
* @param url 请求后端的url
|
||||||
|
* @param method http请求方法,写get或者post
|
||||||
|
* @param successCallback 请求成功的回调函数
|
||||||
|
* @param errorCallback 请求失败的回调函数,后端返回http状态码500
|
||||||
|
*
|
||||||
|
* 使用方法:
|
||||||
|
*
|
||||||
|
* var request = new HttpRequest('/user/list', 'get', function(data){
|
||||||
|
* // ...
|
||||||
|
* }, function(){
|
||||||
|
* // ...
|
||||||
|
* });
|
||||||
|
* request.start();
|
||||||
|
*/
|
||||||
|
var HttpRequest = function (url, method, successCallback, errorCallback) {
|
||||||
|
|
||||||
|
// 请求的url,一般传参时候需要带上contextPath
|
||||||
|
this.url = url;
|
||||||
|
|
||||||
|
// http请求的方法,默认不传为post,一般传 'get' 或 'post'
|
||||||
|
if (method === "" || method == null) {
|
||||||
|
this.method = "post";
|
||||||
|
} else {
|
||||||
|
this.method = method;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 请求成功的回调
|
||||||
|
this.successCallback = successCallback;
|
||||||
|
|
||||||
|
// 请求失败的回调
|
||||||
|
this.errorCallback = errorCallback;
|
||||||
|
|
||||||
|
// 请求的数据
|
||||||
|
this.dataObject = {};
|
||||||
|
|
||||||
|
// 请求的content-type,默认 "application/json"
|
||||||
|
this.contentType = "application/json";
|
||||||
|
|
||||||
|
// 预期服务器返回的数据类型,默认都为 json
|
||||||
|
this.dataType = "json";
|
||||||
|
|
||||||
|
// 默认请求都是同步,不开启异步
|
||||||
|
this.async = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
HttpRequest.prototype = {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 执行http请求
|
||||||
|
*
|
||||||
|
* @param parseJsonFlag 是否在请求时,参数转化为json,如果传 true 就是
|
||||||
|
*/
|
||||||
|
start: function (parseJsonFlag) {
|
||||||
|
var me = this;
|
||||||
|
var result = "";
|
||||||
|
|
||||||
|
// 如果请求需要转化为json则将data转为json
|
||||||
|
if (parseJsonFlag === true) {
|
||||||
|
me.dataObject = JSON.stringify(me.dataObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防止http请求缓存
|
||||||
|
if (this.url.indexOf("?") === -1) {
|
||||||
|
this.url = this.url + "?jstime=" + new Date().getTime();
|
||||||
|
} else {
|
||||||
|
this.url = this.url + "&jstime=" + new Date().getTime();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 初始化ajax
|
||||||
|
$.ajax({
|
||||||
|
type: me.method,
|
||||||
|
url: me.url,
|
||||||
|
contentType: me.contentType,
|
||||||
|
dataType: me.dataType,
|
||||||
|
async: me.async,
|
||||||
|
data: me.dataObject,
|
||||||
|
beforeSend: function (data) {
|
||||||
|
},
|
||||||
|
success: function (data) {
|
||||||
|
result = data;
|
||||||
|
if (me.successCallback !== undefined) {
|
||||||
|
me.successCallback(data);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (xhr) {
|
||||||
|
if (me.errorCallback !== undefined) {
|
||||||
|
me.errorCallback(xhr.responseJSON);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置 key-value 形式的参数
|
||||||
|
*
|
||||||
|
* 此参数组装的是param方式传参的参数,如需传递json请用 setJsonData(data)
|
||||||
|
*
|
||||||
|
* 如果只传了一个key,则key可以是object类型,会将object所有属性都set上
|
||||||
|
*
|
||||||
|
* @param key 参数的key
|
||||||
|
* @param value 参数值
|
||||||
|
*/
|
||||||
|
set: function (key, value) {
|
||||||
|
if (typeof key === "object") {
|
||||||
|
// 遍历object的属性
|
||||||
|
for (var item in key) {
|
||||||
|
if (typeof item != "function") {
|
||||||
|
this.dataObject[item] = key[item];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.dataObject[key] = (typeof value === "undefined") ? $("#" + key).val() : value;
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空传递参数
|
||||||
|
*/
|
||||||
|
clear: function () {
|
||||||
|
this.dataObject = {};
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置请求的content-type
|
||||||
|
*/
|
||||||
|
setContentType: function (contentType) {
|
||||||
|
this.contentType = contentType;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置预期服务器返回的数据类型,默认都为 json
|
||||||
|
*/
|
||||||
|
setDataType: function (dataType) {
|
||||||
|
this.dataType = dataType;
|
||||||
|
return this;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置请求同步还是异步,true-异步,false-同步
|
||||||
|
*/
|
||||||
|
setAsync: function (async) {
|
||||||
|
this.async = async;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
exports('HttpRequest', HttpRequest);
|
||||||
|
});
|
|
@ -1,77 +0,0 @@
|
||||||
layui.define(['jquery'], function (exports) {
|
|
||||||
var $ = layui.$;
|
|
||||||
|
|
||||||
var $ax = function (url, success, error) {
|
|
||||||
this.url = url;
|
|
||||||
this.type = "post";
|
|
||||||
this.data = {};
|
|
||||||
this.contentType = "application/json";
|
|
||||||
this.dataType = "json";
|
|
||||||
this.async = false;
|
|
||||||
this.success = success;
|
|
||||||
this.error = error;
|
|
||||||
};
|
|
||||||
|
|
||||||
$ax.prototype = {
|
|
||||||
start: function () {
|
|
||||||
var me = this;
|
|
||||||
var result = "";
|
|
||||||
|
|
||||||
if (this.url.indexOf("?") === -1) {
|
|
||||||
this.url = this.url + "?jstime=" + new Date().getTime();
|
|
||||||
} else {
|
|
||||||
this.url = this.url + "&jstime=" + new Date().getTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
$.ajax({
|
|
||||||
type: me.type,
|
|
||||||
url: me.url,
|
|
||||||
contentType: me.contentType,
|
|
||||||
dataType: me.dataType,
|
|
||||||
async: me.async,
|
|
||||||
data: JSON.stringify(me.data),
|
|
||||||
beforeSend: function (data) {
|
|
||||||
|
|
||||||
},
|
|
||||||
success: function (data) {
|
|
||||||
result = data;
|
|
||||||
if (me.success !== undefined) {
|
|
||||||
me.success(data);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
error: function (data) {
|
|
||||||
if (me.error !== undefined) {
|
|
||||||
me.error(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
},
|
|
||||||
|
|
||||||
set: function (key, value) {
|
|
||||||
if (typeof key === "object") {
|
|
||||||
for (var i in key) {
|
|
||||||
if (typeof i === "function")
|
|
||||||
continue;
|
|
||||||
this.data[i] = key[i];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.data[key] = (typeof value === "undefined") ? $("#" + key).val() : value;
|
|
||||||
}
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
setData: function (data) {
|
|
||||||
this.data = data;
|
|
||||||
return this;
|
|
||||||
},
|
|
||||||
|
|
||||||
clear: function () {
|
|
||||||
this.data = {};
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports('ax', $ax);
|
|
||||||
});
|
|
|
@ -1,23 +1,23 @@
|
||||||
layui.use(['layer', 'form', 'admin', 'ax'], function () {
|
layui.use(['layer', 'form', 'admin', 'HttpRequest'], function () {
|
||||||
var $ = layui.jquery;
|
var $ = layui.jquery;
|
||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
var form = layui.form;
|
var form = layui.form;
|
||||||
var admin = layui.admin;
|
var admin = layui.admin;
|
||||||
var $ax = layui.ax;
|
var HttpRequest = layui.HttpRequest;
|
||||||
|
|
||||||
// 让当前iframe弹层高度适应
|
// 让当前iframe弹层高度适应
|
||||||
admin.iframeAuto();
|
admin.iframeAuto();
|
||||||
|
|
||||||
// 监听提交
|
// 监听提交
|
||||||
form.on('submit(submit-psw)', function (data) {
|
form.on('submit(submit-psw)', function (data) {
|
||||||
var ajax = new $ax(Feng.ctxPath + "/mgr/changePwd", function (data) {
|
var request = new HttpRequest(Feng.ctxPath + "/sysUser/updatePassword", 'post', function (data) {
|
||||||
Feng.success("修改成功!");
|
Feng.success("修改成功!");
|
||||||
admin.closeThisDialog();
|
admin.closeThisDialog();
|
||||||
}, function (data) {
|
}, function (response) {
|
||||||
Feng.error("修改失败!" + data.responseJSON.message + "!");
|
Feng.dialog("修改失败", response.message);
|
||||||
});
|
});
|
||||||
ajax.setData(data.field);
|
request.set(data.field);
|
||||||
ajax.start();
|
request.start(true);
|
||||||
|
|
||||||
//阻止表单跳转。如果需要表单跳转,去掉这段即可。
|
//阻止表单跳转。如果需要表单跳转,去掉这段即可。
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
layui.use(['form', 'upload', 'element', 'ax', 'laydate'], function () {
|
layui.use(['form', 'upload', 'element', 'HttpRequest', 'laydate'], function () {
|
||||||
var $ = layui.jquery;
|
var $ = layui.jquery;
|
||||||
var form = layui.form;
|
var form = layui.form;
|
||||||
var upload = layui.upload;
|
var upload = layui.upload;
|
||||||
var element = layui.element;
|
var element = layui.element;
|
||||||
var $ax = layui.ax;
|
var HttpRequest = layui.HttpRequest;
|
||||||
var laydate = layui.laydate;
|
var laydate = layui.laydate;
|
||||||
|
|
||||||
//渲染时间选择框
|
//渲染时间选择框
|
||||||
|
@ -12,21 +12,21 @@ layui.use(['form', 'upload', 'element', 'ax', 'laydate'], function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
//获取用户详情
|
//获取用户详情
|
||||||
var ajax = new $ax(Feng.ctxPath + "/system/currentUserInfo");
|
var request = new HttpRequest(Feng.ctxPath + "/sysUser/currentUserInfo", 'get');
|
||||||
var result = ajax.start();
|
var result = request.start();
|
||||||
|
|
||||||
//用这个方法必须用在class有layui-form的元素上
|
//用这个方法必须用在class有layui-form的元素上
|
||||||
form.val('userInfoForm', result.data);
|
form.val('userInfoForm', result.data);
|
||||||
|
|
||||||
//表单提交事件
|
//表单提交事件
|
||||||
form.on('submit(userInfoSubmit)', function (data) {
|
form.on('submit(userInfoSubmit)', function (data) {
|
||||||
var ajax = new $ax(Feng.ctxPath + "/mgr/edit", function (data) {
|
var updateUserInfoRequest = new HttpRequest(Feng.ctxPath + "/sysUser/updateInfo", 'post', function (data) {
|
||||||
Feng.success("修改成功!");
|
Feng.success("修改成功!");
|
||||||
}, function (data) {
|
}, function (response) {
|
||||||
Feng.error("修改失败!" + data.responseJSON.message + "!");
|
Feng.error("修改失败!" + response.message + "!");
|
||||||
});
|
});
|
||||||
ajax.set(data.field);
|
updateUserInfoRequest.set(data.field);
|
||||||
ajax.start();
|
updateUserInfoRequest.start(true);
|
||||||
});
|
});
|
||||||
|
|
||||||
upload.render({
|
upload.render({
|
||||||
|
@ -38,13 +38,13 @@ layui.use(['form', 'upload', 'element', 'ax', 'laydate'], function () {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
, done: function (res) {
|
, done: function (res) {
|
||||||
var ajax = new $ax(Feng.ctxPath + "/system/updateAvatar", function (data) {
|
var updateAvatarRequest = new HttpRequest(Feng.ctxPath + "/system/updateAvatar", function (data) {
|
||||||
Feng.success(res.message);
|
Feng.success(res.message);
|
||||||
}, function (data) {
|
}, function (data) {
|
||||||
Feng.error("修改失败!" + data.responseJSON.message + "!");
|
Feng.error("修改失败!" + data.message + "!");
|
||||||
});
|
});
|
||||||
ajax.set("fileId", res.data.fileId);
|
updateAvatarRequest.set("fileId", res.data.fileId);
|
||||||
ajax.start();
|
updateAvatarRequest.start();
|
||||||
}
|
}
|
||||||
, error: function () {
|
, error: function () {
|
||||||
Feng.error("上传头像失败!");
|
Feng.error("上传头像失败!");
|
|
@ -43,48 +43,12 @@
|
||||||
<script type="text/javascript" src="${ctxPath}/assets/common/js/common.js?v=${constants.getReleaseVersion()}"></script>
|
<script type="text/javascript" src="${ctxPath}/assets/common/js/common.js?v=${constants.getReleaseVersion()}"></script>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
layui.use(['layer', 'element', 'admin', 'index', 'ax'], function () {
|
layui.use(['layer', 'element', 'admin', 'index', 'HttpRequest'], function () {
|
||||||
var $ = layui.jquery;
|
var $ = layui.jquery;
|
||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
var admin = layui.admin;
|
var admin = layui.admin;
|
||||||
var index = layui.index;
|
var index = layui.index;
|
||||||
var $ax = layui.ax;
|
var HttpRequest = layui.HttpRequest;
|
||||||
|
|
||||||
//获取支持的语言列表
|
|
||||||
var ajax = new $ax(Feng.ctxPath + "/translation/languages", function (data) {
|
|
||||||
for (var i = 0; i < data.data.length; i++) {
|
|
||||||
var code = data.data[i].code;
|
|
||||||
var description = data.data[i].description;
|
|
||||||
$("#languageDiv").append('<dd lay-unselect><a id="tran-' + code + '" href="javascript:;">' + description + '</a></dd>');
|
|
||||||
|
|
||||||
//设置监听事件,设置点击按钮切换当前系统语言
|
|
||||||
(function (code) {
|
|
||||||
$('#tran-' + code).click(function () {
|
|
||||||
var ajax = new $ax(Feng.ctxPath + "/translation/changeUserTranslation", function (data) {
|
|
||||||
window.location.href = Feng.ctxPath + "/";
|
|
||||||
}, function (data) {
|
|
||||||
layer.msg("切换多语言失败!" + data.responseJSON.message, {icon: 5, anim: 6});
|
|
||||||
});
|
|
||||||
ajax.set("code", code);
|
|
||||||
ajax.start();
|
|
||||||
});
|
|
||||||
})(code);
|
|
||||||
}
|
|
||||||
}, function (data) {
|
|
||||||
layer.msg("获取语言列表失败!" + data.responseJSON.message, {icon: 5, anim: 6});
|
|
||||||
});
|
|
||||||
ajax.start();
|
|
||||||
|
|
||||||
// 加载当前语言字典并缓存
|
|
||||||
var getUserTranslationAjax = new $ax(Feng.ctxPath + "/translation/getUserTranslation", function (data) {
|
|
||||||
layui.data('system', {
|
|
||||||
key: "lang",
|
|
||||||
value: data.data
|
|
||||||
});
|
|
||||||
}, function (data) {
|
|
||||||
layer.msg("加载语言字典失败!" + data.responseJSON.message, {icon: 5, anim: 6});
|
|
||||||
});
|
|
||||||
getUserTranslationAjax.start();
|
|
||||||
|
|
||||||
// 默认加载主页
|
// 默认加载主页
|
||||||
index.loadHome({
|
index.loadHome({
|
||||||
|
@ -94,7 +58,6 @@
|
||||||
|
|
||||||
// 修改密码点击事件
|
// 修改密码点击事件
|
||||||
$('#setPsw').click(function () {
|
$('#setPsw').click(function () {
|
||||||
|
|
||||||
admin.open({
|
admin.open({
|
||||||
id: 'pswForm',
|
id: 'pswForm',
|
||||||
type: 2,
|
type: 2,
|
||||||
|
@ -106,13 +69,13 @@
|
||||||
|
|
||||||
// 退出登录点击事件
|
// 退出登录点击事件
|
||||||
$('#btnLogout').click(function () {
|
$('#btnLogout').click(function () {
|
||||||
var ajax = new $ax(Feng.ctxPath + "/logout", function (data) {
|
var request = new HttpRequest(Feng.ctxPath + "/logout", 'post', function (data) {
|
||||||
Feng.success("退出成功!");
|
Feng.success("退出成功!");
|
||||||
window.location.href = Feng.ctxPath + "/";
|
window.location.href = Feng.ctxPath + "/";
|
||||||
}, function (data) {
|
}, function (data) {
|
||||||
layer.msg("退出失败!" + data.responseJSON.message, {icon: 5, anim: 6});
|
layer.msg("退出失败!" + data.message, {icon: 5, anim: 6});
|
||||||
});
|
});
|
||||||
ajax.start();
|
request.start();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
@/* 页脚 */
|
@/* 页脚 */
|
||||||
<div class="layui-footer">
|
<div class="layui-footer">
|
||||||
Copyright © 2019 <a href="https://www.stylefeng.cn" target="_blank">stylefeng</a> All rights reserved.
|
Copyright © 2021 <a href="https://www.stylefeng.cn" target="_blank">stylefeng</a> All rights reserved.
|
||||||
<span class="pull-right">Version 企业版 v3.4</span>
|
<span class="pull-right">Version v7</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@/* 手机屏幕遮罩层 */
|
@/* 手机屏幕遮罩层 */
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
@if(objectUtil.isNotEmpty(layuiAppIndexMenus)){
|
@if(objectUtil.isNotEmpty(layuiAppIndexMenus)){
|
||||||
@for(item in layuiAppIndexMenus) {
|
@for(item in layuiAppIndexMenus) {
|
||||||
@if(itemLP.index == 1){
|
@if(itemLP.index == 1){
|
||||||
<li class="layui-nav-item layui-hide-xs layui-this" lay-unselect><a nav-bind="${item.appCode}">${item.appCode}</a></li>
|
<li class="layui-nav-item layui-hide-xs layui-this" lay-unselect><a nav-bind="${item.appCode}">${item.appName}</a></li>
|
||||||
@}else{
|
@}else{
|
||||||
<li class="layui-nav-item layui-hide-xs" lay-unselect><a nav-bind="${item.appCode}">${item.appCode}</a></li>
|
<li class="layui-nav-item layui-hide-xs" lay-unselect><a nav-bind="${item.appCode}">${item.appName}</a></li>
|
||||||
@}
|
@}
|
||||||
@}
|
@}
|
||||||
@}
|
@}
|
||||||
|
@ -44,8 +44,6 @@
|
||||||
<a id="setPsw">修改密码</a>
|
<a id="setPsw">修改密码</a>
|
||||||
</dd>
|
</dd>
|
||||||
<hr>
|
<hr>
|
||||||
<div id="languageDiv"></div>
|
|
||||||
<hr>
|
|
||||||
<dd lay-unselect>
|
<dd lay-unselect>
|
||||||
<a id="btnLogout">退出</a>
|
<a id="btnLogout">退出</a>
|
||||||
</dd>
|
</dd>
|
||||||
|
|
|
@ -163,14 +163,6 @@
|
||||||
<div class="login-wrapper layui-anim layui-anim-scale layui-hide">
|
<div class="login-wrapper layui-anim layui-anim-scale layui-hide">
|
||||||
<div class="layui-form">
|
<div class="layui-form">
|
||||||
<h2>用户登录</h2>
|
<h2>用户登录</h2>
|
||||||
@if(constants.getTenantOpen()){
|
|
||||||
<div class="layui-form-item layui-input-icon-group">
|
|
||||||
<i class="layui-icon layui-icon-username"></i>
|
|
||||||
<select name="tenantCode" id="tenantCode">
|
|
||||||
<option value="">默认租户</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
@}
|
|
||||||
<div class="layui-form-item layui-input-icon-group">
|
<div class="layui-form-item layui-input-icon-group">
|
||||||
<i class="layui-icon layui-icon-username"></i>
|
<i class="layui-icon layui-icon-username"></i>
|
||||||
<input class="layui-input" id="username" name="username" placeholder="请输入登录账号" value="admin" autocomplete="off" lay-verType="tips" lay-verify="required" required/>
|
<input class="layui-input" id="username" name="username" placeholder="请输入登录账号" value="admin" autocomplete="off" lay-verType="tips" lay-verify="required" required/>
|
||||||
|
@ -179,20 +171,13 @@
|
||||||
<i class="layui-icon layui-icon-password"></i>
|
<i class="layui-icon layui-icon-password"></i>
|
||||||
<input class="layui-input" id="password" name="password" placeholder="请输入登录密码" value="111111" type="password" lay-verType="tips" lay-verify="required" required/>
|
<input class="layui-input" id="password" name="password" placeholder="请输入登录密码" value="111111" type="password" lay-verType="tips" lay-verify="required" required/>
|
||||||
</div>
|
</div>
|
||||||
@if(constants.getCaptchaOpen()){
|
|
||||||
<div class="layui-form-item layui-input-icon-group login-captcha-group">
|
|
||||||
<i class="layui-icon layui-icon-auz"></i>
|
|
||||||
<input class="layui-input" id="kaptcha" placeholder="请输入验证码" autocomplete="off" lay-verType="tips" lay-verify="required" required/>
|
|
||||||
<img class="login-captcha" src="${ctxPath}/kaptcha" alt=""/>
|
|
||||||
</div>
|
|
||||||
@}
|
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<button class="layui-btn layui-btn-fluid" id="submit">登录</button>
|
<button class="layui-btn layui-btn-fluid" id="submit">登录</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item login-oauth-group text-center">
|
<div class="layui-form-item login-oauth-group text-center">
|
||||||
<a href="${ctxPath}/oauth/render/qq"><i class="layui-icon layui-icon-login-qq" style="color:#3492ed;"></i></a> 
|
<a href="${ctxPath}/oauth/render/qq"><i class="layui-icon layui-icon-login-qq" style="color:#3492ed;"></i></a> 
|
||||||
<a href="${ctxPath}/oauth/render/gitee">
|
<a href="${ctxPath}/oauth/render/gitee">
|
||||||
<img class="layui-icon" style="height: 28px;width: 28px; margin-top: -12px !important;" src="${ctxPath}/assets/expand/images/git.png" />
|
<img class="layui-icon" style="height: 28px;width: 28px; margin-top: -12px !important;" src="${ctxPath}/assets/expand/images/git.png"/>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -211,57 +196,34 @@
|
||||||
<script type="text/javascript" src="${ctxPath}/assets/common/libs/layui/layui.js?v=${constants.getReleaseVersion()}"></script>
|
<script type="text/javascript" src="${ctxPath}/assets/common/libs/layui/layui.js?v=${constants.getReleaseVersion()}"></script>
|
||||||
<script type="text/javascript" src="${ctxPath}/assets/common/js/common.js?v=${constants.getReleaseVersion()}"></script>
|
<script type="text/javascript" src="${ctxPath}/assets/common/js/common.js?v=${constants.getReleaseVersion()}"></script>
|
||||||
<script>
|
<script>
|
||||||
layui.use(['layer', 'form', 'index', 'ax'], function () {
|
layui.use(['layer', 'form', 'index', 'HttpRequest'], function () {
|
||||||
var $ = layui.jquery;
|
var $ = layui.jquery;
|
||||||
var layer = layui.layer;
|
var layer = layui.layer;
|
||||||
var form = layui.form;
|
var form = layui.form;
|
||||||
var $ax = layui.ax;
|
var HttpRequest = layui.HttpRequest;
|
||||||
var index = layui.index;
|
var index = layui.index;
|
||||||
|
|
||||||
$('.login-wrapper').removeClass('layui-hide');
|
$('.login-wrapper').removeClass('layui-hide');
|
||||||
|
|
||||||
/* 图形验证码 */
|
|
||||||
$('img.login-captcha').click(function () {
|
|
||||||
this.src = this.src + '?t=' + (new Date).getTime();
|
|
||||||
});
|
|
||||||
|
|
||||||
var errorMsg = "${tips!}";
|
var errorMsg = "${tips!}";
|
||||||
if (errorMsg) {
|
if (errorMsg) {
|
||||||
layer.msg(errorMsg, {icon: 5, anim: 6});
|
layer.msg(errorMsg, {icon: 5, anim: 6});
|
||||||
}
|
}
|
||||||
|
|
||||||
@if(constants.getTenantOpen()){
|
// 登录操作
|
||||||
//初始化租户列表
|
|
||||||
var ajax = new $ax(Feng.ctxPath + "/tenantInfo/listTenants", function (data) {
|
|
||||||
for (var i = 0; i < data.data.length; i++) {
|
|
||||||
var name = data.data[i].name;
|
|
||||||
var code = data.data[i].code;
|
|
||||||
$("#tenantCode").append('<option value="' + code + '">' + name + '</option>');
|
|
||||||
}
|
|
||||||
form.render();
|
|
||||||
}, function (data) {
|
|
||||||
});
|
|
||||||
ajax.start();
|
|
||||||
@}
|
|
||||||
|
|
||||||
//登录操作
|
|
||||||
$('#submit').click(function () {
|
$('#submit').click(function () {
|
||||||
var ajax = new $ax(Feng.ctxPath + "/loginAction", function (data) {
|
var request = new HttpRequest(Feng.ctxPath + "/loginAction", 'post', function (data) {
|
||||||
Feng.success("登录成功!");
|
Feng.success("登录成功!");
|
||||||
|
// 清除顶部选择应用的缓存
|
||||||
index.clearTabCache();
|
index.clearTabCache();
|
||||||
|
// 重定向到首页
|
||||||
window.location.href = Feng.ctxPath + "/";
|
window.location.href = Feng.ctxPath + "/";
|
||||||
}, function (data) {
|
}, function (data) {
|
||||||
layer.msg("登录失败!" + data.responseJSON.message, {icon: 5, anim: 6});
|
Feng.error("登录失败!" + data.message);
|
||||||
});
|
});
|
||||||
ajax.set("account", $("#username").val());
|
request.set("account", $("#username").val());
|
||||||
ajax.set("password", $("#password").val());
|
request.set("password", $("#password").val());
|
||||||
@if(constants.getTenantOpen()){
|
request.start(true);
|
||||||
ajax.set("tenantCode", $("#tenantCode").val());
|
|
||||||
@}
|
|
||||||
@if(constants.getCaptchaOpen()){
|
|
||||||
ajax.set("kaptcha", $("#kaptcha").val());
|
|
||||||
@}
|
|
||||||
ajax.start();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">旧密码:</label>
|
<label class="layui-form-label">旧密码:</label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="password" name="oldPassword" placeholder="请输入原始密码" class="layui-input"
|
<input type="password" name="password" placeholder="请输入原始密码" class="layui-input"
|
||||||
lay-verType="tips" lay-verify="required" required/>
|
lay-verType="tips" lay-verify="required" required/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
@layout("/layout/_container.html", {title:"个人中心", css:["/assets/modular/frame/user_info.css"], js:["/assets/modular/frame/user_info.js"]}){
|
@layout("/layout/_container.html", {title:"个人中心", css:["/assets/modular/frame/user_info.css"], js:["/assets/modular/frame/personal_info.js"]}){
|
||||||
<div class="layui-body-header">
|
<div class="layui-body-header">
|
||||||
<span class="layui-body-header-title">个人信息</span>
|
<span class="layui-body-header-title">个人信息</span>
|
||||||
<span class="layui-breadcrumb pull-right">
|
<span class="layui-breadcrumb pull-right">
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">性别:</label>
|
<label class="layui-form-label">性别:<span style="color: red;">*</span></label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="radio" name="sex" value="M" title="男">
|
<input type="radio" name="sex" value="M" title="男">
|
||||||
<input type="radio" name="sex" value="F" title="女">
|
<input type="radio" name="sex" value="F" title="女">
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
<label class="layui-form-label">姓名:<span style="color: red;">*</span></label>
|
<label class="layui-form-label">姓名:<span style="color: red;">*</span></label>
|
||||||
<div class="layui-input-block">
|
<div class="layui-input-block">
|
||||||
<input type="text" name="name" class="layui-input" lay-verify="required" required/>
|
<input type="text" name="realName" class="layui-input" lay-verify="required" required/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="layui-form-item">
|
<div class="layui-form-item">
|
||||||
|
|
Loading…
Reference in New Issue