管理登录,后台首页,退出

This commit is contained in:
chenqiang 2025-08-28 11:23:29 +08:00
parent 366e5596bb
commit 3a05219d2e
5 changed files with 564 additions and 1 deletions

View File

@ -0,0 +1,158 @@
<template>
<el-container class="admin-layout-container">
<!-- 侧边栏 -->
<AdminSider :active-menu="$route.path" @collapse-change="handleCollapseChange" />
<!-- 主内容区 -->
<el-container class="main-container">
<!-- 顶部导航栏 -->
<el-header class="header-container">
<div class="header-left">
<button
class="btn btn-link text-white"
@click="toggleSider"
style="border: none; padding: 0; margin-right: 15px;"
>
<i class="fa fa-bars"></i>
</button>
<h2 class="title-text">系统管理</h2>
</div>
<div class="header-right">
<el-dropdown>
<span class="el-dropdown-link">
<i class="fa fa-user-circle-o mr-2"></i>
<span>管理员</span>
<i class="el-icon-arrow-down el-icon--right"></i>
</span>
<el-dropdown-menu slot="dropdown">
<el-dropdown-item>个人中心</el-dropdown-item>
<el-dropdown-item>修改密码</el-dropdown-item>
<el-dropdown-item divided @click.native="handleLogout">退出登录</el-dropdown-item>
</el-dropdown-menu>
</el-dropdown>
</div>
</el-header>
<!-- 内容区域 -->
<el-main class="content-container">
<router-view />
</el-main>
</el-container>
</el-container>
</template>
<script>
export default {
name: 'AdminLayout',
components: {
AdminSider: require('./Sider.vue').default,
ElContainer: require('element-ui').Container,
ElHeader: require('element-ui').Header,
ElMain: require('element-ui').Main,
ElDropdown: require('element-ui').Dropdown,
ElDropdownMenu: require('element-ui').DropdownMenu,
ElDropdownItem: require('element-ui').DropdownItem
},
data() {
return {
isCollapse: false
}
},
methods: {
handleCollapseChange(isCollapse) {
this.isCollapse = isCollapse
},
toggleSider() {
this.isCollapse = !this.isCollapse
//
this.$children.forEach(child => {
if (child.$options.name === 'AdminSider' && child.toggleCollapse) {
child.toggleCollapse()
}
})
},
handleLogout() {
// 退
this.$confirm('确定要退出登录吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
// token
console.log('用户确认退出登录')
this.$router.push('/')
}).catch(() => {
this.$message.info('已取消退出')
})
}
}
}
</script>
<style scoped>
.admin-layout-container {
height: 100vh;
}
.main-container {
width: 100%;
overflow: hidden;
}
.header-container {
height: 60px;
background-color: #409EFF;
color: white;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 20px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.header-left {
display: flex;
align-items: center;
}
.title-text {
margin: 0;
font-size: 18px;
font-weight: 600;
}
.header-right {
display: flex;
align-items: center;
}
.el-dropdown-link {
color: white;
cursor: pointer;
}
.el-dropdown-link:hover {
color: #fff;
}
.content-container {
background-color: #f5f7fa;
padding: 20px;
overflow-y: auto;
}
/* 适配移动设备 */
@media (max-width: 768px) {
.header-container {
padding: 0 10px;
}
.title-text {
font-size: 16px;
}
.content-container {
padding: 10px;
}
}
</style>

View File

@ -0,0 +1,175 @@
<template>
<el-aside :width="isCollapse ? '64px' : '200px'" class="sider-container">
<div class="logo-container">
<img v-if="!isCollapse" src="@/assets/logo.png" alt="Logo" class="logo mr-3">
<i v-else class="el-icon-menu text-white" style="font-size: 24px;"></i>
<span style="color:#DEDEDE;font-weight:bold;font-size:1.5rem!important">考试系统</span>
</div>
<el-menu
:default-active="activeMenu"
class="el-menu-vertical-demo"
@open="handleOpen"
@close="handleClose"
background-color="#304156"
text-color="#bfcbd9"
active-text-color="#409EFF"
:collapse="isCollapse"
@select="handleMenuSelect"
>
<el-menu-item index="/admin/home">
<i class="el-icon-menu"></i>
<span slot="title">后台首页</span>
</el-menu-item>
<el-menu-item index="/admin/examinee">
<i class="el-icon-user-solid"></i>
<span slot="title">考生管理</span>
</el-menu-item>
<el-menu-item index="/admin/question">
<i class="el-icon-document-checked"></i>
<span slot="title">试题管理</span>
</el-menu-item>
<el-menu-item index="/admin/exam">
<i class="el-icon-date"></i>
<span slot="title">考试管理</span>
</el-menu-item>
<el-menu-item index="/admin/statistics">
<i class="el-icon-data-analysis"></i>
<span slot="title">数据统计</span>
</el-menu-item>
<el-menu-item index="/admin/settings">
<i class="el-icon-setting"></i>
<span slot="title">系统设置</span>
</el-menu-item>
<el-menu-item index="logout">
<i class="el-icon-switch-button"></i>
<span slot="title">退出登录</span>
</el-menu-item>
</el-menu>
<!-- 删除折叠按钮 -->
</el-aside>
</template>
<script>
export default {
name: 'AdminSider',
components: {
ElAside: require('element-ui').Aside,
ElMenu: require('element-ui').Menu,
ElMenuItem: require('element-ui').MenuItem
},
data() {
return {
isCollapse: false,
activeMenu: '/admin/home'
}
},
mounted() {
//
this.$router.afterEach((to) => {
this.activeMenu = to.path
})
},
methods: {
handleOpen(key, keyPath) {
console.log(key, keyPath)
},
handleClose(key, keyPath) {
console.log(key, keyPath)
},
//
handleMenuSelect(index) {
if (index === 'logout') {
this.handleLogout()
} else {
// index
this.$router.push(index)
}
},
// 退
handleLogout() {
this.$confirm('确定要退出登录吗?', '确认退出', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
//
// localStorage.removeItem('token')
//
this.$router.push('/')
}).catch(() => {
// 退
this.$message({
type: 'info',
message: '已取消退出'
})
})
}
},
watch: {
'$route'(to) {
this.activeMenu = to.path
}
}
}
</script>
<style scoped>
.sider-container {
height: 100vh;
background-color: #304156;
overflow-y: auto;
position: relative;
transition: width 0.3s;
}
.logo-container {
height: 60px;
display: flex;
align-items: center;
justify-content: center;
background-color: #2d3a4b;
border-bottom: 1px solid #3d526f;
}
.logo {
width: 28px;
height: auto;
}
.el-menu-vertical-demo:not(.el-menu--collapse) {
width: 100%;
}
/* 设置el-menu-item的padding-left为0 */
.el-menu-item {
padding-left: 0 !important;
}
/* 对于折叠状态的菜单也应用相同的padding */
.el-menu--collapse .el-menu-item {
padding-left: 0 !important;
}
/* 确保菜单中的图标和文字正确显示 */
.el-menu-item i {
margin-right: 10px;
}
/* 滚动条样式 */
.sider-container::-webkit-scrollbar {
width: 6px;
}
.sider-container::-webkit-scrollbar-track {
background: #2d3a4b;
}
.sider-container::-webkit-scrollbar-thumb {
background: #4b6a97;
border-radius: 3px;
}
.sider-container::-webkit-scrollbar-thumb:hover {
background: #587ba0;
}
</style>

View File

@ -5,7 +5,7 @@
<div class="col-auto">
<h2 class="display-6 m-0 d-flex align-items-center">
<img src="../../assets/logo.png" alt="logo" style="width:50px;height:50px;margin-right:1rem;">
{{ thisYear }}<strong>年抚顺市统计行业职工技能大赛考试系统</strong>
<strong>{{ thisYear }}年抚顺市统计行业职工技能大赛考试系统</strong>
</h2>
</div>
</div>

View File

@ -1,6 +1,8 @@
import Vue from 'vue'
import VueRouter from 'vue-router'
import WelcomeView from '../views/WelcomeView.vue'
import AdminLayout from '../components/admin/AdminLayout.vue'
import AdminHomeView from '../views/admin/AdminHomeView.vue'
Vue.use(VueRouter)
@ -9,6 +11,22 @@ const routes = [
path: '/',
name: 'Welcome',
component: WelcomeView
},
{
path: '/admin',
name: 'AdminLayout',
component: AdminLayout,
meta: {
requiresAuth: true
},
children: [
{
path: 'home',
name: 'AdminHome',
component: AdminHomeView
}
// 可以在这里添加更多子路由
]
}
]
@ -18,4 +36,10 @@ const router = new VueRouter({
routes
})
// 添加路由守卫
router.beforeEach((to, from, next) => {
// 这里可以添加实际的认证逻辑
next()
})
export default router

View File

@ -0,0 +1,206 @@
<template>
<div class="dashboard-container">
<!-- 页面标题 -->
<div class="mb-4">
<h1 class="text-primary">系统管理首页</h1>
<p class="text-muted">欢迎管理员登录系统后台管理界面</p>
</div>
<!-- 数据概览卡片 -->
<div class="row mb-4">
<div class="col-md-3">
<div class="card bg-primary text-white">
<div class="card-body">
<h5 class="card-title">总考生数</h5>
<p class="card-text text-4xl">{{ examineeCount }}</p>
<a href="#" class="text-white">查看详情</a>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-success text-white">
<div class="card-body">
<h5 class="card-title">总题目数</h5>
<p class="card-text text-4xl">{{ questionCount }}</p>
<a href="#" class="text-white">查看详情</a>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-warning text-white">
<div class="card-body">
<h5 class="card-title">总考试数</h5>
<p class="card-text text-4xl">{{ examCount }}</p>
<a href="#" class="text-white">查看详情</a>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card bg-info text-white">
<div class="card-body">
<h5 class="card-title">已完成考试</h5>
<p class="card-text text-4xl">{{ completedExamCount }}</p>
<a href="#" class="text-white">查看详情</a>
</div>
</div>
</div>
</div>
<!-- 快速操作区域 -->
<div class="card mb-4">
<div class="card-header">
<h5 class="card-title">快速操作</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-2 mb-2">
<el-button type="primary" icon="el-icon-user" size="medium" class="w-100">
考生管理
</el-button>
</div>
<div class="col-md-2 mb-2">
<el-button type="primary" icon="el-icon-document" size="medium" class="w-100">
试题管理
</el-button>
</div>
<div class="col-md-2 mb-2">
<el-button type="primary" icon="el-icon-date" size="medium" class="w-100">
考试管理
</el-button>
</div>
<div class="col-md-2 mb-2">
<el-button type="primary" icon="el-icon-setting" size="medium" class="w-100">
系统设置
</el-button>
</div>
<div class="col-md-2 mb-2">
<el-button type="primary" icon="el-icon-s-data" size="medium" class="w-100">
数据统计
</el-button>
</div>
<div class="col-md-2 mb-2">
<el-button type="danger" icon="el-icon-switch-button" size="medium" class="w-100">
退出登录
</el-button>
</div>
</div>
</div>
</div>
<!-- 最近活动区域 -->
<div class="card">
<div class="card-header">
<h5 class="card-title">最近活动</h5>
</div>
<div class="card-body">
<el-table :data="recentActivities" style="width: 100%">
<el-table-column prop="time" label="时间" width="180"></el-table-column>
<el-table-column prop="user" label="用户" width="120"></el-table-column>
<el-table-column prop="action" label="操作" width="150"></el-table-column>
<el-table-column prop="details" label="详情"></el-table-column>
</el-table>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'AdminHomeView',
components: {
ElButton: require('element-ui').Button,
ElTable: require('element-ui').Table,
ElTableColumn: require('element-ui').TableColumn
},
data() {
return {
examineeCount: 0,
questionCount: 0,
examCount: 0,
completedExamCount: 0,
recentActivities: [
//
{
time: '2025-08-28 09:30',
user: 'admin',
action: '登录',
details: '管理员成功登录系统'
},
{
time: '2025-08-27 16:45',
user: 'system',
action: '更新',
details: '系统题库已更新至最新版本'
},
{
time: '2025-08-27 14:20',
user: 'admin',
action: '添加',
details: '添加了10名新考生'
}
]
}
},
mounted() {
this.fetchDashboardData()
},
methods: {
async fetchDashboardData() {
try {
//
// 使
console.log('获取仪表盘数据...')
// API
await new Promise(resolve => setTimeout(resolve, 500))
//
this.examineeCount = 120
this.questionCount = 500
this.examCount = 5
this.completedExamCount = 3
} catch (error) {
console.error('获取仪表盘数据失败:', error)
this.$message.error('获取数据失败,请稍后重试')
}
}
}
}
</script>
<style scoped>
.dashboard-container {
height: 100%;
}
.card {
border-radius: 8px;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
margin-bottom: 20px;
}
.card-body {
padding: 15px;
}
.card-title {
margin-bottom: 10px;
font-weight: 600;
}
.text-4xl {
font-size: 2.5rem;
font-weight: 700;
}
/* 适配移动设备 */
@media (max-width: 768px) {
.row > div {
margin-bottom: 15px;
}
.text-4xl {
font-size: 2rem;
}
}
</style>