From 0afe220d0aa6b644598098c8a3d69f5926a6ae94 Mon Sep 17 00:00:00 2001 From: jamesfancy Date: Sun, 26 May 2019 22:05:35 +0800 Subject: [PATCH 1/8] =?UTF-8?q?=E4=BB=8E=20Java=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=E8=BF=87=E6=9D=A5=EF=BC=8C=E7=95=A5=E6=9C=89?= =?UTF-8?q?=E6=94=B9=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.en.md | 36 -- README.md | 42 +- Sdk.sln | 25 ++ Sdk/Entity/FileData.cs | 16 + Sdk/Entity/KeywordPosition.Builder.cs | 223 +++++++++++ Sdk/Entity/KeywordPosition.cs | 35 ++ Sdk/Entity/RectanglePosition.Builder.cs | 115 ++++++ Sdk/Entity/RectanglePosition.cs | 17 + Sdk/Entity/SealData.Builder.cs | 67 ++++ Sdk/Entity/SealData.cs | 9 + Sdk/Entity/Signer.Builder.cs | 48 +++ Sdk/Entity/Signer.cs | 17 + Sdk/Entity/SignerData.Builder.cs | 32 ++ Sdk/Entity/SignerData.cs | 10 + Sdk/Entity/SignerInfo.Builder.cs | 64 +++ Sdk/Entity/SignerInfo.cs | 14 + Sdk/Entity/SignerPosition.cs | 111 ++++++ Sdk/Extentions/StreamExtention.cs | 30 ++ Sdk/Extentions/TaskExtentions.cs | 13 + Sdk/Http/AbstractSignitRequest.cs | 22 ++ Sdk/Http/AbstractSignitResponse.cs | 25 ++ Sdk/Http/ApiOptions.cs | 16 + Sdk/Http/Authentication.cs | 114 ++++++ Sdk/Http/HttpClientSync.Response.cs | 22 ++ Sdk/Http/HttpClientSync.cs | 105 +++++ Sdk/Http/JsonContent.cs | 31 ++ Sdk/Http/OAuthData.cs | 31 ++ Sdk/Http/SignatureRequest.Builder.cs | 59 +++ Sdk/Http/SignatureRequest.cs | 13 + Sdk/Http/SignatureResponse.cs | 10 + Sdk/Http/Webhook/AbstractWebhookResponse.cs | 6 + Sdk/Http/Webhook/BoContact.cs | 14 + Sdk/Http/Webhook/BoContactMetadata.cs | 14 + .../EnterpriseVerificationCompleted.cs | 6 + .../Webhook/EnterpriseVerificationPaid.cs | 6 + .../EnterpriseVerificationPrimaryCompleted.cs | 10 + .../EnterpriseVerificationSubmitted.cs | 8 + Sdk/Http/Webhook/EnvelopeCompleted.cs | 6 + Sdk/Http/Webhook/EnvelopeStarted.cs | 28 ++ Sdk/Http/Webhook/ParticipantConfirmed.cs | 6 + Sdk/Http/Webhook/ParticipantHandling.cs | 35 ++ Sdk/Http/Webhook/ParticipantRejected.cs | 7 + .../Webhook/PersonVerificationCompleted.cs | 12 + .../Webhook/PersonVerificationSubmitted.cs | 8 + Sdk/Http/Webhook/QuickSignCompleted.cs | 8 + Sdk/Http/Webhook/RawDataBasicInfo.cs | 31 ++ Sdk/Http/Webhook/Receiver.cs | 56 +++ Sdk/Http/Webhook/Sender.cs | 18 + Sdk/Http/Webhook/SignData.cs | 21 + Sdk/Http/Webhook/WebhookData.cs | 7 + Sdk/Http/Webhook/WebhookDataBase.cs | 22 ++ Sdk/Http/Webhook/WebhookResponse.cs | 43 ++ Sdk/IVerifyRequest.cs | 11 + Sdk/Properties/AssemblyInfo.cs | 36 ++ Sdk/Sdk.csproj | 165 ++++++++ Sdk/SignitClient.cs | 212 ++++++++++ Sdk/SignitException.cs | 35 ++ Sdk/Types/AuthLevel.cs | 24 ++ Sdk/Types/AuthType.cs | 51 +++ Sdk/Types/CertType.cs | 22 ++ Sdk/Types/Direction.cs | 8 + Sdk/Types/EnterpriseAuthType.cs | 21 + Sdk/Types/Enums.cs | 12 + Sdk/Types/EnvelopeRoleType.cs | 20 + Sdk/Types/EnvelopeType.cs | 36 ++ Sdk/Types/FileType.cs | 174 +++++++++ Sdk/Types/FormType.cs | 33 ++ Sdk/Types/IdCardType.cs | 25 ++ Sdk/Types/NamingStyle.cs | 31 ++ Sdk/Types/ParticipantHandleMode.cs | 25 ++ Sdk/Types/PersonAuthType.cs | 16 + Sdk/Types/ReceiverType.cs | 23 ++ Sdk/Types/RenderMode.cs | 29 ++ Sdk/Types/SecureLevel.cs | 23 ++ Sdk/Types/TokenType.cs | 11 + Sdk/Util/AesTool.cs | 98 +++++ Sdk/Util/HmacSignatureBuilder.cs | 368 ++++++++++++++++++ Sdk/Util/InternalTool.cs | 123 ++++++ Sdk/Util/SignitStreamWriter.cs | 57 +++ Sdk/Util/SymmetricTool.cs | 121 ++++++ Sdk/app.config | 11 + Sdk/packages.config | 8 + 82 files changed, 3505 insertions(+), 68 deletions(-) delete mode 100644 README.en.md create mode 100644 Sdk.sln create mode 100644 Sdk/Entity/FileData.cs create mode 100644 Sdk/Entity/KeywordPosition.Builder.cs create mode 100644 Sdk/Entity/KeywordPosition.cs create mode 100644 Sdk/Entity/RectanglePosition.Builder.cs create mode 100644 Sdk/Entity/RectanglePosition.cs create mode 100644 Sdk/Entity/SealData.Builder.cs create mode 100644 Sdk/Entity/SealData.cs create mode 100644 Sdk/Entity/Signer.Builder.cs create mode 100644 Sdk/Entity/Signer.cs create mode 100644 Sdk/Entity/SignerData.Builder.cs create mode 100644 Sdk/Entity/SignerData.cs create mode 100644 Sdk/Entity/SignerInfo.Builder.cs create mode 100644 Sdk/Entity/SignerInfo.cs create mode 100644 Sdk/Entity/SignerPosition.cs create mode 100644 Sdk/Extentions/StreamExtention.cs create mode 100644 Sdk/Extentions/TaskExtentions.cs create mode 100644 Sdk/Http/AbstractSignitRequest.cs create mode 100644 Sdk/Http/AbstractSignitResponse.cs create mode 100644 Sdk/Http/ApiOptions.cs create mode 100644 Sdk/Http/Authentication.cs create mode 100644 Sdk/Http/HttpClientSync.Response.cs create mode 100644 Sdk/Http/HttpClientSync.cs create mode 100644 Sdk/Http/JsonContent.cs create mode 100644 Sdk/Http/OAuthData.cs create mode 100644 Sdk/Http/SignatureRequest.Builder.cs create mode 100644 Sdk/Http/SignatureRequest.cs create mode 100644 Sdk/Http/SignatureResponse.cs create mode 100644 Sdk/Http/Webhook/AbstractWebhookResponse.cs create mode 100644 Sdk/Http/Webhook/BoContact.cs create mode 100644 Sdk/Http/Webhook/BoContactMetadata.cs create mode 100644 Sdk/Http/Webhook/EnterpriseVerificationCompleted.cs create mode 100644 Sdk/Http/Webhook/EnterpriseVerificationPaid.cs create mode 100644 Sdk/Http/Webhook/EnterpriseVerificationPrimaryCompleted.cs create mode 100644 Sdk/Http/Webhook/EnterpriseVerificationSubmitted.cs create mode 100644 Sdk/Http/Webhook/EnvelopeCompleted.cs create mode 100644 Sdk/Http/Webhook/EnvelopeStarted.cs create mode 100644 Sdk/Http/Webhook/ParticipantConfirmed.cs create mode 100644 Sdk/Http/Webhook/ParticipantHandling.cs create mode 100644 Sdk/Http/Webhook/ParticipantRejected.cs create mode 100644 Sdk/Http/Webhook/PersonVerificationCompleted.cs create mode 100644 Sdk/Http/Webhook/PersonVerificationSubmitted.cs create mode 100644 Sdk/Http/Webhook/QuickSignCompleted.cs create mode 100644 Sdk/Http/Webhook/RawDataBasicInfo.cs create mode 100644 Sdk/Http/Webhook/Receiver.cs create mode 100644 Sdk/Http/Webhook/Sender.cs create mode 100644 Sdk/Http/Webhook/SignData.cs create mode 100644 Sdk/Http/Webhook/WebhookData.cs create mode 100644 Sdk/Http/Webhook/WebhookDataBase.cs create mode 100644 Sdk/Http/Webhook/WebhookResponse.cs create mode 100644 Sdk/IVerifyRequest.cs create mode 100644 Sdk/Properties/AssemblyInfo.cs create mode 100644 Sdk/Sdk.csproj create mode 100644 Sdk/SignitClient.cs create mode 100644 Sdk/SignitException.cs create mode 100644 Sdk/Types/AuthLevel.cs create mode 100644 Sdk/Types/AuthType.cs create mode 100644 Sdk/Types/CertType.cs create mode 100644 Sdk/Types/Direction.cs create mode 100644 Sdk/Types/EnterpriseAuthType.cs create mode 100644 Sdk/Types/Enums.cs create mode 100644 Sdk/Types/EnvelopeRoleType.cs create mode 100644 Sdk/Types/EnvelopeType.cs create mode 100644 Sdk/Types/FileType.cs create mode 100644 Sdk/Types/FormType.cs create mode 100644 Sdk/Types/IdCardType.cs create mode 100644 Sdk/Types/NamingStyle.cs create mode 100644 Sdk/Types/ParticipantHandleMode.cs create mode 100644 Sdk/Types/PersonAuthType.cs create mode 100644 Sdk/Types/ReceiverType.cs create mode 100644 Sdk/Types/RenderMode.cs create mode 100644 Sdk/Types/SecureLevel.cs create mode 100644 Sdk/Types/TokenType.cs create mode 100644 Sdk/Util/AesTool.cs create mode 100644 Sdk/Util/HmacSignatureBuilder.cs create mode 100644 Sdk/Util/InternalTool.cs create mode 100644 Sdk/Util/SignitStreamWriter.cs create mode 100644 Sdk/Util/SymmetricTool.cs create mode 100644 Sdk/app.config create mode 100644 Sdk/packages.config diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 7fc06df..0000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# signit-sdk-net - -#### Description -signit.cn 的 .NET 接口 - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) \ No newline at end of file diff --git a/README.md b/README.md index 5996a68..b79fe8f 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,15 @@ -# signit-sdk-net +# 欢迎使用易企签 .NET SDK -#### 介绍 -signit.cn 的 .NET 接口 +易企签 .NET SDK 包括: -#### 软件架构 -软件架构说明 +- token授权获取 +- 快捷签署 +- 提交企业实名认证(即:开通在线电子签约服务接口(企业)) +- 提交个人实名认证(即:开通在线电子签约服务接口(个人)) +- 启动信封签署流程 +了解更多易企签详情请访问 [https://www.signit.cn](https://www.signit.cn) -#### 安装教程 +## 更新日志 -1. xxxx -2. xxxx -3. xxxx - -#### 使用说明 - -1. xxxx -2. xxxx -3. xxxx - -#### 参与贡献 - -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request - - -#### 码云特技 - -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. 码云官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解码云上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是码云最有价值开源项目,是码云综合评定出的优秀开源项目 -5. 码云官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. 码云封面人物是一档用来展示码云会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) \ No newline at end of file +### v1.0 ... diff --git a/Sdk.sln b/Sdk.sln new file mode 100644 index 0000000..0175a05 --- /dev/null +++ b/Sdk.sln @@ -0,0 +1,25 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.28917.181 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sdk", "Sdk\Sdk.csproj", "{E583EAF3-04F9-4AB6-B265-D737568AAEFC}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {E583EAF3-04F9-4AB6-B265-D737568AAEFC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E583EAF3-04F9-4AB6-B265-D737568AAEFC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E583EAF3-04F9-4AB6-B265-D737568AAEFC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E583EAF3-04F9-4AB6-B265-D737568AAEFC}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {817A68CA-8343-42F8-990B-2BAB20226507} + EndGlobalSection +EndGlobal diff --git a/Sdk/Entity/FileData.cs b/Sdk/Entity/FileData.cs new file mode 100644 index 0000000..ea2c98a --- /dev/null +++ b/Sdk/Entity/FileData.cs @@ -0,0 +1,16 @@ +namespace Signit.Sdk.Entity +{ + public class FileData + { + public string Url { get; set; } + public string Base64 { get; set; } + public bool EnableSinglePage { get; set; } + + public FileData() { } + + public FileData(string url) + { + Url = url; + } + } +} diff --git a/Sdk/Entity/KeywordPosition.Builder.cs b/Sdk/Entity/KeywordPosition.Builder.cs new file mode 100644 index 0000000..dd23944 --- /dev/null +++ b/Sdk/Entity/KeywordPosition.Builder.cs @@ -0,0 +1,223 @@ +namespace Signit.Sdk.Entity +{ + public partial class KeywordPosition + { + public class Builder : KeywordPosition + { + private float? width; + private float? relativeWidthRatio; + private float? height; + private float? relativeHeightRatio; + private Direction direction; + private float? offset; + private float? relativeOffsetRatio; + private string keyword; + private float? scale; + private string pages; + private float? xOffset; + private float? yOffset; + private int? index; + + /// + /// + /// + /// + /// 签名矩形框的宽度(默认为关键字宽度,单位:pt); + /// 在易企签系统中,以左上角为坐标原点,横向为x轴,以纵向为y轴; + /// 宽度也即是签名矩形框在x方向上大小 + /// + /// 利用关键字定位签名矩形框所在位置的数据对象建造器 + public Builder WithWidth(float width) + { + this.width = width; + return this; + } + + /** + * + * @param relativeWidthRatio + * 签名矩形框宽度相对于关键字宽度的比率,默认为1.0;例:关键字宽度为50pt,relativeWidthRatio=2,那么签名矩形框宽度即为100pt;宽度更多介绍详见{@link KeywordPositionBuilder#WithWidth(float)} + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 1.0.0 + */ + public Builder WithRelativeWidthRatio(float relativeWidthRatio) + { + this.relativeWidthRatio = relativeWidthRatio; + return this; + } + + /** + * + * @param height + * 签名矩形框的高度(默认为关键字高度,单位:pt);在易企签系统中,以左上角为坐标原点,横向为x轴,以纵向为y轴;高度也即是签名矩形框在y方向上大小 + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 1.0.0 + */ + public Builder WithHeight(float height) + { + this.height = height; + return this; + } + + /** + * + * @param relativeHeightRatio + * 签名矩形框高度相对于关键字高度的比率,默认为1.0;例:关键字高度为50pt,relativeHeightRatio=2,那么签名矩形框高度即为100pt;高度更多介绍详见{@link KeywordPositionBuilder#WithHeight(float)} + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 1.0.0 + */ + public Builder WithRelativeHeightRatio(float relativeHeightRatio) + { + this.relativeHeightRatio = relativeHeightRatio; + return this; + } + + /** + * + * @param direction + * 偏移方向,即签名矩形框相对于关键字的方向(TOP,BOTTOM,LEFT,RIGHT,CENTER),默认为RIGHT;例:direction=TOP,则签名矩形框在关键字的上方 + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 1.0.0 + */ + public Builder WithDirection(Direction direction) + { + this.direction = direction; + return this; + } + + /** + * + * @param offset + * {@code 偏移量(以签名矩形框中心为0点)配合direction使用,默认为0,单位为pt;例:经过关键字初步定位,以及设置签名矩形框的宽高后,签名矩形框位置为:(100,100)(左上角顶点)->(200,200)(右下角顶点) + * ,direction=RIGHT,offset=20,那么进行偏移后,签名矩形框的坐标是 + * (120,100)(左上角顶点)->(220,200)(右下角顶点)} + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 1.0.0 + */ + public Builder WithOffset(float offset) + { + this.offset = offset; + return this; + } + + /** + * + * @param relativeOffsetRatio + * 在偏移方向上,相对于该方向签名矩形框大小的比率,默认为0。例:假设签名矩形框的宽度是50pt,高度为30pt,relativeOffsetRatio=2.0,direction=RIGHT,那么意味着最终偏移量为offset=100pt;同理,如果签名矩形框 + * 宽度为50,高度为30,relativeOffsetRatio=1.3,direction=TOP,那么最终offset=39;计算后的offset使用方法详见{@link KeywordPositionBuilder#WithOffset} + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 1.0.0 + */ + public Builder WithRelativeOffsetRatio(float relativeOffsetRatio) + { + this.relativeOffsetRatio = relativeOffsetRatio; + return this; + } + + /** + * + * @param keyword + * 用于定位的关键字,例如:甲方(签名)。需要注意:用于定位的关键字在文档通过wps或者adobe + * reader等pdf阅读器打开后,需要能够通过鼠标圈选。例如:如果签署文档是通过图片转换后的pdf,就无法在签署文档中 + * 获取关键字位置。 + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 1.0.0 + */ + public Builder WithKeyword(string keyword) + { + this.keyword = keyword; + return this; + } + + /** + * + * @param scale + * {@code 根据关键字定位后的签名矩形框缩放比例,默认为1.0。例如根据关键字定位后,签名矩形框位置为(100,100)->(200,200),scale为2.0,那么签名矩形框位置将是(50,50)->(250,250)} + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 1.0.0 + */ + public Builder WithScale(float scale) + { + this.scale = scale; + return this; + } + + /** + * + * @param pages + * 关键字需要搜索的页数,默认为"all"。在文档中搜索关键字时,只在指定页中搜索。支持"all","first","last","odd","even","1","1-5","1,2,3,5","(0,5]","[1,5]","(0,5)"这些页数的表示方式 + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 1.0.0 + */ + public Builder WithPages(string pages) + { + this.pages = pages; + return this; + } + + /** + * + * @param xOffset + * 签名矩形框在x轴额外偏移量,单位为pt,默认为0 + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 2.0.0 + */ + public Builder WithXOffset(float xOffset) + { + this.xOffset = xOffset; + return this; + } + + /** + * + * @param yOffset + * 签名矩形框在y轴额外偏移量,单位为pt,默认为0 + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 2.0.0 + */ + public Builder WithYOffset(float yOffset) + { + this.yOffset = yOffset; + return this; + } + + /** + * + * @param index + * 如果关键字所在页数存在多个相同关键字,则需要指定关键字的索引(关键字从索引从0开始),即指定使用第几个关键字。默认为0 + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} + * @since 2.0.0 + */ + public Builder WithIndex(int index) + { + this.index = index; + return this; + } + + /** + * + * @return 利用关键字定位签名矩形框所在位置的数据对象 {@link KeywordPosition} + * @since 1.0.0 + */ + public KeywordPosition Build() + { + return new KeywordPosition + { + Width = width, + RelativeWidthRatio = relativeWidthRatio, + Height = height, + RelativeHeightRatio = relativeHeightRatio, + Direction = direction, + Offset = offset, + RelativeOffsetRatio = relativeOffsetRatio, + Keyword = keyword, + Scale = scale, + Pages = pages, + XOffset = xOffset, + YOffset = yOffset, + Index = index + }; + } + } + } +} diff --git a/Sdk/Entity/KeywordPosition.cs b/Sdk/Entity/KeywordPosition.cs new file mode 100644 index 0000000..f8ac741 --- /dev/null +++ b/Sdk/Entity/KeywordPosition.cs @@ -0,0 +1,35 @@ +namespace Signit.Sdk.Entity +{ + public partial class KeywordPosition + { + public static Builder CreateBuilder() + { + return new Builder(); + } + + public float? Width { get; set; } + public float? RelativeWidthRatio { get; set; } + public float? Height { get; set; } + public float? RelativeHeightRatio { get; set; } + public Direction Direction { get; set; } + public float? Offset { get; set; } + public float? RelativeOffsetRatio { get; set; } + public string Keyword { get; set; } + public float? Scale { get; set; } + public string Pages { get; set; } + + /// + /// x 方向的便移量 正是往右,负是往左,坐标缩放前进行最后的微调参数 + /// + public float? XOffset { get; set; } + + /// + /// y 方向的便移量 正是往上,负是往下,坐标缩放前进行最后的微调参数 + /// + public float? YOffset { get; set; } + + public int? Index { get; set; } + + private KeywordPosition() { } + } +} diff --git a/Sdk/Entity/RectanglePosition.Builder.cs b/Sdk/Entity/RectanglePosition.Builder.cs new file mode 100644 index 0000000..ee39de4 --- /dev/null +++ b/Sdk/Entity/RectanglePosition.Builder.cs @@ -0,0 +1,115 @@ +namespace Signit.Sdk.Entity +{ + public partial class RectanglePosition + { + public class Builder + { + private float? lrX; + private float? lrY; + private float? ulX; + private float? ulY; + private float? scale; + private int? page; + + /** + * 以左上角为原点,横向为x轴,纵向为y轴 + * + * @param lrX + * 矩形框右下角横坐标(单位:pt) + * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} + * @since 2.0.0 + */ + public Builder WithLrX(float lrX) + { + this.lrX = lrX; + return this; + } + + /** + * 以左上角为原点,横向为x轴,纵向为y轴 + * + * @param lrY + * 矩形框右下角纵坐标(单位:pt) + * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} + * @since 2.0.0 + */ + public Builder WithLrY(float lrY) + { + this.lrY = lrY; + return this; + } + + /** + * 以左上角为原点,横向为x轴,纵向为y轴 + * + * @param ulX + * 矩形框左上角横坐标(单位:pt) + * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} + * @since 2.0.0 + */ + public Builder WithUlX(float ulX) + { + this.ulX = ulX; + return this; + } + + /** + * 以左上角为原点,横向为x轴,纵向为y轴 + * + * @param ulY + * 矩形框左上角纵坐标(单位:pt) + * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} + * @since 2.0.0 + */ + public Builder WithUlY(float ulY) + { + this.ulY = ulY; + return this; + } + + /** + * + * @param scale + * 矩形框缩放比例,默认为1.0;参照{@link KeywordPositionBuilder#WithScale(float)} + * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} + * @since 2.0.0 + */ + public Builder WithScale(float scale) + { + this.scale = scale; + return this; + } + + /** + * + * @param page + * rectanglePosition矩形框放在文档的哪一页 + * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} + * @since 2.0.0 + */ + public Builder WithPage(int page) + { + this.page = page; + return this; + } + + /** + * + * @return 签名矩形框坐标对象 {@link RectanglePosition} + * @since 2.0.0 + */ + public RectanglePosition Build() + { + return new RectanglePosition + { + Lrx = lrX, + Lry = lrY, + Ulx = ulX, + Uly = ulY, + Scale = scale, + Page = page, + }; + } + } + } +} diff --git a/Sdk/Entity/RectanglePosition.cs b/Sdk/Entity/RectanglePosition.cs new file mode 100644 index 0000000..858a07f --- /dev/null +++ b/Sdk/Entity/RectanglePosition.cs @@ -0,0 +1,17 @@ +namespace Signit.Sdk.Entity +{ + public partial class RectanglePosition + { + public static Builder CreateBuilder() + { + return new Builder(); + } + + public float? Lrx { get; set; } + public float? Lry { get; set; } + public float? Ulx { get; set; } + public float? Uly { get; set; } + public float? Scale { get; set; } + public int? Page { get; set; } + } +} diff --git a/Sdk/Entity/SealData.Builder.cs b/Sdk/Entity/SealData.Builder.cs new file mode 100644 index 0000000..ded4ff3 --- /dev/null +++ b/Sdk/Entity/SealData.Builder.cs @@ -0,0 +1,67 @@ +namespace Signit.Sdk.Entity +{ + public partial class SealData + { + public class Builder + { + private string url; + private string base64; + private string name; + + /** + * + * @param url + * 印章数据url + * @return 印章数据对象建造器{@link SealDataBuilder} + * @since 2.0.0 + */ + public Builder WithUrl(string url) + { + this.url = url; + return this; + } + + /** + * + * @param base64 + * 印章数据的base64字符串格式 + * @return 印章数据对象建造器{@link SealDataBuilder} + * @since 2.0.0 + */ + public Builder WithBase64(string base64) + { + this.base64 = base64; + return this; + } + + /** + * 印章名字在企业中是唯一时,可以通过填写印章名字指定使用该印章 + * + * @param name + * 印章名称 + * @return 印章数据对象建造器{@link SealDataBuilder} + * @since 2.0.0 + */ + public Builder WithName(string name) + { + this.name = name; + return this; + } + + /** + * + * @return 印章数据对象 + * @since 2.0.0 + */ + public SealData Build() + { + return new SealData + { + Name = name, + Url = url, + Base64 = base64 + }; + } + } + } +} diff --git a/Sdk/Entity/SealData.cs b/Sdk/Entity/SealData.cs new file mode 100644 index 0000000..b5ff97d --- /dev/null +++ b/Sdk/Entity/SealData.cs @@ -0,0 +1,9 @@ +namespace Signit.Sdk.Entity +{ + public partial class SealData : FileData + { + public static Builder CreateBuilder() => new Builder(); + + public string Name { get; set; } + } +} diff --git a/Sdk/Entity/Signer.Builder.cs b/Sdk/Entity/Signer.Builder.cs new file mode 100644 index 0000000..f8c3ffe --- /dev/null +++ b/Sdk/Entity/Signer.Builder.cs @@ -0,0 +1,48 @@ +namespace Signit.Sdk.Entity +{ + public partial class Signer + { + public class Builder + { + private int sequence; + private SignerPosition position; + private SignerData data; + private SignerInfo signerInfo; + + public Builder WithSequence(int sequence) + { + this.sequence = sequence; + return this; + } + + public Builder WithPosition(SignerPosition position) + { + this.position = position; + return this; + } + + public Builder WithData(SignerData data) + { + this.data = data; + return this; + } + + public Builder WithSignerInfo(SignerInfo signerInfo) + { + this.signerInfo = signerInfo; + return this; + } + + public Signer Build() + { + return new Signer() + { + Sequence = sequence, + Position = position, + Data = data, + SignerInfo = signerInfo + }; + } + } + } +} \ No newline at end of file diff --git a/Sdk/Entity/Signer.cs b/Sdk/Entity/Signer.cs new file mode 100644 index 0000000..218ba34 --- /dev/null +++ b/Sdk/Entity/Signer.cs @@ -0,0 +1,17 @@ +namespace Signit.Sdk.Entity +{ + public partial class Signer + { + public static Builder CreateBuilder() + { + return new Builder(); + } + + public int Sequence { get; set; } + public SignerPosition Position { get; set; } + public SignerData Data { get; set; } + public SignerInfo SignerInfo { get; set; } + + private Signer() { } + } +} diff --git a/Sdk/Entity/SignerData.Builder.cs b/Sdk/Entity/SignerData.Builder.cs new file mode 100644 index 0000000..3ef1acd --- /dev/null +++ b/Sdk/Entity/SignerData.Builder.cs @@ -0,0 +1,32 @@ +namespace Signit.Sdk.Entity +{ + public partial class SignerData + { + public class Builder + { + private SealData sealData; + private SealData writeData; + + public Builder WithSealData(SealData sealData) + { + this.sealData = sealData; + return this; + } + + public Builder WithWriteData(SealData writeData) + { + this.writeData = writeData; + return this; + } + + public SignerData Build() + { + return new SignerData + { + SealData = sealData, + WriteData = writeData + }; + } + } + } +} diff --git a/Sdk/Entity/SignerData.cs b/Sdk/Entity/SignerData.cs new file mode 100644 index 0000000..a4f0487 --- /dev/null +++ b/Sdk/Entity/SignerData.cs @@ -0,0 +1,10 @@ +namespace Signit.Sdk.Entity +{ + public partial class SignerData + { + public static Builder CreateBuilder() => new Builder(); + + public SealData SealData { get; set; } + public SealData WriteData { get; set; } + } +} diff --git a/Sdk/Entity/SignerInfo.Builder.cs b/Sdk/Entity/SignerInfo.Builder.cs new file mode 100644 index 0000000..043a950 --- /dev/null +++ b/Sdk/Entity/SignerInfo.Builder.cs @@ -0,0 +1,64 @@ +namespace Signit.Sdk.Entity +{ + public partial class SignerInfo + { + public class Builder + { + private string name; + private string orgnizationName; + private string idCardNo; + private string location; + private string contact; + private string reason; + + public Builder WithName(string name) + { + this.name = name; + return this; + } + + public Builder WithOrgnizationName(string orgnizationName) + { + this.orgnizationName = orgnizationName; + return this; + } + + public Builder WithIdCardNo(string idCardNo) + { + this.idCardNo = idCardNo; + return this; + } + + public Builder WithLocation(string location) + { + this.location = location; + return this; + } + + public Builder WithContact(string contact) + { + this.contact = contact; + return this; + } + + public Builder WithReason(string reason) + { + this.reason = reason; + return this; + } + + public SignerInfo Build() + { + return new SignerInfo + { + Name = name, + OrgnizationName = orgnizationName, + IdCardNo = idCardNo, + Location = location, + Contact = contact, + Reason = reason, + }; + } + } + } +} diff --git a/Sdk/Entity/SignerInfo.cs b/Sdk/Entity/SignerInfo.cs new file mode 100644 index 0000000..9905cc7 --- /dev/null +++ b/Sdk/Entity/SignerInfo.cs @@ -0,0 +1,14 @@ +namespace Signit.Sdk.Entity +{ + public partial class SignerInfo + { + public static Builder CreateBuilder() => new Builder(); + + public string Name { get; set; } + public string OrgnizationName { get; set; } + public string IdCardNo { get; set; } + public string Location { get; set; } + public string Contact { get; set; } + public string Reason { get; set; } + } +} diff --git a/Sdk/Entity/SignerPosition.cs b/Sdk/Entity/SignerPosition.cs new file mode 100644 index 0000000..669debe --- /dev/null +++ b/Sdk/Entity/SignerPosition.cs @@ -0,0 +1,111 @@ +namespace Signit.Sdk.Entity +{ + public class SignerPosition + { + public static Builder CreateBuilder() => new Builder(); + + public KeywordPosition KeywordPosition { get; set; } + public RectanglePosition RectanglePosition { get; set; } + public string FieldName { get; set; } + + /** + * 表单坐标位置对象建造器 + * + * @since 1.0.0 + */ + public class Builder + { + private KeywordPosition keywordPosition; + private RectanglePosition rectanglePosition; + private string fieldName; + + /** + * + * @param keywordPosition + * 利用关键字定位签名矩形框所在位置的数据对象;利用关键字进行定位 + * {@link KeywordPosition} + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link PositionBuilder} + * @since 1.0.0 + */ + public Builder WithKeywordPosition(KeywordPosition keywordPosition) + { + this.keywordPosition = keywordPosition; + return this; + } + + /** + * + * @param keywordPositionBuilder + * 利用关键字定位签名矩形框所在位置的数据对象建造器;利用关键字进行定位{@link KeywordPosition.KeywordPositionBuilder} + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link PositionBuilder} + * @since 1.0.0 + */ + public Builder WithKeywordPosition(KeywordPosition.Builder keywordPositionBuilder) + { + if (keywordPositionBuilder != null) + { + this.keywordPosition = keywordPositionBuilder.Build(); + } + return this; + } + + /** + * + * @param rectanglePosition + * 直接设定好的签名矩形框坐标 {@link RectanglePosition} + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link PositionBuilder} + * @since 1.0.0 + */ + public Builder WithRectanglePosition(RectanglePosition rectanglePosition) + { + this.rectanglePosition = rectanglePosition; + return this; + } + + /** + * + * @param rectanglePositionBuilder + * 直接设定好的签名矩形框坐标对象建造器 {@link RectanglePositionBuilder} + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link PositionBuilder} + * @since 1.0.0 + */ + public Builder WithRectanglePosition(RectanglePosition.Builder rectanglePositionBuilder) + { + if (rectanglePositionBuilder != null) + { + rectanglePosition = rectanglePositionBuilder.Build(); + } + return this; + } + + /** + * + * @param fieldsName + * 签名域名称;签名文件格式需要是pdf,且签名文件中已经设置好签名域名称对应的签名域 + * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link PositionBuilder} + * @since 1.0.0 + */ + public Builder WithFieldName(string fieldName) + { + this.fieldName = fieldName; + return this; + } + + /** + * + * @return 表单坐标位置对象 {@link Position} + * @since 1.0.0 + */ + public SignerPosition Build() + { + return new SignerPosition + { + KeywordPosition = keywordPosition, + RectanglePosition = rectanglePosition, + FieldName = fieldName, + }; + } + } + + } +} diff --git a/Sdk/Extentions/StreamExtention.cs b/Sdk/Extentions/StreamExtention.cs new file mode 100644 index 0000000..015d6b6 --- /dev/null +++ b/Sdk/Extentions/StreamExtention.cs @@ -0,0 +1,30 @@ +using System.IO; +using Viyi.Util.Linq; + +namespace Signit.Sdk.Extentions +{ + public static class StreamExtention + { + public static T Write(this T stream, byte[] data) + where T : Stream + { + stream.Write(data, 0, data.Length); + return stream; + } + + public static T Write(this T stream, byte[] data, byte[] suffix) + where T : Stream + { + stream.Write(data); + stream.Write(suffix); + return stream; + } + + public static T Write(this T stream, params byte[][] multiData) + where T : Stream + { + multiData.ForEach(data => stream.Write(data)); + return stream; + } + } +} diff --git a/Sdk/Extentions/TaskExtentions.cs b/Sdk/Extentions/TaskExtentions.cs new file mode 100644 index 0000000..6a9e67c --- /dev/null +++ b/Sdk/Extentions/TaskExtentions.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; + +namespace Signit.Sdk.Extentions +{ + public static class TaskExtentions + { + public static T WaitResult(this Task task) + { + task.Wait(); + return task.Result; + } + } +} diff --git a/Sdk/Http/AbstractSignitRequest.cs b/Sdk/Http/AbstractSignitRequest.cs new file mode 100644 index 0000000..1d111d2 --- /dev/null +++ b/Sdk/Http/AbstractSignitRequest.cs @@ -0,0 +1,22 @@ +using Signit.Sdk.Entity; + +namespace Signit.Sdk.Http +{ + public abstract class AbstractSignitRequest + { + /// + /// 调用方自定义标识,易企签会原封不动返回. + /// + public string CustomTag { get; set; } + + /// + /// 调用方自定义要求易企签的WEB平台在流程结束后需要跳转的指定URL地址 + /// + public string ReturnUrl { get; set; } + + /// + /// 调用方接受的响应数据类型,支持:BASE64/URL + /// + public AcceptDataType AcceptDataType { get; set; } + } +} diff --git a/Sdk/Http/AbstractSignitResponse.cs b/Sdk/Http/AbstractSignitResponse.cs new file mode 100644 index 0000000..e8ab21a --- /dev/null +++ b/Sdk/Http/AbstractSignitResponse.cs @@ -0,0 +1,25 @@ +namespace Signit.Sdk.Http +{ + public abstract class AbstractSignitResponse + { + public string Code { get; set; } + public string Message { get; set; } + public string CustomTag { get; set; } + public string InvokeNo { get; set; } + + public bool IsSuccess + { + get + { + if (Code == null || Code.Length < 4) + { + return false; + } + + var descCode = Code.Substring(Code.Length - 4); + return int.TryParse(descCode, out int code) + && code >= 0 && code < 100; + } + } + } +} diff --git a/Sdk/Http/ApiOptions.cs b/Sdk/Http/ApiOptions.cs new file mode 100644 index 0000000..f8cb958 --- /dev/null +++ b/Sdk/Http/ApiOptions.cs @@ -0,0 +1,16 @@ +namespace Signit.Sdk.Http +{ + public class ApiOptions + { + public static ApiOptions Default => new ApiOptions(); + + public string EnvUrl = "https://open.signit.cn"; + public string Encoding = "UTF-8"; + public string BaseApiUrl = "/v1/open/signatures/quick-sign"; + public string OAuthTokenUrl = "/v1/oauth/oauth/token"; + public string ClientId = "client_id"; + public string ClientSecret = "client_secret"; + public string GrantType = "grant_type"; + public string AppIdKey = "X-Signit-App-Id"; + } +} diff --git a/Sdk/Http/Authentication.cs b/Sdk/Http/Authentication.cs new file mode 100644 index 0000000..7f9e568 --- /dev/null +++ b/Sdk/Http/Authentication.cs @@ -0,0 +1,114 @@ +using Signit.Sdk.Types; +using Signit.Sdk.Util; +using System.IO; +using System.Security.Cryptography; +using System.Text; +using Viyi.Util.Codec; + +namespace Signit.Sdk.Http +{ + public class Authentication + { + private const string KeyBase64 = "9ijhWI+0fNf0RSRJxgPt7q2zciyGVxmcco95I+gKids="; + + public string AppId { get; set; } = ""; + public string SecuretKey { get; set; } = ""; + public string AccessToken { get; set; } = ""; + public TokenType AccessTokenType { get; set; } = TokenType.CLIENT_CREDENTIALS; + + // TODO private string cacheTokenDir = System.getProperty("java.io.tmpdir"); + public string CacheTokenDir = Path.GetTempPath(); + + + public Authentication() { } + + public Authentication(string apiKey, string secretKey, TokenType authType) + { + AppId = apiKey; + SecuretKey = secretKey; + AccessTokenType = authType; + InitFromLocal(); + } + + public bool HasAppId => !string.IsNullOrEmpty(AppId); + public bool HasSecretKey => !string.IsNullOrEmpty(SecuretKey); + + public bool HasAccessToken + { + get + { + InitFromLocal(); + return !string.IsNullOrEmpty(AccessToken); + } + } + + private void CacheToLocal() + { + if (!string.IsNullOrWhiteSpace(AccessToken)) + { + return; + } + + string filePath = GenerateCachedTokenFilename(); + if (filePath == null) + { + return; + } + + try + { + byte[] data = Encoding.ASCII.GetBytes(AccessToken); + byte[] secretData = data.AesEncrypt(KeyBase64); + File.WriteAllBytes(filePath, secretData); + } + catch + { + // DO-NOTHING + return; + } + } + + private void InitFromLocal() + { + if (!string.IsNullOrWhiteSpace(AccessToken)) + { + return; + } + + string filePath = GenerateCachedTokenFilename(); + if (filePath == null || !File.Exists(filePath)) + { + return; + } + + try + { + var secretData = File.ReadAllBytes(filePath); + var data = secretData.AesDecrypt(KeyBase64); + AccessToken = Encoding.ASCII.GetString(data); + } + catch + { + // DO-NOTHING + return; + } + } + + private string GenerateCachedTokenFilename() + { + if (string.IsNullOrEmpty(AppId) || string.IsNullOrEmpty(SecuretKey)) + { + return null; + } + + var combine = string.Join(",", new[] + { + AppId, SecuretKey, AccessTokenType.ToString() + }); + + var hash = MD5.Create().ComputeHash(Encoding.ASCII.GetBytes(combine)); + var filename = Path.Combine(CacheTokenDir, hash.Base64Encode()); + return filename; + } + } +} diff --git a/Sdk/Http/HttpClientSync.Response.cs b/Sdk/Http/HttpClientSync.Response.cs new file mode 100644 index 0000000..546d403 --- /dev/null +++ b/Sdk/Http/HttpClientSync.Response.cs @@ -0,0 +1,22 @@ +using Newtonsoft.Json; +using System.Net; + +namespace Signit.Sdk.Http +{ + partial class HttpClientSync + { + public class Response + { + public HttpStatusCode Code { get; set; } + public string Content { get; set; } + public bool IsSuccessStatusCode { get; internal set; } + + public T GetObject() + { + return string.IsNullOrWhiteSpace(Content) + ? default(T) + : JsonConvert.DeserializeObject(Content); + } + } + } +} diff --git a/Sdk/Http/HttpClientSync.cs b/Sdk/Http/HttpClientSync.cs new file mode 100644 index 0000000..9652a3b --- /dev/null +++ b/Sdk/Http/HttpClientSync.cs @@ -0,0 +1,105 @@ +using Signit.Sdk.Extentions; +using System.Collections.Specialized; +using System.Diagnostics; +using System.Linq; +using System.Net.Http; +using System.Web; +using Viyi.Util.Linq; + +namespace Signit.Sdk.Http +{ + partial class HttpClientSync + { + private const string USER_AGENT = "Signit HTTP"; + private const string DEFAULT_ENCODING = "UTF-8"; + + private static Response ConvertResponse(HttpResponseMessage response, bool needContentOnError = false) + { + var result = new Response() + { + IsSuccessStatusCode = response.IsSuccessStatusCode, + Code = response.StatusCode + }; + + if (needContentOnError || response.IsSuccessStatusCode) + { + result.Content = response.Content.ReadAsStringAsync().WaitResult(); + } + + Debug.WriteLine($"[RESPONSE] {result.Content}"); + return result; + } + + private NameValueCollection queryParams = new NameValueCollection(); + private Authentication authentication; + + public Response Get(string url) + { + url = ConcatQueryString(url); + + Debug.WriteLine($"[GET] {url}"); + HttpClient client = new HttpClient(); + var response = client.GetAsync(url).WaitResult(); + return ConvertResponse(response); + } + + public Response Post(string url, object payload, NameValueCollection headers = null) + { + url = ConcatQueryString(url); + url = ConcatQueryParam(url, "access_token", authentication.AccessToken); + + var content = new JsonContent(payload); + + HttpClient client = new HttpClient(); + client.DefaultRequestHeaders.Add("Accept", "application/json"); + client.DefaultRequestHeaders.Add("Accept-Encoding", DEFAULT_ENCODING); + client.DefaultRequestHeaders.Add("User-Agent", USER_AGENT); + + headers?.AllKeys.ForEach(key => + { + client.DefaultRequestHeaders.Add(key, headers[key]); + }); + + Debug.WriteLine($"[POST] {url}"); + var response = client.PostAsync(url, content).WaitResult(); + return ConvertResponse(response, true); + } + + + private static string ConcatQueryParam(string url, string key, string value) + { + var pair = $"{key}={HttpUtility.UrlEncode(value)}"; + return $"{url}{(url.Contains("?") ? "&" : "?")}{pair}"; + } + + private string ConcatQueryString(string url) + { + var pairs = queryParams.AllKeys + .SelectMany(key => + { + return queryParams.GetValues(key) + .Select(v => $"{key}={HttpUtility.UrlEncode(v)}"); + }); + var queryString = string.Join("&", pairs); + + if (!string.IsNullOrEmpty(queryString)) + { + url = $"{url}{(url.Contains("?") ? "&" : "?")}{queryString}"; + } + + return url; + } + + public HttpClientSync AddQueryParam(string name, string value) + { + queryParams.Add(name, value); + return this; + } + + public HttpClientSync WithAuthentication(Authentication auth) + { + authentication = auth; + return this; + } + } +} diff --git a/Sdk/Http/JsonContent.cs b/Sdk/Http/JsonContent.cs new file mode 100644 index 0000000..28253da --- /dev/null +++ b/Sdk/Http/JsonContent.cs @@ -0,0 +1,31 @@ +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Serialization; +using System.Net.Http; +using System.Text; + +namespace Signit.Sdk.Http +{ + public class JsonContent : StringContent + { + public JsonContent(object model) : base(ToJson(model), Encoding.UTF8, "application/json") { } + + private static readonly JsonSerializerSettings defaultJsonSettings = CreateDefaultJsonSettings(); + + private static JsonSerializerSettings CreateDefaultJsonSettings() + { + var settings = new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + }; + + settings.Converters.Add(new StringEnumConverter()); + return settings; + } + + private static string ToJson(object model, JsonSerializerSettings settings = null) + { + return JsonConvert.SerializeObject(model, settings ?? defaultJsonSettings); + } + } +} diff --git a/Sdk/Http/OAuthData.cs b/Sdk/Http/OAuthData.cs new file mode 100644 index 0000000..6fdfd42 --- /dev/null +++ b/Sdk/Http/OAuthData.cs @@ -0,0 +1,31 @@ +namespace Signit.Sdk.Http +{ + public class OAuthData + { + public string access_token { private get; set; } + public string token_type { private get; set; } + public int expires_in { private get; set; } + public string scope { private get; set; } + + public string AccessToken + { + get => access_token; + set => access_token = value; + } + public string TokenType + { + get => token_type; + set => token_type = value; + } + public int ExpiresIn + { + get => expires_in; + set => expires_in = value; + } + public string Scope + { + get => scope; + set => scope = value; + } + } +} diff --git a/Sdk/Http/SignatureRequest.Builder.cs b/Sdk/Http/SignatureRequest.Builder.cs new file mode 100644 index 0000000..8d542fa --- /dev/null +++ b/Sdk/Http/SignatureRequest.Builder.cs @@ -0,0 +1,59 @@ +using Signit.Sdk.Entity; +using System.Collections.Generic; + +namespace Signit.Sdk.Http +{ + public partial class SignatureRequest + { + public class Builder + { + private FileData fileData; + private AcceptDataType acceptDataType; + private string returnUrl; + private string customTag; + private IList signDetails; + + public Builder WithFileData(FileData fileData) + { + this.fileData = fileData; + return this; + } + + public Builder WithAcceptDataType(AcceptDataType acceptDataType) + { + this.acceptDataType = acceptDataType; + return this; + } + + public Builder WithReturnUrl(string returnUrl) + { + this.returnUrl = returnUrl; + return this; + } + + public Builder WithCustomTag(string customTag) + { + this.customTag = customTag; + return this; + } + + public Builder WithSignDetails(IList signDetails) + { + this.signDetails = signDetails; + return this; + } + + public SignatureRequest Build() + { + return new SignatureRequest + { + FileData = fileData, + AcceptDataType = acceptDataType, + ReturnUrl = returnUrl, + CustomTag = customTag, + SignDetails = signDetails, + }; + } + } + } +} diff --git a/Sdk/Http/SignatureRequest.cs b/Sdk/Http/SignatureRequest.cs new file mode 100644 index 0000000..45f277e --- /dev/null +++ b/Sdk/Http/SignatureRequest.cs @@ -0,0 +1,13 @@ +using Signit.Sdk.Entity; +using System.Collections.Generic; + +namespace Signit.Sdk.Http +{ + public partial class SignatureRequest : AbstractSignitRequest + { + public static Builder CreateBuilder() => new Builder(); + + public FileData FileData; + public IList SignDetails; + } +} diff --git a/Sdk/Http/SignatureResponse.cs b/Sdk/Http/SignatureResponse.cs new file mode 100644 index 0000000..80be17e --- /dev/null +++ b/Sdk/Http/SignatureResponse.cs @@ -0,0 +1,10 @@ +namespace Signit.Sdk.Http +{ + public class SignatureResponse : AbstractSignitResponse + { + public string ErrorWsid { get; set; } + public string UserMessage { get; set; } + public string DeveloperMessage { get; set; } + public string MemberInfo { get; set; } + } +} diff --git a/Sdk/Http/Webhook/AbstractWebhookResponse.cs b/Sdk/Http/Webhook/AbstractWebhookResponse.cs new file mode 100644 index 0000000..a15de35 --- /dev/null +++ b/Sdk/Http/Webhook/AbstractWebhookResponse.cs @@ -0,0 +1,6 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class AbstractWebhookResponse : AbstractSignitResponse + { + } +} diff --git a/Sdk/Http/Webhook/BoContact.cs b/Sdk/Http/Webhook/BoContact.cs new file mode 100644 index 0000000..814998b --- /dev/null +++ b/Sdk/Http/Webhook/BoContact.cs @@ -0,0 +1,14 @@ +namespace Signit.Sdk.Http.Webhook +{ + /** + * 联系方式详细数据. + * + * @since 2.0.0 + */ + public class BoContact + { + public string AuthorWsid { get; set; } + public string Email { get; set; } + public string Sms { get; set; } + } +} diff --git a/Sdk/Http/Webhook/BoContactMetadata.cs b/Sdk/Http/Webhook/BoContactMetadata.cs new file mode 100644 index 0000000..f96b0f0 --- /dev/null +++ b/Sdk/Http/Webhook/BoContactMetadata.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Signit.Sdk.Http.Webhook +{ + /** + * 联系方式元数据. + * + * @since 2.0.0 + */ + public class BoContactMetadata + { + public IList Contacts { get; set; } + } +} diff --git a/Sdk/Http/Webhook/EnterpriseVerificationCompleted.cs b/Sdk/Http/Webhook/EnterpriseVerificationCompleted.cs new file mode 100644 index 0000000..57117ee --- /dev/null +++ b/Sdk/Http/Webhook/EnterpriseVerificationCompleted.cs @@ -0,0 +1,6 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class EnterpriseVerificationCompleted : EnterpriseVerificationPrimaryCompleted + { + } +} diff --git a/Sdk/Http/Webhook/EnterpriseVerificationPaid.cs b/Sdk/Http/Webhook/EnterpriseVerificationPaid.cs new file mode 100644 index 0000000..1c1bd1d --- /dev/null +++ b/Sdk/Http/Webhook/EnterpriseVerificationPaid.cs @@ -0,0 +1,6 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class EnterpriseVerificationPaid : EnterpriseVerificationPrimaryCompleted + { + } +} diff --git a/Sdk/Http/Webhook/EnterpriseVerificationPrimaryCompleted.cs b/Sdk/Http/Webhook/EnterpriseVerificationPrimaryCompleted.cs new file mode 100644 index 0000000..16ec1be --- /dev/null +++ b/Sdk/Http/Webhook/EnterpriseVerificationPrimaryCompleted.cs @@ -0,0 +1,10 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class EnterpriseVerificationPrimaryCompleted : AbstractWebhookResponse + { + public string Description { get; set; } + public string Status { get; set; } + public long? HandleDatetime { get; set; } + public long? SubmitDatetime { get; set; } + } +} diff --git a/Sdk/Http/Webhook/EnterpriseVerificationSubmitted.cs b/Sdk/Http/Webhook/EnterpriseVerificationSubmitted.cs new file mode 100644 index 0000000..4de3edd --- /dev/null +++ b/Sdk/Http/Webhook/EnterpriseVerificationSubmitted.cs @@ -0,0 +1,8 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class EnterpriseVerificationSubmitted : AbstractWebhookResponse + { + private string Status {get;set;} + private string ActionUrl {get;set;} + } +} diff --git a/Sdk/Http/Webhook/EnvelopeCompleted.cs b/Sdk/Http/Webhook/EnvelopeCompleted.cs new file mode 100644 index 0000000..d9885b8 --- /dev/null +++ b/Sdk/Http/Webhook/EnvelopeCompleted.cs @@ -0,0 +1,6 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class EnvelopeCompleted : EnvelopeStarted + { + } +} diff --git a/Sdk/Http/Webhook/EnvelopeStarted.cs b/Sdk/Http/Webhook/EnvelopeStarted.cs new file mode 100644 index 0000000..532a281 --- /dev/null +++ b/Sdk/Http/Webhook/EnvelopeStarted.cs @@ -0,0 +1,28 @@ +using System.Collections.Generic; + +namespace Signit.Sdk.Http.Webhook +{ + public class EnvelopeStarted : AbstractWebhookResponse + { + // 执行的动作对应的URL地址 + public string ActionUrl { get; set; } + + // 流程允许在易企签WEB执行的动作 + public IList Actions { get; set; } + + // 接收方对应的在易企签的帐号 + public string Account { get; set; } + + // 信封基本信息 + public RawDataBasicInfo BasicEnvelope { get; set; } + + public Sender SenderParticipant { get; set; } + public Receiver ReceiverParticipant { get; set; } + + // 已完成的签署数据 + public SignData SignData { get; set; } + + // 客户端回调地址 + public string ReturnUrl { get; set; } + } +} diff --git a/Sdk/Http/Webhook/ParticipantConfirmed.cs b/Sdk/Http/Webhook/ParticipantConfirmed.cs new file mode 100644 index 0000000..9eb5459 --- /dev/null +++ b/Sdk/Http/Webhook/ParticipantConfirmed.cs @@ -0,0 +1,6 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class ParticipantConfirmed : EnvelopeStarted + { + } +} diff --git a/Sdk/Http/Webhook/ParticipantHandling.cs b/Sdk/Http/Webhook/ParticipantHandling.cs new file mode 100644 index 0000000..fff79f0 --- /dev/null +++ b/Sdk/Http/Webhook/ParticipantHandling.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; + +namespace Signit.Sdk.Http.Webhook +{ + public class ParticipantHandling : AbstractWebhookResponse + { + // 执行的动作对应的URL地址 + public string ActionUrl { get; set; } + + // 流程允许在易企签WEB执行的动作 + public IList Actions { get; set; } + + // 接收方对应的在易企签的帐号 + public string Account { get; set; } + + // 自定义标识 + public string CustomTag { get; set; } + + // 服务调用唯一标识 + public string InvokeNo { get; set; } + + // 信封基本信息 + public RawDataBasicInfo BasicEnvelope { get; set; } + + public Sender SenderParticipant { get; set; } + public Receiver ReceiverParticipant { get; set; } + + // 已完成的签署数据 + public SignData SignData { get; set; } + + // 客户端回调地址 + public string ReturnUrl { get; set; } + } + +} diff --git a/Sdk/Http/Webhook/ParticipantRejected.cs b/Sdk/Http/Webhook/ParticipantRejected.cs new file mode 100644 index 0000000..ee4982a --- /dev/null +++ b/Sdk/Http/Webhook/ParticipantRejected.cs @@ -0,0 +1,7 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class ParticipantRejected : EnvelopeStarted + { + + } +} diff --git a/Sdk/Http/Webhook/PersonVerificationCompleted.cs b/Sdk/Http/Webhook/PersonVerificationCompleted.cs new file mode 100644 index 0000000..c7faf83 --- /dev/null +++ b/Sdk/Http/Webhook/PersonVerificationCompleted.cs @@ -0,0 +1,12 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class PersonVerificationCompleted : AbstractWebhookResponse + { + public string Description { get; set; } + public string Status { get; set; } + public long? HandleDatetime { get; set; } + public long? SubmitDatetime { get; set; } + + } + +} diff --git a/Sdk/Http/Webhook/PersonVerificationSubmitted.cs b/Sdk/Http/Webhook/PersonVerificationSubmitted.cs new file mode 100644 index 0000000..f1526a8 --- /dev/null +++ b/Sdk/Http/Webhook/PersonVerificationSubmitted.cs @@ -0,0 +1,8 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class PersonVerificationSubmitted : EnterpriseVerificationPrimaryCompleted + { + + } + +} diff --git a/Sdk/Http/Webhook/QuickSignCompleted.cs b/Sdk/Http/Webhook/QuickSignCompleted.cs new file mode 100644 index 0000000..9607b31 --- /dev/null +++ b/Sdk/Http/Webhook/QuickSignCompleted.cs @@ -0,0 +1,8 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class QuickSignCompleted : AbstractWebhookResponse + { + public string Url { get; set; } + public string Base64 { get; set; } + } +} diff --git a/Sdk/Http/Webhook/RawDataBasicInfo.cs b/Sdk/Http/Webhook/RawDataBasicInfo.cs new file mode 100644 index 0000000..a68643c --- /dev/null +++ b/Sdk/Http/Webhook/RawDataBasicInfo.cs @@ -0,0 +1,31 @@ +namespace Signit.Sdk.Http.Webhook +{ + /** + * 信封基本信息. + * + * @since 2.0.0 + */ + public class RawDataBasicInfo + { + // 信封全局唯一ID + public string Wsid { get; set; } + + // 信封状态 + public string Status { get; set; } + + // 信封创建时间 + public long? CreatedDatetime { get; set; } + + // 信封过期时间 + public long? ExpireDatetime { get; set; } + + // 信封最新状态时间 + public long? StatusDatetime { get; set; } + + // 信封最新状态原因 + public string StatusReason { get; set; } + + // 当前签署方的序号 + public int? CurrentSequence { get; set; } + } +} diff --git a/Sdk/Http/Webhook/Receiver.cs b/Sdk/Http/Webhook/Receiver.cs new file mode 100644 index 0000000..3708bb6 --- /dev/null +++ b/Sdk/Http/Webhook/Receiver.cs @@ -0,0 +1,56 @@ +namespace Signit.Sdk.Http.Webhook +{ + /** + * 当前需要签署的接收方信息. + * + * @since 2.0.0 + */ + public class Receiver + { + // 接收方信息 + public string Name { get; set; } + + // 接收方联系方式 + public BoContactMetadata ContactMetadata { get; set; } + + // 安全级别 + public string SecureLevel { get; set; } + + // 接收方类型 + public string Type { get; set; } + + // 接收方角色类型 + public string RoleType { get; set; } + + // 接收方是否必须预分配表单域 + public bool NeedForm { get; set; } + + // 设置接收方私人信息 + public string AssignedMessage { get; set; } + + // 设置接收方处理顺序 + public int? AssignedSequence { get; set; } + + // 签署认证等级 + public string AuthLevel { get; set; } + + // 接收方所在企业名称 + public string EnterpriseName { get; set; } + + // 信封自定义元数据信息 + public string Metadata { get; set; } + + // 签署状态 + public string Status { get; set; } + + // 接收方全局唯一标识 + public string Wsid { get; set; } + + // 处理时间 + public long? HandleDatetime { get; set; } + + // 处理原因 + public string HandleReason { get; set; } + + } +} diff --git a/Sdk/Http/Webhook/Sender.cs b/Sdk/Http/Webhook/Sender.cs new file mode 100644 index 0000000..2561eb4 --- /dev/null +++ b/Sdk/Http/Webhook/Sender.cs @@ -0,0 +1,18 @@ +namespace Signit.Sdk.Http.Webhook +{ + /** + * 发送方信息. + * + * @since 2.0.0 + */ + public class Sender + { + // 和Receiver同级 + // 发送者姓名 + public string Name { get; set; } + + // 发送者联系方式 + public BoContactMetadata ContactMetadata { get; set; } + + } +} diff --git a/Sdk/Http/Webhook/SignData.cs b/Sdk/Http/Webhook/SignData.cs new file mode 100644 index 0000000..0a8d084 --- /dev/null +++ b/Sdk/Http/Webhook/SignData.cs @@ -0,0 +1,21 @@ +namespace Signit.Sdk.Http.Webhook +{ + /** + * 已成功完成签署流程的文件数据. + * + * + * @since 2.0.0 + */ + public class SignData + { + // 文件ID + public string FileWsid { get; set; } + + // 已签署的文件数据的URL地址 + public string Url { get; set; } + + // 已签署的文件数据数据的base64表示形式的字符串 + public string Base64 { get; set; } + + } +} diff --git a/Sdk/Http/Webhook/WebhookData.cs b/Sdk/Http/Webhook/WebhookData.cs new file mode 100644 index 0000000..f037794 --- /dev/null +++ b/Sdk/Http/Webhook/WebhookData.cs @@ -0,0 +1,7 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class WebhookData : WebhookDataBase + { + public SignatureResponse RawData { get; set; } + } +} diff --git a/Sdk/Http/Webhook/WebhookDataBase.cs b/Sdk/Http/Webhook/WebhookDataBase.cs new file mode 100644 index 0000000..e936384 --- /dev/null +++ b/Sdk/Http/Webhook/WebhookDataBase.cs @@ -0,0 +1,22 @@ +namespace Signit.Sdk.Http.Webhook +{ + public class WebhookDataBase + { + public string Event { get; set; } + public SourceType Source { get; set; } + public TargetType Target { get; set; } + public bool NeedCallback { get; set; } + + public class SourceType + { + public string Platform { get; set; } + public string Destination { get; set; } + } + + public class TargetType + { + public string WebhookWsid { get; set; } + public string Destination { get; set; } + } + } +} diff --git a/Sdk/Http/Webhook/WebhookResponse.cs b/Sdk/Http/Webhook/WebhookResponse.cs new file mode 100644 index 0000000..90a7596 --- /dev/null +++ b/Sdk/Http/Webhook/WebhookResponse.cs @@ -0,0 +1,43 @@ +using Newtonsoft.Json; +using System; + +namespace Signit.Sdk.Http.Webhook +{ + public partial class WebhookResponse : WebhookDataBase + { + public string RawData { get; set; } + + public AbstractWebhookResponse GetResponseData() + { + return JsonConvert.DeserializeObject(RawData, GetEventType()) as AbstractWebhookResponse; + } + + public T GetResponseData() + where T : AbstractWebhookResponse + { + return JsonConvert.DeserializeObject(RawData); + } + + private Type GetEventType() + { + var @event = Event; + var fullName = $"Signit.Sdk.Http.Webhook.{@event}"; + + try + { + var type = Type.GetType(fullName, true, true); + if (!typeof(AbstractWebhookResponse).IsAssignableFrom(type)) + { + throw new SignitException("无法根据事件名称[%s]自动生成对应的webhook响应数据[%s],请选择重新解析方法"); + } + return type; + } + catch (TypeLoadException tle) + { + throw new SignitException( + "无法根据事件名称[%s]自动生成对应的webhook响应数据[%s],请选择重新解析方法", + tle); + } + } + } +} diff --git a/Sdk/IVerifyRequest.cs b/Sdk/IVerifyRequest.cs new file mode 100644 index 0000000..819ea9e --- /dev/null +++ b/Sdk/IVerifyRequest.cs @@ -0,0 +1,11 @@ +namespace Signit.Sdk +{ + public interface IVerifyRequest + { + string GetHeader(string key); + string GetMethod(); + string ContentType { get; } + + byte[] GetBody(); + } +} diff --git a/Sdk/Properties/AssemblyInfo.cs b/Sdk/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..4a7bf64 --- /dev/null +++ b/Sdk/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("Sdk")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("SignIt")] +[assembly: AssemblyProduct("Sdk")] +[assembly: AssemblyCopyright("Copyright © SignIt 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("e583eaf3-04f9-4ab6-b265-d737568aaefc")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Sdk/Sdk.csproj b/Sdk/Sdk.csproj new file mode 100644 index 0000000..0409340 --- /dev/null +++ b/Sdk/Sdk.csproj @@ -0,0 +1,165 @@ + + + + + Debug + AnyCPU + {E583EAF3-04F9-4AB6-B265-D737568AAEFC} + Library + Properties + Signit.Sdk + Signit.Sdk + v4.0 + 512 + true + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + false + + + + ..\packages\Newtonsoft.Json.12.0.2\lib\net40\Newtonsoft.Json.dll + + + + + ..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.IO.dll + + + ..\packages\Microsoft.Net.Http.2.2.29\lib\net40\System.Net.Http.dll + + + ..\packages\Microsoft.Net.Http.2.2.29\lib\net40\System.Net.Http.Extensions.dll + + + ..\packages\Microsoft.Net.Http.2.2.29\lib\net40\System.Net.Http.Primitives.dll + + + ..\packages\Microsoft.Net.Http.2.2.29\lib\net40\System.Net.Http.WebRequest.dll + + + ..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Runtime.dll + + + ..\packages\Microsoft.Bcl.1.1.10\lib\net40\System.Threading.Tasks.dll + + + + + + + + + ..\packages\Viyi.Util.1.1.2\lib\net40\Viyi.Util.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + \ No newline at end of file diff --git a/Sdk/SignitClient.cs b/Sdk/SignitClient.cs new file mode 100644 index 0000000..2aede33 --- /dev/null +++ b/Sdk/SignitClient.cs @@ -0,0 +1,212 @@ +using Newtonsoft.Json; +using Signit.Sdk.Http; +using Signit.Sdk.Http.Webhook; +using Signit.Sdk.Types; +using Signit.Sdk.Util; +using System.Collections.Specialized; +using System.Diagnostics; +using Viyi.Util; + +namespace Signit.Sdk +{ + public class SignitClient + { + public static WebhookData ParseWebhookData(string raw) + { + return JsonConvert.DeserializeObject(raw); + } + + public static WebhookResponse ParseWebhookResponse(string raw) + { + return JsonConvert.DeserializeObject(raw); + } + + public Authentication Authentication { get; private set; } + private readonly ApiOptions options; + + //private HttpClientWrapper httpClient; + //private readonly int MAX_COUNT = 3; + //private readonly AtomicInteger count = new AtomicInteger(MAX_COUNT); + //private const Pattern LEFT_QUOTATION = Pattern.compile("\"\\{"); + //private const Pattern RIGHT_QUOTATION = Pattern.compile("\\}\""); + //private const Pattern BACKLASH_QUOTATION = Pattern.compile("\\\\\""); + + private string baseUrl; + private string oAuthTokenUrl; + + public SignitClient(ApiOptions options = null) : this(null, null, options) { } + + public SignitClient(string appId, string secretKey, string url) + : this(new Authentication() { AppId = appId, SecuretKey = secretKey }, + url) + { } + + public SignitClient(Authentication auth, string url = null, ApiOptions options = null) + { + this.options = options = options ?? ApiOptions.Default; + options.EnvUrl = url ?? options.EnvUrl; + SetUrl(options.EnvUrl); + Authentication = auth; + } + + public string Url { set => SetUrl(value); } + + public SignitClient SetUrl(string envUrl) + { + var url = string.IsNullOrWhiteSpace(envUrl) + ? options.EnvUrl + : envUrl.Trim(); + + baseUrl = $"{url}{options.BaseApiUrl}"; + oAuthTokenUrl = $"{url}{options.OAuthTokenUrl}"; + + return this; + } + + /// + /// 单纯的进行认证并获取授权相关信息,并不保存 + /// + /// + /// + /// + /// + public OAuthData RequestAuthentication(string apiKey, string secretKey, + TokenType tokenType = TokenType.CLIENT_CREDENTIALS) + { + if (string.IsNullOrEmpty(apiKey) || string.IsNullOrEmpty(secretKey)) + { + throw new SignitException("请完善开发者账户数据"); + } + + HttpClientSync client = new HttpClientSync() + .AddQueryParam(options.ClientId, apiKey) + .AddQueryParam(options.ClientSecret, secretKey) + .AddQueryParam(options.GrantType, tokenType.ToString().ToLower()); + + return client.Get(oAuthTokenUrl).GetObject(); + } + + /// + /// 授权并缓存获取的授权信息 + /// + /// + /// + /// + /// + public Authentication Authenticate(string apiKey, string secretKey, + TokenType tokenType = TokenType.CLIENT_CREDENTIALS) + { + OAuthData authData = RequestAuthentication(apiKey, secretKey, tokenType); + if (authData == null) + { + return null; + } + + Authentication = new Authentication + { + AccessToken = authData.AccessToken, + AccessTokenType = tokenType, + AppId = apiKey, + SecuretKey = secretKey + }; + + return Authentication; + } + + /// + /// 发送快捷签署请求 + /// + /// 快捷签署请求 + /// 快捷签署响应 + + public SignatureResponse QuickSign(SignatureRequest request) + { + + if (request == null) + { + return null; + } + + var auth = Authentication; + if (auth == null || !(auth.HasAppId && auth.HasSecretKey)) + { + throw new SignitException("请完善开发者信息"); + } + + if (!auth.HasAccessToken) + { + Authenticate(auth.AppId, auth.SecuretKey, auth.AccessTokenType); + } + + // TODO 返回 + var client = new HttpClientSync(); + var headers = new NameValueCollection + { + { options.AppIdKey, auth.AppId } + }; + + var response = client + .WithAuthentication(Authentication) + .Post(baseUrl, request, headers); + + return response.GetObject(); + } + + public static bool Verify(string signitSignature, string appId, HmacSignatureBuilder builder) + { + if (builder == null || appId == null || signitSignature == null) + { + return false; + } + + string selfSignature = $"{HmacSignatureBuilder.DEFAULT_ALGORITHM} {appId}:{builder.BuildAsBase64()}"; + return selfSignature == signitSignature; + } + + public static bool Verify(string appId, string secretKey, IVerifyRequest request) + { + var signature = request.GetHeader("X-Signit-Signature") ?? ""; + + HmacSignatureBuilder builder = new HmacSignatureBuilder() + .Scheme(request.GetHeader("X-Signit-Scheme")) + .ApiKey(appId) + .ApiSecret(secretKey.ToByteArray()) + .Method(request.GetMethod().ToUpper()) + .Payload(request.GetBody()) + .ContentType(request.ContentType) + .Host(request.GetHeader("X-Signit-Host") ?? "") + .Resource(request.GetHeader("X-Signit-Resource") ?? "") + .Nonce(request.GetHeader("X-Signit-Nonce") ?? "") + .Date(request.GetHeader("X-Signit-Date") ?? ""); + + string selfSignature = $"{HmacSignatureBuilder.DEFAULT_ALGORITHM} {appId}:{builder.BuildAsBase64()}"; + return selfSignature == signature; + } + + public T Execute(AbstractSignitRequest request) + where T : AbstractSignitResponse + { + if (request == null) + { + return null; + } + + var auth = Authentication; + if (!auth.HasAccessToken || !auth.HasAppId || !auth.HasSecretKey) + { + throw new SignitException("请完善开发者信息"); + } + + var client = new HttpClientSync(); + var headers = new NameValueCollection + { + { options.AppIdKey, auth.AppId } + }; + + var response = client.WithAuthentication(auth) + .Post(baseUrl, request, headers); + + return response.GetObject(); + } + } +} diff --git a/Sdk/SignitException.cs b/Sdk/SignitException.cs new file mode 100644 index 0000000..8bfea0c --- /dev/null +++ b/Sdk/SignitException.cs @@ -0,0 +1,35 @@ +using System; + +namespace Signit.Sdk +{ + public class SignitException : Exception + { + private readonly int httpCode; + private readonly string type; + + public SignitException(Exception e) : base(null, e) { } + + public SignitException(string message) : base(message) { } + + public SignitException(string message, Exception e) : base(message, e) { } + + public SignitException(string message, int httpCode, string type) + : this(message, httpCode, type, null) { } + + public SignitException(string message, int httpCode, string type, Exception e) : base(message, e) + { + this.httpCode = httpCode; + this.type = type; + } + + public int getHttpCode() + { + return httpCode; + } + + public string getType() + { + return type; + } + } +} diff --git a/Sdk/Types/AuthLevel.cs b/Sdk/Types/AuthLevel.cs new file mode 100644 index 0000000..fac3ab4 --- /dev/null +++ b/Sdk/Types/AuthLevel.cs @@ -0,0 +1,24 @@ +namespace Signit.Sdk.Types +{ + + /// + /// 参与者签署认证等级枚举 + /// + public enum AuthLevel + { + /// + /// 低等级 + /// + LOW, + + /// + /// 中等级 + /// + MIDDLE, + + /// + /// 高等级 + /// + HIGH + } +} diff --git a/Sdk/Types/AuthType.cs b/Sdk/Types/AuthType.cs new file mode 100644 index 0000000..19aa5eb --- /dev/null +++ b/Sdk/Types/AuthType.cs @@ -0,0 +1,51 @@ +namespace Signit.Sdk.Types +{ + + /** + * 签署认证类型类型. + * + * 用户确认签署时,需要验证签署人身份,此处为所有验证方式枚举 + * + * @since 2.1.0 + */ + public enum AuthType + { + /** + * 短信验证码 + * + * @since 2.1.0 + */ + SMS_CODE, + /** + * 邮箱验证码 + * + * @since 2.1.0 + */ + EMAIL_CODE, + /** + * 签署密码 + * + * @since 2.1.0 + */ + SIGN_PIN, + /** + * 活体认证 + * + * @since 2.1.0 + */ + LIVING_AUTH, + /** + * usbkey认证 + * + * @since 2.1.0 + */ + USBKEY, + /** + * 手机盾认证 + * + * @since 2.1.0 + */ + MOBILE_SHIELD + + } +} \ No newline at end of file diff --git a/Sdk/Types/CertType.cs b/Sdk/Types/CertType.cs new file mode 100644 index 0000000..262d0d3 --- /dev/null +++ b/Sdk/Types/CertType.cs @@ -0,0 +1,22 @@ +namespace Signit.Sdk.Types +{ + + /** + * + * 签名所使用的证书类型枚举. + * + * @since 2.0.0 + */ + public enum CertType + { + + /** + * 一次性证书 + */ + DISPOSABLE_CERT, + /** + * 标准证书 + */ + STANDARD_CERT + } +} \ No newline at end of file diff --git a/Sdk/Types/Direction.cs b/Sdk/Types/Direction.cs new file mode 100644 index 0000000..12f38f2 --- /dev/null +++ b/Sdk/Types/Direction.cs @@ -0,0 +1,8 @@ +namespace Signit.Sdk.Types +{ + + public enum Direction + { + TOP, BOTTOM, LEFT, RIGHT, CENTER + } +} \ No newline at end of file diff --git a/Sdk/Types/EnterpriseAuthType.cs b/Sdk/Types/EnterpriseAuthType.cs new file mode 100644 index 0000000..e327256 --- /dev/null +++ b/Sdk/Types/EnterpriseAuthType.cs @@ -0,0 +1,21 @@ +namespace Signit.Sdk.Types + +{ + /** + * + * 企业实名认证类型. + * + * @since 1.0.2 + */ + public enum EnterpriseAuthType + { + /** + * 法人认证 + */ + LEGAL_PERSON, + /** + * 经办人认证 + */ + AGENT + } +} \ No newline at end of file diff --git a/Sdk/Types/Enums.cs b/Sdk/Types/Enums.cs new file mode 100644 index 0000000..cabce40 --- /dev/null +++ b/Sdk/Types/Enums.cs @@ -0,0 +1,12 @@ +namespace Signit.Sdk.Entity +{ + public enum AcceptDataType + { + BASE64, URL + } + + public enum Direction + { + TOP, BOTTOM, LEFT, RIGHT, CENTER + } +} diff --git a/Sdk/Types/EnvelopeRoleType.cs b/Sdk/Types/EnvelopeRoleType.cs new file mode 100644 index 0000000..953c4f9 --- /dev/null +++ b/Sdk/Types/EnvelopeRoleType.cs @@ -0,0 +1,20 @@ +namespace Signit.Sdk.Types +{ + /** + * + * 接收方角色类型. + * + * @since 1.0.2 + */ + public enum EnvelopeRoleType + { + /** + * 个人 + */ + PERSON, + /** + * 企业成员 + */ + ENTERPRISE_MEMBER + } +} \ No newline at end of file diff --git a/Sdk/Types/EnvelopeType.cs b/Sdk/Types/EnvelopeType.cs new file mode 100644 index 0000000..db3d318 --- /dev/null +++ b/Sdk/Types/EnvelopeType.cs @@ -0,0 +1,36 @@ +namespace Signit.Sdk.Types +{ + + /** + * 信封类型枚举. + * + * @since 1.0.2 + */ + public enum EnvelopeType + { + /** + * 任意. + * + * @since 1.0.2 + */ + ANY, + /** + * 本人. + * + * @since 1.0.2 + */ + ME, + /** + * 我与他人. + * + * @since 1.0.2 + */ + ME_AND_OTHERS, + /** + * 他人. + * + * @since 1.0.2 + */ + OTHERS + } +} \ No newline at end of file diff --git a/Sdk/Types/FileType.cs b/Sdk/Types/FileType.cs new file mode 100644 index 0000000..631af39 --- /dev/null +++ b/Sdk/Types/FileType.cs @@ -0,0 +1,174 @@ +namespace Signit.Sdk.Types +{ + /** + * 基于文件头描述源文件真实类型. + * + * @since 2.0.0 + */ + public enum FileType + { + /** + * JPEG. + */ + JPEG, + + /** + * JPG. + */ + JPG, + + /** + * JPE. + */ + JPE, + + /** + * PNG. + */ + PNG, + + /** + * GIF. + */ + GIF, + + /** + * TIFF. + */ + TIFF, + + /** + * Windows Bitmap. + */ + BMP, + + /** + * CAD. + */ + DWG, + + /** + * Adobe Photoshop. + */ + PSD, + + /** + * Rich Text Format. + */ + RTF, + + /** + * XML. + */ + XML, + + /** + * HTML. + */ + HTML, + + /** + * Email [thorough only]. + */ + EML, + + /** + * Outlook Express. + */ + DBX, + + /** + * Outlook (pst). + */ + PST, + + /** + * MS 2003 Word/Excel/PointPower. + */ + MS_2003, + + /** + * MS 2007 and later Archive.MS Word/Excel/PointPower. (docx,pptx,xlsx) + */ + MS_2007, + + /** + * MS Access. + */ + MDB, + + /** + * WordPerfect. + */ + WPD, + + /** + * Postscript. + */ + EPS, + + /** + * Adobe Acrobat. + */ + PDF, + + /** + * Quicken. + */ + QDF, + + /** + * Windows Password. + */ + PWL, + + /** + * ZIP Archive. (docx,pptx,xlsx) + */ + ZIP, + + /** + * RAR Archive. + */ + RAR, + + /** + * Wave. + */ + WAV, + /** + * AVI. + */ + AVI, + + /** + * Real Audio. + */ + RAM, + + /** + * Real Media. + */ + RM, + + /** + * MPEG (mpg). + */ + MPG, + + /** + * Quicktime. + */ + MOV, + + /** + * Windows Media. + */ + ASF, + + /** + * MIDI. + */ + MID + } +} diff --git a/Sdk/Types/FormType.cs b/Sdk/Types/FormType.cs new file mode 100644 index 0000000..074c598 --- /dev/null +++ b/Sdk/Types/FormType.cs @@ -0,0 +1,33 @@ +namespace Signit.Sdk.Types +{ + /** + * + * 表单类型枚举. + * + * @since 2.0.0 + */ + public enum FormType + { + + /** + * 印章签名表单域 + */ + SEAL_SIGN, + /** + * 手写签名表单域 + */ + WRITE_SIGN, + /** + * 文本表单域 + */ + TEXT, + /** + * 骑缝章表单域 + */ + MULTI_CHECK_MARK, + /** + * 二维码骑缝章表单域 + */ + MULTI_QRCODE_MARK + } +} \ No newline at end of file diff --git a/Sdk/Types/IdCardType.cs b/Sdk/Types/IdCardType.cs new file mode 100644 index 0000000..ae9990f --- /dev/null +++ b/Sdk/Types/IdCardType.cs @@ -0,0 +1,25 @@ +namespace Signit.Sdk.Types +{ + /** + * + * 身份证类型枚举. + * + * @since 1.0.2 + */ + public enum IdCardType + { + /** + * 二代身份证 + */ + SECOND_GENERATION_IDCARD, + /** + * 临时身份证 + */ + TEMPORARY_IDCARD, + /** + * 护照 + */ + PASSPORT + + } +} \ No newline at end of file diff --git a/Sdk/Types/NamingStyle.cs b/Sdk/Types/NamingStyle.cs new file mode 100644 index 0000000..23138ce --- /dev/null +++ b/Sdk/Types/NamingStyle.cs @@ -0,0 +1,31 @@ +namespace Signit.Sdk.Types +{ + /** + * 命名风格的枚举. + * + * @author zhd + * @since 1.0.0 + */ + public enum NamingStyle + { + /** + * 小驼峰命名风格.如:nameStyle + */ + CAMEL, + + /** + * 字母间均大写命名风格.如:NameStyle + */ + PASCAL, + + /** + * 字母间均以下划线分隔命名风格(unix命名风格).如:name_style + */ + SNAKE, + + /** + * 字母间均以连词符分隔命名风格.如:name-style + */ + KEBAB + } +} diff --git a/Sdk/Types/ParticipantHandleMode.cs b/Sdk/Types/ParticipantHandleMode.cs new file mode 100644 index 0000000..b73840c --- /dev/null +++ b/Sdk/Types/ParticipantHandleMode.cs @@ -0,0 +1,25 @@ +namespace Signit.Sdk.Types +{ + /** + * 参与者处理表单的模式枚举 + * + * @since 2.0.0 + */ + public enum ParticipantHandleMode + { + /** + * 正常处理模式(默认). + * + * @since 2.0.0 + */ + NORMAL, + /** + * 静默处理模式. + * 该接受方不用执行签署流程,自动完成签署。接收方设置为静默签署条件:①接收方类型为签署者SIGNER;②接收方和发起方为同一企业下的同一人;③该接收方有预设表单,且该接收方的预设表单均设置了初始值(手写签名表单除外)。 + * + * @since 2.0.0 + */ + SILENCE + + } +} \ No newline at end of file diff --git a/Sdk/Types/PersonAuthType.cs b/Sdk/Types/PersonAuthType.cs new file mode 100644 index 0000000..aa78860 --- /dev/null +++ b/Sdk/Types/PersonAuthType.cs @@ -0,0 +1,16 @@ +namespace Signit.Sdk.Types +{ + /** + * 个人实名认证方式 + * + * @since 2.1.0 + */ + public enum PersonAuthType + { + /** + * 三网手机号三元素实名认证方式 + */ + PHONE_AUTH + + } +} \ No newline at end of file diff --git a/Sdk/Types/ReceiverType.cs b/Sdk/Types/ReceiverType.cs new file mode 100644 index 0000000..125df20 --- /dev/null +++ b/Sdk/Types/ReceiverType.cs @@ -0,0 +1,23 @@ +namespace Signit.Sdk.Types +{ + /** + * 参与者类型状态枚举. + * + * @since 2.0.0 + */ + public enum ReceiverType + { + /** + * 签署者 + * + * @since 2.0.0 + */ + SIGNER, + /** + * 审核者 + * + * @since 2.0.0 + */ + CHECKER, + } +} \ No newline at end of file diff --git a/Sdk/Types/RenderMode.cs b/Sdk/Types/RenderMode.cs new file mode 100644 index 0000000..22ea1ec --- /dev/null +++ b/Sdk/Types/RenderMode.cs @@ -0,0 +1,29 @@ +namespace Signit.Sdk.Types +{ + /** + * 签名渲染模式. + * + * + * @since 2.0.0 + */ + public enum RenderMode + { + + /** + * The rendering mode is just the description. + */ + DESCRIPTION, + /** + * The rendering mode is the name of the signer and the description. + */ + NAME_AND_DESCRIPTION, + /** + * The rendering mode is an image and the description. + */ + GRAPHIC_AND_DESCRIPTION, + /** + * The rendering mode is just an image. + */ + GRAPHIC + } +} \ No newline at end of file diff --git a/Sdk/Types/SecureLevel.cs b/Sdk/Types/SecureLevel.cs new file mode 100644 index 0000000..3cba61e --- /dev/null +++ b/Sdk/Types/SecureLevel.cs @@ -0,0 +1,23 @@ +namespace Signit.Sdk.Types +{ + /** + * 要求的安全级别类型的枚举 + * + * @since 2.0.0 + */ + public enum SecureLevel + { + /** + * 一次性证书. + * + * @since 2.0.0 + */ + DISPOSABLE_CERT, + /** + * 标准证书. + * + * @since 2.0.0 + */ + STANDARD_CERT + } +} \ No newline at end of file diff --git a/Sdk/Types/TokenType.cs b/Sdk/Types/TokenType.cs new file mode 100644 index 0000000..06960ee --- /dev/null +++ b/Sdk/Types/TokenType.cs @@ -0,0 +1,11 @@ +namespace Signit.Sdk.Types +{ + public enum TokenType + { + CLIENT_CREDENTIALS, + AUTHORIZATION_CODE, + IMPLICIT, + PASSWORD, + REFRESH_TOKEN, + } +} \ No newline at end of file diff --git a/Sdk/Util/AesTool.cs b/Sdk/Util/AesTool.cs new file mode 100644 index 0000000..cb3a227 --- /dev/null +++ b/Sdk/Util/AesTool.cs @@ -0,0 +1,98 @@ +using System.Security.Cryptography; + +namespace Signit.Sdk.Util +{ + public static class AesTool + { + /// + /// 获取所使用 AES 算法的块大小,单位:位 + /// + public static int BlockSize { get { return Aes.BlockSize; } } + + /// + /// 获取所使用 AES 算法的 Key 大小,单位:位 + /// + public static int KeySize { get { return Aes.KeySize; } } + + /// + /// 直接通过密码对数据加密。加密所使用的初始化向量根据密码生成。 + /// + /// 需要加密的数据 + /// 密码,不能为 null,但可以是 string.Empty + /// 加密后的数据 + public static byte[] AesEncrypt(this byte[] me, string password) + { + return SymmetricTool.Encrypt(Aes, password, me); + } + + /// + /// 直接通过密码对数据加密。加密所使用的初始化向量根据密码生成。 + /// + /// 需要加密的数据,不能为 null + /// 起始位置 + /// 需要加密的数据长度 + /// 密码,不能为 null,但可以是 string.Empty + /// 加密后的数据 + public static byte[] AesEncrypt(this byte[] me, int start, int length, string password) + { + return SymmetricTool.Encrypt(Aes, password, me, start, length); + } + + /// + /// 直接通过密码对数据解密。解密所使用的初始化向量根据密码生成。 + /// + /// 需要解密的数据 + /// 密码,不能为 null,但可以是 string.Empty + /// 解密后的数据 + public static byte[] AesDecrypt(this byte[] me, string password) + { + return SymmetricTool.Decrypt(Aes, password, me); + } + + /// + /// 使用AES加密数据。 + /// + /// 数据字节 + /// 初始化向量 + /// 密钥 + /// 加密后的数据。 + /// 如果原数据是null,则返回null + /// 如果需要加密字符串,可以使用string.ToByteArray扩展方法 + /// 先把string转换成字符数组 + public static byte[] AesEncrypt(this byte[] me, byte[] iv, byte[] key) + { + return InternalTool.Encrypt(Aes, me, iv, key); + } + + /// + /// 使用AES加密数据 + /// + /// 数据字节 + /// 随机产生初始化向量并通过iv返回。 + /// 如果源数据是null,返回null + /// 密钥 + /// 加密后的数据。如果原数据是null,则返回null + /// 如果需要加密字符串,可以使用string.ToByteArray扩展方法 + /// 先把string转换成字符数组 + public static byte[] AesEncrypt(this byte[] me, out byte[] iv, byte[] key) + { + return InternalTool.Encrypt(Aes, me, out iv, key); + } + + /// + /// 使用AES解密(加密后的)数据 + /// + /// 数据字节 + /// 初始化向量 + /// 密钥 + /// 解密后的数据,即源数据。 + /// 如果数据字节是null,返回null + public static byte[] AesDecrypt(this byte[] me, byte[] iv, byte[] key) + { + return InternalTool.Decrypt(Aes, me, iv, key); + } + + private static Aes Aes { get { return aesInstance ?? (aesInstance = Aes.Create()); } } + private static Aes aesInstance; + } +} diff --git a/Sdk/Util/HmacSignatureBuilder.cs b/Sdk/Util/HmacSignatureBuilder.cs new file mode 100644 index 0000000..675674b --- /dev/null +++ b/Sdk/Util/HmacSignatureBuilder.cs @@ -0,0 +1,368 @@ +using Signit.Sdk.Extentions; +using System; +using System.Diagnostics; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using Viyi.Util; +using Viyi.Util.Codec; +using Viyi.Util.Linq; + +namespace Signit.Sdk.Util +{ + public class HmacSignatureBuilder + { + public enum BuilderMode + { + /// + /// 所有字段均加入运算 + /// + FULL, + + /// + /// 只有请求头字段加入运算 + /// + ONLY_HEADER + } + + public const string DEFAULT_ALGORITHM = "HmacSHA512"; + public const string DEFAULT_CHARSET = "UTF-8"; + public static readonly byte[] DEFAULT_DELIMITER = "\n".ToByteArray(DEFAULT_CHARSET); + private byte[] delimiter = DEFAULT_DELIMITER; + private string charset = DEFAULT_CHARSET; + private string algorithm = DEFAULT_ALGORITHM; + private string scheme; + private string host; + private string method; + private string resource; + private string nonce; + private string apiKey; + private byte[] apiSecret; + private byte[] payload; + private string date; + private string contentType; + + /** + * 设置加入运算的相关字符的字符集编码规则. + * + * @param charset + * 字符集编码规则 + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder Charset(String charset) + { + this.charset = charset; + return this; + } + + /** + * 设置加入运算的字符间的分隔符. + * + * @param delimiter + * 字符间的分隔符 + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder Delimiter(byte[] delimiter) + { + this.delimiter = delimiter; + return this; + } + + public HmacSignatureBuilder Delimiter(byte delimiter) + { + this.delimiter = new[] { delimiter }; + return this; + } + + /** + * 设置HMAC的算法. + * + * @param algorithm + * HMAC的算法 + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder Algorithm(String algorithm) + { + this.algorithm = algorithm; + return this; + } + + /** + * 设置需要加入运算的协议名称. + * + * @param scheme + * 协议名称(如: http/https/ftp/...) + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder Scheme(String scheme) + { + this.scheme = scheme; + return this; + } + + /** + * 设置需要加入运算的主机名称. + * + * @param host + * 主机名称(如: signit.cn/10.10.10.10/...) + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder Host(String host) + { + this.host = host; + return this; + } + + /** + * 设置需要加入运算的服务器授权给客户端的唯一公开标识.(与apiSecret配套,允许公开). + * + * @param apiKey + * 服务器授权给客户端的唯一公开标识.(与apiSecret配套,允许公开) + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder ApiKey(String apiKey) + { + this.apiKey = apiKey; + return this; + } + + /** + * 设置需要加入运算的请求方法. + * + * @param method + * 请求方法(如: GET/POST/PUT/DELETE/...) + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder Method(String method) + { + this.method = method; + return this; + } + + /** + * 设置需要加入运算的请求资源地址(URI). + * + * @param resource + * 请求资源地址(URI)(如: '/v1/users','/v1/users/123',...) + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder Resource(String resource) + { + this.resource = resource; + return this; + } + + /** + * 设置需要加入运算的请求内容类型(Content-Type). + * + * @param contentType + * 请求内容类型(Content-Type)(如: 'application/json','image/jpeg',...) + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder ContentType(String contentType) + { + this.contentType = contentType; + return this; + } + + /** + * 设置需要加入运算的请求时间(Date). + * + * @param date + * 请求时间(Date)(如: 'Sat, 02 Jul 2011 20:45:57 GMT','Wed, 02 Nov + * 2016 03:25:54 GMT',...) + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder Date(String date) + { + this.date = date; + return this; + } + + /** + * 设置需要加入运算的随机数. + * + * @param nonce + * 随机数(如: '6m0S4nyH1dg7K2gh','8NQq53cLR4g5Y52I',...) + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder Nonce(String nonce) + { + this.nonce = nonce; + return this; + } + + /** + * 设置需要加入运算的服务器授权给客户端的私密密钥.(与apiKey配套,但不公开). + * + + * @param apiSecret + + * 服务器授权给客户端的私密密钥.(与apiKey配套,但不公开) + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder ApiSecret(byte[] apiSecret) + { + this.apiSecret = apiSecret; + return this; + } + + /** + * 设置需要加入运算的请求数据. + * + + * @param payload + + * 请求数据 + * @return 当前HMAC建造器对象 + * @author zhd + * @since 1.0.0 + */ + public HmacSignatureBuilder Payload(byte[] payload) + { + this.payload = payload; + return this; + } + + public string BuildAsHex(BuilderMode builderMode = BuilderMode.FULL) + { + return Build(builderMode).HexEncode(); + } + + public string BuildAsBase64(BuilderMode builderMode = BuilderMode.FULL) + { + return Build(builderMode).Base64Encode(); + } + + /** + * 完成HMAC认证消息的构建,并获得签名摘要值. + * + * @param builderMode + * 构建模式的枚举 + * @return HMAC原始签名摘要值的内存数据字节.若构建失败,则返回null + * @author zhd + * @since 1.0.0 + */ + public byte[] Build(BuilderMode builderMode = BuilderMode.FULL) + { + Func builder = null; + switch (builderMode) + { + case BuilderMode.FULL: + builder = GetFullStream; + break; + case BuilderMode.ONLY_HEADER: + builder = GetOnlyHeaderStream; + break; + } + + if (builder == null) + { + Debug.WriteLine($"不支持的参数类型: {builderMode}"); + return null; + } + + var hmac = HMAC.Create(algorithm); + hmac.Key = apiSecret; + return hmac.ComputeHash(builder()); + } + + + // 完整的数据运算 + private Stream GetFullStream() + { + MemoryStream stream = new MemoryStream(); + SignitStreamWriter writer = new SignitStreamWriter(stream) + .SetDelimiter(delimiter) + .SetEncoding(charset); + + new[] { apiKey, contentType, date, host, method, nonce } + .ForEach(writer.Write); + + if (payload?.Length > 0) + { + writer.Write(payload); + } + + new[] { resource, scheme } + .ForEach(writer.Write); + + stream.Seek(0, SeekOrigin.Begin); + return stream; + } + + private Stream GetOnlyHeaderStream() + { + MemoryStream stream = new MemoryStream(); + SignitStreamWriter writer = new SignitStreamWriter(stream) + .SetDelimiter(delimiter) + .SetEncoding(charset); + + new[] { apiKey, contentType, date, host, method, nonce, resource, scheme } + .ForEach(writer.Write); + + stream.Seek(0, SeekOrigin.Begin); + return stream; + } + + public void VerifySignature(byte[] expect, + BuilderMode mode = BuilderMode.FULL, + string errMessage = null) + { + if (Enumerable.SequenceEqual(expect, Build(mode))) + { + return; + } + + throw new ArgumentException(errMessage); + } + + public void VerifyHexSignature(string expect, + BuilderMode mode = BuilderMode.FULL, + string errMessage = null) + { + if (expect == BuildAsHex(mode)) + { + return; + } + + throw new ArgumentException(errMessage); + } + + public void VerifyBase64Signature(string expect, + BuilderMode mode = BuilderMode.FULL, + string errMessage = null) + { + if (expect == BuildAsBase64(mode)) + { + return; + } + + throw new ArgumentException(errMessage); + } + } +} diff --git a/Sdk/Util/InternalTool.cs b/Sdk/Util/InternalTool.cs new file mode 100644 index 0000000..718c57d --- /dev/null +++ b/Sdk/Util/InternalTool.cs @@ -0,0 +1,123 @@ +using System.Security.Cryptography; +using Viyi.Util.Codec; + +namespace Signit.Sdk.Util +{ + internal static class InternalTool + { + #region 对称加密算法模板 + public static byte[] Encrypt(SymmetricAlgorithm algorithm, byte[] data, byte[] iv, byte[] key) + { + if (data == null) { return null; } + + key = CheckAndPadKey(key, algorithm); + ICryptoTransform transform = algorithm.CreateEncryptor(key, iv); + return transform.TransformFinalBlock(data, 0, data.Length); + } + + public static byte[] Encrypt(SymmetricAlgorithm algorithm, byte[] data, out byte[] iv, byte[] key) + { + if (data == null) + { + iv = null; + return null; + } + + key = CheckAndPadKey(key, algorithm); + iv = algorithm.IV; + ICryptoTransform transform = algorithm.CreateEncryptor(key, iv); + return transform.TransformFinalBlock(data, 0, data.Length); + } + + internal static byte[] Encrypt( + SymmetricAlgorithm algorithm, + byte[] data, int start, int length, + byte[] iv, byte[] key) + { + if (data == null) { return null; } + key = CheckAndPadKey(key, algorithm); + ICryptoTransform transform = algorithm.CreateEncryptor(key, iv); + return transform.TransformFinalBlock(data, start, length); + } + + public static byte[] Decrypt(SymmetricAlgorithm algorithm, byte[] data, byte[] iv, byte[] key) + { + if (data == null) { return null; } + + key = CheckAndPadKey(key, algorithm); + ICryptoTransform transform = algorithm.CreateDecryptor(key, iv); + return transform.TransformFinalBlock(data, 0, data.Length); + } + #endregion + + #region 根据加密算法要求补齐Key + + private static readonly byte[] PadingSalt + = "4KC8A0HCSLFDCPDREVQUVYYCPHB9L549UQ0WITFITWV19D8751QEXN6FTPIT8EGW".HexDecode(); + + private const int PaddingIterations = 64; + + /// + /// 使用PBKDF2算法补齐密码 + /// + /// + /// + /// + internal static byte[] PadKey(byte[] key, int length) + { + return key == null + ? null + : new Rfc2898DeriveBytes(key, PadingSalt, PaddingIterations).GetBytes(length); + } + + /// + /// 检查key的长度对算法来说是否合法,如果合法,直接返回。 + /// 如果不合法,使用PBKDF2算法对其进行补齐至最接近的长度,然后返回 + /// + /// + /// + /// + private static byte[] CheckAndPadKey(byte[] key, SymmetricAlgorithm algorithm) + { + if (key == null) { return null; } + + int length = key.Length * 8; + foreach (KeySizes sizes in algorithm.LegalKeySizes) + { + // 不在范围内,key无效 + if (length < sizes.MinSize || length > sizes.MaxSize) + { + continue; + } + + // 在范围内,又没有步长限制,key有效 + if (sizes.SkipSize == 0) { return key; } + + // 检查如果key的长度是合法长度,不需要Padding,直接返回 + if ((length - sizes.MinSize) % sizes.SkipSize == 0) + { + return key; + } + } + + // 检查key的长度不属于任何合法长度 + KeySizes firstSizes = algorithm.LegalKeySizes[0]; + int paddingLength; + if (length < firstSizes.MinSize) + { + paddingLength = firstSizes.MinSize; + } + else if (length > firstSizes.MaxSize) + { + paddingLength = firstSizes.MaxSize; + } + else + { + paddingLength = length + (length - firstSizes.MinSize) % firstSizes.SkipSize; + } + + return PadKey(key, paddingLength / 8); + } + #endregion + } +} diff --git a/Sdk/Util/SignitStreamWriter.cs b/Sdk/Util/SignitStreamWriter.cs new file mode 100644 index 0000000..80f9632 --- /dev/null +++ b/Sdk/Util/SignitStreamWriter.cs @@ -0,0 +1,57 @@ +using Signit.Sdk.Extentions; +using System.IO; +using System.Text; +using Viyi.Util; + +namespace Signit.Sdk.Util +{ + class SignitStreamWriter + { + public readonly Stream Stream; + private byte[] delimiter = new byte[0]; + private Encoding encoding = Encoding.UTF8; + + public SignitStreamWriter(Stream stream) + { + Stream = stream; + } + + public SignitStreamWriter SetDelimiter(byte[] delimiter) + { + this.delimiter = delimiter ?? new byte[0]; + return this; + } + + public SignitStreamWriter SetEncoding(string encoding) + { + this.encoding = Encoding.GetEncoding(encoding); + return this; + } + + public SignitStreamWriter SetEncoding(Encoding encoding) + { + this.encoding = encoding; + return this; + } + + public SignitStreamWriter Write(byte[] data) + { + Stream.Write(data); + Stream.Write(delimiter); + return this; + } + + public SignitStreamWriter Write(string s) + { + process(); + return this; + + void process() + { + if (s == null) { return; } + Stream.Write(s.ToByteArray(encoding)) + .Write(delimiter); + } + } + } +} diff --git a/Sdk/Util/SymmetricTool.cs b/Sdk/Util/SymmetricTool.cs new file mode 100644 index 0000000..06c6b9e --- /dev/null +++ b/Sdk/Util/SymmetricTool.cs @@ -0,0 +1,121 @@ +using System; +using System.Security.Cryptography; +using System.Text; + +namespace Signit.Sdk.Util +{ + /// + ///

用于对称加密算法的简化使用扩展方法工具类。该工具类使用户只需要提供密码即可对数据进行加解密。 + /// 加解密所使用的初始化向量是通过密码来计算的。

+ ///

由于该工具类使用了特定的生成初始化向量的算法,所以 SymmetricTool.Decrypt 方法只能解密

+ /// 由 SymmetricTool.Encrypt 生成的,或通过其兼容算法生成的密文。 + ///
+ /// + /// string EncryptConnectionString(string connStr, string password) { + /// Aes aes = Aes.Create(); + /// byte[] ed = aes.Encrypt(password, connStr.ToByteArray(Encoding.UTF8)); + /// return ed.HexEncode(); + /// } + /// + /// string DecryptConnectionString(string hexStr, string password) { + /// byte[] d = Aes.Create().Decrypt(password, hexStr.HexDecode()); + /// return d.GetString(Encoding.UTF8); + /// } + /// + /// + /// 对于 AES、DES 和 3DES 算法,可以直接使用 AesToolDesTool 中定义的相关扩展方法。 + /// + /// + /// + public static class SymmetricTool + { + /// + /// 根据指定的对称加密算法,使用给定的密码对数据进行加密。 + /// + /// 对称加密算法 + /// 密码,不能为 null,可以是 string.Empty + /// 需要加密的数据,数据为 null,则加密结果为 null + /// 已加密的数据 + /// passwordnull + /// + /// 密码原文会通过 UTF-8 编码方式转换成字符数据用于加密。 + /// + public static byte[] Encrypt(this SymmetricAlgorithm me, string password, byte[] data) + { + if (password == null) + { + throw new ArgumentNullException("password"); + } + + if (data == null) + { + return null; + } + + byte[] keyData = Encoding.UTF8.GetBytes(password); + byte[] key = InternalTool.PadKey(keyData, me.KeySize / 8); + byte[] iv = InternalTool.PadKey(keyData, me.BlockSize / 8); + return InternalTool.Encrypt(me, data, iv, key); + } + + /// + /// 根据指定的对称加密算法,使用给定的密码对数据的一部分或全部进行加密。 + /// + /// 对称加密算法 + /// 密码,不能为 null,可以是 string.Empty + /// 需要加密的数据,数据不能为 null + /// 原数据起始位置 + /// 需要加密的原数据长度 + /// 已加密的数据 + /// passworddatanull + /// + /// 密码原文会通过 UTF-8 编码方式转换成字符数据用于加密。 + /// + public static byte[] Encrypt(this SymmetricAlgorithm me, string password, byte[] data, int start, int length) + { + if (password == null) + { + throw new ArgumentNullException("password"); + } + + if (data == null) + { + throw new ArgumentNullException("data"); + } + + byte[] keyData = Encoding.UTF8.GetBytes(password); + byte[] key = InternalTool.PadKey(keyData, me.KeySize / 8); + byte[] iv = InternalTool.PadKey(keyData, me.BlockSize / 8); + return InternalTool.Encrypt(me, data, start, length, iv, key); + } + + /// + /// 根据指定的对称加密算法,使用给定的密码对加密数据进行解密。 + /// + /// 对称加密算法 + /// 密码,不能为 null,可以是 string.Empty + /// 已加密的数据 + /// 解密后的数据 + /// passwordnull + /// + /// 密码原文会通过 UTF-8 编码方式转换成字符数据用于解密。 + /// + public static byte[] Decrypt(this SymmetricAlgorithm me, string password, byte[] encryptedData) + { + if (password == null) + { + throw new ArgumentNullException("password"); + } + + if (encryptedData == null) + { + return null; + } + + byte[] keyData = Encoding.UTF8.GetBytes(password); + byte[] key = InternalTool.PadKey(keyData, me.KeySize / 8); + byte[] iv = InternalTool.PadKey(keyData, me.BlockSize / 8); + return InternalTool.Decrypt(me, encryptedData, iv, key); + } + } +} diff --git a/Sdk/app.config b/Sdk/app.config new file mode 100644 index 0000000..6d05181 --- /dev/null +++ b/Sdk/app.config @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/Sdk/packages.config b/Sdk/packages.config new file mode 100644 index 0000000..b809fef --- /dev/null +++ b/Sdk/packages.config @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file -- Gitee From ec9de102b864a572ccc20aa5458e67a4ad3e8e99 Mon Sep 17 00:00:00 2001 From: jamesfancy Date: Sun, 26 May 2019 22:21:53 +0800 Subject: [PATCH 2/8] =?UTF-8?q?=E5=BF=BD=E7=95=A5=20packages?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 3e8a155..26bcd25 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,8 @@ ## ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore +packages + # User-specific files *.rsuser *.suo -- Gitee From 6604ea85c505f27dda7c611281f1f8734a20f655 Mon Sep 17 00:00:00 2001 From: jamesfancy Date: Sun, 26 May 2019 22:34:57 +0800 Subject: [PATCH 3/8] =?UTF-8?q?index=20=E4=B8=8D=E4=B8=BA=20null=EF=BC=8C?= =?UTF-8?q?=E9=BB=98=E8=AE=A4=E4=B8=BA=200?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sdk/Entity/KeywordPosition.Builder.cs | 2 +- Sdk/Entity/KeywordPosition.cs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Sdk/Entity/KeywordPosition.Builder.cs b/Sdk/Entity/KeywordPosition.Builder.cs index dd23944..d40c4c7 100644 --- a/Sdk/Entity/KeywordPosition.Builder.cs +++ b/Sdk/Entity/KeywordPosition.Builder.cs @@ -16,7 +16,7 @@ private string pages; private float? xOffset; private float? yOffset; - private int? index; + private int index; /// /// diff --git a/Sdk/Entity/KeywordPosition.cs b/Sdk/Entity/KeywordPosition.cs index f8ac741..b53cda2 100644 --- a/Sdk/Entity/KeywordPosition.cs +++ b/Sdk/Entity/KeywordPosition.cs @@ -28,8 +28,6 @@ /// public float? YOffset { get; set; } - public int? Index { get; set; } - - private KeywordPosition() { } + public int Index { get; set; } } } -- Gitee From f6c786bc7bd6f1d1350989b26b749b241db2ad6e Mon Sep 17 00:00:00 2001 From: jamesfancy Date: Sun, 26 May 2019 23:12:50 +0800 Subject: [PATCH 4/8] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BC=81=E4=B8=9A?= =?UTF-8?q?=E7=9B=B8=E5=85=B3=E6=95=B0=E6=8D=AE=E7=BB=93=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sdk/Entity/BaseFileData.cs | 8 +++ Sdk/Entity/IdCardImage.cs | 23 +++++++ Sdk/Entity/IdCardImageData.cs | 18 +++++ Sdk/Http/Enterprise/EnterpriseAgent.cs | 42 ++++++++++++ Sdk/Http/Enterprise/EnterpriseBankCardInfo.cs | 33 +++++++++ Sdk/Http/Enterprise/EnterpriseLegalPerson.cs | 37 ++++++++++ .../Enterprise/EnterpriseVerifyRequest.cs | 67 +++++++++++++++++++ .../Enterprise/EnterpriseVerifyResponse.cs | 6 ++ Sdk/Http/PersonVerifyResponse.cs | 10 +++ Sdk/Http/StartEnvelopeResponse.cs | 13 ++++ Sdk/Sdk.csproj | 10 +++ 11 files changed, 267 insertions(+) create mode 100644 Sdk/Entity/BaseFileData.cs create mode 100644 Sdk/Entity/IdCardImage.cs create mode 100644 Sdk/Entity/IdCardImageData.cs create mode 100644 Sdk/Http/Enterprise/EnterpriseAgent.cs create mode 100644 Sdk/Http/Enterprise/EnterpriseBankCardInfo.cs create mode 100644 Sdk/Http/Enterprise/EnterpriseLegalPerson.cs create mode 100644 Sdk/Http/Enterprise/EnterpriseVerifyRequest.cs create mode 100644 Sdk/Http/Enterprise/EnterpriseVerifyResponse.cs create mode 100644 Sdk/Http/PersonVerifyResponse.cs create mode 100644 Sdk/Http/StartEnvelopeResponse.cs diff --git a/Sdk/Entity/BaseFileData.cs b/Sdk/Entity/BaseFileData.cs new file mode 100644 index 0000000..47f9b24 --- /dev/null +++ b/Sdk/Entity/BaseFileData.cs @@ -0,0 +1,8 @@ +namespace Signit.Sdk.Entity +{ + public class BaseFileData + { + public string Url { get; set; } + public string Base64 { get; set; } + } +} diff --git a/Sdk/Entity/IdCardImage.cs b/Sdk/Entity/IdCardImage.cs new file mode 100644 index 0000000..ccb817b --- /dev/null +++ b/Sdk/Entity/IdCardImage.cs @@ -0,0 +1,23 @@ +namespace Signit.Sdk.Entity +{ + /// + /// 证件图像数据. + /// + public class IdCardImage + { + /// + /// 图像名称. + /// + public string ImageName { get; set; } + + /// + /// 图像标识码. + /// + public string ImageCode { get; set; } + + /// + /// 图像标识码. + /// + public IdCardImageData ImageData { get; set; } + } +} \ No newline at end of file diff --git a/Sdk/Entity/IdCardImageData.cs b/Sdk/Entity/IdCardImageData.cs new file mode 100644 index 0000000..359db93 --- /dev/null +++ b/Sdk/Entity/IdCardImageData.cs @@ -0,0 +1,18 @@ +namespace Signit.Sdk.Entity +{ + /** + * 证件图片数据. + * + * @since 2.0.0 + */ + public class IdCardImageData : BaseFileData + { + /** + * 证件的文件全局唯一ID. + * + * @since 2.0.0 + */ + public string FileWsid { get; set; } + + } +} \ No newline at end of file diff --git a/Sdk/Http/Enterprise/EnterpriseAgent.cs b/Sdk/Http/Enterprise/EnterpriseAgent.cs new file mode 100644 index 0000000..18887bb --- /dev/null +++ b/Sdk/Http/Enterprise/EnterpriseAgent.cs @@ -0,0 +1,42 @@ +using Signit.Sdk.Entity; +using Signit.Sdk.Types; +using System.Collections.Generic; + +namespace Signit.Sdk.Http.Enterprise +{ + /// + /// 经办人信息 + /// + public class EnterpriseAgent + { + /// + /// 委托书照片信息. + /// + public IdCardImage TrustInstrumentImage { get; set; } + + /// + /// 待认证的用户姓名. + /// + public string Name { get; set; } + + /// + /// 待认证的用户手机号. + /// + public string Phone { get; set; } + + /// + /// 待认证的用户证件类型. + /// + public IdCardType IdCardType { get; set; } + + /// + /// 待认证的用户证件号. + /// + public string IdCardNo { get; set; } + + /// + /// 待认证的用户证件照片数组. + /// + public IList IdCardImages { get; set; } + } +} \ No newline at end of file diff --git a/Sdk/Http/Enterprise/EnterpriseBankCardInfo.cs b/Sdk/Http/Enterprise/EnterpriseBankCardInfo.cs new file mode 100644 index 0000000..1fe9d02 --- /dev/null +++ b/Sdk/Http/Enterprise/EnterpriseBankCardInfo.cs @@ -0,0 +1,33 @@ +namespace Signit.Sdk.Http.Enterprise +{ + /// + /// 对公银行账户信息 + /// + public class EnterpriseBankCardInfo + { + /// + /// 银行(如:中国农业银行等). + /// + public string Bank { get; set; } + + /// + /// 银行支行. + /// + public string BankBranch { get; set; } + + /// + /// 银行卡号. + /// + public string BankCardNo { get; set; } + + /// + /// 地区(省,市,区/县). + /// + public string Area { get; set; } + + /// + /// 联行号. + /// + public string UnionBankNo { get; set; } + } +} diff --git a/Sdk/Http/Enterprise/EnterpriseLegalPerson.cs b/Sdk/Http/Enterprise/EnterpriseLegalPerson.cs new file mode 100644 index 0000000..24a6338 --- /dev/null +++ b/Sdk/Http/Enterprise/EnterpriseLegalPerson.cs @@ -0,0 +1,37 @@ +using Signit.Sdk.Entity; +using Signit.Sdk.Types; +using System.Collections.Generic; + +namespace Signit.Sdk.Http.Enterprise +{ + /// + /// 法人信息 + /// + public class EnterpriseLegalPerson + { + /// + /// 待认证的用户姓名. + /// + public string Name { get; set; } + + /// + /// 待认证的用户手机号. + /// + public string Phone { get; set; } + + /// + /// 待认证的用户证件类型. + /// + public IdCardType IdCardType { get; set; } + + /// + /// 待认证的用户证件号. + /// + public string IdCardNo { get; set; } + + /// + /// 待认证的用户证件照片数组. + /// + public IList IdCardImages { get; set; } + } +} diff --git a/Sdk/Http/Enterprise/EnterpriseVerifyRequest.cs b/Sdk/Http/Enterprise/EnterpriseVerifyRequest.cs new file mode 100644 index 0000000..0745b3e --- /dev/null +++ b/Sdk/Http/Enterprise/EnterpriseVerifyRequest.cs @@ -0,0 +1,67 @@ +using Signit.Sdk.Entity; +using Signit.Sdk.Types; +using System.Collections.Generic; + +namespace Signit.Sdk.Http.Enterprise +{ + /// + /// 企业实名认证请求数据结构. + /// + public class EnterpriseVerifyRequest : AbstractSignitRequest + { + /// + /// 待认证企业名称. + /// + public string Name { get; set; } + + /// + /// 经办人信息. + /// + public EnterpriseAgent Agent { get; set; } + + /// + /// 法人信息. + /// + public EnterpriseLegalPerson LegalPerson { get; set; } + + /// + /// 统一社会信用代码. + /// + public string UnifiedSocialCode { get; set; } + + /// + /// 营业执照照片信息. + /// + public IdCardImage BusinessLicenceImage { get; set; } + + /// + /// 组织机构代码(已由“统一社会信用代码”替换). + /// + public string OrgCode { get; set; } + + /// + /// 组织机构代码证照片信息. + /// + public IdCardImage OrgImage { get; set; } + + /// + /// 工商注册号(已由“统一社会信用代码”替换). + /// + public string RegistCode { get; set; } + + /// + /// LEGAL_PERSON-法人认证,AGENT-经办人认证. + /// + public EnterpriseAuthType AuthType { get; set; } + + /// + /// 企业对公银行信息. + /// + public EnterpriseBankCardInfo BankCardInfo { get; set; } + + /// + /// 额外认证所需照片信息数组. + /// + public IList ExtraAuthImages { get; set; } + } +} \ No newline at end of file diff --git a/Sdk/Http/Enterprise/EnterpriseVerifyResponse.cs b/Sdk/Http/Enterprise/EnterpriseVerifyResponse.cs new file mode 100644 index 0000000..ef2f992 --- /dev/null +++ b/Sdk/Http/Enterprise/EnterpriseVerifyResponse.cs @@ -0,0 +1,6 @@ +namespace Signit.Sdk.Http.Enterprise +{ + public class EnterpriseVerifyResponse : AbstractSignitResponse + { + } +} diff --git a/Sdk/Http/PersonVerifyResponse.cs b/Sdk/Http/PersonVerifyResponse.cs new file mode 100644 index 0000000..dfd0d7a --- /dev/null +++ b/Sdk/Http/PersonVerifyResponse.cs @@ -0,0 +1,10 @@ +namespace Signit.Sdk.Http +{ + /// + /// 个人实名认证响应. + /// + public class PersonVerifyResponse : AbstractSignitResponse + { + } + +} diff --git a/Sdk/Http/StartEnvelopeResponse.cs b/Sdk/Http/StartEnvelopeResponse.cs new file mode 100644 index 0000000..e596f16 --- /dev/null +++ b/Sdk/Http/StartEnvelopeResponse.cs @@ -0,0 +1,13 @@ +namespace Signit.Sdk.Http +{ + /** + * 启动信封响应 + * + * @since 1.0.2 + */ + public class StartEnvelopeResponse : AbstractSignitResponse + { + + } + +} diff --git a/Sdk/Sdk.csproj b/Sdk/Sdk.csproj index 0409340..b42c453 100644 --- a/Sdk/Sdk.csproj +++ b/Sdk/Sdk.csproj @@ -73,12 +73,22 @@ + + + + + + + + + + -- Gitee From 16bf1453ad11561b8229906632c6f2bcc536bf0b Mon Sep 17 00:00:00 2001 From: jamesfancy Date: Sun, 26 May 2019 23:44:32 +0800 Subject: [PATCH 5/8] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BF=A1=E5=B0=81?= =?UTF-8?q?=E3=80=81=E5=8F=91=E9=80=81=E8=80=85=E3=80=81=E6=8E=A5=E6=94=B6?= =?UTF-8?q?=E8=80=85=E5=8F=8A=E7=9B=B8=E5=85=B3=E6=95=B0=E6=8D=AE=E7=BB=93?= =?UTF-8?q?=E6=9E=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sdk/Entity/CertData.cs | 13 ++ Sdk/Entity/Contact.cs | 18 +++ Sdk/Entity/InitialValue.cs | 73 +++++++++++ Sdk/Entity/PresetForm.cs | 113 ++++++++++++++++++ Sdk/Entity/Receiver.cs | 85 +++++++++++++ Sdk/Entity/Sender.cs | 37 ++++++ Sdk/Entity/WriteData.cs | 18 +++ Sdk/Http/Envelope/EnvelopeBasicInfo.cs | 37 ++++++ Sdk/Http/Envelope/EnvelopeContentInfo.cs | 15 +++ Sdk/Http/Envelope/EnvelopeFile.cs | 55 +++++++++ Sdk/Http/Envelope/EnvelopeParticipantInfo.cs | 6 + Sdk/Http/Envelope/StartEnvelopeRequest.cs | 23 ++++ .../{ => Envelope}/StartEnvelopeResponse.cs | 10 +- Sdk/Http/ErrorResponse.cs | 11 ++ Sdk/Http/SignatureResponse.cs | 4 - Sdk/Sdk.csproj | 15 ++- 16 files changed, 522 insertions(+), 11 deletions(-) create mode 100644 Sdk/Entity/CertData.cs create mode 100644 Sdk/Entity/Contact.cs create mode 100644 Sdk/Entity/InitialValue.cs create mode 100644 Sdk/Entity/PresetForm.cs create mode 100644 Sdk/Entity/Receiver.cs create mode 100644 Sdk/Entity/Sender.cs create mode 100644 Sdk/Entity/WriteData.cs create mode 100644 Sdk/Http/Envelope/EnvelopeBasicInfo.cs create mode 100644 Sdk/Http/Envelope/EnvelopeContentInfo.cs create mode 100644 Sdk/Http/Envelope/EnvelopeFile.cs create mode 100644 Sdk/Http/Envelope/EnvelopeParticipantInfo.cs create mode 100644 Sdk/Http/Envelope/StartEnvelopeRequest.cs rename Sdk/Http/{ => Envelope}/StartEnvelopeResponse.cs (44%) create mode 100644 Sdk/Http/ErrorResponse.cs diff --git a/Sdk/Entity/CertData.cs b/Sdk/Entity/CertData.cs new file mode 100644 index 0000000..44c70c4 --- /dev/null +++ b/Sdk/Entity/CertData.cs @@ -0,0 +1,13 @@ +namespace Signit.Sdk.Entity +{ + /** + * 证书数据. 支持base64、URL、证书数据全局唯一ID中对的任意一种方式. + */ + public class CertData : BaseFileData + { + /** + * 证书数据的全局唯一ID. + */ + public string Wsid { get; set; } + } +} diff --git a/Sdk/Entity/Contact.cs b/Sdk/Entity/Contact.cs new file mode 100644 index 0000000..3009d44 --- /dev/null +++ b/Sdk/Entity/Contact.cs @@ -0,0 +1,18 @@ +namespace Signit.Sdk.Entity +{ + /** + * 用户联系方式. 包含邮箱和手机号码. + */ + public class Contact + { + /** + * 电子邮箱. + */ + public string Email { get; set; } + + /** + * 手机号码. + */ + public string Phone { get; set; } + } +} \ No newline at end of file diff --git a/Sdk/Entity/InitialValue.cs b/Sdk/Entity/InitialValue.cs new file mode 100644 index 0000000..e8bf1cc --- /dev/null +++ b/Sdk/Entity/InitialValue.cs @@ -0,0 +1,73 @@ +using Signit.Sdk.Types; + +namespace Signit.Sdk.Entity +{ + /** + * 签名初始化数据。包含印章数据、手写数据、证书数据、证书签名证书秘钥访问口令、证书类型、 渲染模式、签名地理位置、联系方式、签名是否锁定、签名原因。 + * 印章数据、手写数据仅一个不为空的有效。 + */ + public class InitialValue + { + /** + * 印章数据. + */ + public SealData SealData { get; set; } + + /** + * 手写签名数据. + */ + public WriteData WriteData { get; set; } + + /** + * 证书数据. + */ + public CertData CertData { get; set; } + + /** + * 证书签名证书密钥访问口令. + */ + public string CertPassin { get; set; } + + /** + * 证书类型. + * 对应枚举:CertType + */ + public CertType CertType { get; set; } + + /** + * 渲染模式. 对应枚举: + * 对应枚举:RenderMode + */ + public RenderMode RenderingMode { get; set; } = RenderMode.GRAPHIC; + + /** + * 签名地理位置. + */ + public string Location { get; set; } + + /** + * 联系方式. + */ + public string Contact { get; set; } + + /** + * 签名是否锁定. + */ + public bool Locked { get; set; } + + /** + * 签名原因. + */ + public string Reason { get; set; } + + /** + * 文本框文本内容 + */ + public string TextContent { get; set; } + + /** + * 二维码内容字符串. + */ + public string QrcodeContent { get; set; } + } +} \ No newline at end of file diff --git a/Sdk/Entity/PresetForm.cs b/Sdk/Entity/PresetForm.cs new file mode 100644 index 0000000..6560e71 --- /dev/null +++ b/Sdk/Entity/PresetForm.cs @@ -0,0 +1,113 @@ +using Signit.Sdk.Types; + +namespace Signit.Sdk.Entity +{ + /** + * 预设表单信息。 包括表单类型、印章/手写签名名字、所签署文件ID、签署表单坐标位置、表单是否必填、表单缩放比例 + * 、签名初始化值、表单是否允许修正、当前表单的自定义标识、是否是纠正创建的表单 + */ + public class PresetForm + { + /** + * 表单类型。 对应枚举:FormType + */ + public FormType FormType { get; set; } + + /** + * 当前表单要设置到的文件上,引用contentInfo.files[].id值. + */ + public string FileId { get; set; } + + /** + * 签署表单坐标位置. + */ + public SignerPosition Position { get; set; } + + /** + * 表单缩放比例. + */ + public float scale { get; set; } = 1.0f; + + /** + * 签名初始化值. + */ + public InitialValue InitialValue { get; set; } + + /** + * 表单是否允许修正. + */ + public bool revisable { get; set; } + + /** + * 当前表单的自定义标识. + */ + public string TagId { get; set; } + + /** + * 是否是纠正创建的表单. + */ + public bool corrected { get; set; } + + /** + * 跨页表单距离页面边缘边距,单位px + * @since 2.1.0 + */ + public float Margin { get; set; } + + /** + * 防伪标记中心按顺时针方向,沿页面边缘偏移的量 + * @since 2.1.0 + */ + public float Offset { get; set; } + + /** + * 签署完成后证书所在的页数,若为空字符串或null,则等价于为均为无证书骑缝章。支持格式形如:'first','last','all','odd','even','1','1-5','1,3,4,7,8',... + * @since 2.1.0 + */ + public string CertPages { get; set; } + + /** + * 单位图片所占像素(当且仅当每页宽度不足1px时有效). + * @since 2.1.0 + */ + public int Pixel { get; set; } + + /** + * 单页数是否加盖骑缝章 + * @since 2.1.0 + */ + public bool SinglePageMark { get; set; } + + /** + * 是否重设骑缝章尺寸 + * @since 2.1.0 + */ + public bool Resizable { get; set; } + + /** + * 重设骑缝章尺寸宽度.单位px.当resizablee时该值的设置才有效=tru + * @since 2.1.0 + */ + public float ResizeWidth { get; set; } + + /** + * 重设骑缝章尺寸高度.单位px.当resizablee时该值的设置才有效=tru + * @since 2.1.0 + */ + public float ResizeHeight { get; set; } + + + /** + * 二维码宽,单位px. + * @since 2.1.0 + */ + public float Width { get; set; } + + + /** + * 二维码高,单位px. + * @since 2.1.0 + */ + public float Height { get; set; } + } +} \ No newline at end of file diff --git a/Sdk/Entity/Receiver.cs b/Sdk/Entity/Receiver.cs new file mode 100644 index 0000000..1807edf --- /dev/null +++ b/Sdk/Entity/Receiver.cs @@ -0,0 +1,85 @@ +using Signit.Sdk.Types; +using System.Collections.Generic; + +namespace Signit.Sdk.Entity +{ + /** + * 接收方信息。 包含接收方名字、接收方联系方式、安全等级、接收方类型、 接收方是否必须预分配表单域、设置接收方私人信息、接收方处理顺序、 + * 签署认证等级、接收方所在企业名称、信封自定义元数据信息、预设表单信息. + */ + public class Receiver + { + /** + * 接收方名字. + */ + public string Name { get; set; } + /** + * 接收方联系方式. + */ + public Contact Contact { get; set; } + /** + * 安全等级. + *

+ * 对应枚举:SecureLevel + * + */ + public SecureLevel SecureLevel { get; set; } + /** + * 接收方类型。 接收方类型:ReceiverType + * + */ + public ReceiverType Type { get; set; } + /** + * 接收方是否必须预分配表单域. + */ + public bool needForm { get; set; } + /** + * 设置接收方私人信息. + */ + public string AssignedMessage { get; set; } + /** + * 接收方处理顺序. + */ + public int AssignedSequence { get; set; } + + /** + * 接收方所在企业名称. + */ + public string EnterpriseName { get; set; } + /** + * 信封自定义元数据信息. + */ + public string Metadata { get; set; } + /** + * 预设表单信息. + */ + public IList PresetForms { get; set; } + + public EnvelopeRoleType RoleType { get; set; } + + /** + * 流程完成后删除当前参与者的信封。 默认:false + * + */ + public bool DeleteCompletedEnvelope { get; set; } + /** + * 参与者处理表单各种模式的枚举 + */ + public ParticipantHandleMode HandleMode { get; set; } + + public IList SelectedAuthTypes { get; set; } + + /** + * 启用嵌入模式,调用方系统中直接嵌入易企签WEB流程时设置为true,签署流程消息只会通过webhook事件消息方式通知,用户在易企签平台设置的短信/邮件等消息将自动屏蔽。非必填,默认值:false. + * @since 2.1.0 + */ + public bool EnableEmbeddedMode { get; set; } + + /** + * 签署接收方用户在调用方系统的唯一标识.
+ * enableEmbeddedMode为false时,非必填;当enableEmbeddedMode为true时,则必填。默认:null + * @since 2.1.0 + */ + public string ClientId { get; set; } + } +} diff --git a/Sdk/Entity/Sender.cs b/Sdk/Entity/Sender.cs new file mode 100644 index 0000000..7b85d67 --- /dev/null +++ b/Sdk/Entity/Sender.cs @@ -0,0 +1,37 @@ +namespace Signit.Sdk.Entity +{ + /** + * 发送方信息。 包含姓名和联系方式. + */ + public class Sender + { + /** + * 发送者名字. + */ + public string Name { get; set; } + + /** + * 发送者联系方式. + */ + + public Contact Contact { get; set; } + /** + * 流程完成后删除当前参与者的信封.
+ * 默认:false + * + */ + public bool DeleteCompletedEnvelope { get; set; } + + /** + * 启用嵌入模式,调用方系统中直接嵌入易企签WEB流程时设置为true,签署流程消息只会通过webhook事件消息方式通知,用户在易企签平台设置的短信/邮件等消息将自动屏蔽。非必填,默认值:false. + * @since 2.1.0 + */ + public bool EnableEmbeddedMode { get; set; } + + /** + * 签署发送方用户在调用方系统的唯一标识.
+ * enableEmbeddedMode为false时,非必填;当enableEmbeddedMode为true时,则必填。默认:null + */ + public string ClientId { get; set; } + } +} diff --git a/Sdk/Entity/WriteData.cs b/Sdk/Entity/WriteData.cs new file mode 100644 index 0000000..660ec9d --- /dev/null +++ b/Sdk/Entity/WriteData.cs @@ -0,0 +1,18 @@ +namespace Signit.Sdk.Entity +{ + /** + * 手写签名数据. 支持URL/Base64/签名全局唯一ID/签名名字,代表签名数据. + */ + public class WriteData : BaseFileData + { + /** + * 手写签名全局唯一ID. + */ + public string Wsid { get; set; } + + /** + * 手写签名名子. + */ + public string Name { get; set; } + } +} diff --git a/Sdk/Http/Envelope/EnvelopeBasicInfo.cs b/Sdk/Http/Envelope/EnvelopeBasicInfo.cs new file mode 100644 index 0000000..4ee4af0 --- /dev/null +++ b/Sdk/Http/Envelope/EnvelopeBasicInfo.cs @@ -0,0 +1,37 @@ +using Signit.Sdk.Types; + +namespace Signit.Sdk.Http.Envelope +{ + /** + * 信封基本信息. 包含信封标题、信封主题、信封类型、信封认证等级、自定义元数据信息. + */ + public class EnvelopeBasicInfo + { + /** + * 信封标题. + */ + public string Title { get; set; } + + /** + * 信封主题. + */ + public string Subject { get; set; } + + /** + * 信封类型. + * 对应枚举:EnvelopeType + */ + public EnvelopeType Type { get; set; } + + /** + * 信封认证等级. + * 对应枚举:AuthLevel + */ + public AuthLevel AuthLevel { get; set; } + + /** + * 自定义元数据信息. + */ + public string Metadata { get; set; } + } +} \ No newline at end of file diff --git a/Sdk/Http/Envelope/EnvelopeContentInfo.cs b/Sdk/Http/Envelope/EnvelopeContentInfo.cs new file mode 100644 index 0000000..84da7d0 --- /dev/null +++ b/Sdk/Http/Envelope/EnvelopeContentInfo.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; + +namespace Signit.Sdk.Http.Envelope +{ + /** + * 签署文件内容 + */ + public class EnvelopeContentInfo + { + /** + * 签署文件详细信息列表. + */ + public IList Files { get; set; } + } +} \ No newline at end of file diff --git a/Sdk/Http/Envelope/EnvelopeFile.cs b/Sdk/Http/Envelope/EnvelopeFile.cs new file mode 100644 index 0000000..5641bce --- /dev/null +++ b/Sdk/Http/Envelope/EnvelopeFile.cs @@ -0,0 +1,55 @@ +using Signit.Sdk.Entity; +using Signit.Sdk.Types; + +namespace Signit.Sdk.Http.Envelope +{ + /// + /// 签署文件详细信息。包含:待签文件i唯一标识ID、该文件排列顺序、签署文件的数据、 + /// 文件名、文件拥有者访问口令、文件类型、文件是否作为附件、自定义元数据信息 + /// + public class EnvelopeFile + { + /// + /// 待签文件唯一标识ID. + /// + public string Id { get; set; } + + /// + /// 该文件排列顺序. + /// + public int Sequence { get; set; } + + /// + /// 签署文件的数据. + /// + public BaseFileData Data { get; set; } + + /// + /// 文件名. + /// + public string FileName { get; set; } + + /// + /// 文件拥有者访问口令. + /// + public string FileOverPassin { get; set; } + + /// + /// 文件类型. + /// 对应枚举:FileType + /// + public FileType ContentType { get; set; } + + /// + /// 文件是否作为附件. + /// 默认为false + /// + public bool IsAttached { get; set; } + + /// + /// 自定义元数据信息. + /// + public string Metadata { get; set; } + + } +} \ No newline at end of file diff --git a/Sdk/Http/Envelope/EnvelopeParticipantInfo.cs b/Sdk/Http/Envelope/EnvelopeParticipantInfo.cs new file mode 100644 index 0000000..14ee3d4 --- /dev/null +++ b/Sdk/Http/Envelope/EnvelopeParticipantInfo.cs @@ -0,0 +1,6 @@ +namespace Signit.Sdk.Http.Envelope +{ + public class EnvelopeParticipantInfo + { + } +} \ No newline at end of file diff --git a/Sdk/Http/Envelope/StartEnvelopeRequest.cs b/Sdk/Http/Envelope/StartEnvelopeRequest.cs new file mode 100644 index 0000000..c40c370 --- /dev/null +++ b/Sdk/Http/Envelope/StartEnvelopeRequest.cs @@ -0,0 +1,23 @@ +namespace Signit.Sdk.Http.Envelope +{ + /// + /// 信封启动服务请求体. 包含信封基本信息、信封流程中的签署文件内容、签署参与者信息、自定义跳转URL、自定义可接受数据类型、自定义标识. + /// + class StartEnvelopeRequest : AbstractSignitRequest + { + /// + /// 信封基本信息. + /// + public EnvelopeBasicInfo Basicinfo {get;set;} + + /// + /// 信封流程中的签署文件内容. + /// + public EnvelopeContentInfo ContentInfo {get;set;} + + /// + /// 签署参与者信息. + /// + public EnvelopeParticipantInfo ParticipantInfo {get;set;} + } +} diff --git a/Sdk/Http/StartEnvelopeResponse.cs b/Sdk/Http/Envelope/StartEnvelopeResponse.cs similarity index 44% rename from Sdk/Http/StartEnvelopeResponse.cs rename to Sdk/Http/Envelope/StartEnvelopeResponse.cs index e596f16..d9c55a1 100644 --- a/Sdk/Http/StartEnvelopeResponse.cs +++ b/Sdk/Http/Envelope/StartEnvelopeResponse.cs @@ -1,10 +1,8 @@ -namespace Signit.Sdk.Http +namespace Signit.Sdk.Http.Envelope { - /** - * 启动信封响应 - * - * @since 1.0.2 - */ + /// + /// 启动信封响应 + /// public class StartEnvelopeResponse : AbstractSignitResponse { diff --git a/Sdk/Http/ErrorResponse.cs b/Sdk/Http/ErrorResponse.cs new file mode 100644 index 0000000..4aa9c7d --- /dev/null +++ b/Sdk/Http/ErrorResponse.cs @@ -0,0 +1,11 @@ +namespace Signit.Sdk.Http +{ + public class ErrorResponse + { + public string Code { get; set; } + public string ErrorWsid { get; set; } + public string UserMessage { get; set; } + public string DeveloperMessage { get; set; } + public string MoreInfo { get; set; } + } +} diff --git a/Sdk/Http/SignatureResponse.cs b/Sdk/Http/SignatureResponse.cs index 80be17e..5be40c9 100644 --- a/Sdk/Http/SignatureResponse.cs +++ b/Sdk/Http/SignatureResponse.cs @@ -2,9 +2,5 @@ { public class SignatureResponse : AbstractSignitResponse { - public string ErrorWsid { get; set; } - public string UserMessage { get; set; } - public string DeveloperMessage { get; set; } - public string MemberInfo { get; set; } } } diff --git a/Sdk/Sdk.csproj b/Sdk/Sdk.csproj index b42c453..5aa5241 100644 --- a/Sdk/Sdk.csproj +++ b/Sdk/Sdk.csproj @@ -74,9 +74,16 @@
+ + + + + + + @@ -84,11 +91,17 @@ + + + + + + - + -- Gitee From 8fc93faa1bf843a4bd8869bf6989d8e0f8ffc885 Mon Sep 17 00:00:00 2001 From: jamesfancy Date: Sun, 26 May 2019 23:51:54 +0800 Subject: [PATCH 6/8] =?UTF-8?q?=E5=8E=BB=E6=8E=89=20Builder=EF=BC=8CC#=20?= =?UTF-8?q?=E5=88=9D=E5=A7=8B=E5=8C=96=E6=A8=A1=E5=BC=8F=E6=9B=B4=E5=A5=BD?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sdk/Entity/KeywordPosition.Builder.cs | 223 ------------------------ Sdk/Entity/KeywordPosition.cs | 7 +- Sdk/Entity/RectanglePosition.Builder.cs | 115 ------------ Sdk/Entity/RectanglePosition.cs | 7 +- Sdk/Entity/SealData.Builder.cs | 67 ------- Sdk/Entity/SealData.cs | 4 +- Sdk/Entity/Signer.Builder.cs | 48 ----- Sdk/Entity/Signer.cs | 7 +- Sdk/Entity/SignerData.Builder.cs | 32 ---- Sdk/Entity/SignerData.cs | 4 +- Sdk/Entity/SignerInfo.Builder.cs | 64 ------- Sdk/Entity/SignerInfo.cs | 4 +- Sdk/Entity/SignerPosition.cs | 32 ---- Sdk/Http/AbstractSignitResponse.cs | 4 + Sdk/Http/SignatureRequest.Builder.cs | 59 ------- Sdk/Http/SignatureRequest.cs | 4 +- Sdk/Http/Webhook/ParticipantHandling.cs | 6 - Sdk/Http/Webhook/WebhookResponse.cs | 2 +- Sdk/Sdk.csproj | 7 - 19 files changed, 12 insertions(+), 684 deletions(-) delete mode 100644 Sdk/Entity/KeywordPosition.Builder.cs delete mode 100644 Sdk/Entity/RectanglePosition.Builder.cs delete mode 100644 Sdk/Entity/SealData.Builder.cs delete mode 100644 Sdk/Entity/Signer.Builder.cs delete mode 100644 Sdk/Entity/SignerData.Builder.cs delete mode 100644 Sdk/Entity/SignerInfo.Builder.cs delete mode 100644 Sdk/Http/SignatureRequest.Builder.cs diff --git a/Sdk/Entity/KeywordPosition.Builder.cs b/Sdk/Entity/KeywordPosition.Builder.cs deleted file mode 100644 index d40c4c7..0000000 --- a/Sdk/Entity/KeywordPosition.Builder.cs +++ /dev/null @@ -1,223 +0,0 @@ -namespace Signit.Sdk.Entity -{ - public partial class KeywordPosition - { - public class Builder : KeywordPosition - { - private float? width; - private float? relativeWidthRatio; - private float? height; - private float? relativeHeightRatio; - private Direction direction; - private float? offset; - private float? relativeOffsetRatio; - private string keyword; - private float? scale; - private string pages; - private float? xOffset; - private float? yOffset; - private int index; - - /// - /// - /// - /// - /// 签名矩形框的宽度(默认为关键字宽度,单位:pt); - /// 在易企签系统中,以左上角为坐标原点,横向为x轴,以纵向为y轴; - /// 宽度也即是签名矩形框在x方向上大小 - /// - /// 利用关键字定位签名矩形框所在位置的数据对象建造器 - public Builder WithWidth(float width) - { - this.width = width; - return this; - } - - /** - * - * @param relativeWidthRatio - * 签名矩形框宽度相对于关键字宽度的比率,默认为1.0;例:关键字宽度为50pt,relativeWidthRatio=2,那么签名矩形框宽度即为100pt;宽度更多介绍详见{@link KeywordPositionBuilder#WithWidth(float)} - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 1.0.0 - */ - public Builder WithRelativeWidthRatio(float relativeWidthRatio) - { - this.relativeWidthRatio = relativeWidthRatio; - return this; - } - - /** - * - * @param height - * 签名矩形框的高度(默认为关键字高度,单位:pt);在易企签系统中,以左上角为坐标原点,横向为x轴,以纵向为y轴;高度也即是签名矩形框在y方向上大小 - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 1.0.0 - */ - public Builder WithHeight(float height) - { - this.height = height; - return this; - } - - /** - * - * @param relativeHeightRatio - * 签名矩形框高度相对于关键字高度的比率,默认为1.0;例:关键字高度为50pt,relativeHeightRatio=2,那么签名矩形框高度即为100pt;高度更多介绍详见{@link KeywordPositionBuilder#WithHeight(float)} - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 1.0.0 - */ - public Builder WithRelativeHeightRatio(float relativeHeightRatio) - { - this.relativeHeightRatio = relativeHeightRatio; - return this; - } - - /** - * - * @param direction - * 偏移方向,即签名矩形框相对于关键字的方向(TOP,BOTTOM,LEFT,RIGHT,CENTER),默认为RIGHT;例:direction=TOP,则签名矩形框在关键字的上方 - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 1.0.0 - */ - public Builder WithDirection(Direction direction) - { - this.direction = direction; - return this; - } - - /** - * - * @param offset - * {@code 偏移量(以签名矩形框中心为0点)配合direction使用,默认为0,单位为pt;例:经过关键字初步定位,以及设置签名矩形框的宽高后,签名矩形框位置为:(100,100)(左上角顶点)->(200,200)(右下角顶点) - * ,direction=RIGHT,offset=20,那么进行偏移后,签名矩形框的坐标是 - * (120,100)(左上角顶点)->(220,200)(右下角顶点)} - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 1.0.0 - */ - public Builder WithOffset(float offset) - { - this.offset = offset; - return this; - } - - /** - * - * @param relativeOffsetRatio - * 在偏移方向上,相对于该方向签名矩形框大小的比率,默认为0。例:假设签名矩形框的宽度是50pt,高度为30pt,relativeOffsetRatio=2.0,direction=RIGHT,那么意味着最终偏移量为offset=100pt;同理,如果签名矩形框 - * 宽度为50,高度为30,relativeOffsetRatio=1.3,direction=TOP,那么最终offset=39;计算后的offset使用方法详见{@link KeywordPositionBuilder#WithOffset} - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 1.0.0 - */ - public Builder WithRelativeOffsetRatio(float relativeOffsetRatio) - { - this.relativeOffsetRatio = relativeOffsetRatio; - return this; - } - - /** - * - * @param keyword - * 用于定位的关键字,例如:甲方(签名)。需要注意:用于定位的关键字在文档通过wps或者adobe - * reader等pdf阅读器打开后,需要能够通过鼠标圈选。例如:如果签署文档是通过图片转换后的pdf,就无法在签署文档中 - * 获取关键字位置。 - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 1.0.0 - */ - public Builder WithKeyword(string keyword) - { - this.keyword = keyword; - return this; - } - - /** - * - * @param scale - * {@code 根据关键字定位后的签名矩形框缩放比例,默认为1.0。例如根据关键字定位后,签名矩形框位置为(100,100)->(200,200),scale为2.0,那么签名矩形框位置将是(50,50)->(250,250)} - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 1.0.0 - */ - public Builder WithScale(float scale) - { - this.scale = scale; - return this; - } - - /** - * - * @param pages - * 关键字需要搜索的页数,默认为"all"。在文档中搜索关键字时,只在指定页中搜索。支持"all","first","last","odd","even","1","1-5","1,2,3,5","(0,5]","[1,5]","(0,5)"这些页数的表示方式 - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 1.0.0 - */ - public Builder WithPages(string pages) - { - this.pages = pages; - return this; - } - - /** - * - * @param xOffset - * 签名矩形框在x轴额外偏移量,单位为pt,默认为0 - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 2.0.0 - */ - public Builder WithXOffset(float xOffset) - { - this.xOffset = xOffset; - return this; - } - - /** - * - * @param yOffset - * 签名矩形框在y轴额外偏移量,单位为pt,默认为0 - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 2.0.0 - */ - public Builder WithYOffset(float yOffset) - { - this.yOffset = yOffset; - return this; - } - - /** - * - * @param index - * 如果关键字所在页数存在多个相同关键字,则需要指定关键字的索引(关键字从索引从0开始),即指定使用第几个关键字。默认为0 - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link KeywordPositionBuilder} - * @since 2.0.0 - */ - public Builder WithIndex(int index) - { - this.index = index; - return this; - } - - /** - * - * @return 利用关键字定位签名矩形框所在位置的数据对象 {@link KeywordPosition} - * @since 1.0.0 - */ - public KeywordPosition Build() - { - return new KeywordPosition - { - Width = width, - RelativeWidthRatio = relativeWidthRatio, - Height = height, - RelativeHeightRatio = relativeHeightRatio, - Direction = direction, - Offset = offset, - RelativeOffsetRatio = relativeOffsetRatio, - Keyword = keyword, - Scale = scale, - Pages = pages, - XOffset = xOffset, - YOffset = yOffset, - Index = index - }; - } - } - } -} diff --git a/Sdk/Entity/KeywordPosition.cs b/Sdk/Entity/KeywordPosition.cs index b53cda2..8c7e6a4 100644 --- a/Sdk/Entity/KeywordPosition.cs +++ b/Sdk/Entity/KeywordPosition.cs @@ -1,12 +1,7 @@ namespace Signit.Sdk.Entity { - public partial class KeywordPosition + public class KeywordPosition { - public static Builder CreateBuilder() - { - return new Builder(); - } - public float? Width { get; set; } public float? RelativeWidthRatio { get; set; } public float? Height { get; set; } diff --git a/Sdk/Entity/RectanglePosition.Builder.cs b/Sdk/Entity/RectanglePosition.Builder.cs deleted file mode 100644 index ee39de4..0000000 --- a/Sdk/Entity/RectanglePosition.Builder.cs +++ /dev/null @@ -1,115 +0,0 @@ -namespace Signit.Sdk.Entity -{ - public partial class RectanglePosition - { - public class Builder - { - private float? lrX; - private float? lrY; - private float? ulX; - private float? ulY; - private float? scale; - private int? page; - - /** - * 以左上角为原点,横向为x轴,纵向为y轴 - * - * @param lrX - * 矩形框右下角横坐标(单位:pt) - * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} - * @since 2.0.0 - */ - public Builder WithLrX(float lrX) - { - this.lrX = lrX; - return this; - } - - /** - * 以左上角为原点,横向为x轴,纵向为y轴 - * - * @param lrY - * 矩形框右下角纵坐标(单位:pt) - * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} - * @since 2.0.0 - */ - public Builder WithLrY(float lrY) - { - this.lrY = lrY; - return this; - } - - /** - * 以左上角为原点,横向为x轴,纵向为y轴 - * - * @param ulX - * 矩形框左上角横坐标(单位:pt) - * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} - * @since 2.0.0 - */ - public Builder WithUlX(float ulX) - { - this.ulX = ulX; - return this; - } - - /** - * 以左上角为原点,横向为x轴,纵向为y轴 - * - * @param ulY - * 矩形框左上角纵坐标(单位:pt) - * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} - * @since 2.0.0 - */ - public Builder WithUlY(float ulY) - { - this.ulY = ulY; - return this; - } - - /** - * - * @param scale - * 矩形框缩放比例,默认为1.0;参照{@link KeywordPositionBuilder#WithScale(float)} - * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} - * @since 2.0.0 - */ - public Builder WithScale(float scale) - { - this.scale = scale; - return this; - } - - /** - * - * @param page - * rectanglePosition矩形框放在文档的哪一页 - * @return 签名矩形框坐标对象建造器{@link RectanglePositionBuilder} - * @since 2.0.0 - */ - public Builder WithPage(int page) - { - this.page = page; - return this; - } - - /** - * - * @return 签名矩形框坐标对象 {@link RectanglePosition} - * @since 2.0.0 - */ - public RectanglePosition Build() - { - return new RectanglePosition - { - Lrx = lrX, - Lry = lrY, - Ulx = ulX, - Uly = ulY, - Scale = scale, - Page = page, - }; - } - } - } -} diff --git a/Sdk/Entity/RectanglePosition.cs b/Sdk/Entity/RectanglePosition.cs index 858a07f..191b915 100644 --- a/Sdk/Entity/RectanglePosition.cs +++ b/Sdk/Entity/RectanglePosition.cs @@ -1,12 +1,7 @@ namespace Signit.Sdk.Entity { - public partial class RectanglePosition + public class RectanglePosition { - public static Builder CreateBuilder() - { - return new Builder(); - } - public float? Lrx { get; set; } public float? Lry { get; set; } public float? Ulx { get; set; } diff --git a/Sdk/Entity/SealData.Builder.cs b/Sdk/Entity/SealData.Builder.cs deleted file mode 100644 index ded4ff3..0000000 --- a/Sdk/Entity/SealData.Builder.cs +++ /dev/null @@ -1,67 +0,0 @@ -namespace Signit.Sdk.Entity -{ - public partial class SealData - { - public class Builder - { - private string url; - private string base64; - private string name; - - /** - * - * @param url - * 印章数据url - * @return 印章数据对象建造器{@link SealDataBuilder} - * @since 2.0.0 - */ - public Builder WithUrl(string url) - { - this.url = url; - return this; - } - - /** - * - * @param base64 - * 印章数据的base64字符串格式 - * @return 印章数据对象建造器{@link SealDataBuilder} - * @since 2.0.0 - */ - public Builder WithBase64(string base64) - { - this.base64 = base64; - return this; - } - - /** - * 印章名字在企业中是唯一时,可以通过填写印章名字指定使用该印章 - * - * @param name - * 印章名称 - * @return 印章数据对象建造器{@link SealDataBuilder} - * @since 2.0.0 - */ - public Builder WithName(string name) - { - this.name = name; - return this; - } - - /** - * - * @return 印章数据对象 - * @since 2.0.0 - */ - public SealData Build() - { - return new SealData - { - Name = name, - Url = url, - Base64 = base64 - }; - } - } - } -} diff --git a/Sdk/Entity/SealData.cs b/Sdk/Entity/SealData.cs index b5ff97d..4a9cbe8 100644 --- a/Sdk/Entity/SealData.cs +++ b/Sdk/Entity/SealData.cs @@ -1,9 +1,7 @@ namespace Signit.Sdk.Entity { - public partial class SealData : FileData + public class SealData : FileData { - public static Builder CreateBuilder() => new Builder(); - public string Name { get; set; } } } diff --git a/Sdk/Entity/Signer.Builder.cs b/Sdk/Entity/Signer.Builder.cs deleted file mode 100644 index f8c3ffe..0000000 --- a/Sdk/Entity/Signer.Builder.cs +++ /dev/null @@ -1,48 +0,0 @@ -namespace Signit.Sdk.Entity -{ - public partial class Signer - { - public class Builder - { - private int sequence; - private SignerPosition position; - private SignerData data; - private SignerInfo signerInfo; - - public Builder WithSequence(int sequence) - { - this.sequence = sequence; - return this; - } - - public Builder WithPosition(SignerPosition position) - { - this.position = position; - return this; - } - - public Builder WithData(SignerData data) - { - this.data = data; - return this; - } - - public Builder WithSignerInfo(SignerInfo signerInfo) - { - this.signerInfo = signerInfo; - return this; - } - - public Signer Build() - { - return new Signer() - { - Sequence = sequence, - Position = position, - Data = data, - SignerInfo = signerInfo - }; - } - } - } -} \ No newline at end of file diff --git a/Sdk/Entity/Signer.cs b/Sdk/Entity/Signer.cs index 218ba34..dac5953 100644 --- a/Sdk/Entity/Signer.cs +++ b/Sdk/Entity/Signer.cs @@ -1,12 +1,7 @@ namespace Signit.Sdk.Entity { - public partial class Signer + public class Signer { - public static Builder CreateBuilder() - { - return new Builder(); - } - public int Sequence { get; set; } public SignerPosition Position { get; set; } public SignerData Data { get; set; } diff --git a/Sdk/Entity/SignerData.Builder.cs b/Sdk/Entity/SignerData.Builder.cs deleted file mode 100644 index 3ef1acd..0000000 --- a/Sdk/Entity/SignerData.Builder.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace Signit.Sdk.Entity -{ - public partial class SignerData - { - public class Builder - { - private SealData sealData; - private SealData writeData; - - public Builder WithSealData(SealData sealData) - { - this.sealData = sealData; - return this; - } - - public Builder WithWriteData(SealData writeData) - { - this.writeData = writeData; - return this; - } - - public SignerData Build() - { - return new SignerData - { - SealData = sealData, - WriteData = writeData - }; - } - } - } -} diff --git a/Sdk/Entity/SignerData.cs b/Sdk/Entity/SignerData.cs index a4f0487..b51473b 100644 --- a/Sdk/Entity/SignerData.cs +++ b/Sdk/Entity/SignerData.cs @@ -1,9 +1,7 @@ namespace Signit.Sdk.Entity { - public partial class SignerData + public class SignerData { - public static Builder CreateBuilder() => new Builder(); - public SealData SealData { get; set; } public SealData WriteData { get; set; } } diff --git a/Sdk/Entity/SignerInfo.Builder.cs b/Sdk/Entity/SignerInfo.Builder.cs deleted file mode 100644 index 043a950..0000000 --- a/Sdk/Entity/SignerInfo.Builder.cs +++ /dev/null @@ -1,64 +0,0 @@ -namespace Signit.Sdk.Entity -{ - public partial class SignerInfo - { - public class Builder - { - private string name; - private string orgnizationName; - private string idCardNo; - private string location; - private string contact; - private string reason; - - public Builder WithName(string name) - { - this.name = name; - return this; - } - - public Builder WithOrgnizationName(string orgnizationName) - { - this.orgnizationName = orgnizationName; - return this; - } - - public Builder WithIdCardNo(string idCardNo) - { - this.idCardNo = idCardNo; - return this; - } - - public Builder WithLocation(string location) - { - this.location = location; - return this; - } - - public Builder WithContact(string contact) - { - this.contact = contact; - return this; - } - - public Builder WithReason(string reason) - { - this.reason = reason; - return this; - } - - public SignerInfo Build() - { - return new SignerInfo - { - Name = name, - OrgnizationName = orgnizationName, - IdCardNo = idCardNo, - Location = location, - Contact = contact, - Reason = reason, - }; - } - } - } -} diff --git a/Sdk/Entity/SignerInfo.cs b/Sdk/Entity/SignerInfo.cs index 9905cc7..1a02239 100644 --- a/Sdk/Entity/SignerInfo.cs +++ b/Sdk/Entity/SignerInfo.cs @@ -1,9 +1,7 @@ namespace Signit.Sdk.Entity { - public partial class SignerInfo + public class SignerInfo { - public static Builder CreateBuilder() => new Builder(); - public string Name { get; set; } public string OrgnizationName { get; set; } public string IdCardNo { get; set; } diff --git a/Sdk/Entity/SignerPosition.cs b/Sdk/Entity/SignerPosition.cs index 669debe..37b302f 100644 --- a/Sdk/Entity/SignerPosition.cs +++ b/Sdk/Entity/SignerPosition.cs @@ -33,22 +33,6 @@ return this; } - /** - * - * @param keywordPositionBuilder - * 利用关键字定位签名矩形框所在位置的数据对象建造器;利用关键字进行定位{@link KeywordPosition.KeywordPositionBuilder} - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link PositionBuilder} - * @since 1.0.0 - */ - public Builder WithKeywordPosition(KeywordPosition.Builder keywordPositionBuilder) - { - if (keywordPositionBuilder != null) - { - this.keywordPosition = keywordPositionBuilder.Build(); - } - return this; - } - /** * * @param rectanglePosition @@ -62,22 +46,6 @@ return this; } - /** - * - * @param rectanglePositionBuilder - * 直接设定好的签名矩形框坐标对象建造器 {@link RectanglePositionBuilder} - * @return 利用关键字定位签名矩形框所在位置的数据对象建造器{@link PositionBuilder} - * @since 1.0.0 - */ - public Builder WithRectanglePosition(RectanglePosition.Builder rectanglePositionBuilder) - { - if (rectanglePositionBuilder != null) - { - rectanglePosition = rectanglePositionBuilder.Build(); - } - return this; - } - /** * * @param fieldsName diff --git a/Sdk/Http/AbstractSignitResponse.cs b/Sdk/Http/AbstractSignitResponse.cs index e8ab21a..d297407 100644 --- a/Sdk/Http/AbstractSignitResponse.cs +++ b/Sdk/Http/AbstractSignitResponse.cs @@ -4,7 +4,11 @@ { public string Code { get; set; } public string Message { get; set; } + + // 自定义标识 public string CustomTag { get; set; } + + // 服务调用唯一标识 public string InvokeNo { get; set; } public bool IsSuccess diff --git a/Sdk/Http/SignatureRequest.Builder.cs b/Sdk/Http/SignatureRequest.Builder.cs deleted file mode 100644 index 8d542fa..0000000 --- a/Sdk/Http/SignatureRequest.Builder.cs +++ /dev/null @@ -1,59 +0,0 @@ -using Signit.Sdk.Entity; -using System.Collections.Generic; - -namespace Signit.Sdk.Http -{ - public partial class SignatureRequest - { - public class Builder - { - private FileData fileData; - private AcceptDataType acceptDataType; - private string returnUrl; - private string customTag; - private IList signDetails; - - public Builder WithFileData(FileData fileData) - { - this.fileData = fileData; - return this; - } - - public Builder WithAcceptDataType(AcceptDataType acceptDataType) - { - this.acceptDataType = acceptDataType; - return this; - } - - public Builder WithReturnUrl(string returnUrl) - { - this.returnUrl = returnUrl; - return this; - } - - public Builder WithCustomTag(string customTag) - { - this.customTag = customTag; - return this; - } - - public Builder WithSignDetails(IList signDetails) - { - this.signDetails = signDetails; - return this; - } - - public SignatureRequest Build() - { - return new SignatureRequest - { - FileData = fileData, - AcceptDataType = acceptDataType, - ReturnUrl = returnUrl, - CustomTag = customTag, - SignDetails = signDetails, - }; - } - } - } -} diff --git a/Sdk/Http/SignatureRequest.cs b/Sdk/Http/SignatureRequest.cs index 45f277e..0d99b8e 100644 --- a/Sdk/Http/SignatureRequest.cs +++ b/Sdk/Http/SignatureRequest.cs @@ -3,10 +3,8 @@ using System.Collections.Generic; namespace Signit.Sdk.Http { - public partial class SignatureRequest : AbstractSignitRequest + public class SignatureRequest : AbstractSignitRequest { - public static Builder CreateBuilder() => new Builder(); - public FileData FileData; public IList SignDetails; } diff --git a/Sdk/Http/Webhook/ParticipantHandling.cs b/Sdk/Http/Webhook/ParticipantHandling.cs index fff79f0..670f379 100644 --- a/Sdk/Http/Webhook/ParticipantHandling.cs +++ b/Sdk/Http/Webhook/ParticipantHandling.cs @@ -13,12 +13,6 @@ namespace Signit.Sdk.Http.Webhook // 接收方对应的在易企签的帐号 public string Account { get; set; } - // 自定义标识 - public string CustomTag { get; set; } - - // 服务调用唯一标识 - public string InvokeNo { get; set; } - // 信封基本信息 public RawDataBasicInfo BasicEnvelope { get; set; } diff --git a/Sdk/Http/Webhook/WebhookResponse.cs b/Sdk/Http/Webhook/WebhookResponse.cs index 90a7596..39503d9 100644 --- a/Sdk/Http/Webhook/WebhookResponse.cs +++ b/Sdk/Http/Webhook/WebhookResponse.cs @@ -3,7 +3,7 @@ using System; namespace Signit.Sdk.Http.Webhook { - public partial class WebhookResponse : WebhookDataBase + public class WebhookResponse : WebhookDataBase { public string RawData { get; set; } diff --git a/Sdk/Sdk.csproj b/Sdk/Sdk.csproj index 5aa5241..406e5c3 100644 --- a/Sdk/Sdk.csproj +++ b/Sdk/Sdk.csproj @@ -80,9 +80,7 @@ - - @@ -100,7 +98,6 @@ - @@ -127,16 +124,12 @@ - - - - -- Gitee From fdcdc71739c37cfea174b73c7b1f6f723e876400 Mon Sep 17 00:00:00 2001 From: jamesfancy Date: Sun, 26 May 2019 23:56:19 +0800 Subject: [PATCH 7/8] =?UTF-8?q?=E5=B0=8F=E6=94=B9=E5=8A=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sdk/Entity/Signer.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/Sdk/Entity/Signer.cs b/Sdk/Entity/Signer.cs index dac5953..108f6ea 100644 --- a/Sdk/Entity/Signer.cs +++ b/Sdk/Entity/Signer.cs @@ -6,7 +6,5 @@ public SignerPosition Position { get; set; } public SignerData Data { get; set; } public SignerInfo SignerInfo { get; set; } - - private Signer() { } } } -- Gitee From fed5f1d0b72d9c7c457584e9af822867d2238c76 Mon Sep 17 00:00:00 2001 From: jamesfancy Date: Mon, 27 May 2019 01:10:08 +0800 Subject: [PATCH 8/8] =?UTF-8?q?=E7=BB=86=E8=8A=82=E8=B0=83=E6=95=B4?= =?UTF-8?q?=E4=BB=A5=E5=8F=8A=E8=A1=A5=E5=85=85=E5=AE=8C=E5=96=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Sdk/Entity/KeywordPosition.cs | 4 +- Sdk/Entity/PresetForm.cs | 6 +- Sdk/Entity/Receiver.cs | 2 +- Sdk/Http/AbstractSignitRequest.cs | 2 +- Sdk/Http/AbstractSignitResponse.cs | 2 + Sdk/Http/Envelope/EnvelopeParticipantInfo.cs | 19 +++++- Sdk/Http/Envelope/StartEnvelopeRequest.cs | 8 +-- Sdk/Sdk.csproj | 2 +- Sdk/SignitClient.cs | 67 ++++++++------------ Sdk/Types/{Enums.cs => AcceptDataType.cs} | 7 +- 10 files changed, 58 insertions(+), 61 deletions(-) rename Sdk/Types/{Enums.cs => AcceptDataType.cs} (37%) diff --git a/Sdk/Entity/KeywordPosition.cs b/Sdk/Entity/KeywordPosition.cs index 8c7e6a4..d928c7a 100644 --- a/Sdk/Entity/KeywordPosition.cs +++ b/Sdk/Entity/KeywordPosition.cs @@ -1,4 +1,6 @@ -namespace Signit.Sdk.Entity +using Signit.Sdk.Types; + +namespace Signit.Sdk.Entity { public class KeywordPosition { diff --git a/Sdk/Entity/PresetForm.cs b/Sdk/Entity/PresetForm.cs index 6560e71..5441ce0 100644 --- a/Sdk/Entity/PresetForm.cs +++ b/Sdk/Entity/PresetForm.cs @@ -26,7 +26,7 @@ namespace Signit.Sdk.Entity /** * 表单缩放比例. */ - public float scale { get; set; } = 1.0f; + public float Scale { get; set; } = 1.0f; /** * 签名初始化值. @@ -36,7 +36,7 @@ namespace Signit.Sdk.Entity /** * 表单是否允许修正. */ - public bool revisable { get; set; } + public bool Revisable { get; set; } /** * 当前表单的自定义标识. @@ -46,7 +46,7 @@ namespace Signit.Sdk.Entity /** * 是否是纠正创建的表单. */ - public bool corrected { get; set; } + public bool Corrected { get; set; } /** * 跨页表单距离页面边缘边距,单位px diff --git a/Sdk/Entity/Receiver.cs b/Sdk/Entity/Receiver.cs index 1807edf..65fcbc5 100644 --- a/Sdk/Entity/Receiver.cs +++ b/Sdk/Entity/Receiver.cs @@ -32,7 +32,7 @@ namespace Signit.Sdk.Entity /** * 接收方是否必须预分配表单域. */ - public bool needForm { get; set; } + public bool NeedForm { get; set; } /** * 设置接收方私人信息. */ diff --git a/Sdk/Http/AbstractSignitRequest.cs b/Sdk/Http/AbstractSignitRequest.cs index 1d111d2..36ea6e8 100644 --- a/Sdk/Http/AbstractSignitRequest.cs +++ b/Sdk/Http/AbstractSignitRequest.cs @@ -1,4 +1,4 @@ -using Signit.Sdk.Entity; +using Signit.Sdk.Types; namespace Signit.Sdk.Http { diff --git a/Sdk/Http/AbstractSignitResponse.cs b/Sdk/Http/AbstractSignitResponse.cs index d297407..2f4056d 100644 --- a/Sdk/Http/AbstractSignitResponse.cs +++ b/Sdk/Http/AbstractSignitResponse.cs @@ -25,5 +25,7 @@ && code >= 0 && code < 100; } } + + public ErrorResponse Error { get; set; } } } diff --git a/Sdk/Http/Envelope/EnvelopeParticipantInfo.cs b/Sdk/Http/Envelope/EnvelopeParticipantInfo.cs index 14ee3d4..893cc32 100644 --- a/Sdk/Http/Envelope/EnvelopeParticipantInfo.cs +++ b/Sdk/Http/Envelope/EnvelopeParticipantInfo.cs @@ -1,6 +1,21 @@ -namespace Signit.Sdk.Http.Envelope +using Signit.Sdk.Entity; +using System.Collections.Generic; + +namespace Signit.Sdk.Http.Envelope { + /** + * 参与文件签署人员的信息. 包含发送者信息和接受者信息列表. + */ public class EnvelopeParticipantInfo { + /** + * 发送者信息. + */ + public Sender Sender { get; set; } + + /** + * 接受者信息列表. + */ + public IList Receivers { get; set; } } -} \ No newline at end of file +} diff --git a/Sdk/Http/Envelope/StartEnvelopeRequest.cs b/Sdk/Http/Envelope/StartEnvelopeRequest.cs index c40c370..b7f8e99 100644 --- a/Sdk/Http/Envelope/StartEnvelopeRequest.cs +++ b/Sdk/Http/Envelope/StartEnvelopeRequest.cs @@ -3,21 +3,21 @@ /// /// 信封启动服务请求体. 包含信封基本信息、信封流程中的签署文件内容、签署参与者信息、自定义跳转URL、自定义可接受数据类型、自定义标识. /// - class StartEnvelopeRequest : AbstractSignitRequest + public class StartEnvelopeRequest : AbstractSignitRequest { /// /// 信封基本信息. /// - public EnvelopeBasicInfo Basicinfo {get;set;} + public EnvelopeBasicInfo Basicinfo { get; set; } /// /// 信封流程中的签署文件内容. /// - public EnvelopeContentInfo ContentInfo {get;set;} + public EnvelopeContentInfo ContentInfo { get; set; } /// /// 签署参与者信息. /// - public EnvelopeParticipantInfo ParticipantInfo {get;set;} + public EnvelopeParticipantInfo ParticipantInfo { get; set; } } } diff --git a/Sdk/Sdk.csproj b/Sdk/Sdk.csproj index 406e5c3..6417192 100644 --- a/Sdk/Sdk.csproj +++ b/Sdk/Sdk.csproj @@ -122,7 +122,7 @@ - + diff --git a/Sdk/SignitClient.cs b/Sdk/SignitClient.cs index 2aede33..02e1cf2 100644 --- a/Sdk/SignitClient.cs +++ b/Sdk/SignitClient.cs @@ -31,8 +31,8 @@ namespace Signit.Sdk //private const Pattern RIGHT_QUOTATION = Pattern.compile("\\}\""); //private const Pattern BACKLASH_QUOTATION = Pattern.compile("\\\\\""); - private string baseUrl; - private string oAuthTokenUrl; + public string BaseUrl { get; set; } + public string OAuthTokenUrl { get; set; } public SignitClient(ApiOptions options = null) : this(null, null, options) { } @@ -50,6 +50,7 @@ namespace Signit.Sdk } public string Url { set => SetUrl(value); } + public string EnvUrl => options.EnvUrl; public SignitClient SetUrl(string envUrl) { @@ -57,8 +58,8 @@ namespace Signit.Sdk ? options.EnvUrl : envUrl.Trim(); - baseUrl = $"{url}{options.BaseApiUrl}"; - oAuthTokenUrl = $"{url}{options.OAuthTokenUrl}"; + BaseUrl = $"{url}{options.BaseApiUrl}"; + OAuthTokenUrl = $"{url}{options.OAuthTokenUrl}"; return this; } @@ -83,7 +84,7 @@ namespace Signit.Sdk .AddQueryParam(options.ClientSecret, secretKey) .AddQueryParam(options.GrantType, tokenType.ToString().ToLower()); - return client.Get(oAuthTokenUrl).GetObject(); + return client.Get(OAuthTokenUrl).GetObject(); } /// @@ -113,15 +114,9 @@ namespace Signit.Sdk return Authentication; } - /// - /// 发送快捷签署请求 - /// - /// 快捷签署请求 - /// 快捷签署响应 - - public SignatureResponse QuickSign(SignatureRequest request) + public T Execute(AbstractSignitRequest request) + where T : AbstractSignitResponse { - if (request == null) { return null; @@ -138,7 +133,6 @@ namespace Signit.Sdk Authenticate(auth.AppId, auth.SecuretKey, auth.AccessTokenType); } - // TODO 返回 var client = new HttpClientSync(); var headers = new NameValueCollection { @@ -147,9 +141,24 @@ namespace Signit.Sdk var response = client .WithAuthentication(Authentication) - .Post(baseUrl, request, headers); + .Post(BaseUrl, request, headers); + + var result = response.GetObject(); + if (!result.IsSuccess) + { + result.Error = response.GetObject(); + } + return result; + } - return response.GetObject(); + /// + /// 发送快捷签署请求 + /// + /// 快捷签署请求 + /// 快捷签署响应 + public SignatureResponse QuickSign(SignatureRequest request) + { + return Execute(request); } public static bool Verify(string signitSignature, string appId, HmacSignatureBuilder builder) @@ -182,31 +191,5 @@ namespace Signit.Sdk string selfSignature = $"{HmacSignatureBuilder.DEFAULT_ALGORITHM} {appId}:{builder.BuildAsBase64()}"; return selfSignature == signature; } - - public T Execute(AbstractSignitRequest request) - where T : AbstractSignitResponse - { - if (request == null) - { - return null; - } - - var auth = Authentication; - if (!auth.HasAccessToken || !auth.HasAppId || !auth.HasSecretKey) - { - throw new SignitException("请完善开发者信息"); - } - - var client = new HttpClientSync(); - var headers = new NameValueCollection - { - { options.AppIdKey, auth.AppId } - }; - - var response = client.WithAuthentication(auth) - .Post(baseUrl, request, headers); - - return response.GetObject(); - } } } diff --git a/Sdk/Types/Enums.cs b/Sdk/Types/AcceptDataType.cs similarity index 37% rename from Sdk/Types/Enums.cs rename to Sdk/Types/AcceptDataType.cs index cabce40..eb6d616 100644 --- a/Sdk/Types/Enums.cs +++ b/Sdk/Types/AcceptDataType.cs @@ -1,12 +1,7 @@ -namespace Signit.Sdk.Entity +namespace Signit.Sdk.Types { public enum AcceptDataType { BASE64, URL } - - public enum Direction - { - TOP, BOTTOM, LEFT, RIGHT, CENTER - } } -- Gitee