Эх сурвалжийг харах

!1616 封装常用的钉钉服务端API
Merge pull request !1616 from johnec/next

zuohuaijun 1 жил өмнө
parent
commit
4c82384c5a
73 өөрчлөгдсөн 4782 нэмэгдсэн , 12 устгасан
  1. 3 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/Admin.NET.Plugin.DingTalk.csproj
  2. 54 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/AliTripRequest.cs
  3. 68 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripAddressRequest.cs
  4. 21 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripAddressResponse.cs
  5. 100 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripFlightOrdersRequest.cs
  6. 477 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripFlightOrdersResponse.cs
  7. 100 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripTrainOrdersRequest.cs
  8. 297 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripTrainOrdersResponse.cs
  9. 22 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/IAliTripRequestProxy.cs
  10. 159 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/AttendanceRequest.cs
  11. 106 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/AttdendanceApprovalsFinishRequest.cs
  12. 41 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/AttendanceApprovalsFinishResponse.cs
  13. 28 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/AttendanceApprovelsCancelRequest.cs
  14. 15 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/AttendanceApprovelsCancelResponse.cs
  15. 27 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/Enums.cs
  16. 46 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/GetLeaveStatusRequest.cs
  17. 73 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/GetLeaveStatusResponse.cs
  18. 40 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/ListRecordRequest.cs
  19. 210 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/ListRecordResponse.cs
  20. 27 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/IAttendanceRequestProxy.cs
  21. 21 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseError.cs
  22. 18 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseErrorRequestId.cs
  23. 17 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseErrorResult.cs
  24. 19 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseErrorResultRequestid.cs
  25. 16 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseErrorSuccess.cs
  26. 31 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseHasMoreList.cs
  27. 18 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseRequestId.cs
  28. 16 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseSuccess.cs
  29. 16 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseSuccessResult.cs
  30. 61 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/CheckinRequest.cs
  31. 52 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/DTO/GetDeptRecordRequest.cs
  32. 72 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/DTO/GetDeptRecordResponse.cs
  33. 47 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/DTO/GetUserRecordRequest.cs
  34. 88 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/DTO/GetUserRecordResponse.cs
  35. 23 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/ICheckinRequestProxy.cs
  36. 26 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/GetDeptInfoRequest.cs
  37. 152 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/GetDeptInfoResponse.cs
  38. 19 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/ListSubIdRequest.cs
  39. 25 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/ListSubIdResponse.cs
  40. 26 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/ListSubRequest.cs
  41. 51 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/ListSubResponse.cs
  42. 71 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DepartmentRequest.cs
  43. 19 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/IDepartmentRequestProxy.cs
  44. 29 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/DTO/EmployeeQueryonjobRequest.cs
  45. 38 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/DTO/EmployeeQueryonjobResponse.cs
  46. 32 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/DTO/RosterListsQueryRequest.cs
  47. 81 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/DTO/RosterListsQueryResponse.cs
  48. 63 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/HrmRequest.cs
  49. 19 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/IHrmRequestProxy.cs
  50. 463 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Message/DTO/SendCorpConversationRequest.cs
  51. 21 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Message/DTO/SendCorpConversationResponse.cs
  52. 15 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Message/IMessageRequestProxy.cs
  53. 75 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Message/MessageRequest.cs
  54. 26 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/DTO/GetAccessTokenRequest.cs
  55. 22 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/DTO/GetAccessTokenResponse.cs
  56. 23 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/DTO/GetApiTicketResponse.cs
  57. 19 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/DTO/GetUserInfoRequest.cs
  58. 60 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/DTO/GetUserInfoResponse.cs
  59. 21 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/ITopRequestProxy.cs
  60. 63 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/TopRequest.cs
  61. 25 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/RoleListRequest.cs
  62. 59 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/RoleListResponse.cs
  63. 26 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserDetailRequest.cs
  64. 286 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserDetailResponse.cs
  65. 19 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListIdRequest.cs
  66. 25 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListIdResponse.cs
  67. 59 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListRequest.cs
  68. 151 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListResponse.cs
  69. 59 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListSimpleRequest.cs
  70. 28 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListSimpleResponse.cs
  71. 26 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/IUserRequestProxy.cs
  72. 110 0
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/UserRequest.cs
  73. 21 12
      Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/Service/DingTalkService.cs

+ 3 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/Admin.NET.Plugin.DingTalk.csproj

@@ -19,5 +19,8 @@
   <ItemGroup>
     <ProjectReference Include="..\..\Admin.NET.Core\Admin.NET.Core.csproj" />
   </ItemGroup>
+	<ItemGroup>
+		<Folder Include="..\RequestProxy" />
+	</ItemGroup>
 
 </Project>

+ 54 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/AliTripRequest.cs

@@ -0,0 +1,54 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip.DTO;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip;
+public class AliTripRequest
+{
+    private IAliTripRequestProxy request;
+
+    public AliTripRequest(IAliTripRequestProxy request)
+    {
+        this.request = request;
+    }
+
+    /// <summary>
+    /// 获取阿里商旅访问地址
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="req"></param>
+    /// <returns></returns>
+    public async Task<GetAlitripAddressResponse> GetAlitripAddress(string AccessToken, OpenApiJumpInfoRq req)
+    {
+        var resStr = await request.GetAlitripAddress(AccessToken, new GetAlitripAddressRequest
+        {
+            Request = req
+        });
+        var res = resStr.ToObject<GetAlitripAddressResponse>();
+        return res;
+    }
+
+    /// <summary>
+    /// 获取企业机票订单数据
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="rq"></param>
+    /// <returns></returns>
+    public async Task<GetAlitripFlightOrdersResponse> GetAlitripFlightOrders(string AccessToken, GetAlitripFlightOrdersRequest rq)
+    {
+        var resStr = await request.GetAlitripFlightOrders(AccessToken, rq);
+        var res = resStr.ToObject<GetAlitripFlightOrdersResponse>();
+        return res;
+    }
+
+    public async Task<GetAlitripTrainOrdersResponse> GetAlitripTrainOrders(string AccessToken, GetAlitripTrainOrdersRequest rq)
+    {
+        var resStr = await request.GetAlitripTrainOrders(AccessToken, rq);
+        var res = resStr.ToObject<GetAlitripTrainOrdersResponse>();
+        return res;
+    }
+}

+ 68 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripAddressRequest.cs

@@ -0,0 +1,68 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip.DTO;
+
+public class GetAlitripAddressRequest
+{
+    [JsonProperty("request")]
+    [JsonPropertyName("request")]
+    public OpenApiJumpInfoRq Request { get; set; }
+}
+
+public class OpenApiJumpInfoRq
+{
+    /// <summary>
+    /// 用户id
+    /// </summary>
+    [JsonProperty("userid")]
+    [JsonPropertyName("userid")]
+    public string? UserId { get; set; }
+
+    [JsonProperty("corpid")]
+    [JsonPropertyName("corpid")]
+    public string CorpId { get; set; }
+
+    /// <summary>
+    /// 类目类型:1:机票,2:火车票,3:酒店,4:用车
+    /// </summary>
+
+    [JsonProperty("type")]
+    [JsonPropertyName("type")]
+    public TypeEnum Type { get; set; }
+    public enum TypeEnum
+    {
+        机票 = 1, 火车票, 酒店, 用车
+    }
+
+    /// <summary>
+    /// 操作类型:1:预订,2:我的订单列表,3:商旅管理后台,如果需要获取该场景的地址,只需提供corpid,userid,4:商旅h5主页
+    /// </summary>
+    [JsonProperty("action_type")]
+    [JsonPropertyName("action_type")]
+    public ActionTypeEnum ActionType { get; set; }
+    public enum ActionTypeEnum
+    {
+        预订 = 1, 我的订单列表, 商旅管理后台, 商旅h5主页
+    }
+
+    /// <summary>
+    /// 第三方行程ID。存在代表通过审批单预订,不存在代表特殊场景:普通员工是预览,特殊授权人和代订人是免审批预订场景。
+    /// </summary>
+    [JsonProperty("itinerary_id")]
+    [JsonPropertyName("itinerary_id")]
+    public string ItineraryId { get; set; }
+
+    /// <summary>
+    /// 员工第一次使用用车需要手机号,与司机联系。
+    /// </summary>
+    [JsonProperty("phone")]
+    [JsonPropertyName("phone")]
+    public string Phone { get; set; }
+}
+

+ 21 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripAddressResponse.cs

@@ -0,0 +1,21 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip.DTO;
+public class GetAlitripAddressResponse : DingtalkResponseErrorResult<OpenApiJumpInfoRs>
+{
+}
+
+public class OpenApiJumpInfoRs
+{
+    [JsonProperty("url")]
+    [JsonPropertyName("url")]
+    public string Url { get; set; }
+}

+ 100 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripFlightOrdersRequest.cs

@@ -0,0 +1,100 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip.DTO;
+public class GetAlitripFlightOrdersRequest
+{
+    public GetAlitripFlightOrdersRequestDomain rq;
+}
+
+public class GetAlitripFlightOrdersRequestDomain
+{
+    /// <summary>
+    /// 开始时间 2017-05-01 00:00:00
+    /// </summary>
+    [JsonProperty("start_time")]
+    [JsonPropertyName("start_time")]
+    public string? StartTime { get; set; }
+
+    /// <summary>
+    /// 商旅申请单id
+    /// </summary>
+    [JsonProperty("apply_id")]
+    [JsonPropertyName("apply_id")]
+    public string? ApplyId { get; set; }
+
+    /// <summary>
+    /// 页数,从1开始
+    /// </summary>
+    [JsonProperty("page")]
+    [JsonPropertyName("page")]
+    public int? Page { get; set; }
+
+    /// <summary>
+    /// 用户id
+    /// </summary>
+    [JsonProperty("userid")]
+    [JsonPropertyName("userid")]
+    public string? UserId { get; set; }
+
+    /// <summary>
+    /// 每页数据量,默认10,最高50
+    /// </summary>
+    [JsonProperty("page_size")]
+    [JsonPropertyName("page_size")]
+    public int? PageSize { get; set; }
+
+    /// <summary>
+    /// 部门id
+    /// </summary>
+    [JsonProperty("deptid")]
+    [JsonPropertyName("deptid")]
+    public string? Deptid { get; set; }
+
+    /// <summary>
+    /// 结束时间 2017-05-01 00:00:00
+    /// </summary>
+    [JsonProperty("end_time")]
+    [JsonPropertyName("end_time")]
+    public string? EndTime { get; set; }
+
+    /// <summary>
+    /// 企业id
+    /// </summary>
+    [JsonProperty("corpid")]
+    [JsonPropertyName("corpid")]
+    public string? Corpid { get; set; }
+
+    /// <summary>
+    /// 更新结束时间 2017-05-01 00:00:00
+    /// </summary>
+    [JsonProperty("update_end_time")]
+    [JsonPropertyName("update_end_time")]
+    public string? UpdateEndTime { get; set; }
+
+    /// <summary>
+    /// 更新开始时间 2017-05-01 00:00:00
+    /// </summary>
+    [JsonProperty("update_start_time")]
+    [JsonPropertyName("update_start_time")]
+    public string? UpdateStartTime { get; set; }
+
+    /// <summary>
+    /// false:仅搜索未报销的申请单
+    /// </summary>
+    [JsonProperty("all_apply")]
+    [JsonPropertyName("all_apply")]
+    public string? AllApply { get; set; }
+
+    /// <summary>
+    /// 第三方申请单ID
+    /// </summary>
+    [JsonProperty("thirdpart_apply_id")]
+    [JsonPropertyName("thirdpart_apply_id")]
+    public string? ThirdpartApplyId { get; set; }
+}

+ 477 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripFlightOrdersResponse.cs

@@ -0,0 +1,477 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip.DTO;
+
+public class GetAlitripFlightOrdersResponse : DingtalkResponseErrorSuccess
+{
+    /// <summary>
+    /// 机票列表
+    /// </summary>
+    [JsonProperty("flight_order_list")]
+    [JsonPropertyName("flight_order_list")]
+    public List<FlightOrderDomain> FlightOrderList { get; set; }
+
+    /// <summary>
+    /// 分页相关信息
+    /// </summary>
+    [JsonProperty("page_info")]
+    [JsonPropertyName("page_info")]
+    public PageInfoDomain PageInfo { get; set; }
+}
+
+public class FlightOrderDomain
+{
+    /// <summary>
+    /// 机票订单id
+    /// </summary>
+    public long Id { get; set; }
+
+    /// <summary>
+    /// 更新时间
+    /// </summary>
+    [JsonProperty("gmt_modified")]
+    [JsonPropertyName("gmt_modified")]
+    public DateTime GmtModified { get; set; }
+
+    /// <summary>
+    /// 用户id
+    /// </summary>
+    public string UserId { get; set; }
+
+    /// <summary>
+    /// 企业名称
+    /// </summary>
+    [JsonProperty("corp_name")]
+    [JsonPropertyName("corp_name")]
+    public string CorpName { get; set; }
+
+    /// <summary>
+    /// 企业id
+    /// </summary>
+    public string CorpId { get; set; }
+
+    /// <summary>
+    /// 创建时间
+    /// </summary>
+    [JsonProperty("gmt_create")]
+    [JsonPropertyName("gmt_create")]
+    public DateTime GmtCreate { get; set; }
+
+    /// <summary>
+    /// 用户名称
+    /// </summary>
+    [JsonProperty("user_name")]
+    [JsonPropertyName("user_name")]
+    public string UserName { get; set; }
+
+    /// <summary>
+    /// 部门id
+    /// </summary>
+    public string DeptId { get; set; }
+
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    [JsonProperty("dept_name")]
+    [JsonPropertyName("dept_name")]
+    public string DeptName { get; set; }
+
+    /// <summary>
+    /// 商旅申请单id
+    /// </summary>
+    [JsonProperty("apply_id")]
+    [JsonPropertyName("apply_id")]
+    public string ApplyId { get; set; }
+
+    /// <summary>
+    /// 联系人
+    /// </summary>
+    [JsonProperty("contact_name")]
+    [JsonPropertyName("contact_name")]
+    public string ContactName { get; set; }
+
+    /// <summary>
+    /// 出发城市
+    /// </summary>
+    [JsonProperty("dep_city")]
+    [JsonPropertyName("dep_city")]
+    public string DepCity { get; set; }
+
+    /// <summary>
+    /// 到达城市
+    /// </summary>
+    [JsonProperty("arr_city")]
+    [JsonPropertyName("arr_city")]
+    public string ArrCity { get; set; }
+
+    /// <summary>
+    /// 出发日期
+    /// </summary>
+    [JsonProperty("dep_date")]
+    [JsonPropertyName("dep_date")]
+    public DateTime DepDate { get; set; }
+
+    /// <summary>
+    /// 到达日期
+    /// </summary>
+    [JsonProperty("ret_date")]
+    [JsonPropertyName("ret_date")]
+    public DateTime RetDate { get; set; }
+
+    /// <summary>
+    /// 行程类型。0:单程,1:往返,2:中转
+    /// </summary>
+    [JsonProperty("trip_type")]
+    [JsonPropertyName("trip_type")]
+    public TripTypeEnum TripType { get; set; }
+
+    public enum TripTypeEnum
+    {
+        单程 = 0, 往返 = 1, 中转 = 2
+    }
+
+    /// <summary>
+    /// 乘机人数量
+    /// </summary>
+    [JsonProperty("passenger_count")]
+    [JsonPropertyName("passenger_count")]
+    public int PassengerCount { get; set; }
+
+    /// <summary>
+    /// 舱位类型
+    /// </summary>
+    [JsonProperty("cabin_class")]
+    [JsonPropertyName("cabin_class")]
+    public string CabinClass { get; set; }
+
+    /// <summary>
+    /// 订单状态:0待支付,1出票中,2已关闭,3有改签单,4有退票单,5出票成功,6退票申请中,7改签申请中
+    /// </summary>
+    public int Status { get; set; }
+
+    /// <summary>
+    /// 折扣
+    /// </summary>
+    public string Discount { get; set; }
+
+    /// <summary>
+    /// 航班号
+    /// </summary>
+    [JsonProperty("flight_no")]
+    [JsonPropertyName("flight_no")]
+    public string FlightNo { get; set; }
+
+    /// <summary>
+    /// 乘机人,多个用‘,’分割
+    /// </summary>
+    [JsonProperty("passenger_name")]
+    [JsonPropertyName("passenger_name")]
+    public string PassengerName { get; set; }
+
+    /// <summary>
+    /// 出发机场
+    /// </summary>
+    [JsonProperty("dep_airport")]
+    [JsonPropertyName("dep_airport")]
+    public string DepAirport { get; set; }
+
+    /// <summary>
+    /// 到达机场
+    /// </summary>
+    [JsonProperty("arr_airport")]
+    [JsonPropertyName("arr_airport")]
+    public string ArrAirport { get; set; }
+
+    /// <summary>
+    /// 发票信息对象
+    /// </summary>
+    public InvoiceDomain Invoice { get; set; }
+
+    /// <summary>
+    /// 成本中心对象
+    /// </summary>
+    [JsonProperty("cost_center")]
+    [JsonPropertyName("cost_center")]
+    public CostCenterDomain CostCenter { get; set; }
+
+    /// <summary>
+    /// 价目信息
+    /// </summary>
+    [JsonProperty("price_info_list")]
+    [JsonPropertyName("price_info_list")]
+    public List<PriceInfoDomain> PriceInfoList { get; set; }
+
+    /// <summary>
+    /// 保险信息
+    /// </summary>
+    [JsonProperty("insureInfo_list")]
+    [JsonPropertyName("insureInfo_list")]
+    public List<InsureInfoDomain> InsureInfoList { get; set; }
+
+    /// <summary>
+    /// 第三方行程id
+    /// </summary>
+    [JsonProperty("thirdpart_itinerary_id")]
+    [JsonPropertyName("thirdpart_itinerary_id")]
+    public string ThirdpartItineraryId { get; set; }
+
+    /// <summary>
+    /// 出行人列表
+    /// </summary>
+    [JsonProperty("user_affiliate_list")]
+    [JsonPropertyName("user_affiliate_list")]
+    public List<UserAffiliateDomain> UserAffiliateList { get; set; }
+
+    /// <summary>
+    /// 第三方申请单ID
+    /// </summary>
+    [JsonProperty("thirdpart_apply_id")]
+    [JsonPropertyName("thirdpart_apply_id")]
+    public string ThirdpartApplyId { get; set; }
+
+    /// <summary>
+    /// 申请单名称
+    /// </summary>
+    [JsonProperty("btrip_title")]
+    [JsonPropertyName("btrip_title")]
+    public string BtripTitle { get; set; }
+
+    /// <summary>
+    /// 项目id
+    /// </summary>
+    [JsonProperty("project_id")]
+    [JsonPropertyName("project_id")]
+    public string ProjectId { get; set; }
+
+    /// <summary>
+    /// 项目code
+    /// </summary>
+    [JsonProperty("project_code")]
+    [JsonPropertyName("project_code")]
+    public string ProjectCode { get; set; }
+
+    /// <summary>
+    /// 项目名称
+    /// </summary>
+    [JsonProperty("project_title")]
+    [JsonPropertyName("project_title")]
+    public string ProjectTitle { get; set; }
+
+    /// <summary>
+    /// 第三方项目id
+    /// </summary>
+    [JsonProperty("third_part_project_id")]
+    [JsonPropertyName("third_part_project_id")]
+    public string ThirdPartProjectId { get; set; }
+}
+
+/// <summary>
+/// 发票信息对象
+/// </summary>
+public class InvoiceDomain
+{
+    /// <summary>
+    /// 商旅发票id
+    /// </summary>
+    public long Id { get; set; }
+
+    /// <summary>
+    /// 发票抬头
+    /// </summary>
+    public string Title { get; set; }
+}
+
+/// <summary>
+/// 成本中心对象
+/// </summary>
+public class CostCenterDomain
+{
+    /// <summary>
+    /// 商旅成本中心id
+    /// </summary>
+    public long Id { get; set; }
+
+    /// <summary>
+    /// 企业id
+    /// </summary>
+    public string CorpId { get; set; }
+
+    /// <summary>
+    /// 成本中心编号
+    /// </summary>
+    public string Number { get; set; }
+
+    /// <summary>
+    /// 成本中心名称
+    /// </summary>
+    public string Name { get; set; }
+}
+
+/// <summary>
+/// 价目信息
+/// </summary>
+public class PriceInfoDomain
+{
+    /// <summary>
+    /// 价格
+    /// </summary>
+    public decimal Price { get; set; }
+
+    /// <summary>
+    /// 资金流向:1:支出,2:收入
+    /// </summary>
+    public TypeEnum Type { get; set; }
+
+    public enum TypeEnum
+    {
+        支出 = 1, 收入 = 2
+    }
+
+    /// <summary>
+    /// 交易类目
+    /// </summary>
+    public string Category { get; set; }
+
+    /// <summary>
+    /// 结算方式:1:个人现付,2:企业现付,4:企业月结,8、企业预存
+    /// </summary>
+    [JsonProperty("pay_type")]
+    [JsonPropertyName("pay_type")]
+    public PayTypeEnum PayType { get; set; }
+
+    public enum PayTypeEnum
+    {
+        个人现付 = 1, 企业现付 = 2, 企业月结 = 4, 企业预存 = 8
+    }
+
+    /// <summary>
+    /// 流水创建时间
+    /// </summary>
+    [JsonProperty("gmt_create")]
+    [JsonPropertyName("gmt_create")]
+    public DateTime GmtCreate { get; set; }
+
+    /// <summary>
+    /// 乘机人,多个用‘,’分割
+    /// </summary>
+    [JsonProperty("passenger_name")]
+    [JsonPropertyName("passenger_name")]
+    public string PassengerName { get; set; }
+
+    /// <summary>
+    /// 流水单号
+    /// </summary>
+    public string TradeId { get; set; }
+
+    /// <summary>
+    /// 改签票号
+    /// </summary>
+    [JsonProperty("ticket_no")]
+    [JsonPropertyName("ticket_no")]
+    public string TicketNo { get; set; }
+
+    /// <summary>
+    /// 改签前的票号
+    /// </summary>
+    [JsonProperty("original_ticket_no")]
+    [JsonPropertyName("original_ticket_no")]
+    public string OriginalTicketNo { get; set; }
+
+    /// <summary>
+    /// 改签航班号
+    /// </summary>
+    [JsonProperty("changeFlightNo")]
+    [JsonPropertyName("changeFlightNo")]
+    public string ChangeFlightNo { get; set; }
+
+    /// <summary>
+    /// 改签折扣
+    /// </summary>
+    public string Discount { get; set; }
+
+    /// <summary>
+    /// 改签航班起飞时间
+    /// </summary>
+    public DateTime StartTime { get; set; }
+
+    /// <summary>
+    /// 改签航班到达时间
+    /// </summary>
+    public DateTime EndTime { get; set; }
+}
+
+/// <summary>
+/// 保险信息
+/// </summary>
+public class InsureInfoDomain
+{
+    /// <summary>
+    /// 保单号
+    /// </summary>
+    [JsonProperty("insure_no")]
+    [JsonPropertyName("insure_no")]
+    public string InsureNo { get; set; }
+
+    /// <summary>
+    /// 状态:1已出保 2已退保
+    /// </summary>
+    public StatusEnum Status { get; set; }
+
+    public enum StatusEnum
+    {
+        已出保 = 1, 已退保 = 2
+    }
+
+    /// <summary>
+    /// 乘机人(保险人)姓名
+    /// </summary>
+    public string Name { get; set; }
+}
+
+/// <summary>
+/// 出行人列表
+/// </summary>
+public class UserAffiliateDomain
+{
+    /// <summary>
+    /// 出行人ID
+    /// </summary>
+    public string UserId { get; set; }
+
+    /// <summary>
+    /// 出行人名称
+    /// </summary>
+    [JsonProperty("user_name")]
+    [JsonPropertyName("user_name")]
+    public string UserName { get; set; }
+}
+
+public class PageInfoDomain
+{
+    /// <summary>
+    /// 当前页
+    /// </summary>
+    public string Page { get; set; }
+
+    /// <summary>
+    /// 每页大小
+    /// </summary>
+    [JsonProperty("page_size")]
+    [JsonPropertyName("page_size")]
+    public string PageSize { get; set; }
+
+    /// <summary>
+    /// 总记录数
+    /// </summary>
+    [JsonProperty("total_number")]
+    [JsonPropertyName("total_number")]
+    public string TotalNumber { get; set; }
+}

+ 100 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripTrainOrdersRequest.cs

@@ -0,0 +1,100 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip.DTO;
+public class GetAlitripTrainOrdersRequest
+{
+    public GetAlitripTrainOrdersRequestDomain rq { get; set; }
+}
+public class GetAlitripTrainOrdersRequestDomain
+{
+    /// <summary>
+    /// 开始时间 2017-05-01 00:00:00
+    /// </summary>
+    [JsonProperty("start_time")]
+    [JsonPropertyName("start_time")]
+    public string? StartTime { get; set; }
+
+    /// <summary>
+    /// 商旅申请单id
+    /// </summary>
+    [JsonProperty("apply_id")]
+    [JsonPropertyName("apply_id")]
+    public string? ApplyId { get; set; }
+
+    /// <summary>
+    /// 页数,从1开始
+    /// </summary>
+    [JsonProperty("page")]
+    [JsonPropertyName("page")]
+    public int? Page { get; set; }
+
+    /// <summary>
+    /// 用户id
+    /// </summary>
+    [JsonProperty("userid")]
+    [JsonPropertyName("userid")]
+    public string? UserId { get; set; }
+
+    /// <summary>
+    /// 每页数据量,默认10,最高50
+    /// </summary>
+    [JsonProperty("page_size")]
+    [JsonPropertyName("page_size")]
+    public int? PageSize { get; set; }
+
+    /// <summary>
+    /// 部门id
+    /// </summary>
+    [JsonProperty("deptid")]
+    [JsonPropertyName("deptid")]
+    public string? Deptid { get; set; }
+
+    /// <summary>
+    /// 结束时间 2017-05-01 00:00:00
+    /// </summary>
+    [JsonProperty("end_time")]
+    [JsonPropertyName("end_time")]
+    public string? EndTime { get; set; }
+
+    /// <summary>
+    /// 企业id
+    /// </summary>
+    [JsonProperty("corpid")]
+    [JsonPropertyName("corpid")]
+    public string? Corpid { get; set; }
+
+    /// <summary>
+    /// 更新结束时间 2017-05-01 00:00:00
+    /// </summary>
+    [JsonProperty("update_end_time")]
+    [JsonPropertyName("update_end_time")]
+    public string? UpdateEndTime { get; set; }
+
+    /// <summary>
+    /// 更新开始时间 2017-05-01 00:00:00
+    /// </summary>
+    [JsonProperty("update_start_time")]
+    [JsonPropertyName("update_start_time")]
+    public string? UpdateStartTime { get; set; }
+
+    /// <summary>
+    /// false:仅搜索未报销的申请单
+    /// </summary>
+    [JsonProperty("all_apply")]
+    [JsonPropertyName("all_apply")]
+    public string? AllApply { get; set; }
+
+    /// <summary>
+    /// 第三方申请单ID
+    /// </summary>
+    [JsonProperty("thirdpart_apply_id")]
+    [JsonPropertyName("thirdpart_apply_id")]
+    public string? ThirdpartApplyId { get; set; }
+
+}

+ 297 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/DTO/GetAlitripTrainOrdersResponse.cs

@@ -0,0 +1,297 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.Json.Serialization;
+using System.Threading.Tasks;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip.DTO;
+public class GetAlitripTrainOrdersResponse : DingtalkResponseErrorSuccess
+{
+    /// <summary>
+    /// 机票列表
+    /// </summary>
+    [JsonProperty("train_order_list")]
+    [JsonPropertyName("train_order_list")]
+    public List<TrainOrder> TrainOrderList { get; set; }
+}
+
+public class TrainOrder
+{
+    /// <summary>
+    /// 机票订单id
+    /// </summary>
+    public long Id { get; set; }
+
+    /// <summary>
+    /// 创建时间
+    /// </summary>
+    [JsonProperty("gmt_create")]
+    [JsonPropertyName("gmt_create")]
+    public DateTime GmtCreate { get; set; }
+
+    /// <summary>
+    /// 更新时间
+    /// </summary>
+    [JsonProperty("gmt_modified")]
+    [JsonPropertyName("gmt_modified")]
+    public DateTime GmtModified { get; set; }
+
+    /// <summary>
+    /// 企业id
+    /// </summary>
+    public string CorpId { get; set; }
+
+    /// <summary>
+    /// 企业名称
+    /// </summary>
+    [JsonProperty("corp_name")]
+    [JsonPropertyName("corp_name")]
+    public string CorpName { get; set; }
+
+    /// <summary>
+    /// 用户id
+    /// </summary>
+    public string UserId { get; set; }
+
+    /// <summary>
+    /// 用户姓名
+    /// </summary>
+    [JsonProperty("user_name")]
+    [JsonPropertyName("user_name")]
+    public string UserName { get; set; }
+
+    /// <summary>
+    /// 部门id
+    /// </summary>
+    public string DeptId { get; set; }
+
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    [JsonProperty("dept_name")]
+    [JsonPropertyName("dept_name")]
+    public string DeptName { get; set; }
+
+    /// <summary>
+    /// 商旅申请单id
+    /// </summary>
+    [JsonProperty("apply_id")]
+    [JsonPropertyName("apply_id")]
+    public string ApplyId { get; set; }
+
+    /// <summary>
+    /// 联系人
+    /// </summary>
+    [JsonProperty("contact_name")]
+    [JsonPropertyName("contact_name")]
+    public string ContactName { get; set; }
+
+    /// <summary>
+    /// 出发站
+    /// </summary>
+    [JsonProperty("dep_station")]
+    [JsonPropertyName("dep_station")]
+    public string DepStation { get; set; }
+
+    /// <summary>
+    /// 到达站
+    /// </summary>
+    [JsonProperty("arr_station")]
+    [JsonPropertyName("arr_station")]
+    public string ArrStation { get; set; }
+
+    /// <summary>
+    /// 出发时间
+    /// </summary>
+    [JsonProperty("dep_time")]
+    [JsonPropertyName("dep_time")]
+    public DateTime DepTime { get; set; }
+
+    /// <summary>
+    /// 到达时间
+    /// </summary>
+    [JsonProperty("arr_time")]
+    [JsonPropertyName("arr_time")]
+    public DateTime ArrTime { get; set; }
+
+    /// <summary>
+    /// 车次
+    /// </summary>
+    [JsonProperty("train_number")]
+    [JsonPropertyName("train_number")]
+    public string TrainNumber { get; set; }
+
+    /// <summary>
+    /// 车次类型
+    /// </summary>
+    [JsonProperty("train_type")]
+    [JsonPropertyName("train_type")]
+    public string TrainType { get; set; }
+
+    /// <summary>
+    /// 座位类型
+    /// </summary>
+    [JsonProperty("seat_type")]
+    [JsonPropertyName("seat_type")]
+    public string SeatType { get; set; }
+
+    /// <summary>
+    /// 运行时长
+    /// </summary>
+    [JsonProperty("run_time")]
+    [JsonPropertyName("run_time")]
+    public string RunTime { get; set; }
+
+    /// <summary>
+    /// 12306票号
+    /// </summary>
+    [JsonProperty("ticket_no_12306")]
+    [JsonPropertyName("ticket_no_12306")]
+    public string TicketNo12306 { get; set; }
+
+    /// <summary>
+    /// 出发城市
+    /// </summary>
+    [JsonProperty("dep_city")]
+    [JsonPropertyName("dep_city")]
+    public string DepCity { get; set; }
+
+    /// <summary>
+    /// 到达城市
+    /// </summary>
+    [JsonProperty("arr_city")]
+    [JsonPropertyName("arr_city")]
+    public string ArrCity { get; set; }
+
+    /// <summary>
+    /// 乘客姓名
+    /// </summary>
+    [JsonProperty("rider_name")]
+    [JsonPropertyName("rider_name")]
+    public string RiderName { get; set; }
+
+    /// <summary>
+    /// 票的数量
+    /// </summary>
+    [JsonProperty("ticket_count")]
+    [JsonPropertyName("ticket_count")]
+    public int TicketCount { get; set; }
+
+    /// <summary>
+    /// 订单状态:0:待支付,1:出票中,2:已关闭,3:改签成功,4:退票成功,5:出票完成,6:退票申请中,7:改签申请中,8:已出票/已发货,9:出票失败,10:改签失败,11:退票失败
+    /// </summary>
+    public StatusEnum Status { get; set; }
+
+    public enum StatusEnum
+    {
+        待支付 = 0, 出票中, 已关闭, 改签成功, 退票成功, 出票完成, 退票申请中, 改签申请中, 已出票or已发货, 出票失败, 改签失败, 退票失败
+    }
+
+    /// <summary>
+    /// 发票信息对象
+    /// </summary>
+    public InvoiceDomain Invoice { get; set; }
+
+    /// <summary>
+    /// 成本中心对象
+    /// </summary>
+    [JsonProperty("cost_center")]
+    [JsonPropertyName("cost_center")]
+    public CostCenterDomain CostCenter { get; set; }
+
+    /// <summary>
+    /// 价目信息
+    /// </summary>
+    [JsonProperty("price_info_list")]
+    [JsonPropertyName("price_info_list")]
+    public TrainPriceInfo PriceInfoList { get; set; }
+
+    /// <summary>
+    /// 第三方行程id
+    /// </summary>
+    [JsonProperty("thirdpart_itinerary_id")]
+    [JsonPropertyName("thirdpart_itinerary_id")]
+    public string ThirdpartItineraryId { get; set; }
+
+    /// <summary>
+    /// 出行人列表
+    /// </summary>
+    [JsonProperty("user_affiliate_list")]
+    [JsonPropertyName("user_affiliate_list")]
+    public List<UserAffiliateDomain> UserAffiliateList { get; set; }
+
+    /// <summary>
+    /// 第三方申请单ID
+    /// </summary>
+    [JsonProperty("thirdpart_apply_id")]
+    [JsonPropertyName("thirdpart_apply_id")]
+    public string ThirdpartApplyId { get; set; }
+
+    /// <summary>
+    /// 申请单名称
+    /// </summary>
+    [JsonProperty("btrip_title")]
+    [JsonPropertyName("btrip_title")]
+    public string BtripTitle { get; set; }
+}
+
+/// <summary>
+/// 价目信息
+/// </summary>
+public class TrainPriceInfo
+{
+    /// <summary>
+    /// 价格
+    /// </summary>
+    public decimal Price { get; set; }
+
+    /// <summary>
+    /// 资金流向:1:支出,2:收入
+    /// </summary>
+    public TrainPriceTypeEnum Type { get; set; }
+
+    public enum TrainPriceTypeEnum
+    {
+        支出 = 1, 收入
+    }
+
+    /// <summary>
+    /// 交易类目
+    /// </summary>
+    public string Category { get; set; }
+
+    /// <summary>
+    /// 结算方式:1:个人现付,2:企业现付,4:企业月结,8、企业预存
+    /// </summary>
+    [JsonProperty("pay_type")]
+    [JsonPropertyName("pay_type")]
+    public int PayType { get; set; }
+
+    public enum TrainPricePayTypeEnum
+    {
+        个人现付 = 1, 企业现付 = 2, 企业月结 = 4, 企业预存 = 8
+    }
+
+    /// <summary>
+    /// 流水创建时间
+    /// </summary>
+    [JsonProperty("gmt_create")]
+    [JsonPropertyName("gmt_create")]
+    public DateTime GmtCreate { get; set; }
+
+    /// <summary>
+    /// 乘机人,多个用‘,’分割
+    /// </summary>
+    [JsonProperty("passenger_name")]
+    [JsonPropertyName("passenger_name")]
+    public string PassengerName { get; set; }
+}

+ 22 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/AliTrip/IAliTripRequestProxy.cs

@@ -0,0 +1,22 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip.DTO;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip;
+public interface IAliTripRequestProxy: IHttpDispatchProxy
+{
+    [Post("https://oapi.dingtalk.com/topapi/alitrip/btrip/address/get"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> GetAlitripAddress([QueryString("access_token")] string AccessToken, [Body] GetAlitripAddressRequest request);
+
+    [Post("https://oapi.dingtalk.com/topapi/alitrip/btrip/flight/order/search"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+
+    Task<string> GetAlitripFlightOrders([QueryString("access_token")] string AccessToken, GetAlitripFlightOrdersRequest rq);
+
+    [Post("https://oapi.dingtalk.com/topapi/alitrip/btrip/train/order/search"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> GetAlitripTrainOrders([QueryString("access_token")] string AccessToken, GetAlitripTrainOrdersRequest rq);
+
+}

+ 159 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/AttendanceRequest.cs

@@ -0,0 +1,159 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.Attendance.DTO;
+
+using NewLife;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Attendance;
+
+public class AttendanceRequest : IScoped
+{
+    private IAttendanceRequestProxy request;
+
+    public AttendanceRequest(IAttendanceRequestProxy _request)
+    {
+        request = _request;
+    }
+
+    /// <summary>
+    /// 获取打卡详情
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="useridList">企业内的员工ID列表,最大值50</param>
+    /// <param name="from">查询考勤打卡记录的起始工作日</param>
+    /// <param name="to">查询考勤打卡记录的结束工作日</param>
+    /// <param name="isI18n">是否为海外企业使用</param>
+    /// <returns></returns>
+    public async Task<ListRecordResponse> ListRecord(string AccessToken, List<string> useridList, DateTime from, DateTime to,bool isI18n=false)
+    {
+        var requestBody = new ListRecordRequest
+        {
+            UserIds = useridList,
+            CheckDateFrom = from.ToString("yyyy-MM-dd HH:mm:ss"),
+            CheckDateTo = to.ToString("yyyy-MM-dd HH:mm:ss"),
+            IsI18n = isI18n
+        };
+        var resStr = await request.ListRecord(AccessToken, requestBody);
+        var res = resStr.ToObject<ListRecordResponse>();
+        return res;
+    }
+
+    /// <summary>
+    /// 通知审批通过
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="userid">员工的userId</param>
+    /// <param name="approveId">审批单ID,最大长度100个字符,自定义值</param>
+    /// <param name="tagName">审批单类型名称,最大长度20个字符。 支持类型如下:请假, 出差,外出,加班</param>
+    /// <param name="jumpUrl">审批单跳转地址,最大长度200个字符</param>
+    /// <param name="BizType">审批单类型,可取值:1:加班,2:出差、外出,3:请假</param>
+    /// <param name="fromTime">开始时间。开始时间不能早于当前时间前31天</param>
+    /// <param name="toTime">结束时间</param>
+    /// <param name="durationUnit">时长单位,支持格式如下:day,halfDay,hour:biz_type为1时仅支持hou</param>
+    /// <param name="calculateModel">计算方法:0:按自然日计算,1:按工作日计算</param>
+    /// <param name="leaveCode">假期规则唯一标识。选填。仅支持bizType=3 请假时传不为空,可以支持根据假期类型设置的取整规则进行时长取整</param>
+    /// <param name="subType">子类型名称,最大长度20个字符。审批单类型biz_type=3时,该参数必传。</param>
+    /// <param name="overTimeDuration">biz_type为1时必传,加班时长单位小时</param>
+    /// <param name="overTimeToMore">biz_type为1时必传:1:加班转调休,2:加班转工资</param>
+    /// <returns></returns>
+    public async Task<AttendanceApprovalsFinishResponse> ApproveFinish(string AccessToken, string userid, string approveId, string tagName, string jumpUrl,
+        BizTypeEnum BizType, DateTime fromTime, DateTime toTime, DurationUnitEnum durationUnit, CalculateModelEnum calculateModel, string? leaveCode = null,
+        string? subType = null, string? overTimeDuration = null, long? overTimeToMore = null)
+    {
+        if (BizType == BizTypeEnum.请假 && string.IsNullOrEmpty(subType))
+            throw Oops.Oh("审批单类型biz_type=3时,subType必传。");
+        if (BizType == BizTypeEnum.加班 && (string.IsNullOrEmpty(overTimeDuration) || !overTimeToMore.HasValue))
+            throw Oops.Oh("biz_type为1时,overTimeDuration和overTimeToMore必传");
+        var fromTimeStr = "";
+        var toTimeStr = "";
+        switch (durationUnit)
+        {
+            case DurationUnitEnum.day:
+                fromTimeStr = fromTime.ToString("yyyy-MM-dd");
+                toTimeStr = toTime.ToString("yyyy-MM-dd");
+                break;
+
+            case DurationUnitEnum.halfDay:
+                fromTimeStr = TimeToHalfDay(fromTime);
+                toTimeStr = TimeToHalfDay(toTime);
+                break;
+
+            case DurationUnitEnum.hour:
+                fromTimeStr = fromTime.ToString("yyyy-MM-dd HH:mm");
+                toTimeStr = toTime.ToString("yyyy-MM-dd HH:mm");
+                break;
+
+            default:
+                break;
+        }
+        var requestBody = new AttdendanceApprovalsFinishRequest
+        {
+            ApproveId = approveId,
+            TagName = tagName,
+            JumpUrl = jumpUrl,
+            OvertimeDuration = overTimeDuration,
+            OverTimeToMore = overTimeToMore,
+            SubType = subType,
+            TopCalculateApproveDurationParam = new TopCalculateApproveDurationParamDomain
+            {
+                BizType = BizType,
+                FromTime = fromTimeStr,
+                ToTime = toTimeStr,
+                DurationUnit = durationUnit.ToString(),
+                CalculateModel = (long)calculateModel,
+                LeaveCode = leaveCode
+            }
+        };
+        try
+        {
+            var resStr = await request.ApprovalsFinish(userid, AccessToken, requestBody);
+            var res = resStr.ToObject<AttendanceApprovalsFinishResponse>();
+            return res;
+        }
+        catch (Exception ex)
+        {
+            throw Oops.Oh(ex.Message);
+        }
+    }
+
+    /// <summary>
+    /// 通知审批撤销
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="userid">员工的userId</param>
+    /// <param name="approveId">审批ID</param>
+    /// <returns></returns>
+    public async Task<AttendanceApprovelsCancelResponse> ApproveCancel(string AccessToken, string userid, string approveId)
+    {
+        var resStr = await request.ApprovalsCancel(AccessToken, new AttendanceApprovelsCancelRequest
+        {
+            ApproveId = approveId,
+            UserId = userid,
+        });
+        return resStr.ToObject<AttendanceApprovelsCancelResponse>();
+    }
+
+    public async Task<GetLeaveStatusResponse> GetLeaveStatus(string AccessToken,List<string> UserIdList,DateTime StartTime,DateTime EndTime,int Offset=0,int Size=10)
+    {
+        var resStr = await request.GetLeaveStatus(AccessToken, new GetLeaveStatusRequest
+        {
+            UserIdList = UserIdList.Join(","),
+            StartTime = new DateTimeOffset(StartTime).ToUnixTimeMilliseconds(),
+            EndTime = new DateTimeOffset(EndTime).ToUnixTimeMilliseconds(),
+            Offset = Offset,
+            Size = Size
+        });
+        return resStr.ToObject<GetLeaveStatusResponse>();
+    }
+
+    private string TimeToHalfDay(DateTime time)
+    {
+        var dateStr = time.ToString("yyyy-MM-dd");
+        var apm = time.Hour < 12 ? "AM" : "PM";
+        return dateStr + " " + apm;
+    }
+}

+ 106 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/AttdendanceApprovalsFinishRequest.cs

@@ -0,0 +1,106 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Attendance.DTO;
+
+public class AttdendanceApprovalsFinishRequest
+{
+    /// <summary>
+    /// 审批单类型名称,最大长度20个字符。 支持类型如下: 请假,出差,外出,加班
+    /// </summary>
+    [JsonProperty("tagName")]
+    [JsonPropertyName("tagName")]
+    public string TagName;
+
+    /// <summary>
+    /// 子类型名称,最大长度20个字符。审批单类型biz_type=3时,该参数必传。
+    /// </summary>
+    [JsonProperty("subType")]
+    [JsonPropertyName("subType")]
+    public string? SubType;
+
+    /// <summary>
+    /// 审批单ID,最大长度100个字符,自定义值。
+    /// </summary>
+    [JsonProperty("approveId")]
+    [JsonPropertyName("approveId")]
+    public string ApproveId;
+
+    /// <summary>
+    /// 审批单跳转地址,最大长度200个字符。
+    /// </summary>
+    [JsonProperty("jumpUrl")]
+    [JsonPropertyName("jumpUrl")]
+    public string JumpUrl;
+
+    /// <summary>
+    /// biz_type为1时必传,加班时长单位小时。
+    /// </summary>
+    [JsonProperty("overtimeDuration")]
+    [JsonPropertyName("overtimeDuration")]
+    public string? OvertimeDuration;
+
+    /// <summary>
+    /// biz_type为1时必传:1:加班转调休,2:加班转工资
+    /// </summary>
+    [JsonProperty("overTimeToMore")]
+    [JsonPropertyName("overTimeToMore")]
+    public long? OverTimeToMore;
+
+    /// <summary>
+    /// 时长相关入参。
+    /// </summary>
+    [JsonProperty("topCalculateApproveDurationParam")]
+    [JsonPropertyName("topCalculateApproveDurationParam")]
+    public TopCalculateApproveDurationParamDomain TopCalculateApproveDurationParam;
+}
+
+public class TopCalculateApproveDurationParamDomain
+{
+    /// <summary>
+    /// 审批单类型,可取值:1:加班,2:出差、外出,3:请假
+    /// </summary>
+    [JsonProperty("bizType")]
+    [JsonPropertyName("bizType")]
+    public BizTypeEnum BizType;
+
+    /// <summary>
+    /// 开始时间。开始时间不能早于当前时间前31天。 支持以下格式:2019-08-15,2019-08-15 AM,2019-08-15 12:43
+    /// </summary>
+    [JsonProperty("fromTime")]
+    [JsonPropertyName("fromTime")]
+    public string FromTime;
+
+    /// <summary>
+    /// 结束时间。结束时间减去开始时间的天数不能超过31天。biz_type为1时,结束时间减去开始时间的天数不能超过1天。
+    /// </summary>
+    [JsonProperty("toTime")]
+    [JsonPropertyName("toTime")]
+    public string ToTime;
+
+    /// <summary>
+    /// 时长单位,支持格式如下:day,halfDay,hour:biz_type为1时仅支持hour。
+    /// </summary>
+    [JsonProperty("durationUnit")]
+    [JsonPropertyName("durationUnit")]
+    public string DurationUnit;
+
+    /// <summary>
+    /// 计算方法:0:按自然日计算,1:按工作日计算
+    /// </summary>
+    [JsonProperty("calculateModel")]
+    [JsonPropertyName("calculateModel")]
+    public long CalculateModel;
+
+    /// <summary>
+    /// 假期规则唯一标识。选填。仅支持bizType=3 请假时传不为空,可以支持根据假期类型设置的取整规则进行时长取整。
+    /// </summary>
+    [JsonProperty("leaveCode")]
+    [JsonPropertyName("leaveCode")]
+    public string? LeaveCode;
+}

+ 41 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/AttendanceApprovalsFinishResponse.cs

@@ -0,0 +1,41 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Attendance.DTO;
+
+public class AttendanceApprovalsFinishResponse:DingtalkResponseSuccessResult<AttendanceApprovalsFinishResponseResult>
+{
+}
+
+
+public class AttendanceApprovalsFinishResponseResult
+{
+    /// <summary>
+    /// 总时长,该字段的单位与本企业内对应审批单设置的单位一致
+    /// </summary>
+    public double Duration;
+
+    /// <summary>
+    /// 详细信息
+    /// </summary>
+    public List<DurationDetailDomain> DurationDetail;
+}
+public class DurationDetailDomain
+{
+    /// <summary>
+    /// 审批通过日期
+    /// </summary>
+    public string Date;
+
+    /// <summary>
+    /// 每日时长
+    /// </summary>
+    public double Duration;
+}

+ 28 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/AttendanceApprovelsCancelRequest.cs

@@ -0,0 +1,28 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Attendance.DTO;
+
+public class AttendanceApprovelsCancelRequest
+{
+    /// <summary>
+    /// 用户id
+    /// </summary>
+    [JsonProperty("userid")]
+    [JsonPropertyName("userid")]
+    public string? UserId { get; set; }
+
+    /// <summary>
+    /// 审批ID。 企业内部应用,来自通知审批通过接口自定义的参数approve_id。 第三方企业应用,来自通知审批通过接口自定义的参数approve_id。
+    /// </summary>
+    [JsonProperty("approve_id")]
+    [JsonPropertyName("approve_id")]
+    public string ApproveId { get; set; }
+}

+ 15 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/AttendanceApprovelsCancelResponse.cs

@@ -0,0 +1,15 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Attendance.DTO;
+
+public class AttendanceApprovelsCancelResponse:DingtalkResponseError
+{
+}

+ 27 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/Enums.cs

@@ -0,0 +1,27 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Attendance.DTO;
+
+public enum BizTypeEnum
+{
+    加班 = 1,
+    出差 = 2,
+    请假 = 3
+}
+
+public enum DurationUnitEnum
+{
+    day,
+    halfDay,
+    hour
+}
+
+public enum CalculateModelEnum
+{
+    按自然日计算 = 0,
+    按工作日计算 = 1
+}

+ 46 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/GetLeaveStatusRequest.cs

@@ -0,0 +1,46 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Attendance.DTO;
+public class GetLeaveStatusRequest
+{
+    /// <summary>
+    /// 待查询用户的ID列表,每次最多100个
+    /// </summary>
+    [JsonProperty("userid_list")]
+    [JsonPropertyName("userid_list")]
+    public string UserIdList { get; set; }
+
+    /// <summary>
+    /// 开始时间 ,Unix时间戳,支持最多180天的查询
+    /// </summary>
+    [JsonProperty("start_time")]
+    [JsonPropertyName("start_time")]
+    public long StartTime { get; set; }
+
+    /// <summary>
+    /// 结束时间,Unix时间戳,支持最多180天的查询
+    /// </summary>
+    [JsonProperty("end_time")]
+    [JsonPropertyName("end_time")]
+    public long EndTime { get; set; }
+
+    /// <summary>
+    /// 支持分页查询,与size参数同时设置时才生效,此参数代表偏移量,偏移量从0开始
+    /// </summary>
+    [JsonProperty("offset")]
+    [JsonPropertyName("offset")]
+    public int Offset {  get; set; }
+
+    /// <summary>
+    /// 支持分页查询,与offset参数同时设置时才生效,此参数代表分页大小,最大20
+    /// </summary>
+    [JsonProperty("size")]
+    [JsonPropertyName("size")]
+    public int Size {  get; set; }
+}

+ 73 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/GetLeaveStatusResponse.cs

@@ -0,0 +1,73 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Attendance.DTO;
+
+public class GetLeaveStatusResponse:DingtalkResponseErrorResultRequestid<GetLeaveStatusResult>
+{
+    /// <summary>
+    /// 请求是否成功。true:成功, false:失败
+    /// </summary>
+    public bool Success { get; set; }
+}
+
+public class GetLeaveStatusResult
+{
+    /// <summary>
+    /// 是否还有更多的数据
+    /// </summary>
+    [JsonProperty("has_more")]
+    [JsonPropertyName("has_more")]
+    public bool HasMore { get; set; }
+
+    /// <summary>
+    /// 请假状态列表
+    /// </summary>
+    [JsonProperty("leave_status")]
+    [JsonPropertyName("leave_status")]
+    public List<LeaveStatusDomain> LeaveStatus { get; set; }
+}
+
+public class LeaveStatusDomain
+{
+    /// <summary>
+    /// 请假单位:    percent_day:天    percent_hour:小时
+    /// </summary>
+    [JsonProperty("duration_unit")]
+    [JsonPropertyName("duration_unit")]
+    public string DurationUnit {  get; set; }
+
+    /// <summary>
+    /// 假期时长*100,例如用户请假时长为1天,该值就等于100。
+    /// </summary>
+    [JsonProperty("duration_percent")]
+    [JsonPropertyName("duration_percent")]
+    public double DurationPercent { get; set; }
+
+    /// <summary>
+    /// 请假结束时间,Unix时间戳。
+    /// </summary>
+    [JsonProperty("end_time")]
+    [JsonPropertyName("end_time")]
+    public long EndTime { get; set; }
+
+    /// <summary>
+    /// 请假开始时间,Unix时间戳。
+    /// </summary>
+    [JsonProperty("start_time")]
+    [JsonPropertyName("start_time")]
+    public long StartTime {  get; set; }
+
+    /// <summary>
+    /// 用户ID。
+    /// </summary>
+    public string UserId {  get; set; }
+
+}

+ 40 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/ListRecordRequest.cs

@@ -0,0 +1,40 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Attendance.DTO;
+
+public class ListRecordRequest
+{
+    /// <summary>
+    /// 企业内的员工ID列表,最大值50
+    /// </summary>
+    [JsonProperty("userIds")]
+    [JsonPropertyName("userIds")]
+    public List<string> UserIds { get; set; }
+
+    /// <summary>
+    /// 查询考勤打卡记录的起始工作日。格式为:yyyy-MM-dd hh:mm:ss。例如,参数传"2021-12-01 10:00:00",员工在09:00的打卡信息获取不到。
+    /// </summary>
+    [JsonProperty("checkDateFrom")]
+    [JsonPropertyName("checkDateFrom")]
+    public string CheckDateFrom { get; set; }
+
+    /// <summary>
+    /// 查询考勤打卡记录的结束工作日。格式为:yyyy-MM-dd hh:mm:ss。例如,参数传"2021-12-01 18:00:00",员工在19:00的打卡信息获取不到。
+    /// </summary>
+    [JsonProperty("checkDateTo")]
+    [JsonPropertyName("checkDateTo")]
+    public string CheckDateTo { get; set; }
+
+    /// <summary>
+    /// 是否为海外企业使用: true:海外平台使用。false(默认):国内平台使用
+    /// </summary>
+    [JsonProperty("isI18n")]
+    [JsonPropertyName("isI18n")]
+    public bool IsI18n { get; set; } = false;
+}

+ 210 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/DTO/ListRecordResponse.cs

@@ -0,0 +1,210 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Attendance.DTO;
+
+public class ListRecordResponse:DingtalkResponseError
+{
+    public List<ListRecordResultDomain> RecordResult { get; set; }
+}
+
+public class ListRecordResultDomain
+{
+    /// <summary>
+    /// 关联的审批ID,当该字段非空时,表示打卡记录与请假、加班等审批有关
+    /// </summary>
+    public long ApproveId { get; set; }
+
+    /// <summary>
+    /// 基准定位精度
+    /// </summary>
+    public string BaseAccuracy { get; set; }
+
+    /// <summary>
+    /// 基准地址
+    /// </summary>
+    public string BaseAddress { get; set; }
+
+    /// <summary>
+    /// 计算迟到和早退,基准时间;也可作为排班打卡时间
+    /// </summary>
+    public string BaseCheckTime { get; set; }
+
+    /// <summary>
+    /// 基准纬度
+    /// </summary>
+    public string BaseLatitude { get; set; }
+
+    /// <summary>
+    /// 基准经度
+    /// </summary>
+    public string BaseLongitude { get; set; }
+
+    /// <summary>
+    /// 基准MAC地址
+    /// </summary>
+    public string BaseMacAddr { get; set; }
+
+    /// <summary>
+    /// 基准wifi ssid
+    /// </summary>
+    public string BaseSsid { get; set; }
+
+    /// <summary>
+    /// 关联的业务ID
+    /// </summary>
+    public string BizId { get; set; }
+
+    /// <summary>
+    /// 考勤类型:OnDuty:上班,OffDuty:下班
+    /// </summary>
+    public string CheckType { get; set; }
+
+    /// <summary>
+    /// 班次ID
+    /// </summary>
+    public long ClassId { get; set; }
+
+    /// <summary>
+    /// 打卡设备ID
+    /// </summary>
+    public string DeviceId { get; set; }
+
+    /// <summary>
+    /// 打卡设备序列号
+    /// </summary>
+    public string DeviceSN { get; set; }
+
+    /// <summary>
+    /// 打卡记录创建时间
+    /// </summary>
+    public string GmtCreate { get; set; }
+
+    /// <summary>
+    /// 打卡记录修改时间
+    /// </summary>
+    public string GmtModified { get; set; }
+
+    /// <summary>
+    /// 考勤组ID
+    /// </summary>
+    public long GroupId { get; set; }
+
+    /// <summary>
+    /// 考勤ID
+    /// </summary>
+    public long Id { get; set; }
+
+    /// <summary>
+    /// 对应的invalidRecordType异常信息的具体描述
+    /// </summary>
+    public string InvalidRecordMsg { get; set; }
+
+    /// <summary>
+    /// 异常信息类型: Security:安全相关原因,Other:其他原因
+    /// </summary>
+    public string InvalidRecordType { get; set; }
+
+    /// <summary>
+    /// 是否合法.Y:合法,N:不合法
+    /// </summary>
+    public string IsLegal { get; set; }
+
+    /// <summary>
+    /// 定位方法
+    /// </summary>
+    public string LocationMethod { get; set; }
+
+    /// <summary>
+    /// 位置结果:Normal:范围内,Outside:范围外,NotSigned:未打卡
+    /// </summary>
+    public string LocationResult { get; set; }
+
+    /// <summary>
+    /// 打卡备注
+    /// </summary>
+    public string OutsideRemark { get; set; }
+
+    /// <summary>
+    /// 排班打卡时间
+    /// </summary>
+    public string PlanCheckTime { get; set; }
+
+    /// <summary>
+    /// 排班ID
+    /// </summary>
+    public long PlanId { get; set; }
+
+    /// <summary>
+    /// 关联的审批实例ID,当该字段非空时,表示打卡记录与请假、加班等审批有关
+    /// </summary>
+    public string ProcInstId { get; set; }
+
+    /// <summary>
+    /// 数据来源:ATM:考勤机打卡(指纹/人脸打卡),BEACON:IBeacon,DING_ATM:钉钉考勤机(考勤机蓝牙打卡),USER:用户打卡
+    ///         BOSS:老板改签,APPROVE:审批系统,SYSTEM:考勤系统,AUTO_CHECK:自动打卡
+    /// </summary>
+    public string SourceType { get; set; }
+
+    /// <summary>
+    /// 打卡结果。 Normal:正常,Early:早退,Late:迟到,SeriousLate:严重迟到,Absenteeism:旷工迟到,NotSigned:未打卡
+    /// </summary>
+    public string TimeResult { get; set; }
+
+    /// <summary>
+    /// 用户打卡定位精度
+    /// </summary>
+    public string UserAccuracy { get; set; }
+
+    /// <summary>
+    /// 用户打卡地址
+    /// </summary>
+    public string UserAddress { get; set; }
+
+    /// <summary>
+    /// 实际打卡时间
+    /// </summary>
+    public string UserCheckTime { get; set; }
+
+    /// <summary>
+    /// 打卡人的userId
+    /// </summary>
+    public string UserId { get; set; }
+
+    /// <summary>
+    /// 用户打卡纬度
+    /// </summary>
+    public string UserLatitude { get; set; }
+
+    /// <summary>
+    /// 用户打卡经度
+    /// </summary>
+    public string UserLongitude { get; set; }
+
+    /// <summary>
+    /// 用户打卡wifi Mac地址
+    /// </summary>
+    public string UserMacAddr { get; set; }
+
+    /// <summary>
+    /// 用户打卡wifi SSID
+    /// </summary>
+    public string UserSsid { get; set; }
+
+    /// <summary>
+    /// 工作日
+    /// </summary>
+    public long WorkDate { get; set; }
+
+    /// <summary>
+    /// 企业ID
+    /// </summary>
+    public string CorpId { get; set; }
+}

+ 27 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Attendance/IAttendanceRequestProxy.cs

@@ -0,0 +1,27 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.Attendance.DTO;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Attendance;
+
+public interface IAttendanceRequestProxy : IHttpDispatchProxy
+{
+    [Post("https://oapi.dingtalk.com/attendance/listRecord"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> ListRecord([QueryString("access_token")] string AccessToken, [Body] ListRecordRequest request);
+
+    [Post("https://api.dingtalk.com/v1.0/attendance/approvals/finish"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> ApprovalsFinish([QueryString] string userId, [Headers("x-acs-dingtalk-access-token")] string AccessToken
+        , [Body] AttdendanceApprovalsFinishRequest request);
+
+    [Post("https://oapi.dingtalk.com/topapi/attendance/approve/cancel?access_token={AccessToken}"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> ApprovalsCancel(string AccessToken, [Body] AttendanceApprovelsCancelRequest request);
+
+    [Post("https://oapi.dingtalk.com/topapi/attendance/getleavestatus?access_token={AccessToken}"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    
+    Task<string> GetLeaveStatus(string AccessToken, [Body]GetLeaveStatusRequest request);
+
+}

+ 21 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseError.cs

@@ -0,0 +1,21 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+public abstract class DingtalkResponseError
+{
+    /// <summary>
+    /// 返回码描述=ok
+    /// </summary>
+    public virtual string ErrMsg { get; set; }
+
+    /// <summary>
+    /// 返回码=0
+    /// </summary>
+    public virtual long ErrCode { get; set; }
+}

+ 18 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseErrorRequestId.cs

@@ -0,0 +1,18 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+public abstract class DingtalkResponseErrorRequestId:DingtalkResponseError
+{
+    /// <summary>
+    /// 请求ID
+    /// </summary>
+    [JsonProperty("request_id")]
+    [JsonPropertyName("request_id")]
+    public virtual string RequestId { get; set; }
+}

+ 17 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseErrorResult.cs

@@ -0,0 +1,17 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+public abstract class DingtalkResponseErrorResult<T>:DingtalkResponseError
+{
+    /// <summary>
+    /// 返回结果
+    /// </summary>
+    public virtual T Result { get; set; }
+}

+ 19 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseErrorResultRequestid.cs

@@ -0,0 +1,19 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+public class DingtalkResponseErrorResultRequestid<T> : DingtalkResponseErrorResult<T>
+{
+    /// <summary>
+    /// 请求ID
+    /// </summary>
+    [JsonProperty("request_id")]
+    [JsonPropertyName("request_id")]
+    public string RequestId { get; set; }
+}

+ 16 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseErrorSuccess.cs

@@ -0,0 +1,16 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+public abstract class DingtalkResponseErrorSuccess:DingtalkResponseError
+{
+    /// <summary>
+    /// 接口调用是否成功
+    /// </summary>
+    public virtual bool Success { get; set; }
+}

+ 31 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseHasMoreList.cs

@@ -0,0 +1,31 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+public abstract class DingtalkResponseHasMoreList<T>
+{
+    /// <summary>
+    /// 是否还有更多的数据
+    /// </summary>
+    [JsonProperty("has_more")]
+    [JsonPropertyName("has_more")]
+    public virtual bool HasMore { get; set; }
+
+    /// <summary>
+    /// 下一次分页的游标
+    /// </summary>
+    [JsonProperty("next_cursor")]
+    [JsonPropertyName("next_cursor")]
+    public virtual long? NextCursor { get; set; }
+
+    /// <summary>
+    /// 数据列表
+    /// </summary>
+    public virtual List<T> List { get; set; }
+}

+ 18 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseRequestId.cs

@@ -0,0 +1,18 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+public abstract class DingtalkResponseRequestId
+{
+    /// <summary>
+    /// 请求ID
+    /// </summary>
+    [JsonProperty("request_id")]
+    [JsonPropertyName("request_id")]
+    public virtual string RequestId { get; set; }
+}

+ 16 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseSuccess.cs

@@ -0,0 +1,16 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+public abstract class DingtalkResponseSuccess
+{
+    /// <summary>
+    /// 接口调用是否成功
+    /// </summary>
+    public virtual bool Success {  get; set; }
+}

+ 16 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/BaseTypes/DingtalkResponseSuccessResult.cs

@@ -0,0 +1,16 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+public abstract class DingtalkResponseSuccessResult<T>:DingtalkResponseSuccess
+{
+    /// <summary>
+    /// 返回结果
+    /// </summary>
+    public T Result;
+}

+ 61 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/CheckinRequest.cs

@@ -0,0 +1,61 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using NewLife;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Checkin;
+
+public class CheckinRequest : IScoped
+{
+    private ICheckinRequestProxy request;
+
+    public CheckinRequest(ICheckinRequestProxy request)
+    {
+        this.request = request;
+    }
+
+    /// <summary>
+    /// 获取用户签到记录
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="useridList">需要查询的用户列表,最大列表长度为10</param>
+    /// <param name="startTime">开始时间</param>
+    /// <param name="endTime">截止时间。如果是取1个人的数据,时间范围最大10天。如果是取多个人的数据,时间范围最大1天。</param>
+    /// <param name="cursor">分页查询的游标,最开始可以传0</param>
+    /// <param name="size">分页查询的每页大小,最大100</param>
+    /// <returns></returns>
+    public async Task<DTO.GetUserRecordResponse> GetUserRecord(string AccessToken, List<string> useridList, DateTime startTime, DateTime endTime, long cursor = 0, long size = 100)
+    {
+        var resStr = await request.GetUserRecord(AccessToken, new DTO.GetUserRecordRequest
+        {
+            UserIdList = useridList.Join(","),
+            StartTime = new DateTimeOffset(startTime).ToUnixTimeMilliseconds(),
+            EndTime = new DateTimeOffset(endTime).ToUnixTimeMilliseconds(),
+            Cursor = cursor,
+            Size = size
+        });
+        var res = resStr.ToObject<DTO.GetUserRecordResponse>();
+        return res;
+    }
+
+    /// <summary>
+    /// 获取部门用户签到记录
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="deptId">部门ID,1表示根部门</param>
+    /// <param name="startTime">开始时间</param>
+    /// <param name="endTime">结束时间</param>
+    /// <param name="offset">支持分页查询,与size参数同时设置时才生效,此参数代表偏移量,从0开始</param>
+    /// <param name="size">支持分页查询,与offset 参数同时设置时才生效,此参数代表分页大小,最大100</param>
+    /// <param name="order">排序。asc:正序,desc:倒序</param>
+    /// <returns></returns>
+    public async Task<DTO.GetDeptRecordResponse> GetDeptRecord(string AccessToken, long deptId, DateTime startTime, DateTime endTime, long offset = 1, long size = 100, string order = "asc")
+    {
+        var resStr = await request.GetDeptRecord(AccessToken, deptId.ToString(),new DateTimeOffset(startTime).ToUnixTimeMilliseconds(),new DateTimeOffset(endTime).ToUnixTimeMilliseconds(), offset, size, order);
+        var res = resStr.ToObject<DTO.GetDeptRecordResponse>();
+        return res;
+    }
+}

+ 52 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/DTO/GetDeptRecordRequest.cs

@@ -0,0 +1,52 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Checkin.DTO;
+
+public class GetDeptRecordRequest
+{
+    /// <summary>
+    /// 部门ID,1表示根部门
+    /// </summary>
+    [JsonProperty("department_id")]
+    [JsonPropertyName("department_id")]
+    public string DepartmentId { get; set; }
+
+    /// <summary>
+    /// 开始时间,Unix时间戳,单位毫秒
+    /// </summary>
+    [JsonProperty("start_time")]
+    [JsonPropertyName("start_time")]
+    public long? StartTime { get; set; }
+
+    /// <summary>
+    /// 截止时间,单位毫秒。如果是取1个人的数据,时间范围最大10天。如果是取多个人的数据,时间范围最大1天。
+    /// </summary>
+    [JsonProperty("end_time")]
+    [JsonPropertyName("end_time")]
+    public long? EndTime { get; set; }
+
+    /// <summary>
+    /// 分页查询的游标,最开始可以传0
+    /// </summary>
+    [JsonProperty("offset")]
+    [JsonPropertyName("offset")]
+    public long? Offset { get; set; }
+
+    /// <summary>
+    /// 分页查询的每页大小,最大100
+    /// </summary>
+    [JsonProperty("size")]
+    [JsonPropertyName("size")]
+    public long? Size { get; set; }
+
+    /// <summary>
+    /// 排序。 asc:正序,desc:倒序
+    /// </summary>
+    public string? Order { get; set; }
+}

+ 72 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/DTO/GetDeptRecordResponse.cs

@@ -0,0 +1,72 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Checkin.DTO;
+
+public class GetDeptRecordResponse:DingtalkResponseError
+{
+    /// <summary>
+    /// 返回结果
+    /// </summary>
+    public List<GetDeptRecordResponseData> Data { get; set; }
+}
+
+public class GetDeptRecordResponseData
+{
+    /// <summary>
+    /// 员工姓名
+    /// </summary>
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 员工userId,不可修改
+    /// </summary>
+    public string UserId { get; set; }
+
+    /// <summary>
+    /// 头像URL
+    /// </summary>
+    public string Avatar { get; set; }
+
+    /// <summary>
+    /// 签到时间,不可修改
+    /// </summary>
+    public long Timestamp { get; set; }
+
+    /// <summary>
+    /// 签到地址
+    /// </summary>
+    public string Place { get; set; }
+
+    /// <summary>
+    /// 签到详细地址
+    /// </summary>
+    public string DetailPlace { get; set; }
+
+    /// <summary>
+    /// 签到备注
+    /// </summary>
+    public string Remark { get; set; }
+
+    /// <summary>
+    /// 签到照片URL列表
+    /// </summary>
+    public List<string> ImageList { get; set; }
+
+    /// <summary>
+    /// 纬度
+    /// </summary>
+    public string Latitude { get; set; }
+
+    /// <summary>
+    /// 经度
+    /// </summary>
+    public string Longitude { get; set; }
+}

+ 47 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/DTO/GetUserRecordRequest.cs

@@ -0,0 +1,47 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Checkin.DTO;
+
+public class GetUserRecordRequest
+{
+    /// <summary>
+    /// 需要查询的用户列表,最大列表长度为10
+    /// </summary>
+    [JsonProperty("userid_list")]
+    [JsonPropertyName("userid_list")]
+    public string UserIdList { get; set; }
+
+    /// <summary>
+    /// 开始时间,Unix时间戳,单位毫秒
+    /// </summary>
+    [JsonProperty("start_time")]
+    [JsonPropertyName("start_time")]
+    public long? StartTime { get; set; }
+
+    /// <summary>
+    /// 截止时间,单位毫秒。如果是取1个人的数据,时间范围最大10天。如果是取多个人的数据,时间范围最大1天。
+    /// </summary>
+    [JsonProperty("end_time")]
+    [JsonPropertyName("end_time")]
+    public long? EndTime { get; set; }
+
+    /// <summary>
+    /// 分页查询的游标,最开始可以传0
+    /// </summary>
+    [JsonProperty("cursor")]
+    [JsonPropertyName("cursor")]
+    public long? Cursor { get; set; }
+
+    /// <summary>
+    /// 分页查询的每页大小,最大100
+    /// </summary>
+    [JsonProperty("size")]
+    [JsonPropertyName("size")]
+    public long? Size { get; set; }
+}

+ 88 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/DTO/GetUserRecordResponse.cs

@@ -0,0 +1,88 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Checkin.DTO;
+
+public class GetUserRecordResponse : DingtalkResponseErrorResultRequestid<GetUserRecordResponseResultDomain>
+{
+}
+
+public class GetUserRecordResponseResultDomain
+{
+    /// <summary>
+    /// 下次查询的游标,为null代表没有更多的数据
+    /// </summary>
+    [JsonProperty("next_cursor")]
+    [JsonPropertyName("next_cursor")]
+    public long? NextCursor { get; set; }
+
+    /// <summary>
+    /// 签到信息
+    /// </summary>
+    [JsonProperty("page_list")]
+    [JsonPropertyName("page_list")]
+    public List<GetUserRecordResponsePageDomain> PageList { get; set; }
+}
+
+public class GetUserRecordResponsePageDomain
+{
+    /// <summary>
+    /// 签到时间,单位毫秒
+    /// </summary>
+    [JsonProperty("checkin_time")]
+    [JsonPropertyName("checkin_time")]
+    public long CheckinTime { get; set; }
+
+    /// <summary>
+    /// 签到照片URL列表
+    /// </summary>
+    [JsonProperty("image_list")]
+    [JsonPropertyName("image_list")]
+    public List<string> ImageList { get; set; }
+
+    /// <summary>
+    /// 签到详细地址
+    /// </summary>
+    [JsonProperty("detail_place")]
+    [JsonPropertyName("detail_place")]
+    public string DetailPlace { get; set; }
+
+    /// <summary>
+    /// 签到备注
+    /// </summary>
+    public string Remark { get; set; }
+
+    /// <summary>
+    /// 签到用户userId
+    /// </summary>
+    public string UserId { get; set; }
+
+    /// <summary>
+    /// 签到地址
+    /// </summary>
+    public string Place { get; set; }
+
+    /// <summary>
+    /// 签到位置经度(暂未开放)
+    /// </summary>
+    public string Longitude { get; set; }
+
+    /// <summary>
+    /// 签到位置维度(暂未开放)
+    /// </summary>
+    public string Latitude { get; set; }
+
+    /// <summary>
+    /// 签到的拜访对象,可以为外部联系人的userId或者用户自己输入的名字
+    /// </summary>
+    [JsonProperty("visit_user")]
+    [JsonPropertyName("visit_user")]
+    public string VisitUser { get; set; }
+}

+ 23 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Checkin/ICheckinRequestProxy.cs

@@ -0,0 +1,23 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Checkin;
+
+public interface ICheckinRequestProxy : IHttpDispatchProxy
+{
+    [Post("https://oapi.dingtalk.com/topapi/checkin/record/get"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> GetUserRecord([QueryString("access_token")] string AccessToken, [Body] DTO.GetUserRecordRequest request);
+
+    [Get(("https://oapi.dingtalk.com/checkin/record")), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> GetDeptRecord([QueryString("access_token")] string AccessToken,
+        [QueryString("department_id")] string DepartmentId,
+        [QueryString("start_time")] long StartTime,
+        [QueryString("end_time")] long EndTime,
+        [QueryString("offset")] long Offset,
+        [QueryString("size")] long Size,
+        [QueryString("order")] string Order
+        );
+}

+ 26 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/GetDeptInfoRequest.cs

@@ -0,0 +1,26 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Department.DTO;
+
+public class GetDeptInfoRequest
+{
+    /// <summary>
+    /// 部门ID,根部门ID为1
+    /// </summary>
+    [JsonProperty("dept_id")]
+    [JsonPropertyName("dept_id")]
+    public long? DeptId { get; set; }
+
+    /// <summary>
+    /// 通讯录语言:zh_CN(默认):中文,en_US:英文
+    /// </summary>
+    [JsonProperty("language")]
+    [JsonPropertyName("language")]
+    public string Language { get; set; }
+}

+ 152 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/GetDeptInfoResponse.cs

@@ -0,0 +1,152 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Department.DTO;
+
+public class GetDeptInfoResponse : DingtalkResponseErrorResultRequestid<GetDeptInfoResponseResultDomain>
+{
+}
+
+public class GetDeptInfoResponseResultDomain
+{
+    /// <summary>
+    /// 部门ID
+    /// </summary>
+    [JsonProperty("dept_id")]
+    [JsonPropertyName("dept_id")]
+    public long DeptId { get; set; }
+
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 父部门ID
+    /// </summary>
+    [JsonProperty("parent_id")]
+    [JsonPropertyName("parent_id")]
+    public long ParentId { get; set; }
+
+    /// <summary>
+    /// 部门标识字段
+    /// </summary>
+    [JsonProperty("source_identifier")]
+    [JsonPropertyName("source_identifier")]
+    public string SourceIdentifier { get; set; }
+
+    /// <summary>
+    /// 是否同步创建一个关联此部门的企业群
+    /// </summary>
+    [JsonProperty("create_dept_group")]
+    [JsonPropertyName("create_dept_group")]
+    public bool CreateDeptGroup { get; set; }
+
+    /// <summary>
+    /// 当部门群已经创建后,是否有新人加入部门会自动加入该群
+    /// </summary>
+    [JsonProperty("auto_add_user")]
+    [JsonPropertyName("auto_add_user")]
+    public bool AutoAddUser { get; set; }
+
+    /// <summary>
+    /// 是否默认同意加入该部门的申请
+    /// </summary>
+    [JsonProperty("auto_approve_apply")]
+    [JsonPropertyName("auto_approve_apply")]
+    public bool AutoApproveApply { get; set; }
+
+    /// <summary>
+    /// 部门是否来自关联组织
+    /// </summary>
+    [JsonProperty("from_union_org")]
+    [JsonPropertyName("from_union_org")]
+    public bool FromUnionOrg { get; set; }
+
+    /// <summary>
+    /// 教育部门标签: campus:校区,period:学段,grade:年级,class:班级
+    /// </summary>
+    public string Tags { get; set; }
+
+    /// <summary>
+    /// 在父部门中的次序值
+    /// </summary>
+    public long Order { get; set; }
+
+    /// <summary>
+    /// 部门群ID
+    /// </summary>
+    [JsonProperty("dept_group_chat_id")]
+    [JsonPropertyName("dept_group_chat_id")]
+    public string DeptGroupChatId { get; set; }
+
+    /// <summary>
+    /// 部门群是否包含子部门
+    /// </summary>
+    [JsonProperty("group_contain_sub_dept")]
+    [JsonPropertyName("group_contain_sub_dept")]
+    public bool GroupContainSubDept { get; set; }
+
+    /// <summary>
+    /// 企业群群主userId
+    /// </summary>
+    [JsonProperty("org_dept_owner")]
+    [JsonPropertyName("org_dept_owner")]
+    public string OrgDeptOwner { get; set; }
+
+    /// <summary>
+    /// 部门的主管userd列表
+    /// </summary>
+    [JsonProperty("dept_manager_userid_list")]
+    [JsonPropertyName("dept_manager_userid_list")]
+    public List<string> DeptManagerUserIdList { get; set; }
+
+    /// <summary>
+    /// 是否限制本部门成员查看通讯录
+    /// </summary>
+    [JsonProperty("outer_dept")]
+    [JsonPropertyName("outer_dept")]
+    public bool OuterDept { get; set; }
+
+    /// <summary>
+    /// 配置的部门员工可见部门Id列表
+    /// </summary>
+    [JsonProperty("outer_permit_depts")]
+    [JsonPropertyName("outer_permit_depts")]
+    public List<long> OuterPermitDepts { get; set; }
+
+    /// <summary>
+    /// 配置的部门员工可见员工userId列表
+    /// </summary>
+    [JsonProperty("outer_permit_users")]
+    [JsonPropertyName("outer_permit_users")]
+    public List<string> OuterPermitUsers { get; set; }
+
+    /// <summary>
+    /// 是否开启隐藏本部门
+    /// </summary>
+    [JsonProperty("hide_dept")]
+    [JsonPropertyName("hide_dept")]
+    public bool HideDept { get; set; }
+
+    /// <summary>
+    /// 隐藏部门的员工userId列表
+    /// </summary>
+    [JsonProperty("user_permits")]
+    [JsonPropertyName("user_permits")]
+    public List<string> UserPermits { get; set; }
+
+    /// <summary>
+    /// 隐藏部门的部门Id列表
+    /// </summary>
+    [JsonProperty("dept_permits")]
+    [JsonPropertyName("dept_permits")]
+    public List<long> DeptPermits { get; set; }
+}

+ 19 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/ListSubIdRequest.cs

@@ -0,0 +1,19 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Department.DTO;
+
+public class ListSubIdRequest
+{
+    /// <summary>
+    /// 父部门ID,根部门传1
+    /// </summary>
+    [JsonProperty("dept_id")]
+    [JsonPropertyName("dept_id")]
+    public long DeptId { get; set; }
+}

+ 25 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/ListSubIdResponse.cs

@@ -0,0 +1,25 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Department.DTO;
+
+public class ListSubIdResponse : DingtalkResponseErrorResultRequestid<ListSubIdResponseResultDomain>
+{
+}
+
+public class ListSubIdResponseResultDomain
+{
+    /// <summary>
+    /// 子部门id列表
+    /// </summary>
+    [JsonProperty("dept_id_list")]
+    [JsonPropertyName("dept_id_list")]
+    public List<long> DeptIdList { get; set; }
+}

+ 26 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/ListSubRequest.cs

@@ -0,0 +1,26 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Department.DTO;
+
+public class ListSubRequest
+{
+    /// <summary>
+    /// 父部门ID
+    /// </summary>
+    [JsonProperty("dept_id")]
+    [JsonPropertyName("dept_id")]
+    public long? DeptId { get; set; }
+
+    /// <summary>
+    /// 通讯录语言:,zh_CN(默认):中文,en_US:英文
+    /// </summary>
+    [JsonProperty("language")]
+    [JsonPropertyName("language")]
+    public string Language { get; set; }
+}

+ 51 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DTO/ListSubResponse.cs

@@ -0,0 +1,51 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Department.DTO;
+
+public class ListSubResponse : DingtalkResponseErrorResultRequestid<List<ListSubResponseResultDomain>>
+{
+}
+
+public class ListSubResponseResultDomain
+{
+    /// <summary>
+    /// 部门ID
+    /// </summary>
+    [JsonProperty("dept_id")]
+    [JsonPropertyName("dept_id")]
+    public long DeptId { get; set; }
+
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 父部门ID
+    /// </summary>
+    [JsonProperty("parent_id")]
+    [JsonPropertyName("parent_id")]
+    public long ParentId { get; set; }
+
+    /// <summary>
+    /// 是否同步创建一个关联此部门的企业群
+    /// </summary>
+    [JsonProperty("create_dept_group")]
+    [JsonPropertyName("create_dept_group")]
+    public bool CreateDeptGroup { get; set; }
+
+    /// <summary>
+    /// 部门群已经创建后,有新人加入部门是否会自动加入该群
+    /// </summary>
+    [JsonProperty("auto_add_user")]
+    [JsonPropertyName("auto_add_user")]
+    public bool AutoAddUser { get; set; }
+}

+ 71 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/DepartmentRequest.cs

@@ -0,0 +1,71 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.Department.DTO;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Department;
+
+public class DepartmentRequest : IScoped
+{
+    private readonly IDepartmentRequestProxy request;
+
+    public DepartmentRequest(IDepartmentRequestProxy _request)
+    {
+        this.request = _request;
+    }
+
+    /// <summary>
+    /// 获取部门详情
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="deptId">部门ID,根部门ID为1</param>
+    /// <param name="language">通讯录语言:zh_CN(默认):中文,en_US:英文</param>
+    /// <returns></returns>
+    public async Task<GetDeptInfoResponse> GetDeptInfo(string AccessToken, long deptId = 1, string language = "zh_CN")
+    {
+        var resStr = await request.GetDeptInfo(AccessToken, new DTO.GetDeptInfoRequest
+        {
+            DeptId = deptId,
+            Language = language
+        });
+        var res = resStr.ToObject<GetDeptInfoResponse>();
+        return res;
+    }
+
+    /// <summary>
+    /// 获取子部门ID列表
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="deptId">父部门ID,根部门传1</param>
+    /// <returns></returns>
+    public async Task<ListSubIdResponse> ListSubId(string AccessToken, long deptId = 1)
+    {
+        var resStr = await request.ListSubId(AccessToken, new DTO.ListSubIdRequest
+        {
+            DeptId = deptId
+        });
+        var res = resStr.ToObject<DTO.ListSubIdResponse>();
+        return res;
+    }
+
+    /// <summary>
+    /// 获取部门列表
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="deptId">父部门ID</param>
+    /// <param name="language">通讯录语言:,zh_CN(默认):中文,en_US:英文</param>
+    /// <returns></returns>
+    public async Task<ListSubResponse> ListSub(string AccessToken, long deptId = 1, string language = "zh_CN")
+    {
+        var resStr = await request.ListSub(AccessToken, new ListSubRequest
+        {
+            DeptId = deptId,
+            Language = language
+        });
+        var res = resStr.ToObject<ListSubResponse>();
+        return res;
+    }
+}

+ 19 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Department/IDepartmentRequestProxy.cs

@@ -0,0 +1,19 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Department;
+
+public interface IDepartmentRequestProxy : IHttpDispatchProxy
+{
+    [Post("https://oapi.dingtalk.com/topapi/v2/department/get"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> GetDeptInfo([QueryString("access_token")] string AccessToken, [Body] DTO.GetDeptInfoRequest request);
+
+    [Post("https://oapi.dingtalk.com/topapi/v2/department/listsubid"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> ListSubId([QueryString("access_token")] string AccessToken, [Body] DTO.ListSubIdRequest request);
+
+    [Post("https://oapi.dingtalk.com/topapi/v2/department/listsub"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> ListSub([QueryString("access_token")] string AccessToken, [Body] DTO.ListSubRequest request);
+}

+ 29 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/DTO/EmployeeQueryonjobRequest.cs

@@ -0,0 +1,29 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.NET.Plugin.DingTalk.RequestProxy.HRM.DTO;
+
+public class EmployeeQueryonjobRequest
+{
+    /// <summary>
+    /// 在职员工状态筛选,可以查询多个状态。不同状态之间使用英文逗号分隔。2:试用期、3:正式、5:待离职、-1:无状态
+    /// </summary>
+    [JsonProperty("status_list")]
+    [JsonPropertyName("status_list")]
+    public string StatusList { get; set; }
+
+    /// <summary>
+    /// 分页游标,从0开始。根据返回结果里的next_cursor是否为空来判断是否还有下一页,且再次调用时offset设置成next_cursor的值。
+    /// </summary>
+    public int Offset { get; set; }
+
+    /// <summary>
+    /// 分页大小,最大50。
+    /// </summary>
+    public int Size { get; set; }
+}

+ 38 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/DTO/EmployeeQueryonjobResponse.cs

@@ -0,0 +1,38 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.NET.Plugin.DingTalk.RequestProxy.HRM.DTO;
+
+public class EmployeeQueryonjobResponse: DingtalkResponseErrorSuccess
+{
+    [JsonProperty("request_id")]
+    [JsonPropertyName("request_id")]
+    public string RequestId { get; set; }
+
+
+    public EmployeeQueryonjobResponseResultDomain Result { get; set; }
+}
+
+public class EmployeeQueryonjobResponseResultDomain
+{
+    /// <summary>
+    /// 查询到的员工userId列表
+    /// </summary>
+    [JsonProperty("data_list")]
+    [JsonPropertyName("data_list")]
+    public List<string> DataList { get; set; }
+
+    /// <summary>
+    /// 下一次分页调用的offset值,当返回结果里没有next_cursor时,表示分页结束。
+    /// </summary>
+    [JsonProperty("next_cursor")]
+    [JsonPropertyName("next_cursor")]
+    public int? NextCursor { get; set; }
+}

+ 32 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/DTO/RosterListsQueryRequest.cs

@@ -0,0 +1,32 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.NET.Plugin.DingTalk.RequestProxy.HRM.DTO;
+public class RosterListsQueryRequest
+{
+    /// <summary>
+    /// 员工的userId列表,多个userid之间使用逗号分隔,一次最多支持传100个值。
+    /// </summary>
+    [JsonProperty("userid_list")]
+    [JsonPropertyName("userid_list")]
+    public string UserIdList { get; set; }
+
+    /// <summary>
+    /// 需要获取的花名册字段field_code值列表,多个字段之间使用逗号分隔,一次最多支持传100个值。
+    /// </summary>
+    [JsonProperty("field_filter_list")]
+    [JsonPropertyName("field_filter_list")]
+    public string FieldFilterList { get; set; }
+
+    /// <summary>
+    /// 应用的AgentId
+    /// </summary>
+    [JsonProperty("agentid")]
+    [JsonPropertyName("agentid")]
+    public long AgentId { get; set; }
+}

+ 81 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/DTO/RosterListsQueryResponse.cs

@@ -0,0 +1,81 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.NET.Plugin.DingTalk.RequestProxy.HRM.DTO;
+
+public class RosterListsQueryResponse
+{
+    /// <summary>
+    /// 结果列表
+    /// </summary>
+    public List<ResultDomain> Result { get; set; }
+
+    public class ResultDomain
+    {
+        /// <summary>
+        /// 企业的corpId
+        /// </summary>
+        public string CorpId { get; set; }
+
+        /// <summary>
+        /// 员工的userId
+        /// </summary>
+        public string UserId { get; set; }
+
+        /// <summary>
+        /// 暂未开放
+        /// </summary>
+        public string UnionId { get; set; }
+
+        /// <summary>
+        /// 返回的字段信息列表
+        /// </summary>
+        public List<FielddataDomain> FieldDataList { get; set; }
+
+        public class FielddataDomain
+        {
+            /// <summary>
+            /// 字段标识
+            /// </summary>
+            public string FieldCode { get; set; }
+
+            /// <summary>
+            /// 字段名称
+            /// </summary>
+            public string FieldName { get; set; }
+
+            /// <summary>
+            /// 分组标识
+            /// </summary>
+            public string GroupId { get; set; }
+
+            /// <summary>
+            /// 字段值列表
+            /// </summary>
+            public List<FieldvalueDomain> FieldValueList { get; set; }
+
+            public class FieldvalueDomain
+            {
+                /// <summary>
+                /// 字段取值,选项类型字段对应选项的key
+                /// </summary>
+                public string Value { get; set; }
+
+                /// <summary>
+                /// 字段展示值,选项类型字段对应选项的value
+                /// </summary>
+                public string Label { get; set; }
+
+                /// <summary>
+                /// 第几条的明细标识,下标从0开始
+                /// </summary>
+                public int ItemIndex { get; set; }
+            }
+        }
+    }
+}

+ 63 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/HrmRequest.cs

@@ -0,0 +1,63 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.NET.Plugin.DingTalk.RequestProxy.HRM.DTO;
+
+using NewLife;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Admin.NET.Plugin.DingTalk.RequestProxy.HRM;
+public class HrmRequest
+{
+    private readonly IHrmRequestProxy request;
+    public HrmRequest(IHrmRequestProxy _request)
+    {
+        request = _request;
+    }
+
+    /// <summary>
+    /// 获取在职员工列表
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="StatusList">在职员工状态筛选,可以查询多个状态。不同状态之间使用英文逗号分隔。2:试用期、3:正式、5:待离职、-1:无状态</param>
+    /// <param name="size">分页大小,最大50</param>
+    /// <param name="offset">分页游标,从0开始。根据返回结果里的next_cursor是否为空来判断是否还有下一页,且再次调用时offset设置成next_cursor的值</param>
+    /// <returns></returns>
+    public async Task<EmployeeQueryonjobResponse> EmployeeQueryonjob(string AccessToken,List<string> StatusList,int size=50,int offset=0)
+    {
+        var resStr = await request.EmployeeQueryonjob(AccessToken, new EmployeeQueryonjobRequest
+        {
+            StatusList = StatusList.Join(),
+            Size = size,
+            Offset = offset
+        });
+        return resStr.ToObject<EmployeeQueryonjobResponse>();
+    }
+
+    /// <summary>
+    /// 获取员工花名册字段信息
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="UseridList">员工的 userId 列表,一次最多支持传100个值</param>
+    /// <param name="FieldFilterList">需要获取的花名册字段field_code值列表,一次最多支持传100个值</param>
+    /// <param name="AgentId">应用的AgentId</param>
+    /// <returns></returns>
+    public async Task<RosterListsQueryResponse> RosterListsQuery(string AccessToken,List<string> UseridList,List<string> FieldFilterList,long AgentId)
+    {
+        var resStr = await request.RosterListsQuery(AccessToken, new RosterListsQueryRequest
+        {
+            UserIdList = UseridList.Join(),
+            FieldFilterList = FieldFilterList.Join(),
+            AgentId = AgentId
+        });
+        return resStr.ToObject<RosterListsQueryResponse>();
+    }
+}

+ 19 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/HRM/IHrmRequestProxy.cs

@@ -0,0 +1,19 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.NET.Plugin.DingTalk.RequestProxy.HRM.DTO;
+
+namespace Admin.NET.Plugin.DingTalk.RequestProxy.HRM;
+
+public interface IHrmRequestProxy : IHttpDispatchProxy
+{
+    [Post("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/queryonjob"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> EmployeeQueryonjob([QueryString("access_token")] string AccessToken, [Body] DTO.EmployeeQueryonjobRequest request);
+
+    [Post("https://oapi.dingtalk.com/topapi/smartwork/hrm/employee/v2/list")]
+    Task<string> RosterListsQuery([Headers("x-acs-dingtalk-access-token")] string AccessToken,
+    [Body] RosterListsQueryRequest request);
+}

+ 463 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Message/DTO/SendCorpConversationRequest.cs

@@ -0,0 +1,463 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Newtonsoft.Json.Converters;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Message.DTO;
+
+public class SendCorpConversationRequest
+{
+    /// <summary>
+    /// 发送消息时使用的微应用的AgentID
+    /// </summary>
+    [JsonProperty("agent_id")]
+    [JsonPropertyName("agent_id")]
+    public long? AgentId { get; set; }
+
+    /// <summary>
+    /// 接收者的userid列表,最大用户列表长度100
+    /// </summary>
+    [JsonProperty("userid_list")]
+    [JsonPropertyName("userid_list")]
+    public string? UserIdList { get; set; }
+
+    /// <summary>
+    /// 接收者的部门id列表,最大列表长度20
+    /// </summary>
+    [JsonProperty("dept_id_list")]
+    [JsonPropertyName("dept_id_list")]
+    public string? DeptIdList { get; set; }
+
+    /// <summary>
+    /// 是否发送给企业全部用户
+    /// </summary>
+    [JsonProperty("to_all_user")]
+    [JsonPropertyName("to_all_user")]
+    public bool? ToAllUser { get; set; }
+
+    /// <summary>
+    /// 消息内容,最长不超过2048个字节
+    /// </summary>
+    [JsonProperty("msg")]
+    [JsonPropertyName("msg")]
+    public MsgDomain Msg { get; set; }
+}
+
+public class MsgDomain
+{
+    /// <summary>
+    /// 消息类型
+    /// </summary>
+    [JsonProperty("msgtype")]
+    [JsonPropertyName("msgtype")]
+    [Newtonsoft.Json.JsonConverter(typeof(StringEnumConverter))]
+    public MsgTypeEnum MsgType { get; set; }
+
+    /// <summary>
+    /// 文本消息
+    /// </summary>
+    [JsonProperty("text")]
+    [JsonPropertyName("text")]
+    public MsgTextDomain? Text { get; set; }
+
+    /// <summary>
+    /// 图片消息
+    /// </summary>
+    [JsonProperty("image")]
+    [JsonPropertyName("image")]
+    public MsgImageDomain? Image { get; set; }
+
+    /// <summary>
+    /// 语音消息
+    /// </summary>
+    [JsonProperty("voice")]
+    [JsonPropertyName("voice")]
+    public MsgVoiceDomain? Voice { get; set; }
+
+    /// <summary>
+    /// 文件消息
+    /// </summary>
+    [JsonProperty("file")]
+    [JsonPropertyName("file")]
+    public MsgVoiceDomain? File { get; set; }
+
+    /// <summary>
+    /// 链接消息
+    /// </summary>
+    [JsonProperty("link")]
+    [JsonPropertyName("link")]
+    public MsgLinkDomain? Link { get; set; }
+
+    /// <summary>
+    /// OA消息
+    /// </summary>
+    [JsonProperty("oa")]
+    [JsonPropertyName("oa")]
+    public MsgOaDomain? Oa { get; set; }
+
+    /// <summary>
+    /// markdown消息
+    /// </summary>
+    [JsonProperty("markdown")]
+    [JsonPropertyName("markdown")]
+    public MsgMarkdownDomain? Markdown { get; set; }
+
+    /// <summary>
+    /// 卡片消息
+    /// </summary>
+    [JsonProperty("action_card")]
+    [JsonPropertyName("action_card")]
+    public MsgActionCardDomain? ActionCard { get; set; }
+}
+
+public enum MsgTypeEnum
+{
+    text, image, voice, file, link, oa, markdown, action_card
+}
+
+/// <summary>
+/// 文本消息
+/// </summary>
+public class MsgTextDomain
+{
+    /// <summary>
+    /// 消息内容,建议500字符以内
+    /// </summary>
+    [JsonProperty("content")]
+    [JsonPropertyName("content")]
+    public string Content { get; set; }
+}
+
+/// <summary>
+/// 图片消息
+/// </summary>
+public class MsgImageDomain
+{
+    /// <summary>
+    /// 媒体文件mediaid,建议宽600像素 x 400像素,宽高比3 : 2
+    /// </summary>
+    [JsonProperty("media_id")]
+    [JsonPropertyName("media_id")]
+    public string MediaId { get; set; }
+}
+
+/// <summary>
+/// 语音消息
+/// </summary>
+public class MsgVoiceDomain
+{
+    /// <summary>
+    /// 媒体文件ID
+    /// </summary>
+    [JsonProperty("media_id")]
+    [JsonPropertyName("media_id")]
+    public string MediaId { get; set; }
+
+    /// <summary>
+    /// 正整数,小于60,表示音频时长
+    /// </summary>
+    [JsonProperty("duration")]
+    [JsonPropertyName("duration")]
+    public string Duration { get; set; }
+}
+
+/// <summary>
+/// 文件消息
+/// </summary>
+public class MsgFileDomain
+{
+    /// <summary>
+    /// 媒体文件ID,引用的媒体文件最大10MB
+    /// </summary>
+    [JsonProperty("media_id")]
+    [JsonPropertyName("media_id")]
+    public string MediaId { get; set; }
+}
+
+/// <summary>
+/// 链接消息
+/// </summary>
+public class MsgLinkDomain
+{
+    /// <summary>
+    /// 消息点击链接地址,当发送消息为小程序时支持小程序跳转链接
+    /// </summary>
+    [JsonProperty("messageUrl")]
+    [JsonPropertyName("messageUrl")]
+    public string MessageUrl { get; set; }
+
+    [JsonProperty("picUrl")]
+    [JsonPropertyName("picUrl")]
+    public string PicUrl { get; set; }
+
+    /// <summary>
+    /// 消息标题,建议100字符以内
+    /// </summary>
+    [JsonProperty("title")]
+    [JsonPropertyName("title")]
+    public string Title { get; set; }
+
+    /// <summary>
+    /// 消息描述,建议500字符以内
+    /// </summary>
+    [JsonProperty("text")]
+    [JsonPropertyName("text")]
+    public string Text { get; set; }
+}
+
+/// <summary>
+/// OA消息
+/// </summary>
+public class MsgOaDomain
+{
+    /// <summary>
+    /// 消息点击链接地址,当发送消息为小程序时支持小程序跳转链接
+    /// </summary>
+    [JsonProperty("message_url")]
+    [JsonPropertyName("message_url")]
+    public string MessageUrl { get; set; }
+
+    /// <summary>
+    /// PC端点击消息时跳转到的地址
+    /// </summary>
+    [JsonProperty("pc_message_url")]
+    [JsonPropertyName("pc_message_url")]
+    public string? PcMessageUrl { get; set; }
+
+    /// <summary>
+    /// 消息头部内容
+    /// </summary>
+    [JsonProperty("head")]
+    [JsonPropertyName("head")]
+    public MsgOaHeadDomain Head { get; set; }
+
+    /// <summary>
+    /// 消息体
+    /// </summary>
+    [JsonProperty("body")]
+    [JsonPropertyName("body")]
+    public MsgOaBodyDomain Body { get; set; }
+
+    /// <summary>
+    /// 消息状态栏,只支持接收者的userid列表,userid最多不能超过5个人
+    /// </summary>
+    [JsonProperty("status_bar")]
+    [JsonPropertyName("status_bar")]
+    public MsgOaStatusBarDomain? StatusBar { get; set; }
+
+    public class MsgOaHeadDomain
+    {
+        /// <summary>
+        /// 消息头部的背景颜色。长度限制为8个英文字符,其中前2为表示透明度,后6位表示颜色值。不要添加0x。
+        /// </summary>
+        [JsonProperty("bgcolor")]
+        [JsonPropertyName("bgcolor")]
+        public string Bgcolor { get; set; }
+
+        /// <summary>
+        /// 消息的头部标题
+        /// </summary>
+        [JsonProperty("text")]
+        [JsonPropertyName("text")]
+        public string Text { get; set; }
+    }
+
+    public class MsgOaStatusBarDomain
+    {
+        /// <summary>
+        /// 状态栏文案
+        /// </summary>
+        [JsonProperty("status_value")]
+        [JsonPropertyName("status_value")]
+        public string StatusValue { get; set; }
+
+        /// <summary>
+        /// 状态栏背景色,默认为黑色,推荐0xFF加六位颜色值
+        /// </summary>
+        [JsonProperty("status_bg")]
+        [JsonPropertyName("status_bg")]
+        public string StatusBg { get; set; }
+    }
+
+    public class MsgOaBodyDomain
+    {
+        /// <summary>
+        /// 消息体的标题,建议50个字符以内
+        /// </summary>
+        [JsonProperty("title")]
+        [JsonPropertyName("title")]
+        public string? Title { get; set; }
+
+        /// <summary>
+        /// 消息体的表单,最多显示6个,超过会被隐藏
+        /// </summary>
+        [JsonProperty("form")]
+        [JsonPropertyName("form")]
+        public MsgOaBodyFormDomain[]? Form { get; set; }
+
+        /// <summary>
+        /// 单行富文本信息
+        /// </summary>
+        [JsonProperty("rich")]
+        [JsonPropertyName("rich")]
+        public MsgOaBodyRichDomain? Rich { get; set; }
+
+        /// <summary>
+        /// 消息体的内容,最多显示3行
+        /// </summary>
+        [JsonProperty("content")]
+        [JsonPropertyName("content")]
+        public string? Content { get; set; }
+
+        /// <summary>
+        /// 消息体中的图片,支持图片资源@mediaId。建议宽600像素 x 400像素,宽高比3 : 2
+        /// </summary>
+        [JsonProperty("image")]
+        [JsonPropertyName("image")]
+        public string? Image { get; set; }
+
+        /// <summary>
+        /// 自定义的附件数目。此数字仅供显示,钉钉不作验证
+        /// </summary>
+        [JsonProperty("file_count")]
+        [JsonPropertyName("file_count")]
+        public string? FileCount { get; set; }
+
+        /// <summary>
+        /// 自定义的作者名字
+        /// </summary>
+        [JsonProperty("author")]
+        [JsonPropertyName("author")]
+        public string? Author { get; set; }
+    }
+
+    public class MsgOaBodyRichDomain
+    {
+        /// <summary>
+        /// 单行富文本信息的数目
+        /// </summary>
+        [JsonProperty("num")]
+        [JsonPropertyName("num")]
+        public string? Num { get; set; }
+
+        /// <summary>
+        /// 单行富文本信息的单位
+        /// </summary>
+        [JsonProperty("unit")]
+        [JsonPropertyName("unit")]
+        public string? Unit { get; set; }
+    }
+
+    public class MsgOaBodyFormDomain
+    {
+        /// <summary>
+        /// 消息体的关键字
+        /// </summary>
+        [JsonProperty("key")]
+        [JsonPropertyName("key")]
+        public string? Key { get; set; }
+
+        /// <summary>
+        /// 消息体的关键字对应的值
+        /// </summary>
+        [JsonProperty("value")]
+        [JsonPropertyName("value")]
+        public string? Value { get; set; }
+    }
+}
+
+/// <summary>
+/// markdown消息
+/// </summary>
+public class MsgMarkdownDomain
+{
+    /// <summary>
+    /// 首屏会话透出的展示内容
+    /// </summary>
+    [JsonProperty("title")]
+    [JsonPropertyName("title")]
+    public string Title { get; set; }
+
+    /// <summary>
+    /// markdown格式的消息,最大不超过5000字符
+    /// </summary>
+    [JsonProperty("text")]
+    [JsonPropertyName("text")]
+    public string Text { get; set; }
+}
+
+/// <summary>
+/// 卡片消息
+/// </summary>
+public class MsgActionCardDomain
+{
+    /// <summary>
+    /// 透出到会话列表和通知的文案
+    /// </summary>
+    [JsonProperty("title")]
+    [JsonPropertyName("title")]
+    public string? Title { get; set; }
+
+    /// <summary>
+    /// 消息内容,支持markdown,语法参考标准markdown语法。建议1000个字符以内
+    /// </summary>
+    [JsonProperty("markdown")]
+    [JsonPropertyName("markdown")]
+    public string Markdown { get; set; }
+
+    /// <summary>
+    /// 使用整体跳转ActionCard样式时的标题。必须与single_url同时设置,最长20个字符
+    /// </summary>
+    [JsonProperty("single_title")]
+    [JsonPropertyName("single_title")]
+    public string? SingleTitle { get; set; }
+
+    /// <summary>
+    /// 消息点击链接地址,当发送消息为小程序时支持小程序跳转链接,最长500个字符
+    /// </summary>
+    [JsonProperty("single_url")]
+    [JsonPropertyName("single_url")]
+    public string? SingleUrl { get; set; }
+
+    /// <summary>
+    /// 使用独立跳转ActionCard样式时的按钮排列方式:0:竖直排列,1:横向排列。必须与btn_json_list同时设置
+    /// </summary>
+    [JsonProperty("btn_orientation")]
+    [JsonPropertyName("btn_orientation")]
+    public BenOrientationEnum? BtnOrientation { get; set; }
+
+    public enum BenOrientationEnum
+    {
+        竖直排列,
+        横向排列
+    }
+
+    /// <summary>
+    /// 使用独立跳转ActionCard样式时的按钮列表;必须与btn_orientation同时设置,且长度不超过1000字符
+    /// </summary>
+    [JsonProperty("btn_json_list")]
+    [JsonPropertyName("btn_json_list")]
+    public MsgActionCardBtnJsonListDomain[]? BtnJsonList { get; set; }
+
+    public class MsgActionCardBtnJsonListDomain
+    {
+        /// <summary>
+        /// 使用独立跳转ActionCard样式时的按钮的标题,最长20个字符
+        /// </summary>
+        [JsonProperty("title")]
+        [JsonPropertyName("title")]
+        public string Title { get; set; }
+
+        /// <summary>
+        /// 使用独立跳转ActionCard样式时的跳转链接,最长700个字符
+        /// </summary>
+        [JsonProperty("action_url")]
+        [JsonPropertyName("action_url")]
+        public string ActionUrl { get; set; }
+    }
+}

+ 21 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Message/DTO/SendCorpConversationResponse.cs

@@ -0,0 +1,21 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Message.DTO;
+
+public class SendCorpConversationResponse:DingtalkResponseErrorRequestId
+{
+    /// <summary>
+    /// 创建的异步发送任务ID
+    /// </summary>
+    [JsonProperty("task_id")]
+    [JsonPropertyName("task_id")]
+    public long TaskId { get; set; }
+}

+ 15 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Message/IMessageRequestProxy.cs

@@ -0,0 +1,15 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.Message.DTO;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Message;
+
+public interface IMessageRequestProxy : IHttpDispatchProxy
+{
+    [Post("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> SendCorpConversation([QueryString("access_token")] string AccessToken, [Body] SendCorpConversationRequest request);
+}

+ 75 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Message/MessageRequest.cs

@@ -0,0 +1,75 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.Message.DTO;
+
+using NewLife;
+
+using static Admin.Net.Plugin.DingTalk.RequestProxy.Message.DTO.MsgActionCardDomain;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Message;
+
+public class MessageRequest : IScoped
+{
+    private IMessageRequestProxy request;
+
+    public MessageRequest(IMessageRequestProxy request)
+    {
+        this.request = request;
+    }
+
+    public async Task<SendCorpConversationResponse> SendCorpMarkdown(string AccessToken, long agentId, List<string>? useridList, List<long> deptidList
+        , string mdTitle, string mdText, bool toAllUser = false)
+    {
+        var resStr = await request.SendCorpConversation(AccessToken, new SendCorpConversationRequest
+        {
+            AgentId = agentId,
+            UserIdList = useridList?.ToArray().Join(),
+            DeptIdList = deptidList?.ToArray().Join(),
+            ToAllUser = toAllUser,
+            Msg = new MsgDomain
+            {
+                MsgType = MsgTypeEnum.markdown,
+                Markdown = new MsgMarkdownDomain
+                {
+                    Title = mdTitle,
+                    Text = mdText,
+                }
+            }
+        });
+        var res = resStr.ToObject<SendCorpConversationResponse>();
+        return res;
+    }
+
+    public async Task<SendCorpConversationResponse> SendCorpActionCard(string AccessToken, long agentId, List<string>? useridList, List<long>? deptidList
+        , string markdown, string? title = null, string? singleTitle = null, string? singleUrl = null
+        , BenOrientationEnum? btnOrientation = null, MsgActionCardBtnJsonListDomain[]? btnJsonList = null
+        , bool toAllUser = false)
+    {
+        var resStr = await request.SendCorpConversation(AccessToken, new SendCorpConversationRequest
+        {
+            AgentId = agentId,
+            UserIdList = useridList?.ToArray().Join(),
+            DeptIdList = deptidList?.ToArray().Join(),
+            ToAllUser = toAllUser,
+            Msg = new MsgDomain
+            {
+                MsgType = MsgTypeEnum.action_card,
+                ActionCard = new MsgActionCardDomain
+                {
+                    Markdown = markdown,
+                    Title = title,
+                    SingleTitle = singleTitle,
+                    SingleUrl = singleUrl,
+                    BtnOrientation = btnOrientation,
+                    BtnJsonList = btnJsonList
+                }
+            }
+        });
+        var res = resStr.ToObject<SendCorpConversationResponse>();
+        return res;
+    }
+}

+ 26 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/DTO/GetAccessTokenRequest.cs

@@ -0,0 +1,26 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Top.DTO;
+
+public class GetAccessTokenRequest
+{
+    /// <summary>
+    /// 已创建的企业内部应用的AppKey
+    /// </summary>
+    [JsonProperty("appKey")]
+    [JsonPropertyName("appKey")]
+    public string AppKey { get; set; }
+
+    /// <summary>
+    /// 已创建的企业内部应用的AppSecret
+    /// </summary>
+    [JsonProperty("appSecret")]
+    [JsonPropertyName("appSecret")]
+    public string AppSecret { get; set; }
+}

+ 22 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/DTO/GetAccessTokenResponse.cs

@@ -0,0 +1,22 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Top.DTO;
+
+public class GetAccessTokenResponse
+{
+    /// <summary>
+    /// 生成的accessToken
+    /// </summary>
+    public string AccessToken { get; set; }
+
+    /// <summary>
+    /// accessToken的过期时间,单位秒
+    /// </summary>
+    public long ExpireIn { get; set; }
+}

+ 23 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/DTO/GetApiTicketResponse.cs

@@ -0,0 +1,23 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Top.DTO;
+
+public class GetApiTicketResponse
+{
+    /// <summary>
+    /// jsapiTicket过期时间,单位秒
+    /// </summary>
+    [JsonProperty("expires_in")]
+    [JsonPropertyName("expires_in")]
+    public long ExpiresIn { get; set; }
+
+    [JsonProperty("jsapiTicket")]
+    [JsonPropertyName("jsapiTicket")]
+    public string JsApiTicket { get; set; }
+}

+ 19 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/DTO/GetUserInfoRequest.cs

@@ -0,0 +1,19 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Top.DTO;
+
+public class GetUserInfoRequest
+{
+    /// <summary>
+    /// 免登授权码
+    /// </summary>
+    [JsonProperty("code")]
+    [JsonPropertyName("code")]
+    public string Code { get; set; }
+}

+ 60 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/DTO/GetUserInfoResponse.cs

@@ -0,0 +1,60 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Top.DTO;
+
+public class GetUserInfoResponse : DingtalkResponseErrorResultRequestid<UserGetByCodeResponse>
+{
+}
+
+public class UserGetByCodeResponse
+{
+    /// <summary>
+    /// 用户的userId
+    /// </summary>
+    [JsonProperty("userid")]
+    [JsonPropertyName("userid")]
+    public string UserId { get; set; }
+
+    /// <summary>
+    /// 设备ID
+    /// </summary>
+    [JsonProperty("device_id")]
+    [JsonPropertyName("device_id")]
+    public string DeviceId { get; set; }
+
+    /// <summary>
+    /// 是否是管理员
+    /// </summary>
+    public bool Sys { get; set; }
+
+    /// <summary>
+    /// 级别。1:主管理员,2:子管理员,100:老板,0:其他(如普通员工)
+    /// </summary>
+    [JsonProperty("sys_level")]
+    [JsonPropertyName("sys_level")]
+    public long SysLevel { get; set; }
+
+    /// <summary>
+    /// 用户关联的unionId
+    /// </summary>
+    [JsonProperty("associated_unionid")]
+    [JsonPropertyName("associated_unionid")]
+    public string AssociatedUnionid { get; set; }
+
+    /// <summary>
+    /// 用户unionId
+    /// </summary>
+    public string Unionid { get; set; }
+
+    /// <summary>
+    /// 用户名字
+    /// </summary>
+    public string Name { get; set; }
+}

+ 21 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/ITopRequestProxy.cs

@@ -0,0 +1,21 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip.DTO;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Top;
+
+public interface ITopRequestProxy : IHttpDispatchProxy
+{
+    [Post("https://oapi.dingtalk.com/topapi/v2/user/getuserinfo"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> GetUserInfo([QueryString("access_token")] string AccessToken, [Body] DTO.GetUserInfoRequest request);
+
+    [Post("https://api.dingtalk.com/v1.0/oauth2/accessToken"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> GetAccessToken([Body] DTO.GetAccessTokenRequest request);
+
+    [Post("https://api.dingtalk.com/v1.0/oauth2/jsapiTickets"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> GetApiTickets([Headers("x-acs-dingtalk-access-token")] string AccessToken);
+}

+ 63 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/Top/TopRequest.cs

@@ -0,0 +1,63 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.AliTrip.DTO;
+using Admin.Net.Plugin.DingTalk.RequestProxy.Top.DTO;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.Top;
+
+public class TopRequest : IScoped
+{
+    private ITopRequestProxy request;
+
+    public TopRequest(ITopRequestProxy request)
+    {
+        this.request = request;
+    }
+
+    /// <summary>
+    /// 通过免登码获取用户信息
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="code">免登授权码</param>
+    /// <returns></returns>
+    public async Task<GetUserInfoResponse> GetUserInfo(string AccessToken, string code)
+    {
+        var resStr = await request.GetUserInfo(AccessToken, new GetUserInfoRequest { Code = code });
+        var res = resStr.ToObject<GetUserInfoResponse>();
+        return res;
+    }
+
+    /// <summary>
+    /// 获取企业内部应用的accessToken
+    /// </summary>
+    /// <param name="appKey">已创建的企业内部应用的AppKey</param>
+    /// <param name="appSecret">已创建的企业内部应用的AppSecret</param>
+    /// <returns></returns>
+    public async Task<GetAccessTokenResponse> GetAccessToken(string appKey, string appSecret)
+    {
+        var resStr = await request.GetAccessToken(new GetAccessTokenRequest
+        {
+            AppKey = appKey,
+            AppSecret = appSecret
+        });
+        var res = resStr.ToObject<GetAccessTokenResponse>();
+        return res;
+    }
+
+    /// <summary>
+    /// 获取jsapiTicket
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <returns></returns>
+    public async Task<GetApiTicketResponse> GetJsApiTicket(string AccessToken)
+    {
+        var resStr = await request.GetApiTickets(AccessToken);
+        var res = resStr.ToObject<GetApiTicketResponse>();
+        return res;
+    }
+
+}

+ 25 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/RoleListRequest.cs

@@ -0,0 +1,25 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User.DTO;
+public  class RoleListRequest
+{
+    /// <summary>
+    /// 支持分页查询,与offset参数同时设置时才生效,此参数代表分页大小,默认值20,最大值200。
+    /// </summary>
+    [JsonProperty("size")]
+    [JsonPropertyName("size")]
+    public int Size {  get; set; }
+
+    /// <summary>
+    /// 支持分页查询,与size参数同时设置时才生效,此参数代表偏移量,偏移量从0开始。
+    /// </summary>
+    [JsonProperty("offset")]
+    [JsonPropertyName("offset")]
+    public int Offset {  get; set; }
+}

+ 59 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/RoleListResponse.cs

@@ -0,0 +1,59 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User.DTO;
+
+public class RoleListResponse : DingtalkResponseErrorResultRequestid<RoleListResultDomain>
+{
+}
+
+public class RoleListResultDomain
+{
+    /// <summary>
+    /// 是否还有更多数据
+    /// </summary>
+    public bool HasMore { get; set; }
+
+    /// <summary>
+    /// 角色组列表
+    /// </summary>
+    public List<OpenRoleGroup> List { get; set; }
+
+    public class OpenRoleGroup
+    {
+        /// <summary>
+        /// 角色组ID
+        /// </summary>
+        public long GroupId { get; set; }
+
+        /// <summary>
+        /// 角色组名称
+        /// </summary>
+        public string Name { get; set; }
+
+        /// <summary>
+        /// 角色列表
+        /// </summary>
+        public List<OpenRole> Roles { get; set; }
+
+        public class OpenRole
+        {
+            /// <summary>
+            /// 角色ID
+            /// </summary>
+            public long Id { get; set; }
+
+            /// <summary>
+            /// 角色名称
+            /// </summary>
+            public string Name { get; set; }
+        }
+    }
+}

+ 26 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserDetailRequest.cs

@@ -0,0 +1,26 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User.DTO;
+
+public class UserDetailRequest
+{
+    /// <summary>
+    /// 用户的userId
+    /// </summary>
+    [JsonProperty("userid")]
+    [JsonPropertyName("userid")]
+    public string UserId { get; set; }
+
+    /// <summary>
+    /// 通讯录语言。 zh_CN:中文(默认值)。en_US:英文
+    /// </summary>
+    [JsonProperty("language")]
+    [JsonPropertyName("language")]
+    public string Language { get; set; }
+}

+ 286 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserDetailResponse.cs

@@ -0,0 +1,286 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User.DTO;
+
+public class UserDetailResponse : DingtalkResponseErrorResultRequestid<UserDetailResponseResultDomain>
+{
+}
+
+public class UserDetailResponseResultDomain
+{
+    /// <summary>
+    /// 员工的userId
+    /// </summary>
+    public string UserId { get; set; }
+
+    /// <summary>
+    /// 员工在当前开发者企业账号范围内的唯一标识
+    /// </summary>
+    public string Unionid { get; set; }
+
+    /// <summary>
+    /// 员工姓名
+    /// </summary>
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 头像
+    /// </summary>
+    public string Avatar { get; set; }
+
+    /// <summary>
+    /// 国际电话区号
+    /// </summary>
+    [JsonProperty("state_code")]
+    [JsonPropertyName("state_code")]
+    public string StateCode { get; set; }
+
+    /// <summary>
+    /// 员工的直属主管
+    /// </summary>
+    [JsonProperty("manager_userid")]
+    [JsonPropertyName("manager_userid")]
+    public string ManagerUserId { get; set; }
+
+    /// <summary>
+    /// 手机号码
+    /// </summary>
+    public string Mobile { get; set; }
+
+    /// <summary>
+    /// 是否号码隐藏
+    /// </summary>
+    [JsonProperty("hide_mobile")]
+    [JsonPropertyName("hide_mobile")]
+    public bool HideMobile { get; set; }
+
+    /// <summary>
+    /// 分机号
+    /// </summary>
+    public string Telephone { get; set; }
+
+    /// <summary>
+    /// 员工工号
+    /// </summary>
+    [JsonProperty("job_number")]
+    [JsonPropertyName("job_number")]
+    public string JobNumber { get; set; }
+
+    /// <summary>
+    /// 职位
+    /// </summary>
+    public string Title { get; set; }
+
+    /// <summary>
+    /// 员工邮箱
+    /// </summary>
+    public string Email { get; set; }
+
+    /// <summary>
+    /// 办公地点
+    /// </summary>
+    [JsonProperty("work_place")]
+    [JsonPropertyName("work_place")]
+    public string WorkPlace { get; set; }
+
+    /// <summary>
+    /// 备注
+    /// </summary>
+    public string Remark { get; set; }
+
+    /// <summary>
+    /// 是否为企业账号
+    /// </summary>
+    [JsonProperty("exclusive_account")]
+    [JsonPropertyName("exclusive_account")]
+    public bool ExclusiveAccount { get; set; }
+
+    /// <summary>
+    /// 员工的企业邮箱。如果员工的企业邮箱没有开通,返回信息中不包含该数据
+    /// </summary>
+    [JsonProperty("org_email")]
+    [JsonPropertyName("org_email")]
+    public string OrgEmail { get; set; }
+
+    /// <summary>
+    /// 所属部门id列表
+    /// </summary>
+    [JsonProperty("dept_id_list")]
+    [JsonPropertyName("dept_id_list")]
+    public List<long> DeptIdList { get; set; }
+
+    /// <summary>
+    /// 员工在对应的部门中的排序
+    /// </summary>
+    [JsonProperty("dept_order_list")]
+    [JsonPropertyName("dept_order_list")]
+    public List<DeptOrderDomain> DeptOrderList { get; set; }
+
+    /// <summary>
+    /// 扩展属性,最大长度2000个字符
+    /// </summary>
+    public string Extension { get; set; }
+
+    /// <summary>
+    /// 入职时间,Unix时间戳,单位毫秒
+    /// </summary>
+    [JsonProperty("hired_date")]
+    [JsonPropertyName("hired_date")]
+    public long HiredDate { get; set; }
+
+    /// <summary>
+    /// 是否激活了钉钉
+    /// </summary>
+    public bool Active { get; set; }
+
+    /// <summary>
+    /// 是否完成了实名认证
+    /// </summary>
+    [JsonProperty("real_authed")]
+    [JsonPropertyName("real_authed")]
+    public bool RealAuthed { get; set; }
+
+    /// <summary>
+    /// 是否为企业的高管
+    /// </summary>
+    public bool Senior { get; set; }
+
+    /// <summary>
+    /// 是否为企业的管理员
+    /// </summary>
+    public bool Admin { get; set; }
+
+    /// <summary>
+    /// 是否为企业的老板
+    /// </summary>
+    public bool Boss { get; set; }
+
+    /// <summary>
+    /// 员工所在部门信息及是否是领导
+    /// </summary>
+    [JsonProperty("leader_in_dept")]
+    [JsonPropertyName("leader_in_dept")]
+    public List<DeptLeaderDomain> LeaderInDept { get; set; }
+
+    /// <summary>
+    /// 角色列表
+    /// </summary>
+    [JsonProperty("role_list")]
+    [JsonPropertyName("role_list")]
+    public List<UserRoleDomain> RoleList { get; set; }
+
+    /// <summary>
+    /// 当用户来自于关联组织时的关联信息
+    /// </summary>
+    [JsonProperty("union_emp_ext")]
+    [JsonPropertyName("union_emp_ext")]
+    public UnionEmpExtDomain UnionEmpExt { get; set; }
+}
+
+
+public class DeptOrderDomain
+{
+    /// <summary>
+    /// 部门id
+    /// </summary>
+    [JsonProperty("dept_id")]
+    [JsonPropertyName("dept_id")]
+    public long DeptId { get; set; }
+
+    /// <summary>
+    /// 员工在部门中的排序
+    /// </summary>
+    [JsonProperty("order")]
+    [JsonPropertyName("order")]
+    public long Order { get; set; }
+}
+
+public class DeptLeaderDomain
+{
+    /// <summary>
+    /// 部门ID
+    /// </summary>
+    [JsonProperty("dept_id")]
+    [JsonPropertyName("dept_id")]
+    public long DeptId { get; set; }
+
+    /// <summary>
+    /// 是否是领导
+    /// </summary>
+    [JsonProperty("leader")]
+    [JsonPropertyName("leader")]
+    public bool Leader { get; set; }
+}
+
+public class UserRoleDomain
+{
+    /// <summary>
+    /// 角色ID
+    /// </summary>
+    [JsonProperty("id")]
+    [JsonPropertyName("id")]
+    public long Id { get; set; }
+
+    /// <summary>
+    /// 角色名称
+    /// </summary>
+    [JsonProperty("name")]
+    [JsonPropertyName("name")]
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 角色组名称
+    /// </summary>
+    [JsonProperty("group_name")]
+    [JsonPropertyName("group_name")]
+    public string GroupName { get; set; }
+}
+
+public class UnionEmpMapVoDomain
+{
+    /// <summary>
+    /// 关联分支组织中的员工userId
+    /// </summary>
+    [JsonProperty("userid")]
+    [JsonPropertyName("userid")]
+    public string Userid { get; set; }
+
+    /// <summary>
+    /// 关联分支组织的企业corpId
+    /// </summary>
+    [JsonProperty("corp_id")]
+    [JsonPropertyName("corp_id")]
+    public string CorpId { get; set; }
+}
+
+public class UnionEmpExtDomain
+{
+    /// <summary>
+    /// 员工的userId
+    /// </summary>
+    [JsonProperty("userid")]
+    [JsonPropertyName("userid")]
+    public string Userid { get; set; }
+
+    /// <summary>
+    /// 当前用户所属的组织的企业corpId
+    /// </summary>
+    [JsonProperty("corp_id")]
+    [JsonPropertyName("corp_id")]
+    public string CorpId { get; set; }
+
+    /// <summary>
+    /// 关联映射关系
+    /// </summary>
+    [JsonProperty("union_emp_map_list")]
+    [JsonPropertyName("union_emp_map_list")]
+    public List<UnionEmpMapVoDomain> UnionEmpMapList { get; set; }
+}

+ 19 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListIdRequest.cs

@@ -0,0 +1,19 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User.DTO;
+
+public class UserListIdRequest
+{
+    /// <summary>
+    /// 部门deptId
+    /// </summary>
+    [JsonProperty("dept_id")]
+    [JsonPropertyName("dept_id")]
+    public long DeptId { get; set; }
+}

+ 25 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListIdResponse.cs

@@ -0,0 +1,25 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User.DTO;
+
+public class UserListIdResponse : DingtalkResponseErrorResultRequestid<UserListIdResponseResultDomain>
+{
+}
+
+public class UserListIdResponseResultDomain
+{
+    /// <summary>
+    /// 指定部门的userid列表
+    /// </summary>
+    [JsonProperty("userid_list")]
+    [JsonPropertyName("userid_list")]
+    public List<string> UserIdList { get; set; }
+}

+ 59 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListRequest.cs

@@ -0,0 +1,59 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User.DTO;
+
+public class UserListRequest
+{
+    /// <summary>
+    /// 部门ID,如果是根部门,该参数传1
+    /// </summary>
+    [JsonProperty("dept_id")]
+    [JsonPropertyName("dept_id")]
+    public long? DeptId { get; set; }
+
+    /// <summary>
+    /// 分页查询的游标,最开始传0,后续传返回参数中的next_cursor值
+    /// </summary>
+    [JsonProperty("cursor")]
+    [JsonPropertyName("cursor")]
+    public long? Cursor { get; set; }
+
+    /// <summary>
+    /// 分页长度,最大值100
+    /// </summary>
+    [JsonProperty("size")]
+    [JsonPropertyName("size")]
+    public long? Size { get; set; }
+
+    /// <summary>
+    /// 部门成员的排序规则。默认值,custom
+    /// entry_asc:代表按照进入部门的时间升序。
+    ///entry_desc:代表按照进入部门的时间降序。
+    ///modify_asc:代表按照部门信息修改时间升序。
+    ///modify_desc:代表按照部门信息修改时间降序。
+    ///custom:代表用户定义(未定义时按照拼音)排序。
+    /// </summary>
+    [JsonProperty("order_field")]
+    [JsonPropertyName("order_field")]
+    public string OrderField { get; set; }
+
+    /// <summary>
+    /// 是否返回访问受限的员工
+    /// </summary>
+    [JsonProperty("contain_access_limit")]
+    [JsonPropertyName("contain_access_limit")]
+    public bool? ContainAccessLimit { get; set; }
+
+    /// <summary>
+    /// 通讯录语言,取值。 zh_CN:中文(默认值)。 en_US:英文。
+    /// </summary>
+    [JsonProperty("language")]
+    [JsonPropertyName("language")]
+    public string Language { get; set; }
+}

+ 151 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListResponse.cs

@@ -0,0 +1,151 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User.DTO;
+
+public class UserListResponse : DingtalkResponseErrorResult<DingtalkResponseHasMoreList<UserListResponseResultDomain>>
+{
+}
+
+public class UserListResponseResultDomain
+{
+    /// <summary>
+    /// 是否激活了钉钉
+    /// </summary>
+    public bool Active { get; set; }
+
+    /// <summary>
+    /// 是否为企业的管理员
+    /// </summary>
+    public bool Admin { get; set; }
+
+    /// <summary>
+    /// 头像地址
+    /// </summary>
+    public string Avatar { get; set; }
+
+    /// <summary>
+    /// 是否为企业的老板
+    /// </summary>
+    public bool Boss { get; set; }
+
+    /// <summary>
+    /// 所属部门id列表
+    /// </summary>
+    [JsonProperty("dept_id_list")]
+    [JsonPropertyName("dept_id_list")]
+    public List<long> DeptIdList { get; set; }
+
+    /// <summary>
+    /// 员工在部门中的排序
+    /// </summary>
+    [JsonProperty("dept_order")]
+    [JsonPropertyName("dept_order")]
+    public long DeptOrder { get; set; }
+
+    /// <summary>
+    /// 员工邮箱
+    /// </summary>
+    public string Email { get; set; }
+
+    /// <summary>
+    /// 是否企业账号
+    /// </summary>
+    [JsonProperty("exclusive_account")]
+    [JsonPropertyName("exclusive_account")]
+    public bool ExclusiveAccount { get; set; }
+
+    /// <summary>
+    /// 扩展属性
+    /// </summary>
+    public string Extension { get; set; }
+
+    /// <summary>
+    /// 是否号码隐藏
+    /// </summary>
+    [JsonProperty("hide_mobile")]
+    [JsonPropertyName("hide_mobile")]
+    public bool HideMobile { get; set; }
+
+    /// <summary>
+    /// 入职时间,Unix时间戳,单位毫秒
+    /// </summary>
+    [JsonProperty("hired_date")]
+    [JsonPropertyName("hired_date")]
+    public long HiredDate { get; set; }
+
+    /// <summary>
+    /// 员工工号
+    /// </summary>
+    [JsonProperty("job_number")]
+    [JsonPropertyName("job_number")]
+    public string JobNumber { get; set; }
+
+    /// <summary>
+    /// 是否是部门的主管
+    /// </summary>
+    public bool Leader { get; set; }
+
+    /// <summary>
+    /// 手机号码
+    /// </summary>
+    public string Mobile { get; set; }
+
+    /// <summary>
+    /// 用户姓名
+    /// </summary>
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 员工的企业邮箱
+    /// </summary>
+    [JsonProperty("org_email")]
+    [JsonPropertyName("org_email")]
+    public string OrgEmail { get; set; }
+
+    /// <summary>
+    /// 备注
+    /// </summary>
+    public string Remark { get; set; }
+
+    /// <summary>
+    /// 国际电话区号
+    /// </summary>
+    [JsonProperty("state_code")]
+    [JsonPropertyName("state_code")]
+    public string StateCode { get; set; }
+
+    /// <summary>
+    /// 分机号
+    /// </summary>
+    public string Telephone { get; set; }
+
+    /// <summary>
+    /// 职位
+    /// </summary>
+    public string Title { get; set; }
+
+    /// <summary>
+    /// 用户在当前开发者企业账号范围内的唯一标识
+    /// </summary>
+    public string Unionid { get; set; }
+
+    /// <summary>
+    /// 用户的userId
+    /// </summary>
+    public string UserId { get; set; }
+
+    /// <summary>
+    /// 办公地点
+    /// </summary>
+    [JsonProperty("work_place")]
+    [JsonPropertyName("work_place")]
+    public string WorkPlace { get; set; }
+}

+ 59 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListSimpleRequest.cs

@@ -0,0 +1,59 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User.DTO;
+
+public class UserListSimpleRequest
+{
+    /// <summary>
+    /// 部门ID,如果是根部门,该参数传1
+    /// </summary>
+    [JsonProperty("dept_id")]
+    [JsonPropertyName("dept_id")]
+    public long? DeptId { get; set; }
+
+    /// <summary>
+    /// 分页查询的游标,最开始传0,后续传返回参数中的next_cursor值
+    /// </summary>
+    [JsonProperty("cursor")]
+    [JsonPropertyName("cursor")]
+    public long? Cursor { get; set; }
+
+    /// <summary>
+    /// 分页长度,最大值100
+    /// </summary>
+    [JsonProperty("size")]
+    [JsonPropertyName("size")]
+    public long? Size { get; set; }
+
+    /// <summary>
+    /// 部门成员的排序规则。默认值,custom
+    /// entry_asc:代表按照进入部门的时间升序。
+    ///entry_desc:代表按照进入部门的时间降序。
+    ///modify_asc:代表按照部门信息修改时间升序。
+    ///modify_desc:代表按照部门信息修改时间降序。
+    ///custom:代表用户定义(未定义时按照拼音)排序。
+    /// </summary>
+    [JsonProperty("order_field")]
+    [JsonPropertyName("order_field")]
+    public string OrderField { get; set; }
+
+    /// <summary>
+    /// 是否返回访问受限的员工
+    /// </summary>
+    [JsonProperty("contain_access_limit")]
+    [JsonPropertyName("contain_access_limit")]
+    public bool? ContainAccessLimit { get; set; }
+
+    /// <summary>
+    /// 通讯录语言,取值。 zh_CN:中文(默认值)。 en_US:英文。
+    /// </summary>
+    [JsonProperty("language")]
+    [JsonPropertyName("language")]
+    public string Language { get; set; }
+}

+ 28 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/DTO/UserListSimpleResponse.cs

@@ -0,0 +1,28 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.BaseTypes;
+
+using System.Text.Json.Serialization;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User.DTO;
+
+public class UserListSimpleResponse : DingtalkResponseErrorResultRequestid<DingtalkResponseHasMoreList<UserListSimpleResponseDomain>>
+{
+}
+
+public class UserListSimpleResponseDomain
+{
+    /// <summary>
+    /// 用户姓名
+    /// </summary>
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 用户的userid
+    /// </summary>
+    public string UserId { get; set; }
+}

+ 26 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/IUserRequestProxy.cs

@@ -0,0 +1,26 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User;
+
+public interface IUserRequestProxy : IHttpDispatchProxy
+{
+    [Post("https://oapi.dingtalk.com/topapi/v2/user/get"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> UserDetail([QueryString("access_token")] string AccessToken, [Body] DTO.UserDetailRequest request);
+
+    [Post("https://oapi.dingtalk.com/topapi/user/listsimple"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> UserListSimple([QueryString("access_token")] string AccessToken, [Body] DTO.UserListSimpleRequest request);
+
+    [Post("https://oapi.dingtalk.com/topapi/user/listid"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> UserListId([QueryString("access_token")] string AccessToken, [Body] DTO.UserListIdRequest request);
+
+    [Post("https://oapi.dingtalk.com/topapi/v2/user/list"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> UserList([QueryString("access_token")] string AccessToken, [Body] DTO.UserListRequest request);
+
+
+    [Post("https://oapi.dingtalk.com/topapi/role/list"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<string> RoleList([QueryString("access_token")] string AccessToken, [Body] DTO.RoleListRequest request);
+}

+ 110 - 0
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/RequestProxy/User/UserRequest.cs

@@ -0,0 +1,110 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.Net.Plugin.DingTalk.RequestProxy.User.DTO;
+
+namespace Admin.Net.Plugin.DingTalk.RequestProxy.User;
+
+public class UserRequest : IScoped
+{
+    private readonly IUserRequestProxy request;
+
+    public UserRequest(IUserRequestProxy _request)
+    {
+        this.request = _request;
+    }
+
+    /// <summary>
+    /// 查询用户详情
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="userid">用户的userId</param>
+    /// <param name="language">通讯录语言。zh_CN:中文(默认值),en_US:英文</param>
+    /// <returns></returns>
+    public async Task<UserDetailResponse> UserDetail(string AccessToken, string userid, string language = "zh_CN")
+    {
+        var res = await request.UserDetail(AccessToken, new UserDetailRequest
+        {
+            UserId = userid,
+            Language = language
+        });
+        return res.ToObject<UserDetailResponse>();
+    }
+
+    /// <summary>
+    /// 获取部门用户基础信息
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="deptId">部门ID,如果是根部门,该参数传1</param>
+    /// <param name="cursor">分页查询的游标,最开始传0,后续传返回参数中的next_cursor值</param>
+    /// <param name="size">分页长度,最大值100</param>
+    /// <param name="orderField">部门成员的排序规则。默认值,custom。entry_asc:代表按照进入部门的时间升序。entry_desc:代表按照进入部门的时间降序。modify_asc:代表按照部门信息修改时间升序。modify_desc:代表按照部门信息修改时间降序。custom:代表用户定义(未定义时按照拼音)排序。</param>
+    /// <param name="containAccessLimit">是否返回访问受限的员工</param>
+    /// <param name="language">通讯录语言,取值。 zh_CN:中文(默认值)。 en_US:英文。</param>
+    /// <returns></returns>
+    public async Task<UserListSimpleResponse> UserListSimple(string AccessToken, long deptId = 1, long cursor = 0, long size = 100, string orderField = "custom", bool containAccessLimit = false, string language = "zh_CN")
+    {
+        var resStr = await request.UserListSimple(AccessToken, new UserListSimpleRequest
+        {
+            DeptId = deptId,
+            Cursor = cursor,
+            Size = size,
+            OrderField = orderField,
+            ContainAccessLimit = containAccessLimit,
+            Language = language
+        });
+        var res = resStr.ToObject<UserListSimpleResponse>();
+        return res;
+    }
+
+    /// <summary>
+    /// 获取部门用户userid列表
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="deptId">部门deptId</param>
+    /// <returns></returns>
+    public async Task<UserListIdResponse> UserListId(string AccessToken, long deptId = 1)
+    {
+        var resStr = await request.UserListId(AccessToken, new UserListIdRequest
+        {
+            DeptId = deptId
+        });
+        return resStr.ToObject<UserListIdResponse>();
+    }
+
+    /// <summary>
+    /// 获取部门用户详情
+    /// </summary>
+    /// <param name="AccessToken"></param>
+    /// <param name="deptId">部门ID,如果是根部门,该参数传1</param>
+    /// <param name="cursor">分页查询的游标,最开始传0,后续传返回参数中的next_cursor值</param>
+    /// <param name="size">分页大小</param>
+    /// <param name="orderField">部门成员的排序规则,默认不传是按自定义排序(custom):entry_asc:代表按照进入部门的时间升序,entry_desc:代表按照进入部门的时间降序,modify_asc:代表按照部门信息修改时间升序,modify_desc:代表按照部门信息修改时间降序,custom:代表用户定义(未定义时按照拼音)排序</param>
+    /// <param name="containAccessLimit">是否返回访问受限的员工</param>
+    /// <param name="language">通讯录语言,取值。zh_CN:中文(默认值)。en_US:英文。</param>
+    /// <returns></returns>
+    public async Task<UserListResponse> UserList(string AccessToken, long deptId = 1, long cursor = 0, long size = 100, string orderField = "custom", bool containAccessLimit = false, string language = "zh_CN")
+    {
+        var resStr = await request.UserList(AccessToken, new UserListRequest
+        {
+            DeptId = deptId,
+            Cursor = cursor,
+            Size = size,
+            OrderField = orderField,
+            ContainAccessLimit = containAccessLimit,
+            Language = language
+        });
+        var res = resStr.ToObject<UserListResponse>();
+        return res;
+    }
+
+    public async Task<RoleListResponse> RoleList(string AccessToken, int size=20, int offset=0)
+    {
+        var resStr = await request.RoleList(AccessToken, new RoleListRequest { Offset = offset, Size = size });
+        var res = resStr.ToObject<RoleListResponse>();
+        return res;
+    }
+}

+ 21 - 12
Admin.NET/Plugins/Admin.NET.Plugin.DingTalk/Service/DingTalkService.cs

@@ -4,6 +4,11 @@
 //
 // 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
 
+using Admin.Net.Plugin.DingTalk.RequestProxy.Top;
+using Admin.Net.Plugin.DingTalk.RequestProxy.Top.DTO;
+using Admin.NET.Plugin.DingTalk.RequestProxy.HRM;
+using Admin.NET.Plugin.DingTalk.RequestProxy.HRM.DTO;
+
 namespace Admin.NET.Plugin.DingTalk.Service;
 
 /// <summary>
@@ -14,12 +19,18 @@ public class DingTalkService : IDynamicApiController, IScoped
 {
     private readonly IDingTalkApi _dingTalkApi;
     private readonly DingTalkOptions _dingTalkOptions;
+    private readonly TopRequest _topRequest;
+    private readonly HrmRequest _hrmRequest;
 
     public DingTalkService(IDingTalkApi dingTalkApi,
-        IOptions<DingTalkOptions> dingTalkOptions)
+        IOptions<DingTalkOptions> dingTalkOptions,
+        TopRequest topRequest,
+        HrmRequest hrmRequest)
     {
         _dingTalkApi = dingTalkApi;
         _dingTalkOptions = dingTalkOptions.Value;
+        _topRequest = topRequest;
+        _hrmRequest = hrmRequest;
     }
 
     /// <summary>
@@ -27,13 +38,9 @@ public class DingTalkService : IDynamicApiController, IScoped
     /// </summary>
     /// <returns></returns>
     [DisplayName("获取企业内部应用的access_token")]
-    public async Task<GetDingTalkTokenOutput> GetDingTalkToken()
+    public async Task<GetAccessTokenResponse> GetDingTalkToken()
     {
-        var tokenRes = await _dingTalkApi.GetDingTalkToken(_dingTalkOptions.ClientId, _dingTalkOptions.ClientSecret);
-        if (tokenRes.ErrCode != 0)
-        {
-            throw Oops.Oh(tokenRes.ErrMsg);
-        }
+        var tokenRes = await _topRequest.GetAccessToken(_dingTalkOptions.ClientId, _dingTalkOptions.ClientSecret);
         return tokenRes;
     }
 
@@ -41,12 +48,14 @@ public class DingTalkService : IDynamicApiController, IScoped
     /// 获取在职员工列表 🔖
     /// </summary>
     /// <param name="access_token"></param>
-    /// <param name="input"></param>
+    /// <param name="statusList"></param>
+    /// <param name="size"></param>
+    /// <param name="offset"></param>
     /// <returns></returns>
     [HttpPost, DisplayName("获取在职员工列表")]
-    public async Task<DingTalkBaseResponse<GetDingTalkCurrentEmployeesListOutput>> GetDingTalkCurrentEmployeesList(string access_token, [Required] GetDingTalkCurrentEmployeesListInput input)
+    public async Task<EmployeeQueryonjobResponse> GetDingTalkCurrentEmployeesList(string access_token,List<string> statusList,int size,int offset)
     {
-        return await _dingTalkApi.GetDingTalkCurrentEmployeesList(access_token, input);
+        return await _hrmRequest.EmployeeQueryonjob(access_token, statusList, size, offset);
     }
 
     /// <summary>
@@ -56,9 +65,9 @@ public class DingTalkService : IDynamicApiController, IScoped
     /// <param name="input"></param>
     /// <returns></returns>
     [HttpPost, DisplayName("获取员工花名册字段信息")]
-    public async Task<DingTalkBaseResponse<List<DingTalkEmpRosterFieldVo>>> GetDingTalkCurrentEmployeesRosterList(string access_token, [Required] GetDingTalkCurrentEmployeesRosterListInput input)
+    public async Task<RosterListsQueryResponse> GetDingTalkCurrentEmployeesRosterList(string access_token, List<string> useridList,List<string> fieldFilterList,long appAgentId)
     {
-        return await _dingTalkApi.GetDingTalkCurrentEmployeesRosterList(access_token, input);
+        return await _hrmRequest.RosterListsQuery(access_token,useridList,fieldFilterList,appAgentId);
     }
 
     /// <summary>