You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

323 lines
10 KiB
PHP

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
// +----------------------------------------------------------------------
// | 海豚PHP框架 [ DolphinPHP ]
// +----------------------------------------------------------------------
// | 版权所有 2016~2017 河源市卓锐科技有限公司 [ http://www.zrthink.com ]
// +----------------------------------------------------------------------
// | 官方网站: http://dolphinphp.com
// +----------------------------------------------------------------------
// | 开源协议 ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
namespace app\admin\model;
use app\user\model\Role as RoleModel;
use think\Model;
use think\Exception;
use util\Tree;
/**
* 节点模型
* @package app\admin\model
*/
class Menu extends Model
{
// 设置当前模型对应的完整数据表名称
protected $table = '__ADMIN_MENU__';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
// 将节点url转为小写
public function setUrlValueAttr($value)
{
return strtolower(trim($value));
}
/**
* 递归修改所属模型
* @param int $id 父级节点id
* @param string $module 模型名称
* @author 蔡伟明 <314013107@qq.com>
* @return bool
*/
public static function changeModule($id = 0, $module = '')
{
if ($id > 0) {
$ids = self::where('pid', $id)->column('id');
if ($ids) {
foreach ($ids as $id) {
self::where('id', $id)->setField('module', $module);
self::changeModule($id, $module);
}
}
}
return true;
}
/**
* 获取树形节点
* @param int $id 需要隐藏的节点id
* @param string $default 默认第一个节点项默认为“顶级节点”如果为false则不显示也可传入其他名称
* @param string $module 模型名
* @author 蔡伟明 <314013107@qq.com>
* @return mixed
*/
public static function getMenuTree($id = 0, $default = '', $module = '')
{
$result[0] = '顶级节点';
$where = [
['status', 'egt', 0]
];
if ($module != '') {
$where[] = ['module', '=', $module];
}
// 排除指定节点及其子节点
if ($id !== 0) {
$hide_ids = array_merge([$id], self::getChildsId($id));
$where[] = ['id', 'not in', $hide_ids];
}
// 获取节点
$menus = Tree::toList(self::where($where)->order('pid,id')->column('id,pid,title'));
foreach ($menus as $menu) {
$result[$menu['id']] = $menu['title_display'];
}
// 设置默认节点项标题
if ($default != '') {
$result[0] = $default;
}
// 隐藏默认节点项
if ($default === false) {
unset($result[0]);
}
return $result;
}
/**
* 获取顶部节点
* @param string $max 最多返回多少个
* @param string $cache_tag 缓存标签
* @author 蔡伟明 <314013107@qq.com>
* @return array
*/
public static function getTopMenu($max = '', $cache_tag = '')
{
$cache_tag .= '_role_'.session('user_auth.role');
$menus = cache($cache_tag);
if (!$menus) {
// 非开发模式,只显示可以显示的菜单
if (config('develop_mode') == 0) {
$map['online_hide'] = 0;
}
$map['status'] = 1;
$map['pid'] = 0;
$list_menu = self::where($map)->order('sort,id')->column('id,pid,module,title,url_value,url_type,url_target,icon,params');
$i = 0;
$menus = [];
foreach ($list_menu as $key => &$menu) {
if ($max != '' && $i >= $max) {
break;
}
// 没有访问权限的节点不显示
if (!RoleModel::checkAuth($menu['id'])) {
continue;
}
if ($menu['url_value'] != '' && ($menu['url_type'] == 'module_admin' || $menu['url_type'] == 'module_home')) {
$url = explode('/', $menu['url_value']);
$menu['controller'] = $url[1];
$menu['action'] = $url[2];
$menu['url_value'] = $menu['url_type'] == 'module_admin' ? admin_url($menu['url_value'], $menu['params']) : home_url($menu['url_value'], $menu['params']);
}
$menus[$key] = $menu;
$i++;
}
// 非开发模式,缓存菜单
if (config('develop_mode') == 0) {
cache($cache_tag, $menus);
}
}
return $menus;
}
/**
* 获取侧栏节点
* @param string $id 模块id
* @param string $module 模块名
* @param string $controller 控制器名
* @author 蔡伟明 <314013107@qq.com>
* @return array|mixed
*/
public static function getSidebarMenu($id = '', $module = '', $controller = '')
{
$module = $module == '' ? request()->module() : $module;
$controller = $controller == '' ? request()->controller() : $controller;
$cache_tag = strtolower('_sidebar_menus_' . $module . '_' . $controller).'_role_'.session('user_auth.role');
$menus = cache($cache_tag);
if (!$menus) {
// 获取当前节点地址
$location = self::getLocation($id);
// 当前顶级节点id
$top_id = $location[0]['id'];
// 获取顶级节点下的所有节点
$map = [
'status' => 1
];
// 非开发模式,只显示可以显示的菜单
if (config('develop_mode') == 0) {
$map['online_hide'] = 0;
}
$menus = self::where($map)->order('sort,id')->column('id,pid,module,title,url_value,url_type,url_target,icon,params');
// 解析模块链接
foreach ($menus as $key => &$menu) {
// 没有访问权限的节点不显示
if (!RoleModel::checkAuth($menu['id'])) {
unset($menus[$key]);
continue;
}
if ($menu['url_value'] != '' && ($menu['url_type'] == 'module_admin' || $menu['url_type'] == 'module_home')) {
$menu['url_value'] = $menu['url_type'] == 'module_admin' ? admin_url($menu['url_value'], $menu['params']) : home_url($menu['url_value'], $menu['params']);
}
}
$menus = Tree::toLayer($menus, $top_id, 2);
// 非开发模式,缓存菜单
if (config('develop_mode') == 0) {
cache($cache_tag, $menus);
}
}
return $menus;
}
/**
* 获取指定节点ID的位置
* @param string $id 节点id如果没有指定则取当前节点id
* @param bool $del_last_url 是否删除最后一个节点的url地址
* @param bool $check 检查节点是否存在,不存在则抛出错误
* @author 蔡伟明 <314013107@qq.com>
* @return array
* @throws \think\Exception
*/
public static function getLocation($id = '', $del_last_url = false, $check = true)
{
$model = request()->module();
$controller = request()->controller();
$action = request()->action();
if ($id != '') {
$cache_name = 'location_menu_'.$id;
} else {
$cache_name = 'location_'.$model.'_'.$controller.'_'.$action;
}
$location = cache($cache_name);
if (!$location) {
$map = [
['pid', '<>', 0],
['url_value', '=', strtolower($model.'/'.trim(preg_replace("/[A-Z]/", "_\\0", $controller), "_").'/'.$action)]
];
// 当前操作对应的节点ID
$curr_id = $id == '' ? self::where($map)->value('id') : $id;
// 获取节点ID是所有父级节点
$location = Tree::getParents(self::column('id,pid,title,url_value,params'), $curr_id);
if ($check && empty($location)) {
throw new Exception('获取不到当前节点地址,可能未添加节点', 9001);
}
// 剔除最后一个节点url
if ($del_last_url) {
$location[count($location) - 1]['url_value'] = '';
}
// 非开发模式,缓存菜单
if (config('develop_mode') == 0) {
cache($cache_name, $location);
}
}
return $location;
}
/**
* 根据分组获取节点
* @param string $group 分组名称
* @param bool|string $fields 要返回的字段
* @param array $map 查找条件
* @author 蔡伟明 <314013107@qq.com>
* @return array
*/
public static function getMenusByGroup($group = '', $fields = true, $map = [])
{
$map['module'] = $group;
return self::where($map)->order('sort,id')->column($fields, 'id');
}
/**
* 获取节点分组
* @author 蔡伟明 <314013107@qq.com>
* @return array
*/
public static function getGroup()
{
$map['status'] = 1;
$map['pid'] = 0;
$menus = self::where($map)->order('id,sort')->column('module,title');
return $menus;
}
/**
* 获取所有子节点id
* @param int $pid 父级id
* @author 蔡伟明 <314013107@qq.com>
* @return array
*/
public static function getChildsId($pid = 0)
{
$ids = self::where('pid', $pid)->column('id');
foreach ($ids as $value) {
$ids = array_merge($ids, self::getChildsId($value));
}
return $ids;
}
/**
* 获取所有父节点id
* @param int $id 节点id
* @author 蔡伟明 <314013107@qq.com>
* @return array
*/
public static function getParentsId($id = 0)
{
$pid = self::where('id', $id)->value('pid');
$pids = [];
if ($pid != 0) {
$pids[] = $pid;
$pids = array_merge($pids, self::getParentsId($pid));
}
return $pids;
}
/**
* 根据节点id获取上下级的所有id
* @param int $id 节点id
* @author 蔡伟明 <314013107@qq.com>
* @return array
*/
public static function getLinkIds($id = 0)
{
$childs = self::getChildsId($id);
$parents = self::getParentsId($id);
return array_merge((array)(int)$id, $childs, $parents);
}
}