TableDingDingInfoController.cs 74 KB

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