TableDingDingInfoController.cs 97 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788
  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 System.Text;
  21. using Microsoft.Azure.Cosmos;
  22. using TEAMModelBI.Filter;
  23. using TEAMModelBI.Tool.Extension;
  24. using TEAMModelBI.Models;
  25. using TEAMModelBI.Tool.CosmosBank;
  26. using TEAMModelOS.SDK;
  27. using TEAMModelOS.SDK.Context.BI;
  28. using TEAMModelOS.SDK.Models;
  29. using TEAMModelOS.SDK.Context.Constant;
  30. using TEAMModelOS.SDK.Models.Dtos;
  31. using TEAMModelOS.SDK.Models.Cosmos.BI.BISchool;
  32. using Microsoft.Azure.Cosmos.Table;
  33. namespace TEAMModelBI.Controllers.BITable
  34. {
  35. [Route("tabledd")]
  36. [ApiController]
  37. public class TableDingDingInfoController : ControllerBase
  38. {
  39. //读取配置文件
  40. private readonly IConfiguration _configuration;
  41. //数据容器
  42. private readonly AzureCosmosFactory _azureCosmos;
  43. //blob和table容器
  44. private readonly AzureStorageFactory _azureStorage;
  45. //钉钉提示信息
  46. private readonly DingDing _dingDing;
  47. private readonly Option _option;
  48. private readonly IHttpClientFactory _http;
  49. private readonly CoreAPIHttpService _coreAPIHttpService;
  50. public TableDingDingInfoController(AzureCosmosFactory azureCosmos, DingDing dingDing, AzureStorageFactory azureStorage, IOptionsSnapshot<Option> option, IConfiguration configuration, IHttpClientFactory http, CoreAPIHttpService coreAPIHttpService)
  51. {
  52. _azureCosmos = azureCosmos;
  53. _dingDing = dingDing;
  54. _azureStorage = azureStorage;
  55. _option = option?.Value;
  56. _http = http;
  57. _configuration = configuration;
  58. _coreAPIHttpService = coreAPIHttpService;
  59. }
  60. /// <summary>
  61. /// 从钉钉的组织架构中人员信息数据,并保存或者更新至Blob中 已对接
  62. /// </summary>
  63. /// <returns></returns>
  64. [ProducesDefaultResponseType]
  65. [AuthToken(Roles = "admin,rdc")]
  66. [HttpPost("get-dingdingusers")]
  67. public async Task<IActionResult> GetDingDingUser(JsonElement jsonElement)
  68. {
  69. try
  70. {
  71. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  72. var tableClient = _azureStorage.GetCloudTableClient();
  73. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  74. ////分开部署,就不需要,一站多用时,取消注释
  75. //if ($"{site}".Equals(BIConst.Global))
  76. //{
  77. // tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  78. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  79. //}
  80. var table = tableClient.GetTableReference("BIDDUserInfo");
  81. string appKey = _configuration["DingDingAuth:appKey"];
  82. string appSecret = _configuration["DingDingAuth:appSecret"];
  83. //string divide = _configuration["CustomParam:SiteScope"];
  84. string divide = _option.Location;
  85. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  86. //获取access_token
  87. IDingTalkClient tokenClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  88. OapiGettokenRequest tokenRequest = new() { Appkey = appKey, Appsecret = appSecret };
  89. tokenRequest.SetHttpMethod("Get");
  90. OapiGettokenResponse tokenRespone = tokenClient.Execute(tokenRequest);
  91. if (tokenRespone.IsError)
  92. {
  93. return BadRequest();
  94. }
  95. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  96. string access_token = tokenRespone.AccessToken;
  97. //获取部门接口
  98. IDingTalkClient deptListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
  99. //一级部门
  100. OapiV2DepartmentListsubRequest reqDeptList1 = new() { DeptId = 1L, Language = "zh_CN" };
  101. OapiV2DepartmentListsubResponse rspDeptList1 = deptListClient.Execute(reqDeptList1, access_token);
  102. List<DingDingUserInfo> ddUserInfos = new();
  103. if (rspDeptList1.Result != null)
  104. {
  105. foreach (var tempDept1 in rspDeptList1.Result)
  106. {
  107. //获取一级部门用户信息
  108. List<DingDingUserInfo> dingDingUserInfos1 = await GetDingDingUserInfo(divide, tempDept1.DeptId, tempDept1.ParentId, tempDept1.Name, access_token);
  109. //if (dingDingUserInfos1.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos1.ToList()));
  110. if (dingDingUserInfos1.Count > 0) ddUserInfos.AddRange(dingDingUserInfos1);
  111. //获取二级部门
  112. OapiV2DepartmentListsubRequest reqDeptList2 = new() { DeptId = tempDept1.DeptId, Language = "zh_CN" };
  113. OapiV2DepartmentListsubResponse rspDeptList2 = deptListClient.Execute(reqDeptList2, access_token);
  114. if (rspDeptList2.Result != null)
  115. {
  116. foreach (var tempDept2 in rspDeptList2.Result)
  117. {
  118. //获取二级部门用户信息
  119. List<DingDingUserInfo> dingDingUserInfos2 = await GetDingDingUserInfo(divide, tempDept2.DeptId, tempDept2.ParentId, tempDept2.Name, access_token);
  120. //if (dingDingUserInfos2.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos2.ToList()));
  121. if (dingDingUserInfos2.Count > 0) ddUserInfos.AddRange(dingDingUserInfos2);
  122. //获取三级部门
  123. OapiV2DepartmentListsubRequest reqDeptList3 = new() { DeptId = tempDept2.DeptId, Language = "zh_CN" };
  124. OapiV2DepartmentListsubResponse rspDeptList3 = deptListClient.Execute(reqDeptList3, access_token);
  125. if (rspDeptList3.Result != null)
  126. {
  127. foreach (var tempDept3 in rspDeptList3.Result)
  128. {
  129. //获取三级部门用户信息
  130. List<DingDingUserInfo> dingDingUserInfos3 = await GetDingDingUserInfo(divide, tempDept3.DeptId, tempDept3.ParentId, tempDept3.Name, access_token);
  131. //if (dingDingUserInfos3.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos3.ToList()));
  132. if (dingDingUserInfos3.Count > 0) ddUserInfos.AddRange(dingDingUserInfos3);
  133. //获取四级部门
  134. OapiV2DepartmentListsubRequest reqDeptList4 = new() { DeptId = tempDept3.DeptId, Language = "zh_CN" };
  135. OapiV2DepartmentListsubResponse rspDeptList4 = deptListClient.Execute(reqDeptList4, access_token);
  136. if (rspDeptList4.Result != null)
  137. {
  138. foreach (var tempDept4 in rspDeptList4.Result)
  139. {
  140. //获取四级部门用户信息
  141. List<DingDingUserInfo> dingDingUserInfos4 = await GetDingDingUserInfo(divide, tempDept4.DeptId, tempDept4.ParentId, tempDept4.Name, access_token);
  142. //if (dingDingUserInfos4.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos4.ToList()));
  143. if (dingDingUserInfos4.Count > 0) ddUserInfos.AddRange(dingDingUserInfos4);
  144. //获取五级部门
  145. OapiV2DepartmentListsubRequest reqDeptList5 = new() { DeptId = tempDept4.DeptId, Language = "zh_CN" };
  146. OapiV2DepartmentListsubResponse rspDeptList5 = deptListClient.Execute(reqDeptList5, access_token);
  147. if (rspDeptList5.Result != null)
  148. {
  149. foreach (var tempDept5 in rspDeptList5.Result)
  150. {
  151. //获取五级部门用户信息
  152. List<DingDingUserInfo> dingDingUserInfos5 = await GetDingDingUserInfo(divide, tempDept5.DeptId, tempDept5.ParentId, tempDept5.Name, access_token);
  153. //if (dingDingUserInfos5.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos5).ToList());
  154. if (dingDingUserInfos5.Count > 0) ddUserInfos.AddRange(dingDingUserInfos5);
  155. }
  156. }
  157. }
  158. }
  159. }
  160. }
  161. }
  162. }
  163. }
  164. }
  165. var tempddUserInfos = ddUserInfos.GroupBy(c => c.userId).Select(c => c.First()).ToList();//去重
  166. //List<DingDingUserInfo> TempdingDingUserInfos = await _azureStorage.SaveOrUpdateAll(dingDingUserInfos); //只是保存至Table
  167. //查询数据的数据 并和钉钉查询的数据对比,找出不同的数据,并删除 待后期测试
  168. var users = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{divide}" } });
  169. List<DingDingUserInfo> noExisits = new();
  170. if (users.Count() > 0)
  171. {
  172. //var temps = users.Union(tempddUserInfos).Except(users.Intersect(tempddUserInfos));
  173. List<DingDingUserInfo> existsUserInfo = users.Where(u => !tempddUserInfos.Exists(e => u.userId.Equals(e.userId) && u.PartitionKey.Equals(e.PartitionKey))).ToList();
  174. //if (users.Count > tempddUserInfos.Count)
  175. //{
  176. // existsUserInfo.AddRange(tempddUserInfos.Where(e => !users.Exists(u => e.userId.Equals(u.userId) && e.PartitionKey.Equals(u.PartitionKey))).ToList());
  177. //}
  178. ////List<DingDingUserInfo> existsUserInfo = users.Where((x, i) => users.FindIndex(z => z.userId.Equals(x.userId) && x.PartitionKey.Equals(divide)) == i).Select(x => x).ToList();
  179. if (existsUserInfo.Count > 0)
  180. {
  181. noExisits = await table.DeleteAll(existsUserInfo);
  182. }
  183. }
  184. //保存和修改至Table
  185. List<DingDingUserInfo> UserInfo = await table.SaveOrUpdateAll(tempddUserInfos);
  186. //保存操作记录
  187. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{_tmdName}【{_tmdId}】从钉钉组织结构更新至Azure Table表【DDUserInfo】中。", _dingDing, httpContext: HttpContext);
  188. return Ok(new { state = 200, UserInfo, noExisits });
  189. }
  190. catch (Exception ex)
  191. {
  192. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/get-dingdingusers \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  193. return BadRequest();
  194. }
  195. }
  196. /// <summary>
  197. /// 查询钉钉信息和醍摩豆信息 //已对接
  198. /// </summary>
  199. /// <returns></returns>
  200. [ProducesDefaultResponseType]
  201. [HttpPost("get-ddusers")]
  202. public async Task<IActionResult> GetDingDingUsers(JsonElement jsonElement)
  203. {
  204. try
  205. {
  206. jsonElement.TryGetProperty("busy", out JsonElement busy);
  207. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  208. var cosmosCliet = _azureCosmos.GetCosmosClient();
  209. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  210. ////分开部署,就不需要,一站多用时,取消注释
  211. //if ($"{site}".Equals(BIConst.Global))
  212. // table = _azureStorage.GetCloudTableClient(BIConst.Global).GetTableReference("BIDDUserInfo");
  213. //string divide = _configuration["CustomParam:SiteScope"];
  214. string divide = _option.Location;
  215. List<DDUserInfo> ddUserInfos = new();
  216. Dictionary<string, object> dic = new() { { "PartitionKey", $"{divide}" } };
  217. List<DingDingUserInfo> ddUserInfoList = await table.FindListByDict<DingDingUserInfo>(dic);
  218. switch ($"{busy}")
  219. {
  220. case "admin":
  221. foreach (var item in ddUserInfoList)
  222. {
  223. if (item.roles.Contains("admin"))
  224. {
  225. DDUserInfo ddUserInfo = new()
  226. {
  227. partitionKey = item.PartitionKey,
  228. rowKey = item.RowKey,
  229. userId = item.userId,
  230. unionId = item.unionId,
  231. name = item.name,
  232. title = item.title,
  233. stateCode = item.stateCode,
  234. mobile = item.mobile,
  235. jobNumber = item.jobNumber,
  236. pid = item.pid,
  237. deptId = item.deptId,
  238. deptName = item.deptName,
  239. depts = item.depts,
  240. avatar = item.avatar,
  241. isAdmin = item.isAdmin,
  242. tmdId = item.tmdId,
  243. tmdName = item.tmdName,
  244. tmdMobile = item.tmdMobile,
  245. mail = item.mail,
  246. picture = item.picture,
  247. roles = item.roles,
  248. joinTime = item.joinTime,
  249. isDisable = item.isDisable,
  250. permissions = item.permissions,
  251. handleRoles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(",")) : new List<string>(),
  252. handlePermissions = !string.IsNullOrEmpty($"{item.permissions}") ? new List<string>(item.permissions.Split(",")) : new List<string>(),
  253. };
  254. if (!string.IsNullOrEmpty(item.schoolIds))
  255. {
  256. List<string> tempSchoolIds = new(item.schoolIds.Split("|"));
  257. ddUserInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosCliet, tempSchoolIds);
  258. }
  259. ddUserInfos.Add(ddUserInfo);
  260. }
  261. }
  262. break;
  263. default:
  264. foreach (var item in ddUserInfoList)
  265. {
  266. DDUserInfo ddUserInfo = new()
  267. {
  268. partitionKey = item.PartitionKey,
  269. rowKey = item.RowKey,
  270. userId = item.userId,
  271. unionId = item.unionId,
  272. name = item.name,
  273. title = item.title,
  274. stateCode = item.stateCode,
  275. mobile = item.mobile,
  276. jobNumber = item.jobNumber,
  277. pid = item.pid,
  278. deptId = item.deptId,
  279. deptName = item.deptName,
  280. depts = item.depts,
  281. avatar = item.avatar,
  282. isAdmin = item.isAdmin,
  283. tmdId = item.tmdId,
  284. tmdName = item.tmdName,
  285. tmdMobile = item.tmdMobile,
  286. mail = item.mail,
  287. picture = item.picture,
  288. roles = item.roles,
  289. joinTime = item.joinTime,
  290. isDisable = item.isDisable,
  291. permissions = item.permissions,
  292. handleRoles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(",")) : new List<string>(),
  293. handlePermissions = !string.IsNullOrEmpty($"{item.permissions}") ? new List<string>(item.permissions.Split(",")) : new List<string>(),
  294. };
  295. if (!string.IsNullOrEmpty(item.schoolIds))
  296. {
  297. List<string> tempSchoolIds = new(item.schoolIds.Split("|"));
  298. ddUserInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosCliet, tempSchoolIds);
  299. }
  300. ddUserInfos.Add(ddUserInfo);
  301. }
  302. break;
  303. }
  304. return Ok(new { state = 200, ddUserInfos = ddUserInfos });
  305. }
  306. catch (Exception ex)
  307. {
  308. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/get-ddusers \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  309. return BadRequest();
  310. }
  311. }
  312. /// <summary>
  313. /// 更新钉钉和醍摩豆的BI权限 //已对接
  314. /// </summary>
  315. /// <param name="jsonElement"></param>
  316. /// <returns></returns>
  317. [ProducesDefaultResponseType]
  318. [AuthToken(Roles = "admin,rdc")]
  319. [HttpPost("set-rolesper")]
  320. public async Task<IActionResult> SetPermissions(JsonElement jsonElement)
  321. {
  322. try
  323. {
  324. if (!jsonElement.TryGetProperty("partitionKey", out JsonElement partitionKey)) return BadRequest();
  325. jsonElement.TryGetProperty("userId", out JsonElement userId);
  326. jsonElement.TryGetProperty("tmdId", out JsonElement tmdId);
  327. if (!jsonElement.TryGetProperty("permissions", out JsonElement _permissions)) return BadRequest();
  328. if (!jsonElement.TryGetProperty("roles", out JsonElement _roles)) return BadRequest();
  329. if (!jsonElement.TryGetProperty("isDisable", out JsonElement _isDisable)) return BadRequest();
  330. var cosmosCliet = _azureCosmos.GetCosmosClient();
  331. var tableClient = _azureStorage.GetCloudTableClient();
  332. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  333. long isDisable = 0;
  334. try
  335. {
  336. isDisable = long.Parse($"{_isDisable}");
  337. if (isDisable != 1 && isDisable != 0)
  338. return Ok(new { state = RespondCode.ParamsError, msg = "账户禁用参数错误!" });
  339. }
  340. catch
  341. {
  342. return Ok(new { state = RespondCode.ParamsError, msg = "账户禁用参数错误!" });
  343. }
  344. var table = tableClient.GetTableReference("BIDDUserInfo");
  345. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  346. List<DingDingUserInfo> ddUserInfos = new();
  347. List<string> listper = _permissions.ToObject<List<string>>();
  348. List<string> listroles = _roles.ToObject<List<string>>();
  349. List<string> roles = new();//角色列表
  350. List<string> permissions = new();//权限列表
  351. StringBuilder stringBuilder = new($"{_tmdName}【{_tmdId}】醍摩豆账号");
  352. Dictionary<string, object> dic = new() { { "PartitionKey", $"{partitionKey}" } };
  353. if (!string.IsNullOrEmpty($"{userId}"))
  354. dic.Add("userId", $"{userId}");
  355. if (!string.IsNullOrEmpty($"{tmdId}"))
  356. dic.Add("tmdId", $"{tmdId}");
  357. if (string.IsNullOrEmpty($"{userId}") && string.IsNullOrEmpty($"{tmdId}"))
  358. {
  359. return BadRequest();
  360. }
  361. var tempUser = await table.FindListByDict<DingDingUserInfo>(dic);
  362. List<string> oldRoles = new();
  363. List<Task<ItemResponse<BIRelation>>> upBIRel = new();
  364. //List<Task<ItemResponse<SchoolTeacher>>> upScTch = new();
  365. foreach (var item in tempUser)
  366. {
  367. oldRoles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(",")) : new List<string>();
  368. stringBuilder.Append($"操作醍摩豆账户{item.tmdName}【{item.tmdId}】修改权限:{string.Join("|", listper.ToArray())}");
  369. item.roles = listroles.Count > 0 ? string.Join(",", listroles) : "assist";
  370. item.permissions = string.Join(",", listper);
  371. item.isDisable = isDisable;
  372. ddUserInfos.Add(item);
  373. roles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(",")) : new List<string>();
  374. permissions = !string.IsNullOrEmpty($"{item.permissions}") ? new List<string>(item.permissions.Split(",")) : new List<string>();
  375. foreach (var itemR in listroles)
  376. {
  377. if(itemR.Equals("assist"))
  378. {
  379. string tempSql = $"select value(c) from c join a in c.sales where a.id='{itemR}'";
  380. await foreach (var itemRel in cosmosCliet.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIteratorSql<BIRelation>(queryText: tempSql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("BIRel") }))
  381. {
  382. var tempRel = itemRel.sales.Find(f => f.id.Equals(itemR));
  383. itemRel.sales.Remove(tempRel);
  384. itemRel.assists.Add(tempRel);
  385. itemRel.upDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  386. upBIRel.Add(cosmosCliet.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<BIRelation>(itemRel, itemRel.id, new PartitionKey("BIRel")));
  387. }
  388. //string sql = $"select value(c) from c where c.pk='Teacher' and c.id='{item.tmdId}'";
  389. //await foreach (var scTch in cosmosCliet.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIteratorSql<SchoolTeacher>(queryText: sql, requestOptions: new QueryRequestOptions() { }))
  390. //{
  391. // if (scTch.roles.Contains("sales"))
  392. // {
  393. // //int index = scTch.roles.FindIndex(fi => fi.Equals("sales"));
  394. // //scTch.roles[index]= "assist";
  395. // //scTch.job = "顾问";
  396. // //upScTch.Add(cosmosCliet.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<SchoolTeacher>(scTch, scTch.id, new PartitionKey($"{scTch.code}")));
  397. // int index = scTch.roles.FindIndex(fi => fi.Equals("sales"));
  398. // if (index >= 0)
  399. // {
  400. // scTch.roles[index] = "assist";
  401. // scTch.job = "顾问";
  402. // upScTch.Add(cosmosCliet.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<SchoolTeacher>(scTch, scTch.id, new PartitionKey($"{scTch.code}")));
  403. // }
  404. // }
  405. //}
  406. }
  407. if (itemR.Equals("sales"))
  408. {
  409. string tempSql = $"select value(c) from c join a in c.assists where a.id='{itemR}'";
  410. await foreach (var itemRel in cosmosCliet.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIteratorSql<BIRelation>(queryText: tempSql, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("BIRel") }))
  411. {
  412. var tempRel = itemRel.sales.Find(f => f.id.Equals(itemR));
  413. itemRel.assists.Remove(tempRel);
  414. itemRel.sales.Add(tempRel);
  415. itemRel.upDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  416. upBIRel.Add(cosmosCliet.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<BIRelation>(itemRel, itemRel.id, new PartitionKey("BIRel")));
  417. }
  418. //string sql = $"select value(c) from c where c.pk='Teacher' and c.id='{item.tmdId}'";
  419. //await foreach (var scTch in cosmosCliet.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIteratorSql<SchoolTeacher>(queryText: sql, requestOptions: new QueryRequestOptions() { }))
  420. //{
  421. // if (scTch.roles.Contains("assist"))
  422. // {
  423. // int index = scTch.roles.FindIndex(fi => fi.Equals("assist"));
  424. // if (index >= 0)
  425. // {
  426. // scTch.roles[index] = "sales";
  427. // scTch.job = "销售";
  428. // upScTch.Add(cosmosCliet.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<SchoolTeacher>(scTch, scTch.id, new PartitionKey($"{scTch.code}")));
  429. // }
  430. // }
  431. //}
  432. }
  433. }
  434. }
  435. if (upBIRel.Count < 256)
  436. {
  437. await Task.WhenAll(upBIRel);
  438. }
  439. else
  440. {
  441. int pages = (upBIRel.Count + 255) / 256;
  442. for (int i = 0; i < pages; i++)
  443. {
  444. List<Task<ItemResponse<BIRelation>>> tempRel = upBIRel.Skip((i) * 256).Take(256).ToList();
  445. await Task.WhenAll(tempRel);
  446. }
  447. }
  448. ddUserInfos = await table.UpdateAll<DingDingUserInfo>(ddUserInfos);
  449. List<DDUserInfo> ddUserInfo = new();
  450. foreach (var item in ddUserInfos)
  451. {
  452. DDUserInfo tempInfo = new()
  453. {
  454. partitionKey = item.PartitionKey,
  455. rowKey = item.RowKey,
  456. userId = item.userId,
  457. unionId = item.unionId,
  458. name = item.name,
  459. title = item.title,
  460. stateCode = item.stateCode,
  461. mobile = item.mobile,
  462. jobNumber = item.jobNumber,
  463. pid = item.pid,
  464. deptId = item.deptId,
  465. deptName = item.deptName,
  466. depts = item.depts,
  467. avatar = item.avatar,
  468. isAdmin = item.isAdmin,
  469. tmdId = item.tmdId,
  470. tmdName = item.tmdName,
  471. tmdMobile = item.tmdMobile,
  472. mail = item.mail,
  473. picture = item.picture,
  474. roles = item.roles,
  475. joinTime = item.joinTime,
  476. isDisable = item.isDisable,
  477. permissions = item.permissions,
  478. handleRoles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(",")) : new List<string>(),
  479. handlePermissions = !string.IsNullOrEmpty($"{item.permissions}") ? new List<string>(item.permissions.Split(",")) : new List<string>(),
  480. };
  481. if (!string.IsNullOrEmpty(item.schoolIds))
  482. {
  483. List<string> tempSchoolIds = new(item.schoolIds.Split("|"));
  484. tempInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosCliet, tempSchoolIds);
  485. }
  486. ddUserInfo.Add(tempInfo);
  487. }
  488. //保存操作记录
  489. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", stringBuilder?.ToString(), _dingDing, httpContext: HttpContext);
  490. return Ok(new { state = 200, ddUserInfo, roles, permissions });
  491. }
  492. catch (Exception ex)
  493. {
  494. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/tabledd-update \n {ex.Message}\n{ex.StackTrace} ", GroupNames.成都开发測試群組);
  495. return BadRequest();
  496. }
  497. }
  498. /// <summary>
  499. /// 依据部门ID获取部门列表 //已对接
  500. /// </summary>
  501. /// <param name="jsonElement"></param>
  502. /// <returns></returns>
  503. [ProducesDefaultResponseType]
  504. [HttpPost("get-dddeptiduser")]
  505. public async Task<IActionResult> GetDDDeptIdUser(JsonElement jsonElement)
  506. {
  507. try
  508. {
  509. if (!jsonElement.TryGetProperty("deptId", out JsonElement deptId)) return BadRequest();
  510. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  511. var cosmosCliet = _azureCosmos.GetCosmosClient();
  512. var tableClient = _azureStorage.GetCloudTableClient();
  513. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  514. ////分开部署,就不需要,一站多用时,取消注释
  515. //if ($"{site}".Equals(BIConst.Global))
  516. //{
  517. // cosmosCliet = _azureCosmos.GetCosmosClient(name: BIConst.Global);
  518. // tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  519. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  520. //};
  521. var table = tableClient.GetTableReference("BIDDUserInfo");
  522. //string divide = _configuration["CustomParam:SiteScope"];
  523. string divide = _option.Location;
  524. Dictionary<string, object> dic = new() { { "PartitionKey", $"{divide}" } };
  525. List<DingDingUserInfo> tempUserInfos = await table.FindListByDict<DingDingUserInfo>(dic);
  526. List<DingDingUserInfo> userInfo = new();
  527. tempUserInfos.ForEach(x => {
  528. if (x.depts.Contains($"{deptId}"))
  529. {
  530. userInfo.Add(x);
  531. }
  532. if (x.pid.Equals(long.Parse($"{deptId}")))
  533. {
  534. userInfo.Add(x);
  535. }
  536. });
  537. //userInfo.Distinct().ToList(); //Equals实现去重
  538. userInfo.Where((x, i) => userInfo.FindIndex(z => z.RowKey.Equals(x.RowKey)) == i);//Lambda表达式去重
  539. //userInfo.GroupBy(p => p).Select(p => p.Key).ToList();//去重复
  540. List<DDUserInfo> ddUserInfos = new();
  541. foreach (var item in userInfo)
  542. {
  543. DDUserInfo tempUserInfo = new DDUserInfo()
  544. {
  545. partitionKey = item.PartitionKey,
  546. rowKey = item.RowKey,
  547. userId = item.userId,
  548. unionId = item.unionId,
  549. name = item.name,
  550. title = item.title,
  551. stateCode = item.stateCode,
  552. mobile = item.mobile,
  553. jobNumber = item.jobNumber,
  554. pid = item.pid,
  555. deptId = item.deptId,
  556. deptName = item.deptName,
  557. depts = item.depts,
  558. avatar = item.avatar,
  559. isAdmin = item.isAdmin,
  560. tmdId = item.tmdId,
  561. tmdName = item.tmdName,
  562. tmdMobile = item.tmdMobile,
  563. mail = item.mail,
  564. picture = item.picture,
  565. roles = item.roles,
  566. joinTime = item.joinTime,
  567. isDisable = item.isDisable,
  568. permissions = item.permissions,
  569. handleRoles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(",")) : new List<string>(),
  570. handlePermissions = !string.IsNullOrEmpty($"{item.permissions}") ? new List<string>(item.permissions.Split(",")) : new List<string>(),
  571. };
  572. if (!string.IsNullOrEmpty(item.schoolIds))
  573. {
  574. List<string> tempSchoolIds = new(item.schoolIds.Split("|"));
  575. tempUserInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosCliet, tempSchoolIds);
  576. }
  577. ddUserInfos.Add(tempUserInfo);
  578. }
  579. return Ok(new { state = 200, ddUserInfos });
  580. }
  581. catch (Exception ex)
  582. {
  583. await _dingDing.SendBotMsg($"BI, {_option.Location} /tabledd/get-dddeptiduser \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  584. return BadRequest();
  585. }
  586. }
  587. /// <summary>
  588. /// 通过醍摩豆账户信息 设置BI后台管理员 //已对接
  589. /// </summary>
  590. /// <param name="jsonElement"></param>
  591. /// <returns></returns>
  592. [ProducesDefaultResponseType]
  593. [AuthToken(Roles = "admin,rdc")]
  594. [HttpPost("set-tmdadmin")]
  595. public async Task<IActionResult> SetTmdBackendAdmin(JsonElement jsonElement)
  596. {
  597. try
  598. {
  599. if (!jsonElement.TryGetProperty("tmdId", out JsonElement tmdId)) return BadRequest();
  600. if (!jsonElement.TryGetProperty("tmdName", out JsonElement tmdName)) return BadRequest();
  601. if (!jsonElement.TryGetProperty("mobile", out JsonElement mobile)) return BadRequest();
  602. jsonElement.TryGetProperty("picture ", out JsonElement picture);
  603. jsonElement.TryGetProperty("mail ", out JsonElement mail);
  604. //jsonElement.TryGetProperty("site", out JsonElement site); //分开部署,就不需要,一站多用时,取消注释
  605. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  606. var cosmosCliet = _azureCosmos.GetCosmosClient();
  607. var tableClient = _azureStorage.GetCloudTableClient();
  608. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  609. ////分开部署,就不需要,一站多用时,取消注释
  610. //if ($"{site}".Equals(BIConst.Global))
  611. //{
  612. // cosmosCliet = _azureCosmos.GetCosmosClient(name: BIConst.Global);
  613. // tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  614. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  615. //}
  616. var table = tableClient.GetTableReference("BIDDUserInfo");
  617. List<DDUserInfo> ddUserInfos = new();
  618. List<string> roles = new();//角色列表
  619. List<string> permissions = new();//权限列表
  620. StringBuilder msg = new($"{_tmdName}【{_tmdId}】");
  621. //string divide = _configuration["CustomParam:SiteScope"];
  622. string divide = _option.Location;
  623. Dictionary<string, object> dic = new() { { "PartitionKey", $"{divide}" }, { "mobile", $"{mobile}" } };
  624. List<DingDingUserInfo> ddUserInfoList = await table.FindListByDict<DingDingUserInfo>(dic);
  625. if (ddUserInfoList.Count > 0)
  626. {
  627. foreach (var user in ddUserInfoList)
  628. {
  629. List<string> tempRoles = new(user.roles.Split(","));
  630. if (tempRoles.Count > 0)
  631. {
  632. if (!tempRoles.Contains("admin"))
  633. {
  634. tempRoles.Add("admin");
  635. }
  636. }
  637. else
  638. tempRoles.Add("admin");
  639. user.roles = string.Join(",", tempRoles);
  640. user.joinTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  641. user.tmdId = $"{tmdId}";
  642. user.tmdName = $"{tmdName}";
  643. user.tmdMobile = $"{mobile}";
  644. if (!string.IsNullOrEmpty($"{picture}"))
  645. {
  646. user.picture = $"{picture}";
  647. }
  648. if (!string.IsNullOrEmpty($"{mail}"))
  649. {
  650. user.mail = $"{mail}";
  651. }
  652. msg.Append($" 将:{tmdName}【{tmdId}】醍摩豆账号和({user.name}【{user.unionId}】) 钉钉账户绑定,并设置管理员");
  653. DingDingUserInfo respUser = await table.SaveOrUpdate<DingDingUserInfo>(user);
  654. if (respUser != null)
  655. {
  656. roles = !string.IsNullOrEmpty($"{respUser.roles}") ? new List<string>(respUser.roles.Split(",")) : new List<string>();
  657. }
  658. DDUserInfo dDUserInfo = new()
  659. {
  660. partitionKey = respUser.PartitionKey,
  661. rowKey = respUser.RowKey,
  662. userId = respUser.userId,
  663. unionId = respUser.unionId,
  664. name = respUser.name,
  665. title = respUser.title,
  666. stateCode = respUser.stateCode,
  667. mobile = respUser.mobile,
  668. jobNumber = respUser.jobNumber,
  669. pid = respUser.pid,
  670. deptId = respUser.deptId,
  671. deptName = respUser.deptName,
  672. depts = respUser.depts,
  673. avatar = respUser.avatar,
  674. isAdmin = respUser.isAdmin,
  675. tmdId = respUser.tmdId,
  676. tmdName = respUser.tmdName,
  677. tmdMobile = respUser.tmdMobile,
  678. mail = respUser.mail,
  679. picture = respUser.picture,
  680. roles = respUser.roles,
  681. joinTime = respUser.joinTime,
  682. isDisable = respUser.isDisable,
  683. permissions = respUser.permissions,
  684. handleRoles = !string.IsNullOrEmpty($"{respUser.roles}") ? new List<string>(respUser.roles.Split(",")) : new List<string>(),
  685. handlePermissions = !string.IsNullOrEmpty($"{respUser.permissions}") ? new List<string>(respUser.permissions.Split(",")) : new List<string>()
  686. };
  687. if (!string.IsNullOrEmpty(respUser.schoolIds))
  688. {
  689. List<string> tempSchoolIds = new(respUser.schoolIds.Split("|"));
  690. dDUserInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosCliet, tempSchoolIds);
  691. }
  692. ddUserInfos.Add(dDUserInfo);
  693. }
  694. }
  695. else
  696. {
  697. DingDingUserInfo dingDingUserInfo = new()
  698. {
  699. PartitionKey = divide,
  700. RowKey = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(),
  701. roles = "admin",
  702. tmdId = $"{tmdId}",
  703. tmdName = $"{tmdName}",
  704. tmdMobile = $"{mobile}",
  705. };
  706. if (!string.IsNullOrEmpty($"{picture}"))
  707. {
  708. dingDingUserInfo.picture = $"{picture}";
  709. }
  710. if (!string.IsNullOrEmpty($"{mail}"))
  711. {
  712. dingDingUserInfo.mail = $"{mail}";
  713. }
  714. DingDingUserInfo respUser = await table.SaveOrUpdate<DingDingUserInfo>(dingDingUserInfo);
  715. return Ok(new { state = 201, msg = "新生成的BIadmin", respUser });
  716. }
  717. //保存操作记录
  718. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", msg.ToString(), _dingDing, httpContext: HttpContext);
  719. return Ok(new { state = 200, ddUserInfos });
  720. }
  721. catch (Exception ex)
  722. {
  723. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/set-tmdadmin \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  724. return BadRequest();
  725. }
  726. }
  727. /// <summary>
  728. /// 设置系统管理员 //已对接
  729. /// </summary>
  730. /// <param name="jsonElement"></param>
  731. /// <returns></returns>
  732. [ProducesDefaultResponseType]
  733. [AuthToken(Roles = "admin,rdc")]
  734. [HttpPost("set-backend")]
  735. public async Task<IActionResult> SetBackendAdmin(JsonElement jsonElement)
  736. {
  737. try
  738. {
  739. if (!jsonElement.TryGetProperty("partitionKey", out JsonElement partitionKey)) return BadRequest();
  740. if (!jsonElement.TryGetProperty("rowKey", out JsonElement rowKey)) return BadRequest();
  741. if (!jsonElement.TryGetProperty("isAdmin", out JsonElement isAdmin)) return BadRequest();
  742. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  743. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  744. var tableClient = _azureStorage.GetCloudTableClient();
  745. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  746. ////分开部署,就不需要,一站多用时,取消注释
  747. //if ($"{site}".Equals(BIConst.Global))
  748. //{
  749. // tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  750. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  751. //}
  752. var table = tableClient.GetTableReference("BIDDUserInfo");
  753. var tempUser = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{partitionKey}" }, { "RowKey", $"{rowKey}" } });
  754. List<DDUserInfo> ddUserInfos = new();
  755. List<string> roles = new();//角色列表
  756. List<string> permissions = new();//权限列表
  757. StringBuilder msg = new($"{_tmdName}【{_tmdId}】");
  758. if (bool.Parse($"{isAdmin}") == true)
  759. {
  760. foreach (var user in tempUser)
  761. {
  762. if (string.IsNullOrEmpty(user.roles))
  763. {
  764. user.roles = "admin";
  765. }
  766. List<string> tempRoles = new(user.roles.Split(","));
  767. if (!tempRoles.Contains("admin"))
  768. {
  769. tempRoles.Add("admin");
  770. }
  771. user.roles = string.Join(",", tempRoles);
  772. user.joinTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  773. DingDingUserInfo respUser = await table.SaveOrUpdate<DingDingUserInfo>(user);
  774. if (respUser != null)
  775. {
  776. roles = !string.IsNullOrEmpty($"{respUser.roles}") ? new List<string>(respUser.roles.Split(",")) : new List<string>();
  777. }
  778. msg.Append($"添加{respUser.name}【{respUser.RowKey}】账号的BI管理员");
  779. }
  780. }
  781. else
  782. {
  783. var userInfos = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{partitionKey}" } });
  784. var adminInfos = userInfos.FindAll(x => x.roles.Contains("admin"));
  785. if (adminInfos.Count() == 1)
  786. {
  787. return Ok(new { state = 403, msg = "已经是最后一个管理员了" });
  788. }
  789. else
  790. {
  791. foreach (var user in tempUser)
  792. {
  793. if (!user.userId.Equals($"{did}"))
  794. {
  795. List<string> tempRoles = new(user.roles.Split(","));
  796. if (tempRoles.Contains("admin"))
  797. {
  798. tempRoles.Remove("admin");
  799. }
  800. user.roles = string.Join(",", tempRoles);
  801. DingDingUserInfo respUser = await table.SaveOrUpdate<DingDingUserInfo>(user);
  802. if (respUser != null)
  803. {
  804. roles = !string.IsNullOrEmpty($"{respUser.roles}") ? new List<string>(respUser.roles.Split(",")) : new List<string>();
  805. msg.Append($"取消{respUser.name}【{respUser.RowKey}】账号的BI管理员");
  806. }
  807. }
  808. else return Ok(new { state = 1, msg = "不能删除自己" });
  809. }
  810. }
  811. }
  812. //保存操作记录
  813. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", msg.ToString(), _dingDing, httpContext: HttpContext);
  814. return Ok(new { state = 200, roles });
  815. }
  816. catch (Exception ex)
  817. {
  818. await _dingDing.SendBotMsg($"BI, {_option.Location} /tabledd/set-backend \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  819. return BadRequest();
  820. }
  821. }
  822. /// <summary>
  823. /// 从钉钉的组织架构中人员信息数据,并保存或者更新至Blob中 初始化使用该接口
  824. /// </summary>
  825. /// <returns></returns>
  826. [ProducesDefaultResponseType]
  827. [HttpPost("get-dduserinitial")]
  828. public async Task<IActionResult> GetddUserInitial(JsonElement jsonElement)
  829. {
  830. try
  831. {
  832. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  833. var tableClient = _azureStorage.GetCloudTableClient();
  834. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  835. ////分开部署,就不需要,一站多用时,取消注释
  836. //if ($"{site}".Equals(BIConst.Global))
  837. //{
  838. // tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  839. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  840. //}
  841. var table = tableClient.GetTableReference("BIDDUserInfo");
  842. string appKey = _configuration["DingDingAuth:appKey"];
  843. string appSecret = _configuration["DingDingAuth:appSecret"];
  844. //string divide = _configuration["CustomParam:SiteScope"];
  845. string divide = _option.Location;
  846. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  847. //获取access_token
  848. IDingTalkClient tokenClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  849. OapiGettokenRequest tokenRequest = new() { Appkey = appKey, Appsecret = appSecret };
  850. tokenRequest.SetHttpMethod("Get");
  851. OapiGettokenResponse tokenRespone = tokenClient.Execute(tokenRequest);
  852. if (tokenRespone.IsError)
  853. {
  854. return BadRequest();
  855. }
  856. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  857. string access_token = tokenRespone.AccessToken;
  858. //获取部门接口
  859. IDingTalkClient deptListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
  860. //一级部门
  861. OapiV2DepartmentListsubRequest reqDeptList1 = new() { DeptId = 1L, Language = "zh_CN" };
  862. OapiV2DepartmentListsubResponse rspDeptList1 = deptListClient.Execute(reqDeptList1, access_token);
  863. List<DingDingUserInfo> ddUserInfos = new();
  864. if (rspDeptList1.Result != null)
  865. {
  866. foreach (var tempDept1 in rspDeptList1.Result)
  867. {
  868. //获取一级部门用户信息
  869. List<DingDingUserInfo> dingDingUserInfos1 = await GetDingDingUserInfo(divide, tempDept1.DeptId, tempDept1.ParentId, tempDept1.Name, access_token);
  870. //if (dingDingUserInfos1.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos1.ToList()));
  871. if (dingDingUserInfos1.Count > 0) ddUserInfos.AddRange(dingDingUserInfos1);
  872. //获取二级部门
  873. OapiV2DepartmentListsubRequest reqDeptList2 = new() { DeptId = tempDept1.DeptId, Language = "zh_CN" };
  874. OapiV2DepartmentListsubResponse rspDeptList2 = deptListClient.Execute(reqDeptList2, access_token);
  875. if (rspDeptList2.Result != null)
  876. {
  877. foreach (var tempDept2 in rspDeptList2.Result)
  878. {
  879. //获取二级部门用户信息
  880. List<DingDingUserInfo> dingDingUserInfos2 = await GetDingDingUserInfo(divide, tempDept2.DeptId, tempDept2.ParentId, tempDept2.Name, access_token);
  881. //if (dingDingUserInfos2.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos2.ToList()));
  882. if (dingDingUserInfos2.Count > 0) ddUserInfos.AddRange(dingDingUserInfos2);
  883. //获取三级部门
  884. OapiV2DepartmentListsubRequest reqDeptList3 = new() { DeptId = tempDept2.DeptId, Language = "zh_CN" };
  885. OapiV2DepartmentListsubResponse rspDeptList3 = deptListClient.Execute(reqDeptList3, access_token);
  886. if (rspDeptList3.Result != null)
  887. {
  888. foreach (var tempDept3 in rspDeptList3.Result)
  889. {
  890. //获取三级部门用户信息
  891. List<DingDingUserInfo> dingDingUserInfos3 = await GetDingDingUserInfo(divide, tempDept3.DeptId, tempDept3.ParentId, tempDept3.Name, access_token);
  892. //if (dingDingUserInfos3.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos3.ToList()));
  893. if (dingDingUserInfos3.Count > 0) ddUserInfos.AddRange(dingDingUserInfos3);
  894. //获取四级部门
  895. OapiV2DepartmentListsubRequest reqDeptList4 = new() { DeptId = tempDept3.DeptId, Language = "zh_CN" };
  896. OapiV2DepartmentListsubResponse rspDeptList4 = deptListClient.Execute(reqDeptList4, access_token);
  897. if (rspDeptList4.Result != null)
  898. {
  899. foreach (var tempDept4 in rspDeptList4.Result)
  900. {
  901. //获取四级部门用户信息
  902. List<DingDingUserInfo> dingDingUserInfos4 = await GetDingDingUserInfo(divide, tempDept4.DeptId, tempDept4.ParentId, tempDept4.Name, access_token);
  903. //if (dingDingUserInfos4.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos4.ToList()));
  904. if (dingDingUserInfos4.Count > 0) ddUserInfos.AddRange(dingDingUserInfos4);
  905. //获取五级部门
  906. OapiV2DepartmentListsubRequest reqDeptList5 = new() { DeptId = tempDept4.DeptId, Language = "zh_CN" };
  907. OapiV2DepartmentListsubResponse rspDeptList5 = deptListClient.Execute(reqDeptList5, access_token);
  908. if (rspDeptList5.Result != null)
  909. {
  910. foreach (var tempDept5 in rspDeptList5.Result)
  911. {
  912. //获取五级部门用户信息
  913. List<DingDingUserInfo> dingDingUserInfos5 = await GetDingDingUserInfo(divide, tempDept5.DeptId, tempDept5.ParentId, tempDept5.Name, access_token);
  914. //if (dingDingUserInfos5.Count > 0) ddUserInfos.AddRange(ddUserInfos.Union(dingDingUserInfos5).ToList());
  915. if (dingDingUserInfos5.Count > 0) ddUserInfos.AddRange(dingDingUserInfos5);
  916. }
  917. }
  918. }
  919. }
  920. }
  921. }
  922. }
  923. }
  924. }
  925. }
  926. //保存操作记录
  927. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{_tmdName}【{_tmdId}】从钉钉组织结构初始化至Azure Table表【DDUserInfo】中。", _dingDing, httpContext: HttpContext);
  928. var tempddUserInfos = ddUserInfos.GroupBy(c => c.userId).Select(c => c.First()).ToList();//去重
  929. //List<DingDingUserInfo> TempdingDingUserInfos = await _azureStorage.SaveOrUpdateAll(dingDingUserInfos); //只是保存至Table
  930. //查询数据的数据 并和钉钉查询的数据对比,找出不同的数据,并删除 待后期测试
  931. var users = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{divide}" } });
  932. List<DingDingUserInfo> noExisits = new();
  933. if (users.Count() > 0)
  934. {
  935. //var temps = users.Union(tempddUserInfos).Except(users.Intersect(tempddUserInfos));
  936. List<DingDingUserInfo> existsUserInfo = users.Where(u => !tempddUserInfos.Exists(e => u.userId.Equals(e.userId) && u.PartitionKey.Equals(e.PartitionKey))).ToList();
  937. if (users.Count() >= tempddUserInfos.Count)
  938. {
  939. existsUserInfo.AddRange(tempddUserInfos.Where(e => !users.Exists(u => e.userId.Equals(u.userId) && e.PartitionKey.Equals(u.PartitionKey))).ToList());
  940. }
  941. ////List<DingDingUserInfo> existsUserInfo = users.Where((x, i) => users.FindIndex(z => z.userId.Equals(x.userId) && x.PartitionKey.Equals(divide)) == i).Select(x => x).ToList();
  942. if (existsUserInfo.Count > 0)
  943. {
  944. noExisits = await table.DeleteAll(existsUserInfo);
  945. }
  946. }
  947. List<DingDingUserInfo> UserInfo = await table.SaveOrUpdateAll(tempddUserInfos); //保存和修改至Table
  948. return Ok(new { state = 200, UserInfo, noExisits });
  949. }
  950. catch (Exception ex)
  951. {
  952. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/get-dingdingusers \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  953. return BadRequest();
  954. }
  955. }
  956. /// <summary>
  957. /// 后端钉钉账户和醍摩豆账户进行绑定
  958. /// </summary>
  959. /// <param name="jsonElement"></param>
  960. /// <returns></returns>
  961. [ProducesDefaultResponseType]
  962. [AuthToken(Roles = "admin,rdc")]
  963. [HttpPost("set-backenbind")]
  964. public async Task<IActionResult> SetBackenBind(JsonElement jsonElement)
  965. {
  966. try
  967. {
  968. if (!jsonElement.TryGetProperty("rowKey", out JsonElement rowKey)) return BadRequest();
  969. if (!jsonElement.TryGetProperty("mobile", out JsonElement mobile)) return BadRequest();
  970. //jsonElement.TryGetProperty("site", out JsonElement site); //分开部署,就不需要,一站多用时,取消注释
  971. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  972. var tableClient = _azureStorage.GetCloudTableClient();
  973. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  974. ////分开部署,就不需要,一站多用时,取消注释
  975. //if ($"{site}".Equals(BIConst.Global))
  976. //{
  977. // tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  978. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  979. //}
  980. var table = tableClient.GetTableReference("BIDDUserInfo");
  981. List<DingDingUserInfo> tempddUsers = null;
  982. List<DingDingUserInfo> ddUsers = new();
  983. StringBuilder tableSql = new();
  984. if (!string.IsNullOrEmpty($"{rowKey}"))
  985. tableSql.Append($"RowKey {QueryComparisons.Equal} '{rowKey}'");
  986. string tmdId = null;
  987. string tmdName = null;
  988. string tmdMobile = null;
  989. string mail = null;
  990. string picture = null;
  991. var coreUser = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", $"{mobile}" } }, _option.Location, _configuration);
  992. if (coreUser != null && coreUser.id != null)
  993. {
  994. tmdId = coreUser.id;
  995. tmdName = coreUser.name;
  996. tmdMobile = coreUser.mobile;
  997. mail = coreUser.mail;
  998. picture = coreUser.picture;
  999. }else return Ok(new { state = 1, message = "该手机号未找到醍摩豆账户" });
  1000. tempddUsers = await table.QueryWhereString<DingDingUserInfo>(tableSql.ToString());
  1001. if (tempddUsers.Count > 0)
  1002. {
  1003. foreach (var item in tempddUsers)
  1004. {
  1005. if (item.RowKey.Equals($"{rowKey}"))
  1006. {
  1007. item.tmdId = tmdId;
  1008. item.tmdName = tmdName;
  1009. item.tmdMobile = tmdMobile;
  1010. item.mail = mail;
  1011. item.picture = picture;
  1012. ddUsers.Add(item);
  1013. }
  1014. }
  1015. }
  1016. else return Ok(new { state = 2, message = "钉钉ID错误请检查钉钉ID" });
  1017. if (ddUsers.Count > 0) ddUsers = await table.SaveOrUpdateAll(ddUsers);
  1018. //保存操作记录
  1019. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", $"{_tmdName}【{_tmdId}】操作:绑定钉钉账户[{rowKey}]和醍摩豆账户[{tmdId}]", _dingDing, httpContext: HttpContext);
  1020. return Ok(new { state = 200, ddUsers });
  1021. }
  1022. catch (Exception ex)
  1023. {
  1024. await _dingDing.SendBotMsg($"BI, {_option.Location} /tabledd/set-backenbind \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  1025. return BadRequest();
  1026. }
  1027. }
  1028. /// <summary>
  1029. /// 后端初始化管理员
  1030. /// </summary>
  1031. /// <param name="jsonElement"></param>
  1032. /// <returns></returns>
  1033. [ProducesDefaultResponseType]
  1034. [HttpPost("set-apiphoneadmin")]
  1035. public async Task<IActionResult> SetPhoneAdmin(JsonElement jsonElement)
  1036. {
  1037. jsonElement.TryGetProperty("partitionKey", out JsonElement partitionKey);
  1038. if (!jsonElement.TryGetProperty("mobile", out JsonElement mobile)) return BadRequest();
  1039. //jsonElement.TryGetProperty("site", out JsonElement site); //分开部署,就不需要,一站多用时,取消注释
  1040. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  1041. var partKey = _option.Location;
  1042. if (string.IsNullOrEmpty($"{partitionKey}"))
  1043. {
  1044. partKey = $"{partitionKey}";
  1045. };
  1046. var tableClient = _azureStorage.GetCloudTableClient();
  1047. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  1048. ////分开部署,就不需要,一站多用时,取消注释
  1049. //if ($"{site}".Equals(BIConst.Global))
  1050. //{
  1051. // tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  1052. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  1053. //}
  1054. var table = tableClient.GetTableReference("BIDDUserInfo");
  1055. var tempUser = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{partKey}" }, { "mobile", $"{mobile}" } });
  1056. List<string> roles = new();//角色列表
  1057. List<string> permissions = new();//权限列表
  1058. StringBuilder msg = new();
  1059. foreach (var user in tempUser)
  1060. {
  1061. if (string.IsNullOrEmpty(user.roles))
  1062. {
  1063. user.roles = "admin";
  1064. }
  1065. List<string> tempRoles = new(user.roles.Split(","));
  1066. if (!tempRoles.Contains("admin"))
  1067. {
  1068. tempRoles.Add("admin");
  1069. }
  1070. user.roles = string.Join(",", tempRoles);
  1071. user.joinTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  1072. DingDingUserInfo respUser = await table.SaveOrUpdate<DingDingUserInfo>(user);
  1073. if (respUser != null)
  1074. {
  1075. roles = !string.IsNullOrEmpty($"{respUser.roles}") ? new List<string>(respUser.roles.Split(",")) : new List<string>();
  1076. }
  1077. msg.Append($"初始将{respUser.name}【{respUser.RowKey}】账号的BI管理员");
  1078. }
  1079. //保存操作记录
  1080. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update", msg.ToString(), _dingDing, httpContext: HttpContext);
  1081. return Ok(new { state = 200, roles });
  1082. }
  1083. /// <summary>
  1084. /// 解除钉钉和醍摩豆的绑定
  1085. /// </summary>
  1086. /// <param name="jsonElement"></param>
  1087. /// <returns></returns>
  1088. [ProducesDefaultResponseType]
  1089. [HttpPost("set-unbind")]
  1090. public async Task<IActionResult> SetUnbind(JsonElement jsonElement)
  1091. {
  1092. jsonElement.TryGetProperty("mobile", out JsonElement mobile);
  1093. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  1094. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  1095. ////分开部署,就不需要,一站多用时,取消注释
  1096. //if ($"{site}".Equals(BIConst.Global))
  1097. // table = _azureStorage.GetCloudTableClient(BIConst.Global).GetTableReference("BIDDUserInfo");
  1098. //string divide = _configuration["CustomParam:SiteScope"];
  1099. string divide = _option.Location;
  1100. Dictionary<string, object> dic = new Dictionary<string, object> { { "PartitionKey", $"{divide}" } };
  1101. if (!string.IsNullOrEmpty($"{mobile}"))
  1102. dic.Add("tmdMobile", $"{mobile}");
  1103. else
  1104. dic.Add("tmdMobile", "18281911681");
  1105. List<DingDingUserInfo> ddUserInfoList = await table.FindListByDict<DingDingUserInfo>(dic);
  1106. List<DingDingUserInfo> tempDDUI = new();
  1107. if (ddUserInfoList.Count > 0)
  1108. {
  1109. foreach (var item in ddUserInfoList)
  1110. {
  1111. item.tmdId = null;
  1112. item.tmdName = null;
  1113. item.tmdMobile = null;
  1114. item.picture = null;
  1115. tempDDUI.Add(item);
  1116. }
  1117. }
  1118. else return Ok(new { state = 404, msg = "未找到手机号匹配的绑定号码!,请检查手机号" });
  1119. var userInfos = await table.SaveOrUpdateAll(tempDDUI); //保存和修改至Table
  1120. return Ok(new { state = 200, userInfos });
  1121. }
  1122. /// <summary>
  1123. /// 查询钉钉待入职人员的ID添加至Table数据表中
  1124. /// </summary>
  1125. /// <returns></returns>
  1126. [ProducesDefaultResponseType]
  1127. [AuthToken(Roles = "admin,rdc")]
  1128. [HttpPost("set-ddinductionuser")]
  1129. public async Task<IActionResult> SetDingDingInductionUser(JsonElement jsonElement)
  1130. {
  1131. try
  1132. {
  1133. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  1134. var tableClient = _azureStorage.GetCloudTableClient();
  1135. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  1136. ////分开部署,就不需要,一站多用时,取消注释
  1137. //if ($"{site}".Equals(BIConst.Global))
  1138. //{
  1139. // tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  1140. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  1141. //}
  1142. var table = tableClient.GetTableReference("BIDDUserInfo");
  1143. string appKey = _configuration["DingDingAuth:appKey"];
  1144. string appSecret = _configuration["DingDingAuth:appSecret"];
  1145. //string divide = _configuration["CustomParam:SiteScope"];
  1146. string divide = _option.Location;
  1147. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  1148. //获取access_token
  1149. IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  1150. OapiGettokenRequest request = new() { Appkey = appKey, Appsecret = appSecret };
  1151. request.SetHttpMethod("Get");
  1152. OapiGettokenResponse response = client.Execute(request);
  1153. if (response.IsError)
  1154. {
  1155. return BadRequest();
  1156. }
  1157. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  1158. string access_token = response.AccessToken;
  1159. IDingTalkClient InductionClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/querypreentry");
  1160. OapiSmartworkHrmEmployeeQuerypreentryRequest reqInduction = new() { Offset = 0L, Size = 50 };
  1161. reqInduction.SetHttpMethod("GET");
  1162. OapiSmartworkHrmEmployeeQuerypreentryResponse rspInduction = InductionClient.Execute(reqInduction, access_token);
  1163. if (rspInduction.Result.DataList != null)
  1164. {
  1165. List<DingDingUserInfo> ddUserInfos = new();
  1166. foreach (var itemId in rspInduction.Result.DataList)
  1167. {
  1168. DingDingUserInfo ddUserInfo = new();
  1169. ddUserInfo.PartitionKey = divide;
  1170. ddUserInfo.RowKey = itemId;
  1171. ddUserInfos.Add(ddUserInfo);
  1172. }
  1173. List<DingDingUserInfo> tempddUserInfos = await table.SaveAll(ddUserInfos);
  1174. //保存操作记录
  1175. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-add", $"{_tmdName}【{_tmdId}】添加待入职员工至table数据表中", _dingDing, httpContext: HttpContext);
  1176. if (ddUserInfos.Count == tempddUserInfos.Count)
  1177. return Ok(new { state = 200, UserInfo = tempddUserInfos });
  1178. else
  1179. {
  1180. var diffArr = tempddUserInfos.Where(c => !ddUserInfos.Contains(c)).ToList();
  1181. return Ok(new { state = 201, notUserInfo = diffArr });
  1182. }
  1183. }
  1184. else
  1185. return Ok(new { state = 400, rspInduction.SubErrCode, rspInduction.SubErrMsg });
  1186. }
  1187. catch (Exception ex)
  1188. {
  1189. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/set-ddinductionuser \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  1190. return BadRequest();
  1191. }
  1192. }
  1193. /// <summary>
  1194. /// 获取钉钉离职人员ID并删除Table表中的数据
  1195. /// </summary>
  1196. /// <returns></returns>
  1197. [ProducesDefaultResponseType]
  1198. [AuthToken(Roles = "admin,rdc")]
  1199. [HttpPost("del-ddquituser")]
  1200. public async Task<IActionResult> DeleteDDQuitUser(JsonElement jsonElement)
  1201. {
  1202. try
  1203. {
  1204. //jsonElement.TryGetProperty("site", out JsonElement site);//分开部署,就不需要,一站多用时,取消注释
  1205. var tableClient = _azureStorage.GetCloudTableClient();
  1206. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  1207. ////分开部署,就不需要,一站多用时,取消注释
  1208. //if ($"{site}".Equals(BIConst.Global))
  1209. //{
  1210. // tableClient = _azureStorage.GetCloudTableClient(BIConst.Global);
  1211. // blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public", BIConst.Global);
  1212. //}
  1213. var table = tableClient.GetTableReference("BIDDUserInfo");
  1214. string appKey = _configuration["DingDingAuth:appKey"];
  1215. string appSecret = _configuration["DingDingAuth:appSecret"];
  1216. //string divide = _configuration["CustomParam:SiteScope"];
  1217. string divide = _option.Location;
  1218. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  1219. //获取access_token
  1220. IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  1221. OapiGettokenRequest request = new() { Appkey = appKey, Appsecret = appSecret };
  1222. request.SetHttpMethod("Get");
  1223. OapiGettokenResponse response = client.Execute(request);
  1224. if (response.IsError)
  1225. {
  1226. return BadRequest();
  1227. }
  1228. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  1229. string access_token = response.AccessToken;
  1230. IDingTalkClient quitStaffClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/querydimission");
  1231. OapiSmartworkHrmEmployeeQuerydimissionRequest reqDimission = new() { Offset = 0L, Size = 50L };
  1232. OapiSmartworkHrmEmployeeQuerydimissionResponse rspDimission = quitStaffClient.Execute(reqDimission, access_token);
  1233. if (rspDimission.Result != null)
  1234. {
  1235. List<DingDingUserInfo> ddUserInfos = new();
  1236. foreach (var itemId in rspDimission.Result.DataList)
  1237. {
  1238. await table.DeleteSingle<DingDingUserInfo>(divide, $"{itemId}");
  1239. }
  1240. //保存操作记录
  1241. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-del", $"{_tmdName}【{_tmdId}】从table数据表中删除离职员工", _dingDing, httpContext: HttpContext);
  1242. return Ok(new { state = 200 });
  1243. }
  1244. else
  1245. {
  1246. return Ok(new { state = rspDimission.SubErrCode });
  1247. }
  1248. }
  1249. catch (Exception ex)
  1250. {
  1251. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/del-ddquituser \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  1252. return BadRequest();
  1253. }
  1254. }
  1255. /// <summary>
  1256. /// 依据人员信息唯一编码修改人员信息表中的醍摩豆id信息相关的事情。
  1257. /// </summary>
  1258. /// <param name="jsonElement"></param>
  1259. /// <returns></returns>
  1260. [ProducesDefaultResponseType]
  1261. [AuthToken(Roles = "admin")]
  1262. [HttpPost("set-usettmdinfo")]
  1263. public async Task<IActionResult> UpUserTmdInfo(JsonElement jsonElement)
  1264. {
  1265. try
  1266. {
  1267. var (_tmdId, _tmdName, pic, did, dname, dpic) = HttpJwtAnalysis.JwtXAuthBI(HttpContext.GetXAuth("AuthToken"), _option);
  1268. if (!jsonElement.TryGetProperty("partitionKey", out JsonElement partKey)) return BadRequest();
  1269. if (!jsonElement.TryGetProperty("rowKey", out JsonElement rowKey)) return BadRequest();
  1270. if (!jsonElement.TryGetProperty("role", out JsonElement role)) return BadRequest();
  1271. var cosmosClient = _azureCosmos.GetCosmosClient();
  1272. var tableClient = _azureStorage.GetCloudTableClient();
  1273. var blobClient = _azureStorage.GetBlobContainerClient(containerName: "0-public");
  1274. var table = tableClient.GetTableReference("BIDDUserInfo");
  1275. StringBuilder msg = new($"{_tmdName}[{_tmdId}]将");
  1276. List<DingDingUserInfo> upUserInfos = new();
  1277. List<DDUserInfo> upUserInfo = new();
  1278. CoreUser coreUser = new();
  1279. string oldTmdId = null;
  1280. string reole = null;
  1281. var tempUser = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{partKey}" }, { "RowKey", $"{rowKey}" } });
  1282. if (tempUser.Count() > 0)
  1283. {
  1284. foreach (var item in tempUser)
  1285. {
  1286. oldTmdId = item.tmdId;
  1287. reole = item.roles;
  1288. coreUser = await _coreAPIHttpService.GetUserInfo(new Dictionary<string, string> { { "key", $"{item.mobile}" } }, _option.Location, _configuration);
  1289. if (!string.IsNullOrEmpty(coreUser.id))
  1290. {
  1291. item.tmdId = coreUser.id;
  1292. item.tmdName = coreUser.name;
  1293. item.tmdMobile = coreUser.mobile;
  1294. item.picture = coreUser.picture;
  1295. item.mail = coreUser.mail;
  1296. msg.Append($"{item.name}的{item.tmdId}账号改为新的{coreUser.id}账号;");
  1297. upUserInfos.Add(item);
  1298. }
  1299. else return Ok(new { state = 404, msg = "依据钉钉手机号未找到醍摩豆账号!" });
  1300. }
  1301. }
  1302. if (!string.IsNullOrEmpty(coreUser.id))
  1303. {
  1304. msg.Append("并将学校就的学校信息移植到新的账号,移植的学校:");
  1305. Teacher teacher = new();
  1306. var respone = await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReadItemStreamAsync(coreUser.id, new PartitionKey("Base"));
  1307. if (respone.StatusCode == HttpStatusCode.OK)
  1308. {
  1309. using var json = await JsonDocument.ParseAsync(respone.Content);
  1310. teacher = json.ToObject<Teacher>();
  1311. }
  1312. else
  1313. {
  1314. teacher = new Teacher()
  1315. {
  1316. id = coreUser.id,
  1317. code = "Base",
  1318. name = coreUser.name,
  1319. picture = coreUser.picture,
  1320. createTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds()
  1321. };
  1322. }
  1323. List<Task<ItemResponse<BIRelation>>> scRole = new();
  1324. await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIteratorSql<BIRelation>(queryText: $"select value(c) from c join a in c.assists join s in c.sales where c.code='BIRel' and s.id='{oldTmdId}' or a.id='{oldTmdId}'", requestOptions:new QueryRequestOptions() { PartitionKey = new PartitionKey("BIRel") }))
  1325. {
  1326. var tempAss = item.assists.Find(f => f.id.Equals($"{oldTmdId}"));
  1327. if (tempAss != null)
  1328. item.assists.Remove(tempAss);
  1329. var tempSa = item.sales.Find(f => f.id.Equals($"{oldTmdId}"));
  1330. if (tempSa != null)
  1331. item.sales.Remove(tempAss);
  1332. switch ($"{role}")
  1333. {
  1334. case "assist":
  1335. item.assists.Add(new IdInfo() { id = coreUser.id, name = coreUser.name, picture = coreUser.picture });
  1336. break;
  1337. case "sales":
  1338. item.sales.Add(new IdInfo() { id = coreUser.id, name = coreUser.name, picture = coreUser.picture });
  1339. break;
  1340. }
  1341. item.upDate = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
  1342. scRole.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<BIRelation>(item, item.id, new PartitionKey("BIRel")));
  1343. }
  1344. if (scRole.Count < 256)
  1345. await Task.WhenAll(scRole);
  1346. else
  1347. {
  1348. int pages = (scRole.Count + 255) / 256;
  1349. for (int i = 0; i < pages; i++)
  1350. {
  1351. List<Task<ItemResponse<BIRelation>>> tempScRole = scRole.Skip((i) * 256).Take(256).ToList();
  1352. await Task.WhenAll(tempScRole);
  1353. }
  1354. }
  1355. //List<Task<ItemResponse<SchoolTeacher>>> schoolTeachers = new();
  1356. //await foreach (var item in cosmosClient.GetContainer(Constant.TEAMModelOS, "School").GetItemQueryIteratorSql<SchoolTeacher>($"select value(c) from c where c.pk='Teacher' and c.id='{oldTmdId}'"))
  1357. //{
  1358. // item.id = coreUser.id;
  1359. // var resp = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync($"{coreUser.id}", new PartitionKey($"{item.code}"));
  1360. // if (resp.Status == 200)
  1361. // {
  1362. // using var json = await JsonDocument.ParseAsync(resp.Content);
  1363. // SchoolTeacher scTeacher = json.ToObject<SchoolTeacher>();
  1364. // if (scTeacher.roles.Contains("sales"))
  1365. // scTeacher.roles.Remove("sales");
  1366. // if (scTeacher.roles.Contains("assist"))
  1367. // scTeacher.roles.Remove("assist");
  1368. // string scId = scTeacher.code.Substring(scTeacher.code.IndexOf("-") + 1);
  1369. // Teacher.TeacherSchool isExitId = null;
  1370. // isExitId = teacher.schools.Find(s => s.schoolId.Equals(scId));
  1371. // if (isExitId == null)
  1372. // {
  1373. // ScEasyInfo school = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<ScEasyInfo>(scId, new PartitionKey("Base"));
  1374. // msg.Append($"{school.name}[{school.id}],");
  1375. // teacher.schools.Add(new Teacher.TeacherSchool() { schoolId = school.id, name = school.name, status = "join", time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), picture = school.picture, areaId = school.areaId });
  1376. // }
  1377. // scTeacher.roles.Add(reole);
  1378. // schoolTeachers.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReplaceItemAsync<SchoolTeacher>(scTeacher, scTeacher.id, new PartitionKey($"{scTeacher.code}")));
  1379. // }
  1380. // else
  1381. // {
  1382. // item.name = coreUser.name;
  1383. // string scId = item.code.Substring(item.code.IndexOf("-") + 1);
  1384. // Teacher.TeacherSchool isExitId = null;
  1385. // isExitId = teacher.schools.Find(s => s.schoolId.Equals(scId));
  1386. // if (isExitId == null)
  1387. // {
  1388. // ScEasyInfo school = await cosmosClient.GetContainer(Constant.TEAMModelOS, "School").ReadItemAsync<ScEasyInfo>(scId, new PartitionKey("Base"));
  1389. // msg.Append($"{school.name}[{school.id}],");
  1390. // teacher.schools.Add(new Teacher.TeacherSchool() { schoolId = school.id, name = school.name, status = "join", time = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(), picture = school.picture, areaId = school.areaId });
  1391. // }
  1392. // schoolTeachers.Add(cosmosClient.GetContainer(Constant.TEAMModelOS, "School").CreateItemAsync<SchoolTeacher>(item, new PartitionKey($"{item.code}")));
  1393. // }
  1394. //}
  1395. //if (schoolTeachers.Count < 256)
  1396. // await Task.WhenAll(schoolTeachers);
  1397. //else
  1398. //{
  1399. // int pages = (schoolTeachers.Count + 255) / 256;
  1400. // for (int i = 0; i < pages; i++)
  1401. // {
  1402. // List<Task<ItemResponse<SchoolTeacher>>> tempScTeachers = schoolTeachers.Skip((i) * 256).Take(256).ToList();
  1403. // await Task.WhenAll(tempScTeachers);
  1404. // }
  1405. //}
  1406. if (respone.StatusCode == HttpStatusCode.OK)
  1407. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").ReplaceItemAsync<Teacher>(teacher, teacher.id, new PartitionKey("Base"));
  1408. else
  1409. await cosmosClient.GetContainer(Constant.TEAMModelOS, "Teacher").CreateItemAsync<Teacher>(teacher, new PartitionKey("Base"));
  1410. upUserInfos = await table.SaveOrUpdateAll<DingDingUserInfo>(upUserInfos);
  1411. }
  1412. //保存操作记录
  1413. await AzureStorageBlobExtensions.SaveBILog(blobClient, tableClient, "tabledd-update-tmdinfo", msg.ToString(), _dingDing, httpContext: HttpContext);
  1414. foreach (var item in upUserInfos)
  1415. {
  1416. DDUserInfo tempUserInfo = new()
  1417. {
  1418. partitionKey = item.PartitionKey,
  1419. rowKey = item.RowKey,
  1420. userId = item.userId,
  1421. unionId = item.unionId,
  1422. name = item.name,
  1423. title = item.title,
  1424. stateCode = item.stateCode,
  1425. mobile = item.mobile,
  1426. jobNumber = item.jobNumber,
  1427. pid = item.pid,
  1428. deptId = item.deptId,
  1429. deptName = item.deptName,
  1430. depts = item.depts,
  1431. avatar = item.avatar,
  1432. isAdmin = item.isAdmin,
  1433. tmdId = item.tmdId,
  1434. tmdName = item.tmdName,
  1435. tmdMobile = item.tmdMobile,
  1436. mail = item.mail,
  1437. picture = item.picture,
  1438. roles = item.roles,
  1439. joinTime = item.joinTime,
  1440. isDisable = item.isDisable,
  1441. permissions = item.permissions,
  1442. handleRoles = !string.IsNullOrEmpty($"{item.roles}") ? new List<string>(item.roles.Split(",")) : new List<string>(),
  1443. handlePermissions = !string.IsNullOrEmpty($"{item.permissions}") ? new List<string>(item.permissions.Split(",")) : new List<string>(),
  1444. };
  1445. if (!string.IsNullOrEmpty(item.schoolIds))
  1446. {
  1447. List<string> tempSchoolIds = new(item.schoolIds.Split("|"));
  1448. tempUserInfo.handleSchools = await SchoolWay.GetSchoolInfos(cosmosClient, tempSchoolIds);
  1449. }
  1450. upUserInfo.Add(tempUserInfo);
  1451. }
  1452. return Ok(new { state = RespondCode.Ok, upUserInfo });
  1453. }
  1454. catch (Exception ex)
  1455. {
  1456. await _dingDing.SendBotMsg($"BI,{_option.Location} /tabledd/set-usettmdinfo \n {ex.Message}\n{ex.StackTrace}", GroupNames.成都开发測試群組);
  1457. return BadRequest();
  1458. }
  1459. }
  1460. /// <summary>
  1461. /// 获取钉钉用户信息
  1462. /// 并查询本地Table数据表中是否存在
  1463. /// </summary>
  1464. /// <param name="deptId"></param>
  1465. /// <param name="parentId"></param>
  1466. /// <param name="name"></param>
  1467. /// <param name="access_token"></param>
  1468. /// <returns></returns>
  1469. public async Task<List<DingDingUserInfo>> GetDingDingUserInfo(string partitionKey, long deptId, long parentId, string name, string access_token)
  1470. {
  1471. List<DingDingUserInfo> ddUserInfos = new();
  1472. //获取部门人员信息
  1473. IDingTalkClient userListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/list");
  1474. //long joinDate = DateTimeOffset.UtcNow.AddDays(-91).ToUnixTimeMilliseconds();
  1475. //获取部门用户
  1476. OapiV2UserListRequest reqUserList = new()
  1477. {
  1478. DeptId = deptId,
  1479. Cursor = 0L,
  1480. Size = 50L,
  1481. OrderField = "custom",
  1482. Language = "zh_CN"
  1483. };
  1484. reqUserList.SetHttpMethod("GET");
  1485. OapiV2UserListResponse rspV2UserList = userListClient.Execute(reqUserList, access_token);
  1486. if (rspV2UserList.Result.List != null)
  1487. {
  1488. foreach (var itemUser in rspV2UserList.Result.List)
  1489. {
  1490. //long isDisble = 0;
  1491. //if (!string.IsNullOrEmpty($"{itemUser.HiredDate}"))
  1492. //{
  1493. // if (itemUser.HiredDate < joinDate)
  1494. // isDisble = 1;
  1495. // else
  1496. // isDisble = 0;
  1497. //}
  1498. var tempInfo = ddUserInfos.Find(x => x.RowKey.Equals(itemUser.Unionid));
  1499. if (string.IsNullOrEmpty($"{tempInfo}"))
  1500. {
  1501. var table = _azureStorage.GetCloudTableClient().GetTableReference("BIDDUserInfo");
  1502. var users = await table.FindListByDict<DingDingUserInfo>(new Dictionary<string, object> { { "PartitionKey", $"{partitionKey}" }, { "userId", $"{itemUser.Userid}" }, { "unionId", $"{itemUser.Unionid}" } });
  1503. if (users.Count() > 0)
  1504. {
  1505. foreach (var user in users)
  1506. {
  1507. DingDingUserInfo ddUserInfo = new()
  1508. {
  1509. PartitionKey = user.PartitionKey,
  1510. RowKey = user.RowKey,
  1511. userId = itemUser.Userid,
  1512. unionId = itemUser.Unionid,
  1513. name = itemUser.Name,
  1514. email = itemUser.Email,
  1515. title = itemUser.Title,
  1516. stateCode = itemUser.StateCode,
  1517. mobile = itemUser.Mobile,
  1518. jobNumber = itemUser.JobNumber,
  1519. pid = parentId,
  1520. deptId = deptId,
  1521. deptName = name,
  1522. depts = string.Join(",", itemUser.DeptIdList.ToArray()),
  1523. avatar = itemUser.Avatar,
  1524. isAdmin = itemUser.Admin,
  1525. tmdId = user.tmdId,
  1526. tmdName = user.tmdName,
  1527. tmdMobile = user.tmdMobile,
  1528. mail = user.mail,
  1529. picture = user.picture,
  1530. roles = user.roles,
  1531. joinTime = user.joinTime,
  1532. permissions = user.permissions,
  1533. schoolIds = user.schoolIds,
  1534. isDisable = 1,
  1535. };
  1536. ddUserInfos.Add(ddUserInfo);
  1537. }
  1538. }
  1539. else
  1540. {
  1541. DingDingUserInfo ddUserInfo = new()
  1542. {
  1543. RowKey = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds().ToString(),
  1544. userId = itemUser.Userid,
  1545. unionId = itemUser.Unionid,
  1546. name = itemUser.Name,
  1547. email = itemUser.Email,
  1548. title = itemUser.Title,
  1549. stateCode = itemUser.StateCode,
  1550. mobile = itemUser.Mobile,
  1551. jobNumber = itemUser.JobNumber,
  1552. pid = parentId,
  1553. deptId = deptId,
  1554. deptName = name,
  1555. depts = string.Join(",", itemUser.DeptIdList.ToArray()),
  1556. avatar = itemUser.Avatar,
  1557. isAdmin = itemUser.Admin,
  1558. PartitionKey = partitionKey,
  1559. tmdId = "",
  1560. tmdName = "",
  1561. tmdMobile = "",
  1562. mail = "",
  1563. picture = "",
  1564. roles = "",
  1565. joinTime = 0,
  1566. permissions = "areadata-read,areadata-upd,schooldata-read,schooldata-upd",
  1567. schoolIds = "",
  1568. isDisable = 0,
  1569. };
  1570. ddUserInfos.Add(ddUserInfo);
  1571. }
  1572. }
  1573. }
  1574. }
  1575. return ddUserInfos;
  1576. }
  1577. public record DDUserInfo
  1578. {
  1579. public string partitionKey { get; set; }
  1580. public string rowKey { get; set; }
  1581. public string userId { get; set; }
  1582. public string unionId { get; set; }
  1583. public string name { get; set; }
  1584. public string title { get; set; }
  1585. public string stateCode { get; set; }
  1586. public string mobile { get; set; }
  1587. public string jobNumber { get; set; }
  1588. public long pid { get; set; }
  1589. public long deptId { get; set; }
  1590. public string deptName { get; set; }
  1591. public string depts { get; set; }
  1592. public string avatar { get; set; }
  1593. public bool isAdmin { get; set; }
  1594. public string tmdId { get; set; }
  1595. public string tmdName { get; set; }
  1596. public string tmdMobile { get; set; }
  1597. public string mail { get; set; }
  1598. public string picture { get; set; }
  1599. public string roles { get; set; }
  1600. public long joinTime { get; set; }
  1601. public long isDisable { get; set; }
  1602. public string permissions { get; set; }
  1603. public List<string> handleRoles { get; set; }
  1604. public List<string> handlePermissions { get; set; }
  1605. public List<BaseInfo> handleSchools { get; set; } = new List<BaseInfo>();
  1606. }
  1607. }
  1608. }