mirror of
https://gitcode.com/gh_mirrors/hy/Hydro.git
synced 2026-10-19 09:38:19 +08:00
core&ui: contest: acm: lock scoreboard
This commit is contained in:
1 parent
cb02b8dafe
commit
e67ff511bb
17 files changed
+224
-196
No files matched your search
@@ -47,13 +47,18 @@ registerResolver(
|
||||
'Get a contest by ID',
|
||||
);
|
||||
|
||||
TaskModel.Worker.addHandler('contest.problemHide', async (doc) => {
|
||||
TaskModel.Worker.addHandler('contest', async (doc) => {
|
||||
const tdoc = await contest.get(doc.domainId, doc.tid);
|
||||
if (!tdoc) return;
|
||||
for (const pid of tdoc.pids) {
|
||||
// eslint-disable-next-line no-await-in-loop
|
||||
await problem.edit(doc.domainId, pid, { hidden: false });
|
||||
const tasks = [];
|
||||
for (const op of doc.operation) {
|
||||
if (op === 'unhide') {
|
||||
for (const pid of tdoc.pids) {
|
||||
tasks.push(problem.edit(doc.domainId, pid, { hidden: false }));
|
||||
}
|
||||
} else if (op === 'unlock') tasks.push(contest.recalcStatus(doc.domainId, doc.tid));
|
||||
}
|
||||
await Promise.all(tasks);
|
||||
});
|
||||
|
||||
export class ContestListHandler extends Handler {
|
||||
@@ -129,7 +134,7 @@ export class ContestDetailHandler extends Handler {
|
||||
if (!this.user.own(tdoc)) this.checkPerm(PERM.PERM_EDIT_CONTEST);
|
||||
await contest.del(domainId, tid);
|
||||
await TaskModel.deleteMany({
|
||||
type: 'schedule', subType: 'contest.problemHide', domainId, tid,
|
||||
type: 'schedule', subType: 'contest', domainId, tid,
|
||||
});
|
||||
this.response.redirect = this.url('contest_main');
|
||||
}
|
||||
@@ -167,8 +172,13 @@ export class ContestBroadcastHandler extends Handler {
|
||||
export class ContestScoreboardHandler extends Handler {
|
||||
@param('tid', Types.ObjectID)
|
||||
@param('page', Types.PositiveInt, true)
|
||||
async get(domainId: string, tid: ObjectID, page = 1) {
|
||||
const [tdoc, rows, udict, , nPages] = await contest.getScoreboard.call(this, domainId, tid, false, page);
|
||||
@param('ignoreLock', Types.Boolean, true)
|
||||
async get(domainId: string, tid: ObjectID, page = 1, ignoreLock = false) {
|
||||
const tdoc = await contest.get(domainId, tid);
|
||||
if (ignoreLock && !this.user.own(tdoc)) {
|
||||
this.checkPerm(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD);
|
||||
}
|
||||
const [, rows, udict, , nPages] = await contest.getScoreboard.call(this, domainId, tid, false, page, ignoreLock);
|
||||
const path = [
|
||||
['Hydro', 'homepage'],
|
||||
['contest_main', 'contest_main'],
|
||||
@@ -185,13 +195,18 @@ export class ContestScoreboardHandler extends Handler {
|
||||
export class ContestScoreboardDownloadHandler extends Handler {
|
||||
@param('tid', Types.ObjectID)
|
||||
@param('ext', Types.Range(['csv', 'html']))
|
||||
async get(domainId: string, tid: ObjectID, ext: string) {
|
||||
@param('ignoreLock', Types.Boolean, true)
|
||||
async get(domainId: string, tid: ObjectID, ext: string, ignoreLock = false) {
|
||||
await this.limitRate('scoreboard_download', 120, 3);
|
||||
const getContent = {
|
||||
csv: async (rows) => `\uFEFF${rows.map((c) => (c.map((i) => i.value).join(','))).join('\n')}`,
|
||||
html: (rows, tdoc) => this.renderHTML('contest_scoreboard_download_html.html', { rows, tdoc }),
|
||||
};
|
||||
const [tdoc, rows] = await contest.getScoreboard.call(this, domainId, tid, true, 0);
|
||||
const tdoc = await contest.get(domainId, tid);
|
||||
if (ignoreLock && !this.user.own(tdoc)) {
|
||||
this.checkPerm(PERM.PERM_VIEW_CONTEST_HIDDEN_SCOREBOARD);
|
||||
}
|
||||
const [, rows] = await contest.getScoreboard.call(this, domainId, tid, true, 0, ignoreLock);
|
||||
this.binary(await getContent[ext](rows, tdoc), `${tdoc.title}.${ext}`);
|
||||
}
|
||||
}
|
||||
@@ -240,10 +255,11 @@ export class ContestEditHandler extends Handler {
|
||||
@param('code', Types.String, true)
|
||||
@param('autoHide', Types.String, true)
|
||||
@param('assign', Types.CommaSeperatedArray, true)
|
||||
@param('lock', Types.UnsignedInt, true)
|
||||
async post(
|
||||
domainId: string, tid: ObjectID, beginAtDate: string, beginAtTime: string, duration: number,
|
||||
title: string, content: string, rule: string, _pids: string, rated = false,
|
||||
_code = '', autoHide = false, assign: string[] = null,
|
||||
_code = '', autoHide = false, assign: string[] = null, lock: number = null,
|
||||
) {
|
||||
if (autoHide) this.checkPerm(PERM.PERM_EDIT_PROBLEM);
|
||||
const pids = _pids.replace(/,/g, ',').split(',').map((i) => +i).filter((i) => i);
|
||||
@@ -252,20 +268,22 @@ export class ContestEditHandler extends Handler {
|
||||
const endAt = beginAtMoment.clone().add(duration, 'hours').toDate();
|
||||
if (beginAtMoment.isSameOrAfter(endAt)) throw new ValidationError('duration');
|
||||
const beginAt = beginAtMoment.toDate();
|
||||
const lockAt = lock ? moment(endAt).add(-lock, 'minutes').toDate() : null;
|
||||
await problem.getList(domainId, pids, this.user.hasPerm(PERM.PERM_VIEW_PROBLEM_HIDDEN) || this.user._id, this.user.group, true);
|
||||
if (tid) {
|
||||
await contest.edit(domainId, tid, {
|
||||
title, content, rule, beginAt, endAt, pids, rated,
|
||||
});
|
||||
if (this.tdoc.beginAt !== beginAt || this.tdoc.endAt !== endAt
|
||||
|| Array.isDiff(this.tdoc.pids, pids) || this.tdoc.rule !== rule) {
|
||||
|| Array.isDiff(this.tdoc.pids, pids) || this.tdoc.rule !== rule
|
||||
|| lockAt !== this.tdoc.lockAt) {
|
||||
await contest.recalcStatus(domainId, this.tdoc.docId);
|
||||
}
|
||||
} else {
|
||||
tid = await contest.add(domainId, title, content, this.user._id, rule, beginAt, endAt, pids, rated);
|
||||
}
|
||||
const task = {
|
||||
type: 'schedule', subType: 'contest.problemHide', domainId, tid,
|
||||
type: 'schedule', subType: 'contest', domainId, tid,
|
||||
};
|
||||
await TaskModel.deleteMany(task);
|
||||
if (Date.now() <= endAt.getTime() && autoHide) {
|
||||
@@ -273,10 +291,20 @@ export class ContestEditHandler extends Handler {
|
||||
await Promise.all(pids.map((pid) => problem.edit(domainId, pid, { hidden: true })));
|
||||
await TaskModel.add({
|
||||
...task,
|
||||
operation: ['unhide'],
|
||||
executeAfter: endAt,
|
||||
});
|
||||
}
|
||||
await contest.edit(domainId, tid, { assign, _code, autoHide });
|
||||
if (lock && lockAt <= endAt) {
|
||||
await TaskModel.add({
|
||||
...task,
|
||||
operation: ['unlock'],
|
||||
executeAfter: endAt,
|
||||
});
|
||||
}
|
||||
await contest.edit(domainId, tid, {
|
||||
assign, _code, autoHide, lockAt,
|
||||
});
|
||||
this.response.body = { tid };
|
||||
this.response.redirect = this.url('contest_detail', { tid });
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user