文章目录
前文推荐
汽车租赁系统的介绍和项目搭建(1)
JavaSSM框架学完,手写一个汽车租赁系统,真NE!
汽车租赁系统(2)-完成登录功能
汽车租赁系统(3)-工作台开发和菜单树的加载
菜单管理
特别提醒:
只展示部分比较重要的代码,部分代码省略
菜单管理功能演示
用动图演示一下,菜单管理的主要功能:
我们在动图中主要演示了下列的功能:
- 首先在左侧要加载一颗菜单树(有组织的)
- 右侧希望在点击进来时直接显示所有的菜单信息,并提供模糊查询的功能
- 具有菜单添加,修改,删除的功能.且要求点击左侧菜单树也能实现显示该菜单下的所有菜单
菜单管理分析:
分析:
- 菜单管理页面被分为两部分,左边一部分是菜单的导航树,右边的是菜单相关详细信息的表格和模糊查询的实现
- 根据这样的布局,决定使用framset的布局方式
接下来菜单管理一般步骤的开发
- 生成Menu实体类
- 生成MenuMapper
- 生成MenuMapper
- 创建MenuVo
- 创建MenuService
- 创建MenuServiceImpl
- 创建MenuController
查询
查询分为两部分:
- 根据查询结果构建左侧菜单树
- 显示查询结果到表格中
一.菜单页面布局的实现
创建一个MenuManager,jsp实现页面的布局,将页面分为左边加载菜单的MenuManagerLeft.jsp和MenuManagerRight.jsp.
- 注意使用framset的布局方式,那么在其中不能再出现body标签
MenuManager.jsp
<%--
Created by IntelliJ IDEA.
User: YLJ
Date: 2020年7月8日
Time: 16:43:20
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>菜单管理</title>
</head>
<%--如果使用frameset 包含页面 主页面不能有body--%>
<frameset cols="230,*" border="1">
<frame src="${leiyujia}/sys/toMenuLeft.action" name="left">
<frame src="${leiyujia}/sys/toMenuRight.action" name="right">
</frameset>
</html>
二.实现左侧菜单树
1.创建页面
MenuManagerLeft.jsp
<%--
Created by IntelliJ IDEA.
User: LYJ
Date: 2020年7月8日
Time: 16:42:48
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="utf-8">
<title>菜单树</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link rel="icon" href="favicon.ico">
<link rel="stylesheet" href="${leiyujia}/static/layui/css/layui.css" media="all"/>
<link rel="stylesheet" href="${leiyujia}/static/css/public.css" media="all"/>
<link rel="stylesheet" href="${leiyujia}/static/layui_ext/dtree/dtree.css">
<link rel="stylesheet" href="${leiyujia}/static/layui_ext/dtree/font/dtreefont.css">
</head>
<body class="main_body">
<ul id="menuTree" class="dtree" data-id="0"></ul>
<script type="text/javascript" src="${leiyujia}/static/layui/layui.js"></script>
<script type="text/javascript">
var menuTree;
layui.extend({
dtree: '${leiyujia}/static/layui_ext/dist/dtree'
}).use(['jquery', 'layer', 'form', 'dtree'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var dtree = layui.dtree;
// 初始化树
menuTree = dtree.render({
elem: "#menuTree",
dataStyle: "layuiStyle", //使用layui风格的数据格式
response: {message: "msg", statusCode: 0}, //修改response中返回数据的定义
dataFormat: "list", //配置data的风格为list
url: "${leiyujia}/menu/loadMenuManagerLeftTreeJson.action?spread=1" // 使用url加载(可与data加载同时存在)
});
//监听树的节点点击 事件
dtree.on("node('menuTree')", function (obj) {
var id = obj.param.nodeId;
window.parent.right.reloadTable(id);
});
});
</script>
</body>
</html>
注意使用的是LayUI的dtree+list风格的树型组件
其要求的json的数据格式是
可以看出在layUI中要求的数据结构比较简单,便于我们根据数据库的数据区组装它的结果,所以我们决定用它.
2.修改MenuController
我们需要给前端返回一个LayUI+list的json数据格式,这同样不是一个简单的json数据格式,是一个标准的数据格式
- json数据格式
- json数据中data的数据格式如何实现
/** * 加载菜单左边的菜单树 * @param menuVo * @return */
@RequestMapping("loadMenuManagerLeftTreeJson")
public DataGridView loadMenuManagerLeftTreeJson(MenuVo menuVo){
menuVo.setAvailable(SysConstast.AVAILABLE_TRUE);//只查询可用的
List<Menu> list = this.menuService.queryAllMenuForList(menuVo);
List<TreeNode> nodes = new ArrayList<>();
//把list里面的数据放到nodes
for (Menu menu : list){
Integer id = menu.getId();
Integer pid = menu.getPid();
String title = menu.getTitle();
String icon = menu.getIcon();
String href = menu.getHref();
Boolean spread = menu.getSpread()==SysConstast.SPREAD_TRUE?true:false;
String target = menu.getTarget();
nodes.add(new TreeNode(id,pid,title,icon,href,spread,target));
}
return new DataGridView(nodes);
}
我们在Controller中对查询到的菜单数据进行封装,用之前博客中讲到的封装树型结构的treeNode的工具类,相当于封装了data中的数据格式
还有外层的json数据的格式,我们需要再新建一个工具类来封装
DataGridView工具类
用于将数据包装成要求的json的数据格式
实现细节:
package per.leiyu.sys.utils;
/** * @author lleiyujia */
public class DataGridView {
/** * 封装LayUI数据表格的数据对象 */
private Integer code=0;
private String msg="";
private Long count;
private Object data;
public DataGridView() {
}
public DataGridView(Object data) {
super();
this.data = data;
}
public DataGridView(Long count, Object data) {
super();
this.count = count;
this.data = data;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Long getCount() {
return count;
}
public void setCount(Long count) {
this.count = count;
}
public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
}
- code和meg属性我们都可以是设置为默认的
- 另外为了分页是可以显示到总条数我们还可以为其封装一个count属性
注意:
封装前端所需要的json数据时,可以比简短需要数据格式的属性多,但是不能缺少其中的属性
- 只需要将实际前端需要的json数据封装为Object形式,然后在对Object数据再进行内部的封装就可以了
3.开发关于查询菜单信息的Service类和其实现类
MenuService
/** * 查询所有菜单返回 * @param menuVo * @return */
@Override
public List<Menu> queryAllMenuForList(MenuVo menuVo);
- 注意返回值类型
MenuServiceImpl
/** * 查询所有菜单返回 * @param menuVo * @return */
@Override
public List<Menu> queryAllMenuForList(MenuVo menuVo) {
return menuMapper.queryAllMenu(menuVo);
}
菜单查询和菜单实体的创建这里就不做赘述
注意返回值类型
MenuServiceImpl
/** * 查询所有菜单返回 * @param menuVo * @return */
@Override
public List<Menu> queryAllMenuForList(MenuVo menuVo) {
return menuMapper.queryAllMenu(menuVo);
}
菜单查询和菜单实体的创建这里就不做赘述
三.显示查询到的数据在页面中的显示
1.创建显示页面MenuManagerRight.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<meta charset="utf-8">
<title>菜单管理</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta http-equiv="Access-Control-Allow-Origin" content="*">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<%--<link rel="icon" href="favicon.ico">--%>
<link rel="stylesheet" href="${leiyujia}/static/layui/css/layui.css" media="all"/>
<link rel="stylesheet" href="${leiyujia}/static/css/public.css" media="all"/>
<link rel="stylesheet" href="${leiyujia}/static/layui_ext/dtree/dtree.css">
<link rel="stylesheet" href="${leiyujia}/static/layui_ext/dtree/font/dtreefont.css">
<style type="text/css">
.select-test {
position: absolute;
max-height: 500px;
height: 350px;
overflow: auto;
width: 100%;
z-index: 123;
display: none;
border: 1px solid silver;
top: 42px;
}
.layui-show {
display: block !important;
}
</style>
</head>
<body class="childrenBody">
<!-- 搜索条件开始 -->
<fieldset class="layui-elem-field layui-field-title" style="margin-top: 20px;">
<legend>查询条件</legend>
</fieldset>
<form class="layui-form" method="post" id="searchFrm">
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">菜单名称:</label>
<div class="layui-input-inline" style="padding: 5px">
<input type="text" name="title" autocomplete="off" class="layui-input layui-input-inline"
placeholder="请输入菜单名称" style="height: 30px;border-radius: 10px">
</div>
</div>
<div class="layui-inline">
<button type="button"
class="layui-btn layui-btn-normal layui-icon layui-icon-search layui-btn-radius layui-btn-sm"
id="doSearch">查询
</button>
<button type="reset"
class="layui-btn layui-btn-warm layui-icon layui-icon-refresh layui-btn-radius layui-btn-sm">重置
</button>
</div>
</div>
</form>
<!-- 数据表格开始 -->
<table class="layui-hide" id="menuTable" lay-filter="menuTable"></table>
<div style="display: none;" id="menuToolBar">
<button type="button" class="layui-btn layui-btn-sm layui-btn-radius" lay-event="add">增加</button>
</div>
<div id="menuBar" style="display: none;">
<a class="layui-btn layui-btn-xs layui-btn-radius" lay-event="edit">编辑</a>
<a class="layui-btn layui-btn-danger layui-btn-xs layui-btn-radius" lay-event="del">删除</a>
</div>
<!-- 添加和修改的弹出层开始 -->
<div style="display: none;padding: 20px" id="saveOrUpdateDiv">
<form class="layui-form" lay-filter="dataFrm" id="dataFrm">
<div class="layui-form-item">
<label class="layui-form-label">父级菜单:</label>
<div class="layui-input-block">
<div class="layui-unselect layui-form-select" id="pid_div">
<div class="layui-select-title">
<input type="hidden" name="pid" id="pid">
<input type="text" name="pid_str" id="pid_str" placeholder="请选择" lay-verify="required" readonly=""
class="layui-input layui-unselect">
<i class="layui-edge"></i>
</div>
</div>
<div class="layui-card select-test" id="menuSelectDiv">
<div class="layui-card-body">
<div id="toolbarDiv">
<ul id="menuTree" class="dtree" data-id="0" style="width: 100%;"></ul>
</div>
</div>
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">菜单名称:</label>
<div class="layui-input-block">
<input type="hidden" name="id">
<input type="text" name="title" placeholder="请输入菜单名称" lay-verify="required" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">菜单地址:</label>
<div class="layui-input-block">
<input type="text" name="href" placeholder="请输入菜单地址" autocomplete="off" class="layui-input">
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">菜单图标:</label>
<div class="layui-input-inline">
<input type="text" name="icon" placeholder="请输入菜单图标" lay-verify="required" autocomplete="off"
class="layui-input">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">TARGET:</label>
<div class="layui-input-inline">
<input type="text" name="target" placeholder="请输入TRAGET" autocomplete="off" class="layui-input">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-inline">
<label class="layui-form-label">是否展开:</label>
<div class="layui-input-inline">
<input type="radio" name="spread" value="1" title="展开">
<input type="radio" name="spread" value="0" title="不展开" checked="checked">
</div>
</div>
<div class="layui-inline">
<label class="layui-form-label">是否可用:</label>
<div class="layui-input-inline">
<input type="radio" name="available" value="1" checked="checked" title="可用">
<input type="radio" name="available" value="0" title="不可用">
</div>
</div>
</div>
<div class="layui-form-item">
<div class="layui-input-block" style="text-align: center;padding-right: 120px">
<button type="button"
class="layui-btn layui-btn-normal layui-btn-md layui-icon layui-icon-release layui-btn-radius"
lay-filter="doSubmit" lay-submit="">提交
</button>
<button type="reset"
class="layui-btn layui-btn-warm layui-btn-md layui-icon layui-icon-refresh layui-btn-radius">重置
</button>
</div>
</div>
</form>
</div>
<script src="${leiyujia}/static/layui/layui.js"></script>
<script src="${leiyujia}/static/layui_ext/dist/dtree.js"></script>
<script type="text/javascript">
var tableIns;
layui.extend({
dtree: '${leiyujia}/static/layui_ext/dist/dtree'
}).use(['jquery', 'layer', 'form', 'table', 'dtree'], function () {
var $ = layui.jquery;
var layer = layui.layer;
var form = layui.form;
var table = layui.table;
var dtree = layui.dtree;
//渲染数据表格
tableIns = table.render({
elem: '#menuTable' //渲染的目标对象
, url: '${leiyujia}/menu/loadAllMenu.action' //数据接口
, title: '用户数据表'//数据导出来的标题
, toolbar: "#menuToolBar" //表格的工具条
, height: 'full-148'
, cellMinWidth: 100 //设置列的最小默认宽度
, page: true //是否启用分页
, cols: [[ //列表数据
{type: 'checkbox', fixed: 'left'}
, {field: 'id', title: 'ID', align: 'center', width: '50'}
, {field: 'pid', title: '父节点ID', align: 'center', width: '90'}
, {field: 'title', title: '菜单名称', align: 'center', width: '160'}
, {field: 'href', title: '菜单地址', align: 'center', width: '225'}
, {
field: 'spread', title: '是否展开', align: 'center', width: '90', templet: function (d) {
return d.spread == '1' ? '<font color=blue>展开</font>' : '<font color=red>不展开</font>';
}
}
, {field: 'target', title: 'TARGET', align: 'center', width: '90'}
, {
field: 'icon', title: '菜单图标', align: 'center', width: '90', templet: function (d) {
return "<div class='layui-icon'>" + d.icon + "</div>";
}
}
, {
field: 'available', title: '是否可用', align: 'center', width: '90', templet: function (d) {
return d.available == '1' ? '<font color=blue>可用</font>' : '<font color=red>不可用</font>';
}
}
, {fixed: 'right', title: '操作', toolbar: '#menuBar', width: 120, align: 'center'}
]],
done:function (data, curr, count) {
//不是第一页时,如果当前返回的数据为0那么就返回上一页
if(data.data.length==0&&curr!=1){
tableIns.reload({
page:{
curr:curr-1
}
})
}
}
})
</script>
</body>
</html>
2.创建loadAllMenu的handler
/** * 加载菜单列表返回DataGridView * @param menuVo * @return */
@RequestMapping("loadAllMenu")
public DataGridView loadAllMenu(MenuVo menuVo){
return this.menuService.queryAllMenu(menuVo);
}
3.创建Service和ServiceImpl
作用就是查询都所有的菜单的详细信息,并返回给Controller,注意返回数据的格式要求封装为LayUI的数据表格的格式
/** * 查询所有菜单 * @param menuVo * @return */
public DataGridView queryAllMenu(MenuVo menuVo);
/** * 查询所有菜单列表 * @param menuVo * @return * 分页查询 */
@Override
public DataGridView queryAllMenu(MenuVo menuVo) {
Page<Object> page = PageHelper.startPage(menuVo.getPage(),menuVo.getLimit());
List<Menu> data = this.menuMapper.queryAllMenu(menuVo);
return new DataGridView(page.getTotal(),data);
}
写Mapper抽象接口和其对应的xml文件
/** * 查询所有菜单 */
List<Menu> queryAllMenu(Menu menu);
xml配置文件的sql语句
<!--查询所有菜单-->
<resultMap id="BaseResultMap" type="per.leiyu.sys.domain.Menu">
<id column="id" jdbcType="INTEGER" property="id" />
<result column="pid" jdbcType="INTEGER" property="pid" />
<result column="title" jdbcType="VARCHAR" property="title" />
<result column="href" jdbcType="VARCHAR" property="href" />
<result column="spread" jdbcType="INTEGER" property="spread" />
<result column="target" jdbcType="VARCHAR" property="target" />
<result column="icon" jdbcType="VARCHAR" property="icon" />
<result column="available" jdbcType="INTEGER" property="available" />
</resultMap>
<select id="queryAllMenu" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from sys_menu
<where>
<if test="title!=null and title!=''">
and title like concat("%",#{title},"%")
</if>
<if test="available!=null">
and available=#{available}
</if>
<if test="id!=null">
and (id=#{id} or pid=#{id})
</if>
</where>
</select>
到这里,从前端到后端关于数据库中菜单数据的查询显示的功能就全部实现,下一篇文章将菜单的删除,批量删除,添加和修改功能实现
我是雷雨,一个
普本科
的学生,主要专注于Java后端和大数据开发
如果你喜欢这样的文章,可以关注我,一起努力,一起努力拿大厂offer
如果这篇文章有帮助到你,希望你给我一个的赞
如果有什么问题,希望你能评论区
和我一起研究
.
如果您要转载请转载注明出处
https://blog.csdn.net/qq_40742223