aiController.js 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. import { OpenAI } from 'openai';
  2. import pool from '../config/db.js';
  3. // 初始化 OpenAI API
  4. const openai = new OpenAI({
  5. apiKey: process.env.OPENAI_API_KEY,
  6. baseURL: process.env.OPENAI_API_URL,
  7. });
  8. // 获取用户数据作为系统提示词
  9. const getUserDataForPrompt = async (userId) => {
  10. try {
  11. // 获取用户的待办事项
  12. const [tasks] = await pool.query('SELECT * FROM tasks WHERE user_id = ?', [userId]);
  13. // 获取用户的时间安排
  14. const [schedules] = await pool.query('SELECT * FROM schedules WHERE user_id = ?', [userId]);
  15. return {
  16. tasks,
  17. schedules
  18. };
  19. } catch (error) {
  20. console.error('获取用户数据失败:', error);
  21. return {
  22. tasks: [],
  23. schedules: []
  24. };
  25. }
  26. };
  27. // @desc 与AI对话
  28. // @route POST /api/ai/chat
  29. // @access Private
  30. const chatWithAI = async (req, res) => {
  31. try {
  32. const { message } = req.query; // 从查询参数获取消息
  33. const userId = req.user.id;
  34. // 获取用户数据
  35. const userData = await getUserDataForPrompt(userId);
  36. // 准备系统提示词
  37. const systemPrompt = `你是一个任务管理助手。以下是用户的当前任务和时间安排数据:
  38. 任务数据:
  39. ${JSON.stringify(userData.tasks, null, 2)}
  40. 时间安排数据:
  41. ${JSON.stringify(userData.schedules, null, 2)}
  42. 请基于上述数据帮助用户回答问题、提供建议或分析他们的任务和时间安排。保持简洁、友好和有帮助性的回答。`;
  43. // 创建流式响应
  44. const stream = await openai.chat.completions.create({
  45. model: process.env.OPENAI_MODEL_NAME,
  46. messages: [
  47. { role: 'system', content: systemPrompt },
  48. { role: 'user', content: message }
  49. ],
  50. stream: true,
  51. });
  52. // 设置响应头
  53. res.setHeader('Content-Type', 'text/event-stream');
  54. res.setHeader('Cache-Control', 'no-cache');
  55. res.setHeader('Connection', 'keep-alive');
  56. // 流式发送响应
  57. for await (const chunk of stream) {
  58. const content = chunk.choices[0]?.delta?.content || '';
  59. if (content) {
  60. res.write(`data: ${JSON.stringify({ content })}\n\n`);
  61. }
  62. }
  63. res.write('data: [DONE]\n\n');
  64. res.end();
  65. } catch (error) {
  66. console.error(error);
  67. res.status(500).json({ message: '服务器错误' });
  68. }
  69. };
  70. // @desc 列举待完成事项
  71. // @route GET /api/ai/list-incomplete-tasks
  72. // @access Private
  73. const listIncompleteTasks = async (req, res) => {
  74. try {
  75. const userId = req.user.id;
  76. // 获取用户数据
  77. const userData = await getUserDataForPrompt(userId);
  78. // 准备系统提示词
  79. const systemPrompt = `你是一个任务管理助手。以下是用户的当前任务和时间安排数据:
  80. 任务数据:
  81. ${JSON.stringify(userData.tasks, null, 2)}
  82. 时间安排数据:
  83. ${JSON.stringify(userData.schedules, null, 2)}
  84. 请列举出所有未完成的任务,按照预计完成时间排序,并给出简短的建议。`;
  85. // 创建流式响应
  86. const stream = await openai.chat.completions.create({
  87. model: process.env.OPENAI_MODEL_NAME,
  88. messages: [
  89. { role: 'system', content: systemPrompt },
  90. { role: 'user', content: '请列举我所有未完成的任务,并提供一些建议。' }
  91. ],
  92. stream: true,
  93. });
  94. // 设置响应头
  95. res.setHeader('Content-Type', 'text/event-stream');
  96. res.setHeader('Cache-Control', 'no-cache');
  97. res.setHeader('Connection', 'keep-alive');
  98. // 流式发送响应
  99. for await (const chunk of stream) {
  100. const content = chunk.choices[0]?.delta?.content || '';
  101. if (content) {
  102. res.write(`data: ${JSON.stringify({ content })}\n\n`);
  103. }
  104. }
  105. res.write('data: [DONE]\n\n');
  106. res.end();
  107. } catch (error) {
  108. console.error(error);
  109. res.status(500).json({ message: '服务器错误' });
  110. }
  111. };
  112. // @desc 推荐新的事件
  113. // @route GET /api/ai/recommend-events
  114. // @access Private
  115. const recommendEvents = async (req, res) => {
  116. try {
  117. const userId = req.user.id;
  118. // 获取用户数据
  119. const userData = await getUserDataForPrompt(userId);
  120. // 准备系统提示词
  121. const systemPrompt = `你是一个任务管理助手。以下是用户的当前任务和时间安排数据:
  122. 任务数据:
  123. ${JSON.stringify(userData.tasks, null, 2)}
  124. 时间安排数据:
  125. ${JSON.stringify(userData.schedules, null, 2)}
  126. 请基于用户当前的任务和时间安排,推荐2-3个新的事件或活动,这些事件应该有助于提高用户的工作效率或生活质量。`;
  127. // 创建流式响应
  128. const stream = await openai.chat.completions.create({
  129. model: process.env.OPENAI_MODEL_NAME,
  130. messages: [
  131. { role: 'system', content: systemPrompt },
  132. { role: 'user', content: '请根据我的任务和时间安排,推荐一些新的事件或活动。' }
  133. ],
  134. stream: true,
  135. });
  136. // 设置响应头
  137. res.setHeader('Content-Type', 'text/event-stream');
  138. res.setHeader('Cache-Control', 'no-cache');
  139. res.setHeader('Connection', 'keep-alive');
  140. // 流式发送响应
  141. for await (const chunk of stream) {
  142. const content = chunk.choices[0]?.delta?.content || '';
  143. if (content) {
  144. res.write(`data: ${JSON.stringify({ content })}\n\n`);
  145. }
  146. }
  147. res.write('data: [DONE]\n\n');
  148. res.end();
  149. } catch (error) {
  150. console.error(error);
  151. res.status(500).json({ message: '服务器错误' });
  152. }
  153. };
  154. // @desc 综合分析
  155. // @route GET /api/ai/comprehensive-analysis
  156. // @access Private
  157. const comprehensiveAnalysis = async (req, res) => {
  158. try {
  159. const userId = req.user.id;
  160. // 获取用户数据
  161. const userData = await getUserDataForPrompt(userId);
  162. // 准备系统提示词
  163. const systemPrompt = `你是一个任务管理助手。以下是用户的当前任务和时间安排数据:
  164. 任务数据:
  165. ${JSON.stringify(userData.tasks, null, 2)}
  166. 时间安排数据:
  167. ${JSON.stringify(userData.schedules, null, 2)}
  168. 请对用户的任务和时间安排进行全面分析,包括:
  169. 1. 工作负载分析:任务数量、重要程度分布、截止日期分布
  170. 2. 时间利用分析:空闲时间、重复活动、潜在冲突
  171. 3. 效率提升建议:如何更好地安排任务和时间
  172. 4. 习惯和模式:从数据中可以看出的习惯和模式
  173. 请提供具体、可操作的建议。`;
  174. // 创建流式响应
  175. const stream = await openai.chat.completions.create({
  176. model: process.env.OPENAI_MODEL_NAME,
  177. messages: [
  178. { role: 'system', content: systemPrompt },
  179. { role: 'user', content: '请对我的任务和时间安排进行全面分析。' }
  180. ],
  181. stream: true,
  182. });
  183. // 设置响应头
  184. res.setHeader('Content-Type', 'text/event-stream');
  185. res.setHeader('Cache-Control', 'no-cache');
  186. res.setHeader('Connection', 'keep-alive');
  187. // 流式发送响应
  188. for await (const chunk of stream) {
  189. const content = chunk.choices[0]?.delta?.content || '';
  190. if (content) {
  191. res.write(`data: ${JSON.stringify({ content })}\n\n`);
  192. }
  193. }
  194. res.write('data: [DONE]\n\n');
  195. res.end();
  196. } catch (error) {
  197. console.error(error);
  198. res.status(500).json({ message: '服务器错误' });
  199. }
  200. };
  201. export { chatWithAI, listIncompleteTasks, recommendEvents, comprehensiveAnalysis };