This commit is contained in:
Rao 2025-03-11 16:15:05 +08:00
parent c91cfa81bc
commit ae17534dfb
19 changed files with 436 additions and 159 deletions

View File

@ -0,0 +1,9 @@
import { Controller, UseGuards } from "@nestjs/common";
import { TrainContentService } from "./trainContent.service";
import { AuthGuard } from '@server/auth/auth.guard';
@Controller('train-content')
export class TrainContentController {
constructor(private readonly trainContentService: TrainContentService) {}
//@UseGuards(AuthGuard)
}

View File

@ -0,0 +1,15 @@
import { Module } from '@nestjs/common';
import { TrainContentService } from './trainContent.service';
import { StaffModule } from '../staff/staff.module';
import { TrainContentController } from './trainContent.controller';
import { TrainContentRouter } from './trainContent.router';
import { TrpcService } from '@server/trpc/trpc.service';
@Module({
imports: [StaffModule],
controllers: [TrainContentController],
providers: [TrainContentService,TrainContentRouter,TrpcService],
exports: [TrainContentService,TrainContentRouter],
})
export class TrainContentModule {}

View File

@ -0,0 +1,16 @@
import { Injectable } from "@nestjs/common";
import { TrpcService } from "@server/trpc/trpc.service";
import { TrainContentService } from "./trainContent.service";
@Injectable()
export class TrainContentRouter {
constructor(
private readonly trpc: TrpcService,
private readonly trainContentService: TrainContentService,
) { }
router = this.trpc.router({
})
}

View File

@ -0,0 +1,12 @@
import { Injectable } from "@nestjs/common";
import { BaseService } from "../base/base.service";
import { db, ObjectType, Prisma, UserProfile } from "@nice/common";
@Injectable()
export class TrainContentService extends BaseService<Prisma.TrainContentDelegate> {
constructor() {
super(db,ObjectType.TRAIN_CONTENT,true);
}
}

View File

@ -0,0 +1,9 @@
import { Controller, UseGuards } from "@nestjs/common";
import { TrainSituationService } from "./trainSituation.service";
import { AuthGuard } from '@server/auth/auth.guard';
@Controller('train-situation')
export class TrainSituationController {
constructor(private readonly trainContentService: TrainSituationService) {}
//@UseGuards(AuthGuard)
}

View File

@ -0,0 +1,15 @@
import { Module } from '@nestjs/common';
import { TrainSituationService } from './trainSituation.service';
import { StaffModule } from '../staff/staff.module';
import { TrainSituationController } from './trainSituation.controller';
import { TrainSituationRouter } from './trainSituation.router';
import { TrpcService } from '@server/trpc/trpc.service';
@Module({
imports: [StaffModule],
controllers: [TrainSituationController],
providers: [TrainSituationService,TrainSituationRouter,TrpcService],
exports: [TrainSituationService,TrainSituationRouter],
})
export class TrainSituationModule {}

View File

@ -0,0 +1,25 @@
import { Injectable } from "@nestjs/common";
import { TrpcService } from "@server/trpc/trpc.service";
import { TrainSituationService } from "./trainSituation.service";
import { z, ZodType } from "zod";
import { Prisma } from "@nice/common";
const TrainSituationArgsSchema:ZodType<Prisma.TrainSituationCreateArgs> = z.any()
@Injectable()
export class TrainSituationRouter {
constructor(
private readonly trpc: TrpcService,
private readonly trainSituationService: TrainSituationService,
) { }
router = this.trpc.router({
create:this.trpc.protectProcedure
.input(TrainSituationArgsSchema)
.mutation(async ({ input }) => {
this.trainSituationService.create(input)
}),
})
}

View File

@ -0,0 +1,28 @@
import { Injectable } from "@nestjs/common";
import { BaseService } from "../base/base.service";
import { db, ObjectType, Prisma, UserProfile } from "@nice/common";
import EventBus, { CrudOperation } from "@server/utils/event-bus";
@Injectable()
export class TrainSituationService extends BaseService<Prisma.TrainSituationDelegate> {
constructor() {
super(db,ObjectType.TRAIN_SITUATION,false);
}
async create(
args: Prisma.TrainSituationCreateArgs,
){
console.log(args)
const result = await super.create(args);
this.emitDataChanged(CrudOperation.CREATED, result);
return result;
}
private emitDataChanged(operation: CrudOperation, data: any) {
EventBus.emit('dataChanged', {
type:ObjectType.TRAIN_SITUATION,
operation,
data,
});
}
}

View File

@ -11,11 +11,14 @@ import {
Staff,
TaxonomySlug,
Term,
TrainContent,
} from '@nice/common';
import EventBus from '@server/utils/event-bus';
import { capitalizeFirstLetter, DevDataCounts, getCounts } from './utils';
import { StaffService } from '@server/models/staff/staff.service';
import dayjs from 'dayjs';
import { TrainContentType } from '@nice/common';
@Injectable()
export class GenDevService {
private readonly logger = new Logger(GenDevService.name);
@ -30,8 +33,10 @@ export class GenDevService {
domains: Department[] = [];
domainDepts: Record<string, Department[]> = {};
staffs: Staff[] = [];
trainContents: TrainContent[] = [];
deptGeneratedCount = 0;
courseGeneratedCount = 1;
trainContentGeneratedCount = 0;
constructor(
private readonly appConfigService: AppConfigService,
@ -47,6 +52,7 @@ export class GenDevService {
await this.generateTerms(2, 6);
await this.generateStaffs(4);
await this.generateCourses(8);
await this.generateTrainContent(2,6)
} catch (err) {
this.logger.error(err);
}
@ -338,4 +344,64 @@ export class GenDevService {
await createTermTree(null, 1);
}
private async createTrainContent(
type:string,
title:string,
parentId:string|null
){
const trainContent = await db.trainContent.create({
data: {
type,
title,
parentId
},
});
return trainContent;
}
private async generateTrainContent(depth:number=3,count:number=6){
if(this.counts.trainContentCount !== 0) return;
const totalTrainContent = this.calculateTotalTrainContent(depth,count)
this.logger.log("Start generating train content...")
await this.generateSubTrainContent(null,1,depth,count,totalTrainContent)
this.trainContents = await db.trainContent.findMany()
this.logger.log(`Completed: Generated ${this.trainContents.length} departments.`);
}
private async generateSubTrainContent(
parentId: string | null,
currentDepth:number,
maxDepth:number,
count:number,
total:number,
){
if(currentDepth > maxDepth) return;
const contentType = [TrainContentType.SUBJECTS,TrainContentType.COURSE]
for(let i = 0 ; i < count ; i++){
const trainContentTitle = `${parentId?.slice(0,6) || '根'}公司${currentDepth}-${i}`
const newTrainContent = await this.createTrainContent(
contentType[currentDepth-1],
trainContentTitle,
parentId
)
this.trainContentGeneratedCount++;
this.logger.log(
`Generated ${this.trainContentGeneratedCount}/${total} train contents`
)
await this.generateSubTrainContent(
newTrainContent.id,
currentDepth+1,
maxDepth,
count,
total
)
}
}
private calculateTotalTrainContent(depth:number,count:number):number{
let total = 0;
for(let i = 1 ; i<=depth;i++){
total += Math.pow(count,i);
}
return total;
}
}

View File

@ -8,7 +8,7 @@ import {
import dayjs from 'dayjs';
export interface DevDataCounts {
deptCount: number;
trainContentCount: number;
staffCount: number;
termCount: number;
courseCount: number;
@ -16,7 +16,7 @@ export interface DevDataCounts {
export async function getCounts(): Promise<DevDataCounts> {
const counts = {
deptCount: await db.department.count(),
trainContentCount:await db.trainContent.count(),
staffCount: await db.staff.count(),
termCount: await db.term.count(),
courseCount: await db.post.count({

View File

@ -14,8 +14,9 @@ import { VisitModule } from '@server/models/visit/visit.module';
import { WebSocketModule } from '@server/socket/websocket.module';
import { RoleMapModule } from '@server/models/rbac/rbac.module';
import { TransformModule } from '@server/models/transform/transform.module';
import { TrainContentModule } from '@server/models/train-content/trainContent.module';
import { ResourceModule } from '@server/models/resource/resource.module';
import { TrainSituationModule } from '@server/models/train-situation/trainSituation.module';
@Module({
imports: [
@ -33,6 +34,8 @@ import { ResourceModule } from '@server/models/resource/resource.module';
VisitModule,
WebSocketModule,
ResourceModule,
TrainContentModule,
TrainSituationModule
],
controllers: [],
providers: [TrpcService, TrpcRouter, Logger],

View File

@ -14,6 +14,8 @@ import { RoleMapRouter } from '@server/models/rbac/rolemap.router';
import { TransformRouter } from '@server/models/transform/transform.router';
import { RoleRouter } from '@server/models/rbac/role.router';
import { ResourceRouter } from '../models/resource/resource.router';
import { TrainContentRouter } from '@server/models/train-content/trainContent.router';
import { TrainSituationRouter } from '@server/models/train-situation/trainSituation.router';
@Injectable()
export class TrpcRouter {
@ -32,6 +34,8 @@ export class TrpcRouter {
private readonly message: MessageRouter,
private readonly visitor: VisitRouter,
private readonly resource: ResourceRouter,
private readonly trainContent: TrainContentRouter,
private readonly trainSituation:TrainSituationRouter,
) {}
getRouter() {
return;
@ -49,6 +53,8 @@ export class TrpcRouter {
app_config: this.app_config.router,
visitor: this.visitor.router,
resource: this.resource.router,
trainContent:this.trainContent.router,
trainSituation:this.trainSituation.router
});
wss: WebSocketServer = undefined;

View File

@ -1,11 +1,12 @@
import React, { useState, useCallback, useEffect, useMemo } from "react";
import { Typography, Skeleton } from "antd";
import { stringToColor, TaxonomySlug, TermDto } from "@nice/common";
import { api } from "@nice/client";
import { api, useTrainSituation } from "@nice/client";
import LookForMore from "./LookForMore";
import CategorySectionCard from "./CategorySectionCard";
import { useNavigate } from "react-router-dom";
import { useMainContext } from "../../layout/MainProvider";
import { useAuth } from "@web/src/providers/auth-provider";
const { Title, Text } = Typography;
const CategorySection = () => {
@ -41,6 +42,26 @@ const CategorySection = () => {
navigate("/courses");
window.scrollTo({ top: 0, behavior: "smooth" });
}, []);
const {user} = useAuth()
const {create} = useTrainSituation()
useEffect(() => {
if (user?.id) {
create.mutate({
data: {
//staffId: user.id, // 确保类型匹配
mustTrainTime: "1",
alreadyTrainTime: "1",
//trainContentId: "cm83w52dr00ff3jc8ep4uf4a4",
staff: { connect: { id: user.id } },
trainContent: { connect: { id: "cm847lcc805ne123v81l5h13e" } }
}
});
console.log("create score time")
}
}, []);
return (
<section className="py-8 relative overflow-hidden">
<div className="max-w-screen-2xl mx-auto px-4 relative">

View File

@ -15,7 +15,7 @@ import {
EyeOutlined,
} from "@ant-design/icons";
import type { CarouselRef } from "antd/es/carousel";
import { useAppConfig } from "@nice/client";
import { api, useAppConfig } from "@nice/client";
import { useNavigate } from "react-router-dom";
interface PlatformStat {
@ -70,6 +70,13 @@ const HeroSection = () => {
console.log(count);
setCountStatistics(count);
}, [statistics]);
return (
<section className="relative ">
<div className="group">

View File

@ -2,7 +2,7 @@ server {
# 监听80端口
listen 80;
# 服务器域名/IP地址使用环境变量
server_name host.docker.internal;
server_name 192.168.43.206;
# 基础性能优化配置
# 启用tcp_nopush以优化数据发送
@ -100,7 +100,7 @@ server {
# 仅供内部使用
internal;
# 代理到认证服务
proxy_pass http://host.docker.internal:3006/auth/file;
proxy_pass http://192.168.43.206:3001/auth/file;
# 请求优化:不传递请求体
proxy_pass_request_body off;

View File

@ -10,3 +10,4 @@ export * from "./useVisitor"
export * from "./useMessage"
export * from "./usePost"
export * from "./useEntity"
export * from "./useTrainSituation"

View File

@ -0,0 +1,23 @@
import { getQueryKey } from "@trpc/react-query";
import { api } from "../trpc"; // Adjust path as necessary
import { useQueryClient } from "@tanstack/react-query";
import { ObjectType, Staff } from "@nice/common";
import { findQueryData } from "../utils";
import { CrudOperation, emitDataChange } from "../../event";
export function useTrainSituation(){
const queryClient = useQueryClient();
const queryKey = getQueryKey(api.trainSituation);
const create = api.trainSituation.create.useMutation({
onSuccess: (res:any) => {
queryClient.invalidateQueries({ queryKey });
emitDataChange(ObjectType.TRAIN_SITUATION, res, CrudOperation.CREATED);
},
});
return {
create
}
}

View File

@ -67,80 +67,9 @@ model TermAncestry {
@@map("term_ancestry")
}
model Staff {
id String @id @default(cuid())
showname String? @map("showname")
username String @unique @map("username")
avatar String? @map("avatar")
password String? @map("password")
phoneNumber String? @unique @map("phone_number")
age Int? @map("age")
sex Boolean? @map("sex")
absent Boolean? @map("absent")
domainId String? @map("domain_id")
deptId String? @map("dept_id")
domain Department? @relation("DomainStaff", fields: [domainId], references: [id])
department Department? @relation("DeptStaff", fields: [deptId], references: [id])
order Float?
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
enabled Boolean? @default(true)
deletedAt DateTime? @map("deleted_at")
officerId String? @map("officer_id")
// watchedPost Post[] @relation("post_watch_staff")
visits Visit[]
posts Post[]
learningPosts Post[] @relation("post_student")
sentMsgs Message[] @relation("message_sender")
receivedMsgs Message[] @relation("message_receiver")
registerToken String?
enrollments Enrollment[]
teachedPosts PostInstructor[]
ownedResources Resource[]
traincontent TrainContent[] @relation("StaffTrainContent")
@@index([officerId])
@@index([deptId])
@@index([domainId])
@@index([username])
@@index([order])
@@map("staff")
}
model Department {
id String @id @default(cuid())
name String
order Float?
posts Post[] @relation("post_dept")
ancestors DeptAncestry[] @relation("DescendantToAncestor")
descendants DeptAncestry[] @relation("AncestorToDescendant")
parentId String? @map("parent_id")
parent Department? @relation("ChildParent", fields: [parentId], references: [id])
children Department[] @relation("ChildParent")
domainId String? @map("domain_id")
domainTerms Term[] @relation("TermDom")
deletedAt DateTime? @map("deleted_at")
isDomain Boolean? @default(false) @map("is_domain")
domainStaffs Staff[] @relation("DomainStaff")
deptStaffs Staff[] @relation("DeptStaff")
terms Term[] @relation("department_term")
// watchedPost Post[] @relation("post_watch_dept")
hasChildren Boolean? @default(false) @map("has_children")
@@index([parentId])
@@index([isDomain])
@@index([name])
@@index([order])
@@map("department")
}
model DeptAncestry {
id String @id @default(cuid())
@ -196,45 +125,45 @@ model AppConfig {
model Post {
// 字符串类型字段
id String @id @default(cuid()) // 帖子唯一标识,使用 cuid() 生成默认值
type String? // Post类型课程、章节、小节、讨论都用Post实现
level String?
state String?
title String? // 帖子标题,可为空
subTitle String?
content String? // 帖子内容,可为空
important Boolean? //是否重要/精选/突出
domainId String? @map("domain_id")
terms Term[] @relation("post_term")
order Float? @default(0) @map("order")
duration Int?
rating Int? @default(0)
students Staff[] @relation("post_student")
depts Department[] @relation("post_dept")
views Int @default(0) @map("views")
hates Int @default(0) @map("hates")
likes Int @default(0) @map("likes")
id String @id @default(cuid()) // 帖子唯一标识,使用 cuid() 生成默认值
type String? // Post类型课程、章节、小节、讨论都用Post实现
level String?
state String?
title String? // 帖子标题,可为空
subTitle String?
content String? // 帖子内容,可为空
important Boolean? //是否重要/精选/突出
domainId String? @map("domain_id")
terms Term[] @relation("post_term")
order Float? @default(0) @map("order")
duration Int?
rating Int? @default(0)
students Staff[] @relation("post_student")
depts Department[] @relation("post_dept")
views Int @default(0) @map("views")
hates Int @default(0) @map("hates")
likes Int @default(0) @map("likes")
// 索引
// 日期时间类型字段
createdAt DateTime @default(now()) @map("created_at")
publishedAt DateTime? @map("published_at") // 发布时间
updatedAt DateTime @map("updated_at")
deletedAt DateTime? @map("deleted_at") // 删除时间,可为空
instructors PostInstructor[]
createdAt DateTime @default(now()) @map("created_at")
publishedAt DateTime? @map("published_at") // 发布时间
updatedAt DateTime @map("updated_at")
deletedAt DateTime? @map("deleted_at") // 删除时间,可为空
instructors PostInstructor[]
// 关系类型字段
authorId String? @map("author_id")
author Staff? @relation(fields: [authorId], references: [id]) // 帖子作者,关联 Staff 模型
enrollments Enrollment[] // 学生报名记录
visits Visit[] // 访问记录,关联 Visit 模型
parentId String? @map("parent_id")
parent Post? @relation("PostChildren", fields: [parentId], references: [id]) // 父级帖子,关联 Post 模型
children Post[] @relation("PostChildren") // 子级帖子列表,关联 Post 模型
hasChildren Boolean? @default(false) @map("has_children")
authorId String? @map("author_id")
author Staff? @relation(fields: [authorId], references: [id]) // 帖子作者,关联 Staff 模型
enrollments Enrollment[] // 学生报名记录
visits Visit[] // 访问记录,关联 Visit 模型
parentId String? @map("parent_id")
parent Post? @relation("PostChildren", fields: [parentId], references: [id]) // 父级帖子,关联 Post 模型
children Post[] @relation("PostChildren") // 子级帖子列表,关联 Post 模型
hasChildren Boolean? @default(false) @map("has_children")
// 闭包表关系
ancestors PostAncestry[] @relation("DescendantPosts")
descendants PostAncestry[] @relation("AncestorPosts")
resources Resource[] // 附件列表
meta Json? // 封面url 视频url objectives具体的学习目标 rating评分Int
ancestors PostAncestry[] @relation("DescendantPosts")
descendants PostAncestry[] @relation("AncestorPosts")
resources Resource[] // 附件列表
meta Json? // 封面url 视频url objectives具体的学习目标 rating评分Int
// 索引
@@index([type, domainId])
@ -252,12 +181,13 @@ model Post {
}
model PostAncestry {
id String @id @default(cuid())
ancestorId String? @map("ancestor_id")
descendantId String @map("descendant_id")
relDepth Int @map("rel_depth")
ancestor Post? @relation("AncestorPosts", fields: [ancestorId], references: [id])
descendant Post @relation("DescendantPosts", fields: [descendantId], references: [id])
id String @id @default(cuid())
ancestorId String? @map("ancestor_id")
descendantId String @map("descendant_id")
relDepth Int @map("rel_depth")
ancestor Post? @relation("AncestorPosts", fields: [ancestorId], references: [id])
descendant Post @relation("DescendantPosts", fields: [descendantId], references: [id])
// 复合索引优化
// 索引建议
@@index([ancestorId]) // 针对祖先的查询
@ -281,23 +211,24 @@ model Message {
visits Visit[]
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime? @updatedAt @map("updated_at")
@@index([type, createdAt])
@@map("message")
}
model Visit {
id String @id @default(cuid()) @map("id")
id String @id @default(cuid()) @map("id")
type String?
views Int @default(1) @map("views")
views Int @default(1) @map("views")
// sourceIP String? @map("source_ip")
// 关联关系
visitorId String? @map("visitor_id")
visitor Staff? @relation(fields: [visitorId], references: [id])
postId String? @map("post_id")
post Post? @relation(fields: [postId], references: [id])
message Message? @relation(fields: [messageId], references: [id])
messageId String? @map("message_id")
lectureId String? @map("lecture_id") // 课时ID
postId String? @map("post_id")
post Post? @relation(fields: [postId], references: [id])
message Message? @relation(fields: [messageId], references: [id])
messageId String? @map("message_id")
lectureId String? @map("lecture_id") // 课时ID
createdAt DateTime @default(now()) @map("created_at") // 创建时间
updatedAt DateTime @updatedAt @map("updated_at") // 更新时间
deletedAt DateTime? @map("deleted_at") // 删除时间,可为空
@ -408,44 +339,127 @@ model NodeEdge {
@@index([targetId])
@@map("node_edge")
}
model Animal {
id String @id @default(cuid())
name String
age Int
gender Boolean
personId String?
person Person? @relation(fields: [personId], references: [id])
}
model Person {
id String @id @default(cuid())
name String
age Int
gender Boolean
animals Animal[]
}
model TrainContent {
id String @id @default(cuid())
title String @map("title")
score Float? @map("score")
mustTrainTime String @map("must_train_time")
alreadyTrainTime String @map("already_train_time")
type String @map("type")
parentId String? @map("parent_id")
parent TrainContent? @relation("ContentParent", fields: [parentId], references: [id]) // 指向自身
children TrainContent[] @relation("ContentParent") // 指向自身
staff Staff[] @relation("StaffTrainContent")
deletedAt DateTime? @map("deleted_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
id String @id @default(cuid())
title String @map("title")
trainSituations TrainSituation[]
type String @map("type")
parentId String? @map("parent_id")
parent TrainContent? @relation("ContentParent", fields: [parentId], references: [id]) // 指向自身
children TrainContent[] @relation("ContentParent") // 指向自身
deletedAt DateTime? @map("deleted_at")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("train_content")
}
model TrainSituation {
id String @id @default(cuid())
staffId String @map("staff_id")
staff Staff @relation(fields: [staffId], references: [id])
trainContentId String @map("train_content_id")
trainContent TrainContent @relation(fields: [trainContentId], references: [id])
mustTrainTime String @map("must_train_time")
alreadyTrainTime String @map("already_train_time")
@@map("train_situation")
}
model Position {
id String @id @default(cuid()) @map("id")
type String @map("type")
staff Staff[] @relation("StaffPosition")
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
@@map("position")
}
model Department {
id String @id @default(cuid())
name String
order Float?
posts Post[] @relation("post_dept")
ancestors DeptAncestry[] @relation("DescendantToAncestor")
descendants DeptAncestry[] @relation("AncestorToDescendant")
parentId String? @map("parent_id")
parent Department? @relation("ChildParent", fields: [parentId], references: [id])
children Department[] @relation("ChildParent")
domainId String? @map("domain_id")
domainTerms Term[] @relation("TermDom")
deletedAt DateTime? @map("deleted_at")
isDomain Boolean? @default(false) @map("is_domain")
domainStaffs Staff[] @relation("DomainStaff")
deptStaffs Staff[] @relation("DeptStaff")
terms Term[] @relation("department_term")
// watchedPost Post[] @relation("post_watch_dept")
hasChildren Boolean? @default(false) @map("has_children")
@@index([parentId])
@@index([isDomain])
@@index([name])
@@index([order])
@@map("department")
}
model Staff {
id String @id @default(cuid())
showname String? @map("showname")
username String @unique @map("username")
avatar String? @map("avatar")
password String? @map("password")
phoneNumber String? @unique @map("phone_number")
age Int? @map("age")
sex Boolean? @map("sex")
absent Boolean? @map("absent")
trainSituations TrainSituation[]
position Position? @relation("StaffPosition", fields: [positionId], references: [id])
positionId String? @map("position_id")
domainId String? @map("domain_id")
deptId String? @map("dept_id")
domain Department? @relation("DomainStaff", fields: [domainId], references: [id])
department Department? @relation("DeptStaff", fields: [deptId], references: [id])
order Float?
createdAt DateTime @default(now()) @map("created_at")
updatedAt DateTime @updatedAt @map("updated_at")
enabled Boolean? @default(true)
deletedAt DateTime? @map("deleted_at")
officerId String? @map("officer_id")
// watchedPost Post[] @relation("post_watch_staff")
visits Visit[]
posts Post[]
learningPosts Post[] @relation("post_student")
sentMsgs Message[] @relation("message_sender")
receivedMsgs Message[] @relation("message_receiver")
registerToken String?
enrollments Enrollment[]
teachedPosts PostInstructor[]
ownedResources Resource[]
@@index([officerId])
@@index([deptId])
@@index([domainId])
@@index([username])
@@index([order])
@@map("staff")
}

View File

@ -59,6 +59,8 @@ export enum ObjectType {
LECTURE = "lecture",
ENROLLMENT = "enrollment",
RESOURCE = "resource",
TRAIN_CONTENT = "trainContent",
TRAIN_SITUATION = "trainSituation"
}
export enum RolePerms {
// Create Permissions 创建权限
@ -201,3 +203,8 @@ export const LessonTypeLabel = {
[LessonType.QUIZ]: "测验",
[LessonType.ASSIGNMENT]: "作业",
};
export enum TrainContentType {
SUBJECTS = "科目",
COURSE = "课目"
}