This commit is contained in:
2025-07-21 15:13:26 +08:00
parent 8ad1d7288e
commit b03129667a
41 changed files with 8497 additions and 3968 deletions

View File

@@ -0,0 +1,370 @@
package certification
import (
"context"
"fmt"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
"tyapi-server/internal/domains/certification/entities"
"tyapi-server/internal/domains/certification/enums"
"tyapi-server/internal/domains/certification/repositories"
"tyapi-server/internal/shared/database"
"tyapi-server/internal/shared/interfaces"
)
// ================ 常量定义 ================
const (
// 表名常量
CertificationsTable = "certifications"
// 缓存时间常量
CacheTTLPrimaryQuery = 30 * time.Minute // 主键查询缓存时间
CacheTTLBusinessQuery = 15 * time.Minute // 业务查询缓存时间
CacheTTLUserQuery = 10 * time.Minute // 用户相关查询缓存时间
CacheTTLWarmupLong = 30 * time.Minute // 预热长期缓存
CacheTTLWarmupMedium = 15 * time.Minute // 预热中期缓存
// 缓存键模式常量
CachePatternTable = "gorm_cache:certifications:*"
CachePatternUser = "certification:user_id:*"
)
// ================ Repository 实现 ================
// GormCertificationCommandRepository 认证命令仓储GORM实现
//
// 特性说明:
// - 基于 CachedBaseRepositoryImpl 实现自动缓存管理
// - 支持多级缓存策略主键查询30分钟业务查询15分钟
// - 自动缓存失效:写操作时自动清理相关缓存
// - 智能缓存选择:根据查询复杂度自动选择缓存策略
// - 内置监控支持:提供缓存统计和性能监控
type GormCertificationCommandRepository struct {
*database.CachedBaseRepositoryImpl
}
// 编译时检查接口实现
var _ repositories.CertificationCommandRepository = (*GormCertificationCommandRepository)(nil)
// NewGormCertificationCommandRepository 创建认证命令仓储
//
// 参数:
// - db: GORM数据库连接实例
// - logger: 日志记录器
//
// 返回:
// - repositories.CertificationCommandRepository: 仓储接口实现
func NewGormCertificationCommandRepository(db *gorm.DB, logger *zap.Logger) repositories.CertificationCommandRepository {
return &GormCertificationCommandRepository{
CachedBaseRepositoryImpl: database.NewCachedBaseRepositoryImpl(db, logger, CertificationsTable),
}
}
// ================ 基础CRUD操作 ================
// Create 创建认证
//
// 业务说明:
// - 创建新的认证申请
// - 自动触发相关缓存失效
//
// 参数:
// - ctx: 上下文
// - cert: 认证实体
//
// 返回:
// - error: 创建失败时的错误信息
func (r *GormCertificationCommandRepository) Create(ctx context.Context, cert entities.Certification) error {
r.GetLogger().Info("创建认证申请",
zap.String("user_id", cert.UserID),
zap.String("status", string(cert.Status)))
return r.CreateEntity(ctx, &cert)
}
// Update 更新认证
//
// 缓存影响:
// - GORM缓存插件会自动失效相关缓存
// - 无需手动管理缓存一致性
//
// 参数:
// - ctx: 上下文
// - cert: 认证实体
//
// 返回:
// - error: 更新失败时的错误信息
func (r *GormCertificationCommandRepository) Update(ctx context.Context, cert entities.Certification) error {
r.GetLogger().Info("更新认证",
zap.String("id", cert.ID),
zap.String("status", string(cert.Status)))
return r.UpdateEntity(ctx, &cert)
}
// Delete 删除认证
//
// 参数:
// - ctx: 上下文
// - id: 认证ID
//
// 返回:
// - error: 删除失败时的错误信息
func (r *GormCertificationCommandRepository) Delete(ctx context.Context, id string) error {
r.GetLogger().Info("删除认证", zap.String("id", id))
return r.DeleteEntity(ctx, id, &entities.Certification{})
}
// ================ 业务特定的更新操作 ================
// UpdateStatus 更新认证状态
//
// 业务说明:
// - 更新认证的状态
// - 自动更新时间戳
//
// 缓存影响:
// - GORM缓存插件会自动失效表相关的缓存
// - 状态更新会影响列表查询和统计结果
//
// 参数:
// - ctx: 上下文
// - id: 认证ID
// - status: 新状态
//
// 返回:
// - error: 更新失败时的错误信息
func (r *GormCertificationCommandRepository) UpdateStatus(ctx context.Context, id string, status enums.CertificationStatus) error {
r.GetLogger().Info("更新认证状态",
zap.String("id", id),
zap.String("status", string(status)))
updates := map[string]interface{}{
"status": status,
"updated_at": time.Now(),
}
return r.GetDB(ctx).Model(&entities.Certification{}).
Where("id = ?", id).
Updates(updates).Error
}
// UpdateAuthFlowID 更新认证流程ID
//
// 业务说明:
// - 记录e签宝企业认证流程ID
// - 用于回调处理和状态跟踪
//
// 参数:
// - ctx: 上下文
// - id: 认证ID
// - authFlowID: 认证流程ID
//
// 返回:
// - error: 更新失败时的错误信息
func (r *GormCertificationCommandRepository) UpdateAuthFlowID(ctx context.Context, id string, authFlowID string) error {
r.GetLogger().Info("更新认证流程ID",
zap.String("id", id),
zap.String("auth_flow_id", authFlowID))
updates := map[string]interface{}{
"auth_flow_id": authFlowID,
"updated_at": time.Now(),
}
return r.GetDB(ctx).Model(&entities.Certification{}).
Where("id = ?", id).
Updates(updates).Error
}
// UpdateContractInfo 更新合同信息
//
// 业务说明:
// - 记录合同相关的ID和URL信息
// - 用于合同管理和用户下载
//
// 参数:
// - ctx: 上下文
// - id: 认证ID
// - contractFileID: 合同文件ID
// - esignFlowID: e签宝流程ID
// - contractURL: 合同URL
// - contractSignURL: 合同签署URL
//
// 返回:
// - error: 更新失败时的错误信息
func (r *GormCertificationCommandRepository) UpdateContractInfo(ctx context.Context, id string, contractFileID, esignFlowID, contractURL, contractSignURL string) error {
r.GetLogger().Info("更新合同信息",
zap.String("id", id),
zap.String("contract_file_id", contractFileID),
zap.String("esign_flow_id", esignFlowID))
updates := map[string]interface{}{
"contract_file_id": contractFileID,
"esign_flow_id": esignFlowID,
"contract_url": contractURL,
"contract_sign_url": contractSignURL,
"updated_at": time.Now(),
}
return r.GetDB(ctx).Model(&entities.Certification{}).
Where("id = ?", id).
Updates(updates).Error
}
// UpdateFailureInfo 更新失败信息
//
// 业务说明:
// - 记录认证失败的原因和详细信息
// - 用于错误分析和用户提示
//
// 参数:
// - ctx: 上下文
// - id: 认证ID
// - reason: 失败原因
// - message: 失败详细信息
//
// 返回:
// - error: 更新失败时的错误信息
func (r *GormCertificationCommandRepository) UpdateFailureInfo(ctx context.Context, id string, reason enums.FailureReason, message string) error {
r.GetLogger().Info("更新失败信息",
zap.String("id", id),
zap.String("reason", string(reason)),
zap.String("message", message))
updates := map[string]interface{}{
"failure_reason": reason,
"failure_message": message,
"updated_at": time.Now(),
}
return r.GetDB(ctx).Model(&entities.Certification{}).
Where("id = ?", id).
Updates(updates).Error
}
// ================ 批量操作 ================
// BatchUpdateStatus 批量更新状态
//
// 业务说明:
// - 批量更新多个认证的状态
// - 适用于管理员批量操作
//
// 参数:
// - ctx: 上下文
// - ids: 认证ID列表
// - status: 新状态
//
// 返回:
// - error: 更新失败时的错误信息
func (r *GormCertificationCommandRepository) BatchUpdateStatus(ctx context.Context, ids []string, status enums.CertificationStatus) error {
if len(ids) == 0 {
return fmt.Errorf("批量更新状态ID列表不能为空")
}
r.GetLogger().Info("批量更新认证状态",
zap.Strings("ids", ids),
zap.String("status", string(status)))
updates := map[string]interface{}{
"status": status,
"updated_at": time.Now(),
}
result := r.GetDB(ctx).Model(&entities.Certification{}).
Where("id IN ?", ids).
Updates(updates)
if result.Error != nil {
return fmt.Errorf("批量更新认证状态失败: %w", result.Error)
}
r.GetLogger().Info("批量更新完成", zap.Int64("affected_rows", result.RowsAffected))
return nil
}
// ================ 事务支持 ================
// WithTx 使用事务
//
// 业务说明:
// - 返回支持事务的仓储实例
// - 用于复杂业务操作的事务一致性保证
//
// 参数:
// - tx: 事务对象
//
// 返回:
// - repositories.CertificationCommandRepository: 支持事务的仓储实例
func (r *GormCertificationCommandRepository) WithTx(tx interfaces.Transaction) repositories.CertificationCommandRepository {
// 获取事务的底层*gorm.DB
txDB := tx.GetDB()
if gormDB, ok := txDB.(*gorm.DB); ok {
return &GormCertificationCommandRepository{
CachedBaseRepositoryImpl: database.NewCachedBaseRepositoryImpl(gormDB, r.GetLogger(), CertificationsTable),
}
}
r.GetLogger().Warn("不支持的事务类型,返回原始仓储")
return r
}
// ================ 缓存管理方法 ================
// WarmupCache 预热认证缓存
//
// 业务说明:
// - 系统启动时预热常用查询的缓存
// - 提升首次访问的响应速度
//
// 预热策略:
// - 活跃认证30分钟长期缓存
// - 最近创建15分钟中期缓存
func (r *GormCertificationCommandRepository) WarmupCache(ctx context.Context) error {
r.GetLogger().Info("开始预热认证缓存")
queries := []database.WarmupQuery{
{
Name: "active_certifications",
TTL: CacheTTLWarmupLong,
Dest: &[]entities.Certification{},
},
{
Name: "recent_certifications",
TTL: CacheTTLWarmupMedium,
Dest: &[]entities.Certification{},
},
}
return r.WarmupCommonQueries(ctx, queries)
}
// RefreshCache 刷新认证缓存
//
// 业务说明:
// - 手动刷新认证相关的所有缓存
// - 适用于数据迁移或批量更新后的缓存清理
func (r *GormCertificationCommandRepository) RefreshCache(ctx context.Context) error {
r.GetLogger().Info("刷新认证缓存")
return r.CachedBaseRepositoryImpl.RefreshCache(ctx, CachePatternTable)
}
// GetCacheStats 获取缓存统计信息
//
// 返回当前Repository的缓存使用统计包括
// - 基础缓存信息(命中率、键数量等)
// - 特定的缓存模式列表
// - 性能指标
func (r *GormCertificationCommandRepository) GetCacheStats() map[string]interface{} {
stats := r.GetCacheInfo()
stats["specific_patterns"] = []string{
CachePatternTable,
CachePatternUser,
}
return stats
}

View File

@@ -0,0 +1,514 @@
package certification
import (
"context"
"fmt"
"strings"
"time"
"tyapi-server/internal/domains/certification/entities"
"tyapi-server/internal/domains/certification/enums"
"tyapi-server/internal/domains/certification/repositories"
"tyapi-server/internal/domains/certification/repositories/queries"
"tyapi-server/internal/shared/database"
"go.uber.org/zap"
"gorm.io/gorm"
)
// ================ 常量定义 ================
const (
// 缓存时间常量
QueryCacheTTLPrimaryQuery = 30 * time.Minute // 主键查询缓存时间
QueryCacheTTLBusinessQuery = 15 * time.Minute // 业务查询缓存时间
QueryCacheTTLUserQuery = 10 * time.Minute // 用户相关查询缓存时间
QueryCacheTTLSearchQuery = 2 * time.Minute // 搜索查询缓存时间
QueryCacheTTLActiveRecords = 5 * time.Minute // 活跃记录查询缓存时间
QueryCacheTTLWarmupLong = 30 * time.Minute // 预热长期缓存
QueryCacheTTLWarmupMedium = 15 * time.Minute // 预热中期缓存
// 缓存键模式常量
QueryCachePatternTable = "gorm_cache:certifications:*"
QueryCachePatternUser = "certification:user_id:*"
)
// ================ Repository 实现 ================
// GormCertificationQueryRepository 认证查询仓储GORM实现
//
// 特性说明:
// - 基于 CachedBaseRepositoryImpl 实现自动缓存管理
// - 支持多级缓存策略主键查询30分钟业务查询15分钟搜索2分钟
// - 自动缓存失效:写操作时自动清理相关缓存
// - 智能缓存选择:根据查询复杂度自动选择缓存策略
// - 内置监控支持:提供缓存统计和性能监控
type GormCertificationQueryRepository struct {
*database.CachedBaseRepositoryImpl
}
// 编译时检查接口实现
var _ repositories.CertificationQueryRepository = (*GormCertificationQueryRepository)(nil)
// NewGormCertificationQueryRepository 创建认证查询仓储
//
// 参数:
// - db: GORM数据库连接实例
// - logger: 日志记录器
//
// 返回:
// - repositories.CertificationQueryRepository: 仓储接口实现
func NewGormCertificationQueryRepository(
db *gorm.DB,
logger *zap.Logger,
) repositories.CertificationQueryRepository {
return &GormCertificationQueryRepository{
CachedBaseRepositoryImpl: database.NewCachedBaseRepositoryImpl(db, logger, CertificationsTable),
}
}
// ================ 基础查询操作 ================
// GetByID 根据ID获取认证
//
// 缓存策略:
// - 使用智能主键查询自动缓存30分钟
// - 主键查询命中率高,适合长期缓存
//
// 参数:
// - ctx: 上下文
// - id: 认证ID
//
// 返回:
// - *entities.Certification: 查询到的认证未找到时返回nil
// - error: 查询失败时的错误信息
func (r *GormCertificationQueryRepository) GetByID(ctx context.Context, id string) (*entities.Certification, error) {
var cert entities.Certification
if err := r.SmartGetByID(ctx, id, &cert); err != nil {
if err == gorm.ErrRecordNotFound {
return nil, fmt.Errorf("认证记录不存在")
}
return nil, fmt.Errorf("查询认证记录失败: %w", err)
}
return &cert, nil
}
// GetByUserID 根据用户ID获取认证
//
// 缓存策略:
// - 业务查询缓存15分钟
// - 用户查询频率较高,适合中期缓存
//
// 参数:
// - ctx: 上下文
// - userID: 用户ID
//
// 返回:
// - *entities.Certification: 查询到的认证未找到时返回nil
// - error: 查询失败时的错误信息
func (r *GormCertificationQueryRepository) GetByUserID(ctx context.Context, userID string) (*entities.Certification, error) {
var cert entities.Certification
err := r.SmartGetByField(ctx, &cert, "user_id", userID, QueryCacheTTLUserQuery)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, fmt.Errorf("用户尚未创建认证申请")
}
return nil, fmt.Errorf("查询用户认证记录失败: %w", err)
}
return &cert, nil
}
// Exists 检查认证是否存在
func (r *GormCertificationQueryRepository) Exists(ctx context.Context, id string) (bool, error) {
return r.ExistsEntity(ctx, id, &entities.Certification{})
}
// ================ 列表查询 ================
// List 分页列表查询
//
// 缓存策略:
// - 搜索查询短期缓存2分钟避免频繁数据库查询但保证实时性
// - 常规列表:智能缓存(根据查询复杂度自动选择缓存策略)
//
// 参数:
// - ctx: 上下文
// - query: 列表查询条件
//
// 返回:
// - []*entities.Certification: 查询结果列表
// - int64: 总记录数
// - error: 查询失败时的错误信息
func (r *GormCertificationQueryRepository) List(ctx context.Context, query *queries.ListCertificationsQuery) ([]*entities.Certification, int64, error) {
db := r.GetDB(ctx).Model(&entities.Certification{})
// 应用过滤条件
if query.UserID != "" {
db = db.Where("user_id = ?", query.UserID)
}
if query.Status != "" {
db = db.Where("status = ?", query.Status)
}
if len(query.Statuses) > 0 {
db = db.Where("status IN ?", query.Statuses)
}
// 获取总数
var total int64
if err := db.Count(&total).Error; err != nil {
return nil, 0, fmt.Errorf("查询认证总数失败: %w", err)
}
// 应用排序和分页
if query.SortBy != "" {
orderClause := query.SortBy
if query.SortOrder != "" {
orderClause += " " + strings.ToUpper(query.SortOrder)
}
db = db.Order(orderClause)
} else {
db = db.Order("created_at DESC")
}
offset := (query.Page - 1) * query.PageSize
db = db.Offset(offset).Limit(query.PageSize)
// 执行查询
var certifications []*entities.Certification
if err := db.Find(&certifications).Error; err != nil {
return nil, 0, fmt.Errorf("查询认证列表失败: %w", err)
}
return certifications, total, nil
}
// ListByUserIDs 根据用户ID列表查询
func (r *GormCertificationQueryRepository) ListByUserIDs(ctx context.Context, userIDs []string) ([]*entities.Certification, error) {
if len(userIDs) == 0 {
return []*entities.Certification{}, nil
}
var certifications []*entities.Certification
if err := r.GetDB(ctx).Where("user_id IN ?", userIDs).Find(&certifications).Error; err != nil {
return nil, fmt.Errorf("根据用户ID列表查询认证失败: %w", err)
}
return certifications, nil
}
// ListByStatus 根据状态查询
func (r *GormCertificationQueryRepository) ListByStatus(ctx context.Context, status enums.CertificationStatus, limit int) ([]*entities.Certification, error) {
db := r.GetDB(ctx).Where("status = ?", status)
if limit > 0 {
db = db.Limit(limit)
}
var certifications []*entities.Certification
if err := db.Find(&certifications).Error; err != nil {
return nil, fmt.Errorf("根据状态查询认证失败: %w", err)
}
return certifications, nil
}
// ================ 业务查询 ================
// FindByAuthFlowID 根据认证流程ID查询
//
// 缓存策略:
// - 业务查询缓存15分钟
// - 回调查询频率较高
//
// 参数:
// - ctx: 上下文
// - authFlowID: 认证流程ID
//
// 返回:
// - *entities.Certification: 查询到的认证未找到时返回nil
// - error: 查询失败时的错误信息
func (r *GormCertificationQueryRepository) FindByAuthFlowID(ctx context.Context, authFlowID string) (*entities.Certification, error) {
var cert entities.Certification
err := r.SmartGetByField(ctx, &cert, "auth_flow_id", authFlowID, QueryCacheTTLBusinessQuery)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, fmt.Errorf("认证流程不存在")
}
return nil, fmt.Errorf("根据认证流程ID查询失败: %w", err)
}
return &cert, nil
}
// FindByEsignFlowID 根据e签宝流程ID查询
//
// 缓存策略:
// - 业务查询缓存15分钟
// - 回调查询频率较高
//
// 参数:
// - ctx: 上下文
// - esignFlowID: e签宝流程ID
//
// 返回:
// - *entities.Certification: 查询到的认证未找到时返回nil
// - error: 查询失败时的错误信息
func (r *GormCertificationQueryRepository) FindByEsignFlowID(ctx context.Context, esignFlowID string) (*entities.Certification, error) {
var cert entities.Certification
err := r.SmartGetByField(ctx, &cert, "esign_flow_id", esignFlowID, QueryCacheTTLBusinessQuery)
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, fmt.Errorf("e签宝流程不存在")
}
return nil, fmt.Errorf("根据e签宝流程ID查询失败: %w", err)
}
return &cert, nil
}
// ListPendingRetry 查询待重试的认证
//
// 缓存策略:
// - 管理查询,不缓存保证数据实时性
//
// 参数:
// - ctx: 上下文
// - maxRetryCount: 最大重试次数
//
// 返回:
// - []*entities.Certification: 待重试的认证列表
// - error: 查询失败时的错误信息
func (r *GormCertificationQueryRepository) ListPendingRetry(ctx context.Context, maxRetryCount int) ([]*entities.Certification, error) {
var certifications []*entities.Certification
err := r.WithoutCache().GetDB(ctx).
Where("status IN ? AND retry_count < ?",
[]enums.CertificationStatus{
enums.StatusInfoRejected,
enums.StatusContractRejected,
enums.StatusContractExpired,
},
maxRetryCount).
Order("created_at ASC").
Find(&certifications).Error
if err != nil {
return nil, fmt.Errorf("查询待重试认证失败: %w", err)
}
return certifications, nil
}
// GetPendingCertifications 获取待处理认证
func (r *GormCertificationQueryRepository) GetPendingCertifications(ctx context.Context) ([]*entities.Certification, error) {
var certifications []*entities.Certification
err := r.WithoutCache().GetDB(ctx).
Where("status IN ?", []enums.CertificationStatus{
enums.StatusPending,
enums.StatusInfoSubmitted,
}).
Order("created_at ASC").
Find(&certifications).Error
if err != nil {
return nil, fmt.Errorf("查询待处理认证失败: %w", err)
}
return certifications, nil
}
// GetExpiredContracts 获取过期合同
func (r *GormCertificationQueryRepository) GetExpiredContracts(ctx context.Context) ([]*entities.Certification, error) {
var certifications []*entities.Certification
err := r.WithoutCache().GetDB(ctx).
Where("status = ?", enums.StatusContractExpired).
Order("updated_at DESC").
Find(&certifications).Error
if err != nil {
return nil, fmt.Errorf("查询过期合同失败: %w", err)
}
return certifications, nil
}
// GetCertificationsByDateRange 根据日期范围获取认证
func (r *GormCertificationQueryRepository) GetCertificationsByDateRange(ctx context.Context, startDate, endDate time.Time) ([]*entities.Certification, error) {
var certifications []*entities.Certification
err := r.GetDB(ctx).
Where("created_at BETWEEN ? AND ?", startDate, endDate).
Order("created_at DESC").
Find(&certifications).Error
if err != nil {
return nil, fmt.Errorf("根据日期范围查询认证失败: %w", err)
}
return certifications, nil
}
// GetUserActiveCertification 获取用户当前活跃认证
func (r *GormCertificationQueryRepository) GetUserActiveCertification(ctx context.Context, userID string) (*entities.Certification, error) {
var cert entities.Certification
err := r.GetDB(ctx).
Where("user_id = ? AND status NOT IN ?", userID, []enums.CertificationStatus{
enums.StatusContractSigned,
enums.StatusInfoRejected,
enums.StatusContractRejected,
enums.StatusContractExpired,
}).
First(&cert).Error
if err != nil {
if err == gorm.ErrRecordNotFound {
return nil, fmt.Errorf("用户没有活跃的认证申请")
}
return nil, fmt.Errorf("查询用户活跃认证失败: %w", err)
}
return &cert, nil
}
// ================ 统计查询 ================
// GetStatistics 获取统计数据
func (r *GormCertificationQueryRepository) GetStatistics(ctx context.Context, period repositories.CertificationTimePeriod) (*repositories.CertificationStatistics, error) {
now := time.Now()
var startDate time.Time
switch period {
case repositories.PeriodDaily:
startDate = now.AddDate(0, 0, -1)
case repositories.PeriodWeekly:
startDate = now.AddDate(0, 0, -7)
case repositories.PeriodMonthly:
startDate = now.AddDate(0, -1, 0)
case repositories.PeriodYearly:
startDate = now.AddDate(-1, 0, 0)
default:
startDate = now.AddDate(0, 0, -7)
}
// 使用短期缓存进行统计查询
var totalCount int64
r.WithShortCache().GetDB(ctx).Model(&entities.Certification{}).
Where("created_at BETWEEN ? AND ?", startDate, now).
Count(&totalCount)
var completedCount int64
r.WithShortCache().GetDB(ctx).Model(&entities.Certification{}).
Where("created_at BETWEEN ? AND ? AND status = ?", startDate, now, enums.StatusContractSigned).
Count(&completedCount)
successRate := float64(0)
if totalCount > 0 {
successRate = float64(completedCount) / float64(totalCount)
}
return &repositories.CertificationStatistics{
Period: period,
StartDate: startDate,
EndDate: now,
TotalCertifications: totalCount,
CompletedCount: completedCount,
SuccessRate: successRate,
StatusDistribution: make(map[enums.CertificationStatus]int64),
FailureDistribution: make(map[enums.FailureReason]int64),
AvgProcessingTime: 24 * time.Hour, // 简化实现
}, nil
}
// CountByStatus 按状态统计
func (r *GormCertificationQueryRepository) CountByStatus(ctx context.Context, status enums.CertificationStatus) (int64, error) {
var count int64
if err := r.WithShortCache().GetDB(ctx).Model(&entities.Certification{}).Where("status = ?", status).Count(&count).Error; err != nil {
return 0, fmt.Errorf("按状态统计认证失败: %w", err)
}
return count, nil
}
// CountByFailureReason 按失败原因统计
func (r *GormCertificationQueryRepository) CountByFailureReason(ctx context.Context, reason enums.FailureReason) (int64, error) {
var count int64
if err := r.WithShortCache().GetDB(ctx).Model(&entities.Certification{}).Where("failure_reason = ?", reason).Count(&count).Error; err != nil {
return 0, fmt.Errorf("按失败原因统计认证失败: %w", err)
}
return count, nil
}
// GetProgressStatistics 获取进度统计
func (r *GormCertificationQueryRepository) GetProgressStatistics(ctx context.Context) (*repositories.CertificationProgressStats, error) {
// 简化实现
return &repositories.CertificationProgressStats{
StatusProgress: make(map[enums.CertificationStatus]int64),
ProgressDistribution: make(map[int]int64),
StageTimeStats: make(map[string]*repositories.CertificationStageTimeInfo),
}, nil
}
// SearchByCompanyName 按公司名搜索
func (r *GormCertificationQueryRepository) SearchByCompanyName(ctx context.Context, companyName string, limit int) ([]*entities.Certification, error) {
// 简化实现,暂时返回空结果
r.GetLogger().Warn("按公司名搜索功能待实现,需要企业信息服务支持")
return []*entities.Certification{}, nil
}
// SearchByLegalPerson 按法人搜索
func (r *GormCertificationQueryRepository) SearchByLegalPerson(ctx context.Context, legalPersonName string, limit int) ([]*entities.Certification, error) {
// 简化实现,暂时返回空结果
r.GetLogger().Warn("按法人搜索功能待实现,需要企业信息服务支持")
return []*entities.Certification{}, nil
}
// InvalidateCache 清除缓存
func (r *GormCertificationQueryRepository) InvalidateCache(ctx context.Context, keys ...string) error {
// 简化实现,暂不处理缓存
return nil
}
// RefreshCache 刷新缓存
func (r *GormCertificationQueryRepository) RefreshCache(ctx context.Context, certificationID string) error {
// 简化实现,暂不处理缓存
return nil
}
// ================ 缓存管理方法 ================
// WarmupCache 预热认证查询缓存
//
// 业务说明:
// - 系统启动时预热常用查询的缓存
// - 提升首次访问的响应速度
//
// 预热策略:
// - 活跃认证30分钟长期缓存
// - 待处理认证15分钟中期缓存
func (r *GormCertificationQueryRepository) WarmupCache(ctx context.Context) error {
r.GetLogger().Info("开始预热认证查询缓存")
queries := []database.WarmupQuery{
{
Name: "active_certifications",
TTL: QueryCacheTTLWarmupLong,
Dest: &[]entities.Certification{},
},
{
Name: "pending_certifications",
TTL: QueryCacheTTLWarmupMedium,
Dest: &[]entities.Certification{},
},
}
return r.WarmupCommonQueries(ctx, queries)
}
// GetCacheStats 获取缓存统计信息
//
// 返回当前Repository的缓存使用统计包括
// - 基础缓存信息(命中率、键数量等)
// - 特定的缓存模式列表
// - 性能指标
func (r *GormCertificationQueryRepository) GetCacheStats() map[string]interface{} {
stats := r.GetCacheInfo()
stats["specific_patterns"] = []string{
QueryCachePatternTable,
QueryCachePatternUser,
}
return stats
}

View File

@@ -1,370 +0,0 @@
package repositories
import (
"context"
"errors"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
"tyapi-server/internal/domains/certification/entities"
"tyapi-server/internal/domains/certification/repositories"
"tyapi-server/internal/domains/certification/repositories/queries"
"tyapi-server/internal/shared/interfaces"
)
// GormCertificationRepository GORM认证仓储实现
type GormCertificationRepository struct {
db *gorm.DB
logger *zap.Logger
}
// 编译时检查接口实现
var _ repositories.CertificationRepository = (*GormCertificationRepository)(nil)
// NewGormCertificationRepository 创建GORM认证仓储
func NewGormCertificationRepository(db *gorm.DB, logger *zap.Logger) repositories.CertificationRepository {
return &GormCertificationRepository{
db: db,
logger: logger,
}
}
// ================ 基础CRUD操作 ================
// Create 创建认证申请
func (r *GormCertificationRepository) Create(ctx context.Context, cert entities.Certification) (entities.Certification, error) {
r.logger.Info("创建认证申请", zap.String("user_id", cert.UserID))
err := r.db.WithContext(ctx).Create(&cert).Error
return cert, err
}
// GetByID 根据ID获取认证申请
func (r *GormCertificationRepository) GetByID(ctx context.Context, id string) (entities.Certification, error) {
var cert entities.Certification
err := r.db.WithContext(ctx).Where("id = ?", id).First(&cert).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return entities.Certification{}, gorm.ErrRecordNotFound
}
return entities.Certification{}, err
}
return cert, err
}
// GetByAuthFlowID 根据认证流程ID获取认证申请
func (r *GormCertificationRepository) GetByAuthFlowID(ctx context.Context, authFlowID string) (entities.Certification, error) {
var cert entities.Certification
err := r.db.WithContext(ctx).Where("auth_flow_id = ?", authFlowID).First(&cert).Error
return cert, err
}
// GetByEsignFlowID 根据签署流程ID获取认证申请
func (r *GormCertificationRepository) GetByEsignFlowID(ctx context.Context, esignFlowID string) (entities.Certification, error) {
var cert entities.Certification
err := r.db.WithContext(ctx).Where("esign_flow_id = ?", esignFlowID).First(&cert).Error
return cert, err
}
// Update 更新认证申请
func (r *GormCertificationRepository) Update(ctx context.Context, cert entities.Certification) error {
r.logger.Info("更新认证申请", zap.String("id", cert.ID))
return r.db.WithContext(ctx).Save(&cert).Error
}
// Delete 删除认证申请
func (r *GormCertificationRepository) Delete(ctx context.Context, id string) error {
r.logger.Info("删除认证申请", zap.String("id", id))
return r.db.WithContext(ctx).Delete(&entities.Certification{}, "id = ?", id).Error
}
// SoftDelete 软删除认证申请
func (r *GormCertificationRepository) SoftDelete(ctx context.Context, id string) error {
r.logger.Info("软删除认证申请", zap.String("id", id))
return r.db.WithContext(ctx).Delete(&entities.Certification{}, "id = ?", id).Error
}
// Restore 恢复认证申请
func (r *GormCertificationRepository) Restore(ctx context.Context, id string) error {
r.logger.Info("恢复认证申请", zap.String("id", id))
return r.db.WithContext(ctx).Unscoped().Model(&entities.Certification{}).Where("id = ?", id).Update("deleted_at", nil).Error
}
// Count 统计认证申请数量
func (r *GormCertificationRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
var count int64
query := r.db.WithContext(ctx).Model(&entities.Certification{})
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
if options.Search != "" {
query = query.Where("user_id LIKE ?", "%"+options.Search+"%")
}
err := query.Count(&count).Error
return count, err
}
// Exists 检查认证申请是否存在
func (r *GormCertificationRepository) Exists(ctx context.Context, id string) (bool, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.Certification{}).Where("id = ?", id).Count(&count).Error
return count > 0, err
}
// CreateBatch 批量创建认证申请
func (r *GormCertificationRepository) CreateBatch(ctx context.Context, certs []entities.Certification) error {
r.logger.Info("批量创建认证申请", zap.Int("count", len(certs)))
return r.db.WithContext(ctx).Create(&certs).Error
}
// GetByIDs 根据ID列表获取认证申请
func (r *GormCertificationRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.Certification, error) {
var certs []entities.Certification
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&certs).Error
return certs, err
}
// UpdateBatch 批量更新认证申请
func (r *GormCertificationRepository) UpdateBatch(ctx context.Context, certs []entities.Certification) error {
r.logger.Info("批量更新认证申请", zap.Int("count", len(certs)))
return r.db.WithContext(ctx).Save(&certs).Error
}
// DeleteBatch 批量删除认证申请
func (r *GormCertificationRepository) DeleteBatch(ctx context.Context, ids []string) error {
r.logger.Info("批量删除认证申请", zap.Strings("ids", ids))
return r.db.WithContext(ctx).Delete(&entities.Certification{}, "id IN ?", ids).Error
}
// List 获取认证申请列表
func (r *GormCertificationRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.Certification, error) {
var certs []entities.Certification
query := r.db.WithContext(ctx).Model(&entities.Certification{})
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
if options.Search != "" {
query = query.Where("user_id LIKE ?", "%"+options.Search+"%")
}
if options.Sort != "" {
order := "ASC"
if options.Order != "" {
order = options.Order
}
query = query.Order(options.Sort + " " + order)
}
if options.Page > 0 && options.PageSize > 0 {
offset := (options.Page - 1) * options.PageSize
query = query.Offset(offset).Limit(options.PageSize)
}
return certs, query.Find(&certs).Error
}
// WithTx 使用事务
func (r *GormCertificationRepository) WithTx(tx interface{}) interfaces.Repository[entities.Certification] {
if gormTx, ok := tx.(*gorm.DB); ok {
return &GormCertificationRepository{
db: gormTx,
logger: r.logger,
}
}
return r
}
// ================ 业务方法 ================
// ListCertifications 获取认证申请列表(带分页和筛选)
func (r *GormCertificationRepository) ListCertifications(ctx context.Context, query *queries.ListCertificationsQuery) ([]*entities.Certification, int64, error) {
var certs []entities.Certification
var total int64
dbQuery := r.db.WithContext(ctx).Model(&entities.Certification{})
// 应用筛选条件
if query.UserID != "" {
dbQuery = dbQuery.Where("user_id = ?", query.UserID)
}
if query.Status != "" {
dbQuery = dbQuery.Where("status = ?", query.Status)
}
if query.StartDate != "" {
dbQuery = dbQuery.Where("created_at >= ?", query.StartDate)
}
if query.EndDate != "" {
dbQuery = dbQuery.Where("created_at <= ?", query.EndDate)
}
if query.EnterpriseName != "" {
// 简化企业名称查询,暂时不关联企业表
dbQuery = dbQuery.Where("user_id IN (SELECT user_id FROM enterprise_infos WHERE company_name LIKE ?)", "%"+query.EnterpriseName+"%")
}
// 统计总数
if err := dbQuery.Count(&total).Error; err != nil {
return nil, 0, err
}
// 应用分页
if query.Page > 0 && query.PageSize > 0 {
offset := (query.Page - 1) * query.PageSize
dbQuery = dbQuery.Offset(offset).Limit(query.PageSize)
}
// 排序
dbQuery = dbQuery.Order("created_at DESC")
// 执行查询
if err := dbQuery.Find(&certs).Error; err != nil {
return nil, 0, err
}
// 转换为指针切片
var result []*entities.Certification
for i := range certs {
result = append(result, &certs[i])
}
return result, total, nil
}
// GetByUserID 根据用户ID获取认证申请
func (r *GormCertificationRepository) GetByUserID(ctx context.Context, userID string) (*entities.Certification, error) {
var cert entities.Certification
err := r.db.WithContext(ctx).Where("user_id = ?", userID).First(&cert).Error
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, gorm.ErrRecordNotFound
}
return nil, err
}
return &cert, nil
}
// GetByStatus 根据状态获取认证申请列表
func (r *GormCertificationRepository) GetByStatus(ctx context.Context, status string) ([]*entities.Certification, error) {
var certs []entities.Certification
err := r.db.WithContext(ctx).Where("status = ?", status).Find(&certs).Error
if err != nil {
return nil, err
}
var result []*entities.Certification
for i := range certs {
result = append(result, &certs[i])
}
return result, nil
}
// UpdateStatus 更新认证状态
func (r *GormCertificationRepository) UpdateStatus(ctx context.Context, certificationID string, status string) error {
r.logger.Info("更新认证状态",
zap.String("certification_id", certificationID),
zap.String("status", status),
)
updates := map[string]interface{}{
"status": status,
"updated_at": time.Now(),
}
// 根据状态更新时间戳
switch status {
case "info_submitted":
updates["info_submitted_at"] = time.Now()
case "enterprise_verified":
updates["enterprise_verified_at"] = time.Now()
case "contract_applied":
updates["contract_applied_at"] = time.Now()
case "contract_signed":
updates["contract_signed_at"] = time.Now()
case "completed":
updates["completed_at"] = time.Now()
}
return r.db.WithContext(ctx).Model(&entities.Certification{}).
Where("id = ?", certificationID).
Updates(updates).Error
}
// GetPendingCertifications 获取待处理的认证申请
func (r *GormCertificationRepository) GetPendingCertifications(ctx context.Context) ([]*entities.Certification, error) {
return r.GetByStatus(ctx, "pending")
}
// GetStats 获取认证统计信息
func (r *GormCertificationRepository) GetStats(ctx context.Context) (*repositories.CertificationStats, error) {
var stats repositories.CertificationStats
// 总认证数
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).Count(&stats.TotalCertifications).Error; err != nil {
return nil, err
}
// 待处理认证数
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).Where("status = ?", "pending").Count(&stats.PendingCertifications).Error; err != nil {
return nil, err
}
// 已完成认证数
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).Where("status = ?", "completed").Count(&stats.CompletedCertifications).Error; err != nil {
return nil, err
}
// 今日提交数
today := time.Now().Format("2006-01-02")
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).
Where("DATE(created_at) = ?", today).
Count(&stats.TodaySubmissions).Error; err != nil {
return nil, err
}
return &stats, nil
}
// GetStatsByDateRange 根据日期范围获取认证统计信息
func (r *GormCertificationRepository) GetStatsByDateRange(ctx context.Context, startDate, endDate string) (*repositories.CertificationStats, error) {
var stats repositories.CertificationStats
// 总认证数
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).
Where("created_at BETWEEN ? AND ?", startDate, endDate).
Count(&stats.TotalCertifications).Error; err != nil {
return nil, err
}
// 待处理认证数
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).
Where("status = ? AND created_at BETWEEN ? AND ?", "pending", startDate, endDate).
Count(&stats.PendingCertifications).Error; err != nil {
return nil, err
}
// 已完成认证数
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).
Where("status = ? AND created_at BETWEEN ? AND ?", "completed", startDate, endDate).
Count(&stats.CompletedCertifications).Error; err != nil {
return nil, err
}
// 今日提交数
today := time.Now().Format("2006-01-02")
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).
Where("DATE(created_at) = ?", today).
Count(&stats.TodaySubmissions).Error; err != nil {
return nil, err
}
return &stats, nil
}

View File

@@ -1,596 +0,0 @@
package repositories
import (
"context"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
"tyapi-server/internal/domains/certification/entities"
"tyapi-server/internal/domains/certification/repositories"
"tyapi-server/internal/domains/certification/repositories/queries"
"tyapi-server/internal/shared/database"
"tyapi-server/internal/shared/interfaces"
)
// ================ 常量定义 ================
const (
// 表名常量
EnterpriseInfoSubmitRecordsTable = "enterprise_info_submit_records"
// 缓存时间常量
CacheTTLPrimaryQuery = 30 * time.Minute // 主键查询缓存时间
CacheTTLBusinessQuery = 15 * time.Minute // 业务查询缓存时间
CacheTTLUserQuery = 10 * time.Minute // 用户相关查询缓存时间
CacheTTLSearchQuery = 2 * time.Minute // 搜索查询缓存时间
CacheTTLActiveRecords = 5 * time.Minute // 活跃记录查询缓存时间
CacheTTLWarmupLong = 30 * time.Minute // 预热长期缓存
CacheTTLWarmupMedium = 15 * time.Minute // 预热中期缓存
// 缓存键模式常量
CachePatternTable = "gorm_cache:enterprise_info_submit_records:*"
CachePatternCertification = "enterprise_info:certification_id:*"
CachePatternUser = "enterprise_info:user_id:*"
// 业务常量
StatusActive = "active"
StatusPending = "pending"
)
// ================ Repository 实现 ================
// GormEnterpriseInfoSubmitRecordRepository 企业信息提交记录GORM仓储实现
//
// 特性说明:
// - 基于 CachedBaseRepositoryImpl 实现自动缓存管理
// - 支持多级缓存策略主键查询30分钟业务查询15分钟搜索2分钟
// - 自动缓存失效:写操作时自动清理相关缓存
// - 智能缓存选择:根据查询复杂度自动选择缓存策略
// - 内置监控支持:提供缓存统计和性能监控
type GormEnterpriseInfoSubmitRecordRepository struct {
*database.CachedBaseRepositoryImpl
}
// 编译时检查接口实现
var _ repositories.EnterpriseInfoSubmitRecordRepository = (*GormEnterpriseInfoSubmitRecordRepository)(nil)
// NewGormEnterpriseInfoSubmitRecordRepository 创建企业信息提交记录GORM仓储
//
// 参数:
// - db: GORM数据库连接实例
// - logger: 日志记录器
//
// 返回:
// - repositories.EnterpriseInfoSubmitRecordRepository: 仓储接口实现
func NewGormEnterpriseInfoSubmitRecordRepository(db *gorm.DB, logger *zap.Logger) repositories.EnterpriseInfoSubmitRecordRepository {
return &GormEnterpriseInfoSubmitRecordRepository{
CachedBaseRepositoryImpl: database.NewCachedBaseRepositoryImpl(db, logger, EnterpriseInfoSubmitRecordsTable),
}
}
// ================ Repository[T] 接口实现 ================
// Create 创建企业信息提交记录
//
// 业务说明:
// - 创建新的企业信息提交记录
// - 自动触发相关缓存失效
//
// 参数:
// - ctx: 上下文
// - record: 要创建的记录实体
//
// 返回:
// - entities.EnterpriseInfoSubmitRecord: 创建后的记录包含生成的ID
// - error: 创建失败时的错误信息
func (r *GormEnterpriseInfoSubmitRecordRepository) Create(ctx context.Context, record entities.EnterpriseInfoSubmitRecord) (entities.EnterpriseInfoSubmitRecord, error) {
r.GetLogger().Info("创建企业信息提交记录",
zap.String("user_id", record.UserID),
zap.String("company_name", record.CompanyName))
err := r.CreateEntity(ctx, &record)
return record, err
}
// GetByID 根据ID获取企业信息提交记录
//
// 缓存策略:
// - 使用智能主键查询自动缓存30分钟
// - 主键查询命中率高,适合长期缓存
//
// 参数:
// - ctx: 上下文
// - id: 记录ID
//
// 返回:
// - entities.EnterpriseInfoSubmitRecord: 查询到的记录
// - error: 查询失败或记录不存在时的错误
func (r *GormEnterpriseInfoSubmitRecordRepository) GetByID(ctx context.Context, id string) (entities.EnterpriseInfoSubmitRecord, error) {
var record entities.EnterpriseInfoSubmitRecord
err := r.SmartGetByID(ctx, id, &record)
return record, err
}
// Update 更新企业信息提交记录
//
// 缓存影响:
// - GORM缓存插件会自动失效相关缓存
// - 无需手动管理缓存一致性
//
// 参数:
// - ctx: 上下文
// - record: 要更新的记录实体
//
// 返回:
// - error: 更新失败时的错误信息
func (r *GormEnterpriseInfoSubmitRecordRepository) Update(ctx context.Context, record entities.EnterpriseInfoSubmitRecord) error {
r.GetLogger().Info("更新企业信息提交记录",
zap.String("id", record.ID),
zap.String("company_name", record.CompanyName))
return r.UpdateEntity(ctx, &record)
}
// CreateBatch 批量创建企业信息提交记录
func (r *GormEnterpriseInfoSubmitRecordRepository) CreateBatch(ctx context.Context, records []entities.EnterpriseInfoSubmitRecord) error {
r.GetLogger().Info("批量创建企业信息提交记录", zap.Int("count", len(records)))
return r.CreateBatchEntity(ctx, &records)
}
// GetByIDs 根据ID列表获取企业信息提交记录
func (r *GormEnterpriseInfoSubmitRecordRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.EnterpriseInfoSubmitRecord, error) {
var records []entities.EnterpriseInfoSubmitRecord
err := r.GetEntitiesByIDs(ctx, ids, &records)
return records, err
}
// UpdateBatch 批量更新企业信息提交记录
func (r *GormEnterpriseInfoSubmitRecordRepository) UpdateBatch(ctx context.Context, records []entities.EnterpriseInfoSubmitRecord) error {
r.GetLogger().Info("批量更新企业信息提交记录", zap.Int("count", len(records)))
return r.UpdateBatchEntity(ctx, &records)
}
// DeleteBatch 批量删除企业信息提交记录
func (r *GormEnterpriseInfoSubmitRecordRepository) DeleteBatch(ctx context.Context, ids []string) error {
r.GetLogger().Info("批量删除企业信息提交记录", zap.Strings("ids", ids))
return r.DeleteBatchEntity(ctx, ids, &entities.EnterpriseInfoSubmitRecord{})
}
// List 获取企业信息提交记录列表
//
// 缓存策略:
// - 搜索查询短期缓存2分钟避免频繁数据库查询但保证实时性
// - 常规列表:智能缓存(根据查询复杂度自动选择缓存策略)
//
// 参数:
// - ctx: 上下文
// - options: 列表查询选项(分页、排序、筛选、搜索等)
//
// 返回:
// - []entities.EnterpriseInfoSubmitRecord: 查询结果列表
// - error: 查询失败时的错误信息
func (r *GormEnterpriseInfoSubmitRecordRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.EnterpriseInfoSubmitRecord, error) {
var records []entities.EnterpriseInfoSubmitRecord
// 搜索查询:使用短期缓存避免频繁数据库查询
if options.Search != "" {
return r.handleSearchQuery(ctx, options)
}
// 常规列表:使用智能缓存策略
err := r.SmartList(ctx, &records, options)
return records, err
}
// ================ BaseRepository 接口实现 ================
// Delete 删除企业信息提交记录
func (r *GormEnterpriseInfoSubmitRecordRepository) Delete(ctx context.Context, id string) error {
return r.DeleteEntity(ctx, id, &entities.EnterpriseInfoSubmitRecord{})
}
// Exists 检查企业信息提交记录是否存在
func (r *GormEnterpriseInfoSubmitRecordRepository) Exists(ctx context.Context, id string) (bool, error) {
return r.ExistsEntity(ctx, id, &entities.EnterpriseInfoSubmitRecord{})
}
// Count 统计企业信息提交记录数量
//
// 缓存策略:
// - 搜索统计:使用自定义搜索逻辑,不缓存保证准确性
// - 常规统计:使用基础实现的缓存策略
func (r *GormEnterpriseInfoSubmitRecordRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
if options.Search != "" {
return r.CountWhere(ctx, &entities.EnterpriseInfoSubmitRecord{},
"company_name LIKE ? OR unified_social_code LIKE ? OR legal_person_name LIKE ?",
"%"+options.Search+"%", "%"+options.Search+"%", "%"+options.Search+"%")
}
return r.CountWithOptions(ctx, &entities.EnterpriseInfoSubmitRecord{}, options)
}
// SoftDelete 软删除企业信息提交记录
func (r *GormEnterpriseInfoSubmitRecordRepository) SoftDelete(ctx context.Context, id string) error {
return r.SoftDeleteEntity(ctx, id, &entities.EnterpriseInfoSubmitRecord{})
}
// Restore 恢复企业信息提交记录
func (r *GormEnterpriseInfoSubmitRecordRepository) Restore(ctx context.Context, id string) error {
return r.RestoreEntity(ctx, id, &entities.EnterpriseInfoSubmitRecord{})
}
// ================ 业务专用查询方法 ================
// GetByCertificationID 根据认证ID获取企业信息提交记录
//
// 业务说明:
// - 每个认证流程对应一个企业信息提交记录
// - 适用于认证流程中查询企业信息
//
// 缓存策略:
// - 业务查询缓存15分钟
// - 认证ID查询频率较高适合中期缓存
//
// 参数:
// - ctx: 上下文
// - certificationID: 认证流程ID
//
// 返回:
// - *entities.EnterpriseInfoSubmitRecord: 查询到的记录未找到时返回nil
// - error: 查询失败时的错误信息
func (r *GormEnterpriseInfoSubmitRecordRepository) GetByCertificationID(ctx context.Context, certificationID string) (*entities.EnterpriseInfoSubmitRecord, error) {
var record entities.EnterpriseInfoSubmitRecord
err := r.SmartGetByField(ctx, &record, "certification_id", certificationID, CacheTTLBusinessQuery)
if err != nil {
return nil, err
}
return &record, nil
}
// GetByUserID 根据用户ID获取企业信息提交记录列表
//
// 业务说明:
// - 获取某用户的所有企业信息提交记录
// - 按创建时间倒序排列,最新的在前
//
// 缓存策略:
// - 用户相关查询使用中期缓存10分钟
// - 用户查询频率中等,适合中期缓存
//
// 参数:
// - ctx: 上下文
// - userID: 用户ID
//
// 返回:
// - []*entities.EnterpriseInfoSubmitRecord: 查询结果列表
// - error: 查询失败时的错误信息
func (r *GormEnterpriseInfoSubmitRecordRepository) GetByUserID(ctx context.Context, userID string) ([]*entities.EnterpriseInfoSubmitRecord, error) {
var records []*entities.EnterpriseInfoSubmitRecord
err := r.WithMediumCache().GetDB(ctx).
Where("user_id = ?", userID).
Order("created_at DESC").
Find(&records).Error
return records, err
}
// GetLatestByUserID 根据用户ID获取最新的企业信息提交记录
//
// 业务说明:
// - 获取用户最新提交的企业信息记录
// - 适用于用户中心显示最新提交状态
//
// 缓存策略:
// - 最新记录查询缓存15分钟
// - 用户中心访问频率较高
func (r *GormEnterpriseInfoSubmitRecordRepository) GetLatestByUserID(ctx context.Context, userID string) (*entities.EnterpriseInfoSubmitRecord, error) {
var record entities.EnterpriseInfoSubmitRecord
err := r.GetDB(ctx).
Where("user_id = ?", userID).
Order("created_at DESC").
First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}
// ================ 业务状态管理方法 ================
// UpdateStatus 更新企业信息提交记录状态
//
// 业务说明:
// - 更新记录的审核状态和备注信息
// - 适用于管理员审核流程
//
// 缓存影响:
// - GORM缓存插件会自动失效表相关的缓存
// - 状态更新会影响列表查询和统计结果
//
// 参数:
// - ctx: 上下文
// - recordID: 记录ID
// - status: 新状态
// - reason: 状态变更原因或备注
//
// 返回:
// - error: 更新失败时的错误信息
func (r *GormEnterpriseInfoSubmitRecordRepository) UpdateStatus(ctx context.Context, recordID string, status string, reason string) error {
r.GetLogger().Info("更新企业信息提交记录状态",
zap.String("record_id", recordID),
zap.String("status", status),
zap.String("reason", reason))
updates := map[string]interface{}{
"status": status,
"updated_at": time.Now(),
}
if reason != "" {
updates["reason"] = reason
}
return r.GetDB(ctx).Model(&entities.EnterpriseInfoSubmitRecord{}).
Where("id = ?", recordID).
Updates(updates).Error
}
// ================ 高级查询方法 ================
// ListRecords 获取企业信息提交记录列表(带分页和高级筛选)
//
// 业务说明:
// - 管理员后台的高级查询接口
// - 支持多维度筛选和分页
//
// 参数:
// - ctx: 上下文
// - query: 高级查询条件
//
// 返回:
// - []*entities.EnterpriseInfoSubmitRecord: 查询结果
// - int64: 总记录数
// - error: 查询失败时的错误
func (r *GormEnterpriseInfoSubmitRecordRepository) ListRecords(ctx context.Context, query *queries.ListEnterpriseInfoSubmitRecordsQuery) ([]*entities.EnterpriseInfoSubmitRecord, int64, error) {
var records []*entities.EnterpriseInfoSubmitRecord
var total int64
dbQuery := r.GetDB(ctx).Model(&entities.EnterpriseInfoSubmitRecord{})
// 构建查询条件
dbQuery = r.buildQueryConditions(dbQuery, query)
// 统计总数
if err := dbQuery.Count(&total).Error; err != nil {
return nil, 0, err
}
// 应用分页和排序
dbQuery = r.applyPaginationAndSorting(dbQuery, query)
// 查询数据
if err := dbQuery.Find(&records).Error; err != nil {
return nil, 0, err
}
return records, total, nil
}
// ================ 缓存管理方法 ================
// GetActiveRecords 获取活跃记录
//
// 业务说明:
// - 获取状态为活跃的企业信息提交记录
// - 适用于仪表板统计
//
// 缓存策略:
// - 活跃记录查询使用短期缓存5分钟
// - 活跃状态变化较频繁,使用短期缓存
func (r *GormEnterpriseInfoSubmitRecordRepository) GetActiveRecords(ctx context.Context) ([]entities.EnterpriseInfoSubmitRecord, error) {
var records []entities.EnterpriseInfoSubmitRecord
err := r.WithShortCache().FindWithCache(ctx, &records, CacheTTLActiveRecords, "status = ?", StatusActive)
return records, err
}
// GetPendingRecords 获取待审核记录
//
// 业务说明:
// - 获取待审核的企业信息提交记录
// - 适用于管理员工作台
//
// 缓存策略:
// - 禁用缓存,保证数据实时性
// - 待审核状态需要实时准确的数据
func (r *GormEnterpriseInfoSubmitRecordRepository) GetPendingRecords(ctx context.Context) ([]entities.EnterpriseInfoSubmitRecord, error) {
var records []entities.EnterpriseInfoSubmitRecord
db := r.WithoutCache().GetDB(ctx)
err := db.Where("status = ?", StatusPending).
Order("created_at ASC").
Find(&records).Error
return records, err
}
// WarmupCache 预热企业信息提交记录缓存
//
// 业务说明:
// - 系统启动时预热常用查询的缓存
// - 提升首次访问的响应速度
//
// 预热策略:
// - 活跃记录30分钟长期缓存
// - 最近提交15分钟中期缓存
func (r *GormEnterpriseInfoSubmitRecordRepository) WarmupCache(ctx context.Context) error {
r.GetLogger().Info("开始预热企业信息提交记录缓存")
queries := []database.WarmupQuery{
{
Name: "active_records",
TTL: CacheTTLWarmupLong,
Dest: &[]entities.EnterpriseInfoSubmitRecord{},
},
{
Name: "recent_submissions",
TTL: CacheTTLWarmupMedium,
Dest: &[]entities.EnterpriseInfoSubmitRecord{},
},
}
return r.WarmupCommonQueries(ctx, queries)
}
// RefreshRecordCache 刷新记录缓存
//
// 业务说明:
// - 手动刷新企业信息提交记录相关的所有缓存
// - 适用于数据迁移或批量更新后的缓存清理
func (r *GormEnterpriseInfoSubmitRecordRepository) RefreshRecordCache(ctx context.Context) error {
r.GetLogger().Info("刷新企业信息提交记录缓存")
return r.RefreshCache(ctx, CachePatternTable)
}
// GetCacheStats 获取缓存统计信息
//
// 返回当前Repository的缓存使用统计包括
// - 基础缓存信息(命中率、键数量等)
// - 特定的缓存模式列表
// - 性能指标
func (r *GormEnterpriseInfoSubmitRecordRepository) GetCacheStats() map[string]interface{} {
stats := r.GetCacheInfo()
stats["specific_patterns"] = []string{
CachePatternTable,
CachePatternCertification,
CachePatternUser,
}
return stats
}
// ================ 私有辅助方法 ================
// handleSearchQuery 处理搜索查询
//
// 业务逻辑:
// - 支持按企业名称、统一社会信用代码、法定代表人姓名搜索
// - 使用短期缓存避免频繁数据库查询
//
// 参数:
// - ctx: 上下文
// - options: 查询选项
//
// 返回:
// - []entities.EnterpriseInfoSubmitRecord: 搜索结果
// - error: 查询失败时的错误
func (r *GormEnterpriseInfoSubmitRecordRepository) handleSearchQuery(ctx context.Context, options interfaces.ListOptions) ([]entities.EnterpriseInfoSubmitRecord, error) {
var records []entities.EnterpriseInfoSubmitRecord
db := r.GetDB(ctx).
Set("cache:enabled", true).
Set("cache:ttl", CacheTTLSearchQuery).
Model(&entities.EnterpriseInfoSubmitRecord{})
// 应用筛选条件
if options.Filters != nil {
for key, value := range options.Filters {
db = db.Where(key+" = ?", value)
}
}
// 企业信息特定的搜索逻辑
db = db.Where("company_name LIKE ? OR unified_social_code LIKE ? OR legal_person_name LIKE ?",
"%"+options.Search+"%", "%"+options.Search+"%", "%"+options.Search+"%")
// 应用预加载
for _, include := range options.Include {
db = db.Preload(include)
}
// 应用排序
db = r.applySorting(db, options)
// 应用分页
db = r.applyPagination(db, options)
return records, db.Find(&records).Error
}
// buildQueryConditions 构建查询条件
//
// 参数:
// - db: GORM数据库查询对象
// - query: 查询条件
//
// 返回:
// - *gorm.DB: 应用查询条件后的数据库对象
func (r *GormEnterpriseInfoSubmitRecordRepository) buildQueryConditions(db *gorm.DB, query *queries.ListEnterpriseInfoSubmitRecordsQuery) *gorm.DB {
if query.UserID != "" {
db = db.Where("user_id = ?", query.UserID)
}
if query.Status != "" {
db = db.Where("status = ?", query.Status)
}
if query.StartDate != "" {
db = db.Where("created_at >= ?", query.StartDate)
}
if query.EndDate != "" {
db = db.Where("created_at <= ?", query.EndDate)
}
return db
}
// applyPaginationAndSorting 应用分页和排序
//
// 参数:
// - db: GORM数据库查询对象
// - query: 查询条件
//
// 返回:
// - *gorm.DB: 应用分页和排序后的数据库对象
func (r *GormEnterpriseInfoSubmitRecordRepository) applyPaginationAndSorting(db *gorm.DB, query *queries.ListEnterpriseInfoSubmitRecordsQuery) *gorm.DB {
// 应用分页
offset := (query.Page - 1) * query.PageSize
db = db.Offset(offset).Limit(query.PageSize)
// 默认排序
db = db.Order("created_at DESC")
return db
}
// applySorting 应用排序规则
//
// 参数:
// - db: GORM数据库查询对象
// - options: 查询选项
//
// 返回:
// - *gorm.DB: 应用排序后的数据库对象
func (r *GormEnterpriseInfoSubmitRecordRepository) applySorting(db *gorm.DB, options interfaces.ListOptions) *gorm.DB {
if options.Sort != "" {
order := "ASC"
if options.Order == "desc" || options.Order == "DESC" {
order = "DESC"
}
return db.Order(options.Sort + " " + order)
}
return db.Order("created_at DESC")
}
// applyPagination 应用分页规则
//
// 参数:
// - db: GORM数据库查询对象
// - options: 查询选项
//
// 返回:
// - *gorm.DB: 应用分页后的数据库对象
func (r *GormEnterpriseInfoSubmitRecordRepository) applyPagination(db *gorm.DB, options interfaces.ListOptions) *gorm.DB {
if options.Page > 0 && options.PageSize > 0 {
offset := (options.Page - 1) * options.PageSize
return db.Offset(offset).Limit(options.PageSize)
}
return db
}

View File

@@ -1,315 +0,0 @@
package repositories
import (
"context"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
"tyapi-server/internal/domains/certification/entities"
"tyapi-server/internal/domains/certification/repositories"
"tyapi-server/internal/domains/certification/repositories/queries"
"tyapi-server/internal/shared/interfaces"
)
// GormEsignContractGenerateRecordRepository e签宝生成合同记录GORM仓储实现
type GormEsignContractGenerateRecordRepository struct {
db *gorm.DB
logger *zap.Logger
}
// 编译时检查接口实现
var _ repositories.EsignContractGenerateRecordRepository = (*GormEsignContractGenerateRecordRepository)(nil)
// NewGormEsignContractGenerateRecordRepository 创建e签宝生成合同记录GORM仓储
func NewGormEsignContractGenerateRecordRepository(db *gorm.DB, logger *zap.Logger) repositories.EsignContractGenerateRecordRepository {
return &GormEsignContractGenerateRecordRepository{
db: db,
logger: logger,
}
}
// ================ 基础CRUD操作 ================
// Create 创建e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) Create(ctx context.Context, record entities.EsignContractGenerateRecord) (entities.EsignContractGenerateRecord, error) {
r.logger.Info("创建e签宝生成合同记录", zap.String("certification_id", record.CertificationID))
err := r.db.WithContext(ctx).Create(&record).Error
return record, err
}
// GetByID 根据ID获取e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) GetByID(ctx context.Context, id string) (entities.EsignContractGenerateRecord, error) {
var record entities.EsignContractGenerateRecord
err := r.db.WithContext(ctx).Where("id = ?", id).First(&record).Error
return record, err
}
// Update 更新e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) Update(ctx context.Context, record entities.EsignContractGenerateRecord) error {
r.logger.Info("更新e签宝生成合同记录", zap.String("id", record.ID))
return r.db.WithContext(ctx).Save(&record).Error
}
// Delete 删除e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) Delete(ctx context.Context, id string) error {
r.logger.Info("删除e签宝生成合同记录", zap.String("id", id))
return r.db.WithContext(ctx).Delete(&entities.EsignContractGenerateRecord{}, "id = ?", id).Error
}
// SoftDelete 软删除e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) SoftDelete(ctx context.Context, id string) error {
r.logger.Info("软删除e签宝生成合同记录", zap.String("id", id))
return r.db.WithContext(ctx).Delete(&entities.EsignContractGenerateRecord{}, "id = ?", id).Error
}
// Restore 恢复e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) Restore(ctx context.Context, id string) error {
r.logger.Info("恢复e签宝生成合同记录", zap.String("id", id))
return r.db.WithContext(ctx).Unscoped().Model(&entities.EsignContractGenerateRecord{}).Where("id = ?", id).Update("deleted_at", nil).Error
}
// Count 统计e签宝生成合同记录数量
func (r *GormEsignContractGenerateRecordRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
var count int64
query := r.db.WithContext(ctx).Model(&entities.EsignContractGenerateRecord{})
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
if options.Search != "" {
query = query.Where("contract_name LIKE ?", "%"+options.Search+"%")
}
err := query.Count(&count).Error
return count, err
}
// Exists 检查e签宝生成合同记录是否存在
func (r *GormEsignContractGenerateRecordRepository) Exists(ctx context.Context, id string) (bool, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.EsignContractGenerateRecord{}).Where("id = ?", id).Count(&count).Error
return count > 0, err
}
// CreateBatch 批量创建e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) CreateBatch(ctx context.Context, records []entities.EsignContractGenerateRecord) error {
r.logger.Info("批量创建e签宝生成合同记录", zap.Int("count", len(records)))
return r.db.WithContext(ctx).Create(&records).Error
}
// GetByIDs 根据ID列表获取e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.EsignContractGenerateRecord, error) {
var records []entities.EsignContractGenerateRecord
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&records).Error
return records, err
}
// UpdateBatch 批量更新e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) UpdateBatch(ctx context.Context, records []entities.EsignContractGenerateRecord) error {
r.logger.Info("批量更新e签宝生成合同记录", zap.Int("count", len(records)))
return r.db.WithContext(ctx).Save(&records).Error
}
// DeleteBatch 批量删除e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) DeleteBatch(ctx context.Context, ids []string) error {
r.logger.Info("批量删除e签宝生成合同记录", zap.Strings("ids", ids))
return r.db.WithContext(ctx).Delete(&entities.EsignContractGenerateRecord{}, "id IN ?", ids).Error
}
// List 获取e签宝生成合同记录列表
func (r *GormEsignContractGenerateRecordRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.EsignContractGenerateRecord, error) {
var records []entities.EsignContractGenerateRecord
query := r.db.WithContext(ctx).Model(&entities.EsignContractGenerateRecord{})
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
if options.Search != "" {
query = query.Where("contract_name LIKE ?", "%"+options.Search+"%")
}
if options.Sort != "" {
order := "ASC"
if options.Order != "" {
order = options.Order
}
query = query.Order(options.Sort + " " + order)
}
if options.Page > 0 && options.PageSize > 0 {
offset := (options.Page - 1) * options.PageSize
query = query.Offset(offset).Limit(options.PageSize)
}
return records, query.Find(&records).Error
}
// WithTx 使用事务
func (r *GormEsignContractGenerateRecordRepository) WithTx(tx interface{}) interfaces.Repository[entities.EsignContractGenerateRecord] {
if gormTx, ok := tx.(*gorm.DB); ok {
return &GormEsignContractGenerateRecordRepository{
db: gormTx,
logger: r.logger,
}
}
return r
}
// ================ 业务方法 ================
// GetByCertificationID 根据认证ID获取e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) GetByCertificationID(ctx context.Context, certificationID string) (*entities.EsignContractGenerateRecord, error) {
var record entities.EsignContractGenerateRecord
err := r.db.WithContext(ctx).Where("certification_id = ?", certificationID).First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}
// GetByUserID 根据用户ID获取e签宝生成合同记录列表
func (r *GormEsignContractGenerateRecordRepository) GetByUserID(ctx context.Context, userID string) ([]*entities.EsignContractGenerateRecord, error) {
var records []entities.EsignContractGenerateRecord
err := r.db.WithContext(ctx).Where("user_id = ?", userID).Find(&records).Error
if err != nil {
return nil, err
}
var result []*entities.EsignContractGenerateRecord
for i := range records {
result = append(result, &records[i])
}
return result, nil
}
// GetLatestByCertificationID 根据认证ID获取最新的e签宝生成合同记录
func (r *GormEsignContractGenerateRecordRepository) GetLatestByCertificationID(ctx context.Context, certificationID string) (*entities.EsignContractGenerateRecord, error) {
var record entities.EsignContractGenerateRecord
err := r.db.WithContext(ctx).Where("certification_id = ?", certificationID).Order("created_at DESC").First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}
// ListRecords 获取e签宝生成合同记录列表带分页和筛选
func (r *GormEsignContractGenerateRecordRepository) ListRecords(ctx context.Context, query *queries.ListEsignContractGenerateRecordsQuery) ([]*entities.EsignContractGenerateRecord, int64, error) {
var records []entities.EsignContractGenerateRecord
var total int64
dbQuery := r.db.WithContext(ctx).Model(&entities.EsignContractGenerateRecord{})
// 应用筛选条件
if query.CertificationID != "" {
dbQuery = dbQuery.Where("certification_id = ?", query.CertificationID)
}
if query.UserID != "" {
dbQuery = dbQuery.Where("user_id = ?", query.UserID)
}
if query.Status != "" {
dbQuery = dbQuery.Where("status = ?", query.Status)
}
if query.ContractType != "" {
dbQuery = dbQuery.Where("contract_type = ?", query.ContractType)
}
if query.StartDate != "" {
dbQuery = dbQuery.Where("created_at >= ?", query.StartDate)
}
if query.EndDate != "" {
dbQuery = dbQuery.Where("created_at <= ?", query.EndDate)
}
// 统计总数
if err := dbQuery.Count(&total).Error; err != nil {
return nil, 0, err
}
// 应用分页
if query.Page > 0 && query.PageSize > 0 {
offset := (query.Page - 1) * query.PageSize
dbQuery = dbQuery.Offset(offset).Limit(query.PageSize)
}
// 排序
dbQuery = dbQuery.Order("created_at DESC")
// 执行查询
if err := dbQuery.Find(&records).Error; err != nil {
return nil, 0, err
}
// 转换为指针切片
var result []*entities.EsignContractGenerateRecord
for i := range records {
result = append(result, &records[i])
}
return result, total, nil
}
// UpdateStatus 更新状态
func (r *GormEsignContractGenerateRecordRepository) UpdateStatus(ctx context.Context, recordID string, status string, reason string) error {
r.logger.Info("更新e签宝生成合同记录状态",
zap.String("record_id", recordID),
zap.String("status", status),
)
updates := map[string]interface{}{
"status": status,
"updated_at": time.Now(),
}
// 根据状态设置相应的时间戳
switch status {
case "generating":
// 不需要额外时间戳
case "success":
updates["generated_at"] = time.Now()
case "failed":
updates["failed_at"] = time.Now()
updates["failure_reason"] = reason
}
return r.db.WithContext(ctx).Model(&entities.EsignContractGenerateRecord{}).
Where("id = ?", recordID).
Updates(updates).Error
}
// UpdateSuccessInfo 更新成功信息
func (r *GormEsignContractGenerateRecordRepository) UpdateSuccessInfo(ctx context.Context, recordID, esignFlowID, contractFileID, contractURL string) error {
r.logger.Info("更新e签宝生成合同记录成功信息",
zap.String("record_id", recordID),
zap.String("esign_flow_id", esignFlowID),
)
now := time.Now()
updates := map[string]interface{}{
"status": "success",
"esign_flow_id": esignFlowID,
"contract_file_id": contractFileID,
"contract_url": contractURL,
"generated_at": &now,
"updated_at": now,
}
return r.db.WithContext(ctx).Model(&entities.EsignContractGenerateRecord{}).
Where("id = ?", recordID).
Updates(updates).Error
}
// IncrementRetry 增加重试次数
func (r *GormEsignContractGenerateRecordRepository) IncrementRetry(ctx context.Context, recordID string) error {
r.logger.Info("增加e签宝生成合同记录重试次数", zap.String("record_id", recordID))
return r.db.WithContext(ctx).Model(&entities.EsignContractGenerateRecord{}).
Where("id = ?", recordID).
UpdateColumn("retry_count", gorm.Expr("retry_count + 1")).Error
}

View File

@@ -1,356 +0,0 @@
package repositories
import (
"context"
"time"
"go.uber.org/zap"
"gorm.io/gorm"
"tyapi-server/internal/domains/certification/entities"
"tyapi-server/internal/domains/certification/repositories"
"tyapi-server/internal/domains/certification/repositories/queries"
"tyapi-server/internal/shared/interfaces"
)
// GormEsignContractSignRecordRepository e签宝签署合同记录GORM仓储实现
type GormEsignContractSignRecordRepository struct {
db *gorm.DB
logger *zap.Logger
}
// 编译时检查接口实现
var _ repositories.EsignContractSignRecordRepository = (*GormEsignContractSignRecordRepository)(nil)
// NewGormEsignContractSignRecordRepository 创建e签宝签署合同记录GORM仓储
func NewGormEsignContractSignRecordRepository(db *gorm.DB, logger *zap.Logger) repositories.EsignContractSignRecordRepository {
return &GormEsignContractSignRecordRepository{
db: db,
logger: logger,
}
}
// ================ 基础CRUD操作 ================
// Create 创建e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) Create(ctx context.Context, record entities.EsignContractSignRecord) (entities.EsignContractSignRecord, error) {
r.logger.Info("创建e签宝签署合同记录", zap.String("certification_id", record.CertificationID))
err := r.db.WithContext(ctx).Create(&record).Error
return record, err
}
// GetByID 根据ID获取e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) GetByID(ctx context.Context, id string) (entities.EsignContractSignRecord, error) {
var record entities.EsignContractSignRecord
err := r.db.WithContext(ctx).Where("id = ?", id).First(&record).Error
return record, err
}
// Update 更新e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) Update(ctx context.Context, record entities.EsignContractSignRecord) error {
r.logger.Info("更新e签宝签署合同记录", zap.String("id", record.ID))
return r.db.WithContext(ctx).Save(&record).Error
}
// Delete 删除e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) Delete(ctx context.Context, id string) error {
r.logger.Info("删除e签宝签署合同记录", zap.String("id", id))
return r.db.WithContext(ctx).Delete(&entities.EsignContractSignRecord{}, "id = ?", id).Error
}
// SoftDelete 软删除e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) SoftDelete(ctx context.Context, id string) error {
r.logger.Info("软删除e签宝签署合同记录", zap.String("id", id))
return r.db.WithContext(ctx).Delete(&entities.EsignContractSignRecord{}, "id = ?", id).Error
}
// Restore 恢复e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) Restore(ctx context.Context, id string) error {
r.logger.Info("恢复e签宝签署合同记录", zap.String("id", id))
return r.db.WithContext(ctx).Unscoped().Model(&entities.EsignContractSignRecord{}).Where("id = ?", id).Update("deleted_at", nil).Error
}
// Count 统计e签宝签署合同记录数量
func (r *GormEsignContractSignRecordRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
var count int64
query := r.db.WithContext(ctx).Model(&entities.EsignContractSignRecord{})
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
if options.Search != "" {
query = query.Where("signer_name LIKE ?", "%"+options.Search+"%")
}
err := query.Count(&count).Error
return count, err
}
// Exists 检查e签宝签署合同记录是否存在
func (r *GormEsignContractSignRecordRepository) Exists(ctx context.Context, id string) (bool, error) {
var count int64
err := r.db.WithContext(ctx).Model(&entities.EsignContractSignRecord{}).Where("id = ?", id).Count(&count).Error
return count > 0, err
}
// CreateBatch 批量创建e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) CreateBatch(ctx context.Context, records []entities.EsignContractSignRecord) error {
r.logger.Info("批量创建e签宝签署合同记录", zap.Int("count", len(records)))
return r.db.WithContext(ctx).Create(&records).Error
}
// GetByIDs 根据ID列表获取e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.EsignContractSignRecord, error) {
var records []entities.EsignContractSignRecord
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&records).Error
return records, err
}
// UpdateBatch 批量更新e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) UpdateBatch(ctx context.Context, records []entities.EsignContractSignRecord) error {
r.logger.Info("批量更新e签宝签署合同记录", zap.Int("count", len(records)))
return r.db.WithContext(ctx).Save(&records).Error
}
// DeleteBatch 批量删除e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) DeleteBatch(ctx context.Context, ids []string) error {
r.logger.Info("批量删除e签宝签署合同记录", zap.Strings("ids", ids))
return r.db.WithContext(ctx).Delete(&entities.EsignContractSignRecord{}, "id IN ?", ids).Error
}
// List 获取e签宝签署合同记录列表
func (r *GormEsignContractSignRecordRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.EsignContractSignRecord, error) {
var records []entities.EsignContractSignRecord
query := r.db.WithContext(ctx).Model(&entities.EsignContractSignRecord{})
if options.Filters != nil {
for key, value := range options.Filters {
query = query.Where(key+" = ?", value)
}
}
if options.Search != "" {
query = query.Where("signer_name LIKE ?", "%"+options.Search+"%")
}
if options.Sort != "" {
order := "ASC"
if options.Order != "" {
order = options.Order
}
query = query.Order(options.Sort + " " + order)
}
if options.Page > 0 && options.PageSize > 0 {
offset := (options.Page - 1) * options.PageSize
query = query.Offset(offset).Limit(options.PageSize)
}
return records, query.Find(&records).Error
}
// WithTx 使用事务
func (r *GormEsignContractSignRecordRepository) WithTx(tx interface{}) interfaces.Repository[entities.EsignContractSignRecord] {
if gormTx, ok := tx.(*gorm.DB); ok {
return &GormEsignContractSignRecordRepository{
db: gormTx,
logger: r.logger,
}
}
return r
}
// ================ 业务方法 ================
// GetByCertificationID 根据认证ID获取e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) GetByCertificationID(ctx context.Context, certificationID string) (*entities.EsignContractSignRecord, error) {
var record entities.EsignContractSignRecord
err := r.db.WithContext(ctx).Where("certification_id = ?", certificationID).First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}
// GetByUserID 根据用户ID获取e签宝签署合同记录列表
func (r *GormEsignContractSignRecordRepository) GetByUserID(ctx context.Context, userID string) ([]*entities.EsignContractSignRecord, error) {
var records []entities.EsignContractSignRecord
err := r.db.WithContext(ctx).Where("user_id = ?", userID).Find(&records).Error
if err != nil {
return nil, err
}
var result []*entities.EsignContractSignRecord
for i := range records {
result = append(result, &records[i])
}
return result, nil
}
// GetLatestByCertificationID 根据认证ID获取最新的e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) GetLatestByCertificationID(ctx context.Context, certificationID string) (*entities.EsignContractSignRecord, error) {
var record entities.EsignContractSignRecord
err := r.db.WithContext(ctx).Where("certification_id = ?", certificationID).Order("created_at DESC").First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}
// GetByGenerateRecordID 根据生成记录ID获取e签宝签署合同记录
func (r *GormEsignContractSignRecordRepository) GetByGenerateRecordID(ctx context.Context, generateRecordID string) (*entities.EsignContractSignRecord, error) {
var record entities.EsignContractSignRecord
err := r.db.WithContext(ctx).Where("generate_record_id = ?", generateRecordID).First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}
// ListRecords 获取e签宝签署合同记录列表带分页和筛选
func (r *GormEsignContractSignRecordRepository) ListRecords(ctx context.Context, query *queries.ListEsignContractSignRecordsQuery) ([]*entities.EsignContractSignRecord, int64, error) {
var records []entities.EsignContractSignRecord
var total int64
dbQuery := r.db.WithContext(ctx).Model(&entities.EsignContractSignRecord{})
// 应用筛选条件
if query.CertificationID != "" {
dbQuery = dbQuery.Where("certification_id = ?", query.CertificationID)
}
if query.UserID != "" {
dbQuery = dbQuery.Where("user_id = ?", query.UserID)
}
if query.Status != "" {
dbQuery = dbQuery.Where("status = ?", query.Status)
}
if query.SignerName != "" {
dbQuery = dbQuery.Where("signer_name LIKE ?", "%"+query.SignerName+"%")
}
if query.StartDate != "" {
dbQuery = dbQuery.Where("created_at >= ?", query.StartDate)
}
if query.EndDate != "" {
dbQuery = dbQuery.Where("created_at <= ?", query.EndDate)
}
// 统计总数
if err := dbQuery.Count(&total).Error; err != nil {
return nil, 0, err
}
// 应用分页
if query.Page > 0 && query.PageSize > 0 {
offset := (query.Page - 1) * query.PageSize
dbQuery = dbQuery.Offset(offset).Limit(query.PageSize)
}
// 排序
dbQuery = dbQuery.Order("created_at DESC")
// 执行查询
if err := dbQuery.Find(&records).Error; err != nil {
return nil, 0, err
}
// 转换为指针切片
var result []*entities.EsignContractSignRecord
for i := range records {
result = append(result, &records[i])
}
return result, total, nil
}
// UpdateStatus 更新状态
func (r *GormEsignContractSignRecordRepository) UpdateStatus(ctx context.Context, recordID string, status string, reason string) error {
r.logger.Info("更新e签宝签署合同记录状态",
zap.String("record_id", recordID),
zap.String("status", status),
)
updates := map[string]interface{}{
"status": status,
"updated_at": time.Now(),
}
// 根据状态设置相应的时间戳
switch status {
case "signing":
// 不需要额外时间戳
case "success":
updates["signed_at"] = time.Now()
case "failed":
updates["failed_at"] = time.Now()
updates["failure_reason"] = reason
case "expired":
updates["expired_at"] = time.Now()
}
return r.db.WithContext(ctx).Model(&entities.EsignContractSignRecord{}).
Where("id = ?", recordID).
Updates(updates).Error
}
// UpdateSuccessInfo 更新成功信息
func (r *GormEsignContractSignRecordRepository) UpdateSuccessInfo(ctx context.Context, recordID, signedFileURL string) error {
r.logger.Info("更新e签宝签署合同记录成功信息",
zap.String("record_id", recordID),
)
now := time.Now()
updates := map[string]interface{}{
"status": "success",
"signed_file_url": signedFileURL,
"signed_at": &now,
"updated_at": now,
}
return r.db.WithContext(ctx).Model(&entities.EsignContractSignRecord{}).
Where("id = ?", recordID).
Updates(updates).Error
}
// SetSignURL 设置签署链接
func (r *GormEsignContractSignRecordRepository) SetSignURL(ctx context.Context, recordID, signURL string) error {
r.logger.Info("设置e签宝签署合同记录签署链接",
zap.String("record_id", recordID),
)
updates := map[string]interface{}{
"sign_url": signURL,
"updated_at": time.Now(),
}
return r.db.WithContext(ctx).Model(&entities.EsignContractSignRecord{}).
Where("id = ?", recordID).
Updates(updates).Error
}
// IncrementRetry 增加重试次数
func (r *GormEsignContractSignRecordRepository) IncrementRetry(ctx context.Context, recordID string) error {
r.logger.Info("增加e签宝签署合同记录重试次数", zap.String("record_id", recordID))
return r.db.WithContext(ctx).Model(&entities.EsignContractSignRecord{}).
Where("id = ?", recordID).
UpdateColumn("retry_count", gorm.Expr("retry_count + 1")).Error
}
// MarkExpiredRecords 标记过期的记录
func (r *GormEsignContractSignRecordRepository) MarkExpiredRecords(ctx context.Context) error {
r.logger.Info("标记过期的e签宝签署合同记录")
now := time.Now()
updates := map[string]interface{}{
"status": "expired",
"expired_at": &now,
"updated_at": now,
}
return r.db.WithContext(ctx).Model(&entities.EsignContractSignRecord{}).
Where("status = ? AND expired_at < ?", "pending", now).
Updates(updates).Error
}