181 lines
6.9 KiB
Go
181 lines
6.9 KiB
Go
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,
|
||
}
|
||
}
|