flnxi-Wu/prisma/schema.prisma
2026-05-25 15:36:51 +08:00

418 lines
14 KiB
Plaintext
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.

generator client {
provider = "prisma-client-js"
binaryTargets = ["native", "linux-musl-openssl-3.0.x"]
}
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
enum Role {
USER
ADMIN
}
model User {
id String @id @default(uuid())
email String @unique
username String @unique
password String
role Role @default(USER)
isActive Boolean @default(false)
canDownload Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
department String @default("")
dingtalkUserId String? @unique
loginType String @default("normal")
realName String?
phone String? @unique
avatar String?
managedDepartment String?
isSuperAdmin Boolean @default(false)
parentId String?
likes MaterialLike[]
materials Material[]
downloadLogs MaterialDownloadLog[]
materialLogs MaterialLog[]
parent User? @relation("UserHierarchy", fields: [parentId], references: [id])
children User[] @relation("UserHierarchy")
favorites MaterialFavorite[]
browseHistory BrowseHistory[]
materialShareTokens MaterialShareToken[]
@@map("users")
}
model MaterialShareToken {
id String @id @default(uuid())
tokenHash String @unique
materialId String
createdByUserId String
expiresAt DateTime
revokedAt DateTime?
createdAt DateTime @default(now())
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
createdBy User @relation(fields: [createdByUserId], references: [id], onDelete: Cascade)
@@index([materialId])
@@index([createdByUserId])
@@index([expiresAt])
@@index([revokedAt])
@@map("material_share_tokens")
}
model UploadTemplate {
id String @id @default(uuid())
name String
description String?
status String @default("draft")
materialType String @default("其他")
/// 模板素材类型大类:IMAGE / VIDEO / OTHER(与具体 materialType 文案解耦)
materialKind String @default("IMAGE")
version Int @default(1)
fieldGroups String?
displayConfig String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
fields UploadField[]
materials Material[]
@@index([status])
@@index([materialType])
@@index([materialKind])
@@index([createdAt])
@@index([updatedAt])
}
model UploadField {
id String @id @default(uuid())
templateId String
key String
label String
type String
required Boolean @default(false)
orderIndex Int @default(0)
layoutWidth String?
validations String?
optionsSource String?
optionsStatic String?
allowedExtensions String?
visibleOnHomeFilter Boolean @default(false)
isSearchable Boolean @default(false)
isReadOnly Boolean @default(false)
addToCategory Boolean @default(false)
conditions String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
template UploadTemplate @relation(fields: [templateId], references: [id], onDelete: Cascade)
@@index([templateId])
@@index([key])
@@index([type])
@@index([visibleOnHomeFilter])
@@index([isSearchable])
@@index([addToCategory])
@@index([orderIndex])
@@index([templateId, orderIndex])
}
model FieldDefinition {
id String @id @default(uuid())
key String @unique
label String
type String @default("select")
description String?
source String @default("custom") // standard | custom
sourceTemplateIds String? // JSON array of template ids referencing this field
isStandard Boolean @default(false)
isFilterEnabled Boolean @default(false)
filterDisplayName String?
filterOrder Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
options FieldOption[]
@@index([source])
@@index([isStandard])
@@index([isFilterEnabled])
@@index([filterOrder])
@@index([isFilterEnabled, filterOrder])
}
model FieldOption {
id String @id @default(uuid())
fieldId String
value String
label String
orderIndex Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
field FieldDefinition @relation(fields: [fieldId], references: [id], onDelete: Cascade, onUpdate: NoAction)
@@unique([fieldId, value])
@@index([fieldId])
@@index([fieldId, orderIndex])
}
model FilterItem {
id String @id @default(uuid())
fieldKey String
label String
group String?
orderIndex Int @default(0)
multiSelect Boolean @default(false)
showOnHome Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
}
model Material {
id String @id @default(uuid())
previewUrl String
productModel String
brandName String?
seriesName String?
skuCode String?
materialTexture String?
categoryName String
sceneName String
materialType String @default("3DMAX")
materialKind String @default("IMAGE") // 素材大类:IMAGE / VIDEO / OTHER
renderer String @default("CR")
renderTime String?
imageResolution String?
colorMode String?
audioDuration String? // 音频时长,如:00:30、1:25
audioCategory String? // 音频分类,如:背景音乐、音效、配音
audioScene String? // 音频使用场景,如:广告、产品视频、直播
audioUrl String? // 音频文件URL,用于在线播放
authorName String
/// 素材归属类型:USER(个人负责)/ TEAM(团队空间)
ownerType String @default("TEAM")
/// 素材归属主体ID:当 ownerType=USER 时为用户ID;ownerType=TEAM 时为团队/空间ID
ownerId String @default("default-team")
/// 最初上传者用户ID(离职后仍然保留,便于追溯)
createdByUserId String?
/// 最近一次所有权移交时间
lastTransferredAt DateTime?
zipFileName String @default("")
zipFilePath String @default("")
zipFileSize BigInt @default(0)
// 视频类素材相关字段(为后续视频预览 / 转码预留)
videoSourceUrl String? // 源视频文件 URL
videoPreview540Url String? // 540P 预览视频 URL
videoPreviewClipUrl String? // 首页卡片用 10 秒超小预览视频 URL
videoCoverUrl String? // 从视频帧中截取的封面图 URL
videoDuration Int? // 视频时长(秒)
videoProcessingStatus String? // 视频处理状态:pending / processing / done / failed
downloadCount Int @default(0)
likeCount Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
userId String
displayImages String @default("")
platformName String @default("")
previewUrls String? // 多预览图URLs(JSON数组格式)
metadata String?
templateId String?
isPremium Boolean @default(false)
deletedAt DateTime? // 软删除时间戳
likes MaterialLike[]
favorites MaterialFavorite[]
downloadLogs MaterialDownloadLog[]
logs MaterialLog[]
browseHistory BrowseHistory[]
shareTokens MaterialShareToken[]
template UploadTemplate? @relation(fields: [templateId], references: [id])
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId])
@@index([ownerType, ownerId])
@@index([createdByUserId])
@@index([createdAt])
@@index([categoryName])
@@index([sceneName])
@@index([platformName])
@@index([materialType])
@@index([downloadCount])
@@index([likeCount])
@@index([deletedAt])
@@map("materials")
}
model MaterialLike {
id String @id @default(uuid())
materialId String
userId String
createdAt DateTime @default(now())
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([materialId, userId])
@@index([materialId])
@@index([userId])
@@map("material_likes")
}
model MaterialFavorite {
id String @id @default(uuid())
materialId String
userId String
createdAt DateTime @default(now())
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([materialId, userId])
@@index([materialId])
@@index([userId])
@@map("material_favorites")
}
model MaterialDownloadLog {
id String @id @default(uuid())
materialId String
userId String
downloadedAt DateTime @default(now())
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([materialId])
@@index([userId])
@@index([downloadedAt])
@@index([materialId, userId, downloadedAt])
@@map("material_download_logs")
}
model MaterialLog {
id String @id @default(uuid())
materialId String
userId String
action String // 'UPLOAD', 'UPDATE', 'DELETE', 'TOGGLE_PREMIUM'
changes Json? // 详细变更记录,格式:{ "fieldName": { "oldValue": "...", "newValue": "..." } }
timestamp DateTime @default(now())
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([materialId])
@@index([userId])
@@index([timestamp])
@@map("material_logs")
}
model Category {
id String @id @default(uuid())
name String @unique
options String? // JSON array of options for dropdown
createdAt DateTime @default(now())
@@map("categories")
}
model Scene {
id String @id @default(uuid())
name String @unique
options String? // JSON array of options for dropdown
createdAt DateTime @default(now())
@@map("scenes")
}
model Platform {
id String @id @default(uuid())
name String @unique
options String? // JSON array of options for dropdown
createdAt DateTime @default(now())
@@map("platforms")
}
model SystemSettings {
id String @id @default(uuid())
headerBgColor String @default("#1f2937")
siteName String @default("FLNXI素材库")
premiumRatio Float @default(10.0)
updatedAt DateTime @updatedAt
createdAt DateTime @default(now())
headerLogoUrl String @default("http://s3.1080p.hk/shuzhou/2025/05/18/8ebadf0a7cc34eaea00e8619b8efb827.png")
loginLogoUrl String @default("http://s3.1080p.hk/shuzhou/2025/05/18/8ebadf0a7cc34eaea00e8619b8efb827.png")
s3AccessKey String @default("")
s3Bucket String @default("")
s3Endpoint String @default("")
s3PublicUrl String @default("")
s3Region String @default("us-east-1")
s3SecretKey String @default("")
enableRegistration Boolean @default(true)
enableUserActivation Boolean @default(false)
enableAiImageEdit Boolean @default(false)
enableTunnelService Boolean @default(false)
enabledBuiltinTemplates String? // JSON array of enabled builtin template keys (empty array or null = all enabled)
categoryManagedFields String? // JSON array,记录分类管理已启用的字段 key
@@map("system_settings")
}
model Department {
id String @id @default(uuid())
name String @unique
createdAt DateTime @default(now())
@@map("departments")
}
model Danmaku {
id String @id @default(uuid())
content String
username String
userId String
createdAt DateTime @default(now())
@@index([createdAt])
@@map("danmakus")
}
model Invitation {
id String @id @default(uuid())
code String @unique
createdBy String
usedBy String?
usedAt DateTime?
expiresAt DateTime?
maxUses Int @default(1)
currentUses Int @default(0)
isActive Boolean @default(true)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([code])
@@index([createdBy])
@@map("invitations")
}
model BrowseHistory {
id String @id @default(uuid())
materialId String
userId String
viewedAt DateTime @default(now())
material Material @relation(fields: [materialId], references: [id], onDelete: Cascade)
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([materialId, userId])
@@index([userId])
@@index([viewedAt])
@@index([userId, viewedAt])
@@map("browse_history")
}
// 系统配置表(用于存储许可证等配置)
model SystemConfig {
id String @id @default(uuid())
key String @unique
value String @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@map("system_configs")
}