Skip to content

Commit

Permalink
Merge pull request #22 from graywenn/feature/question
Browse files Browse the repository at this point in the history
Feature/question
  • Loading branch information
greywen authored Aug 12, 2022
2 parents c27cc55 + d2fef88 commit c827a27
Show file tree
Hide file tree
Showing 19 changed files with 525 additions and 134 deletions.
21 changes: 16 additions & 5 deletions src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import {
TimeSheetController,
UserController,
InformController,
CodeController,
LanguageController,
QuestionBankController,
QuestionAnswerController,
} from './controllers';
import {
jwtModuleOptions,
Expand All @@ -29,15 +31,18 @@ import {
UserService,
InformService,
TimeSheetService,
CodeService,
LanguageService,
QuestionBankService,
QuestionAnswerService,
} from './services';
import { JwtStrategy, WsGuard } from './strategys';
import {
DataResource,
DataDepartment,
UserTimesheet,
Language,
QuestionBank,
QuestionAnswer,
QuestionContributor,
} from './entities';

@Module({
Expand All @@ -52,6 +57,8 @@ import {
DataDepartment,
UserTimesheet,
QuestionBank,
QuestionAnswer,
QuestionContributor,
]),
],
controllers: [
Expand All @@ -62,7 +69,9 @@ import {
TimeSheetController,
UserController,
InformController,
CodeController,
LanguageController,
QuestionAnswerController,
QuestionBankController,
],
providers: [
WsGuard,
Expand All @@ -73,7 +82,9 @@ import {
AuthService,
UserService,
InformService,
CodeService,
LanguageService,
QuestionBankService,
QuestionAnswerService,
TimeSheetService,
TimeSheetSocket,
TimeSheetSchedule,
Expand Down
2 changes: 1 addition & 1 deletion src/config/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface IConfig {
environment: ServerEnvironment;
};
services: {
codeService: string;
languageService: string;
};
dingTalk: {
bossId: string;
Expand Down
9 changes: 9 additions & 0 deletions src/constants/resources.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export enum Resources {
'dashboard' = '1',
'timesheet' = '2',
'attendance' = '3',
'questionBank' = '4',
'codeOnline' = '5',
'createQuestion' = '6',
'updateQuestion' = '7',
}
4 changes: 3 additions & 1 deletion src/controllers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ export * from './auth.controller';
export * from './timesheet.controller';
export * from './user.controller';
export * from './inform.controller';
export * from './code.controller';
export * from './language.controller';
export * from './questionBank.controller';
export * from './questionAnswer.controller';
Original file line number Diff line number Diff line change
@@ -1,22 +1,34 @@
import { ICodeRunBody, IQuestionDto } from '@dtos/code';
import { Controller, UseGuards, Post, Body, Get, Param } from '@nestjs/common';
import { ICodeRunBody } from '@dtos/code';
import {
Controller,
UseGuards,
Post,
Body,
Get,
Request,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { CodeService } from '@services/code.service';
import { LanguageService } from '@services/language.service';
import recorder from '@utils/recorder';
import { sleep } from '@utils/utils';
import { v4 as uuid } from 'uuid';
import { ICodeLanguageDto } from '@dtos/code';
import { NestRes } from '@interfaces/nestbase';
const MAX_WAITING_TIME = 360;

@UseGuards(AuthGuard('jwt'))
@Controller('code')
export class CodeController {
constructor(private readonly codeService: CodeService) {}
@Controller('language')
export class LanguageController {
constructor(private readonly languageService: LanguageService) {}
@Post('run/case')
async runByCase(@Body() body: ICodeRunBody): Promise<any> {
async runByCase(
@Body() body: ICodeRunBody,
@Request() req: NestRes,
): Promise<any> {
const id = uuid();
let waitTime = 0;
let result = null;
body.userId = req.user.userId;

recorder.add({
id: id,
Expand All @@ -42,7 +54,7 @@ export class CodeController {
return '';
}

return await this.codeService.runCodeByCase(body);
return await this.languageService.runCodeByCase(body);
}

@Post('run')
Expand Down Expand Up @@ -71,12 +83,12 @@ export class CodeController {

async runImplement(body: ICodeRunBody) {
const { code, languageId } = body;
return await this.codeService.run(languageId, code);
return await this.languageService.run(languageId, code);
}

@Get('languages')
async getLanguages() {
const data = await this.codeService.getLanguages();
const data = await this.languageService.getLanguageList();
return data.map((x) => {
return {
id: x.id,
Expand All @@ -86,15 +98,4 @@ export class CodeController {
} as ICodeLanguageDto;
});
}

@Get('question/:questionId')
async getQuestion(@Param('questionId') questionId: string) {
const data = await this.codeService.getQuestion(questionId);
return {
id: data.id,
name: data.name,
desribe: data.describe,
code: data.code,
} as IQuestionDto;
}
}
25 changes: 25 additions & 0 deletions src/controllers/questionAnswer.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Controller, UseGuards, Get, Param, Request } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { NestRes } from '@interfaces/nestbase';
import { QuestionAnswerService } from '@services/questionAnswer.service';

@UseGuards(AuthGuard('jwt'))
@Controller('answer')
export class QuestionAnswerController {
constructor(private readonly questionAnswerService: QuestionAnswerService) {}

@Get('/last/:questionId/:languageId')
async getUserLastQuestionAnswer(
@Param('questionId') questionId: string,
@Param('languageId') languageId: number,
@Request() req: NestRes,
) {
const data = await this.questionAnswerService.getUserLastQuestionAnswer(
questionId,
req.user.userId,
languageId,
);

return data?.code || null;
}
}
78 changes: 78 additions & 0 deletions src/controllers/questionBank.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import {
Controller,
UseGuards,
Post,
Body,
Get,
Param,
Put,
Request,
HttpException,
HttpStatus,
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import {
ICreateQuestionBankBody,
IUpdateQuestionBankBody,
} from '@models/questionBank.model';
import { QuestionBankService } from '@services/questionBank.service';
import { NestRes } from '@interfaces/nestbase';
import { QuestionAnswerService } from '@services/questionAnswer.service';
import { Resources } from '@constants/resources';

@UseGuards(AuthGuard('jwt'))
@Controller('question')
export class QuestionBankController {
constructor(
private readonly questionAnswerService: QuestionAnswerService,
private readonly questionBankService: QuestionBankService,
) {}

@Get('/list')
async getQuestionList(@Request() req: NestRes) {
const authorized = req.user.resources.includes(Resources.updateQuestion);
return await this.questionBankService.getQuestionList(
req.user.userId,
authorized,
);
}

@Get('/:questionId')
async getQuestion(@Param('questionId') questionId: string) {
return await this.questionBankService.getQuestion(questionId);
}

verifyQuestion(question: ICreateQuestionBankBody) {
if (!question.name) {
throw new HttpException('题目名称不能为空', HttpStatus.BAD_REQUEST);
}
try {
JSON.parse(JSON.stringify(question.cases));
JSON.parse(JSON.stringify(question.entryCodes));
} catch (error) {
throw new HttpException(JSON.stringify(error), HttpStatus.BAD_REQUEST);
}
}

@Post()
async createQuestion(
@Body() body: ICreateQuestionBankBody,
@Request() req: NestRes,
) {
this.verifyQuestion(body);
body.userId = req.user.userId;
body.userName = req.user.username;
return await this.questionBankService.createQuestion(body);
}

@Put()
async updateQuestion(
@Body() body: IUpdateQuestionBankBody,
@Request() req: NestRes,
) {
this.verifyQuestion(body);
body.userId = req.user.userId;
body.userName = req.user.username;
return await this.questionBankService.updateQuestion(body);
}
}
7 changes: 6 additions & 1 deletion src/dtos/code.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { IEntryCode } from '@entities/questionBank.entity';

export interface ICodeRunBody {
once?: boolean;
code: string;
questionId: string;
languageId: number;
userId: string;
}

export interface ICodeLanguageDto {
Expand All @@ -16,7 +19,9 @@ export interface IQuestionDto {
id: string;
name: string;
desribe: string;
code: string;
createTime: string;
level: number;
entrys: IEntryCode[];
}

export interface ICodeRunResult {
Expand Down
2 changes: 2 additions & 0 deletions src/entities/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ export * from './data.permission.entity';
export * from './timesheet.enetity';
export * from './language.entity';
export * from './questionBank.entity';
export * from './questionAnswer.entity';
export * from './questionContributor.entity';
23 changes: 23 additions & 0 deletions src/entities/questionAnswer.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Column, Entity } from 'typeorm';

@Entity({ name: 'question_answer' })
export class QuestionAnswer {
@Column({ primary: true, generated: 'uuid' })
id: string;
@Column('varchar', { length: 50, nullable: true })
questionId: string;
@Column('int2', { nullable: true })
languageId: number;
@Column('varchar', { length: 50, nullable: true })
userId: string;
@Column('text', { nullable: true })
code: string;
@Column('text', { nullable: true })
result: string;
@Column('boolean', { nullable: true })
isPassed: boolean;
@Column('double precision', { nullable: true })
elapsedTime: number;
@Column('timestamp')
createTime: string;
}
23 changes: 15 additions & 8 deletions src/entities/questionBank.entity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,29 @@ export class QuestionBank {
id: string;
@Column('varchar', { length: 100 })
name: string; // 题目名称
@Column('varchar', { length: 50 })
entry: string; // 入口方法
@Column('text')
code: string; // 默认填充代码
@Column('text')
@Column('smallint', { nullable: true })
level: number; // 难度级别
@Column('jsonb', { array: false, default: () => "'[]'", nullable: true })
entryCodes: IEntryCode[]; // 默认填充代码
@Column('text', { nullable: true })
describe?: string; // 题目描述
@Column('jsonb', { array: false, default: () => "'[]'", nullable: true })
cases?: IQuestionCase[]; // 测试cases
@Column('jsonb', { array: false, default: () => "'[]'", nullable: true })
contributor?: string[]; // 贡献者 可以多个
@Column('date')
@Column('boolean', { nullable: true })
enabled: boolean; // 是否展示
@Column('timestamp')
createTime: string;
}

export class IQuestionCase {
languageId: number;
comments: string;
input: any;
output: any;
}

export class IEntryCode {
languageId: number;
function: string; // 入口方法
code: string;
}
15 changes: 15 additions & 0 deletions src/entities/questionContributor.entity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { Column, Entity } from 'typeorm';

@Entity({ name: 'question_contributor' })
export class QuestionContributor {
@Column({ primary: true, generated: 'uuid' })
id: string;
@Column('varchar', { length: 50, nullable: true })
questionId: string;
@Column('varchar', { length: 50, nullable: true })
userId: string;
@Column('varchar', { length: 50, nullable: true })
userName: string;
@Column('timestamp')
createTime: string;
}
Loading

0 comments on commit c827a27

Please sign in to comment.