CheckRateLimit 检查令牌的访问频率限制
(token *Token)
| 420 | |
| 421 | // CheckRateLimit 检查令牌的访问频率限制 |
| 422 | func CheckRateLimit(token *Token) error { |
| 423 | if token == nil { |
| 424 | return errors.New("token不能为空") |
| 425 | } |
| 426 | |
| 427 | // 如果没有设置限制,直接返回 |
| 428 | if token.RateLimitPerMinute <= 0 && token.RateLimitPerDay <= 0 { |
| 429 | return nil |
| 430 | } |
| 431 | |
| 432 | currentTime := time.Now() |
| 433 | currentTimestamp := currentTime.Unix() |
| 434 | |
| 435 | // 获取当前时间的分钟级时间戳(用于分钟级限制) |
| 436 | currentMinute := currentTime.Truncate(time.Minute).Unix() |
| 437 | |
| 438 | // 获取当天开始的时间戳(用于日级限制) |
| 439 | currentDay := time.Date(currentTime.Year(), currentTime.Month(), currentTime.Day(), 0, 0, 0, 0, currentTime.Location()).Unix() |
| 440 | |
| 441 | // 检查是否需要重置计数器 |
| 442 | needUpdate := false |
| 443 | originalToken := *token // 保存原始状态 |
| 444 | |
| 445 | // 检查分钟级限制 |
| 446 | if token.RateLimitPerMinute > 0 { |
| 447 | // 如果上次重置时间不在当前分钟内,重置分钟计数器 |
| 448 | if token.LastRateLimitReset < currentMinute { |
| 449 | token.LastRateLimitReset = currentTimestamp |
| 450 | needUpdate = true |
| 451 | } |
| 452 | |
| 453 | // 计算当前分钟内的使用次数 |
| 454 | var minuteCount int64 |
| 455 | err := DB.Model(&TokenUsageLog{}).Where("token_id = ? AND created_at >= ?", token.Id, currentMinute).Count(&minuteCount).Error |
| 456 | if err != nil { |
| 457 | common.SysError("检查分钟级使用次数失败: " + err.Error()) |
| 458 | return errors.New("系统错误,请稍后再试") |
| 459 | } |
| 460 | |
| 461 | if int(minuteCount) >= token.RateLimitPerMinute { |
| 462 | return errors.New("超出分钟限制,请稍后再试") |
| 463 | } |
| 464 | } |
| 465 | |
| 466 | // 检查日级限制 |
| 467 | if token.RateLimitPerDay > 0 { |
| 468 | // 计算当天内的使用次数 |
| 469 | var dayCount int64 |
| 470 | err := DB.Model(&TokenUsageLog{}).Where("token_id = ? AND created_at >= ?", token.Id, currentDay).Count(&dayCount).Error |
| 471 | if err != nil { |
| 472 | common.SysError("检查日级使用次数失败: " + err.Error()) |
| 473 | return errors.New("系统错误,请稍后再试") |
| 474 | } |
| 475 | |
| 476 | if int(dayCount) >= token.RateLimitPerDay { |
| 477 | return errors.New("超出日限制,请稍后再试") |
| 478 | } |
| 479 | } |
no test coverage detected