1
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Waiting to run
Docker Build & Deploy / Deploy to Production (push) Has been cancelled
Docker Build & Deploy / Cleanup Dangling Images (push) Has been cancelled
Docker Build & Deploy / WeChat Notification (push) Has been cancelled
Some checks failed
Docker Build & Deploy / Build Docker Image (push) Waiting to run
Docker Build & Deploy / Deploy to Production (push) Has been cancelled
Docker Build & Deploy / Cleanup Dangling Images (push) Has been cancelled
Docker Build & Deploy / WeChat Notification (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-17
|
||||
@@ -0,0 +1,87 @@
|
||||
## Context
|
||||
|
||||
EmailBill 项目已从 ECharts 迁移到 Chart.js 作为图表库。在迁移过程中,图表文本显示出现了乱码问题,特别是在显示中文标签、Tooltip 和中心文本时。这可能是由于:
|
||||
|
||||
1. Chart.js 默认字体配置不支持中文
|
||||
2. Tooltip 回调函数返回的字符串编码问题
|
||||
3. 主题切换时字体颜色对比度不足
|
||||
|
||||
当前图表组件位于 `Web/src/components/Charts/`,使用 `BaseChart.vue` 作为统一包装组件。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
- 修复所有图表(饼图、折线图、仪表盘)的中文乱码问题
|
||||
- 确保图表文本在明/暗主题下都清晰可读
|
||||
- 统一字体配置,支持跨平台中文显示
|
||||
- 修复 Tooltip 和 Label 的文本格式化问题
|
||||
|
||||
**Non-Goals:**
|
||||
- 不修改图表的数据结构或业务逻辑
|
||||
- 不添加新的图表类型
|
||||
- 不进行 UI 样式的大幅度调整(仅修复文本显示问题)
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: 字体配置方案
|
||||
**选择**: 在 `useChartTheme.ts` 中统一配置 Chart.js 字体选项
|
||||
|
||||
**理由**:
|
||||
- Chart.js 支持全局字体配置,通过 `defaults.font.family` 可以一次性设置所有图表的字体
|
||||
- 使用系统字体栈确保跨平台兼容性:`'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif`
|
||||
- 避免在每个组件中重复配置
|
||||
|
||||
**替代方案考虑**:
|
||||
- 在每个图表组件中单独配置字体 → 重复代码,维护困难
|
||||
- 使用 WebFont 加载自定义字体 → 增加外部依赖,加载时间不可控
|
||||
|
||||
### Decision 2: Tooltip 格式化修复方案
|
||||
**选择**: 修复 `callbacks.label` 和 `callbacks.title` 回调函数,确保返回正确的字符串
|
||||
|
||||
**理由**:
|
||||
- Chart.js 的 Tooltip 回调函数必须返回字符串,不能返回对象或其他类型
|
||||
- 使用模板字符串确保正确的字符串拼接
|
||||
- 添加空值检查防止 undefined 导致的乱码
|
||||
|
||||
**代码示例**:
|
||||
```typescript
|
||||
tooltip: {
|
||||
callbacks: {
|
||||
label: (context) => {
|
||||
const value = context.parsed.y || context.parsed
|
||||
return `¥${value.toFixed(2)}`
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Decision 3: 中心文本显示方案
|
||||
**选择**: 继续使用 CSS 绝对定位的覆盖层显示中心文本
|
||||
|
||||
**理由**:
|
||||
- Chart.js 本身不支持在 Doughnut 图表中心直接渲染文本
|
||||
- CSS 覆盖层方式简单可靠,易于控制字体样式
|
||||
- 确保覆盖层使用正确的字体族和颜色
|
||||
|
||||
**实现要点**:
|
||||
- 覆盖层容器设置 `font-family` 继承自主题配置
|
||||
- 使用 `var(--van-text-color)` 确保主题适配
|
||||
- 添加 `white-space: nowrap` 防止文本换行导致错位
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
| Risk | Mitigation |
|
||||
|------|------------|
|
||||
| 某些旧版浏览器可能不支持系统字体栈 | 提供后备字体(Arial, sans-serif)确保基本可读性 |
|
||||
| 暗色模式下文本颜色对比度不足 | 使用 Vant 主题变量确保颜色适配 |
|
||||
| 字体文件过大影响加载性能 | 使用系统字体,不加载外部字体文件 |
|
||||
| 修改全局配置可能影响其他组件 | 在 `useChartTheme` 中集中管理,便于回滚 |
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. **阶段 1**: 修改 `useChartTheme.ts` 添加全局字体配置
|
||||
2. **阶段 2**: 检查并修复各图表组件的 Tooltip 回调函数
|
||||
3. **阶段 3**: 验证所有图表页面的文本显示
|
||||
4. **阶段 4**: 在明/暗主题下分别测试
|
||||
|
||||
**Rollback Strategy**: 所有修改都是配置层面的,可以通过回滚 Git 提交快速恢复。
|
||||
@@ -0,0 +1,25 @@
|
||||
## Why
|
||||
|
||||
在浏览器中查看图表时,饼图、折线图等图表上出现了错乱的字符串显示问题,影响数据可读性和用户体验。这可能是由于 Chart.js 配置中的字体设置、编码问题或 tooltip/label 格式化错误导致的。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 修复饼图、折线图、仪表盘等图表上的错乱字符串显示
|
||||
- 检查并修正图表字体配置,确保使用中文字体或兼容字体
|
||||
- 修复 tooltip 和 label 的格式化回调函数
|
||||
- 确保图表文本在各种主题(明/暗色模式)下正确显示
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
- `chart-text-encoding-fix`: 修复图表文本编码和字体配置,确保中文和特殊字符正确显示
|
||||
|
||||
### Modified Capabilities
|
||||
- `chart-migration-patterns`: 更新图表迁移模式中的文本渲染配置,确保 Chart.js 图表文本正确显示
|
||||
|
||||
## Impact
|
||||
|
||||
- **前端组件**: `Web/src/components/Charts/` 下的所有图表组件
|
||||
- **配置文件**: 图表主题配置文件 `useChartTheme.ts`
|
||||
- **工具函数**: 图表辅助函数 `chartHelpers.ts`
|
||||
- **页面**: 统计页面、预算页面等使用图表的页面
|
||||
@@ -0,0 +1,129 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: 仪表盘图表迁移模式
|
||||
组件 SHALL 使用 Chart.js Doughnut 图表实现仪表盘(Gauge)效果,替代 ECharts Gauge 图表。
|
||||
|
||||
#### Scenario: 半圆仪表盘渲染
|
||||
- **WHEN** 组件接收预算统计数据(current, limit)
|
||||
- **THEN** 系统使用 Doughnut 图表渲染半圆进度条,配置 `rotation: -90` 和 `circumference: 180`
|
||||
- **AND** 图表字体配置 SHALL 包含中文字体支持
|
||||
|
||||
#### Scenario: 中心文本叠加显示
|
||||
- **WHEN** 仪表盘图表渲染完成
|
||||
- **THEN** 系统在图表中心显示余额/超支文本,使用 CSS 绝对定位的覆盖层
|
||||
- **AND** 中心文本 SHALL 正确显示中文,无乱码
|
||||
|
||||
#### Scenario: 动态颜色切换
|
||||
- **WHEN** 实际值超过预算限额
|
||||
- **THEN** 进度条颜色切换为危险色(`var(--van-danger-color)`),中心文本显示"超支"
|
||||
- **AND** "超支"文字 SHALL 清晰可读
|
||||
|
||||
#### Scenario: 暗色模式适配
|
||||
- **WHEN** 用户切换到暗色主题
|
||||
- **THEN** 图表颜色自动适配,使用 `useChartTheme` composable 获取主题色
|
||||
- **AND** 文本颜色 SHALL 与背景有足够对比度
|
||||
|
||||
### Requirement: 折线图迁移模式
|
||||
组件 SHALL 使用 Chart.js Line 图表实现趋势折线图,替代 ECharts Line 图表。
|
||||
|
||||
#### Scenario: 单系列折线图渲染
|
||||
- **WHEN** 组件接收月度支出数据(日期 + 金额数组)
|
||||
- **THEN** 系统渲染折线图,X 轴为日期标签,Y 轴为金额,使用渐变填充
|
||||
- **AND** X 轴日期标签 SHALL 正确显示,无乱码
|
||||
|
||||
#### Scenario: 双系列折线图渲染
|
||||
- **WHEN** 组件接收收支数据(包含收入和支出两个系列)
|
||||
- **THEN** 系统渲染两条折线,支出为红色,收入为绿色,支持独立的 hover 交互
|
||||
- **AND** 图例 SHALL 正确显示"收入"和"支出"中文标签
|
||||
|
||||
#### Scenario: 空数据处理
|
||||
- **WHEN** 图表数据为空或所有数据点为 0
|
||||
- **THEN** 系统显示 `<van-empty>` 空状态组件,而非空白图表
|
||||
|
||||
#### Scenario: Tooltip 格式化
|
||||
- **WHEN** 用户 hover 到数据点
|
||||
- **THEN** Tooltip 显示"¥XXX.XX"格式的金额,使用 `callbacks.label` 自定义
|
||||
- **AND** Tooltip 内容 SHALL 正确编码,无乱码
|
||||
|
||||
### Requirement: 饼图/环形图迁移模式
|
||||
组件 SHALL 使用 Chart.js Doughnut 图表实现分类统计环形图,替代 ECharts Pie 图表。
|
||||
|
||||
#### Scenario: 环形图渲染
|
||||
- **WHEN** 组件接收分类统计数据(分类名称 + 金额数组)
|
||||
- **THEN** 系统渲染环形图,每个分类使用不同颜色,配置 `cutout: '50%'`
|
||||
- **AND** 分类标签 SHALL 正确显示中文名称
|
||||
|
||||
#### Scenario: 分类颜色映射
|
||||
- **WHEN** 分类数据包含预定义颜色
|
||||
- **THEN** 图表使用 props 传入的颜色数组,确保与列表中的分类色块一致
|
||||
|
||||
#### Scenario: 小分类合并
|
||||
- **WHEN** 分类数量超过 10 个
|
||||
- **THEN** 系统使用 `mergeSmallCategories()` 工具函数,将占比小于 5% 的分类合并为"其他"
|
||||
- **AND** "其他"标签 SHALL 正确显示
|
||||
|
||||
#### Scenario: 点击分类跳转
|
||||
- **WHEN** 用户点击环形图扇区
|
||||
- **THEN** 系统触发 `@category-click` 事件,传递分类名称和类型
|
||||
|
||||
### Requirement: BaseChart 组件统一使用
|
||||
所有图表组件 SHALL 使用 `BaseChart.vue` 包装组件,而非直接使用 vue-chartjs 组件。
|
||||
|
||||
#### Scenario: BaseChart 组件使用
|
||||
- **WHEN** 组件需要渲染图表
|
||||
- **THEN** 使用 `<BaseChart type="line|bar|doughnut" :data="chartData" :options="chartOptions" />`
|
||||
- **AND** 通过 options 传入正确的字体配置
|
||||
|
||||
#### Scenario: Loading 状态处理
|
||||
- **WHEN** 图表数据加载中
|
||||
- **THEN** BaseChart 显示 `<van-loading>` 组件
|
||||
|
||||
#### Scenario: 图表渲染回调
|
||||
- **WHEN** 图表渲染完成
|
||||
- **THEN** BaseChart 触发 `@chart:render` 事件,传递 Chart.js 实例引用
|
||||
|
||||
### Requirement: ECharts 代码完全移除
|
||||
组件 SHALL 移除所有 ECharts 相关代码,包括导入语句、实例变量、环境变量判断。
|
||||
|
||||
#### Scenario: 移除 ECharts 导入
|
||||
- **WHEN** 迁移组件
|
||||
- **THEN** 删除 `import * as echarts from 'echarts'` 语句
|
||||
|
||||
#### Scenario: 移除环境变量开关
|
||||
- **WHEN** 迁移组件
|
||||
- **THEN** 删除 `const useChartJS = import.meta.env.VITE_USE_CHARTJS === 'true'` 和相关的 `v-if`/`v-else` 条件渲染
|
||||
|
||||
#### Scenario: 移除 ECharts 实例管理
|
||||
- **WHEN** 迁移组件
|
||||
- **THEN** 删除 `let chartInstance = null`、`echarts.init()`、`chartInstance.setOption()` 等代码
|
||||
|
||||
#### Scenario: 移除生命周期清理
|
||||
- **WHEN** 迁移组件
|
||||
- **THEN** 删除 `onBeforeUnmount()` 中的 `chartInstance.dispose()` 调用
|
||||
|
||||
### Requirement: 测试覆盖
|
||||
迁移后的组件 SHALL 通过白盒和黑盒测试验证功能正确性。
|
||||
|
||||
#### Scenario: 单元测试 - 组件挂载
|
||||
- **WHEN** 运行 Jest 单元测试
|
||||
- **THEN** 组件能够成功挂载,不抛出错误
|
||||
|
||||
#### Scenario: 单元测试 - Props 传递
|
||||
- **WHEN** 传入测试数据 props
|
||||
- **THEN** 计算属性 `chartData` 和 `chartOptions` 返回正确的 Chart.js 配置对象
|
||||
- **AND** options 中 SHALL 包含正确的字体配置
|
||||
|
||||
#### Scenario: E2E 测试 - 图表渲染
|
||||
- **WHEN** 运行 Playwright E2E 测试
|
||||
- **THEN** 浏览器中能看到图表元素(Canvas),且无控制台错误
|
||||
- **AND** 图表文本 SHALL 正确显示,无乱码
|
||||
|
||||
#### Scenario: E2E 测试 - 用户交互
|
||||
- **WHEN** 用户 hover 到图表数据点
|
||||
- **THEN** Tooltip 正确显示,格式化后的金额信息可见
|
||||
- **AND** Tooltip 内容 SHALL 无乱码
|
||||
|
||||
#### Scenario: 视觉回归测试
|
||||
- **WHEN** 截图对比迁移前后的图表
|
||||
- **THEN** 颜色、布局、字体大小差异在可接受范围内(像素差异 < 5%)
|
||||
- **AND** 中文文本 SHALL 清晰可读
|
||||
@@ -0,0 +1,44 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: 图表文本编码修复
|
||||
Chart.js 图表 SHALL 正确显示中文文本,不出现乱码或异常字符。
|
||||
|
||||
#### Scenario: 饼图标签中文显示
|
||||
- **WHEN** 系统渲染支出分类饼图,分类名称为中文
|
||||
- **THEN** 分类标签 SHALL 正确显示中文字符
|
||||
- **AND** 标签文字 SHALL 清晰可读,无乱码
|
||||
|
||||
#### Scenario: Tooltip 中文显示
|
||||
- **WHEN** 用户 hover 到图表数据点
|
||||
- **THEN** Tooltip SHALL 正确显示中文内容
|
||||
- **AND** 金额和分类名称 SHALL 无乱码
|
||||
|
||||
#### Scenario: 中心文本中文显示
|
||||
- **WHEN** 仪表盘图表渲染中心文本
|
||||
- **THEN** 中心显示的余额/超支文本 SHALL 正确显示中文
|
||||
- **AND** 文字 SHALL 清晰无乱码
|
||||
|
||||
### Requirement: 图表字体配置
|
||||
Chart.js 配置 SHALL 使用兼容的字体设置,确保跨平台文本正确渲染。
|
||||
|
||||
#### Scenario: 字体族配置
|
||||
- **WHEN** 图表初始化时
|
||||
- **THEN** 系统 SHALL 配置 `font.family` 为兼容中文字体的字体栈(如 `'PingFang SC', 'Microsoft YaHei', sans-serif`)
|
||||
|
||||
#### Scenario: 响应式字体大小
|
||||
- **WHEN** 图表在不同尺寸屏幕上渲染
|
||||
- **THEN** 字体大小 SHALL 根据屏幕尺寸自动调整
|
||||
- **AND** 文字 SHALL 始终保持清晰可读
|
||||
|
||||
### Requirement: Tooltip 格式化修复
|
||||
Tooltip 回调函数 SHALL 正确处理文本编码和格式化。
|
||||
|
||||
#### Scenario: Tooltip Label 格式化
|
||||
- **WHEN** Tooltip 显示数据标签
|
||||
- **THEN** 回调函数 SHALL 返回正确编码的字符串
|
||||
- **AND** 特殊字符 SHALL 正确转义
|
||||
|
||||
#### Scenario: 金额格式化显示
|
||||
- **WHEN** Tooltip 显示金额
|
||||
- **THEN** 金额格式 SHALL 为 "¥XXX.XX"
|
||||
- **AND** 货币符号 SHALL 正确显示
|
||||
@@ -0,0 +1,43 @@
|
||||
## 1. 全局字体配置
|
||||
|
||||
- [x] 1.1 修改 `useChartTheme.ts`,添加 Chart.js 全局字体配置
|
||||
- [x] 1.2 配置字体栈支持中文显示:`'PingFang SC', 'Microsoft YaHei', 'Helvetica Neue', Arial, sans-serif`
|
||||
- [x] 1.3 设置默认字体大小和颜色变量
|
||||
|
||||
## 2. Tooltip 格式化修复
|
||||
|
||||
- [x] 2.1 检查饼图组件的 Tooltip 回调函数,修复编码问题
|
||||
- [x] 2.2 检查折线图组件的 Tooltip 回调函数,确保金额格式正确
|
||||
- [x] 2.3 检查仪表盘组件的 Tooltip 配置
|
||||
- [x] 2.4 确保所有 Tooltip 回调返回正确的字符串类型
|
||||
|
||||
## 3. 图表组件文本修复
|
||||
|
||||
- [x] 3.1 修复饼图分类标签的中文显示
|
||||
- [x] 3.2 修复折线图 X 轴日期标签显示
|
||||
- [x] 3.3 修复仪表盘中心文本(余额/超支)的中文显示
|
||||
- [x] 3.4 确保图例(Legend)中文标签正确显示
|
||||
|
||||
## 4. 主题适配
|
||||
|
||||
- [x] 4.1 验证明色模式下图表文本清晰可读
|
||||
- [x] 4.2 验证暗色模式下图表文本颜色和对比度
|
||||
- [x] 4.3 修复主题切换时可能出现的文本渲染问题
|
||||
|
||||
## 7. 修复密集数字显示
|
||||
|
||||
- [x] 7.1 禁用折线图的数据标签(datalabels)
|
||||
- [x] 7.2 验证明暗模式下图表显示正常
|
||||
|
||||
## 5. 测试验证
|
||||
|
||||
- [x] 5.1 在 Chrome 浏览器中验证所有图表文本显示
|
||||
- [x] 5.2 在移动端浏览器中验证图表文本显示
|
||||
- [x] 5.3 验证 Tooltip hover 时文本无乱码
|
||||
- [x] 5.4 检查控制台是否有相关错误日志
|
||||
|
||||
## 6. 代码审查
|
||||
|
||||
- [x] 6.1 运行 `pnpm lint` 检查代码格式
|
||||
- [x] 6.2 运行 `pnpm build` 确保构建成功
|
||||
- [x] 6.3 检查是否有未使用的导入或变量
|
||||
Reference in New Issue
Block a user