DDStructController.cs 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. using DingTalk.Api;
  2. using DingTalk.Api.Request;
  3. using DingTalk.Api.Response;
  4. using Microsoft.AspNetCore.Http;
  5. using Microsoft.AspNetCore.Mvc;
  6. using Microsoft.Extensions.Configuration;
  7. using Microsoft.Extensions.Options;
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Text.Json;
  12. using System.Threading.Tasks;
  13. using TEAMModelOS.Models;
  14. using TEAMModelOS.SDK.DI;
  15. using TEAMModelOS.SDK.Extension;
  16. using TEAMModelOS.SDK.Models.Service;
  17. using static DingTalk.Api.Response.OapiV2UserGetResponse;
  18. using Azure.Cosmos;
  19. using TEAMModelOS.SDK.Models;
  20. using TEAMModeBI.Controllers.BISchool;
  21. namespace TEAMModeBI.Controllers.DingDingStruc
  22. {
  23. [ProducesResponseType(StatusCodes.Status200OK)]
  24. [ProducesResponseType(StatusCodes.Status400BadRequest)]
  25. [Route("dd")]
  26. [ApiController]
  27. public class DDStructController : ControllerBase
  28. {
  29. private readonly IConfiguration _configuration;
  30. //数据容器
  31. private readonly AzureCosmosFactory _azureCosmos;
  32. //文件容器
  33. private readonly AzureStorageFactory _azureStorage;
  34. //钉钉提示信息
  35. private readonly DingDing _dingDing;
  36. private readonly Option _option;
  37. string type = "ddteammodel";
  38. public DDStructController(IConfiguration configuration, AzureCosmosFactory azureCosmos, AzureStorageFactory azureStorage, DingDing dingDing, IOptionsSnapshot<Option> option, CoreAPIHttpService aoreAPIHttpService)
  39. {
  40. _configuration = configuration;
  41. _azureCosmos = azureCosmos;
  42. _azureStorage = azureStorage;
  43. _dingDing = dingDing;
  44. _option = option?.Value;
  45. }
  46. /// <summary>
  47. /// 获取组织架构列表
  48. /// </summary>
  49. /// <returns></returns>
  50. [ProducesDefaultResponseType]
  51. [HttpPost("ddminstruc")]
  52. public async Task<IActionResult> DDMainStruc()
  53. {
  54. string str_appKey = _configuration["DingDingAuth:appKey"];
  55. string str_appSecret = _configuration["DingDingAuth:appSecret"];
  56. //获取企业内部应用的accessToken
  57. IDingTalkClient Iclient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  58. OapiGettokenRequest request = new OapiGettokenRequest();
  59. request.Appkey = str_appKey;
  60. request.Appsecret = str_appSecret;
  61. request.SetHttpMethod("GET");
  62. OapiGettokenResponse tokenResponse = Iclient.Execute(request);
  63. if (tokenResponse.IsError)
  64. {
  65. return Ok(new { status = 0, message = "请检查配置" });
  66. }
  67. string access_token1 = tokenResponse.AccessToken;
  68. IDingTalkClient dingTalkClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/org/union/trunk/get");
  69. OapiOrgUnionTrunkGetRequest oapiOrgUnionTrunkGetRequest = new OapiOrgUnionTrunkGetRequest();
  70. OapiOrgUnionTrunkGetResponse oapiOrgUnionTrunkGetResponse = dingTalkClient.Execute(oapiOrgUnionTrunkGetRequest, tokenResponse.AccessToken);
  71. return Ok(new { oapiOrgUnionTrunkGetResponse.RequestId , oapiOrgUnionTrunkGetResponse.Body, oapiOrgUnionTrunkGetResponse.Result });
  72. }
  73. /// <summary>
  74. /// 获取分支组织列表信息
  75. /// </summary>
  76. /// <returns></returns>
  77. [ProducesDefaultResponseType]
  78. [HttpPost("ddbranchstruc")]
  79. public async Task<IActionResult> DDBranchStruc()
  80. {
  81. string str_appKey = _configuration["DingDingAuth:appKey"];
  82. string str_appSecret = _configuration["DingDingAuth:appSecret"];
  83. //获取企业内部应用的accessToken
  84. IDingTalkClient Iclient = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  85. OapiGettokenRequest request = new OapiGettokenRequest();
  86. request.Appkey = str_appKey;
  87. request.Appsecret = str_appSecret;
  88. request.SetHttpMethod("GET");
  89. OapiGettokenResponse tokenResponse = Iclient.Execute(request);
  90. if (tokenResponse.IsError)
  91. {
  92. return Ok(new { status = 0, message = "请检查配置" });
  93. }
  94. IDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/org/union/branch/get");
  95. OapiOrgUnionBranchGetRequest req = new OapiOrgUnionBranchGetRequest();
  96. OapiOrgUnionBranchGetResponse rsp = client.Execute(req, tokenResponse.AccessToken);
  97. return Ok(new { Result = rsp.Result, Body = rsp.Body, RequestId = rsp.RequestId, SubErrCode = rsp.SubErrCode, Success = rsp.Success });
  98. }
  99. /// <summary>
  100. /// 获取企业部门列表
  101. /// </summary>
  102. [ProducesDefaultResponseType]
  103. [HttpPost("get-deptlist")]
  104. public async Task<IActionResult> GetDeptList()
  105. {
  106. try
  107. {
  108. string appKey = _configuration["DingDingAuth:appKey"];
  109. string appSecret = _configuration["DingDingAuth:appSecret"];
  110. //获取access_token
  111. DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  112. OapiGettokenRequest request = new OapiGettokenRequest();
  113. request.Appkey = appKey;
  114. request.Appsecret = appSecret;
  115. request.SetHttpMethod("Get");
  116. OapiGettokenResponse response = client.Execute(request);
  117. if (response.IsError)
  118. {
  119. return BadRequest();
  120. }
  121. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  122. string access_token = response.AccessToken;
  123. //获取一级部门列表
  124. IDingTalkClient v2ListsubClient1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
  125. OapiV2DepartmentListsubRequest reqlistsub1 = new OapiV2DepartmentListsubRequest() { DeptId = 1L, Language = "zh_CN" };
  126. OapiV2DepartmentListsubResponse rsplistsub1 = v2ListsubClient1.Execute(reqlistsub1, access_token);
  127. List<DeptInfo> templsit = new List<DeptInfo>();
  128. if (rsplistsub1.Result != null)
  129. {
  130. foreach (var deptList in rsplistsub1.Result)
  131. {
  132. DeptInfo deptInfo = new DeptInfo();
  133. deptInfo.deptId = deptList.DeptId;
  134. deptInfo.deptName = deptList.Name;
  135. deptInfo.parentId = deptList.ParentId;
  136. //获取一级部门用户列表
  137. IDingTalkClient userListClient1 = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
  138. OapiUserListidRequest reqUserList1 = new OapiUserListidRequest() { DeptId = deptList.DeptId };
  139. OapiUserListidResponse rspUserList1 = userListClient1.Execute(reqUserList1, access_token);
  140. if (rspUserList1.Result != null)
  141. {
  142. deptInfo.ddUserList = rspUserList1.Result.UseridList;
  143. }
  144. //获取用户详细信息
  145. IDingTalkClient v2UserListClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
  146. OapiV2UserGetRequest reqv2UserList = new OapiV2UserGetRequest();
  147. OapiV2UserGetResponse rspv2UserList = v2UserListClient.Execute(reqv2UserList, access_token);
  148. //获取二级部门列表
  149. OapiV2DepartmentListsubRequest reqlistsub = new OapiV2DepartmentListsubRequest() { DeptId = deptList.DeptId, Language = "zh_CN" };
  150. OapiV2DepartmentListsubResponse rsplistsub = v2ListsubClient1.Execute(reqlistsub, access_token);
  151. List<DeptBaseResponseDomain> deptBaseResponseDomainList = new List<DeptBaseResponseDomain>();
  152. if (rsplistsub.Result != null)
  153. {
  154. foreach (var deptlist2 in rsplistsub.Result)
  155. {
  156. //添加二级部门
  157. DeptBaseResponseDomain deptBaseResponseDomain2 = new DeptBaseResponseDomain();
  158. deptBaseResponseDomain2.deptId = deptlist2.DeptId;
  159. deptBaseResponseDomain2.Name = deptlist2.Name;
  160. deptBaseResponseDomain2.ParentId = deptlist2.ParentId;
  161. //获取三级部门用户列表
  162. OapiUserListidRequest reqUserList2 = new OapiUserListidRequest() { DeptId = deptlist2.DeptId };
  163. OapiUserListidResponse rspUserList2 = userListClient1.Execute(reqUserList2, access_token);
  164. if (rspUserList2.Result != null)
  165. {
  166. //添加三级部门用户
  167. deptBaseResponseDomain2.ddUserList = rspUserList2.Result.UseridList;
  168. }
  169. //获取三级部门列表
  170. OapiV2DepartmentListsubRequest reqlistsub3 = new OapiV2DepartmentListsubRequest() { DeptId = deptlist2.DeptId, Language = "zh_CN" };
  171. OapiV2DepartmentListsubResponse rsplistsub3 = v2ListsubClient1.Execute(reqlistsub3, access_token);
  172. List<DeptBaseResponseDomain> deptBaseResponseDomain3List = new List<DeptBaseResponseDomain>();
  173. if (rsplistsub3.Result != null)
  174. {
  175. foreach (var dept3List in rsplistsub3.Result)
  176. {
  177. //添加三级部门
  178. DeptBaseResponseDomain deptBaseResponseDomain3 = new DeptBaseResponseDomain();
  179. deptBaseResponseDomain3.deptId = dept3List.DeptId;
  180. deptBaseResponseDomain3.Name = dept3List.Name;
  181. deptBaseResponseDomain3.ParentId = dept3List.ParentId;
  182. //获取部门用户列表
  183. OapiUserListidRequest reqUserList3 = new OapiUserListidRequest() { DeptId = dept3List.DeptId };
  184. OapiUserListidResponse rspUserList3 = userListClient1.Execute(reqUserList3, access_token);
  185. if (rspUserList3.Result != null)
  186. {
  187. //添加三级部门的用户
  188. deptBaseResponseDomain3.ddUserList = rspUserList3.Result.UseridList;
  189. }
  190. //获取部门列表 四级目录
  191. OapiV2DepartmentListsubRequest reqlistsub4 = new OapiV2DepartmentListsubRequest() { DeptId = dept3List.DeptId, Language = "zh_CN" };
  192. OapiV2DepartmentListsubResponse rsplistsu4 = v2ListsubClient1.Execute(reqlistsub4, access_token);
  193. List<DeptBaseResponseDomain> deptBaseResponseDomain4List = new List<DeptBaseResponseDomain>();
  194. if (rsplistsu4.Result != null)
  195. {
  196. foreach (var dept4List in rsplistsu4.Result)
  197. {
  198. DeptBaseResponseDomain deptBaseResponseDomain4 = new DeptBaseResponseDomain();
  199. deptBaseResponseDomain4.deptId = dept4List.DeptId;
  200. deptBaseResponseDomain4.Name = dept4List.Name;
  201. deptBaseResponseDomain4.ParentId = dept4List.ParentId;
  202. deptBaseResponseDomain4List.Add(deptBaseResponseDomain4);
  203. //获取四级部门用户列表
  204. OapiUserListidRequest reqUserList4 = new OapiUserListidRequest() { DeptId = dept4List.DeptId };
  205. OapiUserListidResponse rspUserList4 = userListClient1.Execute(reqUserList4, access_token);
  206. if (rspUserList4.Result != null)
  207. {
  208. //添加四级部门的用户
  209. deptBaseResponseDomain4.ddUserList = rspUserList4.Result.UseridList;
  210. }
  211. }
  212. }
  213. //添加四级部门列表
  214. deptBaseResponseDomain3.LowerDeip_List = deptBaseResponseDomain4List;
  215. deptBaseResponseDomain3List.Add(deptBaseResponseDomain3);
  216. }
  217. }
  218. //添加三级部门列表
  219. deptBaseResponseDomain2.LowerDeip_List = deptBaseResponseDomain3List;
  220. deptBaseResponseDomainList.Add(deptBaseResponseDomain2);
  221. }
  222. }
  223. //添加二级部门列表
  224. deptInfo.deptList = deptBaseResponseDomainList;
  225. templsit.Add(deptInfo);
  226. }
  227. }
  228. return Ok(new { state = 200, deptlist = templsit });
  229. }
  230. catch (Exception ex)
  231. {
  232. return Ok(new { state = 1, message=$"查询失败!:状态:{ex.StackTrace}错误:{ex.Message}" }) ;
  233. }
  234. }
  235. /// <summary>
  236. /// 获取当前用户的父级集合
  237. /// </summary>
  238. /// <param name="jsonElement"></param>
  239. /// <returns></returns>
  240. [ProducesDefaultResponseType]
  241. [HttpPost("get-parentdept")]
  242. public async Task<IActionResult> GetParentDept(JsonElement jsonElement)
  243. {
  244. try
  245. {
  246. if (!jsonElement.TryGetProperty("userId", out JsonElement userId)) return Ok(new { state = 1, message = "参数错误!" });
  247. string appKey = _configuration["DingDingAuth:appKey"];
  248. string appSecret = _configuration["DingDingAuth:appSecret"];
  249. //获取access_token
  250. DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  251. OapiGettokenRequest request = new OapiGettokenRequest();
  252. request.Appkey = appKey;
  253. request.Appsecret = appSecret;
  254. request.SetHttpMethod("Get");
  255. OapiGettokenResponse response = client.Execute(request);
  256. if (response.IsError)
  257. {
  258. return BadRequest();
  259. }
  260. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  261. string access_token = response.AccessToken;
  262. IDingTalkClient v2DeartDeptClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listparentbyuser");
  263. OapiV2DepartmentListparentbyuserRequest reqDeartDept = new OapiV2DepartmentListparentbyuserRequest() { Userid = userId.ToString() };
  264. OapiV2DepartmentListparentbyuserResponse rspDeartDept = v2DeartDeptClient.Execute(reqDeartDept, access_token);
  265. if (rspDeartDept.Result != null)
  266. {
  267. List<long> userParentDept = new List<long>();
  268. //var parentDept = rspDeartDept.Result.ParentList;
  269. foreach (var temp in rspDeartDept.Result.ParentList)
  270. {
  271. foreach (var deptTemp in temp.ParentDeptIdList)
  272. {
  273. userParentDept.Add(deptTemp);
  274. }
  275. }
  276. return Ok(new { state = 200, parentList = userParentDept });
  277. }
  278. return Ok(new { state = 2, message = "访问失败!" });
  279. }
  280. catch (Exception ex)
  281. {
  282. return Ok(new { state = 2, message = $"访问失败!状态:{ex.StackTrace} 错误:{ex.Message}" });
  283. }
  284. }
  285. /// <summary>
  286. /// 依据钉钉UserID查询钉钉用户信息
  287. /// </summary>
  288. /// <param name="jsonElement"></param>
  289. /// <returns></returns>
  290. [ProducesDefaultResponseType]
  291. [HttpPost("get-dduserinfo")]
  292. public async Task<IActionResult> GetDDUserInfo(JsonElement jsonElement)
  293. {
  294. try
  295. {
  296. if (!jsonElement.TryGetProperty("userids", out JsonElement userIds)) return Ok(new { state = 1, message = "参数问题" });
  297. List<DDUserInfoAndTMD> dDUserInfoAndTMDs = new List<DDUserInfoAndTMD>();//返回钉钉信息和查询的醍摩豆信息
  298. string appKey = _configuration["DingDingAuth:appKey"];
  299. string appSecret = _configuration["DingDingAuth:appSecret"];
  300. //获取access_token
  301. DefaultDingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/gettoken");
  302. OapiGettokenRequest request = new OapiGettokenRequest();
  303. request.Appkey = appKey;
  304. request.Appsecret = appSecret;
  305. request.SetHttpMethod("Get");
  306. OapiGettokenResponse response = client.Execute(request);
  307. if (response.IsError)
  308. {
  309. return BadRequest();
  310. }
  311. //access_token的有效期为7200秒(2小时),有效期内重复获取会返回相同结果并自动续期,过期后获取会返回新的access_token
  312. string access_token = response.AccessToken;
  313. IDingTalkClient userInfoClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
  314. Dictionary<string, object> dic = new Dictionary<string, object> { { "PartitionKey", "authority-bi" } };
  315. List<Authority> authorityBIList = await _azureStorage.FindListByDict<Authority>(dic);
  316. if (!string.IsNullOrEmpty($"{userIds}"))
  317. {
  318. //List<string> str_userids = userIds.ToObject<List<string>>().Distinct().ToList();//通过数组的Equals实现去重
  319. List<string> str_userids1 = userIds.ToObject<List<string>>();
  320. List<string> str_userids = str_userids1.Where((x, i) => str_userids1.FindIndex(z => z == x) == i).ToList();//Lambda表达式去重
  321. foreach (var tempid in str_userids)
  322. {
  323. OapiV2UserGetRequest reqUserInfo = new OapiV2UserGetRequest() { Userid = $"{tempid}", Language = "zh_CN" };
  324. OapiV2UserGetResponse rspUserInfo = userInfoClient.Execute(reqUserInfo, access_token);
  325. if (rspUserInfo.Result != null)
  326. {
  327. List<string> roles = new List<string>();//角色列表
  328. List<string> power = new List<string>();//权限列表
  329. DDUserInfoAndTMD dDUserInfoAndTMD = new DDUserInfoAndTMD();
  330. dDUserInfoAndTMD.Unionid = rspUserInfo.Result.Unionid;
  331. dDUserInfoAndTMD.title = rspUserInfo.Result.Title;
  332. dDUserInfoAndTMD.Userid = rspUserInfo.Result.Userid;
  333. dDUserInfoAndTMD.jobNumber = rspUserInfo.Result.JobNumber;
  334. dDUserInfoAndTMD.name = rspUserInfo.Result.Name;
  335. dDUserInfoAndTMD.deptIdList = rspUserInfo.Result.DeptIdList;
  336. string sqltxt = $"select distinct value(c) from c join A1 in c.ddbinds where A1.userid ='{tempid}'";
  337. try
  338. {
  339. await foreach (var item in _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "Teacher").GetItemQueryIterator<Teacher>(queryText: sqltxt, requestOptions: new QueryRequestOptions() { PartitionKey = new PartitionKey("Base") }))
  340. {
  341. dDUserInfoAndTMD.tmdid = item.id;
  342. dDUserInfoAndTMD.isexist = true;
  343. if (!string.IsNullOrEmpty($"{item.defaultSchool}"))
  344. {
  345. var schoolRoles = await _azureCosmos.GetCosmosClient().GetContainer(Constant.TEAMModelOS, "School").ReadItemStreamAsync(item.id, new PartitionKey($"Teacher-{item.defaultSchool}"));
  346. if (schoolRoles.Status == 200)
  347. {
  348. using var json = await JsonDocument.ParseAsync(schoolRoles.ContentStream);
  349. if (json.RootElement.TryGetProperty("roles", out JsonElement _roles) && _roles.ValueKind != JsonValueKind.Null)
  350. {
  351. foreach (var obj in _roles.EnumerateArray())
  352. {
  353. //初始定义顾问的assistant 更改为assist
  354. if (obj.GetString().Equals($"assist"))
  355. {
  356. roles.Add(obj.GetString());
  357. }
  358. }
  359. }
  360. if (json.RootElement.TryGetProperty("permissions", out JsonElement _permissions) && _permissions.ValueKind != JsonValueKind.Null)
  361. {
  362. foreach (var obj in _permissions.EnumerateArray())
  363. {
  364. foreach (var aut in authorityBIList)
  365. {
  366. if (aut.RowKey.Equals(obj.GetString()))
  367. {
  368. power.Add(obj.GetString());
  369. }
  370. }
  371. }
  372. }
  373. }
  374. dDUserInfoAndTMD.tmdroles = roles;
  375. dDUserInfoAndTMD.tmdpower = power;
  376. }
  377. }
  378. }
  379. catch { }
  380. dDUserInfoAndTMDs.Add(dDUserInfoAndTMD);
  381. }
  382. else return Ok(new { state = 2, message = "访问失败!" });
  383. }
  384. }
  385. return Ok(new { state = 200, ddUserInfos = dDUserInfoAndTMDs});
  386. }
  387. catch (Exception ex)
  388. {
  389. await _dingDing.SendBotMsg($"BI,{_option.Location},dd/get-dduserinfo \n{ex.Message}{ex.StackTrace}", GroupNames.醍摩豆服務運維群組);
  390. return BadRequest();
  391. }
  392. }
  393. /// <summary>
  394. /// 返回钉钉和能查询到醍摩豆信息
  395. /// </summary>
  396. public class DDUserInfoAndTMD
  397. {
  398. /// <summary>
  399. /// 是否存在醍摩豆账户
  400. /// </summary>
  401. public bool isexist { get; set; }
  402. /// <summary>
  403. /// 绑定的醍摩豆账户
  404. /// </summary>
  405. public string tmdid { get; set; }
  406. /// <summary>
  407. /// 醍摩豆角色
  408. /// </summary>
  409. public List<string> tmdroles { get; set; }
  410. /// <summary>
  411. /// 醍摩豆角色权限
  412. /// </summary>
  413. public List<string> tmdpower { get; set; }
  414. /// <summary>
  415. /// 所属部门id列表
  416. /// </summary>
  417. public List<long> deptIdList { get; set; }
  418. /// <summary>
  419. /// 员工工号
  420. /// </summary>
  421. public string jobNumber { get; set; }
  422. /// <summary>
  423. /// 员工名称
  424. /// </summary>
  425. public string name { get; set; }
  426. /// <summary>
  427. /// 职位
  428. /// </summary>
  429. public string title { get; set; }
  430. /// <summary>
  431. /// 员工在当前开发者企业账号范围内的唯一标识
  432. /// </summary>
  433. public string Unionid { get; set; }
  434. /// <summary>
  435. /// 用户ID
  436. /// </summary>
  437. public string Userid { get; set; }
  438. }
  439. public record DeptInfo
  440. {
  441. /// <summary>
  442. /// 部门ID
  443. /// </summary>
  444. public long deptId { get; set; }
  445. /// <summary>
  446. /// 部门名称
  447. /// </summary>
  448. public string deptName { get; set; }
  449. /// <summary>
  450. /// 父部门id,根部门为1
  451. /// </summary>
  452. public long parentId { get; set; }
  453. /// <summary>
  454. /// 部门集合
  455. /// </summary>
  456. public List<DeptBaseResponseDomain> deptList { get; set; }
  457. /// <summary>
  458. /// 钉钉用户列表
  459. /// </summary>
  460. public List<string> ddUserList { get; set; }
  461. }
  462. public record DeptBaseResponseDomain
  463. {
  464. /// <summary>
  465. /// 部门ID
  466. /// </summary>
  467. public long deptId { get; set; }
  468. /// <summary>
  469. /// 部门名称
  470. /// </summary>
  471. public string Name { get; set; }
  472. /// <summary>
  473. /// 父部门ID
  474. /// </summary>
  475. public long ParentId { get; set; }
  476. /// <summary>
  477. /// 下级列表
  478. /// </summary>
  479. public List<DeptBaseResponseDomain> LowerDeip_List { get; set; }
  480. /// <summary>
  481. /// 钉钉用户列表
  482. /// </summary>
  483. public List<string> ddUserList { get; set; }
  484. }
  485. }
  486. }