admin; if (!$admin instanceof Admin) { throw new \RuntimeException('管理員信息未找到。'); } $this->admin = $admin; } /** * 獲取 LLM 提供商列表 * * @return JsonResponse */ public function index(): JsonResponse { try { /** @var \Illuminate\Database\Eloquent\Builder $providers */ $providers = LlmProvider::select([ 'id', 'name', 'service_name', 'api_url', 'status', 'created_at', ]); // 如果不是超級管理員,只能看到自己管理的提供商 if (!$this->admin->isSuperAdmin()) { $providers->whereHas('clients', function ($query) { $query->whereHas('admins', function ($query) { $query->where('admin_id', $this->admin->id); }); }); } /** @var \Illuminate\Database\Eloquent\Collection $providerList */ $providerList = $providers->get(); return response()->json([ 'items' => $providerList->map(fn($provider) => [ 'id' => $provider->id, 'name' => $provider->name, 'service_name' => $provider->service_name, 'api_url' => $provider->api_url, 'status' => $provider->status, 'created_at' => $provider->created_at->toIso8601String(), ]) ]); } catch (\Exception $e) { Log::error('Error fetching LLM providers', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), ]); return response()->json([ 'error' => ErrorCode::SERVER_ERROR, 'message' => ErrorCode::getMessage(ErrorCode::SERVER_ERROR) ]); } } /** * 新增 LLM 提供商 * * @param Request $request * @return JsonResponse * @throws ValidationException */ public function store(Request $request): JsonResponse { try { // 只有超級管理員可以新增提供商 if (!$this->admin->isSuperAdmin()) { return response()->json([ 'error' => ErrorCode::FORBIDDEN, 'message' => '只有超級管理員可以新增 LLM 提供商。' ]); } /** @var array{ * name: string, * service_name: string, * api_url: string, * api_token: string * } $validated */ $validated = $request->validate([ 'name' => [ 'required', 'string', 'max:100', 'unique:llm_providers', ], 'service_name' => [ 'required', 'string', 'max:100', ], 'api_url' => [ 'required', 'string', 'url', 'max:255', ], 'api_token' => [ 'required', 'string', 'max:255', ], ]); $validated['status'] = LlmProvider::STATUS_ACTIVE; /** @var LlmProvider $provider */ $provider = LlmProvider::create($validated); return response()->json([ 'id' => $provider->id, 'name' => $provider->name, 'service_name' => $provider->service_name, 'api_url' => $provider->api_url, 'api_token' => $provider->api_token, 'created_at' => $provider->created_at->toIso8601String(), ]); } catch (ValidationException $e) { return response()->json([ 'error' => ErrorCode::VALIDATION_ERROR, 'message' => ErrorCode::getMessage(ErrorCode::VALIDATION_ERROR), 'errors' => $e->errors() ]); } catch (\Exception $e) { Log::error('Error creating LLM provider', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), 'request_data' => $request->except(['api_token']), ]); return response()->json([ 'error' => ErrorCode::SERVER_ERROR, 'message' => ErrorCode::getMessage(ErrorCode::SERVER_ERROR) ]); } } /** * 修改 LLM 提供商 */ public function update(Request $request, int $id): JsonResponse { try { $provider = LlmProvider::findOrFail($id); if (!$this->admin->canManageLlmProvider($provider->id)) { return response()->json([ 'error' => ErrorCode::FORBIDDEN, 'message' => '您無權管理該 LLM 提供商。' ]); } $validated = $request->validate([ 'name' => [ 'required', 'string', 'max:100', "unique:llm_providers,name,{$id}", ], 'service_name' => [ 'required', 'string', 'max:100', ], 'api_url' => [ 'required', 'string', 'url', 'max:255', ], 'api_token' => [ 'required', 'string', 'max:255', ], 'status' => [ 'required', 'string', 'in:active,inactive', ], ]); // 如果要停用提供商,檢查是否有客戶在使用 if ($validated['status'] === LlmProvider::STATUS_INACTIVE && $provider->status === LlmProvider::STATUS_ACTIVE) { if ($provider->clients()->exists()) { return response()->json([ 'error' => ErrorCode::RESOURCE_IN_USE, 'message' => '該提供商正在被客戶使用,無法停用。' ]); } } $provider->update($validated); return response()->json([ 'id' => $provider->id, 'name' => $provider->name, 'service_name' => $provider->service_name, 'api_url' => $provider->api_url, 'api_token' => $provider->api_token, 'updated_at' => $provider->updated_at->toIso8601String(), ]); } catch (ValidationException $e) { return response()->json([ 'error' => ErrorCode::VALIDATION_ERROR, 'message' => ErrorCode::getMessage(ErrorCode::VALIDATION_ERROR), 'errors' => $e->errors() ]); } catch (\Exception $e) { Log::error('Error updating LLM provider', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), 'provider_id' => $id, 'request_data' => $request->except(['api_token']), ]); return response()->json([ 'error' => ErrorCode::SERVER_ERROR, 'message' => ErrorCode::getMessage(ErrorCode::SERVER_ERROR) ]); } } /** * 刪除 LLM 提供商 */ public function destroy(int $id): JsonResponse { try { $provider = LlmProvider::findOrFail($id); if (!$this->admin->canManageLlmProvider($provider->id)) { return response()->json([ 'error' => ErrorCode::FORBIDDEN, 'message' => '您無權管理該 LLM 提供商。' ]); } // 檢查是否有客戶在使用 if ($provider->clients()->exists()) { return response()->json([ 'error' => ErrorCode::RESOURCE_IN_USE, 'message' => '該提供商正在被客戶使用,無法刪除。' ]); } $providerName = $provider->name; $provider->delete(); return response()->json([ 'message' => 'LLM 提供商已刪除。' ]); } catch (\Exception $e) { Log::error('Error deleting LLM provider', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), 'provider_id' => $id, ]); return response()->json([ 'error' => ErrorCode::SERVER_ERROR, 'message' => ErrorCode::getMessage(ErrorCode::SERVER_ERROR) ]); } } }