diff --git a/yuthon_ai_agent/__manifest__.py b/yuthon_ai_agent/__manifest__.py index f5cfef0e4..2ef678c76 100644 --- a/yuthon_ai_agent/__manifest__.py +++ b/yuthon_ai_agent/__manifest__.py @@ -38,6 +38,7 @@ 'yuthon_ai_agent/static/src/js/ai_chat_action.js', 'yuthon_ai_agent/static/src/js/ai_floating.js', 'yuthon_ai_agent/static/src/js/ai_chat_open.js', + 'yuthon_ai_agent/static/src/js/ai_rule_test.js', 'yuthon_ai_agent/static/src/xml/ai_chat_template.xml', 'yuthon_ai_agent/static/src/css/ai_chat.css', 'yuthon_ai_agent/static/src/css/ai_floating.css', diff --git a/yuthon_ai_agent/controllers/main.py b/yuthon_ai_agent/controllers/main.py index a6968a9d5..e8ba2ec18 100644 --- a/yuthon_ai_agent/controllers/main.py +++ b/yuthon_ai_agent/controllers/main.py @@ -375,3 +375,19 @@ class AiChatController(http.Controller): 'file_type': file_type_code, '_ocr_diag': ocr_diag, }) + + @http.route('/ai/rule/test_guide', type='json', auth='user', methods=['POST']) + def test_active_guide(self, rule_id): + """测试主动感知规则:创建引导消息,返回 conversation_id 供前端打开聊天""" + err = self._check_ai_access() + if err: + return err + rule = request.env['ai.rule'].browse(rule_id) + if not rule.exists(): + return {'error': '规则不存在'} + try: + conv_id = rule._do_test_guide() + return {'success': True, 'conversation_id': conv_id} + except Exception as e: + _logger.exception('Test guide failed') + return {'error': str(e)} diff --git a/yuthon_ai_agent/models/ai_rule.py b/yuthon_ai_agent/models/ai_rule.py index a9ed8ad1c..2502f370a 100644 --- a/yuthon_ai_agent/models/ai_rule.py +++ b/yuthon_ai_agent/models/ai_rule.py @@ -4,7 +4,8 @@ import logging import requests -from odoo import models, fields, api +from odoo import models, fields, api, _ +from odoo.exceptions import UserError _logger = logging.getLogger(__name__) @@ -231,11 +232,11 @@ class AiRule(models.Model): string='方法说明', ) - def action_test_guide(self): - """测试主动感知:模拟触发,创建引导消息并打开AI对话""" + def _do_test_guide(self): + """测试主动感知:模拟触发,创建引导消息(内部方法,由控制器调用)""" self.ensure_one() if self.rule_type != 'active_guide': - return {'warning': {'title': '提示', 'message': '仅主动感知类型的规则可以测试'}} + raise UserError('仅主动感知类型的规则可以测试') # 获取或创建用户对话 conv = self.env['ai.conversation'].search([ @@ -245,14 +246,14 @@ class AiRule(models.Model): if not conv: provider = self.env['ai.provider'].search([('active', '=', True)], limit=1) if not provider: - return {'warning': {'title': '错误', 'message': '请先配置 AI 服务商'}} + raise UserError('请先配置 AI 服务商') conv = self.env['ai.conversation'].create({ 'name': 'AI 对话', 'provider_id': provider.id, }) # 组装测试消息(替换变量为测试值) - message = self.guide_message or f'【测试】主动感知已触发' + message = self.guide_message or '【测试】主动感知已触发' message = message.replace('{record_name}', '[测试记录]') message = message.replace('{user_name}', self.env.user.name) message = message.replace('{record_id}', '[测试]') @@ -279,10 +280,5 @@ class AiRule(models.Model): }, ensure_ascii=False), }) - # 返回 client action 打开浮动聊天框 - return { - 'type': 'ir.actions.client', - 'tag': 'yuthon_ai_chat_open', - 'params': {'conversation_id': conv.id}, - } + return conv.id diff --git a/yuthon_ai_agent/static/src/js/ai_floating.js b/yuthon_ai_agent/static/src/js/ai_floating.js index 0fdf8376d..d8d706c06 100644 --- a/yuthon_ai_agent/static/src/js/ai_floating.js +++ b/yuthon_ai_agent/static/src/js/ai_floating.js @@ -643,10 +643,8 @@ window.addEventListener("yuthon:ai_open_chat", async () => { if (!isVisible) { toggleChat(); } - // 刷新消息列表以显示新创建的测试消息 - const msgs = await loadHistory(); - if (chatEl) { - renderMessages(msgs); - scrollToBottom(); - } + // 延迟刷新消息,等待 DOM 渲染完成 + setTimeout(async () => { + renderChat(); + }, 300); }); diff --git a/yuthon_ai_agent/views/ai_rule_views.xml b/yuthon_ai_agent/views/ai_rule_views.xml index d7dda08a7..3e681094c 100644 --- a/yuthon_ai_agent/views/ai_rule_views.xml +++ b/yuthon_ai_agent/views/ai_rule_views.xml @@ -70,11 +70,10 @@
-
@@ -87,9 +86,6 @@ placeholder="后台方法名,如 notice_send_to_all" /> -

- 后台自动传入当前记录ID,无需手动配置参数 -