为什么优先开发菜单,而不是优先开发管理员?查看一下程序草图就明白,还有一个重点就是,管理员需要添加图片,而我还没有封装上传工具及上传目标。
一、添加路由
在根目录下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测试及开发角色控制。