ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
# 注意:本文档后期不在跟新,新文档迁移到:[http://www.openkit.cc/docs/kitadmin/#/](http://www.openkit.cc/docs/kitadmin/#/) #### 首先感谢使用KitAdmin后台开发框架 #### 反馈交流QQ群:696279396 --- ### 说明 > 在开发的时候,我们后台管理页面,经常需要添加一些管理的按钮,我们添加一个管理的栏目,和一些对应的页面,那么为什么说 KitAdmin 的效率非常的高,就体现在这里,我们只需要按照下面的方法就可以添加一些单独的功能模块 ### 步骤 - 第一步:我们打开后台管理页面,依次点击 --> 菜单管理 --> 添加 ![](https://box.kancloud.cn/e9c4770c7a477cebca54e5dbba390900_3210x1620.png) - 这时候会有一个弹窗,在弹窗页面添加你需要给他的内容即可链接地址就是我们的对应的舔砖地址 ![](https://box.kancloud.cn/64dbe0b543e75ff8387ddef4243def35_1772x1340.png) > 上面的链接地址是我们需要在`Controller` 里边实现的方法,上面的标题就是左侧对应的栏目,你也可以自己去分组 - 第二步:你需要将你添加的功能模块给对应的分组权限,按照下图一次点击 --> 分组管理 --> 修改,当然如果你想添加一个分组,也是可以的,主要添加的时候直接赋予其权限即可 ![](https://box.kancloud.cn/cc427550a47d0e08e05acce76acd7333_3248x1702.png) - 接下来在弹框中勾选对应职位即可,对了,最后别忘了保存哦 ![](https://box.kancloud.cn/4899c6113ab1a2a2dde61546e22695b5_1730x1304.png) - 接下来你要做的就非常简单了,你只要将对应赋予权限的用户账号,重新登录一下就可以看到左侧增加了一个我们刚刚添加的模块,当然这个时候我们点击会发现啥都没有。不要着急,请接着往下看: - 第三步:我们需要到对应的`controller`中实现上面添加的方法,比如: > 在这之前,我们先在菜单管理列表页面找到新增加的菜单的ID,如下图 ![](https://box.kancloud.cn/98fbe7a31f529cbe33a261a88e40b854_2786x1080.png) > 然后利用代码生成工具生成`model`,`dao`,`mapper`,然后根据需求处理,不会的可以参考文档中的 --> 公告方法 --> 代码自动生成 - 编写方法 ```java /** * 添加的方法 * @return */ @RequestMapping(value = "/getAll", method = RequestMethod.GET) public ModelAndView getAll(HttpServletRequest request){ // 权限验证。这里的最后的 5 就是上面我们找到菜单的ID,需要在这里查找 GGroupLimit gGroupLimit = gGroupLimitService.testGroup(request, 5); ModelAndView mv = new ModelAndView(); // 没有权限,返回错误页面 if(gGroupLimit==null){ mv.setViewName("/admin/err/no_group_err"); mv.addObject("msg", StaticFinalVar.NO_GROUP_MSG+StaticFinalVar.CALL_GROUP); return mv; } // 取值 mv.setViewName("/admin/XXXX/list"); // 需要跳转的页面 mv.addObject("kitG",gGroupLimit); return mv; } ``` > 为了代码的重复利用,比如可能获取列表数据接口在其他地方也会用到,所以我们在这个`Controller`里边只做权限验证和跳转,其他的数据,我们再下面的接口中取得 👇👇👇👇👇👇👇 - 第四步:我们上面的`Controller`里边有一个跳转页面`mv.setViewName("/admin/XXXX/list"); `下面我们就要去实现这些文件 > 为了方便,我们直接将`src/main/webapp/templates/admin`文件夹下面的`admin`文件夹复制一份,将文件夹的名字改成上面的`XXXX`即可,这个时候我们去从其下服务,重新登录,再次点击左侧的新增的栏目现在就已经可以看到跳转页面了。当然,我们还需要修改一下获取数据的方式 - `List`页面源码解析 ```html <%@ page contentType="text/html;charset=UTF-8" language="java" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>用户管理</title> <link rel="stylesheet" href="<%=basePath%>templates/style/plugins/layui/css/layui.css" media="all"> <link rel="stylesheet" href="<%=basePath%>templates/style/build/css/doc.css" media="all"> <script src="<%=basePath%>templates/style/plugins/layui/layui.js"></script> <script src="<%=basePath%>templates/style/plugins/layui/jquery-3.3.1.min.js"></script> </head> <body> <div class="kit-doc"> <!--这里写页面的代码--> <blockquote class="layui-elem-quote">这里的用户是后台登录的用户,不是前台注册的用户</blockquote> <div class="kit-doc-title"> <fieldset> <legend><a name="blockquote">用户列表</a></legend> </fieldset> </div> <div> <!-- 判断是否有添加权限,如果有则显示按钮 --> <c:if test="${kitG.groupC==1}"><button class="layui-btn" id="add">添加</button></c:if> <!-- 判断结束 --> <!-- 模糊搜索框开始 --> <div class="layui-inline" style="float: right"> <div class="layui-input-inline"> <input name="search" id="search" lay-verify="required" autocomplete="off" class="layui-input" type="text"> </div> <button class="layui-btn layui-btn-primary" onclick="search()">搜索</button> </div> <!-- 模糊搜索框结束--> <div style="clear:both;"></div> <!-- 列表开始 --> <table class="layui-hide" id="test" lay-filter="demo"></table> <!-- 列表前面的 序号栏目 --> <script type="text/html" id="indexTpl"> {{d.LAY_TABLE_INDEX+1}} </script> <!-- 列表最后的操作按钮 --> <script type="text/html" id="barDemo"> <c:if test="${kitG.groupU==1}"><button class="layui-btn layui-btn-xs" lay-event="edit">编辑</button></c:if> {{# if(d.kitAdminId != 1){ }} <c:if test="${kitG.groupR==1}"><button class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</button></c:if> {{# } }} </script> <!-- 列表结束 --> </div> </div> <script> // 添加 方法 layui.use(['jquery', 'layer', 'table'], function () { var table = layui.table; //让层自适应iframe $('#add').on('click', function(){ var index = layer.open({ type: 2, content: '<%=basePath%>admin/goAdd', // 这里是弹窗请求方法,下面我们需要实现的 area: ['400px', '570px'], // 这里是弹窗大小,可以根据需求自己设置 maxmin: true, end: function () { location.reload(); } }); parent.layer.iframeAuto(index); }); }); // 默认渲染数据 layui.use('table', function(){ var table = layui.table; var search = $('#search').val(); table.render({ elem: '#test' ,url:'<%=basePath%>admin/getAllJson' ,where: {search: search} ,method: 'post' ,page: {layout: ['limit', 'count', 'prev', 'page', 'next', 'skip']} ,cols: [[ // 这里就是对于的列 第一行显示序号,最后一行显示操作不需要修改,中间的filed就是对应返回值列表对象中的名称。 {field:'',align:'center', width:70, title: '序号', toolbar: '#indexTpl'} ,{field:'kitAdminName', title: '管理员名字'} ,{field:'kitAdminUsername', title: '登录名'} ,{field:'groupName', title: '所属分组'} ,{field:'right',align:'center', width:150, toolbar: '#barDemo', title: '操作'} ]] }); //监听工具条 table.on('tool(demo)', function(obj){ var data = obj.data; if(obj.event === 'edit'){ // 编辑按钮方法实现 var index = layer.open({ type: 2, // 这里是编辑实现方法,下面我们需要实现,参数是id ,data.kitAdminID, 就是列表对象中传来的唯一id的属性名 content: '<%=basePath%>admin/goUpdate?id='+data.kitAdminId, area: ['400px', '570px'], maxmin: true, end: function () { location.reload(); } }); parent.layer.iframeAuto(index); } else if(obj.event === 'del'){ layer.confirm('真的要删除么?', function(index){ // 写删除方法 // 这里是编辑实现方法,下面我们需要实现,参数是id ,data.kitAdminID, 就是列表对象中传来的唯一id的属性名 $.post("<%=basePath%>admin/del", {"id": data.kitAdminId}, function (data) { if (data.code == "200") { layer.msg(data.msg, {icon: 1, time: 1000}); // 前端修改 layer.close(index); window.location.reload(); } else { layer.msg(data.msg, {icon: 0, time: 1000}); layer.close(index); } }); }); } }); }); // 点击搜索按钮之后渲染数据方法 function search(){ var table = layui.table; var search = $('#search').val(); table.render({ elem: '#test' ,url:'<%=basePath%>admin/getAllJson' ,where: {search: search} ,method: 'post' ,page: {layout: ['limit', 'count', 'prev', 'page', 'next', 'skip']} ,cols: [[ // 这里就是对于的列 第一行显示序号,最后一行显示操作不需要修改,中间的filed就是对应返回值列表对象中的名称。 {field:'left',align:'center', width:140, title: '序号', toolbar: '#indexTpl'} ,{field:'kitAdminName', title: '管理员名字'} ,{field:'kitAdminUsername', title: '登录名'} ,{field:'groupName', title: '所属分组'} ,{field:'right',align:'center', width:150, toolbar: '#barDemo', title: '操作'} ]] }); } </script> </body> </html> ``` - 第五步:添加获取数据接口 ```java /** * 获取列表数据 * @return */ @RequestMapping(value = "/getAllJson", method = RequestMethod.POST) @ResponseBody public Object getAllJson(HttpServletRequest request){ log.info("获取APP广告列表的数据"); Map<String,Object> map = new HashMap<String,Object>(); // 分页需要的参数 String page = request.getParameter("page");// 获得页数 String limit = request.getParameter("limit");// 获得每页显示条数 String search = request.getParameter("search");// 获取搜索条件 // 封装数据 AdvHello advHello = new AdvHello(); if(KitUtil.feikong(search)){ advHello.setAhTitle(search); } // 分页查询 List<AdvHello> advHelloList = advHelloService.queryPageListByWhere(advHello, Integer.valueOf(page), Integer.valueOf(limit)); // 获取查询到的总数 int size = advHelloService.queryCount(advHello); // 返回数据 map.put("code",0); map.put("msg",""); map.put("count",size); map.put("data",advHelloList); return JSONObject.toJSON(map); } ``` > 这里是单表的查询,不涉及到自己写SQL,如果需要自己实现service和mapper,这个跟SSM框架一毛一样自己编写即可。👇👇👇👇👇👇下面我们继续 - 第六步:实现添加弹窗跳转方法 ``` /** * 去添加页面 * @param request * @return */ @RequestMapping(value = "/goAdd", method = RequestMethod.GET) public Object goAdd(HttpServletRequest request){ log.info("APP首次登录幻灯片 》 添加 》 跳转"); ModelAndView mv = new ModelAndView(); mv.setViewName("/admin/xxx/add"); return mv; } ``` 这里我没有带参数出去,如果有额外参数,自己带出去,然后用` jsp` 的 `EL`表达式渲染即可 - `add.jsp`页面解读 ``` <%-- Created by IntelliJ IDEA. User: benhailong Date: 2018/2/7 Time: 下午3:48 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>添加管理员</title> <link rel="stylesheet" href="<%=basePath%>templates/style/plugins/layui/css/layui.css" media="all"> <link rel="stylesheet" href="<%=basePath%>templates/style/build/css/doc.css" media="all"> <script src="<%=basePath%>templates/style/plugins/layui/layui.js"></script> <script src="<%=basePath%>templates/style/plugins/layui/jquery-3.3.1.min.js"></script> </head> <body> <div class="kit-doc"> <!-- form 表单,action 已经封装,不需要写 --> <form class="layui-form layui-form-pane" action=""> <div class="layui-form-item"> <label class="layui-form-label">用户名</label> <div class="layui-input-block"> <input name="kitAdminName" lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input" type="text"> </div> </div> <div class="layui-form-item" > <label class="layui-form-label" style="height: 137px; line-height: 117px">上传头像</label> <input name="imgurl" id="imgurl" lay-verify="required" value="" autocomplete="off" class="layui-input" type="hidden"> <div class=" layui-upload-drag" id="img" style="border-left: 0px;"> <i class="layui-icon">&#xe654;</i> <p>点击上传头像</p> <img id="demo1" style="position: absolute;height: 137px;width: 137px;margin: -106px auto auto -30px;display: none" /> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">登录账号</label> <div class="layui-input-block"> <input name="kitAdminUsername" lay-verify="required" placeholder="请输入用户名" autocomplete="off" class="layui-input" type="text"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">密码</label> <div class="layui-input-block"> <input name="kitAdminPassword" lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input" type="password"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">确认密码</label> <div class="layui-input-block"> <input name="kitAdminPasswordAgen" lay-verify="required" placeholder="请输入密码" autocomplete="off" class="layui-input" type="password"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">所属管理组</label> <div class="layui-input-block"> <select name="groupId" lay-verify="required" lay-search=""> <c:forEach items="${kitList}" var="kitList" > <option value="${kitList.groupId}">${kitList.groupName}</option> </c:forEach> </select> </div> </div> <div class="layui-form-item"> <button class="layui-btn" lay-submit="" lay-filter="add">提交</button> </div> </form> <!--这里写页面的代码--> </div> <script> layui.use(['form', 'layedit', 'laydate', 'element', 'layer', 'upload'], function(){ var form = layui.form, layer = layui.layer, element = layui.element, upload = layui.upload; //普通图片上传 var uploadInst = upload.render({ elem: '#img' , url: '/apiCommon/setImage' , field: 'layuiFile' , before: function (obj) { //预读本地文件示例,不支持ie8 obj.preview(function (index, file, result, data) { $('#demo1').css('display','block').attr('src', result); //链接(base64) }); } , done: function (res) { //如果上传失败 if (res.code > 0) { return layer.msg('上传失败'); } //上传成功 if(res.code == 0){ $('#imgurl').val(res.data.src); } } , error: function () { //演示失败状态,并实现重传 var demoText = $('#demoText'); demoText.html('<span style="color: #FF5722;">上传失败</span> <a class="layui-btn layui-btn-mini demo-reload">重试</a>'); demoText.find('.demo-reload').on('click', function () { uploadInst.upload(); }); } }); //监听提交,发送请求,这里就是提交了 // 这个方法提交之前会自己根据 Layui 的验证规则先对表单验证 form.on('submit(add)', function(data){ if(data.field.kitAdminPassword!=data.field.kitAdminPasswordAgen){ layer.alert('两次密码输入不一致'); return false; } // 这里是提交事项方法,方法需要实现 $.post("<%=basePath%>XXXX/add",data.field,function(data){ // 获取 session if(data.code!=200){ layer.alert(data.msg, {offset: 't',icon: 5}); } if(data.code==200){ layer.alert(data.msg, {offset: 't',icon: 6}); } }); return false; }); }); </script> </body> </html> ``` - 第七步:添加提交方法实现,这里我用APP首次登录幻灯为例 ``` /** * 添加 * * @param request * @return */ @RequestMapping(value = "/add", method = RequestMethod.POST) @ResponseBody public Object add(HttpServletRequest request) throws Exception{ log.info("APP首次登录幻灯片 》 添加 》 保存"); // 取值 String ahTitle = request.getParameter("ahTitle"); String ahSummary = request.getParameter("ahSummary"); String ahSequence = request.getParameter("ahSequence"); String imgurl = request.getParameter("imgurl"); String ahUrl = request.getParameter("ahUrl"); String ahStartAndEndTime = request.getParameter("ahStartAndEndTime"); String ahType = request.getParameter("ahType"); // 封装对象 AdvHello advHello = new AdvHello(); advHello.setAhId(KitUtil.uuid()); advHello.setAhTitle(ahTitle); if(KitUtil.feikong(ahSummary)){ advHello.setAhSummary(ahSummary); } if(KitUtil.feikong(ahSequence)){ advHello.setAhSequence(Integer.valueOf(ahSequence)); } advHello.setAhImg(imgurl); if(KitUtil.feikong(ahUrl)){ advHello.setAhUrl(ahUrl); } advHello.setAhType("on".equals(ahType)?1:2); // 分割字符串 String[] time = ahStartAndEndTime.split(" - "); advHello.setAhStartTime(KitUtil.stringToData(time[0],"yyyy-MM-dd HH:mm:ss")); advHello.setAhEndTime(KitUtil.stringToData(time[1],"yyyy-MM-dd HH:mm:ss")); advHello.setAhTime(new Date()); // 保存并返回 return JSONObject.toJSON(advHelloService.save(advHello)==1 ? KitUtil.returnMap("200",StaticFinalVar.ADD_OK) : KitUtil.returnMap("101",StaticFinalVar.ADD_ERR)); } ``` - 第八步:实现删除方法 ``` /** * 删除 * @param request * @return * @throws Exception */ @RequestMapping(value = "/del", method = RequestMethod.POST) @ResponseBody public Object del(HttpServletRequest request) throws Exception{ log.info("APP首次登录幻灯片 》 添加 》 删除"); String id = request.getParameter("id"); int i = advHelloService.deleteByUUId(id); return i==1?KitUtil.returnMap("200",StaticFinalVar.DEL_OK):KitUtil.returnMap("101",StaticFinalVar.DEL_ERR); } ``` - 第九步:实现修改弹窗跳转方法 ``` /** * 修改前的查询 * @param request * @return * @throws Exception */ @RequestMapping(value = "/goUpdate", method = RequestMethod.GET) public ModelAndView goUpdate(HttpServletRequest request) throws Exception{ String id = request.getParameter("id"); AdvHello advHello = advHelloService.queryByUUID(id); ModelAndView mv = new ModelAndView(); mv.setViewName("/admin/adv_hello/update"); mv.addObject("kitModel",advHello); return mv; } ``` > `update.jsp`页面跟之前的`add.jsp`是一样的,对一个`input` 隐藏域存放数据的唯一 `id` 即可,当然我们需要返回将放回的数据用`EL`表达式渲染 - 第十步:实现修改提交方法,这里其实更添加的方法也是差不多的 ``` /** * 修改 * @param request * @return * @throws Exception */ @RequestMapping(value = "/update", method = RequestMethod.POST) @ResponseBody public Object update(HttpServletRequest request) throws Exception{ // 取值 String ahId = request.getParameter("ahId"); ... // 封装对象 AdvHello advHello = new AdvHello(); advHello.setAhId(ahId);// 这里要传刚刚获取的唯一id ... // 修改保存并返回参数 return JSONObject.toJSON(advHelloService.updateSelective(advHello)==1 ? KitUtil.returnMap("200",StaticFinalVar.UPDATE_OK) : KitUtil.returnMap("101",StaticFinalVar.UPDATE_ERR)); } ``` --- #### 反馈交流QQ群:696279396 #### 赞助 ![](https://box.kancloud.cn/e49c441e59a5c0981c0de2e9bb0871fd_600x500.png)