兼容win7版应用
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

154 lines
5.8 KiB

using AIK.Common.Language;
using AIK.Models;
using AIK.Models.ApiModels.Record;
using AIK.Service.IService;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using HidSharp.Utility;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
namespace AIK.ViewModels.UserKeyRecord
{
public partial class UserKeyRecordViewModel : ObservableObject
{
private readonly IAikDataService _aikDataService;
private readonly IDataCacheService _dataCacheService;
private readonly IImageCacheService _imageCacheService;
private readonly ILogger<UserKeyRecordViewModel> _logger;
[ObservableProperty]
private ObservableCollection<RecordModel> _records = new();
[ObservableProperty]
private int currentIndex = 1;
[ObservableProperty]
private int size = 20;
[ObservableProperty]
private bool isShowLoadMore = true;
[ObservableProperty]
private string notMoreTip = "没有更多记录了~";
public UserKeyRecordViewModel(IAikDataService aikDataService, IDataCacheService dataCacheService, IImageCacheService imageCacheService, ILogger<UserKeyRecordViewModel> logger)
{
_aikDataService = aikDataService;
_dataCacheService = dataCacheService;
_imageCacheService = imageCacheService;
_logger = logger;
_ = LoadUserKeyRecordsAsync();
}
private async Task LoadUserKeyRecordsAsync()
{
var token = await _dataCacheService.GetLatestUserTokenAsync();
if (!string.IsNullOrEmpty(token))
{
var result = await _aikDataService.GetKeyLogList(token);
if (result != null)
{
Records = new ObservableCollection<RecordModel>(result.Records);
if (result.Total == result.Records.Count)
{
IsShowLoadMore = false;
NotMoreTip = AiKLanguage.LanguageKey.GetValueOrDefault("NotMoreTips");
}
if (Records != null)
{
_ = LoadImagesPathAsync(result.Records);
}
}
}
}
private async Task LoadImagesPathAsync(List<RecordModel> items, CancellationToken cancellationToken = default)
{
try
{
var itemsWithImages = items.Where(keym => !string.IsNullOrEmpty(keym.Img)).ToList();
// 使用信号量限制并发数量
var semaphore = new SemaphoreSlim(initialCount: 5, maxCount: 5);
var imageTasks = itemsWithImages.Select(async keym =>
{
await semaphore.WaitAsync(cancellationToken);
try
{
cancellationToken.ThrowIfCancellationRequested();
var imageUrl = keym.Img;
var localiamgepath = await _imageCacheService.GetImagePathAsync(imageUrl, null, cancellationToken);
if (!string.IsNullOrEmpty(localiamgepath))
{
await Application.Current.Dispatcher.InvokeAsync(() =>
{
keym.LocalImagePath = localiamgepath;
}, System.Windows.Threading.DispatcherPriority.Background);
}
}
catch (OperationCanceledException)
{
// 单个图片加载被取消,静默处理
_logger.LogDebug("图片加载被取消: {ImageUrl}", keym.Img);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "加载图片失败: {ImageUrl}", keym.Img);
}
finally
{
semaphore.Release();
}
});
await Task.WhenAll(imageTasks);
}
catch (OperationCanceledException)
{
_logger.LogInformation("图片加载操作被取消");
// 不需要重新抛出,这是正常的取消操作
}
catch (Exception ex)
{
_logger.LogError(ex, "加载图片时发生错误");
throw;
}
}
#region 页面方法
[RelayCommand]
private async Task LoadMore()
{
CurrentIndex++;
var token = await _dataCacheService.GetLatestUserTokenAsync();
if (!string.IsNullOrEmpty(token))
{
var result = await _aikDataService.GetKeyLogList(token, CurrentIndex, Size);
if (result != null)
{
if (result.Records != null)
{
if (result.Records.Count > 0)
{
foreach (var item in result.Records)
{
Records.Add(item);
}
_ = LoadImagesPathAsync(result.Records);
}
else
{
IsShowLoadMore = false;
NotMoreTip = AiKLanguage.LanguageKey.GetValueOrDefault("NotMoreTips");
}
}
}
}
}
#endregion
}
}