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 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 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 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}