feat: 支付闭环
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
package radio
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sundynix-go/model/radio"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type OrderService struct{}
|
||||
|
||||
var OrderServiceApp = new(OrderService)
|
||||
|
||||
// ExecuteOrderUnlock 核心原子操作:解锁权限
|
||||
func (s *OrderService) ExecuteOrderUnlock(tx *gorm.DB, outTradeNo string) error {
|
||||
var order radio.Order
|
||||
// 1. 锁住订单行,防止回调和主动查询并发导致时长翻倍
|
||||
if err := tx.Set("gorm:query_option", "FOR UPDATE").
|
||||
Where("out_trade_no = ?", outTradeNo).First(&order).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 2. 幂等检查
|
||||
if order.Status == 1 {
|
||||
return nil // 已处理,直接返回
|
||||
}
|
||||
|
||||
// 3. 更新订单状态
|
||||
if err := tx.Model(&order).Updates(map[string]interface{}{
|
||||
"status": 1,
|
||||
"pay_status": "SUCCESS",
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 4. 根据订单中的 sub_type 决定增加几个月
|
||||
var months int
|
||||
switch order.SubscriptionType {
|
||||
case "1":
|
||||
months = 1 // 月
|
||||
case "2":
|
||||
months = 3 // 季
|
||||
case "3":
|
||||
months = 12 // 年
|
||||
}
|
||||
|
||||
// 5. 更新或创建订阅权限
|
||||
var sub radio.RadioSubscription
|
||||
now := time.Now()
|
||||
err := tx.Where("user_id = ? AND channel_id = ?", order.UserId, order.ChannelId).First(&sub).Error
|
||||
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
// 首次订阅
|
||||
return tx.Create(&radio.RadioSubscription{
|
||||
UserId: order.UserId,
|
||||
ChannelId: order.ChannelId,
|
||||
ExpiredAt: now.AddDate(0, months, 0),
|
||||
Status: 1,
|
||||
}).Error
|
||||
} else {
|
||||
// 续费逻辑
|
||||
newExpiredAt := sub.ExpiredAt
|
||||
if sub.ExpiredAt.Before(now) {
|
||||
newExpiredAt = now // 已过期,从现在开始往后加
|
||||
}
|
||||
return tx.Model(&sub).Updates(map[string]interface{}{
|
||||
"expired_at": newExpiredAt.AddDate(0, months, 0),
|
||||
"status": 1,
|
||||
}).Error
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user