Прайс: загрузка всего прайса постранично (limit/offset вместо потолка 5000) — локальный поиск теперь находит все позиции

This commit is contained in:
Magomed 2026-07-17 12:56:41 +03:00
parent a6601567f2
commit cdfd8353ec
2 changed files with 53 additions and 15 deletions

View File

@ -97,7 +97,7 @@ namespace Электронная_Фармация.Classes
public bool IsAuthenticated => !string.IsNullOrEmpty(_token);
public async Task<PriceSummaryResponse> GetPriceSummaryAsync(string supplierId = null, string regionId = null)
public async Task<PriceSummaryResponse> GetPriceSummaryAsync(string supplierId = null, string regionId = null, string q = null, int? limit = null, int? offset = null)
{
EnsureAuthenticated();
@ -110,6 +110,18 @@ namespace Электронная_Фармация.Classes
{
queryParams.Add($"region_id={Uri.EscapeDataString(regionId)}");
}
if (!string.IsNullOrWhiteSpace(q))
{
queryParams.Add($"q={Uri.EscapeDataString(q)}");
}
if (limit.HasValue)
{
queryParams.Add($"limit={limit.Value}");
}
if (offset.HasValue)
{
queryParams.Add($"offset={offset.Value}");
}
var path = "/api/supplier-prices/summary";
if (queryParams.Count > 0)

View File

@ -38,8 +38,8 @@ namespace Электронная_Фармация.HelpForms
{
await EnsureAuthenticatedAsync(client);
AppendStatus("Загружаю сводный прайс для всех поставщиков...");
var allSuppliersSummary = await GetPriceSummaryWithRetryAsync(client);
AppendStatus("Загружаю сводный прайс (постранично, весь)...");
var allSuppliersSummary = await GetFullPriceSummaryPagedAsync(client);
AppendStatus($"Получено {allSuppliersSummary.Summary?.Count ?? 0} позиций");
var tablePrice = BuildPriceTable(allSuppliersSummary);
@ -98,25 +98,51 @@ namespace Электронная_Фармация.HelpForms
AppendStatus("Авторизация успешно пройдена");
}
private async Task<PriceSummaryResponse> GetPriceSummaryWithRetryAsync(ApiClient client)
// Тянем весь прайс постранично: сервер отдаёт максимум 5000 за запрос,
// поэтому идём offset'ом, пока страница не окажется неполной.
private async Task<PriceSummaryResponse> GetFullPriceSummaryPagedAsync(ApiClient client)
{
var regionId = string.IsNullOrWhiteSpace(Settings.Default.RegionId)
? null
: Settings.Default.RegionId;
try
const int pageSize = 5000;
const int maxPages = 100; // страховка от бесконечного цикла (до 500k позиций)
var combined = new PriceSummaryResponse { Summary = new List<PriceSummaryItem>() };
for (int page = 0; page < maxPages; page++)
{
return await client.GetPriceSummaryAsync(supplierId: null, regionId: regionId);
}
catch (UnauthorizedAccessException)
{
AppendStatus("Токен недействителен, повторная авторизация...");
Settings.Default.stringToken = string.Empty;
Settings.Default.Save();
client.SetToken(null);
await LoginAndSaveTokenAsync(client);
return await client.GetPriceSummaryAsync(supplierId: null, regionId: regionId);
int offset = page * pageSize;
PriceSummaryResponse chunk;
try
{
chunk = await client.GetPriceSummaryAsync(supplierId: null, regionId: regionId, limit: pageSize, offset: offset);
}
catch (UnauthorizedAccessException)
{
AppendStatus("Токен недействителен, повторная авторизация...");
Settings.Default.stringToken = string.Empty;
Settings.Default.Save();
client.SetToken(null);
await LoginAndSaveTokenAsync(client);
chunk = await client.GetPriceSummaryAsync(supplierId: null, regionId: regionId, limit: pageSize, offset: offset);
}
int got = chunk?.Summary?.Count ?? 0;
if (got > 0)
{
combined.Summary.AddRange(chunk.Summary);
AppendStatus($"Загружено {combined.Summary.Count} позиций...");
}
if (got < pageSize)
{
break; // последняя (неполная) страница — дальше данных нет
}
}
return combined;
}
private static DataTable BuildPriceTable(PriceSummaryResponse allSuppliersSummary)