159 lines
5.8 KiB
Plaintext
159 lines
5.8 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())
|
|||
|
|
phone String? @unique
|
|||
|
|
appleId String? @unique @map("apple_id")
|
|||
|
|
nickname String?
|
|||
|
|
avatar String?
|
|||
|
|
agreementAccepted Boolean @default(false) @map("agreement_accepted")
|
|||
|
|
isPro Boolean @default(false) @map("is_pro") // 是否为付费会员
|
|||
|
|
proExpireDate DateTime? @map("pro_expire_date") // 会员过期时间(可选,预留给订阅制)
|
|||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|||
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|||
|
|
|
|||
|
|
settings UserSettings?
|
|||
|
|
learningProgress UserLearningProgress[]
|
|||
|
|
achievements UserAchievement[]
|
|||
|
|
courses UserCourse[]
|
|||
|
|
|
|||
|
|
@@map("users")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
model UserSettings {
|
|||
|
|
userId String @id @map("user_id")
|
|||
|
|
pushNotification Boolean @default(true) @map("push_notification")
|
|||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|||
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|||
|
|
|
|||
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|||
|
|
|
|||
|
|
@@map("user_settings")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
model Course {
|
|||
|
|
id String @id @default(uuid())
|
|||
|
|
title String
|
|||
|
|
subtitle String? // 课程副标题
|
|||
|
|
description String?
|
|||
|
|
coverImage String? @map("cover_image")
|
|||
|
|
type String @default("system") // ✅ 新增:system | single
|
|||
|
|
status String @default("published") // ✅ 新增:published | draft
|
|||
|
|
deletedAt DateTime? @map("deleted_at") // ✅ 新增:软删除时间戳
|
|||
|
|
totalNodes Int @default(0) @map("total_nodes")
|
|||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|||
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|||
|
|
|
|||
|
|
chapters CourseChapter[]
|
|||
|
|
nodes CourseNode[]
|
|||
|
|
userCourses UserCourse[]
|
|||
|
|
|
|||
|
|
@@map("courses")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
model CourseChapter {
|
|||
|
|
id String @id @default(uuid())
|
|||
|
|
courseId String @map("course_id")
|
|||
|
|
title String
|
|||
|
|
orderIndex Int @map("order_index")
|
|||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|||
|
|
|
|||
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|||
|
|
nodes CourseNode[]
|
|||
|
|
|
|||
|
|
@@unique([courseId, orderIndex])
|
|||
|
|
@@map("course_chapters")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
model CourseNode {
|
|||
|
|
id String @id @default(uuid())
|
|||
|
|
courseId String @map("course_id")
|
|||
|
|
chapterId String? @map("chapter_id") // 可选,支持无章节的节点
|
|||
|
|
title String
|
|||
|
|
subtitle String?
|
|||
|
|
orderIndex Int @map("order_index")
|
|||
|
|
duration Int? // 预估时长(分钟)
|
|||
|
|
unlockCondition String? @map("unlock_condition") // 解锁条件
|
|||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|||
|
|
|
|||
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|||
|
|
chapter CourseChapter? @relation(fields: [chapterId], references: [id], onDelete: SetNull)
|
|||
|
|
slides NodeSlide[]
|
|||
|
|
learningProgress UserLearningProgress[]
|
|||
|
|
|
|||
|
|
@@unique([courseId, orderIndex])
|
|||
|
|
@@map("course_nodes")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
model NodeSlide {
|
|||
|
|
id String @id @default(uuid())
|
|||
|
|
nodeId String @map("node_id")
|
|||
|
|
slideType String @map("slide_type") // text | image | quiz | interactive
|
|||
|
|
orderIndex Int @map("order_index")
|
|||
|
|
content Json // 存储卡片内容(灵活结构)
|
|||
|
|
effect String? // fade_in | typewriter | slide_up
|
|||
|
|
interaction String? // tap_to_reveal | zoom | parallax
|
|||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|||
|
|
|
|||
|
|
node CourseNode @relation(fields: [nodeId], references: [id], onDelete: Cascade)
|
|||
|
|
|
|||
|
|
@@map("node_slides")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
model UserLearningProgress {
|
|||
|
|
id String @id @default(uuid())
|
|||
|
|
userId String @map("user_id")
|
|||
|
|
nodeId String @map("node_id")
|
|||
|
|
status String @default("not_started") // not_started | in_progress | completed
|
|||
|
|
startedAt DateTime? @map("started_at")
|
|||
|
|
completedAt DateTime? @map("completed_at")
|
|||
|
|
totalStudyTime Int @default(0) @map("total_study_time") // 总学习时长(秒)
|
|||
|
|
currentSlide Int @default(0) @map("current_slide") // 当前学习到的幻灯片位置
|
|||
|
|
completionRate Int @default(0) @map("completion_rate") // 完成度(%)
|
|||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|||
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|||
|
|
|
|||
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|||
|
|
node CourseNode @relation(fields: [nodeId], references: [id], onDelete: Cascade)
|
|||
|
|
|
|||
|
|
@@unique([userId, nodeId])
|
|||
|
|
@@map("user_learning_progress")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
model UserAchievement {
|
|||
|
|
id String @id @default(uuid())
|
|||
|
|
userId String @map("user_id")
|
|||
|
|
achievementType String @map("achievement_type") // lesson_completed | course_completed
|
|||
|
|
achievementData Json @map("achievement_data") // 存储成就详情
|
|||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|||
|
|
|
|||
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|||
|
|
|
|||
|
|
@@map("user_achievements")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
model UserCourse {
|
|||
|
|
id String @id @default(uuid())
|
|||
|
|
userId String @map("user_id")
|
|||
|
|
courseId String @map("course_id")
|
|||
|
|
lastOpenedAt DateTime? @map("last_opened_at") // ✅ 新增:最近打开时间,用于排序
|
|||
|
|
createdAt DateTime @default(now()) @map("created_at")
|
|||
|
|
updatedAt DateTime @updatedAt @map("updated_at")
|
|||
|
|
|
|||
|
|
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|||
|
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
|||
|
|
|
|||
|
|
@@unique([userId, courseId])
|
|||
|
|
@@map("user_courses")
|
|||
|
|
}
|