TriggerHomework.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412
  1. using Azure.Cosmos;
  2. using Azure.Messaging.ServiceBus;
  3. using HTEXLib.COMM.Helpers;
  4. using Microsoft.Azure.Documents;
  5. using Microsoft.Extensions.Configuration;
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Text.Json;
  11. using System.Threading.Tasks;
  12. using TEAMModelOS.SDK;
  13. using TEAMModelOS.SDK.DI;
  14. using TEAMModelOS.SDK.Extension;
  15. using TEAMModelOS.SDK.Models;
  16. using TEAMModelOS.SDK.Models.Cosmos.Common;
  17. using TEAMModelOS.SDK.Models.Service;
  18. using TEAMModelOS.SDK.Models.Service.BI;
  19. using TEAMModelOS.Function;
  20. namespace TEAMModelOS.CosmosDBTriggers
  21. {
  22. public static class TriggerHomework
  23. {
  24. public static async Task Trigger(CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, AzureStorageFactory _azureStorage, DingDing _dingDing,
  25. CosmosClient client, JsonElement input, TriggerData tdata, AzureRedisFactory _azureRedis, IConfiguration _configuration)
  26. {
  27. try
  28. {
  29. if ((tdata.status != null && tdata.status.Value == 404))
  30. {
  31. await client.GetContainer(Constant.TEAMModelOS, "Common").DeleteItemStreamAsync(tdata.id, new PartitionKey(tdata.code));
  32. ActivityList data = input.ToObject<ActivityList>();
  33. //await IESActivityService.DeleteActivity(_coreAPIHttpService, client, _dingDing, data);
  34. var table_cancel = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
  35. List<ChangeRecord> records = await table_cancel.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id } });
  36. foreach (var record in records)
  37. {
  38. try
  39. {
  40. await table_cancel.DeleteSingle<ChangeRecord>(record.PartitionKey, record.RowKey);
  41. await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), record.sequenceNumber);
  42. }
  43. catch (Exception)
  44. {
  45. continue;
  46. }
  47. }
  48. await BIStats.SetTypeAddStats(client, _dingDing, tdata.school, "Homework", -1, careDate: tdata.startTime);//BI统计增/减量
  49. return;
  50. }
  51. var adid = tdata.id;
  52. var adcode = "";
  53. string blobcntr = null;
  54. if (tdata.scope.Equals("school"))
  55. {
  56. adcode = $"Activity-{tdata.school}";
  57. blobcntr = tdata.school;
  58. }
  59. else
  60. {
  61. adcode = $"Activity-{tdata.creatorId}";
  62. blobcntr = tdata.creatorId;
  63. }
  64. //await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}作业活动【{tdata.name}-{tdata.id}-ttl={tdata.ttl}】正在操作", GroupNames.醍摩豆服務運維群組);
  65. Homework work = await client.GetContainer("TEAMModelOS", "Common").ReadItemAsync<Homework>(tdata.id, new Azure.Cosmos.PartitionKey($"{tdata.code}"));
  66. var table = _azureStorage.GetCloudTableClient().GetTableReference("ChangeRecord");
  67. if (work != null)
  68. {
  69. string PartitionKey = string.Format("{0}{1}{2}", work.code, "-", work.progress);
  70. List<ChangeRecord> changeRecords = await table.FindListByDict<ChangeRecord>(new Dictionary<string, object>() { { "RowKey", tdata.id }, { "PartitionKey", PartitionKey } });
  71. switch (work.progress)
  72. {
  73. case "pending":
  74. var messageWork = new ServiceBusMessage(new { tdata.id, progress = "going", tdata.code }.ToJsonString());
  75. messageWork.ApplicationProperties.Add("name", "Homework");
  76. if (changeRecords.Count > 0)
  77. {
  78. try
  79. {
  80. await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber);
  81. }
  82. catch (Exception)
  83. {
  84. }
  85. long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWork, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
  86. changeRecords[0].sequenceNumber = start;
  87. await table.SaveOrUpdate<ChangeRecord>(changeRecords[0]);
  88. }
  89. else
  90. {
  91. long start = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWork, DateTimeOffset.FromUnixTimeMilliseconds(tdata.startTime));
  92. ChangeRecord changeRecord = new()
  93. {
  94. RowKey = tdata.id,
  95. PartitionKey = PartitionKey,
  96. sequenceNumber = start,
  97. msgId = messageWork.MessageId
  98. };
  99. await table.Save<ChangeRecord>(changeRecord);
  100. }
  101. break;
  102. case "going":
  103. try {
  104. await Activity(_coreAPIHttpService, _serviceBus, _dingDing, client, _configuration, work);
  105. var messageWorkEnd = new ServiceBusMessage(new { id = tdata.id, progress = "finish", code = tdata.code }.ToJsonString());
  106. messageWorkEnd.ApplicationProperties.Add("name", "Homework");
  107. if (changeRecords.Count > 0)
  108. {
  109. long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWorkEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
  110. try
  111. {
  112. await _serviceBus.GetServiceBusClient().CancelMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), changeRecords[0].sequenceNumber);
  113. }
  114. catch (Exception)
  115. {
  116. }
  117. changeRecords[0].sequenceNumber = end;
  118. await table.SaveOrUpdate<ChangeRecord>(changeRecords[0]);
  119. }
  120. else
  121. {
  122. long end = await _serviceBus.GetServiceBusClient().SendScheduleMessageAsync(Environment.GetEnvironmentVariable("Azure:ServiceBus:ActiveTask"), messageWorkEnd, DateTimeOffset.FromUnixTimeMilliseconds(tdata.endTime));
  123. ChangeRecord changeRecord = new()
  124. {
  125. RowKey = tdata.id,
  126. PartitionKey = PartitionKey,
  127. sequenceNumber = end,
  128. msgId = messageWorkEnd.MessageId
  129. };
  130. await table.Save<ChangeRecord>(changeRecord);
  131. }
  132. if (work!=null && work.scope.Equals("private"))
  133. {
  134. await SystemService.RecordAccumulateData(_azureRedis, _dingDing, new SDK.Models.Dtos.Accumulate { client="web", count=1, id=work.id, key="homework-going", name=work.name, scope="teacher", target=work.creatorId });
  135. }
  136. } catch (Exception e) {
  137. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}研修作业活动going{e.Message}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  138. }
  139. finally {
  140. string pkey = string.Format("{0}{1}{2}", work.code, "-", "pending");
  141. await table.DeleteSingle<ChangeRecord>(pkey, tdata.id);
  142. }
  143. //if (bustasks.IsNotEmpty())
  144. //{
  145. // await Task.WhenAll(bustasks);
  146. //}
  147. break;
  148. case "finish":
  149. try {
  150. await Activity(_coreAPIHttpService, _serviceBus, _dingDing, client, _configuration, work);
  151. List<(string pId, List<string> gid)> gls = new List<(string pId, List<string> gid)>();
  152. if (work.groupLists.Count > 0)
  153. {
  154. var group = work.groupLists;
  155. foreach (var gp in group)
  156. {
  157. foreach (KeyValuePair<string, List<string>> pp in gp)
  158. {
  159. gls.Add((pp.Key, pp.Value));
  160. }
  161. }
  162. }
  163. //处理家庭作业活动结束统计账户信息
  164. if (work.staffIds.Count == 0)
  165. {
  166. List<FMember> idsList = await GroupListService.GetFinishMemberInfo(_coreAPIHttpService, client, _dingDing, work.school, work.classes, work.stuLists, work.tchLists, gls);
  167. work.staffIds = idsList;
  168. await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<Homework>(work, work.id, new Azure.Cosmos.PartitionKey(work.code));
  169. }
  170. } catch (Exception e) {
  171. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}研修作业活动finish{e.Message}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  172. } finally {
  173. string pk = string.Format("{0}{1}{2}", work.code, "-", "going");
  174. await table.DeleteSingle<ChangeRecord>(pk, tdata.id);
  175. }
  176. break;
  177. }
  178. }
  179. }
  180. catch (CosmosException e)
  181. {
  182. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-CosmosDB异常{e.Message}\n{e.StackTrace}\n{e.Status}", GroupNames.醍摩豆服務運維群組);
  183. }
  184. catch (Exception ex)
  185. {
  186. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}研修作业活动异常{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  187. }
  188. }
  189. private static async Task Activity(CoreAPIHttpService _coreAPIHttpService, AzureServiceBusFactory _serviceBus, DingDing _dingDing, CosmosClient client, IConfiguration _configuration, Homework work)
  190. {
  191. List<(string pId, List<string> gid)> ps = new List<(string pId, List<string> gid)>();
  192. if (work.groupLists.Count > 0)
  193. {
  194. var group = work.groupLists;
  195. foreach (var gp in group)
  196. {
  197. foreach (KeyValuePair<string, List<string>> pp in gp)
  198. {
  199. ps.Add((pp.Key, pp.Value));
  200. }
  201. }
  202. }
  203. List<string> classes = ExamService.getClasses(work.classes, work.stuLists);
  204. (List<RMember> tmdids, List<RGroupList> classLists) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, classes, work.school, ps);
  205. var addStudentsCls = tmdids.FindAll(x => x.type == 2);
  206. var addTmdidsCls = tmdids.FindAll(x => x.type == 1);
  207. //List<StuActivity> stuActivities = new();
  208. //List<StuActivity> tmdActivities = new();
  209. //List<StuActivity> tchActivities = new();
  210. //List<StuActivity> tac = new();
  211. List<string> tIds = addStudentsCls.Select(x => x.id).ToList();
  212. /*
  213. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<StuActivity>(queryText: $"select value(c) from c where c.id ='{work.id}' and c.type = 'Homework'"))
  214. {
  215. tac.Add(item);
  216. }
  217. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<StuActivity>(queryText: $"select value(c) from c where c.id ='{work.id}' and c.type = 'Homework'"))
  218. {
  219. tac.Add(item);
  220. }
  221. List<string> sub = new();
  222. if (work.tchLists.Count == 0)
  223. {
  224. if (work.targets.Count > 0)
  225. {
  226. foreach (var course in work.targets)
  227. {
  228. var info = course.ToObject<List<string>>();
  229. if (info.Count > 1)
  230. {
  231. sub.Add(info[0]);
  232. }
  233. }
  234. }
  235. }
  236. if (addTmdidsCls.IsNotEmpty())
  237. {
  238. addTmdidsCls.ForEach(x =>
  239. {
  240. HashSet<string> classIds = new HashSet<string>();
  241. classLists.ForEach(z =>
  242. {
  243. z.members.ForEach(y =>
  244. {
  245. if (y.id.Equals(x.id) && y.type == 1)
  246. {
  247. classIds.Add(z.id);
  248. }
  249. });
  250. });
  251. int sta = -1;
  252. if (tac.Count > 0)
  253. {
  254. StuActivity activity = tac.Where(t => t.code.Equals($"Activity-{x.id}")).FirstOrDefault();
  255. if (activity != null)
  256. {
  257. sta = activity.taskStatus;
  258. }
  259. }
  260. tmdActivities.Add(new StuActivity
  261. {
  262. pk = "Activity",
  263. id = work.id,
  264. code = $"Activity-{x.id}",
  265. type = "Homework",
  266. name = work.name,
  267. startTime = work.startTime,
  268. endTime = work.endTime,
  269. scode = work.code,
  270. scope = work.scope,
  271. school = work.school,
  272. creatorId = work.creatorId,
  273. subjects = sub,
  274. blob = work.blob,
  275. owner = work.owner,
  276. createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  277. taskStatus = sta,
  278. mustSubmit = work.mustSubmit,
  279. classIds = classIds.ToList()
  280. });
  281. });
  282. }
  283. if (addStudentsCls.IsNotEmpty())
  284. {
  285. addStudentsCls.ForEach(x =>
  286. {
  287. HashSet<string> classIds = new HashSet<string>();
  288. classLists.ForEach(z =>
  289. {
  290. z.members.ForEach(y =>
  291. {
  292. if (y.id.Equals(x.id) && y.type == 2)
  293. {
  294. classIds.Add(z.id);
  295. }
  296. });
  297. });
  298. int sta = -1;
  299. if (tac.Count > 0)
  300. {
  301. StuActivity activity = tac.Where(t => t.code.Equals($"Activity-{x.code.Replace("Base-", "")}-{x.id}")).FirstOrDefault();
  302. if (activity != null)
  303. {
  304. sta = activity.taskStatus;
  305. }
  306. }
  307. stuActivities.Add(new StuActivity
  308. {
  309. pk = "Activity",
  310. id = work.id,
  311. code = $"Activity-{x.code.Replace("Base-", "")}-{x.id}",
  312. type = "Homework",
  313. name = work.name,
  314. startTime = work.startTime,
  315. endTime = work.endTime,
  316. scode = work.code,
  317. scope = work.scope,
  318. school = work.school,
  319. creatorId = work.creatorId,
  320. subjects = sub,
  321. blob = work.blob,
  322. owner = work.owner,
  323. createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  324. taskStatus = sta,
  325. classIds = classIds.ToList(),
  326. mustSubmit = work.mustSubmit
  327. });
  328. });
  329. }
  330. */
  331. (List<RMember> tchList, List<RGroupList> classInfos) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, work.tchLists, work.school, ps);
  332. (string standard, List<string> tmdids, string school, List<string> update, int statistics) list = (null, null, null, new List<string> { StatisticsService.OfflineRecord }, 0);
  333. if (tchList.IsNotEmpty())
  334. {
  335. list.tmdids = tchList.Select(x => x.id).ToList();
  336. School school = null;
  337. if (!string.IsNullOrEmpty(work.school))
  338. {
  339. school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(work.school, new Azure.Cosmos.PartitionKey("Base"));
  340. list.school = school.id;
  341. list.standard = school.standard;
  342. }
  343. /*
  344. tchList.ForEach(x =>
  345. {
  346. HashSet<string> classIds = new();
  347. classInfos.ForEach(z =>
  348. {
  349. z.members.ForEach(y =>
  350. {
  351. if (y.id.Equals(x.id) && y.type == 1)
  352. {
  353. classIds.Add(z.id);
  354. }
  355. });
  356. });
  357. int sta = -1;
  358. if (tac.Count > 0)
  359. {
  360. StuActivity activity = tac.Where(t => t.code.Equals($"Activity-{x.id}")).FirstOrDefault();
  361. if (activity != null)
  362. {
  363. sta = activity.taskStatus;
  364. }
  365. }
  366. tchActivities.Add(new StuActivity
  367. {
  368. pk = "Activity",
  369. id = work.id,
  370. code = $"Activity-{x.id}",
  371. type = "Homework",
  372. name = work.name,
  373. startTime = work.startTime,
  374. endTime = work.endTime,
  375. scode = work.code,
  376. scope = work.scope,
  377. school = work.school,
  378. creatorId = work.creatorId,
  379. subjects = new List<string> { "" },
  380. blob = work.blob,
  381. owner = work.owner,
  382. createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  383. taskStatus = sta,
  384. classIds = classIds.ToList()
  385. });
  386. });
  387. */
  388. }
  389. //await IESActivityService.SaveStuActivity(client, _dingDing, stuActivities, tmdActivities, tchActivities);
  390. await StatisticsService.SendServiceBus(list, _configuration, _serviceBus, client);
  391. }
  392. }
  393. }