diff --git a/apps/server/src/integration/dingtalk.service.ts b/apps/server/src/integration/dingtalk.service.ts index ea6226c..4f3811a 100644 --- a/apps/server/src/integration/dingtalk.service.ts +++ b/apps/server/src/integration/dingtalk.service.ts @@ -258,41 +258,6 @@ export class DingTalkService { return ids; } - /** - * BFS from rootDeptId=1, returns depth of every department. - * Depth is 1-based (root=1). Uses listsubid API only, no detail fetches. - */ - private async getDeptDepthMap(token: string): Promise> { - const depthMap = new Map(); - const queue: Array<{ id: number; depth: number }> = [{ id: 1, depth: 1 }]; - - while (queue.length > 0) { - const { id, depth } = queue.shift()!; - depthMap.set(id, depth); - - try { - await this.rateLimit(); - const res = await fetch( - `https://oapi.dingtalk.com/topapi/v2/department/listsubid?access_token=${token}`, - { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ dept_id: id }), - }, - ); - const body: SubDeptIdListResponse = await res.json(); - if (body.errcode === 0 && body.result?.dept_id_list) { - for (const childId of body.result.dept_id_list) { - queue.push({ id: childId, depth: depth + 1 }); - } - } - } catch (e) { - this.logger.error(`getDeptDepthMap 获取部门 ${id} 子部门失败: ${(e as Error).message}`); - } - } - - return depthMap; - } // ═══════════════════════════════════════════ // Department detail @@ -511,36 +476,21 @@ export class DingTalkService { } const token = await this.getAccessToken(); - // Compute global depth map (always from rootDeptId=1) - const depthMap = await this.getDeptDepthMap(token); - const maxDepth = Math.max(...depthMap.values()); - - // Get subtree IDs for the user's selected root - const subtreeIds = await this.getAllDeptIds(token, rootDeptId); - - // Filter: only keep departments at the deepest 2 levels of the global tree - const filteredIds = subtreeIds.filter((id) => { - const d = depthMap.get(id) ?? -1; - return d === maxDepth || d === maxDepth - 1; - }); - - if (filteredIds.length === 0) { - return []; - } + const deptIds = await this.getAllDeptIds(token, rootDeptId); // 拉每个部门详情 const nodes: DingOrgTreeNodeWithUsers[] = []; // Before dedup: collect deptIds per user const userDeptMap = new Map(); - for (let i = 0; i < filteredIds.length; i++) { + for (let i = 0; i < deptIds.length; i++) { if (i > 0) await this.delay(i); - const detail = await this.getDeptDetail(token, filteredIds[i]); + const detail = await this.getDeptDetail(token, deptIds[i]); if (!detail) continue; // 拉该部门下的用户 - const dingUsers = await this.getDeptUsers(token, filteredIds[i]); - this.logger.log(`[dingtalk] dept ${filteredIds[i]} (${detail.name}): ${dingUsers.length} users`); + const dingUsers = await this.getDeptUsers(token, deptIds[i]); + this.logger.log(`[dingtalk] dept ${deptIds[i]} (${detail.name}): ${dingUsers.length} users`); nodes.push({ id: detail.dept_id, @@ -585,7 +535,7 @@ export class DingTalkService { const roots: DingOrgTreeNodeWithUsers[] = []; for (const node of nodes) { const parent = map.get(node.parentId); - if (parent) { + if (parent && node.id !== rootDeptId) { parent.children.push(node); } else { roots.push(node);