BatchAreaController.cs 77 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.AspNetCore.Mvc;
  3. using Microsoft.Extensions.Configuration;
  4. using Microsoft.Extensions.Options;
  5. using System;
  6. using System.Collections.Generic;
  7. using System.Linq;
  8. using System.Threading.Tasks;
  9. using TEAMModelOS.Models;
  10. using TEAMModelOS.SDK.DI;
  11. using TEAMModelOS.SDK.Models;
  12. using Azure.Cosmos;
  13. using System.Text.Json;
  14. using HTEXLib.COMM.Helpers;
  15. using TEAMModelOS.SDK.Models.Cosmos.Common;
  16. using TEAMModelOS.SDK.Models.Cosmos.BI;
  17. using Azure.Messaging.ServiceBus;
  18. using TEAMModelOS.SDK.Extension;
  19. using TEAMModelBI.Filter;
  20. using TEAMModelBI.Tool.Extension;
  21. using TEAMModelBI.Tool;
  22. using Azure.Storage.Blobs.Models;
  23. using Azure;
  24. using Azure.Storage.Blobs.Specialized;
  25. using System.Net.Http;
  26. using System.Net.Http.Json;
  27. using System.Net;
  28. using TEAMModelOS.SDK;
  29. using TEAMModelOS.SDK.Context.BI;
  30. using TEAMModelOS.SDK.DI.CoreAPI;
  31. using System.Text;
  32. using DocumentFormat.OpenXml.Bibliography;
  33. using Microsoft.Extensions.Hosting;
  34. using Microsoft.AspNetCore.Hosting;
  35. using static TEAMModelBI.Controllers.RepairApi.InitialAreaController;
  36. using TEAMModelOS.SDK.Context.Constant;
  37. namespace TEAMModelBI.Controllers.BINormal
  38. {
  39. [Route("batcharea")]
  40. [ApiController]
  41. public class BatchAreaController : ControllerBase
  42. {
  43. private readonly AzureCosmosFactory _azureCosmos;
  44. private readonly DingDing _dingDing;
  45. private readonly Option _option;
  46. private readonly AzureStorageFactory _azureStorage;
  47. private readonly IConfiguration _configuration;
  48. private readonly NotificationService _notificationService;
  49. private readonly AzureServiceBusFactory _serviceBus;
  50. private readonly IHttpClientFactory _http;
  51. private readonly CoreAPIHttpService _coreAPIHttpService;
  52. private readonly IWebHostEnvironment _environment; //读取文件
  53. public BatchAreaController(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, IOptionsSnapshot<Option> option, IConfiguration configuration, NotificationService notificationService, AzureServiceBusFactory serviceBus, IHttpClientFactory http, CoreAPIHttpService coreAPIHttpService, IWebHostEnvironment hostingEnvironment)
  54. {
  55. _azureCosmos = azureCosmos;
  56. _dingDing = dingDing;
  57. _azureStorage = azureStorage;
  58. _option = option?.Value;
  59. _configuration = configuration;
  60. _notificationService = notificationService;
  61. _serviceBus = serviceBus;
  62. _http = http;
  63. _coreAPIHttpService = coreAPIHttpService;
  64. _environment = hostingEnvironment;
  65. }
  66. /// <summary>
  67. /// 查询所有的区域标准 //已对接
  68. /// </summary>
  69. /// <returns></returns>
  70. [ProducesDefaultResponseType]
  71. [HttpPost("get-areas")]
  72. public async Task<IActionResult> GetArea(JsonElement jsonElement)
  73. {
  74. try
  75. {
  76. jsonElement.TryGetProperty("id", out JsonElement id);
  77. jsonElement.TryGetProperty("name", out JsonElement name);
  78. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  79. int? pageSize = 100; //默认不指定返回大小
  80. string continuationToken = string.Empty; //返给前端分页token
  81. string pageToken = default;//接受前端的分页Tolen
  82. bool iscontinuation = false;//是否需要进行分页查询,默认不分页
  83. if (jsonElement.TryGetProperty("pageSize", out JsonElement jsonPageSize))
  84. {
  85. if (!jsonPageSize.ValueKind.Equals(JsonValueKind.Undefined) && !jsonPageSize.ValueKind.Equals(JsonValueKind.Null) && jsonPageSize.TryGetInt32(out int tempPageSize))
  86. {
  87. pageSize = tempPageSize;
  88. }
  89. }
  90. if (pageSize != null && pageSize.Value > 0)
  91. {
  92. iscontinuation = true;
  93. }
  94. if (jsonElement.TryGetProperty("contToken", out JsonElement ContToken))
  95. {
  96. pageToken = ContToken.GetString();
  97. }
  98. List<RecArea> areas = new();
  99. var table = _azureStorage.GetCloudTableClient().GetTableReference("IESLogin");
  100. var cosmosClient = _azureCosmos.GetCosmosClient();
  101. ////分开部署,就不需要,一站多用时,取消注释
  102. //if ($"{site}".Equals(BIConst.Global))
  103. //{
  104. // cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
  105. // table = _azureStorage.GetCloudTableClient(BIConst.Global).GetTableReference("IESLogin");
  106. //}
  107. StringBuilder areaSql = new($"select c.id,c.code,c.pk,c.name,c.provCode,c.provName,c.cityCode,c.cityName,c.standard,c.standardName,c.institution,c.updateTime,c.quoteId from c");
  108. if (!string.IsNullOrEmpty($"{id}") && string.IsNullOrEmpty($"{name}"))
  109. areaSql.Append($" where c.id='{id}'");
  110. if (string.IsNullOrEmpty($"{id}") && !string.IsNullOrEmpty($"{name}"))
  111. areaSql.Append($" where Contains(c.name,'{name}')");
  112. await foreach (var itemArea in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryStreamIterator(queryText: areaSql.ToString(), continuationToken: pageToken, requestOptions: new QueryRequestOptions() { MaxItemCount = pageSize, PartitionKey = new PartitionKey("Base-Area") }))
  113. {
  114. using var json = await JsonDocument.ParseAsync(itemArea.ContentStream);
  115. if (json.RootElement.TryGetProperty("_count", out JsonElement count) && count.GetInt16() > 0)
  116. {
  117. foreach (var obj in json.RootElement.GetProperty("Documents").EnumerateArray())
  118. {
  119. areas.Add(obj.ToObject<RecArea>());
  120. }
  121. if (iscontinuation)
  122. {
  123. continuationToken = itemArea.GetContinuationToken();
  124. break;
  125. }
  126. }
  127. }
  128. //areas.ForEach(async area =>
  129. //{
  130. // area.schoolCount = await CommonFind.GetSqlValueCount(cosmosClient, "School", $"select value(count(c.id)) from c where c.areaId='{area.id}' and c.standard='{area.standard}'", "Base");
  131. // area.aquoteRec = await table.QueryWhereString<AreaQuoteRecord>($"PartitionKey eq 'QuoteRecord' and areaId eq '{area.id}'");
  132. // //List<AreaQuoteRecord> aqr = await table.QueryWhereString<AreaQuoteRecord>($"PartitionKey eq 'QuoteRecord' and areaId eq '{area.id}'");
  133. // //aqr.Sort((x, y) => y.RowKey.CompareTo(x.RowKey));
  134. // await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<string>(queryText: $"select value(c.accessConfig) from c where c.id='{area.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("AreaSetting") }))
  135. // {
  136. // if (string.IsNullOrEmpty(item))
  137. // area.cutArea = false;
  138. // else
  139. // area.cutArea = true;
  140. // };
  141. //});
  142. foreach (var area in areas)
  143. {
  144. area.schoolCount = await CommonFind.GetSqlValueCount(cosmosClient, "School", $"select value(count(c.id)) from c where c.areaId='{area.id}' and c.standard='{area.standard}'", "Base");
  145. area.aquoteRec = await table.QueryWhereString<AreaQuoteRecord>($"PartitionKey eq 'QuoteRecord' and areaId eq '{area.id}'");
  146. //List<AreaQuoteRecord> aqr = await table.QueryWhereString<AreaQuoteRecord>($"PartitionKey eq 'QuoteRecord' and areaId eq '{area.id}'");
  147. //aqr.Sort((x, y) => y.RowKey.CompareTo(x.RowKey));
  148. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<string>(queryText: $"select value(c.accessConfig) from c where c.id='{area.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("AreaSetting") }))
  149. {
  150. if (string.IsNullOrEmpty(item))
  151. area.cutArea = false;
  152. else
  153. area.cutArea = true;
  154. };
  155. }
  156. return Ok(new { state = 200, areas, continuationToken });
  157. }
  158. catch (Exception ex)
  159. {
  160. await _dingDing.SendBotMsg($"BI,{_option.Location} batcharea/get-areas \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  161. return BadRequest();
  162. }
  163. }
  164. /// <summary>
  165. /// 批量创区 新接口 //已对接
  166. /// </summary>
  167. /// <param name="jsonElement"></param>
  168. /// <returns></returns>
  169. [ProducesDefaultResponseType]
  170. [AuthToken(Roles = "admin,rdc")]
  171. [HttpPost("batch-area")]
  172. public async Task<IActionResult> batchArea(JsonElement jsonElement)
  173. {
  174. try
  175. {
  176. if (!jsonElement.TryGetProperty("name", out JsonElement name)) return BadRequest();
  177. jsonElement.TryGetProperty("provCode", out JsonElement provCode);
  178. jsonElement.TryGetProperty("provName", out JsonElement provName);
  179. jsonElement.TryGetProperty("cityCode", out JsonElement cityCode);
  180. jsonElement.TryGetProperty("cityName", out JsonElement cityName);
  181. jsonElement.TryGetProperty("areaAdmin", out JsonElement areadAdmin);
  182. if (!jsonElement.TryGetProperty("standard", out JsonElement standard)) return BadRequest();
  183. if (!jsonElement.TryGetProperty("standardName", out JsonElement standardName)) return BadRequest();
  184. jsonElement.TryGetProperty("institution", out JsonElement institution);
  185. jsonElement.TryGetProperty("oldId", out JsonElement _oldId);
  186. jsonElement.TryGetProperty("oldStandard", out JsonElement oldStandard);
  187. jsonElement.TryGetProperty("oldName", out JsonElement oldName);
  188. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  189. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  190. //操作记录实体
  191. var tempStandard = !string.IsNullOrEmpty($"{oldStandard}") && !string.IsNullOrEmpty($"{_oldId}") ? $"{oldStandard}" : "standard2";
  192. var cosmosClient = _azureCosmos.GetCosmosClient();//数据库连接
  193. var tableClient = _azureStorage.GetCloudTableClient();
  194. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  195. ServiceBusClient serBusClient;
  196. try
  197. {
  198. serBusClient = _serviceBus.GetServiceBusClient();
  199. }
  200. catch
  201. {
  202. return Ok(new { state = 403, msg = "Functionn未启动,请联系管理员" });
  203. }
  204. var activeTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");//秘钥地址
  205. //分开部署,就不需要,一站多用时,取消注释
  206. //if ($"{site}".Equals(BIConst.Global))
  207. //{
  208. // cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
  209. // tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  210. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", name: BIConst.Global);
  211. //}
  212. var table = tableClient.GetTableReference("IESLogin");
  213. //查询新的是否存在
  214. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Area>(queryText: $"select value(c) from c where c.standard='{standard}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-Area") }))
  215. {
  216. if (item.standard.Equals($"{standard}"))
  217. return Ok(new { state = 1, message = "新创区的standard已存在请检查" });
  218. }
  219. //区级的ID
  220. string areaId = Guid.NewGuid().ToString();
  221. Area addArea = new()
  222. {
  223. id = areaId,
  224. code = $"Base-Area",
  225. name = $"{name}",
  226. provCode = $"{provCode}",
  227. provName = $"{provName}",
  228. cityCode = $"{cityCode}",
  229. cityName = $"{cityName}",
  230. standard = $"{standard}",
  231. standardName = $"{standardName}",
  232. institution = $"{institution}",
  233. quoteId = $"{_oldId}"
  234. };
  235. #region 区级管理员
  236. var coreUser = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", $"{areadAdmin}" } }, _option.Location, _configuration);
  237. if (coreUser == null || coreUser.id == null)
  238. return Ok(new { state = 404, msg = "未找到改账户的管理员" });
  239. //string tmdId = !string.IsNullOrEmpty(tempTmdId) ? tempTmdId : $"{areadAdmin}";
  240. Teacher teacher = null;
  241. try
  242. {
  243. //查询该教师是否存在
  244. teacher = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Teacher>($"{coreUser.id}", new PartitionKey("Base"));
  245. }
  246. catch
  247. {
  248. }
  249. if (teacher != null)
  250. {
  251. //教师存在,在该教师信息中添加要管理的学校信息
  252. teacher.areas.Add(new Teacher.TeacherArea { areaId = addArea.id, status = "join", name = addArea.name });
  253. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey("Base"));
  254. }
  255. else
  256. {
  257. teacher.id = coreUser.id;
  258. teacher.name = coreUser.name;
  259. teacher.picture = coreUser.picture;
  260. teacher.pk = "Base";
  261. teacher.code = "Base";
  262. teacher.size = 1;
  263. teacher.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  264. //教师存在,在该教师信息中添加要管理的学校信息
  265. teacher.areas.Add(new Teacher.TeacherArea { areaId = addArea.id, status = "join", name = addArea.name });
  266. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<Teacher>(teacher, new PartitionKey("Base"));
  267. }
  268. #endregion
  269. //创建区域
  270. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync<Area>(addArea, new PartitionKey("Base-Area"));
  271. //保存引用记录
  272. await table.SaveOrUpdate<AreaQuoteRecord>(new AreaQuoteRecord() { PartitionKey = "QuoteRecord", RowKey = $"{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}", areaId = $"{areaId}", quoteId = $"{_oldId}", quoteName = $"{oldName}", standard = tempStandard });
  273. //消息分区键
  274. string partitionCode = "copyAbility-mark";
  275. #region 使用Function创区
  276. //string areaCode = "copyArea-mark";
  277. //BatchCopyAreaRelevant bCopyArea = new BatchCopyAreaRelevant()
  278. //{
  279. // tmdid = $"{_tmdId}",
  280. // tmdName = $"{_tmdName}",
  281. // codeKey = areaCode,
  282. // tmdIds = new List<string> { $"{_tmdId}"},
  283. // oldStandard = $"{oldStandard}",
  284. // oldId = $"{_oldId}",
  285. // standard = $"{standard}",
  286. // areaId = areaId,
  287. // cut="",
  288. //};
  289. //var messageBatchCopyArea = new ServiceBusMessage(bCopyArea.ToJsonString());
  290. //messageBatchCopyArea.ApplicationProperties.Add("name", "CopyAreaRelevant");
  291. //var activeTaskArea = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  292. //await _serviceBus.GetServiceBusClient().SendMessageAsync(activeTaskArea, messageBatchCopyArea);
  293. #endregion
  294. #region 旧的批量创区
  295. List<Task<ItemResponse<Ability>>> abilities = new List<Task<ItemResponse<Ability>>>(); //存储区域数据
  296. List<Task<ItemResponse<AbilityTask>>> abilityTasks = new List<Task<ItemResponse<AbilityTask>>>(); //存储章节
  297. if (!string.IsNullOrEmpty($"{oldStandard}") && !string.IsNullOrEmpty($"{_oldId}"))
  298. {
  299. //查询要复制区域的能力标准点
  300. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Ability>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{oldStandard}") }))
  301. {
  302. if (!string.IsNullOrEmpty(item.blob))
  303. {
  304. item.blob = item.blob.Replace($"/{oldStandard}/", $"/{standard}/");
  305. };
  306. item.standard = $"{standard}";
  307. item.code = $"Ability-{standard}";
  308. item.school = $"{standard}";
  309. //添加区能力标准点
  310. abilities.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(item, new PartitionKey($"Ability-{standard}")));
  311. }
  312. try
  313. {
  314. if (abilities.Count < 256)
  315. {
  316. await Task.WhenAll(abilities);
  317. }
  318. else
  319. {
  320. int pages = (abilities.Count + 255) / 256;
  321. for (int i = 0; i < pages; i++)
  322. {
  323. List<Task<ItemResponse<Ability>>> tempAbility = abilities.Skip((i) * 256).Take(256).ToList();
  324. await Task.WhenAll(tempAbility);
  325. }
  326. }
  327. }
  328. catch
  329. {
  330. return Ok(new { state = 200, msg = "创区成功,能力标准点复制失败,遗留数据影响!" });
  331. }
  332. try
  333. {
  334. //微能力点
  335. await foreach (var atask in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AbilityTask>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilityTask-{oldStandard}") }))
  336. {
  337. List<Tnode> tnodes = new List<Tnode>();
  338. foreach (Tnode tnode in atask.children)
  339. {
  340. if (tnode.rnodes != null)
  341. {
  342. List<Rnode> rnodes = new List<Rnode>();
  343. foreach (Rnode rnode in tnode.rnodes)
  344. {
  345. if (!string.IsNullOrEmpty($"{rnode.link}"))
  346. {
  347. rnode.link = rnode.link.Replace($"/{oldStandard}/", $"/{standard}/");
  348. }
  349. rnodes.Add(rnode);
  350. }
  351. tnode.rnodes = rnodes;
  352. }
  353. tnodes.Add(tnode);
  354. }
  355. atask.children = tnodes;
  356. atask.code = $"AbilityTask-{standard}";
  357. atask.standard = $"{standard}";
  358. atask.codeval = $"{standard}";
  359. //添加区能力标准点中的节点
  360. //abilityTasks.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(atask, new PartitionKey($"AbilityTask-{standard}")));
  361. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(atask, new PartitionKey($"AbilityTask-{standard}"));
  362. }
  363. }
  364. catch
  365. {
  366. return Ok(new { state = 200, msg = "创区成功,能力标准创建成功,微能力点复制失败,遗留数据影响!" });
  367. }
  368. //if (abilityTasks.Count > 0)
  369. //{
  370. // for (int i = 0; i < abilityTasks.Count; i++)
  371. // {
  372. // List<Task<ItemResponse<AbilityTask>>> tempAbilityTasks = abilityTasks.Skip((i)).Take(1).ToList();
  373. // await Task.WhenAll(tempAbilityTasks);
  374. // }
  375. //}
  376. //新政策文件
  377. await foreach (StandardFile standardFile in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<StandardFile>(queryText: $"select value(c) from c where c.id='{_oldId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StandardFile") }))
  378. {
  379. if (standardFile != null)
  380. {
  381. standardFile.standard = $"{standard}";
  382. standardFile.id = areaId;
  383. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(standardFile, new PartitionKey($"StandardFile"));
  384. }
  385. }
  386. //新的区域设置
  387. await foreach (AreaSetting areaSetting in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AreaSetting>(queryText: $"select value(c) from c where c.id='{_oldId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("AreaSetting") }))
  388. {
  389. if (areaSetting != null)
  390. {
  391. areaSetting.accessConfig = null;
  392. areaSetting.id = areaId;
  393. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(areaSetting, new PartitionKey($"AreaSetting"));
  394. }
  395. }
  396. }
  397. else
  398. {
  399. Area area = null;
  400. await foreach (var tempArea in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Area>(queryText: $"select value(c) from c where c.standard='standard2'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base-Area") }))
  401. {
  402. area = tempArea;
  403. }
  404. if (area != null)
  405. {
  406. //查询要复制区域的能力标准点
  407. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Ability>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{area.standard}") }))
  408. {
  409. if (!string.IsNullOrEmpty(item.blob))
  410. {
  411. item.blob = item.blob.Replace($"/{area.standard}/", $"/{standard}/");
  412. };
  413. item.standard = $"{standard}";
  414. item.code = $"Ability-{standard}";
  415. item.school = $"{standard}";
  416. //添加区能力标准点
  417. abilities.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(item, new PartitionKey($"Ability-{standard}")));
  418. }
  419. try
  420. {
  421. if (abilities.Count < 256)
  422. {
  423. await Task.WhenAll(abilities);
  424. }
  425. else
  426. {
  427. int pages = (abilities.Count + 255) / 256;
  428. for (int i = 0; i < pages; i++)
  429. {
  430. List<Task<ItemResponse<Ability>>> tempAbility = abilities.Skip((i) * 256).Take(256).ToList();
  431. await Task.WhenAll(tempAbility);
  432. }
  433. }
  434. }
  435. catch
  436. {
  437. return Ok(new { state = 200, msg = "创区成功,能力标准点复制失败,遗留数据影响!" });
  438. }
  439. try
  440. {
  441. //微能力点
  442. await foreach (var atask in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AbilityTask>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilityTask-{area.standard}") }))
  443. {
  444. List<Tnode> tnodes = new List<Tnode>();
  445. foreach (Tnode tnode in atask.children)
  446. {
  447. if (tnode.rnodes != null)
  448. {
  449. List<Rnode> rnodes = new List<Rnode>();
  450. foreach (Rnode rnode in tnode.rnodes)
  451. {
  452. if (!string.IsNullOrEmpty($"{rnode.link}"))
  453. {
  454. rnode.link = rnode.link.Replace($"/{area.standard}/", $"/{standard}/");
  455. }
  456. rnodes.Add(rnode);
  457. }
  458. tnode.rnodes = rnodes;
  459. }
  460. tnodes.Add(tnode);
  461. }
  462. atask.children = tnodes;
  463. atask.code = $"AbilityTask-{standard}";
  464. atask.standard = $"{standard}";
  465. atask.codeval = $"{standard}";
  466. //添加区能力标准点中的节点
  467. //abilityTasks.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(atask, new PartitionKey($"AbilityTask-{standard}")));
  468. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(atask, new PartitionKey($"AbilityTask-{standard}"));
  469. }
  470. }
  471. catch
  472. {
  473. return Ok(new { state = 200, msg = "创区成功,能力标准创建成功,微能力点复制失败,遗留数据影响!" });
  474. }
  475. //if (abilityTasks.Count > 0)
  476. //{
  477. // for (int i = 0; i < abilityTasks.Count; i++)
  478. // {
  479. // List<Task<ItemResponse<AbilityTask>>> tempAbilityTasks = abilityTasks.Skip(i).Take(1).ToList();
  480. // await Task.WhenAll(tempAbilityTasks);
  481. // }
  482. //}
  483. //新政策文件
  484. await foreach (StandardFile standardFile in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<StandardFile>(queryText: $"select value(c) from c where c.id='{area.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StandardFile") }))
  485. {
  486. if (standardFile != null)
  487. {
  488. standardFile.standard = $"{standard}";
  489. standardFile.id = areaId;
  490. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(standardFile, new PartitionKey($"StandardFile"));
  491. }
  492. }
  493. //新的区域设置
  494. await foreach (AreaSetting areaSetting in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AreaSetting>(queryText: $"select value(c) from c where c.id='{area.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("AreaSetting") }))
  495. {
  496. if (areaSetting != null)
  497. {
  498. areaSetting.accessConfig = null;
  499. areaSetting.id = areaId;
  500. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(areaSetting, new PartitionKey($"AreaSetting"));
  501. }
  502. }
  503. }
  504. else return Ok(new { state = 201, message = "未找到默认能力点!" });
  505. }
  506. #endregion
  507. //执行复制操作
  508. BatchCopyFile batchCopyFile = new BatchCopyFile();
  509. batchCopyFile.blobCntr = "teammodelos";
  510. batchCopyFile.oldFileName = $"{oldStandard}";
  511. batchCopyFile.newFileName = $"{standard}";
  512. batchCopyFile.tmdid = $"{_tmdId}";
  513. batchCopyFile.tmdIds = new List<string> { $"{ _tmdId}" };
  514. batchCopyFile.codeKey = partitionCode;
  515. batchCopyFile.tmdName = $"{_tmdName}";
  516. var messageBatchCopyFile = new ServiceBusMessage(batchCopyFile.ToJsonString());
  517. messageBatchCopyFile.ApplicationProperties.Add("name", "CopyStandardFile");
  518. //var activeTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");
  519. try
  520. {
  521. //await _serviceBus.GetServiceBusClient().SendMessageAsync(activeTask, messageBatchCopyFile);
  522. await serBusClient.SendMessageAsync(activeTask, messageBatchCopyFile);
  523. }
  524. catch (Exception)
  525. {
  526. return Ok(new { state = 201, msg = "能力点复制成功,复制能力点的文件失败," });
  527. }
  528. //发送消息实体
  529. Notification notification = new Notification
  530. {
  531. hubName = "hita",
  532. type = "msg",
  533. from = $"BI:{_option.Location}:private",
  534. to = new List<string> { $"{ _tmdId}" },
  535. label = $"{partitionCode}_start",
  536. body = new { location = _option.Location, biz = partitionCode, tmdid = $"{_tmdId}", tmdname = $"{_tmdName}", status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
  537. expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
  538. };
  539. var notiUrl = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
  540. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  541. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  542. var location = _option.Location;
  543. await _notificationService.SendNotification(clientID, clientSecret, location, notiUrl, notification); //站内发送消息
  544. //保存操作记录
  545. //await _azureStorage.SaveBILog("area-add", $"{_tmdName}【{_tmdId}】已操作创区功能模块:{name},当前标准【{standard}】,复制的微能力点:{tempStandard}", _dingDing, httpContext: HttpContext);
  546. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "area-add", $"{_tmdName}【{_tmdId}】已操作创区功能模块:{name},当前标准【{standard}】,复制的微能力点:{tempStandard}", _dingDing, httpContext: HttpContext);
  547. return Ok(new { state = 200, area = addArea });
  548. }
  549. catch (Exception ex)
  550. {
  551. await _dingDing.SendBotMsg($"BI,{_option.Location} /batcharea/batch-area \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  552. return BadRequest();
  553. }
  554. }
  555. /// <summary>
  556. /// 创区后切换能力点, 先删除原来的能力点,后复制新的能力点 //已对接
  557. /// </summary>
  558. /// <param name="jsonElement"></param>
  559. /// <returns></returns>
  560. [ProducesDefaultResponseType]
  561. [AuthToken(Roles = "admin,rdc")]
  562. [HttpPost("cut-standard")]
  563. public async Task<IActionResult> CutStandard(JsonElement jsonElement)
  564. {
  565. try
  566. {
  567. if (!jsonElement.TryGetProperty("oldId", out JsonElement _oldId)) return BadRequest();
  568. if (!jsonElement.TryGetProperty("oldStandard", out JsonElement _oldStandard)) return BadRequest();
  569. if (!jsonElement.TryGetProperty("newId", out JsonElement _newId)) return BadRequest();
  570. if (!jsonElement.TryGetProperty("newStandard", out JsonElement _newStandard)) return BadRequest();
  571. jsonElement.TryGetProperty("newName", out JsonElement newName);
  572. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  573. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  574. //操作记录实体
  575. string blobOrTable = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString();
  576. var tableClient = _azureStorage.GetCloudTableClient();
  577. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  578. var cosmosClient = _azureCosmos.GetCosmosClient();
  579. var serBusClient = _serviceBus.GetServiceBusClient();
  580. var activeTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");//秘钥地址
  581. ////分开部署,就不需要,一站多用时,取消注释
  582. //if ($"{site}".Equals(BIConst.Global))
  583. //{
  584. // cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
  585. // tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  586. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  587. // serBusClient = _serviceBus.GetServiceBusClient(BIConst.Global); //暂未确定使用默认
  588. // //activeTask = _configuration.GetValue<string>("GlobalAzure:ServiceBus:ActiveTask"); //暂未确定使用默认
  589. //}
  590. var table = tableClient.GetTableReference("IESLogin");
  591. var responseSet = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync($"{_oldId}", new PartitionKey("AreaSetting"));
  592. if (responseSet.Status == 200)
  593. {
  594. using var fileJson = await JsonDocument.ParseAsync(responseSet.ContentStream);
  595. AreaSetting delSet = fileJson.ToObject<AreaSetting>();
  596. if (!string.IsNullOrEmpty(delSet.accessConfig))
  597. return Ok(new { state = 401, msg = "区域已经规定了,不能切换能能力" });
  598. }
  599. //保存引用记录
  600. await table.SaveOrUpdate<AreaQuoteRecord>(new AreaQuoteRecord() { PartitionKey = "QuoteRecord", RowKey = $"{DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()}", areaId = $"{_oldId}", quoteId = $"{_newId}", quoteName = $"{newName}", standard = $"{_newStandard}" });
  601. List<string> abilityIds = new(); //册别的ID集合
  602. //查询册别信息
  603. await foreach (var tempAbility in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Ability>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{_oldStandard}") }))
  604. {
  605. abilityIds.Add(tempAbility.id); //查询出来册别ID添加册别ID集合
  606. }
  607. //删除册别
  608. if (abilityIds.IsNotEmpty())
  609. {
  610. var sresponse = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemsStreamAsync(abilityIds, $"Ability-{_oldStandard}");
  611. }
  612. List<string> abilityTaskIds = new(); //章节ID集合
  613. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AbilityTask>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilityTask-{_oldStandard}") }))
  614. {
  615. abilityTaskIds.Add(item.id); //查询出来的章节信息ID添加到战绩集合
  616. }
  617. //删除章节
  618. if (abilityTaskIds.IsNotEmpty())
  619. {
  620. var sresponse = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemsStreamAsync(abilityTaskIds, $"AbilityTask-{_oldStandard}");
  621. }
  622. List<Task<ItemResponse<Ability>>> abilities = new(); //存储册别数据
  623. List<Task<ItemResponse<AbilityTask>>> abilityTasks = new(); //存储章节
  624. //查询要复制区域的能力标准点
  625. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Ability>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{_newStandard}") }))
  626. {
  627. if (!string.IsNullOrEmpty(item.blob))
  628. {
  629. item.blob = item.blob.Replace($"/{_newStandard}/", $"/{_oldStandard}/");
  630. };
  631. item.standard = $"{_oldStandard}";
  632. item.code = $"Ability-{_oldStandard}";
  633. item.school = $"{_oldStandard}";
  634. //添加区能力标准点
  635. abilities.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(item, new PartitionKey($"Ability-{_oldStandard}")));
  636. }
  637. try
  638. {
  639. if (abilities.Count < 256)
  640. {
  641. await Task.WhenAll(abilities);
  642. }
  643. else
  644. {
  645. int pages = (abilities.Count + 255) / 256;
  646. for (int i = 0; i < pages; i++)
  647. {
  648. List<Task<ItemResponse<Ability>>> tempAbility = abilities.Skip((i) * 256).Take(256).ToList();
  649. await Task.WhenAll(tempAbility);
  650. }
  651. }
  652. }
  653. catch
  654. {
  655. return Ok(new { state = 200, msg = "能力标准点复制失败,遗留数据影响!" });
  656. }
  657. try
  658. {
  659. //微能力点
  660. await foreach (var atask in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AbilityTask>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilityTask-{_newStandard}") }))
  661. {
  662. List<Tnode> tnodes = new();
  663. foreach (Tnode tnode in atask.children)
  664. {
  665. if (tnode.rnodes != null)
  666. {
  667. List<Rnode> rnodes = new();
  668. foreach (Rnode rnode in tnode.rnodes)
  669. {
  670. if (!string.IsNullOrEmpty($"{rnode.link}"))
  671. {
  672. rnode.link = rnode.link.Replace($"/{_newStandard}/", $"/{_oldStandard}/");
  673. }
  674. rnodes.Add(rnode);
  675. }
  676. tnode.rnodes = rnodes;
  677. }
  678. tnodes.Add(tnode);
  679. }
  680. atask.children = tnodes;
  681. atask.code = $"AbilityTask-{_oldStandard}";
  682. atask.standard = $"{_oldStandard}";
  683. atask.codeval = $"{_oldStandard}";
  684. ////添加区能力标准点中的节点
  685. //abilityTasks.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(atask, new PartitionKey($"AbilityTask-{_oldStandard}")));
  686. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(atask, new PartitionKey($"AbilityTask-{_oldStandard}"));
  687. }
  688. }
  689. catch
  690. {
  691. return Ok(new { state = 200, msg = "能力标准创建成功,微能力点复制失败,遗留数据影响!" });
  692. }
  693. StandardFile saveFile = new();
  694. //新政策文件
  695. await foreach (StandardFile standardFile in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<StandardFile>(queryText: $"select value(c) from c where c.id='{_newId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StandardFile") }))
  696. {
  697. if (standardFile != null)
  698. {
  699. standardFile.standard = $"{_oldStandard}";
  700. standardFile.id = $"{_oldId}";
  701. saveFile = standardFile;
  702. }
  703. }
  704. StandardFile tempFile = new();
  705. if (saveFile.id != null)
  706. {
  707. var respFile = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync(saveFile.id, new PartitionKey("StandardFile"));
  708. if (respFile.Status == 200)
  709. {
  710. using var json = await JsonDocument.ParseAsync(respFile.ContentStream);
  711. tempFile = json.ToObject<StandardFile>();
  712. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemAsync<StandardFile>(tempFile.id, new PartitionKey("StandardFile"));
  713. }
  714. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(saveFile, new PartitionKey($"StandardFile")); // 需要删除原来的政策文件数据在进行添加
  715. }
  716. //新的区域设置
  717. AreaSetting saveSetting = new AreaSetting();
  718. await foreach (AreaSetting areaSetting in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AreaSetting>(queryText: $"select value(c) from c where c.id='{_newId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("AreaSetting") }))
  719. {
  720. if (areaSetting != null)
  721. {
  722. areaSetting.accessConfig = null;
  723. areaSetting.id = $"{_oldId}";
  724. saveSetting = areaSetting;
  725. }
  726. }
  727. AreaSetting tempSetting = new();
  728. if (saveSetting.id != null)
  729. {
  730. var respSetting = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync(saveSetting.id, new PartitionKey("AreaSetting"));
  731. if (respSetting.Status == 200)
  732. {
  733. using var json = await JsonDocument.ParseAsync(respSetting.ContentStream);
  734. tempSetting = json.ToObject<AreaSetting>();
  735. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemAsync<AreaSetting>(tempFile.id, new PartitionKey("AreaSetting"));
  736. }
  737. tempSetting = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(saveSetting, new PartitionKey($"AreaSetting")); //需要删除原来的区域设置数据在进行添加
  738. }
  739. //修改切换区级能力引用id
  740. Area area = new();
  741. area = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync<Area>($"{_oldId}", new PartitionKey("Base-Area"));
  742. area.quoteId = $"{_newId}";
  743. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReplaceItemAsync<Area>(area, area.id, new PartitionKey(area.code));
  744. //发送消息分区键
  745. string partitionCode = "DelBeforeCopyAbility-mark";
  746. //v2通知
  747. Teacher targetTeacher = await cosmosClient.GetContainer(Constant.TEAMModelOS, Constant.Teacher).ReadItemAsync<Teacher>($"{_tmdId}", new PartitionKey($"Base"));
  748. _coreAPIHttpService.PushNotify(new List<IdNameCode> { new IdNameCode { id = targetTeacher.id, name = targetTeacher.name, code = targetTeacher.lang } }, "copy-file_area", Constant.NotifyType_IES5_Management, new Dictionary<string, object> { { "tmdname", $"{_tmdName}" } }, _option.Location, _configuration, _dingDing, _environment.ContentRootPath);
  749. //执行复制操作
  750. BatchCopyFile batchCopyFile = new();
  751. batchCopyFile.blobCntr = "teammodelos";
  752. batchCopyFile.oldFileName = $"{_newStandard}";
  753. batchCopyFile.newFileName = $"{_oldStandard}";
  754. batchCopyFile.tmdid = $"{_tmdId}";
  755. batchCopyFile.tmdIds = new List<string> { $"{ _tmdId}" };
  756. batchCopyFile.codeKey = partitionCode;
  757. batchCopyFile.tmdName = $"{_tmdName}";
  758. var messageBatchCopyFile = new ServiceBusMessage(batchCopyFile.ToJsonString());
  759. messageBatchCopyFile.ApplicationProperties.Add("name", "CopyStandardFile");
  760. try
  761. {
  762. //await _serviceBus.GetServiceBusClient().SendMessageAsync(activeTask, messageBatchCopyFile); //先执行删除操作,在执行复制 单一
  763. await serBusClient.SendMessageAsync(activeTask, messageBatchCopyFile); //先执行删除操作,在执行复制
  764. }
  765. catch (Exception)
  766. {
  767. return Ok(new { state = 201 ,msg = "能力点复制成功,复制能力点的文件失败," });
  768. }
  769. //发送消息实体
  770. Notification notification = new()
  771. {
  772. hubName = "hita",
  773. type = "msg",
  774. from = $"BI:{_option.Location}:private",
  775. to = new List<string> { $"{ _tmdId}" },
  776. label = $"{partitionCode}_start",
  777. body = new { location = _option.Location, biz = partitionCode, tmdid = $"{_tmdId}", tmdname = $"{_tmdName}", status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
  778. expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
  779. };
  780. var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
  781. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  782. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  783. var location = _option.Location;
  784. await _notificationService.SendNotification(clientID, clientSecret, location, url, notification); //发送站内发送消息
  785. //保存操作记录
  786. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "area-cut", $"{_tmdName}【{_tmdId}】已操作【{_oldStandard}】切换至{_newStandard}微能力点,复制标准:{_newStandard}", _dingDing, httpContext: HttpContext);
  787. return Ok(new { state = 200 });
  788. }
  789. catch (Exception ex)
  790. {
  791. await _dingDing.SendBotMsg($"BI,{_option.Location} batcharea/cut-standard \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  792. return BadRequest();
  793. }
  794. }
  795. /// <summary>
  796. /// 删除区域和区域的册别、能力点、区域文件、区域设置
  797. /// </summary>
  798. /// <param name="jsonElement"></param>
  799. /// <returns></returns>
  800. [ProducesDefaultResponseType]
  801. [HttpPost("del-area")]
  802. public async Task<IActionResult> DelArea(JsonElement jsonElement)
  803. {
  804. if (!jsonElement.TryGetProperty("areaId", out JsonElement areaId)) return BadRequest();
  805. if (!jsonElement.TryGetProperty("standard", out JsonElement standard)) return BadRequest();
  806. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  807. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "teammodelos");
  808. var cosmosClient = _azureCosmos.GetCosmosClient();
  809. ////分开部署,就不需要,一站多用时,取消注释
  810. //if ($"{site}".Equals(BIConst.Global))
  811. //{
  812. // cosmosClient = _azureCosmos.GetCosmosClient(name: BIConst.Global);
  813. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "teammodelos", BIConst.Global);
  814. //}
  815. var response = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync($"{areaId}", new PartitionKey("Base-Area"));
  816. if (response.Status == 200)
  817. {
  818. using var json = await JsonDocument.ParseAsync(response.ContentStream);
  819. Area area = json.ToObject<Area>();
  820. if (area.standard == $"{standard}")
  821. {
  822. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemAsync<Area>(area.id, new PartitionKey("Base-Area")); //删除区
  823. List<Teacher> teachers = new();
  824. await foreach (var item in cosmosClient.GetContainer("TEAMModelOS", "Teacher").GetItemQueryIterator<Teacher>(queryText: $"SELECT distinct value(c) FROM c join a in c.areas join s in c.schools where a.areaId='{area.id}' or s.areaId='{area.id}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
  825. {
  826. teachers.Add(item);
  827. }
  828. foreach (var item in teachers)
  829. {
  830. var tempArea = item.areas.Find(f => f.areaId.Equals(area.id));
  831. if (tempArea != null)
  832. {
  833. item.areas.Remove(tempArea);
  834. }
  835. item.schools.ForEach(fe => { if (fe.areaId.Equals(area.id)) fe.areaId = ""; });
  836. await cosmosClient.GetContainer("TEAMModelOS", "Teacher").ReplaceItemAsync<Teacher>(item, item.id, new PartitionKey("Base"));
  837. }
  838. List<string> scIds = await CommonFind.FindScIds(cosmosClient, $"select c.id from c where c.areaId='{area.id}' and c.standard ='{area.standard}'", "Base");
  839. foreach (var item in scIds)
  840. {
  841. School school = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<School>(item, new PartitionKey("Base"));
  842. school.areaId = "";
  843. school.standard = "";
  844. school = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<School>(school, school.id, new PartitionKey("Base"));
  845. }
  846. List<string> abilityIds = new(); //册别的ID集合
  847. List<string> abilityTaskIds = new(); //章节ID集合
  848. //查询册别信息
  849. await foreach (var tempAbility in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Ability>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{area.standard}") }))
  850. {
  851. abilityIds.Add(tempAbility.id); //查询出来册别ID添加册别ID集合
  852. }
  853. //删除册别
  854. if (abilityIds.IsNotEmpty())
  855. {
  856. var sresponse = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemsStreamAsync(abilityIds, $"Ability-{area.standard}");
  857. }
  858. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AbilityTask>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilityTask-{area.standard}") }))
  859. {
  860. abilityTaskIds.Add(item.id); //查询出来的章节信息ID添加到战绩集合
  861. }
  862. //删除章节
  863. if (abilityTaskIds.IsNotEmpty())
  864. {
  865. var sresponse = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemsStreamAsync(abilityTaskIds, $"AbilityTask-{standard}");
  866. }
  867. //区域政策文件
  868. StandardFile delFile = new();
  869. var responseFile = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync(area.id, new PartitionKey("StandardFile"));
  870. if(responseFile.Status == 200)
  871. {
  872. using var fileJson = await JsonDocument.ParseAsync(responseFile.ContentStream);
  873. delFile = fileJson.ToObject<StandardFile>();
  874. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemAsync<StandardFile>(delFile.id, new PartitionKey("StandardFile"));
  875. }
  876. //区域设置
  877. AreaSetting delSet = new();
  878. var responseSet = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync(area.id, new PartitionKey("AreaSetting"));
  879. if (responseSet.Status == 200)
  880. {
  881. using var fileJson = await JsonDocument.ParseAsync(responseSet.ContentStream);
  882. delSet = fileJson.ToObject<AreaSetting>();
  883. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemAsync<AreaSetting>(delSet.id, new PartitionKey("AreaSetting"));
  884. }
  885. List<object> fileobj = new();
  886. //先删除原有的文件
  887. List<Task<Response<bool>>> DelList = new();
  888. await foreach (BlobItem blobItem in blobClient.GetBlobsAsync(BlobTraits.None, BlobStates.None, $"yxpt/{area.standard}/"))
  889. {
  890. fileobj.Add(blobItem.Name);
  891. DelList.Add(blobClient.GetBlobBaseClient(blobItem.Name).DeleteIfExistsAsync());
  892. }
  893. if (DelList.Count <= 256)
  894. {
  895. await Task.WhenAll(DelList);
  896. }
  897. else
  898. {
  899. int pages = (DelList.Count + 255) / 256;
  900. for (int i = 0; i < pages; i++)
  901. {
  902. List<Task<Response<bool>>> delList = DelList.Skip((i) * 256).Take(256).ToList();
  903. await Task.WhenAll(delList);
  904. }
  905. }
  906. return Ok(new { state = 200,area, scIds, abilityIds, abilityTaskIds, delFile, delSet, fileobj });
  907. }
  908. else return Ok(new { state = 400, msg = "id和standard不匹配!" });
  909. }
  910. else return Ok(new { state = 404,msg="依据Id未找到该区!" });
  911. }
  912. /// <summary>
  913. /// 同步两个区到新的区中
  914. /// </summary>
  915. /// <param name="jsonElement"></param>
  916. /// <returns></returns>
  917. [ProducesDefaultResponseType]
  918. [AuthToken(Roles = "admin")]
  919. [HttpPost("cut-full-statndard")]
  920. public async Task<IActionResult> CutFullStandard(JsonElement jsonElement)
  921. {
  922. try
  923. {
  924. string _oldId = "bde5c011-2ae4-461a-b46c-5483ba72ae45";
  925. //string _oldStandard = "standard27";
  926. string standardFileId = "02944f32-f534-3397-ea56-e6f1fc6c3714";
  927. string standard = "standard2";
  928. List<CopyStandard> copyStand = new()
  929. {
  930. new CopyStandard() { id = standardFileId, standard = standard },
  931. new CopyStandard() { id = "99a4a33b-e21b-44ac-80a1-b31dc40496e0", standard = "standard3" }
  932. };
  933. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  934. var tableClient = _azureStorage.GetCloudTableClient();
  935. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  936. var cosmosClient = _azureCosmos.GetCosmosClient();
  937. var serBusClient = _serviceBus.GetServiceBusClient();
  938. var activeTask = _configuration.GetValue<string>("Azure:ServiceBus:ActiveTask");//秘钥地址
  939. var table = tableClient.GetTableReference("IESLogin");
  940. Area area = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemAsync<Area>($"{_oldId}", new PartitionKey("Base-Area"));
  941. if (area != null)
  942. {
  943. var responseSet = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync($"{_oldId}", new PartitionKey("AreaSetting"));
  944. if (responseSet.Status == 200)
  945. {
  946. using var fileJson = await JsonDocument.ParseAsync(responseSet.ContentStream);
  947. AreaSetting delSet = fileJson.ToObject<AreaSetting>();
  948. if (!string.IsNullOrEmpty(delSet.accessConfig))
  949. return Ok(new { state = 401, msg = "区域已经规定了,不能切换能能力" });
  950. }
  951. List<string> abilityIds = new(); //册别的ID集合
  952. //查询册别信息
  953. await foreach (var tempAbility in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Ability>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{area.standard}") }))
  954. {
  955. abilityIds.Add(tempAbility.id); //查询出来册别ID添加册别ID集合
  956. }
  957. //删除册别
  958. if (abilityIds.IsNotEmpty())
  959. {
  960. var sresponse = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemsStreamAsync(abilityIds, $"Ability-{area.standard}");
  961. }
  962. List<string> abilityTaskIds = new List<string>(); //章节ID集合
  963. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AbilityTask>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilityTask-{area.standard}") }))
  964. {
  965. abilityTaskIds.Add(item.id); //查询出来的章节信息ID添加到战绩集合
  966. }
  967. //删除章节
  968. if (abilityTaskIds.IsNotEmpty())
  969. {
  970. var sresponse = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemsStreamAsync(abilityTaskIds, $"AbilityTask-{area.standard}");
  971. }
  972. List<Task<ItemResponse<Ability>>> abilities = new(); //存储册别数据
  973. List<Task<ItemResponse<AbilityTask>>> abilityTasks = new(); //存储章节
  974. List<string> repeatAbilityId = new();
  975. List<string> repeatAbilityTaskId = new();
  976. foreach (var newstand in copyStand)
  977. {
  978. try
  979. {
  980. //查询要复制区域的能力标准点
  981. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<Ability>(queryText: $"select value(c) from c", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Ability-{newstand.standard}") }))
  982. {
  983. if (!string.IsNullOrEmpty(item.blob))
  984. item.blob = item.blob.Replace($"/{newstand.standard}/", $"/{area.standard}/");
  985. item.standard = $"{area.standard}";
  986. item.code = $"Ability-{area.standard}";
  987. item.school = $"{area.standard}";
  988. //添加区能力标准点
  989. //abilities.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(item, new PartitionKey($"Ability-{_oldStandard}")));
  990. //await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(item, new PartitionKey($"Ability-{_oldStandard}"));
  991. var respond = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync(item.id, new PartitionKey(item.code));
  992. if (respond.Status != 200)
  993. abilities.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(item, new PartitionKey($"Ability-{area.standard}")));
  994. else
  995. repeatAbilityId.Add(item.id);
  996. }
  997. }
  998. catch
  999. {
  1000. return Ok(new { state = 200, msg = "创区成功,能力标准点复制失败,遗留数据影响!" });
  1001. }
  1002. try
  1003. {
  1004. if (abilities.Count < 256)
  1005. {
  1006. await Task.WhenAll(abilities);
  1007. }
  1008. else
  1009. {
  1010. int pages = (abilities.Count + 255) / 256;
  1011. for (int i = 0; i < pages; i++)
  1012. {
  1013. List<Task<ItemResponse<Ability>>> tempAbility = abilities.Skip((i) * 256).Take(256).ToList();
  1014. await Task.WhenAll(tempAbility);
  1015. }
  1016. }
  1017. }
  1018. catch
  1019. {
  1020. return Ok(new { state = 200, msg = "创区成功,能力标准点复制失败,遗留数据影响!" });
  1021. }
  1022. try
  1023. {
  1024. //微能力点
  1025. await foreach (var atask in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AbilityTask>(queryText: $"select value(c) from c ", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AbilityTask-{newstand.standard}") }))
  1026. {
  1027. List<Tnode> tnodes = new();
  1028. foreach (Tnode tnode in atask.children)
  1029. {
  1030. if (tnode.rnodes != null)
  1031. {
  1032. List<Rnode> rnodes = new();
  1033. foreach (Rnode rnode in tnode.rnodes)
  1034. {
  1035. if (!string.IsNullOrEmpty($"{rnode.link}"))
  1036. {
  1037. rnode.link = rnode.link.Replace($"/{newstand.standard}/", $"/{area.standard}/");
  1038. }
  1039. rnodes.Add(rnode);
  1040. }
  1041. tnode.rnodes = rnodes;
  1042. }
  1043. tnodes.Add(tnode);
  1044. }
  1045. atask.children = tnodes;
  1046. atask.code = $"AbilityTask-{area.standard}";
  1047. atask.standard = $"{area.standard}";
  1048. atask.codeval = $"{area.standard}";
  1049. var respond = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync(atask.id, new PartitionKey(atask.code));
  1050. if (respond.Status != 200)
  1051. ////添加区能力标准点中的节点
  1052. //abilityTasks.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(atask, new PartitionKey($"AbilityTask-{_oldStandard}")));
  1053. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(atask, new PartitionKey($"AbilityTask-{area.standard}"));
  1054. else
  1055. repeatAbilityTaskId.Add(atask.id);
  1056. }
  1057. }
  1058. catch
  1059. {
  1060. return Ok(new { state = 200, msg = "创区成功,能力标准创建成功,微能力点复制失败,遗留数据影响!" });
  1061. }
  1062. //发送消息分区键
  1063. string partitionCode = "DelBeforeCopyAbility-mark";
  1064. //执行复制操作
  1065. BatchCopyFile batchCopyFile = new();
  1066. batchCopyFile.blobCntr = "teammodelos";
  1067. batchCopyFile.oldFileName = $"{newstand.standard}";
  1068. batchCopyFile.newFileName = $"{area.standard}";
  1069. batchCopyFile.tmdid = $"{_tmdId}";
  1070. batchCopyFile.tmdIds = new List<string> { $"{_tmdId}" };
  1071. batchCopyFile.codeKey = partitionCode;
  1072. batchCopyFile.tmdName = $"{_tmdName}";
  1073. var messageBatchCopyFile = new ServiceBusMessage(batchCopyFile.ToJsonString());
  1074. messageBatchCopyFile.ApplicationProperties.Add("name", "CopyStandardFile");
  1075. try
  1076. {
  1077. //await _serviceBus.GetServiceBusClient().SendMessageAsync(activeTask, messageBatchCopyFile); //先执行删除操作,在执行复制 单一
  1078. await serBusClient.SendMessageAsync(activeTask, messageBatchCopyFile); //先执行删除操作,在执行复制
  1079. }
  1080. catch (Exception)
  1081. {
  1082. return Ok(new { state = 201, msg = "能力点复制成功,复制能力点的文件失败," });
  1083. }
  1084. //发送消息实体
  1085. Notification notification = new()
  1086. {
  1087. hubName = "hita",
  1088. type = "msg",
  1089. from = $"BI:{_option.Location}:private",
  1090. to = new List<string> { $"{_tmdId}" },
  1091. label = $"{partitionCode}_start",
  1092. body = new { location = _option.Location, biz = partitionCode, tmdid = $"{_tmdId}", tmdname = $"{_tmdName}", status = 1, time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() }.ToJsonString(),
  1093. expires = DateTimeOffset.UtcNow.AddDays(7).ToUnixTimeSeconds()
  1094. };
  1095. var url = _configuration.GetValue<string>("HaBookAuth:CoreService:sendnotification");
  1096. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  1097. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  1098. var location = _option.Location;
  1099. await _notificationService.SendNotification(clientID, clientSecret, location, url, notification); //发送站内发送消息
  1100. }
  1101. StandardFile saveFile = new();
  1102. //新政策文件
  1103. await foreach (StandardFile standardFile in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<StandardFile>(queryText: $"select value(c) from c where c.id='{standardFileId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"StandardFile") }))
  1104. {
  1105. if (standardFile != null)
  1106. {
  1107. standardFile.standard = $"{area.standard}";
  1108. standardFile.id = $"{_oldId}";
  1109. saveFile = standardFile;
  1110. }
  1111. }
  1112. StandardFile tempFile = new();
  1113. if (saveFile.id != null)
  1114. {
  1115. var respFile = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync(saveFile.id, new PartitionKey("StandardFile"));
  1116. if (respFile.Status == 200)
  1117. {
  1118. using var json = await JsonDocument.ParseAsync(respFile.ContentStream);
  1119. tempFile = json.ToObject<StandardFile>();
  1120. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemAsync<StandardFile>(tempFile.id, new PartitionKey("StandardFile"));
  1121. }
  1122. tempFile = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(saveFile, new PartitionKey($"StandardFile")); // 需要删除原来的政策文件数据在进行添加
  1123. }
  1124. //if (tempFile.id != null)
  1125. //{
  1126. // if (tempFile.id.Equals(saveFile.id))
  1127. // await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReplaceItemAsync<StandardFile>(saveFile, saveFile.id, new PartitionKey("StandardFile")); //直接替换以前的数据
  1128. // else
  1129. // await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(saveFile, new PartitionKey($"StandardFile")); // 需要删除原来的政策文件数据在进行添加
  1130. //}
  1131. //新的区域设置
  1132. AreaSetting saveSetting = new();
  1133. await foreach (AreaSetting areaSetting in cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AreaSetting>(queryText: $"select value(c) from c where c.id='{standardFileId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("AreaSetting") }))
  1134. {
  1135. if (areaSetting != null)
  1136. {
  1137. areaSetting.accessConfig = null;
  1138. areaSetting.id = $"{_oldId}";
  1139. saveSetting = areaSetting;
  1140. }
  1141. }
  1142. AreaSetting tempSetting = new();
  1143. if (saveSetting.id != null)
  1144. {
  1145. var respSetting = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReadItemStreamAsync(saveSetting.id, new PartitionKey("AreaSetting"));
  1146. if (respSetting.Status == 200)
  1147. {
  1148. using var json = await JsonDocument.ParseAsync(respSetting.ContentStream);
  1149. tempSetting = json.ToObject<AreaSetting>();
  1150. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").DeleteItemAsync<AreaSetting>(saveSetting.id, new PartitionKey("AreaSetting"));
  1151. }
  1152. tempSetting = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(saveSetting, new PartitionKey($"AreaSetting")); //需要删除原来的区域设置数据在进行添加
  1153. }
  1154. //if (tempSetting.id != null)
  1155. //{
  1156. // if (tempSetting.id.Equals(saveSetting.id))
  1157. // await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").ReplaceItemAsync<AreaSetting>(saveSetting, saveSetting.id, new PartitionKey($"AreaSetting")); //直接替换以前的数据
  1158. // else
  1159. // await cosmosClient.GetContainer(Constant.TEAMModelOS, "Normal").CreateItemAsync(saveSetting, new PartitionKey($"AreaSetting")); //需要删除原来的区域设置数据在进行添加
  1160. //}
  1161. return Ok(new { state = RespondCode.Ok, repeatAbilityId, repeatAbilityTaskId });
  1162. }
  1163. else
  1164. return Ok(new { state = RespondCode.NotFound, msg = "标准为空"}) ;
  1165. }
  1166. catch (Exception ex)
  1167. {
  1168. await _dingDing.SendBotMsg($"BI,{_option.Location} batcharea/cut-full-statndard \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  1169. return BadRequest();
  1170. }
  1171. }
  1172. /// <summary>
  1173. /// 区域列表
  1174. /// </summary>
  1175. public record RecArea
  1176. {
  1177. public string id { get; set; }
  1178. public string code { get; set; }
  1179. public string pk { get; set; }
  1180. public string name { get; set; }
  1181. public string provCode { get; set; }
  1182. public string provName { get; set; }
  1183. public string cityCode { get; set; }
  1184. public string cityName { get; set; }
  1185. public string standard { get; set; }
  1186. public string standardName { get; set; }
  1187. public string institution { get; set; }
  1188. public int schoolCount { get; set; }
  1189. public long updateTime { get; set; }
  1190. public string quoteId { get; set; } = null;
  1191. public bool cutArea { get; set; } = false;
  1192. public List<AreaQuoteRecord> aquoteRec { get; set; } = new List<AreaQuoteRecord>();
  1193. }
  1194. }
  1195. }