支持选取已有题目作为比赛题目

This commit is contained in:
zema1 2017-12-03 18:55:08 +08:00
parent 48d36d3141
commit 6ac4bb9fcb
5 changed files with 152 additions and 24 deletions

View File

@ -1,6 +1,7 @@
import Vue from 'vue'
import router from './router'
import axios from 'axios'
import utils from '@/utils/utils'
Vue.prototype.$http = axios
axios.defaults.baseURL = '/api'
@ -212,20 +213,14 @@ export default {
}
})
},
getProblemList (offset, limit, keyword) {
let params = {paging: true, offset, limit}
if (keyword) {
params.keyword = keyword
}
getProblemList (params) {
params = utils.filterEmptyValue(params)
return ajax('admin/problem', 'get', {
params
})
},
getContestProblemList (offset, limit, keyword, contestId) {
let params = {paging: true, offset, limit, contest_id: contestId}
if (keyword) {
params.keyword = keyword
}
getContestProblemList (params) {
params = utils.filterEmptyValue(params)
return ajax('admin/contest/problem', 'get', {
params
})
@ -258,6 +253,11 @@ export default {
return ajax('admin/contest_problem/make_public', 'post', {
data
})
},
addProblemFromPublic (data) {
return ajax('admin/contest/add_problem_from_public', 'post', {
data
})
}
}

View File

@ -70,7 +70,8 @@
<Panel>
<span slot="title">Import User
<el-popover placement="right" trigger="hover">
<p>Only support csv file without headers, check the <a href="http://docs.onlinejudge.me/#/onlinejudge/guide/import_users">link</a> for details</p>
<p>Only support csv file without headers, check the <a
href="http://docs.onlinejudge.me/#/onlinejudge/guide/import_users">link</a> for details</p>
<i slot="reference" class="el-icon-fa-question-circle import-user-icon"></i>
</el-popover>
</span>
@ -128,9 +129,9 @@
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="Suffix" prop="suffix">
<el-input v-model="formGenerateUser.suffix" placeholder="Suffix"></el-input>
</el-form-item>
<el-form-item label="Suffix" prop="suffix">
<el-input v-model="formGenerateUser.suffix" placeholder="Suffix"></el-input>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="Start Number" prop="number_from" required>
@ -138,9 +139,9 @@
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="End Number" prop="number_to" required>
<el-input-number v-model="formGenerateUser.number_to" style="width: 100%"></el-input-number>
</el-form-item>
<el-form-item label="End Number" prop="number_to" required>
<el-input-number v-model="formGenerateUser.number_to" style="width: 100%"></el-input-number>
</el-form-item>
</el-col>
<el-col :span="4">
<el-form-item label="Password Length" prop="password_length" required>

View File

@ -0,0 +1,99 @@
<template>
<div>
<el-table :data="problems" v-loading="loading">
<el-table-column
label="ID"
width="100"
prop="id">
</el-table-column>
<el-table-column
label="DisplayID"
width="200"
prop="_id">
</el-table-column>
<el-table-column
label="Title"
prop="title">
</el-table-column>
<el-table-column
label="option"
align="center"
width="100"
fixed="right">
<template slot-scope="{row}">
<icon-btn icon="plus" name="Add the problem"
@click.native="handleAddProblem(row.id)"></icon-btn>
</template>
</el-table-column>
</el-table>
<el-pagination
class="page"
layout="prev, pager, next"
@current-change="getPublicProblem"
:page-size="limit"
:total="total">
</el-pagination>
</div>
</template>
<script>
import api from '@admin/api'
export default {
name: 'add-problem-from-public',
props: ['contestID'],
data () {
return {
page: 1,
limit: 10,
total: 0,
loading: false,
problems: [],
contest: {}
}
},
mounted () {
api.getContest(this.contestID).then(res => {
this.contest = res.data.data
this.getPublicProblem()
}).catch(() => {
})
},
methods: {
getPublicProblem (page) {
this.loading = true
let params = {
offset: (page - 1) * this.limit,
limit: this.limit,
rule_type: this.contest.rule_type
}
api.getProblemList(params).then(res => {
this.loading = false
this.total = res.data.data.total
this.problems = res.data.data.results
}).catch(() => {
})
},
handleAddProblem (problemID) {
this.$prompt('Please input display id for the contest problem', 'confirm').then(({value}) => {
let data = {
problem_id: problemID,
contest_id: this.contestID,
display_id: value
}
api.addProblemFromPublic(data).then(() => {
this.$emit('on-change')
}, () => {})
}, () => {
})
}
}
}
</script>
<style scoped>
.page {
margin-top: 20px;
text-align: right
}
</style>

View File

@ -1,10 +1,10 @@
<template>
<div class="view">
<Panel title="Problem List">
<Panel :title="contestId ? 'Contest Problem List' : 'Problem List'">
<div slot="header">
<el-input
v-model="keyword"
suffix-icon="search"
prefix-icon="el-icon-search"
placeholder="Keywords">
</el-input>
</div>
@ -81,7 +81,13 @@
</el-table-column>
</el-table>
<div class="panel-options">
<el-button type="primary" size="small" @click.native="goCreateProblem" icon="el-icon-plus">Create</el-button>
<el-button type="primary" size="small"
@click="goCreateProblem" icon="el-icon-plus">Create
</el-button>
<el-button v-if="contestId" type="primary"
size="small" icon="el-icon-plus"
@click="addProblemDialogVisible = true">Add From Public Problem
</el-button>
<el-pagination
class="page"
layout="prev, pager, next"
@ -104,15 +110,26 @@
<save @click.native="updateProblem(currentRow)"></save>
</span>
</el-dialog>
<el-dialog title="Add Contest Problem"
v-if="contestId"
width="80%"
:visible.sync="addProblemDialogVisible"
@close-on-click-modal="false">
<add-problem-component :contestID="contestId" @on-change="getProblemList"></add-problem-component>
</el-dialog>
</div>
</template>
<script>
import api from '../../api.js'
import utils from '@/utils/utils'
import AddProblemComponent from './AddPublicProblem.vue'
export default {
name: 'ProblemList',
components: {
AddProblemComponent
},
data () {
return {
pageSize: 10,
@ -127,7 +144,8 @@
currentProblemID: '',
currentRow: {},
InlineEditDialogVisible: false,
makePublicDialogVisible: false
makePublicDialogVisible: false,
addProblemDialogVisible: false
}
},
mounted () {
@ -161,7 +179,13 @@
getProblemList (page = 1) {
this.loading = true
let funcName = this.routeName === 'problem-list' ? 'getProblemList' : 'getContestProblemList'
api[funcName]((page - 1) * this.pageSize, this.pageSize, this.keyword, this.contestId).then(res => {
let params = {
limit: this.pageSize,
offset: (page - 1) * this.pageSize,
keyword: this.keyword,
contest_id: this.contestId
}
api[funcName](params).then(res => {
this.loading = false
this.total = res.data.data.total
for (let problem of res.data.data.results) {
@ -181,7 +205,8 @@
this.getProblemList(this.currentPage - 1)
]).catch(() => {
})
}, () => {})
}, () => {
})
},
makeContestProblemPublic (problemID) {
this.$prompt('Please input display id for the public problem', 'confirm').then(({value}) => {
@ -212,6 +237,9 @@
downloadTestCase (problemID) {
let url = '/admin/test_case?problem_id=' + problemID
utils.downloadFile(url)
},
getPublicProblem () {
api.getProblemList()
}
},
watch: {

View File

@ -24,7 +24,7 @@ function getACRate (acCount, totalCount) {
function filterEmptyValue (object) {
let query = {}
Object.keys(object).forEach(key => {
if (object[key]) {
if (object[key] || object[key] === 0 || object[key] === false) {
query[key] = object[key]
}
})