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) }