215 lines
5.9 KiB
Go
215 lines
5.9 KiB
Go
|
|
package esign
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"fmt"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// SignFlowService 签署流程服务
|
|||
|
|
// 处理签署流程创建、链接获取等操作
|
|||
|
|
type SignFlowService struct {
|
|||
|
|
httpClient *HTTPClient
|
|||
|
|
config *Config
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// NewSignFlowService 创建签署流程服务
|
|||
|
|
func NewSignFlowService(httpClient *HTTPClient, config *Config) *SignFlowService {
|
|||
|
|
return &SignFlowService{
|
|||
|
|
httpClient: httpClient,
|
|||
|
|
config: config,
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// UpdateConfig 更新配置
|
|||
|
|
func (s *SignFlowService) UpdateConfig(config *Config) {
|
|||
|
|
s.config = config
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Create 创建签署流程
|
|||
|
|
// 创建包含多个签署人的签署流程,支持自动盖章和手动签署
|
|||
|
|
func (s *SignFlowService) Create(req *CreateSignFlowRequest) (string, error) {
|
|||
|
|
fmt.Println("开始创建签署流程...")
|
|||
|
|
fmt.Println("(将创建包含甲方自动盖章和乙方手动签署的流程)")
|
|||
|
|
|
|||
|
|
// 构建甲方签署人信息(自动盖章)
|
|||
|
|
partyASigner := s.buildPartyASigner(req.FileID)
|
|||
|
|
|
|||
|
|
// 构建乙方签署人信息(手动签署)
|
|||
|
|
partyBSigner := s.buildPartyBSigner(req.FileID, req.SignerAccount, req.SignerName, req.TransactorPhone, req.TransactorName, req.TransactorIDCardNum)
|
|||
|
|
|
|||
|
|
signers := []SignerInfo{partyASigner, partyBSigner}
|
|||
|
|
|
|||
|
|
// 构建请求数据
|
|||
|
|
requestData := CreateSignFlowByFileRequest{
|
|||
|
|
Docs: []DocInfo{
|
|||
|
|
{
|
|||
|
|
FileId: req.FileID,
|
|||
|
|
FileName: "天远数据API合作协议.pdf",
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
SignFlowConfig: s.buildSignFlowConfig(),
|
|||
|
|
Signers: signers,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 序列化请求数据
|
|||
|
|
jsonData, err := MarshalRequest(requestData)
|
|||
|
|
if err != nil {
|
|||
|
|
return "", err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fmt.Printf("发起签署请求数据: %s\n", string(jsonData))
|
|||
|
|
|
|||
|
|
// 发送API请求
|
|||
|
|
responseBody, err := s.httpClient.Request("POST", "/v3/sign-flow/create-by-file", jsonData)
|
|||
|
|
if err != nil {
|
|||
|
|
return "", fmt.Errorf("发起签署失败: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 解析响应
|
|||
|
|
var response CreateSignFlowByFileResponse
|
|||
|
|
if err := UnmarshalResponse(responseBody, &response); err != nil {
|
|||
|
|
return "", err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if err := CheckResponseCode(response.Code, response.Message); err != nil {
|
|||
|
|
return "", err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fmt.Printf("签署流程创建成功,流程ID: %s\n", response.Data.SignFlowId)
|
|||
|
|
return response.Data.SignFlowId, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetSignURL 获取签署页面链接
|
|||
|
|
// 为指定的签署人获取签署页面链接
|
|||
|
|
func (s *SignFlowService) GetSignURL(signFlowID, psnAccount, orgName string) (string, string, error) {
|
|||
|
|
fmt.Println("开始获取签署页面链接...")
|
|||
|
|
|
|||
|
|
// 构建请求数据
|
|||
|
|
requestData := GetSignUrlRequest{
|
|||
|
|
NeedLogin: false,
|
|||
|
|
UrlType: UrlTypeSign,
|
|||
|
|
Operator: &Operator{
|
|||
|
|
PsnAccount: psnAccount,
|
|||
|
|
},
|
|||
|
|
Organization: &Organization{
|
|||
|
|
OrgName: orgName,
|
|||
|
|
},
|
|||
|
|
ClientType: ClientTypeAll,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 序列化请求数据
|
|||
|
|
jsonData, err := MarshalRequest(requestData)
|
|||
|
|
if err != nil {
|
|||
|
|
return "", "", err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fmt.Printf("获取签署页面链接请求数据: %s\n", string(jsonData))
|
|||
|
|
|
|||
|
|
// 发送API请求
|
|||
|
|
urlPath := fmt.Sprintf("/v3/sign-flow/%s/sign-url", signFlowID)
|
|||
|
|
responseBody, err := s.httpClient.Request("POST", urlPath, jsonData)
|
|||
|
|
if err != nil {
|
|||
|
|
return "", "", fmt.Errorf("获取签署页面链接失败: %v", err)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 解析响应
|
|||
|
|
var response GetSignUrlResponse
|
|||
|
|
if err := UnmarshalResponse(responseBody, &response); err != nil {
|
|||
|
|
return "", "", err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if err := CheckResponseCode(response.Code, response.Message); err != nil {
|
|||
|
|
return "", "", err
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
fmt.Printf("签署页面链接获取成功!\n")
|
|||
|
|
fmt.Printf("完整链接: %s\n", response.Data.Url)
|
|||
|
|
fmt.Printf("短链接: %s\n", response.Data.ShortUrl)
|
|||
|
|
|
|||
|
|
return response.Data.Url, response.Data.ShortUrl, nil
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// buildPartyASigner 构建甲方签署人信息(自动盖章)
|
|||
|
|
func (s *SignFlowService) buildPartyASigner(fileID string) SignerInfo {
|
|||
|
|
return SignerInfo{
|
|||
|
|
SignConfig: &SignConfig{SignOrder: 1},
|
|||
|
|
SignerType: SignerTypeOrg,
|
|||
|
|
SignFields: []SignField{
|
|||
|
|
{
|
|||
|
|
CustomBizNum: "甲方签章",
|
|||
|
|
FileId: fileID,
|
|||
|
|
NormalSignFieldConfig: &NormalSignFieldConfig{
|
|||
|
|
AutoSign: true,
|
|||
|
|
SignFieldStyle: SignFieldStyleNormal,
|
|||
|
|
SignFieldPosition: &SignFieldPosition{
|
|||
|
|
PositionPage: "1",
|
|||
|
|
PositionX: 200,
|
|||
|
|
PositionY: 200,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// buildPartyBSigner 构建乙方签署人信息(手动签署)
|
|||
|
|
func (s *SignFlowService) buildPartyBSigner(fileID, signerAccount, signerName, transactorPhone, transactorName, transactorIDCardNum string) SignerInfo {
|
|||
|
|
return SignerInfo{
|
|||
|
|
SignConfig: &SignConfig{
|
|||
|
|
SignOrder: 2,
|
|||
|
|
},
|
|||
|
|
AuthConfig: &AuthConfig{
|
|||
|
|
PsnAvailableAuthModes: []string{AuthModeMobile3},
|
|||
|
|
WillingnessAuthModes: []string{WillingnessAuthSMS},
|
|||
|
|
},
|
|||
|
|
SignerType: SignerTypeOrg,
|
|||
|
|
OrgSignerInfo: &OrgSignerInfo{
|
|||
|
|
OrgName: signerName,
|
|||
|
|
OrgInfo: &OrgInfo{
|
|||
|
|
LegalRepName: transactorName,
|
|||
|
|
LegalRepIDCardNum: transactorIDCardNum,
|
|||
|
|
LegalRepIDCardType: IDCardTypeChina,
|
|||
|
|
OrgIDCardNum: signerAccount,
|
|||
|
|
OrgIDCardType: OrgCardTypeUSCC,
|
|||
|
|
},
|
|||
|
|
TransactorInfo: &TransactorInfo{
|
|||
|
|
PsnAccount: transactorPhone,
|
|||
|
|
PsnInfo: &PsnInfo{
|
|||
|
|
PsnName: transactorName,
|
|||
|
|
PsnIDCardNum: transactorIDCardNum,
|
|||
|
|
PsnIDCardType: IDCardTypeChina,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
SignFields: []SignField{
|
|||
|
|
{
|
|||
|
|
CustomBizNum: "乙方签章",
|
|||
|
|
FileId: fileID,
|
|||
|
|
NormalSignFieldConfig: &NormalSignFieldConfig{
|
|||
|
|
AutoSign: false,
|
|||
|
|
SignFieldStyle: SignFieldStyleNormal,
|
|||
|
|
SignFieldPosition: &SignFieldPosition{
|
|||
|
|
PositionPage: "1",
|
|||
|
|
PositionX: 458,
|
|||
|
|
PositionY: 200,
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// buildSignFlowConfig 构建签署流程配置
|
|||
|
|
func (s *SignFlowService) buildSignFlowConfig() SignFlowConfig {
|
|||
|
|
return SignFlowConfig{
|
|||
|
|
SignFlowTitle: "天远数据API合作协议签署",
|
|||
|
|
SignFlowExpireTime: calculateExpireTime(7), // 7天后过期
|
|||
|
|
AutoFinish: true, // 所有签署方完成后自动完结
|
|||
|
|
AuthConfig: &AuthConfig{
|
|||
|
|
PsnAvailableAuthModes: []string{AuthModeMobile3},
|
|||
|
|
WillingnessAuthModes: []string{WillingnessAuthSMS},
|
|||
|
|
},
|
|||
|
|
ContractConfig: &ContractConfig{
|
|||
|
|
AllowToRescind: false,
|
|||
|
|
},
|
|||
|
|
}
|
|||
|
|
}
|