From 8a953eb7699bc0ae9b6aa9f666bc75675fcceae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BC=A0=E6=88=90?= Date: Sat, 28 Feb 2026 17:58:03 +0800 Subject: [PATCH] 1 --- api/middleware/job/managers/chatManager.js | 34 +++++++++++++++++----- api/model/chat_reply_intent_log.js | 8 ++++- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/api/middleware/job/managers/chatManager.js b/api/middleware/job/managers/chatManager.js index 46367e7..588edd4 100644 --- a/api/middleware/job/managers/chatManager.js +++ b/api/middleware/job/managers/chatManager.js @@ -218,8 +218,8 @@ class ChatManager { } - /** AI 回复后写入 chat_reply_intent_log,options 含 sn_code/platform/friendId/encryptFriendId 时落库 */ - _saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, replied, reason) { + /** AI 回复后写入 chat_reply_intent_log,options 含 sn_code/platform/friendId/encryptFriendId,securityId 为 HR 消息唯一 id */ + _saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, replied, reason, securityId) { if (!options || options.sn_code == null) return; try { const model = db.getModel('chat_reply_intent_log'); @@ -228,6 +228,7 @@ class ChatManager { platform: options.platform || 'boss', friendId: options.friendId ?? null, encrypt_friend_id: options.encryptFriendId || '', + security_id: securityId || null, hr_message_text: hr_message_text || null, action: action || '', reply_content: reply_content || null, @@ -276,13 +277,13 @@ class ChatManager { const hrList = this._filterHrReplyableMessages(messages, geek_uid); if (hrList.length === 0) { - this._saveReplyIntentLog(options, '', jobInfo, '', '', false, '无HR可回复消息(已过滤系统与己方)'); + this._saveReplyIntentLog(options, '', jobInfo, '', '', false, '无HR可回复消息(已过滤系统与己方)', null); return { replied: false, reason: '无HR可回复消息(已过滤系统与己方)' }; } const last = hrList[hrList.length - 1]; if (!last.from || last.from.uid !== hr_uid) { - this._saveReplyIntentLog(options, '', jobInfo, '', '', false, '最后一条可回复消息不是HR'); + this._saveReplyIntentLog(options, '', jobInfo, '', '', false, '最后一条可回复消息不是HR', null); return { replied: false, reason: '最后一条可回复消息不是HR' }; } @@ -291,7 +292,25 @@ class ChatManager { (typeof body.text === 'string' && body.text) || (typeof last.pushText === 'string' && last.pushText) || ''; + const security_id = last.securityId || last.security_id || ''; + if (security_id && options) { + try { + const logModel = db.getModel('chat_reply_intent_log'); + const existing = await logModel.findOne({ where: { security_id } }); + if (existing) { + return { + replied: !!existing.replied, + action: existing.action || 'text', + reply_content: existing.reply_content || '', + hr_message_text: existing.hr_message_text || hr_message_text, + reason: existing.reason || null + }; + } + } catch (e) { + console.warn('[聊天管理] 查询 chat_reply_intent_log 失败:', e.message); + } + } const { action, reply_content } = await ai_service.replyIntentAndContent({ jobInfo, @@ -299,19 +318,18 @@ class ChatManager { previousMessages: hrList.slice(-5).map(m => (m.body && m.body.text) || m.pushText || '') }); - if (action === 'no_reply') { - this._saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, false, 'HR表示暂不匹配/无需回复'); + this._saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, false, 'HR表示暂不匹配/无需回复', security_id || null); return { replied: false, reason: 'HR表示暂不匹配/无需回复' }; } const needContent = action === 'text'; if (needContent && (!reply_content || !reply_content.trim())) { - this._saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, false, 'AI 未生成有效回复文案'); + this._saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, false, 'AI 未生成有效回复文案', security_id || null); return { replied: false, reason: 'AI 未生成有效回复文案' }; } - this._saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, true, null); + this._saveReplyIntentLog(options, hr_message_text, jobInfo, action, reply_content, true, null, security_id || null); return { replied: true, action: action || 'text', diff --git a/api/model/chat_reply_intent_log.js b/api/model/chat_reply_intent_log.js index 2ccd470..9fe932f 100644 --- a/api/model/chat_reply_intent_log.js +++ b/api/model/chat_reply_intent_log.js @@ -29,6 +29,11 @@ module.exports = (db) => { allowNull: true, defaultValue: '' }, + security_id: { + comment: 'HR 消息唯一 id,用于去重,同一消息只调用一次 AI', + type: Sequelize.STRING(500), + allowNull: true + }, hr_message_text: { comment: 'HR 最新消息原文(AI 入参)', type: Sequelize.TEXT, @@ -70,12 +75,13 @@ module.exports = (db) => { }, { timestamps: false, indexes: [ + { unique: true, fields: ['security_id'], name: 'uk_security_id' }, { unique: false, fields: ['sn_code', 'platform', 'friendId'] }, { unique: false, fields: ['create_time'] } ] }); - // chat_reply_intent_log.sync({ force: true }); +// chat_reply_intent_log.sync({ force: true }); return chat_reply_intent_log; };