fadd
This commit is contained in:
262
internal/shared/fadada/template_service.go
Normal file
262
internal/shared/fadada/template_service.go
Normal file
@@ -0,0 +1,262 @@
|
||||
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
|
||||
}
|
||||
Reference in New Issue
Block a user