@lark-apaas/coding-steering 0.1.6-alpha.7 → 0.1.6-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/steering/design-stack/skills/.gitkeep +0 -0
- package/steering/nestjs-react-fullstack/skills/authz-guide/SKILL.md +174 -0
- package/steering/nestjs-react-fullstack/skills/authz-guide/references/dynamic-permission-guide.md +621 -0
- package/steering/nestjs-react-fullstack/skills/authz-guide/references/management-page-spec.md +505 -0
- package/steering/nestjs-react-fullstack/skills/authz-guide/references/runtime-role-controller-spec.md +203 -0
- package/steering/nestjs-react-fullstack/skills/authz-guide/references/sdk-examples.md +90 -0
- package/steering/nestjs-react-fullstack/skills/authz-guide/references/sdk-types.md +216 -0
- package/steering/nestjs-react-fullstack/skills/client-builtins-file-storage-service/SKILL.md +405 -0
- package/steering/nestjs-react-fullstack/skills/devops-guide/SKILL.md +119 -0
- package/steering/nestjs-react-fullstack/skills/plugin-guide/SKILL.md +582 -0
- package/steering/nestjs-react-fullstack/skills/plugin-guide/references/plugin-coding-guide.md +357 -0
- package/steering/nestjs-react-fullstack/skills/plugin-guide/references/table.md +513 -0
- package/steering/nestjs-react-fullstack/skills/react-hook-best-practices/SKILL.md +118 -0
- package/steering/nestjs-react-fullstack/skills/server-builtins-file-storage-service/SKILL.md +177 -0
- package/steering/nestjs-react-fullstack/skills/user-management-best-practices/SKILL.md +142 -0
- package/steering/design-stack/skills/client-add-aily-web-chat/SKILL.md +0 -139
- package/steering/design-stack/skills/client-builtins-user-service/SKILL.md +0 -628
- package/steering/design-stack/skills/code-fix/SKILL.md +0 -246
- package/steering/design-stack/skills/feishu/SKILL.md +0 -270
- package/steering/design-stack/skills/feishu/references/approval.md +0 -214
- package/steering/design-stack/skills/feishu/references/attendance.md +0 -163
- package/steering/design-stack/skills/feishu/references/bitable.md +0 -309
- package/steering/design-stack/skills/feishu/references/calendar.md +0 -190
- package/steering/design-stack/skills/feishu/references/contacts.md +0 -160
- package/steering/design-stack/skills/feishu/references/doc.md +0 -256
- package/steering/design-stack/skills/feishu/references/drive.md +0 -103
- package/steering/design-stack/skills/feishu/references/events.md +0 -198
- package/steering/design-stack/skills/feishu/references/id-convert.md +0 -128
- package/steering/design-stack/skills/feishu/references/messaging.md +0 -207
- package/steering/design-stack/skills/feishu/references/oauth.md +0 -164
- package/steering/design-stack/skills/feishu/references/perm.md +0 -90
- package/steering/design-stack/skills/feishu/references/wiki.md +0 -164
- package/steering/design-stack/skills/user-identity/SKILL.md +0 -300
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
# 运行态角色管理 Controller 实施规格
|
|
2
|
+
|
|
3
|
+
> **前置条件**:应用必须已开启角色服务。
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. 注入
|
|
8
|
+
|
|
9
|
+
```typescript
|
|
10
|
+
import { AuthorizationSDK } from '@lark-apaas/fullstack-nestjs-core';
|
|
11
|
+
|
|
12
|
+
// AuthorizationSDK 由 AuthZPaasModule 全局注册,直接注入即可
|
|
13
|
+
// SDK 自动从请求上下文获取 appId 和 userId
|
|
14
|
+
constructor(private readonly authzSDK: AuthorizationSDK) {}
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## 2. DTO 定义
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import type { MemberMutationData, FilterParams, MemberType } from '@lark-apaas/fullstack-nestjs-core';
|
|
21
|
+
|
|
22
|
+
export class CreateRoleDto {
|
|
23
|
+
role: { name: string; description?: string; bizID: string };
|
|
24
|
+
userID?: string; // 可不传,默认为当前登录用户
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class UpdateRoleDto {
|
|
28
|
+
role: { name?: string; description?: string };
|
|
29
|
+
userID?: string;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export class AddMembersDto {
|
|
33
|
+
members: MemberMutationData;
|
|
34
|
+
userID?: string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export class RemoveMembersDto {
|
|
38
|
+
members: MemberMutationData;
|
|
39
|
+
userID?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export class SearchDto {
|
|
43
|
+
query: string;
|
|
44
|
+
filters?: FilterParams;
|
|
45
|
+
includeExternalUser?: boolean;
|
|
46
|
+
includeExternalGroup?: boolean;
|
|
47
|
+
pageSize?: number;
|
|
48
|
+
page?: number;
|
|
49
|
+
userID?: string;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export class ListMembersQueryDto {
|
|
53
|
+
type?: MemberType;
|
|
54
|
+
page?: number;
|
|
55
|
+
pageSize?: number;
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## 3. Controller
|
|
60
|
+
|
|
61
|
+
管理接口可按需改为 `@CanRole(['admin'])`:
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { Controller, Get, Post, Put, Delete, Body, Param, Query } from '@nestjs/common';
|
|
65
|
+
import { AuthorizationSDK } from '@lark-apaas/fullstack-nestjs-core';
|
|
66
|
+
|
|
67
|
+
@Controller('api/role_manager')
|
|
68
|
+
export class AuthorizationController {
|
|
69
|
+
constructor(private readonly authzSDK: AuthorizationSDK) {}
|
|
70
|
+
|
|
71
|
+
@Get('roles')
|
|
72
|
+
listRoles() { return this.authzSDK.roles.list(); }
|
|
73
|
+
|
|
74
|
+
@Get('roles/:bizID')
|
|
75
|
+
getRole(@Param('bizID') bizID: string) { return this.authzSDK.roles.get(bizID); }
|
|
76
|
+
|
|
77
|
+
@Post('roles')
|
|
78
|
+
createRole(@Body() dto: CreateRoleDto) { return this.authzSDK.roles.create(dto); }
|
|
79
|
+
|
|
80
|
+
@Put('roles/:bizID')
|
|
81
|
+
updateRole(@Param('bizID') bizID: string, @Body() dto: UpdateRoleDto) {
|
|
82
|
+
return this.authzSDK.roles.update(bizID, dto);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@Delete('roles/:bizID')
|
|
86
|
+
deleteRole(@Param('bizID') bizID: string) { return this.authzSDK.roles.delete(bizID); }
|
|
87
|
+
|
|
88
|
+
@Get('roles/:bizID/members')
|
|
89
|
+
listMembers(@Param('bizID') bizID: string, @Query() query: ListMembersQueryDto) {
|
|
90
|
+
return this.authzSDK.members.list(bizID, query);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
@Post('roles/:bizID/members')
|
|
94
|
+
addMembers(@Param('bizID') bizID: string, @Body() dto: AddMembersDto) {
|
|
95
|
+
return this.authzSDK.members.add(bizID, dto);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
@Post('roles/:bizID/members/batch_remove')
|
|
99
|
+
removeMembers(@Param('bizID') bizID: string, @Body() dto: RemoveMembersDto) {
|
|
100
|
+
return this.authzSDK.members.remove(bizID, dto);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
@Delete('roles/:bizID/members')
|
|
104
|
+
clearMembers(@Param('bizID') bizID: string) { return this.authzSDK.members.clear(bizID); }
|
|
105
|
+
|
|
106
|
+
@Post('search')
|
|
107
|
+
search(@Body() dto: SearchDto) { return this.authzSDK.search.search(dto); }
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## 4. Shared 类型定义
|
|
112
|
+
|
|
113
|
+
在 `shared/api.interface.ts` 中定义前后端共享的接口类型。SDK 已导出的类型直接 re-export,请求/响应类型与 Controller DTO 对齐。
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// shared/api.interface.ts — 角色管理相关类型
|
|
117
|
+
|
|
118
|
+
// ---- re-export SDK 类型,前后端统一引用 ----
|
|
119
|
+
export type {
|
|
120
|
+
ForceRoleDTO,
|
|
121
|
+
RoleMemberDTO,
|
|
122
|
+
MemberMutationData,
|
|
123
|
+
MemberType,
|
|
124
|
+
UserSimpleDTO,
|
|
125
|
+
DepartmentDTO,
|
|
126
|
+
DepartmentMutationDTO,
|
|
127
|
+
ChatSimpleDTO,
|
|
128
|
+
PresetGroupDTO,
|
|
129
|
+
SearchResponse,
|
|
130
|
+
SearchResult,
|
|
131
|
+
FilterParams,
|
|
132
|
+
I18nText,
|
|
133
|
+
} from '@lark-apaas/fullstack-nestjs-core';
|
|
134
|
+
|
|
135
|
+
// ---- 请求类型(与 Controller DTO 一致) ----
|
|
136
|
+
|
|
137
|
+
/** POST /api/role_manager/roles */
|
|
138
|
+
export interface CreateRoleRequest {
|
|
139
|
+
role: { name: string; description?: string; bizID: string };
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** PUT /api/role_manager/roles/:bizID */
|
|
143
|
+
export interface UpdateRoleRequest {
|
|
144
|
+
role: { name?: string; description?: string };
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/** POST /api/role_manager/roles/:bizID/members */
|
|
148
|
+
export interface AddMembersRequest {
|
|
149
|
+
members: MemberMutationData;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/** POST /api/role_manager/roles/:bizID/members/batch_remove */
|
|
153
|
+
export interface RemoveMembersRequest {
|
|
154
|
+
members: MemberMutationData;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** POST /api/role_manager/search */
|
|
158
|
+
export interface SearchMembersRequest {
|
|
159
|
+
query: string;
|
|
160
|
+
filters?: FilterParams;
|
|
161
|
+
pageSize?: number;
|
|
162
|
+
page?: number;
|
|
163
|
+
}
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
> **注意**:请求类型省略了 `userID` 字段——`userID` 由后端从请求上下文自动注入,前端无需传递。
|
|
167
|
+
|
|
168
|
+
### 前端 API 层引用示例
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
// client/src/api/index.ts
|
|
172
|
+
import type {
|
|
173
|
+
ForceRoleDTO,
|
|
174
|
+
CreateRoleRequest,
|
|
175
|
+
UpdateRoleRequest,
|
|
176
|
+
AddMembersRequest,
|
|
177
|
+
RemoveMembersRequest,
|
|
178
|
+
SearchMembersRequest,
|
|
179
|
+
SearchResponse,
|
|
180
|
+
} from '@shared/api.interface';
|
|
181
|
+
|
|
182
|
+
export async function getRoles(): Promise<ForceRoleDTO[]> { ... }
|
|
183
|
+
export async function createRole(data: CreateRoleRequest): Promise<void> { ... }
|
|
184
|
+
export async function updateRole(bizID: string, data: UpdateRoleRequest): Promise<void> { ... }
|
|
185
|
+
export async function deleteRole(bizID: string): Promise<void> { ... }
|
|
186
|
+
export async function addRoleMembers(bizID: string, data: AddMembersRequest): Promise<void> { ... }
|
|
187
|
+
export async function removeRoleMembers(bizID: string, data: RemoveMembersRequest): Promise<void> { ... }
|
|
188
|
+
export async function searchMembers(data: SearchMembersRequest): Promise<SearchResponse> { ... }
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
## 5. 模块注册
|
|
192
|
+
|
|
193
|
+
创建 `server/modules/role-manager/role-manager.module.ts`,并在 `app.module.ts` 中注册(ViewModule 之前)。
|
|
194
|
+
|
|
195
|
+
## 错误处理
|
|
196
|
+
|
|
197
|
+
SDK 内部统一将平台错误转为 `HttpException`,Controller 无需 try-catch:
|
|
198
|
+
|
|
199
|
+
| 场景 | HTTP 状态码 | 说明 |
|
|
200
|
+
|------|-----------|------|
|
|
201
|
+
| 平台 4xx | 透传 | 参数错误、权限不足、角色不存在等 |
|
|
202
|
+
| 平台 5xx | 502 | 平台内部错误 |
|
|
203
|
+
| HTTP 200 + `status_code !== '0'` | 502 | 平台业务错误(如远程服务不可用) |
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# AuthorizationSDK 调用示例
|
|
2
|
+
|
|
3
|
+
> 完整类型定义见 [sdk-types.md](./sdk-types.md)
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// ===================== 角色管理 =====================
|
|
7
|
+
|
|
8
|
+
// 获取所有角色列表,needMember=true 会在每个角色中附带成员数据
|
|
9
|
+
const roles: ForceRoleDTO[] = await sdk.roles.list({ needMember: true });
|
|
10
|
+
|
|
11
|
+
// 获取单个角色详情
|
|
12
|
+
const role: ForceRoleDTO = await sdk.roles.get('editor');
|
|
13
|
+
|
|
14
|
+
// 创建角色,bizID 为角色唯一 key,应用内不可重复
|
|
15
|
+
const created: CreateRoleResponse = await sdk.roles.create({
|
|
16
|
+
role: { bizID: 'editor', name: '编辑者', description: '可编辑内容' },
|
|
17
|
+
});
|
|
18
|
+
// created.bizID → 'editor', created.apiID → 平台分配的 API 标识
|
|
19
|
+
|
|
20
|
+
// 更新角色名称或描述
|
|
21
|
+
await sdk.roles.update('editor', { role: { name: '高级编辑者' } });
|
|
22
|
+
|
|
23
|
+
// 删除角色(⚠️ 包含「企业全员」或「互联网公开」成员的角色不支持删除)
|
|
24
|
+
await sdk.roles.delete('editor');
|
|
25
|
+
|
|
26
|
+
// ===================== 成员管理 =====================
|
|
27
|
+
// 成员按类型分组传递(MemberMutationData),不是扁平数组
|
|
28
|
+
|
|
29
|
+
// 添加用户到角色
|
|
30
|
+
await sdk.members.add('admin', {
|
|
31
|
+
members: { userList: [{ userID: '1826968659245100' }] },
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// 添加部门到角色(ID 保持字符串)
|
|
35
|
+
await sdk.members.add('admin', {
|
|
36
|
+
members: { departmentList: [{ id: '7579138586559286811' }] },
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// 添加群组到角色
|
|
40
|
+
await sdk.members.add('admin', {
|
|
41
|
+
members: { groupChatList: [{ chatID: '123456' }] },
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// 设置包含应用开发者(唯一可通过 SDK 修改的特殊范围)
|
|
45
|
+
await sdk.members.add('admin', { members: { isContainsAdmin: true } });
|
|
46
|
+
// 取消包含应用开发者
|
|
47
|
+
await sdk.members.remove('admin', { members: { isContainsAdmin: true } });
|
|
48
|
+
|
|
49
|
+
// 查询成员列表,不传 type 返回所有类型(用户+部门+群组)
|
|
50
|
+
const membersRes: ListMembersResponse = await sdk.members.list('admin');
|
|
51
|
+
// 响应按类型分组:
|
|
52
|
+
// membersRes.members.userList → 用户列表
|
|
53
|
+
// membersRes.members.departmentList → 部门列表
|
|
54
|
+
// membersRes.members.groupChatList → 群组列表
|
|
55
|
+
// membersRes.members.allEmployees → 是否包含企业全员(只读)
|
|
56
|
+
// membersRes.members.public → 是否互联网公开(只读)
|
|
57
|
+
// membersRes.members.presetGroup?.isContainsAdmin → 是否包含应用开发者
|
|
58
|
+
// membersRes.total / membersRes.hasMore → 分页信息
|
|
59
|
+
|
|
60
|
+
// 按类型过滤查询,只获取用户成员
|
|
61
|
+
const userMembers = await sdk.members.list('admin', { type: 'User', pageSize: 20 });
|
|
62
|
+
|
|
63
|
+
// 从角色移除指定用户
|
|
64
|
+
await sdk.members.remove('admin', {
|
|
65
|
+
members: { userList: [{ userID: '1826968659245100' }] },
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
// 清空角色下所有成员
|
|
69
|
+
await sdk.members.clear('admin');
|
|
70
|
+
|
|
71
|
+
// ===================== 混合搜索 =====================
|
|
72
|
+
// 同时搜索用户、部门、群组,不传 filters 时默认三种类型各 pageSize=20
|
|
73
|
+
|
|
74
|
+
const searchRes: SearchResponse = await sdk.search.search({
|
|
75
|
+
query: '张三',
|
|
76
|
+
pageSize: 20,
|
|
77
|
+
page: 1,
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
// 响应按类型分组,分别遍历
|
|
81
|
+
searchRes.result.userResult?.items?.forEach(u =>
|
|
82
|
+
console.log('用户:', u.name, u.userID, u.avatar),
|
|
83
|
+
);
|
|
84
|
+
searchRes.result.departmentResult?.items?.forEach(d =>
|
|
85
|
+
console.log('部门:', d.name, d.departmentID),
|
|
86
|
+
);
|
|
87
|
+
searchRes.result.chatResult?.items?.forEach(c =>
|
|
88
|
+
console.log('群组:', c.name, c.chatID, '成员数:', c.userCount),
|
|
89
|
+
);
|
|
90
|
+
```
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# AuthorizationSDK 类型定义
|
|
2
|
+
|
|
3
|
+
> 所有类型均从 `@lark-apaas/fullstack-nestjs-core` 导入。
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// ===================== 通用 =====================
|
|
7
|
+
|
|
8
|
+
interface I18nText {
|
|
9
|
+
[locale: string]: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/** 部门名称的国际化格式(language_code: 2052=zh_cn, 1033=en_us) */
|
|
13
|
+
interface I18nLangItem {
|
|
14
|
+
language_code: number;
|
|
15
|
+
text: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// ===================== 角色 =====================
|
|
19
|
+
|
|
20
|
+
interface ForceRoleDTO {
|
|
21
|
+
id?: number; // 数据库自增 ID
|
|
22
|
+
apiID?: string; // 平台 API 标识
|
|
23
|
+
bizID?: string; // 角色唯一 key
|
|
24
|
+
tenantID?: number; // 租户 ID
|
|
25
|
+
name?: string; // 角色名称
|
|
26
|
+
description?: string; // 角色描述
|
|
27
|
+
type?: number; // 0-普通角色, 1-预置角色
|
|
28
|
+
source?: string; // 来源: 'aPaaS' | 'MiaoDa'
|
|
29
|
+
status?: number;
|
|
30
|
+
memberScope?: string; // 'all' | 'custom'
|
|
31
|
+
envScope?: string; // 'all' | 'custom'
|
|
32
|
+
feature?: string;
|
|
33
|
+
deletedAt?: number;
|
|
34
|
+
version?: number;
|
|
35
|
+
createdBy?: number;
|
|
36
|
+
createdAt?: number;
|
|
37
|
+
updatedBy?: number;
|
|
38
|
+
updatedAt?: number;
|
|
39
|
+
roleMembers?: RoleMemberDTO; // 仅 needMember=true 时返回
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
interface ListRolesParams {
|
|
43
|
+
needMember?: boolean; // 是否返回成员信息,默认 true
|
|
44
|
+
userID?: string; // 可不传,默认为当前登录用户
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface CreateRoleParams {
|
|
48
|
+
role: {
|
|
49
|
+
name: string; // 角色名称(必填)
|
|
50
|
+
description?: string;
|
|
51
|
+
bizID: string; // 角色唯一 key(必填)
|
|
52
|
+
};
|
|
53
|
+
userID?: string; // 可不传,默认为当前登录用户
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
interface CreateRoleResponse {
|
|
57
|
+
bizID: string; // 角色唯一 key
|
|
58
|
+
apiID: string; // 平台 API 标识
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
interface UpdateRoleParams {
|
|
62
|
+
role: { name?: string; description?: string };
|
|
63
|
+
userID?: string; // 可不传,默认为当前登录用户
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// ===================== 成员 =====================
|
|
67
|
+
|
|
68
|
+
type MemberType =
|
|
69
|
+
| 'User'
|
|
70
|
+
| 'Department'
|
|
71
|
+
| 'GroupChat'
|
|
72
|
+
| 'Tenant'
|
|
73
|
+
| 'PresetGroup'
|
|
74
|
+
| 'Public'
|
|
75
|
+
| 'AllEmployee';
|
|
76
|
+
|
|
77
|
+
interface UserSimpleDTO {
|
|
78
|
+
userID?: string; // 用户 ID
|
|
79
|
+
name?: I18nText;
|
|
80
|
+
avatar?: string;
|
|
81
|
+
email?: string;
|
|
82
|
+
userType?: string;
|
|
83
|
+
larkUserID?: number;
|
|
84
|
+
department?: DepartmentSimpleDTO;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
interface DepartmentSimpleDTO {
|
|
88
|
+
departmentID?: number;
|
|
89
|
+
larkDepartmentID?: number;
|
|
90
|
+
name?: I18nText; // SDK 归一化后统一为 { zh_cn, en_us } 格式
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** 查询响应中的部门(SDK 已将平台的数组格式归一化为 I18nText) */
|
|
94
|
+
interface DepartmentDTO {
|
|
95
|
+
id?: string; // 部门 ID
|
|
96
|
+
name?: I18nText; // 部门名称,SDK 归一化后统一为 { zh_cn, en_us } 格式
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** 变更入参中的部门(提交接口只需 id) */
|
|
100
|
+
interface DepartmentMutationDTO {
|
|
101
|
+
id?: string; // 部门 ID
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
interface ChatSimpleDTO {
|
|
105
|
+
chatID?: string; // 群组 ID
|
|
106
|
+
name?: I18nText;
|
|
107
|
+
avatar?: string;
|
|
108
|
+
isExternal?: boolean;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
interface PresetGroupDTO {
|
|
112
|
+
isContainsAdmin?: boolean;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/** 平台返回的成员数据(list 响应中使用) */
|
|
116
|
+
interface RoleMemberDTO {
|
|
117
|
+
userList?: UserSimpleDTO[];
|
|
118
|
+
departmentList?: DepartmentDTO[];
|
|
119
|
+
groupChatList?: ChatSimpleDTO[];
|
|
120
|
+
allEmployees?: boolean; // 是否包含企业全员(只读)
|
|
121
|
+
public?: boolean; // 是否互联网公开(只读)
|
|
122
|
+
presetGroup?: PresetGroupDTO; // 是否包含应用开发者
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/** 用户接口的成员变更数据(add/remove 参数中使用),SDK 内部自动映射 isContainsAdmin 为 presetGroup */
|
|
126
|
+
interface MemberMutationData {
|
|
127
|
+
userList?: UserSimpleDTO[];
|
|
128
|
+
departmentList?: DepartmentMutationDTO[];
|
|
129
|
+
groupChatList?: ChatSimpleDTO[];
|
|
130
|
+
isContainsAdmin?: boolean; // 是否包含应用开发者,SDK 内部映射为 presetGroup.isContainsAdmin
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
interface ListMembersParams {
|
|
134
|
+
type?: MemberType; // 不传返回所有类型
|
|
135
|
+
page?: number;
|
|
136
|
+
pageSize?: number;
|
|
137
|
+
userID?: string; // 可不传,默认为当前登录用户
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
interface ListMembersResponse {
|
|
141
|
+
members: RoleMemberDTO; // 按类型分组
|
|
142
|
+
total: number;
|
|
143
|
+
hasMore: boolean;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
interface AddMembersParams {
|
|
147
|
+
members: MemberMutationData;
|
|
148
|
+
userID?: string; // 可不传,默认为当前登录用户
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
interface RemoveMembersParams {
|
|
152
|
+
members: MemberMutationData;
|
|
153
|
+
userID?: string; // 可不传,默认为当前登录用户
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ===================== 搜索 =====================
|
|
157
|
+
|
|
158
|
+
interface CommonParam {
|
|
159
|
+
searchable?: boolean;
|
|
160
|
+
pageSize?: number;
|
|
161
|
+
offset?: number;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
interface FilterParams {
|
|
165
|
+
userParam?: { commonParam?: CommonParam };
|
|
166
|
+
departmentParam?: { commonParam?: CommonParam; searchType?: string };
|
|
167
|
+
chatParam?: { commonParam?: CommonParam };
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
interface SearchParams {
|
|
171
|
+
query: string; // 关键词(必填)
|
|
172
|
+
filters?: FilterParams; // 不传时默认三种类型各 pageSize=20
|
|
173
|
+
includeExternalUser?: boolean; // 默认 true
|
|
174
|
+
includeExternalGroup?: boolean; // 默认 true
|
|
175
|
+
pageSize?: number; // 默认 20
|
|
176
|
+
page?: number; // 默认 1
|
|
177
|
+
userID?: string; // 可不传,默认为当前登录用户
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
interface SearchUserEntity {
|
|
181
|
+
userID?: string;
|
|
182
|
+
larkUserID?: number;
|
|
183
|
+
name?: I18nText;
|
|
184
|
+
avatar?: string;
|
|
185
|
+
department?: DepartmentSimpleDTO; // 用户所属部门(name 已归一化)
|
|
186
|
+
userType?: string;
|
|
187
|
+
email?: string;
|
|
188
|
+
userStatus?: number;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
interface DepartmentEntity {
|
|
192
|
+
departmentID?: number;
|
|
193
|
+
larkDepartmentID?: number;
|
|
194
|
+
name?: I18nText; // SDK 归一化后统一为 { zh_cn, en_us } 格式
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
interface SearchChatEntity {
|
|
198
|
+
chatID?: number;
|
|
199
|
+
name?: I18nText;
|
|
200
|
+
avatar?: string;
|
|
201
|
+
isExternal?: boolean;
|
|
202
|
+
userCount?: number;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
interface SearchResult {
|
|
206
|
+
userResult?: { total?: number; items?: SearchUserEntity[] };
|
|
207
|
+
departmentResult?: { total?: number; items?: DepartmentEntity[] };
|
|
208
|
+
chatResult?: { total?: number; items?: SearchChatEntity[] };
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
interface SearchResponse {
|
|
212
|
+
result: SearchResult;
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
> **部门名称归一化**:平台返回的部门 `name` 有两种格式(`I18nText` 对象或 `[{ language_code, text }]` 数组),SDK 在所有查询接口(`roles.list`、`roles.get`、`members.list`、`search.search`)中已统一归一化为 `I18nText`(`{ zh_cn: "...", en_us: "..." }`),下游直接用 `name?.zh_cn` 取值即可。
|