86 lines
2.6 KiB
Go
86 lines
2.6 KiB
Go
// Package file 提供文件元数据(files 表)的数据访问。
|
|
// 所有查询均参数化,杜绝 SQL 注入;仅负责持久化,不涉及存储后端 IO。
|
|
package file
|
|
|
|
import (
|
|
"context"
|
|
|
|
"gorm.io/gorm"
|
|
|
|
"portal-mini-go/internal/model"
|
|
"portal-mini-go/internal/pkg/errors"
|
|
)
|
|
|
|
// Repository 文件元数据仓储。
|
|
type Repository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func New(db *gorm.DB) *Repository { return &Repository{db: db} }
|
|
|
|
// Create 写入文件记录。
|
|
func (r *Repository) Create(ctx context.Context, f *model.File) error {
|
|
if err := r.db.WithContext(ctx).Create(f).Error; err != nil {
|
|
return errors.Wrap(50000, "create file record", err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetByID 按 ID 查询文件元数据,不存在返回 ErrNotFound。
|
|
func (r *Repository) GetByID(ctx context.Context, id uint64) (*model.File, error) {
|
|
var f model.File
|
|
if err := r.db.WithContext(ctx).Where("id = ?", id).First(&f).Error; err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, errors.ErrNotFound
|
|
}
|
|
return nil, errors.Wrap(50000, "query file", err)
|
|
}
|
|
return &f, nil
|
|
}
|
|
|
|
// Delete 按 ID 删除文件元数据,不存在返回 ErrNotFound。
|
|
func (r *Repository) Delete(ctx context.Context, id uint64) error {
|
|
res := r.db.WithContext(ctx).Where("id = ?", id).Delete(&model.File{})
|
|
if res.Error != nil {
|
|
return errors.Wrap(50000, "delete file", res.Error)
|
|
}
|
|
if res.RowsAffected == 0 {
|
|
return errors.ErrNotFound
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// ListFilter 文件列表过滤条件。
|
|
type ListFilter struct {
|
|
UploaderType string // 上传者类型(admin/ma),为空表示不限
|
|
UploaderID uint64 // 上传者主键,0 表示不限
|
|
Keyword string // 模糊匹配 origin_name 或 filename,为空表示不限
|
|
Page int // 页码,从 1 开始
|
|
Size int // 每页条数
|
|
}
|
|
|
|
// List 分页查询文件,所有条件均为可选。返回列表、总数与错误。
|
|
func (r *Repository) List(ctx context.Context, f ListFilter) ([]model.File, int64, error) {
|
|
q := r.db.WithContext(ctx).Model(&model.File{})
|
|
if f.UploaderType != "" {
|
|
q = q.Where("uploader_type = ?", f.UploaderType)
|
|
}
|
|
if f.UploaderID != 0 {
|
|
q = q.Where("uploader_id = ?", f.UploaderID)
|
|
}
|
|
if f.Keyword != "" {
|
|
kw := "%" + f.Keyword + "%"
|
|
q = q.Where("origin_name LIKE ? OR filename LIKE ?", kw, kw)
|
|
}
|
|
|
|
var total int64
|
|
if err := q.Count(&total).Error; err != nil {
|
|
return nil, 0, errors.Wrap(50000, "count files", err)
|
|
}
|
|
var list []model.File
|
|
if err := q.Order("id DESC").Offset((f.Page - 1) * f.Size).Limit(f.Size).Find(&list).Error; err != nil {
|
|
return nil, 0, errors.Wrap(50000, "list files", err)
|
|
}
|
|
return list, total, nil
|
|
}
|