voucher/internal/data/repoimpl/order.go

396 lines
9.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package repoimpl
import (
"context"
"errors"
"fmt"
"gorm.io/gorm"
"time"
"unicode/utf8"
err2 "voucher/api/err"
"voucher/internal/biz/bo"
"voucher/internal/biz/do"
"voucher/internal/biz/repo"
"voucher/internal/biz/vo"
"voucher/internal/data"
"voucher/internal/data/model"
)
// OrderRepoImpl .
type OrderRepoImpl struct {
Base[model.Order, bo.OrderBo]
db *data.Db
}
// NewOrderRepoImpl .
func NewOrderRepoImpl(db *data.Db) repo.OrderRepo {
return &OrderRepoImpl{db: db}
}
func (p *OrderRepoImpl) DB(ctx context.Context) *gorm.DB {
return p.db.DB(ctx).Model(model.Order{})
}
func (p *OrderRepoImpl) FinSucByStockIdInBatches(ctx context.Context, req *do.WechatQuery, fun func(ctx context.Context, rows []*bo.OrderBo) error) error {
tx := p.DB(ctx).Where("status = ?", vo.OrderStatusSuccess.GetValue())
if req.ProductNo != "" {
tx = tx.Where("product_no = ?", req.ProductNo)
}
if req.StartTime != "" {
tx = tx.Where("receive_success_time >= ?", req.StartTime)
}
if req.EndTime != "" {
tx = tx.Where("receive_success_time <= ?", req.EndTime)
}
var results = make([]*model.Order, 0)
result := tx.FindInBatches(&results, 100, func(tx *gorm.DB, batch int) error {
return fun(ctx, p.ToBos(results))
})
if result.Error != nil {
return result.Error
}
return nil
}
func (p *OrderRepoImpl) FinFailByStockIdInBatches(ctx context.Context, batchNo string, fun func(ctx context.Context, rows []*bo.OrderBo) error) error {
var results = make([]*model.Order, 0)
result := p.DB(ctx).
Where("batch_no = ?", batchNo).
Where("status = ?", vo.OrderStatusFail.GetValue()).
//Where("remark <> ?", "error: code = 500 reason = WechatFAIL message = 微信返回错误:该用户账号异常,无法领券。商家可联系微信支付或让用户联系微信支付客服处理。 metadat").
FindInBatches(&results, 100, func(tx *gorm.DB, batch int) error {
return fun(ctx, p.ToBos(results))
})
if result.Error != nil {
return result.Error
}
return nil
}
func (p *OrderRepoImpl) FindIngInBatches(ctx context.Context, fun func(ctx context.Context, rows []*bo.OrderBo) error) error {
var results = make([]*model.Order, 0)
result := p.DB(ctx).
Where("status = ?", vo.OrderStatusIng.GetValue()).
Limit(20).
FindInBatches(&results, 10, func(tx *gorm.DB, batch int) error {
return fun(ctx, p.ToBos(results))
})
if result.Error != nil {
return result.Error
}
return nil
}
func (p *OrderRepoImpl) FindInBatches(ctx context.Context, w *bo.FindInBatchesUseBo, fun func(ctx context.Context, rows []*bo.OrderBo) error) error {
var results = make([]*model.Order, 0)
result := p.DB(ctx).
Where("status IN (?)", []uint8{vo.OrderStatusSuccess.GetValue(), vo.OrderStatusUse.GetValue()}).
Where("receive_success_time BETWEEN ? AND ?", w.StartTime, w.EndTime).
FindInBatches(&results, 100, func(tx *gorm.DB, batch int) error {
// tx.RowsAffected 提供当前批处理中记录的计数the count of records in the current batch
// 'batch' 变量表示当前批号the current batch number
// 返回 error 将阻止更多的批处理
return fun(ctx, p.ToBos(results))
})
if result.Error != nil {
return result.Error
}
return nil
}
func (p *OrderRepoImpl) Create(ctx context.Context, req *bo.OrderBo) (*bo.OrderBo, error) {
now := time.Now()
info := &model.Order{
OrderNo: req.OrderNo,
OutBizNo: req.OutBizNo,
ProductNo: req.ProductNo,
BatchNo: req.BatchNo,
Account: req.Account,
AccountType: req.AccountType.GetValue(),
Status: req.Status.GetValue(),
Type: req.Type.GetValue(),
AppID: req.AppID,
MerchantNo: req.MerchantNo,
Channel: req.Channel.GetValue(),
NotifyUrl: req.NotifyUrl,
Attach: req.Attach,
CreateTime: &now,
UpdateTime: &now,
}
tx := p.DB(ctx).Create(info)
if tx.Error != nil {
return nil, fmt.Errorf("create db fail %w", tx.Error)
}
return p.ToBo(info), nil
}
func (p *OrderRepoImpl) GetByOutBizNo(ctx context.Context, t vo.OrderType, outBizNo string) (*bo.OrderBo, error) {
info := &model.Order{}
tx := p.DB(ctx).Where(model.Order{Type: t.GetValue(), OutBizNo: outBizNo}).First(&info)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, err2.ErrorDbNotFound("订单数据不存在")
}
return nil, fmt.Errorf("order db fail %w", tx.Error)
}
if tx.RowsAffected == 0 {
return nil, err2.ErrorDbNotFound("订单数据不存在")
}
return p.ToBo(info), nil
}
func (p *OrderRepoImpl) GetByID(ctx context.Context, id uint64) (*bo.OrderBo, error) {
info := &model.Order{}
tx := p.DB(ctx).Where(model.Order{ID: id}).First(&info)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, err2.ErrorDbNotFound("订单数据不存在")
}
return nil, fmt.Errorf("order db fail %w", tx.Error)
}
if tx.RowsAffected == 0 {
return nil, err2.ErrorDbNotFound("订单数据不存在")
}
return p.ToBo(info), nil
}
func (p *OrderRepoImpl) GetByOrderNo(ctx context.Context, orderNo string) (*bo.OrderBo, error) {
info := &model.Order{}
tx := p.DB(ctx).Where(model.Order{OrderNo: orderNo}).First(&info)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, err2.ErrorDbNotFound("订单数据不存在")
}
return nil, fmt.Errorf("order db fail %w", tx.Error)
}
if tx.RowsAffected == 0 {
return nil, err2.ErrorDbNotFound("订单数据不存在")
}
return p.ToBo(info), nil
}
func (p *OrderRepoImpl) GetByVoucherNo(ctx context.Context, merchantNo, batchNo, voucherNo string) (*bo.OrderBo, error) {
info := &model.Order{}
tx := p.DB(ctx).Where(model.Order{MerchantNo: merchantNo, BatchNo: batchNo, VoucherNo: voucherNo}).First(&info)
if tx.Error != nil {
if errors.Is(tx.Error, gorm.ErrRecordNotFound) {
return nil, err2.ErrorDbNotFound("订单数据不存在")
}
return nil, fmt.Errorf("db fail %w", tx.Error)
}
if tx.RowsAffected == 0 {
return nil, err2.ErrorDbNotFound("订单数据不存在")
}
return p.ToBo(info), nil
}
func (this *OrderRepoImpl) GetByTransactionId(ctx context.Context, stockCreatorMchId, stockID, transactionId string) (*bo.OrderBo, error) {
row := &model.Order{}
tx := this.DB(ctx).Where(model.Order{MerchantNo: stockCreatorMchId, BatchNo: stockID, TransactionId: transactionId}).First(&row)
if tx.Error != nil {
return nil, tx.Error
}
if tx.RowsAffected == 0 {
return nil, gorm.ErrRecordNotFound
}
return this.ToBo(row), nil
}
func (p *OrderRepoImpl) Ing(ctx context.Context, id uint64) error {
now := time.Now()
tx := p.DB(ctx).
Where(model.Order{
ID: id,
Status: vo.OrderStatusWait.GetValue(),
}).
Updates(model.Order{
Status: vo.OrderStatusIng.GetValue(),
UpdateTime: &now,
})
if tx.Error != nil {
return fmt.Errorf("db fail %w", tx.Error)
}
return nil
}
func (p *OrderRepoImpl) Success(ctx context.Context, id uint64, voucherNo string) error {
now := time.Now()
tx := p.DB(ctx).
Where(model.Order{
ID: id,
}).
Updates(model.Order{
Status: vo.OrderStatusSuccess.GetValue(),
VoucherNo: voucherNo,
ReceiveSuccessTime: &now,
UpdateTime: &now,
})
if tx.Error != nil {
return fmt.Errorf("update db fail %w", tx.Error)
}
return nil
}
func (p *OrderRepoImpl) Available(ctx context.Context, id uint64) error {
now := time.Now()
tx := p.DB(ctx).
Where(model.Order{
ID: id,
Status: vo.OrderStatusUse.GetValue(),
}).
Updates(model.Order{
Status: vo.OrderStatusSuccess.GetValue(),
ReceiveSuccessTime: &now, // 领取成功时间重置
UpdateTime: &now,
})
if tx.Error != nil {
return fmt.Errorf("update db fail %w", tx.Error)
}
return nil
}
func (p *OrderRepoImpl) Fail(ctx context.Context, id uint64, remark string) error {
now := time.Now()
if utf8.RuneCountInString(remark) > 100 {
runes := []rune(remark)
if len(runes) > 100 {
remark = string(runes[:100])
}
}
tx := p.DB(ctx).
Where(model.Order{
ID: id,
}).
Updates(model.Order{
Status: vo.OrderStatusFail.GetValue(),
Remark: remark,
UpdateTime: &now,
})
if tx.Error != nil {
return fmt.Errorf("update db fail %w", tx.Error)
}
return nil
}
func (p *OrderRepoImpl) Used(ctx context.Context, id uint64) error {
now := time.Now()
tx := p.DB(ctx).
Where(model.Order{
ID: id,
}).
Updates(model.Order{
Status: vo.OrderStatusUse.GetValue(),
LastUseTime: &now,
UpdateTime: &now,
})
if tx.Error != nil {
return fmt.Errorf("update db fail %w", tx.Error)
}
return nil
}
func (p *OrderRepoImpl) NotifyUsed(ctx context.Context, id uint64, transactionId string) error {
now := time.Now()
tx := p.DB(ctx).
Where(model.Order{
ID: id,
}).
Updates(model.Order{
Status: vo.OrderStatusUse.GetValue(),
TransactionId: transactionId,
LastUseTime: &now,
UpdateTime: &now,
})
if tx.Error != nil {
return fmt.Errorf("update db fail %w", tx.Error)
}
return nil
}
func (p *OrderRepoImpl) Expired(ctx context.Context, id uint64) error {
now := time.Now()
tx := p.DB(ctx).
Where(model.Order{
ID: id,
}).
Updates(model.Order{
Status: vo.OrderStatusExpired.GetValue(),
UpdateTime: &now,
})
if tx.Error != nil {
return fmt.Errorf("update db fail %w", tx.Error)
}
return nil
}