import { WebPartContext } from '@microsoft/sp-webpart-base'; import { spForSite } from '../pnp/pnpjs'; import '@pnp/sp/webs'; import '@pnp/sp/site-users/web'; /** * Числовой Id пользователя НА КОНКРЕТНОМ САЙТЕ — с кешом на сессию. * * Зачем: почти все фильтры SharePoint REST по Person-полям строятся по числовому * Id (`AuthorId eq N`, `TansuSiteApproverId eq N`) — фильтр по EMail у Person-поля * ненадёжен. Id свой на каждом сайте, поэтому его приходится резолвить, но * в пределах сессии он не меняется. * * Раньше резолв стоял ВНУТРИ функций, которые вызываются в цикле по типам заявок * (getOwnRowsForType / getRecentlyChangedOwnRowsForType): при восьми типах это * восемь одинаковых GET /_api/web/currentuser подряд, и каждый — лишний * round-trip ПЕРЕД основным запросом. ensureUser в очереди согласования — то же * самое, только POST. * * Ошибку НЕ кешируем: упавший на холодном старте запрос должен повториться, * а не залипнуть до конца сессии (тот же принцип, что у requestTypesPromise * в approvalRoute.service.ts). */ const byKey = new Map>(); function remember(key: string, load: () => Promise): Promise { const pending = byKey.get(key); if (pending) return pending; const promise = load().catch((e) => { byKey.delete(key); throw e; }); byKey.set(key, promise); return promise; } /** Полный сброс — на случай смены личности (отладочная подмена) или реинициализации. */ export function resetSiteUserCache(): void { byKey.clear(); } /** Id ТЕКУЩЕГО (реального) пользователя на сайте. */ export async function currentUserIdFor(context: WebPartContext, siteUrl: string): Promise { return remember(`current|${siteUrl.toLowerCase()}`, async () => { const me = await spForSite(siteUrl, context).web.currentUser.select('Id')(); return me.Id as number; }); } /** * Id пользователя по claims-логину. ensureUser — это POST (он при необходимости * заводит пользователя в коллекции сайта), поэтому повторять его особенно жаль. */ export async function ensureUserIdFor( context: WebPartContext, siteUrl: string, claimsLogin: string ): Promise { return remember(`ensure|${siteUrl.toLowerCase()}|${claimsLogin.toLowerCase()}`, async () => { const user = await spForSite(siteUrl, context).web.ensureUser(claimsLogin); return user.Id; }); }