Files
2026-07-21 15:53:29 +08:00

205 lines
5.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package esign
import (
"context"
"encoding/json"
"fmt"
"strings"
"hyapi-server/internal/domains/certification/enums"
"hyapi-server/internal/domains/certification/ports"
sharedesign "hyapi-server/internal/shared/esign"
)
type Provider struct {
client *sharedesign.Client
}
func NewProvider(client *sharedesign.Client) *Provider {
return &Provider{client: client}
}
func (p *Provider) Platform() enums.SignPlatform {
return enums.SignPlatformEsign
}
func (p *Provider) GenerateEnterpriseAuth(ctx context.Context, req *ports.EnterpriseAuthRequest) (*ports.AuthLinkResult, error) {
_ = ctx
res, err := p.client.GenerateEnterpriseAuth(&sharedesign.EnterpriseAuthRequest{
CompanyName: req.CompanyName,
UnifiedSocialCode: req.UnifiedSocialCode,
LegalPersonName: req.LegalPersonName,
LegalPersonID: req.LegalPersonID,
TransactorName: req.TransactorName,
TransactorMobile: req.TransactorMobile,
TransactorID: req.TransactorID,
})
if err != nil {
return nil, err
}
return &ports.AuthLinkResult{
AuthFlowID: res.AuthFlowID,
AuthURL: res.AuthURL,
AuthShortURL: firstNonEmpty(res.AuthShortURL, res.AuthURL),
}, nil
}
func (p *Provider) QueryOrgVerified(ctx context.Context, req *ports.OrgIdentityQuery) (bool, error) {
_ = ctx
identity, err := p.client.QueryOrgIdentityInfo(&sharedesign.QueryOrgIdentityRequest{
OrgName: req.OrgName,
OrgIDCardNum: req.OrgIdentNo,
})
if err != nil {
return false, err
}
return identity != nil && identity.Data.RealnameStatus == 1, nil
}
func (p *Provider) GenerateContractFile(ctx context.Context, req *ports.ContractGenerateRequest) (*ports.ContractFileResult, error) {
_ = ctx
components := map[string]string{
"jfqym": req.CompanyName,
"jfqym2": req.CompanyName,
"jfsqdb": req.AuthorizedRepName,
"jftyshxydm": req.UnifiedSocialCode,
"jflxdz": req.EnterpriseAddress,
"xybh": req.AgreementNo,
"qsrq1": req.SignDate,
"qsrq3": req.SignDate,
"qsrq2": req.SignDate,
}
res, err := p.client.FillTemplate(components)
if err != nil {
return nil, err
}
return &ports.ContractFileResult{
FileID: res.FileID,
FileDownloadURL: res.FileDownloadUrl,
}, nil
}
func (p *Provider) CreateSignFlow(ctx context.Context, req *ports.SignFlowCreateRequest) (*ports.SignFlowResult, error) {
_ = ctx
flowID, err := p.client.CreateSignFlow(&sharedesign.CreateSignFlowRequest{
FileID: req.FileID,
SignerAccount: req.PartyAUSCC,
SignerName: req.PartyAName,
TransactorPhone: req.TransactorMobile,
TransactorName: req.TransactorName,
TransactorIDCardNum: req.TransactorID,
})
if err != nil {
return nil, err
}
if req.SkipActorURL {
return &ports.SignFlowResult{SignFlowID: flowID}, nil
}
longURL, shortURL, err := p.client.GetSignURL(flowID, req.TransactorMobile, req.PartyAName)
if err != nil {
return nil, err
}
return &ports.SignFlowResult{
SignFlowID: flowID,
SignURL: firstNonEmpty(longURL, shortURL),
ShortURL: shortURL,
}, nil
}
func (p *Provider) GetActorSignURL(ctx context.Context, req *ports.GetActorSignURLRequest) (*ports.ActorSignURLResult, error) {
_ = ctx
if req == nil || strings.TrimSpace(req.SignFlowID) == "" {
return nil, fmt.Errorf("signFlowId 不能为空")
}
longURL, shortURL, err := p.client.GetSignURL(req.SignFlowID, req.TransactorMobile, req.PartyAName)
if err != nil {
return nil, err
}
return &ports.ActorSignURLResult{
SignFlowID: req.SignFlowID,
EmbedURL: firstNonEmpty(longURL, shortURL),
ShortURL: shortURL,
}, nil
}
func (p *Provider) GetSignTaskPreviewURL(ctx context.Context, signFlowID string) (*ports.SignTaskPreviewURLResult, error) {
_ = ctx
// e签宝无独立预览接口用已签/合同文件下载链作为预览源(前端用 PDF 打开)
files, err := p.DownloadSignedFiles(ctx, signFlowID)
if err != nil {
return nil, err
}
if len(files) == 0 || strings.TrimSpace(files[0].DownloadURL) == "" {
return nil, fmt.Errorf("未获取到可预览的合同文件")
}
return &ports.SignTaskPreviewURLResult{
SignFlowID: signFlowID,
PreviewURL: files[0].DownloadURL,
}, nil
}
func (p *Provider) QuerySignStatus(ctx context.Context, flowID string) (*ports.SignStatusResult, error) {
_ = ctx
detail, err := p.client.QuerySignFlowDetail(flowID)
if err != nil {
return nil, err
}
status := detail.Data.SignFlowStatus
return &ports.SignStatusResult{
SignFlowID: flowID,
Status: fmt.Sprintf("%d", status),
Completed: status == 2,
Rejected: status == 7,
Expired: status == 5,
Message: detail.Data.SignFlowDescription,
}, nil
}
func (p *Provider) DownloadSignedFiles(ctx context.Context, flowID string) ([]*ports.SignedFile, error) {
_ = ctx
res, err := p.client.DownloadSignedFile(flowID)
if err != nil {
return nil, err
}
files := make([]*ports.SignedFile, 0, len(res.Data.Files))
for _, f := range res.Data.Files {
files = append(files, &ports.SignedFile{DownloadURL: f.DownloadUrl})
}
return files, nil
}
func (p *Provider) VerifyCallback(ctx context.Context, headers map[string]string, body []byte) error {
_ = ctx
_ = headers
_ = body
// e签宝现有回调走独立验签逻辑此处保持兼容由原 HandleEsignCallback 处理)
return nil
}
func (p *Provider) ParseCallback(ctx context.Context, headers map[string]string, body []byte) (*ports.CallbackEvent, error) {
_ = ctx
_ = headers
var raw map[string]interface{}
_ = json.Unmarshal(body, &raw)
action, _ := raw["action"].(string)
ev := &ports.CallbackEvent{Event: action, Raw: raw}
if action == "AUTH_PASS" {
ev.AuthPassed = true
}
if action == "SIGN_FLOW_COMPLETE" || action == "SIGN_MISSON_COMPLETE" {
ev.SignCompleted = true
}
return ev, nil
}
func firstNonEmpty(values ...string) string {
for _, v := range values {
if strings.TrimSpace(v) != "" {
return v
}
}
return ""
}
var _ ports.SignPlatformProvider = (*Provider)(nil)