兼容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.

183 lines
6.8 KiB

using AIK.Common.Interface;
using AIK.Models.BannerModels;
using AIK.Service.IService;
using AIK.Service.Service;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
namespace AIK.ViewModels.HomePage
{
public partial class HomePageViewModel : ObservableObject
{
private readonly DispatcherTimer _timer;
[ObservableProperty]
[NotifyPropertyChangedFor(nameof(IsFirst))]
[NotifyPropertyChangedFor(nameof(IsLast))]
private int _currentIndexPublic = -1;
public bool IsFirst => CurrentIndexPublic == 0;
[ObservableProperty]
private string _currentImagePath;
[ObservableProperty]
private BitmapImage _currentBitmapImage;
public bool IsLast => Banners.Count > 0 && CurrentIndexPublic == Banners.Count - 1;
public ObservableCollection<BannerItem> Banners { get; } = new ObservableCollection<BannerItem>();
private readonly IConfigurationService _configurationService;
private readonly IQRCodeService _qRCodeService;
//国内版
private string defaultLogoPath = "AIK.Assets.Images.AIKChina.png";
//国外版
//private const string defaultLogoPath = "AIK.Assets.Images.AIKInternationl.png";
[ObservableProperty]
private byte[]? _qrCodeBytes; // 👈 只暴露字节数组
private readonly IAikDataService _aikDataService;
private readonly IImageCacheService _imageCacheService;
public HomePageViewModel(IConfigurationService configurationService, IQRCodeService qRCodeService, IAikDataService aikDataService, IImageCacheService imageCacheService)
{
#if CN
defaultLogoPath = "AIK.Assets.Images.AIKChina.png";
#elif TEST
defaultLogoPath = "AIK.Assets.Images.AIKChina.png";
#else
defaultLogoPath = "AIK.Assets.Images.AIKInternationl.png";
#endif
_configurationService = configurationService;
_qRCodeService = qRCodeService;
_aikDataService = aikDataService;
_imageCacheService = imageCacheService;
//LoadLocalBanners();
_ = LoadRemoteBanners();
LoadQrCodeImage();
if (Banners.Count > 0)
{
CurrentIndexPublic = 0;
}
_timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(5) };
_timer.Tick += OnTimerTick;
_timer.Start();
}
partial void OnCurrentIndexPublicChanged(int value)
{
if (Banners.Count == 0) return;
// 边界保护
if (value < 0 || value >= Banners.Count) return;
for (int i = 0; i < Banners.Count; i++)
{
Banners[i].IsSelected = (i == value);
if (Banners[i].IsSelected)
{
CurrentImagePath = Banners[i].ImagePath!;
CurrentBitmapImage = Banners[i].BitmapImage!;
}
}
//_timer.Stop();
//_timer.Start(); // 重置自动轮播
}
private void LoadQrCodeImage()
{
QrCodeBytes = _qRCodeService.GenerateQRCodeWithLogo(_configurationService.ApiSettings.QRCodeUrl, defaultLogoPath, 12);
}
private void LoadLocalBanners()
{
// 修改为你的实际图片文件夹路径(相对路径)
string imageFolder = @"C:\Users\23231\Desktop\Images";
if (!Directory.Exists(imageFolder)) return;
var validExtensions = new[] { ".jpg", ".jpeg", ".png", ".bmp", ".gif" };
var imageFiles = Directory.GetFiles(imageFolder)
.Where(f => validExtensions.Contains(Path.GetExtension(f).ToLowerInvariant()))
.OrderBy(f => f) // 可按需排序
.ToList();
for (int i = 0; i < imageFiles.Count; i++)
{
try
{
Banners.Add(new BannerItem { ImagePath = imageFiles[i], Index = i });
}
catch (Exception ex)
{
// 可记录日志或跳过损坏图片
System.Diagnostics.Debug.WriteLine($"Failed to load image {imageFiles[i]}: {ex.Message}");
}
}
}
private async Task LoadRemoteBanners()
{
try
{
var bannerlist = await _aikDataService.GetBannerCache();
//var bannerlist = await _aikDataService.GetBanner();
int i = 0;
foreach (var item in bannerlist)
{
if (!string.IsNullOrEmpty(item.ImgUrl))
{
var start = DateTime.Now;
var localbitmapImage = await _imageCacheService.GetImageByLocalPathAsync(item.ImgUrl);
Banners.Add(new BannerItem { BitmapImage = localbitmapImage, ImagePath = item.ImgUrl, Index = i++ });
var loaded = DateTime.Now;
Debug.WriteLine($"Loaded: {(loaded - start).TotalMilliseconds}ms");
}
}
if (Banners.Count > 0 && CurrentIndexPublic < 0)
{
CurrentIndexPublic = 0;
}
}
catch (Exception ex)
{
// fire-and-forget 任务(_ = LoadRemoteBanners())必须捕获异常,
// 否则异常会成为"未观察任务异常"(终结器线程重新抛出,App 记录 Task未观察异常)。
// Banner 加载失败(如网络/TLS 问题)不应影响主流程。
Debug.WriteLine($"加载远程Banner失败: {ex.Message}");
}
}
private void OnTimerTick(object? sender, EventArgs e)
{
if (Banners.Count == 0) return;
CurrentIndexPublic = (CurrentIndexPublic + 1) % Banners.Count;
}
[RelayCommand]
private void Previous()
{
if (Banners.Count == 0) return;
CurrentIndexPublic = (CurrentIndexPublic - 1 + Banners.Count) % Banners.Count;
}
[RelayCommand]
private void Next()
{
if (Banners.Count == 0) return;
CurrentIndexPublic = (CurrentIndexPublic + 1) % Banners.Count;
}
[RelayCommand]
private void SelectBanner(int index) => CurrentIndexPublic = index;
}
}