通知公告优化

This commit is contained in:
李鹏宇
2026-05-29 18:12:12 +08:00
parent c48b1333f8
commit d872f7ac2e
2 changed files with 27 additions and 42 deletions
+1 -13
View File
@@ -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)。
+26 -29
View File
@@ -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'<div class="normal">{desc_text[:400]}</div>'
# 说明只显示基本信息,不含链接文字
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(