LessonService.cs 60 KB

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