修复(#81): 修复永久订阅回归促销误判
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
@@ -12,6 +12,7 @@ import (
|
|||||||
"github.com/perfect-panel/server/pkg/xerr"
|
"github.com/perfect-panel/server/pkg/xerr"
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/clause"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@@ -250,12 +251,7 @@ func (s *gormPromoEligibilitySource) UserCreatedAt(ctx context.Context, userID i
|
|||||||
|
|
||||||
func (s *gormPromoEligibilitySource) LastSubscribeExpireAt(ctx context.Context, userID int64) (time.Time, error) {
|
func (s *gormPromoEligibilitySource) LastSubscribeExpireAt(ctx context.Context, userID int64) (time.Time, error) {
|
||||||
var item user.Subscribe
|
var item user.Subscribe
|
||||||
err := s.db.WithContext(ctx).
|
err := lastSubscribeExpireQuery(s.db.WithContext(ctx), userID).
|
||||||
Model(&user.Subscribe{}).
|
|
||||||
Where("user_id = ?", userID).
|
|
||||||
Where("expire_time != ?", time.UnixMilli(0)).
|
|
||||||
Order("expire_time DESC").
|
|
||||||
Limit(1).
|
|
||||||
Take(&item).Error
|
Take(&item).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if stderrors.Is(err, gorm.ErrRecordNotFound) {
|
if stderrors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
@@ -266,6 +262,17 @@ func (s *gormPromoEligibilitySource) LastSubscribeExpireAt(ctx context.Context,
|
|||||||
return item.ExpireTime, nil
|
return item.ExpireTime, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func lastSubscribeExpireQuery(db *gorm.DB, userID int64) *gorm.DB {
|
||||||
|
return db.
|
||||||
|
Model(&user.Subscribe{}).
|
||||||
|
Where("user_id = ?", userID).
|
||||||
|
Order(clause.OrderBy{Expression: clause.Expr{
|
||||||
|
SQL: "CASE WHEN expire_time = ? THEN 0 ELSE 1 END ASC, expire_time DESC",
|
||||||
|
Vars: []interface{}{time.UnixMilli(0)},
|
||||||
|
}}).
|
||||||
|
Limit(1)
|
||||||
|
}
|
||||||
|
|
||||||
func loadEnabledPromoRules(ctx context.Context, svcCtx *svc.ServiceContext) ([]promoRule, error) {
|
func loadEnabledPromoRules(ctx context.Context, svcCtx *svc.ServiceContext) ([]promoRule, error) {
|
||||||
if cached, ok := getPromoCache[[]promoRule](ctx, svcCtx, promoRulesEnabledCacheKey); ok {
|
if cached, ok := getPromoCache[[]promoRule](ctx, svcCtx, promoRulesEnabledCacheKey); ok {
|
||||||
return cached, nil
|
return cached, nil
|
||||||
|
|||||||
@@ -2,8 +2,13 @@ package common
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"gorm.io/driver/mysql"
|
||||||
|
"gorm.io/gorm"
|
||||||
|
"gorm.io/gorm/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
type fakePromoEligibilitySource struct {
|
type fakePromoEligibilitySource struct {
|
||||||
@@ -148,3 +153,26 @@ func TestEvaluatePromoInactiveUser(t *testing.T) {
|
|||||||
t.Fatal("inactive promo should require positive inactive_months")
|
t.Fatal("inactive promo should require positive inactive_months")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestLastSubscribeExpireAtIncludesUnlimitedSubscription(t *testing.T) {
|
||||||
|
db, err := gorm.Open(mysql.New(mysql.Config{
|
||||||
|
DSN: "gorm:password@tcp(localhost:9910)/gorm?charset=utf8&parseTime=True&loc=Local",
|
||||||
|
SkipInitializeWithVersion: true,
|
||||||
|
}), &gorm.Config{
|
||||||
|
DryRun: true,
|
||||||
|
DisableAutomaticPing: true,
|
||||||
|
Logger: logger.Default.LogMode(logger.Silent),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("open gorm db: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt := lastSubscribeExpireQuery(db, 10).Take(nil).Statement
|
||||||
|
sql := strings.ToLower(stmt.SQL.String())
|
||||||
|
if strings.Contains(sql, "expire_time <>") || strings.Contains(sql, "expire_time !=") {
|
||||||
|
t.Fatalf("last subscribe query should include unlimited subscription, sql: %s", stmt.SQL.String())
|
||||||
|
}
|
||||||
|
if !strings.Contains(sql, "case when expire_time = ? then 0 else 1 end asc") {
|
||||||
|
t.Fatalf("last subscribe query should prioritize unlimited subscription, sql: %s", stmt.SQL.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user