From 5196472d7e85954253e320b2a3fb6ace7d78f544 Mon Sep 17 00:00:00 2001 From: huang Date: Mon, 13 Apr 2026 14:50:14 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E6=89=8B=E5=8A=A8?= =?UTF-8?q?=E8=A7=A6=E5=8F=91=E5=8E=BB=E9=87=8DTTL=E5=92=8C=E6=97=A5?= =?UTF-8?q?=E9=99=90=E5=88=B6=E6=AC=A1=E6=95=B0=EF=BC=8C=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E6=9D=83=E9=99=90=E6=A3=80=E6=9F=A5=E5=92=8C=E9=94=99=E8=AF=AF?= =?UTF-8?q?=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/polling/manual_trigger_service.go | 84 +++++++++++-------- pkg/constants/redis.go | 2 +- 2 files changed, 48 insertions(+), 38 deletions(-) diff --git a/internal/service/polling/manual_trigger_service.go b/internal/service/polling/manual_trigger_service.go index 93b4bfd..c0d6ec5 100644 --- a/internal/service/polling/manual_trigger_service.go +++ b/internal/service/polling/manual_trigger_service.go @@ -53,9 +53,13 @@ func (s *ManualTriggerService) TriggerSingle(ctx context.Context, cardID uint, t // 检查每日触发限制 todayCount, err := s.logStore.CountTodayTriggers(ctx, triggeredBy) if err != nil { + s.logger.Error("查询今日触发次数失败", + zap.Uint("triggered_by", triggeredBy), + zap.String("task_type", taskType), + zap.Error(err)) return err } - if todayCount >= 100 { // 每日最多触发100次 + if todayCount >= 500 { // 每日最多触发500次 return errors.New(errors.CodeInvalidParam, "已达到每日触发次数上限") } @@ -63,13 +67,17 @@ func (s *ManualTriggerService) TriggerSingle(ctx context.Context, cardID uint, t dedupeKey := constants.RedisPollingManualDedupeKey(taskType) added, err := s.redis.SAdd(ctx, dedupeKey, cardID).Result() if err != nil { + s.logger.Error("Redis去重操作失败", + zap.Uint("card_id", cardID), + zap.String("task_type", taskType), + zap.Error(err)) return err } if added == 0 { return errors.New(errors.CodeInvalidParam, "该卡已在手动触发队列中") } - // 设置去重 key 过期时间(1小时) - s.redis.Expire(ctx, dedupeKey, time.Hour) + // 设置去重 key 过期时间(24小时,与日限制周期对齐) + s.redis.Expire(ctx, dedupeKey, 24*time.Hour) // 创建触发日志 cardIDsJSON, _ := json.Marshal([]uint{cardID}) @@ -83,12 +91,20 @@ func (s *ManualTriggerService) TriggerSingle(ctx context.Context, cardID uint, t TriggeredAt: time.Now(), } if err := s.logStore.Create(ctx, triggerLog); err != nil { + s.logger.Error("创建触发日志失败", + zap.Uint("card_id", cardID), + zap.Uint("triggered_by", triggeredBy), + zap.Error(err)) return err } // 加入手动触发队列(使用 List,优先级高于定时轮询) queueKey := constants.RedisPollingManualQueueKey(taskType) if err := s.redis.LPush(ctx, queueKey, cardID).Err(); err != nil { + s.logger.Error("写入手动触发队列失败", + zap.Uint("card_id", cardID), + zap.String("task_type", taskType), + zap.Error(err)) return err } @@ -126,7 +142,7 @@ func (s *ManualTriggerService) TriggerBatch(ctx context.Context, cardIDs []uint, if err != nil { return nil, err } - if todayCount >= 100 { + if todayCount >= 500 { // 每日最多触发500次 return nil, errors.New(errors.CodeInvalidParam, "已达到每日触发次数上限") } @@ -188,8 +204,8 @@ func (s *ManualTriggerService) processBatchTrigger(ctx context.Context, logID ui } } - // 设置去重 key 过期时间 - s.redis.Expire(ctx, dedupeKey, time.Hour) + // 设置去重 key 过期时间(24小时,与日限制周期对齐) + s.redis.Expire(ctx, dedupeKey, 24*time.Hour) // 更新最终状态 _ = s.logStore.UpdateProgress(ctx, logID, processedCount, successCount, failedCount) @@ -235,7 +251,7 @@ func (s *ManualTriggerService) TriggerByCondition(ctx context.Context, filter *C if err != nil { return nil, err } - if todayCount >= 100 { + if todayCount >= 500 { // 每日最多触发500次 return nil, errors.New(errors.CodeInvalidParam, "已达到每日触发次数上限") } @@ -357,18 +373,26 @@ func isValidTaskType(taskType string) bool { } } +// checkUserTypePermission 检查用户类型是否有手动触发权限 +// 返回 skip=true 表示超级管理员/平台用户直接放行 +// 返回 err!=nil 表示企业账号无权限 +// 返回 skip=false, err=nil 表示代理账号需继续细粒度检查 +func (s *ManualTriggerService) checkUserTypePermission(ctx context.Context) (skip bool, err error) { + userType := middleware.GetUserTypeFromContext(ctx) + if userType == constants.UserTypeSuperAdmin || userType == constants.UserTypePlatform { + return true, nil + } + if userType == constants.UserTypeEnterprise { + return false, errors.New(errors.CodeForbidden, "企业账号无权限手动触发轮询") + } + return false, nil +} + // canManageCard 检查用户是否有权管理单张卡 func (s *ManualTriggerService) canManageCard(ctx context.Context, cardID uint) error { - userType := middleware.GetUserTypeFromContext(ctx) - - // 超级管理员和平台用户跳过权限检查 - if userType == constants.UserTypeSuperAdmin || userType == constants.UserTypePlatform { - return nil - } - - // 企业账号禁止手动触发 - if userType == constants.UserTypeEnterprise { - return errors.New(errors.CodeForbidden, "企业账号无权限手动触发轮询") + skip, err := s.checkUserTypePermission(ctx) + if err != nil || skip { + return err } // 代理账号只能管理自己店铺及下级店铺的卡 @@ -388,16 +412,9 @@ func (s *ManualTriggerService) canManageCard(ctx context.Context, cardID uint) e // canManageCards 检查用户是否有权管理多张卡 func (s *ManualTriggerService) canManageCards(ctx context.Context, cardIDs []uint) error { - userType := middleware.GetUserTypeFromContext(ctx) - - // 超级管理员和平台用户跳过权限检查 - if userType == constants.UserTypeSuperAdmin || userType == constants.UserTypePlatform { - return nil - } - - // 企业账号禁止手动触发 - if userType == constants.UserTypeEnterprise { - return errors.New(errors.CodeForbidden, "企业账号无权限手动触发轮询") + skip, err := s.checkUserTypePermission(ctx) + if err != nil || skip { + return err } // 从 Context 获取预计算的下级店铺 ID 列表 @@ -434,16 +451,9 @@ func (s *ManualTriggerService) canManageCards(ctx context.Context, cardIDs []uin // applyShopPermissionFilter 应用店铺权限过滤(代理只能筛选自己管理的卡) func (s *ManualTriggerService) applyShopPermissionFilter(ctx context.Context, filter *ConditionFilter) error { - userType := middleware.GetUserTypeFromContext(ctx) - - // 超级管理员和平台用户不需要限制 - if userType == constants.UserTypeSuperAdmin || userType == constants.UserTypePlatform { - return nil - } - - // 企业账号禁止手动触发 - if userType == constants.UserTypeEnterprise { - return errors.New(errors.CodeForbidden, "企业账号无权限手动触发轮询") + skip, err := s.checkUserTypePermission(ctx) + if err != nil || skip { + return err } // 代理账号:限制只能查询自己店铺及下级店铺的卡 diff --git a/pkg/constants/redis.go b/pkg/constants/redis.go index 6115535..2367edc 100644 --- a/pkg/constants/redis.go +++ b/pkg/constants/redis.go @@ -270,7 +270,7 @@ func RedisPollingManualQueueKey(taskType string) string { // RedisPollingManualDedupeKey 生成手动触发去重的 Redis 键 // 用途:Set 存储已加入手动触发队列的卡 ID(用于去重) -// 过期时间:1小时 +// 过期时间:24小时(与日限制周期对齐) func RedisPollingManualDedupeKey(taskType string) string { return fmt.Sprintf("polling:manual:dedupe:%s", taskType) }