LessonService.cs 47 KB

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