1、前期准备工作
(1)模板介绍
添加菜单的模板页面
菜单管理首页:
添加菜单页面:
(2)公共类引入介绍
公共函数文件的引入(位置: Application/Admin/Controller/CommonController.class.php)
1)获取登录用户信息
public function getLoginUser() { return session("adminUser"); }
2)判断是否登录
public function isLogin() { $user = $this->getLoginUser(); if($user && is_array($user)) { return true; } return false; }
3)初始化验证用户登录并处理
private function _init() { // 如果已经登录 $isLogin = $this->isLogin(); if(!$isLogin) { // 跳转到登录页面 $this->redirect('/admin.php?c=login'); } return ; }
2、菜单添加
(1)菜单管理首页面添加功能的触发
1)菜单管理首页模板页面处理
<div> <button id="button-add" type="button" class="btn btn-primary dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-plus" aria-hidden="true"></span>添加 </button> </div>
2)添加按钮的url设置(全局)
<script> var SCOPE = { 'add_url' : '/admin.php?c=menu&a=add' } </script>
3)js点击事件处理页面跳转(位置:Public/js/admin/common.js)
菜单添加、文章添加等添加功能的实现方式相同,为提升代码复用性,可通过公共文件
$("#button-add").click(function(){ var url = SCOPE.add_url; window.location.href=url; });
4)将js文件引入到当前项目中(位置:Application/Admin/View/Index/footer.html)
<script src="/Public/js/admin/common.js"></script>
(2)JS获取表单提交的数据
1)添加模板的页面处理(form表单)
2)保存提交数据的url、数据保存成功的自动跳转url设置(全局)
<script> var SCOPE = {
'save_url' : '/admin.php?c=menu&a=add', //数据提交url
'jump_url' : '/admin.php?c=menu' //菜单添加成功跳转url
}
</script>
3)数据请求的触发及处理的逻辑
$("#cms-button-submit").click(function(){
// 获取表单数据并序列化 var data = $("#cms-form").serializeArray(); postData = {};
// 遍历表单数据,并将键名和键值一一对应的保存到postData中 $(data).each(function(i){ postData[this.name] = this.value; }); // 将获取到的数据post给服务器(ajax异步请求) url = SCOPE.save_url; jump_url = SCOPE.jump_url; $.post(url,postData,function(result){ if(result.status == 1) { //成功并跳转 return dialog.success(result.message,jump_url); }else if(result.status == 0) { // 失败 return dialog.error(result.message); } },"JSON"); });
(3)PHP处理数据交互
1)$_POST接收提交数据(Application/Admin/Controller/MenuController.class.php)
public function add() { if ($_POST) { print_r($_POST); //测试打印表单提交过来的数据 } $this->display(); }
2)浏览器验证
3)校验表单提交数据
if(!isset($_POST['name']) || !$_POST['name']) { return show(0,'菜单名不能为空'); } if(!isset($_POST['m']) || !$_POST['m']) { return show(0,'模块名不能为空'); } if(!isset($_POST['c']) || !$_POST['c']) { return show(0,'控制器不能为空'); } if(!isset($_POST['f']) || !$_POST['f']) { return show(0,'方法名不能为空'); }
4)校验通过后将数据插入到menu数据表中(模型层操作数据库)
(位置:Application/Common/Model/MenuModel.class.php)
public function insert($data = array()) { if (!$data || !is_array($data)) { return 0; } return $this->_db->add($data); }
5)执行添加菜单,提示成功
6)查看数据库中菜单记录
select * from cms_menu;
菜单添加成功!
3、菜单列表
(1)添加条件搜索功能
1)模板添加搜索框
<!--搜索表单--> <div class="row"> <form action="/admin.php" method="get"> <div class="input-group"> <span class="input-group-addon">类型</span> <select class="form-control" name="type" > <option value='' >请选择类型</option> <option value="1">后台菜单</option> <option value="0">前端导航</option> </select> <input type="hidden" name="c" value="menu"/> <input type="hidden" name="a" value="index"/> <span class="input-group-btn"> <button id="sub_data" type="submit" class="btn btn-primary"><i class="glyphicon glyphicon-search"></i></button> </span> </div> </form> </div>
2)通过下拉菜单选择的选项的type值,添加查询条件(index方法)
if (isset($_REQUEST['type']) && in_array($_REQUEST['type'], array(0,1))) { $data['type'] = intval($_REQUEST['type']); }
3)点击搜索显示后,保持下拉菜单选择状态(默认会恢复到未选择)
1.将搜索的筛选条件传入模板中 if (isset($_REQUEST['type']) && in_array($_REQUEST['type'], array(0,1))) { $data['type'] = intval($_REQUEST['type']); $this->assign('type', $data['type']); }else{ $this->assign('type', -1); }
2.通过对$data['type']的值进行判断,设置相应的选项为选中状态 <select class="form-control" name="type" > <option value='' >请选择类型</option> <option value="1" <if condition="$type eq 1">selected="selected"</if>>后台菜单</option> <option value="0" <if condition="$type eq 0">selected="selected"</if>>前端导航</option> </select>
4)效果
(2)获取菜单列表
1)根据页码获取当前页菜单记录(标记为未删除)(通过菜单模型Application/Common/Model/MenuModel.class.php)
public function getMenus($data,$page,$pageSize=10) { // 获取未被删除的数据(用status标记记录时候被删除) $data['status'] array('neq', -1); $offset = ($page-1) * $pageSize; $list = $this->_db->where($data)->order('menu_id desc')->limit($offset,$pageSize)->select(); return $list; }
2)获取所有菜单记录条数(标记为未删除)(通过菜单模型Application/Common/Model/MenuModel.class.php)
public function getMenusCount($data = array()) { $data['status'] = array('neq', -1); $menuCount = $this->_db->where($data)->count(); return $list; }
(3)菜单分页功能
1)分页参数设置
2)调用ThinkPHP框架自带的分页类进行分页处理
$res = new \Think\Page($menusCount, $pageSize); $pageRes = $res->show();
框架分页类所在位置如下:ThinkPHP/Library/Think/Page.class.php
3)使用模板引擎,将获取到的数据显示到页面(Application/Admin/Controller/MenuController.class.php)
$this->assign('pageRes', $pageRes); $this->assign('menus', $menus);
4)模板中使用参数显示相应数据(ThinkPHP自带的模板引擎)
<volist name="menus" id="menu"> <tr> <td>{$menu.menu_id}</td> <td>{$menu.name}</td> <td>{$menu.m}</td> <td>{$menu.type}</td> <td>{$menu.status}</td> <td><span class="glyphicon glyphicon-edit" aria-hidden="true" id="cms-edit" attr-id="{$menu.menu_id}"></span> <a href="javascript:void(0)" attr-id="{$menu.menu_id}" id="cms-delete" attr-a="menu" attr-message="删除"><span class="glyphicon glyphicon-remove-circle" aria-hidden="true"></span></a></td> </tr> </volist>
(设置每页显示记录数为3)
5)添加分页导航条
<nav> <ul class="pagination"> {$pageRes} </ul> </nav>
默认显示的样式如下:
首页: 末页:
6)对显示的菜单列表状态和类型进行处理,使更直观
<td>{$menu.type|getMenuType}</td> <td>{$menu.status|getMenuStatus}</td>
添加公共函数(位置:Application/Common/Common/function.php)
function getMenuType($type=''){ return $type == 1 ? "后台菜单" : "前端导航"; } function getMenuStatus($status=''){ if ($status == 0) { $str = "关闭"; }elseif ($status == 1) { $str = "正常"; }elseif ($status == -1) { $stt = "删除"; } return $str; }
以文字形式显示:
4、菜单修改
(1)修改模板添加
1)添加控制器中的edit方法和edit视图模板
public function edit($data) { $this->display(); }
2)通过菜单显示页面编辑功能设置链接,添加传递参数menu_id,通过该id获取该条记录的具体信息,并显示到相应位置
1.edit.html定义url <script> var SCOPE = { 'edit_url' : '/admin.php?c=menu&a=edit' } </script>
2.common.js文件设置url跳转
$('.cms-table #cms-edit').on('click',function(){ var id = $(this).attr('attr-id'); url = SCOPE.edit_url + '&id='+id; window.location.href=url; });
3)通过url传递的id值获取该条记录
public function getMenuById($id) { if(!$id || !is_numeric($id) { return array(); } return $this->_db->where("menu_id=".$id)->find(); }
4)控制器实现功能
public function edit() { $id = $_GET['id']; $menuInfo = D('Menu')->getMenuById($id); $this->assign('menuInfo', $menuInfo); $this->display(); }
5)通过模板引擎将数据分配到编辑菜单表单的相应位置
6)实现修改处理并保存修改到数据库
1.设置修改提交的url和处理完成后自动跳转的url <script> var SCOPE = { save_url' : '/admin.php?c=menu&a=add', 'jump_url' : '/admin.php?c=menu' } </script>
2.add方法的条件判断 if ($_POST['menu_id']) {
// 转到save方法处理更新 return $this->save($_POST); } //修改操作添加该条记录的menu_id, 创建数据时没有该数据项
3.save()处理更新 public function save($data) { $menuId = $data['menu_id']; unset($data['menu_id']); try { $id = D('Menu')->updateMenuById($menuId, $data); if ($id === false) { return show(0,"更新失败"); } return show(1,"更新成功"); }catch (Exception $e) { return show(0,$e->getMessage()); } }
4.菜单模板将数据更新到数据库 public function updateMenuById($id, $data) { if (!$id || !is_numeric($id)) { throw_exception('ID不合法!'); } if (!$data || !is_array($data)) { throw_exception('更新的数据不合法!'); } return $this->_db->where("menu_id=".$id)->save($data); }
7)查看效果
新建一条记录,将其菜单名修改为666
修改成功
自动跳转到菜单首页
5、菜单删除
菜单删除是通过status进行状态标记,进行逻辑上的删除,而并非实际性的删除
(1)删除的js弹出提示
点击删除icon
弹出提示窗口
1)设置删除处理的url
'set_status_url' : '/admin.php?c=menu&a=setStatus'
2)js逻辑
$('.cms-table #singcms-delete').on('click',function(){ var id = $(this).attr('attr-id'); var a = $(this).attr("attr-a"); var message = $(this).attr("attr-message"); var url = SCOPE.set_status_url; data = {}; data['menu_id'] = id; data['status'] = -1; layer.open({ type : 0, title : '是否提交?', btn: ['确定', '取消'], icon : 3, closeBtn : 2, content: "是否确定"+message, scrollbar: true, yes: function(){ // 执行相关跳转 todelete(url, data); } }); });
// 确认删除后执行ajax请求 function todelete(url, data) { $.post( url, data, function(s){ if(s.status == 1) { return dialog.success(s.message,''); // 跳转到相关页面 }else { return dialog.error(s.message); } } ,"JSON"); }
3)ajax请求的后台处理
public function setStatus() { try { if ($_POST) { $id = $_POST['menu_id']; $status = $_POST['status']; $res = D('Menu')->setMenuStatus($id, $status); if ($res) { return show(1, "删除成功"); } } }catch (Exception $e) { return show(0, $e->getMessage()); } return show(0,'没有提交数据,删除失败'); }
4)菜单模块操作数据库更新状态
public function setMenuStatus($id, $status) { if (!$id || !is_numeric($id)) { throw_exception('ID不合法!'); } if (!$status || !is_numeric($status)) { throw_exception('状态不合法!'); } $data['status'] = $status; return $this->_db->where("menu_id=".$id)->save($data); }
5)实现效果(删除成功,并自动跳转)