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

305 lines
8.6 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
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
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 pay_service
  2. import (
  3. "errors"
  4. "fmt"
  5. "github.com/xormplus/xorm"
  6. "hudongzhuanjia/logger"
  7. "hudongzhuanjia/models"
  8. im_service "hudongzhuanjia/services/im"
  9. "hudongzhuanjia/utils"
  10. "hudongzhuanjia/utils/define"
  11. "math"
  12. "time"
  13. )
  14. func init() {
  15. //go loopOrder()
  16. go utils.HandleTicker(1*time.Second, HandleReward) // 打赏24小时退款
  17. }
  18. var orderDelayQueue = make(chan *models.UserOrder, math.MaxInt8)
  19. func PutOrderDelayQueue(order *models.UserOrder) {
  20. orderDelayQueue <- order
  21. }
  22. func loopOrder() {
  23. orders, err := models.GetUserOrdersByStatus(0, 3)
  24. if err != nil {
  25. panic(err)
  26. }
  27. for _, order := range orders {
  28. PutOrderDelayQueue(order)
  29. }
  30. defer func() {
  31. if err := recover(); err != nil {
  32. logger.Error("订单轮询查询: panic 恢复错误", err)
  33. }
  34. // 重启
  35. time.Sleep(5 * time.Second)
  36. loopOrder()
  37. }()
  38. for {
  39. select {
  40. case order, ok := <-orderDelayQueue:
  41. if !ok {
  42. panic("通道异常关闭")
  43. }
  44. if order.ExpireAt <= time.Now().Unix() { // 订单超时
  45. if order.Status == 0 {
  46. go HandleTimeout(order)
  47. }
  48. continue
  49. }
  50. if order.Status == 0 {
  51. res, err := OrderQuery(order.OutTradeNo)
  52. if err != nil {
  53. logger.Error("查询订单出现错误: 错误原因-->", err.Error(), "交易订单号-->", order.OutTradeNo)
  54. orderDelayQueue <- order // 重新进入队列
  55. continue
  56. }
  57. if res["trade_state"] == define.CODE_TRADE_SUCCESS {
  58. go HandleSuccess(order)
  59. } else if res["trade_state"] == define.CODE_TRADE_REFUND {
  60. order.Status = 3
  61. orderDelayQueue <- order
  62. continue
  63. } else {
  64. orderDelayQueue <- order
  65. continue
  66. }
  67. } else if order.Status == 3 {
  68. res, err := QueryRefund(order.OutTradeNo)
  69. if err != nil {
  70. logger.Error("退款订单查询错误: 错误原因-->", err.Error(), "交易订单号-->", order.OutTradeNo)
  71. continue
  72. }
  73. order.RefundAccount = res.RefundList[0].RefundAccount
  74. order.RefundRecvAccount = res.RefundList[0].RefundRecvAccout
  75. order.Status = 4
  76. _, err = models.Update(order.Id, order, "refund_account", "refund_recv_account", "status")
  77. if err != nil {
  78. logger.Error("退款状态改变错误: 错误原因-->", err, "交易订单号-->", order.OutTradeNo)
  79. continue
  80. }
  81. }
  82. }
  83. }
  84. }
  85. //处理支付成功之后的回调问题
  86. func HandleSuccess(order *models.UserOrder) error {
  87. if order.GoodType == 4 { // 直播商品
  88. customerOrder := new(models.CustomerOrder)
  89. _, err := customerOrder.UpdateStatusBy(order.OutTradeNo, 0, 1)
  90. if err != nil {
  91. return errors.New("更新状态发送错误")
  92. }
  93. customerOrder.GetByOutTradeNO(order.OutTradeNo)
  94. if customerOrder.Status != 1 {
  95. return errors.New("商品订单状态信息出现异常")
  96. }
  97. subs, err := models.GetCustomerOrderSubsByOrderNos(customerOrder.OrderNo)
  98. if err != nil {
  99. logger.Error("商品子订单查询异常", err)
  100. return err
  101. }
  102. for _, sub := range subs {
  103. go im_service.SendGroupCustomMessage(customerOrder.BuyerId, order.ActivityId, im_service.NoticeLiveGoodBuy,
  104. map[string]interface{}{
  105. "goods_pic_url": sub["goods_pic_url"],
  106. "goods_num": sub["goods_num"],
  107. "good_name": sub["good_name"],
  108. "good_price": sub["good_price"],
  109. "goods_id": sub["goods_id"],
  110. "timestamp": time.Now().Unix(),
  111. })
  112. }
  113. activity := new(models.Activity)
  114. exist, err := models.Get(activity, order.ActivityId)
  115. if err != nil || !exist {
  116. return errors.New("互动信息异常")
  117. }
  118. gift := new(models.OrderGift)
  119. exist, err = gift.GetByActivityId(order.ActivityId)
  120. if err != nil {
  121. err = fmt.Errorf("获取订单送礼错误: err-> %v, activity_id-> %v", err, activity.Id)
  122. logger.Error(err)
  123. return err
  124. }
  125. if !exist {
  126. return nil
  127. }
  128. prize := new(models.UserPrize)
  129. prize.UserId = order.UserId
  130. prize.ActivityId = order.ActivityId
  131. prize.RehearsalId = activity.RehearsalId
  132. prize.ActivityName = activity.Name
  133. prize.PrizeName = gift.GiftName
  134. prize.PrizeImg = gift.GiftPicUrl
  135. prize.PrizeType = 4
  136. prize.IsDelete = false
  137. prize.Status = 1
  138. prize.CreatedAt = time.Now()
  139. prize.UpdatedAt = time.Now()
  140. if gift.Num > 0 {
  141. count, err := new(models.CustomerOrder).
  142. Count(activity.Id, activity.RehearsalId, customerOrder.CreatedAt)
  143. if err != nil {
  144. err = fmt.Errorf("订单人数统计失败: err->%v, out_trade_no->%v", err, order.OutTradeNo)
  145. logger.Error(err)
  146. return err
  147. }
  148. if gift.Num <= int(count) { // 人数足够
  149. return nil
  150. }
  151. }
  152. _, err = prize.Add()
  153. if err != nil {
  154. err = fmt.Errorf("奖品添加失败: err->%v, out_trade_no->%v", err, order.OutTradeNo)
  155. logger.Error(err)
  156. return err
  157. }
  158. customerOrder.UserPrizeId = prize.Id
  159. _, err = models.Update(customerOrder.Id, customerOrder, "user_prize_id")
  160. if err != nil {
  161. err = fmt.Errorf("奖品记录添加失败: err-> %v, out_trade_no-> %v, prize_id->%v", err, order.OutTradeNo, prize.Id)
  162. logger.Error(err)
  163. return err
  164. }
  165. } else if order.GoodType == 3 { // 直播红包
  166. info := new(models.LiveRedEnvelopeRule)
  167. _, err := info.UpdateStatusByOutTradeNo(order.OutTradeNo, 1)
  168. if err != nil {
  169. err = fmt.Errorf("状态改变出现错误: err->%v, out_trade_no->%v", err, order.OutTradeNo)
  170. logger.Error(err.Error())
  171. return err
  172. }
  173. exist, err := info.GetByOutTradeNo(order.OutTradeNo)
  174. if err != nil || !exist || info.Status != 1 {
  175. err = fmt.Errorf("直播红包信息异常: err-> %v, exist->%v, status->%v, out_trade_no->%v",
  176. err, exist, info.Status, order.OutTradeNo)
  177. logger.Error(err.Error())
  178. return err
  179. }
  180. go im_service.SendGroupCustomMessage(info.UserId, order.ActivityId, im_service.NoticeLiveRedPackStart,
  181. map[string]interface{}{
  182. "live_red_envelope_rule_id": info.Id,
  183. "prompt": info.Prompt,
  184. "timestamp": time.Now().Unix(),
  185. })
  186. } else if order.GoodType == 2 { // 打赏
  187. history := new(models.RewardHistory)
  188. exist, err := history.GetByOutTradeNo(order.OutTradeNo)
  189. if err != nil || !exist || history.Status != -1 {
  190. err = fmt.Errorf("打赏历史异常: err->%v, out_trade_no %v", err, order.OutTradeNo)
  191. logger.Error(err.Error())
  192. return err
  193. }
  194. _, err = history.UpdateStatus(history.Id, 0)
  195. if err != nil {
  196. err = fmt.Errorf("打赏状态发送变化: err->%v, out_trade_no %v", err, order.OutTradeNo)
  197. logger.Error(err.Error())
  198. return err
  199. }
  200. } else if order.GoodType == 1 { // 霸屏
  201. history := new(models.BullyScreenHistory)
  202. exist, err := history.GetByOutTradeNo(order.OutTradeNo)
  203. if err != nil || !exist || history.Status != -1 {
  204. err = fmt.Errorf("打赏历史异常: err->%v, out_trade_no %v", err, order.OutTradeNo)
  205. logger.Error(err.Error())
  206. return err
  207. }
  208. _, err = history.UpdateStatus(history.Id, 0)
  209. if err != nil {
  210. err = fmt.Errorf("霸屏状态发送变化: err->%v, out_trade_no %v", err, order.OutTradeNo)
  211. logger.Error(err.Error())
  212. }
  213. }
  214. return nil
  215. }
  216. func HandleTimeout(order *models.UserOrder) error {
  217. // 退还库存
  218. if order.GoodType == 4 {
  219. err := HandleCancelOrder(order.OutTradeNo)
  220. if err != nil {
  221. logger.Error(err)
  222. }
  223. }
  224. return nil
  225. }
  226. // 处理打赏
  227. func HandleReward() error {
  228. result, err := models.GetExpireRewardHistory()
  229. if err != nil {
  230. err = fmt.Errorf("获取过期打赏错误原因: %v", err)
  231. return err
  232. }
  233. for _, v := range result {
  234. if v.RehearsalId != 0 && v.Type == 0 { // 欧轩互动h5彩排
  235. continue
  236. }
  237. _, err := Refund("欧轩互动-打赏过期退款", v.OutTradeNo)
  238. if err != nil {
  239. err = fmt.Errorf("欧轩互动打赏过期退款错误: %v, out_trade_no: %v", err, v.OutTradeNo)
  240. return err
  241. }
  242. v.Status = 4
  243. _, err = models.Update(v.Id, v, "status")
  244. if err != nil {
  245. err = fmt.Errorf("欧轩互动打赏过期状态改变错误: %v, out_trade_no: %v", err, v.OutTradeNo)
  246. return err
  247. }
  248. }
  249. return nil
  250. }
  251. func HandleCancelOrder(outTradeNo string) error {
  252. return models.Commit(func(session *xorm.Session) error {
  253. order := new(models.CustomerOrder)
  254. exist, err := session.Where("is_delete=0 and status=0 and out_trade_no=?",
  255. outTradeNo).Get(order)
  256. if err != nil {
  257. return err
  258. }
  259. if !exist || order.Status != 0 {
  260. return errors.New("客户订单异常")
  261. }
  262. order.Status = 9
  263. order.CancelTime = time.Now()
  264. _, err = session.Where("is_delete=0 and out_trade_no=?",
  265. outTradeNo).Cols("status, cancel_time").Update(order)
  266. if err != nil {
  267. return err
  268. }
  269. subs := make([]*models.CustomerOrderSub, 0)
  270. err = session.Where("is_delete=0 and order_no=?", order.OrderNo).Find(&subs)
  271. if err != nil {
  272. return err
  273. }
  274. for _, sub := range subs {
  275. _, err = session.Where("id=?", sub.GoodsId).
  276. Incr("stock", sub.GoodsNum).Update(&models.CustomerGoods{})
  277. if err != nil {
  278. return err
  279. }
  280. }
  281. return nil
  282. })
  283. }