mirror of
https://github.com/QingdaoU/OnlineJudgeFE.git
synced 2024-12-29 16:01:51 +00:00
增加代码高亮highlight.js; 增加提交也导航,将导航组件抽离以便复用。
This commit is contained in:
parent
f3f94bdb75
commit
1e6a8e1ac2
14
oj/package-lock.json
generated
14
oj/package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "oj",
|
||||
"version": "1.0.0",
|
||||
"name": "onlinejudge",
|
||||
"version": "2.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"abbrev": {
|
||||
@ -2752,6 +2752,11 @@
|
||||
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
|
||||
"dev": true
|
||||
},
|
||||
"highlight.js": {
|
||||
"version": "9.12.0",
|
||||
"resolved": "http://registry.npm.taobao.org/highlight.js/download/highlight.js-9.12.0.tgz",
|
||||
"integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4="
|
||||
},
|
||||
"hmac-drbg": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "http://registry.npm.taobao.org/hmac-drbg/download/hmac-drbg-1.0.1.tgz",
|
||||
@ -5136,6 +5141,11 @@
|
||||
"resolved": "http://registry.npm.taobao.org/vue-codemirror/download/vue-codemirror-3.0.8.tgz",
|
||||
"integrity": "sha1-oBG0fOvX5WWabCRktwAkGhjcbWc="
|
||||
},
|
||||
"vue-highlightjs": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "http://registry.npm.taobao.org/vue-highlightjs/download/vue-highlightjs-1.3.3.tgz",
|
||||
"integrity": "sha1-KaDVcTL8HOFc+mHolpGPW3GMXVI="
|
||||
},
|
||||
"vue-hot-reload-api": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "http://registry.npm.taobao.org/vue-hot-reload-api/download/vue-hot-reload-api-2.1.0.tgz",
|
||||
|
@ -18,6 +18,7 @@
|
||||
"moment": "^2.18.1",
|
||||
"vue": "^2.3.3",
|
||||
"vue-codemirror": "^3.0.8",
|
||||
"vue-highlightjs": "^1.3.3",
|
||||
"vue-resource": "^1.3.4",
|
||||
"vue-router": "^2.6.0"
|
||||
},
|
||||
|
@ -212,7 +212,9 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
getSubmissionList(params) {
|
||||
getSubmissionList(offset, limit, params) {
|
||||
params.limit = limit
|
||||
params.offset = offset
|
||||
return ajax('submissions', 'get', {
|
||||
options: {
|
||||
params
|
||||
|
43
oj/src/components/Highlight.vue
Normal file
43
oj/src/components/Highlight.vue
Normal file
@ -0,0 +1,43 @@
|
||||
<template>
|
||||
<div class="code_container">
|
||||
<pre v-highlightjs="code"><code :class="language" :style="styleObject"></code></pre>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'highlight',
|
||||
data() {
|
||||
return {
|
||||
styleObject: {
|
||||
'border-left': '2px solid green'
|
||||
}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
language: {
|
||||
type: String
|
||||
},
|
||||
code: {
|
||||
required: true,
|
||||
type: String
|
||||
},
|
||||
borderColor: {
|
||||
type: String,
|
||||
default: 'green'
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'borderColor'(newVal, oldVal) {
|
||||
this.styleObject['border-left'] = '2px solid ' + newVal
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
code {
|
||||
padding: 20px;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
</style>
|
33
oj/src/components/Pagination.vue
Normal file
33
oj/src/components/Pagination.vue
Normal file
@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="page">
|
||||
<Page class="pagination" :total="total" :page-size="pageSize" @on-change="onChange"></Page>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'pagina',
|
||||
props: {
|
||||
total: {
|
||||
required: true,
|
||||
type: Number
|
||||
},
|
||||
pageSize: {
|
||||
required: true,
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onChange(page) {
|
||||
this.$emit('on-change', page)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
.page {
|
||||
margin: 20px;
|
||||
float: right;
|
||||
}
|
||||
</style>
|
@ -1,71 +0,0 @@
|
||||
<template>
|
||||
<div class="panel" :class="{'small': small}">
|
||||
<header>
|
||||
<h2>{{title}}</h2>
|
||||
<div class="header_right">
|
||||
<slot name="header"></slot>
|
||||
</div>
|
||||
</header>
|
||||
<div class="body">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default{
|
||||
name: 'Panel',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
small: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="less">
|
||||
.panel{
|
||||
margin-bottom: 20px;
|
||||
background-color: #fff;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 1px 1px rgba(0,0,0,.05);
|
||||
&.small{
|
||||
max-width: 830px;
|
||||
min-width: 700px;
|
||||
margin-left: 20px;
|
||||
margin-top: 10px;
|
||||
}
|
||||
header{
|
||||
position: relative;
|
||||
z-index: 10;
|
||||
>h2{
|
||||
margin: 0;
|
||||
color: #333;
|
||||
border-color: #ddd;
|
||||
font-size: 20px;
|
||||
font-weight: 300;
|
||||
letter-spacing: 0.025em;
|
||||
height: 66px;
|
||||
line-height: 45px;
|
||||
padding: 10px 15px;
|
||||
border-bottom: 1px solid #eee;
|
||||
border-top-left-radius: 3px;
|
||||
border-top-right-radius: 3px;
|
||||
}
|
||||
>.header_right{
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
right: 20px;
|
||||
transform: translate(0,-50%);
|
||||
}
|
||||
}
|
||||
.body{
|
||||
padding: 15px 20px 30px 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,68 +0,0 @@
|
||||
<template>
|
||||
<textarea ref="editor">
|
||||
</textarea>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Simditor from 'simditor'
|
||||
import 'simditor/styles/simditor.css'
|
||||
import 'simditor-markdown'
|
||||
import 'simditor-markdown/styles/simditor-markdown.css'
|
||||
export default {
|
||||
name: 'Simditor',
|
||||
props: {
|
||||
toolbar: {
|
||||
type: Array,
|
||||
default: () => ['title', 'bold', 'italic', 'underline', 'fontScale', 'color', 'ol', 'ul', '|', 'link', 'image', 'hr', '|', 'indent', 'outdent', 'alignment', '|', 'markdown']
|
||||
},
|
||||
value: {
|
||||
type: String,
|
||||
default: ''
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editor: null,
|
||||
currentValue: this.value
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
Simditor.locale = 'en-US'
|
||||
this.editor = new Simditor({
|
||||
textarea: this.$refs.editor,
|
||||
placeholder: this.placeholder,
|
||||
toolbar: this.toolbar,
|
||||
pasteImage: true,
|
||||
markdown: true
|
||||
})
|
||||
this.editor.on('decorate', (e, src) => {
|
||||
this.currentValue = this.editor.getValue()
|
||||
})
|
||||
let simditorBody = this.$el.parentNode.querySelector('.simditor-body')
|
||||
if (simditorBody !== undefined) {
|
||||
simditorBody.oninput = () => {
|
||||
this.currentValue = this.editor.getValue()
|
||||
}
|
||||
}
|
||||
this.editor.setValue(this.value)
|
||||
},
|
||||
watch: {
|
||||
'value'(val) {
|
||||
if (this.currentValue !== val) {
|
||||
this.currentValue = val
|
||||
this.editor.setValue(val)
|
||||
}
|
||||
},
|
||||
'currentValue'(newVal, oldVal) {
|
||||
if (newVal !== oldVal) {
|
||||
this.$emit('change', newVal)
|
||||
this.$emit('input', newVal)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
@ -2,9 +2,12 @@ import Vue from 'vue'
|
||||
import App from './App.vue'
|
||||
import router from './routers/index'
|
||||
import iView from 'iview'
|
||||
import VueHighlightJS from 'vue-highlightjs'
|
||||
import locale from 'iview/src/locale/lang/en-US'
|
||||
|
||||
import 'iview/dist/styles/iview.css'
|
||||
import 'font-awesome/css/font-awesome.min.css'
|
||||
import 'highlight.js/styles/atom-one-light.css'
|
||||
|
||||
import * as filters from './utils/filters.js'
|
||||
|
||||
@ -18,6 +21,8 @@ Object.keys(filters).forEach(key => {
|
||||
})
|
||||
|
||||
Vue.use(iView, {locale})
|
||||
Vue.use(VueHighlightJS)
|
||||
|
||||
// Vue.use(VueI18n)
|
||||
// Vue.component(IconBtn.name, IconBtn)
|
||||
// Vue.component(Panel.name, Panel)
|
||||
|
@ -22,7 +22,7 @@
|
||||
<Col :span="7">
|
||||
<Form-item style="float: right">
|
||||
<Button type="ghost" @click="onReset" style="margin-right: 10px;">Reset</Button>
|
||||
<Button type="primary">Filter</Button>
|
||||
<Button type="primary" @click="onFilter">Filter</Button>
|
||||
</Form-item>
|
||||
</Col>
|
||||
</Row>
|
||||
@ -30,7 +30,7 @@
|
||||
</div>
|
||||
<Table style="width: 100%" :columns="problemTableColumns" :data="problemList" stripe></Table>
|
||||
</Card>
|
||||
<Page class="pagination" :total="total" :page-size="pageSize" @on-change="changePage"></Page>
|
||||
<Pagination :total="total" :page-size="pageSize" @on-change="changePage"></Pagination>
|
||||
|
||||
</Col>
|
||||
|
||||
@ -43,9 +43,13 @@
|
||||
|
||||
<script>
|
||||
import api from '../../api.js'
|
||||
import Pagination from '../../components/Pagination'
|
||||
|
||||
export default {
|
||||
name: 'ProblemList',
|
||||
|
||||
components: {
|
||||
Pagination
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
tagTableColumns: [
|
||||
@ -124,7 +128,6 @@
|
||||
},
|
||||
created() {
|
||||
this.routeName = this.$route.name
|
||||
// this.contestId = this.$route.params.contestId
|
||||
this.getTagList()
|
||||
this.getProblemList()
|
||||
},
|
||||
@ -140,9 +143,8 @@
|
||||
},
|
||||
getProblemList(page = 1) {
|
||||
let self = this
|
||||
let funcName = this.routeName === 'problem-list' ? 'getProblemList' : 'getContestProblemList'
|
||||
let offset = (page - 1) * this.pageSize
|
||||
api[funcName](offset, this.pageSize, {}, this.contestId).then(res => {
|
||||
api.getProblemList(offset, this.pageSize, {}, this.contestId).then(res => {
|
||||
self.$Loading.finish()
|
||||
this.total = res.data.data.total
|
||||
this.problemList = res.data.data.results
|
||||
@ -164,6 +166,9 @@
|
||||
difficulty: ''
|
||||
}
|
||||
this.getProblemList(1)
|
||||
},
|
||||
onFilter() {
|
||||
console.log(this.filterForm)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -177,9 +182,4 @@
|
||||
}
|
||||
}
|
||||
|
||||
.pagination {
|
||||
float: right;
|
||||
margin-top: 20px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
|
@ -1,28 +1,28 @@
|
||||
<template>
|
||||
<Row type="flex" justify="space-around">
|
||||
<Col :span="20" id="status">
|
||||
<Alert :type="type" showIcon>
|
||||
<span class="title">{{statusName}}</span>
|
||||
<div slot="desc" class="content">
|
||||
<template v-if="data.result == -2">
|
||||
{{data.statistic_info.err_info}}
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>Time: {{data.statistic_info.time_cost}}MS</span>
|
||||
<span>Memory: {{parseMemory(data.statistic_info.memory_cost)}}MB</span>
|
||||
<span>Lang: {{data.language}}</span>
|
||||
</template>
|
||||
</div>
|
||||
</Alert>
|
||||
<Alert :type="type" showIcon>
|
||||
<span class="title">{{statusName}}</span>
|
||||
<div slot="desc" class="content">
|
||||
<template v-if="data.result == -2">
|
||||
{{data.statistic_info.err_info}}
|
||||
</template>
|
||||
<template v-else>
|
||||
<span>Time: {{data.statistic_info.time_cost}}MS</span>
|
||||
<span>Memory: {{parseMemory(data.statistic_info.memory_cost)}}MB</span>
|
||||
<span>Lang: {{data.language}}</span>
|
||||
</template>
|
||||
</div>
|
||||
</Alert>
|
||||
</Col>
|
||||
|
||||
<!-- OI模式后台会返info -->
|
||||
<Col v-if="data.info && data.result != -2" :span="20">
|
||||
<Table stripe :disabled-hover="true" :columns="columns" :data="data.info.data"></Table>
|
||||
<Table stripe :disabled-hover="true" :columns="columns" :data="data.info.data"></Table>
|
||||
</Col>
|
||||
|
||||
<Col :span="20">
|
||||
<pre>{{data.code}}</pre>
|
||||
<Highlight :code="data.code" :language="data.language" :border-color="color"></Highlight>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
@ -32,8 +32,12 @@
|
||||
import api from '@/api'
|
||||
import {STATUS} from '@/utils/consts'
|
||||
import utils from '@/utils/utils'
|
||||
import Highlight from '@/components/Highlight'
|
||||
export default {
|
||||
name: 'submissionDetails',
|
||||
components: {
|
||||
Highlight
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
columns: [
|
||||
@ -70,6 +74,7 @@
|
||||
],
|
||||
data: {
|
||||
result: '0',
|
||||
code: '',
|
||||
info: {
|
||||
data: []
|
||||
},
|
||||
@ -86,7 +91,9 @@
|
||||
next((vm) => {
|
||||
vm.data = res.data.data
|
||||
})
|
||||
}, (res) => { next() })
|
||||
}, (res) => {
|
||||
next()
|
||||
})
|
||||
},
|
||||
methods: {
|
||||
parseMemory(memory) {
|
||||
@ -99,22 +106,25 @@
|
||||
},
|
||||
statusName() {
|
||||
return STATUS[this.data.result].name
|
||||
},
|
||||
color() {
|
||||
return STATUS[this.data.result].color
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped lang="less">
|
||||
#status {
|
||||
.title {
|
||||
font-size: 20px;
|
||||
}
|
||||
.content {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
span {
|
||||
margin-right: 10px;
|
||||
#status {
|
||||
.title {
|
||||
font-size: 20px;
|
||||
}
|
||||
.content {
|
||||
margin-top: 10px;
|
||||
font-size: 14px;
|
||||
span {
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -2,6 +2,7 @@
|
||||
<Row type="flex" justify="space-around">
|
||||
<Col :span="23">
|
||||
<Table stripe :disabled-hover="true" :columns="columns" :data="submissions"></Table>
|
||||
<Pagination :total="total" :pageSize="pageSize" @on-change="changePage"></Pagination>
|
||||
</Col>
|
||||
</Row>
|
||||
</template>
|
||||
@ -11,8 +12,13 @@
|
||||
import bus from '@/utils/eventBus'
|
||||
import {STATUS} from '@/utils/consts'
|
||||
import utils from '@/utils/utils'
|
||||
import Pagination from '@/components/Pagination'
|
||||
|
||||
export default {
|
||||
name: 'submissionList',
|
||||
components: {
|
||||
Pagination
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
columns: [
|
||||
@ -104,7 +110,9 @@
|
||||
key: 'username'
|
||||
}
|
||||
],
|
||||
submissions: []
|
||||
submissions: [],
|
||||
total: 30,
|
||||
pageSize: 10
|
||||
}
|
||||
},
|
||||
created() {
|
||||
@ -120,15 +128,18 @@
|
||||
})
|
||||
}
|
||||
},
|
||||
changePage(page) {
|
||||
this.getSubmissions((page - 1) * this.pageSize, this.pageSize)
|
||||
},
|
||||
// TODO myself 添加切换按钮
|
||||
getSubmissions() {
|
||||
getSubmissions(offset = 0, limit = this.pageSize) {
|
||||
let params = {
|
||||
myself: 1,
|
||||
myself: 0,
|
||||
problem_id: this.$route.params.id
|
||||
}
|
||||
api.getSubmissionList(params).then((res) => {
|
||||
console.log(res.data.data)
|
||||
this.submissions = res.data.data
|
||||
api.getSubmissionList(offset, limit, params).then((res) => {
|
||||
this.submissions = res.data.data.results
|
||||
this.total = res.data.data.total
|
||||
})
|
||||
}
|
||||
},
|
||||
|
@ -7,6 +7,7 @@
|
||||
<script>
|
||||
// import api from '@/api'
|
||||
export default {
|
||||
name: 'test',
|
||||
components: {
|
||||
},
|
||||
data() {
|
||||
@ -15,8 +16,7 @@
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
methods: {
|
||||
}
|
||||
methods: {}
|
||||
}
|
||||
</script>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user