'text/plain; charset=utf-8', ]); } return response(file_get_contents($path), 200, [ 'Content-Type' => 'text/html; charset=utf-8', ]); }; Route::get('/', fn () => $serveSpa('index.html')); Route::options('api/:path', function () { return response('', 204); })->pattern(['path' => '.*']); Route::group('api', function () { Route::post('auth/register', 'api.Auth/register'); Route::post('auth/login', 'api.Auth/login'); Route::post('auth/guest', 'api.Auth/guest'); Route::get('settings/features', 'api.Settings/features'); Route::get('settings/public', 'api.Settings/publicSettings'); Route::get('uploads/:filename', 'api.Upload/serve'); Route::group(function () { Route::get('auth/me', 'api.Auth/me'); Route::put('auth/profile', 'api.Auth/updateProfile'); Route::post('auth/logout', 'api.Auth/logout'); Route::get('conversations', 'api.Conversation/index'); Route::post('conversations', 'api.Conversation/create'); Route::get('conversations/:id', 'api.Conversation/show'); Route::put('conversations/:id', 'api.Conversation/update'); Route::delete('conversations/:id', 'api.Conversation/delete'); Route::get('conversations/:id/messages', 'api.Conversation/messages'); Route::post('chat/completions', 'api.Chat/completions'); Route::post('chat/speech', 'api.Chat/speech'); Route::post('chat/speech/stream', 'api.Chat/speechStream'); Route::post('chat/speech/cancel', 'api.Chat/speechCancel'); Route::post('upload', 'api.Upload/upload'); Route::get('models', 'api.Settings/models'); Route::get('agents', 'api.Settings/agents'); Route::get('short-drama/bootstrap', 'api.ShortDrama/bootstrap'); Route::get('short-drama/projects', 'api.ShortDrama/index'); Route::post('short-drama/projects', 'api.ShortDrama/createProject'); Route::get('short-drama/projects/:id', 'api.ShortDrama/show'); Route::delete('short-drama/projects/:id', 'api.ShortDrama/deleteProject'); Route::post('short-drama/projects/:id/characters', 'api.ShortDrama/addCharacter'); Route::delete('short-drama/projects/:id/characters/:characterId', 'api.ShortDrama/deleteCharacter'); Route::post('short-drama/projects/:id/generate', 'api.ShortDrama/generate'); Route::get('short-drama/projects/:id/status', 'api.ShortDrama/status'); Route::post('short-drama/projects/:id/shots/:shotId/retry', 'api.ShortDrama/retryShot'); })->middleware(\app\middleware\JwtAuth::class); Route::group('admin', function () { Route::get('users', 'api.Admin/users'); Route::post('users', 'api.Admin/createUser'); Route::put('users/:id', 'api.Admin/updateUser'); Route::delete('users/:id', 'api.Admin/deleteUser'); Route::get('guests', 'api.Admin/guests'); Route::put('guests/:id/status', 'api.Admin/updateGuestStatus'); Route::delete('guests/:id', 'api.Admin/deleteGuest'); Route::get('roles', 'api.Admin/roles'); Route::post('roles', 'api.Admin/createRole'); Route::put('roles/:id', 'api.Admin/updateRole'); Route::delete('roles/:id', 'api.Admin/deleteRole'); Route::get('permissions/tree', 'api.Admin/permissionTree'); Route::post('permissions', 'api.Admin/createPermission'); Route::put('permissions/:id', 'api.Admin/updatePermission'); Route::delete('permissions/:id', 'api.Admin/deletePermission'); Route::get('departments', 'api.Admin/departments'); Route::get('department-options', 'api.Admin/departmentOptions'); Route::post('departments', 'api.Admin/createDepartment'); Route::put('departments/:id', 'api.Admin/updateDepartment'); Route::delete('departments/:id', 'api.Admin/deleteDepartment'); Route::get('invitations', 'api.Admin/invitations'); Route::post('invitations', 'api.Admin/createInvitation'); Route::put('invitations/:id/revoke', 'api.Admin/revokeInvitation'); Route::get('conversations', 'api.Admin/conversations'); Route::get('conversations/:id', 'api.Admin/conversationDetail'); Route::get('stats', 'api.Admin/stats'); Route::get('settings', 'api.Admin/settings'); Route::put('settings', 'api.Admin/updateSettings'); Route::post('voice/reference', 'api.Admin/uploadVoiceReference'); Route::post('voice/preview', 'api.Admin/previewVoicePersona'); Route::get('models', 'api.Admin/models'); Route::post('models/test', 'api.Admin/testModel'); Route::post('models/:id/test', 'api.Admin/testModel'); Route::post('models', 'api.Admin/createModel'); Route::put('models/:id', 'api.Admin/updateModel'); Route::delete('models/:id', 'api.Admin/deleteModel'); Route::get('memberships', 'api.Admin/memberships'); Route::post('memberships', 'api.Admin/createMembership'); Route::put('memberships/:id', 'api.Admin/updateMembership'); Route::delete('memberships/:id', 'api.Admin/deleteMembership'); })->middleware([\app\middleware\JwtAuth::class, \app\middleware\AdminAuth::class]); })->middleware(Cors::class); // 伪静态误将前端路由交给 PHP 时的兜底(如 phpstudy 使用 ThinkPHP 默认规则) Route::miss(function () use ($serveSpa) { $path = ltrim(request()->pathinfo(), '/'); if ($path === '' || $path === 'index.php') { return $serveSpa('index.html'); } if (str_starts_with($path, 'api')) { return json(['code' => 1, 'message' => '接口不存在', 'data' => null], 404); } if (str_starts_with($path, 'admin')) { return $serveSpa('admin/index.html'); } return $serveSpa('index.html'); });