parent
863dffa20d
commit
f3795fedab
@ -1,11 +1,11 @@
|
||||
# 页面标题
|
||||
VUE_APP_TITLE = 若依管理系统
|
||||
VUE_APP_TITLE = 金鸡湖现代服务业品牌管理系统
|
||||
|
||||
# 开发环境配置
|
||||
ENV = 'development'
|
||||
|
||||
# 若依管理系统/开发环境
|
||||
VUE_APP_BASE_API = '/dev-api'
|
||||
# 金鸡湖现代服务业品牌管理系统/开发环境
|
||||
VUE_APP_BASE_API = 'https://vue.ruoyi.vip/prod-api'
|
||||
|
||||
# 路由懒加载
|
||||
VUE_CLI_BABEL_TRANSPILE_MODULES = true
|
||||
|
@ -1,8 +1,8 @@
|
||||
# 页面标题
|
||||
VUE_APP_TITLE = 若依管理系统
|
||||
VUE_APP_TITLE = 金鸡湖现代服务业品牌管理系统
|
||||
|
||||
# 生产环境配置
|
||||
ENV = 'production'
|
||||
|
||||
# 若依管理系统/生产环境
|
||||
# 金鸡湖现代服务业品牌管理系统/生产环境
|
||||
VUE_APP_BASE_API = '/prod-api'
|
||||
|
@ -1,10 +1,10 @@
|
||||
# 页面标题
|
||||
VUE_APP_TITLE = 若依管理系统
|
||||
VUE_APP_TITLE = 金鸡湖现代服务业品牌管理系统
|
||||
|
||||
NODE_ENV = production
|
||||
|
||||
# 测试环境配置
|
||||
ENV = 'staging'
|
||||
|
||||
# 若依管理系统/测试环境
|
||||
# 金鸡湖现代服务业品牌管理系统/测试环境
|
||||
VUE_APP_BASE_API = '/stage-api'
|
||||
|
Before Width: | Height: | Size: 509 KiB After Width: | Height: | Size: 201 KiB |
After Width: | Height: | Size: 5.5 KiB |
@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div class="menu-item-container">
|
||||
<div
|
||||
class="menu-item"
|
||||
v-for="(router, routerIndex) in topMenus"
|
||||
:key="routerIndex"
|
||||
>
|
||||
<el-dropdown
|
||||
v-if="router.children && router.children.length > 0"
|
||||
class="menu-item-box"
|
||||
trigger="hover"
|
||||
>
|
||||
<div
|
||||
class="item-title"
|
||||
:class="handleActive(router.path) ? 'dropdownActive' : ''"
|
||||
>
|
||||
{{ router.meta.title }}
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<router-link
|
||||
active-class="dropdownActive"
|
||||
:to="router.path + '/' + item.path"
|
||||
v-for="(item, itemIndex) in router.children"
|
||||
:key="itemIndex"
|
||||
>
|
||||
<el-dropdown-item>
|
||||
<el-dropdown
|
||||
v-if="item.children && item.children.length > 0"
|
||||
class="menu-item-box"
|
||||
trigger="hover"
|
||||
>
|
||||
<div
|
||||
class="item-title"
|
||||
:class="
|
||||
handleActive(router.path + '/' + item.path)
|
||||
? 'dropdownActive'
|
||||
: ''
|
||||
"
|
||||
>
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"
|
||||
/>
|
||||
{{ item.meta.title }}
|
||||
</div>
|
||||
<router-link
|
||||
active-class="dropdownActive"
|
||||
v-for="(item2, itemIndex2) in item.children"
|
||||
:key="itemIndex2"
|
||||
>
|
||||
<el-dropdown-item>
|
||||
<svg-icon
|
||||
v-if="
|
||||
item2.meta && item2.meta.icon && item2.meta.icon !== '#'
|
||||
"
|
||||
:icon-class="item2.meta.icon"
|
||||
/>
|
||||
<span style="margin-left: 6px">{{ item2.meta.title }}</span>
|
||||
</el-dropdown-item>
|
||||
</router-link>
|
||||
</el-dropdown>
|
||||
|
||||
<div v-else>
|
||||
<svg-icon
|
||||
v-if="item.meta && item.meta.icon && item.meta.icon !== '#'"
|
||||
:icon-class="item.meta.icon"
|
||||
/>
|
||||
<span style="margin-left: 6px">{{ item.meta.title }}</span>
|
||||
</div>
|
||||
</el-dropdown-item>
|
||||
</router-link>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
|
||||
<router-link
|
||||
v-else
|
||||
tag="div"
|
||||
class="item-title"
|
||||
active-class="dropdownActive"
|
||||
:to="router.path"
|
||||
>
|
||||
<span>{{ router.meta.title }}</span>
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
methods: {
|
||||
handleActive(path) {
|
||||
return this.$route.path.includes(path);
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
// 顶部显示菜单
|
||||
topMenus() {
|
||||
let topMenus = [];
|
||||
this.routers.map((menu) => {
|
||||
if (menu.hidden !== true) {
|
||||
// 兼容顶部栏一级菜单内部跳转
|
||||
if (menu.path === "/") {
|
||||
topMenus.push(menu.children[0]);
|
||||
} else {
|
||||
topMenus.push(menu);
|
||||
}
|
||||
}
|
||||
});
|
||||
console.log(topMenus, "aa");
|
||||
return topMenus;
|
||||
},
|
||||
// 所有的路由信息
|
||||
routers() {
|
||||
return this.$store.state.permission.topbarRouters;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.menu-item-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.item-title {
|
||||
padding: 3px 10px;
|
||||
font-size: 18px;
|
||||
cursor: pointer;
|
||||
border-radius: 24px;
|
||||
margin: 0 5px;
|
||||
color: #fff;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.dropdownActive {
|
||||
border-color: #fff !important;
|
||||
background: hsla(0, 0%, 100%, 0.15);
|
||||
}
|
||||
|
||||
.dropdownActive li {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
@ -0,0 +1,125 @@
|
||||
<template>
|
||||
<div class="system-header">
|
||||
<div
|
||||
class="navigation-bar"
|
||||
:style="{ background: variables.navBackground }"
|
||||
>
|
||||
<div class="left-menu">
|
||||
<img class="system-logo" src="@/assets/images/logo.png" />
|
||||
<div class="system-title">{{ systemTitle }}</div>
|
||||
<div class="sysyem-menu">
|
||||
<menu-item></menu-item>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-menu">
|
||||
<el-dropdown
|
||||
class="avatar-container right-menu-item hover-effect"
|
||||
trigger="click"
|
||||
>
|
||||
<div class="avatar-wrapper">
|
||||
<img :src="avatar" class="user-avatar" />
|
||||
<div class="user-name">{{ name }}</div>
|
||||
<i class="el-icon-caret-bottom" />
|
||||
</div>
|
||||
<el-dropdown-menu slot="dropdown">
|
||||
<router-link to="/user/profile">
|
||||
<el-dropdown-item>个人中心</el-dropdown-item>
|
||||
</router-link>
|
||||
|
||||
<el-dropdown-item divided @click.native="logout">
|
||||
<span>退出登录</span>
|
||||
</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapGetters } from "vuex";
|
||||
import variables from "@/assets/styles/variables.scss";
|
||||
import MenuItem from "./components/MenuItem.vue";
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
systemTitle: process.env.VUE_APP_TITLE,
|
||||
};
|
||||
},
|
||||
components: {
|
||||
MenuItem,
|
||||
},
|
||||
computed: {
|
||||
...mapGetters(["avatar", "name", "sidebarRouters"]),
|
||||
variables() {
|
||||
return variables;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async logout() {
|
||||
this.$confirm("确定注销并退出系统吗?", "提示", {
|
||||
confirmButtonText: "确定",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(() => {
|
||||
this.$store.dispatch("LogOut").then(() => {
|
||||
location.href = "/index";
|
||||
});
|
||||
})
|
||||
.catch(() => {});
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.system-header {
|
||||
height: 98px;
|
||||
width: 100%;
|
||||
color: #fff;
|
||||
.navigation-bar {
|
||||
height: 64px;
|
||||
padding: 0 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
overflow: hidden;
|
||||
.left-menu {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
.system-logo {
|
||||
height: 48px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
.system-title {
|
||||
margin-right: 20px;
|
||||
cursor: pointer;
|
||||
font-size: 22px;
|
||||
}
|
||||
.sysyem-menu {
|
||||
}
|
||||
}
|
||||
.right-menu {
|
||||
.avatar-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #fff;
|
||||
cursor: pointer;
|
||||
.user-avatar {
|
||||
height: 40px;
|
||||
width: 40px;
|
||||
border-radius: 10px;
|
||||
}
|
||||
.user-name {
|
||||
padding: 0 10px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
font-size: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -1,5 +1,6 @@
|
||||
export { default as AppMain } from './AppMain'
|
||||
export { default as Navbar } from './Navbar'
|
||||
export { default as Settings } from './Settings'
|
||||
export { default as Sidebar } from './Sidebar/index.vue'
|
||||
export { default as TagsView } from './TagsView/index.vue'
|
||||
export { default as AppMain } from "./AppMain";
|
||||
export { default as Navbar } from "./Navbar";
|
||||
export { default as Settings } from "./Settings";
|
||||
export { default as Sidebar } from "./Sidebar/index.vue";
|
||||
export { default as TagsView } from "./TagsView/index.vue";
|
||||
export { default as FixedHeader } from "./FixedHeader/index.vue";
|
||||
|
@ -0,0 +1,111 @@
|
||||
<template>
|
||||
<div :class="classObj" class="app-wrapper" :style="{'--current-color': theme}">
|
||||
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside"/>
|
||||
<sidebar v-if="!sidebar.hide" class="sidebar-container"/>
|
||||
<div :class="{hasTagsView:needTagsView,sidebarHide:sidebar.hide}" class="main-container">
|
||||
<div :class="{'fixed-header':fixedHeader}">
|
||||
<navbar/>
|
||||
<tags-view v-if="needTagsView"/>
|
||||
</div>
|
||||
<app-main/>
|
||||
<right-panel>
|
||||
<settings/>
|
||||
</right-panel>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import RightPanel from '@/components/RightPanel'
|
||||
import { AppMain, Navbar, Settings, Sidebar, TagsView } from './components'
|
||||
import ResizeMixin from './mixin/ResizeHandler'
|
||||
import { mapState } from 'vuex'
|
||||
import variables from '@/assets/styles/variables.scss'
|
||||
|
||||
export default {
|
||||
name: 'Layout',
|
||||
components: {
|
||||
AppMain,
|
||||
Navbar,
|
||||
RightPanel,
|
||||
Settings,
|
||||
Sidebar,
|
||||
TagsView
|
||||
},
|
||||
mixins: [ResizeMixin],
|
||||
computed: {
|
||||
...mapState({
|
||||
theme: state => state.settings.theme,
|
||||
sideTheme: state => state.settings.sideTheme,
|
||||
sidebar: state => state.app.sidebar,
|
||||
device: state => state.app.device,
|
||||
needTagsView: state => state.settings.tagsView,
|
||||
fixedHeader: state => state.settings.fixedHeader
|
||||
}),
|
||||
classObj() {
|
||||
return {
|
||||
hideSidebar: !this.sidebar.opened,
|
||||
openSidebar: this.sidebar.opened,
|
||||
withoutAnimation: this.sidebar.withoutAnimation,
|
||||
mobile: this.device === 'mobile'
|
||||
}
|
||||
},
|
||||
variables() {
|
||||
return variables;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handleClickOutside() {
|
||||
this.$store.dispatch('app/closeSideBar', { withoutAnimation: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@import "~@/assets/styles/mixin.scss";
|
||||
@import "~@/assets/styles/variables.scss";
|
||||
|
||||
.app-wrapper {
|
||||
@include clearfix;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
&.mobile.openSidebar {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.drawer-bg {
|
||||
background: #000;
|
||||
opacity: 0.3;
|
||||
width: 100%;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
z-index: 999;
|
||||
}
|
||||
|
||||
.fixed-header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
z-index: 9;
|
||||
width: calc(100% - #{$base-sidebar-width});
|
||||
transition: width 0.28s;
|
||||
}
|
||||
|
||||
.hideSidebar .fixed-header {
|
||||
width: calc(100% - 54px);
|
||||
}
|
||||
|
||||
.sidebarHide .fixed-header {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.mobile .fixed-header {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
Loading…
Reference in new issue