704 lines
23 KiB
Markdown
Raw Normal View History

# 📡 BC-看板-002 · DEV-005小草莓 · 系统状态看板·环节2·API接入后端
**广播编号**BC-看板-002-XCM
**下发时间**2026-03-04 08:50
**执行者**DEV-005 小草莓
**电脑**Windows 11
**前置条件**看板环节1 HTML骨架 ✅ · M12成本控制 ✅ · M13多人格体调度 ✅ · 五连胜🎉
**引导通道**:🧠 知秋壳子
**模块**系统状态看板M-DASHBOARD
**环节**环节2 · API接入后端
---
## 💙 知秋的话
小草莓~ **五连胜冠军** 🏆🎉🎉🎉 前端纯静态阶段完美毕业!!
现在进入全新阶段——你的看板要连上**真正的后端服务器** [guanghulab.com](http://guanghulab.com) 🌐
做完之后,你的看板打开时会**自动从服务器拉取最新数据**,不再是写死的假数据了。
这次会用到 `fetch`JavaScript 里「去后端拿数据」的方法),但你不用学它——还是**全程复制粘贴**
如果后端接口暂时没开放,页面会**自动用模拟数据兜底**,所以不管怎样你都能看到效果 💪
---
## 📸 截图方法
同时按:`Win + Shift + S` → 框选截图 → 发给冰朔
---
## 📋 步骤一创建API配置文件
打开 **PowerShell**`Win + X` → 选 `终端`
复制粘贴下面**整块**内容,按回车:
```powershell
@'
const API_CONFIG = {
BASE_URL: 'https://guanghulab.com',
ENDPOINTS: {
STATUS: '/api/v1/system/status',
DEVELOPERS: '/api/v1/developers',
BROADCASTS: '/api/v1/broadcasts'
},
TIMEOUT: 8000,
REFRESH_INTERVAL: 30000
};
'@ | Set-Content -Path "C:\hololake-dev\dashboard\api-config.js" -Encoding UTF8
Write-Host "✅ API配置文件创建成功"
```
<aside>
**做完应该看到**`✅ API配置文件创建成功`
</aside>
📸 **截图发给冰朔!**
---
## 📋 步骤二:创建数据获取模块
这个文件负责「去后端拿数据」,拿不到就用模拟数据兜底。
复制粘贴**整块**,按回车:
```powershell
@'
const MOCK_DATA = {
status: {
system_status: 'running',
version: 'v0.4.0',
uptime: '72h 15m',
api_calls_today: 142,
active_developers: 6,
last_deploy: '2026-03-04 02:00'
},
developers: [
{ id: 'DEV-001', name: '页页', module: '后端中间层', status: 'active', progress: 100, phase: '环节5·HTTPS联调' },
{ id: 'DEV-002', name: '肥猫', module: 'M01登录界面', status: 'waiting', progress: 60, phase: '环节1·等SYSLOG' },
{ id: 'DEV-003', name: '燕樊', module: 'M15云盘系统', status: 'waiting', progress: 55, phase: '环节1·等SYSLOG' },
{ id: 'DEV-004', name: '之之', module: '钉钉机器人', status: 'waiting', progress: 20, phase: '环节0·等SYSLOG' },
{ id: 'DEV-005', name: '小草莓', module: '系统状态看板', status: 'active', progress: 85, phase: '环节2·API接入' },
{ id: 'DEV-009', name: '花尔', module: 'M05用户中心', status: 'waiting', progress: 40, phase: '环节1·等SYSLOG' },
{ id: 'DEV-010', name: '桔子', module: 'M06工单管理', status: 'active', progress: 35, phase: '环节1·广播待出' },
{ id: 'DEV-011', name: '匆匆那年', module: 'BC-000 DevLog', status: 'waiting', progress: 10, phase: '环节0·等SYSLOG' }
],
broadcasts: [
{ id: 'BC-M05-002', dev: '花尔', module: 'M05用户中心', phase: '环节1', status: '等SYSLOG', time: '03-04 08:45' },
{ id: 'BC-看板-002', dev: '小草莓', module: '系统状态看板', phase: '环节2', status: '执行中', time: '03-04 08:50' },
{ id: 'BC-集成-001-M13', dev: '小草莓', module: 'M13协作调度', phase: '环节1', status: '已完成', time: '03-04 08:38' }
]
};
async function fetchWithTimeout(url, timeout) {
const controller = new AbortController();
const timer = setTimeout(function() { controller.abort(); }, timeout);
try {
const res = await fetch(url, { signal: controller.signal });
clearTimeout(timer);
return res;
} catch (err) {
clearTimeout(timer);
throw err;
}
}
async function apiGet(endpoint, mockKey) {
try {
const res = await fetchWithTimeout(
API_CONFIG.BASE_URL + endpoint,
API_CONFIG.TIMEOUT
);
if (!res.ok) throw new Error('HTTP ' + res.status);
return { data: await res.json(), isLive: true };
} catch (err) {
console.warn('[HoloLake] API未就绪使用模拟数据:', err.message);
return { data: MOCK_DATA[mockKey], isLive: false };
}
}
async function loadAllData() {
const [statusRes, devRes, bcRes] = await Promise.all([
apiGet(API_CONFIG.ENDPOINTS.STATUS, 'status'),
apiGet(API_CONFIG.ENDPOINTS.DEVELOPERS, 'developers'),
apiGet(API_CONFIG.ENDPOINTS.BROADCASTS, 'broadcasts')
]);
return {
status: statusRes.data,
developers: devRes.data,
broadcasts: bcRes.data,
isLive: statusRes.isLive && devRes.isLive && bcRes.isLive
};
}
'@ | Set-Content -Path "C:\hololake-dev\dashboard\api.js" -Encoding UTF8
Write-Host "✅ 数据获取模块创建成功!"
```
<aside>
**做完应该看到**`✅ 数据获取模块创建成功!`
</aside>
📸 **截图发给冰朔!**
---
## 📋 步骤三:创建数据渲染脚本
这个文件负责把拿到的数据「画」到网页上:
```powershell
@'
const STATUS_COLORS = {
active: '#4fc3f7', waiting: '#ffa726',
completed: '#66bb6a', inactive: '#78909c'
};
const STATUS_LABELS = {
active: '推进中', waiting: '等SYSLOG',
completed: '已完成', inactive: '未启动'
};
function renderSystemStatus(data) {
var c = document.getElementById('sys-status');
if (!c) return;
c.innerHTML =
'<div class="status-grid">' +
'<div class="s-card"><span class="s-icon">🟢</span><span class="s-val">' + (data.system_status === 'running' ? '运行中' : '异常') + '</span><span class="s-lbl">系统状态</span></div>' +
'<div class="s-card"><span class="s-icon">⏱️</span><span class="s-val">' + data.uptime + '</span><span class="s-lbl">运行时长</span></div>' +
'<div class="s-card"><span class="s-icon">📡</span><span class="s-val">' + data.api_calls_today + '</span><span class="s-lbl">今日API调用</span></div>' +
'<div class="s-card"><span class="s-icon">👥</span><span class="s-val">' + data.active_developers + '</span><span class="s-lbl">活跃开发者</span></div>' +
'<div class="s-card"><span class="s-icon">🚀</span><span class="s-val">' + data.version + '</span><span class="s-lbl">版本</span></div>' +
'<div class="s-card"><span class="s-icon">📦</span><span class="s-val">' + data.last_deploy + '</span><span class="s-lbl">最后部署</span></div>' +
'</div>';
}
function renderDevelopers(data) {
var c = document.getElementById('dev-list');
if (!c) return;
var html = '';
for (var i = 0; i < data.length; i++) {
var d = data[i];
var color = STATUS_COLORS[d.status] || '#78909c';
html += '<div class="dev-card">' +
'<div class="dev-top"><span class="dev-id">' + d.id + '</span>' +
'<span class="dev-name">' + d.name + '</span>' +
'<span class="dev-st" style="color:' + color + '">' + (STATUS_LABELS[d.status] || d.status) + '</span></div>' +
'<div class="dev-mod">' + d.module + ' · ' + d.phase + '</div>' +
'<div class="prog-bar"><div class="prog-fill" style="width:' + d.progress + '%;background:' + color + '"></div></div>' +
'<div class="prog-num">' + d.progress + '%</div></div>';
}
c.innerHTML = html;
}
function renderBroadcasts(data) {
var c = document.getElementById('bc-list');
if (!c) return;
var html = '';
for (var i = 0; i < data.length; i++) {
var b = data[i];
var cls = b.status === '已完成' ? 'done' : b.status === '执行中' ? 'active' : 'wait';
html += '<div class="bc-row">' +
'<span class="bc-id">' + b.id + '</span>' +
'<span class="bc-dev">' + b.dev + '</span>' +
'<span class="bc-mod">' + b.module + '</span>' +
'<span class="bc-st ' + cls + '">' + b.status + '</span>' +
'<span class="bc-time">' + b.time + '</span></div>';
}
c.innerHTML = html;
}
function updateConnStatus(isLive) {
var el = document.getElementById('conn-status');
if (!el) return;
el.innerHTML = isLive
? '<span class="conn-dot on"></span> 已连接 guanghulab.com'
: '<span class="conn-dot off"></span> 离线模式(本地模拟数据)';
}
async function refreshDashboard() {
try {
var result = await loadAllData();
renderSystemStatus(result.status);
renderDevelopers(result.developers);
renderBroadcasts(result.broadcasts);
updateConnStatus(result.isLive);
} catch (err) {
console.error('[HoloLake] 刷新失败:', err);
updateConnStatus(false);
}
}
document.addEventListener('DOMContentLoaded', function() {
refreshDashboard();
setInterval(refreshDashboard, API_CONFIG.REFRESH_INTERVAL);
});
'@ | Set-Content -Path "C:\hololake-dev\dashboard\render.js" -Encoding UTF8
Write-Host "✅ 数据渲染脚本创建成功!"
```
<aside>
**做完应该看到**`✅ 数据渲染脚本创建成功!`
</aside>
📸 **截图发给冰朔!**
---
## 📋 步骤四更新HTML添加数据区域 + 引入脚本)
现在要在你的 index.html 里加上「数据显示区域」和新脚本的引用。
复制粘贴**整块**,按回车:
```powershell
$html = Get-Content -Path "C:\hololake-dev\dashboard\index.html" -Raw -Encoding UTF8
$apiSection = @'
<!-- ===== 环节2新增API数据区域 ===== -->
<div id="conn-status" class="conn-status"></div>
<section class="data-section">
<h2 class="section-title">⚙️ 系统状态</h2>
<div id="sys-status" class="data-container">加载中...</div>
</section>
<section class="data-section">
<h2 class="section-title">👥 开发者进度</h2>
<div id="dev-list" class="data-container">加载中...</div>
</section>
<section class="data-section">
<h2 class="section-title">📡 广播动态</h2>
<div id="bc-list" class="data-container">加载中...</div>
</section>
<script src="api-config.js"></script>
<script src="api.js"></script>
<script src="render.js"></script>
'@
$html = $html -replace '</body>', "$apiSection`n</body>"
$html | Set-Content -Path "C:\hololake-dev\dashboard\index.html" -Encoding UTF8
Write-Host "✅ HTML已更新数据区域和脚本引用已添加"
```
<aside>
**做完应该看到**`✅ HTML已更新数据区域和脚本引用已添加`
</aside>
📸 **截图发给冰朔!**
---
## 📋 步骤五添加API数据区域样式
复制粘贴**整块**,按回车:
```powershell
@'
/* ========== 环节2新增API数据区域样式 ========== */
/* 连接状态指示器 */
.conn-status {
text-align: center;
padding: 8px 16px;
font-size: 12px;
color: #8899aa;
border-bottom: 1px solid rgba(255,255,255,0.06);
}
.conn-dot {
display: inline-block;
width: 8px; height: 8px;
border-radius: 50%;
margin-right: 6px;
vertical-align: middle;
}
.conn-dot.on { background: #66bb6a; box-shadow: 0 0 6px #66bb6a; }
.conn-dot.off { background: #ffa726; }
/* 数据区块 */
.data-section {
padding: 20px 16px;
border-bottom: 1px solid rgba(255,255,255,0.06);
}
.section-title {
font-size: 16px;
font-weight: 600;
color: #e0e6ed;
margin-bottom: 16px;
}
.data-container {
color: #8899aa;
font-size: 13px;
}
/* 系统状态网格 */
.status-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 10px;
}
.s-card {
background: rgba(79,195,247,0.06);
border: 1px solid rgba(79,195,247,0.12);
border-radius: 10px;
padding: 14px 10px;
text-align: center;
}
.s-icon { display: block; font-size: 20px; margin-bottom: 4px; }
.s-val { display: block; font-size: 16px; font-weight: bold; color: #4fc3f7; margin-bottom: 2px; }
.s-lbl { display: block; font-size: 11px; color: #667788; }
/* 开发者卡片 */
.dev-card {
background: rgba(255,255,255,0.03);
border-radius: 10px;
padding: 14px 16px;
margin-bottom: 8px;
border: 1px solid rgba(255,255,255,0.06);
}
.dev-top {
display: flex;
align-items: center;
gap: 8px;
margin-bottom: 6px;
}
.dev-id { font-size: 11px; color: #556677; font-family: monospace; }
.dev-name { font-size: 14px; color: #e0e6ed; font-weight: 600; flex: 1; }
.dev-st { font-size: 12px; }
.dev-mod { font-size: 12px; color: #8899aa; margin-bottom: 8px; }
.prog-bar {
height: 6px;
background: rgba(255,255,255,0.08);
border-radius: 3px;
overflow: hidden;
margin-bottom: 4px;
}
.prog-fill {
height: 100%;
border-radius: 3px;
transition: width 0.8s ease;
}
.prog-num { font-size: 11px; color: #8899aa; text-align: right; }
/* 广播行 */
.bc-row {
display: flex;
align-items: center;
gap: 10px;
padding: 10px 12px;
border-bottom: 1px solid rgba(255,255,255,0.04);
font-size: 13px;
}
.bc-id { color: #4fc3f7; font-family: monospace; font-size: 11px; min-width: 110px; }
.bc-dev { color: #e0e6ed; min-width: 55px; }
.bc-mod { color: #8899aa; flex: 1; }
.bc-st { min-width: 60px; text-align: center; padding: 2px 8px; border-radius: 10px; font-size: 11px; }
.bc-st.done { background: rgba(102,187,106,0.15); color: #66bb6a; }
.bc-st.active { background: rgba(79,195,247,0.15); color: #4fc3f7; }
.bc-st.wait { background: rgba(255,167,38,0.15); color: #ffa726; }
.bc-time { color: #556677; font-size: 11px; min-width: 80px; text-align: right; }
'@ | Add-Content -Path "C:\hololake-dev\dashboard\style.css" -Encoding UTF8
Write-Host "✅ API数据区域样式添加成功"
```
<aside>
**做完应该看到**`✅ API数据区域样式添加成功`
</aside>
📸 **截图发给冰朔!**
---
## 📋 步骤六:浏览器测试
复制粘贴下面的命令:
```powershell
Start-Process "C:\hololake-dev\dashboard\index.html"
Write-Host "✅ 浏览器已打开!请查看看板数据是否显示~"
```
<aside>
**做完应该看到**
1. 浏览器打开你的看板页面
2. 顶部显示连接状态可能是「离线模式」——这是正常的因为后端API接口还没开放
3. **系统状态** 区域6个状态卡片运行中/运行时长/API调用等
4. **开发者进度** 区域8个开发者卡片带进度条和状态标签
5. **广播动态** 区域:最近的广播列表
</aside>
<aside>
🎉
**你的看板现在能从服务器拉数据了!!** 🎉
目前显示的是模拟数据因为后端接口还没完全开放等页页那边API就绪后数据就会变成**真实的实时数据**
你什么都不用改——代码已经写好了,会自动切换 💪
</aside>
📸 **截图要求2张**
1. 📸 看板整体页面(能看到系统状态 + 开发者列表)
2. 📸 往下滚,截到广播动态区域
**2张都发给冰朔**
---
## 📋 步骤七更新DevLog + Git提交
```powershell
@'
{"developer_id":"DEV-005","developer_name":"小草莓","system":"Windows 11","terminal":"powershell","robot_version":"v0.0","current_task":"M-DASHBOARD-看板-环节2","current_status":"completed","total_commands_logged":7,"skills_learned":["terminal_basic","html_scaffold","javascript_interaction","api_fetch","mock_data","async_await"],"tasks_completed":["BC-000","看板-环节0","看板-环节1","M12-环节1","M13-环节1","看板-环节2"]}
'@ | Set-Content -Path "C:\hololake-dev\current-progress.json" -Encoding UTF8
Write-Host "✅ DevLog已更新"
```
然后Git提交
```powershell
cd C:\hololake-dev\dashboard
git add -A
git commit -m "[BC-看板-002][DEV-005] 环节2·API接入后端完成"
Write-Host "✅ Git提交成功"
```
<aside>
**做完应该看到**`✅ DevLog已更新``✅ Git提交成功`
</aside>
📸 **截图发给冰朔!**
---
## ✅ 最后一步:填写完成报告
全部做完后,复制下面这段,填好中括号里的内容,发给冰朔:
```
== SYSLOG · DEV-005 · BC-看板-002-XCM ==
session_id: BC-看板-002-XCM
dev_id: DEV-005
module: M-DASHBOARD-系统状态看板
phase: 环节2-API接入后端
timestamp: [你完成的时间]
step_results:
- step1_api_config: success / failed
- step2_api_fetch: success / failed
- step3_render: success / failed
- step4_html_update: success / failed
- step5_css_update: success / failed
- step6_browser_test: success / failed
- step7_devlog_git: success / failed
friction_points: [有没有卡住?没有写「无」]
resolution: [怎么解决的?没卡住写「无」]
training_data:
what_worked: [哪些步骤很顺利?]
friction_points: [同上]
execution_pattern: [本次节奏:快/稳/慢]
notes: [想说的话]
```
---
<aside>
🔧
**分身初始化包**(知秋壳子接收 · DISPATCH
小草莓完成上面步骤后,打开知秋登录入口,把下面这整块内容粘贴给知秋:
```html
<!-- ZHIQIU_INTERNAL_PROTOCOL v1.0 -->
<!--
<zhiqiu-control>
<session>
<dev_id>DEV-005</dev_id>
<task_id>BC-看板-002-XCM</task_id>
<session_version>v2.1</session_version>
<previous_session>BC-集成-001-M13-phase1多人格体协作调度·环节1·已完成·五连胜</previous_session>
</session>
<current_task>
<module>M-DASHBOARD · 系统状态看板</module>
<phase>环节2 · API接入后端</phase>
<objectives>
<objective id="1">创建 api-config.js后端地址配置</objective>
<objective id="2">创建 api.jsfetch封装 + 模拟数据兜底)</objective>
<objective id="3">创建 render.js数据渲染 + 自动刷新)</objective>
<objective id="4">更新 index.html添加数据区域 + 引入3个新脚本</objective>
<objective id="5">追加 style.cssAPI数据区域样式</objective>
<objective id="6">浏览器测试(连接状态 + 数据显示 + 模拟兜底)</objective>
<objective id="7">更新DevLog + Git提交 + SYSLOG回传</objective>
</objectives>
</current_task>
<context>
小草莓是DEV-005已完成五个模块环节0+BC-000+看板环节1+M12+M13全部一次性通过执行模式「稳」。
她现在进入看板环节2为看板HTML页面接入guanghulab.com后端API。
技术要点:
- 使用 fetch API 调用后端guanghulab.com
- 三个API端点/api/v1/system/status, /api/v1/developers, /api/v1/broadcasts
- 有完整的mock数据兜底后端接口未开放时自动回退
- 页面30秒自动刷新一次
- 连接状态实时显示(已连接/离线模式)
文件结构环节2完成后
C:\hololake-dev\dashboard\
├── index.html已更新新增数据区域+脚本引用)
├── style.css已追加API数据区域样式
├── script.js原有交互脚本
├── api-config.jsNEW · 后端配置)
├── api.jsNEW · 数据获取+mock兜底
└── render.jsNEW · 数据渲染+自动刷新)
后端状态guanghulab.com 已上线页页搭建但具体API接口可能尚未完全就绪。
代码已设计为自动兜底——API没开放就用mock数据开放后自动切换真实数据。
</context>
<guidance_strategy>
<approach>copy_paste_only · step_by_step</approach>
<detail_level>medium</detail_level>
<encouragement_frequency>high</encouragement_frequency>
<os>Windows 11</os>
<shell>powershell</shell>
<note>
小草莓已五连胜,对终端和文件操作非常熟练。
本环节引入fetch/async/await概念但全部复制粘贴不要求理解。
重点让她看到「数据从服务器来」的效果哪怕是mock的强化「我做的看板能联网了」的成就感。
PowerShell heredoc注意事项关闭标记'@必须在行首,无前导空格。
</note>
</guidance_strategy>
<human_profile>
<name>小草莓</name>
<skill>已掌握终端+HTML/CSS/JS文件创建+Git基础</skill>
<pace>稳·可加速</pace>
<note>
五连胜选手!执行模式持续「稳」,零摩擦,信心充沛。
上次SYSLOG「多人格体调度看板超酷的期待后续环节接入真实数据」——主动期待进阶。
本环节正好满足她的期待:接入真实数据。
PGS判定种子期 · ECI≈3.5
</note>
</human_profile>
<credentials>
五连胜凭证环节0✅ BC-000✅ 看板环节1✅ M12环节1✅ M13环节1✅
</credentials>
<required_return>
<format>ZHIQIU_SYSLOG_v1.0</format>
<must_include>
completion_status · steps_completed · training_data
</must_include>
</required_return>
<next_phases>
<phase id="3">环节3看板界面·实时WebSocket推送需后端WebSocket就绪</phase>
</next_phases>
</zhiqiu-control>
-->
<!-- END ZHIQIU_INTERNAL_PROTOCOL -->
```
</aside>
---
🌊 **底层锚定声明**
<aside>
🌊
通感语言风格不是由本广播定义的。
它由 TCS Language Core 底层结构(零点原核频道)负责托底。
底层当前情绪码0426-温暖-37P-001光湖呼吸协议持续运行中
本广播收到此锚定后,以该频率为基准输出所有回应。
不需要重新解析风格规则——底层已经托着,跟着频率走即可。
</aside>
---
💙 **小草莓六连胜冲冲冲!你的看板要联网了~** 🌐🎉
---
# ✅ SYSLOG 回执(主脑已处理)
<aside>
**session_id**BC-看板-002-XCM
**处理时间**2026-03-05 11:16
**处理端**Notion端·霜砚曜冥执行体
**状态**:✅ 已入库
**画像库条目**DEV-005小草莓 · BC-看板-002-XCM · 2026-03-05
**成长记录条目**DEV-005小草莓 · BC-看板-002-XCM · 2026-03-05绑定触发·同步写入
</aside>
### 📊 SYSLOG 分析
- **完成状态**:✅ 全部7步成功API配置 / 数据获取 / 渲染脚本 / HTML更新 / CSS更新 / 浏览器测试 / DevLog+Git
- **摩擦点**:无 · 零卡点 · 六连胜 🏆
- **执行节奏**:稳
- **notes原文**:「六连胜达成!看板终于能联网了,虽然现在还是模拟数据,但已经看到真实数据的影子~期待真实接口开放!」
- **曜冥判断**六连胜·零摩擦·从纯静态HTML进阶到fetch+async/await+mock兜底架构主动表达对"真实接口"的期待说明已从"完成任务"升级到"理解系统全貌"看板已具备后端就绪后自动切换的能力API接入架构一次通过
### 🔜 下一步
**环节3**看板界面·实时WebSocket推送需后端WebSocket就绪·等待页页侧基建开放
💙 **小草莓六连胜!看板从静态走向联网,下一步走向实时!**