TableDingDingInfoController.cs 63 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235
  1. using Microsoft.AspNetCore.Http;
  2. using Microsoft.AspNetCore.Mvc;
  3. using System;
  4. using System.Collections.Generic;
  5. using System.Linq;
  6. using System.Threading.Tasks;
  7. using TEAMModelOS.Models;
  8. using TEAMModelOS.SDK.DI;
  9. using Microsoft.Extensions.Options;
  10. using System.Net.Http;
  11. using Microsoft.Extensions.Configuration;
  12. using DingTalk.Api;
  13. using DingTalk.Api.Request;
  14. using DingTalk.Api.Response;
  15. using System.Text.Json;
  16. using System.Net.Http.Json;
  17. using TEAMModelOS.SDK.Models.Cosmos.BI;
  18. using System.Net;
  19. using TEAMModelOS.SDK.Extension;
  20. using OpenXmlPowerTools;
  21. using System.Text;
  22. using Azure.Cosmos;
  23. using Microsoft.Azure.Cosmos.Table;
  24. using TEAMModelBI.Filter;
  25. using TEAMModelBI.Tool.Extension;
  26. using TEAMModelBI.Models;
  27. using TEAMModelBI.Tool.CosmosBank;
  28. using TEAMModelBI.Tool.Context;
  29. namespace TEAMModelBI.Controllers.DingDingStruc
  30. {
  31. [Route("tabledd")]
  32. [ApiController]
  33. public class TableDingDingInfoController : ControllerBase
  34. {
  35. //读取配置文件
  36. private readonly IConfiguration _configuration;
  37. //数据容器
  38. private readonly AzureCosmosFactory _azureCosmos;
  39. //blob和table容器
  40. private readonly AzureStorageFactory _azureStorage;
  41. //钉钉提示信息
  42. private readonly DingDing _dingDing;
  43. private readonly Option _option;
  44. private readonly IHttpClientFactory _http;
  45. public TableDingDingInfoController(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, IOptionsSnapshot<Option> option, IConfiguration configuration, IHttpClientFactory http)
  46. {
  47. _azureCosmos = azureCosmos;
  48. _dingDing = dingDing;
  49. _azureStorage = azureStorage;
  50. _option = option?.Value;
  51. _http = http;
  52. _configuration = configuration;
  53. }
  54. /// <summary>
  55. /// 从钉钉的组织架构中人员信息数据,并保存或者更新至Blob中
  56. /// </summary>
  57. /// <returns></returns>
  58. [ProducesDefaultResponseType]
  59. [AuthToken(Roles = "admin")]
  60. [HttpPost("get-dingdingusers")]
  61. public async Task<IActionResult> GetDingDingUser(JsonElement jsonElement)
  62. {
  63. try
  64. {
  65. jsonElement.TryGetProperty("site", out JsonElement site);
  66. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  67. if ($"{site}".Equals(BIConst.GlobalSite))
  68. {
  69. table = _azureStorage.GetCloudTableClient(BIConst.GlobalSite).GetTableReference("BIDDUserInfo");
  70. }
  71. string appKey = _configuration["DingDingAuth:appKey"];
  72. string appSecret = _configuration["DingDingAuth:appSecret"];
  73. //string divide = _configuration["CustomParam:SiteScope"];
  74. string divide = _option.Location;
  75. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  76. HttpClient httpClient = _http.CreateClient();
  77. string url = _configuration.GetValue<string>("HaBookAuth:CoreId:userinfo");
  78. //获取access_token
  79. IDingTalkClient tokenClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  80. OapiGettokenRequest tokenRequest = new OapiGettokenRequest() { Appkey = appKey, Appsecret = appSecret };
  81. tokenRequest.SetHttpMethod("Get");
  82. OapiGettokenResponse tokenRespone = tokenClient.Execute(tokenRequest);
  83. if (tokenRespone.IsError)
  84. {
  85. return BadRequest();
  86. }
  87. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  88. string access_token = tokenRespone.AccessToken;
  89. //获取部门接口
  90. IDingTalkClient deptListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
  91. //一级部门
  92. OapiV2DepartmentListsubRequest reqDeptList1 = new OapiV2DepartmentListsubRequest() { DeptId = 1L, Language = "zh_CN" };
  93. OapiV2DepartmentListsubResponse rspDeptList1 = deptListClient.Execute(reqDeptList1, access_token);
  94. List<DingDingUserInfo> ddUserInfos = new();
  95. if (rspDeptList1.Result != null)
  96. {
  97. foreach (var tempDept1 in rspDeptList1.Result)
  98. {
  99. //获取一级部门用户信息
  100. List<DingDingUserInfo> dingDingUserInfos1 = await GetDingDingUserInfo(divide, tempDept1.DeptId, tempDept1.ParentId, tempDept1.Name, access_token);
  101. //if (dingDingUserInfos1.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos1.ToList()));
  102. if (dingDingUserInfos1.Count > 0) ddUserInfos.AddRange(dingDingUserInfos1);
  103. //获取二级部门
  104. OapiV2DepartmentListsubRequest reqDeptList2 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept1.DeptId, Language = "zh_CN" };
  105. OapiV2DepartmentListsubResponse rspDeptList2 = deptListClient.Execute(reqDeptList2, access_token);
  106. if (rspDeptList2.Result != null)
  107. {
  108. foreach (var tempDept2 in rspDeptList2.Result)
  109. {
  110. //获取二级部门用户信息
  111. List<DingDingUserInfo> dingDingUserInfos2 = await GetDingDingUserInfo(divide, tempDept2.DeptId, tempDept2.ParentId, tempDept2.Name, access_token);
  112. //if (dingDingUserInfos2.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos2.ToList()));
  113. if (dingDingUserInfos2.Count > 0) ddUserInfos.AddRange(dingDingUserInfos2);
  114. //获取三级部门
  115. OapiV2DepartmentListsubRequest reqDeptList3 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept2.DeptId, Language = "zh_CN" };
  116. OapiV2DepartmentListsubResponse rspDeptList3 = deptListClient.Execute(reqDeptList3, access_token);
  117. if (rspDeptList3.Result != null)
  118. {
  119. foreach (var tempDept3 in rspDeptList3.Result)
  120. {
  121. //获取三级部门用户信息
  122. List<DingDingUserInfo> dingDingUserInfos3 = await GetDingDingUserInfo(divide, tempDept3.DeptId, tempDept3.ParentId, tempDept3.Name, access_token);
  123. //if (dingDingUserInfos3.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos3.ToList()));
  124. if (dingDingUserInfos3.Count > 0) ddUserInfos.AddRange(dingDingUserInfos3);
  125. //获取四级部门
  126. OapiV2DepartmentListsubRequest reqDeptList4 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept3.DeptId, Language = "zh_CN" };
  127. OapiV2DepartmentListsubResponse rspDeptList4 = deptListClient.Execute(reqDeptList4, access_token);
  128. if (rspDeptList4.Result != null)
  129. {
  130. foreach (var tempDept4 in rspDeptList4.Result)
  131. {
  132. //获取四级部门用户信息
  133. List<DingDingUserInfo> dingDingUserInfos4 = await GetDingDingUserInfo(divide, tempDept4.DeptId, tempDept4.ParentId, tempDept4.Name, access_token);
  134. //if (dingDingUserInfos4.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos4.ToList()));
  135. if (dingDingUserInfos4.Count > 0) ddUserInfos.AddRange(dingDingUserInfos4);
  136. //获取五级部门
  137. OapiV2DepartmentListsubRequest reqDeptList5 = new OapiV2DepartmentListsubRequest() { DeptId = tempDept4.DeptId, Language = "zh_CN" };
  138. OapiV2DepartmentListsubResponse rspDeptList5 = deptListClient.Execute(reqDeptList5, access_token);
  139. if (rspDeptList5.Result != null)
  140. {
  141. foreach (var tempDept5 in rspDeptList5.Result)
  142. {
  143. //获取五级部门用户信息
  144. List<DingDingUserInfo> dingDingUserInfos5 = await GetDingDingUserInfo(divide, tempDept5.DeptId, tempDept5.ParentId, tempDept5.Name, access_token);
  145. //if (dingDingUserInfos5.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos5).ToList());
  146. if (dingDingUserInfos5.Count > 0) ddUserInfos.AddRange(dingDingUserInfos5);
  147. }
  148. }
  149. }
  150. }
  151. }
  152. }
  153. }
  154. }
  155. }
  156. }
  157. //保存操作记录
  158. await _azureStorage.SaveBILog("tabledd-update", $"{_tmdName}【{_tmdId}】从钉钉组织结构更新至Azure Table表【DDUserInfo】中。", _dingDing, httpContext: HttpContext);
  159. var tempddUserInfos = ddUserInfos.GroupBy(c => c.userId).Select(c => c.First()).ToList();//去重
  160. //List<DingDingUserInfo> TempdingDingUserInfos = await _azureStorage.SaveOrUpdateAll(dingDingUserInfos); //只是保存至Table
  161. //查询数据的数据 并和钉钉查询的数据对比,找出不同的数据,并删除 待后期测试
  162. var users = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{divide}" } });
  163. List<DingDingUserInfo> noExisits = new();
  164. if (users.Count > 0)
  165. {
  166. //var temps = users.Union(tempddUserInfos).Except(users.Intersect(tempddUserInfos));
  167. List<DingDingUserInfo> existsUserInfo = users.Where(u => !tempddUserInfos.Exists(e => u.userId.Equals(e.userId) && u.PartitionKey.Equals(e.PartitionKey))).ToList();
  168. existsUserInfo.AddRange(tempddUserInfos.Where(e => !users.Exists(u => e.userId.Equals(u.userId) && e.PartitionKey.Equals(u.PartitionKey))).ToList());
  169. ////List<DingDingUserInfo> existsUserInfo = users.Where((x, i) => users.FindIndex(z => z.userId.Equals(x.userId) && x.PartitionKey.Equals(divide)) == i).Select(x => x).ToList();
  170. if (existsUserInfo.Count > 0)
  171. {
  172. noExisits = await table.DeleteAll(existsUserInfo);
  173. }
  174. }
  175. List<DingDingUserInfo> UserInfo = await table.SaveOrUpdateAll(tempddUserInfos); //保存和修改至Table
  176. return Ok(new { state = 200, UserInfo, noExisits });
  177. }
  178. catch (Exception ex)
  179. {
  180. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/get-dingdingusers \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  181. return BadRequest();
  182. }
  183. }
  184. /// <summary>
  185. /// 查询钉钉信息和醍摩豆信息
  186. /// </summary>
  187. /// <returns></returns>
  188. [ProducesDefaultResponseType]
  189. [HttpPost("get-ddusers")]
  190. public async Task<IActionResult> GetDingDingUsers(JsonElement jsonElement)
  191. {
  192. try
  193. {
  194. jsonElement.TryGetProperty("busy", out JsonElement busy);
  195. jsonElement.TryGetProperty("site", out JsonElement site);
  196. var cosmosCliet = _azureCosmos.GetCosmosClient();
  197. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  198. if ($"{site}".Equals(BIConst.GlobalSite))
  199. {
  200. table = _azureStorage.GetCloudTableClient(BIConst.GlobalSite).GetTableReference("BIDDUserInfo");
  201. }
  202. //string divide = _configuration["CustomParam:SiteScope"];
  203. string divide = _option.Location;
  204. List<DDUserInfo> ddUserInfos = new();
  205. Dictionary<string, object> dic = new() { { "PartitionKey", $"{divide}" } };
  206. List<DingDingUserInfo> ddUserInfoList = await table.FindListByDict<DingDingUserInfo>(dic);
  207. switch ($"{busy}")
  208. {
  209. case "admin":
  210. foreach (var item in ddUserInfoList)
  211. {
  212. if (item.roles.Contains("admin"))
  213. {
  214. DDUserInfo ddUserInfo = new()
  215. {
  216. partitionKey = item.PartitionKey,
  217. rowKey = item.RowKey,
  218. userId = item.userId,
  219. unionId = item.unionId,
  220. name = item.name,
  221. title = item.title,
  222. stateCode = item.stateCode,
  223. mobile = item.mobile,
  224. jobNumber = item.jobNumber,
  225. pid = item.pid,
  226. deptId = item.deptId,
  227. deptName = item.deptName,
  228. depts = item.depts,
  229. avatar = item.avatar,
  230. isAdmin = item.isAdmin,
  231. tmdId = item.tmdId,
  232. tmdName = item.tmdName,
  233. tmdMobile = item.tmdMobile,
  234. mail = item.mail,
  235. picture = item.picture,
  236. roles = item.roles,
  237. joinTime = item.joinTime,
  238. permissions = item.permissions,
  239. handleRoles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(",")) : new List<string>(),
  240. handlePermissions = !string.IsNullOrEmpty($"{item.permissions}") ? new List<string>(item.permissions.Split(",")) : new List<string>(),
  241. };
  242. if (!string.IsNullOrEmpty(item.schoolIds))
  243. {
  244. List<string> tempSchoolIds = new(item.schoolIds.Split("|"));
  245. ddUserInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosCliet, tempSchoolIds);
  246. }
  247. ddUserInfos.Add(ddUserInfo);
  248. }
  249. }
  250. break;
  251. default:
  252. foreach (var item in ddUserInfoList)
  253. {
  254. DDUserInfo ddUserInfo = new()
  255. {
  256. partitionKey = item.PartitionKey,
  257. rowKey = item.RowKey,
  258. userId = item.userId,
  259. unionId = item.unionId,
  260. name = item.name,
  261. title = item.title,
  262. stateCode = item.stateCode,
  263. mobile = item.mobile,
  264. jobNumber = item.jobNumber,
  265. pid = item.pid,
  266. deptId = item.deptId,
  267. deptName = item.deptName,
  268. depts = item.depts,
  269. avatar = item.avatar,
  270. isAdmin = item.isAdmin,
  271. tmdId = item.tmdId,
  272. tmdName = item.tmdName,
  273. tmdMobile = item.tmdMobile,
  274. mail = item.mail,
  275. picture = item.picture,
  276. roles = item.roles,
  277. joinTime = item.joinTime,
  278. permissions = item.permissions,
  279. handleRoles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(",")) : new List<string>(),
  280. handlePermissions = !string.IsNullOrEmpty($"{item.permissions}") ? new List<string>(item.permissions.Split(",")) : new List<string>(),
  281. };
  282. if (!string.IsNullOrEmpty(item.schoolIds))
  283. {
  284. List<string> tempSchoolIds = new(item.schoolIds.Split("|"));
  285. ddUserInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosCliet, tempSchoolIds);
  286. }
  287. ddUserInfos.Add(ddUserInfo);
  288. }
  289. break;
  290. }
  291. return Ok(new { state = 200, ddUserInfos = ddUserInfos });
  292. }
  293. catch (Exception ex)
  294. {
  295. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/get-ddusers \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  296. return BadRequest();
  297. }
  298. }
  299. /// <summary>
  300. /// 查询钉钉待入职人员的ID添加至Table数据表中
  301. /// </summary>
  302. /// <returns></returns>
  303. [ProducesDefaultResponseType]
  304. [AuthToken(Roles = "admin,assist")]
  305. [HttpPost("set-ddinductionuser")]
  306. public async Task<IActionResult> SetDingDingInductionUser(JsonElement jsonElement)
  307. {
  308. try
  309. {
  310. jsonElement.TryGetProperty("site", out JsonElement site);
  311. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  312. if ($"{site}".Equals(BIConst.GlobalSite))
  313. {
  314. table = _azureStorage.GetCloudTableClient(BIConst.GlobalSite).GetTableReference("BIDDUserInfo");
  315. }
  316. string appKey = _configuration["DingDingAuth:appKey"];
  317. string appSecret = _configuration["DingDingAuth:appSecret"];
  318. //string divide = _configuration["CustomParam:SiteScope"];
  319. string divide = _option.Location;
  320. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  321. //获取access_token
  322. IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  323. OapiGettokenRequest request = new OapiGettokenRequest() { Appkey = appKey, Appsecret = appSecret };
  324. request.SetHttpMethod("Get");
  325. OapiGettokenResponse response = client.Execute(request);
  326. if (response.IsError)
  327. {
  328. return BadRequest();
  329. }
  330. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  331. string access_token = response.AccessToken;
  332. IDingTalkClient InductionClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/querypreentry");
  333. OapiSmartworkHrmEmployeeQuerypreentryRequest reqInduction = new OapiSmartworkHrmEmployeeQuerypreentryRequest() { Offset = 0L, Size = 50 };
  334. reqInduction.SetHttpMethod("GET");
  335. OapiSmartworkHrmEmployeeQuerypreentryResponse rspInduction = InductionClient.Execute(reqInduction, access_token);
  336. if (rspInduction.Result.DataList != null)
  337. {
  338. List<DingDingUserInfo> ddUserInfos = new List<DingDingUserInfo>();
  339. foreach (var itemId in rspInduction.Result.DataList)
  340. {
  341. DingDingUserInfo ddUserInfo = new DingDingUserInfo();
  342. ddUserInfo.PartitionKey = divide;
  343. ddUserInfo.RowKey = itemId;
  344. ddUserInfos.Add(ddUserInfo);
  345. }
  346. List<DingDingUserInfo> tempddUserInfos = await table.SaveAll(ddUserInfos);
  347. //保存操作记录
  348. await _azureStorage.SaveBILog("tabledd-add", $"{_tmdName}【{_tmdId}】添加待入职员工至table数据表中", _dingDing, httpContext: HttpContext);
  349. if (ddUserInfos.Count == tempddUserInfos.Count)
  350. {
  351. return Ok(new { state = 200, UserInfo = tempddUserInfos });
  352. }
  353. else
  354. {
  355. var diffArr = tempddUserInfos.Where(c => !ddUserInfos.Contains(c)).ToList();
  356. return Ok(new { state = 201, notUserInfo = diffArr });
  357. }
  358. }
  359. else
  360. {
  361. return Ok(new { state = 400, rspInduction.SubErrCode, rspInduction.SubErrMsg });
  362. }
  363. }
  364. catch (Exception ex)
  365. {
  366. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/set-ddinductionuser \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  367. return BadRequest();
  368. }
  369. }
  370. /// <summary>
  371. /// 获取钉钉离职人员ID并删除Table表中的数据
  372. /// </summary>
  373. /// <returns></returns>
  374. [ProducesDefaultResponseType]
  375. [AuthToken(Roles = "admin,assist")]
  376. [HttpPost("del-ddquituser")]
  377. public async Task<IActionResult> DeleteDDQuitUser(JsonElement jsonElement)
  378. {
  379. try
  380. {
  381. jsonElement.TryGetProperty("site", out JsonElement site);
  382. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  383. if ($"{site}".Equals(BIConst.GlobalSite))
  384. {
  385. table = _azureStorage.GetCloudTableClient(BIConst.GlobalSite).GetTableReference("BIDDUserInfo");
  386. }
  387. string appKey = _configuration["DingDingAuth:appKey"];
  388. string appSecret = _configuration["DingDingAuth:appSecret"];
  389. //string divide = _configuration["CustomParam:SiteScope"];
  390. string divide = _option.Location;
  391. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  392. //获取access_token
  393. IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  394. OapiGettokenRequest request = new() { Appkey = appKey, Appsecret = appSecret };
  395. request.SetHttpMethod("Get");
  396. OapiGettokenResponse response = client.Execute(request);
  397. if (response.IsError)
  398. {
  399. return BadRequest();
  400. }
  401. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  402. string access_token = response.AccessToken;
  403. IDingTalkClient quitStaffClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/querydimission");
  404. OapiSmartworkHrmEmployeeQuerydimissionRequest reqDimission = new OapiSmartworkHrmEmployeeQuerydimissionRequest() { Offset = 0L, Size = 50L };
  405. OapiSmartworkHrmEmployeeQuerydimissionResponse rspDimission = quitStaffClient.Execute(reqDimission, access_token);
  406. if (rspDimission.Result != null)
  407. {
  408. List<DingDingUserInfo> ddUserInfos = new();
  409. foreach (var itemId in rspDimission.Result.DataList)
  410. {
  411. await table.DeleteSingle<DingDingUserInfo>(divide, $"{itemId}");
  412. }
  413. //保存操作记录
  414. await _azureStorage.SaveBILog("tabledd-del", $"{_tmdName}【{_tmdId}】从table数据表中删除离职员工", _dingDing, httpContext: HttpContext);
  415. return Ok(new { state = 200 });
  416. }
  417. else
  418. {
  419. return Ok(new { state = rspDimission.SubErrCode });
  420. }
  421. }
  422. catch (Exception ex)
  423. {
  424. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/del-ddquituser \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  425. return BadRequest();
  426. }
  427. }
  428. /// <summary>
  429. /// 更新钉钉和醍摩豆的BI权限
  430. /// </summary>
  431. /// <param name="jsonElement"></param>
  432. /// <returns></returns>
  433. [ProducesDefaultResponseType]
  434. [AuthToken(Roles = "admin")]
  435. [HttpPost("set-rolesper")]
  436. public async Task<IActionResult> SetPermissions(JsonElement jsonElement)
  437. {
  438. try
  439. {
  440. if (!jsonElement.TryGetProperty("partitionKey", out JsonElement partitionKey)) return BadRequest();
  441. jsonElement.TryGetProperty("userId", out JsonElement userId);
  442. jsonElement.TryGetProperty("tmdId", out JsonElement tmdId);
  443. if (!jsonElement.TryGetProperty("permissions", out JsonElement _permissions)) return BadRequest();
  444. if (!jsonElement.TryGetProperty("roles", out JsonElement _roles)) return BadRequest();
  445. jsonElement.TryGetProperty("site", out JsonElement site);
  446. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  447. if ($"{site}".Equals(BIConst.GlobalSite))
  448. {
  449. table = _azureStorage.GetCloudTableClient(BIConst.GlobalSite).GetTableReference("BIDDUserInfo");
  450. }
  451. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  452. List<DingDingUserInfo> ddUserInfo = new();
  453. List<string> listper = _permissions.ToObject<List<string>>();
  454. List<string> listroles = _roles.ToObject<List<string>>();
  455. List<string> roles = new();//角色列表
  456. List<string> permissions = new();//权限列表
  457. StringBuilder stringBuilder = new($"{_tmdName}【{_tmdId}】醍摩豆账号");
  458. Dictionary<string, object> dic = new() { { "PartitionKey", $"{partitionKey}" } };
  459. if (!string.IsNullOrEmpty($"{userId}"))
  460. {
  461. dic.Add("userId", $"{userId}");
  462. }
  463. if (!string.IsNullOrEmpty($"{tmdId}"))
  464. {
  465. dic.Add("tmdId", $"{tmdId}");
  466. }
  467. if (string.IsNullOrEmpty($"{userId}") && string.IsNullOrEmpty($"{tmdId}"))
  468. {
  469. return BadRequest();
  470. }
  471. var tempUser = await table.FindListByDict<DingDingUserInfo>(dic);
  472. foreach (var item in tempUser)
  473. {
  474. stringBuilder.Append($"操作醍摩豆账户{item.tmdName}【{item.tmdId}】修改权限:{string.Join("|", listper.ToArray())}");
  475. item.roles = listroles.Count > 0 ? string.Join(",", listroles) : "assist";
  476. item.permissions = string.Join(",", listper);
  477. ddUserInfo.Add(item);
  478. roles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(",")) : new List<string>();
  479. permissions = !string.IsNullOrEmpty($"{item.permissions}") ? new List<string>(item.permissions.Split(",")) : new List<string>();
  480. }
  481. ddUserInfo = await table.UpdateAll<DingDingUserInfo>(ddUserInfo);
  482. //保存操作记录
  483. await _azureStorage.SaveBILog("tabledd-update", stringBuilder?.ToString(), _dingDing, httpContext: HttpContext);
  484. return Ok(new { state = 200, ddUserInfo, roles, permissions });
  485. }
  486. catch (Exception ex)
  487. {
  488. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/set-permissions \n {ex.Message}\n{ex.StackTrace} ", GroupNames.成都开发測試群組);
  489. return BadRequest();
  490. }
  491. }
  492. /// <summary>
  493. /// 依据部门ID获取部门列表
  494. /// </summary>
  495. /// <param name="jsonElement"></param>
  496. /// <returns></returns>
  497. [ProducesDefaultResponseType]
  498. [HttpPost("get-dddeptiduser")]
  499. public async Task<IActionResult> GetDDDeptIdUser(JsonElement jsonElement)
  500. {
  501. try
  502. {
  503. var cosmosCliet = _azureCosmos.GetCosmosClient();
  504. if (!jsonElement.TryGetProperty("deptId", out JsonElement deptId)) return BadRequest();
  505. jsonElement.TryGetProperty("site", out JsonElement site);
  506. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  507. if ($"{site}".Equals(BIConst.GlobalSite))
  508. {
  509. table = _azureStorage.GetCloudTableClient(BIConst.GlobalSite).GetTableReference("BIDDUserInfo");
  510. cosmosCliet = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  511. };
  512. //string divide = _configuration["CustomParam:SiteScope"];
  513. string divide = _option.Location;
  514. Dictionary<string, object> dic = new Dictionary<string, object> { { "PartitionKey", $"{divide}" } };
  515. List<DingDingUserInfo> tempUserInfos = await table.FindListByDict<DingDingUserInfo>(dic);
  516. List<DingDingUserInfo> userInfo = new();
  517. tempUserInfos.ForEach(x => {
  518. if (x.depts.Contains($"{deptId}"))
  519. {
  520. userInfo.Add(x);
  521. }
  522. if (x.pid.Equals(long.Parse($"{deptId}")))
  523. {
  524. userInfo.Add(x);
  525. }
  526. });
  527. //userInfo.Distinct().ToList(); //Equals实现去重
  528. userInfo.Where((x, i) => userInfo.FindIndex(z => z.RowKey.Equals(x.RowKey)) == i);//Lambda表达式去重
  529. //userInfo.GroupBy(p => p).Select(p => p.Key).ToList();//去重复
  530. //List<DingDingUserInfo> ddUserInfo = new();
  531. //List<DingDingUserInfo> tempUser = new();
  532. //tempUser = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "deptId", $"{deptId}" } });
  533. //if (tempUser.Count == 0)
  534. //{
  535. // tempUser = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "pid", $"{deptId}" } });
  536. //}
  537. //foreach (var itemUser in tempUser)
  538. //{
  539. // var tempUser1 = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "pid", $"{deptId}" } });
  540. // foreach (var itemUser1 in tempUser1)
  541. // {
  542. // if (!long.Parse($"{deptId}").Equals(itemUser1.pid))
  543. // {
  544. // var tempUser2 = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "pid", $"{itemUser1.pid}" } });
  545. // foreach (var itemUser2 in tempUser2)
  546. // {
  547. // if (!itemUser1.pid.Equals(itemUser2.pid))
  548. // {
  549. // var tempUser3 = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "pid", $"{itemUser2.pid}" } });
  550. // foreach (var itemUser3 in tempUser3)
  551. // {
  552. // if (!itemUser2.pid.Equals(itemUser3.pid))
  553. // {
  554. // var tempUser4 = await _azureStorage.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "pid", $"{itemUser3.pid}" } });
  555. // foreach (var itemUser4 in tempUser4)
  556. // {
  557. // if (!itemUser3.pid.Equals(itemUser4.pid)) { }
  558. // if (ddUserInfo.Find(x => x.RowKey.Equals(itemUser4.RowKey)) == null)
  559. // {
  560. // ddUserInfo.Add(itemUser4);
  561. // }
  562. // }
  563. // }
  564. // if (ddUserInfo.Find(x => x.RowKey.Equals(itemUser3.RowKey)) == null)
  565. // {
  566. // ddUserInfo.Add(itemUser3);
  567. // }
  568. // }
  569. // }
  570. // if (ddUserInfo.Find(x => x.RowKey.Equals(itemUser2.RowKey)) == null)
  571. // {
  572. // ddUserInfo.Add(itemUser2);
  573. // }
  574. // }
  575. // }
  576. // if (ddUserInfo.Find(x => x.RowKey.Equals(itemUser1.RowKey)) == null)
  577. // {
  578. // ddUserInfo.Add(itemUser1);
  579. // }
  580. // }
  581. // if (ddUserInfo.Find(x => x.RowKey.Equals(itemUser.RowKey)) == null)
  582. // {
  583. // ddUserInfo.Add(itemUser);
  584. // }
  585. //}
  586. List<DDUserInfo> ddUserInfos = new();
  587. foreach (var item in userInfo)
  588. {
  589. DDUserInfo tempUserInfo = new DDUserInfo()
  590. {
  591. partitionKey = item.PartitionKey,
  592. rowKey = item.RowKey,
  593. userId = item.userId,
  594. unionId = item.unionId,
  595. name = item.name,
  596. title = item.title,
  597. stateCode = item.stateCode,
  598. mobile = item.mobile,
  599. jobNumber = item.jobNumber,
  600. pid = item.pid,
  601. deptId = item.deptId,
  602. deptName = item.deptName,
  603. depts = item.depts,
  604. avatar = item.avatar,
  605. isAdmin = item.isAdmin,
  606. tmdId = item.tmdId,
  607. tmdName = item.tmdName,
  608. tmdMobile = item.tmdMobile,
  609. mail = item.mail,
  610. picture = item.picture,
  611. roles = item.roles,
  612. joinTime = item.joinTime,
  613. permissions = item.permissions,
  614. handleRoles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(",")) : new List<string>(),
  615. handlePermissions = !string.IsNullOrEmpty($"{item.permissions}") ? new List<string>(item.permissions.Split(",")) : new List<string>(),
  616. };
  617. if (!string.IsNullOrEmpty(item.schoolIds))
  618. {
  619. List<string> tempSchoolIds = new List<string>(item.schoolIds.Split("|"));
  620. tempUserInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosCliet, tempSchoolIds);
  621. }
  622. ddUserInfos.Add(tempUserInfo);
  623. }
  624. return Ok(new { state = 200, ddUserInfos });
  625. }
  626. catch (Exception ex)
  627. {
  628. await _dingDing.SendBotMsg($"BI, {_option.Location} /tabledd/get-dddeptiduser \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  629. return BadRequest();
  630. }
  631. }
  632. /// <summary>
  633. /// 后端钉钉账户和醍摩豆账户进行绑定
  634. /// </summary>
  635. /// <param name="jsonElement"></param>
  636. /// <returns></returns>
  637. [ProducesDefaultResponseType]
  638. [AuthToken(Roles = "admin,assist")]
  639. [HttpPost("set-backenbind")]
  640. public async Task<IActionResult> SetBackenBind(JsonElement jsonElement)
  641. {
  642. try
  643. {
  644. if (!jsonElement.TryGetProperty("rowKey", out JsonElement rowKey)) return BadRequest();
  645. if (!jsonElement.TryGetProperty("mobile", out JsonElement mobile)) return BadRequest();
  646. jsonElement.TryGetProperty("site", out JsonElement site);
  647. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  648. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  649. if ($"{site}".Equals(BIConst.GlobalSite))
  650. {
  651. table = _azureStorage.GetCloudTableClient(BIConst.GlobalSite).GetTableReference("BIDDUserInfo");
  652. }
  653. List<DingDingUserInfo> tempddUsers = null;
  654. List<DingDingUserInfo> ddUsers = new();
  655. StringBuilder tableSql = new();
  656. if (!string.IsNullOrEmpty($"{rowKey}"))
  657. tableSql.Append($"RowKey {QueryComparisons.Equal} '{rowKey}'");
  658. string tmdId = null;
  659. string tmdName = null;
  660. string tmdMobile = null;
  661. string mail = null;
  662. string picture = null;
  663. HttpClient httpClient = _http.CreateClient();
  664. string url = _configuration.GetValue<string>("HaBookAuth:CoreId:userinfo");
  665. List<string> mobiles = new List<string>() { $"{mobile}" };
  666. HttpResponseMessage responseMessage = await httpClient.PostAsJsonAsync(url, mobiles);
  667. if (responseMessage.StatusCode == HttpStatusCode.OK)
  668. {
  669. string temp = responseMessage.Content.ReadAsStringAsync().Result;
  670. List<JsonElement> json_id = temp.ToObject<List<JsonElement>>();
  671. if (json_id.Count > 0)
  672. {
  673. foreach (var item in json_id)
  674. {
  675. tmdId = item.GetProperty("id").ToString();
  676. tmdName = item.GetProperty("name").ToString();
  677. tmdMobile = item.GetProperty("mobile").ToString();
  678. mail = item.GetProperty("mail").ToString();
  679. picture = item.GetProperty("picture").ToString();
  680. }
  681. }
  682. else return Ok(new { state = 1, message = "该手机号未找到醍摩豆账户" });
  683. }
  684. tempddUsers = await table.QueryWhereString<DingDingUserInfo>(tableSql.ToString());
  685. if (tempddUsers.Count > 0)
  686. {
  687. foreach (var item in tempddUsers)
  688. {
  689. if (item.RowKey.Equals($"{rowKey}"))
  690. {
  691. item.tmdId = tmdId;
  692. item.tmdName = tmdName;
  693. item.tmdMobile = tmdMobile;
  694. item.mail = mail;
  695. item.picture = picture;
  696. ddUsers.Add(item);
  697. }
  698. }
  699. }
  700. else return Ok(new { state = 2, message = "钉钉ID错误请检查钉钉ID" });
  701. if (ddUsers.Count > 0) ddUsers = await table.SaveOrUpdateAll(ddUsers);
  702. //保存操作记录
  703. await _azureStorage.SaveBILog("tabledd-update", $"{_tmdName}【{_tmdId}】操作:绑定钉钉账户[{rowKey}]和醍摩豆账户[{tmdId}]", _dingDing, httpContext: HttpContext);
  704. return Ok(new { state = 200, ddUsers });
  705. }
  706. catch (Exception ex)
  707. {
  708. await _dingDing.SendBotMsg($"BI, {_option.Location} /tabledd/set-backenbind \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  709. return BadRequest();
  710. }
  711. }
  712. /// <summary>
  713. /// 设置系统管理员
  714. /// </summary>
  715. /// <param name="jsonElement"></param>
  716. /// <returns></returns>
  717. [ProducesDefaultResponseType]
  718. [AuthToken(Roles = "admin")]
  719. [HttpPost("set-backend")]
  720. public async Task<IActionResult> SetBackendAdmin(JsonElement jsonElement)
  721. {
  722. try
  723. {
  724. if (!jsonElement.TryGetProperty("partitionKey", out JsonElement partitionKey)) return BadRequest();
  725. if (!jsonElement.TryGetProperty("rowKey", out JsonElement rowKey)) return BadRequest();
  726. if (!jsonElement.TryGetProperty("isAdmin", out JsonElement isAdmin)) return BadRequest();
  727. jsonElement.TryGetProperty("site", out JsonElement site);
  728. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  729. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  730. if ($"{site}".Equals(BIConst.GlobalSite))
  731. {
  732. table = _azureStorage.GetCloudTableClient(BIConst.GlobalSite).GetTableReference("BIDDUserInfo");
  733. }
  734. var tempUser = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{partitionKey}" }, { "RowKey", $"{rowKey}" } });
  735. List<DDUserInfo> ddUserInfos = new();
  736. List<string> roles = new();//角色列表
  737. List<string> permissions = new();//权限列表
  738. StringBuilder msg = new($"{_tmdName}【{_tmdId}】");
  739. if (bool.Parse($"{isAdmin}") == true)
  740. {
  741. foreach (var user in tempUser)
  742. {
  743. if (string.IsNullOrEmpty(user.roles))
  744. {
  745. user.roles = "admin,assist";
  746. }
  747. List<string> tempRoles = new(user.roles.Split(","));
  748. if (!tempRoles.Contains("admin"))
  749. {
  750. tempRoles.Add("admin");
  751. }
  752. user.roles = string.Join(",", tempRoles);
  753. user.joinTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  754. DingDingUserInfo respUser = await table.SaveOrUpdate<DingDingUserInfo>(user);
  755. if (respUser != null)
  756. {
  757. roles = !string.IsNullOrEmpty($"{respUser.roles}") ? new List<string>(respUser.roles.Split(",")) : new List<string>();
  758. }
  759. msg.Append($"添加{respUser.name}【{respUser.RowKey}】账号的BI管理员");
  760. }
  761. }
  762. else
  763. {
  764. var userInfos = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{partitionKey}" } });
  765. var adminInfos = userInfos.FindAll(x => x.roles.Contains("admin"));
  766. if (adminInfos.Count == 1)
  767. {
  768. return Ok(new { state = 403, msg = "已经是最后一个管理员了" });
  769. }
  770. else
  771. {
  772. foreach (var user in tempUser)
  773. {
  774. if (!user.userId.Equals($"{did}"))
  775. {
  776. List<string> tempRoles = new(user.roles.Split(","));
  777. if (tempRoles.Contains("admin"))
  778. {
  779. tempRoles.Remove("admin");
  780. }
  781. user.roles = string.Join(",", tempRoles);
  782. DingDingUserInfo respUser = await table.SaveOrUpdate<DingDingUserInfo>(user);
  783. if (respUser != null)
  784. {
  785. roles = !string.IsNullOrEmpty($"{respUser.roles}") ? new List<string>(respUser.roles.Split(",")) : new List<string>();
  786. msg.Append($"取消{respUser.name}【{respUser.RowKey}】账号的BI管理员");
  787. }
  788. }
  789. else return Ok(new { state = 1, msg = "不能删除自己" });
  790. }
  791. }
  792. }
  793. //保存操作记录
  794. await _azureStorage.SaveBILog("tabledd-update", msg.ToString(), _dingDing, httpContext: HttpContext);
  795. return Ok(new { state = 200, roles });
  796. }
  797. catch (Exception ex)
  798. {
  799. await _dingDing.SendBotMsg($"BI, {_option.Location} /tabledd/set-backend \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  800. return BadRequest();
  801. }
  802. }
  803. /// <summary>
  804. /// 通过醍摩豆账户信息 设置BI后台管理员
  805. /// </summary>
  806. /// <param name="jsonElement"></param>
  807. /// <returns></returns>
  808. [ProducesDefaultResponseType]
  809. [AuthToken(Roles = "admin")]
  810. [HttpPost("set-tmdadmin")]
  811. public async Task<IActionResult> SetTmdBackendAdmin(JsonElement jsonElement)
  812. {
  813. try
  814. {
  815. if (!jsonElement.TryGetProperty("tmdId", out JsonElement tmdId)) return BadRequest();
  816. if (!jsonElement.TryGetProperty("tmdName", out JsonElement tmdName)) return BadRequest();
  817. if (!jsonElement.TryGetProperty("mobile", out JsonElement mobile)) return BadRequest();
  818. jsonElement.TryGetProperty("picture ", out JsonElement picture);
  819. jsonElement.TryGetProperty("mail ", out JsonElement mail);
  820. jsonElement.TryGetProperty("site", out JsonElement site);
  821. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  822. var cosmosCliet = _azureCosmos.GetCosmosClient();
  823. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  824. if ($"{site}".Equals(BIConst.GlobalSite))
  825. {
  826. cosmosCliet = _azureCosmos.GetCosmosClient(name: BIConst.GlobalSite);
  827. table = _azureStorage.GetCloudTableClient(BIConst.GlobalSite).GetTableReference("BIDDUserInfo");
  828. }
  829. List<DDUserInfo> ddUserInfos = new();
  830. List<string> roles = new();//角色列表
  831. List<string> permissions = new();//权限列表
  832. StringBuilder msg = new($"{_tmdName}【{_tmdId}】");
  833. //string divide = _configuration["CustomParam:SiteScope"];
  834. string divide = _option.Location;
  835. Dictionary<string, object> dic = new Dictionary<string, object> { { "PartitionKey", $"{divide}" }, { "mobile", $"{mobile}" } };
  836. List<DingDingUserInfo> ddUserInfoList = await table.FindListByDict<DingDingUserInfo>(dic);
  837. if (ddUserInfoList.Count > 0)
  838. {
  839. foreach (var user in ddUserInfoList)
  840. {
  841. List<string> tempRoles = new(user.roles.Split(","));
  842. if (tempRoles.Count > 0)
  843. {
  844. if (!tempRoles.Contains("admin"))
  845. {
  846. tempRoles.Add("admin");
  847. }
  848. }
  849. else
  850. tempRoles.Add("admin");
  851. user.roles = string.Join(",", tempRoles);
  852. user.joinTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  853. user.tmdId = $"{tmdId}";
  854. user.tmdName = $"{tmdName}";
  855. user.tmdMobile = $"{mobile}";
  856. if (!string.IsNullOrEmpty($"{picture}"))
  857. {
  858. user.picture = $"{picture}";
  859. }
  860. if (!string.IsNullOrEmpty($"{mail}"))
  861. {
  862. user.mail = $"{mail}";
  863. }
  864. msg.Append($" 将:{tmdName}【{tmdId}】醍摩豆账号和({user.name}【{user.unionId}】) 钉钉账户绑定,并设置管理员");
  865. DingDingUserInfo respUser = await table.SaveOrUpdate<DingDingUserInfo>(user);
  866. if (respUser != null)
  867. {
  868. roles = !string.IsNullOrEmpty($"{respUser.roles}") ? new List<string>(respUser.roles.Split(",")) : new List<string>();
  869. }
  870. DDUserInfo dDUserInfo = new()
  871. {
  872. partitionKey = respUser.PartitionKey,
  873. rowKey = respUser.RowKey,
  874. userId = respUser.userId,
  875. unionId = respUser.unionId,
  876. name = respUser.name,
  877. title = respUser.title,
  878. stateCode = respUser.stateCode,
  879. mobile = respUser.mobile,
  880. jobNumber = respUser.jobNumber,
  881. pid = respUser.pid,
  882. deptId = respUser.deptId,
  883. deptName = respUser.deptName,
  884. depts = respUser.depts,
  885. avatar = respUser.avatar,
  886. isAdmin = respUser.isAdmin,
  887. tmdId = respUser.tmdId,
  888. tmdName = respUser.tmdName,
  889. tmdMobile = respUser.tmdMobile,
  890. mail = respUser.mail,
  891. picture = respUser.picture,
  892. roles = respUser.roles,
  893. joinTime = respUser.joinTime,
  894. permissions = respUser.permissions,
  895. handleRoles = !string.IsNullOrEmpty($"{respUser.roles}") ? new List<string>(respUser.roles.Split(",")) : new List<string>(),
  896. handlePermissions = !string.IsNullOrEmpty($"{respUser.permissions}") ? new List<string>(respUser.permissions.Split(",")) : new List<string>()
  897. };
  898. if (!string.IsNullOrEmpty(respUser.schoolIds))
  899. {
  900. List<string> tempSchoolIds = new List<string>(respUser.schoolIds.Split("|"));
  901. dDUserInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosCliet, tempSchoolIds);
  902. }
  903. ddUserInfos.Add(dDUserInfo);
  904. }
  905. }
  906. else
  907. {
  908. DingDingUserInfo dingDingUserInfo = new()
  909. {
  910. PartitionKey = divide,
  911. RowKey = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(),
  912. roles = "admin",
  913. tmdId = $"{tmdId}",
  914. tmdName = $"{tmdName}",
  915. tmdMobile = $"{mobile}",
  916. };
  917. if (!string.IsNullOrEmpty($"{picture}"))
  918. {
  919. dingDingUserInfo.picture = $"{picture}";
  920. }
  921. if (!string.IsNullOrEmpty($"{mail}"))
  922. {
  923. dingDingUserInfo.mail = $"{mail}";
  924. }
  925. DingDingUserInfo respUser = await table.SaveOrUpdate<DingDingUserInfo>(dingDingUserInfo);
  926. return Ok(new { state = 201, msg = "新生成的BIadmin", respUser });
  927. }
  928. //保存操作记录
  929. await _azureStorage.SaveBILog("tabledd-update",msg.ToString(), _dingDing, httpContext: HttpContext);
  930. return Ok(new { state = 200, ddUserInfos });
  931. }
  932. catch (Exception ex)
  933. {
  934. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/set-tmdadmin \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  935. return BadRequest();
  936. }
  937. }
  938. /// <summary>
  939. /// 解除钉钉和醍摩豆的绑定
  940. /// </summary>
  941. /// <param name="jsonElement"></param>
  942. /// <returns></returns>
  943. [ProducesDefaultResponseType]
  944. [HttpPost("set-unbind")]
  945. public async Task<IActionResult> SetUnbind(JsonElement jsonElement)
  946. {
  947. jsonElement.TryGetProperty("mobile", out JsonElement mobile);
  948. jsonElement.TryGetProperty("site", out JsonElement site);
  949. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  950. if ($"{site}".Equals(BIConst.GlobalSite))
  951. {
  952. table = _azureStorage.GetCloudTableClient(BIConst.GlobalSite).GetTableReference("BIDDUserInfo");
  953. }
  954. //string divide = _configuration["CustomParam:SiteScope"];
  955. string divide = _option.Location;
  956. Dictionary<string, object> dic = new Dictionary<string, object> { { "PartitionKey", $"{divide}" } };
  957. if (!string.IsNullOrEmpty($"{mobile}"))
  958. dic.Add("tmdMobile", $"{mobile}");
  959. else
  960. dic.Add("tmdMobile", "18281911681");
  961. List<DingDingUserInfo> ddUserInfoList = await table.FindListByDict<DingDingUserInfo>(dic);
  962. List<DingDingUserInfo> tempDDUI = new();
  963. if (ddUserInfoList.Count > 0)
  964. {
  965. foreach (var item in ddUserInfoList)
  966. {
  967. item.tmdId = null;
  968. item.tmdName = null;
  969. item.tmdMobile = null;
  970. item.picture = null;
  971. tempDDUI.Add(item);
  972. }
  973. }
  974. else return Ok(new { state = 404, msg = "未找到手机号匹配的绑定号码!,请检查手机号" });
  975. var userInfos = await table.SaveOrUpdateAll(tempDDUI); //保存和修改至Table
  976. return Ok(new { state = 200, userInfos });
  977. }
  978. /// <summary>
  979. /// 获取钉钉用户信息
  980. /// 并查询本地Table数据表中是否存在
  981. /// </summary>
  982. /// <param name="deptId"></param>
  983. /// <param name="parentId"></param>
  984. /// <param name="name"></param>
  985. /// <param name="access_token"></param>
  986. /// <returns></returns>
  987. public async Task<List<DingDingUserInfo>> GetDingDingUserInfo(string partitionKey, long deptId, long parentId, string name, string access_token)
  988. {
  989. List<DingDingUserInfo> ddUserInfos = new();
  990. //获取部门人员信息
  991. IDingTalkClient userListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/list");
  992. //获取部门用户
  993. OapiV2UserListRequest reqUserList = new()
  994. {
  995. DeptId = deptId,
  996. Cursor = 0L,
  997. Size = 50L,
  998. OrderField = "custom",
  999. Language = "zh_CN"
  1000. };
  1001. reqUserList.SetHttpMethod("GET");
  1002. OapiV2UserListResponse rspV2UserList = userListClient.Execute(reqUserList, access_token);
  1003. if (rspV2UserList.Result.List != null)
  1004. {
  1005. foreach (var itemUser in rspV2UserList.Result.List)
  1006. {
  1007. var tempInfo = ddUserInfos.Find(x => x.RowKey.Equals(itemUser.Unionid));
  1008. if (string.IsNullOrEmpty($"{tempInfo}"))
  1009. {
  1010. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  1011. var users = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "userId", $"{itemUser.Userid}" }, { "unionId", $"{itemUser.Unionid}" } });
  1012. if (users.Count > 0)
  1013. {
  1014. foreach (var user in users)
  1015. {
  1016. DingDingUserInfo ddUserInfo = new()
  1017. {
  1018. PartitionKey = user.PartitionKey,
  1019. RowKey = user.RowKey,
  1020. userId = itemUser.Userid,
  1021. unionId = itemUser.Unionid,
  1022. name = itemUser.Name,
  1023. email = itemUser.Email,
  1024. title = itemUser.Title,
  1025. stateCode = itemUser.StateCode,
  1026. mobile = itemUser.Mobile,
  1027. jobNumber = itemUser.JobNumber,
  1028. pid = parentId,
  1029. deptId = deptId,
  1030. deptName = name,
  1031. depts = string.Join(",", itemUser.DeptIdList.ToArray()),
  1032. avatar = itemUser.Avatar,
  1033. isAdmin = itemUser.Admin,
  1034. tmdId = user.tmdId,
  1035. tmdName = user.tmdName,
  1036. tmdMobile = user.tmdMobile,
  1037. mail = user.mail,
  1038. picture = user.picture,
  1039. roles = user.roles,
  1040. joinTime = user.joinTime,
  1041. permissions = user.permissions,
  1042. schoolIds = user.schoolIds
  1043. };
  1044. ddUserInfos.Add(ddUserInfo);
  1045. }
  1046. }
  1047. else
  1048. {
  1049. DingDingUserInfo ddUserInfo = new()
  1050. {
  1051. RowKey = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(),
  1052. userId = itemUser.Userid,
  1053. unionId = itemUser.Unionid,
  1054. name = itemUser.Name,
  1055. email = itemUser.Email,
  1056. title = itemUser.Title,
  1057. stateCode = itemUser.StateCode,
  1058. mobile = itemUser.Mobile,
  1059. jobNumber = itemUser.JobNumber,
  1060. pid = parentId,
  1061. deptId = deptId,
  1062. deptName = name,
  1063. depts = string.Join(",", itemUser.DeptIdList.ToArray()),
  1064. avatar = itemUser.Avatar,
  1065. isAdmin = itemUser.Admin,
  1066. PartitionKey = partitionKey,
  1067. tmdId = "",
  1068. tmdName = "",
  1069. tmdMobile = "",
  1070. mail = "",
  1071. picture = "",
  1072. roles = "",
  1073. joinTime = 0,
  1074. permissions = "areadata-read,areadata-upd,schooldata-read,schooldata-upd",
  1075. schoolIds = ""
  1076. };
  1077. ddUserInfos.Add(ddUserInfo);
  1078. }
  1079. }
  1080. }
  1081. }
  1082. return ddUserInfos;
  1083. }
  1084. public record DDUserInfo
  1085. {
  1086. public string partitionKey { get; set; }
  1087. public string rowKey { get; set; }
  1088. public string userId { get; set; }
  1089. public string unionId { get; set; }
  1090. public string name { get; set; }
  1091. public string title { get; set; }
  1092. public string stateCode { get; set; }
  1093. public string mobile { get; set; }
  1094. public string jobNumber { get; set; }
  1095. public long pid { get; set; }
  1096. public long deptId { get; set; }
  1097. public string deptName { get; set; }
  1098. public string depts { get; set; }
  1099. public string avatar { get; set; }
  1100. public bool isAdmin { get; set; }
  1101. public string tmdId { get; set; }
  1102. public string tmdName { get; set; }
  1103. public string tmdMobile { get; set; }
  1104. public string mail { get; set; }
  1105. public string picture { get; set; }
  1106. public string roles { get; set; }
  1107. public long joinTime { get; set; }
  1108. public string permissions { get; set; }
  1109. public List<string> handleRoles { get; set; }
  1110. public List<string> handlePermissions { get; set; }
  1111. public List<AdvSchool> handleSchools { get; set; } = new List<AdvSchool>();
  1112. }
  1113. }
  1114. }