StudyController.cs 34 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. using Azure.Cosmos;
  2. using Microsoft.AspNetCore.Authorization;
  3. using Microsoft.AspNetCore.Http;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.Extensions.Configuration;
  6. using Microsoft.Extensions.Options;
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Net;
  11. using System.Text.Json;
  12. using System.Threading.Tasks;
  13. using TEAMModelOS.Filter;
  14. using TEAMModelOS.Models;
  15. using TEAMModelOS.SDK;
  16. using TEAMModelOS.SDK.DI;
  17. using TEAMModelOS.SDK.Extension;
  18. using TEAMModelOS.SDK.Models;
  19. using TEAMModelOS.SDK.Models.Service;
  20. namespace TEAMModelOS.Controllers.Common
  21. {
  22. [ProducesResponseType(StatusCodes.Status200OK)]
  23. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  24. [Route("common/study")]
  25. [ApiController]
  26. public class StudyController : ControllerBase
  27. {
  28. private readonly AzureCosmosFactory _azureCosmos;
  29. private readonly SnowflakeId _snowflakeId;
  30. private readonly AzureServiceBusFactory _serviceBus;
  31. private readonly DingDing _dingDing;
  32. private readonly Option _option;
  33. private readonly AzureStorageFactory _azureStorage;
  34. private readonly AzureRedisFactory _azureRedis;
  35. public IConfiguration _configuration { get; set; }
  36. private readonly CoreAPIHttpService _coreAPIHttpService;
  37. public StudyController(CoreAPIHttpService coreAPIHttpService,AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId, DingDing dingDing,
  38. IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, IConfiguration configuration)
  39. {
  40. _coreAPIHttpService = coreAPIHttpService;
  41. _azureCosmos = azureCosmos;
  42. _serviceBus = serviceBus;
  43. _snowflakeId = snowflakeId;
  44. _dingDing = dingDing;
  45. _option = option?.Value;
  46. _azureStorage = azureStorage;
  47. _azureRedis = azureRedis;
  48. _configuration = configuration;
  49. }
  50. /// <summary>
  51. /// 保存研修信息
  52. /// </summary>
  53. /// <param name="request"></param>
  54. /// <returns></returns>
  55. [ProducesDefaultResponseType]
  56. [AuthToken(Roles = "teacher,admin")]
  57. [HttpPost("save")]
  58. [Authorize(Roles = "IES")]
  59. public async Task<IActionResult> Save(JsonElement request)
  60. {
  61. try
  62. {
  63. if (!request.TryGetProperty("study", out JsonElement stu)) return BadRequest();
  64. var client = _azureCosmos.GetCosmosClient();
  65. Study study = stu.ToObject<Study>();
  66. string code = study.school;
  67. study.publish = 0;
  68. study.ttl = -1;
  69. study.progress = "going";
  70. if (!study.owner.Equals("area")) {
  71. study.owner = "school";
  72. study.code = "Study-" + code;
  73. study.scope = "school";
  74. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  75. study.createTime = now;
  76. }
  77. if (string.IsNullOrEmpty(study.id))
  78. {
  79. study.id = Guid.NewGuid().ToString();
  80. await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(study, new PartitionKey($"{study.code}"));
  81. }
  82. else
  83. {
  84. if (request.TryGetProperty("ids", out JsonElement ids))
  85. {
  86. List<string> gIds = study.tchLists;
  87. List<string> tIds = ids.ToObject<List<string>>();
  88. foreach (string gId in gIds)
  89. {
  90. var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(gId, new PartitionKey($"GroupList"));
  91. if (response.Status == 200)
  92. {
  93. var json = await JsonDocument.ParseAsync(response.ContentStream);
  94. GroupList group = json.ToObject<GroupList>();
  95. foreach (string id in tIds)
  96. {
  97. /* bool flag = group.members.Exists(m => m.id.Equals(id));
  98. if (flag)
  99. {
  100. continue;
  101. }*/
  102. //else {
  103. Member member = new();
  104. member.id = id;
  105. member.type = 1;
  106. member.code = study.school;
  107. group.members.Add(member);
  108. //}
  109. }
  110. await GroupListService.UpsertList(group,_azureCosmos,_configuration,_serviceBus);
  111. // await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(group, group.id, new PartitionKey($"{group.code}"));
  112. }
  113. }
  114. }
  115. await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(study, study.id, new PartitionKey($"{study.code}"));
  116. }
  117. return Ok(new { study });
  118. }
  119. catch (Exception ex)
  120. {
  121. await _dingDing.SendBotMsg($"OS,{_option.Location},study/save()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  122. return BadRequest();
  123. }
  124. }
  125. /// <summary>
  126. /// 签到
  127. /// </summary>
  128. /// <param name="request"></param>
  129. /// <returns></returns>
  130. [ProducesDefaultResponseType]
  131. //[Authorize(Roles = "IES")]
  132. //[AuthToken(Roles = "teacher,admin")]
  133. [HttpPost("sign-in")]
  134. public async Task<IActionResult> Sign(JsonElement request)
  135. {
  136. // await _dingDing.SendBotMsg($"OS,{_option.Location},study/sign-in()\n{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
  137. try
  138. {
  139. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  140. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  141. request.TryGetProperty("tId", out JsonElement tId);
  142. request.TryGetProperty("mobile", out JsonElement mobile);
  143. string tmdid = "";
  144. if (!string.IsNullOrWhiteSpace($"{mobile}"))
  145. {
  146. var coreUser = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", $"{mobile}" } }, _option.Location, _configuration);
  147. if (coreUser != null)
  148. {
  149. tmdid = coreUser.id;
  150. }
  151. }
  152. else {
  153. if (!string.IsNullOrWhiteSpace($"{tId}") && string.IsNullOrWhiteSpace(tmdid) ) {
  154. tmdid = $"{tId}";
  155. }
  156. }
  157. if (string.IsNullOrWhiteSpace(tmdid)) {
  158. return Ok(new { code = HttpStatusCode.NotFound ,msg="账号不存在!"});
  159. }
  160. var client = _azureCosmos.GetCosmosClient();
  161. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  162. var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(id.ToString(), new PartitionKey($"StudyRecord-{tmdid}"));
  163. var sresponse = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(id.ToString(), new PartitionKey($"Study-{code}"));
  164. if (sresponse.Status == (int)HttpStatusCode.OK)
  165. {
  166. var sJson = await JsonDocument.ParseAsync(sresponse.ContentStream);
  167. Study study = sJson.ToObject<Study>();
  168. if (response.Status == (int)HttpStatusCode.OK)
  169. {
  170. return Ok(new { code = 200, msg = "已经签到" });
  171. /*var json = await JsonDocument.ParseAsync(response.ContentStream);
  172. StudyRecord record = json.ToObject<StudyRecord>();
  173. record.sign = study.startTime < now ? "2" : "1";
  174. record.signTime = now;
  175. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(record, record.id, new PartitionKey($"{record.code}"));*/
  176. }
  177. else
  178. {
  179. StudyRecord setting = new();
  180. setting.id = id.GetString();
  181. setting.tId = tmdid;
  182. setting.signTime = now;
  183. setting.code = "StudyRecord-" + tmdid;
  184. setting.sign = study.startTime < now ? "2" : "1";
  185. await client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(setting, new PartitionKey($"{setting.code}"));
  186. }
  187. }
  188. else
  189. {
  190. return Ok(new { code = HttpStatusCode.NotFound });
  191. }
  192. return Ok();
  193. }
  194. catch (Exception ex)
  195. {
  196. await _dingDing.SendBotMsg($"OS,{_option.Location},study/sign-in()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  197. return BadRequest();
  198. }
  199. }
  200. /*/// <summary>
  201. /// 上传作业
  202. /// </summary>
  203. /// <param name="request"></param>
  204. /// <returns></returns>
  205. [ProducesDefaultResponseType]
  206. [AuthToken(Roles = "teacher,admin")]
  207. [HttpPost("upload")]
  208. public async Task<IActionResult> Upload(JsonElement request)
  209. {
  210. try
  211. {
  212. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  213. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  214. if (!request.TryGetProperty("tId", out JsonElement tId)) return BadRequest();
  215. if (!request.TryGetProperty("hw", out JsonElement hw)) return BadRequest();
  216. var client = _azureCosmos.GetCosmosClient();
  217. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  218. var response = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(id.ToString(), new PartitionKey($"Study-{code}"));
  219. if (response.Status == (int)HttpStatusCode.OK)
  220. {
  221. var json = await JsonDocument.ParseAsync(response.ContentStream);
  222. Study study = json.ToObject<Study>();
  223. bool flag = study.teachers.Exists(s => s.id.Equals(tId.GetString()));
  224. if (flag)
  225. {
  226. foreach (Setting setting in study.teachers)
  227. {
  228. if (setting.id.Equals(tId.GetString()))
  229. {
  230. setting.hwTime = now;
  231. setting.hw = hw.GetString();
  232. }
  233. }
  234. }
  235. else {
  236. Setting setting = new Setting();
  237. setting.id = tId.GetString();
  238. setting.hwTime = now;
  239. setting.hw = hw.GetString();
  240. study.teachers.Add(setting);
  241. }
  242. await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(study, study.id, new PartitionKey($"{study.code}"));
  243. }
  244. else
  245. {
  246. return Ok(new { code = HttpStatusCode.NotFound });
  247. }
  248. return Ok(new { code = HttpStatusCode.OK});
  249. }
  250. catch (Exception ex)
  251. {
  252. await _dingDing.SendBotMsg($"OS,{_option.Location},study/upload()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  253. return BadRequest();
  254. }
  255. }*/
  256. [ProducesDefaultResponseType]
  257. [AuthToken(Roles = "teacher,admin")]
  258. [HttpPost("delete")]
  259. [Authorize(Roles = "IES")]
  260. public async Task<IActionResult> Delete(JsonElement request)
  261. {
  262. try
  263. {
  264. object userScope = null;
  265. object _standard = null;
  266. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  267. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  268. string standard = null;
  269. HttpContext?.Items?.TryGetValue("Scope", out userScope);
  270. if (userScope != null && $"{userScope}".Equals(Constant.ScopeTeacher))
  271. {
  272. HttpContext?.Items?.TryGetValue("Standard", out _standard);
  273. standard = _standard != null && string.IsNullOrEmpty($"{userScope}") ? _standard.ToString() : null;
  274. }
  275. var client = _azureCosmos.GetCosmosClient();
  276. var sresponse = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(id.ToString(), new PartitionKey($"Study-{code}"));
  277. if (sresponse.Status == 200)
  278. {
  279. using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
  280. Study study = json.ToObject<Study>();
  281. List<(string pId, List<string> gid)> ps = new List<(string pId, List<string> gid)>();
  282. if (study.groupLists.Count > 0)
  283. {
  284. var group = study.groupLists;
  285. foreach (var gp in group)
  286. {
  287. foreach (KeyValuePair<string, List<string>> pp in gp)
  288. {
  289. ps.Add((pp.Key, pp.Value));
  290. }
  291. }
  292. }
  293. try
  294. {
  295. (List<RMember> members, List<RGroupList> groups) = await GroupListService.GetStutmdidListids(_coreAPIHttpService, client, _dingDing, study.tchLists, study.school, ps);
  296. await StatisticsService.DoChange(new TeacherTrainChange
  297. { standard = standard, tmdids = members.Select(x => x.id)?.ToList(), school = study.school, update = new HashSet<string> { StatisticsService.OfflineRecord }, statistics = 0 }, _azureCosmos);
  298. }
  299. catch (Exception ex ) {
  300. await _dingDing.SendBotMsg($"OS,{_option.Location},study/delete()ex\n{ex.Message},\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  301. }
  302. if (!string.IsNullOrEmpty(study.examId))
  303. {
  304. await client.GetContainer("TEAMModelOS", "Common").DeleteItemStreamAsync(study.examId, new PartitionKey($"ExamLite-{code}"));
  305. }
  306. if (!string.IsNullOrEmpty(study.surveyId))
  307. {
  308. await client.GetContainer("TEAMModelOS", "Common").DeleteItemStreamAsync(study.surveyId, new PartitionKey($"Survey-{code}"));
  309. }
  310. if (!string.IsNullOrEmpty(study.workId))
  311. {
  312. await client.GetContainer("TEAMModelOS", "Common").DeleteItemStreamAsync(study.workId, new PartitionKey($"Homework-{code}"));
  313. }
  314. }
  315. var response = await client.GetContainer("TEAMModelOS", "Common").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Study-{code}"));
  316. return Ok(new { id, code = response.Status });
  317. }
  318. catch (Exception e)
  319. {
  320. await _dingDing.SendBotMsg($"OS,{_option.Location},study/delete()\n{e.Message},\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  321. return BadRequest();
  322. }
  323. }
  324. /// <param name="request"></param>
  325. /// <returns></returns>
  326. [ProducesDefaultResponseType]
  327. [Authorize(Roles = "IES")]
  328. [AuthToken(Roles = "teacher,admin")]
  329. [HttpPost("find")]
  330. public async Task<IActionResult> Find(JsonElement requert)
  331. {
  332. try
  333. {
  334. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  335. var client = _azureCosmos.GetCosmosClient();
  336. var query = $"select c.id,c.img,c.name,c.type,c.startTime,c.endTime,c.presenter,c.topic,c.address,c.owner,c.progress from c ";
  337. string continuationToken = string.Empty;
  338. string token = default;
  339. //是否需要进行分页查询,默认不分页
  340. bool iscontinuation = false;
  341. if (requert.TryGetProperty("token", out JsonElement token_1))
  342. {
  343. token = token_1.GetString();
  344. iscontinuation = true;
  345. };
  346. //默认不指定返回大小
  347. int? topcout = null;
  348. if (requert.TryGetProperty("count", out JsonElement jcount))
  349. {
  350. if (!jcount.ValueKind.Equals(JsonValueKind.Undefined) && !jcount.ValueKind.Equals(JsonValueKind.Null) && jcount.TryGetInt32(out int data))
  351. {
  352. topcout = data;
  353. }
  354. }
  355. List<object> studies = new();
  356. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: query, continuationToken: token, requestOptions: new QueryRequestOptions() { MaxItemCount = topcout, PartitionKey = new PartitionKey($"Study-{code}") }))
  357. {
  358. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  359. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  360. {
  361. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  362. {
  363. studies.Add(obj.ToObject<object>());
  364. }
  365. }
  366. if (iscontinuation)
  367. {
  368. continuationToken = item.GetContinuationToken();
  369. break;
  370. }
  371. }
  372. return Ok(new { studies });
  373. }
  374. catch (Exception e)
  375. {
  376. await _dingDing.SendBotMsg($"OS,{_option.Location},study/find()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
  377. return BadRequest();
  378. }
  379. }
  380. [ProducesDefaultResponseType]
  381. [Authorize(Roles = "IES")]
  382. [AuthToken(Roles = "teacher,admin")]
  383. [HttpPost("find-summary")]
  384. public async Task<IActionResult> FindSummary(JsonElement requert)
  385. {
  386. try
  387. {
  388. if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
  389. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  390. var client = _azureCosmos.GetCosmosClient();
  391. Study study = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<Study>(id.GetString(), new PartitionKey($"Study-{code}"));
  392. if (study != null)
  393. {
  394. (List<RMember> tchList, List<RGroupList> classInfo) = await GroupListService.GetStutmdidListids(_coreAPIHttpService, client, _dingDing, study.tchLists, study.school);
  395. List<StudyRecord> records = new();
  396. foreach (var member in tchList)
  397. {
  398. var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(id.ToString(), new PartitionKey($"StudyRecord-{member.id}"));
  399. if (response.Status == (int)HttpStatusCode.OK)
  400. {
  401. var json = await JsonDocument.ParseAsync(response.ContentStream);
  402. StudyRecord record = json.ToObject<StudyRecord>();
  403. records.Add(record);
  404. }
  405. }
  406. // (List<TmdInfo> tmdInfos, List<ClassListInfo> classInfos) = await TriggerStuActivity.GetTchList(client, _dingDing, ids, $"{school}");
  407. //(List<TmdInfo> tchList, _) = await TriggerStuActivity.GetTchList(client, _dingDing, study.tchLists, study.school);
  408. return Ok(new { study, records, status = 200 });
  409. }
  410. else
  411. {
  412. return Ok(new { study, status = 404 });
  413. }
  414. }
  415. catch (Exception e)
  416. {
  417. await _dingDing.SendBotMsg($"OS,{_option.Location},study/FindSummary()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
  418. return Ok(new { status = 404 });
  419. }
  420. }
  421. /// <param name="request"></param>
  422. /// <returns></returns>
  423. [ProducesDefaultResponseType]
  424. [Authorize(Roles = "IES")]
  425. [AuthToken(Roles = "teacher,admin")]
  426. [HttpPost("find-by-teacher")]
  427. public async Task<IActionResult> FindByTeacher(JsonElement requert)
  428. {
  429. try
  430. {
  431. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  432. if (!requert.TryGetProperty("tId", out JsonElement tId)) return BadRequest();
  433. var client = _azureCosmos.GetCosmosClient();
  434. var query = $"select c.id,c.img,c.name,c.startTime,c.type,c.endTime,c.presenter,c.topic,c.address,c.owner from c join A0 in c.teachers where A0.id = '{tId}'";
  435. List<object> studies = new();
  436. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Study-{code}") }))
  437. {
  438. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  439. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  440. {
  441. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  442. {
  443. studies.Add(obj.ToObject<object>());
  444. }
  445. }
  446. }
  447. return Ok(new { studies });
  448. }
  449. catch (Exception e)
  450. {
  451. await _dingDing.SendBotMsg($"OS,{_option.Location},study/find-by-teacher()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
  452. return BadRequest();
  453. }
  454. }
  455. [ProducesDefaultResponseType]
  456. [Authorize(Roles = "IES")]
  457. [AuthToken(Roles = "teacher,admin")]
  458. [HttpPost("find-summary-by-teacher")]
  459. public async Task<IActionResult> FindSummaryByTeacher(JsonElement requert)
  460. {
  461. try
  462. {
  463. if (!requert.TryGetProperty("id", out JsonElement id)) return BadRequest();
  464. if (!requert.TryGetProperty("code", out JsonElement code)) return BadRequest();
  465. if (!requert.TryGetProperty("tId", out JsonElement tId)) return BadRequest();
  466. var client = _azureCosmos.GetCosmosClient();
  467. List<object> studies = new();
  468. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: $"select value(c) from c join A0 in c.teachers where A0.id = '{tId}' and c.id = '{id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Study-{code}") }))
  469. {
  470. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  471. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  472. {
  473. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  474. {
  475. studies.Add(obj.ToObject<object>());
  476. }
  477. }
  478. }
  479. return Ok(new { studies });
  480. }
  481. catch (Exception e)
  482. {
  483. await _dingDing.SendBotMsg($"OS,{_option.Location},study/find-summary-by-teacher()\n{e.Message}", GroupNames.醍摩豆服務運維群組);
  484. return BadRequest();
  485. }
  486. }
  487. [ProducesDefaultResponseType]
  488. [AuthToken(Roles = "teacher,admin,area")]
  489. [HttpPost("audit")]
  490. [Authorize(Roles = "IES")]
  491. public async Task<IActionResult> Audit(JsonElement request)
  492. {
  493. try
  494. {
  495. (string tmdid, _, _, string school) = HttpContext.GetAuthTokenInfo();
  496. if (!HttpContext.Items.TryGetValue("Standard", out object standard)) return BadRequest();
  497. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  498. //if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  499. //if (!request.TryGetProperty("tId", out JsonElement tId)) return BadRequest();
  500. if (!request.TryGetProperty("type", out JsonElement type)) return BadRequest();
  501. var client = _azureCosmos.GetCosmosClient();
  502. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  503. List<Dictionary<string, List<string>>> acId = id.ToObject<List<Dictionary<string, List<string>>>>();
  504. List<string> value = new List<string>();
  505. List<Task> tasks = new();
  506. List<Task<ItemResponse<StudyRecord>>> tasky = new();
  507. List<(string op, string tId)> opp = new List<(string op, string tId)>();
  508. int statu = type.GetInt32();
  509. (string standard, List<string> tmdid, string school, List<string> update, int statistics) list = ( $"{standard}", null, school, new List<string> { StatisticsService.OfflineRecord } , 0);
  510. HashSet<string> tch= new HashSet<string>();
  511. foreach (var aId in acId)
  512. {
  513. foreach (KeyValuePair<string, List<string>> pair in aId)
  514. {
  515. /* await foreach (var key in TeacTask(pair.Key, pair.Value, client, type.GetInt32(), now, standard, school)) {
  516. opp.Add((key.op,key.tId));
  517. };*/
  518. foreach (var teacId in pair.Value)
  519. {
  520. var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(pair.Key, new PartitionKey($"StudyRecord-{teacId}"));
  521. if (response.Status == 200)
  522. {
  523. var json = await JsonDocument.ParseAsync(response.ContentStream);
  524. StudyRecord study = json.ToObject<StudyRecord>();
  525. if (study.tId.Equals(teacId) && study.status == statu)
  526. {
  527. continue;
  528. }
  529. else
  530. {
  531. study.status = statu;
  532. study.aTime = now;
  533. }
  534. tasky.Add(client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(study, study.id, new PartitionKey($"{study.code}")));
  535. }
  536. else
  537. {
  538. StudyRecord setting = new()
  539. {
  540. id = pair.Key,
  541. tId = teacId,
  542. code = "StudyRecord-" + teacId,
  543. status = statu,
  544. aTime = now
  545. };
  546. tasky.Add(client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(setting, new PartitionKey($"{setting.code}")));
  547. }
  548. tch.Add($"{teacId}");
  549. }
  550. }
  551. }
  552. list.tmdid = new List<string>(tch);
  553. await tasky.TaskPage(10);
  554. await StatisticsService.SendServiceBus(list, _configuration, _serviceBus, client);
  555. return Ok(new { code = HttpStatusCode.OK });
  556. }
  557. catch (Exception ex)
  558. {
  559. await _dingDing.SendBotMsg($"OS,{_option.Location},Study/audit()\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  560. return BadRequest();
  561. }
  562. }
  563. private async IAsyncEnumerable<(string op, string tId)> AuditTask(List<Dictionary<string, List<string>>> ids, CosmosClient client, int type, long now, object standard, string school)
  564. {
  565. List<Task> tasks = new();
  566. List<Task<ItemResponse<StudyRecord>>> tasky = new();
  567. foreach (var id in ids)
  568. {
  569. foreach (KeyValuePair<string, List<string>> pair in id)
  570. {
  571. foreach (var teacId in pair.Value)
  572. {
  573. //var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(pair.Key, new PartitionKey($"StudyRecord-{teacId}"));
  574. List<StudyRecord> studyRecords = new();
  575. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<StudyRecord>(queryText: $"select value(c) from c where c.id = '{pair.Key}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StudyRecord-{teacId}") }))
  576. {
  577. studyRecords.Add(item);
  578. }
  579. if (studyRecords.Count > 0)
  580. {
  581. if (studyRecords[0].tId.Equals(teacId))
  582. {
  583. studyRecords[0].status = type;
  584. studyRecords[0].aTime = now;
  585. }
  586. tasky.Add(client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(studyRecords[0], studyRecords[0].id, new PartitionKey($"{studyRecords[0].code}")));
  587. }
  588. else
  589. {
  590. StudyRecord setting = new()
  591. {
  592. id = pair.Key,
  593. tId = teacId,
  594. code = "StudyRecord-" + teacId,
  595. status = type,
  596. aTime = now
  597. };
  598. tasky.Add(client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(setting, new PartitionKey($"{setting.code}")));
  599. }
  600. //tasks.Add(StatisticsService.SendServiceBus($"{standard}", $"{teacId}", $"{school}", StatisticsService.OfflineRecord, 1, _configuration, _serviceBus));
  601. }
  602. yield return ("", "");
  603. }
  604. }
  605. await Task.WhenAll(tasks);
  606. await Task.WhenAll(tasky);
  607. }
  608. private async IAsyncEnumerable<(string op, string tId)> TeacTask(string id, List<string> ids, CosmosClient client, int type, long now, object standard, string school)
  609. {
  610. List<Task> tasks = new();
  611. foreach (var teacId in ids)
  612. {
  613. /* var response = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(id, new PartitionKey($"StudyRecord-{teacId}"));*/
  614. List<StudyRecord> studyRecords = new();
  615. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<StudyRecord>(queryText: $"select value(c) from c where c.id = '{id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StudyRecord-{teacId}") }))
  616. {
  617. studyRecords.Add(item);
  618. }
  619. string op;
  620. if (studyRecords.Count > 0)
  621. {
  622. if (studyRecords[0].tId.Equals(teacId))
  623. {
  624. studyRecords[0].status = type;
  625. studyRecords[0].aTime = now;
  626. }
  627. op = "update";
  628. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(studyRecords[0], studyRecords[0].id, new PartitionKey($"{studyRecords[0].code}"));
  629. }
  630. else
  631. {
  632. StudyRecord setting = new()
  633. {
  634. id = id,
  635. tId = teacId,
  636. code = "StudyRecord-" + teacId,
  637. status = type,
  638. aTime = now
  639. };
  640. op = "insert";
  641. await client.GetContainer("TEAMModelOS", "Teacher").CreateItemAsync(setting, new PartitionKey($"{setting.code}"));
  642. }
  643. //tasks.Add(StatisticsService.SendServiceBus($"{standard}", $"{teacId}", $"{school}", StatisticsService.OfflineRecord, 1, _configuration, _serviceBus));
  644. yield return (op, teacId);
  645. }
  646. await Task.WhenAll(tasks);
  647. }
  648. }
  649. }