12301344
This commit is contained in:
parent
56c5a35673
commit
3e47150b1a
|
@ -108,14 +108,14 @@ export class PostService extends BaseService<Prisma.PostDelegate> {
|
||||||
authorId: staff.id,
|
authorId: staff.id,
|
||||||
},
|
},
|
||||||
staff?.id && {
|
staff?.id && {
|
||||||
watchStaffs: {
|
watchableStaffs: {
|
||||||
some: {
|
some: {
|
||||||
id: staff.id,
|
id: staff.id,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
deptId && {
|
deptId && {
|
||||||
watchDepts: {
|
watchableDepts: {
|
||||||
some: {
|
some: {
|
||||||
id: {
|
id: {
|
||||||
in: parentDeptIds,
|
in: parentDeptIds,
|
||||||
|
@ -127,13 +127,13 @@ export class PostService extends BaseService<Prisma.PostDelegate> {
|
||||||
{
|
{
|
||||||
AND: [
|
AND: [
|
||||||
{
|
{
|
||||||
watchStaffs: {
|
watchableStaffs: {
|
||||||
none: {}, // 匹配 watchStaffs 为空
|
none: {}, // 匹配 watchableStaffs 为空
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
watchDepts: {
|
watchableDepts: {
|
||||||
none: {}, // 匹配 watchDepts 为空
|
none: {}, // 匹配 watchableDepts 为空
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -22,7 +22,7 @@ datasource db {
|
||||||
}
|
}
|
||||||
|
|
||||||
model Taxonomy {
|
model Taxonomy {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
name String @unique
|
name String @unique
|
||||||
slug String @unique @map("slug")
|
slug String @unique @map("slug")
|
||||||
deletedAt DateTime? @map("deleted_at")
|
deletedAt DateTime? @map("deleted_at")
|
||||||
|
@ -36,7 +36,7 @@ model Taxonomy {
|
||||||
}
|
}
|
||||||
|
|
||||||
model Term {
|
model Term {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
name String
|
name String
|
||||||
taxonomy Taxonomy? @relation(fields: [taxonomyId], references: [id])
|
taxonomy Taxonomy? @relation(fields: [taxonomyId], references: [id])
|
||||||
taxonomyId String? @map("taxonomy_id")
|
taxonomyId String? @map("taxonomy_id")
|
||||||
|
@ -55,6 +55,7 @@ model Term {
|
||||||
createdBy String? @map("created_by")
|
createdBy String? @map("created_by")
|
||||||
depts Department[] @relation("department_term")
|
depts Department[] @relation("department_term")
|
||||||
hasChildren Boolean? @default(false) @map("has_children")
|
hasChildren Boolean? @default(false) @map("has_children")
|
||||||
|
courses Course[] @relation("course_term")
|
||||||
|
|
||||||
@@index([name]) // 对name字段建立索引,以加快基于name的查找速度
|
@@index([name]) // 对name字段建立索引,以加快基于name的查找速度
|
||||||
@@index([parentId]) // 对parentId字段建立索引,以加快基于parentId的查找速度
|
@@index([parentId]) // 对parentId字段建立索引,以加快基于parentId的查找速度
|
||||||
|
@ -62,7 +63,7 @@ model Term {
|
||||||
}
|
}
|
||||||
|
|
||||||
model TermAncestry {
|
model TermAncestry {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
ancestorId String? @map("ancestor_id")
|
ancestorId String? @map("ancestor_id")
|
||||||
descendantId String @map("descendant_id")
|
descendantId String @map("descendant_id")
|
||||||
relDepth Int @map("rel_depth")
|
relDepth Int @map("rel_depth")
|
||||||
|
@ -78,7 +79,7 @@ model TermAncestry {
|
||||||
}
|
}
|
||||||
|
|
||||||
model Staff {
|
model Staff {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
showname String? @map("showname")
|
showname String? @map("showname")
|
||||||
username String @unique @map("username")
|
username String @unique @map("username")
|
||||||
avatar String? @map("avatar")
|
avatar String? @map("avatar")
|
||||||
|
@ -88,10 +89,9 @@ model Staff {
|
||||||
domainId String? @map("domain_id")
|
domainId String? @map("domain_id")
|
||||||
deptId String? @map("dept_id")
|
deptId String? @map("dept_id")
|
||||||
|
|
||||||
domain Department? @relation("DomainStaff", fields: [domainId], references: [id])
|
domain Department? @relation("DomainStaff", fields: [domainId], references: [id])
|
||||||
department Department? @relation("DeptStaff", fields: [deptId], references: [id])
|
department Department? @relation("DeptStaff", fields: [deptId], references: [id])
|
||||||
registerToken String? @map("register_token")
|
order Float?
|
||||||
order Float?
|
|
||||||
|
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
updatedAt DateTime @updatedAt @map("updated_at")
|
updatedAt DateTime @updatedAt @map("updated_at")
|
||||||
|
@ -99,14 +99,15 @@ model Staff {
|
||||||
deletedAt DateTime? @map("deleted_at")
|
deletedAt DateTime? @map("deleted_at")
|
||||||
officerId String? @map("officer_id")
|
officerId String? @map("officer_id")
|
||||||
|
|
||||||
|
watchedPost Post[] @relation("post_watch_staff")
|
||||||
|
visits Visit[]
|
||||||
|
posts Post[]
|
||||||
|
sentMsgs Message[] @relation("message_sender")
|
||||||
|
receivedMsgs Message[] @relation("message_receiver")
|
||||||
|
|
||||||
watchedPost Post[] @relation("post_watch_staff")
|
enrollments Enrollment[]
|
||||||
visits Visit[]
|
courseReviews CourseReview[]
|
||||||
posts Post[]
|
teachedCourses CourseInstructor[]
|
||||||
sentMsgs Message[] @relation("message_sender")
|
|
||||||
receivedMsgs Message[] @relation("message_receiver")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@index([officerId])
|
@@index([officerId])
|
||||||
@@index([deptId])
|
@@index([deptId])
|
||||||
|
@ -117,25 +118,24 @@ model Staff {
|
||||||
}
|
}
|
||||||
|
|
||||||
model Department {
|
model Department {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
name String
|
name String
|
||||||
order Float?
|
order Float?
|
||||||
ancestors DeptAncestry[] @relation("DescendantToAncestor")
|
ancestors DeptAncestry[] @relation("DescendantToAncestor")
|
||||||
descendants DeptAncestry[] @relation("AncestorToDescendant")
|
descendants DeptAncestry[] @relation("AncestorToDescendant")
|
||||||
parentId String? @map("parent_id")
|
parentId String? @map("parent_id")
|
||||||
parent Department? @relation("ChildParent", fields: [parentId], references: [id])
|
parent Department? @relation("ChildParent", fields: [parentId], references: [id])
|
||||||
children Department[] @relation("ChildParent")
|
children Department[] @relation("ChildParent")
|
||||||
domainId String? @map("domain_id")
|
domainId String? @map("domain_id")
|
||||||
domainTerms Term[] @relation("TermDom")
|
domainTerms Term[] @relation("TermDom")
|
||||||
deletedAt DateTime? @map("deleted_at")
|
deletedAt DateTime? @map("deleted_at")
|
||||||
isDomain Boolean? @default(false) @map("is_domain")
|
isDomain Boolean? @default(false) @map("is_domain")
|
||||||
domainStaffs Staff[] @relation("DomainStaff")
|
domainStaffs Staff[] @relation("DomainStaff")
|
||||||
deptStaffs Staff[] @relation("DeptStaff")
|
deptStaffs Staff[] @relation("DeptStaff")
|
||||||
terms Term[] @relation("department_term")
|
terms Term[] @relation("department_term")
|
||||||
|
|
||||||
visits Visit[] @relation("visit_dept")
|
watchedPost Post[] @relation("post_watch_dept")
|
||||||
watchedPost Post[] @relation("post_watch_dept")
|
hasChildren Boolean? @default(false) @map("has_children")
|
||||||
hasChildren Boolean? @default(false) @map("has_children")
|
|
||||||
|
|
||||||
@@index([parentId])
|
@@index([parentId])
|
||||||
@@index([isDomain])
|
@@index([isDomain])
|
||||||
|
@ -145,7 +145,7 @@ model Department {
|
||||||
}
|
}
|
||||||
|
|
||||||
model DeptAncestry {
|
model DeptAncestry {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
ancestorId String? @map("ancestor_id")
|
ancestorId String? @map("ancestor_id")
|
||||||
descendantId String @map("descendant_id")
|
descendantId String @map("descendant_id")
|
||||||
relDepth Int @map("rel_depth")
|
relDepth Int @map("rel_depth")
|
||||||
|
@ -161,7 +161,7 @@ model DeptAncestry {
|
||||||
}
|
}
|
||||||
|
|
||||||
model RoleMap {
|
model RoleMap {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
objectId String @map("object_id")
|
objectId String @map("object_id")
|
||||||
roleId String @map("role_id")
|
roleId String @map("role_id")
|
||||||
domainId String? @map("domain_id")
|
domainId String? @map("domain_id")
|
||||||
|
@ -174,7 +174,7 @@ model RoleMap {
|
||||||
}
|
}
|
||||||
|
|
||||||
model Role {
|
model Role {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
name String @unique @map("name")
|
name String @unique @map("name")
|
||||||
permissions String[] @default([]) @map("permissions")
|
permissions String[] @default([]) @map("permissions")
|
||||||
roleMaps RoleMap[]
|
roleMaps RoleMap[]
|
||||||
|
@ -187,7 +187,7 @@ model Role {
|
||||||
}
|
}
|
||||||
|
|
||||||
model AppConfig {
|
model AppConfig {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
slug String @unique
|
slug String @unique
|
||||||
title String?
|
title String?
|
||||||
description String?
|
description String?
|
||||||
|
@ -197,25 +197,27 @@ model AppConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
model Post {
|
model Post {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
type String?
|
type String?
|
||||||
title String?
|
title String?
|
||||||
content String?
|
content String?
|
||||||
author Staff? @relation(fields: [authorId], references: [id])
|
author Staff? @relation(fields: [authorId], references: [id])
|
||||||
authorId String?
|
authorId String?
|
||||||
domainId String?
|
domainId String?
|
||||||
referenceId String?
|
referenceId String?
|
||||||
attachments String[] @default([])
|
attachments String[] @default([])
|
||||||
createdAt DateTime @default(now())
|
createdAt DateTime @default(now())
|
||||||
updatedAt DateTime @updatedAt
|
updatedAt DateTime @updatedAt
|
||||||
visits Visit[]
|
visits Visit[]
|
||||||
watchStaffs Staff[] @relation("post_watch_staff")
|
watchableStaffs Staff[] @relation("post_watch_staff")
|
||||||
watchDepts Department[] @relation("post_watch_dept")
|
watchableDepts Department[] @relation("post_watch_dept")
|
||||||
|
|
||||||
parentId String?
|
parentId String?
|
||||||
parent Post? @relation("PostChildren", fields: [parentId], references: [id])
|
parent Post? @relation("PostChildren", fields: [parentId], references: [id])
|
||||||
children Post[] @relation("PostChildren")
|
children Post[] @relation("PostChildren")
|
||||||
deletedAt DateTime? @map("deleted_at")
|
deletedAt DateTime? @map("deleted_at")
|
||||||
|
Lecture Lecture? @relation(fields: [lectureId], references: [id])
|
||||||
|
lectureId String?
|
||||||
|
|
||||||
// 复合索引
|
// 复合索引
|
||||||
@@index([type, domainId]) // 类型和域组合查询
|
@@index([type, domainId]) // 类型和域组合查询
|
||||||
|
@ -228,7 +230,7 @@ model Post {
|
||||||
}
|
}
|
||||||
|
|
||||||
model Message {
|
model Message {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
url String?
|
url String?
|
||||||
intent String?
|
intent String?
|
||||||
option Json?
|
option Json?
|
||||||
|
@ -247,24 +249,265 @@ model Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
model Visit {
|
model Visit {
|
||||||
id String @id @default(uuid())
|
id String @id @default(cuid())
|
||||||
postId String? @map("post_id")
|
visitType String? @map("visit_type")
|
||||||
troubleId String? @map("trouble_id")
|
|
||||||
messageId String? @map("message_id")
|
|
||||||
visitorId String @map("visitor_id")
|
visitorId String @map("visitor_id")
|
||||||
visitor Staff @relation(fields: [visitorId], references: [id])
|
visitor Staff @relation(fields: [visitorId], references: [id])
|
||||||
deptId String? @map("dept_id")
|
postId String? @map("post_id")
|
||||||
department Department? @relation(name: "visit_dept", fields: [deptId], references: [id])
|
post Post? @relation(fields: [postId], references: [id])
|
||||||
|
message Message? @relation(fields: [messageId], references: [id])
|
||||||
|
messageId String? @map("message_id")
|
||||||
|
views Int @default(1)
|
||||||
createdAt DateTime? @default(now()) @map("created_at")
|
createdAt DateTime? @default(now()) @map("created_at")
|
||||||
updatedAt DateTime? @updatedAt @map("updated_at")
|
updatedAt DateTime? @updatedAt @map("updated_at")
|
||||||
sourceIP String? @map("source_ip")
|
sourceIP String? @map("source_ip")
|
||||||
visitType String? @map("visit_type")
|
|
||||||
post Post? @relation(fields: [postId], references: [id])
|
|
||||||
message Message? @relation(fields: [messageId], references: [id])
|
|
||||||
views Int @default(1)
|
|
||||||
|
|
||||||
@@index([postId, visitType, visitorId])
|
@@index([postId, visitType, visitorId])
|
||||||
@@index([troubleId, visitType, visitorId])
|
|
||||||
@@index([messageId, visitType, visitorId])
|
@@index([messageId, visitType, visitorId])
|
||||||
@@map("visit")
|
@@map("visit")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
model Course {
|
||||||
|
id String @id @default(cuid()) // 课程唯一标识符
|
||||||
|
title String // 课程标题
|
||||||
|
subTitle String? // 课程副标题(可选)
|
||||||
|
description String // 课程详细描述
|
||||||
|
thumbnail String? // 课程封面图片URL(可选)
|
||||||
|
level String // 课程难度等级
|
||||||
|
|
||||||
|
// 课程内容组织结构
|
||||||
|
terms Term[] @relation("course_term") // 课程学期
|
||||||
|
instructors CourseInstructor[] // 课程讲师团队
|
||||||
|
sections Section[] // 课程章节结构
|
||||||
|
enrollments Enrollment[] // 学生报名记录
|
||||||
|
reviews CourseReview[] // 学员课程评价
|
||||||
|
|
||||||
|
// 课程规划与目标设定
|
||||||
|
requirements String[] // 课程学习前置要求
|
||||||
|
objectives String[] // 具体的学习目标
|
||||||
|
skills String[] // 课程结束后可掌握的技能
|
||||||
|
audiences String[] // 目标受众群体描述
|
||||||
|
|
||||||
|
// 课程统计指标
|
||||||
|
totalDuration Int @default(0) // 课程总时长(分钟)
|
||||||
|
totalLectures Int @default(0) // 总课时数
|
||||||
|
averageRating Float @default(0) // 平均评分(1-5分)
|
||||||
|
numberOfReviews Int @default(0) // 评价总数
|
||||||
|
numberOfStudents Int @default(0) // 学习人数
|
||||||
|
completionRate Float @default(0) // 完课率(0-100%)
|
||||||
|
|
||||||
|
// 课程状态管理
|
||||||
|
status String // 课程状态(如:草稿/已发布/已归档)
|
||||||
|
isFeatured Boolean @default(false) // 是否为精选推荐课程
|
||||||
|
|
||||||
|
// 生命周期时间戳
|
||||||
|
createdAt DateTime @default(now()) // 创建时间
|
||||||
|
updatedAt DateTime @updatedAt // 最后更新时间
|
||||||
|
publishedAt DateTime? // 发布时间
|
||||||
|
archivedAt DateTime? // 归档时间
|
||||||
|
deletedAt DateTime? // 软删除时间
|
||||||
|
|
||||||
|
// 数据库索引优化
|
||||||
|
@@index([status]) // 课程状态索引,用于快速筛选
|
||||||
|
@@index([level]) // 难度等级索引,用于分类查询
|
||||||
|
@@index([isFeatured]) // 精选标记索引,用于首页推荐
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
model Section {
|
||||||
|
id String @id @default(cuid()) // 章节唯一标识符
|
||||||
|
title String // 章节标题
|
||||||
|
description String? // 章节描述(可选)
|
||||||
|
objectives String[] // 本章节的具体学习目标
|
||||||
|
order Float? @default(0) // 章节排序权重
|
||||||
|
|
||||||
|
// 关联关系
|
||||||
|
course Course @relation(fields: [courseId], references: [id], onDelete: Cascade)
|
||||||
|
courseId String // 所属课程ID
|
||||||
|
lectures Lecture[] // 包含的所有课时
|
||||||
|
|
||||||
|
// 章节统计数据
|
||||||
|
totalDuration Int @default(0) // 本章节总时长(分钟)
|
||||||
|
totalLectures Int @default(0) // 本章节课时总数
|
||||||
|
|
||||||
|
// 时间管理
|
||||||
|
createdAt DateTime @default(now()) // 创建时间
|
||||||
|
updatedAt DateTime @updatedAt // 更新时间
|
||||||
|
deletedAt DateTime? // 软删除时间
|
||||||
|
|
||||||
|
@@index([courseId, order]) // 复合索引:用于按课程ID和顺序快速查询
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
model Lecture {
|
||||||
|
id String @id @default(cuid()) // 课时唯一标识符
|
||||||
|
title String // 课时标题
|
||||||
|
description String? // 课时描述(可选)
|
||||||
|
order Float? @default(0) // 课时排序权重
|
||||||
|
duration Int // 学习时长(分钟)
|
||||||
|
type String // 课时类型(video/article)
|
||||||
|
|
||||||
|
// 课时内容
|
||||||
|
content String? // Markdown格式文章内容
|
||||||
|
videoUrl String? // 视频URL地址
|
||||||
|
videoThumbnail String? // 视频封面图URL
|
||||||
|
|
||||||
|
// 关联内容
|
||||||
|
resources Resource[] // 课时附属资源
|
||||||
|
section Section @relation(fields: [sectionId], references: [id], onDelete: Cascade)
|
||||||
|
sectionId String // 所属章节ID
|
||||||
|
comments Post[] // 课时评论
|
||||||
|
progress LectureProgress[] // 学习进度记录
|
||||||
|
|
||||||
|
// 时间管理
|
||||||
|
publishedAt DateTime? // 发布时间
|
||||||
|
createdAt DateTime @default(now()) // 创建时间
|
||||||
|
updatedAt DateTime @updatedAt // 更新时间
|
||||||
|
deletedAt DateTime? // 软删除时间
|
||||||
|
|
||||||
|
@@index([sectionId, order]) // 章节内课时排序索引
|
||||||
|
@@index([type, publishedAt]) // 课时类型和发布时间复合索引
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
model Enrollment {
|
||||||
|
id String @id @default(cuid()) // 报名记录唯一标识符
|
||||||
|
status String // 报名状态(如:进行中/已完成/已过期)
|
||||||
|
|
||||||
|
// 关联关系
|
||||||
|
student Staff @relation(fields: [studentId], references: [id])
|
||||||
|
studentId String // 学员ID
|
||||||
|
course Course @relation(fields: [courseId], references: [id])
|
||||||
|
courseId String // 课程ID
|
||||||
|
progress LectureProgress[] // 课时学习进度记录
|
||||||
|
|
||||||
|
// 学习数据统计
|
||||||
|
completionRate Float @default(0) // 课程完成度(0-100%)
|
||||||
|
lastAccessedAt DateTime? // 最后访问时间
|
||||||
|
|
||||||
|
// 时间管理
|
||||||
|
createdAt DateTime @default(now()) // 报名时间
|
||||||
|
updatedAt DateTime @updatedAt // 更新时间
|
||||||
|
completedAt DateTime? // 完课时间
|
||||||
|
|
||||||
|
|
||||||
|
@@unique([studentId, courseId]) // 确保学员不会重复报名同一课程
|
||||||
|
@@index([status]) // 报名状态索引
|
||||||
|
@@index([completedAt]) // 完课时间索引
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
model LectureProgress {
|
||||||
|
id String @id @default(cuid()) // 进度记录唯一标识符
|
||||||
|
progress Float @default(0) // 完成进度(0-100%)
|
||||||
|
isCompleted Boolean @default(false) // 是否完成
|
||||||
|
|
||||||
|
// 关联关系
|
||||||
|
enrollment Enrollment @relation(fields: [enrollmentId], references: [id], onDelete: Cascade)
|
||||||
|
enrollmentId String // 报名记录ID
|
||||||
|
lecture Lecture @relation(fields: [lectureId], references: [id], onDelete: Cascade)
|
||||||
|
lectureId String // 课时ID
|
||||||
|
|
||||||
|
// 学习数据
|
||||||
|
lastPosition Int @default(0) // 视频播放位置(秒)
|
||||||
|
viewCount Int @default(0) // 观看次数
|
||||||
|
readCount Int @default(0) // 阅读次数
|
||||||
|
totalWatchTime Int @default(0) // 总观看时长(秒)
|
||||||
|
|
||||||
|
// 时间记录
|
||||||
|
lastWatchedAt DateTime? // 最后观看时间
|
||||||
|
createdAt DateTime @default(now()) // 创建时间
|
||||||
|
updatedAt DateTime @updatedAt // 更新时间
|
||||||
|
|
||||||
|
@@unique([enrollmentId, lectureId]) // 确保每个报名只有一条课时进度
|
||||||
|
@@index([isCompleted]) // 完成状态索引
|
||||||
|
@@index([lastWatchedAt]) // 最后观看时间索引
|
||||||
|
}
|
||||||
|
|
||||||
|
model CourseInstructor {
|
||||||
|
course Course @relation(fields: [courseId], references: [id])
|
||||||
|
courseId String // 课程ID
|
||||||
|
instructor Staff @relation(fields: [instructorId], references: [id])
|
||||||
|
instructorId String // 讲师ID
|
||||||
|
role String // 讲师角色
|
||||||
|
createdAt DateTime @default(now()) // 创建时间
|
||||||
|
order Float? @default(0) // 讲师显示顺序
|
||||||
|
|
||||||
|
@@id([courseId, instructorId]) // 联合主键
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
model CourseReview {
|
||||||
|
id String @id @default(cuid()) // 评价唯一标识符
|
||||||
|
rating Int // 评分(1-5星)
|
||||||
|
content String? // 评价内容
|
||||||
|
student Staff @relation(fields: [studentId], references: [id])
|
||||||
|
studentId String // 评价学员ID
|
||||||
|
course Course @relation(fields: [courseId], references: [id])
|
||||||
|
courseId String // 课程ID
|
||||||
|
helpfulCount Int @default(0) // 评价点赞数
|
||||||
|
createdAt DateTime @default(now()) // 评价时间
|
||||||
|
updatedAt DateTime @updatedAt // 更新时间
|
||||||
|
|
||||||
|
@@unique([studentId, courseId]) // 确保学员对同一课程只能评价一次
|
||||||
|
@@index([rating]) // 评分索引
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
model Resource {
|
||||||
|
id String @id @default(cuid()) // 资源唯一标识符
|
||||||
|
title String // 资源标题
|
||||||
|
description String? // 资源描述
|
||||||
|
type String // 资源类型
|
||||||
|
url String // 资源URL
|
||||||
|
|
||||||
|
fileType String? // 文件MIME类型
|
||||||
|
fileSize Int? // 文件大小(bytes)
|
||||||
|
|
||||||
|
lecture Lecture @relation(fields: [lectureId], references: [id], onDelete: Cascade)
|
||||||
|
lectureId String // 所属课时ID
|
||||||
|
downloadCount Int @default(0) // 下载次数
|
||||||
|
createdAt DateTime @default(now()) // 创建时间
|
||||||
|
updatedAt DateTime @updatedAt // 更新时间
|
||||||
|
|
||||||
|
@@index([lectureId, type]) // 课时资源类型复合索引
|
||||||
|
}
|
||||||
|
|
||||||
|
model Node {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
title String
|
||||||
|
description String?
|
||||||
|
type String
|
||||||
|
// 节点之间的关系
|
||||||
|
sourceEdges NodeEdge[] @relation("from_node")
|
||||||
|
targetEdges NodeEdge[] @relation("to_node")
|
||||||
|
style Json?
|
||||||
|
position Json? // 存储节点在画布中的位置 {x: number, y: number}
|
||||||
|
data Json?
|
||||||
|
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
}
|
||||||
|
|
||||||
|
// 节点之间的关系
|
||||||
|
model NodeEdge {
|
||||||
|
id String @id @default(cuid())
|
||||||
|
// 关系的起点和终点
|
||||||
|
source Node @relation("from_node", fields: [sourceId], references: [id], onDelete: Cascade)
|
||||||
|
sourceId String
|
||||||
|
target Node @relation("to_node", fields: [targetId], references: [id], onDelete: Cascade)
|
||||||
|
targetId String
|
||||||
|
// 关系属性
|
||||||
|
type String?
|
||||||
|
label String?
|
||||||
|
description String?
|
||||||
|
// 自定义边的样式(可选)
|
||||||
|
style Json? // 存储边的样式,如 {color: string, strokeWidth: number}
|
||||||
|
createdAt DateTime @default(now())
|
||||||
|
updatedAt DateTime @updatedAt
|
||||||
|
|
||||||
|
@@unique([sourceId, targetId, type])
|
||||||
|
@@index([sourceId])
|
||||||
|
@@index([targetId])
|
||||||
|
}
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
import { Prisma } from "@prisma/client";
|
import { Prisma } from "@prisma/client";
|
||||||
import {
|
import {
|
||||||
AppConfigSlug,
|
AppConfigSlug,
|
||||||
RiskState,
|
|
||||||
RolePerms,
|
RolePerms,
|
||||||
TaxonomySlug,
|
TaxonomySlug,
|
||||||
TroubleParamsKey,
|
|
||||||
TroubleState,
|
|
||||||
TroubleType,
|
|
||||||
VisitType,
|
|
||||||
} from "./enum";
|
} from "./enum";
|
||||||
|
|
||||||
export const InitRoles: {
|
export const InitRoles: {
|
||||||
|
@ -15,50 +12,50 @@ export const InitRoles: {
|
||||||
permissions: string[];
|
permissions: string[];
|
||||||
system?: boolean;
|
system?: boolean;
|
||||||
}[] = [
|
}[] = [
|
||||||
{
|
{
|
||||||
name: "基层",
|
name: "基层",
|
||||||
permissions: [
|
permissions: [
|
||||||
RolePerms.CREATE_TROUBLE,
|
RolePerms.CREATE_TROUBLE,
|
||||||
RolePerms.CREATE_WORKPROGRESS,
|
RolePerms.CREATE_WORKPROGRESS,
|
||||||
RolePerms.READ_DOM_TERM,
|
RolePerms.READ_DOM_TERM,
|
||||||
RolePerms.READ_AUDIT_TROUBLE,
|
RolePerms.READ_AUDIT_TROUBLE,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "机关",
|
name: "机关",
|
||||||
permissions: [
|
permissions: [
|
||||||
RolePerms.CREATE_TROUBLE,
|
RolePerms.CREATE_TROUBLE,
|
||||||
RolePerms.CREATE_WORKPROGRESS,
|
RolePerms.CREATE_WORKPROGRESS,
|
||||||
RolePerms.CREATE_ALERT,
|
RolePerms.CREATE_ALERT,
|
||||||
RolePerms.READ_DOM_TERM,
|
RolePerms.READ_DOM_TERM,
|
||||||
RolePerms.MANAGE_DOM_TROUBLE,
|
RolePerms.MANAGE_DOM_TROUBLE,
|
||||||
RolePerms.READ_AUDIT_TROUBLE,
|
RolePerms.READ_AUDIT_TROUBLE,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "领导",
|
name: "领导",
|
||||||
permissions: [
|
permissions: [
|
||||||
RolePerms.READ_DOM_TERM,
|
RolePerms.READ_DOM_TERM,
|
||||||
RolePerms.READ_DOM_TROUBLE,
|
RolePerms.READ_DOM_TROUBLE,
|
||||||
RolePerms.CREATE_INSTRUCTION,
|
RolePerms.CREATE_INSTRUCTION,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "域管理员",
|
name: "域管理员",
|
||||||
permissions: Object.keys(RolePerms).filter(
|
permissions: Object.keys(RolePerms).filter(
|
||||||
(perm) =>
|
(perm) =>
|
||||||
![
|
![
|
||||||
RolePerms.READ_ANY_CHART,
|
RolePerms.READ_ANY_CHART,
|
||||||
RolePerms.READ_ANY_TROUBLE,
|
RolePerms.READ_ANY_TROUBLE,
|
||||||
RolePerms.READ_ANY_TERM,
|
RolePerms.READ_ANY_TERM,
|
||||||
].includes(perm as any)
|
].includes(perm as any)
|
||||||
) as RolePerms[],
|
) as RolePerms[],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "根管理员",
|
name: "根管理员",
|
||||||
permissions: Object.keys(RolePerms) as RolePerms[],
|
permissions: Object.keys(RolePerms) as RolePerms[],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
export const InitTaxonomies: { name: string; slug: string }[] = [
|
export const InitTaxonomies: { name: string; slug: string }[] = [
|
||||||
{
|
{
|
||||||
name: "分类",
|
name: "分类",
|
||||||
|
|
|
@ -2,8 +2,6 @@ export enum SocketMsgType {
|
||||||
NOTIFY,
|
NOTIFY,
|
||||||
}
|
}
|
||||||
export enum PostType {
|
export enum PostType {
|
||||||
TROUBLE_PROGRESS = "trouble_progress",
|
|
||||||
TROUBLE_INSTRUCTION = "trouble_instrcution",
|
|
||||||
POST = "post",
|
POST = "post",
|
||||||
POST_COMMENT = "post_comment",
|
POST_COMMENT = "post_comment",
|
||||||
}
|
}
|
||||||
|
@ -16,44 +14,13 @@ export enum VisitType {
|
||||||
STAR = "star",
|
STAR = "star",
|
||||||
READED = "read",
|
READED = "read",
|
||||||
}
|
}
|
||||||
export enum TroubleState {
|
|
||||||
AUDITING = 0,
|
|
||||||
PROCESSING = 1,
|
|
||||||
CANCEL_REQUEST = 2,
|
|
||||||
CANCELED = 3,
|
|
||||||
}
|
|
||||||
export enum RiskState {
|
|
||||||
AUDITING = 0,
|
|
||||||
CONTROLLING = 4,
|
|
||||||
RELEASED = 5,
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum QuadrantType {
|
|
||||||
URG_IMPORTANT = "super",
|
|
||||||
URGENT = "urgent",
|
|
||||||
IMPORTANT = "imporant",
|
|
||||||
TRIVIAL = "trival",
|
|
||||||
}
|
|
||||||
export enum TroubleType {
|
|
||||||
RISK = "安全风险",
|
|
||||||
TROUBLE = "问题隐患",
|
|
||||||
ALERT = "风险预警",
|
|
||||||
}
|
|
||||||
export enum AssessmentStatus {
|
|
||||||
ASSESSING = "评估中",
|
|
||||||
COMPLETED = "已完成",
|
|
||||||
}
|
|
||||||
export enum TermType {
|
|
||||||
RISK_UNIT = "RISK_UNIT",
|
|
||||||
RISK_INDICATOR = "RISK_INDICATOR",
|
|
||||||
RISK_CATEGORY = "RISK_CATEGORY",
|
|
||||||
}
|
|
||||||
export enum ObjectType {
|
export enum ObjectType {
|
||||||
DEPARTMENT = "department",
|
DEPARTMENT = "department",
|
||||||
STAFF = "staff",
|
STAFF = "staff",
|
||||||
COMMENT = "comment",
|
COMMENT = "comment",
|
||||||
TERM = "term",
|
TERM = "term",
|
||||||
TROUBLE = "trouble",
|
|
||||||
APP_CONFIG = "app_config",
|
APP_CONFIG = "app_config",
|
||||||
ROLE = "role",
|
ROLE = "role",
|
||||||
ROLE_MAP = "rolemap",
|
ROLE_MAP = "rolemap",
|
||||||
|
@ -100,112 +67,60 @@ export enum RolePerms {
|
||||||
MANAGE_ANY_ROLE = "MANAGE_ANY_ROLE",
|
MANAGE_ANY_ROLE = "MANAGE_ANY_ROLE",
|
||||||
MANAGE_DOM_ROLE = "MANAGE_DOM_ROLE",
|
MANAGE_DOM_ROLE = "MANAGE_DOM_ROLE",
|
||||||
}
|
}
|
||||||
export enum RemindType {
|
|
||||||
BOTH = "both",
|
|
||||||
CHECK = "check",
|
|
||||||
DUTY = "duty",
|
|
||||||
}
|
|
||||||
|
|
||||||
export const LevelColor = {
|
|
||||||
1: "#BBDDFF",
|
|
||||||
2: "#FFE6B3",
|
|
||||||
3: "#FFC2C2",
|
|
||||||
4: "#FFC2C2",
|
|
||||||
} as const;
|
|
||||||
|
|
||||||
export enum AppConfigSlug {
|
export enum AppConfigSlug {
|
||||||
BASE_SETTING = "base_setting",
|
BASE_SETTING = "base_setting",
|
||||||
}
|
}
|
||||||
export const TroubleStateMap = {
|
// 资源类型的枚举,定义了不同类型的资源,以字符串值表示
|
||||||
[TroubleState.AUDITING]: "待审核",
|
export enum ResourceType {
|
||||||
[TroubleState.PROCESSING]: "处理中",
|
VIDEO = "video", // 视频资源
|
||||||
[TroubleState.CANCEL_REQUEST]: "待销帐",
|
PDF = "pdf", // PDF文档
|
||||||
[TroubleState.CANCELED]: "已销帐",
|
DOC = "doc", // Word文档
|
||||||
};
|
EXCEL = "excel", // Excel表格
|
||||||
export const RiskStateMap = {
|
PPT = "ppt", // PowerPoint演示文稿
|
||||||
[RiskState.AUDITING]: "待审核",
|
CODE = "code", // 代码文件
|
||||||
[RiskState.CONTROLLING]: "管控中",
|
LINK = "link", // 超链接
|
||||||
[RiskState.RELEASED]: "已解除",
|
IMAGE = "image", // 图片资源
|
||||||
};
|
AUDIO = "audio", // 音频资源
|
||||||
export const TroubleTypeStateMap = new Map<string, string>([
|
ZIP = "zip", // 压缩包文件
|
||||||
[`${TroubleType.TROUBLE}_${TroubleState.AUDITING}`, "待审核"],
|
OTHER = "other" // 其他未分类资源
|
||||||
[`${TroubleType.TROUBLE}_${TroubleState.PROCESSING}`, `处理中`],
|
|
||||||
[`${TroubleType.TROUBLE}_${TroubleState.CANCEL_REQUEST}`, `待销帐`],
|
|
||||||
[`${TroubleType.TROUBLE}_${TroubleState.CANCELED}`, `已销帐`],
|
|
||||||
|
|
||||||
[`${TroubleType.RISK}_${RiskState.AUDITING}`, "待审核"],
|
|
||||||
[`${TroubleType.RISK}_${RiskState.CONTROLLING}`, `管控中`],
|
|
||||||
[`${TroubleType.RISK}_${RiskState.RELEASED}`, `已解除`],
|
|
||||||
|
|
||||||
[`${TroubleType.ALERT}_${RiskState.AUDITING}`, "待审核"],
|
|
||||||
[`${TroubleType.ALERT}_${RiskState.CONTROLLING}`, `管控中`],
|
|
||||||
[`${TroubleType.ALERT}_${RiskState.RELEASED}`, `已解除`],
|
|
||||||
]);
|
|
||||||
export const TroubleLevelMap = new Map<string, string>([
|
|
||||||
[`${TroubleType.TROUBLE}_0`, "全部级别"],
|
|
||||||
[`${TroubleType.TROUBLE}_1`, `四级隐患`],
|
|
||||||
[`${TroubleType.TROUBLE}_2`, `三级隐患`],
|
|
||||||
[`${TroubleType.TROUBLE}_3`, `二级隐患`],
|
|
||||||
[`${TroubleType.TROUBLE}_4`, `一级隐患`],
|
|
||||||
|
|
||||||
[`${TroubleType.RISK}_0`, "全部级别"],
|
|
||||||
[`${TroubleType.RISK}_1`, `一般风险`],
|
|
||||||
[`${TroubleType.RISK}_2`, `较大风险`],
|
|
||||||
[`${TroubleType.RISK}_3`, `重大风险`],
|
|
||||||
[`${TroubleType.RISK}_4`, `特大风险`],
|
|
||||||
|
|
||||||
[`${TroubleType.ALERT}_0`, "全部预警"],
|
|
||||||
[`${TroubleType.ALERT}_1`, `蓝色预警`],
|
|
||||||
[`${TroubleType.ALERT}_2`, `黄色预警`],
|
|
||||||
[`${TroubleType.ALERT}_3`, `橙色预警`],
|
|
||||||
[`${TroubleType.ALERT}_4`, `红色预警`],
|
|
||||||
]);
|
|
||||||
export function GetTroubleLevel(
|
|
||||||
type: string | undefined,
|
|
||||||
level: number | undefined
|
|
||||||
): string | undefined {
|
|
||||||
return TroubleLevelMap.get(`${type || "ELSE"}_${level}`) || "暂未评级";
|
|
||||||
}
|
|
||||||
export function GetTroubleState(
|
|
||||||
type: string | undefined,
|
|
||||||
state: number | undefined
|
|
||||||
): string | undefined {
|
|
||||||
return TroubleTypeStateMap.get(`${type || "ELSE"}_${state}`) || "无状态";
|
|
||||||
}
|
|
||||||
export enum SendMessageType {
|
|
||||||
TO_DUTY = "to_duty",
|
|
||||||
TO_CHECK = "to_check",
|
|
||||||
TO_REQUEST_DELAY = "to_request_delay",
|
|
||||||
TO_DELAY = "to_delay",
|
|
||||||
TO_REQUEST_CANCEL = "to_request_cancel",
|
|
||||||
INSTRUCTION = "instrcution",
|
|
||||||
PROGRESS = "progress",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum DraftType {
|
// 课程等级的枚举,描述了不同学习水平的课程
|
||||||
TROUBLE = "trouble_darft",
|
export enum CourseLevel {
|
||||||
POST = "post_darft",
|
BEGINNER = "beginner", // 初级课程,适合初学者
|
||||||
|
INTERMEDIATE = "intermediate", // 中级课程,适合有一定基础的学习者
|
||||||
|
ADVANCED = "advanced", // 高级课程,适合高级水平学习者
|
||||||
|
ALL_LEVELS = "all_levels" // 适用于所有学习水平的课程
|
||||||
}
|
}
|
||||||
export enum ForwardType {
|
|
||||||
TROUBLE = "trouble",
|
// 课时(课程内容)类型的枚举,定义了课程中可能包含的不同内容形式
|
||||||
POST = "post",
|
export enum LessonType {
|
||||||
|
VIDEO = "video", // 视频课程
|
||||||
|
ARTICLE = "article", // 文章型课程内容
|
||||||
|
QUIZ = "quiz", // 测验类型
|
||||||
|
ASSIGNMENT = "assignment", // 作业类型
|
||||||
}
|
}
|
||||||
export enum ToWhoType {
|
|
||||||
DOMAIN = "本域可见",
|
// 课程状态的枚举,定义了课程生命周期中的各个状态
|
||||||
DEPT = "本单位可见",
|
export enum CourseStatus {
|
||||||
SELF = "仅自己可见",
|
DRAFT = "draft", // 草稿状态的课程,尚未发布
|
||||||
CUSTOM = "自定义",
|
UNDER_REVIEW = "under_review", // 正在审核中的课程
|
||||||
|
PUBLISHED = "published", // 已发布的课程,可以被学员报名学习
|
||||||
|
ARCHIVED = "archived" // 已归档的课程,不再对外展示
|
||||||
}
|
}
|
||||||
// 定义枚举来存储查询键
|
|
||||||
export enum TroubleParamsKey {
|
// 报名状态的枚举,描述了用户报名参加课程的不同状态
|
||||||
RISK_AUDITING = "RISK_AUDITING",
|
export enum EnrollmentStatus {
|
||||||
RISK_CONTROLLING = "RISK_CONTROLLING",
|
PENDING = "pending", // 报名待处理状态
|
||||||
RISK_RELEASED = "RISK_RELEASED",
|
ACTIVE = "active", // 活跃状态,用户可参与课程
|
||||||
TROUBLE_AUDITING = "TROUBLE_AUDITING",
|
COMPLETED = "completed", // 完成状态,用户已完成课程
|
||||||
TROUBLE_PROCESSING = "TROUBLE_PROCESSING",
|
CANCELLED = "cancelled", // 已取消的报名
|
||||||
TROUBLE_CANCEL_REQUEST = "TROUBLE_CANCEL_REQUEST",
|
REFUNDED = "refunded" // 已退款的报名
|
||||||
TROUBLE_CANCELED = "TROUBLE_CANCELED",
|
|
||||||
STAR = "STAR",
|
|
||||||
DUTY = "DUTY",
|
|
||||||
CHECK = "CHECK",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 授课角色的枚举,定义了讲师在课程中的角色分配
|
||||||
|
export enum InstructorRole {
|
||||||
|
MAIN = "main", // 主讲教师
|
||||||
|
ASSISTANT = "assistant" // 助教
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import { z } from "zod";
|
import { z } from "zod";
|
||||||
import { ObjectType, RiskState, TroubleState } from "./enum";
|
import { ObjectType } from "./enum";
|
||||||
export const AuthSchema = {
|
export const AuthSchema = {
|
||||||
signUpRequest: z.object({
|
signUpRequest: z.object({
|
||||||
username: z.string(),
|
username: z.string(),
|
||||||
|
@ -170,10 +170,7 @@ export const DepartmentMethodSchema = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TransformMethodSchema = {
|
export const TransformMethodSchema = {
|
||||||
importTrouble: z.object({
|
|
||||||
base64: z.string(),
|
|
||||||
domainId: z.string().nullish(),
|
|
||||||
}),
|
|
||||||
importStaffs: z.object({
|
importStaffs: z.object({
|
||||||
base64: z.string(),
|
base64: z.string(),
|
||||||
domainId: z.string().nullish(),
|
domainId: z.string().nullish(),
|
||||||
|
@ -189,21 +186,7 @@ export const TransformMethodSchema = {
|
||||||
domainId: z.string().nullish(),
|
domainId: z.string().nullish(),
|
||||||
parentId: z.string().nullish(),
|
parentId: z.string().nullish(),
|
||||||
}),
|
}),
|
||||||
exportTroubles: z.object({
|
|
||||||
termIdFilters: z.map(z.string(), z.array(z.string())).nullish(),
|
|
||||||
deptIds: z.array(z.string()).nullish(),
|
|
||||||
search: z.string().nullish(),
|
|
||||||
type: z.string().nullish(),
|
|
||||||
levels: z.array(z.number()).nullish(),
|
|
||||||
createStartDate: z.string().nullish(),
|
|
||||||
createEndDate: z.string().nullish(),
|
|
||||||
domainId: z.string().nullish(),
|
|
||||||
states: z
|
|
||||||
.array(
|
|
||||||
z.union([z.nativeEnum(TroubleState), z.nativeEnum(RiskState)])
|
|
||||||
)
|
|
||||||
.nullish(),
|
|
||||||
}),
|
|
||||||
};
|
};
|
||||||
export const TermMethodSchema = {
|
export const TermMethodSchema = {
|
||||||
getRows: RowRequestSchema.extend({
|
getRows: RowRequestSchema.extend({
|
||||||
|
|
|
@ -7,8 +7,8 @@ export const postDetailSelect: Prisma.PostSelect = {
|
||||||
content: true,
|
content: true,
|
||||||
attachments: true,
|
attachments: true,
|
||||||
referenceId: true,
|
referenceId: true,
|
||||||
watchDepts: true,
|
watchableDepts: true,
|
||||||
watchStaffs: true,
|
watchableStaffs: true,
|
||||||
updatedAt: true,
|
updatedAt: true,
|
||||||
author: {
|
author: {
|
||||||
select: {
|
select: {
|
||||||
|
|
|
@ -137,8 +137,8 @@ export type PostDto = Post & {
|
||||||
delete: boolean;
|
delete: boolean;
|
||||||
// edit: boolean;
|
// edit: boolean;
|
||||||
};
|
};
|
||||||
watchDepts: Department[];
|
watchableDepts: Department[];
|
||||||
watchStaffs: Staff[];
|
watchableStaffs: Staff[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TermDto = Term & {
|
export type TermDto = Term & {
|
||||||
|
|
Loading…
Reference in New Issue