LessonService.cs 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. using Azure.Cosmos;
  2. using Azure.Messaging.ServiceBus;
  3. using HTEXLib.COMM.Helpers;
  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.Helper.Common.DateTimeHelper;
  14. using TEAMModelOS.SDK.Models.Cosmos.Common;
  15. namespace TEAMModelOS.SDK.Models.Service
  16. {
  17. public class LessonService
  18. {
  19. public static readonly DateTime dateTime1970 = new DateTime(1970, 1, 1).ToLocalTime();
  20. public static Dictionary<string, object> GetLessonCond(JsonElement request)
  21. {
  22. Dictionary<string, object> dict = new Dictionary<string, object>();
  23. if (request.TryGetProperty("tmdid", out JsonElement tmdid) && !string.IsNullOrWhiteSpace($"{tmdid}"))
  24. {
  25. dict.Add("tmdid", tmdid);
  26. }
  27. if (request.TryGetProperty("courseId", out JsonElement courseId) && !string.IsNullOrWhiteSpace($"{courseId}"))
  28. {
  29. dict.Add("courseId", courseId);
  30. }
  31. if (request.TryGetProperty("courseIds", out JsonElement courseIds))
  32. {
  33. dict.Add("courseId[*]", courseIds);
  34. }
  35. if (request.TryGetProperty("periodId", out JsonElement periodId) && !string.IsNullOrWhiteSpace($"{periodId}"))
  36. {
  37. dict.Add("periodId", periodId);
  38. }
  39. if (request.TryGetProperty("subjectId", out JsonElement subjectId))
  40. {
  41. dict.Add("subjectId", subjectId);
  42. }
  43. if (request.TryGetProperty("groupIds", out JsonElement groupIds))
  44. {
  45. dict.Add("groupIds[*]", groupIds);
  46. }
  47. if (request.TryGetProperty("grade", out JsonElement grade))
  48. {
  49. dict.Add("grade[*]", grade);
  50. }
  51. if (request.TryGetProperty("category", out JsonElement category))
  52. {
  53. dict.Add("category[*]", category);
  54. }
  55. if (request.TryGetProperty("doubleGreen", out JsonElement doubleGreen) && doubleGreen.GetBoolean())
  56. {
  57. dict.Add(">=.tScore", 70);
  58. dict.Add(">=.pScore", 70);
  59. }
  60. if (request.TryGetProperty("quality", out JsonElement quality) && quality.GetBoolean())
  61. {
  62. dict.Add(">=.discuss", 1);
  63. }
  64. if (request.TryGetProperty("excellent", out JsonElement excellent) && excellent.GetBoolean())
  65. {
  66. dict.Add(">=.excellent", 1);
  67. }
  68. if (request.TryGetProperty("name", out JsonElement name) && !string.IsNullOrWhiteSpace($"{name}"))
  69. {
  70. dict.Add("$.name", name);
  71. }
  72. if (request.TryGetProperty("today", out JsonElement today) && today.GetBoolean())
  73. {
  74. DateTime dateTimeA = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D"));
  75. DateTime dateTimeB = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D")).AddDays(1);
  76. double dayOf00_00_00 = (dateTimeA - dateTime1970).TotalMilliseconds;
  77. double day1Of00_00_00 = (dateTimeB - dateTime1970).TotalMilliseconds;
  78. dict.Add(">=.startTime", dayOf00_00_00);
  79. dict.Add("<.startTime", day1Of00_00_00);
  80. }
  81. if (request.TryGetProperty("week", out JsonElement week) && week.GetBoolean())
  82. {
  83. // DateTime dateTimeA = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D"));
  84. DateTime dateTimeB = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D")).AddDays(-7);
  85. double now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  86. double dayB = (dateTimeB - dateTime1970).TotalMilliseconds;
  87. dict.Add("<=.startTime", now);
  88. dict.Add(">=.startTime", dayB);
  89. }
  90. //查询即将到期的且没有被清理的。
  91. if (request.TryGetProperty("expire", out JsonElement expire) && expire.ValueKind.Equals(JsonValueKind.True))
  92. {
  93. dict.Add(">.expire", 0);
  94. dict.Add("!=.status", 404);
  95. }
  96. //查询已经清理的
  97. if (request.TryGetProperty("is404", out JsonElement is404) && is404.ValueKind.Equals(JsonValueKind.True))
  98. {
  99. dict.Add("=.status", 404);
  100. }
  101. //只查有效的
  102. if (request.TryGetProperty("isOk", out JsonElement isOk) && isOk.ValueKind.Equals(JsonValueKind.True))
  103. {
  104. dict.Add("<=.expire", 0);
  105. dict.Add("!=.status", 404);
  106. }
  107. if (request.TryGetProperty("month", out JsonElement month) && month.GetBoolean())
  108. {
  109. //DateTime dateTimeA = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D"));
  110. DateTime dateTimeB = Convert.ToDateTime(DateTimeOffset.UtcNow.ToString("D")).AddDays(-30);
  111. double now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  112. double dayB = (dateTimeB - dateTime1970).TotalMilliseconds;
  113. dict.Add("<=.startTime", now);
  114. dict.Add(">=.startTime", dayB);
  115. }
  116. if (request.TryGetProperty("stime", out JsonElement stime) && !string.IsNullOrWhiteSpace($"{stime}"))
  117. {
  118. dict.Add(">=.startTime", stime);
  119. }
  120. if (request.TryGetProperty("etime", out JsonElement etime) && !string.IsNullOrWhiteSpace($"{etime}"))
  121. {
  122. dict.Add("<=.startTime", etime);
  123. }
  124. if (request.TryGetProperty("conds", out JsonElement conds) && conds.ValueKind.Equals(JsonValueKind.Array))
  125. {
  126. List<LessonSettingCond> settingConds = conds.Deserialize<List<LessonSettingCond>>();
  127. foreach (var item in settingConds)
  128. {
  129. dict.TryAdd($"{item.type}.{item.key}", item.val);
  130. //switch (item.type)
  131. //{
  132. // case ">=":
  133. // dict.TryAdd($">=.{item.key}",item.val);
  134. // break;
  135. // case "<=":
  136. // dict.TryAdd($"<=.{item.key}", item.val);
  137. // break;
  138. //}
  139. }
  140. }
  141. return dict;
  142. }
  143. public static async void DoLessonStudentRecord(DingDing _dingding, SnowflakeId snowflakeId, LessonRecord lessonRecord, string scope, CosmosClient client, string school, string tmdid,
  144. Teacher teacher, NotificationService _notificationService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, IConfiguration _configuration, LessonBase lessonBase)
  145. {
  146. try
  147. {
  148. int year = DateTimeOffset.UtcNow.Year;
  149. var clientSummaryList = lessonBase.report.clientSummaryList.Where(x => x.groupTaskCompleteCount != 0 || x.groupScore != 0 || x.score != 0 || x.tnteractScore != 0 || x.taskCompleteCount != 0);
  150. IEnumerable<LessonStudent> students = new List<LessonStudent>();
  151. if (clientSummaryList.Any())
  152. {
  153. students = lessonBase.student.Where(x => clientSummaryList.Select(x => x.seatID).Contains(x.seatID));
  154. }
  155. var stuids = students.Where(x => x.type == 2);
  156. if (stuids.Any())
  157. {
  158. stuids.ToList().ForEach(x => {
  159. x.school = string.IsNullOrWhiteSpace(x.school) ? school : x.school;
  160. });
  161. }
  162. var groups = stuids.Where(z => !string.IsNullOrWhiteSpace(z.school)).GroupBy(x => x.school).Select(y => new { code = y.Key, list = y.ToList() });
  163. List<StudentScoreRecord> lessonStudentRecords = new List<StudentScoreRecord>();
  164. foreach (var group in groups)
  165. {
  166. 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}";
  167. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryIterator<StudentScoreRecord>(queryText: stusql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"StudentScoreRecord") }))
  168. {
  169. lessonStudentRecords.Add(item);
  170. }
  171. }
  172. var tmdids = students.Where(x => x.type == 1);
  173. if (tmdids.Any())
  174. {
  175. string tmdsql = $"select value(c) from c where c.tmdid in({string.Join(",", tmdids.Select(x => $"'{x}'"))}) and c.year={year}";
  176. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryIterator<StudentScoreRecord>(queryText: tmdsql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"StudentScoreRecord") }))
  177. {
  178. lessonStudentRecords.Add(item);
  179. }
  180. }
  181. List<Task<ItemResponse<StudentScoreRecord>>> records = new List<Task<ItemResponse<StudentScoreRecord>>>();
  182. stuids.ToList().ForEach(x => {
  183. var record = lessonStudentRecords.Find(l => l.stuid.Equals(x.id) && l.code.Equals($"StudentScoreRecord") && l.school.Equals(x.school));
  184. ClientSummaryList clientSummaryList = lessonBase.report.clientSummaryList.Find(c => c.seatID == x.seatID);
  185. if (record != null)
  186. {
  187. if (clientSummaryList != null)
  188. {
  189. var hasrecord= record.lessonRecords.Find(x => x.lessonId.Equals(lessonRecord.id));
  190. if (hasrecord != null)
  191. {
  192. hasrecord.gscore = clientSummaryList.groupScore;
  193. hasrecord.pscore = clientSummaryList.score;
  194. hasrecord.tscore = clientSummaryList.tnteractScore;
  195. hasrecord.tmdid = teacher.id;
  196. hasrecord.school = school;
  197. hasrecord.scope = lessonRecord.scope;
  198. hasrecord.lessonId = lessonRecord.id;
  199. hasrecord.courseId = lessonRecord.courseId;
  200. hasrecord.periodId = lessonRecord.periodId;
  201. hasrecord.subjectId = lessonRecord.subjectId;
  202. hasrecord.time = lessonRecord.startTime;
  203. }
  204. else {
  205. record.lessonRecords.Add(
  206. new StudentLessonRecord
  207. {
  208. gscore = clientSummaryList.groupScore,
  209. pscore = clientSummaryList.score,
  210. tscore = clientSummaryList.tnteractScore,
  211. tmdid = teacher.id,
  212. school = school,
  213. scope = lessonRecord.scope,
  214. lessonId = lessonRecord.id,
  215. courseId = lessonRecord.courseId,
  216. periodId = lessonRecord.periodId,
  217. subjectId = lessonRecord.subjectId,
  218. time = lessonRecord.startTime
  219. }
  220. );
  221. }
  222. }
  223. }
  224. else
  225. {
  226. record = new StudentScoreRecord
  227. {
  228. userType = Constant.ScopeStudent,
  229. id = $"{snowflakeId.NextId()}",
  230. year = year,
  231. stuid = x.id,
  232. school = x.school,
  233. code = $"StudentScoreRecord",
  234. pk = "StudentScoreRecord",
  235. ttl = -1,
  236. lessonRecords = new List<StudentLessonRecord> { new StudentLessonRecord
  237. {
  238. gscore = clientSummaryList.groupScore,
  239. pscore = clientSummaryList.score,
  240. tscore = clientSummaryList.tnteractScore,
  241. tmdid = teacher.id,
  242. school = school,
  243. scope = lessonRecord.scope,
  244. lessonId = lessonRecord.id,
  245. courseId = lessonRecord.courseId,
  246. periodId = lessonRecord.periodId,
  247. subjectId = lessonRecord.subjectId,
  248. time= lessonRecord.startTime
  249. }}
  250. };
  251. }
  252. record.userType = Constant.ScopeStudent;
  253. record.gscore = record.lessonRecords.Select(x => x.gscore).Sum();
  254. record.pscore = record.lessonRecords.Select(x => x.pscore).Sum();
  255. record.tscore = record.lessonRecords.Select(x => x.tscore).Sum();
  256. records.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(record, partitionKey: new PartitionKey(record.code)));
  257. });
  258. tmdids.ToList().ForEach(x => {
  259. var record = lessonStudentRecords.Find(l => l.tmdid.Equals(x.id) && l.code.Equals($"StudentScoreRecord"));
  260. ClientSummaryList clientSummaryList = lessonBase.report.clientSummaryList.Find(c => c.seatID == x.seatID);
  261. if (record != null)
  262. {
  263. if (clientSummaryList != null)
  264. {
  265. var hasrecord = record.lessonRecords.Find(x => x.lessonId.Equals(lessonRecord.id));
  266. if (hasrecord != null)
  267. {
  268. hasrecord.gscore = clientSummaryList.groupScore;
  269. hasrecord.pscore = clientSummaryList.score;
  270. hasrecord.tscore = clientSummaryList.tnteractScore;
  271. hasrecord.tmdid = teacher.id;
  272. hasrecord.school = school;
  273. hasrecord.scope = lessonRecord.scope;
  274. hasrecord.lessonId = lessonRecord.id;
  275. hasrecord.courseId = lessonRecord.courseId;
  276. hasrecord.periodId = lessonRecord.periodId;
  277. hasrecord.subjectId = lessonRecord.subjectId;
  278. hasrecord.time = lessonRecord.startTime;
  279. }
  280. else
  281. {
  282. record.lessonRecords.Add(
  283. new StudentLessonRecord
  284. {
  285. gscore = clientSummaryList.groupScore,
  286. pscore = clientSummaryList.score,
  287. tscore = clientSummaryList.tnteractScore,
  288. tmdid = teacher.id,
  289. school = school,
  290. scope = lessonRecord.scope,
  291. lessonId = lessonRecord.id,
  292. courseId = lessonRecord.courseId,
  293. periodId = lessonRecord.periodId,
  294. subjectId = lessonRecord.subjectId,
  295. time = lessonRecord.startTime
  296. }
  297. );
  298. }
  299. }
  300. }
  301. else
  302. {
  303. record = new StudentScoreRecord
  304. {
  305. userType = Constant.ScopeTmdUser,
  306. id = $"{snowflakeId.NextId()}",
  307. code = $"StudentScoreRecord",
  308. pk = "StudentScoreRecord",
  309. ttl = -1,
  310. year = year,
  311. tmdid = x.id,
  312. lessonRecords = new List<StudentLessonRecord>
  313. {
  314. new StudentLessonRecord
  315. {
  316. gscore = clientSummaryList.groupScore,
  317. pscore = clientSummaryList.score,
  318. tscore = clientSummaryList.tnteractScore,
  319. tmdid = teacher.id,
  320. school = school,
  321. scope = lessonRecord.scope,
  322. lessonId = lessonRecord.id,
  323. courseId = lessonRecord.courseId,
  324. periodId = lessonRecord.periodId,
  325. subjectId = lessonRecord.subjectId,
  326. time=lessonRecord.startTime
  327. }
  328. }
  329. };
  330. }
  331. record.userType = Constant.ScopeStudent;
  332. record.gscore = record.lessonRecords.Select(x => x.gscore).Sum();
  333. record.pscore = record.lessonRecords.Select(x => x.pscore).Sum();
  334. record.tscore = record.lessonRecords.Select(x => x.tscore).Sum();
  335. records.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(record, partitionKey: new PartitionKey(record.code)));
  336. });
  337. if (records.Any())
  338. {
  339. await Task.WhenAll(records);
  340. }
  341. }
  342. catch (Exception ex)
  343. {
  344. await _dingding.SendBotMsg($"学生个人课例统计信息异常,{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  345. }
  346. }
  347. public static async void DoAutoDeleteSchoolLessonRecord(LessonRecord lessonRecord, string scope, CosmosClient client, string school, string tmdid,
  348. Teacher teacher, NotificationService _notificationService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, IConfiguration _configuration)
  349. {
  350. if (lessonRecord.scope.Equals("school"))
  351. {
  352. SchoolSetting setting = null;
  353. Azure.Response schoolSetting = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemStreamAsync(school, new PartitionKey("SchoolSetting"));
  354. School schoolBase = await client.GetContainer(Constant.TEAMModelOS, Constant.School).ReadItemAsync<School>(school, new PartitionKey("Base"));
  355. if (schoolSetting.Status == 200)
  356. {
  357. setting = JsonDocument.Parse(schoolSetting.Content).RootElement.Deserialize<SchoolSetting>();
  358. if (setting.lessonSetting != null)
  359. {
  360. if (setting.lessonSetting.openAutoClean != 0 && setting.lessonSetting.openAutoClean != 1)
  361. {
  362. setting.lessonSetting.openAutoClean = 0;
  363. setting.lessonSetting.expireDays = Constant.school_lesson_expire;
  364. }
  365. }
  366. else
  367. {
  368. setting.lessonSetting = new LessonSetting() { openAutoClean = 0, expireDays = Constant.school_lesson_expire };
  369. }
  370. }
  371. else
  372. {
  373. setting = new SchoolSetting() { lessonSetting = new LessonSetting { openAutoClean = 0, expireDays = Constant.school_lesson_expire } };
  374. }
  375. int school_lesson_expire = 0;
  376. bool save = true;
  377. List<string> msg = new List<string>();
  378. if (setting.lessonSetting.openAutoClean == 1)
  379. {
  380. if (setting.lessonSetting.conds.IsEmpty())
  381. {
  382. save = false;
  383. }
  384. else
  385. {
  386. school_lesson_expire = setting.lessonSetting.expireDays;
  387. foreach (var item in setting.lessonSetting.conds)
  388. {
  389. switch (item.type)
  390. {
  391. case ">=":
  392. switch (item.key)
  393. {
  394. case "attendRate":
  395. if (!(lessonRecord.attendRate >= item.val))
  396. {
  397. save = false;
  398. msg.Add($"{item.key}:{lessonRecord.attendRate}{item.type}{item.val}");
  399. }
  400. break;
  401. case "groupCount":
  402. if (!(lessonRecord.groupCount >= item.val))
  403. {
  404. save = false;
  405. msg.Add($"{item.key}:{lessonRecord.groupCount}{item.type}{item.val}");
  406. }
  407. break;
  408. case "totalPoint":
  409. if (!(lessonRecord.totalPoint >= item.val))
  410. {
  411. save = false;
  412. msg.Add($"{item.key}:{lessonRecord.totalPoint}{item.type}{item.val}");
  413. }
  414. break;
  415. case "collateTaskCount":
  416. if (!(lessonRecord.collateTaskCount >= item.val))
  417. {
  418. save = false;
  419. msg.Add($"{item.key}:{lessonRecord.collateTaskCount}{item.type}{item.val}");
  420. }
  421. break;
  422. case "collateCount":
  423. if (!(lessonRecord.collateCount >= item.val))
  424. {
  425. save = false;
  426. msg.Add($"{item.key}:{lessonRecord.collateCount}{item.type}{item.val}");
  427. }
  428. break;
  429. case "pushCount":
  430. if (!(lessonRecord.pushCount >= item.val))
  431. {
  432. save = false;
  433. msg.Add($"{item.key}:{lessonRecord.pushCount}{item.type}{item.val}");
  434. }
  435. break;
  436. case "totalInteractPoint":
  437. if (!(lessonRecord.totalInteractPoint >= item.val))
  438. {
  439. save = false;
  440. msg.Add($"{item.key}:{lessonRecord.totalInteractPoint}{item.type}{item.val}");
  441. }
  442. break;
  443. case "interactionCount":
  444. if (!(lessonRecord.interactionCount >= item.val))
  445. {
  446. save = false;
  447. msg.Add($"{item.key}:{lessonRecord.interactionCount}{item.type}{item.val}");
  448. }
  449. break;
  450. case "clientInteractionCount":
  451. if (!(lessonRecord.clientInteractionCount >= item.val))
  452. {
  453. save = false;
  454. msg.Add($"{item.key}:{lessonRecord.clientInteractionCount}{item.type}{item.val}");
  455. }
  456. break;
  457. case "examQuizCount":
  458. if (!(lessonRecord.examQuizCount >= item.val))
  459. {
  460. save = false;
  461. msg.Add($"{item.key}:{lessonRecord.examQuizCount}{item.type}{item.val}");
  462. }
  463. break;
  464. case "examPointRate":
  465. if (!(lessonRecord.examPointRate >= item.val))
  466. {
  467. save = false;
  468. msg.Add($"{item.key}:{lessonRecord.examPointRate}{item.type}{item.val}");
  469. }
  470. break;
  471. }
  472. break;
  473. case "<=":
  474. switch (item.key)
  475. {
  476. case "attendRate":
  477. if (!(lessonRecord.attendRate <= item.val))
  478. {
  479. save = false;
  480. msg.Add($"{item.key}:{lessonRecord.attendRate}{item.type}{item.val}");
  481. }
  482. break;
  483. case "groupCount":
  484. if (!(lessonRecord.groupCount <= item.val))
  485. {
  486. save = false;
  487. msg.Add($"{item.key}:{lessonRecord.groupCount}{item.type}{item.val}");
  488. }
  489. break;
  490. case "totalPoint":
  491. if (!(lessonRecord.totalPoint <= item.val))
  492. {
  493. save = false;
  494. msg.Add($"{item.key}:{lessonRecord.totalPoint}{item.type}{item.val}");
  495. }
  496. break;
  497. case "collateTaskCount":
  498. if (!(lessonRecord.collateTaskCount <= item.val))
  499. {
  500. save = false;
  501. msg.Add($"{item.key}:{lessonRecord.collateTaskCount}{item.type}{item.val}");
  502. }
  503. break;
  504. case "collateCount":
  505. if (!(lessonRecord.collateCount <= item.val))
  506. {
  507. save = false;
  508. msg.Add($"{item.key}:{lessonRecord.collateCount}{item.type}{item.val}");
  509. }
  510. break;
  511. case "pushCount":
  512. if (!(lessonRecord.pushCount <= item.val))
  513. {
  514. save = false;
  515. msg.Add($"{item.key}:{lessonRecord.pushCount}{item.type}{item.val}");
  516. }
  517. break;
  518. case "totalInteractPoint":
  519. if (!(lessonRecord.totalInteractPoint <= item.val))
  520. {
  521. save = false;
  522. msg.Add($"{item.key}:{lessonRecord.totalInteractPoint}{item.type}{item.val}");
  523. }
  524. break;
  525. case "interactionCount":
  526. if (!(lessonRecord.interactionCount <= item.val))
  527. {
  528. save = false;
  529. msg.Add($"{item.key}:{lessonRecord.interactionCount}{item.type}{item.val}");
  530. }
  531. break;
  532. case "clientInteractionCount":
  533. if (!(lessonRecord.clientInteractionCount <= item.val))
  534. {
  535. save = false;
  536. msg.Add($"{item.key}:{lessonRecord.clientInteractionCount}{item.type}{item.val}");
  537. }
  538. break;
  539. case "examQuizCount":
  540. if (!(lessonRecord.examQuizCount <= item.val))
  541. {
  542. save = false;
  543. msg.Add($"{item.key}:{lessonRecord.examQuizCount}{item.type}{item.val}");
  544. }
  545. break;
  546. case "examPointRate":
  547. if (!(lessonRecord.examPointRate <= item.val))
  548. {
  549. save = false;
  550. msg.Add($"{item.key}:{lessonRecord.examPointRate}{item.type}{item.val}");
  551. }
  552. break;
  553. }
  554. break;
  555. }
  556. }
  557. }
  558. }
  559. else
  560. {
  561. save = false;
  562. school_lesson_expire = Constant.school_lesson_expire;
  563. }
  564. if (!save && school_lesson_expire > 0)
  565. {
  566. // 1-时间戳,7-时间戳
  567. Dictionary<int, ExpireTag> result = new Dictionary<int, ExpireTag>();
  568. //暂定7天
  569. var now = DateTimeOffset.UtcNow;
  570. //剩余3天的通知
  571. //var day3= now.AddDays(school_lesson_expire - 3).ToUnixTimeMilliseconds();
  572. //result.Add(3, day3);
  573. //剩余1天的通知
  574. var day1 = now.AddDays(school_lesson_expire - (school_lesson_expire - 1)).ToUnixTimeMilliseconds();
  575. result.Add(1, new ExpireTag { expire = day1, tag = "notification" });
  576. //到期通知
  577. //不到五点上传的课例,七天之后直接删除。
  578. int addSecond = 0;
  579. if (now.Hour > 5)
  580. {
  581. // 到凌晨00点还差 (24 - now.Hour) *60 * 60 分钟,再加天数;
  582. addSecond = school_lesson_expire * 86400 + (24 - now.Hour) * 3600 - (now.Hour * 3600);
  583. //再加 00到05小时内的 随机秒数
  584. Random rand = new Random();
  585. int randInt = rand.Next(0, 18000);
  586. addSecond += randInt;
  587. }
  588. else
  589. {
  590. addSecond = school_lesson_expire * 24 * 60 * 60;
  591. }
  592. lessonRecord.expire = now.AddSeconds(addSecond).ToUnixTimeMilliseconds();
  593. result.Add(school_lesson_expire, new ExpireTag { expire = lessonRecord.expire, tag = "delete" });
  594. // result.Add(school_lesson_expire, lessonRecord.expire);
  595. string biz = "expire";
  596. Notification notification = new Notification
  597. {
  598. hubName = "hita",
  599. type = "msg",
  600. from = $"ies5:{Environment.GetEnvironmentVariable("Option:Location")}:private",
  601. to = new List<string> { tmdid },
  602. label = $"{biz}_lessonRecord",
  603. body = new
  604. {
  605. location = $"{Environment.GetEnvironmentVariable("Option:Location")}",
  606. biz = biz,
  607. tmdid = tmdid,
  608. tmdname = teacher.name,
  609. scope = scope,
  610. school = school,
  611. schoolName = schoolBase.name,
  612. sid = lessonRecord.id,
  613. sname = lessonRecord.name,
  614. stime = lessonRecord.startTime,
  615. expire = lessonRecord.expire,
  616. status = 1,
  617. //day = school_lesson_expire,
  618. time = now
  619. }.ToJsonString(),
  620. expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
  621. };
  622. var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
  623. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  624. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  625. var location = $"{Environment.GetEnvironmentVariable("Option:Location")}";
  626. await _notificationService.SendNotification(clientID, clientSecret, location, url, notification); //站内发送消息
  627. var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
  628. List<ChangeRecord> records = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", lessonRecord.id } });
  629. if (records.Count <= 0)
  630. {
  631. foreach (var item in result)
  632. {
  633. string PartitionKey = string.Format("{0}{1}{2}", lessonRecord.code, "-", $"expire-{item.Key}");
  634. //课堂的id ,
  635. //课堂的通知时间类型progress, 默认就会发送一条,到期前一天发送一条,最后已到期发送一条。
  636. var message = new ServiceBusMessage(new
  637. {
  638. id = lessonRecord.id,
  639. progress = item.Key,
  640. code = lessonRecord.code,
  641. scope = lessonRecord.scope,
  642. school = lessonRecord.school,
  643. opt = "delete",
  644. expire = lessonRecord.expire,
  645. tmdid = tmdid,
  646. tmdname = teacher.name,
  647. name = lessonRecord.name,
  648. startTime = lessonRecord.startTime,
  649. tag = item.Value.tag
  650. }.ToJsonString());
  651. message.ApplicationProperties.Add("name", "LessonRecordExpire");
  652. long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), message, DateTimeOffset.FromUnixTimeMilliseconds(item.Value.expire));
  653. ChangeRecord changeRecord = new ChangeRecord
  654. {
  655. RowKey = lessonRecord.id,
  656. PartitionKey = PartitionKey,
  657. sequenceNumber = start,
  658. msgId = message.MessageId
  659. };
  660. await table.Save<ChangeRecord>(changeRecord);
  661. }
  662. }
  663. }
  664. else
  665. {
  666. if (lessonRecord.expire > 0)
  667. {
  668. var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
  669. List<ChangeRecord> records = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", lessonRecord.id } });
  670. foreach (var record in records)
  671. {
  672. try
  673. {
  674. await table.DeleteSingle<ChangeRecord>(record.PartitionKey, record.RowKey);
  675. await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), record.sequenceNumber);
  676. }
  677. catch (Exception)
  678. {
  679. continue;
  680. }
  681. }
  682. }
  683. lessonRecord.save = 1;
  684. lessonRecord.expire = -1;
  685. }
  686. }
  687. }
  688. public record ExpireTag
  689. {
  690. public long expire { get; set; }
  691. public string tag { get; set; }
  692. }
  693. /// <summary>
  694. ///
  695. /// </summary>
  696. /// <param name="client"></param>
  697. /// <param name="_dingDing"></param>
  698. /// <param name="data"></param>
  699. /// <returns></returns>
  700. public static LessonDis DisLessonCount(LessonRecord oldRecord, LessonRecord newRecord, LessonDis lessonDis)
  701. {
  702. //创建课堂的情况
  703. if (oldRecord == null && newRecord != null)
  704. {
  705. lessonDis.record = 1;
  706. }
  707. //删除数据的情况
  708. //不再对LessonCount进行减
  709. else if (oldRecord != null && newRecord == null)
  710. {
  711. /*lessonDis.record = -1;
  712. //P分数量加减
  713. if (oldRecord.pScore >= 70)
  714. {
  715. lessonDis.disPCount = -1;
  716. }
  717. //T分数量加减
  718. if (oldRecord.tScore >= 70)
  719. {
  720. lessonDis.disTCount = -1;
  721. }
  722. if (oldRecord.tScore >= 70 && oldRecord.pScore >= 70)
  723. {
  724. lessonDis.disTCount = -1;
  725. }*/
  726. }
  727. //无效操作
  728. else if (oldRecord == null && newRecord == null)
  729. {
  730. }
  731. //前后操作都有值,则表示更新
  732. else
  733. {
  734. //P分数量加减
  735. if (oldRecord.pScore >= 70)
  736. {
  737. if (newRecord.pScore < 70)
  738. {
  739. lessonDis.disPCount = -1;
  740. }
  741. }
  742. else
  743. {
  744. if (newRecord.pScore >= 70)
  745. {
  746. lessonDis.disPCount = 1;
  747. }
  748. }
  749. //T分数量加减
  750. if (oldRecord.tScore >= 70)
  751. {
  752. if (newRecord.tScore < 70)
  753. {
  754. lessonDis.disTCount = -1;
  755. }
  756. }
  757. else
  758. {
  759. if (newRecord.tScore >= 70)
  760. {
  761. lessonDis.disTCount = 1;
  762. }
  763. }
  764. //双绿灯数量
  765. if (oldRecord.tScore >= 70 && oldRecord.pScore >= 70)
  766. {
  767. if (newRecord.tScore < 70 || newRecord.pScore < 70)
  768. {
  769. lessonDis.disDCount = -1;
  770. }
  771. }
  772. else
  773. {
  774. if (newRecord.tScore >= 70 && newRecord.pScore >= 70)
  775. {
  776. lessonDis.disDCount = 1;
  777. }
  778. }
  779. }
  780. return lessonDis;
  781. }
  782. public static LessonDis DisLessonCount_2(LessonRecord oldRecord, LessonRecord newRecord, LessonDis lessonDis)
  783. {
  784. //创建课堂的情况
  785. if (oldRecord == null && newRecord != null)
  786. {
  787. lessonDis.record = 1;
  788. //P分数量加减
  789. if (newRecord.pScore >= 70)
  790. {
  791. lessonDis.disPCount = 1;
  792. }
  793. //T分数量加减
  794. if (newRecord.tScore >= 70)
  795. {
  796. lessonDis.disTCount = 1;
  797. }
  798. //双绿灯数量
  799. if (newRecord.tScore >= 70 && newRecord.pScore >= 70)
  800. {
  801. lessonDis.disDCount = 1;
  802. }
  803. }
  804. return lessonDis;
  805. }
  806. public static async Task FixLessonCount(CosmosClient client, DingDing _dingDing, LessonRecord record, LessonRecord oldRecord, LessonDis lessonDis)
  807. {
  808. LessonRecord data = null;
  809. try
  810. {
  811. if (record != null && oldRecord == null)
  812. {
  813. data = record;
  814. }
  815. if (record == null && oldRecord != null)
  816. {
  817. data = oldRecord;
  818. }
  819. if (record != null && oldRecord != null)
  820. {
  821. data = record;
  822. }
  823. int day = DateTimeOffset.FromUnixTimeMilliseconds(data.startTime).DayOfYear;
  824. int year = DateTimeOffset.FromUnixTimeMilliseconds(data.startTime).Year;
  825. int days = DateTimeHelper.getDays(year);
  826. //int years = DateTimeOffset.UtcNow.DayOfYear;
  827. string tbname = string.Empty;
  828. string code = string.Empty;
  829. if (data.scope != null && data.scope.Equals("school"))
  830. {
  831. if (string.IsNullOrEmpty(data.periodId))
  832. {
  833. code = $"LessonCount-{data.school}-{year}";
  834. tbname = "School";
  835. }
  836. else
  837. {
  838. code = $"LessonCount-{data.school}-{year}-{data.periodId}";
  839. tbname = "School";
  840. }
  841. }
  842. else
  843. {
  844. code = $"LessonCount-{year}";
  845. tbname = "Teacher";
  846. }
  847. var response = await client.GetContainer(Constant.TEAMModelOS, tbname).ReadItemStreamAsync(data.tmdid.ToString(), new PartitionKey(code));
  848. if (response.Status == 200)
  849. {
  850. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  851. LessonCount count = json.ToObject<LessonCount>();
  852. count.tCount[day - 1] += lessonDis.disTCount;
  853. count.pCount[day - 1] += lessonDis.disPCount;
  854. count.ptCount[day - 1] += lessonDis.disDCount;
  855. count.beginCount[day - 1] += lessonDis.record;
  856. await client.GetContainer("TEAMModelOS", tbname).ReplaceItemAsync(count, count.id, new PartitionKey(code));
  857. }
  858. else
  859. {
  860. LessonCount count = new()
  861. {
  862. id = data.tmdid,
  863. code = code,
  864. ttl = -1
  865. };
  866. double[] da = new double[days];
  867. List<double> list = new(da);
  868. List<double> listT = new(da);
  869. List<double> listP = new(da);
  870. List<double> listPT = new(da);
  871. list[day - 1] += lessonDis.record;
  872. listT[day - 1] += lessonDis.disTCount;
  873. listP[day - 1] += lessonDis.disPCount;
  874. listPT[day - 1] += lessonDis.disDCount;
  875. count.beginCount.AddRange(list);
  876. count.tCount.AddRange(listT);
  877. count.pCount.AddRange(listP);
  878. count.ptCount.AddRange(listPT);
  879. //count.courseIds.Add(data.courseId);
  880. await client.GetContainer("TEAMModelOS", tbname).CreateItemAsync(count, new PartitionKey(code));
  881. }
  882. }
  883. catch (Exception ex)
  884. {
  885. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-LessonCount-FixLessonCount\n{ex.Message}\n{ex.StackTrace}{data.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
  886. }
  887. }
  888. }
  889. }