| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285 |
- package qiyuesuosdk
- import (
- "encoding/base64"
- "errors"
- "strconv"
- "strings"
- v2seal_request "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/v2seal/request"
- v2seal_response "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/v2seal/response"
- "git.sxidc.com/student-physical-examination/contract_lock_sdk/model/common"
- )
- // DeriveCompanySealName 根据机构名称推导契约锁公章名称(与制章/授权逻辑一致)。
- func DeriveCompanySealName(companyDisplayName string) string {
- sealName := strings.TrimSpace(companyDisplayName)
- if sealName == "" {
- return "机构公章"
- }
- if !strings.Contains(sealName, "章") {
- sealName += "公章"
- }
- return sealName
- }
- // CompanySealImage 下载机构电子公章图片(PNG)。
- func (c *Client) CompanySealImage(company CompanyLocateParams, sealName string) ([]byte, string, error) {
- sealName = strings.TrimSpace(sealName)
- if sealName == "" {
- return nil, "", ErrInvalidParams
- }
- body := map[string]any{
- "sealName": sealName,
- "sealAttribute": "ELECTRONIC",
- "sealImageFormatRequest": map[string]any{
- "imageFormat": "png",
- },
- }
- if company.ID != "" {
- body["companyId"] = company.ID
- }
- if company.Name != "" {
- body["companyName"] = company.Name
- }
- if company.RegisterNo != "" {
- body["registerNo"] = company.RegisterNo
- }
- data, contentType, err := c.postForImageBytes("/seal/customparam/image", body)
- if err != nil {
- return nil, "", err
- }
- if len(data) == 0 {
- return nil, "", ErrSealImageUnavailable
- }
- return data, contentType, nil
- }
- // CompanySealImageBase64 下载机构公章并返回标准 Base64(不含 data: 前缀)。
- func (c *Client) CompanySealImageBase64(company CompanyLocateParams, sealName string) (string, string, error) {
- data, contentType, err := c.CompanySealImage(company, sealName)
- if err != nil {
- return "", "", err
- }
- 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"`
- SM2Cert bool `json:"sm2Cert"`
- RSACert bool `json:"rsaCert"`
- }
- type companySignQualificationsResp struct {
- apiResponse
- Result CompanySignQualifications `json:"result"`
- }
- type sealCreateResp struct {
- apiResponse
- Result v2seal_response.V2SealCreateResponse `json:"result"`
- }
- // UserPortalURL 由开放平台 API 地址推导用户前台地址(制章/登录)。
- func UserPortalURL(apiAddress string) string {
- addr := strings.TrimRight(apiAddress, "/")
- if strings.Contains(addr, ":9182") {
- return strings.Replace(addr, ":9182", ":9180", 1)
- }
- return addr
- }
- // CompanySignQualificationsFor 查询法人单位是否具备电子印章等签章资质。
- func (c *Client) CompanySignQualificationsFor(company CompanyLocateParams) (*CompanySignQualifications, error) {
- companyReq, err := company.toCompanyRequest()
- if err != nil {
- return nil, err
- }
- var resp companySignQualificationsResp
- if err := c.postJSON("/company/sign/qualifications", map[string]any{
- "companyRequest": companyReq,
- }, &resp); err != nil {
- return nil, err
- }
- if err := resp.err(); err != nil {
- return nil, err
- }
- return &resp.Result, nil
- }
- // CompanySealCreatePageURL 获取制作电子公章的页面链接(method=page)。
- func (c *Client) CompanySealCreatePageURL(company CompanyLocateParams, companyDisplayName, sealName, operatorMobile string) (string, error) {
- if sealName == "" || operatorMobile == "" {
- return "", ErrInvalidParams
- }
- displayName := companyDisplayName
- if displayName == "" {
- displayName = company.Name
- }
- comp := &common.Company{Name: displayName}
- if company.RegisterNo != "" {
- comp.RegisterNo = company.RegisterNo
- }
- if company.ID != "" {
- if id, err := strconv.ParseInt(company.ID, 10, 64); err == nil {
- comp.Id = &id
- }
- }
- modify := true
- req := v2seal_request.V2SealCreateRequest{
- BusinessType: "ELECTRONIC",
- SealType: "COMPANY",
- Method: "page",
- Name: sealName,
- SealCategoryName: "公章",
- Company: comp,
- OperatorInfo: &common.UserInfoRequest{
- Mobile: operatorMobile,
- },
- Modify: &modify,
- }
- var resp sealCreateResp
- if err := c.postJSON("/v2/seal/create", req, &resp); err != nil {
- return "", err
- }
- if err := resp.err(); err != nil {
- return "", err
- }
- url := resp.Result.PageUrl
- if url == "" {
- url = resp.Result.LocalPageUrl
- }
- if url == "" {
- return "", ErrSealCreatePageUnavailable
- }
- return url, nil
- }
- // 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, "无可授权的印章")
- }
|