This commit is contained in:
Chiaki 2017-04-26 13:59:14 +08:00
parent f061a648bf
commit f25f5e94f7
7 changed files with 227 additions and 90 deletions

View File

@ -17,6 +17,15 @@ module.exports = {
// allow async-await // allow async-await
'generator-star-spacing': 0, 'generator-star-spacing': 0,
// allow debugger during development // allow debugger during development
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
"space-before-function-paren": ["error", {
"anonymous": "always",
"named": "never",
"asyncArrow": "always"
}],
"no-irregular-whitespace": ["error", {
"skipComments": true,
"skipTemplates": true
}]
} }
} }

View File

@ -1,80 +1,81 @@
<template> <template>
<div>
<div> <div>
<div> <Navbar></Navbar>
<SideMenu></SideMenu> </div>
</div> <div class="content-app">
<div class="content-app"> <router-view></router-view>
<router-view></router-view> <div class="footer">
<div class="footer"> Build Version: {{ version }}
Build Version: {{ version }}
</div>
</div> </div>
</div> </div>
</div>
</template> </template>
<script> <script>
import 'font-awesome/css/font-awesome.min.css' import 'font-awesome/css/font-awesome.min.css'
import SideMenu from './components/SideMenu.vue' // import SideMenu from './components/SideMenu.vue'
import api from './api.js' import Navbar from './components/Navbar.vue'
// import api from './api.js'
export default { export default {
name: 'app', name: 'app',
data () { data() {
return { return {
version: process.env.VERSION version: process.env.VERSION
}
},
components: {
SideMenu
},
methods: {},
mounted () {
api.login('root', 'rootroot').then(res => {})
} }
} },
components: {
Navbar
},
methods: {}
// mounted () {
// api.login('root', 'rootroot').then(res => {})
// }
}
</script> </script>
<style lang="less"> <style lang="less">
body { body {
margin: 0; margin: 0;
background-color: rgb(236, 242, 247)!important; background-color: rgb(236, 242, 247)!important;
} }
a { a {
background-color: transparent; background-color: transparent;
-webkit-text-decoration-skip: objects -webkit-text-decoration-skip: objects;
} }
a:active,
a:hover {
outline-width: 0;
}
a:active, a:hover { img {
outline-width: 0 border-style: none;
} }
img { body {
border-style: none
}
body {
font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif; font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, SimSun, sans-serif;
overflow: auto; overflow: auto;
font-weight: 400; font-weight: 400;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
background-color: #EDECEC; background-color: #EDECEC;
overflow-y: scroll; overflow-y: scroll;
} }
* { * {
box-sizing: border-box; box-sizing: border-box;
} }
.content-app { .content-app {
padding-top: 20px; padding-top: 20px;
padding-right:10px; padding-right: 10px;
padding-left: 210px; padding-left: 10px;
} }
.footer { .footer {
margin: 15px; margin: 15px;
text-align: center; text-align: center;
font-size: small; font-size: small;
} }
</style> </style>

View File

@ -5,7 +5,7 @@ Vue.use(VueResource)
Vue.http.options.root = '/api' Vue.http.options.root = '/api'
Vue.http.options.emulateJSON = false Vue.http.options.emulateJSON = false
function getCookie (name) { function getCookie(name) {
let allCookies = document.cookie.split('; ') let allCookies = document.cookie.split('; ')
for (let i = 0; i < allCookies.length; i++) { for (let i = 0; i < allCookies.length; i++) {
let cookie = allCookies[i].split('=') let cookie = allCookies[i].split('=')
@ -24,8 +24,8 @@ Vue.http.interceptors.push((request, next) => {
export default { export default {
// 登录 // 登录
login (username, password) { login(username, password) {
return ajax('login', 'get', { return ajax('/api/login', 'post', {
options: { options: {
params: { params: {
username, username,
@ -35,7 +35,7 @@ export default {
}) })
}, },
// 获取公告列表 // 获取公告列表
getAnnouncementList (offset, limit) { getAnnouncementList(offset, limit) {
return ajax('admin/announcement', 'get', { return ajax('admin/announcement', 'get', {
options: { options: {
params: { params: {
@ -47,7 +47,7 @@ export default {
}) })
}, },
// 删除公告 // 删除公告
deleteAnnouncement (id) { deleteAnnouncement(id) {
return ajax('admin/announcement', 'delete', { return ajax('admin/announcement', 'delete', {
options: { options: {
params: { params: {
@ -57,7 +57,7 @@ export default {
}) })
}, },
// 修改公告 // 修改公告
modifyAnnouncement (id, title, content, visible) { modifyAnnouncement(id, title, content, visible) {
return ajax('admin/announcement', 'put', { return ajax('admin/announcement', 'put', {
body: { body: {
id, id,
@ -68,7 +68,7 @@ export default {
}) })
}, },
// 添加公告 // 添加公告
createAnnouncement (title, content, visible) { createAnnouncement(title, content, visible) {
return ajax('admin/announcement', 'post', { return ajax('admin/announcement', 'post', {
body: { body: {
title, title,
@ -78,8 +78,12 @@ export default {
}) })
}, },
// 获取用户列表 // 获取用户列表
getUserList (offset, limit, keyword) { getUserList(offset, limit, keyword) {
let params = {paging: true, offset, limit} let params = {
paging: true,
offset,
limit
}
if (keyword) { if (keyword) {
params.keyword = keyword params.keyword = keyword
} }
@ -90,7 +94,7 @@ export default {
}) })
}, },
// 获取单个用户信息 // 获取单个用户信息
getUser (id) { getUser(id) {
return ajax('admin/user', 'get', { return ajax('admin/user', 'get', {
options: { options: {
params: { params: {
@ -100,39 +104,39 @@ export default {
}) })
}, },
// 编辑用户 // 编辑用户
editUser (body) { editUser(body) {
return ajax('admin/user', 'put', { return ajax('admin/user', 'put', {
body body
}) })
}, },
getLanguages () { getLanguages() {
return ajax('languages', 'get') return ajax('languages', 'get')
}, },
getSMTPConfig () { getSMTPConfig() {
return ajax('admin/smtp', 'get') return ajax('admin/smtp', 'get')
}, },
createSMTPConfig (body) { createSMTPConfig(body) {
return ajax('admin/smtp', 'post', { return ajax('admin/smtp', 'post', {
body body
}) })
}, },
editSMTPConfig (body) { editSMTPConfig(body) {
return ajax('admin/smtp', 'put', { return ajax('admin/smtp', 'put', {
body body
}) })
}, },
getWebsiteConfig () { getWebsiteConfig() {
return ajax('admin/website', 'get') return ajax('admin/website', 'get')
}, },
editWebsiteConfig (config) { editWebsiteConfig(config) {
return ajax('admin/website', 'post', { return ajax('admin/website', 'post', {
body: config body: config
}) })
}, },
getJudgeServer () { getJudgeServer() {
return ajax('admin/judge_server', 'get') return ajax('admin/judge_server', 'get')
}, },
deleteJudgeServer (hostname) { deleteJudgeServer(hostname) {
return ajax('admin/judge_server', 'delete', { return ajax('admin/judge_server', 'delete', {
options: { options: {
params: { params: {
@ -141,12 +145,12 @@ export default {
} }
}) })
}, },
createContest (body) { createContest(body) {
return ajax('admin/contest', 'post', { return ajax('admin/contest', 'post', {
body: body body: body
}) })
}, },
getContest (id) { getContest(id) {
return ajax('admin/contest', 'get', { return ajax('admin/contest', 'get', {
options: { options: {
params: { params: {
@ -155,13 +159,17 @@ export default {
} }
}) })
}, },
editContest (body) { editContest(body) {
return ajax('admin/contest', 'put', { return ajax('admin/contest', 'put', {
body body
}) })
}, },
getContestList (offset, limit, keyword) { getContestList(offset, limit, keyword) {
let params = {paging: true, offset, limit} let params = {
paging: true,
offset,
limit
}
if (keyword) { if (keyword) {
params.keyword = keyword params.keyword = keyword
} }
@ -171,7 +179,7 @@ export default {
} }
}) })
}, },
getContestAnnouncementList (contestId) { getContestAnnouncementList(contestId) {
return ajax('admin/contest/announcement', 'get', { return ajax('admin/contest/announcement', 'get', {
options: { options: {
params: { params: {
@ -180,12 +188,12 @@ export default {
} }
}) })
}, },
createContestAnnouncement (body) { createContestAnnouncement(body) {
return ajax('admin/contest/announcement', 'post', { return ajax('admin/contest/announcement', 'post', {
body body
}) })
}, },
deleteContestAnnouncement (id) { deleteContestAnnouncement(id) {
return ajax('admin/contest/announcement', 'delete', { return ajax('admin/contest/announcement', 'delete', {
options: { options: {
params: { params: {
@ -194,20 +202,20 @@ export default {
} }
}) })
}, },
getProblemTagList () { getProblemTagList() {
return ajax('problem/tags', 'get') return ajax('problem/tags', 'get')
}, },
createProblem (body) { createProblem(body) {
return ajax('admin/problem', 'post', { return ajax('admin/problem', 'post', {
body body
}) })
}, },
editProblem (body) { editProblem(body) {
return ajax('admin/problem', 'put', { return ajax('admin/problem', 'put', {
body body
}) })
}, },
getProblem (id) { getProblem(id) {
return ajax('admin/problem', 'get', { return ajax('admin/problem', 'get', {
options: { options: {
params: { params: {
@ -216,8 +224,12 @@ export default {
} }
}) })
}, },
getProblemList (offset, limit, keyword) { getProblemList(offset, limit, keyword) {
let params = {paging: true, offset, limit} let params = {
paging: true,
offset,
limit
}
if (keyword) { if (keyword) {
params.keyword = keyword params.keyword = keyword
} }
@ -227,8 +239,13 @@ export default {
} }
}) })
}, },
getContestProblemList (offset, limit, keyword, contestId) { getContestProblemList(offset, limit, keyword, contestId) {
let params = {paging: true, offset, limit, contest_id: contestId} let params = {
paging: true,
offset,
limit,
contest_id: contestId
}
if (keyword) { if (keyword) {
params.keyword = keyword params.keyword = keyword
} }
@ -238,7 +255,7 @@ export default {
} }
}) })
}, },
getContestProblem (id) { getContestProblem(id) {
return ajax('admin/contest/problem', 'get', { return ajax('admin/contest/problem', 'get', {
options: { options: {
params: { params: {
@ -247,12 +264,12 @@ export default {
} }
}) })
}, },
createContestProblem (body) { createContestProblem(body) {
return ajax('admin/contest/problem', 'post', { return ajax('admin/contest/problem', 'post', {
body body
}) })
}, },
editContestProblem (body) { editContestProblem(body) {
return ajax('admin/contest/problem', 'put', { return ajax('admin/contest/problem', 'put', {
body body
}) })
@ -271,8 +288,8 @@ export default {
@return Promise @return Promise
*/ */
function ajax (url, type, options) { function ajax(url, type, options) {
return new Promise(function (resolve, reject) { return new Promise(function(resolve, reject) {
options = options || {} options = options || {}
if (options.body === undefined) { if (options.body === undefined) {
options.body = options.options options.body = options.options

View File

@ -0,0 +1,38 @@
<template>
<el-menu theme="dark" :default-active="activeIndex" class="el-menu-demo" mode="horizontal">
<el-row :gutter="10">
<el-col :xs="3" :sm="3" :lg="3">&nbsp;</el-col>
<el-col :xs="2" :sm="2" :lg="2">
<div style="color:#bfcbd9;margin-top:16px;font-size:20px;">QDUOJ</div>
</el-col>
<el-col :xs="16" :sm="16" :lg="16">
<el-menu-item index="1">题目</el-menu-item>
<el-menu-item index="2">提交</el-menu-item>
<el-menu-item index="3">比赛</el-menu-item>
<el-menu-item index="4">排名</el-menu-item>
<el-menu-item index="5">帮助</el-menu-item>
</el-col>
<el-col :xs="3" :sm="3" :lg="3">
<el-submenu index="2">
<template slot="title">Hieda no Chiaki
</template>
<el-menu-item index="2-1">我的主页</el-menu-item>
<el-menu-item index="2-2">我的提交</el-menu-item>
<el-menu-item index="2-3">设置</el-menu-item>
<el-menu-item index="2-4">退出</el-menu-item>
</el-submenu>
</el-col>
</el-row>
</el-menu>
</template>
<script>
export default {
data () {
return {
activeIndex: '1'
}
}
}
</script>

View File

@ -27,12 +27,17 @@ Vue.component(Cancel.name, Cancel)
// 引入 view 组件 // 引入 view 组件
import { Announcement, User, Conf, JudgeServer, Problem, Contest, ContestList, import { Announcement, User, Conf, JudgeServer, Problem, Contest, ContestList,
ContestAnnouncement, ProblemList } from './views' ContestAnnouncement, ProblemList, Login } from './views'
const router = new VueRouter({ const router = new VueRouter({
mode: 'history', mode: 'history',
scrollBehavior: () => ({ y: 0 }), scrollBehavior: () => ({ y: 0 }),
routes: [ routes: [
{
path: '/login',
name: 'login',
component: Login
},
{ {
path: '/announcement', path: '/announcement',
name: 'announcement', name: 'announcement',

View File

@ -7,8 +7,9 @@ import ProblemList from './problem/ProblemList.vue'
import ContestList from './contest/ContestList.vue' import ContestList from './contest/ContestList.vue'
import Contest from './contest/Contest.vue' import Contest from './contest/Contest.vue'
import ContestAnnouncement from './contest/Announcement.vue' import ContestAnnouncement from './contest/Announcement.vue'
import Login from './user/Login.vue'
export { export {
Announcement, User, Conf, JudgeServer, Problem, ProblemList, Contest, Announcement, User, Conf, JudgeServer, Problem, ProblemList, Contest,
ContestList, ContestAnnouncement ContestList, ContestAnnouncement, Login
} }

View File

@ -0,0 +1,66 @@
<template>
<div class="center">
<el-card class="box-card" id="login-card">
<div slot="header" class="clearfix" id="login-title">
<span style="line-height: 36px;">用户登录</span>
</div>
<el-form :label-position="labelPosition" label-width="80px" :model="formLabelAlign">
<el-form-item label="账号">
<el-input v-model="formLabelAlign.name"></el-input>
</el-form-item>
<el-form-item label="密码">
<el-input v-model="formLabelAlign.password" type="password"></el-input>
</el-form-item>
<el-form-item label="二次验证">
<el-input v-model="formLabelAlign.totp"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">立即登录</el-button>
<el-button>用户注册</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</template>
<script>
import api from '../../api.js'
export default {
data() {
return {
labelPosition: 'top',
formLabelAlign: {
name: '',
region: '',
type: ''
}
}
},
methods: {
onSubmit() {
console.log('submit!')
api.login(this.formLabelAlign.name, this.formLabelAlign.password).then(function (res) {
console.log(res)
})
}
}
}
</script>
<style lang="css">
.center{
margin-top: 50px;
}
#login-card{
max-width: 400px;
margin: auto;
}
#login-title{
text-align: center;
font-size: 20px;
}
</style>