br_wechat/
wecom.rs

1use chrono::Local;
2use json::{array, JsonValue, object};
3use log::info;
4use crate::{WechatMethod, ACCOUNT};
5
6#[derive(Clone)]
7pub struct WeCom {
8    pub appid: String,
9    pub agent_id: String,
10    pub secret: String,
11    pub access_token: String,
12    pub expires_in: i64,
13}
14
15impl WeCom {
16    fn _access_token(&mut self) -> String {
17        let dt = Local::now();
18        let timestamp = dt.timestamp_millis();
19        if self.expires_in > timestamp {
20            return self.access_token.clone();
21        }
22        let url = format!("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={}&corpsecret={}", self.appid, self.secret);
23        let mut http = br_reqwest::Client::new();
24        http.get(url.as_str());
25        let res = match http.send() {
26            Ok(e) => e,
27            Err(_) => return "".to_string()
28        };
29        let res = match res.json() {
30            Ok(e) => e,
31            Err(_) => return "".to_string()
32        };
33        if res["errcode"].as_i32().unwrap() == 0 {
34            self.access_token = res["access_token"].to_string();
35            self.expires_in = timestamp + res["expires_in"].as_i64().unwrap();
36            {
37                ACCOUNT.write().unwrap().get_mut(&self.appid.clone()).unwrap().access_token = self.access_token.clone();
38                ACCOUNT.write().unwrap().get_mut(&self.appid.clone()).unwrap().expires_in = self.expires_in;
39            }
40        } else {
41            info!("access_token: {}", res["errmsg"].as_str().unwrap());
42        }
43        self.access_token.clone()
44    }
45    /// 获取访问用户身份
46    pub fn getuserinfo(&mut self, code: &str) -> Result<JsonValue, String> {
47        let url = format!("https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token={}&code={}", self.clone()._access_token(), code);
48        let mut http = br_reqwest::Client::new();
49        http.get(url.as_str());
50        let res = http.send().unwrap();
51        let res = res.json().unwrap();
52        let mut user_info = object! {};
53        if res["errcode"].as_i32().unwrap() == 0 {
54            user_info = self.clone().get_by_userid(res["userid"].to_string().as_str());
55            user_info["openid"] = self.clone().convert_to_openid(res["userid"].to_string().as_str())["openid"].clone();
56        } else {
57            info!("getuserinfo: {}", res["errmsg"].as_str().unwrap());
58        }
59        Ok(user_info)
60    }
61
62    /// 获取成员详细信息
63    pub fn get_by_userid(&mut self, userid: &str) -> JsonValue {
64        let url = format!("https://qyapi.weixin.qq.com/cgi-bin/user/get?access_token={}&userid={}", self.clone()._access_token(), userid);
65        let mut http = br_reqwest::Client::new();
66        http.get(url.as_str());
67        let res = http.send().unwrap();
68        let res = res.json().unwrap();
69        let mut user_info = object! {};
70        if res["errcode"].as_i32().unwrap() == 0 {
71            user_info = res.clone();
72        } else {
73            info!("get_by_userid: {}", res["errmsg"].as_str().unwrap());
74        }
75        user_info
76    }
77
78    pub fn convert_to_openid(&mut self, userid: &str) -> JsonValue {
79        let url = format!("https://qyapi.weixin.qq.com/cgi-bin/user/convert_to_openid?access_token={}", self.clone()._access_token());
80        let mut http = br_reqwest::Client::new();
81        http.post(url.as_str());
82        http.raw_json(object! {
83            "userid": userid
84        });
85        let res = http.send().unwrap();
86        let res = res.json().unwrap();
87        let mut user_info = object! {};
88        if res["errcode"].as_i32().unwrap() == 0 {
89            user_info["userid"] = userid.into();
90            user_info["openid"] = res["openid"].clone();
91        } else {
92            info!("convert_to_openid: {}", res["errmsg"].as_str().unwrap());
93        }
94        user_info
95    }
96
97    pub fn login_link(&mut self, redirect_uri: &str, state: &str) -> String {
98        let redirect_uri = urlencoding::encode(redirect_uri);
99        let url = format!("https://login.work.weixin.qq.com/wwlogin/sso/login?appid={}&redirect_uri={redirect_uri}&state={}&login_type=CorpApp&agentid={}", self.appid, state, self.agent_id);
100        url
101    }
102    pub fn get_department(&mut self) -> JsonValue {
103        let url = format!("https://qyapi.weixin.qq.com/cgi-bin/department/list?access_token={}", self._access_token());
104        let mut http = br_reqwest::Client::new();
105        http.get(url.as_str());
106        let res = http.send().unwrap();
107        let mut res = res.json().unwrap();
108        let mut data = array![];
109
110        let mut keys = object! {
111            "1":""
112        };
113        if res["errcode"].as_i32().unwrap() == 0 {
114            for item in res["department"].members_mut() {
115                // let userlist = self.get_simplelist(item["id"].to_string().as_str().clone());
116                if item["id"] == "1" {
117                    continue;
118                }
119                keys[item["id"].to_string()] = item["name"].as_str().unwrap().into();
120                item["sort"] = item["order"].to_string().into();
121                item["org_dept"] = keys[item["parentid"].to_string()].clone();
122
123                data.push(object! {
124                    name:item["name"].clone(),
125                    org_dept:item["org_dept"].clone(),
126                    sort:item["sort"].clone(),
127                    code:item["id"].clone(),
128                }).unwrap();
129            }
130        } else {
131            info!("convert_to_openid: {}", res["errmsg"].as_str().unwrap());
132        }
133        data
134    }
135    pub fn get_simplelist(&mut self, department_id: &str) -> JsonValue {
136        let url = format!("https://qyapi.weixin.qq.com/cgi-bin/user/simplelist?access_token={}&department_id={}", self.clone()._access_token(), department_id);
137
138        let mut http = br_reqwest::Client::new();
139        http.post(url.as_str());
140        http.raw_json(object! {});
141        let res = http.send().unwrap();
142        let mut res = res.json().unwrap();
143
144        let mut data = array![];
145        if res["errcode"].as_i32().unwrap() == 0 {
146            for item in res["userlist"].members_mut() {
147                item.remove("department");
148                data.push(object! {
149                    name:item["name"].clone(),
150                    account:item["userid"].clone()
151                }).unwrap();
152            }
153        } else {
154            info!("convert_to_openid: {}", res["errmsg"].as_str().unwrap());
155        }
156        data
157    }
158    pub fn get_simplelist_details(&mut self, department_id: &str) -> JsonValue {
159        let url = format!("https://qyapi.weixin.qq.com/cgi-bin/user/list?access_token={}&department_id={}", self.clone()._access_token(), department_id);
160        let mut http = br_reqwest::Client::new();
161        http.post(url.as_str());
162        http.raw_json(object! {});
163        let res = http.send().unwrap();
164        let mut res = res.json().unwrap();
165        let mut data = array![];
166        if res["errcode"].as_i32().unwrap() == 0 {
167            for item in res["userlist"].members_mut() {
168                data.push(object! {
169                    status:item["status"].clone(),
170                    position:item["position"].clone(),
171                    department:item["department"].clone(),
172                    name:item["name"].clone(),
173                    account:item["userid"].clone()
174                }).unwrap();
175            }
176        } else {
177            info!("convert_to_openid: {}", res["errmsg"].as_str().unwrap());
178        }
179        data
180    }
181}
182
183impl WechatMethod for WeCom {
184    fn check(&mut self) -> Result<bool, String> {
185        Ok(self._access_token() != "")
186    }
187
188    fn login(&mut self, _code: &str) -> Result<JsonValue, String> {
189        todo!()
190    }
191
192    fn getuserinfo(&mut self, _code: &str) -> Result<JsonValue, String> {
193        todo!()
194    }
195}