数据库结构
CREATE TABLE `sys_menu` (
`id` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`parent_id` varchar(36) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '0' COMMENT '父菜单ID',
`menu_sort` int(11) DEFAULT 0 COMMENT '字典排序',
`menu_name` varchar(60) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '菜单名称',
`menu_icon` varchar(264) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '菜单图标',
`menu_url` varchar(264) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '菜单地址',
`create_time` datetime(0) DEFAULT NULL,
`update_time` datetime(0) DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `id`(`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '菜单表'
示例数据
一级数据
{
"total": 48,
"rows": [
{
"id": "256259227696369664",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541263427000,
"updateTime": 1541263427000,
"parentId": "0",
"menuSort": 1,
"menuName": "系统设置",
"menuIcon": "fa fa-fw fa-cog fa-lg",
"menuUrl": null
},
{
"id": "256261167226425344",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541263889000,
"updateTime": 1541263889000,
"parentId": "0",
"menuSort": 2,
"menuName": "统计报表",
"menuIcon": "fa fa-fw fa-line-chart fa-lg",
"menuUrl": null
},
{
"id": "256261202764763136",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541263897000,
"updateTime": 1541263897000,
"parentId": "0",
"menuSort": 3,
"menuName": "我的面板",
"menuIcon": "fa fa-fw fa-columns fa-lg",
"menuUrl": null
},
{
"id": "256261243550175232",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541263907000,
"updateTime": 1541263907000,
"parentId": "0",
"menuSort": 4,
"menuName": "系统监控",
"menuIcon": "fa fa-fw fa-video-camera fa-lg",
"menuUrl": null
},
{
"id": "256261285983948800",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541263917000,
"updateTime": 1541263917000,
"parentId": "0",
"menuSort": 5,
"menuName": "常用工具",
"menuIcon": "fa fa-fw fa-anchor fa-lg",
"menuUrl": null
},
{
"id": "256265204629901312",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541264852000,
"updateTime": 1541264852000,
"parentId": "0",
"menuSort": 6,
"menuName": "代码生成",
"menuIcon": "fa fa-fw fa-codepen fa-lg",
"menuUrl": null
},
{
"id": "256262059950477312",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541264102000,
"updateTime": 1541264102000,
"parentId": "256259227696369664",
"menuSort": 101,
"menuName": "菜单管理",
"menuIcon": null,
"menuUrl": "admin/menu/list"
},
{
"id": "256262311390613504",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541264162000,
"updateTime": 1541264162000,
"parentId": "256259227696369664",
"menuSort": 102,
"menuName": "用户管理",
"menuIcon": null,
"menuUrl": null
},
{
"id": "256262348275322880",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541264171000,
"updateTime": 1541264171000,
"parentId": "256259227696369664",
"menuSort": 103,
"menuName": "机构管理",
"menuIcon": null,
"menuUrl": null
},
{
"id": "256262388507086848",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541264180000,
"updateTime": 1541264180000,
"parentId": "256259227696369664",
"menuSort": 104,
"menuName": "角色管理",
"menuIcon": null,
"menuUrl": null
}
]
}
二级数据
{
"total": 6,
"rows": [
{
"id": "256262059950477312",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541264102000,
"updateTime": 1541264102000,
"parentId": "256259227696369664",
"menuSort": 101,
"menuName": "菜单管理",
"menuIcon": null,
"menuUrl": "/admin/menu/list"
},
{
"id": "256262311390613504",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541264162000,
"updateTime": 1541264162000,
"parentId": "256259227696369664",
"menuSort": 102,
"menuName": "用户管理",
"menuIcon": null,
"menuUrl": null
},
{
"id": "256262348275322880",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541264171000,
"updateTime": 1541264171000,
"parentId": "256259227696369664",
"menuSort": 103,
"menuName": "机构管理",
"menuIcon": null,
"menuUrl": null
},
{
"id": "256262388507086848",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541264180000,
"updateTime": 1541264180000,
"parentId": "256259227696369664",
"menuSort": 104,
"menuName": "角色管理",
"menuIcon": null,
"menuUrl": null
},
{
"id": "256262407406620672",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541264185000,
"updateTime": 1541264185000,
"parentId": "256259227696369664",
"menuSort": 105,
"menuName": "区域管理",
"menuIcon": null,
"menuUrl": null
},
{
"id": "256262435986608128",
"newRecord": true,
"idtype": "SNOWFLAKE",
"remarks": null,
"createTime": 1541264191000,
"updateTime": 1541264191000,
"parentId": "256259227696369664",
"menuSort": 106,
"menuName": "字典管理",
"menuIcon": null,
"menuUrl": null
}
]
}
后台代码
package com.laolang.bbs.modules.admin.web;
import com.github.pagehelper.PageInfo;
import com.laolang.bbs.common.json.BootstrapTableVo;
import com.laolang.bbs.core.web.BaseController;
import com.laolang.bbs.modules.admin.entity.SysMenuEntity;
import com.laolang.bbs.modules.admin.service.SysMenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
@RequestMapping("/admin/menu")
@Controller
public class SysMenuController extends BaseController {
@Autowired
private SysMenuService sysMenuService;
@RequestMapping(value = "list")
public String list() {
return "modules/admin/sysmenu/list";
}
@RequestMapping(value = "data", method = RequestMethod.GET, produces = "application/json")
public ResponseEntity<BootstrapTableVo> data(@RequestParam(value = "page", defaultValue = "1") Integer page,
@RequestParam(value = "size", defaultValue = "10") Integer size,
@RequestParam(value = "parentId", defaultValue = "0") String parentId) {
try {
PageInfo<SysMenuEntity> sysMenuEntityPageInfo = sysMenuService.list(page, size, parentId);
return ResponseEntity.ok(getBootstrapTableData(sysMenuEntityPageInfo));
} catch (Exception e) {
e.printStackTrace();
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(null);
}
}
}
前台代码
jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@include file="/WEB-INF/webpage/common/common.jsp" %>
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico" media="screen"/>
<link type="text/css" rel="stylesheet" href="<%=basePath%>/static/libs/bootstrap-3.3.7/css/bootstrap.min.css"/>
<link type="text/css" rel="stylesheet" href="<%=basePath%>/static/libs/font-awesome-4.7.0/css/font-awesome.min.css"/>
<link type="text/css" rel="stylesheet" href="<%=basePath%>/static/libs/bootstrap-table-1.12.1/bootstrap-table.min.css"/>
<title>菜单管理</title>
</head>
<body>
<table id="menu-table">
</table>
<script type="text/javascript" src="<%=basePath%>/static/libs/jquery-2.1.4/jquery.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/static/libs/bootstrap-3.3.7/js/bootstrap.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/static/libs/bootstrap-table-1.12.1/bootstrap-table.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/static/libs/bootstrap-table-1.12.1/locale/bootstrap-table-zh-CN.min.js"></script>
<script type="text/javascript" src="<%=basePath%>/static/common/js/km.js"></script>
<script type="text/javascript" src="<%=basePath%>/static/common/js/km-bootstrap-table-extend.js"></script>
<script type="text/javascript" src="<%=basePath%>/static/admin/js/sys/sysmenu/list.js"></script>
</body>
</html>
JS
list.js
'use strict';
$(function () {
var table = $('#menu-table');
var _table = table.bootstrapTable({
url: km.getBaseUrl() + '/admin/menu/data',
idField: "id",
method: 'get',
dataType: "json",
showRefresh: true,
showColumns: true,
showToggle: false,
checkboxHeader: true,
clickToSelect: false,
singleSelect: true,
striped: true,
cache: false,
sortOrder: "asc",
dataField: 'rows',
totalField: 'total',
pagination: true,
showPaginationSwitch: false,
sidePagination: 'server',
pageSize: 10,
pageList: [10, 25, 50, 100],
queryParamsType: 'limit',
queryParams: function (params) {
var searchParam = {};
searchParam.page = params.limit === undefined ? "1" : params.offset / params.limit + 1;
searchParam.size = params.limit === undefined ? -1 : params.limit;
return searchParam;
},
onClickRow: function (row, $element, field) {
console.log(row);
},
treeView: true,
columns: [{
field: 'ck',
checkbox: true
}, {
field: 'menuName',
title: '菜单名称',
sortable: true,
formatter: function (value, row, index) {
return table.kmBootstrapTableTreeFormatter({
treeColumn: 1,
parentIdField: 'parentId',
value: value,
row: row,
index: index,
}).kmBootstrapTableTreeFormatter('formatter');
}
}, {
field: 'menuSort',
title: '排序值',
sortable: true
}, {
field: 'menuIcon',
title: '图标',
sortable: true,
formatter: function operateFormatter(value, row, index) {
if (value && value.trim().length > 0) {
return '<span class="' + value + '">';
} else {
return undefined;
}
}
}, {
field: 'menuUrl',
title: '地址',
sortable: true
}, {
field: 'operate',
title: '操作',
align: 'center',
events: {
'click .btn-info': function (e, value, row, index) {
console.log('查看');
top.layui.use('layer', function () {
var layer = top.layui.layer;
layer.open({
title: '在线调试'
, content: '可以填写任意的layer代码'
});
});
},
'click .btn-success': function (e, value, row, index) {
console.log('修改');
},
'click .btn-danger': function (e, value, row, index) {
console.log('删除');
},
'click .btn-primary': function (e, value, row, index) {
console.log('添加下级菜单');
}
},
formatter: function (value, row, index) {
return [
'<a href="#" class="btn btn-info btn-xs" title="查看" ><i class="fa fa-search-plus"></i> 查看</a>',
'<a href="#" class="btn btn-success btn-xs" title="修改"><i class="fa fa-edit"></i> 修改</a>',
'<a href="#" class="btn btn-danger btn-xs" title="删除"><i class="fa fa-trash"></i> 删除</a>',
'<a href="#" class="btn btn-primary btn-xs" title="添加下级菜单"><i class="fa fa-plus"></i> 添加下级菜单</a>'
].join('');
}
}]
});
table.kmBootstrapTableFix();
});
km.js
'use strict';
String.prototype.endWith = function (s) {
if (null == s || "" === s || 0 === this.length || s.length > this.length) {
return false;
}
return s === this.substring(this.length - s.length);
};
String.prototype.startWith = function (s) {
if (null === s || "" === s || 0 === this.length || s.length > this.length) {
return false;
}
return s === this.substr(0, s.length);
};
var km = null;
$(function () {
var _km = function () {
return {
getBaseUrl() {
return document.location.protocol + '//' + document.location.host;
},
loadBootstrapTreeData: function (tableId, idField, parentIdField, treeColumn,
index, expanderExpandedClass, expanderCollapsedClass) {
var jq = $('#' + tableId);
var pid = jq.bootstrapTable('getOptions').data[index][idField];
var dataQuery = {};
dataQuery[parentIdField] = pid;
var tbody = jq.children('tbody');
var tr = tbody.children('tr').eq(index);
var td = tr.children('td').eq(treeColumn);
var span = td.children('span:last');
if (expanderExpandedClass ===
jq.children('tbody').children('tr').eq(index).children('td').eq(treeColumn).children('span:last').attr('class')) {
var level = td.children('span').length - 1;
var i = index + 1;
var ids = [];
while (true) {
var trSub = tbody.children('tr').eq(index + 1);
var subLevel = trSub.children('td').eq(treeColumn).children('span').length - 1;
if (subLevel > level) {
var data = jq.bootstrapTable('getData');
var row = data[i];
if (row) {
if (row[parentIdField] === data[index][parentIdField]) {
break;
}
ids.push(row[idField]);
jq.children('tbody').children('tr').eq(i).remove();
} else {
break;
}
} else {
break;
}
i++;
}
jq.children('tbody').children('tr').eq(index).children('td').eq(treeColumn).children('span:last')
.attr('class', expanderCollapsedClass);
jq.bootstrapTable('remove', {
field: idField,
values: ids
});
} else {
$.ajax({
url: jq.bootstrapTable('getOptions').url,
method: jq.bootstrapTable('getOptions').method,
cache: false,
data: dataQuery,
success: function (data) {
var rows = data.rows;
if (rows.length > 0) {
rows.forEach(function (item, i, array) {
jq.bootstrapTable('insertRow', {
index: i + index + 1,
row: item
});
});
} else {
span.hide();
}
}
});
}
event.stopPropagation();
}
};
};
km = _km();
});