|
|
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 = 100 // 1块钱
MaxRedPackAmount = 20000 // 200块钱
)
func GenRedPack(amount, num int) []int { sumMoney := 0 redPacks := make([]int, 0) maxMoney := MaxRedPackAmount r := rand.New(rand.NewSource(time.Now().UnixNano())) for i := 0; i < num; i++ { maxMoney = (amount - sumMoney) / (num - i) if maxMoney > MaxRedPackAmount { maxMoney = MaxRedPackAmount } money := r.Int() 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 int64, name string, rid int64, rule *models.ShakeRedEnvelopeRule) error { // 判断红包是否存在
// 根据算法提前生成红包
r := rand.New(rand.NewSource(time.Now().Unix())) if rule.Model == define.SHAKERB_RULE_RANDOM { // 随机红包
// 检测红包是否存在
randSum := int(rule.RandSum * 100) sumMoney := 0 maxMoney := MaxRedPackAmount if randSum/rule.RedEnvelopeNum <= MinRedPackAmount && randSum/rule.RedEnvelopeNum >= MaxRedPackAmount { return errors.New("每个红包的平均金额必须在1.00元到200.00元之间") } for i := 0; i < rule.RedEnvelopeNum; i++ { // 前置判断每次循环是否存在最小值
//最大可领金额 = 剩余金额的平均值x2 = (剩余金额 / 剩余数量) * 2
maxMoney = (randSum - sumMoney) / (rule.RedEnvelopeNum - i) if maxMoney > MaxRedPackAmount { maxMoney = MaxRedPackAmount } money := r.Intn(maxMoney) if money < MinRedPackAmount { // 随机的金额可能小于1块钱
money = MinRedPackAmount } else if money > MaxRedPackAmount { money = MaxRedPackAmount }
// 提前预判剩余红包和红包的金额比例 ==> money/num <= 0.01
rate := (randSum - sumMoney - money) / (rule.RedEnvelopeNum - i) if rate <= MinRedPackAmount { money = MinRedPackAmount } else if rate >= MaxRedPackAmount { money = MaxRedPackAmount }
if rule.RedEnvelopeNum-i == 1 { money = randSum - sumMoney } record := new(models.ShakeRedEnvelopeRecord) record.ActivityId = aid record.Name = name record.RehearsalId = rid record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId record.ShakeRedEnvelopeRuleId = rule.Id record.Amount = utils.Float64CusDecimal(float64(money)/float64(100), 2) record.IsDraw = -1
if _, err := models.Add(record); err != nil { return err } sumMoney += money } } else if rule.Model == define.SHAKERB_RULE_COMMON { // 普通红包
for i := 0; i < rule.RedEnvelopeNum; i++ { record := new(models.ShakeRedEnvelopeRecord) record.ActivityId = aid record.Name = name record.RehearsalId = rid record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId record.ShakeRedEnvelopeRuleId = rule.Id record.Amount = rule.Single record.IsDraw = -1 if _, err := models.Add(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.Name = name record.RehearsalId = rid record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId record.ShakeRedEnvelopeRuleId = rule.Id record.Amount = ladder.Single record.IsDraw = -1 if _, err := models.Add(record); err != nil { return err } } } } return nil }
|