ZaiZai 1 gadu atpakaļ
vecāks
revīzija
f84c49dd8c

+ 7 - 292
src/layout/index.scss

@@ -20,10 +20,15 @@
             }
         }
         .hc-layout-aside-menu {
-
+            position: relative;
+            height: calc(100% - 51px - 46px);
         }
         .hc-layout-aside-user {
+            position: relative;
             border-top: 1px solid #434343;
+            .el-dropdown {
+                display: block;
+            }
         }
     }
     .hc-layout-page {
@@ -32,143 +37,8 @@
     }
 }
 
-
-.hc-layout-box {
-    position: relative;
-    height: 100vh;
-    width: 100%;
-    .hc-layout-header {
-        position: relative;
-        display: flex;
-        align-items: center;
-        flex-direction: row;
-        --el-header-padding: 0;
-        --el-header-height: 44px;
-        background: var(--el-color-primary);
-        color: white;
-        .hc-layout-header-logo {
-            position: relative;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            transition: opacity 0.3s;
-            cursor: pointer;
-            height: 100%;
-            box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.4);
-            z-index: 222;
-            #logo-icon {
-                height: 28px;
-                width: 28px;
-                filter: invert(85%) sepia(91%) saturate(0%) hue-rotate(233deg) brightness(114%) contrast(101%)
-            }
-            .logo-name {
-                color: white;
-                font-size: 18px;
-                font-weight: 300;
-            }
-            &:hover {
-                opacity: .8;
-            }
-        }
-        .header-top-collapse-bar {
-            position: relative;
-            height: 100%;
-            font-size: 20px;
-            display: flex;
-            justify-content: center;
-            align-items: center;
-            padding: 0 10px;
-            cursor: pointer;
-            transition: opacity .2s;
-            &:hover {
-                opacity: 0.7;
-            }
-        }
-        .header-top-menu-bar {
-            position: relative;
-            padding: 0 4px;
-            height: 100%;
-            flex: 1;
-            .el-scrollbar__view {
-                height: 100%;
-            }
-            .hc-top-menu-bar-item {
-                position: relative;
-                height: 100%;
-                display: inline-flex;
-                align-items: center;
-                padding: 0 6px;
-                cursor: pointer;
-                transition: background .2s;
-                .hc-icon-i {
-                    margin-right: 3px;
-                    font-size: 18px;
-                }
-                &:hover {
-                    background: var(--el-color-primary-light-8);
-                }
-            }
-        }
-        .header-content-bar {
-            position: relative;
-            padding: 0 20px;
-            height: 100%;
-            display: flex;
-            align-items: center;
-            .header-icon-bar {
-                position: relative;
-                height: 100%;
-                display: flex;
-                justify-content: center;
-                align-items: center;
-                cursor: pointer;
-                font-size: 23px;
-                margin-right: 16px;
-                color: #efefef;
-                transition: color .2s;
-                &:hover {
-                    color: white;
-                }
-            }
-        }
-    }
-    .hc-layout-container {
-        position: relative;
-        .hc-layout-aside {
-            position: relative;
-            color: white;
-            padding: 8px 0;
-            background: var(--el-color-primary);
-        }
-        .hc-layout-main {
-            position: relative;
-            overflow: hidden;
-            height: 100%;
-            --el-main-padding: 0;
-            .hc-router-menu-bar {
-                position: relative;
-                height: 36px;
-                padding: 0 10px;
-                background: white;
-                box-shadow: 0 2px 6px 0 rgba(0, 0, 0, .1);
-                z-index: 222;
-            }
-            .hc-main-page {
-                position: relative;
-                height: calc(100% - 36px);
-                overflow: hidden;
-                .hc-main-body {
-                    position: absolute;
-                    padding: 12px;
-                    inset: 0;
-                }
-            }
-        }
-    }
-}
-
 //左侧菜单
-.hc-layout-box .hc-layout-container .hc-layout-aside .el-menu {
+.hc-layout-main .hc-layout-aside .hc-layout-aside-menu .el-menu {
     --el-menu-bg-color: transparent;
     --el-menu-text-color: #ffffff;
     --el-menu-active-color: var(--el-menu-text-color);
@@ -345,158 +215,3 @@
         }
     }
 }
-
-//菜单路由
-.hc-layout-box .hc-layout-container .hc-layout-main .hc-router-menu-bar {
-    .el-scrollbar__view {
-        height: 100%;
-    }
-    .hc-router-tab-box {
-        position: relative;
-        display: flex;
-        align-items: center;
-        white-space: nowrap;
-        height: 100%;
-    }
-    .hc-router-tab-item {
-        position: relative;
-        height: 100%;
-        padding: 0 8px;
-        display: inline-flex;
-        align-items: center;
-        cursor: pointer;
-        color: #8F8F8F;
-        user-select: none;
-        transition: .3s;
-        .close-icon {
-            height: 30px;
-            width: 18px;
-            display: flex;
-            align-items: center;
-            justify-content: center;
-            margin-left: 6px;
-            font-size: 16px;
-            cursor: pointer;
-            transition: color 0.3s;
-            &:hover {
-                color: var(--el-color-primary);
-            }
-        }
-        &::after{
-            content: '';
-            left: 0;
-            bottom: 0;
-            height: 2.5px;
-            width: 100%;
-            position: absolute;
-            background-size: 200%;
-        }
-        &:hover:not([class*='cur']) {
-            color: var(--el-color-primary);
-        }
-        &.cur {
-            color: var(--el-color-primary-dark-2);
-            &::after {
-                background: linear-gradient(to right, var(--el-color-primary-light-5), var(--el-color-primary), var(--el-color-primary-dark-2));
-            }
-        }
-    }
-    .el-scrollbar__bar.is-horizontal {
-        bottom: -10px;
-    }
-    .el-scrollbar__bar.is-vertical {
-        display: none;
-    }
-}
-
-
-.aside-menu-popper.el-popper.is-light {
-    background: initial !important;
-    border: 0 !important;
-    outline: none;
-}
-.aside-menu-popper.el-popper .el-menu--vertical .el-menu {
-    --el-menu-bg-color: #f1f5f8;
-    --el-menu-text-color: #838791;
-    --el-menu-active-color: #ffffff;
-    --el-menu-hover-bg-color: initial;
-    --el-menu-item-font-size: 16px;
-    background-color: #f1f5f8;
-    color: #838791;
-    .el-sub-menu__title {
-        padding: 0;
-        justify-content: center;
-        transition: 0.2s;
-    }
-    .el-menu-item, .el-sub-menu {
-        color: inherit;
-        padding: 0;
-        transition: 0.2s;
-        .hc-aside-menu-item {
-            flex: 1;
-            position: relative;
-            padding: 0 16px;
-            display: flex;
-            align-items: center;
-            transition: 0.2s;
-            .menu---item {
-                display: contents;
-            }
-            .hc-menu-icon {
-                font-size: 22px;
-                margin-right: 10px;
-                line-height: initial;
-            }
-            .name {
-                flex: 1;
-                width: 0;
-            }
-            .el-badge, .el-badge .el-badge__content {
-                vertical-align: initial;
-            }
-        }
-        &.is-active {
-            color: white;
-        }
-    }
-    .el-sub-menu .el-icon {
-        display: none;
-    }
-    .el-sub-menu .el-icon.hc-icon-i {
-        position: relative;
-        display: inline-block;
-        font-size: 16px;
-        right: 10px;
-        top: initial;
-        height: initial;
-        width: initial;
-        margin-top: 0;
-        vertical-align: initial;
-    }
-    .el-sub-menu:not(.is-active) .el-sub-menu__title:hover {
-        background-color: var(--el-color-primary-light-9);
-        color: var(--el-color-primary);
-    }
-    .el-menu-item:not(.is-active):hover {
-        .hc-aside-menu-item {
-            background-color: var(--el-color-primary-light-9);
-            color: var(--el-color-primary);
-        }
-    }
-    .el-menu-item.is-active {
-        .hc-aside-menu-item {
-            background-color: var(--el-color-primary);
-        }
-    }
-    .el-sub-menu.is-active .el-sub-menu__title {
-        background-color: var(--el-color-primary-light-9);
-        color: var(--el-color-primary);
-    }
-}
-
-.aside-menu-popper.el-popper .el-menu--vertical.home-index .el-menu {
-    --el-menu-bg-color: initial;
-    --el-menu-text-color: initial;
-    color: white;
-    background-color: var(--el-color-primary-dark-2);
-}

+ 3 - 4
src/layout/index.vue

@@ -8,8 +8,7 @@
                     <hc-upload-bar />
                 </div>
                 <div class="hc-layout-aside-menu">
-                    2222
-                    <!-- MenuBar :cur="menuBarKey" :datas="menuBarData" @change="menuBarChange" / -->
+                    <MenuBar :cur="menuBarKey" :datas="testMenu" @change="menuBarChange" />
                 </div>
                 <div class="hc-layout-aside-user">
                     <UserInfoBar @load="userInfoLoad" />
@@ -29,6 +28,7 @@ import { onMounted, ref } from 'vue'
 import { useAppStore } from '~src/store'
 import { useRouter } from 'vue-router'
 import { initButtons } from '~store/app'
+import testMenu from '~src/router/modules/menu'
 
 //logo文件
 import logoPng from '~src/assets/logo/logo.png'
@@ -39,12 +39,11 @@ const store = useAppStore()
 
 //子组件
 import MenuBar from './modules/MenuBar.vue'
-import HcRefresh from './modules/Refresh.vue'
 import UserInfoBar from './modules/UserInfoBar.vue'
 
 //菜单数据
 const menuBarKey = ref('')
-const menuBarData = ref(store.getMenus)
+//const menuBarData = ref(store.menus)
 
 //渲染完成
 onMounted(() => {

+ 4 - 19
src/layout/modules/MenuBar.vue

@@ -1,7 +1,7 @@
 <template>
     <el-scrollbar>
-        <el-menu :collapse="isCollapse" :default-active="curKey" class="hc-aside-menu" unique-opened text-color="#fff">
-            <MenuItem :collapse="isCollapse" :cur="curKey" :datas="datas" :msg-count="msgCount" @change="MenuClick" />
+        <el-menu :default-active="curKey" class="hc-aside-menu" unique-opened text-color="#fff">
+            <MenuItem :cur="curKey" :datas="datas" @change="MenuClick" />
         </el-menu>
     </el-scrollbar>
 </template>
@@ -19,30 +19,15 @@ const props = defineProps({
         type: String,
         default: 'home-index',
     },
-    collapse: {
-        type: Boolean,
-        default: false,
-    },
-    msgCount: {
-        type: Object,
-        default: () => ({}),
-    },
 })
 
 //事件
 const emit = defineEmits(['change'])
 
-//初始变量
-const curKey = ref(props.cur)
-const isCollapse = ref(props.collapse)
-
 //监听
-watch(() => [
-    props.cur,
-    props.collapse,
-], ([cur, collapse]) => {
+const curKey = ref(props.cur)
+watch(() => props.cur, (cur) => {
     curKey.value = cur
-    isCollapse.value = collapse
 })
 
 //处理菜单数据

+ 6 - 35
src/layout/modules/MenuItem.vue

@@ -1,27 +1,22 @@
 <template>
     <template v-for="item in datas" :key="item?.code">
-        <el-sub-menu v-if="item?.children && item?.children.length > 0" :index="item?.code" :popper-offset="0" :popper-class="`aside-menu-popper ${curKey}`">
+        <el-sub-menu v-if="item?.children && item?.children.length > 0" :index="item?.code">
             <template #title>
                 <div class="hc-aside-menu-item">
                     <div class="menu---item">
                         <hc-icon v-if="item?.source" :name="item?.source" :fill="curKey === item?.code" class="hc-menu-icon" />
-                        <div v-if="isCollapse" class="name truncate">{{ item?.name.substring(0, 2) }}</div>
-                        <div v-else class="name truncate">{{ item?.name }}</div>
-                        <el-badge v-if="item?.code === 'tasks' && msgCount?.allCount > 0" :value="msgCount.allCount" />
+                        <div class="name truncate">{{ item?.name }}</div>
                     </div>
                 </div>
                 <hc-icon name="arrow-down-s" ui="el-icon el-sub-menu__icon-arrow" />
             </template>
-            <MenuItem :datas="item?.children" :cur="curKey" :msg-count="msgCount" @change="MenuClick" />
+            <MenuItem :datas="item?.children" :cur="curKey" @change="MenuClick" />
         </el-sub-menu>
         <el-menu-item v-else :index="item?.code" @click="MenuClick(item)">
             <div class="hc-aside-menu-item">
                 <div class="menu---item">
                     <hc-icon v-if="item?.source" :name="item?.source" :fill="curKey === item?.code" class="hc-menu-icon" />
-                    <div v-if="isCollapse" class="name truncate">{{ item?.name.substring(0, 2) }}</div>
-                    <div v-else class="name truncate">{{ item?.name }}</div>
-                    <el-badge v-if="item?.code === 'tasks-data' && msgCount?.taskCount > 0" :value="msgCount.taskCount" />
-                    <el-badge v-if="item?.code === 'message-data' && msgCount?.messageCount > 0" :value="msgCount.messageCount" />
+                    <div class="name truncate">{{ item?.name }}</div>
                 </div>
             </div>
         </el-menu-item>
@@ -41,38 +36,14 @@ const props = defineProps({
         type: String,
         default: '',
     },
-    collapse: {
-        type: Boolean,
-        default: false,
-    },
-    msgCount: {
-        type: Object,
-        default: () => ({
-            allCount: 0,
-            taskCount: 0,
-            messageCount: 0,
-            messageCount_1: 0,
-            messageCount_2: 0,
-            messageCount_3: 0,
-            messageCount_4: 0,
-            messageCount_5: 0,
-        }),
-    },
 })
 //事件
 const emit = defineEmits(['change'])
 
-//初始变量
-const curKey = ref(props.cur)
-const isCollapse = ref(props.collapse)
-
 //监听
-watch(() => [
-    props.cur,
-    props.collapse,
-], ([cur, collapse]) => {
+const curKey = ref(props.cur)
+watch(() => props.cur, (cur) => {
     curKey.value = cur
-    isCollapse.value = collapse
 })
 
 const MenuClick = (item) => {

+ 0 - 45
src/layout/modules/Refresh.vue

@@ -1,45 +0,0 @@
-<template>
-    <div class="header-icon-bar" @click="tapClick">
-        <el-tooltip content="强刷新" placement="top">
-            <hc-icon name="refresh" class="header-icon" :class="isLoading ? 'rotation' : ''" />
-        </el-tooltip>
-    </div>
-</template>
-
-<script setup>
-import { nextTick, ref } from 'vue'
-import { setRouterData } from '~store/user'
-import { initButtons } from '~store/app'
-import { delStore } from 'hc-vue3-ui'
-
-//被点击
-const isLoading = ref(false)
-const tapClick = async () => {
-    if (isLoading.value) return
-    isLoading.value = true
-    //获取路由菜单
-    const routerRes = await setRouterData()
-    if (routerRes.length <= 0) {
-        return { error: true, msg: '路由异常' }
-    }
-    //获取按钮权限数据
-    delStore('buttons')
-    await nextTick()
-    await initButtons()
-    //刷新路由
-    await nextTick()
-    isLoading.value = false
-    window.location.reload()
-}
-</script>
-
-<style lang="scss" scoped>
-.rotation {
-    animation: hc-ani-rotation-loop 1s linear infinite;
-}
-@keyframes hc-ani-rotation-loop {
-    from { transform: rotate(0deg);}
-    50%  { transform: rotate(180deg);}
-    to   { transform: rotate(360deg);}
-}
-</style>

+ 9 - 16
src/layout/modules/UserInfoBar.vue

@@ -1,9 +1,9 @@
 <template>
     <el-dropdown size="large">
-        <div class="header-bar user-info-bar">
+        <div class="hc-user-info-bar">
             <img :alt="userInfo.account" :src="userInfo.avatar || avatarPng" class="user-avatar">
-            <span class="user-name">{{ userInfo.real_name || '还未登录' }}</span>
-            <hc-icon name="arrow-down-s" ui="arrow-icon" />
+            <div class="user-name">{{ userInfo.real_name || '还未登录' }}</div>
+            <hc-icon name="more-2" fill ui="arrow-icon" />
         </div>
         <template #dropdown>
             <el-dropdown-menu>
@@ -92,21 +92,24 @@ const handleSelect = (key) => {
 </script>
 
 <style lang="scss" scoped>
-.user-info-bar {
+.hc-user-info-bar {
     position: relative;
     display: flex;
     align-items: center;
-    height: 100%;
+    height: 50px;
     cursor: pointer;
     outline: none;
+    width: 100%;
+    padding: 0 10px;
     .user-avatar {
         width: 26px;
         height: 26px;
-        border-radius: 50%;
+        border-radius: 5px;
         background: white;
         object-fit: cover;
     }
     .user-name {
+        flex: 1;
         font-size: 16px;
         margin-left: 10px;
         color: white;
@@ -117,16 +120,6 @@ const handleSelect = (key) => {
         color: white;
     }
 }
-.hc-layout-box .hc-container-view.home .hc-header-view .hc-header-content .user-info-bar {
-    color: inherit;
-    .user-name {
-        color: white;
-    }
-    .arrow-icon {
-        color: white;
-    }
-}
-
 .hc-dropdown-item {
     display: flex;
     align-items: center;

+ 99 - 3
src/router/modules/base.js

@@ -17,24 +17,120 @@ export default [
     {
         path: '/anomaly',
         name: 'anomaly',
-        redirect: '/anomaly-invest',
+        redirect: '/anomaly/invest',
         meta: { title: '异常管理' },
         component: Layout,
         children: [
             {
-                path: '/anomaly-invest',
+                path: '/anomaly/invest',
                 name: 'anomaly-invest',
                 meta: { title: '项目投资异常管理' },
                 component: () => import('~src/views/anomaly/index.vue'),
             },
             {
-                path: '/anomaly-progress?type=progress',
+                path: '/anomaly/progress?type=progress',
                 name: 'anomaly-progress',
                 meta: { title: '项目进度异常管理' },
                 component: () => import('~src/views/anomaly/index.vue'),
             },
         ],
     },
+    {
+        path: '/project',
+        name: 'project',
+        redirect: '/project/collect',
+        meta: { title: '项目管理' },
+        component: Layout,
+        children: [
+            {
+                path: '/project/collect',
+                name: 'project-collect',
+                meta: { title: '项目资料收集' },
+                redirect: '/project/collect/admin',
+                children: [
+                    {
+                        path: '/project/collect/admin',
+                        name: 'project-collect-admin',
+                        meta: { title: '项目管理' },
+                        redirect: '/project/collect/admin/create',
+                        children: [
+                            {
+                                path: '/project/collect/admin/create',
+                                name: 'project-collect-admin-create',
+                                meta: { title: '创建项目' },
+                                component: () => import('~src/views/project/admin/create.vue'),
+                            },
+                            {
+                                path: '/project/collect/admin/list',
+                                name: 'project-collect-admin-list',
+                                meta: { title: '项目列表' },
+                                component: () => import('~src/views/project/admin/list.vue'),
+                            },
+                        ],
+                    },
+                    {
+                        path: '/project/collect/gist',
+                        name: 'project-collect-gist',
+                        meta: { title: '工作要点管理' },
+                        redirect: '/project/collect/gist/create',
+                        children: [
+                            {
+                                path: '/project/collect/gist/create',
+                                name: 'project-collect-gist-create',
+                                meta: { title: '创建工作要点' },
+                                component: () => import('~src/views/project/gist/create.vue'),
+                            },
+                            {
+                                path: '/project/collect/gist/list',
+                                name: 'project-collect-gist-list',
+                                meta: { title: '工作要点列表' },
+                                component: () => import('~src/views/project/gist/list.vue'),
+                            },
+                        ],
+                    },
+                ],
+            },
+            {
+                path: '/project/ledger',
+                name: 'project-ledger',
+                meta: { title: '项目台账' },
+                component: () => import('~src/views/project/ledger.vue'),
+            },
+        ],
+    },
+    {
+        path: '/system',
+        name: 'system',
+        redirect: '/system/user',
+        meta: { title: '系统管理' },
+        component: Layout,
+        children: [
+            {
+                path: '/system/user',
+                name: 'system-user',
+                meta: { title: '用户管理' },
+                component: () => import('~src/views/system/user.vue'),
+            },
+            {
+                path: '/system/menu',
+                name: 'system-menu',
+                meta: { title: '菜单管理' },
+                component: () => import('~src/views/system/menu.vue'),
+            },
+            {
+                path: '/system/role',
+                name: 'system-role',
+                meta: { title: '角色管理' },
+                component: () => import('~src/views/system/role.vue'),
+            },
+            {
+                path: '/system/set',
+                name: 'system-set',
+                meta: { title: '系统设置' },
+                component: () => import('~src/views/system/set.vue'),
+            },
+        ],
+    },
     {
         path: '/403',
         name: '403',

+ 90 - 0
src/router/modules/menu.js

@@ -0,0 +1,90 @@
+export default [
+    {
+        source: 'menu',
+        name: '数据看板',
+        code: 'index',
+    },
+    {
+        source: 'menu',
+        name: '异常管理',
+        code: 'anomaly',
+        children: [
+            {
+                name: '项目投资异常管理',
+                code: 'anomaly-invest',
+            },
+            {
+                name: '项目进度异常管理',
+                code: 'anomaly-progress',
+            },
+        ],
+    },
+    {
+        source: 'menu',
+        name: '项目管理',
+        code: 'project',
+        children: [
+            {
+                name: '项目资料收集',
+                code: 'project-collect',
+                children: [
+                    {
+                        name: '项目管理',
+                        code: 'project-collect-admin',
+                        children: [
+                            {
+                                name: '创建项目',
+                                code: 'project-collect-admin-create',
+                            },
+                            {
+                                name: '项目列表',
+                                code: 'project-collect-admin-list',
+                            },
+                        ],
+                    },
+                    {
+                        name: '工作要点管理',
+                        code: 'project-collect-gist',
+                        children: [
+                            {
+                                name: '创建工作要点',
+                                code: 'project-collect-gist-create',
+                            },
+                            {
+                                name: '工作要点列表',
+                                code: 'project-collect-gist-list',
+                            },
+                        ],
+                    },
+                ],
+            },
+            {
+                name: '项目台账',
+                code: 'project-ledger',
+            },
+        ],
+    },
+    {
+        source: 'menu',
+        name: '系统设置',
+        code: 'system',
+        children: [
+            {
+                name: '用户管理',
+                code: 'system-user',
+            },
+            {
+                name: '角色管理',
+                code: 'system-role',
+            },
+            {
+                name: '菜单管理',
+                code: 'system-menu',
+            },
+            {
+                name: '系统设置',
+                code: 'system-set',
+            },
+        ],
+    },
+]

+ 12 - 0
src/views/project/admin/create.vue

@@ -0,0 +1,12 @@
+<template>
+    <div>创建项目</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped lang="scss">
+
+</style>
+

+ 11 - 0
src/views/project/admin/list.vue

@@ -0,0 +1,11 @@
+<template>
+    <div>项目列表</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 12 - 0
src/views/project/gist/create.vue

@@ -0,0 +1,12 @@
+<template>
+    <div>创建工作要点</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped lang="scss">
+
+</style>
+

+ 11 - 0
src/views/project/gist/list.vue

@@ -0,0 +1,11 @@
+<template>
+    <div>工作要点列表</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 11 - 0
src/views/project/ledger.vue

@@ -0,0 +1,11 @@
+<template>
+    <div>项目台账</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 11 - 0
src/views/system/menu.vue

@@ -0,0 +1,11 @@
+<template>
+    <div>菜单管理</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 11 - 0
src/views/system/role.vue

@@ -0,0 +1,11 @@
+<template>
+    <div>角色管理</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 11 - 0
src/views/system/set.vue

@@ -0,0 +1,11 @@
+<template>
+    <div>系统设置</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped lang="scss">
+
+</style>

+ 11 - 0
src/views/system/user.vue

@@ -0,0 +1,11 @@
+<template>
+    <div>用户管理</div>
+</template>
+
+<script setup>
+
+</script>
+
+<style scoped lang="scss">
+
+</style>