feat: 限制用户单日提问次数

This commit is contained in:
Blizzard
2026-04-24 17:07:52 +08:00
parent e9c93d4029
commit 3aae619af5
6 changed files with 56 additions and 4 deletions
+42 -3
View File
@@ -1,6 +1,7 @@
package plant
import (
"fmt"
"sundynix-go/global"
"sundynix-go/model/commom/response"
"sundynix-go/utils/auth"
@@ -24,7 +25,19 @@ func (a *AiChatApi) ChatStreamPlant(c *gin.Context) {
return
}
// SSE Headers(微信小程序通过 enableChunked: true 配合实现打字机效果)
userId := auth.GetUserId(c)
// ── 每日用量检查 ──
cfg, cfgErr := sysAiConfigService.GetActiveAiConfig()
if cfgErr == nil && cfg.DailyQueryLimit > 0 {
todayCount, _ := chatHistoryService.GetTodayCount(userId)
if todayCount >= int64(cfg.DailyQueryLimit) {
response.FailWithMsg(fmt.Sprintf("今日问答次数已达上限(%d次),明天再来吧", cfg.DailyQueryLimit), c)
return
}
}
// SSE Headers
w := c.Writer
header := w.Header()
header.Set("Content-Type", "text/event-stream")
@@ -46,14 +59,12 @@ func (a *AiChatApi) ChatStreamPlant(c *gin.Context) {
_, _ = w.WriteString("data: [ERROR]" + err.Error() + "\n\n")
w.Flush()
} else {
// 流结束标志
_, _ = w.WriteString("data: [DONE]\n\n")
w.Flush()
}
// 异步保存问答历史
if fullAnswer != "" {
userId := auth.GetUserId(c)
go func() {
if saveErr := chatHistoryService.SaveHistory(userId, query, fullAnswer); saveErr != nil {
global.Logger.Error("Save chat history failed", zap.Error(saveErr))
@@ -138,6 +149,34 @@ func (a *AiChatApi) ClearChatHistory(c *gin.Context) {
response.OkWithMsg("已清空", c)
}
// GetChatQuota 获取当前用户今日剩余问答额度
// @Tags Plant-AiChat
// @Router /plant/chat/quota [get]
func (a *AiChatApi) GetChatQuota(c *gin.Context) {
userId := auth.GetUserId(c)
todayCount, _ := chatHistoryService.GetTodayCount(userId)
limit := 0 // 0 = unlimited
cfg, err := sysAiConfigService.GetActiveAiConfig()
if err == nil && cfg.DailyQueryLimit > 0 {
limit = cfg.DailyQueryLimit
}
remaining := -1 // -1 means unlimited
if limit > 0 {
remaining = limit - int(todayCount)
if remaining < 0 {
remaining = 0
}
}
response.OkWithData(map[string]interface{}{
"used": todayCount,
"limit": limit,
"remaining": remaining,
}, c)
}
func parseInt(s string) int {
n := 0
for _, c := range s {
+1
View File
@@ -31,4 +31,5 @@ var (
exchangeService = service.GroupApp.PlantServiceGroup.ExchangeService
aiRagService = service.GroupApp.PlantServiceGroup.AiRagService
chatHistoryService = service.GroupApp.PlantServiceGroup.AiChatHistoryService
sysAiConfigService = service.GroupApp.SystemServiceGroup.SysAiConfigService
)