// +---------------------------------------------------------------------- namespace app\controller\admin; use app\model\addons\Addons; use app\model\auth\AuthGroup; use app\model\auth\Menu; use app\model\module\Model; use think\facade\View; use think\facade\Config; class Base extends \app\controller\Base { // 使用内置PHP模板引擎渲染模板输出 protected $tpl_config = [ 'view_dir_name' => 'view', 'tpl_replace_string' => [ '__static__' => '/static', '__img__' => '/static/admin/images', '__css__' => '/static/admin/css', '__js__' => '/static/admin/js', '__plugins__' => '/static/plugins', '__public__' => '/static/admin', ], ]; protected $middleware = [ '\app\http\middleware\Validate', '\app\http\middleware\Admin', ]; protected function initialize() { $url = $this->request->rule()->getRule(); if (!is_login() and !in_array($url, array('admin/login', 'admin/logout', 'admin/index/verify'))) { $this->redirect('/admin/login'); } if (!in_array($url, array('admin/login', 'admin/logout', 'admin/index/verify'))) { // 是否是超级管理员 define('IS_ROOT', is_administrator()); if (!IS_ROOT && $this->config['admin_allow_ip']) { // 检查IP地址访问 if (!in_array(get_client_ip(), explode(',', $this->config['admin_allow_ip']))) { $this->error('403:禁止访问'); } } // 检测系统权限 if (!IS_ROOT) { $access = $this->accessControl(); if (false === $access) { $this->error('403:禁止访问'); } elseif (null === $access) { $dynamic = $this->checkDynamic(); //检测分类栏目有关的各项动态权限 if ($dynamic === null) { //检测访问权限 if (!$this->checkRule($url, [1,2])) { $this->error('未授权访问!'); } else { // 检测分类及内容有关的各项动态权限 $dynamic = $this->checkDynamic(); if (false === $dynamic) { $this->error('未授权访问!'); } } } elseif ($dynamic === false) { $this->error('未授权访问!'); } } } //菜单设置 $this->getMenu(); View::assign('meta_title', isset($this->data['meta_title']) ? $this->data['meta_title'] : $this->getCurrentTitle()); } } /** * 权限检测 * @param string $rule 检测的规则 * @param string $mode check模式 * @return boolean * @author 朱亚杰 */ final protected function checkRule($rule, $type = AuthRule::rule_url, $mode = 'url') { static $Auth = null; if (!$Auth) { $Auth = new \sent\auth\Auth(); } if (!$Auth->check($rule, session('adminInfo.uid'), $type, $mode)) { return false; } return true; } /** * 检测是否是需要动态判断的权限 * @return boolean|null * 返回true则表示当前访问有权限 * 返回false则表示当前访问无权限 * 返回null,则表示权限不明 * * @author 朱亚杰 */ protected function checkDynamic() { if (IS_ROOT) { return true; //管理员允许访问任何页面 } return null; //不明,需checkRule } /** * action访问控制,在 **登陆成功** 后执行的第一项权限检测任务 * * @return boolean|null 返回值必须使用 `===` 进行判断 * * 返回 **false**, 不允许任何人访问(超管除外) * 返回 **true**, 允许任何管理员访问,无需执行节点权限检测 * 返回 **null**, 需要继续执行节点权限检测决定是否允许访问 * @author 朱亚杰 */ final protected function accessControl() { $allow = []; $deny = []; foreach ($this->config['allow_visit'] as $key => $value) { $allow[] = $value['label']; } foreach ($this->config['deny_visit'] as $key => $value) { $deny[] = $value['label']; } $check = strtolower(str_replace(".", "/", $this->request->controller()) . '/' . $this->request->action()); if (!empty($deny) && in_array_case($check, $deny)) { return false; //非超管禁止访问deny中的方法 } if (!empty($allow) && in_array_case($check, $allow)) { return true; } return null; //需要检测节点权限 } protected function getMenu() { $addon = $this->request->param('addon', false); $hover_url = str_replace(".", "/", strtolower($this->request->controller())); $controller = str_replace(".", "/", strtolower($this->request->controller())); $menu = array( 'main' => array(), 'child' => array(), ); $where['pid'] = 0; $where['hide'] = 0; $where['type'] = 'admin'; if (!config('develop_mode')) { // 是否开发者模式 $where['is_dev'] = 0; } $row = Menu::where($where)->order('sort asc')->field("id,title,url,icon,'' as style")->select(); foreach ($row as $key => $value) { //此处用来做权限判断 if (!IS_ROOT && !$this->checkRule(substr($value['url'], 1), 2, null)) { unset($menu['main'][$value['id']]); continue; //继续循环 } if (false !== strripos($controller, $value['url'])) { $value['style'] = "active"; } $menu['main'][$value['id']] = $value; } // 查找当前子菜单 $pid = Menu::where("pid !=0 AND url like '%{$hover_url}%'")->value('pid'); $id = Menu::where("pid = 0 AND url like '%{$hover_url}%'")->value('id'); $pid = $pid ? $pid : $id; if (strtolower($hover_url) == 'admin/content' || strtolower($hover_url) == 'admin/attribute') { //内容管理菜单 $pid = Menu::where("pid =0 AND url like '%admin/category%'")->value('id'); } if ($addon) { //扩展管理菜单 $pid = Menu::where("pid =0 AND url like '%admin/addons%'")->value('id'); $this->getAddonsMenu(); } if ($pid) { $map['pid'] = $pid; $map['hide'] = 0; $map['type'] = 'admin'; $row = Menu::field("id,title,url,icon,`group`,pid,'' as style")->where($map)->order('sort asc')->select(); foreach ($row as $key => $value) { if (IS_ROOT || $this->checkRule(substr($value['url'], 1), 2, null)) { if ($controller == $value['url']) { $menu['main'][$value['pid']]['style'] = "active"; $value['style'] = "active"; } $menu['child'][$value['group']][] = $value; } } } View::assign('__menu__', $menu); } protected function getContentMenu() { $list = []; $menu = []; $map[] = ['status', '>', 0]; $list = Model::where($map)->field("name,id,title,icon,'' as 'style'")->select(); //判断是否有模型权限 $models = AuthGroup::getAuthModels(session('userInfo.uid')); foreach ($list as $key => $value) { if (IS_ROOT || in_array($value['id'], $models)) { if ('/admin/content/index' == $this->request->url() && input('model_id') == $value['id']) { $value['style'] = "active"; } $value['url'] = "/admin/" . $value['name'] . "/index"; $value['title'] = $value['title'] . "管理"; $value['icon'] = $value['icon'] ? $value['icon'] : 'file'; $menu[] = $value; } } if (!empty($menu)) { View::assign('extend_menu', array('内容管理' => $menu)); } } protected function getAddonsMenu() { $list = array(); $map[] = ['isinstall', '>', 0]; $map[] = ['status', '>', 0]; $list = Addons::where($map)->field("name,id,title,'' as 'style'")->select(); $menu = array(); foreach ($list as $key => $value) { $class = "\\addons\\" . strtolower($value['name']) . "\\controller\\Admin"; if (is_file($this->app->getRootPath() . '/addons/' . strtolower($value['name']) . "/controller/Admin.php")) { $action = get_class_methods($class); $value['url'] = "/addons/" . $value['name'] . "/admin/" . $action[0]; $menu[$key] = $value; } } if (!empty($menu)) { View::assign('extend_menu', array('管理插件' => $menu)); } } }