|
|
@@ -2,6 +2,7 @@ package qiyuesuosdk
|
|
|
|
|
|
import (
|
|
|
"encoding/base64"
|
|
|
+ "errors"
|
|
|
"strconv"
|
|
|
"strings"
|
|
|
|
|
|
@@ -63,6 +64,122 @@ func (c *Client) CompanySealImageBase64(company CompanyLocateParams, sealName st
|
|
|
return base64.StdEncoding.EncodeToString(data), contentType, nil
|
|
|
}
|
|
|
|
|
|
+// CompanySealSummary 法人单位电子印章摘要(来自 /seal/customparam/cert/list)。
|
|
|
+type CompanySealSummary struct {
|
|
|
+ ID string
|
|
|
+ Name string
|
|
|
+ Type string
|
|
|
+ SealAttribute string
|
|
|
+ StatusKey string
|
|
|
+}
|
|
|
+
|
|
|
+type sealCertListItem struct {
|
|
|
+ ID string `json:"id"`
|
|
|
+ Name string `json:"name"`
|
|
|
+ Type string `json:"type"`
|
|
|
+ SealAttribute string `json:"sealAttribute"`
|
|
|
+ Status *struct {
|
|
|
+ Key string `json:"key"`
|
|
|
+ } `json:"status"`
|
|
|
+}
|
|
|
+
|
|
|
+type sealCertListResp struct {
|
|
|
+ apiResponse
|
|
|
+ List []sealCertListItem `json:"list"`
|
|
|
+}
|
|
|
+
|
|
|
+// ListCompanyElectronicSeals 查询法人单位下状态正常的电子印章列表。
|
|
|
+func (c *Client) ListCompanyElectronicSeals(company CompanyLocateParams) ([]CompanySealSummary, error) {
|
|
|
+ companyReq, err := company.toCompanyRequest()
|
|
|
+ if err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ var resp sealCertListResp
|
|
|
+ if err := c.postJSON("/seal/customparam/cert/list", map[string]any{
|
|
|
+ "companyRequest": companyReq,
|
|
|
+ "sealAttribute": "ELECTRONIC",
|
|
|
+ "sealQueryStatus": "NORMAL",
|
|
|
+ }, &resp); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ if err := resp.err(); err != nil {
|
|
|
+ return nil, err
|
|
|
+ }
|
|
|
+ out := make([]CompanySealSummary, 0, len(resp.List))
|
|
|
+ for _, item := range resp.List {
|
|
|
+ statusKey := ""
|
|
|
+ if item.Status != nil {
|
|
|
+ statusKey = item.Status.Key
|
|
|
+ }
|
|
|
+ if statusKey != "" && statusKey != "NORMAL" {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ out = append(out, CompanySealSummary{
|
|
|
+ ID: item.ID,
|
|
|
+ Name: item.Name,
|
|
|
+ Type: item.Type,
|
|
|
+ SealAttribute: item.SealAttribute,
|
|
|
+ StatusKey: statusKey,
|
|
|
+ })
|
|
|
+ }
|
|
|
+ return out, nil
|
|
|
+}
|
|
|
+
|
|
|
+func pickCompanySeal(seals []CompanySealSummary, preferredName string) (*CompanySealSummary, error) {
|
|
|
+ if len(seals) == 0 {
|
|
|
+ return nil, ErrSealNotFound
|
|
|
+ }
|
|
|
+ preferredName = strings.TrimSpace(preferredName)
|
|
|
+ if preferredName != "" {
|
|
|
+ for i := range seals {
|
|
|
+ if seals[i].Name == preferredName {
|
|
|
+ return &seals[i], nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ for i := range seals {
|
|
|
+ if seals[i].Type == "COMPANY" {
|
|
|
+ return &seals[i], nil
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return &seals[0], nil
|
|
|
+}
|
|
|
+
|
|
|
+// SealImageByID 按印章 id 下载电子章图片。
|
|
|
+func (c *Client) SealImageByID(sealID string) ([]byte, string, error) {
|
|
|
+ sealID = strings.TrimSpace(sealID)
|
|
|
+ if sealID == "" {
|
|
|
+ return nil, "", ErrInvalidParams
|
|
|
+ }
|
|
|
+ return c.postForImageBytes("/seal/customparam/image", map[string]any{
|
|
|
+ "sealId": sealID,
|
|
|
+ "sealAttribute": "ELECTRONIC",
|
|
|
+ "sealImageFormatRequest": map[string]any{
|
|
|
+ "imageFormat": "png",
|
|
|
+ },
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+// ResolveCompanySealImageBase64 先列出法人单位电子章,再按 sealId 拉图(避免印章名不一致)。
|
|
|
+func (c *Client) ResolveCompanySealImageBase64(company CompanyLocateParams, preferredSealName string) (string, string, string, error) {
|
|
|
+ seals, err := c.ListCompanyElectronicSeals(company)
|
|
|
+ if err != nil {
|
|
|
+ return "", "", "", err
|
|
|
+ }
|
|
|
+ seal, err := pickCompanySeal(seals, preferredSealName)
|
|
|
+ if err != nil {
|
|
|
+ return "", "", "", err
|
|
|
+ }
|
|
|
+ data, contentType, err := c.SealImageByID(seal.ID)
|
|
|
+ if err != nil {
|
|
|
+ return "", "", "", err
|
|
|
+ }
|
|
|
+ if len(data) == 0 {
|
|
|
+ return "", "", "", ErrSealImageUnavailable
|
|
|
+ }
|
|
|
+ return seal.Name, base64.StdEncoding.EncodeToString(data), contentType, nil
|
|
|
+}
|
|
|
+
|
|
|
// CompanySignQualifications 法人单位签章资质(是否已有可用电子章等)。
|
|
|
type CompanySignQualifications struct {
|
|
|
ElectronicSeal bool `json:"electronicSeal"`
|
|
|
@@ -155,11 +272,14 @@ func (c *Client) CompanySealCreatePageURL(company CompanyLocateParams, companyDi
|
|
|
return url, nil
|
|
|
}
|
|
|
|
|
|
-// IsSealNotFoundError 静默授权时「查询的印章不存在」。
|
|
|
+// IsSealNotFoundError 静默授权或查章时「查询的印章不存在」。
|
|
|
func IsSealNotFoundError(err error) bool {
|
|
|
if err == nil {
|
|
|
return false
|
|
|
}
|
|
|
+ if errors.Is(err, ErrSealNotFound) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
msg := err.Error()
|
|
|
return strings.Contains(msg, "查询的印章不存在") || strings.Contains(msg, "无可授权的印章")
|
|
|
}
|