63 lines
1.8 KiB
Markdown
63 lines
1.8 KiB
Markdown
# 组织同步 Drawer 只展示最深两层
|
||
|
||
**日期**:2026-07-09
|
||
**范围**:后端 `DingTalkService.fetchOrgTreeWithUsers` + 前端 `IntegrationConfig` Drawer
|
||
|
||
## 需求
|
||
|
||
钉钉组织架构树可能很深(5+ 层),「同步用户」Drawer 中只展示整棵树的最深两层,减少噪音和 API 调用。
|
||
|
||
- 深度以 rootDeptId=1 的全局树为准
|
||
- 最深两层 = depth ∈ [maxDepth-1, maxDepth]
|
||
- `fetchOrgTree`(dept picker)不变
|
||
- `syncAll` 同步逻辑不变
|
||
|
||
## 方案
|
||
|
||
### 后端:`DingTalkService`
|
||
|
||
#### 新增 `getDeptDepthMap(token)`
|
||
|
||
```typescript
|
||
// BFS 从 rootDeptId=1 出发,返回 Map<deptId, depth(1-based)>
|
||
private async getDeptDepthMap(token: string): Promise<Map<number, number>>
|
||
```
|
||
|
||
不调 `getDeptDetail`,仅用 `listsubid` API 遍历树。
|
||
|
||
#### 修改 `fetchOrgTreeWithUsers(rootDeptId)`
|
||
|
||
```
|
||
depthMap = getDeptDepthMap(token) // 全局深度
|
||
maxDepth = max(depthMap.values())
|
||
subtree = getAllDeptIds(token, rootDeptId) // 子树范围
|
||
filtered = subtree.filter(d => depthMap.get(d) ∈ [maxDepth-1, maxDepth])
|
||
|
||
for each filtered: getDeptDetail + getDeptUsers
|
||
assemble tree(父节点不在 filtered 中的提升为根)
|
||
```
|
||
|
||
#### 边界
|
||
|
||
|情况|行为|
|
||
|---|---|
|
||
|树只有 1 层|取 depth=1,展示根部门|
|
||
|树 2 层|取 depth=1,2,展示全部(和现在一致)|
|
||
|子树最深层 < maxDepth-1|返回空数组|
|
||
|中间层有用户|不展示(被裁剪)|
|
||
|
||
### 前端
|
||
|
||
零改动。返回数据仍是 `DingOrgTreeNodeWithUsers[]`,只是节点变少。空树时现有 `<Spin />` 兜底。
|
||
|
||
## 不受影响
|
||
|
||
- `fetchOrgTree` — dept picker 仍显示完整树
|
||
- `syncAll` — 同步全部部门
|
||
- `getAllDeptIds` / `getDeptDetail` / `getDeptUsers` — 不变
|
||
|
||
## 改动量
|
||
|
||
- `dingtalk.service.ts`:约 30 行(新方法 + 改旧方法)
|
||
- 前端:0 行
|