thinkphp5 之 菜单管理

来源:互联网 发布:马克笔淘宝网 编辑:程序博客网 时间:2024/06/10 14:54

就我个人而言,并不喜欢把相关菜单写死在页面中,我一直是把后台的相关管理命令菜单写入数据,然后缓存在服务器上来,这样修改时比较方便

好的直接上代码


在菜单的列表页面,因为要显示菜单的上下级关系,所以用了树状显示(我是用PHP来实现的,可换成JS),代码如下

    // 菜单首页    public function index()    {        $result = zcache('menu');        $tree = new \zzcms\util\Tree();        $tree->icon = ['   │ ', '   ├─ ', '   └─ '];        $tree->nbsp = '   ';        foreach ($result as $r) {            $r['str_manage'] = '<div class="layui-btn-group"><a class="layui-btn layui-btn-normal publish" data-url="' . url("publish", array("id" => $r['id'], 'menuid' => $this->menuid)) . '">修改</a>';            $r['str_manage'] .= '<a class="layui-btn layui-btn-danger delete" data-id="' . $r['id'] . '">删除</a></div>';            $r['display'] = $r['display'] ? "<i class=\"layui-icon icon_style\"></i> " : "<i class=\"layui-icon icon_style\">ဇ</i> ";            $array [] = $r;        }        $tree->init($array);        $str = "<tr id='tr\$id'>                    <td><input name='listorders[\$id]' type='text' size='1' value='\$listorder' class='layui-input'></td>                    <td>\$id</td>                    <td>\$spacer\$name</td>                    <td>\$controller/\$action</td>                    <td>\$display</td>                    <td>\$str_manage</td>                 </tr>";        $categorys = $tree->get_tree(0, $str);        $this->assign("categorys", $categorys);        return $this->fetch();    }


添加修改菜单代码如下:

// 添加菜单    public function publish()    {        if ($this->request->isPost()) {            $post = $this->request->param();            if (empty($post)) {               $this->error('数据不能为空');            }            //验证  唯一规则: 表名,字段名,排除主键值,主键名            $validate = new \think\Validate([                ['name', 'require', '名称不能为空'],                ['app', 'require', '模块名不能为空'],                ['controller', 'require', '文件名不能为空'],                ['action', 'require', '方法名不能为空'],            ]);            //验证数据合法性            if (!$validate->check($post)) {                $this->error('提交失败:' . $validate->getError());            }            $id = isset($post['id']) ? intval($post['id']) : 0;            if ($id < 1) {                $status = $this->model->addData($post);            } else {                $status = $this->model->editData($post);            }            if ($status) {                $this->success('操作成功', url('index'));            } else {                $this->error($this->model->getError());            }        } else {            $id = $this->request->has('id') ? $this->request->param('id', 0, 'intval') : 0;            $info = [];            if ($id > 0) {                $info = Db::name('menu')->find($id);            } else {                $info['parentid'] = 0;            }            $menuCache = zcache('menu');            foreach ($menuCache as $item) {                $item['selected'] = $item['id'] == $info['parentid'] ? 'selected' : '';                $array [] = $item;            }            unset($menuCache);            $str = "<option value='\$id' \$selected>\$spacer \$name</option>";            $tree = new \zzcms\util\Tree();            $tree->init($array);            $info['select_categorys'] = $tree->get_tree(0, $str);            $this->assign($info);            return $this->fetch();        }    }


删除菜单代码如下


 // 删除    public function delete()    {        $id = $this->request->has('id') ? $this->request->param('id', 0, 'intval') : 0;        if ($id < 1) {            return $this->error("ID非法!");        }        if ($this->model->deleteData($id)) {            return $this->success("删除成功!");        } else {            return $this->error($this->model->getError());        }    }


至此,主要的PHP代码已完成,当然还包括其他功能,如:排序,生成菜单,完整代码如下

menu.php

<?php// +----------------------------------------------------------------------// | ZZCMS 菜单管理   QQ:5404172// +----------------------------------------------------------------------namespace zzcms\admin\controller;use zzcms\common\controller\Admin;use \think\Loader;use \think\Db;class Menu extends Admin{    protected $model;    protected function _initialize()    {        parent::_initialize();        $this->model = Loader::model('admin/Menu');    }    // 菜单首页    public function index()    {        $result = zcache('menu');        $tree = new \zzcms\util\Tree();        $tree->icon = ['   │ ', '   ├─ ', '   └─ '];        $tree->nbsp = '   ';        foreach ($result as $r) {            $r['str_manage'] = '<div class="layui-btn-group"><a class="layui-btn layui-btn-normal publish" data-url="' . url("publish", array("id" => $r['id'], 'menuid' => $this->menuid)) . '">修改</a>';            $r['str_manage'] .= '<a class="layui-btn layui-btn-danger delete" data-id="' . $r['id'] . '">删除</a></div>';            $r['display'] = $r['display'] ? "<i class=\"layui-icon icon_style\"></i> " : "<i class=\"layui-icon icon_style\">ဇ</i> ";            $array [] = $r;        }        $tree->init($array);        $str = "<tr id='tr\$id'>                    <td><input name='listorders[\$id]' type='text' size='1' value='\$listorder' class='layui-input'></td>                    <td>\$id</td>                    <td>\$spacer\$name</td>                    <td>\$controller/\$action</td>                    <td>\$display</td>                    <td>\$str_manage</td>                 </tr>";        $categorys = $tree->get_tree(0, $str);        $this->assign("categorys", $categorys);        return $this->fetch();    }    // 添加菜单    public function publish()    {        if ($this->request->isPost()) {            $post = $this->request->param();            if (empty($post)) {               $this->error('数据不能为空');            }            //验证  唯一规则: 表名,字段名,排除主键值,主键名            $validate = new \think\Validate([                ['name', 'require', '名称不能为空'],                ['app', 'require', '模块名不能为空'],                ['controller', 'require', '文件名不能为空'],                ['action', 'require', '方法名不能为空'],            ]);            //验证数据合法性            if (!$validate->check($post)) {                $this->error('提交失败:' . $validate->getError());            }            $id = isset($post['id']) ? intval($post['id']) : 0;            if ($id < 1) {                $status = $this->model->addData($post);            } else {                $status = $this->model->editData($post);            }            if ($status) {                $this->success('操作成功', url('index'));            } else {                $this->error($this->model->getError());            }        } else {            $id = $this->request->has('id') ? $this->request->param('id', 0, 'intval') : 0;            $info = [];            if ($id > 0) {                $info = Db::name('menu')->find($id);            } else {                $info['parentid'] = 0;            }            $menuCache = zcache('menu');            foreach ($menuCache as $item) {                $item['selected'] = $item['id'] == $info['parentid'] ? 'selected' : '';                $array [] = $item;            }            unset($menuCache);            $str = "<option value='\$id' \$selected>\$spacer \$name</option>";            $tree = new \zzcms\util\Tree();            $tree->init($array);            $info['select_categorys'] = $tree->get_tree(0, $str);            $this->assign($info);            return $this->fetch();        }    }    // 删除    public function delete()    {        $id = $this->request->has('id') ? $this->request->param('id', 0, 'intval') : 0;        if ($id < 1) {            return $this->error("ID非法!");        }        if ($this->model->deleteData($id)) {            return $this->success("删除成功!");        } else {            return $this->error($this->model->getError());        }    }    /**     * 排序     */    public function listorder()    {        if ($this->request->isPost()) {            $post = $this->request->post();            foreach ($post['listorders'] as $id => $listorder) {                $this->model->where(['id' => $id])->setField(['listorder' => intval($listorder)]);            }            $this->success('设置成功', url('index'));        } else {            $this->redirect(url('index'));        }    }    /**     * 根据 menuid 获取后台左侧下级菜单     */    public function left_menu()    {        $menuid = $this->request->has('menuid') ? $this->request->param('menuid', 0, 'intval') : 0;// 获取父级menuid        if ($menuid < 1) {            $this->error('菜单ID不能为空');        }        return $this->menu_childlist($menuid);    }    /**     * 获取下属菜单     * @param $menuid     * @return array     */    public function menu_childlist($menuid)    {        // 菜单缓存        $menulist = zcache('menu');        //生成树形结构        $menu_tree = $this->get_trees($menulist);        $menulist = isset($menu_tree[$menuid]) ? $menu_tree[$menuid] : '';        if (empty($menulist)) {            return ['code' => 0, 'msg' => '菜单不存在'];        }        //所有下属菜单列表        $childlists = isset($menulist['child']) ? $menulist['child'] : '';        if (empty($childlists)) {            return ['code' => 0, 'msg' => '不存在下属菜单'];        }        $str = '';        $i = 0;        foreach ($childlists as $item) {            if ($i == 0) {                $str .= '<li class="layui-nav-item layui-nav-itemed">';            } else {                $str .= '<li class="layui-nav-item">';            }            if (isset($item['child'])) {                $str .= '<a class="" href="javascript:;">' . $item['name'] . '</a>';                $str .= '<dl class="layui-nav-child">';                foreach ($item['child'] as $childinfo) {                    $mid = $childinfo['id'];                    $param = ['menuid' => $mid];                    //参数处理                    if (!empty($childinfo['data'])) {                        $params = explode('=', $childinfo['data']);                        $param[$params[0]] = $params[1];                    }                    $str .= '<dd class=""><a data-url="' . url($childinfo['app'] . '/' . $childinfo['controller'] . '/' . $childinfo['action'], $param) . '">' . $childinfo['name'] . '</a></dd>';                }                $str .= '</dl>';            } else {                $mid = $item['id'];                $param = ['menuid' => $mid];                //参数处理                if (!empty($item['data'])) {                    $params = explode('=', $item['data']);                    $param[$params[0]] = $params[1];                }                $str .= '<a data-url="' . url($item['app'] . '/' . $item['controller'] . '/' . $item['action'], $param) . '">' . $item['name'] . '</a>';            }            $str .= '</li>';            $i++;        }        return ['code' => 1, 'msg' => $str];    }    /*     * 格式化树形结构     */    function get_trees($items)    {        $tree = []; //初始化格式化好的树        foreach ($items as $item) {            $mid = (int)$item['id'];            if (isset($items[$item['parentid']])) {                $items[$item['parentid']]['child'][$mid] = &$items[$mid];            } else {                $tree[$mid] = &$items[$mid];            }        }        return $tree;    }}


模型代码  menu.php


<?phpnamespace zzcms\admin\model;/** * 菜单 * Class Menu * @package zzcms\common\model
 * QQ:5404172
 */class Menu extends \think\Model{    protected $name = 'menu';    protected $pk = 'id';    protected $childnode = [];    // 初始化    protected function initialize()    {        parent::initialize();    }    /**添加     * @param $data     * @return bool     */    public function addData(array $data)    {        $id = $this->isUpdate(false)->allowField(true)->save($data);        if ($id) {            $this->create_cache();            return $id;        } else {            $this->error = '添加失败!';            return false;        }    }    /**     * 编辑     *     * @param type $data     *            提交数据     * @return boolean     */    public function editData($data, $id = 0)    {        if (empty ($data)) {            $this->error = '数据不能为空!';            return false;        }        $id = $id ? $id : (int)$data [$this->pk];        if (!$id) {            $this->error = 'ID不能为空!';            return false;        }        $info = $this->get($id);        if (empty ($info)) {            $this->error = '信息不存在!';            return false;        }        $data [$this->pk] = $id;        if (false !== $this->isUpdate(true)->allowField(true)->save($data)) {            $this->create_cache();            return $id;        } else {            $this->error = '更新失败!';            return false;        }    }    /**删除     * @param $id     * @return bool     */    public function deleteData($id)    {        if (empty ($id)) {            $this->error = 'ID不存在!';            return false;        }        $info = $this->where([$this->pk => $id])->find();        if (empty($info)) {            $this->error = '您要删除的信息不存在!';            return false;        }        //查询其下属所有分类        $deleteid = $this->get_childnode($id);        if (count($deleteid) > 1) {            $this->error = '此菜单下有子类,不允许删除!';            return false;        }        $status = $this->where(['id' => $id])->delete();        if (false === $status) {            $this->error = '删除信息错误!';            return false;        } else {            $this->create_cache();            return true;        }    }    /**     * 更新缓存     *     * @param type $data     * @return type     */    public function create_cache($options = ['type' => 'all'])    {        $list = $this->order('listorder asc')->select();        if (empty($list)) {            return false;        }        //转换为数组        $list = collection($list)->toArray();        $cache = $rootMenu = [];        foreach ($list as $item) {            $pk = (int)$item['id'];            $cache[$pk] = $item;            if ($item['parentid'] == 0 && $item['display'] == 1) {                $rootMenu[$pk] = $item;            }        }        unset($list);        cache('menu', $cache);        cache('root_menu', $rootMenu);        //默认返回所有菜单        return $options['type'] == 'all' ? $cache : $rootMenu;    }    /**     * 递归查询下属菜单     * @param $id   要查询的菜单ID     * @return array     */    private function get_childnode($id)    {        $this->childnode[] = intval($id);        $list = $this->where(['parentid' => $id])->select();        if (is_array($list)) {            foreach ($list as $item) {                $this->get_childnode($item['id']);            }        }        return $this->childnode;    }}