资源状态条使用指南¶
快速开始¶
资源状态条是 AI 资源详情页的紧凑评分展示组件,用于快速传达项目健康状态。
在模板中使用¶
HTML 模板¶
<!-- 在侧边栏资源信息卡片中添加 -->
<div class="ai-info-card">
<h5><i class="fas fa-info-circle"></i> 资源信息</h5>
<div class="info-list">
<!-- 其他信息项 -->
<!-- 资源状态条 -->
<div class="info-item info-item-health">
<div class="resource-status"
data-ai-resource-status
data-ai-repo="{{ $repoSlug }}">
</div>
</div>
</div>
</div>
必需属性¶
data-ai-resource-status: 标记容器为资源状态条data-ai-repo: GitHub 仓库 slug(格式:owner/repo)
样式定制¶
基础样式结构¶
.resource-status {
// 容器样式
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0.75rem 0;
// 综合状态行
&__overall {
font-size: 0.9375rem;
font-weight: 600;
}
// 子评分行
&__scores {
font-size: 0.8125rem;
white-space: nowrap;
}
// 更新时间行
&__update {
font-size: 0.75rem;
}
}
状态标签颜色¶
状态标签会根据评分自动应用颜色:
| 状态 | 类名 | 颜色 |
|---|---|---|
| 优秀 | .status-label--excellent | 绿色系 |
| 良好 | .status-label--good | 蓝色系 |
| 一般 | .status-label--fair | 黄色系 |
| 风险 | .status-label--poor | 红色系 |
自定义颜色¶
.status-label--excellent {
background: rgba(34, 197, 94, 0.12);
color: #15803d;
.dark-mode & {
background: rgba(34, 197, 94, 0.18);
color: #86efac;
}
}
JavaScript API¶
手动渲染¶
// 获取容器
const container = document.querySelector('[data-ai-resource-status]');
// 准备数据
const data = {
scores: {
health: 73,
activity: 91,
community: 58,
quality: 71,
sustainability: 69
},
metrics: {
daysSinceLastCommit: 2,
lastCommitAt: "2025-12-13T10:00:00Z"
}
};
// 渲染状态条
renderResourceStatus(container, data);
自定义状态映射¶
如果需要修改状态映射规则:
// 修改 HEALTH_LEVELS 对象
const HEALTH_LEVELS = {
excellent: { min: 85, label: { zh: '卓越', en: 'Excellent' }, class: 'excellent' },
good: { min: 65, label: { zh: '良好', en: 'Good' }, class: 'good' },
fair: { min: 45, label: { zh: '一般', en: 'Fair' }, class: 'fair' },
poor: { min: 0, label: { zh: '较差', en: 'Poor' }, class: 'poor' }
};
国际化支持¶
添加新语言¶
-
扩展状态标签:
const HEALTH_LEVELS = { excellent: { min: 80, label: { zh: '优秀', en: 'Excellent', ja: '優秀' }, class: 'excellent' }, // ...其他级别 }; -
更新渲染函数:
function renderResourceStatus(container, data) { const lang = getCurrentLanguage(); // 获取当前语言 // 使用 lang 变量选择对应文本 const overallLabel = lang === 'zh' ? '综合状态' : lang === 'ja' ? '総合状態' : 'Overall Status'; // ... 其他文本处理 }
响应式行为¶
默认断点¶
// 移动端:隐藏更新时间
@media (max-width: 768px) {
.resource-status__update {
display: none;
}
}
// 小屏幕:隐藏子评分
@media (max-width: 380px) {
.resource-status__scores {
display: none;
}
}
自定义断点¶
// 在项目样式文件中覆盖
.resource-status__scores {
@media (max-width: 480px) {
font-size: 0.75rem; // 缩小字号而不是隐藏
}
}
常见问题¶
Q: 如何修改状态条高度?¶
A: 调整容器的 padding 和 gap:
.resource-status {
padding: 0.5rem 0; // 减小内边距
gap: 0.375rem; // 减小行间距
}
Q: 能否在列表页使用?¶
A: 可以,但建议使用原有的 data-ai-health-bars 或 data-ai-health-summary,因为列表页需要更紧凑的展示。资源状态条设计用于详情页。
Q: 如何处理数据加载失败?¶
A: JavaScript 会自动显示错误提示:
<div class="health-error-small">Data unavailable</div>
你可以自定义错误样式:
.health-error-small {
color: #dc2626;
font-size: 0.875rem;
padding: 0.5rem 0;
}
Q: 评分数据从哪里来?¶
A: 数据由 Cloudflare Worker 提供,缓存 30 分钟:
- API:
https://ai-oss-rank-worker.jimmysong.io - 缓存键:
ai-health-{repo-slug}-{locale} - 缓存时长: 1800 秒
如需手动刷新缓存:
localStorage.removeItem('ai-health-owner/repo-zh');
location.reload();
Q: 如何添加新的子评分项?¶
A: 修改 renderResourceStatus 函数:
const html = `
<div class="resource-status__scores">
<!-- 原有子评分 -->
<span class="score-item">
<span class="score-name">${lang === 'zh' ? '活跃度' : 'Activity'}</span>
<span class="score-value">${activityScore}</span>
</span>
<!-- 新增子评分 -->
<span>·</span>
<span class="score-item">
<span class="score-name">${lang === 'zh' ? '新指标' : 'New Metric'}</span>
<span class="score-value">${newMetricScore}</span>
</span>
</div>
`;
最佳实践¶
✅ 推荐做法¶
- 保持三行结构: 不要添加额外行,保持紧凑性
- 固定子评分顺序: 便于用户形成记忆
- 使用相对时间: 比"2025-12-13"更友好
- 提供 Tooltip: 帮助用户理解评分含义
- 测试深色模式: 确保颜色在两种模式下都清晰
❌ 避免做法¶
- 不要添加图标: 除 info 图标外,避免视觉噪音
- 不要使用大号字体: 破坏紧凑性
- 不要纵向排列子评分: 增加高度
- 不要添加动画: 影响性能和可读性
- 不要修改评分算法: 保持与后端一致
性能优化¶
减少重绘¶
// ❌ 避免:逐个设置内容
container.querySelector('.score-value').textContent = score;
container.querySelector('.status-label').textContent = label;
// ✅ 推荐:一次性设置 innerHTML
container.innerHTML = generateHTML(data);
使用缓存¶
// 检查缓存
const cacheKey = `ai-health-${repoSlug}-${locale}`;
const cached = getCachedData(cacheKey);
if (cached && Date.now() - cached.timestamp < CACHE_DURATION) {
renderResourceStatus(container, cached.data);
return;
}
// 获取新数据并缓存
const data = await fetchHealthData(repoSlug, locale);
setCachedData(cacheKey, data);
调试技巧¶
查看渲染数据¶
// 在浏览器控制台执行
const container = document.querySelector('[data-ai-resource-status]');
const repo = container.dataset.aiRepo;
const cacheKey = `ai-health-${repo}-zh`;
const cached = localStorage.getItem(cacheKey);
console.log(JSON.parse(cached));
强制刷新数据¶
// 清除特定项目缓存
localStorage.removeItem('ai-health-kubernetes/kubernetes-zh');
// 清除所有健康数据缓存
Object.keys(localStorage)
.filter(key => key.startsWith('ai-health-'))
.forEach(key => localStorage.removeItem(key));
模拟不同评分¶
// 临时修改数据进行测试
const testData = {
scores: {
health: 45, // 测试"一般"状态
activity: 60,
community: 40,
quality: 50,
sustainability: 45
},
metrics: {
daysSinceLastCommit: 90
}
};
const container = document.querySelector('[data-ai-resource-status]');
renderResourceStatus(container, testData);
相关资源¶
- 设计文档:
changelogs/resource-status-compact-refactor.md - 测试指南:
docs/developer-guide/testing-resource-status-compact.md - 样式文件:
assets/scss/layouts/ai/_ai-health.scss - 脚本文件:
assets/js/ai-health-indicators.js - 模板文件:
layouts/ai/single.html
需要帮助? 查看测试指南或联系开发团队。