refactor: 优化代码结构,添加中文注释,完善 README 文档
- Hooks/组件添加 useMemo 优化,减少不必要的重计算 - 简化 TokenUsageDashboard 的 Suspense 嵌套层级 - 完善 README: 技术栈、构建产物位置、架构说明
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
/**
|
||||
* HealthRing 组件
|
||||
*
|
||||
* Apple 健康风格的圆环进度指示器
|
||||
* 中心显示倒计时
|
||||
* Apple 健康风格的圆环进度指示器,用于可视化配额使用情况。
|
||||
* 中心显示百分比和倒计时,颜色根据剩余配额自动变化。
|
||||
*/
|
||||
import { useMemo } from 'react'
|
||||
import { useCountdown } from '@/hooks/useCountdown'
|
||||
|
||||
/** 组件 Props 类型定义 */
|
||||
export interface HealthRingProps {
|
||||
/** 账户名称 */
|
||||
account: string
|
||||
@@ -17,28 +19,36 @@ export interface HealthRingProps {
|
||||
remainingFraction: number
|
||||
/** 配额重置时间 (ISO 8601) */
|
||||
resetTime?: string
|
||||
/** 圆环尺寸 */
|
||||
/** 圆环尺寸 (像素),默认 160 */
|
||||
size?: number
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据剩余配额获取颜色
|
||||
* 颜色阈值配置
|
||||
* 根据剩余配额百分比决定显示颜色
|
||||
*/
|
||||
const getRingColor = (fraction: number): string => {
|
||||
if (fraction < 0.05) return '#FF3B30' // 红色 - 紧急
|
||||
if (fraction < 0.2) return '#FF9500' // 橙色 - 警告
|
||||
if (fraction < 0.5) return '#FFCC00' // 黄色 - 注意
|
||||
return '#34C759' // 绿色 - 正常
|
||||
}
|
||||
const COLOR_THRESHOLDS = [
|
||||
{ threshold: 0.05, color: '#FF3B30', bgColor: 'rgba(255, 59, 48, 0.2)' }, // 红色 - 紧急
|
||||
{ threshold: 0.2, color: '#FF9500', bgColor: 'rgba(255, 149, 0, 0.2)' }, // 橙色 - 警告
|
||||
{ threshold: 0.5, color: '#FFCC00', bgColor: 'rgba(255, 204, 0, 0.2)' }, // 黄色 - 注意
|
||||
] as const
|
||||
|
||||
/** 默认颜色 (绿色 - 正常状态) */
|
||||
const DEFAULT_COLOR = { color: '#34C759', bgColor: 'rgba(52, 199, 89, 0.2)' }
|
||||
|
||||
/**
|
||||
* 根据剩余配额获取背景色(较暗)
|
||||
* 根据剩余配额获取对应的颜色配置
|
||||
*
|
||||
* @param fraction - 剩余配额百分比 (0-1)
|
||||
* @returns 前景色和背景色配置
|
||||
*/
|
||||
const getRingBgColor = (fraction: number): string => {
|
||||
if (fraction < 0.05) return 'rgba(255, 59, 48, 0.2)'
|
||||
if (fraction < 0.2) return 'rgba(255, 149, 0, 0.2)'
|
||||
if (fraction < 0.5) return 'rgba(255, 204, 0, 0.2)'
|
||||
return 'rgba(52, 199, 89, 0.2)'
|
||||
const getColorConfig = (
|
||||
fraction: number,
|
||||
): { color: string; bgColor: string } => {
|
||||
for (const { threshold, color, bgColor } of COLOR_THRESHOLDS) {
|
||||
if (fraction < threshold) return { color, bgColor }
|
||||
}
|
||||
return DEFAULT_COLOR
|
||||
}
|
||||
|
||||
export const HealthRing = ({
|
||||
@@ -50,20 +60,25 @@ export const HealthRing = ({
|
||||
size = 160,
|
||||
}: HealthRingProps) => {
|
||||
const countdown = useCountdown(resetTime)
|
||||
|
||||
// 使用 useMemo 缓存 SVG 计算值,避免不必要的重新计算
|
||||
const svgParams = useMemo(() => {
|
||||
const strokeWidth = size * 0.1
|
||||
const radius = (size - strokeWidth) / 2
|
||||
const circumference = 2 * Math.PI * radius
|
||||
const strokeDashoffset = circumference * (1 - remainingFraction)
|
||||
|
||||
return { strokeWidth, radius, circumference, strokeDashoffset }
|
||||
}, [size, remainingFraction])
|
||||
|
||||
const percentage = Math.round(remainingFraction * 100)
|
||||
|
||||
// SVG 参数
|
||||
const strokeWidth = size * 0.1
|
||||
const radius = (size - strokeWidth) / 2
|
||||
const circumference = 2 * Math.PI * radius
|
||||
const strokeDashoffset = circumference * (1 - remainingFraction)
|
||||
|
||||
const ringColor = getRingColor(remainingFraction)
|
||||
const ringBgColor = getRingBgColor(remainingFraction)
|
||||
const { color: ringColor, bgColor: ringBgColor } =
|
||||
getColorConfig(remainingFraction)
|
||||
const { strokeWidth, radius, circumference, strokeDashoffset } = svgParams
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center gap-3">
|
||||
{/* 圆环 */}
|
||||
{/* 圆环容器 */}
|
||||
<div className="relative" style={{ width: size, height: size }}>
|
||||
<svg
|
||||
width={size}
|
||||
@@ -97,7 +112,7 @@ export const HealthRing = ({
|
||||
/>
|
||||
</svg>
|
||||
|
||||
{/* 中心内容 - 倒计时 */}
|
||||
{/* 中心内容 - 百分比和倒计时 */}
|
||||
<div className="absolute inset-0 flex flex-col items-center justify-center">
|
||||
<span className="text-2xl font-bold" style={{ color: ringColor }}>
|
||||
{percentage}%
|
||||
@@ -108,7 +123,7 @@ export const HealthRing = ({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 标签 */}
|
||||
{/* 底部标签 */}
|
||||
<div className="text-center">
|
||||
<div
|
||||
className="text-sm font-medium truncate max-w-[140px] text-[var(--on-container-color)]"
|
||||
|
||||
Reference in New Issue
Block a user