添加SPJ problem 需要编译成功才能保存

This commit is contained in:
zema1 2017-11-16 22:08:48 +08:00
parent 35553febb8
commit 9a72d11a40
10 changed files with 99 additions and 39 deletions

View File

@ -12,6 +12,18 @@
</script>
<style lang="less">
[class^="el-icon-fa"], [class*=" el-icon-fa"] {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome !important;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@import url("../../../node_modules/font-awesome/less/font-awesome");
@fa-css-prefix: el-icon-fa;
body {
margin: 0;
padding: 0;

View File

@ -164,6 +164,11 @@ export default {
getProblemTagList () {
return ajax('problem/tags', 'get')
},
compileSPJ (data) {
return ajax('admin/compile_spj', 'post', {
data
})
},
createProblem (data) {
return ajax('admin/problem', 'post', {
data

View File

@ -1,8 +1,7 @@
<template>
<div style="display: inline-block;">
<el-tooltip class="item" effect="dark" :content="name" placement="top">
<el-button type="primary" :plain="true" size="small">
<i :class="'fa fa-' + icon" aria-hidden="true"></i>
<el-button type="primary" :plain="true" :icon="'fa-' + icon" size="small">
</el-button>
</el-tooltip>
</div>

View File

@ -24,7 +24,6 @@
</template>
<script>
import 'font-awesome/css/font-awesome.min.css'
import SideMenu from '../components/SideMenu.vue'
import ScreenFull from '@admin/components/ScreenFull.vue'
import api from '../api'

View File

@ -159,24 +159,26 @@
</el-row>
</el-form-item>
<el-form-item label="Special Judge" :error="error.spj">
<el-row :gutter="20">
<el-col :span="12">
<el-checkbox v-model="problem.spj" @click.native.prevent="switchSpj()">Use Special Judge</el-checkbox>
</el-col>
<el-col v-if="problem.spj" :span="12">
<el-form-item label="Special Judge Language">
<el-radio-group v-model="problem.spj_language">
<el-tooltip class="spj-radio" v-for="lang in allLanguage.spj_languages" :key="lang.name" effect="dark"
:content="lang.description" placement="top-start">
<el-radio :label="lang.name">{{ lang.name }}</el-radio>
</el-tooltip>
</el-radio-group>
</el-form-item>
</el-col>
</el-row>
<el-form-item v-if="problem.spj" label="Special Judge Code">
<el-col :span="24">
<el-checkbox v-model="problem.spj" @click.native.prevent="switchSpj()">Use Special Judge</el-checkbox>
</el-col>
</el-form-item>
<el-form-item v-if="problem.spj">
<Accordion title="Special Judge Code">
<template slot="header">
<span>SPJ language</span>
<el-radio-group v-model="problem.spj_language">
<el-tooltip class="spj-radio" v-for="lang in allLanguage.spj_languages" :key="lang.name" effect="dark"
:content="lang.description" placement="top-start">
<el-radio :label="lang.name">{{ lang.name }}</el-radio>
</el-tooltip>
</el-radio-group>
<el-button type="primary" size="small" icon="fa-random" @click="compileSPJ" :loading="loadingCompile">
Compile
</el-button>
</template>
<code-mirror v-model="problem.spj_code" :mode="spjMode"></code-mirror>
</el-form-item>
</Accordion>
</el-form-item>
<el-row :gutter="20">
<el-col :span="4">
@ -260,6 +262,7 @@
input_description: {required: true, message: 'Input Description is required', trigger: 'blur'},
output_description: {required: true, message: 'Output Description is required', trigger: 'blur'}
},
loadingCompile: false,
mode: '',
contest: {},
problem: {
@ -310,6 +313,7 @@
spj: false,
spj_language: '',
spj_code: '',
spj_compile_ok: false,
test_case_id: '',
test_case_score: [],
rule_type: 'ACM',
@ -448,6 +452,29 @@
uploadFailed () {
this.$error('Upload failed')
},
compileSPJ () {
let data = {
id: this.problem.id,
spj_code: this.problem.spj_code,
spj_language: this.problem.spj_language
}
this.loadingCompile = true
api.compileSPJ(data).then(res => {
this.loadingCompile = false
this.problem.spj_compile_ok = true
}, err => {
this.loadingCompile = false
const h = this.$createElement
this.$msgbox({
title: 'Compile Error',
type: 'error',
message: h('pre', err.data.data),
showCancelButton: false,
closeOnClickModal: false,
customClass: 'dialog-compile-error'
})
})
},
submit () {
if (!this.problem.samples.length) {
this.$error('Sample is required')
@ -464,10 +491,17 @@
this.$error(this.error.tags)
return
}
if (this.problem.spj && !this.problem.spj_code) {
this.error.spj = 'Spj code is required'
this.$error(this.error.spj)
return
if (this.problem.spj) {
if (!this.problem.spj_code) {
this.error.spj = 'Spj code is required'
this.$error(this.error.spj)
} else if (!this.problem.spj_compile_ok) {
this.error.spj = 'SPJ code has not been successfully compiled'
}
if (this.error.spj) {
this.$error(this.error.spj)
return
}
}
if (!this.problem.languages.length) {
this.error.languages = 'Please choose at least one language for problem'
@ -527,7 +561,10 @@
width: 120px;
}
.spj-radio {
margin-right: 15px;
margin-left: 10px;
&:last-child {
margin-right: 20px;
}
}
.input-new-tag {
width: 78px;
@ -565,6 +602,15 @@
.add-sample-btn {
margin-bottom: 10px;
}
}
</style>
<style>
.dialog-compile-error {
width: auto;
max-width: 80%;
overflow-x: scroll;
}
</style>

View File

@ -66,6 +66,7 @@
<Dropdown-item name="/user-home">Home</Dropdown-item>
<Dropdown-item name="/status?myself=1">Submissions</Dropdown-item>
<Dropdown-item name="/setting">Settings</Dropdown-item>
<Dropdown-item name="/admin/">Management</Dropdown-item>
<Dropdown-item divided name="/logout">Logout</Dropdown-item>
</Dropdown-menu>
</Dropdown>
@ -95,8 +96,10 @@
methods: {
...mapActions(['getProfile', 'changeModalStatus']),
handleRoute (route) {
if (route) {
if (route && route.indexOf('admin') < 0) {
this.$router.push(route)
} else {
window.open('/admin/')
}
},
handleBtnClick (mode) {
@ -107,7 +110,7 @@
}
},
computed: {
...mapGetters(['website', 'modalStatus', 'user', 'isAuthenticated']),
...mapGetters(['website', 'modalStatus', 'user', 'isAuthenticated', 'isAdmin']),
//
activeMenu () {
return '/' + this.$route.path.split('/')[1]

View File

@ -37,16 +37,6 @@ hljs.registerLanguage('cpp', cpp)
hljs.registerLanguage('java', java)
hljs.registerLanguage('python', python)
// add global EventBus
const EventBus = new Vue()
Object.defineProperties(Vue.prototype, {
$bus: {
get () {
return EventBus
}
}
})
// register global utility filters.
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])

View File

@ -1,7 +1,7 @@
import types from '../types'
import api from '@oj/api'
import storage from '@/utils/storage'
import { STORAGE_KEY } from '@/utils/constants'
import { STORAGE_KEY, USER_TYPE } from '@/utils/constants'
const state = {
profile: {}
@ -12,6 +12,10 @@ const getters = {
profile: state => state.profile,
isAuthenticated: (state, getters) => {
return !!getters.user.id
},
isAdmin: (state, getters) => {
return getters.user.admin_type === USER_TYPE.ADMIN ||
getters.user.admin_type === USER_TYPE.SUPER_ADMIN
}
}

View File

@ -312,9 +312,11 @@
height: 400px;
width: 98%;
}
.screen-full {
margin-right: 8px;
}
#switches {
span {
margin-left: 5px;

View File

@ -105,7 +105,7 @@
show: true,
feature: {
dataView: {show: true, readOnly: true},
magicType: {show: true, type: ['line', 'bar']},
magicType: {show: true, type: ['line', 'bar', 'stack']},
saveAsImage: {show: true}
},
right: '10%'