mirror of
https://gitee.com/likeadmin/likeadmin_java.git
synced 2026-05-10 09:16:21 +08:00
初始化admin pc端
This commit is contained in:
89
admin/src/layout/components/layout-aside/index.vue
Normal file
89
admin/src/layout/components/layout-aside/index.vue
Normal file
@@ -0,0 +1,89 @@
|
||||
<template>
|
||||
<div class="layout-aside">
|
||||
<router-link to="/workbench" class="logo flex col-center">
|
||||
<img class="logo-img" :src="config.web_logo" alt />
|
||||
<div class="line-1">{{ config.web_name }}</div>
|
||||
</router-link>
|
||||
<div class="scrollbar-wrap">
|
||||
<el-scrollbar style="height: 100%" class="ls-scrollbar">
|
||||
<el-menu
|
||||
active-text-color="#fff"
|
||||
background-color="#2a2c41"
|
||||
:default-active="currentPath"
|
||||
text-color="#E5E5E5"
|
||||
router
|
||||
>
|
||||
<template v-for="(item, index) in sidebar" :key="index">
|
||||
<sub-menu :route="item">
|
||||
<template v-for="(item, index) in item?.children" :key="index">
|
||||
<sub-menu :route="item">
|
||||
<template v-for="(item, index) in item?.children" :key="index">
|
||||
<sub-menu :route="item"></sub-menu>
|
||||
</template>
|
||||
</sub-menu>
|
||||
</template>
|
||||
</sub-menu>
|
||||
</template>
|
||||
</el-menu>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import { useAdmin } from '@/core/hooks/app'
|
||||
import SubMenu from './sub-menu.vue'
|
||||
export default defineComponent({
|
||||
components: {
|
||||
SubMenu
|
||||
},
|
||||
setup() {
|
||||
const { store, route } = useAdmin()
|
||||
const sidebar = computed(() => store.state.permission.sidebar)
|
||||
const currentPath = computed(() => route.meta?.parent ?? route.path)
|
||||
const config = computed(() => store.getters.config)
|
||||
return {
|
||||
config,
|
||||
sidebar,
|
||||
currentPath
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.layout-aside {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: #2a2c41;
|
||||
.logo {
|
||||
height: $layout-header-height;
|
||||
font-weight: 500;
|
||||
font-size: 18px;
|
||||
color: #fff;
|
||||
padding: 0 20px;
|
||||
.logo-img {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
.scrollbar-wrap {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
.el-menu {
|
||||
box-sizing: border-box;
|
||||
padding: 10px 0 20px;
|
||||
:deep(.el-menu-item) {
|
||||
&.is-active {
|
||||
background-color: $color-primary;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
38
admin/src/layout/components/layout-aside/sub-menu.vue
Normal file
38
admin/src/layout/components/layout-aside/sub-menu.vue
Normal file
@@ -0,0 +1,38 @@
|
||||
<template>
|
||||
<template v-if="!route.meta.hidden">
|
||||
<el-sub-menu v-if="hasChildren" :index="route.path">
|
||||
<template #title>
|
||||
<i class="iconfont m-r-10" :class="route.meta.icon"></i>
|
||||
<span>{{ route.meta.title }}</span>
|
||||
</template>
|
||||
<slot></slot>
|
||||
</el-sub-menu>
|
||||
<el-menu-item v-else :index="route.path">
|
||||
<i class="iconfont m-r-10" :class="route.meta.icon"></i>
|
||||
<span>{{ route.meta.title }}</span>
|
||||
</el-menu-item>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import { RouteRecordRaw } from 'vue-router'
|
||||
export default defineComponent({
|
||||
components: {},
|
||||
props: {
|
||||
route: {
|
||||
type: Object,
|
||||
default: () => ({})
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const hasChildren = computed(() => {
|
||||
const children: RouteRecordRaw[] = props.route.children ?? []
|
||||
return !!children.filter(item => !item.meta?.hidden).length
|
||||
})
|
||||
return {
|
||||
hasChildren
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
67
admin/src/layout/components/layout-header.vue
Normal file
67
admin/src/layout/components/layout-header.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="layout-header">
|
||||
<!-- <input class="search-input" placeholder="请输入搜索内容…" type="text" /> -->
|
||||
<div class="admin-info flex flex-center m-l-40">
|
||||
<el-avatar :size="40" :src="userInfo.avatar"></el-avatar>
|
||||
<div class="m-l-10">
|
||||
<el-dropdown trigger="hover" @command="handleCommand">
|
||||
<div class="flex flex-center">
|
||||
{{ userInfo.name }}
|
||||
<el-icon class="el-icon--right"><arrow-down /></el-icon>
|
||||
</div>
|
||||
<template #dropdown>
|
||||
<el-dropdown-menu>
|
||||
<el-dropdown-item command="logout">退出登录</el-dropdown-item>
|
||||
</el-dropdown-menu>
|
||||
</template>
|
||||
</el-dropdown>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import { useAdmin } from '@/core/hooks/app'
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const { store, router } = useAdmin()
|
||||
const userInfo = computed(() => store.getters.userInfo)
|
||||
const handleCommand = (command: string) => {
|
||||
switch (command) {
|
||||
case 'logout':
|
||||
store.dispatch('user/logout').then(() => {
|
||||
router.push('/login')
|
||||
store.commit('permission/setPermission', {
|
||||
auth: null,
|
||||
root: 0
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
return {
|
||||
userInfo,
|
||||
handleCommand
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.layout-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
flex: none;
|
||||
height: $layout-header-height;
|
||||
background: #fff;
|
||||
padding: 0 24px;
|
||||
.search-input {
|
||||
width: 460px;
|
||||
height: 40px;
|
||||
border-radius: 20px;
|
||||
background: #f6f6f6;
|
||||
padding: 0 20px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
26
admin/src/layout/components/layout-main.vue
Normal file
26
admin/src/layout/components/layout-main.vue
Normal file
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<div class="layout-main">
|
||||
<el-scrollbar>
|
||||
<div class="p-15">
|
||||
<perm />
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import Perm from './perm.vue'
|
||||
export default defineComponent({
|
||||
components: {
|
||||
Perm
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.layout-main {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
}
|
||||
</style>
|
||||
57
admin/src/layout/components/perm.vue
Normal file
57
admin/src/layout/components/perm.vue
Normal file
@@ -0,0 +1,57 @@
|
||||
<template>
|
||||
<div v-if="permission" class="perm">
|
||||
<template v-if="hasPermission">
|
||||
<router-view></router-view>
|
||||
</template>
|
||||
<template v-else>
|
||||
<div class="no-perm flex flex-col flex-center">
|
||||
<img src="@/assets/images/no_perm.png" />
|
||||
<div class="muted">暂无查看权限</div>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import { useAdmin } from '@/core/hooks/app'
|
||||
export default defineComponent({
|
||||
components: {},
|
||||
props: {},
|
||||
setup(props) {
|
||||
const { store, route } = useAdmin()
|
||||
const permission = computed(() => store.getters.permission)
|
||||
const isAdmin = computed(() => store.getters.isAdmin)
|
||||
const hasPermission = computed(() => {
|
||||
const { path, meta } = route
|
||||
if (isAdmin.value) {
|
||||
return true
|
||||
}
|
||||
const actions = permission.value[path]
|
||||
console.log(permission.value, path)
|
||||
if (!actions || !meta?.permission) {
|
||||
return true
|
||||
}
|
||||
return actions.some((item: string) => {
|
||||
return (meta?.permission as string[]).includes(item)
|
||||
})
|
||||
})
|
||||
return {
|
||||
permission,
|
||||
hasPermission
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.perm {
|
||||
.no-perm {
|
||||
height: calc(100vh - #{$layout-header-height} - 32px);
|
||||
img {
|
||||
width: 152px;
|
||||
height: 152px;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
44
admin/src/layout/index.vue
Normal file
44
admin/src/layout/index.vue
Normal file
@@ -0,0 +1,44 @@
|
||||
<template>
|
||||
<div class="layout">
|
||||
<div class="aside">
|
||||
<layout-aside />
|
||||
</div>
|
||||
<div class="main">
|
||||
<layout-header />
|
||||
<layout-main />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import LayoutAside from './components/layout-aside/index.vue'
|
||||
import LayoutMain from './components/layout-main.vue'
|
||||
import LayoutHeader from './components/layout-header.vue'
|
||||
export default defineComponent({
|
||||
components: {
|
||||
LayoutAside,
|
||||
LayoutMain,
|
||||
LayoutHeader
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.layout {
|
||||
display: flex;
|
||||
height: 100vh;
|
||||
width: 100vw;
|
||||
min-width: $layout-min-width;
|
||||
.aside {
|
||||
flex: none;
|
||||
width: $layout-aside-width;
|
||||
}
|
||||
.main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user