package pay_service import ( "errors" "fmt" "github.com/xormplus/xorm" "hudongzhuanjia/logger" "hudongzhuanjia/models" im_service "hudongzhuanjia/services/im" "hudongzhuanjia/utils" "hudongzhuanjia/utils/define" "math" "time" ) func init() { go loopOrder() go utils.HandleTicker(1*time.Hour, HandleReward) // 打赏24小时退款 } var orderDelayQueue = make(chan *models.UserOrder, math.MaxInt8) func PutOrderDelayQueue(order *models.UserOrder) { orderDelayQueue <- order } func loopOrder() { orders, err := models.GetUserOrdersByStatus(0, 3) if err != nil { panic(err) } for _, order := range orders { PutOrderDelayQueue(order) } defer func() { if err := recover(); err != nil { logger.Error("订单轮询查询: panic 恢复错误", err) } // 重启 time.Sleep(5 * time.Second) loopOrder() }() for { select { case order, ok := <-orderDelayQueue: if !ok { panic("通道异常关闭") } if order.ExpireAt <= time.Now().Unix() { // 订单超时 if order.Status == 0 { go HandleTimeout(order) } continue } if order.Status == 0 { res, err := OrderQuery(order.OutTradeNo) if err != nil { logger.Error("查询订单出现错误: 错误原因-->", err.Error(), "交易订单号-->", order.OutTradeNo) orderDelayQueue <- order // 重新进入队列 continue } if res["trade_state"] == define.CODE_TRADE_SUCCESS { go HandleSuccess(order) } else if res["trade_state"] == define.CODE_TRADE_REFUND { order.Status = 3 orderDelayQueue <- order continue } else { orderDelayQueue <- order continue } } else if order.Status == 3 { res, err := QueryRefund(order.OutTradeNo) if err != nil { logger.Error("退款订单查询错误: 错误原因-->", err.Error(), "交易订单号-->", order.OutTradeNo) continue } order.RefundAccount = res.RefundList[0].RefundAccount order.RefundRecvAccount = res.RefundList[0].RefundRecvAccout order.Status = 4 _, err = models.Update(order.Id, order, "refund_account", "refund_recv_account", "status") if err != nil { logger.Error("退款状态改变错误: 错误原因-->", err, "交易订单号-->", order.OutTradeNo) continue } } } } } //处理支付成功之后的回调问题 func HandleSuccess(order *models.UserOrder) error { if order.GoodType == 4 { // 直播商品 customerOrder := new(models.CustomerOrder) _, err := customerOrder.UpdateStatusBy(order.OutTradeNo, 0, 1) if err != nil { return errors.New("更新状态发送错误") } customerOrder.GetByOutTradeNO(order.OutTradeNo) if customerOrder.Status != 1 { return errors.New("商品订单状态信息出现异常") } subs, err := models.GetCustomerOrderSubsByOrderNos(customerOrder.OrderNo) if err != nil { logger.Error("商品子订单查询异常", err) return err } for _, sub := range subs { err = im_service.SendGroupCustomMessage(customerOrder.BuyerId, order.ActivityId, im_service.NoticeLiveGoodBuy, map[string]interface{}{ "goods_pic_url": sub["goods_pic_url"], "goods_num": sub["goods_num"], "good_name": sub["good_name"], "good_price": sub["good_price"], "goods_id": sub["goods_id"], "timestamp": time.Now().Unix(), }) if err != nil { logger.Error("直播商品子订单信息发送异常异常", err) return err } } activity := new(models.Activity) exist, err := models.Get(activity, order.ActivityId) if err != nil || !exist { return errors.New("互动信息异常") } gift := new(models.OrderGift) exist, err = gift.GetByActivityId(order.ActivityId) if err != nil { err = fmt.Errorf("获取订单送礼错误: err-> %v, activity_id-> %v", err, activity.Id) logger.Error(err) return err } if !exist { return nil } prize := new(models.UserPrize) prize.UserId = order.UserId prize.ActivityId = order.ActivityId prize.RehearsalId = activity.RehearsalId prize.ActivityName = activity.Name prize.PrizeName = gift.GiftName prize.PrizeImg = gift.GiftPicUrl prize.PrizeType = 4 prize.IsDelete = false prize.Status = 1 prize.CreatedAt = time.Now() prize.UpdatedAt = time.Now() if gift.Num > 0 { count, err := new(models.CustomerOrder). Count(activity.Id, activity.RehearsalId, customerOrder.CreatedAt) if err != nil { err = fmt.Errorf("订单人数统计失败: err->%v, out_trade_no->%v", err, order.OutTradeNo) logger.Error(err) return err } if gift.Num <= int(count) { // 人数足够 return nil } } _, err = prize.Add() if err != nil { err = fmt.Errorf("奖品添加失败: err->%v, out_trade_no->%v", err, order.OutTradeNo) logger.Error(err) return err } customerOrder.UserPrizeId = prize.Id _, err = models.Update(customerOrder.Id, customerOrder, "user_prize_id") if err != nil { err = fmt.Errorf("奖品记录添加失败: err-> %v, out_trade_no-> %v, prize_id->%v", err, order.OutTradeNo, prize.Id) logger.Error(err) return err } } else if order.GoodType == 3 { // 直播红包 info := new(models.LiveRedEnvelopeRule) _, err := info.UpdateStatusByOutTradeNo(order.OutTradeNo, 1) if err != nil { err = fmt.Errorf("状态改变出现错误: err->%v, out_trade_no->%v", err, order.OutTradeNo) logger.Error(err.Error()) return err } exist, err := info.GetByOutTradeNo(order.OutTradeNo) if err != nil || !exist || info.Status != 1 { err = fmt.Errorf("直播红包信息异常: err-> %v, exist->%v, status->%v, out_trade_no->%v", err, exist, info.Status, order.OutTradeNo) logger.Error(err.Error()) return err } err = im_service.SendGroupCustomMessage(info.UserId, order.ActivityId, im_service.NoticeLiveRedPackStart, map[string]interface{}{ "live_red_envelope_rule_id": info.Id, "prompt": info.Prompt, "timestamp": time.Now().Unix(), }) if err != nil { err = fmt.Errorf("发送腾讯im信息出现错误: err->%v, info_id->%v, out_trade_no->%v", err, info.Id, order.OutTradeNo) logger.Error(err.Error()) return err } } else if order.GoodType == 2 { // 打赏 history := new(models.RewardHistory) exist, err := history.GetByOutTradeNo(order.OutTradeNo) if err != nil || !exist || history.Status != -1 { err = fmt.Errorf("打赏历史异常: err->%v, out_trade_no %v", err, order.OutTradeNo) logger.Error(err.Error()) return err } _, err = history.UpdateStatus(history.Id, 0) if err != nil { err = fmt.Errorf("打赏状态发送变化: err->%v, out_trade_no %v", err, order.OutTradeNo) logger.Error(err.Error()) return err } } else if order.GoodType == 1 { // 霸屏 history := new(models.BullyScreenHistory) exist, err := history.GetByOutTradeNo(order.OutTradeNo) if err != nil || !exist || history.Status != -1 { err = fmt.Errorf("打赏历史异常: err->%v, out_trade_no %v", err, order.OutTradeNo) logger.Error(err.Error()) return err } _, err = history.UpdateStatus(history.Id, 0) if err != nil { err = fmt.Errorf("霸屏状态发送变化: err->%v, out_trade_no %v", err, order.OutTradeNo) logger.Error(err.Error()) } } return nil } func HandleTimeout(order *models.UserOrder) error { // 退还库存 if order.GoodType == 4 { err := HandleCancelOrder(order.OutTradeNo) if err != nil { logger.Error(err) } } return nil } // 处理打赏 func HandleReward() error { result, err := models.GetExpireRewardHistory() if err != nil { logger.Error("获取过期打赏错误原因", err) return err } for _, v := range result { if v.RehearsalId != 0 && v.Type == 0 { // 欧轩互动h5彩排 continue } _, err := Refund("欧轩互动-打赏过期退款", v.OutTradeNo) if err != nil { logger.Error("欧轩互动打赏过期退款", v.OutTradeNo) return err } v.Status = 4 _, err = models.Update(v.Id, v, "status") if err != nil { logger.Error("欧轩互动打赏过期状态改变错误") } } return nil } func HandleCancelOrder(outTradeNo string) error { return models.Commit(func(session *xorm.Session) error { order := new(models.CustomerOrder) exist, err := session.Where("is_delete=0 and status=0 and out_trade_no=?", outTradeNo).Get(order) if err != nil { return err } if !exist || order.Status != 0 { return errors.New("客户订单异常") } order.Status = 9 order.CancelTime = time.Now() _, err = session.Where("is_delete=0 and out_trade_no=?", outTradeNo).Cols("status, cancel_time").Update(order) if err != nil { return err } subs := make([]*models.CustomerOrderSub, 0) err = session.Where("is_delete=0 and order_no=?", order.OrderNo).Find(&subs) if err != nil { return err } for _, sub := range subs { _, err = session.Where("id=?", sub.GoodsId). Incr("stock", sub.GoodsNum).Update(&models.CustomerGoods{}) if err != nil { return err } } return nil }) }