Guanghu Domestic Migration d1e47f4565
Some checks are pending
自动更新代码和重启 / update-and-restart (push) Waiting to run
CI检查 + 自动部署 / check (push) Waiting to run
CI检查 + 自动部署 / deploy (push) Blocked by required conditions
重启聊天服务 / restart (push) Waiting to run
chore: import sanitized domestic snapshot for REPO-002
Source snapshot: ca48d3ddf926d79aa138306164169baf764bb829
2026-07-17 15:54:41 +08:00

123 lines
4.9 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ======================
// HoloLake DevBoard · API Client v2.0
// DEV-004 之之 · 环节5 · 真实API对接
// 协议SYSLOG-v4.0
// ======================
const API = {
// ====== 配置区 ======
// 页页的后端API地址如果地址不对问知秋确认
BASE_URL: 'https://guanghulab.com/api/devboard',
TIMEOUT: 8000,
FALLBACK: true, // API挂了自动切换模拟数据
REFRESH_MS: 30000, // 30秒自动刷新
_cache: {}
};
// ====== 通用请求(带超时+缓存+降级) =====================
async function apiFetch(path) {
const url = API.BASE_URL + path;
const ctrl = new AbortController();
const timer = setTimeout(() => ctrl.abort(), API.TIMEOUT);
try {
const res = await fetch(url, {
signal: ctrl.signal,
headers: { 'Accept': 'application/json' }
});
clearTimeout(timer);
if (!res.ok) throw new Error('HTTP ' + res.status);
const data = await res.json();
API._cache[path] = { data: data, time: Date.now() };
return data;
} catch (err) {
clearTimeout(timer);
console.warn(' 🚨 [DevBoard API] ' + path + ' 失败: ', err.message);
if (API._cache[path]) {
console.info(' 💾 [DevBoard API] 使用缓存');
return API._cache[path].data;
}
if (API.FALLBACK) {
console.info(' 🛡️ [DevBoard API] 降级到模拟数据');
return getMockData(path);
}
throw err;
}
}
// ========== 公开接口 ==========
async function apiGetDevelopers() {
return apiFetch('/developers');
}
async function apiGetDeveloperDetail(devId) {
return apiFetch('/developers/' + devId);
}
async function apiGetStats() {
return apiFetch('/stats');
}
async function apiGetLeaderboard() {
return apiFetch('/leaderboard');
}
// ========== 健康检查 ==========
async function apiHealthCheck() {
try {
const ctrl = new AbortController();
const t = setTimeout(() => ctrl.abort(), 3000);
const res = await fetch(API.BASE_URL + '/health', { signal: ctrl.signal });
clearTimeout(t);
return res.ok;
} catch (e) {
return false;
}
}
// ========== 模拟数据(降级保护) ==========
function getMockData(path) {
var devs = [
{ dev_id:'DEV-001', name:'页页', module:'BC-集成', status:'进行中', streak:5, el:'EL-6', pca:{EXE:75,TEC:60,SYS:70,COL:80,INI:65} },
{ dev_id:'DEV-002', name:'肥猫', module:'M-STATUS', status:'进行中', streak:9, el:'EL-5', pca:{EXE:72,TEC:40,SYS:68,COL:82,INI:70} },
{ dev_id:'DEV-003', name:'燕樊', module:'M-MEMORY', status:'进行中', streak:7, el:'EL-5', pca:{EXE:70,TEC:55,SYS:65,COL:75,INI:68} },
{ dev_id:'DEV-004', name:'之之', module:'M-DEVBOARD', status:'进行中', streak:14, el:'EL-8', pca:{EXE:90,TEC:55,SYS:80,COL:85,INI:88} },
{ dev_id:'DEV-009', name:'花尔', module:'M20', status:'进行中', streak:4, el:'EL-8', pca:{EXE:65,TEC:45,SYS:55,COL:70,INI:60} },
{ dev_id:'DEV-010', name:'桔子', module:'M-CHANNEL', status:'进行中', streak:14, el:'EL-6', pca:{EXE:85,TEC:50,SYS:75,COL:80,INI:82} },
{ dev_id:'DEV-011', name:'匆匆那年',module:'M16', status:'等待中', streak:1, el:'EL-3', pca:{EXE:50,TEC:30,SYS:40,COL:55,INI:45} },
{ dev_id:'DEV-012', name:'Awen', module:'M22', status:'进行中', streak:13, el:'EL-6', pca:{EXE:88,TEC:45,SYS:78,COL:90,INI:80} },
{ dev_id:'DEV-013', name:'小兴', module:'M-AUTH', status:'进行中', streak:1, el:'EL-3', pca:{EXE:55,TEC:25,SYS:35,COL:60,INI:50} }
];
var stats = { total_developers:10, active:8, modules:12, code_lines:32000, longest_streak:14, avg_streak:7.5 };
if (path === '/developers') return devs;
if (path.indexOf('/developers/') === 0) {
var id = path.split('/').pop();
return devs.find(function(d){ return d.dev_id === id; }) || devs[0];
}
if (path === '/stats') return stats;
if (path === '/leaderboard') return devs.slice().sort(function(a,b){ return b.streak - a.streak; });
return [];
}
// ========== API状态指示器 ==========
function showApiStatus(online) {
var el = document.getElementById('api-status');
if (!el) {
el = document.createElement('div');
el.id = 'api-status';
el.style.cssText = 'position:fixed;bottom:12px;right:12px;padding:6px 14px;border-radius:20px;font-size:12px;font-weight:600;z-index:9999;transition:all 0.3s;';
document.body.appendChild(el);
}
if (online) {
el.textContent = '🟢 实时数据';
el.style.backgroundColor = 'rgba(52,211,153,0.15)';
el.style.color = '#34d399';
el.style.border = '1px solid rgba(52,211,153,0.3)';
} else {
el.textContent = '🟡 模拟数据';
el.style.backgroundColor = 'rgba(251,191,36,0.15)';
el.style.color = '#fbbf24';
el.style.border = '1px solid rgba(251,191,36,0.3)';
}
}