SyllabusController.cs 20 KB

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