593 lines
14 KiB
Go
593 lines
14 KiB
Go
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) SpecifyFindInBatches(ctx context.Context, req *bo.FindInBatchesBo, fun func(ctx context.Context, rows []*bo.OrderBo) error) error {
|
||
|
||
tx := p.DB(ctx).Where("activity_id = ''")
|
||
|
||
if req.ProductNo != "" {
|
||
tx = tx.Where("product_no = ?", req.ProductNo)
|
||
}
|
||
|
||
if req.StartTime != "" && req.EndTime != "" {
|
||
tx = tx.Where("receive_success_time BETWEEN ? AND ?", req.StartTime, req.EndTime)
|
||
}
|
||
|
||
if req.OrderNos != nil {
|
||
tx = tx.Where("order_no IN (?)", req.OrderNos)
|
||
}
|
||
|
||
if req.OutBizNos != nil {
|
||
tx = tx.Where("out_biz_no IN (?)", req.OutBizNos)
|
||
}
|
||
|
||
if req.VoucherNos != nil {
|
||
tx = tx.Where("voucher_no IN (?)", req.VoucherNos)
|
||
}
|
||
|
||
tx.Order("receive_success_time asc") // 显式清除排序,移除默认的 ORDER BY
|
||
|
||
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) FinSucByStockIdInBatches(ctx context.Context, req *do.WechatQuery, fun func(ctx context.Context, rows []*bo.OrderBo) error) error {
|
||
|
||
tx := p.DB(ctx).
|
||
Where("`status` in (?)", []uint8{vo.OrderStatusSuccess.GetValue(), vo.OrderStatusUse.GetValue(), vo.OrderStatusExpired.GetValue()}).
|
||
Where("activity_id = ''")
|
||
|
||
if req.ProductNo != "" {
|
||
tx = tx.Where("product_no = ?", req.ProductNo)
|
||
}
|
||
if req.BatchNo != "" {
|
||
tx = tx.Where("batch_no = ?", req.BatchNo)
|
||
}
|
||
if req.StartTime != "" {
|
||
tx = tx.Where("receive_success_time > ?", req.StartTime)
|
||
}
|
||
if req.EndTime != "" {
|
||
tx = tx.Where("receive_success_time <= ?", req.EndTime)
|
||
}
|
||
if req.OrderNo != "" {
|
||
tx = tx.Where("order_no = ?", req.OrderNo)
|
||
}
|
||
|
||
var results = make([]*model.Order, 0)
|
||
|
||
tx.Order("receive_success_time asc") // 显式清除排序,移除默认的 ORDER BY
|
||
|
||
result := tx.FindInBatches(&results, 1000, 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) FinUsedInBatches(ctx context.Context, req *do.WechatUsedQuery, fun func(ctx context.Context, rows []*bo.OrderBo) error) error {
|
||
|
||
var results = make([]*model.Order, 0)
|
||
|
||
tx := p.DB(ctx).
|
||
Where("`status` = ?", vo.OrderStatusUse.GetValue()).
|
||
Where("activity_id = ''")
|
||
|
||
if req.StartTime != "" {
|
||
tx = tx.Where("last_use_time > ?", req.StartTime)
|
||
}
|
||
if req.EndTime != "" {
|
||
tx = tx.Where("last_use_time <= ?", req.EndTime)
|
||
}
|
||
if req.ProductNo != "" {
|
||
tx = tx.Where("product_no = ?", req.ProductNo)
|
||
}
|
||
if req.BatchNo != "" {
|
||
tx = tx.Where("batch_no = ?", req.ProductNo)
|
||
}
|
||
if req.OrderNo != "" {
|
||
tx = tx.Where("order_no = ?", req.OrderNo)
|
||
}
|
||
|
||
// 显式清除排序,移除默认的 ORDER BY
|
||
result := tx.Order("last_use_time asc").FindInBatches(&results, 500, 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()).
|
||
// Order("receive_success_time asc"). // 显式清除排序,移除默认的 ORDER BY
|
||
// FindInBatches(&results, 200, 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).
|
||
// Order("receive_success_time asc"). // 显式清除排序,移除默认的 ORDER BY
|
||
// 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, req *bo.FindInBatchesUseBo, fun func(ctx context.Context, rows []*bo.OrderBo) error) error {
|
||
|
||
var results = make([]*model.Order, 0)
|
||
|
||
result := p.DB(ctx).
|
||
Where("activity_id = ''").
|
||
Where("`status` IN (?)", []uint8{vo.OrderStatusSuccess.GetValue(), vo.OrderStatusUse.GetValue()}).
|
||
Where("receive_success_time BETWEEN ? AND ?", req.StartTime, req.EndTime).
|
||
Order("receive_success_time asc"). // 显式清除排序,移除默认的 ORDER BY
|
||
FindInBatches(&results, 1000, 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) FindRetryQuery(ctx context.Context, req *do.RetryQueryNotice, fun func(ctx context.Context, rows []*bo.OrderBo) error) error {
|
||
|
||
statusArr := []uint8{
|
||
vo.OrderStatusSuccess.GetValue(),
|
||
vo.OrderStatusUse.GetValue(),
|
||
vo.OrderStatusExpired.GetValue(),
|
||
}
|
||
|
||
tx := p.DB(ctx).
|
||
Where("`status` in (?)", statusArr).
|
||
Where("activity_id = ''")
|
||
|
||
if req.ProductNo != "" {
|
||
tx = tx.Where("product_no = ?", req.ProductNo)
|
||
}
|
||
|
||
if req.ReceiveSuccessStartTime != "" {
|
||
tx = tx.Where("receive_success_time > ?", req.ReceiveSuccessStartTime)
|
||
}
|
||
if req.ReceiveSuccessEndTime != "" {
|
||
tx = tx.Where("receive_success_time <= ?", req.ReceiveSuccessEndTime)
|
||
}
|
||
|
||
if req.ProductNo != "" {
|
||
tx = tx.Where("product_no = ?", req.ProductNo)
|
||
}
|
||
|
||
if req.OrderNos != nil {
|
||
tx = tx.Where("order_no IN (?)", req.OrderNos)
|
||
}
|
||
|
||
if req.OutBizNos != nil {
|
||
tx = tx.Where("out_biz_no IN (?)", req.OutBizNos)
|
||
}
|
||
|
||
if req.VoucherNos != nil {
|
||
tx = tx.Where("voucher_no IN (?)", req.VoucherNos)
|
||
}
|
||
|
||
var results = make([]*model.Order, 0)
|
||
|
||
tx.Order("receive_success_time asc") // 显式清除排序,移除默认的 ORDER BY
|
||
|
||
result := tx.FindInBatches(&results, 1000, 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) 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,
|
||
|
||
ActivityId: req.ActivityId,
|
||
}
|
||
|
||
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) GetByCouponId(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 {
|
||
return nil, tx.Error
|
||
}
|
||
|
||
if tx.RowsAffected == 0 {
|
||
return nil, gorm.ErrRecordNotFound
|
||
}
|
||
|
||
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,
|
||
Remark: "成功",
|
||
ReceiveSuccessTime: &now,
|
||
UpdateTime: &now,
|
||
})
|
||
|
||
if tx.Error != nil {
|
||
return fmt.Errorf("update db fail %w", tx.Error)
|
||
}
|
||
|
||
if tx.RowsAffected == 0 {
|
||
return fmt.Errorf("no rows affected")
|
||
}
|
||
|
||
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(),
|
||
Remark: "重置为成功,领取成功时间重置",
|
||
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)
|
||
}
|
||
|
||
if tx.RowsAffected == 0 {
|
||
return fmt.Errorf("no rows affected")
|
||
}
|
||
|
||
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(),
|
||
Remark: "核销",
|
||
LastUseTime: &now,
|
||
UpdateTime: &now,
|
||
})
|
||
|
||
if tx.Error != nil {
|
||
return fmt.Errorf("update db fail %w", tx.Error)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
func (p *OrderRepoImpl) MultiLastUsed(ctx context.Context, id uint64, lastUseTime time.Time) error {
|
||
now := time.Now()
|
||
|
||
tx := p.DB(ctx).
|
||
Where(model.Order{
|
||
ID: id,
|
||
}).
|
||
Updates(model.Order{
|
||
Remark: "核销",
|
||
LastUseTime: &lastUseTime,
|
||
UpdateTime: &now,
|
||
})
|
||
|
||
if tx.Error != nil {
|
||
return fmt.Errorf("update db fail %w", tx.Error)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
|
||
func (p *OrderRepoImpl) MultiOverUsed(ctx context.Context, id uint64, lastUseTime time.Time, remark string) error {
|
||
now := time.Now()
|
||
|
||
tx := p.DB(ctx).
|
||
Where(model.Order{
|
||
ID: id,
|
||
}).
|
||
Updates(model.Order{
|
||
Status: vo.OrderStatusUse.GetValue(),
|
||
Remark: remark,
|
||
LastUseTime: &lastUseTime,
|
||
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, lastUseTime time.Time) error {
|
||
now := time.Now()
|
||
|
||
tx := p.DB(ctx).
|
||
Where(model.Order{
|
||
ID: id,
|
||
}).
|
||
Updates(model.Order{
|
||
Status: vo.OrderStatusUse.GetValue(),
|
||
TransactionId: transactionId,
|
||
Remark: "微信回调核销",
|
||
LastUseTime: &lastUseTime,
|
||
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(),
|
||
Remark: "过期",
|
||
UpdateTime: &now,
|
||
})
|
||
|
||
if tx.Error != nil {
|
||
return fmt.Errorf("update db fail %w", tx.Error)
|
||
}
|
||
|
||
return nil
|
||
}
|