<template>
|
<el-container class="admin-layout">
|
<el-aside class="admin-aside" width="220px">
|
<div class="brand-area">
|
<el-icon :size="24" class="brand-icon"><Cpu /></el-icon>
|
<div class="brand-text">
|
<div class="brand-title">WCS 模拟平台</div>
|
<div class="brand-subtitle">S7 Simulator</div>
|
</div>
|
</div>
|
|
<el-menu
|
class="aside-menu"
|
:default-active="activeMenu"
|
background-color="#1f2a37"
|
text-color="#c7d2fe"
|
active-text-color="#ffffff"
|
router
|
>
|
<el-menu-item index="/">
|
<el-icon><House /></el-icon>
|
<span>实例管理</span>
|
</el-menu-item>
|
<el-menu-item index="/protocol-templates">
|
<el-icon><Files /></el-icon>
|
<span>协议模板</span>
|
</el-menu-item>
|
<el-menu-item index="/robot-clients">
|
<el-icon><Connection /></el-icon>
|
<span>机械手客户端</span>
|
</el-menu-item>
|
</el-menu>
|
</el-aside>
|
|
<el-container>
|
<el-header class="admin-header">
|
<div class="header-left">
|
<div class="page-title">{{ pageTitle }}</div>
|
<div class="page-path">{{ route.path }}</div>
|
</div>
|
</el-header>
|
|
<el-main class="admin-main">
|
<div class="content-shell">
|
<router-view />
|
</div>
|
</el-main>
|
</el-container>
|
</el-container>
|
</template>
|
|
<script setup lang="ts">
|
import { computed } from 'vue'
|
import { useRoute } from 'vue-router'
|
import { Connection, Cpu, Files, House } from '@element-plus/icons-vue'
|
|
const route = useRoute()
|
|
const activeMenu = computed(() => {
|
if (route.path.startsWith('/protocol-templates')) return '/protocol-templates'
|
if (route.path.startsWith('/robot-clients')) return '/robot-clients'
|
return '/'
|
})
|
|
const pageTitle = computed(() => {
|
if (route.path.startsWith('/create')) return '创建实例'
|
if (route.path.startsWith('/edit')) return '编辑实例'
|
if (route.path.startsWith('/details')) return '实例详情'
|
if (route.path.startsWith('/protocol-templates')) return '协议模板'
|
if (route.path.startsWith('/robot-clients')) return '机械手客户端'
|
return '实例管理'
|
})
|
</script>
|
|
<style scoped>
|
.admin-layout {
|
height: 100vh;
|
}
|
|
.admin-aside {
|
background: linear-gradient(180deg, #1f2a37 0%, #111827 100%);
|
border-right: 1px solid #263445;
|
display: flex;
|
flex-direction: column;
|
}
|
|
.brand-area {
|
height: 64px;
|
padding: 0 14px;
|
display: flex;
|
align-items: center;
|
border-bottom: 1px solid #2b3a4f;
|
color: #e5e7eb;
|
}
|
|
.brand-icon {
|
margin-right: 10px;
|
}
|
|
.brand-title {
|
font-size: 15px;
|
font-weight: 700;
|
line-height: 1.2;
|
}
|
|
.brand-subtitle {
|
font-size: 12px;
|
color: #94a3b8;
|
line-height: 1.2;
|
}
|
|
.aside-menu {
|
border-right: none;
|
flex: 1;
|
}
|
|
.admin-header {
|
height: 64px;
|
background: #ffffff;
|
border-bottom: 1px solid #e5e7eb;
|
display: flex;
|
align-items: center;
|
padding: 0 20px;
|
}
|
|
.header-left {
|
display: flex;
|
flex-direction: column;
|
gap: 2px;
|
}
|
|
.page-title {
|
font-size: 18px;
|
font-weight: 600;
|
color: #0f172a;
|
}
|
|
.page-path {
|
font-size: 12px;
|
color: #64748b;
|
}
|
|
.admin-main {
|
background: #f1f5f9;
|
padding: 14px;
|
}
|
|
.content-shell {
|
min-height: calc(100vh - 64px - 28px);
|
width: 100%;
|
max-width: 1680px;
|
margin: 0 auto;
|
padding: 2px;
|
}
|
|
@media (max-width: 960px) {
|
.admin-aside {
|
width: 64px !important;
|
}
|
|
.brand-text {
|
display: none;
|
}
|
|
.admin-header {
|
padding: 0 12px;
|
}
|
}
|
</style>
|