update route service
This commit is contained in:
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Model\Route;
|
||||
use Hyperf\HttpServer\Router\DispatcherFactory;
|
||||
use Hyperf\HttpServer\Router\Handler;
|
||||
use Hyperf\HttpServer\Router\RouteCollector;
|
||||
use Psr\Container\ContainerInterface;
|
||||
|
||||
class RouteSyncService
|
||||
{
|
||||
public function __construct(
|
||||
protected readonly ContainerInterface $container,
|
||||
) {}
|
||||
|
||||
/**
|
||||
* 同步 Hyperf 注解路由到 routes 表
|
||||
*
|
||||
* @return array{synced: int, total: int}
|
||||
*/
|
||||
public function sync(): array
|
||||
{
|
||||
$factory = $this->container->get(DispatcherFactory::class);
|
||||
$router = $factory->getRouter('http');
|
||||
$routes = $this->extractRoutes($router);
|
||||
|
||||
$synced = 0;
|
||||
foreach ($routes as $route_info) {
|
||||
Route::query()->updateOrCreate(
|
||||
['method' => $route_info['method'], 'path' => $route_info['path']],
|
||||
['name' => $route_info['name']]
|
||||
);
|
||||
$synced++;
|
||||
}
|
||||
|
||||
return [
|
||||
'synced' => $synced,
|
||||
'total' => count($routes),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* 从路由收集器中提取所有 API 路由
|
||||
*
|
||||
* @return array<int, array{method: string, path: string, name: string|null}>
|
||||
*/
|
||||
private function extractRoutes(RouteCollector $router): array
|
||||
{
|
||||
$routes = [];
|
||||
[$staticRouters, $variableRouters] = $router->getData();
|
||||
|
||||
// 静态路由(无路径参数)
|
||||
foreach ($staticRouters as $method => $items) {
|
||||
foreach ($items as $handler) {
|
||||
$this->collectRoute($routes, $method, $handler);
|
||||
}
|
||||
}
|
||||
|
||||
// 动态路由(含路径参数如 {id})
|
||||
foreach ($variableRouters as $method => $items) {
|
||||
foreach ($items as $item) {
|
||||
if (is_array($item['routeMap'] ?? false)) {
|
||||
foreach ($item['routeMap'] as $routeMap) {
|
||||
$this->collectRoute($routes, $method, $routeMap[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_values($routes);
|
||||
}
|
||||
|
||||
/**
|
||||
* 收集单条路由信息,仅同步 /api/ 前缀的路由
|
||||
*/
|
||||
private function collectRoute(array &$routes, string $method, Handler $handler): void
|
||||
{
|
||||
$path = $handler->route;
|
||||
|
||||
// 仅同步 API 路由
|
||||
if (!str_starts_with($path, '/api/')) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 解析 action 名称
|
||||
$name = null;
|
||||
if (is_array($handler->callback)) {
|
||||
$name = $handler->callback[0] . '::' . $handler->callback[1];
|
||||
} elseif (is_string($handler->callback)) {
|
||||
$name = $handler->callback;
|
||||
}
|
||||
|
||||
$key = $method . '|' . $path;
|
||||
if (!isset($routes[$key])) {
|
||||
$routes[$key] = [
|
||||
'method' => $method,
|
||||
'path' => $path,
|
||||
'name' => $name,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user