mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-20 01:38:19 +08:00
修复一处可能导致training状态异常的问题
This commit is contained in:
1 parent
b5c1f41dd2
commit
a1aeb521fe
11 files changed
+52
-37
No files matched your search
@@ -14,7 +14,7 @@ export interface Result {
|
|||||||
display: string
|
display: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export function lookup(ip: string, locale: string): any {
|
export function lookup(ip: string, locale: string) {
|
||||||
const res: any = reader.get(ip);
|
const res: any = reader.get(ip);
|
||||||
if (!res) return {};
|
if (!res) return {};
|
||||||
const ret: Result = { display: '' };
|
const ret: Result = { display: '' };
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@hydrooj/geoip",
|
"name": "@hydrooj/geoip",
|
||||||
"version": "1.1.11",
|
"version": "1.1.12",
|
||||||
"main": "package.json",
|
"main": "package.json",
|
||||||
"repository": "git@github.com:hydro-dev/Hydro.git",
|
"repository": "git@github.com:hydro-dev/Hydro.git",
|
||||||
"author": "undefined <masnn0@outlook.com>",
|
"author": "undefined <masnn0@outlook.com>",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "hydrooj",
|
"name": "hydrooj",
|
||||||
"version": "2.12.26",
|
"version": "2.12.27",
|
||||||
"bin": "bin/hydrooj.js",
|
"bin": "bin/hydrooj.js",
|
||||||
"main": "dist/loader.js",
|
"main": "dist/loader.js",
|
||||||
"typings": "dist/loader.d.ts",
|
"typings": "dist/loader.d.ts",
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ const checks: Dictionary<CheckItem> = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function start(ctx, log, warn, error, cb) {
|
export async function start(ctx, log, warn, error, cb: (id: string) => any) {
|
||||||
const id = String.random(6);
|
const id = String.random(6);
|
||||||
cb(id);
|
cb(id);
|
||||||
for (const name in checks) {
|
for (const name in checks) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import paginate from '../lib/paginate';
|
|||||||
import {
|
import {
|
||||||
Route, Handler, Types, param,
|
Route, Handler, Types, param,
|
||||||
} from '../service/server';
|
} from '../service/server';
|
||||||
|
import { DomainDoc } from '../interface';
|
||||||
|
|
||||||
class DomainRankHandler extends Handler {
|
class DomainRankHandler extends Handler {
|
||||||
@param('page', Types.PositiveInt, true)
|
@param('page', Types.PositiveInt, true)
|
||||||
@@ -40,7 +41,7 @@ class DomainRankHandler extends Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ManageHandler extends Handler {
|
class ManageHandler extends Handler {
|
||||||
domain: any;
|
domain: DomainDoc;
|
||||||
|
|
||||||
async prepare({ domainId }) {
|
async prepare({ domainId }) {
|
||||||
this.checkPerm(PERM.PERM_EDIT_DOMAIN);
|
this.checkPerm(PERM.PERM_EDIT_DOMAIN);
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ class SystemMainHandler extends SystemHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class SystemCheckConnHandler extends ConnectionHandler {
|
class SystemCheckConnHandler extends ConnectionHandler {
|
||||||
id: any;
|
id: string;
|
||||||
|
|
||||||
async prepare() {
|
async prepare() {
|
||||||
this.checkPriv(PRIV.PRIV_EDIT_SYSTEM);
|
this.checkPriv(PRIV.PRIV_EDIT_SYSTEM);
|
||||||
|
|||||||
@@ -102,8 +102,8 @@ class TrainingDetailHandler extends Handler {
|
|||||||
problem.getList(domainId, pids, this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN)),
|
problem.getList(domainId, pids, this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN)),
|
||||||
]);
|
]);
|
||||||
const psdict = await problem.getListStatus(domainId, this.user._id, pids);
|
const psdict = await problem.getListStatus(domainId, this.user._id, pids);
|
||||||
const donePids = new Set();
|
const donePids = new Set<number>();
|
||||||
const progPids = new Set();
|
const progPids = new Set<number>();
|
||||||
for (const pid in psdict) {
|
for (const pid in psdict) {
|
||||||
const psdoc = psdict[pid];
|
const psdoc = psdict[pid];
|
||||||
if (psdoc.status) {
|
if (psdoc.status) {
|
||||||
@@ -114,7 +114,7 @@ class TrainingDetailHandler extends Handler {
|
|||||||
}
|
}
|
||||||
const nsdict = {};
|
const nsdict = {};
|
||||||
const ndict = {};
|
const ndict = {};
|
||||||
const doneNids = new Set();
|
const doneNids = new Set<number>();
|
||||||
for (const node of tdoc.dag) {
|
for (const node of tdoc.dag) {
|
||||||
ndict[node._id] = node;
|
ndict[node._id] = node;
|
||||||
const totalCount = node.pids.length;
|
const totalCount = node.pids.length;
|
||||||
@@ -174,13 +174,9 @@ class TrainingCreateHandler extends Handler {
|
|||||||
_dag: string, description: string,
|
_dag: string, description: string,
|
||||||
) {
|
) {
|
||||||
const dag = await _parseDagJson(domainId, _dag);
|
const dag = await _parseDagJson(domainId, _dag);
|
||||||
const pids = training.getPids({ dag });
|
const pids = training.getPids(dag);
|
||||||
assert(pids.length, new ValidationError('dag'));
|
assert(pids.length, new ValidationError('dag'));
|
||||||
const pdocs = await problem.getMulti(domainId, {
|
const pdocs = await problem.getMulti(domainId, { docId: { $in: pids } }).sort('_id', 1).toArray();
|
||||||
// TODO
|
|
||||||
// @ts-ignore
|
|
||||||
$or: [{ docId: { $in: pids } }, { pid: { $in: pids } }],
|
|
||||||
}).sort('_id', 1).toArray();
|
|
||||||
const existPids = pdocs.map((pdoc) => pdoc.docId);
|
const existPids = pdocs.map((pdoc) => pdoc.docId);
|
||||||
const existPnames = pdocs.map((pdoc) => pdoc.pid);
|
const existPnames = pdocs.map((pdoc) => pdoc.pid);
|
||||||
if (pids.length !== existPids.length) {
|
if (pids.length !== existPids.length) {
|
||||||
@@ -235,7 +231,7 @@ class TrainingEditHandler extends Handler {
|
|||||||
_dag: string, description: string,
|
_dag: string, description: string,
|
||||||
) {
|
) {
|
||||||
const dag = await _parseDagJson(domainId, _dag);
|
const dag = await _parseDagJson(domainId, _dag);
|
||||||
const pids = training.getPids({ dag });
|
const pids = training.getPids(dag);
|
||||||
assert(pids.length, new ValidationError('dag'));
|
assert(pids.length, new ValidationError('dag'));
|
||||||
const pdocs = await problem.getMulti(domainId, {
|
const pdocs = await problem.getMulti(domainId, {
|
||||||
$or: [
|
$or: [
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export interface Udoc extends Dictionary<any> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface User extends Dictionary<any> {
|
export interface User extends Dictionary<any> {
|
||||||
udoc: () => any,
|
udoc: () => Udoc,
|
||||||
dudoc: () => any,
|
dudoc: () => any,
|
||||||
_id: number,
|
_id: number,
|
||||||
mail: string,
|
mail: string,
|
||||||
@@ -211,6 +211,13 @@ export interface ScoreboardNode {
|
|||||||
|
|
||||||
export type PenaltyRules = Dictionary<number>;
|
export type PenaltyRules = Dictionary<number>;
|
||||||
|
|
||||||
|
export interface TrainingNode {
|
||||||
|
_id: number,
|
||||||
|
title: string,
|
||||||
|
requireNids: number[],
|
||||||
|
pids: number[],
|
||||||
|
}
|
||||||
|
|
||||||
export interface Tdoc {
|
export interface Tdoc {
|
||||||
_id: ObjectID,
|
_id: ObjectID,
|
||||||
domainId: string,
|
domainId: string,
|
||||||
@@ -230,7 +237,13 @@ export interface Tdoc {
|
|||||||
penaltyRules?: PenaltyRules,
|
penaltyRules?: PenaltyRules,
|
||||||
|
|
||||||
// For training
|
// For training
|
||||||
dag: any
|
description?: string,
|
||||||
|
dag?: TrainingNode[],
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface TrainingDoc extends Tdoc {
|
||||||
|
description: string,
|
||||||
|
dag: TrainingNode[],
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DomainDoc extends Dictionary<any> {
|
export interface DomainDoc extends Dictionary<any> {
|
||||||
@@ -365,7 +378,7 @@ export interface JudgeResultBody {
|
|||||||
stderr?: string,
|
stderr?: string,
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PathComponent = [string, string, any?, boolean?];
|
export type PathComponent = [string, string, Dictionary<any>?, boolean?];
|
||||||
|
|
||||||
export interface Model {
|
export interface Model {
|
||||||
blacklist: typeof import('./model/blacklist'),
|
blacklist: typeof import('./model/blacklist'),
|
||||||
|
|||||||
@@ -533,6 +533,11 @@ export const LANG_HIGHLIGHT_ID = {
|
|||||||
rb: 'ruby',
|
rb: 'ruby',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export function registerLanguage(id: string, display: string, highlight: string) {
|
||||||
|
LANG_TEXTS[id] = display;
|
||||||
|
LANG_HIGHLIGHT_ID[id] = highlight;
|
||||||
|
}
|
||||||
|
|
||||||
export const STATUS = {
|
export const STATUS = {
|
||||||
STATUS_WAITING: 0,
|
STATUS_WAITING: 0,
|
||||||
STATUS_ACCEPTED: 1,
|
STATUS_ACCEPTED: 1,
|
||||||
@@ -618,6 +623,7 @@ export const CONSTANT = {
|
|||||||
|
|
||||||
global.Hydro.model.builtin = {
|
global.Hydro.model.builtin = {
|
||||||
Permission,
|
Permission,
|
||||||
|
registerLanguage,
|
||||||
PERM,
|
PERM,
|
||||||
PERMS,
|
PERMS,
|
||||||
PERMS_BY_FAMILY,
|
PERMS_BY_FAMILY,
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ export async function getVnode(domainId: string, type: number, id: string) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (type === document.TYPE_TRAINING) {
|
if (type === document.TYPE_TRAINING) {
|
||||||
const tdoc = await training.get(domainId, id);
|
const tdoc = await training.get(domainId, new ObjectID(id));
|
||||||
return { ...tdoc, type, id };
|
return { ...tdoc, type, id };
|
||||||
}
|
}
|
||||||
if (type === document.TYPE_HOMEWORK) {
|
if (type === document.TYPE_HOMEWORK) {
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
import { ObjectID } from 'mongodb';
|
import { FilterQuery, ObjectID } from 'mongodb';
|
||||||
|
import { flatten } from 'lodash';
|
||||||
import * as document from './document';
|
import * as document from './document';
|
||||||
import { TrainingNotFoundError, TrainingAlreadyEnrollError } from '../error';
|
import { TrainingNotFoundError, TrainingAlreadyEnrollError } from '../error';
|
||||||
|
import { TrainingDoc, TrainingNode } from '../interface';
|
||||||
|
|
||||||
export function getStatus(domainId: string, tid: ObjectID, uid: number) {
|
export function getStatus(domainId: string, tid: ObjectID, uid: number) {
|
||||||
return document.getStatus(domainId, document.TYPE_TRAINING, tid, uid);
|
return document.getStatus(domainId, document.TYPE_TRAINING, tid, uid);
|
||||||
@@ -34,7 +36,7 @@ export function setStatus(domainId: string, tid: ObjectID, uid: number, $set: an
|
|||||||
|
|
||||||
export function add(
|
export function add(
|
||||||
domainId: string, title: string, content: string,
|
domainId: string, title: string, content: string,
|
||||||
owner: number, dag = [], description = '',
|
owner: number, dag: TrainingNode[] = [], description = '',
|
||||||
) {
|
) {
|
||||||
return document.add(domainId, content, owner, document.TYPE_TRAINING, null, null, null, {
|
return document.add(domainId, content, owner, document.TYPE_TRAINING, null, null, null, {
|
||||||
dag,
|
dag,
|
||||||
@@ -44,24 +46,20 @@ export function add(
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export function edit(domainId: string, tid: ObjectID, $set) {
|
export function edit(domainId: string, tid: ObjectID, $set: Partial<TrainingDoc>) {
|
||||||
return document.set(domainId, document.TYPE_TRAINING, tid, $set);
|
return document.set(domainId, document.TYPE_TRAINING, tid, $set);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getPids(tdoc): number[] {
|
export function getPids(dag: TrainingNode[]) {
|
||||||
const pids: Set<number> = new Set();
|
return Array.from(new Set(flatten(dag.map((node) => node.pids))));
|
||||||
for (const node of tdoc.dag) {
|
|
||||||
for (const pid of node.pids) pids.add(pid);
|
|
||||||
}
|
|
||||||
return Array.from(pids);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isDone(node, doneNids, donePids) {
|
export function isDone(node: TrainingNode, doneNids: Set<number> | number[], donePids: Set<number> | number[]) {
|
||||||
return (Set.isSuperset(new Set(doneNids), new Set(node.requireNids))
|
return (Set.isSuperset(new Set(doneNids), new Set(node.requireNids))
|
||||||
&& Set.isSuperset(new Set(donePids), new Set(node.pids)));
|
&& Set.isSuperset(new Set(donePids), new Set(node.pids)));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isProgress(node, doneNids, donePids, progPids) {
|
export function isProgress(node: TrainingNode, doneNids: Set<number> | number[], donePids: Set<number> | number[], progPids: Set<number> | number[]) {
|
||||||
return (Set.isSuperset(new Set(doneNids), new Set(node.requireNids))
|
return (Set.isSuperset(new Set(doneNids), new Set(node.requireNids))
|
||||||
&& !Set.isSuperset(new Set(donePids), new Set(node.pids))
|
&& !Set.isSuperset(new Set(donePids), new Set(node.pids))
|
||||||
&& Set.intersection(
|
&& Set.intersection(
|
||||||
@@ -70,7 +68,7 @@ export function isProgress(node, doneNids, donePids, progPids) {
|
|||||||
).size);
|
).size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isOpen(node, doneNids, donePids, progPids) {
|
export function isOpen(node: TrainingNode, doneNids: Set<number> | number[], donePids: Set<number> | number[], progPids: Set<number> | number[]) {
|
||||||
return (Set.isSuperset(new Set(doneNids), new Set(node.requireNids))
|
return (Set.isSuperset(new Set(doneNids), new Set(node.requireNids))
|
||||||
&& !Set.isSuperset(new Set(donePids), new Set(node.pids))
|
&& !Set.isSuperset(new Set(donePids), new Set(node.pids))
|
||||||
&& !Set.intersection(
|
&& !Set.intersection(
|
||||||
@@ -79,13 +77,14 @@ export function isOpen(node, doneNids, donePids, progPids) {
|
|||||||
).size);
|
).size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const isInvalid = (node, doneNids) =>
|
export const isInvalid = (node: TrainingNode, doneNids: Set<number> | number[]) =>
|
||||||
!Set.isSuperset(new Set(doneNids), new Set(node.requireNids));
|
!Set.isSuperset(new Set(doneNids), new Set(node.requireNids));
|
||||||
|
|
||||||
export const count = (domainId: string, query: any) =>
|
export async function count(domainId: string, query: FilterQuery<TrainingDoc>) {
|
||||||
document.count(domainId, document.TYPE_TRAINING, query);
|
return await document.count(domainId, document.TYPE_TRAINING, query);
|
||||||
|
}
|
||||||
|
|
||||||
export async function get(domainId, tid) {
|
export async function get(domainId: string, tid: ObjectID) {
|
||||||
const tdoc = await document.get(domainId, document.TYPE_TRAINING, tid);
|
const tdoc = await document.get(domainId, document.TYPE_TRAINING, tid);
|
||||||
if (!tdoc) throw new TrainingNotFoundError(tid);
|
if (!tdoc) throw new TrainingNotFoundError(tid);
|
||||||
for (const i in tdoc.dag) {
|
for (const i in tdoc.dag) {
|
||||||
@@ -107,7 +106,7 @@ export async function getList(domainId: string, tids: ObjectID[]) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getMulti = (domainId: string, query: any = {}) =>
|
export const getMulti = (domainId: string, query: FilterQuery<TrainingDoc> = {}) =>
|
||||||
document.getMulti(domainId, document.TYPE_TRAINING, query).sort('_id', 1);
|
document.getMulti(domainId, document.TYPE_TRAINING, query).sort('_id', 1);
|
||||||
|
|
||||||
global.Hydro.model.training = {
|
global.Hydro.model.training = {
|
||||||
|
|||||||
Reference in new issue
Block a user