BatchAreaController.cs 77 KB

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