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

314 lines
8.8 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.Hour, 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. err = 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. if err != nil {
  113. logger.Error("直播商品子订单信息发送异常异常", err)
  114. return err
  115. }
  116. }
  117. activity := new(models.Activity)
  118. exist, err := models.Get(activity, order.ActivityId)
  119. if err != nil || !exist {
  120. return errors.New("互动信息异常")
  121. }
  122. gift := new(models.OrderGift)
  123. exist, err = gift.GetByActivityId(order.ActivityId)
  124. if err != nil {
  125. err = fmt.Errorf("获取订单送礼错误: err-> %v, activity_id-> %v", err, activity.Id)
  126. logger.Error(err)
  127. return err
  128. }
  129. if !exist {
  130. return nil
  131. }
  132. prize := new(models.UserPrize)
  133. prize.UserId = order.UserId
  134. prize.ActivityId = order.ActivityId
  135. prize.RehearsalId = activity.RehearsalId
  136. prize.ActivityName = activity.Name
  137. prize.PrizeName = gift.GiftName
  138. prize.PrizeImg = gift.GiftPicUrl
  139. prize.PrizeType = 4
  140. prize.IsDelete = false
  141. prize.Status = 1
  142. prize.CreatedAt = time.Now()
  143. prize.UpdatedAt = time.Now()
  144. if gift.Num > 0 {
  145. count, err := new(models.CustomerOrder).
  146. Count(activity.Id, activity.RehearsalId, customerOrder.CreatedAt)
  147. if err != nil {
  148. err = fmt.Errorf("订单人数统计失败: err->%v, out_trade_no->%v", err, order.OutTradeNo)
  149. logger.Error(err)
  150. return err
  151. }
  152. if gift.Num <= int(count) { // 人数足够
  153. return nil
  154. }
  155. }
  156. _, err = prize.Add()
  157. if err != nil {
  158. err = fmt.Errorf("奖品添加失败: err->%v, out_trade_no->%v", err, order.OutTradeNo)
  159. logger.Error(err)
  160. return err
  161. }
  162. customerOrder.UserPrizeId = prize.Id
  163. _, err = models.Update(customerOrder.Id, customerOrder, "user_prize_id")
  164. if err != nil {
  165. err = fmt.Errorf("奖品记录添加失败: err-> %v, out_trade_no-> %v, prize_id->%v", err, order.OutTradeNo, prize.Id)
  166. logger.Error(err)
  167. return err
  168. }
  169. } else if order.GoodType == 3 { // 直播红包
  170. info := new(models.LiveRedEnvelopeRule)
  171. _, err := info.UpdateStatusByOutTradeNo(order.OutTradeNo, 1)
  172. if err != nil {
  173. err = fmt.Errorf("状态改变出现错误: err->%v, out_trade_no->%v", err, order.OutTradeNo)
  174. logger.Error(err.Error())
  175. return err
  176. }
  177. exist, err := info.GetByOutTradeNo(order.OutTradeNo)
  178. if err != nil || !exist || info.Status != 1 {
  179. err = fmt.Errorf("直播红包信息异常: err-> %v, exist->%v, status->%v, out_trade_no->%v",
  180. err, exist, info.Status, order.OutTradeNo)
  181. logger.Error(err.Error())
  182. return err
  183. }
  184. err = im_service.SendGroupCustomMessage(info.UserId, order.ActivityId, im_service.NoticeLiveRedPackStart,
  185. map[string]interface{}{
  186. "live_red_envelope_rule_id": info.Id,
  187. "prompt": info.Prompt,
  188. "timestamp": time.Now().Unix(),
  189. })
  190. if err != nil {
  191. err = fmt.Errorf("发送腾讯im信息出现错误: err->%v, info_id->%v, out_trade_no->%v",
  192. err, info.Id, order.OutTradeNo)
  193. logger.Error(err.Error())
  194. return err
  195. }
  196. } else if order.GoodType == 2 { // 打赏
  197. history := new(models.RewardHistory)
  198. exist, err := history.GetByOutTradeNo(order.OutTradeNo)
  199. if err != nil || !exist || history.Status != -1 {
  200. err = fmt.Errorf("打赏历史异常: err->%v, out_trade_no %v", err, order.OutTradeNo)
  201. logger.Error(err.Error())
  202. return err
  203. }
  204. _, err = history.UpdateStatus(history.Id, 0)
  205. if err != nil {
  206. err = fmt.Errorf("打赏状态发送变化: err->%v, out_trade_no %v", err, order.OutTradeNo)
  207. logger.Error(err.Error())
  208. return err
  209. }
  210. } else if order.GoodType == 1 { // 霸屏
  211. history := new(models.BullyScreenHistory)
  212. exist, err := history.GetByOutTradeNo(order.OutTradeNo)
  213. if err != nil || !exist || history.Status != -1 {
  214. err = fmt.Errorf("打赏历史异常: err->%v, out_trade_no %v", err, order.OutTradeNo)
  215. logger.Error(err.Error())
  216. return err
  217. }
  218. _, err = history.UpdateStatus(history.Id, 0)
  219. if err != nil {
  220. err = fmt.Errorf("霸屏状态发送变化: err->%v, out_trade_no %v", err, order.OutTradeNo)
  221. logger.Error(err.Error())
  222. }
  223. }
  224. return nil
  225. }
  226. func HandleTimeout(order *models.UserOrder) error {
  227. // 退还库存
  228. if order.GoodType == 4 {
  229. err := HandleCancelOrder(order.OutTradeNo)
  230. if err != nil {
  231. logger.Error(err)
  232. }
  233. }
  234. return nil
  235. }
  236. // 处理打赏
  237. func HandleReward() error {
  238. result, err := models.GetExpireRewardHistory()
  239. if err != nil {
  240. logger.Error("获取过期打赏错误原因", err)
  241. return err
  242. }
  243. for _, v := range result {
  244. if v.RehearsalId != 0 && v.Type == 0 { // 欧轩互动h5彩排
  245. continue
  246. }
  247. _, err := Refund("欧轩互动-打赏过期退款", v.OutTradeNo)
  248. if err != nil {
  249. logger.Error("欧轩互动打赏过期退款", v.OutTradeNo)
  250. return err
  251. }
  252. v.Status = 4
  253. _, err = models.Update(v.Id, v, "status")
  254. if err != nil {
  255. logger.Error("欧轩互动打赏过期状态改变错误")
  256. }
  257. }
  258. return nil
  259. }
  260. func HandleCancelOrder(outTradeNo string) error {
  261. return models.Commit(func(session *xorm.Session) error {
  262. order := new(models.CustomerOrder)
  263. exist, err := session.Where("is_delete=0 and status=0 and out_trade_no=?",
  264. outTradeNo).Get(order)
  265. if err != nil {
  266. return err
  267. }
  268. if !exist || order.Status != 0 {
  269. return errors.New("客户订单异常")
  270. }
  271. order.Status = 9
  272. order.CancelTime = time.Now()
  273. _, err = session.Where("is_delete=0 and out_trade_no=?",
  274. outTradeNo).Cols("status, cancel_time").Update(order)
  275. if err != nil {
  276. return err
  277. }
  278. subs := make([]*models.CustomerOrderSub, 0)
  279. err = session.Where("is_delete=0 and order_no=?", order.OrderNo).Find(&subs)
  280. if err != nil {
  281. return err
  282. }
  283. for _, sub := range subs {
  284. _, err = session.Where("id=?", sub.GoodsId).
  285. Incr("stock", sub.GoodsNum).Update(&models.CustomerGoods{})
  286. if err != nil {
  287. return err
  288. }
  289. }
  290. return nil
  291. })
  292. }