package entities import ( "fmt" "math/rand" "time" "github.com/google/uuid" "github.com/shopspring/decimal" "gorm.io/gorm" ) // PurchaseOrderStatus 购买订单状态枚举(通用) type PurchaseOrderStatus string const ( PurchaseOrderStatusCreated PurchaseOrderStatus = "created" // 已创建 PurchaseOrderStatusPaid PurchaseOrderStatus = "paid" // 已支付 PurchaseOrderStatusFailed PurchaseOrderStatus = "failed" // 支付失败 PurchaseOrderStatusCancelled PurchaseOrderStatus = "cancelled" // 已取消 PurchaseOrderStatusRefunded PurchaseOrderStatus = "refunded" // 已退款 PurchaseOrderStatusClosed PurchaseOrderStatus = "closed" // 已关闭 ) // PurchaseOrder 购买订单实体(统一表 ty_purchase_orders,兼容多支付渠道) type PurchaseOrder struct { // 基础标识 ID string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"购买订单唯一标识"` UserID string `gorm:"type:varchar(36);not null;index" json:"user_id" comment:"购买用户ID"` OrderNo string `gorm:"type:varchar(64);not null;uniqueIndex" json:"order_no" comment:"商户订单号"` TradeNo *string `gorm:"type:varchar(64);uniqueIndex" json:"trade_no,omitempty" comment:"第三方支付交易号"` // 产品信息 ProductID string `gorm:"type:varchar(36);not null;index" json:"product_id" comment:"产品ID"` ProductCode string `gorm:"type:varchar(50);not null" json:"product_code" comment:"产品编号"` ProductName string `gorm:"type:varchar(200);not null" json:"product_name" comment:"产品名称"` Category string `gorm:"type:varchar(50)" json:"category,omitempty" comment:"产品分类"` // 订单信息 Subject string `gorm:"type:varchar(200);not null" json:"subject" comment:"订单标题"` Amount decimal.Decimal `gorm:"type:decimal(20,8);not null" json:"amount" comment:"订单金额"` PayAmount *decimal.Decimal `gorm:"type:decimal(20,8)" json:"pay_amount,omitempty" comment:"实际支付金额"` Status PurchaseOrderStatus `gorm:"type:varchar(20);not null;default:'created';index" json:"status" comment:"订单状态"` Platform string `gorm:"type:varchar(20);not null" json:"platform" comment:"下单平台:app/h5/pc/wx_h5/wx_mini等"` PayChannel string `gorm:"type:varchar(20);default:'alipay';index" json:"pay_channel" comment:"支付渠道:alipay/wechat"` PaymentType string `gorm:"type:varchar(20);not null" json:"payment_type" comment:"支付类型:alipay, wechat, free"` // 支付渠道返回信息 BuyerID string `gorm:"type:varchar(64)" json:"buyer_id,omitempty" comment:"买家ID(支付渠道方)"` SellerID string `gorm:"type:varchar(64)" json:"seller_id,omitempty" comment:"卖家ID(支付渠道方)"` ReceiptAmount decimal.Decimal `gorm:"type:decimal(20,8)" json:"receipt_amount,omitempty" comment:"实收金额"` // 回调信息 NotifyTime *time.Time `gorm:"index" json:"notify_time,omitempty" comment:"异步通知时间"` ReturnTime *time.Time `gorm:"index" json:"return_time,omitempty" comment:"同步返回时间"` PayTime *time.Time `gorm:"index" json:"pay_time,omitempty" comment:"支付完成时间"` // 文件信息 FilePath *string `gorm:"type:varchar(500)" json:"file_path,omitempty" comment:"产品文件路径"` FileSize *int64 `gorm:"type:bigint" json:"file_size,omitempty" comment:"文件大小(字节)"` // 备注信息 Remark string `gorm:"type:varchar(500)" json:"remark,omitempty" comment:"备注信息"` // 错误信息 ErrorCode string `gorm:"type:varchar(64)" json:"error_code,omitempty" comment:"错误码"` ErrorMessage string `gorm:"type:text" json:"error_message,omitempty" 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 (PurchaseOrder) TableName() string { return "ty_purchase_orders" } // BeforeCreate GORM钩子:创建前自动生成UUID和订单号 func (p *PurchaseOrder) BeforeCreate(tx *gorm.DB) error { if p.ID == "" { p.ID = uuid.New().String() } if p.OrderNo == "" { p.OrderNo = generatePurchaseOrderNo() } return nil } // generatePurchaseOrderNo 生成购买订单号 func generatePurchaseOrderNo() string { // 使用时间戳+随机数生成唯一订单号,例如:PO202312200001 timestamp := time.Now().Format("20060102") random := fmt.Sprintf("%04d", rand.Intn(9999)) return fmt.Sprintf("PO%s%s", timestamp, random) } // IsCreated 检查是否为已创建状态 func (p *PurchaseOrder) IsCreated() bool { return p.Status == PurchaseOrderStatusCreated } // IsPaid 检查是否为已支付状态 func (p *PurchaseOrder) IsPaid() bool { return p.Status == PurchaseOrderStatusPaid } // IsFailed 检查是否为支付失败状态 func (p *PurchaseOrder) IsFailed() bool { return p.Status == PurchaseOrderStatusFailed } // IsCancelled 检查是否为已取消状态 func (p *PurchaseOrder) IsCancelled() bool { return p.Status == PurchaseOrderStatusCancelled } // IsRefunded 检查是否为已退款状态 func (p *PurchaseOrder) IsRefunded() bool { return p.Status == PurchaseOrderStatusRefunded } // IsClosed 检查是否为已关闭状态 func (p *PurchaseOrder) IsClosed() bool { return p.Status == PurchaseOrderStatusClosed } // MarkPaid 标记为已支付 func (p *PurchaseOrder) MarkPaid(tradeNo, buyerID, sellerID string, payAmount, receiptAmount decimal.Decimal) { p.Status = PurchaseOrderStatusPaid p.TradeNo = &tradeNo p.BuyerID = buyerID p.SellerID = sellerID p.PayAmount = &payAmount p.ReceiptAmount = receiptAmount now := time.Now() p.PayTime = &now p.NotifyTime = &now } // MarkFailed 标记为支付失败 func (p *PurchaseOrder) MarkFailed(errorCode, errorMessage string) { p.Status = PurchaseOrderStatusFailed p.ErrorCode = errorCode p.ErrorMessage = errorMessage } // MarkCancelled 标记为已取消 func (p *PurchaseOrder) MarkCancelled() { p.Status = PurchaseOrderStatusCancelled } // MarkRefunded 标记为已退款 func (p *PurchaseOrder) MarkRefunded() { p.Status = PurchaseOrderStatusRefunded } // MarkClosed 标记为已关闭 func (p *PurchaseOrder) MarkClosed() { p.Status = PurchaseOrderStatusClosed } // NewPurchaseOrder 通用工厂方法 - 创建购买订单(支持多支付渠道) func NewPurchaseOrder(userID, productID, productCode, productName, subject string, amount decimal.Decimal, platform, payChannel, paymentType string) *PurchaseOrder { return &PurchaseOrder{ ID: uuid.New().String(), UserID: userID, OrderNo: generatePurchaseOrderNo(), ProductID: productID, ProductCode: productCode, ProductName: productName, Subject: subject, Amount: amount, Status: PurchaseOrderStatusCreated, Platform: platform, PayChannel: payChannel, PaymentType: paymentType, } }