core&ui: contest correction mode

This commit is contained in:
undefined committed 2025-06-30 16:46:33 +08:00
1 parent a9215698f9
commit e479cb94ea
10 files changed
+56 -16

No files matched your search

+2 -2
View File
@@ -143,11 +143,11 @@ Hydro 用户群:1085853538
- framework: 添加 Subscription API
- core: 添加 fixStorage 脚本
- core: websocket: 重构 Subscription API
- ui: 允许跨页选择题目
- ui: 允许跨页选择题目,支持批量选择题目
- judge: 重构 config.detail 设置
- core: 自动清理多余的静态文件
- ui: 优化比赛题目列表显示
- core: 添加补题模式
### Bug Fixes
+10 -1
View File
@@ -207,9 +207,18 @@ export class ContestProblemListHandler extends ContestDetailBaseHandler {
const psdocs: any[] = Object.values(this.response.body.psdict);
const canViewRecord = contest.canShowSelfRecord.call(this, this.tdoc);
this.response.body.canViewRecord = canViewRecord;
const rids = psdocs.map((i) => i.rid);
if (contest.isDone(this.tdoc) && canViewRecord) {
const correction = await problem.getListStatus(domainId, this.user._id, this.tdoc.pids);
for (const pid in correction) {
if (this.tsdoc.detail[pid]?.rid === correction[pid].rid) delete correction[pid];
}
rids.push(...Object.values(correction).map((i) => i.rid));
this.response.body.correction = correction;
}
[this.response.body.rdict, this.response.body.rdocs] = canViewRecord
? await Promise.all([
record.getList(domainId, psdocs.map((i: any) => i.rid)),
record.getList(domainId, rids),
record.getMulti(domainId, { contest: tid, uid: this.user._id })
.sort({ _id: -1 }).toArray(),
])
+5 -1
View File
@@ -334,6 +334,10 @@ export class ProblemDetailHandler extends ContestDetailBaseHandler {
discussionCount: dcnt,
tdoc: this.tdoc,
owner_udoc: (tid && this.tdoc.owner !== this.pdoc.owner) ? await user.getById(domainId, this.tdoc.owner) : null,
mode: !tid ? 'normal'
: !this.tsdoc?.attend ? 'view'
: !contest.isDone(this.tdoc) ? 'contest'
: problem.canViewBy(this.pdoc, this.user) ? 'correction' : 'none',
};
if (this.tdoc && this.tsdoc) {
const fields = ['attend', 'startAt'];
@@ -802,7 +806,7 @@ export class ProblemFileDownloadHandler extends ProblemDetailHandler {
@param('filename', Types.Filename)
@param('noDisposition', Types.Boolean)
@query('tid', Types.ObjectId, true)
async get(domainId: string, type = 'additional_file', filename: string, noDisposition = false, tid: ObjectId) {
async get({ }, type = 'additional_file', filename: string, noDisposition = false, tid: ObjectId) {
if (!tid) this.checkPerm(PERM.PERM_VIEW_PROBLEM);
if (this.pdoc.reference) {
if (type === 'testdata') throw new ProblemIsReferencedError('download testdata');
+2
View File
@@ -223,6 +223,7 @@ Copy Selected: 复制选中
Copy WeChat Account: 复制微信号
Copy: 复制
Copyright Complaint: 版权申诉
Correction: 补题
CPU Info: CPU信息
Create a contest: 创建一个比赛
Create a Discussion: 创建一个讨论
@@ -914,6 +915,7 @@ Testdata: 测试数据
Text: 文本
The 'default' role applies to ALL REGISTERED USER.: default 角色作用于<b>所有已注册用户</b>
The contest is a flexible time contest. You need to complete the contest within a specified time after you attended.: 本场比赛采用灵活时间模式,你需要在参加后的指定时间内完成比赛。
The contest is ended. New submissions will be treated as correction submissions and will not be counted in the contest.: 比赛已经结束。新提交将被视为补题提交,不计入比赛成绩。
The group to join when user joining the domain.: 加入域时自动加入的小组。
The homework's deadline is due but in extension. You can still submit for this problem but your score will be penalized.: 作业已超过截止时间,但仍在延期时间内。您递交题目将无法获得全部分数。
The invitation code to enter to successfully join the domain. You can only use letters and numbers in the code and it should not be longer than 64 characters.: 加入此域的邀请码。您只能使用字母和数字,并且不能长于 64 个字符。
+2 -2
View File
@@ -110,7 +110,7 @@ $highlight-button-color = #F6DF45
width: auto
.page--contest_problemlist
.col--status
.col--status, .col--correction
width: rem(150px)
.col--submit-at
@@ -128,7 +128,7 @@ $highlight-button-color = #F6DF45
border-left: 1px solid $table-border-color
+mobile()
.col--submit-at
.col--submit-at, .col--correction
display: none
+tablet()
@@ -5,6 +5,7 @@
{% block content %}
{{ set(UiContext, 'tdoc', tdoc) }}
{{ set(UiContext, 'tsdoc', tsdoc) }}
{% set hasCorrection = correction and Object.keys(correction).length %}
<div class="row" data-sticky-parent>
<div class="medium-9 columns">
<div class="section">
@@ -27,7 +28,11 @@
<tr>
{% if handler.user.hasPriv(PRIV.PRIV_USER_PROFILE) %}
<th class="col--status record-status--border">{{ _('Status') }}</th>
<th class="col--submit-at">{{ _('Last Submit At') }}</th>
{% if hasCorrection %}
<th class="col--correction">{{ _('Correction') }}</th>
{% else %}
<th class="col--submit-at">{{ _('Last Submit At') }}</th>
{% endif %}
{% endif %}
{% if showScore %}
<th class="col--score">{{ _('Score') }}</th>
@@ -47,10 +52,21 @@
{% else %}
<td class="col--status record-status--border"><a href="{{ url('record_detail', rid=rdoc._id) }}">{{ _('Submitted') }}</a></td>
{% endif %}
<td class="col--submit-at">{{ datetimeSpan(rdoc._id)|safe }}</td>
{% if not hasCorrection %}
<td class="col--submit-at">{{ datetimeSpan(rdoc._id)|safe }}</td>
{% endif %}
{% else %}
<td class="col--status record-status--border">{{ _('No Submissions') }}</td>
<td class="col--submit-at">-</td>
{% if not hasCorrection %}
<td class="col--submit-at">-</td>
{% endif %}
{% endif %}
{% if hasCorrection %}
{% if correction[pid] %}
{{ record.render_status_td(rdict[correction[pid].rid], class="col--correction") }}
{% else %}
<td class="col--correction">-</td>
{% endif %}
{% endif %}
{% endif %}
{% if showScore %}
@@ -14,10 +14,16 @@
<p>{{ _('No submission language available for this problem.') }}</p>
</blockquote>
{% endif %}
{% if tdoc and tdoc.docType == model.document.TYPE_CONTEST and model.contest.isDone(tdoc) %}
{% if tdoc and tdoc.docType == model.document.TYPE_CONTEST %}
{% if mode == 'view' %}
<blockquote class="note">
<p>{{ _('You cannot submit for this problem because the contest is ended. You can click "Open in Problem Set" to view this problem in normal mode.') }}</p>
</blockquote>
{% elif mode == 'correction' %}
<blockquote class="note">
<p>{{ _('The contest is ended. New submissions will be treated as correction submissions and will not be counted in the contest.') }}</p>
</blockquote>
{% endif %}
{% endif %}
{% if not renderredContent %}
{% set preferredLang = handler.request.query.lang or handler.user.viewLang or handler.session.viewLang %}
@@ -7,7 +7,7 @@
{% endif %}
<div>
<ol class="menu">
{% if model.contest.isOngoing(tdoc, tsdoc) %}
{% if mode == 'contest' or mode == 'correction' %}
{% if page_name == 'contest_detail_problem' %}
<li class="menu__item scratchpad--hide nojs--hide"><a class="menu__link highlight" name="problem-sidebar__open-scratchpad" href="javascript:;" data-global-hotkey="alt+e">
<span class="icon icon-enlarge"></span> {{ _('Open Scratchpad') }} (Alt+E)
@@ -20,10 +20,11 @@
<span class="icon icon-flag"></span> {{ _('View Problem') }}
</a></li>
{% endif %}
<li class="menu__item scratchpad--hide"><a class="menu__link{% if page_name == 'contest_detail_problem_submit' %} active{% endif %}" href="{{ url('problem_submit', pid=pdoc.pid|default(pdoc.docId), query={tid:tdoc.docId}) }}">
<li class="menu__item scratchpad--hide"><a class="menu__link{% if page_name == 'contest_detail_problem_submit' %} active{% endif %}" href="{{ url('problem_submit', pid=pdoc.pid|default(pdoc.docId), query={tid:tdoc.docId} if mode=='contest' else {}) }}">
<span class="icon icon-send"></span> {{ _('Submit') }}
</a></li>
{% elif model.contest.isDone(tdoc) %}
{% endif %}
{% if mode != 'none' and model.contest.isDone(tdoc) %}
<li class="menu__item"><a class="menu__link" href="{{ url('problem_detail', pid=pdoc.pid|default(pdoc.docId)) }}">
<span class="icon icon-send"></span> {{ _('Open in Problem Set') }}
</a></li>
@@ -28,7 +28,7 @@
<li class="menu__seperator"></li>
{% endif %}
{% if page_name == 'problem_detail' %}
{% if handler.user.hasPerm(perm.PERM_SUBMIT_PROBLEM) %}
{% if handler.user.hasPerm(perm.PERM_SUBMIT_PROBLEM) and handler.ctx.setting.get('ui-default.enableScratchpad') %}
<li class="menu__item scratchpad--hide nojs--hide"><a class="menu__link highlight" name="problem-sidebar__open-scratchpad" href="javascript:;" data-global-hotkey="alt+e">
<span class="icon icon-enlarge"></span> {{ _('Open Scratchpad') }} (Alt+E)
</a></li>
@@ -9,13 +9,15 @@
pdoc: pdoc
}) }}
{% if tdoc %}
{{ set(UiContext, 'tdoc', tdoc) }}
{{ set(UiContext, 'tsdoc', tsdoc) }}
{% endif %}
{% if tdoc and mode == 'contest' %}
{{ set(UiContext, 'canViewRecord', model.contest.canShowSelfRecord.call(handler, tdoc)) }}
{{ set(UiContext, 'postSubmitUrl', url('problem_submit', pid=pdoc.docId, query={tid:tdoc.docId})) }}
{{ set(UiContext, 'getSubmissionsUrl', url('record_main', query={fullStatus:'true', pid:pdoc.docId, tid:tdoc.docId})) }}
{{ set(UiContext, 'getRecordDetailUrl', url('record_detail', rid='{rid}', query={tid:tdoc.docId})) }}
{{ set(UiContext, 'pretestConnUrl', "record-conn?pretest=1&uidOrName=" + handler.user._id + "&pid=" + pdoc.docId + "&domainId=" + handler.args.domainId + "&tid=" + tdoc.docId) }}
{{ set(UiContext, 'tdoc', tdoc) }}
{{ set(UiContext, 'tsdoc', tsdoc) }}
{% else %}
{{ set(UiContext, 'canViewRecord', true) }}
{{ set(UiContext, 'postSubmitUrl', url('problem_submit', pid=pdoc.docId)) }}