package services import ( "context" "errors" "strings" "time" "quyun/v2/app/errorx" user_dto "quyun/v2/app/http/v1/dto" "quyun/v2/database/models" "quyun/v2/pkg/consts" "go.ipao.vip/gen/field" "gorm.io/gorm" ) // @provider type wallet struct{} func (s *wallet) GetWallet(ctx context.Context, tenantID, userID int64) (*user_dto.WalletResponse, error) { // Get Balance u, err := models.UserQuery.WithContext(ctx).Where(models.UserQuery.ID.Eq(userID)).First() if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, errorx.ErrRecordNotFound } return nil, errorx.ErrDatabaseError.WithCause(err) } // Get Transactions (Orders) // Both purchase (expense) and recharge (income - if paid) tbl, q := models.OrderQuery.QueryContext(ctx) if tenantID > 0 { q = q.Where(tbl.Status.Eq(consts.OrderStatusPaid)). Where(field.Or( field.And(tbl.UserID.Eq(userID), tbl.TenantID.Eq(tenantID)), field.And(tbl.UserID.Eq(userID), tbl.Type.Eq(consts.OrderTypeRecharge)), )) } else { q = q.Where(tbl.UserID.Eq(userID), tbl.Status.Eq(consts.OrderStatusPaid)) } orders, err := q. Order(tbl.CreatedAt.Desc()). Limit(20). // Limit to recent 20 Find() if err != nil { return nil, errorx.ErrDatabaseError.WithCause(err) } var txs []user_dto.Transaction for _, o := range orders { var txType string var title string switch o.Type { case consts.OrderTypeContentPurchase: txType = "expense" title = "购买内容" case consts.OrderTypeRecharge: txType = "income" title = "钱包充值" } txs = append(txs, user_dto.Transaction{ ID: o.ID, Title: title, Amount: float64(o.AmountPaid) / 100.0, Type: txType, Date: o.CreatedAt.Format(time.RFC3339), }) } return &user_dto.WalletResponse{ Balance: float64(u.Balance) / 100.0, Transactions: txs, }, nil } func (s *wallet) Recharge( ctx context.Context, tenantID int64, userID int64, form *user_dto.RechargeForm, ) (*user_dto.RechargeResponse, error) { code := strings.TrimSpace(form.Code) if code == "" { return nil, errorx.ErrBadRequest.WithMsg("充值码不能为空") } resp, err := Recharge.Redeem(ctx, tenantID, userID, code) if err != nil { return nil, err } return &user_dto.RechargeResponse{ OrderID: resp.OrderID, Amount: resp.Amount, }, nil }