library-picturebook-activity/backend/prisma/schema.prisma

1099 lines
60 KiB
Plaintext
Raw Normal View History

2025-11-23 14:04:20 +08:00
// 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") /// 修改时间
2026-01-13 14:01:17 +08:00
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[] /// 赛事报名
2026-01-09 18:14:35 +08:00
contestRegistrationTeachers ContestRegistrationTeacher[] /// 报名指导老师关联
2026-01-13 14:01:17 +08:00
contestWorks ContestWork[] /// 参赛作品
contestWorkAttachments ContestWorkAttachment[] /// 作品附件
contestWorkScores ContestWorkScore[] /// 作品评分
contestReviewRules ContestReviewRule[] /// 评审规则
2026-01-09 18:14:35 +08:00
// 作业管理关联
2026-01-13 14:01:17 +08:00
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)
2025-11-23 14:04:20 +08:00
@@map("tenants")
}
/// 用户表
model User {
2026-01-12 16:06:34 +08:00
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-失效
2026-01-13 14:01:17 +08:00
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")
2025-12-09 11:10:36 +08:00
// 赛事相关关联
2026-01-13 14:01:17 +08:00
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")
2025-12-09 11:10:36 +08:00
modifiedContestWorkJudgeAssignments ContestWorkJudgeAssignment[] @relation("ContestWorkJudgeAssignmentModifier")
2026-01-13 14:01:17 +08:00
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")
2026-01-09 18:14:35 +08:00
modifiedContestRegistrationTeachers ContestRegistrationTeacher[] @relation("ContestRegistrationTeacherModifier")
// 作业管理关联
2026-01-13 14:01:17 +08:00
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 生成任务
2025-11-23 14:04:20 +08:00
@@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") /// 修改时间
2025-12-09 11:10:36 +08:00
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
2025-11-23 14:04:20 +08:00
users UserRole[]
permissions RolePermission[]
2025-12-09 11:10:36 +08:00
creatorUser User? @relation("RoleCreator", fields: [creator], references: [id], onDelete: SetNull)
modifierUser User? @relation("RoleModifier", fields: [modifier], references: [id], onDelete: SetNull)
2025-11-23 14:04:20 +08:00
@@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") /// 修改时间
2025-12-09 11:10:36 +08:00
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
2025-11-23 14:04:20 +08:00
roles RolePermission[]
2025-12-09 11:10:36 +08:00
creatorUser User? @relation("PermissionCreator", fields: [creator], references: [id], onDelete: SetNull)
modifierUser User? @relation("PermissionModifier", fields: [modifier], references: [id], onDelete: SetNull)
2025-11-23 14:04:20 +08:00
@@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") /// 修改时间
2025-12-09 11:10:36 +08:00
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)
2025-11-23 14:04:20 +08:00
@@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") /// 修改时间
2025-12-09 11:10:36 +08:00
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)
2025-11-23 14:04:20 +08:00
@@unique([tenantId, key])
@@map("configs")
}
/// 日志记录表
model Log {
id Int @id @default(autoincrement())
userId Int? @map("user_id") /// 用户ID
action String /// 操作类型
2025-12-09 11:10:36 +08:00
content String? @db.Text /// 操作内容(使用 TEXT 类型支持长文本)
2025-11-23 14:04:20 +08:00
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")
}
2025-12-09 11:10:36 +08:00
/// 学校信息表(扩展租户信息)
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
2026-01-08 09:17:46 +08:00
status String @default("ongoing") /// 赛事进度状态ongoing/finished
2025-12-09 11:10:36 +08:00
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? /// 赞助单位数组
2026-01-08 09:17:46 +08:00
// 报名配置
2025-12-09 11:10:36 +08:00
registerStartTime DateTime @map("register_start_time") /// 报名开始时间
registerEndTime DateTime @map("register_end_time") /// 报名结束时间
registerState String? @map("register_state") /// 报名任务状态started/closed
2026-01-08 09:17:46 +08:00
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") /// 团队最多成员数
// 作品配置
2025-12-09 11:10:36 +08:00
submitRule String @default("once") @map("submit_rule") /// 提交规则once/resubmit
submitStartTime DateTime @map("submit_start_time") /// 作品提交开始时间
submitEndTime DateTime @map("submit_end_time") /// 作品提交结束时间
2026-01-08 09:17:46 +08:00
workType String? @map("work_type") /// 作品类型image/video/document/code
2026-01-13 14:01:17 +08:00
workRequirement String? @map("work_requirement") @db.Text /// 作品要求说明
2026-01-08 09:17:46 +08:00
// 评审配置
2025-12-09 11:10:36 +08:00
reviewRuleId Int? @map("review_rule_id") /// 评审规则id
reviewStartTime DateTime @map("review_start_time") /// 评审开始时间
reviewEndTime DateTime @map("review_end_time") /// 评审结束时间
2026-01-08 09:17:46 +08:00
// 赛果配置
resultState String @default("unpublished") @map("result_state") /// 赛果状态unpublished/published
2025-12-09 11:10:36 +08:00
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-失效
2026-01-13 14:01:17 +08:00
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[] /// 赛事公告
creatorUser User? @relation("ContestCreator", fields: [creator], references: [id], onDelete: SetNull)
modifierUser User? @relation("ContestModifier", fields: [modifier], references: [id], onDelete: SetNull)
2025-12-09 11:10:36 +08:00
@@unique([contestName])
@@index([contestState])
@@index([startTime, endTime])
@@index([reviewRuleId])
@@map("t_contest")
}
/// 赛事附件表
model ContestAttachment {
2026-01-13 14:01:17 +08:00
id Int @id @default(autoincrement())
contestId Int @map("contest_id") /// 赛事id
fileName String @map("file_name") /// 文件名
fileUrl String @map("file_url") /// 文件路径
2025-12-09 11:10:36 +08:00
format String? /// 文件类型png,mp4
2026-01-13 14:01:17 +08:00
fileType String? @map("file_type") /// 素材类型image,video
size String @default("0") /// 文件大小
2025-12-09 11:10:36 +08:00
creator Int? /// 创建人ID
modifier Int? /// 修改人ID
2026-01-13 14:01:17 +08:00
createTime DateTime @default(now()) @map("create_time") /// 创建时间
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
validState Int @default(1) @map("valid_state") /// 有效状态1-有效2-失效
2025-12-09 11:10:36 +08:00
2026-01-13 14:01:17 +08:00
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)
2025-12-09 11:10:36 +08:00
@@index([contestId])
@@map("t_contest_attachment")
}
2026-01-08 09:17:46 +08:00
/// 评审规则表(独立存在,可被多个赛事使用)
2025-12-09 11:10:36 +08:00
model ContestReviewRule {
2026-01-13 14:01:17 +08:00
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") /// 评委数量
2025-12-09 11:10:36 +08:00
dimensions Json /// 评分维度配置JSON
2026-01-13 14:01:17 +08:00
calculationRule String @default("average") @map("calculation_rule") /// 计算规则average/remove_max_min/remove_min
2025-12-09 11:10:36 +08:00
creator Int? /// 创建人ID
modifier Int? /// 修改人ID
2026-01-13 14:01:17 +08:00
createTime DateTime @default(now()) @map("create_time") /// 创建时间
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
validState Int @default(1) @map("valid_state") /// 有效状态1-有效2-失效
2025-12-09 11:10:36 +08:00
2026-01-08 09:17:46 +08:00
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)
2025-12-09 11:10:36 +08:00
2026-01-08 09:17:46 +08:00
@@index([tenantId])
2025-12-09 11:10:36 +08:00
@@map("t_contest_review_rule")
}
/// 赛事团队表
model ContestTeam {
2026-01-13 14:01:17 +08:00
id Int @id @default(autoincrement())
tenantId Int @map("tenant_id") /// 团队所属租户ID
contestId Int @map("contest_id") /// 赛事id
teamName String @map("team_name") /// 团队名称(租户内唯一)
2025-12-09 11:10:36 +08:00
leaderUserId Int @map("leader_user_id") /// 团队负责人用户id
2026-01-13 14:01:17 +08:00
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-失效
2025-12-09 11:10:36 +08:00
2026-01-13 14:01:17 +08:00
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[] /// 团队成员
2025-12-09 11:10:36 +08:00
registrations ContestRegistration[] /// 报名记录
2026-01-13 14:01:17 +08:00
creatorUser User? @relation("ContestTeamCreator", fields: [creator], references: [id], onDelete: SetNull)
modifierUser User? @relation("ContestTeamModifier", fields: [modifier], references: [id], onDelete: SetNull)
2025-12-09 11:10:36 +08:00
@@unique([tenantId, contestId, teamName])
@@index([contestId])
@@index([leaderUserId])
@@map("t_contest_team")
}
/// 团队成员表
model ContestTeamMember {
2026-01-13 14:01:17 +08:00
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)
2025-12-09 11:10:36 +08:00
@@unique([tenantId, teamId, userId])
@@index([teamId])
@@index([userId])
@@map("t_contest_team_member")
}
/// 赛事报名表
model ContestRegistration {
2026-01-13 14:01:17 +08:00
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)
2025-12-09 11:10:36 +08:00
works ContestWork[] /// 参赛作品
2026-01-13 14:01:17 +08:00
creatorUser User? @relation("ContestRegistrationCreator", fields: [creator], references: [id], onDelete: SetNull)
modifierUser User? @relation("ContestRegistrationModifier", fields: [modifier], references: [id], onDelete: SetNull)
2025-12-09 11:10:36 +08:00
2026-01-09 18:14:35 +08:00
teachers ContestRegistrationTeacher[] /// 指导老师关联
2025-12-09 11:10:36 +08:00
@@index([contestId, tenantId])
@@index([userId, contestId])
@@index([teamId])
@@index([registrationState])
@@map("t_contest_registration")
}
2026-01-09 18:14:35 +08:00
/// 报名指导老师关联表
model ContestRegistrationTeacher {
2026-01-13 14:01:17 +08:00
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") /// 更新时间
2026-01-09 18:14:35 +08:00
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")
}
2025-12-09 11:10:36 +08:00
/// 参赛作品表
model ContestWork {
2026-01-13 14:01:17 +08:00
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
2026-01-14 17:00:06 +08:00
previewUrl String? @map("preview_url") @db.Text /// 作品预览URL
2026-01-13 14:01:17 +08:00
aiModelMeta Json? @map("ai_model_meta") /// AI建模元数据
2026-01-08 09:17:46 +08:00
// 赛果相关字段
2026-01-13 14:01:17 +08:00
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)
2025-12-09 11:10:36 +08:00
@@index([tenantId, contestId, isLatest])
@@index([registrationId])
@@index([tenantId, contestId, submitTime, status])
@@index([contestId, status])
@@map("t_contest_work")
}
/// 作品附件文件表
model ContestWorkAttachment {
2026-01-13 14:01:17 +08:00
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") /// 文件路径
2025-12-09 11:10:36 +08:00
format String? /// 文件类型png,mp4
2026-01-13 14:01:17 +08:00
fileType String? @map("file_type") /// 素材类型image,video
size String @default("0") /// 文件大小
2025-12-09 11:10:36 +08:00
creator Int? /// 创建人ID
modifier Int? /// 修改人ID
2026-01-13 14:01:17 +08:00
createTime DateTime @default(now()) @map("create_time") /// 创建时间
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
2025-12-09 11:10:36 +08:00
2026-01-13 14:01:17 +08:00
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)
2025-12-09 11:10:36 +08:00
@@index([tenantId, contestId, workId])
@@map("t_contest_work_attachment")
}
/// 比赛评委关联表(比赛与评委的多对多关系)
model ContestJudge {
2026-01-13 14:01:17 +08:00
id Int @id @default(autoincrement())
contestId Int @map("contest_id") /// 比赛id
judgeId Int @map("judge_id") /// 评委用户id
2025-12-09 11:10:36 +08:00
specialty String? /// 评审专业领域(可选)
2026-01-13 14:01:17 +08:00
weight Decimal? @db.Decimal(3, 2) /// 评审权重(可选,用于加权平均计算)
description String? @db.Text /// 评委在该比赛中的说明
2025-12-09 11:10:36 +08:00
creator Int? /// 创建人ID
modifier Int? /// 修改人ID
2026-01-13 14:01:17 +08:00
createTime DateTime @default(now()) @map("create_time") /// 创建时间
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
validState Int @default(1) @map("valid_state") /// 有效状态1-有效2-失效
2025-12-09 11:10:36 +08:00
2026-01-13 14:01:17 +08:00
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)
2025-12-09 11:10:36 +08:00
@@unique([contestId, judgeId])
@@index([contestId])
@@index([judgeId])
@@map("t_contest_judge")
}
/// 作品分配表(评委分配作品)
model ContestWorkJudgeAssignment {
2026-01-13 14:01:17 +08:00
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
2025-12-09 11:10:36 +08:00
creator Int? /// 创建人ID
modifier Int? /// 修改人ID
2026-01-13 14:01:17 +08:00
createTime DateTime @default(now()) @map("create_time") /// 创建时间
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
2025-12-09 11:10:36 +08:00
2026-01-13 14:01:17 +08:00
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)
2025-12-09 11:10:36 +08:00
@@unique([workId, judgeId])
@@index([contestId, judgeId])
@@index([workId])
@@index([status])
@@map("t_contest_work_judge_assignment")
}
/// 作品评分表
model ContestWorkScore {
2026-01-13 14:01:17 +08:00
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") /// 评分时间
2025-12-09 11:10:36 +08:00
creator Int? /// 创建人ID
modifier Int? /// 修改人ID
2026-01-13 14:01:17 +08:00
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)
2025-12-09 11:10:36 +08:00
@@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-失效
2026-01-13 14:01:17 +08:00
contest Contest @relation(fields: [contestId], references: [id], onDelete: Cascade)
creatorUser User? @relation("ContestNoticeCreator", fields: [creator], references: [id], onDelete: SetNull)
2025-12-09 11:10:36 +08:00
modifierUser User? @relation("ContestNoticeModifier", fields: [modifier], references: [id], onDelete: SetNull)
@@index([contestId])
@@index([publishTime])
@@index([noticeType])
@@map("t_contest_notice")
}
2026-01-09 18:14:35 +08:00
// ============================================
// 作业管理模块
// ============================================
/// 作业表
model Homework {
id Int @id @default(autoincrement())
tenantId Int @map("tenant_id") /// 租户ID
2026-01-13 14:01:17 +08:00
name String /// 作业名称
2026-01-09 18:14:35 +08:00
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") /// 提交结束时间
2026-01-13 14:01:17 +08:00
attachments Json? /// 附件列表 [{fileName, fileUrl, size}]
2026-01-09 18:14:35 +08:00
publishScope Json? @map("publish_scope") /// 公开范围班级ID数组
reviewRuleId Int? @map("review_rule_id") /// 评审规则ID
2026-01-13 14:01:17 +08:00
creator Int? /// 创建人ID
modifier Int? /// 修改人ID
2026-01-09 18:14:35 +08:00
createTime DateTime @default(now()) @map("create_time") /// 创建时间
modifyTime DateTime @updatedAt @map("modify_time") /// 更新时间
validState Int @default(1) @map("valid_state") /// 有效状态1-有效2-失效
2026-01-13 14:01:17 +08:00
tenant Tenant @relation(fields: [tenantId], references: [id], onDelete: Cascade)
reviewRule HomeworkReviewRule? @relation(fields: [reviewRuleId], references: [id], onDelete: SetNull)
2026-01-09 18:14:35 +08:00
submissions HomeworkSubmission[] /// 作业提交记录
2026-01-13 14:01:17 +08:00
creatorUser User? @relation("HomeworkCreator", fields: [creator], references: [id], onDelete: SetNull)
modifierUser User? @relation("HomeworkModifier", fields: [modifier], references: [id], onDelete: SetNull)
2026-01-09 18:14:35 +08:00
@@index([tenantId, status])
@@index([tenantId, submitStartTime, submitEndTime])
@@map("t_homework")
}
/// 作业提交表
model HomeworkSubmission {
2026-01-13 14:01:17 +08:00
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-失效
2026-01-09 18:14:35 +08:00
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 {
2026-01-13 14:01:17 +08:00
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-失效
2026-01-09 18:14:35 +08:00
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 {
2026-01-13 14:01:17 +08:00
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-失效
2026-01-09 18:14:35 +08:00
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")
}
2026-01-13 14:01:17 +08:00
// ============================================
// 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
status String @default("pending") /// 任务状态pending | processing | completed | failed | timeout
2026-01-14 10:06:08 +08:00
resultUrl String? @map("result_url") @db.Text /// 生成的3D模型URL单个结果兼容旧数据
previewUrl String? @map("preview_url") @db.Text /// 预览图URL单个结果兼容旧数据
2026-01-13 16:41:12 +08:00
resultUrls Json? @map("result_urls") /// 生成的3D模型URL数组多个结果文生3D生成4个
previewUrls Json? @map("preview_urls") /// 预览图URL数组多个结果
2026-01-13 14:01:17 +08:00
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")
}