QiYeWeChatApiService.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813
  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 SqlSugar;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Diagnostics;
  9. using System.Text.Json;
  10. using Ubiety.Dns.Core;
  11. namespace OASystem.API.OAMethodLib.QiYeWeChatAPI
  12. {
  13. /// <summary>
  14. /// 聚合Api 服务
  15. /// </summary>
  16. public class QiYeWeChatApiService: IQiYeWeChatApiService
  17. {
  18. private readonly HttpClient _httpClient;
  19. private readonly string CorpId = "wwe978bef5495a0728"; //企业Id
  20. private readonly string PersonnelAssistant_AgentId = "3010011"; //人事助手Id
  21. private readonly string PersonnelAssistant_Corpsecret = "ig--IJd6TxWDMJ1wT4e-RDRcRX12v5GjB359DNATwJ4"; //人事助手凭证密钥
  22. private readonly string PunchCard_AgentId = "3010185"; //打卡Id
  23. private readonly string PunchCard_Corpsecret = "Xhrl37GOqlAjsu0VzUSJECaJdjzkDXQLbvrzRsZQb8M"; //打卡凭证密钥
  24. private readonly string Email_AgentId = "1000004"; //E-Mail Id
  25. private readonly string Email_Corpsecret = "NA1zbJM15GmgjPYwDOqz59dIo1Wnug-MbU107MeUemc"; //E-Mail 凭证密钥
  26. private readonly string AddressBook_Corpsecret = "Y1tnjh7j-BvbqAytAoXZPUbmDR6dqLTL6mXtc6PZ7fo"; //通讯录同步 凭证密钥
  27. private readonly string Approve_AgentId = "3010040"; //审批 Id
  28. private readonly string Approve_Corpsecret = "k_Jo69Jw9Hqg_in-Rypbs30PNbxOYa1t4e-dxYuT-kw"; //审批 凭证密钥
  29. private readonly DateTime _1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0);
  30. private readonly JobPostRepository _jobPostRep;
  31. /// <summary>
  32. /// 初始化
  33. /// </summary>
  34. /// <param name="clientFactory"></param>
  35. /// <param name="jobPostRep"></param>
  36. public QiYeWeChatApiService(IHttpClientFactory clientFactory, JobPostRepository jobPostRep)
  37. {
  38. _httpClient = clientFactory.CreateClient("PublicQiYeWeChatApi"); ;
  39. _jobPostRep = jobPostRep;
  40. }
  41. /// <summary>
  42. /// 获取access_token
  43. /// </summary>
  44. /// <param name="applicationType">
  45. /// 1:人事助手
  46. /// 2:打卡
  47. /// 3:邮件
  48. /// 4:通讯录同步
  49. /// 5:审批
  50. /// </param>
  51. /// <returns></returns>
  52. private async Task<Access_TokenView> GetTokenAsync(int applicationType)
  53. {
  54. Access_TokenView tokenResult = new Access_TokenView();
  55. Access_Token_Request access_Token = new Access_Token_Request();
  56. string cacheName = string.Empty;
  57. if (applicationType == 1)
  58. {
  59. access_Token.corpsecret = PersonnelAssistant_Corpsecret; //人事助手
  60. cacheName = "PersonnelAssistant_Access_Token";
  61. }
  62. else if (applicationType == 2)
  63. {
  64. access_Token.corpsecret = PunchCard_Corpsecret; //打卡
  65. cacheName = "PunchCard_Access_Token";
  66. }
  67. else if (applicationType == 3)
  68. {
  69. access_Token.corpsecret = Email_Corpsecret; //E-Mail
  70. cacheName = "Enail_Access_Token";
  71. }
  72. else if (applicationType == 4) //通讯录同步
  73. {
  74. access_Token.corpsecret = AddressBook_Corpsecret;
  75. cacheName = "AddressBook_Access_Token";
  76. }
  77. else if (applicationType == 5) //审批
  78. {
  79. access_Token.corpsecret = Approve_Corpsecret;
  80. cacheName = "Approve_Access_Token";
  81. }
  82. else
  83. {
  84. tokenResult.errmsg = "未识别应用类型Id!";
  85. return tokenResult;
  86. }
  87. string access_token = await RedisRepository.RedisFactory
  88. .CreateRedisRepository()
  89. .StringGetAsync<string>(cacheName);//string 取
  90. if (string.IsNullOrEmpty(access_token))
  91. {
  92. string access_token_url = string.Format(@"/cgi-bin/gettoken?corpid={0}&corpsecret={1}", access_Token.corpid, access_Token.corpsecret);
  93. var access_tokenReq = await _httpClient.GetAsync(access_token_url);
  94. if (access_tokenReq.IsSuccessStatusCode)
  95. {
  96. var stringResponse = await access_tokenReq.Content.ReadAsStringAsync();
  97. tokenResult = System.Text.Json.JsonSerializer.Deserialize<Access_TokenView>(stringResponse,
  98. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  99. if (tokenResult.errcode == 0)
  100. {
  101. TimeSpan ts = DateTime.Now.AddMinutes(118) - DateTime.Now; //设置redis 过期时间 118分钟
  102. await RedisRepository
  103. .RedisFactory
  104. .CreateRedisRepository()
  105. .StringSetAsync<string>(cacheName, tokenResult.access_token, ts);//string 存
  106. }
  107. }
  108. else
  109. {
  110. tokenResult.errmsg = "企业微信Token未获取到!";
  111. }
  112. }
  113. else
  114. {
  115. tokenResult.errcode = 0;
  116. tokenResult.access_token = access_token;
  117. }
  118. return tokenResult;
  119. }
  120. #region 添加员工
  121. /// <summary>
  122. /// 获取成员ID列表
  123. /// </summary>
  124. /// <returns></returns>
  125. private async Task<UserIdListView> GetUserIdListAsync()
  126. {
  127. UserIdListView userIdListView = new UserIdListView();
  128. Access_TokenView access_Token = await GetTokenAsync(4);
  129. if (access_Token.errcode != 0)
  130. {
  131. userIdListView.errcode = access_Token.errcode;
  132. userIdListView.errmsg = access_Token.errmsg;
  133. return userIdListView;
  134. }
  135. string url = string.Format("/cgi-bin/user/list_id?access_token={0}&debug=1", access_Token.access_token);
  136. var jsonData = new
  137. {
  138. access_token = access_Token.access_token, //调用接口凭证
  139. };
  140. var json = System.Text.Json.JsonSerializer.Serialize(jsonData);
  141. var content = new StringContent(json, Encoding.UTF8, "application/json");
  142. var create_Req = await _httpClient.PostAsync(url, content);
  143. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  144. userIdListView = System.Text.Json.JsonSerializer.Deserialize<UserIdListView>(stringResponse,
  145. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  146. return userIdListView;
  147. }
  148. /// <summary>
  149. /// 获取部门列表
  150. /// </summary>
  151. /// <param name="access_token"></param>
  152. /// <returns></returns>
  153. private async Task<DepartmentListView> GetDepartmentAsync(string access_token)
  154. {
  155. DepartmentListView result = new DepartmentListView();
  156. string dep_url = string.Format("/cgi-bin/department/list?access_token={0}&debug=1", access_token);
  157. var depReq = await _httpClient.GetAsync(dep_url);
  158. if (depReq.IsSuccessStatusCode)
  159. {
  160. var stringResponse = await depReq.Content.ReadAsStringAsync();
  161. result = System.Text.Json.JsonSerializer.Deserialize<DepartmentListView>(stringResponse,
  162. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  163. }
  164. else
  165. {
  166. result.errcode = -1;
  167. result.errmsg = "企业微信部门列表未获取到!";
  168. }
  169. return result;
  170. }
  171. /// <summary>
  172. /// 创建员工
  173. /// </summary>
  174. /// <param name="create_Request"></param>
  175. /// <returns></returns>
  176. public async Task<ResponseBase> CreateAsync(Create_Request create_Request)
  177. {
  178. ResponseBase responseBase = new ResponseBase();
  179. #region 职位
  180. string depName = string.Empty,
  181. jobName = string.Empty;
  182. List<Sys_JobPostI> jobs = await _jobPostRep.QueryJobPost(string.Empty);
  183. Sys_JobPostI jobPost = jobs.Where(it => it.IsDel == 0 && it.Id == Convert.ToInt32(create_Request.position)).FirstOrDefault();
  184. if (jobPost != null)
  185. {
  186. depName = jobPost.DepName;
  187. jobName = jobPost.JobName;
  188. }
  189. create_Request.position = jobName;
  190. if (string.IsNullOrEmpty(create_Request.biz_mail))
  191. {
  192. create_Request.biz_mail = string.Format("{0}@pan-american-intl.com", create_Request.userid);
  193. }
  194. #endregion
  195. Access_TokenView access_Token = new Access_TokenView();
  196. access_Token = await GetTokenAsync(4);
  197. if (access_Token.errcode == 0)
  198. {
  199. create_Request.access_token = access_Token.access_token;
  200. #region 处理部门
  201. Access_TokenView dep_Access_Token = await GetTokenAsync(1);
  202. if (dep_Access_Token.errcode != 0)
  203. {
  204. responseBase.errcode = dep_Access_Token.errcode;
  205. responseBase.errmsg = dep_Access_Token.errmsg;
  206. }
  207. DepartmentListView depData = await GetDepartmentAsync(dep_Access_Token.access_token);
  208. if (depData.errcode == 0)
  209. {
  210. var depData1 = depData.department.Where(x => x.name == depName).FirstOrDefault();
  211. if (depData1 != null)
  212. {
  213. create_Request.department = new List<long> { depData1.id };
  214. }
  215. else
  216. {
  217. responseBase.errcode = -1;
  218. responseBase.errmsg = "未在企业微信上找到OA内设置的部门";
  219. return responseBase;
  220. }
  221. }
  222. else
  223. {
  224. responseBase.errcode = depData.errcode;
  225. responseBase.errmsg = depData.errmsg;
  226. return responseBase;
  227. }
  228. #endregion
  229. create_Request.access_token = access_Token.access_token;
  230. string create_url = string.Format("/cgi-bin/user/create?access_token={0}", create_Request.access_token);
  231. var json = System.Text.Json.JsonSerializer.Serialize(create_Request);
  232. var content = new StringContent(json, Encoding.UTF8, "application/json");
  233. var create_Req = await _httpClient.PostAsync(create_url, content);
  234. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  235. responseBase = System.Text.Json.JsonSerializer.Deserialize<ResponseBase>(stringResponse,
  236. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  237. }
  238. else
  239. {
  240. responseBase.errcode = access_Token.errcode;
  241. responseBase.errmsg = access_Token.errmsg;
  242. }
  243. return responseBase;
  244. }
  245. #endregion
  246. #region 打卡
  247. /// <summary>
  248. /// 获取月打卡数据(redis缓存)
  249. /// </summary>
  250. /// <param name="startDt"></param>
  251. /// <param name="endDt"></param>
  252. /// <returns></returns>
  253. public async Task<CheckInView> GetCheckin_MonthDataAsync(DateTime startDt,DateTime endDt)
  254. {
  255. CheckInView checkInView = new CheckInView();
  256. //获取员工Id
  257. UserIdListView userIdListView = await GetUserIdListAsync();
  258. if (userIdListView.errcode != 0)
  259. {
  260. checkInView.errcode = userIdListView.errcode;
  261. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】{0}",userIdListView.errmsg);
  262. return checkInView;
  263. }
  264. if (userIdListView.dept_user == null || userIdListView.dept_user.Count <= 0)
  265. {
  266. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】未查出员工Id");
  267. return checkInView;
  268. }
  269. //获取月打卡数据 token
  270. Access_TokenView access_Token = await GetTokenAsync(2);
  271. if (access_Token.errcode != 0)
  272. {
  273. checkInView.errcode = access_Token.errcode;
  274. checkInView.errmsg = string.Format("【企业微信】【获取月打卡数据】【Token】【Msg】{0}", access_Token.errmsg);
  275. return checkInView;
  276. }
  277. string url = string.Format("/cgi-bin/checkin/getcheckin_monthdata?access_token={0}", access_Token.access_token);
  278. Checkin_MonthData_Request checkInReq = new Checkin_MonthData_Request();
  279. checkInReq.access_token = access_Token.access_token;
  280. checkInReq.starttime = (uint)(startDt - _1970).TotalSeconds;
  281. checkInReq.endtime = (uint)(endDt - _1970).TotalSeconds;
  282. checkInReq.useridlist = userIdListView.dept_user.Select(it => it.userid).ToList();
  283. var json = System.Text.Json.JsonSerializer.Serialize(checkInReq);
  284. var content = new StringContent(json, Encoding.UTF8, "application/json");
  285. var create_Req = await _httpClient.PostAsync(url, content);
  286. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  287. checkInView = System.Text.Json.JsonSerializer.Deserialize<CheckInView>(stringResponse,
  288. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  289. return checkInView;
  290. }
  291. /// <summary>
  292. /// 获取月打卡数据(redis缓存)
  293. /// </summary>
  294. /// <param name="startDt"></param>
  295. /// <param name="endDt"></param>
  296. /// <returns></returns>
  297. public async Task<CheckInView> GetCheckin_MonthDataRedisAsync(DateTime startDt, DateTime endDt)
  298. {
  299. CheckInView checkInView = new CheckInView();
  300. string checkInDatastring = await RedisRepository.RedisFactory
  301. .CreateRedisRepository()
  302. .StringGetAsync<string>("Checkin_MonthData");//List<T> 取
  303. if (!string.IsNullOrEmpty(checkInDatastring))
  304. {
  305. checkInView = JsonConvert.DeserializeObject<CheckInView>(checkInDatastring);
  306. return checkInView;
  307. }
  308. //获取员工Id
  309. UserIdListView userIdListView = await GetUserIdListAsync();
  310. if (userIdListView.errcode != 0)
  311. {
  312. checkInView.errcode = userIdListView.errcode;
  313. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】{0}", userIdListView.errmsg);
  314. return checkInView;
  315. }
  316. if (userIdListView.dept_user == null || userIdListView.dept_user.Count <= 0)
  317. {
  318. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】未查出员工Id");
  319. return checkInView;
  320. }
  321. //获取月打卡数据 token
  322. Access_TokenView access_Token = await GetTokenAsync(2);
  323. if (access_Token.errcode != 0)
  324. {
  325. checkInView.errcode = access_Token.errcode;
  326. checkInView.errmsg = string.Format("【企业微信】【获取月打卡数据】【Token】【Msg】{0}", access_Token.errmsg);
  327. return checkInView;
  328. }
  329. string url = string.Format("/cgi-bin/checkin/getcheckin_monthdata?access_token={0}", access_Token.access_token);
  330. Checkin_MonthData_Request checkInReq = new Checkin_MonthData_Request();
  331. checkInReq.access_token = access_Token.access_token;
  332. checkInReq.starttime = (uint)(startDt - _1970).TotalSeconds;
  333. checkInReq.endtime = (uint)(endDt - _1970).TotalSeconds;
  334. checkInReq.useridlist = userIdListView.dept_user.Select(it => it.userid).ToList();
  335. var json = System.Text.Json.JsonSerializer.Serialize(checkInReq);
  336. var content = new StringContent(json, Encoding.UTF8, "application/json");
  337. var create_Req = await _httpClient.PostAsync(url, content);
  338. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  339. checkInView = System.Text.Json.JsonSerializer.Deserialize<CheckInView>(stringResponse,
  340. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  341. if (checkInView.errcode == 0)
  342. {
  343. TimeSpan ts = DateTime.Now.AddMinutes(60) - DateTime.Now; //设置redis 过期时间 60分钟
  344. await RedisRepository
  345. .RedisFactory
  346. .CreateRedisRepository()
  347. .StringSetAsync<string>("Checkin_MonthData", JsonConvert.SerializeObject(checkInView), ts);//List<T> 存
  348. }
  349. return checkInView;
  350. }
  351. #endregion
  352. #region 审批
  353. /// <summary>
  354. /// 获取审批数据(旧)
  355. /// </summary>
  356. /// <param name="startDt"></param>
  357. /// <param name="endDt"></param>
  358. /// <returns></returns>
  359. public async Task<ApprovalDataView> GetApprovalDataAsync(DateTime startDt, DateTime endDt)
  360. {
  361. ApprovalDataView approvalDataView = new ApprovalDataView();
  362. //获取审批数据 token
  363. Access_TokenView access_Token = await GetTokenAsync(5);
  364. if (access_Token.errcode != 0)
  365. {
  366. approvalDataView.errcode = access_Token.errcode;
  367. approvalDataView.errmsg = string.Format("【企业微信】【获取审批数据】【Token】【Msg】{0}", access_Token.errmsg);
  368. return approvalDataView;
  369. }
  370. string url = string.Format("/cgi-bin/corp/getapprovaldata?access_token={0}", access_Token.access_token);
  371. ApprovalData_Request approvalDataReq = new ApprovalData_Request();
  372. approvalDataReq.access_token = access_Token.access_token;
  373. approvalDataReq.starttime = (uint)(startDt - _1970).TotalSeconds;
  374. approvalDataReq.endtime = (uint)(endDt - _1970).TotalSeconds;
  375. var json = System.Text.Json.JsonSerializer.Serialize(approvalDataReq);
  376. var content = new StringContent(json, Encoding.UTF8, "application/json");
  377. var create_Req = await _httpClient.PostAsync(url, content);
  378. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  379. approvalDataView = System.Text.Json.JsonSerializer.Deserialize<ApprovalDataView>(stringResponse,
  380. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  381. List<Sp_Info> sp_datas = new List<Sp_Info>();
  382. sp_datas.AddRange(approvalDataView.data);
  383. int index = 0;
  384. //多次访问审批接口
  385. if (approvalDataView.total>=100)
  386. {
  387. approvalDataView.total -= 100;
  388. int forTotal = approvalDataView.total % 100 == 0 ? approvalDataView.total / 100 : approvalDataView.total / 100 + 1;
  389. long? next_spnum = approvalDataView.next_spnum;
  390. approvalDataReq.next_spnum = next_spnum;
  391. for (int i = 0; i < forTotal; i++)
  392. {
  393. index++;
  394. var for_json = System.Text.Json.JsonSerializer.Serialize(approvalDataReq);
  395. var for_content = new StringContent(for_json, Encoding.UTF8, "application/json");
  396. var for_create_Req = await _httpClient.PostAsync(url, for_content);
  397. var for_stringResponse = await for_create_Req.Content.ReadAsStringAsync();
  398. ApprovalDataView for_approvalDataView = System.Text.Json.JsonSerializer.Deserialize<ApprovalDataView>(for_stringResponse,
  399. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  400. approvalDataReq.next_spnum = for_approvalDataView.next_spnum; //重新定义游标
  401. sp_datas.AddRange(for_approvalDataView.data); //追加数据
  402. }
  403. approvalDataView.total += 100;
  404. }
  405. approvalDataView.data = sp_datas;
  406. return approvalDataView;
  407. }
  408. /// <summary>
  409. /// 获取审批数据(旧)(redis缓存)
  410. /// </summary>
  411. /// <param name="startDt"></param>
  412. /// <param name="endDt"></param>
  413. /// <returns></returns>
  414. public async Task<List<Sp_Info>> GetApprovalDatasAsync(DateTime startDt, DateTime endDt)
  415. {
  416. List<Sp_Info> sp_Infos = new List<Sp_Info>();
  417. //获取所有打卡补卡,审批 数据 前后范围增加10天
  418. DateTime sp_startDt = startDt.AddDays(-10);
  419. DateTime sp_centerDt = sp_startDt.AddDays(30);
  420. DateTime sp_endDt = endDt.AddDays(10);
  421. ApprovalDataView approvalData_1 = await GetApprovalDataAsync(sp_startDt, sp_centerDt); //时间段内所有 审批数据
  422. ApprovalDataView approvalData_2 = await GetApprovalDataAsync(sp_centerDt, sp_endDt); //时间段内所有 审批数据
  423. if (approvalData_1.errcode != 0)
  424. {
  425. Log.Error("企业微信 获取 " + sp_startDt + " - " + sp_centerDt + " 内审批 Msg:" + approvalData_1.errmsg);
  426. return sp_Infos;
  427. }
  428. sp_Infos.AddRange(approvalData_1.data);
  429. if (approvalData_2.errcode != 0)
  430. {
  431. Log.Error("企业微信 获取 " + sp_centerDt + " - " + sp_endDt + " 内审批 Msg:" + approvalData_2.errmsg);
  432. return sp_Infos;
  433. }
  434. sp_Infos.AddRange(approvalData_2.data);
  435. sp_Infos = sp_Infos.Where(it => it.sp_status == 2).ToList(); //存储已审核的数据
  436. return sp_Infos;
  437. }
  438. /// <summary>
  439. /// 获取审批数据(旧)(redis缓存)
  440. /// </summary>
  441. /// <param name="startDt"></param>
  442. /// <param name="endDt"></param>
  443. /// <returns></returns>
  444. public async Task<List<Sp_Info>> GetApprovalDatasRedisAsync(DateTime startDt, DateTime endDt)
  445. {
  446. List<Sp_Info> sp_Infos = new List<Sp_Info>();
  447. //获取所有打卡补卡,审批 数据 前后范围增加10天
  448. DateTime sp_startDt = startDt.AddDays(-10);
  449. DateTime sp_centerDt = sp_startDt.AddDays(30);
  450. DateTime sp_endDt = endDt.AddDays(10);
  451. string redisName = "ApprovalData" + sp_startDt.ToString("yyyyMMdd") + "-" + sp_endDt.ToString("yyyyMMdd");
  452. string sp_InfosString = string.Empty;
  453. //sp_InfosString = await RedisRepository.RedisFactory
  454. // .CreateRedisRepository()
  455. // .StringGetAsync<string>(redisName);//string 取
  456. if (string.IsNullOrEmpty(sp_InfosString))
  457. {
  458. ApprovalDataView approvalData_1 = await GetApprovalDataAsync(sp_startDt, sp_centerDt); //时间段内所有 审批数据
  459. ApprovalDataView approvalData_2 = await GetApprovalDataAsync(sp_centerDt, sp_endDt); //时间段内所有 审批数据
  460. if (approvalData_1.errcode != 0)
  461. {
  462. Log.Error("企业微信 获取 "+ sp_startDt + " - "+ sp_centerDt + " 内审批 Msg:" + approvalData_1.errmsg);
  463. return sp_Infos;
  464. }
  465. sp_Infos.AddRange(approvalData_1.data);
  466. if (approvalData_2.errcode != 0)
  467. {
  468. Log.Error("企业微信 获取 "+ sp_centerDt + " - "+ sp_endDt + " 内审批 Msg:" + approvalData_2.errmsg);
  469. return sp_Infos;
  470. }
  471. sp_Infos.AddRange(approvalData_2.data);
  472. sp_Infos = sp_Infos.Where(it => it.sp_status == 2).ToList(); //存储已审核的数据
  473. TimeSpan ts = DateTime.Now.AddMinutes(60) - DateTime.Now; //设置redis 过期时间 60分钟
  474. await RedisRepository
  475. .RedisFactory
  476. .CreateRedisRepository()
  477. .StringSetAsync<string>(redisName, JsonConvert.SerializeObject(sp_Infos), ts);//string 存
  478. }
  479. else
  480. {
  481. sp_Infos = JsonConvert.DeserializeObject<List<Sp_Info>>(sp_InfosString);
  482. }
  483. return sp_Infos;
  484. }
  485. /// <summary>
  486. /// 批量获取审批单号
  487. /// </summary>
  488. /// <param name="startDt"></param>
  489. /// <param name="endDt"></param>
  490. /// <param name="sp_status">
  491. /// sp_status-审批单状态(1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付)
  492. /// </param>
  493. /// <param name="record_type">
  494. /// record_type - 审批单类型属性,1-请假;2-打卡补卡;3-出差;4-外出;5-加班; 6- 调班;7-会议室预定;8-退款审批;9-红包报销审批
  495. /// </param>
  496. /// <returns></returns>
  497. private async Task<ApprovalInfoView> GetApprovalInfoAsync(DateTime startDt,DateTime endDt,int sp_status, int record_type)
  498. {
  499. Stopwatch sw = new Stopwatch();
  500. sw.Start();
  501. ApprovalInfoView approvalInfoView = new ApprovalInfoView();
  502. //获取所有打卡补卡,审批 数据 前后范围增加10天
  503. DateTime sp_startDt = startDt.AddDays(-10);
  504. DateTime sp_centerDt = sp_startDt.AddDays(30);
  505. DateTime sp_endDt = endDt.AddDays(10);
  506. //获取审批数据 token
  507. Access_TokenView access_Token = await GetTokenAsync(5);
  508. if (access_Token.errcode != 0)
  509. {
  510. approvalInfoView.errcode = access_Token.errcode;
  511. approvalInfoView.errmsg = string.Format("【企业微信】【批量获取审批单号】【Token】【Msg】{0}", access_Token.errmsg);
  512. return approvalInfoView;
  513. }
  514. string url = string.Format("/cgi-bin/oa/getapprovalinfo?access_token={0}", access_Token.access_token);
  515. List<Dic> filters = new List<Dic> {
  516. new Dic() { key = "sp_status", value = sp_status.ToString() }, //筛选条件 审核状态 2 已同意
  517. new Dic() { key = "record_type", value = record_type.ToString() }, //筛选条件 审批单类型 请假 1
  518. };
  519. ApprovalInfo_Request approvalInfoReq = new ApprovalInfo_Request()
  520. {
  521. access_token = access_Token.access_token,
  522. starttime = (uint)(startDt - _1970).TotalSeconds,
  523. endtime = (uint)(endDt - _1970).TotalSeconds,
  524. filters = filters.ToList(),
  525. };
  526. var json = System.Text.Json.JsonSerializer.Serialize(approvalInfoReq);
  527. var content = new StringContent(json, Encoding.UTF8, "application/json");
  528. var create_Req = await _httpClient.PostAsync(url, content);
  529. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  530. approvalInfoView = System.Text.Json.JsonSerializer.Deserialize<ApprovalInfoView>(stringResponse,
  531. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  532. List<string> sp_datas = new List<string>();
  533. sp_datas.AddRange(approvalInfoView.sp_no_list);
  534. int index = 0;
  535. while (true)
  536. {
  537. if (string.IsNullOrEmpty(approvalInfoView.new_next_cursor)) break;
  538. string new_cursor = approvalInfoView.new_next_cursor;
  539. approvalInfoReq.new_cursor = new_cursor;
  540. var while_json = System.Text.Json.JsonSerializer.Serialize(approvalInfoReq);
  541. var while_content = new StringContent(while_json, Encoding.UTF8, "application/json");
  542. var while_create_Req = await _httpClient.PostAsync(url, while_content);
  543. var while_stringResponse = await while_create_Req.Content.ReadAsStringAsync();
  544. approvalInfoView = System.Text.Json.JsonSerializer.Deserialize<ApprovalInfoView>(while_stringResponse,
  545. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  546. sp_datas.AddRange(approvalInfoView.sp_no_list); //追加数据
  547. index++;
  548. }
  549. approvalInfoView.sp_no_list = sp_datas;
  550. sw.Stop();
  551. approvalInfoView.errmsg = approvalInfoView.errmsg + " 耗时:" + sw.Elapsed.TotalMilliseconds + "ms";
  552. return approvalInfoView;
  553. }
  554. /// <summary>
  555. /// 获取审批申请详情
  556. /// </summary>
  557. /// <param name="sp_no"></param>
  558. /// <returns></returns>
  559. private async Task<ApprovalDetailView> GetApprovalDetailAsync(string sp_no)
  560. {
  561. ApprovalDetailView ApprovalDetailView = new ApprovalDetailView();
  562. if (string.IsNullOrEmpty(sp_no))
  563. {
  564. return ApprovalDetailView;
  565. }
  566. //获取审批数据 token
  567. Access_TokenView access_Token = await GetTokenAsync(5);
  568. if (access_Token.errcode != 0)
  569. {
  570. ApprovalDetailView.errcode = access_Token.errcode;
  571. ApprovalDetailView.errmsg = string.Format("【企业微信】【审批申请详情】【Token】【Msg】{0}", access_Token.errmsg);
  572. return ApprovalDetailView;
  573. }
  574. string url = string.Format("/cgi-bin/oa/getapprovaldetail?access_token={0}", access_Token.access_token);
  575. ApprovalDetail_Request approvalDetail_Req = new ApprovalDetail_Request() {
  576. access_token = access_Token.access_token,
  577. sp_no = sp_no,
  578. };
  579. var json = System.Text.Json.JsonSerializer.Serialize(approvalDetail_Req);
  580. var content = new StringContent(json, Encoding.UTF8, "application/json");
  581. var create_Req = await _httpClient.PostAsync(url, content);
  582. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  583. ApprovalDetailView = System.Text.Json.JsonSerializer.Deserialize<ApprovalDetailView>(stringResponse,
  584. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  585. return ApprovalDetailView;
  586. }
  587. /// <summary>
  588. /// 批量获取审批详情
  589. /// </summary>
  590. /// <param name="startDt"></param>
  591. /// <param name="endDt"></param>
  592. /// <param name="sp_status">
  593. /// sp_status-审批单状态(1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付)
  594. /// </param>
  595. /// <param name="record_type">
  596. /// record_type - 审批单类型属性,1-请假;2-打卡补卡;3-出差;4-外出;5-加班; 6- 调班;7-会议室预定;8-退款审批;9-红包报销审批
  597. /// </param>
  598. /// <returns></returns>
  599. public async Task<List<Sp_Detail>> GetApprovalDetailsAsync(DateTime startDt, DateTime endDt,int sp_status, int record_type)
  600. {
  601. List<Sp_Detail> details = new List<Sp_Detail>();
  602. Stopwatch sw = new Stopwatch();
  603. sw.Start();
  604. ApprovalInfoView approvalInfoView = new ApprovalInfoView();
  605. approvalInfoView = await GetApprovalInfoAsync(startDt,endDt, sp_status,record_type);
  606. if (approvalInfoView.errcode != 0)
  607. {
  608. return details;
  609. }
  610. //循环查询详情
  611. foreach (var item in approvalInfoView.sp_no_list)
  612. {
  613. ApprovalDetailView approvalDetailView = new ApprovalDetailView();
  614. approvalDetailView = await GetApprovalDetailAsync(item);
  615. if (approvalDetailView.errcode != 0)
  616. {
  617. Log.Error("【GetApprovalDetailsAsync】 record_type:" + record_type + " ErrorMsg:" + approvalDetailView.errmsg);
  618. break;
  619. }
  620. details.Add(approvalDetailView.info);
  621. }
  622. sw.Stop();
  623. double hs = sw.Elapsed.TotalMilliseconds;
  624. return details;
  625. }
  626. /// <summary>
  627. /// 获取审批模板详情
  628. /// </summary>
  629. /// <param name="template_id">模板Id</param>
  630. /// <returns></returns>
  631. public async Task<TemplateDetailView> GetTemplateDetailAsync(string template_id)
  632. {
  633. TemplateDetailView templateDetailView = new TemplateDetailView();
  634. if (string.IsNullOrEmpty(template_id))
  635. {
  636. templateDetailView.errmsg = "template_id为空!";
  637. return templateDetailView;
  638. }
  639. //获取审批数据 token
  640. Access_TokenView access_Token = await GetTokenAsync(5);
  641. if (access_Token.errcode != 0)
  642. {
  643. templateDetailView.errcode = access_Token.errcode;
  644. templateDetailView.errmsg = string.Format("【企业微信】【审批申请详情】【Token】【Msg】{0}", access_Token.errmsg);
  645. return templateDetailView;
  646. }
  647. string url = string.Format("/cgi-bin/oa/gettemplatedetail?access_token={0}", access_Token.access_token);
  648. var approvalDetail_Req = new
  649. {
  650. access_token = access_Token.access_token,
  651. template_id = template_id,
  652. };
  653. var json = System.Text.Json.JsonSerializer.Serialize(approvalDetail_Req);
  654. var content = new StringContent(json, Encoding.UTF8, "application/json");
  655. var create_Req = await _httpClient.PostAsync(url, content);
  656. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  657. templateDetailView = System.Text.Json.JsonSerializer.Deserialize<TemplateDetailView>(stringResponse,
  658. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  659. return templateDetailView;
  660. }
  661. #endregion
  662. }
  663. }