TableDingDingInfoController.cs 74 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408
  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() { 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() { 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() { 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() { 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() { 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() { 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() { { "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(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() { { "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(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() { 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() { 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() { 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() { 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() { 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() { 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. [ProducesDefaultResponseType]
  907. [HttpPost("set-apiphoneadmin")]
  908. public async Task<IActionResult> SetPhoneAdmin(JsonElement jsonElement)
  909. {
  910. jsonElement.TryGetProperty("partitionKey", out JsonElement partitionKey);
  911. if (!jsonElement.TryGetProperty("mobile", out JsonElement mobile)) return BadRequest();
  912. jsonElement.TryGetProperty("site", out JsonElement site);
  913. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  914. var partKey = _option.Location;
  915. if (string.IsNullOrEmpty($"{partitionKey}"))
  916. {
  917. partKey = $"{partitionKey}";
  918. };
  919. var tableClient = _azureStorage.GetCloudTableClient();
  920. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  921. if ($"{site}".Equals(BIConst.Global))
  922. {
  923. tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  924. blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  925. }
  926. var table = tableClient.GetTableReference("BIDDUserInfo");
  927. var tempUser = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{partKey}" }, { "mobile", $"{mobile}" } });
  928. List<string> roles = new();//角色列表
  929. List<string> permissions = new();//权限列表
  930. StringBuilder msg = new();
  931. foreach (var user in tempUser)
  932. {
  933. if (string.IsNullOrEmpty(user.roles))
  934. {
  935. user.roles = "admin,assist";
  936. }
  937. List<string> tempRoles = new(user.roles.Split(","));
  938. if (!tempRoles.Contains("admin"))
  939. {
  940. tempRoles.Add("admin");
  941. }
  942. user.roles = string.Join(",", tempRoles);
  943. user.joinTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  944. DingDingUserInfo respUser = await table.SaveOrUpdate<DingDingUserInfo>(user);
  945. if (respUser != null)
  946. {
  947. roles = !string.IsNullOrEmpty($"{respUser.roles}") ? new List<string>(respUser.roles.Split(",")) : new List<string>();
  948. }
  949. msg.Append($"初始将{respUser.name}【{respUser.RowKey}】账号的BI管理员");
  950. }
  951. //保存操作记录
  952. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", msg.ToString(), _dingDing, httpContext: HttpContext);
  953. return Ok(new { state = 200, roles });
  954. }
  955. /// <summary>
  956. /// 解除钉钉和醍摩豆的绑定
  957. /// </summary>
  958. /// <param name="jsonElement"></param>
  959. /// <returns></returns>
  960. [ProducesDefaultResponseType]
  961. [HttpPost("set-unbind")]
  962. public async Task<IActionResult> SetUnbind(JsonElement jsonElement)
  963. {
  964. jsonElement.TryGetProperty("mobile", out JsonElement mobile);
  965. jsonElement.TryGetProperty("site", out JsonElement site);
  966. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  967. if ($"{site}".Equals(BIConst.Global))
  968. {
  969. table = _azureStorage.GetCloudTableClient(BIConst.Global).GetTableReference("BIDDUserInfo");
  970. }
  971. //string divide = _configuration["CustomParam:SiteScope"];
  972. string divide = _option.Location;
  973. Dictionary<string, object> dic = new Dictionary<string, object> { { "PartitionKey", $"{divide}" } };
  974. if (!string.IsNullOrEmpty($"{mobile}"))
  975. dic.Add("tmdMobile", $"{mobile}");
  976. else
  977. dic.Add("tmdMobile", "18281911681");
  978. List<DingDingUserInfo> ddUserInfoList = await table.FindListByDict<DingDingUserInfo>(dic);
  979. List<DingDingUserInfo> tempDDUI = new();
  980. if (ddUserInfoList.Count > 0)
  981. {
  982. foreach (var item in ddUserInfoList)
  983. {
  984. item.tmdId = null;
  985. item.tmdName = null;
  986. item.tmdMobile = null;
  987. item.picture = null;
  988. tempDDUI.Add(item);
  989. }
  990. }
  991. else return Ok(new { state = 404, msg = "未找到手机号匹配的绑定号码!,请检查手机号" });
  992. var userInfos = await table.SaveOrUpdateAll(tempDDUI); //保存和修改至Table
  993. return Ok(new { state = 200, userInfos });
  994. }
  995. /// <summary>
  996. /// 查询钉钉待入职人员的ID添加至Table数据表中
  997. /// </summary>
  998. /// <returns></returns>
  999. [ProducesDefaultResponseType]
  1000. [AuthToken(Roles = "admin,rdc")]
  1001. [HttpPost("set-ddinductionuser")]
  1002. public async Task<IActionResult> SetDingDingInductionUser(JsonElement jsonElement)
  1003. {
  1004. try
  1005. {
  1006. jsonElement.TryGetProperty("site", out JsonElement site);
  1007. var tableClient = _azureStorage.GetCloudTableClient();
  1008. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  1009. if ($"{site}".Equals(BIConst.Global))
  1010. {
  1011. tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  1012. blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  1013. }
  1014. var table = tableClient.GetTableReference("BIDDUserInfo");
  1015. string appKey = _configuration["DingDingAuth:appKey"];
  1016. string appSecret = _configuration["DingDingAuth:appSecret"];
  1017. //string divide = _configuration["CustomParam:SiteScope"];
  1018. string divide = _option.Location;
  1019. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  1020. //获取access_token
  1021. IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  1022. OapiGettokenRequest request = new() { Appkey = appKey, Appsecret = appSecret };
  1023. request.SetHttpMethod("Get");
  1024. OapiGettokenResponse response = client.Execute(request);
  1025. if (response.IsError)
  1026. {
  1027. return BadRequest();
  1028. }
  1029. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  1030. string access_token = response.AccessToken;
  1031. IDingTalkClient InductionClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/querypreentry");
  1032. OapiSmartworkHrmEmployeeQuerypreentryRequest reqInduction = new() { Offset = 0L, Size = 50 };
  1033. reqInduction.SetHttpMethod("GET");
  1034. OapiSmartworkHrmEmployeeQuerypreentryResponse rspInduction = InductionClient.Execute(reqInduction, access_token);
  1035. if (rspInduction.Result.DataList != null)
  1036. {
  1037. List<DingDingUserInfo> ddUserInfos = new();
  1038. foreach (var itemId in rspInduction.Result.DataList)
  1039. {
  1040. DingDingUserInfo ddUserInfo = new();
  1041. ddUserInfo.PartitionKey = divide;
  1042. ddUserInfo.RowKey = itemId;
  1043. ddUserInfos.Add(ddUserInfo);
  1044. }
  1045. List<DingDingUserInfo> tempddUserInfos = await table.SaveAll(ddUserInfos);
  1046. //保存操作记录
  1047. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-add", $"{_tmdName}【{_tmdId}】添加待入职员工至table数据表中", _dingDing, httpContext: HttpContext);
  1048. if (ddUserInfos.Count == tempddUserInfos.Count)
  1049. return Ok(new { state = 200, UserInfo = tempddUserInfos });
  1050. else
  1051. {
  1052. var diffArr = tempddUserInfos.Where(c => !ddUserInfos.Contains(c)).ToList();
  1053. return Ok(new { state = 201, notUserInfo = diffArr });
  1054. }
  1055. }
  1056. else
  1057. return Ok(new { state = 400, rspInduction.SubErrCode, rspInduction.SubErrMsg });
  1058. }
  1059. catch (Exception ex)
  1060. {
  1061. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/set-ddinductionuser \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  1062. return BadRequest();
  1063. }
  1064. }
  1065. /// <summary>
  1066. /// 获取钉钉离职人员ID并删除Table表中的数据
  1067. /// </summary>
  1068. /// <returns></returns>
  1069. [ProducesDefaultResponseType]
  1070. [AuthToken(Roles = "admin,rdc")]
  1071. [HttpPost("del-ddquituser")]
  1072. public async Task<IActionResult> DeleteDDQuitUser(JsonElement jsonElement)
  1073. {
  1074. try
  1075. {
  1076. jsonElement.TryGetProperty("site", out JsonElement site);
  1077. var tableClient = _azureStorage.GetCloudTableClient();
  1078. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  1079. if ($"{site}".Equals(BIConst.Global))
  1080. {
  1081. tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  1082. blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  1083. }
  1084. var table = tableClient.GetTableReference("BIDDUserInfo");
  1085. string appKey = _configuration["DingDingAuth:appKey"];
  1086. string appSecret = _configuration["DingDingAuth:appSecret"];
  1087. //string divide = _configuration["CustomParam:SiteScope"];
  1088. string divide = _option.Location;
  1089. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  1090. //获取access_token
  1091. IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  1092. OapiGettokenRequest request = new() { Appkey = appKey, Appsecret = appSecret };
  1093. request.SetHttpMethod("Get");
  1094. OapiGettokenResponse response = client.Execute(request);
  1095. if (response.IsError)
  1096. {
  1097. return BadRequest();
  1098. }
  1099. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  1100. string access_token = response.AccessToken;
  1101. IDingTalkClient quitStaffClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/querydimission");
  1102. OapiSmartworkHrmEmployeeQuerydimissionRequest reqDimission = new() { Offset = 0L, Size = 50L };
  1103. OapiSmartworkHrmEmployeeQuerydimissionResponse rspDimission = quitStaffClient.Execute(reqDimission, access_token);
  1104. if (rspDimission.Result != null)
  1105. {
  1106. List<DingDingUserInfo> ddUserInfos = new();
  1107. foreach (var itemId in rspDimission.Result.DataList)
  1108. {
  1109. await table.DeleteSingle<DingDingUserInfo>(divide, $"{itemId}");
  1110. }
  1111. //保存操作记录
  1112. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-del", $"{_tmdName}【{_tmdId}】从table数据表中删除离职员工", _dingDing, httpContext: HttpContext);
  1113. return Ok(new { state = 200 });
  1114. }
  1115. else
  1116. {
  1117. return Ok(new { state = rspDimission.SubErrCode });
  1118. }
  1119. }
  1120. catch (Exception ex)
  1121. {
  1122. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/del-ddquituser \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  1123. return BadRequest();
  1124. }
  1125. }
  1126. /// <summary>
  1127. /// 获取钉钉用户信息
  1128. /// 并查询本地Table数据表中是否存在
  1129. /// </summary>
  1130. /// <param name="deptId"></param>
  1131. /// <param name="parentId"></param>
  1132. /// <param name="name"></param>
  1133. /// <param name="access_token"></param>
  1134. /// <returns></returns>
  1135. public async Task<List<DingDingUserInfo>> GetDingDingUserInfo(string partitionKey, long deptId, long parentId, string name, string access_token)
  1136. {
  1137. List<DingDingUserInfo> ddUserInfos = new();
  1138. //获取部门人员信息
  1139. IDingTalkClient userListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/list");
  1140. //获取部门用户
  1141. OapiV2UserListRequest reqUserList = new()
  1142. {
  1143. DeptId = deptId,
  1144. Cursor = 0L,
  1145. Size = 50L,
  1146. OrderField = "custom",
  1147. Language = "zh_CN"
  1148. };
  1149. reqUserList.SetHttpMethod("GET");
  1150. OapiV2UserListResponse rspV2UserList = userListClient.Execute(reqUserList, access_token);
  1151. if (rspV2UserList.Result.List != null)
  1152. {
  1153. foreach (var itemUser in rspV2UserList.Result.List)
  1154. {
  1155. var tempInfo = ddUserInfos.Find(x => x.RowKey.Equals(itemUser.Unionid));
  1156. if (string.IsNullOrEmpty($"{tempInfo}"))
  1157. {
  1158. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  1159. var users = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{partitionKey}" }, { "userId", $"{itemUser.Userid}" }, { "unionId", $"{itemUser.Unionid}" } });
  1160. if (users.Count > 0)
  1161. {
  1162. foreach (var user in users)
  1163. {
  1164. DingDingUserInfo ddUserInfo = new()
  1165. {
  1166. PartitionKey = user.PartitionKey,
  1167. RowKey = user.RowKey,
  1168. userId = itemUser.Userid,
  1169. unionId = itemUser.Unionid,
  1170. name = itemUser.Name,
  1171. email = itemUser.Email,
  1172. title = itemUser.Title,
  1173. stateCode = itemUser.StateCode,
  1174. mobile = itemUser.Mobile,
  1175. jobNumber = itemUser.JobNumber,
  1176. pid = parentId,
  1177. deptId = deptId,
  1178. deptName = name,
  1179. depts = string.Join(",", itemUser.DeptIdList.ToArray()),
  1180. avatar = itemUser.Avatar,
  1181. isAdmin = itemUser.Admin,
  1182. tmdId = user.tmdId,
  1183. tmdName = user.tmdName,
  1184. tmdMobile = user.tmdMobile,
  1185. mail = user.mail,
  1186. picture = user.picture,
  1187. roles = user.roles,
  1188. joinTime = user.joinTime,
  1189. permissions = user.permissions,
  1190. schoolIds = user.schoolIds
  1191. };
  1192. ddUserInfos.Add(ddUserInfo);
  1193. }
  1194. }
  1195. else
  1196. {
  1197. DingDingUserInfo ddUserInfo = new()
  1198. {
  1199. RowKey = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(),
  1200. userId = itemUser.Userid,
  1201. unionId = itemUser.Unionid,
  1202. name = itemUser.Name,
  1203. email = itemUser.Email,
  1204. title = itemUser.Title,
  1205. stateCode = itemUser.StateCode,
  1206. mobile = itemUser.Mobile,
  1207. jobNumber = itemUser.JobNumber,
  1208. pid = parentId,
  1209. deptId = deptId,
  1210. deptName = name,
  1211. depts = string.Join(",", itemUser.DeptIdList.ToArray()),
  1212. avatar = itemUser.Avatar,
  1213. isAdmin = itemUser.Admin,
  1214. PartitionKey = partitionKey,
  1215. tmdId = "",
  1216. tmdName = "",
  1217. tmdMobile = "",
  1218. mail = "",
  1219. picture = "",
  1220. roles = "",
  1221. joinTime = 0,
  1222. permissions = "areadata-read,areadata-upd,schooldata-read,schooldata-upd",
  1223. schoolIds = ""
  1224. };
  1225. ddUserInfos.Add(ddUserInfo);
  1226. }
  1227. }
  1228. }
  1229. }
  1230. return ddUserInfos;
  1231. }
  1232. public record DDUserInfo
  1233. {
  1234. public string partitionKey { get; set; }
  1235. public string rowKey { get; set; }
  1236. public string userId { get; set; }
  1237. public string unionId { get; set; }
  1238. public string name { get; set; }
  1239. public string title { get; set; }
  1240. public string stateCode { get; set; }
  1241. public string mobile { get; set; }
  1242. public string jobNumber { get; set; }
  1243. public long pid { get; set; }
  1244. public long deptId { get; set; }
  1245. public string deptName { get; set; }
  1246. public string depts { get; set; }
  1247. public string avatar { get; set; }
  1248. public bool isAdmin { get; set; }
  1249. public string tmdId { get; set; }
  1250. public string tmdName { get; set; }
  1251. public string tmdMobile { get; set; }
  1252. public string mail { get; set; }
  1253. public string picture { get; set; }
  1254. public string roles { get; set; }
  1255. public long joinTime { get; set; }
  1256. public string permissions { get; set; }
  1257. public List<string> handleRoles { get; set; }
  1258. public List<string> handlePermissions { get; set; }
  1259. public List<BaseInfo> handleSchools { get; set; } = new List<BaseInfo>();
  1260. }
  1261. }
  1262. }