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 }