import { AadHttpClient, HttpClientResponse } from '@microsoft/sp-http'; import { WebPartContext } from '@microsoft/sp-webpart-base'; import { APPROVAL_API_CLIENT_ID, DICTIONARY_API_BASE_URL } from '../config'; import { IStorageLike, readCachedCompanies, writeCachedCompanies } from './companiesCache'; import { ICompany } from './models/ICompany'; // GET /Dictionary/Companies — справочник компаний, ответ — плоский массив // { Id, Name, Bin } (без обёртки, как /Dictionary/Departments). async function fetchCompanies(context: WebPartContext): Promise { const client = await context.aadHttpClientFactory.getClient(APPROVAL_API_CLIENT_ID); const response: HttpClientResponse = await client.get( `${DICTIONARY_API_BASE_URL}/Dictionary/Companies`, AadHttpClient.configurations.v1 ); if (!response.ok) { throw new Error(`Dictionary/Companies: ${response.status} ${response.statusText}`); } return response.json(); } /** localStorage, если он есть: в некоторых режимах браузера обращение к нему бросает исключение. */ function browserStorage(): IStorageLike | undefined { try { return window.localStorage; } catch { return undefined; } } async function loadCompanies(context: WebPartContext): Promise { const storage = browserStorage(); const cached = storage ? readCachedCompanies(storage, Date.now()) : undefined; if (cached) return cached; const fresh = await fetchCompanies(context); if (storage) writeCachedCompanies(storage, fresh, Date.now()); return fresh; } // Справочник живёт в localStorage 4 часа (см. companiesCache.ts) — между перезагрузками страницы // к API не ходим. Поверх этого один промис на сессию: параллельные вызовы делят один запрос и не // читают хранилище заново (как в departments.service). Ошибку не кешируем — следующий вызов // попробует ещё раз. let cache: Promise | undefined; export function getCompanies(context: WebPartContext): Promise { if (!cache) { cache = loadCompanies(context).catch((e) => { cache = undefined; throw e; }); } return cache; }