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