拆分 service 与前端大文件,修复 CORS 配置与格式问题
- 后端 internal/service 按职责拆分: fulfillment.go(1397→527)拆出 wallet/timeout/data/order/query/dashboard/shipnotify delivery.go(1124→801)拆出 upstream/link/state/helpers merchant.go(855→251)拆出 member/product/api_client/catalog/helpers - 前端 MerchantCenter.tsx(1327→606)拆出 merchantCenterTabs/merchantCenterUtils - docker-compose backend 透传 CORS_ALLOWED_ORIGINS - CORS 白名单实现(config/router/README/.env.example 配套) - 修复 gofmt 与文件尾部多余空行
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"affiliate_dash/internal/model"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type WalletAdjustInput struct {
|
||||
MerchantID uint
|
||||
ActorUserID uint
|
||||
Amount int64
|
||||
IdempotencyKey string
|
||||
Note string
|
||||
}
|
||||
|
||||
func (s *FulfillmentService) AdjustWallet(in WalletAdjustInput) (*model.WalletAccount, error) {
|
||||
if in.Amount == 0 {
|
||||
return nil, errors.New("调整金额不能为零")
|
||||
}
|
||||
if in.IdempotencyKey == "" {
|
||||
return nil, errors.New("账务调整必须提供幂等键")
|
||||
}
|
||||
var out model.WalletAccount
|
||||
err := s.db.Transaction(func(tx *gorm.DB) error {
|
||||
var existing model.WalletLedgerEntry
|
||||
if err := tx.Where("merchant_id = ? AND idempotency_key = ?", in.MerchantID, in.IdempotencyKey).First(&existing).Error; err == nil {
|
||||
if err := tx.First(&out, existing.WalletAccountID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
} else if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
|
||||
var wallet model.WalletAccount
|
||||
if err := tx.Clauses(clause.Locking{Strength: "UPDATE"}).Where("merchant_id = ?", in.MerchantID).First(&wallet).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
newBalance := wallet.AvailableBalance + in.Amount
|
||||
if newBalance < 0 {
|
||||
return errors.New("调整后余额不能小于零")
|
||||
}
|
||||
if err := tx.Model(&wallet).Update("available_balance", newBalance).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
entryType := model.WalletLedgerAdjust
|
||||
if in.Amount > 0 {
|
||||
entryType = model.WalletLedgerCredit
|
||||
} else {
|
||||
entryType = model.WalletLedgerDebit
|
||||
}
|
||||
idempotencyKey := in.IdempotencyKey
|
||||
if err := tx.Create(&model.WalletLedgerEntry{
|
||||
MerchantID: in.MerchantID,
|
||||
WalletAccountID: wallet.ID,
|
||||
EntryNo: "WL" + uuid.NewString(),
|
||||
Type: entryType,
|
||||
Amount: in.Amount,
|
||||
BalanceAfter: newBalance,
|
||||
ReferenceType: "manual_adjustment",
|
||||
ReferenceNo: in.IdempotencyKey,
|
||||
IdempotencyKey: &idempotencyKey,
|
||||
Note: in.Note,
|
||||
}).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
out = wallet
|
||||
out.AvailableBalance = newBalance
|
||||
return writeAudit(tx, &in.MerchantID, &in.ActorUserID, nil, "wallet.adjust", "wallet_account", fmt.Sprint(wallet.ID), map[string]int64{"amount": in.Amount})
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &out, nil
|
||||
}
|
||||
|
||||
func (s *FulfillmentService) GetWallet(merchantID uint) (*model.WalletAccount, error) {
|
||||
var wallet model.WalletAccount
|
||||
if err := s.db.Where("merchant_id = ?", merchantID).First(&wallet).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, errors.New("商户钱包不存在")
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return &wallet, nil
|
||||
}
|
||||
|
||||
func (s *FulfillmentService) ListWalletLedger(merchantID uint, page, size int, referenceNo, entryType string) ([]model.WalletLedgerEntry, int64, error) {
|
||||
page, size = normalizePage(page, size)
|
||||
tx := s.db.Model(&model.WalletLedgerEntry{}).Where("merchant_id = ?", merchantID)
|
||||
if referenceNo != "" {
|
||||
tx = tx.Where("reference_no LIKE ?", "%"+referenceNo+"%")
|
||||
}
|
||||
if entryType != "" {
|
||||
tx = tx.Where("type = ?", entryType)
|
||||
}
|
||||
var total int64
|
||||
if err := tx.Count(&total).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
var entries []model.WalletLedgerEntry
|
||||
err := tx.Order("id DESC").Offset((page - 1) * size).Limit(size).Find(&entries).Error
|
||||
return entries, total, err
|
||||
}
|
||||
Reference in New Issue
Block a user