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.
171 lines
6.5 KiB
171 lines
6.5 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");
|
|
}
|
|
}
|
|
}
|
|
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() => CurrentIndexPublic = (CurrentIndexPublic - 1 + Banners.Count) % Banners.Count;
|
|
|
|
[RelayCommand]
|
|
private void Next() => CurrentIndexPublic = (CurrentIndexPublic + 1) % Banners.Count;
|
|
|
|
[RelayCommand]
|
|
private void SelectBanner(int index) => CurrentIndexPublic = index;
|
|
}
|
|
|
|
}
|
|
|