package dao import ( "context" "errors" "gitea.com/red-future/common/db/gfdb" "github.com/gogf/gf/v2/database/gdb" "github.com/gogf/gf/v2/util/gconv" "shop-user-trade/consts/public" walletConsts "shop-user-trade/consts/wallet" walletDto "shop-user-trade/model/dto/wallet" walletEntity "shop-user-trade/model/entity/wallet" ) var Wallet = new(walletDao) type walletDao struct{} // GetByUserID 根据用户ID获取钱包 func (d *walletDao) GetByUserID(ctx context.Context, userID int64) (res *walletEntity.Wallet, err error) { r, err := gfdb.DB(ctx).Model(ctx, public.TableNameWallet). Where(walletEntity.WalletCol.UserID, userID). WhereNot(walletEntity.WalletCol.Status, int(walletConsts.WalletStatusFrozen)). One() if err != nil { return } if r.IsEmpty() { return nil, nil } err = r.Struct(&res) return } // GetByID 根据ID获取钱包 func (d *walletDao) GetByID(ctx context.Context, walletID int64) (res *walletEntity.Wallet, err error) { r, err := gfdb.DB(ctx).Model(ctx, public.TableNameWallet). Where(walletEntity.WalletCol.Id, walletID). One() if err != nil { return } if r.IsEmpty() { return nil, nil } err = r.Struct(&res) return } // Create 创建钱包 func (d *walletDao) Create(ctx context.Context, req *walletDto.CreateWalletReq) (id int64, err error) { entity := &walletEntity.Wallet{ UserID: req.UserId, Balance: 0, Currency: req.Currency, Status: walletConsts.WalletStatusEnabled, Version: 1, } r, err := gfdb.DB(ctx).Model(ctx, public.TableNameWallet).Data(entity).Insert() if err != nil { return } return r.LastInsertId() } // UpdateBalance 更新余额(乐观锁) func (d *walletDao) UpdateBalance(ctx context.Context, walletID int64, amount int64, opType string, version int64) (bool, error) { var updateData gdb.Map switch opType { case "income": updateData = gdb.Map{ "balance": gdb.Raw("balance + " + gconv.String(amount)), "version": gdb.Raw("version + 1"), } case "expense": updateData = gdb.Map{ "balance": gdb.Raw("balance - " + gconv.String(amount)), "version": gdb.Raw("version + 1"), } case "freeze": updateData = gdb.Map{ "status": int(walletConsts.WalletStatusFrozen), } case "unfreeze": updateData = gdb.Map{ "status": int(walletConsts.WalletStatusEnabled), } default: return false, errors.New("unsupported operation type") } result, err := gfdb.DB(ctx).Model(ctx, public.TableNameWallet). Data(updateData). Where(walletEntity.WalletCol.Id, walletID). Where(walletEntity.WalletCol.Version, version). Update() if err != nil { return false, err } rows, err := result.RowsAffected() if err != nil { return false, err } return rows > 0, nil } // CreateLog 创建钱包日志 func (d *walletDao) CreateLog(ctx context.Context, req *walletDto.CreateWalletLogReq) (id int64, err error) { var entity *walletEntity.WalletLog if err = gconv.Struct(req, &entity); err != nil { return } r, err := gfdb.DB(ctx).Model(ctx, public.TableNameWalletLog).Data(entity).Insert() if err != nil { return } return r.LastInsertId() } // ListLogs 获取钱包日志列表 func (d *walletDao) ListLogs(ctx context.Context, userID int64, page, pageSize int) (res []walletEntity.WalletLog, total int, err error) { r, total, err := gfdb.DB(ctx).Model(ctx, public.TableNameWalletLog). Where(walletEntity.WalletLogCol.UserID, userID). OrderDesc(walletEntity.WalletLogCol.CreatedAt). Page(page, pageSize). AllAndCount(false) if err != nil { return } err = r.Structs(&res) return }