1use crate::entity::ChimesCompanyAccountInfo;
2use crate::entity::ChimesDeptInfo;
3use crate::entity::ChimesJobInfo;
4use crate::entity::ChimesRoleInfo;
5use crate::entity::ChimesUserInfo;
6use crate::entity::ChimesUserJobInfo;
7use crate::entity::ChimesUserRoleInfo;
8use chimes_utils::{bool_from_str, i64_from_str};
9use rbatis::error::Error;
10use rbatis::rbatis::Rbatis;
11use serde_derive::{Deserialize, Serialize};
12use std::fmt::Debug;
16
17#[derive(Debug, Clone, Default, Deserialize, Serialize)]
18pub struct ChimesUserDetailInfo {
19 pub user_id: Option<i64>,
20 pub dept_id: Option<i64>,
21 pub username: Option<String>,
22 pub nick_name: Option<String>,
23 pub gender: Option<String>,
24 pub phone: Option<String>,
25 pub email: Option<String>,
26 pub area_id: Option<String>,
27 pub avatar_name: Option<String>,
28 pub avatar_path: Option<String>,
29 pub password: Option<String>,
30 pub open_id: Option<String>,
31 pub union_id: Option<String>,
32
33 #[serde(default)]
34 #[serde(deserialize_with = "bool_from_str")]
35 pub is_admin: Option<bool>,
36 #[serde(default)]
37 #[serde(deserialize_with = "bool_from_str")]
38 pub enabled: Option<bool>,
39 pub create_by: Option<String>,
40 pub update_by: Option<String>,
41 pub data_scope: Option<String>,
42 pub pwd_reset_time: Option<rbatis::DateTimeNative>,
43 pub create_time: Option<rbatis::DateTimeNative>,
44 pub update_time: Option<rbatis::DateTimeNative>,
45 pub dept: Option<ChimesDeptInfo>,
46 #[serde(default)]
47 pub roles: Vec<ChimesRoleInfo>,
48 #[serde(default)]
49 pub jobs: Vec<ChimesJobInfo>,
50 pub company_code: Option<String>,
51
52 #[serde(default)]
53 #[serde(deserialize_with = "i64_from_str")]
54 pub company_id: Option<i64>,
55}
56
57impl ChimesUserDetailInfo {
58 fn to_roles_vec(roles: &Option<String>) -> Vec<ChimesRoleInfo> {
59 if roles.is_none() {
60 vec![]
61 } else {
62 let role_text = roles.clone().unwrap_or_default();
63 let rolevec = role_text
64 .split(',')
65 .map(|f| ChimesRoleInfo {
66 role_code: Some(f.to_string()),
67 ..Default::default()
68 })
69 .collect::<Vec<ChimesRoleInfo>>();
70 rolevec
71 }
72 }
73
74 #[allow(dead_code)]
75 pub fn from_user(param: &ChimesUserInfo) -> Self {
76 ChimesUserDetailInfo {
77 user_id: param.user_id,
78 dept_id: param.dept_id,
79 username: param.username.clone(),
80 nick_name: param.nick_name.clone(),
81 gender: param.gender.clone(),
82 phone: param.phone.clone(),
83 email: param.email.clone(),
84 area_id: param.area_id.clone(),
85 avatar_name: param.avatar_name.clone(),
86 avatar_path: param.avatar_path.clone(),
87 password: param.password.clone(),
88 open_id: param.open_id.clone(),
89 union_id: param.union_id.clone(),
90 is_admin: param.is_admin,
91 enabled: param.enabled,
92 create_by: param.create_by.clone(),
93 update_by: param.update_by.clone(),
94 pwd_reset_time: param.pwd_reset_time,
95 create_time: param.create_time,
96 update_time: param.update_time,
97 company_code: param.company_code.clone(),
98 company_id: param.company_id,
99 data_scope: param.data_scope.clone(),
100 dept: None,
101 roles: Self::to_roles_vec(¶m.simulate_roles.clone()),
102 jobs: vec![],
103 }
104 }
105
106 pub fn from_account(param: &ChimesCompanyAccountInfo) -> Self {
107 ChimesUserDetailInfo {
108 user_id: param.account_id,
109 dept_id: None,
110 username: param.username.clone(),
111 nick_name: param.real_name.clone(),
112 gender: param.gender.clone(),
113 phone: param.telephone.clone(),
114 email: param.email.clone(),
115 area_id: None,
116 avatar_name: None, avatar_path: None, password: param.sign_password.clone(),
119 open_id: param.wechat_open_id.clone(),
120 union_id: param.wechat_union_id.clone(),
121 is_admin: Some(false),
122 enabled: param.enabled,
123 create_by: None,
124 update_by: None,
125 pwd_reset_time: None,
126 data_scope: None,
127 create_time: param.create_time,
128 update_time: param.update_time,
129 company_code: param.company_code.clone(),
130 company_id: param.company_id,
131 dept: None,
132 roles: Self::to_roles_vec(¶m.role_id.clone()),
133 jobs: vec![],
134 }
135 }
136
137 #[allow(dead_code)]
138 pub fn to_user(&self) -> ChimesUserInfo {
139 let self_dept_id = match self.dept.clone() {
140 Some(np) => np.dept_id,
141 None => self.dept_id,
142 };
143 let roles = self
144 .roles
145 .clone()
146 .into_iter()
147 .map(|f| f.role_code.unwrap_or_default())
148 .collect::<Vec<String>>()
149 .join(",");
150 ChimesUserInfo {
151 user_id: self.user_id,
152 dept_id: self_dept_id,
153 username: self.username.clone(),
154 nick_name: self.nick_name.clone(),
155 gender: self.gender.clone(),
156 phone: self.phone.clone(),
157 email: self.email.clone(),
158 area_id: self.area_id.clone(),
159 avatar_name: self.avatar_name.clone(),
160 avatar_path: self.avatar_path.clone(),
161 password: self.password.clone(),
162 open_id: self.open_id.clone(),
163 union_id: self.union_id.clone(),
164 is_admin: self.is_admin,
165 enabled: self.enabled,
166 create_by: self.create_by.clone(),
167 update_by: self.update_by.clone(),
168 data_scope: self.data_scope.clone(),
169 pwd_reset_time: self.pwd_reset_time,
170 create_time: self.create_time,
171 update_time: self.update_time,
172 company_id: self.company_id,
173 company_code: self.company_code.clone(),
174 simulate_roles: if roles.is_empty() { None } else { Some(roles) },
175 }
176 }
177
178 #[allow(dead_code)]
179 pub async fn load(rb: &Rbatis, user_id: &i64) -> Result<Option<Self>, Error> {
180 match ChimesUserInfo::from_id(rb, user_id).await {
181 Ok(ts) => {
182 match ts {
183 Some(mp) => {
184 let mut selfmp = Self::from_user(&mp);
185 selfmp.dept =
186 match ChimesDeptInfo::from_id(rb, &selfmp.dept_id.unwrap_or_default())
187 .await
188 {
189 Ok(lst) => lst,
190 Err(_) => None,
191 };
192 let mut rb_args = vec![];
193 let sql_role = "SELECT tp.* FROM chimes_role tp INNER JOIN chimes_users_roles mt ON tp.role_id = mt.role_id WHERE mt.user_id = ?";
194 rb_args.push(
195 rbson::to_bson(selfmp.user_id.unwrap_or_default()).unwrap_or_default(),
196 );
197 selfmp.roles = match rb.fetch(sql_role, rb_args).await {
198 Ok(lst) => lst,
199 Err(_) => {
200 vec![]
201 }
202 };
203 let mut rb_args = vec![];
204 let sql_job = "SELECT tp.* FROM chimes_job tp INNER JOIN chimes_users_jobs mt ON tp.job_id = mt.job_id WHERE mt.user_id = ?";
205 rb_args.push(
206 rbson::to_bson(selfmp.user_id.unwrap_or_default()).unwrap_or_default(),
207 );
208 selfmp.jobs = match rb.fetch(sql_job, rb_args).await {
209 Ok(lst) => lst,
210 Err(_) => {
211 vec![]
212 }
213 };
214 Ok(Some(selfmp))
215 }
216 None => Ok(None),
217 }
218 }
219 Err(err) => Err(err),
220 }
221 }
222
223 #[allow(dead_code)]
224 pub async fn load_openid(rb: &Rbatis, open_id: &str) -> Result<Option<Self>, Error> {
225 match ChimesUserInfo::load_openid(rb, open_id).await {
226 Ok(ts) => {
227 match ts {
228 Some(mp) => {
229 let mut selfmp = Self::from_user(&mp);
230 selfmp.dept =
231 match ChimesDeptInfo::from_id(rb, &selfmp.dept_id.unwrap_or_default())
232 .await
233 {
234 Ok(lst) => lst,
235 Err(_) => None,
236 };
237 let mut rb_args = vec![];
238 let sql_role = "SELECT tp.* FROM chimes_role tp INNER JOIN chimes_users_roles mt ON tp.role_id = mt.role_id WHERE mt.user_id = ?";
239 rb_args.push(
240 rbson::to_bson(selfmp.user_id.unwrap_or_default()).unwrap_or_default(),
241 );
242 selfmp.roles = match rb.fetch(sql_role, rb_args).await {
243 Ok(lst) => lst,
244 Err(_) => {
245 vec![]
246 }
247 };
248 let mut rb_args = vec![];
249 let sql_job = "SELECT tp.* FROM chimes_job tp INNER JOIN chimes_users_jobs mt ON tp.job_id = mt.job_id WHERE mt.user_id = ?";
250 rb_args.push(
251 rbson::to_bson(selfmp.user_id.unwrap_or_default()).unwrap_or_default(),
252 );
253 selfmp.jobs = match rb.fetch(sql_job, rb_args).await {
254 Ok(lst) => lst,
255 Err(_) => {
256 vec![]
257 }
258 };
259 Ok(Some(selfmp))
260 }
261 None => {
262 match ChimesCompanyAccountInfo::load_openid(rb, open_id).await {
263 Ok(ts) => {
264 match ts {
265 Some(mt) => {
266 let mut cds = Self::from_account(&mt);
267 let mut codes = vec![];
268
269 codes.push("ROLE_COMMONUSER".to_string());
270 if mt.role_id.is_some() {
271 codes.push(mt.role_id.unwrap_or_default());
273 }
274
275 match ChimesRoleInfo::query_multicode(rb, &codes).await {
276 Ok(mlst) => {
277 cds.roles = mlst;
278 }
279 Err(err) => {
280 log::warn!("Could not fetch the roles {}", err);
281 }
282 }
283
284 Ok(Some(cds))
285 }
286 None => Ok(None),
287 }
288 }
289 Err(err) => Err(err),
290 }
291 }
292 }
293 }
294 Err(err) => Err(err),
295 }
296 }
297
298 #[allow(dead_code)]
299 pub async fn load_username(
300 rb: &Rbatis,
301 username: &String,
302 company_code: &Option<String>,
303 ) -> Result<Option<Self>, Error> {
304 if company_code.is_some() {
305 match ChimesCompanyAccountInfo::find_code(
307 rb,
308 &company_code.clone().unwrap_or_default(),
309 username,
310 )
311 .await
312 {
313 Ok(ts) => {
314 match ts {
315 Some(mt) => {
316 let mut cds = Self::from_account(&mt);
317 let mut codes = vec![];
318
319 codes.push("ROLE_COMMONUSER".to_string());
320 if mt.role_id.is_some() {
321 codes.push(mt.role_id.unwrap_or_default());
323 }
324
325 match ChimesRoleInfo::query_multicode(rb, &codes).await {
326 Ok(mlst) => {
327 cds.roles = mlst;
328 }
329 Err(err) => {
330 log::warn!("Could not fetch the roles {}", err);
331 }
332 }
333
334 Ok(Some(cds))
335 }
336 None => Ok(None),
337 }
338 }
339 Err(err) => Err(err),
340 }
341 } else {
342 match ChimesUserInfo::load_username(rb, username).await {
343 Ok(ts) => match ts {
344 Some(mp) => {
345 let mut selfmp = Self::from_user(&mp);
346 selfmp.dept =
347 match ChimesDeptInfo::from_id(rb, &selfmp.dept_id.unwrap_or_default())
348 .await
349 {
350 Ok(lst) => lst,
351 Err(_) => None,
352 };
353 let mut rb_args = vec![];
354 let sql_role = "SELECT tp.* FROM chimes_role tp INNER JOIN chimes_users_roles mt ON tp.role_id = mt.role_id WHERE mt.user_id = ?";
355 rb_args.push(
356 rbson::to_bson(selfmp.user_id.unwrap_or_default()).unwrap_or_default(),
357 );
358 selfmp.roles = match rb.fetch(sql_role, rb_args).await {
359 Ok(lst) => lst,
360 Err(_) => {
361 vec![]
362 }
363 };
364 let mut rb_args = vec![];
365 let sql_job = "SELECT tp.* FROM chimes_job tp INNER JOIN chimes_users_jobs mt ON tp.job_id = mt.job_id WHERE mt.user_id = ?";
366 rb_args.push(
367 rbson::to_bson(selfmp.user_id.unwrap_or_default()).unwrap_or_default(),
368 );
369 selfmp.jobs = match rb.fetch(sql_job, rb_args).await {
370 Ok(lst) => lst,
371 Err(_) => {
372 vec![]
373 }
374 };
375 Ok(Some(selfmp))
376 }
377 None => Ok(None),
378 },
379 Err(err) => Err(err),
380 }
381 }
382 }
383
384 #[allow(dead_code)]
385 pub async fn save(&self, rb: &Rbatis) -> Result<bool, Error> {
386 let mut ret: Option<Error>;
387 let mut self_user = self.to_user();
388 if self_user.user_id.is_none() {
389 ret = match self_user.save(rb).await {
390 Ok(_rs) => None,
391 Err(err) => {
392 log::warn!("Save user occurred an error {}", err);
393 Some(err)
394 }
395 }
396 } else {
397 ret = match self_user.update_selective(rb).await {
398 Ok(_rs) => None,
399 Err(err) => {
400 log::warn!("Update user occurred an error {}", err);
401 Some(err)
402 }
403 }
404 }
405 if ret.is_none() {
407 let rm_user_role_info = ChimesUserRoleInfo {
408 user_id: self_user.user_id,
409 ..Default::default()
410 };
411 ret = match rm_user_role_info.remove_batch(rb).await {
412 Ok(_) => None,
413 Err(err) => {
414 log::warn!("Remove user_role_info occurred an error {}", err);
415 Some(err)
416 }
417 };
418 }
419 for row in self.roles.clone() {
420 log::info!("Insert new roles: {}", row.role_id.unwrap_or_default());
421 let mut svrow_user_role_info = ChimesUserRoleInfo {
422 user_id: self_user.user_id,
423 role_id: row.role_id,
424 };
425 ret = match svrow_user_role_info.save(rb).await {
426 Ok(_) => None,
427 Err(err) => {
428 log::warn!("Save user_role_info occurred an error {}", err);
429 Some(err)
430 }
431 };
432 }
433 if ret.is_none() {
435 let rm_user_job_info = ChimesUserJobInfo {
436 user_id: self_user.user_id,
437 ..Default::default()
438 };
439
440 ret = match rm_user_job_info.remove_batch(rb).await {
441 Ok(_) => None,
442 Err(err) => {
443 log::warn!("Remove user_job_info occurred an error {}", err);
444 Some(err)
445 }
446 };
447 }
448 for row in self.jobs.clone() {
449 let mut svrow_user_job_info = ChimesUserJobInfo {
450 user_id: self_user.user_id,
451 job_id: row.job_id,
452 };
453 ret = match svrow_user_job_info.save(rb).await {
454 Ok(_) => None,
455 Err(err) => {
456 log::warn!("Save user_job_info occurred an error {}", err);
457 Some(err)
458 }
459 };
460 }
461 match ret {
462 Some(err) => Err(err),
463 None => Ok(true),
464 }
465 }
466
467 #[allow(dead_code)]
468 pub async fn remove(&self, rb: &Rbatis) -> Result<bool, Error> {
469 let mut ret: Option<Error> = None;
470 if ret.is_none() {
472 let rm_user_role_info = ChimesUserRoleInfo {
473 user_id: self.user_id,
474 ..Default::default()
475 };
476 ret = match rm_user_role_info.remove_batch(rb).await {
477 Ok(_rtremove) => None,
478 Err(err) => {
479 log::warn!("Remove user_role_info occurred an error {}", err);
480 Some(err)
481 }
482 };
483 }
484 if ret.is_none() {
486 let rm_user_job_info = ChimesUserJobInfo {
487 user_id: self.user_id,
488 ..Default::default()
489 };
490 ret = match rm_user_job_info.remove_batch(rb).await {
491 Ok(_rtremove) => None,
492 Err(err) => {
493 log::warn!("Remove user_job_info occurred an error {}", err);
494 Some(err)
495 }
496 };
497 }
498
499 if let Some(ret) = ret {
500 Err(ret)
501 } else {
502 match self.to_user().remove(rb).await {
503 Ok(_rs) => Ok(true),
504 Err(err) => {
505 log::warn!("Remove user occurred an error {}", err);
506 Err(err)
507 }
508 }
509 }
510 }
511}