ArtController.cs 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071
  1. using Azure.Core;
  2. using Azure.Cosmos;
  3. using DinkToPdf.Contracts;
  4. using DocumentFormat.OpenXml.Bibliography;
  5. using DocumentFormat.OpenXml.Office2010.Excel;
  6. using DocumentFormat.OpenXml.Office2013.Excel;
  7. using DocumentFormat.OpenXml.Office2016.Excel;
  8. using DocumentFormat.OpenXml.Spreadsheet;
  9. using DocumentFormat.OpenXml.Wordprocessing;
  10. using MathNet.Numerics.RootFinding;
  11. using Microsoft.AspNetCore.Authorization;
  12. using Microsoft.AspNetCore.Http;
  13. using Microsoft.AspNetCore.Mvc;
  14. using Microsoft.Extensions.Configuration;
  15. using Microsoft.Extensions.Options;
  16. using NUnit.Framework;
  17. using OpenXmlPowerTools;
  18. using System;
  19. using System.Collections.Generic;
  20. using System.Linq;
  21. using System.Net;
  22. using System.Reflection;
  23. using System.Text;
  24. using System.Text.Json;
  25. using System.Threading.Tasks;
  26. using System.Xml.Linq;
  27. using TEAMModelOS.Filter;
  28. using TEAMModelOS.Models;
  29. using TEAMModelOS.SDK;
  30. using TEAMModelOS.SDK.DI;
  31. using TEAMModelOS.SDK.Extension;
  32. using TEAMModelOS.SDK.Models;
  33. using TEAMModelOS.SDK.Models.Cosmos.Common;
  34. using Survey = TEAMModelOS.SDK.Models.Survey;
  35. namespace TEAMModelOS.Controllers.Common
  36. {
  37. [ProducesResponseType(StatusCodes.Status200OK)]
  38. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  39. [Route("common/art")]
  40. [ApiController]
  41. public class ArtController : ControllerBase
  42. {
  43. private readonly AzureCosmosFactory _azureCosmos;
  44. private readonly SnowflakeId _snowflakeId;
  45. private readonly AzureServiceBusFactory _serviceBus;
  46. private readonly DingDing _dingDing;
  47. private readonly Option _option;
  48. private readonly AzureStorageFactory _azureStorage;
  49. private readonly AzureRedisFactory _azureRedis;
  50. private readonly IConverter _converter;
  51. public IConfiguration _configuration { get; set; }
  52. private readonly CoreAPIHttpService _coreAPIHttpService;
  53. public ArtController(IConverter converter, CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId, DingDing dingDing,
  54. IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, IConfiguration configuration)
  55. {
  56. _coreAPIHttpService = coreAPIHttpService;
  57. _azureCosmos = azureCosmos;
  58. _serviceBus = serviceBus;
  59. _snowflakeId = snowflakeId;
  60. _dingDing = dingDing;
  61. _option = option?.Value;
  62. _azureStorage = azureStorage;
  63. _azureRedis = azureRedis;
  64. _configuration = configuration;
  65. _converter = converter;
  66. }
  67. /// <summary>
  68. /// 保存艺术评价信息
  69. /// </summary>
  70. /// <param name="request"></param>
  71. /// <returns></returns>
  72. [ProducesDefaultResponseType]
  73. [AuthToken(Roles = "teacher,admin")]
  74. [HttpPost("save")]
  75. [Authorize(Roles = "IES")]
  76. public async Task<IActionResult> Save(JsonElement request)
  77. {
  78. try
  79. {
  80. if (!request.TryGetProperty("art", out JsonElement art)) return BadRequest();
  81. var client = _azureCosmos.GetCosmosClient();
  82. ArtEvaluation ae = art.ToObject<ArtEvaluation>();
  83. bool flag = false;
  84. ArtMusic music = new();
  85. if (request.TryGetProperty("ArtMusic", out JsonElement am))
  86. {
  87. music = am.ToObject<ArtMusic>();
  88. music.ttl = -1;
  89. music.code = "ArtMusic";
  90. flag = true;
  91. };
  92. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  93. string code = ae.school;
  94. ae.ttl = -1;
  95. ae.progress = "going";
  96. ae.creatorId = userid;
  97. if (!ae.owner.Equals("area"))
  98. {
  99. ae.owner = "school";
  100. ae.code = "Art-" + code;
  101. ae.scope = "school";
  102. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  103. ae.createTime = now;
  104. ae.publish = 0;
  105. }
  106. if (string.IsNullOrEmpty(ae.id))
  107. {
  108. ae.id = Guid.NewGuid().ToString();
  109. await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(ae, new PartitionKey($"{ae.code}"));
  110. if (flag)
  111. {
  112. music.id = ae.id;
  113. await client.GetContainer("TEAMModelOS", "Common").CreateItemAsync(music, new PartitionKey("ArtMusic"));
  114. }
  115. }
  116. else
  117. {
  118. if (flag)
  119. {
  120. await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(music, music.id, new PartitionKey("ArtMusic"));
  121. }
  122. await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(ae, ae.id, new PartitionKey($"{ae.code}"));
  123. }
  124. return Ok(new { ae });
  125. }
  126. catch (Exception ex)
  127. {
  128. await _dingDing.SendBotMsg($"OS,{_option.Location},art/save()\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  129. return Ok(new { code = 500, msg = ex.Message });
  130. }
  131. }
  132. [ProducesDefaultResponseType]
  133. [AuthToken(Roles = "teacher,admin,student")]
  134. [HttpPost("update-state")]
  135. [Authorize(Roles = "IES")]
  136. public async Task<IActionResult> UpdateState(ArtRecord request)
  137. {
  138. var client = _azureCosmos.GetCosmosClient();
  139. try
  140. {
  141. var (userid, name, picture, school) = HttpContext.GetAuthTokenInfo();
  142. HttpContext.Items.TryGetValue("Scope", out object scope);
  143. int userType = $"{scope}".Equals(Constant.ScopeStudent) ? 2 : 1;
  144. request.school = school;
  145. request.stuId = userid;
  146. request.code = "ArtRecord";
  147. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  148. request.createTime = now;
  149. ArtRecord record;
  150. if (string.IsNullOrEmpty(request.id))
  151. {
  152. request.id = Guid.NewGuid().ToString();
  153. record = await client.GetContainer("TEAMModelOS", "Student").CreateItemAsync(request, new PartitionKey($"{request.code}"));
  154. }
  155. else
  156. {
  157. record = await client.GetContainer("TEAMModelOS", "Student").ReplaceItemAsync(request, request.id, new PartitionKey($"{request.code}"));
  158. }
  159. return Ok(record);
  160. }
  161. catch (Exception e)
  162. {
  163. return BadRequest(new { msg = e.Message });
  164. }
  165. }
  166. [ProducesDefaultResponseType]
  167. [AuthToken(Roles = "teacher,admin,student")]
  168. [HttpPost("upload")]
  169. [Authorize(Roles = "IES")]
  170. public async Task<IActionResult> Upload(ArtRecord request)
  171. {
  172. try
  173. {
  174. var client = _azureCosmos.GetCosmosClient();
  175. var (userid, name, picture, school) = HttpContext.GetAuthTokenInfo();
  176. HttpContext.Items.TryGetValue("Scope", out object scope);
  177. int userType = $"{scope}".Equals(Constant.ScopeStudent) ? 2 : 1;
  178. request.school = school;
  179. request.stuId = userid;
  180. request.code = "ArtRecord";
  181. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  182. request.createTime = now;
  183. ArtRecord record;
  184. StudentArtResult artResult;
  185. ArtEvaluation art;
  186. List<string> classIds = new();
  187. List<GroupListGrp> groups = await GroupListService.GetMemberInGroupList(_coreAPIHttpService, client, _dingDing, userid, userType, school, new List<string> { "class", "teach" });
  188. foreach (var grp in groups)
  189. {
  190. classIds.Add(grp.id);
  191. }
  192. if (string.IsNullOrEmpty(request.id))
  193. {
  194. request.id = Guid.NewGuid().ToString();
  195. record = await client.GetContainer("TEAMModelOS", "Student").CreateItemAsync(request, new PartitionKey($"{request.code}"));
  196. }
  197. else
  198. {
  199. record = await client.GetContainer("TEAMModelOS", "Student").ReplaceItemAsync(request, request.id, new PartitionKey($"{request.code}"));
  200. }
  201. string rId = string.Format("{0}{1}{2}", request.school, "-", userid);
  202. //首先根据大ID获取整个活动得内容
  203. var aresponse = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(request.artId, new PartitionKey($"Art-{school}"));
  204. if (aresponse.Status == 200)
  205. {
  206. using var json = await JsonDocument.ParseAsync(aresponse.ContentStream);
  207. art = json.ToObject<ArtEvaluation>();
  208. var response = await client.GetContainer("TEAMModelOS", "Student").ReadItemStreamAsync(rId, new PartitionKey($"ArtResult-{request.artId}"));
  209. if (response.Status == 200)
  210. {
  211. using var json_1 = await JsonDocument.ParseAsync(response.ContentStream);
  212. artResult = json_1.ToObject<StudentArtResult>();
  213. List<Attachment> files = new();
  214. files = request.attachments;
  215. //bool flage = artResult.results.Exists(a => a.taskId == request.acId);
  216. artResult.results.ForEach(a =>
  217. {
  218. if (a.taskId == request.acId)
  219. {
  220. a.files = files;
  221. }
  222. });
  223. await client.GetContainer("TEAMModelOS", "Student").ReplaceItemAsync(artResult, artResult.id, new PartitionKey($"{artResult.code}"));
  224. }
  225. else
  226. {
  227. artResult = new StudentArtResult
  228. {
  229. id = rId,
  230. pk = "ArtResult",
  231. code = $"ArtResult-{request.artId}",
  232. studentId = userid,
  233. picture = picture,
  234. studentName = name,
  235. school = school,
  236. userType = userType,
  237. artId = request.artId,
  238. classIds = classIds,
  239. };
  240. foreach (var qIds in art.settings)
  241. {
  242. foreach (var task in qIds.task)
  243. {
  244. ArtQuotaResult quotaResult = new()
  245. {
  246. quotaId = qIds.id,
  247. quotaName = qIds.quotaname,
  248. quotaType = (int)task.type,
  249. subjectId = task.subject,
  250. taskId = task.acId
  251. };
  252. if (!string.IsNullOrEmpty(quotaResult.taskId))
  253. {
  254. if (quotaResult.taskId.Equals(request.acId))
  255. {
  256. quotaResult.files = request.attachments;
  257. }
  258. }
  259. artResult.results.Add(quotaResult);
  260. }
  261. }
  262. await client.GetContainer("TEAMModelOS", "Student").CreateItemAsync(artResult, new PartitionKey($"{artResult.code}"));
  263. }
  264. }
  265. return Ok(new { record, code = 200 });
  266. }
  267. catch (Exception ex)
  268. {
  269. await _dingDing.SendBotMsg($"OS,{_option.Location},art/upload()\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  270. return Ok(new { code = 500, msg = ex.Message });
  271. }
  272. }
  273. [ProducesDefaultResponseType]
  274. [AuthToken(Roles = "teacher,admin,student")]
  275. [HttpPost("upload-all")]
  276. [Authorize(Roles = "IES")]
  277. public async Task<IActionResult> UploadAll(JsonElement element)
  278. {
  279. try
  280. {
  281. var client = _azureCosmos.GetCosmosClient();
  282. var (_, _, _, school) = HttpContext.GetAuthTokenInfo();
  283. if (!element.TryGetProperty("artId", out JsonElement artId)) return BadRequest();
  284. if (!element.TryGetProperty("classId", out JsonElement classId)) return BadRequest();
  285. if (!element.TryGetProperty("quotaId", out JsonElement quotaId)) return BadRequest();
  286. if (!element.TryGetProperty("acId", out JsonElement acId)) return BadRequest();
  287. if (!element.TryGetProperty("subject", out JsonElement subject)) return BadRequest();
  288. if (!element.TryGetProperty("stus", out JsonElement stus)) return BadRequest();
  289. //HttpContext.Items.TryGetValue("Scope", out object scope);
  290. //int userType = $"{scope}".Equals(Constant.ScopeStudent) ? 2 : 1;
  291. List<stuFiles> stuFiles = stus.ToObject<List<stuFiles>>();
  292. List<string> value = new List<string>();
  293. await foreach (var s in stuTask(stuFiles, client, school, artId.GetString(), classId.GetString(), quotaId.GetString(), acId.GetString(), subject.GetString()))
  294. {
  295. if (s.code == 1)
  296. {
  297. value.Add(s.value);
  298. }
  299. }
  300. if (value.Count > 0)
  301. {
  302. return Ok(new { code = 1, msg = "学生ID导入异常", value = value });
  303. }
  304. else
  305. {
  306. return Ok(new { code = 0 });
  307. }
  308. }
  309. catch (Exception ex)
  310. {
  311. await _dingDing.SendBotMsg($"OS,{_option.Location},art/uploadAll()\n{ex.Message}\n{ex.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  312. return Ok(new { code = 500, msg = ex.Message });
  313. }
  314. }
  315. private async IAsyncEnumerable<(int code, string value)> stuTask(List<stuFiles> stuFiles, CosmosClient client, string school, string artId, string classId, string quotaId, string acId, string subject)
  316. {
  317. string queryScore = $" select c.id from c where c.artId ='{artId}' and c.quotaId = '{quotaId}' and c.acId = '{acId}' and c.subject = '{subject}' and c.classId = '{classId}'";
  318. List<string> ids = new();
  319. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryStreamIterator
  320. (queryText: queryScore, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("ArtRecord") }))
  321. {
  322. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  323. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  324. {
  325. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  326. {
  327. if (obj.TryGetProperty("id", out JsonElement subScore))
  328. {
  329. //string sId = obj.GetProperty("id").GetString();
  330. ids.Add(subScore.GetString());
  331. }
  332. }
  333. }
  334. }
  335. await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemsAsync<ArtRecord>(ids, "ArtRecord");
  336. // await _azureStorage.GetBlobServiceClient().DeleteBlobs(_dingDing, school, new List<string> { $"art/{artId}" });
  337. foreach (var request in stuFiles)
  338. {
  339. string value = "";
  340. int code = 0;
  341. try
  342. {
  343. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  344. ArtRecord record = new()
  345. {
  346. school = school,
  347. stuId = request.stuId,
  348. artId = artId,
  349. classId = classId,
  350. quotaId = quotaId,
  351. acId = acId,
  352. subject = subject,
  353. createTime = now,
  354. code = "ArtRecord",
  355. attachments = request.attachments
  356. };
  357. StudentArtResult artResult;
  358. ArtEvaluation art;
  359. List<string> classIds = new();
  360. List<GroupListGrp> groups = await GroupListService.GetMemberInGroupList(_coreAPIHttpService, client, _dingDing, request.stuId, request.userType, school, new List<string> { "class", "teach" });
  361. foreach (var grp in groups)
  362. {
  363. classIds.Add(grp.id);
  364. }
  365. if (string.IsNullOrEmpty(record.id))
  366. {
  367. record.id = Guid.NewGuid().ToString();
  368. record = await client.GetContainer("TEAMModelOS", "Student").CreateItemAsync(record, new PartitionKey($"{record.code}"));
  369. }
  370. else
  371. {
  372. record = await client.GetContainer("TEAMModelOS", "Student").ReplaceItemAsync(record, record.id, new PartitionKey($"{record.code}"));
  373. }
  374. string rId = string.Format("{0}{1}{2}", record.school, "-", record.stuId);
  375. //首先根据大ID获取整个活动得内容
  376. var aresponse = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(artId, new PartitionKey($"Art-{school}"));
  377. if (aresponse.Status == 200)
  378. {
  379. using var json = await JsonDocument.ParseAsync(aresponse.ContentStream);
  380. art = json.ToObject<ArtEvaluation>();
  381. var response = await client.GetContainer("TEAMModelOS", "Student").ReadItemStreamAsync(rId, new PartitionKey($"ArtResult-{artId}"));
  382. if (response.Status == 200)
  383. {
  384. using var json_1 = await JsonDocument.ParseAsync(response.ContentStream);
  385. artResult = json_1.ToObject<StudentArtResult>();
  386. List<Attachment> files = new();
  387. files = request.attachments;
  388. //bool flage = artResult.results.Exists(a => a.taskId == request.acId);
  389. artResult.results.ForEach(a =>
  390. {
  391. if (a.taskId == acId)
  392. {
  393. a.files = files;
  394. }
  395. });
  396. await client.GetContainer("TEAMModelOS", "Student").ReplaceItemAsync(artResult, artResult.id, new PartitionKey($"{artResult.code}"));
  397. }
  398. else
  399. {
  400. artResult = new StudentArtResult
  401. {
  402. id = rId,
  403. pk = "ArtResult",
  404. code = $"ArtResult-{artId}",
  405. studentId = request.stuId,
  406. //picture = picture,
  407. studentName = request.name,
  408. school = school,
  409. userType = request.userType,
  410. artId = artId,
  411. classIds = classIds,
  412. };
  413. foreach (var qIds in art.settings)
  414. {
  415. foreach (var task in qIds.task)
  416. {
  417. ArtQuotaResult quotaResult = new()
  418. {
  419. quotaId = qIds.id,
  420. quotaName = qIds.quotaname,
  421. quotaType = (int)task.type,
  422. subjectId = task.subject,
  423. taskId = task.acId
  424. };
  425. if (!string.IsNullOrEmpty(quotaResult.taskId))
  426. {
  427. if (quotaResult.taskId.Equals(acId))
  428. {
  429. quotaResult.files = request.attachments;
  430. }
  431. }
  432. artResult.results.Add(quotaResult);
  433. }
  434. }
  435. await client.GetContainer("TEAMModelOS", "Student").CreateItemAsync(artResult, new PartitionKey($"{artResult.code}"));
  436. }
  437. }
  438. }
  439. catch (Exception e)
  440. {
  441. value = request.stuId;
  442. code = 1;
  443. }
  444. yield return (code, value);
  445. }
  446. }
  447. [ProducesDefaultResponseType]
  448. [AuthToken(Roles = "teacher,admin")]
  449. [HttpPost("delete")]
  450. [Authorize(Roles = "IES")]
  451. public async Task<IActionResult> Delete(JsonElement request)
  452. {
  453. try
  454. {
  455. //object userScope = null;
  456. //object _standard = null;
  457. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  458. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  459. /* string standard = null;
  460. HttpContext?.Items?.TryGetValue("Scope", out userScope);
  461. if (userScope != null && $"{userScope}".Equals(Constant.ScopeTeacher))
  462. {
  463. HttpContext?.Items?.TryGetValue("Standard", out _standard);
  464. standard = _standard != null && string.IsNullOrEmpty($"{userScope}") ? _standard.ToString() : null;
  465. }*/
  466. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  467. var client = _azureCosmos.GetCosmosClient();
  468. var sresponse = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(id.ToString(), new PartitionKey($"Art-{code}"));
  469. if (sresponse.Status == 200)
  470. {
  471. using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
  472. ArtEvaluation art = json.ToObject<ArtEvaluation>();
  473. //必须是本人或者这个学校的管理者才能删除
  474. bool flag = false;
  475. if (art.creatorId == userid)
  476. {
  477. flag = true;
  478. }
  479. else
  480. {
  481. if (art.scope == "school" && art.school.Equals(school))
  482. {
  483. flag = true;
  484. }
  485. }
  486. /*try
  487. {
  488. (List<RMember> members, List<RGroupList> groups) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, null, art.school, null);
  489. await StatisticsService.DoChange(new TeacherTrainChange
  490. { standard = standard, tmdids = members.Select(x => x.id)?.ToList(), school = art.school, update = new HashSet<string> { StatisticsService.OfflineRecord }, statistics = 0 }, _azureCosmos);
  491. }
  492. catch (Exception ex)
  493. {
  494. await _dingDing.SendBotMsg($"OS,{_option.Location},art/delete()ex\n{ex.Message}\n{ex.StackTrace},\n", GroupNames.醍摩豆服務運維群組);
  495. }*/
  496. if (flag)
  497. {
  498. art.status = 404;
  499. foreach (var info in art.settings)
  500. {
  501. /* if (info.TryGetProperty("examId", out JsonElement eId)) {
  502. }*/
  503. foreach (var acs in info.task)
  504. {
  505. if (!string.IsNullOrEmpty(acs.acId))
  506. {
  507. if (acs.type == 1)
  508. {
  509. Azure.Response response = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(acs.acId, new PartitionKey($"Exam-{code}"));
  510. if (response.Status == 200)
  511. {
  512. ExamInfo data = JsonDocument.Parse(response.Content).RootElement.Deserialize<ExamInfo>();
  513. data.status = 404;
  514. await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(data, data.id, new PartitionKey($"Exam-{code}"));
  515. }
  516. }
  517. }
  518. }
  519. }
  520. await client.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync(art, art.id, new PartitionKey($"{art.code}"));
  521. //如果是区级活动删除 先查询该区下面所有的艺术评测ID集合
  522. if (art.publish == 0)
  523. {
  524. List<string> artIds = new();
  525. string sql = $"select c.id from c where c.pId = {art.pId}";
  526. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Common).GetItemQueryStreamIterator
  527. (queryText: sql))
  528. {
  529. using var sjson = await JsonDocument.ParseAsync(item.ContentStream);
  530. if (sjson.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  531. {
  532. foreach (var obj in sjson.RootElement.GetProperty("Documents").EnumerateArray())
  533. {
  534. if (obj.TryGetProperty("id", out JsonElement subScore))
  535. {
  536. string sId = obj.GetProperty("id").GetString();
  537. artIds.Add(sId);
  538. }
  539. }
  540. }
  541. }
  542. foreach (string artId in artIds) {
  543. await client.GetContainer("TEAMModelOS", "Common").DeleteItemStreamAsync(artId, new PartitionKey("ArtMusic"));
  544. await client.GetContainer("TEAMModelOS", "Common").DeleteItemStreamAsync(artId, new PartitionKey("ArtExam"));
  545. }
  546. string queryScore = $" select c.id from c where c.artId in ({string.Join(",", artIds.Select(o => $"'{o}'"))})";
  547. List<string> ids = new();
  548. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryStreamIterator
  549. (queryText: queryScore, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("ArtRecord") }))
  550. {
  551. using var sjson = await JsonDocument.ParseAsync(item.ContentStream);
  552. if (sjson.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  553. {
  554. foreach (var obj in sjson.RootElement.GetProperty("Documents").EnumerateArray())
  555. {
  556. if (obj.TryGetProperty("id", out JsonElement subScore))
  557. {
  558. string sId = obj.GetProperty("id").GetString();
  559. ids.Add(sId);
  560. }
  561. }
  562. }
  563. }
  564. await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemsAsync<ArtRecord>(ids, "ArtRecord");
  565. }
  566. else {
  567. string queryScore = $" select c.id from c where c.artId = {art.id})";
  568. List<string> ids = new();
  569. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryStreamIterator
  570. (queryText: queryScore, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("ArtRecord") }))
  571. {
  572. using var sjson = await JsonDocument.ParseAsync(item.ContentStream);
  573. if (sjson.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  574. {
  575. foreach (var obj in sjson.RootElement.GetProperty("Documents").EnumerateArray())
  576. {
  577. if (obj.TryGetProperty("id", out JsonElement subScore))
  578. {
  579. string sId = obj.GetProperty("id").GetString();
  580. ids.Add(sId);
  581. }
  582. }
  583. }
  584. }
  585. await client.GetContainer(Constant.TEAMModelOS, "Student").DeleteItemsAsync<ArtRecord>(ids, "ArtRecord");
  586. await client.GetContainer("TEAMModelOS", "Common").DeleteItemStreamAsync(art.id, new PartitionKey("ArtMusic"));
  587. }
  588. }
  589. }
  590. return Ok(new { id });
  591. }
  592. catch (Exception e)
  593. {
  594. await _dingDing.SendBotMsg($"OS,{_option.Location},art/delete()\n{e.Message}\n{e.StackTrace},\n", GroupNames.醍摩豆服務運維群組);
  595. return Ok(new { code = 500 });
  596. }
  597. }
  598. /// <param name="request"></param>
  599. /// <returns></returns>
  600. [ProducesDefaultResponseType]
  601. [Authorize(Roles = "IES")]
  602. [AuthToken(Roles = "teacher,admin")]
  603. [HttpPost("find")]
  604. public async Task<IActionResult> Find(JsonElement request)
  605. {
  606. try
  607. {
  608. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  609. request.TryGetProperty("periodId", out JsonElement period);
  610. request.TryGetProperty("periodType", out JsonElement periodType);
  611. if (string.IsNullOrWhiteSpace($"{period}") && string.IsNullOrWhiteSpace($"{periodType}"))
  612. {
  613. return BadRequest();
  614. }
  615. var client = _azureCosmos.GetCosmosClient();
  616. StringBuilder stringBuilder = new($"select c.id,c.img,c.name,c.classes,c.code,c.type,c.startTime,c.endTime,c.presenter,c.topic,c.address,c.owner,c.progress from c where (c.status<>404 or IS_DEFINED(c.status) = false )");
  617. string continuationToken = string.Empty;
  618. string token = default;
  619. if (!string.IsNullOrWhiteSpace($"{period}") && !string.IsNullOrWhiteSpace($"{periodType}"))
  620. {
  621. stringBuilder.Append($" and (c.period.id = '{period}' or c.periodType = '{periodType}')");
  622. }
  623. if (string.IsNullOrWhiteSpace($"{period}") && !string.IsNullOrWhiteSpace($"{periodType}"))
  624. {
  625. stringBuilder.Append($" and c.periodType = '{periodType}' ");
  626. }
  627. if (!string.IsNullOrWhiteSpace($"{period}") && string.IsNullOrWhiteSpace($"{periodType}"))
  628. {
  629. stringBuilder.Append($" and c.period.id = '{period}' ");
  630. }
  631. stringBuilder.Append("order by c.createTime desc");
  632. //是否需要进行分页查询,默认不分页
  633. bool iscontinuation = false;
  634. if (request.TryGetProperty("token", out JsonElement token_1))
  635. {
  636. token = token_1.GetString();
  637. iscontinuation = true;
  638. };
  639. //默认不指定返回大小
  640. int? topcout = null;
  641. if (request.TryGetProperty("count", out JsonElement jcount))
  642. {
  643. if (!jcount.ValueKind.Equals(JsonValueKind.Undefined) && !jcount.ValueKind.Equals(JsonValueKind.Null) && jcount.TryGetInt32(out int data))
  644. {
  645. topcout = data;
  646. }
  647. }
  648. List<ArtEvaluation> arts = new();
  649. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: stringBuilder.ToString(), continuationToken: token, requestOptions: new QueryRequestOptions() { MaxItemCount = topcout, PartitionKey = new PartitionKey($"Art-{code}") }))
  650. {
  651. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  652. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  653. {
  654. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  655. {
  656. arts.Add(obj.ToObject<ArtEvaluation>());
  657. }
  658. }
  659. if (iscontinuation)
  660. {
  661. continuationToken = item.GetContinuationToken();
  662. break;
  663. }
  664. }
  665. arts = arts.Where((x, i) => arts.FindIndex(z => z.id == x.id) == i).ToList();
  666. return Ok(new { arts });
  667. }
  668. catch (Exception e)
  669. {
  670. await _dingDing.SendBotMsg($"OS,{_option.Location},art/find()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  671. return Ok(new { code = 500 });
  672. }
  673. }
  674. [ProducesDefaultResponseType]
  675. [Authorize(Roles = "IES")]
  676. [AuthToken(Roles = "teacher,admin,student")]
  677. [HttpPost("find-summary")]
  678. public async Task<IActionResult> FindSummary(JsonElement request)
  679. {
  680. try
  681. {
  682. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  683. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  684. var client = _azureCosmos.GetCosmosClient();
  685. ArtEvaluation art = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ArtEvaluation>(id.GetString(), new PartitionKey($"Art-{code}"));
  686. ArtMusic music = new();
  687. ArtExam ae = new();
  688. if (art != null)
  689. {
  690. string queryArtExam = $" select value(c) from c where c.activityId = '{art.pId}' ";
  691. //List<ArtExam> aes = new List<ArtExam>();
  692. /* await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Common).GetItemQueryIterator<ArtExam>
  693. (queryText: queryArtExam, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtExam") }))
  694. {
  695. aes.Add(item);
  696. }*/
  697. if (!string.IsNullOrWhiteSpace(art.pId))
  698. {
  699. var response = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(art.pId, new PartitionKey("ArtMusic"));
  700. var sresponse = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(art.pId, new PartitionKey("ArtExam"));
  701. if (sresponse.Status == 200)
  702. {
  703. using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
  704. ae = json.ToObject<ArtExam>();
  705. }
  706. if (response.Status == 200)
  707. {
  708. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  709. music = json.ToObject<ArtMusic>();
  710. }
  711. }
  712. else
  713. {
  714. var response = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(art.id, new PartitionKey("ArtMusic"));
  715. if (response.Status == 200)
  716. {
  717. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  718. music = json.ToObject<ArtMusic>();
  719. }
  720. }
  721. (List<RMember> rmembers, List<RGroupList> groups) = await GroupListService.GetMemberByListids(_coreAPIHttpService, client, _dingDing, art.classes, art.school);
  722. var classes = art.classes.Select(c => new
  723. {
  724. id = c,
  725. groups.Where(g => g.id.Equals(c)).FirstOrDefault()?.name
  726. });
  727. rmembers.ForEach(x =>
  728. {
  729. groups.ForEach(z =>
  730. {
  731. if (z.members.Exists(y => y.id.Equals(x.id) && y.type == x.type))
  732. {
  733. x.groupListIds.Add(z.id);
  734. }
  735. });
  736. });
  737. List<ArtSubjectScore> subjectScores = new List<ArtSubjectScore>();
  738. art.subjects.ForEach(z => { subjectScores.Add(new ArtSubjectScore { subjectId = z.id, score = 0 }); });
  739. var students = rmembers.Select(z => new StudentArtResult
  740. {
  741. studentId = z.id,
  742. studentName = z.name,
  743. userType = z.type,
  744. classIds = z.groupListIds,
  745. school = z.schoolId,
  746. picture = z.picture,
  747. artId = $"{id}",
  748. id = $"{z.schoolId}-{z.id}",
  749. code = $"ArtResult-{id}",
  750. pk = "ArtResult",
  751. ttl = -1,
  752. subjectScores = subjectScores,
  753. }).ToList();
  754. //TODO 缺考人数的结算(多科评量检测,作业的提交)
  755. if (students.Any())
  756. {
  757. string query = $" select value c.id from c where c.id in({string.Join(",", students.Select(x => $"'{x.id}'"))}) ";
  758. List<string> list = new List<string>();
  759. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryIterator<string>
  760. (queryText: query, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtResult-{id}") }))
  761. {
  762. list.Add(item);
  763. }
  764. students.RemoveAll(x => list.Contains(x.id));
  765. students.ForEach(x =>
  766. {
  767. art.settings.ForEach(a =>
  768. {
  769. a.task.ForEach(z =>
  770. {
  771. ArtQuotaResult quotaResult = new ArtQuotaResult
  772. {
  773. taskId = z.acId,
  774. subjectId = z.subject,
  775. quotaId = a.id,
  776. quotaType = z.type.Value,
  777. quotaName = a.quotaname
  778. };
  779. x.results.Add(quotaResult);
  780. });
  781. });
  782. });
  783. List<Task<ItemResponse<StudentArtResult>>> responses = new();
  784. students.ForEach(z =>
  785. {
  786. responses.Add(client.GetContainer(Constant.TEAMModelOS, Constant.Student).CreateItemAsync(z, new PartitionKey(z.code)));
  787. });
  788. if (responses.Count > 0)
  789. {
  790. await responses.TaskPage(10);
  791. }
  792. }
  793. if (!string.IsNullOrWhiteSpace(ae.id))
  794. {
  795. return Ok(new { art, classes, ae, music,count = rmembers.Count, code = 200 });
  796. }
  797. else
  798. {
  799. return Ok(new { art, classes, music,count = rmembers.Count, code = 200 });
  800. }
  801. }
  802. else
  803. {
  804. return Ok(new { art, code = 404 });
  805. }
  806. }
  807. catch (CosmosException ex) when (ex.Status == 404)
  808. {
  809. return Ok(new { code = 404 });
  810. }
  811. catch (Exception e)
  812. {
  813. await _dingDing.SendBotMsg($"OS,{_option.Location},art/FindSummary()\n{e.Message}\n{e.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  814. return Ok(new { code = 500 });
  815. }
  816. }
  817. [ProducesDefaultResponseType]
  818. [Authorize(Roles = "IES")]
  819. [AuthToken(Roles = "teacher,admin,student")]
  820. [HttpPost("find-summary-by-student")]
  821. public async Task<IActionResult> findByStudent(JsonElement request)
  822. {
  823. try
  824. {
  825. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  826. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  827. var client = _azureCosmos.GetCosmosClient();
  828. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  829. ArtEvaluation art = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ArtEvaluation>(id.GetString(), new PartitionKey($"Art-{code}"));
  830. ArtMusic music = new();
  831. if (art != null)
  832. {
  833. List<StuActivity> stus = new();
  834. List<string> wIds = new();
  835. List<ArtRecord> works = new();
  836. if (!string.IsNullOrWhiteSpace(art.pId))
  837. {
  838. var response = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(art.pId, new PartitionKey("ArtMusic"));
  839. if (response.Status == 200)
  840. {
  841. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  842. music = json.ToObject<ArtMusic>();
  843. }
  844. }
  845. else
  846. {
  847. var response = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync(art.id, new PartitionKey("ArtMusic"));
  848. if (response.Status == 200)
  849. {
  850. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  851. music = json.ToObject<ArtMusic>();
  852. }
  853. }
  854. var taskType1 = art.settings.SelectMany(z => z.task).Where(t => t.type == 1);
  855. wIds = art.settings.SelectMany(z => z.task).Where(t => t.type == 2).Select(a => a.acId).ToList();
  856. if (taskType1 != null && taskType1.Any())
  857. {
  858. string sql = $"select value c from c where c.id in ({string.Join(",", taskType1.Select(z => $"'{z.acId}'"))})";
  859. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student)
  860. .GetItemQueryIterator<StuActivity>(sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"Activity-{school}-{userid}") }))
  861. {
  862. stus.Add(item);
  863. }
  864. }
  865. //foreach (var tt in art.settings)
  866. //{
  867. // foreach (var acs in tt.task)
  868. // {
  869. // if (acs.type == 1)
  870. // {
  871. // var response = await client.GetContainer("TEAMModelOS", "Student").ReadItemStreamAsync(acs.acId, new PartitionKey($"Activity-{school}-{userid}"));
  872. // if (response.Status == 200)
  873. // {
  874. // using var json = await JsonDocument.ParseAsync(response.ContentStream);
  875. // StuActivity info = json.ToObject<StuActivity>();
  876. // stus.Add(info);
  877. // }
  878. // }
  879. // if (acs.type == 2)
  880. // {
  881. // wIds.Add(acs.acId);
  882. // }
  883. // }
  884. //}
  885. if (wIds.Count > 0)
  886. {
  887. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryIterator<ArtRecord>(
  888. queryText: $"select value(c) from c where c.stuId = '{userid}' and c.acId in ({string.Join(",", wIds.Select(o => $"'{o}'"))})",
  889. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ArtRecord") }))
  890. {
  891. works.Add(item);
  892. }
  893. }
  894. return Ok(new { art, stus, works, music, code = 200 });
  895. }
  896. else
  897. {
  898. return Ok(new { art, code = 404 });
  899. }
  900. }
  901. catch (CosmosException ex) when (ex.Status == 404)
  902. {
  903. return Ok(new { code = 404 });
  904. }
  905. catch (Exception e)
  906. {
  907. await _dingDing.SendBotMsg($"OS,{_option.Location},art/find-summary-by-student()\n{e.Message}\n{e.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  908. return Ok(new { code = 500 });
  909. }
  910. }
  911. [ProducesDefaultResponseType]
  912. [Authorize(Roles = "IES")]
  913. [AuthToken(Roles = "teacher,admin")]
  914. [HttpPost("find-summary-by-work")]
  915. public async Task<IActionResult> findBywork(JsonElement request)
  916. {
  917. try
  918. {
  919. if (!request.TryGetProperty("classId", out JsonElement classId)) return BadRequest();
  920. if (!request.TryGetProperty("subject", out JsonElement subject)) return BadRequest();
  921. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  922. var client = _azureCosmos.GetCosmosClient();
  923. var (userid, _, _, school) = HttpContext.GetAuthTokenInfo();
  924. List<object> works = new();
  925. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Student").GetItemQueryStreamIterator(
  926. queryText: $"select c.stuId,c.attachments,c.isAnswer,c.createTime,c.url from c where c.classId = '{classId}' and c.acId = '{id}' and c.subject = '{subject}'",
  927. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"ArtRecord") }))
  928. {
  929. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  930. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  931. {
  932. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  933. {
  934. works.Add(obj.ToObject<object>());
  935. }
  936. }
  937. }
  938. return Ok(new { works, code = 200 });
  939. }
  940. catch (CosmosException ex) when (ex.Status == 404)
  941. {
  942. return Ok(new { code = 404 });
  943. }
  944. catch (Exception e)
  945. {
  946. await _dingDing.SendBotMsg($"OS,{_option.Location},art/find-summary-by-work()\n{e.Message}\n{e.StackTrace}\n", GroupNames.醍摩豆服務運維群組);
  947. return Ok(new { code = 500 });
  948. }
  949. }
  950. /// <param name="request"></param>
  951. /// <returns></returns>
  952. [ProducesDefaultResponseType]
  953. [Authorize(Roles = "IES")]
  954. [AuthToken(Roles = "teacher,admin")]
  955. [HttpPost("find-by-teacher")]
  956. public async Task<IActionResult> FindByTeacher(JsonElement request)
  957. {
  958. try
  959. {
  960. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  961. if (!request.TryGetProperty("tId", out JsonElement tId)) return BadRequest();
  962. var client = _azureCosmos.GetCosmosClient();
  963. 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}'";
  964. List<object> arts = new();
  965. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(queryText: query, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Art-{code}") }))
  966. {
  967. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  968. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  969. {
  970. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  971. {
  972. arts.Add(obj.ToObject<object>());
  973. }
  974. }
  975. }
  976. return Ok(new { arts });
  977. }
  978. catch (Exception e)
  979. {
  980. await _dingDing.SendBotMsg($"OS,{_option.Location},art/find-by-teacher()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  981. return Ok(new { code = 500 });
  982. }
  983. }
  984. [ProducesDefaultResponseType]
  985. [Authorize(Roles = "IES")]
  986. [AuthToken(Roles = "teacher,admin")]
  987. [HttpPost("find-summary-by-teacher")]
  988. public async Task<IActionResult> FindSummaryByTeacher(JsonElement request)
  989. {
  990. try
  991. {
  992. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  993. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  994. if (!request.TryGetProperty("tId", out JsonElement tId)) return BadRequest();
  995. var client = _azureCosmos.GetCosmosClient();
  996. List<object> arts = new();
  997. 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($"Art-{code}") }))
  998. {
  999. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  1000. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  1001. {
  1002. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  1003. {
  1004. arts.Add(obj.ToObject<object>());
  1005. }
  1006. }
  1007. }
  1008. return Ok(new { arts });
  1009. }
  1010. catch (Exception e)
  1011. {
  1012. await _dingDing.SendBotMsg($"OS,{_option.Location},art/find-summary-by-teacher()\n{e.Message}\n{e.StackTrace}\n{e.StackTrace}", GroupNames.醍摩豆服務運維群組);
  1013. return Ok(new { code = 500 });
  1014. }
  1015. }
  1016. private class stuFiles
  1017. {
  1018. public string stuId { get; set; }
  1019. public int userType { get; set; }
  1020. public string name { get; set; }
  1021. public List<Attachment> attachments { get; set; } = new List<Attachment>();
  1022. }
  1023. }
  1024. }