package entities import ( "time" "tyapi-server/internal/domains/certification/enums" "gorm.io/gorm" ) // Certification 认证申请实体 // 这是企业认证流程的核心实体,负责管理整个认证申请的生命周期 // 包含认证状态、时间节点、审核信息、合同信息等核心数据 type Certification struct { // 基础信息 ID string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"认证申请唯一标识"` UserID string `gorm:"type:varchar(36);not null;index" json:"user_id" comment:"申请用户ID"` EnterpriseID *string `gorm:"type:varchar(36);index" json:"enterprise_id" comment:"关联的企业信息ID"` Status enums.CertificationStatus `gorm:"type:varchar(50);not null;index" json:"status" comment:"当前认证状态"` // 流程节点时间戳 - 记录每个关键步骤的完成时间 InfoSubmittedAt *time.Time `json:"info_submitted_at,omitempty" comment:"企业信息提交时间"` FaceVerifiedAt *time.Time `json:"face_verified_at,omitempty" comment:"人脸识别完成时间"` ContractAppliedAt *time.Time `json:"contract_applied_at,omitempty" comment:"合同申请时间"` ContractApprovedAt *time.Time `json:"contract_approved_at,omitempty" comment:"合同审核通过时间"` ContractSignedAt *time.Time `json:"contract_signed_at,omitempty" comment:"合同签署完成时间"` CompletedAt *time.Time `json:"completed_at,omitempty" comment:"认证完成时间"` // 审核信息 - 管理员审核相关数据 AdminID *string `gorm:"type:varchar(36)" json:"admin_id,omitempty" comment:"审核管理员ID"` ApprovalNotes string `gorm:"type:text" json:"approval_notes,omitempty" comment:"审核备注信息"` RejectReason string `gorm:"type:text" json:"reject_reason,omitempty" comment:"拒绝原因说明"` // 合同信息 - 电子合同相关链接 ContractURL string `gorm:"type:varchar(500)" json:"contract_url,omitempty" comment:"合同文件访问链接"` SigningURL string `gorm:"type:varchar(500)" json:"signing_url,omitempty" comment:"电子签署链接"` // OCR识别信息 - 营业执照OCR识别结果 OCRRequestID string `gorm:"type:varchar(100)" json:"ocr_request_id,omitempty" comment:"OCR识别请求ID"` OCRConfidence float64 `gorm:"type:decimal(5,2)" json:"ocr_confidence,omitempty" comment:"OCR识别置信度(0-1)"` // 时间戳字段 CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at" comment:"创建时间"` UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at" comment:"更新时间"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-" comment:"软删除时间"` // 关联关系 - 与其他实体的关联 Enterprise *Enterprise `gorm:"foreignKey:EnterpriseID" json:"enterprise,omitempty" comment:"关联的企业信息"` LicenseUploadRecord *LicenseUploadRecord `gorm:"foreignKey:CertificationID" json:"license_upload_record,omitempty" comment:"关联的营业执照上传记录"` FaceVerifyRecords []FaceVerifyRecord `gorm:"foreignKey:CertificationID" json:"face_verify_records,omitempty" comment:"关联的人脸识别记录列表"` ContractRecords []ContractRecord `gorm:"foreignKey:CertificationID" json:"contract_records,omitempty" comment:"关联的合同记录列表"` NotificationRecords []NotificationRecord `gorm:"foreignKey:CertificationID" json:"notification_records,omitempty" comment:"关联的通知记录列表"` } // TableName 指定数据库表名 func (Certification) TableName() string { return "certifications" } // IsStatusChangeable 检查状态是否可以变更 // 只有非最终状态(完成/拒绝)的认证申请才能进行状态变更 func (c *Certification) IsStatusChangeable() bool { return !enums.IsFinalStatus(c.Status) } // CanRetryFaceVerify 检查是否可以重试人脸识别 // 只有人脸识别失败状态的申请才能重试 func (c *Certification) CanRetryFaceVerify() bool { return c.Status == enums.StatusFaceFailed } // CanRetrySign 检查是否可以重试签署 // 只有签署失败状态的申请才能重试 func (c *Certification) CanRetrySign() bool { return c.Status == enums.StatusSignFailed } // CanRestart 检查是否可以重新开始流程 // 只有被拒绝的申请才能重新开始认证流程 func (c *Certification) CanRestart() bool { return c.Status == enums.StatusRejected } // GetNextValidStatuses 获取当前状态可以转换到的下一个状态列表 // 根据状态机规则,返回所有合法的下一个状态 func (c *Certification) GetNextValidStatuses() []enums.CertificationStatus { switch c.Status { case enums.StatusPending: return []enums.CertificationStatus{enums.StatusInfoSubmitted} case enums.StatusInfoSubmitted: return []enums.CertificationStatus{enums.StatusFaceVerified, enums.StatusFaceFailed} case enums.StatusFaceVerified: return []enums.CertificationStatus{enums.StatusContractApplied} case enums.StatusContractApplied: return []enums.CertificationStatus{enums.StatusContractPending} case enums.StatusContractPending: return []enums.CertificationStatus{enums.StatusContractApproved, enums.StatusRejected} case enums.StatusContractApproved: return []enums.CertificationStatus{enums.StatusContractSigned, enums.StatusSignFailed} case enums.StatusContractSigned: return []enums.CertificationStatus{enums.StatusCompleted} case enums.StatusFaceFailed: return []enums.CertificationStatus{enums.StatusFaceVerified} case enums.StatusSignFailed: return []enums.CertificationStatus{enums.StatusContractSigned} case enums.StatusRejected: return []enums.CertificationStatus{enums.StatusInfoSubmitted} default: return []enums.CertificationStatus{} } } // CanTransitionTo 检查是否可以转换到指定状态 // 验证状态转换的合法性,确保状态机规则得到遵守 func (c *Certification) CanTransitionTo(targetStatus enums.CertificationStatus) bool { validStatuses := c.GetNextValidStatuses() for _, status := range validStatuses { if status == targetStatus { return true } } return false } // GetProgressPercentage 获取认证进度百分比 // 根据当前状态计算认证流程的完成进度,用于前端进度条显示 func (c *Certification) GetProgressPercentage() int { switch c.Status { case enums.StatusPending: return 0 case enums.StatusInfoSubmitted: return 12 case enums.StatusFaceVerified: return 25 case enums.StatusContractApplied: return 37 case enums.StatusContractPending: return 50 case enums.StatusContractApproved: return 75 case enums.StatusContractSigned: return 87 case enums.StatusCompleted: return 100 case enums.StatusFaceFailed, enums.StatusSignFailed: return c.GetProgressPercentage() // 失败状态保持原进度 case enums.StatusRejected: return 0 default: return 0 } } // IsUserActionRequired 检查是否需要用户操作 // 判断当前状态是否需要用户进行下一步操作,用于前端提示 func (c *Certification) IsUserActionRequired() bool { userActionStatuses := []enums.CertificationStatus{ enums.StatusPending, enums.StatusInfoSubmitted, enums.StatusFaceVerified, enums.StatusContractApproved, enums.StatusFaceFailed, enums.StatusSignFailed, enums.StatusRejected, } for _, status := range userActionStatuses { if c.Status == status { return true } } return false } // IsAdminActionRequired 检查是否需要管理员操作 // 判断当前状态是否需要管理员审核,用于后台管理界面 func (c *Certification) IsAdminActionRequired() bool { return c.Status == enums.StatusContractPending }