LePeiController.cs 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571
  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;
  15. using Microsoft.Extensions.Options;
  16. using Azure.Messaging.ServiceBus;
  17. using Microsoft.Extensions.Configuration;
  18. using HTEXLib.COMM.Helpers;
  19. using TEAMModelOS.SDK;
  20. using System.IdentityModel.Tokens.Jwt;
  21. using TEAMModelOS.Services;
  22. using TEAMModelOS.SDK.Models.Service;
  23. using System.IO;
  24. using System.Dynamic;
  25. using Microsoft.AspNetCore.Authorization;
  26. using Azure.Storage.Blobs.Models;
  27. using static TEAMModelOS.SDK.Models.Teacher;
  28. using System.Web;
  29. using static TEAMModelOS.Controllers.FixDataController;
  30. using static TEAMModelOS.SDK.SchoolService;
  31. using Microsoft.AspNetCore.Hosting;
  32. using Microsoft.Azure.Cosmos.Table;
  33. using System.Net.Http;
  34. using TEAMModelOS.SDK.Context.Attributes.Azure;
  35. using System.Security.Cryptography.Xml;
  36. using DocumentFormat.OpenXml.Office2010.Excel;
  37. using DocumentFormat.OpenXml.Wordprocessing;
  38. using Microsoft.OData.UriParser;
  39. using System.ComponentModel.DataAnnotations;
  40. using System.Runtime.Intrinsics.X86;
  41. using System.Security.Policy;
  42. using Top.Api;
  43. using Grpc.Core;
  44. namespace TEAMModelOS.Controllers.Third.LePei
  45. {
  46. [ApiController]
  47. public class LePeiController : ControllerBase
  48. {
  49. private readonly SnowflakeId _snowflakeId;
  50. private readonly AzureCosmosFactory _azureCosmos;
  51. private readonly DingDing _dingDing;
  52. private readonly Option _option;
  53. private readonly AzureStorageFactory _azureStorage;
  54. private readonly AzureServiceBusFactory _serviceBus;
  55. private readonly AzureRedisFactory _azureRedis;
  56. private readonly CoreAPIHttpService _coreAPIHttpService;
  57. public readonly string type = "scsyxpt";
  58. public readonly IHttpClientFactory _httpClientFactory;
  59. public IConfiguration _configuration { get; set; }
  60. public LePeiController(IWebHostEnvironment environment, AzureCosmosFactory azureCosmos, SnowflakeId snowflakeId, DingDing dingDing, IOptionsSnapshot<Option> option, AzureStorageFactory azureStorage,
  61. AzureRedisFactory azureRedis, AzureServiceBusFactory serviceBus, IConfiguration configuration, CoreAPIHttpService coreAPIHttpService, IHttpClientFactory httpClientFactory)
  62. {
  63. _azureCosmos = azureCosmos;
  64. _snowflakeId = snowflakeId;
  65. _dingDing = dingDing;
  66. _option = option?.Value;
  67. _azureStorage = azureStorage;
  68. _serviceBus = serviceBus;
  69. _configuration = configuration;
  70. _azureRedis = azureRedis;
  71. _coreAPIHttpService = coreAPIHttpService;
  72. _httpClientFactory = httpClientFactory;
  73. }
  74. [HttpPost("lepei/bind")]
  75. [AllowAnonymous]
  76. public async Task<IActionResult> Bind(LPBind bind) {
  77. string HostName = HttpContext.GetHostName();
  78. if (!string.IsNullOrWhiteSpace(_option.HostName))
  79. {
  80. HostName = _option.HostName;
  81. }
  82. if (!_option.Location.Contains("Dep"))
  83. {
  84. HostName = "www.teammodel.cn";
  85. }
  86. var rurl = new StringBuilder($"https://{HostName}/sso");
  87. try {
  88. TmdidImplicit tmdidImplicit = null;
  89. int status = 0;
  90. string msg = "账号未关联";
  91. LPTeacher teacherLP = null;
  92. var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt");
  93. LPSSOEncryptData encryptData = HttpUtility.UrlDecode(bind.param, Encoding.UTF8).ToObject<LPSSOEncryptData>();
  94. if (!string.IsNullOrWhiteSpace(bind.mobile))
  95. {
  96. var coreUser = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", bind.mobile } }, _option.Location, _configuration);
  97. if (coreUser != null)
  98. {
  99. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  100. tmdidImplicit = await _coreAPIHttpService.Implicit(new Dictionary<string, string> { { "grant_type", "implicit" },
  101. { "client_id",clientID },
  102. { "account",coreUser.id },
  103. { "nonce",Guid.NewGuid().ToString()} }, _option.Location, _configuration);
  104. if (tmdidImplicit != null && !string.IsNullOrWhiteSpace(tmdidImplicit.id_token))
  105. {
  106. bind.id_token = tmdidImplicit.id_token;
  107. }
  108. else
  109. {
  110. status = 7;
  111. }
  112. }
  113. else
  114. {
  115. status = 7;
  116. }
  117. }
  118. if (string.IsNullOrWhiteSpace(bind.id_token))
  119. {
  120. status =7;
  121. }
  122. else {
  123. JwtSecurityToken jwt = new JwtSecurityToken(bind.id_token);
  124. var id = jwt.Payload.Sub;
  125. CoreUser coreUserById = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", $"{id}" } }, _option.Location, _configuration);
  126. if (coreUserById == null || string.IsNullOrWhiteSpace(coreUserById.mobile) || coreUserById.mobile.Length != 11)
  127. {
  128. status = 7;
  129. }
  130. jwt.Payload.TryGetValue("name", out object name);
  131. jwt.Payload.TryGetValue("picture", out object picture);
  132. List<LPTeacher> teachers = await table.FindListByDict<LPTeacher>(new Dictionary<string, object>() { { Constant.PartitionKey, $"LPTeacher-{encryptData.schoolId}" }, { Constant.RowKey, encryptData.userId } });
  133. if (teachers.Any())
  134. {
  135. teacherLP=teachers.First();
  136. teacherLP.tmdid = id;
  137. }
  138. else {
  139. teacherLP = new LPTeacher()
  140. {
  141. PartitionKey = $"LPTeacher-{encryptData.schoolId}",
  142. RowKey = encryptData.userId,
  143. mobile = encryptData.mobile,
  144. path = encryptData.path,
  145. schoolId = encryptData.schoolId,
  146. userId = encryptData.userId,
  147. };
  148. }
  149. List<LPSchool> schools = await table.FindListByDict<LPSchool>(new Dictionary<string, object>() { { Constant.PartitionKey, $"LPSchool" }, { Constant.RowKey,$"{encryptData.schoolId}-{encryptData.appId}" }, { "path",encryptData. path } });
  150. if (schools.IsNotEmpty())
  151. {
  152. teacherLP.schoolCode = schools[0].schoolCode;
  153. //检查自动加入学校
  154. Azure.Response responseSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(teacherLP.schoolCode, new PartitionKey("Base"));
  155. if (responseSchool.Status == 200)
  156. {
  157. School school = JsonDocument.Parse(responseSchool.Content).RootElement.ToObject<School>();
  158. JoinSchool(id, name?.ToString(), picture?.ToString(), school);
  159. }
  160. }
  161. await table.SaveOrUpdate<LPTeacher>(teacherLP);
  162. status = 200;
  163. }
  164. if (status == 200)
  165. {
  166. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  167. var location = _option.Location;
  168. var implicit_token = await _coreAPIHttpService.Implicit(
  169. new Dictionary<string, string>()
  170. {
  171. { "grant_type", "implicit" },
  172. { "client_id",clientID },
  173. { "account",teacherLP.tmdid },
  174. { "nonce",Guid.NewGuid().ToString()}
  175. }, location, _configuration);
  176. if (implicit_token != null)
  177. {
  178. rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode("登录成功", Encoding.UTF8)}&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();
  179. return Redirect(rurl.ToString());
  180. }
  181. else {
  182. rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode("隐式登录异常", Encoding.UTF8)}");
  183. return Redirect(rurl.ToString());
  184. }
  185. }
  186. else if (status == 7)
  187. {
  188. msg = $"教师账号:{encryptData.userId},{encryptData.mobile}失败";
  189. rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode(msg, Encoding.UTF8)}&param={HttpUtility.UrlEncode(encryptData.ToJsonString(), Encoding.UTF8)}");
  190. return Redirect(rurl.ToString());
  191. }
  192. else
  193. {
  194. rurl.Append($"?status={7}&msg={HttpUtility.UrlEncode("账号未关联成功", Encoding.UTF8)}");
  195. return Redirect(rurl.ToString());
  196. }
  197. } catch (Exception ex) {
  198. await _dingDing.SendBotMsg($"乐培项目绑定账号异常,{ex.Message},{ex.StackTrace},\n{bind.ToJsonString()}", GroupNames.成都开发測試群組);
  199. }
  200. rurl.Append($"?status={7}&msg={HttpUtility.UrlEncode("账号未关联成功", Encoding.UTF8)}");
  201. return Redirect(rurl.ToString());
  202. }
  203. [HttpPost("{path}/lepei-sso")]
  204. [AllowAnonymous]
  205. public async Task<IActionResult> Sso(LPSSO sso, string path) {
  206. string HostName = HttpContext.GetHostName();
  207. if (!string.IsNullOrWhiteSpace(_option.HostName))
  208. {
  209. HostName = _option.HostName;
  210. }
  211. if (path.Equals("xinjin"))
  212. {
  213. if (!_option.Location.Contains("Dep"))
  214. {
  215. HostName = "www.teammodel.cn";
  216. }
  217. }
  218. var rurl = new StringBuilder($"https://{HostName}/lepei-sso");
  219. var table = _azureStorage.GetCloudTableClient().GetTableReference("ScYxpt");
  220. List<LPSchool> configs = await table.FindListByDict<LPSchool>(new Dictionary<string, object>() { { Constant.PartitionKey, "LPSchool" }, { Constant.RowKey,$"{sso.schoolId}-{sso.appId}"}, { "path",path } });
  221. LPTeacher teacher = null;
  222. int status = 4;//1项目未配置,2 账号未未关联,3账号已关联
  223. string msg = "账号未关联";
  224. TmdidImplicit implicit_token = null;
  225. LPSSOEncryptData encryptData = null;
  226. if (configs.Any())
  227. {
  228. LPSchool config = configs[0];
  229. string data = AESHelper.Decryptor(sso.encryptData, config.secretKey, config.secretKey.Substring(0, 16));
  230. encryptData = data.ToObject<LPSSOEncryptData>();
  231. encryptData.path = path;
  232. List<LPTeacher> teachers = await table.FindListByDict<LPTeacher>(new Dictionary<string, object>() { { Constant.PartitionKey, $"LPTeacher-{encryptData.schoolId}" }, { Constant.RowKey, encryptData.userId } });
  233. if (teachers.Any())
  234. {
  235. teacher = teachers[0];
  236. if (!string.IsNullOrWhiteSpace(teacher.tmdid))
  237. {
  238. status = 3;//已关联
  239. msg = "账号已关联";
  240. }
  241. else
  242. {
  243. //未绑定,尝试用手机号进行关联
  244. var coreUser = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", encryptData.mobile } }, _option.Location, _configuration);
  245. if (coreUser != null)
  246. {
  247. teacher.tmdid = coreUser.id;
  248. status = 3;//已关联
  249. msg = "账号已关联";
  250. }
  251. else
  252. {
  253. status = 4;
  254. }
  255. teacher.mobile = encryptData.mobile;
  256. await table.SaveOrUpdate<LPTeacher>(teacher);
  257. }
  258. }
  259. else
  260. {
  261. if (!string.IsNullOrWhiteSpace(encryptData.mobile))
  262. {
  263. List<LPSchool> schools = await table.FindListByDict<LPSchool>(new Dictionary<string, object>() { { Constant.PartitionKey, $"LPSchool" }, { Constant.RowKey, $"{sso.schoolId}-{sso.appId}" }, { "path", path } });
  264. if (schools.IsNotEmpty())
  265. {
  266. teacher = new LPTeacher()
  267. {
  268. PartitionKey = $"LPTeacher-{encryptData.schoolId}",
  269. RowKey = encryptData.userId,
  270. mobile = encryptData.mobile,
  271. path = path,
  272. schoolId = encryptData.schoolId,
  273. schoolCode = schools[0].schoolCode,
  274. userId = encryptData.userId,
  275. };
  276. //未绑定,尝试用手机号进行关联
  277. var coreUser = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", encryptData.mobile } }, _option.Location, _configuration);
  278. if (coreUser != null)
  279. {
  280. teacher.tmdid = coreUser.id;
  281. status = 3;//已关联
  282. msg = "账号已关联";
  283. }
  284. else
  285. {
  286. status = 4;
  287. }
  288. await table.SaveOrUpdate<LPTeacher>(teacher);
  289. }
  290. else
  291. {
  292. status = 5;
  293. msg = "学校信息未同步";
  294. }
  295. }
  296. else
  297. {
  298. status = 2;
  299. msg = "乐培教师信息没有手机号";
  300. }
  301. }
  302. if (status == 3)
  303. {
  304. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  305. var location = _option.Location;
  306. implicit_token = await _coreAPIHttpService.Implicit(
  307. new Dictionary<string, string>()
  308. {
  309. { "grant_type", "implicit" },
  310. { "client_id",clientID },
  311. { "account",teacher.tmdid },
  312. { "nonce",Guid.NewGuid().ToString()}
  313. }, location, _configuration);
  314. if (implicit_token != null)
  315. {
  316. if (string.IsNullOrWhiteSpace(implicit_token.id_token))
  317. {
  318. await _dingDing.SendBotMsg($"OS,隐式登录获得信息为空:{_option.Location}-\n{sso.ToJsonString()} \npath:{path}\n{implicit_token.ToJsonString()}", GroupNames.醍摩豆服務運維群組);
  319. status = 6;
  320. msg = "隐式登录异常";
  321. }
  322. else
  323. {
  324. status = 200;
  325. msg = "登录成功";
  326. if (!string.IsNullOrWhiteSpace(teacher.schoolCode)) {
  327. //检查自动加入学校
  328. Azure.Response responseSchool = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(teacher.schoolCode, new PartitionKey("Base"));
  329. if (responseSchool.Status == 200)
  330. {
  331. School school= JsonDocument.Parse(responseSchool.Content).RootElement.ToObject<School>();
  332. JwtSecurityToken jwt = new JwtSecurityToken(implicit_token.id_token);
  333. var id = jwt.Payload.Sub;
  334. jwt.Payload.TryGetValue("name", out object name);
  335. jwt.Payload.TryGetValue("picture", out object picture);
  336. JoinSchool(id, name?.ToString(), picture?.ToString(), school);
  337. }
  338. }
  339. }
  340. }
  341. else
  342. {
  343. status = 6;
  344. msg = "隐式登录异常";
  345. }
  346. }
  347. }
  348. else {
  349. status = 1;
  350. msg = $"未配置{path}项目";
  351. }
  352. if (status == 200)
  353. {
  354. rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode(msg, Encoding.UTF8)}&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();
  355. #if !DEBUG
  356. return Redirect(rurl.ToString());
  357. #else
  358. return Ok(new { code = 200, message = msg, data = rurl.ToString() });
  359. #endif
  360. }
  361. else if (status == 4) {
  362. msg = $"教师账号:{encryptData.userId},{encryptData.mobile}未关联";
  363. rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode(msg, Encoding.UTF8)}&mobile={encryptData.mobile}&param={HttpUtility.UrlEncode(encryptData.ToJsonString(), Encoding.UTF8)}");
  364. #if !DEBUG
  365. return Redirect(rurl.ToString());
  366. #else
  367. return Ok(new { code = 200, message = msg, data = rurl.ToString() });
  368. #endif
  369. }
  370. else
  371. {
  372. rurl.Append($"?status={status}&msg={HttpUtility.UrlEncode(msg, Encoding.UTF8)}");
  373. #if !DEBUG
  374. return Redirect(rurl.ToString());
  375. #else
  376. return Ok(new { code = 400, message = msg, data =rurl.ToString() });
  377. #endif
  378. }
  379. }
  380. private async void JoinSchool(string tmdid,string name ,string picture, School school )
  381. {
  382. Teacher teacher = null;
  383. Azure .Response responseTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemStreamAsync(tmdid, new PartitionKey("Base"));
  384. Azure.Response responseSchoolTeacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS,Constant.School).ReadItemStreamAsync(tmdid, new PartitionKey($"Teacher-{school.id}"));
  385. if (responseSchoolTeacher.Status != 200)
  386. {
  387. SchoolTeacher schoolTeacher = new SchoolTeacher
  388. {
  389. id = teacher.id,
  390. code = $"Teacher-{school.id}",
  391. roles = new List<string> { "teacher" },
  392. permissions = new List<string>(),
  393. pk = "Teacher",
  394. name = teacher.name,
  395. picture = teacher.picture,
  396. status = "join",
  397. createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  398. ttl = -1
  399. };
  400. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(schoolTeacher, new PartitionKey(schoolTeacher.code));
  401. }
  402. else {
  403. SchoolTeacher schoolTeacher= JsonDocument.Parse(responseSchoolTeacher.Content).RootElement.ToObject<SchoolTeacher>();
  404. if (schoolTeacher != null)
  405. {
  406. if (!schoolTeacher.roles.IsEmpty())
  407. {
  408. if (!schoolTeacher.roles.Contains("teacher"))
  409. {
  410. schoolTeacher.roles.Add("teacher");
  411. }
  412. }
  413. else
  414. {
  415. schoolTeacher.roles = new List<string> { "teacher" };
  416. }
  417. schoolTeacher.status = "join";
  418. schoolTeacher.pk = "Teacher";
  419. schoolTeacher.name = teacher.name;
  420. schoolTeacher.picture = teacher.picture;
  421. schoolTeacher.createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  422. schoolTeacher.ttl = -1;
  423. schoolTeacher.permissions = schoolTeacher.permissions.IsNotEmpty() ? schoolTeacher.permissions : new List<string>();
  424. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").UpsertItemAsync(schoolTeacher, new PartitionKey(schoolTeacher.code));
  425. }
  426. }
  427. if (responseTeacher.Status == 200)
  428. {
  429. teacher = JsonDocument.Parse(responseTeacher.Content).RootElement.ToObject<Teacher>();
  430. var sc=teacher.schools.Find(z => z.schoolId.Equals(school.id));
  431. if (sc == null) {
  432. teacher.schools.Add(new TeacherSchool
  433. {
  434. schoolId = school.id,
  435. name = school.name,
  436. picture = school.picture,
  437. status = "join",
  438. time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  439. areaId = school.areaId
  440. });
  441. teacher.defaultSchool = school.id;
  442. }
  443. }
  444. else {
  445. teacher = new Teacher
  446. {
  447. createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),
  448. id = tmdid,
  449. pk = "Teacher",
  450. code = "Base",
  451. name = name,
  452. picture = picture?.ToString(),
  453. //创建账号并第一次登录IES5则默认赠送1G
  454. size = 1,
  455. defaultSchool = school.id,
  456. schools = new List<Teacher.TeacherSchool>() { new TeacherSchool
  457. {
  458. schoolId=school.id,
  459. name=school.name,picture=school.picture,status="join",time=DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(),areaId=school.areaId
  460. } },
  461. };
  462. }
  463. }
  464. }
  465. public class LPBind
  466. {
  467. [Required(ErrorMessage = "{0} 必须填写")]
  468. public string param { get; set; }
  469. public string id_token { get; set; }
  470. public string mobile { get; set; }
  471. }
  472. public class LPSSO {
  473. public string appId { get; set; }
  474. public string schoolId { get; set; }
  475. public string encryptData { get; set; }
  476. }
  477. public class LPSSOEncryptData
  478. {
  479. public string appId { get; set; }
  480. public string schoolId { get; set; }
  481. public string userId { get; set; }
  482. public string mobile { get; set; }
  483. public string path { get; set; }
  484. }
  485. [TableName(Name = "ScYxpt")]
  486. public class LPTeacher :TableEntity
  487. {
  488. /// <summary>
  489. /// PartitionKey = "LPTeacher-{schoolId}"
  490. /// RowKey = $"{userId}"
  491. /// </summary>
  492. public string userId { get; set; }
  493. /// <summary>
  494. /// 乐陪对应的学校id
  495. /// </summary>
  496. public string schoolId { get; set; }
  497. /// <summary>
  498. /// 醍摩豆对应的学校编码
  499. /// </summary>
  500. public string schoolCode { get; set; }
  501. public string mobile { get; set; }
  502. public string tmdid { get; set; }
  503. /// <summary>
  504. /// {path}/lepei-sso 中的path
  505. /// </summary>
  506. public string path { get; set; }
  507. }
  508. [TableName(Name = "ScYxpt")]
  509. public class LPSchool : TableEntity
  510. {
  511. public LPSchool()
  512. {
  513. PartitionKey = "LPSchool";
  514. }
  515. /// <summary>
  516. /// PartitionKey = "LPSchool"
  517. /// RowKey = $"{schoolId学校id}"
  518. /// </summary>
  519. public string schoolId { get; set; }
  520. public string schoolName { get; set; }
  521. /// <summary>
  522. /// 醍摩豆对应的学校编码
  523. /// </summary>
  524. public string schoolCode { get; set; }
  525. /// <summary>
  526. /// {path}/lepei-sso 中的path
  527. /// </summary>
  528. public string path { get; set; }
  529. public string appId { get; set; }
  530. public string secretKey { get; set; }
  531. }
  532. [TableName(Name = "ScYxpt")]
  533. public class LPConfig : TableEntity
  534. {
  535. public LPConfig (){
  536. PartitionKey = "LPConfig-{appId}";
  537. }
  538. /// <summary>
  539. /// pk="LPConfig"
  540. /// rk=$"{path}"
  541. /// </summary>
  542. public string path { get; set; }
  543. public string appId { get; set;}
  544. public string secretKey { get; set; }
  545. }
  546. /*
  547. * https://easydoc.net/doc/61463617/Ufnsdona/k3Zb68pX
  548. 新津区外国语实验学校
  549. 乐陪学校ID:115
  550. 乐陪appId:1602542204202872832
  551. 乐陪密钥:Pk5Bmb4dl8aFYR5ezbgGpjdpXS4aFp4l
  552. 新津区五津初级中学
  553. 乐陪学校ID:116
  554. 乐陪appId:1602542306216734720
  555. 乐陪密钥:R7mCHT2QlidOxF8MasKjSKeWmaKXGOvG
  556. */
  557. }