ai动态报表

This commit is contained in:
李鹏宇
2026-05-29 13:01:48 +08:00
parent b795f3a4a1
commit 6565c7859b
3 changed files with 80 additions and 10 deletions
+62 -7
View File
@@ -5,6 +5,7 @@
"""
import logging
import re
from odoo import models, fields, api
@@ -179,16 +180,70 @@ class WecomAiChat(models.Model):
return chat_record
def _send_wecom_reply(self, wecom_userid, message):
"""通过企业微信主动推送消息回复"""
"""通过企业微信推送消息回复(自动检测报表URL,使用卡片消息)"""
try:
self.env['wecom.apps'].sudo().sync_send_message(
category='agent',
user_id=wecom_userid,
message=message,
)
_logger.info("企业微信AI回复已推送: user=%s, len=%d", wecom_userid, len(message))
# 检测是否包含报表 URL(格式:/ai/report/32位hex)
report_match = re.search(r'(https?://[^\s/]+)?/ai/report/([a-f0-9]{32})', message)
if report_match:
# 提取完整 URL
base = report_match.group(1) or ''
token = report_match.group(2)
report_url = f'{base}/ai/report/{token}'
# 提取报表名称:尝试从 URL 前的文字中提取
title = '动态报表'
desc_text = message[:500]
# 尝试在 AI 回复中找到报表名称(通常在 "生成报表" 附近)
name_search = re.search(r'[「"]([^」"]+报表[^」"]*)[」"]', message)
if name_search:
title = name_search.group(1)
else:
# 尝试用 URL 前的文案做标题
before_url = message[:report_match.start()].strip()
if before_url:
# 取最后一句作为标题
sentences = re.split(r'[。!\n]', before_url)
title = sentences[-1].strip()[:50] if sentences else '动态报表'
# 检查 URL 是否带 base(如果不带,说明 web.base.url 可能为 localhost)
if not base:
# 尝试从 ir.config_parameter 获取公共URL
public_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url', '')
if public_url and 'localhost' not in public_url:
report_url = f'{public_url}/ai/report/{token}'
# 构建卡片描述(支持 HTML 格式)
card_desc = f'<div class="normal">{desc_text[:400]}</div>'
self.env['wecom.apps'].sudo().sync_send_message_textcard(
category='agent',
user_id=wecom_userid,
title=title,
description=card_desc,
url=report_url,
btntxt='查看报表',
)
_logger.info("企业微信AI报表卡片已推送: user=%s, token=%s", wecom_userid, token[:8])
else:
# 普通文本消息
self.env['wecom.apps'].sudo().sync_send_message(
category='agent',
user_id=wecom_userid,
message=message,
)
_logger.info("企业微信AI回复已推送: user=%s, len=%d", wecom_userid, len(message))
except Exception as e:
_logger.exception("企业微信AI回复推送失败 [user=%s]: %s", wecom_userid, e)
# fallback: 发送普通文本
try:
self.env['wecom.apps'].sudo().sync_send_message(
category='agent',
user_id=wecom_userid,
message=message,
)
except:
pass
def _log_message(self, chat_record, wecom_userid, user_content, ai_reply):
"""记录企业微信AI消息日志"""