MonitorServicesBus.cs 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Text.Json;
  5. using System.Threading.Tasks;
  6. using Azure.Cosmos;
  7. using Azure.Messaging.ServiceBus;
  8. using Microsoft.Azure.WebJobs;
  9. using Microsoft.Azure.WebJobs.Host;
  10. using Microsoft.Extensions.Logging;
  11. using StackExchange.Redis;
  12. using TEAMModelOS.SDK.DI;
  13. using TEAMModelOS.SDK.Extension;
  14. using TEAMModelOS.SDK;
  15. using TEAMModelOS.SDK.Models;
  16. using TEAMModelOS.SDK.Models.Cosmos;
  17. using TEAMModelOS.SDK.Models.Cosmos.Common;
  18. using TEAMModelOS.Services.Common;
  19. using System.Linq;
  20. using TEAMModelOS.SDK.Models.Service;
  21. using TEAMModelOS.SDK.Models.Cosmos.BI;
  22. using TEAMModelOS.Models;
  23. using Microsoft.Extensions.Options;
  24. using Microsoft.Extensions.Configuration;
  25. using HTEXLib.COMM.Helpers;
  26. namespace TEAMModelFunction
  27. {
  28. public class MonitorServicesBus
  29. {
  30. private readonly AzureCosmosFactory _azureCosmos;
  31. private readonly DingDing _dingDing;
  32. private readonly AzureStorageFactory _azureStorage;
  33. private readonly AzureRedisFactory _azureRedis;
  34. private readonly AzureServiceBusFactory _serviceBus;
  35. private readonly Option _option;
  36. private readonly NotificationService _notificationService;
  37. private readonly IConfiguration _configuration;
  38. public MonitorServicesBus(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, AzureServiceBusFactory serviceBus, IOptionsSnapshot<Option> option, NotificationService notificationService, IConfiguration configuration)
  39. {
  40. _azureCosmos = azureCosmos;
  41. _dingDing = dingDing;
  42. _azureStorage = azureStorage;
  43. _azureRedis = azureRedis;
  44. _serviceBus = serviceBus;
  45. _option = option?.Value;
  46. _notificationService = notificationService;
  47. _configuration = configuration;
  48. }
  49. [FunctionName("Exam")]
  50. public async Task ExamFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "exam", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  51. {
  52. try
  53. {
  54. var json = JsonDocument.Parse(msg);
  55. json.RootElement.TryGetProperty("id", out JsonElement id);
  56. json.RootElement.TryGetProperty("progress", out JsonElement progress);
  57. json.RootElement.TryGetProperty("code", out JsonElement code);
  58. //Dictionary<string, object> keyValuePairs = mySbMsg.ToObject<Dictionary<string, object>>();
  59. var client = _azureCosmos.GetCosmosClient();
  60. ExamInfo exam = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ExamInfo>(id.ToString(), new PartitionKey($"{code}"));
  61. exam.progress = progress.ToString();
  62. await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(exam, id.ToString(), new PartitionKey($"{code}"));
  63. }
  64. catch (CosmosException)
  65. {
  66. }
  67. catch (Exception ex)
  68. {
  69. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,ExamBus()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  70. }
  71. }
  72. [FunctionName("Vote")]
  73. public async Task VoteFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "vote", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  74. {
  75. try
  76. {
  77. var jsonMsg = JsonDocument.Parse(msg);
  78. jsonMsg.RootElement.TryGetProperty("id", out JsonElement id);
  79. jsonMsg.RootElement.TryGetProperty("progress", out JsonElement progress);
  80. jsonMsg.RootElement.TryGetProperty("code", out JsonElement code);
  81. var client = _azureCosmos.GetCosmosClient();
  82. Vote vote = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<Vote>(id.ToString(), new PartitionKey($"{code}"));
  83. vote.progress = progress.ToString();
  84. await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(vote, id.ToString(), new PartitionKey($"{code}"));
  85. }
  86. catch (CosmosException)
  87. {
  88. }
  89. catch (Exception ex)
  90. {
  91. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,VoteBus()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  92. }
  93. }
  94. [FunctionName("Correct")]
  95. public async Task CorrectFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "correct", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  96. {
  97. try
  98. {
  99. var jsonMsg = JsonDocument.Parse(msg);
  100. jsonMsg.RootElement.TryGetProperty("id", out JsonElement id);
  101. jsonMsg.RootElement.TryGetProperty("progress", out JsonElement progress);
  102. jsonMsg.RootElement.TryGetProperty("code", out JsonElement code);
  103. var client = _azureCosmos.GetCosmosClient();
  104. Correct correct = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<Correct>(id.ToString(), new PartitionKey($"{code}"));
  105. correct.progress = progress.ToString();
  106. await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(correct, id.ToString(), new PartitionKey($"{code}"));
  107. }
  108. catch (CosmosException)
  109. {
  110. }
  111. catch (Exception ex)
  112. {
  113. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,Correct()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  114. }
  115. }
  116. [FunctionName("Survey")]
  117. public async Task SurveyFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "survey", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  118. {
  119. try
  120. {
  121. var jsonMsg = JsonDocument.Parse(msg);
  122. jsonMsg.RootElement.TryGetProperty("id", out JsonElement id);
  123. jsonMsg.RootElement.TryGetProperty("progress", out JsonElement progress);
  124. jsonMsg.RootElement.TryGetProperty("code", out JsonElement code);
  125. //Dictionary<string, object> keyValuePairs = mySbMsg.ToObject<Dictionary<string, object>>();
  126. var client = _azureCosmos.GetCosmosClient();
  127. Survey survey = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<Survey>(id.ToString(), new PartitionKey($"{code}"));
  128. survey.progress = progress.ToString();
  129. await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(survey, id.ToString(), new PartitionKey($"{code}"));
  130. }
  131. catch (CosmosException)
  132. {
  133. }
  134. catch (Exception ex)
  135. {
  136. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,SurveyBus()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  137. }
  138. }
  139. [FunctionName("Homework")]
  140. public async Task HomeworkFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "homework", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  141. {
  142. try
  143. {
  144. var jsonMsg = JsonDocument.Parse(msg);
  145. jsonMsg.RootElement.TryGetProperty("id", out JsonElement id);
  146. jsonMsg.RootElement.TryGetProperty("progress", out JsonElement progress);
  147. jsonMsg.RootElement.TryGetProperty("code", out JsonElement code);
  148. var client = _azureCosmos.GetCosmosClient();
  149. Homework homework = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<Homework>(id.ToString(), new PartitionKey($"{code}"));
  150. homework.progress = progress.ToString();
  151. await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(homework, id.ToString(), new PartitionKey($"{code}"));
  152. }
  153. catch (CosmosException)
  154. {
  155. }
  156. catch (Exception ex)
  157. {
  158. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,Homework()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  159. }
  160. }
  161. [FunctionName("Study")]
  162. public async Task StudyFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "study", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  163. {
  164. try
  165. {
  166. var jsonMsg = JsonDocument.Parse(msg);
  167. jsonMsg.RootElement.TryGetProperty("id", out JsonElement id);
  168. jsonMsg.RootElement.TryGetProperty("progress", out JsonElement progress);
  169. jsonMsg.RootElement.TryGetProperty("code", out JsonElement code);
  170. var client = _azureCosmos.GetCosmosClient();
  171. Study study = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<Study>(id.ToString(), new PartitionKey($"{code}"));
  172. study.progress = progress.ToString();
  173. await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(study, id.ToString(), new PartitionKey($"{code}"));
  174. }
  175. catch (CosmosException)
  176. {
  177. }
  178. catch (Exception ex)
  179. {
  180. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,Study()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  181. }
  182. }
  183. [FunctionName("ExamLite")]
  184. public async Task ExamLiteFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "examlite", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  185. {
  186. try
  187. {
  188. var jsonMsg = JsonDocument.Parse(msg);
  189. jsonMsg.RootElement.TryGetProperty("id", out JsonElement id);
  190. jsonMsg.RootElement.TryGetProperty("progress", out JsonElement progress);
  191. jsonMsg.RootElement.TryGetProperty("code", out JsonElement code);
  192. var client = _azureCosmos.GetCosmosClient();
  193. ExamLite lite = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ExamLite>(id.ToString(), new PartitionKey($"{code}"));
  194. lite.progress = progress.ToString();
  195. await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(lite, id.ToString(), new PartitionKey($"{code}"));
  196. }
  197. catch (CosmosException)
  198. {
  199. }
  200. catch (Exception ex)
  201. {
  202. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,ExamLite()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  203. }
  204. }
  205. /// <summary>
  206. /// 根据容器的根目录刷新redis并获取redis的最新使用情况
  207. /// </summary>
  208. /// <param name="msg"></param>
  209. /// <returns></returns>
  210. [FunctionName("BlobRoot")]
  211. public async Task BlobRootFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "blobroot", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  212. {
  213. try
  214. {
  215. var jsonMsg = JsonDocument.Parse(msg);
  216. if (jsonMsg.RootElement.TryGetProperty("name", out JsonElement _name) && _name.ValueKind == JsonValueKind.String
  217. && jsonMsg.RootElement.TryGetProperty("root", out JsonElement root) && root.ValueKind == JsonValueKind.String)
  218. {
  219. //await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,Blob() 容器:触发变更,{jsonMsg.ToJsonString()}",
  220. // GroupNames.成都开发測試群組);
  221. List<Dictionary<string, double?>> list = new List<Dictionary<string, double?>>();
  222. string[] uls = System.Web.HttpUtility.UrlDecode($"{root}", Encoding.UTF8).Split("/");
  223. string u = !string.IsNullOrEmpty(uls[0]) ? uls[0] : uls[1];
  224. string name = $"{_name}";
  225. string lockKey = $"Blob:Lock:{name}:{u}";
  226. bool exist = await _azureRedis.GetRedisClient(8).KeyExistsAsync(lockKey);
  227. if (!exist)
  228. { ///key不存在则正常进行计算
  229. bool condition = false;
  230. TimeSpan timeSpan = new TimeSpan(DateTimeOffset.UtcNow.AddMinutes(5).Ticks);
  231. timeSpan = timeSpan - new TimeSpan(DateTimeOffset.UtcNow.Ticks);
  232. //准备处理Blob刷新时间
  233. long action = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  234. await _azureRedis.GetRedisClient(8).StringSetAsync(lockKey, action, expiry: timeSpan);
  235. await RefreshBlob(name, u);
  236. //将action 与Redis最新的时间进行比较,如果
  237. var rds = await CheckLockKey(lockKey, action);
  238. condition = rds.condition;
  239. exist = rds.exist;
  240. if (condition || !exist)
  241. {
  242. await RefreshBlob(name, u);
  243. }
  244. //使用 CancellationToken
  245. //while (condition || !exist)
  246. //{
  247. //}
  248. }
  249. else
  250. {
  251. ///key存在则,则刷新key对应的值
  252. TimeSpan timeSpan = new TimeSpan(DateTimeOffset.UtcNow.AddMinutes(5).Ticks);
  253. timeSpan = timeSpan - new TimeSpan(DateTimeOffset.UtcNow.Ticks);
  254. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  255. await _azureRedis.GetRedisClient(8).StringSetAsync(lockKey, now, expiry: timeSpan);
  256. }
  257. //await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,Blob() 容器:{name}使用:{u},文件分类:{list.ToJsonString()}",
  258. // GroupNames.成都开发測試群組);
  259. }
  260. }
  261. catch (Exception ex)
  262. {
  263. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,Blob()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  264. }
  265. }
  266. private async Task<(bool condition, bool exist)> CheckLockKey(string lockKey, long nowTime)
  267. {
  268. //Redis的最新时间
  269. long newestTime = 0;
  270. RedisValue value = await _azureRedis.GetRedisClient(8).StringGetAsync(lockKey);
  271. if (value != default && !value.IsNullOrEmpty)
  272. {
  273. JsonElement record = value.ToString().ToObject<JsonElement>();
  274. if (record.TryGetInt64(out newestTime))
  275. {
  276. }
  277. }
  278. //说明key已经不存在
  279. if (newestTime == 0)
  280. {
  281. return (false, true);
  282. }
  283. //说明key存在
  284. else
  285. {
  286. //说明Redis记录了最新的时间戳
  287. if (nowTime != newestTime)
  288. {
  289. return (true, false);
  290. }
  291. //时间相同,没有被再次记录最新的时间戳
  292. else
  293. {
  294. await _azureRedis.GetRedisClient(8).KeyDeleteAsync(lockKey);
  295. return (false, true);
  296. }
  297. }
  298. }
  299. private async Task RefreshBlob(string name, string u)
  300. {
  301. long statr = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  302. var client = _azureStorage.GetBlobContainerClient(name);
  303. var size = await client.GetBlobsSize(u);
  304. await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Blob:Catalog:{name}", u);
  305. await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Blob:Catalog:{name}", u, size.HasValue ? size.Value : 0);
  306. var scores = await _azureRedis.GetRedisClient(8).SortedSetRangeByRankWithScoresAsync($"Blob:Catalog:{name}");
  307. double blobsize = 0;
  308. if (scores != default && scores != null)
  309. {
  310. foreach (var score in scores)
  311. {
  312. blobsize = blobsize + score.Score;
  313. }
  314. }
  315. await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", new RedisValue(name), new RedisValue($"{blobsize}"));
  316. long end = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  317. long dis = (end - statr) / 1000;
  318. long timeout = 10;
  319. if (dis > timeout)
  320. {
  321. await _dingDing.SendBotMsg($"ServiceBus,RefreshBlob:空间计算已经超过{timeout}秒\n容器名:{name}\n文件夹:{u}\n计算时长:{dis}", GroupNames.醍摩豆服務運維群組);
  322. }
  323. }
  324. /// <summary>
  325. /// 完善课程变更,StuListChange, originCode是学校编码 则表示名单是学校自定义名单,如果是tmdid则表示醍摩豆的私有名单,scope=school,private。
  326. /// </summary>
  327. /// <data msg>
  328. /// CourseChange
  329. ///// </data>
  330. /// <param name="msg"></param>
  331. /// <returns></returns>
  332. [FunctionName("TeacherTrainChange")]
  333. public async Task TeacherTrainChangeFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "teacher-train-change", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  334. {
  335. try
  336. {
  337. // await _dingDing.SendBotMsg($"teacher-train-change\n{msg}",GroupNames.成都开发測試群組);
  338. TeacherTrainChange change = msg.ToObject<TeacherTrainChange>();
  339. if (change.update == null || change.update.Count <= 0 || change.tmdids.IsEmpty())
  340. {
  341. return;
  342. }
  343. var client = _azureCosmos.GetCosmosClient();
  344. string insql = $"where c.id in ({string.Join(",", change.tmdids.Select(x => $"'{x}'"))})";
  345. string selsql = $"select value(c) from c {insql} ";
  346. List<TeacherTrain> teacherTrains = new List<TeacherTrain>();
  347. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<TeacherTrain>(queryText: selsql,
  348. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"TeacherTrain-{change.school}") }))
  349. {
  350. teacherTrains.Add(item);
  351. }
  352. if (change.statistics != 1)
  353. {
  354. List<Task<ItemResponse<TeacherTrain>>> task = new List<Task<ItemResponse<TeacherTrain>>>();
  355. teacherTrains.ForEach(x =>
  356. {
  357. x.update.UnionWith(change.update);
  358. task.Add(client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<TeacherTrain>(x, x.id, new PartitionKey($"TeacherTrain-{change.school}")));
  359. });
  360. await task.TaskPage(5);
  361. var unchange = change.tmdids.Except(teacherTrains.Select(x => x.id));
  362. if (unchange != null)
  363. {
  364. task.Clear();
  365. unchange.ToList().ForEach(x =>
  366. {
  367. TeacherTrain teacherTrain = new TeacherTrain
  368. {
  369. pk = "TeacherTrain",
  370. id = x,
  371. code = $"TeacherTrain-{change.school}",
  372. tmdid = x,
  373. school = change.school,
  374. update = new HashSet<string> { StatisticsService.TeacherAbility,
  375. StatisticsService.TeacherClass, StatisticsService.OfflineRecord }
  376. };
  377. teacherTrain.update.UnionWith(change.update);
  378. task.Add(client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<TeacherTrain>(teacherTrain, new PartitionKey($"TeacherTrain-{change.school}")));
  379. });
  380. await task.TaskPage(1);
  381. }
  382. }
  383. else
  384. {
  385. Area area = null;
  386. string sql = $"select value(c) from c where c.standard='{change.standard}'";
  387. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Area>(queryText: sql,
  388. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-Area") }))
  389. {
  390. area = item;
  391. }
  392. AreaSetting setting = null;
  393. if (area != null)
  394. {
  395. try
  396. {
  397. //优先找校级
  398. setting = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<AreaSetting>(change.school, new PartitionKey("AreaSetting"));
  399. }
  400. catch (CosmosException)
  401. {
  402. try
  403. {
  404. setting = await client.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync<AreaSetting>(area.id, new PartitionKey("AreaSetting"));
  405. }
  406. catch (CosmosException)
  407. {
  408. setting = null;
  409. }
  410. }
  411. }
  412. if (setting == null)
  413. {
  414. setting = new AreaSetting
  415. {
  416. allTime = 50,
  417. classTime = 5,
  418. submitTime = 15,
  419. onlineTime = 20,
  420. offlineTime = 10,
  421. lessonMinutes = 45,
  422. };
  423. }
  424. List<Task<TeacherTrain>> task = new List<Task<TeacherTrain>>();
  425. teacherTrains.ForEach(x =>
  426. {
  427. x.update.UnionWith(change.update);
  428. task.Add(StatisticsService.StatisticsTeacher(x, setting, area, client, null));
  429. });
  430. await task.TaskPage(1);
  431. var unchange = change.tmdids.Except(teacherTrains.Select(x => x.id));
  432. if (unchange != null)
  433. {
  434. task.Clear();
  435. unchange.ToList().ForEach(x =>
  436. {
  437. task.Add(StatisticsService.StatisticsTeacher(new TeacherTrain
  438. {
  439. pk = "TeacherTrain",
  440. id = x,
  441. code = $"TeacherTrain-{change.school}",
  442. tmdid = x,
  443. school = change.school,
  444. update = new HashSet<string> { StatisticsService.TeacherAbility,
  445. StatisticsService.TeacherClass, StatisticsService.OfflineRecord }
  446. }, setting, area, client, null));
  447. });
  448. await task.TaskPage(1);
  449. }
  450. }
  451. }
  452. catch (CosmosException ex)
  453. {
  454. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-研修数据变更,重新统计-TeacherTrainChange\n{msg}\n{ex.Message}\n{ex.StackTrace}CosmosException{ex.Status}", GroupNames.成都开发測試群組);
  455. }
  456. catch (Exception ex)
  457. {
  458. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-研修数据变更,重新统计-TeacherTrainChange\n{msg}\n{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  459. }
  460. }
  461. /// <summary>
  462. /// 完善课程变更,StuListChange, originCode是学校编码 则表示名单是学校自定义名单,如果是tmdid则表示醍摩豆的私有名单,scope=school,private。
  463. /// </summary>
  464. /// <data msg>
  465. /// CourseChange
  466. ///// </data>
  467. /// <param name="msg"></param>
  468. /// <returns></returns>
  469. [FunctionName("GroupChange")]
  470. public async Task GroupChangeFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "group-change", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  471. {
  472. var client = _azureCosmos.GetCosmosClient();
  473. try
  474. {
  475. //await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-名单成员变更-GroupChange\n{msg}", GroupNames.成都开发測試群組);
  476. var jsonMsg = JsonDocument.Parse(msg);
  477. GroupChange groupChange = msg.ToObject<GroupChange>();
  478. //名单变动修改学生课程关联信息
  479. //await StuListService.FixStuCourse(client, stuListChange);
  480. //Vote投票 Survey问卷 Exam评测 Learn学习活动 Homework作业活动
  481. //名单变动修改学生问卷关联信息
  482. await ActivityService.FixActivity(client, _dingDing, groupChange, "Survey");
  483. //名单变动修改学生投票关联信息
  484. await ActivityService.FixActivity(client, _dingDing, groupChange, "Vote");
  485. //名单变动修改学生评测关联信息
  486. await ActivityService.FixActivity(client, _dingDing, groupChange, "Exam");
  487. //名单变动修改学生研修关联信息
  488. await ActivityService.FixActivity(client, _dingDing, groupChange, "Study");
  489. //名单变动修改学生简易评测关联信息
  490. await ActivityService.FixActivity(client, _dingDing, groupChange, "ExamLite");
  491. //TODO学习活动
  492. //await FixActivity(client, stuListChange, "Learn");
  493. //名单变动修改学生作业活动信息
  494. await ActivityService.FixActivity(client, _dingDing, groupChange, "Homework");
  495. if (groupChange.type == null || !groupChange.type.Equals("research") || !groupChange.type.Equals("yxtrain") || !groupChange.type.Equals("activity"))
  496. {
  497. //课程名单变动修改学生课程关联信息
  498. await ActivityService.FixStuCourse(client, _dingDing, groupChange);
  499. }
  500. }
  501. catch (Exception ex)
  502. {
  503. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-GroupChange-GroupChange\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.成都开发測試群組);
  504. }
  505. }
  506. [FunctionName("ItemCond")]
  507. public async Task ItemCondFunc([ServiceBusTrigger("%Azure:ServiceBus:ItemCondQueue%", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  508. {
  509. try
  510. {
  511. var client = _azureCosmos.GetCosmosClient();
  512. var jsonMsg = JsonDocument.Parse(msg);
  513. List<ItemCondDto> itemCondDtos = msg.ToObject<List<ItemCondDto>>();
  514. foreach (var itemCondDto in itemCondDtos)
  515. {
  516. if (itemCondDto.scope.Equals("school"))
  517. {
  518. ItemCond itemCond = null;
  519. List<ItemInfo> items = new List<ItemInfo>();
  520. var queryslt = $"SELECT c.gradeIds,c.subjectId,c.periodId,c.type,c.level,c.field ,c.scope FROM c where c.periodId='{itemCondDto.filed}' and c.pid= null ";
  521. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<ItemInfo>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{itemCondDto.key}") }))
  522. {
  523. items.Add(item);
  524. }
  525. itemCond = new ItemCond()
  526. {
  527. id = $"{itemCondDto.filed}",
  528. code = $"ItemCond-{itemCondDto.key}",
  529. pk = "ItemCond",
  530. ttl = -1,
  531. count = items.Count,
  532. grades = new List<GradeCount>(),
  533. subjects = new List<SubjectCount>()
  534. };
  535. items.ForEach(z =>
  536. {
  537. if (!string.IsNullOrEmpty(z.type))
  538. {
  539. ItemService.CountItemCond(z, null, itemCond);
  540. }
  541. });
  542. await _azureRedis.GetRedisClient(8).HashSetAsync($"ItemCond:{itemCondDto.key}", $"{itemCondDto.filed}", itemCond.ToJsonString());
  543. }
  544. else
  545. {
  546. ItemCond itemCond = null;
  547. List<ItemInfo> items = new List<ItemInfo>();
  548. var queryslt = $"SELECT c.gradeIds,c.subjectId,c.periodId,c.type,c.level,c.field ,c.scope FROM c where c.pid= null ";
  549. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<ItemInfo>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{itemCondDto.filed}") }))
  550. {
  551. items.Add(item);
  552. }
  553. itemCond = new ItemCond() { id = $"{itemCondDto.filed}", code = $"ItemCond", pk = "ItemCond", ttl = -1, count = items.Count };
  554. items.ForEach(z =>
  555. {
  556. if (!string.IsNullOrEmpty(z.type))
  557. {
  558. ItemService.CountItemCond(z, null, itemCond);
  559. }
  560. });
  561. await _azureRedis.GetRedisClient(8).HashSetAsync($"ItemCond:ItemCond", $"{itemCondDto.filed}", itemCond.ToJsonString());
  562. }
  563. }
  564. }
  565. catch (CosmosException ex)
  566. {
  567. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,ItemCond()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  568. }
  569. catch (Exception ex)
  570. {
  571. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,ItemCond()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  572. }
  573. }
  574. //更新產品一覽表
  575. [FunctionName("Product")]
  576. public async Task ProductFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "product", Connection = "Azure:ServiceBus:ConnectionString")] string msg, ILogger log)
  577. {
  578. try
  579. {
  580. var jsonMsg = JsonDocument.Parse(msg);
  581. jsonMsg.RootElement.TryGetProperty("method", out JsonElement method);
  582. jsonMsg.RootElement.TryGetProperty("schoolId", out JsonElement schoolId);
  583. jsonMsg.RootElement.TryGetProperty("prodCode", out JsonElement prodCode);
  584. jsonMsg.RootElement.TryGetProperty("prodId", out JsonElement prodId);
  585. var client = _azureCosmos.GetCosmosClient();
  586. string strQuery = string.Empty;
  587. //取得所有學校產品
  588. ////序號
  589. List<SchoolProductSumData> serialsProductSumOrg = new List<SchoolProductSumData>();
  590. strQuery = $"SELECT * FROM c WHERE c.dataType = 'serial'";
  591. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: strQuery, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Product-{schoolId}") }))
  592. {
  593. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  594. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  595. {
  596. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  597. {
  598. SchoolProductSerial serialInfo = obj.ToObject<SchoolProductSerial>();
  599. SchoolProductSumData serialProd = serialsProductSumOrg.Where(sp => sp.prodCode == serialInfo.prodCode).FirstOrDefault();
  600. if (serialProd == null)
  601. {
  602. SchoolProductSumData serialProdAdd = new SchoolProductSumData();
  603. serialProdAdd.prodCode = serialInfo.prodCode;
  604. serialProdAdd.ids.Add(serialInfo.id);
  605. serialProdAdd.avaliable = serialProdAdd.ids.Count;
  606. serialsProductSumOrg.Add(serialProdAdd);
  607. }
  608. else
  609. {
  610. if (!serialProd.ids.Contains(serialInfo.id))
  611. {
  612. serialProd.ids.Add(serialInfo.id);
  613. }
  614. serialProd.avaliable = serialProd.ids.Count;
  615. }
  616. }
  617. }
  618. }
  619. ////服務
  620. List<SchoolProductSumData> servicesProductSumOrg = new List<SchoolProductSumData>();
  621. long timestampToday = DateTimeOffset.UtcNow.AddSeconds(1).ToUnixTimeSeconds(); //比現實時間延遲1秒
  622. strQuery = $"SELECT * FROM c WHERE c.dataType = 'service' AND c.startDate <= {timestampToday} AND {timestampToday} <= c.endDate AND c.ttl < 0"; //在授權期間、ttl < 0 才取
  623. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: strQuery, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Product-{schoolId}") }))
  624. {
  625. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  626. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  627. {
  628. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  629. {
  630. SchoolProductService serviceInfo = obj.ToObject<SchoolProductService>();
  631. SchoolProductSumData serviceProd = servicesProductSumOrg.Where(sp => sp.prodCode == serviceInfo.prodCode).FirstOrDefault();
  632. if (serviceProd == null)
  633. {
  634. SchoolProductSumData serviceProdAdd = new SchoolProductSumData();
  635. serviceProdAdd.prodCode = serviceInfo.prodCode;
  636. serviceProdAdd.avaliable = 0;
  637. serviceProdAdd.ids.Add(serviceInfo.id);
  638. serviceProdAdd.avaliable += serviceInfo.number;
  639. servicesProductSumOrg.Add(serviceProdAdd);
  640. }
  641. else
  642. {
  643. if (!serviceProd.ids.Contains(serviceInfo.id))
  644. {
  645. serviceProd.ids.Add(serviceInfo.id);
  646. serviceProd.avaliable += serviceInfo.number;
  647. }
  648. }
  649. }
  650. }
  651. }
  652. ////服務產品特別對應項
  653. if (servicesProductSumOrg.Count > 0)
  654. {
  655. foreach (SchoolProductSumData servicesProductSumOrgRow in servicesProductSumOrg)
  656. {
  657. //更新學校空間
  658. if (servicesProductSumOrgRow.prodCode.Equals("IPALJ6NY"))
  659. {
  660. School school = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>($"{schoolId}", new PartitionKey("Base"));
  661. school.size = (servicesProductSumOrgRow.avaliable < 1) ? 1 : servicesProductSumOrgRow.avaliable;
  662. await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<School>(school, $"{schoolId}", new PartitionKey("Base"));
  663. }
  664. }
  665. }
  666. ////硬體
  667. List<SchoolProductSumDataHard> hardsProductSumOrg = new List<SchoolProductSumDataHard>();
  668. strQuery = $"SELECT * FROM c WHERE c.dataType = 'hard'";
  669. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: strQuery, requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Product-{schoolId}") }))
  670. {
  671. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  672. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  673. {
  674. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  675. {
  676. SchoolProductHard hardInfo = obj.ToObject<SchoolProductHard>();
  677. SchoolProductSumData hardProd = hardsProductSumOrg.Where(sp => sp.prodCode == hardInfo.prodCode).FirstOrDefault();
  678. if (hardProd == null)
  679. {
  680. SchoolProductSumDataHard hardProdAdd = new SchoolProductSumDataHard();
  681. hardProdAdd.prodCode = hardInfo.prodCode;
  682. hardProdAdd.model = hardInfo.model;
  683. hardProdAdd.ids.Add(hardInfo.id);
  684. hardProdAdd.avaliable = hardProdAdd.ids.Count;
  685. hardsProductSumOrg.Add(hardProdAdd);
  686. }
  687. else
  688. {
  689. if (!hardProd.ids.Contains(hardInfo.id))
  690. {
  691. hardProd.ids.Add(hardInfo.id);
  692. }
  693. hardProd.avaliable = hardProd.ids.Count;
  694. }
  695. }
  696. }
  697. }
  698. //更新學校產品一覽表
  699. SchoolProductSum prodSum = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<SchoolProductSum>(schoolId.ToString(), new PartitionKey($"ProductSum"));
  700. prodSum.serial = serialsProductSumOrg;
  701. prodSum.service = servicesProductSumOrg;
  702. prodSum.hard = hardsProductSumOrg;
  703. await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<SchoolProductSum>(prodSum, prodSum.id, new PartitionKey($"{prodSum.code}"));
  704. }
  705. catch (CosmosException ex)
  706. {
  707. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,Product()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  708. }
  709. catch (Exception ex)
  710. {
  711. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-ServiceBus,Product()\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  712. }
  713. }
  714. /// <summary>
  715. /// 批量复制文件
  716. /// </summary>
  717. /// <param name="msg"></param>
  718. /// <returns></returns>
  719. [FunctionName("CopyStandardFile")]
  720. public async Task BatchCopyBlobFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "copy-standard-file", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  721. {
  722. try
  723. {
  724. //await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-Blob复制文件-CopyStandardFile\n{msg}", GroupNames.成都开发測試群組);
  725. var jsonMsg = JsonDocument.Parse(msg);
  726. BatchCopyFile bIBatchCopyFile = msg.ToObject<BatchCopyFile>();
  727. //批量复制文件
  728. var result = await BatchCopyFileService.CopyFile(_dingDing, _azureStorage, bIBatchCopyFile);
  729. if (result == 200)
  730. {
  731. //发送消息实体
  732. Notification notification = new Notification
  733. {
  734. hubName = "hita",
  735. type = "msg",
  736. from = $"ies5:{_option.Location}:private",
  737. to = bIBatchCopyFile.tmdIds,
  738. label = $"{bIBatchCopyFile.codeKey}_finish",
  739. body = new { location = _option.Location, biz = $"{bIBatchCopyFile.codeKey}", tmdid = $"{bIBatchCopyFile.tmdid}", tmdname = $"{bIBatchCopyFile.tmdName}", status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
  740. expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
  741. };
  742. var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
  743. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  744. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  745. var location = _option.Location;
  746. await _notificationService.SendNotification(clientID, clientSecret, location, url, notification); //站内发送消息
  747. }
  748. }
  749. catch (Exception ex)
  750. {
  751. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-Blob复制文件-CopyStandardFile\n{ex.Message}\n{ex.StackTrace}\n{msg}", GroupNames.醍摩豆服務運維群組);
  752. }
  753. }
  754. /// <summary>
  755. /// 更新开课数据事件
  756. /// </summary>
  757. /// <param name="msg"></param>
  758. /// <returns></returns>
  759. [FunctionName("LessonRecordEvent")]
  760. public async Task LessonRecordFunc([ServiceBusTrigger("%Azure:ServiceBus:ActiveTask%", "lesson-record-event", Connection = "Azure:ServiceBus:ConnectionString")] string msg)
  761. {
  762. JsonElement data = msg.ToObject<JsonElement>();
  763. string scope = "";
  764. string tmdid = "";
  765. string lessonId;
  766. string school;
  767. string tbname;
  768. string code;
  769. string blobname;
  770. List<LessonUpdate> updates = new List<LessonUpdate>();
  771. //更新课堂记录
  772. if (data.TryGetProperty("lesson_id", out JsonElement _lessonId) && !string.IsNullOrEmpty($"{_lessonId}"))
  773. {
  774. if (!data.TryGetProperty("tmdid", out JsonElement _tmdid)) return;
  775. if (!data.TryGetProperty("scope", out JsonElement _scope)) return;
  776. if (!data.TryGetProperty("grant_types", out JsonElement _grant_types)) return;
  777. data.TryGetProperty("school", out JsonElement _school);
  778. school = $"{_school}";
  779. scope = $"{_scope}";
  780. tmdid = $"{_tmdid}";
  781. lessonId = $"{_lessonId}";
  782. updates = _grant_types.ToObject<List<LessonUpdate>>();
  783. }//创建课堂记录
  784. else if (data.TryGetProperty("id", out JsonElement _id) && !string.IsNullOrEmpty($"{_id}")
  785. && data.TryGetProperty("tmdid", out JsonElement _tmdid) && !string.IsNullOrEmpty($"{_tmdid}")
  786. && data.TryGetProperty("scope", out JsonElement _scope) && !string.IsNullOrEmpty($"{_scope}"))
  787. {
  788. data.TryGetProperty("school", out JsonElement _school);
  789. school = $"{_school}";
  790. scope = $"{_scope}";
  791. tmdid = $"{_tmdid}";
  792. lessonId = $"{_id}";
  793. updates.Add(new LessonUpdate { grant_type = "create" });
  794. }//删除课堂记录
  795. else if (data.TryGetProperty("delete_id", out JsonElement _delete_id) && !string.IsNullOrEmpty($"{_delete_id}")
  796. && data.TryGetProperty("tmdid", out JsonElement _dtmdid) && !string.IsNullOrEmpty($"{_dtmdid}")
  797. && data.TryGetProperty("scope", out JsonElement _dscope) && !string.IsNullOrEmpty($"{_dscope}")
  798. && data.TryGetProperty("opt", out JsonElement _opt) && !string.IsNullOrEmpty($"{_opt}"))
  799. {
  800. data.TryGetProperty("school", out JsonElement _dschool);
  801. school = $"{_dschool}";
  802. if ($"{_opt}".Equals("delete"))
  803. {
  804. scope = $"{_dscope}";
  805. tmdid = $"{_dtmdid}";
  806. lessonId = $"{_delete_id}";
  807. updates.Add(new LessonUpdate { grant_type = "delete" });
  808. }
  809. else { return; }
  810. }
  811. else
  812. {
  813. return;
  814. }
  815. var client = _azureCosmos.GetCosmosClient();
  816. if ($"{scope}".Equals("school") && !string.IsNullOrEmpty($"{school}"))
  817. {
  818. blobname = $"{school}";
  819. code = $"LessonRecord-{school}";
  820. tbname = "School";
  821. }
  822. else if ($"{scope}".Equals("private"))
  823. {
  824. blobname = $"{tmdid}";
  825. code = $"LessonRecord-{tmdid}";
  826. tbname = "Teacher";
  827. }
  828. else
  829. {
  830. return;
  831. }
  832. LessonDis lessonDis = new LessonDis();
  833. List<LessonUpdate> msgs = new List<LessonUpdate>();
  834. try
  835. {
  836. LessonRecord oldlessonRecord = null;
  837. LessonRecord lessonRecord = null;
  838. Azure.Response response = await client.GetContainer(Constant.TEAMModelOS, tbname).ReadItemStreamAsync(lessonId, new PartitionKey(code));
  839. if (response.Status == 200)
  840. {
  841. var doc = JsonDocument.Parse(response.ContentStream);
  842. lessonRecord = doc.RootElement.ToObject<LessonRecord>();
  843. oldlessonRecord = doc.RootElement.ToObject<LessonRecord>();
  844. }
  845. else
  846. {
  847. lessonRecord = null;
  848. }
  849. if (updates.IsNotEmpty())
  850. {
  851. foreach (LessonUpdate update in updates)
  852. {
  853. switch (update.grant_type)
  854. {
  855. //更新课堂时长
  856. case "up-duration":
  857. var duration = double.Parse($"{update.data}");
  858. lessonRecord.duration = duration;
  859. msgs.Add(update);
  860. break;
  861. //更新T分
  862. case "up-tScore":
  863. var tScore = int.Parse($"{update.data}");
  864. lessonRecord.tScore = tScore;
  865. msgs.Add(update);
  866. break;
  867. //更新课P分
  868. case "up-pScore":
  869. var pScore = int.Parse($"{update.data}");
  870. lessonRecord.pScore = pScore;
  871. msgs.Add(update);
  872. break;
  873. //更新 学生人数
  874. case "up-mCount":
  875. var mCount = int.Parse($"{update.data}");
  876. lessonRecord.mCount = mCount;
  877. msgs.Add(update);
  878. break;
  879. //更新 议课次数
  880. case "up-techCount":
  881. var techCount = int.Parse($"{update.data}");
  882. lessonRecord.mCount = techCount;
  883. msgs.Add(update);
  884. break;
  885. //更新 时间线
  886. case "up-TimeLine":
  887. //BlobDownloadResult TimeLineblobDownload = await _azureStorage.GetBlobContainerClient(blobname).GetBlobClient($"/{_lessonId}/IES/TimeLine.json").DownloadContentAsync();
  888. //var timeline = TimeLineblobDownload.Content.ToObjectFromJson<List<LessonTimeLine>>();
  889. msgs.Add(update);
  890. break;
  891. //更新 课堂总览信息
  892. case "up-ActivityInfo":
  893. //BlobDownloadResult ActivityInfoblobDownload = await _azureStorage.GetBlobContainerClient(blobname).GetBlobClient($"/{_lessonId}/IES/ActivityInfo.json").DownloadContentAsync();
  894. //var activityInfos = ActivityInfoblobDownload.Content.ToObjectFromJson<List<LessonActivityInfo>>();
  895. msgs.Add(update);
  896. break;
  897. case "delete":
  898. try
  899. {
  900. await client.GetContainer(Constant.TEAMModelOS, tbname).DeleteItemAsync<LessonRecord>(lessonId, new PartitionKey(code));
  901. msgs.Add(update);
  902. }
  903. catch (CosmosException ex)
  904. {
  905. msgs.Add(update);
  906. }
  907. lessonRecord = null;
  908. break;
  909. case "create":
  910. oldlessonRecord = null;
  911. //处理课堂选用的课程信息
  912. if (!string.IsNullOrEmpty(lessonRecord.courseId))
  913. {
  914. Course course = null;
  915. try
  916. {
  917. course = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<Course>(lessonRecord.courseId, new PartitionKey($"Course-{lessonRecord.school}"));
  918. }
  919. catch (CosmosException ex) when (ex.Status != 404)
  920. {
  921. try
  922. {
  923. course = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Course>(lessonRecord.courseId, new PartitionKey($"Course-{lessonRecord.tmdid}"));
  924. }
  925. catch (CosmosException e) when (e.Status != 404)
  926. {
  927. course = null;
  928. }
  929. }
  930. if (course != null)
  931. {
  932. lessonRecord.periodId = course.period?.id;
  933. lessonRecord.subjectId = course.subject?.id;
  934. }
  935. }
  936. //处理课堂选用的名单
  937. if (lessonRecord.groupIds.IsNotEmpty())
  938. {
  939. HashSet<string> grades = new HashSet<string>();
  940. List<GroupListDto> groups = await GroupListService.GetGroupListListids(client, _dingDing, lessonRecord.groupIds, lessonRecord.school);
  941. List<GroupListDto> groupLists = groups.FindAll(x => !string.IsNullOrEmpty(x.periodId) && x.year > 0 && !string.IsNullOrEmpty(x.school));
  942. if (groupLists.IsNotEmpty() && !string.IsNullOrEmpty(lessonRecord.periodId))
  943. {
  944. School schoolObj = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(lessonRecord.school, new PartitionKey("Base"));
  945. //年级算法
  946. int? Count = schoolObj.period.Find(x => x.id.Equals(lessonRecord.periodId)).grades?.Count;
  947. if (Count.HasValue)
  948. {
  949. int Month = DateTimeOffset.UtcNow.Month;
  950. int Year = DateTimeOffset.UtcNow.Year;
  951. foreach (int year in groupLists.Select(x => x.year))
  952. {
  953. int grade;
  954. if (Month >= 1 && Month <= 6)
  955. {
  956. grade = (Year - year + 1) / Count.Value;
  957. }
  958. else
  959. {
  960. grade = (Year - year) / Count.Value;
  961. }
  962. grades.Add($"{grade}");
  963. }
  964. }
  965. }
  966. lessonRecord.grade.AddRange(grades);
  967. }
  968. msgs.Add(update);
  969. break;
  970. default:
  971. break;
  972. }
  973. }
  974. //
  975. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, tbname).ReplaceItemAsync<LessonRecord>(lessonRecord, lessonId, new PartitionKey(code));
  976. //计算课堂更新前后的差值
  977. lessonDis = LessonService.DisLessonCount(oldlessonRecord, lessonRecord, lessonDis);
  978. await LessonService.FixLessonCount(client, _dingDing, lessonRecord, oldlessonRecord, lessonDis);
  979. }
  980. }
  981. catch (Exception ex)
  982. {
  983. await _dingDing.SendBotMsg($"{Environment.GetEnvironmentVariable("Option:Location")}-更新课堂记录出错\n{ex.Message}\n{ex.StackTrace}\n{data}\n{code}\n", GroupNames.成都开发測試群組);
  984. }
  985. }
  986. }
  987. }