sign.go 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  1. package qiyuesuosdk
  2. import (
  3. "net/url"
  4. "strconv"
  5. contract_request "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/contract/request"
  6. "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/common"
  7. v2contract_request "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/v2contract/request"
  8. v2document_response "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/v2document/response"
  9. )
  10. // SignDocument 上传 PDF → 创建合同 → 企业静默签 → [个人静默签] → 下载。
  11. func (c *Client) SignDocument(req SignDocumentRequest) ([]byte, error) {
  12. processID := c.resolveProcessID(req.ProcessID)
  13. launcher := c.resolveLauncher(req.Launcher)
  14. if processID == "" || launcher == "" {
  15. return nil, ErrInvalidParams
  16. }
  17. docID, err := c.uploadDocument(req.Subject, req.PDF)
  18. if err != nil {
  19. return nil, err
  20. }
  21. openUserIDs := make([]string, 0, len(req.PersonalSeals))
  22. for _, p := range req.PersonalSeals {
  23. openUserIDs = append(openUserIDs, p.OpenUserID)
  24. }
  25. contractID, err := c.createContract(processID, req.Subject, launcher, docID, req.CompanySeal.CompanyName, openUserIDs)
  26. if err != nil {
  27. return nil, err
  28. }
  29. if err = c.companySilentSign(contractID, req.CompanySeal); err != nil {
  30. return nil, err
  31. }
  32. for _, p := range req.PersonalSeals {
  33. if err = c.personalSilentSign(contractID, p); err != nil {
  34. return nil, err
  35. }
  36. }
  37. return c.downloadDocument(docID)
  38. }
  39. // SignDualCompany 双企业公章签署(无个人签)。
  40. func (c *Client) SignDualCompany(req SignDualCompanyRequest) ([]byte, error) {
  41. processID := c.resolveProcessID(req.ProcessID)
  42. launcher := c.resolveLauncher(req.Launcher)
  43. if processID == "" || launcher == "" || len(req.CompanySeals) == 0 {
  44. return nil, ErrInvalidParams
  45. }
  46. docID, err := c.uploadDocument(req.Subject, req.PDF)
  47. if err != nil {
  48. return nil, err
  49. }
  50. names := make([]string, len(req.CompanySeals))
  51. for i, s := range req.CompanySeals {
  52. names[i] = s.CompanyName
  53. }
  54. contractID, err := c.createDualCompanyContract(processID, req.Subject, launcher, docID, names)
  55. if err != nil {
  56. return nil, err
  57. }
  58. for _, seal := range req.CompanySeals {
  59. if err = c.companySilentSign(contractID, seal); err != nil {
  60. return nil, err
  61. }
  62. }
  63. return c.downloadDocument(docID)
  64. }
  65. func (c *Client) uploadDocument(title string, pdf []byte) (string, error) {
  66. fields := map[string]string{
  67. "title": title,
  68. "fileType": "pdf",
  69. }
  70. var resp struct {
  71. apiResponse
  72. Result v2document_response.V2DocumentCreatebyfileResponse `json:"result"`
  73. }
  74. if err := c.postMultipart("/v2/document/createbyfile", fields, "file", pdf, &resp); err != nil {
  75. return "", err
  76. }
  77. if err := resp.err(); err != nil {
  78. return "", err
  79. }
  80. return resp.Result.DocumentId, nil
  81. }
  82. func (c *Client) createContract(processID, subject, launcher, documentID, companyName string, openUserIDs []string) (string, error) {
  83. docInt, err := strconv.ParseInt(documentID, 10, 64)
  84. if err != nil {
  85. return "", err
  86. }
  87. send := true
  88. remind := false
  89. var serialNo int64 = 1
  90. signatories := []*common.Signatory{{
  91. TenantName: companyName,
  92. TenantType: "COMPANY",
  93. SerialNo: &serialNo,
  94. Remind: &remind,
  95. }}
  96. for _, uid := range openUserIDs {
  97. serialNo++
  98. sNo := serialNo
  99. signatories = append(signatories, &common.Signatory{
  100. TenantType: "PERSONAL",
  101. SerialNo: &sNo,
  102. Remind: &remind,
  103. OpenUserId: uid,
  104. })
  105. }
  106. req := contract_request.ContractCreatebycategoryRequest{
  107. CategoryId: processID,
  108. Subject: subject,
  109. Send: &send,
  110. TenantName: launcher,
  111. Documents: []int64{docInt},
  112. Signatories: signatories,
  113. }
  114. var contractID string
  115. resp := c.sdk.ServiceAsModel(req, contractID)
  116. id, err := c.serviceString(resp)
  117. return id, err
  118. }
  119. func (c *Client) createDualCompanyContract(processID, subject, launcher, documentID string, companyNames []string) (string, error) {
  120. docInt, err := strconv.ParseInt(documentID, 10, 64)
  121. if err != nil {
  122. return "", err
  123. }
  124. send := true
  125. remind := false
  126. var serialNo int64 = 1
  127. var actionSerial int64 = 1
  128. signatories := make([]*common.Signatory, 0, len(companyNames))
  129. for _, name := range companyNames {
  130. sNo := serialNo
  131. serialNo++
  132. aNo := actionSerial
  133. signatories = append(signatories, &common.Signatory{
  134. TenantName: name,
  135. TenantType: "COMPANY",
  136. SerialNo: &sNo,
  137. Remind: &remind,
  138. Actions: []*common.Action{{
  139. Type_: "CORPORATE",
  140. SerialNo: &aNo,
  141. }},
  142. })
  143. }
  144. req := contract_request.ContractCreatebycategoryRequest{
  145. CategoryId: processID,
  146. Subject: subject,
  147. Send: &send,
  148. TenantName: launcher,
  149. Documents: []int64{docInt},
  150. Signatories: signatories,
  151. }
  152. var contractID string
  153. resp := c.sdk.ServiceAsModel(req, contractID)
  154. id, err := c.serviceString(resp)
  155. return id, err
  156. }
  157. func (c *Client) companySilentSign(contractID string, spec CompanySealSpec) error {
  158. cInt, err := strconv.ParseInt(contractID, 10, 64)
  159. if err != nil {
  160. return err
  161. }
  162. stamper := &common.CompanyStamperBean{
  163. Type_: "SEAL_CORPORATE",
  164. Keyword: spec.Keyword,
  165. OffsetX: spec.OffsetX,
  166. OffsetY: spec.OffsetY,
  167. }
  168. if spec.RotateDegree != 0 {
  169. stamper.RotateDegree = &spec.RotateDegree
  170. }
  171. if spec.Page != "" {
  172. stamper.Page = spec.Page
  173. }
  174. req := v2contract_request.V2ContractSignbycompanyRequest{
  175. Contract: &common.SignSilentContract{Id: &cInt},
  176. Company: &common.CompanyRequest{Name: spec.CompanyName},
  177. SealRequest: &common.SealMultipleRequest{
  178. Company: &common.CompanyRequest{Name: spec.CompanyName},
  179. },
  180. Stampers: []*common.CompanyStamperBean{stamper},
  181. }
  182. return c.serviceOK(c.sdk.Service(req))
  183. }
  184. func (c *Client) personalSilentSign(contractID string, spec PersonalSealSpec) error {
  185. cInt, err := strconv.ParseInt(contractID, 10, 64)
  186. if err != nil {
  187. return err
  188. }
  189. width, height := 12.0, 5.0
  190. offsetX, offsetY := -30.0, 16.0
  191. useDefault := true
  192. req := v2contract_request.V2ContractSignbypersonRequest{
  193. Contract: &common.SignSilentContract{Id: &cInt},
  194. User: &common.User{OpenUserId: spec.OpenUserID},
  195. SealInfoRequest: &common.PersonSealInfoRequest{
  196. User: &common.UserInfoRequest{OpenUserId: spec.OpenUserID},
  197. DefaultPersonSignFlag: &useDefault,
  198. PersonSealCarrier: "PERSON_SIGN",
  199. },
  200. Stampers: []*common.StamperBean{{
  201. Type_: "SEAL_PERSONAL",
  202. Keyword: spec.Keyword,
  203. KeywordIndex: "0",
  204. Width: &width,
  205. Height: &height,
  206. OffsetX: &offsetX,
  207. OffsetY: &offsetY,
  208. OffsetUnit: "POINT",
  209. }},
  210. }
  211. return c.serviceOK(c.sdk.Service(req))
  212. }
  213. func (c *Client) downloadDocument(documentID string) ([]byte, error) {
  214. q := url.Values{"documentId": {documentID}}
  215. return c.download("/document/download", q)
  216. }