open_lark/service/contact/v3/
group.rs

1use crate::{
2    core::{
3        api_req::ApiRequest, api_resp::ApiResponseTrait, config::Config,
4        constants::AccessTokenType, endpoints::EndpointBuilder, http::Transport,
5        trait_system::Service,
6    },
7    service::contact::models::*,
8};
9use serde::{Deserialize, Serialize};
10
11/// 用户组管理服务
12pub struct GroupService {
13    config: Config,
14}
15
16impl GroupService {
17    pub fn new(config: Config) -> Self {
18        Self { config }
19    }
20
21    /// 创建用户组
22    pub async fn create(
23        &self,
24        req: &CreateGroupRequest,
25    ) -> crate::core::SDKResult<CreateGroupResponse> {
26        let api_req = ApiRequest {
27            http_method: reqwest::Method::POST,
28            api_path: crate::core::endpoints::contact::CONTACT_V3_GROUPS.to_string(),
29            supported_access_token_types: vec![AccessTokenType::Tenant],
30            body: serde_json::to_vec(req)?,
31            ..Default::default()
32        };
33
34        let resp = Transport::<CreateGroupResponse>::request(api_req, &self.config, None).await?;
35        Ok(resp.data.unwrap_or_default())
36    }
37
38    /// 更新用户组
39    pub async fn patch(
40        &self,
41        group_id: &str,
42        req: &PatchGroupRequest,
43    ) -> crate::core::SDKResult<PatchGroupResponse> {
44        let api_req = ApiRequest {
45            http_method: reqwest::Method::PATCH,
46            api_path: EndpointBuilder::replace_param(
47                crate::core::endpoints::contact::CONTACT_V3_GROUP_GET,
48                "group_id",
49                group_id,
50            ),
51            supported_access_token_types: vec![AccessTokenType::Tenant],
52            body: serde_json::to_vec(req)?,
53            ..Default::default()
54        };
55
56        let resp = Transport::<PatchGroupResponse>::request(api_req, &self.config, None).await?;
57        Ok(resp.data.unwrap_or_default())
58    }
59
60    /// 查询指定用户组
61    pub async fn get(
62        &self,
63        group_id: &str,
64        _req: &GetGroupRequest,
65    ) -> crate::core::SDKResult<GetGroupResponse> {
66        let api_req = ApiRequest {
67            http_method: reqwest::Method::GET,
68            api_path: EndpointBuilder::replace_param(
69                crate::core::endpoints::contact::CONTACT_V3_GROUP_GET,
70                "group_id",
71                group_id,
72            ),
73            supported_access_token_types: vec![AccessTokenType::Tenant],
74            body: Vec::new(),
75            query_params: std::collections::HashMap::new(),
76            ..Default::default()
77        };
78
79        let resp = Transport::<GetGroupResponse>::request(api_req, &self.config, None).await?;
80        Ok(resp.data.unwrap_or_default())
81    }
82
83    /// 查询用户组列表
84    pub async fn simplelist(
85        &self,
86        _req: &ListGroupsRequest,
87    ) -> crate::core::SDKResult<ListGroupsResponse> {
88        let api_req = ApiRequest {
89            http_method: reqwest::Method::GET,
90            api_path: crate::core::endpoints::contact::CONTACT_V3_GROUPS_SIMPLELIST.to_string(),
91            supported_access_token_types: vec![AccessTokenType::Tenant],
92            body: Vec::new(),
93            query_params: std::collections::HashMap::new(),
94            ..Default::default()
95        };
96
97        let resp = Transport::<ListGroupsResponse>::request(api_req, &self.config, None).await?;
98        Ok(resp.data.unwrap_or_default())
99    }
100
101    /// 查询用户所属用户组
102    pub async fn member_belong(
103        &self,
104        _req: &GetUserGroupsRequest,
105    ) -> crate::core::SDKResult<GetUserGroupsResponse> {
106        let api_req = ApiRequest {
107            http_method: reqwest::Method::GET,
108            api_path: crate::core::endpoints::contact::CONTACT_V3_GROUPS_MEMBER_BELONG.to_string(),
109            supported_access_token_types: vec![AccessTokenType::Tenant],
110            body: Vec::new(),
111            query_params: std::collections::HashMap::new(),
112            ..Default::default()
113        };
114
115        let resp = Transport::<GetUserGroupsResponse>::request(api_req, &self.config, None).await?;
116        Ok(resp.data.unwrap_or_default())
117    }
118
119    /// 删除用户组
120    pub async fn delete(&self, group_id: &str) -> crate::core::SDKResult<DeleteGroupResponse> {
121        let api_req = ApiRequest {
122            http_method: reqwest::Method::DELETE,
123            api_path: EndpointBuilder::replace_param(
124                crate::core::endpoints::contact::CONTACT_V3_GROUP_GET,
125                "group_id",
126                group_id,
127            ),
128            supported_access_token_types: vec![AccessTokenType::Tenant],
129            body: Vec::new(),
130            ..Default::default()
131        };
132
133        let resp = Transport::<DeleteGroupResponse>::request(api_req, &self.config, None).await?;
134        Ok(resp.data.unwrap_or_default())
135    }
136
137    /// 获取用户组详细信息
138    pub async fn get_detail(
139        &self,
140        group_id: &str,
141        req: &GetGroupDetailRequest,
142    ) -> crate::core::SDKResult<GetGroupDetailResponse> {
143        let mut query_params = std::collections::HashMap::new();
144
145        if let Some(user_id_type) = &req.user_id_type {
146            query_params.insert("user_id_type", user_id_type.clone());
147        }
148        if let Some(department_id_type) = &req.department_id_type {
149            query_params.insert("department_id_type", department_id_type.clone());
150        }
151        if let Some(include_members) = req.include_members {
152            query_params.insert("include_members", include_members.to_string());
153        }
154
155        let api_req = ApiRequest {
156            http_method: reqwest::Method::GET,
157            api_path: EndpointBuilder::replace_param(
158                crate::core::endpoints::contact::CONTACT_V3_GROUP_DETAIL,
159                "group_id",
160                group_id,
161            ),
162            supported_access_token_types: vec![AccessTokenType::Tenant],
163            body: Vec::new(),
164            query_params,
165            ..Default::default()
166        };
167
168        let resp =
169            Transport::<GetGroupDetailResponse>::request(api_req, &self.config, None).await?;
170        Ok(resp.data.unwrap_or_default())
171    }
172}
173
174impl Service for GroupService {
175    fn config(&self) -> &Config {
176        &self.config
177    }
178
179    fn service_name() -> &'static str {
180        "group"
181    }
182
183    fn service_version() -> &'static str {
184        "v3"
185    }
186}
187
188#[derive(Debug, Clone, Serialize, Deserialize)]
189pub struct CreateGroupRequest {
190    pub group: Group,
191}
192
193#[derive(Debug, Clone, Serialize, Deserialize, Default)]
194pub struct CreateGroupResponse {
195    pub group: Group,
196}
197
198impl ApiResponseTrait for CreateGroupResponse {
199    fn data_format() -> crate::core::api_resp::ResponseFormat {
200        crate::core::api_resp::ResponseFormat::Data
201    }
202}
203
204#[derive(Debug, Clone, Serialize, Deserialize)]
205pub struct PatchGroupRequest {
206    pub group: Group,
207}
208
209#[derive(Debug, Clone, Serialize, Deserialize, Default)]
210pub struct PatchGroupResponse {
211    pub group: Group,
212}
213
214impl ApiResponseTrait for PatchGroupResponse {
215    fn data_format() -> crate::core::api_resp::ResponseFormat {
216        crate::core::api_resp::ResponseFormat::Data
217    }
218}
219
220#[derive(Debug, Clone, Default, Serialize, Deserialize)]
221pub struct GetGroupRequest {
222    #[serde(skip_serializing_if = "Option::is_none")]
223    pub user_id_type: Option<String>,
224    #[serde(skip_serializing_if = "Option::is_none")]
225    pub department_id_type: Option<String>,
226}
227
228#[derive(Debug, Clone, Serialize, Deserialize, Default)]
229pub struct GetGroupResponse {
230    pub group: Group,
231}
232
233impl ApiResponseTrait for GetGroupResponse {
234    fn data_format() -> crate::core::api_resp::ResponseFormat {
235        crate::core::api_resp::ResponseFormat::Data
236    }
237}
238
239#[derive(Debug, Clone, Default, Serialize, Deserialize)]
240pub struct ListGroupsRequest {
241    #[serde(skip_serializing_if = "Option::is_none")]
242    pub page_size: Option<i32>,
243    #[serde(skip_serializing_if = "Option::is_none")]
244    pub page_token: Option<String>,
245    #[serde(skip_serializing_if = "Option::is_none")]
246    pub user_id_type: Option<String>,
247    #[serde(skip_serializing_if = "Option::is_none")]
248    pub department_id_type: Option<String>,
249}
250
251#[derive(Debug, Clone, Serialize, Deserialize, Default)]
252pub struct ListGroupsResponse {
253    pub groups: Vec<Group>,
254    #[serde(skip_serializing_if = "Option::is_none")]
255    pub has_more: Option<bool>,
256    #[serde(skip_serializing_if = "Option::is_none")]
257    pub page_token: Option<String>,
258}
259
260impl ApiResponseTrait for ListGroupsResponse {
261    fn data_format() -> crate::core::api_resp::ResponseFormat {
262        crate::core::api_resp::ResponseFormat::Data
263    }
264}
265
266#[derive(Debug, Clone, Default, Serialize, Deserialize)]
267pub struct GetUserGroupsRequest {
268    #[serde(skip_serializing_if = "Option::is_none")]
269    pub member_id: Option<String>,
270    #[serde(skip_serializing_if = "Option::is_none")]
271    pub member_id_type: Option<String>,
272    #[serde(skip_serializing_if = "Option::is_none")]
273    pub page_size: Option<i32>,
274    #[serde(skip_serializing_if = "Option::is_none")]
275    pub page_token: Option<String>,
276}
277
278#[derive(Debug, Clone, Serialize, Deserialize, Default)]
279pub struct GetUserGroupsResponse {
280    pub group_list: Vec<Group>,
281    #[serde(skip_serializing_if = "Option::is_none")]
282    pub has_more: Option<bool>,
283    #[serde(skip_serializing_if = "Option::is_none")]
284    pub page_token: Option<String>,
285}
286
287impl ApiResponseTrait for GetUserGroupsResponse {
288    fn data_format() -> crate::core::api_resp::ResponseFormat {
289        crate::core::api_resp::ResponseFormat::Data
290    }
291}
292
293#[derive(Debug, Clone, Serialize, Deserialize, Default)]
294pub struct DeleteGroupResponse {}
295
296impl ApiResponseTrait for DeleteGroupResponse {
297    fn data_format() -> crate::core::api_resp::ResponseFormat {
298        crate::core::api_resp::ResponseFormat::Data
299    }
300}
301
302/// 获取用户组详细信息请求
303#[derive(Debug, Clone, Default, Serialize, Deserialize)]
304pub struct GetGroupDetailRequest {
305    /// 用户 ID 类型
306    #[serde(skip_serializing_if = "Option::is_none")]
307    pub user_id_type: Option<String>,
308    /// 部门 ID 类型
309    #[serde(skip_serializing_if = "Option::is_none")]
310    pub department_id_type: Option<String>,
311    /// 是否包含成员信息
312    #[serde(skip_serializing_if = "Option::is_none")]
313    pub include_members: Option<bool>,
314}
315
316/// 获取用户组详细信息响应
317#[derive(Debug, Clone, Serialize, Deserialize, Default)]
318pub struct GetGroupDetailResponse {
319    /// 用户组信息
320    pub group: GroupDetail,
321}
322
323impl ApiResponseTrait for GetGroupDetailResponse {
324    fn data_format() -> crate::core::api_resp::ResponseFormat {
325        crate::core::api_resp::ResponseFormat::Data
326    }
327}
328
329/// 用户组详细信息
330#[derive(Debug, Clone, Default, Serialize, Deserialize)]
331pub struct GroupDetail {
332    /// 用户组ID
333    #[serde(skip_serializing_if = "Option::is_none")]
334    pub group_id: Option<String>,
335    /// 用户组名称
336    #[serde(skip_serializing_if = "Option::is_none")]
337    pub name: Option<String>,
338    /// 用户组描述
339    #[serde(skip_serializing_if = "Option::is_none")]
340    pub description: Option<String>,
341    /// 用户组类型
342    #[serde(skip_serializing_if = "Option::is_none")]
343    pub group_type: Option<i32>,
344    /// 成员列表
345    #[serde(skip_serializing_if = "Option::is_none")]
346    pub members: Option<Vec<GroupMember>>,
347    /// 创建时间
348    #[serde(skip_serializing_if = "Option::is_none")]
349    pub create_time: Option<String>,
350    /// 更新时间
351    #[serde(skip_serializing_if = "Option::is_none")]
352    pub update_time: Option<String>,
353    /// 成员数量
354    #[serde(skip_serializing_if = "Option::is_none")]
355    pub member_count: Option<i32>,
356}