SchoolController.cs 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146
  1. using Azure.Cosmos;
  2. using HTEXLib.COMM.Helpers;
  3. using Microsoft.AspNetCore.Http;
  4. using Microsoft.AspNetCore.Mvc;
  5. using Microsoft.Extensions.Configuration;
  6. using Microsoft.Extensions.Options;
  7. using StackExchange.Redis;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Net.Http;
  12. using System.Text;
  13. using System.Text.Json;
  14. using System.Threading.Tasks;
  15. using TEAMModelBI.DI.BIAzureStorage;
  16. using TEAMModelBI.Filter;
  17. using TEAMModelBI.Tool;
  18. using TEAMModelBI.Tool.Context;
  19. using TEAMModelBI.Tool.CosmosBank;
  20. using TEAMModelBI.Tool.Extension;
  21. using TEAMModelOS.Models;
  22. using TEAMModelOS.SDK;
  23. using TEAMModelOS.SDK.DI;
  24. using TEAMModelOS.SDK.Extension;
  25. using TEAMModelOS.SDK.Models;
  26. using TEAMModelOS.SDK.Models.Cosmos.BI;
  27. using TEAMModelOS.SDK.Models.Service;
  28. namespace TEAMModelBI.Controllers.BISchool
  29. {
  30. [Route("schoolcheck")]
  31. [ApiController]
  32. public class SchoolController : ControllerBase
  33. {
  34. private readonly AzureCosmosFactory _azureCosmos;
  35. private readonly DingDing _dingDing;
  36. private readonly Option _option;
  37. private readonly AzureStorageFactory _azureStorage;
  38. private readonly AzureRedisFactory _azureRedis;
  39. private readonly IConfiguration _configuration;
  40. private readonly NotificationService _notificationService;
  41. private readonly CoreAPIHttpService _coreAPIHttpService;
  42. public SchoolController(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, IOptionsSnapshot<Option> option, AzureRedisFactory azureRedis, IConfiguration configuration, NotificationService notificationService, CoreAPIHttpService coreAPIHttpService)
  43. {
  44. _azureCosmos = azureCosmos;
  45. _dingDing = dingDing;
  46. _azureStorage = azureStorage;
  47. _option = option?.Value;
  48. _azureRedis = azureRedis;
  49. _configuration = configuration;
  50. _notificationService = notificationService;
  51. _coreAPIHttpService = coreAPIHttpService;
  52. }
  53. /// <summary>
  54. /// 查询未加入区域的学校
  55. /// </summary>
  56. /// <returns></returns>
  57. [ProducesDefaultResponseType]
  58. [HttpPost("get-notarea")]
  59. public async Task<IActionResult> GetNotAreaSchool(JsonElement jsonElement)
  60. {
  61. try
  62. {
  63. jsonElement.TryGetProperty("areaId", out JsonElement areaId);
  64. jsonElement.TryGetProperty("site", out JsonElement site);
  65. var cosmosClient = _azureCosmos.GetCosmosClient();
  66. if ($"{site}".Equals(BIConst.GlobalSite))
  67. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  68. //默认不指定返回大小
  69. int? pageSize = null;
  70. string continuationToken = string.Empty;
  71. string pageToken = default;
  72. if (jsonElement.TryGetProperty("pageSize", out JsonElement jsonPageSize))
  73. {
  74. if (!jsonPageSize.ValueKind.Equals(JsonValueKind.Undefined) && !jsonPageSize.ValueKind.Equals(JsonValueKind.Null) && jsonPageSize.TryGetInt32(out int tempPageSize))
  75. {
  76. pageSize = tempPageSize;
  77. }
  78. }
  79. //是否需要进行分页查询,默认不分页
  80. bool iscontinuation = false;
  81. if (pageSize != null && pageSize.Value > 0)
  82. {
  83. iscontinuation = true;
  84. }
  85. if (jsonElement.TryGetProperty("contToken", out JsonElement ContToken))
  86. {
  87. pageToken = ContToken.GetString();
  88. }
  89. string sqltxt = "SELECT c.id,c.name,c.schoolCode,c.province,c.city,c.dist,c.picture,c.period,c.areaId,c.standard,c.manyAreas FROM c WHERE c.areaId !='{areaId}'";
  90. List<NotAreaSchool> tempNotAreaSchools = new();
  91. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: sqltxt, continuationToken: pageToken, requestOptions: new QueryRequestOptions() { MaxItemCount = pageSize, PartitionKey = new PartitionKey("Base") }))
  92. {
  93. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  94. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  95. {
  96. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  97. {
  98. //List<string> temp0 = obj.GetProperty("period").ToObject<List<Period>>().Select(x=>x.name).ToList();
  99. NotAreaSchool notAreaSchool = new NotAreaSchool()
  100. {
  101. id = obj.GetProperty("id").GetString(),
  102. name = obj.GetProperty("name").GetString(),
  103. schoolCode = obj.GetProperty("schoolCode").GetString(),
  104. picture = obj.GetProperty("picture").GetString(),
  105. period = obj.GetProperty("period").ToObject<List<Period>>().Select(x => x.name).ToList(),
  106. province = obj.GetProperty("province").GetString(),
  107. city = obj.GetProperty("city").GetString(),
  108. dist = obj.GetProperty("dist").GetString(),
  109. areaId = obj.GetProperty("areaId").GetString(),
  110. standard = obj.GetProperty("standard").GetString()
  111. };
  112. try
  113. {
  114. notAreaSchool.manyAreas = obj.GetProperty("manyAreas").ToObject<List<ManyArea>>();
  115. }
  116. catch { }
  117. tempNotAreaSchools.Add(notAreaSchool);
  118. }
  119. if (iscontinuation)
  120. {
  121. continuationToken = item.GetContinuationToken();
  122. break;
  123. }
  124. }
  125. }
  126. List<NotAreaSchool> notAreaSchools = new List<NotAreaSchool>();
  127. tempNotAreaSchools.ForEach(nas =>
  128. {
  129. if (nas.manyAreas == null)
  130. notAreaSchools.Add(nas);
  131. else
  132. {
  133. var not = nas.manyAreas.Find(f => f.areaId == $"{areaId}");
  134. if (not == null)
  135. notAreaSchools.Add(nas);
  136. }
  137. });
  138. //if (!string.IsNullOrEmpty($"{areaId}"))
  139. // notAreaSchools = notAreaSchools.Select(na => new NotAreaSchool { id = na.id, name = na.name, schoolCode = na.schoolCode, picture = na.picture, period = na.period, province = na.province, city = na.city = na.city, dist = na.dist, manyAreas = new List<ManyArea> { na.manyAreas.Find(m => m.areaId != $"{areaId}") } }).ToList();
  140. return Ok(new { state = 200, continuationToken,cont= notAreaSchools.Count, notAreaSchools });
  141. }
  142. catch (Exception ex)
  143. {
  144. await _dingDing.SendBotMsg($"BI,{_option.Location} /schoolcheck/get-notarea \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  145. return BadRequest();
  146. }
  147. }
  148. /// <summary>
  149. /// 学校加入区
  150. /// </summary>
  151. /// <param name="jsonElement"></param>
  152. /// <returns></returns>
  153. [ProducesDefaultResponseType]
  154. [AuthToken(Roles = "admin,rdc,assist,sales")]
  155. [HttpPost("set-schooljoinarea")]
  156. public async Task<IActionResult> SetSchoolJoinArea(JsonElement jsonElement)
  157. {
  158. try
  159. {
  160. if (!jsonElement.TryGetProperty("standard", out JsonElement standard)) return BadRequest();
  161. if (!jsonElement.TryGetProperty("schoolCode", out JsonElement _schoolCode)) return BadRequest();
  162. if (!jsonElement.TryGetProperty("areaId", out JsonElement _areaId)) return BadRequest();
  163. jsonElement.TryGetProperty("isDefault", out JsonElement isDefault);
  164. jsonElement.TryGetProperty("site", out JsonElement site);
  165. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  166. List<string> schoolCodes = _schoolCode.ToObject<List<string>>();
  167. var cosmosClient = _azureCosmos.GetCosmosClient();
  168. var tableClient = _azureStorage.GetCloudTableClient();
  169. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  170. if ($"{site}".Equals(BIConst.GlobalSite))
  171. {
  172. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  173. tableClient = _azureStorage.GetCloudTableClient(BIConst.GlobalSite);
  174. blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.GlobalSite);
  175. }
  176. if (schoolCodes.Count > 0)
  177. {
  178. foreach (var tempCode in schoolCodes)
  179. {
  180. School school = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(tempCode, new PartitionKey("Base"));
  181. if (school != null)
  182. {
  183. if (bool.Parse($"{isDefault}") == true)
  184. {
  185. school.standard = $"{standard}";
  186. school.areaId = $"{_areaId}";
  187. }
  188. if (school.manyAreas == null)
  189. {
  190. //ManyArea manyArea = new ManyArea() { areaId = $"{_areaId}", standard = $"{standard}" };
  191. school.manyAreas = new List<ManyArea>() { new ManyArea() { areaId = $"{_areaId}", standard = $"{standard}" } };
  192. }
  193. else
  194. {
  195. var marea = school.manyAreas.Find(ma => ma.areaId == $"{_areaId}" && ma.standard == $"{standard}");
  196. if (marea == null)
  197. school.manyAreas.Add(new ManyArea() { areaId = $"{_areaId}", standard = $"{standard}" });
  198. }
  199. await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<School>(school, school.id, new PartitionKey(school.code));
  200. }
  201. }
  202. }
  203. //保存操作记录
  204. //await _azureStorage.SaveBILog("school-update", $"{_tmdName}【{_tmdId}】操作学校加入区域功能,加入的区域:{standard},学校ID:{string.Join("|", schoolCodes.ToArray())}", _dingDing, httpContext: HttpContext);
  205. await BIAzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "school-update", $"{_tmdName}【{_tmdId}】操作学校加入区域功能,加入的区域:{standard},学校ID:{string.Join("|", schoolCodes.ToArray())}", _dingDing, httpContext: HttpContext);
  206. return Ok(new { state = 200 });
  207. }
  208. catch (Exception ex)
  209. {
  210. await _dingDing.SendBotMsg($"BI,{_option.Location} /schoolcheck/set-schooljoinarea \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  211. return BadRequest();
  212. }
  213. }
  214. /// <summary>
  215. /// 依据醍摩豆账户查询顾问管理学校的基础信息
  216. /// </summary>
  217. /// <param name="jsonElement"></param>
  218. /// <returns></returns>
  219. [HttpPost("get-assistschool")]
  220. public async Task<IActionResult> GetAssistSchool(JsonElement jsonElement)
  221. {
  222. try
  223. {
  224. if (!jsonElement.TryGetProperty("tmdId", out JsonElement tmdId)) return BadRequest();
  225. jsonElement.TryGetProperty("site", out JsonElement site);
  226. List<object> schools = new List<object>();
  227. var cosmosClient = _azureCosmos.GetCosmosClient();
  228. if ($"{site}".Equals(BIConst.GlobalSite))
  229. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  230. //List<string> schoolIds = new List<string>();
  231. //string sqlTxt = $"SELECT DISTINCT REPLACE(c.code, 'Teacher-', '') AS schoolId FROM c WHERE c.pk = 'Teacher' AND c.status = 'join' AND ARRAY_CONTAINS(c.roles, 'assist', true) AND c.id='{tmdId}' ";
  232. //await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { }))
  233. //{
  234. // using var json = await JsonDocument.ParseAsync(item.ContentStream);
  235. // foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  236. // {
  237. // schoolIds.Add(obj.GetProperty("schoolId").GetString());
  238. // }
  239. //}
  240. List<string> schoolIds = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
  241. foreach (var item in schoolIds)
  242. {
  243. await foreach (var itemBase in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: $"select c.id,c.code,c.name,c.picture,c.region,c.province,c.city,c.dist from c where c.id='{item}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
  244. {
  245. var json = await JsonDocument.ParseAsync(itemBase.ContentStream);
  246. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  247. {
  248. schools.Add(obj.ToObject<object>());
  249. }
  250. }
  251. }
  252. return Ok(new { state = 200, schools });
  253. }
  254. catch (Exception ex)
  255. {
  256. await _dingDing.SendBotMsg($"BI,{_option.Location} /schoolcheck/get-assustschool \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  257. return BadRequest();
  258. }
  259. }
  260. /// <summary>
  261. /// 依据学校编号查询学校信息
  262. /// </summary>
  263. /// <param name="jsonElement"></param>
  264. /// <returns></returns>
  265. [HttpPost("get-schoolid")]
  266. public async Task<IActionResult> GetSchoolId(JsonElement jsonElement)
  267. {
  268. try
  269. {
  270. if (!jsonElement.TryGetProperty("schoolId", out JsonElement schoolId)) return BadRequest();
  271. jsonElement.TryGetProperty("site", out JsonElement site);
  272. var cosmosClient = _azureCosmos.GetCosmosClient();
  273. if ($"{site}".Equals(BIConst.GlobalSite))
  274. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  275. var rsponse = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync($"{schoolId}", new PartitionKey("Base"));
  276. if (rsponse.Status == 200)
  277. {
  278. using var json = await JsonDocument.ParseAsync(rsponse.ContentStream);
  279. School school = json.ToObject<School>();
  280. return Ok(new { state = 200, school });
  281. }
  282. else
  283. return Ok(new { state = 404, msg = $"未找到ID是({schoolId})的学校" });
  284. }
  285. catch (Exception ex)
  286. {
  287. await _dingDing.SendBotMsg($"BI,{_option.Location} /schoolcheck/get-schoolid \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  288. return BadRequest();
  289. }
  290. }
  291. /// <summary>
  292. /// 修改学校信息
  293. /// </summary>
  294. /// <param name="school"></param>
  295. /// <returns></returns>
  296. [ProducesDefaultResponseType]
  297. [AuthToken(Roles = "admin,rdc,assist,sales")]
  298. [HttpPost("upd-school")]
  299. public async Task<IActionResult> UpdSchool(School school, [FromHeader] string site)
  300. {
  301. try
  302. {
  303. School schoolInfo = new School();
  304. var cosmosClient = _azureCosmos.GetCosmosClient();
  305. var tableClient = _azureStorage.GetCloudTableClient();
  306. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  307. if ($"{site}".Equals(BIConst.GlobalSite))
  308. {
  309. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  310. tableClient = _azureStorage.GetCloudTableClient(BIConst.GlobalSite);
  311. blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.GlobalSite);
  312. }
  313. string _auth = HttpContext.GetXAuth("AuthToken");
  314. //var (tmdId, tmdName) = HttpJwtAnalysis.JwtXAuth(_auth, _option);
  315. var (tmdId, tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(_auth, _option);
  316. var response = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(school.id, new PartitionKey($"Base"));
  317. if (response.Status == 200)
  318. {
  319. string sql = $"SELECT distinct value(c) FROM c join A1 in c.schools where A1.schoolId='{school.id}'";
  320. List<Teacher> teachers = new List<Teacher>();
  321. await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Teacher>(sql, requestOptions: new QueryRequestOptions { PartitionKey = new PartitionKey("Base") }))
  322. {
  323. teachers.Add(item);
  324. }
  325. foreach (var item in teachers)
  326. {
  327. Teacher.TeacherSchool teacherSchool = item.schools.Find(x => x.schoolId.Equals(school.id));
  328. if (teacherSchool != null)
  329. {
  330. teacherSchool.name = school.name;
  331. teacherSchool.picture = school.picture;
  332. teacherSchool.areaId = school.areaId;
  333. }
  334. await cosmosClient.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync(item, item.id, new PartitionKey($"Base"));
  335. }
  336. schoolInfo = await cosmosClient.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<School>(school, school.id, new PartitionKey($"Base"));
  337. //保存操作记录
  338. //await _azureStorage.SaveBILog("school-update", $"{tmdName}【{tmdId}】修改学校信息,学校和ID:{school.name}【{school.id}】", _dingDing, httpContext: HttpContext);
  339. await BIAzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "school-update", $"{tmdName}【{tmdId}】修改学校信息,学校和ID:{school.name}【{school.id}】", _dingDing, httpContext: HttpContext);
  340. }
  341. else return Ok(new { state = 400, message = "请求错误!" });
  342. return Ok(new { state = 200, schoolInfo });
  343. //School tempShool = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(replaceSchool.school.id, new PartitionKey("Base"));
  344. //if (tempShool != null)
  345. //{
  346. // List<Teacher> teachers = new List<Teacher>();
  347. // string sqltxt = $"select distinct value(c) from c join a1 in c.schools where a1.schoolId='{replaceSchool.school.id}'";
  348. // await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sqltxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
  349. // {
  350. // teachers.Add(item);
  351. // }
  352. // foreach (var item in teachers)
  353. // {
  354. // Teacher.TeacherSchool teacherSchool = item.schools.Find(x => x.schoolId.Equals(replaceSchool.school.id));
  355. // if (teacherSchool != null)
  356. // {
  357. // teacherSchool.name = replaceSchool.school.name;
  358. // teacherSchool.picture = replaceSchool.school.picture;
  359. // teacherSchool.areaId = replaceSchool.school.areaId;
  360. // }
  361. // await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync(item, item.id, new PartitionKey("Base"));
  362. // }
  363. // schoolInfo = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<School>(replaceSchool.school, replaceSchool.school.id, new PartitionKey("Base"));
  364. // //保存操作记录
  365. // await _azureStorage.SaveBILog("school-update", $"{replaceSchool.tmdName}【{replaceSchool.tmdId}】修改学校信息,学校和ID:{replaceSchool.school.name}【{replaceSchool.school.id}】", _dingDing, httpContext: HttpContext);
  366. // return Ok(new { state = 200, schoolInfo });
  367. //}
  368. //else return Ok(new { state = 400, message = "请求错误!" });
  369. }
  370. catch (Exception ex)
  371. {
  372. await _dingDing.SendBotMsg($"BI,{_option.Location} /batchschool/upd-school \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  373. return BadRequest();
  374. }
  375. }
  376. /// <summary>
  377. /// 顾问学校空间使用情况
  378. /// </summary>
  379. /// <param name="jsonElement"></param>
  380. /// <returns></returns>
  381. [HttpPost("get-assistspace")]
  382. public async Task<IActionResult> GetAssistSchoolSpace(JsonElement jsonElement)
  383. {
  384. if (!jsonElement.TryGetProperty("tmdId", out JsonElement tmdId)) return BadRequest();
  385. jsonElement.TryGetProperty("site", out JsonElement site);
  386. var cosmosClient = _azureCosmos.GetCosmosClient();
  387. if ($"{site}".Equals(BIConst.GlobalSite))
  388. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  389. List<string> schools = await CommonFind.FindSchoolIds(cosmosClient, $"{tmdId}");
  390. List<SchoolSpace> schoolSpaces = new();
  391. foreach (var sid in schools)
  392. {
  393. School school = new();
  394. var response = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync(sid, new PartitionKey("Base"));
  395. if (response.Status == 200)
  396. {
  397. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  398. school = json.ToObject<School>();
  399. }
  400. long teach = 0;
  401. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: $"SELECT sum(c.size) as size FROM c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{sid}") }))
  402. {
  403. var json = await JsonDocument.ParseAsync(item.ContentStream);
  404. foreach (var elmt in json.RootElement.GetProperty("Documents").EnumerateArray())
  405. {
  406. if (elmt.TryGetProperty("size", out JsonElement _size) && _size.ValueKind.Equals(JsonValueKind.Number))
  407. {
  408. teach = _size.GetInt32();
  409. break;
  410. }
  411. }
  412. }
  413. SchoolSpace schoolSpace = new() { id = sid, name = school != null ? school.name : sid };
  414. Space space = new Space();
  415. long blobsize = 0; //使用大小
  416. RedisValue value = default;
  417. value = _azureRedis.GetRedisClient(8).HashGet($"Blob:Record", sid);
  418. if (value != default && !value.IsNullOrEmpty)
  419. {
  420. JsonElement record = value.ToString().ToObject<JsonElement>();
  421. if (record.TryGetInt64(out blobsize))
  422. {
  423. }
  424. }
  425. else
  426. {
  427. var client = _azureStorage.GetBlobContainerClient(sid);
  428. var size = await client.GetBlobsCatalogSize();
  429. await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", sid, size.Item1);
  430. foreach (var key in size.Item2.Keys)
  431. {
  432. await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Blob:Catalog:{sid}", key);
  433. await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Blob:Catalog:{sid}", key, size.Item2[key].HasValue ? size.Item2[key].Value : 0);
  434. }
  435. space.useSize = (long)size.Item1; space.tSize = teach; space.catalogSize = size.Item2;
  436. schoolSpace.space = space;
  437. schoolSpaces.Add(schoolSpace);
  438. continue;
  439. }
  440. Dictionary<string, double?> catalog = new Dictionary<string, double?>();
  441. SortedSetEntry[] Scores = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Blob:Catalog:{sid}");
  442. if (Scores != null)
  443. {
  444. foreach (var score in Scores)
  445. {
  446. double val = score.Score;
  447. string key = score.Element.ToString();
  448. catalog.Add(key, val);
  449. }
  450. space.useSize = blobsize; space.tSize = teach; space.catalogSize = catalog;
  451. schoolSpace.space = space;
  452. schoolSpaces.Add(schoolSpace);
  453. continue;
  454. }
  455. else
  456. {
  457. var client = _azureStorage.GetBlobContainerClient(sid);
  458. var size = await client.GetBlobsCatalogSize();
  459. await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", sid, size.Item1);
  460. foreach (var key in size.Item2.Keys)
  461. {
  462. await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Blob:Catalog:{sid}", key);
  463. await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Blob:Catalog:{sid}", key, size.Item2[key].HasValue ? size.Item2[key].Value : 0);
  464. }
  465. space.useSize = (long)size.Item1;
  466. space.tSize = teach;
  467. space.catalogSize = size.Item2;
  468. schoolSpace.space = space;
  469. schoolSpaces.Add(schoolSpace);
  470. continue;
  471. }
  472. }
  473. return Ok(new { state = 200, schoolSpaces });
  474. }
  475. /// <summary>
  476. /// 移交学校顾问
  477. /// </summary>
  478. /// <param name="jsonElement"></param>
  479. /// <returns></returns>
  480. [HttpPost("get-shift")]
  481. public async Task<IActionResult> GetShift(JsonElement jsonElement)
  482. {
  483. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  484. if (!jsonElement.TryGetProperty("school", out JsonElement _school)) return BadRequest();
  485. //if (!jsonElement.TryGetProperty("teacher", out JsonElement _teacher)) return BadRequest();
  486. if (!jsonElement.TryGetProperty("shiftTeacher", out JsonElement _shiftTeacher)) return BadRequest();
  487. jsonElement.TryGetProperty("site", out JsonElement site);
  488. var cosmosClient = _azureCosmos.GetCosmosClient();
  489. var tableClient = _azureStorage.GetCloudTableClient();
  490. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  491. if ($"{site}".Equals(BIConst.GlobalSite))
  492. {
  493. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  494. tableClient = _azureStorage.GetCloudTableClient(BIConst.GlobalSite);
  495. blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.GlobalSite);
  496. }
  497. SchoolTeacher schoolTeacher = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemAsync<SchoolTeacher>($"{_tmdId}", new PartitionKey($"Teacher-{_school}"));
  498. if (schoolTeacher.roles.IsNotEmpty() && schoolTeacher.roles.Contains("assist"))
  499. {
  500. schoolTeacher.roles.Remove("assist");
  501. SchoolTeacher newSchoolTeacher = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemAsync<SchoolTeacher>($"{_shiftTeacher}", new PartitionKey($"Teacher-{_school}"));
  502. if (!newSchoolTeacher.roles.Contains("assist"))
  503. {
  504. newSchoolTeacher.roles.Add("assist");
  505. newSchoolTeacher = await cosmosClient.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<SchoolTeacher>(newSchoolTeacher, $"{_shiftTeacher}", new PartitionKey($"Teacher-{_school}"));
  506. }
  507. await cosmosClient.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<SchoolTeacher>(schoolTeacher, $"{_tmdId}", new PartitionKey($"Teacher-{_school}"));
  508. School schoolBase = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemAsync<School>($"{_school}", new PartitionKey($"Base"));
  509. //发送消息实体
  510. string shiftCode = "shift-assist";
  511. Notification notification = new Notification
  512. {
  513. hubName = "hita",
  514. type = "msg",
  515. from = $"BI:{_option.Location}:{_school}",
  516. to = new List<string> { $"{_shiftTeacher}" },
  517. label = $"{shiftCode}_school",
  518. body = new { location = _option.Location, biz = shiftCode, tmdid = $"{_tmdId}", tmdname = $"{_tmdName}", status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
  519. expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
  520. };
  521. if (notification != null)
  522. {
  523. var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
  524. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  525. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  526. var location = _option.Location;
  527. await _notificationService.SendNotification(clientID, clientSecret, location, url, notification);//站内发送消息
  528. }
  529. //保存操作记录
  530. //await _azureStorage.SaveBILog("schoolTeacher-add", $"{_tmdName}【{_tmdId}】移交顾问给{newSchoolTeacher.name}【{newSchoolTeacher.id}】", _dingDing, httpContext: HttpContext);
  531. await BIAzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "schoolTeacher-add", $"{_tmdName}【{_tmdId}】移交顾问给{newSchoolTeacher.name}【{newSchoolTeacher.id}】", _dingDing, httpContext: HttpContext);
  532. return Ok(new { state = 200 });
  533. }
  534. else { return Ok(new { status = 201, msg = $"{_tmdName}【{_tmdId}】账号不是顾问" }); }
  535. }
  536. /// <summary>
  537. /// 修改顾问学校
  538. /// </summary>
  539. /// <param name="jsonElement"></param>
  540. /// <returns></returns>
  541. [ProducesDefaultResponseType]
  542. [AuthToken(Roles = "admin,rdc")]
  543. [HttpPost("set-aistschool")]
  544. public async Task<IActionResult> SetAssistSchool(JsonElement jsonElement)
  545. {
  546. try
  547. {
  548. if (!jsonElement.TryGetProperty("partitionKey", out JsonElement parKey)) return BadRequest();
  549. jsonElement.TryGetProperty("userId", out JsonElement userId);
  550. jsonElement.TryGetProperty("tmdId", out JsonElement tmdId);
  551. if (!jsonElement.TryGetProperty("schoolIds", out JsonElement jsSchoolIds)) return BadRequest();
  552. if (!jsonElement.TryGetProperty("busy", out JsonElement busy)) return BadRequest();
  553. jsonElement.TryGetProperty("site", out JsonElement site);
  554. List<string> schoolIds = jsSchoolIds.ToObject<List<string>>();
  555. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  556. var cosmosClient = _azureCosmos.GetCosmosClient();
  557. string divide = _option.Location;
  558. if ($"{site}".Equals(BIConst.GlobalSite))
  559. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  560. Dictionary<string, object> dic = new() { { "PartitionKey", $"{parKey}" } };
  561. if (!string.IsNullOrEmpty($"{userId}"))
  562. {
  563. dic.Add("userId", $"{userId}");
  564. }
  565. if (string.IsNullOrEmpty($"{userId}") && string.IsNullOrEmpty($"{tmdId}"))
  566. {
  567. return Ok(new { state = 400, msg = "钉钉账户或醍摩豆账户需要至少要传一个!" });
  568. }
  569. Dictionary<string, List<string>> noSchools = new();
  570. List<DingDingUserInfo> ddUserInfoList = await table.FindListByDict<DingDingUserInfo>(dic);
  571. List<DingDingUserInfo> updUsers = new();
  572. if (ddUserInfoList.Count > 0)
  573. {
  574. foreach (var ddInfo in ddUserInfoList)
  575. {
  576. if (schoolIds.Count > 0)
  577. {
  578. if (string.IsNullOrEmpty(ddInfo.tmdId))
  579. {
  580. List<string> moblie = new() { $"{ddInfo.mobile}" };
  581. var content = new StringContent(moblie.ToJsonString(), Encoding.UTF8, "application/json");
  582. string json = await _coreAPIHttpService.GetUserInfos(content);
  583. if (!string.IsNullOrEmpty(json))
  584. {
  585. List<JsonElement> json_id = json.ToObject<List<JsonElement>>();
  586. foreach (var tmd in json_id)
  587. {
  588. ddInfo.tmdId = tmd.GetProperty("id").ToString();
  589. ddInfo.tmdName = tmd.GetProperty("name").ToString();
  590. ddInfo.tmdMobile = tmd.GetProperty("mobile").ToString();
  591. ddInfo.picture = tmd.GetProperty("picture").ToString();
  592. ddInfo.mail = tmd.GetProperty("mail").ToString();
  593. }
  594. }
  595. else return Ok(new { state = 404, msg = "依据钉钉手机号未找到醍摩豆账号!" });
  596. }
  597. List<string> noSchool = await SchoolWay.SchoolAdviser(cosmosClient, ddInfo, schoolIds, $"{busy}");
  598. if (noSchool.Count > 0)
  599. {
  600. noSchools.Add(ddInfo.tmdId, noSchool);
  601. }
  602. }
  603. List<string> userSchoolAdv = new(ddInfo.schoolIds.Split("|", StringSplitOptions.RemoveEmptyEntries));
  604. if ($"{busy}".Equals("add"))
  605. {
  606. userSchoolAdv.AddRange(schoolIds);
  607. ddInfo.schoolIds = userSchoolAdv.Count > 0 ? string.Join("|", userSchoolAdv) : "";
  608. }
  609. if ($"{busy}".Equals("del"))
  610. {
  611. var temp = userSchoolAdv.Where(p => !schoolIds.Any(x => x == p)).ToList();
  612. ddInfo.schoolIds = temp.Count > 0 ? string.Join("|", temp) : "";
  613. }
  614. updUsers.Add(ddInfo);
  615. }
  616. }
  617. updUsers = await table.SaveOrUpdateAll(updUsers);
  618. if (noSchools.Count > 0)
  619. return Ok(new { state = 201, recUsers = updUsers, noSchools });
  620. else
  621. return Ok(new { state = 200, recUsers = updUsers });
  622. }
  623. catch (Exception ex)
  624. {
  625. await _dingDing.SendBotMsg($"BI,{_option.Location} /batchschool/set-aistschool \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  626. return BadRequest();
  627. }
  628. }
  629. /// <summary>
  630. /// 依据学校ID查学校管理员信息
  631. /// </summary>
  632. /// <param name="jsonElement"></param>
  633. /// <returns></returns>
  634. [HttpPost("get-schoolmanage")]
  635. public async Task<IActionResult> GetSchoolManage(JsonElement jsonElement)
  636. {
  637. if (!jsonElement.TryGetProperty("schoolCode", out JsonElement schoolCode)) return BadRequest();
  638. if (!jsonElement.TryGetProperty("isAdmin", out JsonElement isAdmin)) return BadRequest();
  639. jsonElement.TryGetProperty("site", out JsonElement site);
  640. var cosmosClient = _azureCosmos.GetCosmosClient();
  641. if ($"{site}".Equals(BIConst.GlobalSite))
  642. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  643. List<SchoolTeacher> schoolTeachers = new List<SchoolTeacher>();
  644. //string sqlTxt = "select value(c) from c where array_contains(c.roles,'admin')";
  645. string sqlTxt = "select value(c) from c";
  646. await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: sqlTxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{schoolCode}") }))
  647. {
  648. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  649. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetInt16() > 0)
  650. {
  651. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  652. {
  653. SchoolTeacher schoolTeacher = obj.ToObject<SchoolTeacher>();
  654. //schoolTeachers.Add(schoolTeacher);
  655. if (bool.Parse($"{isAdmin}") == true)
  656. {
  657. if (schoolTeacher.roles.Contains("admin"))
  658. {
  659. schoolTeachers.Add(schoolTeacher);
  660. }
  661. }
  662. else
  663. {
  664. if (!schoolTeacher.roles.Contains("admin"))
  665. {
  666. schoolTeachers.Add(schoolTeacher);
  667. }
  668. }
  669. }
  670. }
  671. }
  672. return Ok(new { state = 200, schoolTeachers });
  673. }
  674. /// <summary>
  675. /// 设置学校管理员
  676. /// </summary>
  677. /// <param name="jsonElement"></param>
  678. /// <returns></returns>
  679. [HttpPost("set-schoolme")]
  680. public async Task<IActionResult> SetSchoolManage(JsonElement jsonElement)
  681. {
  682. try
  683. {
  684. var (_tmdId, _tmdName, _, _, _, _) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  685. if (!jsonElement.TryGetProperty("manageId", out JsonElement _adminTmdId)) return BadRequest();
  686. if (!jsonElement.TryGetProperty("manageName", out JsonElement _adminTmdName)) return BadRequest();
  687. if (!jsonElement.TryGetProperty("schoolId", out JsonElement _schoolId)) return BadRequest();
  688. jsonElement.TryGetProperty("site", out JsonElement site);
  689. var cosmosClient = _azureCosmos.GetCosmosClient();
  690. var tableClient = _azureStorage.GetCloudTableClient();
  691. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  692. if ($"{site}".Equals(BIConst.GlobalSite))
  693. {
  694. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  695. tableClient = _azureStorage.GetCloudTableClient(BIConst.GlobalSite);
  696. blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.GlobalSite);
  697. }
  698. var response = await cosmosClient.GetContainer("TEAMModelOS", "School").ReadItemStreamAsync($"{_adminTmdId}", new PartitionKey($"Teacher-{_schoolId}"));
  699. if (response.Status == 200)
  700. {
  701. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  702. SchoolTeacher schoolTeacher = json.ToObject<SchoolTeacher>();
  703. if (!schoolTeacher.roles.Contains("admin"))
  704. {
  705. schoolTeacher.roles.Add("admin");
  706. SchoolTeacher st = await cosmosClient.GetContainer("TEAMModelOS", "School").ReplaceItemAsync<SchoolTeacher>(schoolTeacher, schoolTeacher.id, new PartitionKey(schoolTeacher.code));
  707. //保存操作记录
  708. //await _azureStorage.SaveBILog("schoolTeacher-update", $"{_tmdName}【{_tmdId}】账户把{_adminTmdName}【{_adminTmdId}】设置学校id为{_schoolId}管理员。", _dingDing, httpContext: HttpContext);
  709. await BIAzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "schoolTeacher-update", $"{_tmdName}【{_tmdId}】账户把{_adminTmdName}【{_adminTmdId}】设置学校id为{_schoolId}管理员。", _dingDing, httpContext: HttpContext);
  710. return Ok(new { state = 200, schoolTeacher = st });
  711. }
  712. else
  713. return Ok(new { state = 201, schoolTeacher = "已经是管理人员" });
  714. }
  715. else
  716. {
  717. SchoolTeacher schoolTeacher = new SchoolTeacher
  718. {
  719. id = $"{_adminTmdId}",
  720. code = $"Teacher-{_schoolId}",
  721. roles = new List<string> { "admin" },
  722. job = "管理员",
  723. name = $"{_adminTmdName}",
  724. picture = "",
  725. status = "join",
  726. createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  727. pk = "Teacher",
  728. ttl = -1
  729. };
  730. schoolTeacher = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<SchoolTeacher>(schoolTeacher, new PartitionKey(schoolTeacher.code));
  731. //保存操作记录
  732. //await _azureStorage.SaveBILog("schoolTeacher-add", $"{_tmdName}【{_tmdId}】账户创建{_adminTmdName}【{_adminTmdId}】账户,并设学校管理员。学校ID:{_schoolId}。", _dingDing, httpContext: HttpContext);
  733. await BIAzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "schoolTeacher-add", $"{_tmdName}【{_tmdId}】账户创建{_adminTmdName}【{_adminTmdId}】账户,并设学校管理员。学校ID:{_schoolId}。", _dingDing, httpContext: HttpContext);
  734. return Ok(new { status = 200, schoolTeacher });
  735. }
  736. }
  737. catch (Exception ex)
  738. {
  739. await _dingDing.SendBotMsg($"BI,{_option.Location} /batchschool/set-schoolme \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  740. return BadRequest();
  741. }
  742. }
  743. /// <summary>
  744. /// 删除学校、学校相关的教师、学生
  745. /// </summary>
  746. /// <param name="jsonElement"></param>
  747. /// <returns></returns>
  748. [ProducesDefaultResponseType]
  749. [AuthToken(Roles = "admin,rdc")]
  750. [HttpPost("set-del")]
  751. public async Task<IActionResult> DelSchool(JsonElement jsonElement)
  752. {
  753. try
  754. {
  755. if (!jsonElement.TryGetProperty("schoolId", out JsonElement schoolId)) return BadRequest();
  756. jsonElement.TryGetProperty("site", out JsonElement site);
  757. string _auth = HttpContext.GetXAuth("AuthToken");
  758. var (tmdId, tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(_auth, _option);
  759. var cosmosClient = _azureCosmos.GetCosmosClient();
  760. var tableClient = _azureStorage.GetCloudTableClient();
  761. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  762. if ($"{site}".Equals(BIConst.GlobalSite))
  763. {
  764. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  765. tableClient = _azureStorage.GetCloudTableClient(BIConst.GlobalSite);
  766. blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.GlobalSite);
  767. }
  768. StringBuilder msg = new();
  769. List<DelSchoolRel> delSchoolRels = new();
  770. List<string> scTchIds = new();
  771. List<string> scStuIds = new();
  772. string scTecSql = $"select value(c.id) from c where ARRAY_LENGTH(c.roles) > 0 and c.status = 'join'";
  773. await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<string>(queryText: scTecSql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{schoolId}") }))
  774. {
  775. scTchIds.Add(item);
  776. }
  777. string scStuSql = $"select value(c.id) from c";
  778. await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryIterator<string>(queryText: scStuSql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-{schoolId}") }))
  779. {
  780. scStuIds.Add(item);
  781. }
  782. var response = await cosmosClient.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync($"{schoolId}", new PartitionKey($"Base"));
  783. if (response.Status == 204)
  784. msg.AppendLine($"{tmdName}【{tmdId}】删除学校,删除状态:{response.Status},删除ID:{schoolId}");
  785. else
  786. delSchoolRels.Add(new DelSchoolRel() { id = $"{schoolId}", code = "Base", type = 1, status = response.Status });
  787. foreach (var item in scTchIds)
  788. {
  789. var tchRespnse = await cosmosClient.GetContainer("TEAMModelOS", "School").DeleteItemStreamAsync($"{item}", new PartitionKey($"Teacher-{schoolId}"));
  790. if (tchRespnse.Status == 204)
  791. msg.AppendLine($"删除教师,删除状态:{tchRespnse.Status},删除ID:{item}");
  792. else
  793. delSchoolRels.Add(new DelSchoolRel() { id = $"{item}", code = $"Teacher-{schoolId}", type = 2, status = response.Status });
  794. }
  795. foreach (var item in scStuIds)
  796. {
  797. var stuRespnse = await cosmosClient.GetContainer("TEAMModelOS", "Student").DeleteItemStreamAsync($"{item}", new PartitionKey($"Base-{schoolId}"));
  798. if (stuRespnse.Status == 204)
  799. msg.AppendLine($"删除学生,删除状态:{stuRespnse.Status},删除ID:{item}");
  800. else
  801. delSchoolRels.Add(new DelSchoolRel() { id = $"{item}", code = $"Base-{schoolId}", type = 3, status = response.Status });
  802. }
  803. //保存操作记录
  804. //await _azureStorage.SaveBILog("set-del", msg.ToString(), _dingDing, httpContext: HttpContext);
  805. await BIAzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "set-del", msg.ToString(), _dingDing, httpContext: HttpContext);
  806. if (delSchoolRels.Count > 0)
  807. return Ok(new { state = 201, delSchoolRels });
  808. else
  809. return Ok(new { state = 200 });
  810. }
  811. catch (Exception ex)
  812. {
  813. await _dingDing.SendBotMsg($"BI,{_option.Location} /batchschool/set-del \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  814. return BadRequest();
  815. }
  816. }
  817. /// <summary>
  818. /// 通过学校Id查询详情 数据管理工具——查询工具
  819. /// </summary>
  820. /// <returns></returns>
  821. [HttpPost("get-info")]
  822. public async Task<IActionResult> GetSchool(JsonElement jsonElement)
  823. {
  824. jsonElement.TryGetProperty("schoolId", out JsonElement schoolId);
  825. jsonElement.TryGetProperty("site", out JsonElement site);
  826. var cosmosClient = _azureCosmos.GetCosmosClient();
  827. if ($"{site}".Equals(BIConst.GlobalSite))
  828. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  829. StringBuilder sqlTxt = new StringBuilder("select * from c");
  830. if (!string.IsNullOrEmpty($"{schoolId}"))
  831. {
  832. sqlTxt.Append($" where c.id='{schoolId}'");
  833. }
  834. List<School> schools = new();
  835. await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: sqlTxt.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
  836. {
  837. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  838. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  839. {
  840. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  841. {
  842. schools.Add(obj.ToObject<School>());
  843. }
  844. }
  845. }
  846. return Ok(new { state = 200, schools });
  847. }
  848. /// <summary>
  849. /// 依据区域Id查询区域空间统计
  850. /// </summary>
  851. /// <param name="jsonElement"></param>
  852. /// <returns></returns>
  853. [ProducesDefaultResponseType]
  854. [HttpPost("get-spance")]
  855. public async Task<IActionResult> GetAreaSpace(JsonElement jsonElement)
  856. {
  857. jsonElement.TryGetProperty("areaId", out JsonElement areaId);
  858. jsonElement.TryGetProperty("schoolId", out JsonElement schoolId);
  859. jsonElement.TryGetProperty("site", out JsonElement site);
  860. var cosmosClient = _azureCosmos.GetCosmosClient();
  861. if ($"{site}".Equals(BIConst.GlobalSite))
  862. cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  863. long allSize = 0; //全部大小
  864. int teacherSpace = 0; //学校分配给教师的空间
  865. long useSize = 0; //已使用大小
  866. Dictionary<string, double?> useSpaceInfo = new(); //学校使用详情
  867. //查询区域所有学校
  868. if (!string.IsNullOrEmpty($"{areaId}"))
  869. {
  870. List<string> schools = new();
  871. schools = await CommonFind.FindSchoolIds(cosmosClient, $"select c.id from c where c.areaId='{areaId}'", "Base");
  872. allSize = await CommonFind.FindTotals(cosmosClient, $"select sum(c.size) as totals from c where c.areaId='{areaId}'", new List<string> { "School" }); //区域所有学校空间
  873. foreach (var school in schools)
  874. {
  875. await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "School").GetItemQueryStreamIterator(queryText: $"SELECT sum(c.size) as size FROM c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Teacher-{school}") }))
  876. {
  877. var json = await JsonDocument.ParseAsync(item.ContentStream);
  878. foreach (var elmt in json.RootElement.GetProperty("Documents").EnumerateArray())
  879. {
  880. if (elmt.TryGetProperty("size", out JsonElement _size) && _size.ValueKind.Equals(JsonValueKind.Number))
  881. {
  882. teacherSpace += _size.GetInt32();
  883. break;
  884. }
  885. }
  886. }
  887. long blobsize = 0;
  888. RedisValue value = _azureRedis.GetRedisClient(8).HashGet($"Blob:Record", $"{school}");
  889. if (!value.IsNullOrEmpty)
  890. {
  891. JsonElement record = value.ToString().ToObject<JsonElement>();
  892. if (record.TryGetInt64(out blobsize))
  893. {
  894. }
  895. }
  896. else
  897. {
  898. var storageClient = _azureStorage.GetBlobContainerClient("school");
  899. var size = await storageClient.GetBlobsCatalogSize();
  900. await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", $"{school}", size.Item1);
  901. foreach (var key in size.Item2.Keys)
  902. {
  903. await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Bolb:Catalog:{school}", key);
  904. await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Bolb:Catalog:school", key, size.Item2[key].HasValue ? size.Item2[key].Value : 0);
  905. }
  906. useSize += size.Item1.Value;
  907. useSpaceInfo = useSpaceInfo.Concat(size.Item2).GroupBy(g => g.Key).ToDictionary(k => k.Key, k => k.Sum(kvp => kvp.Value)); //lamebda表达式
  908. //useSpaceInfo = (from e in useSpaceInfo.Concat(size.Item2) group e by e.Key into g select new { Name = g.Key, value = g.Sum(kvp => kvp.Value) }).ToDictionary(item => item.Name, item => item.value); //linq 方式合并
  909. }
  910. SortedSetEntry[] Scores = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Blob:Catalog:{school}");
  911. if (Scores != null)
  912. {
  913. Dictionary<string, double?> catalog = new();
  914. foreach (var score in Scores)
  915. {
  916. double val = score.Score;
  917. string key = score.Element.ToString();
  918. catalog.Add(key, val);
  919. }
  920. useSpaceInfo = useSpaceInfo.Concat(catalog).GroupBy(g => g.Key).ToDictionary(k => k.Key, k => k.Sum(kvp => kvp.Value)); //lamebda表达式
  921. //useSpaceInfo = (from e in useSpaceInfo.Concat(catalog) group e by e.Key into g select new { Name = g.Key, value = g.Sum(kvp => kvp.Value) }).ToDictionary(item => item.Name, item => item.value); //linq 方式合并
  922. }
  923. else
  924. {
  925. var client = _azureStorage.GetBlobContainerClient("school");
  926. var size = await client.GetBlobsCatalogSize();
  927. await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", $"{school}", size.Item1);
  928. foreach (var key in size.Item2.Keys)
  929. {
  930. await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Blob:Catalog:{school}", key);
  931. await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Blob:Catalog:{school}", key, size.Item2[key].HasValue ? size.Item2[key].Value : 0);
  932. }
  933. useSize += size.Item1.Value;
  934. useSpaceInfo = useSpaceInfo.Concat(size.Item2).GroupBy(g => g.Key).ToDictionary(k => k.Key, k => k.Sum(kvp => kvp.Value)); //lamebda表达式
  935. //useSpaceInfo = (from e in useSpaceInfo.Concat(size.Item2) group e by e.Key into g select new { Name = g.Key, value = g.Sum(kvp => kvp.Value) }).ToDictionary(item => item.Name, item => item.value); //linq 方式合并
  936. }
  937. }
  938. }
  939. //查询学校
  940. if (!string.IsNullOrEmpty($"{schoolId}"))
  941. {
  942. allSize = await CommonFind.FindTotals(cosmosClient, $"SELECT c.size as totals FROM c where c.id='{schoolId}'", "School", "Base");
  943. teacherSpace = await CommonFind.FindTotals(cosmosClient, $"SELECT sum(c.size) as totals FROM c", "School", $"Teacher-{schoolId}");
  944. long blobsize = 0;
  945. RedisValue value = _azureRedis.GetRedisClient(8).HashGet($"Blob:Record", $"{schoolId}");
  946. if (!value.IsNullOrEmpty)
  947. {
  948. JsonElement record = value.ToString().ToObject<JsonElement>();
  949. if (record.TryGetInt64(out blobsize))
  950. {
  951. useSize = blobsize;
  952. }
  953. }
  954. else
  955. {
  956. var storageClient = _azureStorage.GetBlobContainerClient("school");
  957. var size = await storageClient.GetBlobsCatalogSize();
  958. await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", $"{schoolId}", size.Item1);
  959. foreach (var key in size.Item2.Keys)
  960. {
  961. await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Bolb:Catalog:{schoolId}", key);
  962. await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Bolb:Catalog:school", key, size.Item2[key].HasValue ? size.Item2[key].Value : 0);
  963. }
  964. useSpaceInfo = size.Item2;
  965. }
  966. Dictionary<string, double?> catalog = new();
  967. SortedSetEntry[] Scores = _azureRedis.GetRedisClient(8).SortedSetRangeByScoreWithScores($"Blob:Catalog:{schoolId}");
  968. if (Scores != null)
  969. {
  970. foreach (var score in Scores)
  971. {
  972. double val = score.Score;
  973. string key = score.Element.ToString();
  974. catalog.Add(key, val);
  975. }
  976. useSpaceInfo = catalog;
  977. }
  978. else
  979. {
  980. var client = _azureStorage.GetBlobContainerClient("school");
  981. var size = await client.GetBlobsCatalogSize();
  982. await _azureRedis.GetRedisClient(8).HashSetAsync($"Blob:Record", $"{schoolId}", size.Item1);
  983. foreach (var key in size.Item2.Keys)
  984. {
  985. await _azureRedis.GetRedisClient(8).SortedSetRemoveAsync($"Blob:Catalog:{schoolId}", key);
  986. await _azureRedis.GetRedisClient(8).SortedSetIncrementAsync($"Blob:Catalog:{schoolId}", key, size.Item2[key].HasValue ? size.Item2[key].Value : 0);
  987. }
  988. useSize = size.Item1.Value;
  989. useSpaceInfo = size.Item2;
  990. }
  991. }
  992. return Ok(new { state = 200, allSize, useSize, teacherSpace, useSpaceInfo });
  993. }
  994. /// <summary>
  995. /// 未加入区域的学校
  996. /// </summary>
  997. public record NotAreaSchool
  998. {
  999. public string id { get; set; }
  1000. public string name { get; set; }
  1001. public string schoolCode { get; set; }
  1002. public string picture { get; set; }
  1003. public List<string> period { get; set; }
  1004. public string province { get; set; }
  1005. public string city { get; set; }
  1006. public string dist { get; set; }
  1007. public string areaId { get; set; }
  1008. public string standard { get; set; }
  1009. public List<ManyArea> manyAreas { get; set; } = new List<ManyArea>();
  1010. }
  1011. /// <summary>
  1012. /// 学校空间使用情况
  1013. /// </summary>
  1014. public record SchoolSpace
  1015. {
  1016. public string id { get; set; }
  1017. public string name { get; set; }
  1018. public Space space { get; set; }
  1019. }
  1020. /// <summary>
  1021. /// 空间
  1022. /// </summary>
  1023. public record Space
  1024. {
  1025. /// <summary>
  1026. /// 已使用空间
  1027. /// </summary>
  1028. public long useSize { get; set; }
  1029. /// <summary>
  1030. /// 分配教师空间
  1031. /// </summary>
  1032. public long tSize { get; set; }
  1033. /// <summary>
  1034. /// 空间类型
  1035. /// </summary>
  1036. public Dictionary<string, double?> catalogSize { get; set; }
  1037. }
  1038. public record DelSchoolRel
  1039. {
  1040. public string id { get; set; }
  1041. public string code { get; set; }
  1042. /// <summary>
  1043. /// 未删除的类型 1 学校 2教师 3学生
  1044. /// </summary>
  1045. public int type { get; set; }
  1046. public int status { get; set; }
  1047. }
  1048. }
  1049. }