82 lines
2.1 KiB
Go
82 lines
2.1 KiB
Go
package radio
|
|
|
|
import (
|
|
"errors"
|
|
"sundynix-go/model/radio"
|
|
"sundynix-go/model/system"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type OrderService struct{}
|
|
|
|
var OrderServiceApp = new(OrderService)
|
|
|
|
// ExecuteOrderUnlock 订阅/开通vip 核心原子操作:解锁权限
|
|
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
|
|
}
|
|
if order.Type == 2 {
|
|
//4.开通vip 过期时间为2099 年
|
|
return tx.Model(&system.User{}).Where("id = ?", order.UserId).Updates(map[string]interface{}{
|
|
"is_vip": 1,
|
|
"vip_expire_at": time.Date(2099, 12, 31, 23, 59, 59, 999, time.Local),
|
|
}).Error
|
|
} else if order.Type == 1 {
|
|
// 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
|
|
}
|
|
}
|
|
return nil
|
|
}
|