temp
This commit is contained in:
@@ -2,6 +2,7 @@ package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"go.uber.org/zap"
|
||||
@@ -43,6 +44,26 @@ func (r *GormCertificationRepository) Create(ctx context.Context, cert entities.
|
||||
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
|
||||
}
|
||||
|
||||
@@ -179,9 +200,6 @@ func (r *GormCertificationRepository) ListCertifications(ctx context.Context, qu
|
||||
if query.Status != "" {
|
||||
dbQuery = dbQuery.Where("status = ?", query.Status)
|
||||
}
|
||||
if query.AdminID != "" {
|
||||
dbQuery = dbQuery.Where("admin_id = ?", query.AdminID)
|
||||
}
|
||||
if query.StartDate != "" {
|
||||
dbQuery = dbQuery.Where("created_at >= ?", query.StartDate)
|
||||
}
|
||||
@@ -189,8 +207,8 @@ func (r *GormCertificationRepository) ListCertifications(ctx context.Context, qu
|
||||
dbQuery = dbQuery.Where("created_at <= ?", query.EndDate)
|
||||
}
|
||||
if query.EnterpriseName != "" {
|
||||
dbQuery = dbQuery.Joins("JOIN enterprises ON certifications.enterprise_id = enterprises.id").
|
||||
Where("enterprises.enterprise_name LIKE ?", "%"+query.EnterpriseName+"%")
|
||||
// 简化企业名称查询,暂时不关联企业表
|
||||
dbQuery = dbQuery.Where("user_id IN (SELECT user_id FROM enterprise_infos WHERE company_name LIKE ?)", "%"+query.EnterpriseName+"%")
|
||||
}
|
||||
|
||||
// 统计总数
|
||||
@@ -199,24 +217,26 @@ func (r *GormCertificationRepository) ListCertifications(ctx context.Context, qu
|
||||
}
|
||||
|
||||
// 应用分页
|
||||
offset := (query.Page - 1) * query.PageSize
|
||||
dbQuery = dbQuery.Offset(offset).Limit(query.PageSize)
|
||||
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
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
certPtrs := make([]*entities.Certification, len(certs))
|
||||
var result []*entities.Certification
|
||||
for i := range certs {
|
||||
certPtrs[i] = &certs[i]
|
||||
result = append(result, &certs[i])
|
||||
}
|
||||
|
||||
return certPtrs, total, nil
|
||||
return result, total, nil
|
||||
}
|
||||
|
||||
// GetByUserID 根据用户ID获取认证申请
|
||||
@@ -224,6 +244,9 @@ func (r *GormCertificationRepository) GetByUserID(ctx context.Context, userID st
|
||||
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
|
||||
@@ -237,82 +260,73 @@ func (r *GormCertificationRepository) GetByStatus(ctx context.Context, status st
|
||||
return nil, err
|
||||
}
|
||||
|
||||
certPtrs := make([]*entities.Certification, len(certs))
|
||||
var result []*entities.Certification
|
||||
for i := range certs {
|
||||
certPtrs[i] = &certs[i]
|
||||
result = append(result, &certs[i])
|
||||
}
|
||||
|
||||
return certPtrs, nil
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// UpdateStatus 更新认证状态
|
||||
func (r *GormCertificationRepository) UpdateStatus(ctx context.Context, certificationID string, status string, adminID *string, notes string) error {
|
||||
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,
|
||||
"status": status,
|
||||
"updated_at": time.Now(),
|
||||
}
|
||||
|
||||
if adminID != nil {
|
||||
updates["admin_id"] = *adminID
|
||||
}
|
||||
|
||||
if notes != "" {
|
||||
updates["approval_notes"] = notes
|
||||
}
|
||||
|
||||
// 根据状态设置相应的时间戳
|
||||
// 根据状态更新时间戳
|
||||
switch status {
|
||||
case "INFO_SUBMITTED":
|
||||
case "info_submitted":
|
||||
updates["info_submitted_at"] = time.Now()
|
||||
case "FACE_VERIFIED":
|
||||
updates["face_verified_at"] = time.Now()
|
||||
case "CONTRACT_APPLIED":
|
||||
case "enterprise_verified":
|
||||
updates["enterprise_verified_at"] = time.Now()
|
||||
case "contract_applied":
|
||||
updates["contract_applied_at"] = time.Now()
|
||||
case "CONTRACT_APPROVED":
|
||||
updates["contract_approved_at"] = time.Now()
|
||||
case "CONTRACT_SIGNED":
|
||||
case "contract_signed":
|
||||
updates["contract_signed_at"] = time.Now()
|
||||
case "COMPLETED":
|
||||
case "completed":
|
||||
updates["completed_at"] = time.Now()
|
||||
}
|
||||
|
||||
return r.db.WithContext(ctx).
|
||||
Model(&entities.Certification{}).
|
||||
return r.db.WithContext(ctx).Model(&entities.Certification{}).
|
||||
Where("id = ?", certificationID).
|
||||
Updates(updates).Error
|
||||
}
|
||||
|
||||
// GetPendingCertifications 获取待审核的认证申请
|
||||
// GetPendingCertifications 获取待处理的认证申请
|
||||
func (r *GormCertificationRepository) GetPendingCertifications(ctx context.Context) ([]*entities.Certification, error) {
|
||||
return r.GetByStatus(ctx, "CONTRACT_PENDING")
|
||||
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 = ?", "CONTRACT_PENDING").Count(&stats.PendingCertifications).Error; err != nil {
|
||||
// 待处理认证数
|
||||
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
|
||||
}
|
||||
|
||||
// 被拒绝认证申请数
|
||||
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).Where("status = ?", "REJECTED").Count(&stats.RejectedCertifications).Error; err != nil {
|
||||
// 已完成认证数
|
||||
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).Where("status = ?", "completed").Count(&stats.CompletedCertifications).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 今日提交数
|
||||
today := time.Now().Truncate(24 * time.Hour)
|
||||
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).Where("created_at >= ?", today).Count(&stats.TodaySubmissions).Error; err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -323,29 +337,32 @@ func (r *GormCertificationRepository) GetStats(ctx context.Context) (*repositori
|
||||
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 {
|
||||
// 总认证数
|
||||
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 ?", "CONTRACT_PENDING", startDate, endDate).Count(&stats.PendingCertifications).Error; err != nil {
|
||||
// 待处理认证数
|
||||
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
|
||||
}
|
||||
|
||||
// 被拒绝认证申请数
|
||||
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).Where("status = ? AND created_at BETWEEN ? AND ?", "REJECTED", startDate, endDate).Count(&stats.RejectedCertifications).Error; err != nil {
|
||||
// 已完成认证数
|
||||
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().Truncate(24 * time.Hour)
|
||||
if err := r.db.WithContext(ctx).Model(&entities.Certification{}).Where("created_at >= ?", today).Count(&stats.TodaySubmissions).Error; err != nil {
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -1,422 +0,0 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// GormContractRecordRepository GORM合同记录仓储实现
|
||||
type GormContractRecordRepository struct {
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// 编译时检查接口实现
|
||||
var _ repositories.ContractRecordRepository = (*GormContractRecordRepository)(nil)
|
||||
|
||||
// NewGormContractRecordRepository 创建GORM合同记录仓储
|
||||
func NewGormContractRecordRepository(db *gorm.DB, logger *zap.Logger) repositories.ContractRecordRepository {
|
||||
return &GormContractRecordRepository{
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// ================ 基础CRUD操作 ================
|
||||
|
||||
// Create 创建合同记录
|
||||
func (r *GormContractRecordRepository) Create(ctx context.Context, record entities.ContractRecord) (entities.ContractRecord, error) {
|
||||
if err := r.db.WithContext(ctx).Create(&record).Error; err != nil {
|
||||
r.logger.Error("创建合同记录失败",
|
||||
zap.String("certification_id", record.CertificationID),
|
||||
zap.String("contract_type", record.ContractType),
|
||||
zap.Error(err),
|
||||
)
|
||||
return entities.ContractRecord{}, fmt.Errorf("创建合同记录失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("合同记录创建成功",
|
||||
zap.String("id", record.ID),
|
||||
zap.String("contract_type", record.ContractType),
|
||||
)
|
||||
|
||||
return record, nil
|
||||
}
|
||||
|
||||
// GetByID 根据ID获取合同记录
|
||||
func (r *GormContractRecordRepository) GetByID(ctx context.Context, id string) (entities.ContractRecord, error) {
|
||||
var record entities.ContractRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).First(&record, "id = ?", id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return entities.ContractRecord{}, fmt.Errorf("合同记录不存在")
|
||||
}
|
||||
r.logger.Error("获取合同记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return entities.ContractRecord{}, fmt.Errorf("获取合同记录失败: %w", err)
|
||||
}
|
||||
|
||||
return record, nil
|
||||
}
|
||||
|
||||
// Update 更新合同记录
|
||||
func (r *GormContractRecordRepository) Update(ctx context.Context, record entities.ContractRecord) error {
|
||||
if err := r.db.WithContext(ctx).Save(&record).Error; err != nil {
|
||||
r.logger.Error("更新合同记录失败",
|
||||
zap.String("id", record.ID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("更新合同记录失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete 删除合同记录
|
||||
func (r *GormContractRecordRepository) Delete(ctx context.Context, id string) error {
|
||||
if err := r.db.WithContext(ctx).Delete(&entities.ContractRecord{}, "id = ?", id).Error; err != nil {
|
||||
r.logger.Error("删除合同记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("删除合同记录失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SoftDelete 软删除合同记录
|
||||
func (r *GormContractRecordRepository) SoftDelete(ctx context.Context, id string) error {
|
||||
return r.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// Restore 恢复合同记录
|
||||
func (r *GormContractRecordRepository) Restore(ctx context.Context, id string) error {
|
||||
if err := r.db.WithContext(ctx).Unscoped().Model(&entities.ContractRecord{}).Where("id = ?", id).Update("deleted_at", nil).Error; err != nil {
|
||||
r.logger.Error("恢复合同记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("恢复合同记录失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("合同记录恢复成功", zap.String("id", id))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Count 统计合同记录数量
|
||||
func (r *GormContractRecordRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
|
||||
var count int64
|
||||
query := r.db.WithContext(ctx).Model(&entities.ContractRecord{})
|
||||
|
||||
if options.Filters != nil {
|
||||
for key, value := range options.Filters {
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
if options.Search != "" {
|
||||
query = query.Where("contract_type LIKE ? OR contract_name LIKE ?", "%"+options.Search+"%", "%"+options.Search+"%")
|
||||
}
|
||||
|
||||
return count, query.Count(&count).Error
|
||||
}
|
||||
|
||||
// Exists 检查合同记录是否存在
|
||||
func (r *GormContractRecordRepository) Exists(ctx context.Context, id string) (bool, error) {
|
||||
var count int64
|
||||
err := r.db.WithContext(ctx).Model(&entities.ContractRecord{}).Where("id = ?", id).Count(&count).Error
|
||||
return count > 0, err
|
||||
}
|
||||
|
||||
// CreateBatch 批量创建合同记录
|
||||
func (r *GormContractRecordRepository) CreateBatch(ctx context.Context, records []entities.ContractRecord) error {
|
||||
r.logger.Info("批量创建合同记录", zap.Int("count", len(records)))
|
||||
return r.db.WithContext(ctx).Create(&records).Error
|
||||
}
|
||||
|
||||
// GetByIDs 根据ID列表获取合同记录
|
||||
func (r *GormContractRecordRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.ContractRecord, error) {
|
||||
var records []entities.ContractRecord
|
||||
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&records).Error
|
||||
return records, err
|
||||
}
|
||||
|
||||
// UpdateBatch 批量更新合同记录
|
||||
func (r *GormContractRecordRepository) UpdateBatch(ctx context.Context, records []entities.ContractRecord) error {
|
||||
r.logger.Info("批量更新合同记录", zap.Int("count", len(records)))
|
||||
return r.db.WithContext(ctx).Save(&records).Error
|
||||
}
|
||||
|
||||
// DeleteBatch 批量删除合同记录
|
||||
func (r *GormContractRecordRepository) DeleteBatch(ctx context.Context, ids []string) error {
|
||||
r.logger.Info("批量删除合同记录", zap.Strings("ids", ids))
|
||||
return r.db.WithContext(ctx).Delete(&entities.ContractRecord{}, "id IN ?", ids).Error
|
||||
}
|
||||
|
||||
// List 获取合同记录列表
|
||||
func (r *GormContractRecordRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.ContractRecord, error) {
|
||||
var records []entities.ContractRecord
|
||||
query := r.db.WithContext(ctx).Model(&entities.ContractRecord{})
|
||||
|
||||
if options.Filters != nil {
|
||||
for key, value := range options.Filters {
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
if options.Search != "" {
|
||||
query = query.Where("contract_type LIKE ? OR contract_name LIKE ?", "%"+options.Search+"%", "%"+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 *GormContractRecordRepository) WithTx(tx interface{}) interfaces.Repository[entities.ContractRecord] {
|
||||
if gormTx, ok := tx.(*gorm.DB); ok {
|
||||
return &GormContractRecordRepository{
|
||||
db: gormTx,
|
||||
logger: r.logger,
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ================ 业务方法 ================
|
||||
|
||||
// GetByCertificationID 根据认证申请ID获取合同记录列表
|
||||
func (r *GormContractRecordRepository) GetByCertificationID(ctx context.Context, certificationID string) ([]*entities.ContractRecord, error) {
|
||||
var records []entities.ContractRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).Where("certification_id = ?", certificationID).Order("created_at DESC").Find(&records).Error; err != nil {
|
||||
r.logger.Error("根据认证申请ID获取合同记录失败",
|
||||
zap.String("certification_id", certificationID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, fmt.Errorf("获取合同记录失败: %w", err)
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.ContractRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, nil
|
||||
}
|
||||
|
||||
// GetLatestByCertificationID 根据认证申请ID获取最新的合同记录
|
||||
func (r *GormContractRecordRepository) GetLatestByCertificationID(ctx context.Context, certificationID string) (*entities.ContractRecord, error) {
|
||||
var record entities.ContractRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).Where("certification_id = ?", certificationID).Order("created_at DESC").First(&record).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, fmt.Errorf("合同记录不存在")
|
||||
}
|
||||
r.logger.Error("根据认证申请ID获取最新合同记录失败",
|
||||
zap.String("certification_id", certificationID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, fmt.Errorf("获取合同记录失败: %w", err)
|
||||
}
|
||||
|
||||
return &record, nil
|
||||
}
|
||||
|
||||
// ListRecords 获取合同记录列表(带分页和筛选)
|
||||
func (r *GormContractRecordRepository) ListRecords(ctx context.Context, query *queries.ListContractRecordsQuery) ([]*entities.ContractRecord, int64, error) {
|
||||
var records []entities.ContractRecord
|
||||
var total int64
|
||||
|
||||
dbQuery := r.db.WithContext(ctx).Model(&entities.ContractRecord{})
|
||||
|
||||
// 应用筛选条件
|
||||
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.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
|
||||
}
|
||||
|
||||
// 应用分页
|
||||
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
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.ContractRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, total, nil
|
||||
}
|
||||
|
||||
// UpdateContractStatus 更新合同状态
|
||||
func (r *GormContractRecordRepository) UpdateContractStatus(ctx context.Context, recordID string, status string, adminID *string, notes string) error {
|
||||
updates := map[string]interface{}{
|
||||
"status": status,
|
||||
}
|
||||
|
||||
if adminID != nil {
|
||||
updates["admin_id"] = *adminID
|
||||
}
|
||||
|
||||
if notes != "" {
|
||||
updates["admin_notes"] = notes
|
||||
}
|
||||
|
||||
if err := r.db.WithContext(ctx).
|
||||
Model(&entities.ContractRecord{}).
|
||||
Where("id = ?", recordID).
|
||||
Updates(updates).Error; err != nil {
|
||||
r.logger.Error("更新合同状态失败",
|
||||
zap.String("record_id", recordID),
|
||||
zap.String("status", status),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("更新合同状态失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("合同状态更新成功",
|
||||
zap.String("record_id", recordID),
|
||||
zap.String("status", status),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetByUserID 根据用户ID获取合同记录列表
|
||||
func (r *GormContractRecordRepository) GetByUserID(ctx context.Context, userID string, page, pageSize int) ([]*entities.ContractRecord, int, error) {
|
||||
var records []entities.ContractRecord
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(ctx).Model(&entities.ContractRecord{}).Where("user_id = ?", userID)
|
||||
|
||||
// 获取总数
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
r.logger.Error("获取用户合同记录总数失败", zap.Error(err))
|
||||
return nil, 0, fmt.Errorf("获取合同记录总数失败: %w", err)
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (page - 1) * pageSize
|
||||
if err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&records).Error; err != nil {
|
||||
r.logger.Error("获取用户合同记录列表失败", zap.Error(err))
|
||||
return nil, 0, fmt.Errorf("获取合同记录列表失败: %w", err)
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.ContractRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, int(total), nil
|
||||
}
|
||||
|
||||
// GetByStatus 根据状态获取合同记录列表
|
||||
func (r *GormContractRecordRepository) GetByStatus(ctx context.Context, status string, page, pageSize int) ([]*entities.ContractRecord, int, error) {
|
||||
var records []entities.ContractRecord
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(ctx).Model(&entities.ContractRecord{}).Where("status = ?", status)
|
||||
|
||||
// 获取总数
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
r.logger.Error("根据状态获取合同记录总数失败", zap.Error(err))
|
||||
return nil, 0, fmt.Errorf("获取合同记录总数失败: %w", err)
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (page - 1) * pageSize
|
||||
if err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&records).Error; err != nil {
|
||||
r.logger.Error("根据状态获取合同记录列表失败", zap.Error(err))
|
||||
return nil, 0, fmt.Errorf("获取合同记录列表失败: %w", err)
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.ContractRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, int(total), nil
|
||||
}
|
||||
|
||||
// GetPendingContracts 获取待审核的合同记录
|
||||
func (r *GormContractRecordRepository) GetPendingContracts(ctx context.Context, page, pageSize int) ([]*entities.ContractRecord, int, error) {
|
||||
return r.GetByStatus(ctx, "PENDING", page, pageSize)
|
||||
}
|
||||
|
||||
// GetExpiredSigningContracts 获取签署链接已过期的合同记录
|
||||
func (r *GormContractRecordRepository) GetExpiredSigningContracts(ctx context.Context, limit int) ([]*entities.ContractRecord, error) {
|
||||
var records []entities.ContractRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).
|
||||
Where("expires_at < NOW() AND status = ?", "APPROVED").
|
||||
Limit(limit).
|
||||
Order("expires_at ASC").
|
||||
Find(&records).Error; err != nil {
|
||||
r.logger.Error("获取过期签署合同记录失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("获取过期签署合同记录失败: %w", err)
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.ContractRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, nil
|
||||
}
|
||||
|
||||
// GetExpiredContracts 获取已过期的合同记录(通用方法)
|
||||
func (r *GormContractRecordRepository) GetExpiredContracts(ctx context.Context, limit int) ([]*entities.ContractRecord, error) {
|
||||
return r.GetExpiredSigningContracts(ctx, limit)
|
||||
}
|
||||
@@ -0,0 +1,596 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,315 @@
|
||||
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
|
||||
}
|
||||
@@ -0,0 +1,356 @@
|
||||
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
|
||||
}
|
||||
@@ -1,394 +0,0 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// GormFaceVerifyRecordRepository GORM人脸识别记录仓储实现
|
||||
type GormFaceVerifyRecordRepository struct {
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// 编译时检查接口实现
|
||||
var _ repositories.FaceVerifyRecordRepository = (*GormFaceVerifyRecordRepository)(nil)
|
||||
|
||||
// NewGormFaceVerifyRecordRepository 创建GORM人脸识别记录仓储
|
||||
func NewGormFaceVerifyRecordRepository(db *gorm.DB, logger *zap.Logger) repositories.FaceVerifyRecordRepository {
|
||||
return &GormFaceVerifyRecordRepository{
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// ================ 基础CRUD操作 ================
|
||||
|
||||
// Create 创建人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) Create(ctx context.Context, record entities.FaceVerifyRecord) (entities.FaceVerifyRecord, error) {
|
||||
if err := r.db.WithContext(ctx).Create(&record).Error; err != nil {
|
||||
r.logger.Error("创建人脸识别记录失败",
|
||||
zap.String("certification_id", record.CertificationID),
|
||||
zap.String("certify_id", record.CertifyID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return entities.FaceVerifyRecord{}, fmt.Errorf("创建人脸识别记录失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("人脸识别记录创建成功",
|
||||
zap.String("id", record.ID),
|
||||
zap.String("certify_id", record.CertifyID),
|
||||
)
|
||||
|
||||
return record, nil
|
||||
}
|
||||
|
||||
// GetByID 根据ID获取人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) GetByID(ctx context.Context, id string) (entities.FaceVerifyRecord, error) {
|
||||
var record entities.FaceVerifyRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).First(&record, "id = ?", id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return entities.FaceVerifyRecord{}, fmt.Errorf("人脸识别记录不存在")
|
||||
}
|
||||
r.logger.Error("获取人脸识别记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return entities.FaceVerifyRecord{}, fmt.Errorf("获取人脸识别记录失败: %w", err)
|
||||
}
|
||||
|
||||
return record, nil
|
||||
}
|
||||
|
||||
// Update 更新人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) Update(ctx context.Context, record entities.FaceVerifyRecord) error {
|
||||
if err := r.db.WithContext(ctx).Save(&record).Error; err != nil {
|
||||
r.logger.Error("更新人脸识别记录失败",
|
||||
zap.String("id", record.ID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("更新人脸识别记录失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete 删除人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) Delete(ctx context.Context, id string) error {
|
||||
if err := r.db.WithContext(ctx).Delete(&entities.FaceVerifyRecord{}, "id = ?", id).Error; err != nil {
|
||||
r.logger.Error("删除人脸识别记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("删除人脸识别记录失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SoftDelete 软删除人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) SoftDelete(ctx context.Context, id string) error {
|
||||
return r.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// Restore 恢复人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) Restore(ctx context.Context, id string) error {
|
||||
if err := r.db.WithContext(ctx).Unscoped().Model(&entities.FaceVerifyRecord{}).Where("id = ?", id).Update("deleted_at", nil).Error; err != nil {
|
||||
r.logger.Error("恢复人脸识别记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("恢复人脸识别记录失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("人脸识别记录恢复成功", zap.String("id", id))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Count 统计人脸识别记录数量
|
||||
func (r *GormFaceVerifyRecordRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
|
||||
var count int64
|
||||
query := r.db.WithContext(ctx).Model(&entities.FaceVerifyRecord{})
|
||||
|
||||
if options.Filters != nil {
|
||||
for key, value := range options.Filters {
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
if options.Search != "" {
|
||||
query = query.Where("certify_id LIKE ? OR user_id LIKE ?", "%"+options.Search+"%", "%"+options.Search+"%")
|
||||
}
|
||||
|
||||
return count, query.Count(&count).Error
|
||||
}
|
||||
|
||||
// Exists 检查人脸识别记录是否存在
|
||||
func (r *GormFaceVerifyRecordRepository) Exists(ctx context.Context, id string) (bool, error) {
|
||||
var count int64
|
||||
err := r.db.WithContext(ctx).Model(&entities.FaceVerifyRecord{}).Where("id = ?", id).Count(&count).Error
|
||||
return count > 0, err
|
||||
}
|
||||
|
||||
// CreateBatch 批量创建人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) CreateBatch(ctx context.Context, records []entities.FaceVerifyRecord) error {
|
||||
r.logger.Info("批量创建人脸识别记录", zap.Int("count", len(records)))
|
||||
return r.db.WithContext(ctx).Create(&records).Error
|
||||
}
|
||||
|
||||
// GetByIDs 根据ID列表获取人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.FaceVerifyRecord, error) {
|
||||
var records []entities.FaceVerifyRecord
|
||||
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&records).Error
|
||||
return records, err
|
||||
}
|
||||
|
||||
// UpdateBatch 批量更新人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) UpdateBatch(ctx context.Context, records []entities.FaceVerifyRecord) error {
|
||||
r.logger.Info("批量更新人脸识别记录", zap.Int("count", len(records)))
|
||||
return r.db.WithContext(ctx).Save(&records).Error
|
||||
}
|
||||
|
||||
// DeleteBatch 批量删除人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) DeleteBatch(ctx context.Context, ids []string) error {
|
||||
r.logger.Info("批量删除人脸识别记录", zap.Strings("ids", ids))
|
||||
return r.db.WithContext(ctx).Delete(&entities.FaceVerifyRecord{}, "id IN ?", ids).Error
|
||||
}
|
||||
|
||||
// List 获取人脸识别记录列表
|
||||
func (r *GormFaceVerifyRecordRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.FaceVerifyRecord, error) {
|
||||
var records []entities.FaceVerifyRecord
|
||||
query := r.db.WithContext(ctx).Model(&entities.FaceVerifyRecord{})
|
||||
|
||||
if options.Filters != nil {
|
||||
for key, value := range options.Filters {
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
if options.Search != "" {
|
||||
query = query.Where("certify_id LIKE ? OR user_id LIKE ?", "%"+options.Search+"%", "%"+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 *GormFaceVerifyRecordRepository) WithTx(tx interface{}) interfaces.Repository[entities.FaceVerifyRecord] {
|
||||
if gormTx, ok := tx.(*gorm.DB); ok {
|
||||
return &GormFaceVerifyRecordRepository{
|
||||
db: gormTx,
|
||||
logger: r.logger,
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ================ 业务方法 ================
|
||||
|
||||
// GetByCertificationID 根据认证申请ID获取人脸识别记录列表
|
||||
func (r *GormFaceVerifyRecordRepository) GetByCertificationID(ctx context.Context, certificationID string) ([]*entities.FaceVerifyRecord, error) {
|
||||
var records []entities.FaceVerifyRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).Where("certification_id = ?", certificationID).Order("created_at DESC").Find(&records).Error; err != nil {
|
||||
r.logger.Error("根据认证申请ID获取人脸识别记录失败",
|
||||
zap.String("certification_id", certificationID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, fmt.Errorf("获取人脸识别记录失败: %w", err)
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.FaceVerifyRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, nil
|
||||
}
|
||||
|
||||
// GetLatestByCertificationID 根据认证申请ID获取最新的人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) GetLatestByCertificationID(ctx context.Context, certificationID string) (*entities.FaceVerifyRecord, error) {
|
||||
var record entities.FaceVerifyRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).Where("certification_id = ?", certificationID).Order("created_at DESC").First(&record).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, fmt.Errorf("人脸识别记录不存在")
|
||||
}
|
||||
r.logger.Error("根据认证申请ID获取最新人脸识别记录失败",
|
||||
zap.String("certification_id", certificationID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, fmt.Errorf("获取人脸识别记录失败: %w", err)
|
||||
}
|
||||
|
||||
return &record, nil
|
||||
}
|
||||
|
||||
// ListRecords 获取人脸识别记录列表(带分页和筛选)
|
||||
func (r *GormFaceVerifyRecordRepository) ListRecords(ctx context.Context, query *queries.ListFaceVerifyRecordsQuery) ([]*entities.FaceVerifyRecord, int64, error) {
|
||||
var records []entities.FaceVerifyRecord
|
||||
var total int64
|
||||
|
||||
dbQuery := r.db.WithContext(ctx).Model(&entities.FaceVerifyRecord{})
|
||||
|
||||
// 应用筛选条件
|
||||
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.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
|
||||
}
|
||||
|
||||
// 应用分页
|
||||
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
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.FaceVerifyRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, total, nil
|
||||
}
|
||||
|
||||
// GetSuccessRate 获取成功率
|
||||
func (r *GormFaceVerifyRecordRepository) GetSuccessRate(ctx context.Context, days int) (float64, error) {
|
||||
var totalCount int64
|
||||
var successCount int64
|
||||
|
||||
// 计算指定天数前的日期
|
||||
startDate := fmt.Sprintf("DATE_SUB(NOW(), INTERVAL %d DAY)", days)
|
||||
|
||||
// 获取总数
|
||||
if err := r.db.WithContext(ctx).Model(&entities.FaceVerifyRecord{}).
|
||||
Where("created_at >= " + startDate).Count(&totalCount).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
// 获取成功数
|
||||
if err := r.db.WithContext(ctx).Model(&entities.FaceVerifyRecord{}).
|
||||
Where("created_at >= "+startDate+" AND status = ?", "SUCCESS").Count(&successCount).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if totalCount == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
return float64(successCount) / float64(totalCount) * 100, nil
|
||||
}
|
||||
|
||||
// GetByCertifyID 根据认证ID获取人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) GetByCertifyID(ctx context.Context, certifyID string) (*entities.FaceVerifyRecord, error) {
|
||||
var record entities.FaceVerifyRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).First(&record, "certify_id = ?", certifyID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, fmt.Errorf("人脸识别记录不存在")
|
||||
}
|
||||
r.logger.Error("根据认证ID获取人脸识别记录失败",
|
||||
zap.String("certify_id", certifyID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, fmt.Errorf("获取人脸识别记录失败: %w", err)
|
||||
}
|
||||
|
||||
return &record, nil
|
||||
}
|
||||
|
||||
// GetByUserID 根据用户ID获取人脸识别记录列表
|
||||
func (r *GormFaceVerifyRecordRepository) GetByUserID(ctx context.Context, userID string, page, pageSize int) ([]*entities.FaceVerifyRecord, int, error) {
|
||||
var records []entities.FaceVerifyRecord
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(ctx).Model(&entities.FaceVerifyRecord{}).Where("user_id = ?", userID)
|
||||
|
||||
// 获取总数
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
r.logger.Error("获取用户人脸识别记录总数失败", zap.Error(err))
|
||||
return nil, 0, fmt.Errorf("获取人脸识别记录总数失败: %w", err)
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (page - 1) * pageSize
|
||||
if err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&records).Error; err != nil {
|
||||
r.logger.Error("获取用户人脸识别记录列表失败", zap.Error(err))
|
||||
return nil, 0, fmt.Errorf("获取人脸识别记录列表失败: %w", err)
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.FaceVerifyRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, int(total), nil
|
||||
}
|
||||
|
||||
// GetExpiredRecords 获取已过期的人脸识别记录
|
||||
func (r *GormFaceVerifyRecordRepository) GetExpiredRecords(ctx context.Context, limit int) ([]*entities.FaceVerifyRecord, error) {
|
||||
var records []entities.FaceVerifyRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).
|
||||
Where("expires_at < NOW() AND status = ?", "PROCESSING").
|
||||
Limit(limit).
|
||||
Order("expires_at ASC").
|
||||
Find(&records).Error; err != nil {
|
||||
r.logger.Error("获取过期人脸识别记录失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("获取过期人脸识别记录失败: %w", err)
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.FaceVerifyRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, nil
|
||||
}
|
||||
@@ -1,374 +0,0 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// GormLicenseUploadRecordRepository GORM营业执照上传记录仓储实现
|
||||
type GormLicenseUploadRecordRepository struct {
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// 编译时检查接口实现
|
||||
var _ repositories.LicenseUploadRecordRepository = (*GormLicenseUploadRecordRepository)(nil)
|
||||
|
||||
// NewGormLicenseUploadRecordRepository 创建GORM营业执照上传记录仓储
|
||||
func NewGormLicenseUploadRecordRepository(db *gorm.DB, logger *zap.Logger) repositories.LicenseUploadRecordRepository {
|
||||
return &GormLicenseUploadRecordRepository{
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// ================ 基础CRUD操作 ================
|
||||
|
||||
// Create 创建上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) Create(ctx context.Context, record entities.LicenseUploadRecord) (entities.LicenseUploadRecord, error) {
|
||||
if err := r.db.WithContext(ctx).Create(&record).Error; err != nil {
|
||||
r.logger.Error("创建上传记录失败",
|
||||
zap.String("user_id", record.UserID),
|
||||
zap.String("file_name", record.OriginalFileName),
|
||||
zap.Error(err),
|
||||
)
|
||||
return entities.LicenseUploadRecord{}, fmt.Errorf("创建上传记录失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("上传记录创建成功",
|
||||
zap.String("id", record.ID),
|
||||
zap.String("file_name", record.OriginalFileName),
|
||||
)
|
||||
|
||||
return record, nil
|
||||
}
|
||||
|
||||
// GetByID 根据ID获取上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) GetByID(ctx context.Context, id string) (entities.LicenseUploadRecord, error) {
|
||||
var record entities.LicenseUploadRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).First(&record, "id = ?", id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return entities.LicenseUploadRecord{}, fmt.Errorf("上传记录不存在")
|
||||
}
|
||||
r.logger.Error("获取上传记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return entities.LicenseUploadRecord{}, fmt.Errorf("获取上传记录失败: %w", err)
|
||||
}
|
||||
|
||||
return record, nil
|
||||
}
|
||||
|
||||
// Update 更新上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) Update(ctx context.Context, record entities.LicenseUploadRecord) error {
|
||||
if err := r.db.WithContext(ctx).Save(&record).Error; err != nil {
|
||||
r.logger.Error("更新上传记录失败",
|
||||
zap.String("id", record.ID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("更新上传记录失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete 删除上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) Delete(ctx context.Context, id string) error {
|
||||
if err := r.db.WithContext(ctx).Delete(&entities.LicenseUploadRecord{}, "id = ?", id).Error; err != nil {
|
||||
r.logger.Error("删除上传记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("删除上传记录失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SoftDelete 软删除上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) SoftDelete(ctx context.Context, id string) error {
|
||||
return r.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// Restore 恢复上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) Restore(ctx context.Context, id string) error {
|
||||
if err := r.db.WithContext(ctx).Unscoped().Model(&entities.LicenseUploadRecord{}).Where("id = ?", id).Update("deleted_at", nil).Error; err != nil {
|
||||
r.logger.Error("恢复上传记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("恢复上传记录失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("上传记录恢复成功", zap.String("id", id))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Count 统计上传记录数量
|
||||
func (r *GormLicenseUploadRecordRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
|
||||
var count int64
|
||||
query := r.db.WithContext(ctx).Model(&entities.LicenseUploadRecord{})
|
||||
|
||||
if options.Filters != nil {
|
||||
for key, value := range options.Filters {
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
if options.Search != "" {
|
||||
query = query.Where("original_file_name LIKE ? OR user_id LIKE ?", "%"+options.Search+"%", "%"+options.Search+"%")
|
||||
}
|
||||
|
||||
return count, query.Count(&count).Error
|
||||
}
|
||||
|
||||
// Exists 检查上传记录是否存在
|
||||
func (r *GormLicenseUploadRecordRepository) Exists(ctx context.Context, id string) (bool, error) {
|
||||
var count int64
|
||||
err := r.db.WithContext(ctx).Model(&entities.LicenseUploadRecord{}).Where("id = ?", id).Count(&count).Error
|
||||
return count > 0, err
|
||||
}
|
||||
|
||||
// CreateBatch 批量创建上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) CreateBatch(ctx context.Context, records []entities.LicenseUploadRecord) error {
|
||||
r.logger.Info("批量创建上传记录", zap.Int("count", len(records)))
|
||||
return r.db.WithContext(ctx).Create(&records).Error
|
||||
}
|
||||
|
||||
// GetByIDs 根据ID列表获取上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.LicenseUploadRecord, error) {
|
||||
var records []entities.LicenseUploadRecord
|
||||
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&records).Error
|
||||
return records, err
|
||||
}
|
||||
|
||||
// UpdateBatch 批量更新上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) UpdateBatch(ctx context.Context, records []entities.LicenseUploadRecord) error {
|
||||
r.logger.Info("批量更新上传记录", zap.Int("count", len(records)))
|
||||
return r.db.WithContext(ctx).Save(&records).Error
|
||||
}
|
||||
|
||||
// DeleteBatch 批量删除上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) DeleteBatch(ctx context.Context, ids []string) error {
|
||||
r.logger.Info("批量删除上传记录", zap.Strings("ids", ids))
|
||||
return r.db.WithContext(ctx).Delete(&entities.LicenseUploadRecord{}, "id IN ?", ids).Error
|
||||
}
|
||||
|
||||
// List 获取上传记录列表
|
||||
func (r *GormLicenseUploadRecordRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.LicenseUploadRecord, error) {
|
||||
var records []entities.LicenseUploadRecord
|
||||
query := r.db.WithContext(ctx).Model(&entities.LicenseUploadRecord{})
|
||||
|
||||
if options.Filters != nil {
|
||||
for key, value := range options.Filters {
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
if options.Search != "" {
|
||||
query = query.Where("original_file_name LIKE ? OR user_id LIKE ?", "%"+options.Search+"%", "%"+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 *GormLicenseUploadRecordRepository) WithTx(tx interface{}) interfaces.Repository[entities.LicenseUploadRecord] {
|
||||
if gormTx, ok := tx.(*gorm.DB); ok {
|
||||
return &GormLicenseUploadRecordRepository{
|
||||
db: gormTx,
|
||||
logger: r.logger,
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ================ 业务方法 ================
|
||||
|
||||
// GetByCertificationID 根据认证ID获取上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) GetByCertificationID(ctx context.Context, certificationID string) (*entities.LicenseUploadRecord, error) {
|
||||
var record entities.LicenseUploadRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).First(&record, "certification_id = ?", certificationID).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, fmt.Errorf("上传记录不存在")
|
||||
}
|
||||
r.logger.Error("根据认证ID获取上传记录失败",
|
||||
zap.String("certification_id", certificationID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, fmt.Errorf("获取上传记录失败: %w", err)
|
||||
}
|
||||
|
||||
return &record, nil
|
||||
}
|
||||
|
||||
// ListRecords 获取上传记录列表(带分页和筛选)
|
||||
func (r *GormLicenseUploadRecordRepository) ListRecords(ctx context.Context, query *queries.ListLicenseUploadRecordsQuery) ([]*entities.LicenseUploadRecord, int64, error) {
|
||||
var records []entities.LicenseUploadRecord
|
||||
var total int64
|
||||
|
||||
dbQuery := r.db.WithContext(ctx).Model(&entities.LicenseUploadRecord{})
|
||||
|
||||
// 应用筛选条件
|
||||
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.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
|
||||
}
|
||||
|
||||
// 应用分页
|
||||
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
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.LicenseUploadRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, total, nil
|
||||
}
|
||||
|
||||
// UpdateOCRResult 更新OCR结果
|
||||
func (r *GormLicenseUploadRecordRepository) UpdateOCRResult(ctx context.Context, recordID string, ocrResult string, confidence float64) error {
|
||||
updates := map[string]interface{}{
|
||||
"ocr_result": ocrResult,
|
||||
"ocr_confidence": confidence,
|
||||
"ocr_processed": true,
|
||||
"ocr_success": true,
|
||||
}
|
||||
|
||||
if err := r.db.WithContext(ctx).
|
||||
Model(&entities.LicenseUploadRecord{}).
|
||||
Where("id = ?", recordID).
|
||||
Updates(updates).Error; err != nil {
|
||||
r.logger.Error("更新OCR结果失败",
|
||||
zap.String("record_id", recordID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("更新OCR结果失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("OCR结果更新成功",
|
||||
zap.String("record_id", recordID),
|
||||
zap.Float64("confidence", confidence),
|
||||
)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetByUserID 根据用户ID获取上传记录列表
|
||||
func (r *GormLicenseUploadRecordRepository) GetByUserID(ctx context.Context, userID string, page, pageSize int) ([]*entities.LicenseUploadRecord, int, error) {
|
||||
var records []entities.LicenseUploadRecord
|
||||
var total int64
|
||||
|
||||
query := r.db.WithContext(ctx).Model(&entities.LicenseUploadRecord{}).Where("user_id = ?", userID)
|
||||
|
||||
// 获取总数
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
r.logger.Error("获取用户上传记录总数失败", zap.Error(err))
|
||||
return nil, 0, fmt.Errorf("获取上传记录总数失败: %w", err)
|
||||
}
|
||||
|
||||
// 分页查询
|
||||
offset := (page - 1) * pageSize
|
||||
if err := query.Offset(offset).Limit(pageSize).Order("created_at DESC").Find(&records).Error; err != nil {
|
||||
r.logger.Error("获取用户上传记录列表失败", zap.Error(err))
|
||||
return nil, 0, fmt.Errorf("获取上传记录列表失败: %w", err)
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.LicenseUploadRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, int(total), nil
|
||||
}
|
||||
|
||||
// GetByQiNiuKey 根据七牛云Key获取上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) GetByQiNiuKey(ctx context.Context, key string) (*entities.LicenseUploadRecord, error) {
|
||||
var record entities.LicenseUploadRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).First(&record, "qiniu_key = ?", key).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return nil, fmt.Errorf("上传记录不存在")
|
||||
}
|
||||
r.logger.Error("根据七牛云Key获取上传记录失败",
|
||||
zap.String("qiniu_key", key),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, fmt.Errorf("获取上传记录失败: %w", err)
|
||||
}
|
||||
|
||||
return &record, nil
|
||||
}
|
||||
|
||||
// GetPendingOCR 获取待OCR处理的上传记录
|
||||
func (r *GormLicenseUploadRecordRepository) GetPendingOCR(ctx context.Context, limit int) ([]*entities.LicenseUploadRecord, error) {
|
||||
var records []entities.LicenseUploadRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).
|
||||
Where("ocr_processed = ? OR (ocr_processed = ? AND ocr_success = ?)", false, true, false).
|
||||
Limit(limit).
|
||||
Order("created_at ASC").
|
||||
Find(&records).Error; err != nil {
|
||||
r.logger.Error("获取待OCR处理记录失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("获取待OCR处理记录失败: %w", err)
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.LicenseUploadRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, nil
|
||||
}
|
||||
@@ -1,344 +0,0 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"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"
|
||||
)
|
||||
|
||||
// GormNotificationRecordRepository GORM通知记录仓储实现
|
||||
type GormNotificationRecordRepository struct {
|
||||
db *gorm.DB
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// 编译时检查接口实现
|
||||
var _ repositories.NotificationRecordRepository = (*GormNotificationRecordRepository)(nil)
|
||||
|
||||
// NewGormNotificationRecordRepository 创建GORM通知记录仓储
|
||||
func NewGormNotificationRecordRepository(db *gorm.DB, logger *zap.Logger) repositories.NotificationRecordRepository {
|
||||
return &GormNotificationRecordRepository{
|
||||
db: db,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// ================ 基础CRUD操作 ================
|
||||
|
||||
// Create 创建通知记录
|
||||
func (r *GormNotificationRecordRepository) Create(ctx context.Context, record entities.NotificationRecord) (entities.NotificationRecord, error) {
|
||||
if err := r.db.WithContext(ctx).Create(&record).Error; err != nil {
|
||||
r.logger.Error("创建通知记录失败",
|
||||
zap.String("user_id", *record.UserID),
|
||||
zap.String("type", record.NotificationType),
|
||||
zap.Error(err),
|
||||
)
|
||||
return entities.NotificationRecord{}, fmt.Errorf("创建通知记录失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("通知记录创建成功",
|
||||
zap.String("id", record.ID),
|
||||
zap.String("type", record.NotificationType),
|
||||
)
|
||||
|
||||
return record, nil
|
||||
}
|
||||
|
||||
// GetByID 根据ID获取通知记录
|
||||
func (r *GormNotificationRecordRepository) GetByID(ctx context.Context, id string) (entities.NotificationRecord, error) {
|
||||
var record entities.NotificationRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).First(&record, "id = ?", id).Error; err != nil {
|
||||
if err == gorm.ErrRecordNotFound {
|
||||
return entities.NotificationRecord{}, fmt.Errorf("通知记录不存在")
|
||||
}
|
||||
r.logger.Error("获取通知记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return entities.NotificationRecord{}, fmt.Errorf("获取通知记录失败: %w", err)
|
||||
}
|
||||
|
||||
return record, nil
|
||||
}
|
||||
|
||||
// Update 更新通知记录
|
||||
func (r *GormNotificationRecordRepository) Update(ctx context.Context, record entities.NotificationRecord) error {
|
||||
if err := r.db.WithContext(ctx).Save(&record).Error; err != nil {
|
||||
r.logger.Error("更新通知记录失败",
|
||||
zap.String("id", record.ID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("更新通知记录失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// Delete 删除通知记录
|
||||
func (r *GormNotificationRecordRepository) Delete(ctx context.Context, id string) error {
|
||||
if err := r.db.WithContext(ctx).Delete(&entities.NotificationRecord{}, "id = ?", id).Error; err != nil {
|
||||
r.logger.Error("删除通知记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("删除通知记录失败: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SoftDelete 软删除通知记录
|
||||
func (r *GormNotificationRecordRepository) SoftDelete(ctx context.Context, id string) error {
|
||||
return r.Delete(ctx, id)
|
||||
}
|
||||
|
||||
// Restore 恢复通知记录
|
||||
func (r *GormNotificationRecordRepository) Restore(ctx context.Context, id string) error {
|
||||
if err := r.db.WithContext(ctx).Unscoped().Model(&entities.NotificationRecord{}).Where("id = ?", id).Update("deleted_at", nil).Error; err != nil {
|
||||
r.logger.Error("恢复通知记录失败",
|
||||
zap.String("id", id),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("恢复通知记录失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("通知记录恢复成功", zap.String("id", id))
|
||||
return nil
|
||||
}
|
||||
|
||||
// Count 统计通知记录数量
|
||||
func (r *GormNotificationRecordRepository) Count(ctx context.Context, options interfaces.CountOptions) (int64, error) {
|
||||
var count int64
|
||||
query := r.db.WithContext(ctx).Model(&entities.NotificationRecord{})
|
||||
|
||||
if options.Filters != nil {
|
||||
for key, value := range options.Filters {
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
if options.Search != "" {
|
||||
query = query.Where("title LIKE ? OR content LIKE ? OR user_id LIKE ?", "%"+options.Search+"%", "%"+options.Search+"%", "%"+options.Search+"%")
|
||||
}
|
||||
|
||||
return count, query.Count(&count).Error
|
||||
}
|
||||
|
||||
// Exists 检查通知记录是否存在
|
||||
func (r *GormNotificationRecordRepository) Exists(ctx context.Context, id string) (bool, error) {
|
||||
var count int64
|
||||
err := r.db.WithContext(ctx).Model(&entities.NotificationRecord{}).Where("id = ?", id).Count(&count).Error
|
||||
return count > 0, err
|
||||
}
|
||||
|
||||
// CreateBatch 批量创建通知记录
|
||||
func (r *GormNotificationRecordRepository) CreateBatch(ctx context.Context, records []entities.NotificationRecord) error {
|
||||
r.logger.Info("批量创建通知记录", zap.Int("count", len(records)))
|
||||
return r.db.WithContext(ctx).Create(&records).Error
|
||||
}
|
||||
|
||||
// GetByIDs 根据ID列表获取通知记录
|
||||
func (r *GormNotificationRecordRepository) GetByIDs(ctx context.Context, ids []string) ([]entities.NotificationRecord, error) {
|
||||
var records []entities.NotificationRecord
|
||||
err := r.db.WithContext(ctx).Where("id IN ?", ids).Find(&records).Error
|
||||
return records, err
|
||||
}
|
||||
|
||||
// UpdateBatch 批量更新通知记录
|
||||
func (r *GormNotificationRecordRepository) UpdateBatch(ctx context.Context, records []entities.NotificationRecord) error {
|
||||
r.logger.Info("批量更新通知记录", zap.Int("count", len(records)))
|
||||
return r.db.WithContext(ctx).Save(&records).Error
|
||||
}
|
||||
|
||||
// DeleteBatch 批量删除通知记录
|
||||
func (r *GormNotificationRecordRepository) DeleteBatch(ctx context.Context, ids []string) error {
|
||||
r.logger.Info("批量删除通知记录", zap.Strings("ids", ids))
|
||||
return r.db.WithContext(ctx).Delete(&entities.NotificationRecord{}, "id IN ?", ids).Error
|
||||
}
|
||||
|
||||
// List 获取通知记录列表
|
||||
func (r *GormNotificationRecordRepository) List(ctx context.Context, options interfaces.ListOptions) ([]entities.NotificationRecord, error) {
|
||||
var records []entities.NotificationRecord
|
||||
query := r.db.WithContext(ctx).Model(&entities.NotificationRecord{})
|
||||
|
||||
if options.Filters != nil {
|
||||
for key, value := range options.Filters {
|
||||
query = query.Where(key+" = ?", value)
|
||||
}
|
||||
}
|
||||
|
||||
if options.Search != "" {
|
||||
query = query.Where("title LIKE ? OR content LIKE ? OR user_id LIKE ?", "%"+options.Search+"%", "%"+options.Search+"%", "%"+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 *GormNotificationRecordRepository) WithTx(tx interface{}) interfaces.Repository[entities.NotificationRecord] {
|
||||
if gormTx, ok := tx.(*gorm.DB); ok {
|
||||
return &GormNotificationRecordRepository{
|
||||
db: gormTx,
|
||||
logger: r.logger,
|
||||
}
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
// ================ 业务方法 ================
|
||||
|
||||
// GetByCertificationID 根据认证申请ID获取通知记录列表
|
||||
func (r *GormNotificationRecordRepository) GetByCertificationID(ctx context.Context, certificationID string) ([]*entities.NotificationRecord, error) {
|
||||
var records []entities.NotificationRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).Where("certification_id = ?", certificationID).Order("created_at DESC").Find(&records).Error; err != nil {
|
||||
r.logger.Error("根据认证申请ID获取通知记录失败",
|
||||
zap.String("certification_id", certificationID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, fmt.Errorf("获取通知记录失败: %w", err)
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.NotificationRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, nil
|
||||
}
|
||||
|
||||
// GetUnreadByUserID 根据用户ID获取未读通知记录列表
|
||||
func (r *GormNotificationRecordRepository) GetUnreadByUserID(ctx context.Context, userID string) ([]*entities.NotificationRecord, error) {
|
||||
var records []entities.NotificationRecord
|
||||
|
||||
if err := r.db.WithContext(ctx).Where("user_id = ? AND is_read = ?", userID, false).Order("created_at DESC").Find(&records).Error; err != nil {
|
||||
r.logger.Error("根据用户ID获取未读通知记录失败",
|
||||
zap.String("user_id", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return nil, fmt.Errorf("获取未读通知记录失败: %w", err)
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.NotificationRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, nil
|
||||
}
|
||||
|
||||
// ListRecords 获取通知记录列表(带分页和筛选)
|
||||
func (r *GormNotificationRecordRepository) ListRecords(ctx context.Context, query *queries.ListNotificationRecordsQuery) ([]*entities.NotificationRecord, int64, error) {
|
||||
var records []entities.NotificationRecord
|
||||
var total int64
|
||||
|
||||
dbQuery := r.db.WithContext(ctx).Model(&entities.NotificationRecord{})
|
||||
|
||||
// 应用筛选条件
|
||||
if query.CertificationID != "" {
|
||||
dbQuery = dbQuery.Where("certification_id = ?", query.CertificationID)
|
||||
}
|
||||
if query.UserID != "" {
|
||||
dbQuery = dbQuery.Where("user_id = ?", query.UserID)
|
||||
}
|
||||
if query.Type != "" {
|
||||
dbQuery = dbQuery.Where("type = ?", query.Type)
|
||||
}
|
||||
if query.IsRead != nil {
|
||||
dbQuery = dbQuery.Where("is_read = ?", *query.IsRead)
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// 应用分页
|
||||
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
|
||||
}
|
||||
|
||||
// 转换为指针切片
|
||||
recordPtrs := make([]*entities.NotificationRecord, len(records))
|
||||
for i := range records {
|
||||
recordPtrs[i] = &records[i]
|
||||
}
|
||||
|
||||
return recordPtrs, total, nil
|
||||
}
|
||||
|
||||
// BatchCreate 批量创建通知记录
|
||||
func (r *GormNotificationRecordRepository) BatchCreate(ctx context.Context, records []entities.NotificationRecord) error {
|
||||
r.logger.Info("批量创建通知记录", zap.Int("count", len(records)))
|
||||
return r.db.WithContext(ctx).Create(&records).Error
|
||||
}
|
||||
|
||||
// MarkAsRead 标记通知记录为已读
|
||||
func (r *GormNotificationRecordRepository) MarkAsRead(ctx context.Context, recordIDs []string) error {
|
||||
if err := r.db.WithContext(ctx).
|
||||
Model(&entities.NotificationRecord{}).
|
||||
Where("id IN ?", recordIDs).
|
||||
Update("is_read", true).Error; err != nil {
|
||||
r.logger.Error("标记通知记录为已读失败",
|
||||
zap.Strings("record_ids", recordIDs),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("标记通知记录为已读失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("通知记录标记为已读成功", zap.Strings("record_ids", recordIDs))
|
||||
return nil
|
||||
}
|
||||
|
||||
// MarkAllAsReadByUser 标记用户所有通知记录为已读
|
||||
func (r *GormNotificationRecordRepository) MarkAllAsReadByUser(ctx context.Context, userID string) error {
|
||||
if err := r.db.WithContext(ctx).
|
||||
Model(&entities.NotificationRecord{}).
|
||||
Where("user_id = ? AND is_read = ?", userID, false).
|
||||
Update("is_read", true).Error; err != nil {
|
||||
r.logger.Error("标记用户所有通知记录为已读失败",
|
||||
zap.String("user_id", userID),
|
||||
zap.Error(err),
|
||||
)
|
||||
return fmt.Errorf("标记用户所有通知记录为已读失败: %w", err)
|
||||
}
|
||||
|
||||
r.logger.Info("用户所有通知记录标记为已读成功", zap.String("user_id", userID))
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user