Files
mengyastore/mengyastore-backend-go/internal/database/models.go
2026-05-13 12:11:46 +08:00

133 lines
5.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package database
import (
"database/sql/driver"
"encoding/json"
"fmt"
"time"
)
// StringSlice 表示以 JSON 序列化形式存入 MySQL TEXT/JSON 列的字符串切片。
type StringSlice []string
func (s StringSlice) Value() (driver.Value, error) {
if s == nil {
return "[]", nil
}
b, err := json.Marshal(s)
return string(b), err
}
func (s *StringSlice) Scan(src any) error {
var raw []byte
switch v := src.(type) {
case string:
raw = []byte(v)
case []byte:
raw = v
default:
return fmt.Errorf("StringSlice: unsupported type %T", src)
}
return json.Unmarshal(raw, s)
}
// ─── 商品 ─────────────────────────────────────────────────────────────────────
// ProductRow 为 `products` 表的 GORM 模型。
type ProductRow struct {
ID string `gorm:"primaryKey;size:36"`
Name string `gorm:"size:255;not null"`
Price float64 `gorm:"not null;default:0"`
DiscountPrice float64 `gorm:"default:0"`
Tags StringSlice `gorm:"type:json"`
CoverURL string `gorm:"size:500"`
ScreenshotURLs StringSlice `gorm:"type:json"`
VerificationURL string `gorm:"size:500;default:''"`
Description string `gorm:"type:text"`
Active bool `gorm:"default:true;index"`
RequireLogin bool `gorm:"default:false"`
MaxPerAccount int `gorm:"default:0"`
TotalSold int `gorm:"default:0"`
ViewCount int `gorm:"default:0"`
DeliveryMode string `gorm:"size:20;default:'auto'"`
// FulfillmentType: card=卡密库存 / fixed=固定内容(不限库存,内容见 FixedContent
FulfillmentType string `gorm:"size:16;default:card;index"`
FixedContent string `gorm:"type:text"`
ShowNote bool `gorm:"default:true"`
ShowContact bool `gorm:"default:true"`
// PaymentQrURLs JSON萌芽支付等多张收款码图片链接。
PaymentQrURLs StringSlice `gorm:"column:payment_qr_urls;type:json"`
CreatedAt time.Time `gorm:"index"`
}
func (ProductRow) TableName() string { return "products" }
// ProductCodeRow 单条卡密一行,按商品维度存储。
type ProductCodeRow struct {
ID uint `gorm:"primaryKey;autoIncrement"`
ProductID string `gorm:"size:36;not null;index"`
Code string `gorm:"type:text;not null"`
}
func (ProductCodeRow) TableName() string { return "product_codes" }
// ─── 订单 ─────────────────────────────────────────────────────────────────────
type OrderRow struct {
ID string `gorm:"primaryKey;size:36"`
ProductID string `gorm:"size:36;not null;index"`
ProductName string `gorm:"size:255;not null"`
UserAccount string `gorm:"size:255;index"`
UserName string `gorm:"size:255"`
Quantity int `gorm:"not null;default:1"`
DeliveredCodes StringSlice `gorm:"type:json"`
Status string `gorm:"size:20;not null;default:'pending';index"`
DeliveryMode string `gorm:"size:20;default:'auto'"`
Note string `gorm:"type:text"`
ContactPhone string `gorm:"size:50"`
ContactEmail string `gorm:"size:255"`
NotifyEmail string `gorm:"size:255"`
// PaymentMethod 如 mengya历史订单或免费单可能为空。
PaymentMethod string `gorm:"size:32;default:'';index"`
// PaymentExpectedTotal 待支付时应付快照(元),用于 Webhook 金额核对。
PaymentExpectedTotal float64 `gorm:"default:0"`
// PaymentExpiresAt 待支付截止时间;非待支付订单为 NULL。
PaymentExpiresAt *time.Time `gorm:"index"`
CreatedAt time.Time
}
func (OrderRow) TableName() string { return "orders" }
// ─── 站点设置 ─────────────────────────────────────────────────────────────────
// SiteSettingRow 站点级键值配置。
type SiteSettingRow struct {
Key string `gorm:"primaryKey;size:64"`
Value string `gorm:"type:text"`
}
func (SiteSettingRow) TableName() string { return "site_settings" }
// ─── 收藏夹 ───────────────────────────────────────────────────────────────────
type WishlistRow struct {
ID uint `gorm:"primaryKey;autoIncrement"`
AccountID string `gorm:"size:255;not null;index:idx_wishlist,unique"`
ProductID string `gorm:"size:36;not null;index:idx_wishlist,unique"`
}
func (WishlistRow) TableName() string { return "wishlists" }
// ─── 聊天消息 ─────────────────────────────────────────────────────────────────
type ChatMessageRow struct {
ID string `gorm:"primaryKey;size:36"`
AccountID string `gorm:"size:255;not null;index"`
AccountName string `gorm:"size:255"`
Content string `gorm:"type:text;not null"`
SentAt time.Time `gorm:"not null"`
FromAdmin bool `gorm:"default:false"`
}
func (ChatMessageRow) TableName() string { return "chat_messages" }