SchoolRepController.cs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713
  1. using Microsoft.AspNetCore.Hosting;
  2. using Microsoft.AspNetCore.Http;
  3. using Microsoft.AspNetCore.Mvc;
  4. using Microsoft.Extensions.Configuration;
  5. using Microsoft.Extensions.Options;
  6. using System.Net.Http;
  7. using TEAMModelOS.SDK.DI;
  8. using TEAMModelOS.SDK;
  9. using TEAMModelOS.Models;
  10. using System.Threading.Tasks;
  11. using System.Text.Json;
  12. using System.IO;
  13. using TEAMModelBI.Models;
  14. using System.Collections.Generic;
  15. using System.Text;
  16. using TEAMModelOS.SDK.Extension;
  17. using System;
  18. using TEAMModelOS.SDK.Models;
  19. using Azure.Cosmos;
  20. using System.Linq;
  21. using TEAMModelOS.SDK.Context.Constant;
  22. using Pipelines.Sockets.Unofficial.Arenas;
  23. using TEAMModelBI.Tool;
  24. using TEAMModelOS.SDK.Models.Cosmos.BI.BISchool;
  25. using TEAMModelOS.SDK.Models.Cosmos.BI;
  26. using DocumentFormat.OpenXml.Math;
  27. using TEAMModelOS.SDK.Models.Service.BI;
  28. using TEAMModelBI.Tool.CosmosBank;
  29. using TEAMModelOS.SDK.Models.Service.BIStatsWay;
  30. using StackExchange.Redis;
  31. using System.Text.RegularExpressions;
  32. namespace TEAMModelBI.Controllers.RepairApi
  33. {
  34. [Route("sccholrep")]
  35. [ApiController]
  36. public class SchoolRepController : ControllerBase
  37. {
  38. private readonly AzureCosmosFactory _azureCosmos;
  39. private readonly DingDing _dingDing;
  40. private readonly Option _option;
  41. private readonly AzureStorageFactory _azureStorage;
  42. private readonly AzureRedisFactory _azureRedis;
  43. private readonly IConfiguration _configuration;
  44. private readonly CoreAPIHttpService _coreAPIHttpService;
  45. private readonly IWebHostEnvironment _environment; //读取文件
  46. private readonly IHttpClientFactory _httpClient;
  47. public SchoolRepController(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, IOptionsSnapshot<Option> option, AzureRedisFactory azureRedis, IConfiguration configuration, CoreAPIHttpService coreAPIHttpService, IHttpClientFactory httpClient, IWebHostEnvironment hostingEnvironment)
  48. {
  49. _azureCosmos = azureCosmos;
  50. _dingDing = dingDing;
  51. _azureStorage = azureStorage;
  52. _option = option?.Value;
  53. _azureRedis = azureRedis;
  54. _configuration = configuration;
  55. _coreAPIHttpService = coreAPIHttpService;
  56. _httpClient = httpClient;
  57. _environment = hostingEnvironment;
  58. }
  59. /// <summary>
  60. /// 添加新学段的学校
  61. /// </summary>
  62. /// <param name="jsonElement"></param>
  63. /// <returns></returns>
  64. [ProducesDefaultResponseType]
  65. [HttpPost("set-allscperiod")]
  66. public async Task<IActionResult> SetAllScPeriod(JsonElement jsonElement)
  67. {
  68. jsonElement.TryGetProperty("Language", out JsonElement Language);
  69. jsonElement.TryGetProperty("scId", out JsonElement scId);
  70. jsonElement.TryGetProperty("periodName", out JsonElement periodName);
  71. var cosmosClient = _azureCosmos.GetCosmosClient();
  72. var builder = $"{_environment.ContentRootPath}/JsonFile/Preset/LangSchoolConfig.json";
  73. StreamReader streamReader = new(new FileStream(builder, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.UTF8);
  74. StringBuilder stringBuilder = new();
  75. string text;
  76. while ((text = streamReader.ReadLine()) != null)
  77. {
  78. stringBuilder.Append(text.ToString());
  79. }
  80. streamReader.Close();
  81. string input = stringBuilder.ToString();
  82. List<SchoolConfig> schoolConfigs = input.ToObject<List<SchoolConfig>>();
  83. SchoolConfig schoolConfig = null;
  84. string Lang = string.Empty; //語系判斷用字串
  85. if (!string.IsNullOrEmpty($"{Language}"))
  86. schoolConfig = schoolConfigs.Find(x => x.Lang.Contains($"{Language}"));
  87. Lang = $"{Language}";
  88. if (schoolConfig == null)
  89. {
  90. //CN站
  91. if(_option.Location.Contains("china", StringComparison.OrdinalIgnoreCase)) {
  92. if ($"{Language}".Contains("en"))
  93. {
  94. schoolConfig = schoolConfigs.Find(x => x.Lang.Contains("en-US"));
  95. Lang = "en-US";
  96. }
  97. else
  98. {
  99. schoolConfig = schoolConfigs.Find(x => x.Lang.Contains("zh-CN"));
  100. Lang = "zh-CN";
  101. }
  102. }
  103. //GL站
  104. else
  105. {
  106. if ($"{Language}".Contains("tw", StringComparison.OrdinalIgnoreCase))
  107. {
  108. schoolConfig = schoolConfigs.Find(x => x.Lang.Contains("zh-TW"));
  109. Lang = "zh-TW";
  110. }
  111. else
  112. {
  113. schoolConfig = schoolConfigs.Find(x => x.Lang.Contains("en-US"));
  114. Lang = "en-US";
  115. }
  116. }
  117. }
  118. string campusId = Guid.NewGuid().ToString();
  119. //默認學段、通識科目、學前、语言 各語系名稱取得
  120. string scName = string.Empty;
  121. string subjectGeneral = string.Empty;
  122. string subjectLanage = string.Empty;
  123. string gradePreschool = string.Empty;
  124. switch (Lang)
  125. {
  126. case "zh-CN":
  127. scName = "默认学段";
  128. subjectGeneral = "通识";
  129. subjectLanage = "语言";
  130. gradePreschool = "学前";
  131. break;
  132. case "zh-TW":
  133. scName = "預設學段";
  134. subjectGeneral = "通識";
  135. subjectLanage = "語言";
  136. gradePreschool = "學前";
  137. break;
  138. case "en-US":
  139. scName = "Default period";
  140. subjectGeneral = "General Studies";
  141. subjectLanage = "Language";
  142. gradePreschool = "Preschool";
  143. break;
  144. }
  145. StringBuilder noPeriodScSql = new("SELECT DISTINCT value(c) FROM c ");
  146. List<School> allSc = new();
  147. List<string> scidList = new(); //更新的學校ID(回傳值)
  148. if (!string.IsNullOrEmpty($"{scId}"))
  149. noPeriodScSql.Append($" where c.id='{scId}'");
  150. else
  151. noPeriodScSql.Append($" join sp in c.period where c.code = 'Base' AND ( NOT IS_DEFINED(sp.grades) OR ARRAY_LENGTH(sp.grades) = 0 OR NOT IS_DEFINED(sp.subjects) OR ARRAY_LENGTH(sp.subjects) = 0 )");
  152. if (!string.IsNullOrEmpty($"{periodName}"))
  153. scName = $"{periodName}";
  154. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<School>(queryText: "select value(c) from c where c.code='Base' and c.period=[]", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
  155. {
  156. allSc.Add(item);
  157. }
  158. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<School>(queryText: noPeriodScSql.ToString(), requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
  159. {
  160. allSc.Add(item);
  161. }
  162. foreach (var school in allSc)
  163. {
  164. if (school.name.Contains("幼儿园") || school.name.Contains("幼稚園") || school.name.Contains("幼兒園") || school.name.Contains("kindergarten", StringComparison.OrdinalIgnoreCase) || school.name.Contains("preschool", StringComparison.OrdinalIgnoreCase))
  165. {
  166. List<Subject> newSubjects = new List<Subject>() {
  167. new Subject { id = Guid.NewGuid().ToString(), name = subjectLanage, type = 1 }
  168. };
  169. if (school.period.Count > 0)
  170. {
  171. List<Period> grades = school.period.FindAll(sg => sg.grades.Count == 0);
  172. foreach (Period grade in grades)
  173. {
  174. grade.grades = new List<string>() { gradePreschool };
  175. grade.gradeCount = grade.grades.Count;
  176. }
  177. List<Period> semesters = school.period.FindAll(sg => sg.semesters.Count == 0);
  178. foreach (Period semester in semesters)
  179. {
  180. semester.semesters = new List<Semester>() {
  181. new Semester { name = schoolConfig.semester[0].term, start = schoolConfig.semester[0].start, month = schoolConfig.semester[0].month, day = schoolConfig.semester[0].day, id = Guid.NewGuid().ToString() },
  182. new Semester { name = schoolConfig.semester[1].term, start = schoolConfig.semester[1].start, month = schoolConfig.semester[1].month, day = schoolConfig.semester[1].day, id = Guid.NewGuid().ToString() }
  183. };
  184. semester.semesterCount = semester.semesters.Count;
  185. }
  186. List<Period> subjects = school.period.FindAll(sg => sg.subjects.Count == 0);
  187. foreach (Period subject in subjects)
  188. {
  189. subject.subjects = newSubjects;
  190. subject.subjectCount = subject.subjects.Count;
  191. }
  192. }
  193. else
  194. {
  195. if (school.campuses.Count > 0)
  196. campusId = school.campuses.Select(x => x.id).FirstOrDefault().ToString();
  197. school.period.Add(new Period
  198. {
  199. id = Guid.NewGuid().ToString(),
  200. name = scName,
  201. grades = new List<string>() { gradePreschool },
  202. campusId = campusId,
  203. subjects = newSubjects,
  204. semesters = new List<Semester>() {
  205. new Semester { name = schoolConfig.semester[0].term, start = schoolConfig.semester[0].start, month = schoolConfig.semester[0].month, day = schoolConfig.semester[0].day, id = Guid.NewGuid().ToString() },
  206. new Semester { name = schoolConfig.semester[1].term, start = schoolConfig.semester[1].start, month = schoolConfig.semester[1].month, day = schoolConfig.semester[1].day, id = Guid.NewGuid().ToString() }
  207. },
  208. gradeCount = 1,
  209. semesterCount = 2,
  210. subjectCount = newSubjects.Count,
  211. });
  212. if (!school.campuses.Select(x => x.id).Contains(campusId))
  213. school.campuses.Add(new Campus { name = school.name, id = campusId });
  214. }
  215. }
  216. else
  217. {
  218. if (school.period.Count > 0)
  219. {
  220. List<Period> grades = school.period.FindAll(sg => sg.grades.Count == 0);
  221. foreach (Period grade in grades)
  222. {
  223. grade.grades = schoolConfig.grades;
  224. grade.gradeCount = schoolConfig.grades.Count;
  225. }
  226. List<Period> semesters = school.period.FindAll(sg => sg.semesters.Count == 0);
  227. foreach (Period semester in semesters)
  228. {
  229. semester.semesters = new List<Semester>()
  230. {
  231. new Semester { name = schoolConfig.semester[0].term, start = schoolConfig.semester[0].start, month = schoolConfig.semester[0].month, day = schoolConfig.semester[0].day, id = Guid.NewGuid().ToString() },
  232. new Semester { name = schoolConfig.semester[1].term, start = schoolConfig.semester[1].start, month = schoolConfig.semester[1].month, day = schoolConfig.semester[1].day, id = Guid.NewGuid().ToString() }
  233. };
  234. semester.semesterCount = semester.semesters.Count;
  235. }
  236. List<Period> subjects = school.period.FindAll(sg => sg.subjects.Count == 0);
  237. foreach (Period subject in subjects)
  238. {
  239. subject.subjects = (school.type.Equals(2)) ? new List<Subject>() //高教
  240. {
  241. new Subject { id=Guid.NewGuid().ToString(),name=subjectGeneral,type=1 }
  242. } : new List<Subject>() //普教
  243. {
  244. new Subject { id=Guid.NewGuid().ToString(),name=schoolConfig.PresetSubject[0].name,type=schoolConfig.PresetSubject[0].type },
  245. new Subject { id=Guid.NewGuid().ToString(),name=schoolConfig.PresetSubject[1].name,type=schoolConfig.PresetSubject[1].type },
  246. new Subject { id=Guid.NewGuid().ToString(),name=schoolConfig.PresetSubject[2].name,type=schoolConfig.PresetSubject[2].type }
  247. };
  248. subject.subjectCount = subject.subjects.Count;
  249. }
  250. }
  251. else
  252. {
  253. if (school.campuses.Count > 0)
  254. campusId = school.campuses.Select(x => x.id).FirstOrDefault().ToString();
  255. school.period.Add(new Period
  256. {
  257. id = Guid.NewGuid().ToString(),
  258. name = scName,
  259. campusId = campusId,
  260. semesters = new List<Semester>() {
  261. new Semester { name = schoolConfig.semester[0].term, start = schoolConfig.semester[0].start, month = schoolConfig.semester[0].month, day = schoolConfig.semester[0].day, id = Guid.NewGuid().ToString() },
  262. new Semester { name = schoolConfig.semester[1].term, start = schoolConfig.semester[1].start, month = schoolConfig.semester[1].month, day = schoolConfig.semester[1].day, id = Guid.NewGuid().ToString() }
  263. },
  264. subjects = (school.type.Equals(2)) ? new List<Subject>() { //高教
  265. new Subject { id=Guid.NewGuid().ToString(),name=subjectGeneral,type=1 },
  266. } : new List<Subject>() { //普教
  267. new Subject { id=Guid.NewGuid().ToString(),name=schoolConfig.PresetSubject[0].name,type=schoolConfig.PresetSubject[0].type },
  268. new Subject { id=Guid.NewGuid().ToString(),name=schoolConfig.PresetSubject[1].name,type=schoolConfig.PresetSubject[1].type },
  269. new Subject { id=Guid.NewGuid().ToString(),name=schoolConfig.PresetSubject[2].name,type=schoolConfig.PresetSubject[2].type }
  270. },
  271. grades = schoolConfig.grades,
  272. analysis = new Analysis()
  273. {
  274. type = new List<ExamSimple>() {
  275. new ExamSimple { id = Guid.NewGuid().ToString(), name = schoolConfig.PresetExam[0].type[0].name },
  276. new ExamSimple { id = Guid.NewGuid().ToString(), name = schoolConfig.PresetExam[0].type[1].name },
  277. new ExamSimple { id = Guid.NewGuid().ToString(), name = schoolConfig.PresetExam[0].type[2].name },
  278. new ExamSimple { id = Guid.NewGuid().ToString(), name = schoolConfig.PresetExam[0].type[3].name }
  279. },
  280. income = schoolConfig.PresetExam[0].income,
  281. eugenics = schoolConfig.PresetExam[0].eugenics,
  282. touch = schoolConfig.PresetExam[0].touch
  283. },
  284. gradeCount = schoolConfig.grades.Count,
  285. semesterCount = schoolConfig.semester.Count,
  286. subjectCount = (school.type.Equals(2)) ? 1 : schoolConfig.PresetSubject.Count
  287. });
  288. if (!school.campuses.Select(x => x.id).Contains(campusId))
  289. school.campuses.Add(new Campus { name = school.name, id = campusId });
  290. }
  291. }
  292. School rSchool = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<School>(school, school.id, new PartitionKey("Base"));
  293. scidList.Add(rSchool.id);
  294. }
  295. return Ok(new { state = RespondCode.Ok, ids = scidList });
  296. }
  297. /// <summary>
  298. /// 新增学校学段(多个)
  299. /// </summary>
  300. /// <param name="jsonElement"></param>
  301. /// <returns></returns>
  302. [ProducesDefaultResponseType]
  303. [HttpPost("set-scperiod")]
  304. public async Task<IActionResult> SetScPeriod(JsonElement jsonElement)
  305. {
  306. if (!jsonElement.TryGetProperty("scId", out JsonElement scId)) return BadRequest();
  307. if (!jsonElement.TryGetProperty("periodName", out JsonElement periodName)) return BadRequest();
  308. List<string> periodNames = $"{periodName}".ToObject<List<string>>();
  309. jsonElement.TryGetProperty("Language", out JsonElement Language);
  310. var cosmosClient = _azureCosmos.GetCosmosClient();
  311. var builder = $"{_environment.ContentRootPath}/JsonFile/Preset/LangSchoolConfig.json";
  312. StreamReader streamReader = new(new FileStream(builder, FileMode.Open, FileAccess.Read, FileShare.ReadWrite), Encoding.UTF8);
  313. StringBuilder stringBuilder = new();
  314. string text;
  315. while ((text = streamReader.ReadLine()) != null)
  316. {
  317. stringBuilder.Append(text.ToString());
  318. }
  319. streamReader.Close();
  320. string input = stringBuilder.ToString();
  321. List<SchoolConfig> schoolConfigs = input.ToObject<List<SchoolConfig>>();
  322. SchoolConfig schoolConfig = null;
  323. if (!string.IsNullOrEmpty($"{Language}"))
  324. schoolConfig = schoolConfigs.Find(x => x.Lang.Contains($"{Language}"));
  325. if (schoolConfig == null)
  326. {
  327. if ($"{Language}".Contains("en"))
  328. schoolConfig = schoolConfigs.Find(x => x.Lang.Contains("en-US"));
  329. else
  330. schoolConfig = schoolConfigs.Find(x => x.Lang.Contains("zh-CN"));
  331. }
  332. string campusId = Guid.NewGuid().ToString();
  333. School school = null;
  334. school = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>($"{scId}", new PartitionKey("Base"));
  335. if (school != null)
  336. {
  337. foreach (var item in periodNames)
  338. {
  339. if (school.campuses.Count > 0)
  340. campusId = school.campuses.Select(x => x.id).FirstOrDefault().ToString();
  341. school.period.Add(new Period
  342. {
  343. id = Guid.NewGuid().ToString(),
  344. name = item,
  345. campusId = campusId,
  346. semesters = new List<Semester>() { new Semester { name = schoolConfig.semester[0].term, start = schoolConfig.semester[0].start, month = schoolConfig.semester[0].month, day = schoolConfig.semester[0].day, id = Guid.NewGuid().ToString() },
  347. new Semester { name = schoolConfig.semester[1].term, start = schoolConfig.semester[1].start, month = schoolConfig.semester[1].month, day = schoolConfig.semester[1].day, id = Guid.NewGuid().ToString() } },
  348. subjects = new List<Subject>() {
  349. new Subject { id=Guid.NewGuid().ToString(),name=schoolConfig.PresetSubject[0].name,type=schoolConfig.PresetSubject[0].type },
  350. new Subject { id=Guid.NewGuid().ToString(),name=schoolConfig.PresetSubject[1].name,type=schoolConfig.PresetSubject[1].type },
  351. new Subject { id=Guid.NewGuid().ToString(),name=schoolConfig.PresetSubject[2].name,type=schoolConfig.PresetSubject[2].type }
  352. },
  353. grades = schoolConfig.grades,
  354. analysis = new Analysis()
  355. {
  356. type = new List<ExamSimple>() { new ExamSimple { id = Guid.NewGuid().ToString(), name = schoolConfig.PresetExam[0].type[0].name },
  357. new ExamSimple { id = Guid.NewGuid().ToString(), name = schoolConfig.PresetExam[0].type[1].name },
  358. new ExamSimple { id = Guid.NewGuid().ToString(), name = schoolConfig.PresetExam[0].type[2].name },
  359. new ExamSimple { id = Guid.NewGuid().ToString(), name = schoolConfig.PresetExam[0].type[3].name } },
  360. income = schoolConfig.PresetExam[0].income,
  361. eugenics = schoolConfig.PresetExam[0].eugenics,
  362. touch = schoolConfig.PresetExam[0].touch
  363. }
  364. });
  365. }
  366. if (!school.campuses.Select(x => x.id).Contains(campusId))
  367. school.campuses.Add(new Campus { name = school.name, id = campusId });
  368. }
  369. school = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<School>(school, school.id, new PartitionKey("Base"));
  370. return Ok(new { state = RespondCode.Ok, school });
  371. }
  372. /// <summary>
  373. /// 学校信息中间件查询和修复接口
  374. /// </summary>
  375. /// <param name="jsonElement"></param>
  376. /// <returns></returns>
  377. [ProducesDefaultResponseType]
  378. [HttpPost("set-allscinfos")]
  379. public async Task<IActionResult> SetAllScInfos(JsonElement jsonElement)
  380. {
  381. try
  382. {
  383. jsonElement.TryGetProperty("scId", out JsonElement scId);
  384. var cosmosClient = _azureCosmos.GetCosmosClient();
  385. List<string> scIds = new();
  386. if (!string.IsNullOrEmpty($"{scId}"))
  387. scIds.Add($"{scId}");
  388. else
  389. scIds = await CommonFind.FindScIds(cosmosClient, "select value(c.id) from c ", "Base");
  390. List<BIRelation> scInfos = new();
  391. foreach (var itemId in scIds)
  392. {
  393. BIRelation bIRelation = null;
  394. var resRel = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(itemId, new PartitionKey("BIRel"));
  395. if (resRel.Status == 200)
  396. {
  397. continue;
  398. //using var fileJson = await JsonDocument.ParseAsync(resRel.ContentStream);
  399. //bIRelation = fileJson.ToObject<BIRelation>();
  400. }
  401. else
  402. {
  403. ScBaseInfo scBaseInfo = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<ScBaseInfo>(itemId, new PartitionKey("Base"));
  404. string areaName = null;
  405. if (!string.IsNullOrEmpty(scBaseInfo.areaId))
  406. {
  407. await foreach (var itemName in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<string>(queryText: $"select value(c.name) from c where c.pk='Area' and c.id='{scBaseInfo.areaId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base-Area") }))
  408. {
  409. areaName = itemName;
  410. }
  411. }
  412. bIRelation = new BIRelation()
  413. {
  414. id = scBaseInfo.id,
  415. name = scBaseInfo.name,
  416. picture = scBaseInfo.picture,
  417. size = scBaseInfo.size,
  418. createDate = scBaseInfo.createTime,
  419. region = scBaseInfo.region,
  420. province = scBaseInfo.province,
  421. city = scBaseInfo.city,
  422. dist = scBaseInfo.dist,
  423. address = scBaseInfo.address,
  424. areaId = scBaseInfo.areaId,
  425. scale = scBaseInfo.scale,
  426. areaName = areaName,
  427. upDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
  428. };
  429. var response = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(itemId, new PartitionKey("ProductSum"));
  430. if (response.Status == 200)
  431. {
  432. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  433. if (json.RootElement.TryGetProperty("serial", out JsonElement serial) && !serial.ValueKind.Equals(JsonValueKind.Null))
  434. {
  435. List<string> serials = serial.ToObject<List<SchoolProductSumData>>().Select(x => x.prodCode).ToList();
  436. bIRelation.serial = serials;
  437. }
  438. if (json.RootElement.TryGetProperty("service", out JsonElement service) && !service.ValueKind.Equals(JsonValueKind.Null))
  439. {
  440. List<string> services = service.ToObject<List<SchoolProductSumData>>().Select(x => x.prodCode).ToList();
  441. bIRelation.service = services;
  442. }
  443. if (json.RootElement.TryGetProperty("hard", out JsonElement hard) && !hard.ValueKind.Equals(JsonValueKind.Null))
  444. {
  445. List<string> hards = hard.ToObject<List<SchoolProductSumDataHard>>().Select(x => x.prodCode).ToList();
  446. bIRelation.hard = hards;
  447. }
  448. }
  449. bIRelation = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<BIRelation>(bIRelation, new PartitionKey("BIRel"));
  450. }
  451. scInfos.Add(bIRelation);
  452. }
  453. return Ok(new { state = RespondCode.Ok, cnt = scIds.Count, scInfos });
  454. }
  455. catch (Exception ex)
  456. {
  457. await _dingDing.SendBotMsg($"BI,{_option.Location},/sccholrep/set-allscinfos \n{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  458. return BadRequest();
  459. }
  460. }
  461. /// <summary>
  462. /// 修复所有学校统计数据中间件接口
  463. /// </summary>
  464. /// <param name="jsonElement"></param>
  465. /// <returns></returns>
  466. [ProducesDefaultResponseType]
  467. [HttpPost("set-allscstats")]
  468. public async Task<IActionResult> SetAllScStats(JsonElement jsonElement)
  469. {
  470. string id = "";
  471. try
  472. {
  473. jsonElement.TryGetProperty("scId", out JsonElement scId);
  474. jsonElement.TryGetProperty("year", out JsonElement _year);
  475. var cosmosClient = _azureCosmos.GetCosmosClient();
  476. var redisClinet = _azureRedis.GetRedisClient(8);
  477. List<string> scIds = new();
  478. if (!string.IsNullOrEmpty($"{scId}"))
  479. scIds.Add($"{scId}");
  480. else
  481. scIds = await CommonFind.FindScIds(cosmosClient, "select value(c.id) from c ", "Base");
  482. DateTimeOffset dateTime = DateTimeOffset.UtcNow;
  483. int year = dateTime.Year;
  484. if (!string.IsNullOrEmpty($"{_year}"))
  485. {
  486. year = _year.GetInt32();
  487. dateTime = dateTime.AddYears(-1);
  488. }
  489. List<StatsInfo> statsInfos = new();
  490. List<Task<ItemResponse<StatsInfo>>> taskStss = new();
  491. foreach (var sc in scIds)
  492. {
  493. id = sc;
  494. StatsInfo statsInfo = new();
  495. var scDataStats = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReadItemStreamAsync($"{year}-{sc}", new PartitionKey("Statistics"));
  496. if (scDataStats.Status == 200)
  497. {
  498. using var fileJson = await JsonDocument.ParseAsync(scDataStats.ContentStream);
  499. statsInfo = fileJson.ToObject<StatsInfo>();
  500. }
  501. else
  502. {
  503. statsInfo.id = $"{year}-{sc}";
  504. }
  505. statsInfo = await SchoolStatsWay.GetSingleSc(cosmosClient, redisClinet, sc, year);
  506. statsInfo.witRoom = ((int)await SchoolStatsWay.GetShoolWisdomRoomCount(_azureCosmos, _azureRedis, _configuration, _httpClient, _dingDing, statsInfo.schoolId));
  507. if (scDataStats.Status == 200)
  508. taskStss.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").ReplaceItemAsync<StatsInfo>(statsInfo, $"{year}-{sc}", new PartitionKey("Statistics")));
  509. else
  510. taskStss.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Common").CreateItemAsync<StatsInfo>(statsInfo, new PartitionKey("Statistics")));
  511. //statsInfo = await StatsWay.upSingleSc(cosmosClient, sc);
  512. statsInfos.Add(statsInfo);
  513. }
  514. if (taskStss.Count < 256)
  515. await Task.WhenAll(taskStss);
  516. else
  517. {
  518. int pages = (taskStss.Count + 255) / 256;
  519. for (int i = 0; i < pages; i++)
  520. {
  521. List<Task<ItemResponse<StatsInfo>>> temTaskStss = taskStss.Skip(i * 256).Take(256).ToList();
  522. await Task.WhenAll(temTaskStss);
  523. }
  524. }
  525. return Ok(new { state = RespondCode.Ok, statsInfos });
  526. }
  527. catch (Exception ex)
  528. {
  529. await _dingDing.SendBotMsg($"BI,{_option.Location},/sccholrep/set-allscstats 学校id:{id} \n{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  530. return BadRequest();
  531. }
  532. }
  533. /// <summary>
  534. /// 取得IOT所有資料並生成每日學校產品分析統計data
  535. /// </summary>
  536. /// <returns></returns>
  537. [ProducesDefaultResponseType]
  538. [HttpPost("set-allProdAnalysis")]
  539. public async Task<IActionResult> SetAllProdAnalysis()
  540. {
  541. var _azureCosmosClient = _azureCosmos.GetCosmosClient();
  542. var _azureCosmosClientCsv2 = _azureCosmos.GetCosmosClient(name: "CoreServiceV2");
  543. var _azureCosmosClientCsv2Read = _azureCosmos.GetCosmosClient(name: "CoreServiceV2CnRead");
  544. var datetime = DateTimeOffset.UtcNow;
  545. var y = $"{datetime.Year}";
  546. var redisClinet2 = _azureRedis.GetRedisClient(2);
  547. var keys = new HashSet<RedisKey>();
  548. int nextCursor = 0;
  549. do
  550. {
  551. RedisResult redisResult = redisClinet2.Execute("SCAN", nextCursor.ToString(), "MATCH", "TeachingData:*", "COUNT", "1000");
  552. var innerResult = (RedisResult[])redisResult;
  553. nextCursor = int.Parse((string)innerResult[0]);
  554. List<RedisKey> resultLines = ((RedisKey[])innerResult[1]).ToList();
  555. keys.UnionWith(resultLines);
  556. }
  557. while (nextCursor != 0);
  558. List<string> resultKeys = new List<string>();
  559. if(keys.Count > 0)
  560. {
  561. foreach(RedisKey key in keys)
  562. {
  563. string date = $"{key}".Replace("TeachingData:", "");
  564. Regex rgx = new Regex(@"[0-9]{4}");
  565. if (rgx.IsMatch(date))
  566. {
  567. string m = date.Substring(0, 2);
  568. string d = date.Substring(2, 2);
  569. await BIProdAnalysis.BICreatDailyAnalData(_azureRedis, _azureCosmosClient, _azureCosmosClientCsv2, _azureCosmosClientCsv2Read, _dingDing, y, m, d);
  570. resultKeys.Add($"{key}");
  571. }
  572. }
  573. }
  574. return Ok(new { state = RespondCode.Ok, keys = resultKeys });
  575. }
  576. /// <summary>
  577. /// 比較IES5學校Base與BIRel中間件的scale、size,若不一致則將學校的Base的數值寫入BIRel
  578. /// </summary>
  579. /// <returns></returns>
  580. [ProducesDefaultResponseType]
  581. [HttpPost("set-schoolBaseToBIRel")]
  582. public async Task<IActionResult> SetSchoolBaseToBIRel(JsonElement jsonElement)
  583. {
  584. string mode = (jsonElement.TryGetProperty("mode", out JsonElement modeJob)) ? modeJob.GetString() : "0"; // 執行模式 "0":測試 "1":執行 預設值:測試
  585. List<string> scIds = (jsonElement.TryGetProperty("scId", out JsonElement scId)) ? scId.ToObject<List<string>>() : new List<string>(); // 學校ID(array)
  586. var cosmosClient = _azureCosmos.GetCosmosClient();
  587. string schIdListStr = JsonSerializer.Serialize(scIds);
  588. //取得IES5學校Base
  589. Dictionary<string, SimpleSchoolInfo> schBaseDic = new Dictionary<string, SimpleSchoolInfo>();
  590. string qry = "SELECT c.id, c.name, c.scale, c.size FROM c";
  591. string where = string.Empty;
  592. if (scIds.Count > 0)
  593. {
  594. where += (string.IsNullOrWhiteSpace(where)) ? " WHERE " : " AND ";
  595. where += $"ARRAY_CONTAINS({schIdListStr}, c.id, true)";
  596. }
  597. qry = $"{qry}{where}";
  598. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: qry, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  599. {
  600. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  601. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  602. {
  603. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  604. {
  605. SimpleSchoolInfo schRow = obj.ToObject<SimpleSchoolInfo>();
  606. schBaseDic.Add(schRow.id, schRow);
  607. }
  608. }
  609. }
  610. //取得IES5學校BIRel中間件
  611. Dictionary<string, SimpleSchoolInfo> updSchBIRel = new Dictionary<string, SimpleSchoolInfo>(); //回傳值 更新的學校BIRel資訊
  612. if (schBaseDic.Count > 0)
  613. {
  614. string qryBIRel = "SELECT * FROM c";
  615. string whereBIRel = string.Empty;
  616. if (scIds.Count > 0)
  617. {
  618. whereBIRel += (string.IsNullOrWhiteSpace(whereBIRel)) ? " WHERE " : " AND ";
  619. whereBIRel += $"ARRAY_CONTAINS({schIdListStr}, c.id, true)";
  620. }
  621. qryBIRel = $"{qryBIRel}{whereBIRel}";
  622. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryStreamIterator(queryText: qryBIRel, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"BIRel") }))
  623. {
  624. using var json = await JsonDocument.ParseAsync(item.ContentStream);
  625. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetUInt16() > 0)
  626. {
  627. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  628. {
  629. bool updFlg = false;
  630. BIRelation schBIRelRow = obj.ToObject<BIRelation>();
  631. if (schBaseDic.ContainsKey(schBIRelRow.id))
  632. {
  633. //size比對
  634. if (!schBIRelRow.size.Equals(schBaseDic[schBIRelRow.id].size))
  635. {
  636. schBIRelRow.size = schBaseDic[schBIRelRow.id].size;
  637. updFlg = true;
  638. }
  639. //scale比對
  640. if (!schBIRelRow.scale.Equals(schBaseDic[schBIRelRow.id].scale))
  641. {
  642. schBIRelRow.scale = schBaseDic[schBIRelRow.id].scale;
  643. updFlg = true;
  644. }
  645. //更新
  646. if (updFlg)
  647. {
  648. if(mode.Equals("1")) await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<BIRelation>(schBIRelRow, schBIRelRow.id, new PartitionKey("BIRel"));
  649. updSchBIRel.Add(schBIRelRow.id, schBaseDic[schBIRelRow.id]);
  650. }
  651. }
  652. }
  653. }
  654. }
  655. }
  656. return Ok(new { state = RespondCode.Ok, updSchBIRel });
  657. }
  658. private class SimpleSchoolInfo
  659. {
  660. public string id { get; set; }
  661. public string name { get; set; }
  662. public int scale { get; set; }
  663. public int size { get; set; }
  664. }
  665. }
  666. }