浏览代码

常用菜单 service 获取常用菜单代码优化加注释

ANG YU 5 年之前
父节点
当前提交
9f4af26f9f

+ 123 - 26
app/Services/CheckActiveMenuService.php

@@ -5,35 +5,40 @@ namespace App\Services;
 
 
 use App\Menu;
-use App\User;
 use App\UserVisitMenuLog;
+use Illuminate\Database\Eloquent\Builder;
+use Illuminate\Database\Eloquent\Model;
 use Illuminate\Http\Request;
-use Illuminate\Support\Arr;
+use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\Redis;
 
 class CheckActiveMenuService
 {
+    /**
+     *同步数据到数据库并且将L1转移到L2
+     */
     public static function sync()
+
     {
         try {
-            $userVisitMenuLogsL1 = Redis::LRANGE('UserVisitMenuLogsL1', 0, -1);
-            UserVisitMenuLog::query()->insert(self::redisListToArray($userVisitMenuLogsL1));
+            self::syncToDB();
             self::switchL1ToL2();
         } catch (\Exception $e) {
+            // TODO 同步异常的处理策略
             return;
         }
     }
 
     /**
+     * 将用户菜单点击事件保存
      * @param Request $request
      */
     public static function set(Request $request): void
     {
-        $uri = substr($request->getRequestUri(), 1);
         // 请求方法为get
         if ($request->method() == 'GET') {
-            $menu = Menu::query()->where('route', $uri)->first();
+            $menu = Menu::query()->where('route', substr($request->getRequestUri(), 1))->first();
             if ($menu) {
                 //redis正常保存在缓存中
                 $date = date('Y-m-d H:i:s');
@@ -47,35 +52,31 @@ class CheckActiveMenuService
                     //菜单点击入缓存
                     Redis::LPUSH('UserVisitMenuLogsL1', $userVisitMenuLog);
                 } catch (\Exception $e) {
-                    //连接不上缓存。直接入库
+                    // TODO 缓存异常的处理策略
+                }finally{
                     $userVisitMenuLog->save();
                 }
             }
         }
     }
 
+    /**
+     * 获取活跃菜单
+     * @return Builder|Builder[]|\Illuminate\Database\Eloquent\Collection|Model|null
+     */
     public static function activeMenus()
     {
-        if (Redis::LLEN('UserVisitMenuLogsL1') + Redis::LLEN('UserVisitMenuLogsL2') > 0) {
-            //缓存中有数据
-
-            $array1 = self::redisListToArray(Redis::LRANGE('UserVisitMenuLogsL1', 0, -1));
-            $array2 = self::redisListToArray(Redis::LRANGE('UserVisitMenuLogsL2', 0, -1));
-            $array = array_merge($array1, $array2);
-            $conller = collect($array);
-            $user_id = 1;
-            if (Auth::user()) {
-                $user_id = Auth::user()->id;
+        $user_id = self::getUserId();
+        try {
+            Redis::LLEN('UserVisitMenuLogsL1');
+            if (Redis::LLEN('UserVisitMenuLogsL1') + Redis::LLEN('UserVisitMenuLogsL2') > 0) {
+                //缓存中有数据
+                return self::getFromRedis($user_id);
             }
-            $arr = $conller->filter(function ($item) use ($user_id){
-                return $user_id === $item['user_id'];
-            })->groupBy('menu_id')->sortByDesc(function ($item){
-                return $item->count();
-            })->forPage(0,5)->keys();
-            $menus = Menu::query()->find($arr)->sortBy(function($item)use($arr){
-                return $arr->search($item->id);
-            });
-            dd($menus,$arr);
+        } catch (\Exception $e) {
+            // TODO 缓存异常的处理策略
+        } finally {
+            return self::getFromDB($user_id);
         }
     }
 
@@ -108,4 +109,100 @@ class CheckActiveMenuService
             Redis::LPUSH('UserVisitMenuLogsL2', Redis::LPOP('UserVisitMenuLogsL1'));
         }
     }
+
+    /**
+     * @return int
+     */
+    public static function getUserId(): int
+    {
+        $user_id = 1;
+        if (Auth::user()) {
+            $user_id = Auth::user()->id;
+        }
+        return $user_id;
+    }
+
+    /**
+     * 从数据库获取活跃菜单
+     * @param $user_id
+     * @return Builder|Builder[]|\Illuminate\Database\Eloquent\Collection|Model|null
+     */
+    public static function getFromDB($user_id)
+    {
+        return self::getMenusAndSort(self::getMenuIdsFromDB($user_id));
+    }
+
+    /**
+     * 从缓存获取活跃菜单
+     * @param $user_id
+     * @return Builder|Builder[]|\Illuminate\Database\Eloquent\Collection|Model|null
+     */
+    public static function getFromRedis($user_id)
+    {
+        return self::getMenusAndSort(self::getMenuIdsFromRedis($user_id));
+    }
+
+    /**
+     * 获取活跃菜单并按照活跃度排序
+     * @param Collection $arr
+     * @return Builder|Builder[]|\Illuminate\Database\Eloquent\Collection|Model|null
+     */
+    public static function getMenusAndSort(Collection $arr)
+    {
+        return Menu::query()
+            ->find($arr)
+            //根据菜单Id查询
+            ->sortBy(function ($item) use ($arr) {
+                return $arr->search($item->id);
+                //将查询结果按照上面拍好的顺序重新排列
+            });
+    }
+
+    /**
+     * @param $user_id
+     * @return Collection|\Tightenco\Collect\Support\Collection
+     */
+    public static function getMenuIdsFromRedis($user_id)
+    {
+        return collect(array_merge(self::redisListToArray(Redis::LRANGE('UserVisitMenuLogsL1', 0, -1)), self::redisListToArray(Redis::LRANGE('UserVisitMenuLogsL2', 0, -1))))
+            //从缓存中查找全部用户的活跃菜单数据,合并L1,L2
+            ->filter(function ($item) use ($user_id) {
+                return $user_id === $item['user_id'];
+            })
+            //根据user_id筛选
+            ->groupBy('menu_id')
+            //根据menu_id分组
+            ->sortByDesc(function ($item) {
+                return $item->count();
+            })
+            //根据分组结果的二级列表降序排列
+            ->forPage(0, 5)
+            //取前数量最高的五条
+            ->keys();
+        //只获取对应的菜单Id
+    }
+
+    /**
+     * @param $user_id
+     * @return Builder[]|\Illuminate\Database\Eloquent\Collection|Collection
+     */
+    public static function getMenuIdsFromDB($user_id)
+    {
+        return UserVisitMenuLog::query()
+            ->selectRaw('id')
+            ->where('user_id', $user_id)
+            ->groupBy('menu_id')
+            ->get()->sortByDesc(function ($item) {
+                return $item->count();
+            })
+            ->forPage(0, 5)
+            ->map(function ($item) {
+                return $item->id;
+            });
+    }
+
+    public static function syncToDB(): void
+    {
+        UserVisitMenuLog::query()->insert(self::redisListToArray(Redis::LRANGE('UserVisitMenuLogsL1', 0, -1)));
+    }
 }

+ 1 - 1
tests/Services/CheckActiveMenuService/CheckActiveMenuServiceActiveMenusTest.php

@@ -20,7 +20,7 @@ class CheckActiveMenuServiceActiveMenusTest extends TestCase
 
     public function testActiveMenus()
     {
-        $this->checkActiveMenuService->activeMenus();
+        dd($this->checkActiveMenuService->activeMenus());
     }
 
 }