- 支持一对多/多对一关系定义并生成到 Prisma schema - 简化流程:查询关联配置根据关系自动预填 - 修复 Handlebars 模板 HTML 转义导致的乱码问题 - 修复 controller 模板缺少 Prisma 导入的问题 - 新增页面模板 (page.hbs) 生成前端页面 - 添加 FindAllParams/PaginationQueryDto 索引签名修复类型兼容 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
232 lines
6.2 KiB
Plaintext
232 lines
6.2 KiB
Plaintext
generator client {
|
||
provider = "prisma-client-js"
|
||
}
|
||
|
||
datasource db {
|
||
provider = "postgresql"
|
||
url = env("DATABASE_URL")
|
||
}
|
||
|
||
model User {
|
||
id String @id @default(cuid(2))
|
||
email String
|
||
password String
|
||
name String?
|
||
avatarId String? // 头像文件 ID
|
||
isSuperAdmin Boolean @default(false) // 超级管理员标记
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
deletedAt DateTime?
|
||
|
||
roles UserRole[]
|
||
uploadFiles File[] @relation("FileUploader")
|
||
|
||
// 复合唯一约束:未删除用户邮箱唯一,已删除用户邮箱可重复
|
||
@@unique([email, deletedAt])
|
||
@@map("users")
|
||
}
|
||
|
||
// 文件表
|
||
model File {
|
||
id String @id @default(cuid(2))
|
||
filename String // 原始文件名
|
||
objectName String // MinIO 中的对象名
|
||
mimeType String // MIME 类型
|
||
size Int // 文件大小(字节)
|
||
purpose String // 用途: avatar, attachment 等
|
||
uploaderId String // 上传者 ID
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
deletedAt DateTime?
|
||
|
||
uploader User @relation("FileUploader", fields: [uploaderId], references: [id])
|
||
|
||
@@index([uploaderId])
|
||
@@index([purpose])
|
||
@@map("files")
|
||
}
|
||
|
||
// 角色表
|
||
model Role {
|
||
id String @id @default(cuid(2))
|
||
code String @unique // 角色编码: admin, user
|
||
name String // 角色名称
|
||
description String?
|
||
isSystem Boolean @default(false) // 系统内置角色不可删
|
||
isEnabled Boolean @default(true)
|
||
sort Int @default(0)
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
deletedAt DateTime?
|
||
|
||
users UserRole[]
|
||
permissions RolePermission[]
|
||
menus RoleMenu[]
|
||
|
||
@@map("roles")
|
||
}
|
||
|
||
// 权限表
|
||
model Permission {
|
||
id String @id @default(cuid(2))
|
||
code String @unique // 权限编码: user:create
|
||
name String
|
||
description String?
|
||
resource String // 资源: user
|
||
action String // 操作: create
|
||
isEnabled Boolean @default(true)
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
deletedAt DateTime?
|
||
|
||
roles RolePermission[]
|
||
|
||
@@index([resource])
|
||
@@map("permissions")
|
||
}
|
||
|
||
// 菜单表
|
||
model Menu {
|
||
id String @id @default(cuid(2))
|
||
parentId String?
|
||
code String @unique
|
||
name String
|
||
type String @default("menu") // dir / menu / button
|
||
path String?
|
||
icon String? // Lucide 图标名
|
||
isExternal Boolean @default(false)
|
||
isHidden Boolean @default(false)
|
||
isEnabled Boolean @default(true)
|
||
isStatic Boolean @default(false) // 静态/动态菜单
|
||
sort Int @default(0)
|
||
meta Json?
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
deletedAt DateTime?
|
||
|
||
parent Menu? @relation("MenuTree", fields: [parentId], references: [id])
|
||
children Menu[] @relation("MenuTree")
|
||
roles RoleMenu[]
|
||
|
||
@@index([parentId])
|
||
@@map("menus")
|
||
}
|
||
|
||
// 用户-角色关联表
|
||
model UserRole {
|
||
id String @id @default(cuid(2))
|
||
userId String
|
||
roleId String
|
||
createdAt DateTime @default(now())
|
||
|
||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
||
|
||
@@unique([userId, roleId])
|
||
@@map("user_roles")
|
||
}
|
||
|
||
// 角色-权限关联表
|
||
model RolePermission {
|
||
id String @id @default(cuid(2))
|
||
roleId String
|
||
permissionId String
|
||
createdAt DateTime @default(now())
|
||
|
||
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
||
permission Permission @relation(fields: [permissionId], references: [id], onDelete: Cascade)
|
||
|
||
@@unique([roleId, permissionId])
|
||
@@map("role_permissions")
|
||
}
|
||
|
||
// 角色-菜单关联表
|
||
model RoleMenu {
|
||
id String @id @default(cuid(2))
|
||
roleId String
|
||
menuId String
|
||
createdAt DateTime @default(now())
|
||
|
||
role Role @relation(fields: [roleId], references: [id], onDelete: Cascade)
|
||
menu Menu @relation(fields: [menuId], references: [id], onDelete: Cascade)
|
||
|
||
@@unique([roleId, menuId])
|
||
@@map("role_menus")
|
||
}
|
||
|
||
// ============ 教学管理模块 ============
|
||
|
||
// 教师表
|
||
model Teacher {
|
||
id String @id @default(cuid(2))
|
||
teacherNo String @unique // 工号
|
||
name String
|
||
gender String? // male / female
|
||
phone String?
|
||
email String?
|
||
subject String? // 任教科目
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
deletedAt DateTime?
|
||
|
||
// 关系
|
||
headOfClasses Class[] @relation("HeadTeacher") // 作为班主任的班级(一对一的反向)
|
||
teachClasses ClassTeacher[] // 任课班级(多对多)
|
||
|
||
@@map("teachers")
|
||
}
|
||
|
||
// 班级表
|
||
model Class {
|
||
id String @id @default(cuid(2))
|
||
code String @unique // 班级代码
|
||
name String // 班级名称
|
||
grade String? // 年级
|
||
headTeacherId String? // 班主任 ID(一对一)
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
deletedAt DateTime?
|
||
|
||
// 关系
|
||
headTeacher Teacher? @relation("HeadTeacher", fields: [headTeacherId], references: [id])
|
||
students Student[] // 班级学生(一对多)
|
||
teachers ClassTeacher[] // 任课教师(多对多)
|
||
|
||
@@index([headTeacherId])
|
||
@@map("classes")
|
||
}
|
||
|
||
// 学生表
|
||
model Student {
|
||
id String @id @default(cuid(2))
|
||
studentNo String @unique // 学号
|
||
name String
|
||
gender String? // male / female
|
||
phone String?
|
||
email String?
|
||
classId String? // 所属班级(多对一)
|
||
createdAt DateTime @default(now())
|
||
updatedAt DateTime @updatedAt
|
||
deletedAt DateTime?
|
||
|
||
// 关系
|
||
class Class? @relation(fields: [classId], references: [id])
|
||
|
||
@@index([classId])
|
||
@@map("students")
|
||
}
|
||
|
||
// 班级-教师关联表(多对多:任课关系)
|
||
model ClassTeacher {
|
||
id String @id @default(cuid(2))
|
||
classId String
|
||
teacherId String
|
||
createdAt DateTime @default(now())
|
||
|
||
class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
|
||
teacher Teacher @relation(fields: [teacherId], references: [id], onDelete: Cascade)
|
||
|
||
@@unique([classId, teacherId])
|
||
@@map("class_teachers")
|
||
}
|