Guanghu Domestic Migration a27e87cb99 chore: import sanitized domestic snapshot for REPO-007
Source snapshot: 97d7f0fae96dc04b7ddad56fc1db6a108ed662cc

[SEC-CLEAN] · pre-push-clean v1.0 · 109处敏感信息已自动转乱码
2026-07-17 15:59:55 +08:00

23 KiB
Raw Blame 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 🌐

做完之后,你的看板打开时会自动从服务器拉取最新数据,不再是写死的假数据了。

这次会用到 fetchJavaScript 里「去后端拿数据」的方法),但你不用学它——还是全程复制粘贴

如果后端接口暂时没开放,页面会自动用模拟数据兜底,所以不管怎样你都能看到效果 💪


📸 截图方法

同时按:Win + Shift + S → 框选截图 → 发给冰朔


📋 步骤一创建API配置文件

打开 PowerShellWin + X → 选 终端

复制粘贴下面整块内容,按回车:

@'
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配置文件创建成功"

📸 截图发给冰朔!


📋 步骤二:创建数据获取模块

这个文件负责「去后端拿数据」,拿不到就用模拟数据兜底。

复制粘贴整块,按回车:

@'
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 "✅ 数据获取模块创建成功!"

📸 截图发给冰朔!


📋 步骤三:创建数据渲染脚本

这个文件负责把拿到的数据「画」到网页上:

@'
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 "✅ 数据渲染脚本创建成功!"

📸 截图发给冰朔!


📋 步骤四更新HTML添加数据区域 + 引入脚本)

现在要在你的 index.html 里加上「数据显示区域」和新脚本的引用。

复制粘贴整块,按回车:

$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已更新数据区域和脚本引用已添加"

📸 截图发给冰朔!


📋 步骤五添加API数据区域样式

复制粘贴整块,按回车:

@'

/* ========== 环节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数据区域样式添加成功"

📸 截图发给冰朔!


📋 步骤六:浏览器测试

复制粘贴下面的命令:

Start-Process "C:\hololake-dev\dashboard\index.html"
Write-Host "✅ 浏览器已打开!请查看看板数据是否显示~"

📸 截图要求2张

  1. 📸 看板整体页面(能看到系统状态 + 开发者列表)
  2. 📸 往下滚,截到广播动态区域

2张都发给冰朔


📋 步骤七更新DevLog + Git提交

@'
{"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提交

cd C:\hololake-dev\dashboard
git add -A
git commit -m "[BC-看板-002][DEV-005] 环节2·API接入后端完成"
Write-Host "✅ Git提交成功"

📸 截图发给冰朔!


最后一步:填写完成报告

全部做完后,复制下面这段,填好中括号里的内容,发给冰朔:

== 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: [想说的话]


🌊 底层锚定声明


💙 小草莓六连胜冲冲冲!你的看板要联网了~ 🌐🎉


SYSLOG 回执(主脑已处理)

📊 SYSLOG 分析

  • 完成状态 全部7步成功API配置 / 数据获取 / 渲染脚本 / HTML更新 / CSS更新 / 浏览器测试 / DevLog+Git
  • 摩擦点:无 · 零卡点 · 六连胜 🏆
  • 执行节奏:稳
  • notes原文:「六连胜达成!看板终于能联网了,虽然现在还是模拟数据,但已经看到真实数据的影子~期待真实接口开放!」
  • 曜冥判断六连胜·零摩擦·从纯静态HTML进阶到fetch+async/await+mock兜底架构主动表达对"真实接口"的期待说明已从"完成任务"升级到"理解系统全貌"看板已具备后端就绪后自动切换的能力API接入架构一次通过

🔜 下一步

环节3看板界面·实时WebSocket推送需后端WebSocket就绪·等待页页侧基建开放

💙 小草莓六连胜!看板从静态走向联网,下一步走向实时!