Files
MrleeAdmin/backend/core/route/RouteOrganizerService.php
T
2026-08-31 11:33:59 +08:00

229 lines
7.0 KiB
PHP

<?php
/**
*+------------------
* madong
*+------------------
* Copyright (c) https://gitee.com/motion-code All rights reserved.
*+------------------
* Author: Mr. April (405784684@qq.com)
*+------------------
* Official Website: https://madong.tech
*/
namespace core\route;
use Closure;
use core\uuid\Snowflake;
use Webman\Route;
/**
* webman路由处理
*
* @author Mr.April
* @since 1.0
*/
class RouteOrganizerService
{
/**
* 输出路由列表
*
* @param string $format
*
* @return mixed
*/
public function getRoutes(string $format = 'normal'): array
{
$data = [];
foreach (Route::getRoutes() as $route) {
$callback = $route->getCallback();
if ($callback instanceof Closure) {
continue;
}
$row = [
'name' => $route->getName(),
'path' => $route->getPath(),
'methods' => $route->getMethods()[0],
'middleware' => $route->getMiddleware(),
'file_path' => $callback[0],
'action' => $callback[1],
];
$data[] = $row;
}
$methods = [
'tree' => 'buildRouteTree',
'pid_tree' => 'buildPidTree',
'normal' => 'buildSnowflakeTree',
];
$format_function = $methods[$format] ?? 'formatNormal';
return call_user_func([$this, $format_function], $data);
}
/**
* 路由数据检索器
*
* @param array $routes 原始路由数据集
* @param string|null $type 精确匹配类型(route/directory)
* @param string|null $keyword 名称模糊关键词
*
* @return array 过滤后的路由列表
*/
public function search(array $routes, ?string $type = null, ?string $keyword = null): array
{
return array_values(array_filter($routes, function ($route) use ($type, $keyword) {
// 类型匹配检测
$typeMatch = ($type === null) || ($route['type'] === $type);
// 名称模糊匹配检测
$nameMatch = ($keyword === null) ||
(mb_stripos($route['name'], $keyword) !== false);
return $typeMatch && $nameMatch;
}));
}
/**
* 路由数据重构输出children格式
*
* @param array $routes
*
* @return array
*/
public function buildRouteTree(array $routes): array
{
$tree = [];
foreach ($routes as $route) {
$parts = explode('.', $route['name']);
$current = &$tree;
$depth = 0;
while ($depth < count($parts)) {
$isLeaf = ($depth === count($parts) - 1);
$currentPart = $parts[$depth];
// 节点类型判断
$nodeType = $isLeaf ? 'route' : 'directory';
// 合并路由数据
$nodeData = ($isLeaf)
? array_merge($route, ['name' => $currentPart, 'type' => $nodeType])
: ['type' => $nodeType, 'name' => $currentPart, 'children' => []];
// 搜索已存在节点
$existIndex = array_search($currentPart, array_column($current, 'name'));
if ($existIndex === false) {
$current[] = $nodeData;
$existIndex = array_key_last($current);
}
// 指针下钻(仅目录需要)
if (!$isLeaf) {
$current = &$current[$existIndex]['children'];
}
$depth++;
}
}
return $tree;
}
/**
* 路由数据重构输出列表格式
*
* @param array $routes
*
* @return array
*/
public function buildPidTree(array $routes): array
{
$nodes = [];
$idCounter = 1;
$pathMap = ['root' => ['id' => 0]]; // 根节点锚点
foreach ($routes as $route) {
$parts = explode('.', $route['name']);
$currentPath = 'root';
$parentId = 0;
foreach ($parts as $part) {
$nodePath = $currentPath . '.' . $part;
// 节点已存在检测
if (!isset($pathMap[$nodePath])) {
$isLeaf = ($part === end($parts));
$node = [
'id' => $idCounter,
'pid' => $parentId,
'name' => $part,
'type' => $isLeaf ? 'route' : 'directory',
] + ($isLeaf ? $route : []); // 合并路由元数据
$nodes[] = $node;
$pathMap[$nodePath] = [
'id' => $idCounter,
'pid' => $parentId,
];
$idCounter++;
}
// 更新指针
$parentId = $pathMap[$nodePath]['id'];
$currentPath = $nodePath;
}
}
return $nodes;
}
public function buildSnowflakeTree(array $routes, int $workerId = 1, int $dataCenterId = 1): array
{
$nodes = [];
$pathMap = ['root' => ['id' => Snowflake::generate(), 'level' => 0]]; // 初始化根节点层级
foreach ($routes as $route) {
$parts = explode('.', $route['name']);
$currentPath = 'root';
$parentId = 0; // 顶级节点的 pid 设为 0
$currentLevel = 0; // 当前层级计数器
foreach ($parts as $index => $part) {
$nodePath = $currentPath . '.' . $part;
$isLeaf = ($index === count($parts) - 1);
// 节点存在性检测
if (!isset($pathMap[$nodePath])) {
$nodeId = Snowflake::generate();
$node = [
'id' => $nodeId,
'pid' => $parentId,
'name' => $part, // 仅存储当前层级名称
'level' => $currentLevel + 1, // 层级=父层级+1
'type' => $isLeaf ? 'route' : 'directory',
];
// 合并路由元数据
if ($isLeaf) {
unset($route['name']); // 移除冗余字段
$node = array_merge($node, $route);
}
$nodes[] = $node;
$pathMap[$nodePath] = [
'id' => $nodeId,
'pid' => $parentId,
'level' => $currentLevel + 1,
];
}
// 更新指针
$parentId = $pathMap[$nodePath]['id'];
$currentLevel = $pathMap[$nodePath]['level']; // 继承当前层级
$currentPath = $nodePath;
}
}
return $nodes;
}
}