schema.prisma 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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. audios Audio[]
  21. orders Order[]
  22. playRecords PlayRecord[]
  23. preferences UserPreference?
  24. favorites Favorite[]
  25. comments Comment[]
  26. albumSubscriptions AlbumSubscription[]
  27. @@index([phone])
  28. @@index([openid])
  29. }
  30. model Audio {
  31. id Int @id @default(autoincrement())
  32. userId Int?
  33. title String
  34. text String @db.Text
  35. summary String? @db.Text
  36. tags String? @db.Text // JSON 字符串存储数组
  37. audioUrl String @db.Text
  38. audioDuration Int @default(0)
  39. audioSize Int @default(0)
  40. wordCount Int
  41. voiceId String
  42. voiceParams String? @db.Text // JSON 存储 {speed, pitch, volume}
  43. status String @default("processing")
  44. isFavorite Boolean @default(false)
  45. categoryId Int?
  46. albumId Int? // 专辑ID,没有则归入默认专辑
  47. createdAt DateTime @default(now())
  48. updatedAt DateTime @updatedAt
  49. user User? @relation(fields: [userId], references: [id])
  50. category Category? @relation("CategoryAudios", fields: [categoryId], references: [id])
  51. album Album? @relation(fields: [albumId], references: [id])
  52. playRecords PlayRecord[]
  53. favorites Favorite[]
  54. comments Comment[]
  55. albumAudios AlbumAudio[]
  56. @@index([userId, createdAt])
  57. @@index([userId, isFavorite])
  58. @@index([categoryId])
  59. @@index([albumId])
  60. }
  61. model Order {
  62. id Int @id @default(autoincrement())
  63. userId Int
  64. orderNo String @unique
  65. productType String // monthly 或 yearly
  66. amount Decimal @db.Decimal(10, 2)
  67. status String @default("pending")
  68. paymentMethod String?
  69. paidAt DateTime?
  70. createdAt DateTime @default(now())
  71. updatedAt DateTime @updatedAt
  72. user User @relation(fields: [userId], references: [id])
  73. @@index([userId, createdAt])
  74. @@index([orderNo])
  75. }
  76. model PlayRecord {
  77. id Int @id @default(autoincrement())
  78. userId Int
  79. audioId Int
  80. progress Float @default(0) // 播放进度(秒)
  81. duration Float @default(0) // 总时长
  82. updatedAt DateTime @updatedAt
  83. createdAt DateTime @default(now())
  84. user User @relation(fields: [userId], references: [id])
  85. audio Audio @relation(fields: [audioId], references: [id])
  86. @@unique([userId, audioId])
  87. @@index([userId])
  88. @@index([audioId])
  89. }
  90. model UserPreference {
  91. id Int @id @default(autoincrement())
  92. userId Int @unique
  93. playSpeed Float @default(1.0)
  94. quality String @default("standard") // standard, high
  95. theme String @default("light")
  96. updatedAt DateTime @updatedAt
  97. createdAt DateTime @default(now())
  98. user User @relation(fields: [userId], references: [id])
  99. }
  100. model Favorite {
  101. id Int @id @default(autoincrement())
  102. userId Int
  103. audioId Int
  104. createdAt DateTime @default(now())
  105. user User @relation(fields: [userId], references: [id])
  106. audio Audio @relation(fields: [audioId], references: [id])
  107. @@unique([userId, audioId])
  108. @@index([userId])
  109. }
  110. model Category {
  111. id Int @id @default(autoincrement())
  112. name String
  113. icon String @default("")
  114. sort Int @default(0)
  115. createdAt DateTime @default(now())
  116. audios Audio[] @relation("CategoryAudios")
  117. }
  118. model Comment {
  119. id Int @id @default(autoincrement())
  120. userId Int
  121. audioId Int
  122. content String @db.Text
  123. rating Int // 1-5星
  124. createdAt DateTime @default(now())
  125. user User @relation(fields: [userId], references: [id])
  126. audio Audio @relation(fields: [audioId], references: [id])
  127. @@index([audioId])
  128. @@index([userId])
  129. }
  130. model Notification {
  131. id String @id @default(uuid())
  132. userId String
  133. title String
  134. content String @db.Text
  135. isRead Boolean @default(false)
  136. createdAt DateTime @default(now())
  137. }
  138. model Album {
  139. id Int @id @default(autoincrement())
  140. name String
  141. description String? @db.Text
  142. coverUrl String?
  143. userId Int?
  144. isDefault Boolean @default(false) // 是否是默认专辑
  145. createdAt DateTime @default(now())
  146. updatedAt DateTime @updatedAt
  147. albumAudios AlbumAudio[]
  148. subscriptions AlbumSubscription[]
  149. audios Audio[]
  150. @@index([userId])
  151. @@index([createdAt])
  152. }
  153. model AlbumAudio {
  154. id Int @id @default(autoincrement())
  155. albumId Int
  156. audioId Int
  157. order Int @default(0)
  158. addedAt DateTime @default(now())
  159. album Album @relation(fields: [albumId], references: [id], onDelete: Cascade)
  160. audio Audio @relation(fields: [audioId], references: [id], onDelete: Cascade)
  161. @@unique([albumId, audioId])
  162. @@index([albumId])
  163. @@index([audioId])
  164. }
  165. model AlbumSubscription {
  166. id Int @id @default(autoincrement())
  167. userId Int
  168. albumId Int
  169. createdAt DateTime @default(now())
  170. user User @relation(fields: [userId], references: [id], onDelete: Cascade)
  171. album Album @relation(fields: [albumId], references: [id], onDelete: Cascade)
  172. @@unique([userId, albumId])
  173. @@index([userId])
  174. @@index([albumId])
  175. }
  176. model Template {
  177. id Int @id @default(autoincrement())
  178. name String
  179. category String // 广告营销/知识付费/短视频/企业宣传/日常生活/新闻资讯
  180. content String @db.Text // 模板内容
  181. description String? @db.Text // 模板描述
  182. createdAt DateTime @default(now())
  183. updatedAt DateTime @updatedAt
  184. @@index([category])
  185. }
  186. // 学习路径任务
  187. model LearningPath {
  188. id Int @id @default(autoincrement())
  189. userId Int?
  190. topic String @db.Text // 用户输入的主题
  191. status String @default("pending") // pending, generating, completed, failed
  192. progress Int @default(0) // 0-100 进度百分比
  193. totalCount Int @default(0) // 总内容块数
  194. completedCount Int @default(0) // 已完成内容块数
  195. errorMsg String? @db.Text // 错误信息
  196. // 生成模式: progressive(渐进确认) | multi-agent(多Agent并行)
  197. generationMode String @default("progressive")
  198. // 当前步骤(渐进模式): pending, subjects, chapters, sections, content, completed
  199. currentStep String @default("pending")
  200. // 多Agent模式状态: 存储各Agent的进度JSON
  201. agentStatus String? @db.Text
  202. createdAt DateTime @default(now())
  203. updatedAt DateTime @updatedAt
  204. subjects Subject[]
  205. @@index([userId, status])
  206. }
  207. // 学科(大类)
  208. model Subject {
  209. id Int @id @default(autoincrement())
  210. learningPathId Int
  211. name String // 学科名称,如"计算机原理"
  212. orderIndex Int @default(0) // 排序
  213. status String @default("pending") // pending, generating, completed
  214. aiResponse String? @db.Text // AI返回的原始内容
  215. // 确认状态(渐进模式): pending, confirmed, regenerating
  216. confirmationStatus String @default("pending")
  217. createdAt DateTime @default(now())
  218. updatedAt DateTime @updatedAt
  219. learningPath LearningPath @relation(fields: [learningPathId], references: [id], onDelete: Cascade)
  220. chapters Chapter[]
  221. @@index([learningPathId, orderIndex])
  222. }
  223. // 章节
  224. model Chapter {
  225. id Int @id @default(autoincrement())
  226. subjectId Int
  227. name String // 章节名称
  228. orderIndex Int @default(0)
  229. status String @default("pending")
  230. aiResponse String? @db.Text
  231. // 确认状态(渐进模式): pending, confirmed, regenerating
  232. confirmationStatus String @default("pending")
  233. createdAt DateTime @default(now())
  234. updatedAt DateTime @updatedAt
  235. subject Subject @relation(fields: [subjectId], references: [id], onDelete: Cascade)
  236. sections Section[]
  237. @@index([subjectId, orderIndex])
  238. }
  239. // 小节
  240. model Section {
  241. id Int @id @default(autoincrement())
  242. chapterId Int
  243. name String // 小节名称
  244. orderIndex Int @default(0)
  245. status String @default("pending")
  246. aiResponse String? @db.Text
  247. // 确认状态(渐进模式): pending, confirmed, regenerating
  248. confirmationStatus String @default("pending")
  249. createdAt DateTime @default(now())
  250. updatedAt DateTime @updatedAt
  251. chapter Chapter @relation(fields: [chapterId], references: [id], onDelete: Cascade)
  252. contentBlocks ContentBlock[]
  253. @@index([chapterId, orderIndex])
  254. }
  255. // 内容块(详细内容)
  256. model ContentBlock {
  257. id Int @id @default(autoincrement())
  258. sectionId Int
  259. content String @db.Text // 详细内容
  260. orderIndex Int @default(0)
  261. wordCount Int @default(0)
  262. createdAt DateTime @default(now())
  263. updatedAt DateTime @updatedAt
  264. section Section @relation(fields: [sectionId], references: [id], onDelete: Cascade)
  265. @@index([sectionId, orderIndex])
  266. }