Browse Source

feat: 😀接入企业微信Api

喵你个旺呀 1 năm trước cách đây
mục cha
commit
b06aa6aae1
18 tập tin đã thay đổi với 1073 bổ sung5 xóa
  1. 4 5
      Admin.NET/Admin.NET.sln
  2. 24 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Admin.NET.Plugin.WorkWeixin.csproj
  3. 8 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Configuration/WorkWeixin.json
  4. 30 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/GlobalUsings.cs
  5. 25 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Option/WorkWeixinOptions.cs
  6. 425 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/AppChat/Dto/AppChatHttpInput.cs
  7. 17 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/AppChat/Dto/AppChatHttpOutput.cs
  8. 53 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/AppChat/IWorkWeixinAppChatHttp.cs
  9. 24 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Auth/Dto/WorkWeixinAuthHttpOutput.cs
  10. 23 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Auth/IWorkWeixinAuthHttp.cs
  11. 48 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Department/Dto/DepartmentHttpInput.cs
  12. 95 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Department/Dto/DepartmentHttpOutput.cs
  13. 63 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Department/IDepartmentHttp.cs
  14. 53 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Tag/Dto/TagHttpInput.cs
  15. 33 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Tag/Dto/TagHttpOutput.cs
  16. 83 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Tag/ITagHttp.cs
  17. 25 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Startup.cs
  18. 40 0
      Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Utils/BaseHttpOutput.cs

+ 4 - 5
Admin.NET/Admin.NET.sln

@@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Web.Core", "Admin
 EndProject
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Web.Entry", "Admin.NET.Web.Entry\Admin.NET.Web.Entry.csproj", "{11EA630B-4600-4236-A117-CE6C6CD67586}"
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Web.Entry", "Admin.NET.Web.Entry\Admin.NET.Web.Entry.csproj", "{11EA630B-4600-4236-A117-CE6C6CD67586}"
 EndProject
 EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Admin.NET.Test", "Admin.NET.Test\Admin.NET.Test.csproj", "{57350E6A-B5A0-452C-9FD4-C69617C6DA30}"
+EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{662E0B8E-F23E-4C7D-80BD-CAA5707503CC}"
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{662E0B8E-F23E-4C7D-80BD-CAA5707503CC}"
 	ProjectSection(SolutionItems) = preProject
 	ProjectSection(SolutionItems) = preProject
 		.editorconfig = .editorconfig
 		.editorconfig = .editorconfig
@@ -28,7 +30,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Plugin.ApprovalFl
 EndProject
 EndProject
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Plugin.K3Cloud", "Plugins\Admin.NET.Plugin.K3Cloud\Admin.NET.Plugin.K3Cloud.csproj", "{72EB89AB-15F7-4F85-88DB-7C2EF7C3D588}"
 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Admin.NET.Plugin.K3Cloud", "Plugins\Admin.NET.Plugin.K3Cloud\Admin.NET.Plugin.K3Cloud.csproj", "{72EB89AB-15F7-4F85-88DB-7C2EF7C3D588}"
 EndProject
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Admin.NET.Test", "Admin.NET.Test\Admin.NET.Test.csproj", "{57350E6A-B5A0-452C-9FD4-C69617C6DA30}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Admin.NET.Plugin.WorkWeixin", "Plugins\Admin.NET.Plugin.WorkWeixin\Admin.NET.Plugin.WorkWeixin.csproj", "{BFE4764F-1FF8-47A7-B4AD-085F7D8CD6C4}"
 EndProject
 EndProject
 Global
 Global
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 	GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -72,10 +74,6 @@ Global
 		{72EB89AB-15F7-4F85-88DB-7C2EF7C3D588}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{72EB89AB-15F7-4F85-88DB-7C2EF7C3D588}.Debug|Any CPU.Build.0 = Debug|Any CPU
 		{72EB89AB-15F7-4F85-88DB-7C2EF7C3D588}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{72EB89AB-15F7-4F85-88DB-7C2EF7C3D588}.Release|Any CPU.ActiveCfg = Release|Any CPU
 		{72EB89AB-15F7-4F85-88DB-7C2EF7C3D588}.Release|Any CPU.Build.0 = Release|Any CPU
 		{72EB89AB-15F7-4F85-88DB-7C2EF7C3D588}.Release|Any CPU.Build.0 = Release|Any CPU
-		{57350E6A-B5A0-452C-9FD4-C69617C6DA30}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{57350E6A-B5A0-452C-9FD4-C69617C6DA30}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{57350E6A-B5A0-452C-9FD4-C69617C6DA30}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{57350E6A-B5A0-452C-9FD4-C69617C6DA30}.Release|Any CPU.Build.0 = Release|Any CPU
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
 		HideSolutionNode = FALSE
@@ -86,6 +84,7 @@ Global
 		{04AB2E76-DE8B-4EFD-9F48-F8D4C0993106} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
 		{04AB2E76-DE8B-4EFD-9F48-F8D4C0993106} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
 		{902A91A7-5EF0-4A63-BC2C-9B783DC00880} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
 		{902A91A7-5EF0-4A63-BC2C-9B783DC00880} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
 		{72EB89AB-15F7-4F85-88DB-7C2EF7C3D588} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
 		{72EB89AB-15F7-4F85-88DB-7C2EF7C3D588} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
+		{BFE4764F-1FF8-47A7-B4AD-085F7D8CD6C4} = {76F70D22-8D53-468E-A3B6-1704666A1D71}
 	EndGlobalSection
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 	GlobalSection(ExtensibilityGlobals) = postSolution
 		SolutionGuid = {5CD801D7-984A-4F5C-8FA2-211B7A5EA9F3}
 		SolutionGuid = {5CD801D7-984A-4F5C-8FA2-211B7A5EA9F3}

+ 24 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Admin.NET.Plugin.WorkWeixin.csproj

@@ -0,0 +1,24 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+    <PropertyGroup>
+        <TargetFrameworks>net6.0;net8.0</TargetFrameworks>
+        <NoWarn>1701;1702;1591;8632</NoWarn>
+        <ImplicitUsings>enable</ImplicitUsings>
+        <Nullable>disable</Nullable>
+        <GenerateDocumentationFile>True</GenerateDocumentationFile>
+        <Copyright>Admin.NET</Copyright>
+        <Description>Admin.NET 通用权限开发平台</Description>
+        <RootNamespace>Admin.NET.Plugin.WorkWeixin</RootNamespace>
+    </PropertyGroup>
+
+    <ItemGroup>
+        <None Update="Configuration\**">
+            <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+        </None>
+    </ItemGroup>
+
+    <ItemGroup>
+        <ProjectReference Include="..\..\Admin.NET.Core\Admin.NET.Core.csproj" />
+    </ItemGroup>
+
+</Project>

+ 8 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Configuration/WorkWeixin.json

@@ -0,0 +1,8 @@
+{
+  "$schema": "https://gitee.com/dotnetchina/Furion/raw/v4/schemas/v4/furion-schema.json",
+
+  "WorkWeixin": {
+    "CorpId": "xxxx", // 企业ID
+    "CorpSecret": "xxxx" // 企业微信凭证密钥
+  }
+}

+ 30 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/GlobalUsings.cs

@@ -0,0 +1,30 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+global using Admin.NET.Core;
+global using Admin.NET.Core.Service;
+global using Admin.NET.Plugin.WorkWeixin;
+global using Furion;
+global using Furion.RemoteRequest;
+global using Furion.DatabaseAccessor;
+global using Furion.DataValidation;
+global using Furion.DynamicApiController;
+global using Furion.FriendlyException;
+global using Furion.JsonSerialization;
+global using Furion.UnifyResult;
+global using Mapster;
+global using Microsoft.AspNetCore.Authorization;
+global using Microsoft.AspNetCore.Http;
+global using Microsoft.AspNetCore.Mvc;
+global using Microsoft.AspNetCore.Mvc.Filters;
+global using Newtonsoft.Json;
+global using SqlSugar;
+global using System.Collections;
+global using System.ComponentModel;
+global using System.ComponentModel.DataAnnotations;
+global using System.Data;
+global using System.Linq.Dynamic.Core;
+global using System.Text.Json.Serialization;

+ 25 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Option/WorkWeixinOptions.cs

@@ -0,0 +1,25 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// 
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+// 
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Furion.ConfigurableOptions;
+
+namespace Admin.NET.Plugin.WorkWeixin.Option;
+
+/// <summary>
+/// 企业微信配置项
+/// </summary>
+public class WorkWeixinOptions : IConfigurableOptions
+{
+    /// <summary>
+    /// 企业ID
+    /// </summary>
+    public string CorpId { get; set; }
+
+    /// <summary>
+    /// 企业微信凭证密钥
+    /// </summary>
+    public string CorpSecret { get; set; }
+}

+ 425 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/AppChat/Dto/AppChatHttpInput.cs

@@ -0,0 +1,425 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// 
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+// 
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.WorkWeixin.Proxy;
+
+/// <summary>
+/// 创建群聊会话输入参数
+/// </summary>
+public class CreatAppChatInput
+{
+    /// <summary>
+    /// 群名称
+    /// </summary>
+    [JsonProperty("name")]
+    [JsonPropertyName("name")]
+    [Required(ErrorMessage = "群名称不能为空"), MaxLength(50, ErrorMessage = "群名称最多不能超过50个字符")]
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 群主Id
+    /// </summary>
+    [JsonProperty("owner")]
+    [JsonPropertyName("owner")]
+    [Required(ErrorMessage = "群主Id不能为空")]
+    public string Owner { get; set; }
+
+    /// <summary>
+    /// 群成员Id列表
+    /// </summary>
+    [JsonProperty("userlist")]
+    [JsonPropertyName("userlist")]
+    [NotEmpty(ErrorMessage = "群成员列表不能为空")]
+    public List<string> UserList { get; set; }
+
+    /// <summary>
+    /// 群Id
+    /// </summary>
+    [JsonProperty("chatid")]
+    [JsonPropertyName("chatid")]
+    [Required(ErrorMessage = "群Id不能为空"), MaxLength(32, ErrorMessage = "群Id最多不能超过32个字符")]
+    public string ChatId { get; set; }
+}
+
+/// <summary>
+/// 修改群聊会话输入参数
+/// </summary>
+public class UpdateAppChatInput
+{
+    /// <summary>
+    /// 群Id
+    /// </summary>
+    [JsonProperty("chatid")]
+    [JsonPropertyName("chatid")]
+    [Required(ErrorMessage = "群Id不能为空"), MaxLength(32, ErrorMessage = "群Id最多不能超过32个字符")]
+    public string ChatId { get; set; }
+
+    /// <summary>
+    /// 群名称
+    /// </summary>
+    [JsonProperty("name")]
+    [JsonPropertyName("name")]
+    [Required(ErrorMessage = "群名称不能为空"), MaxLength(50, ErrorMessage = "群名称最多不能超过50个字符")]
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 群主Id
+    /// </summary>
+    [JsonProperty("owner")]
+    [JsonPropertyName("owner")]
+    [Required(ErrorMessage = "群主Id不能为空")]
+    public string Owner { get; set; }
+
+    /// <summary>
+    /// 添加成员的id列表
+    /// </summary>
+    [JsonProperty("add_user_list")]
+    [JsonPropertyName("add_user_list")]
+    public List<string> AddUserList { get; set; }
+
+    /// <summary>
+    /// 踢出成员的id列表
+    /// </summary>
+    [JsonProperty("del_user_list")]
+    [JsonPropertyName("del_user_list")]
+    public List<string> DelUserList { get; set; }
+}
+
+/// <summary>
+/// 应用消息推送输入基类参数
+/// </summary>
+public class SendBaseAppChatInput
+{
+    /// <summary>
+    /// 群Id
+    /// </summary>
+    [JsonProperty("chatid")]
+    [JsonPropertyName("chatid")]
+    [Required(ErrorMessage = "群Id不能为空"), MaxLength(32, ErrorMessage = "群Id最多不能超过32个字符")]
+    public string ChatId { get; set; }
+
+    /// <summary>
+    /// 消息类型
+    /// </summary>
+    /// <example>text:文本消息</example>
+    /// <example>image:图片消息</example>
+    /// <example>voice:图片消息</example>
+    /// <example>video:视频消息</example>
+    /// <example>file:文件消息</example>
+    /// <example>textcard:文本卡片</example>
+    /// <example>news:图文消息</example>
+    /// <example>mpnews:图文消息(存储在企业微信)</example>
+    /// <example>markdown:markdown消息</example>
+    [JsonProperty("msgtype")]
+    [JsonPropertyName("msgtype")]
+    [Required(ErrorMessage = "消息类型不能为空")]
+    protected string MsgType { get; set; }
+
+    /// <summary>
+    /// 是否是保密消息
+    /// </summary>
+    [JsonProperty("safe")]
+    [JsonPropertyName("safe")]
+    [Required(ErrorMessage = "消息类型不能为空")]
+    public int Safe { get; set; }
+
+    public SendBaseAppChatInput(string chatId, string msgType, bool safe = false)
+    {
+        ChatId = chatId;
+        MsgType = msgType;
+        Safe = safe ? 1 : 0;
+    }
+}
+
+/// <summary>
+/// 推送文本消息输入参数
+/// </summary>
+public class SendTextAppChatInput : SendBaseAppChatInput
+{
+    /// <summary>
+    /// 消息内容
+    /// </summary>
+    [JsonProperty("text")]
+    [JsonPropertyName("text")]
+    public object Text { get; set; }
+
+    /// <summary>
+    /// 文本消息
+    /// </summary>
+    /// <param name="chatId"></param>
+    /// <param name="content"></param>
+    /// <param name="safe"></param>
+    public SendTextAppChatInput(string chatId, string content, bool safe = false) : base(chatId, "text", safe)
+    {
+        Text = new { content };
+    }
+}
+
+/// <summary>
+/// 推送图片消息输入参数
+/// </summary>
+public class SendImageAppChatInput : SendBaseAppChatInput
+{
+    /// <summary>
+    /// 消息内容
+    /// </summary>
+    [JsonProperty("image")]
+    [JsonPropertyName("image")]
+    public object Image { get; set; }
+
+    /// <summary>
+    /// 图片消息
+    /// </summary>
+    /// <param name="chatId"></param>
+    /// <param name="mediaId"></param>
+    /// <param name="safe"></param>
+    public SendImageAppChatInput(string chatId, string mediaId, bool safe = false) : base(chatId, "image", safe)
+    {
+        Image = new { media_id = mediaId };
+    }
+}
+
+/// <summary>
+/// 推送语音消息输入参数
+/// </summary>
+public class SendVoiceAppChatInput : SendBaseAppChatInput
+{
+    /// <summary>
+    /// 消息内容
+    /// </summary>
+    [JsonProperty("voice")]
+    [JsonPropertyName("voice")]
+    public object Voice { get; set; }
+
+    /// <summary>
+    /// 语音消息
+    /// </summary>
+    /// <param name="chatId"></param>
+    /// <param name="mediaId"></param>
+    /// <param name="safe"></param>
+    public SendVoiceAppChatInput(string chatId, string mediaId, bool safe = false) : base(chatId, "voice", safe)
+    {
+        Voice = new { media_id = mediaId };
+    }
+}
+
+/// <summary>
+/// 推送视频消息输入参数
+/// </summary>
+public class SendVideoAppChatInput : SendBaseAppChatInput
+{
+    /// <summary>
+    /// 消息内容
+    /// </summary>
+    [JsonProperty("video")]
+    [JsonPropertyName("video")]
+    public object Video { get; set; }
+
+    /// <summary>
+    /// 视频消息
+    /// </summary>
+    /// <param name="chatId"></param>
+    /// <param name="title"></param>
+    /// <param name="description"></param>
+    /// <param name="mediaId"></param>
+    /// <param name="safe"></param>
+    public SendVideoAppChatInput(string chatId, string title, string description, string mediaId, bool safe = false) : base(chatId, "video", safe)
+    {
+        Video = new
+        {
+            media_id = mediaId,
+            description,
+            title
+        };
+    }
+}
+
+/// <summary>
+/// 推送视频消息输入参数
+/// </summary>
+public class SendFileAppChatInput : SendBaseAppChatInput
+{
+    /// <summary>
+    /// 消息内容
+    /// </summary>
+    [JsonProperty("file")]
+    [JsonPropertyName("file")]
+    public object File { get; set; }
+
+    /// <summary>
+    /// 文件消息
+    /// </summary>
+    /// <param name="chatId"></param>
+    /// <param name="mediaId"></param>
+    /// <param name="safe"></param>
+    public SendFileAppChatInput(string chatId, string mediaId, bool safe = false) : base(chatId, "video", safe)
+    {
+        File = new { media_id = mediaId };
+    }
+}
+
+/// <summary>
+/// 推送文本卡片消息输入参数
+/// </summary>
+public class SendTextCardAppChatInput : SendBaseAppChatInput
+{
+    /// <summary>
+    /// 消息内容
+    /// </summary>
+    [JsonProperty("textcard")]
+    [JsonPropertyName("textcard")]
+    public object TextCard { get; set; }
+
+    /// <summary>
+    /// 文本卡片消息
+    /// </summary>
+    /// <param name="chatId"></param>
+    /// <param name="title">标题</param>
+    /// <param name="description">描述</param>
+    /// <param name="url">点击后跳转的链接</param>
+    /// <param name="btnTxt">按钮文字</param>
+    /// <param name="safe"></param>
+    public SendTextCardAppChatInput(string chatId, string title, string description, string url, string btnTxt, bool safe = false) : base(chatId, "textcard", safe)
+    {
+        TextCard = new
+        {
+            title,
+            description,
+            url,
+            btntxt = btnTxt
+        };
+    }
+}
+
+/// <summary>
+/// 图文消息项
+/// </summary>
+public class SendNewsItem
+{
+    /// <summary>
+    /// 标题
+    /// </summary>
+    [JsonProperty("title")]
+    [JsonPropertyName("title")]
+    public string Title { get; set; }
+
+    /// <summary>
+    /// 描述
+    /// </summary>
+    [JsonProperty("description")]
+    [JsonPropertyName("description")]
+    public string Description { get; set; }
+
+    /// <summary>
+    /// 描述
+    /// </summary>
+    [JsonProperty("url")]
+    [JsonPropertyName("url")]
+    public string Url { get; set; }
+
+    /// <summary>
+    /// 图文消息的图片链接(推荐大图1068 * 455,小图150 * 150)
+    /// </summary>
+    [JsonProperty("picurl")]
+    [JsonPropertyName("picurl")]
+    public string PicUrl { get; set; }
+}
+
+/// <summary>
+/// 推送图文消息输入参数
+/// </summary>
+public class SendNewsAppChatInput : SendBaseAppChatInput
+{
+    /// <summary>
+    /// 消息内容
+    /// </summary>
+    [JsonProperty("news")]
+    [JsonPropertyName("news")]
+    public object News { get; set; }
+
+    /// <summary>
+    /// 图文消息
+    /// </summary>
+    /// <param name="chatId"></param>
+    /// <param name="newsList">图文消息列表</param>
+    /// <param name="safe"></param>
+    public SendNewsAppChatInput(string chatId, List<SendNewsItem> newsList, bool safe = false) : base(chatId, "news", safe)
+    {
+        News = new { articles = newsList };
+    }
+}
+
+/// <summary>
+/// 图文消息项
+/// </summary>
+public class SendMpNewsItem
+{
+    /// <summary>
+    /// 标题
+    /// </summary>
+    [JsonProperty("title")]
+    [JsonPropertyName("title")]
+    public string Title { get; set; }
+
+    /// <summary>
+    /// 缩略图media_id
+    /// </summary>
+    [JsonProperty("thumb_media_id")]
+    [JsonPropertyName("thumb_media_id")]
+    public string ThumbMediaId { get; set; }
+
+    /// <summary>
+    /// 作者
+    /// </summary>
+    [JsonProperty("author")]
+    [JsonPropertyName("author")]
+    public string Author { get; set; }
+
+    /// <summary>
+    /// 点击“阅读原文”之后的页面链接
+    /// </summary>
+    [JsonProperty("content_source_url")]
+    [JsonPropertyName("content_source_url")]
+    public string ContentSourceUrl { get; set; }
+
+    /// <summary>
+    /// 图文消息的内容
+    /// </summary>
+    [JsonProperty("content")]
+    [JsonPropertyName("content")]
+    public string Content { get; set; }
+
+    /// <summary>
+    /// 图文消息的描述
+    /// </summary>
+    [JsonProperty("digest")]
+    [JsonPropertyName("digest")]
+    public string Digest { get; set; }
+}
+
+/// <summary>
+/// 推送图文消息(存储在企业微信)输入参数
+/// </summary>
+public class SendMpNewsAppChatInput : SendBaseAppChatInput
+{
+    /// <summary>
+    /// 消息内容
+    /// </summary>
+    [JsonProperty("mpnews")]
+    [JsonPropertyName("mpnews")]
+    public object MpNews { get; set; }
+
+    /// <summary>
+    /// 图文消息
+    /// </summary>
+    /// <param name="chatId"></param>
+    /// <param name="mpNewsList">图文消息列表</param>
+    /// <param name="safe"></param>
+    public SendMpNewsAppChatInput(string chatId, List<SendMpNewsItem> mpNewsList, bool safe = false) : base(chatId, "mpnews", safe)
+    {
+        MpNews = new { articles = mpNewsList };
+    }
+}

+ 17 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/AppChat/Dto/AppChatHttpOutput.cs

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

+ 53 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/AppChat/IWorkWeixinAppChatHttp.cs

@@ -0,0 +1,53 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// 
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+// 
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.WorkWeixin.Proxy.AppChat;
+
+/// <summary>
+/// 群聊会话远程调用服务
+/// </summary>
+public interface IWorkWeixinAppChatHttp : IHttpDispatchProxy
+{
+    /// <summary>
+    /// 创建群聊会话
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="body"></param>
+    /// <returns></returns>
+    /// <inheritdoc cref="https://developer.work.weixin.qq.com/document/path/90245"/>
+    [Post("https://qyapi.weixin.qq.com/cgi-bin/appchat/create"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<CreatAppChatOutput> Create([QueryString("access_token")] string accessToken, [Body] CreatAppChatInput body);
+
+    /// <summary>
+    /// 修改群聊会话
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="body"></param>
+    /// <returns></returns>
+    /// <inheritdoc cref="https://developer.work.weixin.qq.com/document/path/98913"/>
+    [Post("https://qyapi.weixin.qq.com/cgi-bin/appchat/update"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<CreatAppChatOutput> Update([QueryString("access_token")] string accessToken, [Body] UpdateAppChatInput body);
+
+    /// <summary>
+    /// 获取群聊会话
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="chatId"></param>
+    /// <returns></returns>
+    /// <inheritdoc cref="https://developer.work.weixin.qq.com/document/path/98914"/>
+    [Get("https://qyapi.weixin.qq.com/cgi-bin/appchat/get"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<CreatAppChatOutput> Get([QueryString("access_token")] string accessToken, [QueryString("chatid")] string chatId);
+
+    /// <summary>
+    /// 应用推送消息
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="body"></param>
+    /// <returns></returns>
+    /// <inheritdoc cref="https://developer.work.weixin.qq.com/document/path/90248"/>
+    [Post("https://qyapi.weixin.qq.com/cgi-bin/appchat/send"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<BaseWorkOutput> Send([QueryString("access_token")] string accessToken, [Body] SendBaseAppChatInput body);
+}

+ 24 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Auth/Dto/WorkWeixinAuthHttpOutput.cs

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

+ 23 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Auth/IWorkWeixinAuthHttp.cs

@@ -0,0 +1,23 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// 
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+// 
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.WorkWeixin.Proxy.AppChat;
+
+/// <summary>
+/// 授权会话远程服务
+/// </summary>
+public interface IWorkWeixinAuthHttp : IHttpDispatchProxy
+{
+    /// <summary>
+    /// 获取接口凭证
+    /// </summary>
+    /// <param name="corpId">企业ID</param>
+    /// <param name="corpSecret">应用的凭证密钥</param>
+    /// <returns></returns>
+    /// <inheritdoc cref="https://developer.work.weixin.qq.com/document/path/91039"/>
+    [Post("https://qyapi.weixin.qq.com/cgi-bin/gettoken"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<AuthAccessTokenHttpOutput> GetToken([QueryString("corpid")] string corpId, [QueryString("corpsecret")] string corpSecret);
+}

+ 48 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Department/Dto/DepartmentHttpInput.cs

@@ -0,0 +1,48 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// 
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+// 
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.WorkWeixin.Proxy;
+
+/// <summary>
+/// 创建部门输入参数
+/// </summary>
+public class DepartmentHttpInput
+{
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    [JsonProperty("id")]
+    [JsonPropertyName("id")]
+    public long? Id { get; set; }
+
+    /// <summary>
+    /// 父部门id
+    /// </summary>
+    [JsonProperty("parentid")]
+    [JsonPropertyName("parentid")]
+    public long? ParentId { get; set; }
+
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    [JsonProperty("name")]
+    [JsonPropertyName("name")]
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 英文名称
+    /// </summary>
+    [JsonProperty("name_en")]
+    [JsonPropertyName("name_en")]
+    public string NameEn { get; set; }
+
+    /// <summary>
+    /// 序号
+    /// </summary>
+    [JsonProperty("order")]
+    [JsonPropertyName("order")]
+    public int? Order { get; set; }
+}

+ 95 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Department/Dto/DepartmentHttpOutput.cs

@@ -0,0 +1,95 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// 
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+// 
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.WorkWeixin.Proxy;
+
+/// <summary>
+/// 部门Id列表输出参数
+/// </summary>
+public class DepartmentIdOutput : BaseWorkOutput
+{
+    /// <summary>
+    /// id
+    /// </summary>
+    [JsonProperty("department_id")]
+    [JsonPropertyName("department_id")]
+    public List<DepartmentItemOutput> DepartmentList { get; set; }
+}
+
+/// <summary>
+/// 部门Id输出参数
+/// </summary>
+public class DepartmentItemOutput
+{
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    [JsonProperty("id")]
+    [JsonPropertyName("id")]
+    public long? Id { get; set; }
+
+    /// <summary>
+    /// 父部门id
+    /// </summary>
+    [JsonProperty("parentid")]
+    [JsonPropertyName("parentid")]
+    public long? ParentId { get; set; }
+
+    /// <summary>
+    /// 序号
+    /// </summary>
+    [JsonProperty("order")]
+    [JsonPropertyName("order")]
+    public int? Order { get; set; }
+}
+
+/// <summary>
+/// 部门输出参数
+/// </summary>
+public class DepartmentOutput
+{
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    [JsonProperty("id")]
+    [JsonPropertyName("id")]
+    public long? Id { get; set; }
+
+    /// <summary>
+    /// 父部门id
+    /// </summary>
+    [JsonProperty("parentid")]
+    [JsonPropertyName("parentid")]
+    public long? ParentId { get; set; }
+
+    /// <summary>
+    /// 部门名称
+    /// </summary>
+    [JsonProperty("name")]
+    [JsonPropertyName("name")]
+    public string Name { get; set; }
+
+    /// <summary>
+    /// 英文名称
+    /// </summary>
+    [JsonProperty("name_en")]
+    [JsonPropertyName("name_en")]
+    public string NameEn { get; set; }
+
+    /// <summary>
+    /// 部门负责人列表
+    /// </summary>
+    [JsonProperty("department_leader")]
+    [JsonPropertyName("department_leader")]
+    public List<string> Leaders { get; set; }
+
+    /// <summary>
+    /// 序号
+    /// </summary>
+    [JsonProperty("order")]
+    [JsonPropertyName("order")]
+    public int? Order { get; set; }
+}

+ 63 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Department/IDepartmentHttp.cs

@@ -0,0 +1,63 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.WorkWeixin.Proxy.AppChat;
+
+/// <summary>
+/// 部门远程调用服务
+/// </summary>
+public interface IDepartmentHttp : IHttpDispatchProxy
+{
+    /// <summary>
+    /// 创建部门
+    /// https://developer.work.weixin.qq.com/document/path/90205
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="body"></param>
+    /// <returns></returns>
+    [Post("https://qyapi.weixin.qq.com/cgi-bin/department/create"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<BaseWorkIdOutput> Create([QueryString("access_token")] string accessToken, [Body] DepartmentHttpInput body);
+
+    /// <summary>
+    /// 修改部门
+    /// https://developer.work.weixin.qq.com/document/path/90206
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="body"></param>
+    /// <returns></returns>
+    [Post("https://qyapi.weixin.qq.com/cgi-bin/department/update"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<BaseWorkOutput> Update([QueryString("access_token")] string accessToken, [Body] DepartmentHttpInput body);
+
+    /// <summary>
+    /// 删除部门
+    /// https://developer.work.weixin.qq.com/document/path/90207
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="id"></param>
+    /// <returns></returns>
+    [Get("https://qyapi.weixin.qq.com/cgi-bin/department/delete"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<BaseWorkOutput> Delete([QueryString("access_token")] string accessToken, [QueryString] long id);
+
+    /// <summary>
+    /// 获取部门Id列表
+    /// https://developer.work.weixin.qq.com/document/path/90208
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="id"></param>
+    /// <returns></returns>
+    [Get("https://qyapi.weixin.qq.com/cgi-bin/department/simplelist"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<DepartmentIdOutput> SimpleList([QueryString("access_token")] string accessToken, [QueryString] long id);
+
+    /// <summary>
+    /// 获取部门详情
+    /// https://developer.work.weixin.qq.com/document/path/90208
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="id"></param>
+    /// <returns></returns>
+    [Get("https://qyapi.weixin.qq.com/cgi-bin/department/get"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<DepartmentOutput> Get([QueryString("access_token")] string accessToken, [QueryString] long id);
+}

+ 53 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Tag/Dto/TagHttpInput.cs

@@ -0,0 +1,53 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// 
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+// 
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.WorkWeixin.Proxy;
+
+/// <summary>
+/// 标签输入参数
+/// </summary>
+public class TagHttpInput
+{
+    /// <summary>
+    /// 标签id
+    /// </summary>
+    [JsonProperty("tagid")]
+    [JsonPropertyName("tagid")]
+    public long? TagId { get; set; }
+
+    /// <summary>
+    /// 标签名称
+    /// </summary>
+    [JsonProperty("tagname")]
+    [JsonPropertyName("tagname")]
+    public string TagName { get; set; }
+}
+
+/// <summary>
+/// 增加标签成员输入参数
+/// </summary>
+public class TagUsersTagInput {
+    /// <summary>
+    /// 标签id
+    /// </summary>
+    [JsonProperty("tagid")]
+    [JsonPropertyName("tagid")]
+    public long TagId { get; set; }
+
+    /// <summary>
+    /// 企业成员ID列表
+    /// </summary>
+    [JsonProperty("userlist")]
+    [JsonPropertyName("userlist")]
+    public List<string> UserList { get; set; }
+
+    /// <summary>
+    /// 企业部门ID列表
+    /// </summary>
+    [JsonProperty("partylist")]
+    [JsonPropertyName("partylist")]
+    public List<long> PartyList { get; set; }
+}

+ 33 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Tag/Dto/TagHttpOutput.cs

@@ -0,0 +1,33 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// 
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+// 
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.WorkWeixin.Proxy;
+
+/// <summary>
+/// 新增标签输出参数
+/// </summary>
+public class TagIdHttpOutput : BaseWorkOutput
+{
+    /// <summary>
+    /// 标签Id
+    /// </summary>
+    [JsonProperty("tagid")]
+    [JsonPropertyName("tagid")]
+    public long? TagId { get; set; }
+}
+
+/// <summary>
+/// 标签列表输出参数
+/// </summary>
+public class TagListHttpOutput : BaseWorkOutput
+{
+    /// <summary>
+    /// 标签Id
+    /// </summary>
+    [JsonProperty("taglist")]
+    [JsonPropertyName("taglist")]
+    public List<TagHttpInput> TagList { get; set; }
+}

+ 83 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Proxy/Tag/ITagHttp.cs

@@ -0,0 +1,83 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.WorkWeixin.Proxy;
+
+/// <summary>
+/// 标签远程调用服务
+/// </summary>
+public interface ITagHttp : IHttpDispatchProxy
+{
+    /// <summary>
+    /// 创建标签
+    /// https://developer.work.weixin.qq.com/document/path/90210
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="body"></param>
+    /// <returns></returns>
+    [Post("https://qyapi.weixin.qq.com/cgi-bin/tag/create"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<BaseWorkIdOutput> Create([QueryString("access_token")] string accessToken, [Body] TagHttpInput body);
+
+    /// <summary>
+    /// 更新标签名字
+    /// https://developer.work.weixin.qq.com/document/path/90211
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="body"></param>
+    /// <returns></returns>
+    [Post("https://qyapi.weixin.qq.com/cgi-bin/tag/update"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<TagIdHttpOutput> Update([QueryString("access_token")] string accessToken, [Body] TagHttpInput body);
+
+    /// <summary>
+    /// 删除标签
+    /// https://developer.work.weixin.qq.com/document/path/90212
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="tagId"></param>
+    /// <returns></returns>
+    [Get("https://qyapi.weixin.qq.com/cgi-bin/tag/delete"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<BaseWorkOutput> Delete([QueryString("access_token")] string accessToken, [QueryString("tagid")] long tagId);
+
+    /// <summary>
+    /// 获取标签详情
+    /// https://developer.work.weixin.qq.com/document/path/90213
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="tagId"></param>
+    /// <returns></returns>
+    [Get("https://qyapi.weixin.qq.com/cgi-bin/tag/get"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<DepartmentOutput> Get([QueryString("access_token")] string accessToken, [QueryString("tagid")] long tagId);
+
+    /// <summary>
+    /// 增加标签成员
+    /// https://developer.work.weixin.qq.com/document/path/90214
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="body"></param>
+    /// <returns></returns>
+    [Post("https://qyapi.weixin.qq.com/cgi-bin/tag/addtagusers"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<DepartmentOutput> AddTagUsers([QueryString("access_token")] string accessToken, [Body] TagUsersTagInput body);
+
+    /// <summary>
+    /// 删除标签成员
+    /// https://developer.work.weixin.qq.com/document/path/90215
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="body"></param>
+    /// <returns></returns>
+    [Post("https://qyapi.weixin.qq.com/cgi-bin/tag/deltagusers"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<DepartmentOutput> DelTagUsers([QueryString("access_token")] string accessToken, [Body] TagUsersTagInput body);
+
+    /// <summary>
+    /// 获取标签列表
+    /// https://developer.work.weixin.qq.com/document/path/90216
+    /// </summary>
+    /// <param name="accessToken"></param>
+    /// <param name="body"></param>
+    /// <returns></returns>
+    [Get("https://qyapi.weixin.qq.com/cgi-bin/tag/list"), JsonSerialization(typeof(NewtonsoftJsonSerializerProvider))]
+    Task<TagListHttpOutput> List([QueryString("access_token")] string accessToken);
+}

+ 25 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Startup.cs

@@ -0,0 +1,25 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+//
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+//
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+using Admin.NET.Plugin.WorkWeixin.Option;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace Admin.NET.Plugin.WorkWeixin;
+
+[AppStartup(100)]
+public class Startup : AppStartup
+{
+    public void ConfigureServices(IServiceCollection services)
+    {
+        services.AddConfigurableOptions<WorkWeixinOptions>();
+    }
+
+    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
+    {
+    }
+}

+ 40 - 0
Admin.NET/Plugins/Admin.NET.Plugin.WorkWeixin/Utils/BaseHttpOutput.cs

@@ -0,0 +1,40 @@
+// Admin.NET 项目的版权、商标、专利和其他相关权利均受相应法律法规的保护。使用本项目应遵守相关法律法规和许可证的要求。
+// 
+// 本项目主要遵循 MIT 许可证和 Apache 许可证(版本 2.0)进行分发和使用。许可证位于源代码树根目录中的 LICENSE-MIT 和 LICENSE-APACHE 文件。
+// 
+// 不得利用本项目从事危害国家安全、扰乱社会秩序、侵犯他人合法权益等法律法规禁止的活动!任何基于本项目二次开发而产生的一切法律纠纷和责任,我们不承担任何责任!
+
+namespace Admin.NET.Plugin.WorkWeixin;
+
+/// <summary>
+/// 企业微信接口输出基类
+/// </summary>
+public class BaseWorkOutput
+{
+    /// <summary>
+    /// 返回码
+    /// </summary>
+    [JsonProperty("errcode")]
+    [JsonPropertyName("errcode")]
+    public int ErrCode { get; set; }
+
+    /// <summary>
+    /// 对返回码的文本描述内容
+    /// </summary>
+    [JsonProperty("errmsg")]
+    [JsonPropertyName("errmsg")]
+    public string ErrMsg { get; set; }
+}
+
+/// <summary>
+/// 带id的输出参数
+/// </summary>
+public class BaseWorkIdOutput : BaseWorkOutput
+{
+    /// <summary>
+    /// id
+    /// </summary>
+    [JsonProperty("id")]
+    [JsonPropertyName("id")]
+    public long? Id { get; set; }
+}