QiYeWeChatApiService.cs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444
  1. using OASystem.Domain.Dtos.QiYeWeChat;
  2. using OASystem.Domain.ViewModels.JuHeExchangeRate;
  3. using OASystem.Domain.ViewModels.QiYeWeChat;
  4. using Org.BouncyCastle.Ocsp;
  5. using System.Collections.Generic;
  6. using System.Text.Json;
  7. using Ubiety.Dns.Core;
  8. namespace OASystem.API.OAMethodLib.QiYeWeChatAPI
  9. {
  10. /// <summary>
  11. /// 聚合Api 服务
  12. /// </summary>
  13. public class QiYeWeChatApiService: IQiYeWeChatApiService
  14. {
  15. private readonly HttpClient _httpClient;
  16. private readonly string CorpId = "wwe978bef5495a0728"; //企业Id
  17. private readonly string PersonnelAssistant_AgentId = "3010011"; //人事助手Id
  18. private readonly string PersonnelAssistant_Corpsecret = "ig--IJd6TxWDMJ1wT4e-RDRcRX12v5GjB359DNATwJ4"; //人事助手凭证密钥
  19. private readonly string PunchCard_AgentId = "3010185"; //打卡Id
  20. private readonly string PunchCard_Corpsecret = "Xhrl37GOqlAjsu0VzUSJECaJdjzkDXQLbvrzRsZQb8M"; //打卡凭证密钥
  21. private readonly string Email_AgentId = "1000004"; //E-Mail Id
  22. private readonly string Email_Corpsecret = "NA1zbJM15GmgjPYwDOqz59dIo1Wnug-MbU107MeUemc"; //E-Mail 凭证密钥
  23. private readonly string AddressBook_Corpsecret = "Y1tnjh7j-BvbqAytAoXZPUbmDR6dqLTL6mXtc6PZ7fo"; //通讯录同步 凭证密钥
  24. private readonly string Approve_AgentId = "3010040"; //审批 Id
  25. private readonly string Approve_Corpsecret = "k_Jo69Jw9Hqg_in-Rypbs30PNbxOYa1t4e-dxYuT-kw"; //审批 凭证密钥
  26. private readonly DateTime _1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0);
  27. private readonly JobPostRepository _jobPostRep;
  28. /// <summary>
  29. /// 初始化
  30. /// </summary>
  31. /// <param name="clientFactory"></param>
  32. /// <param name="jobPostRep"></param>
  33. public QiYeWeChatApiService(IHttpClientFactory clientFactory, JobPostRepository jobPostRep)
  34. {
  35. _httpClient = clientFactory.CreateClient("PublicQiYeWeChatApi"); ;
  36. _jobPostRep = jobPostRep;
  37. }
  38. /// <summary>
  39. /// 获取access_token
  40. /// </summary>
  41. /// <param name="applicationType">
  42. /// 1:人事助手
  43. /// 2:打卡
  44. /// 3:邮件
  45. /// 4:通讯录同步
  46. /// 5:审批
  47. /// </param>
  48. /// <returns></returns>
  49. private async Task<Access_TokenView> GetTokenAsync(int applicationType)
  50. {
  51. Access_TokenView tokenResult = new Access_TokenView();
  52. Access_Token_Request access_Token = new Access_Token_Request();
  53. string cacheName = string.Empty;
  54. if (applicationType == 1)
  55. {
  56. access_Token.corpsecret = PersonnelAssistant_Corpsecret; //人事助手
  57. cacheName = "PersonnelAssistant_Access_Token";
  58. }
  59. else if (applicationType == 2)
  60. {
  61. access_Token.corpsecret = PunchCard_Corpsecret; //打卡
  62. cacheName = "PunchCard_Access_Token";
  63. }
  64. else if (applicationType == 3)
  65. {
  66. access_Token.corpsecret = Email_Corpsecret; //E-Mail
  67. cacheName = "Enail_Access_Token";
  68. }
  69. else if (applicationType == 4) //通讯录同步
  70. {
  71. access_Token.corpsecret = AddressBook_Corpsecret;
  72. cacheName = "AddressBook_Access_Token";
  73. }
  74. else if (applicationType == 5) //审批
  75. {
  76. access_Token.corpsecret = Approve_Corpsecret;
  77. cacheName = "Approve_Access_Token";
  78. }
  79. else
  80. {
  81. tokenResult.errmsg = "未识别应用类型Id!";
  82. return tokenResult;
  83. }
  84. string access_token = await RedisRepository.RedisFactory
  85. .CreateRedisRepository()
  86. .StringGetAsync<string>(cacheName);//string 取
  87. if (string.IsNullOrEmpty(access_token))
  88. {
  89. string access_token_url = string.Format(@"/cgi-bin/gettoken?corpid={0}&corpsecret={1}", access_Token.corpid, access_Token.corpsecret);
  90. var access_tokenReq = await _httpClient.GetAsync(access_token_url);
  91. if (access_tokenReq.IsSuccessStatusCode)
  92. {
  93. var stringResponse = await access_tokenReq.Content.ReadAsStringAsync();
  94. tokenResult = System.Text.Json.JsonSerializer.Deserialize<Access_TokenView>(stringResponse,
  95. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  96. if (tokenResult.errcode == 0)
  97. {
  98. TimeSpan ts = DateTime.Now.AddMinutes(118) - DateTime.Now; //设置redis 过期时间 118分钟
  99. await RedisRepository
  100. .RedisFactory
  101. .CreateRedisRepository()
  102. .StringSetAsync<string>(cacheName, tokenResult.access_token, ts);//string 存
  103. }
  104. }
  105. else
  106. {
  107. tokenResult.errmsg = "企业微信Token未获取到!";
  108. }
  109. }
  110. else
  111. {
  112. tokenResult.errcode = 0;
  113. tokenResult.access_token = access_token;
  114. }
  115. return tokenResult;
  116. }
  117. #region 添加员工
  118. /// <summary>
  119. /// 获取成员ID列表
  120. /// </summary>
  121. /// <returns></returns>
  122. private async Task<UserIdListView> GetUserIdListAsync()
  123. {
  124. UserIdListView userIdListView = new UserIdListView();
  125. Access_TokenView access_Token = await GetTokenAsync(4);
  126. if (access_Token.errcode != 0)
  127. {
  128. userIdListView.errcode = access_Token.errcode;
  129. userIdListView.errmsg = access_Token.errmsg;
  130. return userIdListView;
  131. }
  132. string url = string.Format("/cgi-bin/user/list_id?access_token={0}&debug=1", access_Token.access_token);
  133. var jsonData = new
  134. {
  135. access_token = access_Token.access_token, //调用接口凭证
  136. };
  137. var json = System.Text.Json.JsonSerializer.Serialize(jsonData);
  138. var content = new StringContent(json, Encoding.UTF8, "application/json");
  139. var create_Req = await _httpClient.PostAsync(url, content);
  140. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  141. userIdListView = System.Text.Json.JsonSerializer.Deserialize<UserIdListView>(stringResponse,
  142. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  143. return userIdListView;
  144. }
  145. /// <summary>
  146. /// 获取部门列表
  147. /// </summary>
  148. /// <param name="access_token"></param>
  149. /// <returns></returns>
  150. private async Task<DepartmentListView> GetDepartmentAsync(string access_token)
  151. {
  152. DepartmentListView result = new DepartmentListView();
  153. string dep_url = string.Format("/cgi-bin/department/list?access_token={0}&debug=1", access_token);
  154. var depReq = await _httpClient.GetAsync(dep_url);
  155. if (depReq.IsSuccessStatusCode)
  156. {
  157. var stringResponse = await depReq.Content.ReadAsStringAsync();
  158. result = System.Text.Json.JsonSerializer.Deserialize<DepartmentListView>(stringResponse,
  159. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  160. }
  161. else
  162. {
  163. result.errcode = -1;
  164. result.errmsg = "企业微信部门列表未获取到!";
  165. }
  166. return result;
  167. }
  168. /// <summary>
  169. /// 创建员工
  170. /// </summary>
  171. /// <param name="create_Request"></param>
  172. /// <returns></returns>
  173. public async Task<ResponseBase> CreateAsync(Create_Request create_Request)
  174. {
  175. ResponseBase responseBase = new ResponseBase();
  176. #region 职位
  177. string depName = string.Empty,
  178. jobName = string.Empty;
  179. List<Sys_JobPostI> jobs = await _jobPostRep.QueryJobPost(string.Empty);
  180. Sys_JobPostI jobPost = jobs.Where(it => it.IsDel == 0 && it.Id == Convert.ToInt32(create_Request.position)).FirstOrDefault();
  181. if (jobPost != null)
  182. {
  183. depName = jobPost.DepName;
  184. jobName = jobPost.JobName;
  185. }
  186. create_Request.position = jobName;
  187. if (string.IsNullOrEmpty(create_Request.biz_mail))
  188. {
  189. create_Request.biz_mail = string.Format("{0}@pan-american-intl.com", create_Request.userid);
  190. }
  191. #endregion
  192. Access_TokenView access_Token = new Access_TokenView();
  193. access_Token = await GetTokenAsync(4);
  194. if (access_Token.errcode == 0)
  195. {
  196. create_Request.access_token = access_Token.access_token;
  197. #region 处理部门
  198. Access_TokenView dep_Access_Token = await GetTokenAsync(1);
  199. if (dep_Access_Token.errcode != 0)
  200. {
  201. responseBase.errcode = dep_Access_Token.errcode;
  202. responseBase.errmsg = dep_Access_Token.errmsg;
  203. }
  204. DepartmentListView depData = await GetDepartmentAsync(dep_Access_Token.access_token);
  205. if (depData.errcode == 0)
  206. {
  207. var depData1 = depData.department.Where(x => x.name == depName).FirstOrDefault();
  208. if (depData1 != null)
  209. {
  210. create_Request.department = new List<long> { depData1.id };
  211. }
  212. else
  213. {
  214. responseBase.errcode = -1;
  215. responseBase.errmsg = "未在企业微信上找到OA内设置的部门";
  216. return responseBase;
  217. }
  218. }
  219. else
  220. {
  221. responseBase.errcode = depData.errcode;
  222. responseBase.errmsg = depData.errmsg;
  223. return responseBase;
  224. }
  225. #endregion
  226. create_Request.access_token = access_Token.access_token;
  227. string create_url = string.Format("/cgi-bin/user/create?access_token={0}", create_Request.access_token);
  228. var json = System.Text.Json.JsonSerializer.Serialize(create_Request);
  229. var content = new StringContent(json, Encoding.UTF8, "application/json");
  230. var create_Req = await _httpClient.PostAsync(create_url, content);
  231. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  232. responseBase = System.Text.Json.JsonSerializer.Deserialize<ResponseBase>(stringResponse,
  233. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  234. }
  235. else
  236. {
  237. responseBase.errcode = access_Token.errcode;
  238. responseBase.errmsg = access_Token.errmsg;
  239. }
  240. return responseBase;
  241. }
  242. #endregion
  243. #region 打卡
  244. /// <summary>
  245. /// 获取月打卡数据
  246. /// </summary>
  247. /// <param name="startDt"></param>
  248. /// <param name="endDt"></param>
  249. /// <returns></returns>
  250. public async Task<CheckInView> GetCheckin_MonthDataAsync(DateTime startDt,DateTime endDt)
  251. {
  252. CheckInView checkInView = new CheckInView();
  253. string checkInDatastring = await RedisRepository.RedisFactory
  254. .CreateRedisRepository()
  255. .StringGetAsync<string>("Checkin_MonthData");//List<T> 取
  256. if (!string.IsNullOrEmpty(checkInDatastring))
  257. {
  258. checkInView = JsonConvert.DeserializeObject<CheckInView>(checkInDatastring);
  259. return checkInView;
  260. }
  261. //获取员工Id
  262. UserIdListView userIdListView = await GetUserIdListAsync();
  263. if (userIdListView.errcode != 0)
  264. {
  265. checkInView.errcode = userIdListView.errcode;
  266. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】{0}",userIdListView.errmsg);
  267. return checkInView;
  268. }
  269. if (userIdListView.dept_user == null || userIdListView.dept_user.Count <= 0)
  270. {
  271. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】未查出员工Id");
  272. return checkInView;
  273. }
  274. //获取月打卡数据 token
  275. Access_TokenView access_Token = await GetTokenAsync(2);
  276. if (access_Token.errcode != 0)
  277. {
  278. checkInView.errcode = access_Token.errcode;
  279. checkInView.errmsg = string.Format("【企业微信】【获取月打卡数据】【Token】【Msg】{0}", access_Token.errmsg);
  280. return checkInView;
  281. }
  282. string url = string.Format("/cgi-bin/checkin/getcheckin_monthdata?access_token={0}", access_Token.access_token);
  283. Checkin_MonthData_Request checkInReq = new Checkin_MonthData_Request();
  284. checkInReq.access_token = access_Token.access_token;
  285. checkInReq.starttime = (uint)(startDt - _1970).TotalSeconds;
  286. checkInReq.endtime = (uint)(endDt - _1970).TotalSeconds;
  287. checkInReq.useridlist = userIdListView.dept_user.Select(it => it.userid).ToList();
  288. var json = System.Text.Json.JsonSerializer.Serialize(checkInReq);
  289. var content = new StringContent(json, Encoding.UTF8, "application/json");
  290. var create_Req = await _httpClient.PostAsync(url, content);
  291. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  292. checkInView = System.Text.Json.JsonSerializer.Deserialize<CheckInView>(stringResponse,
  293. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  294. TimeSpan ts = DateTime.Now.AddMinutes(60) - DateTime.Now; //设置redis 过期时间 60分钟
  295. await RedisRepository
  296. .RedisFactory
  297. .CreateRedisRepository()
  298. .StringSetAsync<string>("Checkin_MonthData", JsonConvert.SerializeObject(checkInView), ts);//List<T> 存
  299. return checkInView;
  300. }
  301. #endregion
  302. #region 审批
  303. /// <summary>
  304. /// 获取审批数据(旧)
  305. /// </summary>
  306. /// <param name="startDt"></param>
  307. /// <param name="endDt"></param>
  308. /// <returns></returns>
  309. public async Task<ApprovalDataView> GetApprovalDataAsync(DateTime startDt, DateTime endDt)
  310. {
  311. ApprovalDataView approvalDataView = new ApprovalDataView();
  312. //获取审批数据 token
  313. Access_TokenView access_Token = await GetTokenAsync(5);
  314. if (access_Token.errcode != 0)
  315. {
  316. approvalDataView.errcode = access_Token.errcode;
  317. approvalDataView.errmsg = string.Format("【企业微信】【获取审批数据】【Token】【Msg】{0}", access_Token.errmsg);
  318. return approvalDataView;
  319. }
  320. string url = string.Format("/cgi-bin/corp/getapprovaldata?access_token={0}", access_Token.access_token);
  321. ApprovalData_Request approvalDataReq = new ApprovalData_Request();
  322. approvalDataReq.access_token = access_Token.access_token;
  323. approvalDataReq.starttime = (uint)(startDt - _1970).TotalSeconds;
  324. approvalDataReq.endtime = (uint)(endDt - _1970).TotalSeconds;
  325. var json = System.Text.Json.JsonSerializer.Serialize(approvalDataReq);
  326. var content = new StringContent(json, Encoding.UTF8, "application/json");
  327. var create_Req = await _httpClient.PostAsync(url, content);
  328. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  329. approvalDataView = System.Text.Json.JsonSerializer.Deserialize<ApprovalDataView>(stringResponse,
  330. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  331. List<Sp_Info> sp_datas = new List<Sp_Info>();
  332. sp_datas.AddRange(approvalDataView.data);
  333. int index = 0;
  334. //多次访问审批接口
  335. if (approvalDataView.total>=100)
  336. {
  337. approvalDataView.total -= 100;
  338. int forTotal = approvalDataView.total % 100 == 0 ? approvalDataView.total / 100 : approvalDataView.total / 100 + 1;
  339. long? next_spnum = approvalDataView.next_spnum;
  340. approvalDataReq.next_spnum = next_spnum;
  341. for (int i = 0; i < forTotal; i++)
  342. {
  343. index++;
  344. var for_json = System.Text.Json.JsonSerializer.Serialize(approvalDataReq);
  345. var for_content = new StringContent(for_json, Encoding.UTF8, "application/json");
  346. var for_create_Req = await _httpClient.PostAsync(url, for_content);
  347. var for_stringResponse = await for_create_Req.Content.ReadAsStringAsync();
  348. ApprovalDataView for_approvalDataView = System.Text.Json.JsonSerializer.Deserialize<ApprovalDataView>(for_stringResponse,
  349. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  350. approvalDataReq.next_spnum = for_approvalDataView.next_spnum; //重新定义游标
  351. sp_datas.AddRange(for_approvalDataView.data); //追加数据
  352. }
  353. approvalDataView.total += 100;
  354. }
  355. approvalDataView.data = sp_datas;
  356. return approvalDataView;
  357. }
  358. #endregion
  359. }
  360. }