| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103 |
- package admin
- import (
- "errors"
- "strconv"
- "github.com/Wei-Shaw/sub2api/internal/pkg/response"
- "github.com/Wei-Shaw/sub2api/internal/service"
- "github.com/gin-gonic/gin"
- )
- // SpendGuardHandler 烧钱防护:token 速率/错误率超阈自动冻结 key。
- type SpendGuardHandler struct {
- service *service.SpendGuardService
- }
- func NewSpendGuardHandler(svc *service.SpendGuardService) *SpendGuardHandler {
- return &SpendGuardHandler{service: svc}
- }
- func (h *SpendGuardHandler) requireService(c *gin.Context) bool {
- if h == nil || h.service == nil {
- response.ErrorFrom(c, errors.New("spend guard service unavailable"))
- return false
- }
- return true
- }
- // Offenders 窗口内各 key 用量与错误排行。
- // GET /api/v1/admin/spend-guard
- func (h *SpendGuardHandler) Offenders(c *gin.Context) {
- if !h.requireService(c) {
- return
- }
- items, err := h.service.Offenders(c.Request.Context(), 0)
- if err != nil {
- response.ErrorFrom(c, err)
- return
- }
- if items == nil {
- items = []service.SpendGuardOffender{}
- }
- response.Success(c, gin.H{"items": items, "count": len(items)})
- }
- // GetSettings 读取防护配置。
- // GET /api/v1/admin/spend-guard/settings
- func (h *SpendGuardHandler) GetSettings(c *gin.Context) {
- if !h.requireService(c) {
- return
- }
- response.Success(c, h.service.GetSettings(c.Request.Context()))
- }
- // UpdateSettings 更新防护配置。
- // PUT /api/v1/admin/spend-guard/settings
- func (h *SpendGuardHandler) UpdateSettings(c *gin.Context) {
- if !h.requireService(c) {
- return
- }
- var req service.SpendGuardSettings
- if err := c.ShouldBindJSON(&req); err != nil {
- response.BadRequest(c, "Invalid request: "+err.Error())
- return
- }
- out, err := h.service.UpdateSettings(c.Request.Context(), req)
- if err != nil {
- response.ErrorFrom(c, err)
- return
- }
- response.Success(c, out)
- }
- // Events 近期冻结/解冻事件。
- // GET /api/v1/admin/spend-guard/events
- func (h *SpendGuardHandler) Events(c *gin.Context) {
- if !h.requireService(c) {
- return
- }
- events := h.service.Events()
- if events == nil {
- events = []service.SpendGuardEvent{}
- }
- response.Success(c, gin.H{"items": events, "count": len(events)})
- }
- // Unfreeze 手动解冻 key。
- // POST /api/v1/admin/spend-guard/keys/:id/unfreeze
- func (h *SpendGuardHandler) Unfreeze(c *gin.Context) {
- if !h.requireService(c) {
- return
- }
- id, err := strconv.ParseInt(c.Param("id"), 10, 64)
- if err != nil || id <= 0 {
- response.BadRequest(c, "Invalid API key ID")
- return
- }
- if err := h.service.Unfreeze(c.Request.Context(), id); err != nil {
- response.ErrorFrom(c, err)
- return
- }
- response.Success(c, gin.H{"message": "API key unfrozen successfully"})
- }
|