diff --git a/docs/WechatWork/Advanced_ModelDefinition.md b/docs/WechatWork/Advanced_ModelDefinition.md index d3a5cdd0..be444ccb 100644 --- a/docs/WechatWork/Advanced_ModelDefinition.md +++ b/docs/WechatWork/Advanced_ModelDefinition.md @@ -97,8 +97,10 @@ | √ | 政民沟通:巡查上报 | 企业 | | | √ | 政民沟通:居民上报 | 企业 | | | √ | 政民沟通:防疫场所码 | 企业 | | +| √ | 接口调用许可 | 服务商 | | | √ | 应用授权 | 服务商 & 硬件接入 | | | √ | 推广二维码 | 服务商 & 硬件接入 | | +| √ | 自建应用代开发 | 服务商 | | | √ | 设备管理 | 硬件接入 | | diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/LicenseAutoActivateEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/LicenseAutoActivateEvent.cs new file mode 100644 index 00000000..a3989dc5 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/LicenseAutoActivateEvent.cs @@ -0,0 +1,75 @@ +namespace SKIT.FlurlHttpClient.Wechat.Work.Events +{ + /// + /// 表示 INFO.auto_activate 事件的数据。 + /// REF: https://developer.work.weixin.qq.com/document/path/95994 + /// + public class LicenseAutoActivateEvent : WechatWorkEvent, WechatWorkEvent.Serialization.IXmlSerializable + { + public static class Types + { + public class Account + { + /// + /// 获取或设置激活码。 + /// + [System.Xml.Serialization.XmlElement("ActiveCode")] + public string ActiveCode { get; set; } = default!; + + /// + /// 获取或设置类型。 + /// + [System.Xml.Serialization.XmlElement("Type")] + public int Type { get; set; } + + /// + /// 获取或设置许可到期时间戳。 + /// + [System.Xml.Serialization.XmlElement("ExpireTime")] + public long ExpireTimestamp { get; set; } + + /// + /// 获取或设置成员 UserId。 + /// + [System.Xml.Serialization.XmlElement("UserId")] + public string UserId { get; set; } = default!; + + /// + /// 获取或设置之前的许可状态。 + /// + [System.Xml.Serialization.XmlElement("PreviousStatus", IsNullable = true)] + public int? PreviousStatus { get; set; } + + /// + /// 获取或设置之前的激活码。 + /// + [System.Xml.Serialization.XmlElement("PreviousActiveCode", IsNullable = true)] + public string? PreviousActiveCode { get; set; } + } + } + + /// + /// 获取或设置服务商 CorpId。 + /// + [System.Xml.Serialization.XmlElement("ServiceCorpId")] + public string ServiceCorpId { get; set; } = default!; + + /// + /// 获取或设置授权方的 CorpId。 + /// + [System.Xml.Serialization.XmlElement("AuthCorpId", IsNullable = true)] + public string? AuthorizerCorpId { get; set; } + + /// + /// 获取或设置许可自动激活场景值。 + /// + [System.Xml.Serialization.XmlElement("Scene")] + public int Scene { get; set; } + + /// + /// 获取或设置激活的许可帐号列表。 + /// + [System.Xml.Serialization.XmlElement("AccountList", Type = typeof(Types.Account))] + public Types.Account[] AccountList { get; set; } = default!; + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/LicensePaySuccessEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/LicensePaySuccessEvent.cs new file mode 100644 index 00000000..6b677e6f --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/LicensePaySuccessEvent.cs @@ -0,0 +1,33 @@ +namespace SKIT.FlurlHttpClient.Wechat.Work.Events +{ + /// + /// 表示 INFO.license_pay_success 事件的数据。 + /// REF: https://developer.work.weixin.qq.com/document/path/95716 + /// + public class LicensePaySuccessEvent : WechatWorkEvent, WechatWorkEvent.Serialization.IXmlSerializable + { + /// + /// 获取或设置服务商 CorpId。 + /// + [System.Xml.Serialization.XmlElement("ServiceCorpId")] + public string ServiceCorpId { get; set; } = default!; + + /// + /// 获取或设置授权方的 CorpId。 + /// + [System.Xml.Serialization.XmlElement("AuthCorpId", IsNullable = true)] + public string? AuthorizerCorpId { get; set; } + + /// + /// 获取或设置订单号。 + /// + [System.Xml.Serialization.XmlElement("OrderId")] + public string OrderId { get; set; } = default!; + + /// + /// 获取或设置服务商内下单用户 UserId。 + /// + [System.Xml.Serialization.XmlElement("BuyerUserId", IsNullable = true)] + public string? BuyerUserId { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/LicenseRefundEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/LicenseRefundEvent.cs new file mode 100644 index 00000000..86126253 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/LicenseRefundEvent.cs @@ -0,0 +1,33 @@ +namespace SKIT.FlurlHttpClient.Wechat.Work.Events +{ + /// + /// 表示 INFO.license_refund 事件的数据。 + /// REF: https://developer.work.weixin.qq.com/document/path/95805 + /// + public class LicenseRefundEvent : WechatWorkEvent, WechatWorkEvent.Serialization.IXmlSerializable + { + /// + /// 获取或设置服务商 CorpId。 + /// + [System.Xml.Serialization.XmlElement("ServiceCorpId")] + public string ServiceCorpId { get; set; } = default!; + + /// + /// 获取或设置授权方的 CorpId。 + /// + [System.Xml.Serialization.XmlElement("AuthCorpId", IsNullable = true)] + public string? AuthorizerCorpId { get; set; } + + /// + /// 获取或设置订单号。 + /// + [System.Xml.Serialization.XmlElement("OrderId")] + public string OrderId { get; set; } = default!; + + /// + /// 获取或设置订单状态。 + /// + [System.Xml.Serialization.XmlElement("OrderStatus")] + public int OrderStatus { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/UnlicensedNotifyEvent.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/UnlicensedNotifyEvent.cs new file mode 100644 index 00000000..d26fe91f --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Events/License/UnlicensedNotifyEvent.cs @@ -0,0 +1,15 @@ +namespace SKIT.FlurlHttpClient.Wechat.Work.Events +{ + /// + /// 表示 EVENT.unlicensed_notify 事件的数据。 + /// REF: https://developer.work.weixin.qq.com/document/path/95716 + /// + public class UnlicensedNotifyEvent : WechatWorkEvent, WechatWorkEvent.Serialization.IXmlSerializable + { + /// + /// 获取或设置应用 ID。 + /// + [System.Xml.Serialization.XmlElement("AgentID")] + public int AgentId { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientExecuteCgibinLicenseExtensions.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientExecuteCgibinLicenseExtensions.cs new file mode 100644 index 00000000..5aff7281 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Extensions/WechatWorkClientExecuteCgibinLicenseExtensions.cs @@ -0,0 +1,37 @@ +using System; +using System.Net.Http; +using System.Threading; +using System.Threading.Tasks; +using Flurl; +using Flurl.Http; + +namespace SKIT.FlurlHttpClient.Wechat.Work +{ + public static class WechatWorkClientExecuteCgibinLicenseExtensions + { + #region App + /// + /// 异步调用 [POST] /cgi-bin/license/get_app_license_info 接口。 + /// REF: https://developer.work.weixin.qq.com/document/path/95844 + /// + /// + /// + /// + /// + public static async Task ExecuteCgibinLicenseGetAppLicenseInfoAsync(this WechatWorkClient client, Models.CgibinLicenseGetAppLicenseInfoRequest request, CancellationToken cancellationToken = default) + { + if (client is null) throw new ArgumentNullException(nameof(client)); + if (request is null) throw new ArgumentNullException(nameof(request)); + + if (request.SuiteId == null) + request.SuiteId = client.Credentials.SuiteId; + + IFlurlRequest flurlReq = client + .CreateRequest(request, HttpMethod.Post, "cgi-bin", "license", "get_app_license_info") + .SetQueryParam("access_token", request.ProviderAccessToken); + + return await client.SendRequestWithJsonAsync(flurlReq, cancellationToken: cancellationToken); + } + #endregion + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Models/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoRequest.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Models/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoRequest.cs new file mode 100644 index 00000000..ca5026c5 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Models/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoRequest.cs @@ -0,0 +1,29 @@ +namespace SKIT.FlurlHttpClient.Wechat.Work.Models +{ + /// + /// 表示 [POST] /cgi-bin/license/get_app_license_info 接口的请求。 + /// + public class CgibinLicenseGetAppLicenseInfoRequest : WechatWorkRequest + { + /// + /// 获取或设置服务商 AccessToken。 + /// + [Newtonsoft.Json.JsonIgnore] + [System.Text.Json.Serialization.JsonIgnore] + public string ProviderAccessToken { get; set; } = string.Empty; + + /// + /// 获取或设置企业 CorpId。 + /// + [Newtonsoft.Json.JsonProperty("corpid")] + [System.Text.Json.Serialization.JsonPropertyName("corpid")] + public string CorpId { get; set; } = string.Empty; + + /// + /// 获取或设置第三方应用 SuiteId。如果不指定将使用构造 时的 参数。 + /// + [Newtonsoft.Json.JsonProperty("suite_id")] + [System.Text.Json.Serialization.JsonPropertyName("suite_id")] + public string? SuiteId { get; set; } + } +} diff --git a/src/SKIT.FlurlHttpClient.Wechat.Work/Models/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoResponse.cs b/src/SKIT.FlurlHttpClient.Wechat.Work/Models/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoResponse.cs new file mode 100644 index 00000000..caa50270 --- /dev/null +++ b/src/SKIT.FlurlHttpClient.Wechat.Work/Models/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoResponse.cs @@ -0,0 +1,42 @@ +namespace SKIT.FlurlHttpClient.Wechat.Work.Models +{ + /// + /// 表示 [POST] /cgi-bin/license/get_app_license_info 接口的响应。 + /// + public class CgibinLicenseGetAppLicenseInfoResponse : WechatWorkResponse + { + public static class Types + { + public class TrailInfo + { + /// + /// 获取或设置试用开始时间戳。 + /// + [Newtonsoft.Json.JsonProperty("start_time")] + [System.Text.Json.Serialization.JsonPropertyName("start_time")] + public long StartTimestamp { get; set; } + + /// + /// 获取或设置试用到期时间戳。 + /// + [Newtonsoft.Json.JsonProperty("end_time")] + [System.Text.Json.Serialization.JsonPropertyName("end_time")] + public long EndTimestamp { get; set; } + } + } + + /// + /// 获取或设置接口许可状态。 + /// + [Newtonsoft.Json.JsonProperty("license_status")] + [System.Text.Json.Serialization.JsonPropertyName("license_status")] + public int LicenseStatus { get; set; } + + /// + /// 获取或设置试用期信息。 + /// + [Newtonsoft.Json.JsonProperty("trail_info")] + [System.Text.Json.Serialization.JsonPropertyName("trail_info")] + public Types.TrailInfo? TrailInfo { get; set; } + } +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/LicenseAutoActivateEvent.xml b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/LicenseAutoActivateEvent.xml new file mode 100644 index 00000000..add70833 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/LicenseAutoActivateEvent.xml @@ -0,0 +1,15 @@ + + + + + 1 + 1403610513 + + + 1 + 1700000000 + + 1 + + + diff --git a/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/LicensePaySuccessEvent.xml b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/LicensePaySuccessEvent.xml new file mode 100644 index 00000000..8384fe30 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/LicensePaySuccessEvent.xml @@ -0,0 +1,8 @@ + + + + + + + 1403610513 + diff --git a/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/LicenseRefundEvent.xml b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/LicenseRefundEvent.xml new file mode 100644 index 00000000..0210788b --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/LicenseRefundEvent.xml @@ -0,0 +1,8 @@ + + + + + + 1 + 1403610513 + diff --git a/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/UnlicensedNotifyEvent.xml b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/UnlicensedNotifyEvent.xml new file mode 100644 index 00000000..a064cc23 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/EventSamples/License/UnlicensedNotifyEvent.xml @@ -0,0 +1,8 @@ + + + + 1408091189 + + + 1 + diff --git a/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/ModelSamples/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoRequest.json b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/ModelSamples/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoRequest.json new file mode 100644 index 00000000..277683a9 --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/ModelSamples/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoRequest.json @@ -0,0 +1,4 @@ +{ + "corpid": "xxxx", + "suite_id": "xxxx" +} diff --git a/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/ModelSamples/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoResponse.json b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/ModelSamples/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoResponse.json new file mode 100644 index 00000000..5c72285d --- /dev/null +++ b/test/SKIT.FlurlHttpClient.Wechat.Work.UnitTests/ModelSamples/CgibinLicense/App/CgibinLicenseGetAppLicenseInfoResponse.json @@ -0,0 +1,9 @@ +{ + "errcode": 0, + "errmsg": "ok", + "license_status": 1, + "trail_info": { + "start_time": 1651752000, + "end_time": 1659700800 + } +}