mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
core: 向前端发送题目类型
This commit is contained in:
1 parent
e02bbd970e
commit
cdbbee8180
8 files changed
+40
-48
No files matched your search
@@ -7,7 +7,6 @@ import {
|
|||||||
} from '../error';
|
} from '../error';
|
||||||
import { ProblemDoc, Tdoc, User } from '../interface';
|
import { ProblemDoc, Tdoc, User } from '../interface';
|
||||||
import paginate from '../lib/paginate';
|
import paginate from '../lib/paginate';
|
||||||
import { parseConfig } from '../lib/testdataConfig';
|
|
||||||
import { PERM, PRIV } from '../model/builtin';
|
import { PERM, PRIV } from '../model/builtin';
|
||||||
import * as contest from '../model/contest';
|
import * as contest from '../model/contest';
|
||||||
import * as system from '../model/system';
|
import * as system from '../model/system';
|
||||||
@@ -270,11 +269,6 @@ class ContestProblemHandler extends Handler {
|
|||||||
attended: this.attended,
|
attended: this.attended,
|
||||||
page_name: 'contest_detail_problem',
|
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
|
// eslint-disable-next-line
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import problem from '../model/problem';
|
|||||||
import record from '../model/record';
|
import record from '../model/record';
|
||||||
import * as document from '../model/document';
|
import * as document from '../model/document';
|
||||||
import paginate from '../lib/paginate';
|
import paginate from '../lib/paginate';
|
||||||
import { parseConfig } from '../lib/testdataConfig';
|
|
||||||
|
|
||||||
const validatePenaltyRules = (input: string) => {
|
const validatePenaltyRules = (input: string) => {
|
||||||
const s = yaml.load(input);
|
const s = yaml.load(input);
|
||||||
@@ -144,11 +143,6 @@ class HomeworkDetailProblemHandler extends Handler {
|
|||||||
udoc: this.udoc,
|
udoc: this.udoc,
|
||||||
attended: this.attended,
|
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)
|
@param('tid', Types.ObjectID)
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import {
|
|||||||
import paginate from '../lib/paginate';
|
import paginate from '../lib/paginate';
|
||||||
import { isPid, parsePid as convertPid } from '../lib/validator';
|
import { isPid, parsePid as convertPid } from '../lib/validator';
|
||||||
import difficultyAlgorithm from '../lib/difficulty';
|
import difficultyAlgorithm from '../lib/difficulty';
|
||||||
import { parseConfig } from '../lib/testdataConfig';
|
|
||||||
import * as system from '../model/system';
|
import * as system from '../model/system';
|
||||||
import problem from '../model/problem';
|
import problem from '../model/problem';
|
||||||
import record from '../model/record';
|
import record from '../model/record';
|
||||||
@@ -203,12 +202,6 @@ export class ProblemDetailHandler extends ProblemHandler {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
this.extraTitleContent = this.pdoc.title;
|
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
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
@@ -597,11 +590,20 @@ export class ProblemCreateHandler extends Handler {
|
|||||||
export class ProblemPrefixListHandler extends Handler {
|
export class ProblemPrefixListHandler extends Handler {
|
||||||
@param('prefix', Types.Name)
|
@param('prefix', Types.Name)
|
||||||
async get(domainId: string, prefix: string) {
|
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)) {
|
if (!Number.isNaN(+prefix)) {
|
||||||
const pdoc = await problem.get(domainId, +prefix, ['domainId', 'docId', 'pid', 'title']);
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -207,7 +207,8 @@ declare module './model/problem' {
|
|||||||
/** @deprecated */
|
/** @deprecated */
|
||||||
category?: string[],
|
category?: string[],
|
||||||
|
|
||||||
config: string,
|
/** string (errormsg) */
|
||||||
|
config: string | ProblemConfig,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
export type { ProblemDoc } from './model/problem';
|
export type { ProblemDoc } from './model/problem';
|
||||||
|
|||||||
@@ -9,21 +9,23 @@ interface ParseResult {
|
|||||||
timeMax: number;
|
timeMax: number;
|
||||||
timeMin: number;
|
timeMin: number;
|
||||||
langs?: string[];
|
langs?: string[];
|
||||||
|
type: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function parseConfig(config: string | ProblemConfig = {}) {
|
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 = {
|
const result: ParseResult = {
|
||||||
count: 0,
|
count: 0,
|
||||||
memoryMin: Number.MAX_SAFE_INTEGER,
|
memoryMin: Number.MAX_SAFE_INTEGER,
|
||||||
memoryMax: 0,
|
memoryMax: 0,
|
||||||
timeMin: Number.MAX_SAFE_INTEGER,
|
timeMin: Number.MAX_SAFE_INTEGER,
|
||||||
timeMax: 0,
|
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) {
|
if (cfg.subtasks.length) {
|
||||||
for (const subtask of cfg.subtasks) {
|
for (const subtask of cfg.subtasks) {
|
||||||
result.memoryMax = Math.max(result.memoryMax, subtask.memory);
|
result.memoryMax = Math.max(result.memoryMax, subtask.memory);
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import {
|
|||||||
} from '../typeutils';
|
} from '../typeutils';
|
||||||
import { ProblemNotFoundError, ValidationError } from '../error';
|
import { ProblemNotFoundError, ValidationError } from '../error';
|
||||||
import * as bus from '../service/bus';
|
import * as bus from '../service/bus';
|
||||||
|
import { parseConfig } from '../lib/testdataConfig';
|
||||||
|
|
||||||
export interface ProblemDoc extends Document { }
|
export interface ProblemDoc extends Document { }
|
||||||
export type Field = keyof ProblemDoc;
|
export type Field = keyof ProblemDoc;
|
||||||
@@ -79,9 +80,16 @@ export class ProblemModel {
|
|||||||
if (typeof pid !== 'number') {
|
if (typeof pid !== 'number') {
|
||||||
if (Number.isSafeInteger(parseInt(pid, 10))) pid = parseInt(pid, 10);
|
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.get(domainId, document.TYPE_PROBLEM, pid, projection)
|
||||||
: (await document.getMulti(domainId, document.TYPE_PROBLEM, { pid }).toArray())[0];
|
: (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) {
|
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);
|
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 cursor = document.getMulti(domainId, document.TYPE_PROBLEM, query);
|
||||||
const pcount = await cursor.count();
|
const pcount = await cursor.count();
|
||||||
if (pcount) {
|
if (pcount) {
|
||||||
const pdoc = await cursor.skip(Math.floor(Math.random() * pcount)).limit(1).toArray();
|
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;
|
} return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,6 +202,12 @@ export class ProblemModel {
|
|||||||
const pdocs = await document.getMulti(domainId, document.TYPE_PROBLEM, q)
|
const pdocs = await document.getMulti(domainId, document.TYPE_PROBLEM, q)
|
||||||
.project(buildProjection(projection)).toArray();
|
.project(buildProjection(projection)).toArray();
|
||||||
for (const pdoc of pdocs) {
|
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;
|
r[pdoc.docId] = pdoc;
|
||||||
l[pdoc.pid] = pdoc;
|
l[pdoc.pid] = pdoc;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import React from 'react';
|
|||||||
import { sortBy } from 'lodash';
|
import { sortBy } from 'lodash';
|
||||||
import request from 'vj/utils/request';
|
import request from 'vj/utils/request';
|
||||||
|
|
||||||
export default class MessagePadContainer extends React.PureComponent {
|
export default class SubjectiveContainer extends React.PureComponent {
|
||||||
constructor(args) {
|
constructor(args) {
|
||||||
super(args);
|
super(args);
|
||||||
this.state = {};
|
this.state = {};
|
||||||
|
|||||||
@@ -103,22 +103,6 @@ const page = new NamedPage(['problem_detail', 'contest_detail_problem', 'homewor
|
|||||||
let unmountReact = null;
|
let unmountReact = null;
|
||||||
const extender = new ProblemPageExtender();
|
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() {
|
async function handleClickDownloadProblem() {
|
||||||
await downloadProblemSet([UiContext.problemNumId]);
|
await downloadProblemSet([UiContext.problemNumId]);
|
||||||
}
|
}
|
||||||
@@ -192,7 +176,8 @@ const page = new NamedPage(['problem_detail', 'contest_detail_problem', 'homewor
|
|||||||
|
|
||||||
async function loadSubjective() {
|
async function loadSubjective() {
|
||||||
try {
|
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;
|
if (!(props instanceof Array)) return;
|
||||||
$('.outer-loader-container').show();
|
$('.outer-loader-container').show();
|
||||||
const { default: Subjective } = await import('vj/components/subjective-question/index');
|
const { default: Subjective } = await import('vj/components/subjective-question/index');
|
||||||
|
|||||||
Reference in new issue
Block a user