From cf63ed5e3fe41661fa59ea71dbb9a5ca5fa791cc Mon Sep 17 00:00:00 2001 From: kicer Date: Wed, 22 Jul 2026 15:38:37 +0800 Subject: [PATCH] backup codes --- server/server.js | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/server/server.js b/server/server.js index edc45b7..84cfe8d 100644 --- a/server/server.js +++ b/server/server.js @@ -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},%`); } 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 { ...room, 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) => { - 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); }); @@ -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 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, { type: 'new_message', message: msg, 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) => { const pur = db.prepare('SELECT * FROM purchases WHERE id = ?').get(req.params.id); 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); res.json({ ...pur, history, attachments }); }); @@ -273,7 +273,7 @@ function storeAndBroadcastText(roomId, user, text) { const now = timestamp(); 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 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 : '' } }); 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字段。 -- 总金额(amount)由系统自动按“数量×单价+邮费”计算,你无需提供该字段。 -- 如果无法确定 purchase_item(物品名称),必须 action="ask" 并追问“请提供物品名称”,绝不允许将 purchase_item 设为空字符串、null 或 undefined。`; +- 总金额(amount)由系统自动按"数量×单价+邮费"计算,你无需提供该字段。 +- 如果无法确定 purchase_item(物品名称),必须 action="ask" 并追问"请提供物品名称",绝不允许将 purchase_item 设为空字符串、null 或 undefined。`; const messages = [ { role: 'system', content: systemPrompt }, @@ -409,7 +413,7 @@ function handleAIResult(aiResult, roomId, username, originalText, attachments) { let usedRecentImage = false; if (aiResult.use_recent_image) { 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 : '(无)'); if (recentMsg) { try { @@ -419,8 +423,13 @@ function handleAIResult(aiResult, roomId, username, originalText, attachments) { } } 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}%`, '已完成'); - console.log('📦 purchase_item:', aiResult.purchase_item, purchase ? '(已有)' : '(新建)'); + // 新建 vs 更新:AI 标记 is_new 时强制新建,不尝试匹配已有记录 + 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 = ''; const quantity = aiResult.quantity || 1; const unitPrice = aiResult.unit_price || 0;