From 7a4dcf4e4dbdc68573f73aebe606280811dda9d5 Mon Sep 17 00:00:00 2001
From: zhaoxiang <756958008@qq.com>
Date: Sun, 19 May 2019 15:56:22 +0800
Subject: [PATCH] =?UTF-8?q?modified=20=E5=8A=A0=E5=85=A5=E5=90=8E=E7=AB=AF?=
 =?UTF-8?q?=E4=B8=AD=E9=97=B4=E4=BB=B6=E4=BB=A3=E7=A0=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 application/admin/controller/Menu.php         |   2 +-
 application/admin/controller/Miss.php         |   3 +-
 application/http/middleware/AdminAuth.php     |  37 +++++-
 .../http/middleware/AdminPermission.php       | 105 +++++++++++++++++-
 application/http/middleware/AdminResponse.php |   9 +-
 application/util/Tools.php                    |  54 +++++++++
 config/app.php                                |   2 +-
 route/route.php                               |  31 +++---
 8 files changed, 213 insertions(+), 30 deletions(-)

diff --git a/application/admin/controller/Menu.php b/application/admin/controller/Menu.php
index 938b2ec..c94f496 100644
--- a/application/admin/controller/Menu.php
+++ b/application/admin/controller/Menu.php
@@ -23,7 +23,7 @@ class Menu extends Base {
     public function index() {
         $list = (new AdminMenu)->where([])->order('sort', 'ASC')->select();
         $list = Tools::buildArrFromObj($list);
-        $list = formatTree(listToTree($list));
+        $list = Tools::formatTree(Tools::listToTree($list));
 
         return $this->buildSuccess([
             'list' => $list
diff --git a/application/admin/controller/Miss.php b/application/admin/controller/Miss.php
index c4171ae..4f7a164 100644
--- a/application/admin/controller/Miss.php
+++ b/application/admin/controller/Miss.php
@@ -2,11 +2,10 @@
 
 namespace app\admin\controller;
 use app\util\ReturnCode;
-use think\facade\Request;
 
 class Miss extends Base {
     public function index() {
-        if (Request::instance()->isOptions()) {
+        if ($this->request->isOptions()) {
             return $this->buildSuccess([]);
         } else {
             return $this->buildFailed(ReturnCode::INVALID, '接口地址异常', []);
diff --git a/application/http/middleware/AdminAuth.php b/application/http/middleware/AdminAuth.php
index fae9399..f231365 100644
--- a/application/http/middleware/AdminAuth.php
+++ b/application/http/middleware/AdminAuth.php
@@ -2,9 +2,38 @@
 
 namespace app\http\middleware;
 
-class AdminAuth
-{
-    public function handle($request, \Closure $next)
-    {
+use app\util\ReturnCode;
+
+class AdminAuth {
+
+    /**
+     * ApiAuth鉴权
+     * @param \think\facade\Request $request
+     * @param \Closure $next
+     * @return mixed|\think\response\Json
+     * @author zhaoxiang <zhaoxiang051405@gmail.com>
+     */
+    public function handle($request, \Closure $next) {
+        $header = config('apiadmin.CROSS_DOMAIN');
+        $ApiAuth = $request->header('ApiAuth', '');
+        if ($ApiAuth) {
+            $userInfo = cache('Login:' . $ApiAuth);
+            $userInfo = json_decode($userInfo, true);
+            if (!$userInfo || !isset($userInfo['id'])) {
+                return json([
+                    'code' => ReturnCode::AUTH_ERROR,
+                    'msg'  => 'ApiAuth不匹配',
+                    'data' => []
+                ])->header($header);
+            }
+
+            return $next($request);
+        } else {
+            return json([
+                'code' => ReturnCode::AUTH_ERROR,
+                'msg'  => '缺少ApiAuth',
+                'data' => []
+            ])->header($header);
+        }
     }
 }
diff --git a/application/http/middleware/AdminPermission.php b/application/http/middleware/AdminPermission.php
index 1259ea2..e73ba68 100644
--- a/application/http/middleware/AdminPermission.php
+++ b/application/http/middleware/AdminPermission.php
@@ -2,9 +2,106 @@
 
 namespace app\http\middleware;
 
-class AdminPermission
-{
-    public function handle($request, \Closure $next)
-    {
+use app\model\AdminAuthGroup;
+use app\model\AdminAuthGroupAccess;
+use app\model\AdminAuthRule;
+use app\util\ReturnCode;
+use app\util\Tools;
+
+class AdminPermission {
+
+    /**
+     * 用户权限检测
+     * @param \think\facade\Request $request
+     * @param \Closure $next
+     * @return mixed|\think\response\Json
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     * @author zhaoxiang <zhaoxiang051405@gmail.com>
+     */
+    public function handle($request, \Closure $next) {
+        $ApiAuth = $request->header('ApiAuth');
+        $userInfo = cache('Login:' . $ApiAuth);
+
+        if (!$userInfo) {
+            return json([
+                'code' => ReturnCode::INVALID,
+                'msg'  => '非常抱歉,您的登录状态已丢失或已过期!',
+                'data' => []
+            ])->header(config('apiAdmin.CROSS_DOMAIN'));
+        }
+
+        $userInfo = json_decode($userInfo, true);
+        if (!$this->checkAuth($userInfo['id'], $request->path())) {
+            return json([
+                'code' => ReturnCode::INVALID,
+                'msg'  => '非常抱歉,您没有权限这么做!',
+                'data' => []
+            ])->header(config('apiAdmin.CROSS_DOMAIN'));
+        }
+
+        return $next($request);
     }
+
+    /**
+     * 检测用户权限
+     * @param $uid
+     * @param $route
+     * @return bool
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     * @author zhaoxiang <zhaoxiang051405@gmail.com>
+     */
+    private function checkAuth($uid, $route) {
+        $isSupper = Tools::isAdministrator($uid);
+        if (!$isSupper) {
+            $rules = $this->getAuth($uid);
+
+            return in_array($route, $rules);
+        } else {
+            return true;
+        }
+
+    }
+
+    /**
+     * 根据用户ID获取全部权限节点
+     * @param $uid
+     * @return array
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\ModelNotFoundException
+     * @throws \think\exception\DbException
+     * @author zhaoxiang <zhaoxiang051405@gmail.com>
+     */
+    private function getAuth($uid) {
+        $groups = AdminAuthGroupAccess::get(['uid' => $uid]);
+        if (isset($groups) && $groups->groupId) {
+            $openGroup = (new AdminAuthGroup())->whereIn('id', $groups->groupId)->where(['status' => 1])->select();
+            if (isset($openGroup)) {
+                $openGroupArr = [];
+                foreach ($openGroup as $group) {
+                    $openGroupArr[] = $group->id;
+                }
+                $allRules = (new AdminAuthRule())->whereIn('groupId', $openGroupArr)->select();
+                if (isset($allRules)) {
+                    $rules = [];
+                    foreach ($allRules as $rule) {
+                        $rules[] = $rule->url;
+                    }
+                    $rules = array_unique($rules);
+
+                    return $rules;
+                } else {
+                    return [];
+                }
+            } else {
+                return [];
+            }
+        } else {
+            return [];
+        }
+    }
+
 }
diff --git a/application/http/middleware/AdminResponse.php b/application/http/middleware/AdminResponse.php
index 8228bc8..3f79fc5 100644
--- a/application/http/middleware/AdminResponse.php
+++ b/application/http/middleware/AdminResponse.php
@@ -2,9 +2,10 @@
 
 namespace app\http\middleware;
 
-class AdminResponse
-{
-    public function handle($request, \Closure $next)
-    {
+use think\facade\Config;
+
+class AdminResponse {
+    public function handle($request, \Closure $next) {
+        return $next($request)->header(Config::get('apiadmin.CROSS_DOMAIN'));
     }
 }
diff --git a/application/util/Tools.php b/application/util/Tools.php
index f91fab7..e91ac0c 100644
--- a/application/util/Tools.php
+++ b/application/util/Tools.php
@@ -112,4 +112,58 @@ class Tools {
         }
         return $list;
     }
+
+    /**
+     * 把返回的数据集转换成Tree
+     * @param $list
+     * @param string $pk
+     * @param string $pid
+     * @param string $child
+     * @param string $root
+     * @return array
+     */
+    public static function listToTree($list, $pk='id', $pid = 'fid', $child = '_child', $root = '0') {
+        $tree = array();
+        if(is_array($list)) {
+            $refer = array();
+            foreach ($list as $key => $data) {
+                $refer[$data[$pk]] = &$list[$key];
+            }
+            foreach ($list as $key => $data) {
+                $parentId =  $data[$pid];
+                if ($root == $parentId) {
+                    $tree[] = &$list[$key];
+                }else{
+                    if (isset($refer[$parentId])) {
+                        $parent = &$refer[$parentId];
+                        $parent[$child][] = &$list[$key];
+                    }
+                }
+            }
+        }
+        return $tree;
+    }
+
+    public static function formatTree($list, $lv = 0, $title = 'name'){
+        $formatTree = array();
+        foreach($list as $key => $val){
+            $title_prefix = '';
+            for( $i=0;$i<$lv;$i++ ){
+                $title_prefix .= "|---";
+            }
+            $val['lv'] = $lv;
+            $val['namePrefix'] = $lv == 0 ? '' : $title_prefix;
+            $val['showName'] = $lv == 0 ? $val[$title] : $title_prefix.$val[$title];
+            if(!array_key_exists('_child', $val)){
+                array_push($formatTree, $val);
+            }else{
+                $child = $val['_child'];
+                unset($val['_child']);
+                array_push($formatTree, $val);
+                $middle = self::formatTree($child, $lv+1, $title); //进行下一层递归
+                $formatTree = array_merge($formatTree, $middle);
+            }
+        }
+        return $formatTree;
+    }
 }
diff --git a/config/app.php b/config/app.php
index 3653eeb..bde326a 100644
--- a/config/app.php
+++ b/config/app.php
@@ -97,7 +97,7 @@ return [
     // 是否开启路由延迟解析
     'url_lazy_route'         => false,
     // 是否强制使用路由
-    'url_route_must'         => false,
+    'url_route_must'         => true,
     // 合并路由规则
     'route_rule_merge'       => false,
     // 路由是否完全匹配
diff --git a/route/route.php b/route/route.php
index 253b6d6..3c2c251 100644
--- a/route/route.php
+++ b/route/route.php
@@ -11,11 +11,12 @@
 
 use think\facade\Route;
 
-Route::rule('admin/Login/index','admin/Login/index','post');
-Route::rule('admin/Index/upload','admin/Index/upload','post');
-Route::rule('admin/Login/logout','admin/Login/logout','get');
 
 Route::group('admin', function () {
+    Route::rule('Login/index','admin/Login/index','post');
+    Route::rule('Index/upload','admin/Index/upload','post');
+    Route::rule('Login/logout','admin/Login/logout','get');
+
     //大部分控制器的路由都以分组的形式写到这里
     Route::group('Menu', [
         'index'        => [
@@ -38,7 +39,7 @@ Route::group('admin', function () {
             'admin/Menu/del',
             ['method' => 'get']
         ]
-    ]);
+    ])->middleware('AdminPermission');;
     Route::group('User', [
         'index'        => [
             'admin/User/index',
@@ -68,7 +69,7 @@ Route::group('admin', function () {
             'admin/User/del',
             ['method' => 'get']
         ],
-    ]);
+    ])->middleware('Auth');
     Route::group('Auth', [
         'index'        => [
             'admin/Auth/index',
@@ -102,7 +103,7 @@ Route::group('admin', function () {
             'admin/Auth/getRuleList',
             ['method' => 'get']
         ]
-    ]);
+    ])->middleware('Auth');
     Route::group('App', [
         'index'            => [
             'admin/App/index',
@@ -132,7 +133,7 @@ Route::group('admin', function () {
             'admin/App/del',
             ['method' => 'get']
         ]
-    ]);
+    ])->middleware('Auth');
     Route::group('InterfaceList', [
         'index'        => [
             'admin/InterfaceList/index',
@@ -162,7 +163,7 @@ Route::group('admin', function () {
             'admin/InterfaceList/getHash',
             ['method' => 'get']
         ]
-    ]);
+    ])->middleware('Auth');
     Route::group('Fields', [
         'index'    => [
             'admin/Fields/index',
@@ -192,7 +193,7 @@ Route::group('admin', function () {
             'admin/Fields/upload',
             ['method' => 'post']
         ]
-    ]);
+    ])->middleware('Auth');
     Route::group('InterfaceGroup', [
         'index'        => [
             'admin/InterfaceGroup/index',
@@ -218,7 +219,7 @@ Route::group('admin', function () {
             'admin/InterfaceGroup/del',
             ['method' => 'get']
         ]
-    ]);
+    ])->middleware('Auth');
     Route::group('AppGroup', [
         'index'        => [
             'admin/AppGroup/index',
@@ -244,7 +245,7 @@ Route::group('admin', function () {
             'admin/AppGroup/del',
             ['method' => 'get']
         ]
-    ]);
+    ])->middleware('Auth');
     Route::group('Log', [
         'index' => [
             'admin/Log/index',
@@ -254,7 +255,9 @@ Route::group('admin', function () {
             'admin/Log/del',
             ['method' => 'get']
         ]
-    ]);
-    Route::miss('admin/Miss/index');
-})->middleware('Auth');
+    ])->middleware('Auth');
+
+    //MISS路由定义
+    Route::miss('admin/Miss/index');
+})->middleware('AdminResponse');