SyllabusController.cs 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  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;
  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. if (!string.IsNullOrEmpty(syllabusTree.id))
  118. {
  119. Syllabus syllabus = null;
  120. if (syllabusTree.scope == "school")
  121. {
  122. try
  123. {
  124. syllabus = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReadItemAsync<Syllabus>(syllabusTree.id, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  125. }
  126. catch
  127. {
  128. }
  129. if (syllabus == null)
  130. {
  131. if (syllabusTree.trees.IsNotEmpty())
  132. {
  133. syllabusTree.trees.ForEach(x => x.id = syllabusTree.id);
  134. }
  135. List<Tnode> nodes = new List<Tnode>();
  136. SyllabusService.TreeToList(syllabusTree.trees, nodes, now);
  137. syllabus = new Syllabus();
  138. syllabus.id = syllabusTree.id;
  139. syllabus.children = nodes;
  140. syllabus.code = $"Syllabus-{syllabusTree.codeval}";
  141. syllabus.pk = "Syllabus";
  142. syllabus.ttl = -1;
  143. syllabus.volumeId = syllabusTree.volumeId;
  144. syllabus.scope = syllabusTree.scope;
  145. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  146. }
  147. else
  148. {
  149. if (syllabusTree.trees.IsNotEmpty())
  150. {
  151. syllabusTree.trees.ForEach(x => x.id = syllabusTree.id);
  152. }
  153. List<Tnode> nodes = new List<Tnode>();
  154. SyllabusService.TreeToList(syllabusTree.trees, nodes, now);
  155. syllabus.children = nodes;
  156. syllabusTree.auth = syllabus.auth;
  157. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").ReplaceItemAsync<Syllabus>(syllabus,syllabus.id, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  158. }
  159. }
  160. else {
  161. try
  162. {
  163. syllabus = await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Syllabus>(syllabusTree.id, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  164. }
  165. catch
  166. {
  167. }
  168. if (syllabus == null)
  169. {
  170. if (syllabusTree.trees.IsNotEmpty()) {
  171. syllabusTree.trees.ForEach(x => x.id = syllabusTree.id);
  172. }
  173. List<Tnode> nodes = new List<Tnode>();
  174. SyllabusService.TreeToList(syllabusTree.trees, nodes, now);
  175. syllabus = new Syllabus();
  176. syllabus.id = syllabusTree.id;
  177. syllabus.children = nodes;
  178. syllabus.code = $"Syllabus-{syllabusTree.codeval}";
  179. syllabus.pk = "Syllabus";
  180. syllabus.ttl = -1;
  181. syllabus.volumeId = syllabusTree.volumeId;
  182. syllabus.scope = syllabusTree.scope;
  183. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  184. }
  185. else
  186. {
  187. if (syllabusTree.trees.IsNotEmpty())
  188. {
  189. syllabusTree.trees.ForEach(x => x.id = syllabusTree.id);
  190. }
  191. List<Tnode> nodes = new List<Tnode>();
  192. SyllabusService.TreeToList(syllabusTree.trees, nodes, now);
  193. syllabus.children = nodes;
  194. syllabusTree.auth = syllabus.auth;
  195. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").UpsertItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  196. }
  197. }
  198. }
  199. else {
  200. string id = Guid.NewGuid().ToString();
  201. syllabusTree.id = id;
  202. if (syllabusTree.trees.IsNotEmpty())
  203. {
  204. syllabusTree.trees.ForEach(x => x.id = syllabusTree.id);
  205. }
  206. List<Tnode> nodes = new List<Tnode>();
  207. SyllabusService.TreeToList(syllabusTree.trees, nodes, now);
  208. Syllabus syllabus = new Syllabus {
  209. id = id,
  210. code = $"Syllabus-{syllabusTree.codeval}",
  211. pk = "Syllabus",
  212. ttl = -1,
  213. volumeId=syllabusTree.volumeId,
  214. children=nodes,
  215. scope = syllabusTree.scope
  216. };
  217. if (syllabusTree.scope == "school") {
  218. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "School").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  219. } else {
  220. await _azureCosmos.GetCosmosClient().GetContainer("TEAMModelOS", "Teacher").CreateItemAsync<Syllabus>(syllabus, new Azure.Cosmos.PartitionKey($"Syllabus-{syllabusTree.codeval}"));
  221. }
  222. }
  223. }
  224. return Ok(request);
  225. }
  226. /*
  227. {"volumeId":"册别id:0baf00db-0768-4b62-a8f7-280f6bcebf71","scope":"school","volumeCode":"册别分区键"}
  228. */
  229. /// <summary>
  230. /// 查找课纲
  231. /// </summary>
  232. /// <param name="request"></param>
  233. /// <returns></returns>
  234. [ProducesDefaultResponseType]
  235. [HttpPost("find-id")]
  236. public async Task<IActionResult> Find(JsonElement request)
  237. {
  238. var client = _azureCosmos.GetCosmosClient();
  239. if (!request.TryGetProperty("volumeId", out JsonElement volumeId)) return BadRequest();
  240. if (!request.TryGetProperty("volumeCode", out JsonElement volumeCode)) return BadRequest();
  241. if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  242. Volume volume = null;
  243. List<SyllabusTreeNode> treeNodes = new List<SyllabusTreeNode>();
  244. List<SyllabusTreeNode> redt = new List<SyllabusTreeNode>();
  245. try {
  246. if (scope.ToString().Equals("school"))
  247. {
  248. volume = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Volume>($"{volumeId}", new PartitionKey($"{volumeCode}"));
  249. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<Syllabus>(queryText: $"select value(c) from c where c.volumeId='{volumeId}'",
  250. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Syllabus-{volume.school}") }))
  251. {
  252. List<SyllabusTree> trees = SyllabusService.ListToTree(item.children);
  253. SyllabusTreeNode tree = new SyllabusTreeNode() { id = item.id, scope =item.scope, trees = trees ,volumeId=item.volumeId,auth=item.auth,codeval=volume.school};
  254. treeNodes.Add(tree);
  255. }
  256. }
  257. else
  258. {
  259. volume = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Volume>($"{volumeId}", new PartitionKey($"{volumeCode}"));
  260. await foreach (var item in client.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Syllabus>(queryText: $"select value(c) from c where c.volumeId='{volumeId}'",
  261. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Syllabus-{volume.creatorId}") }))
  262. {
  263. List<SyllabusTree> trees = SyllabusService.ListToTree(item.children);
  264. SyllabusTreeNode tree = new SyllabusTreeNode() { id = item.id, scope = item.scope, trees = trees, volumeId = item.volumeId, auth = item.auth,codeval=volume.creatorId };
  265. treeNodes.Add(tree);
  266. }
  267. }
  268. //对课纲树形结构排序
  269. if (volume.syllabusIds.IsNotEmpty())
  270. {
  271. volume.syllabusIds.ForEach(x =>
  272. {
  273. for (int index = 0; index < treeNodes.Count; index++)
  274. {
  275. if (treeNodes[index].id == x)
  276. {
  277. redt.Add(treeNodes[index]);
  278. treeNodes.RemoveAt(index);
  279. }
  280. }
  281. });
  282. redt.AddRange(treeNodes);
  283. return Ok(new { tree = redt });
  284. }
  285. else {
  286. return Ok(new { tree = treeNodes });
  287. }
  288. } catch (Exception ex) {
  289. await _dingDing.SendBotMsg($"OS,{_option.Location},common/syllabus/find-id\n{ex.Message}{ex.StackTrace}", GroupNames.成都开发測試群組);
  290. return Ok(new { tree= treeNodes });
  291. }
  292. }
  293. /*
  294. {"id":"章节id","code":"学校编码/醍摩豆id","scope":"school/private"}
  295. */
  296. /// <summary>
  297. /// 删除章节
  298. /// </summary>
  299. /// <param name="request"></param>
  300. /// <returns></returns>
  301. [ProducesDefaultResponseType]
  302. [HttpPost("delete")]
  303. public async Task<IActionResult> Delete(JsonElement request)
  304. {
  305. try
  306. {
  307. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  308. if (!request.TryGetProperty("code", out JsonElement code)) return BadRequest();
  309. if (!request.TryGetProperty("scope", out JsonElement scope)) return BadRequest();
  310. var client = _azureCosmos.GetCosmosClient();
  311. if (scope.ToString().Equals("school"))
  312. {
  313. Syllabus syllabus = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<Syllabus>(id.ToString(), new PartitionKey($"Syllabus-{code}"));
  314. if (syllabus.auth.IsNotEmpty()) {
  315. foreach (var a in syllabus.auth)
  316. {
  317. try
  318. {
  319. Share share = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Share>(syllabus.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  320. share.agree = -1;
  321. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Share>(share, syllabus.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  322. }
  323. catch (Exception ex)
  324. {
  325. ///仅用于处理查不到该数据的问题
  326. }
  327. }
  328. }
  329. var response = await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Syllabus-{code}"));
  330. return Ok(new { code = response.Status });
  331. }
  332. else
  333. {
  334. Syllabus syllabus = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Syllabus>(id.ToString(), new PartitionKey($"Syllabus-{code}"));
  335. if (syllabus.auth.IsNotEmpty())
  336. {
  337. foreach (var a in syllabus.auth)
  338. {
  339. try
  340. {
  341. Share share = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Share>(syllabus.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  342. share.agree = -1;
  343. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Share>(share, syllabus.id, new PartitionKey($"Share-{a.type}-{a.tmdid}"));
  344. }
  345. catch (Exception ex)
  346. {
  347. ///仅用于处理查不到该数据的问题
  348. }
  349. }
  350. }
  351. var response = await client.GetContainer("TEAMModelOS", "Teacher").DeleteItemStreamAsync(id.ToString(), new PartitionKey($"Syllabus-{code}"));
  352. return Ok(new { code = response.Status });
  353. }
  354. }
  355. catch {
  356. return Ok(new { code = 404});
  357. }
  358. }
  359. }
  360. }