ShareController.cs 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610
  1. using Azure.Cosmos;
  2. using HTEXLib.COMM.Helpers;
  3. using Microsoft.AspNetCore.Authorization;
  4. using Microsoft.AspNetCore.Http;
  5. using Microsoft.AspNetCore.Mvc;
  6. using Microsoft.Extensions.Configuration;
  7. using Microsoft.Extensions.Options;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Text;
  12. using System.Text.Json;
  13. using System.Threading.Tasks;
  14. using TEAMModelOS.Filter;
  15. using TEAMModelOS.Models;
  16. using TEAMModelOS.SDK.DI;
  17. using TEAMModelOS.SDK.Extension;
  18. using TEAMModelOS.SDK.Models;
  19. using TEAMModelOS.SDK.Models.Cosmos;
  20. using TEAMModelOS.SDK.Models.Cosmos.Common;
  21. using TEAMModelOS.SDK.Models.Service;
  22. using TEAMModelOS.SDK.Services;
  23. namespace TEAMModelOS.Controllers
  24. {
  25. [ProducesResponseType(StatusCodes.Status200OK)]
  26. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  27. [Route("teacher/share")]
  28. [ApiController]
  29. public class ShareController : ControllerBase
  30. {
  31. private readonly AzureCosmosFactory _azureCosmos;
  32. private readonly SnowflakeId _snowflakeId;
  33. private readonly DingDing _dingDing;
  34. private readonly Option _option;
  35. private readonly IConfiguration _configuration;
  36. private readonly NotificationService _notificationService;
  37. public ShareController(AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, IConfiguration configuration, NotificationService notificationService)
  38. {
  39. _azureCosmos = azureCosmos;
  40. _snowflakeId = snowflakeId;
  41. _dingDing = dingDing;
  42. _option = option?.Value;
  43. _configuration = configuration;
  44. _notificationService = notificationService;
  45. }
  46. /*
  47. {
  48. "school": "学校编码",
  49. "scope":"school|private",
  50. "tmdInfo":["tmdid":"id1","tmdname":"name1"],
  51. "type":"coedit共编,share分享",
  52. "agree":0,1,
  53. "issuer":"权限颁发者tmdid",
  54. "opt":"add/del/edit"
  55. "syllabusId":"分享的课纲章节id",
  56. "syllabusName":"章节名称",
  57. "volumeId":"册别id",
  58. "volumeName":"册别name"
  59. }
  60. */
  61. /// <summary>
  62. /// 分享及邀请共编,并设置TTL过期时间
  63. /// </summary>
  64. /// <param name="request"></param>
  65. /// <returns></returns>
  66. [ProducesDefaultResponseType]
  67. [HttpPost("to")]
  68. [Authorize(Roles = "IES")]
  69. [AuthToken(Roles = "teacher,admin")]
  70. public async Task<IActionResult> To(ShareData request)
  71. {
  72. // var (id, _, _, _) = HttpContext.GetAuthTokenInfo();
  73. try
  74. {
  75. var client = _azureCosmos.GetCosmosClient();
  76. //需要判断id== req.issuer 才能进行授权操作
  77. if (request.scope.Equals("school"))
  78. {
  79. if (request.syllabus.IsNotEmpty())
  80. {
  81. foreach (var quest in request.syllabus)
  82. {
  83. Syllabus syllabusD = null;
  84. try
  85. {
  86. syllabusD = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<Syllabus>(quest.syllabusId, new PartitionKey($"Syllabus-{request.school}"));
  87. }
  88. catch (CosmosException ex)
  89. {
  90. if (ex.Status == 404)
  91. {
  92. await _dingDing.SendBotMsg($"OS,{_option.Location},teacher/share/to\n{ex.Message}\n{ex.StackTrace}{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
  93. return Ok(new { code = 404 });
  94. }
  95. }
  96. if (request.opt.Equals("del"))
  97. {
  98. if (syllabusD.auth.IsNotEmpty())
  99. {
  100. List<SyllabusAuth> syllabusAuths = new List<SyllabusAuth>();
  101. syllabusD.auth.ForEach(x => {
  102. if (request.tmdInfo.Select(tmd => tmd.tmdid).Contains(x.tmdid))
  103. {
  104. syllabusAuths.Add(x);
  105. }
  106. });
  107. syllabusAuths.ForEach(x => {
  108. syllabusD.auth.Remove(x);
  109. });
  110. await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<Syllabus>(syllabusD, quest.syllabusId, new PartitionKey($"Syllabus-{request.school}"));
  111. request.tmdInfo.ForEach(async x => {
  112. await client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemAsync<Share>(quest.syllabusId, new PartitionKey($"Share-{request.type}-{x.tmdid}"));
  113. });
  114. }
  115. }
  116. else if (request.opt.Equals("add") || request.opt.Equals("edit"))
  117. {
  118. var schresponse = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(request.school.ToString(), new PartitionKey("Base"));
  119. string schname = string.Empty;
  120. if (schresponse.Status == 200)
  121. {
  122. using var schjson = await JsonDocument.ParseAsync(schresponse.ContentStream);
  123. schjson.RootElement.TryGetProperty("name", out JsonElement jsonschname);
  124. schname = jsonschname.ToString();
  125. }
  126. else
  127. {
  128. return BadRequest();
  129. }
  130. (Syllabus syllabus, List<Share> shares) = DoAuth(request, syllabusD);
  131. foreach (var x in shares)
  132. {
  133. await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<Share>(x, new PartitionKey($"{x.code}"));
  134. //发送共编或分享通知
  135. string to = x.code.Replace("Share-", "").Replace($"{x.type}-", "");
  136. //如果被邀请人与邀请人相同 则不发通知。
  137. if (to.Equals(x.issuer))
  138. {
  139. continue;
  140. }
  141. Notification notification = new Notification
  142. {
  143. hubName = "hita",
  144. type = "msg",
  145. from = $"ies5:{_option.Location}:{request.school}",
  146. to = new List<string>() { x.code.Replace("Share-", "").Replace($"{x.type}-", "") },
  147. label = $"{x.type}_syllabus",
  148. body = new {
  149. location = _option.Location,
  150. biz = x.type,
  151. tmdid = x.issuer,
  152. tmdname = x.issuerName,
  153. schoolcode = $"{request.school}",
  154. schoolname = $"{schname}",
  155. sid = x.id,
  156. sname = x.syllabusName,
  157. vid = x.volumeId,
  158. vname = x.volumeName,
  159. status = 1,
  160. time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
  161. }.ToJsonString(),
  162. expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
  163. };
  164. var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
  165. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  166. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  167. var location = _option.Location;
  168. var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
  169. }
  170. await client.GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync<Syllabus>(syllabus, new PartitionKey($"Syllabus-{request.school}"));
  171. }
  172. }
  173. }
  174. }
  175. else if (request.scope.Equals("private"))
  176. {
  177. if (request.syllabus.IsNotEmpty())
  178. {
  179. foreach (var quest in request.syllabus)
  180. {
  181. Syllabus syllabusD = null;
  182. try
  183. {
  184. syllabusD = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Syllabus>(quest.syllabusId, new PartitionKey($"Syllabus-{request.issuer}"));
  185. }
  186. catch (CosmosException ex)
  187. {
  188. if (ex.Status == 404)
  189. {
  190. await _dingDing.SendBotMsg($"OS,{_option.Location},teacher/share/to\n{ex.Message}\n{ex.StackTrace}{request.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
  191. return Ok(new { code = 404 });
  192. }
  193. }
  194. if (request.opt.Equals("del"))
  195. {
  196. if (syllabusD.auth.IsNotEmpty())
  197. {
  198. List<SyllabusAuth> syllabusAuths = new List<SyllabusAuth>();
  199. syllabusD.auth.ForEach(x => {
  200. if (request.tmdInfo.Select(tmd => x.tmdid).Contains(x.tmdid))
  201. {
  202. syllabusAuths.Add(x);
  203. }
  204. });
  205. syllabusAuths.ForEach(x => {
  206. syllabusD.auth.Remove(x);
  207. });
  208. await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Syllabus>(syllabusD, quest.syllabusId, new PartitionKey($"Syllabus-{request.issuer}"));
  209. request.tmdInfo.ForEach(async x => {
  210. try
  211. {
  212. await client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemAsync<Share>(quest.syllabusId, new PartitionKey($"Share-{request.type}-{x.tmdid}"));
  213. }
  214. catch
  215. {
  216. //仅处理找不到数据的情况
  217. }
  218. });
  219. }
  220. }
  221. else if (request.opt.Equals("add") || request.opt.Equals("edit"))
  222. {
  223. (Syllabus vlm, List<Share> shares) = DoAuth(request, syllabusD);
  224. foreach (var x in shares)
  225. {
  226. await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<Share>(x, new PartitionKey($"{x.code}"));
  227. //发送共编或分享通知
  228. string to = x.code.Replace("Share-", "").Replace($"{x.type}-", "");
  229. //如果被邀请人与邀请人相同 则不发通知。
  230. if (to.Equals(x.issuer))
  231. {
  232. continue;
  233. }
  234. Notification notification = new Notification
  235. {
  236. hubName = "hita",
  237. type = "msg",
  238. from = $"ies5:{_option.Location}:private",
  239. to = new List<string>() { x.code.Replace("Share-", "").Replace($"{x.type}-", "") },
  240. label = $"{x.type}_syllabus",
  241. body = new { location = _option.Location, biz = x.type, tmdid = x.issuer, tmdname = x.issuerName, sid = x.id, sname = x.syllabusName, vid = x.volumeId, vname = x.volumeName, status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
  242. expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
  243. };
  244. var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
  245. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  246. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  247. var location = _option.Location;
  248. var code = await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);
  249. }
  250. await client.GetContainer(Constant.TEAMModelOS, "Teacher").UpsertItemAsync<Syllabus>(syllabusD, new PartitionKey($"Syllabus-{request.issuer}"));
  251. }
  252. }
  253. }
  254. }
  255. return Ok(new { code = 200 });
  256. }
  257. catch (Exception ex)
  258. {
  259. await _dingDing.SendBotMsg($"OS,{_option.Location},teacher/share/to\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  260. }
  261. return Ok(new { code = 500 });
  262. }
  263. private (Syllabus, List<Share>) DoAuth(ShareData request, Syllabus syllabus)
  264. {
  265. long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  266. List<Share> shares = new List<Share>();
  267. request.tmdInfo.ForEach(xmd => {
  268. request.syllabus.ForEach(sbs => {
  269. var share = new Share
  270. {
  271. id = sbs.syllabusId,
  272. volumeId = request.volumeId,
  273. volumeName = request.volumeName,
  274. syllabusName = sbs.syllabusName,
  275. code = $"Share-{request.type}-{xmd.tmdid}",
  276. pk = "Share",
  277. ttl = -1,
  278. issuer = request.issuer,
  279. issuerName = request.issuerName,
  280. createTime = now,
  281. school = request.school,
  282. scope = request.scope,
  283. type = request.type,
  284. agree = request.agree,
  285. volumeAll = request.volumeAll,
  286. };
  287. shares.Add(share);
  288. });
  289. });
  290. if (syllabus.auth.IsNotEmpty())
  291. {
  292. request.tmdInfo.ForEach(xmd => {
  293. bool flag = false;
  294. int indx = 0;
  295. for (int index = 0; index < syllabus.auth.Count; index++)
  296. {
  297. if (syllabus.auth[index].tmdid == xmd.tmdid && request.type == syllabus.auth[index].type)
  298. {
  299. flag = true;
  300. indx = index;
  301. break;
  302. }
  303. }
  304. ///更新位置上的授权信息
  305. if (flag)
  306. {
  307. syllabus.auth[indx] = new SyllabusAuth
  308. {
  309. tmdid = xmd.tmdid,
  310. tmdname = xmd.tmdname,
  311. type = request.type,
  312. agree = request.agree,
  313. };
  314. }
  315. //新增
  316. else
  317. {
  318. syllabus.auth.Add(new SyllabusAuth
  319. {
  320. tmdid = xmd.tmdid,
  321. tmdname = xmd.tmdname,
  322. type = request.type,
  323. agree = request.agree,
  324. });
  325. }
  326. });
  327. }
  328. else
  329. {
  330. request.tmdInfo.ForEach(xmd => {
  331. syllabus.auth = new List<SyllabusAuth>() {
  332. new SyllabusAuth {
  333. tmdid = xmd.tmdid,
  334. tmdname = xmd.tmdname,
  335. type = request.type,
  336. agree = request.agree,
  337. }
  338. };
  339. });
  340. }
  341. return (syllabus, shares);
  342. }
  343. /// <summary>
  344. /// {"code":"教师编码","id":"章节id","type":"coedit/share","opt":"ignore/agree"}
  345. ///
  346. /// 教师操作收到的分享及课纲共编, ignore 忽略,需要删除Share 数据 并更新syllabus.auth
  347. /// </summary>
  348. /// <param name="request"></param>
  349. /// <returns></returns>
  350. [ProducesDefaultResponseType]
  351. [HttpPost("agree-share")]
  352. [Authorize(Roles = "IES")]
  353. // [AuthToken(Roles = "Teacher")]
  354. public async Task<IActionResult> AgreeShare(JsonElement request)
  355. {
  356. try
  357. {
  358. if (!request.TryGetProperty("type", out JsonElement type)) { return BadRequest(); }
  359. if (!request.TryGetProperty("code", out JsonElement code)) { return BadRequest(); }
  360. if (!request.TryGetProperty("ids", out JsonElement ids)) { return BadRequest(); }
  361. if (!request.TryGetProperty("opt", out JsonElement opt)) { return BadRequest(); }
  362. var client = _azureCosmos.GetCosmosClient();
  363. if (ids.ValueKind.Equals(JsonValueKind.Array))
  364. {
  365. List<string> idss = ids.ToObject<List<string>>();
  366. foreach (var id in idss)
  367. {
  368. Share share = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Share>($"{id}", new PartitionKey($"Share-{type}-{code}"));
  369. if ($"{opt}".Equals("agree"))
  370. {
  371. share.agree = 1;
  372. await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Share>(share, $"{id}", new PartitionKey($"Share-{type}-{code}"));
  373. }
  374. else if ($"{opt}".Equals("ignore"))
  375. {
  376. await client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemAsync<Share>($"{id}", new PartitionKey($"Share-{type}-{code}"));
  377. }
  378. Syllabus syllabus = null;
  379. if (share.scope.Equals("school"))
  380. {
  381. try
  382. {
  383. syllabus = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<Syllabus>($"{id}", new PartitionKey($"Syllabus-{share.school}"));
  384. }
  385. catch
  386. {
  387. //仅处理差不到数据的情况
  388. }
  389. }
  390. else if (share.scope.Equals("private"))
  391. {
  392. try
  393. {
  394. syllabus = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Syllabus>($"{id}", new PartitionKey($"Syllabus-{share.issuer}"));
  395. }
  396. catch
  397. {
  398. }
  399. }
  400. if (syllabus != null)
  401. {
  402. if (syllabus.auth.IsNotEmpty())
  403. {
  404. syllabus.auth.ForEach(x =>
  405. {
  406. if (x.tmdid == $"{code}" && x.type == $"{type}")
  407. {
  408. if ($"{opt}".Equals("ignore"))
  409. {
  410. x.agree = 0;
  411. }
  412. else if ($"{opt}".Equals("agree"))
  413. {
  414. x.agree = 1;
  415. }
  416. }
  417. });
  418. }
  419. if (share.scope.Equals("school"))
  420. {
  421. syllabus = await client.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<Syllabus>(syllabus, $"{id}", new PartitionKey($"Syllabus-{share.school}"));
  422. }
  423. else if (share.scope.Equals("private"))
  424. {
  425. syllabus = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Syllabus>(syllabus, $"{id}", new PartitionKey($"Syllabus-{share.issuer}"));
  426. }
  427. }
  428. }
  429. }
  430. return Ok(new { status = 200 });
  431. }
  432. catch (Exception ex)
  433. {
  434. await _dingDing.SendBotMsg($"OS,{_option.Location},teacher/share/agree-share()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  435. return Ok(new { status = 500 });
  436. }
  437. }
  438. /// <summary>
  439. /// 删除共享记录
  440. /// {"id":"章节id","type:"coedit/share","code":"教师tmdid"}
  441. /// </summary>
  442. /// <param name="request"></param>
  443. /// <returns></returns>
  444. [ProducesDefaultResponseType]
  445. [HttpPost("del-share")]
  446. [Authorize(Roles = "IES")]
  447. public async Task<IActionResult> DelShare(JsonElement request)
  448. {
  449. try
  450. {
  451. var client = _azureCosmos.GetCosmosClient();
  452. if (!request.TryGetProperty("type", out JsonElement type)) { return BadRequest(); }
  453. if (!request.TryGetProperty("code", out JsonElement code)) { return BadRequest(); }
  454. if (!request.TryGetProperty("id", out JsonElement id)) { return BadRequest(); }
  455. await client.GetContainer(Constant.TEAMModelOS, "Teacher").DeleteItemAsync<Share>($"{id}", new PartitionKey($"Share-{type}-{code}"));
  456. return Ok(new { status = 200 });
  457. }
  458. catch (Exception ex)
  459. {
  460. await _dingDing.SendBotMsg($"OS,{_option.Location},teacher/share/del-share()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  461. return Ok(new { status = 500 });
  462. }
  463. }
  464. /// <summary>
  465. /// {"code":"教师编码","type":"coedit/share","id":"册别id"}
  466. /// 教师拉取自己收到的分享及共编
  467. /// </summary>
  468. /// <param name="request"></param>
  469. /// <returns></returns>
  470. [ProducesDefaultResponseType]
  471. [HttpPost("find")]
  472. [Authorize(Roles = "IES")]
  473. // [AuthToken(Roles = "Teacher")]
  474. public async Task<IActionResult> Find(JsonElement request)
  475. {
  476. try
  477. {
  478. List<Share> shares = new List<Share>();
  479. if (!request.TryGetProperty("code", out JsonElement code)) { return BadRequest(); }
  480. if (!request.TryGetProperty("type", out JsonElement type)) { return BadRequest(); }
  481. request.TryGetProperty("id", out JsonElement id);
  482. var client = _azureCosmos.GetCosmosClient();
  483. StringBuilder queryText = new StringBuilder("select value(c) from c");
  484. queryText.Append($" where c.type='{type}' ");
  485. if (id.ValueKind.Equals(JsonValueKind.String) && !string.IsNullOrEmpty(id.GetString()))
  486. {
  487. queryText.Append($" and c.id='{id}'");
  488. }
  489. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Share>(queryText: queryText.ToString(),
  490. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"Share-{type}-{code}") }))
  491. {
  492. shares.Add(item);
  493. }
  494. var sharesGp = shares.GroupBy(x => new { id = x.volumeId, code = x.scope == "school" ? x.school : x.issuer, issuerName = x.issuerName }).Select(y => new { id = y.Key.id, code = y.Key.code, issuerName = y.Key.issuerName, list = y.ToList() });
  495. return Ok(new { shares = sharesGp, status = 200 });
  496. }
  497. catch (Exception ex)
  498. {
  499. await _dingDing.SendBotMsg($"OS,{_option.Location},teacher/share/find()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  500. return Ok(new { status = 404 });
  501. }
  502. }
  503. public record ShareView
  504. {
  505. public string scope { get; set; }
  506. // public string code { get; set; }
  507. public string school { get; set; }
  508. public string issuer { get; set; }
  509. public string volumeId { get; set; }
  510. public List<string> syllabusId { get; set; }
  511. }
  512. /*
  513. {
  514. "scope": "school/private",
  515. "school": "学校编码",
  516. "issuer": "权限颁发者",
  517. "volumeId": "册别id",
  518. "syllabusId": ["id1课纲章节节点id","id2课纲章节节点id"],
  519. }
  520. */
  521. /// <summary>
  522. /// 查看分享
  523. /// </summary>
  524. /// <param name="request"></param>
  525. /// <returns></returns>
  526. [ProducesDefaultResponseType]
  527. [HttpPost("view-share")]
  528. [AuthToken(Roles = "teacher")]
  529. [Authorize(Roles = "IES")]
  530. public async Task<IActionResult> View(ShareView request)
  531. {
  532. try
  533. {
  534. List<SyllabusTreeNode> treeNodes = new List<SyllabusTreeNode>();
  535. Volume volume;
  536. var client = _azureCosmos.GetCosmosClient();
  537. string code = null;
  538. List<string> sid = new List<string>();
  539. request.syllabusId.ForEach(x => { sid.Add($"'{x}'"); });
  540. var sidSql = string.Join(",", sid);
  541. if (request.scope.Equals("school"))
  542. {
  543. code = request.school;
  544. var queryslt = $"SELECT value(c) FROM c where c.id in ({sidSql})";
  545. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<Syllabus>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Syllabus-{request.school}") }))
  546. {
  547. List<SyllabusTree> trees = SyllabusService.ListToTree(item.children);
  548. SyllabusTreeNode tree = new SyllabusTreeNode() { id = item.id, scope = item.scope, trees = trees, volumeId = item.volumeId, auth = item.auth };
  549. treeNodes.Add(tree);
  550. }
  551. volume = await client.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<Volume>(request.volumeId, new PartitionKey($"Volume-{code}"));
  552. }
  553. else if (request.scope.Equals("private"))
  554. {
  555. code = request.issuer;
  556. var queryslt = $"SELECT value(c) FROM c where c.id in ({sidSql})";
  557. await foreach (var item in client.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Syllabus>(queryText: queryslt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Syllabus-{request.issuer}") }))
  558. {
  559. List<SyllabusTree> trees = SyllabusService.ListToTree(item.children);
  560. SyllabusTreeNode tree = new SyllabusTreeNode() { id = item.id, scope = item.scope, trees = trees, volumeId = item.volumeId, auth = item.auth };
  561. treeNodes.Add(tree);
  562. }
  563. volume = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Volume>(request.volumeId, new PartitionKey($"Volume-{code}"));
  564. }
  565. else
  566. {
  567. return BadRequest();
  568. }
  569. return Ok(new { volume, tree = treeNodes });
  570. }
  571. catch (Exception ex)
  572. {
  573. await _dingDing.SendBotMsg($"OS,{_option.Location},teacher/share/view()\n{ex.Message}\n{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  574. return BadRequest();
  575. }
  576. }
  577. /// <summary>
  578. ///二维码扫码方式
  579. /// </summary>
  580. /// <param name="request"></param>
  581. /// <returns></returns>
  582. [ProducesDefaultResponseType]
  583. [HttpPost("qrcode")]
  584. //[AuthToken(Roles = "teacher")]
  585. public async Task<IActionResult> Qrcode(JsonElement request)
  586. {
  587. return Ok();
  588. }
  589. }
  590. }