append(['status_desc']) ->order(['sort' => 'desc', 'id' => 'desc']) ->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')); } return self::getTree($lists, $pid); } /** * 每个部门人数(直属 + 所有下级部门),基于全表部门树汇总;管理员来自 admin_dept,排除已删除账号 * * @return array 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 $deptIds * @return array */ 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 列表树状结构 * @param $array * @param int $pid * @param int $level * @return array * @author 段誉 * @date 2022/5/30 15:44 */ public static function getTree($array, $pid = 0, $level = 0) { $list = []; foreach ($array as $key => $item) { if ($item['pid'] == $pid) { $item['level'] = $level; $item['children'] = self::getTree($array, $item['id'], $level + 1); $list[] = $item; } } return $list; } /** * @notes 上级部门 * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @author 段誉 * @date 2022/5/26 18:36 */ public static function leaderDept() { $lists = Dept::field(['id', 'name'])->where(['status' => 1]) ->order(['sort' => 'desc', 'id' => 'desc']) ->select() ->toArray(); return $lists; } /** * @notes 添加部门 * @param array $params * @author 段誉 * @date 2022/5/25 18:20 */ public static function add(array $params) { Dept::create([ 'pid' => $params['pid'], 'name' => $params['name'], 'leader' => $params['leader'] ?? '', 'mobile' => $params['mobile'] ?? '', 'status' => $params['status'], 'sort' => $params['sort'] ?? 0 ]); } /** * @notes 编辑部门 * @param array $params * @return bool * @author 段誉 * @date 2022/5/25 18:39 */ public static function edit(array $params): bool { try { $pid = $params['pid']; $oldDeptData = Dept::findOrEmpty($params['id']); if ($oldDeptData['pid'] == 0) { $pid = 0; } Dept::update([ 'id' => $params['id'], 'pid' => $pid, 'name' => $params['name'], 'leader' => $params['leader'] ?? '', 'mobile' => $params['mobile'] ?? '', 'status' => $params['status'], 'sort' => $params['sort'] ?? 0 ]); return true; } catch (\Exception $e) { self::setError($e->getMessage()); return false; } } /** * @notes 删除部门 * @param array $params * @author 段誉 * @date 2022/5/25 18:40 */ public static function delete(array $params) { Dept::destroy($params['id']); } /** * @notes 获取部门详情 * @param $params * @return array * @author 段誉 * @date 2022/5/25 18:40 */ public static function detail($params): array { return Dept::findOrEmpty($params['id'])->toArray(); } /** * @notes 部门数据 * @return array * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException * @author 段誉 * @date 2022/10/13 10:19 */ public static function getAllData() { $data = Dept::where(['status' => YesNoEnum::YES]) ->order(['sort' => 'desc', 'id' => 'desc']) ->select() ->toArray(); $pid = min(array_column($data, 'pid')); return self::getTree($data, $pid); } }