mirror of
https://github.com/QingdaoU/OnlineJudgeFE.git
synced 2024-12-29 16:01:51 +00:00
优化加载本地保存的代码的逻辑; 部分细节优化
This commit is contained in:
parent
1910fc3bb0
commit
67c3b97be8
@ -1,11 +1,11 @@
|
|||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "6.2.2"
|
- "6.11.2"
|
||||||
env:
|
env:
|
||||||
- CXX=g++-4.8
|
- CXX=g++-4.8
|
||||||
script:
|
script:
|
||||||
- cd admin
|
|
||||||
- npm install
|
- npm install
|
||||||
|
- npm run build:dll
|
||||||
- npm run build
|
- npm run build
|
||||||
addons:
|
addons:
|
||||||
apt:
|
apt:
|
||||||
|
@ -32,10 +32,9 @@ rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => {
|
|||||||
process.exit(1)
|
process.exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(chalk.cyan(' Build complete.\n'))
|
console.log(chalk.cyan(' Congratulations, the project build complete without error\n'))
|
||||||
console.log(chalk.yellow(
|
console.log(chalk.yellow(
|
||||||
' Tip: built files are meant to be served over an HTTP server.\n' +
|
' You can now check the onlinejudge in http://YouIP/'
|
||||||
' Opening index.html over file:// won\'t work.\n'
|
|
||||||
))
|
))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -19,15 +19,11 @@
|
|||||||
</Tag>
|
</Tag>
|
||||||
</div>
|
</div>
|
||||||
<div v-html="contest.description"></div>
|
<div v-html="contest.description"></div>
|
||||||
<div v-if="passwordFormVisible">
|
<div v-if="passwordFormVisible" class="contest-password">
|
||||||
<Form inline class="contest-password">
|
<Input v-model="contestPassword" type="password"
|
||||||
<FormItem>
|
placeholder="contest password" class="contest-password-input"
|
||||||
<Input v-model="contestPassword" type="password" placeholder="contest password"/>
|
@on-enter="checkPassword" />
|
||||||
</FormItem>
|
<Button type="info" @click="checkPassword">Enter</Button>
|
||||||
<FormItem>
|
|
||||||
<Button type="info" @click="checkPassword">Enter</Button>
|
|
||||||
</FormItem>
|
|
||||||
</Form>
|
|
||||||
</div>
|
</div>
|
||||||
</Panel>
|
</Panel>
|
||||||
<Table :columns="columns" :data="contest_table" disabled-hover style="margin-bottom: 40px;"></Table>
|
<Table :columns="columns" :data="contest_table" disabled-hover style="margin-bottom: 40px;"></Table>
|
||||||
@ -61,7 +57,7 @@
|
|||||||
:disabled="contestMenuDisabled"
|
:disabled="contestMenuDisabled"
|
||||||
:route="{name: 'contest-rank', params: {contestID: contestID}}">
|
:route="{name: 'contest-rank', params: {contestID: contestID}}">
|
||||||
<Icon type="stats-bars"></Icon>
|
<Icon type="stats-bars"></Icon>
|
||||||
Ranklist
|
Rankings
|
||||||
</VerticalMenu-item>
|
</VerticalMenu-item>
|
||||||
|
|
||||||
<VerticalMenu-item :route="{name: 'contest-details', params: {contestID: contestID}}">
|
<VerticalMenu-item :route="{name: 'contest-details', params: {contestID: contestID}}">
|
||||||
@ -205,6 +201,10 @@
|
|||||||
.contest-password {
|
.contest-password {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
margin-bottom: -10px;
|
margin-bottom: -10px;
|
||||||
|
&-input {
|
||||||
|
width: 200px;
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p style="margin-top: 10px">
|
<p style="margin-top: 10px">
|
||||||
<span>Auto Refresh(10s)</span>
|
<span>Auto Refresh(10s)</span>
|
||||||
<i-switch @on-change="handleAutoRefresh"></i-switch>
|
<i-switch :disabled="refreshDisabled" @on-change="handleAutoRefresh"></i-switch>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Poptip>
|
</Poptip>
|
||||||
@ -32,18 +32,20 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import moment from 'moment'
|
import moment from 'moment'
|
||||||
import Pagination from '@oj/components/Pagination'
|
import { mapActions } from 'vuex'
|
||||||
|
|
||||||
import { mapActions, mapState } from 'vuex'
|
import Pagination from '@oj/components/Pagination'
|
||||||
import { types } from '@oj/store'
|
import ContestRankMixin from './contestRankMixin'
|
||||||
import api from '@oj/api'
|
import api from '@oj/api'
|
||||||
import time from '@/utils/time'
|
import time from '@/utils/time'
|
||||||
|
import utils from '@/utils/utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'acm-contest-rank',
|
name: 'acm-contest-rank',
|
||||||
components: {
|
components: {
|
||||||
Pagination
|
Pagination
|
||||||
},
|
},
|
||||||
|
mixins: [ContestRankMixin],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
total: 0,
|
total: 0,
|
||||||
@ -60,7 +62,6 @@
|
|||||||
{
|
{
|
||||||
title: 'User',
|
title: 'User',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 250,
|
|
||||||
render: (h, params) => {
|
render: (h, params) => {
|
||||||
return h('Button', {
|
return h('Button', {
|
||||||
props: {
|
props: {
|
||||||
@ -69,6 +70,9 @@
|
|||||||
'class': {
|
'class': {
|
||||||
'link-button': true
|
'link-button': true
|
||||||
},
|
},
|
||||||
|
style: {
|
||||||
|
'max-width': '150px'
|
||||||
|
},
|
||||||
on: {
|
on: {
|
||||||
click: () => {
|
click: () => {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
@ -132,7 +136,7 @@
|
|||||||
right: 0,
|
right: 0,
|
||||||
data: [],
|
data: [],
|
||||||
formatter: (value) => {
|
formatter: (value) => {
|
||||||
return value.replace(/(.{16})/g, '$1\n')
|
return utils.breakLongWords(value, 16)
|
||||||
},
|
},
|
||||||
textStyle: {
|
textStyle: {
|
||||||
fontSize: 12
|
fontSize: 12
|
||||||
@ -140,7 +144,7 @@
|
|||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
x: 80,
|
x: 80,
|
||||||
x2: 250
|
x2: 200
|
||||||
},
|
},
|
||||||
xAxis: [{
|
xAxis: [{
|
||||||
type: 'time',
|
type: 'time',
|
||||||
@ -266,6 +270,9 @@
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
size: 'large'
|
size: 'large'
|
||||||
},
|
},
|
||||||
|
style: {
|
||||||
|
padding: 0
|
||||||
|
},
|
||||||
on: {
|
on: {
|
||||||
click: () => {
|
click: () => {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
@ -294,55 +301,7 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
|
||||||
handleAutoRefresh (status) {
|
|
||||||
if (status === true) {
|
|
||||||
this.refreshFunc = setInterval(() => {
|
|
||||||
this.getContestRankData(1, true)
|
|
||||||
}, 10000)
|
|
||||||
} else {
|
|
||||||
clearInterval(this.refreshFunc)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState({
|
|
||||||
'contest': state => state.contest.contest,
|
|
||||||
'contestProblems': state => state.contest.contestProblems
|
|
||||||
}),
|
|
||||||
showChart: {
|
|
||||||
get () {
|
|
||||||
return this.$store.state.contest.showChart
|
|
||||||
},
|
|
||||||
set (value) {
|
|
||||||
this.$store.commit(types.CHANGE_CONTEST_CHART_VISIBLE, {visible: value})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showMenu: {
|
|
||||||
get () {
|
|
||||||
return this.$store.state.contest.showMenu
|
|
||||||
},
|
|
||||||
set (value) {
|
|
||||||
this.$store.commit(types.CHANGE_CONTEST_MENU_VISIBLE, {visible: value})
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.tableRank.handleResize()
|
|
||||||
if (this.showChart) {
|
|
||||||
this.$refs.chart.resize()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
limit: {
|
|
||||||
get () {
|
|
||||||
return this.$store.state.contest.rankLimit
|
|
||||||
},
|
|
||||||
set (value) {
|
|
||||||
this.$store.commit(types.CHANGE_CONTEST_RANK_LIMIT, {rankLimit: value})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy () {
|
|
||||||
clearInterval(this.refreshFunc)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
</p>
|
</p>
|
||||||
<p style="margin-top: 10px">
|
<p style="margin-top: 10px">
|
||||||
<span>Auto Refresh(10s)</span>
|
<span>Auto Refresh(10s)</span>
|
||||||
<i-switch @on-change="handleAutoRefresh"></i-switch>
|
<i-switch :disabled="refreshDisabled" @on-change="handleAutoRefresh"></i-switch>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</Poptip>
|
</Poptip>
|
||||||
@ -31,10 +31,11 @@
|
|||||||
</Panel>
|
</Panel>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import Pagination from '@oj/components/Pagination'
|
import { mapActions } from 'vuex'
|
||||||
|
|
||||||
import { mapActions, mapState } from 'vuex'
|
import Pagination from '@oj/components/Pagination'
|
||||||
import { types } from '@oj/store'
|
import ContestRankMixin from './contestRankMixin'
|
||||||
|
import utils from '@/utils/utils'
|
||||||
import api from '@oj/api'
|
import api from '@oj/api'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -42,6 +43,7 @@
|
|||||||
components: {
|
components: {
|
||||||
Pagination
|
Pagination
|
||||||
},
|
},
|
||||||
|
mixins: [ContestRankMixin],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
total: 0,
|
total: 0,
|
||||||
@ -58,7 +60,6 @@
|
|||||||
{
|
{
|
||||||
title: 'User',
|
title: 'User',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 250,
|
|
||||||
render: (h, params) => {
|
render: (h, params) => {
|
||||||
return h('Button', {
|
return h('Button', {
|
||||||
props: {
|
props: {
|
||||||
@ -67,6 +68,9 @@
|
|||||||
'class': {
|
'class': {
|
||||||
'link-button': true
|
'link-button': true
|
||||||
},
|
},
|
||||||
|
style: {
|
||||||
|
'max-width': '150px'
|
||||||
|
},
|
||||||
on: {
|
on: {
|
||||||
click: () => {
|
click: () => {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
@ -116,7 +120,7 @@
|
|||||||
showMaxLabel: true,
|
showMaxLabel: true,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
formatter: (value, index) => {
|
formatter: (value, index) => {
|
||||||
return value.replace(/(.{8})/g, '$1\n')
|
return utils.breakLongWords(value, 14)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
axisTick: {
|
axisTick: {
|
||||||
@ -207,6 +211,9 @@
|
|||||||
type: 'text',
|
type: 'text',
|
||||||
size: 'large'
|
size: 'large'
|
||||||
},
|
},
|
||||||
|
style: {
|
||||||
|
padding: 0
|
||||||
|
},
|
||||||
on: {
|
on: {
|
||||||
click: () => {
|
click: () => {
|
||||||
this.$router.push({
|
this.$router.push({
|
||||||
@ -225,55 +232,7 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
},
|
|
||||||
handleAutoRefresh (status) {
|
|
||||||
if (status === true) {
|
|
||||||
this.refreshFunc = setInterval(() => {
|
|
||||||
this.getContestRankData(1, true)
|
|
||||||
}, 10000)
|
|
||||||
} else {
|
|
||||||
clearInterval(this.refreshFunc)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
...mapState({
|
|
||||||
'contest': state => state.contest.contest,
|
|
||||||
'contestProblems': state => state.contest.contestProblems
|
|
||||||
}),
|
|
||||||
showChart: {
|
|
||||||
get () {
|
|
||||||
return this.$store.state.contest.showChart
|
|
||||||
},
|
|
||||||
set (value) {
|
|
||||||
this.$store.commit(types.CHANGE_CONTEST_CHART_VISIBLE, {visible: value})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
showMenu: {
|
|
||||||
get () {
|
|
||||||
return this.$store.state.contest.showMenu
|
|
||||||
},
|
|
||||||
set (value) {
|
|
||||||
this.$store.commit(types.CHANGE_CONTEST_MENU_VISIBLE, {visible: value})
|
|
||||||
this.$nextTick(() => {
|
|
||||||
this.$refs.tableRank.handleResize()
|
|
||||||
if (this.showChart) {
|
|
||||||
this.$refs.chart.resize()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
limit: {
|
|
||||||
get () {
|
|
||||||
return this.$store.state.contest.rankLimit
|
|
||||||
},
|
|
||||||
set (value) {
|
|
||||||
this.$store.commit(types.CHANGE_CONTEST_RANK_LIMIT, {rankLimit: value})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy () {
|
|
||||||
clearInterval(this.refreshFunc)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
60
src/pages/oj/views/contest/children/contestRankMixin.js
Normal file
60
src/pages/oj/views/contest/children/contestRankMixin.js
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
import { mapState } from 'vuex'
|
||||||
|
import { types } from '@oj/store/index'
|
||||||
|
import { CONTEST_STATUS } from '@/utils/constants'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
methods: {
|
||||||
|
handleAutoRefresh (status) {
|
||||||
|
if (status === true) {
|
||||||
|
this.refreshFunc = setInterval(() => {
|
||||||
|
this.page = 1
|
||||||
|
this.getContestRankData(1, true)
|
||||||
|
}, 10000)
|
||||||
|
} else {
|
||||||
|
clearInterval(this.refreshFunc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapState({
|
||||||
|
'contest': state => state.contest.contest,
|
||||||
|
'contestProblems': state => state.contest.contestProblems
|
||||||
|
}),
|
||||||
|
showChart: {
|
||||||
|
get () {
|
||||||
|
return this.$store.state.contest.showChart
|
||||||
|
},
|
||||||
|
set (value) {
|
||||||
|
this.$store.commit(types.CHANGE_CONTEST_CHART_VISIBLE, {visible: value})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
showMenu: {
|
||||||
|
get () {
|
||||||
|
return this.$store.state.contest.showMenu
|
||||||
|
},
|
||||||
|
set (value) {
|
||||||
|
this.$store.commit(types.CHANGE_CONTEST_MENU_VISIBLE, {visible: value})
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$refs.tableRank.handleResize()
|
||||||
|
if (this.showChart) {
|
||||||
|
this.$refs.chart.resize()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
},
|
||||||
|
refreshDisabled () {
|
||||||
|
return this.contest.status === CONTEST_STATUS.ENDED
|
||||||
|
},
|
||||||
|
limit: {
|
||||||
|
get () {
|
||||||
|
return this.$store.state.contest.rankLimit
|
||||||
|
},
|
||||||
|
set (value) {
|
||||||
|
this.$store.commit(types.CHANGE_CONTEST_RANK_LIMIT, {rankLimit: value})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
beforeDestroy () {
|
||||||
|
clearInterval(this.refreshFunc)
|
||||||
|
}
|
||||||
|
}
|
@ -26,6 +26,7 @@
|
|||||||
</CarouselItem>
|
</CarouselItem>
|
||||||
</Carousel>
|
</Carousel>
|
||||||
</panel>
|
</panel>
|
||||||
|
|
||||||
<Announcements class="announcement"></Announcements>
|
<Announcements class="announcement"></Announcements>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
|
@ -105,7 +105,7 @@
|
|||||||
<VerticalMenu-item v-if="!this.contestID || OIContestRealTimePermission"
|
<VerticalMenu-item v-if="!this.contestID || OIContestRealTimePermission"
|
||||||
:route="{name: 'contest-rank', params: {contestID: contestID}}">
|
:route="{name: 'contest-rank', params: {contestID: contestID}}">
|
||||||
<Icon type="stats-bars"></Icon>
|
<Icon type="stats-bars"></Icon>
|
||||||
Ranklist
|
Rankings
|
||||||
</VerticalMenu-item>
|
</VerticalMenu-item>
|
||||||
<VerticalMenu-item :route="{name: 'contest-details', params: {contestID: contestID}}">
|
<VerticalMenu-item :route="{name: 'contest-details', params: {contestID: contestID}}">
|
||||||
<Icon type="home"></Icon>
|
<Icon type="home"></Icon>
|
||||||
@ -184,7 +184,7 @@
|
|||||||
import storage from '@/utils/storage'
|
import storage from '@/utils/storage'
|
||||||
import { FormMixin } from '@oj/components/mixins'
|
import { FormMixin } from '@oj/components/mixins'
|
||||||
import { types } from '@oj/store'
|
import { types } from '@oj/store'
|
||||||
import { JUDGE_STATUS, CONTEST_STATUS, STORAGE_KEY } from '@/utils/constants'
|
import { JUDGE_STATUS, CONTEST_STATUS, buildProblemCodeKey } from '@/utils/constants'
|
||||||
import api from '@oj/api'
|
import api from '@oj/api'
|
||||||
|
|
||||||
import { pie, largePie } from './chartData'
|
import { pie, largePie } from './chartData'
|
||||||
@ -231,6 +231,16 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
beforeRouteEnter (to, from, next) {
|
||||||
|
let problemCode = storage.get(buildProblemCodeKey(to.params.problemID, to.params.contestID))
|
||||||
|
if (problemCode) {
|
||||||
|
next(vm => {
|
||||||
|
vm.language = problemCode.language
|
||||||
|
vm.code = problemCode.code
|
||||||
|
})
|
||||||
|
}
|
||||||
|
next()
|
||||||
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
this.$store.commit(types.CHANGE_CONTEST_MENU_VISIBLE, {visible: false})
|
this.$store.commit(types.CHANGE_CONTEST_MENU_VISIBLE, {visible: false})
|
||||||
this.init()
|
this.init()
|
||||||
@ -245,16 +255,13 @@
|
|||||||
this.$Loading.finish()
|
this.$Loading.finish()
|
||||||
this.problem = res.data.data
|
this.problem = res.data.data
|
||||||
this.changePie(res.data.data)
|
this.changePie(res.data.data)
|
||||||
let problemCode = storage.get(STORAGE_KEY.PROBLEM_CODE + this.problem.id)
|
|
||||||
|
// 在beforeRouteEnter中修改了, 说明本地有code, 无需加载template
|
||||||
|
if (this.language !== 'C++' || this.code !== '') {
|
||||||
|
return
|
||||||
|
}
|
||||||
let template = this.problem.template
|
let template = this.problem.template
|
||||||
if (problemCode) {
|
if (template && template[this.language]) {
|
||||||
this.language = problemCode.language
|
|
||||||
if (problemCode.code === '' && template[this.language]) {
|
|
||||||
this.code = template[this.language]
|
|
||||||
} else {
|
|
||||||
this.code = problemCode.code
|
|
||||||
}
|
|
||||||
} else if (template[this.language]) {
|
|
||||||
this.code = template[this.language]
|
this.code = template[this.language]
|
||||||
}
|
}
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
@ -391,8 +398,9 @@
|
|||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
// 防止切换组件后仍然不断请求
|
// 防止切换组件后仍然不断请求
|
||||||
clearInterval(this.refreshStatus)
|
clearInterval(this.refreshStatus)
|
||||||
|
|
||||||
this.$store.commit(types.CHANGE_CONTEST_MENU_VISIBLE, {visible: true})
|
this.$store.commit(types.CHANGE_CONTEST_MENU_VISIBLE, {visible: true})
|
||||||
storage.set(STORAGE_KEY.PROBLEM_CODE + this.problem.id, {
|
storage.set(buildProblemCodeKey(this.problem._id, this.$route.params.contestID), {
|
||||||
code: this.code,
|
code: this.code,
|
||||||
language: this.language
|
language: this.language
|
||||||
})
|
})
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
<Table style="width: 100%; font-size: 16px;"
|
<Table style="width: 100%; font-size: 16px;"
|
||||||
:columns="problemTableColumns"
|
:columns="problemTableColumns"
|
||||||
:data="problemList"
|
:data="problemList"
|
||||||
|
:loading="loadings.table"
|
||||||
disabled-hover></Table>
|
disabled-hover></Table>
|
||||||
</Panel>
|
</Panel>
|
||||||
<Pagination :total="total" :page-size="limit" @on-change="pushRouter" :current.sync="query.page"></Pagination>
|
<Pagination :total="total" :page-size="limit" @on-change="pushRouter" :current.sync="query.page"></Pagination>
|
||||||
@ -59,7 +60,7 @@
|
|||||||
Pick one
|
Pick one
|
||||||
</Button>
|
</Button>
|
||||||
</Panel>
|
</Panel>
|
||||||
<Spin v-if="spinShow" fix size="large"></Spin>
|
<Spin v-if="loadings.tag" fix size="large"></Spin>
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</template>
|
</template>
|
||||||
@ -145,16 +146,17 @@
|
|||||||
problemList: [],
|
problemList: [],
|
||||||
limit: 15,
|
limit: 15,
|
||||||
total: 0,
|
total: 0,
|
||||||
problemLoading: false,
|
loadings: {
|
||||||
tagLoading: false,
|
table: true,
|
||||||
|
tag: true
|
||||||
|
},
|
||||||
routeName: '',
|
routeName: '',
|
||||||
query: {
|
query: {
|
||||||
keyword: '',
|
keyword: '',
|
||||||
difficulty: '',
|
difficulty: '',
|
||||||
tag: '',
|
tag: '',
|
||||||
page: 1
|
page: 1
|
||||||
},
|
}
|
||||||
spinShow: true
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
@ -181,21 +183,24 @@
|
|||||||
},
|
},
|
||||||
getProblemList () {
|
getProblemList () {
|
||||||
let offset = (this.query.page - 1) * this.limit
|
let offset = (this.query.page - 1) * this.limit
|
||||||
|
this.loadings.table = true
|
||||||
api.getProblemList(offset, this.limit, this.query).then(res => {
|
api.getProblemList(offset, this.limit, this.query).then(res => {
|
||||||
|
this.loadings.table = false
|
||||||
this.total = res.data.data.total
|
this.total = res.data.data.total
|
||||||
this.problemList = res.data.data.results
|
this.problemList = res.data.data.results
|
||||||
if (this.isAuthenticated) {
|
if (this.isAuthenticated) {
|
||||||
this.addStatusColumn(this.problemTableColumns, res.data.data.results)
|
this.addStatusColumn(this.problemTableColumns, res.data.data.results)
|
||||||
}
|
}
|
||||||
}, res => {
|
}, res => {
|
||||||
|
this.loadings.table = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
getTagList () {
|
getTagList () {
|
||||||
api.getProblemTagList().then(res => {
|
api.getProblemTagList().then(res => {
|
||||||
this.tagList = res.data.data
|
this.tagList = res.data.data
|
||||||
this.spinShow = false
|
this.loadings.tag = false
|
||||||
}, res => {
|
}, res => {
|
||||||
this.spinShow = false
|
this.loadings.tag = false
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
filterByTag (tagName) {
|
filterByTag (tagName) {
|
||||||
|
@ -44,15 +44,17 @@
|
|||||||
{
|
{
|
||||||
title: 'user',
|
title: 'user',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 250,
|
|
||||||
render: (h, params) => {
|
render: (h, params) => {
|
||||||
return h('Button', {
|
return h('Button', {
|
||||||
props: {
|
props: {
|
||||||
type: 'text'
|
type: 'text'
|
||||||
},
|
},
|
||||||
class: {
|
'class': {
|
||||||
'link-button': true
|
'link-button': true
|
||||||
},
|
},
|
||||||
|
style: {
|
||||||
|
'max-width': '200px'
|
||||||
|
},
|
||||||
on: {
|
on: {
|
||||||
click: () => {
|
click: () => {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
@ -82,6 +84,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Rating',
|
title: 'Rating',
|
||||||
|
align: 'center',
|
||||||
render: (h, params) => {
|
render: (h, params) => {
|
||||||
return h('span', utils.getACRate(params.row.accepted_number, params.row.submission_number))
|
return h('span', utils.getACRate(params.row.accepted_number, params.row.submission_number))
|
||||||
}
|
}
|
||||||
@ -118,7 +121,7 @@
|
|||||||
showMaxLabel: true,
|
showMaxLabel: true,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
formatter: (value, index) => {
|
formatter: (value, index) => {
|
||||||
return value.replace(/(.{8})/g, '$1\n')
|
return utils.breakLongWords(value, 10)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -165,7 +168,7 @@
|
|||||||
api.getUserRank(offset, this.limit, RULE_TYPE.ACM).then(res => {
|
api.getUserRank(offset, this.limit, RULE_TYPE.ACM).then(res => {
|
||||||
this.loadingTable = false
|
this.loadingTable = false
|
||||||
if (page === 1) {
|
if (page === 1) {
|
||||||
this.changeCharts(res.data.data.results)
|
this.changeCharts(res.data.data.results.slice(0, 10))
|
||||||
}
|
}
|
||||||
this.total = res.data.data.total
|
this.total = res.data.data.total
|
||||||
this.dataRank = res.data.data.results
|
this.dataRank = res.data.data.results
|
||||||
|
@ -43,7 +43,6 @@
|
|||||||
{
|
{
|
||||||
title: 'user',
|
title: 'user',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 250,
|
|
||||||
render: (h, params) => {
|
render: (h, params) => {
|
||||||
return h('Button', {
|
return h('Button', {
|
||||||
props: {
|
props: {
|
||||||
@ -52,6 +51,9 @@
|
|||||||
'class': {
|
'class': {
|
||||||
'link-button': true
|
'link-button': true
|
||||||
},
|
},
|
||||||
|
style: {
|
||||||
|
'max-width': '200px'
|
||||||
|
},
|
||||||
on: {
|
on: {
|
||||||
click: () => {
|
click: () => {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
@ -86,6 +88,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Rating',
|
title: 'Rating',
|
||||||
|
align: 'center',
|
||||||
render: (h, params) => {
|
render: (h, params) => {
|
||||||
return h('span', utils.getACRate(params.row.accepted_number, params.row.submission_number))
|
return h('span', utils.getACRate(params.row.accepted_number, params.row.submission_number))
|
||||||
}
|
}
|
||||||
@ -123,7 +126,7 @@
|
|||||||
showMaxLabel: true,
|
showMaxLabel: true,
|
||||||
align: 'center',
|
align: 'center',
|
||||||
formatter: (value, index) => {
|
formatter: (value, index) => {
|
||||||
return value.replace(/(.{8})/g, '$1\n')
|
return utils.breakLongWords(value, 14)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
axisTick: {
|
axisTick: {
|
||||||
@ -162,7 +165,7 @@
|
|||||||
bar.showLoading({maskColor: 'rgba(250, 250, 250, 0.8)'})
|
bar.showLoading({maskColor: 'rgba(250, 250, 250, 0.8)'})
|
||||||
api.getUserRank(offset, this.limit, RULE_TYPE.OI).then(res => {
|
api.getUserRank(offset, this.limit, RULE_TYPE.OI).then(res => {
|
||||||
if (page === 1) {
|
if (page === 1) {
|
||||||
this.changeCharts(res.data.data.results)
|
this.changeCharts(res.data.data.results.slice(0, 10))
|
||||||
}
|
}
|
||||||
this.total = res.data.data.total
|
this.total = res.data.data.total
|
||||||
this.dataRank = res.data.data.results
|
this.dataRank = res.data.data.results
|
||||||
|
@ -147,7 +147,6 @@
|
|||||||
{
|
{
|
||||||
title: 'Author',
|
title: 'Author',
|
||||||
align: 'center',
|
align: 'center',
|
||||||
width: 250,
|
|
||||||
render: (h, params) => {
|
render: (h, params) => {
|
||||||
return h('Button', {
|
return h('Button', {
|
||||||
props: {
|
props: {
|
||||||
@ -156,6 +155,9 @@
|
|||||||
'class': {
|
'class': {
|
||||||
'link-button': true
|
'link-button': true
|
||||||
},
|
},
|
||||||
|
style: {
|
||||||
|
'max-width': '200px'
|
||||||
|
},
|
||||||
on: {
|
on: {
|
||||||
click: () => {
|
click: () => {
|
||||||
this.$router.push(
|
this.$router.push(
|
||||||
|
@ -112,3 +112,10 @@ export const STORAGE_KEY = {
|
|||||||
PROBLEM_CODE: 'problem_code_',
|
PROBLEM_CODE: 'problem_code_',
|
||||||
languages: 'languages'
|
languages: 'languages'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildProblemCodeKey (problemID, contestID = null) {
|
||||||
|
if (contestID) {
|
||||||
|
return `${STORAGE_KEY.PROBLEM_CODE}_${contestID}_${problemID}`
|
||||||
|
}
|
||||||
|
return `${STORAGE_KEY.PROBLEM_CODE}_NaN_${problemID}`
|
||||||
|
}
|
||||||
|
@ -25,9 +25,24 @@ function filterEmptyValue (object) {
|
|||||||
})
|
})
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 按指定字符数截断添加换行,非英文字符按指定字符的半数添加
|
||||||
|
function breakLongWords (value, length = 16) {
|
||||||
|
let re
|
||||||
|
if (escape(value).indexOf('%u') === -1) {
|
||||||
|
// 没有中文
|
||||||
|
re = new RegExp('(.{' + length + '})', 'g')
|
||||||
|
} else {
|
||||||
|
// 中文字符
|
||||||
|
re = new RegExp('(.{' + (length / 2 + 1) + '})', 'g')
|
||||||
|
}
|
||||||
|
return value.replace(re, '$1\n')
|
||||||
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
submissionMemoryFormat: submissionMemoryFormat,
|
submissionMemoryFormat: submissionMemoryFormat,
|
||||||
submissionTimeFormat: submissionTimeFormat,
|
submissionTimeFormat: submissionTimeFormat,
|
||||||
getACRate: getACRate,
|
getACRate: getACRate,
|
||||||
filterEmptyValue: filterEmptyValue
|
filterEmptyValue: filterEmptyValue,
|
||||||
|
breakLongWords: breakLongWords
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user