21 changed files with 799 additions and 2 deletions
@ -0,0 +1,17 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Work.Security.Models; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Security; |
||||
|
public interface IWeChatWorkServerProvider |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 获取企业微信域名IP信息
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 参考:https://developer.work.weixin.qq.com/document/path/100079
|
||||
|
/// </remarks>
|
||||
|
/// <param name="cancellationToken"></param>
|
||||
|
/// <returns></returns>
|
||||
|
Task<WeChatServerDomainModel> GetWeChatServerAsync(CancellationToken cancellationToken = default); |
||||
|
} |
||||
@ -0,0 +1,44 @@ |
|||||
|
using Newtonsoft.Json; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Security.Models; |
||||
|
public class WeChatDomainModel |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 域名
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("domain")] |
||||
|
[JsonPropertyName("domain")] |
||||
|
public string Domain { get; set; } = default!; |
||||
|
/// <summary>
|
||||
|
/// 泛域名
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("universal_domian")] |
||||
|
[JsonPropertyName("universal_domian")] |
||||
|
public string UniversalDomian { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 协议 如TCP UDP
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("protocol")] |
||||
|
[JsonPropertyName("protocol")] |
||||
|
public string Protocol { get; set; } = default!; |
||||
|
/// <summary>
|
||||
|
/// 端口号列表
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("port")] |
||||
|
[JsonPropertyName("port")] |
||||
|
public List<int> Port { get; set; } = new List<int>(); |
||||
|
/// <summary>
|
||||
|
/// 是否必要,0-否 1-是, 如果必要的域名或IP被拦截,将导致企业微信的功能出现异常
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("is_necessary")] |
||||
|
[JsonPropertyName("is_necessary")] |
||||
|
public int IsNecessary { get; set; } = default!; |
||||
|
/// <summary>
|
||||
|
/// IP涉及到的功能的描述信息
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("description")] |
||||
|
[JsonPropertyName("description")] |
||||
|
public string Description { get; set; } |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
using Newtonsoft.Json; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Security.Models; |
||||
|
public class WeChatIpModel |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// ip地址
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("ip")] |
||||
|
[JsonPropertyName("ip")] |
||||
|
public string Ip { get; set; } = default!; |
||||
|
/// <summary>
|
||||
|
/// 协议 如TCP UDP
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("protocol")] |
||||
|
[JsonPropertyName("protocol")] |
||||
|
public string Protocol { get; set; } = default!; |
||||
|
/// <summary>
|
||||
|
/// 端口号列表
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("port")] |
||||
|
[JsonPropertyName("port")] |
||||
|
public List<int> Port { get; set; } = new List<int>(); |
||||
|
/// <summary>
|
||||
|
/// 是否必要,0-否 1-是, 如果必要的域名或IP被拦截,将导致企业微信的功能出现异常
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("is_necessary")] |
||||
|
[JsonPropertyName("is_necessary")] |
||||
|
public int IsNecessary { get; set; } = default!; |
||||
|
/// <summary>
|
||||
|
/// IP涉及到的功能的描述信息
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("description")] |
||||
|
[JsonPropertyName("description")] |
||||
|
public string Description { get; set; } |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using Newtonsoft.Json; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Security.Models; |
||||
|
public class WeChatServerDomainModel |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 域名列表
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("domain_list")] |
||||
|
[JsonPropertyName("domain_list")] |
||||
|
public List<WeChatDomainModel> Domains { get; } |
||||
|
/// <summary>
|
||||
|
/// Ip列表
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("ip_list")] |
||||
|
[JsonPropertyName("ip_list")] |
||||
|
public List<WeChatIpModel> Ips { get; } |
||||
|
public WeChatServerDomainModel(List<WeChatDomainModel> domains, List<WeChatIpModel> ips) |
||||
|
{ |
||||
|
Domains = domains; |
||||
|
Ips = ips; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,22 @@ |
|||||
|
using Newtonsoft.Json; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Security.Models; |
||||
|
public class WeChatServerDomainResponse : WeChatWorkResponse |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 域名列表
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("domain_list")] |
||||
|
public List<WeChatDomainModel> Domains { get; set; } = new List<WeChatDomainModel>(); |
||||
|
/// <summary>
|
||||
|
/// Ip列表
|
||||
|
/// </summary>
|
||||
|
[JsonProperty("ip_list")] |
||||
|
public List<WeChatIpModel> Ips { get; set; } = new List<WeChatIpModel>(); |
||||
|
public WeChatServerDomainModel ToServerDomain() |
||||
|
{ |
||||
|
ThrowIfNotSuccess(); |
||||
|
return new WeChatServerDomainModel(Domains, Ips); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,32 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Work.Security.Models; |
||||
|
using LINGYUN.Abp.WeChat.Work.Token; |
||||
|
using System.Net.Http; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Security; |
||||
|
public class WeChatWorkServerProvider : IWeChatWorkServerProvider, ISingletonDependency |
||||
|
{ |
||||
|
protected IHttpClientFactory HttpClientFactory { get; } |
||||
|
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; } |
||||
|
|
||||
|
public WeChatWorkServerProvider( |
||||
|
IHttpClientFactory httpClientFactory, |
||||
|
IWeChatWorkTokenProvider weChatWorkTokenProvider) |
||||
|
{ |
||||
|
HttpClientFactory = httpClientFactory; |
||||
|
WeChatWorkTokenProvider = weChatWorkTokenProvider; |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<WeChatServerDomainModel> GetWeChatServerAsync(CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
||||
|
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
||||
|
|
||||
|
using var response = await client.GetServerDomainIpAsync(token.AccessToken, cancellationToken); |
||||
|
var serverDomainResponse = await response.DeserializeObjectAsync<WeChatServerDomainResponse>(); |
||||
|
|
||||
|
return serverDomainResponse.ToServerDomain(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,93 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Work.Tags.Request; |
||||
|
using LINGYUN.Abp.WeChat.Work.Tags.Response; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags; |
||||
|
/// <summary>
|
||||
|
/// 标签管理接口
|
||||
|
/// </summary>
|
||||
|
public interface IWeChatWorkTagProvider |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 创建标签
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 详情见:https://developer.work.weixin.qq.com/document/path/90210
|
||||
|
/// </remarks>
|
||||
|
/// <param name="request">创建标签请求参数</param>
|
||||
|
/// <param name="cancellationToken"></param>
|
||||
|
/// <returns>创建标签响应参数</returns>
|
||||
|
Task<WeChatWorkTagCreateResponse> CreateAsync( |
||||
|
WeChatWorkTagCreateRequest request, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
/// <summary>
|
||||
|
/// 更新标签名字
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 详情见:https://developer.work.weixin.qq.com/document/path/90211
|
||||
|
/// </remarks>
|
||||
|
/// <param name="request">更新标签名字请求参数</param>
|
||||
|
/// <param name="cancellationToken"></param>
|
||||
|
/// <returns>更新标签名字响应参数</returns>
|
||||
|
Task<WeChatWorkResponse> UpdateAsync( |
||||
|
WeChatWorkTagUpdateRequest request, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
/// <summary>
|
||||
|
/// 删除标签
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 详情见:https://developer.work.weixin.qq.com/document/path/90212
|
||||
|
/// </remarks>
|
||||
|
/// <param name="request">删除标签请求参数</param>
|
||||
|
/// <param name="cancellationToken"></param>
|
||||
|
/// <returns>删除标签响应参数</returns>
|
||||
|
Task<WeChatWorkResponse> DeleteAsync( |
||||
|
WeChatWorkGetTagRequest request, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
/// <summary>
|
||||
|
/// 获取标签成员
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 详情见:https://developer.work.weixin.qq.com/document/path/90213
|
||||
|
/// </remarks>
|
||||
|
/// <param name="request">获取标签成员请求参数</param>
|
||||
|
/// <param name="cancellationToken"></param>
|
||||
|
/// <returns>获取标签成员响应参数</returns>
|
||||
|
Task<WeChatWorkTagMemberInfoResponse> GetMemberAsync( |
||||
|
WeChatWorkGetTagRequest request, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
/// <summary>
|
||||
|
/// 增加标签成员
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 详情见:https://developer.work.weixin.qq.com/document/path/90214
|
||||
|
/// </remarks>
|
||||
|
/// <param name="request">增加标签成员请求参数</param>
|
||||
|
/// <param name="cancellationToken"></param>
|
||||
|
/// <returns>增加标签成员响应参数</returns>
|
||||
|
Task<WeChatWorkTagChangeMemberResponse> AddMemberAsync( |
||||
|
WeChatWorkTagChangeMemberRequest request, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
/// <summary>
|
||||
|
/// 增加标签成员
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 详情见:https://developer.work.weixin.qq.com/document/path/90214
|
||||
|
/// </remarks>
|
||||
|
/// <param name="request">增加标签成员请求参数</param>
|
||||
|
/// <param name="cancellationToken"></param>
|
||||
|
/// <returns>增加标签成员响应参数</returns>
|
||||
|
Task<WeChatWorkTagChangeMemberResponse> DeleteMemberAsync( |
||||
|
WeChatWorkTagChangeMemberRequest request, |
||||
|
CancellationToken cancellationToken = default); |
||||
|
/// <summary>
|
||||
|
/// 获取标签列表
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 详情见:https://developer.work.weixin.qq.com/document/path/90214
|
||||
|
/// </remarks>
|
||||
|
/// <param name="cancellationToken"></param>
|
||||
|
/// <returns>获取标签列表响应参数</returns>
|
||||
|
Task<WeChatWorkTagListResponse> GetListAsync(CancellationToken cancellationToken = default); |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Newtonsoft.Json; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags.Models; |
||||
|
/// <summary>
|
||||
|
/// 标签
|
||||
|
/// </summary>
|
||||
|
public class TagInfo |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 标签id
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("tagid")] |
||||
|
[JsonPropertyName("tagid")] |
||||
|
public int TagId { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 标签名
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("tagname")] |
||||
|
[JsonPropertyName("tagname")] |
||||
|
public string TagName { get; set; } |
||||
|
} |
||||
@ -0,0 +1,25 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Newtonsoft.Json; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags.Models; |
||||
|
/// <summary>
|
||||
|
/// 标签中包含的成员
|
||||
|
/// </summary>
|
||||
|
public class TagUserInfo |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 成员账号
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("userid")] |
||||
|
[JsonPropertyName("userid")] |
||||
|
public string UserId { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 成员名称
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("name")] |
||||
|
[JsonPropertyName("name")] |
||||
|
public string Name { get; set; } |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Newtonsoft.Json; |
||||
|
using System.Text.Json.Serialization; |
||||
|
using Volo.Abp; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags.Request; |
||||
|
/// <summary>
|
||||
|
/// 获取标签请求参数
|
||||
|
/// </summary>
|
||||
|
public class WeChatWorkGetTagRequest |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 标签id
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("tagid")] |
||||
|
[JsonPropertyName("tagid")] |
||||
|
public int TagId { get; set; } |
||||
|
public WeChatWorkGetTagRequest(int tagId) |
||||
|
{ |
||||
|
TagId = Check.Positive(tagId, nameof(tagId)); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,57 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Newtonsoft.Json; |
||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text.Json.Serialization; |
||||
|
using Volo.Abp; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags.Request; |
||||
|
/// <summary>
|
||||
|
/// 标签成员变更请求参数
|
||||
|
/// </summary>
|
||||
|
public class WeChatWorkTagChangeMemberRequest |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 标签id,非负整型,指定此参数时新增的标签会生成对应的标签id,不指定时则以目前最大的id自增。
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("tagid")] |
||||
|
[JsonPropertyName("tagid")] |
||||
|
public int TagId { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 企业成员ID列表,注意:userlist、partylist不能同时为空,单次请求个数不超过1000
|
||||
|
/// </summary>
|
||||
|
[CanBeNull] |
||||
|
[JsonProperty("userlist")] |
||||
|
[JsonPropertyName("userlist")] |
||||
|
public List<string> Users { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 企业部门ID列表,注意:userlist、partylist不能同时为空,单次请求个数不超过100
|
||||
|
/// </summary>
|
||||
|
[CanBeNull] |
||||
|
[JsonProperty("partylist")] |
||||
|
[JsonPropertyName("partylist")] |
||||
|
public List<int> Parts { get; set; } |
||||
|
public WeChatWorkTagChangeMemberRequest( |
||||
|
int tagId, |
||||
|
List<string> users = null, |
||||
|
List<int> parts = null) |
||||
|
{ |
||||
|
TagId = Check.Positive(tagId, nameof(tagId)); |
||||
|
Users = users; |
||||
|
Parts = parts; |
||||
|
|
||||
|
if (users == null && parts == null) |
||||
|
{ |
||||
|
throw new ArgumentNullException("users/parts", "userlist、partylist不能同时为空!"); |
||||
|
} |
||||
|
if (users.Count > 1000) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(users), "企业成员ID列表单次请求个数不超过1000!"); |
||||
|
} |
||||
|
if (parts.Count > 100) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(users), "企业部门ID列表单次请求个数不超过100!"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Newtonsoft.Json; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using System.Text.Json.Serialization; |
||||
|
using Volo.Abp; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags.Request; |
||||
|
/// <summary>
|
||||
|
/// 创建标签请求参数
|
||||
|
/// </summary>
|
||||
|
public class WeChatWorkTagCreateRequest |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 标签id,非负整型,指定此参数时新增的标签会生成对应的标签id,不指定时则以目前最大的id自增。
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("tagid")] |
||||
|
[JsonPropertyName("tagid")] |
||||
|
public int? TagId { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 标签名称,长度限制为32个字以内(汉字或英文字母),标签名不可与其他标签重名。
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[StringLength(32)] |
||||
|
[JsonProperty("tagname")] |
||||
|
[JsonPropertyName("tagname")] |
||||
|
public string TagName { get; set; } |
||||
|
public WeChatWorkTagCreateRequest(string tagName, int? tagId = null) |
||||
|
{ |
||||
|
TagName = Check.NotNullOrWhiteSpace(tagName, nameof(tagName), 32); |
||||
|
TagId = tagId; |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,33 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Newtonsoft.Json; |
||||
|
using System.ComponentModel.DataAnnotations; |
||||
|
using System.Text.Json.Serialization; |
||||
|
using Volo.Abp; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags.Request; |
||||
|
/// <summary>
|
||||
|
/// 更新标签请求参数
|
||||
|
/// </summary>
|
||||
|
public class WeChatWorkTagUpdateRequest |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 标签id,非负整型,指定此参数时新增的标签会生成对应的标签id,不指定时则以目前最大的id自增。
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("tagid")] |
||||
|
[JsonPropertyName("tagid")] |
||||
|
public int TagId { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 标签名称,长度限制为32个字以内(汉字或英文字母),标签名不可与其他标签重名。
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[StringLength(32)] |
||||
|
[JsonProperty("tagname")] |
||||
|
[JsonPropertyName("tagname")] |
||||
|
public string TagName { get; set; } |
||||
|
public WeChatWorkTagUpdateRequest(int tagId, string tagName) |
||||
|
{ |
||||
|
TagId = Check.Positive(tagId, nameof(tagId)); |
||||
|
TagName = Check.NotNullOrWhiteSpace(tagName, nameof(tagName), 32); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,26 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Newtonsoft.Json; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags.Response; |
||||
|
/// <summary>
|
||||
|
/// 标签成员变更响应参数
|
||||
|
/// </summary>
|
||||
|
public class WeChatWorkTagChangeMemberResponse : WeChatWorkResponse |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 若部分userid非法,则返回
|
||||
|
/// </summary>
|
||||
|
[CanBeNull] |
||||
|
[JsonProperty("invalidlist")] |
||||
|
[JsonPropertyName("invalidlist")] |
||||
|
public string InvalidList { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 若部分partylist非法,则返回
|
||||
|
/// </summary>
|
||||
|
[CanBeNull] |
||||
|
[JsonProperty("invalidparty")] |
||||
|
[JsonPropertyName("invalidparty")] |
||||
|
public List<int> InvalidPart { get; set; } |
||||
|
} |
||||
@ -0,0 +1,21 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using Newtonsoft.Json; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags.Response; |
||||
|
/// <summary>
|
||||
|
/// 创建标签响应参数
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 详情见: https://developer.work.weixin.qq.com/document/path/90210
|
||||
|
/// </remarks>
|
||||
|
public class WeChatWorkTagCreateResponse : WeChatWorkResponse |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 标签id
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("tagid")] |
||||
|
[JsonPropertyName("tagid")] |
||||
|
public string TagId { get; set; } |
||||
|
} |
||||
@ -0,0 +1,23 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using LINGYUN.Abp.WeChat.Work.Tags.Models; |
||||
|
using Newtonsoft.Json; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags.Response; |
||||
|
/// <summary>
|
||||
|
/// 获取标签列表响应参数
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 详情见: https://developer.work.weixin.qq.com/document/path/90216
|
||||
|
/// </remarks>
|
||||
|
public class WeChatWorkTagListResponse : WeChatWorkResponse |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 标签列表
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("taglist")] |
||||
|
[JsonPropertyName("taglist")] |
||||
|
public List<TagInfo> Tags { get; set; } |
||||
|
} |
||||
@ -0,0 +1,37 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
using LINGYUN.Abp.WeChat.Work.Tags.Models; |
||||
|
using Newtonsoft.Json; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Text.Json.Serialization; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags.Response; |
||||
|
/// <summary>
|
||||
|
/// 标签成员响应参数
|
||||
|
/// </summary>
|
||||
|
/// <remarks>
|
||||
|
/// 详情见: https://developer.work.weixin.qq.com/document/path/90213
|
||||
|
/// </remarks>
|
||||
|
public class WeChatWorkTagMemberInfoResponse : WeChatWorkResponse |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// 标签名
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("tagname")] |
||||
|
[JsonPropertyName("tagname")] |
||||
|
public string TagName { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 标签中包含的成员列表
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("userlist")] |
||||
|
[JsonPropertyName("userlist")] |
||||
|
public List<TagUserInfo> Users { get; set; } |
||||
|
/// <summary>
|
||||
|
/// 标签中包含的部门id列表
|
||||
|
/// </summary>
|
||||
|
[NotNull] |
||||
|
[JsonProperty("partylist")] |
||||
|
[JsonPropertyName("partylist")] |
||||
|
public List<int> Parts { get; set; } |
||||
|
} |
||||
@ -0,0 +1,89 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Work.Features; |
||||
|
using LINGYUN.Abp.WeChat.Work.Tags.Request; |
||||
|
using LINGYUN.Abp.WeChat.Work.Tags.Response; |
||||
|
using LINGYUN.Abp.WeChat.Work.Token; |
||||
|
using System.Net.Http; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
using Volo.Abp.Features; |
||||
|
|
||||
|
namespace LINGYUN.Abp.WeChat.Work.Tags; |
||||
|
|
||||
|
[RequiresFeature(WeChatWorkFeatureNames.Enable)] |
||||
|
public class WeChatWorkTagProvider : IWeChatWorkTagProvider, ISingletonDependency |
||||
|
{ |
||||
|
protected IHttpClientFactory HttpClientFactory { get; } |
||||
|
protected IWeChatWorkTokenProvider WeChatWorkTokenProvider { get; } |
||||
|
|
||||
|
public WeChatWorkTagProvider( |
||||
|
IHttpClientFactory httpClientFactory, |
||||
|
IWeChatWorkTokenProvider weChatWorkTokenProvider) |
||||
|
{ |
||||
|
HttpClientFactory = httpClientFactory; |
||||
|
WeChatWorkTokenProvider = weChatWorkTokenProvider; |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<WeChatWorkTagChangeMemberResponse> AddMemberAsync(WeChatWorkTagChangeMemberRequest request, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
||||
|
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
||||
|
|
||||
|
using var response = await client.AddTagMemberAsync(token.AccessToken, request, cancellationToken); |
||||
|
return await response.DeserializeObjectAsync<WeChatWorkTagChangeMemberResponse>(); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<WeChatWorkTagCreateResponse> CreateAsync(WeChatWorkTagCreateRequest request, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
||||
|
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
||||
|
|
||||
|
using var response = await client.CreateTagAsync(token.AccessToken, request, cancellationToken); |
||||
|
return await response.DeserializeObjectAsync<WeChatWorkTagCreateResponse>(); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<WeChatWorkResponse> DeleteAsync(WeChatWorkGetTagRequest request, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
||||
|
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
||||
|
|
||||
|
using var response = await client.DeleteTagAsync(token.AccessToken, request, cancellationToken); |
||||
|
return await response.DeserializeObjectAsync<WeChatWorkResponse>(); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<WeChatWorkTagChangeMemberResponse> DeleteMemberAsync(WeChatWorkTagChangeMemberRequest request, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
||||
|
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
||||
|
|
||||
|
using var response = await client.DeleteTagMemberAsync(token.AccessToken, request, cancellationToken); |
||||
|
return await response.DeserializeObjectAsync<WeChatWorkTagChangeMemberResponse>(); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<WeChatWorkTagListResponse> GetListAsync(CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
||||
|
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
||||
|
|
||||
|
using var response = await client.GetTagListAsync(token.AccessToken, cancellationToken); |
||||
|
return await response.DeserializeObjectAsync<WeChatWorkTagListResponse>(); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<WeChatWorkTagMemberInfoResponse> GetMemberAsync(WeChatWorkGetTagRequest request, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
||||
|
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
||||
|
|
||||
|
using var response = await client.GetTagMemberAsync(token.AccessToken, request, cancellationToken); |
||||
|
return await response.DeserializeObjectAsync<WeChatWorkTagMemberInfoResponse>(); |
||||
|
} |
||||
|
|
||||
|
public async virtual Task<WeChatWorkResponse> UpdateAsync(WeChatWorkTagUpdateRequest request, CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var token = await WeChatWorkTokenProvider.GetTokenAsync(cancellationToken); |
||||
|
var client = HttpClientFactory.CreateClient(AbpWeChatWorkGlobalConsts.ApiClient); |
||||
|
|
||||
|
using var response = await client.UpdateTagAsync(token.AccessToken, request, cancellationToken); |
||||
|
return await response.DeserializeObjectAsync<WeChatWorkResponse>(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,134 @@ |
|||||
|
using LINGYUN.Abp.WeChat.Work.Tags.Request; |
||||
|
using System.Text; |
||||
|
using System.Threading; |
||||
|
using System.Threading.Tasks; |
||||
|
|
||||
|
namespace System.Net.Http; |
||||
|
internal static partial class HttpClientWeChatWorkRequestExtensions |
||||
|
{ |
||||
|
public async static Task<HttpResponseMessage> AddTagMemberAsync( |
||||
|
this HttpMessageInvoker client, |
||||
|
string accessToken, |
||||
|
WeChatWorkTagChangeMemberRequest request, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var urlBuilder = new StringBuilder(); |
||||
|
urlBuilder.Append("/cgi-bin/tag/addtagusers"); |
||||
|
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
||||
|
|
||||
|
var httpRequest = new HttpRequestMessage( |
||||
|
HttpMethod.Post, |
||||
|
urlBuilder.ToString()) |
||||
|
{ |
||||
|
Content = new StringContent(request.SerializeToJson()) |
||||
|
}; |
||||
|
|
||||
|
return await client.SendAsync(httpRequest, cancellationToken); |
||||
|
} |
||||
|
public async static Task<HttpResponseMessage> CreateTagAsync( |
||||
|
this HttpMessageInvoker client, |
||||
|
string accessToken, |
||||
|
WeChatWorkTagCreateRequest request, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var urlBuilder = new StringBuilder(); |
||||
|
urlBuilder.Append("/cgi-bin/tag/create"); |
||||
|
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
||||
|
|
||||
|
var httpRequest = new HttpRequestMessage( |
||||
|
HttpMethod.Post, |
||||
|
urlBuilder.ToString()) |
||||
|
{ |
||||
|
Content = new StringContent(request.SerializeToJson()) |
||||
|
}; |
||||
|
|
||||
|
return await client.SendAsync(httpRequest, cancellationToken); |
||||
|
} |
||||
|
public async static Task<HttpResponseMessage> DeleteTagAsync( |
||||
|
this HttpMessageInvoker client, |
||||
|
string accessToken, |
||||
|
WeChatWorkGetTagRequest request, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var urlBuilder = new StringBuilder(); |
||||
|
urlBuilder.Append("/cgi-bin/tag/delete"); |
||||
|
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
||||
|
urlBuilder.AppendFormat("&tagid={0}", request.TagId); |
||||
|
|
||||
|
var httpRequest = new HttpRequestMessage( |
||||
|
HttpMethod.Get, |
||||
|
urlBuilder.ToString()); |
||||
|
|
||||
|
return await client.SendAsync(httpRequest, cancellationToken); |
||||
|
} |
||||
|
public async static Task<HttpResponseMessage> DeleteTagMemberAsync( |
||||
|
this HttpMessageInvoker client, |
||||
|
string accessToken, |
||||
|
WeChatWorkTagChangeMemberRequest request, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var urlBuilder = new StringBuilder(); |
||||
|
urlBuilder.Append("/cgi-bin/tag/deltagusers"); |
||||
|
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
||||
|
|
||||
|
var httpRequest = new HttpRequestMessage( |
||||
|
HttpMethod.Post, |
||||
|
urlBuilder.ToString()) |
||||
|
{ |
||||
|
Content = new StringContent(request.SerializeToJson()) |
||||
|
}; |
||||
|
|
||||
|
return await client.SendAsync(httpRequest, cancellationToken); |
||||
|
} |
||||
|
public async static Task<HttpResponseMessage> GetTagListAsync( |
||||
|
this HttpMessageInvoker client, |
||||
|
string accessToken, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var urlBuilder = new StringBuilder(); |
||||
|
urlBuilder.Append("/cgi-bin/tag/list"); |
||||
|
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
||||
|
|
||||
|
var httpRequest = new HttpRequestMessage( |
||||
|
HttpMethod.Get, |
||||
|
urlBuilder.ToString()); |
||||
|
|
||||
|
return await client.SendAsync(httpRequest, cancellationToken); |
||||
|
} |
||||
|
public async static Task<HttpResponseMessage> GetTagMemberAsync( |
||||
|
this HttpMessageInvoker client, |
||||
|
string accessToken, |
||||
|
WeChatWorkGetTagRequest request, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var urlBuilder = new StringBuilder(); |
||||
|
urlBuilder.Append("/cgi-bin/tag/get"); |
||||
|
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
||||
|
urlBuilder.AppendFormat("&tagid={0}", request.TagId); |
||||
|
|
||||
|
var httpRequest = new HttpRequestMessage( |
||||
|
HttpMethod.Get, |
||||
|
urlBuilder.ToString()); |
||||
|
|
||||
|
return await client.SendAsync(httpRequest, cancellationToken); |
||||
|
} |
||||
|
public async static Task<HttpResponseMessage> UpdateTagAsync( |
||||
|
this HttpMessageInvoker client, |
||||
|
string accessToken, |
||||
|
WeChatWorkTagUpdateRequest request, |
||||
|
CancellationToken cancellationToken = default) |
||||
|
{ |
||||
|
var urlBuilder = new StringBuilder(); |
||||
|
urlBuilder.Append("/cgi-bin/tag/update"); |
||||
|
urlBuilder.AppendFormat("?access_token={0}", accessToken); |
||||
|
|
||||
|
var httpRequest = new HttpRequestMessage( |
||||
|
HttpMethod.Post, |
||||
|
urlBuilder.ToString()) |
||||
|
{ |
||||
|
Content = new StringContent(request.SerializeToJson()) |
||||
|
}; |
||||
|
|
||||
|
return await client.SendAsync(httpRequest, cancellationToken); |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue