Files
smartmate/backend/services/tokenstore/model/token.go
2026-05-06 00:30:08 +08:00

156 lines
9.3 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 model
import "time"
const (
// TokenProductStatusActive 表示商品可在 Token 商店展示和购买。
TokenProductStatusActive = "active"
// TokenProductStatusInactive 表示商品已下架,不再对前端展示。
TokenProductStatusInactive = "inactive"
)
const (
// TokenOrderStatusPending 表示订单已创建,等待支付确认。
TokenOrderStatusPending = "pending"
// TokenOrderStatusPaid 表示订单已确认支付,等待写入获取账本。
TokenOrderStatusPaid = "paid"
// TokenOrderStatusGranted 表示订单已经写入 token_grants 获取账本。
TokenOrderStatusGranted = "granted"
// TokenOrderStatusClosed 表示订单关闭P0 暂不实现复杂关闭流程。
TokenOrderStatusClosed = "closed"
)
const (
// TokenGrantStatusRecorded 表示 Token 获取事实已记录在 token-store 内。
TokenGrantStatusRecorded = "recorded"
// TokenGrantStatusApplied 表示后续已同步到 user/auth 权威额度。
TokenGrantStatusApplied = "applied"
// TokenGrantStatusSkipped 表示命中奖励规则或幂等条件后跳过发放。
TokenGrantStatusSkipped = "skipped"
// TokenGrantStatusFailed 表示记录或后续同步失败,可按 event_id 重试。
TokenGrantStatusFailed = "failed"
)
const (
// TokenGrantSourcePurchase 表示购买 Token 商品产生的获取记录。
TokenGrantSourcePurchase = "purchase"
// TokenGrantSourceForumLike 表示计划被点赞产生的作者奖励。
TokenGrantSourceForumLike = "forum_like"
// TokenGrantSourceForumImport 表示计划被导入产生的作者奖励。
TokenGrantSourceForumImport = "forum_import"
// TokenGrantSourceManual 预留人工补偿来源P0 不做管理后台。
TokenGrantSourceManual = "manual"
)
const (
// TokenRewardRuleStatusActive 表示奖励规则启用。
TokenRewardRuleStatusActive = "active"
// TokenRewardRuleStatusInactive 表示奖励规则停用。
TokenRewardRuleStatusInactive = "inactive"
)
// TokenProduct 是 Token 商店商品表。
//
// 职责边界:
// 1. P0 从表读取商品,由 seed 初始化 2-3 个固定商品;
// 2. 不承载真实支付渠道配置,也不做商品管理后台;
// 3. 下单时会复制商品快照到订单,避免后续改价影响历史订单。
type TokenProduct struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
SKU string `gorm:"column:sku;type:varchar(64);not null;uniqueIndex:uk_token_products_sku;comment:商品稳定编码"`
Name string `gorm:"column:name;type:varchar(80);not null;comment:商品名称"`
Description string `gorm:"column:description;type:varchar(255);comment:商品描述"`
TokenAmount int64 `gorm:"column:token_amount;not null;comment:商品包含Token数量"`
PriceCent int64 `gorm:"column:price_cent;not null;comment:价格,单位分"`
Currency string `gorm:"column:currency;type:varchar(16);not null;default:'CNY';comment:币种"`
Badge string `gorm:"column:badge;type:varchar(32);comment:前端角标"`
Status string `gorm:"column:status;type:varchar(32);not null;default:'active';index:idx_token_products_status_sort,priority:1;comment:active/inactive"`
SortOrder int `gorm:"column:sort_order;not null;default:0;index:idx_token_products_status_sort,priority:2;comment:展示排序"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime;comment:创建时间"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime;comment:更新时间"`
}
func (TokenProduct) TableName() string {
return "token_products"
}
// TokenOrder 是 Token 商品订单表。
//
// 职责边界:
// 1. 记录用户购买商品的订单状态机;
// 2. P0 只支持 mock paid不接真实支付网关
// 3. granted 只表示已写入 token-store 获取账本,不代表已同步到 user/auth 权威额度。
type TokenOrder struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
OrderNo string `gorm:"column:order_no;type:varchar(64);not null;uniqueIndex:uk_token_orders_order_no;comment:订单号"`
UserID uint64 `gorm:"column:user_id;not null;uniqueIndex:uk_token_orders_user_idem,priority:1;index:idx_token_orders_user_status_created,priority:1;comment:下单用户ID"`
ProductID uint64 `gorm:"column:product_id;not null;index:idx_token_orders_product;comment:商品ID"`
ProductSKU string `gorm:"column:product_sku;type:varchar(64);not null;comment:商品SKU快照"`
ProductName string `gorm:"column:product_name;type:varchar(80);not null;comment:商品名称快照"`
ProductSnapshotJSON string `gorm:"column:product_snapshot_json;type:json;not null;comment:商品完整快照JSON"`
Quantity int `gorm:"column:quantity;not null;default:1;comment:购买数量"`
TokenAmount int64 `gorm:"column:token_amount;not null;comment:订单总Token数量"`
AmountCent int64 `gorm:"column:amount_cent;not null;comment:订单总金额,单位分"`
Currency string `gorm:"column:currency;type:varchar(16);not null;default:'CNY';comment:币种"`
Status string `gorm:"column:status;type:varchar(32);not null;default:'pending';index:idx_token_orders_user_status_created,priority:2;comment:pending/paid/granted/closed"`
PaymentMode string `gorm:"column:payment_mode;type:varchar(32);not null;default:'mock';comment:支付模式P0为mock"`
IdempotencyKey *string `gorm:"column:idempotency_key;type:varchar(128);uniqueIndex:uk_token_orders_user_idem,priority:2;comment:创建订单幂等键"`
PaidAt *time.Time `gorm:"column:paid_at;comment:支付确认时间"`
GrantedAt *time.Time `gorm:"column:granted_at;comment:写入获取账本时间"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime;index:idx_token_orders_user_status_created,priority:3;comment:创建时间"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime;comment:更新时间"`
}
func (TokenOrder) TableName() string {
return "token_orders"
}
// TokenGrant 是 Token 获取账本表。
//
// 职责边界:
// 1. 记录购买、论坛点赞奖励、论坛导入奖励等 Token 获取事实;
// 2. event_id 是最终幂等边界,避免订单或 outbox 重试重复发放;
// 3. P0 不直接修改 users 表quota_applied 默认为 false。
type TokenGrant struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
EventID string `gorm:"column:event_id;type:varchar(128);not null;uniqueIndex:uk_token_grants_event;comment:幂等事件ID"`
UserID uint64 `gorm:"column:user_id;not null;index:idx_token_grants_user_source_created,priority:1;comment:获得Token的用户ID"`
Source string `gorm:"column:source;type:varchar(32);not null;index:idx_token_grants_user_source_created,priority:2;comment:purchase/forum_like/forum_import/manual"`
SourceLabel string `gorm:"column:source_label;type:varchar(64);comment:前端展示来源"`
SourceRefID *uint64 `gorm:"column:source_ref_id;index:idx_token_grants_source_ref;comment:来源业务ID如order_id/post_id/import_id"`
OrderID *uint64 `gorm:"column:order_id;index:idx_token_grants_order;comment:购买订单ID非购买来源为空"`
Amount int64 `gorm:"column:amount;not null;comment:获取Token数量"`
Status string `gorm:"column:status;type:varchar(32);not null;default:'recorded';index:idx_token_grants_status;comment:recorded/applied/skipped/failed"`
QuotaApplied bool `gorm:"column:quota_applied;not null;default:false;comment:是否已同步到user/auth权威额度"`
Description string `gorm:"column:description;type:varchar(255);comment:前端展示描述"`
AppliedAt *time.Time `gorm:"column:applied_at;comment:同步到权威额度时间"`
LastError *string `gorm:"column:last_error;type:text;comment:后续同步失败原因"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime;index:idx_token_grants_user_source_created,priority:3;comment:创建时间"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime;comment:更新时间"`
}
func (TokenGrant) TableName() string {
return "token_grants"
}
// TokenRewardRule 是社区奖励规则表。
//
// 职责边界:
// 1. P0 可用 seed 初始化点赞、导入奖励额度;
// 2. 不提供管理后台,规则调整先通过配置或 seed 变更;
// 3. 规则命中后的最终发放仍以 token_grants.event_id 幂等为准。
type TokenRewardRule struct {
ID uint64 `gorm:"column:id;primaryKey;autoIncrement"`
Source string `gorm:"column:source;type:varchar(32);not null;uniqueIndex:uk_token_reward_rules_source;comment:forum_like/forum_import"`
Name string `gorm:"column:name;type:varchar(80);not null;comment:规则名称"`
Amount int64 `gorm:"column:amount;not null;comment:奖励Token数量"`
Status string `gorm:"column:status;type:varchar(32);not null;default:'active';index:idx_token_reward_rules_status;comment:active/inactive"`
ConfigJSON *string `gorm:"column:config_json;type:json;comment:预留扩展配置"`
CreatedAt time.Time `gorm:"column:created_at;autoCreateTime;comment:创建时间"`
UpdatedAt time.Time `gorm:"column:updated_at;autoUpdateTime;comment:更新时间"`
}
func (TokenRewardRule) TableName() string {
return "token_reward_rules"
}