305 lines
11 KiB
Plaintext
305 lines
11 KiB
Plaintext
generator client {
|
||
provider = "prisma-client-js"
|
||
}
|
||
|
||
datasource db {
|
||
provider = "postgresql"
|
||
url = env("DATABASE_URL")
|
||
}
|
||
|
||
// ============================================
|
||
// 钱包账户表 (状态表)
|
||
// ============================================
|
||
model WalletAccount {
|
||
id BigInt @id @default(autoincrement()) @map("wallet_id")
|
||
accountSequence String @unique @map("account_sequence") @db.VarChar(20) // 跨服务关联标识 (全局唯一业务ID)
|
||
userId BigInt @unique @map("user_id") // 保留兼容
|
||
|
||
// USDT 余额
|
||
usdtAvailable Decimal @default(0) @map("usdt_available") @db.Decimal(20, 8)
|
||
usdtFrozen Decimal @default(0) @map("usdt_frozen") @db.Decimal(20, 8)
|
||
|
||
// DST 余额
|
||
dstAvailable Decimal @default(0) @map("dst_available") @db.Decimal(20, 8)
|
||
dstFrozen Decimal @default(0) @map("dst_frozen") @db.Decimal(20, 8)
|
||
|
||
// BNB 余额
|
||
bnbAvailable Decimal @default(0) @map("bnb_available") @db.Decimal(20, 8)
|
||
bnbFrozen Decimal @default(0) @map("bnb_frozen") @db.Decimal(20, 8)
|
||
|
||
// OG 余额
|
||
ogAvailable Decimal @default(0) @map("og_available") @db.Decimal(20, 8)
|
||
ogFrozen Decimal @default(0) @map("og_frozen") @db.Decimal(20, 8)
|
||
|
||
// RWAD 余额
|
||
rwadAvailable Decimal @default(0) @map("rwad_available") @db.Decimal(20, 8)
|
||
rwadFrozen Decimal @default(0) @map("rwad_frozen") @db.Decimal(20, 8)
|
||
|
||
// 算力
|
||
hashpower Decimal @default(0) @map("hashpower") @db.Decimal(20, 8)
|
||
|
||
// 待领取收益
|
||
pendingUsdt Decimal @default(0) @map("pending_usdt") @db.Decimal(20, 8)
|
||
pendingHashpower Decimal @default(0) @map("pending_hashpower") @db.Decimal(20, 8)
|
||
pendingExpireAt DateTime? @map("pending_expire_at")
|
||
|
||
// 可结算收益
|
||
settleableUsdt Decimal @default(0) @map("settleable_usdt") @db.Decimal(20, 8)
|
||
settleableHashpower Decimal @default(0) @map("settleable_hashpower") @db.Decimal(20, 8)
|
||
|
||
// 已结算总额
|
||
settledTotalUsdt Decimal @default(0) @map("settled_total_usdt") @db.Decimal(20, 8)
|
||
settledTotalHashpower Decimal @default(0) @map("settled_total_hashpower") @db.Decimal(20, 8)
|
||
|
||
// 已过期总额
|
||
expiredTotalUsdt Decimal @default(0) @map("expired_total_usdt") @db.Decimal(20, 8)
|
||
expiredTotalHashpower Decimal @default(0) @map("expired_total_hashpower") @db.Decimal(20, 8)
|
||
|
||
// 状态
|
||
status String @default("ACTIVE") @map("status") @db.VarChar(20)
|
||
|
||
// 是否已认种过(认种后分享权益直接进入可结算)
|
||
hasPlanted Boolean @default(false) @map("has_planted")
|
||
|
||
// 乐观锁版本号
|
||
version Int @default(0) @map("version")
|
||
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
||
@@map("wallet_accounts")
|
||
@@index([userId])
|
||
@@index([usdtAvailable(sort: Desc)])
|
||
@@index([hashpower(sort: Desc)])
|
||
@@index([status])
|
||
}
|
||
|
||
// ============================================
|
||
// 账本流水表 (行为表, append-only)
|
||
// ============================================
|
||
model LedgerEntry {
|
||
id BigInt @id @default(autoincrement()) @map("entry_id")
|
||
accountSequence String @map("account_sequence") @db.VarChar(20) // 跨服务关联标识
|
||
userId BigInt @map("user_id") // 保留兼容
|
||
|
||
// 流水类型
|
||
entryType String @map("entry_type") @db.VarChar(50)
|
||
|
||
// 金额变动 (正数入账, 负数支出)
|
||
amount Decimal @map("amount") @db.Decimal(20, 8)
|
||
assetType String @map("asset_type") @db.VarChar(20)
|
||
|
||
// 余额快照 (操作后余额)
|
||
balanceAfter Decimal? @map("balance_after") @db.Decimal(20, 8)
|
||
|
||
// 关联引用
|
||
refOrderId String? @map("ref_order_id") @db.VarChar(100)
|
||
refTxHash String? @map("ref_tx_hash") @db.VarChar(100)
|
||
|
||
// 备注
|
||
memo String? @map("memo") @db.VarChar(500)
|
||
|
||
// 扩展数据
|
||
payloadJson Json? @map("payload_json")
|
||
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
@@map("wallet_ledger_entries")
|
||
@@index([accountSequence, createdAt(sort: Desc)])
|
||
@@index([userId, createdAt(sort: Desc)])
|
||
@@index([entryType])
|
||
@@index([assetType])
|
||
@@index([refOrderId])
|
||
@@index([refTxHash])
|
||
@@index([createdAt])
|
||
}
|
||
|
||
// ============================================
|
||
// 充值订单表
|
||
// ============================================
|
||
model DepositOrder {
|
||
id BigInt @id @default(autoincrement()) @map("order_id")
|
||
accountSequence String @map("account_sequence") @db.VarChar(20) // 跨服务关联标识
|
||
userId BigInt @map("user_id") // 保留兼容
|
||
|
||
// 充值信息
|
||
chainType String @map("chain_type") @db.VarChar(20)
|
||
amount Decimal @map("amount") @db.Decimal(20, 8)
|
||
txHash String @unique @map("tx_hash") @db.VarChar(100)
|
||
|
||
// 状态
|
||
status String @default("PENDING") @map("status") @db.VarChar(20)
|
||
confirmedAt DateTime? @map("confirmed_at")
|
||
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
@@map("deposit_orders")
|
||
@@index([accountSequence])
|
||
@@index([userId])
|
||
@@index([txHash])
|
||
@@index([status])
|
||
@@index([chainType])
|
||
}
|
||
|
||
// ============================================
|
||
// 结算订单表
|
||
// ============================================
|
||
model SettlementOrder {
|
||
id BigInt @id @default(autoincrement()) @map("order_id")
|
||
userId BigInt @map("user_id")
|
||
|
||
// 结算信息
|
||
usdtAmount Decimal @map("usdt_amount") @db.Decimal(20, 8)
|
||
settleCurrency String @map("settle_currency") @db.VarChar(10)
|
||
|
||
// SWAP 信息
|
||
swapTxHash String? @map("swap_tx_hash") @db.VarChar(100)
|
||
receivedAmount Decimal? @map("received_amount") @db.Decimal(20, 8)
|
||
|
||
// 状态
|
||
status String @default("PENDING") @map("status") @db.VarChar(20)
|
||
settledAt DateTime? @map("settled_at")
|
||
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
@@map("settlement_orders")
|
||
@@index([userId])
|
||
@@index([status])
|
||
@@index([settleCurrency])
|
||
@@index([createdAt])
|
||
}
|
||
|
||
// ============================================
|
||
// 提现订单表
|
||
// ============================================
|
||
model WithdrawalOrder {
|
||
id BigInt @id @default(autoincrement()) @map("order_id")
|
||
orderNo String @unique @map("order_no") @db.VarChar(50)
|
||
accountSequence String @map("account_sequence") @db.VarChar(20) // 跨服务关联标识
|
||
userId BigInt @map("user_id")
|
||
|
||
// 提现信息
|
||
amount Decimal @map("amount") @db.Decimal(20, 8) // 提现金额
|
||
fee Decimal @map("fee") @db.Decimal(20, 8) // 手续费
|
||
chainType String @map("chain_type") @db.VarChar(20) // 目标链 (BSC/KAVA)
|
||
toAddress String @map("to_address") @db.VarChar(100) // 提现目标地址
|
||
|
||
// 交易信息
|
||
txHash String? @map("tx_hash") @db.VarChar(100) // 链上交易哈希
|
||
|
||
// 内部转账标识
|
||
isInternalTransfer Boolean @default(false) @map("is_internal_transfer") // 是否为内部转账(ID转ID)
|
||
toAccountSequence String? @map("to_account_sequence") @db.VarChar(20) // 接收方ID(内部转账时有值)
|
||
toUserId BigInt? @map("to_user_id") // 接收方用户ID(内部转账时有值)
|
||
|
||
// 状态
|
||
status String @default("PENDING") @map("status") @db.VarChar(20)
|
||
errorMessage String? @map("error_message") @db.VarChar(500)
|
||
|
||
// 时间戳
|
||
frozenAt DateTime? @map("frozen_at")
|
||
broadcastedAt DateTime? @map("broadcasted_at")
|
||
confirmedAt DateTime? @map("confirmed_at")
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
@@map("withdrawal_orders")
|
||
@@index([accountSequence])
|
||
@@index([userId])
|
||
@@index([status])
|
||
@@index([chainType])
|
||
@@index([txHash])
|
||
@@index([createdAt])
|
||
}
|
||
|
||
// ============================================
|
||
// 待领取奖励表 (逐笔记录)
|
||
// 每笔待领取奖励独立跟踪过期时间
|
||
// ============================================
|
||
model PendingReward {
|
||
id BigInt @id @default(autoincrement()) @map("pending_reward_id")
|
||
accountSequence String @map("account_sequence") @db.VarChar(20) // 跨服务关联标识
|
||
userId BigInt @map("user_id") // 保留兼容
|
||
|
||
// 奖励金额
|
||
usdtAmount Decimal @map("usdt_amount") @db.Decimal(20, 8)
|
||
hashpowerAmount Decimal @map("hashpower_amount") @db.Decimal(20, 8)
|
||
|
||
// 来源信息
|
||
sourceOrderId String @map("source_order_id") @db.VarChar(100) // 触发奖励的认种订单
|
||
allocationType String @map("allocation_type") @db.VarChar(50) // 分配类型 (SHARE_RIGHT, TEAM_RIGHT 等)
|
||
|
||
// 过期时间
|
||
expireAt DateTime @map("expire_at")
|
||
|
||
// 状态: PENDING(待领取) / SETTLED(已结算) / EXPIRED(已过期)
|
||
status String @default("PENDING") @map("status") @db.VarChar(20)
|
||
|
||
// 结算/过期时间
|
||
settledAt DateTime? @map("settled_at")
|
||
expiredAt DateTime? @map("expired_at")
|
||
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
|
||
@@map("pending_rewards")
|
||
@@index([accountSequence, status])
|
||
@@index([userId, status])
|
||
@@index([status, expireAt]) // 用于定时任务查询过期奖励
|
||
@@index([sourceOrderId])
|
||
@@index([createdAt])
|
||
}
|
||
|
||
// ============================================
|
||
// 提取手续费配置表
|
||
// ============================================
|
||
model WithdrawalFeeConfig {
|
||
id BigInt @id @default(autoincrement()) @map("config_id")
|
||
|
||
// 费率类型: FIXED(固定金额) / PERCENTAGE(百分比)
|
||
feeType String @map("fee_type") @db.VarChar(20)
|
||
|
||
// 费率值: 固定金额时为具体数值,百分比时为小数 (如 0.001 = 0.1%)
|
||
feeValue Decimal @map("fee_value") @db.Decimal(20, 8)
|
||
|
||
// 最小手续费 (百分比模式下生效)
|
||
minFee Decimal @default(0) @map("min_fee") @db.Decimal(20, 8)
|
||
|
||
// 最大手续费 (百分比模式下生效,0表示不限制)
|
||
maxFee Decimal @default(0) @map("max_fee") @db.Decimal(20, 8)
|
||
|
||
// 是否启用
|
||
isActive Boolean @default(true) @map("is_active")
|
||
|
||
// 备注
|
||
memo String? @map("memo") @db.VarChar(200)
|
||
|
||
createdAt DateTime @default(now()) @map("created_at")
|
||
updatedAt DateTime @updatedAt @map("updated_at")
|
||
|
||
@@map("withdrawal_fee_configs")
|
||
@@index([isActive])
|
||
}
|
||
|
||
// ============================================
|
||
// 已处理事件表 (幂等性检查)
|
||
// 用于确保 Kafka 事件不会被重复处理
|
||
// ============================================
|
||
model ProcessedEvent {
|
||
id BigInt @id @default(autoincrement()) @map("processed_id")
|
||
|
||
// 事件标识 (聚合根ID + 事件类型)
|
||
eventId String @map("event_id") @db.VarChar(200)
|
||
eventType String @map("event_type") @db.VarChar(100)
|
||
|
||
// 来源服务
|
||
sourceService String @map("source_service") @db.VarChar(50)
|
||
|
||
// 处理时间
|
||
processedAt DateTime @default(now()) @map("processed_at")
|
||
|
||
@@unique([eventId, eventType])
|
||
@@map("processed_events")
|
||
@@index([eventId])
|
||
@@index([eventType])
|
||
@@index([processedAt])
|
||
}
|