互动
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.

176 lines
5.2 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. package red_envelope_service
  2. import (
  3. "errors"
  4. "github.com/ouxuanserver/osmanthuswine/src/core"
  5. "hudongzhuanjia/models"
  6. "hudongzhuanjia/utils"
  7. "hudongzhuanjia/utils/define"
  8. "math/rand"
  9. "time"
  10. )
  11. func GetCurrentRB(aid, uid, rid int64) (map[string]interface{}, error) {
  12. // 信息 一轮只能有一个
  13. rule := new(models.ShakeRedEnvelopeRule)
  14. exist, err := rule.GetCurrent(aid)
  15. if err != nil {
  16. return nil, err
  17. }
  18. if exist {
  19. shakeUser := new(models.ShakeRedEnvelopeUser)
  20. shakeUser.UserId = uid
  21. shakeUser.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId
  22. shakeUser.ShakeRedEnvelopeRuleId = rule.Id
  23. shakeUser.RehearsalId = rid
  24. shakeUser.CreatedAt = time.Now()
  25. shakeUser.UpdateAt = time.Now()
  26. shakeUser.IsDelete = 0
  27. err := models.Save(map[string]interface{}{
  28. "user_id=": uid,
  29. "shake_red_envelope_activity_id=": rule.ShakeRedEnvelopeActivityId,
  30. "shake_red_envelope_rule_id=": rule.Id,
  31. "rehearsal_id=": rid,
  32. }, shakeUser)
  33. if err != nil {
  34. return nil, err
  35. }
  36. return map[string]interface{}{
  37. "rule": rule,
  38. }, nil
  39. }
  40. return nil, errors.New("尚未开启轮次")
  41. // 记录一下参与人数
  42. }
  43. const (
  44. MinRedPackAmount = 100 // 1块钱
  45. MaxRedPackAmount = 20000 // 200块钱
  46. )
  47. func GenRedPack(amount, num int) []int {
  48. sumMoney := 0
  49. redPacks := make([]int, 0)
  50. maxMoney := MaxRedPackAmount
  51. r := rand.New(rand.NewSource(time.Now().UnixNano()))
  52. for i := 0; i < num; i++ {
  53. maxMoney = (amount - sumMoney) / (num - i)
  54. if maxMoney > MaxRedPackAmount {
  55. maxMoney = MaxRedPackAmount
  56. }
  57. money := r.Int()
  58. if money < MinRedPackAmount {
  59. money = MinRedPackAmount
  60. } else if money > MaxRedPackAmount {
  61. money = MaxRedPackAmount
  62. }
  63. // 剩余红包的限制
  64. rate := (amount - sumMoney - money) / (num - i)
  65. if rate <= MinRedPackAmount {
  66. money = MinRedPackAmount
  67. } else if rate >= MaxRedPackAmount {
  68. money = MaxRedPackAmount
  69. }
  70. if num-i == 1 { // 最后一个
  71. money = amount - sumMoney
  72. }
  73. sumMoney += money
  74. redPacks = append(redPacks, money)
  75. }
  76. return redPacks
  77. }
  78. // 提前生成红包
  79. func GenRedEnvelope(aid int64, name string, rid int64, rule *models.ShakeRedEnvelopeRule) error {
  80. // 判断红包是否存在
  81. // 根据算法提前生成红包
  82. r := rand.New(rand.NewSource(time.Now().Unix()))
  83. if rule.Model == define.SHAKERB_RULE_RANDOM { // 随机红包
  84. // 检测红包是否存在
  85. randSum := int(rule.RandSum * 100)
  86. sumMoney := 0
  87. maxMoney := MaxRedPackAmount
  88. if randSum/rule.RedEnvelopeNum <= MinRedPackAmount && randSum/rule.RedEnvelopeNum >= MaxRedPackAmount {
  89. return errors.New("每个红包的平均金额必须在1.00元到200.00元之间")
  90. }
  91. for i := 0; i < rule.RedEnvelopeNum; i++ {
  92. // 前置判断每次循环是否存在最小值
  93. //最大可领金额 = 剩余金额的平均值x2 = (剩余金额 / 剩余数量) * 2
  94. maxMoney = (randSum - sumMoney) / (rule.RedEnvelopeNum - i)
  95. if maxMoney > MaxRedPackAmount {
  96. maxMoney = MaxRedPackAmount
  97. }
  98. money := r.Intn(maxMoney)
  99. if money < MinRedPackAmount { // 随机的金额可能小于1块钱
  100. money = MinRedPackAmount
  101. } else if money > MaxRedPackAmount {
  102. money = MaxRedPackAmount
  103. }
  104. // 提前预判剩余红包和红包的金额比例 ==> money/num <= 0.01
  105. rate := (randSum - sumMoney - money) / (rule.RedEnvelopeNum - i)
  106. if rate <= MinRedPackAmount {
  107. money = MinRedPackAmount
  108. } else if rate >= MaxRedPackAmount {
  109. money = MaxRedPackAmount
  110. }
  111. if rule.RedEnvelopeNum-i == 1 {
  112. money = randSum - sumMoney
  113. }
  114. record := new(models.ShakeRedEnvelopeRecord)
  115. record.ActivityId = aid
  116. record.Name = name
  117. record.RehearsalId = rid
  118. record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId
  119. record.ShakeRedEnvelopeRuleId = rule.Id
  120. record.Amount = utils.Float64CusDecimal(float64(money)/float64(100), 2)
  121. record.IsDraw = -1
  122. if _, err := models.Add(record); err != nil {
  123. return err
  124. }
  125. sumMoney += money
  126. }
  127. } else if rule.Model == define.SHAKERB_RULE_COMMON { // 普通红包
  128. for i := 0; i < rule.RedEnvelopeNum; i++ {
  129. record := new(models.ShakeRedEnvelopeRecord)
  130. record.ActivityId = aid
  131. record.Name = name
  132. record.RehearsalId = rid
  133. record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId
  134. record.ShakeRedEnvelopeRuleId = rule.Id
  135. record.Amount = rule.Single
  136. record.IsDraw = -1
  137. if _, err := models.Add(record); err != nil {
  138. return err
  139. }
  140. }
  141. } else if rule.Model == define.SHAKERB_RULE_LADDER { // 阶梯红包
  142. ladders := make([]*models.ShakeRedEnvelopeRuleLadder, 0)
  143. err := core.GetXormAuto().Where("is_delete=0 and shake_red_envelope_rule_id=?", rule.Id).
  144. Desc("created_at").Find(&ladders)
  145. if err != nil {
  146. return err
  147. }
  148. for _, ladder := range ladders {
  149. for i := 0; i < int(ladder.RedEnvelopeNum); i++ {
  150. record := new(models.ShakeRedEnvelopeRecord)
  151. record.ActivityId = aid
  152. record.Name = name
  153. record.RehearsalId = rid
  154. record.ShakeRedEnvelopeActivityId = rule.ShakeRedEnvelopeActivityId
  155. record.ShakeRedEnvelopeRuleId = rule.Id
  156. record.Amount = ladder.Single
  157. record.IsDraw = -1
  158. if _, err := models.Add(record); err != nil {
  159. return err
  160. }
  161. }
  162. }
  163. }
  164. return nil
  165. }