增加代码高亮highlight.js; 增加提交也导航,将导航组件抽离以便复用。

This commit is contained in:
zemal 2017-07-06 21:07:13 +08:00
parent f3f94bdb75
commit 1e6a8e1ac2
12 changed files with 163 additions and 187 deletions

14
oj/package-lock.json generated
View File

@ -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",

View File

@ -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"
},

View File

@ -212,7 +212,9 @@ export default {
}
})
},
getSubmissionList(params) {
getSubmissionList(offset, limit, params) {
params.limit = limit
params.offset = offset
return ajax('submissions', 'get', {
options: {
params

View 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>

View 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>

View File

@ -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>

View File

@ -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>

View File

@ -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)

View File

@ -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>

View File

@ -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>

View File

@ -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
})
}
},

View File

@ -7,6 +7,7 @@
<script>
// import api from '@/api'
export default {
name: 'test',
components: {
},
data() {
@ -15,8 +16,7 @@
},
mounted() {
},
methods: {
}
methods: {}
}
</script>