LessonService.cs 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160
  1. using Azure.Core;
  2. using Azure.Cosmos;
  3. using Azure.Messaging.ServiceBus;
  4. using DocumentFormat.OpenXml.Drawing.Charts;
  5. using DocumentFormat.OpenXml.VariantTypes;
  6. using HTEXLib.COMM.Helpers;
  7. using MathNet.Numerics.Distributions;
  8. using Microsoft.Extensions.Configuration;
  9. using Microsoft.Extensions.Hosting;
  10. using OpenXmlPowerTools;
  11. using StackExchange.Redis;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Linq;
  15. using System.Text;
  16. using System.Text.Json;
  17. using System.Threading.Tasks;
  18. using TEAMModelOS.SDK.DI;
  19. using TEAMModelOS.SDK.Extension;
  20. using TEAMModelOS.SDK.Models.Cosmos.Common;
  21. using TEAMModelOS.SDK.Models.Cosmos.OpenEntity;
  22. using TEAMModelOS.SDK.Services;
  23. namespace TEAMModelOS.SDK.Models.Service
  24. {
  25. public class LessonService
  26. {
  27. public static readonly DateTime dateTime1970 = new DateTime(1970, 1, 1).ToLocalTime();
  28. public static Dictionary<string, object> GetLessonCond(JsonElement request)
  29. {
  30. Dictionary<string, object> dict = new Dictionary<string, object>();
  31. if (request.TryGetProperty("tmdid", out JsonElement tmdid))
  32. {
  33. if (tmdid.ValueKind.Equals(JsonValueKind.String) && !string.IsNullOrWhiteSpace($"{tmdid}"))
  34. {
  35. dict.Add("tmdid", tmdid);
  36. }
  37. else if(tmdid.ValueKind.Equals(JsonValueKind.Array)) {
  38. dict.Add("tmdid", tmdid);
  39. }
  40. }
  41. if (request.TryGetProperty("courseId", out JsonElement courseId) && !string.IsNullOrWhiteSpace($"{courseId}"))
  42. {
  43. dict.Add("courseId", courseId);
  44. }
  45. if (request.TryGetProperty("courseIds", out JsonElement courseIds))
  46. {
  47. dict.Add("courseId[*]", courseIds);
  48. }
  49. if (request.TryGetProperty("periodId", out JsonElement periodId) && !string.IsNullOrWhiteSpace($"{periodId}"))
  50. {
  51. dict.Add("periodId", periodId);
  52. }
  53. if (request.TryGetProperty("subjectId", out JsonElement subjectId))
  54. {
  55. dict.Add("subjectId", subjectId);
  56. }
  57. if (request.TryGetProperty("groupIds", out JsonElement groupIds))
  58. {
  59. dict.Add("groupIds[*]", groupIds);
  60. }
  61. if (request.TryGetProperty("grade", out JsonElement grade))
  62. {
  63. dict.Add("grade[*]", grade);
  64. }
  65. if (request.TryGetProperty("category", out JsonElement category))
  66. {
  67. dict.Add("category[*]", category);
  68. }
  69. if (request.TryGetProperty("doubleGreen", out JsonElement doubleGreen) && doubleGreen.GetBoolean())
  70. {
  71. dict.Add("=.tLevel", 2);
  72. dict.Add("=.pLevel", 2);
  73. //dict.Add(">=.tScore", 70);
  74. //dict.Add(">=.pScore", 70);
  75. }
  76. if (request.TryGetProperty("doubleRed", out JsonElement doubleRed) && doubleRed.GetBoolean())
  77. {
  78. dict.Add("=.tLevel", 0);
  79. dict.Add("=.pLevel", 0);
  80. //dict.Add(">=.tScore", 70);
  81. //dict.Add(">=.pScore", 70);
  82. }
  83. if (request.TryGetProperty("quality", out JsonElement quality) && quality.GetBoolean())
  84. {
  85. dict.Add(">=.discuss", 1);
  86. }
  87. if (request.TryGetProperty("excellent", out JsonElement excellent) && excellent.GetBoolean())
  88. {
  89. dict.Add(">=.excellent", 1);
  90. }
  91. if (request.TryGetProperty("name", out JsonElement name) && !string.IsNullOrWhiteSpace($"{name}"))
  92. {
  93. dict.Add("$.name", name);
  94. }
  95. if (request.TryGetProperty("today", out JsonElement today) && today.GetBoolean())
  96. {
  97. DateTime dateTimeA = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D"));
  98. DateTime dateTimeB = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D")).AddDays(1);
  99. double dayOf00_00_00 = (dateTimeA - dateTime1970).TotalMilliseconds;
  100. double day1Of00_00_00 = (dateTimeB - dateTime1970).TotalMilliseconds;
  101. dict.Add(">=.startTime", dayOf00_00_00);
  102. dict.Add("<.startTime", day1Of00_00_00);
  103. }
  104. if (request.TryGetProperty("week", out JsonElement week) && week.GetBoolean())
  105. {
  106. // DateTime dateTimeA = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D"));
  107. DateTime dateTimeB = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D")).AddDays(-7);
  108. double now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  109. double dayB = (dateTimeB - dateTime1970).TotalMilliseconds;
  110. dict.Add("<=.startTime", now);
  111. dict.Add(">=.startTime", dayB);
  112. }
  113. //查询即将到期的且没有被清理的。
  114. if (request.TryGetProperty("expire", out JsonElement expire) && expire.ValueKind.Equals(JsonValueKind.True))
  115. {
  116. dict.Add(">.expire", 0);
  117. dict.Add("!=.status", 404);
  118. }
  119. //查询已经清理的
  120. if (request.TryGetProperty("is404", out JsonElement is404) && is404.ValueKind.Equals(JsonValueKind.True))
  121. {
  122. dict.Add("=.status", 404);
  123. }
  124. //只查有效的
  125. if (request.TryGetProperty("isOk", out JsonElement isOk) && isOk.ValueKind.Equals(JsonValueKind.True))
  126. {
  127. dict.Add("<=.expire", 0);
  128. dict.Add("!=.status", 404);
  129. }
  130. if (request.TryGetProperty("month", out JsonElement month) && month.GetBoolean())
  131. {
  132. //DateTime dateTimeA = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D"));
  133. DateTime dateTimeB = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D")).AddDays(-30);
  134. double now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  135. double dayB = (dateTimeB - dateTime1970).TotalMilliseconds;
  136. dict.Add("<=.startTime", now);
  137. dict.Add(">=.startTime", dayB);
  138. }
  139. if (request.TryGetProperty("stime", out JsonElement stime) && !string.IsNullOrWhiteSpace($"{stime}"))
  140. {
  141. dict.Add(">=.startTime", stime);
  142. }
  143. if (request.TryGetProperty("etime", out JsonElement etime) && !string.IsNullOrWhiteSpace($"{etime}"))
  144. {
  145. dict.Add("<=.startTime", etime);
  146. }
  147. if (request.TryGetProperty("conds", out JsonElement conds) && conds.ValueKind.Equals(JsonValueKind.Array))
  148. {
  149. List<LessonSettingCond> settingConds = conds.Deserialize<List<LessonSettingCond>>();
  150. foreach (var item in settingConds)
  151. {
  152. dict.TryAdd($"{item.type}.{item.key}", item.val);
  153. //switch (item.type)
  154. //{
  155. // case ">=":
  156. // dict.TryAdd($">=.{item.key}",item.val);
  157. // break;
  158. // case "<=":
  159. // dict.TryAdd($"<=.{item.key}", item.val);
  160. // break;
  161. //}
  162. }
  163. }
  164. return dict;
  165. }
  166. public static async void DoLessonStudentRecord(DingDing _dingding, SnowflakeId snowflakeId, LessonRecord lessonRecord, string scope, CosmosClient client, string school, string tmdid,
  167. Teacher teacher, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, IConfiguration _configuration, LessonBase lessonBase,AzureRedisFactory _azureRedis,
  168. List<int> pickupMemberIds, List<TaskData> taskDatas, List<IRSData> iRSDatas)
  169. {
  170. School schoolBase = null;
  171. Period period = null;
  172. try
  173. {
  174. int year = DateTimeOffset.UtcNow.Year;
  175. string hs = lessonBase?.report?.clientSummaryList.ToJsonString();
  176. var clientSummaryLists = lessonBase?.report?.clientSummaryList?.Where(x => x.groupTaskCompleteCount != 0 || x.groupScore != 0 || x.score != 0 || x.interactScore != 0 || x.taskCompleteCount != 0);
  177. IEnumerable<LessonStudent> students = new List<LessonStudent>();
  178. if (clientSummaryLists.Any())
  179. {
  180. var ids = clientSummaryLists.Select(x => x.seatID);
  181. students = lessonBase.student.Where(x => ids.Contains(x.seatID));
  182. }
  183. List<Student> studentsBase = new List<Student>();
  184. var stuids = students.Where(x => x.type == 2);
  185. if (stuids.Any())
  186. {
  187. stuids.ToList().ForEach(x => {
  188. x.school = string.IsNullOrWhiteSpace(x.school) ? school : x.school;
  189. });
  190. var result= await client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<Student>($"select value c from c where c.id in ({string.Join(",",stuids.Select(d=>$"'{d.id}'"))})", $"Base-{school}");
  191. if (result.list.Any()) {
  192. studentsBase = result.list;
  193. }
  194. }
  195. var groups = stuids.Where(z => !string.IsNullOrWhiteSpace(z.school)).GroupBy(x => x.school).Select(y => new { code = y.Key, list = y.ToList() });
  196. List<StudentScoreRecord> lessonStudentRecords = new List<StudentScoreRecord>();
  197. foreach (var group in groups)
  198. {
  199. string stusql = $"select value(c) from c where c.stuid in({string.Join(",", group.list.Select(x => $"'{x.id}'"))}) and c.school='{group.code}' and c.year={year}";
  200. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryIterator<StudentScoreRecord>(queryText: stusql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"StudentScoreRecord") }))
  201. {
  202. lessonStudentRecords.Add(item);
  203. }
  204. }
  205. var tmdids = students.Where(x => x.type == 1);
  206. if (tmdids.Any())
  207. {
  208. string tmdsql = $"select value(c) from c where c.tmdid in({string.Join(",", tmdids.Select(x => $"'{x}'"))}) and c.year={year}";
  209. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryIterator<StudentScoreRecord>(queryText: tmdsql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"StudentScoreRecord") }))
  210. {
  211. lessonStudentRecords.Add(item);
  212. }
  213. }
  214. (Semester currSemester, int studyYear, DateTimeOffset currSemesterDate, DateTimeOffset date, DateTimeOffset nextSemester) dataSemester = new(null,-1, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow) ;
  215. if (!string.IsNullOrWhiteSpace(school)) {
  216. schoolBase = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
  217. period = schoolBase.period.Find(x => x.id.Equals($"{lessonRecord.periodId}"));
  218. if (period!= null) {
  219. dataSemester= SchoolService.GetSemester(period);
  220. }
  221. }
  222. List <Task<ItemResponse<StudentScoreRecord>>> records = new List<Task<ItemResponse<StudentScoreRecord>>>();
  223. HashSet <OverallEducation> overallEducations = new HashSet<OverallEducation>();
  224. // 互动次数,-1 表示没有进行互动。 与 0 不同
  225. int interactCount = -1;
  226. //抢权作答的学生
  227. List<int > buzzClients= new List<int>();
  228. if (iRSDatas.IsNotEmpty()) {
  229. var keys = iRSDatas.Where(z => z.isBuzz==false).Select(v => v.clientAnswers).SelectMany(z => z.Keys).ToList();
  230. var values = iRSDatas.Where(z => z.isBuzz==false).Select(v => v.clientAnswers).SelectMany(z => z.Values).ToList();
  231. interactCount= keys.Count();
  232. var bclients = iRSDatas.Where(z => z.buzzClients.IsNotEmpty()).SelectMany(v => v.buzzClients);
  233. if (bclients!=null && bclients.Count()>0) {
  234. foreach (var bc in bclients) {
  235. if (int.TryParse(bc, out int b)) {
  236. buzzClients.Add(b);
  237. }
  238. }
  239. }
  240. }
  241. //任务发布次数 ,-1 表示没有进行互动。 与 0 不同
  242. int taskCount = -1;
  243. var groupNames = lessonBase.report.clientSummaryList.Where(z => !string.IsNullOrEmpty(z.groupName))?.Select(z=>z.groupName)?.ToHashSet()?.OrderBy(z=>z)?.ToList();
  244. List<IdCodeCount> groupTaskJoinCounts = new List<IdCodeCount>();
  245. if (groupNames.IsNotEmpty()) {
  246. groupTaskJoinCounts = groupNames.Select(z => new IdCodeCount { name=z, count = 0 }).ToList();
  247. }
  248. //組任務發佈數
  249. int groupTaskCount = -1;
  250. if (taskDatas.IsNotEmpty())
  251. {
  252. taskCount=0;
  253. bool hasGroupTask = false;
  254. int groupTaksCountTemp = 0;
  255. foreach (var taskData in taskDatas)
  256. {
  257. var isGroupItem = taskData.clientWorks.FindAll(z => z.isGroupItem);
  258. if (isGroupItem.IsNotEmpty())
  259. {
  260. //有组任务
  261. hasGroupTask = true;
  262. groupTaksCountTemp += 1;
  263. foreach (var item in isGroupItem)
  264. {
  265. int groupIndex = 0;
  266. int.TryParse(item.groupID,out groupIndex);
  267. //由于分组下标从1 开始,则需要判断是否与分组数组大小一致,且提交了作品,则数量+1
  268. if ( groupIndex>0 && item.blobFiles.IsNotEmpty() && groupIndex <= groupTaskJoinCounts.Count) {
  269. groupTaskJoinCounts[groupIndex-1].count+=1;
  270. }
  271. }
  272. }
  273. else
  274. {
  275. //没有组任务
  276. taskCount += 1;
  277. }
  278. }
  279. if (hasGroupTask) {
  280. groupTaskCount=groupTaksCountTemp;
  281. }
  282. }
  283. foreach (var x in stuids) {
  284. var record = lessonStudentRecords.Find(l => l.stuid.Equals(x.id) && l.code.Equals($"StudentScoreRecord") && l.school.Equals(x.school));
  285. ClientSummaryList clientSummaryList = lessonBase.report.clientSummaryList.Find(c => c.seatID == x.seatID);
  286. int stuInteractCount = -1;
  287. int stuInteractJoin = 0;
  288. //获取挑人的互动
  289. var ids= pickupMemberIds.FindAll(z => z==x.seatID);
  290. if (ids.IsNotEmpty())
  291. {
  292. stuInteractJoin=ids.Count;
  293. if (interactCount>=0)
  294. {
  295. stuInteractCount=interactCount+ids.Count;
  296. }
  297. else
  298. {
  299. stuInteractCount=ids.Count;
  300. }
  301. }
  302. //获取抢权的互动
  303. var buzIds = buzzClients.FindAll(z => z==x.seatID);
  304. if (buzIds.IsNotEmpty()) {
  305. stuInteractJoin=stuInteractJoin+buzIds.Count;
  306. if (stuInteractCount>-1)
  307. {
  308. stuInteractCount = stuInteractCount + buzIds.Count;
  309. }
  310. else {
  311. stuInteractCount = buzIds.Count;
  312. }
  313. }
  314. //普通作答的互动
  315. if (record != null)
  316. {
  317. if (clientSummaryList != null)
  318. {
  319. var hasrecord = record.lessonRecords.Find(x => x.lessonId.Equals(lessonRecord.id));
  320. if (hasrecord != null)
  321. {
  322. hasrecord.gscore = clientSummaryList.groupScore;
  323. hasrecord.pscore = clientSummaryList.score;
  324. hasrecord.tscore = clientSummaryList.interactScore;
  325. hasrecord.tmdid = teacher.id;
  326. hasrecord.school = school;
  327. hasrecord.scope = lessonRecord.scope;
  328. hasrecord.lessonId = lessonRecord.id;
  329. hasrecord.courseId = lessonRecord.courseId;
  330. hasrecord.periodId = lessonRecord.periodId;
  331. hasrecord.subjectId = lessonRecord.subjectId;
  332. hasrecord.time = lessonRecord.startTime;
  333. }
  334. else
  335. {
  336. record.lessonRecords.Add(
  337. new StudentLessonRecord
  338. {
  339. gscore = clientSummaryList.groupScore,
  340. pscore = clientSummaryList.score,
  341. tscore = clientSummaryList.interactScore,
  342. tmdid = teacher.id,
  343. school = school,
  344. scope = lessonRecord.scope,
  345. lessonId = lessonRecord.id,
  346. courseId = lessonRecord.courseId,
  347. periodId = lessonRecord.periodId,
  348. subjectId = lessonRecord.subjectId,
  349. time = lessonRecord.startTime
  350. }
  351. );
  352. }
  353. }
  354. }
  355. else
  356. {
  357. record = new StudentScoreRecord
  358. {
  359. userType = Constant.ScopeStudent,
  360. id = $"{snowflakeId.NextId()}",
  361. year = year,
  362. stuid = x.id,
  363. school = x.school,
  364. code = $"StudentScoreRecord",
  365. pk = "StudentScoreRecord",
  366. ttl = -1,
  367. lessonRecords = new List<StudentLessonRecord> { new StudentLessonRecord
  368. {
  369. gscore = clientSummaryList.groupScore,
  370. pscore = clientSummaryList.score,
  371. tscore = clientSummaryList.interactScore,
  372. tmdid = teacher.id,
  373. school = school,
  374. scope = lessonRecord.scope,
  375. lessonId = lessonRecord.id,
  376. courseId = lessonRecord.courseId,
  377. periodId = lessonRecord.periodId,
  378. subjectId = lessonRecord.subjectId,
  379. time= lessonRecord.startTime
  380. }}
  381. };
  382. }
  383. record.userType = Constant.ScopeStudent;
  384. record.gscore = record.lessonRecords.Select(x => x.gscore).Sum();
  385. record.pscore = record.lessonRecords.Select(x => x.pscore).Sum();
  386. record.tscore = record.lessonRecords.Select(x => x.tscore).Sum();
  387. if (dataSemester.currSemester != null && (clientSummaryList.groupScore>0 || clientSummaryList.score > 0 || clientSummaryList.interactScore > 0))
  388. {
  389. string oid = $"{dataSemester.studyYear}-{dataSemester.currSemester.id}-{record.stuid}";
  390. string ocode = $"OverallEducation-{school}";
  391. var student = studentsBase.Find(stu => stu.id.Equals(x.id));
  392. Azure.Response response = await client.GetContainer(Constant.TEAMModelOS, Constant.Student).ReadItemStreamAsync(oid, new PartitionKey(ocode));
  393. OverallEducation overallEducation = null;
  394. if (response.Status != 200)
  395. {
  396. overallEducation = new OverallEducation
  397. {
  398. id =oid,
  399. code = $"OverallEducation-{school}",
  400. pk = "OverallEducation",
  401. ttl = -1,
  402. name = x.name,
  403. classId = student?.classId,
  404. schoolCode = $"{school}",
  405. semesterId = dataSemester.currSemester.id,
  406. year = dataSemester.studyYear,
  407. periodId = $"{period.id}",
  408. stuYear = student.year,
  409. studentId = x.id,
  410. lessonScore= new List<StudentLessonRecord> { new StudentLessonRecord
  411. {
  412. gscore = clientSummaryList.groupScore,
  413. pscore = clientSummaryList.score,
  414. tscore = clientSummaryList.interactScore,
  415. tmdid = teacher.id,
  416. school = school,
  417. scope = lessonRecord.scope,
  418. lessonId = lessonRecord.id,
  419. courseId = lessonRecord.courseId,
  420. periodId = lessonRecord.periodId,
  421. subjectId = lessonRecord.subjectId,
  422. time= lessonRecord.startTime
  423. }}
  424. };
  425. }
  426. else
  427. {
  428. overallEducation=JsonDocument.Parse(response.Content).RootElement.ToObject<OverallEducation>();
  429. var hasrecord = overallEducation.lessonScore.Find(x => x.lessonId.Equals(lessonRecord.id));
  430. if (hasrecord != null)
  431. {
  432. hasrecord.gscore = clientSummaryList.groupScore;
  433. hasrecord.pscore = clientSummaryList.score;
  434. hasrecord.tscore = clientSummaryList.interactScore;
  435. hasrecord.tmdid = teacher.id;
  436. hasrecord.school = school;
  437. hasrecord.scope = lessonRecord.scope;
  438. hasrecord.lessonId = lessonRecord.id;
  439. hasrecord.courseId = lessonRecord.courseId;
  440. hasrecord.periodId = lessonRecord.periodId;
  441. hasrecord.subjectId = lessonRecord.subjectId;
  442. hasrecord.time = lessonRecord.startTime;
  443. }
  444. else
  445. {
  446. overallEducation.lessonScore.Add(
  447. new StudentLessonRecord
  448. {
  449. gscore = clientSummaryList.groupScore,
  450. pscore = clientSummaryList.score,
  451. tscore = clientSummaryList.interactScore,
  452. tmdid = teacher.id,
  453. school = school,
  454. scope = lessonRecord.scope,
  455. lessonId = lessonRecord.id,
  456. courseId = lessonRecord.courseId,
  457. periodId = lessonRecord.periodId,
  458. subjectId = lessonRecord.subjectId,
  459. time = lessonRecord.startTime
  460. }
  461. );
  462. }
  463. }
  464. overallEducations.Add(overallEducation);
  465. }
  466. records.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(record, partitionKey: new PartitionKey(record.code)));
  467. }
  468. foreach (var x in tmdids) {
  469. var record = lessonStudentRecords.Find(l => l.tmdid.Equals(x.id) && l.code.Equals($"StudentScoreRecord"));
  470. ClientSummaryList clientSummaryList = lessonBase.report.clientSummaryList.Find(c => c.seatID == x.seatID);
  471. if (record != null)
  472. {
  473. if (clientSummaryList != null)
  474. {
  475. var hasrecord = record.lessonRecords.Find(x => x.lessonId.Equals(lessonRecord.id));
  476. if (hasrecord != null)
  477. {
  478. hasrecord.gscore = clientSummaryList.groupScore;
  479. hasrecord.pscore = clientSummaryList.score;
  480. hasrecord.tscore = clientSummaryList.interactScore;
  481. hasrecord.tmdid = teacher.id;
  482. hasrecord.school = school;
  483. hasrecord.scope = lessonRecord.scope;
  484. hasrecord.lessonId = lessonRecord.id;
  485. hasrecord.courseId = lessonRecord.courseId;
  486. hasrecord.periodId = lessonRecord.periodId;
  487. hasrecord.subjectId = lessonRecord.subjectId;
  488. hasrecord.time = lessonRecord.startTime;
  489. }
  490. else
  491. {
  492. record.lessonRecords.Add(
  493. new StudentLessonRecord
  494. {
  495. gscore = clientSummaryList.groupScore,
  496. pscore = clientSummaryList.score,
  497. tscore = clientSummaryList.interactScore,
  498. tmdid = teacher.id,
  499. school = school,
  500. scope = lessonRecord.scope,
  501. lessonId = lessonRecord.id,
  502. courseId = lessonRecord.courseId,
  503. periodId = lessonRecord.periodId,
  504. subjectId = lessonRecord.subjectId,
  505. time = lessonRecord.startTime
  506. }
  507. );
  508. }
  509. }
  510. }
  511. else
  512. {
  513. record = new StudentScoreRecord
  514. {
  515. userType = Constant.ScopeTmdUser,
  516. id = $"{snowflakeId.NextId()}",
  517. code = $"StudentScoreRecord",
  518. pk = "StudentScoreRecord",
  519. ttl = -1,
  520. year = year,
  521. tmdid = x.id,
  522. lessonRecords = new List<StudentLessonRecord>
  523. {
  524. new StudentLessonRecord
  525. {
  526. gscore = clientSummaryList.groupScore,
  527. pscore = clientSummaryList.score,
  528. tscore = clientSummaryList.interactScore,
  529. tmdid = teacher.id,
  530. school = school,
  531. scope = lessonRecord.scope,
  532. lessonId = lessonRecord.id,
  533. courseId = lessonRecord.courseId,
  534. periodId = lessonRecord.periodId,
  535. subjectId = lessonRecord.subjectId,
  536. time=lessonRecord.startTime
  537. }
  538. }
  539. };
  540. }
  541. record.userType = Constant.ScopeStudent;
  542. record.gscore = record.lessonRecords.Select(x => x.gscore).Sum();
  543. record.pscore = record.lessonRecords.Select(x => x.pscore).Sum();
  544. record.tscore = record.lessonRecords.Select(x => x.tscore).Sum();
  545. records.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(record, partitionKey: new PartitionKey(record.code)));
  546. }
  547. if (records.Any())
  548. {
  549. await Task.WhenAll(records);
  550. }
  551. if (overallEducations.Any())
  552. {
  553. foreach (var item in overallEducations) {
  554. await client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(item, partitionKey: new PartitionKey(item.code));
  555. string key = $"OverallEducation:{item.schoolCode}:{item.periodId}:{item.year}:{item.semesterId}:{item.classId}";
  556. await _azureRedis.GetRedisClient(8).HashSetAsync(key, item.studentId, item.ToJsonString());
  557. await _azureRedis.GetRedisClient(8).KeyExpireAsync(key,new TimeSpan(180 *24 ,0,0));
  558. }
  559. }
  560. }
  561. catch (Exception ex)
  562. {
  563. await _dingding.SendBotMsg($"学生个人课例统计信息异常,{ex.Message}\n{ex.StackTrace},{lessonRecord?.ToJsonString()}{school}", GroupNames.醍摩豆服務運維群組);
  564. }
  565. }
  566. public static async void DoAutoDeleteSchoolLessonRecord(LessonRecord lessonRecord, string scope, CosmosClient client, string school, string tmdid,
  567. Teacher teacher, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, IConfiguration _configuration, CoreAPIHttpService _coreAPIHttpService,DingDing _dingDing,AzureRedisFactory _azureRedis)
  568. {
  569. if (lessonRecord.scope.Equals("school"))
  570. {
  571. SchoolSetting setting = null;
  572. Azure.Response schoolSetting = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync(school, new PartitionKey("SchoolSetting"));
  573. School schoolBase = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
  574. if (schoolSetting.Status == 200)
  575. {
  576. setting = JsonDocument.Parse(schoolSetting.Content).RootElement.Deserialize<SchoolSetting>();
  577. if (setting.lessonSetting != null)
  578. {
  579. //两种状态都不属于,则默认未开启。
  580. if (setting.lessonSetting.openAutoClean != 0 && setting.lessonSetting.openAutoClean != 1)
  581. {
  582. setting.lessonSetting.openAutoClean = 0;
  583. setting.lessonSetting.expireDays = Constant.school_lesson_expire;
  584. }
  585. else {
  586. //属于 要么开启1,要么关闭0
  587. }
  588. }
  589. else
  590. {
  591. setting.lessonSetting = new LessonSetting() { openAutoClean = 0, expireDays = Constant.school_lesson_expire };
  592. }
  593. }
  594. else
  595. {
  596. setting = new SchoolSetting() { lessonSetting = new LessonSetting { openAutoClean = 0, expireDays = Constant.school_lesson_expire } };
  597. }
  598. int school_lesson_expire = 0;
  599. bool save = true;
  600. List<string> msg = new List<string>();
  601. if (setting.lessonSetting.openAutoClean == 1)
  602. {
  603. if (setting.lessonSetting.conds.IsEmpty())
  604. {
  605. save = false;
  606. }
  607. else
  608. {
  609. school_lesson_expire = setting.lessonSetting.expireDays;
  610. foreach (var item in setting.lessonSetting.conds)
  611. {
  612. switch (item.type)
  613. {
  614. case ">=":
  615. switch (item.key)
  616. {
  617. case "attendRate":
  618. if (!(lessonRecord.attendRate >= item.val))
  619. {
  620. save = false;
  621. msg.Add($"{item.key}:{lessonRecord.attendRate}{item.type}{item.val}");
  622. }
  623. break;
  624. case "groupCount":
  625. if (!(lessonRecord.groupCount >= item.val))
  626. {
  627. save = false;
  628. msg.Add($"{item.key}:{lessonRecord.groupCount}{item.type}{item.val}");
  629. }
  630. break;
  631. case "totalPoint":
  632. if (!(lessonRecord.totalPoint >= item.val))
  633. {
  634. save = false;
  635. msg.Add($"{item.key}:{lessonRecord.totalPoint}{item.type}{item.val}");
  636. }
  637. break;
  638. case "collateTaskCount":
  639. if (!(lessonRecord.collateTaskCount >= item.val))
  640. {
  641. save = false;
  642. msg.Add($"{item.key}:{lessonRecord.collateTaskCount}{item.type}{item.val}");
  643. }
  644. break;
  645. case "collateCount":
  646. if (!(lessonRecord.collateCount >= item.val))
  647. {
  648. save = false;
  649. msg.Add($"{item.key}:{lessonRecord.collateCount}{item.type}{item.val}");
  650. }
  651. break;
  652. case "pushCount":
  653. if (!(lessonRecord.pushCount >= item.val))
  654. {
  655. save = false;
  656. msg.Add($"{item.key}:{lessonRecord.pushCount}{item.type}{item.val}");
  657. }
  658. break;
  659. case "totalInteractPoint":
  660. if (!(lessonRecord.totalInteractPoint >= item.val))
  661. {
  662. save = false;
  663. msg.Add($"{item.key}:{lessonRecord.totalInteractPoint}{item.type}{item.val}");
  664. }
  665. break;
  666. case "interactionCount":
  667. if (!(lessonRecord.interactionCount >= item.val))
  668. {
  669. save = false;
  670. msg.Add($"{item.key}:{lessonRecord.interactionCount}{item.type}{item.val}");
  671. }
  672. break;
  673. case "clientInteractionCount":
  674. if (!(lessonRecord.clientInteractionCount >= item.val))
  675. {
  676. save = false;
  677. msg.Add($"{item.key}:{lessonRecord.clientInteractionCount}{item.type}{item.val}");
  678. }
  679. break;
  680. case "examQuizCount":
  681. if (!(lessonRecord.examQuizCount >= item.val))
  682. {
  683. save = false;
  684. msg.Add($"{item.key}:{lessonRecord.examQuizCount}{item.type}{item.val}");
  685. }
  686. break;
  687. case "examPointRate":
  688. if (!(lessonRecord.examPointRate >= item.val))
  689. {
  690. save = false;
  691. msg.Add($"{item.key}:{lessonRecord.examPointRate}{item.type}{item.val}");
  692. }
  693. break;
  694. }
  695. break;
  696. case "<=":
  697. switch (item.key)
  698. {
  699. case "attendRate":
  700. if (!(lessonRecord.attendRate <= item.val))
  701. {
  702. save = false;
  703. msg.Add($"{item.key}:{lessonRecord.attendRate}{item.type}{item.val}");
  704. }
  705. break;
  706. case "groupCount":
  707. if (!(lessonRecord.groupCount <= item.val))
  708. {
  709. save = false;
  710. msg.Add($"{item.key}:{lessonRecord.groupCount}{item.type}{item.val}");
  711. }
  712. break;
  713. case "totalPoint":
  714. if (!(lessonRecord.totalPoint <= item.val))
  715. {
  716. save = false;
  717. msg.Add($"{item.key}:{lessonRecord.totalPoint}{item.type}{item.val}");
  718. }
  719. break;
  720. case "collateTaskCount":
  721. if (!(lessonRecord.collateTaskCount <= item.val))
  722. {
  723. save = false;
  724. msg.Add($"{item.key}:{lessonRecord.collateTaskCount}{item.type}{item.val}");
  725. }
  726. break;
  727. case "collateCount":
  728. if (!(lessonRecord.collateCount <= item.val))
  729. {
  730. save = false;
  731. msg.Add($"{item.key}:{lessonRecord.collateCount}{item.type}{item.val}");
  732. }
  733. break;
  734. case "pushCount":
  735. if (!(lessonRecord.pushCount <= item.val))
  736. {
  737. save = false;
  738. msg.Add($"{item.key}:{lessonRecord.pushCount}{item.type}{item.val}");
  739. }
  740. break;
  741. case "totalInteractPoint":
  742. if (!(lessonRecord.totalInteractPoint <= item.val))
  743. {
  744. save = false;
  745. msg.Add($"{item.key}:{lessonRecord.totalInteractPoint}{item.type}{item.val}");
  746. }
  747. break;
  748. case "interactionCount":
  749. if (!(lessonRecord.interactionCount <= item.val))
  750. {
  751. save = false;
  752. msg.Add($"{item.key}:{lessonRecord.interactionCount}{item.type}{item.val}");
  753. }
  754. break;
  755. case "clientInteractionCount":
  756. if (!(lessonRecord.clientInteractionCount <= item.val))
  757. {
  758. save = false;
  759. msg.Add($"{item.key}:{lessonRecord.clientInteractionCount}{item.type}{item.val}");
  760. }
  761. break;
  762. case "examQuizCount":
  763. if (!(lessonRecord.examQuizCount <= item.val))
  764. {
  765. save = false;
  766. msg.Add($"{item.key}:{lessonRecord.examQuizCount}{item.type}{item.val}");
  767. }
  768. break;
  769. case "examPointRate":
  770. if (!(lessonRecord.examPointRate <= item.val))
  771. {
  772. save = false;
  773. msg.Add($"{item.key}:{lessonRecord.examPointRate}{item.type}{item.val}");
  774. }
  775. break;
  776. }
  777. break;
  778. }
  779. }
  780. }
  781. }
  782. /* 注释start 2023.3.22,该段逻辑在开课的时候已经处理,详见ActiveTaskTopic. LessonRecordEvent create ,无论有没有开启setting.lessonSetting.openAutoClean 自动删除策略,只要空间不足都会对课例进行自动清理管理。
  783. else
  784. {
  785. ///未设置openAutoClean=1时,则检查学校使用空间是否充足。
  786. double usize = 0;
  787. int tsize = schoolBase.tsize;
  788. //schoolBase.tsize
  789. //計算學校或個人的使用空間
  790. RedisValue redisValue = _azureRedis.GetRedisClient(8).HashGet($"Blob:Record", $"{schoolBase.id}");
  791. if (redisValue.HasValue && long.TryParse(redisValue.ToString(), out var bsize))
  792. {
  793. usize = Math.Round(bsize / 1073741824.0 - (tsize), 2, MidpointRounding.AwayFromZero); //1073741824 1G
  794. }
  795. else //如果檢測不到緩存,觸發刷新計算空間
  796. {
  797. await BlobService.RefreshBlobRoot(new BlobRefreshMessage { progress = "update", root = "records", name = $"{schoolBase.id}" }, _serviceBus, _configuration, _azureRedis);
  798. }
  799. ///空间充足的情况保存。
  800. if (schoolBase.size - usize > 0)
  801. {
  802. save = true;
  803. }
  804. else {
  805. save = false;
  806. school_lesson_expire = Constant.school_lesson_expire;
  807. }
  808. } 注释end 2023.3.22,该段逻辑在开课的时候已经处理,详见ActiveTaskTopic. LessonRecordEvent create ,无论有没有开启setting.lessonSetting.openAutoClean 自动删除策略,只要空间不足都会对课例进行自动清理管理。
  809. */
  810. if (!save && school_lesson_expire > 0)
  811. {
  812. // 1-时间戳,7-时间戳
  813. Dictionary<int, ExpireTag> result = new Dictionary<int, ExpireTag>();
  814. //暂定7天
  815. var now = DateTimeOffset.UtcNow;
  816. //剩余3天的通知
  817. //var day3= now.AddDays(school_lesson_expire - 3).ToUnixTimeMilliseconds();
  818. //result.Add(3, day3);
  819. //剩余1天的通知
  820. var day1 = now.AddDays(school_lesson_expire - (school_lesson_expire - 1)).ToUnixTimeMilliseconds();
  821. result.Add(1, new ExpireTag { expire = day1, tag = "notification" });
  822. //到期通知
  823. //不到五点上传的课例,七天之后直接删除。
  824. int addSecond = 0;
  825. if (now.Hour > 5)
  826. {
  827. // 到凌晨00点还差 (24 - now.Hour) *60 * 60 分钟,再加天数;
  828. addSecond = school_lesson_expire * 86400 + (24 - now.Hour) * 3600 - (now.Hour * 3600);
  829. //再加 00到05小时内的 随机秒数
  830. Random rand = new Random();
  831. int randInt = rand.Next(0, 18000);
  832. addSecond += randInt;
  833. }
  834. else
  835. {
  836. addSecond = school_lesson_expire * 24 * 60 * 60;
  837. }
  838. lessonRecord.expire = now.AddSeconds(addSecond).ToUnixTimeMilliseconds();
  839. result.Add(school_lesson_expire, new ExpireTag { expire = lessonRecord.expire, tag = "delete" });
  840. // result.Add(school_lesson_expire, lessonRecord.expire);
  841. string biz = "expire";
  842. string expireTime = DateTimeOffset.FromUnixTimeMilliseconds(lessonRecord.expire).ToString("yyyy-MM-dd HH:mm:ss");
  843. Teacher targetTeacher = await client.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>($"{tmdid}", new PartitionKey($"Base"));
  844. _coreAPIHttpService.PushNotify(new List<IdNameCode> { new IdNameCode { id = targetTeacher.id, name = targetTeacher.name, code = targetTeacher.lang } }, "expire-school_lessonRecord", Constant.NotifyType_IES5_Course,
  845. new Dictionary<string, object> { { "tmdid", teacher.id }, { "tmdname", teacher.name }, { "schoolName", schoolBase.name },
  846. { "schoolId", $"{school}" },{ "lessonId",lessonRecord.id }, { "expireTime", expireTime },{ "lessonName",lessonRecord.name } }, $"{Environment.GetEnvironmentVariable("Option:Location")}", _configuration, _dingDing, "");
  847. var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
  848. List<ChangeRecord> records = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", lessonRecord.id } });
  849. if (records.Count <= 0)
  850. {
  851. foreach (var item in result)
  852. {
  853. string PartitionKey = string.Format("{0}{1}{2}", lessonRecord.code, "-", $"expire-{item.Key}");
  854. //课堂的id ,
  855. //课堂的通知时间类型progress, 默认就会发送一条,到期前一天发送一条,最后已到期发送一条。
  856. var message = new ServiceBusMessage(new
  857. {
  858. id = lessonRecord.id,
  859. progress = item.Key,
  860. code = lessonRecord.code,
  861. scope = lessonRecord.scope,
  862. school = lessonRecord.school,
  863. opt = "delete",
  864. expire = lessonRecord.expire,
  865. tmdid = tmdid,
  866. tmdname = teacher.name,
  867. name = lessonRecord.name,
  868. startTime = lessonRecord.startTime,
  869. tag = item.Value.tag
  870. }.ToJsonString());
  871. message.ApplicationProperties.Add("name", "LessonRecordExpire");
  872. long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), message, DateTimeOffset.FromUnixTimeMilliseconds(item.Value.expire));
  873. ChangeRecord changeRecord = new ChangeRecord
  874. {
  875. RowKey = lessonRecord.id,
  876. PartitionKey = PartitionKey,
  877. sequenceNumber = start,
  878. msgId = message.MessageId
  879. };
  880. await table.Save<ChangeRecord>(changeRecord);
  881. }
  882. }
  883. }
  884. else
  885. {
  886. if (lessonRecord.expire > 0)
  887. {
  888. var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
  889. List<ChangeRecord> records = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", lessonRecord.id } });
  890. foreach (var record in records)
  891. {
  892. try
  893. {
  894. await table.DeleteSingle<ChangeRecord>(record.PartitionKey, record.RowKey);
  895. await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), record.sequenceNumber);
  896. }
  897. catch (Exception)
  898. {
  899. continue;
  900. }
  901. }
  902. }
  903. lessonRecord.save = 1;
  904. lessonRecord.expire = -1;
  905. }
  906. }
  907. }
  908. public record ExpireTag
  909. {
  910. public long expire { get; set; }
  911. public string tag { get; set; }
  912. }
  913. /// <summary>
  914. ///
  915. /// </summary>
  916. /// <param name="client"></param>
  917. /// <param name="_dingDing"></param>
  918. /// <param name="data"></param>
  919. /// <returns></returns>
  920. public static LessonDis DisLessonCount(LessonRecord oldRecord, LessonRecord newRecord, LessonDis lessonDis)
  921. {
  922. //创建课堂的情况
  923. if (oldRecord == null && newRecord != null)
  924. {
  925. lessonDis.record = 1;
  926. }
  927. //删除数据的情况
  928. //不再对LessonCount进行减
  929. else if (oldRecord != null && newRecord == null)
  930. {
  931. /*lessonDis.record = -1;
  932. //P分数量加减
  933. if (oldRecord.pScore >= 70)
  934. {
  935. lessonDis.disPCount = -1;
  936. }
  937. //T分数量加减
  938. if (oldRecord.tScore >= 70)
  939. {
  940. lessonDis.disTCount = -1;
  941. }
  942. if (oldRecord.tScore >= 70 && oldRecord.pScore >= 70)
  943. {
  944. lessonDis.disTCount = -1;
  945. }*/
  946. }
  947. //无效操作
  948. else if (oldRecord == null && newRecord == null)
  949. {
  950. }
  951. //前后操作都有值,则表示更新
  952. else
  953. {
  954. //P分数量加减
  955. if (oldRecord.pScore >= 70)
  956. {
  957. if (newRecord.pScore < 70)
  958. {
  959. lessonDis.disPCount = -1;
  960. }
  961. }
  962. else
  963. {
  964. if (newRecord.pScore >= 70)
  965. {
  966. lessonDis.disPCount = 1;
  967. }
  968. }
  969. //T分数量加减
  970. if (oldRecord.tScore >= 70)
  971. {
  972. if (newRecord.tScore < 70)
  973. {
  974. lessonDis.disTCount = -1;
  975. }
  976. }
  977. else
  978. {
  979. if (newRecord.tScore >= 70)
  980. {
  981. lessonDis.disTCount = 1;
  982. }
  983. }
  984. //双绿灯数量
  985. if (oldRecord.tScore >= 70 && oldRecord.pScore >= 70)
  986. {
  987. if (newRecord.tScore < 70 || newRecord.pScore < 70)
  988. {
  989. lessonDis.disDCount = -1;
  990. }
  991. }
  992. else
  993. {
  994. if (newRecord.tScore >= 70 && newRecord.pScore >= 70)
  995. {
  996. lessonDis.disDCount = 1;
  997. }
  998. }
  999. }
  1000. return lessonDis;
  1001. }
  1002. public static LessonDis DisLessonCount_2(LessonRecord oldRecord, LessonRecord newRecord, LessonDis lessonDis)
  1003. {
  1004. //创建课堂的情况
  1005. if (oldRecord == null && newRecord != null)
  1006. {
  1007. lessonDis.record = 1;
  1008. //P分数量加减
  1009. if (newRecord.pScore >= 70)
  1010. {
  1011. lessonDis.disPCount = 1;
  1012. }
  1013. //T分数量加减
  1014. if (newRecord.tScore >= 70)
  1015. {
  1016. lessonDis.disTCount = 1;
  1017. }
  1018. //双绿灯数量
  1019. if (newRecord.tScore >= 70 && newRecord.pScore >= 70)
  1020. {
  1021. lessonDis.disDCount = 1;
  1022. }
  1023. }
  1024. return lessonDis;
  1025. }
  1026. public static async Task FixLessonCount(CosmosClient client, DingDing _dingDing, LessonRecord record, LessonRecord oldRecord, LessonDis lessonDis)
  1027. {
  1028. LessonRecord data = null;
  1029. try
  1030. {
  1031. if (record != null && oldRecord == null)
  1032. {
  1033. data = record;
  1034. }
  1035. if (record == null && oldRecord != null)
  1036. {
  1037. data = oldRecord;
  1038. }
  1039. if (record != null && oldRecord != null)
  1040. {
  1041. data = record;
  1042. }
  1043. int day = DateTimeOffset.FromUnixTimeMilliseconds(data.startTime).DayOfYear;
  1044. int year = DateTimeOffset.FromUnixTimeMilliseconds(data.startTime).Year;
  1045. int days = DateTimeHelper.getDays(year);
  1046. //int years = DateTimeOffset.UtcNow.DayOfYear;
  1047. string tbname = string.Empty;
  1048. string code = string.Empty;
  1049. if (data.groupIds.Any()) {
  1050. if (data.scope != null && data.scope.Equals("school"))
  1051. {
  1052. if (string.IsNullOrEmpty(data.periodId))
  1053. {
  1054. code = $"LessonCount-{data.school}-{year}";
  1055. tbname = "School";
  1056. }
  1057. else
  1058. {
  1059. code = $"LessonCount-{data.school}-{year}-{data.periodId}";
  1060. tbname = "School";
  1061. }
  1062. }
  1063. else
  1064. {
  1065. code = $"LessonCount-{year}";
  1066. tbname = "Teacher";
  1067. }
  1068. var response = await client.GetContainer(Constant.TEAMModelOS, tbname).ReadItemStreamAsync(data.tmdid.ToString(), new PartitionKey(code));
  1069. if (response.Status == 200)
  1070. {
  1071. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  1072. LessonCount count = json.ToObject<LessonCount>();
  1073. count.tCount[day - 1] += lessonDis.disTCount;
  1074. count.pCount[day - 1] += lessonDis.disPCount;
  1075. count.ptCount[day - 1] += lessonDis.disDCount;
  1076. count.beginCount[day - 1] += lessonDis.record;
  1077. await client.GetContainer("TEAMModelOS", tbname).ReplaceItemAsync(count, count.id, new PartitionKey(code));
  1078. }
  1079. else
  1080. {
  1081. LessonCount count = new()
  1082. {
  1083. id = data.tmdid,
  1084. code = code,
  1085. ttl = -1
  1086. };
  1087. double[] da = new double[days];
  1088. List<double> list = new(da);
  1089. List<double> listT = new(da);
  1090. List<double> listP = new(da);
  1091. List<double> listPT = new(da);
  1092. list[day - 1] += lessonDis.record;
  1093. listT[day - 1] += lessonDis.disTCount;
  1094. listP[day - 1] += lessonDis.disPCount;
  1095. listPT[day - 1] += lessonDis.disDCount;
  1096. count.beginCount.AddRange(list);
  1097. count.tCount.AddRange(listT);
  1098. count.pCount.AddRange(listP);
  1099. count.ptCount.AddRange(listPT);
  1100. //count.courseIds.Add(data.courseId);
  1101. await client.GetContainer("TEAMModelOS", tbname).CreateItemAsync(count, new PartitionKey(code));
  1102. }
  1103. }
  1104. }
  1105. catch (Exception ex)
  1106. {
  1107. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-LessonCount-FixLessonCount\n{ex.Message}\n{ex.StackTrace}{data.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
  1108. }
  1109. }
  1110. }
  1111. }