跳转至

资源状态条使用指南

快速开始

资源状态条是 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' }
};

国际化支持

添加新语言

  1. 扩展状态标签:

    const HEALTH_LEVELS = {
      excellent: { 
        min: 80, 
        label: { zh: '优秀', en: 'Excellent', ja: '優秀' }, 
        class: 'excellent' 
      },
      // ...其他级别
    };
    
  2. 更新渲染函数:

    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: 调整容器的 paddinggap:

.resource-status {
  padding: 0.5rem 0; // 减小内边距
  gap: 0.375rem;     // 减小行间距
}

Q: 能否在列表页使用?

A: 可以,但建议使用原有的 data-ai-health-barsdata-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>
`;

最佳实践

✅ 推荐做法

  1. 保持三行结构: 不要添加额外行,保持紧凑性
  2. 固定子评分顺序: 便于用户形成记忆
  3. 使用相对时间: 比"2025-12-13"更友好
  4. 提供 Tooltip: 帮助用户理解评分含义
  5. 测试深色模式: 确保颜色在两种模式下都清晰

❌ 避免做法

  1. 不要添加图标: 除 info 图标外,避免视觉噪音
  2. 不要使用大号字体: 破坏紧凑性
  3. 不要纵向排列子评分: 增加高度
  4. 不要添加动画: 影响性能和可读性
  5. 不要修改评分算法: 保持与后端一致

性能优化

减少重绘

// ❌ 避免:逐个设置内容
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

需要帮助? 查看测试指南或联系开发团队。