| package handler |
|
|
| import ( |
| "github.com/Wei-Shaw/sub2api/internal/handler/dto" |
| "github.com/Wei-Shaw/sub2api/internal/pkg/response" |
| middleware2 "github.com/Wei-Shaw/sub2api/internal/server/middleware" |
| "github.com/Wei-Shaw/sub2api/internal/service" |
|
|
| "github.com/gin-gonic/gin" |
| ) |
|
|
| |
| type SubscriptionSummaryItem struct { |
| ID int64 `json:"id"` |
| GroupID int64 `json:"group_id"` |
| GroupName string `json:"group_name"` |
| Status string `json:"status"` |
| DailyUsedUSD float64 `json:"daily_used_usd,omitempty"` |
| DailyLimitUSD float64 `json:"daily_limit_usd,omitempty"` |
| WeeklyUsedUSD float64 `json:"weekly_used_usd,omitempty"` |
| WeeklyLimitUSD float64 `json:"weekly_limit_usd,omitempty"` |
| MonthlyUsedUSD float64 `json:"monthly_used_usd,omitempty"` |
| MonthlyLimitUSD float64 `json:"monthly_limit_usd,omitempty"` |
| ExpiresAt *string `json:"expires_at,omitempty"` |
| } |
|
|
| |
| type SubscriptionProgressInfo struct { |
| Subscription *dto.UserSubscription `json:"subscription"` |
| Progress *service.SubscriptionProgress `json:"progress"` |
| } |
|
|
| |
| type SubscriptionHandler struct { |
| subscriptionService *service.SubscriptionService |
| } |
|
|
| |
| func NewSubscriptionHandler(subscriptionService *service.SubscriptionService) *SubscriptionHandler { |
| return &SubscriptionHandler{ |
| subscriptionService: subscriptionService, |
| } |
| } |
|
|
| |
| |
| func (h *SubscriptionHandler) List(c *gin.Context) { |
| subject, ok := middleware2.GetAuthSubjectFromContext(c) |
| if !ok { |
| response.Unauthorized(c, "User not found in context") |
| return |
| } |
|
|
| subscriptions, err := h.subscriptionService.ListUserSubscriptions(c.Request.Context(), subject.UserID) |
| if err != nil { |
| response.ErrorFrom(c, err) |
| return |
| } |
|
|
| out := make([]dto.UserSubscription, 0, len(subscriptions)) |
| for i := range subscriptions { |
| out = append(out, *dto.UserSubscriptionFromService(&subscriptions[i])) |
| } |
| response.Success(c, out) |
| } |
|
|
| |
| |
| func (h *SubscriptionHandler) GetActive(c *gin.Context) { |
| subject, ok := middleware2.GetAuthSubjectFromContext(c) |
| if !ok { |
| response.Unauthorized(c, "User not found in context") |
| return |
| } |
|
|
| subscriptions, err := h.subscriptionService.ListActiveUserSubscriptions(c.Request.Context(), subject.UserID) |
| if err != nil { |
| response.ErrorFrom(c, err) |
| return |
| } |
|
|
| out := make([]dto.UserSubscription, 0, len(subscriptions)) |
| for i := range subscriptions { |
| out = append(out, *dto.UserSubscriptionFromService(&subscriptions[i])) |
| } |
| response.Success(c, out) |
| } |
|
|
| |
| |
| func (h *SubscriptionHandler) GetProgress(c *gin.Context) { |
| subject, ok := middleware2.GetAuthSubjectFromContext(c) |
| if !ok { |
| response.Unauthorized(c, "User not found in context") |
| return |
| } |
|
|
| |
| subscriptions, err := h.subscriptionService.ListActiveUserSubscriptions(c.Request.Context(), subject.UserID) |
| if err != nil { |
| response.ErrorFrom(c, err) |
| return |
| } |
|
|
| result := make([]SubscriptionProgressInfo, 0, len(subscriptions)) |
| for i := range subscriptions { |
| sub := &subscriptions[i] |
| progress, err := h.subscriptionService.GetSubscriptionProgress(c.Request.Context(), sub.ID) |
| if err != nil { |
| |
| continue |
| } |
| result = append(result, SubscriptionProgressInfo{ |
| Subscription: dto.UserSubscriptionFromService(sub), |
| Progress: progress, |
| }) |
| } |
|
|
| response.Success(c, result) |
| } |
|
|
| |
| |
| func (h *SubscriptionHandler) GetSummary(c *gin.Context) { |
| subject, ok := middleware2.GetAuthSubjectFromContext(c) |
| if !ok { |
| response.Unauthorized(c, "User not found in context") |
| return |
| } |
|
|
| |
| subscriptions, err := h.subscriptionService.ListActiveUserSubscriptions(c.Request.Context(), subject.UserID) |
| if err != nil { |
| response.ErrorFrom(c, err) |
| return |
| } |
|
|
| var totalUsed float64 |
| items := make([]SubscriptionSummaryItem, 0, len(subscriptions)) |
|
|
| for _, sub := range subscriptions { |
| item := SubscriptionSummaryItem{ |
| ID: sub.ID, |
| GroupID: sub.GroupID, |
| Status: sub.Status, |
| DailyUsedUSD: sub.DailyUsageUSD, |
| WeeklyUsedUSD: sub.WeeklyUsageUSD, |
| MonthlyUsedUSD: sub.MonthlyUsageUSD, |
| } |
|
|
| |
| if sub.Group != nil { |
| item.GroupName = sub.Group.Name |
| if sub.Group.DailyLimitUSD != nil { |
| item.DailyLimitUSD = *sub.Group.DailyLimitUSD |
| } |
| if sub.Group.WeeklyLimitUSD != nil { |
| item.WeeklyLimitUSD = *sub.Group.WeeklyLimitUSD |
| } |
| if sub.Group.MonthlyLimitUSD != nil { |
| item.MonthlyLimitUSD = *sub.Group.MonthlyLimitUSD |
| } |
| } |
|
|
| |
| if !sub.ExpiresAt.IsZero() { |
| formatted := sub.ExpiresAt.Format("2006-01-02T15:04:05Z07:00") |
| item.ExpiresAt = &formatted |
| } |
|
|
| |
| totalUsed += sub.MonthlyUsageUSD |
|
|
| items = append(items, item) |
| } |
|
|
| summary := struct { |
| ActiveCount int `json:"active_count"` |
| TotalUsedUSD float64 `json:"total_used_usd"` |
| Subscriptions []SubscriptionSummaryItem `json:"subscriptions"` |
| }{ |
| ActiveCount: len(subscriptions), |
| TotalUsedUSD: totalUsed, |
| Subscriptions: items, |
| } |
|
|
| response.Success(c, summary) |
| } |
|
|