132 lines
4.4 KiB
JavaScript
132 lines
4.4 KiB
JavaScript
const express = require('express');
|
|
const { v4: uuidv4 } = require('uuid');
|
|
const { readTable, writeTable } = require('../utils/db');
|
|
const authMiddleware = require('../middleware/auth');
|
|
|
|
const router = express.Router();
|
|
|
|
// POST /api/ai/conversations — 保存一次对话
|
|
router.post('/', authMiddleware, (req, res) => {
|
|
const { sceneId, roomId, messages } = req.body || {};
|
|
if (!sceneId || !Array.isArray(messages)) {
|
|
return res.status(400).json({ code: 400, message: 'sceneId 和 messages 不能为空' });
|
|
}
|
|
|
|
const conversations = readTable('conversations');
|
|
const now = new Date().toISOString();
|
|
|
|
// 统一存为 role/content 格式,兼容旧的 { userId, text } 格式
|
|
const formattedMessages = messages.map((m) => ({
|
|
role: (m.role === 'user' || m.role === 'assistant')
|
|
? m.role
|
|
: (m.userId === req.user.userId ? 'user' : 'assistant'),
|
|
content: m.content || m.text || '',
|
|
createdAt: m.time || now,
|
|
}));
|
|
|
|
// 推断会话开始/结束时间
|
|
const startedAt = formattedMessages[0]?.createdAt || now;
|
|
const endedAt = formattedMessages[formattedMessages.length - 1]?.createdAt || now;
|
|
|
|
const session = {
|
|
id: uuidv4(),
|
|
userId: req.user.userId,
|
|
sceneId,
|
|
roomId: roomId || '',
|
|
startedAt,
|
|
endedAt,
|
|
createdAt: now,
|
|
messages: formattedMessages,
|
|
};
|
|
|
|
conversations.push(session);
|
|
writeTable('conversations', conversations);
|
|
|
|
return res.json({ code: 200, data: { sessionId: session.id } });
|
|
});
|
|
|
|
// GET /api/ai/conversations — 分页列表(仅当前用户)
|
|
router.get('/', authMiddleware, (req, res) => {
|
|
const page = Math.max(1, parseInt(req.query.page) || 1);
|
|
const size = Math.max(1, Math.min(100, parseInt(req.query.size) || 20));
|
|
|
|
const all = readTable('conversations').filter((c) => c.userId === req.user.userId);
|
|
// 按时间倒序
|
|
all.sort((a, b) => new Date(b.createdAt) - new Date(a.createdAt));
|
|
|
|
const total = all.length;
|
|
const list = all.slice((page - 1) * size, page * size).map((c) => ({
|
|
id: c.id,
|
|
sceneId: c.sceneId,
|
|
roomId: c.roomId,
|
|
startedAt: c.startedAt,
|
|
endedAt: c.endedAt,
|
|
messageCount: c.messages.length,
|
|
firstMessage: c.messages.find((m) => m.role === 'user')?.content || '',
|
|
}));
|
|
|
|
return res.json({ code: 200, data: { total, page, size, list } });
|
|
});
|
|
|
|
// GET /api/ai/conversations/:id — 详情(含消息)
|
|
router.get('/:id', authMiddleware, (req, res) => {
|
|
const conversations = readTable('conversations');
|
|
const conv = conversations.find((c) => c.id === req.params.id);
|
|
|
|
if (!conv) {
|
|
return res.status(404).json({ code: 404, message: '对话记录不存在' });
|
|
}
|
|
if (conv.userId !== req.user.userId) {
|
|
return res.status(403).json({ code: 403, message: '无权访问该对话' });
|
|
}
|
|
|
|
return res.json({ code: 200, data: conv });
|
|
});
|
|
|
|
// POST /api/ai/conversations/:id/append — 继续对话追加消息
|
|
router.post('/:id/append', authMiddleware, (req, res) => {
|
|
const { messages } = req.body || {};
|
|
if (!Array.isArray(messages)) {
|
|
return res.status(400).json({ code: 400, message: 'messages 不能为空' });
|
|
}
|
|
|
|
const conversations = readTable('conversations');
|
|
const conv = conversations.find((c) => c.id === req.params.id);
|
|
|
|
if (!conv) return res.status(404).json({ code: 404, message: '对话记录不存在' });
|
|
if (conv.userId !== req.user.userId) return res.status(403).json({ code: 403, message: '无权操作该对话' });
|
|
|
|
const now = new Date().toISOString();
|
|
const newFormatted = messages.map((m) => ({
|
|
role: m.role === 'user' || m.role === 'assistant' ? m.role : 'assistant',
|
|
content: m.content || '',
|
|
createdAt: m.time || now,
|
|
}));
|
|
|
|
conv.messages.push(...newFormatted);
|
|
conv.endedAt = newFormatted[newFormatted.length - 1]?.createdAt || now;
|
|
|
|
writeTable('conversations', conversations);
|
|
return res.json({ code: 200, data: { sessionId: conv.id } });
|
|
});
|
|
|
|
// DELETE /api/ai/conversations/:id — 删除(仅本人)
|
|
router.delete('/:id', authMiddleware, (req, res) => {
|
|
const conversations = readTable('conversations');
|
|
const idx = conversations.findIndex((c) => c.id === req.params.id);
|
|
|
|
if (idx === -1) {
|
|
return res.status(404).json({ code: 404, message: '对话记录不存在' });
|
|
}
|
|
if (conversations[idx].userId !== req.user.userId) {
|
|
return res.status(403).json({ code: 403, message: '无权删除该对话' });
|
|
}
|
|
|
|
conversations.splice(idx, 1);
|
|
writeTable('conversations', conversations);
|
|
|
|
return res.json({ code: 200, data: null });
|
|
});
|
|
|
|
module.exports = router;
|