diff --git a/README.md b/README.md index eb7b2cb..380bcb3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,4 @@ -# 上一套框架用的SSM 配置过于麻烦。 -# 现在重新起了一套SpringBoot框架 - -## 每套框架我都给他起了一个名字(这次的叫做黑科MES,代表黑马、黑科技) +# sp-archetype ## 界面展示 ![](https://s2.ax1x.com/2020/03/06/3b89zD.gif) @@ -47,9 +44,8 @@ springBoot+mybatis-plus+redis+shiro+hutool+layuimini+jenkins * https://gitee.com/whvse/treetable-lay * 图标库使用 - * http://www.fontawesome.com.cn/faicons/ - * 阿里矢量图标 - * https://www.iconfont.cn/ + * http://www.fontawesome.com.cn/faicons + * 发送 ajax 示例:[详情](./docs/ajax.md) * 后端 * Hutool 是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。 * 枚举 @@ -58,12 +54,7 @@ springBoot+mybatis-plus+redis+shiro+hutool+layuimini+jenkins * 请求参数 * 每张表的分页查询参数,严格按照一张表对应一个请求参数对象进行开发,如系统用户分页查询参数:com.songpeng.sparchetype.system.request.SysUserPageReq * - -#### 安装教程 -1. xxxx -2. xxxx -3. xxxx diff --git a/docs/ajax.md b/docs/ajax.md new file mode 100644 index 0000000..ab24f70 --- /dev/null +++ b/docs/ajax.md @@ -0,0 +1,25 @@ +### 前端 Ajax 工具类使用说明 + +封装 Jquery Ajax 请求方法,并对 session 失效进行检测,通过整合 Shiro,利用拦截器解决 Ajax 302 无法跳转登录页问题。 + +``` +// spUtil.ajax() +spUtil.ajax({ + url: '${request.contextPath}/admin/sys/user/page', + async: false, + type: 'POST', + // 是否显示 loading + showLoading: true, + // 是否序列化参数 + serializable: false, + // 参数 + data: { + current: 1, + size: 10 + }, + success: function (data) { + console.log(data); + } +}); +``` + diff --git a/sparchetype/src/main/java/com/songpeng/sparchetype/common/Result.java b/sparchetype/src/main/java/com/songpeng/sparchetype/common/Result.java index fd3d0e4..af0fd30 100644 --- a/sparchetype/src/main/java/com/songpeng/sparchetype/common/Result.java +++ b/sparchetype/src/main/java/com/songpeng/sparchetype/common/Result.java @@ -11,11 +11,11 @@ import java.util.HashMap; public class Result extends HashMap { public static Result success() { - return restResult(null, 0, null); + return restResult(null, 0, "操作成功"); } public static Result success(T data) { - return restResult(data, 0, null); + return restResult(data, 0, "操作成功"); } public static Result success(T data, String msg) { @@ -23,7 +23,7 @@ public class Result extends HashMap { } public static Result failure() { - return restResult(null, 1, null); + return restResult(null, 1, "操作失败"); } public static Result failure(String msg) { @@ -31,7 +31,7 @@ public class Result extends HashMap { } public static Result failure(T data) { - return restResult(data, 1, null); + return restResult(data, 1, "操作失败"); } public static Result failure(T data, String msg) { diff --git a/sparchetype/src/main/java/com/songpeng/sparchetype/common/advice/ExceptionAdvice.java b/sparchetype/src/main/java/com/songpeng/sparchetype/common/advice/ExceptionAdvice.java index fac7e12..6ad091c 100644 --- a/sparchetype/src/main/java/com/songpeng/sparchetype/common/advice/ExceptionAdvice.java +++ b/sparchetype/src/main/java/com/songpeng/sparchetype/common/advice/ExceptionAdvice.java @@ -1,7 +1,7 @@ package com.songpeng.sparchetype.common.advice; import com.songpeng.sparchetype.common.Result; -import com.songpeng.sparchetype.common.util.HttpServletUtils; +import com.songpeng.sparchetype.common.util.HttpUtil; import org.apache.shiro.authz.AuthorizationException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -26,7 +26,7 @@ public class ExceptionAdvice { @ResponseBody public Object handleAuthorizationException(AuthorizationException e, HttpServletRequest request) { log.error(e.getMessage(), e); - if (HttpServletUtils.isAjax(request)) { + if (HttpUtil.isAjax(request)) { return Result.failure("未授权"); } return new ModelAndView("error/403"); @@ -36,7 +36,7 @@ public class ExceptionAdvice { @ResponseBody public Object handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) { log.error(e.getMessage(), e); - if (HttpServletUtils.isAjax(request)) { + if (HttpUtil.isAjax(request)) { return Result.failure("数据重复"); } return new ModelAndView("error/403"); @@ -46,7 +46,7 @@ public class ExceptionAdvice { @ResponseBody public Object handleException(Exception e, HttpServletRequest request) { log.error(e.getMessage(), e); - if (HttpServletUtils.isAjax(request)) { + if (HttpUtil.isAjax(request)) { return Result.failure("服务器错误,请联系管理员"); } return new ModelAndView("error/500"); diff --git a/sparchetype/src/main/java/com/songpeng/sparchetype/common/util/HttpServletUtils.java b/sparchetype/src/main/java/com/songpeng/sparchetype/common/util/HttpServletUtils.java deleted file mode 100644 index ff06a26..0000000 --- a/sparchetype/src/main/java/com/songpeng/sparchetype/common/util/HttpServletUtils.java +++ /dev/null @@ -1,23 +0,0 @@ -package com.songpeng.sparchetype.common.util; - -import org.apache.commons.lang3.StringUtils; - -import javax.servlet.http.HttpServletRequest; - -public class HttpServletUtils { - - /** - * 判断请求是否是 ajax 请求 - * - * @param req - * @return - */ - public static boolean isAjax(HttpServletRequest req) { - //判断是否为ajax请求,默认不是 - boolean isAjaxRequest = false; - if (!StringUtils.isBlank(req.getHeader("x-requested-with")) && req.getHeader("x-requested-with").equals("XMLHttpRequest")) { - isAjaxRequest = true; - } - return isAjaxRequest; - } -} diff --git a/sparchetype/src/main/java/com/songpeng/sparchetype/common/util/HttpUtil.java b/sparchetype/src/main/java/com/songpeng/sparchetype/common/util/HttpUtil.java new file mode 100644 index 0000000..ca9c5ea --- /dev/null +++ b/sparchetype/src/main/java/com/songpeng/sparchetype/common/util/HttpUtil.java @@ -0,0 +1,23 @@ +package com.songpeng.sparchetype.common.util; + +import org.apache.commons.lang3.StringUtils; + +import javax.servlet.http.HttpServletRequest; + +public class HttpUtil extends cn.hutool.http.HttpUtil { + + /** + * 判断请求是否是 ajax 请求 + * + * @param req + * @return + */ + public static boolean isAjax(HttpServletRequest req) { + //判断是否为ajax请求,默认不是 + boolean isAjaxRequest = false; + if (!StringUtils.isBlank(req.getHeader("x-requested-with")) && req.getHeader("x-requested-with").equals("XMLHttpRequest")) { + isAjaxRequest = true; + } + return isAjaxRequest; + } +} diff --git a/sparchetype/src/main/java/com/songpeng/sparchetype/system/config/shiro/ShiroConfig.java b/sparchetype/src/main/java/com/songpeng/sparchetype/system/config/shiro/ShiroConfig.java index c437a3d..813d731 100644 --- a/sparchetype/src/main/java/com/songpeng/sparchetype/system/config/shiro/ShiroConfig.java +++ b/sparchetype/src/main/java/com/songpeng/sparchetype/system/config/shiro/ShiroConfig.java @@ -15,9 +15,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; -import java.util.ArrayList; -import java.util.Collection; -import java.util.LinkedHashMap; +import javax.servlet.Filter; +import java.util.*; /** * Shiro 安全管理器配置 @@ -97,6 +96,12 @@ public class ShiroConfig { filterChainDefinitionMap.put("/blog", "anon"); filterChainDefinitionMap.put("/blog/open/**", "anon"); filterChainDefinitionMap.put("/**", "authc"); + + Map filters = new HashMap<>(2); + Filter loginFilter = new SpLoginFormFilter(); + //此处使用自定义的拦截器,autho默认使用FormAuthenticationFilter拦截器 + filters.put("authc", loginFilter); + shiroFilterFactoryBean.setFilters(filters); // TODO 测试期间暂时打开 //filterChainDefinitionMap.put("/**", "anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); @@ -142,7 +147,8 @@ public class ShiroConfig { RedisManager redisManager = new RedisManager(); redisManager.setHost(host); redisManager.setPort(port); - redisManager.setExpire(1800);// 配置缓存过期时间 + // 配置缓存过期时间 + redisManager.setExpire(1800); //redisManager.setTimeout(1800); redisManager.setPassword(password); return redisManager; diff --git a/sparchetype/src/main/java/com/songpeng/sparchetype/system/config/shiro/SpLoginFormFilter.java b/sparchetype/src/main/java/com/songpeng/sparchetype/system/config/shiro/SpLoginFormFilter.java new file mode 100644 index 0000000..80464d9 --- /dev/null +++ b/sparchetype/src/main/java/com/songpeng/sparchetype/system/config/shiro/SpLoginFormFilter.java @@ -0,0 +1,52 @@ +package com.songpeng.sparchetype.system.config.shiro; + +import com.songpeng.sparchetype.common.util.HttpUtil; +import org.apache.shiro.web.filter.authc.FormAuthenticationFilter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author SongPeng + * @date 2020/3/6 + */ +public class SpLoginFormFilter extends FormAuthenticationFilter { + + private static final Logger log = LoggerFactory.getLogger(SpLoginFormFilter.class); + + @Override + protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception { + HttpServletRequest httpServletRequest = (HttpServletRequest) request; + HttpServletResponse httpServletResponse = (HttpServletResponse) response; + if (isLoginRequest(request, response)) { + if (isLoginSubmission(request, response)) { + if (log.isTraceEnabled()) { + log.trace("Login submission detected. Attempting to execute login."); + } + return executeLogin(request, response); + } else { + if (log.isTraceEnabled()) { + log.trace("Login page view."); + } + //allow them to see the login page + return true; + } + } else { + if (log.isTraceEnabled()) { + log.trace("Attempting to access a path which requires authentication. Forwarding to the " + + "Authentication url [" + getLoginUrl() + "]"); + } + //如果是Ajax请求,不跳转登录 + if (HttpUtil.isAjax(httpServletRequest)) { + httpServletResponse.setStatus(401); + } else { + saveRequestAndRedirectToLogin(request, response); + } + return false; + } + } +} diff --git a/sparchetype/src/main/resources/static/js/layuimodule/splayui/splayui.js b/sparchetype/src/main/resources/static/js/layuimodule/splayui/splayui.js index a51cc86..6eb06ef 100644 --- a/sparchetype/src/main/resources/static/js/layuimodule/splayui/splayui.js +++ b/sparchetype/src/main/resources/static/js/layuimodule/splayui/splayui.js @@ -76,7 +76,6 @@ layui.define(["element", "jquery"], function (exports) { * @param data */ this.initHome = function (data) { - console.log(data) sessionStorage.setItem('splayuiHomeHref', data.url); $('#splayuiHomeTabId').html(' ' + data.name + ''); $('#splayuiHomeTabId').attr('lay-id', data.url); diff --git a/sparchetype/src/main/resources/static/js/layuimodule/sptable/sptable.js b/sparchetype/src/main/resources/static/js/layuimodule/sptable/sptable.js index 97932c9..a8bfa85 100644 --- a/sparchetype/src/main/resources/static/js/layuimodule/sptable/sptable.js +++ b/sparchetype/src/main/resources/static/js/layuimodule/sptable/sptable.js @@ -16,6 +16,8 @@ layui.define(['table'], function (exports) { method: 'POST', limits: [10, 20, 50, 100], limit: 10, + page: true, + height: 'full-' + ($('#js-search-form').height() + 40), request: { pageName: 'current' , limitName: 'size' diff --git a/sparchetype/src/main/resources/static/js/spUtil.js b/sparchetype/src/main/resources/static/js/spUtil.js index 878d848..1b15fdb 100644 --- a/sparchetype/src/main/resources/static/js/spUtil.js +++ b/sparchetype/src/main/resources/static/js/spUtil.js @@ -25,7 +25,7 @@ spUtil.submitForm = function(options) { } }, error: function (e) { - layer.alert(e, { + layer.alert('系统错误,请联系管理员', { icon: 2 }); } @@ -66,8 +66,7 @@ spUtil.ajax = function (options) { options.success && options.success(data); } else { if (!options.errNoTip) { - tnComp.operationTip(data.msg, 'error'); - layer.alert('操作失败,请重试!', { + layer.alert(data.msg, { icon: 2 }); } @@ -75,6 +74,7 @@ spUtil.ajax = function (options) { }; // 失败回调 opt.error = function (jqXHR, textStatus, errorThrown) { + console.log(jqXHR); if (_this.sessionCheck(jqXHR, textStatus, errorThrown, options.sessionNoTip)) { return; } @@ -111,17 +111,31 @@ spUtil.ajax = function (options) { spUtil.sessionCheck = function (jqXHR, textStatus, errorThrown, sessionNoTip) { if (jqXHR.status === 401) { if (!sessionNoTip) { - tnComp.operationTipCallback('登录状态已失效,请重新登录!', 'error', function () { - top.location = '/'; + layer.alert('登录状态已失效,请重新登录!', { + icon: 2 + }, function (index) { + top.location = '/login-ui'; }); } else { // session超时,不提示直接跳转 - top.location = '/'; + top.location = '/login-ui'; } return true; } }; +/** + * 生成url + * @param url url + * @returns {string} + */ +spUtil.generateUrl = function (url, param) { + // 增加时间戳,解决IE浏览器ajax请求缓存问题 + var p = $.extend({}, {_t: new Date().getTime()}, param || {}); + var operator = /\?/gi.test(url) ? '&' : '?'; + return url + operator + $.param(p); +}; + /** * 将对象转为url路径字符串参数(编码之后的字符串) * @param param diff --git a/sparchetype/src/main/resources/templates/admin/blog/article/list.ftl b/sparchetype/src/main/resources/templates/admin/blog/article/list.ftl index a2b253e..4e85500 100644 --- a/sparchetype/src/main/resources/templates/admin/blog/article/list.ftl +++ b/sparchetype/src/main/resources/templates/admin/blog/article/list.ftl @@ -48,7 +48,6 @@
- + \ No newline at end of file diff --git a/sparchetype/src/main/resources/templates/admin/system/department/addOrUpdate.ftl b/sparchetype/src/main/resources/templates/admin/system/department/addOrUpdate.ftl index ac989c3..f380dc4 100644 --- a/sparchetype/src/main/resources/templates/admin/system/department/addOrUpdate.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/department/addOrUpdate.ftl @@ -8,7 +8,6 @@ <#include "${request.contextPath}/common/common.ftl"> -
diff --git a/sparchetype/src/main/resources/templates/admin/system/department/list.ftl b/sparchetype/src/main/resources/templates/admin/system/department/list.ftl index 5c7f9e1..3ac8d73 100644 --- a/sparchetype/src/main/resources/templates/admin/system/department/list.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/department/list.ftl @@ -63,8 +63,6 @@ // 表格及数据初始化 var tableIns = sptable.render({ - height: 'full-' + ($('#js-search-form').height() + 40), - page: true, url: '${request.contextPath}/admin/sys/department/page', cols: [ [{ diff --git a/sparchetype/src/main/resources/templates/admin/system/dict/addOrUpdate.ftl b/sparchetype/src/main/resources/templates/admin/system/dict/addOrUpdate.ftl index 1a469e4..b44d277 100644 --- a/sparchetype/src/main/resources/templates/admin/system/dict/addOrUpdate.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/dict/addOrUpdate.ftl @@ -8,83 +8,81 @@ <#include "${request.contextPath}/common/common.ftl"> - -
-
-
- -
- -
+
+ +
+ +
+
+
-
- -
- -
+
+ +
+
+
-
- -
- -
+
+ +
+
+
-
- -
- -
+
+ +
+
+
-
- -
- -
+
+ +
+
+
-
- -
- - -
+
+ +
+ +
+
-
- - - -
- -
- +
+ + + +
+ +
+ \ No newline at end of file diff --git a/sparchetype/src/main/resources/templates/admin/system/dict/list.ftl b/sparchetype/src/main/resources/templates/admin/system/dict/list.ftl index 96dbc59..684ae97 100644 --- a/sparchetype/src/main/resources/templates/admin/system/dict/list.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/dict/list.ftl @@ -3,115 +3,83 @@ 系统字典列表 - - + <#include "${request.contextPath}/common/common.ftl"> -
-
- + + - + \ No newline at end of file diff --git a/sparchetype/src/main/resources/templates/admin/system/menu/addOrUpdate.ftl b/sparchetype/src/main/resources/templates/admin/system/menu/addOrUpdate.ftl index 3897316..be6f294 100644 --- a/sparchetype/src/main/resources/templates/admin/system/menu/addOrUpdate.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/menu/addOrUpdate.ftl @@ -8,7 +8,6 @@ <#include "${request.contextPath}/common/common.ftl"> -
@@ -105,7 +104,6 @@
- + \ No newline at end of file diff --git a/sparchetype/src/main/resources/templates/admin/system/menu/list.ftl b/sparchetype/src/main/resources/templates/admin/system/menu/list.ftl index 78f7dd9..9505f22 100644 --- a/sparchetype/src/main/resources/templates/admin/system/menu/list.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/menu/list.ftl @@ -3,18 +3,10 @@ 系统菜单列表 - - + <#include "${request.contextPath}/common/common.ftl"> -
@@ -22,12 +14,12 @@
+
- + \ No newline at end of file diff --git a/sparchetype/src/main/resources/templates/admin/system/role/list.ftl b/sparchetype/src/main/resources/templates/admin/system/role/list.ftl index b63b630..8193c76 100644 --- a/sparchetype/src/main/resources/templates/admin/system/role/list.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/role/list.ftl @@ -3,10 +3,9 @@ 系统角色列表 - - + <#include "${request.contextPath}/common/common.ftl"> @@ -64,8 +63,6 @@ // 表格及数据初始化 var tableIns = sptable.render({ - height: 'full-' + ($('#js-search-form').height() + 40), - page: true, url: '${request.contextPath}/admin/sys/role/page', cols: [ [{ diff --git a/sparchetype/src/main/resources/templates/admin/system/tool/colorSelect.ftl b/sparchetype/src/main/resources/templates/admin/system/tool/colorSelect.ftl index 31e58f4..15477ad 100644 --- a/sparchetype/src/main/resources/templates/admin/system/tool/colorSelect.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/tool/colorSelect.ftl @@ -29,8 +29,6 @@ $('.paigusu').paigusu({ color: '#1926dc',//初始色 支持两种配置方案 }, function (event, obj) { - console.log(event); - console.log(obj); $(event).css('color', '#' + obj.hex) }); }); @@ -43,8 +41,6 @@ $('.test-select-color').paigusu({ color: '#1aa094',//初始色 支持两种配置方案 }, function (event, obj) { - console.log(event); - console.log(obj); $(event).css('background-color', '#' + obj.hex); $('input[name="test_color"]').val('#' + obj.hex); }); diff --git a/sparchetype/src/main/resources/templates/admin/system/tool/editor.ftl b/sparchetype/src/main/resources/templates/admin/system/tool/editor.ftl index 42ae2a8..631c647 100644 --- a/sparchetype/src/main/resources/templates/admin/system/tool/editor.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/tool/editor.ftl @@ -37,7 +37,6 @@ }, // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置 customInsert: function (insertImg, result, editor) { - console.log(result); if (result.code == 1) { var url = result.data.url; url.forEach(function (e) { @@ -76,7 +75,6 @@ }, // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置 customInsert: function (insertImg, result, editor) { - console.log(result); if (result.code == 1) { var url = result.data.url; url.forEach(function (e) { diff --git a/sparchetype/src/main/resources/templates/admin/system/tool/iconPicker.ftl b/sparchetype/src/main/resources/templates/admin/system/tool/iconPicker.ftl index bd620df..4c4db9e 100644 --- a/sparchetype/src/main/resources/templates/admin/system/tool/iconPicker.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/tool/iconPicker.ftl @@ -48,11 +48,9 @@ limit: 12, // 点击回调 click: function (data) { - console.log(data); }, // 渲染成功后的回调 success: function (d) { - console.log(d); } }); @@ -78,11 +76,9 @@ limit: 12, // 点击回调 click: function (data) { - console.log(data); }, // 渲染成功后的回调 success: function (d) { - console.log(d); } }); @@ -99,15 +95,12 @@ limit: 12, // 点击回调 click: function (data) { - console.log(data); }, // 渲染成功后的回调 success: function (d) { - console.log(d); } }); }); - \ No newline at end of file diff --git a/sparchetype/src/main/resources/templates/admin/system/user/addOrUpdate.ftl b/sparchetype/src/main/resources/templates/admin/system/user/addOrUpdate.ftl index 697a676..f1ff92c 100644 --- a/sparchetype/src/main/resources/templates/admin/system/user/addOrUpdate.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/user/addOrUpdate.ftl @@ -220,7 +220,6 @@ //监听提交 form.on('submit(js-submit-filter)', function (data) { - console.log(data.field) //return false; spUtil.submitForm({ diff --git a/sparchetype/src/main/resources/templates/admin/system/user/list.ftl b/sparchetype/src/main/resources/templates/admin/system/user/list.ftl index 9d54326..b27c6a9 100644 --- a/sparchetype/src/main/resources/templates/admin/system/user/list.ftl +++ b/sparchetype/src/main/resources/templates/admin/system/user/list.ftl @@ -63,8 +63,6 @@ // 表格及数据初始化 var tableIns = sptable.render({ - height: 'full-' + ($('#js-search-form').height() + 40), - page: true, url: '${request.contextPath}/admin/sys/user/page', cols: [ [{ diff --git a/sparchetype/src/main/resources/templates/client/blog/index.ftl b/sparchetype/src/main/resources/templates/client/blog/index.ftl index 4cc130e..bf82604 100644 --- a/sparchetype/src/main/resources/templates/client/blog/index.ftl +++ b/sparchetype/src/main/resources/templates/client/blog/index.ftl @@ -5,6 +5,14 @@ Title -

blog index

+

blog index

+ \ No newline at end of file diff --git a/sparchetype/src/main/resources/templates/error/403.ftl b/sparchetype/src/main/resources/templates/error/403.ftl index d4d0668..00c08da 100644 --- a/sparchetype/src/main/resources/templates/error/403.ftl +++ b/sparchetype/src/main/resources/templates/error/403.ftl @@ -2,7 +2,7 @@ - 欢迎页面-WeAdmin Frame型后台管理系统-WeAdmin 1.0 + 后台管理系统