Files
sundynix-radio-be/service/radio/order_service.go
T
2026-03-04 17:05:48 +08:00

73 lines
1.7 KiB
Go

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