Files
request-portal/src/webparts/requestPortal/shared/approval/siteUser.ts
T
2026-08-20 16:40:05 +05:00

66 lines
3.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<string, Promise<number>>();
function remember(key: string, load: () => Promise<number>): Promise<number> {
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<number> {
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<number> {
return remember(`ensure|${siteUrl.toLowerCase()}|${claimsLogin.toLowerCase()}`, async () => {
const user = await spForSite(siteUrl, context).web.ensureUser(claimsLogin);
return user.Id;
});
}