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

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