Files
hyapi-server/internal/shared/fadada/template_service.go
2026-07-21 15:53:29 +08:00

263 lines
7.1 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 fadada
import (
"fmt"
"strings"
"time"
)
// FillTemplate 填写文档模板并生成合同文件POST /doc-template/fill-values
func (c *Client) FillTemplate(req *ContractFillRequest) (*ContractFileResult, error) {
if err := c.config.ValidateTemplateFields(); err != nil {
return nil, err
}
if err := validateContractFillRequest(req); err != nil {
return nil, err
}
accessToken, err := c.ensureAccessToken()
if err != nil {
return nil, err
}
signDate := strings.TrimSpace(req.SignDate)
if signDate == "" {
signDate = time.Now().Format("2006年01月02日")
}
fileName := strings.TrimSpace(req.FileName)
if fileName == "" {
if c.config.Contract != nil && c.config.Contract.Name != "" {
fileName = c.config.Contract.Name
} else {
fileName = "海宇数据-合作协议"
}
fileName = fmt.Sprintf("%s-%s", fileName, strings.TrimSpace(req.AgreementNo))
}
fieldValues := c.BuildTemplateFieldValues(&ContractFillRequest{
AgreementNo: req.AgreementNo,
CompanyName: req.CompanyName,
UnifiedSocialCode: req.UnifiedSocialCode,
EnterpriseAddress: req.EnterpriseAddress,
AuthorizedRepName: req.AuthorizedRepName,
SignDate: signDate,
})
docFieldValues := make([]docFieldValue, 0, len(fieldValues))
for _, fv := range fieldValues {
docFieldValues = append(docFieldValues, docFieldValue{
FieldID: fv.FieldID,
FieldValue: fv.FieldValue,
})
}
res, err := c.http.PostBiz(pathFillDocTemplateValues, accessToken, &fillDocTemplateReq{
OwnerID: &openID{IDType: "corp", OpenID: c.config.OpenCorpID},
DocTemplateID: c.config.TemplateID,
FileName: fileName,
DocFieldValues: docFieldValues,
})
if err != nil {
return nil, err
}
if res.Code != successCode {
return nil, fmt.Errorf("法大大填写模板失败: code=%s msg=%s requestId=%s", res.Code, res.Msg, res.RequestID)
}
var data fillDocTemplateData
if err := decodeData(res.Data, &data); err != nil {
return nil, fmt.Errorf("解析模板填单响应失败: %w", err)
}
if data.FileID == "" {
return nil, fmt.Errorf("法大大填写模板失败: fileId 为空 requestId=%s", res.RequestID)
}
return &ContractFileResult{
FileID: data.FileID,
FileDownloadURL: data.FileDownloadURL,
}, nil
}
// FillSignTaskFields 向已创建的签署任务填写控件POST /sign-task/field/fill-values
func (c *Client) FillSignTaskFields(signTaskID string, req *ContractFillRequest) error {
if strings.TrimSpace(signTaskID) == "" {
return fmt.Errorf("signTaskId 不能为空")
}
if err := c.config.ValidateTemplateFields(); err != nil {
return err
}
if err := validateContractFillRequest(req); err != nil {
return err
}
accessToken, err := c.ensureAccessToken()
if err != nil {
return err
}
docID, err := c.resolveSignTaskDocID(signTaskID, accessToken)
if err != nil {
return err
}
signDate := strings.TrimSpace(req.SignDate)
if signDate == "" {
signDate = time.Now().Format("2006年01月02日")
}
fieldValues := c.BuildTemplateFieldValues(&ContractFillRequest{
AgreementNo: req.AgreementNo,
CompanyName: req.CompanyName,
UnifiedSocialCode: req.UnifiedSocialCode,
EnterpriseAddress: req.EnterpriseAddress,
AuthorizedRepName: req.AuthorizedRepName,
SignDate: signDate,
})
docFieldValues := make([]docFieldValue, 0, len(fieldValues))
for _, fv := range fieldValues {
docFieldValues = append(docFieldValues, docFieldValue{
DocID: docID,
FieldDocID: docID,
FieldID: fv.FieldID,
FieldValue: fv.FieldValue,
})
}
res, err := c.http.PostBiz(pathFillSignTaskFieldValues, accessToken, &fillSignTaskFieldsReq{
SignTaskID: signTaskID,
DocFieldValues: docFieldValues,
})
if err != nil {
return err
}
if res.Code != successCode {
return fmt.Errorf("法大大签署任务填单失败: code=%s msg=%s requestId=%s", res.Code, res.Msg, res.RequestID)
}
return nil
}
// resolveSignTaskDocID 解析签署任务文档 docId填单必填
func (c *Client) resolveSignTaskDocID(signTaskID, accessToken string) (string, error) {
if c.config != nil {
if id := strings.TrimSpace(c.config.TemplateDocID); id != "" {
return id, nil
}
}
res, err := c.http.PostBiz(pathGetSignTaskDetail, accessToken, &getSignTaskDetailReq{
SignTaskID: signTaskID,
})
if err != nil {
return "", fmt.Errorf("查询签署任务文档失败: %w", err)
}
if res.Code != successCode {
return "", fmt.Errorf("查询签署任务文档失败: code=%s msg=%s requestId=%s", res.Code, res.Msg, res.RequestID)
}
var data getSignTaskDetailData
if err := decodeData(res.Data, &data); err != nil {
return "", fmt.Errorf("解析签署任务文档失败: %w", err)
}
for _, d := range data.Docs {
if id := strings.TrimSpace(d.DocID); id != "" {
return id, nil
}
}
return "", fmt.Errorf("签署任务未返回 docId请在配置 fadada.template_doc_id 中填写模板文档ID")
}
// BuildTemplateFieldValues 将业务字段映射为法大大控件编码/值
func (c *Client) BuildTemplateFieldValues(req *ContractFillRequest) []TemplateFieldValue {
fields := c.config.TemplateFields
if fields == nil || req == nil {
return nil
}
signDate := strings.TrimSpace(req.SignDate)
agreementNo := strings.TrimSpace(req.AgreementNo)
companyName := strings.TrimSpace(req.CompanyName)
pairs := make([]struct {
fieldID string
value string
}, 0, len(fields.AgreementNo)+len(fields.PartyAName)+6)
for _, id := range fields.AgreementNo {
id = strings.TrimSpace(id)
if id == "" {
continue
}
pairs = append(pairs, struct {
fieldID string
value string
}{id, agreementNo})
}
for _, id := range fields.PartyAName {
id = strings.TrimSpace(id)
if id == "" {
continue
}
pairs = append(pairs, struct {
fieldID string
value string
}{id, companyName})
}
pairs = append(pairs,
struct {
fieldID string
value string
}{fields.ContractDate, signDate},
struct {
fieldID string
value string
}{fields.PartyAUSCC, strings.TrimSpace(req.UnifiedSocialCode)},
struct {
fieldID string
value string
}{fields.PartyAAddress, strings.TrimSpace(req.EnterpriseAddress)},
struct {
fieldID string
value string
}{fields.PartyARep, strings.TrimSpace(req.AuthorizedRepName)},
struct {
fieldID string
value string
}{fields.PartyASignDate, signDate},
struct {
fieldID string
value string
}{fields.PartyBSignDate, signDate},
)
out := make([]TemplateFieldValue, 0, len(pairs))
for _, p := range pairs {
if p.fieldID == "" {
continue
}
out = append(out, TemplateFieldValue{
FieldID: p.fieldID,
FieldValue: p.value,
})
}
return out
}
func validateContractFillRequest(req *ContractFillRequest) error {
if req == nil {
return fmt.Errorf("合同填单请求不能为空")
}
if strings.TrimSpace(req.AgreementNo) == "" {
return fmt.Errorf("协议编号不能为空")
}
if strings.TrimSpace(req.CompanyName) == "" {
return fmt.Errorf("甲方企业名不能为空")
}
if strings.TrimSpace(req.UnifiedSocialCode) == "" {
return fmt.Errorf("甲方统一信用代码不能为空")
}
if strings.TrimSpace(req.AuthorizedRepName) == "" {
return fmt.Errorf("甲方授权代表不能为空")
}
return nil
}