first commit

This commit is contained in:
JaguarJack
2022-12-05 23:01:12 +08:00
commit 0024080c28
322 changed files with 27698 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
<script lang="ts">
import { h, defineComponent, VNode } from 'vue'
import { usePermissionsStore } from '/admin/stores/modules/user/permissions'
import MenuItem from './item.vue'
import menus from './menus.vue'
import { useUserStore } from '/admin/stores/modules/user'
import { Menu } from '/admin/types/Menu'
/**
* 递归渲染 Menu 节点
*/
function getVNodes(menus: Menu[] | undefined, _subMenuClass: string | undefined): VNode[] {
const vnodes: VNode[] = []
menus?.forEach(menu => {
if (!menu.meta?.hidden) {
let vnode: VNode
const len = menu.children?.length
if (len) {
vnode = h(
MenuItem,
{
subMenuClass: _subMenuClass,
menu,
},
{
default: () => getVNodes(menu.children, 'children-menu'),
},
)
} else {
vnode = h(MenuItem, {
subMenuClass: _subMenuClass,
menu,
})
}
vnodes.push(vnode)
}
})
return vnodes
}
/**
* filter menus
*
* @param menus
*/
function filterMenus(menus: Menu[] | undefined): Menu[] {
const newMenus: Menu[] = []
menus?.forEach(m => {
if (m.meta?.hidden) {
return false
}
if (isHasOnlyChild(m) && m.children?.length) {
newMenus.push(
Object.assign({
path: m.children[0].path,
meta: m.children[0].meta,
name: m.name,
}),
)
} else {
newMenus.push(m)
}
})
return newMenus
}
/**
* is has only child
*
* @param menu
*/
function isHasOnlyChild(menu: Menu): boolean {
if (menu.children === undefined) {
return true
}
if (menu.children.length > 1 || !menu.children.length) {
return false
}
if (menu.children[0].children?.length) {
return false
}
return true
}
export default defineComponent({
props: {
subMenuClass: {
type: String,
require: true,
},
menuClass: {
type: String,
require: true,
},
},
setup(props, ctx) {
const permissionsStore = usePermissionsStore()
const userStore = useUserStore()
// 后端的 permissions 返回 undefined则认为该后端无权限系统
const permissions = userStore.getPermissions === undefined ? [] : userStore.getPermissions
const vnodes = getVNodes(filterMenus(permissionsStore.getMenusFrom(permissions)), props.subMenuClass)
return () => {
return h(
menus,
{
class: 'border-none side-menu ' + props.menuClass,
},
{
default: () => vnodes,
},
)
}
},
})
</script>

View File

@@ -0,0 +1,58 @@
<template>
<el-sub-menu :index="menu?.path" :class="subMenuClass" v-if="menu?.children?.length">
<template #title>
<el-icon>
<Icon :name="menu?.meta?.icon" v-if="menu?.meta?.icon" class="text-sm"/>
</el-icon>
<span>{{ menu?.meta?.title }}</span>
</template>
<slot/>
</el-sub-menu>
<el-menu-item v-else class="ct-menu-item" :index="menu?.path" @click="isMiniScreen() && store.changeExpaned()">
<el-icon>
<Icon :name="menu?.meta?.icon" v-if="menu?.meta?.icon" class="text-sm"/>
</el-icon>
<span>{{ menu?.meta?.title }}</span>
</el-menu-item>
</template>
<script lang="ts" name="MenuItem" setup>
import { Menu } from '/admin/types/Menu'
import { PropType } from 'vue'
import { useAppStore } from '/admin/stores/modules/app'
import { isMiniScreen } from '/admin/support/Helper'
const store = useAppStore()
defineProps({
subMenuClass: {
type: String,
require: true,
default: '',
},
menu: {
type: Object as PropType<Menu>,
require: true,
},
})
</script>
<style scoped lang="scss">
:deep(.el-menu) {
background-color: var(--sider-sub-menu-bg-color);
}
.ct-menu-item:hover {
background-color: var(--sider-sub-menu-hover-bg-color) !important;
}
:deep(.children-menu .el-sub-menu__title) {
background-color: var(--sider-sub-menu-bg-color) !important;
}
:deep(.el-menu-item-group__title) {
padding: 0;
}
</style>

View File

@@ -0,0 +1,9 @@
<template>
<div class="block sm:hidden z-40 w-screen h-full absolute mask-bg left-0 top-0" />
</template>
<style scoped>
.mask-bg {
background-color: #00000080;
}
</style>

View File

@@ -0,0 +1,66 @@
<template>
<el-menu
:default-active="appStore.getActiveMenu"
background-color="var(--sider-menu-bg-color)"
active-text-color="var(--sider-ment-active-text-color)"
text-color="var(--sider-menu-text-color)"
:collapse="!appStore.isExpand"
:collapse-transition="false"
:router="true"
@select="selectMenu"
:unique-opened="true"
>
<slot/>
</el-menu>
</template>
<script lang="ts" setup name="menus">
import { useAppStore } from '/admin/stores/modules/app'
const appStore = useAppStore()
const selectMenu = (index: string) => {
if (index.startsWith('http') || index.startsWith('https')) {
window.open(index)
}
}
</script>
<style scoped lang="scss">
.el-menu {
border-right: none;
}
:deep(.el-menu--inline) {
@apply pt-1 pb-2;
}
:deep(.ct-menu-item) {
@apply mt-1;
}
:deep(.is-active) {
background-color: var(--side-active-menu-bg-color) !important;
}
:deep(.el-sub-menu__title) {
padding-left: calc(calc(var(--el-menu-base-level-padding) + var(--el-menu-level) * var(--el-menu-level-padding)));
color: var(--sider-menu-text-color);
}
:deep(.el-sub-menu) {
color: var(--sider-sub-menu-bg-color);
}
:deep(.el-sub-menu__title:hover) {
background-color: var(--sider-menu-bg-color);
}
:deep(.el-menu--popup .el-menu-item:hover) {
background-color: var(--sider-menu-bg-color) !important;
}
:deep(.el-menu-item:hover) {
background-color: var(--sider-sub-menu-hover-bg-color) !important;
}
</style>