293 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			293 lines
		
	
	
		
			7.4 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
|  | # e签宝 SDK - 重构版本
 | |||
|  | 
 | |||
|  | 这是重构后的e签宝Go SDK,提供了更清晰、更易用的API接口。 | |||
|  | 
 | |||
|  | ## 架构设计
 | |||
|  | 
 | |||
|  | ### 主要组件
 | |||
|  | 
 | |||
|  | 1. **Client (client.go)** - 统一的客户端入口 | |||
|  | 2. **Config (config.go)** - 配置管理 | |||
|  | 3. **HTTPClient (http.go)** - HTTP请求处理 | |||
|  | 4. **服务模块**: | |||
|  |    - **TemplateService** - 模板操作服务 | |||
|  |    - **SignFlowService** - 签署流程服务 | |||
|  |    - **OrgAuthService** - 机构认证服务 | |||
|  |    - **FileOpsService** - 文件操作服务 | |||
|  | 
 | |||
|  | ### 设计特点
 | |||
|  | 
 | |||
|  | - ✅ **模块化设计**:功能按模块分离,职责清晰 | |||
|  | - ✅ **统一入口**:通过Client提供统一的API | |||
|  | - ✅ **易于使用**:提供高级业务接口和底层操作接口 | |||
|  | - ✅ **配置管理**:集中的配置验证和管理 | |||
|  | - ✅ **错误处理**:统一的错误处理和响应验证 | |||
|  | - ✅ **类型安全**:完整的类型定义和结构体 | |||
|  | 
 | |||
|  | ## 快速开始
 | |||
|  | 
 | |||
|  | ### 1. 创建客户端
 | |||
|  | 
 | |||
|  | ```go | |||
|  | package main | |||
|  | 
 | |||
|  | import ( | |||
|  |     "github.com/your-org/tyapi-server-gin/internal/shared/esign" | |||
|  | ) | |||
|  | 
 | |||
|  | func main() { | |||
|  |     // 创建配置 | |||
|  |     config, err := esign.NewConfig( | |||
|  |         "your_app_id", | |||
|  |         "your_app_secret", | |||
|  |         "https://smlopenapi.esign.cn", | |||
|  |         "your_template_id", | |||
|  |     ) | |||
|  |     if err != nil { | |||
|  |         panic(err) | |||
|  |     } | |||
|  | 
 | |||
|  |     // 创建客户端 | |||
|  |     client := esign.NewClient(config) | |||
|  | } | |||
|  | ``` | |||
|  | 
 | |||
|  | ### 2. 基础用法 - 一键合同签署
 | |||
|  | 
 | |||
|  | ```go | |||
|  | // 最简单的合同签署 | |||
|  | result, err := client.GenerateContractSigning(&esign.ContractSigningRequest{ | |||
|  |     CompanyName:       "我的公司", | |||
|  |     UnifiedSocialCode: "123456789012345678", | |||
|  |     LegalPersonName:   "张三", | |||
|  |     LegalPersonID:     "123456789012345678", | |||
|  |     LegalPersonPhone:  "13800138000", | |||
|  | }) | |||
|  | 
 | |||
|  | if err != nil { | |||
|  |     log.Fatal("签署失败:", err) | |||
|  | } | |||
|  | 
 | |||
|  | fmt.Printf("请访问链接进行签署: %s\n", result.SignURL) | |||
|  | ``` | |||
|  | 
 | |||
|  | ### 3. 企业认证
 | |||
|  | 
 | |||
|  | ```go | |||
|  | // 企业认证 | |||
|  | authResult, err := client.GenerateEnterpriseAuth(&esign.EnterpriseAuthRequest{ | |||
|  |     CompanyName:       "我的公司", | |||
|  |     UnifiedSocialCode: "123456789012345678", | |||
|  |     LegalPersonName:   "张三", | |||
|  |     LegalPersonID:     "123456789012345678", | |||
|  |     TransactorName:    "李四", | |||
|  |     TransactorPhone:   "13800138001", | |||
|  |     TransactorID:      "123456789012345679", | |||
|  | }) | |||
|  | 
 | |||
|  | if err != nil { | |||
|  |     log.Fatal("企业认证失败:", err) | |||
|  | } | |||
|  | 
 | |||
|  | fmt.Printf("请访问链接进行企业认证: %s\n", authResult.AuthURL) | |||
|  | ``` | |||
|  | 
 | |||
|  | ## 高级用法
 | |||
|  | 
 | |||
|  | ### 分步操作
 | |||
|  | 
 | |||
|  | 如果需要更精细的控制,可以使用分步操作: | |||
|  | 
 | |||
|  | ```go | |||
|  | // 1. 填写模板 | |||
|  | templateData := map[string]string{ | |||
|  |     "JFQY": "甲方公司", | |||
|  |     "JFFR": "甲方法人", | |||
|  |     "YFQY": "乙方公司",  | |||
|  |     "YFFR": "乙方法人", | |||
|  |     "QDRQ": "2024年01月01日", | |||
|  | } | |||
|  | 
 | |||
|  | fileID, err := client.FillTemplate(templateData) | |||
|  | if err != nil { | |||
|  |     return err | |||
|  | } | |||
|  | 
 | |||
|  | // 2. 创建签署流程 | |||
|  | signFlowReq := &esign.CreateSignFlowRequest{ | |||
|  |     FileID:              fileID, | |||
|  |     SignerAccount:       "123456789012345678", | |||
|  |     SignerName:          "乙方公司", | |||
|  |     TransactorPhone:     "13800138000", | |||
|  |     TransactorName:      "乙方法人", | |||
|  |     TransactorIDCardNum: "123456789012345678", | |||
|  |     TransactorMobile:    "13800138000", | |||
|  | } | |||
|  | 
 | |||
|  | signFlowID, err := client.CreateSignFlow(signFlowReq) | |||
|  | if err != nil { | |||
|  |     return err | |||
|  | } | |||
|  | 
 | |||
|  | // 3. 获取签署链接 | |||
|  | signURL, shortURL, err := client.GetSignURL(signFlowID, "13800138000", "乙方公司") | |||
|  | if err != nil { | |||
|  |     return err | |||
|  | } | |||
|  | 
 | |||
|  | // 4. 查询签署状态 | |||
|  | status, err := client.GetSignFlowStatus(signFlowID) | |||
|  | if err != nil { | |||
|  |     return err | |||
|  | } | |||
|  | 
 | |||
|  | // 5. 检查是否完成 | |||
|  | completed, err := client.IsSignFlowCompleted(signFlowID) | |||
|  | if err != nil { | |||
|  |     return err | |||
|  | } | |||
|  | ``` | |||
|  | 
 | |||
|  | ### 自定义模板数据
 | |||
|  | 
 | |||
|  | ```go | |||
|  | customData := map[string]string{ | |||
|  |     "custom_field_1": "自定义值1", | |||
|  |     "custom_field_2": "自定义值2", | |||
|  |     "contract_date":  "2024年01月01日", | |||
|  | } | |||
|  | 
 | |||
|  | result, err := client.GenerateContractSigning(&esign.ContractSigningRequest{ | |||
|  |     CompanyName:       "我的公司", | |||
|  |     UnifiedSocialCode: "123456789012345678", | |||
|  |     LegalPersonName:   "张三", | |||
|  |     LegalPersonID:     "123456789012345678", | |||
|  |     LegalPersonPhone:  "13800138000", | |||
|  |     CustomData:        customData, // 使用自定义数据 | |||
|  | }) | |||
|  | ``` | |||
|  | 
 | |||
|  | ## API参考
 | |||
|  | 
 | |||
|  | ### 主要接口
 | |||
|  | 
 | |||
|  | #### 合同签署
 | |||
|  | - `GenerateContractSigning(req *ContractSigningRequest) (*ContractSigningResult, error)` - 一键生成合同签署 | |||
|  | 
 | |||
|  | #### 企业认证
 | |||
|  | - `GenerateEnterpriseAuth(req *EnterpriseAuthRequest) (*EnterpriseAuthResult, error)` - 一键企业认证 | |||
|  | 
 | |||
|  | #### 模板操作
 | |||
|  | - `FillTemplate(components map[string]string) (string, error)` - 填写模板 | |||
|  | - `FillTemplateWithDefaults(partyA, legalRepA, partyB, legalRepB string) (string, error)` - 使用默认数据填写模板 | |||
|  | 
 | |||
|  | #### 签署流程
 | |||
|  | - `CreateSignFlow(req *CreateSignFlowRequest) (string, error)` - 创建签署流程 | |||
|  | - `GetSignURL(signFlowID, psnAccount, orgName string) (string, string, error)` - 获取签署链接 | |||
|  | - `QuerySignFlowDetail(signFlowID string) (*QuerySignFlowDetailResponse, error)` - 查询流程详情 | |||
|  | - `IsSignFlowCompleted(signFlowID string) (bool, error)` - 检查是否完成 | |||
|  | 
 | |||
|  | #### 机构认证
 | |||
|  | - `GetOrgAuthURL(req *OrgAuthRequest) (string, string, string, error)` - 获取认证链接 | |||
|  | - `ValidateOrgAuthInfo(req *OrgAuthRequest) error` - 验证认证信息 | |||
|  | 
 | |||
|  | #### 文件操作
 | |||
|  | - `DownloadSignedFile(signFlowID string) (*DownloadSignedFileResponse, error)` - 下载已签署文件 | |||
|  | - `GetSignFlowStatus(signFlowID string) (string, error)` - 获取流程状态 | |||
|  | 
 | |||
|  | ## 配置管理
 | |||
|  | 
 | |||
|  | ### 配置结构
 | |||
|  | 
 | |||
|  | ```go | |||
|  | type Config struct { | |||
|  |     AppID      string `json:"app_id"`      // 应用ID | |||
|  |     AppSecret  string `json:"app_secret"`  // 应用密钥 | |||
|  |     ServerURL  string `json:"server_url"`  // 服务器URL | |||
|  |     TemplateID string `json:"template_id"` // 模板ID | |||
|  | } | |||
|  | ``` | |||
|  | 
 | |||
|  | ### 配置验证
 | |||
|  | 
 | |||
|  | SDK会自动验证配置的完整性: | |||
|  | 
 | |||
|  | ```go | |||
|  | config, err := esign.NewConfig("", "", "", "") | |||
|  | // 返回错误:应用ID不能为空 | |||
|  | 
 | |||
|  | // 手动验证 | |||
|  | err := config.Validate() | |||
|  | ``` | |||
|  | 
 | |||
|  | ## 错误处理
 | |||
|  | 
 | |||
|  | SDK提供统一的错误处理: | |||
|  | 
 | |||
|  | ```go | |||
|  | result, err := client.GenerateContractSigning(req) | |||
|  | if err != nil { | |||
|  |     // 错误包含详细的错误信息 | |||
|  |     log.Printf("签署失败: %v", err) | |||
|  |     return | |||
|  | } | |||
|  | ``` | |||
|  | 
 | |||
|  | ## 迁移指南
 | |||
|  | 
 | |||
|  | ### 从旧版本迁移
 | |||
|  | 
 | |||
|  | 旧版本: | |||
|  | ```go | |||
|  | service := service.NewEQService(config) | |||
|  | result, err := service.ExecuteSignProcess(req) | |||
|  | ``` | |||
|  | 
 | |||
|  | 新版本: | |||
|  | ```go | |||
|  | client := esign.NewClient(config) | |||
|  | result, err := client.GenerateContractSigning(req) | |||
|  | ``` | |||
|  | 
 | |||
|  | ### 主要变化
 | |||
|  | 
 | |||
|  | 1. **包名变更**:`service` → `esign` | |||
|  | 2. **入口简化**:`EQService` → `Client` | |||
|  | 3. **方法重命名**:更语义化的方法名 | |||
|  | 4. **结构重组**:按功能模块划分 | |||
|  | 5. **类型优化**:更简洁的请求/响应结构 | |||
|  | 
 | |||
|  | ## 示例代码
 | |||
|  | 
 | |||
|  | 完整的示例代码请参考 `example.go` 文件。 | |||
|  | 
 | |||
|  | ## 注意事项
 | |||
|  | 
 | |||
|  | 1. **配置安全**:请妥善保管AppID和AppSecret | |||
|  | 2. **网络超时**:默认HTTP超时为30秒 | |||
|  | 3. **并发安全**:Client实例是并发安全的 | |||
|  | 4. **错误重试**:建议实现适当的重试机制 | |||
|  | 5. **日志记录**:SDK会输出调试信息,生产环境请注意日志级别 | |||
|  | 
 | |||
|  | ## 常见问题
 | |||
|  | 
 | |||
|  | ### Q: 如何更新配置?
 | |||
|  | ```go | |||
|  | newConfig, _ := esign.NewConfig("new_app_id", "new_secret", "new_url", "new_template") | |||
|  | client.UpdateConfig(newConfig) | |||
|  | ``` | |||
|  | 
 | |||
|  | ### Q: 如何处理网络错误?
 | |||
|  | ```go | |||
|  | result, err := client.GenerateContractSigning(req) | |||
|  | if err != nil { | |||
|  |     if strings.Contains(err.Error(), "timeout") { | |||
|  |         // 处理超时 | |||
|  |     } else if strings.Contains(err.Error(), "API调用失败") { | |||
|  |         // 处理API错误 | |||
|  |     } | |||
|  | } | |||
|  | ``` | |||
|  | 
 | |||
|  | ### Q: 如何自定义HTTP客户端?
 | |||
|  | 当前版本使用内置的HTTP客户端,如需自定义,可以修改`http.go`中的客户端配置。  |