mirror of
https://github.com/QingdaoU/OnlineJudgeFE.git
synced 2025-01-01 09:31:42 +00:00
添加SPJ problem 需要编译成功才能保存
This commit is contained in:
parent
35553febb8
commit
9a72d11a40
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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'
|
||||
|
@ -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>
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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])
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -312,9 +312,11 @@
|
||||
height: 400px;
|
||||
width: 98%;
|
||||
}
|
||||
|
||||
.screen-full {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
#switches {
|
||||
span {
|
||||
margin-left: 5px;
|
||||
|
@ -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%'
|
||||
|
Loading…
Reference in New Issue
Block a user