v0.1
This commit is contained in:
@@ -12,35 +12,35 @@ import (
|
||||
// 封装电子合同相关的核心信息,包含合同状态和签署流程管理
|
||||
type ContractInfo struct {
|
||||
// 合同基本信息
|
||||
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"` // 合同签署链接
|
||||
|
||||
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"` // 合同签署链接
|
||||
|
||||
// 合同元数据
|
||||
ContractTitle string `json:"contract_title"` // 合同标题
|
||||
ContractVersion string `json:"contract_version"` // 合同版本
|
||||
TemplateID string `json:"template_id"` // 模板ID
|
||||
|
||||
ContractTitle string `json:"contract_title"` // 合同标题
|
||||
ContractVersion string `json:"contract_version"` // 合同版本
|
||||
TemplateID string `json:"template_id"` // 模板ID
|
||||
|
||||
// 签署相关信息
|
||||
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"` // 经办人身份证号
|
||||
|
||||
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"` // 经办人身份证号
|
||||
|
||||
// 时间信息
|
||||
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"` // 签署链接过期时间
|
||||
|
||||
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"` // 签署链接过期时间
|
||||
|
||||
// 状态信息
|
||||
Status string `json:"status"` // 合同状态
|
||||
SignProgress int `json:"sign_progress"` // 签署进度
|
||||
|
||||
Status string `json:"status"` // 合同状态
|
||||
SignProgress int `json:"sign_progress"` // 签署进度
|
||||
|
||||
// 附加信息
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"` // 元数据
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"` // 元数据
|
||||
}
|
||||
|
||||
// ContractStatus 合同状态常量
|
||||
@@ -57,19 +57,19 @@ const (
|
||||
// NewContractInfo 创建合同信息值对象
|
||||
func NewContractInfo(contractFileID, esignFlowID, contractURL, contractSignURL string) (*ContractInfo, error) {
|
||||
info := &ContractInfo{
|
||||
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{}),
|
||||
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{}),
|
||||
}
|
||||
|
||||
|
||||
if err := info.Validate(); err != nil {
|
||||
return nil, fmt.Errorf("合同信息验证失败: %w", err)
|
||||
}
|
||||
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
@@ -78,27 +78,27 @@ func (c *ContractInfo) Validate() error {
|
||||
if err := c.validateContractFileID(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
if err := c.validateEsignFlowID(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
if err := c.validateContractURL(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
if err := c.validateContractSignURL(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
if err := c.validateSignerInfo(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
if err := c.validateStatus(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -107,12 +107,12 @@ func (c *ContractInfo) validateContractFileID() error {
|
||||
if c.ContractFileID == "" {
|
||||
return errors.New("合同文件ID不能为空")
|
||||
}
|
||||
|
||||
|
||||
// 简单的格式验证
|
||||
if len(c.ContractFileID) < 10 {
|
||||
return errors.New("合同文件ID格式不正确")
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -121,12 +121,12 @@ func (c *ContractInfo) validateEsignFlowID() error {
|
||||
if c.EsignFlowID == "" {
|
||||
return errors.New("e签宝流程ID不能为空")
|
||||
}
|
||||
|
||||
|
||||
// 简单的格式验证
|
||||
if len(c.EsignFlowID) < 10 {
|
||||
return errors.New("e签宝流程ID格式不正确")
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -135,18 +135,18 @@ func (c *ContractInfo) validateContractURL() error {
|
||||
if c.ContractURL == "" {
|
||||
return errors.New("合同访问链接不能为空")
|
||||
}
|
||||
|
||||
|
||||
// URL格式验证
|
||||
urlPattern := `^https?://.*`
|
||||
matched, err := regexp.MatchString(urlPattern, c.ContractURL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("合同访问链接格式验证错误: %w", err)
|
||||
}
|
||||
|
||||
|
||||
if !matched {
|
||||
return errors.New("合同访问链接格式不正确,必须以http://或https://开头")
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -155,18 +155,18 @@ func (c *ContractInfo) validateContractSignURL() error {
|
||||
if c.ContractSignURL == "" {
|
||||
return errors.New("合同签署链接不能为空")
|
||||
}
|
||||
|
||||
|
||||
// URL格式验证
|
||||
urlPattern := `^https?://.*`
|
||||
matched, err := regexp.MatchString(urlPattern, c.ContractSignURL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("合同签署链接格式验证错误: %w", err)
|
||||
}
|
||||
|
||||
|
||||
if !matched {
|
||||
return errors.New("合同签署链接格式不正确,必须以http://或https://开头")
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -177,11 +177,11 @@ func (c *ContractInfo) validateSignerInfo() error {
|
||||
if c.SignerAccount == "" {
|
||||
return errors.New("签署人账号不能为空")
|
||||
}
|
||||
|
||||
|
||||
if c.SignerName == "" {
|
||||
return errors.New("签署人姓名不能为空")
|
||||
}
|
||||
|
||||
|
||||
if c.TransactorPhone != "" {
|
||||
// 手机号格式验证
|
||||
phonePattern := `^1[3-9]\d{9}$`
|
||||
@@ -189,12 +189,12 @@ func (c *ContractInfo) validateSignerInfo() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("经办人手机号格式验证错误: %w", err)
|
||||
}
|
||||
|
||||
|
||||
if !matched {
|
||||
return errors.New("经办人手机号格式不正确")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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]$`
|
||||
@@ -202,13 +202,13 @@ func (c *ContractInfo) validateSignerInfo() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("经办人身份证号格式验证错误: %w", err)
|
||||
}
|
||||
|
||||
|
||||
if !matched {
|
||||
return errors.New("经办人身份证号格式不正确")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -223,13 +223,13 @@ func (c *ContractInfo) validateStatus() error {
|
||||
ContractStatusRejected,
|
||||
ContractStatusCancelled,
|
||||
}
|
||||
|
||||
|
||||
for _, status := range validStatuses {
|
||||
if c.Status == status {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return fmt.Errorf("无效的合同状态: %s", c.Status)
|
||||
}
|
||||
|
||||
@@ -240,7 +240,7 @@ func (c *ContractInfo) SetSignerInfo(signerAccount, signerName, transactorPhone,
|
||||
c.TransactorPhone = strings.TrimSpace(transactorPhone)
|
||||
c.TransactorName = strings.TrimSpace(transactorName)
|
||||
c.TransactorIDCardNum = strings.TrimSpace(transactorIDCardNum)
|
||||
|
||||
|
||||
return c.validateSignerInfo()
|
||||
}
|
||||
|
||||
@@ -248,15 +248,15 @@ func (c *ContractInfo) SetSignerInfo(signerAccount, signerName, transactorPhone,
|
||||
func (c *ContractInfo) UpdateStatus(status string) error {
|
||||
oldStatus := c.Status
|
||||
c.Status = status
|
||||
|
||||
|
||||
if err := c.validateStatus(); err != nil {
|
||||
c.Status = oldStatus // 回滚
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
// 根据状态更新进度
|
||||
c.updateProgressByStatus()
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ func (c *ContractInfo) updateProgressByStatus() {
|
||||
ContractStatusRejected: 50,
|
||||
ContractStatusCancelled: 0,
|
||||
}
|
||||
|
||||
|
||||
if progress, exists := progressMap[c.Status]; exists {
|
||||
c.SignProgress = progress
|
||||
}
|
||||
@@ -283,7 +283,7 @@ func (c *ContractInfo) MarkAsSigning() error {
|
||||
c.SignProgress = 50
|
||||
now := time.Now()
|
||||
c.SignFlowCreatedAt = &now
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -293,7 +293,7 @@ func (c *ContractInfo) MarkAsSigned() error {
|
||||
c.SignProgress = 100
|
||||
now := time.Now()
|
||||
c.SignedAt = &now
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ func (c *ContractInfo) MarkAsExpired() error {
|
||||
c.Status = ContractStatusExpired
|
||||
now := time.Now()
|
||||
c.ExpiresAt = &now
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -310,7 +310,7 @@ func (c *ContractInfo) MarkAsExpired() error {
|
||||
func (c *ContractInfo) MarkAsRejected() error {
|
||||
c.Status = ContractStatusRejected
|
||||
c.SignProgress = 50
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -319,7 +319,7 @@ func (c *ContractInfo) IsExpired() bool {
|
||||
if c.ExpiresAt == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
return time.Now().After(*c.ExpiresAt)
|
||||
}
|
||||
|
||||
@@ -344,7 +344,7 @@ func (c *ContractInfo) GetStatusName() string {
|
||||
ContractStatusRejected: "被拒绝",
|
||||
ContractStatusCancelled: "已取消",
|
||||
}
|
||||
|
||||
|
||||
if name, exists := statusNames[c.Status]; exists {
|
||||
return name
|
||||
}
|
||||
@@ -364,7 +364,7 @@ func (c *ContractInfo) GetMaskedSignerAccount() string {
|
||||
if len(c.SignerAccount) <= 6 {
|
||||
return c.SignerAccount
|
||||
}
|
||||
|
||||
|
||||
// 保留前3位和后3位,中间用*替代
|
||||
return c.SignerAccount[:3] + "***" + c.SignerAccount[len(c.SignerAccount)-3:]
|
||||
}
|
||||
@@ -374,7 +374,7 @@ func (c *ContractInfo) GetMaskedTransactorPhone() string {
|
||||
if len(c.TransactorPhone) != 11 {
|
||||
return c.TransactorPhone
|
||||
}
|
||||
|
||||
|
||||
// 保留前3位和后4位,中间用*替代
|
||||
return c.TransactorPhone[:3] + "****" + c.TransactorPhone[7:]
|
||||
}
|
||||
@@ -384,7 +384,7 @@ func (c *ContractInfo) GetMaskedTransactorIDCardNum() string {
|
||||
if len(c.TransactorIDCardNum) != 18 {
|
||||
return c.TransactorIDCardNum
|
||||
}
|
||||
|
||||
|
||||
// 保留前6位和后4位,中间用*替代
|
||||
return c.TransactorIDCardNum[:6] + "********" + c.TransactorIDCardNum[14:]
|
||||
}
|
||||
@@ -411,7 +411,7 @@ func (c *ContractInfo) Equals(other *ContractInfo) bool {
|
||||
if other == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
return c.ContractFileID == other.ContractFileID &&
|
||||
c.EsignFlowID == other.EsignFlowID &&
|
||||
c.Status == other.Status
|
||||
@@ -435,7 +435,7 @@ func (c *ContractInfo) Clone() *ContractInfo {
|
||||
Status: c.Status,
|
||||
SignProgress: c.SignProgress,
|
||||
}
|
||||
|
||||
|
||||
// 复制时间字段
|
||||
if c.GeneratedAt != nil {
|
||||
generatedAt := *c.GeneratedAt
|
||||
@@ -453,7 +453,7 @@ func (c *ContractInfo) Clone() *ContractInfo {
|
||||
expiresAt := *c.ExpiresAt
|
||||
cloned.ExpiresAt = &expiresAt
|
||||
}
|
||||
|
||||
|
||||
// 复制元数据
|
||||
if c.Metadata != nil {
|
||||
cloned.Metadata = make(map[string]interface{})
|
||||
@@ -461,38 +461,38 @@ func (c *ContractInfo) Clone() *ContractInfo {
|
||||
cloned.Metadata[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return cloned
|
||||
}
|
||||
|
||||
// String 返回合同信息的字符串表示
|
||||
func (c *ContractInfo) String() string {
|
||||
return fmt.Sprintf("合同信息[文件ID:%s, 流程ID:%s, 状态:%s, 进度:%d%%]",
|
||||
c.ContractFileID,
|
||||
c.EsignFlowID,
|
||||
c.GetStatusName(),
|
||||
return fmt.Sprintf("合同信息[文件ID:%s, 流程ID:%s, 状态:%s, 进度:%d%%]",
|
||||
c.ContractFileID,
|
||||
c.EsignFlowID,
|
||||
c.GetStatusName(),
|
||||
c.SignProgress)
|
||||
}
|
||||
|
||||
// ToMap 转换为map格式(用于序列化)
|
||||
func (c *ContractInfo) ToMap() map[string]interface{} {
|
||||
result := map[string]interface{}{
|
||||
"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,
|
||||
"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,
|
||||
}
|
||||
|
||||
|
||||
// 添加时间字段
|
||||
if c.GeneratedAt != nil {
|
||||
result["generated_at"] = c.GeneratedAt
|
||||
@@ -506,11 +506,11 @@ func (c *ContractInfo) ToMap() map[string]interface{} {
|
||||
if c.ExpiresAt != nil {
|
||||
result["expires_at"] = c.ExpiresAt
|
||||
}
|
||||
|
||||
|
||||
// 添加元数据
|
||||
if c.Metadata != nil {
|
||||
result["metadata"] = c.Metadata
|
||||
}
|
||||
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,35 +11,36 @@ import (
|
||||
// 封装企业认证所需的核心信息,包含完整的业务规则验证
|
||||
type EnterpriseInfo struct {
|
||||
// 企业基本信息
|
||||
CompanyName string `json:"company_name"` // 企业名称
|
||||
UnifiedSocialCode string `json:"unified_social_code"` // 统一社会信用代码
|
||||
|
||||
CompanyName string `json:"company_name"` // 企业名称
|
||||
UnifiedSocialCode string `json:"unified_social_code"` // 统一社会信用代码
|
||||
|
||||
// 法定代表人信息
|
||||
LegalPersonName string `json:"legal_person_name"` // 法定代表人姓名
|
||||
LegalPersonID string `json:"legal_person_id"` // 法定代表人身份证号
|
||||
LegalPersonPhone string `json:"legal_person_phone"` // 法定代表人手机号
|
||||
|
||||
LegalPersonName string `json:"legal_person_name"` // 法定代表人姓名
|
||||
LegalPersonID string `json:"legal_person_id"` // 法定代表人身份证号
|
||||
LegalPersonPhone string `json:"legal_person_phone"` // 法定代表人手机号
|
||||
|
||||
// 企业详细信息
|
||||
RegisteredAddress string `json:"registered_address"` // 注册地址
|
||||
BusinessScope string `json:"business_scope"` // 经营范围
|
||||
RegisteredCapital string `json:"registered_capital"` // 注册资本
|
||||
EstablishmentDate string `json:"establishment_date"` // 成立日期
|
||||
RegisteredAddress string `json:"registered_address"` // 注册地址
|
||||
EnterpriseAddress string `json:"enterprise_address"` // 企业地址(新增)
|
||||
EnterpriseEmail string `json:"enterprise_email"` // 企业邮箱
|
||||
}
|
||||
|
||||
// NewEnterpriseInfo 创建企业信息值对象
|
||||
func NewEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone string) (*EnterpriseInfo, error) {
|
||||
func NewEnterpriseInfo(companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone, enterpriseAddress, enterpriseEmail string) (*EnterpriseInfo, error) {
|
||||
info := &EnterpriseInfo{
|
||||
CompanyName: strings.TrimSpace(companyName),
|
||||
UnifiedSocialCode: strings.TrimSpace(unifiedSocialCode),
|
||||
LegalPersonName: strings.TrimSpace(legalPersonName),
|
||||
LegalPersonID: strings.TrimSpace(legalPersonID),
|
||||
LegalPersonPhone: strings.TrimSpace(legalPersonPhone),
|
||||
EnterpriseAddress: strings.TrimSpace(enterpriseAddress),
|
||||
EnterpriseEmail: strings.TrimSpace(enterpriseEmail),
|
||||
}
|
||||
|
||||
|
||||
if err := info.Validate(); err != nil {
|
||||
return nil, fmt.Errorf("企业信息验证失败: %w", err)
|
||||
}
|
||||
|
||||
|
||||
return info, nil
|
||||
}
|
||||
|
||||
@@ -48,23 +49,31 @@ func (e *EnterpriseInfo) Validate() error {
|
||||
if err := e.validateCompanyName(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
if err := e.validateUnifiedSocialCode(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
if err := e.validateLegalPersonName(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
if err := e.validateLegalPersonID(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
if err := e.validateLegalPersonPhone(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
if err := e.validateEnterpriseAddress(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := e.validateEnterpriseEmail(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -73,15 +82,15 @@ func (e *EnterpriseInfo) validateCompanyName() error {
|
||||
if e.CompanyName == "" {
|
||||
return errors.New("企业名称不能为空")
|
||||
}
|
||||
|
||||
|
||||
if len(e.CompanyName) < 2 {
|
||||
return errors.New("企业名称长度不能少于2个字符")
|
||||
}
|
||||
|
||||
|
||||
if len(e.CompanyName) > 100 {
|
||||
return errors.New("企业名称长度不能超过100个字符")
|
||||
}
|
||||
|
||||
|
||||
// 检查是否包含非法字符
|
||||
invalidChars := []string{"`", "~", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "+", "=", "{", "}", "[", "]", "\\", "|", ";", ":", "'", "\"", "<", ">", ",", ".", "?", "/"}
|
||||
for _, char := range invalidChars {
|
||||
@@ -89,7 +98,7 @@ func (e *EnterpriseInfo) validateCompanyName() error {
|
||||
return fmt.Errorf("企业名称不能包含特殊字符: %s", char)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -98,18 +107,18 @@ func (e *EnterpriseInfo) validateUnifiedSocialCode() error {
|
||||
if e.UnifiedSocialCode == "" {
|
||||
return errors.New("统一社会信用代码不能为空")
|
||||
}
|
||||
|
||||
|
||||
// 统一社会信用代码格式验证(18位数字和字母)
|
||||
pattern := `^[0-9A-HJ-NPQRTUWXY]{2}[0-9]{6}[0-9A-HJ-NPQRTUWXY]{10}$`
|
||||
matched, err := regexp.MatchString(pattern, e.UnifiedSocialCode)
|
||||
if err != nil {
|
||||
return fmt.Errorf("统一社会信用代码格式验证错误: %w", err)
|
||||
}
|
||||
|
||||
|
||||
if !matched {
|
||||
return errors.New("统一社会信用代码格式不正确,应为18位数字和字母组合")
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -118,26 +127,26 @@ func (e *EnterpriseInfo) validateLegalPersonName() error {
|
||||
if e.LegalPersonName == "" {
|
||||
return errors.New("法定代表人姓名不能为空")
|
||||
}
|
||||
|
||||
|
||||
if len(e.LegalPersonName) < 2 {
|
||||
return errors.New("法定代表人姓名长度不能少于2个字符")
|
||||
}
|
||||
|
||||
|
||||
if len(e.LegalPersonName) > 50 {
|
||||
return errors.New("法定代表人姓名长度不能超过50个字符")
|
||||
}
|
||||
|
||||
|
||||
// 中文姓名格式验证
|
||||
pattern := `^[\u4e00-\u9fa5·]+$`
|
||||
pattern := "^[一-龥·]+$"
|
||||
matched, err := regexp.MatchString(pattern, e.LegalPersonName)
|
||||
if err != nil {
|
||||
return fmt.Errorf("法定代表人姓名格式验证错误: %w", err)
|
||||
}
|
||||
|
||||
|
||||
if !matched {
|
||||
return errors.New("法定代表人姓名只能包含中文字符和间隔号")
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -146,27 +155,27 @@ func (e *EnterpriseInfo) validateLegalPersonID() error {
|
||||
if e.LegalPersonID == "" {
|
||||
return errors.New("法定代表人身份证号不能为空")
|
||||
}
|
||||
|
||||
|
||||
// 身份证号格式验证(18位)
|
||||
if len(e.LegalPersonID) != 18 {
|
||||
return errors.New("身份证号必须为18位")
|
||||
}
|
||||
|
||||
|
||||
pattern := `^[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(pattern, e.LegalPersonID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("身份证号格式验证错误: %w", err)
|
||||
}
|
||||
|
||||
|
||||
if !matched {
|
||||
return errors.New("身份证号格式不正确")
|
||||
}
|
||||
|
||||
|
||||
// 身份证号校验码验证
|
||||
if !e.validateIDChecksum() {
|
||||
return errors.New("身份证号校验码错误")
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -175,22 +184,22 @@ func (e *EnterpriseInfo) validateIDChecksum() bool {
|
||||
if len(e.LegalPersonID) != 18 {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
// 加权因子
|
||||
weights := []int{7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2}
|
||||
// 校验码对应表
|
||||
checkCodes := []string{"1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"}
|
||||
|
||||
|
||||
sum := 0
|
||||
for i := 0; i < 17; i++ {
|
||||
digit := int(e.LegalPersonID[i] - '0')
|
||||
sum += digit * weights[i]
|
||||
}
|
||||
|
||||
|
||||
checkCodeIndex := sum % 11
|
||||
expectedCheckCode := checkCodes[checkCodeIndex]
|
||||
actualCheckCode := strings.ToUpper(string(e.LegalPersonID[17]))
|
||||
|
||||
|
||||
return expectedCheckCode == actualCheckCode
|
||||
}
|
||||
|
||||
@@ -199,18 +208,53 @@ func (e *EnterpriseInfo) validateLegalPersonPhone() error {
|
||||
if e.LegalPersonPhone == "" {
|
||||
return errors.New("法定代表人手机号不能为空")
|
||||
}
|
||||
|
||||
|
||||
// 手机号格式验证(11位数字,1开头)
|
||||
pattern := `^1[3-9]\d{9}$`
|
||||
matched, err := regexp.MatchString(pattern, e.LegalPersonPhone)
|
||||
if err != nil {
|
||||
return fmt.Errorf("手机号格式验证错误: %w", err)
|
||||
}
|
||||
|
||||
|
||||
if !matched {
|
||||
return errors.New("手机号格式不正确,应为11位数字且以1开头")
|
||||
}
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateEnterpriseAddress 验证企业地址
|
||||
func (e *EnterpriseInfo) validateEnterpriseAddress() error {
|
||||
if strings.TrimSpace(e.EnterpriseAddress) == "" {
|
||||
return errors.New("企业地址不能为空")
|
||||
}
|
||||
if len(e.EnterpriseAddress) < 5 {
|
||||
return errors.New("企业地址长度不能少于5个字符")
|
||||
}
|
||||
if len(e.EnterpriseAddress) > 200 {
|
||||
return errors.New("企业地址长度不能超过200个字符")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateEnterpriseEmail 验证企业邮箱
|
||||
func (e *EnterpriseInfo) validateEnterpriseEmail() error {
|
||||
if strings.TrimSpace(e.EnterpriseEmail) == "" {
|
||||
return errors.New("企业邮箱不能为空")
|
||||
}
|
||||
if len(e.EnterpriseEmail) < 5 {
|
||||
return errors.New("企业邮箱长度不能少于5个字符")
|
||||
}
|
||||
if len(e.EnterpriseEmail) > 100 {
|
||||
return errors.New("企业邮箱长度不能超过100个字符")
|
||||
}
|
||||
|
||||
// 邮箱格式验证
|
||||
emailPattern := regexp.MustCompile(`^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$`)
|
||||
if !emailPattern.MatchString(e.EnterpriseEmail) {
|
||||
return errors.New("企业邮箱格式不正确")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -220,16 +264,16 @@ func (e *EnterpriseInfo) IsComplete() bool {
|
||||
e.UnifiedSocialCode != "" &&
|
||||
e.LegalPersonName != "" &&
|
||||
e.LegalPersonID != "" &&
|
||||
e.LegalPersonPhone != ""
|
||||
e.LegalPersonPhone != "" &&
|
||||
e.EnterpriseAddress != "" &&
|
||||
e.EnterpriseEmail != ""
|
||||
}
|
||||
|
||||
// IsDetailComplete 检查企业详细信息是否完整
|
||||
func (e *EnterpriseInfo) IsDetailComplete() bool {
|
||||
return e.IsComplete() &&
|
||||
e.RegisteredAddress != "" &&
|
||||
e.BusinessScope != "" &&
|
||||
e.RegisteredCapital != "" &&
|
||||
e.EstablishmentDate != ""
|
||||
e.EnterpriseAddress != ""
|
||||
}
|
||||
|
||||
// GetDisplayName 获取显示用的企业名称
|
||||
@@ -245,7 +289,7 @@ func (e *EnterpriseInfo) GetMaskedUnifiedSocialCode() string {
|
||||
if len(e.UnifiedSocialCode) != 18 {
|
||||
return e.UnifiedSocialCode
|
||||
}
|
||||
|
||||
|
||||
// 保留前6位和后4位,中间用*替代
|
||||
return e.UnifiedSocialCode[:6] + "********" + e.UnifiedSocialCode[14:]
|
||||
}
|
||||
@@ -255,7 +299,7 @@ func (e *EnterpriseInfo) GetMaskedLegalPersonID() string {
|
||||
if len(e.LegalPersonID) != 18 {
|
||||
return e.LegalPersonID
|
||||
}
|
||||
|
||||
|
||||
// 保留前6位和后4位,中间用*替代
|
||||
return e.LegalPersonID[:6] + "********" + e.LegalPersonID[14:]
|
||||
}
|
||||
@@ -265,7 +309,7 @@ func (e *EnterpriseInfo) GetMaskedLegalPersonPhone() string {
|
||||
if len(e.LegalPersonPhone) != 11 {
|
||||
return e.LegalPersonPhone
|
||||
}
|
||||
|
||||
|
||||
// 保留前3位和后4位,中间用*替代
|
||||
return e.LegalPersonPhone[:3] + "****" + e.LegalPersonPhone[7:]
|
||||
}
|
||||
@@ -275,34 +319,34 @@ func (e *EnterpriseInfo) Equals(other *EnterpriseInfo) bool {
|
||||
if other == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
|
||||
return e.CompanyName == other.CompanyName &&
|
||||
e.UnifiedSocialCode == other.UnifiedSocialCode &&
|
||||
e.LegalPersonName == other.LegalPersonName &&
|
||||
e.LegalPersonID == other.LegalPersonID &&
|
||||
e.LegalPersonPhone == other.LegalPersonPhone
|
||||
e.LegalPersonPhone == other.LegalPersonPhone &&
|
||||
e.EnterpriseEmail == other.EnterpriseEmail
|
||||
}
|
||||
|
||||
// Clone 创建企业信息的副本
|
||||
func (e *EnterpriseInfo) Clone() *EnterpriseInfo {
|
||||
return &EnterpriseInfo{
|
||||
CompanyName: e.CompanyName,
|
||||
UnifiedSocialCode: e.UnifiedSocialCode,
|
||||
LegalPersonName: e.LegalPersonName,
|
||||
LegalPersonID: e.LegalPersonID,
|
||||
LegalPersonPhone: e.LegalPersonPhone,
|
||||
RegisteredAddress: e.RegisteredAddress,
|
||||
BusinessScope: e.BusinessScope,
|
||||
RegisteredCapital: e.RegisteredCapital,
|
||||
EstablishmentDate: e.EstablishmentDate,
|
||||
CompanyName: e.CompanyName,
|
||||
UnifiedSocialCode: e.UnifiedSocialCode,
|
||||
LegalPersonName: e.LegalPersonName,
|
||||
LegalPersonID: e.LegalPersonID,
|
||||
LegalPersonPhone: e.LegalPersonPhone,
|
||||
RegisteredAddress: e.RegisteredAddress,
|
||||
EnterpriseAddress: e.EnterpriseAddress,
|
||||
EnterpriseEmail: e.EnterpriseEmail,
|
||||
}
|
||||
}
|
||||
|
||||
// String 返回企业信息的字符串表示
|
||||
func (e *EnterpriseInfo) String() string {
|
||||
return fmt.Sprintf("企业信息[名称:%s, 信用代码:%s, 法人:%s]",
|
||||
e.CompanyName,
|
||||
e.GetMaskedUnifiedSocialCode(),
|
||||
return fmt.Sprintf("企业信息[名称:%s, 信用代码:%s, 法人:%s]",
|
||||
e.CompanyName,
|
||||
e.GetMaskedUnifiedSocialCode(),
|
||||
e.LegalPersonName)
|
||||
}
|
||||
|
||||
@@ -315,9 +359,8 @@ func (e *EnterpriseInfo) ToMap() map[string]interface{} {
|
||||
"legal_person_id": e.LegalPersonID,
|
||||
"legal_person_phone": e.LegalPersonPhone,
|
||||
"registered_address": e.RegisteredAddress,
|
||||
"business_scope": e.BusinessScope,
|
||||
"registered_capital": e.RegisteredCapital,
|
||||
"establishment_date": e.EstablishmentDate,
|
||||
"enterprise_address": e.EnterpriseAddress,
|
||||
"enterprise_email": e.EnterpriseEmail,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -331,22 +374,21 @@ func FromMap(data map[string]interface{}) (*EnterpriseInfo, error) {
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
|
||||
info := &EnterpriseInfo{
|
||||
CompanyName: getString("company_name"),
|
||||
UnifiedSocialCode: getString("unified_social_code"),
|
||||
LegalPersonName: getString("legal_person_name"),
|
||||
LegalPersonID: getString("legal_person_id"),
|
||||
LegalPersonPhone: getString("legal_person_phone"),
|
||||
RegisteredAddress: getString("registered_address"),
|
||||
BusinessScope: getString("business_scope"),
|
||||
RegisteredCapital: getString("registered_capital"),
|
||||
EstablishmentDate: getString("establishment_date"),
|
||||
CompanyName: getString("company_name"),
|
||||
UnifiedSocialCode: getString("unified_social_code"),
|
||||
LegalPersonName: getString("legal_person_name"),
|
||||
LegalPersonID: getString("legal_person_id"),
|
||||
LegalPersonPhone: getString("legal_person_phone"),
|
||||
RegisteredAddress: getString("registered_address"),
|
||||
EnterpriseAddress: getString("enterprise_address"),
|
||||
EnterpriseEmail: getString("enterprise_email"),
|
||||
}
|
||||
|
||||
|
||||
if err := info.Validate(); err != nil {
|
||||
return nil, fmt.Errorf("从Map创建企业信息失败: %w", err)
|
||||
}
|
||||
|
||||
|
||||
return info, nil
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user