SystemService.cs 90 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793
  1. using Azure.Storage.Blobs.Models;
  2. using DocumentFormat.OpenXml.Bibliography;
  3. using DocumentFormat.OpenXml.Office2010.Excel;
  4. using DocumentFormat.OpenXml.Wordprocessing;
  5. using HTEXLib;
  6. using HTEXLib.COMM.Helpers;
  7. using Microsoft.Azure.Amqp.Framing;
  8. using Newtonsoft.Json.Linq;
  9. using OpenXmlPowerTools;
  10. using System;
  11. using System.Collections.Concurrent;
  12. using System.Collections.Generic;
  13. using System.Diagnostics.PerformanceData;
  14. using System.IdentityModel.Tokens.Jwt;
  15. using System.Linq;
  16. using System.Text;
  17. using System.Text.Json;
  18. using System.Text.RegularExpressions;
  19. using System.Threading.Tasks;
  20. using TEAMModelOS.SDK.DI;
  21. using TEAMModelOS.SDK.Extension;
  22. using TEAMModelOS.SDK.Models.Cosmos.Common;
  23. using TEAMModelOS.SDK.Models.Dtos;
  24. using static Azure.Core.HttpHeader;
  25. using static OpenXmlPowerTools.RevisionProcessor;
  26. using static TEAMModelOS.SDK.Models.Service.SystemService;
  27. namespace TEAMModelOS.SDK.Models.Service
  28. {
  29. public static class SystemService
  30. {
  31. public static async Task RecordAccumulateData(AzureRedisFactory azureRedis, DingDing dingDing, Accumulate accumulate)
  32. {
  33. if (!string.IsNullOrWhiteSpace(accumulate.key) && !string.IsNullOrWhiteSpace(accumulate.target) &&
  34. !string.IsNullOrWhiteSpace(accumulate.id) && !string.IsNullOrWhiteSpace(accumulate.name) &&
  35. !string.IsNullOrWhiteSpace(accumulate.scope) && !string.IsNullOrWhiteSpace(accumulate.client))
  36. {
  37. await RecordAccumulateData(azureRedis, accumulate.key, accumulate.target, accumulate.id, accumulate.name, accumulate.scope, accumulate.client, accumulate.count);
  38. }
  39. else
  40. {
  41. await dingDing.SendBotMsg($"IES累计数据变更统计参数异常,{accumulate.ToJsonString()}", GroupNames.成都开发測試群組);
  42. }
  43. }
  44. /// <summary>
  45. /// 记录累计数据
  46. /// </summary>
  47. public static async Task RecordAccumulateData(AzureRedisFactory azureRedis, string key, string target, string id, string name, string scope, string client, int count)
  48. {
  49. if (!string.IsNullOrWhiteSpace(key) && !string.IsNullOrWhiteSpace(target) &&
  50. !string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(name) &&
  51. !string.IsNullOrWhiteSpace(scope)&& !string.IsNullOrWhiteSpace(client))
  52. {
  53. //处理UTC时差
  54. var nowTime = DateTimeOffset.UtcNow.GetGMTTime();
  55. int difference = (DayOfWeek.Sunday - nowTime.DayOfWeek + 7) % 7; //1-7的结果0-6
  56. var day = nowTime.ToString("yyyyMMdd");
  57. string redisKey = $"Accumulate:Daily:{scope}:{key}:{day}";
  58. string member = $"{target}::{id}::{client}::{name}";
  59. await azureRedis.GetRedisClient(8).SortedSetIncrementAsync(redisKey, member, count);
  60. await azureRedis.GetRedisClient(8).KeyExpireAsync(redisKey, new TimeSpan((difference+1)*24, 10, 0));
  61. //if (key.Equals("lesson") || key.StartsWith("login_"))
  62. //{
  63. // redisKey = $"Accumulate:Daily:ies:{key}:{day}";
  64. // if (scope.Equals("school"))
  65. // {
  66. // member = $"ies::{id}::{name}";
  67. // }
  68. // else {
  69. // member = $"ies::ies::{name}";
  70. // }
  71. // await azureRedis.GetRedisClient(8).SortedSetIncrementAsync(redisKey, member, 1);
  72. //}
  73. }
  74. }
  75. static double GetUserDuration(List<long> times )
  76. {
  77. if (times.IsNotEmpty())
  78. {
  79. if (times.Count>=2)
  80. {
  81. double totalDuration = 0;
  82. // DateTime lastTime = DateTimeOffset.FromUnixTimeMilliseconds((long)jsonData[0]["time"]).UtcDateTime;
  83. long ltime = times[0];
  84. for (int i = 1; i < times.Count; i++)
  85. {
  86. long ctime = times[i];
  87. //DateTime currentTime = DateTimeOffset.FromUnixTimeMilliseconds((long)jsonData[i]["time"]).UtcDateTime;
  88. long timeDifference = ctime - ltime;
  89. ///如果一小时内连续操作,则按真实时间累计
  90. if (timeDifference < 3600000)
  91. {
  92. totalDuration += timeDifference;
  93. }
  94. else
  95. { ///如果一小时内没有连续操作,则按象征性加10秒,以确保数据有效性。 如果因为一小时没有操作,则表示没有新的接口再次请求,当即就已经退出系统。否则后续仍然会有接口进入,并且带有时间戳
  96. totalDuration += 10000;
  97. }
  98. ltime = ctime;
  99. }
  100. return totalDuration;
  101. }
  102. else { return 10000; }
  103. }
  104. else {
  105. return 0;
  106. }
  107. }
  108. public static List<SchoolStick> CountSchoolStickiness(IEnumerable<IGrouping<string,ApiVisit>> schoolApiVisits, IEnumerable<ApiVisit> apiVisits)
  109. {
  110. List<SchoolStick> schoolStickiness = new List<SchoolStick>();
  111. foreach (var chinaSchoolKey in schoolApiVisits)
  112. {
  113. SchoolStick stickiness = new SchoolStick()
  114. {
  115. id = chinaSchoolKey.Key
  116. };
  117. var teachers = chinaSchoolKey.ToList().Where(x => !string.IsNullOrWhiteSpace(x.userId) && !string.IsNullOrWhiteSpace(x.scope) && x.scope.Equals("teacher")).GroupBy(x => x.userId);
  118. double hitaTime = 0, hiteachTime = 0, ies5TchTime = 0, otherTchTime = 0, ies5StuTime = 0, otherStuTime = 0;
  119. int hitaTch= 0, hiteachTch = 0, ies5Tch = 0, otherTch = 0, ies5Stu = 0, otherStu = 0;
  120. double hitaCount = 0, hiteachCount = 0, ies5TchCount = 0, otherTchCount = 0, ies5StuCount = 0, otherStuCount = 0;
  121. double lessonCount= chinaSchoolKey.ToList().Where(x => x.path.Contains("hiteach/create-lesson")).Count() ;
  122. int teacherCount= teachers.Count() ;
  123. foreach (var user in teachers)
  124. {
  125. TchStick tchStick = new TchStick()
  126. {
  127. id = user.Key,
  128. school= chinaSchoolKey.Key
  129. };
  130. //HiTA
  131. var teacherHitaVisit = apiVisits.Where(x => !string.IsNullOrWhiteSpace(x.userId) && x.userId.Equals(user.Key) && x.client.Equals("hita"));
  132. var teacherHitaVisitCount = teacherHitaVisit.Count();
  133. if (teacherHitaVisitCount>0)
  134. { hitaTch+=1; }
  135. var teacherHitaVisitTime = GetUserDuration(teacherHitaVisit.OrderBy(x => x.time).Select(x => x.time).ToList());
  136. hitaCount+=teacherHitaVisitCount;
  137. hitaTime+=teacherHitaVisitTime;
  138. tchStick.hita.count.value=teacherHitaVisitCount;
  139. tchStick.hita.duration.value=teacherHitaVisitTime;
  140. //Other
  141. var teacherOtherVisit = user.Where(x => !x.client.Equals("hita")&&!x.client.Equals("hiteach")&&!x.client.Equals("ies5"));
  142. var teacherOtherVisitCount= teacherOtherVisit.Count();
  143. var teacherOtherVisitTime= GetUserDuration(teacherOtherVisit.OrderBy(x => x.time).Select(x => x.time).ToList());
  144. if (teacherOtherVisitCount>0)
  145. { otherTch+=1; }
  146. otherTchCount+=teacherOtherVisitCount;
  147. otherTchTime+=teacherOtherVisitTime;
  148. tchStick.otherTch.count.value=teacherOtherVisitCount;
  149. tchStick.otherTch.duration.value=teacherOtherVisitTime;
  150. //HiTeach
  151. //教师访问hiteach 不带学校信息的
  152. var teacherHiteachVisit = apiVisits.Where(x => !string.IsNullOrWhiteSpace(x.userId) && x.userId.Equals(user.Key) && x.client.Equals("hiteach") && string.IsNullOrWhiteSpace(x.school));
  153. //教师访问hiteach 包含学校信息的
  154. var teacherHiteachSchoolVisit = user.Where(x => x.client.Equals("hiteach"));
  155. //教师所有的Hiteach访问
  156. List<ApiVisit> teacherHiteachAllVisit = new List<ApiVisit>();
  157. teacherHiteachAllVisit.AddRange(teacherHiteachVisit);
  158. teacherHiteachAllVisit.AddRange(teacherHiteachSchoolVisit);
  159. var teacherHiteachAllVisitCount = teacherHiteachAllVisit.Count();
  160. if (teacherHiteachAllVisitCount>0)
  161. { hiteachTch+=1; }
  162. var teacherHiteachAllVisitTime = GetUserDuration(teacherHiteachAllVisit.OrderBy(x => x.time).Select(x => x.time).ToList());
  163. hiteachCount+=teacherHiteachAllVisitCount;
  164. hiteachTime+=teacherHiteachAllVisitTime;
  165. tchStick.hiteach.count.value=teacherHiteachAllVisitCount;
  166. tchStick.hiteach.duration.value=teacherHiteachAllVisitTime;
  167. //IES5
  168. var teacherIes5Visit = user.Where(x => x.client.Equals("ies5"));
  169. var teacherIes5VisitCount= teacherIes5Visit.Count();
  170. if (teacherIes5VisitCount>0)
  171. { ies5Tch+=1; }
  172. var teacherIes5VisitTime = GetUserDuration(teacherIes5Visit.OrderBy(x => x.time).Select(x => x.time).ToList());
  173. ies5TchCount+=teacherIes5VisitCount;
  174. ies5TchTime+=teacherIes5VisitTime;
  175. tchStick.ies5Tch.count.value=teacherIes5VisitCount;
  176. tchStick.ies5Tch.duration.value=teacherIes5VisitTime;
  177. double lessonCountTch = chinaSchoolKey.ToList().Where(x => x.path.Contains("hiteach/create-lesson") && x.userId.Equals(user.Key)).Count();
  178. tchStick.lesson.value=lessonCountTch;
  179. tchStick.tmd.count.value=tchStick.hita.count.value+tchStick.hiteach.count.value+tchStick.ies5Tch.count.value+tchStick.otherTch.count.value;
  180. tchStick.tmd.duration.value=tchStick.hita.duration.value+tchStick.hiteach.duration.value+tchStick.ies5Tch.duration.value+tchStick.otherTch.duration.value;
  181. tchStick.hita.userCount=1;
  182. tchStick.hiteach.userCount=1;
  183. tchStick.ies5Tch.userCount=1;
  184. tchStick.otherTch.userCount=1;
  185. tchStick.tmd.userCount=1;
  186. if (tchStick.hita.count.value>0 && tchStick.hita.duration.value>0)
  187. {
  188. tchStick.hita.stick.value= (tchStick.hita.duration.value/1000/tchStick.hita.count.value);
  189. }
  190. if (tchStick.ies5Tch.count.value>0 && tchStick.ies5Tch.duration.value>0)
  191. {
  192. tchStick.ies5Tch.stick.value= (tchStick.ies5Tch.duration.value/1000/tchStick.ies5Tch.count.value);
  193. }
  194. if (tchStick.otherTch.count.value>0 && tchStick.otherTch.duration.value>0)
  195. {
  196. tchStick.otherTch.stick.value= (tchStick.otherTch.duration.value/1000/tchStick.otherTch.count.value);
  197. }
  198. if (tchStick.hiteach.count.value>0 && tchStick.hiteach.duration.value>0)
  199. {
  200. tchStick.hiteach.stick.value= (tchStick.hiteach.duration.value/1000/tchStick.hiteach.count.value)+tchStick.lesson.value;
  201. }
  202. if (tchStick.tmd.count.value>0 && tchStick.tmd.duration.value>0)
  203. {
  204. tchStick.tmd.stick.value= (tchStick.tmd.duration.value/1000/tchStick.tmd.count.value)+ tchStick.lesson.value;
  205. }
  206. stickiness.tchSticks.Add(tchStick);
  207. }
  208. var student = chinaSchoolKey.ToList().Where(x => !string.IsNullOrWhiteSpace(x.userId) && !string.IsNullOrWhiteSpace(x.scope) && (x.scope.Equals("student")||x.scope.Equals("tmduser"))).GroupBy(x => x.userId);
  209. var studentCount = student.Count();
  210. foreach (var user in student)
  211. {
  212. StuStick stuStick = new StuStick
  213. {
  214. id=user.Key,
  215. school=chinaSchoolKey.Key
  216. };
  217. var studentOtherVisit = user.Where(x => !x.client.Equals("ies5"));
  218. var studentOtherVisitCount = studentOtherVisit.Count();
  219. if (studentOtherVisitCount>0)
  220. { otherStu+=1; }
  221. double studentOtherVisitTime = GetUserDuration(studentOtherVisit.OrderBy(x => x.time).Select(x => x.time).ToList()) ;
  222. var studentIes5Visit = user.Where(x => x.client.Equals("ies5"));
  223. var studentIes5VisitCount = studentIes5Visit.Count();
  224. if (studentIes5VisitCount>0)
  225. { ies5Stu+=1; }
  226. double studentIes5VisitTime = GetUserDuration(studentIes5Visit.OrderBy(x => x.time).Select(x => x.time).ToList());
  227. ies5StuCount+=studentIes5VisitCount;
  228. ies5StuTime+=studentIes5VisitTime;
  229. otherStuCount+=studentOtherVisitCount;
  230. otherStuTime+=studentOtherVisitTime;
  231. stuStick.ies5Stu.count.value=studentIes5VisitCount;
  232. stuStick.ies5Stu.duration.value=studentIes5VisitTime;
  233. stuStick.otherStu.count.value=studentOtherVisitCount;
  234. stuStick.otherStu.duration.value=studentOtherVisitTime;
  235. stuStick.tmd.count.value= stuStick.ies5Stu.count.value+stuStick.otherStu.count.value;
  236. stuStick.tmd.duration.value= stuStick.ies5Stu.duration.value+stuStick.otherStu.duration.value;
  237. stuStick.ies5Stu.userCount=1;
  238. stuStick.otherStu.userCount=1;
  239. stuStick.tmd.userCount=1;
  240. if (stuStick.ies5Stu.count.value>0 && stuStick.ies5Stu.duration.value>0)
  241. {
  242. stuStick.ies5Stu.stick.value= (stuStick.ies5Stu.duration.value/1000/stuStick.ies5Stu.count.value);
  243. }
  244. if (stuStick.otherStu.count.value>0 && stuStick.otherStu.duration.value>0)
  245. {
  246. stuStick.otherStu.stick.value=(stuStick.otherStu.duration.value/1000/stuStick.otherStu.count.value);
  247. }
  248. if (stuStick.tmd.count.value>0 && stuStick.tmd.duration.value>0)
  249. {
  250. stuStick.tmd.stick.value=(stuStick.tmd.duration.value/1000/stuStick.tmd.count.value);
  251. }
  252. stickiness.stuSticks.Add(stuStick);
  253. }
  254. stickiness.hita.duration.value=hitaTime;
  255. stickiness.hiteach.duration.value=hiteachTime;
  256. stickiness.otherTch.duration.value=otherTchTime;
  257. stickiness.ies5Tch.duration.value=ies5TchTime;
  258. stickiness.tmd.duration.value=hitaTime+hiteachTime+otherTchTime+ies5TchTime+otherStuTime+ies5StuTime;
  259. stickiness.hita.userCount=hitaTch;
  260. stickiness.hiteach.userCount=hiteachTch;
  261. stickiness.ies5Tch.userCount=ies5Tch;
  262. stickiness.otherTch.userCount=otherTch;
  263. stickiness.ies5Stu.userCount=ies5Stu;
  264. stickiness.otherStu.userCount=otherStu;
  265. stickiness.hita.count.value=hitaCount;
  266. stickiness.hiteach.count.value=hiteachCount;
  267. stickiness.ies5Tch.count.value=ies5TchCount;
  268. stickiness.otherTch.count.value=otherTchCount;
  269. stickiness.ies5Stu.count.value=ies5StuCount;
  270. stickiness.otherStu.count.value=otherStuCount;
  271. stickiness.tmd.count.value=hitaCount+hiteachCount+ies5TchCount+otherTchCount+ies5StuCount+otherStuCount;
  272. stickiness.lesson.value=lessonCount;
  273. stickiness.tmd.userCount=teacherCount+studentCount;
  274. if(stickiness.hita.count.value>0 && stickiness.hita.duration.value>0)
  275. {
  276. stickiness.hita.stick.value=(stickiness.hita.userCount* stickiness.hita.count.value)/(stickiness.hita.duration.value/1000/stickiness.hita.count.value);
  277. }
  278. if (stickiness.ies5Stu.count.value>0 && stickiness.ies5Stu.duration.value>0)
  279. {
  280. stickiness.ies5Stu.stick.value=(stickiness.ies5Stu.userCount* stickiness.ies5Stu.count.value)/(stickiness.ies5Stu.duration.value/1000/stickiness.ies5Stu.count.value);
  281. }
  282. if (stickiness.ies5Tch.count.value>0 && stickiness.ies5Tch.duration.value>0)
  283. {
  284. stickiness.ies5Tch.stick.value=(stickiness.ies5Tch.userCount* stickiness.ies5Tch.count.value)/(stickiness.ies5Tch.duration.value/1000/stickiness.ies5Tch.count.value);
  285. }
  286. if (stickiness.otherStu.count.value>0 && stickiness.otherStu.duration.value>0)
  287. {
  288. stickiness.otherStu.stick.value=(stickiness.otherStu.userCount* stickiness.otherStu.count.value)/(stickiness.otherStu.duration.value/1000/stickiness.otherStu.count.value);
  289. }
  290. if (stickiness.otherTch.count.value>0 && stickiness.otherTch.duration.value>0)
  291. {
  292. stickiness.otherTch.stick.value=(stickiness.otherTch.userCount* stickiness.otherTch.count.value)/(stickiness.otherTch.duration.value/1000/stickiness.otherTch.count.value);
  293. }
  294. if (stickiness.hiteach.count.value>0 && stickiness.hiteach.duration.value>0)
  295. {
  296. stickiness.hiteach.stick.value=(stickiness.hiteach.userCount* stickiness.hiteach.count.value)/(stickiness.hiteach.duration.value/1000/stickiness.hiteach.count.value)+stickiness.lesson.value;
  297. }
  298. if (stickiness.tmd.count.value>0 && stickiness.tmd.duration.value>0)
  299. {
  300. stickiness.tmd.stick.value=(stickiness.tmd.userCount* stickiness.tmd.count.value)/(stickiness.tmd.duration.value/1000/stickiness.tmd.count.value)+ stickiness.lesson.value;
  301. }
  302. stickiness.tchSticks= OrderByTchStick(stickiness.tchSticks);
  303. stickiness.stuSticks= OrderByStuStick(stickiness.stuSticks);
  304. schoolStickiness.Add(stickiness);
  305. }
  306. return OrderBySchoolStick(schoolStickiness);
  307. }
  308. private static List<StuStick> OrderByStuStick(List<StuStick> stuStickiness)
  309. {
  310. // 假设visit已经填充了数据
  311. #region
  312. var rank_tmd_count = stuStickiness.Select(x => x.tmd.count.value).Distinct().OrderByDescending(v => v).ToList();
  313. var rank_ies5Stu_count = stuStickiness.Select(x => x.ies5Stu.count.value).Distinct().OrderByDescending(v => v).ToList();
  314. var rank_otherStu_count = stuStickiness.Select(x => x.otherStu.count.value).Distinct().OrderByDescending(v => v).ToList();
  315. #endregion
  316. #region
  317. var rank_tmd_duration = stuStickiness.Select(x => x.tmd.duration.value).Distinct().OrderByDescending(v => v).ToList();
  318. var rank_ies5Stu_duration = stuStickiness.Select(x => x.ies5Stu.duration.value).Distinct().OrderByDescending(v => v).ToList();
  319. var rank_otherStu_duration = stuStickiness.Select(x => x.otherStu.duration.value).Distinct().OrderByDescending(v => v).ToList();
  320. #endregion
  321. #region
  322. var rank_tmd_stick = stuStickiness.Select(x => x.tmd.stick.value).Distinct().OrderByDescending(v => v).ToList();
  323. var rank_ies5Stu_stick = stuStickiness.Select(x => x.ies5Stu.stick.value).Distinct().OrderByDescending(v => v).ToList();
  324. var rank_otherStu_stick = stuStickiness.Select(x => x.otherStu.stick.value).Distinct().OrderByDescending(v => v).ToList();
  325. #endregion
  326. stuStickiness.ForEach(x =>
  327. {
  328. #region
  329. if (x.tmd.count.value>0)
  330. {
  331. int index_tmd_count = rank_tmd_count.FindIndex(i => i==x.tmd.count.value);
  332. if (index_tmd_count!=-1)
  333. {
  334. x.tmd.count.rank = index_tmd_count + 1;
  335. }
  336. }
  337. if (x.ies5Stu.count.value>0)
  338. {
  339. int index_ies5Stu_count = rank_ies5Stu_count.FindIndex(i => i==x.ies5Stu.count.value);
  340. if (index_ies5Stu_count!=-1)
  341. {
  342. x.ies5Stu.count.rank = index_ies5Stu_count + 1;
  343. }
  344. }
  345. if (x.otherStu.count.value>0)
  346. {
  347. int index_otherStu_count = rank_otherStu_count.FindIndex(i => i==x.otherStu.count.value);
  348. if (index_otherStu_count!=-1)
  349. {
  350. x.otherStu.count.rank = index_otherStu_count + 1;
  351. }
  352. }
  353. #endregion
  354. #region
  355. if (x.tmd.duration.value> 0) {
  356. int index_tmd_duration = rank_tmd_duration.FindIndex(i => i==x.tmd.duration.value);
  357. if (index_tmd_duration!=-1)
  358. {
  359. x.tmd.duration.rank = index_tmd_duration + 1;
  360. }
  361. }
  362. if (x.ies5Stu.duration.value>0) {
  363. int index_ies5Stu_duration = rank_ies5Stu_duration.FindIndex(i => i==x.ies5Stu.duration.value);
  364. if (index_ies5Stu_duration!=-1)
  365. {
  366. x.ies5Stu.duration.rank = index_ies5Stu_duration + 1;
  367. }
  368. }
  369. if (x.otherStu.duration.value>0) {
  370. int index_otherStu_duration = rank_otherStu_duration.FindIndex(i => i==x.otherStu.duration.value);
  371. if (index_otherStu_duration!=-1)
  372. {
  373. x.otherStu.duration.rank = index_otherStu_duration + 1;
  374. }
  375. }
  376. #endregion
  377. #region
  378. if (x.tmd.stick.value>0)
  379. {
  380. int index_tmd_stick = rank_tmd_stick.FindIndex(i => i==x.tmd.stick.value);
  381. if (index_tmd_stick!=-1)
  382. {
  383. x.tmd.stick.rank = index_tmd_stick + 1;
  384. }
  385. }
  386. if (x.ies5Stu.stick.value>0)
  387. {
  388. int index_ies5Stu_stick = rank_ies5Stu_stick.FindIndex(i => i==x.ies5Stu.stick.value);
  389. if (index_ies5Stu_stick!=-1)
  390. {
  391. x.ies5Stu.stick.rank = index_ies5Stu_stick + 1;
  392. }
  393. }
  394. if (x.otherStu.stick.value>0)
  395. {
  396. int index_otherStu_stick = rank_otherStu_stick.FindIndex(i => i==x.otherStu.stick.value);
  397. if (index_otherStu_stick!=-1)
  398. {
  399. x.otherStu.stick.rank = index_otherStu_stick + 1;
  400. }
  401. }
  402. #endregion
  403. });
  404. return stuStickiness;
  405. }
  406. private static List<TchStick> OrderByTchStick(List<TchStick> tchStickiness)
  407. {
  408. // 假设visit已经填充了数据
  409. #region
  410. var rank_tmd_count = tchStickiness.Select(x => x.tmd.count.value).Distinct().OrderByDescending(v => v).ToList();
  411. var rank_hita_count = tchStickiness.Select(x => x.hita.count.value).Distinct().OrderByDescending(v => v).ToList();
  412. var rank_hiteach_count = tchStickiness.Select(x => x.hiteach.count.value).Distinct().OrderByDescending(v => v).ToList();
  413. var rank_ies5Tch_count = tchStickiness.Select(x => x.ies5Tch.count.value).Distinct().OrderByDescending(v => v).ToList();
  414. var rank_otherTch_count = tchStickiness.Select(x => x.otherTch.count.value).Distinct().OrderByDescending(v => v).ToList();
  415. var rank_lesson_count = tchStickiness.Select(x => x.lesson.value).Distinct().OrderByDescending(v => v).ToList();
  416. #endregion
  417. #region
  418. var rank_tmd_duration = tchStickiness.Select(x => x.tmd.duration.value).Distinct().OrderByDescending(v => v).ToList();
  419. var rank_hita_duration = tchStickiness.Select(x => x.hita.duration.value).Distinct().OrderByDescending(v => v).ToList();
  420. var rank_hiteach_duration = tchStickiness.Select(x => x.hiteach.duration.value).Distinct().OrderByDescending(v => v).ToList();
  421. var rank_ies5Tch_duration = tchStickiness.Select(x => x.ies5Tch.duration.value).Distinct().OrderByDescending(v => v).ToList();
  422. var rank_otherTch_duration = tchStickiness.Select(x => x.otherTch.duration.value).Distinct().OrderByDescending(v => v).ToList();
  423. #endregion
  424. #region
  425. var rank_tmd_stick = tchStickiness.Select(x => x.tmd.stick.value).Distinct().OrderByDescending(v => v).ToList();
  426. var rank_hita_stick = tchStickiness.Select(x => x.hita.stick.value).Distinct().OrderByDescending(v => v).ToList();
  427. var rank_hiteach_stick = tchStickiness.Select(x => x.hiteach.stick.value).Distinct().OrderByDescending(v => v).ToList();
  428. var rank_ies5Tch_stick = tchStickiness.Select(x => x.ies5Tch.stick.value).Distinct().OrderByDescending(v => v).ToList();
  429. var rank_otherTch_stick = tchStickiness.Select(x => x.otherTch.stick.value).Distinct().OrderByDescending(v => v).ToList();
  430. #endregion
  431. tchStickiness.ForEach(x => {
  432. #region
  433. int index_tmd_count = rank_tmd_count.FindIndex(i => i==x.tmd.count.value);
  434. if (index_tmd_count!=-1)
  435. {
  436. x.tmd.count.rank = index_tmd_count + 1;
  437. }
  438. int index_hita_count = rank_hita_count.FindIndex(i => i==x.hita.count.value);
  439. if (index_hita_count!=-1)
  440. {
  441. x.hita.count.rank = index_hita_count + 1;
  442. }
  443. int index_hiteach_count = rank_hiteach_count.FindIndex(i => i==x.hiteach.count.value);
  444. if (index_hiteach_count!=-1)
  445. {
  446. x.hiteach.count.rank = index_hiteach_count + 1;
  447. }
  448. int index_ies5Tch_count = rank_ies5Tch_count.FindIndex(i => i==x.ies5Tch.count.value);
  449. if (index_ies5Tch_count!=-1)
  450. {
  451. x.ies5Tch.count.rank = index_ies5Tch_count + 1;
  452. }
  453. int index_otherTch_count = rank_otherTch_count.FindIndex(i => i==x.otherTch.count.value);
  454. if (index_otherTch_count!=-1)
  455. {
  456. x.otherTch.count.rank = index_otherTch_count + 1;
  457. }
  458. int index_lesson_count = rank_lesson_count.FindIndex(i => i==x.lesson.value);
  459. if (index_lesson_count!=-1)
  460. {
  461. x.lesson.rank = index_lesson_count + 1;
  462. }
  463. #endregion
  464. #region
  465. int index_tmd_duration = rank_tmd_duration.FindIndex(i => i==x.tmd.duration.value);
  466. if (index_tmd_duration!=-1)
  467. {
  468. x.tmd.duration.rank = index_tmd_duration + 1;
  469. }
  470. int index_hita_duration = rank_hita_duration.FindIndex(i => i==x.hita.duration.value);
  471. if (index_hita_duration!=-1)
  472. {
  473. x.hita.duration.rank = index_hita_duration + 1;
  474. }
  475. int index_hiteach_duration = rank_hiteach_duration.FindIndex(i => i==x.hiteach.duration.value);
  476. if (index_hiteach_duration!=-1)
  477. {
  478. x.hiteach.duration.rank = index_hiteach_duration + 1;
  479. }
  480. int index_ies5Tch_duration = rank_ies5Tch_duration.FindIndex(i => i==x.ies5Tch.duration.value);
  481. if (index_ies5Tch_duration!=-1)
  482. {
  483. x.ies5Tch.duration.rank = index_ies5Tch_duration + 1;
  484. }
  485. int index_otherTch_duration = rank_otherTch_duration.FindIndex(i => i==x.otherTch.duration.value);
  486. if (index_otherTch_duration!=-1)
  487. {
  488. x.otherTch.duration.rank = index_otherTch_duration + 1;
  489. }
  490. #endregion
  491. #region
  492. int index_tmd_stick = rank_tmd_stick.FindIndex(i => i==x.tmd.stick.value);
  493. if (index_tmd_stick!=-1)
  494. {
  495. x.tmd.stick.rank = index_tmd_stick + 1;
  496. }
  497. int index_hita_stick = rank_hita_stick.FindIndex(i => i==x.hita.stick.value);
  498. if (index_hita_stick!=-1)
  499. {
  500. x.hita.stick.rank = index_hita_stick + 1;
  501. }
  502. int index_hiteach_stick = rank_hiteach_stick.FindIndex(i => i==x.hiteach.stick.value);
  503. if (index_hiteach_stick!=-1)
  504. {
  505. x.hiteach.stick.rank = index_hiteach_stick + 1;
  506. }
  507. int index_ies5Tch_stick = rank_ies5Tch_stick.FindIndex(i => i==x.ies5Tch.stick.value);
  508. if (index_ies5Tch_stick!=-1)
  509. {
  510. x.ies5Tch.stick.rank = index_ies5Tch_stick + 1;
  511. }
  512. int index_otherTch_stick = rank_otherTch_stick.FindIndex(i => i==x.otherTch.stick.value);
  513. if (index_otherTch_stick!=-1)
  514. {
  515. x.otherTch.stick.rank = index_otherTch_stick + 1;
  516. }
  517. #endregion
  518. });
  519. return tchStickiness;
  520. }
  521. private static List<SchoolStick> OrderBySchoolStick(List<SchoolStick> schoolStickiness)
  522. {
  523. // 假设visit已经填充了数据
  524. #region
  525. var rank_tmd_count = schoolStickiness.Select(x => x.tmd.count.value).Distinct().OrderByDescending(v => v).ToList();
  526. var rank_hita_count = schoolStickiness.Select(x => x.hita.count.value).Distinct().OrderByDescending(v => v).ToList();
  527. var rank_hiteach_count = schoolStickiness.Select(x => x.hiteach.count.value).Distinct().OrderByDescending(v => v).ToList();
  528. var rank_ies5Tch_count = schoolStickiness.Select(x => x.ies5Tch.count.value).Distinct().OrderByDescending(v => v).ToList();
  529. var rank_otherTch_count = schoolStickiness.Select(x => x.otherTch.count.value).Distinct().OrderByDescending(v => v).ToList();
  530. var rank_ies5Stu_count = schoolStickiness.Select(x => x.ies5Stu.count.value).Distinct().OrderByDescending(v => v).ToList();
  531. var rank_otherStu_count = schoolStickiness.Select(x => x.otherStu.count.value).Distinct().OrderByDescending(v => v).ToList();
  532. var rank_lesson_count = schoolStickiness.Select(x => x.lesson.value).Distinct().OrderByDescending(v => v).ToList();
  533. #endregion
  534. #region
  535. var rank_tmd_duration = schoolStickiness.Select(x => x.tmd.duration.value).Distinct().OrderByDescending(v => v).ToList();
  536. var rank_hita_duration = schoolStickiness.Select(x => x.hita.duration.value).Distinct().OrderByDescending(v => v).ToList();
  537. var rank_hiteach_duration = schoolStickiness.Select(x => x.hiteach.duration.value).Distinct().OrderByDescending(v => v).ToList();
  538. var rank_ies5Tch_duration = schoolStickiness.Select(x => x.ies5Tch.duration.value).Distinct().OrderByDescending(v => v).ToList();
  539. var rank_otherTch_duration = schoolStickiness.Select(x => x.otherTch.duration.value).Distinct().OrderByDescending(v => v).ToList();
  540. var rank_ies5Stu_duration = schoolStickiness.Select(x => x.ies5Stu.duration.value).Distinct().OrderByDescending(v => v).ToList();
  541. var rank_otherStu_duration = schoolStickiness.Select(x => x.otherStu.duration.value).Distinct().OrderByDescending(v => v).ToList();
  542. #endregion
  543. #region
  544. var rank_tmd_stick = schoolStickiness.Select(x => x.tmd.stick.value).Distinct().OrderByDescending(v => v).ToList();
  545. var rank_hita_stick = schoolStickiness.Select(x => x.hita.stick.value).Distinct().OrderByDescending(v => v).ToList();
  546. var rank_hiteach_stick = schoolStickiness.Select(x => x.hiteach.stick.value).Distinct().OrderByDescending(v => v).ToList();
  547. var rank_ies5Tch_stick = schoolStickiness.Select(x => x.ies5Tch.stick.value).Distinct().OrderByDescending(v => v).ToList();
  548. var rank_otherTch_stick = schoolStickiness.Select(x => x.otherTch.stick.value).Distinct().OrderByDescending(v => v).ToList();
  549. var rank_ies5Stu_stick = schoolStickiness.Select(x => x.ies5Stu.stick.value).Distinct().OrderByDescending(v => v).ToList();
  550. var rank_otherStu_stick = schoolStickiness.Select(x => x.otherStu.stick.value).Distinct().OrderByDescending(v => v).ToList();
  551. #endregion
  552. schoolStickiness.ForEach(x => {
  553. #region
  554. if (x.tmd.count.value>0)
  555. {
  556. int index_tmd_count = rank_tmd_count.FindIndex(i => i==x.tmd.count.value);
  557. if (index_tmd_count!=-1)
  558. {
  559. x.tmd.count.rank = index_tmd_count + 1;
  560. }
  561. }
  562. if (x.hita.count.value>0)
  563. {
  564. int index_hita_count = rank_hita_count.FindIndex(i => i==x.hita.count.value);
  565. if (index_hita_count!=-1)
  566. {
  567. x.hita.count.rank = index_hita_count + 1;
  568. }
  569. }
  570. if (x.hiteach.count.value>0)
  571. {
  572. int index_hiteach_count = rank_hiteach_count.FindIndex(i => i==x.hiteach.count.value);
  573. if (index_hiteach_count!=-1)
  574. {
  575. x.hiteach.count.rank = index_hiteach_count + 1;
  576. }
  577. }
  578. if (x.ies5Tch.count.value>0)
  579. {
  580. int index_ies5Tch_count = rank_ies5Tch_count.FindIndex(i => i==x.ies5Tch.count.value);
  581. if (index_ies5Tch_count!=-1)
  582. {
  583. x.ies5Tch.count.rank = index_ies5Tch_count + 1;
  584. }
  585. }
  586. if (x.otherTch.count.value>0)
  587. {
  588. int index_otherTch_count = rank_otherTch_count.FindIndex(i => i==x.otherTch.count.value);
  589. if (index_otherTch_count!=-1)
  590. {
  591. x.otherTch.count.rank = index_otherTch_count + 1;
  592. }
  593. }
  594. if (x.ies5Stu.count.value>0)
  595. {
  596. int index_ies5Stu_count = rank_ies5Stu_count.FindIndex(i => i==x.ies5Stu.count.value);
  597. if (index_ies5Stu_count!=-1)
  598. {
  599. x.ies5Stu.count.rank = index_ies5Stu_count + 1;
  600. }
  601. }
  602. if (x.otherStu.count.value>0)
  603. {
  604. int index_otherStu_count = rank_otherStu_count.FindIndex(i => i==x.otherStu.count.value);
  605. if (index_otherStu_count!=-1)
  606. {
  607. x.otherStu.count.rank = index_otherStu_count + 1;
  608. }
  609. }
  610. if (x.lesson.value>0)
  611. {
  612. int index_lesson_count = rank_lesson_count.FindIndex(i => i==x.lesson.value);
  613. if (index_lesson_count!=-1)
  614. {
  615. x.lesson.rank = index_lesson_count + 1;
  616. }
  617. }
  618. #endregion
  619. #region
  620. if (x.tmd.duration.value>0)
  621. {
  622. int index_tmd_duration = rank_tmd_duration.FindIndex(i => i==x.tmd.duration.value);
  623. if (index_tmd_duration!=-1)
  624. {
  625. x.tmd.duration.rank = index_tmd_duration + 1;
  626. }
  627. }
  628. if (x.hita.duration.value>0)
  629. {
  630. int index_hita_duration = rank_hita_duration.FindIndex(i => i==x.hita.duration.value);
  631. if (index_hita_duration!=-1)
  632. {
  633. x.hita.duration.rank = index_hita_duration + 1;
  634. }
  635. }
  636. if (x.hiteach.duration.value>0)
  637. {
  638. int index_hiteach_duration = rank_hiteach_duration.FindIndex(i => i==x.hiteach.duration.value);
  639. if (index_hiteach_duration!=-1)
  640. {
  641. x.hiteach.duration.rank = index_hiteach_duration + 1;
  642. }
  643. }
  644. if (x.ies5Tch.duration.value>0) {
  645. int index_ies5Tch_duration = rank_ies5Tch_duration.FindIndex(i => i==x.ies5Tch.duration.value);
  646. if (index_ies5Tch_duration!=-1)
  647. {
  648. x.ies5Tch.duration.rank = index_ies5Tch_duration + 1;
  649. }
  650. }
  651. if (x.otherTch.duration.value>0)
  652. {
  653. int index_otherTch_duration = rank_otherTch_duration.FindIndex(i => i==x.otherTch.duration.value);
  654. if (index_otherTch_duration!=-1)
  655. {
  656. x.otherTch.duration.rank = index_otherTch_duration + 1;
  657. }
  658. }
  659. if (x.ies5Stu.duration.value>0)
  660. {
  661. int index_ies5Stu_duration = rank_ies5Stu_duration.FindIndex(i => i==x.ies5Stu.duration.value);
  662. if (index_ies5Stu_duration!=-1)
  663. {
  664. x.ies5Stu.duration.rank = index_ies5Stu_duration + 1;
  665. }
  666. }
  667. if (x.otherStu.duration.value>0)
  668. {
  669. int index_otherStu_duration = rank_otherStu_duration.FindIndex(i => i==x.otherStu.duration.value);
  670. if (index_otherStu_duration!=-1)
  671. {
  672. x.otherStu.duration.rank = index_otherStu_duration + 1;
  673. }
  674. }
  675. #endregion
  676. #region
  677. if (x.tmd.stick.value>0)
  678. {
  679. int index_tmd_stick = rank_tmd_stick.FindIndex(i => i==x.tmd.stick.value);
  680. if (index_tmd_stick!=-1)
  681. {
  682. x.tmd.stick.rank = index_tmd_stick + 1;
  683. }
  684. }
  685. if (x.hita.stick.value>0)
  686. {
  687. int index_hita_stick = rank_hita_stick.FindIndex(i => i==x.hita.stick.value);
  688. if (index_hita_stick!=-1)
  689. {
  690. x.hita.stick.rank = index_hita_stick + 1;
  691. }
  692. }
  693. if (x.hiteach.stick.value>0)
  694. {
  695. int index_hiteach_stick = rank_hiteach_stick.FindIndex(i => i==x.hiteach.stick.value);
  696. if (index_hiteach_stick!=-1)
  697. {
  698. x.hiteach.stick.rank = index_hiteach_stick + 1;
  699. }
  700. }
  701. if (x.ies5Tch.stick.value>0)
  702. {
  703. int index_ies5Tch_stick = rank_ies5Tch_stick.FindIndex(i => i==x.ies5Tch.stick.value);
  704. if (index_ies5Tch_stick!=-1)
  705. {
  706. x.ies5Tch.stick.rank = index_ies5Tch_stick + 1;
  707. }
  708. }
  709. if (x.otherTch.stick.value>0)
  710. {
  711. int index_otherTch_stick = rank_otherTch_stick.FindIndex(i => i==x.otherTch.stick.value);
  712. if (index_otherTch_stick!=-1)
  713. {
  714. x.otherTch.stick.rank = index_otherTch_stick + 1;
  715. }
  716. }
  717. if (x.ies5Stu.stick.value>0)
  718. {
  719. int index_ies5Stu_stick = rank_ies5Stu_stick.FindIndex(i => i==x.ies5Stu.stick.value);
  720. if (index_ies5Stu_stick!=-1)
  721. {
  722. x.ies5Stu.stick.rank = index_ies5Stu_stick + 1;
  723. }
  724. }
  725. if (x.otherStu.stick.value>0)
  726. {
  727. int index_otherStu_stick = rank_otherStu_stick.FindIndex(i => i==x.otherStu.stick.value);
  728. if (index_otherStu_stick!=-1)
  729. {
  730. x.otherStu.stick.rank = index_otherStu_stick + 1;
  731. }
  732. }
  733. #endregion
  734. });
  735. return schoolStickiness;
  736. }
  737. /// <summary>
  738. /// 结算访问日志
  739. /// </summary>
  740. public static async Task<(List<SchoolStick> chinaSchoolStickiness, List<SchoolStick> globalSchoolStickiness)> VisitSettle(List<string> times ,AzureStorageFactory _azureStorage,AzureRedisFactory _azureRedis, Region2LongitudeLatitudeTranslator _longitudeLatitudeTranslator, IPSearcher _ipSearcher) {
  741. List<SchoolStick> chinaSchoolStickiness = new List<SchoolStick>();
  742. List<SchoolStick> globalSchoolStickiness = new List<SchoolStick>();
  743. foreach (var timeDate in times)
  744. {
  745. List<ApiVisit> apiVisits = new List<ApiVisit>();
  746. if (DateTimeOffset.TryParse(timeDate, out DateTimeOffset date))
  747. {
  748. BlobDownloadResult result = await _azureStorage.GetBlobContainerClient("0-service-log").GetBlobClient($"http-log/{date:yyyy}/{date:MM}/{date:dd}/index.log").DownloadContentAsync();
  749. var content = result.Content.ToString();
  750. content= content.Substring(0, content.Length-2);
  751. if (content.EndsWith("}"))
  752. {
  753. content=$"[{content}]";
  754. }
  755. else
  756. {
  757. content=$"[{content}}}]";
  758. }
  759. apiVisits.AddRange(content.ToObject<List<ApiVisit>>());
  760. var dateNow = DateTimeOffset.Now.GetGMTTime(8);
  761. if ($"{dateNow:yyyy-MM-dd}".Equals($"{date:yyyy-MM-dd}"))
  762. { //当前小时一致的
  763. BlobDownloadResult resultHour = await _azureStorage.GetBlobContainerClient("0-service-log").GetBlobClient($"http-log/{date:yyyy}/{date:MM}/{date:dd}/{date:HH}.log").DownloadContentAsync();
  764. var contentHour = resultHour.Content.ToString();
  765. contentHour= contentHour.Substring(0, contentHour.Length-2);
  766. if (contentHour.EndsWith("}"))
  767. {
  768. contentHour=$"[{contentHour}]";
  769. }
  770. else
  771. {
  772. contentHour=$"[{contentHour}}}]";
  773. }
  774. var httpLog = contentHour.ToObject<List<HttpLog>>();
  775. (ConcurrentBag<ApiVisit> visits, ConcurrentBag<(string uuid, HttpLog httpLog, List<string> tmdid, List<string> school)> uuidInfo) = await SystemService.ConvertHttpLog(httpLog, _azureRedis, _ipSearcher, _longitudeLatitudeTranslator, dateNow, false);
  776. apiVisits.AddRange(visits);
  777. }
  778. }
  779. //大陆学校
  780. var chinaApiVisits = apiVisits.Where(x => x.hostName.Equals("大陆站"));
  781. var chinaSchoolVisits = apiVisits.Where(x => !string.IsNullOrWhiteSpace(x.school) && x.hostName.Equals("大陆站")).GroupBy(x => x.school);
  782. List<SchoolStick> chinaStickiness = CountSchoolStickiness(chinaSchoolVisits, chinaApiVisits);
  783. chinaSchoolStickiness.AddRange(chinaStickiness);
  784. //国际学校
  785. var globalApiVisits = apiVisits.Where(x => x.hostName.Equals("国际站"));
  786. var globalSchoolVisits = apiVisits.Where(x => !string.IsNullOrWhiteSpace(x.school) && x.hostName.Equals("国际站")).GroupBy(x => x.school);
  787. List<SchoolStick> globalStickiness = CountSchoolStickiness(globalSchoolVisits, globalApiVisits);
  788. globalSchoolStickiness.AddRange(globalStickiness);
  789. }
  790. return (chinaSchoolStickiness, globalSchoolStickiness);
  791. }
  792. public static async Task<(ConcurrentBag<ApiVisit> visits, ConcurrentBag<(string uuid, HttpLog httpLog, List<string> tmdid, List<string> school)> uuidInfo)>
  793. ConvertHttpLog(List<HttpLog> logs, AzureRedisFactory _azureRedis, IPSearcher _ipSearcher, Region2LongitudeLatitudeTranslator _longitudeLatitudeTranslator, DateTimeOffset gmt8Time, bool test = false)
  794. {
  795. ConcurrentBag<ApiVisit> visits = new ConcurrentBag<ApiVisit>();
  796. ConcurrentBag<(string uuid, HttpLog httpLog, List<string> tmdid, List<string> school)> uuidInfo = new ConcurrentBag<(string uuid, HttpLog httpLog, List<string> tmdid, List<string> school)>();
  797. object lockObj = new object();
  798. await Parallel.ForEachAsync(logs, async (log, _) =>
  799. {
  800. if (!log.path.Contains("."))
  801. {
  802. string uuid = Guid.NewGuid().ToString();
  803. List<string> schoolMatch = new List<string>();
  804. List<string> useridMatch = new List<string>();
  805. var vist = new ApiVisit()
  806. {
  807. id=uuid,
  808. ip=log.ip,
  809. tid=log.tid,
  810. time= log.time,
  811. userId= log.id,
  812. school= log.school,
  813. tname= log.name,
  814. path = log.path,
  815. client=log.p.Equals("os", StringComparison.OrdinalIgnoreCase) ? "ies5" : log.p,
  816. scope=log.scope,
  817. host= log.host,
  818. hostName=log.hostName,
  819. l=log.l,
  820. year = $"{gmt8Time:yyyy}",
  821. month = $"{gmt8Time:MM}",
  822. day = $"{gmt8Time:dd}",
  823. hour =$"{gmt8Time:HH}"
  824. };
  825. if (test)
  826. {
  827. var time = DateTimeOffset.FromUnixTimeMilliseconds(log.time);
  828. //本地调试时间
  829. if (vist.ip.Equals("0.0.0.1"))
  830. {
  831. time= time.AddHours(8);
  832. }
  833. vist.year = $"{time:yyyy}";
  834. vist.month = $"{time:MM}";
  835. vist.day = $"{time:dd}";
  836. vist.hour =$"{time:HH}";
  837. }
  838. if (string.IsNullOrWhiteSpace(vist.userId))
  839. {
  840. //var jsonPathContext = new JsonPathContext();
  841. //jsonPathContext.ValueSystem= new JsonTextValueSystem();
  842. string path = "$..['id_token','idToken','idtoken','tmdid','id','teacherId','teacher','tid','tId','userid','userId','code','studentId','student','studentid']";
  843. if (!log.param.ValueKind.Equals(JsonValueKind.Null)) {
  844. JObject jsonObject = JObject.Parse(log.param.GetRawText());
  845. //var nodes_path = jsonPathContext.SelectNodes(log.param, path);
  846. var nodes_path = jsonObject.SelectTokens(path);
  847. foreach (var node in nodes_path)
  848. {
  849. // 只获取是字符串的
  850. if (node.Type.Equals(JTokenType.String))
  851. {
  852. switch (true)
  853. {
  854. case bool when node.Path.Contains("id_token")||node.Path.Contains("idToken")||node.Path.Contains("idtoken"):
  855. {
  856. try
  857. {
  858. var jwt = new JwtSecurityToken($"{node}");
  859. string id = jwt.Payload.Sub;
  860. var name = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("name"))?.Value;
  861. if (!string.IsNullOrWhiteSpace(id) && long.TryParse(id, out long _id))
  862. {
  863. vist.userId=id;
  864. vist.scope="teacher";
  865. vist.tname=name;
  866. useridMatch.Add(id);
  867. }
  868. }
  869. catch (Exception ex) { }
  870. break;
  871. }
  872. case bool when node.Path.Contains("tmdid")||node.Path.Contains("id")||node.Path.Contains("teacherId")
  873. ||node.Path.Contains("teacher")||node.Path.Contains("tid")||node.Path.Contains("tId")||node.Path.Contains("userid")
  874. ||node.Path.Contains("userId"):
  875. {
  876. if (!string.IsNullOrWhiteSpace($"{node}") && long.TryParse($"{node}", out long _id))
  877. {
  878. vist.userId=$"{node}";
  879. vist.scope="teacher";
  880. useridMatch.Add($"{node}");
  881. }
  882. break;
  883. }
  884. case bool when node.Path.Contains("studentId")||node.Path.Contains("student")||node.Path.Contains("studentid"):
  885. {
  886. if (!string.IsNullOrWhiteSpace($"{node}") && long.TryParse($"{node}", out long _id))
  887. {
  888. vist.userId=$"{node}";
  889. vist.scope="student";
  890. useridMatch.Add($"{node}");
  891. }
  892. break;
  893. }
  894. case bool when node.Path.Contains("code"):
  895. {
  896. if (!string.IsNullOrWhiteSpace($"{node}"))
  897. {
  898. if (long.TryParse($"{node}", out long _id))
  899. {
  900. vist.userId=$"{node}";
  901. useridMatch.Add($"{node}");
  902. }
  903. else
  904. {
  905. string[] codes = $"{node}".Split("-");
  906. foreach (var _code in codes)
  907. {
  908. if (long.TryParse(_code, out long _codeid))
  909. {
  910. vist.userId=$"{node}";
  911. useridMatch.Add($"{_code}");
  912. break;
  913. }
  914. }
  915. }
  916. }
  917. break;
  918. }
  919. }
  920. }
  921. }
  922. if (log.path.Contains("process-notify", StringComparison.OrdinalIgnoreCase))
  923. {
  924. string s = log.param.ToJsonString().Replace("\\", "");
  925. Regex regextmdid = new Regex("\"tmdid\":\"(\\d+)\"");
  926. Match matchtmdid = regextmdid.Match(s);
  927. if (matchtmdid.Success)
  928. {
  929. var t = matchtmdid.Groups[1].Value;
  930. if (!string.IsNullOrWhiteSpace(t))
  931. {
  932. vist.userId=t;
  933. vist.scope="teacher";
  934. useridMatch.Add(t);
  935. }
  936. }
  937. Regex regexname = new Regex("\"tmdname\":\"(.+?)\"");
  938. Match matchname = regexname.Match(s);
  939. if (matchname.Success)
  940. {
  941. var t = matchname.Groups[1].Value;
  942. if (!string.IsNullOrWhiteSpace(t))
  943. {
  944. vist.tname=t;
  945. }
  946. }
  947. }
  948. }
  949. }
  950. else
  951. {
  952. if (string.IsNullOrWhiteSpace($"{vist.scope}"))
  953. {
  954. vist.scope="teacher";
  955. uuidInfo.Add((uuid, log, new List<string>() { vist.userId }, new List<string>()));
  956. }
  957. }
  958. if (string.IsNullOrWhiteSpace(vist.school) || vist.school.Equals("true") || vist.school.Equals("false"))
  959. {
  960. vist.school="";
  961. string path = "$..['school','id','schoolId','schoolid','schoolCode','school_code','schoolcode','code']";
  962. if (!log.param.ValueKind.Equals(JsonValueKind.Null)) {
  963. JObject jsonObject = JObject.Parse(log.param.GetRawText());
  964. var nodes_path = jsonObject.SelectTokens(path);
  965. foreach (var node in nodes_path)
  966. {
  967. // 只获取是字符串的
  968. if (node.Type.Equals(JTokenType.String))
  969. {
  970. switch (true)
  971. {
  972. case bool when node.Path.Contains("school")||node.Path.Contains("id")||node.Path.Contains("schoolId")
  973. ||node.Path.Contains("schoolid")||node.Path.Contains("schoolCode")||node.Path.Contains("school_code")||node.Path.Contains("schoolcode"):
  974. {
  975. if (!$"{node}".Contains("-")&& $"{node}".Length<=8 && $"{node}".Length>=1)
  976. {
  977. vist.school=$"{node}";
  978. schoolMatch.Add($"{node}");
  979. }
  980. break;
  981. }
  982. case bool when node.Path.Contains("code"):
  983. {
  984. if (!$"{node}".Contains("-")&& $"{node}".Length<=8&& $"{node}".Length>=1)
  985. {
  986. vist.school=$"{node}";
  987. schoolMatch.Add($"{node}");
  988. }
  989. else
  990. {
  991. string[] codes = $"{node}".Split("-");
  992. foreach (var _code in codes)
  993. {
  994. if ($"{_code}".Length<=8 && $"{_code}".Length>=1)
  995. {
  996. vist.school=$"{_code}";
  997. schoolMatch.Add($"{_code}");
  998. break;
  999. }
  1000. }
  1001. }
  1002. break;
  1003. }
  1004. }
  1005. }
  1006. }
  1007. if (log.path.Contains("process-notify", StringComparison.OrdinalIgnoreCase))
  1008. {
  1009. string s = log.param.ToJsonString().Replace("\\", "");
  1010. Regex regexname = new Regex("\"schoolId\":\"(.+?)\"");
  1011. Match matchname = regexname.Match(s);
  1012. if (matchname.Success)
  1013. {
  1014. var t = matchname.Groups[1].Value;
  1015. if (!string.IsNullOrWhiteSpace(t))
  1016. {
  1017. vist.school=t;
  1018. }
  1019. }
  1020. }
  1021. }
  1022. }
  1023. //处理 client
  1024. {
  1025. if (!string.IsNullOrWhiteSpace(log.client))
  1026. {
  1027. if (log.client.Equals("IES", StringComparison.OrdinalIgnoreCase))
  1028. {
  1029. vist.client="ies5";
  1030. }
  1031. if (log.client.Equals("AClassONE", StringComparison.OrdinalIgnoreCase))
  1032. {
  1033. vist.client="aclassone";
  1034. }
  1035. if (log.client.Equals("BB", StringComparison.OrdinalIgnoreCase))
  1036. {
  1037. vist.client="habb";
  1038. }
  1039. if (log.client.Equals("HiTool", StringComparison.OrdinalIgnoreCase) ||log.client.Equals("HiTools", StringComparison.OrdinalIgnoreCase))
  1040. {
  1041. vist.client="hiscan";
  1042. }
  1043. if (log.client.Equals("HiTA", StringComparison.OrdinalIgnoreCase))
  1044. {
  1045. vist.client="hita";
  1046. vist.scope="teacher";
  1047. }
  1048. if (log.client.Equals("HiTeachCC", StringComparison.OrdinalIgnoreCase))
  1049. {
  1050. vist.client="hiteachcc";
  1051. }
  1052. if (log.client.Equals("HiTeach", StringComparison.OrdinalIgnoreCase))
  1053. {
  1054. vist.scope="teacher";
  1055. vist.client="hiteach";
  1056. }
  1057. if (log.client.Equals("Open", StringComparison.OrdinalIgnoreCase))
  1058. {
  1059. vist.client="open";
  1060. }
  1061. }
  1062. }
  1063. //补全站点
  1064. {
  1065. if (
  1066. (log.host.Equals("wwww.teammodel.net")||log.host.Equals("ies5-rc.teammodel.net")))
  1067. {
  1068. vist.hostName="国际站";
  1069. vist.host="www.teammodel.net";
  1070. vist.client="ies5";
  1071. vist.l="Global";
  1072. }
  1073. else if (
  1074. log.host.Equals("teammodelos-yx.chinacloudsites.cn")||log.host.Equals("teammodelos.chinacloudsites.cn")
  1075. ||log.host.Equals("yx.teammodel.cn")||log.host.Equals("teammodelos-rc.chinacloudsites.cn")||log.host.Equals("rc.teammodel.cn")|| log.host.Equals("www.teammodel.cn"))
  1076. {
  1077. vist.hostName="大陆站";
  1078. vist.host="www.teammodel.cn";
  1079. vist.client="ies5"; vist.l="China";
  1080. }
  1081. else if ((log.host.Contains("localhost") && log.p.Equals("os"))|| log.host.Equals("teammodelos-test.chinacloudsites.cn") ||log.host.Equals("test.teammodel.cn"))
  1082. {
  1083. vist.hostName="测试站";
  1084. vist.host="test.teammodel.cn";
  1085. vist.client="ies5";
  1086. vist.l="China";
  1087. }
  1088. else if (
  1089. (log.host.Equals("scyx.teammodel.cn") ||log.host.Equals("jinniu.teammodel.cn")))
  1090. {
  1091. vist.hostName="研修2.0";
  1092. vist.host="scyx.teammodel.cn";
  1093. vist.client="ability"; vist.l="China";
  1094. }
  1095. else if (
  1096. log.host.Equals("open.teammodel.cn")||log.host.Equals("open-test.teammodel.cn") ||log.host.Equals("zhiyin-test.teammodel.cn"))
  1097. {
  1098. vist.hostName="开放平台";
  1099. vist.host="open.teammodel.cn";
  1100. vist.client="open";
  1101. vist.l="China";
  1102. }
  1103. else if ((log.host.Equals("bi-rc.teammodel.net") || log.host.Equals("bi.teammodel.net")))
  1104. {
  1105. vist.hostName="国际站";
  1106. vist.host="bi.teammodel.net";
  1107. vist.client="bi";
  1108. vist.scope="admin";
  1109. vist.l="Global";
  1110. }
  1111. else if (log.host.Equals("teammodelbi.chinacloudsites.cn") ||log.host.Equals("bi.teammodel.cn"))
  1112. {
  1113. vist.hostName="大陆站";
  1114. vist.host="bi.teammodel.cn";
  1115. vist.client="bi";
  1116. vist.scope="admin";
  1117. vist.l="China";
  1118. }
  1119. else if (log.host.Equals("bitest.teammodel.cn")||log.host.Equals("teammodelbi-test.chinacloudsites.cn")||(log.host.Contains("localhost") && (log.p.Equals("bi"))))
  1120. {
  1121. vist.hostName="测试站";
  1122. vist.host="testbi.teammodel.cn";
  1123. vist.client="bi";
  1124. vist.scope="admin";
  1125. vist.l="China";
  1126. }
  1127. else if (
  1128. log.host.Equals("teamcontest.chinacloudsites.cn")||log.host.Equals("contest.chinacloudsites.cn")||log.host.Equals("contest-test.chinacloudsites.cn"))
  1129. {
  1130. vist.hostName="大陆站";
  1131. vist.host="contest.teammodel.cn";
  1132. vist.client="contest"; vist.l="China";
  1133. }
  1134. else if (
  1135. log.host.Equals("hiteachcc.chinacloudsites.cn"))
  1136. {
  1137. vist.hostName="正式站";
  1138. vist.host="hiteachcc.teammodel.cn";
  1139. vist.client="hiteachcc";
  1140. vist.l="China";
  1141. }
  1142. else if (log.host.Equals("appraisal.chinacloudsites.cn"))
  1143. {
  1144. vist.hostName="大陆站";
  1145. vist.host="appraisal.teammodel.cn";
  1146. vist.client="appraisal";
  1147. vist.l="China";
  1148. }
  1149. else if ((log.host.Contains("localhost") && log.p.Equals("appraisal"))||log.host.Equals("appraisal-test.teammodel.cn") ||log.host.Equals("appraisal-test.chinacloudsites.cn"))
  1150. {
  1151. vist.hostName="测试站";
  1152. vist.host="appraisal-test.teammodel.cn";
  1153. vist.client="appraisal";
  1154. vist.l="China";
  1155. }
  1156. else
  1157. {
  1158. if (!string.IsNullOrWhiteSpace(log.p))
  1159. {
  1160. vist.client=log.p.Equals("os", StringComparison.OrdinalIgnoreCase) ? "ies5" : log.p;
  1161. }
  1162. else
  1163. {
  1164. vist.client="other";
  1165. }
  1166. if (log.host.EndsWith(".cn"))
  1167. {
  1168. vist.hostName="大陆站";
  1169. vist.l="China";
  1170. }
  1171. else if (log.host.EndsWith(".net"))
  1172. {
  1173. vist.hostName="国际站";
  1174. vist.l="Global";
  1175. }
  1176. else
  1177. {
  1178. vist.hostName="其他";
  1179. vist.l="其他";
  1180. }
  1181. }
  1182. }
  1183. //补全产品端
  1184. {
  1185. //研修2.0
  1186. if (log.path.Contains("research") || log.path.Contains("study") || log.path.Contains("standard-file"))
  1187. {
  1188. vist.client="ability";
  1189. }
  1190. if (log.path.Contains("teacher"))
  1191. {
  1192. vist.scope="teacher";
  1193. }
  1194. if (log.path.Contains("tmduser"))
  1195. {
  1196. vist.scope=Constant.ScopeTmdUser;
  1197. }
  1198. if (log.path.Contains("student/login"))
  1199. {
  1200. vist.scope=Constant.ScopeStudent;
  1201. }
  1202. if (log.path.StartsWith("/activity"))
  1203. {
  1204. vist.client="contest";
  1205. }
  1206. //小程序
  1207. if (log.path.Contains("aclassone"))
  1208. {
  1209. vist.client="aclassone";
  1210. }
  1211. // /// <summary>
  1212. /// ExamInfo qamode 書面問答類型 0:書面問答 1:紙本測驗 2:艺术评测
  1213. /// </summary>
  1214. //艺术评测
  1215. if (log.path.Contains("art") ||log.path.Contains("aclassone/find-children-activity") ||log.path.Contains("aclassone/find-teacher-activity") ||log.path.Contains("aclassone/find-summary-activity") ||log.path.Contains("aclassone/upload-all") ||log.path.Contains("aclassone/delete"))
  1216. {
  1217. vist.client="art";
  1218. }
  1219. if (log.path.Contains("common/exam/upsert-record"))
  1220. {
  1221. JObject jobject = JObject.Parse(log.param.GetRawText());
  1222. var jtokens = jobject.SelectTokens("$..artId");
  1223. if (jtokens!=null && jtokens.Count()>0)
  1224. {
  1225. vist.client="art";
  1226. vist.scope=Constant.ScopeStudent;
  1227. }
  1228. }
  1229. if (log.path.Contains("habb"))
  1230. {
  1231. vist.client="habb";
  1232. }
  1233. //阅卷客户端
  1234. if (log.path.Contains("hiscan"))
  1235. {
  1236. vist.client="hiscan";
  1237. }
  1238. if (log.path.Contains("hita"))
  1239. {
  1240. vist.client="hita";
  1241. }
  1242. if (log.path.Contains("hiteachcc"))
  1243. {
  1244. vist.client="hiteachcc";
  1245. }
  1246. if (log.path.Contains("sokrate"))
  1247. {
  1248. vist.client="sokrate";
  1249. }
  1250. if (log.path.Contains("sokrate") || log.path.Contains("score"))
  1251. {
  1252. vist.client="sokrate";
  1253. }
  1254. if (log.path.Contains("hiteach"))
  1255. {
  1256. vist.client="hiteach";
  1257. }
  1258. ///IES开放平台
  1259. if (log.path.Contains("business") || log.path.Contains("biz") || log.path.Contains("openapi-config") || log.path.Contains("open-api"))
  1260. {
  1261. vist.client="open";
  1262. }
  1263. //从token的role 能否获取 开放平台
  1264. //单点登录及第三方接口
  1265. if (log.path.Contains("lepei") || log.path.Contains("sc/") || log.path.Contains("/sso") || log.path.Contains("sc-init")|| log.path.Contains("moofen") || log.path.Contains("data-push") || log.path.Contains("xkw")|| log.path.Contains("tianbo")
  1266. || log.path.Contains("oauth/check-bind")|| log.path.Contains("dingding") || log.path.Contains("wechat")
  1267. )
  1268. {
  1269. vist.client="sso-third";
  1270. }
  1271. }
  1272. //处理IP转地区
  1273. var region = await _ipSearcher.SearchIpAsync(vist.ip);
  1274. if (string.IsNullOrWhiteSpace(region))
  1275. {
  1276. region="未知IP·未知IP·未知IP";
  1277. }
  1278. if (!string.IsNullOrWhiteSpace(region))
  1279. {
  1280. region= region.Replace("省·", "·").Replace("市·", "·").Replace("特别行政区·", "·").Replace("藏族羌族自治州·", "·");
  1281. var regions = region.Split("·");
  1282. if (regions.Length==4)
  1283. {
  1284. vist.area= regions[0];
  1285. vist.province = regions[1];
  1286. vist.city = regions[2];
  1287. }
  1288. if (regions.Length==3)
  1289. {
  1290. vist.area= regions[0];
  1291. vist.province = regions[1];
  1292. }
  1293. if (regions.Length==2)
  1294. {
  1295. vist.area= regions[0];
  1296. vist.province = regions[1];
  1297. }
  1298. if (regions.Length==1)
  1299. {
  1300. vist.area= regions[0];
  1301. }
  1302. }
  1303. //处理地区转经纬度
  1304. {
  1305. IEnumerable<JToken> tokens = default;
  1306. if (!string.IsNullOrWhiteSpace(vist.city) && !string.IsNullOrWhiteSpace(vist.province) && !string.IsNullOrWhiteSpace(vist.area))
  1307. {
  1308. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.province}/i && @.city=~ /.*{vist.city}/i)]");
  1309. if (!(tokens.Any() && tokens.Count()>0))
  1310. {
  1311. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.city}/i && @.city=~ /.*{vist.province}/i)]");
  1312. if (!(tokens.Any() && tokens.Count()>0))
  1313. {
  1314. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.city}/i || @.city=~ /.*{vist.city}/i)]");
  1315. }
  1316. if (!(tokens.Any() && tokens.Count()>0))
  1317. {
  1318. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.province}/i||@.city=~ /.*{vist.province}/i)]");
  1319. }
  1320. }
  1321. }
  1322. else if (string.IsNullOrWhiteSpace(vist.city) && !string.IsNullOrWhiteSpace(vist.province) && !string.IsNullOrWhiteSpace(vist.area))
  1323. {
  1324. if (vist.area.Equals("中国"))
  1325. {
  1326. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.province}/i)]");
  1327. if (!(tokens.Any() && tokens.Count()>0))
  1328. {
  1329. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.city=~ /.*{vist.province}/i)]");
  1330. }
  1331. }
  1332. else
  1333. {
  1334. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.city=~ /.*{vist.province}/i || @.province=~ /.*{vist.province}/i)]");
  1335. }
  1336. }
  1337. else if (!string.IsNullOrWhiteSpace(vist.city) && string.IsNullOrWhiteSpace(vist.province)&& !string.IsNullOrWhiteSpace(vist.area))
  1338. {
  1339. if (vist.area.Equals("中国"))
  1340. {
  1341. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.city}/i)]");
  1342. if (!(tokens.Any() && tokens.Count()>0))
  1343. {
  1344. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.city=~ /.*{vist.province}/i)]");
  1345. }
  1346. }
  1347. else
  1348. {
  1349. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.city=~ /.*{vist.city}/i || @.city=~ /.*{vist.province}/i)]");
  1350. }
  1351. }
  1352. else if (string.IsNullOrWhiteSpace(vist.city) && string.IsNullOrWhiteSpace(vist.province)&& !string.IsNullOrWhiteSpace(vist.area))
  1353. {
  1354. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.country=~ /.*{vist.area}/i && @.m=='1')]");
  1355. }
  1356. if (tokens!=null && tokens.Any())
  1357. {
  1358. List<RegionLngLat> regionLngLats = new List<RegionLngLat>();
  1359. foreach (JToken token in tokens)
  1360. {
  1361. regionLngLats.Add(token.ToString().ToObject<RegionLngLat>());
  1362. }
  1363. var points = regionLngLats.FindAll(x => string.IsNullOrWhiteSpace(x.area));
  1364. if (!points.IsNotEmpty())
  1365. {
  1366. points= regionLngLats.FindAll(x => !string.IsNullOrWhiteSpace(x.m) && x.m.Equals("1"));
  1367. }
  1368. if (string.IsNullOrWhiteSpace(vist.city))
  1369. {
  1370. vist.city=points?.FirstOrDefault()?.city;
  1371. if (!string.IsNullOrWhiteSpace(vist.city) && vist.city.EndsWith("市"))
  1372. {
  1373. vist.city=vist.city.Replace("市", "");
  1374. }
  1375. }
  1376. vist.lat=points?.FirstOrDefault()?.lat;
  1377. vist.lng=points?.FirstOrDefault()?.lng;
  1378. }
  1379. else
  1380. {
  1381. if (vist.area.Equals("内网IP"))
  1382. {
  1383. if (vist.host.Contains(".cn") || vist.host.Contains("localhost"))
  1384. {
  1385. vist.lat="30.655821878416408";
  1386. vist.lng="104.08153351042463";
  1387. vist.area="中国";
  1388. vist.province="四川";
  1389. vist.city="成都";
  1390. }
  1391. else
  1392. {
  1393. vist.lat="25.044332";
  1394. vist.lng="121.509062";
  1395. vist.area="中国";
  1396. vist.province="台湾";
  1397. vist.city="台湾";
  1398. }
  1399. }
  1400. else
  1401. {
  1402. vist.lat="30.655821878416408";
  1403. vist.lng="104.08153351042463";
  1404. vist.area="中国";
  1405. vist.province="四川";
  1406. vist.city="成都";
  1407. }
  1408. }
  1409. }
  1410. uuidInfo.Add((uuid, log, useridMatch, schoolMatch));
  1411. visits.Add(vist);
  1412. }
  1413. }
  1414. );
  1415. List<(string tmd, bool exists, string scope)> tmdexists = new List<(string tmd, bool exists, string scope)>();
  1416. List<(string sch, bool exists)> schexists = new List<(string sch, bool exists)>();
  1417. var tmds = uuidInfo.SelectMany(x => x.tmdid).ToHashSet();
  1418. if (tmds.Any())
  1419. {
  1420. foreach (var tmd in tmds)
  1421. {
  1422. var exists = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"Blob:Catalog:{tmd}");
  1423. if (exists)
  1424. {
  1425. tmdexists.Add((tmd, exists, "teacher"));
  1426. }
  1427. else
  1428. {
  1429. exists = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"Login:School:hbcn:student:{tmd}");
  1430. tmdexists.Add((tmd, exists, "student"));
  1431. }
  1432. }
  1433. }
  1434. var schs = uuidInfo.SelectMany(x => x.school).ToHashSet();
  1435. if (schs.Any())
  1436. {
  1437. foreach (var sch in schs)
  1438. {
  1439. var exists = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"Blob:Catalog:{sch}");
  1440. schexists.Add((sch, exists));
  1441. }
  1442. }
  1443. foreach (var item in uuidInfo)
  1444. {
  1445. foreach (var tmd in item.tmdid)
  1446. {
  1447. var tmdext = tmdexists.Find(x => x.tmd.Equals(tmd));
  1448. if (tmdext.tmd!= null && tmdext.exists)
  1449. {
  1450. var vist = visits.Where(x => x.id.Equals(item.uuid));
  1451. foreach (var vi in vist)
  1452. {
  1453. vi.userId=tmd;
  1454. if (string.IsNullOrWhiteSpace(vi.scope))
  1455. {
  1456. vi.scope=tmdext.scope;
  1457. }
  1458. }
  1459. break;
  1460. }
  1461. }
  1462. foreach (var sch in item.school)
  1463. {
  1464. var schext = schexists.Find(x => x.sch.Equals(sch));
  1465. if (schext.sch!= null && schext.exists)
  1466. {
  1467. var vist = visits.Where(x => x.id.Equals(item.uuid));
  1468. foreach (var vi in vist)
  1469. {
  1470. vi.school=sch;
  1471. }
  1472. break;
  1473. }
  1474. }
  1475. }
  1476. return (visits, uuidInfo);
  1477. }
  1478. public class ApiVisit
  1479. {
  1480. public string id { get; set; }
  1481. public string path { get; set; }
  1482. /// <summary>
  1483. /// 细分
  1484. /// ies5 ,hiteach,hita,cc,bi,contest,open,aclassone,sokrates,ability,art
  1485. /// 产品端
  1486. /// </summary>
  1487. public string client { get; set; }
  1488. /// <summary>
  1489. /// 具体功能
  1490. /// </summary>
  1491. // public string func { get; set; }
  1492. public string userId { get; set; }
  1493. public string scope { get; set; }
  1494. public string tname { get; set; }
  1495. public string school { get; set; }
  1496. public string ip { get; set; }
  1497. //public string region { get; set; }
  1498. public string area { get; set; }
  1499. public string province { get; set; }
  1500. public string city { get; set; } = "";
  1501. public long time { get; set; }
  1502. /// <summary>
  1503. ///
  1504. /// </summary>
  1505. public string host { get; set; }
  1506. public string hostName { get; set; } = "其他";
  1507. /// <summary>
  1508. /// tokenid
  1509. /// </summary>
  1510. public string tid { get; set; }
  1511. public string year { get; set; }
  1512. public string month { get; set; }
  1513. public string day { get; set; }
  1514. public string hour { get; set; }
  1515. //public RegionLngLat point { get; set; }
  1516. public string lat { get; set; }
  1517. public string lng { get; set; }
  1518. public string l { get; set; }
  1519. }
  1520. public class HttpLog
  1521. {
  1522. public string ip { get; set; }
  1523. public long time { get; set; }
  1524. public string host { get; set; }
  1525. public string hostName = "其他";
  1526. public string tid { get; set; }
  1527. public string path { get; set; }
  1528. public string client { get; set; }
  1529. public JsonElement param { get; set; }
  1530. public string id { get; set; }
  1531. public string name { get; set; }
  1532. public string school { get; set; }
  1533. public string p { get; set; }
  1534. // public string ua { get; set; }
  1535. // public string referer { get; set; }
  1536. public string scope { get; set; }
  1537. public string year { get; set; }
  1538. public string month { get; set; }
  1539. public string day { get; set; }
  1540. public string hour { get; set; }
  1541. public string l { get; set; }
  1542. }
  1543. public record RegionLngLat
  1544. {
  1545. public string country { get; set; }
  1546. public string province { get; set; }
  1547. public string city { get; set; }
  1548. public string lat { get; set; }
  1549. public string lng { get; set; }
  1550. public string area { get; set; }
  1551. public string m { get; set; } = "0";
  1552. }
  1553. public class CountData
  1554. {
  1555. public string pk { get; set; } = "";
  1556. public string sk { get; set; } = "";
  1557. public string sp { get; set; } = "";
  1558. public int count { get; set; }
  1559. }
  1560. public class SchoolStick
  1561. {
  1562. /// <summary>
  1563. /// 名字
  1564. /// </summary>
  1565. public string name { get; set; }
  1566. public string picture { get; set; }
  1567. /// <summary>
  1568. /// 编码
  1569. /// </summary>
  1570. public string id { get; set; }
  1571. public string last { get; set; }
  1572. #region tmd
  1573. public ClientStick tmd { get; set; } = new ClientStick();
  1574. #endregion
  1575. #region hiteach
  1576. public ClientStick hiteach { get; set; } = new ClientStick();
  1577. public Indicator lesson { get; set; } = new Indicator();
  1578. #endregion
  1579. #region hita
  1580. public ClientStick hita { get; set; } = new ClientStick();
  1581. #endregion
  1582. #region ies5Teacher
  1583. public ClientStick ies5Tch { get; set; } = new ClientStick();
  1584. #endregion
  1585. #region otherTeacher
  1586. public ClientStick otherTch { get; set; } = new ClientStick();
  1587. #endregion
  1588. #region ies5Student
  1589. public ClientStick ies5Stu { get; set; } = new ClientStick();
  1590. #endregion
  1591. #region otherStudent
  1592. public ClientStick otherStu { get; set; } = new ClientStick();
  1593. #endregion
  1594. public List<TchStick> tchSticks { get; set; } = new List<TchStick>();
  1595. public List<StuStick> stuSticks { get; set; } = new List<StuStick>();
  1596. }
  1597. public class TchStick {
  1598. public string school { get; set; }
  1599. /// <summary>
  1600. /// 名字
  1601. /// </summary>
  1602. public string name { get; set; }
  1603. public string picture { get; set; }
  1604. /// <summary>
  1605. /// 编码
  1606. /// </summary>
  1607. public string id { get; set; }
  1608. public string last { get; set; }
  1609. #region tmd
  1610. public ClientStick tmd { get; set; } = new ClientStick();
  1611. #endregion
  1612. #region hiteach
  1613. public ClientStick hiteach { get; set; } = new ClientStick();
  1614. public Indicator lesson { get; set; } = new Indicator();
  1615. #endregion
  1616. #region hita
  1617. public ClientStick hita { get; set; } = new ClientStick();
  1618. #endregion
  1619. #region ies5Teacher
  1620. public ClientStick ies5Tch { get; set; } = new ClientStick();
  1621. #endregion
  1622. #region otherTeacher
  1623. public ClientStick otherTch { get; set; } = new ClientStick();
  1624. #endregion
  1625. }
  1626. public class StuStick
  1627. {
  1628. public string school { get; set; }
  1629. /// <summary>
  1630. /// 名字
  1631. /// </summary>
  1632. public string name { get; set; }
  1633. public string picture { get; set; }
  1634. /// <summary>
  1635. /// 编码
  1636. /// </summary>
  1637. public string id { get; set; }
  1638. public string last { get; set; }
  1639. #region tmd
  1640. public ClientStick tmd { get; set; } = new ClientStick();
  1641. #endregion
  1642. #region ies5Student
  1643. public ClientStick ies5Stu { get; set; } = new ClientStick();
  1644. #endregion
  1645. #region otherStudent
  1646. public ClientStick otherStu { get; set; } = new ClientStick();
  1647. #endregion
  1648. }
  1649. public class ClientStick
  1650. {
  1651. public int userCount { get; set; }
  1652. public Indicator stick { get; set; } = new Indicator();
  1653. public Indicator duration { get; set; } = new Indicator();
  1654. public Indicator count { get; set; } = new Indicator();
  1655. }
  1656. public class Indicator
  1657. {
  1658. /// <summary>
  1659. /// 值
  1660. /// </summary>
  1661. public double value { get; set; } = 0;
  1662. /// <summary>
  1663. /// 值的增减浮动
  1664. /// </summary>
  1665. public double range { get; set; } = 0;
  1666. /// <summary>
  1667. /// 排名
  1668. /// </summary>
  1669. public double rank { get; set; } = 0;
  1670. /// <summary>
  1671. /// 排名的上升下降
  1672. /// </summary>
  1673. public double updown { get; set; } = 0;
  1674. }
  1675. }
  1676. }