Files
junhong_cmp_fiber/internal/task/commission_stats_update.go
huang 1cf17e8f14
All checks were successful
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Successful in 5m46s
清理冗余的梯度返佣(TierCommission)配置
- 移除 Model 层:删除 ShopSeriesCommissionTier 模型及相关字段
- 更新 DTO:删除 TierCommissionConfig、TierEntry 类型及相关请求/响应字段
- 删除 Store 层:移除 ShopSeriesCommissionTierStore 及相关查询逻辑
- 简化 Service 层:删除梯度返佣处理逻辑,统计查询移除 tier_bonus 字段
- 数据库迁移:创建 000034_remove_tier_commission 移除相关表和字段
- 更新测试:移除梯度返佣相关测试用例,更新集成测试
- OpenAPI 文档:删除梯度返佣相关 schema 和枚举值
- 归档变更:归档 remove-tier-commission-redundancy 到 archive/2026-01-30-
- 同步规范:更新 4 个主 specs,标记废弃功能并添加迁移指引

原因:梯度返佣功能与一次性梯度佣金功能重复,且从未实现实际计算逻辑
迁移:使用一次性佣金的梯度模式 (OneTimeCommissionConfig.type = "tiered") 替代
2026-01-30 14:57:24 +08:00

96 lines
2.6 KiB
Go

package task
import (
"context"
"time"
"github.com/bytedance/sonic"
"github.com/hibiken/asynq"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
"github.com/break/junhong_cmp_fiber/internal/store/postgres"
"github.com/break/junhong_cmp_fiber/pkg/constants"
pkggorm "github.com/break/junhong_cmp_fiber/pkg/gorm"
)
type CommissionStatsUpdatePayload struct {
AllocationID uint `json:"allocation_id"`
SalesCount int64 `json:"sales_count"`
SalesAmount int64 `json:"sales_amount"`
}
type CommissionStatsUpdateHandler struct {
redis *redis.Client
statsStore *postgres.ShopSeriesCommissionStatsStore
allocationStore *postgres.ShopSeriesAllocationStore
logger *zap.Logger
}
func NewCommissionStatsUpdateHandler(
redis *redis.Client,
statsStore *postgres.ShopSeriesCommissionStatsStore,
allocationStore *postgres.ShopSeriesAllocationStore,
logger *zap.Logger,
) *CommissionStatsUpdateHandler {
return &CommissionStatsUpdateHandler{
redis: redis,
statsStore: statsStore,
allocationStore: allocationStore,
logger: logger,
}
}
func (h *CommissionStatsUpdateHandler) HandleCommissionStatsUpdate(ctx context.Context, task *asynq.Task) error {
ctx = pkggorm.SkipDataPermission(ctx)
var payload CommissionStatsUpdatePayload
if err := sonic.Unmarshal(task.Payload(), &payload); err != nil {
h.logger.Error("解析统计更新任务载荷失败",
zap.Error(err),
zap.String("task_id", task.ResultWriter().TaskID()),
)
return asynq.SkipRetry
}
now := time.Now()
period := getCurrentPeriod(now)
redisKey := constants.RedisCommissionStatsKey(payload.AllocationID, period)
pipe := h.redis.Pipeline()
pipe.HIncrBy(ctx, redisKey, "total_count", payload.SalesCount)
pipe.HIncrBy(ctx, redisKey, "total_amount", payload.SalesAmount)
periodEnd := getPeriodEnd(now)
expireAt := periodEnd.AddDate(0, 0, 7)
pipe.ExpireAt(ctx, redisKey, expireAt)
if _, err := pipe.Exec(ctx); err != nil {
h.logger.Error("更新 Redis 统计失败",
zap.Uint("allocation_id", payload.AllocationID),
zap.String("period", period),
zap.Error(err),
)
return err
}
h.logger.Info("统计更新成功",
zap.Uint("allocation_id", payload.AllocationID),
zap.String("period", period),
zap.Int64("sales_count", payload.SalesCount),
zap.Int64("sales_amount", payload.SalesAmount),
)
return nil
}
func getCurrentPeriod(t time.Time) string {
return t.Format("2006-01")
}
func getPeriodEnd(t time.Time) time.Time {
year, month, _ := t.Date()
nextMonth := time.Date(year, month+1, 1, 0, 0, 0, 0, t.Location())
return nextMonth.Add(-time.Second)
}