Прайс: загрузка всего прайса постранично (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 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(); EnsureAuthenticated();
@ -110,6 +110,18 @@ namespace Электронная_Фармация.Classes
{ {
queryParams.Add($"region_id={Uri.EscapeDataString(regionId)}"); 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"; var path = "/api/supplier-prices/summary";
if (queryParams.Count > 0) if (queryParams.Count > 0)

View File

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