LoginController.cs 41 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. using Azure.Cosmos;
  2. using DingTalk.Api;
  3. using DingTalk.Api.Request;
  4. using DingTalk.Api.Response;
  5. using Microsoft.AspNetCore.Http;
  6. using Microsoft.AspNetCore.Mvc;
  7. using Microsoft.Extensions.Configuration;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Text.Json;
  12. using System.Threading.Tasks;
  13. using TEAMModelOS.SDK.DI;
  14. using TEAMModelOS.SDK.Models;
  15. using HTEXLib.COMM.Helpers;
  16. using TEAMModelOS.Models;
  17. using Microsoft.Extensions.Options;
  18. using TEAMModelOS.SDK.Extension;
  19. using TEAMModelOS.SDK.Models.Service;
  20. using Microsoft.AspNetCore.Authorization;
  21. using Azure.Storage.Blobs.Models;
  22. using System.IdentityModel.Tokens.Jwt;
  23. using System.Net.Http;
  24. using System.Text;
  25. using System.Net;
  26. using Newtonsoft.Json;
  27. using System.Collections;
  28. using Newtonsoft.Json.Linq;
  29. using static TEAMModelOS.SDK.Models.Teacher;
  30. //using static DingTalk.Api.Response.OapiV2UserGetResponse;
  31. namespace TEAMModeBI.Controllers
  32. {
  33. [ProducesResponseType(StatusCodes.Status200OK)]
  34. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  35. [Route("common/login")]
  36. [ApiController]
  37. public class LoginController : ControllerBase
  38. {
  39. private readonly IConfiguration _configuration;
  40. //数据容器
  41. private readonly AzureCosmosFactory _azureCosmos;
  42. //文件容器
  43. private readonly AzureStorageFactory _azureStorage;
  44. //钉钉提示信息
  45. private readonly DingDing _dingDing;
  46. private readonly Option _option;
  47. //隐式登录
  48. private readonly CoreAPIHttpService _aoreAPIHttpService;
  49. string type = "ddteammodel";
  50. public LoginController(IConfiguration configuration, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, DingDing dingDing, IOptionsSnapshot<Option> option, CoreAPIHttpService aoreAPIHttpService)
  51. {
  52. _configuration = configuration;
  53. _azureCosmos = azureCosmos;
  54. _azureStorage = azureStorage;
  55. _dingDing = dingDing;
  56. _option = option?.Value;
  57. _aoreAPIHttpService = aoreAPIHttpService;
  58. }
  59. /// <summary>
  60. /// 钉钉扫描登录
  61. /// </summary>
  62. /// <param name="loginTmpCode"></param>
  63. /// <returns>Json结果</returns>
  64. [ProducesDefaultResponseType]
  65. [HttpGet("dingding")]
  66. public IActionResult DingDingLogin(string loginTmpCode)
  67. {
  68. string appKey = _configuration["DingDingAuth:appKey"];
  69. string appSecret = _configuration["DingDingAuth:appSecret"];
  70. string getuserinfo_bycode = _configuration["DingDingAuth:getuserinfo_bycode"];
  71. //判断参数是否为空
  72. if (string.IsNullOrEmpty(loginTmpCode))
  73. {
  74. return BadRequest("temp code error");
  75. }
  76. //获取access_token
  77. DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  78. OapiGettokenRequest request = new OapiGettokenRequest();
  79. request.Appkey = appKey;
  80. request.Appsecret = appSecret;
  81. request.SetHttpMethod("Get");
  82. OapiGettokenResponse response = client.Execute(request);
  83. if (response.IsError)
  84. {
  85. return BadRequest();
  86. }
  87. string access_token = response.AccessToken;
  88. //获取临时授权码 获取授权用户的个人信息
  89. DefaultDingTalkClient client1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/sns/getuserinfo_bycode");
  90. OapiSnsGetuserinfoBycodeRequest bycodeRequest = new OapiSnsGetuserinfoBycodeRequest()
  91. {
  92. //通过扫描二维码,跳转到指定的Url后,向Url中追加Code临时授权码
  93. TmpAuthCode = loginTmpCode
  94. };
  95. OapiSnsGetuserinfoBycodeResponse bycodeResponse = client1.Execute(bycodeRequest, appKey, appSecret);
  96. if (bycodeResponse.IsError)
  97. {
  98. return BadRequest();
  99. }
  100. //根据unionid获取userid
  101. string unionid = bycodeResponse.UserInfo.Unionid;
  102. DefaultDingTalkClient clientDingTalkClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/getbyunionid");
  103. OapiUserGetbyunionidRequest byunionidRequest = new OapiUserGetbyunionidRequest()
  104. {
  105. Unionid = unionid
  106. };
  107. OapiUserGetbyunionidResponse byunionidResponse = clientDingTalkClient.Execute(byunionidRequest, access_token);
  108. if (byunionidResponse.IsError)
  109. {
  110. return BadRequest();
  111. }
  112. string userid = byunionidResponse.Result.Userid;
  113. //根据userId获取用户信息
  114. DefaultDingTalkClient clientDingTalkClient2 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
  115. OapiV2UserGetRequest getRequest = new OapiV2UserGetRequest()
  116. {
  117. Userid = userid,
  118. Language = "zh_CN"
  119. };
  120. getRequest.SetHttpMethod("Get");
  121. OapiV2UserGetResponse getResponse = clientDingTalkClient2.Execute(getRequest, access_token);
  122. if (getResponse.IsError)
  123. {
  124. return BadRequest();
  125. }
  126. return Ok(getResponse.Body);
  127. }
  128. /// <summary>
  129. /// 钉钉扫码登录
  130. /// 先获取是否在钉钉架构中
  131. /// 获取数据库是否有该人员
  132. /// </summary>
  133. /// <param name="jsonElement"></param>
  134. /// <returns>Json结果</returns>
  135. [ProducesDefaultResponseType]
  136. [HttpPost("DingLogin")]
  137. [AllowAnonymous]
  138. public async Task<IActionResult> DingLogin(JsonElement jsonElement)
  139. {
  140. //state 是前端传入的,钉钉并不会修改,比如有多种登录方式的时候,一个登录方法判断登录方式可以进行不同的处理。
  141. try
  142. {
  143. string str_appKey = _configuration["DingDingAuth:appKey"];
  144. string str_appSecret = _configuration["DingDingAuth:appSecret"];
  145. if (string.IsNullOrWhiteSpace(str_appKey) || string.IsNullOrWhiteSpace(str_appSecret))
  146. {
  147. return Ok(new { status = 0, message = "扫码登录失败" });
  148. }
  149. //自己传的code
  150. if (!jsonElement.TryGetProperty("code", out JsonElement LoginTempCode)) return BadRequest();
  151. //获取企业内部应用的accessToken
  152. DefaultDingTalkClient Iclient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  153. OapiGettokenRequest request = new OapiGettokenRequest();
  154. request.Appkey = str_appKey;
  155. request.Appsecret = str_appSecret;
  156. request.SetHttpMethod("GET");
  157. OapiGettokenResponse tokenResponse = Iclient.Execute(request);
  158. if (tokenResponse.IsError)
  159. {
  160. return Ok(new { status = 0, message = "扫码登录失败" });
  161. }
  162. string access_token = tokenResponse.AccessToken;
  163. //获取临时授权码 获取授权用户的个人信息
  164. DefaultDingTalkClient clientinfo = new DefaultDingTalkClient("https://oapi.dingtalk.com/sns/getuserinfo_bycode");
  165. OapiSnsGetuserinfoBycodeRequest req = new OapiSnsGetuserinfoBycodeRequest() { TmpAuthCode = $"{LoginTempCode}" }; //通过扫描二维码,跳转到指定的Url后,向Url中追加Code临时授权码
  166. OapiSnsGetuserinfoBycodeResponse response = clientinfo.Execute(req, str_appKey, str_appSecret);
  167. if (response.IsError)
  168. {
  169. return Ok(new { status = 0, message = "扫码登录失败" });
  170. }
  171. string unionid = response.UserInfo.Unionid;
  172. IDingTalkClient client2 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/getbyunionid"); //userid地址
  173. OapiUserGetbyunionidRequest byunionidRequest = new OapiUserGetbyunionidRequest() { Unionid = unionid };
  174. OapiUserGetbyunionidResponse byunionidResponse = client2.Execute(byunionidRequest, access_token);
  175. if (byunionidResponse.IsError)
  176. {
  177. return Ok(new { status = 0, message = "扫码登录失败" });
  178. }
  179. // 根据userId获取用户信息
  180. string userid = byunionidResponse.Result.Userid;
  181. IDingTalkClient client3 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
  182. OapiV2UserGetRequest v2GetRequest = new OapiV2UserGetRequest()
  183. {
  184. Userid = userid,
  185. Language = "zh_CN"
  186. };
  187. v2GetRequest.SetHttpMethod("POST");
  188. OapiV2UserGetResponse v2GetResponse = client3.Execute(v2GetRequest, access_token);
  189. if (v2GetResponse.IsError)
  190. {
  191. return Ok(new { status = 0, message = "扫码登录失败" });
  192. }
  193. var DDbind = v2GetResponse.Result;
  194. List<DeptOrderDomain> deptOrderDomain_List = new List<DeptOrderDomain>();
  195. if (DDbind.DeptOrderList != null)
  196. {
  197. foreach (var temp in DDbind.DeptOrderList)
  198. {
  199. DeptOrderDomain deptOrderDomain = new DeptOrderDomain();
  200. deptOrderDomain.deptId = temp.DeptId;
  201. deptOrderDomain.order = temp.Order;
  202. deptOrderDomain_List.Add(deptOrderDomain);
  203. }
  204. }
  205. List<DeptPositionDomain> deptPositionDomain_List = new List<DeptPositionDomain>();
  206. if (DDbind.DeptPositionList != null)
  207. {
  208. foreach (var temp in DDbind.DeptPositionList)
  209. {
  210. DeptPositionDomain deptPositionDomain = new DeptPositionDomain();
  211. deptPositionDomain.deptId = temp.DeptId;
  212. deptPositionDomain.isMain = temp.IsMain;
  213. deptPositionDomain.title = temp.Title;
  214. deptPositionDomain.workPlace = temp.WorkPlace;
  215. deptPositionDomain_List.Add(deptPositionDomain);
  216. }
  217. }
  218. List<DeptLeaderDomain> deptLeaderDomain_List = new List<DeptLeaderDomain>();
  219. if (DDbind.LeaderInDept != null)
  220. {
  221. foreach (var temp in DDbind.LeaderInDept)
  222. {
  223. DeptLeaderDomain deptLeaderDomain = new DeptLeaderDomain();
  224. deptLeaderDomain.deptId = temp.DeptId;
  225. deptLeaderDomain.leader = temp.Leader;
  226. deptLeaderDomain_List.Add(deptLeaderDomain);
  227. }
  228. }
  229. List<UserRoleDomain> userRoleDomain_list = new List<UserRoleDomain>();
  230. if (DDbind.RoleList != null)
  231. {
  232. foreach (var temp in DDbind.RoleList)
  233. {
  234. UserRoleDomain userRoleDomain = new UserRoleDomain();
  235. userRoleDomain.groupName = temp.GroupName;
  236. userRoleDomain.id = temp.Id;
  237. userRoleDomain.name = temp.Name;
  238. userRoleDomain_list.Add(userRoleDomain);
  239. }
  240. }
  241. UnionEmpExtDomain unionEmpExtDomain = new UnionEmpExtDomain();
  242. if (DDbind.UnionEmpExt != null)
  243. {
  244. unionEmpExtDomain.corpId = DDbind.UnionEmpExt.CorpId;
  245. List<UnionEmpMapVoDomain> unionEmpMapVoDomain_list = new List<UnionEmpMapVoDomain>();
  246. if (DDbind.UnionEmpExt.UnionEmpMapList != null)
  247. {
  248. foreach (var temp in DDbind.UnionEmpExt.UnionEmpMapList)
  249. {
  250. UnionEmpMapVoDomain unionEmpMapVoDomain = new UnionEmpMapVoDomain();
  251. unionEmpMapVoDomain.corpId = temp.CorpId;
  252. unionEmpMapVoDomain.userid = temp.Userid;
  253. unionEmpMapVoDomain_list.Add(unionEmpMapVoDomain);
  254. }
  255. }
  256. unionEmpExtDomain.unionEmpMapList = unionEmpMapVoDomain_list;
  257. unionEmpExtDomain.userid = DDbind.UnionEmpExt.Userid;
  258. }
  259. DingDingbinds dingDingBind = new DingDingbinds
  260. {
  261. type = type,
  262. active = DDbind.Avatar,
  263. admin = DDbind.Admin,
  264. avatar = DDbind.Avatar,
  265. boss = DDbind.Boss,
  266. deptIdList = DDbind.DeptIdList,
  267. deptOrderList = deptOrderDomain_List,//DDbind.DeptOrderList?.ToJsonString().ToObject<List<DeptOrderDomain>>(),
  268. deptPositionList = deptPositionDomain_List, //DDbind.DeptPositionList,
  269. jobNumber = DDbind.JobNumber,
  270. leaderInDept = deptLeaderDomain_List,//DDbind.LeaderInDept,
  271. managerUserid = DDbind.ManagerUserid,
  272. mobile = DDbind.Mobile,
  273. roleList = userRoleDomain_list,//DDbind.RoleList,
  274. senior = DDbind.Senior,
  275. title = DDbind.Title,
  276. unionEmpExt = unionEmpExtDomain,//DDbind.UnionEmpExt,
  277. name = DDbind.Name,
  278. unionid = DDbind.Unionid,
  279. userid = DDbind.Userid,
  280. };
  281. Teacher teacher = null;
  282. string sql = $"select distinct value(c) from c join A1 in c.ddbinds where A1.userid='{dingDingBind.userid}' AND A1.unionid ='{dingDingBind.unionid}'";
  283. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  284. {
  285. teacher = item;
  286. break;
  287. }
  288. if (teacher == null)
  289. {
  290. return Ok(new { status = 1, dingDingBind = dingDingBind });
  291. }
  292. else
  293. {
  294. var url = _configuration.GetValue<string>("HaBookAuth:CoreAPI");
  295. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  296. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  297. var logintion = _option.Location;
  298. //隐式登录
  299. (int code, string content) = await _aoreAPIHttpService.Implicit(clientID, clientSecret, logintion, $"{url}/oauth2/implicit",
  300. new Dictionary<string, string>()
  301. {
  302. { "grant_type", "implicit" },
  303. { "client_id",clientID},
  304. { "account",teacher.id},
  305. { "nonce",Guid.NewGuid().ToString()}
  306. });
  307. TmdidImplicit implicit_token = new TmdidImplicit();
  308. if (!string.IsNullOrEmpty(content) && code == 200)
  309. {
  310. implicit_token = content.ToObject<TmdidImplicit>();
  311. var ddbind = teacher.ddbinds.Find(x => x.userid.Equals($"{dingDingBind.userid}") && x.unionid.Equals($"{dingDingBind.unionid}"));
  312. if (ddbind != null)
  313. {
  314. return Ok(new { status = 200, teacher = teacher, id_token = implicit_token.id_token, access_token = implicit_token.access_token, expires_in = implicit_token.expires_in, token_type = implicit_token.token_type });
  315. }
  316. }
  317. return Ok(new { status = 1, dingdinginfo = dingDingBind });
  318. }
  319. }
  320. catch (Exception e)
  321. {
  322. return Ok(new { status = 1, message = "code失效" });
  323. }
  324. }
  325. /// <summary>
  326. /// 发送验证码
  327. /// </summary>
  328. /// <param name="jsonElement"></param>
  329. /// <returns></returns>
  330. [ProducesDefaultResponseType]
  331. [HttpPost("send-sms")]
  332. public async Task<IActionResult> send_sms(JsonElement jsonElement)
  333. {
  334. try
  335. {
  336. if (!jsonElement.TryGetProperty("country", out JsonElement country)) return BadRequest();
  337. if (!jsonElement.TryGetProperty("to", out JsonElement to)) return BadRequest();
  338. if (!jsonElement.TryGetProperty("lang", out JsonElement lang)) return BadRequest();
  339. if (!jsonElement.TryGetProperty("HasUser", out JsonElement HasUser)) return BadRequest();
  340. string smsurl = _configuration.GetValue<string>("HaBookAuth:CoreAPI");
  341. HttpClient httpClient = new HttpClient();
  342. var content = new StringContent(jsonElement.ToString(), Encoding.UTF8, "application/json");
  343. HttpResponseMessage responseMessage = await httpClient.PostAsync($"{smsurl}/service/sandsms/pin", content);
  344. if (responseMessage.StatusCode == HttpStatusCode.OK)
  345. {
  346. string str_json = await responseMessage.Content.ReadAsStringAsync();
  347. if (string.IsNullOrEmpty($"{str_json}"))
  348. {
  349. return Ok(new { status = 200, message = "发送成功" });
  350. }
  351. else
  352. {
  353. JsonElement json = str_json.ToObject<JsonElement>();
  354. return Ok(json);
  355. }
  356. }
  357. else
  358. {
  359. return Ok(new { status = 0, message = "发送失败!" });
  360. }
  361. }
  362. catch (Exception ex)
  363. {
  364. return Ok(new { status = 0, message = $"发送失败!{ex.Message}" });
  365. }
  366. }
  367. /// <summary>
  368. /// 验证码和手机的验证
  369. /// </summary>
  370. /// <param name="jsonElement"></param>
  371. /// <returns></returns>
  372. [ProducesDefaultResponseType]
  373. [HttpPost("verfiypin")]
  374. public async Task<IActionResult> VerifiyPIN(JsonElement jsonElement)
  375. {
  376. try
  377. {
  378. if (!jsonElement.TryGetProperty("mobile", out JsonElement mobile)) return BadRequest();
  379. if (!jsonElement.TryGetProperty("Authorization_Pin", out JsonElement sms)) return BadRequest();
  380. string smsurl = _configuration.GetValue<string>("HaBookAuth:CoreAPI");
  381. HttpClient httpClient = new HttpClient();
  382. var temp_job = new { Authorization_Pin = sms };
  383. var content = new StringContent(temp_job.ToJsonString(), Encoding.UTF8, "application/json");
  384. HttpResponseMessage responseMessage = await httpClient.PostAsync($"{smsurl}/service/verifiy/pin", content);
  385. if (responseMessage.StatusCode == HttpStatusCode.OK)
  386. {
  387. string responseBody = await responseMessage.Content.ReadAsStringAsync();
  388. var json = responseBody.ToObject<JsonElement>();
  389. json.TryGetProperty("resule", out JsonElement jsone);
  390. if (!string.IsNullOrEmpty($"{jsone}"))
  391. {
  392. string[] mobules = $"{jsone}".Split("-");
  393. string temp_mobile = mobules.Length >= 2 ? mobules[1] : mobules[0];
  394. if (mobile.ToString().Equals(temp_mobile))
  395. {
  396. return Ok(new { status = 200, message = "手机号和验证码验证都过了" });
  397. }
  398. else
  399. {
  400. return Ok(new { status = 5, message = "手机号码不正确" });
  401. }
  402. }
  403. else
  404. {
  405. return Ok(json);
  406. }
  407. }
  408. else
  409. {
  410. return Ok(new { status = 0, message = "发送状态错误" });
  411. }
  412. }
  413. catch (Exception ex)
  414. {
  415. return Ok(new { status = 0, message = $"发送状态错误{ex.Message}" });
  416. }
  417. }
  418. /// <summary>
  419. /// 钉钉绑定醍摩豆信息
  420. /// </summary>
  421. /// <param name="ddbindparam"></param>
  422. /// <returns></returns>
  423. [ProducesDefaultResponseType]
  424. [HttpPost("bind")]
  425. [AllowAnonymous]
  426. public async Task<IActionResult> Bind(JsonElement jsonElement)
  427. {
  428. try
  429. {
  430. jsonElement.TryGetProperty("mobile", out JsonElement mobile);
  431. jsonElement.TryGetProperty("idToken", out JsonElement idToken);
  432. if (!jsonElement.TryGetProperty("param", out JsonElement param)) return BadRequest();
  433. HttpClient httpClient = new HttpClient();
  434. Teacher teacher = new Teacher();
  435. DingDingbinds ddbinds = param.ToObject<DingDingbinds>(); //将json数据转换为实体类
  436. TmdidImplicit implicit_token = new TmdidImplicit();
  437. if (!string.IsNullOrEmpty($"{mobile}"))
  438. {
  439. List<JsonElement> mbs = new List<JsonElement>() { mobile };
  440. string url = _configuration.GetValue<string>("HaBookAuth:CoreId:userinfo");
  441. var content = new StringContent(mbs.ToJsonString(), Encoding.UTF8, "application/json");
  442. HttpResponseMessage responseMessage = await httpClient.PostAsync(url, content);
  443. if (responseMessage.StatusCode == HttpStatusCode.OK)
  444. {
  445. string responseBody = await responseMessage.Content.ReadAsStringAsync();
  446. List<JsonElement> json_id = responseBody.ToObject<List<JsonElement>>();
  447. string temp_id = null;
  448. if (json_id.IsNotEmpty())
  449. {
  450. temp_id = json_id[0].GetProperty("id").ToString();
  451. }
  452. var client = _azureCosmos.GetCosmosClient();
  453. teacher = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Teacher>(temp_id, new PartitionKey("Base"));
  454. string sql = $"SELECT distinct value(c) FROM c join A1 in c.ddbinds where A1.userid='{ddbinds.userid}' and A1.unionid='{ddbinds.unionid}'";
  455. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sql,
  456. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  457. {
  458. teacher = item;
  459. break;
  460. }
  461. if (teacher != null)
  462. {
  463. if (teacher.id.Equals(temp_id))
  464. {
  465. var infourl = _configuration.GetValue<string>("HaBookAuth:CoreAPI");
  466. var clientID = _configuration.GetValue<string>("HaBookAuth:CoreService:clientID");
  467. var clientSecret = _configuration.GetValue<string>("HaBookAuth:CoreService:clientSecret");
  468. var location = _option.Location;
  469. (int code, string temp_content) = await _aoreAPIHttpService.Implicit(clientID, clientSecret, location, $"{infourl}/oauth2/implicit", new Dictionary<string, string>()
  470. {
  471. { "grant_type", "implicit" },
  472. { "client_id",clientID },
  473. { "account",teacher.id },
  474. { "nonce",Guid.NewGuid().ToString()}
  475. });
  476. if (!string.IsNullOrEmpty(temp_content) && code == 200)
  477. {
  478. implicit_token = temp_content.ToObject<TmdidImplicit>();
  479. var ddbind = teacher.ddbinds.Find(x => x.userid.Equals($"{ddbinds.userid}") && x.unionid.Equals($"{ddbinds.unionid}"));
  480. if (ddbind == null)
  481. {
  482. teacher.ddbinds = new List<Teacher.DingDingBind> { new Teacher.DingDingBind { type = $"{type}", active = ddbinds.active, admin = ddbinds.admin, avatar = ddbinds.avatar, boss = ddbinds.boss, deptIdList = ddbinds.deptIdList, deptOrderList = ddbinds.deptOrderList, deptPositionList = ddbinds.deptPositionList, jobNumber = ddbinds.jobNumber, leaderInDept = ddbinds.leaderInDept, managerUserid = ddbinds.managerUserid, mobile = ddbinds.mobile, roleList = ddbinds.roleList, senior = ddbinds.senior, title = ddbinds.title, unionEmpExt = ddbinds.unionEmpExt, name = ddbinds.name, unionid = ddbinds.unionid, userid = ddbinds.userid } };
  483. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey(teacher.code));
  484. }
  485. }
  486. else
  487. {
  488. if (teacher.ddbinds.IsNotEmpty())
  489. {
  490. teacher.ddbinds.RemoveAll(x => x.userid.Equals(ddbinds.userid) && x.unionid.Equals(ddbinds.unionid));
  491. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey(teacher.code));
  492. }
  493. return Ok(new { status = 1, message = "绑定失败" });
  494. }
  495. }
  496. else
  497. {
  498. return Ok(new
  499. {
  500. location = _option.Location,
  501. //账号已被别的醍摩豆id绑定
  502. status = 2,
  503. tmdid = teacher.id,
  504. name = teacher.name,
  505. ddid = ddbinds.userid,
  506. ddname = ddbinds.name
  507. });
  508. }
  509. }
  510. else
  511. {
  512. teacher = new Teacher
  513. {
  514. id = temp_id,
  515. pk = "Base",
  516. code = "Base",
  517. name = temp_id,
  518. //创建账号并第一次登录IES5则默认赠送1G
  519. size = 1,
  520. defaultSchool = null,
  521. schools = new List<Teacher.TeacherSchool>(),
  522. ddbinds = new List<Teacher.DingDingBind> { new Teacher.DingDingBind { type = $"{type}", active = ddbinds.active, admin = ddbinds.admin, avatar = ddbinds.avatar, boss = ddbinds.boss, deptIdList = ddbinds.deptIdList, deptOrderList = ddbinds.deptOrderList, deptPositionList = ddbinds.deptPositionList, jobNumber = ddbinds.jobNumber, leaderInDept = ddbinds.leaderInDept, managerUserid = ddbinds.managerUserid, mobile = ddbinds.mobile, roleList = ddbinds.roleList, senior = ddbinds.senior, title = ddbinds.title, unionEmpExt = ddbinds.unionEmpExt, name = ddbinds.name, unionid = ddbinds.unionid, userid = ddbinds.userid } },
  523. };
  524. var container = _azureStorage.GetBlobContainerClient(temp_id);
  525. await container.CreateIfNotExistsAsync(PublicAccessType.None); //尝试创建Teacher私有容器,如存在则不做任何事,保障容器一定存在
  526. teacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<Teacher>(teacher, new PartitionKey("Base"));
  527. }
  528. }
  529. else
  530. {
  531. return Ok(new { status = 3, message = "通过手机号查询用户信息异常" });
  532. }
  533. }
  534. if (!string.IsNullOrEmpty($"{idToken}"))
  535. {
  536. var jwt = new JwtSecurityToken($"{idToken}");
  537. if (!jwt.Payload.Iss.Equals("account.teammodel", StringComparison.OrdinalIgnoreCase)) return BadRequest();
  538. var id = jwt.Payload.Sub;
  539. jwt.Payload.TryGetValue("name", out object name);
  540. jwt.Payload.TryGetValue("picture", out object picture);
  541. //检查是否有绑定信息
  542. var client = _azureCosmos.GetCosmosClient();
  543. teacher = await client.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemAsync<Teacher>(id, new PartitionKey("Base"));
  544. string sql = $"select distinct value(c) from c join A1 in c.ddbinds where A1.userid='{ddbinds.userid}' AND A1.unionid ='{ddbinds.unionid}'";
  545. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sql,
  546. requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey($"Base") }))
  547. {
  548. teacher = item;
  549. break;
  550. }
  551. if (teacher != null)
  552. {
  553. if (teacher.id.Equals(id))
  554. {
  555. var ddbind = teacher.ddbinds.Find(x => x.userid.Equals($"{ddbinds.userid}") && x.unionid.Equals($"{ddbinds.unionid}"));
  556. if (ddbind == null)
  557. {
  558. teacher.ddbinds = new List<Teacher.DingDingBind> { new Teacher.DingDingBind { type = $"{type}", active = ddbinds.active, admin = ddbinds.admin, avatar = ddbinds.avatar, boss = ddbinds.boss, deptIdList = ddbinds.deptIdList, deptOrderList = ddbinds.deptOrderList, deptPositionList = ddbinds.deptPositionList, jobNumber = ddbinds.jobNumber, leaderInDept = ddbinds.leaderInDept, managerUserid = ddbinds.managerUserid, mobile = ddbinds.mobile, roleList = ddbinds.roleList, senior = ddbinds.senior, title = ddbinds.title, unionEmpExt = ddbinds.unionEmpExt, name = ddbinds.name, unionid = ddbinds.unionid, userid = ddbinds.userid } };
  559. await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey(teacher.code));
  560. }
  561. return Ok(new
  562. {
  563. status = 200,
  564. idToken = idToken,
  565. teacher = teacher,
  566. location = _option.Location,
  567. });
  568. }
  569. else
  570. {
  571. return Ok(new
  572. {
  573. location = _option.Location,
  574. //账号已被别的醍摩豆id绑定
  575. status = 2,
  576. tmdid = teacher.id,
  577. name = teacher.name,
  578. userid = ddbinds.userid,
  579. ddname = ddbinds.name
  580. });
  581. }
  582. }
  583. else
  584. {
  585. teacher = new Teacher
  586. {
  587. id = id,
  588. pk = "Base",
  589. code = "Base",
  590. name = name?.ToString(),
  591. picture = picture?.ToString(),
  592. //创建账号并第一次登录IES5则默认赠送1G
  593. size = 1,
  594. defaultSchool = null,
  595. schools = new List<Teacher.TeacherSchool>(),
  596. ddbinds = new List<Teacher.DingDingBind> { new Teacher.DingDingBind { type = $"{type}", active = ddbinds.active, admin = ddbinds.admin, avatar = ddbinds.avatar, boss = ddbinds.boss, deptIdList = ddbinds.deptIdList, deptOrderList = ddbinds.deptOrderList, deptPositionList = ddbinds.deptPositionList, jobNumber = ddbinds.jobNumber, leaderInDept = ddbinds.leaderInDept, managerUserid = ddbinds.managerUserid, mobile = ddbinds.mobile, roleList = ddbinds.roleList, senior = ddbinds.senior, title = ddbinds.title, unionEmpExt = ddbinds.unionEmpExt, name = ddbinds.name, unionid = ddbinds.unionid, userid = ddbinds.userid } }
  597. };
  598. var container = _azureStorage.GetBlobContainerClient(id);
  599. await container.CreateIfNotExistsAsync(PublicAccessType.None); //尝试创建Teacher私有容器,如存在则不做任何事,保障容器一定存在
  600. teacher = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<Teacher>(teacher, new PartitionKey("Base"));
  601. return Ok(new
  602. {
  603. status = 200,
  604. idToken = id,
  605. teacher = teacher,
  606. location = _option.Location,
  607. });
  608. }
  609. }
  610. string temp_idToken = string.IsNullOrEmpty($"{idToken}") ? implicit_token.id_token : idToken.ToString();
  611. return Ok(new
  612. {
  613. status = 200,
  614. idToken = temp_idToken,
  615. teacher = teacher,
  616. location = _option.Location,
  617. });
  618. }
  619. catch (Exception)
  620. {
  621. return Ok(new
  622. {
  623. status = 1,
  624. location = _option.Location
  625. });
  626. }
  627. }
  628. public record DingDingbinds
  629. {
  630. public string type { get; set; }
  631. /// <summary>
  632. /// 是否激活
  633. /// </summary>
  634. public string active { get; set; }
  635. /// <summary>
  636. /// 是否管理员
  637. /// </summary>
  638. public bool admin { get; set; }
  639. /// <summary>
  640. /// 头像
  641. /// </summary>
  642. public string avatar { get; set; }
  643. /// <summary>
  644. /// 是否老板
  645. /// </summary>
  646. public bool boss { get; set; }
  647. /// <summary>
  648. /// 所属部门id列表
  649. /// </summary>
  650. public List<long> deptIdList { get; set; }
  651. /// <summary>
  652. /// 员工在对应的部门中的排序
  653. /// </summary>
  654. public List<DeptOrderDomain> deptOrderList { get; set; }
  655. /// <summary>
  656. /// 任职信息
  657. /// </summary>
  658. public List<DeptPositionDomain> deptPositionList { get; set; }
  659. /// <summary>
  660. /// 员工工号
  661. /// </summary>
  662. public string jobNumber { get; set; }
  663. /// <summary>
  664. /// 员工在对应的部门中是否领导。
  665. /// </summary>
  666. public List<DeptLeaderDomain> leaderInDept { get; set; }
  667. /// <summary>
  668. /// 主管的ID,仅限企业内部开发调用
  669. /// </summary>
  670. public string managerUserid { get; set; }
  671. /// <summary>
  672. /// 手机号
  673. /// </summary>
  674. public string mobile { get; set; }
  675. /// <summary>
  676. /// 角色列表
  677. /// </summary>
  678. public List<UserRoleDomain> roleList { get; set; }
  679. /// <summary>
  680. /// 是否高管
  681. /// </summary>
  682. public bool senior { get; set; }
  683. /// <summary>
  684. /// 职位名称
  685. /// </summary>
  686. public string title { get; set; }
  687. /// <summary>
  688. /// 关联信息
  689. /// </summary>
  690. public UnionEmpExtDomain unionEmpExt { get; set; }
  691. /// <summary>
  692. /// 钉钉用户名
  693. /// </summary>
  694. public string name { get; set; }
  695. /// <summary>
  696. /// 钉钉unionid
  697. /// </summary>
  698. public string unionid { get; set; }
  699. /// <summary>
  700. /// 钉钉ID
  701. /// </summary>
  702. public string userid { get; set; }
  703. }
  704. /// <summary>
  705. /// 员工在对应的部门中的排序的数据结构
  706. /// </summary>
  707. //public record DeptOrderDomain
  708. //{
  709. // /// <summary>
  710. // /// 部门id
  711. // /// </summary>
  712. // public long deptId { get; set; }
  713. // /// <summary>
  714. // /// 员工在部门中的排序。
  715. // /// </summary>
  716. // public long order { get; set; }
  717. //}
  718. ///// <summary>
  719. ///// 任职信息数据结构
  720. ///// </summary>
  721. //public record DeptPositionDomain
  722. //{
  723. // /// <summary>
  724. // /// 部门ID
  725. // /// </summary>
  726. // public long deptId { get; set; }
  727. // /// <summary>
  728. // /// 是否是主任职
  729. // /// </summary>
  730. // public bool isMain { get; set; }
  731. // /// <summary>
  732. // /// 部门内职位
  733. // /// </summary>
  734. // public string title { get; set; }
  735. // /// <summary>
  736. // /// 部门内工作地
  737. // /// </summary>
  738. // public string workPlace { get; set; }
  739. //}
  740. ///// <summary>
  741. ///// 员工在对应的部门中是否领导 数据结构
  742. ///// </summary>
  743. //public record DeptLeaderDomain
  744. //{
  745. // /// <summary>
  746. // /// 部门id
  747. // /// </summary>
  748. // public long deptId { get; set; }
  749. // /// <summary>
  750. // /// 是否领导
  751. // /// </summary>
  752. // public bool leader { get; set; }
  753. //}
  754. ///// <summary>
  755. ///// 角色列表 数据结构
  756. ///// </summary>
  757. //public record UserRoleDomain
  758. //{
  759. // /// <summary>
  760. // /// 角色组名称
  761. // /// </summary>
  762. // public string groupName { get; set; }
  763. // /// <summary>
  764. // /// 角色id
  765. // /// </summary>
  766. // public long id { get; set; }
  767. // /// <summary>
  768. // /// 角色名称
  769. // /// </summary>
  770. // public string name { get; set; }
  771. //}
  772. ///// <summary>
  773. ///// 关联信息 数据结构
  774. ///// </summary>
  775. //public record UnionEmpExtDomain
  776. //{
  777. // /// <summary>
  778. // /// 企业ID
  779. // /// </summary>
  780. // public string corpId { get; set; }
  781. // /// <summary>
  782. // /// 关联映射关系
  783. // /// </summary>
  784. // public List<UnionEmpMapVoDomain> unionEmpMapList { get; set; }
  785. // /// <summary>
  786. // /// 员工id
  787. // /// </summary>
  788. // public string userid { get; set; }
  789. //}
  790. ///// <summary>
  791. ///// 关联映射关系
  792. ///// </summary>
  793. //public record UnionEmpMapVoDomain
  794. //{
  795. // /// <summary>
  796. // /// 企业id
  797. // /// </summary>
  798. // public string corpId { get; set; }
  799. // /// <summary>
  800. // /// 用户id
  801. // /// </summary>
  802. // public string userid { get; set; }
  803. //}
  804. public record TmdidImplicit
  805. {
  806. public string id_token { get; set; }
  807. public string access_token { get; set; }
  808. public string expires_in { get; set; }
  809. public string token_type { get; set; }
  810. }
  811. }
  812. }