173 lines
2.5 KiB
PHP
173 lines
2.5 KiB
PHP
<?php
|
||
|
||
|
||
|
||
namespace app\service;
|
||
|
||
|
||
|
||
use app\model\Department;
|
||
|
||
use app\model\User;
|
||
|
||
|
||
|
||
class DepartmentService
|
||
|
||
{
|
||
|
||
/**
|
||
|
||
* 获取部门及其所有下级部门 ID(含自身)。
|
||
|
||
*
|
||
|
||
* @return int[]
|
||
|
||
*/
|
||
|
||
public static function descendantIds(int $departmentId): array
|
||
|
||
{
|
||
|
||
$all = Department::field('id,parent_id')->select()->toArray();
|
||
|
||
$childrenMap = [];
|
||
|
||
foreach ($all as $row) {
|
||
|
||
$parentId = (int) ($row['parent_id'] ?? 0);
|
||
|
||
$childrenMap[$parentId][] = (int) $row['id'];
|
||
|
||
}
|
||
|
||
|
||
|
||
$result = [];
|
||
|
||
$stack = [$departmentId];
|
||
|
||
while ($stack) {
|
||
|
||
$current = array_pop($stack);
|
||
|
||
if (in_array($current, $result, true)) {
|
||
|
||
continue;
|
||
|
||
}
|
||
|
||
$result[] = $current;
|
||
|
||
foreach ($childrenMap[$current] ?? [] as $childId) {
|
||
|
||
$stack[] = $childId;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
return $result;
|
||
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
|
||
* 构建带层级缩进的部门树(扁平列表,供下拉选择)。
|
||
|
||
*/
|
||
|
||
public static function treeOptions(): array
|
||
|
||
{
|
||
|
||
$rows = Department::order('sort_order')->order('id')->select()->toArray();
|
||
|
||
$childrenMap = [];
|
||
|
||
foreach ($rows as $row) {
|
||
|
||
$parentId = (int) ($row['parent_id'] ?? 0);
|
||
|
||
$childrenMap[$parentId][] = $row;
|
||
|
||
}
|
||
|
||
|
||
|
||
$options = [];
|
||
|
||
self::walkTree($childrenMap, 0, 0, $options);
|
||
|
||
|
||
|
||
return $options;
|
||
|
||
}
|
||
|
||
|
||
|
||
private static function walkTree(array $childrenMap, int $parentId, int $depth, array &$options): void
|
||
|
||
{
|
||
|
||
foreach ($childrenMap[$parentId] ?? [] as $row) {
|
||
|
||
$prefix = $depth > 0 ? str_repeat(' ', $depth) . '└ ' : '';
|
||
|
||
$options[] = [
|
||
|
||
'id' => (int) $row['id'],
|
||
|
||
'name' => $row['name'],
|
||
|
||
'parent_id' => $row['parent_id'] ? (int) $row['parent_id'] : null,
|
||
|
||
'label' => $prefix . $row['name'],
|
||
|
||
'depth' => $depth,
|
||
|
||
];
|
||
|
||
self::walkTree($childrenMap, (int) $row['id'], $depth + 1, $options);
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
|
||
* 获取某部门及下级部门内的所有用户 ID。
|
||
|
||
*
|
||
|
||
* @return int[]
|
||
|
||
*/
|
||
|
||
public static function userIdsInDepartments(array $departmentIds): array
|
||
|
||
{
|
||
|
||
if (empty($departmentIds)) {
|
||
|
||
return [];
|
||
|
||
}
|
||
|
||
|
||
|
||
return User::whereIn('department_id', $departmentIds)->column('id');
|
||
|
||
}
|
||
|
||
}
|
||
|