|
|
@@ -0,0 +1,63 @@
|
|
|
+import { NextRequest, NextResponse } from 'next/server';
|
|
|
+import { buildIronRulesPrompt } from '@/app/lib/chapter-prompts';
|
|
|
+
|
|
|
+export async function POST(request: NextRequest) {
|
|
|
+ const body = await request.json().catch(() => null);
|
|
|
+ if (!body) return NextResponse.json({ success: false, error: '无效的请求体' }, { status: 400 });
|
|
|
+
|
|
|
+ const { projectInfo, apiSettings } = body;
|
|
|
+ if (!projectInfo || !apiSettings) {
|
|
|
+ return NextResponse.json({ success: false, error: '缺少参数' }, { status: 400 });
|
|
|
+ }
|
|
|
+
|
|
|
+ const prompt = buildIronRulesPrompt(projectInfo);
|
|
|
+
|
|
|
+ try {
|
|
|
+ const response = await fetch(apiSettings.apiUrl, {
|
|
|
+ method: 'POST',
|
|
|
+ headers: {
|
|
|
+ 'Content-Type': 'application/json',
|
|
|
+ Authorization: `Bearer ${apiSettings.apiKey}`,
|
|
|
+ },
|
|
|
+ body: JSON.stringify({
|
|
|
+ model: apiSettings.model,
|
|
|
+ messages: [{ role: 'user', content: prompt }],
|
|
|
+ max_tokens: 1000,
|
|
|
+ }),
|
|
|
+ signal: AbortSignal.timeout(55000),
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!response.ok) {
|
|
|
+ return NextResponse.json({ success: false, error: `AI 请求失败: ${response.status}` }, { status: 502 });
|
|
|
+ }
|
|
|
+
|
|
|
+ const data = await response.json();
|
|
|
+ const text = data.choices?.[0]?.message?.content || '';
|
|
|
+
|
|
|
+ // Parse JSON from response (handle markdown code fences)
|
|
|
+ const jsonMatch = text.match(/```(?:json)?\s*([\s\S]*?)```/) || [null, text];
|
|
|
+ const rules = JSON.parse(jsonMatch[1].trim());
|
|
|
+
|
|
|
+ // Format as markdown
|
|
|
+ const categories: Record<string, string> = {
|
|
|
+ character: '角色铁律',
|
|
|
+ worldbuilding: '世界观铁律',
|
|
|
+ plot: '情节铁律',
|
|
|
+ style: '风格铁律',
|
|
|
+ };
|
|
|
+ let markdown = '# 项目铁律\n\n';
|
|
|
+ for (const [cat, label] of Object.entries(categories)) {
|
|
|
+ const catRules = rules.filter((r: { category: string }) => r.category === cat);
|
|
|
+ if (catRules.length === 0) continue;
|
|
|
+ markdown += `## ${label}\n\n`;
|
|
|
+ for (const r of catRules) {
|
|
|
+ markdown += `- ${r.rule}\n`;
|
|
|
+ }
|
|
|
+ markdown += '\n';
|
|
|
+ }
|
|
|
+
|
|
|
+ return NextResponse.json({ success: true, rules, markdown });
|
|
|
+ } catch (error) {
|
|
|
+ return NextResponse.json({ success: false, error: (error as Error).message }, { status: 500 });
|
|
|
+ }
|
|
|
+}
|