package asset import ( "context" kratoserrors "github.com/go-kratos/kratos/v3/errors" "strings" "time" ) var ( ErrNotFound = kratoserrors.NotFound("ASSET_USER_NOT_FOUND", "user asset not found") ErrInsufficient = kratoserrors.BadRequest("ASSET_INSUFFICIENT", "insufficient diamond balance") ErrInvalidAdjustment = kratoserrors.BadRequest("ASSET_ADJUSTMENT_INVALID", "invalid balance adjustment") ErrSelfDisable = kratoserrors.BadRequest("ASSET_SELF_DISABLE", "current administrator cannot be disabled") ) type User struct { UserID uint Username, Nickname, Avatar string Enabled bool DiamondBalance, TotalRechargeCents, TotalSpentDiamonds int64 CreatedAt time.Time LastLoginAt *time.Time RecentOrders []OrderRecord RecentSends []SendRecord } type OrderRecord struct { OrderNo string Diamonds, AmountCents int64 Status string CreatedAt time.Time } type SendRecord struct { SerialNo, RoomName, GiftName, GiftIcon string DiamondTotal int64 CreatedAt time.Time } type Filter struct { Keyword string UserID uint Enabled *bool CreatedAt []time.Time } type ListOptions struct { Offset, Limit int OrderBy string } type Adjustment struct { UserID, OperatorUserID uint Type string Amount int64 Reason string } type Repo interface { List(context.Context, Filter, ListOptions) ([]*User, int64, error) Get(context.Context, uint) (*User, error) SetEnabled(context.Context, uint, bool) error Adjust(context.Context, *Adjustment) (*User, error) } type Usecase struct{ repo Repo } func NewUsecase(repo Repo) *Usecase { return &Usecase{repo: repo} } func (uc *Usecase) List(ctx context.Context, f Filter, o ListOptions) ([]*User, int64, error) { if o.Limit < 1 || o.Limit > 100 { o.Limit = 10 } return uc.repo.List(ctx, f, o) } func (uc *Usecase) Get(ctx context.Context, id uint) (*User, error) { if id == 0 { return nil, ErrNotFound } return uc.repo.Get(ctx, id) } func (uc *Usecase) SetEnabled(ctx context.Context, actor, id uint, enabled bool) error { if actor == id && !enabled { return ErrSelfDisable } return uc.repo.SetEnabled(ctx, id, enabled) } func (uc *Usecase) Adjust(ctx context.Context, v *Adjustment) (*User, error) { if v == nil || v.UserID == 0 || v.OperatorUserID == 0 || v.Amount < 1 || v.Amount > 99999 || (v.Type != "increase" && v.Type != "decrease") { return nil, ErrInvalidAdjustment } v.Reason = strings.TrimSpace(v.Reason) if n := len([]rune(v.Reason)); n < 5 || n > 50 { return nil, ErrInvalidAdjustment } return uc.repo.Adjust(ctx, v) }