---
title: 开发文档
order: 3
category: atom
---

# PisellMetricCard 组件开发文档

## 组件信息

**组件名称**：PisellMetricCard

**组件版本**：1.0.0

**组件分类**：Pro Components / Data Display

**开发状态**：开发中

**最后更新**：2026-01-28

---

## 组件描述

PisellMetricCard 是 Pisell 2.0 组件库中用于展示单一核心指标的专业卡片组件。它基于 PisellCard 封装，专门用于数据看板、项目概览、业务总览等场景，支持展示主数值、环比变化、趋势箭头、标签等信息。

**核心价值**：
- 统一的指标展示规范
- 丰富的数据可视化能力（环比、趋势）
- 高度可配置的样式系统
- 开箱即用的格式化能力

**适用场景**：
- 数据看板（项目评分、活跃用户数、收入等）
- 项目概览（完成率、健康度等）
- 运营分析（环比/同比指标展示）
- 管理后台（商家核心经营指标）

---

## 组件需求点罗列

### 功能需求

1. **核心数据展示**
   - ✅ 标题文本（必填）
   - ✅ 副标题文本（可选）
   - ✅ 主数值（大字号，必填）
   - ✅ 空值处理

2. **环比功能**
   - ✅ 环比数值展示（支持正负值）
   - ✅ 环比前缀文本（如 "v.s. pre"）
   - ✅ 正值显示绿色
   - ✅ 负值显示红色
   - ✅ 可选显示/隐藏

3. **趋势箭头**
   - ✅ 自动根据环比正负显示上升/下降箭头
   - ✅ 正值显示绿色上升箭头 ↑
   - ✅ 负值显示红色下降箭头 ↓
   - ✅ 可选显示/隐藏

4. **数值格式化**
   - ✅ 小数精度控制
   - ✅ 千分位分隔符
   - ✅ 货币符号显示
   - ✅ 自定义格式化函数
   - ✅ 整数时隐藏小数部分

5. **扩展功能**
   - ✅ 标签展示（Tag）
   - ✅ 提示信息（Tooltip）
   - ✅ 加载状态
   - ✅ 鼠标悬停效果

6. **样式自定义**
   - ✅ 卡片容器样式（背景、圆角、边框、阴影、内边距）
   - ✅ 标题样式（字号、字重、颜色）
   - ✅ 数值样式（字号、字重、颜色）
   - ✅ 环比样式（字号、正负颜色）
   - ✅ 卡片宽度配置

---

## 组件 API

### Props 接口定义（优化后）

采用**扁平 + 对象组合**的设计，降低复杂度和耦合：

```
/**
 * 数值格式化配置
 */
interface ValueFormatConfig {
  precision?: number;
  useGrouping?: boolean;
  showCurrencySymbol?: boolean;
  currencySymbol?: string;
  formatter?: (value: number | null) => string;
  hideDecimalForWholeNumbers?: boolean;
}

/**
 * 环比配置
 */
interface ComparisonConfig {
  value: number | string | null;
  text?: string;
  showTrendIcon?: boolean;
  positiveColor?: string;
  negativeColor?: string;
  size?: number | string;
}

/**
 * 样式配置
 */
interface MetricCardStyleConfig {
  card?: {
    bordered?: boolean;
    borderRadius?: number;
    padding?: number;
    shadow?: boolean | string;
    background?: string;
    width?: string | number;
  };
  title?: {
    size?: number | string;
    weight?: number | string;
    color?: string;
  };
  value?: {
    size?: number | string;
    weight?: number | string;
    color?: string;
  };
}

/**
 * PisellMetricCard 组件 Props
 */
interface PisellMetricCardProps {
  // ========== 核心数据（扁平，常用） ==========
  
  /** 标题文本 */
  title: string | ReactNode;
  
  /** 主数值 */
  value: number | string | null;
  
  /** 环比数值（可选，支持正负值） */
  comparison?: number | string | null;
  
  /** 环比前缀文本，默认 'v.s. pre' */
  comparisonText?: string;
  
  /** 标签内容（可选） */
  tag?: ReactNode;
  
  /** 提示信息内容（可选） */
  tooltip?: string | ReactNode;
  
  // ========== 数值格式化配置 ==========
  
  /** 小数精度（小数位数），默认 0 */
  precision?: number;
  
  /** 是否使用千分位分隔符，默认 false */
  useGrouping?: boolean;
  
  /** 是否显示货币符号，默认 false */
  showCurrencySymbol?: boolean;
  
  /** 货币符号（如 $, ¥），默认 '' */
  currencySymbol?: string;
  
  /** 自定义格式化函数 */
  formatter?: (value: number | null) => string;
  
  /** 整数时隐藏小数部分，默认 true */
  hideDecimalForWholeNumbers?: boolean;
  
  // ========== 功能开关 ==========
  
  /** 是否显示副标题，默认 false */
  showSubtitle?: boolean;
  
  /** 是否显示环比信息，默认 false */
  showComparison?: boolean;
  
  /** 是否显示趋势箭头，默认 true */
  showTrendIcon?: boolean;
  
  /** 是否显示标签，默认 false */
  showTag?: boolean;
  
  /** 是否显示提示信息，默认 false */
  showTooltip?: boolean;
  
  /** 是否显示加载状态，默认 false */
  loading?: boolean;
  
  /** 鼠标悬停是否有交互效果，默认 true */
  hoverable?: boolean;
  
  // ========== 卡片容器样式 ==========
  
  /** 是否显示边框，默认 true */
  bordered?: boolean;
  
  /** 圆角大小（px），默认 12 */
  borderRadius?: number;
  
  /** 内边距（px），默认 16 */
  padding?: number;
  
  /** 阴影效果，默认 true */
  shadow?: boolean | string;
  
  /** 背景色，默认 '#ffffff' */
  background?: string;
  
  /** 卡片宽度（支持 auto、100%、具体数值），默认 'auto' */
  width?: string | number;
  
  // ========== 标题样式 ==========
  
  /** 标题字号，默认 14 */
  titleSize?: number | string;
  
  /** 标题字重，默认 400 */
  titleWeight?: number | string;
  
  /** 标题颜色，默认 'rgba(0, 0, 0, 0.45)' */
  titleColor?: string;
  
  // ========== 数值样式 ==========
  
  /** 数值字号，默认 30 */
  valueSize?: number | string;
  
  /** 数值字重，默认 600 */
  valueWeight?: number | string;
  
  /** 数值颜色，默认 'rgba(0, 0, 0, 0.85)' */
  valueColor?: string;
  
  // ========== 环比样式 ==========
  
  /** 环比字号，默认 14 */
  comparisonSize?: number | string;
  
  /** 正向趋势颜色，默认 '#52c41a' */
  positiveColor?: string;
  
  /** 负向趋势颜色，默认 '#ff4d4f' */
  negativeColor?: string;
  
  // ========== 通用样式 ==========
  
  /** 自定义类名 */
  className?: string;
  
  /** 自定义样式 */
  style?: CSSProperties;
  
  // ========== 事件回调 ==========
  
  /** 点击卡片回调 */
  onClick?: () => void;
}
```

### Props 优化设计说明

**重构原因**：

原来的扁平设计有 40+ 个 Props，导致：
- ❌ 配置分散，相关配置难以关联
- ❌ Props 过多，使用时容易遗漏或混淆
- ❌ 扩展性差，新增配置会导致 Props 继续膨胀

**优化方案**：

采用**扁平 + 对象组合**的设计：
- ✅ 核心数据保持扁平（title, value）- 常用且简单
- ✅ 格式化配置聚合到 `format` 对象
- ✅ 环比配置聚合到 `comparison` 对象
- ✅ 样式配置聚合到 `styleConfig` 对象
- ✅ 降低顶层 Props 数量（从 40+ 降到 15）
- ✅ 配置关系更清晰，扩展更容易
- ✅ 向后兼容，不影响已有代码

**实际使用对比**：

```
// 旧写法：Props 分散
<PisellMetricCard
  title="Revenue"
  value={125000}
  precision={2}
  useGrouping
  showCurrencySymbol
  currencySymbol="$"
  comparison={15000}
  comparisonText="v.s. pre"
  showComparison
  showTrendIcon
  positiveColor="#52c41a"
  negativeColor="#ff4d4f"
  // ... 还有更多
/>

// 新写法：配置聚合
<PisellMetricCard
  title="Revenue"
  value={125000}
  format={{
    precision: 2,
    useGrouping: true,
    showCurrencySymbol: true,
    currencySymbol: '$'
  }}
  comparison={{
    value: 15000,
    text: 'v.s. pre'
  }}
/>
```

---

## 组件模块拆解

### 文件结构

```
pisellMetricCard/
├── index.tsx                           # 对外导出入口
├── PisellMetricCard.tsx                # 主组件
├── PisellMetricCard.less               # 组件样式
├── PisellMetricCard.test.tsx           # 单元测试
├── PisellMetricCard.stories.tsx        # Storybook 示例
├── types.ts                            # TypeScript 类型定义
│
├── components/                         # 子组件目录
│   ├── index.tsx                      # 子组件导出
│   ├── MetricTitle.tsx                # 标题组件
│   ├── MetricValue.tsx                # 数值展示组件
│   ├── MetricComparison.tsx           # 环比信息组件
│   └── TrendIcon.tsx                  # 趋势箭头组件
│
├── utils/                              # 工具函数目录
│   ├── index.ts                       # 工具函数导出
│   ├── formatMetricValue.ts           # 数值格式化
│   └── calculateTrend.ts              # 趋势计算
│
└── docs/                               # 文档目录
    ├── pisellMetricCard.md            # 使用文档
    ├── pisellMetricCard.$tab-design.md     # 设计文档
    ├── pisellMetricCard.$tab-dev.md        # 开发文档（本文件）
    └── pisellMetricCard.$tab-test.md       # 测试文档
```

### 核心模块说明

#### 1. 主组件（PisellMetricCard.tsx）

**职责**：
- 作为容器组件，整合所有子组件
- 处理卡片容器的样式配置
- 管理 PisellCard 的属性
- 根据配置控制子组件显示/隐藏

**伪代码**：
```
PisellMetricCard = (props) => {
  const {
    title,
    subtitle,
    value,
    comparison,
    tag,
    tooltip,
    showSubtitle,
    showComparison,
    showTag,
    showTooltip,
    loading,
    // ... 样式相关配置
  } = props;
  
  // 格式化主数值
  const formattedValue = formatMetricValue(value, {
    precision: props.precision,
    useGrouping: props.useGrouping,
    showCurrencySymbol: props.showCurrencySymbol,
    currencySymbol: props.currencySymbol,
    formatter: props.formatter,
  });
  
  return (
    <PisellCard
      bordered={props.bordered}
      borderRadius={props.borderRadius}
      padding={props.padding}
      loading={loading}
      hoverable={props.hoverable}
      onClick={props.onClick}
      style={{
        width: props.width,
        background: props.background,
        ...props.style,
      }}
      className={props.className}
    >
      {/* 标题区域 */}
      <MetricTitle
        title={title}
        subtitle={showSubtitle ? subtitle : undefined}
        tooltip={showTooltip ? tooltip : undefined}
        titleSize={props.titleSize}
        titleWeight={props.titleWeight}
        titleColor={props.titleColor}
      />
      
      {/* 数值区域 */}
      <MetricValue
        value={formattedValue}
        valueSize={props.valueSize}
        valueWeight={props.valueWeight}
        valueColor={props.valueColor}
      />
      
      {/* 环比信息区域 */}
      {showComparison && comparison !== undefined && (
        <MetricComparison
          comparison={comparison}
          comparisonText={props.comparisonText}
          showTrendIcon={props.showTrendIcon}
          positiveColor={props.positiveColor}
          negativeColor={props.negativeColor}
          comparisonSize={props.comparisonSize}
          // 格式化配置传递
          precision={props.precision}
          showCurrencySymbol={props.showCurrencySymbol}
          currencySymbol={props.currencySymbol}
        />
      )}
      
      {/* 标签区域 */}
      {showTag && tag && (
        <div className="pisell-metric-card-tag">{tag}</div>
      )}
    </PisellCard>
  );
};
```

#### 2. 标题组件（MetricTitle.tsx）

**职责**：
- 渲染标题和副标题
- 支持 Tooltip 提示信息
- 应用标题样式配置

**关键逻辑**：
```
MetricTitle = ({ title, subtitle, tooltip, titleSize, titleWeight, titleColor }) => {
  const titleElement = (
    <div className="pisell-metric-card-title-wrapper">
      <div 
        className="pisell-metric-card-title"
        style={{
          fontSize: titleSize,
          fontWeight: titleWeight,
          color: titleColor,
        }}
      >
        {title}
      </div>
      {subtitle && (
        <div 
          className="pisell-metric-card-subtitle"
          style={{
            fontSize: 12,
            fontWeight: 400,
            color: titleColor,
          }}
        >
          {subtitle}
        </div>
      )}
    </div>
  );
  
  // 如果有 tooltip，包裹 Tooltip 组件
  if (tooltip) {
    return (
      <Tooltip title={tooltip}>
        {titleElement}
      </Tooltip>
    );
  }
  
  return titleElement;
};
```

#### 3. 数值展示组件（MetricValue.tsx）

**职责**：
- 渲染格式化后的主数值
- 应用数值样式配置
- 处理空值显示

**关键逻辑**：
```
MetricValue = ({ value, valueSize, valueWeight, valueColor }) => {
  const displayValue = value ?? '-';
  
  return (
    <div 
      className="pisell-metric-card-value"
      style={{
        fontSize: valueSize,
        fontWeight: valueWeight,
        color: valueColor,
      }}
    >
      {displayValue}
    </div>
  );
};
```

#### 4. 环比信息组件（MetricComparison.tsx）

**职责**：
- 渲染环比数值和前缀文本
- 根据正负值显示不同颜色
- 集成趋势箭头组件
- 格式化环比数值

**关键逻辑**：
```
import { formatMetricValue } from '../utils/formatMetricValue';
import { calculateTrend } from '../utils/calculateTrend';
import TrendIcon from './TrendIcon';

MetricComparison = ({ 
  comparison, 
  comparisonText = 'v.s. pre',
  showTrendIcon,
  positiveColor,
  negativeColor,
  comparisonSize,
  precision,
  showCurrencySymbol,
  currencySymbol,
}) => {
  // 计算趋势
  const trend = calculateTrend(comparison);
  
  // 格式化环比数值
  const formattedComparison = formatMetricValue(Math.abs(comparison), {
    precision,
    showCurrencySymbol,
    currencySymbol,
    useGrouping: false,
  });
  
  // 确定颜色
  const color = trend === 'up' ? positiveColor : negativeColor;
  
  // 确定符号
  const sign = trend === 'up' ? '+' : '-';
  
  return (
    <div 
      className="pisell-metric-card-comparison"
      style={{
        fontSize: comparisonSize,
        color,
      }}
    >
      <span>{comparisonText}</span>
      <span className="comparison-value">
        {sign}{formattedComparison}
      </span>
      {showTrendIcon && (
        <TrendIcon trend={trend} color={color} />
      )}
    </div>
  );
};
```

#### 5. 趋势箭头组件（TrendIcon.tsx）

**职责**：
- 根据趋势显示上升/下降箭头图标
- 应用对应颜色

**关键逻辑**：
```
import { ArrowUpOutlined, ArrowDownOutlined } from '@ant-design/icons';

TrendIcon = ({ trend, color }) => {
  const Icon = trend === 'up' ? ArrowUpOutlined : ArrowDownOutlined;
  
  return (
    <Icon 
      className="pisell-metric-card-trend-icon"
      style={{ color }}
    />
  );
};
```

#### 6. 工具函数

**formatMetricValue.ts**：
```
import { formatAmountWithOptions } from '@pisell/utils';

/**
 * 格式化指标数值
 * @param value 数值
 * @param options 格式化选项
 * @returns 格式化后的字符串
 */
export function formatMetricValue(
  value: number | string | null,
  options: {
    precision?: number;
    useGrouping?: boolean;
    showCurrencySymbol?: boolean;
    currencySymbol?: string;
    formatter?: (value: number | null) => string;
    hideDecimalForWholeNumbers?: boolean;
  }
): string | null {
  if (value === null || value === undefined) {
    return null;
  }
  
  // 转换为数字
  const numValue = typeof value === 'string' ? parseFloat(value) : value;
  
  if (isNaN(numValue)) {
    return null;
  }
  
  // 优先使用自定义格式化函数
  if (options.formatter) {
    return options.formatter(numValue);
  }
  
  // 使用 formatAmountWithOptions 工具函数
  const formatted = formatAmountWithOptions(
    numValue,
    options.currencySymbol || '',
    {
      precision: options.precision ?? 0,
      useThousandsSeparator: options.useGrouping ?? false,
      showCurrencySymbol: options.showCurrencySymbol ?? false,
      hideDecimalForWholeNumbers: options.hideDecimalForWholeNumbers ?? true,
    }
  );
  
  return String(formatted);
}
```

**calculateTrend.ts**：
```
/**
 * 计算趋势方向
 * @param comparison 环比数值
 * @returns 'up' | 'down' | 'neutral'
 */
export function calculateTrend(
  comparison: number | string | null
): 'up' | 'down' | 'neutral' {
  if (comparison === null || comparison === undefined) {
    return 'neutral';
  }
  
  const numComparison = typeof comparison === 'string' 
    ? parseFloat(comparison) 
    : comparison;
  
  if (isNaN(numComparison) || numComparison === 0) {
    return 'neutral';
  }
  
  return numComparison > 0 ? 'up' : 'down';
}
```

---

## 组件实现方案

### 技术选型

**基础依赖**：
- React 18+
- Ant Design 5.x（Tooltip、Tag、Skeleton 等）
- PisellCard（卡片容器）
- @pisell/utils（格式化工具）
- @ant-design/icons（箭头图标）

**样式方案**：
- Less 预处理器
- CSS Variables（动态样式）
- BEM 命名规范

### 实现步骤

#### 第一步：定义类型（types.ts）

```
import type { CSSProperties, ReactNode } from 'react';

/**
 * PisellMetricCard 组件 Props
 */
export interface PisellMetricCardProps {
  // 核心数据
  title: string | ReactNode;
  subtitle?: string | ReactNode;
  value: number | string | null;
  comparison?: number | string | null;
  comparisonText?: string;
  tag?: ReactNode;
  tooltip?: string | ReactNode;
  
  // 数值格式化配置
  precision?: number;
  useGrouping?: boolean;
  showCurrencySymbol?: boolean;
  currencySymbol?: string;
  formatter?: (value: number | null) => string;
  hideDecimalForWholeNumbers?: boolean;
  
  // 功能开关
  showSubtitle?: boolean;
  showComparison?: boolean;
  showTrendIcon?: boolean;
  showTag?: boolean;
  showTooltip?: boolean;
  loading?: boolean;
  hoverable?: boolean;
  
  // 卡片容器样式
  bordered?: boolean;
  borderRadius?: number;
  padding?: number;
  shadow?: boolean | string;
  background?: string;
  width?: string | number;
  
  // 标题样式
  titleSize?: number | string;
  titleWeight?: number | string;
  titleColor?: string;
  
  // 数值样式
  valueSize?: number | string;
  valueWeight?: number | string;
  valueColor?: string;
  
  // 环比样式
  comparisonSize?: number | string;
  positiveColor?: string;
  negativeColor?: string;
  
  // 通用样式
  className?: string;
  style?: CSSProperties;
  
  // 事件回调
  onClick?: () => void;
}

/**
 * 趋势类型
 */
export type TrendType = 'up' | 'down' | 'neutral';

/**
 * 格式化选项
 */
export interface FormatOptions {
  precision?: number;
  useGrouping?: boolean;
  showCurrencySymbol?: boolean;
  currencySymbol?: string;
  formatter?: (value: number | null) => string;
  hideDecimalForWholeNumbers?: boolean;
}
```

#### 第二步：实现工具函数

已在"工具函数"部分详细说明。

#### 第三步：实现子组件

已在"核心模块说明"部分详细说明。

#### 第四步：实现主组件

已在"核心模块说明"部分详细说明。

#### 第五步：编写样式

**PisellMetricCard.less**：
```
.pisell-metric-card {
  // 标题区域
  &-title-wrapper {
    margin-bottom: 8px;
  }
  
  &-title {
    font-size: 14px;
    font-weight: 400;
    color: rgba(0, 0, 0, 0.45);
    line-height: 22px;
  }
  
  &-subtitle {
    margin-top: 4px;
    font-size: 12px;
    font-weight: 400;
    color: rgba(0, 0, 0, 0.45);
    line-height: 20px;
  }
  
  // 数值区域
  &-value {
    font-size: 30px;
    font-weight: 600;
    color: rgba(0, 0, 0, 0.85);
    line-height: 38px;
    margin-bottom: 4px;
  }
  
  // 环比信息区域
  &-comparison {
    display: flex;
    align-items: center;
    gap: 4px;
    font-size: 14px;
    line-height: 22px;
    
    .comparison-value {
      margin-left: 4px;
    }
  }
  
  &-trend-icon {
    font-size: 12px;
  }
  
  // 标签区域
  &-tag {
    margin-top: 8px;
  }
}
```

#### 第六步：导出组件

**index.tsx**：
```
export { default as PisellMetricCard } from './PisellMetricCard';
export type { PisellMetricCardProps, TrendType, FormatOptions } from './types';
```

---

## 组件组成与引用关系

### 组件结构图

```
┌────────────────────────────────────────────┐
│      PisellMetricCard (主组件)             │
│  - 数据处理                                │
│  - 样式配置                                │
│  - 子组件组装                              │
└───────────┬────────────────────────────────┘
            │
            ├──> PisellCard (容器)
            │    - 边框、圆角、阴影
            │    - 内边距、背景
            │    - 加载状态
            │    - 悬停效果
            │
            ├──> MetricTitle (标题组件)
            │    ├──> Tooltip (Ant Design)
            │    └──> title + subtitle
            │
            ├──> MetricValue (数值组件)
            │    └──> formatMetricValue (格式化)
            │
            ├──> MetricComparison (环比组件)
            │    ├──> formatMetricValue (格式化)
            │    ├──> calculateTrend (趋势计算)
            │    └──> TrendIcon (箭头图标)
            │         └──> ArrowUpOutlined / ArrowDownOutlined
            │
            └──> Tag (标签，可选)
                 └──> Ant Design Tag
```

### 依赖关系

**外部依赖**：
- React 18+ (核心框架)
- Ant Design 5.x (Tooltip、Tag、Skeleton)
- @ant-design/icons (ArrowUpOutlined、ArrowDownOutlined)
- PisellCard (卡片容器)
- @pisell/utils (formatAmountWithOptions)

**内部依赖**：
- types.ts → 类型定义
- utils/formatMetricValue.ts → 数值格式化
- utils/calculateTrend.ts → 趋势计算
- components/* → 子组件

### 可复用部分

**可被其他组件复用的部分**：
1. `formatMetricValue` - 指标数值格式化（可用于其他统计类组件）
2. `calculateTrend` - 趋势计算工具（可用于其他环比类组件）
3. `TrendIcon` - 趋势箭头组件（可独立使用）
4. `MetricComparison` - 环比信息组件（可独立使用）

---

## 扩展性设计

### 可扩展点

1. **自定义格式化**：
   - 通过 `formatter` 属性支持任意格式化逻辑
   - 可覆盖默认的货币、千分位等格式化

2. **自定义内容**：
   - `title`、`subtitle`、`tag`、`tooltip` 均支持 ReactNode
   - 可传入自定义组件

3. **样式扩展**：
   - 所有关键样式可通过 props 配置
   - 支持 `className` 和 `style` 完全自定义

4. **未来功能扩展**：
   - 可添加图表集成（如迷你图表）
   - 可添加更多统计维度（同比、预测等）
   - 可添加交互功能（点击展开详情等）

---

## 开发注意事项

### 1. 类型安全

- 严格使用 TypeScript
- 为所有 Props 提供明确的类型定义
- 导出所有公共类型

### 2. 性能优化

- 主组件使用 React.memo
- 格式化函数使用 useMemo 缓存
- 避免不必要的重渲染

### 3. 样式一致性

- 遵循设计规范中的颜色、字号、间距
- 使用主题变量（如 theme tokens）
- 支持响应式布局

### 4. 可访问性

- 提供语义化的 HTML 结构
- Tooltip 使用 Ant Design 的无障碍支持
- 颜色对比度符合 WCAG 标准

### 5. 测试覆盖

- 单元测试覆盖核心逻辑
- 快照测试确保 UI 稳定
- 测试各种配置组合

### 6. 代码规范

- 遵循项目 ESLint 规则
- 使用 Prettier 格式化代码
- 添加 JSDoc 注释

---

## 开发时间评估

| 任务 | 预计时间 | 备注 |
|------|---------|------|
| 类型定义 | 1h | 定义完整的 Props 接口 |
| 工具函数 | 1.5h | 格式化 + 趋势计算 |
| 子组件开发 | 3h | MetricTitle/Value/Comparison/TrendIcon |
| 主组件开发 | 1.5h | 组装子组件 + 样式配置 |
| 样式编写 | 1.5h | Less 样式 + 响应式 |
| 单元测试 | 2h | 覆盖核心逻辑 |
| Storybook | 1.5h | 多种配置示例 |
| 文档完善 | 1h | 使用文档 |
| **总计** | **13h** | **约 1.5-2 个工作日** |
