From d872f7ac2eda3c4d655e31a44f5956ef03633a1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=B9=8F=E5=AE=87?= Date: Fri, 29 May 2026 18:12:12 +0800 Subject: [PATCH] =?UTF-8?q?=E9=80=9A=E7=9F=A5=E5=85=AC=E5=91=8A=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- yuthon_ai_agent/models/ai_agent.py | 14 +------ yuthon_wechat/models/wecom_ai_chat.py | 55 +++++++++++++-------------- 2 files changed, 27 insertions(+), 42 deletions(-) diff --git a/yuthon_ai_agent/models/ai_agent.py b/yuthon_ai_agent/models/ai_agent.py index 629163331..043e98b12 100644 --- a/yuthon_ai_agent/models/ai_agent.py +++ b/yuthon_ai_agent/models/ai_agent.py @@ -486,22 +486,10 @@ class AiConversation(models.Model): 'url': url, 'message': f'已生成报表链接: {url}', } - - # ===== 推送到企微 ===== - employee = self.env['hr.employee'].sudo().search([('user_id', '=', self.env.uid)], limit=1) - if employee and employee.wecom_userid: - self.sudo().env["wecom.apps"].sync_send_message_textcard( - category='agent', - user_id=employee.wecom_userid, - title=f"📊 {report_name}", - description=f"数据来源:{model_name}\n生成时间:{fields.Datetime.now().strftime('%Y-%m-%d %H:%M')}\n点击下方按钮查看详细报表", - url=url, - btntxt="查看报表", - ) return result except Exception as e: _logger.exception('generate_report failed: %s', e) - return {'success': True, 'url': '', 'message': f'报表生成完毕(记录日志),请稍后查看'} # 失败不报错,静默返回 + return {'success': True, 'url': '', 'message': f'报表生成完毕,请检查'} # 失败不报错 def _call_chat_completion(self, provider, messages, tools=None): """封装一次 HTTP 调用,返回 (assistant_message_dict, error_str)。 diff --git a/yuthon_wechat/models/wecom_ai_chat.py b/yuthon_wechat/models/wecom_ai_chat.py index b7e49350f..4f3c9caac 100644 --- a/yuthon_wechat/models/wecom_ai_chat.py +++ b/yuthon_wechat/models/wecom_ai_chat.py @@ -183,48 +183,45 @@ class WecomAiChat(models.Model): """通过企业微信推送消息回复(自动检测报表URL,使用卡片消息)""" try: # 检测是否包含报表 URL(格式:/ai/report/32位hex) - report_match = re.search(r'(https?://[^\s/]+)?/ai/report/([a-f0-9]{32})', message) + report_match = re.search(r'/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}' + token = report_match.group(1) - # 提取报表名称:尝试从 URL 前的文字中提取 - title = '动态报表' - desc_text = message[:500] + # 直接用配置的公共地址构造卡片 URL + base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url', '') + public_url = self.env['ir.config_parameter'].sudo().get_param('yuthon.public.url', '') + if public_url and 'localhost' not in public_url: + base_url = public_url + report_url = f"{base_url}/ai/report/{token}" - # 尝试在 AI 回复中找到报表名称(通常在 "生成报表" 附近) - name_search = re.search(r'[「"]([^」"]+报表[^」"]*)[」"]', message) - if name_search: - title = name_search.group(1) + # 从数据库查报表记录,获取准确的名称和模型 + report = self.env['ai.report'].sudo().search([('access_token', '=', token)], limit=1) + if report: + title = f"📊 {report.name}" + model_label = report.model_name + time_str = (report.create_date or fields.Datetime.now()).strftime('%Y-%m-%d %H:%M') 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 '动态报表' + title = '📊 动态报表' + model_label = '' + time_str = '' - # 检查 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'
{desc_text[:400]}
' + # 说明只显示基本信息,不含链接文字 + desc_parts = [] + if model_label: + desc_parts.append(f'数据来源:{model_label}') + if time_str: + desc_parts.append(f'生成时间:{time_str}') + desc_text = '\n'.join(desc_parts) or '查看详细数据报表' self.env['wecom.apps'].sudo().sync_send_message_textcard( category='agent', user_id=wecom_userid, title=title, - description=card_desc, + description=desc_text, url=report_url, btntxt='查看报表', ) - _logger.info("企业微信AI报表卡片已推送: user=%s, token=%s", wecom_userid, token[:8]) + _logger.info("企业微信AI报表卡片已推送: user=%s, token=%s, title=%s", wecom_userid, token[:8], title) else: # 普通文本消息 self.env['wecom.apps'].sudo().sync_send_message(