using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Elfisa.Core; namespace Elfisa.Avalonia.ViewModels; /// «Загрузить» — скачивание актуального прайса с сервера в память. public partial class LoadPriceViewModel : ViewModelBase { private readonly ApiClient _api = new(); [ObservableProperty] private bool _busy; [ObservableProperty] private double _progress; // 0..100 [ObservableProperty] private string _progressText = ""; [ObservableProperty] private string? _result; public string LastLoaded => PriceCache.LoadedAt is { } dt ? $"Последняя загрузка: {dt:dd.MM.yyyy HH:mm} — {PriceCache.Items.Count} позиций" : "Прайс ещё не загружался в этой сессии."; public LoadPriceViewModel() { _api.SetToken(Session.Current.Token); } [RelayCommand] private async Task LoadAsync() { Result = null; try { Busy = true; Progress = 0; ProgressText = "Соединение с сервером…"; var all = new List(); const int page = 500; int offset = 0, total = 0; while (true) { var resp = await _api.GetPriceSummaryAsync(null, limit: page, offset: offset); var batch = resp.Summary ?? new(); if (resp.TotalDrugs > 0) total = resp.TotalDrugs; all.AddRange(batch); Progress = total > 0 ? Math.Min(100.0, all.Count * 100.0 / total) : 0; ProgressText = total > 0 ? $"Загружено {all.Count} из {total} позиций…" : $"Загружено {all.Count} позиций…"; offset += batch.Count; if (batch.Count < page || (total > 0 && all.Count >= total) || offset > 30000) break; } PriceCache.Items = all; PriceCache.LoadedAt = DateTime.Now; Progress = 100; ProgressText = "Готово."; var suppliers = all.Select(x => x.SupplierName).Where(s => !string.IsNullOrWhiteSpace(s)).Distinct().Count(); Result = $"Прайс загружен: {all.Count} позиций от {suppliers} поставщик(ов)."; OnPropertyChanged(nameof(LastLoaded)); } catch (Exception ex) { Result = "Ошибка загрузки: " + ex.Message; ProgressText = ""; } finally { Busy = false; } } }