代码初始化

This commit is contained in:
2026-04-02 10:22:36 +08:00
commit 7394983236
35 changed files with 3014 additions and 0 deletions

View File

@@ -0,0 +1,153 @@
package service
import (
"context"
"errors"
"fmt"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/util/gconv"
walletDao "shop-user-trade/dao/wallet"
walletDto "shop-user-trade/model/dto/wallet"
walletEntity "shop-user-trade/model/entity/wallet"
)
type wallet struct{}
// Wallet 钱包服务
var Wallet = new(wallet)
// GetByUserId 根据用户ID获取钱包
func (s *wallet) GetByUserId(ctx context.Context, req *walletDto.GetWalletByUserIdReq) (*walletDto.GetWalletByUserIdResp, error) {
w, err := walletDao.Wallet.GetByUserID(ctx, req.UserId)
if err != nil {
g.Log().Errorf(ctx, "获取用户钱包失败, userId: %d, error: %v", req.UserId, err)
return nil, err
}
if w == nil {
return nil, errors.New("钱包不存在")
}
return &walletDto.GetWalletByUserIdResp{
Data: walletDto.WalletInfo{
ID: w.Id,
UserID: w.UserID,
Balance: w.Balance,
Currency: w.Currency,
Status: int(w.Status),
},
}, nil
}
// Create 创建钱包
func (s *wallet) Create(ctx context.Context, req *walletDto.CreateWalletReq) (*walletDto.CreateWalletResp, error) {
// 检查钱包是否已存在
existing, err := walletDao.Wallet.GetByUserID(ctx, req.UserId)
if err != nil {
g.Log().Errorf(ctx, "检查用户钱包失败, userId: %d, error: %v", req.UserId, err)
return nil, err
}
if existing != nil {
return nil, errors.New("钱包已存在")
}
id, err := walletDao.Wallet.Create(ctx, req)
if err != nil {
g.Log().Errorf(ctx, "创建钱包失败, userId: %d, error: %v", req.UserId, err)
return nil, err
}
return &walletDto.CreateWalletResp{
Data: walletDto.CreateWalletData{WalletID: id},
}, nil
}
// UpdateBalance 更新余额
func (s *wallet) UpdateBalance(ctx context.Context, req *walletDto.UpdateBalanceReq) (*walletDto.UpdateBalanceResp, error) {
w, err := walletDao.Wallet.GetByID(ctx, req.WalletID)
if err != nil {
g.Log().Errorf(ctx, "获取钱包失败, walletId: %d, error: %v", req.WalletID, err)
return nil, err
}
if w == nil {
return nil, errors.New("钱包不存在")
}
// 检查余额是否充足
if req.Type == "expense" && w.Balance < req.Amount {
return nil, errors.New("余额不足")
}
// 记录操作前余额
balanceBefore := w.Balance
var balanceAfter int64
switch req.Type {
case "income":
balanceAfter = balanceBefore + req.Amount
case "expense":
balanceAfter = balanceBefore - req.Amount
default:
balanceAfter = balanceBefore
}
// 更新余额(乐观锁)
success, err := walletDao.Wallet.UpdateBalance(ctx, req.WalletID, req.Amount, req.Type, w.Version)
if err != nil {
g.Log().Errorf(ctx, "更新余额失败, walletId: %d, error: %v", req.WalletID, err)
return nil, err
}
if !success {
return nil, errors.New("余额更新失败,请重试")
}
// 记录流水日志
logReq := &walletDto.CreateWalletLogReq{
UserID: w.UserID,
WalletID: w.Id,
OrderNo: req.OrderNo,
TransactionNo: req.TransactionNo,
Type: req.Type,
Amount: req.Amount,
BalanceBefore: balanceBefore,
BalanceAfter: balanceAfter,
Currency: w.Currency,
Description: req.Description,
ExtraData: req.ExtraData,
}
if _, err = walletDao.Wallet.CreateLog(ctx, logReq); err != nil {
g.Log().Warningf(ctx, "记录钱包日志失败, walletId: %d, error: %v", req.WalletID, err)
}
return &walletDto.UpdateBalanceResp{
Success: true,
Message: "更新成功",
}, nil
}
// GetWalletLogs 获取钱包日志
func (s *wallet) GetWalletLogs(ctx context.Context, req *walletDto.GetWalletLogsReq) (*walletDto.GetWalletLogsResp, error) {
logs, total, err := walletDao.Wallet.ListLogs(ctx, req.UserId, req.Page, req.PageSize)
if err != nil {
return nil, fmt.Errorf("获取钱包日志失败: %w", err)
}
var logInfos []walletDto.WalletLogInfo
for _, log := range logs {
logInfos = append(logInfos, s.logEntityToInfo(&log))
}
return &walletDto.GetWalletLogsResp{
Data: walletDto.WalletLogData{
Logs: logInfos,
Total: total,
},
}, nil
}
// logEntityToInfo 日志实体转换为Info
func (s *wallet) logEntityToInfo(e *walletEntity.WalletLog) walletDto.WalletLogInfo {
info := walletDto.WalletLogInfo{}
_ = gconv.Struct(e, &info)
info.ID = e.Id
info.Type = string(e.Type)
if e.CreatedAt != nil {
info.CreatedAt = e.CreatedAt.String()
}
return info
}