schema.prisma 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. generator client {
  2. provider = "prisma-client-js"
  3. }
  4. datasource db {
  5. provider = "mysql"
  6. url = env("DATABASE_URL")
  7. }
  8. model User {
  9. id Int @id @default(autoincrement())
  10. phone String? @unique
  11. openid String? @unique
  12. nickname String @default("用户")
  13. avatar String @default("")
  14. memberLevel Int @default(0)
  15. memberExpireAt DateTime?
  16. dailyUsage Int @default(0)
  17. lastUsageDate String @default("")
  18. createdAt DateTime @default(now())
  19. updatedAt DateTime @updatedAt
  20. orders Order[]
  21. playRecords PlayRecord[]
  22. preferences UserPreference?
  23. favorites Favorite[]
  24. comments Comment[]
  25. @@index([phone])
  26. @@index([openid])
  27. }
  28. // 订单
  29. model Order {
  30. id Int @id @default(autoincrement())
  31. userId Int
  32. orderNo String @unique
  33. productType String // monthly 或 yearly
  34. amount Decimal @db.Decimal(10, 2)
  35. status String @default("pending")
  36. paymentMethod String?
  37. paidAt DateTime?
  38. createdAt DateTime @default(now())
  39. updatedAt DateTime @updatedAt
  40. user User @relation(fields: [userId], references: [id])
  41. @@index([userId, createdAt])
  42. @@index([orderNo])
  43. }
  44. // 播放记录(播放的是章节的音频)
  45. model PlayRecord {
  46. id Int @id @default(autoincrement())
  47. userId Int
  48. chapterId Int // BookChapter.id(章节ID)
  49. progress Float @default(0) // 播放进度(秒)
  50. duration Float @default(0) // 总时长
  51. updatedAt DateTime @updatedAt
  52. createdAt DateTime @default(now())
  53. user User @relation(fields: [userId], references: [id])
  54. chapter BookChapter @relation(fields: [chapterId], references: [id])
  55. @@unique([userId, chapterId])
  56. @@index([userId])
  57. @@index([chapterId])
  58. }
  59. // 用户偏好
  60. model UserPreference {
  61. id Int @id @default(autoincrement())
  62. userId Int @unique
  63. playSpeed Float @default(1.0)
  64. quality String @default("standard") // standard, high
  65. theme String @default("light")
  66. updatedAt DateTime @updatedAt
  67. createdAt DateTime @default(now())
  68. user User @relation(fields: [userId], references: [id])
  69. }
  70. // 收藏(收藏的是书籍/专辑)
  71. model Favorite {
  72. id Int @id @default(autoincrement())
  73. userId Int
  74. bookId Int // Book.id(收藏的是整本书籍)
  75. createdAt DateTime @default(now())
  76. user User @relation(fields: [userId], references: [id])
  77. book Book @relation(fields: [bookId], references: [id], onDelete: Cascade)
  78. @@unique([userId, bookId])
  79. @@index([userId])
  80. @@index([bookId])
  81. }
  82. // 分类
  83. model Category {
  84. id Int @id @default(autoincrement())
  85. name String
  86. icon String @default("")
  87. sort Int @default(0)
  88. createdAt DateTime @default(now())
  89. }
  90. // 评论(评论的是章节)
  91. model Comment {
  92. id Int @id @default(autoincrement())
  93. userId Int
  94. chapterId Int // BookChapter.id
  95. content String @db.Text
  96. rating Int // 1-5星
  97. createdAt DateTime @default(now())
  98. user User @relation(fields: [userId], references: [id])
  99. chapter BookChapter @relation(fields: [chapterId], references: [id])
  100. @@index([chapterId])
  101. @@index([userId])
  102. }
  103. // 系统通知
  104. model Notification {
  105. id String @id @default(uuid())
  106. userId String
  107. title String
  108. content String @db.Text
  109. isRead Boolean @default(false)
  110. createdAt DateTime @default(now())
  111. }
  112. // ============ 模板管理 ============
  113. model Template {
  114. id Int @id @default(autoincrement())
  115. name String
  116. category String // 广告营销/知识付费/短视频/企业宣传/日常生活/新闻资讯
  117. content String @db.Text // 模板内容
  118. description String? @db.Text // 模板描述
  119. createdAt DateTime @default(now())
  120. updatedAt DateTime @updatedAt
  121. @@index([category])
  122. }
  123. // ============ 书籍/章节(核心内容) ============
  124. // 书籍(专辑)
  125. model Book {
  126. id Int @id @default(autoincrement())
  127. userId Int?
  128. title String // 书名
  129. subtitle String? // 副标题
  130. description String @db.Text // 书籍描述/用户输入
  131. coverUrl String? // 封面图
  132. targetAudience String @default("通用") // 目标受众
  133. style String @default("专业严谨") // 写作风格
  134. totalChapters Int @default(10) // 总章节数
  135. estimatedWords Int @default(0) // 预估总字数
  136. status String @default("draft") // draft, planning, generating, completed, failed
  137. progress Int @default(0) // 生成进度 0-100
  138. isPublished Boolean @default(false) // 是否已发布
  139. // 大纲(JSON 存储)
  140. outlineJson String? @db.LongText // BookOutline JSON
  141. // 前言/后记
  142. foreword String? @db.Text
  143. afterword String? @db.Text
  144. // 错误信息
  145. errorMsg String? @db.Text
  146. createdAt DateTime @default(now())
  147. updatedAt DateTime @updatedAt
  148. chapters BookChapter[]
  149. videoProjects VideoProject[] // 关联的视频项目
  150. favorites Favorite[] // 收藏此书籍的用户
  151. @@index([userId, status])
  152. @@index([createdAt])
  153. }
  154. // 书籍章节(内容单元)
  155. // 一个章节 = 一份内容,有3种形式:content(文本)、audioUrl(音频)、videoUrl(视频)
  156. model BookChapter {
  157. id Int @id @default(autoincrement())
  158. bookId Int
  159. number Int // 章节序号
  160. title String // 章节标题
  161. summary String? @db.Text // 章节概述
  162. keyPoints String? @db.Text // 核心知识点(JSON数组)
  163. estimatedWords Int @default(1000) // 预估字数
  164. content String? @db.LongText // 正文内容(原始文本)
  165. wordCount Int @default(0) // 实际字数
  166. status String @default("pending") // pending, generating, completed, failed
  167. errorMsg String? @db.Text
  168. generatedAt DateTime?
  169. // 3种表现形式
  170. audioUrl String? @db.Text // 音频URL(由 content 生成)
  171. audioDuration Int @default(0) // 音频时长(秒)
  172. videoUrl String? @db.Text // 视频URL(由 content/audio 生成)
  173. videoDuration Int? // 视频时长(秒)
  174. book Book @relation(fields: [bookId], references: [id], onDelete: Cascade)
  175. videoProjects VideoProject[]
  176. playRecords PlayRecord[]
  177. comments Comment[]
  178. @@unique([bookId, number])
  179. @@index([bookId])
  180. }
  181. // ============ 学习路径模块 ============
  182. // 学习路径任务
  183. model LearningPath {
  184. id Int @id @default(autoincrement())
  185. userId Int?
  186. topic String @db.Text // 用户输入的主题
  187. status String @default("pending") // pending, generating, completed, failed
  188. progress Int @default(0) // 0-100 进度百分比
  189. totalCount Int @default(0) // 总内容块数
  190. completedCount Int @default(0) // 已完成内容块数
  191. errorMsg String? @db.Text // 错误信息
  192. // 生成模式: progressive(渐进确认) | multi-agent(多Agent并行)
  193. generationMode String @default("progressive")
  194. // 当前步骤(渐进模式): pending, subjects, chapters, sections, content, completed
  195. currentStep String @default("pending")
  196. // 多Agent模式状态: 存储各Agent的进度JSON
  197. agentStatus String? @db.Text
  198. createdAt DateTime @default(now())
  199. updatedAt DateTime @updatedAt
  200. subjects Subject[]
  201. @@index([userId, status])
  202. }
  203. // 学科(大类)
  204. model Subject {
  205. id Int @id @default(autoincrement())
  206. learningPathId Int
  207. name String // 学科名称,如"计算机原理"
  208. orderIndex Int @default(0) // 排序
  209. status String @default("pending") // pending, generating, completed
  210. aiResponse String? @db.Text // AI返回的原始内容
  211. // 确认状态(渐进模式): pending, confirmed, regenerating
  212. confirmationStatus String @default("pending")
  213. createdAt DateTime @default(now())
  214. updatedAt DateTime @updatedAt
  215. learningPath LearningPath @relation(fields: [learningPathId], references: [id], onDelete: Cascade)
  216. chapters Chapter[]
  217. @@index([learningPathId, orderIndex])
  218. }
  219. // 章节
  220. model Chapter {
  221. id Int @id @default(autoincrement())
  222. subjectId Int
  223. name String // 章节名称
  224. orderIndex Int @default(0)
  225. status String @default("pending")
  226. aiResponse String? @db.Text
  227. // 确认状态(渐进模式): pending, confirmed, regenerating
  228. confirmationStatus String @default("pending")
  229. createdAt DateTime @default(now())
  230. updatedAt DateTime @updatedAt
  231. subject Subject @relation(fields: [subjectId], references: [id], onDelete: Cascade)
  232. sections Section[]
  233. @@index([subjectId, orderIndex])
  234. }
  235. // 小节
  236. model Section {
  237. id Int @id @default(autoincrement())
  238. chapterId Int
  239. name String // 小节名称
  240. orderIndex Int @default(0)
  241. status String @default("pending")
  242. aiResponse String? @db.Text
  243. // 确认状态(渐进模式): pending, confirmed, regenerating
  244. confirmationStatus String @default("pending")
  245. createdAt DateTime @default(now())
  246. updatedAt DateTime @updatedAt
  247. chapter Chapter @relation(fields: [chapterId], references: [id], onDelete: Cascade)
  248. contentBlocks ContentBlock[]
  249. @@index([chapterId, orderIndex])
  250. }
  251. // 内容块(详细内容)
  252. model ContentBlock {
  253. id Int @id @default(autoincrement())
  254. sectionId Int
  255. content String @db.Text // 详细内容
  256. orderIndex Int @default(0)
  257. wordCount Int @default(0)
  258. createdAt DateTime @default(now())
  259. updatedAt DateTime @updatedAt
  260. section Section @relation(fields: [sectionId], references: [id], onDelete: Cascade)
  261. @@index([sectionId, orderIndex])
  262. }
  263. // ============ 视频生成模块 ============
  264. // 视频项目(关联到书籍的某个章节)
  265. model VideoProject {
  266. id Int @id @default(autoincrement())
  267. userId Int?
  268. title String // 项目标题
  269. description String? // 描述
  270. coverUrl String? // 封面图
  271. // 素材配置(JSON存储)
  272. configJson String? @db.LongText // VideoConfig JSON
  273. // 输出视频
  274. outputUrl String? // 生成后的视频URL
  275. duration Int? // 视频时长(秒)
  276. fileSize Int? // 文件大小(字节)
  277. // 关联:直接关联到章节
  278. bookId Int? // 关联的书籍ID(可选)
  279. chapterId Int? // 关联的章节ID(直接关联章节获取 content/audioUrl)
  280. status String @default("draft") // draft, processing, completed, failed
  281. progress Int @default(0) // 0-100
  282. errorMsg String? @db.Text
  283. createdAt DateTime @default(now())
  284. updatedAt DateTime @updatedAt
  285. book Book? @relation(fields: [bookId], references: [id])
  286. chapter BookChapter? @relation(fields: [chapterId], references: [id])
  287. @@index([userId, status])
  288. @@index([createdAt])
  289. }
  290. // 视频素材库(保留作为独立素材)
  291. model VideoMaterial {
  292. id Int @id @default(autoincrement())
  293. userId Int? // null 表示公共素材
  294. type String // image, audio, template
  295. name String // 素材名称
  296. url String @db.Text // 素材URL
  297. thumbnail String? // 缩略图URL
  298. tags String? @db.Text // 标签(JSON数组)
  299. category String? // 分类:nature, abstract, business, music等
  300. duration Int? // 音频时长(秒)
  301. size Int? // 文件大小(字节)
  302. width Int? // 图片宽度
  303. height Int? // 图片高度
  304. createdAt DateTime @default(now())
  305. updatedAt DateTime @updatedAt
  306. @@index([userId, type])
  307. @@index([type, category])
  308. }