File size: 2,272 Bytes
cfea436
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import { Hono } from 'hono';
import { eq } from 'drizzle-orm';
import { prompts } from '../db/schema';
import { getFullSettings } from './settings';
import type { Env, Variables } from '../index';

export const translateApi = new Hono<{ Bindings: Env; Variables: Variables }>();

// POST /api/translate/:promptId  body: { kind: 'image' | 'video' }
translateApi.post('/:promptId', async (c) => {
  const db = c.var.db;
  const promptId = c.req.param('promptId');
  const { kind } = await c.req.json<{ kind: 'image' | 'video' }>();
  if (kind !== 'image' && kind !== 'video') return c.json({ error: 'bad_kind' }, 400);

  const p = (await db.select().from(prompts).where(eq(prompts.id, promptId))).at(0);
  if (!p) return c.json({ error: 'prompt_not_found' }, 404);
  const text = (kind === 'image' ? p.contentImage : p.contentVideo) || '';
  if (!text.trim()) return c.json({ error: 'empty_prompt' }, 400);

  const s = await getFullSettings(db);
  const baseUrl = (s.openaiBaseUrl || 'https://api.openai.com/v1').replace(/\/+$/, '');
  const apiKey = s.openaiApiKey;
  if (!apiKey) return c.json({ error: 'api_key_not_set' }, 400);

  const res = await fetch(baseUrl + '/chat/completions', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${apiKey}`,
    },
    body: JSON.stringify({
      model: s.translateModel || 'gpt-4o-mini',
      messages: [
        { role: 'system', content: '你是一个翻译助手。把用户输入的 AI 图像/视频生成提示词翻译成简体中文,只输出译文,不要解释,不要加引号。' },
        { role: 'user', content: text },
      ],
      temperature: 0.3,
    }),
  });
  if (!res.ok) {
    const t = await res.text();
    return c.json({ error: 'upstream_error', status: res.status, message: t.slice(0, 500) }, 502);
  }
  const data: any = await res.json();
  const tr = data?.choices?.[0]?.message?.content?.trim();
  if (!tr) return c.json({ error: 'empty_response' }, 502);

  const update: Record<string, any> = { updatedAt: Date.now() };
  if (kind === 'image') update.translationImage = tr;
  else update.translationVideo = tr;
  await db.update(prompts).set(update).where(eq(prompts.id, promptId));

  return c.json({ translation: tr });
});