feat: 路线图R1决策建议一键落地+R2机会推送+R5预算闭环
R1(P0): AI建议一键应用到KPI/预算/行动方案
- 新表 ai_suggestions + AISuggestion 模型(init_db自动建)
- /api/cma/ai/suggestions CRUD + /{id}/apply(复用kpis/budget/action_plans) + dismiss
- 应用写 OperationLog(action=ai_suggestion_apply, detail含suggestion_id/before/after)
- 规则驱动建议生成 generate_rule_suggestions(低执行率/高执行率/预算超支/pending预警)
- 幂等: 同entity+type+target_id+title+unapplied不重复建; applied后拒绝重复应用
- 前端: Dashboard AI面板建议卡(应用到/忽略) + 建议中心页 /ai-suggestions
R2(P1): 数据找人扩大-机会类推送
- scripts/opportunity_detector.py: KPI向好(执行率>110%)/预算余量(<70%且actual>0)/预测上行
- scripts/daily_push.py: 异常+机会 每日9:15推企微(8800/send, --dry-run调试)
- crontab: 15 9 * * * (alert_generator 9:00之后)
R5(P0): 预算闭环加固
- auto-decompose批量幂等: 只取年度行(period=YYYY-00)+同KPI多版本取一行
- scripts/closed_loop_check.py: 预算执行率异常→检查现金流/行动同步→缺失提示+报告
- scripts/verify_decompose_idempotent.py: 幂等验证脚本
测试: test_ai_suggestions(10例)+test_roadmap_r2r5(14例); 修test_budget幂等契约适配年度行
全量: 673 passed
This commit is contained in:
@@ -911,3 +911,25 @@ class CashPlanUnclassified(Base):
|
||||
status = Column(String(20), default="pending", comment="pending/classified/ignored")
|
||||
created_at = Column(DateTime, server_default=func.now())
|
||||
resolved_at = Column(DateTime, nullable=True)
|
||||
|
||||
|
||||
class AISuggestion(Base):
|
||||
"""AI决策建议 — 一键应用到KPI/预算/行动方案 (路线图R1 2026-08-30)"""
|
||||
__tablename__ = "ai_suggestions"
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
entity_id = Column(Integer, default=1, comment="企业ID")
|
||||
user_id = Column(Integer, nullable=True, comment="建议创建人ID")
|
||||
source = Column(String(30), default="dashboard", comment="来源: dashboard/kpi/budget/manual/rule")
|
||||
suggestion_type = Column(String(30), nullable=False, comment="kpi_target/budget_adjust/action_plan")
|
||||
target_type = Column(String(30), nullable=False, comment="kpi/budget/action_plan")
|
||||
target_id = Column(Integer, nullable=True, comment="目标ID (KPI ID/预算KPI ID等)")
|
||||
title = Column(String(300), nullable=False, comment="建议标题")
|
||||
content = Column(Text, nullable=True, comment="建议内容/理由")
|
||||
suggestion_data = Column(JSON, nullable=True, comment="应用参数: {target_value, period, budget_value, plan_title, ...}")
|
||||
status = Column(String(20), default="unapplied", comment="unapplied/applied/dismissed")
|
||||
applied_by = Column(String(100), nullable=True, comment="应用人姓名")
|
||||
applied_user_id = Column(Integer, nullable=True, comment="应用人ID")
|
||||
applied_at = Column(DateTime, nullable=True, comment="应用时间")
|
||||
apply_detail = Column(JSON, nullable=True, comment="应用结果明细: [{target_type,target_id,action,before,after}]")
|
||||
created_at = Column(DateTime, server_default=func.now())
|
||||
updated_at = Column(DateTime, server_default=func.now(), onupdate=func.now())
|
||||
|
||||
Reference in New Issue
Block a user