Files
backend/internal/repository/uploaded_file_repo.go
lafay a0e210feab
All checks were successful
Build Backend / build (push) Successful in 3m1s
Build Backend / build-docker (push) Successful in 2m10s
feat(server): implement chat file TTL cleanup and enhance JPush vendor channel support
Add FileCleanupWorker for automatic expiration of chat files with configurable retention period and batch processing. Files uploaded via `/api/v1/uploads/files` are tracked in `uploaded_files` table with expiration timestamps, then deleted from S3 and database upon expiry. Expired file URLs are injected as `"expired": true` in message responses.

Extend JPush push notification configuration with vendor-specific channel_id support (xiaomi, huawei, oppo, vivo, meizu, honor, fcm) for differentiating system vs chat notifications. Add iOS APNs thread-id grouping configuration for notification categorization.
2026-06-17 20:41:55 +08:00

92 lines
2.9 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}