## Context 当前系统使用AI生成SVG图标来表示分类,但生成的图标不够直观,与分类名称匹配度低,用户体验不佳。Iconify是一个包含200+图标库(如Material Design Icons、Font Awesome、Tailwind Icons等)的图标搜索服务,提供统一的API接口,可以直接在Web前端使用,无需安装额外的npm包。 ## Goals / Non-Goals **Goals:** - 集成Iconify API,实现图标搜索和检索功能 - 使用AI生成英文搜索关键字,提高搜索相关性 - 将检索到的图标持久化到数据库,避免重复搜索 - 提供RESTful API接口,支持图标管理操作 - 替换现有的AI生成SVG图标逻辑,提升图标可视化质量 **Non-Goals:** - 不实现图标上传功能(仅使用Iconify API检索) - 不实现图标的在线编辑功能 - 不支持自定义图标(仅使用Iconify现有图标库) - 不实现图标的热门推荐或相似图标推荐功能 ## Decisions ### 1. 使用Iconify API而非其他图标库 **决策**: 选择Iconify API作为图标检索服务 **理由**: - Iconify集成了200+图标库,覆盖范围广,包括Material Design Icons、Font Awesome、Bootstrap Icons等主流库 - 提供统一的搜索API,无需逐个调用不同图标库 - 前端可以直接使用Iconify CDN,无需安装npm包 - 搜索API响应快,返回数据结构清晰 **替代方案考虑**: - 方案A:使用单个图标库(如Material Design Icons)→ 覆盖范围有限,图标数量不足 - 方案B:自建图标数据库 → 维护成本高,图标更新不及时 - 方案C:使用多个图标库API → 需要分别集成不同API,开发复杂度高 ### 2. AI生成搜索关键字而非直接使用分类名称翻译 **决策**: 使用AI生成多个英文搜索关键字,而非直接翻译分类名称 **理由**: - 直接翻译可能不准确(如"餐饮"翻译为"catering",但更常用"food"或"restaurant") - 一个分类可能有多个相关的图标概念(如"交通"可以是"car"、"bus"、"transport") - AI能够理解语义,生成更准确的英文搜索词 **替代方案考虑**: - 方案A:直接翻译分类名称 → 关键字可能不准确,搜索结果相关性低 - 方案B:硬编码关键字映射表 → 维护成本高,不灵活 - 方案C:用户手动输入关键字 → 增加用户操作负担 ### 3. 图标持久化到数据库而非实时搜索 **决策**: 将检索到的图标保存到数据库,避免重复搜索 **理由**: - 减少对Iconify API的调用次数,降低依赖风险 - 提高图标获取速度(从数据库读取比API调用快) - 可以记录每个图标使用的搜索关键字,便于后续分析和优化 - 避免重复存储相同图标,节省存储空间 **替代方案考虑**: - 方案A:每次都实时调用Iconify API → 依赖性强,API可能限流或中断 - 方案B:使用缓存(如Redis) → 缓存可能过期,需要处理缓存失效逻辑 - 方案C:前端缓存图标 → 无法跨设备同步,数据不一致 ### 4. 修改TransactionCategory实体 **决策**: 修改TransactionCategory.Icon字段,从存储SVG格式改为存储Iconify图标标识符;新增IconKeywords字段 **理由**: - 现有的TransactionCategory表已有Icon字段,无需创建新表 - 存储Iconify标识符(如"mdi:home")比存储SVG字符串更简洁 - 新增IconKeywords字段记录AI生成的搜索关键字,便于后续分析和重新搜索 **字段修改**: ```csharp public class TransactionCategory : BaseEntity { /// /// 图标(Iconify标识符格式:{collection}:{name},如"mdi:home") /// [Column(StringLength = 50)] public string? Icon { get; set; } /// /// 搜索关键字(JSON数组,如["food", "restaurant", "dining"]) /// [Column(StringLength = 200)] public string? IconKeywords { get; set; } } ``` **数据库迁移**: - 添加IconKeywords字段(可选,如果不需要记录关键字则跳过) - 修改Icon字段长度限制(从-1改为50) ### 5. AI搜索关键字生成服务 **决策**: 使用Semantic Kernel或OpenAI API生成搜索关键字 **理由**: - 项目已集成Semantic Kernel,复用现有基础设施 - AI能够理解中文分类名称的语义,生成准确的英文关键字 - 可以配置生成的关键字数量(如3-5个) **实现方案**: - 使用Semantic Kernel的Text Generation功能 - Prompt模板:`为以下中文分类名称生成3-5个相关的英文搜索关键字,用于搜索图标:{categoryName}。输出格式为JSON数组。` ### 6. Iconify API调用格式 **决策**: 使用Iconify搜索API `https://api.iconify.design/search?query=&limit=` **理由**: - Iconify官方API,稳定可靠 - 响应速度快,支持批量查询 - 返回数据结构清晰,包含图标集名称和图标名称 **响应数据格式**: ```json { "icons": [ { "name": "home", "collection": { "name": "mdi" } } ] } ``` **图标渲染标识符**: `mdi:home`(图标集名称:图标名称) ## Risks / Trade-offs ### 风险1:Iconify API限流或中断 **风险**: Iconify API可能限流或服务中断,导致无法检索图标 **缓解措施**: - 实现API调用重试机制(指数退避) - 记录API调用失败日志,监控API可用性 - 如果API长时间不可用,提供备选方案(如使用已缓存的图标) ### 风险2:AI生成搜索关键字不准确 **风险**: AI生成的搜索关键字可能不准确,导致检索到的图标与分类不相关 **缓解措施**: - 优化AI Prompt,提供更多上下文信息 - 提供人工审核接口,允许用户修改或补充搜索关键字 - 基于用户反馈不断优化AI Prompt ### 风险3:图标数量过多导致前端性能问题 **风险**: 某个分类可能关联大量图标,导致前端渲染性能下降 **缓解措施**: - 前端分页加载图标(如每页显示10-20个) - 提供图标搜索功能,允许用户过滤图标 - 图标懒加载,仅在可见区域渲染图标 ### 风险4:Iconify API返回的图标不匹配分类 **风险**: AI生成的搜索关键字可能不准确,导致Iconify API返回的图标与分类不相关 **缓解措施**: - 优化AI Prompt,提供更多上下文信息 - 提供用户选择界面,允许用户从多个图标中选择最合适的 - 支持用户手动输入Iconify图标标识符(如"mdi:home") ### 权衡1:实时搜索 vs 数据库存储 **选择**: 数据库存储 **权衡**: 数据库存储需要额外的存储空间,但减少了API调用,提高性能 ### 权衡:AI生成关键字 vs 硬编码映射表 **选择**: AI生成关键字 **权衡**: AI生成关键字增加了API调用成本,但更灵活,覆盖范围更广 ## Migration Plan ### 部署步骤 1. **数据库迁移** - 执行SQL脚本添加TransactionCategory.IconKeywords字段(可选) - 修改TransactionCategory.Icon字段长度限制(从-1改为50) 2. **代码部署** - 修改Entity层(TransactionCategory实体) - 部署Service层(IconSearchService) - 部署WebApi层(IconController) - 更新前端图标渲染逻辑(使用Iconify图标组件) 3. **数据迁移** - 为现有分类生成搜索关键字 - 允许用户为现有分类选择新图标 4. **验证** - 测试API接口(搜索关键字生成、图标搜索、更新分类图标) - 测试前端图标渲染 - 性能测试(Iconify API调用速度) ### 回滚策略 - 如果新系统出现问题,可以回滚到旧的AI生成SVG图标逻辑 - 保留旧代码分支,确保回滚时可以使用 - IconKeywords字段可以保留,不影响回滚 ## Open Questions 1. **AI搜索关键字生成的准确性** - 问题: 如何评估AI生成的搜索关键字是否准确? - 解决方案: 可以先进行小规模测试,人工评估关键字质量,再逐步扩大范围 2. **Iconify API调用量限制** - 问题: Iconify API是否有调用量限制?是否需要付费? - 解决方案: 需要查阅Iconify API文档,确认限流策略和费用 3. **前端图标渲染性能** - 问题: 大量图标渲染是否会影响前端性能? - 解决方案: 需要进行性能测试,必要时使用虚拟滚动或分页加载 4. **图标更新策略** - 问题: Iconify图标库更新后,如何同步更新系统中的图标? - 解决方案: 可以定期运行同步任务,或提供手动刷新接口