CommonController.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. using Azure.Cosmos;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Microsoft.Extensions.Options;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.IO;
  8. using System.Linq;
  9. using System.Net.Http;
  10. using System.Net.Http.Json;
  11. using System.Text;
  12. using System.Text.Json;
  13. using System.Threading.Tasks;
  14. using TEAMModelFunction;
  15. using TEAMModelOS.Filter;
  16. using TEAMModelOS.Models;
  17. using TEAMModelOS.SDK.DI;
  18. using TEAMModelOS.SDK.Extension;
  19. using TEAMModelOS.SDK.Models;
  20. using TEAMModelOS.SDK.Models.Cosmos.Common;
  21. namespace TEAMModelOS.Controllers.Common
  22. {
  23. [ProducesResponseType(StatusCodes.Status200OK)]
  24. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  25. //[Authorize(Roles = "IES5")
  26. [Route("common")]
  27. [ApiController]
  28. public class CommonController : ControllerBase
  29. {
  30. private readonly AzureCosmosFactory _azureCosmos;
  31. private readonly SnowflakeId _snowflakeId;
  32. private readonly AzureServiceBusFactory _serviceBus;
  33. private readonly DingDing _dingDing;
  34. private readonly Option _option;
  35. private readonly AzureStorageFactory _azureStorage;
  36. private readonly IHttpClientFactory _clientFactory;
  37. public CommonController(AzureCosmosFactory azureCosmos, AzureServiceBusFactory serviceBus, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage, IHttpClientFactory clientFactory)
  38. {
  39. _azureCosmos = azureCosmos;
  40. _serviceBus = serviceBus;
  41. _snowflakeId = snowflakeId;
  42. _dingDing = dingDing;
  43. _option = option?.Value;
  44. _azureStorage = azureStorage;
  45. _clientFactory = clientFactory;
  46. }
  47. [ProducesDefaultResponseType]
  48. // [AuthToken(Roles = "teacher,admin")]
  49. [HttpPost("count-activity")]
  50. public async Task<IActionResult> countActivity(JsonElement element)
  51. {
  52. try
  53. {
  54. List<string> keys = new List<string> { "Vote","Exam", "Survey","Homework","Learn" };
  55. var client = _azureCosmos.GetCosmosClient();
  56. element.TryGetProperty("code", out JsonElement code) ;
  57. element.TryGetProperty("tmdid", out JsonElement tmdid);
  58. Dictionary<string, int> countall = new Dictionary<string, int>();
  59. foreach (var key in keys) {
  60. string queryList = $"select count(1) as countschool from c where c.pk='{key}' ";
  61. if (code.ValueKind.Equals(JsonValueKind.String)) {
  62. var queryschool = $"select count(1) as countschool from c where c.pk='{key}' ";
  63. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(
  64. queryText: queryschool, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{key}-{code}") }))
  65. {
  66. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  67. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  68. {
  69. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  70. {
  71. if (countall.ContainsKey(key.ToLower()))
  72. {
  73. countall[key.ToLower()] = countall[key.ToLower()] + obj.GetProperty("countprivate").GetInt32();
  74. }
  75. else
  76. {
  77. countall.Add(key.ToLower(), obj.GetProperty("countschool").GetInt32());
  78. }
  79. }
  80. }
  81. }
  82. }
  83. if (tmdid.ValueKind.Equals(JsonValueKind.String)) {
  84. var queryprivate = $"select count(1) as countprivate from c where c.pk='{key}' ";
  85. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryStreamIterator(
  86. queryText: queryprivate, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"{key}-{tmdid}") }))
  87. {
  88. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  89. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  90. {
  91. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  92. {
  93. if (countall.ContainsKey(key.ToLower()))
  94. {
  95. countall[key.ToLower()] = countall[key.ToLower()] + obj.GetProperty("countprivate").GetInt32();
  96. }
  97. else
  98. {
  99. countall.Add(key.ToLower(), obj.GetProperty("countprivate").GetInt32());
  100. }
  101. }
  102. }
  103. }
  104. }
  105. }
  106. return Ok(new { countall });
  107. } catch (Exception ex) {
  108. await _dingDing.SendBotMsg($"OS,{_option.Location},common/count-activity\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  109. return BadRequest();
  110. }
  111. }
  112. //立即结束某个活动
  113. [ProducesDefaultResponseType]
  114. // [AuthToken(Roles = "teacher,admin")]
  115. [HttpPost("get-class-info")]
  116. public async Task<IActionResult> GetClassInfo(JsonElement element)
  117. {
  118. //var (id, school) = HttpContext.GetAuthTokenInfo();
  119. try
  120. {
  121. var client = _azureCosmos.GetCosmosClient();
  122. if (!element.TryGetProperty("classes", out JsonElement _classes)) return BadRequest();
  123. if (!element.TryGetProperty("school", out JsonElement _school)) return BadRequest();
  124. List<string> classes = _classes.ToObject<List<string>>();
  125. var classInfos=await TriggerStuActivity.GetClassInfo(client, _dingDing, classes, $"{_school}");
  126. return Ok(new { classInfos ,code = 200 });
  127. }
  128. catch (Exception ex)
  129. {
  130. await _dingDing.SendBotMsg($"OS,{_option.Location},common/get-class-info\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  131. return BadRequest();
  132. }
  133. }
  134. //立即结束某个活动
  135. [ProducesDefaultResponseType]
  136. [AuthToken(Roles = "teacher,admin")]
  137. [HttpPost("finish")]
  138. public async Task<IActionResult> finish(JsonElement element)
  139. {
  140. //var (id, school) = HttpContext.GetAuthTokenInfo();
  141. try
  142. {
  143. if (!element.TryGetProperty("id", out JsonElement id)) return BadRequest();
  144. if (!element.TryGetProperty("code", out JsonElement code)) return BadRequest();
  145. var client = _azureCosmos.GetCosmosClient();
  146. var data = await client.GetContainer("TEAMModelOS", "Common").ReadItemStreamAsync($"{id}", new Azure.Cosmos.PartitionKey($"{code}"));
  147. using var json = await JsonDocument.ParseAsync(data.ContentStream);
  148. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  149. Dictionary<string, object> dy = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(json.RootElement.ToString());
  150. dy["endTime"] = now;
  151. dy["progress"] = "finish";
  152. await client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync<Dictionary<string, object>>(dy, dy["id"].ToString(), new Azure.Cosmos.PartitionKey(dy["code"].ToString()));
  153. var httpClient = _clientFactory.CreateClient();
  154. var content = new { id = $"{id}", code = $"{code}" };
  155. await TriggerStuActivity.RefreshStuActivity(client, _dingDing, $"{id}", $"{code}");
  156. return Ok(new { code=200});
  157. }
  158. catch (Exception ex)
  159. {
  160. await _dingDing.SendBotMsg($"OS,{_option.Location},common/finish\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  161. return BadRequest();
  162. }
  163. }
  164. //更新评测活动size
  165. [ProducesDefaultResponseType]
  166. //[AuthToken(Roles = "teacher,admin")]
  167. [HttpPost("exam-size")]
  168. public async Task<IActionResult> examSize(JsonElement element)
  169. {
  170. //var (id, school) = HttpContext.GetAuthTokenInfo();
  171. try
  172. {
  173. //if (!element.TryGetProperty("id", out JsonElement id)) return BadRequest();
  174. if (!element.TryGetProperty("code", out JsonElement code)) return BadRequest();
  175. var client = _azureCosmos.GetCosmosClient();
  176. List<ExamInfo> examInfo = new();
  177. List<Task<ItemResponse<ExamInfo>>> tasks = new();
  178. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<ExamInfo>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Exam-{code}") }))
  179. {
  180. examInfo.Add(item);
  181. }
  182. foreach (ExamInfo info in examInfo)
  183. {
  184. if (info.size == 0)
  185. {
  186. info.size = await _azureStorage.GetBlobContainerClient(info.school).GetBlobsSize($"exam/{info.id}");
  187. tasks.Add(client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(info, info.id, new PartitionKey($"{info.code}")));
  188. }
  189. }
  190. await Task.WhenAll(tasks);
  191. return Ok();
  192. }
  193. catch (Exception ex)
  194. {
  195. await _dingDing.SendBotMsg($"OS,{_option.Location},common/exam-size\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  196. return BadRequest();
  197. }
  198. }
  199. //更新投票活动size
  200. [ProducesDefaultResponseType]
  201. //[AuthToken(Roles = "teacher,admin")]
  202. [HttpPost("vote-size")]
  203. public async Task<IActionResult> voteSize(JsonElement element)
  204. {
  205. //var (id, school) = HttpContext.GetAuthTokenInfo();
  206. try
  207. {
  208. //if (!element.TryGetProperty("id", out JsonElement id)) return BadRequest();
  209. if (!element.TryGetProperty("code", out JsonElement code)) return BadRequest();
  210. var client = _azureCosmos.GetCosmosClient();
  211. List<Vote> votes = new();
  212. List<Task<ItemResponse<Vote>>> tasks = new();
  213. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<Vote>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Vote-{code}") }))
  214. {
  215. votes.Add(item);
  216. }
  217. foreach (Vote vote in votes)
  218. {
  219. if (vote.size == 0)
  220. {
  221. vote.size = await _azureStorage.GetBlobContainerClient(vote.school).GetBlobsSize($"vote/{vote.id}");
  222. tasks.Add(client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(vote, vote.id, new PartitionKey($"{vote.code}")));
  223. }
  224. }
  225. await Task.WhenAll(tasks);
  226. return Ok();
  227. }
  228. catch (Exception ex)
  229. {
  230. await _dingDing.SendBotMsg($"OS,{_option.Location},common/vote-size\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  231. return BadRequest();
  232. }
  233. }
  234. //更新问卷活动size
  235. [ProducesDefaultResponseType]
  236. //[AuthToken(Roles = "teacher,admin")]
  237. [HttpPost("survey-size")]
  238. public async Task<IActionResult> surveySize(JsonElement element)
  239. {
  240. try
  241. {
  242. //if (!element.TryGetProperty("id", out JsonElement id)) return BadRequest();
  243. if (!element.TryGetProperty("code", out JsonElement code)) return BadRequest();
  244. var client = _azureCosmos.GetCosmosClient();
  245. List<Survey> surveys = new();
  246. List<Task<ItemResponse<Survey>>> tasks = new();
  247. await foreach (var item in client.GetContainer("TEAMModelOS", "Common").GetItemQueryIterator<Survey>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Survey-{code}") }))
  248. {
  249. surveys.Add(item);
  250. }
  251. foreach (Survey survey in surveys)
  252. {
  253. if (survey.size == 0)
  254. {
  255. survey.size = await _azureStorage.GetBlobContainerClient(survey.school).GetBlobsSize($"vote/{survey.id}");
  256. tasks.Add(client.GetContainer("TEAMModelOS", "Common").ReplaceItemAsync(survey, survey.id, new PartitionKey($"{survey.code}")));
  257. }
  258. }
  259. await Task.WhenAll(tasks);
  260. return Ok();
  261. }
  262. catch (Exception ex)
  263. {
  264. await _dingDing.SendBotMsg($"OS,{_option.Location},common/survey-size\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  265. return BadRequest();
  266. }
  267. }
  268. //更新试题库size
  269. [ProducesDefaultResponseType]
  270. //[AuthToken(Roles = "teacher,admin")]
  271. [HttpPost("item-size")]
  272. public async Task<IActionResult> itemSize(JsonElement element)
  273. {
  274. try
  275. {
  276. //if (!element.TryGetProperty("id", out JsonElement id)) return BadRequest();
  277. if (!element.TryGetProperty("code", out JsonElement code)) return BadRequest();
  278. var client = _azureCosmos.GetCosmosClient();
  279. List<ItemInfo> items = new();
  280. List<Task<ItemResponse<ItemInfo>>> tasks = new();
  281. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<ItemInfo>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Item-{code}") }))
  282. {
  283. items.Add(item);
  284. }
  285. foreach (ItemInfo info in items)
  286. {
  287. if (info.size == 0)
  288. {
  289. info.size = await _azureStorage.GetBlobContainerClient(code.ToString()).GetBlobsSize($"item/{info.id}");
  290. tasks.Add(client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(info, info.id, new PartitionKey($"{info.code}")));
  291. }
  292. }
  293. await Task.WhenAll(tasks);
  294. return Ok();
  295. }
  296. catch (Exception ex)
  297. {
  298. await _dingDing.SendBotMsg($"OS,{_option.Location},common/item-size\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  299. return BadRequest();
  300. }
  301. }
  302. //更新试卷库size
  303. [ProducesDefaultResponseType]
  304. //[AuthToken(Roles = "teacher,admin")]
  305. [HttpPost("paper-size")]
  306. public async Task<IActionResult> paperSize(JsonElement element)
  307. {
  308. try
  309. {
  310. //if (!element.TryGetProperty("id", out JsonElement id)) return BadRequest();
  311. if (!element.TryGetProperty("code", out JsonElement code)) return BadRequest();
  312. var client = _azureCosmos.GetCosmosClient();
  313. List<Paper> papers = new();
  314. List<Task<ItemResponse<Paper>>> tasks = new();
  315. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Paper>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Paper-{code}") }))
  316. {
  317. papers.Add(item);
  318. }
  319. foreach (Paper paper in papers)
  320. {
  321. if (paper.size == 0)
  322. {
  323. paper.size = await _azureStorage.GetBlobContainerClient(code.ToString()).GetBlobsSize($"paper/{paper.name}");
  324. tasks.Add(client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(paper, paper.id, new PartitionKey($"{paper.code}")));
  325. }
  326. }
  327. await Task.WhenAll(tasks);
  328. return Ok();
  329. }
  330. catch (Exception ex)
  331. {
  332. await _dingDing.SendBotMsg($"OS,{_option.Location},common/paper-size\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  333. return BadRequest();
  334. }
  335. }
  336. /// <summary>
  337. ///
  338. /// </summary>
  339. /// <param name="element"></param>
  340. /// <returns></returns>
  341. [ProducesDefaultResponseType]
  342. [HttpPost("delete-activity")]
  343. [AuthToken(Roles = "teacher,admin,student")]
  344. public async Task<IActionResult> DeleteActivity(JsonElement element) {
  345. try {
  346. if (!element.TryGetProperty("id", out JsonElement id)) return BadRequest();
  347. if (!element.TryGetProperty("code", out JsonElement code)) return BadRequest();
  348. if (!element.TryGetProperty("role", out JsonElement role)) return BadRequest();
  349. var client = _azureCosmos.GetCosmosClient();
  350. if (role.ValueKind.Equals(JsonValueKind.String))
  351. {
  352. if (role.GetString().Equals("teacher") || role.GetString().Equals("admin"))
  353. {
  354. await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemAsync<StuActivity>($"{id}", new PartitionKey($"{code}"));
  355. }
  356. else if (role.GetString().Equals("student"))
  357. {
  358. await client.GetContainer("TEAMModelOS", "Student").DeleteItemAsync<StuActivity>($"{id}", new PartitionKey($"{code}"));
  359. }
  360. else
  361. {
  362. return Ok(new { status = 500 });
  363. }
  364. }
  365. else {
  366. return Ok(new { status = 500 });
  367. }
  368. return Ok(new { status = 200 });
  369. } catch (Exception ex) {
  370. await _dingDing.SendBotMsg($"OS,{_option.Location},common/delete-activity\n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  371. return Ok(new { status = 500 });
  372. }
  373. }
  374. }
  375. }