SchoolController.cs 55 KB

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