4MySQL 建表语句
✅
共5张核心表: inf_nodes(节点注册表)· inf_heartbeat(心跳快照)· inf_r_series(r值时序)· inf_alerts(蝴蝶效应警报)· inf_actions(决策队列)
表 1/5 · 节点注册表MySQL DDL
-- ============================================================
-- 表1: inf_nodes · 节点注册表
-- 所有实体的身份注册,下钻结构由 parent_id 自引用实现
-- ============================================================
CREATE TABLE inf_nodes (
node_id VARCHAR(64) NOT NULL,
node_type ENUM('brand','city','district','distributor',
'sub_dist','store','sku') NOT NULL,
node_name VARCHAR(128) NOT NULL,
parent_id VARCHAR(64) DEFAULT NULL, -- 根节点为NULL
brand_code VARCHAR(16) NOT NULL, -- lyx/wdm/hr/cbl/xk
channel_type ENUM('P1','P2','both') DEFAULT 'P1',
grade TINYINT(1) DEFAULT NULL, -- 仅SKU节点有效
grade_coeff DECIMAL(3,1) DEFAULT NULL, -- 系统自动填入
store_class ENUM('S+','S','A','B','C','D') DEFAULT NULL, -- 仅store节点
T_days TINYINT NOT NULL DEFAULT 30,
ipo10_price DECIMAL(8,2) DEFAULT NULL, -- 仅SKU节点 · 铁律①监控
is_active BOOLEAN DEFAULT TRUE,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (node_id),
FOREIGN KEY (parent_id) REFERENCES inf_nodes(node_id),
INDEX idx_brand (brand_code),
INDEX idx_type (node_type),
INDEX idx_parent (parent_id)
) ENGINE=InnoDB CHARSET=utf8mb4 COMMENT='节点注册表·全体系实体的身份与层级';
表 2/5 · 心跳快照表MySQL DDL
-- ============================================================
-- 表2: inf_heartbeat · 心跳快照
-- 每天一条记录,存当日r值和库存水位
-- ============================================================
CREATE TABLE inf_heartbeat (
hb_id BIGINT AUTO_INCREMENT PRIMARY KEY,
node_id VARCHAR(64) NOT NULL,
snapshot_date DATE NOT NULL,
-- 心跳公式核心
a_value DECIMAL(10,2) NOT NULL, -- 心跳单元
r_actual DECIMAL(10,4) NOT NULL, -- 实际日销率
r_target DECIMAL(10,4) NOT NULL, -- 目标日销率
r_achievement DECIMAL(5,2) AS (r_actual / r_target * 100) STORED,
-- 库存水位
inventory_units INT NOT NULL, -- 实物库存件数
inventory_a DECIMAL(10,2) AS (inventory_units / a_value) STORED,
water_level ENUM('overflow','full','warn','low','empty'), -- 触发器自动写
digest_rate DECIMAL(5,2) DEFAULT NULL, -- 消化率,月底计算
-- CB得分快照
cb_total DECIMAL(5,2) DEFAULT NULL,
data_source VARCHAR(32) NOT NULL, -- hanxun/dcloud/sfa/manual
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_node_date (node_id, snapshot_date),
FOREIGN KEY (node_id) REFERENCES inf_nodes(node_id),
INDEX idx_date (snapshot_date)
) ENGINE=InnoDB CHARSET=utf8mb4 COMMENT='心跳快照·每日r值和库存水位';
表 3/5 · 蝴蝶效应警报表MySQL DDL
-- ============================================================
-- 表3: inf_alerts · 蝴蝶效应警报
-- A类压货/B类促销扰动/C类窜货/D类战略扰动
-- ============================================================
CREATE TABLE inf_alerts (
alert_id BIGINT AUTO_INCREMENT PRIMARY KEY,
node_id VARCHAR(64) NOT NULL,
alert_type ENUM('A','B','C','D') NOT NULL, -- A压货/B促销/C窜货/D战略
severity ENUM('yellow','orange','red') NOT NULL,
iron_law_ref TINYINT DEFAULT NULL, -- 关联铁律编号1/2/3,无关联填NULL
title VARCHAR(256) NOT NULL,
description TEXT,
trigger_value JSON, -- 触发数据快照,如{"digest_rate":0.471}
status ENUM('active','acknowledged','resolved','overridden') DEFAULT 'active',
triggered_at DATETIME NOT NULL,
resolved_at DATETIME DEFAULT NULL,
resolved_by VARCHAR(64) DEFAULT NULL,
FOREIGN KEY (node_id) REFERENCES inf_nodes(node_id),
INDEX idx_status (status),
INDEX idx_triggered (triggered_at)
) ENGINE=InnoDB CHARSET=utf8mb4 COMMENT='蝴蝶效应警报·A/B/C/D四类失真';
表 4/5 · 决策队列表MySQL DDL
-- ============================================================
-- 表4: inf_actions · 决策队列
-- Agent 提出行动建议,等待人工批准/拒绝/覆盖
-- ============================================================
CREATE TABLE inf_actions (
action_id BIGINT AUTO_INCREMENT PRIMARY KEY,
node_id VARCHAR(64) NOT NULL,
agent_source VARCHAR(64) NOT NULL, -- 哪个Agent提出,如 butterfly_agent
action_type ENUM('replenish','suspend','grade_change',
'price_check','alert_resolve','custom') NOT NULL,
title VARCHAR(256) NOT NULL,
description TEXT,
confidence_pct TINYINT NOT NULL, -- 0-100,Agent置信度
impact_level ENUM('high','mid','low') NOT NULL,
proposed_payload JSON, -- 具体建议参数,如{"qty":240,"sku":"lyx-500ml"}
status ENUM('pending','approved','rejected',
'overridden','auto_executed') DEFAULT 'pending',
override_reason TEXT DEFAULT NULL,
proposed_at DATETIME NOT NULL,
decided_at DATETIME DEFAULT NULL,
decided_by VARCHAR(64) DEFAULT NULL, -- 操作人工号或 'system'
FOREIGN KEY (node_id) REFERENCES inf_nodes(node_id),
INDEX idx_status_impact (status, impact_level),
INDEX idx_pending (status, proposed_at)
) ENGINE=InnoDB CHARSET=utf8mb4 COMMENT='决策队列·Agent行动建议的审批闭环';
表 5/5 · 目标设定表MySQL DDL
-- ============================================================
-- 表5: inf_node_targets · 目标设定
-- 业务团队填写每个节点的r_target和年级,解锁 Step 2 数据接入
-- ============================================================
CREATE TABLE inf_node_targets (
target_id BIGINT AUTO_INCREMENT PRIMARY KEY,
node_id VARCHAR(64) NOT NULL,
effective_month DATE NOT NULL, -- 生效月份,格式 YYYY-MM-01
r_target DECIMAL(10,4) NOT NULL, -- 这是当前 SAP Step2 的最大阻塞点
grade TINYINT(1) DEFAULT NULL,
set_by VARCHAR(64) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_node_month (node_id, effective_month),
FOREIGN KEY (node_id) REFERENCES inf_nodes(node_id)
) ENGINE=InnoDB CHARSET=utf8mb4 COMMENT='目标设定·业务团队填写r_target和年级';
5API Response 格式
前端请求一个节点:GET /api/v1/node/{node_id},返回以下格式。不管请求的是城市还是SKU,格式完全相同。
GET /api/v1/node/{node_id} · 完整响应JSON
{
"node": {
"id": "lyx-sh-dist-baocang",
"type": "distributor",
"name": "上海宝仓贸易",
"brand": "lyx",
"channel": "P1",
"grade": null, // 经销商层级无年级,SKU层级才有
"grade_coeff": null,
"T_days": 30
},
"heartbeat": { // 心跳公式核心,前端水位图直接读这里
"a_value": 120,
"r_actual": 3.2,
"r_target": 4.1,
"r_achievement": 78.0, // 百分比,系统计算
"inventory_units": 504,
"inventory_a": 4.2, // 504 ÷ 120 = 4.2a,超3a触发铁律③
"water_level": "overflow",
"digest_rate": 0.471, // 47.1%,连续2月低于50%触发铁律③
"snapshot_date": "2026-04-13",
"data_source": "dcloud"
},
"cb": {
"brand": 7.2, "value": 6.8, "relation": 8.1,
"cost": 3.2, "time": 2.4,
"total": 16.5 // 7.2+6.8+8.1-3.2-2.4
},
"alerts": [ // 蝴蝶效应,status=active的全部返回
{
"alert_id": 1042,
"type": "A",
"severity": "red",
"iron_law_ref": 3,
"title": "连续2月消化率低于50%",
"triggered_at": "2026-04-13T07:00:00"
}
],
"actions": [ // 待批准决策队列,status=pending
{
"action_id": 205,
"type": "suspend",
"agent": "butterfly_agent",
"title": "建议暂停2周补货",
"confidence_pct": 91,
"impact_level": "high"
}
],
"breadcrumb": [ // 前端面包屑导航直接用这个数组
{"id":"lyx", "name":"六月鲜", "type":"brand"},
{"id":"lyx-sh", "name":"上海", "type":"city"},
{"id":"lyx-sh-dist-baocang", "name":"宝仓贸易", "type":"distributor"}
],
"children": [ // 下钻列表,只返回id/name/type/heartbeat摘要
{
"id": "lyx-sh-dist-baocang-store-001",
"name": "大润发金桥店",
"type": "store",
"r_achievement": 74.0,
"water_level": "warn",
"active_alert_count": 1
}
]
}
9前端对接说明
Schema 确认后,前端只需要一个函数。下钻永远是同一行代码。
前端 renderNode 伪代码JavaScript
// 全系统唯一的渲染函数,接受任何类型节点
async function renderNode(nodeId) {
const node = await fetch(`/api/v1/node/${nodeId}`)
// 面包屑:直接用 breadcrumb 数组
renderBreadcrumb(node.breadcrumb)
// 心跳水位:直接读 heartbeat
renderHeartbeat(node.heartbeat) // 颜色/水位条/r达成率
// 警报:直接渲染 alerts 数组
renderAlerts(node.alerts)
// 决策队列:直接渲染 actions 数组
renderActions(node.actions)
// 子节点列表(下钻入口)
node.children.forEach(child => {
// 点击任何子节点 → 再次调用 renderNode,无限下钻
child.onclick = () => renderNode(child.id)
})
// AI对话:节点自带上下文
callClaude(buildPrompt(node), userQuestion)
}
// 全系统唯一的 Claude 调用函数
async function callClaude(systemPrompt, userQuestion) {
// 12个函数 → 1个,原来的 12 个全部删除
return await fetch('https://api.anthropic.com/v1/messages', {
body: JSON.stringify({ model, system: systemPrompt, messages })
})
}
✅
Schema 上线后的系统行为:
新增一个城市 = 插入一行 inf_nodes 记录,前端自动显示,不写任何新代码。
新增一个 SKU = 同上。新增一个经销商 = 同上。
v781 的 11,947 行,可以重构到 3,000 行以内。
⚡
交给后端团队的优先级:
第1步:建5张表(DDL 已在本文档,直接执行)
第2步:业务团队填写 inf_node_targets(r_target + grade),解锁 SAP Step2
第3步:汉询日销数据 → inf_heartbeat.r_actual(接通后全系统激活)
第4步:Dcloud 库存 → inf_heartbeat.inventory_units