seal.go 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. package qiyuesuosdk
  2. import (
  3. "encoding/base64"
  4. "strconv"
  5. "strings"
  6. v2seal_request "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/v2seal/request"
  7. v2seal_response "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/v2seal/response"
  8. "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/common"
  9. )
  10. // DeriveCompanySealName 根据机构名称推导契约锁公章名称(与制章/授权逻辑一致)。
  11. func DeriveCompanySealName(companyDisplayName string) string {
  12. sealName := strings.TrimSpace(companyDisplayName)
  13. if sealName == "" {
  14. return "机构公章"
  15. }
  16. if !strings.Contains(sealName, "章") {
  17. sealName += "公章"
  18. }
  19. return sealName
  20. }
  21. // CompanySealImage 下载机构电子公章图片(PNG)。
  22. func (c *Client) CompanySealImage(company CompanyLocateParams, sealName string) ([]byte, string, error) {
  23. sealName = strings.TrimSpace(sealName)
  24. if sealName == "" {
  25. return nil, "", ErrInvalidParams
  26. }
  27. body := map[string]any{
  28. "sealName": sealName,
  29. "sealAttribute": "ELECTRONIC",
  30. "sealImageFormatRequest": map[string]any{
  31. "imageFormat": "png",
  32. },
  33. }
  34. if company.ID != "" {
  35. body["companyId"] = company.ID
  36. }
  37. if company.Name != "" {
  38. body["companyName"] = company.Name
  39. }
  40. if company.RegisterNo != "" {
  41. body["registerNo"] = company.RegisterNo
  42. }
  43. data, contentType, err := c.postForImageBytes("/seal/customparam/image", body)
  44. if err != nil {
  45. return nil, "", err
  46. }
  47. if len(data) == 0 {
  48. return nil, "", ErrSealImageUnavailable
  49. }
  50. return data, contentType, nil
  51. }
  52. // CompanySealImageBase64 下载机构公章并返回标准 Base64(不含 data: 前缀)。
  53. func (c *Client) CompanySealImageBase64(company CompanyLocateParams, sealName string) (string, string, error) {
  54. data, contentType, err := c.CompanySealImage(company, sealName)
  55. if err != nil {
  56. return "", "", err
  57. }
  58. return base64.StdEncoding.EncodeToString(data), contentType, nil
  59. }
  60. // CompanySignQualifications 法人单位签章资质(是否已有可用电子章等)。
  61. type CompanySignQualifications struct {
  62. ElectronicSeal bool `json:"electronicSeal"`
  63. SM2Cert bool `json:"sm2Cert"`
  64. RSACert bool `json:"rsaCert"`
  65. }
  66. type companySignQualificationsResp struct {
  67. apiResponse
  68. Result CompanySignQualifications `json:"result"`
  69. }
  70. type sealCreateResp struct {
  71. apiResponse
  72. Result v2seal_response.V2SealCreateResponse `json:"result"`
  73. }
  74. // UserPortalURL 由开放平台 API 地址推导用户前台地址(制章/登录)。
  75. func UserPortalURL(apiAddress string) string {
  76. addr := strings.TrimRight(apiAddress, "/")
  77. if strings.Contains(addr, ":9182") {
  78. return strings.Replace(addr, ":9182", ":9180", 1)
  79. }
  80. return addr
  81. }
  82. // CompanySignQualificationsFor 查询法人单位是否具备电子印章等签章资质。
  83. func (c *Client) CompanySignQualificationsFor(company CompanyLocateParams) (*CompanySignQualifications, error) {
  84. companyReq, err := company.toCompanyRequest()
  85. if err != nil {
  86. return nil, err
  87. }
  88. var resp companySignQualificationsResp
  89. if err := c.postJSON("/company/sign/qualifications", map[string]any{
  90. "companyRequest": companyReq,
  91. }, &resp); err != nil {
  92. return nil, err
  93. }
  94. if err := resp.err(); err != nil {
  95. return nil, err
  96. }
  97. return &resp.Result, nil
  98. }
  99. // CompanySealCreatePageURL 获取制作电子公章的页面链接(method=page)。
  100. func (c *Client) CompanySealCreatePageURL(company CompanyLocateParams, companyDisplayName, sealName, operatorMobile string) (string, error) {
  101. if sealName == "" || operatorMobile == "" {
  102. return "", ErrInvalidParams
  103. }
  104. displayName := companyDisplayName
  105. if displayName == "" {
  106. displayName = company.Name
  107. }
  108. comp := &common.Company{Name: displayName}
  109. if company.RegisterNo != "" {
  110. comp.RegisterNo = company.RegisterNo
  111. }
  112. if company.ID != "" {
  113. if id, err := strconv.ParseInt(company.ID, 10, 64); err == nil {
  114. comp.Id = &id
  115. }
  116. }
  117. modify := true
  118. req := v2seal_request.V2SealCreateRequest{
  119. BusinessType: "ELECTRONIC",
  120. SealType: "COMPANY",
  121. Method: "page",
  122. Name: sealName,
  123. SealCategoryName: "公章",
  124. Company: comp,
  125. OperatorInfo: &common.UserInfoRequest{
  126. Mobile: operatorMobile,
  127. },
  128. Modify: &modify,
  129. }
  130. var resp sealCreateResp
  131. if err := c.postJSON("/v2/seal/create", req, &resp); err != nil {
  132. return "", err
  133. }
  134. if err := resp.err(); err != nil {
  135. return "", err
  136. }
  137. url := resp.Result.PageUrl
  138. if url == "" {
  139. url = resp.Result.LocalPageUrl
  140. }
  141. if url == "" {
  142. return "", ErrSealCreatePageUnavailable
  143. }
  144. return url, nil
  145. }
  146. // IsSealNotFoundError 静默授权时「查询的印章不存在」。
  147. func IsSealNotFoundError(err error) bool {
  148. if err == nil {
  149. return false
  150. }
  151. msg := err.Error()
  152. return strings.Contains(msg, "查询的印章不存在") || strings.Contains(msg, "无可授权的印章")
  153. }