| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- generator client {
- provider = "prisma-client-js"
- }
- datasource db {
- provider = "mysql"
- url = env("DATABASE_URL")
- }
- model User {
- id Int @id @default(autoincrement())
- phone String? @unique
- openid String? @unique
- nickname String @default("用户")
- avatar String @default("")
- memberLevel Int @default(0)
- memberExpireAt DateTime?
- dailyUsage Int @default(0)
- lastUsageDate String @default("")
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- audios Audio[]
- orders Order[]
- playRecords PlayRecord[]
- preferences UserPreference?
- favorites Favorite[]
- comments Comment[]
- albumSubscriptions AlbumSubscription[]
- @@index([phone])
- @@index([openid])
- }
- model Audio {
- id Int @id @default(autoincrement())
- userId Int?
- title String
- text String @db.Text
- summary String? @db.Text
- tags String? @db.Text // JSON 字符串存储数组
- audioUrl String @db.Text
- audioDuration Int @default(0)
- audioSize Int @default(0)
- wordCount Int
- voiceId String
- voiceParams String? @db.Text // JSON 存储 {speed, pitch, volume}
- status String @default("processing")
- isFavorite Boolean @default(false)
- categoryId Int?
- albumId Int? // 专辑ID,没有则归入默认专辑
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- user User? @relation(fields: [userId], references: [id])
- category Category? @relation("CategoryAudios", fields: [categoryId], references: [id])
- album Album? @relation(fields: [albumId], references: [id])
- playRecords PlayRecord[]
- favorites Favorite[]
- comments Comment[]
- albumAudios AlbumAudio[]
- @@index([userId, createdAt])
- @@index([userId, isFavorite])
- @@index([categoryId])
- @@index([albumId])
- }
- model Order {
- id Int @id @default(autoincrement())
- userId Int
- orderNo String @unique
- productType String // monthly 或 yearly
- amount Decimal @db.Decimal(10, 2)
- status String @default("pending")
- paymentMethod String?
- paidAt DateTime?
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
-
- user User @relation(fields: [userId], references: [id])
-
- @@index([userId, createdAt])
- @@index([orderNo])
- }
- model PlayRecord {
- id Int @id @default(autoincrement())
- userId Int
- audioId Int
- progress Float @default(0) // 播放进度(秒)
- duration Float @default(0) // 总时长
- updatedAt DateTime @updatedAt
- createdAt DateTime @default(now())
-
- user User @relation(fields: [userId], references: [id])
- audio Audio @relation(fields: [audioId], references: [id])
-
- @@unique([userId, audioId])
- @@index([userId])
- @@index([audioId])
- }
- model UserPreference {
- id Int @id @default(autoincrement())
- userId Int @unique
- playSpeed Float @default(1.0)
- quality String @default("standard") // standard, high
- theme String @default("light")
- updatedAt DateTime @updatedAt
- createdAt DateTime @default(now())
-
- user User @relation(fields: [userId], references: [id])
- }
- model Favorite {
- id Int @id @default(autoincrement())
- userId Int
- audioId Int
- createdAt DateTime @default(now())
-
- user User @relation(fields: [userId], references: [id])
- audio Audio @relation(fields: [audioId], references: [id])
-
- @@unique([userId, audioId])
- @@index([userId])
- }
- model Category {
- id Int @id @default(autoincrement())
- name String
- icon String @default("")
- sort Int @default(0)
- createdAt DateTime @default(now())
-
- audios Audio[] @relation("CategoryAudios")
- }
- model Comment {
- id Int @id @default(autoincrement())
- userId Int
- audioId Int
- content String @db.Text
- rating Int // 1-5星
- createdAt DateTime @default(now())
- user User @relation(fields: [userId], references: [id])
- audio Audio @relation(fields: [audioId], references: [id])
- @@index([audioId])
- @@index([userId])
- }
- model Notification {
- id String @id @default(uuid())
- userId String
- title String
- content String @db.Text
- isRead Boolean @default(false)
- createdAt DateTime @default(now())
- }
- model Album {
- id Int @id @default(autoincrement())
- name String
- description String? @db.Text
- coverUrl String?
- userId Int?
- isDefault Boolean @default(false) // 是否是默认专辑
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- albumAudios AlbumAudio[]
- subscriptions AlbumSubscription[]
- audios Audio[]
- @@index([userId])
- @@index([createdAt])
- }
- model AlbumAudio {
- id Int @id @default(autoincrement())
- albumId Int
- audioId Int
- order Int @default(0)
- addedAt DateTime @default(now())
- album Album @relation(fields: [albumId], references: [id], onDelete: Cascade)
- audio Audio @relation(fields: [audioId], references: [id], onDelete: Cascade)
- @@unique([albumId, audioId])
- @@index([albumId])
- @@index([audioId])
- }
- model AlbumSubscription {
- id Int @id @default(autoincrement())
- userId Int
- albumId Int
- createdAt DateTime @default(now())
- user User @relation(fields: [userId], references: [id], onDelete: Cascade)
- album Album @relation(fields: [albumId], references: [id], onDelete: Cascade)
- @@unique([userId, albumId])
- @@index([userId])
- @@index([albumId])
- }
- model Template {
- id Int @id @default(autoincrement())
- name String
- category String // 广告营销/知识付费/短视频/企业宣传/日常生活/新闻资讯
- content String @db.Text // 模板内容
- description String? @db.Text // 模板描述
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- @@index([category])
- }
- // 学习路径任务
- model LearningPath {
- id Int @id @default(autoincrement())
- userId Int?
- topic String @db.Text // 用户输入的主题
- status String @default("pending") // pending, generating, completed, failed
- progress Int @default(0) // 0-100 进度百分比
- totalCount Int @default(0) // 总内容块数
- completedCount Int @default(0) // 已完成内容块数
- errorMsg String? @db.Text // 错误信息
- // 生成模式: progressive(渐进确认) | multi-agent(多Agent并行)
- generationMode String @default("progressive")
- // 当前步骤(渐进模式): pending, subjects, chapters, sections, content, completed
- currentStep String @default("pending")
- // 多Agent模式状态: 存储各Agent的进度JSON
- agentStatus String? @db.Text
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- subjects Subject[]
- @@index([userId, status])
- }
- // 学科(大类)
- model Subject {
- id Int @id @default(autoincrement())
- learningPathId Int
- name String // 学科名称,如"计算机原理"
- orderIndex Int @default(0) // 排序
- status String @default("pending") // pending, generating, completed
- aiResponse String? @db.Text // AI返回的原始内容
- // 确认状态(渐进模式): pending, confirmed, regenerating
- confirmationStatus String @default("pending")
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- learningPath LearningPath @relation(fields: [learningPathId], references: [id], onDelete: Cascade)
- chapters Chapter[]
- @@index([learningPathId, orderIndex])
- }
- // 章节
- model Chapter {
- id Int @id @default(autoincrement())
- subjectId Int
- name String // 章节名称
- orderIndex Int @default(0)
- status String @default("pending")
- aiResponse String? @db.Text
- // 确认状态(渐进模式): pending, confirmed, regenerating
- confirmationStatus String @default("pending")
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- subject Subject @relation(fields: [subjectId], references: [id], onDelete: Cascade)
- sections Section[]
- @@index([subjectId, orderIndex])
- }
- // 小节
- model Section {
- id Int @id @default(autoincrement())
- chapterId Int
- name String // 小节名称
- orderIndex Int @default(0)
- status String @default("pending")
- aiResponse String? @db.Text
- // 确认状态(渐进模式): pending, confirmed, regenerating
- confirmationStatus String @default("pending")
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- chapter Chapter @relation(fields: [chapterId], references: [id], onDelete: Cascade)
- contentBlocks ContentBlock[]
- @@index([chapterId, orderIndex])
- }
- // 内容块(详细内容)
- model ContentBlock {
- id Int @id @default(autoincrement())
- sectionId Int
- content String @db.Text // 详细内容
- orderIndex Int @default(0)
- wordCount Int @default(0)
- createdAt DateTime @default(now())
- updatedAt DateTime @updatedAt
- section Section @relation(fields: [sectionId], references: [id], onDelete: Cascade)
- @@index([sectionId, orderIndex])
- }
|