SchoolTeacherController.cs 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442
  1. using Microsoft.AspNetCore.Mvc;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. using TEAMModelOS.Models;
  7. using TEAMModelOS.SDK;
  8. using TEAMModelOS.SDK.DI;
  9. using TEAMModelOS.SDK.Helper.Common.CollectionHelper;
  10. using TEAMModelOS.SDK.Context.Exception;
  11. using System.Text.Json;
  12. using TEAMModelOS.Models.SchoolInfo;
  13. using Microsoft.AspNetCore.Http;
  14. using Azure.Cosmos;
  15. using TEAMModelOS.SDK.Extension;
  16. using System.IdentityModel.Tokens.Jwt;
  17. using System.IO;
  18. using TEAMModelOS.Models.TeacherInfo;
  19. using System.Linq;
  20. using Microsoft.Extensions.Options;
  21. using System.Net.Http;
  22. using Newtonsoft.Json;
  23. using TEAMModelOS.SDK.Context.Configuration;
  24. using System.Net;
  25. namespace TEAMModelOS.Controllers
  26. {
  27. [ProducesResponseType(StatusCodes.Status200OK)]
  28. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  29. //[Authorize(Roles = "teacher")]
  30. [Route("school/teacher")]
  31. [ApiController]
  32. public class SchoolTeacherController : Controller
  33. {
  34. private readonly AzureCosmosFactory _azureCosmos;
  35. private readonly AzureStorageFactory _azureStorage;
  36. private readonly Option _option;
  37. public SchoolTeacherController(AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, IOptionsSnapshot<Option> option)
  38. {
  39. _azureCosmos = azureCosmos;
  40. _azureStorage = azureStorage;
  41. _option = option?.Value;
  42. }
  43. /// <summary>
  44. /// 取得學校所有老師(不論加入狀態)
  45. /// </summary>
  46. /// <param name="request"></param>
  47. /// <returns></returns>
  48. [ProducesDefaultResponseType]
  49. [HttpPost("get-teacher-all")]
  50. public async Task<IActionResult> GetSchoolTeacherAll(JsonElement request)
  51. {
  52. var client = _azureCosmos.GetCosmosClient();
  53. //參數取得
  54. if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
  55. //string status_str = (request.TryGetProperty("join_status", out JsonElement status_json)) ? status_json.ToString() : "join";
  56. //資料取得
  57. List<object> teachers = new List<object>();
  58. await foreach (var item in client.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: $"SELECT c.id, c.name, c.classes, c.picture ,c.status, c.job, c.createTime, ARRAY_LENGTH(c.permissions) as permissionCount FROM c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school_code}") }))
  59. {
  60. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  61. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  62. {
  63. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  64. {
  65. teachers.Add(obj.ToObject<object>());
  66. }
  67. }
  68. }
  69. return Ok(new { teachers });
  70. }
  71. /// <summary>
  72. /// 取得某位老師的權限
  73. /// </summary>
  74. /// <param name="request"></param>
  75. /// <returns></returns>
  76. [ProducesDefaultResponseType]
  77. [HttpPost("get-teacher-permission")]
  78. public async Task<IActionResult> GetPermissionById(JsonElement request)
  79. {
  80. var client = _azureCosmos.GetCosmosClient();
  81. //參數取得
  82. if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
  83. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  84. //老師權限資料取得
  85. object permissions = null;
  86. var response = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(id.ToString(), new PartitionKey($"Teacher-{school_code}"));
  87. if (response.Status == 200)
  88. {
  89. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  90. if (json.RootElement.TryGetProperty("permissions", out JsonElement value))
  91. {
  92. permissions = value.ToObject<object>();
  93. }
  94. }
  95. return Ok(new { permissions });
  96. }
  97. /// <summary>
  98. /// 取得權限總列表
  99. /// </summary>
  100. [ProducesDefaultResponseType]
  101. [HttpPost("get-teacher-authoritylist")]
  102. public async Task<IActionResult> GetSchoolAuthorityList()
  103. {
  104. ResponseBuilder builder = ResponseBuilder.custom();
  105. Dictionary<string, object> dict = new Dictionary<string, object>
  106. {
  107. { "PartitionKey", "authority"}
  108. };
  109. List<Authority> authoritylist = await _azureStorage.FindListByDict<Authority>(dict);
  110. return Ok(new { authoritylist });
  111. }
  112. /// <summary>
  113. /// 更新老師的權限(可複數)
  114. /// </summary>
  115. /// <param name="request"></param>
  116. /// <returns></returns>
  117. [ProducesDefaultResponseType]
  118. [HttpPost("upd-teacher-permission")]
  119. public async Task<IActionResult> UpdSchoolTeacherPermission(JsonElement request)
  120. {
  121. try
  122. {
  123. var client = _azureCosmos.GetCosmosClient();
  124. //參數取得
  125. if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
  126. request.TryGetProperty("ids", out JsonElement ids);
  127. request.TryGetProperty("mode", out JsonElement mode);
  128. request.TryGetProperty("pmAdd", out JsonElement pmAdd);
  129. request.TryGetProperty("pmRmv", out JsonElement pmRmv);
  130. List<string> pmAddList = new List<string>();
  131. List<string> pmRmvList = new List<string>();
  132. request.TryGetProperty("job", out JsonElement job);
  133. if (mode.GetString() == "multi")
  134. {
  135. foreach (var pm in pmAdd.EnumerateArray())
  136. {
  137. pmAddList.Add(pm.GetString());
  138. }
  139. foreach (var pm in pmRmv.EnumerateArray())
  140. {
  141. pmRmvList.Add(pm.GetString());
  142. }
  143. } else
  144. {
  145. foreach (var pm in pmAdd.EnumerateArray())
  146. {
  147. pmAddList.Add(pm.GetString());
  148. }
  149. }
  150. //更新權限
  151. foreach (var id in ids.EnumerateArray())
  152. {
  153. SchoolTeacher st = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<SchoolTeacher>(id.GetString(), new PartitionKey($"Teacher-{school_code}"));
  154. if(mode.GetString() == "multi")
  155. {
  156. foreach (var pm in pmRmvList)
  157. {
  158. if(st.permissions.Contains(pm))
  159. {
  160. st.permissions.Remove(pm);
  161. }
  162. }
  163. foreach (var pm in pmAddList)
  164. {
  165. if (!st.permissions.Contains(pm))
  166. {
  167. st.permissions.Add(pm);
  168. }
  169. }
  170. } else
  171. {
  172. st.permissions = pmAddList;
  173. st.job = (!string.IsNullOrEmpty(job.GetString())) ? job.GetString() : null;
  174. }
  175. await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<SchoolTeacher>(st, id.GetString(), new PartitionKey($"Teacher-{school_code}"));
  176. }
  177. return Ok(new {});
  178. }
  179. catch (Exception ex)
  180. {
  181. return BadRequest();
  182. }
  183. }
  184. /// <summary>
  185. /// 追加老師及學校加入狀態
  186. /// </summary>
  187. /// <param name="request"></param>
  188. /// <returns></returns>
  189. [ProducesDefaultResponseType]
  190. [HttpPost("add-teacher-status")]
  191. public async Task<IActionResult> AddSchoolTeacher(JsonElement request)
  192. {
  193. var client = _azureCosmos.GetCosmosClient();
  194. //參數取得
  195. if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
  196. if (!request.TryGetProperty("user_list", out JsonElement user_list)) return BadRequest();
  197. if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
  198. //取得學校資訊
  199. var schresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school_code.ToString(), new PartitionKey("Base"));
  200. string schname = string.Empty;
  201. if (schresponse.Status == 200)
  202. {
  203. using var schjson = await JsonDocument.ParseAsync(schresponse.ContentStream);
  204. schjson.RootElement.TryGetProperty("name", out JsonElement jsonschname);
  205. schname = jsonschname.ToString();
  206. }
  207. else
  208. {
  209. return BadRequest();
  210. }
  211. try
  212. {
  213. foreach (var obj in user_list.EnumerateArray())
  214. {
  215. obj.TryGetProperty("id", out JsonElement id);
  216. obj.TryGetProperty("name", out JsonElement name);
  217. obj.TryGetProperty("picture", out JsonElement picture);
  218. //老師個人資料
  219. var tresponse = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemStreamAsync(id.ToString(), new PartitionKey("Base"));
  220. if(tresponse.Status == 200)
  221. {
  222. using var json = await JsonDocument.ParseAsync(tresponse.ContentStream);
  223. Teacher teacher = json.ToObject<Teacher>();
  224. var school = teacher.schools.FirstOrDefault(x => x.schoolId.Equals(school_code.GetString(), StringComparison.OrdinalIgnoreCase));
  225. if (school != null)
  226. school.status = grant_type.GetString();
  227. else
  228. teacher.schools.Add(new Teacher.School() { schoolId = school_code.GetString(), name = schname, status = grant_type.GetString() });
  229. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Teacher>(teacher, id.ToString(), new PartitionKey("Base"));
  230. }
  231. else
  232. {
  233. using var stream = new MemoryStream();
  234. using var writer = new Utf8JsonWriter(stream);
  235. writer.WriteStartObject();
  236. writer.WriteString("pk", "Base");
  237. writer.WriteString("code", "Base");
  238. writer.WriteString("id", id.ToString());
  239. writer.WriteString("name", name.ToString());
  240. writer.WriteString("picture", picture.ToString());
  241. writer.WriteNumber("size", 1);
  242. writer.WriteNull("defaultSchool");
  243. writer.WriteStartArray("schools");
  244. writer.WriteStartObject();
  245. writer.WriteString("schoolId", school_code.ToString());
  246. writer.WriteString("name", schname);
  247. writer.WriteString("status", grant_type.ToString());
  248. writer.WriteEndObject();
  249. writer.WriteEndArray();
  250. writer.WriteEndObject();
  251. writer.Flush();
  252. await client.GetContainer("TEAMModelOS", "Teacher").CreateItemStreamAsync(stream, new PartitionKey("Base"));
  253. }
  254. //學校老師資料
  255. var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(id.ToString(), new PartitionKey($"Teacher-{school_code}"));
  256. //SchoolTeacher schteacher = await client.GetContainer("TEAMModelOS", "School").ReadItemAsync<SchoolTeacher>(id.ToString(), new PartitionKey($"Teacher-{school_code}"));
  257. if (sresponse.Status == 200)
  258. {
  259. using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
  260. SchoolTeacher schteacher = json.ToObject<SchoolTeacher>();
  261. schteacher.status = grant_type.ToString();
  262. await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<SchoolTeacher>(schteacher, id.ToString(), new PartitionKey($"Teacher-{school_code}"));
  263. }
  264. else
  265. {
  266. using var stream = new MemoryStream();
  267. using var writer = new Utf8JsonWriter(stream);
  268. writer.WriteStartObject();
  269. writer.WriteString("pk", "Teacher");
  270. writer.WriteString("code", $"Teacher-{school_code}");
  271. writer.WriteString("id", id.ToString());
  272. writer.WriteString("name", name.ToString());
  273. writer.WriteString("picture", picture.ToString());
  274. writer.WriteNull("job");
  275. writer.WriteStartArray("roles");
  276. writer.WriteStringValue("teacher");
  277. writer.WriteEndArray();
  278. writer.WriteStartArray("permissions");
  279. writer.WriteEndArray();
  280. writer.WriteString("status", grant_type.ToString());
  281. writer.WriteNumber("createTime", DateTimeOffset.UtcNow.ToUnixTimeSeconds());
  282. writer.WriteEndObject();
  283. writer.Flush();
  284. await client.GetContainer("TEAMModelOS", "School").CreateItemStreamAsync(stream, new PartitionKey($"Teacher-{school_code}"));
  285. }
  286. }
  287. return Ok(new { });
  288. }
  289. catch(Exception ex)
  290. {
  291. return BadRequest();
  292. }
  293. }
  294. /// <summary>
  295. /// 學校變更老師加入狀態
  296. /// </summary>
  297. /// <param name="request"></param>
  298. /// <returns></returns>
  299. [ProducesDefaultResponseType]
  300. //[AuthToken(Roles = "admin")]
  301. [HttpPost("upd-teacher-status")]
  302. public async Task<IActionResult> UpdSchoolTeacherStatus(JsonElement request)
  303. {
  304. try
  305. {
  306. if (!request.TryGetProperty("grant_type", out JsonElement grant_type)) return BadRequest();
  307. if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
  308. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  309. var client = _azureCosmos.GetCosmosClient();
  310. //取得學校資訊
  311. var schresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school_code.ToString(), new PartitionKey("Base"));
  312. string schname = string.Empty;
  313. if (schresponse.Status == 200)
  314. {
  315. using var schjson = await JsonDocument.ParseAsync(schresponse.ContentStream);
  316. schjson.RootElement.TryGetProperty("name", out JsonElement jsonschname);
  317. schname = jsonschname.ToString();
  318. }
  319. else
  320. {
  321. return BadRequest();
  322. }
  323. //在老師表找出老師,處理該學校狀態 (老師基本資料應該要存在)
  324. Teacher teacher = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Teacher>(id.ToString(), new PartitionKey("Base"));
  325. if (teacher.schools == null)
  326. teacher.schools = new List<Teacher.School>();
  327. var school = teacher.schools?.FirstOrDefault(x => x.schoolId.Equals(school_code.GetString(), StringComparison.OrdinalIgnoreCase));
  328. if (school != null)
  329. school.status = grant_type.GetString();
  330. else
  331. teacher.schools.Add(new Teacher.School() { schoolId = school_code.GetString(), name = schname, status = grant_type.GetString() });
  332. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Teacher>(teacher, id.ToString(), new PartitionKey("Base"));
  333. //在學校表處理該學校教師帳號的狀態
  334. var sresponse = await client.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(id.GetString(), new PartitionKey($"Teacher-{school_code}"));
  335. if (sresponse.Status == 200)
  336. {
  337. using var json = await JsonDocument.ParseAsync(sresponse.ContentStream);
  338. SchoolTeacher steacher = json.ToObject<SchoolTeacher>();
  339. steacher.status = grant_type.GetString();
  340. var response = await client.GetContainer("TEAMModelOS", "School").ReplaceItemAsync(steacher, id.GetString(), new PartitionKey($"Teacher-{school_code}"));
  341. }
  342. else
  343. {
  344. SchoolTeacher st = new SchoolTeacher()
  345. {
  346. pk = "Teacher",
  347. code = $"Teacher-{school_code}",
  348. createTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
  349. id = teacher.id,
  350. name = teacher.name,
  351. picture = teacher.picture,
  352. roles = new List<string>(new string[] { "teacher" }),
  353. permissions = null,
  354. status = grant_type.GetString()
  355. };
  356. var response = await client.GetContainer("TEAMModelOS", "School").CreateItemAsync(st, new PartitionKey($"Teacher-{school_code}"));
  357. }
  358. return Ok(new { });
  359. }
  360. catch (Exception ex)
  361. {
  362. return BadRequest();
  363. }
  364. }
  365. /// <summary>
  366. /// 學校移除老師跟學校關聯
  367. /// </summary>
  368. /// <param name="request"></param>
  369. /// <returns></returns>
  370. [ProducesDefaultResponseType]
  371. //[AuthToken(Roles = "admin")]
  372. [HttpPost("rmv-teacher")]
  373. public async Task<IActionResult> RmvSchoolTeacher(JsonElement request)
  374. {
  375. try
  376. {
  377. if (!request.TryGetProperty("school_code", out JsonElement school_code)) return BadRequest();
  378. if (!request.TryGetProperty("id", out JsonElement id)) return BadRequest();
  379. var client = _azureCosmos.GetCosmosClient();
  380. //在老師表找出老師,刪除該學校 (老師基本資料應該要存在)
  381. Teacher teacher = await client.GetContainer("TEAMModelOS", "Teacher").ReadItemAsync<Teacher>(id.ToString(), new PartitionKey("Base"));
  382. var school = teacher.schools.RemoveAll(x => x.schoolId.Equals(school_code.GetString(), StringComparison.OrdinalIgnoreCase));
  383. await client.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Teacher>(teacher, id.ToString(), new PartitionKey("Base"));
  384. //移除學校表中的老師document
  385. var sresponse = await client.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync(id.GetString(), new PartitionKey($"Teacher-{school_code}"));
  386. return Ok(new { });
  387. }
  388. catch (Exception ex)
  389. {
  390. return BadRequest();
  391. }
  392. }
  393. /// <summary>
  394. /// 取得CoreID資訊
  395. /// </summary>
  396. /// <param name="request"></param>
  397. /// <returns></returns>
  398. [ProducesDefaultResponseType]
  399. //[AuthToken(Roles = "admin")]
  400. [HttpPost("get-coreuser")]
  401. public async Task<IActionResult> GetUserFromCoreID(JsonElement request)
  402. {
  403. try
  404. {
  405. string url = BaseConfigModel.Configuration["HaBookAuth:CoreId:userinfo"];
  406. HttpClient client = new HttpClient();
  407. var content = new StringContent(request.ToString(), Encoding.UTF8, "application/json");
  408. HttpResponseMessage responseMessage = await client.PostAsync(url, content);
  409. if(responseMessage.StatusCode == HttpStatusCode.OK)
  410. {
  411. string responseBody = responseMessage.Content.ReadAsStringAsync().Result;
  412. return Ok(responseBody);
  413. }
  414. else
  415. {
  416. return BadRequest();
  417. }
  418. }
  419. catch (Exception ex)
  420. {
  421. return BadRequest();
  422. }
  423. }
  424. }
  425. }