- 新增预设评语表(PresetComment)及相关API - 新增预设评语管理页面 - 优化评审作品弹框,支持预设评语选择 - 优化赛果发布列表页面 - 更新路由和菜单配置 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1126 lines
62 KiB
Plaintext
1126 lines
62 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 = "mysql"
|
||
url = env("DATABASE_URL")
|
||
}
|
||
|
||
/// 租户表
|
||
model Tenant {
|
||
id Int @id @default(autoincrement())
|
||
name String /// 租户名称
|
||
code String @unique /// 租户编码(唯一,用于访问链接)
|
||
domain String? @unique /// 租户域名(可选,用于子域名访问)
|
||
description String? /// 租户描述
|
||
isSuper Int @default(0) @map("is_super") /// 是否为超级租户:0-否,1-是
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? /// 创建人ID(超级租户的用户ID)
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
users User[]
|
||
roles Role[]
|
||
menus TenantMenu[]
|
||
permissions Permission[]
|
||
dicts Dict[]
|
||
configs Config[]
|
||
school School? /// 学校信息(一对一)
|
||
grades Grade[] /// 年级
|
||
departments Department[] /// 部门
|
||
classes Class[] /// 班级
|
||
teachers Teacher[] /// 教师
|
||
students Student[] /// 学生
|
||
contestTeams ContestTeam[] /// 赛事团队
|
||
contestTeamMembers ContestTeamMember[] /// 团队成员
|
||
contestRegistrations ContestRegistration[] /// 赛事报名
|
||
contestRegistrationTeachers ContestRegistrationTeacher[] /// 报名指导老师关联
|
||
contestWorks ContestWork[] /// 参赛作品
|
||
contestWorkAttachments ContestWorkAttachment[] /// 作品附件
|
||
contestWorkScores ContestWorkScore[] /// 作品评分
|
||
contestReviewRules ContestReviewRule[] /// 评审规则
|
||
// 作业管理关联
|
||
homeworks Homework[] /// 作业
|
||
homeworkSubmissions HomeworkSubmission[] /// 作业提交记录
|
||
homeworkReviewRules HomeworkReviewRule[] /// 作业评审规则
|
||
homeworkScores HomeworkScore[] /// 作业评分
|
||
// AI 3D 生成关联
|
||
ai3dTasks AI3DTask[] /// AI 3D 生成任务
|
||
creatorUser User? @relation("TenantCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("TenantModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@map("tenants")
|
||
}
|
||
|
||
/// 用户表
|
||
model User {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
username String /// 用户名(在租户内唯一)
|
||
password String /// 密码(加密存储)
|
||
nickname String /// 昵称
|
||
email String? /// 邮箱(在租户内唯一,可选)
|
||
phone String? /// 联系方式/手机号
|
||
gender String? /// 性别:male-男,female-女
|
||
avatar String? /// 头像URL
|
||
organization String? /// 所属单位(用于评委等独立用户)
|
||
status String @default("enabled") /// 账号状态:enabled-启用,disabled-停用
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? @map("creator") /// 创建人ID
|
||
modifier Int? @map("modifier") /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
roles UserRole[]
|
||
logs Log[]
|
||
createdBy User? @relation("UserCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifiedBy User? @relation("UserModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
createdUsers User[] @relation("UserCreator")
|
||
modifiedUsers User[] @relation("UserModifier")
|
||
createdRoles Role[] @relation("RoleCreator")
|
||
modifiedRoles Role[] @relation("RoleModifier")
|
||
createdPermissions Permission[] @relation("PermissionCreator")
|
||
modifiedPermissions Permission[] @relation("PermissionModifier")
|
||
createdMenus Menu[] @relation("MenuCreator")
|
||
modifiedMenus Menu[] @relation("MenuModifier")
|
||
createdDicts Dict[] @relation("DictCreator")
|
||
modifiedDicts Dict[] @relation("DictModifier")
|
||
createdDictItems DictItem[] @relation("DictItemCreator")
|
||
modifiedDictItems DictItem[] @relation("DictItemModifier")
|
||
createdConfigs Config[] @relation("ConfigCreator")
|
||
modifiedConfigs Config[] @relation("ConfigModifier")
|
||
createdTenants Tenant[] @relation("TenantCreator")
|
||
modifiedTenants Tenant[] @relation("TenantModifier")
|
||
teacher Teacher? /// 教师信息(一对一)
|
||
student Student? /// 学生信息(一对一)
|
||
createdSchools School[] @relation("SchoolCreator")
|
||
modifiedSchools School[] @relation("SchoolModifier")
|
||
createdGrades Grade[] @relation("GradeCreator")
|
||
modifiedGrades Grade[] @relation("GradeModifier")
|
||
createdDepartments Department[] @relation("DepartmentCreator")
|
||
modifiedDepartments Department[] @relation("DepartmentModifier")
|
||
createdClasses Class[] @relation("ClassCreator")
|
||
modifiedClasses Class[] @relation("ClassModifier")
|
||
createdTeachers Teacher[] @relation("TeacherCreator")
|
||
modifiedTeachers Teacher[] @relation("TeacherModifier")
|
||
createdStudents Student[] @relation("StudentCreator")
|
||
modifiedStudents Student[] @relation("StudentModifier")
|
||
// 赛事相关关联
|
||
createdContests Contest[] @relation("ContestCreator")
|
||
modifiedContests Contest[] @relation("ContestModifier")
|
||
createdContestAttachments ContestAttachment[] @relation("ContestAttachmentCreator")
|
||
modifiedContestAttachments ContestAttachment[] @relation("ContestAttachmentModifier")
|
||
createdContestReviewRules ContestReviewRule[] @relation("ContestReviewRuleCreator")
|
||
modifiedContestReviewRules ContestReviewRule[] @relation("ContestReviewRuleModifier")
|
||
createdContestTeams ContestTeam[] @relation("ContestTeamCreator")
|
||
modifiedContestTeams ContestTeam[] @relation("ContestTeamModifier")
|
||
ledContestTeams ContestTeam[] @relation("ContestTeamLeader")
|
||
createdContestTeamMembers ContestTeamMember[] @relation("ContestTeamMemberCreator")
|
||
modifiedContestTeamMembers ContestTeamMember[] @relation("ContestTeamMemberModifier")
|
||
contestTeamMembers ContestTeamMember[] @relation("ContestTeamMemberUser")
|
||
createdContestRegistrations ContestRegistration[] @relation("ContestRegistrationCreator")
|
||
modifiedContestRegistrations ContestRegistration[] @relation("ContestRegistrationModifier")
|
||
contestRegistrations ContestRegistration[] @relation("ContestRegistrationUser")
|
||
createdContestWorks ContestWork[] @relation("ContestWorkCreator")
|
||
modifiedContestWorks ContestWork[] @relation("ContestWorkModifier")
|
||
createdContestWorkAttachments ContestWorkAttachment[] @relation("ContestWorkAttachmentCreator")
|
||
modifiedContestWorkAttachments ContestWorkAttachment[] @relation("ContestWorkAttachmentModifier")
|
||
createdContestWorkJudgeAssignments ContestWorkJudgeAssignment[] @relation("ContestWorkJudgeAssignmentCreator")
|
||
modifiedContestWorkJudgeAssignments ContestWorkJudgeAssignment[] @relation("ContestWorkJudgeAssignmentModifier")
|
||
assignedContestWorks ContestWorkJudgeAssignment[] @relation("ContestWorkJudgeAssignmentJudge")
|
||
createdContestWorkScores ContestWorkScore[] @relation("ContestWorkScoreCreator")
|
||
modifiedContestWorkScores ContestWorkScore[] @relation("ContestWorkScoreModifier")
|
||
scoredContestWorks ContestWorkScore[] @relation("ContestWorkScoreJudge")
|
||
createdContestNotices ContestNotice[] @relation("ContestNoticeCreator")
|
||
modifiedContestNotices ContestNotice[] @relation("ContestNoticeModifier")
|
||
contestJudges ContestJudge[] @relation("ContestJudgeUser")
|
||
createdContestJudges ContestJudge[] @relation("ContestJudgeCreator")
|
||
modifiedContestJudges ContestJudge[] @relation("ContestJudgeModifier")
|
||
contestRegistrationTeachers ContestRegistrationTeacher[] @relation("ContestRegistrationTeacherUser")
|
||
createdContestRegistrationTeachers ContestRegistrationTeacher[] @relation("ContestRegistrationTeacherCreator")
|
||
modifiedContestRegistrationTeachers ContestRegistrationTeacher[] @relation("ContestRegistrationTeacherModifier")
|
||
// 作业管理关联
|
||
createdHomeworks Homework[] @relation("HomeworkCreator")
|
||
modifiedHomeworks Homework[] @relation("HomeworkModifier")
|
||
homeworkSubmissions HomeworkSubmission[] @relation("HomeworkSubmissionStudent")
|
||
createdHomeworkSubmissions HomeworkSubmission[] @relation("HomeworkSubmissionCreator")
|
||
modifiedHomeworkSubmissions HomeworkSubmission[] @relation("HomeworkSubmissionModifier")
|
||
createdHomeworkReviewRules HomeworkReviewRule[] @relation("HomeworkReviewRuleCreator")
|
||
modifiedHomeworkReviewRules HomeworkReviewRule[] @relation("HomeworkReviewRuleModifier")
|
||
homeworkScoresAsReviewer HomeworkScore[] @relation("HomeworkScoreReviewer")
|
||
createdHomeworkScores HomeworkScore[] @relation("HomeworkScoreCreator")
|
||
modifiedHomeworkScores HomeworkScore[] @relation("HomeworkScoreModifier")
|
||
// AI 3D 生成关联
|
||
ai3dTasks AI3DTask[] @relation("AI3DTaskUser") /// 用户的 AI 3D 生成任务
|
||
// 预设评语关联
|
||
presetComments PresetComment[] @relation("PresetCommentJudge") /// 评委的预设评语
|
||
|
||
@@unique([tenantId, username])
|
||
@@unique([tenantId, email])
|
||
@@map("users")
|
||
}
|
||
|
||
/// 角色表
|
||
model Role {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
name String /// 角色名称(在租户内唯一)
|
||
code String /// 角色编码(在租户内唯一)
|
||
description String? /// 角色描述
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
users UserRole[]
|
||
permissions RolePermission[]
|
||
creatorUser User? @relation("RoleCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("RoleModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, name])
|
||
@@unique([tenantId, code])
|
||
@@map("roles")
|
||
}
|
||
|
||
/// 用户角色关联表
|
||
model UserRole {
|
||
id Int @id @default(autoincrement())
|
||
userId Int @map("user_id") /// 用户ID
|
||
roleId Int @map("role_id") /// 角色ID
|
||
|
||
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 Permission {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
name String /// 权限名称
|
||
code String /// 权限编码(在租户内唯一)
|
||
resource String /// 资源名称,如 user, role, menu
|
||
action String /// 操作类型,如 create, read, update, delete
|
||
description String? /// 权限描述
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
roles RolePermission[]
|
||
creatorUser User? @relation("PermissionCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("PermissionModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, resource, action])
|
||
@@unique([tenantId, code])
|
||
@@map("permissions")
|
||
}
|
||
|
||
/// 角色权限关联表
|
||
model RolePermission {
|
||
id Int @id @default(autoincrement())
|
||
roleId Int @map("role_id") /// 角色ID
|
||
permissionId Int @map("permission_id") /// 权限ID
|
||
|
||
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 Menu {
|
||
id Int @id @default(autoincrement())
|
||
name String /// 菜单名称
|
||
path String? /// 路由路径
|
||
icon String? /// 图标
|
||
component String? /// 组件路径
|
||
parentId Int? @map("parent_id") /// 父菜单ID
|
||
permission String? /// 权限编码(用于控制菜单显示,如:menu:read)
|
||
sort Int @default(0) /// 排序
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? @map("creator") /// 创建人ID
|
||
modifier Int? @map("modifier") /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
parent Menu? @relation("MenuTree", fields: [parentId], references: [id])
|
||
children Menu[] @relation("MenuTree")
|
||
tenantMenus TenantMenu[] /// 租户菜单关联
|
||
creatorUser User? @relation("MenuCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("MenuModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@map("menus")
|
||
}
|
||
|
||
/// 租户菜单关联表(租户分配的菜单)
|
||
model TenantMenu {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
menuId Int @map("menu_id") /// 菜单ID
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
menu Menu @relation(fields: [menuId], references: [id], onDelete: Cascade)
|
||
|
||
@@unique([tenantId, menuId])
|
||
@@map("tenant_menus")
|
||
}
|
||
|
||
/// 数据字典表
|
||
model Dict {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
name String /// 字典名称
|
||
code String /// 字典编码(在租户内唯一)
|
||
description String? /// 字典描述
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
items DictItem[]
|
||
creatorUser User? @relation("DictCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("DictModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, code])
|
||
@@map("dicts")
|
||
}
|
||
|
||
/// 字典项表
|
||
model DictItem {
|
||
id Int @id @default(autoincrement())
|
||
dictId Int @map("dict_id") /// 字典ID
|
||
label String /// 标签
|
||
value String /// 值
|
||
sort Int @default(0) /// 排序
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? @map("creator") /// 创建人ID
|
||
modifier Int? @map("modifier") /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
dict Dict @relation(fields: [dictId], references: [id], onDelete: Cascade)
|
||
creatorUser User? @relation("DictItemCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("DictItemModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@map("dict_items")
|
||
}
|
||
|
||
/// 系统配置表
|
||
model Config {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
key String /// 配置键(在租户内唯一)
|
||
value String /// 配置值
|
||
description String? /// 配置描述
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
creatorUser User? @relation("ConfigCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ConfigModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, key])
|
||
@@map("configs")
|
||
}
|
||
|
||
/// 日志记录表
|
||
model Log {
|
||
id Int @id @default(autoincrement())
|
||
userId Int? @map("user_id") /// 用户ID
|
||
action String /// 操作类型
|
||
content String? @db.Text /// 操作内容(使用 TEXT 类型支持长文本)
|
||
ip String? /// IP地址
|
||
userAgent String? @map("user_agent") /// 用户代理
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
|
||
user User? @relation(fields: [userId], references: [id], onDelete: SetNull)
|
||
|
||
@@map("logs")
|
||
}
|
||
|
||
/// 学校信息表(扩展租户信息)
|
||
model School {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @unique @map("tenant_id") /// 租户ID(一对一)
|
||
address String? /// 学校地址
|
||
phone String? /// 联系电话
|
||
principal String? /// 校长姓名
|
||
established DateTime? /// 建校时间
|
||
description String? @db.Text /// 学校描述
|
||
logo String? /// 学校Logo URL
|
||
website String? /// 学校网站
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
creatorUser User? @relation("SchoolCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("SchoolModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@map("schools")
|
||
}
|
||
|
||
/// 年级表
|
||
model Grade {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
name String /// 年级名称(如:一年级、二年级)
|
||
code String /// 年级编码(在租户内唯一,如:grade_1, grade_2)
|
||
level Int /// 年级级别(用于排序,如:1, 2, 3)
|
||
description String? /// 年级描述
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
classes Class[] /// 班级
|
||
creatorUser User? @relation("GradeCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("GradeModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, code])
|
||
@@unique([tenantId, level])
|
||
@@map("grades")
|
||
}
|
||
|
||
/// 部门表(支持树形结构)
|
||
model Department {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
name String /// 部门名称
|
||
code String /// 部门编码(在租户内唯一)
|
||
parentId Int? @map("parent_id") /// 父部门ID(支持树形结构)
|
||
description String? /// 部门描述
|
||
sort Int @default(0) /// 排序
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
parent Department? @relation("DepartmentTree", fields: [parentId], references: [id])
|
||
children Department[] @relation("DepartmentTree")
|
||
teachers Teacher[] /// 教师
|
||
creatorUser User? @relation("DepartmentCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("DepartmentModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, code])
|
||
@@map("departments")
|
||
}
|
||
|
||
/// 班级表
|
||
model Class {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
gradeId Int @map("grade_id") /// 年级ID
|
||
name String /// 班级名称(如:一年级1班、二年级2班)
|
||
code String /// 班级编码(在租户内唯一)
|
||
type Int @default(1) @map("type") /// 班级类型:1-行政班级(教学班级),2-兴趣班
|
||
capacity Int? /// 班级容量(可选)
|
||
description String? /// 班级描述
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
grade Grade @relation(fields: [gradeId], references: [id], onDelete: Cascade)
|
||
students Student[] /// 学生(行政班级)
|
||
studentInterestClasses StudentInterestClass[] /// 学生兴趣班关联
|
||
creatorUser User? @relation("ClassCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ClassModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, code])
|
||
@@map("classes")
|
||
}
|
||
|
||
/// 教师表
|
||
model Teacher {
|
||
id Int @id @default(autoincrement())
|
||
userId Int @unique @map("user_id") /// 用户ID(一对一)
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
departmentId Int @map("department_id") /// 部门ID
|
||
employeeNo String? @map("employee_no") /// 工号(在租户内唯一)
|
||
phone String? /// 联系电话
|
||
idCard String? @map("id_card") /// 身份证号
|
||
gender Int? /// 性别:1-男,2-女
|
||
birthDate DateTime? @map("birth_date") /// 出生日期
|
||
hireDate DateTime? @map("hire_date") /// 入职日期
|
||
subject String? /// 任教科目(可选,如:语文、数学)
|
||
title String? /// 职称(可选,如:高级教师、一级教师)
|
||
description String? @db.Text /// 教师描述
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
department Department @relation(fields: [departmentId], references: [id], onDelete: Restrict)
|
||
creatorUser User? @relation("TeacherCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("TeacherModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, employeeNo])
|
||
@@map("teachers")
|
||
}
|
||
|
||
/// 学生表
|
||
model Student {
|
||
id Int @id @default(autoincrement())
|
||
userId Int @unique @map("user_id") /// 用户ID(一对一)
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
classId Int @map("class_id") /// 行政班级ID
|
||
studentNo String? @map("student_no") /// 学号(在租户内唯一)
|
||
phone String? /// 联系电话
|
||
idCard String? @map("id_card") /// 身份证号
|
||
gender Int? /// 性别:1-男,2-女
|
||
birthDate DateTime? @map("birth_date") /// 出生日期
|
||
enrollmentDate DateTime? @map("enrollment_date") /// 入学日期
|
||
parentName String? @map("parent_name") /// 家长姓名
|
||
parentPhone String? @map("parent_phone") /// 家长电话
|
||
address String? /// 家庭地址
|
||
description String? @db.Text /// 学生描述
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
class Class @relation(fields: [classId], references: [id], onDelete: Restrict)
|
||
interestClasses StudentInterestClass[] /// 兴趣班关联
|
||
creatorUser User? @relation("StudentCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("StudentModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, studentNo])
|
||
@@map("students")
|
||
}
|
||
|
||
/// 学生兴趣班关联表(多对多)
|
||
model StudentInterestClass {
|
||
id Int @id @default(autoincrement())
|
||
studentId Int @map("student_id") /// 学生ID
|
||
classId Int @map("class_id") /// 兴趣班ID
|
||
|
||
student Student @relation(fields: [studentId], references: [id], onDelete: Cascade)
|
||
class Class @relation(fields: [classId], references: [id], onDelete: Cascade)
|
||
|
||
@@unique([studentId, classId])
|
||
@@map("student_interest_classes")
|
||
}
|
||
|
||
// ============================================
|
||
// 赛事管理模块
|
||
// ============================================
|
||
|
||
/// 赛事表
|
||
model Contest {
|
||
id Int @id @default(autoincrement())
|
||
contestName String @map("contest_name") /// 赛事名称
|
||
contestType String @map("contest_type") /// 赛事类型:individual/team
|
||
contestState String @default("unpublished") @map("contest_state") /// 赛事状态:unpublished/published
|
||
status String @default("ongoing") /// 赛事进度状态:ongoing/finished
|
||
startTime DateTime @map("start_time") /// 赛事开始时间
|
||
endTime DateTime @map("end_time") /// 赛事结束时间
|
||
address String? /// 线下地址
|
||
content String? @db.Text /// 赛事详情
|
||
contestTenants Json? @map("contest_tenants") /// 授权租户ID数组
|
||
coverUrl String? @map("cover_url") /// 封面url
|
||
posterUrl String? @map("poster_url") /// 海报url
|
||
contactName String? @map("contact_name") /// 联系人
|
||
contactPhone String? @map("contact_phone") /// 联系电话
|
||
contactQrcode String? @map("contact_qrcode") /// 联系人二维码
|
||
organizers Json? /// 主办单位数组
|
||
coOrganizers Json? @map("co_organizers") /// 协办单位数组
|
||
sponsors Json? /// 赞助单位数组
|
||
// 报名配置
|
||
registerStartTime DateTime @map("register_start_time") /// 报名开始时间
|
||
registerEndTime DateTime @map("register_end_time") /// 报名结束时间
|
||
registerState String? @map("register_state") /// 报名任务状态:started/closed
|
||
requireAudit Boolean @default(true) @map("require_audit") /// 报名是否需要审核
|
||
allowedGrades Json? @map("allowed_grades") /// 允许报名的年级ID数组
|
||
allowedClasses Json? @map("allowed_classes") /// 允许报名的班级ID数组
|
||
teamMinMembers Int? @map("team_min_members") /// 团队最少成员数
|
||
teamMaxMembers Int? @map("team_max_members") /// 团队最多成员数
|
||
// 作品配置
|
||
submitRule String @default("once") @map("submit_rule") /// 提交规则:once/resubmit
|
||
submitStartTime DateTime @map("submit_start_time") /// 作品提交开始时间
|
||
submitEndTime DateTime @map("submit_end_time") /// 作品提交结束时间
|
||
workType String? @map("work_type") /// 作品类型(如:image/video/document/code)
|
||
workRequirement String? @map("work_requirement") @db.Text /// 作品要求说明
|
||
// 评审配置
|
||
reviewRuleId Int? @map("review_rule_id") /// 评审规则id
|
||
reviewStartTime DateTime @map("review_start_time") /// 评审开始时间
|
||
reviewEndTime DateTime @map("review_end_time") /// 评审结束时间
|
||
// 赛果配置
|
||
resultState String @default("unpublished") @map("result_state") /// 赛果状态:unpublished/published
|
||
resultPublishTime DateTime? @map("result_publish_time") /// 结果发布时间
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
attachments ContestAttachment[] /// 赛事附件
|
||
reviewRule ContestReviewRule? @relation("ContestReviewRuleContest", fields: [reviewRuleId], references: [id], onDelete: SetNull)
|
||
teams ContestTeam[] /// 赛事团队
|
||
registrations ContestRegistration[] /// 报名记录
|
||
works ContestWork[] /// 参赛作品
|
||
judges ContestJudge[] /// 比赛评委
|
||
workAssignments ContestWorkJudgeAssignment[] @relation("ContestWorkJudgeAssignmentContest") /// 作品分配
|
||
workScores ContestWorkScore[] @relation("ContestWorkScoreContest") /// 作品评分
|
||
notices ContestNotice[] /// 赛事公告
|
||
presetComments PresetComment[] /// 预设评语
|
||
creatorUser User? @relation("ContestCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([contestName])
|
||
@@index([contestState])
|
||
@@index([startTime, endTime])
|
||
@@index([reviewRuleId])
|
||
@@map("t_contest")
|
||
}
|
||
|
||
/// 赛事附件表
|
||
model ContestAttachment {
|
||
id Int @id @default(autoincrement())
|
||
contestId Int @map("contest_id") /// 赛事id
|
||
fileName String @map("file_name") /// 文件名
|
||
fileUrl String @map("file_url") /// 文件路径
|
||
format String? /// 文件类型(png,mp4)
|
||
fileType String? @map("file_type") /// 素材类型(image,video)
|
||
size String @default("0") /// 文件大小
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
contest Contest @relation(fields: [contestId], references: [id], onDelete: Cascade)
|
||
creatorUser User? @relation("ContestAttachmentCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestAttachmentModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@index([contestId])
|
||
@@map("t_contest_attachment")
|
||
}
|
||
|
||
/// 评审规则表(独立存在,可被多个赛事使用)
|
||
model ContestReviewRule {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
ruleName String @map("rule_name") /// 规则名称
|
||
ruleDescription String? @map("rule_description") @db.Text /// 规则说明
|
||
judgeCount Int? @map("judge_count") /// 评委数量
|
||
dimensions Json /// 评分维度配置JSON
|
||
calculationRule String @default("average") @map("calculation_rule") /// 计算规则:average/remove_max_min/remove_min
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
contests Contest[] @relation("ContestReviewRuleContest") /// 使用此规则的赛事列表
|
||
creatorUser User? @relation("ContestReviewRuleCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestReviewRuleModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@index([tenantId])
|
||
@@map("t_contest_review_rule")
|
||
}
|
||
|
||
/// 赛事团队表
|
||
model ContestTeam {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 团队所属租户ID
|
||
contestId Int @map("contest_id") /// 赛事id
|
||
teamName String @map("team_name") /// 团队名称(租户内唯一)
|
||
leaderUserId Int @map("leader_user_id") /// 团队负责人用户id
|
||
maxMembers Int? @map("max_members") /// 团队最大成员数
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
contest Contest @relation(fields: [contestId], references: [id], onDelete: Cascade)
|
||
leader User @relation("ContestTeamLeader", fields: [leaderUserId], references: [id], onDelete: Restrict)
|
||
members ContestTeamMember[] /// 团队成员
|
||
registrations ContestRegistration[] /// 报名记录
|
||
creatorUser User? @relation("ContestTeamCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestTeamModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, contestId, teamName])
|
||
@@index([contestId])
|
||
@@index([leaderUserId])
|
||
@@map("t_contest_team")
|
||
}
|
||
|
||
/// 团队成员表
|
||
model ContestTeamMember {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 成员所属租户ID
|
||
teamId Int @map("team_id") /// 团队id
|
||
userId Int @map("user_id") /// 成员用户id
|
||
role String @default("member") /// 成员角色:member/leader/mentor
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
team ContestTeam @relation(fields: [teamId], references: [id], onDelete: Cascade)
|
||
user User @relation("ContestTeamMemberUser", fields: [userId], references: [id], onDelete: Cascade)
|
||
creatorUser User? @relation("ContestTeamMemberCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestTeamMemberModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, teamId, userId])
|
||
@@index([teamId])
|
||
@@index([userId])
|
||
@@map("t_contest_team_member")
|
||
}
|
||
|
||
/// 赛事报名表
|
||
model ContestRegistration {
|
||
id Int @id @default(autoincrement())
|
||
contestId Int @map("contest_id") /// 赛事id
|
||
tenantId Int @map("tenant_id") /// 所属租户ID
|
||
registrationType String? @map("registration_type") /// 报名类型:individual/team
|
||
teamId Int? @map("team_id") /// 团队id
|
||
teamName String? @map("team_name") /// 团队名称快照(团队赛)
|
||
userId Int @map("user_id") /// 账号id
|
||
accountNo String @map("account_no") /// 报名账号(记录报名快照)
|
||
accountName String @map("account_name") /// 报名账号名称(记录报名快照)
|
||
role String? /// 报名角色快照:leader/member/mentor
|
||
registrationState String @default("pending") @map("registration_state") /// 报名状态:pending/passed/rejected/withdrawn
|
||
registrant Int? /// 实际报名人用户ID
|
||
registrationTime DateTime @map("registration_time") /// 报名时间
|
||
reason String? @db.VarChar(1023) /// 审核理由
|
||
operator Int? /// 审核人用户ID
|
||
operationDate DateTime? @map("operation_date") /// 审核时间
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
|
||
contest Contest @relation(fields: [contestId], references: [id], onDelete: Cascade)
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
team ContestTeam? @relation(fields: [teamId], references: [id], onDelete: SetNull)
|
||
user User @relation("ContestRegistrationUser", fields: [userId], references: [id], onDelete: Restrict)
|
||
works ContestWork[] /// 参赛作品
|
||
creatorUser User? @relation("ContestRegistrationCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestRegistrationModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
teachers ContestRegistrationTeacher[] /// 指导老师关联
|
||
|
||
@@index([contestId, tenantId])
|
||
@@index([userId, contestId])
|
||
@@index([teamId])
|
||
@@index([registrationState])
|
||
@@map("t_contest_registration")
|
||
}
|
||
|
||
/// 报名指导老师关联表
|
||
model ContestRegistrationTeacher {
|
||
id Int @id @default(autoincrement())
|
||
registrationId Int @map("registration_id") /// 报名记录ID
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
userId Int @map("user_id") /// 指导老师用户ID
|
||
isDefault Boolean @default(false) @map("is_default") /// 是否为默认指导老师(报名时自动添加的,不能移除)
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
|
||
registration ContestRegistration @relation(fields: [registrationId], references: [id], onDelete: Cascade)
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
user User @relation("ContestRegistrationTeacherUser", fields: [userId], references: [id], onDelete: Cascade)
|
||
creatorUser User? @relation("ContestRegistrationTeacherCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestRegistrationTeacherModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([tenantId, registrationId, userId])
|
||
@@index([registrationId])
|
||
@@index([userId])
|
||
@@map("t_contest_registration_teacher")
|
||
}
|
||
|
||
/// 参赛作品表
|
||
model ContestWork {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 作品所属租户ID
|
||
contestId Int @map("contest_id") /// 赛事id
|
||
registrationId Int @map("registration_id") /// 报名记录id
|
||
workNo String? @unique @map("work_no") /// 作品编号(展示用唯一编号)
|
||
title String /// 作品标题
|
||
description String? @db.Text /// 作品说明
|
||
files Json? /// 作品文件列表(简易场景)
|
||
version Int @default(1) /// 作品版本号(递增)
|
||
isLatest Boolean @default(true) @map("is_latest") /// 是否最新版本
|
||
status String @default("submitted") /// 作品状态:submitted/locked/reviewing/rejected/accepted
|
||
submitTime DateTime @default(now()) @map("submit_time") /// 提交时间
|
||
submitterUserId Int? @map("submitter_user_id") /// 提交人用户id
|
||
submitterAccountNo String? @map("submitter_account_no") /// 提交人账号
|
||
submitSource String @default("teacher") @map("submit_source") /// 提交来源:teacher/student/team_leader
|
||
previewUrl String? @map("preview_url") @db.Text /// 作品预览URL(兼容单预览图)
|
||
previewUrls Json? @map("preview_urls") /// 作品预览图URL列表(多模型场景)
|
||
aiModelMeta Json? @map("ai_model_meta") /// AI建模元数据
|
||
// 赛果相关字段
|
||
finalScore Decimal? @map("final_score") @db.Decimal(10, 2) /// 最终得分(根据规则计算)
|
||
rank Int? /// 排名
|
||
awardLevel String? @map("award_level") /// 奖项等级:first/second/third/excellent/none
|
||
awardName String? @map("award_name") /// 奖项名称(如:一等奖、金奖)
|
||
certificateUrl String? @map("certificate_url") /// 证书URL
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
contest Contest @relation(fields: [contestId], references: [id], onDelete: Cascade)
|
||
registration ContestRegistration @relation(fields: [registrationId], references: [id], onDelete: Restrict)
|
||
attachments ContestWorkAttachment[] /// 作品附件
|
||
assignments ContestWorkJudgeAssignment[] /// 作品分配
|
||
scores ContestWorkScore[] /// 作品评分
|
||
creatorUser User? @relation("ContestWorkCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestWorkModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@index([tenantId, contestId, isLatest])
|
||
@@index([registrationId])
|
||
@@index([tenantId, contestId, submitTime, status])
|
||
@@index([contestId, status])
|
||
@@map("t_contest_work")
|
||
}
|
||
|
||
/// 作品附件文件表
|
||
model ContestWorkAttachment {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 所属租户ID
|
||
contestId Int @map("contest_id") /// 赛事id
|
||
workId Int @map("work_id") /// 作品id
|
||
fileName String @map("file_name") /// 文件名
|
||
fileUrl String @map("file_url") /// 文件路径
|
||
format String? /// 文件类型(png,mp4)
|
||
fileType String? @map("file_type") /// 素材类型(image,video)
|
||
size String @default("0") /// 文件大小
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
|
||
work ContestWork @relation(fields: [workId], references: [id], onDelete: Cascade)
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
creatorUser User? @relation("ContestWorkAttachmentCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestWorkAttachmentModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@index([tenantId, contestId, workId])
|
||
@@map("t_contest_work_attachment")
|
||
}
|
||
|
||
/// 比赛评委关联表(比赛与评委的多对多关系)
|
||
model ContestJudge {
|
||
id Int @id @default(autoincrement())
|
||
contestId Int @map("contest_id") /// 比赛id
|
||
judgeId Int @map("judge_id") /// 评委用户id
|
||
specialty String? /// 评审专业领域(可选)
|
||
weight Decimal? @db.Decimal(3, 2) /// 评审权重(可选,用于加权平均计算)
|
||
description String? @db.Text /// 评委在该比赛中的说明
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
contest Contest @relation(fields: [contestId], references: [id], onDelete: Cascade)
|
||
judge User @relation("ContestJudgeUser", fields: [judgeId], references: [id], onDelete: Cascade)
|
||
creatorUser User? @relation("ContestJudgeCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestJudgeModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([contestId, judgeId])
|
||
@@index([contestId])
|
||
@@index([judgeId])
|
||
@@map("t_contest_judge")
|
||
}
|
||
|
||
/// 作品分配表(评委分配作品)
|
||
model ContestWorkJudgeAssignment {
|
||
id Int @id @default(autoincrement())
|
||
contestId Int @map("contest_id") /// 赛事id
|
||
workId Int @map("work_id") /// 作品id
|
||
judgeId Int @map("judge_id") /// 评委用户id
|
||
assignmentTime DateTime @default(now()) @map("assignment_time") /// 分配时间
|
||
status String @default("assigned") /// 分配状态:assigned/reviewing/completed
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
|
||
contest Contest @relation("ContestWorkJudgeAssignmentContest", fields: [contestId], references: [id], onDelete: Cascade)
|
||
work ContestWork @relation(fields: [workId], references: [id], onDelete: Cascade)
|
||
judge User @relation("ContestWorkJudgeAssignmentJudge", fields: [judgeId], references: [id], onDelete: Restrict)
|
||
scores ContestWorkScore[] /// 评分记录
|
||
creatorUser User? @relation("ContestWorkJudgeAssignmentCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestWorkJudgeAssignmentModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([workId, judgeId])
|
||
@@index([contestId, judgeId])
|
||
@@index([workId])
|
||
@@index([status])
|
||
@@map("t_contest_work_judge_assignment")
|
||
}
|
||
|
||
/// 作品评分表
|
||
model ContestWorkScore {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 所属租户ID
|
||
contestId Int @map("contest_id") /// 赛事id
|
||
workId Int @map("work_id") /// 作品id
|
||
assignmentId Int @map("assignment_id") /// 分配记录id
|
||
judgeId Int @map("judge_id") /// 评委用户id
|
||
judgeName String @map("judge_name") /// 评委姓名
|
||
dimensionScores Json @map("dimension_scores") /// 各维度评分JSON
|
||
totalScore Decimal @map("total_score") @db.Decimal(10, 2) /// 总分
|
||
comments String? @db.Text /// 评语
|
||
scoreTime DateTime @map("score_time") /// 评分时间
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
contest Contest @relation("ContestWorkScoreContest", fields: [contestId], references: [id], onDelete: Cascade)
|
||
work ContestWork @relation(fields: [workId], references: [id], onDelete: Cascade)
|
||
assignment ContestWorkJudgeAssignment @relation(fields: [assignmentId], references: [id], onDelete: Restrict)
|
||
judge User @relation("ContestWorkScoreJudge", fields: [judgeId], references: [id], onDelete: Restrict)
|
||
creatorUser User? @relation("ContestWorkScoreCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestWorkScoreModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@index([contestId, workId, judgeId])
|
||
@@index([workId])
|
||
@@index([assignmentId])
|
||
@@map("t_contest_work_score")
|
||
}
|
||
|
||
/// 赛事公告表
|
||
model ContestNotice {
|
||
id Int @id @default(autoincrement())
|
||
contestId Int @map("contest_id") /// 赛事id
|
||
title String /// 公告标题
|
||
content String @db.Text /// 公告内容
|
||
noticeType String @default("manual") @map("notice_type") /// 公告类型:system/manual/urgent
|
||
priority Int @default(0) /// 优先级(数字越大优先级越高)
|
||
publishTime DateTime? @map("publish_time") /// 发布时间
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
contest Contest @relation(fields: [contestId], references: [id], onDelete: Cascade)
|
||
creatorUser User? @relation("ContestNoticeCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("ContestNoticeModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@index([contestId])
|
||
@@index([publishTime])
|
||
@@index([noticeType])
|
||
@@map("t_contest_notice")
|
||
}
|
||
|
||
// ============================================
|
||
// 作业管理模块
|
||
// ============================================
|
||
|
||
/// 作业表
|
||
model Homework {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
name String /// 作业名称
|
||
content String? @db.Text /// 作业内容(富文本)
|
||
status String @default("unpublished") /// 作业状态:unpublished/published
|
||
publishTime DateTime? @map("publish_time") /// 发布时间
|
||
submitStartTime DateTime @map("submit_start_time") /// 提交开始时间
|
||
submitEndTime DateTime @map("submit_end_time") /// 提交结束时间
|
||
attachments Json? /// 附件列表 [{fileName, fileUrl, size}]
|
||
publishScope Json? @map("publish_scope") /// 公开范围(班级ID数组)
|
||
reviewRuleId Int? @map("review_rule_id") /// 评审规则ID
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
reviewRule HomeworkReviewRule? @relation(fields: [reviewRuleId], references: [id], onDelete: SetNull)
|
||
submissions HomeworkSubmission[] /// 作业提交记录
|
||
creatorUser User? @relation("HomeworkCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("HomeworkModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@index([tenantId, status])
|
||
@@index([tenantId, submitStartTime, submitEndTime])
|
||
@@map("t_homework")
|
||
}
|
||
|
||
/// 作业提交表
|
||
model HomeworkSubmission {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
homeworkId Int @map("homework_id") /// 作业ID
|
||
studentId Int @map("student_id") /// 学生用户ID
|
||
workNo String? @map("work_no") /// 作品编号
|
||
workName String @map("work_name") /// 作品名称
|
||
workDescription String? @map("work_description") @db.Text /// 作品介绍
|
||
files Json? /// 作品文件列表
|
||
attachments Json? /// 附件列表
|
||
submitTime DateTime @default(now()) @map("submit_time") /// 提交时间
|
||
status String @default("pending") /// 状态:pending/reviewed/rejected
|
||
totalScore Decimal? @map("total_score") @db.Decimal(10, 2) /// 总分
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
homework Homework @relation(fields: [homeworkId], references: [id], onDelete: Cascade)
|
||
student User @relation("HomeworkSubmissionStudent", fields: [studentId], references: [id], onDelete: Cascade)
|
||
scores HomeworkScore[] /// 评分记录
|
||
creatorUser User? @relation("HomeworkSubmissionCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("HomeworkSubmissionModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([homeworkId, studentId])
|
||
@@index([tenantId, homeworkId])
|
||
@@index([studentId])
|
||
@@index([status])
|
||
@@map("t_homework_submission")
|
||
}
|
||
|
||
/// 作业评审规则表
|
||
model HomeworkReviewRule {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
name String /// 规则名称
|
||
description String? @db.Text /// 规则描述
|
||
criteria Json /// 评分标准 [{name, maxScore, description}]
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
homeworks Homework[] /// 关联的作业
|
||
creatorUser User? @relation("HomeworkReviewRuleCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("HomeworkReviewRuleModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@index([tenantId])
|
||
@@map("t_homework_review_rule")
|
||
}
|
||
|
||
/// 作业评分表
|
||
model HomeworkScore {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
submissionId Int @map("submission_id") /// 提交记录ID
|
||
reviewerId Int @map("reviewer_id") /// 评审人ID
|
||
dimensionScores Json @map("dimension_scores") /// 各维度评分
|
||
totalScore Decimal @map("total_score") @db.Decimal(10, 2) /// 总分
|
||
comments String? @db.Text /// 评语
|
||
scoreTime DateTime @default(now()) @map("score_time") /// 评分时间
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
submission HomeworkSubmission @relation(fields: [submissionId], references: [id], onDelete: Cascade)
|
||
reviewer User @relation("HomeworkScoreReviewer", fields: [reviewerId], references: [id], onDelete: Restrict)
|
||
creatorUser User? @relation("HomeworkScoreCreator", fields: [creator], references: [id], onDelete: SetNull)
|
||
modifierUser User? @relation("HomeworkScoreModifier", fields: [modifier], references: [id], onDelete: SetNull)
|
||
|
||
@@unique([submissionId, reviewerId])
|
||
@@index([tenantId, submissionId])
|
||
@@index([reviewerId])
|
||
@@map("t_homework_score")
|
||
}
|
||
|
||
// ============================================
|
||
// AI 3D 模型生成模块
|
||
// ============================================
|
||
|
||
/// AI 3D 生成任务表
|
||
model AI3DTask {
|
||
id Int @id @default(autoincrement())
|
||
tenantId Int @map("tenant_id") /// 租户ID
|
||
userId Int @map("user_id") /// 用户ID(任务归属用户)
|
||
inputType String @map("input_type") /// 输入类型:text | image
|
||
inputContent String @map("input_content") @db.Text /// 输入内容:文字描述或图片URL
|
||
generateType String @default("Normal") @map("generate_type") /// 生成类型:Normal(带纹理) | Geometry(白模) | LowPoly(低多边形) | Sketch(草图)
|
||
status String @default("pending") /// 任务状态:pending | processing | completed | failed | timeout
|
||
resultUrl String? @map("result_url") @db.Text /// 生成的3D模型URL(单个结果,兼容旧数据)
|
||
previewUrl String? @map("preview_url") @db.Text /// 预览图URL(单个结果,兼容旧数据)
|
||
resultUrls Json? @map("result_urls") /// 生成的3D模型URL数组(多个结果,文生3D生成4个)
|
||
previewUrls Json? @map("preview_urls") /// 预览图URL数组(多个结果)
|
||
errorMessage String? @map("error_message") @db.Text /// 失败时的错误信息
|
||
externalTaskId String? @map("external_task_id") /// 外部AI服务的任务ID
|
||
retryCount Int @default(0) @map("retry_count") /// 已重试次数
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
completeTime DateTime? @map("complete_time") /// 完成时间
|
||
|
||
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
|
||
user User @relation("AI3DTaskUser", fields: [userId], references: [id], onDelete: Cascade)
|
||
|
||
@@index([userId])
|
||
@@index([tenantId])
|
||
@@index([status])
|
||
@@index([createTime])
|
||
@@map("t_ai_3d_task")
|
||
}
|
||
|
||
/// 预设评语表
|
||
model PresetComment {
|
||
id Int @id @default(autoincrement())
|
||
contestId Int @map("contest_id") /// 赛事ID
|
||
judgeId Int @map("judge_id") /// 评委用户ID
|
||
content String @db.Text /// 评语内容
|
||
score Decimal? @db.Decimal(10, 2) /// 关联评审分数
|
||
sortOrder Int @default(0) @map("sort_order") /// 排序顺序
|
||
useCount Int @default(0) @map("use_count") /// 使用次数
|
||
validState Int @default(1) @map("valid_state") /// 有效状态:1-有效,2-失效
|
||
creator Int? /// 创建人ID
|
||
modifier Int? /// 修改人ID
|
||
createTime DateTime @default(now()) @map("create_time") /// 创建时间
|
||
modifyTime DateTime @updatedAt @map("modify_time") /// 修改时间
|
||
|
||
contest Contest @relation(fields: [contestId], references: [id], onDelete: Cascade)
|
||
judge User @relation("PresetCommentJudge", fields: [judgeId], references: [id], onDelete: Cascade)
|
||
|
||
@@index([contestId, judgeId])
|
||
@@map("t_preset_comment")
|
||
}
|