open_lark/service/contact/
models.rs

1use serde::{Deserialize, Serialize};
2
3// 导出所有请求/响应结构体
4pub use crate::service::contact::v3::{
5    custom_attr::*, department::*, employee_type_enum::*, functional_role::*,
6    functional_role_member::*, group::*, group_member::*, job_family::*, job_level::*,
7    job_title::*, scope::*, unit::*, user::*, work_city::*,
8};
9
10/// 用户信息
11#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
12pub struct User {
13    /// 用户ID
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub user_id: Option<String>,
16    /// 用户名
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub name: Option<String>,
19    /// 英文名
20    #[serde(skip_serializing_if = "Option::is_none")]
21    pub en_name: Option<String>,
22    /// 邮箱
23    #[serde(skip_serializing_if = "Option::is_none")]
24    pub email: Option<String>,
25    /// 手机号
26    #[serde(skip_serializing_if = "Option::is_none")]
27    pub mobile: Option<String>,
28    /// 电话号码
29    #[serde(skip_serializing_if = "Option::is_none")]
30    pub mobile_visible: Option<bool>,
31    /// 性别
32    #[serde(skip_serializing_if = "Option::is_none")]
33    pub gender: Option<i32>,
34    /// 头像
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub avatar: Option<Avatar>,
37    /// 状态
38    #[serde(skip_serializing_if = "Option::is_none")]
39    pub status: Option<UserStatus>,
40    /// 部门ID列表
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub department_ids: Option<Vec<String>>,
43    /// 直属上级用户ID
44    #[serde(skip_serializing_if = "Option::is_none")]
45    pub leader_user_id: Option<String>,
46    /// 城市
47    #[serde(skip_serializing_if = "Option::is_none")]
48    pub city: Option<String>,
49    /// 国家
50    #[serde(skip_serializing_if = "Option::is_none")]
51    pub country: Option<String>,
52    /// 工位
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub work_station: Option<String>,
55    /// 入职时间
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub join_time: Option<i64>,
58    /// 离职时间
59    #[serde(skip_serializing_if = "Option::is_none")]
60    pub leave_time: Option<i64>,
61    /// 员工编号
62    #[serde(skip_serializing_if = "Option::is_none")]
63    pub employee_no: Option<String>,
64    /// 员工类型
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub employee_type: Option<i32>,
67    /// 职务
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub job_title: Option<String>,
70    /// 是否是租户超级管理员
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub is_tenant_manager: Option<bool>,
73    /// 自定义字段
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub custom_attrs: Option<Vec<UserCustomAttr>>,
76    /// 企业邮箱
77    #[serde(skip_serializing_if = "Option::is_none")]
78    pub enterprise_email: Option<String>,
79    /// 时区
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub timezone: Option<String>,
82    /// 描述
83    #[serde(skip_serializing_if = "Option::is_none")]
84    pub description: Option<String>,
85    /// 职级ID
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub job_level_id: Option<String>,
88    /// 序列ID
89    #[serde(skip_serializing_if = "Option::is_none")]
90    pub job_family_id: Option<String>,
91    /// 工作城市ID
92    #[serde(skip_serializing_if = "Option::is_none")]
93    pub work_city: Option<String>,
94}
95
96/// 头像信息
97#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
98pub struct Avatar {
99    /// 头像URL
100    #[serde(skip_serializing_if = "Option::is_none")]
101    pub avatar_72: Option<String>,
102    /// 头像URL
103    #[serde(skip_serializing_if = "Option::is_none")]
104    pub avatar_240: Option<String>,
105    /// 头像URL
106    #[serde(skip_serializing_if = "Option::is_none")]
107    pub avatar_640: Option<String>,
108    /// 头像原图URL
109    #[serde(skip_serializing_if = "Option::is_none")]
110    pub avatar_origin: Option<String>,
111}
112
113/// 用户状态
114#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
115pub struct UserStatus {
116    /// 是否冻结
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub is_frozen: Option<bool>,
119    /// 是否离职
120    #[serde(skip_serializing_if = "Option::is_none")]
121    pub is_resigned: Option<bool>,
122    /// 是否激活
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub is_activated: Option<bool>,
125    /// 是否主动离职
126    #[serde(skip_serializing_if = "Option::is_none")]
127    pub is_exited: Option<bool>,
128    /// 是否unjoin
129    #[serde(skip_serializing_if = "Option::is_none")]
130    pub is_unjoin: Option<bool>,
131}
132
133/// 用户自定义字段
134#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
135pub struct UserCustomAttr {
136    /// 字段类型
137    #[serde(skip_serializing_if = "Option::is_none")]
138    pub r#type: Option<String>,
139    /// 字段ID
140    #[serde(skip_serializing_if = "Option::is_none")]
141    pub id: Option<String>,
142    /// 字段值
143    #[serde(skip_serializing_if = "Option::is_none")]
144    pub value: Option<serde_json::Value>,
145}
146
147/// 部门信息
148#[derive(Debug, Clone, Default, Serialize, Deserialize)]
149pub struct Department {
150    /// 部门名称
151    #[serde(skip_serializing_if = "Option::is_none")]
152    pub name: Option<String>,
153    /// 国际化部门名称
154    #[serde(skip_serializing_if = "Option::is_none")]
155    pub i18n_name: Option<I18nName>,
156    /// 父部门ID
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub parent_department_id: Option<String>,
159    /// 部门ID
160    #[serde(skip_serializing_if = "Option::is_none")]
161    pub department_id: Option<String>,
162    /// 部门状态
163    #[serde(skip_serializing_if = "Option::is_none")]
164    pub status: Option<DepartmentStatus>,
165    /// 部门负责人
166    #[serde(skip_serializing_if = "Option::is_none")]
167    pub leaders: Option<Vec<String>>,
168    /// 部门群ID
169    #[serde(skip_serializing_if = "Option::is_none")]
170    pub chat_id: Option<String>,
171    /// 排序
172    #[serde(skip_serializing_if = "Option::is_none")]
173    pub order: Option<String>,
174    /// 单位绑定
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub unit_ids: Option<Vec<String>>,
177    /// 成员数量
178    #[serde(skip_serializing_if = "Option::is_none")]
179    pub member_count: Option<i32>,
180    /// 创建组织架构
181    #[serde(skip_serializing_if = "Option::is_none")]
182    pub create_group_chat: Option<bool>,
183}
184
185/// 国际化名称
186#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
187pub struct I18nName {
188    /// 中文名
189    #[serde(skip_serializing_if = "Option::is_none")]
190    pub zh_cn: Option<String>,
191    /// 英文名
192    #[serde(skip_serializing_if = "Option::is_none")]
193    pub en_us: Option<String>,
194    /// 日文名
195    #[serde(skip_serializing_if = "Option::is_none")]
196    pub ja_jp: Option<String>,
197}
198
199/// 部门状态
200#[derive(Debug, Clone, Default, Serialize, Deserialize)]
201pub struct DepartmentStatus {
202    /// 是否被删除
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub is_deleted: Option<bool>,
205}
206
207/// 用户组信息
208#[derive(Debug, Clone, Default, Serialize, Deserialize)]
209pub struct Group {
210    /// 用户组ID
211    #[serde(skip_serializing_if = "Option::is_none")]
212    pub id: Option<String>,
213    /// 用户组名称
214    #[serde(skip_serializing_if = "Option::is_none")]
215    pub name: Option<String>,
216    /// 用户组描述
217    #[serde(skip_serializing_if = "Option::is_none")]
218    pub description: Option<String>,
219    /// 用户组成员数量
220    #[serde(skip_serializing_if = "Option::is_none")]
221    pub member_user_count: Option<i32>,
222    /// 用户组部门数量
223    #[serde(skip_serializing_if = "Option::is_none")]
224    pub member_department_count: Option<i32>,
225    /// 用户组类型
226    #[serde(skip_serializing_if = "Option::is_none")]
227    pub r#type: Option<i32>,
228}
229
230/// 用户组成员
231#[derive(Debug, Clone, Default, Serialize, Deserialize)]
232pub struct GroupMember {
233    /// 成员ID
234    #[serde(skip_serializing_if = "Option::is_none")]
235    pub member_id: Option<String>,
236    /// 成员类型
237    #[serde(skip_serializing_if = "Option::is_none")]
238    pub member_type: Option<String>,
239    /// 成员ID类型
240    #[serde(skip_serializing_if = "Option::is_none")]
241    pub member_id_type: Option<String>,
242}
243
244/// 用户组成员信息
245#[derive(Debug, Clone, Default, Serialize, Deserialize)]
246pub struct GroupMemberInfo {
247    /// 成员ID
248    pub member_id: String,
249    /// 成员类型
250    #[serde(skip_serializing_if = "Option::is_none")]
251    pub member_type: Option<String>,
252    /// 成员ID类型
253    #[serde(skip_serializing_if = "Option::is_none")]
254    pub member_id_type: Option<String>,
255}
256
257/// 用户组成员操作结果
258#[derive(Debug, Clone, Default, Serialize, Deserialize)]
259pub struct GroupMemberResult {
260    /// 成员ID
261    #[serde(skip_serializing_if = "Option::is_none")]
262    pub member_id: Option<String>,
263    /// 操作结果码
264    #[serde(skip_serializing_if = "Option::is_none")]
265    pub code: Option<i32>,
266    /// 操作结果消息
267    #[serde(skip_serializing_if = "Option::is_none")]
268    pub msg: Option<String>,
269}
270
271/// 自定义字段
272#[derive(Debug, Clone, Default, Serialize, Deserialize)]
273pub struct CustomAttr {
274    /// 字段ID
275    #[serde(skip_serializing_if = "Option::is_none")]
276    pub id: Option<String>,
277    /// 字段类型
278    #[serde(skip_serializing_if = "Option::is_none")]
279    pub r#type: Option<String>,
280    /// 字段名称
281    #[serde(skip_serializing_if = "Option::is_none")]
282    pub name: Option<I18nName>,
283    /// 字段描述
284    #[serde(skip_serializing_if = "Option::is_none")]
285    pub description: Option<I18nName>,
286    /// 是否必填
287    #[serde(skip_serializing_if = "Option::is_none")]
288    pub is_required: Option<bool>,
289    /// 字段配置
290    #[serde(skip_serializing_if = "Option::is_none")]
291    pub options: Option<serde_json::Value>,
292}
293
294/// 人员类型枚举
295#[derive(Debug, Clone, Default, Serialize, Deserialize)]
296pub struct EmployeeTypeEnum {
297    /// 枚举ID
298    #[serde(skip_serializing_if = "Option::is_none")]
299    pub enum_id: Option<String>,
300    /// 枚举值
301    #[serde(skip_serializing_if = "Option::is_none")]
302    pub enum_value: Option<String>,
303    /// 枚举内容
304    #[serde(skip_serializing_if = "Option::is_none")]
305    pub content: Option<String>,
306    /// 枚举类型
307    #[serde(skip_serializing_if = "Option::is_none")]
308    pub enum_type: Option<i32>,
309    /// 枚举状态
310    #[serde(skip_serializing_if = "Option::is_none")]
311    pub enum_status: Option<i32>,
312    /// 国际化内容
313    #[serde(skip_serializing_if = "Option::is_none")]
314    pub i18n_content: Option<Vec<I18nContent>>,
315}
316
317/// 国际化内容
318#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
319pub struct I18nContent {
320    /// 语言代码
321    #[serde(skip_serializing_if = "Option::is_none")]
322    pub locale: Option<String>,
323    /// 内容值
324    #[serde(skip_serializing_if = "Option::is_none")]
325    pub value: Option<String>,
326}
327
328/// 单位信息
329#[derive(Debug, Clone, Default, Serialize, Deserialize)]
330pub struct Unit {
331    /// 单位ID
332    #[serde(skip_serializing_if = "Option::is_none")]
333    pub unit_id: Option<String>,
334    /// 单位名称
335    #[serde(skip_serializing_if = "Option::is_none")]
336    pub name: Option<String>,
337    /// 单位类型
338    #[serde(skip_serializing_if = "Option::is_none")]
339    pub unit_type: Option<String>,
340}
341
342/// 角色成员信息
343#[derive(Debug, Clone, Default, Serialize, Deserialize)]
344pub struct RoleMemberInfo {
345    /// 成员ID
346    pub user_id: String,
347    /// 管理范围
348    #[serde(skip_serializing_if = "Option::is_none")]
349    pub scope_type: Option<String>,
350    /// 管理范围ID列表
351    #[serde(skip_serializing_if = "Option::is_none")]
352    pub scope_ids: Option<Vec<String>>,
353}
354
355/// 角色成员
356#[derive(Debug, Clone, Default, Serialize, Deserialize)]
357pub struct RoleMember {
358    /// 成员ID
359    #[serde(skip_serializing_if = "Option::is_none")]
360    pub user_id: Option<String>,
361    /// 管理范围类型
362    #[serde(skip_serializing_if = "Option::is_none")]
363    pub scope_type: Option<String>,
364    /// 管理范围ID列表
365    #[serde(skip_serializing_if = "Option::is_none")]
366    pub scope_ids: Option<Vec<String>>,
367}
368
369/// 角色成员管理范围
370#[derive(Debug, Clone, Default, Serialize, Deserialize)]
371pub struct RoleMemberScope {
372    /// 成员ID
373    pub user_id: String,
374    /// 管理范围类型
375    #[serde(skip_serializing_if = "Option::is_none")]
376    pub scope_type: Option<String>,
377    /// 管理范围ID列表
378    #[serde(skip_serializing_if = "Option::is_none")]
379    pub scope_ids: Option<Vec<String>>,
380}
381
382/// 角色成员操作结果
383#[derive(Debug, Clone, Default, Serialize, Deserialize)]
384pub struct RoleMemberResult {
385    /// 成员ID
386    #[serde(skip_serializing_if = "Option::is_none")]
387    pub user_id: Option<String>,
388    /// 操作结果码
389    #[serde(skip_serializing_if = "Option::is_none")]
390    pub code: Option<i32>,
391    /// 操作结果消息
392    #[serde(skip_serializing_if = "Option::is_none")]
393    pub msg: Option<String>,
394}
395
396/// 职级信息
397#[derive(Debug, Clone, Default, Serialize, Deserialize)]
398pub struct JobLevel {
399    /// 职级ID
400    #[serde(skip_serializing_if = "Option::is_none")]
401    pub job_level_id: Option<String>,
402    /// 职级名称
403    #[serde(skip_serializing_if = "Option::is_none")]
404    pub name: Option<Vec<I18nContent>>,
405    /// 职级描述
406    #[serde(skip_serializing_if = "Option::is_none")]
407    pub description: Option<Vec<I18nContent>>,
408    /// 职级状态
409    #[serde(skip_serializing_if = "Option::is_none")]
410    pub status: Option<bool>,
411    /// 职级等级
412    #[serde(skip_serializing_if = "Option::is_none")]
413    pub rank: Option<i32>,
414}
415
416/// 序列信息
417#[derive(Debug, Clone, Default, Serialize, Deserialize)]
418pub struct JobFamily {
419    /// 序列ID
420    #[serde(skip_serializing_if = "Option::is_none")]
421    pub job_family_id: Option<String>,
422    /// 序列名称
423    #[serde(skip_serializing_if = "Option::is_none")]
424    pub name: Option<Vec<I18nContent>>,
425    /// 序列描述
426    #[serde(skip_serializing_if = "Option::is_none")]
427    pub description: Option<Vec<I18nContent>>,
428    /// 序列状态
429    #[serde(skip_serializing_if = "Option::is_none")]
430    pub status: Option<bool>,
431}
432
433/// 职务信息
434#[derive(Debug, Clone, Default, Serialize, Deserialize)]
435pub struct JobTitle {
436    /// 职务ID
437    #[serde(skip_serializing_if = "Option::is_none")]
438    pub job_title_id: Option<String>,
439    /// 职务名称
440    #[serde(skip_serializing_if = "Option::is_none")]
441    pub name: Option<Vec<I18nContent>>,
442    /// 职务状态
443    #[serde(skip_serializing_if = "Option::is_none")]
444    pub status: Option<bool>,
445}
446
447/// 工作城市信息
448#[derive(Debug, Clone, Default, Serialize, Deserialize)]
449pub struct WorkCity {
450    /// 工作城市ID
451    #[serde(skip_serializing_if = "Option::is_none")]
452    pub work_city_id: Option<String>,
453    /// 工作城市名称
454    #[serde(skip_serializing_if = "Option::is_none")]
455    pub name: Option<Vec<I18nContent>>,
456    /// 工作城市状态
457    #[serde(skip_serializing_if = "Option::is_none")]
458    pub status: Option<bool>,
459}
460
461#[cfg(test)]
462#[allow(unused_variables, unused_unsafe)]
463mod tests {
464    use super::*;
465    use serde_json;
466
467    #[test]
468    fn test_user_serialization() {
469        let user = User {
470            user_id: Some("user_123".to_string()),
471            name: Some("张三".to_string()),
472            en_name: Some("Zhang San".to_string()),
473            email: Some("zhangsan@example.com".to_string()),
474            mobile: Some("+86-13812345678".to_string()),
475            mobile_visible: Some(true),
476            gender: Some(1),
477            avatar: Some(Avatar {
478                avatar_72: Some("avatar72.jpg".to_string()),
479                avatar_240: Some("avatar240.jpg".to_string()),
480                avatar_640: Some("avatar640.jpg".to_string()),
481                avatar_origin: Some("avatar_origin.jpg".to_string()),
482            }),
483            status: Some(UserStatus {
484                is_frozen: Some(false),
485                is_resigned: Some(false),
486                is_activated: Some(true),
487                is_exited: Some(false),
488                is_unjoin: Some(false),
489            }),
490            department_ids: Some(vec!["dept_1".to_string(), "dept_2".to_string()]),
491            leader_user_id: Some("leader_456".to_string()),
492            city: Some("北京".to_string()),
493            country: Some("中国".to_string()),
494            work_station: Some("A座101".to_string()),
495            join_time: Some(1640995200),
496            leave_time: None,
497            employee_no: Some("EMP001".to_string()),
498            employee_type: Some(1),
499            job_title: Some("高级工程师".to_string()),
500            is_tenant_manager: Some(false),
501            custom_attrs: Some(vec![UserCustomAttr {
502                r#type: Some("text".to_string()),
503                id: Some("custom_1".to_string()),
504                value: Some(serde_json::Value::String("自定义值".to_string())),
505            }]),
506            enterprise_email: Some("zhangsan@company.com".to_string()),
507            timezone: Some("Asia/Shanghai".to_string()),
508            description: Some("用户描述".to_string()),
509            job_level_id: Some("level_5".to_string()),
510            job_family_id: Some("family_tech".to_string()),
511            work_city: Some("beijing".to_string()),
512        };
513        let serialized = serde_json::to_string(&user).unwrap();
514        let deserialized: User = serde_json::from_str(&serialized).unwrap();
515        assert_eq!(user.user_id, deserialized.user_id);
516        assert_eq!(user.name, deserialized.name);
517        assert_eq!(user.email, deserialized.email);
518        assert_eq!(user.mobile, deserialized.mobile);
519        assert_eq!(user.gender, deserialized.gender);
520    }
521
522    #[test]
523    fn test_user_default() {
524        let user = User::default();
525        assert_eq!(user.user_id, None);
526        assert_eq!(user.name, None);
527        assert_eq!(user.email, None);
528        assert_eq!(user.mobile, None);
529        assert_eq!(user.gender, None);
530    }
531
532    #[test]
533    fn test_user_minimal_data() {
534        let user = User {
535            user_id: Some("minimal_user".to_string()),
536            name: Some("最小用户".to_string()),
537            ..Default::default()
538        };
539        let serialized = serde_json::to_string(&user).unwrap();
540        assert!(!serialized.contains("email"));
541        assert!(!serialized.contains("mobile"));
542        assert!(!serialized.contains("gender"));
543        let deserialized: User = serde_json::from_str(&serialized).unwrap();
544        assert_eq!(user.user_id, deserialized.user_id);
545        assert_eq!(user.name, deserialized.name);
546        assert_eq!(user.email, deserialized.email);
547    }
548
549    #[test]
550    fn test_avatar_serialization() {
551        let avatar = Avatar {
552            avatar_72: Some("https://example.com/avatar_72.jpg".to_string()),
553            avatar_240: Some("https://example.com/avatar_240.jpg".to_string()),
554            avatar_640: Some("https://example.com/avatar_640.jpg".to_string()),
555            avatar_origin: Some("https://example.com/avatar_origin.jpg".to_string()),
556        };
557        let serialized = serde_json::to_string(&avatar).unwrap();
558        let deserialized: Avatar = serde_json::from_str(&serialized).unwrap();
559        assert_eq!(avatar.avatar_72, deserialized.avatar_72);
560        assert_eq!(avatar.avatar_240, deserialized.avatar_240);
561        assert_eq!(avatar.avatar_640, deserialized.avatar_640);
562        assert_eq!(avatar.avatar_origin, deserialized.avatar_origin);
563    }
564
565    #[test]
566    fn test_avatar_with_none_values() {
567        let avatar = Avatar {
568            avatar_72: Some("avatar72.jpg".to_string()),
569            avatar_240: None,
570            avatar_640: None,
571            avatar_origin: None,
572        };
573        let serialized = serde_json::to_string(&avatar).unwrap();
574        assert!(!serialized.contains("avatar_240"));
575        assert!(!serialized.contains("avatar_640"));
576        assert!(!serialized.contains("avatar_origin"));
577        let deserialized: Avatar = serde_json::from_str(&serialized).unwrap();
578        assert_eq!(avatar.avatar_72, deserialized.avatar_72);
579        assert_eq!(avatar.avatar_240, deserialized.avatar_240);
580    }
581
582    #[test]
583    fn test_user_status_serialization() {
584        let status = UserStatus {
585            is_frozen: Some(false),
586            is_resigned: Some(true),
587            is_activated: Some(true),
588            is_exited: Some(false),
589            is_unjoin: Some(false),
590        };
591        let serialized = serde_json::to_string(&status).unwrap();
592        let deserialized: UserStatus = serde_json::from_str(&serialized).unwrap();
593        assert_eq!(status.is_frozen, deserialized.is_frozen);
594        assert_eq!(status.is_resigned, deserialized.is_resigned);
595        assert_eq!(status.is_activated, deserialized.is_activated);
596        assert_eq!(status.is_exited, deserialized.is_exited);
597        assert_eq!(status.is_unjoin, deserialized.is_unjoin);
598    }
599
600    #[test]
601    fn test_user_custom_attr_serialization() {
602        let custom_attr = UserCustomAttr {
603            r#type: Some("number".to_string()),
604            id: Some("attr_123".to_string()),
605            value: Some(serde_json::Value::Number(serde_json::Number::from(42))),
606        };
607        let serialized = serde_json::to_string(&custom_attr).unwrap();
608        let deserialized: UserCustomAttr = serde_json::from_str(&serialized).unwrap();
609        assert_eq!(custom_attr.r#type, deserialized.r#type);
610        assert_eq!(custom_attr.id, deserialized.id);
611        assert_eq!(custom_attr.value, deserialized.value);
612    }
613
614    #[test]
615    fn test_department_serialization() {
616        let department = Department {
617            name: Some("技术部".to_string()),
618            i18n_name: Some(I18nName {
619                zh_cn: Some("技术部".to_string()),
620                en_us: Some("Technology Department".to_string()),
621                ja_jp: Some("技術部".to_string()),
622            }),
623            parent_department_id: Some("parent_dept_123".to_string()),
624            department_id: Some("dept_456".to_string()),
625            status: Some(DepartmentStatus {
626                is_deleted: Some(false),
627            }),
628            leaders: Some(vec!["leader_1".to_string(), "leader_2".to_string()]),
629            chat_id: Some("chat_789".to_string()),
630            order: Some("100".to_string()),
631            unit_ids: Some(vec!["unit_1".to_string()]),
632            member_count: Some(25),
633            create_group_chat: Some(true),
634        };
635        let serialized = serde_json::to_string(&department).unwrap();
636        let deserialized: Department = serde_json::from_str(&serialized).unwrap();
637        assert_eq!(department.name, deserialized.name);
638        assert_eq!(department.department_id, deserialized.department_id);
639        assert_eq!(department.member_count, deserialized.member_count);
640    }
641
642    #[test]
643    fn test_i18n_name_serialization() {
644        let i18n_name = I18nName {
645            zh_cn: Some("中文名称".to_string()),
646            en_us: Some("English Name".to_string()),
647            ja_jp: Some("日本語名前".to_string()),
648        };
649        let serialized = serde_json::to_string(&i18n_name).unwrap();
650        let deserialized: I18nName = serde_json::from_str(&serialized).unwrap();
651        assert_eq!(i18n_name.zh_cn, deserialized.zh_cn);
652        assert_eq!(i18n_name.en_us, deserialized.en_us);
653        assert_eq!(i18n_name.ja_jp, deserialized.ja_jp);
654    }
655
656    #[test]
657    fn test_department_status_serialization() {
658        let status = DepartmentStatus {
659            is_deleted: Some(true),
660        };
661        let serialized = serde_json::to_string(&status).unwrap();
662        let deserialized: DepartmentStatus = serde_json::from_str(&serialized).unwrap();
663        assert_eq!(status.is_deleted, deserialized.is_deleted);
664    }
665
666    #[test]
667    fn test_group_serialization() {
668        let group = Group {
669            id: Some("group_123".to_string()),
670            name: Some("开发组".to_string()),
671            description: Some("负责产品开发的用户组".to_string()),
672            member_user_count: Some(15),
673            member_department_count: Some(3),
674            r#type: Some(1),
675        };
676        let serialized = serde_json::to_string(&group).unwrap();
677        let deserialized: Group = serde_json::from_str(&serialized).unwrap();
678        assert_eq!(group.id, deserialized.id);
679        assert_eq!(group.name, deserialized.name);
680        assert_eq!(group.description, deserialized.description);
681        assert_eq!(group.member_user_count, deserialized.member_user_count);
682    }
683
684    #[test]
685    fn test_group_member_serialization() {
686        let member = GroupMember {
687            member_id: Some("member_123".to_string()),
688            member_type: Some("user".to_string()),
689            member_id_type: Some("user_id".to_string()),
690        };
691        let serialized = serde_json::to_string(&member).unwrap();
692        let deserialized: GroupMember = serde_json::from_str(&serialized).unwrap();
693        assert_eq!(member.member_id, deserialized.member_id);
694        assert_eq!(member.member_type, deserialized.member_type);
695        assert_eq!(member.member_id_type, deserialized.member_id_type);
696    }
697
698    #[test]
699    fn test_group_member_info_serialization() {
700        let member_info = GroupMemberInfo {
701            member_id: "required_member_123".to_string(),
702            member_type: Some("user".to_string()),
703            member_id_type: Some("open_id".to_string()),
704        };
705        let serialized = serde_json::to_string(&member_info).unwrap();
706        let deserialized: GroupMemberInfo = serde_json::from_str(&serialized).unwrap();
707        assert_eq!(member_info.member_id, deserialized.member_id);
708        assert_eq!(member_info.member_type, deserialized.member_type);
709        assert_eq!(member_info.member_id_type, deserialized.member_id_type);
710    }
711
712    #[test]
713    fn test_group_member_result_serialization() {
714        let result = GroupMemberResult {
715            member_id: Some("member_456".to_string()),
716            code: Some(0),
717            msg: Some("操作成功".to_string()),
718        };
719        let serialized = serde_json::to_string(&result).unwrap();
720        let deserialized: GroupMemberResult = serde_json::from_str(&serialized).unwrap();
721        assert_eq!(result.member_id, deserialized.member_id);
722        assert_eq!(result.code, deserialized.code);
723        assert_eq!(result.msg, deserialized.msg);
724    }
725
726    #[test]
727    fn test_custom_attr_serialization() {
728        let custom_attr = CustomAttr {
729            id: Some("custom_field_1".to_string()),
730            r#type: Some("select".to_string()),
731            name: Some(I18nName {
732                zh_cn: Some("自定义字段".to_string()),
733                en_us: Some("Custom Field".to_string()),
734                ja_jp: None,
735            }),
736            description: Some(I18nName {
737                zh_cn: Some("字段描述".to_string()),
738                en_us: Some("Field Description".to_string()),
739                ja_jp: None,
740            }),
741            is_required: Some(true),
742            options: Some(serde_json::json!({"choices": ["选项1", "选项2"]})),
743        };
744        let serialized = serde_json::to_string(&custom_attr).unwrap();
745        let deserialized: CustomAttr = serde_json::from_str(&serialized).unwrap();
746        assert_eq!(custom_attr.id, deserialized.id);
747        assert_eq!(custom_attr.r#type, deserialized.r#type);
748        assert_eq!(custom_attr.is_required, deserialized.is_required);
749    }
750
751    #[test]
752    fn test_employee_type_enum_serialization() {
753        let employee_type = EmployeeTypeEnum {
754            enum_id: Some("type_1".to_string()),
755            enum_value: Some("1".to_string()),
756            content: Some("正式员工".to_string()),
757            enum_type: Some(1),
758            enum_status: Some(1),
759            i18n_content: Some(vec![
760                I18nContent {
761                    locale: Some("zh_cn".to_string()),
762                    value: Some("正式员工".to_string()),
763                },
764                I18nContent {
765                    locale: Some("en_us".to_string()),
766                    value: Some("Full-time Employee".to_string()),
767                },
768            ]),
769        };
770        let serialized = serde_json::to_string(&employee_type).unwrap();
771        let deserialized: EmployeeTypeEnum = serde_json::from_str(&serialized).unwrap();
772        assert_eq!(employee_type.enum_id, deserialized.enum_id);
773        assert_eq!(employee_type.enum_value, deserialized.enum_value);
774        assert_eq!(employee_type.content, deserialized.content);
775    }
776
777    #[test]
778    fn test_i18n_content_serialization() {
779        let content = I18nContent {
780            locale: Some("zh_cn".to_string()),
781            value: Some("中文内容".to_string()),
782        };
783        let serialized = serde_json::to_string(&content).unwrap();
784        let deserialized: I18nContent = serde_json::from_str(&serialized).unwrap();
785        assert_eq!(content.locale, deserialized.locale);
786        assert_eq!(content.value, deserialized.value);
787    }
788
789    #[test]
790    fn test_unit_serialization() {
791        let unit = Unit {
792            unit_id: Some("unit_123".to_string()),
793            name: Some("技术中心".to_string()),
794            unit_type: Some("center".to_string()),
795        };
796        let serialized = serde_json::to_string(&unit).unwrap();
797        let deserialized: Unit = serde_json::from_str(&serialized).unwrap();
798        assert_eq!(unit.unit_id, deserialized.unit_id);
799        assert_eq!(unit.name, deserialized.name);
800        assert_eq!(unit.unit_type, deserialized.unit_type);
801    }
802
803    #[test]
804    fn test_role_member_info_serialization() {
805        let role_member = RoleMemberInfo {
806            user_id: "role_user_123".to_string(),
807            scope_type: Some("department".to_string()),
808            scope_ids: Some(vec!["dept_1".to_string(), "dept_2".to_string()]),
809        };
810        let serialized = serde_json::to_string(&role_member).unwrap();
811        let deserialized: RoleMemberInfo = serde_json::from_str(&serialized).unwrap();
812        assert_eq!(role_member.user_id, deserialized.user_id);
813        assert_eq!(role_member.scope_type, deserialized.scope_type);
814        assert_eq!(role_member.scope_ids, deserialized.scope_ids);
815    }
816
817    #[test]
818    fn test_role_member_serialization() {
819        let role_member = RoleMember {
820            user_id: Some("user_789".to_string()),
821            scope_type: Some("all".to_string()),
822            scope_ids: None,
823        };
824        let serialized = serde_json::to_string(&role_member).unwrap();
825        assert!(!serialized.contains("scope_ids"));
826        let deserialized: RoleMember = serde_json::from_str(&serialized).unwrap();
827        assert_eq!(role_member.user_id, deserialized.user_id);
828        assert_eq!(role_member.scope_type, deserialized.scope_type);
829        assert_eq!(role_member.scope_ids, deserialized.scope_ids);
830    }
831
832    #[test]
833    fn test_role_member_scope_serialization() {
834        let scope = RoleMemberScope {
835            user_id: "scope_user_456".to_string(),
836            scope_type: Some("department".to_string()),
837            scope_ids: Some(vec!["dept_tech".to_string()]),
838        };
839        let serialized = serde_json::to_string(&scope).unwrap();
840        let deserialized: RoleMemberScope = serde_json::from_str(&serialized).unwrap();
841        assert_eq!(scope.user_id, deserialized.user_id);
842        assert_eq!(scope.scope_type, deserialized.scope_type);
843        assert_eq!(scope.scope_ids, deserialized.scope_ids);
844    }
845
846    #[test]
847    fn test_role_member_result_serialization() {
848        let result = RoleMemberResult {
849            user_id: Some("result_user_123".to_string()),
850            code: Some(200),
851            msg: Some("角色分配成功".to_string()),
852        };
853        let serialized = serde_json::to_string(&result).unwrap();
854        let deserialized: RoleMemberResult = serde_json::from_str(&serialized).unwrap();
855        assert_eq!(result.user_id, deserialized.user_id);
856        assert_eq!(result.code, deserialized.code);
857        assert_eq!(result.msg, deserialized.msg);
858    }
859
860    #[test]
861    fn test_job_level_serialization() {
862        let job_level = JobLevel {
863            job_level_id: Some("level_senior".to_string()),
864            name: Some(vec![
865                I18nContent {
866                    locale: Some("zh_cn".to_string()),
867                    value: Some("高级".to_string()),
868                },
869                I18nContent {
870                    locale: Some("en_us".to_string()),
871                    value: Some("Senior".to_string()),
872                },
873            ]),
874            description: Some(vec![I18nContent {
875                locale: Some("zh_cn".to_string()),
876                value: Some("高级职级".to_string()),
877            }]),
878            status: Some(true),
879            rank: Some(5),
880        };
881        let serialized = serde_json::to_string(&job_level).unwrap();
882        let deserialized: JobLevel = serde_json::from_str(&serialized).unwrap();
883        assert_eq!(job_level.job_level_id, deserialized.job_level_id);
884        assert_eq!(job_level.status, deserialized.status);
885        assert_eq!(job_level.rank, deserialized.rank);
886    }
887
888    #[test]
889    fn test_job_family_serialization() {
890        let job_family = JobFamily {
891            job_family_id: Some("family_tech".to_string()),
892            name: Some(vec![
893                I18nContent {
894                    locale: Some("zh_cn".to_string()),
895                    value: Some("技术序列".to_string()),
896                },
897                I18nContent {
898                    locale: Some("en_us".to_string()),
899                    value: Some("Technology Track".to_string()),
900                },
901            ]),
902            description: Some(vec![I18nContent {
903                locale: Some("zh_cn".to_string()),
904                value: Some("技术发展序列".to_string()),
905            }]),
906            status: Some(true),
907        };
908        let serialized = serde_json::to_string(&job_family).unwrap();
909        let deserialized: JobFamily = serde_json::from_str(&serialized).unwrap();
910        assert_eq!(job_family.job_family_id, deserialized.job_family_id);
911        assert_eq!(job_family.status, deserialized.status);
912    }
913
914    #[test]
915    fn test_job_title_serialization() {
916        let job_title = JobTitle {
917            job_title_id: Some("title_engineer".to_string()),
918            name: Some(vec![
919                I18nContent {
920                    locale: Some("zh_cn".to_string()),
921                    value: Some("软件工程师".to_string()),
922                },
923                I18nContent {
924                    locale: Some("en_us".to_string()),
925                    value: Some("Software Engineer".to_string()),
926                },
927            ]),
928            status: Some(true),
929        };
930        let serialized = serde_json::to_string(&job_title).unwrap();
931        let deserialized: JobTitle = serde_json::from_str(&serialized).unwrap();
932        assert_eq!(job_title.job_title_id, deserialized.job_title_id);
933        assert_eq!(job_title.status, deserialized.status);
934    }
935
936    #[test]
937    fn test_work_city_serialization() {
938        let work_city = WorkCity {
939            work_city_id: Some("city_beijing".to_string()),
940            name: Some(vec![
941                I18nContent {
942                    locale: Some("zh_cn".to_string()),
943                    value: Some("北京".to_string()),
944                },
945                I18nContent {
946                    locale: Some("en_us".to_string()),
947                    value: Some("Beijing".to_string()),
948                },
949            ]),
950            status: Some(true),
951        };
952        let serialized = serde_json::to_string(&work_city).unwrap();
953        let deserialized: WorkCity = serde_json::from_str(&serialized).unwrap();
954        assert_eq!(work_city.work_city_id, deserialized.work_city_id);
955        assert_eq!(work_city.status, deserialized.status);
956    }
957
958    #[test]
959    fn test_work_city_with_none_values() {
960        let work_city = WorkCity {
961            work_city_id: Some("city_minimal".to_string()),
962            name: None,
963            status: None,
964        };
965        let serialized = serde_json::to_string(&work_city).unwrap();
966        assert!(!serialized.contains("name"));
967        assert!(!serialized.contains("status"));
968        let deserialized: WorkCity = serde_json::from_str(&serialized).unwrap();
969        assert_eq!(work_city.work_city_id, deserialized.work_city_id);
970        assert_eq!(work_city.name, deserialized.name);
971        assert_eq!(work_city.status, deserialized.status);
972    }
973}