修复(#85): 修复促销审查反馈问题

Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
2026-05-27 02:05:38 -07:00
parent ae64cc635d
commit c5ce89b4f4
6 changed files with 75 additions and 13 deletions
+1 -2
View File
@@ -4324,8 +4324,7 @@
"title": "SubscribeDiscount", "title": "SubscribeDiscount",
"required": [ "required": [
"quantity", "quantity",
"discount", "discount"
"promo"
] ]
}, },
"SubscribeGroup": { "SubscribeGroup": {
@@ -11,10 +11,63 @@ CREATE TABLE IF NOT EXISTS `promo_rule` (
`updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `updated_at` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`deleted_at` DATETIME DEFAULT NULL COMMENT '软删除时间', `deleted_at` DATETIME DEFAULT NULL COMMENT '软删除时间',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `idx_enabled_priority` (`enabled`, `priority` DESC), KEY `idx_enabled_priority_deleted` (`enabled`, `deleted_at`, `priority` DESC)
KEY `idx_deleted_at` (`deleted_at`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='促销规则表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='促销规则表';
SET @index_exists = (
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'promo_rule'
AND INDEX_NAME = 'idx_enabled_priority'
);
SET @sql = IF(
@index_exists = 1,
'ALTER TABLE `promo_rule` DROP INDEX `idx_enabled_priority`',
'SELECT ''Index idx_enabled_priority does not exist on promo_rule table'''
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'promo_rule'
AND INDEX_NAME = 'idx_deleted_at'
);
SET @sql = IF(
@index_exists = 1,
'ALTER TABLE `promo_rule` DROP INDEX `idx_deleted_at`',
'SELECT ''Index idx_deleted_at does not exist on promo_rule table'''
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @index_exists = (
SELECT COUNT(*)
FROM INFORMATION_SCHEMA.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'promo_rule'
AND INDEX_NAME = 'idx_enabled_priority_deleted'
);
SET @sql = IF(
@index_exists = 0,
'ALTER TABLE `promo_rule` ADD KEY `idx_enabled_priority_deleted` (`enabled`, `deleted_at`, `priority` DESC)',
'SELECT ''Index idx_enabled_priority_deleted already exists on promo_rule table'''
);
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
CREATE TABLE IF NOT EXISTS `subscribe_promo` ( CREATE TABLE IF NOT EXISTS `subscribe_promo` (
`id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
`subscribe_id` BIGINT UNSIGNED NOT NULL COMMENT '套餐规格 ID', `subscribe_id` BIGINT UNSIGNED NOT NULL COMMENT '套餐规格 ID',
@@ -47,6 +47,10 @@ func (l *PreCreateOrderLogic) PreCreateOrder(req *types.PurchaseOrderRequest) (r
l.Debugf("[PreCreateOrder] Quantity is less than or equal to 0, setting to 1") l.Debugf("[PreCreateOrder] Quantity is less than or equal to 0, setting to 1")
req.Quantity = 1 req.Quantity = 1
} }
entitlement, entErr := commonLogic.ResolveEntitlementUser(l.ctx, l.svcCtx.DB, u.Id)
if entErr != nil {
return nil, entErr
}
targetSubscribeID := req.SubscribeId targetSubscribeID := req.SubscribeId
orderType := uint8(1) orderType := uint8(1)
@@ -54,7 +58,7 @@ func (l *PreCreateOrderLogic) PreCreateOrder(req *types.PurchaseOrderRequest) (r
decision, routeErr := commonLogic.ResolvePurchaseRoute( decision, routeErr := commonLogic.ResolvePurchaseRoute(
l.ctx, l.ctx,
l.svcCtx.Config.Subscribe.SingleModel, l.svcCtx.Config.Subscribe.SingleModel,
u.Id, entitlement.EffectiveUserID,
req.SubscribeId, req.SubscribeId,
l.svcCtx.UserModel.FindSingleModeAnchorSubscribe, l.svcCtx.UserModel.FindSingleModeAnchorSubscribe,
) )
@@ -75,6 +79,7 @@ func (l *PreCreateOrderLogic) PreCreateOrder(req *types.PurchaseOrderRequest) (r
logger.Field("route", "purchase_to_renewal"), logger.Field("route", "purchase_to_renewal"),
logger.Field("anchor_user_subscribe_id", decision.Anchor.Id), logger.Field("anchor_user_subscribe_id", decision.Anchor.Id),
logger.Field("user_id", u.Id), logger.Field("user_id", u.Id),
logger.Field("effective_user_id", entitlement.EffectiveUserID),
) )
} }
} }
@@ -85,7 +90,7 @@ func (l *PreCreateOrderLogic) PreCreateOrder(req *types.PurchaseOrderRequest) (r
var existSub user.Subscribe var existSub user.Subscribe
if e := l.svcCtx.DB.WithContext(l.ctx). if e := l.svcCtx.DB.WithContext(l.ctx).
Model(&user.Subscribe{}). Model(&user.Subscribe{}).
Where("user_id = ? AND token != '' AND (order_id > 0 OR token LIKE 'iap:%')", u.Id). Where("user_id = ? AND token != '' AND (order_id > 0 OR token LIKE 'iap:%')", entitlement.EffectiveUserID).
Order("expire_time DESC"). Order("expire_time DESC").
Order("updated_at DESC"). Order("updated_at DESC").
Order("id DESC"). Order("id DESC").
@@ -97,6 +102,7 @@ func (l *PreCreateOrderLogic) PreCreateOrder(req *types.PurchaseOrderRequest) (r
logger.Field("existing_subscribe_id", existSub.Id), logger.Field("existing_subscribe_id", existSub.Id),
logger.Field("existing_status", existSub.Status), logger.Field("existing_status", existSub.Status),
logger.Field("user_id", u.Id), logger.Field("user_id", u.Id),
logger.Field("effective_user_id", entitlement.EffectiveUserID),
logger.Field("resolved_subscribe_id", targetSubscribeID), logger.Field("resolved_subscribe_id", targetSubscribeID),
) )
} else if e != nil && !errors.Is(e, gorm.ErrRecordNotFound) { } else if e != nil && !errors.Is(e, gorm.ErrRecordNotFound) {
@@ -114,7 +120,7 @@ func (l *PreCreateOrderLogic) PreCreateOrder(req *types.PurchaseOrderRequest) (r
// check subscribe plan quota limit for new purchase flow only // check subscribe plan quota limit for new purchase flow only
if !isSingleModeRenewal && sub.Quota > 0 { if !isSingleModeRenewal && sub.Quota > 0 {
userSub, err := l.svcCtx.UserModel.QueryUserSubscribe(l.ctx, u.Id) userSub, err := l.svcCtx.UserModel.QueryUserSubscribe(l.ctx, entitlement.EffectiveUserID)
if err != nil { if err != nil {
l.Errorw("[PreCreateOrder] Database query error", logger.Field("error", err.Error()), logger.Field("user_id", u.Id)) l.Errorw("[PreCreateOrder] Database query error", logger.Field("error", err.Error()), logger.Field("user_id", u.Id))
return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find user subscription error: %v", err.Error()) return nil, errors.Wrapf(xerr.NewErrCode(xerr.DatabaseQueryError), "find user subscription error: %v", err.Error())
@@ -130,7 +136,7 @@ func (l *PreCreateOrderLogic) PreCreateOrder(req *types.PurchaseOrderRequest) (r
} }
} }
newUserDiscount, err := resolveNewUserDiscountEligibility(l.ctx, l.svcCtx.DB, u.Id, targetSubscribeID, req.Quantity, sub.Discount) newUserDiscount, err := resolveNewUserDiscountEligibility(l.ctx, l.svcCtx.DB, entitlement.EffectiveUserID, targetSubscribeID, req.Quantity, sub.Discount)
if err != nil { if err != nil {
l.Errorw("[PreCreateOrder] Database query error resolving new user eligibility", l.Errorw("[PreCreateOrder] Database query error resolving new user eligibility",
logger.Field("error", err.Error()), logger.Field("error", err.Error()),
@@ -145,7 +151,7 @@ func (l *PreCreateOrderLogic) PreCreateOrder(req *types.PurchaseOrderRequest) (r
priceResult, err := calculatePurchasePrice( priceResult, err := calculatePurchasePrice(
l.ctx, l.ctx,
l.svcCtx, l.svcCtx,
u.Id, entitlement.EffectiveUserID,
targetSubscribeID, targetSubscribeID,
sub.UnitPrice, sub.UnitPrice,
req.Quantity, req.Quantity,
+1 -2
View File
@@ -3688,8 +3688,7 @@
"title": "SubscribeDiscount", "title": "SubscribeDiscount",
"required": [ "required": [
"quantity", "quantity",
"discount", "discount"
"promo"
] ]
}, },
"SubscribeGroup": { "SubscribeGroup": {
+6
View File
@@ -150,6 +150,12 @@ func (l *ActivateOrderLogic) ProcessTask(ctx context.Context, task *asynq.Task)
} }
if err = l.recordPromoUsage(ctx, orderInfo); err != nil { if err = l.recordPromoUsage(ctx, orderInfo); err != nil {
if releaseErr := l.releaseClaim(ctx, orderInfo.OrderNo); releaseErr != nil {
logger.WithContext(ctx).Error("[ActivateOrderLogic] releaseClaim also failed, stuck recovery will handle",
logger.Field("order_no", orderInfo.OrderNo),
logger.Field("release_error", releaseErr.Error()),
)
}
logger.WithContext(ctx).Error("[ActivateOrderLogic] 促销使用记录写入失败,将重试", logger.WithContext(ctx).Error("[ActivateOrderLogic] 促销使用记录写入失败,将重试",
logger.Field("order_no", orderInfo.OrderNo), logger.Field("order_no", orderInfo.OrderNo),
logger.Field("promo_rule_id", orderInfo.PromoRuleId), logger.Field("promo_rule_id", orderInfo.PromoRuleId),
+1 -2
View File
@@ -5908,8 +5908,7 @@
"title": "SubscribeDiscount", "title": "SubscribeDiscount",
"required": [ "required": [
"quantity", "quantity",
"discount", "discount"
"promo"
] ]
}, },
"SubscribeGroup": { "SubscribeGroup": {