Compare commits

..

No commits in common. 'master' and 'feature/unlimited-reply' have entirely different histories.

  1. 29
      libs/judger.js
  2. 1
      libs/submissions_process.js
  3. 1
      models-built/contest_player.js.map
  4. 3
      models/contest_player.ts
  5. 3
      models/judge_state.ts
  6. 4
      modules/contest.js
  7. 21
      modules/practice.js
  8. 2
      modules/problem.js
  9. 4
      views/admin_classify.ejs
  10. 4
      views/header.ejs
  11. 1
      views/submission.ejs
  12. 1
      views/submission_contest.ejs
  13. 46
      views/submission_practice.ejs
  14. 1
      views/submissions.ejs
  15. 21
      views/submissions_item.ejs

29
libs/judger.js

@ -174,7 +174,7 @@ async function connect() {
if (!judge_state) return; if (!judge_state) return;
const problemId = judge_state.problem_id; const problemId = judge_state.problem_id;
let problemQuery = await Problem.createQueryBuilder(); let problemQuery = await Problem.createQueryBuilder();
const problemInfo = await problemQuery.where("id = :id", {id: problemId}).getOne(); const problemInfo = await problemQuery.where("id = :id", { id: problemId }).getOne();
const problem_time_limit = problemInfo.time_limit; const problem_time_limit = problemInfo.time_limit;
const subtasksArray = convertedResult.result.judge ? convertedResult.result.judge.subtasks : []; const subtasksArray = convertedResult.result.judge ? convertedResult.result.judge.subtasks : [];
const timeArray = subtasksArray.map((subtasksItem) => { const timeArray = subtasksArray.map((subtasksItem) => {
@ -182,10 +182,9 @@ async function connect() {
return subtasksItemCases.result.time return subtasksItemCases.result.time
}) })
}); });
function flat(array, result=[]){
function flat(array, result = []) { for (let i=0;i<array.length;i++){
for (let i = 0; i < array.length; i++) { if (Array.isArray(array[i])){
if (Array.isArray(array[i])) {
flat(array[i], result); flat(array[i], result);
} else { } else {
result.push(array[i]); result.push(array[i]);
@ -193,27 +192,13 @@ async function connect() {
} }
return result; return result;
} }
const flatTimeArray = flat(timeArray); const flatTimeArray = flat(timeArray);
const maxItemTime = Math.max.apply(this, flatTimeArray); const maxItemTime = Math.max.apply(this, flatTimeArray);
let baseScore = 0; if (judge_state.type_info && convertedResult.statusString === 'Accepted' && maxItemTime < problem_time_limit * 0.9) {
if (judge_state.type === 0 || judge_state.type === 1) {
baseScore = 100;
}
if (judge_state.type === 2) {
baseScore = syzoj.config.practice_rating
}
if (convertedResult.statusString === 'Accepted' && maxItemTime < problem_time_limit * 0.9)
{
const beyondTime = problem_time_limit - maxItemTime; const beyondTime = problem_time_limit - maxItemTime;
const extraScore = (beyondTime / problem_time_limit).toString().slice(0, 3) * baseScore; const extraScore = (beyondTime / problem_time_limit).toString().slice(0,3)*100;
if (judge_state.type === 2) {
judge_state.score = convertedResult.score + extraScore + syzoj.config.practice_rating;
}
judge_state.score = convertedResult.score + extraScore; judge_state.score = convertedResult.score + extraScore;
} } else {
else
{
judge_state.score = convertedResult.score; judge_state.score = convertedResult.score;
} }
judge_state.pending = false; judge_state.pending = false;

1
libs/submissions_process.js

@ -5,7 +5,6 @@ const getSubmissionInfo = (s, displayConfig) => {
return { return {
submissionId: s.id, submissionId: s.id,
taskId: s.task_id, taskId: s.task_id,
type: s.type,
user: s.is_anonymous ? null: s.user.username, user: s.is_anonymous ? null: s.user.username,
userId: s.is_anonymous ? null : s.user_id, userId: s.is_anonymous ? null : s.user_id,
problemName: s.problem.title, problemName: s.problem.title,

1
models-built/contest_player.js.map

File diff suppressed because one or more lines are too long

3
models/contest_player.ts

@ -80,8 +80,9 @@ export default class ContestPlayer extends Model {
} }
} else if (this.contest.type === 'noi') { } else if (this.contest.type === 'noi') {
if (this.score_details[judge_state.problem_id] && this.score_details[judge_state.problem_id].judge_id > judge_state.id) return; if (this.score_details[judge_state.problem_id] && this.score_details[judge_state.problem_id].judge_id > judge_state.id) return;
this.score_details[judge_state.problem_id] = { this.score_details[judge_state.problem_id] = {
score: this.score_details[judge_state.problem_id] ? Math.max(judge_state.score ,this.score_details[judge_state.problem_id].score) : judge_state.score, score: Math.max(judge_state.score ,this.score_details[judge_state.problem_id].score),
judge_id: judge_state.id judge_id: judge_state.id
}; };

3
models/judge_state.ts

@ -89,7 +89,6 @@ export default class JudgeState extends Model {
/* /*
* "type" indicate it's contest's submission(type = 1) or normal submission(type = 0) * "type" indicate it's contest's submission(type = 1) or normal submission(type = 0)
* 2
* if it's contest's submission (type = 1), the type_info is contest_id * if it's contest's submission (type = 1), the type_info is contest_id
* use this way represent because it's easy to expand // Menci:这锅我不背,是 Chenyao 留下来的坑。 * use this way represent because it's easy to expand // Menci:这锅我不背,是 Chenyao 留下来的坑。
*/ */
@ -131,7 +130,7 @@ export default class JudgeState extends Model {
await this.loadRelationships(); await this.loadRelationships();
if (user && user.id === this.problem.user_id) return true; if (user && user.id === this.problem.user_id) return true;
else if (this.type === 0 || this.type === 2) return this.problem.is_public || (user && (await user.hasPrivilege('manage_problem'))); else if (this.type === 0) return this.problem.is_public || (user && (await user.hasPrivilege('manage_problem')));
else if (this.type === 1) { else if (this.type === 1) {
let contest = await Contest.findById(this.type_info); let contest = await Contest.findById(this.type_info);
if (contest.isRunning()) { if (contest.isRunning()) {

4
modules/contest.js

@ -207,7 +207,7 @@ app.get('/contest/:id', async (req, res) => {
for (let player of players) { for (let player of players) {
if (player.score_details[problem.problem.id]) { if (player.score_details[problem.problem.id]) {
problem.statistics.attempt++; problem.statistics.attempt++;
if ((contest.type === 'acm' && player.score_details[problem.problem.id].accepted) || ((contest.type === 'noi' || contest.type === 'ioi') && player.score_details[problem.problem.id].score >= 100)) { if ((contest.type === 'acm' && player.score_details[problem.problem.id].accepted) || ((contest.type === 'noi' || contest.type === 'ioi') && player.score_details[problem.problem.id].score === 100)) {
problem.statistics.accepted++; problem.statistics.accepted++;
} }
@ -458,12 +458,12 @@ app.get('/contest/submission/:id', async (req, res) => {
judge.problem_id = problems_id.indexOf(judge.problem_id) + 1; judge.problem_id = problems_id.indexOf(judge.problem_id) + 1;
judge.problem.title = syzoj.utils.removeTitleTag(judge.problem.title); judge.problem.title = syzoj.utils.removeTitleTag(judge.problem.title);
displayConfig.showUsage = true; displayConfig.showUsage = true;
displayConfig.showResult=true;
displayConfig.showDetailResult=true; displayConfig.showDetailResult=true;
if (judge.problem.type !== 'submit-answer') { if (judge.problem.type !== 'submit-answer') {
judge.codeLength = Buffer.from(judge.code).length; judge.codeLength = Buffer.from(judge.code).length;
judge.code = await syzoj.utils.highlight(judge.code, syzoj.languages[judge.language].highlight); judge.code = await syzoj.utils.highlight(judge.code, syzoj.languages[judge.language].highlight);
} }
res.render('submission_contest', { res.render('submission_contest', {
contest_id: contest.id, contest_id: contest.id,
info: getSubmissionInfo(judge, displayConfig), info: getSubmissionInfo(judge, displayConfig),

21
modules/practice.js

@ -1,5 +1,4 @@
let Classify = syzoj.model('classify'); let Classify = syzoj.model('classify');
let JudgeState = syzoj.model('judge_state');
let Problem = syzoj.model('problem'); let Problem = syzoj.model('problem');
let CToP = syzoj.model('classify_to_problem'); let CToP = syzoj.model('classify_to_problem');
let Article = syzoj.model('article'); let Article = syzoj.model('article');
@ -177,7 +176,6 @@ app.get('/api/pass/:cid/:pid/:sid',async (req, res) => {
let utopQuery = UToP.createQueryBuilder(); let utopQuery = UToP.createQueryBuilder();
let query = Classify.createQueryBuilder(); let query = Classify.createQueryBuilder();
let userQuery = User.createQueryBuilder(); let userQuery = User.createQueryBuilder();
let judgeStateQuery = JudgeState.createQueryBuilder();
let classify = await Classify.queryAll(query); let classify = await Classify.queryAll(query);
classify.sort(function(a,b) { classify.sort(function(a,b) {
return a.order - b.order; return a.order - b.order;
@ -201,26 +199,15 @@ app.get('/api/pass/:cid/:pid/:sid',async (req, res) => {
await utop.save(); await utop.save();
} }
let newutopQuery = UToP.createQueryBuilder(); let newutopQuery = UToP.createQueryBuilder();
let userACArray = await newutopQuery.select("p_id").where('u_id=:u_id',{u_id}).andWhere("is_finished=1").getRawMany(); let userACArray = await newutopQuery.where('u_id=:u_id',{u_id}).andWhere("is_finished=1").getMany();
console.log(userACArray.length);
if (syzoj.config.practice_rating) { if (syzoj.config.practice_rating) {
const scoreArray = await judgeStateQuery.select("score").addSelect("problem_id").where("user_id=:u_id",{u_id}).andWhere("type=2").andWhere("score>=100").getRawMany();
let newScore = 0;
if (scoreArray && scoreArray.length !== 0) {
let num = 0;
for(let i=0;i<userACArray.length;i++){
const problem_id = userACArray[i].p_id;
const item = scoreArray.find(item => item.problem_id === problem_id)
num+=parseInt(item.score);
}
newScore = num - userACArray.length * 100;
}
const originRating = syzoj.config.default.user.rating; const originRating = syzoj.config.default.user.rating;
const newRating = originRating + newScore; const newRating = originRating + userACArray.length * syzoj.config.practice_rating;
await userQuery.update(User).set({rating: newRating}).where('id=:u_id',{u_id}).execute(); await userQuery.update(User).set({rating: newRating}).where('id=:u_id',{u_id}).execute();
res.send({newRating: newRating});
} }
res.send();
} catch(e) { } catch(e) {
console.log(e);
res.send({ error_code: e.errno, error_msg: '练习失败,请稍后重试' }); res.send({ error_code: e.errno, error_msg: '练习失败,请稍后重试' });
} }
}); });

2
modules/problem.js

@ -633,7 +633,7 @@ app.post('/problem/practice/:pid/:cid/submit', app.multer.fields([{ name: 'answe
}); });
if (!await problem.isAllowedUseBy(curUser)) throw new ErrorMessage('您没有权限进行此操作。'); if (!await problem.isAllowedUseBy(curUser)) throw new ErrorMessage('您没有权限进行此操作。');
judge_state.type = 2; judge_state.type = 0;
await judge_state.save(); await judge_state.save();
await judge_state.updateRelatedInfo(true); await judge_state.updateRelatedInfo(true);

4
views/admin_classify.ejs

@ -109,10 +109,10 @@
</div> </div>
</div> </div>
</div> </div>
<link href="https://cdn.bootcss.com/element-ui/2.13.0/theme-chalk/index.css" rel="stylesheet"> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 --> <!-- 引入组件库 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.bootcss.com/element-ui/2.13.0/index.js"></script> <script src="https://unpkg.com/element-ui/lib/index.js"></script>
<% include problem_table %> <% include problem_table %>
<script> <script>
new window.Vue({ new window.Vue({

4
views/header.ejs

@ -33,10 +33,10 @@
<link href="<%- this.builtInCdnUrl %>/google-fonts/exo-2.css" rel="stylesheet"> <link href="<%- this.builtInCdnUrl %>/google-fonts/exo-2.css" rel="stylesheet">
<% } %> <% } %>
<script src="<%- lib('jquery/3.3.1/jquery.min.js') %>"></script> <script src="<%- lib('jquery/3.3.1/jquery.min.js') %>"></script>
<link href="https://cdn.bootcss.com/element-ui/2.13.0/theme-chalk/index.css" rel="stylesheet"> <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" />
<!-- 引入组件库 --> <!-- 引入组件库 -->
<script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="https://cdn.jsdelivr.net/npm/vue"></script>
<script src="https://cdn.bootcss.com/element-ui/2.13.0/index.js"></script> <script src="https://unpkg.com/element-ui/lib/index.js"></script>
<% if (syzoj.config.google_analytics && syzoj.config.google_analytics !== 'UA-XXXXXXXX-X') { %> <% if (syzoj.config.google_analytics && syzoj.config.google_analytics !== 'UA-XXXXXXXX-X') { %>
<script> <script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){

1
views/submission.ejs

@ -36,7 +36,6 @@
<tr> <tr>
<th>已分享</th> <th>已分享</th>
<th>编号</th> <th>编号</th>
<th>提交类型</th>
<th>题目</th> <th>题目</th>
<th>状态</th> <th>状态</th>
<th v-if="displayConfig.showScore">分数</th> <th v-if="displayConfig.showScore">分数</th>

1
views/submission_contest.ejs

@ -37,7 +37,6 @@
<tr> <tr>
<th>已分享</th> <th>已分享</th>
<th>编号</th> <th>编号</th>
<th>提交类型</th>
<th>题目</th> <th>题目</th>
<th>状态</th> <th>状态</th>
<th v-if="displayConfig.showScore">分数</th> <th v-if="displayConfig.showScore">分数</th>

46
views/submission_practice.ejs

@ -37,9 +37,7 @@
<table class="ui very basic center aligned table" id="status_table"> <table class="ui very basic center aligned table" id="status_table">
<thead> <thead>
<tr> <tr>
<th>已分享</th>
<th>编号</th> <th>编号</th>
<th>提交类型</th>
<th>题目</th> <th>题目</th>
<th>状态</th> <th>状态</th>
<th v-if="displayConfig.showScore">分数</th> <th v-if="displayConfig.showScore">分数</th>
@ -348,7 +346,7 @@ if (token != null) {
console.log("Judge finished"); console.log("Judge finished");
vueApp.roughData.running = false; vueApp.roughData.running = false;
vueApp.roughData.result = p.roughResult; vueApp.roughData.result = p.roughResult;
if (p.roughResult && p.roughResult.result === 'Accepted') { if (p.roughResult.result === 'Accepted') {
$.ajax({ $.ajax({
url: `/api/pass/${cid}/${pid}/${sid}`, url: `/api/pass/${cid}/${pid}/${sid}`,
type: 'GET', type: 'GET',
@ -384,32 +382,32 @@ if (token != null) {
// } // }
// data.running=false; // data.running=false;
if (data && data.ok) { if (data && data.ok) {
if (data.roughResult && data.roughResult.result === 'Accepted') {
$.ajax({
url: `/api/pass/${cid}/${pid}/${sid}`,
type: 'GET',
success: function (data) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('练习功能发生故障');
}
});
} else {
$.ajax({
url: `/api/nopass/${cid}/${pid}/${sid}`,
type: 'GET',
success: function (data) {
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert('练习功能发生故障');
}
});
}
if (data.finished) { if (data.finished) {
vueApp.roughData.result = data.roughResult; vueApp.roughData.result = data.roughResult;
// if (!data.result) location.reload(true); // if (!data.result) location.reload(true);
vueApp.detailResult = data.result; vueApp.detailResult = data.result;
vueApp.roughData.running = false; vueApp.roughData.running = false;
// if (data.roughResult.result === 'Accepted') {
// $.ajax({
// url: `/api/pass/${cid}/${pid}/${sid}`,
// type: 'GET',
// success: function (data) {
// },
// error: function (XMLHttpRequest, textStatus, errorThrown) {
// alert('练习功能发生故障');
// }
// });
// } else {
// $.ajax({
// url: `/api/nopass/${cid}/${pid}/${sid}`,
// type: 'GET',
// success: function (data) {
// },
// error: function (XMLHttpRequest, textStatus, errorThrown) {
// alert('练习功能发生故障');
// }
// });
// }
socket.close(); socket.close();
} else { } else {
if (data.running) { if (data.running) {

1
views/submissions.ejs

@ -108,7 +108,6 @@
<tr> <tr>
<th>已分享</th> <th>已分享</th>
<th>编号</th> <th>编号</th>
<th>提交类型</th>
<th>题目</th> <th>题目</th>
<th>状态</th> <th>状态</th>
<th v-if="displayConfig.showScore">分数</th> <th v-if="displayConfig.showScore">分数</th>

21
views/submissions_item.ejs

@ -22,16 +22,6 @@
template: '#submissionItemTemplate', template: '#submissionItemTemplate',
props: ['data', 'config', 'showRejudge', 'showShare', 'progress', 'compiling', 'rough'], props: ['data', 'config', 'showRejudge', 'showShare', 'progress', 'compiling', 'rough'],
computed: { computed: {
type() {
let type = "";
switch(this.data.info.type) {
case 0: type = "普通提交";break;
case 1: type = "比赛提交";break;
case 2: type = "练习提交";break;
default:type="普通提交";
}
return type;
},
statusString() { statusString() {
const data = this.data; const data = this.data;
@ -83,15 +73,10 @@
<tr> <tr>
<td><i class="icon" :class="data.info.is_share ? 'smile outline success': 'meh outline'" style="font-size: 1.5em"></i></td> <td><i class="icon" :class="data.info.is_share ? 'smile outline success': 'meh outline'" style="font-size: 1.5em"></i></td>
<td><a :href="submissionLink"><b>#{{ data.info.submissionId }}</b></a></td> <td><a :href="submissionLink"><b>#{{ data.info.submissionId }}</b></a></td>
<td>{{type}}</td> <td ref="problemLabel"><a ref="problemLabelTextFit"
<td ref="problemLabel">
<a ref="problemLabelTextFit"
style="width: 230px; height: 22px; display: block; margin: 0 auto; line-height: 22px;" style="width: 230px; height: 22px; display: block; margin: 0 auto; line-height: 22px;"
:href="problemLink" :href="problemLink"><b>#{{ config.inContest ? alpha(data.info.problemId) :
> data.info.problemId }}.</b> {{ data.info.problemName }}</a></td>
<b>#{{ config.inContest ? alpha(data.info.problemId) : data.info.problemId }}.</b>
{{ data.info.problemName }}</a>
</td>
<% if (active === 'submissions') { %> <% if (active === 'submissions') { %>
<td><a :href="submissionLink"><b> <td><a :href="submissionLink"><b>
<status-label :status="statusString" :progress="progress"></status-label> <status-label :status="statusString" :progress="progress"></status-label>

Loading…
Cancel
Save