(key string, userId int)
| 111 | } |
| 112 | |
| 113 | func Redeem(key string, userId int) (quota int, err error) { |
| 114 | if key == "" { |
| 115 | return 0, errors.New("未提供兑换码") |
| 116 | } |
| 117 | if userId == 0 { |
| 118 | return 0, errors.New("无效的 user id") |
| 119 | } |
| 120 | redemption := &Redemption{} |
| 121 | |
| 122 | keyCol := "`key`" |
| 123 | if common.UsingPostgreSQL { |
| 124 | keyCol = `"key"` |
| 125 | } |
| 126 | common.RandomSleep() |
| 127 | err = DB.Transaction(func(tx *gorm.DB) error { |
| 128 | err := tx.Set("gorm:query_option", "FOR UPDATE").Where(keyCol+" = ?", key).First(redemption).Error |
| 129 | if err != nil { |
| 130 | return errors.New("无效的兑换码") |
| 131 | } |
| 132 | if redemption.Status != common.RedemptionCodeStatusEnabled { |
| 133 | return errors.New("该兑换码已被使用") |
| 134 | } |
| 135 | if redemption.ExpiredTime != 0 && redemption.ExpiredTime < common.GetTimestamp() { |
| 136 | return errors.New("该兑换码已过期") |
| 137 | } |
| 138 | err = tx.Model(&User{}).Where("id = ?", userId).Update("quota", gorm.Expr("quota + ?", redemption.Quota)).Error |
| 139 | if err != nil { |
| 140 | return err |
| 141 | } |
| 142 | redemption.RedeemedTime = common.GetTimestamp() |
| 143 | redemption.Status = common.RedemptionCodeStatusUsed |
| 144 | redemption.UsedUserId = userId |
| 145 | err = tx.Save(redemption).Error |
| 146 | return err |
| 147 | }) |
| 148 | if err != nil { |
| 149 | return 0, errors.New("兑换失败," + err.Error()) |
| 150 | } |
| 151 | RecordLog(userId, LogTypeTopup, fmt.Sprintf("通过兑换码充值 %s,兑换码ID %d", common.LogQuota(redemption.Quota), redemption.Id)) |
| 152 | return redemption.Quota, nil |
| 153 | } |
| 154 | |
| 155 | func (redemption *Redemption) Insert() error { |
| 156 | var err error |
no test coverage detected