#### 代码示例:
#### 菜单列表前端:
/**
* @Description 菜单列表
* @Author https://gitee.com/qlslylq/UnityDesign
* @link https://gitee.com/qlslylq/FlutterDesign
* @link https://gitee.com/qlslylq/AndroidDesign
**/
$(document).ready(function () {
initElement();
initData();
initListener();
});
function initElement() {
initToolBarEle();
initGridEle();
}
function initData() {
}
function initListener() {
}
function onClick(ele) {
if (ele.id == "icon-add") {
openAddDialog();
} else if (ele.id == "icon-add-btn") {
openAddBtnDialog();
} else if (ele.id == "icon-edit") {
openEditDialog();
} else if (ele.id == "icon-remove") {
openDeleteDialog();
} else if (ele.id == "icon-reload") {
queryForAll();
} else if (ele.id == "icon-search") {
queryForSearchText();
} else if ($(ele).attr("iconCls") == "icon-add") {
openIconSelectDialog(ele);
} else if (ele.id == "img") {
selectElement(ele, "img-selected");
}
}
/**
* 初始化工具栏按钮
*/
function initToolBarEle() {
var roleThirdMenus = JSON.parse(sessionStorage.getItem('roleThirdMenus'));
for (var i = 0; i < roleThirdMenus.length; i++) {
var btnHtml = ' ' + roleThirdMenus[i].name + ' ';
$(".wu-toolbar-button").append(btnHtml);
$(".wu-toolbar-button [data-index=" + i + "]").linkbutton({
iconCls: roleThirdMenus[i].icon
});
}
}
/**
* 填充菜单数据
*/
function initGridEle() {
$('#grid').treegrid({
loadMsg: false,//网络层自定义控制loading显隐
url: '../menu/getList',
queryParams: {},
idField: 'id',
treeField: 'name',//从哪个Field开始展开树-->首个Field
// loadFilter: filterDataForPager,
loadFilter: function (data) {
return data.data;
},
rownumbers: false,
singleSelect: true,
pageNumber: 1,
pageSize: 100,
pageList: [10, 20, 50, 80, 100],
pagePosition: 'bottom',
pagination: true,
multiSort: true,
fitColumns: true,
fit: true,
columns: [
[{
checkbox: true
}, {
field: 'id',
title: 'ID',
width: 130,
sortable: true,
hidden: "true"
}, {
field: 'name',
title: '名称',
width: 130,
sortable: false
}, {
field: 'parent',
title: '父级菜单',
width: 130,
sortable: false,
formatter: function (value, row, index) {
if (row.parent) {
return row.parent.name;
} else {
return null;
}
}
}, {
field: 'icon',
title: '图标',
width: 130,
sortable: false,
formatter(value, row, index) {
return ele + value;
}
}, {
field: 'link',
title: '链接',
width: 130,
sortable: false
},]
], onLoadSuccess: function () {//数据加载成功
$(this).treegrid('clearSelections');//选中即使刷新也会有选中缓存
}
});
}
/**
* 打开添加窗口
*/
function openAddDialog() {
showCustomDialog($("#dialog-add"), "添加菜单", false, function () {
if (add()) {
$("#dialog-add").dialog('close');
}
});
}
/**
* 打开添加按钮窗口
*/
function openAddBtnDialog() {
var item = $('#grid').treegrid('getSelected');
if (item == null) {
$.messager.warning("请先选择要绑定到的二级菜单~");
return;
}
if (item._parentId == 0 || item.parent._parentId != 0) {
$.messager.warning("请选择二级菜单~");
return;
}
showCustomDialog($("#dialog-add-btn"), "添加按钮", false, function () {
if (addBtn()) {
$("#dialog-add-btn").dialog('close');
}
}, function () {
$("#form-add-btn .easyui-combobox").combobox('setValue', item.id);
$("#form-add-btn .easyui-combobox").combobox('setText', item.name);
});
}
/**
* 打开修改一二三级菜单窗口
*/
function openEditDialog() {
var item = $('#grid').treegrid('getSelected');
if (item == null) {
$.messager.warning("请选择要修改的菜单项~");
return;
}
if (item._parentId == 0 || item.parent._parentId == 0) {//一二级菜单
showCustomDialog($("#dialog-edit"), "编辑菜单", false, function () {
if (edit()) {
$("#dialog-edit").dialog('close');
}
}, function () {
$("#form-edit input[type='hidden']").val(item.id);
$("#form-edit .easyui-combobox").combobox('setValue', item._parentId);
$("#form-edit .easyui-combobox").combobox('setText', item.parent ? item.parent.name : "顶级菜单");
$("#form-edit input[name='name']").val(item.name);
$("#form-edit input[name='icon']").val(item.icon);
$("#form-edit input[name='link']").val(item.link);
});
} else {//三级菜单
showCustomDialog($("#dialog-edit-btn"), "编辑按钮", false, function () {
if (editBtn()) {
$("#dialog-edit-btn").dialog('close');
}
}, function () {
$("#form-edit-btn input[type='hidden']").val(item.id);
$("#form-edit-btn .easyui-combobox").combobox('setValue', item._parentId);
$("#form-edit-btn .easyui-combobox").combobox('setText', item.parent.name);
$("#form-edit-btn input[name='name']").val(item.name);
$("#form-edit-btn input[name='icon']").val(item.icon);
$("#form-edit-btn input[name='link']").val(item.link);
});
}
}
/**
* 打开图标选择窗口
*/
function openIconSelectDialog(ele) {
if ($("#table").children().length == 0) {
$.post({
url: "../menu/getIconList",
async: false,
success: function (data) {
var list_icon = data.data;
var tbody = $("#table");
var content = '';
tbody.empty();
$.each(list_icon, function (i, item) {
var fileName = item.toString();
var iconName = fileName.substring(0, fileName.indexOf("."));
var iconClassName = "icon-" + iconName.replace(/_/g, "-");
var tr_start = '
';var td = '
' + icon + '';var tr_end = '
';var cols = 10;
if (i % cols == 0) {
content += tr_start;
}
content += td;
if ((i + 1) % cols == 0 || i == list_icon.length - 1) {
content += tr_end;
}
});
tbody.append(content);
}
});
}
showCustomDialog($("#dialog-icon-select"), "选择图标", true, function () {
var imgClass = $(".img-selected").prop('class').split(" ")[0];
$("input[name='icon']", getParentUntil(ele, "form")).val(imgClass);
}, function () {
$(".img-selected").removeClass("img-selected");
});
}
/**
* 打开删除窗口
*/
function openDeleteDialog() {
var item = $('#grid').treegrid('getSelected');
if (item == null) {
$.messager.warning("请选择要删除的菜单项~");
return;
}
showDialog("删除菜单", "确定删除?", function () {
remove(item);
});
}
/**
* 添加记录
*/
function add() {
//校验表单
var validate = validateForm($("#form-add"));
if (!validate) {
$.messager.warning("请正确填写相关信息~");
return false;
}
//校验combobox
var validateParentId = validateCombobox($("#form-add .easyui-combobox"), "父级菜单无效~");
if (!validateParentId) {
return false;
}
//校验icon
var iconClass = $("#form-add input[name='icon']").val();
var validateIcon = iconClass.length > 0 ? $("." + iconClass).length > 0 : false;
if (!validateIcon) {
$.messager.warning("图标无效~");
return false;
}
var data = $("#form-add").serialize(); //www-form格式:k1=v1&k2=v2
$.post({
url: '../menu/add',
data: data,
success: function (data) {
$.messager.info('添加成功~');
queryForAll();
}
});
return true;
}
/**
* 添加三级菜单
*/
function addBtn() {
//校验表单
var validate = validateForm($("#form-add-btn"));
if (!validate) {
$.messager.warning("请正确填写相关信息~");
return false;
}
//校验icon
var iconClass = $("#form-add-btn input[name='icon']").val();
var validateIcon = iconClass.length > 0 ? $("." + iconClass).length > 0 : false;
if (!validateIcon) {
$.messager.warning("图标无效~");
return false;
}
var data = $("#form-add-btn").serialize(); //www-form格式:k1=v1&k2=v2
$.post({
url: '../menu/addBtn',
data: data,
success: function (data) {
$.messager.info('添加成功~');
queryForAll();
}
});
return true;
}
/**
* 修改记录
*/
function edit() {
//校验表单
var validate = validateForm($("#form-edit"));
if (!validate) {
$.messager.warning("请正确填写相关信息~");
return false;
}
//校验combobox (设定规则:编辑下,不可变更父子关系,后端不校验关系变更,前端防控)
var id = $("#form-edit input[type='hidden']").val();
var parentId = $("#form-edit .easyui-combobox").combobox('getValue');
if (id == parentId) {
$.messager.warning("父级菜单不能指定为自身~");
return false;
}
var validateParentId = validateCombobox($("#form-edit .easyui-combobox"), "父级菜单无效~");
if (!validateParentId) {
return false;
}
//校验icon
var iconClass = $("#form-edit input[name='icon']").val();
var validateIcon = iconClass.length > 0 ? $("." + iconClass).length > 0 : false;
if (!validateIcon) {
$.messager.warning("图标无效~");
return false;
}
var data = $("#form-edit").serialize(); //www-form格式:k1=v1&k2=v2
$.post({
url: '../menu/edit',
data: data,
success: function (data) {
$.messager.info('修改成功~');
queryForAll();
}
});
return true;
}
/**
* 修改三级菜单
*/
function editBtn() {
//校验表单
var validate = validateForm($("#form-edit-btn"));
if (!validate) {
$.messager.warning("请正确填写相关信息~");
return false;
}
//校验icon
var iconClass = $("#form-edit-btn input[name='icon']").val();
var validateIcon = iconClass.length > 0 ? $("." + iconClass).length > 0 : false;
if (!validateIcon) {
$.messager.warning("图标无效~");
return false;
}
var data = $("#form-edit-btn").serialize(); //www-form格式:k1=v1&k2=v2
$.post({
url: '../menu/editBtn',
data: data,
success: function (data) {
$.messager.info('修改成功~');
queryForAll();
}
});
return true;
}
/**
* 删除记录
*/
function remove(item) {
$.post({
url: '../menu/delete',
data: {
id: item.id
},
success: function (data) {
$.messager.info('删除成功~');
queryForAll();
}
});
}
/**
* 查询
*/
function queryForAll() {
$("#grid").treegrid('load', {
keyword: ""
});
$("#dialog-add .easyui-combobox").combobox('reload');
//设定规则:编辑下,不可变更父子关系
// $("#dialog-edit .easyui-combobox").combobox('reload');
}
/**
* 搜索(不支持二级搜索,因为_parentId有效,但无parent返回,如何显示一二级与如何返回一二级结构会比较尴尬,且需兼容非搜索)
*/
function queryForSearchText() {
$("#grid").treegrid('load', {
keyword: $("#input-search").val()
});
}
/**
* 按键监听
*/
function onkeyUp(event) {
if (event.key == "Enter") {
queryForSearchText();
}
}
#### 菜单列表后端:
package com.qlslylq.javadesign.controller;
import com.qlslylq.javadesign.enums.ErrorEnum;
import com.qlslylq.javadesign.mapper.service.MenuService;
import com.qlslylq.javadesign.model.Menu;
import com.qlslylq.javadesign.model.request.MenuEditReq;
import com.qlslylq.javadesign.pojo.Pager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
/**
* @Description 菜单控制器
* @Author https://gitee.com/qlslylq/UnityDesign
* @link https://gitee.com/qlslylq/FlutterDesign
* @link https://gitee.com/qlslylq/AndroidDesign
**/
@Controller
@RequestMapping(value = "/menu")
public class MenuController {
@Autowired
private MenuService menuService;
/**
* 菜单列表页
*/
@RequestMapping(value = "/list", method = RequestMethod.GET)
public ModelAndView list(ModelAndView mv) {
mv.setViewName("menu/list");
return mv;
}
/**
* 一级菜单列表页
*/
@RequestMapping(value = "/getTopList", method = RequestMethod.POST)
@ResponseBody
public List
List
Menu item = new Menu();
item.setId(0L);
item.set_parentId(0L);
item.setName("顶级菜单");
list.add(0, item);
return list;
}
/**
* 获取菜单详情
*/
@RequestMapping(value = "/get", method = RequestMethod.POST)
@ResponseBody
public Map get(long id) {
Menu item = menuService.get(id);
Map map = new LinkedHashMap<>();
map.put("code", ErrorEnum.ERR_0.getId());
map.put("msg", "");
map.put("data", item);
return map;
}
/**
* 获取图标资源集
*/
@RequestMapping(value = "/getIconList", method = RequestMethod.POST)
@ResponseBody
public Map getIconList(HttpServletRequest servletRequest) {
Map map = new LinkedHashMap<>();
String root_path = servletRequest.getServletContext().getRealPath("/");
File file = new File(root_path + "resources/easyui/css/icons");
if (!file.exists()) {
map.put("code", ErrorEnum.ERR_403.getId());
map.put("msg", "文件夹不存在~");
return map;
}
File[] files = file.listFiles();
List data = new ArrayList<>();
for (File item : files) {
if (item.getName().contains(".png")) {
data.add(item.getName());
}
}
map.put("code", ErrorEnum.ERR_0.getId());
map.put("msg", "");
map.put("data", data);
return map;
}
/**
* 添加一二级菜单
*/
@RequestMapping(value = "/add", method = RequestMethod.POST)
@ResponseBody
public Map add(MenuEditReq menu) {
Map map = new LinkedHashMap<>();
if (menu.getParentId() == null || (menu.getParentId() != null && menu.getParentId() < 0)) {
menu.setParentId(0L);
}
//确认parentId有效性
if (menu.getParentId() != null && menu.getParentId() != 0) {
List
boolean validateParentId = false;
for (Menu item : list_top) {
if (item.getId().equals(menu.getParentId())) {
validateParentId = true;
break;
}
}
if (!validateParentId) {
map.put("code", ErrorEnum.ERR_404.getId());
map.put("msg", "父级菜单不存在~");
return map;
}
}
if (StringUtils.isEmpty(menu.getName()) || StringUtils.isEmpty(menu.getIcon()) || StringUtils.isEmpty(menu.getLink())) {
map.put("code", ErrorEnum.ERR_405.getId());
map.put("msg", ErrorEnum.ERR_405.getName());
return map;
}
int code = menuService.add(menu);
map.put("code", code > 0 ? ErrorEnum.ERR_0.getId() : ErrorEnum.ERR_501.getId());
map.put("msg", code > 0 ? "" : ErrorEnum.ERR_501.getName());
return map;
}
/**
* 添加按钮(三级菜单)
*/
@RequestMapping(value = "/addBtn", method = RequestMethod.POST)
@ResponseBody
public Map addBtn(MenuEditReq menu) {
Map map = new LinkedHashMap<>();
if (menu.getParentId() == null || (menu.getParentId() != null && menu.getParentId() <= 0)) {
map.put("code", ErrorEnum.ERR_404.getId());
map.put("msg", "父级菜单不存在~");
return map;
}
//确认parentId有效性
if (menu.getParentId() != null && menu.getParentId() != 0) {
List
boolean validateParentId = false;
for (Menu item : list_top) {
List
for (Menu item_child : list_children) {
if (item_child.getId().equals(menu.getParentId())) {
validateParentId = true;
break;
}
}
if (validateParentId) {
break;
}
}
if (!validateParentId) {
map.put("code", ErrorEnum.ERR_404.getId());
map.put("msg", "父级菜单不存在~");
return map;
}
}
if (StringUtils.isEmpty(menu.getName()) || StringUtils.isEmpty(menu.getIcon()) || StringUtils.isEmpty(menu.getLink())) {
map.put("code", ErrorEnum.ERR_405.getId());
map.put("msg", ErrorEnum.ERR_405.getName());
return map;
}
int code = menuService.add(menu);
map.put("code", code > 0 ? ErrorEnum.ERR_0.getId() : ErrorEnum.ERR_501.getId());
map.put("msg", code > 0 ? "" : ErrorEnum.ERR_501.getName());
return map;
}
/**
* 修改一二级菜单
* 一级菜单可变更为二级菜单,二级菜单不能变更为一级菜单
* 设定规则:编辑下,不可变更父子关系,后端不校验关系变更,前端防控
*/
@RequestMapping(value = "/edit", method = RequestMethod.POST)
@ResponseBody
public Map edit(MenuEditReq menu) {
Map map = new LinkedHashMap<>();
if (menu.getParentId() == null || (menu.getParentId() != null && menu.getParentId() < 0)) {
menu.setParentId(0L);
}
if (menu.getId().equals(menu.getParentId())) {
map.put("code", ErrorEnum.ERR_404.getId());
map.put("msg", "父级菜单不能指定为自身~");
return map;
}
//确认parentId有效性
if (menu.getParentId() != null && menu.getParentId() != 0) {
List
boolean validateParentId = false;
for (Menu item : list_top) {
if (item.getId().equals(menu.getParentId())) {
validateParentId = true;
break;
}
}
if (!validateParentId) {
map.put("code", ErrorEnum.ERR_404.getId());
map.put("msg", "父级菜单不存在~");
return map;
}
}
if (StringUtils.isEmpty(menu.getName()) || StringUtils.isEmpty(menu.getIcon()) || StringUtils.isEmpty(menu.getLink())) {
map.put("code", ErrorEnum.ERR_405.getId());
map.put("msg", ErrorEnum.ERR_405.getName());
return map;
}
int code = menuService.edit(menu);
map.put("code", code > 0 ? ErrorEnum.ERR_0.getId() : ErrorEnum.ERR_501.getId());
map.put("msg", code > 0 ? "" : ErrorEnum.ERR_501.getName());
return map;
}
/**
* 修改三级菜单
* 一级菜单可变更为二级菜单,二级菜单不能变更为一级菜单
*/
@RequestMapping(value = "/editBtn", method = RequestMethod.POST)
@ResponseBody
public Map editBtn(MenuEditReq menu) {
Map map = new LinkedHashMap<>();
if (menu.getParentId() == null || (menu.getParentId() != null && menu.getParentId() < 0)) {
menu.setParentId(0L);
}
if (menu.getId().equals(menu.getParentId())) {
map.put("code", ErrorEnum.ERR_404.getId());
map.put("msg", "父级菜单不能指定为自身~");
return map;
}
//确认parentId有效性
if (menu.getParentId() != null && menu.getParentId() != 0) {
List
boolean validateParentId = false;
for (Menu item : list_top) {
List
for (Menu item_child : list_children) {
if (item_child.getId().equals(menu.getParentId())) {
validateParentId = true;
break;
}
}
if (validateParentId) {
break;
}
}
if (!validateParentId) {
map.put("code", ErrorEnum.ERR_404.getId());
map.put("msg", "父级菜单不存在~");
return map;
}
}
if (StringUtils.isEmpty(menu.getName()) || StringUtils.isEmpty(menu.getIcon()) || StringUtils.isEmpty(menu.getLink())) {
map.put("code", ErrorEnum.ERR_405.getId());
map.put("msg", ErrorEnum.ERR_405.getName());
return map;
}
int code = menuService.edit(menu);
map.put("code", code > 0 ? ErrorEnum.ERR_0.getId() : ErrorEnum.ERR_501.getId());
map.put("msg", code > 0 ? "" : ErrorEnum.ERR_501.getName());
return map;
}
/**
* 删除菜单
*/
@RequestMapping(value = "/delete", method = RequestMethod.POST)
@ResponseBody
public Map delete(long id) {
Map map = new LinkedHashMap<>();
if (menuService.getChildrenList(id).size() > 0) {
map.put("code", ErrorEnum.ERR_404.getId());
map.put("msg", "请先删除该菜单下的所有子菜单~");
return map;
}
int code = 0;
try {
code = menuService.delete(id);
} catch (Exception e) {
map.put("code", ErrorEnum.ERR_404.getId());
map.put("msg", "请先删除关联该菜单的所有权限~");
return map;
}
map.put("code", code > 0 ? ErrorEnum.ERR_0.getId() : ErrorEnum.ERR_502.getId());
map.put("msg", code > 0 ? "" : ErrorEnum.ERR_502.getName());
return map;
}
/**
* 查询及搜索菜单
*/
@RequestMapping(value = "/getList", method = RequestMethod.POST)
@ResponseBody
public Map getList(Pager pager, @RequestParam(value = "keyword", required = false, defaultValue = "") String keyword) {
Map map = new LinkedHashMap<>();
Map data = new LinkedHashMap<>();
List
map.put("code", ErrorEnum.ERR_0.getId());
map.put("msg", "");
data.put("total", menuService.getTotalCount(keyword));
data.put("rows", list);
map.put("data", data);
return map;
}
}
#### 远端多字段排序
/**
* 查询及搜索用户
*/
@RequestMapping(value = "/getList", method = RequestMethod.POST)
@ResponseBody
public Map getList(Pager pager, @RequestParam(value = "keyword", required = false, defaultValue = "") String keyword,
@RequestParam(value = "roleId", required = false, defaultValue = "-1") long roleId,
@RequestParam(value = "sex", required = false, defaultValue = "-1") int sex, SortOrder sortOrder) {
Map map = new LinkedHashMap<>();
Map data = new LinkedHashMap<>();
sortOrder.setSortSql();
List list = userService.getList(pager, keyword, roleId, sex, sortOrder);
map.put("code", ErrorEnum.ERR_0.getId());
map.put("msg", "");
data.put("total", userService.getTotalCount(keyword, roleId, sex));
data.put("rows", list);
map.put("data", data);
return map;
}