package repository import ( "context" "time" "with_you/internal/model" "gorm.io/gorm" ) // UploadedFileRepository 文件上传记录仓储接口 type UploadedFileRepository interface { // Create 写入一条上传记录 Create(ctx context.Context, file *model.UploadedFile) error // GetByURL 按 URL 查询记录(DTO 失效标记用) GetByURL(ctx context.Context, url string) (*model.UploadedFile, error) // ListPendingCleanup 取 created_at < before 且 expired=false 的记录,分批 ListPendingCleanup(ctx context.Context, before time.Time, limit int) ([]model.UploadedFile, error) // MarkExpired 标记某条记录已清理 MarkExpired(ctx context.Context, id uint, at time.Time) error // GetExpiredURLSet 批量查询已标记过期的 URL 集合(DTO 注入用) // 注意:这是全量扫描 expired=true 的记录,适用于上传量不大的场景; // 若 uploaded_files 表增长过大,可改为按时间窗口分页。 GetExpiredURLSet(ctx context.Context) (map[string]struct{}, error) } // uploadedFileRepository 文件上传记录仓储实现 type uploadedFileRepository struct { db *gorm.DB } // NewUploadedFileRepository 创建文件上传记录仓储 func NewUploadedFileRepository(db *gorm.DB) UploadedFileRepository { return &uploadedFileRepository{db: db} } // Create 写入一条上传记录 func (r *uploadedFileRepository) Create(ctx context.Context, file *model.UploadedFile) error { return r.db.WithContext(ctx).Create(file).Error } // GetByURL 按 URL 查询记录 func (r *uploadedFileRepository) GetByURL(ctx context.Context, url string) (*model.UploadedFile, error) { var file model.UploadedFile if err := r.db.WithContext(ctx).Where("url = ?", url).First(&file).Error; err != nil { return nil, err } return &file, nil } // ListPendingCleanup 取待清理记录 func (r *uploadedFileRepository) ListPendingCleanup(ctx context.Context, before time.Time, limit int) ([]model.UploadedFile, error) { if limit <= 0 { limit = 100 } var files []model.UploadedFile err := r.db.WithContext(ctx). Where("created_at < ? AND expired = ?", before, false). Order("created_at ASC"). Limit(limit). Find(&files).Error return files, err } // MarkExpired 标记已清理 func (r *uploadedFileRepository) MarkExpired(ctx context.Context, id uint, at time.Time) error { return r.db.WithContext(ctx).Model(&model.UploadedFile{}). Where("id = ?", id). Updates(map[string]any{ "expired": true, "expired_at": at, }).Error } // GetExpiredURLSet 批量查询已过期 URL 集合 func (r *uploadedFileRepository) GetExpiredURLSet(ctx context.Context) (map[string]struct{}, error) { var urls []string err := r.db.WithContext(ctx). Model(&model.UploadedFile{}). Where("expired = ?", true). Pluck("url", &urls).Error if err != nil { return nil, err } set := make(map[string]struct{}, len(urls)) for _, u := range urls { set[u] = struct{}{} } return set, nil }