package handler import ( "errors" "io" "net/http" "time" "github.com/gin-gonic/gin" "wx_service/internal/middleware" "wx_service/internal/model" smokeservice "wx_service/internal/smoke/service" ) type unlockAIAdviceRequest struct { Date string `json:"date"` AdWatchedAt string `json:"ad_watched_at"` } func (h *SmokeHandler) GetAIAdvice(c *gin.Context) { user, ok := middleware.CurrentUser(c) if !ok { c.JSON(http.StatusUnauthorized, model.Error(http.StatusUnauthorized, "未登录或登录已过期")) return } dateStr := c.Query("date") adviceDate := yesterdayDate() if dateStr != "" { parsed, err := time.ParseInLocation(dateLayout, dateStr, time.Local) if err != nil { c.JSON(http.StatusBadRequest, model.Error(http.StatusBadRequest, "date 格式错误,应为 YYYY-MM-DD")) return } adviceDate = parsed } record, err := h.smokeAIAdviceService.GetOrGenerate(c.Request.Context(), user, adviceDate, smokeservice.DefaultAdvicePromptVersion) if err != nil { switch { case errors.Is(err, smokeservice.ErrAIAdviceLocked): c.JSON(http.StatusForbidden, model.Error(http.StatusForbidden, "需要会员或观看广告解锁后才可生成建议")) return case errors.Is(err, smokeservice.ErrAIServiceDisabled): c.JSON(http.StatusServiceUnavailable, model.Error(http.StatusServiceUnavailable, "AI 服务暂不可用,请联系管理员")) return case errors.Is(err, smokeservice.ErrNoSmokeLogs): c.JSON(http.StatusBadRequest, model.Error(http.StatusBadRequest, "该日期没有抽烟记录,无法生成建议")) return default: c.JSON(http.StatusInternalServerError, model.Error(http.StatusInternalServerError, "生成建议失败,请稍后重试")) return } } c.JSON(http.StatusOK, model.Success(gin.H{ "date": record.AdviceDate.Format(dateLayout), "advice": record.Advice, })) } func (h *SmokeHandler) UnlockAIAdvice(c *gin.Context) { user, ok := middleware.CurrentUser(c) if !ok { c.JSON(http.StatusUnauthorized, model.Error(http.StatusUnauthorized, "未登录或登录已过期")) return } var req unlockAIAdviceRequest if err := c.ShouldBindJSON(&req); err != nil && !errors.Is(err, io.EOF) { c.JSON(http.StatusBadRequest, model.Error(http.StatusBadRequest, "请求参数错误")) return } unlockDate := yesterdayDate() if req.Date != "" { parsed, err := time.ParseInLocation(dateLayout, req.Date, time.Local) if err != nil { c.JSON(http.StatusBadRequest, model.Error(http.StatusBadRequest, "date 格式错误,应为 YYYY-MM-DD")) return } unlockDate = parsed } if err := h.smokeAIAdviceService.Unlock(c.Request.Context(), user, unlockDate); err != nil { c.JSON(http.StatusInternalServerError, model.Error(http.StatusInternalServerError, "解锁失败,请稍后重试")) return } c.JSON(http.StatusOK, model.Success(gin.H{ "unlocked": true, "date": unlockDate.Format(dateLayout), })) } func yesterdayDate() time.Time { now := time.Now().In(time.Local) y := now.AddDate(0, 0, -1) return time.Date(y.Year(), y.Month(), y.Day(), 0, 0, 0, 0, time.Local) }