package handlers import ( "platform/pkg/u" "platform/web/auth" "platform/web/core" g "platform/web/globals" m "platform/web/models" q "platform/web/queries" s "platform/web/services" "time" "gorm.io/gen/field" "github.com/gofiber/fiber/v2" ) // ListResourceShort 分页短效套餐 func ListResourceShort(c *fiber.Ctx) error { // 检查权限 authCtx, err := auth.GetAuthCtx(c).PermitUser() if err != nil { return err } // 解析请求参数 req := new(ListResourceShortReq) if err := c.BodyParser(req); err != nil { return err } // 查询套餐列表 do := q.Resource.Where( q.Resource.UserID.Eq(authCtx.User.ID), q.Resource.Type.Eq(int(m.ResourceTypeShort)), ) if req.ResourceNo != nil && *req.ResourceNo != "" { do.Where(q.Resource.ResourceNo.Eq(*req.ResourceNo)) } if req.Active != nil { do.Where(q.Resource.Active.Is(*req.Active)) } if req.Type != nil { do.Where(q.ResourceShort.As(q.Resource.Short.Name()).Type.Eq(*req.Type)) } if req.CreateAfter != nil { do.Where(q.Resource.CreatedAt.Gte(*req.CreateAfter)) } if req.CreateBefore != nil { do.Where(q.Resource.CreatedAt.Lte(*req.CreateBefore)) } if req.ExpireAfter != nil { do.Where(q.ResourceShort.As(q.Resource.Short.Name()).ExpireAt.Gte(*req.ExpireAfter)) } if req.ExpireBefore != nil { do.Where(q.ResourceShort.As(q.Resource.Short.Name()).ExpireAt.Lte(*req.ExpireBefore)) } resource, err := q.Resource.Where(do). Joins(q.Resource.Short). Order(q.Resource.CreatedAt.Desc()). Offset(req.GetOffset()). Limit(req.GetLimit()). Find() if err != nil { return err } var total int64 if len(resource) < req.GetLimit() { total = int64(len(resource) + req.GetOffset()) } else { total, err = q.Resource. Where(do). Count() if err != nil { return err } } return c.JSON(core.PageResp{ Total: int(total), Page: req.GetPage(), Size: req.GetSize(), List: resource, }) } type ListResourceShortReq struct { core.PageReq ResourceNo *string `json:"resource_no"` Active *bool `json:"active"` Type *int `json:"type"` CreateAfter *time.Time `json:"create_after"` CreateBefore *time.Time `json:"create_before"` ExpireAfter *time.Time `json:"expire_after"` ExpireBefore *time.Time `json:"expire_before"` } // ListResourceLong 分页长效套餐 func ListResourceLong(c *fiber.Ctx) error { // 检查权限 authCtx, err := auth.GetAuthCtx(c).PermitUser() if err != nil { return err } // 解析请求参数 req := new(ListResourceLongReq) if err := c.BodyParser(req); err != nil { return err } // 查询套餐列表 do := q.Resource.Where( q.Resource.UserID.Eq(authCtx.User.ID), q.Resource.Type.Eq(int(m.ResourceTypeLong)), ) if req.ResourceNo != nil && *req.ResourceNo != "" { do.Where(q.Resource.ResourceNo.Eq(*req.ResourceNo)) } if req.Active != nil { do.Where(q.Resource.Active.Is(*req.Active)) } if req.Type != nil { do.Where(q.ResourceLong.As(q.Resource.Long.Name()).Type.Eq(int(*req.Type))) } if req.CreateAfter != nil { do.Where(q.Resource.CreatedAt.Gte(*req.CreateAfter)) } if req.CreateBefore != nil { do.Where(q.Resource.CreatedAt.Lte(*req.CreateBefore)) } if req.ExpireAfter != nil { do.Where(q.ResourceLong.As(q.Resource.Long.Name()).ExpireAt.Gte(*req.ExpireAfter)) } if req.ExpireBefore != nil { do.Where(q.ResourceLong.As(q.Resource.Long.Name()).ExpireAt.Lte(*req.ExpireBefore)) } resource, err := q.Resource.Where(do). Joins(q.Resource.Long). Order(q.Resource.CreatedAt.Desc()). Offset(req.GetOffset()). Limit(req.GetLimit()). Find() if err != nil { return err } var total int64 if len(resource) < req.GetLimit() { total = int64(len(resource) + req.GetOffset()) } else { total, err = q.Resource. Where(do). Count() if err != nil { return err } } return c.JSON(core.PageResp{ Total: int(total), Page: req.GetPage(), Size: req.GetSize(), List: resource, }) } type ListResourceLongReq struct { core.PageReq ResourceNo *string `json:"resource_no"` Active *bool `json:"active"` Type *int `json:"type"` CreateAfter *time.Time `json:"create_after"` CreateBefore *time.Time `json:"create_before"` ExpireAfter *time.Time `json:"expire_after"` ExpireBefore *time.Time `json:"expire_before"` } // AllActiveResource 所有可用套餐 func AllActiveResource(c *fiber.Ctx) error { // 检查权限 authCtx, err := auth.GetAuthCtx(c).PermitUser() if err != nil { return err } // 查询套餐列表 var now = time.Now() var short = q.ResourceShort.As(q.Resource.Short.Name()) var long = q.ResourceLong.As(q.Resource.Long.Name()) resources, err := q.Resource. Joins( q.Resource.Short, q.Resource.Long, ). Where( q.Resource.UserID.Eq(authCtx.User.ID), q.Resource.Active.Is(true), q.Resource.Where( q.Resource.Type.Eq(int(m.ResourceTypeShort)), q.ResourceShort.As(q.Resource.Short.Name()).Where( short.Type.Eq(int(m.ResourceModeTime)), short.ExpireAt.Gte(now), q.ResourceShort.As(q.Resource.Short.Name()). Where(short.LastAt.Lt(u.Today())). Or(short.Quota.GtCol(short.Daily)), ).Or( short.Type.Eq(int(m.ResourceModeQuota)), short.Quota.GtCol(short.Used), ), ).Or( q.Resource.Type.Eq(int(m.ResourceTypeLong)), q.ResourceLong.As(q.Resource.Long.Name()).Where( long.Type.Eq(int(m.ResourceModeTime)), long.ExpireAt.Gte(now), q.ResourceLong.As(q.Resource.Long.Name()). Where(long.LastAt.Lt(u.Today())). Or(long.Quota.GtCol(long.Daily)), ).Or( long.Type.Eq(int(m.ResourceModeQuota)), long.Quota.GtCol(long.Used), ), ), ). Order(q.Resource.CreatedAt.Desc()). Find() if err != nil { return err } return c.JSON(resources) } type AllResourceReq struct { } // StatisticResourceFree 统计每日可用 func StatisticResourceFree(c *fiber.Ctx) error { // 检查权限 authCtx, err := auth.GetAuthCtx(c).PermitUser() if err != nil { return err } // 统计套餐剩余数量 resources, err := q.Resource. Preload( q.Resource.Short, q.Resource.Long, ). Where( q.Resource.UserID.Eq(authCtx.User.ID), q.Resource.Active.Is(true), ). Select(q.Resource.ID, q.Resource.Type). Find() if err != nil { return err } var shortCount, shortQuotaSum, shortDailyFreeSum int var longCount, longQuotaSum, longDailyFreeSum int for _, resource := range resources { switch { // 短效包量 case resource.Type == m.ResourceTypeShort && resource.Short.Type == m.ResourceModeQuota: if resource.Short.Quota > resource.Short.Used { shortCount++ shortQuotaSum += int(resource.Short.Quota - resource.Short.Used) } // 长效包量 case resource.Type == m.ResourceTypeLong && resource.Long.Type == m.ResourceModeQuota: if resource.Long.Quota > resource.Long.Used { longCount++ longQuotaSum += int(resource.Long.Quota - resource.Long.Used) } // 短效包时 case resource.Type == m.ResourceTypeShort && resource.Short.Type == m.ResourceModeTime: if time.Time(*resource.Short.ExpireAt).After(time.Now()) { if resource.Short.LastAt == nil || u.IsToday(time.Time(*resource.Short.LastAt)) == false { shortCount++ shortDailyFreeSum += int(resource.Short.Quota) } else if resource.Short.Quota > resource.Short.Daily { shortCount++ shortDailyFreeSum += int(resource.Short.Quota - resource.Short.Daily) } } // 长效包时 case resource.Type == m.ResourceTypeLong && resource.Long.Type == m.ResourceModeTime: if time.Time(*resource.Long.ExpireAt).After(time.Now()) { if resource.Long.LastAt == nil || u.IsToday(time.Time(*resource.Long.LastAt)) == false { longCount++ longDailyFreeSum += int(resource.Long.Quota) } else if resource.Long.Quota > resource.Long.Daily { longCount++ longDailyFreeSum += int(resource.Long.Quota - resource.Long.Daily) } } } } return c.JSON(StatisticPersonalResp{ Short: StatisticShort{ ResourceCount: shortCount, ResourceQuotaSum: shortQuotaSum, ResourceDailyFreeSum: shortDailyFreeSum, }, Long: StatisticLong{ ResourceCount: longCount, ResourceQuotaSum: longQuotaSum, ResourceDailyFreeSum: longDailyFreeSum, }, }) } type StatisticPersonalResp struct { Short StatisticShort `json:"short"` Long StatisticLong `json:"long"` } type StatisticShort struct { ResourceCount int `json:"resource_count"` ResourceQuotaSum int `json:"resource_quota_sum"` ResourceDailyFreeSum int `json:"resource_daily_free_sum"` } type StatisticLong struct { ResourceCount int `json:"resource_count"` ResourceQuotaSum int `json:"resource_quota_sum"` ResourceDailyFreeSum int `json:"resource_daily_free_sum"` } // StatisticResourceUsage 统计每日用量 func StatisticResourceUsage(c *fiber.Ctx) error { // 检查权限 authCtx, err := auth.GetAuthCtx(c).PermitUser() if err != nil { return err } // 解析请求参数 var req = new(StatisticResourceUsageReq) if err := g.Validator.ParseBody(c, req); err != nil { return err } // 统计套餐提取数量 do := q.LogsUserUsage.Where( q.LogsUserUsage.UserID.Eq(authCtx.User.ID), ) if req.TimeAfter != nil { do.Where(q.LogsUserUsage.Time.Gte(*req.TimeAfter)) } if req.TimeBefore != nil { do.Where(q.LogsUserUsage.Time.Lte(*req.TimeBefore)) } var data = new(StatisticResourceUsageResp) err = q.LogsUserUsage. Select( q.LogsUserUsage.Count_.Sum().As("count"), field.NewUnsafeFieldRaw("date_trunc('day', time)").As("date"), ). Where(do). Group( field.NewField("", "date"), ). Order( field.NewField("", "date").Desc(), ). Scan(&data) if err != nil { return err } return c.JSON(data) } type StatisticResourceUsageReq struct { TimeAfter *time.Time `json:"time_start"` TimeBefore *time.Time `json:"time_end"` } type StatisticResourceUsageResp []struct { Date time.Time `json:"date"` Count int `json:"count"` } // CreateResource 创建套餐 func CreateResource(c *fiber.Ctx) error { // 检查权限 authCtx, err := auth.GetAuthCtx(c).PermitUser() if err != nil { return err } // 解析请求参数 var req = new(CreateResourceReq) if err := g.Validator.ParseBody(c, req); err != nil { return err } // 创建套餐 err = s.Resource.CreateResourceByBalance(authCtx.User.ID, time.Now(), req.CreateResourceData) if err != nil { return err } return nil } type CreateResourceReq struct { *s.CreateResourceData } // ResourcePrice 套餐价格 func ResourcePrice(c *fiber.Ctx) error { // 检查权限 _, err := auth.GetAuthCtx(c).PermitSecretClient() if err != nil { return err } // 解析请求参数 var req = new(CreateResourceReq) if err := g.Validator.ParseBody(c, req); err != nil { return core.NewBizErr("接口参数解析异常", err) } // 获取套餐价格 amount, err := req.GetAmount() if err != nil { return err } // 计算折扣 return c.JSON(ResourcePriceResp{ Price: amount.StringFixed(2), Discounted: 1, DiscountedPrice: amount.StringFixed(2), }) } type ResourcePriceResp struct { Price string `json:"price"` Discounted float32 `json:"discounted"` DiscountedPrice string `json:"discounted_price"` }