ScController.cs 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009
  1. using Microsoft.AspNetCore.Mvc;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Threading.Tasks;
  6. using TEAMModelOS.Models;
  7. using TEAMModelOS.SDK.DI;
  8. using System.Text.Json;
  9. using TEAMModelOS.SDK.Models;
  10. using Microsoft.AspNetCore.Http;
  11. using TEAMModelOS.SDK.Extension;
  12. using Azure.Cosmos;
  13. using System.Text;
  14. using TEAMModelOS.SDK.DI.AzureCosmos.Inner;
  15. using Microsoft.Extensions.Options;
  16. using Azure.Messaging.ServiceBus;
  17. using Microsoft.Extensions.Configuration;
  18. using TEAMModelOS.Services.Common;
  19. using HTEXLib.COMM.Helpers;
  20. using TEAMModelOS.SDK;
  21. using System.IdentityModel.Tokens.Jwt;
  22. using TEAMModelOS.Services;
  23. using TEAMModelOS.SDK.Models.Service;
  24. using System.IO;
  25. using System.Dynamic;
  26. using Microsoft.AspNetCore.Authorization;
  27. using Azure.Storage.Blobs.Models;
  28. using static TEAMModelOS.SDK.Models.Teacher;
  29. using System.Web;
  30. using static TEAMModelOS.Controllers.FixDataController;
  31. using static TEAMModelOS.SDK.SchoolService;
  32. using Microsoft.AspNetCore.Hosting;
  33. namespace TEAMModelOS.Controllers.Third
  34. {
  35. /// <summary>
  36. ///
  37. /// </summary>
  38. ///
  39. [ProducesResponseType(StatusCodes.Status200OK)]
  40. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  41. //[Authorize(Roles = "IES")]
  42. //[Route("")]
  43. //[Route("api/[controller]")]
  44. [ApiController]
  45. public class ScController : ControllerBase
  46. {
  47. private readonly SnowflakeId _snowflakeId;
  48. private readonly AzureCosmosFactory _azureCosmos;
  49. private readonly DingDing _dingDing;
  50. private readonly Option _option;
  51. private readonly AzureStorageFactory _azureStorage;
  52. private readonly AzureServiceBusFactory _serviceBus;
  53. private readonly AzureRedisFactory _azureRedis;
  54. private readonly CoreAPIHttpService _coreAPIHttpService;
  55. private readonly ThirdApisService _scsApisService;
  56. public readonly string type = "scsyxpt";
  57. private readonly HttpTrigger _httpTrigger;
  58. private readonly IWebHostEnvironment _environment;
  59. /// <summary>
  60. /// 机构安全码
  61. /// </summary>
  62. public string _sc_passKey;
  63. /// <summary>
  64. /// 机构ID
  65. /// </summary>
  66. public string _sc_trainComID;
  67. /// <summary>
  68. /// 机构 AES 密钥
  69. /// </summary>
  70. public string _sc_privateKey;
  71. /// <summary>
  72. /// 访问地址
  73. /// </summary>
  74. public string _sc_url;
  75. public IConfiguration _configuration { get; set; }
  76. public ScController(IWebHostEnvironment environment,AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage,
  77. AzureRedisFactory azureRedis, AzureServiceBusFactory serviceBus, IConfiguration configuration, CoreAPIHttpService coreAPIHttpService, ThirdApisService scsApisService, HttpTrigger httpTrigger)
  78. {
  79. _azureCosmos = azureCosmos;
  80. _snowflakeId = snowflakeId;
  81. _dingDing = dingDing;
  82. _option = option?.Value;
  83. _azureStorage = azureStorage;
  84. _serviceBus = serviceBus;
  85. _configuration = configuration;
  86. _azureRedis = azureRedis;
  87. _coreAPIHttpService = coreAPIHttpService;
  88. _scsApisService = scsApisService;
  89. _sc_passKey = _configuration.GetValue<string>("Third:scsyxpt:passKey");
  90. _sc_trainComID = _configuration.GetValue<string>("Third:scsyxpt:trainComID");
  91. _sc_privateKey = _configuration.GetValue<string>("Third:scsyxpt:privateKey");
  92. _sc_url = _configuration.GetValue<string>("Third:scsyxpt:url");
  93. _httpTrigger = httpTrigger;
  94. _environment = environment;
  95. }
  96. /// <summary>
  97. /// 检查醍摩豆id存在多个学校的情况
  98. /// </summary>
  99. /// <param name="request"></param>
  100. /// <returns></returns>
  101. [ProducesDefaultResponseType]
  102. [HttpPost("sc/get-project-school-teacher")]
  103. [AllowAnonymous]
  104. public async Task<IActionResult> GetProjectSchoolTeacher(JsonElement request) {
  105. if (!request.TryGetProperty("accessConfig", out JsonElement accessConfig)) return BadRequest();
  106. if (!request.TryGetProperty("ignoreSchools", out JsonElement ignoreSchools)) return BadRequest();
  107. if (!request.TryGetProperty("city", out JsonElement city)) return BadRequest();
  108. if (!request.TryGetProperty("dist", out JsonElement dist)) return BadRequest();
  109. if (!request.TryGetProperty("areaId", out JsonElement areaId)) return BadRequest();
  110. if (!request.TryGetProperty("standard", out JsonElement standard)) return BadRequest();
  111. List<IdNameCode> ignore = ignoreSchools.ToObject<List<IdNameCode>>();
  112. Dictionary<string, object> dict = new Dictionary<string, object> { { "accessConfig", $"{accessConfig}" } };
  113. int status = -1;string json = null;
  114. //5.3.1.1获取项目列表
  115. (status, json) = await _httpTrigger.RequestHttpTrigger(dict, _option.Location, "GetProjectInfoByTrainComID");
  116. List<ScProject> projects = null;
  117. List<ScSchool> saveschools = null;
  118. List<ScSchool> schools = null;
  119. List<ScSchool> matchSchools = null;
  120. List<ScSchool> tbschools=null;
  121. if (status == 200)
  122. {
  123. projects = json.ToObject<List<ScProject>>(new JsonSerializerOptions { PropertyNameCaseInsensitive = false });
  124. }
  125. // 5.3.1.18根据机构ID、项目ID、子项目ID返回学校列表
  126. (status, json) = await _httpTrigger.RequestHttpTrigger(dict, _option.Location, "GetSchoolList");
  127. if (status == 200)
  128. {
  129. schools = json.ToObject<List<ScSchool>>(new JsonSerializerOptions { PropertyNameCaseInsensitive = false });
  130. if (ignore.IsNotEmpty())
  131. {
  132. matchSchools = schools.FindAll(x => ignore.Select(y=>y.name).Contains(x.schoolname));
  133. if (matchSchools.IsNotEmpty())
  134. {
  135. if (matchSchools.Count != ignore.Count)
  136. {
  137. var matched = matchSchools.Select(x => x.schoolname);
  138. var unmatch = ignore.Select(y => y.name).Except(matched);
  139. return Ok(new { matched, unmatch });
  140. }
  141. else {
  142. matchSchools.ForEach(x => {
  143. var exschool= ignore.Find(y => y.name.Equals(x.schoolname));
  144. if (exschool != null) {
  145. x.schoolCode = exschool.id;
  146. x.areaId = $"{areaId}";
  147. x.city = $"{city}";
  148. x.dist = $"{dist}";
  149. }
  150. });
  151. }
  152. }
  153. else {
  154. return Ok(new { unmatch=ignore, schools }) ;
  155. }
  156. }
  157. //数据校验
  158. tbschools = await _azureStorage.FindListByDict<ScSchool>(new Dictionary<string, object>() { { "PartitionKey", $"ScSchool" } });
  159. if (tbschools.IsNotEmpty())
  160. {
  161. var a = tbschools.Select(y => $"{y.RowKey}").ToList();
  162. saveschools = schools.Where(x=>!a.Exists(z=>z.Equals($"{x.schoolid}"))).ToList();
  163. List<SchoolData> schoolDatas = new List<SchoolData>();
  164. saveschools.ForEach(x =>
  165. {
  166. x.RowKey = $"{x.schoolid}";
  167. x.PartitionKey = "ScSchool";
  168. x.areaId = $"{areaId}";
  169. x.city = $"{city}";
  170. x.dist = $"{dist}";
  171. if (string.IsNullOrEmpty(x.schoolCode))
  172. {
  173. schoolDatas.Add(new SchoolData { uid = $"{x.schoolid}", province = "四川省", city = $"{city}", name = x.schoolname });
  174. }
  175. });
  176. schoolDatas = await SchoolService.GenerateSchoolCode(schoolDatas, _dingDing, _environment);
  177. saveschools.ForEach(x => {
  178. var schoolData = schoolDatas.Find(y => y.uid.Equals($"{x.schoolid}"));
  179. if (schoolData != null && !string.IsNullOrEmpty(schoolData.id))
  180. {
  181. x.schoolCode = schoolData.id;
  182. x.areaId = $"{areaId}";
  183. x.city = $"{city}";
  184. x.dist = $"{dist}";
  185. }
  186. });
  187. saveschools.RemoveAll(x => string.IsNullOrEmpty(x.schoolCode));
  188. saveschools.RemoveAll(x => tbschools.FindAll(z=>!string.IsNullOrEmpty(z.schoolCode)).Exists(y=>y.schoolCode.Equals(x.schoolCode)));
  189. saveschools = await _azureStorage.SaveAll(saveschools);
  190. }
  191. else {
  192. List<SchoolData> schoolDatas = new List<SchoolData>();
  193. schools.ForEach(x =>
  194. {
  195. x.RowKey = $"{x.schoolid}";
  196. x.PartitionKey = "ScSchool";
  197. x.areaId = $"{areaId}";
  198. x.city = $"{city}";
  199. x.dist = $"{dist}";
  200. if (string.IsNullOrEmpty(x.schoolCode))
  201. {
  202. schoolDatas.Add(new SchoolData { uid = $"{x.schoolid}", province = "四川省", city = $"{city}", name = x.schoolname });
  203. }
  204. });
  205. schoolDatas = await SchoolService.GenerateSchoolCode(schoolDatas, _dingDing, _environment);
  206. schools.ForEach(x => {
  207. var schoolData = schoolDatas.Find(y => y.uid.Equals($"{x.schoolid}"));
  208. if (schoolData != null && !string.IsNullOrEmpty(schoolData.id)) {
  209. x.schoolCode = schoolData.id;
  210. x.areaId = $"{areaId}";
  211. x.city = $"{city}";
  212. x.dist = $"{dist}";
  213. }
  214. });
  215. schools.RemoveAll(x => string.IsNullOrEmpty(x.schoolCode));
  216. saveschools = await _azureStorage.SaveAll(schools);
  217. }
  218. }
  219. List<string> unsave = new List<string>();
  220. if (saveschools.IsNotEmpty()) {
  221. var ex = schools.Select(x => $"{x.schoolid}").Except(saveschools.Select(y=>y.RowKey));
  222. if (ex.Count() > 0) {
  223. unsave.AddRange(ex);
  224. }
  225. }
  226. if (tbschools.IsNotEmpty())
  227. {
  228. var ex = schools.Select(x => $"{x.schoolid}").Except(tbschools.Select(y => y.RowKey));
  229. if (ex.Count() > 0)
  230. {
  231. unsave.AddRange(ex);
  232. }
  233. }
  234. var areaschools = await _azureStorage.FindListByDict<ScSchool>(new Dictionary<string, object>() { { "PartitionKey", $"ScSchool" } ,{ "areaId",$"{areaId}" } });
  235. List<School> cosbdschools = new List<School>();
  236. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<School>(queryText: $"select value(c) from c where c.areaId='{areaId}'", requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  237. {
  238. cosbdschools.Add(item);
  239. }
  240. var tbs = areaschools.FindAll(x => areaschools.Select(z => z.schoolCode).Except(cosbdschools.Select(x => x.id)).Contains(x.schoolCode));
  241. List<CSchool> cSchools = new List<CSchool>();
  242. foreach (var sch in tbs) {
  243. cSchools.Add(new CSchool
  244. {
  245. id = sch.schoolCode,
  246. name = sch.schoolname,
  247. // admin = "1530606136",
  248. period = new List<string>() { sch.schooltypename },
  249. size = 100,
  250. });
  251. }
  252. var client = _azureCosmos.GetCosmosClient();
  253. List<School> schoolsfailed = new List<School>();
  254. List<School> schoolsScucess = new List<School>();
  255. List<string> failedmsg= new List<string>();
  256. foreach (var sc in cSchools)
  257. {
  258. List<Period> periods = new List<Period>();
  259. string campusId = Guid.NewGuid().ToString();
  260. sc.period.ForEach(x => {
  261. periods.Add(new Period { id = Guid.NewGuid().ToString(), name = x, campusId = campusId });
  262. });
  263. School school = new School
  264. {
  265. id = sc.id,
  266. name = sc.name,
  267. size = sc.size,
  268. code = "Base",
  269. campuses = new List<Campus> { new Campus { name = sc.name, id = campusId } },
  270. region = "中国",
  271. province = "四川省",
  272. city = $"{city}",
  273. timeZone = new SDK.Models.TimeZone { label = "(UTC+08:00) 北京,重庆,香港特别行政区,乌鲁木齐", value = "+08:00" },
  274. type = 1,
  275. pk = "School",
  276. ttl = -1,
  277. schoolCode = sc.id,
  278. dist=$"{dist}",
  279. period = periods,
  280. areaId =$"{areaId}",
  281. standard=$"{standard}"
  282. };
  283. try
  284. {
  285. await client.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<School>(school, new PartitionKey(school.code));
  286. schoolsScucess.Add(school);
  287. }
  288. catch (CosmosException ex)
  289. {
  290. failedmsg.Add($"{school.ToJsonString()}\n \n{ex.Status}{ex.Message }\n {ex.StackTrace}");
  291. schoolsfailed.Add(school);
  292. }
  293. catch (Exception ex) {
  294. failedmsg.Add($"{school.ToJsonString()}\n{ex.Message }\n {ex.StackTrace}");
  295. schoolsfailed.Add(school);
  296. }
  297. }
  298. //省平台获取到的学生。
  299. List<ScTeacher> teachers = new();
  300. // 5.3.1.2获取学员名单
  301. (status, json) = await _httpTrigger.RequestHttpTrigger(dict, _option.Location, "GetTeachersListByProject");
  302. if (status == 200)
  303. {
  304. teachers = json.ToObject<List<ScTeacher>>(new JsonSerializerOptions { PropertyNameCaseInsensitive = false });
  305. if (teachers.IsNotEmpty()) {
  306. teachers.ForEach(x => {
  307. x.RowKey = $"{x.PXID}";
  308. x.PartitionKey = "ScTeacher";
  309. x.areaId = $"{areaId}";
  310. });
  311. var areaTeacher = await _azureStorage.FindListByDict<ScSchool>(new Dictionary<string, object>() { { "PartitionKey", $"ScTeacher" }, { "areaId", $"{areaId}" } });
  312. if (areaTeacher.IsNotEmpty())
  313. {
  314. // areaTeacher
  315. }
  316. else
  317. {
  318. teachers= await _azureStorage.SaveAll(teachers);
  319. }
  320. }
  321. }
  322. return Ok(new {
  323. projects, msg=$"Table中已经有:{tbschools.Count}个学校,省平台获取到:{schools.Count}个学校,本次保存有:{saveschools?.Count},没有被保存的学校:{unsave.Count},创建失败的学校有:{schoolsfailed.Count()},创建成功的的学校有:{schoolsScucess.Count()}",
  324. schoolsfailed,
  325. failedmsg,
  326. schoolsScucess,
  327. tbsch= tbschools.Select(x=>new { x.schoolname,x.schoolCode})
  328. });
  329. }
  330. /// <summary>
  331. /// 检查醍摩豆id存在多个学校的情况
  332. /// </summary>
  333. /// <param name="request"></param>
  334. /// <returns></returns>
  335. [ProducesDefaultResponseType]
  336. [HttpPost("sc/check-bind")]
  337. [AllowAnonymous]
  338. public async Task<IActionResult> CheckBlobBinds(JsonElement json)
  339. {
  340. List<GroupList> teachers = new List<GroupList>();
  341. string sqs = "select c.members from c where c.pk='GroupList' and c.type='yxtrain' and c.school in ('pjsyzx','pjzx','pjsazx','pjbjxx','pjxnxx','pjthxx','pjcyxx','pjfxxx','pjwjxx','pjzyzx','psywgy','hscjzx','cyhjnz','psasmx','psacjz','pwxjnx','pptsfx','pjjysx','xlzjnx','pdtjnx','pgxjnx','pcjjnx','pdxjnx','pnjyey','pbjyey','pcbyey','pcxyey','pcnyey','xjwhye','pxlyey','sazxye','saxcye','pthyey','psmyey','pshyey','pwxyey','pjysye','pfxyey','pgxyey','pcjyey','pcyhye','pbyyey','pdtyey','xyheye','xhyey','xbeyey','hhzyey','xxyey','saxgye','xllxye','dxxmye','dtxmye','dtydye','pnjdxy','pcxgmy','pcbgqy','saxccq','pjjsjx') ";
  342. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupList>(queryText: sqs))
  343. {
  344. teachers.Add(item);
  345. }
  346. var a = teachers.SelectMany(x => x.members).GroupBy(y=>y.id).ToList();
  347. var ae= a.Select(x => new { key = x.Key, val = x.ToList().Count() });
  348. ae= ae.Where(x => x.val > 1);
  349. return Ok(new { ae });
  350. }
  351. /// <summary>
  352. ///
  353. /// </summary>
  354. /// <param name="request"></param>
  355. /// <returns></returns>
  356. [ProducesDefaultResponseType]
  357. [HttpPost("sc/fix-bind")]
  358. [AllowAnonymous]
  359. public async Task<IActionResult> FixBlobBinds(JsonElement json)
  360. {
  361. List<string> teacherids = new List<string>();
  362. string sql = $" SELECT value(c.id) FROM c where ARRAY_LENGTH(c.binds)>0 ";
  363. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<string>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  364. {
  365. teacherids.Add(item);
  366. }
  367. var bloblist = await _azureStorage.GetBlobContainerClient("teammodelos").List($"yxpt/scpjx/scbind");
  368. bloblist = bloblist.Select(x => x.Substring(18, 10)).ToList();
  369. List<string> tmdids = teacherids.Except(bloblist).ToList();
  370. List<Teacher> teachers = new List<Teacher>();
  371. sql = $" SELECT value(c) FROM c where ARRAY_LENGTH(c.binds)>0 ";
  372. if (tmdids != null)
  373. {
  374. sql = $"{sql} and c.id in ( {string.Join(",", tmdids.Select(x => $"'{x}'"))} )";
  375. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sql,
  376. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  377. {
  378. teachers.Add(item);
  379. }
  380. }
  381. List<string> unbind = new List<string>();
  382. List<string> list = new List<string>();
  383. HashSet<string> schoolIds= teachers.Where(z=>z.schools.IsNotEmpty()).SelectMany(x => x.schools).Where(m=>m.status.Equals("join")).Select(y => y.schoolId).ToHashSet();
  384. List<GroupList> groupLists = new List<GroupList>();
  385. foreach (var schoolid in schoolIds) {
  386. StringBuilder queryText = new StringBuilder($"SELECT distinct value(c) FROM c where c.type='yxtrain'");
  387. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupList>(queryText: queryText.ToString(),
  388. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{schoolid}") }))
  389. {
  390. groupLists.Add(item);
  391. }
  392. }
  393. foreach (var teacher in teachers)
  394. {
  395. var a = teacher.binds.SelectMany(y => y.data).ToList().Find(x => !string.IsNullOrEmpty(x));
  396. if (a != null)
  397. {
  398. await _azureStorage.UploadFileByContainer("teammodelos", a, $"yxpt/scpjx/scbind", $"{teacher.id}.json");
  399. }
  400. else
  401. {
  402. unbind.Add(teacher.id);
  403. }
  404. if (teacher.schools.IsNotEmpty())
  405. {
  406. foreach (var school in teacher.schools)
  407. {
  408. if (!string.IsNullOrEmpty(school.schoolId) )
  409. {
  410. if (school.status.Equals("join")) {
  411. List<GroupList> yxtrain = groupLists.FindAll(x=>x.code.Equals($"GroupList-{school.schoolId}"));
  412. if (yxtrain.IsNotEmpty())
  413. {
  414. var meber = yxtrain.SelectMany(x => x.members).Where(y => y.id.Equals(teacher.id));
  415. //不在研修名单
  416. if (meber == null || meber.Count() <= 0)
  417. {
  418. yxtrain[0].members.Add(new Member { id = teacher.id, type = 1 });
  419. await GroupListService.UpsertList(yxtrain[0], _azureCosmos, _configuration, _serviceBus);
  420. }
  421. }
  422. else
  423. {
  424. GroupList groupList = new GroupList()
  425. {
  426. id = Guid.NewGuid().ToString(),
  427. code = $"GroupList-{school.schoolId}",
  428. creatorId = teacher.id,
  429. type = "yxtrain",
  430. year = DateTimeOffset.UtcNow.Year,
  431. members = new List<Member> { new Member { id = teacher.id, type = 1 } },
  432. scope = "school",
  433. school = school.schoolId,
  434. name = "研修名单",
  435. pk = "GroupList",
  436. ttl = -1
  437. };
  438. await GroupListService.UpsertList(groupList, _azureCosmos, _configuration, _serviceBus);
  439. }
  440. }
  441. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(teacher.id, new PartitionKey($"Teacher-{school.schoolId}"));
  442. if (response.Status != 200)
  443. {
  444. SchoolTeacher schoolTeacher = new SchoolTeacher
  445. {
  446. id = teacher.id,
  447. code = $"Teacher-{school.schoolId}",
  448. pk = "Teacher",
  449. name = teacher.name,
  450. picture = teacher.picture,
  451. size = 0,
  452. roles = new List<string> { "teacher" },
  453. permissions = new List<string>(),
  454. status = school.status,
  455. createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  456. ttl = -1
  457. };
  458. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync(teacher.id, new PartitionKey($"Teacher-{school.schoolId}"));
  459. }
  460. else {
  461. JsonDocument document = await JsonDocument.ParseAsync(response.ContentStream);
  462. SchoolTeacher schoolTeacher = document.RootElement.ToObject<SchoolTeacher>();
  463. schoolTeacher.status =school.status;
  464. schoolTeacher.pk = "Teacher";
  465. schoolTeacher.name = teacher.name;
  466. schoolTeacher.picture = teacher.picture;
  467. if (schoolTeacher.roles.IsEmpty() || !schoolTeacher.roles.Contains("teacher"))
  468. {
  469. schoolTeacher.roles = new List<string> { "teacher" };
  470. }
  471. schoolTeacher.permissions = schoolTeacher.permissions.IsNotEmpty() ? schoolTeacher.permissions : new List<string>();
  472. schoolTeacher.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  473. schoolTeacher.ttl = -1;
  474. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync(schoolTeacher, schoolTeacher.id, new PartitionKey($"Teacher-{school.schoolId}"));
  475. }
  476. }
  477. }
  478. }
  479. }
  480. return Ok(new { unbind ,list});
  481. }
  482. /// <summary>
  483. ///
  484. /// </summary>
  485. /// <param name="request"></param>
  486. /// <returns></returns>
  487. [ProducesDefaultResponseType]
  488. [HttpPost("sc/bind")]
  489. [AllowAnonymous]
  490. public async Task<IActionResult> Bind(SSO sso) {
  491. try
  492. {
  493. Teacher teacher = null;
  494. if (string.IsNullOrEmpty(sso.id_token) && string.IsNullOrEmpty(sso.mobile)) {
  495. return Ok(new
  496. {
  497. location = _option.Location,
  498. status = 2,
  499. });
  500. }
  501. if (string.IsNullOrEmpty(sso.id_token) && !string.IsNullOrEmpty(sso.mobile)) {
  502. }
  503. JwtSecurityToken jwt = null;
  504. try {
  505. jwt = new JwtSecurityToken(sso.id_token);
  506. } catch (Exception ex) {
  507. await _dingDing.SendBotMsg($"OS,{_option.Location}\n绑定失败,出现的原因可能是 参数异常:\n{sso.ToJsonString()},{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  508. return BadRequest();
  509. }
  510. if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
  511. var id = jwt.Payload.Sub;
  512. jwt.Payload.TryGetValue("name", out object name);
  513. jwt.Payload.TryGetValue("picture", out object picture);
  514. ScSSOData scsso = HttpUtility.UrlDecode(sso.param, Encoding.UTF8).ToObject<ScSSOData>();
  515. var client = _azureCosmos.GetCosmosClient();
  516. try
  517. {
  518. teacher = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Teacher>(id, new PartitionKey("Base"));
  519. //先检查绑定的平台是否已经被绑定
  520. //四川研训平台跳转隐式登录/或者绑定IES平台接入规范
  521. string sql = $"SELECT distinct value(c) FROM c join A1 in c.binds where A1.tid='{scsso.tid}'";
  522. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sql,
  523. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  524. {
  525. teacher = item;
  526. break;
  527. }
  528. if (teacher != null)
  529. {
  530. if (teacher.id.Equals(id))
  531. {
  532. //var bind = teacher.binds.Find(x => x.source.Equals($"{scsso.Webid}") && x.userid.Equals($"{scsso.tid}"));
  533. var bind = teacher.binds.Find(x => x.userid.Equals($"{scsso.tid}"));
  534. if (bind == null)
  535. {
  536. teacher.binds = new List<Teacher.ThirdBind> { new Teacher.ThirdBind { data = new List<string> { scsso.data }, userid = $"{scsso.tid}",account=scsso.account,username=scsso.username, type = type } };
  537. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey(teacher.code));
  538. }
  539. else
  540. {
  541. bind.username=scsso.username;
  542. bind.account=scsso.account;
  543. var bindData = scsso.data.ToObject<ScBindData>();
  544. bool isnew = true;
  545. for (int index = 0; index < bind.data.Count; index++)
  546. {
  547. ScBindData scBind = bind.data[index].ToObject<ScBindData>();
  548. if (scBind.pxid.Equals(bindData.pxid))
  549. {
  550. bind.data[index] = bindData.ToJsonString();
  551. isnew = false;
  552. }
  553. }
  554. if (isnew)
  555. {
  556. bind.data.Add(bindData.ToJsonString());
  557. }
  558. if (bindData != null) {
  559. bindData.userid = scsso.tid;
  560. bindData.username=scsso.username;
  561. bindData.account = scsso.account;
  562. }
  563. if (teacher.schools.IsNotEmpty())
  564. {
  565. foreach (var school in teacher.schools)
  566. {
  567. if (!string.IsNullOrEmpty(school.schoolId))
  568. {
  569. if (school.status.Equals("join")) {
  570. StringBuilder queryText = new StringBuilder($"SELECT distinct value(c) FROM c where c.type='yxtrain'");
  571. List<GroupList> yxtrain = new List<GroupList>();
  572. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupList>(queryText: queryText.ToString(),
  573. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{school.schoolId}") }))
  574. {
  575. yxtrain.Add(item);
  576. }
  577. if (yxtrain.IsNotEmpty())
  578. {
  579. var meber = yxtrain.SelectMany(x => x.members).Where(y => y.id.Equals(teacher.id));
  580. //不在研修名单
  581. if (meber == null || meber.Count() <= 0)
  582. {
  583. yxtrain[0].members.Add(new Member { id = teacher.id, type = 1 });
  584. await GroupListService.UpsertList(yxtrain[0], _azureCosmos, _configuration, _serviceBus);
  585. }
  586. }
  587. else
  588. {
  589. GroupList groupList = new GroupList()
  590. {
  591. id = Guid.NewGuid().ToString(),
  592. code = $"GroupList-{school.schoolId}",
  593. creatorId = teacher.id,
  594. type = "yxtrain",
  595. year = DateTimeOffset.UtcNow.Year,
  596. members = new List<Member> { new Member { id = teacher.id, type = 1 } },
  597. scope = "school",
  598. school = school.schoolId,
  599. name = "研修名单",
  600. pk = "GroupList",
  601. ttl = -1
  602. };
  603. await GroupListService.UpsertList(groupList, _azureCosmos, _configuration, _serviceBus);
  604. }
  605. }
  606. Azure.Response response = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(teacher.id, new PartitionKey($"Teacher-{school.schoolId}"));
  607. if (response.Status != 200)
  608. {
  609. SchoolTeacher schoolTeacher = new SchoolTeacher
  610. {
  611. id = teacher.id,
  612. code = $"Teacher-{school.schoolId}",
  613. pk = "Teacher",
  614. name = teacher.name,
  615. picture = teacher.picture,
  616. size = 0,
  617. roles = new List<string> { "teacher" },
  618. permissions = new List<string>(),
  619. status = school.status,
  620. createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  621. ttl = -1
  622. };
  623. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync(schoolTeacher, new PartitionKey($"Teacher-{school.schoolId}"));
  624. }
  625. else {
  626. JsonDocument document = await JsonDocument.ParseAsync(response.ContentStream);
  627. SchoolTeacher schoolTeacher = document.RootElement.ToObject<SchoolTeacher>();
  628. schoolTeacher.status = school.status;
  629. schoolTeacher.pk = "Teacher";
  630. schoolTeacher.name = teacher.name;
  631. schoolTeacher.picture = teacher.picture;
  632. if (schoolTeacher.roles.IsEmpty() || !schoolTeacher.roles.Contains("teacher"))
  633. {
  634. schoolTeacher.roles = new List<string> { "teacher" };
  635. }
  636. schoolTeacher.permissions = schoolTeacher.permissions.IsNotEmpty() ? schoolTeacher.permissions : new List<string>();
  637. schoolTeacher.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  638. schoolTeacher.ttl = -1;
  639. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync(schoolTeacher, schoolTeacher.id, new PartitionKey($"Teacher-{school.schoolId}"));
  640. }
  641. }
  642. }
  643. }
  644. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey(teacher.code));
  645. await _azureStorage.UploadFileByContainer("teammodelos", bindData.ToJsonString(), $"yxpt/{scsso.path}/scbind", $"{teacher.id}.json");
  646. }
  647. }
  648. else
  649. {
  650. return Ok(new
  651. {
  652. location = _option.Location,
  653. //账号已被别的醍摩豆id绑定
  654. status = 3,
  655. tmdid = teacher.id,
  656. name = teacher.name,
  657. tid = scsso.tid
  658. });
  659. }
  660. }
  661. }
  662. catch (CosmosException ex)
  663. {
  664. teacher = new Teacher
  665. {
  666. id = id,
  667. pk = "Teacher",
  668. code = "Base",
  669. name = name?.ToString(),
  670. picture = picture?.ToString(),
  671. //创建账号并第一次登录IES5则默认赠送1G
  672. size = 1,
  673. defaultSchool = null,
  674. schools = new List<Teacher.TeacherSchool>(),
  675. binds = new List<Teacher.ThirdBind> { new Teacher.ThirdBind { data = new List<string> { scsso.data }, userid = $"{scsso.tid}", /*source = $"{scsso.Webid}",*/ type = type } }
  676. };
  677. var container = _azureStorage.GetBlobContainerClient(id);
  678. await container.CreateIfNotExistsAsync(PublicAccessType.None); //嘗試創建Teacher私有容器,如存在則不做任何事,保障容器一定存在
  679. teacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<Teacher>(teacher, new PartitionKey("Base"));
  680. ScBindData bindData = scsso.data.ToObject<ScBindData>();
  681. if (bindData != null)
  682. {
  683. bindData.userid = scsso.tid;
  684. bindData.username = scsso.username;
  685. bindData.account = scsso.account;
  686. await _azureStorage.UploadFileByContainer("teammodelos", bindData.ToJsonString(), $"yxpt/{scsso.path}/scbind", $"{teacher.id}.json");
  687. }
  688. else {
  689. await _azureStorage.UploadFileByContainer("teammodelos", scsso.data.ToJsonString(), $"yxpt/{scsso.path}/scbind", $"{teacher.id}.json");
  690. }
  691. }
  692. catch (Exception ex) {
  693. await _dingDing.SendBotMsg($"OS,{_option.Location}\n绑定失败:\n{sso.ToJsonString()},{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  694. return Ok(new
  695. {
  696. location = _option.Location,
  697. status = 2,
  698. });
  699. }
  700. return Ok(new
  701. {
  702. location = _option.Location,
  703. status = 200,
  704. });
  705. } catch (Exception ex ) {
  706. await _dingDing.SendBotMsg($"OS,{_option.Location}\n绑定失败:\n{sso.ToJsonString()},{ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  707. return Ok(new
  708. {
  709. location = _option.Location,
  710. status = 2,
  711. });
  712. }
  713. }
  714. /// <summary>
  715. /// 动态地址路由。"config":"scsyxpt","path":"sc{pjx/jinniu}"
  716. /// </summary>
  717. /// <param name="request"></param>
  718. /// <returns></returns>
  719. [HttpGet("{path}/sso")]
  720. [AllowAnonymous]
  721. public async Task<IActionResult> Sso([FromQuery] ScSSO scsso,string path)
  722. {
  723. var HostName = HttpContext.GetHostName();
  724. if (path.Equals("sc"))
  725. {
  726. path = $"scpjx";
  727. }
  728. else
  729. {
  730. path = $"sc{path}";
  731. }
  732. //var rurl = new StringBuilder($"https://{_option.HostName}/sso");
  733. var rurl = new StringBuilder($"https://{HostName}/sso");
  734. try {
  735. string parmas = $"Pxid={scsso.Pxid}&Webid={scsso.Webid}&tid={scsso.tid}&time={scsso.time}";
  736. if (Md5Hash.GetMd5String(parmas).Equals($"{scsso.Encrypt}"))
  737. {
  738. //四川研训平台跳转隐式登录/或者绑定IES平台接入规范
  739. long ssotime = long.Parse($"{scsso.time}");
  740. long nowtime = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
  741. if (nowtime - ssotime > 60 * 10)//10分钟有效期
  742. {
  743. // return Ok(new { status = 2, msg = "登录超时!" });
  744. }
  745. }
  746. else
  747. {
  748. return Redirect(rurl.Append($"?status=1").ToString());
  749. }
  750. string setsql = $"select value(c) from c where contains(c.accessConfig,'{path}') and contains(c.accessConfig,'scsyxpt') ";
  751. AreaSetting setting = null;
  752. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Normal").GetItemQueryIterator<AreaSetting>(queryText: setsql,
  753. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"AreaSetting") }))
  754. {
  755. setting = item;
  756. break;
  757. }
  758. if (setting==null ||(setting != null && string.IsNullOrEmpty(setting.accessConfig)))
  759. {
  760. return Redirect(rurl.Append($"?status=1").ToString());
  761. }
  762. string accessConfig = setting.accessConfig;
  763. Dictionary<string, object> dict = new Dictionary<string, object> { { "accessConfig", accessConfig }, { "pxid", scsso.Pxid }, { "tid", scsso.tid } };
  764. string SchoolName = "", SchoolID = "", ProjectID = "", ProjectItemID = "", TeacherName = "" , Account="";
  765. (int status, string json) = await _httpTrigger.RequestHttpTrigger(dict, _option.Location, "GetSingleTeacherByProject");
  766. if (status == 200)
  767. {
  768. ScTeacher scTeacher = json.ToObject<ScTeacher>(new JsonSerializerOptions { PropertyNameCaseInsensitive = false });
  769. if (scTeacher != null && $"{scTeacher.PXID}".Equals(scsso.Pxid) && $"{scTeacher.TID}".Equals(scsso.tid))
  770. {
  771. SchoolName = scTeacher.SchoolName;
  772. SchoolID = $"{scTeacher.SchoolID}";
  773. ProjectID = $"{ scTeacher.ProjectID}";
  774. ProjectItemID = $"{ scTeacher.ProjectItemID}";
  775. TeacherName = $"{ scTeacher.TeacherName}";
  776. Account = $"{ scTeacher.Account}";
  777. }
  778. }
  779. else {
  780. await _dingDing.SendBotMsg($"OS,{_option.Location}\n省平台教师信息:\nstatus:{status}{json}\n{dict.ToJsonString()} \nGetSingleTeacherByProject", GroupNames.成都开发測試群組);
  781. }
  782. ScBindData bindData = new ScBindData
  783. {
  784. sn = SchoolName,
  785. sid = SchoolID,
  786. pd = ProjectID,
  787. pid = ProjectItemID,
  788. pxid = scsso.Pxid,
  789. userid = scsso.tid,
  790. username = TeacherName,
  791. account = Account,
  792. path = path,
  793. };
  794. var data = bindData.ToJsonString();
  795. ScSSOData sso = new ScSSOData {
  796. username = TeacherName,
  797. account=Account,
  798. path = path,
  799. Pxid = scsso.Pxid,
  800. Encrypt = scsso.Encrypt,
  801. tid = scsso.tid,
  802. time = scsso.time,
  803. data= data
  804. };
  805. Teacher teacher = null;
  806. //四川研训平台跳转隐式登录/或者绑定IES平台接入规范
  807. //string sql = $"SELECT distinct value(c) FROM c join A1 in c.binds where A1.pxid='{sso.Pxid}' and A1.webid='{sso.Webid}' and A1.tid='{sso.tid}'";
  808. string sql = $"SELECT distinct value(c) FROM c join A1 in c.binds where A1.userid='{sso.tid}'";
  809. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sql,
  810. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  811. {
  812. teacher = item;
  813. break;
  814. }
  815. if (teacher == null)
  816. {
  817. //string enurl = HttpUtility.UrlEncode(rurl.Append($"?status=4&param={sso.ToJsonString()}&type={type}&bindurl=sc/bind").ToString());
  818. string enurl = $"status=4&param={HttpUtility.UrlEncode(sso.ToJsonString(), Encoding.UTF8)}&type={type}&bindurl=sc/bind";
  819. return Redirect(rurl.Append($"?{enurl}").ToString());
  820. }
  821. else
  822. {
  823. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  824. var location = _option.Location;
  825. TmdidImplicit implicit_token = await _coreAPIHttpService.Implicit(
  826. new Dictionary<string, string>()
  827. {
  828. { "grant_type", "implicit" },
  829. { "client_id",clientID },
  830. { "account",teacher.id },
  831. { "nonce",Guid.NewGuid().ToString()}
  832. },location,_configuration);
  833. if (implicit_token!=null)
  834. {
  835. if (string.IsNullOrEmpty(implicit_token.id_token)) {
  836. await _dingDing.SendBotMsg($"OS,隐式登录获得信息为空:{_option.Location}-\n{scsso.ToJsonString()} \npath:{path}\n{implicit_token.ToJsonString()}", GroupNames.成都开发測試群組);
  837. return Redirect(rurl.Append($"?status=1").ToString());
  838. }
  839. var bind = teacher.binds.Find(x => x.userid.Equals(sso.tid));
  840. //var bind = teacher.binds.Find(x => x.userid.Equals(sso.tid) && x.source.Equals(sso.Webid));
  841. if (bind != null)
  842. {
  843. bool isnew = true;
  844. for (int index = 0;index< bind.data.Count; index++) {
  845. ScBindData scBind = bind.data[index].ToObject<ScBindData>();
  846. if (scBind.pxid.Equals(bindData.pxid))
  847. {
  848. bind.data[index]= bindData.ToJsonString();
  849. isnew = false;
  850. }
  851. }
  852. if (isnew)
  853. {
  854. bind.data.Add(bindData.ToJsonString());
  855. }
  856. bind.username = TeacherName;
  857. bind.account = Account;
  858. if (teacher.schools.IsNotEmpty()) {
  859. foreach (var school in teacher.schools) {
  860. if (!string.IsNullOrEmpty(school.schoolId) ) {
  861. if (school.status.Equals("join")) {
  862. StringBuilder queryText = new StringBuilder($"SELECT distinct value(c) FROM c where c.type='yxtrain'");
  863. List<GroupList> yxtrain = new List<GroupList>();
  864. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIterator<GroupList>(queryText: queryText.ToString(),
  865. requestOptions: new QueryRequestOptions() { PartitionKey = new Azure.Cosmos.PartitionKey($"GroupList-{school.schoolId}") }))
  866. {
  867. yxtrain.Add(item);
  868. }
  869. if (yxtrain.IsNotEmpty())
  870. {
  871. var meber = yxtrain.SelectMany(x => x.members).Where(y => y.id.Equals(teacher.id));
  872. //不在研修名单
  873. if (meber == null || meber.Count() <= 0)
  874. {
  875. yxtrain[0].members.Add(new Member { id = teacher.id, type = 1 });
  876. await GroupListService.UpsertList(yxtrain[0], _azureCosmos, _configuration, _serviceBus);
  877. }
  878. }
  879. else
  880. {
  881. GroupList groupList = new GroupList()
  882. {
  883. id = Guid.NewGuid().ToString(),
  884. code = $"GroupList-{school.schoolId}",
  885. creatorId = teacher.id,
  886. type = "yxtrain",
  887. year = DateTimeOffset.UtcNow.Year,
  888. members = new List<Member> { new Member { id = teacher.id, type = 1 } },
  889. scope = "school",
  890. school = school.schoolId,
  891. name = "研修名单",
  892. pk = "GroupList",
  893. ttl = -1
  894. };
  895. await GroupListService.UpsertList(groupList, _azureCosmos, _configuration, _serviceBus);
  896. }
  897. }
  898. Azure.Response response= await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(teacher.id, new PartitionKey($"Teacher-{school.schoolId}"));
  899. if (response.Status != 200) {
  900. SchoolTeacher schoolTeacher = new SchoolTeacher
  901. {
  902. id = teacher.id,
  903. code = $"Teacher-{school.schoolId}",
  904. pk= "Teacher",
  905. name=teacher.name,
  906. picture= teacher.picture,
  907. size=0,
  908. roles=new List<string> { "teacher" },
  909. permissions= new List<string>(),
  910. status=school.status,
  911. createTime=DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  912. ttl=-1
  913. };
  914. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync(schoolTeacher, new PartitionKey($"Teacher-{school.schoolId}"));
  915. }
  916. else
  917. {
  918. JsonDocument document = await JsonDocument.ParseAsync(response.ContentStream);
  919. SchoolTeacher schoolTeacher = document.RootElement.ToObject<SchoolTeacher>();
  920. schoolTeacher.status =school.status;
  921. schoolTeacher.pk = "Teacher";
  922. schoolTeacher.name = teacher.name;
  923. schoolTeacher.picture = teacher.picture;
  924. if (schoolTeacher.roles.IsEmpty() ||! schoolTeacher.roles.Contains("teacher")) {
  925. schoolTeacher.roles = new List<string> { "teacher" };
  926. }
  927. schoolTeacher.permissions = schoolTeacher.permissions.IsNotEmpty()? schoolTeacher.permissions: new List<string>();
  928. schoolTeacher.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  929. schoolTeacher.ttl = -1;
  930. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync(schoolTeacher, schoolTeacher.id, new PartitionKey($"Teacher-{school.schoolId}"));
  931. }
  932. }
  933. }
  934. }
  935. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey(teacher.code));
  936. }
  937. try
  938. {
  939. await _azureStorage.UploadFileByContainer("teammodelos", bindData.ToJsonString(), $"yxpt/{sso.path}/scbind", $"{teacher.id}.json");
  940. }
  941. catch (Exception ex) {
  942. await _dingDing.SendBotMsg($"OS,{_option.Location}-\n文件失败 \npath:{path}\n{ex.StackTrace}\n{ex.Message}\n yxpt/{sso.path}/scbind/{teacher.id}.json", GroupNames.醍摩豆服務運維群組);
  943. }
  944. rurl.Append($"?status=200&id_token={implicit_token.id_token}&access_token={implicit_token.access_token}&expires_in={HttpUtility.UrlEncode(implicit_token.expires_in)}&token_type={HttpUtility.UrlEncode(implicit_token.token_type)}").ToString();
  945. string uri = rurl.ToString();
  946. return Redirect(uri);
  947. }
  948. else
  949. {
  950. //绑定失效
  951. if (teacher.binds.IsNotEmpty())
  952. {
  953. // teacher.binds.RemoveAll(x => x.userid.Equals(sso.tid) && x.source.Equals(sso.Webid));
  954. teacher.binds.RemoveAll(x => x.userid.Equals(sso.tid) );
  955. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey(teacher.code));
  956. }
  957. // string enurl = HttpUtility.UrlEncode(rurl.Append($"status=4&param={sso.ToJsonString()}&type={type}&bindurl=sc/bind").ToString());
  958. string enurl = $"status=4&param={HttpUtility.UrlEncode(sso.ToJsonString(),Encoding.UTF8)}&type={type}&bindurl=sc/bind";
  959. return Redirect(rurl.Append($"?{enurl}").ToString());
  960. }
  961. }
  962. } catch (Exception ex) {
  963. await _dingDing.SendBotMsg($"OS,{_option.Location}-\n{scsso.ToJsonString()} \npath:{path}\n{ex.StackTrace}\n{ex.Message}", GroupNames.醍摩豆服務運維群組);
  964. return Redirect(rurl.Append($"?status=1").ToString());
  965. }
  966. }
  967. }
  968. }