diff --git a/libs/submissions_process.js b/libs/submissions_process.js index 02b644f..30677cd 100644 --- a/libs/submissions_process.js +++ b/libs/submissions_process.js @@ -4,13 +4,24 @@ const getSubmissionInfo = (s, displayConfig) => ({ userId: s.user_id, problemName: s.problem.title, problemId: s.problem_id, - language: displayConfig.hideCode ? null : ((s.language != null && s.language !== '') ? syzoj.config.languages[s.language].show : null), - codeSize: displayConfig.hideCode ? null : syzoj.utils.formatSize(s.code.length), + language: displayConfig.showCode ? ((s.language != null && s.language !== '') ? syzoj.config.languages[s.language].show : null) : null, + codeSize: displayConfig.showCode ? syzoj.utils.formatSize(s.code.length) : null, submitTime: syzoj.utils.formatDate(s.submit_time), }); const getRoughResult = (x, displayConfig) => { - if (displayConfig.hideResult) { + if (displayConfig.showResult) { + if (x.pending) { + return null; + } else { + return { + result: x.status, + time: displayConfig.showUsage ? x.total_time : null, + memory: displayConfig.showUsage ? x.max_memory : null, + score: displayConfig.showUsage ? x.score : null + }; + } + } else { // 0: Waiting 1: Running if (x.status === "System Error") return { result: "System Error" }; @@ -23,18 +34,41 @@ const getRoughResult = (x, displayConfig) => { return { result: "Compile Error" }; } } - } else { - if (x.pending) { - return null; - } else { - return { - result: x.status, - time: displayConfig.hideUsage ? null : x.total_time, - memory: displayConfig.hideUsage ? null : x.max_memory, - score: displayConfig.hideUsage ? null : x.score - }; - } } } -module.exports = { getRoughResult, getSubmissionInfo }; \ No newline at end of file +const processOverallResult = (source, config) => { + if (source == null) + return null; + if (source.error != null) { + return { + error: source.error, + systemMessage: source.systemMessage + }; + } + return { + compile: source.compile, + judge: config.showDetailResult ? (source.judge && { + subtasks: source.judge.subtasks && source.judge.subtasks.map(st => ({ + score: st.score, + cases: st.cases.map(cs => ({ + status: cs.status, + result: cs.result && { + type: cs.result.type, + time: config.showUsage ? cs.result.time : undefined, + memory: config.showUsage ? cs.result.memory : undefined, + scoringRate: cs.result.scoringRate, + systemMessage: cs.result.systemMessage, + input: config.showTestdata ? cs.result.input : undefined, + output: config.showTestdata ? cs.result.output : undefined, + userOutput: config.showTestdata ? cs.result.userOutput : undefined, + userError: config.showTestdata ? cs.result.userError : undefined, + spjMessage: config.showTestdata ? cs.result.spjMessage : undefined, + } + })) + })) + }) : null + }; +} + +module.exports = { getRoughResult, getSubmissionInfo, processOverallResult }; \ No newline at end of file diff --git a/modules/contest.js b/modules/contest.js index f7796d9..1b36266 100644 --- a/modules/contest.js +++ b/modules/contest.js @@ -27,7 +27,7 @@ let JudgeState = syzoj.model('judge_state'); let User = syzoj.model('user'); const jwt = require('jsonwebtoken'); -const { getSubmissionInfo, getRoughResult } = require('../libs/submissions_process'); +const { getSubmissionInfo, getRoughResult, processOverallResult } = require('../libs/submissions_process'); app.get('/contests', async (req, res) => { try { @@ -263,14 +263,14 @@ app.get('/contest/:id/ranklist', async (req, res) => { }); function getDisplayConfig(contest) { - const hideResult = !contest.allowedSeeingResult(); return { - hideScore: !contest.allowedSeeingScore(), - hideUsage: true, - hideCode: true, - hideResult: hideResult, - hideOthers: !contest.allowedSeeingOthers(), + showScore: contest.allowedSeeingScore(), + showUsage: false, + showCode: false, + showResult: contest.allowedSeeingResult(), + showOthers: contest.allowedSeeingOthers(), showDetailResult: contest.allowedSeeingTestcase(), + showTestdata: false, inContest: true }; } @@ -292,19 +292,19 @@ app.get('/contest/:id/submissions', async (req, res) => { let user = req.query.submitter && await User.fromName(req.query.submitter); let where = {}; - if (displayConfig.hideOthers) { + if (displayConfig.showOthers) { + if (user) { + where.user_id = user.id; + } + } else { if (curUser == null || // Not logined (user && user.id !== curUser.id)) { // Not querying himself throw new ErrorMessage("您没有权限执行此操作"); } where.user_id = curUser.id; - } else { - if (user) { - where.user_id = user.id; - } } - if (!displayConfig.hideScore) { + if (displayConfig.showScore) { let minScore = parseInt(req.query.min_score); let maxScore = parseInt(req.query.max_score); @@ -325,7 +325,7 @@ app.get('/contest/:id/submissions', async (req, res) => { else where.language = req.query.language; } - if (!displayConfig.hideResult) { + if (displayConfig.showResult) { if (req.query.status) where.status = { $like: req.query.status + '%' }; } @@ -342,7 +342,7 @@ app.get('/contest/:id/submissions', async (req, res) => { obj.problem.title = syzoj.utils.removeTitleTag(obj.problem.title); }); - const pushType = hideResult ? 'compile' : 'rough'; + const pushType = displayConfig.showResult ? 'rough' : 'compile'; res.render('submissions', { contest: contest, items: judge_state.map(x => ({ @@ -358,6 +358,7 @@ app.get('/contest/:id/submissions', async (req, res) => { paginate: paginate, form: req.query, displayConfig: displayConfig, + pushType: pushType }); } catch (e) { syzoj.log(e); @@ -370,42 +371,44 @@ app.get('/contest/:id/submissions', async (req, res) => { app.get('/contest/submission/:id', async (req, res) => { try { - let id = parseInt(req.params.id); - let judge = await JudgeState.fromID(id); - if (!judge || !await judge.isAllowedVisitBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。'); - - let contest; - if (judge.type === 1) { - contest = await Contest.fromID(judge.type_info); - contest.ended = contest.isEnded(); - let problems_id = await contest.getProblems(); - judge.problem_id = problems_id.indexOf(judge.problem_id) + 1; - judge.problem.title = syzoj.utils.removeTitleTag(judge.problem.title); - - if (!contest.ended && !await judge.problem.isAllowedEditBy(res.locals.user)) { - throw new Error("对不起,在比赛结束之前,您不能查看评测结果。"); - } + const id = parseInt(req.params.id); + const judge = await JudgeState.fromID(id); + if (!judge) throw new ErrorMessage("提交记录 ID 不正确。"); + const curUser = res.locals.user; + if ((!curUser) || judge.user_id !== curUser.id) throw new ErrorMessage("您没有权限执行此操作。"); + + if (judge.type !== 1) { + return res.redirect(syzoj.utils.makeUrl(['submission', id])); } + const contest = await Contest.fromID(judge.type_info); + contest.ended = contest.isEnded(); + + const displayConfig = getDisplayConfig(contest); + displayConfig.showCode = true; + await judge.loadRelationships(); + const problems_id = await contest.getProblems(); + judge.problem_id = problems_id.indexOf(judge.problem_id) + 1; + judge.problem.title = syzoj.utils.removeTitleTag(judge.problem.title); if (judge.problem.type !== 'submit-answer') { judge.codeLength = judge.code.length; judge.code = await syzoj.utils.highlight(judge.code, syzoj.config.languages[judge.language].highlight); } - judge.allowedRejudge = await judge.problem.isAllowedEditBy(res.locals.user); - judge.allowedManage = await judge.problem.isAllowedManageBy(res.locals.user); - res.render('submission', { - info: getSubmissionInfo(judge), - roughResult: getRoughResult(judge), - code: (judge.problem.type !== 'submit-answer') ? judge.code.toString("utf8") : '', - detailResult: judge.result, - socketToken: judge.pending ? jwt.sign({ + info: getSubmissionInfo(judge, displayConfig), + roughResult: getRoughResult(judge, displayConfig), + code: (displayConfig.showCode && judge.problem.type !== 'submit-answer') ? judge.code.toString("utf8") : '', + detailResult: processOverallResult(judge.result, displayConfig), + socketToken: (displayConfig.showDetailResult && judge.pending) ? jwt.sign({ taskId: judge.id, + displayConfig: displayConfig, type: 'detail' - }, syzoj.config.judge_token) : null + }, syzoj.config.judge_token) : null, + displayConfig: displayConfig, + contest: contest }); } catch (e) { syzoj.log(e); diff --git a/modules/submission.js b/modules/submission.js index 87ed11e..4b38cfc 100644 --- a/modules/submission.js +++ b/modules/submission.js @@ -24,7 +24,18 @@ let User = syzoj.model('user'); let Contest = syzoj.model('contest'); const jwt = require('jsonwebtoken'); -const { getSubmissionInfo, getRoughResult } = require('../libs/submissions_process'); +const { getSubmissionInfo, getRoughResult, processOverallResult } = require('../libs/submissions_process'); + +const displayConfig = { + showScore: true, + showUsage: true, + showCode: true, + showResult: true, + showOthers: true, + showTestdata: true, + showDetailResult: true, + inContest: false, +}; // s is JudgeState app.get('/submissions', async (req, res) => { @@ -93,15 +104,6 @@ app.get('/submissions', async (req, res) => { await judge_state.forEachAsync(async obj => obj.loadRelationships()); - const displayConfig = { - hideScore: false, - hideUsage: false, - hideCode: false, - hideResult: false, - hideOthers: false, - inContest: false, - showDetailResult: true - }; res.render('submissions', { // judge_state: judge_state, items: judge_state.map(x => ({ @@ -129,17 +131,15 @@ app.get('/submissions', async (req, res) => { app.get('/submission/:id', async (req, res) => { try { - let id = parseInt(req.params.id); - let judge = await JudgeState.fromID(id); - if (!judge || !await judge.isAllowedVisitBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。'); + const id = parseInt(req.params.id); + const judge = await JudgeState.fromID(id); + if (!judge) throw new ErrorMessage("提交记录 ID 不正确。"); + if (!await judge.isAllowedVisitBy(res.locals.user)) throw new ErrorMessage('您没有权限进行此操作。'); let contest; if (judge.type === 1) { contest = await Contest.fromID(judge.type_info); contest.ended = contest.isEnded(); - let problems_id = await contest.getProblems(); - judge.problem_id = problems_id.indexOf(judge.problem_id) + 1; - judge.problem.title = syzoj.utils.removeTitleTag(judge.problem.title); if (!contest.ended && !await judge.problem.isAllowedEditBy(res.locals.user)) { throw new Error("对不起,在比赛结束之前,您不能查看评测结果。"); @@ -157,14 +157,16 @@ app.get('/submission/:id', async (req, res) => { judge.allowedManage = await judge.problem.isAllowedManageBy(res.locals.user); res.render('submission', { - info: getSubmissionInfo(judge), - roughResult: getRoughResult(judge), + info: getSubmissionInfo(judge, displayConfig), + roughResult: getRoughResult(judge, displayConfig), code: (judge.problem.type !== 'submit-answer') ? judge.code.toString("utf8") : '', - detailResult: judge.result, + detailResult: processOverallResult(judge.result, displayConfig), socketToken: judge.pending ? jwt.sign({ taskId: judge.id, - type: 'detail' - }, syzoj.config.judge_token) : null + type: 'detail', + displayConfig: displayConfig + }, syzoj.config.judge_token) : null, + displayConfig: displayConfig }); } catch (e) { syzoj.log(e); diff --git a/views/submission.ejs b/views/submission.ejs index 977eeb3..bb4976d 100644 --- a/views/submission.ejs +++ b/views/submission.ejs @@ -1,5 +1,263 @@ <% this.title = '提交记录 #' + info.taskId %> +<% include util %> <% include header %> -<% include submission_content %> + +
+ + + + + + + + + + + + + + + + + +
编号题目状态分数总时间内存代码 / 答案文件提交者提交时间
+ + + + + +
+ +
+
+ + + + +<% include submissions_item %> + + + + +
<% include footer %> \ No newline at end of file diff --git a/views/submission_content.ejs b/views/submission_content.ejs deleted file mode 100644 index 364c6b7..0000000 --- a/views/submission_content.ejs +++ /dev/null @@ -1,247 +0,0 @@ -<% include util %> - -
- - - - - - - - - - - - - - - - - -
编号题目状态分数总时间内存代码 / 答案文件提交者提交时间
- - - - - -
- -
-
- - - - -<% include submissions_item %> - - - - diff --git a/views/submissions.ejs b/views/submissions.ejs index 3f3dca8..c58df40 100644 --- a/views/submissions.ejs +++ b/views/submissions.ejs @@ -6,23 +6,23 @@ <% if (displayConfig.inContest) { %>
比赛 - <%= contest.title %>
- <% if (displayConfig.hideOthers) { %> -

您只能看到自己的提交。

- <% } else { %> + <% if (displayConfig.showOthers) { %>

您可以看到其他人的提交。 + <% } else { %> +

您只能看到自己的提交。

<% } %>
<% } %> -
+
- <% if (!displayConfig.hideOthers) { %> + <% if (displayConfig.showOthers) { %>
<% } %> - <% if (!displayConfig.hideScore) { %> + <% if (displayConfig.showScore) { %>
@@ -43,7 +43,7 @@
- <% if (!displayConfig.hideResult) { %> + <% if (displayConfig.showResult) { %>
- - + + <% include submissions_item %> + @@ -46,18 +47,18 @@ Vue.component('submission-item', {