core: 向前端发送题目类型

This commit is contained in:
undefined committed 2021-05-27 14:07:16 +08:00
1 parent e02bbd970e
commit cdbbee8180
8 files changed
+40 -48

No files matched your search

-6
View File
@@ -7,7 +7,6 @@ import {
} from '../error';
import { ProblemDoc, Tdoc, User } from '../interface';
import paginate from '../lib/paginate';
import { parseConfig } from '../lib/testdataConfig';
import { PERM, PRIV } from '../model/builtin';
import * as contest from '../model/contest';
import * as system from '../model/system';
@@ -270,11 +269,6 @@ class ContestProblemHandler extends Handler {
attended: this.attended,
page_name: 'contest_detail_problem',
};
try {
this.response.body.pdoc.config = await parseConfig(this.pdoc.config);
} catch (e) {
this.response.body.pdoc.config = `Cannot parse: ${e.message}`;
}
}
// eslint-disable-next-line
-6
View File
@@ -24,7 +24,6 @@ import problem from '../model/problem';
import record from '../model/record';
import * as document from '../model/document';
import paginate from '../lib/paginate';
import { parseConfig } from '../lib/testdataConfig';
const validatePenaltyRules = (input: string) => {
const s = yaml.load(input);
@@ -144,11 +143,6 @@ class HomeworkDetailProblemHandler extends Handler {
udoc: this.udoc,
attended: this.attended,
};
try {
this.response.body.pdoc.config = await parseConfig(this.pdoc.config);
} catch (e) {
this.response.body.pdoc.config = `Cannot parse: ${e.message}`;
}
}
@param('tid', Types.ObjectID)
+11 -9
View File
@@ -13,7 +13,6 @@ import {
import paginate from '../lib/paginate';
import { isPid, parsePid as convertPid } from '../lib/validator';
import difficultyAlgorithm from '../lib/difficulty';
import { parseConfig } from '../lib/testdataConfig';
import * as system from '../model/system';
import problem from '../model/problem';
import record from '../model/record';
@@ -203,12 +202,6 @@ export class ProblemDetailHandler extends ProblemHandler {
],
};
this.extraTitleContent = this.pdoc.title;
// Get time and memory limit
try {
this.response.body.pdoc.config = await parseConfig(this.pdoc.config);
} catch (e) {
this.response.body.pdoc.config = `Cannot parse: ${e.message}`;
}
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -597,11 +590,20 @@ export class ProblemCreateHandler extends Handler {
export class ProblemPrefixListHandler extends Handler {
@param('prefix', Types.Name)
async get(domainId: string, prefix: string) {
this.response.body = await problem.getPrefixList(domainId, prefix);
const pdocs = await problem.getPrefixList(domainId, prefix);
if (!Number.isNaN(+prefix)) {
const pdoc = await problem.get(domainId, +prefix, ['domainId', 'docId', 'pid', 'title']);
if (pdoc) this.response.body.unshift(pdoc);
if (pdoc) pdocs.unshift(pdoc);
}
const search = global.Hydro.lib.problemSearch;
if (pdocs.length < 20) {
if (search) {
const result = await search(domainId, prefix, 20 - pdocs.length);
const docs = await problem.getMulti(domainId, { docId: { $in: result } }).toArray();
pdocs.push(...docs);
}
}
this.response.body = pdocs;
}
}
+2 -1
View File
@@ -207,7 +207,8 @@ declare module './model/problem' {
/** @deprecated */
category?: string[],
config: string,
/** string (errormsg) */
config: string | ProblemConfig,
}
}
export type { ProblemDoc } from './model/problem';
+7 -5
View File
@@ -9,21 +9,23 @@ interface ParseResult {
timeMax: number;
timeMin: number;
langs?: string[];
type: string;
}
export async function parseConfig(config: string | ProblemConfig = {}) {
let cfg: ProblemConfig = {};
if (typeof config === 'string') {
// TODO should validate here?
cfg = await readYamlCases(load(config) as Record<string, any>);
} else if (typeof config === 'object') cfg = await readYamlCases(config);
const result: ParseResult = {
count: 0,
memoryMin: Number.MAX_SAFE_INTEGER,
memoryMax: 0,
timeMin: Number.MAX_SAFE_INTEGER,
timeMax: 0,
type: cfg.type || 'default',
};
let cfg: ProblemConfig = {};
if (typeof config === 'string') {
// TODO should validate here?
cfg = await readYamlCases(load(config) as Record<string, any>);
} else if (typeof config === 'object') cfg = await readYamlCases(config);
if (cfg.subtasks.length) {
for (const subtask of cfg.subtasks) {
result.memoryMax = Math.max(result.memoryMax, subtask.memory);
+17 -3
View File
@@ -12,6 +12,7 @@ import {
} from '../typeutils';
import { ProblemNotFoundError, ValidationError } from '../error';
import * as bus from '../service/bus';
import { parseConfig } from '../lib/testdataConfig';
export interface ProblemDoc extends Document { }
export type Field = keyof ProblemDoc;
@@ -79,9 +80,16 @@ export class ProblemModel {
if (typeof pid !== 'number') {
if (Number.isSafeInteger(parseInt(pid, 10))) pid = parseInt(pid, 10);
}
return typeof pid === 'number'
const res = typeof pid === 'number'
? await document.get(domainId, document.TYPE_PROBLEM, pid, projection)
: (await document.getMulti(domainId, document.TYPE_PROBLEM, { pid }).toArray())[0];
if (!res) return null;
try {
res.config = await parseConfig(res.config);
} catch (e) {
res.config = `Cannot parse: ${e.message}`;
}
return res;
}
static getMulti(domainId: string, query: FilterQuery<ProblemDoc>, projection = ProblemModel.PROJECTION_LIST) {
@@ -173,12 +181,12 @@ export class ProblemModel {
await bus.emit('problem/delAdditionalFile', domainId, pid, names);
}
static async random(domainId: string, query: FilterQuery<ProblemDoc>): Promise<string | null> {
static async random(domainId: string, query: FilterQuery<ProblemDoc>): Promise<string | number | null> {
const cursor = document.getMulti(domainId, document.TYPE_PROBLEM, query);
const pcount = await cursor.count();
if (pcount) {
const pdoc = await cursor.skip(Math.floor(Math.random() * pcount)).limit(1).toArray();
return pdoc[0].pid;
return pdoc[0].pid || pdoc[0].docId;
} return null;
}
@@ -194,6 +202,12 @@ export class ProblemModel {
const pdocs = await document.getMulti(domainId, document.TYPE_PROBLEM, q)
.project(buildProjection(projection)).toArray();
for (const pdoc of pdocs) {
try {
// eslint-disable-next-line no-await-in-loop
pdoc.config = await parseConfig(pdoc.config);
} catch (e) {
pdoc.config = `Cannot parse: ${e.message}`;
}
r[pdoc.docId] = pdoc;
l[pdoc.pid] = pdoc;
}
@@ -2,7 +2,7 @@ import React from 'react';
import { sortBy } from 'lodash';
import request from 'vj/utils/request';
export default class MessagePadContainer extends React.PureComponent {
export default class SubjectiveContainer extends React.PureComponent {
constructor(args) {
super(args);
this.state = {};
@@ -103,22 +103,6 @@ const page = new NamedPage(['problem_detail', 'contest_detail_problem', 'homewor
let unmountReact = null;
const extender = new ProblemPageExtender();
const copyProblemDialog = new ActionDialog({
$body: $('.dialog__body--send-to > div'),
onDispatch(action) {
const $target = copyProblemDialog.$dom.find('[name="target"]');
if (action === 'ok' && $target.val() === '') {
$target.focus();
return false;
}
return true;
},
});
copyProblemDialog.clear = function () {
this.$dom.find('[name="target"]').val('');
return this;
};
async function handleClickDownloadProblem() {
await downloadProblemSet([UiContext.problemNumId]);
}
@@ -192,7 +176,8 @@ const page = new NamedPage(['problem_detail', 'contest_detail_problem', 'homewor
async function loadSubjective() {
try {
const props = yaml.load(base64.decode(document.getElementsByClassName('section__body typo')[0].innerText));
if (UiContext.pdoc.config?.type !== 'subjective') return;
const props = yaml.load(document.getElementsByClassName('section__body typo')[0].innerText);
if (!(props instanceof Array)) return;
$('.outer-loader-container').show();
const { default: Subjective } = await import('vj/components/subjective-question/index');