基本功能实现

This commit is contained in:
2026-01-26 21:53:34 +08:00
commit c6e5e655f9
28 changed files with 4803 additions and 0 deletions

View File

@@ -0,0 +1,92 @@
package image
import (
"context"
"fmt"
"time"
"BingDailyImage/internal/config"
"BingDailyImage/internal/model"
"BingDailyImage/internal/repo"
"BingDailyImage/internal/storage"
"BingDailyImage/internal/util"
"go.uber.org/zap"
)
func CleanupOldImages(ctx context.Context) error {
days := config.GetConfig().Retention.Days
if days <= 0 {
return nil
}
threshold := time.Now().AddDate(0, 0, -days).Format("2006-01-02")
util.Logger.Info("Starting cleanup task", zap.Int("retention_days", days), zap.String("threshold", threshold))
var images []model.Image
if err := repo.DB.Where("date < ?", threshold).Preload("Variants").Find(&images).Error; err != nil {
return err
}
for _, img := range images {
util.Logger.Info("Deleting old image", zap.String("date", img.Date))
for _, v := range img.Variants {
if err := storage.GlobalStorage.Delete(ctx, v.StorageKey); err != nil {
util.Logger.Warn("Failed to delete storage object", zap.String("key", v.StorageKey), zap.Error(err))
}
}
// 删除 DB 记录 (级联删除由代码处理,或者 GORM 会处理已加载的关联吗?)
// 简单起见,手动删除关联
repo.DB.Where("image_id = ?", img.ID).Delete(&model.ImageVariant{})
repo.DB.Delete(&img)
}
util.Logger.Info("Cleanup task completed", zap.Int("deleted_count", len(images)))
return nil
}
func GetTodayImage() (*model.Image, error) {
today := time.Now().Format("2006-01-02")
var img model.Image
err := repo.DB.Where("date = ?", today).Preload("Variants").First(&img).Error
if err != nil {
// 如果今天没有,尝试获取最近的一张
err = repo.DB.Order("date desc").Preload("Variants").First(&img).Error
}
return &img, err
}
func GetRandomImage() (*model.Image, error) {
var img model.Image
// SQLite 使用 RANDOM(), MySQL/Postgres 使用 RANDOM() 或 RAND()
// 简单起见,先查总数再 Offset
var count int64
repo.DB.Model(&model.Image{}).Count(&count)
if count == 0 {
return nil, fmt.Errorf("no images found")
}
// 这种方法不适合海量数据,但对于 30 天的数据没问题
err := repo.DB.Order("RANDOM()").Preload("Variants").First(&img).Error
if err != nil {
// 适配 MySQL
err = repo.DB.Order("RAND()").Preload("Variants").First(&img).Error
}
return &img, err
}
func GetImageByDate(date string) (*model.Image, error) {
var img model.Image
err := repo.DB.Where("date = ?", date).Preload("Variants").First(&img).Error
return &img, err
}
func GetImageList(limit int) ([]model.Image, error) {
var images []model.Image
db := repo.DB.Order("date desc").Preload("Variants")
if limit > 0 {
db = db.Limit(limit)
}
err := db.Find(&images).Error
return images, err
}