exchange.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. package service
  2. import (
  3. "context"
  4. "fmt"
  5. "sort"
  6. "time"
  7. "go-common/app/interface/main/growup/dao"
  8. "go-common/app/interface/main/growup/model"
  9. "go-common/library/ecode"
  10. "go-common/library/log"
  11. xtime "go-common/library/time"
  12. )
  13. var (
  14. _display = 2
  15. _bigVipType = 1
  16. _remark = "激励兑换"
  17. )
  18. // GoodsState get goods new state
  19. func (s *Service) GoodsState(c context.Context) (data interface{}, err error) {
  20. var newDisplay string
  21. goods, err := s.dao.GetDisplayGoods(c, _display)
  22. if err != nil {
  23. log.Error("s.dao.GetDisplayGoods error(%v)", err)
  24. return
  25. }
  26. if len(goods) > 0 {
  27. sort.Slice(goods, func(i, j int) bool {
  28. return goods[i].DisplayOnTime > goods[j].DisplayOnTime
  29. })
  30. newDisplay = fmt.Sprintf("%s+%d+%d", goods[0].ProductID, goods[0].GoodsType, goods[0].DisplayOnTime)
  31. }
  32. data = map[string]interface{}{
  33. "new_display": newDisplay,
  34. "open_exchange": time.Now().Day() >= 8, // 1-7号不开放兑换
  35. }
  36. return
  37. }
  38. // GoodsShow show goods
  39. func (s *Service) GoodsShow(c context.Context, mid int64) (goods []*model.GoodsInfo, err error) {
  40. goods, err = s.dao.GetDisplayGoods(c, _display)
  41. if err != nil {
  42. log.Error("s.dao.GetDisplayGoods error(%v)", err)
  43. return
  44. }
  45. vips, err := s.dao.ListVipProducts(c, mid)
  46. if err != nil {
  47. log.Error("s.dao.ListVipProducts error(%v)", err)
  48. return
  49. }
  50. // get vip price
  51. for _, g := range goods {
  52. if g.GoodsType != _bigVipType {
  53. continue
  54. }
  55. if v, ok := vips[g.ProductID]; ok {
  56. g.Month = v.Month
  57. g.ProductName = v.ProductName
  58. g.OriginPrice = v.OriginPrice
  59. g.CurrentPrice = int64(dao.Round(dao.Mul(float64(v.OriginPrice), float64(g.Discount)/float64(100)), 0))
  60. }
  61. }
  62. sort.Slice(goods, func(i, j int) bool {
  63. return goods[i].Month < goods[j].Month
  64. })
  65. return
  66. }
  67. // GoodsRecord get goods record
  68. func (s *Service) GoodsRecord(c context.Context, mid int64, page, size int) (monthOrder map[string][]*model.GoodsOrder, count int, err error) {
  69. monthOrder = make(map[string][]*model.GoodsOrder)
  70. if page == 0 {
  71. page = 1
  72. }
  73. start, end := (page-1)*size, page*size
  74. count, err = s.dao.GetGoodsOrderCount(c, mid)
  75. if err != nil {
  76. log.Error("s.dao.GetGoodsRecordCount error(%v)", err)
  77. return
  78. }
  79. orders, err := s.dao.GetGoodsOrders(c, mid, start, end)
  80. if err != nil {
  81. log.Error("s.dao.GetGoodsOrders error(%v)", err)
  82. return
  83. }
  84. for i := 0; i < len(orders); i++ {
  85. month := orders[i].OrderTime.Time().Format("2006-01")
  86. if _, ok := monthOrder[month]; !ok {
  87. monthOrder[month] = make([]*model.GoodsOrder, 0)
  88. }
  89. monthOrder[month] = append(monthOrder[month], orders[i])
  90. }
  91. return
  92. }
  93. // GoodsBuy buy goods from creative
  94. func (s *Service) GoodsBuy(c context.Context, mid int64, productID string, goodsType int, price int64) (err error) {
  95. date := time.Now()
  96. // 1-7号不开放兑换
  97. if date.Day() < 8 {
  98. err = ecode.GrowupGoodsTimeErr
  99. return
  100. }
  101. p, err := s.getProduct(c, mid, productID, goodsType)
  102. if err != nil {
  103. log.Error("s.getProduct error(%v)", err)
  104. return
  105. }
  106. p.CurrentPrice = int64(dao.Round(dao.Mul(float64(p.OriginPrice), float64(p.Discount)/float64(100)), 0))
  107. if price != p.CurrentPrice {
  108. err = ecode.GrowupPriceErr
  109. return
  110. }
  111. // check upwithdraw_income
  112. upAccount, totalUnwithdraw, err := s.getUpTotalUnwithdraw(c, mid)
  113. if err != nil {
  114. log.Error("s.getUpTotalUnwithdraw error(%v)", err)
  115. return
  116. }
  117. if totalUnwithdraw < p.CurrentPrice {
  118. err = ecode.GrowupPriceNotEnough
  119. return
  120. }
  121. uuid, err := s.sf.Generate()
  122. if err != nil {
  123. return
  124. }
  125. order := &model.GoodsOrder{
  126. MID: mid,
  127. OrderNo: fmt.Sprintf("DHY-%s-%d-%d", date.Format("20060102150405"), uuid, mid),
  128. OrderTime: xtime.Time(date.Unix()),
  129. GoodsType: p.GoodsType,
  130. GoodsID: productID,
  131. GoodsName: p.ProductName,
  132. GoodsPrice: p.CurrentPrice,
  133. GoodsCost: p.OriginPrice,
  134. }
  135. // 清除up_summary redis缓存
  136. if err = s.dao.DelCacheKey(c, fmt.Sprintf("growup-up-summary:%d", mid)); err != nil {
  137. log.Error("s.dao.DelCacheKey error(%v)", err)
  138. return
  139. }
  140. tx, err := s.dao.BeginTran(c)
  141. if err != nil {
  142. log.Error("s.dao.BeginTran error(%v)", err)
  143. return
  144. }
  145. // update up account
  146. rows, err := s.dao.TxUpdateUpAccountExchangeIncome(tx, mid, p.CurrentPrice, upAccount.Version)
  147. if err != nil {
  148. tx.Rollback()
  149. log.Error("s.dao.TxUpdateUpAccountExchangeIncome error(%v)", err)
  150. return
  151. }
  152. if rows != 1 {
  153. tx.Rollback()
  154. log.Error("s.dao.TxUpdateUpAccountExchangeIncome update rows(%d) != 1")
  155. err = ecode.GrowupBuyErr
  156. return
  157. }
  158. // generate order
  159. rows, err = s.dao.TxInsertGoodsOrder(tx, order)
  160. if err != nil {
  161. tx.Rollback()
  162. log.Error("s.dao.InsertGoodsOrder error(%v)", err)
  163. return
  164. }
  165. if rows != 1 {
  166. tx.Rollback()
  167. log.Error("s.dao.InsertGoodsOrder insert rows(%d) != 1", rows)
  168. err = ecode.GrowupBuyErr
  169. return
  170. }
  171. // use vip batch info
  172. if err = s.dao.ExchangeBigVIP(c, mid, p.ResourceID, uuid, _remark); err != nil {
  173. tx.Rollback()
  174. log.Error("s.dao.ExchangeBigVIP error(%v)", err)
  175. err = ecode.GrowupBuyErr
  176. return
  177. }
  178. if err = tx.Commit(); err != nil {
  179. log.Error("tx.Commit error")
  180. }
  181. return
  182. }
  183. func (s *Service) getProduct(c context.Context, mid int64, productID string, goodsType int) (p *model.GoodsInfo, err error) {
  184. p, err = s.dao.GetGoodsByProductID(c, productID, goodsType)
  185. if err != nil {
  186. log.Error("s.dao.GetGoodsByProductID error(%v)", err)
  187. return
  188. }
  189. vips, err := s.dao.ListVipProducts(c, mid)
  190. if err != nil {
  191. log.Error("s.dao.ListVipProducts error(%v)", err)
  192. return
  193. }
  194. // check ResourceID
  195. if p.ResourceID == 0 || len(vips) == 0 {
  196. err = ecode.GrowupGoodsNotExist
  197. return
  198. }
  199. vip, ok := vips[productID]
  200. if !ok {
  201. err = ecode.GrowupGoodsNotExist
  202. return
  203. }
  204. p.OriginPrice = vip.OriginPrice
  205. p.ProductName = vip.ProductName
  206. return
  207. }
  208. func (s *Service) getUpTotalUnwithdraw(c context.Context, mid int64) (upAccount *model.UpAccount, unwithdraw int64, err error) {
  209. lastDay := time.Now().AddDate(0, 0, -1)
  210. upIncomes, err := s.dao.ListUpIncome(c, mid, "up_income", lastDay.Format(_layout), lastDay.Format(_layout))
  211. if err != nil {
  212. log.Error("s.dao.ListUpIncome error(%v)", err)
  213. return
  214. }
  215. var lastDayIncome int64
  216. for _, up := range upIncomes {
  217. if up.Date.Time().Format(_layout) == lastDay.Format(_layout) {
  218. lastDayIncome = up.Income
  219. }
  220. }
  221. upAccount, err = s.dao.ListUpAccount(c, mid)
  222. if err != nil {
  223. log.Error("s.dao.ListUpAccount error(%v)", err)
  224. return
  225. }
  226. if upAccount == nil {
  227. err = ecode.GrowupPriceNotEnough
  228. return
  229. }
  230. unwithdraw = upAccount.TotalUnwithdrawIncome - lastDayIncome
  231. return
  232. }