Уже давно использую такой метод:
Код:
// Метод получения пользователей из роли|группы|орг.структуры. Особенности:
// Метод возвращает пользователей из группы с учетом вложенности. Бесконечная рекурсия возможна, но она ограничивается значением limit_nesting (не советую ставить слишком высокое значение)
// Метод также успешно возвращает пользователей из вложенной в группу орг. структуры
// В случае если орг.структура это отдел, метод возвращает всех сотрудников из данного отдела. В случае если это группа или должность, то возвращает только пользователей по данным позициям
// В случае если в роли находится пользователь метод также успешно его вернёт
async function getUsersFromRole(outside_role : Role | UserGroupItemRef | OrganisationStructureItemRef) : Promise<UserItem[]> {
const limit_nesting = 10 // Максимальный уровень вложенности рекурсивных вызовов
//#region Разбиваем переменную типа "Role" на "UserGroupItemRef | OrganisationStructureItemRef" для более удобной работы
let user_component : UserGroupItemRef | OrganisationStructureItemRef
if ((outside_role as any).type === "group" || (outside_role as any).type === "orgstruct" || (outside_role as any).type === "user") { // Это роль - вытягиваем UserGroupItemRef | OrganisationStructureItemRef
let role : Role = (outside_role as any)
if (role.type === "group") {
user_component = (await System.userGroups.search().where((f,g) => g.and(f.__deletedAt.eq(null),f.__id.eq(role.code))).first())!
} else if (role.type === "orgstruct") {
user_component = (await System.organisationStructure.search().where((f,g) => g.and(f.__deletedAt.eq(null),f.__id.eq(role.code))).first())!
} else if (role.type === "user") { // Выход из функции
return await System.users.search().where((f,g) => g.and(f.__status.eq(UserStatus.Active),f.__id.eq(role.code))).all()
}
} else {
user_component = (outside_role as any)
}
//#endregion
//#region Получение пользователей из группы|орг.структуры с применением рекурсии
let users = await async function getUsersFromRoleRecursive(user_component: UserGroupItemRef | OrganisationStructureItemRef,current_nesting:number) {
// Проверка лимитов рекурсивных вызовов
if (current_nesting > limit_nesting) return [];
current_nesting++;
let users : UserItem[] = [];
if (user_component.kind === 'group') { // Группа
let group = (user_component as UserGroupItem)
if (group.data.subOrgunitIds && group.data.subOrgunitIds.length > 0) {
// Получение вложенных групп и орг. структур из группы
let [sub_groups, sub_orgstructs] = (await Promise.all([group.subGroups(),System.organisationStructure.search().where((f,g) => g.and(f.__deletedAt.eq(null),f.__id.in(group.data.subOrgunitIds!))).size(10000).all()]));
// Перебор всех элементов группы
(await Promise.all(group.data.subOrgunitIds.map((sub_element) => {
// Группа
let sub_group_index = sub_groups.map(sub_group => sub_group.id).indexOf(sub_element);
if (sub_group_index != -1) {
return getUsersFromRoleRecursive(sub_groups[sub_group_index],current_nesting);
}
// Орг. структура
let sub_orgstruct_index = sub_orgstructs.map(sub_orgstruct => sub_orgstruct.id).indexOf(sub_element);
if (sub_orgstruct_index != -1) {
return getUsersFromRoleRecursive(sub_orgstructs[sub_orgstruct_index],current_nesting);
}
// Пользователь
return System.users.search().where((f,g) => g.and(f.__status.eq(UserStatus.Active),f.__id.eq(sub_element))).all();
}))).map(sub_users => users = users.concat(sub_users));
}
} else if (user_component.kind === 'orgstruct') { // Орг. структура
let orgstruct = (user_component as OrganisationStructureItem)
if (orgstruct && orgstruct.data.type === "DEPARTMENT") { // Если выбран отдел, то включаем всех сотрудников из отдела
let children_orgstructs = getChildrenOrgs(orgstruct);
users = await System.users.search().where((f,g) => {
let orgstruct_filters : Filter[] = []
children_orgstructs.forEach(children_orgstruct => {
orgstruct_filters.push(f.osIds.has(children_orgstruct))
})
return g.and(f.__status.eq(UserStatus.Active),g.or(...orgstruct_filters))
}).size(10000).all()
} else if (orgstruct) { // Если выбрана группа или должность, то включаем только их
users = users.concat(await System.users.search().where((f,g) => g.and(f.__status.eq(UserStatus.Active),f.osIds.has(orgstruct!))).size(10000).all());
}
}
return users;
}(user_component!,0)
//#endregion
return users;
}
// Получение дочерних орг.структур
function getChildrenOrgs(orgItem : OrganisationStructureItem) : OrganisationStructureItem[] {
let childrenIDs : OrganisationStructureItem[] = []
for (let childrenOrgItem of orgItem.getChildren()) {
if (childrenOrgItem.getChildren().length > 0) {
childrenIDs = childrenIDs.concat(getChildrenOrgs(childrenOrgItem))
}
childrenIDs.push(childrenOrgItem)
}
return childrenIDs
}
И использование:
Код:
const someGroup = await System.userGroups.search().where(f => f.__name.eq("Какая-то группа")).first()
if (someGroup ) {
const users = await getUsersFromRole(someGroup)
}