ArtReviewController.cs 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638
  1. using Azure;
  2. using Microsoft.Azure.Cosmos;
  3. using Azure.Messaging.ServiceBus;
  4. using DinkToPdf.Contracts;
  5. using Microsoft.AspNetCore.Hosting;
  6. using Microsoft.AspNetCore.Http;
  7. using Microsoft.AspNetCore.Mvc;
  8. using Microsoft.Azure.Amqp.Framing;
  9. using Microsoft.Extensions.Configuration;
  10. using Microsoft.Extensions.Options;
  11. using StackExchange.Redis;
  12. using System;
  13. using System.Collections.Generic;
  14. using System.Linq;
  15. using System.Text.Json;
  16. using System.Threading.Tasks;
  17. using TEAMModelOS.Filter;
  18. using TEAMModelOS.Models;
  19. using TEAMModelOS.SDK;
  20. using TEAMModelOS.SDK.DI;
  21. using TEAMModelOS.SDK.Extension;
  22. using TEAMModelOS.SDK.Models;
  23. using TEAMModelOS.SDK.Models.Cosmos;
  24. using TEAMModelOS.SDK.Models.Service;
  25. using Microsoft.AspNetCore.Authorization;
  26. using static SKIT.FlurlHttpClient.Wechat.TenpayV3.Models.CreateApplyForSubjectApplymentRequest.Types;
  27. using TEAMModelOS.SDK.Models.Cosmos.Student;
  28. using TEAMModelOS.Controllers.Analysis;
  29. using System.Threading;
  30. namespace TEAMModelOS.Controllers
  31. {
  32. /// <summary>
  33. /// SELECT distinct value c FROM c join b in c.results where c.code='ArtResult-e4864b04-7e3d-47ac-8a00-4395569c5860' and array_contains(c.classIds,'26a8d509-ce01-406e-b962-b53474ea3e58' ) and b.subjectId='subject_music'
  34. /// </summary>
  35. [ProducesResponseType(StatusCodes.Status200OK)]
  36. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  37. [Route("school/art")]
  38. [ApiController]
  39. public class ArtReviewController : ControllerBase
  40. {
  41. public IWebHostEnvironment _environment { get; set; }
  42. private readonly AzureCosmosFactory _azureCosmos;
  43. private readonly SnowflakeId _snowflakeId;
  44. private readonly AzureServiceBusFactory _serviceBus;
  45. private readonly DingDing _dingDing;
  46. private readonly Option _option;
  47. private readonly AzureStorageFactory _azureStorage;
  48. private readonly AzureRedisFactory _azureRedis;
  49. private readonly IConverter _converter;
  50. public IConfiguration _configuration { get; set; }
  51. private readonly CoreAPIHttpService _coreAPIHttpService;
  52. private readonly HttpTrigger _httpTrigger;
  53. public ArtReviewController(HttpTrigger httpTrigger, IConverter converter, CoreAPIHttpService coreAPIHttpService, AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId, DingDing dingDing,
  54. IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage, AzureRedisFactory azureRedis, IConfiguration configuration, IWebHostEnvironment env)
  55. {
  56. _environment = env;
  57. _coreAPIHttpService = coreAPIHttpService;
  58. _azureCosmos = azureCosmos;
  59. _serviceBus = serviceBus;
  60. _snowflakeId = snowflakeId;
  61. _dingDing = dingDing;
  62. _option = option?.Value;
  63. _azureStorage = azureStorage;
  64. _azureRedis = azureRedis;
  65. _configuration = configuration;
  66. _converter = converter;
  67. _httpTrigger = httpTrigger;
  68. }
  69. /// <summary>
  70. /// 轮询获取报告生成进度。
  71. /// </summary>
  72. /// <param name="request"></param>
  73. /// <returns></returns>
  74. [ProducesDefaultResponseType]
  75. [HttpPost("gen-pdf-process")]
  76. #if !DEBUG
  77. [AuthToken(Roles = "teacher,admin")]
  78. [Authorize(Roles = "IES")]
  79. #endif
  80. public async Task<IActionResult> GenPDFProcess(JsonElement request) {
  81. if (!request.TryGetProperty("artId", out JsonElement _artId))
  82. {
  83. return BadRequest();
  84. }
  85. if (!request.TryGetProperty("schoolId", out JsonElement _schoolId))
  86. {
  87. return BadRequest();
  88. }
  89. List<RedisValue> studentIds = new List<RedisValue>();
  90. if (request.TryGetProperty("studentIds", out JsonElement _studentIds) && _studentIds.ValueKind.Equals(JsonValueKind.Array))
  91. {
  92. var studentIdS = _studentIds.ToObject<List<string>>();
  93. studentIdS.ForEach(z => { studentIds.Add(z); }) ;
  94. }
  95. string key = $"ArtPDF:{_artId}:{_schoolId}";
  96. List<StudentArtResult> results= new List<StudentArtResult>();
  97. if (studentIds.IsNotEmpty())
  98. {
  99. var values = _azureRedis.GetRedisClient(8).HashGet(key, studentIds.ToArray());
  100. if (values != null)
  101. {
  102. foreach (var rcd in values)
  103. {
  104. if (!rcd.IsNullOrEmpty)
  105. {
  106. var value = rcd.ToString().ToObject<StudentArtResult>();
  107. results.Add(value);
  108. }
  109. }
  110. }
  111. }
  112. else {
  113. var values = _azureRedis.GetRedisClient(8).HashGetAll(key);
  114. if (values != null)
  115. {
  116. foreach (var rcd in values)
  117. {
  118. if (!rcd.Value.IsNullOrEmpty)
  119. {
  120. var value = rcd.Value.ToString().ToObject<StudentArtResult>();
  121. results.Add(value);
  122. }
  123. }
  124. }
  125. }
  126. var finish = results.Where(z => z.pdf != null && z.pdf.prime == true);
  127. var finishData = finish.Select(z => new { z.studentId, z.artId, z.studentName, z.pdf.url, z.pdf.blob, z.pdf.createTime });
  128. return Ok(new { total= results.Count ,finishCount= finish.Count(), finishData = finishData });
  129. }
  130. /// <summary>
  131. ///
  132. /// </summary>
  133. /// <param name="request"></param>
  134. /// <returns></returns>
  135. [ProducesDefaultResponseType]
  136. [HttpPost("gen-pdf")]
  137. #if !DEBUG
  138. //[AuthToken(Roles = "teacher,admin")]
  139. //[Authorize(Roles = "IES")]
  140. #endif
  141. public async Task<IActionResult> GenPDF(JsonElement request)
  142. {
  143. string head_lang = "";
  144. if (HttpContext.Request.Headers.TryGetValue("lang", out var _lang))
  145. {
  146. head_lang = $"{_lang}";
  147. }
  148. if (string.IsNullOrWhiteSpace(head_lang))
  149. {
  150. head_lang = _option.Location.Contains("China") ? "zh-cn" : "en-us";
  151. }
  152. if (!request.TryGetProperty("opt", out JsonElement _opt))
  153. {
  154. return BadRequest();
  155. }
  156. if (!request.TryGetProperty("artId", out JsonElement _artId))
  157. {
  158. return BadRequest();
  159. }
  160. if (!request.TryGetProperty("schoolId", out JsonElement _schoolId))
  161. {
  162. return BadRequest();
  163. }
  164. List<string> studentIds = new List<string>();
  165. if (request.TryGetProperty("studentIds", out JsonElement _studentIds) && _studentIds.ValueKind.Equals(JsonValueKind.Array))
  166. {
  167. studentIds = _studentIds.ToObject<List<string>>();
  168. }
  169. await ArtService.GenArtPDF(studentIds, $"{_artId}", $"{_schoolId}", head_lang, _serviceBus, _configuration);
  170. return Ok(new {code=0,msg="加入PDF报告生成队列中。" });
  171. }
  172. /**
  173. {
  174. "artId": "99a946a7-f475-463f-846f-834a276e1b34",
  175. "schoolId": "hbcn",
  176. "schoolCode":"hbcn",
  177. "opt": "gen-pdf",
  178. "headLang":"zh-cn",
  179. "studentIds": [
  180. "202206001", "202206002"
  181. ]
  182. }
  183. */
  184. [ProducesDefaultResponseType]
  185. //[AuthToken(Roles = "teacher,admin")]
  186. [HttpPost("update-custom-comment")]
  187. public async Task<IActionResult> UpdateCustomComment(JsonElement json)
  188. {
  189. string head_lang = "";
  190. if (HttpContext.Request.Headers.TryGetValue("lang", out var _lang))
  191. {
  192. head_lang = $"{_lang}";
  193. }
  194. if (string.IsNullOrWhiteSpace(head_lang))
  195. {
  196. head_lang = _option.Location.Contains("China") ? "zh-cn" : "en-us";
  197. }
  198. if (!json.TryGetProperty("artId", out JsonElement _artId))
  199. {
  200. return BadRequest();
  201. }
  202. if (!json.TryGetProperty("schoolId", out JsonElement _schoolId))
  203. {
  204. return BadRequest();
  205. }
  206. if (!json.TryGetProperty("studentId", out JsonElement _studentId))
  207. {
  208. return BadRequest();
  209. }
  210. json.TryGetProperty("comment", out JsonElement _comment);
  211. json.TryGetProperty("comment_music", out JsonElement _comment_music);
  212. json.TryGetProperty("comment_painting", out JsonElement _comment_painting);
  213. string query = $" select value c from c where c.school = '{_schoolId}' and c.studentId ='{_studentId}'";
  214. List<StudentArtResult> artResults = new List<StudentArtResult>();
  215. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryIteratorSql<StudentArtResult>
  216. (queryText: query, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtResult-{_artId}") }))
  217. {
  218. item.comment=$"{_comment}";
  219. item.subjectScores.ForEach(x => {
  220. if(x.subjectId.Equals("subject_music"))
  221. {
  222. x.comment=$"{_comment_music}";
  223. }
  224. if (x.subjectId.Equals("subject_painting"))
  225. {
  226. x.comment = $"{_comment_painting}";
  227. }
  228. });
  229. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).UpsertItemAsync(item, new PartitionKey($"ArtResult-{_artId}"));
  230. artResults.Add(item);
  231. }
  232. if (artResults.IsNotEmpty())
  233. {
  234. var data = await GenPDFService.GenArtStudentPdf(_azureRedis, _azureCosmos, _coreAPIHttpService, _dingDing, _azureStorage, _configuration, artResults.Select(x=>x.studentId).ToList(), $"{_artId}", $"{_schoolId}", $"{head_lang}");
  235. return Ok(new { code = 0, dataFile = data.studentPdfs.Select(x => new { x.blob, x.blobFullUrl }) });
  236. }
  237. return Ok(new { code = 1, msg = "没有找到学生数据" });
  238. }
  239. [ProducesDefaultResponseType]
  240. //[AuthToken(Roles = "teacher,admin")]
  241. [HttpPost("get-pdf-data")]
  242. public async Task<IActionResult> GetPdfData(JsonElement json)
  243. {
  244. if (!json.TryGetProperty("artId", out JsonElement _artId))
  245. {
  246. return BadRequest();
  247. }
  248. if (!json.TryGetProperty("schoolId", out JsonElement _schoolId))
  249. {
  250. return BadRequest();
  251. }
  252. List<string> studentIds = new List<string>();
  253. if (json.TryGetProperty("studentIds", out JsonElement _studentIds) && _studentIds.ValueKind.Equals(JsonValueKind.Array))
  254. {
  255. studentIds = _studentIds.ToObject<List<string>>();
  256. }
  257. string head_lang = string.Empty;
  258. if (HttpContext.Request.Headers.TryGetValue("lang", out var _lang))
  259. {
  260. head_lang = $"{_lang}";
  261. }
  262. if (string.IsNullOrWhiteSpace(head_lang))
  263. {
  264. head_lang = _option.Location.Contains("China") ? "zh-cn" : "en-us";
  265. }
  266. var data = await GenPDFService.GenArtStudentPdf(_azureRedis, _azureCosmos, _coreAPIHttpService, _dingDing, _azureStorage, _configuration, studentIds,$"{_artId}",$"{_schoolId}",$"{head_lang}");
  267. return Ok(new {code=0, dataFiles= data.studentPdfs.Select(x=>new { x.blob,x.blobFullUrl}) });
  268. }
  269. /// <summary>
  270. ///
  271. /// </summary>
  272. /// <param name="request"></param>
  273. /// <returns></returns>
  274. [ProducesDefaultResponseType]
  275. [AuthToken(Roles = "teacher,admin")]
  276. [HttpPost("review")]
  277. # if !DEBUG
  278. [Authorize(Roles = "IES")]
  279. #endif
  280. public async Task<IActionResult> Review(JsonElement request)
  281. {
  282. var client = _azureCosmos.GetCosmosClient();
  283. string head_lang = "";
  284. if (HttpContext.Request.Headers.TryGetValue("lang", out var _lang))
  285. {
  286. head_lang = $"{_lang}";
  287. }
  288. if (string.IsNullOrWhiteSpace(head_lang))
  289. {
  290. head_lang = _option.Location.Contains("China") ? "zh-cn" : "en-us";
  291. }
  292. if (!request.TryGetProperty("opt", out JsonElement _opt))
  293. {
  294. return BadRequest();
  295. }
  296. if (!request.TryGetProperty("artId", out JsonElement _artId))
  297. {
  298. return BadRequest();
  299. }
  300. var (userid, name, _, school) = HttpContext.GetAuthTokenInfo();
  301. try
  302. {
  303. switch (true)
  304. {
  305. case bool when $"{_opt}".Equals("find", StringComparison.OrdinalIgnoreCase):
  306. {
  307. string results_join = "";
  308. string results_where = "";
  309. //string results_filed = "c.results";
  310. string classIds_join = "";
  311. string classIds_where = "";
  312. //string classIds_filed = "c.classIds";
  313. request.TryGetProperty("studentName", out JsonElement studentName);
  314. request.TryGetProperty("studentId", out JsonElement studentId);
  315. request.TryGetProperty("classIds", out JsonElement _classIds);
  316. request.TryGetProperty("subjects", out JsonElement _subjects);
  317. request.TryGetProperty("continuationToken", out JsonElement _continuationToken);
  318. request.TryGetProperty("pageCount", out JsonElement _pageCount);
  319. string continuationToken = null;
  320. if (!string.IsNullOrWhiteSpace($"{_continuationToken}"))
  321. {
  322. continuationToken = $"{_continuationToken}";
  323. }
  324. int pageCount = 100;
  325. if (_pageCount.ValueKind.Equals(JsonValueKind.Number))
  326. {
  327. pageCount = int.Parse($"{_pageCount}");
  328. }
  329. if (_classIds.ValueKind.Equals(JsonValueKind.Array))
  330. {
  331. var classIds = _classIds.Deserialize<List<string>>();
  332. if (classIds.IsNotEmpty())
  333. {
  334. //classIds_filed = " ARRAY_CONCAT([classIds],[]) as classIds ";
  335. classIds_join = " join classIds in c.classIds ";
  336. classIds_where = $" and classIds in({string.Join(",", classIds.Select(x => $"'{x}'"))}) ";
  337. }
  338. }
  339. List<string> subjects = new List<string>();
  340. if (_subjects.ValueKind.Equals(JsonValueKind.Array))
  341. {
  342. subjects = _subjects.Deserialize<List<string>>();
  343. if (subjects.IsNotEmpty())
  344. {
  345. //results_filed = " ARRAY_CONCAT([results],[]) as results ";
  346. results_join = " join results in c.results ";
  347. results_where = $" and ( results.subjectId in({string.Join(",", subjects.Select(x => $"'{x}'"))}) or results.subjectId= null )";
  348. }
  349. }
  350. string studentNameWhere = "";
  351. if (!string.IsNullOrWhiteSpace($"{studentName}"))
  352. {
  353. studentNameWhere = $" and contains(c.studentName,'{studentName}') ";
  354. }
  355. string studentIdWhere = "";
  356. if (!string.IsNullOrWhiteSpace($"{studentId}"))
  357. {
  358. studentIdWhere = $" and c.id = '{school}-{studentId}' ";
  359. }
  360. //string sql = $"SELECT c.id,c.code,c.pk,c.studentId,c.studentName,c.picture,c.userType,c.school,c.artId,c.totalScore ,{results_filed},{classIds_filed}" +
  361. string sql = $"SELECT distinct value( c.id ) " +
  362. $" FROM c {classIds_join} {results_join} where c.pk='ArtResult' {classIds_where} {results_where} {studentIdWhere} {studentNameWhere} ";
  363. List<string> ids = new List<string>();
  364. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryIteratorSql<string>
  365. (queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtResult-{_artId}") }))
  366. {
  367. ids.Add(item);
  368. }
  369. List<StudentArtResult> results = new List<StudentArtResult>();
  370. List<double> scores = new();
  371. List<ArtSubjectScore> As = new();
  372. List<ArtAttachment> artAttachments = new();
  373. string sqlTask = $"select value(c) from c where c.artId = '{_artId}' and c.subjectId = '{subjects[0]}'";
  374. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, Constant.Student).
  375. GetItemQueryIteratorSql<ArtAttachment>(queryText: sqlTask, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtAttachment-{school}") }))
  376. {
  377. artAttachments.Add(item);
  378. }
  379. if (ids.Any())
  380. {
  381. string query = $" select value c from c where c.id in({string.Join(",", ids.Select(x => $"'{x}'"))}) ";
  382. //var result= await client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetList<StudentArtResult>(query, $"ArtResult-{_artId}", continuationToken, pageCount);
  383. //if (result.list.IsNotEmpty()) {
  384. // results.AddRange(result.list);
  385. // continuationToken=result.continuationToken;
  386. //}
  387. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryStreamIteratorSql
  388. (queryText: query, continuationToken: continuationToken, requestOptions: new QueryRequestOptions { MaxItemCount = pageCount, PartitionKey = new PartitionKey($"ArtResult-{_artId}") }))
  389. {
  390. using var json = await JsonDocument.ParseAsync(item.Content);
  391. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  392. {
  393. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  394. {
  395. StudentArtResult student = obj.ToObject<StudentArtResult>();
  396. results.Add(student);
  397. }
  398. }
  399. continuationToken = item.ContinuationToken;
  400. break;
  401. }
  402. if (subjects.IsNotEmpty())
  403. {
  404. results.ForEach(x => x.results.RemoveAll(z => !string.IsNullOrWhiteSpace(z.subjectId) && !subjects.Contains(z.subjectId)));
  405. results.ForEach(x => x.subjectScores.RemoveAll(z => !string.IsNullOrWhiteSpace(z.subjectId) && !subjects.Contains(z.subjectId)));
  406. }
  407. string queryScore = $" select c.totalScore,c.subjectScores from c where c.id in({string.Join(",", ids.Select(x => $"'{x}'"))}) ";
  408. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student).GetItemQueryStreamIteratorSql
  409. (queryText: queryScore, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtResult-{_artId}") }))
  410. {
  411. using var json = await JsonDocument.ParseAsync(item.Content);
  412. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  413. {
  414. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  415. {
  416. if (obj.TryGetProperty("totalScore", out JsonElement element))
  417. {
  418. double sc = element.GetDouble();
  419. scores.Add(sc);
  420. }
  421. else
  422. {
  423. scores.Add(0);
  424. }
  425. if (obj.TryGetProperty("subjectScores", out JsonElement subScore))
  426. {
  427. List<ArtSubjectScore> sc = subScore.ToObject<List<ArtSubjectScore>>();
  428. As.AddRange(sc);
  429. }
  430. else
  431. {
  432. As.AddRange(new List<ArtSubjectScore>());
  433. }
  434. }
  435. }
  436. }
  437. }
  438. ;
  439. if (subjects.IsNotEmpty())
  440. {
  441. var subjectScore = subjects.Select(s => new
  442. {
  443. id = s,
  444. name = As.Where(a => a.subjectId.Equals(s)).Select(x => x.score)
  445. });
  446. var works = results.Select(x => new
  447. {
  448. x.studentId,
  449. x.studentName,
  450. x.classIds,
  451. x.code,
  452. x.blob,
  453. x.id,
  454. x.pdf,
  455. x.picture,
  456. x.school,
  457. x.totalScore,
  458. x.userType,
  459. x.zyanswer,
  460. x.pk,
  461. x.subjectScores,
  462. x.artId,
  463. results = x.results.Select(c => new {
  464. attachments = artAttachments.Where(z=> z.studentId.Equals(x.studentId) && z.taskId.Equals(c.taskId)).ToList().FirstOrDefault(),
  465. c.files,
  466. c.name,
  467. c.quotaId,
  468. c.quotaName,
  469. c.score,
  470. c.source,
  471. c.subjectId,
  472. c.subjectName,
  473. c.taskId,
  474. c.taskName
  475. }),
  476. //attachments = artAttachments.Where(c => c.studentId.Equals(x.studentId)).ToList().FirstOrDefault(),
  477. //url = x.results.Where(c => c.taskId.Equals(taskId.GetString())).FirstOrDefault().quotaId.Equals("quota_22") ? zyUrl.Where(c => c.stuId.Equals(x.studentId)).FirstOrDefault().url : ""
  478. });
  479. return Ok(new { subjectScore, scores, results = works.OrderBy(z => z.studentId), status = 1, continuationToken });
  480. }
  481. else
  482. {
  483. return Ok(new { scores, results = results.OrderBy(z => z.studentId), status = 1, continuationToken });
  484. }
  485. }
  486. case bool when $"{_opt}".Equals("saveScore", StringComparison.OrdinalIgnoreCase)
  487. && request.TryGetProperty("studentScore", out JsonElement _studentScore):
  488. {
  489. //_studentScore的结构:
  490. /*
  491. [
  492. {
  493. "studentId":"学生id",
  494. "totalScore":12,
  495. "results":
  496. [
  497. {
  498. "taskId":"",
  499. "subjectId":"",
  500. "quotaId":"",
  501. "score":50.5,
  502. }
  503. ]
  504. }
  505. ]
  506. */
  507. List<StudentArt> results = _studentScore.Deserialize<List<StudentArt>>();
  508. var valid = results.Valid();
  509. if (!valid.isVaild)
  510. {
  511. return BadRequest(valid);
  512. }
  513. var ids = results.Select(x => $"{school}-{x.studentId}").ToHashSet();
  514. if (ids.Any())
  515. {
  516. List<StudentArtResult> studentArtResults = new List<StudentArtResult>();
  517. string sql = $"SELECT value c FROM c where c.pk='ArtResult' and c.id in ( {string.Join(",", ids.Select(x => $"'{x}'"))} ) ";
  518. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, Constant.Student)
  519. .GetItemQueryIteratorSql<StudentArtResult>(queryText: sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey($"ArtResult-{_artId}") }))
  520. {
  521. studentArtResults.Add(item);
  522. }
  523. studentArtResults.ForEach(x =>
  524. {
  525. var res = results.FindAll(y => $"{school}-{y.studentId}".Equals(x.id));
  526. if (res.Any())
  527. {
  528. if (res[0].subjectScores.IsNotEmpty())
  529. {
  530. res[0].subjectScores.ForEach(z =>
  531. {
  532. var sc = x.subjectScores.Find(s => s.subjectId.Equals(z.subjectId));
  533. if (sc != null)
  534. {
  535. sc.score = z.score;
  536. }
  537. else
  538. {
  539. x.subjectScores.Add(new ArtSubjectScore { subjectId = z.subjectId, score = z.score });
  540. }
  541. });
  542. }
  543. //计算所有科目总分
  544. x.totalScore = Math.Round(x.subjectScores.Where(m => m.score >= 0).Sum(z => z.score), 2);
  545. res[0].results.ForEach(re =>
  546. {
  547. if (string.IsNullOrWhiteSpace(re.taskId))
  548. {
  549. var result = x.results.FindAll(z => string.IsNullOrWhiteSpace(z.taskId) && $"{z.subjectId}".Equals(re.subjectId) && $"{z.quotaId}".Equals(re.quotaId));
  550. if (result.Any())
  551. {
  552. result[0].score = re.score;
  553. }
  554. else
  555. {
  556. }
  557. }
  558. else
  559. {
  560. var result = x.results.FindAll(z => $"{z.taskId}".Equals(re.taskId) && $"{z.subjectId}".Equals(re.subjectId) && $"{z.quotaId}".Equals(re.quotaId));
  561. if (result.Any())
  562. {
  563. result[0].score = re.score;
  564. }
  565. }
  566. });
  567. }
  568. });
  569. List<StudentArtResult> artResults = new List<StudentArtResult>();
  570. ArtEvaluation art = await client.GetContainer(Constant.TEAMModelOS, "Common").ReadItemAsync<ArtEvaluation>($"{_artId}", new PartitionKey($"Art-{school}"));
  571. //科目数量
  572. var scount = art.subjects.Count;
  573. //指标数量
  574. var qcount = art.settings.Count;
  575. //需要进行的打分项
  576. var tcount = scount * qcount;
  577. foreach (var rs in studentArtResults)
  578. {
  579. //已经打分的数量
  580. var rcount = rs.results.Where(z => z.score > -1).Count();
  581. if (rcount == tcount)
  582. {
  583. artResults.Add(rs);
  584. //已经打分的数量等于总的打分项,则发起报告生成。
  585. }
  586. await client.GetContainer(Constant.TEAMModelOS, Constant.Student).ReplaceItemAsync(rs, rs.id, new PartitionKey(rs.code));
  587. }
  588. if (artResults.Any()) {
  589. //先移除自动化生成
  590. // await ArtService.GenArtPDF(artResults.Select(z=>z.studentId).ToList(), $"{_artId}", $"{school}", head_lang, _serviceBus, _configuration);
  591. }
  592. return Ok(new { results = studentArtResults, status = 1 });
  593. }
  594. break;
  595. }
  596. }
  597. }
  598. catch (Exception ex)
  599. {
  600. await _dingDing.SendBotMsg($"{_option.Location},艺术评测审核异常:{ex.Message}\n{ex.StackTrace}\n{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
  601. }
  602. return Ok();
  603. }
  604. }
  605. }