Merge branch 'songpengmaster'

# Conflicts:
#	README.md
pull/1/head
wangziyangyang 2020-03-06 12:57:45 +08:00
commit 340e6ad05d
26 changed files with 325 additions and 297 deletions

View File

@ -1,7 +1,4 @@
# 上一套框架用的SSM 配置过于麻烦。 # sp-archetype
# 现在重新起了一套SpringBoot框架
## 每套框架我都给他起了一个名字这次的叫做黑科MES代表黑马、黑科技
## 界面展示 ## 界面展示
![](https://s2.ax1x.com/2020/03/06/3b89zD.gif) ![](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 * https://gitee.com/whvse/treetable-lay
* 图标库使用 * 图标库使用
* http://www.fontawesome.com.cn/faicons/ * http://www.fontawesome.com.cn/faicons
* 阿里矢量图标 * 发送 ajax 示例:[详情](./docs/ajax.md)
* https://www.iconfont.cn/
* 后端 * 后端
* Hutool 是一个小而全的Java工具类库通过静态方法封装降低相关API的学习成本提高工作效率使Java拥有函数式语言般的优雅让Java语言也可以“甜甜的”。 * Hutool 是一个小而全的Java工具类库通过静态方法封装降低相关API的学习成本提高工作效率使Java拥有函数式语言般的优雅让Java语言也可以“甜甜的”。
* 枚举 * 枚举
@ -58,12 +54,7 @@ springBoot+mybatis-plus+redis+shiro+hutool+layuimini+jenkins
* 请求参数 * 请求参数
* 每张表的分页查询参数严格按照一张表对应一个请求参数对象进行开发如系统用户分页查询参数com.songpeng.sparchetype.system.request.SysUserPageReq * 每张表的分页查询参数严格按照一张表对应一个请求参数对象进行开发如系统用户分页查询参数com.songpeng.sparchetype.system.request.SysUserPageReq
* *
#### 安装教程
1. xxxx
2. xxxx
3. xxxx

25
docs/ajax.md Normal file
View File

@ -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);
}
});
```

View File

@ -11,11 +11,11 @@ import java.util.HashMap;
public class Result<T> extends HashMap<String, Object> { public class Result<T> extends HashMap<String, Object> {
public static <T> Result<T> success() { public static <T> Result<T> success() {
return restResult(null, 0, null); return restResult(null, 0, "操作成功");
} }
public static <T> Result<T> success(T data) { public static <T> Result<T> success(T data) {
return restResult(data, 0, null); return restResult(data, 0, "操作成功");
} }
public static <T> Result<T> success(T data, String msg) { public static <T> Result<T> success(T data, String msg) {
@ -23,7 +23,7 @@ public class Result<T> extends HashMap<String, Object> {
} }
public static <T> Result<T> failure() { public static <T> Result<T> failure() {
return restResult(null, 1, null); return restResult(null, 1, "操作失败");
} }
public static <T> Result<T> failure(String msg) { public static <T> Result<T> failure(String msg) {
@ -31,7 +31,7 @@ public class Result<T> extends HashMap<String, Object> {
} }
public static <T> Result<T> failure(T data) { public static <T> Result<T> failure(T data) {
return restResult(data, 1, null); return restResult(data, 1, "操作失败");
} }
public static <T> Result<T> failure(T data, String msg) { public static <T> Result<T> failure(T data, String msg) {

View File

@ -1,7 +1,7 @@
package com.songpeng.sparchetype.common.advice; package com.songpeng.sparchetype.common.advice;
import com.songpeng.sparchetype.common.Result; 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.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -26,7 +26,7 @@ public class ExceptionAdvice {
@ResponseBody @ResponseBody
public Object handleAuthorizationException(AuthorizationException e, HttpServletRequest request) { public Object handleAuthorizationException(AuthorizationException e, HttpServletRequest request) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
if (HttpServletUtils.isAjax(request)) { if (HttpUtil.isAjax(request)) {
return Result.failure("未授权"); return Result.failure("未授权");
} }
return new ModelAndView("error/403"); return new ModelAndView("error/403");
@ -36,7 +36,7 @@ public class ExceptionAdvice {
@ResponseBody @ResponseBody
public Object handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) { public Object handleDuplicateKeyException(DuplicateKeyException e, HttpServletRequest request) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
if (HttpServletUtils.isAjax(request)) { if (HttpUtil.isAjax(request)) {
return Result.failure("数据重复"); return Result.failure("数据重复");
} }
return new ModelAndView("error/403"); return new ModelAndView("error/403");
@ -46,7 +46,7 @@ public class ExceptionAdvice {
@ResponseBody @ResponseBody
public Object handleException(Exception e, HttpServletRequest request) { public Object handleException(Exception e, HttpServletRequest request) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
if (HttpServletUtils.isAjax(request)) { if (HttpUtil.isAjax(request)) {
return Result.failure("服务器错误,请联系管理员"); return Result.failure("服务器错误,请联系管理员");
} }
return new ModelAndView("error/500"); return new ModelAndView("error/500");

View File

@ -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;
}
}

View File

@ -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;
}
}

View File

@ -15,9 +15,8 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import java.util.ArrayList; import javax.servlet.Filter;
import java.util.Collection; import java.util.*;
import java.util.LinkedHashMap;
/** /**
* Shiro * Shiro
@ -97,6 +96,12 @@ public class ShiroConfig {
filterChainDefinitionMap.put("/blog", "anon"); filterChainDefinitionMap.put("/blog", "anon");
filterChainDefinitionMap.put("/blog/open/**", "anon"); filterChainDefinitionMap.put("/blog/open/**", "anon");
filterChainDefinitionMap.put("/**", "authc"); filterChainDefinitionMap.put("/**", "authc");
Map<String, Filter> filters = new HashMap<>(2);
Filter loginFilter = new SpLoginFormFilter();
//此处使用自定义的拦截器,autho默认使用FormAuthenticationFilter拦截器
filters.put("authc", loginFilter);
shiroFilterFactoryBean.setFilters(filters);
// TODO 测试期间暂时打开 // TODO 测试期间暂时打开
//filterChainDefinitionMap.put("/**", "anon"); //filterChainDefinitionMap.put("/**", "anon");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
@ -142,7 +147,8 @@ public class ShiroConfig {
RedisManager redisManager = new RedisManager(); RedisManager redisManager = new RedisManager();
redisManager.setHost(host); redisManager.setHost(host);
redisManager.setPort(port); redisManager.setPort(port);
redisManager.setExpire(1800);// 配置缓存过期时间 // 配置缓存过期时间
redisManager.setExpire(1800);
//redisManager.setTimeout(1800); //redisManager.setTimeout(1800);
redisManager.setPassword(password); redisManager.setPassword(password);
return redisManager; return redisManager;

View File

@ -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;
}
}
}

View File

@ -76,7 +76,6 @@ layui.define(["element", "jquery"], function (exports) {
* @param data * @param data
*/ */
this.initHome = function (data) { this.initHome = function (data) {
console.log(data)
sessionStorage.setItem('splayuiHomeHref', data.url); sessionStorage.setItem('splayuiHomeHref', data.url);
$('#splayuiHomeTabId').html('<i class="' + data.icon + '"></i> <span>' + data.name + '</span>'); $('#splayuiHomeTabId').html('<i class="' + data.icon + '"></i> <span>' + data.name + '</span>');
$('#splayuiHomeTabId').attr('lay-id', data.url); $('#splayuiHomeTabId').attr('lay-id', data.url);

View File

@ -16,6 +16,8 @@ layui.define(['table'], function (exports) {
method: 'POST', method: 'POST',
limits: [10, 20, 50, 100], limits: [10, 20, 50, 100],
limit: 10, limit: 10,
page: true,
height: 'full-' + ($('#js-search-form').height() + 40),
request: { request: {
pageName: 'current' pageName: 'current'
, limitName: 'size' , limitName: 'size'

View File

@ -25,7 +25,7 @@ spUtil.submitForm = function(options) {
} }
}, },
error: function (e) { error: function (e) {
layer.alert(e, { layer.alert('系统错误,请联系管理员', {
icon: 2 icon: 2
}); });
} }
@ -66,8 +66,7 @@ spUtil.ajax = function (options) {
options.success && options.success(data); options.success && options.success(data);
} else { } else {
if (!options.errNoTip) { if (!options.errNoTip) {
tnComp.operationTip(data.msg, 'error'); layer.alert(data.msg, {
layer.alert('操作失败,请重试!', {
icon: 2 icon: 2
}); });
} }
@ -75,6 +74,7 @@ spUtil.ajax = function (options) {
}; };
// 失败回调 // 失败回调
opt.error = function (jqXHR, textStatus, errorThrown) { opt.error = function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR);
if (_this.sessionCheck(jqXHR, textStatus, errorThrown, options.sessionNoTip)) { if (_this.sessionCheck(jqXHR, textStatus, errorThrown, options.sessionNoTip)) {
return; return;
} }
@ -111,17 +111,31 @@ spUtil.ajax = function (options) {
spUtil.sessionCheck = function (jqXHR, textStatus, errorThrown, sessionNoTip) { spUtil.sessionCheck = function (jqXHR, textStatus, errorThrown, sessionNoTip) {
if (jqXHR.status === 401) { if (jqXHR.status === 401) {
if (!sessionNoTip) { if (!sessionNoTip) {
tnComp.operationTipCallback('登录状态已失效,请重新登录!', 'error', function () { layer.alert('登录状态已失效,请重新登录!', {
top.location = '/'; icon: 2
}, function (index) {
top.location = '/login-ui';
}); });
} else { } else {
// session超时不提示直接跳转 // session超时不提示直接跳转
top.location = '/'; top.location = '/login-ui';
} }
return true; 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路径字符串参数编码之后的字符串 * 将对象转为url路径字符串参数编码之后的字符串
* @param param * @param param

View File

@ -48,7 +48,6 @@
<!--数据表格--> <!--数据表格-->
<table class="layui-hide" id="articleList" lay-filter="table-filter"></table> <table class="layui-hide" id="articleList" lay-filter="table-filter"></table>
</div> </div>
</body>
<script type="text/html" id="toolbar-top"> <script type="text/html" id="toolbar-top">
<div class="layui-btn-container"> <div class="layui-btn-container">
<button class="layui-btn layui-btn-danger layui-btn-sm" lay-event="getCheckData"><i class="layui-icon">&#xe640;</i>批量删除</button> <button class="layui-btn layui-btn-danger layui-btn-sm" lay-event="getCheckData"><i class="layui-icon">&#xe640;</i>批量删除</button>
@ -233,4 +232,5 @@
}); });
} }
</script> </script>
</body>
</html> </html>

View File

@ -8,7 +8,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<#include "${request.contextPath}/common/common.ftl"> <#include "${request.contextPath}/common/common.ftl">
</head> </head>
<body> <body>
<div class="splayui-container"> <div class="splayui-container">
<div class="splayui-main"> <div class="splayui-main">

View File

@ -63,8 +63,6 @@
// 表格及数据初始化 // 表格及数据初始化
var tableIns = sptable.render({ var tableIns = sptable.render({
height: 'full-' + ($('#js-search-form').height() + 40),
page: true,
url: '${request.contextPath}/admin/sys/department/page', url: '${request.contextPath}/admin/sys/department/page',
cols: [ cols: [
[{ [{

View File

@ -8,83 +8,81 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<#include "${request.contextPath}/common/common.ftl"> <#include "${request.contextPath}/common/common.ftl">
</head> </head>
<body> <body>
<div class=""> <div class="">
<form class="layui-form"> <form class="layui-form">
<div class="layui-form-item"> <div class="layui-form-item">
<label for="js-name" class="layui-form-label sp-required">标签名 <label for="js-name" class="layui-form-label sp-required">标签名
</label> </label>
<div class="layui-input-inline"> <div class="layui-input-inline">
<input type="text" id="js-name" name="name" lay-verify="required" autocomplete="off" class="layui-input" value="${dict.name}"> <input type="text" id="js-name" name="name" lay-verify="required" autocomplete="off" class="layui-input" value="${dict.name}">
</div>
</div> </div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label for="js-value" class="layui-form-label sp-required">标签值 <label for="js-value" class="layui-form-label sp-required">标签值
</label> </label>
<div class="layui-input-inline"> <div class="layui-input-inline">
<input type="text" id="js-value" name="value" lay-verify="required" autocomplete="off" class="layui-input" value="${dict.value}"> <input type="text" id="js-value" name="value" lay-verify="required" autocomplete="off" class="layui-input" value="${dict.value}">
</div>
</div> </div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label for="js-type" class="layui-form-label sp-required">类别</label> <label for="js-type" class="layui-form-label sp-required">类别</label>
<div class="layui-input-inline"> <div class="layui-input-inline">
<input type="text" id="js-type" name="type" lay-verify="required" autocomplete="off" class="layui-input" value="${dict.type}"> <input type="text" id="js-type" name="type" lay-verify="required" autocomplete="off" class="layui-input" value="${dict.type}">
</div>
</div> </div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label for="js-descr" class="layui-form-label sp-required">描述 <label for="js-descr" class="layui-form-label sp-required">描述
</label> </label>
<div class="layui-input-inline"> <div class="layui-input-inline">
<input type="text" id="js-descr" name="descr" lay-verify="required" autocomplete="off" class="layui-input" value="${dict.descr}"> <input type="text" id="js-descr" name="descr" lay-verify="required" autocomplete="off" class="layui-input" value="${dict.descr}">
</div>
</div> </div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label for="js-sort-num" class="layui-form-label sp-required">排序 <label for="js-sort-num" class="layui-form-label sp-required">排序
</label> </label>
<div class="layui-input-inline"> <div class="layui-input-inline">
<input type="text" id="js-sort-num" name="sortNum" lay-verify="required|number" autocomplete="off" class="layui-input" value="${dict.sortNum}"> <input type="text" id="js-sort-num" name="sortNum" lay-verify="required|number" autocomplete="off" class="layui-input" value="${dict.sortNum}">
</div>
</div> </div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<label for="js-deleted" class="layui-form-label sp-required"><span class="sp-red">*</span>状态</label> <label for="js-deleted" class="layui-form-label sp-required"><span class="sp-red">*</span>状态</label>
<div class="layui-input-block" id="js-deleted"> <div class="layui-input-block" id="js-deleted">
<input type="radio" name="deleted" value="0" title="正常" checked> <input type="radio" name="deleted" value="0" title="正常" checked>
<input type="radio" name="deleted" value="1" title="已删除"> <input type="radio" name="deleted" value="1" title="已删除">
</div>
</div> </div>
</div>
<div class="layui-form-item"> <div class="layui-form-item">
<input type="hidden" name="id" id="js-id" value="" /> <input type="hidden" name="id" id="js-id" value=""/>
<label for="js-add-btn" class="layui-form-label sp-required"></label> <label for="js-add-btn" class="layui-form-label sp-required"></label>
<button id="js-add-btn" class="layui-btn" lay-filter="add" lay-submit="">确定</button> <button id="js-add-btn" class="layui-btn" lay-filter="add" lay-submit="">确定</button>
</div> </div>
</form> </form>
</div> </div>
</body>
<script> <script>
layui.use(['form', 'util', 'layer'], function() { layui.use(['form', 'util', 'layer'], function () {
var form = layui.form, var form = layui.form,
util = layui.util, util = layui.util,
layer = layui.layer; layer = layui.layer;
//失去焦点时判断值为空不验证,一旦填写必须验证 //失去焦点时判断值为空不验证,一旦填写必须验证
$('input[name="email"]').blur(function(){ $('input[name="email"]').blur(function () {
//这里是失去焦点时的事件 //这里是失去焦点时的事件
if($('input[name="email"]').val()){ if ($('input[name="email"]').val()) {
$('input[name="email"]').attr('lay-verify','email'); $('input[name="email"]').attr('lay-verify', 'email');
}else{ } else {
$('input[name="email"]').removeAttr('lay-verify'); $('input[name="email"]').removeAttr('lay-verify');
} }
}); });
//监听提交 //监听提交
form.on('submit(add)', function(data) { form.on('submit(add)', function (data) {
$.ajax({ $.ajax({
type: "POST", type: "POST",
//请求的媒体类型 //请求的媒体类型
@ -92,7 +90,7 @@
url: "${request.contextPath}/admin/sys/dict/add-or-update", url: "${request.contextPath}/admin/sys/dict/add-or-update",
//data: JSON.stringify(data), //data: JSON.stringify(data),
data: data.field, data: data.field,
success: function(result) { success: function (result) {
if (result.code === 0) { if (result.code === 0) {
//获取提交成功的时间 //获取提交成功的时间
var time = new Date(); var time = new Date();
@ -105,13 +103,13 @@
parent.layer.close(index); parent.layer.close(index);
} else { } else {
layer.alert(result.msg, { layer.alert(result.msg, {
icon: 2 icon: 2
}) })
} }
}, },
error: function(e){ error: function (e) {
layer.alert(e, { layer.alert(e, {
icon: 2 icon: 2
}) })
} }
}); });
@ -120,4 +118,5 @@
}); });
}); });
</script> </script>
</body>
</html> </html>

View File

@ -3,115 +3,83 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>系统字典列表</title> <title>系统字典列表</title>
<meta name="Description" content="基于layUI数据表格操作"/>
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<#include "${request.contextPath}/common/common.ftl"> <#include "${request.contextPath}/common/common.ftl">
</head> </head>
<body> <body>
<div class=""> <div class="splayui-container">
<div class="layui-row"> <div class="splayui-main">
<form class="layui-form layui-col-md12 we-search" lay-filter="search-form-filter"> <!--查询参数-->
<div class="layui-input-inline"> <form id="js-search-form" class="layui-form" lay-filter="js-q-form-filter">
<select name="cateid"> <div class="layui-form-item">
<option>请选择分类</option> <div class="layui-inline">
<option>文章</option> <label class="layui-form-label">姓名</label>
<option>会员</option> <div class="layui-input-inline">
<option>权限</option> <input type="text" name="nameLike" autocomplete="off" class="layui-input">
</select> </div>
</div> </div>
<div class="layui-inline"> <div class="layui-inline">
<input class="layui-input" placeholder="开始日" name="start" id="start"> <label class="layui-form-label">用户名</label>
<div class="layui-input-inline">
<input type="text" name="usernameLike" autocomplete="off" class="layui-input">
</div>
</div> </div>
<div class="layui-inline"> <div class="layui-inline">
<input class="layui-input" placeholder="截止日" name="end" id="end"> <a class="layui-btn" lay-submit lay-filter="js-search-filter"><i class="layui-icon layui-icon-search layuiadmin-button-btn"></i></a>
</div> </div>
<div class="layui-inline"> </div>
<input type="text" name="keyword" placeholder="请输入关键字" autocomplete="off" class="layui-input"> </form>
</div>
<button class="layui-btn" lay-submit lay-filter="search-form-btn-filter"><i class="layui-icon">&#xe615;</i></button> <!--表格-->
</form> <table class="layui-hide" id="js-record-table" lay-filter="js-record-table-filter"></table>
</div> </div>
<!--数据表格--> </div>
<table class="layui-hide" id="record-table" lay-filter="table-filter"></table> <!--表格头操作模板-->
<script type="text/html" id="js-record-table-toolbar-top">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-danger layui-btn-sm" lay-event="deleteBatch"><i class="layui-icon">&#xe640;</i>批量删除</button>
<@shiro.hasPermission name="user:add">
<button class="layui-btn layui-btn-sm" lay-event="add"><i class="layui-icon">&#xe61f;</i>添加</button>
</@shiro.hasPermission>
</div> </div>
</body>
<script type="text/html" id="toolbar-top">
<div class="layui-btn-container">
<button class="layui-btn layui-btn-danger layui-btn-sm" lay-event="getCheckData"><i class="layui-icon">&#xe640;</i>批量删除</button>
<@shiro.hasPermission name="nemu:add">
<button class="layui-btn layui-btn-sm" onclick="WeAdminShow('添加字典','${request.contextPath}/admin/sys/dict/add-or-update-ui',600,400)">
<i class="layui-icon">&#xe61f;</i>添加
</button>
</@shiro.hasPermission>
</div>
</script> </script>
<script type="text/html" id="operateTpl"> <!--行操作模板-->
<a title="编辑" onclick="WeAdminEdit('编辑','${request.contextPath}/admin/sys/dict/add-or-update-ui', '{{ d.id }}', 600, 400)" href="javascript:;"> <script type="text/html" id="js-record-table-toolbar-right">
<i class="layui-icon">&#xe642;</i> <a class="layui-btn layui-btn-xs" lay-event="edit"><i class="layui-icon layui-icon-edit"></i>编辑</a>
</a> <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="delete"><i class="layui-icon layui-icon-delete"></i>删除</a>
<a title="查看" onclick="WeAdminShow('查看字典','./show.html',600,400)" href="javascript:;">
<i class="layui-icon">&#xe63c;</i>
</a>
<a title="删除" onclick="member_del(this,'要删除的id')" href="javascript:;">
<i class="layui-icon">&#xe640;</i>
</a>
</script> </script>
<script type="text/javascript"> <script type="text/javascript">
layui.use(['table', 'form', 'laydate'], function() {
var table = layui.table,
form = layui.form,
laydate = layui.laydate;
laydate.render({ layui.use(['form', 'table', 'splayer', 'sptable'], function () {
elem: '#start' var form = layui.form,
}); table = layui.table,
laydate.render({ splayer = layui.splayer,
elem: '#end' sptable = layui.sptable;
});
var tableIns = table.render({ // 表格及数据初始化
elem: '#record-table', var tableIns = sptable.render({
cellMinWidth: 80,
toolbar: '#toolbar-top',
method: 'POST',
event: true,
page: true,
url: '${request.contextPath}/admin/sys/dict/page', url: '${request.contextPath}/admin/sys/dict/page',
request: {
pageName: 'current' //页码的参数名称默认page
,limitName: 'size' //每页数据量的参数名默认limit
},
parseData: function(res){ //res 即为原始返回的数据
return {
"code": res.code, //解析接口状态
"msg": res.msg, //解析提示文本
"count": res.data ? res.data.total : 0, //解析数据长度
"data": res.data ? res.data.records : [] //解析数据列表
};
},
cols: [ cols: [
[{ [{
type: 'checkbox' type: 'checkbox'
}, { }, {
field: 'name', title: '标签名' field: 'name', title: '标签名'
}, { }, {
field: 'value',title: '标签值' field: 'value', title: '标签值'
}, { }, {
field: 'type',title: '类别' field: 'type', title: '类别'
}, { }, {
field: 'descr',title: '描述' field: 'descr', title: '描述'
}, { }, {
field: 'deleted',title: '状态' field: 'deleted', title: '状态'
}, { }, {
field: 'operate',title: '操作', toolbar: '#operateTpl', unresize: true field: 'operate', title: '操作', toolbar: '#operateTpl', unresize: true
}] }]
], ],
done: function(res, curr, count){ done: function (res, curr, count) {
//如果是异步请求数据方式res即为你接口返回的信息。
//如果是直接赋值的方式res即为{data: [], count: 99} data为当前页数据、count为数据总长度
} }
}); });
@ -119,86 +87,81 @@
* 数据表格中form表单元素是动态插入,所以需要更新渲染下 * 数据表格中form表单元素是动态插入,所以需要更新渲染下
* http://www.layui.com/doc/modules/form.html#render * http://www.layui.com/doc/modules/form.html#render
*/ */
$(function(){ $(function () {
form.render(); form.render();
}); });
form.on('submit(search-form-btn-filter)', function(data){ /**
* 搜索按钮事件
*/
form.on('submit(js-search-filter)', function (data) {
tableIns.reload({ tableIns.reload({
// 设定异步数据接口的额外参数,任意设
where: data.field, where: data.field,
page: { page: {
curr: 1 //重新从第 1 页开始 // 重新从第 1 页开始
curr: 1
} }
}); });
// 阻止表单跳转。如果需要表单跳转,去掉这段即可。 // 阻止表单跳转。如果需要表单跳转,去掉这段即可。
return false; return false;
}); });
//头工具栏事件 /**
table.on('toolbar(table-filter)', function(obj){ * 头工具栏事件
*/
table.on('toolbar(js-record-table-filter)', function (obj) {
var checkStatus = table.checkStatus(obj.config.id); var checkStatus = table.checkStatus(obj.config.id);
switch(obj.event){
case 'getCheckData':
var checkStatus = table.checkStatus('record-table'),
data = checkStatus.data;
if(data.length > 0) {
layer.confirm('确认要删除吗?' + JSON.stringify(data), function(index) {
layer.msg('删除成功', {
icon: 1
});
//找到所有被选中的,发异步进行删除
$(".layui-table-body .layui-form-checked").parents('tr').remove();
});
} else {
layer.msg("请先选择需要删除的文章!");
}
break;
case 'recommend':
var checkStatus = table.checkStatus('record-table'),
data = checkStatus.data;
if(data.length > 0) {
layer.msg("您点击了推荐操作");
for(var i = 0; i < data.length; i++) {
data[i].recommend = "checked";
form.render();
}
} else { // 批量删除
layer.msg("请先选择"); if (obj.event === 'deleteBatch') {
} var checkStatus = table.checkStatus('js-record-table'),
break; data = checkStatus.data;
case 'top': if (data.length > 0) {
layer.msg("您点击了置顶操作"); layer.confirm('确认要删除吗?', function (index) {
break;
case 'review':
layer.msg("您点击了审核操作");
break;
};
});
/*用户-删除*/ });
window.member_del = function(obj, id) { } else {
layer.confirm('确认要删除吗?', function(index) { layer.msg("请先选择需要删除的数据!");
//发异步删除数据 }
$(obj).parents("tr").remove(); }
layer.msg('已删除!', {
icon: 1, // 添加
time: 1000 if (obj.event === 'add') {
var index = splayer.open({
title: '添加',
area: ['90%', '90%'],
content: '${request.contextPath}/admin/sys/dict/add-or-update-ui'
}); });
}); }
}
});
function delAll(argument) {
var data = tableCheck.getData();
layer.confirm('确认要删除吗?' + data, function(index) {
//捉到所有被选中的,发异步进行删除
layer.msg('删除成功', {
icon: 1
});
$(".layui-form-checked").not('.header').parents('tr').remove();
}); });
}
/**
* 监听行工具事件
*/
table.on('tool(js-record-table-filter)', function (obj) {
var data = obj.data;
// 编辑
if (obj.event === 'edit') {
splayer.open({
title: '编辑',
area: ['90%', '90%'],
// 请求url参数
spWhere: {id: data.id},
content: '${request.contextPath}/admin/sys/dict/add-or-update-ui'
});
}
// 删除
if (obj.event === 'delete') {
layer.confirm('确认要删除吗?', function (index) {
obj.del();
layer.close(index);
});
}
});
});
</script> </script>
</body>
</html> </html>

View File

@ -8,7 +8,6 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">
<#include "${request.contextPath}/common/common.ftl"> <#include "${request.contextPath}/common/common.ftl">
</head> </head>
<body> <body>
<div class="splayui-container"> <div class="splayui-container">
<div class="splayui-main"> <div class="splayui-main">
@ -105,7 +104,6 @@
</form> </form>
</div> </div>
</div> </div>
</body>
<script> <script>
layui.use(['form', 'util', 'layer'], function () { layui.use(['form', 'util', 'layer'], function () {
var form = layui.form, var form = layui.form,
@ -123,4 +121,5 @@
}); });
}); });
</script> </script>
</body>
</html> </html>

View File

@ -3,18 +3,10 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>系统菜单列表</title> <title>系统菜单列表</title>
<meta name="Description" content="基于layUI数据表格操作"/>
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<#include "${request.contextPath}/common/common.ftl"> <#include "${request.contextPath}/common/common.ftl">
<style>
.layui-btn:not(.layui-btn-lg ):not(.layui-btn-sm):not(.layui-btn-xs) {
height: 34px;
line-height: 34px;
padding: 0 8px;
}
</style>
</head> </head>
<body> <body>
<div class="splayui-container"> <div class="splayui-container">
@ -22,12 +14,12 @@
<div> <div>
<div class="layui-btn-group"> <div class="layui-btn-group">
<button class="layui-btn" id="js-expand-fold-all">全部展开/折叠</button> <button class="layui-btn" id="js-expand-fold-all">全部展开/折叠</button>
<button class="layui-btn" id="testtt">testtt</button>
</div> </div>
<table id="js-record-table" class="layui-table" lay-filter="js-record-table-filter"></table> <table id="js-record-table" class="layui-table" lay-filter="js-record-table-filter"></table>
</div> </div>
</div> </div>
</div> </div>
</body>
<!-- 表格操作列 --> <!-- 表格操作列 -->
<script type="text/html" id="js-record-table-bar"> <script type="text/html" id="js-record-table-bar">
<a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="edit">修改</a> <a class="layui-btn layui-btn-primary layui-btn-xs" lay-event="edit">修改</a>
@ -46,9 +38,6 @@
treeTable = layui.treeTable, treeTable = layui.treeTable,
splayer = layui.splayer; splayer = layui.splayer;
treeData = [];
// TODO 封装ajax
// 渲染表格 // 渲染表格
var insTb = treeTable.render({ var insTb = treeTable.render({
elem: '#js-record-table', elem: '#js-record-table',
@ -60,9 +49,11 @@
cols: [ cols: [
{type: 'numbers'}, {type: 'numbers'},
{field: 'name', title: '名称', width: 160}, {field: 'name', title: '名称', width: 160},
{field: 'type', title: '类型', width: 160, templet: function (d) { {
return d.icon ? {'0': '目录','1': '菜单','2': '按钮'}[d.type] : ''; field: 'type', title: '类型', width: 160, templet: function (d) {
}}, return d.icon ? {'0': '目录', '1': '菜单', '2': '按钮'}[d.type] : '';
}
},
{ {
field: 'icon', title: '图标', width: 160, templet: function (d) { field: 'icon', title: '图标', width: 160, templet: function (d) {
return d.icon ? '<i class="' + d.icon + ' fa-lg"></i>' : ''; return d.icon ? '<i class="' + d.icon + ' fa-lg"></i>' : '';
@ -144,4 +135,5 @@
}); });
}); });
</script> </script>
</body>
</html> </html>

View File

@ -3,10 +3,9 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>系统角色列表</title> <title>系统角色列表</title>
<meta name="Description" content="基于layUI数据表格操作"/>
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<#include "${request.contextPath}/common/common.ftl"> <#include "${request.contextPath}/common/common.ftl">
</head> </head>
<body> <body>
@ -64,8 +63,6 @@
// 表格及数据初始化 // 表格及数据初始化
var tableIns = sptable.render({ var tableIns = sptable.render({
height: 'full-' + ($('#js-search-form').height() + 40),
page: true,
url: '${request.contextPath}/admin/sys/role/page', url: '${request.contextPath}/admin/sys/role/page',
cols: [ cols: [
[{ [{

View File

@ -29,8 +29,6 @@
$('.paigusu').paigusu({ $('.paigusu').paigusu({
color: '#1926dc',//初始色 支持两种配置方案 color: '#1926dc',//初始色 支持两种配置方案
}, function (event, obj) { }, function (event, obj) {
console.log(event);
console.log(obj);
$(event).css('color', '#' + obj.hex) $(event).css('color', '#' + obj.hex)
}); });
}); });
@ -43,8 +41,6 @@
$('.test-select-color').paigusu({ $('.test-select-color').paigusu({
color: '#1aa094',//初始色 支持两种配置方案 color: '#1aa094',//初始色 支持两种配置方案
}, function (event, obj) { }, function (event, obj) {
console.log(event);
console.log(obj);
$(event).css('background-color', '#' + obj.hex); $(event).css('background-color', '#' + obj.hex);
$('input[name="test_color"]').val('#' + obj.hex); $('input[name="test_color"]').val('#' + obj.hex);
}); });

View File

@ -37,7 +37,6 @@
}, },
// 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置 // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
customInsert: function (insertImg, result, editor) { customInsert: function (insertImg, result, editor) {
console.log(result);
if (result.code == 1) { if (result.code == 1) {
var url = result.data.url; var url = result.data.url;
url.forEach(function (e) { url.forEach(function (e) {
@ -76,7 +75,6 @@
}, },
// 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置 // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置
customInsert: function (insertImg, result, editor) { customInsert: function (insertImg, result, editor) {
console.log(result);
if (result.code == 1) { if (result.code == 1) {
var url = result.data.url; var url = result.data.url;
url.forEach(function (e) { url.forEach(function (e) {

View File

@ -48,11 +48,9 @@
limit: 12, limit: 12,
// 点击回调 // 点击回调
click: function (data) { click: function (data) {
console.log(data);
}, },
// 渲染成功后的回调 // 渲染成功后的回调
success: function (d) { success: function (d) {
console.log(d);
} }
}); });
</pre> </pre>
@ -78,11 +76,9 @@
limit: 12, limit: 12,
// 点击回调 // 点击回调
click: function (data) { click: function (data) {
console.log(data);
}, },
// 渲染成功后的回调 // 渲染成功后的回调
success: function (d) { success: function (d) {
console.log(d);
} }
}); });
@ -99,15 +95,12 @@
limit: 12, limit: 12,
// 点击回调 // 点击回调
click: function (data) { click: function (data) {
console.log(data);
}, },
// 渲染成功后的回调 // 渲染成功后的回调
success: function (d) { success: function (d) {
console.log(d);
} }
}); });
}); });
</script> </script>
</body> </body>
</html> </html>

View File

@ -220,7 +220,6 @@
//监听提交 //监听提交
form.on('submit(js-submit-filter)', function (data) { form.on('submit(js-submit-filter)', function (data) {
console.log(data.field)
//return false; //return false;
spUtil.submitForm({ spUtil.submitForm({

View File

@ -63,8 +63,6 @@
// 表格及数据初始化 // 表格及数据初始化
var tableIns = sptable.render({ var tableIns = sptable.render({
height: 'full-' + ($('#js-search-form').height() + 40),
page: true,
url: '${request.contextPath}/admin/sys/user/page', url: '${request.contextPath}/admin/sys/user/page',
cols: [ cols: [
[{ [{

View File

@ -5,6 +5,14 @@
<title>Title</title> <title>Title</title>
</head> </head>
<body> <body>
<h1>blog index</h1> <h1>blog index</h1>
<script>
layui.use(['element', 'layer', 'splayui'], function () {
var element = layui.element,
layer = layui.layer,
splayui = layui.splayui;
});
</script>
</body> </body>
</html> </html>

View File

@ -2,7 +2,7 @@
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>欢迎页面-WeAdmin Frame型后台管理系统-WeAdmin 1.0</title> <title>后台管理系统</title>
<meta name="renderer" content="webkit"> <meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0"> <meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=0">