Compare commits
No commits in common. "08355a0fa8b9ad8f830cb2d7c38c30171b4fe1ef" and "b5b07a4d79325e445b3b3a0aa648190376b6d3ca" have entirely different histories.
08355a0fa8
...
b5b07a4d79
|
|
@ -22,8 +22,6 @@ Thumbs.db
|
||||||
*.swp
|
*.swp
|
||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
.trae/
|
|
||||||
|
|
||||||
bin/
|
bin/
|
||||||
cert/
|
cert/
|
||||||
log
|
log
|
||||||
|
|
|
||||||
|
|
@ -16,19 +16,6 @@ type ConsumeInformation struct {
|
||||||
ConsumeAmount int `json:"consume_amount"` // 核销金额(单位:分) // 多笔立减金必须 validate:"required"
|
ConsumeAmount int `json:"consume_amount"` // 核销金额(单位:分) // 多笔立减金必须 validate:"required"
|
||||||
}
|
}
|
||||||
|
|
||||||
// CombineSubOrder 定义合单子单消费信息结构体
|
|
||||||
type CombineSubOrder struct {
|
|
||||||
TransactionID string `json:"transaction_id" validate:"required"` // 合单子单微信支付订单号
|
|
||||||
ConsumeAmount int `json:"comsume_amount" validate:"required"` // 子单核销金额,微信文档字段名如此定义
|
|
||||||
ConsumeTime time.Time `json:"consume_time" validate:"required"` // 子单核销时间
|
|
||||||
}
|
|
||||||
|
|
||||||
// CombineOrderInfo 定义合单订单信息结构体
|
|
||||||
type CombineOrderInfo struct {
|
|
||||||
CombineConsumeAmount int `json:"combine_consume_amount"` // 合单总核销金额
|
|
||||||
SubOrders []CombineSubOrder `json:"sub_orders,omitempty"` // 合单子单列表
|
|
||||||
}
|
|
||||||
|
|
||||||
// PlainText 定义明文数据结构体
|
// PlainText 定义明文数据结构体
|
||||||
type PlainText struct {
|
type PlainText struct {
|
||||||
StockCreatorMchid string `json:"stock_creator_mchid" validate:"required"`
|
StockCreatorMchid string `json:"stock_creator_mchid" validate:"required"`
|
||||||
|
|
@ -42,9 +29,7 @@ type PlainText struct {
|
||||||
NoCash bool `json:"no_cash"`
|
NoCash bool `json:"no_cash"`
|
||||||
Singleitem bool `json:"singleitem"`
|
Singleitem bool `json:"singleitem"`
|
||||||
BusinessType string `json:"business_type"` // 业务类型
|
BusinessType string `json:"business_type"` // 业务类型
|
||||||
IsCombineOrder bool `json:"is_combine_order,omitempty"`
|
|
||||||
ConsumeInformation *ConsumeInformation `json:"consume_information,omitempty"`
|
ConsumeInformation *ConsumeInformation `json:"consume_information,omitempty"`
|
||||||
CombineOrderInfo *CombineOrderInfo `json:"combine_order_info,omitempty"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type WechatVoucherNotifyBo struct {
|
type WechatVoucherNotifyBo struct {
|
||||||
|
|
@ -78,39 +63,3 @@ func (c *WechatVoucherNotifyBo) Validate() error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *WechatVoucherNotifyBo) ValidateMultiNotify() error {
|
|
||||||
if err := c.Validate(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.PlainText.IsCombineOrder {
|
|
||||||
if c.PlainText.CombineOrderInfo == nil {
|
|
||||||
return fmt.Errorf("合单订单信息不能为空")
|
|
||||||
}
|
|
||||||
if len(c.PlainText.CombineOrderInfo.SubOrders) == 0 {
|
|
||||||
return fmt.Errorf("合单子单不能为空")
|
|
||||||
}
|
|
||||||
for _, subOrder := range c.PlainText.CombineOrderInfo.SubOrders {
|
|
||||||
if subOrder.TransactionID == "" {
|
|
||||||
return fmt.Errorf("合单子单微信支付订单号不能为空")
|
|
||||||
}
|
|
||||||
if subOrder.ConsumeAmount <= 0 {
|
|
||||||
return fmt.Errorf("合单子单核销金额必须大于0")
|
|
||||||
}
|
|
||||||
if subOrder.ConsumeTime.IsZero() {
|
|
||||||
return fmt.Errorf("合单子单核销时间不能为空")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if c.PlainText.ConsumeInformation == nil {
|
|
||||||
return fmt.Errorf("消费信息不能为空")
|
|
||||||
}
|
|
||||||
if c.PlainText.ConsumeInformation.ConsumeAmount <= 0 {
|
|
||||||
return fmt.Errorf("消费金额必须大于0")
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -71,8 +71,8 @@ func (biz *MultiBiz) Notify(ctx context.Context, ip, source string, req *bo.Wech
|
||||||
|
|
||||||
return lock.NewMutex(biz.rdb.Rdb, cl.TTL).Lock(ctx, cl.Key, func(ctx context.Context) error {
|
return lock.NewMutex(biz.rdb.Rdb, cl.TTL).Lock(ctx, cl.Key, func(ctx context.Context) error {
|
||||||
|
|
||||||
if err = req.ValidateMultiNotify(); err != nil {
|
if req.PlainText.ConsumeInformation.ConsumeAmount == 0 {
|
||||||
return fmt.Errorf("multi validate req error: %v", err)
|
return fmt.Errorf("消费金额不能为0")
|
||||||
}
|
}
|
||||||
|
|
||||||
order, err := biz.order(ctx, req)
|
order, err := biz.order(ctx, req)
|
||||||
|
|
@ -115,7 +115,7 @@ func (biz *MultiBiz) Run(ctx context.Context, ip, source string, req *bo.WechatV
|
||||||
}
|
}
|
||||||
|
|
||||||
if mnd != nil {
|
if mnd != nil {
|
||||||
if !req.PlainText.IsCombineOrder && mnd.NoticeNum > 0 {
|
if mnd.NoticeNum > 0 {
|
||||||
log.Warnf("[%s] multi notify log already exists,req:%+v", source, req)
|
log.Warnf("[%s] multi notify log already exists,req:%+v", source, req)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -150,14 +150,6 @@ func (biz *MultiBiz) RetryRunByMultiNotifyDataId(ctx context.Context, multiNotif
|
||||||
}
|
}
|
||||||
|
|
||||||
func (biz *MultiBiz) run(ctx context.Context, req *bo.WechatVoucherNotifyBo, mnd *bo.MultiNotifyDataBo, order *bo.OrderBo) error {
|
func (biz *MultiBiz) run(ctx context.Context, req *bo.WechatVoucherNotifyBo, mnd *bo.MultiNotifyDataBo, order *bo.OrderBo) error {
|
||||||
if req.PlainText.IsCombineOrder {
|
|
||||||
return biz.runCombine(ctx, req, mnd, order)
|
|
||||||
}
|
|
||||||
|
|
||||||
return biz.runSingle(ctx, req, mnd, order)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (biz *MultiBiz) runSingle(ctx context.Context, req *bo.WechatVoucherNotifyBo, mnd *bo.MultiNotifyDataBo, order *bo.OrderBo) error {
|
|
||||||
// 如果核销金额为空,不再推送下游
|
// 如果核销金额为空,不再推送下游
|
||||||
if mnd.ConsumeAmount == 0 {
|
if mnd.ConsumeAmount == 0 {
|
||||||
log.Warnf("[%s] multi notify log consume amount is 0,req:%+v", mnd.NotifyID, req)
|
log.Warnf("[%s] multi notify log consume amount is 0,req:%+v", mnd.NotifyID, req)
|
||||||
|
|
@ -173,50 +165,20 @@ func (biz *MultiBiz) runSingle(ctx context.Context, req *bo.WechatVoucherNotifyB
|
||||||
return fmt.Errorf("请求错误 error: %v", err)
|
return fmt.Errorf("请求错误 error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return biz.updateOrderStatus(ctx, req, order)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (biz *MultiBiz) runCombine(ctx context.Context, req *bo.WechatVoucherNotifyBo, mnd *bo.MultiNotifyDataBo, order *bo.OrderBo) error {
|
|
||||||
for _, subOrder := range req.PlainText.CombineOrderInfo.SubOrders {
|
|
||||||
exists, err := biz.MultiNotifyLogRepo.ExistsSuccessByDataIDAndTransactionID(ctx, mnd.ID, subOrder.TransactionID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("查询合单子单通知记录错误 error: %v", err)
|
|
||||||
}
|
|
||||||
if exists {
|
|
||||||
log.Warnf("[%s] combine sub order already notified,transaction_id:%s", mnd.NotifyID, subOrder.TransactionID)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
nl, request, err := biz.nlCreateBySubOrder(ctx, req, mnd, order, subOrder)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("创建合单子单通知日志错误 error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = biz.Request(ctx, mnd, nl, request); err != nil {
|
|
||||||
return fmt.Errorf("合单子单请求错误 error: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return biz.updateOrderStatus(ctx, req, order)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (biz *MultiBiz) updateOrderStatus(ctx context.Context, req *bo.WechatVoucherNotifyBo, order *bo.OrderBo) error {
|
|
||||||
consumeTime := req.PlainText.ConsumeInformation.ConsumeTime
|
|
||||||
|
|
||||||
if req.PlainText.Status.IsUsed() {
|
if req.PlainText.Status.IsUsed() {
|
||||||
|
|
||||||
if order.Status.IsUse() {
|
if order.Status.IsUse() {
|
||||||
if err := biz.OrderRepo.MultiOverUsed(ctx, order.ID, consumeTime, "再次核销完成"); err != nil {
|
if err = biz.OrderRepo.MultiOverUsed(ctx, order.ID, req.PlainText.ConsumeInformation.ConsumeTime, "再次核销完成"); err != nil {
|
||||||
return fmt.Errorf("订单再次核销完成修改发生错误 error: %v", err)
|
return fmt.Errorf("订单再次核销完成修改发生错误 error: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if err := biz.OrderRepo.MultiOverUsed(ctx, order.ID, consumeTime, "核销完成"); err != nil {
|
if err = biz.OrderRepo.MultiOverUsed(ctx, order.ID, req.PlainText.ConsumeInformation.ConsumeTime, "核销完成"); err != nil {
|
||||||
return fmt.Errorf("订单核销完成修改发生错误 error: %v", err)
|
return fmt.Errorf("订单核销完成修改发生错误 error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if err := biz.OrderRepo.MultiLastUsed(ctx, order.ID, consumeTime); err != nil {
|
if err = biz.OrderRepo.MultiLastUsed(ctx, order.ID, req.PlainText.ConsumeInformation.ConsumeTime); err != nil {
|
||||||
return fmt.Errorf("订单核销修改发生错误 error: %v", err)
|
return fmt.Errorf("订单核销修改发生错误 error: %v", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -231,13 +193,6 @@ func (biz *MultiBiz) mndCreate(ctx context.Context, ip, source string, req *bo.W
|
||||||
return nil, fmt.Errorf("通知数据 json str 错误 error: %v", err)
|
return nil, fmt.Errorf("通知数据 json str 错误 error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
consumeAmount := int32(req.PlainText.ConsumeInformation.ConsumeAmount)
|
|
||||||
consumeTime := &req.PlainText.ConsumeInformation.ConsumeTime
|
|
||||||
transactionID := req.PlainText.ConsumeInformation.TransactionID
|
|
||||||
if req.PlainText.IsCombineOrder {
|
|
||||||
consumeAmount = int32(req.PlainText.CombineOrderInfo.CombineConsumeAmount)
|
|
||||||
}
|
|
||||||
|
|
||||||
return biz.MultiNotifyDataRepo.Create(ctx, &bo.MultiNotifyDataBo{
|
return biz.MultiNotifyDataRepo.Create(ctx, &bo.MultiNotifyDataBo{
|
||||||
Source: source,
|
Source: source,
|
||||||
IP: ip,
|
IP: ip,
|
||||||
|
|
@ -246,57 +201,15 @@ func (biz *MultiBiz) mndCreate(ctx context.Context, ip, source string, req *bo.W
|
||||||
OutBizNo: order.OutBizNo,
|
OutBizNo: order.OutBizNo,
|
||||||
CouponID: req.PlainText.CouponID,
|
CouponID: req.PlainText.CouponID,
|
||||||
StockID: req.PlainText.StockID,
|
StockID: req.PlainText.StockID,
|
||||||
ConsumeAmount: consumeAmount,
|
ConsumeAmount: int32(req.PlainText.ConsumeInformation.ConsumeAmount),
|
||||||
ConsumeTime: consumeTime,
|
ConsumeTime: &req.PlainText.ConsumeInformation.ConsumeTime,
|
||||||
TransactionID: transactionID,
|
TransactionID: req.PlainText.ConsumeInformation.TransactionID,
|
||||||
EventType: req.EventType,
|
EventType: req.EventType,
|
||||||
Status: req.PlainText.Status,
|
Status: req.PlainText.Status,
|
||||||
OriginalData: originalData,
|
OriginalData: originalData,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (biz *MultiBiz) nlCreateBySubOrder(ctx context.Context, req *bo.WechatVoucherNotifyBo, mnd *bo.MultiNotifyDataBo, order *bo.OrderBo, subOrder bo.CombineSubOrder) (*bo.MultiNotifyLogBo, *v1.CmbRequest, error) {
|
|
||||||
if biz.bc.Cmb.MultiNotifyUrl == "" {
|
|
||||||
return nil, nil, fmt.Errorf("CMB多笔立减金通知地址为空")
|
|
||||||
}
|
|
||||||
|
|
||||||
consumeTime := subOrder.ConsumeTime
|
|
||||||
nl := &bo.MultiNotifyLogBo{
|
|
||||||
MultiNotifyDataID: mnd.ID,
|
|
||||||
OrderNo: mnd.OrderNo,
|
|
||||||
OutBizNo: mnd.OutBizNo,
|
|
||||||
CouponID: mnd.CouponID,
|
|
||||||
ActivityNo: order.ProductNo,
|
|
||||||
StockID: mnd.StockID,
|
|
||||||
EventType: mnd.EventType,
|
|
||||||
Status: req.PlainText.Status,
|
|
||||||
ConsumeAmount: int32(subOrder.ConsumeAmount),
|
|
||||||
ConsumeTime: &consumeTime,
|
|
||||||
TransactionID: subOrder.TransactionID,
|
|
||||||
RequestURL: biz.bc.Cmb.MultiNotifyUrl,
|
|
||||||
RequestStatus: vo.MultiNotifyLogStatusWait.GetValue(),
|
|
||||||
OrderCreateTime: order.CreateTime,
|
|
||||||
CouponCreateTime: &req.PlainText.CreateTime,
|
|
||||||
}
|
|
||||||
|
|
||||||
request, cmbRequestBo, err := biz.GetRequest(ctx, nl, order)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
b, _ := json.Marshal(request)
|
|
||||||
nl.OriginReq = cmbRequestBo.BizContent
|
|
||||||
nl.Request = string(b)
|
|
||||||
|
|
||||||
res, err := biz.MultiNotifyLogRepo.Create(ctx, nl)
|
|
||||||
if err != nil {
|
|
||||||
return nil, nil, fmt.Errorf("创建通知日志错误 error: %v", err)
|
|
||||||
}
|
|
||||||
res.ConsumeTime = nl.ConsumeTime
|
|
||||||
|
|
||||||
return res, request, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (biz *MultiBiz) nlCreate(ctx context.Context, req *bo.WechatVoucherNotifyBo, mnd *bo.MultiNotifyDataBo, order *bo.OrderBo) (*bo.MultiNotifyLogBo, *v1.CmbRequest, error) {
|
func (biz *MultiBiz) nlCreate(ctx context.Context, req *bo.WechatVoucherNotifyBo, mnd *bo.MultiNotifyDataBo, order *bo.OrderBo) (*bo.MultiNotifyLogBo, *v1.CmbRequest, error) {
|
||||||
|
|
||||||
if biz.bc.Cmb.MultiNotifyUrl == "" {
|
if biz.bc.Cmb.MultiNotifyUrl == "" {
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import (
|
||||||
type MultiNotifyLogRepo interface {
|
type MultiNotifyLogRepo interface {
|
||||||
Create(ctx context.Context, req *bo.MultiNotifyLogBo) (*bo.MultiNotifyLogBo, error)
|
Create(ctx context.Context, req *bo.MultiNotifyLogBo) (*bo.MultiNotifyLogBo, error)
|
||||||
GetByID(ctx context.Context, id int64) (*bo.MultiNotifyLogBo, error)
|
GetByID(ctx context.Context, id int64) (*bo.MultiNotifyLogBo, error)
|
||||||
ExistsSuccessByDataIDAndTransactionID(ctx context.Context, multiNotifyDataID int64, transactionID string) (bool, error)
|
|
||||||
Success(ctx context.Context, id int64, response string) error
|
Success(ctx context.Context, id int64, response string) error
|
||||||
Fail(ctx context.Context, id int64, remark string) error
|
Fail(ctx context.Context, id int64, remark string) error
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ func (this *VoucherBiz) WechatNotifyConsumer(ctx context.Context, ip string, req
|
||||||
}
|
}
|
||||||
|
|
||||||
if order.ActivityId != "" {
|
if order.ActivityId != "" {
|
||||||
if err = req.ValidateMultiNotify(); err != nil {
|
if err = req.Validate(); err != nil {
|
||||||
return fmt.Errorf("multi validate req error: %v", err)
|
return fmt.Errorf("multi validate req error: %v", err)
|
||||||
}
|
}
|
||||||
return this.MultiBiz.Run(ctx, ip, req.PlainText.StockCreatorMchid, req, order)
|
return this.MultiBiz.Run(ctx, ip, req.PlainText.StockCreatorMchid, req, order)
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@ package repoimpl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"gorm.io/gorm"
|
||||||
"time"
|
"time"
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
err2 "voucher/api/err"
|
err2 "voucher/api/err"
|
||||||
|
|
@ -12,8 +12,6 @@ import (
|
||||||
"voucher/internal/biz/vo"
|
"voucher/internal/biz/vo"
|
||||||
"voucher/internal/data"
|
"voucher/internal/data"
|
||||||
"voucher/internal/data/model"
|
"voucher/internal/data/model"
|
||||||
|
|
||||||
"gorm.io/gorm"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MultiNotifyLogRepoImpl .
|
// MultiNotifyLogRepoImpl .
|
||||||
|
|
@ -79,24 +77,6 @@ func (p *MultiNotifyLogRepoImpl) GetByID(ctx context.Context, id int64) (*bo.Mul
|
||||||
return p.ToBo(&item), nil
|
return p.ToBo(&item), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *MultiNotifyLogRepoImpl) ExistsSuccessByDataIDAndTransactionID(ctx context.Context, multiNotifyDataID int64, transactionID string) (bool, error) {
|
|
||||||
var item model.MultiNotifyLog
|
|
||||||
|
|
||||||
err := p.DB(ctx).
|
|
||||||
Select("id").
|
|
||||||
Where("multi_notify_data_id = ? AND transaction_id = ? AND request_status = ?", multiNotifyDataID, transactionID, vo.MultiNotifyLogStatusSuccess.GetValue()).
|
|
||||||
Limit(1).
|
|
||||||
Take(&item).Error
|
|
||||||
if err != nil {
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *MultiNotifyLogRepoImpl) Success(ctx context.Context, id int64, response string) error {
|
func (p *MultiNotifyLogRepoImpl) Success(ctx context.Context, id int64, response string) error {
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue