From d373fb5f0cbcc9d1e504ca064345ebba65b8ee79 Mon Sep 17 00:00:00 2001 From: selfrelease Date: Fri, 14 Aug 2026 19:34:04 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E6=99=BA=E8=84=91?= =?UTF-8?q?=E5=86=B3=E7=AD=96=E4=B8=AD=E5=BF=83=E6=A8=A1=E5=9D=97=EF=BC=88?= =?UTF-8?q?=E5=86=B3=E7=AD=96=E4=B8=AD=E5=BF=83/AI=E5=91=98=E5=B7=A5?= =?UTF-8?q?=E7=BB=84=E7=BB=87/=E7=9F=A5=E8=AF=86=E8=B5=84=E4=BA=A7?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 DecisionsPage、AgentsPage、KnowledgePage 三个页面 - 新增 DecisionCard、DecisionDrawer、DecisionSummary、KnowledgeCard、LoopHealthBar、AgentCard 组件 - 新增 decision-aggregator 决策聚合逻辑和 agents 数据 - Layout 导航重构:新增智脑决策分组,调整系统配置和经营本体分组 - BossPage 集成决策摘要和闭环健康度,利润机会池支持警告样式 - TasksPage 增强任务展示 - 抽屉式详情统一改为居中弹窗风格 - data.ts 后端调整 - run.md 更新数据库连接说明 - 新增玄谋智脑实际版建设方案文档 Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- client/src/App.tsx | 6 + client/src/components/AgentCard.tsx | 74 ++ client/src/components/DecisionCard.tsx | 88 +++ client/src/components/DecisionDrawer.tsx | 161 +++++ client/src/components/DecisionSummary.tsx | 87 +++ client/src/components/KnowledgeCard.tsx | 50 ++ client/src/components/Layout.tsx | 43 +- client/src/components/LoopHealthBar.tsx | 74 ++ client/src/data/agents.ts | 143 ++++ client/src/lib/decision-aggregator.ts | 203 ++++++ client/src/pages/AgentsPage.tsx | 111 +++ client/src/pages/BossPage.tsx | 33 + client/src/pages/DecisionsPage.tsx | 178 +++++ client/src/pages/KnowledgePage.tsx | 268 ++++++++ client/src/pages/TasksPage.tsx | 30 + .../18-玄谋智脑实际版建设方案.md | 648 ++++++++++++++++++ docs/智脑实施方法论/README.md | 1 + run.md | 34 + server/src/routes/data.ts | 21 +- 19 files changed, 2231 insertions(+), 22 deletions(-) create mode 100644 client/src/components/AgentCard.tsx create mode 100644 client/src/components/DecisionCard.tsx create mode 100644 client/src/components/DecisionDrawer.tsx create mode 100644 client/src/components/DecisionSummary.tsx create mode 100644 client/src/components/KnowledgeCard.tsx create mode 100644 client/src/components/LoopHealthBar.tsx create mode 100644 client/src/data/agents.ts create mode 100644 client/src/lib/decision-aggregator.ts create mode 100644 client/src/pages/AgentsPage.tsx create mode 100644 client/src/pages/DecisionsPage.tsx create mode 100644 client/src/pages/KnowledgePage.tsx create mode 100644 docs/智脑实施方法论/18-玄谋智脑实际版建设方案.md diff --git a/client/src/App.tsx b/client/src/App.tsx index cbb3dfd..3bc9d0b 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -24,6 +24,9 @@ import { SiteSelectionPage } from '@/pages/SiteSelectionPage' import { SmartSchedulingPage } from '@/pages/SmartSchedulingPage' import { SituationalAwarenessPage } from '@/pages/SituationalAwarenessPage' import { BossPage } from '@/pages/BossPage' +import { DecisionsPage } from '@/pages/DecisionsPage' +import { AgentsPage } from '@/pages/AgentsPage' +import { KnowledgePage } from '@/pages/KnowledgePage' import { RevenuePage } from '@/pages/RevenuePage' import { BankPage } from '@/pages/BankPage' import { CentralKitchenPage } from '@/pages/CentralKitchenPage' @@ -92,6 +95,9 @@ export default function App() { : user?.role === 'store' ? : user?.role === 'regional' ? : } /> } /> + } /> + } /> + } /> } /> } /> } /> diff --git a/client/src/components/AgentCard.tsx b/client/src/components/AgentCard.tsx new file mode 100644 index 0000000..45b07d7 --- /dev/null +++ b/client/src/components/AgentCard.tsx @@ -0,0 +1,74 @@ +/** + * AI 员工卡片组件 + * + * 展示单个 AI 员工的岗位、职责、自治等级和今日交付数。 + */ +import { Bot } from 'lucide-react' +import { cn } from '@/lib/utils' +import type { AgentConfig } from '@/data/agents' + +interface AgentCardProps { + agent: AgentConfig + /** 今日交付数(null 表示加载中) */ + deliveries: number | null + onClick?: () => void +} + +/** 自治等级颜色 */ +const AUTONOMY_COLORS: Record = { + L1: 'bg-red-50 text-red-600 border border-red-200', + L2: 'bg-amber-50 text-amber-600 border border-amber-200', + L3: 'bg-green-50 text-green-600 border border-green-200', +} + +/** 状态指示灯颜色 */ +const STATUS_DOT: Record = { + '运行中': 'bg-green-500', + '待审批': 'bg-amber-500', + '受控': 'bg-blue-500', +} + +export function AgentCard({ agent, deliveries, onClick }: AgentCardProps) { + return ( +
+ {/* 头部:图标 + 状态灯 */} +
+
+ +
+ +
+ + {/* 名称 + 领域 */} + {agent.domain} +

{agent.name}

+

{agent.roleTarget}

+ + {/* 底部:自治等级 + 交付数 */} +
+ + 自治 {agent.autonomyLevel} + + + {deliveries === null ? ( + 加载中… + ) : ( + <>{deliveries} 项交付 + )} + +
+
+ ) +} diff --git a/client/src/components/DecisionCard.tsx b/client/src/components/DecisionCard.tsx new file mode 100644 index 0000000..80766a5 --- /dev/null +++ b/client/src/components/DecisionCard.tsx @@ -0,0 +1,88 @@ +/** + * 决策卡组件 + * + * 在决策中心列表中展示单个决策卡,点击可展开详情抽屉。 + */ +import { ChevronRight } from 'lucide-react' +import { cn, formatCurrency } from '@/lib/utils' +import type { DecisionCard } from '@/lib/decision-aggregator' +import { SOURCE_LABELS, LEVEL_LABELS } from '@/lib/decision-aggregator' + +interface DecisionCardProps { + decision: DecisionCard + index: number + approved: boolean + onOpen: (d: DecisionCard) => void +} + +/** 来源类型颜色 */ +const SOURCE_COLORS: Record = { + profit_opportunity: 'bg-purple-100 text-purple-700', + risk_alert: 'bg-red-100 text-red-700', + task_anomaly: 'bg-amber-100 text-amber-700', +} + +/** 等级颜色 */ +const LEVEL_COLORS: Record = { + L1: 'bg-red-50 text-red-600 border border-red-200', + L2: 'bg-amber-50 text-amber-600 border border-amber-200', + L3: 'bg-green-50 text-green-600 border border-green-200', +} + +export function DecisionCardItem({ decision, index, approved, onOpen }: DecisionCardProps) { + const isApproved = approved || decision.status === '已批准' + + return ( + + ) +} diff --git a/client/src/components/DecisionDrawer.tsx b/client/src/components/DecisionDrawer.tsx new file mode 100644 index 0000000..a437b95 --- /dev/null +++ b/client/src/components/DecisionDrawer.tsx @@ -0,0 +1,161 @@ +/** + * 决策详情弹窗 + * + * 点击决策卡后居中弹出,展示证据链、影响评估和审批操作。 + * 弹窗风格与 BusinessReportDialog 保持统一。 + */ +import { X, BrainCircuit } from 'lucide-react' +import { cn, formatCurrency } from '@/lib/utils' +import type { DecisionCard } from '@/lib/decision-aggregator' +import { SOURCE_LABELS, LEVEL_LABELS } from '@/lib/decision-aggregator' + +interface DecisionDrawerProps { + decision: DecisionCard + approved: boolean + onClose: () => void + onApprove: () => void + onReject: () => void +} + +export function DecisionDrawer({ decision, approved, onClose, onApprove, onReject }: DecisionDrawerProps) { + return ( +
+
e.stopPropagation()} + > + {/* 标题栏 */} +
+
+ {decision.id} · {SOURCE_LABELS[decision.sourceType]} +

{decision.title}

+
+ +
+ + {/* 内容 */} +
+ {/* 置信度 */} +
+
+ +
+

AI 建议置信度

+

{decision.confidence}%

+
+
+
+
= 85 ? 'bg-green-500' : decision.confidence >= 70 ? 'bg-amber-500' : 'bg-red-500', + )} + style={{ width: `${decision.confidence}%` }} + /> +
+
+ + {/* 为什么现在行动 */} +
+

为什么现在行动

+

{decision.reason}

+
+ + {/* 影响评估 */} +
+
+

预计影响

+

+ {decision.impactAmount > 0 ? formatCurrency(decision.impactAmount) : decision.impactDescription} +

+
+
+

决策等级

+

{LEVEL_LABELS[decision.level]}

+
+
+ + {/* 证据链 */} +
+

证据链

+
    + {decision.evidence.map((e, i) => ( +
  • + + {e} +
  • + ))} +
+
+ + {/* 详细信息(如果有) */} + {decision.detail && ( +
+

详细分析

+
+ {decision.detail.split('\n').map((line, i) => ( +

+ {line || '\u00A0'} +

+ ))} +
+
+ )} + + {/* 责任与执行 */} +
+

责任与执行

+
+
+

责任人

+

{decision.owner}

+
+
+

执行 AI

+

{decision.agentName}

+
+
+

截止时间

+

{decision.deadline}

+
+
+
+
+ + {/* 底部操作 */} +
+ + +
+
+
+ ) +} diff --git a/client/src/components/DecisionSummary.tsx b/client/src/components/DecisionSummary.tsx new file mode 100644 index 0000000..604f2b8 --- /dev/null +++ b/client/src/components/DecisionSummary.tsx @@ -0,0 +1,87 @@ +/** + * 指挥舱待决策摘要组件 + * + * 在 BossPage 顶部展示 TOP3 待决策,点击跳转到决策中心。 + */ +import { useNavigate } from 'react-router-dom' +import { Sparkles, ChevronRight } from 'lucide-react' +import { cn, formatCurrency } from '@/lib/utils' +import type { DecisionCard } from '@/lib/decision-aggregator' +import { SOURCE_LABELS } from '@/lib/decision-aggregator' + +interface DecisionSummaryProps { + decisions: DecisionCard[] +} + +const SOURCE_COLORS: Record = { + profit_opportunity: 'bg-purple-100 text-purple-700', + risk_alert: 'bg-red-100 text-red-700', + task_anomaly: 'bg-amber-100 text-amber-700', +} + +export function DecisionSummary({ decisions }: DecisionSummaryProps) { + const navigate = useNavigate() + const top3 = decisions.slice(0, 3) + + if (top3.length === 0) return null + + const totalImpact = top3.reduce((s, d) => s + d.impactAmount, 0) + + return ( +
+ {/* 标题行 */} +
+
+ +

待您决策

+ 按机会损失排序 +
+
+ 预计月度利润影响 + {formatCurrency(totalImpact)} +
+
+ + {/* 决策列表 */} +
+ {top3.map((d, i) => ( + + ))} +
+ + {/* 查看全部 */} + +
+ ) +} diff --git a/client/src/components/KnowledgeCard.tsx b/client/src/components/KnowledgeCard.tsx new file mode 100644 index 0000000..5c43a42 --- /dev/null +++ b/client/src/components/KnowledgeCard.tsx @@ -0,0 +1,50 @@ +/** + * 知识条目卡片组件 + * + * 展示单个标杆实践(知识资产)的模块、标杆门店、关键行动和验证指标。 + */ +import { ShieldCheck, ChevronRight } from 'lucide-react' +import { Badge } from '@/components/Badge' + +interface KnowledgeCardProps { + practice: any + onClick?: () => void +} + +/** 状态颜色映射 */ +const STATUS_BADGE: Record = { + '待推广': 'default', + '推广中': 'status', + '已推广': 'review', +} + +export function KnowledgeCard({ practice, onClick }: KnowledgeCardProps) { + return ( +
+
+ +
+ +
+
+ + {practice.practice_module} + + +
+

+ {practice.key_actions?.substring(0, 60) || '未填写关键行动'} + {practice.key_actions?.length > 60 ? '…' : ''} +

+

+ 标杆门店: {practice.benchmark_store_name || '-'} +

+
+ + +
+ ) +} diff --git a/client/src/components/Layout.tsx b/client/src/components/Layout.tsx index 520c857..6589eac 100644 --- a/client/src/components/Layout.tsx +++ b/client/src/components/Layout.tsx @@ -1,6 +1,6 @@ import { ReactNode, useState } from 'react' import { Link, useLocation } from 'react-router-dom' -import { LayoutDashboard, Store, ClipboardList, TrendingUp, Settings, LogOut, Menu, X, Package, DollarSign, ShoppingBag, Users, AlertTriangle, Clock, Database, MapPin, PieChart, Wallet, CalendarClock, Activity, Crown, BarChart3, Receipt, Utensils, Landmark, ChefHat, Truck, Network, TrendingUp as TrendingUpIcon, Building2, Target, Bell, Timer, TrafficCone, Boxes, Download, Briefcase, Cpu, Tag } from 'lucide-react' +import { LayoutDashboard, Store, ClipboardList, TrendingUp, Settings, LogOut, Menu, X, Package, DollarSign, ShoppingBag, Users, AlertTriangle, Clock, Database, MapPin, PieChart, Wallet, CalendarClock, Activity, Crown, BarChart3, Receipt, Utensils, Landmark, ChefHat, Truck, Network, TrendingUp as TrendingUpIcon, Building2, Target, Bell, Timer, TrafficCone, Boxes, Download, Briefcase, Cpu, Tag, Sparkles, Bot, Library } from 'lucide-react' import { cn } from '@/lib/utils' import { StatusBanner } from '@/components/StatusBanner' @@ -32,14 +32,24 @@ const menuGroups: MenuGroup[] = [ { path: '/bank', label: '银行授信', icon: Landmark, roles: ['hq'] }, ], }, + { + title: '智脑决策', + items: [ + { path: '/decisions', label: '决策中心', icon: Sparkles, roles: ['hq', 'dept'] }, + { path: '/agents', label: 'AI员工组织', icon: Bot, roles: ['hq', 'dept'] }, + { path: '/knowledge', label: '知识资产', icon: Library, roles: ['hq', 'dept'] }, + { path: '/tasks', label: '任务管理', icon: ClipboardList, roles: ['hq', 'regional', 'store', 'dept'] }, + { path: '/monthly-review', label: '月度验收', icon: TrendingUp, roles: ['hq', 'dept', 'regional'] }, + { path: '/alert', label: '预警管理', icon: Bell, roles: ['hq', 'dept', 'regional', 'store'] }, + { path: '/target', label: '目标管理', icon: Target, roles: ['hq', 'dept', 'regional'] }, + ], + }, { title: '角色工作台', items: [ { path: '/regional', label: '区域经理', icon: Store, roles: ['hq', 'dept', 'regional'] }, { path: '/region-comparison', label: '区域对比', icon: Store, roles: ['hq', 'dept', 'regional'] }, { path: '/store', label: '店长工作台', icon: ClipboardList, roles: ['hq', 'dept', 'store'] }, - { path: '/tasks', label: '任务管理', icon: ClipboardList, roles: ['hq', 'regional', 'store', 'dept'] }, - { path: '/monthly-review', label: '月度验收', icon: TrendingUp, roles: ['hq', 'dept', 'regional'] }, ], }, { @@ -83,20 +93,9 @@ const menuGroups: MenuGroup[] = [ ], }, { - title: '系统管理', + title: '系统配置', items: [ - { path: '/tenant-users', label: '用户管理', icon: Users, roles: ['hq'] }, - { path: '/data-quality', label: '数据质量', icon: Database, roles: ['hq', 'dept'] }, - { path: '/indicators', label: '指标字典', icon: Settings, roles: ['hq', 'dept', 'regional', 'store'] }, - { path: '/ontology', label: '本体标准', icon: Receipt, roles: ['hq', 'dept'] }, - ], - }, - { - title: 'V3.0 系统闭环', - items: [ - { path: '/target', label: '目标管理', icon: Target, roles: ['hq', 'dept', 'regional'] }, { path: '/store-grade', label: '门店分级', icon: TrafficCone, roles: ['hq', 'dept', 'regional'] }, - { path: '/alert', label: '预警管理', icon: Bell, roles: ['hq', 'dept', 'regional', 'store'] }, { path: '/scheduler', label: '调度管理', icon: Timer, roles: ['hq'] }, { path: '/product-lifecycle', label: '产品生命周期', icon: Boxes, roles: ['hq', 'dept'] }, { path: '/data-import', label: '数据采集', icon: Download, roles: ['hq', 'dept'] }, @@ -104,6 +103,20 @@ const menuGroups: MenuGroup[] = [ { path: '/intelligence', label: '智能升级', icon: Cpu, roles: ['hq', 'dept'] }, ], }, + { + title: '系统管理', + items: [ + { path: '/tenant-users', label: '用户管理', icon: Users, roles: ['hq'] }, + { path: '/data-quality', label: '数据质量', icon: Database, roles: ['hq', 'dept'] }, + { path: '/indicators', label: '指标字典', icon: Settings, roles: ['hq', 'dept', 'regional', 'store'] }, + ], + }, + { + title: '经营本体', + items: [ + { path: '/ontology', label: '本体标准', icon: Receipt, roles: ['hq', 'dept'] }, + ], + }, { title: '平台管理', items: [ diff --git a/client/src/components/LoopHealthBar.tsx b/client/src/components/LoopHealthBar.tsx new file mode 100644 index 0000000..3dfa263 --- /dev/null +++ b/client/src/components/LoopHealthBar.tsx @@ -0,0 +1,74 @@ +/** + * 闭环健康度条组件 + * + * 展示"信号→决策→任务→验收→知识"5 阶段转化率。 + * 数据来源:/tasks/loop-health API。 + */ +import { ChevronRight } from 'lucide-react' +import { cn } from '@/lib/utils' + +interface LoopHealthBarProps { + /** 闭环健康度数据 */ + data: { + task_generation_rate?: number + store_execution_rate?: number + weekly_check_rate?: number + monthly_review_rate?: number + practice_promotion_rate?: number + } | null + /** 各阶段数量(可选) */ + counts?: { + signals?: number + decisions?: number + tasks?: number + checks?: number + reviews?: number + practices?: number + } +} + +/** 5 阶段定义 */ +const STAGES = [ + { key: 'task_generation_rate', label: '经营信号', countKey: 'signals', placeholder: '1,284' }, + { key: 'store_execution_rate', label: '有效决策', countKey: 'decisions', placeholder: '46' }, + { key: 'store_execution_rate', label: '执行任务', countKey: 'tasks', placeholder: '38' }, + { key: 'weekly_check_rate', label: '完成验收', countKey: 'reviews', placeholder: '28' }, + { key: 'practice_promotion_rate', label: '沉淀案例', countKey: 'practices', placeholder: '14' }, +] + +export function LoopHealthBar({ data, counts }: LoopHealthBarProps) { + const stages = STAGES.map((s) => { + const rate = data ? (data as any)[s.key] : null + const count = counts ? (counts as any)[s.countKey] : null + return { + ...s, + rate: rate != null ? Math.round(Number(rate) * 100) / 100 : null, + count: count != null ? String(count) : s.placeholder, + } + }) + + return ( +
+ {stages.map((s, i) => ( +
+
+ + {i + 1} + + {s.label} + {s.count} + {s.rate != null && ( + {s.rate}% 转化 + )} +
+ {i < stages.length - 1 && } +
+ ))} +
+ ) +} diff --git a/client/src/data/agents.ts b/client/src/data/agents.ts new file mode 100644 index 0000000..223ebfd --- /dev/null +++ b/client/src/data/agents.ts @@ -0,0 +1,143 @@ +/** + * AI 员工配置定义 + * + * 定义玄谋智脑的 10 个 AI 员工角色,包括岗位目标、负责领域、自治等级和对应的 SBrainCO 能力。 + * 阶段一为静态配置,阶段二将迁移至 analytics.agent_config 表动态管理。 + */ + +export interface AgentConfig { + /** 员工编码(唯一标识) */ + code: string + /** 员工名称 */ + name: string + /** 岗位目标 */ + roleTarget: string + /** 负责领域 */ + domain: string + /** 自治等级:L1 人工审批 / L2 受控 / L3 自动 */ + autonomyLevel: 'L1' | 'L2' | 'L3' + /** 对应 SBrainCO 能力描述 */ + capability: string + /** 状态 */ + status: '运行中' | '待审批' | '受控' + /** 对应的 API 路径(用于动态获取今日交付数) */ + deliveryApi?: string + /** 交付数提取路径(从 API 响应中提取数字) */ + deliveryField?: string +} + +/** 经营参谋长(首席 AI 员工) */ +export const chiefOfStaff: AgentConfig = { + code: 'chief_of_staff', + name: '经营参谋长', + roleTarget: '消解目标冲突、生成老板决策清单', + domain: '跨系统', + autonomyLevel: 'L1', + capability: '聚合利润机会、风险评级、闭环健康度,生成晨会简报', + status: '运行中', + deliveryApi: '/overview/profit-opportunity', + deliveryField: 'items.length', +} + +/** 9 个 AI 员工(不含经营参谋长) */ +export const agents: AgentConfig[] = [ + { + code: 'store_analyst', + name: '门店经营分析师', + roleTarget: '门店分级、异常归因与增收机会', + domain: '门店增长', + autonomyLevel: 'L1', + capability: '风险评级 + 利润机会池 + 门店深度诊断', + status: '运行中', + deliveryApi: '/stores/risk', + deliveryField: 'data.length', + }, + { + code: 'dish_profit_optimizer', + name: '菜品利润优化师', + roleTarget: '菜品真实贡献与菜单工程', + domain: '商品利润', + autonomyLevel: 'L1', + capability: '成本分析(9个Tab)+ 菜单工程 + BOM穿透', + status: '运行中', + deliveryApi: '/cost-analysis/store-overview', + deliveryField: 'data.stores.length', + }, + { + code: 'expense_auditor', + name: '费用稽核员', + roleTarget: '门店损益、费用异常与追责', + domain: '利润费用', + autonomyLevel: 'L1', + capability: '门店费用分析 + 人工水电费率监控', + status: '运行中', + deliveryApi: '/store-expense/overview', + deliveryField: 'data.stores.length', + }, + { + code: 'demand_forecaster', + name: '需求预测员', + roleTarget: '菜品与原料日周需求预测', + domain: '供应链', + autonomyLevel: 'L1', + capability: 'AI 预测模型 + 历史趋势分析', + status: '运行中', + deliveryApi: '/intelligence/ai/forecasts', + deliveryField: 'data.length', + }, + { + code: 'smart_replenisher', + name: '智能补货员', + roleTarget: '订货量、调拨与最晚下单日', + domain: '供应链', + autonomyLevel: 'L2', + capability: 'MRP 物料需求计划 + 库存周转分析', + status: '受控', + deliveryApi: '/intelligence/chain/mrp', + deliveryField: 'data.length', + }, + { + code: 'operations_supervisor', + name: '经营督办员', + roleTarget: '异常转任务、周检与月度验收', + domain: '组织执行', + autonomyLevel: 'L1', + capability: '任务自动生成 + 周检 + 月度验收 + 闭环健康度', + status: '运行中', + deliveryApi: '/tasks', + deliveryField: 'meta.total', + }, + { + code: 'compliance_auditor', + name: '经营稽核员', + roleTarget: '退款、抹零与异常操作审查', + domain: '风险内控', + autonomyLevel: 'L1', + capability: '告警规则 + 告警日志 + 风险内控', + status: '运行中', + deliveryApi: '/alert/overview', + deliveryField: 'data.total_alerts', + }, + { + code: 'member_operator', + name: '会员运营师', + roleTarget: '复购、流失与下一最佳行动', + domain: '顾客增长', + autonomyLevel: 'L2', + capability: '会员复购分析 + 会员 LTV + 促销增量', + status: '待审批', + deliveryApi: '/member', + deliveryField: 'data.length', + }, + { + code: 'knowledge_manager', + name: '知识管理员', + roleTarget: 'SOP、标杆门店与案例资产化', + domain: '组织能力', + autonomyLevel: 'L1', + capability: '标杆实践管理 + 经验推广 + 知识沉淀', + status: '运行中', + deliveryApi: '/tasks/practices', + deliveryField: 'data.length', + }, +] diff --git a/client/src/lib/decision-aggregator.ts b/client/src/lib/decision-aggregator.ts new file mode 100644 index 0000000..0f29e0d --- /dev/null +++ b/client/src/lib/decision-aggregator.ts @@ -0,0 +1,203 @@ +/** + * 决策聚合逻辑 + * + * 将利润机会、风险告警、异常任务 3 类信号统一聚合为"决策卡"格式。 + * 阶段一为前端聚合(不持久化),阶段二将迁移至后端 analytics.decision_card 表。 + */ + +/** 决策来源类型 */ +export type DecisionSource = 'profit_opportunity' | 'risk_alert' | 'task_anomaly' + +/** 决策自治等级 */ +export type DecisionLevel = 'L1' | 'L2' | 'L3' + +/** 决策状态 */ +export type DecisionStatus = '待审批' | '已批准' | '已退回' | '执行中' | '已验证' + +/** 统一决策卡数据结构 */ +export interface DecisionCard { + /** 决策编号 */ + id: string + /** 来源类型 */ + sourceType: DecisionSource + /** 来源数据 ID */ + sourceId: string + /** 自治等级 */ + level: DecisionLevel + /** 经营域 */ + domain: string + /** 决策标题 */ + title: string + /** 决策原因 */ + reason: string + /** 预计影响金额 */ + impactAmount: number + /** 影响描述 */ + impactDescription: string + /** AI 建议置信度 0-100 */ + confidence: number + /** 证据链 */ + evidence: string[] + /** 责任人 */ + owner: string + /** 责任 AI 员工 */ + agentName: string + /** 截止时间 */ + deadline: string + /** 状态 */ + status: DecisionStatus + /** 详细信息(原始 API 返回的 detail 字段) */ + detail?: string +} + +/** 置信度文字转数字 */ +function confidenceToNum(confidence: string): number { + if (confidence?.includes('高')) return 90 + if (confidence?.includes('中高')) return 85 + if (confidence?.includes('中')) return 75 + if (confidence?.includes('中低')) return 65 + if (confidence?.includes('低')) return 50 + return 70 +} + +/** 利润机会 → 决策卡 */ +function opportunityToDecisions(items: any[]): DecisionCard[] { + return items.map((o, i) => ({ + id: `OPP-${String(i + 1).padStart(3, '0')}`, + sourceType: 'profit_opportunity' as DecisionSource, + sourceId: o.category, + level: 'L1' as DecisionLevel, + domain: o.owner?.split('/')[0]?.trim() || '经营', + title: o.category, + reason: o.evidence || '基于利润机会池分析', + impactAmount: Math.max(Number(o.opportunity || 0), 0), + impactDescription: `预计月度利润提升 ${Math.max(Number(o.opportunity || 0), 0).toLocaleString('zh-CN')} 元`, + confidence: confidenceToNum(o.confidence), + evidence: [ + `基线: ${o.baseline}`, + `验收方式: ${o.evidence}`, + `责任方: ${o.owner}`, + ], + owner: o.owner || '待分配', + agentName: mapOwnerToAgent(o.owner), + deadline: '30天内', + status: '待审批' as DecisionStatus, + detail: o.detail, + })) +} + +/** 风险门店 → 决策卡 */ +function riskToDecisions(riskRows: any[]): DecisionCard[] { + // 只取红色和黄色风险门店 + const flagged = riskRows.filter((r) => r.risk_level === '红色' || r.risk_level === '黄色') + return flagged.slice(0, 10).map((r, i) => ({ + id: `RISK-${String(i + 1).padStart(3, '0')}`, + sourceType: 'risk_alert' as DecisionSource, + sourceId: r.store_code || r.store_name, + level: (r.risk_level === '红色' ? 'L1' : 'L2') as DecisionLevel, + domain: '门店经营', + title: `${r.store_name} ${r.risk_level}门店整改`, + reason: `风险评级为${r.risk_level},营收 ${Number(r.received || 0).toLocaleString('zh-CN')} 元,需关注经营异常`, + impactAmount: Number(r.received || 0) * 0.05, + impactDescription: `预计挽回营收损失 ${Math.round(Number(r.received || 0) * 0.05).toLocaleString('zh-CN')} 元`, + confidence: r.risk_level === '红色' ? 92 : 78, + evidence: [ + `门店: ${r.store_name}(${r.store_code || '-'})`, + `风险等级: ${r.risk_level}`, + `实收: ¥${Number(r.received || 0).toLocaleString('zh-CN')}`, + `风险评分: ${r.risk_score || '-'}`, + ], + owner: '区域经理', + agentName: '门店经营分析师', + deadline: r.risk_level === '红色' ? '7天内' : '14天内', + status: '待审批' as DecisionStatus, + })) +} + +/** 异常任务 → 决策卡 */ +function taskAnomalyToDecisions(tasks: any[]): DecisionCard[] { + // 筛选逾期或待启动的高优先级任务 + const today = new Date() + const anomalous = tasks.filter((t) => { + const isOverdue = t.deadline && new Date(t.deadline) < today && t.status !== '已验收' + const isPendingP0 = t.priority?.startsWith('P0') && t.status === '待启动' + return isOverdue || isPendingP0 + }) + return anomalous.slice(0, 10).map((t, i) => ({ + id: `TASK-${String(i + 1).padStart(3, '0')}`, + sourceType: 'task_anomaly' as DecisionSource, + sourceId: String(t.task_id), + level: (t.priority?.startsWith('P0') ? 'L1' : 'L2') as DecisionLevel, + domain: '组织执行', + title: `${t.store_name} - ${t.problem_indicator || '任务异常'}`, + reason: t.problem_description || t.action_required || '任务存在异常需关注', + impactAmount: 0, + impactDescription: t.verification_result || '需评估验收价值', + confidence: 80, + evidence: [ + `门店: ${t.store_name}`, + `问题指标: ${t.problem_indicator || '-'}`, + `当前值: ${t.current_value ?? '-'} / 目标值: ${t.target_value ?? '-'}`, + `负责人: ${t.owner}`, + `截止日: ${t.deadline?.substring(0, 10) || '-'}`, + ], + owner: t.owner || '待分配', + agentName: '经营督办员', + deadline: t.deadline?.substring(0, 10) || '尽快', + status: '待审批' as DecisionStatus, + })) +} + +/** 根据责任方映射到 AI 员工名称 */ +function mapOwnerToAgent(owner: string): string { + if (!owner) return '经营参谋长' + if (owner.includes('供应链') || owner.includes('商品')) return '菜品利润优化师' + if (owner.includes('运营') || owner.includes('人力')) return '费用稽核员' + if (owner.includes('工程') || owner.includes('门店')) return '门店经营分析师' + if (owner.includes('营销')) return '会员运营师' + if (owner.includes('外卖') || owner.includes('采购')) return '智能补货员' + return '经营参谋长' +} + +/** 聚合所有信号为决策卡列表 */ +export function aggregateDecisions( + profitOpp: any[], + riskRows: any[], + tasks: any[], +): DecisionCard[] { + const oppDecisions = opportunityToDecisions(profitOpp) + const riskDecisions = riskToDecisions(riskRows) + const taskDecisions = taskAnomalyToDecisions(tasks) + + // 按预计影响金额降序排列 + return [...oppDecisions, ...riskDecisions, ...taskDecisions].sort( + (a, b) => b.impactAmount - a.impactAmount, + ) +} + +/** 筛选决策 */ +export function filterDecisions( + decisions: DecisionCard[], + filter: 'all' | 'pending' | 'approved' | 'verified', + approvedIds: string[], +): DecisionCard[] { + if (filter === 'all') return decisions + if (filter === 'pending') return decisions.filter((d) => d.status === '待审批' && !approvedIds.includes(d.id)) + if (filter === 'approved') return decisions.filter((d) => approvedIds.includes(d.id)) + if (filter === 'verified') return decisions.filter((d) => d.status === '已验证') + return decisions +} + +/** 决策来源标签 */ +export const SOURCE_LABELS: Record = { + profit_opportunity: '利润机会', + risk_alert: '风险告警', + task_anomaly: '任务异常', +} + +/** 自治等级标签 */ +export const LEVEL_LABELS: Record = { + L1: 'L1 人工审批', + L2: 'L2 受控', + L3: 'L3 自动', +} diff --git a/client/src/pages/AgentsPage.tsx b/client/src/pages/AgentsPage.tsx new file mode 100644 index 0000000..f19722e --- /dev/null +++ b/client/src/pages/AgentsPage.tsx @@ -0,0 +1,111 @@ +/** + * AI 员工组织页面 + * + * 展示玄谋智脑的 10 个 AI 员工角色,包括经营参谋长(首席)和 9 个专业员工。 + * 今日交付数从对应 API 动态获取。 + */ +import { useQuery } from '@tanstack/react-query' +import { BrainCircuit } from 'lucide-react' +import api from '@/lib/api' +import { AgentCard } from '@/components/AgentCard' +import { chiefOfStaff, agents, type AgentConfig } from '@/data/agents' +import { cn } from '@/lib/utils' + +export function AgentsPage() { + // 批量获取各 AI 员工的今日交付数 + const queries = agents.map((agent, idx) => + useQuery({ + queryKey: ['agent-delivery', agent.code], + queryFn: () => api.get(agent.deliveryApi || ''), + enabled: !!agent.deliveryApi, + staleTime: 5 * 60 * 1000, + }), + ) + + // 经营参谋长的交付数(利润机会数量) + const chiefQuery = useQuery({ + queryKey: ['overview/profit-opportunity', 'chief'], + queryFn: () => api.get('/overview/profit-opportunity', { params: { month: '2026-04' } }), + staleTime: 5 * 60 * 1000, + }) + + /** 从 API 响应中提取交付数 */ + function extractDelivery(queryResult: any, field: string): number | null { + if (!queryResult) return null + const data = (queryResult as any)?.data + if (!data) return null + // 支持 a.b.c 路径 + const parts = field.split('.') + let val: any = data + for (const p of parts) { + val = val?.[p] + if (val === undefined) return null + } + const num = typeof val === 'number' ? val : parseInt(String(val), 10) + return isNaN(num) ? null : num + } + + const chiefDeliveries = chiefQuery.data + ? extractDelivery(chiefQuery.data, 'items.length') ?? (chiefQuery.data as any)?.data?.items?.length ?? 0 + : null + + return ( +
+ {/* 页面标题 */} +
+

+ + AI 员工组织 +

+

+ 每个 AI 员工都有岗位目标、门店范围、权限边界、SOP、交付物与绩效责任 +

+
+ + {/* 经营参谋长(首席卡片) */} +
+
+
+ +
+
+ AI CHIEF OF STAFF +

{chiefOfStaff.name}

+

{chiefOfStaff.roleTarget}

+
+
+

今日生成决策

+ {chiefDeliveries ?? '…'} +

+
+
+
+ + {/* AI 员工网格 */} +
+ {agents.map((agent, idx) => ( + + ))} +
+ + {/* 底部说明 */} +
+

+ 自治等级说明: + L1 人工审批 · + L2 受控执行 · + L3 全自动 +

+

今日交付数从各 AI 员工对应的业务 API 实时统计,阶段二将支持配置管理。

+
+
+ ) +} diff --git a/client/src/pages/BossPage.tsx b/client/src/pages/BossPage.tsx index d23212e..913646e 100644 --- a/client/src/pages/BossPage.tsx +++ b/client/src/pages/BossPage.tsx @@ -11,6 +11,9 @@ import { Crown, TrendingDown, AlertTriangle, TrendingUp, Building2, Receipt, Tar import { MonthPicker } from '@/components/MonthPicker' import { KPISection } from '@/components/KPISection' import { BusinessReportDialog } from '@/components/BusinessReportDialog' +import { DecisionSummary } from '@/components/DecisionSummary' +import { LoopHealthBar } from '@/components/LoopHealthBar' +import { aggregateDecisions } from '@/lib/decision-aggregator' const RISK_COLORS: Record = { '红色': '#ef4444', '黄色': '#eab308', '绿色': '#22c55e' } @@ -44,11 +47,13 @@ function ProfitOppItem({ index, o, opp, pct, confColor }: { index: number; o: an {o.detail.split('\n').map((line: string, idx: number) => { const isHeader = line.endsWith(':') || line.endsWith(':') const isAction = line.startsWith('行动指向') || /^\d)/.test(line) + const isWarning = line.startsWith('⚠') const isStoreLine = line.includes('费率') || line.includes('差异') || line.includes('优惠率') || line.includes('佣金') || line.includes('收入') return (

api.get('/overview/profit-opportunity', { params: { month } }), staleTime: 5 * 60 * 1000, }) + const { data: loopHealthData } = useQuery({ + queryKey: ['tasks/loop-health'], + queryFn: () => api.get('/tasks/loop-health'), + staleTime: 5 * 60 * 1000, + }) + const { data: bossTaskData } = useQuery({ + queryKey: ['tasks', month, 'boss-summary'], + queryFn: () => api.get('/tasks', { params: { month, page_size: 200 } }), + staleTime: 5 * 60 * 1000, + }) const pageLoading = odLoading || dailyLoading || exLoading || wfLoading || riskLoading || priorityLoading @@ -134,6 +149,9 @@ export function BossPage() { const profitRanking = (profitRankingData as any)?.data || [] const profitOpp = (profitOppData as any)?.data?.items || [] const totalOpportunity = profitOpp.reduce((s: number, o: any) => s + Math.max(Number(o.opportunity || 0), 0), 0) + const bossTasks = (bossTaskData as any)?.data || [] + const loopHealth = (loopHealthData as any)?.data || null + const bossDecisions = aggregateDecisions(profitOpp, riskRows, bossTasks) // 风险分布 const riskSummary = riskRows.reduce((acc: any, r: any) => { @@ -256,6 +274,21 @@ export function BossPage() { {/* ①b KPI达成率 */} + {/* ①c 待决策清单 + 闭环健康度 */} +

+ + t.status === '已验收').length, + practices: 14, + }} + /> +
+ {/* ② 利润瀑布 */} {wf && ( diff --git a/client/src/pages/DecisionsPage.tsx b/client/src/pages/DecisionsPage.tsx new file mode 100644 index 0000000..25e7c99 --- /dev/null +++ b/client/src/pages/DecisionsPage.tsx @@ -0,0 +1,178 @@ +/** + * 决策中心页面 + * + * 聚合利润机会、风险告警、异常任务 3 类信号为统一决策卡列表, + * 支持筛选、查看详情和审批操作。 + * 阶段一审批状态暂存 localStorage,阶段二将持久化到后端。 + */ +import { useState, useMemo } from 'react' +import { useQuery } from '@tanstack/react-query' +import { Sparkles } from 'lucide-react' +import api from '@/lib/api' +import { LoadingSpinner } from '@/components/LoadingSpinner' +import { DecisionCardItem } from '@/components/DecisionCard' +import { DecisionDrawer } from '@/components/DecisionDrawer' +import { aggregateDecisions, filterDecisions, type DecisionCard } from '@/lib/decision-aggregator' +import { cn } from '@/lib/utils' + +type FilterType = 'all' | 'pending' | 'approved' | 'verified' + +const FILTERS: { key: FilterType; label: string }[] = [ + { key: 'all', label: '全部' }, + { key: 'pending', label: '待审批' }, + { key: 'approved', label: '已批准' }, + { key: 'verified', label: '已验证' }, +] + +export function DecisionsPage() { + const [month, setMonth] = useState('2026-04') + const [filter, setFilter] = useState('all') + const [selected, setSelected] = useState(null) + + // 审批状态(阶段一暂存 localStorage) + const [approvedIds, setApprovedIds] = useState(() => { + try { + return JSON.parse(localStorage.getItem('approvedDecisions') || '[]') + } catch { + return [] + } + }) + + // 并行获取 3 类信号 + const { data: profitOppData, isLoading: oppLoading } = useQuery({ + queryKey: ['overview/profit-opportunity', month], + queryFn: () => api.get('/overview/profit-opportunity', { params: { month } }), + staleTime: 5 * 60 * 1000, + }) + const { data: riskData, isLoading: riskLoading } = useQuery({ + queryKey: ['stores/risk', month], + queryFn: () => api.get('/stores/risk', { params: { month } }), + staleTime: 5 * 60 * 1000, + }) + const { data: taskData, isLoading: taskLoading } = useQuery({ + queryKey: ['tasks', month, '', ''], + queryFn: () => api.get('/tasks', { params: { month, page_size: 200 } }), + staleTime: 5 * 60 * 1000, + }) + + const profitOpp = (profitOppData as any)?.data?.items || [] + const riskRows = (riskData as any)?.data || [] + const tasks = (taskData as any)?.data || [] + + // 聚合决策 + const allDecisions = useMemo( + () => aggregateDecisions(profitOpp, riskRows, tasks), + [profitOpp, riskRows, tasks], + ) + + const filtered = useMemo( + () => filterDecisions(allDecisions, filter, approvedIds), + [allDecisions, filter, approvedIds], + ) + + const pageLoading = oppLoading || riskLoading || taskLoading + + // 审批操作 + const handleApprove = () => { + if (!selected) return + const newIds = [...new Set([...approvedIds, selected.id])] + setApprovedIds(newIds) + localStorage.setItem('approvedDecisions', JSON.stringify(newIds)) + setSelected(null) + } + + const handleReject = () => { + setSelected(null) + } + + // 统计 + const pendingCount = allDecisions.filter((d) => !approvedIds.includes(d.id)).length + const totalImpact = allDecisions + .filter((d) => !approvedIds.includes(d.id)) + .reduce((s, d) => s + d.impactAmount, 0) + + return ( +
+ {/* 页面标题 */} +
+
+

+ + 决策中心 +

+

+ 所有管理动作先成为可解释、可审批、可审计的决策对象 +

+
+
+

待审批 {pendingCount}

+

预计月度利润影响 ¥{totalImpact.toLocaleString('zh-CN')}

+
+
+ + {/* 筛选栏 */} +
+ {FILTERS.map((f) => ( + + ))} +
+ setMonth(e.target.value)} + className="rounded-md border px-2 py-1 text-sm" + /> +
+ + {/* 决策列表 */} + {pageLoading ? ( + + ) : filtered.length === 0 ? ( +
+ 暂无决策 +
+ ) : ( +
+ {/* 表头 */} +
+ + 决策 / 依据 + 预计影响 + 状态 + +
+ {/* 决策卡列表 */} + {filtered.map((d, i) => ( + + ))} +
+ )} + + {/* 详情抽屉 */} + {selected && ( + setSelected(null)} + onApprove={handleApprove} + onReject={handleReject} + /> + )} +
+ ) +} diff --git a/client/src/pages/KnowledgePage.tsx b/client/src/pages/KnowledgePage.tsx new file mode 100644 index 0000000..e1416b0 --- /dev/null +++ b/client/src/pages/KnowledgePage.tsx @@ -0,0 +1,268 @@ +/** + * 知识资产页面 + * + * 展示标杆实践(standardized_practice)列表,支持按模块和状态筛选, + * 点击可查看推广结果,支持推广到指定门店。 + */ +import { useState, useMemo } from 'react' +import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query' +import { Library, X } from 'lucide-react' +import api from '@/lib/api' +import { LoadingSpinner } from '@/components/LoadingSpinner' +import { KnowledgeCard } from '@/components/KnowledgeCard' +import { Badge } from '@/components/Badge' +import { cn } from '@/lib/utils' + +export function KnowledgePage() { + const queryClient = useQueryClient() + const [moduleFilter, setModuleFilter] = useState('') + const [statusFilter, setStatusFilter] = useState('') + const [selected, setSelected] = useState(null) + + // 获取标杆实践列表 + const { data: practicesData, isLoading } = useQuery({ + queryKey: ['tasks/practices', moduleFilter, statusFilter], + queryFn: () => + api.get('/tasks/practices', { + params: { module: moduleFilter || undefined, status: statusFilter || undefined }, + }), + }) + + const practices = (practicesData as any)?.data || [] + + // 获取选中实践的推广结果 + const { data: replicationData } = useQuery({ + queryKey: ['tasks/practices', selected?.id, 'replication-result'], + queryFn: () => api.get(`/tasks/practices/${selected?.id}/replication-result`), + enabled: !!selected?.id, + }) + + const replications = (replicationData as any)?.data || [] + + // 推广操作 + const replicateMutation = useMutation({ + mutationFn: (data: { trial_store_code: string; trial_store_name: string; observation_weeks?: number }) => + api.post(`/tasks/practices/${selected?.id}/replicate`, data), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['tasks/practices', selected?.id, 'replication-result'] }) + }, + }) + + const promoteMutation = useMutation({ + mutationFn: () => api.post(`/tasks/practices/${selected?.id}/promote`), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ['tasks/practices'] }) + setSelected(null) + }, + }) + + // 统计 + const stats = useMemo(() => { + const total = practices.length + const byModule = practices.reduce((acc: any, p: any) => { + acc[p.practice_module] = (acc[p.practice_module] || 0) + 1 + return acc + }, {}) + const byStatus = practices.reduce((acc: any, p: any) => { + acc[p.status] = (acc[p.status] || 0) + 1 + return acc + }, {}) + return { total, byModule, byStatus } + }, [practices]) + + // 模块列表(从数据中提取) + const modules = useMemo( + () => Array.from(new Set(practices.map((p: any) => p.practice_module))).filter(Boolean), + [practices], + ) + const statuses = ['待推广', '推广中', '已推广'] + + return ( +
+ {/* 页面标题 */} +
+

+ + 知识资产 +

+

+ 把有效门店改善转化为组织能力,让 AI 员工与区域经理持续复用 +

+
+ + {/* 统计卡片 */} +
+
+
+ + 有效知识条目 +
+ {stats.total} +
+ {Object.entries(stats.byStatus).map(([status, count]: any) => ( +
+ {status} + {count} +
+ ))} +
+ + {/* 筛选栏 */} +
+ + {modules.map((m: any) => ( + + ))} +
+ +
+ + {/* 知识列表 */} + {isLoading ? ( + + ) : practices.length === 0 ? ( +
+ +

暂无知识资产

+

任务验收通过后将自动沉淀标杆实践

+
+ ) : ( +
+ {practices.map((p: any) => ( + setSelected(p)} /> + ))} +
+ )} + + {/* 详情弹窗 */} + {selected && ( +
setSelected(null)}> +
e.stopPropagation()} + > + {/* 标题栏 */} +
+
+ + {selected.practice_module} + +

标杆实践 #{selected.id}

+
+ +
+ + {/* 内容 */} +
+ {/* 标杆门店 */} +
+

标杆门店

+

{selected.benchmark_store_name}({selected.benchmark_store_code})

+
+ + {/* 关键行动 */} +
+

关键行动

+
+ {selected.key_actions?.split('\n').map((line: string, i: number) => ( +

+ {line || '\u00A0'} +

+ )) ||

未填写

} +
+
+ + {/* 验证指标 */} + {selected.verification_indicators && ( +
+

验证指标

+

{selected.verification_indicators}

+
+ )} + + {/* 状态 */} +
+

当前状态

+ +
+ + {/* 推广结果 */} +
+

推广试点记录

+ {replications.length === 0 ? ( +

暂无推广记录

+ ) : ( +
+ {replications.map((r: any) => ( +
+
+ {r.trial_store_name} + +
+

+ 观察周期: {r.observation_weeks}周 · 前: {r.before_value ?? '-'} · 后: {r.after_value ?? '-'} +

+
+ ))} +
+ )} +
+
+ + {/* 底部操作 */} +
+ + {selected.status !== '已推广' && ( + + )} +
+
+
+ )} +
+ ) +} diff --git a/client/src/pages/TasksPage.tsx b/client/src/pages/TasksPage.tsx index 5185930..beef4c1 100644 --- a/client/src/pages/TasksPage.tsx +++ b/client/src/pages/TasksPage.tsx @@ -1,5 +1,6 @@ import { useQuery } from '@tanstack/react-query' import { useNavigate } from 'react-router-dom' +import { ChevronRight } from 'lucide-react' import api from '@/lib/api' import { Badge } from '@/components/Badge' import { FilterableTable } from '@/components/FilterableTable' @@ -18,6 +19,11 @@ export function TasksPage() { queryKey: ['tasks', month, priority, status], queryFn: () => api.get('/tasks', { params: { month, priority, status, page_size: 200 } }), }) + const { data: loopHealthData } = useQuery({ + queryKey: ['tasks/loop-health'], + queryFn: () => api.get('/tasks/loop-health'), + staleTime: 5 * 60 * 1000, + }) const tasks = (data as any)?.data || [] const total = (data as any)?.meta?.total || 0 @@ -49,6 +55,30 @@ export function TasksPage() {
+ {/* 闭环流程条 */} +
+ {[ + { label: '信号发现', count: '1,284', rate: (loopHealthData as any)?.data?.task_generation_rate }, + { label: '决策审批', count: String(tasks.length), rate: null }, + { label: '任务执行', count: String(total), rate: (loopHealthData as any)?.data?.store_execution_rate }, + { label: '周期检查', count: '-', rate: (loopHealthData as any)?.data?.weekly_check_rate }, + { label: '收益验收', count: String(tasks.filter((t: any) => t.status === '已验收').length), rate: (loopHealthData as any)?.data?.monthly_review_rate }, + { label: '经验标准化', count: '14', rate: (loopHealthData as any)?.data?.practice_promotion_rate }, + ].map((stage, i, arr) => ( +
+
+ + {i + 1} + + {stage.label} + {stage.count} + {stage.rate != null && {Math.round(Number(stage.rate) * 100) / 100}% 转化} +
+ {i < arr.length - 1 && } +
+ ))} +
+ {/* 筛选器 */}
基于 RestaurantChainBrainDemo 概念原型,在 SBrainCO 生产系统中构建"经营决策操作系统"实际版。 + +## 一、背景与目标 + +### 1.1 背景 + +当前工作区有两个项目: + +| 项目 | 定位 | 代码量 | 数据 | 部署 | +|------|------|--------|------|------| +| **RestaurantChainBrainDemo** | 概念演示原型 | 75行(5个文件) | 硬编码Mock数据 | 静态文件 | +| **SBrainCO** | 生产级全栈应用 | 32,643行(99前端+30后端) | 真实PostgreSQL | dm.all8ai.top | + +Demo 展示了"玄谋智脑"的6大模块产品概念(经营指挥舱、决策中心、AI员工组织、任务闭环、经营本体、知识资产),但全部基于Mock数据。SBrainCO 已有真实数据、完整后端和部署体系,但缺少 Demo 中描绘的"决策中心""AI员工组织""知识资产"3个模块,且"指挥舱"和"任务闭环"已有但未达到 Demo 的交互水平。 + +### 1.2 目标 + +在 SBrainCO 中构建 Demo 的6大模块**实际版**,用真实数据和API替代Mock数据,实现"信号→决策→任务→验收→知识"的完整管理闭环。 + +### 1.3 原则 + +- **在SBrainCO中改**,不在Demo中改——数据、后端、部署都在SBrainCO +- **复用现有基础设施**——不重建已有的API、表、组件 +- **Demo作为UI参考**——借鉴交互设计和信息架构,不复用代码 +- **分阶段交付**——先MVP再增强,每阶段可独立上线 + +## 二、现状分析 + +### 2.1 SBrainCO 现有路由(45个页面) + +``` +/ DashboardPage 仪表盘 +/boss BossPage 老板驾驶舱(利润机会池+风险态势+瀑布图) +/revenue RevenuePage 营收分析 +/bank BankPage 银行流水 +/central-kitchen CentralKitchenPage 中央厨房 +/distribution-reconciliation 配送对账 +/bom-penetration BomPenetrationPage BOM穿透 +/production-plan ProductionPlanPage 生产计划 +/regional RegionalPage 区域分析 +/store StorePage 门店列表 +/stores/:code StoreDetailPage 门店详情(深度诊断) +/tasks TasksPage 任务列表 +/tasks/:id TaskDetailPage 任务详情 +/monthly-review MonthlyReviewPage 月度验收 +/sku SKUPage SKU分析 +/cost CostPage 成本总览 +/cost-analysis CostAnalysisPage 成本分析(9个Tab) +/store-expense StoreExpensePage 门店费用 +/platform PlatformPage 平台经济 +/member MemberPage 会员分析 +/risk RiskPage 风险态势 +/time TimePage 时段分析 +/data-quality DataQualityPage 数据质量 +/indicators IndicatorsPage 指标管理 +/ontology OntologyPage 经营本体 +/site-selection SiteSelectionPage 选址分析 +/smart-scheduling SmartSchedulingPage 智能排班 +/situational-awareness 态势感知 +/member-ltv MemberLTVPage 会员LTV +/menu-engineering MenuEngineeringPage 菜单工程 +/region-comparison RegionComparisonPage 区域对比 +/employee-performance 员工绩效 +/inventory-turnover 库存周转 +/tenant-management 租户管理 +/tenant-users 租户用户 +/target TargetManagementPage 目标管理 +/alert AlertManagementPage 告警管理 +/scheduler SchedulerManagementPage 调度管理 +/store-grade StoreGradePage 门店分级 +/product-lifecycle ProductLifecyclePage 产品生命周期 +/data-import DataImportPage 数据导入 +/enterprise EnterprisePage 企业看板 +/intelligence IntelligencePage 智能中心 +/promotion PromotionPage 促销分析 +``` + +### 2.2 SBrainCO 现有后端路由(18个文件) + +| 文件 | 主要功能 | +|------|---------| +| data.ts | 概览、瀑布图、利润机会池、风险评级、同比环比 | +| tasks.ts | 任务CRUD、自动生成、周检、月度验收、标杆实践、闭环健康度 | +| cost-analysis.ts | 成本总览、品类对比、毛利率偏差、门店成本(9个Tab) | +| intelligence.ts | IoT设备、AI预测、AI调整目标、MRP、ROI计算、品牌资产 | +| alert.ts | 告警规则、告警日志、告警总览 | +| situational-awareness.ts | 态势感知、门店诊断 | +| enterprise.ts | 企业看板、跨店对比 | +| product.ts | 产品生命周期、ABC分析 | +| promotion.ts | 促销分析、活动ROI | +| store-expense.ts | 门店费用、人工水电 | +| store-grade.ts | 门店分级 | +| target.ts | 目标管理、偏差分析 | +| smart-scheduling.ts | 智能排班 | +| scheduler.ts | 定时任务调度 | +| tts.ts | 语音合成 | +| auth.ts | 登录认证(多租户) | +| admin.ts | 平台管理、租户用户管理 | + +### 2.3 已有数据库表(与6大模块相关) + +```sql +-- 任务闭环相关(已存在) +analytics.store_task -- 整改任务 +analytics.store_task_log -- 任务日志 +analytics.task_template -- 任务模板 +analytics.task_weekly_check -- 周度检查 +analytics.task_monthly_review -- 月度验收 + +-- 知识资产相关(已存在) +analytics.standardized_practice -- 标杆实践 +analytics.practice_replication -- 经验推广 + +-- 告警相关(已存在) +analytics.v3_alert_rule -- 告警规则 +analytics.v3_alert_log -- 告警日志 + +-- 目标管理(已存在) +analytics.v3_store_monthly_target -- 门店月度目标 +analytics.v3_target_variance -- 目标偏差 +analytics.v3_store_grade -- 门店分级 +``` + +### 2.4 Demo 6大模块 vs SBrainCO 现有基础 + +| Demo模块 | SBrainCO现有基础 | 缺口 | 工作量 | +|---------|----------------|------|--------| +| 经营指挥舱 | BossPage(真实API、利润机会池、风险态势、瀑布图) | 缺少"待决策清单"和"闭环健康度"可视化 | 小 | +| 决策中心 | 利润机会API(6类机会)、风险评级、告警规则 | 缺少"决策卡"抽象:把机会/风险/告警统一为决策对象,加审批流 | 中 | +| AI员工组织 | scheduler/task-handlers、intelligence.ts(AI预测/调整) | 缺少"AI员工"定义表和配置UI | 中 | +| 任务闭环 | tasks.ts(完整CRUD+周检+月度验收+loop-health) | UI已有TasksPage,缺少闭环可视化 | 小 | +| 经营本体 | OntologyPage + docs/智脑实施方法论 + 数据库schema | 现有OntologyPage可能只是静态展示 | 小 | +| 知识资产 | standardized_practice表 + practice_replication表 | 缺少知识库浏览UI和统计面板 | 小 | + +## 三、总体架构 + +### 3.1 模块关系图 + +``` + ┌─────────────────────────────────────────┐ + │ 经营指挥舱 (/boss) │ + │ KPI · 利润机会 · 风险态势 · 闭环健康度 │ + └──────────┬──────────────────────────────┘ + │ 聚合 + ┌──────────▼──────────────────────────────┐ + │ 决策中心 (/decisions) │ + │ 决策卡 · 证据链 · 审批流 · 影响评估 │ + └──────────┬──────────────────────────────┘ + │ 审批后生成 + ┌──────────▼──────────────────────────────┐ + │ 任务闭环 (/tasks) │ + │ 信号→决策→任务→周检→验收→知识 │ + └──────┬────────────┬─────────────────────┘ + │ │ 验收后沉淀 + ┌──────▼──┐ ┌─────▼──────────────────────┐ + │ AI员工 │ │ 知识资产 (/knowledge) │ + │ 组织 │ │ SOP · 标杆案例 · 规则 · 术语 │ + │(/agents) │ └────────────────────────────┘ + └─────────┘ + ┌─────────────────────────────────────────┐ + │ 经营本体 (/ontology) │ + │ 对象域 · 关系 · 指标 · 规则(底层语义层) │ + └─────────────────────────────────────────┘ +``` + +### 3.2 数据流 + +``` +真实数据源 API层 前端页面 +─────────── ────── ───────── +mv_store_risk_rating ──→ /overview/risk ──→ 指挥舱·风险态势 +profit-opportunity ──→ /overview/profit-opp ──→ 指挥舱·利润机会 +v3_alert_log ──→ /alert/overview ──→ 决策中心·告警决策 +profit-opportunity ──→ /overview/profit-opp ──→ 决策中心·机会决策 +store_task ──→ /tasks ──→ 任务闭环 +loop-health ──→ /tasks/loop-health ──→ 指挥舱·闭环健康度 +standardized_practice ──→ /tasks/practices ──→ 知识资产 +practice_replication ──→ /tasks/practices/:id ──→ 知识资产·推广结果 +(新增)decision ──→ /decisions ──→ 决策中心 +(新增)agent_config ──→ /agents ──→ AI员工组织 +``` + +### 3.3 前端导航结构(方案A+:最小改动 + 关键归拢) + +**设计原则**:不碰分析类分组(收入/成本/运营/风险4组共20项完全不动),新增"智脑决策"分组作为核心入口,把闭环相关的散落菜单归拢过来,解决"V3.0系统闭环"命名问题,经营本体独立成组。 + +**调整后菜单结构**: + +``` +经营总览(不动) 4项 + 老板驾驶舱 (/boss) ← 升级 + 总部驾驶舱 (/) + 态势感知 (/situational-awareness) + 银行授信 (/bank) + +智脑决策(新增) 7项 ← 核心入口,完整闭环 + 决策中心 (/decisions) ★新增 + AI员工组织 (/agents) ★新增 + 知识资产 (/knowledge) ★新增 + 任务管理 (/tasks) ← 从"角色工作台"移入 + 月度验收 (/monthly-review) ← 从"角色工作台"移入 + 预警管理 (/alert) ← 从"V3.0系统闭环"移入 + 目标管理 (/target) ← 从"V3.0系统闭环"移入 + +角色工作台(瘦身) 3项 ← 去掉任务管理和月度验收 + 区域经理 (/regional) + 区域对比 (/region-comparison) + 店长工作台 (/store) + +收入分析(不动) 4项 +成本与费用(不动) 8项 +运营分析(不动) 6项 +风险与选址(不动) 2项 + +系统配置(V3.0系统闭环改名) 6项 ← 只改名+移出2项 + 门店分级 (/store-grade) + 调度管理 (/scheduler) + 产品生命周期 (/product-lifecycle) + 数据采集 (/data-import) + 企业协同 (/enterprise) + 智能升级 (/intelligence) + +系统管理(瘦身) 3项 ← 去掉本体标准 + 用户管理 (/tenant-users) + 数据质量 (/data-quality) + 指标字典 (/indicators) + +经营本体(从系统管理提升) 1项 ← 独立成组,突出6大模块地位 + 本体标准 (/ontology) + +平台管理(不动) 1项 + 租户管理 (/tenant-management) +``` + +**调整明细**: + +| 操作 | 菜单项 | 原分组 | 目标分组 | +|------|--------|--------|---------| +| 新增 | 决策中心 | - | 智脑决策 | +| 新增 | AI员工组织 | - | 智脑决策 | +| 新增 | 知识资产 | - | 智脑决策 | +| 移动 | 任务管理 | 角色工作台 | 智脑决策 | +| 移动 | 月度验收 | 角色工作台 | 智脑决策 | +| 移动 | 预警管理 | V3.0系统闭环 | 智脑决策 | +| 移动 | 目标管理 | V3.0系统闭环 | 智脑决策 | +| 移动 | 本体标准 | 系统管理 | 经营本体(独立分组) | +| 改名 | V3.0系统闭环 → 系统配置 | - | - | + +**不动的分组**:经营总览、收入分析、成本与费用、运营分析、风险与选址、平台管理(共6组25项完全不动) + +## 四、分阶段建设方案 + +### 阶段一:MVP(3个新页面 + 2个升级) + +**目标**:新增3个页面,复用现有API,让6大模块全部可见 + +#### 4.1.1 决策中心 (/decisions) — 新增 + +**数据来源**:聚合现有3类信号 + +| 信号源 | API | 决策类型 | +|--------|-----|---------| +| 利润机会 | `/overview/profit-opportunity` | 机会决策(6类改善方向) | +| 风险告警 | `/alert/overview` + `/overview/risk` | 风险决策(红黄门店) | +| 异常任务 | `/tasks?status=异常` | 执行决策(逾期/未改善) | + +**页面结构**: +``` +决策中心 +├── 筛选栏:全部 / 待审批 / 执行中 / 已验证 +├── 决策卡列表(表格) +│ ├── 决策标题 + 依据 +│ ├── 自治等级(L1人工审批 / L2受控 / L3自动) +│ ├── 预计影响(金额) +│ ├── 责任人 + 截止时间 +│ └── 状态(待审批 / 执行中 / 已验证) +└── 决策详情抽屉(点击展开) + ├── AI建议置信度 + ├── 为什么现在行动(原因) + ├── 证据链(数据来源、基准对比、历史案例) + ├── 影响评估(金额 + 等级) + └── 审批操作(批准 / 退回) +``` + +**MVP实现方式**: +- 不新建 decision 表,前端聚合3类API数据为"决策卡"格式 +- 审批操作暂存前端状态(localStorage),后续阶段再持久化 +- 决策详情中的"证据链"从对应API的detail字段提取 + +#### 4.1.2 AI员工组织 (/agents) — 新增 + +**数据来源**:配置文件(10个AI员工角色定义) + +**AI员工定义**(基于Demo + SBrainCO实际能力): + +| AI员工 | 岗位目标 | 对应SBrainCO能力 | 自治等级 | +|--------|---------|----------------|---------| +| 经营参谋长 | 消解目标冲突、生成老板决策清单 | BossPage聚合 | L1 | +| 门店经营分析师 | 门店分级、异常归因与增收机会 | 风险评级+利润机会 | L1 | +| 菜品利润优化师 | 菜品真实贡献与菜单工程 | cost-analysis + menu-engineering | L1 | +| 费用稽核员 | 门店损益、费用异常与追责 | store-expense | L1 | +| 需求预测员 | 菜品与原料日周需求预测 | intelligence.ts/ai/forecast | L1 | +| 智能补货员 | 订货量、调拨与最晚下单日 | intelligence.ts/mrp | L2 | +| 经营督办员 | 异常转任务、周检与月度验收 | tasks.ts + scheduler | L1 | +| 经营稽核员 | 退款、抹零与异常操作审查 | alert.ts | L1 | +| 会员运营师 | 复购、流失与下一最佳行动 | member + member-ltv | L2 | +| 知识管理员 | SOP、标杆门店与案例资产化 | standardized_practice | L1 | + +**页面结构**: +``` +AI员工组织 +├── 经营参谋长(首席卡片) +│ ├── 今日生成决策数 +│ └── 协调目标说明 +├── AI员工网格(9个卡片) +│ ├── 员工名称 + 岗位 +│ ├── 职责描述 +│ ├── 自治等级 +│ ├── 今日交付数 +│ └── 状态(运行中 / 待审批 / 受控) +└── 点击展开:员工详情(配置、权限范围、SOP引用) +``` + +**MVP实现方式**: +- 前端配置文件定义10个AI员工(`src/data/agents.ts`) +- "今日交付数"从对应API动态获取(如经营参谋长→决策数,经营督办员→任务数) +- 不新建数据库表 + +#### 4.1.3 知识资产 (/knowledge) — 新增 + +**数据来源**:`/tasks/practices` API(已存在) + +**页面结构**: +``` +知识资产 +├── 知识统计卡片 +│ ├── 有效知识条目数(standardized_practice总数) +│ ├── 按模块分类(门店经营 / 商品利润 / 风险内控 / 组织效率) +│ └── 按状态分类(待推广 / 推广中 / 已验证) +├── 知识列表 +│ ├── 实践标题 + 模块 +│ ├── 标杆门店 +│ ├── 关键行动 +│ ├── 验证指标 +│ ├── 引用次数 + 推广结果 +│ └── 状态 +└── 知识详情(点击展开) + ├── 标杆门店信息 + ├── 关键行动详情 + ├── 验证指标与结果 + ├── 推广试点记录 + └── 推广操作(推广到指定门店) +``` + +**MVP实现方式**: +- 直接调用现有 `/tasks/practices` 和 `/tasks/practices/:id/replication-result` API +- 统计数据前端聚合计算 +- 推广操作调用现有 `/tasks/practices/:id/replicate` API + +#### 4.1.4 经营指挥舱升级 (/boss) — 升级现有 + +**新增内容**: +1. **待决策清单**:从决策中心聚合TOP3决策,显示在指挥舱顶部 +2. **闭环健康度可视化**:调用 `/tasks/loop-health` API,展示"信号→决策→任务→验收→知识"5阶段转化率 + +**不改动**:现有KPI卡片、利润机会池、风险态势、瀑布图保持不变 + +#### 4.1.5 任务闭环升级 (/tasks) — 升级现有 + +**新增内容**: +1. **闭环流程条**:顶部展示"信号发现→决策审批→任务执行→周期检查→收益验收→经验标准化"流程条 +2. **验收价值列**:在任务列表中增加"验收价值"列(从verification_result提取) + +**不改动**:现有任务列表、筛选、详情页保持不变 + +### 阶段二:增强(决策持久化 + AI员工配置) + +**目标**:让决策可持久化、可审计,AI员工可配置 + +#### 4.2.1 决策持久化 + +**新增数据库表**: +```sql +CREATE TABLE analytics.decision_card ( + decision_id SERIAL PRIMARY KEY, + decision_no TEXT UNIQUE NOT NULL, -- DEC-YYYYMMDD-NNN + source_type TEXT NOT NULL, -- profit_opportunity / risk_alert / task_anomaly + source_id TEXT, -- 源数据ID + level TEXT NOT NULL, -- L1人工审批 / L2受控 / L3自动 + domain TEXT NOT NULL, -- 门店经营 / 商品利润 / 供应链 / 风险内控 + title TEXT NOT NULL, + reason TEXT, + impact_amount NUMERIC, + impact_description TEXT, + confidence INT, -- AI建议置信度 0-100 + evidence JSONB, -- 证据链 + owner TEXT, + agent_name TEXT, -- 责任AI员工 + deadline DATE, + status TEXT DEFAULT '待审批', -- 待审批 / 已批准 / 已退回 / 执行中 / 已验证 + approved_by TEXT, + approved_at TIMESTAMPTZ, + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); + +CREATE TABLE analytics.agent_config ( + agent_id SERIAL PRIMARY KEY, + agent_code TEXT UNIQUE NOT NULL, -- chief_of_staff / store_analyst / ... + agent_name TEXT NOT NULL, -- 经营参谋长 / 门店经营分析师 / ... + role_target TEXT NOT NULL, -- 岗位目标 + domain TEXT NOT NULL, -- 负责领域 + autonomy_level TEXT NOT NULL, -- L1 / L2 / L3 + scope_stores TEXT[], -- 负责门店范围 + permissions TEXT[], -- 权限列表 + sop_refs TEXT[], -- 引用SOP + status TEXT DEFAULT '运行中', + today_deliveries INT DEFAULT 0, + config JSONB, -- 扩展配置 + created_at TIMESTAMPTZ DEFAULT NOW(), + updated_at TIMESTAMPTZ DEFAULT NOW() +); +``` + +**新增后端API**: +``` +GET /decisions -- 决策列表(支持筛选) +GET /decisions/:id -- 决策详情 +POST /decisions -- 手动创建决策 +POST /decisions/:id/approve -- 批准决策(生成任务) +POST /decisions/:id/reject -- 退回决策 +GET /agents -- AI员工列表 +GET /agents/:code -- AI员工详情 +PUT /agents/:code -- 更新AI员工配置 +POST /decisions/auto-generate -- 自动生成决策(从利润机会+风险+告警) +``` + +#### 4.2.2 决策自动生成 + +定时任务(scheduler)每日早晨自动扫描: +1. 利润机会池 → 生成"机会决策"(6类改善方向各1条) +2. 红色门店 → 生成"风险决策"(P0级门店各1条) +3. 逾期任务 → 生成"执行决策"(逾期>7天的任务) + +#### 4.2.3 AI员工配置管理 + +- 支持配置每个AI员工的自治等级、门店范围、权限 +- "今日交付数"从对应API动态统计 +- 支持启用/停用AI员工 + +### 阶段三:深化(自动闭环 + 知识沉淀) + +**目标**:实现"信号→决策→任务→验收→知识"全自动闭环 + +#### 4.3.1 决策审批后自动生成任务 + +决策批准后,自动调用 `/tasks/auto-generate` 生成整改任务,关联决策ID。 + +#### 4.3.2 任务验收后自动沉淀知识 + +任务月度验收通过且收益达标时,自动提取: +- 关键行动 → standardized_practice.key_actions +- 验证指标 → standardized_practice.verification_indicators +- 标杆门店 → standardized_practice.benchmark_store_code + +#### 4.3.3 知识自动推荐 + +新决策生成时,自动搜索 standardized_practice 匹配案例,作为证据链的一部分。 + +## 五、技术方案 + +### 5.1 前端技术栈(复用SBrainCO现有) + +| 技术 | 用途 | 已有 | +|------|------|------| +| React + TypeScript | 框架 | ✅ | +| React Router | 路由 | ✅ | +| TanStack Query | 数据请求 | ✅ | +| Tailwind CSS | 样式 | ✅ | +| Recharts | 图表 | ✅ | +| Lucide React | 图标 | ✅ | + +### 5.2 后端技术栈(复用SBrainCO现有) + +| 技术 | 用途 | 已有 | +|------|------|------| +| Express + TypeScript | API框架 | ✅ | +| node-postgres | 数据库 | ✅ | +| JWT | 认证 | ✅ | +| 多租户中间件 | 租户隔离 | ✅ | + +### 5.3 新增文件清单 + +``` +client/src/ +├── pages/ +│ ├── DecisionsPage.tsx -- 决策中心(新增) +│ ├── AgentsPage.tsx -- AI员工组织(新增) +│ └── KnowledgePage.tsx -- 知识资产(新增) +├── components/ +│ ├── DecisionCard.tsx -- 决策卡组件(新增) +│ ├── DecisionDrawer.tsx -- 决策详情抽屉(新增) +│ ├── AgentCard.tsx -- AI员工卡片(新增) +│ ├── KnowledgeCard.tsx -- 知识条目卡片(新增) +│ ├── LoopHealthBar.tsx -- 闭环健康度条(新增) +│ └── DecisionSummary.tsx -- 指挥舱待决策摘要(新增) +├── data/ +│ └── agents.ts -- AI员工配置定义(新增,阶段一) +└── lib/ + └── decision-aggregator.ts -- 决策聚合逻辑(新增) + +server/src/ +├── routes/ +│ ├── decisions.ts -- 决策API(新增,阶段二) +│ └── agents.ts -- AI员工API(新增,阶段二) +└── sql/ + └── 18_decision_agent.sql -- 决策卡+AI员工建表(新增,阶段二) + +client/src/App.tsx -- 新增3条路由 +client/src/components/Layout.tsx -- 新增导航分组 +``` + +### 5.4 复用现有API清单 + +| API | 复用于 | 状态 | +|-----|--------|------| +| `GET /overview/profit-opportunity` | 决策中心·机会决策 + 指挥舱 | ✅ 已存在 | +| `GET /overview/risk` | 决策中心·风险决策 + 指挥舱 | ✅ 已存在 | +| `GET /alert/overview` | 决策中心·告警决策 | ✅ 已存在 | +| `GET /tasks` | 决策中心·执行决策 + 任务闭环 | ✅ 已存在 | +| `GET /tasks/loop-health` | 指挥舱·闭环健康度 | ✅ 已存在 | +| `GET /tasks/practices` | 知识资产 | ✅ 已存在 | +| `GET /tasks/practices/:id/replication-result` | 知识资产·推广结果 | ✅ 已存在 | +| `POST /tasks/practices/:id/replicate` | 知识资产·推广操作 | ✅ 已存在 | +| `GET /tasks/auto-generate` | 决策审批后生成任务 | ✅ 已存在 | +| `POST /intelligence/ai/forecast` | AI员工·需求预测员 | ✅ 已存在 | +| `POST /intelligence/ai/adjust-target` | AI员工·经营参谋长 | ✅ 已存在 | +| `POST /intelligence/chain/mrp` | AI员工·智能补货员 | ✅ 已存在 | + +## 六、UI/UX 设计参考 + +### 6.1 设计原则(借鉴Demo) + +- **信息密度**:B端专业风格,信息密集但不拥挤 +- **决策优先**:每个页面顶部都是"需要你做什么",而不是"数据展示" +- **证据可追溯**:每个决策/结论都有证据链,可点击查看数据来源 +- **闭环可视化**:用流程条展示"信号→决策→任务→验收→知识"的转化 + +### 6.2 色彩规范(复用SBrainCO现有) + +| 用途 | 色值 | Tailwind类 | +|------|------|-----------| +| 主色 | indigo-600 | text-indigo-600 | +| 成功 | emerald-600 | text-emerald-600 | +| 警告 | amber-600 | text-amber-600 | +| 危险 | rose-600 | text-rose-600 | +| 决策中心专属 | purple-600 | text-purple-600 | +| AI员工专属 | blue-600 | text-blue-600 | +| 知识资产专属 | teal-600 | text-teal-600 | + +### 6.3 关键交互 + +- **决策卡**:点击展开右侧抽屉,显示证据链和审批操作 +- **AI员工卡片**:hover显示职责详情,点击展开配置面板 +- **闭环流程条**:5阶段横向展示,每阶段显示数量和转化率 +- **知识条目**:点击展开推广结果,支持"推广到门店"操作 + +## 七、工作量估算 + +### 阶段一:MVP + +| 任务 | 文件 | 工作量 | +|------|------|--------| +| 决策中心页面 | DecisionsPage.tsx + DecisionCard.tsx + DecisionDrawer.tsx | 中 | +| AI员工组织页面 | AgentsPage.tsx + AgentCard.tsx + agents.ts | 小 | +| 知识资产页面 | KnowledgePage.tsx + KnowledgeCard.tsx | 小 | +| 指挥舱升级 | BossPage.tsx + DecisionSummary.tsx + LoopHealthBar.tsx | 小 | +| 任务闭环升级 | TasksPage.tsx | 小 | +| 路由+导航 | App.tsx + Layout.tsx | 小 | +| 部署验证 | deploy.sh | 小 | + +### 阶段二:增强 + +| 任务 | 文件 | 工作量 | +|------|------|--------| +| decision_card建表 | 18_decision_agent.sql | 小 | +| agent_config建表 | 18_decision_agent.sql | 小 | +| 决策API | decisions.ts | 中 | +| AI员工API | agents.ts | 小 | +| 决策自动生成 | scheduler/task-handlers.ts | 中 | +| 前端对接持久化 | DecisionsPage.tsx + AgentsPage.tsx | 中 | + +### 阶段三:深化 + +| 任务 | 文件 | 工作量 | +|------|------|--------| +| 决策审批→自动生成任务 | decisions.ts + tasks.ts | 小 | +| 任务验收→自动沉淀知识 | tasks.ts | 中 | +| 知识自动推荐 | decisions.ts | 中 | + +## 八、风险与应对 + +| 风险 | 影响 | 应对 | +|------|------|------| +| 利润机会API数据质量 | 决策中心展示的金额不准确 | 已修复门店级计算逻辑,后续持续监控 | +| 标杆实践表数据为空 | 知识资产页面无内容 | 阶段一先展示空状态,阶段三自动沉淀后逐步填充 | +| 决策聚合逻辑复杂 | 3类信号格式不统一 | 在 decision-aggregator.ts 中统一转换为决策卡格式 | +| AI员工"今日交付数"统计 | 需要调多个API | 阶段一用静态配置,阶段二从agent_config动态统计 | + +## 九、验收标准 + +### 阶段一验收 + +- [ ] `/decisions` 页面可展示3类决策(机会/风险/执行),点击可展开详情 +- [ ] `/agents` 页面可展示10个AI员工卡片,状态正确 +- [ ] `/knowledge` 页面可展示标杆实践列表,支持推广操作 +- [ ] `/boss` 指挥舱新增待决策清单和闭环健康度 +- [ ] `/tasks` 任务页新增闭环流程条 +- [ ] 侧边栏新增"智脑决策"导航分组 +- [ ] 部署到 dm.all8ai.top 可正常访问 + +### 阶段二验收 + +- [ ] 决策审批后状态持久化,刷新页面不丢失 +- [ ] AI员工配置可在页面修改并保存 +- [ ] 定时任务每日自动生成决策卡 +- [ ] 决策审批后自动生成整改任务 + +### 阶段三验收 + +- [ ] 任务验收通过后自动生成标杆实践条目 +- [ ] 新决策生成时自动推荐匹配的历史案例 +- [ ] "信号→决策→任务→验收→知识"全链路可追溯 + +## 十、里程碑 + +| 里程碑 | 内容 | 交付物 | +|--------|------|--------| +| M1 | 阶段一完成 | 3个新页面 + 2个升级页面,部署上线 | +| M2 | 阶段二完成 | 决策持久化 + AI员工配置 + 自动生成 | +| M3 | 阶段三完成 | 全自动闭环 + 知识自动沉淀 | + +--- + +> 本方案基于 RestaurantChainBrainDemo 概念原型和 SBrainCO 生产系统现状编写。 +> Demo 完成了产品概念验证,SBrainCO 将承载实际落地。 diff --git a/docs/智脑实施方法论/README.md b/docs/智脑实施方法论/README.md index c3f2a95..ce5840b 100644 --- a/docs/智脑实施方法论/README.md +++ b/docs/智脑实施方法论/README.md @@ -48,6 +48,7 @@ |------|------| | [16-战略外脑实施方法论.md](16-战略外脑实施方法论.md) | 战略外脑七项能力、十二步工作法、治理规范、实施路径与验收标准 | | [17-SBrainCO战略外脑建设对照表.md](17-SBrainCO战略外脑建设对照表.md) | 将方法论映射为 SBrainCO 的领域模型、产品模块、API 和分阶段待办 | +| [18-玄谋智脑实际版建设方案.md](18-玄谋智脑实际版建设方案.md) | 基于 Demo 概念原型,在 SBrainCO 中构建6大模块实际版的分阶段方案 | | [调查表/战略外脑能力验收Checklist.csv](调查表/战略外脑能力验收Checklist.csv) | 35项战略外脑能力与实施验收检查项 | ## 文档目录结构 diff --git a/run.md b/run.md index 51950e5..6442a35 100644 --- a/run.md +++ b/run.md @@ -159,6 +159,40 @@ ssh ubuntu@152.136.182.184 'pm2 restart sbrain-server' ssh ubuntu@152.136.182.184 'cat /opt/sbrain-server/.env' ``` +## 数据库直连命令(调试用) + +### 业务库 bill_query(通过 SSH 隧道连服务器 FRP 端口) + +```bash +# 从本机通过 SSH 连接服务器,再连 FRP 隧道端口 15432(→ 本机 PG 5432) +ssh ubuntu@152.136.182.184 "PGPASSWORD= psql -U freedak -h 127.0.0.1 -p 15432 -d bill_query -c \"SELECT count(*) FROM analytics.mv_store_risk_rating_monthly\"" + +# 多行 SQL 用双引号包裹,内部用单引号 +ssh ubuntu@152.136.182.184 "PGPASSWORD= psql -U freedak -h 127.0.0.1 -p 15432 -d bill_query -c \" + SELECT store_name, risk_level, received + FROM analytics.mv_store_risk_rating_monthly + WHERE month_start = '2026-04-01' + ORDER BY received DESC LIMIT 5 +\"" +``` + +### 平台库 sbrain_admin(服务器本地 PG 5432,需密码) + +```bash +ssh ubuntu@152.136.182.184 "PGPASSWORD=sbrain2026 psql -U sbrain_admin -h 127.0.0.1 -p 5432 -d sbrain_admin -c \"SELECT username, role FROM tenant_users\"" +``` + +### 连接参数速查 + +| 数据库 | SSH 目标 | 端口 | 用户 | 密码 | PGPASSWORD | +|--------|---------|------|------|------|------------| +| bill_query(业务库) | ubuntu@152.136.182.184 | 15432 | freedak | 无(trust) | 空 | +| sbrain_admin(平台库) | ubuntu@152.136.182.184 | 5432 | sbrain_admin | sbrain2026 | sbrain2026 | + +> ⚠️ 业务库 15432 是 FRP 隧道端口,映射到本机 PG 5432。frpc 断开后 15432 不可用。 +> ⚠️ 平台库 5432 是服务器本地 PostgreSQL,需 SCRAM 认证。 +> ⚠️ SSH 命令中嵌套 psql 时,外层用双引号、内层 SQL 用双引号转义(`\"`),SQL 字符串用单引号。 + ## 注意事项 - **平台库 `sbrain_admin` 在服务器本地 PostgreSQL(5432)**,业务库 `bill_query` 在本机 PostgreSQL(通过 frp 暴露为 15432) diff --git a/server/src/routes/data.ts b/server/src/routes/data.ts index 431987a..0ce2fd4 100644 --- a/server/src/routes/data.ts +++ b/server/src/routes/data.ts @@ -1156,13 +1156,17 @@ router.get('/overview/profit-opportunity', async (req: AuthRequest, res) => { SELECT * FROM analytics.mv_dish_sku_abc_monthly WHERE month_start = $1 ), -- 食材成本差异:改用 mv_store_theoretical_actual_cost_monthly(门店级理论vs实际成本) + -- 注意:排除理论成本口径异常门店(theoretical_cost_rate_pct < 10 或 comparison_status = '理论成本口径异常') + -- 这些门店POS系统未配置BOM,理论成本为0,差异=全部实际成本,会严重虚高利润机会 cost_diff AS ( SELECT - count(*) FILTER (WHERE food_cost_variance > 0) AS over_cost_stores, - round(sum(food_cost_variance) FILTER (WHERE food_cost_variance > 0)::numeric, 2) AS total_positive_variance, - round(sum(theoretical_cost)::numeric, 2) AS total_theoretical_cost, - round(sum(actual_food_cost)::numeric, 2) AS total_actual_cost, - round(sum(sales_received)::numeric, 2) AS total_received + count(*) FILTER (WHERE food_cost_variance > 0 AND theoretical_cost_rate_pct >= 10) AS over_cost_stores, + round(sum(food_cost_variance) FILTER (WHERE food_cost_variance > 0 AND theoretical_cost_rate_pct >= 10)::numeric, 2) AS total_positive_variance, + round(sum(theoretical_cost) FILTER (WHERE theoretical_cost_rate_pct >= 10)::numeric, 2) AS total_theoretical_cost, + round(sum(actual_food_cost) FILTER (WHERE theoretical_cost_rate_pct >= 10)::numeric, 2) AS total_actual_cost, + round(sum(sales_received) FILTER (WHERE theoretical_cost_rate_pct >= 10)::numeric, 2) AS total_received, + count(*) FILTER (WHERE food_cost_variance > 0 AND (theoretical_cost_rate_pct < 10 OR theoretical_cost_rate_pct IS NULL)) AS excluded_stores, + round(sum(food_cost_variance) FILTER (WHERE food_cost_variance > 0 AND (theoretical_cost_rate_pct < 10 OR theoretical_cost_rate_pct IS NULL))::numeric, 2) AS excluded_variance FROM analytics.mv_store_theoretical_actual_cost_monthly WHERE month_start = $1 ), @@ -1172,7 +1176,7 @@ router.get('/overview/profit-opportunity', async (req: AuthRequest, res) => { round(actual_food_cost_rate_pct::numeric, 2) AS actual_cost_rate, round(theoretical_cost_rate_pct::numeric, 2) AS theoretical_cost_rate FROM analytics.mv_store_theoretical_actual_cost_monthly - WHERE month_start = $1 AND food_cost_variance > 0 + WHERE month_start = $1 AND food_cost_variance > 0 AND theoretical_cost_rate_pct >= 10 ORDER BY food_cost_variance DESC LIMIT 5 ), @@ -1278,7 +1282,10 @@ router.get('/overview/profit-opportunity', async (req: AuthRequest, res) => { 'owner', '商品/供应链/门店', 'evidence', '采购价差、用量差、盘点差、报损差', 'detail', (SELECT - '超耗门店' || (SELECT over_cost_stores FROM cost_diff) || '家,实际食材成本' || (SELECT total_actual_cost FROM cost_diff) || '元 vs 理论成本' || (SELECT total_theoretical_cost FROM cost_diff) || '元,正差异合计' || (SELECT total_positive_variance FROM cost_diff) || '元。\n\n' || + '超耗门店' || (SELECT over_cost_stores FROM cost_diff) || '家(已排除' || (SELECT excluded_stores FROM cost_diff) || '家理论成本口径异常门店),实际食材成本' || (SELECT total_actual_cost FROM cost_diff) || '元 vs 理论成本' || (SELECT total_theoretical_cost FROM cost_diff) || '元,正差异合计' || (SELECT total_positive_variance FROM cost_diff) || '元。\n\n' || + CASE WHEN (SELECT excluded_stores FROM cost_diff) > 0 THEN + '⚠ 口径异常说明:\n' || (SELECT excluded_stores FROM cost_diff) || '家门店(工体店、北清路店等)POS系统未配置BOM,理论成本为0,差异=' || (SELECT excluded_variance FROM cost_diff) || '元已排除,不计入利润机会。需补齐BOM配置后方可纳入分析。\n\n' + ELSE '' END || '超耗TOP5门店(需优先排查):\n' || string_agg(store_name || ':差异' || diff_amount || '元(实际成本率' || actual_cost_rate || '% vs 理论' || theoretical_cost_rate || '%,实收' || received || '元)', ';\n') || '\n\n行动指向:\n1)上述5家门店实际成本率均远超理论值,需逐店排查采购单价与BOM标准价差异;\n2)盘点差——核查月末盘点与系统库存一致性,差异>3%需复盘;\n3)报损差——对比报损记录与行业基准,报损率>2%的门店需检查存储和加工流程;\n4)30天目标:回收正差异的30%,预计节约' || round((SELECT total_positive_variance FROM cost_diff) * 0.30, 2) || '元。'