LessonService.cs 48 KB

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