- Migrated 4 components from ECharts to Chart.js: * MonthlyExpenseCard.vue (折线图) * DailyTrendChart.vue (双系列折线图) * ExpenseCategoryCard.vue (环形图) * BudgetChartAnalysis.vue (仪表盘 + 多种图表) - Removed all ECharts imports and environment variable switches - Unified all charts to use BaseChart.vue component - Build verified: pnpm build success ✓ - No echarts imports remaining ✓ Refs: openspec/changes/migrate-remaining-echarts-to-chartjs
5.0 KiB
5.0 KiB
Iconify 图标集成功能
创建日期: 2026-02-16
状态: ✅ 已完成
功能概述
EmailBill 项目集成了 Iconify 图标库,替换了原有的 AI 生成 SVG 图标方案。用户可以通过图标选择器为交易分类选择来自 200+ 图标库的高质量图标。
核心功能
1. 图标搜索
- AI 关键字生成: 根据分类名称(如"餐饮")自动生成英文搜索关键字(如
["food", "restaurant", "dining"]) - Iconify API 集成: 调用 Iconify 搜索 API 检索图标
- 重试机制: 指数退避重试,确保 API 调用稳定性
2. 图标选择器
- 前端组件:
IconPicker.vue图标选择器组件 - 分页加载: 每页显示 20 个图标,支持滚动加载更多
- 实时搜索: 支持按图标名称过滤
- Iconify CDN: 使用 CDN 加载图标,无需安装 npm 包
3. 数据存储
- Icon 字段: 存储 Iconify 标识符(格式:
{collection}:{name},如"mdi:food") - IconKeywords 字段: 存储 AI 生成的搜索关键字(JSON 数组格式)
技术架构
后端(C# / .NET 10)
Entity 层:
public class TransactionCategory : BaseEntity
{
/// <summary>
/// 图标(Iconify标识符格式:{collection}:{name},如"mdi:home")
/// </summary>
[Column(StringLength = 50)]
public string? Icon { get; set; }
/// <summary>
/// 搜索关键字(JSON数组,如["food", "restaurant", "dining"])
/// </summary>
[Column(StringLength = 200)]
public string? IconKeywords { get; set; }
}
Service 层:
IconifyApiService: Iconify API 调用服务SearchKeywordGeneratorService: AI 搜索关键字生成服务IconSearchService: 图标搜索业务编排服务
WebApi 层:
IconController: 图标管理 API 控制器POST /api/icons/search-keywords: 生成搜索关键字POST /api/icons/search: 搜索图标PUT /api/categories/{categoryId}/icon: 更新分类图标
前端(Vue 3 + TypeScript)
组件:
Icon.vue: Iconify 图标渲染组件IconPicker.vue: 图标选择器组件
API 客户端:
icons.ts: 图标 API 客户端generateSearchKeywords(): 生成搜索关键字searchIcons(): 搜索图标updateCategoryIcon(): 更新分类图标
测试覆盖
总计 130 个测试用例:
- Entity 测试: 12 个测试(TransactionCategory 字段验证)
- Service 测试:
- IconifyApiService: 16 个测试
- SearchKeywordGeneratorService: 19 个测试
- IconSearchService: 20 个测试(含端到端测试)
- Controller 测试: 23 个集成测试(IconController)
API 配置
在 appsettings.json 中配置 Iconify API:
{
"Iconify": {
"ApiUrl": "https://api.iconify.design/search",
"DefaultLimit": 20,
"MaxRetryCount": 3,
"RetryDelayMs": 1000
}
}
使用示例
1. 为分类选择图标
用户在分类管理页面点击"选择图标"按钮:
- 系统根据分类名称生成搜索关键字
- 调用 Iconify API 搜索图标
- 显示图标选择器,用户选择喜欢的图标
- 更新分类的图标标识符到数据库
2. 渲染图标
前端使用 Icon 组件渲染图标:
<template>
<Icon icon="mdi:food" />
</template>
图标通过 Iconify CDN 自动加载,无需手动安装。
性能特点
- CDN 加载: 图标通过 Iconify CDN 加载,首次加载后浏览器缓存
- 分页加载: 图标选择器分页显示,避免一次性加载大量图标
- API 重试: 指数退避重试机制,确保 API 调用成功率
- 关键字缓存: IconKeywords 字段缓存 AI 生成的关键字,避免重复调用 AI API
迁移说明
数据库迁移
TransactionCategory 表已添加以下字段:
Icon(StringLength = 50): 存储 Iconify 图标标识符IconKeywords(StringLength = 200): 存储搜索关键字(可选)
旧数据迁移
- 旧的 AI 生成 SVG 图标数据保留在
Icon字段 - 用户可以通过图标选择器手动更新为 Iconify 图标
- 系统自动识别 Iconify 标识符格式(包含
:)
依赖项
后端
- Semantic Kernel(AI 关键字生成)
- HttpClient(Iconify API 调用)
前端
- Iconify CDN:
https://code.iconify.design/iconify-icon/2.1.0/iconify-icon.min.js - Vue 3 Composition API
- Vant UI(移动端组件库)
相关文档
- OpenSpec 变更:
openspec/changes/icon-search-integration/ - 设计文档:
openspec/changes/icon-search-integration/design.md - 任务列表:
openspec/changes/icon-search-integration/tasks.md - 测试报告: 见
WebApi.Test/Service/IconSearch/和WebApi.Test/Controllers/IconControllerTest.cs
后续优化建议
- 图标推荐: 根据分类名称推荐最匹配的图标
- 图标收藏: 允许用户收藏常用图标
- 自定义图标: 支持用户上传自定义图标
- 图标预览: 在分类列表中预览图标效果
- 批量更新: 批量为多个分类选择图标
作者: AI Assistant
最后更新: 2026-02-16