- 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
49 lines
1.6 KiB
C#
49 lines
1.6 KiB
C#
namespace Service.IconSearch;
|
||
|
||
public class IconSearchService(
|
||
ISearchKeywordGeneratorService keywordGeneratorService,
|
||
IIconifyApiService iconifyApiService,
|
||
ITransactionCategoryRepository categoryRepository,
|
||
ILogger<IconSearchService> logger
|
||
) : IIconSearchService
|
||
{
|
||
public async Task<List<string>> GenerateSearchKeywordsAsync(string categoryName)
|
||
{
|
||
var keywords = await keywordGeneratorService.GenerateKeywordsAsync(categoryName);
|
||
return keywords;
|
||
}
|
||
|
||
public async Task<List<IconCandidate>> SearchIconsAsync(List<string> keywords, int limit = 20)
|
||
{
|
||
if (keywords == null || keywords.Count == 0)
|
||
{
|
||
logger.LogWarning("搜索关键字为空");
|
||
return [];
|
||
}
|
||
|
||
var icons = await iconifyApiService.SearchIconsAsync(keywords, limit);
|
||
logger.LogInformation("搜索到 {Count} 个图标候选", icons.Count);
|
||
return icons;
|
||
}
|
||
|
||
public async Task UpdateCategoryIconAsync(long categoryId, string iconIdentifier)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(iconIdentifier))
|
||
{
|
||
throw new ArgumentException("图标标识符不能为空", nameof(iconIdentifier));
|
||
}
|
||
|
||
var category = await categoryRepository.GetByIdAsync(categoryId);
|
||
if (category == null)
|
||
{
|
||
throw new Exception($"分类不存在,ID:{categoryId}");
|
||
}
|
||
|
||
category.Icon = iconIdentifier;
|
||
category.IconKeywords = null;
|
||
await categoryRepository.UpdateAsync(category);
|
||
|
||
logger.LogInformation("更新分类 {CategoryId} 的图标为 {IconIdentifier}", categoryId, iconIdentifier);
|
||
}
|
||
}
|