Your Name 712041bbeb
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
添加模型后备功能和优化图片生成
2025-12-19 15:30:18 +08:00

154 lines
4.7 KiB
TypeScript

import { z } from "zod";
import { requireAdmin } from "@/lib/middleware/admin";
import {
getAllAiModels,
getAiModelById,
getAiModelsByProviderId,
createAiModel,
updateAiModel,
deleteAiModel,
getAiProviderById,
} from "@/lib/db/queries";
import { ChatSDKError } from "@/lib/errors";
const createModelSchema = z.object({
providerId: z.string().uuid(),
modelId: z.string().min(1).max(128),
displayName: z.string().min(1).max(128),
description: z.string().optional(),
supportsVision: z.boolean().optional(),
supportsImageGen: z.boolean().optional(),
isEnabled: z.boolean().optional(),
isDefault: z.boolean().optional(),
sortOrder: z.number().optional(),
fallbackModelId1: z.string().max(128).optional(), // 🆕 备用模型 ID 1
fallbackModelId2: z.string().max(128).optional(), // 🆕 备用模型 ID 2
});
const updateModelSchema = z.object({
id: z.string().uuid(),
providerId: z.string().uuid().optional(), // 允许修改提供商
modelId: z.string().min(1).max(128).optional(),
displayName: z.string().min(1).max(128).optional(),
description: z.string().optional(),
supportsVision: z.boolean().optional(),
supportsImageGen: z.boolean().optional(),
isEnabled: z.boolean().optional(),
isDefault: z.boolean().optional(),
sortOrder: z.number().optional(),
fallbackModelId1: z.string().max(128).optional(), // 🆕 备用模型 ID 1
fallbackModelId2: z.string().max(128).optional(), // 🆕 备用模型 ID 2
});
export async function GET(request: Request) {
try {
await requireAdmin();
const { searchParams } = new URL(request.url);
const id = searchParams.get("id");
const providerId = searchParams.get("providerId");
if (id) {
const model = await getAiModelById({ id });
if (!model) {
return new ChatSDKError("bad_request:api", "Model not found").toResponse();
}
return Response.json({ model });
}
if (providerId) {
const models = await getAiModelsByProviderId({ providerId });
return Response.json({ models });
}
const models = await getAllAiModels();
return Response.json({ models });
} catch (error) {
if (error instanceof ChatSDKError) {
return error.toResponse();
}
return new ChatSDKError("offline:admin").toResponse();
}
}
export async function POST(request: Request) {
try {
await requireAdmin();
const body = await request.json();
const data = createModelSchema.parse(body);
// 验证 provider 是否存在
const provider = await getAiProviderById({ id: data.providerId });
if (!provider) {
return new ChatSDKError("bad_request:api", "Provider not found").toResponse();
}
const model = await createAiModel(data);
return Response.json({ model: model[0] });
} catch (error) {
if (error instanceof ChatSDKError) {
return error.toResponse();
}
if (error instanceof z.ZodError) {
return new ChatSDKError("bad_request:api", error.message).toResponse();
}
return new ChatSDKError("offline:admin").toResponse();
}
}
export async function PUT(request: Request) {
try {
await requireAdmin();
const body = await request.json();
console.log("[Admin API] Update model request body:", JSON.stringify(body)); // Debug log
const data = updateModelSchema.parse(body);
console.log("[Admin API] Validation passed, updating model..."); // Debug log
const model = await updateAiModel(data);
if (model.length === 0) {
console.error("[Admin API] Model not found:", data.id); // Debug log
return new ChatSDKError("bad_request:api", "Model not found").toResponse();
}
console.log("[Admin API] Model updated successfully:", model[0].id); // Debug log
return Response.json({ model: model[0] });
} catch (error) {
console.error("[Admin API] Update model error:", error); // Debug log
if (error instanceof ChatSDKError) {
return error.toResponse();
}
if (error instanceof z.ZodError) {
console.error("[Admin API] Validation error details:", error.errors); // Debug log
return new ChatSDKError("bad_request:api", error.message).toResponse();
}
return new ChatSDKError("offline:admin").toResponse();
}
}
export async function DELETE(request: Request) {
try {
await requireAdmin();
const { searchParams } = new URL(request.url);
const id = searchParams.get("id");
if (!id) {
return new ChatSDKError("bad_request:api", "Model ID is required").toResponse();
}
await deleteAiModel({ id });
return Response.json({ success: true });
} catch (error) {
if (error instanceof ChatSDKError) {
return error.toResponse();
}
return new ChatSDKError("offline:admin").toResponse();
}
}