Bootstrap

群控系统服务端开发模式-应用开发-菜单功能开发

        为什么优先开发菜单,而不是优先开发管理员?查看一下程序草图就明白,还有一个重点就是,管理员需要添加图片,而我还没有封装上传工具及上传目标。

一、添加路由

        在根目录下route文件夹下的app.php文件里面,添加如下代码

Route::post('menu/get_all','permission.Menu/getAll');// 获取所有菜单数据
Route::post('menu/get_info','permission.Menu/getInfo');// 获取单个菜单数据
Route::post('menu/save_info','permission.Menu/saveInfo');// 保存菜单数据
Route::post('menu/status_info','permission.Menu/statusInfo');// 启禁用菜单数据
Route::post('menu/delete_info','permission.Menu/deleteInfo');// 删除菜单数据

二、添加控制层管理

        在根目录下app文件夹下controller文件夹中创建文件夹并命名为permission,然后在permission文件夹中创建控制器并命名为Menu,然后让Menu继承Base总控制,最后优先开发菜单数据层管理,也就是本文中写到的《添加数据层管理》。代码如下:

<?php
/**
 * 菜单控制管理
 * User: 龙哥·三年风水
 * Date: 2024/10/31
 * Time: 9:36
 */
namespace app\controller\permission;
use app\controller\Base;
use app\model\permission\Menu as MenuModel;
class Menu extends Base
{

}

        1、获取所有数据方法

public function getAll(){
    $list = MenuModel::getAll([],'id,menuname,pid,title,path,component,icon,redirect,always_show,is_hidden,is_cache,is_icon,is_menu,button_type,status','sort DESC,id DESC');
    return succ(Tree::list_to_tree($list, 0, 'id', 'pid', 'children'));
}

        2、单个菜单数据方法

public function getInfo(){
    $id = $this->request->param('id', 0);
    if(empty($id))return err('主键参数必须上传');
    $data = MenuModel::dataFind(['id' => $id], 'id,menuname,pid,title,path,component,icon,redirect,always_show,is_hidden,is_cache,is_icon,is_menu,button_type,sort,status', true);
    return succ($data);
}

        3、保存菜单数据方法

                优先开发验证层管理,也就是本文中第四节所说的《添加验证层管理》。

    //保存菜单数据
    public function saveInfo(){
        $param = $this->request->param();
        $validate = new \app\validate\permission\Menu;
        if (!$validate->check($param)) return err($validate->getError());
        $data['menuname'] = $param['menuname'];
        $data['title'] = $param['title'];
        $data['path'] = $param['path'];
        $data['component'] = $param['component'];
        $data['icon'] = $param['icon'];
        $data['redirect'] = $param['redirect'];
        $data['always_show'] = (int)$param['always_show'];
        $data['is_hidden'] = (int)$param['is_hidden'];
        $data['is_cache'] = (int)$param['is_menu'] === 1 ? (int)$param['is_cache'] : 0;
        $data['is_icon'] = (int)$param['is_menu'] === 1 ? (int)$param['is_icon'] : 0;
        $data['is_menu'] = (int)$param['is_menu'];
        $data['button_type'] = (int)$param['button_type'];
        $data['sort'] = (int)$param['sort'];
        $data['status'] = (int)$param['status'];
        $data['update_time'] = date('Y-m-d H:i:s', time());
        if (empty($param['id']))$data['create_time'] = date('Y-m-d H:i:s', time());
        if (is_array($param['pid'])) {
            $data['pid'] = $param['pid'][count($param['pid']) - 1];
        } else {
            $data['pid'] = $param['pid'];
        }
        MenuModel::dataSave($data, empty($param['id']) ? [] : ['id' => $param['id']]);
        return succ('操作成功');
    }

        4、启禁用数据方法

    public function statusInfo(){
        $param = $this->request->param();
        if (!is_array($param['id']) || count($param['id']) === 0) return err('唯一编号必须是数组且至少需要一个');
        if (!in_array($param['status'],[0,1])) return err('状态必须选择一种');
        MenuModel::toStatus($param['id'],$param['status']);
        return succ('操作成功');
    }

        5、删除数据方法

    public function deleteInfo(){
        $id = $this->request->param('id');
        if (!is_array($id) || count($id) === 0) return err('请上传参数');
        MenuModel::dataDetele($id);
        return succ('操作成功');
    }

三、添加数据层管理

        在根目录下app文件夹下的model文件夹中创建管理层文件夹并命名为permission,然后在permission文件夹下创建角色数据控制器并命名为Menu,然后继承Tools验证工具集。代码如下:

<?php
/**
 * 菜单数据管理
 * User: 龙哥·三年风水
 * Date: 2024/10/31
 * Time: 9:43
 */
namespace app\model\permission;
use app\model\Tools;
class Menu extends Tools
{
    protected static $name = 'permission_menu';
    protected static $connection = 'mysql';
    protected $pk = 'id';

    //获取所有列表
    public static function getAll($where = [], $field = '*', $order = 'id DESC')
    {
        return self::dataAlls(self::$name, $where, $field, $order, [], self::$connection);
    }

    //获取单条数据
    public static function dataFind($where = [], $field, $findType = true)
    {
        return self::dataFinds(self::$name, $where, $field, $findType, self::$connection);
    }

    //保存数据
    public static function dataSave($data, $where = [])
    {
        return self::dataSaves(self::$name, $data, $where, self::$connection);
    }

    //启禁用数据
    public static function toStatus($ids,$status){
        foreach($ids as $k => $v){
            self::recursions(self::$name,['id' => $v],'pid', self::$connection,$ids);
        }
        return self::dataSaves(self::$name, ['status' => $status], [['id','in',$ids]], self::$connection);
    }

    //删除数据
    public static function dataDetele($where)
    {
        return self::recursionDeteles(self::$name, $where, 'pid', self::$connection); // TODO: Change the autogenerated stub
    }
}

四、添加验证层管理

        在根目录下app文件夹下的validate文件夹中创建管理层文件夹并命名为permission,然后在permission文件夹下创建菜单验证控制器并命名为Menu,然后继承Tools验证工具集。代码如下:

<?php
/**
 * 菜单验证管理
 * User: 龙哥·三年风水
 * Date: 2024/10/31
 * Time: 10:16
 */
namespace app\validate\permission;
use app\validate\Tools;
class Menu extends Tools
{
    protected $rule = [
        'id' => 'require|number',
        'menuname' => 'requireIf:is_menu,1|length:1,40|alpha|unique:permission_menu',
        'pid' => 'require',
        'title' => 'require|length:1,30',
        'path' => 'requireIf:is_menu,1|length:1,100',
        'component' => 'requireIf:is_menu,1|length:1,100',
        'icon' => 'requireIf:is_menu,1|length:1,100',
        'redirect'  =>  'length:1,100',
        'button_type' => 'require|checkButtonType'
    ];
    protected $message = [
        'id.require' => '编号必须填写',
        'id.number' => '编号必须是数字类型',
        'menuname.requireIf' => '规则唯一标识必须填写',
        'menuname.length' => '规则唯一标识必须是1到40位',
        'menuname.alpha' => '规则唯一标识必须是纯字母',
        'menuname.unique' => '路由名称必须唯一',
        'pid.require' => '父类必须选择',
        'title.require' => '路由名称必须填写',
        'title.length' => '路由名称必须是1到30位',
        'path.requireIf' => '路径必须填写',
        'path.length' => '路径的长度必须是1到30位',
        'component.requireIf' => '组件地址必须填写',
        'component.length' => '组件地址必须是1到100位',
        'icon.requireIf' => '图标必须填写',
        'icon.length' => '图标必须是1到100位',
        'redirect.length' => '重定向地址必须是1到100位',
        'button_type.require' => '按钮类型必须选择',
    ];
    

    /**
     * 按钮类型验证
     * @ param $value
     * @ param string $rule
     * @ param string $data
     * @ param string $field
     * @ return bool|string
     */

    protected function checkButtonType($value, $rule = '', $data = '', $field = ''){
        if ($data['is_menu'] === 0) {
            if (in_array($value, [1, 2, 3, 4, 5, 6, 7, 8, 9])) {
                return true;
            } else {
                return '按钮类型必须是1到9之间';
            }
        } else {
            return true;
        }
    }
}

五、树形结构工具开发

        在根目录下extend文件夹下Other文件夹中创建树形结构工具并命名为Tree。代码如下:

<?php
/**
 * 树形结构工具
 * User: 龙哥·三年风水
 * Date: 2024/10/31
 * Time: 9:53
 */
namespace Other;
class Tree
{

    /**
     * 格式化分类,生成多维数组的树
     * @ param $list 数组
     * @ param int $root 指定根节点
     * @ param string $pk 主键标识
     * @ param string $pid 父级标识
     * @ param string $child 子级标识
     * @ return array 返回整理后的树形结构数组
     */

    public static function list_to_tree($list, $root = 0, $pk = 'id', $pid = 'parentId', $child = 'child'){
        // 创建Tree
        $tree = array();
        if (is_array($list)) {
            // 创建基于主键的数组引用
            $refer = array();
            foreach ($list as $key => $data) {
                $refer[$data[$pk]] =& $list[$key];
            }
            foreach ($list as $key => $data) {
                // 判断是否存在parent
                $parentId = $data[$pid];
                if ($root == $parentId) {
                    $tree[] =& $list[$key];
                } else {
                    if (isset($refer[$parentId])) {
                        $parent =& $refer[$parentId];
                        $parent[$child][] =& $list[$key];
                    }
                }
            }
        }
        return $tree;
    }
}

六、提前说明 

        到处,整个菜单api控制已经开发完毕。下一步采用apipost测试及开发角色控制。

;