소스 검색

添加OpenAPI模块到后台菜单

- 创建新的顶级菜单'外接管理'
- 添加OpenAPI应用管理子菜单
- 简化OpenAPI服务提供者,专注后台管理功能
- 简化配置文件,移除暂时用不到的配置
- 修复控制器中的json字段类型问题
- 创建数据库表kku_openapi_apps
- 创建管理命令InsertOpenAPIAdminMenu用于自动化菜单配置
notfff 7 달 전
부모
커밋
612fbcb882

+ 6 - 0
AiWork/WORK2.md

@@ -66,3 +66,9 @@ Fund 模块的 小数 适配还未完成 ,比如 \App\Module\Fund\Services\Fun
 
 在非Fund模块外,不应该自行处理资金数值问题,从Fund模块服务层返回的资金数值是可信的;
 
+需要增加1个‘开放平台’的模块,用于处理第三方应用的接入
+处理第三方应用的接入信息 和 处理接入第三方应用的信息 ,适合一个模块么?
+OpenAPI模块 - 专门处理对外开放API的需求
+OpenAPI模块  加入到后台菜单(数据库,而不是硬编码),创建新的顶级菜单‘外接管理’
+
+ThirdParty模块 - 专门处理接入第三方服务的需求

+ 4 - 1
AiWork/记忆习惯.md

@@ -106,4 +106,7 @@
 - 使用mcp执行sql
 - 当遇到接口数据问题时,优先检查数据结构字段名是否匹配,特别注意Logic层返回的字段名与Handler中访问的字段名要一致
 - 在Handler中处理protobuf响应时,确保所有必需字段都有正确的数据源,特别是user_id等关键字段
-- 使用`php artisan debug:reproduce-error`命令回放错误请求进行调试验证
+- 使用`php artisan debug:reproduce-error`命令回放错误请求进行调试验证
+
+## 项目相关运行和访问
+- 项目已经使用Docker运行,访问地址:http://kku_laravel.local.gd

+ 123 - 0
app/Console/Commands/InsertOpenAPIAdminMenu.php

@@ -0,0 +1,123 @@
+<?php
+
+namespace App\Console\Commands;
+
+use App\Module\System\Models\AdminMenu;
+use Illuminate\Console\Command;
+
+class InsertOpenAPIAdminMenu extends Command
+{
+    /**
+     * The name and signature of the console command.
+     *
+     * @var string
+     */
+    protected $signature = 'admin:insert-openapi-menu';
+
+    /**
+     * The console command description.
+     *
+     * @var string
+     */
+    protected $description = '添加OpenAPI模块的后台管理菜单';
+
+    /**
+     * Execute the console command.
+     *
+     * @return int
+     */
+    public function handle()
+    {
+        $this->info('开始添加OpenAPI模块后台菜单...');
+
+        // 1. 创建顶级菜单'外接管理'
+        $externalManageMenu = $this->createExternalManageMenu();
+        
+        // 2. 创建OpenAPI应用管理子菜单
+        $this->createOpenAPIAppMenu($externalManageMenu->id);
+
+        $this->info('OpenAPI模块后台菜单添加完成!');
+        return 0;
+    }
+
+    /**
+     * 创建顶级菜单'外接管理'
+     *
+     * @return AdminMenu
+     */
+    protected function createExternalManageMenu(): AdminMenu
+    {
+        // 检查是否已存在
+        $existingMenu = AdminMenu::where('title', '外接管理')
+            ->where('parent_id', 0)
+            ->first();
+
+        if ($existingMenu) {
+            $this->info("顶级菜单'外接管理'已存在: ID = {$existingMenu->id}");
+            return $existingMenu;
+        }
+
+        // 获取最大的order值
+        $maxOrder = AdminMenu::max('order');
+        $nextOrder = $maxOrder + 1;
+
+        // 创建顶级菜单
+        $menu = AdminMenu::create([
+            'parent_id' => 0,
+            'order' => $nextOrder,
+            'title' => '外接管理',
+            'icon' => 'fa-plug',
+            'uri' => '',
+            'show' => 1
+        ]);
+
+        $this->info("创建顶级菜单'外接管理': ID = {$menu->id}, Order = {$nextOrder}");
+        return $menu;
+    }
+
+    /**
+     * 创建OpenAPI应用管理子菜单
+     *
+     * @param int $parentId
+     * @return AdminMenu
+     */
+    protected function createOpenAPIAppMenu(int $parentId): AdminMenu
+    {
+        // 检查是否已存在
+        $existingMenu = AdminMenu::where('title', 'OpenAPI应用管理')
+            ->where('parent_id', $parentId)
+            ->first();
+
+        if ($existingMenu) {
+            $this->info("子菜单'OpenAPI应用管理'已存在: ID = {$existingMenu->id}");
+            return $existingMenu;
+        }
+
+        // 获取父菜单下的最大order值
+        $maxOrder = AdminMenu::where('parent_id', $parentId)->max('order');
+        $nextOrder = $maxOrder ? $maxOrder + 1 : 1;
+
+        // 创建子菜单
+        $menu = AdminMenu::create([
+            'parent_id' => $parentId,
+            'order' => $nextOrder,
+            'title' => 'OpenAPI应用管理',
+            'icon' => 'fa-key',
+            'uri' => 'openapi-apps',
+            'show' => 1
+        ]);
+
+        $this->info("创建子菜单'OpenAPI应用管理': ID = {$menu->id}, URI = openapi-apps");
+        return $menu;
+    }
+
+    /**
+     * 显示菜单结构
+     */
+    protected function showMenuStructure()
+    {
+        $this->info("\n当前菜单结构:");
+        $this->info("外接管理 (fa-plug)");
+        $this->info("  └── OpenAPI应用管理 (fa-key) -> openapi-apps");
+    }
+}

+ 12 - 7
app/Module/OpenAPI/AdminControllers/AppController.php

@@ -95,11 +95,12 @@ class AppController extends AdminController
                 $filter->between('created_at', '创建时间')->datetime();
             });
 
+            // TODO: 创建批量操作类
             // 批量操作
-            $grid->batchActions([
-                new \App\Module\OpenAPI\AdminActions\BatchApproveAction(),
-                new \App\Module\OpenAPI\AdminActions\BatchSuspendAction(),
-            ]);
+            // $grid->batchActions([
+            //     new \App\Module\OpenAPI\AdminActions\BatchApproveAction(),
+            //     new \App\Module\OpenAPI\AdminActions\BatchSuspendAction(),
+            // ]);
 
             // 行操作
             $grid->actions(function (Grid\Displayers\Actions $actions) {
@@ -169,8 +170,12 @@ class AppController extends AdminController
                 return implode(', ', $labels);
             });
 
-            $show->field('rate_limits', '限流配置')->json();
-            $show->field('ip_whitelist', 'IP白名单')->json();
+            $show->field('rate_limits', '限流配置')->as(function ($value) {
+                return $value ? json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) : '无';
+            });
+            $show->field('ip_whitelist', 'IP白名单')->as(function ($value) {
+                return $value ? json_encode($value, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) : '无';
+            });
 
             $show->field('user_id', '创建用户ID');
             $show->field('user_name', '创建用户');
@@ -214,7 +219,7 @@ class AppController extends AdminController
 
             $form->checkbox('scopes', '权限范围')->options($this->getScopeOptions());
 
-            $form->json('rate_limits', '限流配置');
+            $form->textarea('rate_limits', '限流配置')->help('JSON格式的限流配置');
             $form->tags('ip_whitelist', 'IP白名单');
 
             $form->number('user_id', '创建用户ID')->required();

+ 1 - 222
app/Module/OpenAPI/Config/openapi.php

@@ -6,7 +6,7 @@ return [
     | OpenAPI模块配置
     |--------------------------------------------------------------------------
     |
-    | OpenAPI模块的基础配置选项
+    | OpenAPI模块的基础配置选项,专注于后台管理功能
     |
     */
 
@@ -18,87 +18,6 @@ return [
         'author' => 'System',
     ],
 
-    // API基础配置
-    'api' => [
-        'prefix' => 'openapi',
-        'version' => 'v1',
-        'base_url' => env('OPENAPI_BASE_URL', 'https://api.example.com'),
-        'timeout' => 30, // 秒
-        'max_requests_per_minute' => 1000,
-    ],
-
-    // 认证配置
-    'auth' => [
-        'default_type' => 'API_KEY',
-        'api_key' => [
-            'header_name' => 'X-API-Key',
-            'query_param' => 'api_key',
-            'length' => 32,
-            'prefix' => 'ak_',
-        ],
-        'oauth2' => [
-            'enabled' => true,
-            'access_token_expire' => 3600, // 1小时
-            'refresh_token_expire' => 2592000, // 30天
-            'auth_code_expire' => 600, // 10分钟
-        ],
-        'jwt' => [
-            'enabled' => true,
-            'secret' => env('OPENAPI_JWT_SECRET'),
-            'expire' => 3600, // 1小时
-            'algorithm' => 'HS256',
-        ],
-        'signature' => [
-            'enabled' => true,
-            'algorithm' => 'sha256',
-            'expire' => 300, // 5分钟
-            'header_name' => 'X-Signature',
-            'timestamp_header' => 'X-Timestamp',
-        ],
-    ],
-
-    // 权限配置
-    'scopes' => [
-        'default' => ['USER_READ', 'GAME_READ'],
-        'basic' => ['USER_READ', 'GAME_READ', 'ITEM_READ', 'TRADE_READ'],
-        'standard' => ['USER_READ', 'USER_WRITE', 'GAME_READ', 'GAME_WRITE', 'ITEM_READ', 'ITEM_WRITE', 'TRADE_READ', 'TRADE_WRITE'],
-        'premium' => ['USER_READ', 'USER_WRITE', 'GAME_READ', 'GAME_WRITE', 'ITEM_READ', 'ITEM_WRITE', 'ITEM_TRANSFER', 'FUND_READ', 'TRADE_READ', 'TRADE_WRITE', 'STATS_READ'],
-        'admin' => ['*'], // 所有权限
-    ],
-
-    // 限流配置
-    'rate_limit' => [
-        'enabled' => true,
-        'default' => [
-            'requests_per_minute' => 60,
-            'requests_per_hour' => 1000,
-            'requests_per_day' => 10000,
-        ],
-        'by_scope' => [
-            'USER_READ' => ['requests_per_minute' => 100],
-            'USER_WRITE' => ['requests_per_minute' => 30],
-            'FUND_TRANSFER' => ['requests_per_minute' => 10],
-            'SYSTEM_ADMIN' => ['requests_per_minute' => 5],
-        ],
-        'by_app_status' => [
-            'ACTIVE' => ['requests_per_minute' => 100],
-            'SUSPENDED' => ['requests_per_minute' => 10],
-        ],
-    ],
-
-    // IP白名单配置
-    'ip_whitelist' => [
-        'enabled' => false,
-        'default_allowed' => true, // 默认允许所有IP
-        'whitelist' => [
-            // '127.0.0.1',
-            // '192.168.1.0/24',
-        ],
-        'blacklist' => [
-            // '10.0.0.1',
-        ],
-    ],
-
     // 应用配置
     'app' => [
         'auto_approve' => false, // 是否自动审核通过
@@ -128,144 +47,4 @@ return [
         'expire_days' => 0, // 0表示永不过期
     ],
 
-    // 日志配置
-    'logging' => [
-        'enabled' => true,
-        'log_requests' => true,
-        'log_responses' => false, // 响应可能包含敏感信息
-        'log_errors' => true,
-        'retention_days' => 90,
-        'channels' => [
-            'api_calls' => [
-                'driver' => 'daily',
-                'path' => storage_path('logs/openapi-calls.log'),
-                'level' => 'info',
-                'days' => 30,
-            ],
-            'api_errors' => [
-                'driver' => 'daily',
-                'path' => storage_path('logs/openapi-errors.log'),
-                'level' => 'error',
-                'days' => 90,
-            ],
-        ],
-    ],
-
-    // 监控配置
-    'monitoring' => [
-        'enabled' => true,
-        'metrics' => [
-            'request_count' => true,
-            'response_time' => true,
-            'error_rate' => true,
-            'rate_limit_hits' => true,
-        ],
-        'alerts' => [
-            'error_rate_threshold' => 5, // 百分比
-            'response_time_threshold' => 2000, // 毫秒
-            'rate_limit_threshold' => 80, // 百分比
-        ],
-        'stats_retention_days' => 30,
-    ],
-
-    // 回调配置
-    'webhook' => [
-        'enabled' => true,
-        'timeout' => 10, // 秒
-        'retry_times' => 3,
-        'retry_delay' => 5, // 秒
-        'events' => [
-            'app.created',
-            'app.approved',
-            'app.suspended',
-            'api.rate_limit_exceeded',
-            'api.error',
-        ],
-    ],
-
-    // 文档配置
-    'documentation' => [
-        'enabled' => true,
-        'title' => '开放API文档',
-        'description' => '开心农场开放API接口文档',
-        'version' => '1.0.0',
-        'contact' => [
-            'name' => 'API Support',
-            'email' => 'api@example.com',
-            'url' => 'https://example.com/support',
-        ],
-        'license' => [
-            'name' => 'MIT',
-            'url' => 'https://opensource.org/licenses/MIT',
-        ],
-        'servers' => [
-            [
-                'url' => 'https://api.example.com/v1',
-                'description' => '生产环境',
-            ],
-            [
-                'url' => 'https://api-test.example.com/v1',
-                'description' => '测试环境',
-            ],
-        ],
-    ],
-
-    // SDK配置
-    'sdk' => [
-        'enabled' => true,
-        'languages' => [
-            'php' => [
-                'enabled' => true,
-                'version' => '1.0.0',
-                'namespace' => 'OpenAPI\\SDK',
-            ],
-            'javascript' => [
-                'enabled' => true,
-                'version' => '1.0.0',
-                'package_name' => 'openapi-sdk',
-            ],
-            'python' => [
-                'enabled' => true,
-                'version' => '1.0.0',
-                'package_name' => 'openapi-sdk',
-            ],
-        ],
-    ],
-
-    // 安全配置
-    'security' => [
-        'encrypt_secrets' => true,
-        'hash_algorithm' => 'sha256',
-        'signature_tolerance' => 300, // 签名时间容差(秒)
-        'max_request_size' => 1024 * 1024, // 1MB
-        'allowed_origins' => [
-            '*', // 允许所有来源,生产环境应该限制
-        ],
-        'blocked_user_agents' => [
-            // 'BadBot',
-        ],
-    ],
-
-    // 缓存配置
-    'cache' => [
-        'enabled' => true,
-        'default_ttl' => 300, // 5分钟
-        'keys' => [
-            'app_info' => 'openapi:app:{app_id}',
-            'api_key' => 'openapi:key:{api_key}',
-            'rate_limit' => 'openapi:rate:{app_id}:{scope}',
-            'user_scopes' => 'openapi:scopes:{user_id}',
-        ],
-    ],
-
-    // 队列配置
-    'queue' => [
-        'enabled' => true,
-        'connection' => 'redis',
-        'jobs' => [
-            'webhook_delivery' => 'openapi_webhooks',
-            'log_processing' => 'openapi_logs',
-            'stats_calculation' => 'openapi_stats',
-        ],
-    ],
 ];

+ 3 - 182
app/Module/OpenAPI/Providers/OpenAPIServiceProvider.php

@@ -2,24 +2,15 @@
 
 namespace App\Module\OpenAPI\Providers;
 
-use App\Module\OpenAPI\Events\ApiCallEvent;
 use App\Module\OpenAPI\Events\AppCreatedEvent;
-use App\Module\OpenAPI\Events\RateLimitExceededEvent;
-use App\Module\OpenAPI\Listeners\ApiCallListener;
 use App\Module\OpenAPI\Listeners\AppCreatedListener;
-use App\Module\OpenAPI\Listeners\RateLimitListener;
-use App\Module\OpenAPI\Middleware\ApiAuthMiddleware;
-use App\Module\OpenAPI\Middleware\RateLimitMiddleware;
-use App\Module\OpenAPI\Middleware\ScopeMiddleware;
-use App\Module\OpenAPI\Middleware\IpWhitelistMiddleware;
 use Illuminate\Support\Facades\Event;
-use Illuminate\Support\Facades\Route;
 use Illuminate\Support\ServiceProvider;
 
 /**
  * OpenAPI模块服务提供者
- * 
- * 负责注册OpenAPI模块的服务、中间件、事件监听器等
+ *
+ * 专注于后台管理功能,使用注解路由,不注册API路由和资源
  */
 class OpenAPIServiceProvider extends ServiceProvider
 {
@@ -47,20 +38,8 @@ class OpenAPIServiceProvider extends ServiceProvider
      */
     public function boot()
     {
-        // 注册中间件
-        $this->registerMiddleware();
-
         // 注册事件监听器
         $this->registerEventListeners();
-
-        // 注册路由
-        $this->registerRoutes();
-
-        // 注册命令
-        $this->registerCommands();
-
-        // 发布资源
-        $this->publishResources();
     }
 
     /**
@@ -71,7 +50,7 @@ class OpenAPIServiceProvider extends ServiceProvider
     protected function registerServices()
     {
         // 注册OpenAPI服务
-        $this->app->singleton('openapi.service', function ($app) {
+        $this->app->singleton('openapi.service', function () {
             return new \App\Module\OpenAPI\Services\OpenApiService();
         });
 
@@ -81,49 +60,6 @@ class OpenAPIServiceProvider extends ServiceProvider
                 $app->make('openapi.service')
             );
         });
-
-        // 注册限流服务
-        $this->app->singleton('openapi.rate_limit', function ($app) {
-            return new \App\Module\OpenAPI\Services\RateLimitService();
-        });
-
-        // 注册权限服务
-        $this->app->singleton('openapi.scope', function ($app) {
-            return new \App\Module\OpenAPI\Services\ScopeService();
-        });
-
-        // 注册日志服务
-        $this->app->singleton('openapi.log', function ($app) {
-            return new \App\Module\OpenAPI\Services\LogService();
-        });
-
-        // 注册Webhook服务
-        $this->app->singleton('openapi.webhook', function ($app) {
-            return new \App\Module\OpenAPI\Services\WebhookService();
-        });
-    }
-
-    /**
-     * 注册中间件
-     *
-     * @return void
-     */
-    protected function registerMiddleware()
-    {
-        $router = $this->app['router'];
-
-        // 注册中间件别名
-        $router->aliasMiddleware('openapi.auth', ApiAuthMiddleware::class);
-        $router->aliasMiddleware('openapi.rate_limit', RateLimitMiddleware::class);
-        $router->aliasMiddleware('openapi.scope', ScopeMiddleware::class);
-        $router->aliasMiddleware('openapi.ip_whitelist', IpWhitelistMiddleware::class);
-
-        // 注册中间件组
-        $router->middlewareGroup('openapi', [
-            'openapi.auth',
-            'openapi.rate_limit',
-            'openapi.ip_whitelist',
-        ]);
     }
 
     /**
@@ -133,121 +69,10 @@ class OpenAPIServiceProvider extends ServiceProvider
      */
     protected function registerEventListeners()
     {
-        Event::listen(
-            ApiCallEvent::class,
-            ApiCallListener::class
-        );
-
         Event::listen(
             AppCreatedEvent::class,
             AppCreatedListener::class
         );
-
-        Event::listen(
-            RateLimitExceededEvent::class,
-            RateLimitListener::class
-        );
-    }
-
-    /**
-     * 注册路由
-     *
-     * @return void
-     */
-    protected function registerRoutes()
-    {
-        if (config('openapi.api.enabled', true)) {
-            $this->registerApiRoutes();
-        }
-
-        if (config('openapi.documentation.enabled', true)) {
-            $this->registerDocumentationRoutes();
-        }
-    }
-
-    /**
-     * 注册API路由
-     *
-     * @return void
-     */
-    protected function registerApiRoutes()
-    {
-        Route::group([
-            'prefix' => config('openapi.api.prefix', 'openapi'),
-            'namespace' => 'App\Module\OpenAPI\Controllers',
-            'middleware' => ['api'],
-        ], function () {
-            // 认证相关路由
-            Route::post('auth/token', 'AuthController@token');
-            Route::post('auth/refresh', 'AuthController@refresh');
-            Route::post('auth/revoke', 'AuthController@revoke');
-
-            // 应用信息路由
-            Route::middleware(['openapi.auth'])->group(function () {
-                Route::get('app/info', 'AppController@info');
-                Route::get('app/scopes', 'AppController@scopes');
-                Route::get('app/stats', 'AppController@stats');
-            });
-
-            // Webhook路由
-            Route::post('webhook/{app_id}', 'WebhookController@handle');
-        });
-    }
-
-    /**
-     * 注册文档路由
-     *
-     * @return void
-     */
-    protected function registerDocumentationRoutes()
-    {
-        Route::group([
-            'prefix' => 'openapi/docs',
-            'namespace' => 'App\Module\OpenAPI\Controllers',
-        ], function () {
-            Route::get('/', 'DocumentationController@index');
-            Route::get('openapi.yaml', 'DocumentationController@openapi');
-            Route::get('postman.json', 'DocumentationController@postman');
-        });
-    }
-
-    /**
-     * 注册命令
-     *
-     * @return void
-     */
-    protected function registerCommands()
-    {
-        if ($this->app->runningInConsole()) {
-            $this->commands([
-                \App\Module\OpenAPI\Commands\GenerateApiKeyCommand::class,
-                \App\Module\OpenAPI\Commands\CleanExpiredTokensCommand::class,
-                \App\Module\OpenAPI\Commands\ApiStatsCommand::class,
-            ]);
-        }
-    }
-
-    /**
-     * 发布资源
-     *
-     * @return void
-     */
-    protected function publishResources()
-    {
-        // 发布配置文件
-        $this->publishes([
-            __DIR__ . '/../Config/openapi.php' => config_path('openapi.php'),
-        ], 'openapi-config');
-
-        // 发布文档资源
-        $this->publishes([
-            __DIR__ . '/../Documentation' => public_path('openapi/docs'),
-        ], 'openapi-docs');
-
-        // 发布SDK
-        $this->publishes([
-            __DIR__ . '/../SDK' => resource_path('openapi/sdk'),
-        ], 'openapi-sdk');
     }
 
     /**
@@ -260,10 +85,6 @@ class OpenAPIServiceProvider extends ServiceProvider
         return [
             'openapi.service',
             'openapi.auth',
-            'openapi.rate_limit',
-            'openapi.scope',
-            'openapi.log',
-            'openapi.webhook',
         ];
     }
 }

+ 3 - 0
config/app.php

@@ -217,6 +217,9 @@ return [
         // Mex 模块
         \App\Module\Mex\Providers\MexServiceProvider::class,
 
+        // OpenAPI 模块
+        \App\Module\OpenAPI\Providers\OpenAPIServiceProvider::class,
+
         // SQL日志服务提供者
         App\Providers\SqlLogServiceProvider::class,
     ],