SystemService.cs 251 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543
  1. using Azure.Storage.Blobs.Models;
  2. using Microsoft.Extensions.Configuration;
  3. using Newtonsoft.Json.Linq;
  4. using StackExchange.Redis;
  5. using System;
  6. using System.Collections.Concurrent;
  7. using System.Collections.Generic;
  8. using System.IdentityModel.Tokens.Jwt;
  9. using System.Linq;
  10. using System.Net.Http;
  11. using System.Net.Http.Json;
  12. using System.Text;
  13. using System.Text.Json;
  14. using System.Text.RegularExpressions;
  15. using System.Threading.Tasks;
  16. using TEAMModelOS.SDK.DI;
  17. using TEAMModelOS.SDK.Extension;
  18. using TEAMModelOS.SDK.Models.Dtos;
  19. using static TEAMModelOS.SDK.CoreAPIHttpService;
  20. using Microsoft.Azure.Cosmos;
  21. using System.Collections;
  22. using TEAMModelOS.SDK.Models.Cosmos.OpenEntity;
  23. using System.Globalization;
  24. using Microsoft.OData;
  25. namespace TEAMModelOS.SDK.Models.Service
  26. {
  27. public static class SystemService
  28. {
  29. #region
  30. static string cn_wb = @"
  31. IES晚间报告:{tmdname}您好,以下是您的今日个人IES教学汇总报告,截至{sendTime}时,您已发布{examCount}次评测任务,{homeworkCount}次作业任务,并使用HiTeach教师端开设了{lessonCount}节课堂教学活动。
  32. 以下是报告的具体详细信息。
  33. {cn_examTitle}{cn_examList}
  34. {cn_lessonTitle}{cn_lessonList}
  35. {cn_groupTitle}{cn_groupList}
  36. 如有布置作业任务,将于次日8点通过早报方式发送。
  37. ";
  38. static string cn_examList = "【{examName}】已经有{submitCount}位学生提交,仍有{unsubmitCount}位学生未提交。";
  39. static string cn_lessonList = "【{lessonName}】课例应出席人数{memberCount},实际出席人数{attendCount},出席率{attendRate}%。";
  40. static string cn_groupListJoin = "【{grouplistName}】已有总人数{memberCount}位,有{joinCount}位加入。";
  41. static string cn_groupListLeave = "【{grouplistName}】已有总人数{memberCount}位,有{joinCount}位离开。";
  42. static string cn_zb = @"
  43. IES早间报告:{tmdname}您好,以下是您发布过的作业任务汇总报告。
  44. 以下是报告的具体详细信息。
  45. {cn_homeworkTitle}{cn_homeworkList}
  46. ";
  47. static string cn_homeworkList = "【{homeworkName}】已经有{submitCount}位学生提交,仍有{unsubmitCount}位学生未提交。";
  48. static string cn_homeworkTitle = "作业任务提交详情:";
  49. static string cn_examTitle = "评测任务提交详情:";
  50. static string cn_lessonTitle = "课堂教学出席详情:";
  51. static string cn_groupTitle = "个人课程名单变化详情:";
  52. static string cn_lessonDetail = @"</br>课例名称:{name},开课时间:{time},时长:{duration}分钟</br>
  53. 1.本节课名单{count}人,分成{groupCount}组,出席人数:{attendCount}人,缺席:{absentCount}人,出席率{attendRate}%</br>
  54. 2.学习参与度指数平均:{engagementIndexAverge} </br>
  55. 分组参与度:{grpEngagement}</br>
  56. 参与较多者:{highRankEngagement}</br>
  57. 3.记分:总记分:{totalPoint}分 </br>
  58. 个人记分较多者:{highRankPerPoint}</br>
  59. 小组记分较多的:{highRankGrpPoint}</br>
  60. 4.互动:{interactionCount}题,总互动分:{totalInteractPoint}分</br>
  61. 5.任务:{pushCount}次,作品总数:{collateTaskCount}件</br>
  62. 6.测验:{examCount}次,题数:{examQuizCount}题,平均得分率:{examPointRate}% </br>
  63. 表现较好者:{highRankExam}</br>
  64. 表现较弱者:{lowRankExam}</br>
  65. 7.互评:{smartRatingCount}次,合计参与:{clientSmartRatingCount}次</br>
  66. 8.协作:{coworkTaskCount}次,作品总数:{coworkGroupCount}件,总操作量:{coworkGroupCount}</br>";
  67. #endregion
  68. #region
  69. static string tw_wb = @"
  70. IES晚間報告:{tmdname}您好,以下是您的今日個人IES教學總結報告,截至{sendTime},您已發布{examCount}次測驗任務,{homeworkCount}次作業任務,並使用HiTeach上傳了{lessonCount}節課堂教學活動。
  71. 以下是詳細資訊。
  72. {tw_examTitle}{tw_examList}
  73. {tw_lessonTitle}{tw_lessonList}
  74. {tw_groupTitle}{tw_groupList}
  75. 如有佈署作業任務,將於隔天早上8點透過晨間報告方式發送。
  76. ";
  77. static string tw_examList = "【{examName}】已經有{submitCount}位學生繳交,仍有{unsubmitCount}位學生未繳交。";
  78. static string tw_lessonList = "【{lessonName}】課堂應出席人數{memberCount},實際出席人數{attendCount},出席率{attendRate}%。";
  79. static string tw_groupListJoin = "【{grouplistName}】已有總人數{memberCount}位,有{joinCount}位加入。";
  80. static string tw_groupListLeave = "【{grouplistName}】已有總人數{memberCount}位,有{joinCount}位離開。";
  81. static string tw_zb = @"
  82. IES晨間報告:{tmdname}您好,以下是您曾經發佈過的作業任務總結報告。
  83. 以下是具體詳細資訊。
  84. {tw_homeworkTitle}{tw_homeworkList}
  85. ";
  86. static string tw_homeworkList = "【{homeworkName}】已經有{submitCount}位學生繳交,仍有{unsubmitCount}位學生未繳交。";
  87. static string tw_homeworkTitle = "作業任務繳交詳情:";
  88. static string tw_examTitle = "測驗任務完成詳情:";
  89. static string tw_lessonTitle = "課堂教學出席詳情:";
  90. static string tw_groupTitle = "個人課程名單變動詳情:";
  91. static string tw_lessonDetail = @"</br>课例名称:{name},開課時間:{time},時長:{duration}分鐘</br>
  92. 1.本節課名單{count}人,分成{groupCount}組,出席人数:{attendCount}人,缺席:{absentCount}人,出席率{attendRate}%</br>
  93. 2.學習参與度指數平均:{engagementIndexAverge}</br>
  94. 分組参舆度:{grpEngagement}</br>
  95. 参與较多者:{highRankEngagement}</br>
  96. 3.記分:總記分:{totalPoint}分</br>
  97. 個人記分较多者:{highRankPerPoint}</br>
  98. 小組記分较多的:{highRankGrpPoint}</br>
  99. 4.互動:{interactionCount}题,總互動分:{totalInteractPoint}分</br>
  100. 5.任務:{pushCount}次,作品總数:{collateTaskCount}件</br>
  101. 6.測驗:{examCount}次,题數:{examQuizCount}题,平均得分率:{examPointRate}%</br>
  102. 表現较好者:{highRankExam}</br>
  103. 表現较弱者:{lowRankExam}</br>
  104. 7.互评:{smartRatingCount}次,合計参與:{clientSmartRatingCount}次</br>
  105. 8.協作:{coworkTaskCount}次,作品總數:{coworkGroupCount}件,總操作量:{coworkGroupCount}</br>";
  106. #endregion
  107. #region
  108. static string en_wb = @"
  109. IES Evening Report:Hello {tmdname}, here is your personal IES teaching summary report for today. As of {sendTime}, you have published {examCount} test tasks, {homeworkCount} homework tasks, and uploaded {lessonCount} HiTeach lesson activity records.
  110. The following are the specific details.
  111. {en_examTitle}{en_examList}
  112. {en_lessonTitle}{en_lessonList}
  113. {en_groupTitle}{en_groupList}
  114. If there are homework tasks assigned, they will be sent through the morning report at 8 am the next day.
  115. ";
  116. static string en_examList = "[ {examName} ] has {submitCount} students submitted, and there are still {unsubmitCount} students who have not submitted.";
  117. static string en_lessonList = "[ {lessonName} ] lesson should have {memberCount} attendees, actual attendees {attendCount}, attendance rate {attendRate}%.";
  118. static string en_groupListJoin = "[ {grouplistName} ] has a total of {memberCount}, {joinCount} joined.";
  119. static string en_groupListLeave = "[ {grouplistName} ] has a total of {memberCount}, {joinCount} left.";
  120. static string en_zb = @"
  121. IES Morning Report:
  122. Hello {tmdname}, here is the summary report of the homework tasks you have posted.
  123. {en_homeworkTitle}{en_homeworkList}
  124. ";
  125. static string en_homeworkList = "[ {homeworkName} ] has {submitCount} students submitted, and there are still {unsubmitCount} students who have not submitted.";
  126. static string en_homeworkTitle = "Homework Submission Details:";
  127. static string en_examTitle = "Test task submission details:";
  128. static string en_lessonTitle = "Lesson attendance details:";
  129. static string en_groupTitle = "Personal course list change details:";
  130. static string en_lessonDetail = @"</br>Lesson Name: {name}, Start time: {time}, Duration: {duration} Minutes</br>
  131. 1. There are {count} people in this course, divided into {groupCount} groups, attendance: {attendCount} people, absences: 0 people, attendance rate {attendRate}%</br>
  132. 2. Learning Engagement : {engagementIndexAverge}</br>
  133. Engagement per group: {grpEngagement}</br>
  134. More engaged students: {highRankEngagement}</br>
  135. 3. Total Points: {totalPoint} points</br>
  136. Persons with more points: {highRankPerPoint}</br>
  137. Groups with more points: {highRankGrpPoint}</br>
  138. 4. IRS Interaction: {interactionCount} questions, total IRS interaction score: {totalInteractPoint} points</br>
  139. 5. Tasks: {pushCount} times, total number of collected works: {collateTaskCount} </br>
  140. 6. Test/Exam: {examCount} times, number of questions: {examQuizCount} questions, average scoring rate: {examPointRate}%</br>
  141. Better performers: {highRankExam}</br>
  142. Weaker performers: {lowRankExam}</br>
  143. 7. Smart Rating: {smartRatingCount} times, total participation: {clientSmartRatingCount} times</br>
  144. 8. Collaboration: {coworkTaskCount} times, total number of works: {coworkGroupCount}, total operation: {coworkGroupCount}</br>";
  145. #endregion
  146. // #region
  147. // static string cn_wb = @"
  148. //IES晚间报告:</br>{tmdname}您好,以下是您的今日个人IES教学汇总报告,截至{sendTime}时,您已发布{examCount}次评测任务,{homeworkCount}次作业任务,并使用HiTeach教师端开设了{lessonCount}节课堂教学活动。
  149. //</br>&nbsp;&nbsp;&nbsp;以下是报告的具体详细信息。
  150. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{cn_examTitle}</br>{cn_examList}
  151. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{cn_lessonTitle}</br>{cn_lessonList}
  152. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{cn_groupTitle}</br>{cn_groupList}
  153. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如有布置作业任务,将于次日8点通过早报方式发送。
  154. //";
  155. // static string cn_examList = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;【{examName}】已经有{submitCount}位学生提交,仍有{unsubmitCount}位学生未提交。</br>";
  156. // static string cn_lessonList = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;【{lessonName}】课例应出席人数{memberCount},实际出席人数{attendCount},出席率{attendRate}%。</br>";
  157. // static string cn_groupListJoin = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;【{grouplistName}】已有总人数{memberCount}位,有{joinCount}位加入。</br>";
  158. // static string cn_groupListLeave = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;【{grouplistName}】已有总人数{memberCount}位,有{joinCount}位离开。</br>";
  159. // static string cn_zb = @"
  160. //IES早间报告:</br>{tmdname}您好,以下是您发布过的作业任务汇总报告。
  161. //</br>&nbsp;&nbsp;&nbsp;以下是报告的具体详细信息。
  162. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{cn_homeworkTitle}</br>{cn_homeworkList}
  163. //";
  164. // static string cn_homeworkList = "【{homeworkName}】已经有{submitCount}位学生提交,仍有{unsubmitCount}位学生未提交。</br>";
  165. // static string cn_homeworkTitle = "作业任务提交详情:";
  166. // static string cn_examTitle = "评测任务提交详情:";
  167. // static string cn_lessonTitle = "课堂教学出席详情:";
  168. // static string cn_groupTitle = "个人课程名单变化详情:";
  169. // #endregion
  170. // #region
  171. // static string tw_wb = @"
  172. //IES晚間報告:</br>{tmdname}您好,以下是您的今日個人IES教學總結報告,截至{sendTime},您已發布{examCount}次測驗任務,{homeworkCount}次作業任務,並使用HiTeach上傳了{lessonCount}節課堂教學活動。
  173. //</br>&nbsp;&nbsp;&nbsp;以下是詳細資訊。
  174. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{tw_examTitle}</br>{tw_examList}
  175. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{tw_lessonTitle}</br>{tw_lessonList}
  176. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{tw_groupTitle}</br>{tw_groupList}
  177. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;如有佈署作業任務,將於隔天早上8點透過晨間報告方式發送。
  178. //";
  179. // static string tw_examList = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;【{examName}】已經有{submitCount}位學生繳交,仍有{unsubmitCount}位學生未繳交。</br>";
  180. // static string tw_lessonList = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;【{lessonName}】課堂應出席人數{memberCount},實際出席人數{attendCount},出席率{attendRate}%。</br>";
  181. // static string tw_groupListJoin = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;【{grouplistName}】已有總人數{memberCount}位,有{joinCount}位加入。</br>";
  182. // static string tw_groupListLeave = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;【{grouplistName}】已有總人數{memberCount}位,有{joinCount}位離開。</br>";
  183. // static string tw_zb = @"
  184. //IES晨間報告:</br>{tmdname}您好,以下是您曾經發佈過的作業任務總結報告。
  185. //</br>&nbsp;&nbsp;&nbsp;以下是具體詳細資訊。
  186. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{tw_homeworkTitle}</br>{tw_homeworkList}
  187. //";
  188. // static string tw_homeworkList = "【{homeworkName}】已經有{submitCount}位學生繳交,仍有{unsubmitCount}位學生未繳交。</br>";
  189. // static string tw_homeworkTitle = "作業任務繳交詳情:";
  190. // static string tw_examTitle = "測驗任務完成詳情:";
  191. // static string tw_lessonTitle = "課堂教學出席詳情:";
  192. // static string tw_groupTitle = "個人課程名單變動詳情:";
  193. // #endregion
  194. // #region
  195. // static string en_wb = @"
  196. //IES Evening Report:</br>Hello {tmdname}, here is your personal IES teaching summary report for today. As of {sendTime}, you have published {examCount} test tasks, {homeworkCount} homework tasks, and uploaded {lessonCount} HiTeach lesson activity records.
  197. //</br>&nbsp;&nbsp;&nbsp;The following are the specific details.
  198. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{en_examTitle}</br>{en_examList}
  199. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{en_lessonTitle}</br>{en_lessonList}
  200. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{en_groupTitle}</br>{en_groupList}
  201. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;If there are homework tasks assigned, they will be sent through the morning report at 8 am the next day.
  202. //";
  203. // static string en_examList = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ {examName} ] has {submitCount} students submitted, and there are still {unsubmitCount} students who have not submitted.</br>";
  204. // static string en_lessonList = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ {lessonName} ] lesson should have {memberCount} attendees, actual attendees {attendCount}, attendance rate {attendRate}%.</br>";
  205. // static string en_groupListJoin = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ {grouplistName} ] has a total of {memberCount}, {joinCount} joined.</br>";
  206. // static string en_groupListLeave = "&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ {grouplistName} ] has a total of {memberCount}, {joinCount} left.</br>";
  207. // static string en_zb = @"
  208. //IES Morning Report:
  209. //</br>&nbsp;&nbsp;&nbsp;Hello {tmdname}, here is the summary report of the homework tasks you have posted.
  210. //</br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{en_homeworkTitle}</br>{en_homeworkList}
  211. //";
  212. // static string en_homeworkList = "[ {homeworkName} ] has {submitCount} students submitted, and there are still {unsubmitCount} students who have not submitted.</br>";
  213. // static string en_homeworkTitle = "Homework Submission Details:";
  214. // static string en_examTitle = "Test task submission details:";
  215. // static string en_lessonTitle = "Lesson attendance details:";
  216. // static string en_groupTitle = "Personal course list change details:";
  217. // #endregion
  218. public static string weeklyReportCN = @"<!DOCTYPE html>
  219. <html>
  220. <head>
  221. <title>HiTeach课堂数据周报</title>
  222. <meta charset=""UTF-8"">
  223. <style>
  224. </style>
  225. </head>
  226. <body>
  227. <div style=""margin: 0 0 20px 10px;"">
  228. <p style=""font-size: 20px;"">
  229. <span id=""tmdName"">{tmdName}</span>
  230. 教师您好,你于{year}第{Week}周({weekTime})创建了{lessonCount}节HiTeach5课堂教学活动,以下是报告总览信息,点击其中一行可查看报告详细信息
  231. </p>
  232. <div style=""margin-left: 10px;"">
  233. <table border=""1"" cellpadding=""10"" cellspacing=""0"" border=""1"" cellpadding=""10"" border=""1"" id=""acourseData"">
  234. <thead>
  235. <tr>
  236. <th>课程名称</th>
  237. <th>科目</th>
  238. <th>学校/个人</th>
  239. <th>名单</th>
  240. <th>课例数量</th>
  241. <th>查看详情</th>
  242. </tr>
  243. </thead>
  244. <tbody>
  245. {tableData}
  246. </tbody>
  247. </table>
  248. </div>
  249. </div>
  250. </body>
  251. </html>";
  252. /// <summary>
  253. ///
  254. /// </summary>
  255. /// <param name="_azureRedis"></param>
  256. /// <param name="_azureCosmos"></param>
  257. /// <param name="coreAPIHttpService"></param>
  258. /// <param name="dingDing"></param>
  259. /// <param name="_httpClient"></param>
  260. /// <param name="_snowflakeId"></param>
  261. /// <param name="notifyUrl"></param>
  262. /// <param name="_mailFactory"></param>
  263. /// <param name="am"></param>
  264. /// <param name="pm"></param>
  265. /// <returns></returns>
  266. public static async Task<List<CodeValue> > AccumulateDaily(IConfiguration _configuration,AzureRedisFactory _azureRedis,AzureCosmosFactory _azureCosmos,AzureStorageFactory _azureStorage,
  267. CoreAPIHttpService coreAPIHttpService, DingDing dingDing,HttpClient _httpClient, SnowflakeId _snowflakeId,string notifyUrl, int am=0 ,int pm=0)
  268. {
  269. DateTimeOffset now = DateTimeOffset.Now;
  270. string day = now.ToString("yyyyMMdd");
  271. string homeworkYesterday = now.AddDays(-1).ToString("yyyyMMdd");
  272. HashSet<string> keys = new HashSet<string>();
  273. //当天评测发布的。
  274. //当天的个人评测提交数
  275. Dictionary<string, double?> exam_submit = new();
  276. SortedSetEntry[] exam_goingScores = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Accumulate:Daily:teacher:exam-going:{day}");
  277. // Dictionary<string, double?> exam_going = new();
  278. if (exam_goingScores != null)
  279. {
  280. foreach (var score in exam_goingScores)
  281. {
  282. double val = score.Score;
  283. string key = score.Element.ToString();
  284. // exam_going.Add(key, val);
  285. exam_submit.Add(key, val);
  286. keys.Add(key);
  287. }
  288. }
  289. ///需要再次获取 没有任何人提交的作业和评测任务。
  290. SortedSetEntry[] exam_submitScores = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Accumulate:Daily:private:exam-submit:{day}");
  291. if (exam_submitScores != null)
  292. {
  293. foreach (var score in exam_submitScores)
  294. {
  295. double val = score.Score;
  296. string key = score.Element.ToString();
  297. exam_submit.TryAdd(key, val);
  298. keys.Add(key);
  299. }
  300. }
  301. //今天发布的作业
  302. SortedSetEntry[] homework_goingScores_today = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Accumulate:Daily:teacher:homework-going:{day}");
  303. Dictionary<string, double?> homework_submit_today = new();
  304. //Dictionary<string, double?> homework_going = new();
  305. if (homework_goingScores_today != null)
  306. {
  307. foreach (var score in homework_goingScores_today)
  308. {
  309. double val = score.Score;
  310. string key = score.Element.ToString();
  311. //homework_going.Add(key, val);
  312. homework_submit_today.TryAdd(key, val);
  313. keys.Add(key);
  314. }
  315. }
  316. //昨天发布的作业
  317. SortedSetEntry[] homework_goingScores = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Accumulate:Daily:teacher:homework-going:{homeworkYesterday}");
  318. Dictionary<string, double?> homework_submit = new();
  319. //Dictionary<string, double?> homework_going = new();
  320. if (homework_goingScores != null)
  321. {
  322. foreach (var score in homework_goingScores)
  323. {
  324. double val = score.Score;
  325. string key = score.Element.ToString();
  326. //homework_going.Add(key, val);
  327. homework_submit.TryAdd(key, val);
  328. keys.Add(key);
  329. }
  330. }
  331. //昨天的个人作业提交数
  332. SortedSetEntry[] homework_submitScores = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Accumulate:Daily:teacher:homework-submit:{homeworkYesterday}");
  333. if (homework_submitScores != null)
  334. {
  335. foreach (var score in homework_submitScores)
  336. {
  337. double val = score.Score;
  338. string key = score.Element.ToString();
  339. homework_submit.TryAdd(key, val);
  340. keys.Add(key);
  341. }
  342. }
  343. //当天的个人名单加入人数
  344. Dictionary<string, double?> grouplist = new();
  345. SortedSetEntry[] grouplistScores = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Accumulate:Daily:teacher:grouplist:{day}");
  346. if (grouplistScores != null)
  347. {
  348. foreach (var score in grouplistScores)
  349. {
  350. double val = score.Score;
  351. string key = score.Element.ToString();
  352. grouplist.TryAdd(key, val);
  353. keys.Add(key);
  354. }
  355. }
  356. //当天教师的开课数量Accumulate:Daily:teacher:lesson-create:20240527
  357. Dictionary<string, double?> lessoncreate = new();
  358. SortedSetEntry[] llessoncreateScores = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Accumulate:Daily:teacher:lesson-create:{day}");
  359. if (llessoncreateScores != null)
  360. {
  361. foreach (var score in llessoncreateScores)
  362. {
  363. double val = score.Score;
  364. string key = score.Element.ToString();
  365. lessoncreate.TryAdd(key, val);
  366. keys.Add(key);
  367. }
  368. }
  369. List<string> ids = new List<string>();
  370. keys.ToList().ForEach(x => {
  371. ids.Add(x.Split("::")[0]);
  372. });
  373. List<CoreUser> coreUsers = new List<CoreUser>();
  374. List<Teacher> teachers= new List<Teacher>();
  375. if (ids.IsNotEmpty())
  376. {
  377. string sql = $"select value c from c where c.id in ({string.Join(",", ids.Select(x => $"'{x}'"))})";
  378. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<Teacher>(sql, "Base");
  379. if (result.list.IsNotEmpty())
  380. {
  381. teachers.AddRange(result.list);
  382. }
  383. var content = new StringContent(ids.Distinct().ToJsonString(), Encoding.UTF8, "application/json");
  384. try
  385. {
  386. string json = await coreAPIHttpService.GetUserInfos(content);
  387. if (!string.IsNullOrWhiteSpace(json))
  388. {
  389. coreUsers = json.ToObject<List<CoreUser>>();
  390. }
  391. }
  392. catch (Exception ex)
  393. {
  394. await dingDing.SendBotMsg($"{coreAPIHttpService.options.location}用户转换失败:{coreAPIHttpService.options.coreUrl}", GroupNames.醍摩豆服務運維群組);
  395. }
  396. }
  397. List<CodeValue> notifys = new List<CodeValue>();
  398. foreach (var teacher in teachers)
  399. {
  400. //if (!(teacher.id.Equals("1535418750")))
  401. //{
  402. // continue;
  403. //}
  404. //if (!(teacher.id.Equals("1535418750")))
  405. //{
  406. // continue;
  407. //}
  408. StringBuilder notify = new StringBuilder();
  409. #if DEBUG
  410. int sendTime_pm = now.Hour;
  411. int sendTime_am = now.Hour;
  412. #else
  413. int sendTime_pm = 20;
  414. int sendTime_am =8;
  415. #endif
  416. if (am>0) {
  417. sendTime_am = am;
  418. }
  419. if (pm>0)
  420. {
  421. sendTime_pm = pm;
  422. }
  423. string lang = teacher.lang;
  424. var tzt = now.GetGMTTime((int)teacher.timezone);
  425. if (string.IsNullOrWhiteSpace(teacher.lang))
  426. {
  427. if (coreAPIHttpService.options.location.Contains("China", StringComparison.OrdinalIgnoreCase))
  428. {
  429. lang= "zh-cn";
  430. }
  431. if (coreAPIHttpService.options.location.Contains("Global",StringComparison.OrdinalIgnoreCase))
  432. {
  433. lang= "en-us";
  434. }
  435. }
  436. int examCount = 0,homeworkCount=0,lessonCount=0;
  437. StringBuilder examSB= new StringBuilder();
  438. foreach (var exam in exam_submit)
  439. {
  440. string[] ks = exam.Key.Split("::");
  441. string tid = ks[0];
  442. string examId = ks[1];
  443. string examName = ks[3];
  444. if (tid.Equals(teacher.id)) {
  445. if (tzt.Hour==sendTime_pm)
  446. {
  447. string sql = $"select c.status from c where c.examId='{examId}' and c.pk='ExamClassResult'";
  448. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).GetList<ExamClassResult>(sql, $"ExamClassResult-{tid}");
  449. if (result.list.IsNotEmpty()) {
  450. var unsubmit = result.list.SelectMany(x => x.status).Where(x => x==1);
  451. var submit = result.list.SelectMany(x => x.status).Where(x => x==0);
  452. examCount++;
  453. switch (lang)
  454. {
  455. case "zh-cn":
  456. examSB.Append(cn_examList.Replace("{examName}", examName).Replace("{submitCount}", $"{submit.Count()}").Replace("{unsubmitCount}", $"{unsubmit.Count()}"));
  457. break;
  458. case "zh-tw":
  459. examSB.Append(tw_examList.Replace("{examName}", examName).Replace("{submitCount}", $"{submit.Count()}").Replace("{unsubmitCount}", $"{unsubmit.Count()}"));
  460. break;
  461. case "en-us":
  462. examSB.Append(en_examList.Replace("{examName}", examName).Replace("{submitCount}", $"{submit.Count()}").Replace("{unsubmitCount}", $"{unsubmit.Count()}"));
  463. break;
  464. }
  465. }
  466. }
  467. }
  468. }
  469. StringBuilder homeworkSB = new StringBuilder();
  470. foreach (var homeworksm in homework_submit_today)
  471. {
  472. string[] ks = homeworksm.Key.Split("::");
  473. string tid = ks[0];
  474. string homeworkId = ks[1];
  475. string homeworkName = ks[3];
  476. if (tid.Equals(teacher.id))
  477. {
  478. if (tzt.Hour==sendTime_pm)
  479. {
  480. homeworkCount++;
  481. }
  482. }
  483. }
  484. foreach (var homeworksm in homework_submit)
  485. {
  486. string[] ks = homeworksm.Key.Split("::");
  487. string tid = ks[0];
  488. string homeworkId = ks[1];
  489. string homeworkName = ks[3];
  490. if (tid.Equals(teacher.id))
  491. {
  492. if (tzt.Hour==sendTime_am)
  493. {
  494. var response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Common).ReadItemStreamAsync(homeworkId, new PartitionKey($"Homework-{tid}"));
  495. if (response.StatusCode == System.Net.HttpStatusCode.OK) {
  496. Homework homework= JsonDocument.Parse(response.Content).RootElement.ToObject<Homework>();
  497. List<string > classes= new List<string>();
  498. classes.AddRange(homework.stuLists);
  499. classes.AddRange(homework.classes);
  500. List<HomeworkUser> homeworkUsers= await HomeworkService.AnswerRecordAll(_azureCosmos.GetCosmosClient(), coreAPIHttpService, dingDing, homework, tid, "Student", classes, "student");
  501. // homeworkCount++;
  502. switch (lang)
  503. {
  504. case "zh-cn":
  505. homeworkSB.Append(cn_homeworkList.Replace("{homeworkName}", homework.name).Replace("{submitCount}", $"{homeworkUsers.Where(x => x.submit).Count()}").Replace("{unsubmitCount}", $"{homeworkUsers.Where(x => !x.submit).Count()}"));
  506. break;
  507. case "zh-tw":
  508. homeworkSB.Append(tw_homeworkList.Replace("{homeworkName}", homework.name).Replace("{submitCount}", $"{homeworkUsers.Where(x => x.submit).Count()}").Replace("{unsubmitCount}", $"{homeworkUsers.Where(x => !x.submit).Count()}"));
  509. break;
  510. case "en-us":
  511. homeworkSB.Append(en_homeworkList.Replace("{homeworkName}", homework.name).Replace("{submitCount}", $"{homeworkUsers.Where(x => x.submit).Count()}").Replace("{unsubmitCount}", $"{homeworkUsers.Where(x => !x.submit).Count()}"));
  512. break;
  513. }
  514. }
  515. }
  516. }
  517. }
  518. StringBuilder lessonSB = new StringBuilder();
  519. StringBuilder lessonDetailSB = new StringBuilder();
  520. foreach (var lesson in lessoncreate)
  521. {
  522. string[] ks = lesson.Key.Split("::");
  523. string tid = ks[0];
  524. if (tid.Equals(teacher.id))
  525. {
  526. if (tzt.Hour==sendTime_pm)
  527. {
  528. long stime = now.AddHours(-20).ToUnixTimeMilliseconds();
  529. string sql = $"select value c from c where c.tmdid='{teacher.id}' and c.pk='LessonRecord' and c.startTime> {stime} ";
  530. List<LessonRecord>lessons = new List<LessonRecord>();
  531. var schoolResult= await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<LessonRecord>(sql);
  532. var teahcerResult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<LessonRecord>(sql, "LessonRecord");
  533. lessons.AddRange(schoolResult.list);
  534. lessons.AddRange(teahcerResult.list);
  535. foreach (var lessonRecord in lessons)
  536. {
  537. LessonBase lessonBase = null;
  538. try
  539. {
  540. string owner = lessonRecord.scope.Equals("school") ? lessonRecord.school : lessonRecord.tmdid;
  541. BlobDownloadResult baseblobDownload = await _azureStorage.GetBlobContainerClient(owner).GetBlobClient($"/records/{lessonRecord.id}/IES/base.json").DownloadContentAsync();
  542. string basejson = baseblobDownload.Content.ToString().Replace("\"Uncall\"", "0").Replace("Uncall", "0");
  543. lessonBase = basejson.ToObject<LessonBase>();
  544. lessonCount++;
  545. var grpEngagement = string.Join(",", lessonBase.summary?.grpEngagement.Select((x, index) => $"G{index+1}({x})"));
  546. var highRankEngagement = string.Join(",", lessonBase.summary?.highRankEngagement?.Select((x, index) => $"S{index+1}({x})"));
  547. var highRankPerPoint = string.Join(",", lessonBase.summary?.highRankPerPoint?.Select((x, index) => $"S{index+1}({x})"));
  548. var highRankGrpPoint = string.Join(",", lessonBase.summary?.highRankGrpPoint?.Select((x, index) => $"S{index+1}({x})"));
  549. var highRankExam = string.Join(",", lessonBase.summary?.highRankExam?.Select((x, index) => $"S{index+1}({x})"));
  550. var lowRankExam = string.Join(",", lessonBase.summary?.lowRankExam?.Select((x, index) => $"S{index+1}({x})"));
  551. switch (lang)
  552. {
  553. case "zh-cn":
  554. if (lessonBase!=null)
  555. {
  556. lessonDetailSB.Append(cn_lessonDetail.Replace("{name}", lessonRecord.name).Replace("{groupCount}",$"{lessonBase.group.Count()}").Replace("{time}", DateTimeOffset.FromUnixTimeMilliseconds(lessonRecord.startTime).ToString("yyyy-MM-dd HH:mm:ss"))
  557. .Replace("{duration}", $"{Math.Round(lessonRecord.duration/60, 2)}").Replace("{count}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")
  558. .Replace("{absentCount}", $"{lessonRecord.clientCount-lessonRecord.attendCount}").Replace("{attendRate}", $"{lessonRecord.attendRate}").Replace("{engagementIndexAverge}", $"{lessonBase.summary?.engagementIndexAverge}")
  559. .Replace("{grpEngagement}", grpEngagement).Replace("{highRankEngagement}", highRankEngagement).Replace("{totalPoint}", $"{lessonBase.summary.totalPoint}").Replace("{highRankPerPoint}", highRankPerPoint)
  560. .Replace("{highRankGrpPoint}", highRankGrpPoint).Replace("{interactionCount}", $"{lessonBase.summary.interactionCount}").Replace("{totalInteractPoint}", $"{lessonBase.summary.totalInteractPoint}")
  561. .Replace("{pushCount}", $"{lessonBase.summary.pushCount}").Replace("{collateTaskCount}", $"{lessonBase.summary.collateTaskCount}").Replace("{examCount}", $"{lessonBase.summary.examCount}")
  562. .Replace("{examQuizCount}", $"{lessonBase.summary.examQuizCount}").Replace("{examPointRate}", $"{lessonBase.summary.examPointRate}").Replace("{highRankExam}", $"{highRankExam}")
  563. .Replace("{lowRankExam}", $"{lowRankExam}").Replace("{smartRatingCount}", $"{lessonBase.summary.smartRatingCount}").Replace("{clientSmartRatingCount}", $"{lessonBase.summary.clientSmartRatingCount}")
  564. .Replace("{coworkTaskCount}", $"{lessonBase.summary.coworkTaskCount}").Replace("{coworkGroupCount}", $"{lessonBase.summary.coworkGroupCount}").Replace("{coworkGroupCount}", $"{lessonBase.summary.coworkGroupCount}")
  565. .Replace("{avgcoworkGroupCount}", lessonRecord.attendCount>0 ? $"{lessonBase.summary.coworkGroupCount/lessonRecord.attendCount}" : "0"));
  566. }
  567. lessonSB.Append(cn_lessonList.Replace("{lessonName}", lessonRecord.name).Replace("{memberCount}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")).Replace("{attendRate}", $"{lessonRecord.attendRate}");
  568. break;
  569. case "zh-tw":
  570. if (lessonBase!=null)
  571. {
  572. lessonDetailSB.Append(tw_lessonDetail.Replace("{name}", lessonRecord.name).Replace("{groupCount}", $"{lessonBase.group.Count()}").Replace("{time}", DateTimeOffset.FromUnixTimeMilliseconds(lessonRecord.startTime).ToString("yyyy-MM-dd HH:mm:ss"))
  573. .Replace("{duration}", $"{Math.Round(lessonRecord.duration/60, 2)}").Replace("{count}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")
  574. .Replace("{absentCount}", $"{lessonRecord.clientCount-lessonRecord.attendCount}").Replace("{attendRate}", $"{lessonRecord.attendRate}").Replace("{engagementIndexAverge}", $"{lessonBase.summary?.engagementIndexAverge}")
  575. .Replace("{grpEngagement}", grpEngagement).Replace("{highRankEngagement}", highRankEngagement).Replace("{totalPoint}", $"{lessonBase.summary.totalPoint}").Replace("{highRankPerPoint}", highRankPerPoint)
  576. .Replace("{highRankGrpPoint}", highRankGrpPoint).Replace("{interactionCount}", $"{lessonBase.summary.interactionCount}").Replace("{totalInteractPoint}", $"{lessonBase.summary.totalInteractPoint}")
  577. .Replace("{pushCount}", $"{lessonBase.summary.pushCount}").Replace("{collateTaskCount}", $"{lessonBase.summary.collateTaskCount}").Replace("{examCount}", $"{lessonBase.summary.examCount}")
  578. .Replace("{examQuizCount}", $"{lessonBase.summary.examQuizCount}").Replace("{examPointRate}", $"{lessonBase.summary.examPointRate}").Replace("{highRankExam}", $"{highRankExam}")
  579. .Replace("{lowRankExam}", $"{lowRankExam}").Replace("{smartRatingCount}", $"{lessonBase.summary.smartRatingCount}").Replace("{clientSmartRatingCount}", $"{lessonBase.summary.clientSmartRatingCount}")
  580. .Replace("{coworkTaskCount}", $"{lessonBase.summary.coworkTaskCount}").Replace("{coworkGroupCount}", $"{lessonBase.summary.coworkGroupCount}").Replace("{coworkGroupCount}", $"{lessonBase.summary.coworkGroupCount}")
  581. .Replace("{avgcoworkGroupCount}", lessonRecord.attendCount>0 ? $"{lessonBase.summary.coworkGroupCount/lessonRecord.attendCount}" : "0"));
  582. }
  583. lessonSB.Append(tw_lessonList.Replace("{lessonName}", lessonRecord.name).Replace("{memberCount}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")).Replace("{attendRate}", $"{lessonRecord.attendRate}");
  584. break;
  585. case "en-us":
  586. if (lessonBase!=null)
  587. {
  588. lessonDetailSB.Append(en_lessonDetail.Replace("{name}", lessonRecord.name).Replace("{groupCount}", $"{lessonBase.group.Count()}").Replace("{time}", DateTimeOffset.FromUnixTimeMilliseconds(lessonRecord.startTime).ToString("yyyy-MM-dd HH:mm:ss"))
  589. .Replace("{duration}", $"{Math.Round(lessonRecord.duration/60, 2)}").Replace("{count}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")
  590. .Replace("{absentCount}", $"{lessonRecord.clientCount-lessonRecord.attendCount}").Replace("{attendRate}", $"{lessonRecord.attendRate}").Replace("{engagementIndexAverge}", $"{lessonBase.summary?.engagementIndexAverge}")
  591. .Replace("{grpEngagement}", grpEngagement).Replace("{highRankEngagement}", highRankEngagement).Replace("{totalPoint}", $"{lessonBase.summary.totalPoint}").Replace("{highRankPerPoint}", highRankPerPoint)
  592. .Replace("{highRankGrpPoint}", highRankGrpPoint).Replace("{interactionCount}", $"{lessonBase.summary.interactionCount}").Replace("{totalInteractPoint}", $"{lessonBase.summary.totalInteractPoint}")
  593. .Replace("{pushCount}", $"{lessonBase.summary.pushCount}").Replace("{collateTaskCount}", $"{lessonBase.summary.collateTaskCount}").Replace("{examCount}", $"{lessonBase.summary.examCount}")
  594. .Replace("{examQuizCount}", $"{lessonBase.summary.examQuizCount}").Replace("{examPointRate}", $"{lessonBase.summary.examPointRate}").Replace("{highRankExam}", $"{highRankExam}")
  595. .Replace("{lowRankExam}", $"{lowRankExam}").Replace("{smartRatingCount}", $"{lessonBase.summary.smartRatingCount}").Replace("{clientSmartRatingCount}", $"{lessonBase.summary.clientSmartRatingCount}")
  596. .Replace("{coworkTaskCount}", $"{lessonBase.summary.coworkTaskCount}").Replace("{coworkGroupCount}", $"{lessonBase.summary.coworkGroupCount}").Replace("{coworkGroupCount}", $"{lessonBase.summary.coworkGroupCount}")
  597. .Replace("{avgcoworkGroupCount}", lessonRecord.attendCount>0 ? $"{lessonBase.summary.coworkGroupCount/lessonRecord.attendCount}" : "0"));
  598. }
  599. lessonSB.Append(en_lessonList.Replace("{lessonName}", lessonRecord.name).Replace("{memberCount}", $"{lessonRecord.clientCount}").Replace("{attendCount}", $"{lessonRecord.attendCount}")).Replace("{attendRate}", $"{lessonRecord.attendRate}");
  600. break;
  601. }
  602. }
  603. catch (Exception ex)
  604. {
  605. }
  606. }
  607. }
  608. }
  609. }
  610. StringBuilder grouplistSB = new StringBuilder();
  611. List<string> grouplistIds=new List<string>();
  612. foreach (var group in grouplist)
  613. {
  614. string[] ks = group.Key.Split("::");
  615. grouplistIds.Add(ks[1]);
  616. }
  617. List<GroupListDto> groupListDtos= await GroupListService.GetGroupListByListids(_azureCosmos.GetCosmosClient(), dingDing, grouplistIds, null);
  618. foreach (var group in grouplist)
  619. {
  620. string[] ks = group.Key.Split("::");
  621. string tid = ks[0];
  622. string grouplistId = ks[1];
  623. string grouplistName = ks[3];
  624. var gpdto= groupListDtos.Find(x => x.id.Equals(grouplistId));
  625. if (gpdto!= null)
  626. {
  627. if (tid.Equals(teacher.id))
  628. {
  629. if (tzt.Hour==sendTime_pm)
  630. {
  631. switch (lang)
  632. {
  633. case "zh-cn":
  634. if (group.Value>=0)
  635. {
  636. grouplistSB.Append(cn_groupListJoin.Replace("{grouplistName}", grouplistName).Replace("{memberCount}", $"{gpdto.tcount+gpdto.scount}").Replace("{joinCount}", $"{group.Value}"));
  637. }
  638. else
  639. {
  640. grouplistSB.Append(cn_groupListLeave.Replace("{grouplistName}", grouplistName).Replace("{memberCount}", $"{gpdto.tcount+gpdto.scount}").Replace("{joinCount}", $"{group.Value}"));
  641. }
  642. break;
  643. case "zh-tw":
  644. if (group.Value>=0)
  645. {
  646. grouplistSB.Append(tw_groupListJoin.Replace("{grouplistName}", grouplistName).Replace("{memberCount}", $"{gpdto.tcount+gpdto.scount}").Replace("{joinCount}", $"{group.Value}"));
  647. }
  648. else
  649. {
  650. grouplistSB.Append(tw_groupListLeave.Replace("{grouplistName}", grouplistName).Replace("{memberCount}", $"{gpdto.tcount+gpdto.scount}").Replace("{joinCount}", $"{group.Value}"));
  651. }
  652. break;
  653. case "en-us":
  654. if (group.Value>=0)
  655. {
  656. grouplistSB.Append(en_groupListJoin.Replace("{grouplistName}", grouplistName).Replace("{memberCount}", $"{gpdto.tcount+gpdto.scount}").Replace("{joinCount}", $"{group.Value}"));
  657. }
  658. else
  659. {
  660. grouplistSB.Append(en_groupListLeave.Replace("{grouplistName}", grouplistName).Replace("{memberCount}", $"{gpdto.tcount+gpdto.scount}").Replace("{joinCount}", $"{group.Value}"));
  661. }
  662. break;
  663. }
  664. }
  665. }
  666. }
  667. }
  668. // await dingDing.SendBotMsg($"{teacher.name},{homework_submit_today.ToJsonString()},pm:{pm},am:{am},tztH:{tzt.Hour},sendPm:{sendTime_pm},sendAm:{sendTime_am},examCount:{examCount},lessonCount:{lessonCount},homeworkCount:{homeworkCount}", GroupNames.成都开发測試群組);
  669. if (tzt.Hour==sendTime_pm && (!string.IsNullOrWhiteSpace(lessonDetailSB.ToString()) || examCount>0 || lessonCount>0 || homeworkCount>0 || (grouplist.Count>0 && !string.IsNullOrWhiteSpace(grouplistSB.ToString()))))
  670. {
  671. string template=string.Empty;
  672. string title=string.Empty;
  673. switch (lang)
  674. {
  675. case "zh-cn":
  676. title="IES晚间报告";
  677. template=cn_wb.Replace("{tmdname}", teacher.name).Replace("{sendTime}", $"{now.ToString("yyyy-MM-dd")} {sendTime_pm}")
  678. .Replace("{examCount}", $"{examCount}").Replace("{homeworkCount}", $"{homeworkCount}").Replace("{lessonCount}", $"{lessonCount}")
  679. .Replace("{cn_examList}", examSB.ToString()).Replace("{cn_lessonList}", lessonSB.ToString()).Replace("{cn_groupList}", grouplistSB.ToString());
  680. if (examCount>0)
  681. {
  682. template= template.Replace("{cn_examTitle}", cn_examTitle);
  683. }
  684. else {
  685. template= template.Replace("{cn_examTitle}", "");
  686. }
  687. if (homeworkCount>0)
  688. {
  689. template= template.Replace("{cn_homeworkTitle}", cn_homeworkTitle);
  690. }
  691. else
  692. {
  693. template= template.Replace("{cn_homeworkTitle}", "");
  694. }
  695. if (lessonCount>0)
  696. {
  697. template= template.Replace("{cn_lessonTitle}", cn_lessonTitle);
  698. }
  699. else
  700. {
  701. template= template.Replace("{cn_lessonTitle}", "");
  702. }
  703. if (grouplist.Count>0 && !string.IsNullOrWhiteSpace(grouplistSB.ToString()))
  704. {
  705. template=template.Replace("{cn_groupTitle}", cn_groupTitle);
  706. }
  707. else
  708. {
  709. template= template.Replace("{cn_groupTitle}", "");
  710. }
  711. break;
  712. case "zh-tw":
  713. title="IES晚間報告";
  714. template=tw_wb.Replace("{tmdname}", teacher.name).Replace("{sendTime}", $"{now.ToString("yyyy-MM-dd")} {sendTime_pm}")
  715. .Replace("{examCount}", $"{examCount}").Replace("{homeworkCount}", $"{homeworkCount}").Replace("{lessonCount}", $"{lessonCount}")
  716. .Replace("{tw_examList}", examSB.ToString()).Replace("{tw_lessonList}", lessonSB.ToString()).Replace("{tw_groupList}", grouplistSB.ToString());
  717. if (examCount>0)
  718. {
  719. template= template.Replace("{tw_examTitle}", tw_examTitle);
  720. }
  721. else
  722. {
  723. template= template.Replace("{tw_examTitle}", "");
  724. }
  725. if (homeworkCount>0)
  726. {
  727. template= template.Replace("{tw_homeworkTitle}", tw_homeworkTitle);
  728. }
  729. else
  730. {
  731. template= template.Replace("{tw_homeworkTitle}", "");
  732. }
  733. if (lessonCount>0)
  734. {
  735. template= template.Replace("{tw_lessonTitle}", tw_lessonTitle);
  736. }
  737. else
  738. {
  739. template= template.Replace("{tw_lessonTitle}", "");
  740. }
  741. if (grouplist.Count>0)
  742. {
  743. template=template.Replace("{tw_groupTitle}", tw_groupTitle);
  744. }
  745. else
  746. {
  747. template= template.Replace("{tw_groupTitle}", "");
  748. }
  749. break;
  750. case "en-us":
  751. title ="IES Evening Report";
  752. template=en_wb.Replace("{tmdname}", teacher.name).Replace("{sendTime}", $"{now.ToString("yyyy-MM-dd")} {sendTime_pm}")
  753. .Replace("{examCount}", $"{examCount}").Replace("{homeworkCount}", $"{homeworkCount}").Replace("{lessonCount}", $"{lessonCount}")
  754. .Replace("{en_examList}", examSB.ToString()).Replace("{en_lessonList}", lessonSB.ToString()).Replace("{en_groupList}", grouplistSB.ToString());
  755. if (examCount>0)
  756. {
  757. template= template.Replace("{en_examTitle}", en_examTitle);
  758. }
  759. else
  760. {
  761. template= template.Replace("{en_examTitle}", "");
  762. }
  763. if (homeworkCount>0)
  764. {
  765. template= template.Replace("{en_homeworkTitle}", en_homeworkTitle);
  766. }
  767. else
  768. {
  769. template= template.Replace("{en_homeworkTitle}", "");
  770. }
  771. if (lessonCount>0)
  772. {
  773. template= template.Replace("{en_lessonTitle}", en_lessonTitle);
  774. }
  775. else
  776. {
  777. template= template.Replace("{en_lessonTitle}", "");
  778. }
  779. if (grouplist.Count>0)
  780. {
  781. template=template.Replace("{en_groupTitle}", en_groupTitle);
  782. }
  783. else
  784. {
  785. template= template.Replace("{en_groupTitle}", "");
  786. }
  787. break;
  788. }
  789. template= template.Replace("\r\n", "");
  790. string eventId = $"Evening_Report-{_snowflakeId.NextId()}";
  791. NotifyData notifyData = new NotifyData
  792. {
  793. hubName = "hita5",
  794. sender = "IES",
  795. tags = new List<string>() { $"{teacher.id}_{Constant.NotifyType_IES5_Course}" },
  796. title = title,
  797. eventId =eventId,
  798. eventName =title,
  799. data = "{\"value\":{}}",
  800. body=template,
  801. };
  802. HttpResponseMessage responseMessage = await _httpClient.PostAsJsonAsync($"{notifyUrl}/service/PushNotify", notifyData);
  803. var coreUser = coreUsers.Find(x => x.id.Equals(teacher.id) && !string.IsNullOrWhiteSpace(x.mail));
  804. if (coreUser!=null)
  805. {
  806. // var token = _mailFactory.GetSmtpClient().SendEmail(_azureCosmos, dingDing, eventId, title, template, coreUser.mail, teacher.id, teacher.name, sender: "TEAMModel");
  807. //var tid = lang.Equals("zh-cn") ? "d-136eddbd974046f1a721c8f4e210b9bf" : lang.Equals("zh-tw") ? "d-136eddbd974046f1a721c8f4e210b9bf" : "d-95ac2d657d1b4d9dbb7b79defc17f714";
  808. var tid = string.Empty;
  809. if (coreAPIHttpService.options.location.Contains("China"))
  810. {
  811. tid=lang.Equals("zh-cn") ? "IES5GeneralTemplateSC" : lang.Equals("zh-tw") ? "IES5GeneralTemplateTC" : "IES5GeneralTemplateEN";
  812. }
  813. else
  814. {
  815. tid=lang.Equals("zh-cn") ? "d-270b4ec690f541a9a4045d7a4032bc3b" : lang.Equals("zh-tw") ? "d-136eddbd974046f1a721c8f4e210b9bf" : "d-95ac2d657d1b4d9dbb7b79defc17f714";
  816. }
  817. await coreAPIHttpService.SendMail(new Dictionary<string, object> { { "to", coreUser.mail }, { "tid", tid }, { "vars", new { title = title, notificationcontent = $"{template}</br>{lessonDetailSB.ToString()}" } } }, coreAPIHttpService.options.location, _configuration);
  818. }
  819. notify.Append(template);
  820. }
  821. if (tzt.Hour==sendTime_am && !string.IsNullOrWhiteSpace(homeworkSB.ToString()))
  822. {
  823. string template = string.Empty;
  824. string title = string.Empty;
  825. switch (lang)
  826. {
  827. case "zh-cn":
  828. title ="IES早间报告";
  829. template= cn_zb.Replace("{tmdname}", teacher.name).Replace("{sendTime}", $"{now.ToString("yyyy-MM-dd")} {sendTime_am}")
  830. .Replace("{cn_homeworkList}", homeworkSB.ToString());
  831. template=template.Replace("{cn_homeworkTitle}", cn_homeworkTitle);
  832. break;
  833. case "zh-tw":
  834. title ="IES晨間報告";
  835. template= tw_zb.Replace("{tmdname}", teacher.name).Replace("{sendTime}", $"{now.ToString("yyyy-MM-dd")} {sendTime_am}")
  836. .Replace("{tw_homeworkList}", homeworkSB.ToString());
  837. template=template.Replace("{tw_homeworkTitle}", tw_homeworkTitle);
  838. break;
  839. case "en-us":
  840. title ="IES Morning Report";
  841. template=en_zb.Replace("{tmdname}", teacher.name).Replace("{sendTime}", $"{now.ToString("yyyy-MM-dd")} {sendTime_am}")
  842. .Replace("{en_homeworkList}", homeworkSB.ToString());
  843. template=template.Replace("{en_homeworkTitle}", en_homeworkTitle);
  844. break;
  845. }
  846. template= template.Replace("\r\n", "");
  847. string eventId = $"Morning_Report-{_snowflakeId.NextId()}";
  848. NotifyData notifyData = new NotifyData
  849. {
  850. hubName = "hita5",
  851. sender = "IES",
  852. tags = new List<string>() { $"{teacher.id}_{Constant.NotifyType_IES5_Course}" },
  853. title = title,
  854. eventId = eventId,
  855. eventName =title,
  856. data = "{\"value\":{}}",
  857. body=template,
  858. };
  859. HttpResponseMessage responseMessage = await _httpClient.PostAsJsonAsync($"{notifyUrl}/service/PushNotify", notifyData);
  860. var coreUser = coreUsers.Find(x => x.id.Equals(teacher.id) && !string.IsNullOrWhiteSpace(x.mail));
  861. if (coreUser!=null)
  862. {
  863. // var token = _mailFactory.GetSmtpClient().SendEmail(_azureCosmos, dingDing, eventId, title, template, coreUser.mail, teacher.id, teacher.name,sender:"TEAMModel");
  864. var tid = string.Empty ;
  865. if (coreAPIHttpService.options.location.Contains("China"))
  866. {
  867. tid=lang.Equals("zh-cn") ? "IES5GeneralTemplateSC" : lang.Equals("zh-tw") ? "IES5GeneralTemplateTC" : "IES5GeneralTemplateEN";
  868. }
  869. else {
  870. tid=lang.Equals("zh-cn")? "d-270b4ec690f541a9a4045d7a4032bc3b" : lang.Equals("zh-tw") ? "d-136eddbd974046f1a721c8f4e210b9bf" : "d-95ac2d657d1b4d9dbb7b79defc17f714";
  871. }
  872. await coreAPIHttpService.SendMail(new Dictionary<string, object> { { "to", coreUser.mail }, { "tid", tid }, { "vars", new { title = title, notificationcontent = template } } }, coreAPIHttpService.options.location, _configuration);
  873. }
  874. notify.Append(template);
  875. }
  876. notifys.Add(new CodeValue { code=teacher.id, value= notify.ToString() });
  877. }
  878. return notifys;
  879. }
  880. public static async Task RecordAccumulateData(AzureRedisFactory azureRedis, DingDing dingDing, Accumulate accumulate)
  881. {
  882. if (!string.IsNullOrWhiteSpace(accumulate.key) && !string.IsNullOrWhiteSpace(accumulate.target) &&
  883. !string.IsNullOrWhiteSpace(accumulate.id) && !string.IsNullOrWhiteSpace(accumulate.name) &&
  884. !string.IsNullOrWhiteSpace(accumulate.scope) && !string.IsNullOrWhiteSpace(accumulate.client))
  885. {
  886. await RecordAccumulateData(azureRedis, accumulate.key, accumulate.target, accumulate.id, accumulate.name, accumulate.scope, accumulate.client, accumulate.count);
  887. }
  888. else
  889. {
  890. await dingDing.SendBotMsg($"IES累计数据变更统计参数异常,{accumulate.ToJsonString()}", GroupNames.成都开发測試群組);
  891. }
  892. }
  893. public static async Task LessonWeekly( AzureRedisFactory _azureRedis, AzureCosmosFactory _azureCosmos, CoreAPIHttpService _coreAPIHttpService, DingDing _dingDing)
  894. {
  895. var now = DateTime.Now;
  896. // 使用当前文化设置的日历
  897. CultureInfo cultureInfo = CultureInfo.CurrentCulture;
  898. Calendar calendar = cultureInfo.Calendar;
  899. //表示如果一年的第一个星期至少有4天在同一年,则该星期被视为第一周,DayOfWeek.Monday和DayOfWeek.Sunday分别表示一周的第一天是星期一或星期日。
  900. var week = calendar.GetWeekOfYear(now, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday);
  901. string schoolKey = $"LessonWeekly:school:{now.Year}-{week}";
  902. string privateKey = $"LessonWeekly:private:{now.Year}-{week}";
  903. int currentDayOfWeek = (int)now.DayOfWeek;
  904. // 计算周一的日期
  905. DateTime startOfWeek = now.AddDays(1 - currentDayOfWeek);
  906. // 计算周日的日期
  907. DateTime endOfWeek = now.AddDays(7 - currentDayOfWeek);
  908. // 获取当前年份
  909. int currentYear = now.Year;
  910. // 获取当前年份的第一天
  911. DateTimeOffset firstDayOfYear = new DateTimeOffset(currentYear, 1, 1, 0, 0, 0,new TimeSpan(8,0,0));
  912. // 获取当前年份的最后一天
  913. DateTimeOffset lastDayOfYear = new DateTimeOffset(currentYear, 12, 31, 23, 59, 59, new TimeSpan(8, 0, 0));
  914. var schoolValues = await _azureRedis.GetRedisClient(8).HashGetAllAsync(schoolKey);
  915. var privateValues = await _azureRedis.GetRedisClient(8).HashGetAllAsync(privateKey);
  916. List<KeyValuePair<string, List<LessonWeek>>> datas = new List<KeyValuePair<string, List<LessonWeek>>>();
  917. HashSet<string> schoolId = new HashSet<string>();
  918. if (schoolValues!=default && schoolValues.Length>0)
  919. {
  920. foreach (var value in schoolValues)
  921. {
  922. var tmdid = value.Name.ToString().Split(":")[0];
  923. LessonWeek data = value.Value.ToString().ToObject<LessonWeek>();
  924. if (!string.IsNullOrWhiteSpace(data.school))
  925. {
  926. schoolId.Add(data.school);
  927. }
  928. var tmdData = datas.Find(x => x.Key.Equals(tmdid));
  929. if (tmdData.Key==null)
  930. {
  931. tmdData= new KeyValuePair<string, List<LessonWeek>>(tmdid, new List<LessonWeek> { data });
  932. datas.Add(tmdData);
  933. }
  934. else
  935. {
  936. tmdData.Value.Add(data);
  937. }
  938. }
  939. }
  940. if (privateValues!=default && privateValues.Length>0)
  941. {
  942. foreach (var value in privateValues)
  943. {
  944. var tmdid = value.Name.ToString().Split(":")[0];
  945. LessonWeek data = value.Value.ToString().ToObject<LessonWeek>();
  946. var tmdData = datas.Find(x => x.Key.Equals(tmdid));
  947. if (tmdData.Key==null)
  948. {
  949. tmdData= new KeyValuePair<string, List<LessonWeek>>(tmdid, new List<LessonWeek> { data });
  950. datas.Add(tmdData);
  951. }
  952. else
  953. {
  954. tmdData.Value.Add(data);
  955. }
  956. }
  957. }
  958. if (datas.IsNotEmpty())
  959. {
  960. List<Teacher> teachers = new List<Teacher>();
  961. string sql = $"select value c from c where c.id in ({string.Join(",", datas.Select(x => $"'{x.Key}'"))})";
  962. var result = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<Teacher>(sql, "Base");
  963. if (result.list.IsNotEmpty())
  964. {
  965. teachers.AddRange(result.list);
  966. }
  967. List<School> schools = new List<School>();
  968. if (schoolId.IsNotEmpty())
  969. {
  970. var schoolIds= datas.SelectMany(x => x.Value).Where(x => !string.IsNullOrWhiteSpace(x.school)).Select(x => x.school).Distinct();
  971. string schsql = $"select value c from c where c.id in ({string.Join(",", schoolIds.Select(x => $"'{x}'"))})";
  972. var schresult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<School>(schsql, "Base");
  973. if (schresult.list.IsNotEmpty())
  974. {
  975. schools.AddRange(schresult.list);
  976. }
  977. }
  978. //个人和学校名单
  979. List<GroupListDto> groupLists = new List<GroupListDto>();
  980. //个人和学校课程
  981. List<CourseBase> courseBases = new List<CourseBase>();
  982. foreach (var data in datas)
  983. {
  984. var teacher = teachers.Find(x => x.id.Equals(data.Key));
  985. if (teacher!=null)
  986. {
  987. string lang = teacher.lang;
  988. var tzt = now.GetGMTTime((int)teacher.timezone);
  989. if (string.IsNullOrWhiteSpace(teacher.lang))
  990. {
  991. if (_coreAPIHttpService.options.location.Contains("China", StringComparison.OrdinalIgnoreCase))
  992. {
  993. lang= "zh-cn";
  994. }
  995. if (_coreAPIHttpService.options.location.Contains("Global", StringComparison.OrdinalIgnoreCase))
  996. {
  997. lang= "en-us";
  998. }
  999. }
  1000. List<LessonRecord> lessonRecords = new List<LessonRecord>();
  1001. #region
  1002. //课例
  1003. //{
  1004. // var pid = data.Value.FindAll(x => !string.IsNullOrWhiteSpace(x.scope) && x.scope.Equals("private")).Select(x => x.id);
  1005. // var sid = data.Value.FindAll(x => !string.IsNullOrWhiteSpace(x.scope) && x.scope.Equals("school"))
  1006. // .Select(x => new CodeValue { code=x.school, value=x.id }).GroupBy(x => x.code).Select(x => new { key = x.Key, list = x.ToList() });
  1007. // if (pid!=null && pid.Count()>0)
  1008. // {
  1009. // var pg = pid.ExceptBy(groupLists.Select(x => x.id), y => y);
  1010. // if (pg!=null && pg.Count()>0)
  1011. // {
  1012. // string csql = $"select value c from c where c.id in ({string.Join(",", pg.Select(x => $"'{x}'"))})";
  1013. // var lresult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<LessonRecord>(csql, "LessonRecord");
  1014. // if (lresult.list.IsNotEmpty())
  1015. // {
  1016. // lessonRecords.AddRange(lresult.list);
  1017. // }
  1018. // }
  1019. // }
  1020. // if (sid!=null && sid.Count()>0)
  1021. // {
  1022. // foreach (var item in sid)
  1023. // {
  1024. // var sg = item.list.Select(x => x.value).ToList().ExceptBy(groupLists.Where(x => x.school.Equals(item.key)).Select(x => x.id), y => y);
  1025. // if (sg!=null && sg.Count()>0)
  1026. // {
  1027. // string csql = $"select value c from c where c.id in ({string.Join(",", sg.Select(x => $"'{x}'"))})";
  1028. // var lresult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<LessonRecord>(csql, $"LessonRecord-{item.key}");
  1029. // if (lresult.list.IsNotEmpty())
  1030. // {
  1031. // lessonRecords.AddRange(lresult.list);
  1032. // }
  1033. // }
  1034. // }
  1035. // }
  1036. //}
  1037. //名单
  1038. {
  1039. var pgid = data.Value.FindAll(x => !string.IsNullOrWhiteSpace(x.scope) && x.scope.Equals("private")).Select(x => x.gid);
  1040. var sgid = data.Value.FindAll(x => !string.IsNullOrWhiteSpace(x.scope) && x.scope.Equals("school"))
  1041. .Select(x => new CodeValue { code=x.school, value=x.gid }).GroupBy(x => x.code).Select(x => new { key = x.Key, list = x.ToList() });
  1042. if (pgid!=null && pgid.Count()>0)
  1043. {
  1044. var pg = pgid.ExceptBy(groupLists.Select(x => x.id), y => y);
  1045. if (pg!=null && pg.Count()>0)
  1046. {
  1047. var grouplist = await GroupListService.GetGroupListByListids(_azureCosmos.GetCosmosClient(), _dingDing, pg.ToList(), null);
  1048. if (grouplist.IsNotEmpty())
  1049. {
  1050. groupLists.AddRange(grouplist);
  1051. }
  1052. }
  1053. }
  1054. if (sgid!=null && sgid.Count()>0)
  1055. {
  1056. foreach (var item in sgid)
  1057. {
  1058. var sg = item.list.Select(x => x.value).ToList().ExceptBy(groupLists.Where(x => x.school.Equals(item.key)).Select(x => x.id), y => y);
  1059. if (sg!=null && sg.Count()>0)
  1060. {
  1061. var grouplist = await GroupListService.GetGroupListByListids(_azureCosmos.GetCosmosClient(), _dingDing, sg.ToList(), item.key);
  1062. if (grouplist.IsNotEmpty())
  1063. {
  1064. groupLists.AddRange(grouplist);
  1065. }
  1066. }
  1067. }
  1068. }
  1069. }
  1070. //课程
  1071. {
  1072. var pcid = data.Value.FindAll(x => !string.IsNullOrWhiteSpace(x.scope) && x.scope.Equals("private") && !string.IsNullOrWhiteSpace(x.cid)).Select(x => x.cid);
  1073. var scid = data.Value.FindAll(x => !string.IsNullOrWhiteSpace(x.scope) && x.scope.Equals("school") && !string.IsNullOrWhiteSpace(x.cid))
  1074. .Select(x => new CodeValue { code=x.school, value=x.cid }).GroupBy(x => x.code).Select(x => new { key = x.Key, list = x.ToList() });
  1075. if (pcid!=null && pcid.Count()>0)
  1076. {
  1077. var pg = pcid.ExceptBy(courseBases.Select(x => x.id), y => y);
  1078. if (pg!=null && pg.Count()>0)
  1079. {
  1080. string csql = $"select value c from c where c.id in ({string.Join(",", pg.Select(x => $"'{x}'"))})";
  1081. var cresult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Teacher).GetList<CourseBase>(csql, "CourseBase");
  1082. if (cresult.list.IsNotEmpty())
  1083. {
  1084. courseBases.AddRange(cresult.list);
  1085. }
  1086. }
  1087. }
  1088. if (scid!=null && scid.Count()>0)
  1089. {
  1090. foreach (var item in scid)
  1091. {
  1092. var sg = item.list.Select(x => x.value).ToList().ExceptBy(courseBases.Where(x => x.school.Equals(item.key)).Select(x => x.id), y => y);
  1093. if (sg!=null && sg.Count()>0)
  1094. {
  1095. string csql = $"select value c from c where c.id in ({string.Join(",", sg.Select(x => $"'{x}'"))})";
  1096. var cresult = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.School).GetList<CourseBase>(csql, $"CourseBase-{item.key}");
  1097. if (cresult.list.IsNotEmpty())
  1098. {
  1099. courseBases.AddRange(cresult.list);
  1100. }
  1101. }
  1102. }
  1103. }
  1104. }
  1105. #endregion
  1106. StringBuilder sb= new StringBuilder();
  1107. var sdata = data.Value.Where(x => x.scope.Equals("school")).GroupBy(x => $"{x.scope}:{x.cid}:{x.gid}:{x.school}:{x.sid}").Select(x=>new { key=x.Key,list= x.ToList()});
  1108. var pdata = data.Value.Where(x => x.scope.Equals("private")).GroupBy(x => $"{x.scope}:{x.cid}:{x.gid}:").Select(x => new { key = x.Key, list = x.ToList() }); ;
  1109. foreach (var s in sdata)
  1110. {
  1111. Dictionary<string, string> @params = new ();
  1112. string[] ids = s.key.Split(":");
  1113. var course = courseBases.Find(x => x.id.Equals(ids[1]));
  1114. var group = groupLists.Find(x => x.id.Equals(ids[2]));
  1115. School school = null;
  1116. Subject subject = null;
  1117. Period period = null;
  1118. long stime = 0;
  1119. long etime = 0;
  1120. school = schools.Find(x => x.id.Equals(ids[3]));
  1121. if (school !=null)
  1122. {
  1123. period=school.period.FirstOrDefault();
  1124. subject = school.period.SelectMany(x => x.subjects).Where(x => x.id.Equals(ids[4])).FirstOrDefault();
  1125. var semester = SchoolService.GetSemester(period, DateTimeOffset.Now.ToUnixTimeMilliseconds());
  1126. stime = semester.currSemesterDate.ToUnixTimeMilliseconds();
  1127. etime = semester.nextSemester.ToUnixTimeMilliseconds();
  1128. }
  1129. if (stime==0)
  1130. {
  1131. stime= firstDayOfYear.ToUnixTimeMilliseconds();
  1132. }
  1133. if (etime==0)
  1134. {
  1135. etime= lastDayOfYear.ToUnixTimeMilliseconds();
  1136. }
  1137. @params.Add("tmdId", teacher.id);
  1138. @params.Add("school", school.id);
  1139. @params.Add("scope", "school");
  1140. @params.Add("courseId", course.id);
  1141. @params.Add("groupIds", group.id);
  1142. @params.Add("stime", $"{stime}");
  1143. @params.Add("etime", $"{etime}");
  1144. @params.Add("srvAdr", _coreAPIHttpService.options.location);
  1145. string page = lang.Equals("zh-cn") ? "reprotCN.html" : lang.Equals("zh-tw") ? "reprotTW.html" : "reprotUS.html";
  1146. string opt = lang.Equals("zh-cn") ? "查看" : lang.Equals("zh-tw") ? "檢視" : "View";
  1147. var host = _coreAPIHttpService.options.location.Contains("China", StringComparison.OrdinalIgnoreCase) ? "https://www.teammodel.cn" : "https://www.teammodel.net";
  1148. string paramStr = string.Join("&", @params.Select(x => $"{x.Key}={x.Value}"));
  1149. string url = $"{host}/{page}?{paramStr}";
  1150. sb.Append($"<tr><td>{course.name}</td><td>{subject.name}</td><td>{school.name}</td><td>{group.name}</td><td>{s.list.Count()}</td><td><a href='{url}'>{opt}</td>");
  1151. }
  1152. foreach (var s in pdata)
  1153. {
  1154. Dictionary<string, string> @params = new();
  1155. string[] ids = s.key.Split(":");
  1156. var course = courseBases.Find(x => x.id.Equals(ids[1]));
  1157. var group = groupLists.Find(x => x.id.Equals(ids[2]));
  1158. long stime = firstDayOfYear.ToUnixTimeMilliseconds();
  1159. long etime = lastDayOfYear.ToUnixTimeMilliseconds();
  1160. @params.Add("tmdId", teacher.id);
  1161. @params.Add("school", "");
  1162. @params.Add("scope", "school");
  1163. @params.Add("courseId", course.id);
  1164. @params.Add("groupIds", group.id);
  1165. @params.Add("stime", $"{stime}");
  1166. @params.Add("etime", $"{etime}");
  1167. @params.Add("srvAdr", _coreAPIHttpService.options.location);
  1168. string page = lang.Equals("zh-cn") ? "reprotCN.html" : lang.Equals("zh-tw") ? "reprotTW.html" : "reprotUS.html";
  1169. string opt = lang.Equals("zh-cn") ? "查看" : lang.Equals("zh-tw") ? "檢視" : "View";
  1170. string scopeStr = lang.Equals("zh-cn") ? "个人课程":lang.Equals("zh-tw") ? "個人課程" : "Personal Course";
  1171. var host = _coreAPIHttpService.options.location.Contains("China", StringComparison.OrdinalIgnoreCase) ? "https://www.teammodel.cn" : "https://www.teammodel.net";
  1172. string paramStr = string.Join("&", @params.Select(x => $"{x.Key}={x.Value}"));
  1173. string url = $"{host}/{page}?{paramStr}";
  1174. sb.Append($"<tr><td>{course.name}</td><td>--</td><td>{scopeStr}</td><td>{group.name}</td><td>{s.list.Count()}</td><td><a href='{url}'>{opt}</td>");
  1175. }
  1176. string html= weeklyReportCN.Replace("{tmdName}", teacher.name).Replace("{year}",$"{now.Year}").Replace("{Week}",$"{week}").Replace("{lessonCount}", $"{data.Value.Count()}").Replace("{tableData}",sb.ToString());
  1177. }
  1178. }
  1179. }
  1180. }
  1181. /// <summary>
  1182. /// 记录累计数据
  1183. /// </summary>
  1184. public static async Task RecordAccumulateData(AzureRedisFactory azureRedis, string key, string target, string id, string name, string scope, string client, int count)
  1185. {
  1186. if (!string.IsNullOrWhiteSpace(key) && !string.IsNullOrWhiteSpace(target) &&
  1187. !string.IsNullOrWhiteSpace(id) && !string.IsNullOrWhiteSpace(name) &&
  1188. !string.IsNullOrWhiteSpace(scope)&& !string.IsNullOrWhiteSpace(client))
  1189. {
  1190. //处理UTC时差
  1191. var nowTime = DateTimeOffset.UtcNow.GetGMTTime();
  1192. int difference = (DayOfWeek.Sunday - nowTime.DayOfWeek + 7) % 7; //1-7的结果0-6
  1193. var day = nowTime.ToString("yyyyMMdd");
  1194. string redisKey = $"Accumulate:Daily:{scope}:{key}:{day}";
  1195. string member = $"{target}::{id}::{client}::{name}";
  1196. await azureRedis.GetRedisClient(8).SortedSetIncrementAsync(redisKey, member, count);
  1197. await azureRedis.GetRedisClient(8).KeyExpireAsync(redisKey, new TimeSpan((difference+1)*24, 10, 0));
  1198. //if (key.Equals("lesson") || key.StartsWith("login_"))
  1199. //{
  1200. // redisKey = $"Accumulate:Daily:ies:{key}:{day}";
  1201. // if (scope.Equals("school"))
  1202. // {
  1203. // member = $"ies::{id}::{name}";
  1204. // }
  1205. // else {
  1206. // member = $"ies::ies::{name}";
  1207. // }
  1208. // await azureRedis.GetRedisClient(8).SortedSetIncrementAsync(redisKey, member, 1);
  1209. //}
  1210. }
  1211. }
  1212. public const double timeWeight = 0.7;
  1213. public const double countWeight = 0.3;
  1214. static double GetUserDuration(List<long> times)
  1215. {
  1216. if (times.IsNotEmpty())
  1217. {
  1218. if (times.Count>=2)
  1219. {
  1220. double totalDuration = 0;
  1221. // DateTime lastTime = DateTimeOffset.FromUnixTimeMilliseconds((long)jsonData[0]["time"]).UtcDateTime;
  1222. long ltime = times[0];
  1223. for (int i = 1; i < times.Count; i++)
  1224. {
  1225. long ctime = times[i];
  1226. //DateTime currentTime = DateTimeOffset.FromUnixTimeMilliseconds((long)jsonData[i]["time"]).UtcDateTime;
  1227. long timeDifference = ctime - ltime;
  1228. ///如果一小时内连续操作,则按真实时间累计
  1229. if (timeDifference < 3600000)
  1230. {
  1231. totalDuration += timeDifference;
  1232. }
  1233. else
  1234. { ///如果一小时内没有连续操作,则按象征性加10秒,以确保数据有效性。 如果因为一小时没有操作,则表示没有新的接口再次请求,当即就已经退出系统。否则后续仍然会有接口进入,并且带有时间戳
  1235. totalDuration += 10000;
  1236. }
  1237. ltime = ctime;
  1238. }
  1239. return totalDuration;
  1240. }
  1241. else { return 10000; }
  1242. }
  1243. else
  1244. {
  1245. return 0;
  1246. }
  1247. }
  1248. public static List<SchoolStick> CountSchoolStickiness(IEnumerable<IGrouping<string, ApiVisit>> schoolApiVisits, IEnumerable<ApiVisit> apiVisits, List<SchoolStick> bygoneStickiness)
  1249. {
  1250. List<SchoolStick> schoolStickiness = new List<SchoolStick>();
  1251. //用于做标准化值的最大最小度量值
  1252. double max_sch_hita_c = 0, max_sch_hiteach_c = 0, max_sch_ies5Tch_c = 0, max_sch_otherTch_c = 0, max_sch_ies5Stu_c = 0, max_sch_otherStu_c = 0;
  1253. double max_sch_hita_d = 0, max_sch_hiteach_d = 0, max_sch_ies5Tch_d = 0, max_sch_otherTch_d = 0, max_sch_ies5Stu_d = 0, max_sch_otherStu_d = 0;
  1254. double min_sch_hita_c = 0, min_sch_hiteach_c = 0, min_sch_ies5Tch_c = 0, min_sch_otherTch_c = 0, min_sch_ies5Stu_c = 0, min_sch_otherStu_c = 0;
  1255. double min_sch_hita_d = 0, min_sch_hiteach_d = 0, min_sch_ies5Tch_d = 0, min_sch_otherTch_d = 0, min_sch_ies5Stu_d = 0, min_sch_otherStu_d = 0;
  1256. double max_tch_hita_c = 0, max_tch_hiteach_c = 0, max_tch_ies5Tch_c = 0, max_tch_otherTch_c = 0;
  1257. double max_tch_hita_d = 0, max_tch_hiteach_d = 0, max_tch_ies5Tch_d = 0, max_tch_otherTch_d = 0;
  1258. double min_tch_hita_c = 0, min_tch_hiteach_c = 0, min_tch_ies5Tch_c = 0, min_tch_otherTch_c = 0;
  1259. double min_tch_hita_d = 0, min_tch_hiteach_d = 0, min_tch_ies5Tch_d = 0, min_tch_otherTch_d = 0;
  1260. foreach (var chinaSchoolKey in schoolApiVisits)
  1261. {
  1262. SchoolStick stickiness = new SchoolStick()
  1263. {
  1264. id = chinaSchoolKey.Key
  1265. };
  1266. var teachers = chinaSchoolKey.ToList().Where(x => !string.IsNullOrWhiteSpace(x.userId) && !string.IsNullOrWhiteSpace(x.scope) && x.scope.Equals("teacher")).GroupBy(x => x.userId);
  1267. double hitaTime = 0, hiteachTime = 0, ies5TchTime = 0, otherTchTime = 0, ies5StuTime = 0, otherStuTime = 0;
  1268. int hitaTch = 0, hiteachTch = 0, ies5Tch = 0, otherTch = 0, ies5Stu = 0, otherStu = 0;
  1269. double hitaCount = 0, hiteachCount = 0, ies5TchCount = 0, otherTchCount = 0, ies5StuCount = 0, otherStuCount = 0;
  1270. double lessonCount = chinaSchoolKey.ToList().Where(x => x.path.Contains("hiteach/create-lesson")).Count();
  1271. int teacherCount = teachers.Count();
  1272. double max_stu_ies5Stu_c = 0, max_stu_otherStu_c = 0;
  1273. double max_stu_ies5Stu_d = 0, max_stu_otherStu_d = 0;
  1274. double min_stu_ies5Stu_c = 0, min_stu_otherStu_c = 0;
  1275. double min_stu_ies5Stu_d = 0, min_stu_otherStu_d = 0;
  1276. foreach (var user in teachers)
  1277. {
  1278. TchStick tchStick = new TchStick()
  1279. {
  1280. id = user.Key,
  1281. school= chinaSchoolKey.Key
  1282. };
  1283. //HiTA
  1284. var teacherHitaVisit = apiVisits.Where(x => !string.IsNullOrWhiteSpace(x.userId) && x.userId.Equals(user.Key) && x.client.Equals("hita"));
  1285. var teacherHitaVisitCount = teacherHitaVisit.Count();
  1286. if (teacherHitaVisitCount>0)
  1287. { hitaTch+=1; }
  1288. var teacherHitaVisitTime = GetUserDuration(teacherHitaVisit.OrderBy(x => x.time).Select(x => x.time).ToList());
  1289. hitaCount+=teacherHitaVisitCount;
  1290. hitaTime+=teacherHitaVisitTime;
  1291. tchStick.hita.count.value=teacherHitaVisitCount;
  1292. tchStick.hita.duration.value=teacherHitaVisitTime;
  1293. //Other
  1294. var teacherOtherVisit = user.Where(x => !x.client.Equals("hita")&&!x.client.Equals("hiteach")&&!x.client.Equals("ies5"));
  1295. var teacherOtherVisitCount = teacherOtherVisit.Count();
  1296. var teacherOtherVisitTime = GetUserDuration(teacherOtherVisit.OrderBy(x => x.time).Select(x => x.time).ToList());
  1297. if (teacherOtherVisitCount>0)
  1298. { otherTch+=1; }
  1299. otherTchCount+=teacherOtherVisitCount;
  1300. otherTchTime+=teacherOtherVisitTime;
  1301. tchStick.otherTch.count.value=teacherOtherVisitCount;
  1302. tchStick.otherTch.duration.value=teacherOtherVisitTime;
  1303. //HiTeach
  1304. //教师访问hiteach 不带学校信息的
  1305. var teacherHiteachVisit = apiVisits.Where(x => !string.IsNullOrWhiteSpace(x.userId) && x.userId.Equals(user.Key) && x.client.Equals("hiteach") && string.IsNullOrWhiteSpace(x.school));
  1306. //教师访问hiteach 包含学校信息的
  1307. var teacherHiteachSchoolVisit = user.Where(x => x.client.Equals("hiteach"));
  1308. //教师所有的Hiteach访问
  1309. List<ApiVisit> teacherHiteachAllVisit = new List<ApiVisit>();
  1310. teacherHiteachAllVisit.AddRange(teacherHiteachVisit);
  1311. teacherHiteachAllVisit.AddRange(teacherHiteachSchoolVisit);
  1312. var teacherHiteachAllVisitCount = teacherHiteachAllVisit.Count();
  1313. if (teacherHiteachAllVisitCount>0)
  1314. { hiteachTch+=1; }
  1315. var teacherHiteachAllVisitTime = GetUserDuration(teacherHiteachAllVisit.OrderBy(x => x.time).Select(x => x.time).ToList());
  1316. hiteachCount+=teacherHiteachAllVisitCount;
  1317. hiteachTime+=teacherHiteachAllVisitTime;
  1318. tchStick.hiteach.count.value=teacherHiteachAllVisitCount;
  1319. tchStick.hiteach.duration.value=teacherHiteachAllVisitTime;
  1320. //IES5
  1321. var teacherIes5Visit = user.Where(x => x.client.Equals("ies5"));
  1322. var teacherIes5VisitCount = teacherIes5Visit.Count();
  1323. if (teacherIes5VisitCount>0)
  1324. { ies5Tch+=1; }
  1325. var teacherIes5VisitTime = GetUserDuration(teacherIes5Visit.OrderBy(x => x.time).Select(x => x.time).ToList());
  1326. ies5TchCount+=teacherIes5VisitCount;
  1327. ies5TchTime+=teacherIes5VisitTime;
  1328. tchStick.ies5Tch.count.value=teacherIes5VisitCount;
  1329. tchStick.ies5Tch.duration.value=teacherIes5VisitTime;
  1330. double lessonCountTch = chinaSchoolKey.ToList().Where(x => x.path.Contains("hiteach/create-lesson") && x.userId.Equals(user.Key)).Count();
  1331. tchStick.lesson.value=lessonCountTch;
  1332. tchStick.teacher.count.value=tchStick.hita.count.value+tchStick.hiteach.count.value+tchStick.ies5Tch.count.value+tchStick.otherTch.count.value;
  1333. tchStick.teacher.duration.value=tchStick.hita.duration.value+tchStick.hiteach.duration.value+tchStick.ies5Tch.duration.value+tchStick.otherTch.duration.value;
  1334. tchStick.hita.userCount=1;
  1335. tchStick.hiteach.userCount=1;
  1336. tchStick.ies5Tch.userCount=1;
  1337. tchStick.otherTch.userCount=1;
  1338. tchStick.teacher.userCount=1;
  1339. //if (tchStick.hita.count.value>0 && tchStick.hita.duration.value>0)
  1340. //{
  1341. // tchStick.hita.stick.value= (tchStick.hita.duration.value/1000/tchStick.hita.count.value * tchStick.hita.count.value/tchStick.teacher.count.value);
  1342. //}
  1343. //if (tchStick.ies5Tch.count.value>0 && tchStick.ies5Tch.duration.value>0)
  1344. //{
  1345. // tchStick.ies5Tch.stick.value= (tchStick.ies5Tch.duration.value/1000/tchStick.ies5Tch.count.value * tchStick.ies5Tch.count.value/tchStick.teacher.count.value);
  1346. //}
  1347. //if (tchStick.otherTch.count.value>0 && tchStick.otherTch.duration.value>0)
  1348. //{
  1349. // tchStick.otherTch.stick.value= (tchStick.otherTch.duration.value/1000/tchStick.otherTch.count.value);
  1350. //}
  1351. //if (tchStick.hiteach.count.value>0 && tchStick.hiteach.duration.value>0)
  1352. //{
  1353. // tchStick.hiteach.stick.value= (tchStick.hiteach.duration.value/1000/tchStick.hiteach.count.value)+(tchStick.lesson.value*100);
  1354. //}
  1355. //if (tchStick.teacher.count.value>0 && tchStick.teacher.duration.value>0)
  1356. //{
  1357. // tchStick.teacher.stick.value= (tchStick.teacher.duration.value/1000/tchStick.teacher.count.value)+ (tchStick.lesson.value*100);
  1358. //}
  1359. #region
  1360. if (tchStick.hita.count.value>0)
  1361. {
  1362. if (min_tch_hita_c ==0)
  1363. {
  1364. min_tch_hita_c= tchStick.hita.count.value;
  1365. }
  1366. else if (min_tch_hita_c>tchStick.hita.count.value)
  1367. {
  1368. min_tch_hita_c=tchStick.hita.count.value;
  1369. }
  1370. if (tchStick.hita.count.value>max_tch_hita_c)
  1371. {
  1372. max_tch_hita_c= tchStick.hita.count.value;
  1373. }
  1374. }
  1375. if (tchStick.hiteach.count.value>0)
  1376. {
  1377. if (min_tch_hiteach_c ==0)
  1378. {
  1379. min_tch_hiteach_c= tchStick.hiteach.count.value;
  1380. }
  1381. else if (min_tch_hiteach_c>tchStick.hiteach.count.value)
  1382. {
  1383. min_tch_hiteach_c=tchStick.hiteach.count.value;
  1384. }
  1385. if (tchStick.hiteach.count.value>max_tch_hiteach_c)
  1386. {
  1387. max_tch_hiteach_c= tchStick.hiteach.count.value;
  1388. }
  1389. }
  1390. if (tchStick.ies5Tch.count.value>0)
  1391. {
  1392. if (min_tch_ies5Tch_c ==0)
  1393. {
  1394. min_tch_ies5Tch_c= tchStick.ies5Tch.count.value;
  1395. }
  1396. else if (min_tch_ies5Tch_c>tchStick.ies5Tch.count.value)
  1397. {
  1398. min_tch_ies5Tch_c=tchStick.ies5Tch.count.value;
  1399. }
  1400. if (tchStick.ies5Tch.count.value>max_tch_ies5Tch_c)
  1401. {
  1402. max_tch_ies5Tch_c= tchStick.ies5Tch.count.value;
  1403. }
  1404. }
  1405. if (tchStick.otherTch.count.value>0)
  1406. {
  1407. if (min_tch_otherTch_c ==0)
  1408. {
  1409. min_tch_otherTch_c= tchStick.otherTch.count.value;
  1410. }
  1411. else if (min_tch_otherTch_c>tchStick.otherTch.count.value)
  1412. {
  1413. min_tch_otherTch_c=tchStick.otherTch.count.value;
  1414. }
  1415. if (tchStick.otherTch.count.value>max_tch_otherTch_c)
  1416. {
  1417. max_tch_otherTch_c= tchStick.otherTch.count.value;
  1418. }
  1419. }
  1420. if (tchStick.hita.duration.value>0)
  1421. {
  1422. if (min_tch_hita_d ==0)
  1423. {
  1424. min_tch_hita_d= tchStick.hita.duration.value;
  1425. }
  1426. else if (min_tch_hita_d>tchStick.hita.duration.value)
  1427. {
  1428. min_tch_hita_d=tchStick.hita.duration.value;
  1429. }
  1430. if (tchStick.hita.duration.value>max_tch_hita_d)
  1431. {
  1432. max_tch_hita_d= tchStick.hita.duration.value;
  1433. }
  1434. }
  1435. if (tchStick.hiteach.duration.value>0)
  1436. {
  1437. if (min_tch_hiteach_d ==0)
  1438. {
  1439. min_tch_hiteach_d= tchStick.hiteach.duration.value;
  1440. }
  1441. else if (min_tch_hiteach_d>tchStick.hiteach.duration.value)
  1442. {
  1443. min_tch_hiteach_d=tchStick.hiteach.duration.value;
  1444. }
  1445. if (tchStick.hiteach.duration.value>max_tch_hiteach_d)
  1446. {
  1447. max_tch_hiteach_d= tchStick.hiteach.duration.value;
  1448. }
  1449. }
  1450. if (tchStick.ies5Tch.duration.value>0)
  1451. {
  1452. if (min_tch_ies5Tch_d ==0)
  1453. {
  1454. min_tch_ies5Tch_d= tchStick.ies5Tch.duration.value;
  1455. }
  1456. else if (min_tch_ies5Tch_d>tchStick.ies5Tch.duration.value)
  1457. {
  1458. min_tch_ies5Tch_d=tchStick.ies5Tch.duration.value;
  1459. }
  1460. if (tchStick.ies5Tch.duration.value>max_tch_ies5Tch_d)
  1461. {
  1462. max_tch_ies5Tch_d= tchStick.ies5Tch.duration.value;
  1463. }
  1464. }
  1465. if (tchStick.otherTch.duration.value>0)
  1466. {
  1467. if (min_tch_otherTch_d ==0)
  1468. {
  1469. min_tch_otherTch_d= tchStick.otherTch.duration.value;
  1470. }
  1471. else if (min_tch_otherTch_d>tchStick.otherTch.duration.value)
  1472. {
  1473. min_tch_otherTch_d=tchStick.otherTch.duration.value;
  1474. }
  1475. if (tchStick.otherTch.duration.value>max_tch_otherTch_d)
  1476. {
  1477. max_tch_otherTch_d= tchStick.otherTch.duration.value;
  1478. }
  1479. }
  1480. #endregion
  1481. stickiness.tchSticks.Add(tchStick);
  1482. }
  1483. 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);
  1484. var studentCount = student.Count();
  1485. foreach (var user in student)
  1486. {
  1487. StuStick stuStick = new StuStick
  1488. {
  1489. id=user.Key,
  1490. school=chinaSchoolKey.Key
  1491. };
  1492. var studentOtherVisit = user.Where(x => !x.client.Equals("ies5"));
  1493. var studentOtherVisitCount = studentOtherVisit.Count();
  1494. if (studentOtherVisitCount>0)
  1495. { otherStu+=1; }
  1496. double studentOtherVisitTime = GetUserDuration(studentOtherVisit.OrderBy(x => x.time).Select(x => x.time).ToList());
  1497. var studentIes5Visit = user.Where(x => x.client.Equals("ies5"));
  1498. var studentIes5VisitCount = studentIes5Visit.Count();
  1499. if (studentIes5VisitCount>0)
  1500. { ies5Stu+=1; }
  1501. double studentIes5VisitTime = GetUserDuration(studentIes5Visit.OrderBy(x => x.time).Select(x => x.time).ToList());
  1502. ies5StuCount+=studentIes5VisitCount;
  1503. ies5StuTime+=studentIes5VisitTime;
  1504. otherStuCount+=studentOtherVisitCount;
  1505. otherStuTime+=studentOtherVisitTime;
  1506. stuStick.ies5Stu.count.value=studentIes5VisitCount;
  1507. stuStick.ies5Stu.duration.value=studentIes5VisitTime;
  1508. stuStick.otherStu.count.value=studentOtherVisitCount;
  1509. stuStick.otherStu.duration.value=studentOtherVisitTime;
  1510. stuStick.student.count.value= stuStick.ies5Stu.count.value+stuStick.otherStu.count.value;
  1511. stuStick.student.duration.value= stuStick.ies5Stu.duration.value+stuStick.otherStu.duration.value;
  1512. stuStick.ies5Stu.userCount=1;
  1513. stuStick.otherStu.userCount=1;
  1514. stuStick.student.userCount=1;
  1515. //if (stuStick.ies5Stu.count.value>0 && stuStick.ies5Stu.duration.value>0)
  1516. //{
  1517. // stuStick.ies5Stu.stick.value= (stuStick.ies5Stu.duration.value/1000/stuStick.ies5Stu.count.value);
  1518. //}
  1519. //if (stuStick.otherStu.count.value>0 && stuStick.otherStu.duration.value>0)
  1520. //{
  1521. // stuStick.otherStu.stick.value=(stuStick.otherStu.duration.value/1000/stuStick.otherStu.count.value);
  1522. //}
  1523. //if (stuStick.student.count.value>0 && stuStick.student.duration.value>0)
  1524. //{
  1525. // stuStick.student.stick.value=(stuStick.student.duration.value/1000/stuStick.student.count.value);
  1526. //}
  1527. #region
  1528. if (stuStick.otherStu.count.value>0)
  1529. {
  1530. if (min_stu_otherStu_c ==0)
  1531. {
  1532. min_stu_otherStu_c= stuStick.otherStu.count.value;
  1533. }
  1534. else if (min_stu_otherStu_c>stuStick.otherStu.count.value)
  1535. {
  1536. min_stu_otherStu_c=stuStick.otherStu.count.value;
  1537. }
  1538. if (stuStick.otherStu.count.value>max_stu_otherStu_c)
  1539. {
  1540. max_stu_otherStu_c= stuStick.otherStu.count.value;
  1541. }
  1542. }
  1543. if (stuStick.ies5Stu.count.value>0)
  1544. {
  1545. if (min_stu_ies5Stu_c ==0)
  1546. {
  1547. min_stu_ies5Stu_c= stuStick.ies5Stu.count.value;
  1548. }
  1549. else if (min_stu_ies5Stu_c>stuStick.ies5Stu.count.value)
  1550. {
  1551. min_stu_ies5Stu_c=stuStick.ies5Stu.count.value;
  1552. }
  1553. if (stuStick.ies5Stu.count.value>max_stu_ies5Stu_c)
  1554. {
  1555. max_stu_ies5Stu_c= stuStick.ies5Stu.count.value;
  1556. }
  1557. }
  1558. if (stuStick.otherStu.duration.value>0)
  1559. {
  1560. if (min_stu_otherStu_d ==0)
  1561. {
  1562. min_stu_otherStu_d= stuStick.otherStu.duration.value;
  1563. }
  1564. else if (min_stu_otherStu_d>stuStick.otherStu.duration.value)
  1565. {
  1566. min_stu_otherStu_d=stuStick.otherStu.duration.value;
  1567. }
  1568. if (stuStick.otherStu.duration.value>max_stu_otherStu_d)
  1569. {
  1570. max_stu_otherStu_d= stuStick.otherStu.duration.value;
  1571. }
  1572. }
  1573. if (stuStick.ies5Stu.duration.value>0)
  1574. {
  1575. if (min_stu_ies5Stu_d ==0)
  1576. {
  1577. min_stu_ies5Stu_d= stuStick.ies5Stu.duration.value;
  1578. }
  1579. else if (min_stu_ies5Stu_d>stuStick.ies5Stu.duration.value)
  1580. {
  1581. min_stu_ies5Stu_d=stuStick.ies5Stu.duration.value;
  1582. }
  1583. if (stuStick.ies5Stu.duration.value>max_stu_ies5Stu_d)
  1584. {
  1585. max_stu_ies5Stu_d= stuStick.ies5Stu.duration.value;
  1586. }
  1587. }
  1588. #endregion
  1589. stickiness.stuSticks.Add(stuStick);
  1590. }
  1591. //时长
  1592. stickiness.hita.duration.value=hitaTime;
  1593. stickiness.hiteach.duration.value=hiteachTime;
  1594. stickiness.otherTch.duration.value=otherTchTime;
  1595. stickiness.ies5Tch.duration.value=ies5TchTime;
  1596. stickiness.ies5Stu.duration.value=ies5StuTime;
  1597. stickiness.otherStu.duration.value=otherStuTime;
  1598. stickiness.teacher.duration.value=hitaTime+hiteachTime+otherTchTime+ies5TchTime;
  1599. stickiness.student.duration.value=otherStuTime+ies5StuTime;
  1600. //用户数
  1601. stickiness.hita.userCount=hitaTch;
  1602. stickiness.hiteach.userCount=hiteachTch;
  1603. stickiness.ies5Tch.userCount=ies5Tch;
  1604. stickiness.otherTch.userCount=otherTch;
  1605. stickiness.ies5Stu.userCount=ies5Stu;
  1606. stickiness.otherStu.userCount=otherStu;
  1607. stickiness.teacher.userCount=teacherCount;
  1608. stickiness.student.userCount=studentCount;
  1609. //访问数
  1610. stickiness.hita.count.value=hitaCount;
  1611. stickiness.hiteach.count.value=hiteachCount;
  1612. stickiness.ies5Tch.count.value=ies5TchCount;
  1613. stickiness.otherTch.count.value=otherTchCount;
  1614. stickiness.ies5Stu.count.value=ies5StuCount;
  1615. stickiness.otherStu.count.value=otherStuCount;
  1616. stickiness.teacher.count.value=hitaCount+hiteachCount+ies5TchCount+otherTchCount;
  1617. stickiness.student.count.value=ies5StuCount+otherStuCount;
  1618. //开课数
  1619. stickiness.lesson.value=lessonCount;
  1620. //if (stickiness.hita.count.value>0 && stickiness.hita.duration.value>0)
  1621. //{
  1622. // stickiness.hita.stick.value=(stickiness.hita.userCount* stickiness.hita.count.value)/(stickiness.hita.duration.value/1000/stickiness.hita.count.value);
  1623. //}
  1624. //if (stickiness.ies5Stu.count.value>0 && stickiness.ies5Stu.duration.value>0)
  1625. //{
  1626. // stickiness.ies5Stu.stick.value=(stickiness.ies5Stu.userCount* stickiness.ies5Stu.count.value)/(stickiness.ies5Stu.duration.value/1000/stickiness.ies5Stu.count.value);
  1627. //}
  1628. //if (stickiness.ies5Tch.count.value>0 && stickiness.ies5Tch.duration.value>0)
  1629. //{
  1630. // stickiness.ies5Tch.stick.value=(stickiness.ies5Tch.userCount* stickiness.ies5Tch.count.value)/(stickiness.ies5Tch.duration.value/1000/stickiness.ies5Tch.count.value);
  1631. //}
  1632. //if (stickiness.otherStu.count.value>0 && stickiness.otherStu.duration.value>0)
  1633. //{
  1634. // stickiness.otherStu.stick.value=(stickiness.otherStu.userCount* stickiness.otherStu.count.value)/(stickiness.otherStu.duration.value/1000/stickiness.otherStu.count.value);
  1635. //}
  1636. //if (stickiness.otherTch.count.value>0 && stickiness.otherTch.duration.value>0)
  1637. //{
  1638. // stickiness.otherTch.stick.value=(stickiness.otherTch.userCount* stickiness.otherTch.count.value)/(stickiness.otherTch.duration.value/1000/stickiness.otherTch.count.value);
  1639. //}
  1640. //if (stickiness.hiteach.count.value>0 && stickiness.hiteach.duration.value>0)
  1641. //{
  1642. // stickiness.hiteach.stick.value=(stickiness.hiteach.userCount* stickiness.hiteach.count.value)/(stickiness.hiteach.duration.value/1000/stickiness.hiteach.count.value)+stickiness.lesson.value;
  1643. //}
  1644. //if (stickiness.teacher.count.value>0 && stickiness.teacher.duration.value>0)
  1645. //{
  1646. // stickiness.teacher.stick.value=(stickiness.teacher.userCount* stickiness.teacher.count.value)/(stickiness.teacher.duration.value/1000/stickiness.teacher.count.value)+ stickiness.lesson.value;
  1647. //}
  1648. //if (stickiness.student.count.value>0 && stickiness.student.duration.value>0)
  1649. //{
  1650. // stickiness.student.stick.value=(stickiness.student.userCount* stickiness.student.count.value)/(stickiness.student.duration.value/1000/stickiness.student.count.value)+ stickiness.lesson.value;
  1651. //}
  1652. #region
  1653. if (stickiness.hita.count.value>0)
  1654. {
  1655. if (min_sch_hita_c ==0)
  1656. {
  1657. min_sch_hita_c= stickiness.hita.count.value;
  1658. }
  1659. else if (min_sch_hita_c>stickiness.hita.count.value)
  1660. {
  1661. min_sch_hita_c=stickiness.hita.count.value;
  1662. }
  1663. if (stickiness.hita.count.value>max_sch_hita_c)
  1664. {
  1665. max_sch_hita_c= stickiness.hita.count.value;
  1666. }
  1667. }
  1668. if (stickiness.hiteach.count.value>0)
  1669. {
  1670. if (min_sch_hiteach_c ==0)
  1671. {
  1672. min_sch_hiteach_c= stickiness.hiteach.count.value;
  1673. }
  1674. else if (min_sch_hiteach_c>stickiness.hiteach.count.value)
  1675. {
  1676. min_sch_hiteach_c=stickiness.hiteach.count.value;
  1677. }
  1678. if (stickiness.hiteach.count.value>max_sch_hiteach_c)
  1679. {
  1680. max_sch_hiteach_c= stickiness.hiteach.count.value;
  1681. }
  1682. }
  1683. if (stickiness.ies5Tch.count.value>0)
  1684. {
  1685. if (min_sch_ies5Tch_c ==0)
  1686. {
  1687. min_sch_ies5Tch_c= stickiness.ies5Tch.count.value;
  1688. }
  1689. else if (min_sch_ies5Tch_c>stickiness.ies5Tch.count.value)
  1690. {
  1691. min_sch_ies5Tch_c=stickiness.ies5Tch.count.value;
  1692. }
  1693. if (stickiness.ies5Tch.count.value>max_sch_ies5Tch_c)
  1694. {
  1695. max_sch_ies5Tch_c= stickiness.ies5Tch.count.value;
  1696. }
  1697. }
  1698. if (stickiness.otherTch.count.value>0)
  1699. {
  1700. if (min_sch_otherTch_c ==0)
  1701. {
  1702. min_sch_otherTch_c= stickiness.otherTch.count.value;
  1703. }
  1704. else if (min_sch_otherTch_c>stickiness.otherTch.count.value)
  1705. {
  1706. min_sch_otherTch_c=stickiness.otherTch.count.value;
  1707. }
  1708. if (stickiness.otherTch.count.value>max_sch_otherTch_c)
  1709. {
  1710. max_sch_otherTch_c= stickiness.otherTch.count.value;
  1711. }
  1712. }
  1713. if (stickiness.otherStu.count.value>0)
  1714. {
  1715. if (min_sch_otherStu_c ==0)
  1716. {
  1717. min_sch_otherStu_c= stickiness.otherStu.count.value;
  1718. }
  1719. else if (min_sch_otherStu_c>stickiness.otherStu.count.value)
  1720. {
  1721. min_sch_otherStu_c=stickiness.otherStu.count.value;
  1722. }
  1723. if (stickiness.otherStu.count.value>max_sch_otherStu_c)
  1724. {
  1725. max_sch_otherStu_c= stickiness.otherStu.count.value;
  1726. }
  1727. }
  1728. if (stickiness.ies5Stu.count.value>0)
  1729. {
  1730. if (min_sch_ies5Stu_c ==0)
  1731. {
  1732. min_sch_ies5Stu_c= stickiness.ies5Stu.count.value;
  1733. }
  1734. else if (min_sch_ies5Stu_c>stickiness.ies5Stu.count.value)
  1735. {
  1736. min_sch_ies5Stu_c=stickiness.ies5Stu.count.value;
  1737. }
  1738. if (stickiness.ies5Stu.count.value>max_sch_ies5Stu_c)
  1739. {
  1740. max_sch_ies5Stu_c= stickiness.ies5Stu.count.value;
  1741. }
  1742. }
  1743. if (stickiness.hita.duration.value>0)
  1744. {
  1745. if (min_sch_hita_d ==0)
  1746. {
  1747. min_sch_hita_d= stickiness.hita.duration.value;
  1748. }
  1749. else if (min_sch_hita_d>stickiness.hita.duration.value)
  1750. {
  1751. min_sch_hita_d=stickiness.hita.duration.value;
  1752. }
  1753. if (stickiness.hita.duration.value>max_sch_hita_d)
  1754. {
  1755. max_sch_hita_d= stickiness.hita.duration.value;
  1756. }
  1757. }
  1758. if (stickiness.hiteach.duration.value>0)
  1759. {
  1760. if (min_sch_hiteach_d ==0)
  1761. {
  1762. min_sch_hiteach_d= stickiness.hiteach.duration.value;
  1763. }
  1764. else if (min_sch_hiteach_d>stickiness.hiteach.duration.value)
  1765. {
  1766. min_sch_hiteach_d=stickiness.hiteach.duration.value;
  1767. }
  1768. if (stickiness.hiteach.duration.value>max_sch_hiteach_d)
  1769. {
  1770. max_sch_hiteach_d= stickiness.hiteach.duration.value;
  1771. }
  1772. }
  1773. if (stickiness.ies5Tch.duration.value>0)
  1774. {
  1775. if (min_sch_ies5Tch_d ==0)
  1776. {
  1777. min_sch_ies5Tch_d= stickiness.ies5Tch.duration.value;
  1778. }
  1779. else if (min_sch_ies5Tch_d>stickiness.ies5Tch.duration.value)
  1780. {
  1781. min_sch_ies5Tch_d=stickiness.ies5Tch.duration.value;
  1782. }
  1783. if (stickiness.ies5Tch.duration.value>max_sch_ies5Tch_d)
  1784. {
  1785. max_sch_ies5Tch_d= stickiness.ies5Tch.duration.value;
  1786. }
  1787. }
  1788. if (stickiness.otherTch.duration.value>0)
  1789. {
  1790. if (min_sch_otherTch_d ==0)
  1791. {
  1792. min_sch_otherTch_d= stickiness.otherTch.duration.value;
  1793. }
  1794. else if (min_sch_otherTch_d>stickiness.otherTch.duration.value)
  1795. {
  1796. min_sch_otherTch_d=stickiness.otherTch.duration.value;
  1797. }
  1798. if (stickiness.otherTch.duration.value>max_sch_otherTch_d)
  1799. {
  1800. max_sch_otherTch_d= stickiness.otherTch.duration.value;
  1801. }
  1802. }
  1803. if (stickiness.otherStu.duration.value>0)
  1804. {
  1805. if (min_sch_otherStu_d ==0)
  1806. {
  1807. min_sch_otherStu_d= stickiness.otherStu.duration.value;
  1808. }
  1809. else if (min_sch_otherStu_d>stickiness.otherStu.duration.value)
  1810. {
  1811. min_sch_otherStu_d=stickiness.otherStu.duration.value;
  1812. }
  1813. if (stickiness.otherStu.duration.value>max_sch_otherStu_d)
  1814. {
  1815. max_sch_otherStu_d= stickiness.otherStu.duration.value;
  1816. }
  1817. }
  1818. if (stickiness.ies5Stu.duration.value>0)
  1819. {
  1820. if (min_sch_ies5Stu_d ==0)
  1821. {
  1822. min_sch_ies5Stu_d= stickiness.ies5Stu.duration.value;
  1823. }
  1824. else if (min_sch_ies5Stu_d>stickiness.ies5Stu.duration.value)
  1825. {
  1826. min_sch_ies5Stu_d=stickiness.ies5Stu.duration.value;
  1827. }
  1828. if (stickiness.ies5Stu.duration.value>max_sch_ies5Stu_d)
  1829. {
  1830. max_sch_ies5Stu_d= stickiness.ies5Stu.duration.value;
  1831. }
  1832. }
  1833. #endregion
  1834. var bygoneStickinessSchool = bygoneStickiness?.Find(x => x.id.Equals(chinaSchoolKey.Key));
  1835. stickiness.tchSticks= OrderByTchStick(stickiness.tchSticks, bygoneStickinessSchool?.tchSticks);
  1836. stickiness.stuSticks= OrderByStuStick(stickiness.stuSticks, bygoneStickinessSchool?.stuSticks);
  1837. schoolStickiness.Add(stickiness);
  1838. }
  1839. return OrderBySchoolStick(schoolStickiness, bygoneStickiness);
  1840. }
  1841. private static List<StuStick> OrderByStuStick(List<StuStick> currentStickiness, List<StuStick>? bygoneStickiness)
  1842. {
  1843. // 假设visit已经填充了数据
  1844. #region
  1845. var rank_tmd_count = currentStickiness.Select(x => x.student.count.value).Distinct().OrderByDescending(v => v).ToList();
  1846. var rank_ies5Stu_count = currentStickiness.Select(x => x.ies5Stu.count.value).Distinct().OrderByDescending(v => v).ToList();
  1847. var rank_otherStu_count = currentStickiness.Select(x => x.otherStu.count.value).Distinct().OrderByDescending(v => v).ToList();
  1848. #endregion
  1849. #region
  1850. var rank_tmd_duration = currentStickiness.Select(x => x.student.duration.value).Distinct().OrderByDescending(v => v).ToList();
  1851. var rank_ies5Stu_duration = currentStickiness.Select(x => x.ies5Stu.duration.value).Distinct().OrderByDescending(v => v).ToList();
  1852. var rank_otherStu_duration = currentStickiness.Select(x => x.otherStu.duration.value).Distinct().OrderByDescending(v => v).ToList();
  1853. #endregion
  1854. #region
  1855. var rank_tmd_stick = currentStickiness.Select(x => x.student.stick.value).Distinct().OrderByDescending(v => v).ToList();
  1856. var rank_ies5Stu_stick = currentStickiness.Select(x => x.ies5Stu.stick.value).Distinct().OrderByDescending(v => v).ToList();
  1857. var rank_otherStu_stick = currentStickiness.Select(x => x.otherStu.stick.value).Distinct().OrderByDescending(v => v).ToList();
  1858. #endregion
  1859. currentStickiness.ForEach(x =>
  1860. {
  1861. #region
  1862. if (x.student.count.value>0)
  1863. {
  1864. int index_tmd_count = rank_tmd_count.FindIndex(i => i==x.student.count.value);
  1865. if (index_tmd_count!=-1)
  1866. {
  1867. x.student.count.rank = index_tmd_count + 1;
  1868. }
  1869. }
  1870. if (x.ies5Stu.count.value>0)
  1871. {
  1872. int index_ies5Stu_count = rank_ies5Stu_count.FindIndex(i => i==x.ies5Stu.count.value);
  1873. if (index_ies5Stu_count!=-1)
  1874. {
  1875. x.ies5Stu.count.rank = index_ies5Stu_count + 1;
  1876. }
  1877. }
  1878. if (x.otherStu.count.value>0)
  1879. {
  1880. int index_otherStu_count = rank_otherStu_count.FindIndex(i => i==x.otherStu.count.value);
  1881. if (index_otherStu_count!=-1)
  1882. {
  1883. x.otherStu.count.rank = index_otherStu_count + 1;
  1884. }
  1885. }
  1886. #endregion
  1887. #region
  1888. if (x.student.duration.value> 0)
  1889. {
  1890. int index_tmd_duration = rank_tmd_duration.FindIndex(i => i==x.student.duration.value);
  1891. if (index_tmd_duration!=-1)
  1892. {
  1893. x.student.duration.rank = index_tmd_duration + 1;
  1894. }
  1895. }
  1896. if (x.ies5Stu.duration.value>0)
  1897. {
  1898. int index_ies5Stu_duration = rank_ies5Stu_duration.FindIndex(i => i==x.ies5Stu.duration.value);
  1899. if (index_ies5Stu_duration!=-1)
  1900. {
  1901. x.ies5Stu.duration.rank = index_ies5Stu_duration + 1;
  1902. }
  1903. }
  1904. if (x.otherStu.duration.value>0)
  1905. {
  1906. int index_otherStu_duration = rank_otherStu_duration.FindIndex(i => i==x.otherStu.duration.value);
  1907. if (index_otherStu_duration!=-1)
  1908. {
  1909. x.otherStu.duration.rank = index_otherStu_duration + 1;
  1910. }
  1911. }
  1912. #endregion
  1913. #region
  1914. if (x.student.stick.value>0)
  1915. {
  1916. int index_tmd_stick = rank_tmd_stick.FindIndex(i => i==x.student.stick.value);
  1917. if (index_tmd_stick!=-1)
  1918. {
  1919. x.student.stick.rank = index_tmd_stick + 1;
  1920. }
  1921. }
  1922. if (x.ies5Stu.stick.value>0)
  1923. {
  1924. int index_ies5Stu_stick = rank_ies5Stu_stick.FindIndex(i => i==x.ies5Stu.stick.value);
  1925. if (index_ies5Stu_stick!=-1)
  1926. {
  1927. x.ies5Stu.stick.rank = index_ies5Stu_stick + 1;
  1928. }
  1929. }
  1930. if (x.otherStu.stick.value>0)
  1931. {
  1932. int index_otherStu_stick = rank_otherStu_stick.FindIndex(i => i==x.otherStu.stick.value);
  1933. if (index_otherStu_stick!=-1)
  1934. {
  1935. x.otherStu.stick.rank = index_otherStu_stick + 1;
  1936. }
  1937. }
  1938. #endregion
  1939. var bygone = bygoneStickiness?.Find(y => y.id.Equals(x.id));
  1940. if (bygone!=null)
  1941. {
  1942. #region tmd
  1943. //人数上升下降
  1944. x.student.userUpdown= x.student.userCount-bygone.student.userCount;
  1945. //访问数量上升下降
  1946. x.student.count.range= x.student.count.value-bygone.student.count.value;
  1947. //访问数量排名上升下降
  1948. x.student.count.updown= -(x.student.count.rank-bygone.student.count.rank);
  1949. //停留时长上升下降
  1950. x.student.duration.range=x.student.duration.value-bygone.student.duration.value;
  1951. //停留时长排名上升下降
  1952. x.student.duration.updown=-(x.student.duration.rank-bygone.student.duration.rank);
  1953. //访问指数上升下降
  1954. x.student.stick.range=x.student.stick.value-bygone.student.stick.value;
  1955. //访问指数排名上升下降
  1956. x.student.stick.updown=-(x.student.stick.rank-bygone.student.stick.rank);
  1957. #endregion
  1958. #region otherStu
  1959. //人数上升下降
  1960. x.otherStu.userUpdown= x.otherStu.userCount-bygone.otherStu.userCount;
  1961. //访问数量上升下降
  1962. x.otherStu.count.range= x.otherStu.count.value-bygone.otherStu.count.value;
  1963. //访问数量排名上升下降
  1964. x.otherStu.count.updown= -(x.otherStu.count.rank-bygone.otherStu.count.rank);
  1965. //停留时长上升下降
  1966. x.otherStu.duration.range=x.otherStu.duration.value-bygone.otherStu.duration.value;
  1967. //停留时长排名上升下降
  1968. x.otherStu.duration.updown=-(x.otherStu.duration.rank - bygone.otherStu.duration.rank);
  1969. //访问指数上升下降
  1970. x.otherStu.stick.range=x.otherStu.stick.value-bygone.otherStu.stick.value;
  1971. //访问指数排名上升下降
  1972. x.otherStu.stick.updown=-(x.otherStu.stick.rank - bygone.otherStu.stick.rank);
  1973. #endregion
  1974. #region ies5Stu
  1975. //人数上升下降
  1976. x.ies5Stu.userUpdown= x.ies5Stu.userCount-bygone.ies5Stu.userCount;
  1977. //访问数量上升下降
  1978. x.ies5Stu.count.range= x.ies5Stu.count.value-bygone.ies5Stu.count.value;
  1979. //访问数量排名上升下降
  1980. x.ies5Stu.count.updown= -(x.ies5Stu.count.rank - bygone.ies5Stu.count.rank);
  1981. //停留时长上升下降
  1982. x.ies5Stu.duration.range=x.ies5Stu.duration.value-bygone.ies5Stu.duration.value;
  1983. //停留时长排名上升下降
  1984. x.ies5Stu.duration.updown=-(x.ies5Stu.duration.rank - bygone.ies5Stu.duration.rank);
  1985. //访问指数上升下降
  1986. x.ies5Stu.stick.range=x.ies5Stu.stick.value-bygone.ies5Stu.stick.value;
  1987. //访问指数排名上升下降
  1988. x.ies5Stu.stick.updown=-(x.ies5Stu.stick.rank - bygone.ies5Stu.stick.rank);
  1989. #endregion
  1990. }
  1991. else
  1992. {
  1993. #region tmd
  1994. //人数上升下降
  1995. x.student.userUpdown= x.student.userCount;
  1996. //访问数量上升下降
  1997. x.student.count.range= x.student.count.value;
  1998. //访问数量排名上升下降
  1999. x.student.count.updown= x.student.count.rank;
  2000. //停留时长上升下降
  2001. x.student.duration.range=x.student.duration.value;
  2002. //停留时长排名上升下降
  2003. x.student.duration.updown=x.student.duration.rank;
  2004. //访问指数上升下降
  2005. x.student.stick.range=x.student.stick.value;
  2006. //访问指数排名上升下降
  2007. x.student.stick.updown=x.student.stick.rank;
  2008. #endregion
  2009. #region otherStu
  2010. //人数上升下降
  2011. x.otherStu.userUpdown= x.otherStu.userCount;
  2012. //访问数量上升下降
  2013. x.otherStu.count.range= x.otherStu.count.value;
  2014. //访问数量排名上升下降
  2015. x.otherStu.count.updown= x.otherStu.count.rank;
  2016. //停留时长上升下降
  2017. x.otherStu.duration.range=x.otherStu.duration.value;
  2018. //停留时长排名上升下降
  2019. x.otherStu.duration.updown=x.otherStu.duration.rank;
  2020. //访问指数上升下降
  2021. x.otherStu.stick.range=x.otherStu.stick.value;
  2022. //访问指数排名上升下降
  2023. x.otherStu.stick.updown=x.otherStu.stick.rank;
  2024. #endregion
  2025. #region ies5Stu
  2026. //人数上升下降
  2027. x.ies5Stu.userUpdown= x.ies5Stu.userCount;
  2028. //访问数量上升下降
  2029. x.ies5Stu.count.range= x.ies5Stu.count.value;
  2030. //访问数量排名上升下降
  2031. x.ies5Stu.count.updown= x.ies5Stu.count.rank;
  2032. //停留时长上升下降
  2033. x.ies5Stu.duration.range=x.ies5Stu.duration.value;
  2034. //停留时长排名上升下降
  2035. x.ies5Stu.duration.updown=x.ies5Stu.duration.rank;
  2036. //访问指数上升下降
  2037. x.ies5Stu.stick.range=x.ies5Stu.stick.value;
  2038. //访问指数排名上升下降
  2039. x.ies5Stu.stick.updown=x.ies5Stu.stick.rank;
  2040. #endregion
  2041. }
  2042. });
  2043. //当前时间没有的
  2044. var disappears = bygoneStickiness?.Where(x => x.student.stick.value!=0).ExceptBy(currentStickiness.Select(x => x.id), y => y.id);
  2045. if (disappears!=null && disappears.Count()>0)
  2046. {
  2047. double rank_tmd_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.student.stick.rank).Max() : 0;
  2048. double rank_tmd_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.student.count.rank).Max() : 0;
  2049. double rank_tmd_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.student.duration.rank).Max() : 0;
  2050. double rank_ies5Stu_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Stu.stick.rank).Max() : 0;
  2051. double rank_ies5Stu_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Stu.count.rank).Max() : 0;
  2052. double rank_ies5Stu_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Stu.duration.rank).Max() : 0;
  2053. double rank_otherStu_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherStu.stick.rank).Max() : 0;
  2054. double rank_otherStu_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherStu.count.rank).Max() : 0;
  2055. double rank_otherStu_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherStu.duration.rank).Max() : 0;
  2056. foreach (var disappear in disappears)
  2057. {
  2058. //下降
  2059. // y 5 t0
  2060. disappear.student.stick.updown= -disappear.student.stick.rank;
  2061. disappear.student.stick.range= -disappear.student.stick.value;
  2062. disappear.student.stick.value=0;
  2063. disappear.student.stick.rank=rank_tmd_stick_Max+1;
  2064. disappear.ies5Stu.stick.updown= -disappear.ies5Stu.stick.rank;
  2065. disappear.ies5Stu.stick.range= -disappear.ies5Stu.stick.value;
  2066. disappear.ies5Stu.stick.value=0;
  2067. disappear.ies5Stu.stick.rank=rank_ies5Stu_stick_Max+1;
  2068. disappear.otherStu.stick.updown= -disappear.otherStu.stick.rank;
  2069. disappear.otherStu.stick.range= -disappear.otherStu.stick.value;
  2070. disappear.otherStu.stick.value=0;
  2071. disappear.otherStu.stick.rank=rank_otherStu_stick_Max+1;
  2072. disappear.student.count.updown= -disappear.student.count.rank;
  2073. disappear.student.count.range= -disappear.student.count.value;
  2074. disappear.student.count.value=0;
  2075. disappear.student.count.rank=rank_tmd_count_Max+1;
  2076. disappear.ies5Stu.count.updown= -disappear.ies5Stu.count.rank;
  2077. disappear.ies5Stu.count.range= -disappear.ies5Stu.count.value;
  2078. disappear.ies5Stu.count.value=0;
  2079. disappear.ies5Stu.count.rank=rank_ies5Stu_count_Max+1;
  2080. disappear.otherStu.count.updown= -disappear.otherStu.count.rank;
  2081. disappear.otherStu.count.range= -disappear.otherStu.count.value;
  2082. disappear.otherStu.count.value=0;
  2083. disappear.otherStu.count.rank=rank_otherStu_count_Max+1;
  2084. disappear.student.duration.updown= -disappear.student.duration.rank;
  2085. disappear.student.duration.range= -disappear.student.duration.value;
  2086. disappear.student.duration.value=0;
  2087. disappear.student.duration.rank=rank_tmd_duration_Max+1;
  2088. disappear.ies5Stu.duration.updown= -disappear.ies5Stu.duration.rank;
  2089. disappear.ies5Stu.duration.range= -disappear.ies5Stu.duration.value;
  2090. disappear.ies5Stu.duration.value=0;
  2091. disappear.ies5Stu.duration.rank=rank_ies5Stu_duration_Max+1;
  2092. disappear.otherStu.duration.updown= -disappear.otherStu.duration.rank;
  2093. disappear.otherStu.duration.range= -disappear.otherStu.duration.value;
  2094. disappear.otherStu.duration.value=0;
  2095. disappear.otherStu.duration.rank=rank_otherStu_duration_Max+1;
  2096. currentStickiness.Add(disappear);
  2097. }
  2098. }
  2099. currentStickiness= currentStickiness.OrderByDescending(x => x.student.stick.value).ToList();
  2100. return currentStickiness;
  2101. }
  2102. private static List<TchStick> OrderByTchStick(List<TchStick> currentStickiness, List<TchStick>? bygoneStickiness)
  2103. {
  2104. // 假设visit已经填充了数据
  2105. #region
  2106. var rank_tmd_count = currentStickiness.Select(x => x.teacher.count.value).Distinct().OrderByDescending(v => v).ToList();
  2107. var rank_hita_count = currentStickiness.Select(x => x.hita.count.value).Distinct().OrderByDescending(v => v).ToList();
  2108. var rank_hiteach_count = currentStickiness.Select(x => x.hiteach.count.value).Distinct().OrderByDescending(v => v).ToList();
  2109. var rank_ies5Tch_count = currentStickiness.Select(x => x.ies5Tch.count.value).Distinct().OrderByDescending(v => v).ToList();
  2110. var rank_otherTch_count = currentStickiness.Select(x => x.otherTch.count.value).Distinct().OrderByDescending(v => v).ToList();
  2111. var rank_lesson_count = currentStickiness.Select(x => x.lesson.value).Distinct().OrderByDescending(v => v).ToList();
  2112. #endregion
  2113. #region
  2114. var rank_tmd_duration = currentStickiness.Select(x => x.teacher.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2115. var rank_hita_duration = currentStickiness.Select(x => x.hita.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2116. var rank_hiteach_duration = currentStickiness.Select(x => x.hiteach.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2117. var rank_ies5Tch_duration = currentStickiness.Select(x => x.ies5Tch.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2118. var rank_otherTch_duration = currentStickiness.Select(x => x.otherTch.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2119. #endregion
  2120. #region
  2121. var rank_tmd_stick = currentStickiness.Select(x => x.teacher.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2122. var rank_hita_stick = currentStickiness.Select(x => x.hita.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2123. var rank_hiteach_stick = currentStickiness.Select(x => x.hiteach.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2124. var rank_ies5Tch_stick = currentStickiness.Select(x => x.ies5Tch.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2125. var rank_otherTch_stick = currentStickiness.Select(x => x.otherTch.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2126. #endregion
  2127. currentStickiness.ForEach(x =>
  2128. {
  2129. #region
  2130. int index_tmd_count = rank_tmd_count.FindIndex(i => i==x.teacher.count.value);
  2131. if (index_tmd_count!=-1)
  2132. {
  2133. x.teacher.count.rank = index_tmd_count + 1;
  2134. }
  2135. int index_hita_count = rank_hita_count.FindIndex(i => i==x.hita.count.value);
  2136. if (index_hita_count!=-1)
  2137. {
  2138. x.hita.count.rank = index_hita_count + 1;
  2139. }
  2140. int index_hiteach_count = rank_hiteach_count.FindIndex(i => i==x.hiteach.count.value);
  2141. if (index_hiteach_count!=-1)
  2142. {
  2143. x.hiteach.count.rank = index_hiteach_count + 1;
  2144. }
  2145. int index_ies5Tch_count = rank_ies5Tch_count.FindIndex(i => i==x.ies5Tch.count.value);
  2146. if (index_ies5Tch_count!=-1)
  2147. {
  2148. x.ies5Tch.count.rank = index_ies5Tch_count + 1;
  2149. }
  2150. int index_otherTch_count = rank_otherTch_count.FindIndex(i => i==x.otherTch.count.value);
  2151. if (index_otherTch_count!=-1)
  2152. {
  2153. x.otherTch.count.rank = index_otherTch_count + 1;
  2154. }
  2155. int index_lesson_count = rank_lesson_count.FindIndex(i => i==x.lesson.value);
  2156. if (index_lesson_count!=-1)
  2157. {
  2158. x.lesson.rank = index_lesson_count + 1;
  2159. }
  2160. #endregion
  2161. #region
  2162. int index_tmd_duration = rank_tmd_duration.FindIndex(i => i==x.teacher.duration.value);
  2163. if (index_tmd_duration!=-1)
  2164. {
  2165. x.teacher.duration.rank = index_tmd_duration + 1;
  2166. }
  2167. int index_hita_duration = rank_hita_duration.FindIndex(i => i==x.hita.duration.value);
  2168. if (index_hita_duration!=-1)
  2169. {
  2170. x.hita.duration.rank = index_hita_duration + 1;
  2171. }
  2172. int index_hiteach_duration = rank_hiteach_duration.FindIndex(i => i==x.hiteach.duration.value);
  2173. if (index_hiteach_duration!=-1)
  2174. {
  2175. x.hiteach.duration.rank = index_hiteach_duration + 1;
  2176. }
  2177. int index_ies5Tch_duration = rank_ies5Tch_duration.FindIndex(i => i==x.ies5Tch.duration.value);
  2178. if (index_ies5Tch_duration!=-1)
  2179. {
  2180. x.ies5Tch.duration.rank = index_ies5Tch_duration + 1;
  2181. }
  2182. int index_otherTch_duration = rank_otherTch_duration.FindIndex(i => i==x.otherTch.duration.value);
  2183. if (index_otherTch_duration!=-1)
  2184. {
  2185. x.otherTch.duration.rank = index_otherTch_duration + 1;
  2186. }
  2187. #endregion
  2188. #region
  2189. int index_tmd_stick = rank_tmd_stick.FindIndex(i => i==x.teacher.stick.value);
  2190. if (index_tmd_stick!=-1)
  2191. {
  2192. x.teacher.stick.rank = index_tmd_stick + 1;
  2193. }
  2194. int index_hita_stick = rank_hita_stick.FindIndex(i => i==x.hita.stick.value);
  2195. if (index_hita_stick!=-1)
  2196. {
  2197. x.hita.stick.rank = index_hita_stick + 1;
  2198. }
  2199. int index_hiteach_stick = rank_hiteach_stick.FindIndex(i => i==x.hiteach.stick.value);
  2200. if (index_hiteach_stick!=-1)
  2201. {
  2202. x.hiteach.stick.rank = index_hiteach_stick + 1;
  2203. }
  2204. int index_ies5Tch_stick = rank_ies5Tch_stick.FindIndex(i => i==x.ies5Tch.stick.value);
  2205. if (index_ies5Tch_stick!=-1)
  2206. {
  2207. x.ies5Tch.stick.rank = index_ies5Tch_stick + 1;
  2208. }
  2209. int index_otherTch_stick = rank_otherTch_stick.FindIndex(i => i==x.otherTch.stick.value);
  2210. if (index_otherTch_stick!=-1)
  2211. {
  2212. x.otherTch.stick.rank = index_otherTch_stick + 1;
  2213. }
  2214. #endregion
  2215. var bygone = bygoneStickiness?.Find(y => y.id.Equals(x.id));
  2216. if (bygone!=null)
  2217. {
  2218. #region
  2219. x.lesson.range=x.lesson.value-bygone.lesson.value;
  2220. x.lesson.updown=x.lesson.rank-bygone.lesson.rank;
  2221. #endregion
  2222. #region tmd
  2223. //人数上升下降
  2224. x.teacher.userUpdown= x.teacher.userCount-bygone.teacher.userCount;
  2225. //访问数量上升下降
  2226. x.teacher.count.range= x.teacher.count.value-bygone.teacher.count.value;
  2227. //访问数量排名上升下降
  2228. x.teacher.count.updown= -(x.teacher.count.rank - bygone.teacher.count.rank);
  2229. //停留时长上升下降
  2230. x.teacher.duration.range=x.teacher.duration.value-bygone.teacher.duration.value;
  2231. //停留时长排名上升下降
  2232. x.teacher.duration.updown=-(x.teacher.duration.rank - bygone.teacher.duration.rank);
  2233. //访问指数上升下降
  2234. x.teacher.stick.range=x.teacher.stick.value-bygone.teacher.stick.value;
  2235. //访问指数排名上升下降
  2236. x.teacher.stick.updown=-(x.teacher.stick.rank - bygone.teacher.stick.rank);
  2237. #endregion
  2238. #region hita
  2239. //人数上升下降
  2240. x.hita.userUpdown= x.hita.userCount-bygone.hita.userCount;
  2241. //访问数量上升下降
  2242. x.hita.count.range= x.hita.count.value-bygone.hita.count.value;
  2243. //访问数量排名上升下降
  2244. x.hita.count.updown= -(x.hita.count.rank - bygone.hita.count.rank);
  2245. //停留时长上升下降
  2246. x.hita.duration.range=x.hita.duration.value-bygone.hita.duration.value;
  2247. //停留时长排名上升下降
  2248. x.hita.duration.updown=-(x.hita.duration.rank - bygone.hita.duration.rank);
  2249. //访问指数上升下降
  2250. x.hita.stick.range=x.hita.stick.value-bygone.hita.stick.value;
  2251. //访问指数排名上升下降
  2252. x.hita.stick.updown=-(x.hita.stick.rank - bygone.hita.stick.rank);
  2253. #endregion
  2254. #region hiteach
  2255. //人数上升下降
  2256. x.hiteach.userUpdown= x.hiteach.userCount-bygone.hiteach.userCount;
  2257. //访问数量上升下降
  2258. x.hiteach.count.range= x.hiteach.count.value-bygone.hiteach.count.value;
  2259. //访问数量排名上升下降
  2260. x.hiteach.count.updown= -(x.hiteach.count.rank - bygone.hiteach.count.rank);
  2261. //停留时长上升下降
  2262. x.hiteach.duration.range=x.hiteach.duration.value-bygone.hiteach.duration.value;
  2263. //停留时长排名上升下降
  2264. x.hiteach.duration.updown=-(x.hiteach.duration.rank - bygone.hiteach.duration.rank);
  2265. //访问指数上升下降
  2266. x.hiteach.stick.range=x.hiteach.stick.value-bygone.hiteach.stick.value;
  2267. //访问指数排名上升下降
  2268. x.hiteach.stick.updown=-(x.hiteach.stick.rank - bygone.hiteach.stick.rank);
  2269. #endregion
  2270. #region otherTch
  2271. //人数上升下降
  2272. x.otherTch.userUpdown= x.otherTch.userCount-bygone.otherTch.userCount;
  2273. //访问数量上升下降
  2274. x.otherTch.count.range= x.otherTch.count.value-bygone.otherTch.count.value;
  2275. //访问数量排名上升下降
  2276. x.otherTch.count.updown= -(x.otherTch.count.rank - bygone.otherTch.count.rank);
  2277. //停留时长上升下降
  2278. x.otherTch.duration.range=x.otherTch.duration.value-bygone.otherTch.duration.value;
  2279. //停留时长排名上升下降
  2280. x.otherTch.duration.updown=-(x.otherTch.duration.rank - bygone.otherTch.duration.rank);
  2281. //访问指数上升下降
  2282. x.otherTch.stick.range=x.otherTch.stick.value-bygone.otherTch.stick.value;
  2283. //访问指数排名上升下降
  2284. x.otherTch.stick.updown=-(x.otherTch.stick.rank - bygone.otherTch.stick.rank);
  2285. #endregion
  2286. #region ies5Tch
  2287. //人数上升下降
  2288. x.ies5Tch.userUpdown= x.ies5Tch.userCount-bygone.ies5Tch.userCount;
  2289. //访问数量上升下降
  2290. x.ies5Tch.count.range= x.ies5Tch.count.value-bygone.ies5Tch.count.value;
  2291. //访问数量排名上升下降
  2292. x.ies5Tch.count.updown= -(x.ies5Tch.count.rank - bygone.ies5Tch.count.rank);
  2293. //停留时长上升下降
  2294. x.ies5Tch.duration.range=x.ies5Tch.duration.value-bygone.ies5Tch.duration.value;
  2295. //停留时长排名上升下降
  2296. x.ies5Tch.duration.updown=-(x.ies5Tch.duration.rank - bygone.ies5Tch.duration.rank);
  2297. //访问指数上升下降
  2298. x.ies5Tch.stick.range=x.ies5Tch.stick.value-bygone.ies5Tch.stick.value;
  2299. //访问指数排名上升下降
  2300. x.ies5Tch.stick.updown=-(x.ies5Tch.stick.rank - bygone.ies5Tch.stick.rank);
  2301. #endregion
  2302. }
  2303. else
  2304. {
  2305. #region
  2306. x.lesson.range=x.lesson.value;
  2307. x.lesson.updown=x.lesson.rank;
  2308. #endregion
  2309. #region tmd
  2310. //人数上升下降
  2311. x.teacher.userUpdown= x.teacher.userCount;
  2312. //访问数量上升下降
  2313. x.teacher.count.range= x.teacher.count.value;
  2314. //访问数量排名上升下降
  2315. x.teacher.count.updown= x.teacher.count.rank;
  2316. //停留时长上升下降
  2317. x.teacher.duration.range=x.teacher.duration.value;
  2318. //停留时长排名上升下降
  2319. x.teacher.duration.updown=x.teacher.duration.rank;
  2320. //访问指数上升下降
  2321. x.teacher.stick.range=x.teacher.stick.value;
  2322. //访问指数排名上升下降
  2323. x.teacher.stick.updown=x.teacher.stick.rank;
  2324. #endregion
  2325. #region hita
  2326. //人数上升下降
  2327. x.hita.userUpdown= x.hita.userCount;
  2328. //访问数量上升下降
  2329. x.hita.count.range= x.hita.count.value;
  2330. //访问数量排名上升下降
  2331. x.hita.count.updown= x.hita.count.rank;
  2332. //停留时长上升下降
  2333. x.hita.duration.range=x.hita.duration.value;
  2334. //停留时长排名上升下降
  2335. x.hita.duration.updown=x.hita.duration.rank;
  2336. //访问指数上升下降
  2337. x.hita.stick.range=x.hita.stick.value;
  2338. //访问指数排名上升下降
  2339. x.hita.stick.updown=x.hita.stick.rank;
  2340. #endregion
  2341. #region hiteach
  2342. //人数上升下降
  2343. x.hiteach.userUpdown= x.hiteach.userCount;
  2344. //访问数量上升下降
  2345. x.hiteach.count.range= x.hiteach.count.value;
  2346. //访问数量排名上升下降
  2347. x.hiteach.count.updown= x.hiteach.count.rank;
  2348. //停留时长上升下降
  2349. x.hiteach.duration.range=x.hiteach.duration.value;
  2350. //停留时长排名上升下降
  2351. x.hiteach.duration.updown=x.hiteach.duration.rank;
  2352. //访问指数上升下降
  2353. x.hiteach.stick.range=x.hiteach.stick.value;
  2354. //访问指数排名上升下降
  2355. x.hiteach.stick.updown=x.hiteach.stick.rank;
  2356. #endregion
  2357. #region otherTch
  2358. //人数上升下降
  2359. x.otherTch.userUpdown= x.otherTch.userCount;
  2360. //访问数量上升下降
  2361. x.otherTch.count.range= x.otherTch.count.value;
  2362. //访问数量排名上升下降
  2363. x.otherTch.count.updown= x.otherTch.count.rank;
  2364. //停留时长上升下降
  2365. x.otherTch.duration.range=x.otherTch.duration.value;
  2366. //停留时长排名上升下降
  2367. x.otherTch.duration.updown=x.otherTch.duration.rank;
  2368. //访问指数上升下降
  2369. x.otherTch.stick.range=x.otherTch.stick.value;
  2370. //访问指数排名上升下降
  2371. x.otherTch.stick.updown=x.otherTch.stick.rank;
  2372. #endregion
  2373. #region ies5Tch
  2374. //人数上升下降
  2375. x.ies5Tch.userUpdown= x.ies5Tch.userCount;
  2376. //访问数量上升下降
  2377. x.ies5Tch.count.range= x.ies5Tch.count.value;
  2378. //访问数量排名上升下降
  2379. x.ies5Tch.count.updown= x.ies5Tch.count.rank;
  2380. //停留时长上升下降
  2381. x.ies5Tch.duration.range=x.ies5Tch.duration.value;
  2382. //停留时长排名上升下降
  2383. x.ies5Tch.duration.updown=x.ies5Tch.duration.rank;
  2384. //访问指数上升下降
  2385. x.ies5Tch.stick.range=x.ies5Tch.stick.value;
  2386. //访问指数排名上升下降
  2387. x.ies5Tch.stick.updown=x.ies5Tch.stick.rank;
  2388. #endregion
  2389. }
  2390. });
  2391. //当前时间没有的
  2392. var disappears = bygoneStickiness?.Where(x => x.teacher.stick.value!=0).ExceptBy(currentStickiness.Select(x => x.id), y => y.id);
  2393. if (disappears!=null && disappears.Count()>0)
  2394. {
  2395. double rank_tmd_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.teacher.stick.rank).Max() : 0;
  2396. double rank_tmd_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.teacher.count.rank).Max() : 0;
  2397. double rank_tmd_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.teacher.duration.rank).Max() : 0;
  2398. double rank_hiteach_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hiteach.stick.rank).Max() : 0;
  2399. double rank_hiteach_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hiteach.count.rank).Max() : 0;
  2400. double rank_hiteach_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hiteach.duration.rank).Max() : 0;
  2401. double rank_hita_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hita.stick.rank).Max() : 0;
  2402. double rank_hita_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hita.count.rank).Max() : 0;
  2403. double rank_hita_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hita.duration.rank).Max() : 0;
  2404. double rank_ies5Tch_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Tch.stick.rank).Max() : 0;
  2405. double rank_ies5Tch_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Tch.count.rank).Max() : 0;
  2406. double rank_ies5Tch_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Tch.duration.rank).Max() : 0;
  2407. double rank_otherTch_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherTch.stick.rank).Max() : 0;
  2408. double rank_otherTch_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherTch.count.rank).Max() : 0;
  2409. double rank_otherTch_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherTch.duration.rank).Max() : 0;
  2410. double rank_lesson_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.lesson.rank).Max() : 0;
  2411. foreach (var disappear in disappears)
  2412. {
  2413. disappear.lesson.updown=-disappear.lesson.rank;
  2414. disappear.lesson.range=-disappear.lesson.value;
  2415. disappear.lesson.value=0;
  2416. disappear.lesson.rank=rank_lesson_Max+1;
  2417. //下降
  2418. // y 5 t0
  2419. disappear.teacher.stick.updown= -disappear.teacher.stick.rank;
  2420. disappear.teacher.stick.range= -disappear.teacher.stick.value;
  2421. disappear.teacher.stick.value=0;
  2422. disappear.teacher.stick.rank=rank_tmd_stick_Max+1;
  2423. disappear.hiteach.stick.updown= -disappear.hiteach.stick.rank;
  2424. disappear.hiteach.stick.range= -disappear.hiteach.stick.value;
  2425. disappear.hiteach.stick.value=0;
  2426. disappear.hiteach.stick.rank=rank_hiteach_stick_Max+1;
  2427. disappear.hita.stick.updown= -disappear.hita.stick.rank;
  2428. disappear.hita.stick.range= -disappear.hita.stick.value;
  2429. disappear.hita.stick.value=0;
  2430. disappear.hita.stick.rank=rank_hita_stick_Max+1;
  2431. disappear.ies5Tch.stick.updown= -disappear.ies5Tch.stick.rank;
  2432. disappear.ies5Tch.stick.range= -disappear.ies5Tch.stick.value;
  2433. disappear.ies5Tch.stick.value=0;
  2434. disappear.ies5Tch.stick.rank=rank_ies5Tch_stick_Max+1;
  2435. disappear.otherTch.stick.updown= -disappear.otherTch.stick.rank;
  2436. disappear.otherTch.stick.range= -disappear.otherTch.stick.value;
  2437. disappear.otherTch.stick.value=0;
  2438. disappear.otherTch.stick.rank=rank_otherTch_stick_Max+1;
  2439. disappear.teacher.count.updown= -disappear.teacher.count.rank;
  2440. disappear.teacher.count.range= -disappear.teacher.count.value;
  2441. disappear.teacher.count.value=0;
  2442. disappear.teacher.count.rank=rank_tmd_count_Max+1;
  2443. disappear.hiteach.count.updown= -disappear.hiteach.count.rank;
  2444. disappear.hiteach.count.range= -disappear.hiteach.count.value;
  2445. disappear.hiteach.count.value=0;
  2446. disappear.hiteach.count.rank=rank_hiteach_count_Max+1;
  2447. disappear.hita.count.updown= -disappear.hita.count.rank;
  2448. disappear.hita.count.range= -disappear.hita.count.value;
  2449. disappear.hita.count.value=0;
  2450. disappear.hita.count.rank=rank_hita_count_Max+1;
  2451. disappear.ies5Tch.count.updown= -disappear.ies5Tch.count.rank;
  2452. disappear.ies5Tch.count.range= -disappear.ies5Tch.count.value;
  2453. disappear.ies5Tch.count.value=0;
  2454. disappear.ies5Tch.count.rank=rank_ies5Tch_count_Max+1;
  2455. disappear.otherTch.count.updown= -disappear.otherTch.count.rank;
  2456. disappear.otherTch.count.range= -disappear.otherTch.count.value;
  2457. disappear.otherTch.count.value=0;
  2458. disappear.otherTch.count.rank=rank_otherTch_count_Max+1;
  2459. disappear.teacher.duration.updown= -disappear.teacher.duration.rank;
  2460. disappear.teacher.duration.range= -disappear.teacher.duration.value;
  2461. disappear.teacher.duration.value=0;
  2462. disappear.teacher.duration.rank=rank_tmd_duration_Max+1;
  2463. disappear.hiteach.duration.updown= -disappear.hiteach.duration.rank;
  2464. disappear.hiteach.duration.range= -disappear.hiteach.duration.value;
  2465. disappear.hiteach.duration.value=0;
  2466. disappear.hiteach.duration.rank=rank_hiteach_duration_Max+1;
  2467. disappear.hita.duration.updown= -disappear.hita.duration.rank;
  2468. disappear.hita.duration.range= -disappear.hita.duration.value;
  2469. disappear.hita.duration.value=0;
  2470. disappear.hita.duration.rank=rank_hita_duration_Max+1;
  2471. disappear.ies5Tch.duration.updown= -disappear.ies5Tch.duration.rank;
  2472. disappear.ies5Tch.duration.range= -disappear.ies5Tch.duration.value;
  2473. disappear.ies5Tch.duration.value=0;
  2474. disappear.ies5Tch.duration.rank=rank_ies5Tch_duration_Max+1;
  2475. disappear.otherTch.duration.updown= -disappear.otherTch.duration.rank;
  2476. disappear.otherTch.duration.range= -disappear.otherTch.duration.value;
  2477. disappear.otherTch.duration.value=0;
  2478. disappear.otherTch.duration.rank=rank_otherTch_duration_Max+1;
  2479. currentStickiness.Add(disappear);
  2480. }
  2481. }
  2482. currentStickiness= currentStickiness.OrderByDescending(x => x.teacher.stick.value).ToList();
  2483. return currentStickiness;
  2484. }
  2485. /// <summary>
  2486. ///
  2487. /// </summary>
  2488. /// <param name="currentStickiness">现在的</param>
  2489. /// <param name="bygoneStickiness">过去的</param>
  2490. /// <returns></returns>
  2491. private static List<SchoolStick> OrderBySchoolStick(List<SchoolStick> currentStickiness, List<SchoolStick>? bygoneStickiness)
  2492. {
  2493. // 假设visit已经填充了数据
  2494. #region
  2495. var rank_teacher_count = currentStickiness.Select(x => x.teacher.count.value).Distinct().OrderByDescending(v => v).ToList();
  2496. var rank_student_count = currentStickiness.Select(x => x.student.count.value).Distinct().OrderByDescending(v => v).ToList();
  2497. var rank_hita_count = currentStickiness.Select(x => x.hita.count.value).Distinct().OrderByDescending(v => v).ToList();
  2498. var rank_hiteach_count = currentStickiness.Select(x => x.hiteach.count.value).Distinct().OrderByDescending(v => v).ToList();
  2499. var rank_ies5Tch_count = currentStickiness.Select(x => x.ies5Tch.count.value).Distinct().OrderByDescending(v => v).ToList();
  2500. var rank_otherTch_count = currentStickiness.Select(x => x.otherTch.count.value).Distinct().OrderByDescending(v => v).ToList();
  2501. var rank_ies5Stu_count = currentStickiness.Select(x => x.ies5Stu.count.value).Distinct().OrderByDescending(v => v).ToList();
  2502. var rank_otherStu_count = currentStickiness.Select(x => x.otherStu.count.value).Distinct().OrderByDescending(v => v).ToList();
  2503. var rank_lesson_count = currentStickiness.Select(x => x.lesson.value).Distinct().OrderByDescending(v => v).ToList();
  2504. #endregion
  2505. #region
  2506. var rank_teacher_duration = currentStickiness.Select(x => x.teacher.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2507. var rank_student_duration = currentStickiness.Select(x => x.student.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2508. var rank_hita_duration = currentStickiness.Select(x => x.hita.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2509. var rank_hiteach_duration = currentStickiness.Select(x => x.hiteach.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2510. var rank_ies5Tch_duration = currentStickiness.Select(x => x.ies5Tch.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2511. var rank_otherTch_duration = currentStickiness.Select(x => x.otherTch.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2512. var rank_ies5Stu_duration = currentStickiness.Select(x => x.ies5Stu.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2513. var rank_otherStu_duration = currentStickiness.Select(x => x.otherStu.duration.value).Distinct().OrderByDescending(v => v).ToList();
  2514. #endregion
  2515. #region
  2516. var rank_teacher_stick = currentStickiness.Select(x => x.teacher.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2517. var rank_student_stick = currentStickiness.Select(x => x.student.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2518. var rank_hita_stick = currentStickiness.Select(x => x.hita.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2519. var rank_hiteach_stick = currentStickiness.Select(x => x.hiteach.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2520. var rank_ies5Tch_stick = currentStickiness.Select(x => x.ies5Tch.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2521. var rank_otherTch_stick = currentStickiness.Select(x => x.otherTch.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2522. var rank_ies5Stu_stick = currentStickiness.Select(x => x.ies5Stu.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2523. var rank_otherStu_stick = currentStickiness.Select(x => x.otherStu.stick.value).Distinct().OrderByDescending(v => v).ToList();
  2524. #endregion
  2525. currentStickiness.ForEach(x =>
  2526. {
  2527. #region
  2528. if (x.teacher.count.value>0)
  2529. {
  2530. int index_teacher_count = rank_teacher_count.FindIndex(i => i==x.teacher.count.value);
  2531. if (index_teacher_count!=-1)
  2532. {
  2533. x.teacher.count.rank = index_teacher_count + 1;
  2534. }
  2535. }
  2536. if (x.student.count.value>0)
  2537. {
  2538. int index_student_count = rank_student_count.FindIndex(i => i==x.student.count.value);
  2539. if (index_student_count!=-1)
  2540. {
  2541. x.student.count.rank = index_student_count + 1;
  2542. }
  2543. }
  2544. if (x.hita.count.value>0)
  2545. {
  2546. int index_hita_count = rank_hita_count.FindIndex(i => i==x.hita.count.value);
  2547. if (index_hita_count!=-1)
  2548. {
  2549. x.hita.count.rank = index_hita_count + 1;
  2550. }
  2551. }
  2552. if (x.hiteach.count.value>0)
  2553. {
  2554. int index_hiteach_count = rank_hiteach_count.FindIndex(i => i==x.hiteach.count.value);
  2555. if (index_hiteach_count!=-1)
  2556. {
  2557. x.hiteach.count.rank = index_hiteach_count + 1;
  2558. }
  2559. }
  2560. if (x.ies5Tch.count.value>0)
  2561. {
  2562. int index_ies5Tch_count = rank_ies5Tch_count.FindIndex(i => i==x.ies5Tch.count.value);
  2563. if (index_ies5Tch_count!=-1)
  2564. {
  2565. x.ies5Tch.count.rank = index_ies5Tch_count + 1;
  2566. }
  2567. }
  2568. if (x.otherTch.count.value>0)
  2569. {
  2570. int index_otherTch_count = rank_otherTch_count.FindIndex(i => i==x.otherTch.count.value);
  2571. if (index_otherTch_count!=-1)
  2572. {
  2573. x.otherTch.count.rank = index_otherTch_count + 1;
  2574. }
  2575. }
  2576. if (x.ies5Stu.count.value>0)
  2577. {
  2578. int index_ies5Stu_count = rank_ies5Stu_count.FindIndex(i => i==x.ies5Stu.count.value);
  2579. if (index_ies5Stu_count!=-1)
  2580. {
  2581. x.ies5Stu.count.rank = index_ies5Stu_count + 1;
  2582. }
  2583. }
  2584. if (x.otherStu.count.value>0)
  2585. {
  2586. int index_otherStu_count = rank_otherStu_count.FindIndex(i => i==x.otherStu.count.value);
  2587. if (index_otherStu_count!=-1)
  2588. {
  2589. x.otherStu.count.rank = index_otherStu_count + 1;
  2590. }
  2591. }
  2592. if (x.lesson.value>0)
  2593. {
  2594. int index_lesson_count = rank_lesson_count.FindIndex(i => i==x.lesson.value);
  2595. if (index_lesson_count!=-1)
  2596. {
  2597. x.lesson.rank = index_lesson_count + 1;
  2598. }
  2599. }
  2600. #endregion
  2601. #region
  2602. if (x.teacher.duration.value>0)
  2603. {
  2604. int index_teacher_duration = rank_teacher_duration.FindIndex(i => i==x.teacher.duration.value);
  2605. if (index_teacher_duration!=-1)
  2606. {
  2607. x.teacher.duration.rank = index_teacher_duration + 1;
  2608. }
  2609. }
  2610. if (x.student.duration.value>0)
  2611. {
  2612. int index_student_duration = rank_student_duration.FindIndex(i => i==x.student.duration.value);
  2613. if (index_student_duration!=-1)
  2614. {
  2615. x.student.duration.rank = index_student_duration + 1;
  2616. }
  2617. }
  2618. if (x.hita.duration.value>0)
  2619. {
  2620. int index_hita_duration = rank_hita_duration.FindIndex(i => i==x.hita.duration.value);
  2621. if (index_hita_duration!=-1)
  2622. {
  2623. x.hita.duration.rank = index_hita_duration + 1;
  2624. }
  2625. }
  2626. if (x.hiteach.duration.value>0)
  2627. {
  2628. int index_hiteach_duration = rank_hiteach_duration.FindIndex(i => i==x.hiteach.duration.value);
  2629. if (index_hiteach_duration!=-1)
  2630. {
  2631. x.hiteach.duration.rank = index_hiteach_duration + 1;
  2632. }
  2633. }
  2634. if (x.ies5Tch.duration.value>0)
  2635. {
  2636. int index_ies5Tch_duration = rank_ies5Tch_duration.FindIndex(i => i==x.ies5Tch.duration.value);
  2637. if (index_ies5Tch_duration!=-1)
  2638. {
  2639. x.ies5Tch.duration.rank = index_ies5Tch_duration + 1;
  2640. }
  2641. }
  2642. if (x.otherTch.duration.value>0)
  2643. {
  2644. int index_otherTch_duration = rank_otherTch_duration.FindIndex(i => i==x.otherTch.duration.value);
  2645. if (index_otherTch_duration!=-1)
  2646. {
  2647. x.otherTch.duration.rank = index_otherTch_duration + 1;
  2648. }
  2649. }
  2650. if (x.ies5Stu.duration.value>0)
  2651. {
  2652. int index_ies5Stu_duration = rank_ies5Stu_duration.FindIndex(i => i==x.ies5Stu.duration.value);
  2653. if (index_ies5Stu_duration!=-1)
  2654. {
  2655. x.ies5Stu.duration.rank = index_ies5Stu_duration + 1;
  2656. }
  2657. }
  2658. if (x.otherStu.duration.value>0)
  2659. {
  2660. int index_otherStu_duration = rank_otherStu_duration.FindIndex(i => i==x.otherStu.duration.value);
  2661. if (index_otherStu_duration!=-1)
  2662. {
  2663. x.otherStu.duration.rank = index_otherStu_duration + 1;
  2664. }
  2665. }
  2666. #endregion
  2667. #region
  2668. if (x.teacher.stick.value>0)
  2669. {
  2670. int index_teacher_stick = rank_teacher_stick.FindIndex(i => i==x.teacher.stick.value);
  2671. if (index_teacher_stick!=-1)
  2672. {
  2673. x.teacher.stick.rank = index_teacher_stick + 1;
  2674. }
  2675. }
  2676. if (x.student.stick.value>0)
  2677. {
  2678. int index_student_stick = rank_student_stick.FindIndex(i => i==x.student.stick.value);
  2679. if (index_student_stick!=-1)
  2680. {
  2681. x.student.stick.rank = index_student_stick + 1;
  2682. }
  2683. }
  2684. if (x.hita.stick.value>0)
  2685. {
  2686. int index_hita_stick = rank_hita_stick.FindIndex(i => i==x.hita.stick.value);
  2687. if (index_hita_stick!=-1)
  2688. {
  2689. x.hita.stick.rank = index_hita_stick + 1;
  2690. }
  2691. }
  2692. if (x.hiteach.stick.value>0)
  2693. {
  2694. int index_hiteach_stick = rank_hiteach_stick.FindIndex(i => i==x.hiteach.stick.value);
  2695. if (index_hiteach_stick!=-1)
  2696. {
  2697. x.hiteach.stick.rank = index_hiteach_stick + 1;
  2698. }
  2699. }
  2700. if (x.ies5Tch.stick.value>0)
  2701. {
  2702. int index_ies5Tch_stick = rank_ies5Tch_stick.FindIndex(i => i==x.ies5Tch.stick.value);
  2703. if (index_ies5Tch_stick!=-1)
  2704. {
  2705. x.ies5Tch.stick.rank = index_ies5Tch_stick + 1;
  2706. }
  2707. }
  2708. if (x.otherTch.stick.value>0)
  2709. {
  2710. int index_otherTch_stick = rank_otherTch_stick.FindIndex(i => i==x.otherTch.stick.value);
  2711. if (index_otherTch_stick!=-1)
  2712. {
  2713. x.otherTch.stick.rank = index_otherTch_stick + 1;
  2714. }
  2715. }
  2716. if (x.ies5Stu.stick.value>0)
  2717. {
  2718. int index_ies5Stu_stick = rank_ies5Stu_stick.FindIndex(i => i==x.ies5Stu.stick.value);
  2719. if (index_ies5Stu_stick!=-1)
  2720. {
  2721. x.ies5Stu.stick.rank = index_ies5Stu_stick + 1;
  2722. }
  2723. }
  2724. if (x.otherStu.stick.value>0)
  2725. {
  2726. int index_otherStu_stick = rank_otherStu_stick.FindIndex(i => i==x.otherStu.stick.value);
  2727. if (index_otherStu_stick!=-1)
  2728. {
  2729. x.otherStu.stick.rank = index_otherStu_stick + 1;
  2730. }
  2731. }
  2732. #endregion
  2733. var bygone = bygoneStickiness?.Find(y => y.id.Equals(x.id));
  2734. if (bygone!=null)
  2735. {
  2736. #region
  2737. x.lesson.range=x.lesson.value-bygone.lesson.value;
  2738. x.lesson.updown=x.lesson.rank-bygone.lesson.rank;
  2739. #endregion
  2740. #region student
  2741. //人数上升下降
  2742. x.student.userUpdown= x.student.userCount-bygone.student.userCount;
  2743. //访问数量上升下降
  2744. x.student.count.range= x.student.count.value-bygone.student.count.value;
  2745. //访问数量排名上升下降
  2746. x.student.count.updown= -(x.student.count.rank - bygone.student.count.rank);
  2747. //停留时长上升下降
  2748. x.student.duration.range=x.student.duration.value-bygone.student.duration.value;
  2749. //停留时长排名上升下降
  2750. x.student.duration.updown=-(x.student.duration.rank - bygone.student.duration.rank);
  2751. //访问指数上升下降
  2752. x.student.stick.range=x.student.stick.value-bygone.student.stick.value;
  2753. //访问指数排名上升下降
  2754. x.student.stick.updown=-(x.student.stick.rank - bygone.student.stick.rank);
  2755. #endregion
  2756. #region teacher
  2757. //人数上升下降
  2758. x.teacher.userUpdown= x.teacher.userCount-bygone.teacher.userCount;
  2759. //访问数量上升下降
  2760. x.teacher.count.range= x.teacher.count.value-bygone.teacher.count.value;
  2761. //访问数量排名上升下降
  2762. x.teacher.count.updown= -(x.teacher.count.rank - bygone.teacher.count.rank);
  2763. //停留时长上升下降
  2764. x.teacher.duration.range=x.teacher.duration.value-bygone.teacher.duration.value;
  2765. //停留时长排名上升下降
  2766. x.teacher.duration.updown=-(x.teacher.duration.rank - bygone.teacher.duration.rank);
  2767. //访问指数上升下降
  2768. x.teacher.stick.range=x.teacher.stick.value-bygone.teacher.stick.value;
  2769. //访问指数排名上升下降
  2770. x.teacher.stick.updown=-(x.teacher.stick.rank - bygone.teacher.stick.rank);
  2771. #endregion
  2772. #region hita
  2773. //人数上升下降
  2774. x.hita.userUpdown= x.hita.userCount-bygone.hita.userCount;
  2775. //访问数量上升下降
  2776. x.hita.count.range= x.hita.count.value-bygone.hita.count.value;
  2777. //访问数量排名上升下降
  2778. x.hita.count.updown= -(x.hita.count.rank - bygone.hita.count.rank);
  2779. //停留时长上升下降
  2780. x.hita.duration.range=x.hita.duration.value-bygone.hita.duration.value;
  2781. //停留时长排名上升下降
  2782. x.hita.duration.updown=-(x.hita.duration.rank - bygone.hita.duration.rank);
  2783. //访问指数上升下降
  2784. x.hita.stick.range=x.hita.stick.value-bygone.hita.stick.value;
  2785. //访问指数排名上升下降
  2786. x.hita.stick.updown=-(x.hita.stick.rank - bygone.hita.stick.rank);
  2787. #endregion
  2788. #region hiteach
  2789. //人数上升下降
  2790. x.hiteach.userUpdown= x.hiteach.userCount-bygone.hiteach.userCount;
  2791. //访问数量上升下降
  2792. x.hiteach.count.range= x.hiteach.count.value-bygone.hiteach.count.value;
  2793. //访问数量排名上升下降
  2794. x.hiteach.count.updown= -(x.hiteach.count.rank - bygone.hiteach.count.rank);
  2795. //停留时长上升下降
  2796. x.hiteach.duration.range=x.hiteach.duration.value-bygone.hiteach.duration.value;
  2797. //停留时长排名上升下降
  2798. x.hiteach.duration.updown=-(x.hiteach.duration.rank - bygone.hiteach.duration.rank);
  2799. //访问指数上升下降
  2800. x.hiteach.stick.range=x.hiteach.stick.value-bygone.hiteach.stick.value;
  2801. //访问指数排名上升下降
  2802. x.hiteach.stick.updown=-(x.hiteach.stick.rank - bygone.hiteach.stick.rank);
  2803. #endregion
  2804. #region otherTch
  2805. //人数上升下降
  2806. x.otherTch.userUpdown= x.otherTch.userCount-bygone.otherTch.userCount;
  2807. //访问数量上升下降
  2808. x.otherTch.count.range= x.otherTch.count.value-bygone.otherTch.count.value;
  2809. //访问数量排名上升下降
  2810. x.otherTch.count.updown= -(x.otherTch.count.rank - bygone.otherTch.count.rank);
  2811. //停留时长上升下降
  2812. x.otherTch.duration.range=x.otherTch.duration.value-bygone.otherTch.duration.value;
  2813. //停留时长排名上升下降
  2814. x.otherTch.duration.updown=-(x.otherTch.duration.rank - bygone.otherTch.duration.rank);
  2815. //访问指数上升下降
  2816. x.otherTch.stick.range=x.otherTch.stick.value-bygone.otherTch.stick.value;
  2817. //访问指数排名上升下降
  2818. x.otherTch.stick.updown=-(x.otherTch.stick.rank - bygone.otherTch.stick.rank);
  2819. #endregion
  2820. #region otherStu
  2821. //人数上升下降
  2822. x.otherStu.userUpdown= x.otherStu.userCount-bygone.otherStu.userCount;
  2823. //访问数量上升下降
  2824. x.otherStu.count.range= x.otherStu.count.value-bygone.otherStu.count.value;
  2825. //访问数量排名上升下降
  2826. x.otherStu.count.updown= -(x.otherStu.count.rank - bygone.otherStu.count.rank);
  2827. //停留时长上升下降
  2828. x.otherStu.duration.range=x.otherStu.duration.value-bygone.otherStu.duration.value;
  2829. //停留时长排名上升下降
  2830. x.otherStu.duration.updown=-(x.otherStu.duration.rank - bygone.otherStu.duration.rank);
  2831. //访问指数上升下降
  2832. x.otherStu.stick.range=x.otherStu.stick.value-bygone.otherStu.stick.value;
  2833. //访问指数排名上升下降
  2834. x.otherStu.stick.updown=-(x.otherStu.stick.rank - bygone.otherStu.stick.rank);
  2835. #endregion
  2836. #region ies5Stu
  2837. //人数上升下降
  2838. x.ies5Stu.userUpdown= x.ies5Stu.userCount-bygone.ies5Stu.userCount;
  2839. //访问数量上升下降
  2840. x.ies5Stu.count.range= x.ies5Stu.count.value-bygone.ies5Stu.count.value;
  2841. //访问数量排名上升下降
  2842. x.ies5Stu.count.updown= -(x.ies5Stu.count.rank - bygone.ies5Stu.count.rank);
  2843. //停留时长上升下降
  2844. x.ies5Stu.duration.range=x.ies5Stu.duration.value-bygone.ies5Stu.duration.value;
  2845. //停留时长排名上升下降
  2846. x.ies5Stu.duration.updown=-(x.ies5Stu.duration.rank - bygone.ies5Stu.duration.rank);
  2847. //访问指数上升下降
  2848. x.ies5Stu.stick.range=x.ies5Stu.stick.value-bygone.ies5Stu.stick.value;
  2849. //访问指数排名上升下降
  2850. x.ies5Stu.stick.updown=-(x.ies5Stu.stick.rank - bygone.ies5Stu.stick.rank);
  2851. #endregion
  2852. #region ies5Tch
  2853. //人数上升下降
  2854. x.ies5Tch.userUpdown= x.ies5Tch.userCount-bygone.ies5Tch.userCount;
  2855. //访问数量上升下降
  2856. x.ies5Tch.count.range= x.ies5Tch.count.value-bygone.ies5Tch.count.value;
  2857. //访问数量排名上升下降
  2858. x.ies5Tch.count.updown= -(x.ies5Tch.count.rank - bygone.ies5Tch.count.rank);
  2859. //停留时长上升下降
  2860. x.ies5Tch.duration.range=x.ies5Tch.duration.value-bygone.ies5Tch.duration.value;
  2861. //停留时长排名上升下降
  2862. x.ies5Tch.duration.updown=-(x.ies5Tch.duration.rank - bygone.ies5Tch.duration.rank);
  2863. //访问指数上升下降
  2864. x.ies5Tch.stick.range=x.ies5Tch.stick.value-bygone.ies5Tch.stick.value;
  2865. //访问指数排名上升下降
  2866. x.ies5Tch.stick.updown=-(x.ies5Tch.stick.rank - bygone.ies5Tch.stick.rank);
  2867. #endregion
  2868. }
  2869. else
  2870. {
  2871. #region
  2872. x.lesson.range=x.lesson.value;
  2873. x.lesson.updown=x.lesson.rank;
  2874. #endregion
  2875. #region teacher
  2876. //人数上升下降
  2877. x.teacher.userUpdown= x.teacher.userCount;
  2878. //访问数量上升下降
  2879. x.teacher.count.range= x.teacher.count.value;
  2880. //访问数量排名上升下降
  2881. x.teacher.count.updown= x.teacher.count.rank;
  2882. //停留时长上升下降
  2883. x.teacher.duration.range=x.teacher.duration.value;
  2884. //停留时长排名上升下降
  2885. x.teacher.duration.updown=x.teacher.duration.rank;
  2886. //访问指数上升下降
  2887. x.teacher.stick.range=x.teacher.stick.value;
  2888. //访问指数排名上升下降
  2889. x.teacher.stick.updown=x.teacher.stick.rank;
  2890. #endregion
  2891. #region student
  2892. //人数上升下降
  2893. x.student.userUpdown= x.student.userCount;
  2894. //访问数量上升下降
  2895. x.student.count.range= x.student.count.value;
  2896. //访问数量排名上升下降
  2897. x.student.count.updown= x.student.count.rank;
  2898. //停留时长上升下降
  2899. x.student.duration.range=x.student.duration.value;
  2900. //停留时长排名上升下降
  2901. x.student.duration.updown=x.student.duration.rank;
  2902. //访问指数上升下降
  2903. x.student.stick.range=x.student.stick.value;
  2904. //访问指数排名上升下降
  2905. x.student.stick.updown=x.student.stick.rank;
  2906. #endregion
  2907. #region hita
  2908. //人数上升下降
  2909. x.hita.userUpdown= x.hita.userCount;
  2910. //访问数量上升下降
  2911. x.hita.count.range= x.hita.count.value;
  2912. //访问数量排名上升下降
  2913. x.hita.count.updown= x.hita.count.rank;
  2914. //停留时长上升下降
  2915. x.hita.duration.range=x.hita.duration.value;
  2916. //停留时长排名上升下降
  2917. x.hita.duration.updown=x.hita.duration.rank;
  2918. //访问指数上升下降
  2919. x.hita.stick.range=x.hita.stick.value;
  2920. //访问指数排名上升下降
  2921. x.hita.stick.updown=x.hita.stick.rank;
  2922. #endregion
  2923. #region hiteach
  2924. //人数上升下降
  2925. x.hiteach.userUpdown= x.hiteach.userCount;
  2926. //访问数量上升下降
  2927. x.hiteach.count.range= x.hiteach.count.value;
  2928. //访问数量排名上升下降
  2929. x.hiteach.count.updown= x.hiteach.count.rank;
  2930. //停留时长上升下降
  2931. x.hiteach.duration.range=x.hiteach.duration.value;
  2932. //停留时长排名上升下降
  2933. x.hiteach.duration.updown=x.hiteach.duration.rank;
  2934. //访问指数上升下降
  2935. x.hiteach.stick.range=x.hiteach.stick.value;
  2936. //访问指数排名上升下降
  2937. x.hiteach.stick.updown=x.hiteach.stick.rank;
  2938. #endregion
  2939. #region otherTch
  2940. //人数上升下降
  2941. x.otherTch.userUpdown= x.otherTch.userCount;
  2942. //访问数量上升下降
  2943. x.otherTch.count.range= x.otherTch.count.value;
  2944. //访问数量排名上升下降
  2945. x.otherTch.count.updown= x.otherTch.count.rank;
  2946. //停留时长上升下降
  2947. x.otherTch.duration.range=x.otherTch.duration.value;
  2948. //停留时长排名上升下降
  2949. x.otherTch.duration.updown=x.otherTch.duration.rank;
  2950. //访问指数上升下降
  2951. x.otherTch.stick.range=x.otherTch.stick.value;
  2952. //访问指数排名上升下降
  2953. x.otherTch.stick.updown=x.otherTch.stick.rank;
  2954. #endregion
  2955. #region otherStu
  2956. //人数上升下降
  2957. x.otherStu.userUpdown= x.otherStu.userCount;
  2958. //访问数量上升下降
  2959. x.otherStu.count.range= x.otherStu.count.value;
  2960. //访问数量排名上升下降
  2961. x.otherStu.count.updown= x.otherStu.count.rank;
  2962. //停留时长上升下降
  2963. x.otherStu.duration.range=x.otherStu.duration.value;
  2964. //停留时长排名上升下降
  2965. x.otherStu.duration.updown=x.otherStu.duration.rank;
  2966. //访问指数上升下降
  2967. x.otherStu.stick.range=x.otherStu.stick.value;
  2968. //访问指数排名上升下降
  2969. x.otherStu.stick.updown=x.otherStu.stick.rank;
  2970. #endregion
  2971. #region ies5Stu
  2972. //人数上升下降
  2973. x.ies5Stu.userUpdown= x.ies5Stu.userCount;
  2974. //访问数量上升下降
  2975. x.ies5Stu.count.range= x.ies5Stu.count.value;
  2976. //访问数量排名上升下降
  2977. x.ies5Stu.count.updown= x.ies5Stu.count.rank;
  2978. //停留时长上升下降
  2979. x.ies5Stu.duration.range=x.ies5Stu.duration.value;
  2980. //停留时长排名上升下降
  2981. x.ies5Stu.duration.updown=x.ies5Stu.duration.rank;
  2982. //访问指数上升下降
  2983. x.ies5Stu.stick.range=x.ies5Stu.stick.value;
  2984. //访问指数排名上升下降
  2985. x.ies5Stu.stick.updown=x.ies5Stu.stick.rank;
  2986. #endregion
  2987. #region ies5Tch
  2988. //人数上升下降
  2989. x.ies5Tch.userUpdown= x.ies5Tch.userCount;
  2990. //访问数量上升下降
  2991. x.ies5Tch.count.range= x.ies5Tch.count.value;
  2992. //访问数量排名上升下降
  2993. x.ies5Tch.count.updown= x.ies5Tch.count.rank;
  2994. //停留时长上升下降
  2995. x.ies5Tch.duration.range=x.ies5Tch.duration.value;
  2996. //停留时长排名上升下降
  2997. x.ies5Tch.duration.updown=x.ies5Tch.duration.rank;
  2998. //访问指数上升下降
  2999. x.ies5Tch.stick.range=x.ies5Tch.stick.value;
  3000. //访问指数排名上升下降
  3001. x.ies5Tch.stick.updown=x.ies5Tch.stick.rank;
  3002. #endregion
  3003. }
  3004. });
  3005. //当前时间没有的
  3006. var disappears = bygoneStickiness?.Where(x => x.teacher.stick.value!=0).ExceptBy(currentStickiness.Select(x => x.id), y => y.id);
  3007. if (disappears!=null && disappears.Count()>0)
  3008. {
  3009. double rank_student_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.student.stick.rank).Max() : 0;
  3010. double rank_student_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.student.count.rank).Max() : 0;
  3011. double rank_student_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.student.duration.rank).Max() : 0;
  3012. double rank_teacher_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.teacher.stick.rank).Max() : 0;
  3013. double rank_teacher_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.teacher.count.rank).Max() : 0;
  3014. double rank_teacher_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.teacher.duration.rank).Max() : 0;
  3015. double rank_hiteach_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hiteach.stick.rank).Max() : 0;
  3016. double rank_hiteach_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hiteach.count.rank).Max() : 0;
  3017. double rank_hiteach_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hiteach.duration.rank).Max() : 0;
  3018. double rank_hita_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hita.stick.rank).Max() : 0;
  3019. double rank_hita_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hita.count.rank).Max() : 0;
  3020. double rank_hita_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.hita.duration.rank).Max() : 0;
  3021. double rank_ies5Stu_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Stu.stick.rank).Max() : 0;
  3022. double rank_ies5Stu_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Stu.count.rank).Max() : 0;
  3023. double rank_ies5Stu_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Stu.duration.rank).Max() : 0;
  3024. double rank_ies5Tch_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Tch.stick.rank).Max() : 0;
  3025. double rank_ies5Tch_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Tch.count.rank).Max() : 0;
  3026. double rank_ies5Tch_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.ies5Tch.duration.rank).Max() : 0;
  3027. double rank_otherStu_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherStu.stick.rank).Max() : 0;
  3028. double rank_otherStu_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherStu.count.rank).Max() : 0;
  3029. double rank_otherStu_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherStu.duration.rank).Max() : 0;
  3030. double rank_otherTch_stick_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherTch.stick.rank).Max() : 0;
  3031. double rank_otherTch_count_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherTch.count.rank).Max() : 0;
  3032. double rank_otherTch_duration_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.otherTch.duration.rank).Max() : 0;
  3033. double rank_lesson_Max = currentStickiness.Count()>0 ? currentStickiness.Select(x => x.lesson.rank).Max() : 0;
  3034. foreach (var disappear in disappears)
  3035. {
  3036. disappear.lesson.updown=-disappear.lesson.rank;
  3037. disappear.lesson.range=-disappear.lesson.value;
  3038. disappear.lesson.value=0;
  3039. disappear.lesson.rank=rank_lesson_Max+1;
  3040. //下降
  3041. // y 5 t0
  3042. disappear.teacher.stick.updown= -disappear.teacher.stick.rank;
  3043. disappear.teacher.stick.range= -disappear.teacher.stick.value;
  3044. disappear.teacher.stick.value=0;
  3045. disappear.teacher.stick.rank=rank_teacher_stick_Max+1;
  3046. disappear.student.stick.updown= -disappear.student.stick.rank;
  3047. disappear.student.stick.range= -disappear.student.stick.value;
  3048. disappear.student.stick.value=0;
  3049. disappear.student.stick.rank=rank_student_stick_Max+1;
  3050. disappear.hiteach.stick.updown= -disappear.hiteach.stick.rank;
  3051. disappear.hiteach.stick.range= -disappear.hiteach.stick.value;
  3052. disappear.hiteach.stick.value=0;
  3053. disappear.hiteach.stick.rank=rank_hiteach_stick_Max+1;
  3054. disappear.hita.stick.updown= -disappear.hita.stick.rank;
  3055. disappear.hita.stick.range= -disappear.hita.stick.value;
  3056. disappear.hita.stick.value=0;
  3057. disappear.hita.stick.rank=rank_hita_stick_Max+1;
  3058. disappear.ies5Stu.stick.updown= -disappear.ies5Stu.stick.rank;
  3059. disappear.ies5Stu.stick.range= -disappear.ies5Stu.stick.value;
  3060. disappear.ies5Stu.stick.value=0;
  3061. disappear.ies5Stu.stick.rank=rank_ies5Stu_stick_Max+1;
  3062. disappear.ies5Tch.stick.updown= -disappear.ies5Tch.stick.rank;
  3063. disappear.ies5Tch.stick.range= -disappear.ies5Tch.stick.value;
  3064. disappear.ies5Tch.stick.value=0;
  3065. disappear.ies5Tch.stick.rank=rank_ies5Tch_stick_Max+1;
  3066. disappear.otherStu.stick.updown= -disappear.otherStu.stick.rank;
  3067. disappear.otherStu.stick.range= -disappear.otherStu.stick.value;
  3068. disappear.otherStu.stick.value=0;
  3069. disappear.otherStu.stick.rank=rank_otherStu_stick_Max+1;
  3070. disappear.otherTch.stick.updown= -disappear.otherTch.stick.rank;
  3071. disappear.otherTch.stick.range= -disappear.otherTch.stick.value;
  3072. disappear.otherTch.stick.value=0;
  3073. disappear.otherTch.stick.rank=rank_otherTch_stick_Max+1;
  3074. disappear.teacher.count.updown= -disappear.teacher.count.rank;
  3075. disappear.teacher.count.range= -disappear.teacher.count.value;
  3076. disappear.teacher.count.value=0;
  3077. disappear.teacher.count.rank=rank_teacher_count_Max+1;
  3078. disappear.student.count.updown= -disappear.student.count.rank;
  3079. disappear.student.count.range= -disappear.student.count.value;
  3080. disappear.student.count.value=0;
  3081. disappear.student.count.rank=rank_student_count_Max+1;
  3082. disappear.hiteach.count.updown= -disappear.hiteach.count.rank;
  3083. disappear.hiteach.count.range= -disappear.hiteach.count.value;
  3084. disappear.hiteach.count.value=0;
  3085. disappear.hiteach.count.rank=rank_hiteach_count_Max+1;
  3086. disappear.hita.count.updown= -disappear.hita.count.rank;
  3087. disappear.hita.count.range= -disappear.hita.count.value;
  3088. disappear.hita.count.value=0;
  3089. disappear.hita.count.rank=rank_hita_count_Max+1;
  3090. disappear.ies5Stu.count.updown= -disappear.ies5Stu.count.rank;
  3091. disappear.ies5Stu.count.range= -disappear.ies5Stu.count.value;
  3092. disappear.ies5Stu.count.value=0;
  3093. disappear.ies5Stu.count.rank=rank_ies5Stu_count_Max+1;
  3094. disappear.ies5Tch.count.updown= -disappear.ies5Tch.count.rank;
  3095. disappear.ies5Tch.count.range= -disappear.ies5Tch.count.value;
  3096. disappear.ies5Tch.count.value=0;
  3097. disappear.ies5Tch.count.rank=rank_ies5Tch_count_Max+1;
  3098. disappear.otherStu.count.updown= -disappear.otherStu.count.rank;
  3099. disappear.otherStu.count.range= -disappear.otherStu.count.value;
  3100. disappear.otherStu.count.value=0;
  3101. disappear.otherStu.count.rank=rank_otherStu_count_Max+1;
  3102. disappear.otherTch.count.updown= -disappear.otherTch.count.rank;
  3103. disappear.otherTch.count.range= -disappear.otherTch.count.value;
  3104. disappear.otherTch.count.value=0;
  3105. disappear.otherTch.count.rank=rank_otherTch_count_Max+1;
  3106. disappear.teacher.duration.updown= -disappear.teacher.duration.rank;
  3107. disappear.teacher.duration.range= -disappear.teacher.duration.value;
  3108. disappear.teacher.duration.value=0;
  3109. disappear.teacher.duration.rank=rank_teacher_duration_Max+1;
  3110. disappear.student.duration.updown= -disappear.student.duration.rank;
  3111. disappear.student.duration.range= -disappear.student.duration.value;
  3112. disappear.student.duration.value=0;
  3113. disappear.student.duration.rank=rank_student_duration_Max+1;
  3114. disappear.hiteach.duration.updown= -disappear.hiteach.duration.rank;
  3115. disappear.hiteach.duration.range= -disappear.hiteach.duration.value;
  3116. disappear.hiteach.duration.value=0;
  3117. disappear.hiteach.duration.rank=rank_hiteach_duration_Max+1;
  3118. disappear.hita.duration.updown= -disappear.hita.duration.rank;
  3119. disappear.hita.duration.range= -disappear.hita.duration.value;
  3120. disappear.hita.duration.value=0;
  3121. disappear.hita.duration.rank=rank_hita_duration_Max+1;
  3122. disappear.ies5Stu.duration.updown= -disappear.ies5Stu.duration.rank;
  3123. disappear.ies5Stu.duration.range= -disappear.ies5Stu.duration.value;
  3124. disappear.ies5Stu.duration.value=0;
  3125. disappear.ies5Stu.duration.rank=rank_ies5Stu_duration_Max+1;
  3126. disappear.ies5Tch.duration.updown= -disappear.ies5Tch.duration.rank;
  3127. disappear.ies5Tch.duration.range= -disappear.ies5Tch.duration.value;
  3128. disappear.ies5Tch.duration.value=0;
  3129. disappear.ies5Tch.duration.rank=rank_ies5Tch_duration_Max+1;
  3130. disappear.otherStu.duration.updown= -disappear.otherStu.duration.rank;
  3131. disappear.otherStu.duration.range= -disappear.otherStu.duration.value;
  3132. disappear.otherStu.duration.value=0;
  3133. disappear.otherStu.duration.rank=rank_otherStu_duration_Max+1;
  3134. disappear.otherTch.duration.updown= -disappear.otherTch.duration.rank;
  3135. disappear.otherTch.duration.range= -disappear.otherTch.duration.value;
  3136. disappear.otherTch.duration.value=0;
  3137. disappear.otherTch.duration.rank=rank_otherTch_duration_Max+1;
  3138. currentStickiness.Add(disappear);
  3139. }
  3140. }
  3141. currentStickiness = currentStickiness.OrderByDescending(x => x.teacher.stick.value).ToList();
  3142. return currentStickiness;
  3143. }
  3144. /// <summary>
  3145. /// 结算访问日志
  3146. /// </summary>
  3147. public static async Task
  3148. VisitSettle(List<string> times, AzureStorageFactory _azureStorage, AzureRedisFactory _azureRedis, Region2LongitudeLatitudeTranslator _longitudeLatitudeTranslator, IPSearcher _ipSearcher, string force)
  3149. {
  3150. foreach (var timeDate in times)
  3151. {
  3152. List<Stick> chinaSticks = new List<Stick>();
  3153. List<Stick> globalSticks = new List<Stick>();
  3154. if (DateTimeOffset.TryParse(timeDate, out DateTimeOffset date))
  3155. {
  3156. var blobClientChina = _azureStorage.GetBlobContainerClient("0-service-log").GetBlobClient($"http-log/{date:yyyy}/{date:MM}/{date:dd}/cday.json");
  3157. var blobClientGlobal = _azureStorage.GetBlobContainerClient("0-service-log").GetBlobClient($"http-log/{date:yyyy}/{date:MM}/{date:dd}/gday.json");
  3158. bool g = true, c = true;
  3159. if (blobClientChina.Exists() && force.Equals("0"))
  3160. {
  3161. c=false;
  3162. BlobDownloadResult result = await _azureStorage.GetBlobContainerClient("0-service-log").GetBlobClient($"http-log/{date:yyyy}/{date:MM}/{date:dd}/cday.json").DownloadContentAsync();
  3163. var contentBygone = result.Content.ToString();
  3164. var chinaStick = contentBygone.ToObject<Stick>();
  3165. chinaSticks.Add(chinaStick);
  3166. }
  3167. if (blobClientGlobal.Exists()&& force.Equals("0"))
  3168. {
  3169. g=false;
  3170. BlobDownloadResult result = await _azureStorage.GetBlobContainerClient("0-service-log").GetBlobClient($"http-log/{date:yyyy}/{date:MM}/{date:dd}/gday.json").DownloadContentAsync();
  3171. var contentBygone = result.Content.ToString();
  3172. var globalStick = contentBygone.ToObject<Stick>();
  3173. globalSticks.Add(globalStick);
  3174. }
  3175. if (g||c)
  3176. {
  3177. BlobDownloadResult result = await _azureStorage.GetBlobContainerClient("0-service-log").GetBlobClient($"http-log/{date:yyyy}/{date:MM}/{date:dd}/index.log").DownloadContentAsync();
  3178. var content = result.Content.ToString();
  3179. content= content.Substring(0, content.Length-2);
  3180. if (content.EndsWith("}"))
  3181. {
  3182. content=$"[{content}]";
  3183. }
  3184. else
  3185. {
  3186. content=$"[{content}}}]";
  3187. }
  3188. List<ApiVisit> apiVisits = new List<ApiVisit>();
  3189. apiVisits.AddRange(content.ToObject<List<ApiVisit>>());
  3190. var dateNow = DateTimeOffset.Now.GetGMTTime(8);
  3191. if ($"{dateNow:yyyy-MM-dd}".Equals($"{date:yyyy-MM-dd}"))
  3192. { //当前小时一致的
  3193. BlobDownloadResult resultHour = await _azureStorage.GetBlobContainerClient("0-service-log").GetBlobClient($"http-log/{date:yyyy}/{date:MM}/{date:dd}/{date:HH}.log").DownloadContentAsync();
  3194. var contentHour = resultHour.Content.ToString();
  3195. contentHour= contentHour.Substring(0, contentHour.Length-2);
  3196. if (contentHour.EndsWith("}"))
  3197. {
  3198. contentHour=$"[{contentHour}]";
  3199. }
  3200. else
  3201. {
  3202. contentHour=$"[{contentHour}}}]";
  3203. }
  3204. var httpLog = contentHour.ToObject<List<HttpLog>>();
  3205. (ConcurrentBag<ApiVisit> visits, ConcurrentBag<(string uuid, HttpLog httpLog, List<string> tmdid, List<string> school)> uuidInfo) = await SystemService.ConvertHttpLog(httpLog, _azureRedis, _ipSearcher, _longitudeLatitudeTranslator, dateNow, false);
  3206. apiVisits.AddRange(visits);
  3207. }
  3208. if (c)
  3209. {
  3210. Stick apiVisitsBygone = await GetBygoneSettleData(_azureStorage, date, "China");
  3211. //大陆学校
  3212. var chinaApiVisits = apiVisits.Where(x => x.hostName.Equals("大陆站"));
  3213. var chinaSchoolVisits = apiVisits.Where(x => !string.IsNullOrWhiteSpace(x.school) && x.hostName.Equals("大陆站")).GroupBy(x => x.school);
  3214. List<SchoolStick> chinaStickiness = CountSchoolStickiness(chinaSchoolVisits, chinaApiVisits, apiVisitsBygone.schoolSticks);
  3215. Stick stickc = new Stick();
  3216. stickc.schoolSticks=chinaStickiness;
  3217. chinaSticks.Add(stickc);
  3218. if (!$"{dateNow:yyyy-MM-dd}".Equals($"{date:yyyy-MM-dd}"))
  3219. {
  3220. await _azureStorage.GetBlobContainerClient("0-service-log").UploadFileByContainer(stickc.ToJsonString(), "http-log", $"{date:yyyy}/{date:MM}/{date:dd}/cday.json", true);
  3221. }
  3222. }
  3223. if (g)
  3224. {
  3225. Stick apiVisitsBygone = await GetBygoneSettleData(_azureStorage, date, "Global");
  3226. //国际学校
  3227. var globalApiVisits = apiVisits.Where(x => x.hostName.Equals("国际站"));
  3228. var globalSchoolVisits = apiVisits.Where(x => !string.IsNullOrWhiteSpace(x.school) && x.hostName.Equals("国际站")).GroupBy(x => x.school);
  3229. List<SchoolStick> globalStickiness = CountSchoolStickiness(globalSchoolVisits, globalApiVisits, apiVisitsBygone.schoolSticks);
  3230. Stick stickg = new Stick();
  3231. stickg.schoolSticks=globalStickiness;
  3232. globalSticks.Add(stickg);
  3233. //如果是当天的 ,则不能保存
  3234. if (!$"{dateNow:yyyy-MM-dd}".Equals($"{date:yyyy-MM-dd}"))
  3235. {
  3236. await _azureStorage.GetBlobContainerClient("0-service-log").UploadFileByContainer(stickg.ToJsonString(), "http-log", $"{date:yyyy}/{date:MM}/{date:dd}/gday.json", true);
  3237. }
  3238. }
  3239. }
  3240. else
  3241. {
  3242. continue;
  3243. }
  3244. }
  3245. }
  3246. }
  3247. public static async Task<Stick> GetBygoneSettleData(AzureStorageFactory _azureStorage, DateTimeOffset date, string cg)
  3248. {
  3249. //过去一天的数据
  3250. var bygone = date.AddDays(-1);
  3251. Stick apiVisitsBygone = new Stick();
  3252. try
  3253. {
  3254. cg=cg.Contains("China", StringComparison.OrdinalIgnoreCase) ? "cday.json" : "gday.json";
  3255. BlobDownloadResult chinaResultBygone = await _azureStorage.GetBlobContainerClient("0-service-log").GetBlobClient($"http-log/{bygone:yyyy}/{bygone:MM}/{bygone:dd}/{cg}").DownloadContentAsync();
  3256. var contentBygone = chinaResultBygone.Content.ToString();
  3257. apiVisitsBygone= contentBygone.ToObject<Stick>();
  3258. }
  3259. catch
  3260. { //可能出现异常,因为文件不存在。第一次初始化,前一天的数据没有 }
  3261. }
  3262. return apiVisitsBygone;
  3263. }
  3264. public static async Task<(ConcurrentBag<ApiVisit> visits, ConcurrentBag<(string uuid, HttpLog httpLog, List<string> tmdid, List<string> school)> uuidInfo)>
  3265. ConvertHttpLog(List<HttpLog> logs, AzureRedisFactory _azureRedis, IPSearcher _ipSearcher, Region2LongitudeLatitudeTranslator _longitudeLatitudeTranslator, DateTimeOffset gmt8Time, bool test = false)
  3266. {
  3267. ConcurrentBag<ApiVisit> visits = new ConcurrentBag<ApiVisit>();
  3268. ConcurrentBag<(string uuid, HttpLog httpLog, List<string> tmdid, List<string> school)> uuidInfo = new ConcurrentBag<(string uuid, HttpLog httpLog, List<string> tmdid, List<string> school)>();
  3269. object lockObj = new object();
  3270. await Parallel.ForEachAsync(logs, async (log, _) =>
  3271. {
  3272. if (!log.path.Contains("."))
  3273. {
  3274. string uuid = Guid.NewGuid().ToString();
  3275. List<string> schoolMatch = new List<string>();
  3276. List<string> useridMatch = new List<string>();
  3277. var vist = new ApiVisit()
  3278. {
  3279. id=uuid,
  3280. ip=log.ip,
  3281. tid=log.tid,
  3282. time= log.time,
  3283. userId= log.id,
  3284. picture=log.picture,
  3285. school= log.school,
  3286. tname= log.name,
  3287. path = log.path,
  3288. client=log.p.Equals("os", StringComparison.OrdinalIgnoreCase) ? "ies5" : log.p,
  3289. scope=log.scope,
  3290. host= log.host,
  3291. hostName=log.hostName,
  3292. l=log.l,
  3293. year = $"{gmt8Time:yyyy}",
  3294. month = $"{gmt8Time:MM}",
  3295. day = $"{gmt8Time:dd}",
  3296. hour =$"{gmt8Time:HH}"
  3297. };
  3298. if (test)
  3299. {
  3300. var time = DateTimeOffset.FromUnixTimeMilliseconds(log.time);
  3301. //本地调试时间
  3302. if (vist.ip.Equals("0.0.0.1"))
  3303. {
  3304. time= time.AddHours(8);
  3305. }
  3306. vist.year = $"{time:yyyy}";
  3307. vist.month = $"{time:MM}";
  3308. vist.day = $"{time:dd}";
  3309. vist.hour =$"{time:HH}";
  3310. }
  3311. if (string.IsNullOrWhiteSpace(vist.userId))
  3312. {
  3313. //var jsonPathContext = new JsonPathContext();
  3314. //jsonPathContext.ValueSystem= new JsonTextValueSystem();
  3315. string path = "$..['id_token','idToken','idtoken','tmdid','id','teacherId','teacher','tid','tId','userid','userId','creatorId','creator','code','studentId','student','studentid']";
  3316. if (!log.param.ValueKind.Equals(JsonValueKind.Null))
  3317. {
  3318. JObject jsonObject = JObject.Parse(log.param.GetRawText());
  3319. //var nodes_path = jsonPathContext.SelectNodes(log.param, path);
  3320. var nodes_path = jsonObject.SelectTokens(path);
  3321. foreach (var node in nodes_path)
  3322. {
  3323. // 只获取是字符串的
  3324. if (node.Type.Equals(JTokenType.String))
  3325. {
  3326. switch (true)
  3327. {
  3328. case bool when node.Path.Contains("id_token")||node.Path.Contains("idToken")||node.Path.Contains("idtoken"):
  3329. {
  3330. try
  3331. {
  3332. var jwt = new JwtSecurityToken($"{node}");
  3333. string id = jwt.Payload.Sub;
  3334. var name = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("name"))?.Value;
  3335. var picture = jwt.Claims.FirstOrDefault(claim => claim.Type.Equals("picture"))?.Value;
  3336. if (!string.IsNullOrWhiteSpace(id) && long.TryParse(id, out long _id))
  3337. {
  3338. vist.userId=id;
  3339. vist.scope="teacher";
  3340. vist.tname=name;
  3341. vist.picture=picture;
  3342. useridMatch.Add(id);
  3343. }
  3344. }
  3345. catch (Exception ex) { }
  3346. break;
  3347. }
  3348. case bool when node.Path.Contains("tmdid")||node.Path.Contains("id")||node.Path.Contains("teacherId")
  3349. ||node.Path.Contains("teacher")||node.Path.Contains("tid")||node.Path.Contains("tId")||node.Path.Contains("userid")
  3350. ||node.Path.Contains("userId"):
  3351. {
  3352. if (!string.IsNullOrWhiteSpace($"{node}") && long.TryParse($"{node}", out long _id))
  3353. {
  3354. vist.userId=$"{node}";
  3355. vist.scope="teacher";
  3356. useridMatch.Add($"{node}");
  3357. }
  3358. break;
  3359. }
  3360. case bool when node.Path.Contains("studentId")||node.Path.Contains("student")||node.Path.Contains("studentid"):
  3361. {
  3362. if (!string.IsNullOrWhiteSpace($"{node}") && long.TryParse($"{node}", out long _id))
  3363. {
  3364. vist.userId=$"{node}";
  3365. vist.scope="student";
  3366. useridMatch.Add($"{node}");
  3367. }
  3368. break;
  3369. }
  3370. case bool when node.Path.Contains("code"):
  3371. {
  3372. if (!string.IsNullOrWhiteSpace($"{node}"))
  3373. {
  3374. if (long.TryParse($"{node}", out long _id))
  3375. {
  3376. vist.userId=$"{node}";
  3377. useridMatch.Add($"{node}");
  3378. }
  3379. else
  3380. {
  3381. string[] codes = $"{node}".Split("-");
  3382. foreach (var _code in codes)
  3383. {
  3384. if (long.TryParse(_code, out long _codeid))
  3385. {
  3386. vist.userId=$"{node}";
  3387. useridMatch.Add($"{_code}");
  3388. break;
  3389. }
  3390. }
  3391. }
  3392. }
  3393. break;
  3394. }
  3395. }
  3396. }
  3397. }
  3398. if (log.path.Contains("process-notify", StringComparison.OrdinalIgnoreCase))
  3399. {
  3400. string s = log.param.ToJsonString().Replace("\\", "");
  3401. Regex regextmdid = new Regex("\"tmdid\":\"(\\d+)\"");
  3402. Match matchtmdid = regextmdid.Match(s);
  3403. if (matchtmdid.Success)
  3404. {
  3405. var t = matchtmdid.Groups[1].Value;
  3406. if (!string.IsNullOrWhiteSpace(t))
  3407. {
  3408. vist.userId=t;
  3409. vist.scope="teacher";
  3410. useridMatch.Add(t);
  3411. }
  3412. }
  3413. Regex regexname = new Regex("\"tmdname\":\"(.+?)\"");
  3414. Match matchname = regexname.Match(s);
  3415. if (matchname.Success)
  3416. {
  3417. var t = matchname.Groups[1].Value;
  3418. if (!string.IsNullOrWhiteSpace(t))
  3419. {
  3420. vist.tname=t;
  3421. }
  3422. }
  3423. }
  3424. }
  3425. }
  3426. else
  3427. {
  3428. if (string.IsNullOrWhiteSpace($"{vist.scope}"))
  3429. {
  3430. vist.scope="teacher";
  3431. uuidInfo.Add((uuid, log, new List<string>() { vist.userId }, new List<string>()));
  3432. }
  3433. }
  3434. if (string.IsNullOrWhiteSpace(vist.school) || vist.school.Equals("true") || vist.school.Equals("false"))
  3435. {
  3436. vist.school="";
  3437. string path = "$..['school','id','schoolId','schoolid','schoolCode','school_code','schoolcode','code']";
  3438. if (!log.param.ValueKind.Equals(JsonValueKind.Null))
  3439. {
  3440. JObject jsonObject = JObject.Parse(log.param.GetRawText());
  3441. var nodes_path = jsonObject.SelectTokens(path);
  3442. foreach (var node in nodes_path)
  3443. {
  3444. // 只获取是字符串的
  3445. if (node.Type.Equals(JTokenType.String))
  3446. {
  3447. switch (true)
  3448. {
  3449. case bool when node.Path.Contains("school")||node.Path.Contains("id")||node.Path.Contains("schoolId")
  3450. ||node.Path.Contains("schoolid")||node.Path.Contains("schoolCode")||node.Path.Contains("school_code")||node.Path.Contains("schoolcode"):
  3451. {
  3452. if (!$"{node}".Contains("-")&& $"{node}".Length<=8 && $"{node}".Length>=1)
  3453. {
  3454. vist.school=$"{node}";
  3455. schoolMatch.Add($"{node}");
  3456. }
  3457. break;
  3458. }
  3459. case bool when node.Path.Contains("code"):
  3460. {
  3461. if (!$"{node}".Contains("-")&& $"{node}".Length<=8&& $"{node}".Length>=1)
  3462. {
  3463. vist.school=$"{node}";
  3464. schoolMatch.Add($"{node}");
  3465. }
  3466. else
  3467. {
  3468. string[] codes = $"{node}".Split("-");
  3469. foreach (var _code in codes)
  3470. {
  3471. if ($"{_code}".Length<=8 && $"{_code}".Length>=1)
  3472. {
  3473. vist.school=$"{_code}";
  3474. schoolMatch.Add($"{_code}");
  3475. break;
  3476. }
  3477. }
  3478. }
  3479. break;
  3480. }
  3481. }
  3482. }
  3483. }
  3484. if (log.path.Contains("process-notify", StringComparison.OrdinalIgnoreCase))
  3485. {
  3486. string s = log.param.ToJsonString().Replace("\\", "");
  3487. Regex regexname = new Regex("\"schoolId\":\"(.+?)\"");
  3488. Match matchname = regexname.Match(s);
  3489. if (matchname.Success)
  3490. {
  3491. var t = matchname.Groups[1].Value;
  3492. if (!string.IsNullOrWhiteSpace(t))
  3493. {
  3494. vist.school=t;
  3495. }
  3496. }
  3497. }
  3498. }
  3499. }
  3500. //处理 client
  3501. {
  3502. if (!string.IsNullOrWhiteSpace(log.client))
  3503. {
  3504. if (log.client.Equals("IES", StringComparison.OrdinalIgnoreCase))
  3505. {
  3506. vist.client="ies5";
  3507. }
  3508. if (log.client.Equals("AClassONE", StringComparison.OrdinalIgnoreCase))
  3509. {
  3510. vist.client="aclassone";
  3511. }
  3512. if (log.client.Equals("BB", StringComparison.OrdinalIgnoreCase))
  3513. {
  3514. vist.client="habb";
  3515. }
  3516. if (log.client.Equals("HiTool", StringComparison.OrdinalIgnoreCase) ||log.client.Equals("HiTools", StringComparison.OrdinalIgnoreCase))
  3517. {
  3518. vist.client="hiscan";
  3519. }
  3520. if (log.client.Equals("HiTA", StringComparison.OrdinalIgnoreCase))
  3521. {
  3522. vist.client="hita";
  3523. vist.scope="teacher";
  3524. }
  3525. if (log.client.Equals("HiTeachCC", StringComparison.OrdinalIgnoreCase))
  3526. {
  3527. vist.client="hiteachcc";
  3528. }
  3529. if (log.client.Equals("HiTeach", StringComparison.OrdinalIgnoreCase))
  3530. {
  3531. vist.scope="teacher";
  3532. vist.client="hiteach";
  3533. }
  3534. if (log.client.Equals("Open", StringComparison.OrdinalIgnoreCase))
  3535. {
  3536. vist.client="open";
  3537. }
  3538. }
  3539. }
  3540. //补全站点
  3541. {
  3542. if (
  3543. (log.host.Equals("wwww.teammodel.net")||log.host.Equals("ies5-rc.teammodel.net")))
  3544. {
  3545. vist.hostName="国际站";
  3546. vist.host="www.teammodel.net";
  3547. vist.client="ies5";
  3548. vist.l="Global";
  3549. }
  3550. else if (
  3551. log.host.Equals("teammodelos-yx.chinacloudsites.cn")||log.host.Equals("teammodelos.chinacloudsites.cn")
  3552. ||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"))
  3553. {
  3554. vist.hostName="大陆站";
  3555. vist.host="www.teammodel.cn";
  3556. vist.client="ies5"; vist.l="China";
  3557. }
  3558. else if ((log.host.Contains("localhost") && log.p.Equals("os"))|| log.host.Equals("teammodelos-test.chinacloudsites.cn") ||log.host.Equals("test.teammodel.cn"))
  3559. {
  3560. vist.hostName="测试站";
  3561. vist.host="test.teammodel.cn";
  3562. vist.client="ies5";
  3563. vist.l="China";
  3564. }
  3565. else if (
  3566. (log.host.Equals("scyx.teammodel.cn") ||log.host.Equals("jinniu.teammodel.cn")))
  3567. {
  3568. vist.hostName="研修2.0";
  3569. vist.host="scyx.teammodel.cn";
  3570. vist.client="ability"; vist.l="China";
  3571. }
  3572. else if (
  3573. log.host.Equals("open.teammodel.cn")||log.host.Equals("open-test.teammodel.cn") ||log.host.Equals("zhiyin-test.teammodel.cn"))
  3574. {
  3575. vist.hostName="开放平台";
  3576. vist.host="open.teammodel.cn";
  3577. vist.client="open";
  3578. vist.l="China";
  3579. }
  3580. else if ((log.host.Equals("bi-rc.teammodel.net") || log.host.Equals("bi.teammodel.net")))
  3581. {
  3582. vist.hostName="国际站";
  3583. vist.host="bi.teammodel.net";
  3584. vist.client="bi";
  3585. vist.scope="admin";
  3586. vist.l="Global";
  3587. }
  3588. else if (log.host.Equals("teammodelbi.chinacloudsites.cn") ||log.host.Equals("bi.teammodel.cn"))
  3589. {
  3590. vist.hostName="大陆站";
  3591. vist.host="bi.teammodel.cn";
  3592. vist.client="bi";
  3593. vist.scope="admin";
  3594. vist.l="China";
  3595. }
  3596. else if (log.host.Equals("bitest.teammodel.cn")||log.host.Equals("teammodelbi-test.chinacloudsites.cn")||(log.host.Contains("localhost") && (log.p.Equals("bi"))))
  3597. {
  3598. vist.hostName="测试站";
  3599. vist.host="testbi.teammodel.cn";
  3600. vist.client="bi";
  3601. vist.scope="admin";
  3602. vist.l="China";
  3603. }
  3604. else if (
  3605. log.host.Equals("teamcontest.chinacloudsites.cn")||log.host.Equals("contest.chinacloudsites.cn")||log.host.Equals("contest-test.chinacloudsites.cn"))
  3606. {
  3607. vist.hostName="大陆站";
  3608. vist.host="contest.teammodel.cn";
  3609. vist.client="contest"; vist.l="China";
  3610. }
  3611. else if (
  3612. log.host.Equals("hiteachcc.chinacloudsites.cn"))
  3613. {
  3614. vist.hostName="正式站";
  3615. vist.host="hiteachcc.teammodel.cn";
  3616. vist.client="hiteachcc";
  3617. vist.l="China";
  3618. }
  3619. else if (log.host.Equals("appraisal.chinacloudsites.cn"))
  3620. {
  3621. vist.hostName="大陆站";
  3622. vist.host="appraisal.teammodel.cn";
  3623. vist.client="appraisal";
  3624. vist.l="China";
  3625. }
  3626. else if ((log.host.Contains("localhost") && log.p.Equals("appraisal"))||log.host.Equals("appraisal-test.teammodel.cn") ||log.host.Equals("appraisal-test.chinacloudsites.cn"))
  3627. {
  3628. vist.hostName="测试站";
  3629. vist.host="appraisal-test.teammodel.cn";
  3630. vist.client="appraisal";
  3631. vist.l="China";
  3632. }
  3633. else
  3634. {
  3635. if (!string.IsNullOrWhiteSpace(log.p))
  3636. {
  3637. vist.client=log.p.Equals("os", StringComparison.OrdinalIgnoreCase) ? "ies5" : log.p;
  3638. }
  3639. else
  3640. {
  3641. vist.client="other";
  3642. }
  3643. if (log.host.EndsWith(".cn"))
  3644. {
  3645. vist.hostName="大陆站";
  3646. vist.l="China";
  3647. }
  3648. else if (log.host.EndsWith(".net"))
  3649. {
  3650. vist.hostName="国际站";
  3651. vist.l="Global";
  3652. }
  3653. else
  3654. {
  3655. vist.hostName="其他";
  3656. vist.l="其他";
  3657. }
  3658. }
  3659. }
  3660. //补全产品端
  3661. {
  3662. //研修2.0
  3663. if (log.path.Contains("research") || log.path.Contains("study") || log.path.Contains("standard-file"))
  3664. {
  3665. vist.client="ability";
  3666. }
  3667. if (log.path.Contains("teacher"))
  3668. {
  3669. vist.scope="teacher";
  3670. }
  3671. if (log.path.Contains("tmduser"))
  3672. {
  3673. vist.scope="tmduser";
  3674. }
  3675. if (log.path.Contains("student/login"))
  3676. {
  3677. vist.scope="student";
  3678. }
  3679. if (log.path.StartsWith("/activity"))
  3680. {
  3681. vist.client="contest";
  3682. }
  3683. //小程序
  3684. if (log.path.Contains("aclassone"))
  3685. {
  3686. vist.client="aclassone";
  3687. }
  3688. // /// <summary>
  3689. /// ExamInfo qamode 書面問答類型 0:書面問答 1:紙本測驗 2:艺术评测
  3690. /// </summary>
  3691. //艺术评测
  3692. 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"))
  3693. {
  3694. vist.client="art";
  3695. }
  3696. if (log.path.Contains("common/exam/upsert-record"))
  3697. {
  3698. JObject jobject = JObject.Parse(log.param.GetRawText());
  3699. var jtokens = jobject.SelectTokens("$..artId");
  3700. if (jtokens!=null && jtokens.Count()>0)
  3701. {
  3702. vist.client="art";
  3703. vist.scope="student";
  3704. }
  3705. }
  3706. if (log.path.Contains("habb"))
  3707. {
  3708. vist.client="habb";
  3709. }
  3710. //阅卷客户端
  3711. if (log.path.Contains("hiscan"))
  3712. {
  3713. vist.client="hiscan";
  3714. }
  3715. if (log.path.Contains("hita"))
  3716. {
  3717. vist.client="hita";
  3718. }
  3719. if (log.path.Contains("hiteachcc"))
  3720. {
  3721. vist.client="hiteachcc";
  3722. }
  3723. if (log.path.Contains("sokrate"))
  3724. {
  3725. vist.client="sokrate";
  3726. }
  3727. if (log.path.Contains("sokrate") || log.path.Contains("score"))
  3728. {
  3729. vist.client="sokrate";
  3730. }
  3731. if (log.path.Contains("hiteach"))
  3732. {
  3733. vist.client="hiteach";
  3734. }
  3735. ///IES开放平台
  3736. if (log.path.Contains("business") || log.path.Contains("biz") || log.path.Contains("openapi-config") || log.path.Contains("open-api"))
  3737. {
  3738. vist.client="open";
  3739. }
  3740. //从token的role 能否获取 开放平台
  3741. //单点登录及第三方接口
  3742. 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")
  3743. || log.path.Contains("oauth/check-bind")|| log.path.Contains("dingding") || log.path.Contains("wechat")
  3744. )
  3745. {
  3746. vist.client="sso-third";
  3747. }
  3748. }
  3749. //处理IP转地区
  3750. var region = await _ipSearcher.SearchIpAsync(vist.ip);
  3751. if (string.IsNullOrWhiteSpace(region))
  3752. {
  3753. region="未知IP·未知IP·未知IP";
  3754. }
  3755. if (!string.IsNullOrWhiteSpace(region))
  3756. {
  3757. region= region.Replace("省·", "·").Replace("市·", "·").Replace("特别行政区·", "·").Replace("藏族羌族自治州·", "·");
  3758. var regions = region.Split("·");
  3759. if (regions.Length==4)
  3760. {
  3761. vist.area= regions[0];
  3762. vist.province = regions[1];
  3763. vist.city = regions[2];
  3764. }
  3765. if (regions.Length==3)
  3766. {
  3767. vist.area= regions[0];
  3768. vist.province = regions[1];
  3769. }
  3770. if (regions.Length==2)
  3771. {
  3772. vist.area= regions[0];
  3773. vist.province = regions[1];
  3774. }
  3775. if (regions.Length==1)
  3776. {
  3777. vist.area= regions[0];
  3778. }
  3779. }
  3780. //处理地区转经纬度
  3781. {
  3782. IEnumerable<JToken> tokens = default;
  3783. if (!string.IsNullOrWhiteSpace(vist.city) && !string.IsNullOrWhiteSpace(vist.province) && !string.IsNullOrWhiteSpace(vist.area))
  3784. {
  3785. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.province}/i && @.city=~ /.*{vist.city}/i)]");
  3786. if (!(tokens.Any() && tokens.Count()>0))
  3787. {
  3788. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.city}/i && @.city=~ /.*{vist.province}/i)]");
  3789. if (!(tokens.Any() && tokens.Count()>0))
  3790. {
  3791. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.city}/i || @.city=~ /.*{vist.city}/i)]");
  3792. }
  3793. if (!(tokens.Any() && tokens.Count()>0))
  3794. {
  3795. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.province}/i||@.city=~ /.*{vist.province}/i)]");
  3796. }
  3797. }
  3798. }
  3799. else if (string.IsNullOrWhiteSpace(vist.city) && !string.IsNullOrWhiteSpace(vist.province) && !string.IsNullOrWhiteSpace(vist.area))
  3800. {
  3801. if (vist.area.Equals("中国"))
  3802. {
  3803. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.province}/i)]");
  3804. if (!(tokens.Any() && tokens.Count()>0))
  3805. {
  3806. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.city=~ /.*{vist.province}/i)]");
  3807. }
  3808. }
  3809. else
  3810. {
  3811. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.city=~ /.*{vist.province}/i || @.province=~ /.*{vist.province}/i)]");
  3812. }
  3813. }
  3814. else if (!string.IsNullOrWhiteSpace(vist.city) && string.IsNullOrWhiteSpace(vist.province)&& !string.IsNullOrWhiteSpace(vist.area))
  3815. {
  3816. if (vist.area.Equals("中国"))
  3817. {
  3818. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.province=~ /.*{vist.city}/i)]");
  3819. if (!(tokens.Any() && tokens.Count()>0))
  3820. {
  3821. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.city=~ /.*{vist.province}/i)]");
  3822. }
  3823. }
  3824. else
  3825. {
  3826. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.city=~ /.*{vist.city}/i || @.city=~ /.*{vist.province}/i)]");
  3827. }
  3828. }
  3829. else if (string.IsNullOrWhiteSpace(vist.city) && string.IsNullOrWhiteSpace(vist.province)&& !string.IsNullOrWhiteSpace(vist.area))
  3830. {
  3831. tokens= _longitudeLatitudeTranslator.regionJson.SelectTokens($"$..[?(@.country=~ /.*{vist.area}/i && @.m=='1')]");
  3832. }
  3833. if (tokens!=null && tokens.Any())
  3834. {
  3835. List<RegionLngLat> regionLngLats = new List<RegionLngLat>();
  3836. foreach (JToken token in tokens)
  3837. {
  3838. regionLngLats.Add(token.ToString().ToObject<RegionLngLat>());
  3839. }
  3840. var points = regionLngLats.FindAll(x => string.IsNullOrWhiteSpace(x.area));
  3841. if (!points.IsNotEmpty())
  3842. {
  3843. points= regionLngLats.FindAll(x => !string.IsNullOrWhiteSpace(x.m) && x.m.Equals("1"));
  3844. }
  3845. if (string.IsNullOrWhiteSpace(vist.city))
  3846. {
  3847. vist.city=points?.FirstOrDefault()?.city;
  3848. if (!string.IsNullOrWhiteSpace(vist.city) && vist.city.EndsWith("市"))
  3849. {
  3850. vist.city=vist.city.Replace("市", "");
  3851. }
  3852. }
  3853. vist.lat=points?.FirstOrDefault()?.lat;
  3854. vist.lng=points?.FirstOrDefault()?.lng;
  3855. }
  3856. else
  3857. {
  3858. if (vist.area.Equals("内网IP"))
  3859. {
  3860. if (vist.host.Contains(".cn") || vist.host.Contains("localhost"))
  3861. {
  3862. vist.lat="30.655821878416408";
  3863. vist.lng="104.08153351042463";
  3864. vist.area="中国";
  3865. vist.province="四川";
  3866. vist.city="成都";
  3867. }
  3868. else
  3869. {
  3870. vist.lat="25.044332";
  3871. vist.lng="121.509062";
  3872. vist.area="中国";
  3873. vist.province="台湾";
  3874. vist.city="台湾";
  3875. }
  3876. }
  3877. else
  3878. {
  3879. vist.lat="30.655821878416408";
  3880. vist.lng="104.08153351042463";
  3881. vist.area="中国";
  3882. vist.province="四川";
  3883. vist.city="成都";
  3884. }
  3885. }
  3886. }
  3887. uuidInfo.Add((uuid, log, useridMatch, schoolMatch));
  3888. visits.Add(vist);
  3889. }
  3890. }
  3891. );
  3892. List<(string tmd, bool exists, string scope)> tmdexists = new List<(string tmd, bool exists, string scope)>();
  3893. List<(string sch, bool exists)> schexists = new List<(string sch, bool exists)>();
  3894. var tmds = uuidInfo.SelectMany(x => x.tmdid).ToHashSet();
  3895. if (tmds.Any())
  3896. {
  3897. foreach (var tmd in tmds)
  3898. {
  3899. var exists = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"Blob:Catalog:{tmd}");
  3900. if (exists)
  3901. {
  3902. tmdexists.Add((tmd, exists, "teacher"));
  3903. }
  3904. else
  3905. {
  3906. exists = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"Login:School:hbcn:student:{tmd}");
  3907. tmdexists.Add((tmd, exists, "student"));
  3908. }
  3909. }
  3910. }
  3911. var schs = uuidInfo.SelectMany(x => x.school).ToHashSet();
  3912. if (schs.Any())
  3913. {
  3914. foreach (var sch in schs)
  3915. {
  3916. var exists = await _azureRedis.GetRedisClient(8).KeyExistsAsync($"Blob:Catalog:{sch}");
  3917. schexists.Add((sch, exists));
  3918. }
  3919. }
  3920. foreach (var item in uuidInfo)
  3921. {
  3922. foreach (var tmd in item.tmdid)
  3923. {
  3924. var tmdext = tmdexists.Find(x => x.tmd.Equals(tmd));
  3925. if (tmdext.tmd!= null && tmdext.exists)
  3926. {
  3927. var vist = visits.Where(x => x.id.Equals(item.uuid));
  3928. foreach (var vi in vist)
  3929. {
  3930. vi.userId=tmd;
  3931. if (string.IsNullOrWhiteSpace(vi.scope))
  3932. {
  3933. vi.scope=tmdext.scope;
  3934. }
  3935. }
  3936. break;
  3937. }
  3938. }
  3939. foreach (var sch in item.school)
  3940. {
  3941. var schext = schexists.Find(x => x.sch.Equals(sch));
  3942. if (schext.sch!= null && schext.exists)
  3943. {
  3944. var vist = visits.Where(x => x.id.Equals(item.uuid));
  3945. foreach (var vi in vist)
  3946. {
  3947. vi.school=sch;
  3948. }
  3949. break;
  3950. }
  3951. }
  3952. }
  3953. return (visits, uuidInfo);
  3954. }
  3955. public class ApiVisit
  3956. {
  3957. public string id { get; set; }
  3958. public string path { get; set; }
  3959. /// <summary>
  3960. /// 细分
  3961. /// ies5 ,hiteach,hita,cc,bi,contest,open,aclassone,sokrates,ability,art
  3962. /// 产品端
  3963. /// </summary>
  3964. public string client { get; set; }
  3965. /// <summary>
  3966. /// 具体功能
  3967. /// </summary>
  3968. // public string func { get; set; }
  3969. public string userId { get; set; }
  3970. public string picture { get; set; }
  3971. public string scope { get; set; }
  3972. public string tname { get; set; }
  3973. public string school { get; set; }
  3974. public string ip { get; set; }
  3975. //public string region { get; set; }
  3976. public string area { get; set; }
  3977. public string province { get; set; }
  3978. public string city { get; set; } = "";
  3979. public long time { get; set; }
  3980. /// <summary>
  3981. ///
  3982. /// </summary>
  3983. public string host { get; set; }
  3984. public string hostName { get; set; } = "其他";
  3985. /// <summary>
  3986. /// tokenid
  3987. /// </summary>
  3988. public string tid { get; set; }
  3989. public string year { get; set; }
  3990. public string month { get; set; }
  3991. public string day { get; set; }
  3992. public string hour { get; set; }
  3993. //public RegionLngLat point { get; set; }
  3994. public string lat { get; set; }
  3995. public string lng { get; set; }
  3996. public string l { get; set; }
  3997. }
  3998. public class HttpLog
  3999. {
  4000. public string ip { get; set; }
  4001. public long time { get; set; }
  4002. public string host { get; set; }
  4003. public string hostName = "其他";
  4004. public string tid { get; set; }
  4005. public string path { get; set; }
  4006. public string client { get; set; }
  4007. public JsonElement param { get; set; }
  4008. public string id { get; set; }
  4009. public string name { get; set; }
  4010. public string picture { get; set; }
  4011. public string school { get; set; }
  4012. public string p { get; set; }
  4013. // public string ua { get; set; }
  4014. // public string referer { get; set; }
  4015. public string scope { get; set; }
  4016. public string year { get; set; }
  4017. public string month { get; set; }
  4018. public string day { get; set; }
  4019. public string hour { get; set; }
  4020. public string l { get; set; }
  4021. }
  4022. public record RegionLngLat
  4023. {
  4024. public string country { get; set; }
  4025. public string province { get; set; }
  4026. public string city { get; set; }
  4027. public string lat { get; set; }
  4028. public string lng { get; set; }
  4029. public string area { get; set; }
  4030. public string m { get; set; } = "0";
  4031. }
  4032. public class CountData
  4033. {
  4034. public string pk { get; set; } = "";
  4035. public string sk { get; set; } = "";
  4036. public string sp { get; set; } = "";
  4037. public int count { get; set; }
  4038. }
  4039. public class SchoolStick
  4040. {
  4041. /// <summary>
  4042. /// 名字
  4043. /// </summary>
  4044. public string name { get; set; }
  4045. public string picture { get; set; }
  4046. /// <summary>
  4047. /// 编码
  4048. /// </summary>
  4049. public string id { get; set; }
  4050. public string last { get; set; }
  4051. #region teacher
  4052. public ClientStick teacher { get; set; } = new ClientStick();
  4053. #endregion
  4054. #region student
  4055. public ClientStick student { get; set; } = new ClientStick();
  4056. #endregion
  4057. #region hiteach
  4058. public ClientStick hiteach { get; set; } = new ClientStick();
  4059. public Indicator lesson { get; set; } = new Indicator();
  4060. #endregion
  4061. #region hita
  4062. public ClientStick hita { get; set; } = new ClientStick();
  4063. #endregion
  4064. #region ies5Teacher
  4065. public ClientStick ies5Tch { get; set; } = new ClientStick();
  4066. #endregion
  4067. #region otherTeacher
  4068. public ClientStick otherTch { get; set; } = new ClientStick();
  4069. #endregion
  4070. #region ies5Student
  4071. public ClientStick ies5Stu { get; set; } = new ClientStick();
  4072. #endregion
  4073. #region otherStudent
  4074. public ClientStick otherStu { get; set; } = new ClientStick();
  4075. #endregion
  4076. public List<TchStick> tchSticks { get; set; } = new List<TchStick>();
  4077. public List<StuStick> stuSticks { get; set; } = new List<StuStick>();
  4078. }
  4079. public class TchStick
  4080. {
  4081. public string school { get; set; }
  4082. /// <summary>
  4083. /// 名字
  4084. /// </summary>
  4085. public string name { get; set; }
  4086. public string picture { get; set; }
  4087. /// <summary>
  4088. /// 编码
  4089. /// </summary>
  4090. public string id { get; set; }
  4091. public string last { get; set; }
  4092. #region tmd
  4093. public ClientStick teacher { get; set; } = new ClientStick();
  4094. #endregion
  4095. #region hiteach
  4096. public ClientStick hiteach { get; set; } = new ClientStick();
  4097. public Indicator lesson { get; set; } = new Indicator();
  4098. #endregion
  4099. #region hita
  4100. public ClientStick hita { get; set; } = new ClientStick();
  4101. #endregion
  4102. #region ies5Teacher
  4103. public ClientStick ies5Tch { get; set; } = new ClientStick();
  4104. #endregion
  4105. #region otherTeacher
  4106. public ClientStick otherTch { get; set; } = new ClientStick();
  4107. #endregion
  4108. }
  4109. public class StuStick
  4110. {
  4111. public string school { get; set; }
  4112. /// <summary>
  4113. /// 名字
  4114. /// </summary>
  4115. public string name { get; set; }
  4116. public string picture { get; set; }
  4117. /// <summary>
  4118. /// 编码
  4119. /// </summary>
  4120. public string id { get; set; }
  4121. public string last { get; set; }
  4122. #region tmd
  4123. public ClientStick student { get; set; } = new ClientStick();
  4124. #endregion
  4125. #region ies5Student
  4126. public ClientStick ies5Stu { get; set; } = new ClientStick();
  4127. #endregion
  4128. #region otherStudent
  4129. public ClientStick otherStu { get; set; } = new ClientStick();
  4130. #endregion
  4131. }
  4132. public class ClientStick
  4133. {
  4134. public int userCount { get; set; }
  4135. public int userUpdown { get; set; }
  4136. public Indicator stick { get; set; } = new Indicator();
  4137. public Indicator duration { get; set; } = new Indicator();
  4138. public Indicator count { get; set; } = new Indicator();
  4139. }
  4140. public class Indicator
  4141. {
  4142. /// <summary>
  4143. /// 值
  4144. /// </summary>
  4145. public double value { get; set; } = 0;
  4146. /// <summary>
  4147. /// 值的增减浮动
  4148. /// </summary>
  4149. public double range { get; set; } = 0;
  4150. /// <summary>
  4151. /// 排名
  4152. /// </summary>
  4153. public double rank { get; set; } = 0;
  4154. /// <summary>
  4155. /// 排名的上升下降
  4156. /// </summary>
  4157. public double updown { get; set; } = 0;
  4158. }
  4159. public class Stick
  4160. {
  4161. public List<SchoolStick> schoolSticks { get; set; } = new List<SchoolStick>();
  4162. public List<TchStick> tchSticks { get; set; } = new List<TchStick>();
  4163. }
  4164. public class LessonWeek
  4165. {
  4166. /// <summary>
  4167. /// 第几周
  4168. /// </summary>
  4169. public int week { get; set; }
  4170. /// <summary>
  4171. /// 课例id
  4172. /// </summary>
  4173. public string? id { get; set; }
  4174. /// <summary>
  4175. /// 课程id
  4176. /// </summary>
  4177. public string? cid { get; set; }
  4178. /// <summary>
  4179. /// 科目id
  4180. /// </summary>
  4181. public string? sid { get; set; }
  4182. /// <summary>
  4183. /// 学校
  4184. /// </summary>
  4185. public string? school { get; set; }
  4186. /// <summary>
  4187. /// 名单id
  4188. /// </summary>
  4189. public string? gid { get; set; }
  4190. /// <summary>
  4191. /// 学段id
  4192. /// </summary>
  4193. //public string? pid { get; set; }
  4194. public string? scope { get; set; }
  4195. }
  4196. public class Product
  4197. {
  4198. public string Name { get; set; }
  4199. public double VisitDuration { get; set; }
  4200. public double VisitCount { get; set; }
  4201. public double CalculateProductIndex(double timeWeight, double countWeight, double minVisitDuration, double maxVisitDuration, double minVisitCount, double maxVisitCount)
  4202. {
  4203. // 计算访问时长的Min-Max标准化值
  4204. double standardizedVisitDuration = (maxVisitDuration - minVisitDuration)!=0 ? (VisitDuration - minVisitDuration) / (maxVisitDuration - minVisitDuration) : 0;
  4205. // 计算访问次数的Min-Max标准化值
  4206. double standardizedVisitCount = (maxVisitCount - minVisitCount)!=0 ? (VisitCount - minVisitCount) / (maxVisitCount - minVisitCount) : 0;
  4207. // 计算加权综合指数
  4208. double comprehensiveIndex = timeWeight * standardizedVisitDuration + countWeight * standardizedVisitCount;
  4209. return Math.Round(comprehensiveIndex, 4);
  4210. }
  4211. }
  4212. }
  4213. }