This commit is contained in:
2025-07-20 20:53:26 +08:00
parent 83bf9aea7d
commit 8ad1d7288e
158 changed files with 18156 additions and 13188 deletions

View File

@@ -12,7 +12,6 @@ import (
// Certification 认证申请实体
// 这是企业认证流程的核心实体,负责管理整个认证申请的生命周期
// 包含认证状态、时间节点、审核信息、合同信息等核心数据
type Certification struct {
// 基础信息
ID string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"认证申请唯一标识"`
@@ -20,36 +19,25 @@ type Certification struct {
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:"拒绝原因说明"`
InfoSubmittedAt *time.Time `json:"info_submitted_at,omitempty" comment:"企业信息提交时间"`
EnterpriseVerifiedAt *time.Time `json:"enterprise_verified_at,omitempty" comment:"企业认证完成时间"`
ContractAppliedAt *time.Time `json:"contract_applied_at,omitempty" comment:"合同申请时间"`
ContractSignedAt *time.Time `json:"contract_signed_at,omitempty" comment:"合同签署完成时间"`
CompletedAt *time.Time `json:"completed_at,omitempty" comment:"认证完成时间"`
// 合同信息 - 电子合同相关链接
ContractURL string `gorm:"type:varchar(500)" json:"contract_url,omitempty" comment:"合同文件访问链接"`
SigningURL string `gorm:"type:varchar(500)" json:"signing_url,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:"合同签署链接"`
// 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)"`
// 认证信息
AuthFlowID string `gorm:"type:varchar(500)" json:"auth_flow_id,omitempty" comment:"认证流程ID"`
// 时间戳字段
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:"软删除时间"`
// 关联关系 - 与其他实体的关联
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 指定数据库表名
@@ -66,122 +54,94 @@ func (c *Certification) BeforeCreate(tx *gorm.DB) error {
}
// IsStatusChangeable 检查状态是否可以变更
// 只有非最终状态(完成/拒绝)的认证申请才能进行状态变更
func (c *Certification) IsStatusChangeable() bool {
return !enums.IsFinalStatus(c.Status)
}
// CanRetryFaceVerify 检查是否可以重试人脸识别
// 只有人脸识别失败状态的申请才能重试
func (c *Certification) CanRetryFaceVerify() bool {
return c.Status == enums.StatusFaceFailed
// GetStatusName 获取状态名称
func (c *Certification) GetStatusName() string {
return enums.GetStatusName(c.Status)
}
// CanRetrySign 检查是否可以重试签署
// 只有签署失败状态的申请才能重试
func (c *Certification) CanRetrySign() bool {
return c.Status == enums.StatusSignFailed
// IsFinalStatus 判断是否为最终状态
func (c *Certification) IsFinalStatus() bool {
return enums.IsFinalStatus(c.Status)
}
// CanRestart 检查是否可以重新开始流程
// 只有被拒绝的申请才能重新开始认证流程
func (c *Certification) CanRestart() bool {
return c.Status == enums.StatusRejected
// GetStatusCategory 获取状态分类
func (c *Certification) GetStatusCategory() string {
return enums.GetStatusCategory(c.Status)
}
// 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{}
}
// GetStatusPriority 获取状态优先级
func (c *Certification) GetStatusPriority() int {
return enums.GetStatusPriority(c.Status)
}
// CanTransitionTo 检查是否可以转换到指定状态
// 验证状态转换的合法性,确保状态机规则得到遵守
func (c *Certification) CanTransitionTo(targetStatus enums.CertificationStatus) bool {
validStatuses := c.GetNextValidStatuses()
for _, status := range validStatuses {
if status == targetStatus {
return true
}
}
return false
}
// GetProgressPercentage 获取认证进度百分比
// 根据当前状态计算认证流程的完成进度,用于前端进度条显示
// 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
progressMap := map[enums.CertificationStatus]int{
enums.StatusPending: 0,
enums.StatusInfoSubmitted: 20,
enums.StatusEnterpriseVerified: 40,
enums.StatusContractApplied: 60,
enums.StatusContractSigned: 80,
enums.StatusCompleted: 100,
}
if progress, exists := progressMap[c.Status]; exists {
return progress
}
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,
userActionRequired := map[enums.CertificationStatus]bool{
enums.StatusPending: true,
enums.StatusInfoSubmitted: true,
enums.StatusEnterpriseVerified: true,
enums.StatusContractApplied: true,
enums.StatusContractSigned: false,
enums.StatusCompleted: false,
}
for _, status := range userActionStatuses {
if c.Status == status {
return true
}
if required, exists := userActionRequired[c.Status]; exists {
return required
}
return false
}
// IsAdminActionRequired 检查是否需要管理员操作
// 判断当前状态是否需要管理员审核,用于后台管理界面
func (c *Certification) IsAdminActionRequired() bool {
return c.Status == enums.StatusContractPending
// GetNextValidStatuses 获取下一个有效状态
func (c *Certification) GetNextValidStatuses() []enums.CertificationStatus {
nextStatusMap := map[enums.CertificationStatus][]enums.CertificationStatus{
enums.StatusPending: {enums.StatusInfoSubmitted},
enums.StatusInfoSubmitted: {enums.StatusEnterpriseVerified, enums.StatusInfoSubmitted}, // 可以重新提交
enums.StatusEnterpriseVerified: {enums.StatusContractApplied},
enums.StatusContractApplied: {enums.StatusContractSigned},
enums.StatusContractSigned: {enums.StatusCompleted},
enums.StatusCompleted: {},
}
if nextStatuses, exists := nextStatusMap[c.Status]; exists {
return nextStatuses
}
return []enums.CertificationStatus{}
}
// CanTransitionTo 检查是否可以转换到指定状态
func (c *Certification) CanTransitionTo(targetStatus enums.CertificationStatus, isUser bool) (bool, string) {
nextStatuses := c.GetNextValidStatuses()
for _, nextStatus := range nextStatuses {
if nextStatus == targetStatus {
// 检查权限
if isUser && !c.IsUserActionRequired() {
return false, "当前状态不需要用户操作"
}
return true, ""
}
}
return false, "不支持的状态转换"
}

View File

@@ -1,107 +0,0 @@
package entities
import (
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
// ContractRecord 合同记录实体
// 记录电子合同的详细信息,包括合同生成、审核、签署的完整流程
// 支持合同状态跟踪、签署信息记录、审核流程管理等功能
type ContractRecord struct {
// 基础标识
ID string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"合同记录唯一标识"`
CertificationID string `gorm:"type:varchar(36);not null;index" json:"certification_id" comment:"关联的认证申请ID"`
UserID string `gorm:"type:varchar(36);not null;index" json:"user_id" comment:"合同申请人ID"`
AdminID *string `gorm:"type:varchar(36);index" json:"admin_id,omitempty" comment:"审核管理员ID"`
// 合同信息 - 电子合同的基本信息
ContractType string `gorm:"type:varchar(50);not null" json:"contract_type" comment:"合同类型(ENTERPRISE_CERTIFICATION)"`
ContractURL string `gorm:"type:varchar(500)" json:"contract_url,omitempty" comment:"合同文件访问链接"`
SigningURL string `gorm:"type:varchar(500)" json:"signing_url,omitempty" comment:"电子签署链接"`
// 签署信息 - 记录用户签署的详细信息
SignatureData string `gorm:"type:text" json:"signature_data,omitempty" comment:"签署数据(JSON格式)"`
SignedAt *time.Time `json:"signed_at,omitempty" comment:"签署完成时间"`
ClientIP string `gorm:"type:varchar(50)" json:"client_ip,omitempty" comment:"签署客户端IP"`
UserAgent string `gorm:"type:varchar(500)" json:"user_agent,omitempty" comment:"签署客户端信息"`
// 状态信息 - 合同的生命周期状态
Status string `gorm:"type:varchar(50);not null;index" json:"status" comment:"合同状态(PENDING/APPROVED/SIGNED/EXPIRED)"`
ApprovalNotes string `gorm:"type:text" json:"approval_notes,omitempty" comment:"审核备注信息"`
RejectReason string `gorm:"type:text" json:"reject_reason,omitempty" comment:"拒绝原因说明"`
ExpiresAt *time.Time `json:"expires_at,omitempty" comment:"合同过期时间"`
// 时间戳字段
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:"软删除时间"`
// 关联关系
Certification *Certification `gorm:"foreignKey:CertificationID" json:"certification,omitempty" comment:"关联的认证申请"`
}
// TableName 指定数据库表名
func (ContractRecord) TableName() string {
return "contract_records"
}
// IsPending 检查合同是否待审核
// 判断合同是否处于等待管理员审核的状态
func (c *ContractRecord) IsPending() bool {
return c.Status == "PENDING"
}
// IsApproved 检查合同是否已审核通过
// 判断合同是否已通过管理员审核,可以进入签署阶段
func (c *ContractRecord) IsApproved() bool {
return c.Status == "APPROVED"
}
// IsSigned 检查合同是否已签署
// 判断合同是否已完成电子签署,认证流程即将完成
func (c *ContractRecord) IsSigned() bool {
return c.Status == "SIGNED"
}
// IsExpired 检查合同是否已过期
// 判断合同是否已超过有效期,过期后需要重新申请
func (c *ContractRecord) IsExpired() bool {
if c.ExpiresAt == nil {
return false
}
return time.Now().After(*c.ExpiresAt)
}
// HasSigningURL 检查是否有签署链接
// 判断是否已生成电子签署链接,用于前端判断是否显示签署按钮
func (c *ContractRecord) HasSigningURL() bool {
return c.SigningURL != ""
}
// GetStatusName 获取状态的中文名称
// 将英文状态码转换为中文显示名称,用于前端展示和用户理解
func (c *ContractRecord) GetStatusName() string {
statusNames := map[string]string{
"PENDING": "待审核",
"APPROVED": "已审核",
"SIGNED": "已签署",
"EXPIRED": "已过期",
"REJECTED": "已拒绝",
}
if name, exists := statusNames[c.Status]; exists {
return name
}
return c.Status
}
// BeforeCreate GORM钩子创建前自动生成UUID
func (c *ContractRecord) BeforeCreate(tx *gorm.DB) error {
if c.ID == "" {
c.ID = uuid.New().String()
}
return nil
}

View File

@@ -0,0 +1,83 @@
package entities
import (
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
// EnterpriseInfoSubmitRecord 企业信息提交记录
type EnterpriseInfoSubmitRecord struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
UserID string `json:"user_id" gorm:"type:varchar(36);not null;index"`
// 企业信息
CompanyName string `json:"company_name" gorm:"type:varchar(200);not null"`
UnifiedSocialCode string `json:"unified_social_code" gorm:"type:varchar(50);not null;index"`
LegalPersonName string `json:"legal_person_name" gorm:"type:varchar(50);not null"`
LegalPersonID string `json:"legal_person_id" gorm:"type:varchar(50);not null"`
LegalPersonPhone string `json:"legal_person_phone" gorm:"type:varchar(50);not null"`
// 提交状态
Status string `json:"status" gorm:"type:varchar(20);not null;default:'submitted'"` // submitted, verified, failed
SubmitAt time.Time `json:"submit_at" gorm:"not null"`
VerifiedAt *time.Time `json:"verified_at"`
FailedAt *time.Time `json:"failed_at"`
FailureReason string `json:"failure_reason" gorm:"type:text"`
// 系统字段
CreatedAt time.Time `json:"created_at" gorm:"not null"`
UpdatedAt time.Time `json:"updated_at" gorm:"not null"`
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
}
// TableName 指定表名
func (EnterpriseInfoSubmitRecord) TableName() string {
return "enterprise_info_submit_records"
}
// NewEnterpriseInfoSubmitRecord 创建新的企业信息提交记录
func NewEnterpriseInfoSubmitRecord(
userID, companyName, unifiedSocialCode, legalPersonName, legalPersonID, legalPersonPhone string,
) *EnterpriseInfoSubmitRecord {
return &EnterpriseInfoSubmitRecord{
ID: uuid.New().String(),
UserID: userID,
CompanyName: companyName,
UnifiedSocialCode: unifiedSocialCode,
LegalPersonName: legalPersonName,
LegalPersonID: legalPersonID,
LegalPersonPhone: legalPersonPhone,
Status: "submitted",
SubmitAt: time.Now(),
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
}
// MarkAsVerified 标记为已验证
func (r *EnterpriseInfoSubmitRecord) MarkAsVerified() {
now := time.Now()
r.Status = "verified"
r.VerifiedAt = &now
r.UpdatedAt = now
}
// MarkAsFailed 标记为验证失败
func (r *EnterpriseInfoSubmitRecord) MarkAsFailed(reason string) {
now := time.Now()
r.Status = "failed"
r.FailedAt = &now
r.FailureReason = reason
r.UpdatedAt = now
}
// IsVerified 检查是否已验证
func (r *EnterpriseInfoSubmitRecord) IsVerified() bool {
return r.Status == "verified"
}
// IsFailed 检查是否验证失败
func (r *EnterpriseInfoSubmitRecord) IsFailed() bool {
return r.Status == "failed"
}

View File

@@ -0,0 +1,35 @@
package entities
import (
"time"
"gorm.io/gorm"
)
// EsignContractGenerateRecord e签宝生成合同文件记录
type EsignContractGenerateRecord struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
CertificationID string `json:"certification_id" gorm:"type:varchar(36);not null;index"`
UserID string `json:"user_id" gorm:"type:varchar(36);not null;index"`
// e签宝相关
TemplateID string `json:"template_id" gorm:"type:varchar(100);index"` // 模板ID
ContractFileID string `json:"contract_file_id" gorm:"type:varchar(100);index"` // 合同文件ID
ContractURL string `json:"contract_url" gorm:"type:varchar(500)"` // 合同文件URL
ContractName string `json:"contract_name" gorm:"type:varchar(200)"` // 合同名称
// 生成状态
Status string `json:"status" gorm:"type:varchar(20);not null"` // success, failed
FillTime *time.Time `json:"fill_time"` // 填写时间
// 系统字段
CreatedAt time.Time `json:"created_at" gorm:"not null"`
UpdatedAt time.Time `json:"updated_at" gorm:"not null"`
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
}
// TableName 指定表名
func (EsignContractGenerateRecord) TableName() string {
return "esign_contract_generate_records"
}

View File

@@ -0,0 +1,147 @@
package entities
import (
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
// EsignContractSignRecord e签宝签署合同记录
type EsignContractSignRecord struct {
ID string `json:"id" gorm:"primaryKey;type:varchar(36)"`
CertificationID string `json:"certification_id" gorm:"type:varchar(36);not null;index"`
UserID string `json:"user_id" gorm:"type:varchar(36);not null;index"`
EnterpriseInfoID string `json:"enterprise_info_id" gorm:"type:varchar(36);not null;index"` // 企业信息ID
// e签宝相关
EsignFlowID string `json:"esign_flow_id" gorm:"type:varchar(100);index"` // e签宝流程ID
ContractFileID string `json:"contract_file_id" gorm:"type:varchar(100);index"` // 合同文件ID
SignURL string `json:"sign_url" gorm:"type:varchar(500)"` // 签署链接
SignShortURL string `json:"sign_short_url" gorm:"type:varchar(500)"` // 签署短链接
SignedFileURL string `json:"signed_file_url" gorm:"type:varchar(500)"` // 已签署文件URL
// 签署状态
Status string `json:"status" gorm:"type:varchar(20);not null;default:'pending'"` // pending, signing, success, failed, expired
RequestAt time.Time `json:"request_at" gorm:"not null"` // 申请签署时间
SignedAt *time.Time `json:"signed_at"` // 签署完成时间
ExpiredAt *time.Time `json:"expired_at"` // 签署链接过期时间
FailedAt *time.Time `json:"failed_at"` // 失败时间
FailureReason string `json:"failure_reason" gorm:"type:text"` // 失败原因
// 签署人信息
SignerName string `json:"signer_name" gorm:"type:varchar(50)"` // 签署人姓名
SignerPhone string `json:"signer_phone" gorm:"type:varchar(20)"` // 签署人手机号
SignerIDCard string `json:"signer_id_card" gorm:"type:varchar(20)"` // 签署人身份证号
// 系统字段
CreatedAt time.Time `json:"created_at" gorm:"not null"`
UpdatedAt time.Time `json:"updated_at" gorm:"not null"`
DeletedAt gorm.DeletedAt `json:"deleted_at" gorm:"index"`
}
// TableName 指定表名
func (EsignContractSignRecord) TableName() string {
return "esign_contract_sign_records"
}
// NewEsignContractSignRecord 创建新的e签宝签署合同记录
func NewEsignContractSignRecord(
certificationID, userID, esignFlowID, contractFileID, signerName, signerPhone, signerIDCard, signURL, signShortURL string,
) *EsignContractSignRecord {
// 设置签署链接过期时间为7天后
expiredAt := time.Now().AddDate(0, 0, 7)
return &EsignContractSignRecord{
ID: uuid.New().String(),
CertificationID: certificationID,
UserID: userID,
EsignFlowID: esignFlowID,
ContractFileID: contractFileID,
SignURL: signURL,
SignShortURL: signShortURL,
SignerName: signerName,
SignerPhone: signerPhone,
SignerIDCard: signerIDCard,
Status: "pending",
RequestAt: time.Now(),
ExpiredAt: &expiredAt,
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
}
}
// MarkAsSigning 标记为签署中
func (r *EsignContractSignRecord) MarkAsSigning() {
r.Status = "signing"
r.UpdatedAt = time.Now()
}
// MarkAsSuccess 标记为签署成功
func (r *EsignContractSignRecord) MarkAsSuccess(signedFileURL string) {
now := time.Now()
r.Status = "success"
r.SignedFileURL = signedFileURL
r.SignedAt = &now
r.UpdatedAt = now
}
// MarkAsFailed 标记为签署失败
func (r *EsignContractSignRecord) MarkAsFailed(reason string) {
now := time.Now()
r.Status = "failed"
r.FailedAt = &now
r.FailureReason = reason
r.UpdatedAt = now
}
// MarkAsExpired 标记为已过期
func (r *EsignContractSignRecord) MarkAsExpired() {
now := time.Now()
r.Status = "expired"
r.ExpiredAt = &now
r.UpdatedAt = now
}
// SetSignURL 设置签署链接
func (r *EsignContractSignRecord) SetSignURL(signURL string) {
r.SignURL = signURL
r.UpdatedAt = time.Now()
}
// IsSuccess 检查是否签署成功
func (r *EsignContractSignRecord) IsSuccess() bool {
return r.Status == "success"
}
// IsFailed 检查是否签署失败
func (r *EsignContractSignRecord) IsFailed() bool {
return r.Status == "failed"
}
// IsExpired 检查是否已过期
func (r *EsignContractSignRecord) IsExpired() bool {
return r.Status == "expired" || (r.ExpiredAt != nil && time.Now().After(*r.ExpiredAt))
}
// IsPending 检查是否待处理
func (r *EsignContractSignRecord) IsPending() bool {
return r.Status == "pending"
}
// IsSigning 检查是否签署中
func (r *EsignContractSignRecord) IsSigning() bool {
return r.Status == "signing"
}
// GetRemainingTime 获取剩余签署时间
func (r *EsignContractSignRecord) GetRemainingTime() time.Duration {
if r.ExpiredAt == nil {
return 0
}
remaining := time.Until(*r.ExpiredAt)
if remaining < 0 {
return 0
}
return remaining
}

View File

@@ -1,98 +0,0 @@
package entities
import (
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
// FaceVerifyRecord 人脸识别记录实体
// 记录用户进行人脸识别验证的详细信息,包括验证状态、结果和身份信息
// 支持多次验证尝试,每次验证都会生成独立的记录,便于追踪和重试
type FaceVerifyRecord struct {
// 基础标识
ID string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"人脸识别记录唯一标识"`
CertificationID string `gorm:"type:varchar(36);not null;index" json:"certification_id" comment:"关联的认证申请ID"`
UserID string `gorm:"type:varchar(36);not null;index" json:"user_id" comment:"进行验证的用户ID"`
// 阿里云人脸识别信息 - 第三方服务的相关数据
CertifyID string `gorm:"type:varchar(100);not null;index" json:"certify_id" comment:"阿里云人脸识别任务ID"`
VerifyURL string `gorm:"type:varchar(500)" json:"verify_url,omitempty" comment:"人脸识别验证页面URL"`
ReturnURL string `gorm:"type:varchar(500)" json:"return_url,omitempty" comment:"验证完成后的回调URL"`
// 身份信息 - 用于人脸识别的身份验证数据
RealName string `gorm:"type:varchar(100);not null" json:"real_name" comment:"真实姓名"`
IDCardNumber string `gorm:"type:varchar(50);not null" json:"id_card_number" comment:"身份证号码"`
// 验证结果 - 记录验证的详细结果信息
Status string `gorm:"type:varchar(50);not null;index" json:"status" comment:"验证状态(PROCESSING/SUCCESS/FAIL)"`
ResultCode string `gorm:"type:varchar(50)" json:"result_code,omitempty" comment:"结果代码"`
ResultMessage string `gorm:"type:varchar(500)" json:"result_message,omitempty" comment:"结果描述信息"`
VerifyScore float64 `gorm:"type:decimal(5,2)" json:"verify_score,omitempty" comment:"验证分数(0-1)"`
// 时间信息 - 验证流程的时间节点
InitiatedAt time.Time `gorm:"autoCreateTime" json:"initiated_at" comment:"验证发起时间"`
CompletedAt *time.Time `json:"completed_at,omitempty" comment:"验证完成时间"`
ExpiresAt time.Time `gorm:"not null" json:"expires_at" comment:"验证链接过期时间"`
// 时间戳字段
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:"软删除时间"`
// 关联关系
Certification *Certification `gorm:"foreignKey:CertificationID" json:"certification,omitempty" comment:"关联的认证申请"`
}
// TableName 指定数据库表名
func (FaceVerifyRecord) TableName() string {
return "face_verify_records"
}
// IsSuccess 检查人脸识别是否成功
// 判断验证状态是否为成功状态
func (f *FaceVerifyRecord) IsSuccess() bool {
return f.Status == "SUCCESS"
}
// IsProcessing 检查是否正在处理中
// 判断验证是否正在进行中,等待用户完成验证
func (f *FaceVerifyRecord) IsProcessing() bool {
return f.Status == "PROCESSING"
}
// IsFailed 检查是否失败
// 判断验证是否失败,包括超时、验证不通过等情况
func (f *FaceVerifyRecord) IsFailed() bool {
return f.Status == "FAIL"
}
// IsExpired 检查是否已过期
// 判断验证链接是否已超过有效期,过期后需要重新发起验证
func (f *FaceVerifyRecord) IsExpired() bool {
return time.Now().After(f.ExpiresAt)
}
// GetStatusName 获取状态的中文名称
// 将英文状态码转换为中文显示名称,用于前端展示
func (f *FaceVerifyRecord) GetStatusName() string {
statusNames := map[string]string{
"PROCESSING": "处理中",
"SUCCESS": "成功",
"FAIL": "失败",
}
if name, exists := statusNames[f.Status]; exists {
return name
}
return f.Status
}
// BeforeCreate GORM钩子创建前自动生成UUID
func (f *FaceVerifyRecord) BeforeCreate(tx *gorm.DB) error {
if f.ID == "" {
f.ID = uuid.New().String()
}
return nil
}

View File

@@ -1,79 +0,0 @@
package entities
import (
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
// LicenseUploadRecord 营业执照上传记录实体
// 记录用户上传营业执照文件的详细信息包括文件元数据和OCR处理结果
// 支持多种文件格式自动进行OCR识别为后续企业信息验证提供数据支持
type LicenseUploadRecord struct {
// 基础标识
ID string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"上传记录唯一标识"`
CertificationID *string `gorm:"type:varchar(36);index" json:"certification_id,omitempty" comment:"关联的认证申请ID(可为空,表示独立上传)"`
UserID string `gorm:"type:varchar(36);not null;index" json:"user_id" comment:"上传用户ID"`
// 文件信息 - 存储文件的元数据信息
OriginalFileName string `gorm:"type:varchar(255);not null" json:"original_file_name" comment:"原始文件名"`
FileSize int64 `gorm:"not null" json:"file_size" comment:"文件大小(字节)"`
FileType string `gorm:"type:varchar(50);not null" json:"file_type" comment:"文件MIME类型"`
FileURL string `gorm:"type:varchar(500);not null" json:"file_url" comment:"文件访问URL"`
QiNiuKey string `gorm:"type:varchar(255);not null;index" json:"qiniu_key" comment:"七牛云存储的Key"`
// OCR处理结果 - 记录OCR识别的详细结果
OCRProcessed bool `gorm:"default:false" json:"ocr_processed" comment:"是否已进行OCR处理"`
OCRSuccess bool `gorm:"default:false" json:"ocr_success" comment:"OCR识别是否成功"`
OCRConfidence float64 `gorm:"type:decimal(5,2)" json:"ocr_confidence,omitempty" comment:"OCR识别置信度(0-1)"`
OCRRawData string `gorm:"type:text" json:"ocr_raw_data,omitempty" comment:"OCR原始返回数据(JSON格式)"`
OCRErrorMessage string `gorm:"type:varchar(500)" json:"ocr_error_message,omitempty" comment:"OCR处理错误信息"`
// 时间戳字段
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:"软删除时间"`
// 关联关系
Certification *Certification `gorm:"foreignKey:CertificationID" json:"certification,omitempty" comment:"关联的认证申请"`
}
// TableName 指定数据库表名
func (LicenseUploadRecord) TableName() string {
return "license_upload_records"
}
// IsOCRSuccess 检查OCR是否成功
// 判断OCR处理已完成且识别成功
func (l *LicenseUploadRecord) IsOCRSuccess() bool {
return l.OCRProcessed && l.OCRSuccess
}
// GetFileExtension 获取文件扩展名
// 从原始文件名中提取文件扩展名,用于文件类型判断
func (l *LicenseUploadRecord) GetFileExtension() string {
// 从OriginalFileName提取扩展名的逻辑
// 这里简化处理实际使用时可以用path.Ext()
return l.FileType
}
// IsValidForOCR 检查文件是否适合OCR处理
// 验证文件类型是否支持OCR识别目前支持JPEG、PNG格式
func (l *LicenseUploadRecord) IsValidForOCR() bool {
validTypes := []string{"image/jpeg", "image/png", "image/jpg"}
for _, validType := range validTypes {
if l.FileType == validType {
return true
}
}
return false
}
// BeforeCreate GORM钩子创建前自动生成UUID
func (l *LicenseUploadRecord) BeforeCreate(tx *gorm.DB) error {
if l.ID == "" {
l.ID = uuid.New().String()
}
return nil
}

View File

@@ -1,136 +0,0 @@
package entities
import (
"time"
"github.com/google/uuid"
"gorm.io/gorm"
)
// NotificationRecord 通知记录实体
// 记录系统发送的所有通知信息,包括短信、企业微信、邮件等多种通知渠道
// 支持通知状态跟踪、重试机制、模板化消息等功能,确保通知的可靠送达
type NotificationRecord struct {
// 基础标识
ID string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"通知记录唯一标识"`
CertificationID *string `gorm:"type:varchar(36);index" json:"certification_id,omitempty" comment:"关联的认证申请ID(可为空)"`
UserID *string `gorm:"type:varchar(36);index" json:"user_id,omitempty" comment:"接收用户ID(可为空)"`
// 通知类型和渠道 - 定义通知的发送方式和业务场景
NotificationType string `gorm:"type:varchar(50);not null;index" json:"notification_type" comment:"通知类型(SMS/WECHAT_WORK/EMAIL)"`
NotificationScene string `gorm:"type:varchar(50);not null;index" json:"notification_scene" comment:"通知场景(ADMIN_NEW_APPLICATION/USER_CONTRACT_READY等)"`
// 接收方信息 - 通知的目标接收者
Recipient string `gorm:"type:varchar(255);not null" json:"recipient" comment:"接收方标识(手机号/邮箱/用户ID)"`
// 消息内容 - 通知的具体内容信息
Title string `gorm:"type:varchar(255)" json:"title,omitempty" comment:"通知标题"`
Content string `gorm:"type:text;not null" json:"content" comment:"通知内容"`
TemplateID string `gorm:"type:varchar(100)" json:"template_id,omitempty" comment:"消息模板ID"`
TemplateParams string `gorm:"type:text" json:"template_params,omitempty" comment:"模板参数(JSON格式)"`
// 发送状态 - 记录通知的发送过程和结果
Status string `gorm:"type:varchar(50);not null;index" json:"status" comment:"发送状态(PENDING/SENT/FAILED)"`
ErrorMessage string `gorm:"type:varchar(500)" json:"error_message,omitempty" comment:"发送失败的错误信息"`
SentAt *time.Time `json:"sent_at,omitempty" comment:"发送成功时间"`
RetryCount int `gorm:"default:0" json:"retry_count" comment:"当前重试次数"`
MaxRetryCount int `gorm:"default:3" json:"max_retry_count" comment:"最大重试次数"`
// 时间戳字段
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:"软删除时间"`
// 关联关系
Certification *Certification `gorm:"foreignKey:CertificationID" json:"certification,omitempty" comment:"关联的认证申请"`
}
// TableName 指定数据库表名
func (NotificationRecord) TableName() string {
return "notification_records"
}
// BeforeCreate GORM钩子创建前自动生成UUID
func (n *NotificationRecord) BeforeCreate(tx *gorm.DB) error {
if n.ID == "" {
n.ID = uuid.New().String()
}
return nil
}
// IsPending 检查通知是否待发送
// 判断通知是否处于等待发送的状态
func (n *NotificationRecord) IsPending() bool {
return n.Status == "PENDING"
}
// IsSent 检查通知是否已发送
// 判断通知是否已成功发送到接收方
func (n *NotificationRecord) IsSent() bool {
return n.Status == "SENT"
}
// IsFailed 检查通知是否发送失败
// 判断通知是否发送失败,包括网络错误、接收方无效等情况
func (n *NotificationRecord) IsFailed() bool {
return n.Status == "FAILED"
}
// CanRetry 检查是否可以重试
// 判断失败的通知是否还可以进行重试发送
func (n *NotificationRecord) CanRetry() bool {
return n.IsFailed() && n.RetryCount < n.MaxRetryCount
}
// IncrementRetryCount 增加重试次数
// 在重试发送时增加重试计数器
func (n *NotificationRecord) IncrementRetryCount() {
n.RetryCount++
}
// GetStatusName 获取状态的中文名称
// 将英文状态码转换为中文显示名称,用于前端展示
func (n *NotificationRecord) GetStatusName() string {
statusNames := map[string]string{
"PENDING": "待发送",
"SENT": "已发送",
"FAILED": "发送失败",
}
if name, exists := statusNames[n.Status]; exists {
return name
}
return n.Status
}
// GetNotificationTypeName 获取通知类型的中文名称
// 将通知类型转换为中文显示名称,便于用户理解
func (n *NotificationRecord) GetNotificationTypeName() string {
typeNames := map[string]string{
"SMS": "短信",
"WECHAT_WORK": "企业微信",
"EMAIL": "邮件",
}
if name, exists := typeNames[n.NotificationType]; exists {
return name
}
return n.NotificationType
}
// GetNotificationSceneName 获取通知场景的中文名称
// 将通知场景转换为中文显示名称,便于业务人员理解通知的触发原因
func (n *NotificationRecord) GetNotificationSceneName() string {
sceneNames := map[string]string{
"ADMIN_NEW_APPLICATION": "管理员新申请通知",
"USER_CONTRACT_READY": "用户合同就绪通知",
"USER_CERTIFICATION_COMPLETED": "用户认证完成通知",
"USER_FACE_VERIFY_FAILED": "用户人脸识别失败通知",
"USER_CONTRACT_REJECTED": "用户合同被拒绝通知",
}
if name, exists := sceneNames[n.NotificationScene]; exists {
return name
}
return n.NotificationScene
}