Commit 9bcf0ea6 authored by 单鹏辉's avatar 单鹏辉

feat: 添加所有清单总览看板

parent 940e46c1
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>BOS 闂娓呭崟鎬昏</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #f5f7fa; color: #333; }
.header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px 40px; }
.header h1 { font-size: 28px; margin-bottom: 8px; }
.header p { opacity: 0.9; font-size: 14px; }
.stats { display: flex; gap: 20px; margin-top: 20px; }
.stat-card { background: rgba(255,255,255,0.2); border-radius: 10px; padding: 15px 25px; }
.stat-card .number { font-size: 32px; font-weight: bold; }
.stat-card .label { font-size: 12px; opacity: 0.9; }
.container { max-width: 1400px; margin: 30px auto; padding: 0 20px; }
.search-bar { margin-bottom: 20px; }
.search-bar input { width: 100%; padding: 12px 20px; border: 2px solid #e1e5ee; border-radius: 10px; font-size: 16px; outline: none; transition: border-color 0.3s; }
.search-bar input:focus { border-color: #667eea; }
.grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 16px; }
.card { background: white; border-radius: 12px; padding: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.06); transition: all 0.3s; cursor: pointer; text-decoration: none; color: inherit; display: block; }
.card:hover { transform: translateY(-2px); box-shadow: 0 8px 24px rgba(0,0,0,0.12); }
.card-header { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 12px; }
.card-title { font-size: 16px; font-weight: 600; color: #1a1a2e; }
.card-badge { font-size: 11px; padding: 4px 10px; border-radius: 20px; font-weight: 500; }
.badge-empty { background: #f0f0f0; color: #888; }
.badge-active { background: #e8f5e9; color: #2e7d32; }
.card-meta { font-size: 12px; color: #888; margin-bottom: 8px; }
.card-path { font-size: 11px; color: #aaa; font-family: monospace; word-break: break-all; }
.footer { text-align: center; padding: 30px; color: #aaa; font-size: 12px; }
</style>
</head>
<body>
<div class="header">
<h1>BOS 闂娓呭崟鎬昏</h1>
<p>bos-project-kb 缁勭粐 路 鎵€鏈夊鎴烽棶棰樻竻鍗?/p>
<div class="stats">
<div class="stat-card">
<div class="number">50</div>
<div class="label">娓呭崟鎬绘暟</div>
</div>
<div class="stat-card">
<div class="number" id="totalIssues">0</div>
<div class="label">闂鎬绘暟</div>
</div>
<div class="stat-card">
<div class="number" id="emptyCount">0</div>
<div class="label">绌烘竻鍗?/div>
</div>
</div>
</div>
<div class="container">
<div class="search-bar">
<input type="text" id="searchInput" placeholder="鎼滅储娓呭崟鍚嶇О..." oninput="filterCards()">
</div>
<div class="grid" id="ledgerGrid"></div>
</div>
<div class="footer">Generated: 2026-07-17 18:40 路 Powered by BOS Issue Ledger</div>
<script>
const ledgers = [
{listId:'aerxi-ops-26', repo:'aerxi-project-kb', issues:0, kanban:'运维项目/aerxi-project-kb/aerxi-ops-26/aerxi-ops-26_看板.html'},
{listId:'CBF-ops-26', repo:'CBF', issues:0, kanban:'运维项目/CBF/CBF-ops-26/CBF-ops-26_看板.html'},
{listId:'changji-ops-26', repo:'changji-project-kb', issues:0, kanban:'运维项目/changji-project-kb/changji-ops-26/changji-ops-26_看板.html'},
{listId:'dadi-ops-26', repo:'dadi-project-kb', issues:0, kanban:'运维项目/dadi-project-kb/dadi-ops-26/dadi-ops-26_看板.html'},
{listId:'daming-ops-26', repo:'daming-project-kb', issues:0, kanban:'运维项目/daming-project-kb/daming-ops-26/daming-ops-26_看板.html'},
{listId:'dashang-ops-26', repo:'dashang-project-kb', issues:0, kanban:'运维项目/dashang-project-kb/dashang-ops-26/dashang-ops-26_看板.html'},
{listId:'dawang-ops-26', repo:'dawang-project-kb', issues:0, kanban:'运维项目/dawang-project-kb/dawang-ops-26/dawang-ops-26_看板.html'},
{listId:'dema-ops-26', repo:'dema-project-kb', issues:0, kanban:'运维项目/dema-project-kb/dema-ops-26/dema-ops-26_看板.html'},
{listId:'EP-ops-26', repo:'EP', issues:0, kanban:'运维项目/EP/EP-ops-26/EP-ops-26_看板.html'},
{listId:'fenglong-ops-26', repo:'fenglong-project-kb', issues:0, kanban:'运维项目/fenglong-project-kb/fenglong-ops-26/fenglong-ops-26_看板.html'},
{listId:'fukang-ops-26', repo:'fukang-project-kb', issues:0, kanban:'运维项目/fukang-project-kb/fukang-ops-26/fukang-ops-26_看板.html'},
{listId:'gebijia-ops-26', repo:'gebijia-project-kb', issues:0, kanban:'运维项目/gebijia-project-kb/gebijia-ops-26/gebijia-ops-26_看板.html'},
{listId:'GEO-ops-26', repo:'GEO-project-kb', issues:0, kanban:'运维项目/GEO-project-kb/GEO-ops-26/GEO-ops-26_看板.html'},
{listId:'guanglian-ops-26', repo:'guanglian', issues:0, kanban:'运维项目/guanglian/guanglian-ops-26/guanglian-ops-26_看板.html'},
{listId:'guohua-ops-26', repo:'guohua-project-kb', issues:0, kanban:'运维项目/guohua-project-kb/guohua-ops-26/guohua-ops-26_看板.html'},
{listId:'hengtian-ops-26', repo:'hengtian-project-kb', issues:0, kanban:'运维项目/hengtian-project-kb/hengtian-ops-26/hengtian-ops-26_看板.html'},
{listId:'hongxing-ops-26', repo:'hongxing-project-kb', issues:0, kanban:'运维项目/hongxing-project-kb/hongxing-ops-26/hongxing-ops-26_看板.html'},
{listId:'huaxintong-ops-26', repo:'huaxintong-project-kb', issues:0, kanban:'运维项目/huaxintong-project-kb/huaxintong-ops-26/huaxintong-ops-26_看板.html'},
{listId:'huide-ops-26', repo:'huide-project-kb', issues:0, kanban:'运维项目/huide-project-kb/huide-ops-26/huide-ops-26_看板.html'},
{listId:'jinghongsheng-ops-26', repo:'jinghongsheng-project-kb', issues:0, kanban:'运维项目/jinghongsheng-project-kb/jinghongsheng-ops-26/jinghongsheng-ops-26_看板.html'},
{listId:'jinhua-ops-26', repo:'jinhua-project-kb', issues:0, kanban:'运维项目/jinhua-project-kb/jinhua-ops-26/jinhua-ops-26_看板.html'},
{listId:'kangnuo-ops-26', repo:'kangnuo-project-kb', issues:0, kanban:'运维项目/kangnuo-project-kb/kangnuo-ops-26/kangnuo-ops-26_看板.html'},
{listId:'latticework-ops-26', repo:'latticework-project-kb', issues:0, kanban:'运维项目/latticework-project-kb/latticework-ops-26/latticework-ops-26_看板.html'},
{listId:'lianchuangjie-ops-26', repo:'lianchuangjie', issues:0, kanban:'运维项目/lianchuangjie/lianchuangjie-ops-26/lianchuangjie-ops-26_看板.html'},
{listId:'longteng-ops-26', repo:'longteng-project-kb', issues:0, kanban:'运维项目/longteng-project-kb/longteng-ops-26/longteng-ops-26_看板.html'},
{listId:'mairui-ops-26', repo:'mairui-project-kb', issues:0, kanban:'运维项目/mairui-project-kb/mairui-ops-26/mairui-ops-26_看板.html'},
{listId:'majesty-ops-26', repo:'Majesty-project-kb', issues:0, kanban:'运维项目/Majesty-project-kb/majesty-ops-26/majesty-ops-26_看板.html'},
{listId:'meisheng-ops-26', repo:'meisheng-project-kb', issues:0, kanban:'运维项目/meisheng-project-kb/meisheng-ops-26/meisheng-ops-26_看板.html'},
{listId:'nuoweiqi-ops-26', repo:'nuoweiqi-project-kb', issues:0, kanban:'运维项目/nuoweiqi-project-kb/nuoweiqi-ops-26/nuoweiqi-ops-26_看板.html'},
{listId:'pulasike-ops-26', repo:'pulasike-project-kb', issues:0, kanban:'运维项目/pulasike-project-kb/pulasike-ops-26/pulasike-ops-26_看板.html'},
{listId:'rongda-ops-26', repo:'rongda-project-kb', issues:0, kanban:'运维项目/rongda-project-kb/rongda-ops-26/rongda-ops-26_看板.html'},
{listId:'sanpangdan-ops-26', repo:'sanpangdan-project-kb', issues:0, kanban:'运维项目/sanpangdan-project-kb/sanpangdan-ops-26/sanpangdan-ops-26_看板.html'},
{listId:'SCB-ops-26', repo:'SCB-project-kb', issues:0, kanban:'运维项目/SCB-project-kb/SCB-ops-26/SCB-ops-26_看板.html'},
{listId:'shijierqian-ops-26', repo:'shijierqian-project-kb', issues:0, kanban:'运维项目/shijierqian-project-kb/shijierqian-ops-26/shijierqian-ops-26_看板.html'},
{listId:'start-ops-26', repo:'start-project-kb', issues:0, kanban:'运维项目/start-project-kb/start-ops-26/start-ops-26_看板.html'},
{listId:'taikang-ops-26', repo:'taikang-project-kb', issues:0, kanban:'运维项目/taikang-project-kb/taikang-ops-26/taikang-ops-26_看板.html'},
{listId:'tianxing-ops-26', repo:'tianxing-project-kb', issues:0, kanban:'运维项目/tianxing-project-kb/tianxing-ops-26/tianxing-ops-26_看板.html'},
{listId:'tongcheng-ops-26', repo:'tongcheng-project-kb', issues:0, kanban:'运维项目/tongcheng-project-kb/tongcheng-ops-26/tongcheng-ops-26_看板.html'},
{listId:'tuochen-ops-26', repo:'tuochen-project-KB', issues:0, kanban:'运维项目/tuochen-project-KB/tuochen-ops-26/tuochen-ops-26_看板.html'},
{listId:'wanhong-ops-26', repo:'wanhong-project-kb', issues:0, kanban:'运维项目/wanhong-project-kb/wanhong-ops-26/wanhong-ops-26_看板.html'},
{listId:'wanrun-ops-26', repo:'wanrun-project-kb', issues:0, kanban:'运维项目/wanrun-project-kb/wanrun-ops-26/wanrun-ops-26_看板.html'},
{listId:'yanlong-ops-26', repo:'yanlong-project-kb', issues:0, kanban:'运维项目/yanlong-project-kb/yanlong-ops-26/yanlong-ops-26_看板.html'},
{listId:'yidianyuan-ops-26', repo:'yidianyuan-project-kb', issues:0, kanban:'运维项目/yidianyuan-project-kb/yidianyuan-ops-26/yidianyuan-ops-26_看板.html'},
{listId:'zhixing-ops-26', repo:'zhixing', issues:0, kanban:'运维项目/zhixing/zhixing-ops-26/zhixing-ops-26_看板.html'},
{listId:'zhongdi-ops-26', repo:'zhongdi-project-kb', issues:0, kanban:'运维项目/zhongdi-project-kb/zhongdi-ops-26/zhongdi-ops-26_看板.html'},
{listId:'zhonghailiqing-ops-26', repo:'zhonghailiqing-project-kb', issues:0, kanban:'运维项目/zhonghailiqing-project-kb/zhonghailiqing-ops-26/zhonghailiqing-ops-26_看板.html'},
{listId:'zhongyou-ops-26', repo:'zhongyou-project-kb', issues:0, kanban:'运维项目/zhongyou-project-kb/zhongyou-ops-26/zhongyou-ops-26_看板.html'},
{listId:'zongxun-ops-26', repo:'zongxun-project-kb', issues:0, kanban:'运维项目/zongxun-project-kb/zongxun-ops-26/zongxun-ops-26_看板.html'}
];
const grid = document.getElementById('ledgerGrid');
let totalIssues = 0;
let emptyCount = 0;
ledgers.forEach(l => {
const card = document.createElement('a');
card.className = 'card';
card.href = l.kanban;
card.dataset.name = l.name.toLowerCase();
card.dataset.repo = l.repo.toLowerCase();
const issueCount = l.issues || 0;
totalIssues += issueCount;
if (issueCount === 0) emptyCount++;
const badge = issueCount > 0 ? 'badge-active' : 'badge-empty';
const badgeText = issueCount > 0 ? issueCount + ' 涓棶棰? : '绌烘竻鍗?;
card.innerHTML = `
<div class="card-header">
<div class="card-title">${l.listId}</div>
<span class="card-badge ${badge}">${badgeText}</span>
</div>
<div class="card-meta">${l.repo}</div>
<div class="card-path">杩愮淮椤圭洰/${l.repo}/</div>
`;
grid.appendChild(card);
});
document.getElementById('totalIssues').textContent = totalIssues;
document.getElementById('emptyCount').textContent = emptyCount;
function filterCards() {
const q = document.getElementById('searchInput').value.toLowerCase();
document.querySelectorAll('.card').forEach(c => {
const match = c.dataset.name.includes(q) || c.dataset.repo.includes(q);
c.style.display = match ? '' : 'none';
});
}
</script>
</body>
</html>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment