283 lines
9.2 KiB
Plaintext
283 lines
9.2 KiB
Plaintext
// This is your Prisma schema file,
|
|
// learn more about it in the docs: https://pris.ly/d/prisma-schema
|
|
|
|
generator client {
|
|
provider = "prisma-client-js"
|
|
}
|
|
|
|
datasource db {
|
|
provider = "postgresql"
|
|
url = env("DATABASE_URL")
|
|
}
|
|
|
|
// ============================================
|
|
// 用户表
|
|
// ============================================
|
|
model User {
|
|
id String @id @default(uuid())
|
|
username String @unique @db.VarChar(50)
|
|
email String @unique @db.VarChar(100)
|
|
passwordHash String @map("password_hash") @db.VarChar(255)
|
|
avatar String? @db.VarChar(255)
|
|
|
|
// VIP 状态
|
|
isVip Boolean @default(false) @map("is_vip")
|
|
vipLevel Int @default(0) @map("vip_level")
|
|
vipExpireAt DateTime? @map("vip_expire_at")
|
|
|
|
// Token 吊销 (递增版本号使旧 token 失效)
|
|
tokenVersion Int @default(0) @map("token_version")
|
|
|
|
// 统计
|
|
schemesCount Int @default(0) @map("schemes_count")
|
|
favoritesCount Int @default(0) @map("favorites_count")
|
|
|
|
// 设备绑定
|
|
installId String? @map("install_id") @db.VarChar(64)
|
|
deviceHash String? @map("device_hash") @db.VarChar(64)
|
|
lastDeviceCheck DateTime? @map("last_device_check")
|
|
|
|
// 元数据
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
lastLoginAt DateTime? @map("last_login_at")
|
|
deletedAt DateTime? @map("deleted_at")
|
|
|
|
// 关系
|
|
schemes Scheme[]
|
|
schemesAob SchemeAob[]
|
|
filterShares FilterShare[]
|
|
favorites Favorite[]
|
|
likes Like[]
|
|
logs UserLog[]
|
|
usedVipCards VipCard[] @relation("UsedCards")
|
|
deviceBindings DeviceBinding[]
|
|
|
|
@@map("users")
|
|
}
|
|
|
|
// ============================================
|
|
// VIP 卡密表
|
|
// ============================================
|
|
model VipCard {
|
|
id String @id @default(uuid())
|
|
cardKey String @unique @map("card_key") @db.VarChar(50)
|
|
|
|
cardType String @map("card_type") @db.VarChar(20)
|
|
days Int
|
|
|
|
status String @default("UNUSED") @db.VarChar(20)
|
|
usedBy String? @map("used_by")
|
|
usedAt DateTime? @map("used_at")
|
|
|
|
batchId String? @map("batch_id")
|
|
generatedAt DateTime @default(now()) @map("generated_at")
|
|
|
|
originalPrice Decimal? @map("original_price") @db.Decimal(10, 2)
|
|
salePrice Decimal? @map("sale_price") @db.Decimal(10, 2)
|
|
|
|
user User? @relation("UsedCards", fields: [usedBy], references: [id], onDelete: SetNull)
|
|
|
|
@@map("vip_cards")
|
|
}
|
|
|
|
// ============================================
|
|
// 方案表 - 烽火地带
|
|
// ============================================
|
|
model Scheme {
|
|
id String @id @default(uuid())
|
|
userId String @map("user_id")
|
|
|
|
title String? @db.VarChar(100)
|
|
description String? @db.Text
|
|
weaponName String? @map("weapon_name") @db.VarChar(100)
|
|
category String? @db.VarChar(50)
|
|
|
|
schemeContent String @map("scheme_content") @db.Text
|
|
contentEncrypted Boolean @default(true) @map("content_encrypted")
|
|
|
|
price Int @default(0)
|
|
|
|
viewsCount Int @default(0) @map("views_count")
|
|
downloadsCount Int @default(0) @map("downloads_count")
|
|
likesCount Int @default(0) @map("likes_count")
|
|
favoritesCount Int @default(0) @map("favorites_count")
|
|
|
|
gpuModel String? @map("gpu_model") @db.VarChar(100)
|
|
driverVersion String? @map("driver_version") @db.VarChar(50)
|
|
appVersion String? @map("app_version") @db.VarChar(20)
|
|
|
|
status String @default("DRAFT") @db.VarChar(20)
|
|
isOfficial Boolean @default(false) @map("is_official")
|
|
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@index([weaponName])
|
|
@@index([category])
|
|
@@index([status])
|
|
@@map("schemes")
|
|
}
|
|
|
|
// ============================================
|
|
// 方案表 - 全面战场 (AOB)
|
|
// ============================================
|
|
model SchemeAob {
|
|
id String @id @default(uuid())
|
|
userId String @map("user_id")
|
|
|
|
title String? @db.VarChar(100)
|
|
description String? @db.Text
|
|
weaponName String? @map("weapon_name") @db.VarChar(100)
|
|
category String? @db.VarChar(50)
|
|
|
|
schemeContent String @map("scheme_content") @db.Text
|
|
contentEncrypted Boolean @default(true) @map("content_encrypted")
|
|
|
|
price Int @default(0)
|
|
|
|
viewsCount Int @default(0) @map("views_count")
|
|
downloadsCount Int @default(0) @map("downloads_count")
|
|
likesCount Int @default(0) @map("likes_count")
|
|
favoritesCount Int @default(0) @map("favorites_count")
|
|
|
|
status String @default("DRAFT") @db.VarChar(20)
|
|
isOfficial Boolean @default(false) @map("is_official")
|
|
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@index([weaponName])
|
|
@@map("schemes_aob")
|
|
}
|
|
|
|
// ============================================
|
|
// 滤镜分享表
|
|
// ============================================
|
|
model FilterShare {
|
|
id String @id @default(uuid())
|
|
userId String @map("user_id")
|
|
|
|
title String @db.VarChar(100)
|
|
description String? @db.Text
|
|
category String? @db.VarChar(50)
|
|
|
|
filterContent String @map("filter_content") @db.Text
|
|
contentFormat String @default("MQTS1") @map("content_format") @db.VarChar(20)
|
|
|
|
viewsCount Int @default(0) @map("views_count")
|
|
likesCount Int @default(0) @map("likes_count")
|
|
|
|
status String @default("DRAFT") @db.VarChar(20)
|
|
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@index([userId])
|
|
@@map("filter_shares")
|
|
}
|
|
|
|
// ============================================
|
|
// 收藏表
|
|
// ============================================
|
|
model Favorite {
|
|
id String @id @default(uuid())
|
|
userId String @map("user_id")
|
|
targetType String @map("target_type") @db.VarChar(20)
|
|
targetId String @map("target_id")
|
|
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, targetType, targetId])
|
|
@@index([userId])
|
|
@@map("favorites")
|
|
}
|
|
|
|
// ============================================
|
|
// 点赞表
|
|
// ============================================
|
|
model Like {
|
|
id String @id @default(uuid())
|
|
userId String @map("user_id")
|
|
targetType String @map("target_type") @db.VarChar(20)
|
|
targetId String @map("target_id")
|
|
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, targetType, targetId])
|
|
@@index([userId])
|
|
@@index([targetType, targetId])
|
|
@@map("likes")
|
|
}
|
|
|
|
// ============================================
|
|
// 分类表
|
|
// ============================================
|
|
model Category {
|
|
id String @id @default(uuid())
|
|
name String @db.VarChar(50)
|
|
type String @db.VarChar(20)
|
|
|
|
sortOrder Int @default(0) @map("sort_order")
|
|
isActive Boolean @default(true) @map("is_active")
|
|
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
@@map("categories")
|
|
}
|
|
|
|
// ============================================
|
|
// 用户日志表
|
|
// ============================================
|
|
model UserLog {
|
|
id String @id @default(uuid())
|
|
userId String? @map("user_id")
|
|
|
|
action String @db.VarChar(50)
|
|
targetType String? @map("target_type") @db.VarChar(50)
|
|
targetId String? @map("target_id")
|
|
|
|
installId String? @map("install_id") @db.VarChar(64)
|
|
deviceHash String? @map("device_hash") @db.VarChar(64)
|
|
ipAddress String? @map("ip_address") @db.VarChar(45)
|
|
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|
|
|
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
|
|
|
@@index([userId])
|
|
@@index([action])
|
|
@@map("user_logs")
|
|
}
|
|
|
|
// ============================================
|
|
// 设备绑定表
|
|
// ============================================
|
|
model DeviceBinding {
|
|
id String @id @default(uuid())
|
|
userId String @map("user_id")
|
|
installId String @map("install_id") @db.VarChar(64)
|
|
deviceHash String @map("device_hash") @db.VarChar(64)
|
|
|
|
boundAt DateTime @default(now()) @map("bound_at")
|
|
lastActiveAt DateTime? @map("last_active_at")
|
|
isActive Boolean @default(true) @map("is_active")
|
|
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
|
|
@@unique([userId, installId])
|
|
@@map("device_bindings")
|
|
}
|