temp
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
package walletservicelogic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"tianyuan-api/apps/user/internal/svc"
|
||||
"tianyuan-api/apps/user/user"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetDeductionByTransactionIdLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGetDeductionByTransactionIdLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetDeductionByTransactionIdLogic {
|
||||
return &GetDeductionByTransactionIdLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
func (l *GetDeductionByTransactionIdLogic) GetDeductionByTransactionId(in *user.GetDeductionByTransactionIdRequest) (*user.GetDeductionByTransactionIdResponse, error) {
|
||||
deduction, err := l.svcCtx.DeductionsModel.FindOneByTransactionId(l.ctx, in.TransactionId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user.GetDeductionByTransactionIdResponse{
|
||||
Id: deduction.Id,
|
||||
UserId: deduction.UserId,
|
||||
Amount: deduction.Amount,
|
||||
TransactionId: deduction.TransactionId,
|
||||
CreatedAt: deduction.CreatedAt.Format("2006-01-02 15:04:05"),
|
||||
}, nil
|
||||
}
|
||||
31
apps/user/internal/logic/walletservice/getdeductionslogic.go
Normal file
31
apps/user/internal/logic/walletservice/getdeductionslogic.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package walletservicelogic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"tianyuan-api/apps/user/internal/svc"
|
||||
"tianyuan-api/apps/user/user"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetDeductionsLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGetDeductionsLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetDeductionsLogic {
|
||||
return &GetDeductionsLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// 查询扣款记录
|
||||
func (l *GetDeductionsLogic) GetDeductions(in *user.GetDeductionsRequest) (*user.GetDeductionsResponse, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return &user.GetDeductionsResponse{}, nil
|
||||
}
|
||||
31
apps/user/internal/logic/walletservice/getwalletlogic.go
Normal file
31
apps/user/internal/logic/walletservice/getwalletlogic.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package walletservicelogic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"tianyuan-api/apps/user/internal/svc"
|
||||
"tianyuan-api/apps/user/user"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type GetWalletLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewGetWalletLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetWalletLogic {
|
||||
return &GetWalletLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
// 查询钱包信息
|
||||
func (l *GetWalletLogic) GetWallet(in *user.GetWalletRequest) (*user.GetWalletResponse, error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
return &user.GetWalletResponse{}, nil
|
||||
}
|
||||
114
apps/user/internal/logic/walletservice/updatewalletlogic.go
Normal file
114
apps/user/internal/logic/walletservice/updatewalletlogic.go
Normal file
@@ -0,0 +1,114 @@
|
||||
package walletservicelogic
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"github.com/zeromicro/go-zero/core/stores/sqlx"
|
||||
"tianyuan-api/apps/sentinel/client/product"
|
||||
"tianyuan-api/apps/user/internal/model"
|
||||
"time"
|
||||
|
||||
"tianyuan-api/apps/user/internal/svc"
|
||||
"tianyuan-api/apps/user/user"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
)
|
||||
|
||||
type UpdateWalletLogic struct {
|
||||
ctx context.Context
|
||||
svcCtx *svc.ServiceContext
|
||||
logx.Logger
|
||||
}
|
||||
|
||||
func NewUpdateWalletLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UpdateWalletLogic {
|
||||
return &UpdateWalletLogic{
|
||||
ctx: ctx,
|
||||
svcCtx: svcCtx,
|
||||
Logger: logx.WithContext(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
const maxRetries = 5 // 最大重试次数
|
||||
// 修改钱包余额
|
||||
func (l *UpdateWalletLogic) UpdateWallet(in *user.UpdateWalletRequest) (*user.UpdateWalletResponse, error) {
|
||||
if !in.Charge {
|
||||
return nil, errors.New("不需要扣款")
|
||||
}
|
||||
// 获取产品信息
|
||||
consumeProduct, getProductByCodeErr := l.svcCtx.ProductRpc.GetProductByCode(l.ctx, &product.GetRecordByCodeRequest{Code: in.ProductCode})
|
||||
if getProductByCodeErr != nil {
|
||||
return nil, getProductByCodeErr
|
||||
}
|
||||
|
||||
// 检查是否已经扣款
|
||||
deduction, FindOneByTransactionIdErr := l.svcCtx.DeductionsModel.FindOneByTransactionId(l.ctx, in.TransactionId)
|
||||
if FindOneByTransactionIdErr != nil {
|
||||
if FindOneByTransactionIdErr == sql.ErrNoRows {
|
||||
} else {
|
||||
// 其他错误,直接返回
|
||||
return nil, FindOneByTransactionIdErr
|
||||
}
|
||||
} else if deduction != nil {
|
||||
// 找到扣款记录,不能重复扣款
|
||||
return nil, errors.New("该订单已扣款")
|
||||
}
|
||||
|
||||
// 启动事务
|
||||
err := l.svcCtx.WalletsModel.TransCtx(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||
var err error
|
||||
// 尝试多次更新余额(用于乐观锁)
|
||||
for i := 0; i < maxRetries; i++ {
|
||||
err = l.svcCtx.WalletsModel.UpdateBalance(session, l.ctx, in.UserId, -consumeProduct.ProductPrice)
|
||||
if err == nil {
|
||||
// 成功,退出循环
|
||||
break
|
||||
}
|
||||
if errors.Is(err, model.ErrVersionMismatch) {
|
||||
// 版本号不匹配,重试
|
||||
time.Sleep(100 * time.Millisecond) // 重试前的延迟
|
||||
continue
|
||||
} else {
|
||||
// 其他错误,直接返回
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新余额成功后,插入扣款记录
|
||||
_, err = l.svcCtx.DeductionsModel.InsertDeductionsTrans(ctx, &model.Deductions{
|
||||
TransactionId: in.TransactionId,
|
||||
UserId: in.UserId,
|
||||
Amount: consumeProduct.ProductPrice,
|
||||
}, session)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 获取最新的用户余额
|
||||
wallet, err := l.svcCtx.WalletsModel.FindOneByUserId(l.ctx, in.UserId)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 如果余额小于 0,更新 QuotaExceeded 字段为 1
|
||||
if wallet.Balance < 0 {
|
||||
users, findOneErr := l.svcCtx.UserModel.FindOne(l.ctx, in.UserId)
|
||||
if findOneErr != nil {
|
||||
return nil, findOneErr
|
||||
}
|
||||
users.QuotaExceeded = 1
|
||||
updateErr := l.svcCtx.UserModel.Update(l.ctx, users)
|
||||
if updateErr != nil {
|
||||
return nil, updateErr
|
||||
}
|
||||
}
|
||||
return &user.UpdateWalletResponse{}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user