diff --git a/controllers/client/good.go b/controllers/client/good.go index f8339b9..0aa2e58 100644 --- a/controllers/client/good.go +++ b/controllers/client/good.go @@ -200,8 +200,9 @@ func (t *GoodCtl) Order() { } } + var expireAt = time.Now().Add(30 * time.Second).Unix() res, err := pay_service.UnifiedOrder("欧轩互动-直播商品", user.Openid, int64(price+int(option.PostFee*100)), - 4, userId, activity.Id, time.Now().Add(30*time.Second).Unix()) + 4, userId, activity.Id, expireAt) if err != nil { session.Rollback() t.CheckErr(err) @@ -224,10 +225,12 @@ func (t *GoodCtl) Order() { TotalAmount: float64(price)/100 + option.PostFee, PayAmount: float64(price)/100 + option.PostFee, Status: 0, + Type: 1, // 直播订单 Receiver: param.Name, Address: param.Address, Phone: param.Phone, IsDrawCash: 0, + ExpireTime: expireAt, Postage: option.PostFee, } _, err = session.InsertOne(&order) diff --git a/controllers/client/order_entry.go b/controllers/client/order_entry.go index 8cc970e..6d37150 100644 --- a/controllers/client/order_entry.go +++ b/controllers/client/order_entry.go @@ -120,6 +120,7 @@ func (t *OrderEntryCtl) Order() { order.AreaName = area.Name order.BuyerId = userId order.GoodsId = goodId + order.Type = 0 order.ActivityId = activityId order.RehearsalId = activity.RehearsalId order.OrderEntryPersonId = entryPerson.Id diff --git a/models/customer_order.go b/models/customer_order.go index 99b1206..f5180c0 100644 --- a/models/customer_order.go +++ b/models/customer_order.go @@ -26,10 +26,12 @@ type CustomerOrder struct { GoodsId int64 `json:"goods_id,omitempty" xorm:"not null default 0 comment('customer_goods表id') BIGINT(20)"` GoodsName string `json:"goods_name,omitempty" xorm:"not null default '' comment('商品名字') VARCHAR(255)"` GoodsNum int `json:"goods_num,omitempty" xorm:"not null default 0 comment('商品数量') INT(11)"` - TotalAmount float64 `json:"total_amount" xorm:"not null default 0.00 comment('订单总额') DECIMAL(18)"` - PayAmount float64 `json:"pay_amount" xorm:"not null default 0.00 comment('支付金额') DECIMAL(18)"` - Postage float64 `json:"postage" xorm:"not null default 0.00 comment('邮费[0免邮]') DECIMAL(18)"` + TotalAmount float64 `json:"total_amount" xorm:"not null default 0.00 comment('订单总额')"` + PayAmount float64 `json:"pay_amount" xorm:"not null default 0.00 comment('支付金额')"` + Postage float64 `json:"postage" xorm:"not null default 0.00 comment('邮费[0免邮]')"` Status int `json:"status" xorm:"not null default 0 comment('订单状态[0未支付1已支付即待发货3已发货4确认收货5申请退款6已退款7申请退货8已退货9已取消]')"` + ExpireTime int64 `json:"expire_time" xorm:"not null default 0 comment('订单过时') INT(11)"` + Type int `json:"type" xorm:"not null default 0 comment('订单类型、0录入订单1直播订单')"` // 快递信息 Receiver string `json:"receiver" xorm:"not null default '' comment('收件人') VARCHAR(128)"` @@ -84,3 +86,12 @@ func (t *CustomerOrder) UpdateStatusBy(outTradeNo string, originStatus, status i return core.GetXormAuto().Where("is_delete=0 and status=? and out_trade_no=?", originStatus, outTradeNo).Cols("status, cancel_time").Update(t) } + +func GetExpiredAtLiveCustomerOrder() ([]*CustomerOrder, error) { + orders := make([]*CustomerOrder, 0) + err := core.GetXormAuto().Where("type=1 and is_delete=0 and status=0 and expire_time <= ?", time.Now()).Find(&orders) + if err != nil { + return nil, err + } + return orders, nil +} diff --git a/models/customer_order_sub.go b/models/customer_order_sub.go index 6a07929..1be46fd 100644 --- a/models/customer_order_sub.go +++ b/models/customer_order_sub.go @@ -40,3 +40,13 @@ func GetCustomerOrderSubsByOrderNos(orderNos ...string) (subs []map[string]strin Desc("s.created_at").Find(&subs) return } + +func GetSubOrdersByOrderNo(orderNo string) ([]*CustomerOrderSub, error) { + subs := make([]*CustomerOrderSub, 0) + err := core.GetXormAuto().Where("is_delete=0 and order_no=?", orderNo).Find(&subs) + return subs, err +} + +func (t *CustomerOrderSub) IncrStock() { + +} diff --git a/services/pay/handle.go b/services/pay/handle.go index a05b932..5b0f3a5 100644 --- a/services/pay/handle.go +++ b/services/pay/handle.go @@ -6,90 +6,15 @@ import ( "github.com/xormplus/xorm" "hudongzhuanjia/logger" "hudongzhuanjia/models" - im_service "hudongzhuanjia/services/im" + "hudongzhuanjia/services/im" "hudongzhuanjia/utils" - "hudongzhuanjia/utils/define" - "math" "time" ) func init() { //go loopOrder() - go utils.HandleTicker(30*time.Minute, 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 - } - } - } - } + go utils.HandleTicker(30*time.Minute, HandleReward) // 打赏24小时退款 + go utils.HandleTicker(30*time.Second, HandleGoodOrder) // 订单关闭信息 } //处理支付成功之后的回调问题 @@ -232,12 +157,40 @@ func HandleSuccess(order *models.UserOrder) error { return nil } -func HandleTimeout(order *models.UserOrder) error { - // 退还库存 - if order.GoodType == 4 { - err := HandleCancelOrder(order.OutTradeNo) +// 处理商品订单超时的状态 +func HandleGoodOrder() error { + orders, err := models.GetExpiredAtLiveCustomerOrder() + if err != nil { + err = fmt.Errorf("获取过期订单信息错误原因: %v", err) + } + for _, v := range orders { + if v.Type != 1 || v.Status != 0 { + continue + } + _, err := OrderQuery(v.OutTradeNo) + if err == nil { + continue + } + err = Close(v.OutTradeNo) + if err != nil { + return err + } + v.Status = 9 + v.CancelTime = time.Now() + _, err = models.Update(v.Id, v, "status", "cancel_time") + if err != nil { + return err + } + + subs, err := models.GetSubOrdersByOrderNo(v.OrderNo) if err != nil { - logger.Error(err) + return err + } + for _, sub := range subs { + _, err = new(models.CustomerGoods).IncrStockById(sub.GoodsId, sub.GoodsNum) + if err != nil { + return err + } } } return nil diff --git a/services/pay/loop.go b/services/pay/loop.go new file mode 100644 index 0000000..043cdc0 --- /dev/null +++ b/services/pay/loop.go @@ -0,0 +1,94 @@ +package pay_service + +import ( + "hudongzhuanjia/logger" + "hudongzhuanjia/models" + "hudongzhuanjia/utils/define" + "math" + "time" +) + +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 HandleTimeout(order *models.UserOrder) error { + // 退还库存 + if order.GoodType == 4 { + err := HandleCancelOrder(order.OutTradeNo) + if err != nil { + logger.Error(err) + } + } + return nil +} diff --git a/services/pay/order.go b/services/pay/order.go index 6a1d911..1c7e697 100644 --- a/services/pay/order.go +++ b/services/pay/order.go @@ -62,7 +62,7 @@ func UnifiedOrder(content, openId string, fee, goodType, userId, activityId, exp pac := "prepay_id=" + resp["prepay_id"] paySign := pay_core.JsapiSign(client.AppId(), timestamp, nonceStr, pac, pay_core.SignType_MD5, define.ApiKey) - go PutOrderDelayQueue(userOrder) + //go PutOrderDelayQueue(userOrder) return map[string]interface{}{ "appid": client.AppId(), "timestamp": timestamp, @@ -90,7 +90,7 @@ func ReOrder(outTradeNo string) (map[string]interface{}, error) { //获取H5支付需要的paySign pac := "prepay_id=" + userOrder.PrepayId paySign := pay_core.JsapiSign(define.AppId, timestamp, nonceStr, pac, pay_core.SignType_MD5, define.ApiKey) - go PutOrderDelayQueue(userOrder) + //go PutOrderDelayQueue(userOrder) return map[string]interface{}{ "appid": define.AppId, "timestamp": timestamp, @@ -249,7 +249,7 @@ func Refund(reason, outTradeNo string) (map[string]string, error) { return nil, err } - go PutOrderDelayQueue(userOrder) // 退款查询 + //go PutOrderDelayQueue(userOrder) // 退款查询 return res, nil } diff --git a/test/order_test.go b/test/order_test.go index 27997c6..0b1d41f 100644 --- a/test/order_test.go +++ b/test/order_test.go @@ -39,3 +39,11 @@ func TestHandleReward(t *testing.T) { func TestLoggerLine(t *testing.T) { logger.Error("test") } + +func TestOrderQuery(t *testing.T) { + fmt.Println(pay_service.OrderQuery("xxxxxx")) +} + +func TestCloseOrder(t *testing.T) { + fmt.Println(pay_service.Close("xxxxxxx")) +}