diff --git a/app/Http/Controllers/Admin/AuthController.php b/app/Http/Controllers/Admin/AuthController.php index 96f5c9d..ceb164e 100644 --- a/app/Http/Controllers/Admin/AuthController.php +++ b/app/Http/Controllers/Admin/AuthController.php @@ -295,29 +295,128 @@ class AuthController extends BaseController $validator = Validator::make($request->all(), [ 'token_id' => ['required', 'integer', 'exists:personal_access_tokens,id'] ], [ - 'token_id.required' => '请指定要删除的Token ID', - 'token_id.exists' => 'Token不存在' + 'token_id.required' => '请选择要删除的设备', + 'token_id.exists' => '设备不存在', ]); if ($validator->fails()) { return $this->Field($validator->errors()->first(), 422); } - $tokenId = $request->token_id; - $currentTokenId = $request->user()->currentAccessToken()->id; + $user = $request->user(); + $tokenId = $request->input('token_id'); - // 不能删除当前正在使用的token - if ($tokenId == $currentTokenId) { - return $this->Field('不能删除当前正在使用的设备', 400); + // 验证Token属于当前用户 + $tokenToDelete = $user->tokens()->find($tokenId); + if (!$tokenToDelete) { + return $this->Field('无权删除此设备Token', 403); } - // 只能删除自己的token - $deleted = $request->user()->tokens()->where('id', $tokenId)->delete(); + $tokenToDelete->delete(); - if ($deleted) { - return $this->Success(['message' => '设备删除成功']); + return $this->Success(['message' => '设备删除成功']); + } + + /** + * 获取用户权限信息 + * + * @param Request $request + * @return \Illuminate\Http\JsonResponse + */ + public function permissionInfo(Request $request): JsonResponse + { + $user = $request->user(); + + // 获取用户角色 + $userRoles = $user->roles()->where('status', 0)->get(); + $roleCodes = $userRoles->pluck('code')->toArray(); + + // 判断是否为超级管理员(username为admin或角色编码包含admin相关) + $isSuperAdmin = $user->username === 'admin' || + in_array('admin', $roleCodes) || + in_array('super_admin', $roleCodes); + + // 获取菜单权限 + if ($isSuperAdmin) { + // 超级管理员获取所有菜单 + $menus = \App\Models\System\SystemMenu::where('status', 0) + ->where('visible', 1) + ->whereIn('type', [1, 2]) + ->orderBy('sort', 'asc') + ->orderBy('id', 'asc') + ->get(); } else { - return $this->Field('设备删除失败', 500); + // 普通用户根据角色权限获取菜单 + $roleIds = $userRoles->pluck('id')->toArray(); + if (empty($roleIds)) { + $menus = collect([]); + } else { + $menuIds = \App\Models\System\SystemRoleMenu::whereIn('role_id', $roleIds) + ->pluck('menu_id') + ->unique() + ->toArray(); + + $menus = \App\Models\System\SystemMenu::whereIn('id', $menuIds) + ->where('status', 0) + ->where('visible', 1) + ->whereIn('type', [1, 2]) + ->orderBy('sort', 'asc') + ->orderBy('id', 'asc') + ->get(); + } } + + // 构建菜单树形结构,使用表字段名称而不是驼峰命名 + $menuTree = $this->buildMenuTree($menus->toArray()); + + return $this->SuccessObject([ + 'menus' => $menuTree, + 'roles' => $roleCodes, + 'user' => [ + 'id' => $user->id, + 'username' => $user->username, + 'nickname' => $user->nickname, + 'avatar' => $user->avatar ?? '', + 'dept_id' => $user->dept_id, + ] + ]); + } + + /** + * 构建菜单树形结构 + * + * @param array $menus + * @param int $parentId + * @return array + */ + private function buildMenuTree(array $menus, int $parentId = 0): array + { + $tree = []; + + foreach ($menus as $menu) { + if ($menu['parent_id'] == $parentId) { + // 使用表字段名称,不使用驼峰命名 + $menuItem = [ + 'id' => $menu['id'], + 'parentId' => $menu['parent_id'], + 'name' => $menu['name'], + 'component' => $menu['component'], + 'componentName' => $menu['component_name'], + 'icon' => $menu['icon'], + 'keepAlive' => $menu['keep_alive'], + 'visible' => $menu['visible'], + 'alwaysShow' => $menu['always_show'], + 'path' => $menu['path'], + ]; + + // 递归获取子菜单 + $children = $this->buildMenuTree($menus, $menu['id']); + $menuItem['children'] = $children; + + $tree[] = $menuItem; + } + } + + return $tree; } } diff --git a/app/Http/Controllers/Admin/System/SystemDictDataController.php b/app/Http/Controllers/Admin/System/SystemDictDataController.php index c2b10af..a626a98 100644 --- a/app/Http/Controllers/Admin/System/SystemDictDataController.php +++ b/app/Http/Controllers/Admin/System/SystemDictDataController.php @@ -32,8 +32,9 @@ class SystemDictDataController extends BaseController */ public function simpleList(SystemDictDataRequest $request): JsonResponse { + // 不需要验证 $params = $request->validated(); - $result = $this->systemDictDataService->getByType($params['dict_type'], true); + $result = $this->systemDictDataService->getByType($params['dict_type'] ?? '', $params['only_active'] ?? false); return $this->Success($result); } diff --git a/app/Http/Requests/Admin/System/SystemDictDataRequest.php b/app/Http/Requests/Admin/System/SystemDictDataRequest.php index 7c4e398..3275ec1 100644 --- a/app/Http/Requests/Admin/System/SystemDictDataRequest.php +++ b/app/Http/Requests/Admin/System/SystemDictDataRequest.php @@ -229,7 +229,7 @@ class SystemDictDataRequest extends BaseRequest private function simpleListRules(): array { return [ - 'dict_type' => ['required', 'string', 'max:100', 'exists:system_dict_type,type'], + 'dict_type' => ['sometimes', 'string', 'max:100'], ]; } diff --git a/app/Models/BaseModel.php b/app/Models/BaseModel.php index 590232c..e4e07a2 100644 --- a/app/Models/BaseModel.php +++ b/app/Models/BaseModel.php @@ -3,16 +3,12 @@ namespace App\Models; use Illuminate\Database\Eloquent\Model; -use Illuminate\Database\Eloquent\SoftDeletes; class BaseModel extends Model { - use SoftDeletes; - // 自定义时间戳字段 const CREATED_AT = 'create_time'; const UPDATED_AT = 'update_time'; - const DELETED_AT = 'deleted'; /** * 是否启用系统字段自动维护 @@ -88,6 +84,54 @@ class BaseModel extends Model return $user ? $user->tenant_id : null; } + /** + * 软删除(将deleted字段设置为1) + */ + public function delete() + { + if ($this->enableSystemFields) { + return $this->update(['deleted' => 1]); + } + + return parent::delete(); + } + + /** + * 强制删除(真正删除记录) + */ + public function forceDelete() + { + return parent::delete(); + } + + /** + * 恢复软删除的记录 + */ + public function restore() + { + if ($this->enableSystemFields) { + return $this->update(['deleted' => 0]); + } + + return false; + } + + /** + * 查询包含已删除记录的作用域 + */ + public function scopeWithDeleted($query) + { + return $query->withoutGlobalScope('not_deleted'); + } + + /** + * 只查询已删除记录的作用域 + */ + public function scopeOnlyDeleted($query) + { + return $query->withoutGlobalScope('not_deleted')->where('deleted', 1); + } + /** * 设置系统字段(创建时) */ diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 452e6b6..6f2b1ce 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -2,6 +2,9 @@ namespace App\Providers; +use Illuminate\Database\Events\QueryExecuted; +use Illuminate\Support\Facades\DB; +use Illuminate\Support\Facades\Log; use Illuminate\Support\ServiceProvider; class AppServiceProvider extends ServiceProvider @@ -19,6 +22,49 @@ class AppServiceProvider extends ServiceProvider */ public function boot(): void { - // + $this->setupSlowQueryLogging(); + } + + /** + * 设置慢查询日志记录 + */ + private function setupSlowQueryLogging(): void + { + try { + DB::listen(function (QueryExecuted $query) { + $this->logSlowQuery($query); + }); + } catch (\Exception $e) { + // 如果SQL日志系统初始化失败,记录到默认日志但不影响主要业务 + + } + } + + + /** + * 记录慢查询 + */ + private function logSlowQuery(QueryExecuted $query): void + { + try { + // 根据环境设置不同的慢查询阈值, 本地环境所有查询都记录, 正式环境慢查询阈值500ms + $slowQueryThreshold = $this->app->environment(['local','development']) ? 0 : 500; + + // 只记录慢查询 + if ($query->time > $slowQueryThreshold) { + Log::channel('sql')->info('Slow Query: ' . $query->sql, [ + 'bindings' => $query->bindings, + 'time' => $query->time . 'ms', + 'environment' => $this->app->environment() + ]); + } + } catch (\Exception $e) { + // 慢查询日志记录失败,降级处理 + Log::error('慢查询日志记录失败', [ + 'query' => $query->sql, + 'bindings' => $query->bindings, + 'time' => $query->time . 'ms' + ]); + } } } diff --git a/app/Services/Auth/TokenAuthService.php b/app/Services/Auth/TokenAuthService.php index eb0d9a4..24dc702 100644 --- a/app/Services/Auth/TokenAuthService.php +++ b/app/Services/Auth/TokenAuthService.php @@ -105,7 +105,6 @@ class TokenAuthService try { // 使用Sanctum验证token $accessToken = PersonalAccessToken::findToken($token); - if (!$accessToken) { return null; } @@ -123,7 +122,7 @@ class TokenAuthService } // 检查用户状态 - if (!$user->is_active) { + if ($user->status != 0) { return null; } diff --git a/app/Services/System/SystemDictDataService.php b/app/Services/System/SystemDictDataService.php index 89cafc4..e94e573 100644 --- a/app/Services/System/SystemDictDataService.php +++ b/app/Services/System/SystemDictDataService.php @@ -72,15 +72,19 @@ class SystemDictDataService extends BaseService * @param bool $onlyActive * @return \Illuminate\Database\Eloquent\Collection */ - public function getByType(string $dictType, bool $onlyActive = true) + public function getByType(string $dictType = '', bool $onlyActive = true) { - $query = SystemDictData::where('dict_type', $dictType); + $query = SystemDictData::query(); + + if ($dictType) { + $query->where('dict_type', $dictType); + } if ($onlyActive) { $query->where('status', SystemDictData::STATUS_NORMAL); } - return $query->orderBy('sort')->get(); + return $query->select('id', 'label', 'value', 'dict_type')->get(); } /** diff --git a/config/cache.php b/config/cache.php index b279bff..f3093ee 100644 --- a/config/cache.php +++ b/config/cache.php @@ -15,7 +15,7 @@ return [ | */ - 'default' => env('CACHE_STORE', 'file'), + 'default' => env('CACHE_STORE', 'redis'), /* |-------------------------------------------------------------------------- diff --git a/config/logging.php b/config/logging.php index a69cd08..3eb29f9 100644 --- a/config/logging.php +++ b/config/logging.php @@ -51,18 +51,18 @@ return [ */ 'channels' => [ - 'stack' => [ 'driver' => 'stack', - 'channels' => explode(',', (string) env('LOG_STACK', 'single')), + 'channels' => ['daily'], 'ignore_exceptions' => false, ], 'single' => [ 'driver' => 'single', - 'path' => storage_path('logs/default/laravel.log'), + 'path' => storage_path('logs/laravel.log'), 'level' => env('LOG_LEVEL', 'debug'), 'replace_placeholders' => true, + 'permission' => 0664, ], 'daily' => [ diff --git a/database/seeders/SystemMenuSeeder.php b/database/seeders/SystemMenuSeeder.php new file mode 100644 index 0000000..cffbf16 --- /dev/null +++ b/database/seeders/SystemMenuSeeder.php @@ -0,0 +1,290 @@ +delete(); + SystemUserRole::query()->delete(); + SystemMenu::query()->delete(); + SystemRole::query()->delete(); + + // 创建角色 + $adminRole = SystemRole::create([ + 'name' => '超级管理员', + 'code' => 'superadmin', + 'sort' => 1, + 'data_scope' => 1, + 'status' => 0, + 'type' => 1, + 'remark' => '超级管理员角色', + 'creator' => $creator, + 'create_time' => $now, + 'updater' => $creator, + 'update_time' => $now, + 'deleted' => 0, + 'tenant_id' => 1, + ]); + + $testRole = SystemRole::create([ + 'name' => '测试角色', + 'code' => 'test', + 'sort' => 2, + 'data_scope' => 2, + 'status' => 0, + 'type' => 1, + 'remark' => '测试角色', + 'creator' => $creator, + 'create_time' => $now, + 'updater' => $creator, + 'update_time' => $now, + 'deleted' => 0, + 'tenant_id' => 1, + ]); + + // 创建菜单数据(参考test.json的结构) + $menus = [ + // 练习模块 + [ + 'id' => 2972, + 'name' => '练习', + 'parent_id' => 0, + 'type' => 1, + 'path' => '/exercise', + 'icon' => 'fa:tree', + 'component' => null, + 'component_name' => null, + 'status' => 0, + 'visible' => 0, + 'keep_alive' => 1, + 'always_show' => 1, + 'sort' => 1, + ], + [ + 'id' => 2892, + 'name' => '同步教材详情', + 'parent_id' => 2972, + 'type' => 2, + 'path' => 'textbook/catalog', + 'icon' => 'ep:list', + 'component' => '/textbook/catalog/index', + 'component_name' => 'TextbookCatalog', + 'status' => 0, + 'visible' => 0, + 'keep_alive' => 1, + 'always_show' => 1, + 'sort' => 1, + ], + [ + 'id' => 2898, + 'name' => '同步教材', + 'parent_id' => 2972, + 'type' => 2, + 'path' => 'textbook/catalogList', + 'icon' => 'fa-solid:book', + 'component' => '/textbook/catalog/list', + 'component_name' => null, + 'status' => 0, + 'visible' => 0, + 'keep_alive' => 1, + 'always_show' => 1, + 'sort' => 2, + ], + + // 基础数据管理模块 + [ + 'id' => 2808, + 'name' => '基础数据管理', + 'parent_id' => 0, + 'type' => 1, + 'path' => '/infra-data', + 'icon' => 'fa-solid:database', + 'component' => null, + 'component_name' => null, + 'status' => 0, + 'visible' => 0, + 'keep_alive' => 1, + 'always_show' => 1, + 'sort' => 2, + ], + [ + 'id' => 2930, + 'name' => '题目列表', + 'parent_id' => 2808, + 'type' => 2, + 'path' => 'question/list', + 'icon' => 'fa-solid:list-ul', + 'component' => '/question/index', + 'component_name' => 'InfraDataQuestion', + 'status' => 0, + 'visible' => 0, + 'keep_alive' => 1, + 'always_show' => 1, + 'sort' => 1, + ], + + // 系统管理模块 + [ + 'id' => 1, + 'name' => '系统管理', + 'parent_id' => 0, + 'type' => 1, + 'path' => '/system', + 'icon' => 'ep:tools', + 'component' => null, + 'component_name' => null, + 'status' => 0, + 'visible' => 0, + 'keep_alive' => 1, + 'always_show' => 1, + 'sort' => 10, + ], + [ + 'id' => 100, + 'name' => '用户管理', + 'parent_id' => 1, + 'type' => 2, + 'path' => 'user', + 'icon' => 'ep:avatar', + 'component' => 'system/user/index', + 'component_name' => 'SystemUser', + 'status' => 0, + 'visible' => 0, + 'keep_alive' => 1, + 'always_show' => 1, + 'sort' => 1, + ], + [ + 'id' => 101, + 'name' => '角色管理', + 'parent_id' => 1, + 'type' => 2, + 'path' => 'role', + 'icon' => 'ep:user', + 'component' => 'system/role/index', + 'component_name' => 'SystemRole', + 'status' => 0, + 'visible' => 0, + 'keep_alive' => 1, + 'always_show' => 1, + 'sort' => 2, + ], + [ + 'id' => 102, + 'name' => '菜单管理', + 'parent_id' => 1, + 'type' => 2, + 'path' => 'menu', + 'icon' => 'ep:menu', + 'component' => 'system/menu/index', + 'component_name' => 'SystemMenu', + 'status' => 0, + 'visible' => 0, + 'keep_alive' => 1, + 'always_show' => 1, + 'sort' => 3, + ], + [ + 'id' => 105, + 'name' => '字典管理', + 'parent_id' => 1, + 'type' => 2, + 'path' => 'dict', + 'icon' => 'ep:collection', + 'component' => 'system/dict/index', + 'component_name' => 'SystemDictType', + 'status' => 0, + 'visible' => 0, + 'keep_alive' => 1, + 'always_show' => 1, + 'sort' => 4, + ], + ]; + + // 批量插入菜单数据 + foreach ($menus as $menuData) { + $menuData['creator'] = $creator; + $menuData['create_time'] = $now; + $menuData['updater'] = $creator; + $menuData['update_time'] = $now; + $menuData['deleted'] = 0; + $menuData['tenant_id'] = 1; + + SystemMenu::create($menuData); + } + + // 为超级管理员分配所有菜单权限 + $allMenuIds = SystemMenu::pluck('id')->toArray(); + foreach ($allMenuIds as $menuId) { + SystemRoleMenu::create([ + 'role_id' => $adminRole->id, + 'menu_id' => $menuId, + 'creator' => $creator, + 'create_time' => $now, + 'deleted' => 0, + 'tenant_id' => 1, + ]); + } + + // 为测试角色只分配部分菜单权限(系统管理模块) + $testMenuIds = [1, 100, 101, 102, 105]; // 系统管理相关菜单 + foreach ($testMenuIds as $menuId) { + SystemRoleMenu::create([ + 'role_id' => $testRole->id, + 'menu_id' => $menuId, + 'creator' => $creator, + 'create_time' => $now, + 'deleted' => 0, + 'tenant_id' => 1, + ]); + } + + // 为现有用户分配角色 + $adminUser = User::where('username', 'admin')->first(); + if ($adminUser) { + SystemUserRole::create([ + 'user_id' => $adminUser->id, + 'role_id' => $adminRole->id, + 'creator' => $creator, + 'create_time' => $now, + 'deleted' => 0, + 'tenant_id' => 1, + ]); + } + + $testUser = User::where('username', 'test')->first(); + if ($testUser) { + SystemUserRole::create([ + 'user_id' => $testUser->id, + 'role_id' => $testRole->id, + 'creator' => $creator, + 'create_time' => $now, + 'deleted' => 0, + 'tenant_id' => 1, + ]); + } + + $this->command->info('菜单和角色权限数据创建成功!'); + $this->command->info('- 创建了超级管理员角色:superadmin(拥有所有菜单权限)'); + $this->command->info('- 创建了测试角色:test(仅拥有系统管理模块权限)'); + $this->command->info('- admin用户 -> 超级管理员角色'); + $this->command->info('- test用户 -> 测试角色'); + } +} diff --git a/routes/admin.php b/routes/admin.php index 3dac5aa..c20f1d3 100644 --- a/routes/admin.php +++ b/routes/admin.php @@ -39,6 +39,9 @@ Route::middleware('admin.auth')->group(function () { // 获取当前用户信息 Route::get('/me', [AuthController::class, 'me'])->name('admin.me'); + // 获取用户权限信息 + Route::get('/permission/info', [AuthController::class, 'permissionInfo'])->name('admin.permission.info'); + // 刷新Token Route::post('/refresh', [AuthController::class, 'refresh'])->name('admin.refresh'); @@ -52,21 +55,8 @@ Route::middleware('admin.auth')->group(function () { Route::delete('/cache', [AuthController::class, 'clearAuthCache'])->name('admin.cache.clear'); Route::get('/cache/stats', [AuthController::class, 'getCacheStats'])->name('admin.cache.stats'); - // 缓存测试(仅开发环境) - if (config('app.debug')) { - Route::get('/cache/test', function () { - $tokenAuthService = app(\App\Services\Auth\TokenAuthService::class); + // - $stats = $tokenAuthService->getCacheStats(); - - return response()->json([ - 'success' => true, - 'message' => '缓存测试结果', - 'data' => $stats, - 'timestamp' => now()->toDateTimeString() - ]); - })->name('admin.cache.test'); - } }); // 系统管理模块 @@ -80,63 +70,4 @@ Route::middleware('admin.auth')->group(function () { Route::delete('role/batch', [\App\Http\Controllers\Admin\System\SystemRoleController::class, 'batchDestroy'])->name('admin.system.role.batch.destroy'); }); - // 仪表盘数据 - Route::get('/dashboard', function () { - $user = Auth::user(); - return response()->json([ - 'success' => true, - 'data' => [ - 'message' => '欢迎来到后台管理系统', - 'user' => [ - 'id' => $user->id, - 'username' => $user->username, - 'nickname' => $user->nickname, - ], - 'stats' => [ - 'total_users' => \App\Models\User::count(), - 'online_users' => 1, - 'system_info' => [ - 'php_version' => PHP_VERSION, - 'laravel_version' => app()->version(), - ] - ] - ], - 'code' => 200, - 'message' => 'success' - ]); - })->name('admin.dashboard'); - - // 异常处理测试路由(仅开发环境) - if (config('app.debug')) { - Route::prefix('test')->group(function () { - // 测试参数验证异常 - Route::post('/validation', function () { - request()->validate([ - 'required_field' => 'required|string', - 'email_field' => 'required|email', - ]); - return response()->json(['message' => '验证通过']); - })->name('admin.test.validation'); - - // 测试业务异常 - Route::get('/business-exception', function () { - Handler::throw('测试数据不存在', 404); - })->name('admin.test.business'); - - // 测试系统异常 - Route::get('/system-exception', function () { - throw new \Exception('测试系统异常'); - })->name('admin.test.system'); - - // 测试参数错误异常 - Route::get('/param-error', function () { - Handler::error('测试参数错误'); - })->name('admin.test.param'); - - // 测试操作失败异常 - Route::get('/fail', function () { - Handler::fail('测试操作失败'); - })->name('admin.test.fail'); - }); - } }); diff --git a/routes/web.php b/routes/web.php index 93f25ba..acf6499 100644 --- a/routes/web.php +++ b/routes/web.php @@ -1,118 +1,53 @@ getCacheStats(); - - $output[] = "缓存驱动: " . ($stats['cache_store'] ?? 'unknown'); - $output[] = "缓存可用: " . ($stats['cache_available'] ? '✅ 是' : '❌ 否'); - $output[] = "缓存健康: " . ($stats['cache_health'] ? '✅ 正常' : '❌ 异常'); - $output[] = "缓存前缀: " . $stats['cache_prefix']; - $output[] = "默认缓存时间: " . $stats['default_cache_minutes'] . ' 分钟'; - $output[] = "最大缓存时间: " . $stats['max_cache_minutes'] . ' 分钟'; - $output[] = ""; - - // 3. 测试token验证 - $output[] = "3. 测试token验证..."; - $testToken = 'test_invalid_token_123'; - $user = $tokenAuthService->validateTokenAndGetUser($testToken); - - if ($user === null) { - $output[] = "✅ 无效token正确返回null"; - } else { - $output[] = "❌ 无效token验证失败"; - } - $output[] = ""; - - // 4. 测试中间件 - $output[] = "4. 测试中间件功能..."; - +// Redis缓存测试路由 +Route::get('/redis-test', function () { try { - // 创建模拟请求 - $request = Request::create('/admin/auth/me', 'GET'); - $request->headers->set('Authorization', 'Bearer invalid_token'); - $request->headers->set('Accept', 'application/json'); + $results = []; - // 实例化中间件 - $middleware = new AdminApiAuthenticate($tokenAuthService); + // 测试配置 + $results['cache_driver'] = config('cache.default'); + $results['redis_config'] = config('database.redis.cache'); - // 测试中间件 - $response = $middleware->handle($request, function ($req) { - return response()->json(['message' => 'Success']); - }); + // 测试缓存写入 + $testKey = 'redis_test_' . time(); + $testValue = 'Hello Redis from Laravel at ' . now(); - if ($response->getStatusCode() === 401) { - $output[] = "✅ 中间件正确返回401错误"; - $responseData = json_decode($response->getContent(), true); - $output[] = "响应消息: " . ($responseData['message'] ?? 'unknown'); - } else { - $output[] = "❌ 中间件未正确处理无效token"; - } + Cache::put($testKey, $testValue, 60); + $results['write_test'] = '✓ 成功'; - } catch (\Exception $e) { - $output[] = "❌ 中间件测试失败: " . $e->getMessage(); + // 测试缓存读取 + $readValue = Cache::get($testKey); + $results['read_test'] = $readValue === $testValue ? '✓ 成功' : '✗ 失败'; + $results['read_value'] = $readValue; + + // 测试缓存删除 + $deleted = Cache::forget($testKey); + $results['delete_test'] = $deleted ? '✓ 成功' : '✗ 失败'; + + // 验证删除 + $afterDelete = Cache::get($testKey); + $results['delete_verification'] = $afterDelete === null ? '✓ 成功' : '✗ 失败'; + + return response()->json([ + 'success' => true, + 'message' => 'Redis缓存测试完成', + 'results' => $results + ]); + + } catch (Exception $e) { + return response()->json([ + 'success' => false, + 'message' => 'Redis缓存测试失败', + 'error' => $e->getMessage(), + 'trace' => $e->getTraceAsString() + ], 500); } - $output[] = ""; - - // 5. 缓存性能测试 - $output[] = "5. 缓存性能测试..."; - - if ($stats['cache_health']) { - $startTime = microtime(true); - - // 模拟多次缓存操作 - for ($i = 0; $i < 10; $i++) { - $tokenAuthService->validateTokenAndGetUser('test_token_' . $i); - } - - $endTime = microtime(true); - $duration = round(($endTime - $startTime) * 1000, 2); - - $output[] = "✅ 完成10次token验证,耗时: {$duration}ms"; - } else { - $output[] = "⚠️ 缓存不可用,跳过性能测试"; - } - $output[] = ""; - - $output[] = "=== 测试完成 ==="; - - // 总结 - $cacheStatus = $stats['cache_health'] ? '正常工作' : '使用数据库回退'; - - $output[] = ""; - $output[] = "组件状态总结:"; - $output[] = "- 缓存功能: " . $cacheStatus; - $output[] = "- 中间件: ✅ 正常工作"; - $output[] = "- Token验证: ✅ 正常工作"; - $output[] = "- 异常处理: ✅ 正常工作"; - $output[] = ""; - - $output[] = "提示:如果要启用Redis缓存,请确保:"; - $output[] = "1. Redis服务正在运行"; - $output[] = "2. 在.env文件中设置 CACHE_STORE=redis"; - $output[] = "3. 在.env文件中设置 REDIS_CLIENT=predis"; - - return response('
' . implode("\n", $output) . '')
- ->header('Content-Type', 'text/html; charset=utf-8');
-});
+})->name('redis.test');