This commit is contained in:
Your Name
2026-04-18 15:54:14 +08:00
parent fa3da15228
commit 4097fe0cc6
271 changed files with 1257 additions and 369 deletions
@@ -16,6 +16,8 @@ namespace app\adminapi\logic\dept;
use app\common\enum\YesNoEnum;
use app\common\logic\BaseLogic;
use app\common\model\auth\Admin;
use app\common\model\auth\AdminDept;
use app\common\model\dept\Dept;
@@ -52,6 +54,12 @@ class DeptLogic extends BaseLogic
->select()
->toArray();
$totalsWithSubtree = self::deptAdminCountTotalsWithSubtree();
foreach ($lists as &$row) {
$row['admin_count'] = $totalsWithSubtree[(int) $row['id']] ?? 0;
}
unset($row);
$pid = 0;
if (!empty($lists)) {
$pid = min(array_column($lists, 'pid'));
@@ -59,6 +67,79 @@ class DeptLogic extends BaseLogic
return self::getTree($lists, $pid);
}
/**
* 每个部门人数(直属 + 所有下级部门),基于全表部门树汇总;管理员来自 admin_dept,排除已删除账号
*
* @return array<int, int> dept_id => count
*/
private static function deptAdminCountTotalsWithSubtree(): array
{
$treeRows = Dept::field(['id', 'pid'])->select()->toArray();
if ($treeRows === []) {
return [];
}
$allIds = array_map('intval', array_column($treeRows, 'id'));
$directMap = self::fetchDirectAdminCountMap($allIds);
$childrenByPid = [];
foreach ($treeRows as $r) {
$pid = (int) $r['pid'];
$id = (int) $r['id'];
if (!isset($childrenByPid[$pid])) {
$childrenByPid[$pid] = [];
}
$childrenByPid[$pid][] = $id;
}
$memo = [];
$dfs = function (int $id) use (&$dfs, $childrenByPid, $directMap, &$memo): int {
if (array_key_exists($id, $memo)) {
return $memo[$id];
}
$sum = $directMap[$id] ?? 0;
foreach ($childrenByPid[$id] ?? [] as $cid) {
$sum += $dfs((int) $cid);
}
$memo[$id] = $sum;
return $sum;
};
$out = [];
foreach ($allIds as $id) {
$out[$id] = $dfs($id);
}
return $out;
}
/**
* 各部门直属管理员人数
*
* @param array<int, int> $deptIds
* @return array<int, int>
*/
private static function fetchDirectAdminCountMap(array $deptIds): array
{
if ($deptIds === []) {
return [];
}
$adminTable = (new Admin())->getTable();
$rows = AdminDept::alias('ad')
->join($adminTable . ' a', 'a.id = ad.admin_id')
->whereNull('a.delete_time')
->whereIn('ad.dept_id', $deptIds)
->field('ad.dept_id, COUNT(*) AS admin_count')
->group('ad.dept_id')
->select()
->toArray();
$map = [];
foreach ($rows as $r) {
$map[(int) $r['dept_id']] = (int) $r['admin_count'];
}
return $map;
}
/**
* @notes 列表树状结构