ai-generate-controller.ts 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. /**
  2. * AI 文本生成 - API 路由
  3. * 简单的 AI 文本生成,用户输入主题,直接调用 AI 生成内容
  4. */
  5. import Router from '@koa/router';
  6. import { Context } from 'koa';
  7. import { callLLM } from '../../services/llm';
  8. const router = new Router();
  9. /**
  10. * POST /api/book-generator/ai-generate
  11. * AI 生成文本内容
  12. */
  13. router.post('/ai-generate', async (ctx: Context) => {
  14. try {
  15. const body = ctx.request.body as {
  16. topic: string;
  17. type?: string; // 'article' | 'story' | 'summary'
  18. length?: 'short' | 'medium' | 'long'; // 'short' ~500字, 'medium' ~1000字, 'long' ~2000字
  19. };
  20. if (!body.topic || body.topic.trim().length === 0) {
  21. ctx.status = 400;
  22. ctx.body = { code: 1, message: '请输入主题' };
  23. return;
  24. }
  25. const topic = body.topic.trim();
  26. const length = body.length || 'medium';
  27. // 根据长度设置字数要求
  28. const lengthConfig = {
  29. short: { words: '500-800', desc: '简短精炼' },
  30. medium: { words: '1000-1500', desc: '中等长度' },
  31. long: { words: '2000-3000', desc: '详细深入' },
  32. };
  33. const config = lengthConfig[length as keyof typeof lengthConfig];
  34. // 构建 prompt
  35. const prompt = `请为"${topic}"主题写一篇${config.desc}的文章。
  36. 要求:
  37. 1. 字数:约${config.words}字
  38. 2. 内容要有深度,逻辑清晰
  39. 3. 语言流畅自然
  40. 4. 直接输出正文,不要有标题和额外说明
  41. 请直接输出文章内容:`;
  42. console.log(`[AI Generate] 主题: ${topic}, 长度: ${length}`);
  43. // 异步调用 AI
  44. const generateContent = async () => {
  45. try {
  46. const content = await callLLM(prompt);
  47. console.log(`[AI Generate] 生成完成,字数: ${content.length}`);
  48. return { success: true, content, wordCount: content.length };
  49. } catch (error: any) {
  50. console.error('[AI Generate] 生成失败:', error);
  51. return { success: false, error: error.message || '生成失败' };
  52. }
  53. };
  54. // 异步执行,不阻塞
  55. const resultPromise = generateContent();
  56. // 先返回任务ID
  57. const taskId = `ai_${Date.now()}`;
  58. // 异步处理结果(不等待)
  59. resultPromise.then(result => {
  60. // 可以在这里存储结果或发送通知
  61. console.log(`[AI Generate] 任务 ${taskId} 完成:`, result.success ? '成功' : '失败');
  62. });
  63. ctx.body = {
  64. code: 0,
  65. message: 'AI 生成任务已启动',
  66. data: {
  67. taskId,
  68. topic,
  69. status: 'started',
  70. },
  71. };
  72. } catch (error) {
  73. console.error('[AI Generate] 启动失败:', error);
  74. ctx.status = 500;
  75. ctx.body = {
  76. code: 1,
  77. message: error instanceof Error ? error.message : '启动失败',
  78. };
  79. }
  80. });
  81. /**
  82. * POST /api/book-generator/ai-generate/sync
  83. * AI 同步生成文本内容(等待结果)
  84. */
  85. router.post('/ai-generate/sync', async (ctx: Context) => {
  86. try {
  87. const body = ctx.request.body as {
  88. topic: string;
  89. };
  90. if (!body.topic || body.topic.trim().length === 0) {
  91. ctx.status = 400;
  92. ctx.body = { code: 1, message: '请输入主题' };
  93. return;
  94. }
  95. const topic = body.topic.trim();
  96. // 构建 prompt - 根据用户输入生成内容
  97. const prompt = `${topic}
  98. 请根据上面的要求生成内容,要求:
  99. 1. 内容要有深度,逻辑清晰,论述完整
  100. 2. 语言流畅自然
  101. 3. 直接输出正文,不要有标题和其他说明
  102. 请直接输出内容:`;
  103. console.log(`[AI Generate Sync] 主题: ${topic}`);
  104. // 同步调用 AI
  105. const content = await callLLM(prompt);
  106. console.log(`[AI Generate Sync] 生成完成,字数: ${content.length}`);
  107. ctx.body = {
  108. code: 0,
  109. message: '生成成功',
  110. data: {
  111. topic,
  112. content,
  113. wordCount: content.length,
  114. },
  115. };
  116. } catch (error: any) {
  117. console.error('[AI Generate Sync] 生成失败:', error);
  118. ctx.status = 500;
  119. ctx.body = {
  120. code: 1,
  121. message: error.message || '生成失败,请稍后重试',
  122. };
  123. }
  124. });
  125. export default router;