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

View File

@@ -0,0 +1,29 @@
package repositories
import (
"context"
"tyapi-server/internal/domains/certification/entities"
"tyapi-server/internal/domains/certification/enums"
"tyapi-server/internal/shared/interfaces"
)
// CertificationCommandRepository 认证命令仓储接口
// 专门处理认证数据的变更操作符合CQRS模式
type CertificationCommandRepository interface {
// 基础CRUD操作
Create(ctx context.Context, cert entities.Certification) error
Update(ctx context.Context, cert entities.Certification) error
Delete(ctx context.Context, id string) error
// 业务特定的更新操作
UpdateStatus(ctx context.Context, id string, status enums.CertificationStatus) error
UpdateAuthFlowID(ctx context.Context, id string, authFlowID string) error
UpdateContractInfo(ctx context.Context, id string, contractFileID, esignFlowID, contractURL, contractSignURL string) error
UpdateFailureInfo(ctx context.Context, id string, reason enums.FailureReason, message string) error
// 批量操作
BatchUpdateStatus(ctx context.Context, ids []string, status enums.CertificationStatus) error
// 事务支持
WithTx(tx interfaces.Transaction) CertificationCommandRepository
}

View File

@@ -0,0 +1,122 @@
package repositories
import (
"context"
"time"
"tyapi-server/internal/domains/certification/entities"
"tyapi-server/internal/domains/certification/enums"
"tyapi-server/internal/domains/certification/repositories/queries"
)
// CertificationQueryRepository 认证查询仓储接口
// 专门处理认证数据的查询操作符合CQRS模式
type CertificationQueryRepository interface {
// 基础查询操作
GetByID(ctx context.Context, id string) (*entities.Certification, error)
GetByUserID(ctx context.Context, userID string) (*entities.Certification, error)
Exists(ctx context.Context, id string) (bool, error)
// 列表查询
List(ctx context.Context, query *queries.ListCertificationsQuery) ([]*entities.Certification, int64, error)
ListByUserIDs(ctx context.Context, userIDs []string) ([]*entities.Certification, error)
ListByStatus(ctx context.Context, status enums.CertificationStatus, limit int) ([]*entities.Certification, error)
// 业务查询
FindByAuthFlowID(ctx context.Context, authFlowID string) (*entities.Certification, error)
FindByEsignFlowID(ctx context.Context, esignFlowID string) (*entities.Certification, error)
ListPendingRetry(ctx context.Context, maxRetryCount int) ([]*entities.Certification, error)
GetPendingCertifications(ctx context.Context) ([]*entities.Certification, error)
GetExpiredContracts(ctx context.Context) ([]*entities.Certification, error)
GetCertificationsByDateRange(ctx context.Context, startDate, endDate time.Time) ([]*entities.Certification, error)
GetUserActiveCertification(ctx context.Context, userID string) (*entities.Certification, error)
// 统计查询
GetStatistics(ctx context.Context, period CertificationTimePeriod) (*CertificationStatistics, error)
CountByStatus(ctx context.Context, status enums.CertificationStatus) (int64, error)
CountByFailureReason(ctx context.Context, reason enums.FailureReason) (int64, error)
GetProgressStatistics(ctx context.Context) (*CertificationProgressStats, error)
// 搜索查询
SearchByCompanyName(ctx context.Context, companyName string, limit int) ([]*entities.Certification, error)
SearchByLegalPerson(ctx context.Context, legalPersonName string, limit int) ([]*entities.Certification, error)
// 缓存相关
InvalidateCache(ctx context.Context, keys ...string) error
RefreshCache(ctx context.Context, certificationID string) error
}
// CertificationTimePeriod 时间周期枚举
type CertificationTimePeriod string
const (
PeriodDaily CertificationTimePeriod = "daily"
PeriodWeekly CertificationTimePeriod = "weekly"
PeriodMonthly CertificationTimePeriod = "monthly"
PeriodYearly CertificationTimePeriod = "yearly"
)
// CertificationStatistics 认证统计信息
type CertificationStatistics struct {
Period CertificationTimePeriod `json:"period"`
StartDate time.Time `json:"start_date"`
EndDate time.Time `json:"end_date"`
// 总体统计
TotalCertifications int64 `json:"total_certifications"`
CompletedCount int64 `json:"completed_count"`
FailedCount int64 `json:"failed_count"`
InProgressCount int64 `json:"in_progress_count"`
// 状态分布
StatusDistribution map[enums.CertificationStatus]int64 `json:"status_distribution"`
// 失败原因分布
FailureDistribution map[enums.FailureReason]int64 `json:"failure_distribution"`
// 成功率统计
SuccessRate float64 `json:"success_rate"`
EnterpriseVerifyRate float64 `json:"enterprise_verify_rate"`
ContractSignRate float64 `json:"contract_sign_rate"`
// 时间统计
AvgProcessingTime time.Duration `json:"avg_processing_time"`
AvgVerificationTime time.Duration `json:"avg_verification_time"`
AvgSigningTime time.Duration `json:"avg_signing_time"`
// 重试统计
RetryStats *CertificationRetryStats `json:"retry_stats"`
}
// CertificationProgressStats 进度统计信息
type CertificationProgressStats struct {
StatusProgress map[enums.CertificationStatus]int64 `json:"status_progress"`
ProgressDistribution map[int]int64 `json:"progress_distribution"` // key: progress percentage
// 各阶段耗时统计
StageTimeStats map[string]*CertificationStageTimeInfo `json:"stage_time_stats"`
}
// CertificationStageTimeInfo 阶段耗时信息
type CertificationStageTimeInfo struct {
StageName string `json:"stage_name"`
AverageTime time.Duration `json:"average_time"`
MinTime time.Duration `json:"min_time"`
MaxTime time.Duration `json:"max_time"`
SampleCount int64 `json:"sample_count"`
}
// CertificationRetryStats 重试统计信息
type CertificationRetryStats struct {
TotalRetries int64 `json:"total_retries"`
SuccessfulRetries int64 `json:"successful_retries"`
FailedRetries int64 `json:"failed_retries"`
RetrySuccessRate float64 `json:"retry_success_rate"`
// 各阶段重试统计
EnterpriseRetries int64 `json:"enterprise_retries"`
ContractRetries int64 `json:"contract_retries"`
// 重试原因分布
RetryReasonStats map[enums.FailureReason]int64 `json:"retry_reason_stats"`
}

View File

@@ -1,91 +0,0 @@
package repositories
import (
"context"
"tyapi-server/internal/domains/certification/entities"
"tyapi-server/internal/domains/certification/repositories/queries"
"tyapi-server/internal/shared/interfaces"
)
// CertificationStats 认证统计信息
type CertificationStats struct {
TotalCertifications int64
PendingCertifications int64
CompletedCertifications int64
TodaySubmissions int64
}
// CertificationRepository 认证申请仓储接口
type CertificationRepository interface {
interfaces.Repository[entities.Certification]
// 基础查询 - 直接使用实体
GetByUserID(ctx context.Context, userID string) (*entities.Certification, error)
GetByStatus(ctx context.Context, status string) ([]*entities.Certification, error)
GetPendingCertifications(ctx context.Context) ([]*entities.Certification, error)
GetByAuthFlowID(ctx context.Context, authFlowID string) (entities.Certification, error)
GetByEsignFlowID(ctx context.Context, esignFlowID string) (entities.Certification, error)
// 复杂查询 - 使用查询参数
ListCertifications(ctx context.Context, query *queries.ListCertificationsQuery) ([]*entities.Certification, int64, error)
// 业务操作
UpdateStatus(ctx context.Context, certificationID string, status string) error
// 统计信息
GetStats(ctx context.Context) (*CertificationStats, error)
GetStatsByDateRange(ctx context.Context, startDate, endDate string) (*CertificationStats, error)
}
// EnterpriseInfoSubmitRecordRepository 企业信息提交记录仓储接口
type EnterpriseInfoSubmitRecordRepository interface {
interfaces.Repository[entities.EnterpriseInfoSubmitRecord]
// 基础查询
GetByUserID(ctx context.Context, userID string) ([]*entities.EnterpriseInfoSubmitRecord, error)
GetLatestByUserID(ctx context.Context, userID string) (*entities.EnterpriseInfoSubmitRecord, error)
// 复杂查询
ListRecords(ctx context.Context, query *queries.ListEnterpriseInfoSubmitRecordsQuery) ([]*entities.EnterpriseInfoSubmitRecord, int64, error)
// 业务操作
UpdateStatus(ctx context.Context, recordID string, status string, reason string) error
}
// EsignContractGenerateRecordRepository e签宝生成合同记录仓储接口
type EsignContractGenerateRecordRepository interface {
interfaces.Repository[entities.EsignContractGenerateRecord]
// 基础查询
GetByCertificationID(ctx context.Context, certificationID string) (*entities.EsignContractGenerateRecord, error)
GetByUserID(ctx context.Context, userID string) ([]*entities.EsignContractGenerateRecord, error)
GetLatestByCertificationID(ctx context.Context, certificationID string) (*entities.EsignContractGenerateRecord, error)
// 复杂查询
ListRecords(ctx context.Context, query *queries.ListEsignContractGenerateRecordsQuery) ([]*entities.EsignContractGenerateRecord, int64, error)
// 业务操作
UpdateStatus(ctx context.Context, recordID string, status string, reason string) error
UpdateSuccessInfo(ctx context.Context, recordID, esignFlowID, contractFileID, contractURL string) error
IncrementRetry(ctx context.Context, recordID string) error
}
// EsignContractSignRecordRepository e签宝签署合同记录仓储接口
type EsignContractSignRecordRepository interface {
interfaces.Repository[entities.EsignContractSignRecord]
// 基础查询
GetByCertificationID(ctx context.Context, certificationID string) (*entities.EsignContractSignRecord, error)
GetByUserID(ctx context.Context, userID string) ([]*entities.EsignContractSignRecord, error)
GetLatestByCertificationID(ctx context.Context, certificationID string) (*entities.EsignContractSignRecord, error)
GetByGenerateRecordID(ctx context.Context, generateRecordID string) (*entities.EsignContractSignRecord, error)
// 复杂查询
ListRecords(ctx context.Context, query *queries.ListEsignContractSignRecordsQuery) ([]*entities.EsignContractSignRecord, int64, error)
// 业务操作
UpdateStatus(ctx context.Context, recordID string, status string, reason string) error
UpdateSuccessInfo(ctx context.Context, recordID, signedFileURL string) error
SetSignURL(ctx context.Context, recordID, signURL string) error
IncrementRetry(ctx context.Context, recordID string) error
MarkExpiredRecords(ctx context.Context) error
}

View File

@@ -1,62 +1,279 @@
package queries
import "tyapi-server/internal/domains/certification/enums"
import (
"fmt"
"time"
// ListCertificationsQuery 认证申请列表查询参数
"tyapi-server/internal/domains/certification/enums"
)
// GetCertificationQuery 获取单个认证查询
type GetCertificationQuery struct {
ID string `json:"id" validate:"required"`
UserID string `json:"user_id,omitempty"` // 可选的用户ID用于权限验证
}
// ListCertificationsQuery 认证列表查询
type ListCertificationsQuery struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
UserID string `json:"user_id"`
Status enums.CertificationStatus `json:"status"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
EnterpriseName string `json:"enterprise_name"`
// 分页参数
Page int `json:"page" validate:"min=1"`
PageSize int `json:"page_size" validate:"min=1,max=100"`
// 排序参数
SortBy string `json:"sort_by"` // 排序字段: created_at, updated_at, status, progress
SortOrder string `json:"sort_order"` // 排序方向: asc, desc
// 过滤条件
UserID string `json:"user_id,omitempty"`
Status enums.CertificationStatus `json:"status,omitempty"`
Statuses []enums.CertificationStatus `json:"statuses,omitempty"`
FailureReason enums.FailureReason `json:"failure_reason,omitempty"`
// 时间范围过滤
CreatedAfter *time.Time `json:"created_after,omitempty"`
CreatedBefore *time.Time `json:"created_before,omitempty"`
UpdatedAfter *time.Time `json:"updated_after,omitempty"`
UpdatedBefore *time.Time `json:"updated_before,omitempty"`
// 企业信息过滤
CompanyName string `json:"company_name,omitempty"`
LegalPersonName string `json:"legal_person_name,omitempty"`
// 业务状态过滤
IsCompleted *bool `json:"is_completed,omitempty"`
IsFailed *bool `json:"is_failed,omitempty"`
IsUserActionRequired *bool `json:"is_user_action_required,omitempty"`
// 高级过滤
MinRetryCount *int `json:"min_retry_count,omitempty"`
MaxRetryCount *int `json:"max_retry_count,omitempty"`
MinProgress *int `json:"min_progress,omitempty"`
MaxProgress *int `json:"max_progress,omitempty"`
// 搜索参数
SearchKeyword string `json:"search_keyword,omitempty"` // 通用搜索关键词
// 包含关联数据
IncludeMetadata bool `json:"include_metadata,omitempty"`
}
// ListEnterprisesQuery 企业信息列表查询参数
type ListEnterprisesQuery struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
UserID string `json:"user_id"`
EnterpriseName string `json:"enterprise_name"`
LicenseNumber string `json:"license_number"`
LegalPersonName string `json:"legal_person_name"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
// DefaultValues 设置默认值
func (q *ListCertificationsQuery) DefaultValues() {
if q.Page <= 0 {
q.Page = 1
}
if q.PageSize <= 0 {
q.PageSize = 20
}
if q.SortBy == "" {
q.SortBy = "created_at"
}
if q.SortOrder == "" {
q.SortOrder = "desc"
}
}
// ListEnterpriseInfoSubmitRecordsQuery 企业信息提交记录列表查询参数
type ListEnterpriseInfoSubmitRecordsQuery struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
CertificationID string `json:"certification_id"`
UserID string `json:"user_id"`
Status string `json:"status"`
CompanyName string `json:"company_name"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
// GetOffset 计算分页偏移量
func (q *ListCertificationsQuery) GetOffset() int {
return (q.Page - 1) * q.PageSize
}
// ListEsignContractGenerateRecordsQuery e签宝生成合同记录列表查询参数
type ListEsignContractGenerateRecordsQuery struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
CertificationID string `json:"certification_id"`
UserID string `json:"user_id"`
Status string `json:"status"`
ContractType string `json:"contract_type"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
// GetLimit 获取查询限制数量
func (q *ListCertificationsQuery) GetLimit() int {
return q.PageSize
}
// ListEsignContractSignRecordsQuery e签宝签署合同记录列表查询参数
type ListEsignContractSignRecordsQuery struct {
Page int `json:"page"`
PageSize int `json:"page_size"`
CertificationID string `json:"certification_id"`
UserID string `json:"user_id"`
Status string `json:"status"`
SignerName string `json:"signer_name"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
// HasTimeFilter 检查是否有时间过滤条件
func (q *ListCertificationsQuery) HasTimeFilter() bool {
return q.CreatedAfter != nil || q.CreatedBefore != nil ||
q.UpdatedAfter != nil || q.UpdatedBefore != nil
}
// HasStatusFilter 检查是否有状态过滤条件
func (q *ListCertificationsQuery) HasStatusFilter() bool {
return q.Status != "" || len(q.Statuses) > 0
}
// HasSearchFilter 检查是否有搜索过滤条件
func (q *ListCertificationsQuery) HasSearchFilter() bool {
return q.CompanyName != "" || q.LegalPersonName != "" || q.SearchKeyword != ""
}
// GetSearchFields 获取搜索字段映射
func (q *ListCertificationsQuery) GetSearchFields() map[string]string {
fields := make(map[string]string)
if q.CompanyName != "" {
fields["company_name"] = q.CompanyName
}
if q.LegalPersonName != "" {
fields["legal_person_name"] = q.LegalPersonName
}
if q.SearchKeyword != "" {
fields["keyword"] = q.SearchKeyword
}
return fields
}
// CertificationStatisticsQuery 认证统计查询
type CertificationStatisticsQuery struct {
// 时间范围
StartDate time.Time `json:"start_date" validate:"required"`
EndDate time.Time `json:"end_date" validate:"required"`
// 统计周期
Period string `json:"period" validate:"oneof=daily weekly monthly yearly"`
// 分组维度
GroupBy []string `json:"group_by,omitempty"` // status, failure_reason, user_type, date
// 过滤条件
UserIDs []string `json:"user_ids,omitempty"`
Statuses []enums.CertificationStatus `json:"statuses,omitempty"`
// 统计类型
IncludeProgressStats bool `json:"include_progress_stats,omitempty"`
IncludeRetryStats bool `json:"include_retry_stats,omitempty"`
IncludeTimeStats bool `json:"include_time_stats,omitempty"`
}
// Validate 验证统计查询参数
func (q *CertificationStatisticsQuery) Validate() error {
if q.EndDate.Before(q.StartDate) {
return fmt.Errorf("结束时间不能早于开始时间")
}
// 检查时间范围是否合理不超过1年
if q.EndDate.Sub(q.StartDate) > 365*24*time.Hour {
return fmt.Errorf("查询时间范围不能超过1年")
}
return nil
}
// GetTimeRange 获取时间范围描述
func (q *CertificationStatisticsQuery) GetTimeRange() string {
return fmt.Sprintf("%s 到 %s",
q.StartDate.Format("2006-01-02"),
q.EndDate.Format("2006-01-02"))
}
// SearchCertificationsQuery 搜索认证查询
type SearchCertificationsQuery struct {
// 搜索关键词
Keyword string `json:"keyword" validate:"required,min=2"`
// 搜索字段
SearchFields []string `json:"search_fields,omitempty"` // company_name, legal_person_name, unified_social_code
// 过滤条件
Statuses []enums.CertificationStatus `json:"statuses,omitempty"`
UserID string `json:"user_id,omitempty"`
// 分页参数
Page int `json:"page" validate:"min=1"`
PageSize int `json:"page_size" validate:"min=1,max=50"`
// 排序参数
SortBy string `json:"sort_by"`
SortOrder string `json:"sort_order"`
// 搜索选项
ExactMatch bool `json:"exact_match,omitempty"` // 是否精确匹配
IgnoreCase bool `json:"ignore_case,omitempty"` // 是否忽略大小写
}
// DefaultValues 设置搜索查询默认值
func (q *SearchCertificationsQuery) DefaultValues() {
if q.Page <= 0 {
q.Page = 1
}
if q.PageSize <= 0 {
q.PageSize = 10
}
if q.SortBy == "" {
q.SortBy = "created_at"
}
if q.SortOrder == "" {
q.SortOrder = "desc"
}
if len(q.SearchFields) == 0 {
q.SearchFields = []string{"company_name", "legal_person_name"}
}
// 默认忽略大小写
q.IgnoreCase = true
}
// GetLimit 获取查询限制数量
func (q *SearchCertificationsQuery) GetLimit() int {
return q.PageSize
}
// GetSearchPattern 获取搜索模式
func (q *SearchCertificationsQuery) GetSearchPattern() string {
if q.ExactMatch {
return q.Keyword
}
// 模糊搜索,添加通配符
return "%" + q.Keyword + "%"
}
// UserCertificationsQuery 用户认证查询
type UserCertificationsQuery struct {
UserID string `json:"user_id" validate:"required"`
// 状态过滤
Status enums.CertificationStatus `json:"status,omitempty"`
IncludeCompleted bool `json:"include_completed,omitempty"`
IncludeFailed bool `json:"include_failed,omitempty"`
// 时间过滤
After *time.Time `json:"after,omitempty"`
Before *time.Time `json:"before,omitempty"`
// 分页
Page int `json:"page"`
PageSize int `json:"page_size"`
// 排序
SortBy string `json:"sort_by"`
SortOrder string `json:"sort_order"`
}
// DefaultValues 设置用户认证查询默认值
func (q *UserCertificationsQuery) DefaultValues() {
if q.Page <= 0 {
q.Page = 1
}
if q.PageSize <= 0 {
q.PageSize = 10
}
if q.SortBy == "" {
q.SortBy = "created_at"
}
if q.SortOrder == "" {
q.SortOrder = "desc"
}
}
// ShouldIncludeStatus 检查是否应该包含指定状态
func (q *UserCertificationsQuery) ShouldIncludeStatus(status enums.CertificationStatus) bool {
// 如果指定了特定状态,只返回该状态
if q.Status != "" {
return status == q.Status
}
// 根据包含选项决定
if enums.IsFinalStatus(status) && !q.IncludeCompleted {
return false
}
if enums.IsFailureStatus(status) && !q.IncludeFailed {
return false
}
return true
}