package qiyuesuosdk import ( "net/url" "strconv" contract_request "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/contract/request" "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/common" v2contract_request "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/v2contract/request" v2document_response "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/v2document/response" ) // SignDocument 上传 PDF → 创建合同 → 企业静默签 → [个人静默签] → 下载。 func (c *Client) SignDocument(req SignDocumentRequest) ([]byte, error) { processID := c.resolveProcessID(req.ProcessID) launcher := c.resolveLauncher(req.Launcher) if processID == "" || launcher == "" { return nil, ErrInvalidParams } docID, err := c.uploadDocument(req.Subject, req.PDF) if err != nil { return nil, err } openUserIDs := make([]string, 0, len(req.PersonalSeals)) for _, p := range req.PersonalSeals { openUserIDs = append(openUserIDs, p.OpenUserID) } contractID, err := c.createContract(processID, req.Subject, launcher, docID, req.CompanySeal.CompanyName, openUserIDs) if err != nil { return nil, err } if err = c.companySilentSign(contractID, req.CompanySeal); err != nil { return nil, err } for _, p := range req.PersonalSeals { if err = c.personalSilentSign(contractID, p); err != nil { return nil, err } } return c.downloadDocument(docID) } // SignDualCompany 双企业公章签署(无个人签)。 func (c *Client) SignDualCompany(req SignDualCompanyRequest) ([]byte, error) { processID := c.resolveProcessID(req.ProcessID) launcher := c.resolveLauncher(req.Launcher) if processID == "" || launcher == "" || len(req.CompanySeals) == 0 { return nil, ErrInvalidParams } docID, err := c.uploadDocument(req.Subject, req.PDF) if err != nil { return nil, err } names := make([]string, len(req.CompanySeals)) for i, s := range req.CompanySeals { names[i] = s.CompanyName } contractID, err := c.createDualCompanyContract(processID, req.Subject, launcher, docID, names) if err != nil { return nil, err } for _, seal := range req.CompanySeals { if err = c.companySilentSign(contractID, seal); err != nil { return nil, err } } return c.downloadDocument(docID) } func (c *Client) uploadDocument(title string, pdf []byte) (string, error) { fields := map[string]string{ "title": title, "fileType": "pdf", } var resp struct { apiResponse Result v2document_response.V2DocumentCreatebyfileResponse `json:"result"` } if err := c.postMultipart("/v2/document/createbyfile", fields, "file", pdf, &resp); err != nil { return "", err } if err := resp.err(); err != nil { return "", err } return resp.Result.DocumentId, nil } func (c *Client) createContract(processID, subject, launcher, documentID, companyName string, openUserIDs []string) (string, error) { docInt, err := strconv.ParseInt(documentID, 10, 64) if err != nil { return "", err } send := true remind := false var serialNo int64 = 1 signatories := []*common.Signatory{{ TenantName: companyName, TenantType: "COMPANY", SerialNo: &serialNo, Remind: &remind, }} for _, uid := range openUserIDs { serialNo++ sNo := serialNo signatories = append(signatories, &common.Signatory{ TenantType: "PERSONAL", SerialNo: &sNo, Remind: &remind, OpenUserId: uid, }) } req := contract_request.ContractCreatebycategoryRequest{ CategoryId: processID, Subject: subject, Send: &send, TenantName: launcher, Documents: []int64{docInt}, Signatories: signatories, } var contractID string resp := c.sdk.ServiceAsModel(req, contractID) id, err := c.serviceString(resp) return id, err } func (c *Client) createDualCompanyContract(processID, subject, launcher, documentID string, companyNames []string) (string, error) { docInt, err := strconv.ParseInt(documentID, 10, 64) if err != nil { return "", err } send := true remind := false var serialNo int64 = 1 var actionSerial int64 = 1 signatories := make([]*common.Signatory, 0, len(companyNames)) for _, name := range companyNames { sNo := serialNo serialNo++ aNo := actionSerial signatories = append(signatories, &common.Signatory{ TenantName: name, TenantType: "COMPANY", SerialNo: &sNo, Remind: &remind, Actions: []*common.Action{{ Type_: "CORPORATE", SerialNo: &aNo, }}, }) } req := contract_request.ContractCreatebycategoryRequest{ CategoryId: processID, Subject: subject, Send: &send, TenantName: launcher, Documents: []int64{docInt}, Signatories: signatories, } var contractID string resp := c.sdk.ServiceAsModel(req, contractID) id, err := c.serviceString(resp) return id, err } func (c *Client) companySilentSign(contractID string, spec CompanySealSpec) error { cInt, err := strconv.ParseInt(contractID, 10, 64) if err != nil { return err } stamper := &common.CompanyStamperBean{ Type_: "SEAL_CORPORATE", Keyword: spec.Keyword, OffsetX: spec.OffsetX, OffsetY: spec.OffsetY, } if spec.RotateDegree != 0 { stamper.RotateDegree = &spec.RotateDegree } if spec.Page != "" { stamper.Page = spec.Page } req := v2contract_request.V2ContractSignbycompanyRequest{ Contract: &common.SignSilentContract{Id: &cInt}, Company: &common.CompanyRequest{Name: spec.CompanyName}, SealRequest: &common.SealMultipleRequest{ Company: &common.CompanyRequest{Name: spec.CompanyName}, }, Stampers: []*common.CompanyStamperBean{stamper}, } return c.serviceOK(c.sdk.Service(req)) } func (c *Client) personalSilentSign(contractID string, spec PersonalSealSpec) error { cInt, err := strconv.ParseInt(contractID, 10, 64) if err != nil { return err } width, height := 12.0, 5.0 offsetX, offsetY := -30.0, 16.0 useDefault := true req := v2contract_request.V2ContractSignbypersonRequest{ Contract: &common.SignSilentContract{Id: &cInt}, User: &common.User{OpenUserId: spec.OpenUserID}, SealInfoRequest: &common.PersonSealInfoRequest{ User: &common.UserInfoRequest{OpenUserId: spec.OpenUserID}, DefaultPersonSignFlag: &useDefault, PersonSealCarrier: "PERSON_SIGN", }, Stampers: []*common.StamperBean{{ Type_: "SEAL_PERSONAL", Keyword: spec.Keyword, KeywordIndex: "0", Width: &width, Height: &height, OffsetX: &offsetX, OffsetY: &offsetY, OffsetUnit: "POINT", }}, } return c.serviceOK(c.sdk.Service(req)) } func (c *Client) downloadDocument(documentID string) ([]byte, error) { q := url.Values{"documentId": {documentID}} return c.download("/document/download", q) }