96 lines
3.5 KiB
Go
96 lines
3.5 KiB
Go
package repository
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
"pay-bridge/internal/model"
|
|
)
|
|
|
|
// PaymentMatchRepository 收款匹配数据访问
|
|
type PaymentMatchRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewPaymentMatchRepository(db *gorm.DB) *PaymentMatchRepository {
|
|
return &PaymentMatchRepository{db: db}
|
|
}
|
|
|
|
// GetAccountByNo 按账号查询子商户收款账户
|
|
func (r *PaymentMatchRepository) GetAccountByNo(ctx context.Context, accountNo string) (*model.SubMerchantAccount, error) {
|
|
var acc model.SubMerchantAccount
|
|
err := r.db.WithContext(ctx).Where("account_no = ? AND status = 1", accountNo).First(&acc).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, nil
|
|
}
|
|
return &acc, err
|
|
}
|
|
|
|
// GetAccountByID 按 id 查询
|
|
func (r *PaymentMatchRepository) GetAccountByID(ctx context.Context, id uint64) (*model.SubMerchantAccount, error) {
|
|
var acc model.SubMerchantAccount
|
|
err := r.db.WithContext(ctx).Where("id = ?", id).First(&acc).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, nil
|
|
}
|
|
return &acc, err
|
|
}
|
|
|
|
// ListAccountsByApp 查询应用下所有收款账户
|
|
func (r *PaymentMatchRepository) ListAccountsByApp(ctx context.Context, appID string) ([]*model.SubMerchantAccount, error) {
|
|
var accs []*model.SubMerchantAccount
|
|
err := r.db.WithContext(ctx).Where("app_id = ? AND status = 1", appID).Find(&accs).Error
|
|
return accs, err
|
|
}
|
|
|
|
// CreateAccount 创建收款账户
|
|
func (r *PaymentMatchRepository) CreateAccount(ctx context.Context, acc *model.SubMerchantAccount) error {
|
|
return r.db.WithContext(ctx).Create(acc).Error
|
|
}
|
|
|
|
// CreateMatchLog 创建匹配记录
|
|
func (r *PaymentMatchRepository) CreateMatchLog(ctx context.Context, log *model.PaymentMatchLog) error {
|
|
return r.db.WithContext(ctx).Create(log).Error
|
|
}
|
|
|
|
// GetMatchLogByBillNo 按渠道流水号查询(幂等检查)
|
|
func (r *PaymentMatchRepository) GetMatchLogByBillNo(ctx context.Context, channelBillNo string) (*model.PaymentMatchLog, error) {
|
|
var log model.PaymentMatchLog
|
|
err := r.db.WithContext(ctx).Where("channel_bill_no = ?", channelBillNo).First(&log).Error
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return nil, nil
|
|
}
|
|
return &log, err
|
|
}
|
|
|
|
// UpdateMatchLog 更新匹配记录
|
|
func (r *PaymentMatchRepository) UpdateMatchLog(ctx context.Context, id uint64, updates map[string]any) error {
|
|
return r.db.WithContext(ctx).Model(&model.PaymentMatchLog{}).Where("id = ?", id).Updates(updates).Error
|
|
}
|
|
|
|
// ListPendingManual 查询待人工确认的记录
|
|
func (r *PaymentMatchRepository) ListPendingManual(ctx context.Context, appID string, limit, offset int) ([]*model.PaymentMatchLog, error) {
|
|
var logs []*model.PaymentMatchLog
|
|
err := r.db.WithContext(ctx).
|
|
Joins("JOIN sub_merchant_account ON sub_merchant_account.id = payment_match_log.account_id").
|
|
Where("sub_merchant_account.app_id = ? AND payment_match_log.match_status = ?",
|
|
appID, model.MatchStatusPendingManual).
|
|
Order("payment_match_log.created_at DESC").
|
|
Limit(limit).Offset(offset).
|
|
Find(&logs).Error
|
|
return logs, err
|
|
}
|
|
|
|
// ListPayingByAmount 按金额查询指定时间窗口内的待支付订单(用于收款匹配降级)
|
|
func (r *PaymentMatchRepository) ListPayingByAmount(ctx context.Context, appID string, amount int64, window time.Duration) ([]*model.TradeOrder, error) {
|
|
var orders []*model.TradeOrder
|
|
since := time.Now().Add(-window)
|
|
err := r.db.WithContext(ctx).
|
|
Where("app_id = ? AND amount = ? AND status = ? AND created_at >= ?",
|
|
appID, amount, model.TradeStatusPaying, since).
|
|
Find(&orders).Error
|
|
return orders, err
|
|
}
|