1
0
mirror of https://github.com/FatttSnake/Pinnacle-OA.git synced 2026-04-04 22:41:24 +08:00

Added page frame

This commit is contained in:
2023-05-01 22:10:03 +08:00
parent bbc51f21ec
commit ac3b71102c
10 changed files with 401 additions and 12 deletions

View File

@@ -1,7 +1,7 @@
<template>
<router-view></router-view>
<router-view></router-view>
</template>
<script setup lang="ts"></script>
<script lang="ts"></script>
<style scoped></style>

View File

@@ -0,0 +1,104 @@
:root {
--main-color: #00D4FF;
--background-color: #F5F5F5;
--font-main-color: #4D4D4D;
--font-secondary-color: #9E9E9E;
}
body {
color: var(--font-main-color);
user-select: none;
}
.fill {
height: 100%;
width: 100%;
}
.fill-with {
width: 100%;
}
.fill-height {
height: 100%;
}
.background-white {
background-color: white;
}
.center-box {
display: flex;
justify-content: center;
align-items: center;
}
.vertical-center-box {
display: flex;
align-items: center;
}
.horizontal-center-box {
display: flex;
justify-content: center;
}
.icon-size-xs {
width: 16px;
height: 16px;
}
.icon-size-xs > use {
width: 16px;
height: 16px;
}
.icon-size-sm {
width: 20px;
height: 20px;
}
.icon-size-sm > use {
width: 20px;
height: 20px;
}
.icon-size-md {
width: 24px;
height: 24px;
}
.icon-size-md > use {
width: 24px;
height: 24px;
}
.icon-size-lg {
width: 32px;
height: 32px;
}
.icon-size-lg > use {
width: 32px;
height: 32px;
}
.icon-size-xl {
width: 64px;
height: 64px;
}
.icon-size-xl > use {
width: 64px;
height: 64px;
}
.icon-size-menu {
width: 23px;
height: 23px;
}
.icon-size-menu > use {
width: 23px;
height: 23px;
}

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="24" height="24" viewBox="0 0 24 24"><defs><clipPath id="master_svg0_24_0283/24_741"><rect x="0" y="0" width="24" height="24" rx="0"/></clipPath></defs><g style="mix-blend-mode:passthrough" clip-path="url(#master_svg0_24_0283/24_741)"><g><path d="M20.9931,13.2849C22.961,11.8133,24,9.92076,24,7.7996C24,3.49885,19.5873,0,14.1641,0C8.74009,0,4.32732,3.49885,4.32732,7.7996C4.32732,8.99721,4.66991,10.1325,5.28122,11.1474C2.2171,11.9155,0,14.1537,0,16.7931C0,18.5202,0.89816,19.9253,2.40879,21.0084C2.73721,21.7533,2.25195,23.3488,1.62118,24Q3.47438,23.6936,4.55685,22.3125C5.54881,22.6766,6.44948,22.721,7.61657,22.721C11.8258,22.721,15.2348,20.0676,15.2348,16.7931C15.2348,16.3789,15.18,15.9748,15.0763,15.5846C15.941,15.558,16.7762,15.4723,17.651,15.2072C19.1046,16.7528,21.2008,17.1153,21.2954,17.1308L23.2183,17.4484L21.8627,16.0497C21.2837,15.452,20.8364,13.9754,20.9931,13.2849ZM5.17427,17.8573C4.64645,17.8573,4.21831,17.4296,4.21831,16.9022C4.21831,16.3745,4.64645,15.9468,5.17427,15.9468C5.70207,15.9468,6.1302,16.3745,6.1302,16.9022C6.13023,17.4296,5.70207,17.8573,5.17427,17.8573ZM7.70619,17.8573C7.17839,17.8573,6.75023,17.4296,6.75023,16.9022C6.75023,16.3745,7.17837,15.9468,7.70619,15.9468C8.23401,15.9468,8.66215,16.3745,8.66215,16.9022C8.66215,17.4296,8.23401,17.8573,7.70619,17.8573ZM10.2381,17.8573C9.71019,17.8573,9.28218,17.4296,9.28218,16.9022C9.28218,16.3745,9.71031,15.9468,10.2381,15.9468C10.7667,15.9468,11.1949,16.3745,11.1949,16.9022C11.1949,17.4296,10.7667,17.8573,10.2381,17.8573ZM20.0069,15.3457C19.4447,15.0699,18.8307,14.6597,18.3631,14.0642L18.0749,13.6959L17.6352,13.857C16.6796,14.2073,15.8092,14.2958,14.5352,14.3084C13.328,12.275,10.6851,10.8628,7.61659,10.8628C7.29068,10.8628,6.96954,10.8788,6.65437,10.9098C5.99134,9.98511,5.61404,8.92533,5.61404,7.79955C5.61404,4.20781,9.44963,1.28565,14.1639,1.28565C18.8775,1.28565,22.713,4.20781,22.713,7.79955C22.713,9.57371,21.8251,11.1089,20.0739,12.3637L19.9306,12.4662L19.8603,12.6269C19.5478,13.3368,19.6652,14.4011,20.0069,15.3457ZM10.6612,6.69636C9.94573,6.69636,9.3659,7.27603,9.3659,7.99135C9.3659,8.70609,9.94559,9.28582,10.6612,9.28582C11.3775,9.28582,11.9573,8.70612,11.9573,7.99135C11.9573,7.27606,11.3775,6.69636,10.6612,6.69636ZM14.0928,6.69636C13.3774,6.69636,12.7975,7.27603,12.7975,7.99135C12.7975,8.70609,13.3774,9.28582,14.0928,9.28582C14.8091,9.28582,15.3889,8.70612,15.3889,7.99135C15.3889,7.27606,14.8091,6.69636,14.0928,6.69636ZM17.5246,6.69636C16.809,6.69636,16.2292,7.27603,16.2292,7.99135C16.2292,8.70609,16.809,9.28582,17.5246,9.28582C18.2409,9.28582,18.8206,8.70612,18.8206,7.99135C18.8206,7.27606,18.2409,6.69636,17.5246,6.69636Z" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="24" height="24" viewBox="0 0 24 24"><g style="mix-blend-mode:passthrough"><g style="mix-blend-mode:passthrough"><path d="M11.2633,0.229798C11.6966,-0.0765992,12.3034,-0.0765992,12.7367,0.229798C12.7367,0.229798,23.5367,7.86616,23.5367,7.86616C23.829,8.07284,24,8.39063,24,8.72727C24,8.72727,24,20.7273,24,20.7273C24,21.5953,23.6207,22.4277,22.9456,23.0414C22.2704,23.6552,21.3548,24,20.4,24C20.4,24,3.6,24,3.6,24C2.64522,24,1.72955,23.6552,1.05442,23.0414C0.379284,22.4277,0,21.5953,0,20.7273C0,20.7273,0,8.72727,0,8.72727C0,8.39063,0.170968,8.07284,0.463271,7.86616C0.463271,7.86616,11.2633,0.229798,11.2633,0.229798C11.2633,0.229798,11.2633,0.229798,11.2633,0.229798ZM9.6,21.8182C9.6,21.8182,14.4,21.8182,14.4,21.8182C14.4,21.8182,14.4,13.0909,14.4,13.0909C14.4,13.0909,9.6,13.0909,9.6,13.0909C9.6,13.0909,9.6,21.8182,9.6,21.8182C9.6,21.8182,9.6,21.8182,9.6,21.8182ZM16.8,21.8182C16.8,21.8182,16.8,12,16.8,12C16.8,11.3975,16.2628,10.9091,15.6,10.9091C15.6,10.9091,8.4,10.9091,8.4,10.9091C7.73726,10.9091,7.2,11.3975,7.2,12C7.2,12,7.2,21.8182,7.2,21.8182C7.2,21.8182,3.6,21.8182,3.6,21.8182C3.28174,21.8182,2.97652,21.7032,2.75147,21.4987C2.52643,21.2941,2.4,21.0166,2.4,20.7273C2.4,20.7273,2.4,9.26081,2.4,9.26081C2.4,9.26081,12,2.47294,12,2.47294C12,2.47294,21.6,9.26081,21.6,9.26081C21.6,9.26081,21.6,20.7273,21.6,20.7273C21.6,21.0166,21.4735,21.2941,21.2485,21.4987C21.0235,21.7032,20.7182,21.8182,20.4,21.8182C20.4,21.8182,16.8,21.8182,16.8,21.8182C16.8,21.8182,16.8,21.8182,16.8,21.8182Z" fill-rule="evenodd" fill-opacity="1"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1,2 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="30.231319427490234" height="32"
viewBox="0 0 30.231319427490234 32"><g><path d="M29.0453,26.1146C28.2855,24.3136,27.192,22.6975,25.8051,21.3106C24.4182,19.9236,22.8021,18.8342,21.0011,18.0704C20.985,18.0623,20.9689,18.0583,20.9528,18.0503C23.4574,16.2412,25.0855,13.2945,25.0855,9.96985C25.0855,4.46231,20.6232,0,15.1157,0C9.60812,0,5.14581,4.46231,5.14581,9.96985C5.14581,13.2945,6.77395,16.2412,9.27847,18.0543C9.26239,18.0623,9.24631,18.0663,9.23023,18.0744C7.42923,18.8342,5.81315,19.9236,4.42621,21.3146C3.03928,22.7015,1.94983,24.3176,1.18601,26.1186C0.438272,27.8794,0.0402826,29.7487,0.0000815847,31.6704C-0.00393876,31.8513,0.140785,32,0.32169,32L2.73375,32C2.91063,32,3.05134,31.8593,3.05536,31.6864C3.13576,28.5829,4.38199,25.6764,6.58501,23.4734C8.8644,21.194,11.8915,19.9397,15.1157,19.9397C18.3398,19.9397,21.3669,21.194,23.6463,23.4734C25.8493,25.6764,27.0956,28.5829,27.176,31.6864C27.18,31.8633,27.3207,32,27.4976,32L29.9096,32C30.0905,32,30.2353,31.8513,30.2312,31.6704C30.191,29.7487,29.793,27.8794,29.0453,26.1146ZM15.1157,16.8844C13.2704,16.8844,11.5338,16.1648,10.2272,14.8583C8.92068,13.5518,8.20109,11.8151,8.20109,9.96985C8.20109,8.12462,8.92068,6.38794,10.2272,5.08141C11.5338,3.77487,13.2704,3.05528,15.1157,3.05528C16.9609,3.05528,18.6976,3.77487,20.0041,5.08141C21.3106,6.38794,22.0302,8.12462,22.0302,9.96985C22.0302,11.8151,21.3106,13.5518,20.0041,14.8583C18.6976,16.1648,16.9609,16.8844,15.1157,16.8844Z" fill-opacity="1"/></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -2,10 +2,10 @@ import { createApp } from 'vue'
import App from '@/App.vue'
import router from '@/router'
import { PRODUCTION_NAME } from './constants/Common.constants.js'
import '@/assets/css/base.css'
import '@/assets/css/common.css'
/*
router.beforeEach((to, from, next) => {
if (to.matched.length === 0) {
from.path ? next({ path: from.path }) : next('/')
@@ -15,6 +15,7 @@ router.beforeEach((to, from, next) => {
}
}
})
*/
const app = createApp(App)

View File

@@ -1,9 +1,256 @@
<template><div></div></template>
<template>
<el-backtop target=".main-box" :right="80" :bottom="80" />
<div class="background">
<el-container class="fill">
<el-aside width="collapse" class="background-white aside">
<el-scrollbar>
<el-menu
:collapse="isCollapsed"
:unique-opened="true"
:default-active="$route.path"
:router="true"
class="menu"
:text-color="COLOR_FONT_MAIN()"
:active-text-color="COLOR_PRODUCTION()"
>
<el-menu-item
@mousedown.left="isCollapsed = !isCollapsed"
:disabled="true"
style="cursor: pointer; opacity: 1; border-bottom: 1px #ddd solid"
>
<el-icon :size="SIZE_ICON_LG()">
<icon-pinnacle-pinnacle :color="COLOR_PRODUCTION()" />
</el-icon>
<template #title>
<span class="menu-production-name">
{{ PRODUCTION_NAME() }}
</span>
</template>
</el-menu-item>
<template v-for="(route, index) in routes">
<el-menu-item
v-if="!route.children"
:key="index"
:index="route.path ?? ''"
>
<el-icon>
<component :is="route.meta.icon" />
</el-icon>
<template #title>{{ route.meta.title }}</template>
</el-menu-item>
<el-sub-menu
v-if="route.children"
:key="index"
:index="route.path ?? ''"
>
<template #title>
<el-icon>
<component :is="route.meta.icon" />
</el-icon>
<span>{{ route.meta.title }}</span>
</template>
<el-menu-item
v-for="(sub, index) in route.children"
:key="index"
:index="sub.path ?? ''"
>
<el-icon>
<component :is="sub.meta.icon" />
</el-icon>
<template #title>{{ sub.meta.title }}</template>
</el-menu-item>
</el-sub-menu>
</template>
</el-menu>
</el-scrollbar>
</el-aside>
<el-container>
<el-header height="56px" class="background-white main-header">
<el-badge is-dot>
<el-icon
:size="SIZE_ICON_MD()"
:color="COLOR_PRODUCTION()"
style="cursor: pointer"
>
<icon-pinnacle-chat />
</el-icon>
</el-badge>
<el-badge is-dot>
<el-icon
:size="SIZE_ICON_MD()"
:color="COLOR_PRODUCTION()"
style="cursor: pointer"
>
<icon-pinnacle-notice />
</el-icon>
</el-badge>
<el-divider direction="vertical" />
<el-popover
transition="el-zoom-in-top"
popper-style="box-shadow: rgb(14 18 22 / 20%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px;"
>
<template #reference>
<div style="display: flex">
<div class="user-head">
<el-avatar>
<el-icon :size="SIZE_ICON_SM()" :color="COLOR_FONT_MAIN()">
<icon-pinnacle-user />
</el-icon>
</el-avatar>
</div>
<div class="user-info">
<div class="user-name">
<span>用户名</span>
</div>
<div class="user-desc">
<span>用户介绍</span>
</div>
</div>
</div>
</template>
<template #default>
<div style="display: flex; gap: 10px; flex-direction: column">
<div>
<el-button style="width: 100%">个人档案</el-button>
</div>
<div>
<el-button style="width: 100%">退出</el-button>
</div>
</div>
</template>
</el-popover>
</el-header>
<ElScrollbar v-if="$route.meta.requiresScrollbar">
<ElMain class="main-box" :class="{ noPadding: !$route.meta.requiresPadding }">
<ElBacktop :right="100" :bottom="100" />
<RouterView></RouterView>
</ElMain>
</ElScrollbar>
<ElMain
v-else
class="main-box"
:class="{ noPadding: !$route.meta.requiresPadding }"
>
<ElBacktop :right="100" :bottom="100" />
<RouterView></RouterView>
</ElMain>
</el-container>
</el-container>
</div>
</template>
<script lang="ts">
import {
COLOR_FONT_MAIN,
COLOR_PRODUCTION,
PRODUCTION_NAME,
SIZE_ICON_LG,
SIZE_ICON_MD,
SIZE_ICON_SM
} from '@/constants/Common.constants.js'
import _ from 'lodash'
<script>
export default {
name: 'MainPage'
name: 'MainFrame',
methods: {
SIZE_ICON_LG() {
return SIZE_ICON_LG
},
PRODUCTION_NAME() {
return PRODUCTION_NAME
},
SIZE_ICON_SM() {
return SIZE_ICON_SM
},
SIZE_ICON_MD() {
return SIZE_ICON_MD
},
COLOR_PRODUCTION() {
return COLOR_PRODUCTION
},
COLOR_FONT_MAIN() {
return COLOR_FONT_MAIN
}
},
data() {
return {
routes: _.filter(_.get(this.$router, 'options.routes[0].children'), 'meta.title'),
isCollapsed: false
}
},
mounted() {
console.log(this.routes)
}
}
</script>
<style scoped></style>
<style scoped>
.background {
width: 100vw;
min-width: 900px;
height: 100vh;
min-height: 500px;
background: var(--background-color);
}
.aside {
border-right: 1px #ddd solid;
box-shadow: 0 0 1em #ddd;
}
.menu:not(.el-menu--collapse) {
width: 245px;
}
.menu-top > * {
padding: 0;
}
.menu-production-name {
width: 100%;
padding: 0 10px;
font-size: 1.2em;
color: var(--main-color);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.main-header {
display: flex;
align-items: center;
justify-content: right;
border-bottom: 1px #ddd solid;
box-shadow: 0 0 1em #ddd;
}
.main-header > *:not(:last-child) {
margin-right: 15px;
}
.user-head {
display: inline-block;
}
.user-head > span {
font-size: 0.8em;
}
.user-info {
margin-left: 10px;
}
.user-name {
color: var(--main-color);
font-size: 1.2em;
font-weight: bold;
}
.user-desc {
color: var(--font-secondary-color);
}
.noPadding {
padding: 0;
}
</style>

View File

@@ -0,0 +1,9 @@
<template><div>Home</div></template>
<script>
export default {
name: 'HomePage'
}
</script>
<style scoped></style>

View File

@@ -2,7 +2,29 @@ import { createRouter, createWebHistory } from 'vue-router'
const router = createRouter({
history: createWebHistory(import.meta.env.BASE_URL),
routes: []
routes: [
{
path: '/',
component: async () => await import('@/pages/Main.vue'),
children: [
{
path: '',
redirect: 'home'
},
{
path: '/home',
component: async () => await import('@/pages/home/Home.vue'),
name: 'home',
meta: {
title: '首页',
icon: IconPinnacleHome,
requiresScrollbar: false,
requiresPadding: true
}
}
]
}
]
})
export default router

View File

@@ -1,7 +1,9 @@
// eslint-disable-next-line @typescript-eslint/triple-slash-reference
/// <reference types="vite/client" />
declare module '*.vue' {
import type { DefineComponent } from 'vue'
const component: DefineComponent<{}, {}, any>
export default component
import type { DefineComponent } from 'vue'
// eslint-disable-next-line @typescript-eslint/ban-types
const component: DefineComponent<{}, {}, any>
export default component
}