LessonService.cs 61 KB

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