108 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			108 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package entities
 | ||
| 
 | ||
| import (
 | ||
| 	"fmt"
 | ||
| 	"time"
 | ||
| 
 | ||
| 	"github.com/google/uuid"
 | ||
| 	"github.com/shopspring/decimal"
 | ||
| 	"gorm.io/gorm"
 | ||
| )
 | ||
| 
 | ||
| // Wallet 钱包聚合根
 | ||
| // 用户数字钱包的核心信息,支持多种钱包类型和精确的余额管理
 | ||
| // 使用decimal类型确保金额计算的精确性,避免浮点数精度问题
 | ||
| // 支持欠费(余额<0),但只允许扣到小于0一次,之后不能再扣
 | ||
| // 新建钱包时可配置默认额度
 | ||
| 
 | ||
| type Wallet struct {
 | ||
| 	// 基础标识
 | ||
| 	ID     string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"钱包唯一标识"`
 | ||
| 	UserID string `gorm:"type:varchar(36);not null;uniqueIndex" json:"user_id" comment:"关联用户ID"`
 | ||
| 
 | ||
| 	// 钱包状态 - 钱包的基本状态信息
 | ||
| 	IsActive bool            `gorm:"default:true" json:"is_active" comment:"钱包是否激活"`
 | ||
| 	Balance  decimal.Decimal `gorm:"type:decimal(20,8);default:0" json:"balance" comment:"钱包余额(精确到8位小数)"`
 | ||
| 	Version  int64           `gorm:"default:0" json:"version" comment:"乐观锁版本号"`
 | ||
| 
 | ||
| 	// 时间戳字段
 | ||
| 	CreatedAt time.Time      `gorm:"autoCreateTime" json:"created_at" comment:"创建时间"`
 | ||
| 	UpdatedAt time.Time      `gorm:"autoUpdateTime" json:"updated_at" comment:"更新时间"`
 | ||
| 	DeletedAt gorm.DeletedAt `gorm:"index" json:"-" comment:"软删除时间"`
 | ||
| }
 | ||
| 
 | ||
| // TableName 指定数据库表名
 | ||
| func (Wallet) TableName() string {
 | ||
| 	return "wallets"
 | ||
| }
 | ||
| 
 | ||
| // IsZeroBalance 检查余额是否为零
 | ||
| func (w *Wallet) IsZeroBalance() bool {
 | ||
| 	return w.Balance.IsZero()
 | ||
| }
 | ||
| 
 | ||
| // HasSufficientBalance 检查是否有足够余额(允许透支额度)
 | ||
| func (w *Wallet) HasSufficientBalance(amount decimal.Decimal) bool {
 | ||
| 	// 允许扣到额度下限
 | ||
| 	return w.Balance.Sub(amount).GreaterThanOrEqual(decimal.Zero)
 | ||
| }
 | ||
| 
 | ||
| // IsArrears 是否欠费(余额<0)
 | ||
| func (w *Wallet) IsArrears() bool {
 | ||
| 	return w.Balance.LessThan(decimal.Zero)
 | ||
| }
 | ||
| 
 | ||
| // IsLowBalance 是否余额较低(余额<300)
 | ||
| func (w *Wallet) IsLowBalance() bool {
 | ||
| 	return w.Balance.LessThan(decimal.NewFromInt(300))
 | ||
| }
 | ||
| 
 | ||
| // GetBalanceStatus 获取余额状态
 | ||
| func (w *Wallet) GetBalanceStatus() string {
 | ||
| 	if w.IsArrears() {
 | ||
| 		return "arrears" // 欠费
 | ||
| 	} else if w.IsLowBalance() {
 | ||
| 		return "low" // 余额较低
 | ||
| 	} else {
 | ||
| 		return "normal" // 正常
 | ||
| 	}
 | ||
| }
 | ||
| 
 | ||
| // AddBalance 增加余额(只做加法,业务规则由服务层控制是否允许充值)
 | ||
| func (w *Wallet) AddBalance(amount decimal.Decimal) {
 | ||
| 	w.Balance = w.Balance.Add(amount)
 | ||
| }
 | ||
| 
 | ||
| // SubtractBalance 扣减余额,含欠费业务规则
 | ||
| func (w *Wallet) SubtractBalance(amount decimal.Decimal) error {
 | ||
| 	if w.Balance.LessThan(decimal.Zero) {
 | ||
| 		return fmt.Errorf("已欠费,不能再扣款")
 | ||
| 	}
 | ||
| 	newBalance := w.Balance.Sub(amount)
 | ||
| 	w.Balance = newBalance
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // GetFormattedBalance 获取格式化的余额字符串
 | ||
| func (w *Wallet) GetFormattedBalance() string {
 | ||
| 	return w.Balance.String()
 | ||
| }
 | ||
| 
 | ||
| // BeforeCreate GORM钩子:创建前自动生成UUID
 | ||
| func (w *Wallet) BeforeCreate(tx *gorm.DB) error {
 | ||
| 	if w.ID == "" {
 | ||
| 		w.ID = uuid.New().String()
 | ||
| 	}
 | ||
| 	return nil
 | ||
| }
 | ||
| 
 | ||
| // NewWallet 工厂方法
 | ||
| func NewWallet(userID string, defaultCreditLimit decimal.Decimal) *Wallet {
 | ||
| 	return &Wallet{
 | ||
| 		UserID:   userID,
 | ||
| 		IsActive: true,
 | ||
| 		Balance:  defaultCreditLimit,
 | ||
| 		Version:  0,
 | ||
| 	}
 | ||
| }
 |