1 Star 0 Fork 0

wosylf/龙飞工具仓库

Create your Gitee Account
Explore and code with more than 13.5 million developers,Free private repositories !:)
Sign up
文件
Clone or Download
易签宝.go 10.43 KB
Copy Edit Raw Blame History
itlun authored 2024-08-21 11:05 +08:00 . 优化易签宝的功能
package xutil
import (
"bytes"
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"strings"
//"errors"
"fmt"
"io"
"net/http"
"os"
"strconv"
"time"
"gitee.com/wosylf/ltool"
"gitee.com/wosylf/ltool/pkg/errors"
)
const (
Host = "https://openapi.esign.cn"
TestHost = "https://smlopenapi.esign.cn"
V合同上传接口 = "/v3/files/file-upload-url"
V发起签署 = "/v3/sign-flow/create-by-file"
V签署流程_结束 = "SIGN_FLOW_COMPLETE"
)
type Esign struct {
ProjectId string //易签宝id
ProjectScert string //易签宝密钥
CompanyName string `gorm:"type:varchar(24);comment:'e签宝应用公司名'" json:"company_name,omitempty"`
CompanyNum string `gorm:"type:varchar(24);comment:'e签宝应用公司号'" json:"company_num,omitempty"`
NotifyUrl string
RedirectUrl string
Orgid string `gorm:"type:varchar(46);comment:'e签宝生成的公司id'" json:"orgid,omitempty"`
Istest bool
}
func F新建易签宝(id, scert, company_name, company_num, orgid, notifyurl, RedirectUrl string) *Esign {
return &Esign{id, scert, company_name, company_num, notifyurl, RedirectUrl, orgid, true}
}
func (e *Esign) F获取签署链接(signFlowId, psnacc string) (inte *S签署链接返回, err error) {
url := "/v3/sign-flow/" + signFlowId + "/sign-url"
bm := make(ltool.BodyMap)
bm.Set("signFlowId", signFlowId).
SetBodyMap("operator", func(b ltool.BodyMap) {
b.Set("psnAccount", psnacc)
})
inte = new(S签署链接返回)
_, err = e.SendCommHttp(url, bm.JsonBody(), "POST", inte)
if err != nil {
return
}
if inte.Code != 0 && inte.Message != "账号已存在" {
err = errors.New(inte.Message)
}
return
}
func (e *Esign) F通过文件发起签署(fileid, phone, name, idcard string) (inte *S签署信息返回, err error) {
bd := &S发起签署{
SignFlowConfig: &SignFlowConfig{
SignFlowTitle: "租赁合同",
AutoFinish: true,
NotifyUrl: e.NotifyUrl,
RedirectConfig: RedirectConfig{RedirectUrl: ""},
},
}
bd.Docs = append(bd.Docs, &Doc{
FileId: fileid,
FileName: "租赁合同",
})
//先添加企业
bd.Signers = append(bd.Signers, &Signers{
SignerType: 1,
SignConfig: &SignConfig{
SignOrder: 1,
},
SignFields: []Signfield{
{FileId: fileid,
NormalSignFieldConfig: NormalSignFieldConfig{
AutoSign: true,
SignFieldStyle: 1,
//AssignedSealId: "4de9c83a-ec02-42ea-8c9a-65a424ccaaf4",
SignFieldPosition: SignFieldPosition{
PositionPage: 1,
PositionX: 100,
PositionY: 100,
},
},
},
},
})
//添加个人
bd.Signers = append(bd.Signers, &Signers{
SignerType: 0,
SignConfig: &SignConfig{
SignOrder: 2,
},
PsnSignerInfo: &PsnSignerInfo{
PsnAccount: phone,
PsnInfo: PsnInfo{
PsnName: name,
PsnIDCardNum: idcard,
},
},
SignFields: []Signfield{
{FileId: fileid,
NormalSignFieldConfig: NormalSignFieldConfig{
SignFieldStyle: 1,
SignFieldPosition: SignFieldPosition{
PositionPage: 1,
PositionX: 200,
PositionY: 100,
},
},
},
},
})
//发起签署请求
inte = new(S签署信息返回)
_, err = e.SendCommHttp(V发起签署, bd, "POST", inte)
if err != nil {
return
}
if inte.Code != 0 {
err = errors.New(inte.Message)
}
return
}
// 创建个人账号
func (e *Esign) F创建个人账号(idc, name, phone, email string) (inte *S创建个人信息返回, err error) {
bm := make(ltool.BodyMap)
bm.Set("email", email).
Set("idNumber", idc).
Set("thirdPartyUserId", idc).
Set("mobile", phone).
Set("name", name)
apiUrl := "/v1/accounts/createByThirdPartyUserId"
inte = new(S创建个人信息返回)
_, err = e.SendCommHttp(apiUrl, bm.JsonBody(), "POST", inte)
if err != nil {
return
}
if inte.Code != 0 && inte.Message != "账号已存在" {
err = errors.New(inte.Message)
}
return
}
func (e *Esign) F查询企业认证(orgName, orgIDCardNum string) (err error) {
bm := make(ltool.BodyMap)
bm.Set("orgName", orgName).
Set("orgIDCardNum", orgIDCardNum).
Set("orgIDCardType", "CRED_ORG_USCC")
apiUrl := "/v3/organizations/identity-info"
//inte = new(S创建个人信息返回)
by, err := e.SendCommHttp(apiUrl, bm.JsonBody(), "POST", nil)
if err != nil {
return
}
fmt.Println("bu", string(by))
return
}
func (e *Esign) F查询签署情况(flowid string) (resp *S查询签署返回, err error) {
apiUrl := "/v3/sign-flow/" + flowid + "/detail"
//inte = new(S创建个人信息返回)
resp = new(S查询签署返回)
_, err = e.SendCommHttp(apiUrl, "", "GET", resp)
if err != nil {
return
}
//fmt.Println("bu", string(by))
return
}
func (e *Esign) F创建企业认证(orgName, orgIDCardNum string) (err error) {
bm := make(ltool.BodyMap)
bm.SetBodyMap("orgAuthConfig", func(b ltool.BodyMap) {
b.Set("orgName", orgName).SetBodyMap("orgInfo", func(b ltool.BodyMap) {
b.Set("orgIDCardNum", orgIDCardNum).Set("orgIDCardType", "CRED_ORG_USCC")
})
})
apiUrl := "/v3/org-auth-url"
//inte = new(S创建个人信息返回)
by, err := e.SendCommHttp(apiUrl, bm.JsonBody(), "POST", nil)
if err != nil {
return
}
fmt.Println("bu", string(by))
return
}
func (e *Esign) F获取文件位置(fileid string, keyword []string) (resp *S查找关键词返回, err error) {
文件地址 := "/v3/files/" + fileid + "/keyword-positions"
bm := make(ltool.BodyMap)
bm.Set("keywords", keyword)
resp = new(S查找关键词返回)
_, err = e.SendCommHttp(文件地址, bm.JsonBody(), "POST", resp)
//fmt.Println("errby", string(by))
if err != nil {
err = errors.WithStack(err)
}
return
}
// 获取文件上传地址
func (e *Esign) F文件上传地址获取(文件地址, filename string) (inte *S文件上传返回, err error) {
contentMd5, size := CountFileMd5(文件地址)
filetype := "application/pdf"
bm := make(ltool.BodyMap)
bm.Set("contentMd5", contentMd5).
Set("contentType", filetype).
Set("convert2Pdf", !strings.Contains(文件地址, ".pdf")).
Set("fileSize", size).
Set("fileName", 文件地址)
inte = new(S文件上传返回)
_, err = e.SendCommHttp(V合同上传接口, bm.JsonBody(), "POST", inte)
if err != nil {
return
}
if inte.Code != 0 {
err = errors.New(inte.Message)
return
}
resp, err := F上传文件(inte.Data.FileUploadUrl, 文件地址, contentMd5, filetype)
if err != nil {
return
}
if resp.ErrCode != 0 {
err = errors.New(resp.Msg)
}
fmt.Println("上传成功", resp)
inte.Data.FileUploadUrl = ""
return
}
func (e *Esign) SendCommHttp(apiUrl string, dataJsonStr interface{}, method string, inter interface{}) (by []byte, err error) {
httpUrl := Host + apiUrl
if e.Istest {
httpUrl = TestHost + apiUrl
}
str, ok := dataJsonStr.(string)
if ok {
fmt.Println("转换为字符串成功:", str)
} else {
bs, err := json.Marshal(dataJsonStr)
if err != nil {
return nil, err
}
str = string(bs)
fmt.Println("===>易签宝请求数据", str, httpUrl)
}
md5Str := DohashMd5(str)
message := AppendSignDataString(method, "*/*", md5Str, "application/json; charset=UTF-8", "", "", apiUrl)
reqSignature := DoSignatureBase64(message, e.ProjectScert)
// 初始化接口返回值
by, err = F发送请求(httpUrl, str, method, e.F获取头部参数(md5Str, reqSignature))
if err != nil {
err = errors.WithStack(err)
}
if inter != nil {
err = errors.WithStack(json.Unmarshal(by, inter))
}
return
}
// sha256摘要签名
func DoSignatureBase64(message string, secret string) string {
h := hmac.New(sha256.New, []byte(secret))
h.Write([]byte(message))
buf := h.Sum(nil)
return base64.StdEncoding.EncodeToString(buf)
}
// 拼接请求参数
func AppendSignDataString(method string, accept string, contentMD5 string, contentType string, date string, headers string, url string) string {
var buffer bytes.Buffer
buffer.WriteString(method)
buffer.WriteString("\n")
buffer.WriteString(accept)
buffer.WriteString("\n")
buffer.WriteString(contentMD5)
buffer.WriteString("\n")
buffer.WriteString(contentType)
buffer.WriteString("\n")
buffer.WriteString(date)
buffer.WriteString("\n")
if len(headers) == 0 {
buffer.WriteString(headers)
buffer.WriteString(url)
} else {
buffer.WriteString(headers)
buffer.WriteString("\n")
buffer.WriteString(url)
}
return buffer.String()
}
func (e *Esign) F获取头部参数(contentMD5 string, reqSignature string) (header map[string]string) {
headers := map[string]string{}
headers["X-Tsign-Open-App-Id"] = e.ProjectId
headers["X-Tsign-Open-Ca-Timestamp"] = strconv.FormatInt(time.Now().UnixNano()/1e6, 10)
headers["Accept"] = "*/*"
headers["X-Tsign-Open-Ca-Signature"] = reqSignature
headers["Content-MD5"] = contentMD5
headers["Content-Type"] = "application/json; charset=UTF-8"
headers["X-Tsign-Open-Auth-Mode"] = "Signature"
return headers
}
// 文件上传
func F上传文件(uploadUrl string, filePath string, contentMD5 string, contentType string) (resp *S文件上传结果, err error) {
//创建一个缓冲区对象,后面的要上传的body都存在这个缓冲区里
bodyBuf := &bytes.Buffer{}
//要上传的文件
//创建第一个需要上传的文件,filepath.Base获取文件的名称
//打开文件
fd1, _ := os.Open(filePath)
defer fd1.Close()
//把第一个文件流写入到缓冲区里去
_, _ = io.Copy(bodyBuf, fd1)
//获取请求Content-Type类型,后面有用
//contentType := bodyWriter.FormDataContentType()
//创建一个http客户端请求对象
client := &http.Client{}
//创建一个post请求
req, _ := http.NewRequest("PUT", uploadUrl, nil)
//设置请求头
req.Header.Set("Content-MD5", contentMD5)
//这里的Content-Type值就是上面contentType的值
req.Header.Set("Content-Type", contentType)
//转换类型
req.Body = io.NopCloser(bodyBuf)
//发送数据
data, _ := client.Do(req)
//读取请求返回的数据
bytes, _ := io.ReadAll(data.Body)
defer data.Body.Close()
resp = new(S文件上传结果)
if err = json.Unmarshal(bytes, resp); err != nil {
err = errors.WithStack(err)
}
//返回数据
return
}
func F发送请求(apiUrl string, data string, method string, headers map[string]string) (by []byte, err error) {
// API接口返回值by
url := apiUrl
var jsonStr = []byte(data)
var req *http.Request
if method == "GET" || method == "DELETE" {
req, err = http.NewRequest(method, url, nil)
} else {
req, err = http.NewRequest(method, url, bytes.NewBuffer(jsonStr))
}
if err != nil {
return
}
for k, v := range headers {
req.Header.Set(k, v)
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return
}
by, err = io.ReadAll(resp.Body)
return
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/wosylf/ltool.git
git@gitee.com:wosylf/ltool.git
wosylf
ltool
龙飞工具仓库
4aab2f4b94f9

Search