fix: 防止 is_new + 附件导致误建空白采购记录

- AI prompt 新增「绝对禁止规则」:纯图片+物品名请求禁止返回 is_new
- AI prompt「新建 vs 更新」补充:附件请求不是新建
- 后端兜底:is_new 但附件非空时,查已有同名记录,存在则强制转为更新模式
- 避免创建 quantity=1 amount=0 的无意义记录
This commit is contained in:
2026-07-22 16:00:20 +08:00
parent 3ea58fcf3d
commit 742bb908a5

View File

@@ -361,9 +361,15 @@ async function analyzeWithDeepSeek(text, historyMessages, username, isAdmin) {
- 如果用户要求"把刚才/之前的图片作为附件存到XX采购",你可以返回 {"action":"purchase","purchase_item":"XX","use_recent_image":true} - 如果用户要求"把刚才/之前的图片作为附件存到XX采购",你可以返回 {"action":"purchase","purchase_item":"XX","use_recent_image":true}
不提供任何数量、价格字段,系统会自动查找最近一张图片并关联。 不提供任何数量、价格字段,系统会自动查找最近一张图片并关联。
⚠️ 绝对禁止规则:
- 如果用户发送图片并明确说"这是XX的图片"或"作为附件存到XX",你**只能返回** purchase_item
**绝对不允许返回** is_new、quantity、unit_price、amount 等任何其他字段。
- 纯图片+指定物品名的请求不是新建采购,系统会自动关联附件到已有记录。
⚠️ 采购规则: ⚠️ 采购规则:
- 新建 vs 更新(极其重要): - 新建 vs 更新(极其重要):
* 如果用户提到"昨天/今天/刚刚/又/再/新/另一批/另外"等时间或重复购买词汇,必须返回 "is_new": true系统会强制创建新记录。 * 如果用户提到"昨天/今天/刚刚/又/再/新/另一批/另外"等时间或重复购买词汇,必须返回 "is_new": true系统会强制创建新记录。
* "纯图片+物品名"的附件请求**不是**新建,不要返回 is_new。
* 如果用户明确说"改一下/更新/修改/调整/更正"等词汇,才不提供 is_new 或设为 false系统会尝试匹配已有记录更新。 * 如果用户明确说"改一下/更新/修改/调整/更正"等词汇,才不提供 is_new 或设为 false系统会尝试匹配已有记录更新。
* 当无法确定是新建还是更新时,默认视为新建(返回 is_new: true * 当无法确定是新建还是更新时,默认视为新建(返回 is_new: true
- 用户补充信息时更新已有记录。更新时请返回完整字段值包括未变化的字段。如果用户要求修改时间请生成正确的created_time字段。 - 用户补充信息时更新已有记录。更新时请返回完整字段值包括未变化的字段。如果用户要求修改时间请生成正确的created_time字段。
@@ -448,9 +454,18 @@ function handleAIResult(aiResult, roomId, username, originalText, attachments) {
} }
const createdTime = normalizeTime(aiResult.created_time); const createdTime = normalizeTime(aiResult.created_time);
// 新建 vs 更新AI 标记 is_new 时强制新建,不尝试匹配已有记录 // 新建 vs 更新AI 标记 is_new 时强制新建,不尝试匹配已有记录
const isNew = aiResult.is_new === true; let isNew = aiResult.is_new === true;
let purchase; let purchase;
if (!isNew) { // 兜底纠正:如果 AI 误将"纯附件请求"标记为 is_new强制转为匹配已有记录
if (isNew && attachments?.length > 0) {
const existing = db.prepare('SELECT * FROM purchases WHERE room_id = ? AND item LIKE ? ORDER BY created_at DESC LIMIT 1').get(roomId, `%${aiResult.purchase_item}%`);
if (existing) {
console.log('🛡️ 兜底纠正: is_new 但附件非空且已有同名记录,转为更新模式');
isNew = false;
purchase = existing;
}
}
if (!isNew && !purchase) {
purchase = db.prepare('SELECT * FROM purchases WHERE room_id = ? AND item LIKE ? AND status != ?').get(roomId, `%${aiResult.purchase_item}%`, '已完成'); 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 ? '(匹配已有)' : '(未匹配-新建)'); console.log('📦 purchase_item:', aiResult.purchase_item, isNew ? '(强制新建)' : purchase ? '(匹配已有)' : '(未匹配-新建)');