SyllabusController.cs 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. using Microsoft.AspNetCore.Mvc;
  2. using System.Collections.Generic;
  3. using System.Threading.Tasks;
  4. using TEAMModelOS.SDK;
  5. using TEAMModelOS.SDK.DI;
  6. using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
  7. using System;
  8. using TEAMModelOS.SDK.Helper.Common.JsonHelper;
  9. using System.Linq;
  10. using TEAMModelOS.Models;
  11. using System.Text.Json;
  12. using TEAMModelOS.SDK.Extension;
  13. using TEAMModelOS.SDK.Models;
  14. using Microsoft.AspNetCore.Http;
  15. using TEAMModelOS.SDK.Models.Cosmos.Common;
  16. using Azure.Cosmos;
  17. using TEAMModelOS.Services.Common;
  18. using Microsoft.Extensions.Options;
  19. using System.Text;
  20. namespace TEAMModelOS.Controllers
  21. {
  22. [ProducesResponseType(StatusCodes.Status200OK)]
  23. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  24. //[Authorize(Roles = "IES5")]
  25. [Route("common/syllabus")]
  26. [ApiController]
  27. //[Authorize]
  28. public class SyllabusController : ControllerBase
  29. {
  30. private readonly AzureCosmosFactory _azureCosmos;
  31. private readonly Option _option;
  32. private readonly DingDing _dingDing;
  33. public SyllabusController(AzureCosmosFactory azureCosmos, DingDing dingDing, IOptionsSnapshot<Option> option)
  34. {
  35. _azureCosmos = azureCosmos;
  36. _dingDing = dingDing;
  37. _option = option?.Value;
  38. }
  39. /// <summary>
  40. /// 检查资源链接是否被其他结构关联
  41. ///
  42. /// </summary>
  43. /// <param name="request"></param>
  44. /// <returns></returns>
  45. [ProducesDefaultResponseType]
  46. [HttpPost("check-link")]
  47. public async Task<IActionResult> CheckLink(JsonElement request) {
  48. if (!request.TryGetProperty("links", out JsonElement _links)) return BadRequest();
  49. if (!request.TryGetProperty("code", out JsonElement _code)) return BadRequest();
  50. if (!request.TryGetProperty("scope", out JsonElement _scope)) return BadRequest();
  51. if (_code.ValueKind.Equals(JsonValueKind.String) && _links.ValueKind.Equals(JsonValueKind.Array))
  52. {
  53. List<LinkDto> links = new List<LinkDto>();
  54. List<string>list= _links.ToObject<List<string>>();
  55. var client = _azureCosmos.GetCosmosClient();
  56. list= list.Select(x => $"'{x}'").ToList();
  57. string lks= string.Join(",", list);
  58. StringBuilder queryText = new StringBuilder($"SELECT c.id as syllabusId,c.volumeId,rnodes.link ,children.id as treeid FROM c join children in c.children join rnodes in children.rnodes where rnodes.link in ({lks}) ");
  59. if (_scope.ValueKind.Equals(JsonValueKind.String) && _scope.GetString() == "school")
  60. {
  61. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<LinkDto>(queryText: queryText.ToString(),
  62. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Syllabus-{_code}") }))
  63. {
  64. links.Add(item);
  65. }
  66. }
  67. else if (_scope.ValueKind.Equals(JsonValueKind.String) && _scope.GetString() == "private") {
  68. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<LinkDto>(queryText: queryText.ToString(),
  69. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Syllabus-{_code}") }))
  70. {
  71. links.Add(item);
  72. }
  73. }
  74. var count= links.GroupBy(x => x.link).Select(y=>new { key= y.Key,count=y.ToList().Count});
  75. return Ok(new { count , links });
  76. }
  77. else {
  78. return BadRequest();
  79. }
  80. }
  81. public class LinkDto{
  82. public string syllabusId { get; set; }
  83. public string volumeId { get; set; }
  84. public string link { get; set; }
  85. public string treeid { get; set; }
  86. }
  87. /*
  88. [
  89. {
  90. "id": "章节id",
  91. "volumeId": "册别id",
  92. "scope": "school",
  93. "trees": [
  94. {
  95. "id": "b2b15c99-83cc-eca7-5b4b-e58d2a457c8e",
  96. "pid": "0baf00db-0768-4b62-a8f7-280f6bcebf71",
  97. "title": "第一单元",
  98. "type": 1,
  99. "children": []
  100. }
  101. ]
  102. }
  103. ]
  104. */
  105. /// <summary>
  106. /// 批量保存或更新课纲
  107. ///
  108. /// </summary>
  109. /// <param name="request"></param>
  110. /// <returns></returns>
  111. [ProducesDefaultResponseType]
  112. [HttpPost("upsert-tree")]
  113. public async Task<IActionResult> SaveOrUpdateAsTree(List<SyllabusTreeNode> request)
  114. {
  115. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  116. foreach (SyllabusTreeNode syllabusTree in request) {
  117. List<Tnode> nodes = new List<Tnode>();
  118. SyllabusService.TreeToList(syllabusTree.trees, nodes, now);
  119. if (!string.IsNullOrEmpty(syllabusTree.id))
  120. {
  121. Syllabus syllabus = null;
  122. if (syllabusTree.scope == "school")
  123. {
  124. try
  125. {
  126. syllabus = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReadItemAsync<Syllabus>(syllabusTree.id, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  127. }
  128. catch
  129. {
  130. }
  131. if (syllabus == null)
  132. {
  133. syllabus = new Syllabus();
  134. syllabus.id = syllabusTree.id;
  135. syllabus.children = nodes;
  136. syllabus.code = $"Syllabus-{syllabusTree.codeval}";
  137. syllabus.pk = "Syllabus";
  138. syllabus.ttl = -1;
  139. syllabus.volumeId = syllabusTree.volumeId;
  140. syllabus.scope = syllabusTree.scope;
  141. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  142. }
  143. else
  144. {
  145. syllabus.children = nodes;
  146. syllabusTree.auth = syllabus.auth;
  147. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Syllabus>(syllabus,syllabus.id, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  148. }
  149. }
  150. else {
  151. try
  152. {
  153. syllabus = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Syllabus>(syllabusTree.id, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  154. }
  155. catch
  156. {
  157. }
  158. if (syllabus == null)
  159. {
  160. syllabus = new Syllabus();
  161. syllabus.id = syllabusTree.id;
  162. syllabus.children = nodes;
  163. syllabus.code = $"Syllabus-{syllabusTree.codeval}";
  164. syllabus.pk = "Syllabus";
  165. syllabus.ttl = -1;
  166. syllabus.volumeId = syllabusTree.volumeId;
  167. syllabus.scope = syllabusTree.scope;
  168. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  169. }
  170. else
  171. {
  172. syllabus.children = nodes;
  173. syllabusTree.auth = syllabus.auth;
  174. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  175. }
  176. }
  177. }
  178. else {
  179. string id = Guid.NewGuid().ToString();
  180. syllabusTree.id = id;
  181. Syllabus syllabus = new Syllabus {
  182. id = id,
  183. code = $"Syllabus-{syllabusTree.codeval}",
  184. pk = "Syllabus",
  185. ttl = -1,
  186. volumeId=syllabusTree.volumeId,
  187. children=nodes,
  188. scope = syllabusTree.scope
  189. };
  190. if (syllabusTree.scope == "school") {
  191. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  192. } else {
  193. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  194. }
  195. }
  196. }
  197. return Ok(request);
  198. }
  199. /*
  200. {"volumeId":"册别id:0baf00db-0768-4b62-a8f7-280f6bcebf71","scope":"school","volumeCode":"册别分区键"}
  201. */
  202. /// <summary>
  203. /// 查找课纲
  204. /// </summary>
  205. /// <param name="request"></param>
  206. /// <returns></returns>
  207. [ProducesDefaultResponseType]
  208. [HttpPost("find-id")]
  209. public async Task<IActionResult> Find(JsonElement request)
  210. {
  211. var client = _azureCosmos.GetCosmosClient();
  212. if (!request.TryGetProperty("volumeId", out JsonElement volumeId)) return BadRequest();
  213. if (!request.TryGetProperty("volumeCode", out JsonElement volumeCode)) return BadRequest();
  214. if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  215. Volume volume = null;
  216. List<SyllabusTreeNode> treeNodes = new List<SyllabusTreeNode>();
  217. List<SyllabusTreeNode> redt = new List<SyllabusTreeNode>();
  218. try {
  219. if (scope.ToString().Equals("school"))
  220. {
  221. volume = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Volume>($"{volumeId}", new PartitionKey($"{volumeCode}"));
  222. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Syllabus>(queryText: $"select value(c) from c where c.volumeId='{volumeId}'",
  223. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Syllabus-{volume.school}") }))
  224. {
  225. List<SyllabusTree> trees = SyllabusService.ListToTree(item.children);
  226. SyllabusTreeNode tree = new SyllabusTreeNode() { id = item.id, scope =item.scope, trees = trees ,volumeId=item.volumeId,auth=item.auth,codeval=volume.school};
  227. treeNodes.Add(tree);
  228. }
  229. }
  230. else
  231. {
  232. volume = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Volume>($"{volumeId}", new PartitionKey($"{volumeCode}"));
  233. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Syllabus>(queryText: $"select value(c) from c where c.volumeId='{volumeId}'",
  234. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Syllabus-{volume.creatorId}") }))
  235. {
  236. List<SyllabusTree> trees = SyllabusService.ListToTree(item.children);
  237. SyllabusTreeNode tree = new SyllabusTreeNode() { id = item.id, scope = item.scope, trees = trees, volumeId = item.volumeId, auth = item.auth,codeval=volume.creatorId };
  238. treeNodes.Add(tree);
  239. }
  240. }
  241. //对课纲树形结构排序
  242. if (volume.syllabusIds.IsNotEmpty())
  243. {
  244. volume.syllabusIds.ForEach(x =>
  245. {
  246. for (int index = 0; index < treeNodes.Count; index++)
  247. {
  248. if (treeNodes[index].id == x)
  249. {
  250. redt.Add(treeNodes[index]);
  251. treeNodes.RemoveAt(index);
  252. }
  253. }
  254. });
  255. redt.AddRange(treeNodes);
  256. return Ok(new { tree = redt });
  257. }
  258. else {
  259. return Ok(new { tree = treeNodes });
  260. }
  261. } catch (Exception ex) {
  262. await _dingDing.SendBotMsg($"OS,{_option.Location},common/syllabus/find-id\n{ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
  263. return Ok(new { tree= treeNodes });
  264. }
  265. }
  266. /*
  267. {"id":"章节id","code":"学校编码/醍摩豆id","scope":"school/private"}
  268. */
  269. /// <summary>
  270. /// 删除章节
  271. /// </summary>
  272. /// <param name="request"></param>
  273. /// <returns></returns>
  274. [ProducesDefaultResponseType]
  275. [HttpPost("delete")]
  276. public async Task<IActionResult> Delete(JsonElement request)
  277. {
  278. try
  279. {
  280. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  281. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  282. if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  283. var client = _azureCosmos.GetCosmosClient();
  284. if (scope.ToString().Equals("school"))
  285. {
  286. Syllabus syllabus = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Syllabus>(id.ToString(), new PartitionKey($"Syllabus-{code}"));
  287. if (syllabus.auth.IsNotEmpty()) {
  288. foreach (var a in syllabus.auth)
  289. {
  290. try
  291. {
  292. Share share = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Share>(syllabus.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  293. share.agree = -1;
  294. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Share>(share, syllabus.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  295. }
  296. catch (Exception ex)
  297. {
  298. ///仅用于处理查不到该数据的问题
  299. }
  300. }
  301. }
  302. var response = await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Syllabus-{code}"));
  303. return Ok(new { code = response.Status });
  304. }
  305. else
  306. {
  307. Syllabus syllabus = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Syllabus>(id.ToString(), new PartitionKey($"Syllabus-{code}"));
  308. if (syllabus.auth.IsNotEmpty())
  309. {
  310. foreach (var a in syllabus.auth)
  311. {
  312. try
  313. {
  314. Share share = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Share>(syllabus.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  315. share.agree = -1;
  316. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Share>(share, syllabus.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  317. }
  318. catch (Exception ex)
  319. {
  320. ///仅用于处理查不到该数据的问题
  321. }
  322. }
  323. }
  324. var response = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Syllabus-{code}"));
  325. return Ok(new { code = response.Status });
  326. }
  327. }
  328. catch {
  329. return Ok(new { code = 404});
  330. }
  331. }
  332. }
  333. }