You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
5.8 KiB
192 lines
5.8 KiB
package red_envelope_service
|
|
|
|
import (
|
|
"errors"
|
|
"github.com/ouxuanserver/osmanthuswine/src/core"
|
|
"hudongzhuanjia/models"
|
|
"hudongzhuanjia/utils"
|
|
"hudongzhuanjia/utils/define"
|
|
"math/rand"
|
|
"time"
|
|
)
|
|
|
|
func GetCurrentRB(aid, uid, rid int64) (map[string]interface{}, error) {
|
|
// 信息 一轮只能有一个
|
|
rule := new(models.ShakeRedEnvelopeRule)
|
|
exist, err := rule.GetCurrent(aid)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if exist {
|
|
|
|
shakeUser := new(models.ShakeRedEnvelopeUser)
|
|
shakeUser.UserId = uid
|
|
shakeUser.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId
|
|
shakeUser.ShakeRedEnvelopeRuleId = rule.Id
|
|
shakeUser.RehearsalId = rid
|
|
shakeUser.CreatedAt = time.Now()
|
|
shakeUser.UpdateAt = time.Now()
|
|
shakeUser.IsDelete = 0
|
|
err := models.Save(map[string]interface{}{
|
|
"user_id=": uid,
|
|
"shake_red_envelope_activity_id=": rule.ShakeRedEnvelopeActivityId,
|
|
"shake_red_envelope_rule_id=": rule.Id,
|
|
"rehearsal_id=": rid,
|
|
}, shakeUser)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return map[string]interface{}{
|
|
"rule": rule,
|
|
}, nil
|
|
}
|
|
return nil, errors.New("尚未开启轮次")
|
|
// 记录一下参与人数
|
|
}
|
|
|
|
const (
|
|
MinRedPackAmount = 1
|
|
MaxRedPackAmount = 499
|
|
)
|
|
|
|
func GenRedPack(amount, num int) []int {
|
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
sumMoney := 0
|
|
redPacks := make([]int, num)
|
|
for i := 0; i < num; i++ {
|
|
money := r.Int()*2*(amount-sumMoney)/num - i
|
|
if money <= MinRedPackAmount {
|
|
money = MinRedPackAmount
|
|
} else if money >= MaxRedPackAmount {
|
|
money = MaxRedPackAmount
|
|
}
|
|
|
|
// 剩余红包的限制
|
|
rate := (amount - sumMoney - money) / (num - i)
|
|
if rate <= MinRedPackAmount {
|
|
money = MinRedPackAmount
|
|
} else if rate >= MaxRedPackAmount {
|
|
money = MaxRedPackAmount
|
|
}
|
|
|
|
if num-i == 1 { // 最后一个
|
|
money = amount - sumMoney
|
|
}
|
|
sumMoney += money
|
|
redPacks = append(redPacks, money)
|
|
}
|
|
return redPacks
|
|
}
|
|
|
|
// 提前生成红包
|
|
func GenRedEnvelope(aid, rid int64, rule *models.ShakeRedEnvelopeRule) error {
|
|
// 判断红包是否存在
|
|
// 根据算法提前生成红包
|
|
|
|
// 删除掉之前存在对的
|
|
_, err := core.GetXormAuto().Where("is_delete=0 and shake_red_envelope_rule_id=? "+
|
|
" and shake_red_envelope_activity_id=? and activity_id=? and rehearsal_id=?",
|
|
rule.Id, rule.ShakeRedEnvelopeActivityId, aid, rid).Cols("is_delete").
|
|
Update(&models.ShakeRedEnvelopeRecord{IsDelete: true})
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
r := rand.New(rand.NewSource(time.Now().UnixNano()))
|
|
if rule.Model == define.SHAKERB_RULE_RANDOM { // 随机红包
|
|
//redPacks := GenRedPack(int(rule.RandSum*100), int(rule.RedEnvelopeNum))
|
|
//for _, redpack := range redPacks {
|
|
// record := new(models.ShakeRedEnvelopeRecord)
|
|
// record.ActivityId = aid
|
|
// record.RehearsalId = rid
|
|
// record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId
|
|
// record.ShakeRedEnvelopeRuleId = rule.Id
|
|
// record.Amount = float64(redpack) / 100
|
|
// record.IsDraw = -1
|
|
// record.IsDelete = false
|
|
// record.CreatedAt = time.Now()
|
|
// record.UpdatedAt = time.Now()
|
|
// if _, err := core.GetXormAuto().InsertOne(record); err != nil {
|
|
// return err
|
|
// }
|
|
//}
|
|
|
|
// 检测红包是否存在
|
|
sumMoney := 0.0
|
|
for i := 0; i < int(rule.RedEnvelopeNum); i++ {
|
|
money := r.Float64() * 2 * (rule.RandSum - sumMoney) / float64(int(rule.RedEnvelopeNum)-i)
|
|
amount := utils.Float64CusDecimal(money, 2)
|
|
if amount <= MinRedPackAmount { // 随机的金额可能小于1块钱
|
|
amount = MinRedPackAmount
|
|
} else if amount >= MaxRedPackAmount {
|
|
amount = MaxRedPackAmount
|
|
}
|
|
// 提前预判剩余红包和红包的金额比例 ==> money/num <= 0.01
|
|
rate := (rule.RandSum - sumMoney - amount) / float64(int(rule.RedEnvelopeNum)-i)
|
|
if rate <= MinRedPackAmount {
|
|
amount = MinRedPackAmount
|
|
} else if rate >= MaxRedPackAmount {
|
|
amount = MaxRedPackAmount
|
|
}
|
|
|
|
if int(rule.RedEnvelopeNum)-i == 1 {
|
|
amount = rule.RandSum - sumMoney
|
|
}
|
|
record := new(models.ShakeRedEnvelopeRecord)
|
|
record.ActivityId = aid
|
|
record.RehearsalId = rid
|
|
record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId
|
|
record.ShakeRedEnvelopeRuleId = rule.Id
|
|
record.Amount = amount
|
|
record.IsDraw = -1
|
|
record.IsDelete = false
|
|
record.CreatedAt = time.Now()
|
|
record.UpdatedAt = time.Now()
|
|
|
|
if _, err := core.GetXormAuto().InsertOne(record); err != nil {
|
|
return err
|
|
}
|
|
sumMoney += record.Amount
|
|
}
|
|
} else if rule.Model == define.SHAKERB_RULE_COMMON { // 普通红包
|
|
for i := 0; i < int(rule.RedEnvelopeNum); i++ {
|
|
record := new(models.ShakeRedEnvelopeRecord)
|
|
record.ActivityId = aid
|
|
record.RehearsalId = rid
|
|
record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId
|
|
record.ShakeRedEnvelopeRuleId = rule.Id
|
|
record.Amount = rule.Single
|
|
record.IsDraw = -1
|
|
record.IsDelete = false
|
|
record.CreatedAt = time.Now()
|
|
record.UpdatedAt = time.Now()
|
|
if _, err := core.GetXormAuto().InsertOne(record); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
} else if rule.Model == define.SHAKERB_RULE_LADDER { // 阶梯红包
|
|
ladders := make([]*models.ShakeRedEnvelopeRuleLadder, 0)
|
|
err := core.GetXormAuto().Where("is_delete=0 and shake_red_envelope_rule_id=?", rule.Id).
|
|
Desc("created_at").Find(&ladders)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
for _, ladder := range ladders {
|
|
for i := 0; i < int(ladder.RedEnvelopeNum); i++ {
|
|
record := new(models.ShakeRedEnvelopeRecord)
|
|
record.ActivityId = aid
|
|
record.RehearsalId = rid
|
|
record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId
|
|
record.ShakeRedEnvelopeRuleId = rule.Id
|
|
record.Amount = ladder.Single
|
|
record.IsDraw = -1
|
|
record.CreatedAt = time.Now()
|
|
record.UpdatedAt = time.Now()
|
|
if _, err := core.GetXormAuto().InsertOne(record); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|