SchoolController.cs 53 KB

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