| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | package value_objects | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | import ( | 
					
						
							|  |  |  |  | 	"errors" | 
					
						
							|  |  |  |  | 	"fmt" | 
					
						
							|  |  |  |  | 	"regexp" | 
					
						
							|  |  |  |  | 	"strings" | 
					
						
							|  |  |  |  | 	"time" | 
					
						
							|  |  |  |  | ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ContractInfo 合同信息值对象 | 
					
						
							|  |  |  |  | // 封装电子合同相关的核心信息,包含合同状态和签署流程管理 | 
					
						
							|  |  |  |  | type ContractInfo struct { | 
					
						
							|  |  |  |  | 	// 合同基本信息 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 	ContractFileID  string `json:"contract_file_id"`  // 合同文件ID | 
					
						
							|  |  |  |  | 	EsignFlowID     string `json:"esign_flow_id"`     // e签宝签署流程ID | 
					
						
							|  |  |  |  | 	ContractURL     string `json:"contract_url"`      // 合同文件访问链接 | 
					
						
							|  |  |  |  | 	ContractSignURL string `json:"contract_sign_url"` // 合同签署链接 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 合同元数据 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 	ContractTitle   string `json:"contract_title"`   // 合同标题 | 
					
						
							|  |  |  |  | 	ContractVersion string `json:"contract_version"` // 合同版本 | 
					
						
							|  |  |  |  | 	TemplateID      string `json:"template_id"`      // 模板ID | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 签署相关信息 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 	SignerAccount       string `json:"signer_account"`         // 签署人账号 | 
					
						
							|  |  |  |  | 	SignerName          string `json:"signer_name"`            // 签署人姓名 | 
					
						
							|  |  |  |  | 	TransactorPhone     string `json:"transactor_phone"`       // 经办人手机号 | 
					
						
							|  |  |  |  | 	TransactorName      string `json:"transactor_name"`        // 经办人姓名 | 
					
						
							|  |  |  |  | 	TransactorIDCardNum string `json:"transactor_id_card_num"` // 经办人身份证号 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 时间信息 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 	GeneratedAt       *time.Time `json:"generated_at,omitempty"`         // 合同生成时间 | 
					
						
							|  |  |  |  | 	SignFlowCreatedAt *time.Time `json:"sign_flow_created_at,omitempty"` // 签署流程创建时间 | 
					
						
							|  |  |  |  | 	SignedAt          *time.Time `json:"signed_at,omitempty"`            // 签署完成时间 | 
					
						
							|  |  |  |  | 	ExpiresAt         *time.Time `json:"expires_at,omitempty"`           // 签署链接过期时间 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 状态信息 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 	Status       string `json:"status"`        // 合同状态 | 
					
						
							|  |  |  |  | 	SignProgress int    `json:"sign_progress"` // 签署进度 | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 附加信息 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 	Metadata map[string]interface{} `json:"metadata,omitempty"` // 元数据 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ContractStatus 合同状态常量 | 
					
						
							|  |  |  |  | const ( | 
					
						
							|  |  |  |  | 	ContractStatusDraft     = "draft"     // 草稿 | 
					
						
							|  |  |  |  | 	ContractStatusGenerated = "generated" // 已生成 | 
					
						
							|  |  |  |  | 	ContractStatusSigning   = "signing"   // 签署中 | 
					
						
							|  |  |  |  | 	ContractStatusSigned    = "signed"    // 已签署 | 
					
						
							|  |  |  |  | 	ContractStatusExpired   = "expired"   // 已过期 | 
					
						
							|  |  |  |  | 	ContractStatusRejected  = "rejected"  // 被拒绝 | 
					
						
							|  |  |  |  | 	ContractStatusCancelled = "cancelled" // 已取消 | 
					
						
							|  |  |  |  | ) | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // NewContractInfo 创建合同信息值对象 | 
					
						
							|  |  |  |  | func NewContractInfo(contractFileID, esignFlowID, contractURL, contractSignURL string) (*ContractInfo, error) { | 
					
						
							|  |  |  |  | 	info := &ContractInfo{ | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 		ContractFileID:  strings.TrimSpace(contractFileID), | 
					
						
							|  |  |  |  | 		EsignFlowID:     strings.TrimSpace(esignFlowID), | 
					
						
							|  |  |  |  | 		ContractURL:     strings.TrimSpace(contractURL), | 
					
						
							|  |  |  |  | 		ContractSignURL: strings.TrimSpace(contractSignURL), | 
					
						
							|  |  |  |  | 		Status:          ContractStatusGenerated, | 
					
						
							|  |  |  |  | 		SignProgress:    0, | 
					
						
							|  |  |  |  | 		Metadata:        make(map[string]interface{}), | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	if err := info.Validate(); err != nil { | 
					
						
							|  |  |  |  | 		return nil, fmt.Errorf("合同信息验证失败: %w", err) | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return info, nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Validate 验证合同信息的完整性和格式 | 
					
						
							|  |  |  |  | func (c *ContractInfo) Validate() error { | 
					
						
							|  |  |  |  | 	if err := c.validateContractFileID(); err != nil { | 
					
						
							|  |  |  |  | 		return err | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	if err := c.validateEsignFlowID(); err != nil { | 
					
						
							|  |  |  |  | 		return err | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	if err := c.validateContractURL(); err != nil { | 
					
						
							|  |  |  |  | 		return err | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	if err := c.validateContractSignURL(); err != nil { | 
					
						
							|  |  |  |  | 		return err | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	if err := c.validateSignerInfo(); err != nil { | 
					
						
							|  |  |  |  | 		return err | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	if err := c.validateStatus(); err != nil { | 
					
						
							|  |  |  |  | 		return err | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // validateContractFileID 验证合同文件ID | 
					
						
							|  |  |  |  | func (c *ContractInfo) validateContractFileID() error { | 
					
						
							|  |  |  |  | 	if c.ContractFileID == "" { | 
					
						
							|  |  |  |  | 		return errors.New("合同文件ID不能为空") | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 简单的格式验证 | 
					
						
							|  |  |  |  | 	if len(c.ContractFileID) < 10 { | 
					
						
							|  |  |  |  | 		return errors.New("合同文件ID格式不正确") | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // validateEsignFlowID 验证e签宝流程ID | 
					
						
							|  |  |  |  | func (c *ContractInfo) validateEsignFlowID() error { | 
					
						
							|  |  |  |  | 	if c.EsignFlowID == "" { | 
					
						
							|  |  |  |  | 		return errors.New("e签宝流程ID不能为空") | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 简单的格式验证 | 
					
						
							|  |  |  |  | 	if len(c.EsignFlowID) < 10 { | 
					
						
							|  |  |  |  | 		return errors.New("e签宝流程ID格式不正确") | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // validateContractURL 验证合同访问链接 | 
					
						
							|  |  |  |  | func (c *ContractInfo) validateContractURL() error { | 
					
						
							|  |  |  |  | 	if c.ContractURL == "" { | 
					
						
							|  |  |  |  | 		return errors.New("合同访问链接不能为空") | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// URL格式验证 | 
					
						
							|  |  |  |  | 	urlPattern := `^https?://.*` | 
					
						
							|  |  |  |  | 	matched, err := regexp.MatchString(urlPattern, c.ContractURL) | 
					
						
							|  |  |  |  | 	if err != nil { | 
					
						
							|  |  |  |  | 		return fmt.Errorf("合同访问链接格式验证错误: %w", err) | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	if !matched { | 
					
						
							|  |  |  |  | 		return errors.New("合同访问链接格式不正确,必须以http://或https://开头") | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // validateContractSignURL 验证合同签署链接 | 
					
						
							|  |  |  |  | func (c *ContractInfo) validateContractSignURL() error { | 
					
						
							|  |  |  |  | 	if c.ContractSignURL == "" { | 
					
						
							|  |  |  |  | 		return errors.New("合同签署链接不能为空") | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// URL格式验证 | 
					
						
							|  |  |  |  | 	urlPattern := `^https?://.*` | 
					
						
							|  |  |  |  | 	matched, err := regexp.MatchString(urlPattern, c.ContractSignURL) | 
					
						
							|  |  |  |  | 	if err != nil { | 
					
						
							|  |  |  |  | 		return fmt.Errorf("合同签署链接格式验证错误: %w", err) | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	if !matched { | 
					
						
							|  |  |  |  | 		return errors.New("合同签署链接格式不正确,必须以http://或https://开头") | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // validateSignerInfo 验证签署人信息 | 
					
						
							|  |  |  |  | func (c *ContractInfo) validateSignerInfo() error { | 
					
						
							|  |  |  |  | 	// 如果有签署人信息,进行验证 | 
					
						
							|  |  |  |  | 	if c.SignerAccount != "" || c.SignerName != "" || c.TransactorPhone != "" { | 
					
						
							|  |  |  |  | 		if c.SignerAccount == "" { | 
					
						
							|  |  |  |  | 			return errors.New("签署人账号不能为空") | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 		if c.SignerName == "" { | 
					
						
							|  |  |  |  | 			return errors.New("签署人姓名不能为空") | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 		if c.TransactorPhone != "" { | 
					
						
							|  |  |  |  | 			// 手机号格式验证 | 
					
						
							|  |  |  |  | 			phonePattern := `^1[3-9]\d{9}$` | 
					
						
							|  |  |  |  | 			matched, err := regexp.MatchString(phonePattern, c.TransactorPhone) | 
					
						
							|  |  |  |  | 			if err != nil { | 
					
						
							|  |  |  |  | 				return fmt.Errorf("经办人手机号格式验证错误: %w", err) | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 			if !matched { | 
					
						
							|  |  |  |  | 				return errors.New("经办人手机号格式不正确") | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 		if c.TransactorIDCardNum != "" { | 
					
						
							|  |  |  |  | 			// 身份证号格式验证 | 
					
						
							|  |  |  |  | 			idPattern := `^[1-9]\d{5}(19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$` | 
					
						
							|  |  |  |  | 			matched, err := regexp.MatchString(idPattern, c.TransactorIDCardNum) | 
					
						
							|  |  |  |  | 			if err != nil { | 
					
						
							|  |  |  |  | 				return fmt.Errorf("经办人身份证号格式验证错误: %w", err) | 
					
						
							|  |  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 			if !matched { | 
					
						
							|  |  |  |  | 				return errors.New("经办人身份证号格式不正确") | 
					
						
							|  |  |  |  | 			} | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // validateStatus 验证合同状态 | 
					
						
							|  |  |  |  | func (c *ContractInfo) validateStatus() error { | 
					
						
							|  |  |  |  | 	validStatuses := []string{ | 
					
						
							|  |  |  |  | 		ContractStatusDraft, | 
					
						
							|  |  |  |  | 		ContractStatusGenerated, | 
					
						
							|  |  |  |  | 		ContractStatusSigning, | 
					
						
							|  |  |  |  | 		ContractStatusSigned, | 
					
						
							|  |  |  |  | 		ContractStatusExpired, | 
					
						
							|  |  |  |  | 		ContractStatusRejected, | 
					
						
							|  |  |  |  | 		ContractStatusCancelled, | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	for _, status := range validStatuses { | 
					
						
							|  |  |  |  | 		if c.Status == status { | 
					
						
							|  |  |  |  | 			return nil | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return fmt.Errorf("无效的合同状态: %s", c.Status) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // SetSignerInfo 设置签署人信息 | 
					
						
							|  |  |  |  | func (c *ContractInfo) SetSignerInfo(signerAccount, signerName, transactorPhone, transactorName, transactorIDCardNum string) error { | 
					
						
							|  |  |  |  | 	c.SignerAccount = strings.TrimSpace(signerAccount) | 
					
						
							|  |  |  |  | 	c.SignerName = strings.TrimSpace(signerName) | 
					
						
							|  |  |  |  | 	c.TransactorPhone = strings.TrimSpace(transactorPhone) | 
					
						
							|  |  |  |  | 	c.TransactorName = strings.TrimSpace(transactorName) | 
					
						
							|  |  |  |  | 	c.TransactorIDCardNum = strings.TrimSpace(transactorIDCardNum) | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return c.validateSignerInfo() | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // UpdateStatus 更新合同状态 | 
					
						
							|  |  |  |  | func (c *ContractInfo) UpdateStatus(status string) error { | 
					
						
							|  |  |  |  | 	oldStatus := c.Status | 
					
						
							|  |  |  |  | 	c.Status = status | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	if err := c.validateStatus(); err != nil { | 
					
						
							|  |  |  |  | 		c.Status = oldStatus // 回滚 | 
					
						
							|  |  |  |  | 		return err | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 根据状态更新进度 | 
					
						
							|  |  |  |  | 	c.updateProgressByStatus() | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // updateProgressByStatus 根据状态更新进度 | 
					
						
							|  |  |  |  | func (c *ContractInfo) updateProgressByStatus() { | 
					
						
							|  |  |  |  | 	progressMap := map[string]int{ | 
					
						
							|  |  |  |  | 		ContractStatusDraft:     0, | 
					
						
							|  |  |  |  | 		ContractStatusGenerated: 25, | 
					
						
							|  |  |  |  | 		ContractStatusSigning:   50, | 
					
						
							|  |  |  |  | 		ContractStatusSigned:    100, | 
					
						
							|  |  |  |  | 		ContractStatusExpired:   50, | 
					
						
							|  |  |  |  | 		ContractStatusRejected:  50, | 
					
						
							|  |  |  |  | 		ContractStatusCancelled: 0, | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	if progress, exists := progressMap[c.Status]; exists { | 
					
						
							|  |  |  |  | 		c.SignProgress = progress | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MarkAsSigning 标记为签署中 | 
					
						
							|  |  |  |  | func (c *ContractInfo) MarkAsSigning() error { | 
					
						
							|  |  |  |  | 	c.Status = ContractStatusSigning | 
					
						
							|  |  |  |  | 	c.SignProgress = 50 | 
					
						
							|  |  |  |  | 	now := time.Now() | 
					
						
							|  |  |  |  | 	c.SignFlowCreatedAt = &now | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MarkAsSigned 标记为已签署 | 
					
						
							|  |  |  |  | func (c *ContractInfo) MarkAsSigned() error { | 
					
						
							|  |  |  |  | 	c.Status = ContractStatusSigned | 
					
						
							|  |  |  |  | 	c.SignProgress = 100 | 
					
						
							|  |  |  |  | 	now := time.Now() | 
					
						
							|  |  |  |  | 	c.SignedAt = &now | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MarkAsExpired 标记为已过期 | 
					
						
							|  |  |  |  | func (c *ContractInfo) MarkAsExpired() error { | 
					
						
							|  |  |  |  | 	c.Status = ContractStatusExpired | 
					
						
							|  |  |  |  | 	now := time.Now() | 
					
						
							|  |  |  |  | 	c.ExpiresAt = &now | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // MarkAsRejected 标记为被拒绝 | 
					
						
							|  |  |  |  | func (c *ContractInfo) MarkAsRejected() error { | 
					
						
							|  |  |  |  | 	c.Status = ContractStatusRejected | 
					
						
							|  |  |  |  | 	c.SignProgress = 50 | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return nil | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // IsExpired 检查合同是否已过期 | 
					
						
							|  |  |  |  | func (c *ContractInfo) IsExpired() bool { | 
					
						
							|  |  |  |  | 	if c.ExpiresAt == nil { | 
					
						
							|  |  |  |  | 		return false | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return time.Now().After(*c.ExpiresAt) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // IsSigned 检查合同是否已签署 | 
					
						
							|  |  |  |  | func (c *ContractInfo) IsSigned() bool { | 
					
						
							|  |  |  |  | 	return c.Status == ContractStatusSigned | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // CanSign 检查是否可以签署 | 
					
						
							|  |  |  |  | func (c *ContractInfo) CanSign() bool { | 
					
						
							|  |  |  |  | 	return c.Status == ContractStatusGenerated || c.Status == ContractStatusSigning | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GetStatusName 获取状态的中文名称 | 
					
						
							|  |  |  |  | func (c *ContractInfo) GetStatusName() string { | 
					
						
							|  |  |  |  | 	statusNames := map[string]string{ | 
					
						
							|  |  |  |  | 		ContractStatusDraft:     "草稿", | 
					
						
							|  |  |  |  | 		ContractStatusGenerated: "已生成", | 
					
						
							|  |  |  |  | 		ContractStatusSigning:   "签署中", | 
					
						
							|  |  |  |  | 		ContractStatusSigned:    "已签署", | 
					
						
							|  |  |  |  | 		ContractStatusExpired:   "已过期", | 
					
						
							|  |  |  |  | 		ContractStatusRejected:  "被拒绝", | 
					
						
							|  |  |  |  | 		ContractStatusCancelled: "已取消", | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	if name, exists := statusNames[c.Status]; exists { | 
					
						
							|  |  |  |  | 		return name | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return c.Status | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GetDisplayTitle 获取显示用的合同标题 | 
					
						
							|  |  |  |  | func (c *ContractInfo) GetDisplayTitle() string { | 
					
						
							|  |  |  |  | 	if c.ContractTitle != "" { | 
					
						
							|  |  |  |  | 		return c.ContractTitle | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	return "企业认证服务合同" | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GetMaskedSignerAccount 获取脱敏的签署人账号 | 
					
						
							|  |  |  |  | func (c *ContractInfo) GetMaskedSignerAccount() string { | 
					
						
							|  |  |  |  | 	if len(c.SignerAccount) <= 6 { | 
					
						
							|  |  |  |  | 		return c.SignerAccount | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 保留前3位和后3位,中间用*替代 | 
					
						
							|  |  |  |  | 	return c.SignerAccount[:3] + "***" + c.SignerAccount[len(c.SignerAccount)-3:] | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GetMaskedTransactorPhone 获取脱敏的经办人手机号 | 
					
						
							|  |  |  |  | func (c *ContractInfo) GetMaskedTransactorPhone() string { | 
					
						
							|  |  |  |  | 	if len(c.TransactorPhone) != 11 { | 
					
						
							|  |  |  |  | 		return c.TransactorPhone | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 保留前3位和后4位,中间用*替代 | 
					
						
							|  |  |  |  | 	return c.TransactorPhone[:3] + "****" + c.TransactorPhone[7:] | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GetMaskedTransactorIDCardNum 获取脱敏的经办人身份证号 | 
					
						
							|  |  |  |  | func (c *ContractInfo) GetMaskedTransactorIDCardNum() string { | 
					
						
							|  |  |  |  | 	if len(c.TransactorIDCardNum) != 18 { | 
					
						
							|  |  |  |  | 		return c.TransactorIDCardNum | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 保留前6位和后4位,中间用*替代 | 
					
						
							|  |  |  |  | 	return c.TransactorIDCardNum[:6] + "********" + c.TransactorIDCardNum[14:] | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // AddMetadata 添加元数据 | 
					
						
							|  |  |  |  | func (c *ContractInfo) AddMetadata(key string, value interface{}) { | 
					
						
							|  |  |  |  | 	if c.Metadata == nil { | 
					
						
							|  |  |  |  | 		c.Metadata = make(map[string]interface{}) | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	c.Metadata[key] = value | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // GetMetadata 获取元数据 | 
					
						
							|  |  |  |  | func (c *ContractInfo) GetMetadata(key string) (interface{}, bool) { | 
					
						
							|  |  |  |  | 	if c.Metadata == nil { | 
					
						
							|  |  |  |  | 		return nil, false | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	value, exists := c.Metadata[key] | 
					
						
							|  |  |  |  | 	return value, exists | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Equals 比较两个合同信息是否相等 | 
					
						
							|  |  |  |  | func (c *ContractInfo) Equals(other *ContractInfo) bool { | 
					
						
							|  |  |  |  | 	if other == nil { | 
					
						
							|  |  |  |  | 		return false | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return c.ContractFileID == other.ContractFileID && | 
					
						
							|  |  |  |  | 		c.EsignFlowID == other.EsignFlowID && | 
					
						
							|  |  |  |  | 		c.Status == other.Status | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // Clone 创建合同信息的副本 | 
					
						
							|  |  |  |  | func (c *ContractInfo) Clone() *ContractInfo { | 
					
						
							|  |  |  |  | 	cloned := &ContractInfo{ | 
					
						
							|  |  |  |  | 		ContractFileID:      c.ContractFileID, | 
					
						
							|  |  |  |  | 		EsignFlowID:         c.EsignFlowID, | 
					
						
							|  |  |  |  | 		ContractURL:         c.ContractURL, | 
					
						
							|  |  |  |  | 		ContractSignURL:     c.ContractSignURL, | 
					
						
							|  |  |  |  | 		ContractTitle:       c.ContractTitle, | 
					
						
							|  |  |  |  | 		ContractVersion:     c.ContractVersion, | 
					
						
							|  |  |  |  | 		TemplateID:          c.TemplateID, | 
					
						
							|  |  |  |  | 		SignerAccount:       c.SignerAccount, | 
					
						
							|  |  |  |  | 		SignerName:          c.SignerName, | 
					
						
							|  |  |  |  | 		TransactorPhone:     c.TransactorPhone, | 
					
						
							|  |  |  |  | 		TransactorName:      c.TransactorName, | 
					
						
							|  |  |  |  | 		TransactorIDCardNum: c.TransactorIDCardNum, | 
					
						
							|  |  |  |  | 		Status:              c.Status, | 
					
						
							|  |  |  |  | 		SignProgress:        c.SignProgress, | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 复制时间字段 | 
					
						
							|  |  |  |  | 	if c.GeneratedAt != nil { | 
					
						
							|  |  |  |  | 		generatedAt := *c.GeneratedAt | 
					
						
							|  |  |  |  | 		cloned.GeneratedAt = &generatedAt | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if c.SignFlowCreatedAt != nil { | 
					
						
							|  |  |  |  | 		signFlowCreatedAt := *c.SignFlowCreatedAt | 
					
						
							|  |  |  |  | 		cloned.SignFlowCreatedAt = &signFlowCreatedAt | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if c.SignedAt != nil { | 
					
						
							|  |  |  |  | 		signedAt := *c.SignedAt | 
					
						
							|  |  |  |  | 		cloned.SignedAt = &signedAt | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if c.ExpiresAt != nil { | 
					
						
							|  |  |  |  | 		expiresAt := *c.ExpiresAt | 
					
						
							|  |  |  |  | 		cloned.ExpiresAt = &expiresAt | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 复制元数据 | 
					
						
							|  |  |  |  | 	if c.Metadata != nil { | 
					
						
							|  |  |  |  | 		cloned.Metadata = make(map[string]interface{}) | 
					
						
							|  |  |  |  | 		for k, v := range c.Metadata { | 
					
						
							|  |  |  |  | 			cloned.Metadata[k] = v | 
					
						
							|  |  |  |  | 		} | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return cloned | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // String 返回合同信息的字符串表示 | 
					
						
							|  |  |  |  | func (c *ContractInfo) String() string { | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 	return fmt.Sprintf("合同信息[文件ID:%s, 流程ID:%s, 状态:%s, 进度:%d%%]", | 
					
						
							|  |  |  |  | 		c.ContractFileID, | 
					
						
							|  |  |  |  | 		c.EsignFlowID, | 
					
						
							|  |  |  |  | 		c.GetStatusName(), | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 		c.SignProgress) | 
					
						
							|  |  |  |  | } | 
					
						
							|  |  |  |  | 
 | 
					
						
							|  |  |  |  | // ToMap 转换为map格式(用于序列化) | 
					
						
							|  |  |  |  | func (c *ContractInfo) ToMap() map[string]interface{} { | 
					
						
							|  |  |  |  | 	result := map[string]interface{}{ | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 		"contract_file_id":       c.ContractFileID, | 
					
						
							|  |  |  |  | 		"esign_flow_id":          c.EsignFlowID, | 
					
						
							|  |  |  |  | 		"contract_url":           c.ContractURL, | 
					
						
							|  |  |  |  | 		"contract_sign_url":      c.ContractSignURL, | 
					
						
							|  |  |  |  | 		"contract_title":         c.ContractTitle, | 
					
						
							|  |  |  |  | 		"contract_version":       c.ContractVersion, | 
					
						
							|  |  |  |  | 		"template_id":            c.TemplateID, | 
					
						
							|  |  |  |  | 		"signer_account":         c.SignerAccount, | 
					
						
							|  |  |  |  | 		"signer_name":            c.SignerName, | 
					
						
							|  |  |  |  | 		"transactor_phone":       c.TransactorPhone, | 
					
						
							|  |  |  |  | 		"transactor_name":        c.TransactorName, | 
					
						
							|  |  |  |  | 		"transactor_id_card_num": c.TransactorIDCardNum, | 
					
						
							|  |  |  |  | 		"status":                 c.Status, | 
					
						
							|  |  |  |  | 		"sign_progress":          c.SignProgress, | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 添加时间字段 | 
					
						
							|  |  |  |  | 	if c.GeneratedAt != nil { | 
					
						
							|  |  |  |  | 		result["generated_at"] = c.GeneratedAt | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if c.SignFlowCreatedAt != nil { | 
					
						
							|  |  |  |  | 		result["sign_flow_created_at"] = c.SignFlowCreatedAt | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if c.SignedAt != nil { | 
					
						
							|  |  |  |  | 		result["signed_at"] = c.SignedAt | 
					
						
							|  |  |  |  | 	} | 
					
						
							|  |  |  |  | 	if c.ExpiresAt != nil { | 
					
						
							|  |  |  |  | 		result["expires_at"] = c.ExpiresAt | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	// 添加元数据 | 
					
						
							|  |  |  |  | 	if c.Metadata != nil { | 
					
						
							|  |  |  |  | 		result["metadata"] = c.Metadata | 
					
						
							|  |  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2025-07-21 15:13:26 +08:00
										 |  |  |  | 	return result | 
					
						
							| 
									
										
										
										
											2025-07-28 01:46:39 +08:00
										 |  |  |  | } |