14 changed files with 314 additions and 347 deletions
-
11controllers/client/good.go
-
6controllers/client/login.go
-
307controllers/client/order_entry.go
-
10controllers/pc/order_draw.go
-
1go.mod
-
2models/base.go
-
2models/customer_goods.go
-
19models/customer_order.go
-
26models/customer_order_option.go
-
18models/customer_order_sub.go
-
47models/user.go
-
3services/pay/handle.go
-
208services/pay/loop.go
-
1utils/code/code.go
@ -1,208 +0,0 @@ |
|||||
package pay_service |
|
||||
|
|
||||
import ( |
|
||||
"go.uber.org/zap" |
|
||||
"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 |
|
||||
} |
|
||||
|
|
||||
func init() { |
|
||||
//go loopTransfer()
|
|
||||
} |
|
||||
|
|
||||
var transferDelayQueue = make(chan *transferDelayQueueParam, math.MaxInt8) |
|
||||
|
|
||||
type transferDelayQueueParam struct { |
|
||||
first bool // 首次跳过
|
|
||||
Retries int `json:"retries"` // 尝试次数
|
|
||||
Delay int `json:"delay"` // 延迟时间, 单位second
|
|
||||
Amount int `json:"amount"` // 转账金额
|
|
||||
Desc string `json:"desc"` // 转账描述
|
|
||||
OpenId string `json:"open_id"` // 被转账人
|
|
||||
PartnerTradeNo string `json:"partner_trade_no"` // 转账账单单号
|
|
||||
} |
|
||||
|
|
||||
func loopTransfer() { |
|
||||
//初始化
|
|
||||
transfers, err := models.GetUserTransferByStatus(0, 1, 3) |
|
||||
if err != nil { |
|
||||
panic(err) |
|
||||
} |
|
||||
|
|
||||
transferDelayQueue = make(chan *transferDelayQueueParam, math.MaxInt8) |
|
||||
for _, transfer := range transfers { |
|
||||
transferDelayQueue <- &transferDelayQueueParam{ |
|
||||
first: true, |
|
||||
Retries: 5, |
|
||||
Delay: 2 * 60, |
|
||||
Amount: transfer.PaymentAmount, |
|
||||
Desc: transfer.Desc, |
|
||||
OpenId: transfer.OpenId, |
|
||||
PartnerTradeNo: transfer.PartnerTradeNo, |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
defer func() { |
|
||||
if errRec := recover(); errRec != nil { |
|
||||
logger.Error("转账轮询 loop transfer panic", zap.Any("错误原因", errRec)) |
|
||||
} |
|
||||
loopTransfer() |
|
||||
}() |
|
||||
for { |
|
||||
select { |
|
||||
case param, ok := <-transferDelayQueue: |
|
||||
if !ok { |
|
||||
panic("转账延迟通道异常关闭") |
|
||||
} |
|
||||
|
|
||||
// 尝试次数
|
|
||||
if param.Retries <= 0 { |
|
||||
logger.Info("微信转账尝试3次失败", zap.String("转账账单单号", param.PartnerTradeNo)) |
|
||||
userTransfer := new(models.UserTransfer) |
|
||||
userTransfer.Status = 4 |
|
||||
_, err = userTransfer.UpdateByPartnerTradeNo(param.PartnerTradeNo) |
|
||||
if err != nil { |
|
||||
logger.Info("微信转账更新状态失败", zap.String("失败原因", err.Error()), |
|
||||
zap.String("转账账单单号", param.PartnerTradeNo)) |
|
||||
} |
|
||||
continue |
|
||||
} else { |
|
||||
param.Retries-- |
|
||||
} |
|
||||
|
|
||||
if !param.first { |
|
||||
time.Sleep(time.Duration(param.Delay) * time.Second) |
|
||||
} |
|
||||
param.first = false |
|
||||
res, err := TransferInfo(param.PartnerTradeNo) |
|
||||
if err != nil { |
|
||||
logger.Error("微信转账查询出现的错误", zap.String("错误原因", err.Error()), |
|
||||
zap.String("转账账单", param.PartnerTradeNo)) |
|
||||
transferDelayQueue <- param |
|
||||
continue |
|
||||
} |
|
||||
|
|
||||
if res.Status == define.CODE_SUCCESS { |
|
||||
continue |
|
||||
} else if res.Status == define.CODE_TRANSFER_PROCESSING { |
|
||||
transferDelayQueue <- param |
|
||||
continue |
|
||||
} else { |
|
||||
//失败 --> 重新转账
|
|
||||
_, err = Transfer(param.Desc, param.OpenId, param.PartnerTradeNo, param.Amount) |
|
||||
if err != nil { |
|
||||
logger.Error("微信转账出现的错误", zap.String("错误原因", err.Error()), |
|
||||
zap.String("转账账单", param.PartnerTradeNo)) |
|
||||
} |
|
||||
transferDelayQueue <- param // 重新确认
|
|
||||
continue |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
func PutTransferDelayQueue(desc, openId, partnerTradeNo string, amount, retries, delay int) { |
|
||||
if retries <= 0 { |
|
||||
retries = 3 |
|
||||
} |
|
||||
if delay == 0 { |
|
||||
delay = 30 |
|
||||
} |
|
||||
transferDelayQueue <- &transferDelayQueueParam{ |
|
||||
first: true, |
|
||||
Retries: retries, |
|
||||
Delay: delay, |
|
||||
Amount: amount, |
|
||||
Desc: desc, |
|
||||
OpenId: openId, |
|
||||
PartnerTradeNo: partnerTradeNo, |
|
||||
} |
|
||||
} |
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue