122 lines
4.0 KiB
JavaScript
122 lines
4.0 KiB
JavaScript
const http = require('http');
|
||
const fs = require('fs');
|
||
const path = require('path');
|
||
|
||
const PORT = 3930;
|
||
const DEEPSEEK_KEY = 'sk-a9b69e9cd2dc4ca68d6aceaa84f22afb';
|
||
|
||
// Prompt 模板:三种模式
|
||
function buildPrompt(mode, input) {
|
||
const base = `你是一位专业的真人短剧编剧。请用以下专业格式输出剧本:
|
||
|
||
【人物表】
|
||
列出主要角色及简介
|
||
|
||
第X幕
|
||
|
||
场景 X · 地点 · 时间 · 内外景
|
||
[镜头提示] 动作/场景描述
|
||
角色名:(语气)"对白"
|
||
角色名:动作描述
|
||
[镜头切至] 下一个镜头
|
||
|
||
注意:
|
||
- 每场标注镜头语言(中景、特写、远景、跟拍等)
|
||
- 对白自然,符合人物性格
|
||
- 动作描写简洁有力
|
||
- 节奏紧凑,3-5分钟短剧体量`;
|
||
|
||
switch (mode) {
|
||
case 'auto':
|
||
return `${base}\n\n用户提供的主题:「${input}」\n请根据这个主题创作一个完整的真人短剧剧本。`;
|
||
case 'assist':
|
||
return `${base}\n\n用户提供的想法:「${input}」\n请根据这个想法展开,创作一个完整的真人短剧剧本。`;
|
||
case 'polish':
|
||
return `${base}\n\n以下是用户提供的剧本草稿。请在不改变核心情节的前提下,优化对白、增强画面感、调整节奏:\n\n${input}`;
|
||
default:
|
||
return `${base}\n\n用户输入:「${input}」`;
|
||
}
|
||
}
|
||
|
||
// 简易 HTML 注入
|
||
function serveStatic(res, filePath) {
|
||
const fullPath = path.join(__dirname, 'public', filePath);
|
||
try {
|
||
const data = fs.readFileSync(fullPath, 'utf-8');
|
||
const ext = path.extname(filePath);
|
||
const mime = { '.html': 'text/html', '.css': 'text/css', '.js': 'application/javascript' }[ext] || 'text/plain';
|
||
res.writeHead(200, { 'Content-Type': mime });
|
||
res.end(data);
|
||
} catch {
|
||
res.writeHead(404);
|
||
res.end('Not found');
|
||
}
|
||
}
|
||
|
||
const server = http.createServer(async (req, res) => {
|
||
const url = new URL(req.url, `http://localhost:${PORT}`);
|
||
const pathname = url.pathname;
|
||
|
||
// CORS
|
||
res.setHeader('Access-Control-Allow-Origin', '*');
|
||
res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
|
||
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
|
||
if (req.method === 'OPTIONS') { res.writeHead(200); res.end(); return; }
|
||
|
||
// 静态文件
|
||
if (pathname === '/' || pathname === '/index.html') return serveStatic(res, 'index.html');
|
||
|
||
// 生成剧本 API
|
||
if (pathname === '/api/generate' && req.method === 'POST') {
|
||
let body = '';
|
||
req.on('data', c => body += c);
|
||
req.on('end', async () => {
|
||
try {
|
||
const { mode, input } = JSON.parse(body);
|
||
if (!input || input.trim().length < 2) {
|
||
res.writeHead(400, { 'Content-Type': 'application/json' });
|
||
res.end(JSON.stringify({ error: '输入内容至少 2 个字符' }));
|
||
return;
|
||
}
|
||
|
||
const prompt = buildPrompt(mode || 'auto', input);
|
||
|
||
// 调 DeepSeek API
|
||
const apiRes = await fetch('https://api.deepseek.com/chat/completions', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
'Authorization': `Bearer ${DEEPSEEK_KEY}`
|
||
},
|
||
body: JSON.stringify({
|
||
model: 'deepseek-chat',
|
||
messages: [
|
||
{ role: 'system', content: '你是一位专业的真人短剧编剧。输出格式严格遵循用户要求的剧本格式。' },
|
||
{ role: 'user', content: prompt }
|
||
],
|
||
temperature: 0.8,
|
||
max_tokens: 4096
|
||
})
|
||
});
|
||
|
||
const data = await apiRes.json();
|
||
const content = data.choices?.[0]?.message?.content || '生成失败,请重试';
|
||
|
||
res.writeHead(200, { 'Content-Type': 'application/json' });
|
||
res.end(JSON.stringify({ success: true, content }));
|
||
} catch (e) {
|
||
res.writeHead(500, { 'Content-Type': 'application/json' });
|
||
res.end(JSON.stringify({ error: e.message }));
|
||
}
|
||
});
|
||
return;
|
||
}
|
||
|
||
res.writeHead(404);
|
||
res.end('Not found');
|
||
});
|
||
|
||
server.listen(PORT, '0.0.0.0', () => {
|
||
console.log(`[drama] 启动成功 http://0.0.0.0:${PORT}`);
|
||
});
|