Merge branch 'master' into group2

# Conflicts:
#	src/main/webapp/assets/common/js/common.js
pull/65/head
chenjinlong 4 years ago
commit bc2500c518

@ -60,12 +60,6 @@
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>jwt-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>cn.stylefeng.roses</groupId>
<artifactId>scanner-spring-boot-starter</artifactId>

@ -1,5 +1,6 @@
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.CustomErrorView;
import cn.stylefeng.guns.core.security.AuthJwtTokenSecurityInterceptor;
@ -60,8 +61,11 @@ public class SpringMvcConfiguration implements WebMvcConfigurer {
* @date 2020/12/16 15:47
*/
@Bean("error")
public CustomErrorView error() {
return new CustomErrorView();
public CustomErrorView error(CustomBeetlGroupUtilConfiguration customBeetlGroupUtilConfiguration) {
CustomErrorView customErrorView = new CustomErrorView();
customErrorView.setUrl("/404.html");
customErrorView.setGroupTemplate(customBeetlGroupUtilConfiguration.getGroupTemplate());
return customErrorView;
}
/**

@ -1,14 +1,6 @@
package cn.stylefeng.guns.core.error;
import cn.hutool.core.bean.BeanUtil;
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;
import org.beetl.ext.spring.BeetlSpringView;
/**
* (404,)
@ -16,17 +8,11 @@ import java.util.Map;
* @author fengshuonan
* @date 2017-05-21 11:34
*/
public class CustomErrorView implements View {
public class CustomErrorView extends BeetlSpringView {
@Override
public String getContentType() {
return "text/html";
}
@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());
return "text/html;charset=UTF-8";
}
}

@ -2,17 +2,21 @@ package cn.stylefeng.guns.core.error;
import cn.hutool.core.util.ObjectUtil;
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.exception.base.ServiceException;
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.util.ExceptionUtil;
import cn.stylefeng.roses.kernel.rule.util.ResponseRenderUtil;
import cn.stylefeng.roses.kernel.system.constants.SymbolConstant;
import cn.stylefeng.roses.kernel.validator.exception.ParamValidateException;
import cn.stylefeng.roses.kernel.validator.exception.enums.ValidatorExceptionEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.ui.Model;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.ObjectError;
@ -27,6 +31,7 @@ import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.ValidationException;
import java.util.List;
@ -136,6 +141,7 @@ public class GlobalExceptionHandler {
*/
@ExceptionHandler(BindException.class)
@ResponseBody
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorResponseData bindException(BindException e) {
String bindingResult = getArgNotValidMessage(e.getBindingResult());
return renderJson(ValidatorExceptionEnum.VALIDATED_RESULT_ERROR, bindingResult);
@ -149,6 +155,7 @@ public class GlobalExceptionHandler {
*/
@ExceptionHandler(ValidationException.class)
@ResponseBody
@ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
public ErrorResponseData bindException(ValidationException e) {
if (e.getCause() instanceof ParamValidateException) {
ParamValidateException paramValidateException = (ParamValidateException) e.getCause();
@ -157,6 +164,44 @@ public class GlobalExceptionHandler {
return renderJson(e);
}
/**
*
* <p>
*
* <p>
* ajaxresponseheadersession-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
*/
@ExceptionHandler(ServiceException.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ResponseBody
public ErrorResponseData businessError(ServiceException e) {
log.error("业务异常,具体信息为:{}", e.getMessage());

@ -3,7 +3,6 @@ package cn.stylefeng.guns.core.security;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.guns.core.security.base.BaseSecurityInterceptor;
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.enums.AuthExceptionEnum;
import cn.stylefeng.roses.kernel.resource.api.pojo.resource.ResourceDefinition;
@ -30,12 +29,6 @@ public class AuthJwtTokenSecurityInterceptor extends BaseSecurityInterceptor {
@Resource
private AuthServiceApi authServiceApi;
/**
* Api
*/
@Resource
private SessionManagerApi sessionManagerApi;
@Override
public void filterAction(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, ResourceDefinition resourceDefinition, String token) {
@ -52,9 +45,6 @@ public class AuthJwtTokenSecurityInterceptor extends BaseSecurityInterceptor {
// 3.校验token和用户会话信息是否正确
authServiceApi.checkAuth(token, requestURI);
// 4.刷新用户的session的过期时间
sessionManagerApi.refreshSession(token);
}
}

@ -1,6 +1,11 @@
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.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.resource.api.pojo.resource.ResourceDefinition;
import cn.stylefeng.roses.kernel.resource.api.pojo.resource.ResourceUrlParam;
@ -25,6 +30,12 @@ public abstract class BaseSecurityInterceptor implements HandlerInterceptor {
@Resource
private ResourceServiceApi resourceServiceApi;
@Resource
private AuthServiceApi authServiceApi;
@Resource
private SessionManagerApi sessionManagerApi;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
@ -32,7 +43,7 @@ public abstract class BaseSecurityInterceptor implements HandlerInterceptor {
String requestURI = request.getRequestURI();
// 2. 不需要权限过滤的资源,直接放行
Boolean noneSecurityFlag = AntPathMatcherUtil.getAntMatchFLag(requestURI, AuthConfigExpander.getNoneSecurityConfig());
Boolean noneSecurityFlag = AntPathMatcherUtil.getAntMatchFLag(requestURI, request.getContextPath(), AuthConfigExpander.getNoneSecurityConfig());
if (noneSecurityFlag) {
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.setUrl(requestURI);
ResourceDefinition resourceDefinition = resourceServiceApi.getResourceByUrl(resourceUrlParam);
// 5. 资源找不到则当前url不被权限控制直接放行
// 7. 资源找不到则当前url不被权限控制直接放行
if (resourceDefinition == null) {
return true;
}
// 6.执行真正过滤器业务,如果拦截器执行不成功会抛出异常
// 8.执行真正过滤器业务,如果拦截器执行不成功会抛出异常
this.filterAction(request, response, resourceDefinition, token);
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.GetResource;
@ -14,7 +14,7 @@ import org.springframework.stereotype.Controller;
@Controller
@Slf4j
@ApiResource(name = "工作台和分析页面")
public class BlackboardViewController {
public class DashboardViewController {
/**
*
@ -22,7 +22,7 @@ public class BlackboardViewController {
* @author fengshuonan
* @date 2018/12/24 22:43
*/
@GetResource(name = "工作台", path = "/blackboard/platform", requiredPermission = false)
@GetResource(name = "工作台", path = "/dashboard/workplace", requiredPermission = false)
public String platform() {
return "/modular/blackboard/board_platform.html";
}
@ -33,7 +33,7 @@ public class BlackboardViewController {
* @author fengshuonan
* @date 2020/12/29 21:27
*/
@GetResource(name = "分析页面", path = "/blackboard/analyse", requiredPermission = false)
@GetResource(name = "分析页面", path = "/dashboard/analysis", requiredPermission = false)
public String analyse() {
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;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.modular.index.service.IndexService;
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.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 org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import javax.annotation.Resource;
import java.util.List;
/**
*
@ -32,13 +22,7 @@ import java.util.List;
public class IndexViewController {
@Resource
private SysMenuService sysMenuService;
@Resource
private SysUserService sysUserService;
@Resource
private HrOrganizationService hrOrganizationService;
private IndexService indexService;
/**
*
@ -51,20 +35,7 @@ public class IndexViewController {
// 当前用户已经登录,跳转到首页
if (LoginContext.me().hasLogin()) {
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());
model.addAllAttributes(indexService.createIndexRenderAttributes());
return "/index.html";
}
@ -80,29 +51,7 @@ public class IndexViewController {
*/
@GetResource(name = "个人中心界面", path = "/personal", requiredLogin = false)
public String personal(Model model) {
LoginUser loginUser = LoginContext.me().getLoginUser();
// 用户基本信息
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()));
model.addAllAttributes(indexService.createPersonInfoRenderAttributes());
return "/modular/index/personal_info.html";
}

@ -1,7 +1,23 @@
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 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
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) {
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) {
top.layer.confirm(tip, {
skin: 'layui-layer-admin'
@ -130,9 +140,8 @@ layui.config({
selectPlus: '../../expand/module/selectPlus/selectPlus',
iconPicker: '../../expand/module/iconPicker/iconPicker',
ztree: '../../expand/module/ztree/ztree-object',
ax: '../../expand/module/ax/ax',
func: '../../expand/module/func/func',
ajaxUtil: '../../expand/module/ax/ajaxUtil'
HttpRequest: '../../expand/module/HttpRequest/HttpRequest',
func: '../../expand/module/func/func'
}).use(['layer', 'admin'], function () {
var $ = layui.jquery;
var layer = layui.layer;
@ -147,12 +156,10 @@ layui.config({
$.ajaxSetup({
contentType: "application/x-www-form-urlencoded;charset=utf-8",
complete: function (XMLHttpRequest, textStatus) {
//如果超时就处理 ,指定要跳转的页面
if (XMLHttpRequest.getResponseHeader("Guns-Session-Timeout") === "true") {
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 layer = layui.layer;
var form = layui.form;
var admin = layui.admin;
var $ax = layui.ax;
var HttpRequest = layui.HttpRequest;
// 让当前iframe弹层高度适应
admin.iframeAuto();
// 监听提交
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("修改成功!");
admin.closeThisDialog();
}, function (data) {
Feng.error("修改失败!" + data.responseJSON.message + "!");
}, function (response) {
Feng.dialog("修改失败", response.message);
});
ajax.setData(data.field);
ajax.start();
request.set(data.field);
request.start(true);
//阻止表单跳转。如果需要表单跳转,去掉这段即可。
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 form = layui.form;
var upload = layui.upload;
var element = layui.element;
var $ax = layui.ax;
var HttpRequest = layui.HttpRequest;
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 result = ajax.start();
var request = new HttpRequest(Feng.ctxPath + "/sysUser/currentUserInfo", 'get');
var result = request.start();
//用这个方法必须用在class有layui-form的元素上
form.val('userInfoForm', result.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("修改成功!");
}, function (data) {
Feng.error("修改失败!" + data.responseJSON.message + "!");
}, function (response) {
Feng.error("修改失败!" + response.message + "!");
});
ajax.set(data.field);
ajax.start();
updateUserInfoRequest.set(data.field);
updateUserInfoRequest.start(true);
});
upload.render({
@ -38,13 +38,13 @@ layui.use(['form', 'upload', 'element', 'ax', 'laydate'], function () {
});
}
, 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);
}, function (data) {
Feng.error("修改失败!" + data.responseJSON.message + "!");
Feng.error("修改失败!" + data.message + "!");
});
ajax.set("fileId", res.data.fileId);
ajax.start();
updateAvatarRequest.set("fileId", res.data.fileId);
updateAvatarRequest.start();
}
, error: function () {
Feng.error("上传头像失败!");

@ -43,48 +43,12 @@
<script type="text/javascript" src="${ctxPath}/assets/common/js/common.js?v=${constants.getReleaseVersion()}"></script>
<script>
layui.use(['layer', 'element', 'admin', 'index', 'ax'], function () {
layui.use(['layer', 'element', 'admin', 'index', 'HttpRequest'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var admin = layui.admin;
var index = layui.index;
var $ax = layui.ax;
//获取支持的语言列表
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();
var HttpRequest = layui.HttpRequest;
// 默认加载主页
index.loadHome({
@ -94,7 +58,6 @@
// 修改密码点击事件
$('#setPsw').click(function () {
admin.open({
id: 'pswForm',
type: 2,
@ -106,13 +69,13 @@
// 退出登录点击事件
$('#btnLogout').click(function () {
var ajax = new $ax(Feng.ctxPath + "/logout", function (data) {
var request = new HttpRequest(Feng.ctxPath + "/logout", 'post', function (data) {
Feng.success("退出成功!");
window.location.href = Feng.ctxPath + "/";
}, function (data) {
layer.msg("退出失败!" + data.responseJSON.message, {icon: 5, anim: 6});
layer.msg("退出失败!" + data.message, {icon: 5, anim: 6});
});
ajax.start();
request.start();
});
});
</script>

@ -1,7 +1,7 @@
@/* 页脚 */
<div class="layui-footer">
Copyright © 2019 <a href="https://www.stylefeng.cn" target="_blank">stylefeng</a> All rights reserved.
<span class="pull-right">Version 企业版 v3.4</span>
Copyright © 2021 <a href="https://www.stylefeng.cn" target="_blank">stylefeng</a> All rights reserved.
<span class="pull-right">Version v7</span>
</div>
@/* 手机屏幕遮罩层 */

@ -16,9 +16,9 @@
@if(objectUtil.isNotEmpty(layuiAppIndexMenus)){
@for(item in layuiAppIndexMenus) {
@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{
<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>
</dd>
<hr>
<div id="languageDiv"></div>
<hr>
<dd lay-unselect>
<a id="btnLogout">退出</a>
</dd>

@ -163,14 +163,6 @@
<div class="login-wrapper layui-anim layui-anim-scale layui-hide">
<div class="layui-form">
<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">
<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/>
@ -179,20 +171,13 @@
<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/>
</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">
<button class="layui-btn layui-btn-fluid" id="submit">登录</button>
</div>
<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>&emsp;
<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>
</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/js/common.js?v=${constants.getReleaseVersion()}"></script>
<script>
layui.use(['layer', 'form', 'index', 'ax'], function () {
layui.use(['layer', 'form', 'index', 'HttpRequest'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var $ax = layui.ax;
var HttpRequest = layui.HttpRequest;
var index = layui.index;
$('.login-wrapper').removeClass('layui-hide');
/* 图形验证码 */
$('img.login-captcha').click(function () {
this.src = this.src + '?t=' + (new Date).getTime();
});
var errorMsg = "${tips!}";
if (errorMsg) {
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 () {
var ajax = new $ax(Feng.ctxPath + "/loginAction", function (data) {
var request = new HttpRequest(Feng.ctxPath + "/loginAction", 'post', function (data) {
Feng.success("登录成功!");
// 清除顶部选择应用的缓存
index.clearTabCache();
// 重定向到首页
window.location.href = Feng.ctxPath + "/";
}, function (data) {
layer.msg("登录失败!" + data.responseJSON.message, {icon: 5, anim: 6});
Feng.error("登录失败!" + data.message);
});
ajax.set("account", $("#username").val());
ajax.set("password", $("#password").val());
@if(constants.getTenantOpen()){
ajax.set("tenantCode", $("#tenantCode").val());
@}
@if(constants.getCaptchaOpen()){
ajax.set("kaptcha", $("#kaptcha").val());
@}
ajax.start();
request.set("account", $("#username").val());
request.set("password", $("#password").val());
request.start(true);
});
});

@ -3,7 +3,7 @@
<div class="layui-form-item">
<label class="layui-form-label">旧密码:</label>
<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/>
</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">
<span class="layui-body-header-title">个人信息</span>
<span class="layui-breadcrumb pull-right">
@ -66,7 +66,7 @@
</div>
</div>
<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">
<input type="radio" name="sex" value="M" title="男">
<input type="radio" name="sex" value="F" title="女">
@ -81,7 +81,7 @@
<div class="layui-form-item">
<label class="layui-form-label">姓名:<span style="color: red;">*</span></label>
<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 class="layui-form-item">

Loading…
Cancel
Save