QiYeWeChatApiService.cs 80 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870
  1. using EyeSoft.Extensions;
  2. using OASystem.Domain.Dtos.QiYeWeChat;
  3. using OASystem.Domain.ViewModels.QiYeWeChat;
  4. using System.Diagnostics;
  5. using System.Net.Mail;
  6. using System.Text.Json;
  7. namespace OASystem.API.OAMethodLib.QiYeWeChatAPI
  8. {
  9. /// <summary>
  10. /// 聚合Api 服务
  11. /// </summary>
  12. public class QiYeWeChatApiService : IQiYeWeChatApiService
  13. {
  14. private readonly HttpClient _httpClient;
  15. //private readonly string CorpId = "wwe978bef5495a0728"; //企业Id
  16. //private readonly string PersonnelAssistant_AgentId = "3010011"; //人事助手Id
  17. //private readonly string PunchCard_AgentId = "3010185"; //打卡Id
  18. //private readonly string Email_AgentId = "1000004"; //E-Mail Id
  19. //private readonly string Approve_AgentId = "3010040"; //审批 Id
  20. //private readonly string GroupStatus_AgentId = "1000008"; //OA通知 Id
  21. /// <summary>
  22. /// 人事助手凭证密钥
  23. /// </summary>
  24. private readonly string PersonnelAssistant_Corpsecret = "ig--IJd6TxWDMJ1wT4e-RDRcRX12v5GjB359DNATwJ4"; // 人事助手凭证密钥
  25. /// <summary>
  26. /// 打卡凭证密钥
  27. /// </summary>
  28. private readonly string PunchCard_Corpsecret = "Xhrl37GOqlAjsu0VzUSJECaJdjzkDXQLbvrzRsZQb8M"; // 打卡凭证密钥
  29. /// <summary>
  30. /// E-Mail 凭证密钥
  31. /// </summary>
  32. private readonly string Email_Corpsecret = "NA1zbJM15GmgjPYwDOqz59dIo1Wnug-MbU107MeUemc"; // E-Mail 凭证密钥
  33. /// <summary>
  34. /// 通讯录同步 凭证密钥
  35. /// </summary>
  36. private readonly string AddressBook_Corpsecret = "Y1tnjh7j-BvbqAytAoXZPUbmDR6dqLTL6mXtc6PZ7fo"; // 通讯录同步 凭证密钥
  37. /// <summary>
  38. /// 审批 凭证密钥
  39. /// </summary>
  40. private readonly string Approve_Corpsecret = "k_Jo69Jw9Hqg_in-Rypbs30PNbxOYa1t4e-dxYuT-kw"; // 审批 凭证密钥
  41. /// <summary>
  42. /// OA通知Secret
  43. /// </summary>
  44. private readonly string GroupStatus_Corpsecret = "7J_ST3jTPzbZpFwl7ttToTVufjEx6O2wuApvKHxt2Ak"; // OA通知Secret
  45. private readonly DateTime _1970 = new DateTime(1970, 1, 1, 0, 0, 0, 0);
  46. private readonly JobPostRepository _jobPostRep;
  47. /// <summary>
  48. /// 初始化
  49. /// </summary>
  50. /// <param name="clientFactory"></param>
  51. /// <param name="jobPostRep"></param>
  52. public QiYeWeChatApiService(IHttpClientFactory clientFactory, JobPostRepository jobPostRep)
  53. {
  54. _httpClient = clientFactory.CreateClient("PublicQiYeWeChatApi"); ;
  55. _jobPostRep = jobPostRep;
  56. }
  57. /// <summary>
  58. /// 获取access_token
  59. /// </summary>
  60. /// <param name="applicationType">
  61. /// 1:人事助手
  62. /// 2:打卡
  63. /// 3:邮件
  64. /// 4:通讯录同步
  65. /// 5:审批
  66. /// 6:团组状态通知
  67. /// </param>
  68. /// <returns></returns>
  69. private async Task<Access_TokenView> GetTokenAsync(int applicationType)
  70. {
  71. Access_TokenView tokenResult = new Access_TokenView();
  72. Access_Token_Request access_Token = new Access_Token_Request();
  73. string cacheName = string.Empty;
  74. if (applicationType == 1)
  75. {
  76. access_Token.corpsecret = PersonnelAssistant_Corpsecret; //人事助手
  77. cacheName = "PersonnelAssistant_Access_Token";
  78. }
  79. else if (applicationType == 2)
  80. {
  81. access_Token.corpsecret = PunchCard_Corpsecret; //打卡
  82. cacheName = "PunchCard_Access_Token";
  83. }
  84. else if (applicationType == 3)
  85. {
  86. access_Token.corpsecret = Email_Corpsecret; //E-Mail
  87. cacheName = "Enail_Access_Token";
  88. }
  89. else if (applicationType == 4) //通讯录同步
  90. {
  91. access_Token.corpsecret = AddressBook_Corpsecret;
  92. cacheName = "AddressBook_Access_Token";
  93. }
  94. else if (applicationType == 5) //审批
  95. {
  96. access_Token.corpsecret = Approve_Corpsecret;
  97. cacheName = "Approve_Access_Token";
  98. }
  99. else if (applicationType == 6) //团组状态通知
  100. {
  101. access_Token.corpsecret = GroupStatus_Corpsecret;
  102. cacheName = "GroupStatus_Access_Token";
  103. }
  104. else
  105. {
  106. tokenResult.errmsg = "未识别应用类型Id!";
  107. return tokenResult;
  108. }
  109. string access_token = await RedisRepository.RedisFactory
  110. .CreateRedisRepository()
  111. .StringGetAsync<string>(cacheName);//string 取
  112. if (string.IsNullOrEmpty(access_token))
  113. {
  114. string access_token_url = string.Format(@"/cgi-bin/gettoken?corpid={0}&corpsecret={1}", access_Token.corpid, access_Token.corpsecret);
  115. var access_tokenReq = await _httpClient.GetAsync(access_token_url);
  116. if (access_tokenReq.IsSuccessStatusCode)
  117. {
  118. var stringResponse = await access_tokenReq.Content.ReadAsStringAsync();
  119. tokenResult = System.Text.Json.JsonSerializer.Deserialize<Access_TokenView>(stringResponse,
  120. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  121. if (tokenResult.errcode == 0)
  122. {
  123. TimeSpan ts = DateTime.Now.AddMinutes(118) - DateTime.Now; //设置redis 过期时间 118分钟
  124. await RedisRepository
  125. .RedisFactory
  126. .CreateRedisRepository()
  127. .StringSetAsync<string>(cacheName, tokenResult.access_token, ts);//string 存
  128. }
  129. }
  130. else
  131. {
  132. tokenResult.errmsg = "企业微信Token未获取到!";
  133. }
  134. }
  135. else
  136. {
  137. tokenResult.errcode = 0;
  138. tokenResult.access_token = access_token;
  139. }
  140. return tokenResult;
  141. }
  142. #region 添加员工
  143. /// <summary>
  144. /// 获取成员ID列表
  145. /// </summary>
  146. /// <returns></returns>
  147. public async Task<UserIdListView> GetUserIdListAsync()
  148. {
  149. UserIdListView userIdListView = new UserIdListView();
  150. Access_TokenView access_Token = await GetTokenAsync(4);
  151. if (access_Token.errcode != 0)
  152. {
  153. userIdListView.errcode = access_Token.errcode;
  154. userIdListView.errmsg = access_Token.errmsg;
  155. return userIdListView;
  156. }
  157. string url = string.Format("/cgi-bin/user/list_id?access_token={0}&debug=1", access_Token.access_token);
  158. var jsonData = new
  159. {
  160. access_token = access_Token.access_token, //调用接口凭证
  161. };
  162. var json = System.Text.Json.JsonSerializer.Serialize(jsonData);
  163. var content = new StringContent(json, Encoding.UTF8, "application/json");
  164. var create_Req = await _httpClient.PostAsync(url, content);
  165. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  166. userIdListView = System.Text.Json.JsonSerializer.Deserialize<UserIdListView>(stringResponse,
  167. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  168. return userIdListView;
  169. }
  170. /// <summary>
  171. /// 获取成员信息
  172. /// </summary>
  173. /// <returns></returns>
  174. public async Task<QYWX_UserInfosView> GetUserInfosAsync()
  175. {
  176. QYWX_UserInfosView infoViews = new QYWX_UserInfosView();
  177. //获取员工useridList
  178. UserIdListView useridView = await GetUserIdListAsync();
  179. if (useridView.errcode != 0)
  180. {
  181. infoViews.errcode = useridView.errcode;
  182. infoViews.errmsg = useridView.errmsg;
  183. return infoViews;
  184. }
  185. Access_TokenView access_Token = await GetTokenAsync(4);
  186. if (access_Token.errcode != 0)
  187. {
  188. infoViews.errcode = access_Token.errcode;
  189. infoViews.errmsg = access_Token.errmsg;
  190. return infoViews;
  191. }
  192. List<QYWX_UserInfo> items = new List<QYWX_UserInfo>();
  193. string urlTitle = string.Format("/cgi-bin/user/get?access_token={0}", access_Token.access_token);
  194. foreach (var item in useridView.dept_user)
  195. {
  196. if (!string.IsNullOrEmpty(item.userid))
  197. {
  198. QYWX_UserInfoView _UserInfoView = new QYWX_UserInfoView();
  199. string url = string.Format("{0}&userid={1}", urlTitle, item.userid);
  200. var create_Req = await _httpClient.GetAsync(url);
  201. if (create_Req.IsSuccessStatusCode)
  202. {
  203. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  204. _UserInfoView = System.Text.Json.JsonSerializer.Deserialize<QYWX_UserInfoView>(stringResponse,
  205. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  206. if (_UserInfoView.errcode == 0)
  207. {
  208. items.Add(new QYWX_UserInfo()
  209. {
  210. userid = _UserInfoView.QYWX_User.userid,
  211. name = _UserInfoView.QYWX_User.name,
  212. mobile = _UserInfoView.QYWX_User.mobile,
  213. position = _UserInfoView.QYWX_User.position,
  214. email = _UserInfoView.QYWX_User.email,
  215. biz_mail = _UserInfoView.QYWX_User.biz_mail,
  216. });
  217. }
  218. }
  219. }
  220. }
  221. infoViews.errcode = 0;
  222. infoViews.errmsg = "操作成功!";
  223. infoViews.QYWX_Users = items;
  224. return infoViews;
  225. }
  226. /// <summary>
  227. /// 获取部门列表
  228. /// </summary>
  229. /// <param name="access_token"></param>
  230. /// <returns></returns>
  231. private async Task<DepartmentListView> GetDepartmentAsync(string access_token)
  232. {
  233. DepartmentListView result = new DepartmentListView();
  234. string dep_url = string.Format("/cgi-bin/department/list?access_token={0}&debug=1", access_token);
  235. var depReq = await _httpClient.GetAsync(dep_url);
  236. if (depReq.IsSuccessStatusCode)
  237. {
  238. var stringResponse = await depReq.Content.ReadAsStringAsync();
  239. result = System.Text.Json.JsonSerializer.Deserialize<DepartmentListView>(stringResponse,
  240. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  241. }
  242. else
  243. {
  244. result.errcode = -1;
  245. result.errmsg = "企业微信部门列表未获取到!";
  246. }
  247. return result;
  248. }
  249. /// <summary>
  250. /// 创建员工
  251. /// </summary>
  252. /// <param name="create_Request"></param>
  253. /// <returns></returns>
  254. public async Task<ResponseBase> CreateAsync(Create_Request create_Request)
  255. {
  256. ResponseBase responseBase = new ResponseBase();
  257. #region 职位
  258. string depName = string.Empty,
  259. jobName = string.Empty;
  260. List<Sys_JobPostI> jobs = await _jobPostRep.QueryJobPost(string.Empty);
  261. Sys_JobPostI jobPost = jobs.Where(it => it.IsDel == 0 && it.Id == Convert.ToInt32(create_Request.position)).FirstOrDefault();
  262. if (jobPost != null)
  263. {
  264. depName = jobPost.DepName;
  265. jobName = jobPost.JobName;
  266. }
  267. create_Request.position = jobName;
  268. if (string.IsNullOrEmpty(create_Request.biz_mail))
  269. {
  270. create_Request.biz_mail = string.Format("{0}@pan-american-intl.com", create_Request.userid);
  271. }
  272. #endregion
  273. Access_TokenView access_Token = new Access_TokenView();
  274. access_Token = await GetTokenAsync(4);
  275. if (access_Token.errcode == 0)
  276. {
  277. create_Request.access_token = access_Token.access_token;
  278. #region 处理部门
  279. Access_TokenView dep_Access_Token = await GetTokenAsync(1);
  280. if (dep_Access_Token.errcode != 0)
  281. {
  282. responseBase.errcode = dep_Access_Token.errcode;
  283. responseBase.errmsg = dep_Access_Token.errmsg;
  284. }
  285. DepartmentListView depData = await GetDepartmentAsync(dep_Access_Token.access_token);
  286. if (depData.errcode == 0)
  287. {
  288. var depData1 = depData.department.Where(x => x.name == depName).FirstOrDefault();
  289. if (depData1 != null)
  290. {
  291. create_Request.department = new List<long> { depData1.id };
  292. }
  293. else
  294. {
  295. responseBase.errcode = -1;
  296. responseBase.errmsg = "未在企业微信上找到OA内设置的部门";
  297. return responseBase;
  298. }
  299. }
  300. else
  301. {
  302. responseBase.errcode = depData.errcode;
  303. responseBase.errmsg = depData.errmsg;
  304. return responseBase;
  305. }
  306. #endregion
  307. create_Request.access_token = access_Token.access_token;
  308. string create_url = string.Format("/cgi-bin/user/create?access_token={0}", create_Request.access_token);
  309. var json = System.Text.Json.JsonSerializer.Serialize(create_Request);
  310. var content = new StringContent(json, Encoding.UTF8, "application/json");
  311. var create_Req = await _httpClient.PostAsync(create_url, content);
  312. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  313. responseBase = System.Text.Json.JsonSerializer.Deserialize<ResponseBase>(stringResponse,
  314. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  315. }
  316. else
  317. {
  318. responseBase.errcode = access_Token.errcode;
  319. responseBase.errmsg = access_Token.errmsg;
  320. }
  321. return responseBase;
  322. }
  323. #endregion
  324. #region 邮件
  325. /// <summary>
  326. /// 发送邮件
  327. /// </summary>
  328. /// <param name="dto">发送邮件的请求对象</param>
  329. /// <returns></returns>
  330. public async Task<EmailResult> EmailSendAsync(EmailRequestDto dto)
  331. {
  332. EmailResult emailResult = new();
  333. // 参数验证
  334. if (dto.ToEmails == null) return new EmailResult() { errcode = -1, errmsg = "收件人邮箱列表不能为空" };
  335. if (string.IsNullOrEmpty(dto.Subject)) return new EmailResult() { errcode = -1, errmsg = "邮件主题不能为空" };
  336. if (string.IsNullOrEmpty(dto.Body)) return new EmailResult() { errcode = -1, errmsg = "邮件内容不能为空" };
  337. // 当前内容大小
  338. long currentSize = GetUtf8ByteSize(dto.Body);
  339. // 文件处理
  340. var attachments = new List<Domain.ViewModels.QiYeWeChat.Attachment>();
  341. var files = dto.Files;
  342. if (files != null && files.Length > 0)
  343. {
  344. if (files.Length > 200) return new EmailResult() { errcode = -1, errmsg = "附件个数不能超过200个" };
  345. foreach (var file in files)
  346. {
  347. if (file == null || file.Length == 0)
  348. {
  349. return new EmailResult() { errcode = -1, errmsg = "文件不能为空" };
  350. }
  351. string base64String = string.Empty;
  352. using (var memoryStream = new MemoryStream())
  353. {
  354. await file.CopyToAsync(memoryStream);
  355. var bytes = memoryStream.ToArray();
  356. base64String = Convert.ToBase64String(bytes);
  357. }
  358. var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(file.FileName);
  359. var extension = Path.GetExtension(file.FileName);
  360. var feilName = $"{fileNameWithoutExtension}{extension}";
  361. currentSize += GetUtf8ByteSize(base64String);
  362. attachments.Add(new Domain.ViewModels.QiYeWeChat.Attachment() {
  363. file_name = feilName,
  364. content = base64String
  365. });
  366. }
  367. }
  368. // 限制大小
  369. long maxSizeBytes = 50 * 1024 * 1024; // 50MB
  370. if (currentSize > maxSizeBytes)
  371. {
  372. return new EmailResult() { errcode = -1, errmsg = "邮件内容和附件总大小不能超过50MB" };
  373. }
  374. Access_TokenView access_Token = await GetTokenAsync(3);
  375. if (access_Token.errcode != 0)
  376. {
  377. emailResult.errcode = access_Token.errcode;
  378. emailResult.errmsg = string.Format("【企业微信】【获取邮件列表】【Token】【Msg】{0}", access_Token.errmsg);
  379. }
  380. string url = string.Format("/cgi-bin/exmail/app/compose_send?access_token={0}", access_Token.access_token);
  381. var reqData = new
  382. {
  383. to = new
  384. {
  385. emails = dto.ToEmails
  386. },
  387. cc = new
  388. {
  389. emails = dto.CcEmails
  390. },
  391. bcc = new
  392. {
  393. emails = dto.BccEmails
  394. },
  395. subject = dto.Subject,
  396. content = dto.Body,
  397. attachment_list = attachments
  398. };
  399. var reqContent = new StringContent(System.Text.Json.JsonSerializer.Serialize(reqData), Encoding.UTF8, "application/json");
  400. var create_Req = await _httpClient.PostAsync(url, reqContent);
  401. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  402. emailResult = System.Text.Json.JsonSerializer.Deserialize<EmailResult>(stringResponse,
  403. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  404. return emailResult;
  405. }
  406. /// <summary>
  407. /// 计算字符串的字节大小(UTF-8编码)
  408. /// </summary>
  409. private static long GetUtf8ByteSize(string text)
  410. {
  411. if (string.IsNullOrEmpty(text))
  412. {
  413. return 0;
  414. }
  415. return Encoding.UTF8.GetByteCount(text);
  416. }
  417. #endregion
  418. #region 打卡
  419. /// <summary>
  420. /// 获取企业所有打卡规则
  421. /// </summary>
  422. /// <returns></returns>
  423. public async Task<CorpCheckInRuleView> GetCheckIn_CorpCheckInOptionAsync()
  424. {
  425. CorpCheckInRuleView corpCheckInRuleView = new CorpCheckInRuleView();
  426. //获取打卡数据 token
  427. Access_TokenView access_Token = await GetTokenAsync(2);
  428. if (access_Token.errcode != 0)
  429. {
  430. corpCheckInRuleView.errcode = access_Token.errcode;
  431. corpCheckInRuleView.errmsg = string.Format("【企业微信】【获取月打卡数据】【Token】【Msg】{0}", access_Token.errmsg);
  432. return corpCheckInRuleView;
  433. }
  434. string url = string.Format("/cgi-bin/checkin/getcorpcheckinoption?access_token={0}", access_Token.access_token);
  435. var content = new StringContent(string.Empty, Encoding.UTF8, "application/json");
  436. var create_Req = await _httpClient.PostAsync(url, content);
  437. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  438. corpCheckInRuleView = System.Text.Json.JsonSerializer.Deserialize<CorpCheckInRuleView>(stringResponse,
  439. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  440. return corpCheckInRuleView;
  441. }
  442. /// <summary>
  443. /// 获取月打卡记录数据
  444. /// </summary>
  445. /// <param name="startDt"></param>
  446. /// <param name="endDt"></param>
  447. /// <returns></returns>
  448. public async Task<CheckInView> GetCheckin_MonthDataAsync1(DateTime startDt, DateTime endDt)
  449. {
  450. CheckInView checkInView = new CheckInView();
  451. //获取员工Id
  452. UserIdListView userIdListView = await GetUserIdListAsync();
  453. if (userIdListView.errcode != 0)
  454. {
  455. checkInView.errcode = userIdListView.errcode;
  456. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】{0}", userIdListView.errmsg);
  457. return checkInView;
  458. }
  459. if (userIdListView.dept_user == null || userIdListView.dept_user.Count <= 0)
  460. {
  461. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】未查出员工Id");
  462. return checkInView;
  463. }
  464. //获取打卡数据 token
  465. Access_TokenView access_Token = await GetTokenAsync(2);
  466. if (access_Token.errcode != 0)
  467. {
  468. checkInView.errcode = access_Token.errcode;
  469. checkInView.errmsg = string.Format("【企业微信】【获取月打卡数据】【Token】【Msg】{0}", access_Token.errmsg);
  470. return checkInView;
  471. }
  472. string url = string.Format("/cgi-bin/checkin/getcheckin_monthdata?access_token={0}", access_Token.access_token);
  473. Checkin_MonthData_Request checkInReq = new Checkin_MonthData_Request();
  474. checkInReq.access_token = access_Token.access_token;
  475. checkInReq.starttime = (uint)(startDt - _1970).TotalSeconds;
  476. checkInReq.endtime = (uint)(endDt - _1970).TotalSeconds;
  477. checkInReq.useridlist = userIdListView.dept_user.Select(it => it.userid!).ToList();
  478. var json = System.Text.Json.JsonSerializer.Serialize(checkInReq);
  479. var content = new StringContent(json, Encoding.UTF8, "application/json");
  480. var create_Req = await _httpClient.PostAsync(url, content);
  481. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  482. checkInView = System.Text.Json.JsonSerializer.Deserialize<CheckInView>(stringResponse,
  483. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  484. return checkInView;
  485. }
  486. /// <summary>
  487. /// 获取月打卡记录数据
  488. /// </summary>
  489. /// <param name="startDt"></param>
  490. /// <param name="endDt"></param>
  491. /// <returns></returns>
  492. public async Task<CheckInView> GetCheckin_MonthDataAsync(DateTime startDt, DateTime endDt)
  493. {
  494. CheckInView checkInView = new CheckInView();
  495. //获取员工Id
  496. UserIdListView userIdListView = await GetUserIdListAsync();
  497. if (userIdListView.errcode != 0)
  498. {
  499. checkInView.errcode = userIdListView.errcode;
  500. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】{0}", userIdListView.errmsg);
  501. return checkInView;
  502. }
  503. if (userIdListView.dept_user == null || userIdListView.dept_user.Count <= 0)
  504. {
  505. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】未查出员工Id");
  506. return checkInView;
  507. }
  508. //获取打卡数据 token
  509. Access_TokenView access_Token = await GetTokenAsync(2);
  510. if (access_Token.errcode != 0)
  511. {
  512. checkInView.errcode = access_Token.errcode;
  513. checkInView.errmsg = string.Format("【企业微信】【获取月打卡数据】【Token】【Msg】{0}", access_Token.errmsg);
  514. return checkInView;
  515. }
  516. #region 处理超31天的月报表数据
  517. string url = string.Format("/cgi-bin/checkin/getcheckin_monthdata?access_token={0}", access_Token.access_token);
  518. Checkin_MonthData_Request checkInReq = new Checkin_MonthData_Request();
  519. checkInReq.access_token = access_Token.access_token;
  520. checkInReq.useridlist = userIdListView.dept_user.Select(it => it.userid ?? "").ToList();
  521. uint starttimeOne, endtimeOne, starttimeTwo, endtimeTwo;
  522. int days = (int)(endDt - startDt).TotalDays;
  523. if (days > 32)
  524. {
  525. starttimeOne = (uint)((startDt.ToUniversalTime().Ticks - 621355968000000000) / 10000000);
  526. endtimeOne = (uint)((startDt.AddDays(31).ToUniversalTime().Ticks - 621355968000000000) / 10000000);
  527. starttimeTwo = (uint)((startDt.AddDays(32).ToUniversalTime().Ticks - 621355968000000000) / 10000000);
  528. endtimeTwo = (uint)((endDt.ToUniversalTime().Ticks - 621355968000000000) / 10000000);
  529. checkInReq.starttime = starttimeOne;
  530. checkInReq.endtime = endtimeOne;
  531. CheckInView checkInViewOne = new CheckInView();
  532. var jsonOne = System.Text.Json.JsonSerializer.Serialize(checkInReq);
  533. var contentOne = new StringContent(jsonOne, Encoding.UTF8, "application/json");
  534. var create_ReqOne = await _httpClient.PostAsync(url, contentOne);
  535. var stringResponseOne = await create_ReqOne.Content.ReadAsStringAsync();
  536. checkInViewOne = System.Text.Json.JsonSerializer.Deserialize<CheckInView>(stringResponseOne,
  537. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  538. if (checkInViewOne.errcode != 0)
  539. {
  540. return checkInViewOne;
  541. }
  542. checkInReq.starttime = starttimeTwo;
  543. checkInReq.endtime = endtimeTwo;
  544. CheckInView checkInViewTwo = new CheckInView();
  545. var jsonTwo = System.Text.Json.JsonSerializer.Serialize(checkInReq);
  546. var contentTwo = new StringContent(jsonTwo, Encoding.UTF8, "application/json");
  547. var create_ReqTwo = await _httpClient.PostAsync(url, contentTwo);
  548. var stringResponseTwo = await create_ReqTwo.Content.ReadAsStringAsync();
  549. checkInViewTwo = System.Text.Json.JsonSerializer.Deserialize<CheckInView>(stringResponseTwo,
  550. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  551. if (checkInViewTwo.errcode != 0)
  552. {
  553. return checkInViewTwo;
  554. }
  555. #region 整合月报表数据
  556. foreach (var item_one in checkInViewOne.datas)
  557. {
  558. foreach (var item_two in checkInViewTwo.datas)
  559. {
  560. if (item_one.base_info.acctid.Equals(item_two.base_info.acctid))
  561. {
  562. #region summary_info 汇总信息整合
  563. item_one.summary_info.work_days += item_two.summary_info.work_days; //应打卡天数
  564. item_one.summary_info.regular_days += item_two.summary_info.regular_days; //正常天数
  565. item_one.summary_info.except_days += item_two.summary_info.except_days; //异常天数
  566. item_one.summary_info.regular_work_sec += item_two.summary_info.regular_work_sec; //实际工作时长,为统计周期每日实际工作时长之和
  567. item_one.summary_info.standard_work_sec += item_two.summary_info.standard_work_sec; //标准工作时长,为统计周期每日标准工作时长之和
  568. #endregion
  569. #region exception_infos 异常状态统计信息 整合
  570. item_one.exception_infos.AddRange(item_two.exception_infos);
  571. #endregion
  572. #region sp_items 假勤统计信息整合
  573. item_one.sp_items.AddRange(item_two.sp_items);
  574. #endregion
  575. #region overwork_info 加班情况 整合
  576. item_one.overwork_info.workday_over_sec += item_two.overwork_info.workday_over_sec; //工作日加班时长
  577. item_one.overwork_info.holidays_over_sec += item_two.overwork_info.holidays_over_sec; //节假日加班时长
  578. item_one.overwork_info.restdays_over_sec += item_two.overwork_info.restdays_over_sec; //休息日加班时长
  579. #endregion
  580. break;
  581. }
  582. }
  583. }
  584. #endregion
  585. checkInView = checkInViewOne;
  586. }
  587. else
  588. {
  589. checkInReq.starttime = (uint)((startDt.ToUniversalTime().Ticks - 621355968000000000) / 10000000);
  590. checkInReq.endtime = (uint)((endDt.ToUniversalTime().Ticks - 621355968000000000) / 10000000);
  591. var json = System.Text.Json.JsonSerializer.Serialize(checkInReq);
  592. var content = new StringContent(json, Encoding.UTF8, "application/json");
  593. var create_Req = await _httpClient.PostAsync(url, content);
  594. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  595. checkInView = System.Text.Json.JsonSerializer.Deserialize<CheckInView>(stringResponse,
  596. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  597. }
  598. #endregion
  599. return checkInView;
  600. }
  601. /// <summary>
  602. /// 获取月打卡数据(redis缓存)
  603. /// </summary>
  604. /// <param name="startDt"></param>
  605. /// <param name="endDt"></param>
  606. /// <returns></returns>
  607. public async Task<CheckInView> GetCheckin_MonthDataRedisAsync(DateTime startDt, DateTime endDt)
  608. {
  609. CheckInView checkInView = new CheckInView();
  610. string checkInDatastring = await RedisRepository.RedisFactory
  611. .CreateRedisRepository()
  612. .StringGetAsync<string>("Checkin_MonthData");//List<T> 取
  613. if (!string.IsNullOrEmpty(checkInDatastring))
  614. {
  615. checkInView = JsonConvert.DeserializeObject<CheckInView>(checkInDatastring);
  616. return checkInView;
  617. }
  618. //获取员工Id
  619. UserIdListView userIdListView = await GetUserIdListAsync();
  620. if (userIdListView.errcode != 0)
  621. {
  622. checkInView.errcode = userIdListView.errcode;
  623. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】{0}", userIdListView.errmsg);
  624. return checkInView;
  625. }
  626. if (userIdListView.dept_user == null || userIdListView.dept_user.Count <= 0)
  627. {
  628. checkInView.errmsg = string.Format("【企业微信】【获取员工IdList】【Msg】未查出员工Id");
  629. return checkInView;
  630. }
  631. //获取月打卡数据 token
  632. Access_TokenView access_Token = await GetTokenAsync(2);
  633. if (access_Token.errcode != 0)
  634. {
  635. checkInView.errcode = access_Token.errcode;
  636. checkInView.errmsg = string.Format("【企业微信】【获取月打卡数据】【Token】【Msg】{0}", access_Token.errmsg);
  637. return checkInView;
  638. }
  639. string url = string.Format("/cgi-bin/checkin/getcheckin_monthdata?access_token={0}", access_Token.access_token);
  640. Checkin_MonthData_Request checkInReq = new Checkin_MonthData_Request();
  641. checkInReq.access_token = access_Token.access_token;
  642. checkInReq.starttime = (uint)(startDt - _1970).TotalSeconds;
  643. checkInReq.endtime = (uint)(endDt - _1970).TotalSeconds;
  644. checkInReq.useridlist = userIdListView.dept_user.Select(it => it.userid!).ToList();
  645. var json = System.Text.Json.JsonSerializer.Serialize(checkInReq);
  646. var content = new StringContent(json, Encoding.UTF8, "application/json");
  647. var create_Req = await _httpClient.PostAsync(url, content);
  648. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  649. checkInView = System.Text.Json.JsonSerializer.Deserialize<CheckInView>(stringResponse,
  650. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  651. if (checkInView.errcode == 0)
  652. {
  653. TimeSpan ts = DateTime.Now.AddMinutes(60) - DateTime.Now; //设置redis 过期时间 60分钟
  654. await RedisRepository
  655. .RedisFactory
  656. .CreateRedisRepository()
  657. .StringSetAsync<string>("Checkin_MonthData", JsonConvert.SerializeObject(checkInView), ts);//List<T> 存
  658. }
  659. return checkInView;
  660. }
  661. public async Task<object> QueryAssessmentByUser(DateTime startDt, DateTime endDt, List<string> qiyeUidList)
  662. {
  663. AssessmentByUserListView assessmentByUserListView = new AssessmentByUserListView();
  664. List<AssessmentByUserView> AssessmentByUserView = new List<AssessmentByUserView>();
  665. assessmentByUserListView.Data = AssessmentByUserView;
  666. assessmentByUserListView.errcode = 0;
  667. assessmentByUserListView.errmsg = "成功";
  668. CheckInView? checkInView = new CheckInView();
  669. //获取打卡数据 token
  670. Access_TokenView access_Token = await GetTokenAsync(2);
  671. if (access_Token.errcode != 0)
  672. {
  673. assessmentByUserListView.errcode = access_Token.errcode;
  674. assessmentByUserListView.errmsg = string.Format("【企业微信】【获取月打卡数据】【Token】【Msg】{0}", access_Token.errmsg);
  675. return assessmentByUserListView;
  676. }
  677. string url = string.Format("/cgi-bin/checkin/getcheckin_monthdata?access_token={0}", access_Token.access_token);
  678. Checkin_MonthData_Request checkInReq = new Checkin_MonthData_Request();
  679. checkInReq.access_token = access_Token.access_token;
  680. checkInReq.starttime = (uint)(startDt - _1970).TotalSeconds;
  681. checkInReq.endtime = (uint)(endDt - _1970).TotalSeconds;
  682. checkInReq.useridlist = qiyeUidList;
  683. var json = System.Text.Json.JsonSerializer.Serialize(checkInReq);
  684. var content = new StringContent(json, Encoding.UTF8, "application/json");
  685. var create_Req = await _httpClient.PostAsync(url, content);
  686. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  687. checkInView = System.Text.Json.JsonSerializer.Deserialize<CheckInView>(stringResponse,
  688. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  689. if (checkInView == null)
  690. {
  691. assessmentByUserListView.errcode = -1;
  692. assessmentByUserListView.errmsg = "checkInView Deserialize Error";
  693. return assessmentByUserListView;
  694. }
  695. if (checkInView.errcode != 0)
  696. {
  697. assessmentByUserListView.errcode = checkInView.errcode;
  698. assessmentByUserListView.errmsg = checkInView.errmsg;
  699. return assessmentByUserListView;
  700. }
  701. var errorUserList = new List<string>();
  702. //遍历用户数据
  703. foreach (var item in checkInView.datas)
  704. {
  705. //有异常状态的情况下获取具体异常信息
  706. if (item.summary_info.except_days > 0)
  707. {
  708. errorUserList.Add(item.base_info.acctid);
  709. }
  710. assessmentByUserListView.Data.Add(new Domain.ViewModels.QiYeWeChat.AssessmentByUserView
  711. {
  712. Accid = item.base_info.acctid,
  713. Except_days = item.summary_info.except_days,
  714. Name = item.base_info.name,
  715. Regular_days = item.summary_info.regular_days,
  716. Exception_info_List = new List<Exception_info>(),
  717. Work_days = item.summary_info.work_days
  718. });
  719. }
  720. if (errorUserList.Count > 0)
  721. {
  722. var dayInfo = await GetCheckinDataAsync(errorUserList, 3, startDt, endDt);
  723. if (dayInfo.errcode != 0)
  724. {
  725. assessmentByUserListView.errcode = dayInfo.errcode;
  726. assessmentByUserListView.errmsg = dayInfo.errmsg;
  727. assessmentByUserListView.Data = new List<AssessmentByUserView>();
  728. return assessmentByUserListView;
  729. }
  730. var dic = new Dictionary<ErrorType, List<string>>()
  731. {
  732. { ErrorType.迟到 , new List<string>{ "时间异常" } },
  733. { ErrorType.缺卡 , new List<string>{ "未打卡" } },
  734. };
  735. foreach (var item in dayInfo.checkindata)
  736. {
  737. foreach (var user in assessmentByUserListView.Data)
  738. {
  739. if (user.Accid == item.userid)
  740. {
  741. //遍历异常信息
  742. if (!item.exception_type.IsNullOrWhiteSpace())
  743. {
  744. var linqFind = dic.First(x => x.Value.Contains(item.exception_type));
  745. var errinfo = new Exception_info
  746. {
  747. Date = item.checkin_time_dt,
  748. Type = linqFind.Key,
  749. Info = item.exception_type
  750. };
  751. user.Exception_info_List.Add(errinfo);
  752. }
  753. }
  754. }
  755. }
  756. }
  757. return assessmentByUserListView;
  758. }
  759. /// <summary>
  760. /// 获取打卡记录数据
  761. /// </summary>
  762. /// <param name="useridlist">需要获取打卡记录的用户列表</param>
  763. /// <param name="opencheckindatatype">打卡类型。1:上下班打卡;2:外出打卡;3:全部打卡</param>
  764. /// <param name="startDt">获取打卡记录的开始时间。Unix时间戳</param>
  765. /// <param name="endDt">获取打卡记录的结束时间。Unix时间戳</param>
  766. /// <returns></returns>
  767. public async Task<CheckInDataView> GetCheckinDataAsync(List<string> useridlist, int opencheckindatatype, DateTime startDt, DateTime endDt)
  768. {
  769. CheckInDataView checkInDataView = new CheckInDataView();
  770. //参数处理
  771. if (useridlist.Count <= 0)
  772. {
  773. checkInDataView.errmsg = "请填写企业微信用户id,可为多个!";
  774. return checkInDataView;
  775. }
  776. if (useridlist.Count > 100)
  777. {
  778. checkInDataView.errmsg = "用户列表不超过100个。若用户超过100个,请分批获取!";
  779. return checkInDataView;
  780. }
  781. //获取打卡数据 token
  782. Access_TokenView access_Token = await GetTokenAsync(2);
  783. if (access_Token.errcode != 0)
  784. {
  785. checkInDataView.errcode = access_Token.errcode;
  786. checkInDataView.errmsg = string.Format("【企业微信】【获取打卡数据】【Token】【Msg】{0}", access_Token.errmsg);
  787. return checkInDataView;
  788. }
  789. string url = string.Format("/cgi-bin/checkin/getcheckindata?access_token={0}", access_Token.access_token);
  790. DateTime centerDt = startDt.AddDays(30);
  791. long startTs = (long)(startDt - _1970).TotalSeconds;
  792. long centerTs = (long)(centerDt - _1970).TotalSeconds;
  793. long endTs = (long)(endDt - _1970).TotalSeconds;
  794. CheckInData_Request checkInData_Req = new CheckInData_Request()
  795. {
  796. access_token = access_Token.access_token,
  797. opencheckindatatype = opencheckindatatype,
  798. useridlist = useridlist,
  799. starttime = startTs,
  800. endtime = centerTs
  801. };
  802. var json = System.Text.Json.JsonSerializer.Serialize(checkInData_Req);
  803. var content = new StringContent(json, Encoding.UTF8, "application/json");
  804. var create_Req = await _httpClient.PostAsync(url, content);
  805. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  806. checkInDataView = System.Text.Json.JsonSerializer.Deserialize<CheckInDataView>(stringResponse,
  807. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  808. if (centerDt < endDt)
  809. {
  810. checkInData_Req.starttime = centerTs;
  811. checkInData_Req.endtime = endTs;
  812. var json1 = System.Text.Json.JsonSerializer.Serialize(checkInData_Req);
  813. var content1 = new StringContent(json1, Encoding.UTF8, "application/json");
  814. var create_Req1 = await _httpClient.PostAsync(url, content1);
  815. var stringResponse1 = await create_Req1.Content.ReadAsStringAsync();
  816. CheckInDataView checkInDataView1 = System.Text.Json.JsonSerializer.Deserialize<CheckInDataView>(stringResponse1,
  817. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  818. if (checkInDataView1.errcode != 0)
  819. {
  820. return checkInDataView1;
  821. }
  822. checkInDataView.checkindata.AddRange(checkInDataView1.checkindata);
  823. return checkInDataView;
  824. }
  825. return checkInDataView;
  826. }
  827. /// <summary>
  828. /// 获取打卡日报数据
  829. /// </summary>
  830. /// <param name="useridlist"></param>
  831. /// <param name="startDt"></param>
  832. /// <param name="endDt"></param>
  833. /// <returns></returns>
  834. public async Task<CheckInDayDataView> GetCheckInDayDataAsync1(List<string> useridlist, DateTime startDt, DateTime endDt)
  835. {
  836. CheckInDayDataView checkInDayDataView = new CheckInDayDataView();
  837. //参数处理
  838. if (useridlist.Count <= 0)
  839. {
  840. checkInDayDataView.errmsg = "请填写企业微信用户id,可为多个!";
  841. return checkInDayDataView;
  842. }
  843. //获取打卡数据 token
  844. Access_TokenView access_Token = await GetTokenAsync(2);
  845. if (access_Token.errcode != 0)
  846. {
  847. checkInDayDataView.errcode = access_Token.errcode;
  848. checkInDayDataView.errmsg = string.Format("【企业微信】【获取打卡日报数据】【Token】【Msg】{0}", access_Token.errmsg);
  849. return checkInDayDataView;
  850. }
  851. string url = string.Format("/cgi-bin/checkin/getcheckin_daydata?access_token={0}&debug=1", access_Token.access_token);
  852. long startTs = (startDt.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
  853. long endTs = (endDt.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
  854. var checkInData_Req = new
  855. {
  856. access_token = access_Token.access_token,
  857. useridlist = useridlist,
  858. starttime = startTs,
  859. endtime = endTs
  860. };
  861. var json = System.Text.Json.JsonSerializer.Serialize(checkInData_Req);
  862. var content = new StringContent(json, Encoding.UTF8, "application/json");
  863. var create_Req = await _httpClient.PostAsync(url, content);
  864. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  865. checkInDayDataView = System.Text.Json.JsonSerializer.Deserialize<CheckInDayDataView>(stringResponse,
  866. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  867. return checkInDayDataView;
  868. }
  869. /// <summary>
  870. /// 获取打卡日报数据
  871. /// </summary>
  872. /// <param name="useridlist"></param>
  873. /// <param name="startDt"></param>
  874. /// <param name="endDt"></param>
  875. /// <returns></returns>
  876. public async Task<CheckInDayDataView> GetCheckInDayDataAsync(List<string> useridlist, DateTime startDt, DateTime endDt)
  877. {
  878. CheckInDayDataView checkInDayDataView = new CheckInDayDataView();
  879. //参数处理
  880. if (useridlist.Count <= 0)
  881. {
  882. checkInDayDataView.errmsg = "请填写企业微信用户id,可为多个!";
  883. return checkInDayDataView;
  884. }
  885. //获取打卡数据 token
  886. Access_TokenView access_Token = await GetTokenAsync(2);
  887. if (access_Token.errcode != 0)
  888. {
  889. checkInDayDataView.errcode = access_Token.errcode;
  890. checkInDayDataView.errmsg = string.Format("【企业微信】【获取打卡日报数据】【Token】【Msg】{0}", access_Token.errmsg);
  891. return checkInDayDataView;
  892. }
  893. string url = string.Format("/cgi-bin/checkin/getcheckin_daydata?access_token={0}&debug=1", access_Token.access_token);
  894. int days = (int)(endDt - startDt).TotalDays;
  895. if (days > 31)
  896. {
  897. long startTs_One = (startDt.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
  898. long endTs_One = (startDt.AddDays(31).ToUniversalTime().Ticks - 621355968000000000) / 10000000;
  899. long startTs_Two = (startDt.AddDays(31).ToUniversalTime().Ticks - 621355968000000000) / 10000000;
  900. long endTs_Two = (endDt.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
  901. var checkInData_ReqOne = new
  902. {
  903. access_token = access_Token.access_token,
  904. useridlist = useridlist,
  905. starttime = startTs_One,
  906. endtime = endTs_One
  907. };
  908. var jsonOne = System.Text.Json.JsonSerializer.Serialize(checkInData_ReqOne);
  909. var contentOne = new StringContent(jsonOne, Encoding.UTF8, "application/json");
  910. var create_ReqOne = await _httpClient.PostAsync(url, contentOne);
  911. var stringResponseOne = await create_ReqOne.Content.ReadAsStringAsync();
  912. CheckInDayDataView checkInDayDataViewOne = System.Text.Json.JsonSerializer.Deserialize<CheckInDayDataView>(stringResponseOne,
  913. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  914. if (checkInDayDataViewOne.errcode != 0)
  915. {
  916. return checkInDayDataViewOne;
  917. }
  918. var checkInData_ReqTwo = new
  919. {
  920. access_token = access_Token.access_token,
  921. useridlist = useridlist,
  922. starttime = startTs_Two,
  923. endtime = endTs_Two
  924. };
  925. var jsonTwo = System.Text.Json.JsonSerializer.Serialize(checkInData_ReqTwo);
  926. var contentTwo = new StringContent(jsonTwo, Encoding.UTF8, "application/json");
  927. var create_ReqTwo = await _httpClient.PostAsync(url, contentTwo);
  928. var stringResponseTwo = await create_ReqTwo.Content.ReadAsStringAsync();
  929. CheckInDayDataView checkInDayDataViewTwo = System.Text.Json.JsonSerializer.Deserialize<CheckInDayDataView>(stringResponseTwo,
  930. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  931. if (checkInDayDataViewTwo.errcode != 0)
  932. {
  933. return checkInDayDataViewTwo;
  934. }
  935. checkInDayDataViewOne.datas.AddRange(checkInDayDataViewTwo.datas);
  936. return checkInDayDataViewOne;
  937. }
  938. else
  939. {
  940. long startTs = (startDt.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
  941. long endTs = (endDt.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
  942. var checkInData_Req = new
  943. {
  944. access_token = access_Token.access_token,
  945. useridlist = useridlist,
  946. starttime = startTs,
  947. endtime = endTs
  948. };
  949. var json = System.Text.Json.JsonSerializer.Serialize(checkInData_Req);
  950. var content = new StringContent(json, Encoding.UTF8, "application/json");
  951. var create_Req = await _httpClient.PostAsync(url, content);
  952. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  953. checkInDayDataView = System.Text.Json.JsonSerializer.Deserialize<CheckInDayDataView>(stringResponse,
  954. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  955. }
  956. return checkInDayDataView;
  957. }
  958. #endregion
  959. #region 审批
  960. /// <summary>
  961. /// 获取审批数据(旧)
  962. /// </summary>
  963. /// <param name="startDt"></param>
  964. /// <param name="endDt"></param>
  965. /// <returns></returns>
  966. public async Task<ApprovalDataView> GetApprovalDataAsync(DateTime startDt, DateTime endDt)
  967. {
  968. ApprovalDataView approvalDataView = new ApprovalDataView();
  969. //获取审批数据 token
  970. Access_TokenView access_Token = await GetTokenAsync(5);
  971. if (access_Token.errcode != 0)
  972. {
  973. approvalDataView.errcode = access_Token.errcode;
  974. approvalDataView.errmsg = string.Format("【企业微信】【获取审批数据】【Token】【Msg】{0}", access_Token.errmsg);
  975. return approvalDataView;
  976. }
  977. string url = string.Format("/cgi-bin/corp/getapprovaldata?access_token={0}", access_Token.access_token);
  978. ApprovalData_Request approvalDataReq = new ApprovalData_Request();
  979. approvalDataReq.access_token = access_Token.access_token;
  980. approvalDataReq.starttime = (uint)(startDt - _1970).TotalSeconds;
  981. approvalDataReq.endtime = (uint)(endDt - _1970).TotalSeconds;
  982. var json = System.Text.Json.JsonSerializer.Serialize(approvalDataReq);
  983. var content = new StringContent(json, Encoding.UTF8, "application/json");
  984. var create_Req = await _httpClient.PostAsync(url, content);
  985. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  986. approvalDataView = System.Text.Json.JsonSerializer.Deserialize<ApprovalDataView>(stringResponse,
  987. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  988. List<Sp_Info> sp_datas = new List<Sp_Info>();
  989. sp_datas.AddRange(approvalDataView.data);
  990. int index = 0;
  991. //多次访问审批接口
  992. if (approvalDataView.total >= 100)
  993. {
  994. approvalDataView.total -= 100;
  995. int forTotal = approvalDataView.total % 100 == 0 ? approvalDataView.total / 100 : approvalDataView.total / 100 + 1;
  996. long? next_spnum = approvalDataView.next_spnum;
  997. approvalDataReq.next_spnum = next_spnum;
  998. for (int i = 0; i < forTotal; i++)
  999. {
  1000. index++;
  1001. var for_json = System.Text.Json.JsonSerializer.Serialize(approvalDataReq);
  1002. var for_content = new StringContent(for_json, Encoding.UTF8, "application/json");
  1003. var for_create_Req = await _httpClient.PostAsync(url, for_content);
  1004. var for_stringResponse = await for_create_Req.Content.ReadAsStringAsync();
  1005. ApprovalDataView for_approvalDataView = System.Text.Json.JsonSerializer.Deserialize<ApprovalDataView>(for_stringResponse,
  1006. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  1007. approvalDataReq.next_spnum = for_approvalDataView.next_spnum; //重新定义游标
  1008. sp_datas.AddRange(for_approvalDataView.data); //追加数据
  1009. }
  1010. approvalDataView.total += 100;
  1011. }
  1012. approvalDataView.data = sp_datas;
  1013. return approvalDataView;
  1014. }
  1015. /// <summary>
  1016. /// 获取审批数据(旧)(redis缓存)
  1017. /// </summary>
  1018. /// <param name="startDt"></param>
  1019. /// <param name="endDt"></param>
  1020. /// <returns></returns>
  1021. public async Task<List<Sp_Info>> GetApprovalDatasAsync(DateTime startDt, DateTime endDt)
  1022. {
  1023. List<Sp_Info> sp_Infos = new List<Sp_Info>();
  1024. //获取所有打卡补卡,审批 数据 前后范围增加10天
  1025. DateTime sp_startDt = startDt.AddDays(-10);
  1026. DateTime sp_centerDt = sp_startDt.AddDays(30);
  1027. DateTime sp_endDt = endDt.AddDays(10);
  1028. ApprovalDataView approvalData_1 = await GetApprovalDataAsync(sp_startDt, sp_centerDt); //时间段内所有 审批数据
  1029. ApprovalDataView approvalData_2 = await GetApprovalDataAsync(sp_centerDt, sp_endDt); //时间段内所有 审批数据
  1030. if (approvalData_1.errcode != 0)
  1031. {
  1032. Log.Error("企业微信 获取 " + sp_startDt + " - " + sp_centerDt + " 内审批 Msg:" + approvalData_1.errmsg);
  1033. return sp_Infos;
  1034. }
  1035. sp_Infos.AddRange(approvalData_1.data);
  1036. if (approvalData_2.errcode != 0)
  1037. {
  1038. Log.Error("企业微信 获取 " + sp_centerDt + " - " + sp_endDt + " 内审批 Msg:" + approvalData_2.errmsg);
  1039. return sp_Infos;
  1040. }
  1041. sp_Infos.AddRange(approvalData_2.data);
  1042. sp_Infos = sp_Infos.Where(it => it.sp_status == 2).ToList(); //存储已审核的数据
  1043. return sp_Infos;
  1044. }
  1045. /// <summary>
  1046. /// 获取审批数据(旧)(redis缓存)
  1047. /// </summary>
  1048. /// <param name="startDt"></param>
  1049. /// <param name="endDt"></param>
  1050. /// <returns></returns>
  1051. public async Task<List<Sp_Info>> GetApprovalDatasRedisAsync(DateTime startDt, DateTime endDt)
  1052. {
  1053. List<Sp_Info> sp_Infos = new List<Sp_Info>();
  1054. //获取所有打卡补卡,审批 数据 前后范围增加10天
  1055. DateTime sp_startDt = startDt.AddDays(-10);
  1056. DateTime sp_centerDt = sp_startDt.AddDays(30);
  1057. DateTime sp_endDt = endDt.AddDays(10);
  1058. string redisName = "ApprovalData" + sp_startDt.ToString("yyyyMMdd") + "-" + sp_endDt.ToString("yyyyMMdd");
  1059. string sp_InfosString = string.Empty;
  1060. //sp_InfosString = await RedisRepository.RedisFactory
  1061. // .CreateRedisRepository()
  1062. // .StringGetAsync<string>(redisName);//string 取
  1063. if (string.IsNullOrEmpty(sp_InfosString))
  1064. {
  1065. ApprovalDataView approvalData_1 = await GetApprovalDataAsync(sp_startDt, sp_centerDt); //时间段内所有 审批数据
  1066. ApprovalDataView approvalData_2 = await GetApprovalDataAsync(sp_centerDt, sp_endDt); //时间段内所有 审批数据
  1067. if (approvalData_1.errcode != 0)
  1068. {
  1069. Log.Error("企业微信 获取 " + sp_startDt + " - " + sp_centerDt + " 内审批 Msg:" + approvalData_1.errmsg);
  1070. return sp_Infos;
  1071. }
  1072. sp_Infos.AddRange(approvalData_1.data);
  1073. if (approvalData_2.errcode != 0)
  1074. {
  1075. Log.Error("企业微信 获取 " + sp_centerDt + " - " + sp_endDt + " 内审批 Msg:" + approvalData_2.errmsg);
  1076. return sp_Infos;
  1077. }
  1078. sp_Infos.AddRange(approvalData_2.data);
  1079. sp_Infos = sp_Infos.Where(it => it.sp_status == 2).ToList(); //存储已审核的数据
  1080. TimeSpan ts = DateTime.Now.AddMinutes(60) - DateTime.Now; //设置redis 过期时间 60分钟
  1081. await RedisRepository
  1082. .RedisFactory
  1083. .CreateRedisRepository()
  1084. .StringSetAsync<string>(redisName, JsonConvert.SerializeObject(sp_Infos), ts);//string 存
  1085. }
  1086. else
  1087. {
  1088. sp_Infos = JsonConvert.DeserializeObject<List<Sp_Info>>(sp_InfosString);
  1089. }
  1090. return sp_Infos;
  1091. }
  1092. /// <summary>
  1093. /// 批量获取审批单号
  1094. /// </summary>
  1095. /// <param name="startDt"></param>
  1096. /// <param name="endDt"></param>
  1097. /// <param name="creator">
  1098. /// 申请人
  1099. /// </param>
  1100. /// <param name="sp_status">
  1101. /// sp_status-审批单状态(1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付)
  1102. /// </param>
  1103. /// <param name="record_type">
  1104. /// record_type == 0 ALL 有值 请填写对应值
  1105. /// record_type - 审批单类型属性,1-请假;2-打卡补卡;3-出差;4-外出;5-加班; 6- 调班;7-会议室预定;8-退款审批;9-红包报销审批
  1106. /// </param>
  1107. /// <returns></returns>
  1108. private async Task<ApprovalInfoView> GetApprovalInfoAsync(DateTime startDt, DateTime endDt, string creator, int sp_status, int record_type)
  1109. {
  1110. Stopwatch sw = new Stopwatch();
  1111. sw.Start();
  1112. ApprovalInfoView approvalInfoView = new ApprovalInfoView();
  1113. //获取所有打卡补卡,审批 数据 向前增加30天 向后范围增加15天
  1114. DateTime sp_startDt = startDt.AddDays(-30);
  1115. DateTime sp_endDt = endDt.AddDays(15);
  1116. //获取审批数据 token
  1117. Access_TokenView access_Token = await GetTokenAsync(5);
  1118. if (access_Token.errcode != 0)
  1119. {
  1120. approvalInfoView.errcode = access_Token.errcode;
  1121. approvalInfoView.errmsg = string.Format("【企业微信】【批量获取审批单号】【Token】【Msg】{0}", access_Token.errmsg);
  1122. return approvalInfoView;
  1123. }
  1124. string url = string.Format("/cgi-bin/oa/getapprovalinfo?access_token={0}", access_Token.access_token);
  1125. List<Dic> filters = new List<Dic> {
  1126. new Dic() { key = "creator", value = creator }, //筛选条件 申请人
  1127. new Dic() { key = "sp_status", value = sp_status.ToString() }, //筛选条件 审核状态 2 已同意
  1128. };
  1129. if (record_type != 0)
  1130. {
  1131. filters.Add(new Dic() { key = "record_type", value = record_type.ToString() }); //筛选条件 审批单类型 请假 1
  1132. }
  1133. int days = (sp_endDt - sp_startDt).Days;
  1134. decimal runCount = days % 30;
  1135. int runCount1 = 0;
  1136. if (runCount == 0) runCount1 = (int)(days % 30.00M);
  1137. else runCount1 = (int)Math.Ceiling(days / 30.00M);
  1138. List<string> sp_no_lists = new List<string>();
  1139. for (int i = 0; i < runCount1; i++)
  1140. {
  1141. DateTime for_sp_startDt = sp_startDt;
  1142. DateTime for_sp_endDt = sp_startDt.AddDays(30);
  1143. sp_startDt = sp_startDt.AddDays(30);
  1144. if (for_sp_endDt >= sp_endDt)
  1145. {
  1146. for_sp_endDt = sp_endDt;
  1147. }
  1148. ApprovalInfo_Request approvalInfoReq = new ApprovalInfo_Request()
  1149. {
  1150. access_token = access_Token.access_token,
  1151. starttime = (uint)ConvertToTimeSpan(for_sp_startDt),
  1152. endtime = (uint)ConvertToTimeSpan(for_sp_endDt),
  1153. filters = filters.ToList(),
  1154. };
  1155. var json = System.Text.Json.JsonSerializer.Serialize(approvalInfoReq);
  1156. var content = new StringContent(json, Encoding.UTF8, "application/json");
  1157. var create_Req = await _httpClient.PostAsync(url, content);
  1158. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  1159. ApprovalInfoView approvalInfoView1 = System.Text.Json.JsonSerializer.Deserialize<ApprovalInfoView>(stringResponse,
  1160. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  1161. #region 分页调用 new_next_cursor != null
  1162. string new_cursor = approvalInfoView1.new_next_cursor;
  1163. while (!string.IsNullOrEmpty(new_cursor))
  1164. {
  1165. approvalInfoReq.new_cursor = new_cursor;
  1166. var json1 = System.Text.Json.JsonSerializer.Serialize(approvalInfoReq);
  1167. var content1 = new StringContent(json, Encoding.UTF8, "application/json");
  1168. var create_Req1 = await _httpClient.PostAsync(url, content1);
  1169. var stringResponse1 = await create_Req1.Content.ReadAsStringAsync();
  1170. ApprovalInfoView approvalInfoView11 = System.Text.Json.JsonSerializer.Deserialize<ApprovalInfoView>(stringResponse1,
  1171. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  1172. if (approvalInfoView11.errcode != 0)
  1173. {
  1174. return approvalInfoView1;
  1175. }
  1176. new_cursor = approvalInfoView11.new_next_cursor;
  1177. if (approvalInfoView11.sp_no_list.Count > 0 || approvalInfoView11.sp_no_list != null)
  1178. {
  1179. sp_no_lists.AddRange(approvalInfoView1.sp_no_list);
  1180. }
  1181. }
  1182. #endregion
  1183. if (approvalInfoView1.errcode != 0)
  1184. {
  1185. return approvalInfoView1;
  1186. }
  1187. if (approvalInfoView1.sp_no_list.Count > 0 || approvalInfoView1.sp_no_list != null)
  1188. {
  1189. sp_no_lists.AddRange(approvalInfoView1.sp_no_list);
  1190. }
  1191. }
  1192. approvalInfoView.errcode = 0;
  1193. if (sp_no_lists.Count > 0)
  1194. {
  1195. sp_no_lists = sp_no_lists.Distinct().ToList();
  1196. }
  1197. approvalInfoView.sp_no_list = sp_no_lists;
  1198. sw.Stop();
  1199. approvalInfoView.errmsg = approvalInfoView.errmsg + " 耗时:" + sw.Elapsed.TotalMilliseconds + "ms";
  1200. return approvalInfoView;
  1201. }
  1202. public async Task<ApprovalInfoView> GetApprovalInfoUpdateAsync(
  1203. DateTime startTime,
  1204. DateTime endTime,
  1205. string newCursor = "",
  1206. int size = 100,
  1207. List<IQiYeWeChatApiService.FilterCondition> filters = null)
  1208. {
  1209. //申请人企业微信Id验证
  1210. var creator = filters?.FirstOrDefault(f => f.key == "creator")?.value ?? "";
  1211. if (string.IsNullOrEmpty(creator))
  1212. {
  1213. return new ApprovalInfoView
  1214. {
  1215. errcode = -1,
  1216. errmsg = "OA用户信息中未填写申请人企业微信ID!"
  1217. };
  1218. }
  1219. long starttime = (long)(startTime - _1970).TotalSeconds;
  1220. long endtime = (long)(endTime - _1970).TotalSeconds;
  1221. var requestData = new
  1222. {
  1223. starttime = starttime,
  1224. endtime = endtime,
  1225. new_cursor = newCursor,
  1226. size = size,
  1227. filters = filters ?? new List<IQiYeWeChatApiService.FilterCondition>()
  1228. };
  1229. string jsonContent = JsonConvert.SerializeObject(requestData);
  1230. var httpContent = new StringContent(jsonContent, Encoding.UTF8, "application/json");
  1231. var token = await GetTokenAsync(5);
  1232. try
  1233. {
  1234. string url = "/cgi-bin/oa/getapprovalinfo?access_token=" + token.access_token;
  1235. HttpResponseMessage response = await _httpClient.PostAsync(url, httpContent);
  1236. response.EnsureSuccessStatusCode();
  1237. string responseContent = await response.Content.ReadAsStringAsync();
  1238. var result = JsonConvert.DeserializeObject<ApprovalInfoView>(responseContent);
  1239. return result;
  1240. }
  1241. catch (Exception ex)
  1242. {
  1243. ApprovalInfoView approvalInfoView = new ApprovalInfoView();
  1244. approvalInfoView.errcode = -1;
  1245. approvalInfoView.errmsg = ex.Message;
  1246. return approvalInfoView;
  1247. }
  1248. }
  1249. /// <summary>
  1250. /// 获取审批申请详情
  1251. /// </summary>
  1252. /// <param name="sp_no"></param>
  1253. /// <returns></returns>
  1254. public async Task<ApprovalDetailView> GetApprovalDetailAsync(string sp_no)
  1255. {
  1256. ApprovalDetailView ApprovalDetailView = new ApprovalDetailView();
  1257. if (string.IsNullOrEmpty(sp_no))
  1258. {
  1259. return ApprovalDetailView;
  1260. }
  1261. //获取审批数据 token
  1262. Access_TokenView access_Token = await GetTokenAsync(5);
  1263. if (access_Token.errcode != 0)
  1264. {
  1265. ApprovalDetailView.errcode = access_Token.errcode;
  1266. ApprovalDetailView.errmsg = string.Format("【企业微信】【审批申请详情】【Token】【Msg】{0}", access_Token.errmsg);
  1267. return ApprovalDetailView;
  1268. }
  1269. string url = string.Format("/cgi-bin/oa/getapprovaldetail?access_token={0}", access_Token.access_token);
  1270. ApprovalDetail_Request approvalDetail_Req = new ApprovalDetail_Request()
  1271. {
  1272. access_token = access_Token.access_token,
  1273. sp_no = sp_no,
  1274. };
  1275. var json = System.Text.Json.JsonSerializer.Serialize(approvalDetail_Req);
  1276. var content = new StringContent(json, Encoding.UTF8, "application/json");
  1277. var create_Req = await _httpClient.PostAsync(url, content);
  1278. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  1279. ApprovalDetailView = System.Text.Json.JsonSerializer.Deserialize<ApprovalDetailView>(stringResponse,
  1280. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  1281. return ApprovalDetailView;
  1282. }
  1283. /// <summary>
  1284. /// 批量获取审批详情
  1285. /// </summary>
  1286. /// <param name="startDt"></param>
  1287. /// <param name="endDt"></param>
  1288. /// <param name="creator">
  1289. /// 申请人
  1290. /// </param>
  1291. /// <param name="sp_status">
  1292. /// sp_status-审批单状态(1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付)
  1293. /// </param>
  1294. /// <param name="record_type">
  1295. /// record_type - 审批单类型属性,1-请假;2-打卡补卡;3-出差;4-外出;5-加班; 6- 调班;7-会议室预定;8-退款审批;9-红包报销审批
  1296. /// </param>
  1297. /// <returns></returns>
  1298. public async Task<List<Sp_Detail>> GetApprovalDetailsAsync(DateTime startDt, DateTime endDt, string creator, int sp_status, int record_type)
  1299. {
  1300. Stopwatch sw = new Stopwatch();
  1301. sw.Start();
  1302. List<Sp_Detail> details = new List<Sp_Detail>();
  1303. if (string.IsNullOrEmpty(creator))
  1304. {
  1305. return details;
  1306. }
  1307. ApprovalInfoView approvalInfoView = new ApprovalInfoView();
  1308. approvalInfoView = await GetApprovalInfoAsync(startDt, endDt, creator, sp_status, record_type);
  1309. if (approvalInfoView.errcode != 0)
  1310. {
  1311. return details;
  1312. }
  1313. //循环查询详情
  1314. foreach (var item in approvalInfoView.sp_no_list)
  1315. {
  1316. ApprovalDetailView approvalDetailView = new ApprovalDetailView();
  1317. approvalDetailView = await GetApprovalDetailAsync(item);
  1318. if (approvalDetailView.errcode != 0)
  1319. {
  1320. Log.Error("【GetApprovalDetailsAsync】 record_type:" + record_type + " ErrorMsg:" + approvalDetailView.errmsg);
  1321. break;
  1322. }
  1323. details.Add(approvalDetailView.info);
  1324. }
  1325. sw.Stop();
  1326. double hs = sw.Elapsed.TotalMilliseconds;
  1327. return details;
  1328. }
  1329. /// <summary>
  1330. /// 获取审批模板详情
  1331. /// </summary>
  1332. /// <param name="template_id">模板Id</param>
  1333. /// <returns></returns>
  1334. public async Task<TemplateDetailView> GetTemplateDetailAsync(string template_id)
  1335. {
  1336. TemplateDetailView templateDetailView = new TemplateDetailView();
  1337. if (string.IsNullOrEmpty(template_id))
  1338. {
  1339. templateDetailView.errmsg = "template_id为空!";
  1340. return templateDetailView;
  1341. }
  1342. //获取审批数据 token
  1343. Access_TokenView access_Token = await GetTokenAsync(5);
  1344. if (access_Token.errcode != 0)
  1345. {
  1346. templateDetailView.errcode = access_Token.errcode;
  1347. templateDetailView.errmsg = string.Format("【企业微信】【审批申请详情】【Token】【Msg】{0}", access_Token.errmsg);
  1348. return templateDetailView;
  1349. }
  1350. string url = string.Format("/cgi-bin/oa/gettemplatedetail?access_token={0}", access_Token.access_token);
  1351. var approvalDetail_Req = new
  1352. {
  1353. access_token = access_Token.access_token,
  1354. template_id = template_id,
  1355. };
  1356. var json = System.Text.Json.JsonSerializer.Serialize(approvalDetail_Req);
  1357. var content = new StringContent(json, Encoding.UTF8, "application/json");
  1358. var create_Req = await _httpClient.PostAsync(url, content);
  1359. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  1360. templateDetailView = System.Text.Json.JsonSerializer.Deserialize<TemplateDetailView>(stringResponse,
  1361. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  1362. return templateDetailView;
  1363. }
  1364. #endregion
  1365. #region hook机器人
  1366. /// <summary>
  1367. /// 发送团组信息给财务群
  1368. /// </summary>
  1369. /// <param name="msg"></param>
  1370. /// <returns></returns>
  1371. /// <exception cref="NotImplementedException"></exception>
  1372. public async Task<ResponseBase> RobotSendMsg_GroupInfo(string msg)
  1373. {
  1374. string key = "b4fe152f-a97a-48b1-830f-ab447f6d2f5f";
  1375. string url = string.Format("/cgi-bin/webhook/send?key={0}", key);
  1376. RobotSendMsg_GroupInfo_Content contentStr = new RobotSendMsg_GroupInfo_Content() { content = msg };
  1377. RobotSendMsg_GroupInfo_Param reqJson = new RobotSendMsg_GroupInfo_Param()
  1378. {
  1379. msgtype = "markdown",
  1380. markdown = contentStr
  1381. };
  1382. var json = System.Text.Json.JsonSerializer.Serialize(reqJson);
  1383. var content = new StringContent(json, Encoding.UTF8, "application/json");
  1384. var create_Req = await _httpClient.PostAsync(url, content);
  1385. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  1386. ResponseBase sendMsgView = System.Text.Json.JsonSerializer.Deserialize<ResponseBase>(stringResponse,
  1387. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  1388. return sendMsgView;
  1389. }
  1390. #endregion
  1391. #region 团组状态通知
  1392. /// <summary>
  1393. /// 获取部门成员
  1394. /// </summary>
  1395. /// <param name="departmentId"></param>
  1396. /// <returns></returns>
  1397. public async Task<GroupStatus_UserSimplelistView> GroupStatus_GetUserList(int departmentId = 8402038)
  1398. {
  1399. GroupStatus_UserSimplelistView result = new GroupStatus_UserSimplelistView();
  1400. Access_TokenView access_Token = await GetTokenAsync(6);
  1401. if (access_Token.errcode != 0)
  1402. {
  1403. result.errcode = access_Token.errcode;
  1404. result.errmsg = string.Format("【企业微信】【团组状态通知】【Token】【Msg】{0}", access_Token.errmsg);
  1405. return result;
  1406. }
  1407. string url = string.Format("/cgi-bin/user/simplelist?access_token={0}&department_id={1}", access_Token.access_token, departmentId);
  1408. var simplelist_Req = await _httpClient.GetAsync(url);
  1409. if (simplelist_Req.IsSuccessStatusCode)
  1410. {
  1411. var stringResponse = await simplelist_Req.Content.ReadAsStringAsync();
  1412. result = System.Text.Json.JsonSerializer.Deserialize<GroupStatus_UserSimplelistView>(stringResponse,
  1413. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  1414. }
  1415. else
  1416. {
  1417. result.errcode = -1;
  1418. result.errmsg = "企业微信部门列表未获取到!";
  1419. }
  1420. return result;
  1421. }
  1422. /// <summary>
  1423. /// 创建群聊
  1424. /// </summary>
  1425. /// <param name="chatName"></param>
  1426. /// <param name="owner"></param>
  1427. /// <param name="userList"></param>
  1428. /// <param name="chatId"></param>
  1429. /// <returns></returns>
  1430. public async Task<GroupStatus_CreateChatView> GroupStatus_CreateChat(string chatName, string owner, List<string> userList, string chatId)
  1431. {
  1432. GroupStatus_CreateChatView result = new GroupStatus_CreateChatView();
  1433. Access_TokenView access_Token = await GetTokenAsync(6);
  1434. if (access_Token.errcode != 0)
  1435. {
  1436. result.errcode = access_Token.errcode;
  1437. result.errmsg = string.Format("【企业微信】【团组状态通知】【Token】【Msg】{0}", access_Token.errmsg);
  1438. return result;
  1439. }
  1440. GroupStatus_CreateChat reqJson = new GroupStatus_CreateChat()
  1441. {
  1442. chatid = chatId,
  1443. name = chatName,
  1444. owner = owner,
  1445. userlist = userList
  1446. };
  1447. string url = string.Format("/cgi-bin/appchat/create?access_token={0}&debug=1", access_Token.access_token);
  1448. var json = System.Text.Json.JsonSerializer.Serialize(reqJson);
  1449. var content = new StringContent(json, Encoding.UTF8, "application/json");
  1450. var create_Req = await _httpClient.PostAsync(url, content);
  1451. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  1452. result = System.Text.Json.JsonSerializer.Deserialize<GroupStatus_CreateChatView>(stringResponse,
  1453. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  1454. return result;
  1455. }
  1456. /// <summary>
  1457. /// 向群聊发送信息
  1458. /// </summary>
  1459. /// <param name="chatId"></param>
  1460. /// <param name="msgContent"></param>
  1461. /// <param name="msgType"></param>
  1462. /// <returns></returns>
  1463. /// <exception cref="NotImplementedException"></exception>
  1464. public async Task<ResponseBase> GroupStatus_SendChatMsg_Markdown(string chatId, string msgContent, string msgType = "markdown")
  1465. {
  1466. ResponseBase result = new ResponseBase();
  1467. Access_TokenView access_Token = await GetTokenAsync(6);
  1468. if (access_Token.errcode != 0)
  1469. {
  1470. result.errcode = access_Token.errcode;
  1471. result.errmsg = string.Format("【企业微信】【团组状态通知】【Token】【Msg】{0}", access_Token.errmsg);
  1472. return result;
  1473. }
  1474. RobotSendMsg_GroupInfo_Content markdown = new RobotSendMsg_GroupInfo_Content() { content = msgContent };
  1475. GroupStatus_AppChatSend_Markdown reqJson = new GroupStatus_AppChatSend_Markdown()
  1476. {
  1477. chatid = chatId,
  1478. msgtype = msgType,
  1479. markdown = markdown
  1480. };
  1481. string url = string.Format("/cgi-bin/appchat/send?access_token={0}", access_Token.access_token);
  1482. var json = System.Text.Json.JsonSerializer.Serialize(reqJson);
  1483. var content = new StringContent(json, Encoding.UTF8, "application/json");
  1484. var create_Req = await _httpClient.PostAsync(url, content);
  1485. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  1486. result = System.Text.Json.JsonSerializer.Deserialize<ResponseBase>(stringResponse,
  1487. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  1488. return result;
  1489. }
  1490. /// <summary>
  1491. /// 向用户发送Markdown信息
  1492. /// </summary>
  1493. /// <param name="toUser"></param>
  1494. /// <param name="msgContent"></param>
  1495. /// <param name="msgType"></param>
  1496. /// <returns></returns>
  1497. /// <exception cref="NotImplementedException"></exception>
  1498. public async Task<GroupStatus_SendMessageView> GroupStatus_SendMessage_ToUser_Markdown(List<string> toUser, string msgContent, string msgType = "markdown")
  1499. {
  1500. GroupStatus_SendMessageView result = new GroupStatus_SendMessageView();
  1501. Access_TokenView access_Token = await GetTokenAsync(6);
  1502. if (access_Token.errcode != 0)
  1503. {
  1504. result.errcode = access_Token.errcode;
  1505. result.errmsg = string.Format("【企业微信】【团组状态通知】【Token】【Msg】{0}", access_Token.errmsg);
  1506. return result;
  1507. }
  1508. RobotSendMsg_GroupInfo_Content markdown = new RobotSendMsg_GroupInfo_Content() { content = msgContent };
  1509. string userIds = "";
  1510. toUser.ForEach(s => userIds += s + "|");
  1511. userIds = userIds.TrimEnd('|');
  1512. GroupStatus_AppSend_Markdown reqJson = new GroupStatus_AppSend_Markdown()
  1513. {
  1514. markdown = markdown,
  1515. touser = userIds
  1516. };
  1517. string url = string.Format("/cgi-bin/message/send?access_token={0}&debug=1", access_Token.access_token);
  1518. var json = System.Text.Json.JsonSerializer.Serialize(reqJson);
  1519. var content = new StringContent(json, Encoding.UTF8, "application/json");
  1520. var create_Req = await _httpClient.PostAsync(url, content);
  1521. var stringResponse = await create_Req.Content.ReadAsStringAsync();
  1522. result = System.Text.Json.JsonSerializer.Deserialize<GroupStatus_SendMessageView>(stringResponse,
  1523. new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase });
  1524. return result;
  1525. }
  1526. #endregion
  1527. public long ConvertToTimeSpan(DateTime dt)
  1528. {
  1529. return (dt.ToUniversalTime().Ticks - 621355968000000000) / 10000000;
  1530. }
  1531. }
  1532. }