f
This commit is contained in:
@@ -3,6 +3,7 @@ package entities
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"tyapi-server/internal/domains/certification/entities/value_objects"
|
||||
@@ -28,15 +29,17 @@ type Certification struct {
|
||||
CompletedAt *time.Time `json:"completed_at,omitempty" comment:"认证完成时间"`
|
||||
ContractFileCreatedAt *time.Time `json:"contract_file_created_at,omitempty" comment:"合同文件生成时间"`
|
||||
|
||||
// === e签宝相关信息 ===
|
||||
// === 签署平台(esign | fadada)===
|
||||
SignPlatform enums.SignPlatform `gorm:"type:varchar(20);index" json:"sign_platform,omitempty" comment:"签署平台: esign|fadada"`
|
||||
|
||||
// === 第三方认证/签署信息(字段名历史兼容,语义为平台无关)===
|
||||
AuthFlowID string `gorm:"type:varchar(500)" json:"auth_flow_id,omitempty" comment:"企业认证流程ID"`
|
||||
AuthURL string `gorm:"type:varchar(500)" json:"auth_url,omitempty" comment:"企业认证链接"`
|
||||
AuthURL string `gorm:"type:text" json:"auth_url,omitempty" comment:"企业认证链接"`
|
||||
ContractCode string `gorm:"type:varchar(100)" json:"contract_code,omitempty" comment:"合同/协议编号"`
|
||||
ContractFileID string `gorm:"type:varchar(500)" json:"contract_file_id,omitempty" comment:"合同文件ID"`
|
||||
EsignFlowID string `gorm:"type:varchar(500)" json:"esign_flow_id,omitempty" comment:"签署流程ID"`
|
||||
ContractURL string `gorm:"type:varchar(500)" json:"contract_url,omitempty" comment:"合同文件访问链接"`
|
||||
ContractSignURL string `gorm:"type:varchar(500)" json:"contract_sign_url,omitempty" comment:"合同签署链接"`
|
||||
// ContractCode 合作协议编号(与电子合同模板控件 xybh 一致,签署完成后写入用户域合同)
|
||||
ContractCode string `gorm:"type:varchar(255)" json:"contract_code,omitempty" comment:"合作协议编号"`
|
||||
EsignFlowID string `gorm:"type:varchar(500)" json:"esign_flow_id,omitempty" comment:"签署流程ID(兼容字段名)"`
|
||||
ContractURL string `gorm:"type:text" json:"contract_url,omitempty" comment:"合同文件访问链接(法大大下载链可能很长)"`
|
||||
ContractSignURL string `gorm:"type:text" json:"contract_sign_url,omitempty" comment:"合同签署链接(短链/长链)"`
|
||||
|
||||
// === 失败信息 ===
|
||||
FailureReason enums.FailureReason `gorm:"type:varchar(100)" json:"failure_reason,omitempty" comment:"失败原因"`
|
||||
@@ -319,8 +322,12 @@ func (c *Certification) ApplyContract(EsignFlowID string, ContractSignURL string
|
||||
if err := c.TransitionTo(enums.StatusContractApplied, enums.ActorTypeUser, c.UserID, "用户申请合同签署"); err != nil {
|
||||
return err
|
||||
}
|
||||
c.EsignFlowID = EsignFlowID
|
||||
c.ContractSignURL = ContractSignURL
|
||||
if EsignFlowID != "" {
|
||||
c.EsignFlowID = EsignFlowID
|
||||
}
|
||||
if ContractSignURL != "" {
|
||||
c.ContractSignURL = ContractSignURL
|
||||
}
|
||||
now := time.Now()
|
||||
c.ContractFileCreatedAt = &now
|
||||
// 添加业务事件
|
||||
@@ -333,7 +340,19 @@ func (c *Certification) ApplyContract(EsignFlowID string, ContractSignURL string
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetContractCode 设置合作协议编号(首次生成合同时写入,后续换文件复用)
|
||||
// BindSignTask 企业认证完成后预创建签署任务(不改状态;乙方可先免签)
|
||||
func (c *Certification) BindSignTask(esignFlowID, contractSignURL string) {
|
||||
if esignFlowID != "" {
|
||||
c.EsignFlowID = esignFlowID
|
||||
}
|
||||
if contractSignURL != "" {
|
||||
c.ContractSignURL = contractSignURL
|
||||
}
|
||||
now := time.Now()
|
||||
c.ContractFileCreatedAt = &now
|
||||
}
|
||||
|
||||
// SetContractCode 设置合同/协议编号
|
||||
func (c *Certification) SetContractCode(code string) {
|
||||
c.ContractCode = code
|
||||
}
|
||||
@@ -509,13 +528,114 @@ func (c *Certification) CompleteCertification() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResolvedSignPlatform 解析签署平台(空则默认 e签宝,兼容历史数据)
|
||||
func (c *Certification) ResolvedSignPlatform() enums.SignPlatform {
|
||||
if enums.IsValidSignPlatform(c.SignPlatform) {
|
||||
return c.SignPlatform
|
||||
}
|
||||
return enums.DefaultSignPlatform()
|
||||
}
|
||||
|
||||
// ResetAfterSignTaskCreateFailed 签署任务未创建却已到 enterprise_verified 时,回退到待选平台
|
||||
func (c *Certification) ResetAfterSignTaskCreateFailed() error {
|
||||
if c.Status != enums.StatusEnterpriseVerified {
|
||||
return fmt.Errorf("当前状态 %s 无需回退", enums.GetStatusName(c.Status))
|
||||
}
|
||||
if strings.TrimSpace(c.EsignFlowID) != "" {
|
||||
return fmt.Errorf("签署任务已存在,不能回退到选平台")
|
||||
}
|
||||
c.Status = enums.StatusInfoPendingReview
|
||||
c.SignPlatform = ""
|
||||
c.AuthURL = ""
|
||||
c.AuthFlowID = ""
|
||||
c.ContractFileID = ""
|
||||
c.ContractURL = ""
|
||||
c.ContractSignURL = ""
|
||||
c.EsignFlowID = ""
|
||||
c.EnterpriseVerifiedAt = nil
|
||||
c.UpdatedAt = time.Now()
|
||||
return nil
|
||||
}
|
||||
|
||||
// ResetForResignContract 管理员触发重新认证:回退到 pending,用户可重新填写企业信息并走完整入驻流程
|
||||
// 不改动用户域认证标记、钱包、API Key、历史合同记录
|
||||
func (c *Certification) ResetForResignContract(actorID, reason string) error {
|
||||
switch c.Status {
|
||||
case enums.StatusCompleted, enums.StatusContractSigned, enums.StatusContractApplied,
|
||||
enums.StatusContractRejected, enums.StatusContractExpired,
|
||||
enums.StatusEnterpriseVerified, enums.StatusInfoSubmitted, enums.StatusInfoPendingReview:
|
||||
// 允许从已进入流程的各状态重置,供用户重新填写企业信息
|
||||
default:
|
||||
if c.Status == enums.StatusPending {
|
||||
return fmt.Errorf("当前已是待提交企业信息状态,无需重置")
|
||||
}
|
||||
return fmt.Errorf("当前状态 %s 不允许重新认证", enums.GetStatusName(c.Status))
|
||||
}
|
||||
|
||||
oldStatus := c.Status
|
||||
now := time.Now()
|
||||
|
||||
c.Status = enums.StatusPending
|
||||
c.SignPlatform = ""
|
||||
c.AuthFlowID = ""
|
||||
c.AuthURL = ""
|
||||
c.ContractCode = ""
|
||||
c.ContractFileID = ""
|
||||
c.EsignFlowID = ""
|
||||
c.ContractURL = ""
|
||||
c.ContractSignURL = ""
|
||||
c.InfoSubmittedAt = nil
|
||||
c.EnterpriseVerifiedAt = nil
|
||||
c.ContractAppliedAt = nil
|
||||
c.ContractSignedAt = nil
|
||||
c.CompletedAt = nil
|
||||
c.ContractFileCreatedAt = nil
|
||||
c.RetryCount = 0
|
||||
c.clearFailureInfo()
|
||||
c.updateTransitionAudit(enums.ActorTypeAdmin, actorID)
|
||||
c.UpdatedAt = now
|
||||
|
||||
c.addDomainEvent(&CertificationStatusChangedEvent{
|
||||
CertificationID: c.ID,
|
||||
UserID: c.UserID,
|
||||
FromStatus: oldStatus,
|
||||
ToStatus: enums.StatusPending,
|
||||
Actor: enums.ActorTypeAdmin,
|
||||
ActorID: actorID,
|
||||
Reason: reason,
|
||||
TransitionedAt: now,
|
||||
})
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetSignPlatform 设置签署平台(选定后锁定)
|
||||
func (c *Certification) SetSignPlatform(platform enums.SignPlatform) error {
|
||||
if !enums.IsValidSignPlatform(platform) {
|
||||
return fmt.Errorf("无效的签署平台: %s", platform)
|
||||
}
|
||||
if c.SignPlatform != "" && c.SignPlatform != platform {
|
||||
return fmt.Errorf("签署平台已选择为 %s,不可更改", enums.GetSignPlatformName(c.SignPlatform))
|
||||
}
|
||||
c.SignPlatform = platform
|
||||
return nil
|
||||
}
|
||||
|
||||
// ClearSignPlatform 清除已选签署平台(内部回退用)
|
||||
func (c *Certification) ClearSignPlatform() {
|
||||
c.SignPlatform = ""
|
||||
}
|
||||
|
||||
// ================ 查询方法 ================
|
||||
// GetDataByStatus 根据当前状态获取对应的数据
|
||||
func (c *Certification) GetDataByStatus() map[string]interface{} {
|
||||
data := map[string]interface{}{}
|
||||
if c.SignPlatform != "" {
|
||||
data["sign_platform"] = string(c.SignPlatform)
|
||||
data["sign_platform_name"] = enums.GetSignPlatformName(c.SignPlatform)
|
||||
}
|
||||
switch c.Status {
|
||||
case enums.StatusInfoPendingReview:
|
||||
// 待审核,无额外数据
|
||||
// 待审核/待选平台,额外元数据由应用层补充
|
||||
case enums.StatusInfoSubmitted:
|
||||
data["auth_url"] = c.AuthURL
|
||||
case enums.StatusInfoRejected:
|
||||
@@ -523,11 +643,24 @@ func (c *Certification) GetDataByStatus() map[string]interface{} {
|
||||
data["failure_message"] = c.FailureMessage
|
||||
case enums.StatusEnterpriseVerified:
|
||||
data["ContractURL"] = c.ContractURL
|
||||
data["contract_url"] = c.ContractURL
|
||||
if c.EsignFlowID != "" {
|
||||
data["esign_flow_id"] = c.EsignFlowID
|
||||
data["sign_task_ready"] = true
|
||||
}
|
||||
case enums.StatusContractApplied:
|
||||
data["contract_sign_url"] = c.ContractSignURL
|
||||
data["ContractURL"] = c.ContractURL
|
||||
data["contract_url"] = c.ContractURL
|
||||
if c.EsignFlowID != "" {
|
||||
data["esign_flow_id"] = c.EsignFlowID
|
||||
}
|
||||
case enums.StatusContractSigned:
|
||||
case enums.StatusCompleted:
|
||||
data["completed_at"] = c.CompletedAt
|
||||
if c.ContractURL != "" {
|
||||
data["contract_url"] = c.ContractURL
|
||||
}
|
||||
case enums.StatusContractRejected:
|
||||
data["failure_reason"] = c.FailureReason
|
||||
data["failure_message"] = c.FailureMessage
|
||||
|
||||
Reference in New Issue
Block a user