From fb636b9450184044cc678283eb35689d47f9975e Mon Sep 17 00:00:00 2001 From: hanxuanyu <2252193204@qq.com> Date: Fri, 30 Jan 2026 15:49:51 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8C=89=E9=9C=80=E6=8A=93?= =?UTF-8?q?=E5=8F=96=E9=80=BB=E8=BE=91=EF=BC=9A=E6=94=B9=E4=B8=BA=E5=BC=82?= =?UTF-8?q?=E6=AD=A5=E5=A4=84=E7=90=86=E4=BB=A5=E6=8F=90=E5=8D=87=E6=80=A7?= =?UTF-8?q?=E8=83=BD=EF=BC=8C=E5=B9=B6=E4=B8=BA=E7=9B=B8=E5=85=B3=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E6=96=B0=E5=A2=9E=20202=20=E7=8A=B6=E6=80=81=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/http/handlers/image.go | 30 ++++++++++++++++++ internal/service/image/image_service.go | 42 ++++++++++++------------- internal/util/regions.go | 2 -- 3 files changed, 51 insertions(+), 23 deletions(-) diff --git a/internal/http/handlers/image.go b/internal/http/handlers/image.go index 5828c8d..846e934 100644 --- a/internal/http/handlers/image.go +++ b/internal/http/handlers/image.go @@ -48,11 +48,16 @@ type ImageMetaResp struct { // @Param format query string false "格式 (jpg)" default(jpg) // @Produce image/jpeg // @Success 200 {file} binary +// @Success 202 {object} map[string]string "按需抓取任务已启动" // @Failure 404 {object} map[string]string "图片未找到,响应体包含具体原因" // @Router /image/today [get] func GetToday(c *gin.Context) { mkt := c.Query("mkt") img, err := image.GetTodayImage(mkt) + if err == image.ErrFetchStarted { + c.JSON(http.StatusAccepted, gin.H{"message": fmt.Sprintf("On-demand fetch started for region [%s]. Please try again later.", mkt)}) + return + } if err != nil { sendImageNotFound(c, mkt) return @@ -67,11 +72,16 @@ func GetToday(c *gin.Context) { // @Param mkt query string false "地区编码 (如 zh-CN, en-US)" // @Produce json // @Success 200 {object} ImageMetaResp +// @Success 202 {object} map[string]string "按需抓取任务已启动" // @Failure 404 {object} map[string]string "图片未找到,响应体包含具体原因" // @Router /image/today/meta [get] func GetTodayMeta(c *gin.Context) { mkt := c.Query("mkt") img, err := image.GetTodayImage(mkt) + if err == image.ErrFetchStarted { + c.JSON(http.StatusAccepted, gin.H{"message": fmt.Sprintf("On-demand fetch started for region [%s]. Please try again later.", mkt)}) + return + } if err != nil { sendImageNotFound(c, mkt) return @@ -89,11 +99,16 @@ func GetTodayMeta(c *gin.Context) { // @Param format query string false "格式" default(jpg) // @Produce image/jpeg // @Success 200 {file} binary +// @Success 202 {object} map[string]string "按需抓取任务已启动" // @Failure 404 {object} map[string]string "图片未找到,响应体包含具体原因" // @Router /image/random [get] func GetRandom(c *gin.Context) { mkt := c.Query("mkt") img, err := image.GetRandomImage(mkt) + if err == image.ErrFetchStarted { + c.JSON(http.StatusAccepted, gin.H{"message": fmt.Sprintf("On-demand fetch started for region [%s]. Please try again later.", mkt)}) + return + } if err != nil { sendImageNotFound(c, mkt) return @@ -108,11 +123,16 @@ func GetRandom(c *gin.Context) { // @Param mkt query string false "地区编码 (如 zh-CN, en-US)" // @Produce json // @Success 200 {object} ImageMetaResp +// @Success 202 {object} map[string]string "按需抓取任务已启动" // @Failure 404 {object} map[string]string "图片未找到,响应体包含具体原因" // @Router /image/random/meta [get] func GetRandomMeta(c *gin.Context) { mkt := c.Query("mkt") img, err := image.GetRandomImage(mkt) + if err == image.ErrFetchStarted { + c.JSON(http.StatusAccepted, gin.H{"message": fmt.Sprintf("On-demand fetch started for region [%s]. Please try again later.", mkt)}) + return + } if err != nil { sendImageNotFound(c, mkt) return @@ -131,12 +151,17 @@ func GetRandomMeta(c *gin.Context) { // @Param format query string false "格式" default(jpg) // @Produce image/jpeg // @Success 200 {file} binary +// @Success 202 {object} map[string]string "按需抓取任务已启动" // @Failure 404 {object} map[string]string "图片未找到,响应体包含具体原因" // @Router /image/date/{date} [get] func GetByDate(c *gin.Context) { date := c.Param("date") mkt := c.Query("mkt") img, err := image.GetImageByDate(date, mkt) + if err == image.ErrFetchStarted { + c.JSON(http.StatusAccepted, gin.H{"message": fmt.Sprintf("On-demand fetch started for region [%s]. Please try again later.", mkt)}) + return + } if err != nil { sendImageNotFound(c, mkt) return @@ -152,12 +177,17 @@ func GetByDate(c *gin.Context) { // @Param mkt query string false "地区编码 (如 zh-CN, en-US)" // @Produce json // @Success 200 {object} ImageMetaResp +// @Success 202 {object} map[string]string "按需抓取任务已启动" // @Failure 404 {object} map[string]string "图片未找到,响应体包含具体原因" // @Router /image/date/{date}/meta [get] func GetByDateMeta(c *gin.Context) { date := c.Param("date") mkt := c.Query("mkt") img, err := image.GetImageByDate(date, mkt) + if err == image.ErrFetchStarted { + c.JSON(http.StatusAccepted, gin.H{"message": fmt.Sprintf("On-demand fetch started for region [%s]. Please try again later.", mkt)}) + return + } if err != nil { sendImageNotFound(c, mkt) return diff --git a/internal/service/image/image_service.go b/internal/service/image/image_service.go index 426ca29..7e67778 100644 --- a/internal/service/image/image_service.go +++ b/internal/service/image/image_service.go @@ -2,6 +2,7 @@ package image import ( "context" + "errors" "fmt" "time" @@ -15,6 +16,8 @@ import ( "go.uber.org/zap" ) +var ErrFetchStarted = errors.New("on-demand fetch started") + func CleanupOldImages(ctx context.Context) error { days := config.GetConfig().Retention.Days if days <= 0 { @@ -60,14 +63,13 @@ func GetTodayImage(mkt string) (*model.Image, error) { } err := tx.Preload("Variants").First(&img).Error if err != nil && mkt != "" && config.GetConfig().API.EnableOnDemandFetch && util.IsValidRegion(mkt) { - // 如果没找到,尝试按需抓取该地区 - util.Logger.Info("Image not found in DB, attempting on-demand fetch", zap.String("mkt", mkt)) + // 如果没找到,尝试异步按需抓取该地区 + util.Logger.Info("Image not found in DB, starting asynchronous on-demand fetch", zap.String("mkt", mkt)) f := fetcher.NewFetcher() - _ = f.FetchRegion(context.Background(), mkt) - - // 抓取后重新查询 - tx = repo.DB.Where("date = ?", today).Where("mkt = ?", mkt) - err = tx.Preload("Variants").First(&img).Error + go func() { + _ = f.FetchRegion(context.Background(), mkt) + }() + return nil, ErrFetchStarted } if err != nil { @@ -118,14 +120,13 @@ func GetRandomImage(mkt string) (*model.Image, error) { } tx.Count(&count) if count == 0 && mkt != "" && config.GetConfig().API.EnableOnDemandFetch && util.IsValidRegion(mkt) { - // 如果没找到,尝试按需抓取该地区 - util.Logger.Info("No images found in DB for region, attempting on-demand fetch", zap.String("mkt", mkt)) + // 如果没找到,尝试异步按需抓取该地区 + util.Logger.Info("No images found in DB for region, starting asynchronous on-demand fetch", zap.String("mkt", mkt)) f := fetcher.NewFetcher() - _ = f.FetchRegion(context.Background(), mkt) - - // 抓取后重新计数 - tx = repo.DB.Model(&model.Image{}).Where("mkt = ?", mkt) - tx.Count(&count) + go func() { + _ = f.FetchRegion(context.Background(), mkt) + }() + return nil, ErrFetchStarted } if count == 0 { @@ -167,14 +168,13 @@ func GetImageByDate(date string, mkt string) (*model.Image, error) { } err := tx.Preload("Variants").First(&img).Error if err != nil && mkt != "" && config.GetConfig().API.EnableOnDemandFetch && util.IsValidRegion(mkt) { - // 如果没找到,尝试按需抓取该地区 - util.Logger.Info("Image not found in DB for date, attempting on-demand fetch", zap.String("mkt", mkt), zap.String("date", date)) + // 如果没找到,尝试异步按需抓取该地区 + util.Logger.Info("Image not found in DB for date, starting asynchronous on-demand fetch", zap.String("mkt", mkt), zap.String("date", date)) f := fetcher.NewFetcher() - _ = f.FetchRegion(context.Background(), mkt) - - // 抓取后重新查询 - tx = repo.DB.Where("date = ?", date).Where("mkt = ?", mkt) - err = tx.Preload("Variants").First(&img).Error + go func() { + _ = f.FetchRegion(context.Background(), mkt) + }() + return nil, ErrFetchStarted } // 兜底逻辑 diff --git a/internal/util/regions.go b/internal/util/regions.go index 9ae9a74..a89d618 100644 --- a/internal/util/regions.go +++ b/internal/util/regions.go @@ -32,6 +32,4 @@ var AllRegions = []Region{ {Value: "ko-KR", Label: "韩国"}, {Value: "en-IN", Label: "印度"}, {Value: "ru-RU", Label: "俄罗斯"}, - {Value: "zh-HK", Label: "中国香港"}, - {Value: "zh-TW", Label: "中国台湾"}, }