ZaiZai %!s(int64=3) %!d(string=hai) anos
pai
achega
951c2a1739

+ 1 - 1
src/global/components/hc-icon/index.vue

@@ -12,7 +12,7 @@ const props = defineProps({
     name: {
         type: [String,Number],
         default: ''
-    },
+    }
 })
 
 //初始变量

+ 15 - 9
src/layout/index.vue

@@ -1,14 +1,22 @@
 <template>
     <el-container class="hc-layout-box">
-        <el-aside width="240px" class="hc-aside-box">
+        <el-aside width="250px" class="hc-aside-box">
             <div class="hc-aside-logo-box" @click="logoClick">
                 <img class="logo-img" :src="getAssetsHomeFile(`${AppColor.name}.png`)" alt="">
                 <img class="logo-img-1" :src="NameWhite" alt="">
             </div>
-
-            <div>
-                <HcIcon name="width_normal"/>
-                <HcIcon name="width_full"/>
+            <div class="hc-aside-menu-box">
+                <el-scrollbar>
+                    <MenuBar :datas="MenuBarData" :cur="MenuBarKey" @change="MenuBarChange"/>
+                </el-scrollbar>
+            </div>
+            <div class="hc-aside-bar-box">
+                <div class="active">
+                    <HcIcon name="width_normal"/>
+                </div>
+                <div>
+                    <HcIcon name="width_full"/>
+                </div>
             </div>
         </el-aside>
         <el-container>
@@ -57,8 +65,6 @@ import {useRoute} from 'vue-router'
 import {useAppStore} from "~src/store/index";
 import router from '~src/router/index';
 import MenuBar from "./modules/MenuBar.vue"
-import MenuQuality from "./modules/MenuQuality.vue"
-import MenuTask from "./modules/MenuTask.vue"
 import HelpInfoBar from "./modules/HelpInfoBar.vue"
 import UserInfoBar from "./modules/UserInfoBar.vue"
 import ConfigBar from "./modules/ConfigBar.vue"
@@ -71,7 +77,7 @@ const useAppState = useAppStore()
 
 const routerQuery = useRoutes?.query;
 const reloadRouter = ref(true)
-const BarMenuKey = routerQuery?.MenuBarKey || '';
+const BarMenuKey = routerQuery?.MenuBarKey || 'home-index';
 
 const HomeTheme = ref(useAppState.getHomeTheme);
 const AppColor = ref(useAppState.getColor);
@@ -185,7 +191,7 @@ const projectContractChange = (val) => {
 }
 
 //菜单被点击
-const MenuBarChange = ({item}) => {
+const MenuBarChange = (item) => {
     MenuBarKey.value = item.key;
 }
 //弹出菜单事件

+ 43 - 2
src/layout/layout.scss

@@ -15,8 +15,8 @@
             justify-content: center;
             transition: opacity 0.3s;
             cursor: pointer;
-            margin-top: 30px;
-            left: -5px;
+            margin: 32px 0;
+            left: -10px;
             .logo-img {
                 height: 40px;
             }
@@ -28,6 +28,47 @@
                 opacity: .8;
             }
         }
+        .hc-aside-menu-box {
+            position: relative;
+            height: calc(100% - 216px);
+            width: 100%;
+        }
+        .hc-aside-bar-box {
+            position: relative;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            padding: 24px 0;
+            margin-top: 24px;
+            &:before {
+                position: absolute;
+                content: '';
+                top: 0;
+                width: 100%;
+                height: 1px;
+                background-image: linear-gradient(90deg, rgba(102,102,102,0.00) 11%, #666666 35%, #666666 64%, rgba(102,102,102,0.00) 86%);
+            }
+            div {
+                position: relative;
+                width: 40px;
+                height: 40px;
+                display: flex;
+                justify-content: center;
+                align-items: center;
+                font-size: 30px;
+                &.active {
+                    border-radius: 6px;
+                    background: var(--el-color-primary);
+                    box-shadow: 4px 4px 8px 0 rgba(0, 0, 0, 0.3), -1px 0 8px 0 #707070;
+                }
+                &:not(.active) {
+                    cursor: pointer;
+                }
+                &+div{
+                    margin-left: 26px;
+                }
+            }
+        }
     }
     .hc-header-view {
         position: relative;

+ 55 - 79
src/layout/modules/MenuBar.vue

@@ -1,26 +1,16 @@
 <template>
-    <div class="hc-horizontal-menu-box">
-        <template v-for="(item,index) in datas">
-            <n-popover trigger="hover" placement="bottom" v-if="item.children?.length > 0">
-                <template #trigger>
-                    <div class="hc-horizontal-menu-item" :class="curKey === item.key?'cur':''" @click="menuClick(item,index)">
-                        <n-badge :value="20" processing v-if="item.key==='tasks'">
-                            {{item.name}}
-                        </n-badge>
-                        <template v-else>
-                            {{item.name}}
-                        </template>
-                    </div>
-                </template>
-                <slot :name="item.key" v-bind="item"/>
-            </n-popover>
-            <div class="hc-horizontal-menu-item" :class="curKey === item.key?'cur':''" @click="menuClick(item,index)" v-else>{{item.name}}</div>
-        </template>
-    </div>
+    <el-menu :default-active="curKey" class="hc-aside-menu" :collapse="isCollapse">
+        <el-menu-item index="home-index">
+            <HcIcon name="home" class="hc-menu-icon" :ui="curKey === 'home-index'?'fill':''"/>
+            <template #title>首页</template>
+        </el-menu-item>
+        <MenuItem :datas="datas" @change="MenuClick"/>
+    </el-menu>
 </template>
 
 <script setup>
 import {ref,watch} from "vue";
+import MenuItem from "./MenuItem.vue"
 const props = defineProps({
     datas: {
         type: Array,
@@ -28,81 +18,67 @@ const props = defineProps({
     },
     cur: {
         type: String,
-        default: ''
-    }
+        default: 'home-index'
+    },
+    collapse: {
+        type: Boolean,
+        default: false
+    },
 })
 
+//初始变量
 const curKey = ref(props.cur);
+const isCollapse = ref(props.collapse);
 
-watch(() => props.cur, (cur) => {
+//监听
+watch(() => [
+    props.cur,
+    props.collapse
+], ([cur,collapse]) => {
     curKey.value = cur
+    isCollapse.value = collapse
 })
 
+//事件
 const emit = defineEmits(['change'])
-const menuClick = (item,index) => {
-    if (item?.children?.length <= 0) {
-        curKey.value = item?.key||'';
-        emit('change', {item,index})
-    }
+const MenuClick = (item) => {
+    console.log(item)
+    curKey.value = item?.key || '';
+    emit('change', item)
 }
 </script>
 
-<style lang="scss" scoped>
-.hc-horizontal-menu-box {
-    position: relative;
-    display: flex;
-    align-items: center;
-    height: 100%;
-    flex: auto;
-    justify-content: flex-end;
-    .hc-horizontal-menu-item {
-        cursor: pointer;
-        padding: 0 20px;
-        height: 100%;
-        position: relative;
-        display: flex;
-        align-items: center;
-        justify-content: center;
-        font-size: 16px;
-        overflow-y: hidden;
-        transition: color 0.3s;
-        color: inherit;
-        &:before {
-            bottom: 0;
-            opacity: 0;
-            height: 4px;
-            content: "";
-            padding: 0 32px;
-            position: absolute;
-            border-radius: 5px;
-            background: var(--hc-primary);
-            transition: opacity 0.3s;
-        }
-        &:hover {
-            color: var(--hc-primary);
-        }
-        &.cur {
-            font-weight: 500;
-            color: var(--hc-primary);
-            &:before {
-                opacity: 1;
-            }
-        }
+<style lang="scss">
+.hc-aside-menu.el-menu {
+    --el-menu-bg-color: #333333;
+    --el-menu-text-color: #ffffff;
+    --el-menu-active-color: #ffffff;
+    --el-menu-hover-bg-color: initial;
+    --el-menu-item-font-size: 16px;
+    --el-menu-item-height: 48px;
+    border-right: 0;
+    &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item,
+    &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-menu-item-group__title,
+    &.el-menu--vertical:not(.el-menu--collapse):not(.el-menu--popup-container) .el-sub-menu__title {
+        white-space: nowrap;
+        padding-left: 20px;
     }
-}
-
-.home-theme-1, .home-theme-2, .home-theme-3 {
-    .hc-horizontal-menu-box .hc-horizontal-menu-item {
-        &:before {
-            background: white;
+    .el-menu-item, .el-sub-menu {
+        margin: 15px 0 0 20px;
+        border-radius: 50px 0 0 50px;
+        .hc-menu-icon {
+            font-size: 22px;
+            margin-right: 10px;
         }
-        &:hover {
-            color: white;
-            background-color: rgba(255, 255, 255, 0.1);
+    }
+    .el-menu-item.is-active {
+        background-color: var(--el-color-primary);
+        box-shadow: 4px 4px 8px 0 rgba(0, 0, 0, 0.3), 0 -6px 8px 0 #707070;
+        &::before {
+            content: '';
         }
-        &.cur {
-            color: white;
-            background-color: rgba(255, 255, 255, 0.1);
+        &::after {
+            content: '';
         }
     }
 }

+ 49 - 0
src/layout/modules/MenuItem.vue

@@ -0,0 +1,49 @@
+<template>
+    <template v-for="item in datas">
+        <el-sub-menu class="truncate" :index="item.key" v-if="item?.children && item?.children.length > 0">
+            <template #title>
+                <HcIcon :name="item.icon" class="hc-menu-icon" :ui="curKey === item.key?'fill':''" v-if="item?.icon"/>
+                <span>{{item.name}}</span>
+            </template>
+            <MenuItem :datas="item.children" @change="MenuClick"/>
+        </el-sub-menu>
+        <el-menu-item class="truncate" :index="item.key" v-else @click="MenuClick(item)">
+            <HcIcon :name="item.icon" class="hc-menu-icon" :ui="curKey === item.key?'fill':''" v-if="item?.icon"/>
+            <template #title>{{item.name}}</template>
+        </el-menu-item>
+    </template>
+</template>
+
+<script setup>
+import {ref,watch} from "vue";
+import MenuItem from "./MenuItem.vue"
+const props = defineProps({
+    datas: {
+        type: Array,
+        default: () => []
+    },
+    cur: {
+        type: String,
+        default: ''
+    },
+})
+//初始变量
+const curKey = ref(props.cur);
+
+//监听
+watch(() => [
+    props.cur
+], ([cur]) => {
+    curKey.value = cur
+})
+
+//事件
+const emit = defineEmits(['change'])
+const MenuClick = (item) => {
+    emit('change', item)
+}
+</script>
+
+<style lang="scss" scoped>
+
+</style>

+ 0 - 64
src/layout/modules/MenuQuality.vue

@@ -1,64 +0,0 @@
-<template>
-    <div class="menu-bar-quality-box">
-        <n-tabs :default-value="datas[0]?.key" justify-content="space-evenly">
-            <template v-for="item in datas">
-                <n-tab-pane :name="item.key" :tab="item.name">
-                    <MenuQualityItem :datas="item.children" @change="MenuQualityItemChange"/>
-                </n-tab-pane>
-            </template>
-        </n-tabs>
-    </div>
-</template>
-
-<script setup>
-import MenuQualityItem from "./MenuQualityItem.vue"
-defineProps({
-    datas: {
-        type: Array,
-        default: () => ([])
-    }
-})
-
-const emit = defineEmits(['change'])
-const MenuQualityItemChange = (item) => {
-    emit('change', {
-        key:'qualityControl',
-        item
-    })
-}
-</script>
-
-<style lang="scss" scoped>
-.menu-bar-quality-box {
-    position: relative;
-    padding: 12px 5px;
-    width: 468px;
-}
-</style>
-
-<style lang="scss">
-.menu-bar-quality-box {
-    .n-tabs .n-tabs-wrapper .n-tabs-tab {
-        border-radius: 24px;
-        padding: 0 15px;
-        height: 32px;
-    }
-    .n-tabs .n-tabs-bar {
-        display: none;
-    }
-    .n-tabs.n-tabs--line-type .n-tabs-tab.n-tabs-tab--active,
-    .n-tabs.n-tabs--bar-type .n-tabs-tab.n-tabs-tab--active {
-        color: var(--hc-primary);
-        background: var(--hc-primary-light-7);
-    }
-}
-html.theme-dark {
-    .menu-bar-quality-box {
-        .n-tabs.n-tabs--line-type .n-tabs-tab.n-tabs-tab--active,
-        .n-tabs.n-tabs--bar-type .n-tabs-tab.n-tabs-tab--active {
-            color: var(--hc-primary);
-            background: #404041;
-        }
-    }
-}
-</style>

+ 0 - 76
src/layout/modules/MenuQualityItem.vue

@@ -1,76 +0,0 @@
-<template>
-    <div class="quality-content-box">
-        <n-grid x-gap="20" :cols="datas.length">
-            <n-gi v-for='item in datas'>
-                <div class="quality-content-item" @click="MenuClick(item)">
-                    <div class="quality-content">
-                        <div class="quality-icon">
-                            <i :class="item.icon"/>
-                        </div>
-                        <div class="quality-text">{{item.name}}</div>
-                    </div>
-                </div>
-            </n-gi>
-        </n-grid>
-    </div>
-</template>
-
-<script setup>
-defineProps({
-    datas: {
-        type: Array,
-        default: () => []
-    }
-})
-
-const emit = defineEmits(['change'])
-const MenuClick = (item) => {
-    emit('change', item)
-}
-</script>
-
-<style lang="scss" scoped>
-.quality-content-box {
-    position: relative;
-    margin-top: 10px;
-    .quality-content-item {
-        position: relative;
-        background-color: #F9F9F9;
-        border-radius: 10px;
-        cursor: pointer;
-        width: 100%;
-        height: 132px;
-        display: flex;
-        justify-content: center;
-        align-items: center;
-        text-align: center;
-        transition: background-color 0.3s;
-        .quality-content {
-            position: relative;
-            width: 115px;
-            .quality-icon {
-                position: relative;
-                font-size: 52px;
-                margin-top: -12px;
-            }
-            .quality-text {
-                font-size: 12px;
-                line-height: 1.6;
-                color: #707070;
-            }
-        }
-        &:hover {
-            background-color: var(--hc-primary-light-7);
-        }
-    }
-}
-
-html.theme-dark {
-    .quality-content-box .quality-content-item {
-        background-color: #2e2e2e;
-        &:hover {
-            background-color: #404041;
-        }
-    }
-}
-</style>

BIN=BIN
src/styles/font/material-fill.woff2


+ 18 - 0
src/styles/icon/material.scss

@@ -15,3 +15,21 @@
     direction: ltr;
     -webkit-font-smoothing: antialiased;
 }
+
+@font-face {
+    font-family: 'Material Symbols Rounded Fill';
+    font-style: normal;
+    font-weight: 300;
+    src: url(../font/material-fill.woff2) format('woff2');
+}
+
+.material-symbols-rounded[class*='fill'] {
+    font-family: 'Material Symbols Rounded Fill';
+    letter-spacing: normal;
+    text-transform: none;
+    display: inline-block;
+    white-space: nowrap;
+    word-wrap: normal;
+    direction: ltr;
+    -webkit-font-smoothing: antialiased;
+}