seaislee1209 530f02a66a
Some checks failed
Build and Deploy Web / build-and-deploy (push) Has been cancelled
Build and Deploy Backend / build-and-deploy (push) Has been cancelled
feat: 飞书报告卡片化 + 报告权限系统 + 产出过滤优化
- 日报/周报/月报改为结构化卡片推送(column_set布局)
- 新增 report:daily/weekly/monthly 权限到角色管理
- 产出统计只算中期制作阶段动画秒数
- 效率之星改为跨项目加权通过率
- AI点评补充风险数据源
- 禁用多余admin账号,股东角色加报告权限

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-02 20:43:35 +08:00

98 lines
3.3 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""豆包大模型服务 —— 通过火山引擎 ARK 平台调用"""
import logging
from config import ARK_API_KEY, ARK_MODEL, ARK_BASE_URL
logger = logging.getLogger(__name__)
# 延迟初始化,避免无 Key 时报错
_client = None
def _get_client():
global _client
if _client is None and ARK_API_KEY:
from openai import OpenAI
_client = OpenAI(api_key=ARK_API_KEY, base_url=ARK_BASE_URL)
return _client
def generate_report_summary(data_context: str, report_type: str) -> str:
"""
调用豆包生成报告摘要
:param data_context: 数据库汇总数据(纯文本)
:param report_type: daily / weekly / monthly
:return: AI 生成的 markdown 摘要,失败时返回空字符串
"""
client = _get_client()
if not client:
logger.warning("豆包 AI 未配置 API Key跳过摘要生成")
return ""
type_labels = {"daily": "日报", "weekly": "周报", "monthly": "月报"}
label = type_labels.get(report_type, "报告")
system_prompt = (
"你是 AirLabs 动画团队的项目管理助手。"
"请根据提供的数据,用简洁的中文生成一段{label}点评。\n"
"重要规则:\n"
"1. 不要重复罗列原始数据(项目数、提交人次、未提交人员等已在报告上方展示)\n"
"2. 直接给出分析洞察和可执行建议\n"
"3. 如果有风险项目,重点提醒并给出具体改进方向\n"
"4. 语言简练专业,适合管理层阅读\n"
"5. 不要使用标题(如 ## 核心数据概览),直接写正文\n"
"6. 总字数控制在 200 字以内"
).format(label=label)
try:
response = client.chat.completions.create(
model=ARK_MODEL,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"以下是{label}数据,请生成总结:\n\n{data_context}"},
],
temperature=0.7,
max_tokens=1024,
timeout=30,
)
return response.choices[0].message.content.strip()
except Exception as e:
logger.error(f"豆包 AI 调用失败: {e}")
return ""
def generate_risk_analysis(project_data: str) -> str:
"""
调用豆包分析项目风险
:param project_data: 项目数据文本
:return: AI 生成的风险分析,失败时返回空字符串
"""
client = _get_client()
if not client:
return ""
system_prompt = (
"你是 AirLabs 动画团队的项目风险分析专家。"
"请根据项目数据,分析风险原因并给出改进建议。"
"要求:\n"
"1. 分析要具体,基于数据说话\n"
"2. 建议要可执行\n"
"3. 使用中文,简练专业\n"
"4. 总字数控制在 150 字以内"
)
try:
response = client.chat.completions.create(
model=ARK_MODEL,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": f"项目数据:\n\n{project_data}"},
],
temperature=0.7,
max_tokens=512,
timeout=30,
)
return response.choices[0].message.content.strip()
except Exception as e:
logger.error(f"豆包 AI 风险分析失败: {e}")
return ""