backup codes

This commit is contained in:
2026-07-22 15:38:37 +08:00
parent 2feb6004b8
commit cf63ed5e3f

View File

@@ -103,7 +103,7 @@ app.get('/api/rooms', auth, (req, res) => {
rooms = db.prepare("SELECT * FROM rooms WHERE white_list = '' OR (',' || white_list || ',' LIKE ?)").all(`%,${username},%`); rooms = db.prepare("SELECT * FROM rooms WHERE white_list = '' OR (',' || white_list || ',' LIKE ?)").all(`%,${username},%`);
} }
const result = rooms.map(room => { const result = rooms.map(room => {
const lastMsg = db.prepare('SELECT text, timestamp FROM messages WHERE room_id = ? ORDER BY timestamp DESC LIMIT 1').get(room.id); const lastMsg = db.prepare('SELECT text, timestamp FROM messages WHERE room_id = ? ORDER BY id DESC LIMIT 1').get(room.id);
return { return {
...room, ...room,
last_message: lastMsg ? lastMsg.text : '', last_message: lastMsg ? lastMsg.text : '',
@@ -144,7 +144,7 @@ app.delete('/api/rooms/:roomId', auth, adminOnly, (req, res) => {
}); });
app.get('/api/rooms/:roomId/messages', auth, (req, res) => { app.get('/api/rooms/:roomId/messages', auth, (req, res) => {
const msgs = db.prepare('SELECT * FROM messages WHERE room_id = ? ORDER BY timestamp ASC').all(req.params.roomId); const msgs = db.prepare('SELECT * FROM messages WHERE room_id = ? ORDER BY id ASC').all(req.params.roomId);
res.json(msgs); res.json(msgs);
}); });
@@ -159,7 +159,7 @@ app.post('/api/rooms/:roomId/messages', auth, async (req, res) => {
); );
const msg = { id: result.lastInsertRowid, room_id: roomId, user: username, text: text || '', attachments: attachments || [], timestamp: now }; const msg = { id: result.lastInsertRowid, room_id: roomId, user: username, text: text || '', attachments: attachments || [], timestamp: now };
const lastMsg = db.prepare('SELECT text, timestamp FROM messages WHERE room_id = ? ORDER BY timestamp DESC LIMIT 1').get(roomId); const lastMsg = db.prepare('SELECT text, timestamp FROM messages WHERE room_id = ? ORDER BY id DESC LIMIT 1').get(roomId);
broadcastToRoomExcludeSelf(roomId, username, { broadcastToRoomExcludeSelf(roomId, username, {
type: 'new_message', message: msg, type: 'new_message', message: msg,
room_preview: { room_id: roomId, last_message: lastMsg ? lastMsg.text : '', last_time: lastMsg ? lastMsg.timestamp : '' } room_preview: { room_id: roomId, last_message: lastMsg ? lastMsg.text : '', last_time: lastMsg ? lastMsg.timestamp : '' }
@@ -195,7 +195,7 @@ app.get('/api/rooms/:roomId/purchases', auth, (req, res) => {
app.get('/api/purchases/:id', auth, (req, res) => { app.get('/api/purchases/:id', auth, (req, res) => {
const pur = db.prepare('SELECT * FROM purchases WHERE id = ?').get(req.params.id); const pur = db.prepare('SELECT * FROM purchases WHERE id = ?').get(req.params.id);
if (!pur) return res.status(404).json({ error: '未找到' }); if (!pur) return res.status(404).json({ error: '未找到' });
const history = db.prepare('SELECT * FROM purchase_history WHERE purchase_id = ? ORDER BY timestamp ASC').all(req.params.id); const history = db.prepare('SELECT * FROM purchase_history WHERE purchase_id = ? ORDER BY id ASC').all(req.params.id);
const attachments = db.prepare('SELECT * FROM purchase_attachments WHERE purchase_id = ?').all(req.params.id); const attachments = db.prepare('SELECT * FROM purchase_attachments WHERE purchase_id = ?').all(req.params.id);
res.json({ ...pur, history, attachments }); res.json({ ...pur, history, attachments });
}); });
@@ -273,7 +273,7 @@ function storeAndBroadcastText(roomId, user, text) {
const now = timestamp(); const now = timestamp();
const result = db.prepare('INSERT INTO messages (room_id, user, text, timestamp) VALUES (?,?,?,?)').run(roomId, user, text, now); const result = db.prepare('INSERT INTO messages (room_id, user, text, timestamp) VALUES (?,?,?,?)').run(roomId, user, text, now);
const msg = { id: result.lastInsertRowid, room_id: roomId, user, text, attachments: [], timestamp: now }; const msg = { id: result.lastInsertRowid, room_id: roomId, user, text, attachments: [], timestamp: now };
const lastMsg = db.prepare('SELECT text, timestamp FROM messages WHERE room_id = ? ORDER BY timestamp DESC LIMIT 1').get(roomId); const lastMsg = db.prepare('SELECT text, timestamp FROM messages WHERE room_id = ? ORDER BY id DESC LIMIT 1').get(roomId);
broadcastToRoom(roomId, { type: 'new_message', message: msg, room_preview: { room_id: roomId, last_message: lastMsg ? lastMsg.text : '', last_time: lastMsg ? lastMsg.timestamp : '' } }); broadcastToRoom(roomId, { type: 'new_message', message: msg, room_preview: { room_id: roomId, last_message: lastMsg ? lastMsg.text : '', last_time: lastMsg ? lastMsg.timestamp : '' } });
return msg; return msg;
} }
@@ -344,9 +344,13 @@ async function analyzeWithDeepSeek(text, historyMessages, username, isAdmin) {
不提供任何数量、价格字段,系统会自动查找最近一张图片并关联。 不提供任何数量、价格字段,系统会自动查找最近一张图片并关联。
⚠️ 采购规则: ⚠️ 采购规则:
- 新建 vs 更新(极其重要):
* 如果用户提到"昨天/今天/刚刚/又/再/新/另一批/另外"等时间或重复购买词汇,必须返回 "is_new": true系统会强制创建新记录。
* 如果用户明确说"改一下/更新/修改/调整/更正"等词汇,才不提供 is_new 或设为 false系统会尝试匹配已有记录更新。
* 当无法确定是新建还是更新时,默认视为新建(返回 is_new: true
- 用户补充信息时更新已有记录。更新时请返回完整字段值包括未变化的字段。如果用户要求修改时间请生成正确的created_time字段。 - 用户补充信息时更新已有记录。更新时请返回完整字段值包括未变化的字段。如果用户要求修改时间请生成正确的created_time字段。
- 总金额amount由系统自动按数量×单价+邮费计算,你无需提供该字段。 - 总金额amount由系统自动按"数量×单价+邮费"计算,你无需提供该字段。
- 如果无法确定 purchase_item物品名称必须 action="ask" 并追问请提供物品名称,绝不允许将 purchase_item 设为空字符串、null 或 undefined。`; - 如果无法确定 purchase_item物品名称必须 action="ask" 并追问"请提供物品名称",绝不允许将 purchase_item 设为空字符串、null 或 undefined。`;
const messages = [ const messages = [
{ role: 'system', content: systemPrompt }, { role: 'system', content: systemPrompt },
@@ -409,7 +413,7 @@ function handleAIResult(aiResult, roomId, username, originalText, attachments) {
let usedRecentImage = false; let usedRecentImage = false;
if (aiResult.use_recent_image) { if (aiResult.use_recent_image) {
console.log('🔍 use_recent_image: 查找最近图片消息, roomId=', roomId); console.log('🔍 use_recent_image: 查找最近图片消息, roomId=', roomId);
const recentMsg = db.prepare("SELECT attachments FROM messages WHERE room_id = ? AND attachments IS NOT NULL AND attachments != '' AND attachments != '[]' ORDER BY timestamp DESC LIMIT 1").get(roomId); const recentMsg = db.prepare("SELECT attachments FROM messages WHERE room_id = ? AND attachments IS NOT NULL AND attachments != '' AND attachments != '[]' ORDER BY id DESC LIMIT 1").get(roomId);
console.log('🔍 最近消息:', recentMsg ? recentMsg.attachments : '(无)'); console.log('🔍 最近消息:', recentMsg ? recentMsg.attachments : '(无)');
if (recentMsg) { if (recentMsg) {
try { try {
@@ -419,8 +423,13 @@ function handleAIResult(aiResult, roomId, username, originalText, attachments) {
} }
} }
const createdTime = aiResult.created_time || now; const createdTime = aiResult.created_time || now;
let purchase = db.prepare('SELECT * FROM purchases WHERE room_id = ? AND item LIKE ? AND status != ?').get(roomId, `%${aiResult.purchase_item}%`, '已完成'); // 新建 vs 更新AI 标记 is_new 时强制新建,不尝试匹配已有记录
console.log('📦 purchase_item:', aiResult.purchase_item, purchase ? '(已有)' : '(新建)'); const isNew = aiResult.is_new === true;
let purchase;
if (!isNew) {
purchase = db.prepare('SELECT * FROM purchases WHERE room_id = ? AND item LIKE ? AND status != ?').get(roomId, `%${aiResult.purchase_item}%`, '已完成');
}
console.log('📦 purchase_item:', aiResult.purchase_item, isNew ? '(强制新建)' : purchase ? '(匹配已有)' : '(未匹配-新建)');
let replyText = ''; let replyText = '';
const quantity = aiResult.quantity || 1; const quantity = aiResult.quantity || 1;
const unitPrice = aiResult.unit_price || 0; const unitPrice = aiResult.unit_price || 0;