rht
This commit is contained in:
parent
c91cfa81bc
commit
ae17534dfb
|
@ -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)
|
||||||
|
}
|
|
@ -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 {}
|
|
@ -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({
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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)
|
||||||
|
}
|
|
@ -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 {}
|
|
@ -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)
|
||||||
|
}),
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
|
@ -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,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,11 +11,14 @@ import {
|
||||||
Staff,
|
Staff,
|
||||||
TaxonomySlug,
|
TaxonomySlug,
|
||||||
Term,
|
Term,
|
||||||
|
TrainContent,
|
||||||
} from '@nice/common';
|
} from '@nice/common';
|
||||||
import EventBus from '@server/utils/event-bus';
|
import EventBus from '@server/utils/event-bus';
|
||||||
import { capitalizeFirstLetter, DevDataCounts, getCounts } from './utils';
|
import { capitalizeFirstLetter, DevDataCounts, getCounts } from './utils';
|
||||||
import { StaffService } from '@server/models/staff/staff.service';
|
import { StaffService } from '@server/models/staff/staff.service';
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
|
import { TrainContentType } from '@nice/common';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class GenDevService {
|
export class GenDevService {
|
||||||
private readonly logger = new Logger(GenDevService.name);
|
private readonly logger = new Logger(GenDevService.name);
|
||||||
|
@ -30,8 +33,10 @@ export class GenDevService {
|
||||||
domains: Department[] = [];
|
domains: Department[] = [];
|
||||||
domainDepts: Record<string, Department[]> = {};
|
domainDepts: Record<string, Department[]> = {};
|
||||||
staffs: Staff[] = [];
|
staffs: Staff[] = [];
|
||||||
|
trainContents: TrainContent[] = [];
|
||||||
deptGeneratedCount = 0;
|
deptGeneratedCount = 0;
|
||||||
courseGeneratedCount = 1;
|
courseGeneratedCount = 1;
|
||||||
|
trainContentGeneratedCount = 0;
|
||||||
constructor(
|
constructor(
|
||||||
private readonly appConfigService: AppConfigService,
|
private readonly appConfigService: AppConfigService,
|
||||||
|
|
||||||
|
@ -47,6 +52,7 @@ export class GenDevService {
|
||||||
await this.generateTerms(2, 6);
|
await this.generateTerms(2, 6);
|
||||||
await this.generateStaffs(4);
|
await this.generateStaffs(4);
|
||||||
await this.generateCourses(8);
|
await this.generateCourses(8);
|
||||||
|
await this.generateTrainContent(2,6)
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
this.logger.error(err);
|
this.logger.error(err);
|
||||||
}
|
}
|
||||||
|
@ -338,4 +344,64 @@ export class GenDevService {
|
||||||
|
|
||||||
await createTermTree(null, 1);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import {
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
export interface DevDataCounts {
|
export interface DevDataCounts {
|
||||||
deptCount: number;
|
deptCount: number;
|
||||||
|
trainContentCount: number;
|
||||||
staffCount: number;
|
staffCount: number;
|
||||||
termCount: number;
|
termCount: number;
|
||||||
courseCount: number;
|
courseCount: number;
|
||||||
|
@ -16,7 +16,7 @@ export interface DevDataCounts {
|
||||||
export async function getCounts(): Promise<DevDataCounts> {
|
export async function getCounts(): Promise<DevDataCounts> {
|
||||||
const counts = {
|
const counts = {
|
||||||
deptCount: await db.department.count(),
|
deptCount: await db.department.count(),
|
||||||
|
trainContentCount:await db.trainContent.count(),
|
||||||
staffCount: await db.staff.count(),
|
staffCount: await db.staff.count(),
|
||||||
termCount: await db.term.count(),
|
termCount: await db.term.count(),
|
||||||
courseCount: await db.post.count({
|
courseCount: await db.post.count({
|
||||||
|
|
|
@ -14,8 +14,9 @@ import { VisitModule } from '@server/models/visit/visit.module';
|
||||||
import { WebSocketModule } from '@server/socket/websocket.module';
|
import { WebSocketModule } from '@server/socket/websocket.module';
|
||||||
import { RoleMapModule } from '@server/models/rbac/rbac.module';
|
import { RoleMapModule } from '@server/models/rbac/rbac.module';
|
||||||
import { TransformModule } from '@server/models/transform/transform.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 { ResourceModule } from '@server/models/resource/resource.module';
|
||||||
|
import { TrainSituationModule } from '@server/models/train-situation/trainSituation.module';
|
||||||
|
|
||||||
@Module({
|
@Module({
|
||||||
imports: [
|
imports: [
|
||||||
|
@ -33,6 +34,8 @@ import { ResourceModule } from '@server/models/resource/resource.module';
|
||||||
VisitModule,
|
VisitModule,
|
||||||
WebSocketModule,
|
WebSocketModule,
|
||||||
ResourceModule,
|
ResourceModule,
|
||||||
|
TrainContentModule,
|
||||||
|
TrainSituationModule
|
||||||
],
|
],
|
||||||
controllers: [],
|
controllers: [],
|
||||||
providers: [TrpcService, TrpcRouter, Logger],
|
providers: [TrpcService, TrpcRouter, Logger],
|
||||||
|
|
|
@ -14,6 +14,8 @@ import { RoleMapRouter } from '@server/models/rbac/rolemap.router';
|
||||||
import { TransformRouter } from '@server/models/transform/transform.router';
|
import { TransformRouter } from '@server/models/transform/transform.router';
|
||||||
import { RoleRouter } from '@server/models/rbac/role.router';
|
import { RoleRouter } from '@server/models/rbac/role.router';
|
||||||
import { ResourceRouter } from '../models/resource/resource.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()
|
@Injectable()
|
||||||
export class TrpcRouter {
|
export class TrpcRouter {
|
||||||
|
@ -32,6 +34,8 @@ export class TrpcRouter {
|
||||||
private readonly message: MessageRouter,
|
private readonly message: MessageRouter,
|
||||||
private readonly visitor: VisitRouter,
|
private readonly visitor: VisitRouter,
|
||||||
private readonly resource: ResourceRouter,
|
private readonly resource: ResourceRouter,
|
||||||
|
private readonly trainContent: TrainContentRouter,
|
||||||
|
private readonly trainSituation:TrainSituationRouter,
|
||||||
) {}
|
) {}
|
||||||
getRouter() {
|
getRouter() {
|
||||||
return;
|
return;
|
||||||
|
@ -49,6 +53,8 @@ export class TrpcRouter {
|
||||||
app_config: this.app_config.router,
|
app_config: this.app_config.router,
|
||||||
visitor: this.visitor.router,
|
visitor: this.visitor.router,
|
||||||
resource: this.resource.router,
|
resource: this.resource.router,
|
||||||
|
trainContent:this.trainContent.router,
|
||||||
|
trainSituation:this.trainSituation.router
|
||||||
});
|
});
|
||||||
wss: WebSocketServer = undefined;
|
wss: WebSocketServer = undefined;
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
import React, { useState, useCallback, useEffect, useMemo } from "react";
|
import React, { useState, useCallback, useEffect, useMemo } from "react";
|
||||||
import { Typography, Skeleton } from "antd";
|
import { Typography, Skeleton } from "antd";
|
||||||
import { stringToColor, TaxonomySlug, TermDto } from "@nice/common";
|
import { stringToColor, TaxonomySlug, TermDto } from "@nice/common";
|
||||||
import { api } from "@nice/client";
|
import { api, useTrainSituation } from "@nice/client";
|
||||||
import LookForMore from "./LookForMore";
|
import LookForMore from "./LookForMore";
|
||||||
import CategorySectionCard from "./CategorySectionCard";
|
import CategorySectionCard from "./CategorySectionCard";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
import { useMainContext } from "../../layout/MainProvider";
|
import { useMainContext } from "../../layout/MainProvider";
|
||||||
|
import { useAuth } from "@web/src/providers/auth-provider";
|
||||||
|
|
||||||
const { Title, Text } = Typography;
|
const { Title, Text } = Typography;
|
||||||
const CategorySection = () => {
|
const CategorySection = () => {
|
||||||
|
@ -41,6 +42,26 @@ const CategorySection = () => {
|
||||||
navigate("/courses");
|
navigate("/courses");
|
||||||
window.scrollTo({ top: 0, behavior: "smooth" });
|
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 (
|
return (
|
||||||
<section className="py-8 relative overflow-hidden">
|
<section className="py-8 relative overflow-hidden">
|
||||||
<div className="max-w-screen-2xl mx-auto px-4 relative">
|
<div className="max-w-screen-2xl mx-auto px-4 relative">
|
||||||
|
|
|
@ -15,7 +15,7 @@ import {
|
||||||
EyeOutlined,
|
EyeOutlined,
|
||||||
} from "@ant-design/icons";
|
} from "@ant-design/icons";
|
||||||
import type { CarouselRef } from "antd/es/carousel";
|
import type { CarouselRef } from "antd/es/carousel";
|
||||||
import { useAppConfig } from "@nice/client";
|
import { api, useAppConfig } from "@nice/client";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
|
||||||
interface PlatformStat {
|
interface PlatformStat {
|
||||||
|
@ -70,6 +70,13 @@ const HeroSection = () => {
|
||||||
console.log(count);
|
console.log(count);
|
||||||
setCountStatistics(count);
|
setCountStatistics(count);
|
||||||
}, [statistics]);
|
}, [statistics]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<section className="relative ">
|
<section className="relative ">
|
||||||
<div className="group">
|
<div className="group">
|
||||||
|
|
|
@ -2,7 +2,7 @@ server {
|
||||||
# 监听80端口
|
# 监听80端口
|
||||||
listen 80;
|
listen 80;
|
||||||
# 服务器域名/IP地址,使用环境变量
|
# 服务器域名/IP地址,使用环境变量
|
||||||
server_name host.docker.internal;
|
server_name 192.168.43.206;
|
||||||
|
|
||||||
# 基础性能优化配置
|
# 基础性能优化配置
|
||||||
# 启用tcp_nopush以优化数据发送
|
# 启用tcp_nopush以优化数据发送
|
||||||
|
@ -100,7 +100,7 @@ server {
|
||||||
# 仅供内部使用
|
# 仅供内部使用
|
||||||
internal;
|
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;
|
proxy_pass_request_body off;
|
||||||
|
|
|
@ -10,3 +10,4 @@ export * from "./useVisitor"
|
||||||
export * from "./useMessage"
|
export * from "./useMessage"
|
||||||
export * from "./usePost"
|
export * from "./usePost"
|
||||||
export * from "./useEntity"
|
export * from "./useEntity"
|
||||||
|
export * from "./useTrainSituation"
|
||||||
|
|
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
|
@ -67,80 +67,9 @@ model TermAncestry {
|
||||||
@@map("term_ancestry")
|
@@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 {
|
model DeptAncestry {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
|
@ -196,45 +125,45 @@ model AppConfig {
|
||||||
|
|
||||||
model Post {
|
model Post {
|
||||||
// 字符串类型字段
|
// 字符串类型字段
|
||||||
id String @id @default(cuid()) // 帖子唯一标识,使用 cuid() 生成默认值
|
id String @id @default(cuid()) // 帖子唯一标识,使用 cuid() 生成默认值
|
||||||
type String? // Post类型,课程、章节、小节、讨论都用Post实现
|
type String? // Post类型,课程、章节、小节、讨论都用Post实现
|
||||||
level String?
|
level String?
|
||||||
state String?
|
state String?
|
||||||
title String? // 帖子标题,可为空
|
title String? // 帖子标题,可为空
|
||||||
subTitle String?
|
subTitle String?
|
||||||
content String? // 帖子内容,可为空
|
content String? // 帖子内容,可为空
|
||||||
important Boolean? //是否重要/精选/突出
|
important Boolean? //是否重要/精选/突出
|
||||||
domainId String? @map("domain_id")
|
domainId String? @map("domain_id")
|
||||||
terms Term[] @relation("post_term")
|
terms Term[] @relation("post_term")
|
||||||
order Float? @default(0) @map("order")
|
order Float? @default(0) @map("order")
|
||||||
duration Int?
|
duration Int?
|
||||||
rating Int? @default(0)
|
rating Int? @default(0)
|
||||||
students Staff[] @relation("post_student")
|
students Staff[] @relation("post_student")
|
||||||
depts Department[] @relation("post_dept")
|
depts Department[] @relation("post_dept")
|
||||||
views Int @default(0) @map("views")
|
views Int @default(0) @map("views")
|
||||||
hates Int @default(0) @map("hates")
|
hates Int @default(0) @map("hates")
|
||||||
likes Int @default(0) @map("likes")
|
likes Int @default(0) @map("likes")
|
||||||
// 索引
|
// 索引
|
||||||
// 日期时间类型字段
|
// 日期时间类型字段
|
||||||
createdAt DateTime @default(now()) @map("created_at")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
publishedAt DateTime? @map("published_at") // 发布时间
|
publishedAt DateTime? @map("published_at") // 发布时间
|
||||||
updatedAt DateTime @map("updated_at")
|
updatedAt DateTime @map("updated_at")
|
||||||
deletedAt DateTime? @map("deleted_at") // 删除时间,可为空
|
deletedAt DateTime? @map("deleted_at") // 删除时间,可为空
|
||||||
instructors PostInstructor[]
|
instructors PostInstructor[]
|
||||||
// 关系类型字段
|
// 关系类型字段
|
||||||
authorId String? @map("author_id")
|
authorId String? @map("author_id")
|
||||||
author Staff? @relation(fields: [authorId], references: [id]) // 帖子作者,关联 Staff 模型
|
author Staff? @relation(fields: [authorId], references: [id]) // 帖子作者,关联 Staff 模型
|
||||||
enrollments Enrollment[] // 学生报名记录
|
enrollments Enrollment[] // 学生报名记录
|
||||||
visits Visit[] // 访问记录,关联 Visit 模型
|
visits Visit[] // 访问记录,关联 Visit 模型
|
||||||
parentId String? @map("parent_id")
|
parentId String? @map("parent_id")
|
||||||
parent Post? @relation("PostChildren", fields: [parentId], references: [id]) // 父级帖子,关联 Post 模型
|
parent Post? @relation("PostChildren", fields: [parentId], references: [id]) // 父级帖子,关联 Post 模型
|
||||||
children Post[] @relation("PostChildren") // 子级帖子列表,关联 Post 模型
|
children Post[] @relation("PostChildren") // 子级帖子列表,关联 Post 模型
|
||||||
hasChildren Boolean? @default(false) @map("has_children")
|
hasChildren Boolean? @default(false) @map("has_children")
|
||||||
// 闭包表关系
|
// 闭包表关系
|
||||||
ancestors PostAncestry[] @relation("DescendantPosts")
|
ancestors PostAncestry[] @relation("DescendantPosts")
|
||||||
descendants PostAncestry[] @relation("AncestorPosts")
|
descendants PostAncestry[] @relation("AncestorPosts")
|
||||||
resources Resource[] // 附件列表
|
resources Resource[] // 附件列表
|
||||||
meta Json? // 封面url 视频url objectives具体的学习目标 rating评分Int
|
meta Json? // 封面url 视频url objectives具体的学习目标 rating评分Int
|
||||||
|
|
||||||
// 索引
|
// 索引
|
||||||
@@index([type, domainId])
|
@@index([type, domainId])
|
||||||
|
@ -252,12 +181,13 @@ model Post {
|
||||||
}
|
}
|
||||||
|
|
||||||
model PostAncestry {
|
model PostAncestry {
|
||||||
id String @id @default(cuid())
|
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")
|
||||||
ancestor Post? @relation("AncestorPosts", fields: [ancestorId], references: [id])
|
ancestor Post? @relation("AncestorPosts", fields: [ancestorId], references: [id])
|
||||||
descendant Post @relation("DescendantPosts", fields: [descendantId], references: [id])
|
descendant Post @relation("DescendantPosts", fields: [descendantId], references: [id])
|
||||||
|
|
||||||
// 复合索引优化
|
// 复合索引优化
|
||||||
// 索引建议
|
// 索引建议
|
||||||
@@index([ancestorId]) // 针对祖先的查询
|
@@index([ancestorId]) // 针对祖先的查询
|
||||||
|
@ -281,23 +211,24 @@ model Message {
|
||||||
visits Visit[]
|
visits Visit[]
|
||||||
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")
|
||||||
|
|
||||||
@@index([type, createdAt])
|
@@index([type, createdAt])
|
||||||
@@map("message")
|
@@map("message")
|
||||||
}
|
}
|
||||||
|
|
||||||
model Visit {
|
model Visit {
|
||||||
id String @id @default(cuid()) @map("id")
|
id String @id @default(cuid()) @map("id")
|
||||||
type String?
|
type String?
|
||||||
views Int @default(1) @map("views")
|
views Int @default(1) @map("views")
|
||||||
// sourceIP String? @map("source_ip")
|
// sourceIP String? @map("source_ip")
|
||||||
// 关联关系
|
// 关联关系
|
||||||
visitorId String? @map("visitor_id")
|
visitorId String? @map("visitor_id")
|
||||||
visitor Staff? @relation(fields: [visitorId], references: [id])
|
visitor Staff? @relation(fields: [visitorId], references: [id])
|
||||||
postId String? @map("post_id")
|
postId String? @map("post_id")
|
||||||
post Post? @relation(fields: [postId], references: [id])
|
post Post? @relation(fields: [postId], references: [id])
|
||||||
message Message? @relation(fields: [messageId], references: [id])
|
message Message? @relation(fields: [messageId], references: [id])
|
||||||
messageId String? @map("message_id")
|
messageId String? @map("message_id")
|
||||||
lectureId String? @map("lecture_id") // 课时ID
|
lectureId String? @map("lecture_id") // 课时ID
|
||||||
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") // 更新时间
|
||||||
deletedAt DateTime? @map("deleted_at") // 删除时间,可为空
|
deletedAt DateTime? @map("deleted_at") // 删除时间,可为空
|
||||||
|
@ -408,44 +339,127 @@ model NodeEdge {
|
||||||
@@index([targetId])
|
@@index([targetId])
|
||||||
@@map("node_edge")
|
@@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 {
|
model TrainContent {
|
||||||
id String @id @default(cuid())
|
id String @id @default(cuid())
|
||||||
title String @map("title")
|
title String @map("title")
|
||||||
score Float? @map("score")
|
trainSituations TrainSituation[]
|
||||||
mustTrainTime String @map("must_train_time")
|
type String @map("type")
|
||||||
alreadyTrainTime String @map("already_train_time")
|
parentId String? @map("parent_id")
|
||||||
|
parent TrainContent? @relation("ContentParent", fields: [parentId], references: [id]) // 指向自身
|
||||||
type String @map("type")
|
children TrainContent[] @relation("ContentParent") // 指向自身
|
||||||
|
deletedAt DateTime? @map("deleted_at")
|
||||||
parentId String? @map("parent_id")
|
createdAt DateTime @default(now()) @map("created_at")
|
||||||
parent TrainContent? @relation("ContentParent", fields: [parentId], references: [id]) // 指向自身
|
updatedAt DateTime @updatedAt @map("updated_at")
|
||||||
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")
|
|
||||||
|
|
||||||
@@map("train_content")
|
@@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")
|
||||||
}
|
}
|
|
@ -59,6 +59,8 @@ export enum ObjectType {
|
||||||
LECTURE = "lecture",
|
LECTURE = "lecture",
|
||||||
ENROLLMENT = "enrollment",
|
ENROLLMENT = "enrollment",
|
||||||
RESOURCE = "resource",
|
RESOURCE = "resource",
|
||||||
|
TRAIN_CONTENT = "trainContent",
|
||||||
|
TRAIN_SITUATION = "trainSituation"
|
||||||
}
|
}
|
||||||
export enum RolePerms {
|
export enum RolePerms {
|
||||||
// Create Permissions 创建权限
|
// Create Permissions 创建权限
|
||||||
|
@ -201,3 +203,8 @@ export const LessonTypeLabel = {
|
||||||
[LessonType.QUIZ]: "测验",
|
[LessonType.QUIZ]: "测验",
|
||||||
[LessonType.ASSIGNMENT]: "作业",
|
[LessonType.ASSIGNMENT]: "作业",
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export enum TrainContentType {
|
||||||
|
SUBJECTS = "科目",
|
||||||
|
COURSE = "课目"
|
||||||
|
}
|
Loading…
Reference in New Issue