270 lines
5.8 KiB
Vue
270 lines
5.8 KiB
Vue
<template>
|
|
<pro-layout
|
|
:menus="menus"
|
|
:collapsed="collapsed"
|
|
:mediaQuery="query"
|
|
:isMobile="isMobile"
|
|
:handleMediaQuery="handleMediaQuery"
|
|
:handleCollapse="handleCollapse"
|
|
:logo="'/logo.png'"
|
|
title="竞赛管理系统"
|
|
fixedHeader
|
|
fixSiderbar
|
|
:headerHeight="64"
|
|
:siderWidth="256"
|
|
primaryColor="#1890ff"
|
|
>
|
|
<template #menuHeaderRender>
|
|
<a-avatar src="/logo.png" :size="40" />
|
|
<h1>竞赛管理系统</h1>
|
|
</template>
|
|
<template #rightContentRender>
|
|
<div :class="rightContentClass">
|
|
<LoginState />
|
|
</div>
|
|
</template>
|
|
<template #footerRender>
|
|
<div class="footer-container">
|
|
校园信息化-竞赛管理系统 ©2024 Created by 陕西科技大学镐京学院
|
|
</div>
|
|
</template>
|
|
<template #headerContentRender>
|
|
<a-breadcrumb
|
|
style="height: 64px; line-height: 64px"
|
|
class="breadcrumb"
|
|
:routes="$route.matched"
|
|
>
|
|
<template #itemRender="{ route }">
|
|
{{ route.meta.title }}
|
|
</template>
|
|
</a-breadcrumb>
|
|
</template>
|
|
<TabLayout />
|
|
</pro-layout>
|
|
</template>
|
|
|
|
<script>
|
|
import { mapGetters } from "vuex";
|
|
import { filterRoutes } from "@/router";
|
|
import { routes } from "@/router";
|
|
import ProLayout from "@ant-design-vue/pro-layout";
|
|
import TabLayout from "@/layouts/TabLayout";
|
|
import LoginState from "@/components/common/LoginState.vue";
|
|
|
|
export default {
|
|
name: "GlobalLayout",
|
|
components: {
|
|
ProLayout,
|
|
LoginState,
|
|
TabLayout,
|
|
},
|
|
data() {
|
|
return {
|
|
collapsed: false,
|
|
autoHideHeader: false,
|
|
query: {},
|
|
layout: "sidemenu",
|
|
contentWidth: "Fluid",
|
|
theme: "dark",
|
|
isMobile: false,
|
|
};
|
|
},
|
|
computed: {
|
|
...mapGetters(["permissions"]),
|
|
menus() {
|
|
const root = routes.find((v) => v.path === "/");
|
|
return filterRoutes(root?.children || [], this.permissions);
|
|
},
|
|
rightContentClass() {
|
|
return [
|
|
"ant-pro-global-header-index-right",
|
|
this.layout === "topmenu" &&
|
|
`ant-pro-global-header-index-${this.theme}`,
|
|
];
|
|
},
|
|
},
|
|
methods: {
|
|
handleCollapse(collapsed) {
|
|
this.collapsed = collapsed;
|
|
},
|
|
handleMediaQuery(query) {
|
|
this.query = query;
|
|
if (this.isMobile && !query["screen-xs"]) {
|
|
this.isMobile = false;
|
|
return;
|
|
}
|
|
if (!this.isMobile && query["screen-xs"]) {
|
|
this.isMobile = true;
|
|
this.collapsed = false;
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="less">
|
|
@import "~ant-design-vue/es/style/themes/default.less";
|
|
|
|
// 定义主题色变量
|
|
@primary-color: #1890ff;
|
|
@primary-hover: #40a9ff;
|
|
@layout-header-background: linear-gradient(90deg, #1890ff, #36cfc9);
|
|
@menu-dark-bg: #001529;
|
|
@menu-dark-submenu-bg: #000c17;
|
|
|
|
.ant-pro-global-header {
|
|
background: @layout-header-background;
|
|
box-shadow: 0 2px 8px rgba(24, 144, 255, 0.15);
|
|
backdrop-filter: blur(8px);
|
|
|
|
.ant-breadcrumb {
|
|
margin-left: 16px;
|
|
|
|
a,
|
|
span {
|
|
color: rgba(255, 255, 255, 0.85);
|
|
transition: color 0.3s;
|
|
|
|
&:hover {
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.ant-pro-sider-menu-logo {
|
|
position: relative;
|
|
height: 64px;
|
|
padding: 0 24px;
|
|
overflow: hidden;
|
|
background: linear-gradient(180deg, #1890ff, #096dd9);
|
|
cursor: pointer;
|
|
transition: all 0.3s;
|
|
|
|
h1 {
|
|
color: white;
|
|
font-size: 20px;
|
|
margin: 0 0 0 12px;
|
|
font-weight: 600;
|
|
opacity: 1;
|
|
transition: all 0.3s;
|
|
background: linear-gradient(90deg, #fff, #e6f7ff);
|
|
-webkit-background-clip: text;
|
|
-webkit-text-fill-color: transparent;
|
|
}
|
|
|
|
&:hover {
|
|
background: linear-gradient(180deg, #096dd9, #1890ff);
|
|
}
|
|
}
|
|
|
|
.ant-menu-dark {
|
|
background: linear-gradient(180deg, #001529, #002140);
|
|
|
|
.ant-menu-item {
|
|
margin: 4px 8px;
|
|
padding: 0 16px;
|
|
border-radius: 4px;
|
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
|
|
&:hover {
|
|
background: linear-gradient(90deg, #1890ff, #40a9ff) !important;
|
|
transform: translateX(4px);
|
|
}
|
|
|
|
&.ant-menu-item-selected {
|
|
background: linear-gradient(90deg, #1890ff, #40a9ff) !important;
|
|
box-shadow: 0 2px 8px rgba(24, 144, 255, 0.2);
|
|
&::after {
|
|
display: none;
|
|
}
|
|
}
|
|
}
|
|
|
|
.ant-menu-submenu {
|
|
&-title {
|
|
margin: 4px 8px;
|
|
padding: 0 16px;
|
|
border-radius: 4px;
|
|
transition: all 0.3s;
|
|
|
|
&:hover {
|
|
background: rgba(24, 144, 255, 0.1) !important;
|
|
}
|
|
}
|
|
|
|
&-open {
|
|
background: rgba(0, 0, 0, 0.2);
|
|
border-radius: 4px;
|
|
}
|
|
}
|
|
}
|
|
|
|
.ant-pro-basicLayout-content {
|
|
margin: 24px;
|
|
padding: 24px;
|
|
background: #fff;
|
|
min-height: calc(100vh - 128px); // 移除固定height
|
|
border-radius: 8px;
|
|
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.05);
|
|
display: flex; // 添加flex布局
|
|
flex-direction: column; // 垂直方向排列
|
|
flex: 1; // 占用剩余空间
|
|
overflow: auto; // 内容过多时显示滚动条
|
|
}
|
|
|
|
// 添加布局容器样式
|
|
.ant-pro-basicLayout {
|
|
min-height: 100vh;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.ant-pro-basicLayout-content-wrapper {
|
|
flex: 1;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.footer-container {
|
|
text-align: center;
|
|
color: rgba(0, 0, 0, 0.45);
|
|
padding: 16px;
|
|
background: white;
|
|
border-radius: 4px;
|
|
margin: 0 24px;
|
|
box-shadow: 0 1px 4px rgba(0, 0, 0, 0.05);
|
|
|
|
&:hover {
|
|
color: rgba(0, 0, 0, 0.65);
|
|
}
|
|
}
|
|
|
|
.ant-pro-global-header-index-right {
|
|
margin-right: 16px;
|
|
display: flex;
|
|
align-items: center;
|
|
height: 100%;
|
|
|
|
.ant-pro-global-header-index-action {
|
|
padding: 0 12px;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
height: 100%;
|
|
color: white;
|
|
transition: all 0.3s;
|
|
|
|
&:hover {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
}
|
|
}
|
|
|
|
.ant-avatar {
|
|
margin-right: 8px;
|
|
border: 2px solid rgba(255, 255, 255, 0.2);
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
|
}
|
|
}
|
|
</style>
|