feat: add wallet and recharge cards

This commit is contained in:
JetSprow
2026-05-01 02:31:29 +10:00
parent 6d6489817d
commit 018bed3f36
32 changed files with 2058 additions and 170 deletions

View File

@@ -88,6 +88,14 @@ enum OrderKind {
TRAFFIC_TOPUP
}
enum WalletTransactionType {
BALANCE_RECHARGE
BALANCE_PAYMENT
CARD_REDEEM
ADMIN_ADJUST
REFUND
}
enum Protocol {
VMESS
VLESS
@@ -165,6 +173,18 @@ enum SupportTicketPriority {
URGENT
}
enum RechargeCardType {
BALANCE
PLAN
}
enum RechargeCardStatus {
UNUSED
REDEEMED
DISABLED
EXPIRED
}
model User {
id String @id @default(cuid())
email String @unique
@@ -196,6 +216,11 @@ model User {
supportTickets SupportTicket[]
supportReplies SupportTicketReply[]
emailTokens EmailToken[]
walletAccount WalletAccount?
walletTransactions WalletTransaction[]
walletRechargeOrders WalletRechargeOrder[]
redeemedRechargeCards RechargeCard[] @relation("RechargeCardRedeemer")
createdRechargeCards RechargeCard[] @relation("RechargeCardCreator")
}
model EmailToken {
@@ -301,6 +326,7 @@ model SubscriptionPlan {
orders Order[]
cartItems ShoppingCartItem[]
orderItems OrderItem[]
rechargeCards RechargeCard[]
@@index([type, isActive, isFeatured, sortOrder])
@@index([inboundId])
@@ -482,6 +508,7 @@ model NodeInbound {
selectedByOrders Order[]
cartItems ShoppingCartItem[]
orderItems OrderItem[]
rechargeCards RechargeCard[]
@@unique([serverId, tag])
@@unique([serverId, panelInboundId])
@@ -598,6 +625,7 @@ model Order {
items OrderItem[]
couponGrants CouponGrant[] @relation("CouponGrantUsedOrder")
inviteRewards InviteRewardLedger[]
walletTransactions WalletTransaction[]
@@index([userId])
@@index([kind])
@@ -608,6 +636,98 @@ model Order {
@@index([couponId])
}
model WalletAccount {
id String @id @default(cuid())
userId String @unique
balance Decimal @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
transactions WalletTransaction[]
@@index([updatedAt])
}
model WalletTransaction {
id String @id @default(cuid())
walletId String
userId String
type WalletTransactionType
amount Decimal
balanceAfter Decimal
description String?
orderId String?
rechargeOrderId String?
rechargeCardId String?
metadata Json?
createdAt DateTime @default(now())
wallet WalletAccount @relation(fields: [walletId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
order Order? @relation(fields: [orderId], references: [id], onDelete: SetNull)
rechargeOrder WalletRechargeOrder? @relation(fields: [rechargeOrderId], references: [id], onDelete: SetNull)
rechargeCard RechargeCard? @relation(fields: [rechargeCardId], references: [id], onDelete: SetNull)
@@index([userId, createdAt])
@@index([walletId, createdAt])
@@index([orderId])
@@index([rechargeOrderId])
@@index([rechargeCardId])
}
model WalletRechargeOrder {
id String @id @default(cuid())
userId String
amount Decimal
status OrderStatus @default(PENDING)
paymentMethod String?
paymentRef String?
paymentUrl String?
tradeNo String? @unique
expireAt DateTime?
note String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
transactions WalletTransaction[]
@@index([userId, createdAt])
@@index([status])
@@index([tradeNo])
}
model RechargeCard {
id String @id @default(cuid())
code String @unique
type RechargeCardType
status RechargeCardStatus @default(UNUSED)
balanceAmount Decimal?
planId String?
selectedInboundId String?
trafficGb Int?
batchName String?
note String?
expiresAt DateTime?
redeemedById String?
redeemedAt DateTime?
createdById String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
plan SubscriptionPlan? @relation(fields: [planId], references: [id], onDelete: SetNull)
selectedInbound NodeInbound? @relation(fields: [selectedInboundId], references: [id], onDelete: SetNull)
redeemedBy User? @relation("RechargeCardRedeemer", fields: [redeemedById], references: [id], onDelete: SetNull)
createdBy User? @relation("RechargeCardCreator", fields: [createdById], references: [id], onDelete: SetNull)
transactions WalletTransaction[]
@@index([type, status, createdAt])
@@index([planId])
@@index([redeemedById, redeemedAt])
@@index([expiresAt])
}
model NodeLatency {
id String @id @default(cuid())
nodeId String