SchoolRepController.cs 40 KB

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