mirror of
https://github.com/QingdaoU/OnlineJudgeFE.git
synced 2024-12-29 16:01:51 +00:00
commit
74644d2a57
@ -8,6 +8,9 @@ export const m = {
|
||||
Judge_Server: 'Judge Server',
|
||||
Prune_Test_Case: 'Prune Test Case',
|
||||
Problem: 'Problem',
|
||||
FromFile: 'From File',
|
||||
ToFile: 'To File',
|
||||
ShareSubmission: 'Share Submission',
|
||||
Problem_List: 'Problem List',
|
||||
Create_Problem: 'Create Problem',
|
||||
Export_Import_Problem: 'Export Or Import Problem',
|
||||
@ -32,7 +35,7 @@ export const m = {
|
||||
General_Announcement: 'Announcement',
|
||||
Announcement_Title: 'Title',
|
||||
Announcement_Content: 'Conten',
|
||||
Announcement_Status: 'Status',
|
||||
Announcement_visible: 'Visible',
|
||||
// Conf.vue
|
||||
SMTP_Config: 'SMTP Config',
|
||||
Server: 'Server',
|
||||
@ -77,6 +80,9 @@ export const m = {
|
||||
SPJ_language: 'SPJ language',
|
||||
Compile: 'Compile',
|
||||
TestCase: 'TestCase',
|
||||
IOMode: 'IO Mode',
|
||||
InputFileName: 'Input File Name',
|
||||
OutputFileName: 'Output File Name',
|
||||
Type: 'Type',
|
||||
Input: 'Input',
|
||||
Output: 'Output',
|
||||
|
@ -8,6 +8,9 @@ export const m = {
|
||||
Judge_Server: '判题服务器',
|
||||
Prune_Test_Case: '测试用例',
|
||||
Problem: '问题',
|
||||
FromFile: '读取文件',
|
||||
ToFile: '写入文件',
|
||||
ShareSubmission: '分享提交',
|
||||
Problem_List: '问题列表',
|
||||
Create_Problem: '增加题目',
|
||||
Export_Import_Problem: '导入导出题目',
|
||||
@ -32,7 +35,7 @@ export const m = {
|
||||
General_Announcement: '公告',
|
||||
Announcement_Title: '标题',
|
||||
Announcement_Content: '内容',
|
||||
Announcement_Status: '状态',
|
||||
Announcement_visible: '是否可见',
|
||||
// Conf.vue
|
||||
SMTP_Config: 'SMTP Config',
|
||||
Server: '服务器',
|
||||
@ -77,6 +80,9 @@ export const m = {
|
||||
SPJ_language: 'SPJ language',
|
||||
Compile: '编译',
|
||||
TestCase: '测试用例',
|
||||
IOMode: 'IO 类型',
|
||||
InputFileName: '输入文件名',
|
||||
OutputFileName: '输出文件名',
|
||||
Type: '测试类型',
|
||||
Input: '输入',
|
||||
Output: '输出',
|
||||
|
@ -8,6 +8,9 @@ export const m = {
|
||||
Judge_Server: 'Judge 伺服器',
|
||||
Prune_Test_Case: '測資',
|
||||
Problem: '試題',
|
||||
FromFile: '讀取檔案',
|
||||
ToFile: '寫入檔案',
|
||||
ShareSubmission: '分享提交',
|
||||
Problem_List: '試題列表',
|
||||
Create_Problem: '增加題目',
|
||||
Export_Import_Problem: '匯入匯出題目',
|
||||
@ -32,7 +35,7 @@ export const m = {
|
||||
General_Announcement: '公告',
|
||||
Announcement_Title: '標題',
|
||||
Announcement_Content: '內容',
|
||||
Announcement_Status: '狀態',
|
||||
Announcement_visible: '是否可見',
|
||||
// Conf.vue
|
||||
SMTP_Config: 'SMTP 設定',
|
||||
Server: '伺服器',
|
||||
@ -77,6 +80,9 @@ export const m = {
|
||||
SPJ_language: 'SPJ language',
|
||||
Compile: '編譯',
|
||||
TestCase: '測資',
|
||||
IOMode: 'IO 類型',
|
||||
InputFileName: '輸入檔名',
|
||||
OutputFileName: '輸出檔名',
|
||||
Type: '測試類型',
|
||||
Input: '輸入',
|
||||
Output: '輸出',
|
||||
|
@ -7,13 +7,14 @@
|
||||
import 'tar-simditor/styles/simditor.css'
|
||||
import 'tar-simditor-markdown'
|
||||
import 'tar-simditor-markdown/styles/simditor-markdown.css'
|
||||
import './simditor-file-upload'
|
||||
|
||||
export default {
|
||||
name: 'Simditor',
|
||||
props: {
|
||||
toolbar: {
|
||||
type: Array,
|
||||
default: () => ['title', 'bold', 'italic', 'underline', 'fontScale', 'color', 'ol', 'ul', '|', 'link', 'image', 'hr', '|', 'indent', 'outdent', 'alignment', '|', 'markdown']
|
||||
default: () => ['title', 'bold', 'italic', 'underline', 'fontScale', 'color', 'ol', 'ul', '|', 'link', 'image', 'uploadfile', 'hr', '|', 'indent', 'outdent', 'alignment', '|', 'markdown']
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
@ -32,7 +33,7 @@
|
||||
textarea: this.$refs.editor,
|
||||
toolbar: this.toolbar,
|
||||
pasteImage: true,
|
||||
markdown: true,
|
||||
markdown: false,
|
||||
upload: {
|
||||
url: '/api/admin/upload_image/',
|
||||
params: null,
|
||||
|
85
src/pages/admin/components/simditor-file-upload.js
Normal file
85
src/pages/admin/components/simditor-file-upload.js
Normal file
@ -0,0 +1,85 @@
|
||||
/* eslint-disable */
|
||||
|
||||
import Simditor from 'tar-simditor'
|
||||
import * as $ from 'jquery'
|
||||
|
||||
var UploadFile,
|
||||
__hasProp = {}.hasOwnProperty,
|
||||
__extends = function (child, parent) {
|
||||
for (var key in parent) {
|
||||
if (__hasProp.call(parent, key)) child[key] = parent[key];
|
||||
}
|
||||
|
||||
function ctor() {
|
||||
this.constructor = child;
|
||||
}
|
||||
|
||||
ctor.prototype = parent.prototype;
|
||||
child.prototype = new ctor();
|
||||
child.__super__ = parent.prototype;
|
||||
return child;
|
||||
},
|
||||
__slice = [].slice;
|
||||
|
||||
UploadFile = (function (_super) {
|
||||
__extends(UploadFile, _super);
|
||||
|
||||
UploadFile.i18n = {
|
||||
'zh-CN': {
|
||||
uploadfile: '上传文件'
|
||||
},
|
||||
'en-US': {
|
||||
uploadfile: 'upload file'
|
||||
}
|
||||
};
|
||||
|
||||
UploadFile.prototype.name = 'uploadfile';
|
||||
|
||||
UploadFile.prototype.icon = 'upload';
|
||||
|
||||
function UploadFile() {
|
||||
var args;
|
||||
args = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
|
||||
UploadFile.__super__.constructor.apply(this, args);
|
||||
this._initUpload();
|
||||
}
|
||||
|
||||
UploadFile.prototype._initUpload = function () {
|
||||
this.input = $('<input />', {
|
||||
type: 'file',
|
||||
style: 'position:absolute;top:0;right:0;height:100%;width:100%;opacity:0;filter:alpha(opacity=0);cursor:pointer;'
|
||||
}).prependTo(this.el)
|
||||
var _this = this;
|
||||
this.el.on('click mousedown', 'input[type=file]', function (e) {
|
||||
return e.stopPropagation();
|
||||
}).on('change', 'input[type=file]', function (e) {
|
||||
|
||||
var formData = new FormData();
|
||||
formData.append('file', this.files[0]);
|
||||
$.ajax({
|
||||
url: '/api/admin/upload_file',
|
||||
type: 'POST',
|
||||
cache: false,
|
||||
data: formData,
|
||||
processData: false,
|
||||
contentType: false
|
||||
}).done(function (res) {
|
||||
if (!res.success) {
|
||||
alert("upload file failed")
|
||||
} else {
|
||||
let link = '<a target="_blank" className="simditor-attach-link" href="' + res.file_path + '">' + res.file_name + '</a>'
|
||||
_this.editor.setValue(_this.editor.getValue() + link)
|
||||
}
|
||||
}).fail(function (res) {
|
||||
alert("upload file failed")
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return UploadFile;
|
||||
|
||||
})(Simditor.Button);
|
||||
|
||||
Simditor.Toolbar.addButton(UploadFile);
|
||||
|
||||
|
@ -84,7 +84,7 @@
|
||||
<Simditor v-model="announcement.content"></Simditor>
|
||||
</el-form-item>
|
||||
<div class="visible-box">
|
||||
<span>{{$t('m.Announcement_Status')}}</span>
|
||||
<span>{{$t('m.Announcement_visible')}}</span>
|
||||
<el-switch
|
||||
v-model="announcement.visible"
|
||||
active-text=""
|
||||
|
@ -26,9 +26,7 @@
|
||||
<el-col :span="24">
|
||||
<el-form-item label="TLS">
|
||||
<el-switch
|
||||
v-model="smtp.tls"
|
||||
active-color="#13ce66"
|
||||
inactive-color="#ff4949">
|
||||
v-model="smtp.tls">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
@ -231,9 +231,7 @@
|
||||
<el-col :span="8">
|
||||
<el-form-item :label="$t('m.Is_Disabled')">
|
||||
<el-switch
|
||||
v-model="user.is_disabled"
|
||||
active-text=""
|
||||
inactive-text="">
|
||||
v-model="user.is_disabled">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -326,7 +324,7 @@
|
||||
})
|
||||
},
|
||||
deleteUsers (ids) {
|
||||
this.$confirm('Sure to delete the user?', 'confirm', {
|
||||
this.$confirm('Sure to delete the user? The associated resources created by this user will be deleted as well, like problem, contest, announcement, etc.', 'confirm', {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
api.deleteUsers(ids.join(',')).then(res => {
|
||||
|
@ -6,7 +6,7 @@
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-form-item prop="_id" :label="$t('m.Display_ID')"
|
||||
:required="this.routeName === 'create-contest-problem' || this.routeName === 'edit-contet-problem'">
|
||||
:required="this.routeName === 'create-contest-problem' || this.routeName === 'edit-contest-problem'">
|
||||
<el-input :placeholder="$t('m.Display_ID')" v-model="problem._id"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
@ -57,7 +57,7 @@
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-col :span="4">
|
||||
<el-form-item :label="$t('m.Visible')">
|
||||
<el-switch
|
||||
v-model="problem.visible"
|
||||
@ -66,6 +66,15 @@
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4">
|
||||
<el-form-item :label="$t('m.ShareSubmission')">
|
||||
<el-switch
|
||||
v-model="problem.share_submission"
|
||||
active-text=""
|
||||
inactive-text="">
|
||||
</el-switch>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-form-item label="Tag" :error="error.tags" required>
|
||||
<span class="tags">
|
||||
@ -177,7 +186,7 @@
|
||||
</Accordion>
|
||||
</el-form-item>
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-col :span="4">
|
||||
<el-form-item :label="$t('m.Type')">
|
||||
<el-radio-group v-model="problem.rule_type" :disabled="disableRuleType">
|
||||
<el-radio label="ACM">ACM</el-radio>
|
||||
@ -185,7 +194,7 @@
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-col :span="6">
|
||||
<el-form-item :label="$t('m.TestCase')" :error="error.testcase">
|
||||
<el-upload
|
||||
action="/api/admin/test_case"
|
||||
@ -199,6 +208,26 @@
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="6">
|
||||
<el-form-item :label="$t('m.IOMode')">
|
||||
<el-radio-group v-model="problem.io_mode.io_mode">
|
||||
<el-radio label="Standard IO">Standard IO</el-radio>
|
||||
<el-radio label="File IO">File IO</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="4" v-if="problem.io_mode.io_mode == 'File IO'">
|
||||
<el-form-item :label="$t('m.InputFileName')" required>
|
||||
<el-input type="text" v-model="problem.io_mode.input"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="4" v-if="problem.io_mode.io_mode == 'File IO'">
|
||||
<el-form-item :label="$t('m.OutputFileName')" required>
|
||||
<el-input type="text" v-model="problem.io_mode.output"></el-input>
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
|
||||
<el-col :span="24">
|
||||
<el-table
|
||||
:data="problem.test_case_score"
|
||||
@ -261,10 +290,12 @@
|
||||
mode: '',
|
||||
contest: {},
|
||||
problem: {
|
||||
languages: []
|
||||
languages: [],
|
||||
io_mode: {'io_mode': 'Standard IO', 'input': 'input.txt', 'output': 'output.txt'}
|
||||
},
|
||||
reProblem: {
|
||||
languages: []
|
||||
languages: [],
|
||||
io_mode: {'io_mode': 'Standard IO', 'input': 'input.txt', 'output': 'output.txt'}
|
||||
},
|
||||
testCaseUploaded: false,
|
||||
allLanguage: {},
|
||||
@ -301,6 +332,7 @@
|
||||
memory_limit: 256,
|
||||
difficulty: 'Low',
|
||||
visible: true,
|
||||
share_submission: false,
|
||||
tags: [],
|
||||
languages: [],
|
||||
template: {},
|
||||
@ -313,7 +345,8 @@
|
||||
test_case_score: [],
|
||||
rule_type: 'ACM',
|
||||
hint: '',
|
||||
source: ''
|
||||
source: '',
|
||||
io_mode: {'io_mode': 'Standard IO', 'input': 'input.txt', 'output': 'output.txt'}
|
||||
}
|
||||
let contestID = this.$route.params.contestId
|
||||
if (contestID) {
|
||||
@ -438,7 +471,7 @@
|
||||
let fileList = response.data.info
|
||||
for (let file of fileList) {
|
||||
file.score = (100 / fileList.length).toFixed(0)
|
||||
if (this.problem.spj) {
|
||||
if (!file.output_name && this.problem.spj) {
|
||||
file.output_name = '-'
|
||||
}
|
||||
}
|
||||
|
@ -197,7 +197,7 @@
|
||||
})
|
||||
},
|
||||
deleteProblem (id) {
|
||||
this.$confirm('You can only delete the problem that doesn\'t have submissions, continue?', 'Delete Problem', {
|
||||
this.$confirm('Sure to delete this problem? The associated submissions will be deleted as well.', 'Delete Problem', {
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
let funcName = this.routeName === 'problem-list' ? 'deleteProblem' : 'deleteContestProblem'
|
||||
|
@ -13,6 +13,12 @@
|
||||
<Button icon="refresh" @click="onResetClick"></Button>
|
||||
</Tooltip>
|
||||
|
||||
<Tooltip content="Upload file" placement="top" style="margin-left: 10px">
|
||||
<Button icon="upload" @click="onUploadFile"></Button>
|
||||
</Tooltip>
|
||||
|
||||
<input type="file" id="file-uploader" style="display: none" @change="onUploadFileDone">
|
||||
|
||||
</div>
|
||||
</Col>
|
||||
<Col :span=12>
|
||||
@ -90,7 +96,7 @@
|
||||
gutters: ['CodeMirror-linenumbers', 'CodeMirror-foldgutter'],
|
||||
// 选中文本自动高亮,及高亮方式
|
||||
styleSelectedText: true,
|
||||
lineWrapping: false,
|
||||
lineWrapping: true,
|
||||
highlightSelectionMatches: {showToken: /\w/, annotateScrollbar: true}
|
||||
},
|
||||
mode: {
|
||||
@ -128,6 +134,20 @@
|
||||
},
|
||||
onResetClick () {
|
||||
this.$emit('resetCode')
|
||||
},
|
||||
onUploadFile () {
|
||||
document.getElementById('file-uploader').click()
|
||||
},
|
||||
onUploadFileDone () {
|
||||
let f = document.getElementById('file-uploader').files[0]
|
||||
let fileReader = new window.FileReader()
|
||||
let self = this
|
||||
fileReader.onload = function (e) {
|
||||
var text = e.target.result
|
||||
self.editor.setValue(text)
|
||||
document.getElementById('file-uploader').value = ''
|
||||
}
|
||||
fileReader.readAsText(f, 'UTF-8')
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -8,10 +8,10 @@
|
||||
<p class="title">{{$t('m.Description')}}</p>
|
||||
<p class="content" v-html=problem.description></p>
|
||||
<!-- {{$t('m.music')}} -->
|
||||
<p class="title">{{$t('m.Input')}}</p>
|
||||
<p class="title">{{$t('m.Input')}} <span v-if="problem.io_mode.io_mode=='File IO'">({{$t('m.FromFile')}}: {{ problem.io_mode.input }})</span></p>
|
||||
<p class="content" v-html=problem.input_description></p>
|
||||
|
||||
<p class="title">{{$t('m.Output')}}</p>
|
||||
<p class="title">{{$t('m.Output')}} <span v-if="problem.io_mode.io_mode=='File IO'">({{$t('m.ToFile')}}: {{ problem.io_mode.output }})</span></p>
|
||||
<p class="content" v-html=problem.output_description></p>
|
||||
|
||||
<div v-for="(sample, index) of problem.samples" :key="index">
|
||||
@ -147,6 +147,11 @@
|
||||
<li>
|
||||
<p>{{$t('m.Memory_Limit')}}</p>
|
||||
<p>{{problem.memory_limit}}MB</p></li>
|
||||
<li>
|
||||
<li>
|
||||
<p>{{$t('m.IOMode')}}</p>
|
||||
<p>{{problem.io_mode.io_mode}}</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>{{$t('m.Created')}}</p>
|
||||
<p>{{problem.created_by.username}}</p></li>
|
||||
@ -242,7 +247,8 @@
|
||||
created_by: {
|
||||
username: ''
|
||||
},
|
||||
tags: []
|
||||
tags: [],
|
||||
io_mode: {'io_mode': 'Standard IO'}
|
||||
},
|
||||
pie: pie,
|
||||
largePie: largePie,
|
||||
|
@ -134,7 +134,7 @@
|
||||
let columns = baseColumn
|
||||
if (data.info && data.info.data && !this.isConcat) {
|
||||
// score exist means the submission is OI problem submission
|
||||
if (data.info.data[0].score) {
|
||||
if (data.info.data[0].score !== undefined) {
|
||||
this.isConcat = true
|
||||
columns = columns.concat(scoreColumn)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user