voucher/internal/data/repoimpl/order.go

304 lines
7.0 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"
"github.com/go-kratos/kratos/v2/log"
"gorm.io/gorm"
"time"
"unicode/utf8"
err2 "voucher/api/err"
"voucher/internal/biz/bo"
"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).WithContext(ctx).Model(model.Order{})
}
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("type = ?", w.Type).
Where("status IN (?)", []uint8{vo.OrderStatusSuccess.GetValue(), vo.OrderStatusUse.GetValue()}).
Where("receive_success_time BETWEEN ? AND ?", w.StartTime, w.EndTime).
Where("product_no <> ?", "001"). // 跳过压测的订单数据
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,
}
if req.ProductNo == "001" {
info.VoucherNo = req.OrderNo
info.Status = vo.OrderStatusSuccess.GetValue()
}
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{}
db := p.DB(ctx)
tx := db.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("订单数据不存在")
}
if errors.Is(tx.Error, context.DeadlineExceeded) {
sqlDB, _ := db.DB()
log.Warnf("order当前打开连接数:%d,空闲连接数:%d", sqlDB.Stats().OpenConnections, sqlDB.Stats().Idle)
}
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 (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,
Status: vo.OrderStatusIng.GetValue(),
}).
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) 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
}