This commit is contained in:
2025-07-11 21:05:58 +08:00
parent 5b4392894f
commit e3d64e7485
74 changed files with 14379 additions and 697 deletions

View File

@@ -0,0 +1,179 @@
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
}

View File

@@ -0,0 +1,98 @@
package entities
import (
"time"
"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
}

View File

@@ -0,0 +1,66 @@
package entities
import (
"time"
"gorm.io/gorm"
)
// Enterprise 企业信息实体
// 存储企业认证的核心信息,包括企业四要素和验证状态
// 与认证申请是一对一关系,每个认证申请对应一个企业信息
type Enterprise 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"`
// 企业四要素 - 企业认证的核心信息
CompanyName string `gorm:"type:varchar(255);not null" json:"company_name" comment:"企业名称"`
UnifiedSocialCode string `gorm:"type:varchar(50);not null;index" json:"unified_social_code" comment:"统一社会信用代码"`
LegalPersonName string `gorm:"type:varchar(100);not null" json:"legal_person_name" comment:"法定代表人姓名"`
LegalPersonID string `gorm:"type:varchar(50);not null" json:"legal_person_id" comment:"法定代表人身份证号"`
// 关联的营业执照上传记录
LicenseUploadRecordID string `gorm:"type:varchar(36);not null;index" json:"license_upload_record_id" comment:"关联的营业执照上传记录ID"`
// OCR识别结果 - 从营业执照中自动识别的信息
OCRRawData string `gorm:"type:text" json:"ocr_raw_data,omitempty" comment:"OCR原始返回数据(JSON格式)"`
OCRConfidence float64 `gorm:"type:decimal(5,2)" json:"ocr_confidence,omitempty" comment:"OCR识别置信度(0-1)"`
// 验证状态 - 各环节的验证结果
IsOCRVerified bool `gorm:"default:false" json:"is_ocr_verified" comment:"OCR验证是否通过"`
IsFaceVerified bool `gorm:"default:false" json:"is_face_verified" comment:"人脸识别是否通过"`
VerificationData string `gorm:"type:text" json:"verification_data,omitempty" comment:"验证数据(JSON格式)"`
// 时间戳字段
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:"关联的认证申请"`
LicenseUploadRecord *LicenseUploadRecord `gorm:"foreignKey:LicenseUploadRecordID" json:"license_upload_record,omitempty" comment:"关联的营业执照上传记录"`
}
// TableName 指定数据库表名
func (Enterprise) TableName() string {
return "enterprises"
}
// IsComplete 检查企业四要素是否完整
// 验证企业名称、统一社会信用代码、法定代表人姓名、身份证号是否都已填写
func (e *Enterprise) IsComplete() bool {
return e.CompanyName != "" &&
e.UnifiedSocialCode != "" &&
e.LegalPersonName != "" &&
e.LegalPersonID != ""
}
// Validate 验证企业信息是否有效
// 这里可以添加企业信息的业务验证逻辑
// 比如统一社会信用代码格式验证、身份证号格式验证等
func (e *Enterprise) Validate() error {
// 这里可以添加企业信息的业务验证逻辑
// 比如统一社会信用代码格式验证、身份证号格式验证等
return nil
}

View File

@@ -0,0 +1,89 @@
package entities
import (
"time"
"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
}

View File

@@ -0,0 +1,70 @@
package entities
import (
"time"
"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
}

View File

@@ -0,0 +1,127 @@
package entities
import (
"time"
"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"
}
// 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
}