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`中的客户端配置。
|