界面调整
This commit is contained in:
parent
6f6fd11d58
commit
c402939b3a
@ -1 +1 @@
|
|||||||
Subproject commit 9218ddcf90a543ca84c7240480a12dd08ceb2b1d
|
Subproject commit 5cb82e750f4f4e6d9523ab9a8a24a4148d12950a
|
93
src/components/SysMenu.vue
Normal file
93
src/components/SysMenu.vue
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<template>
|
||||||
|
<q-list bordered separator>
|
||||||
|
<div v-for="(menu, ii) in list" :key="ii">
|
||||||
|
<div v-if="menu.children">
|
||||||
|
<q-expansion-item :icon="menu.icon" :label="menu.label">
|
||||||
|
<q-card>
|
||||||
|
<q-list bordered separator>
|
||||||
|
<div v-for="(item, index) in menu.children" :key="index">
|
||||||
|
<q-item
|
||||||
|
clickable
|
||||||
|
:to="menu.path + '/' + item.path"
|
||||||
|
exact
|
||||||
|
:inset-level="1"
|
||||||
|
>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon :name="item.icon"></q-icon>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>{{ item.label }}</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</div>
|
||||||
|
</q-list>
|
||||||
|
</q-card>
|
||||||
|
</q-expansion-item>
|
||||||
|
</div>
|
||||||
|
<div v-else>
|
||||||
|
<q-item clickable :to="menu.path" exact>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-icon :name="menu.icon"></q-icon>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>{{ menu.label }}</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</q-list>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { onMounted, ref } from 'vue';
|
||||||
|
import { RouteRecordRaw } from 'vue-router';
|
||||||
|
import routes from 'src/router/routes';
|
||||||
|
|
||||||
|
interface IMenu {
|
||||||
|
path: string;
|
||||||
|
label: string;
|
||||||
|
icon: string;
|
||||||
|
children?: IMenu[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const list = ref<IMenu[]>([]);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
getList();
|
||||||
|
});
|
||||||
|
|
||||||
|
function getList() {
|
||||||
|
const arr: IMenu[] = [];
|
||||||
|
function getPathItem(item: RouteRecordRaw): IMenu | boolean {
|
||||||
|
if (item.meta?.hidden) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
const obj: IMenu = {
|
||||||
|
path: item.path,
|
||||||
|
label: (item.meta?.label as string) || '',
|
||||||
|
icon: (item.meta?.icon as string) || '',
|
||||||
|
};
|
||||||
|
if (item.children) {
|
||||||
|
const child: IMenu[] = [];
|
||||||
|
item.children.forEach((ii) => {
|
||||||
|
const childItem = getPathItem(ii);
|
||||||
|
if (childItem) {
|
||||||
|
child.push(childItem as IMenu);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (child.length) {
|
||||||
|
Object.assign(obj, { children: child });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
routes.forEach((item) => {
|
||||||
|
const pItem = getPathItem(item);
|
||||||
|
if (pItem) {
|
||||||
|
arr.push(pItem as IMenu);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
list.value = arr;
|
||||||
|
}
|
||||||
|
</script>
|
21
src/configs/TokenManage.ts
Normal file
21
src/configs/TokenManage.ts
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
const JwtTokenKey = 'jwttoken';
|
||||||
|
|
||||||
|
export function saveJwtToken(token: string) {
|
||||||
|
sessionStorage.setItem(JwtTokenKey, `Bearer ${token}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getJwtToken(): string | null {
|
||||||
|
return sessionStorage.getItem(JwtTokenKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function clearJwtToken(): void {
|
||||||
|
sessionStorage.removeItem(JwtTokenKey);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getOnlyToken(): string | null {
|
||||||
|
// 去除token前的Bearer
|
||||||
|
let t = sessionStorage.getItem(JwtTokenKey);
|
||||||
|
const Rxg = /^Bearer /;
|
||||||
|
t = t ? t.replace(Rxg, '') : '';
|
||||||
|
return t;
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<q-layout view="lHh Lpr lFf">
|
<q-layout view="hHh Lpr lFf">
|
||||||
<q-header elevated>
|
<q-header elevated>
|
||||||
|
<q-resize-observer @resize="onHeaderResize" />
|
||||||
<q-toolbar>
|
<q-toolbar>
|
||||||
<q-btn
|
<q-btn
|
||||||
flat
|
flat
|
||||||
@ -11,87 +12,173 @@
|
|||||||
@click="toggleLeftDrawer"
|
@click="toggleLeftDrawer"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<q-toolbar-title> Quasar App </q-toolbar-title>
|
<q-toolbar-title> 北京玖琏 </q-toolbar-title>
|
||||||
|
|
||||||
<div>Quasar v{{ $q.version }}</div>
|
<div class="q-gutter-sm no-wrap">
|
||||||
|
<q-btn
|
||||||
|
round
|
||||||
|
dense
|
||||||
|
flat
|
||||||
|
color="white"
|
||||||
|
:icon="$q.fullscreen.isActive ? 'fullscreen_exit' : 'fullscreen'"
|
||||||
|
@click="$q.fullscreen.toggle()"
|
||||||
|
v-if="$q.screen.gt.sm"
|
||||||
|
>
|
||||||
|
</q-btn>
|
||||||
|
<q-btn-dropdown flat stretch icon="person">
|
||||||
|
<q-list>
|
||||||
|
<q-item clickable v-close-popup @click="showUserInfo">
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>用户信息</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
|
||||||
|
<q-item clickable v-close-popup @click="logOut">
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label>登出</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-btn-dropdown>
|
||||||
|
</div>
|
||||||
</q-toolbar>
|
</q-toolbar>
|
||||||
</q-header>
|
</q-header>
|
||||||
|
|
||||||
<q-drawer v-model="leftDrawerOpen" show-if-above bordered>
|
<q-drawer v-model="leftDrawerOpen" show-if-above bordered>
|
||||||
<q-list>
|
<q-resize-observer @resize="onLeftResize" />
|
||||||
<q-item-label header> Essential Links </q-item-label>
|
<sys-menu></sys-menu>
|
||||||
|
|
||||||
<EssentialLink
|
|
||||||
v-for="link in linksList"
|
|
||||||
:key="link.title"
|
|
||||||
v-bind="link"
|
|
||||||
/>
|
|
||||||
</q-list>
|
|
||||||
</q-drawer>
|
</q-drawer>
|
||||||
|
|
||||||
<q-page-container>
|
<q-page-container>
|
||||||
<router-view />
|
<q-resize-observer @resize="onResize" />
|
||||||
|
<q-scroll-area :style="{ height: scrollHeight + 'px' }">
|
||||||
|
<router-view :sizeHeight="scrollHeight" :sizeWidth="scrollWidth" />
|
||||||
|
</q-scroll-area>
|
||||||
</q-page-container>
|
</q-page-container>
|
||||||
|
<q-dialog v-model="showInfo">
|
||||||
|
<q-card style="width: 400px; max-width: 80vw">
|
||||||
|
<q-card-section>
|
||||||
|
<div class="text-h6">用户信息</div>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-section class="q-pt-none">
|
||||||
|
<q-list>
|
||||||
|
<q-item>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label caption>ID:</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-item-label>{{ userInfo?.id }}</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label caption>用户名:</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-item-label>{{ userInfo?.name }}</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label caption>角色:</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label avatar style="text-align: right">
|
||||||
|
{{ getRoleName(userInfo?.roles) }}
|
||||||
|
</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label caption>电话:</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-item-label>{{ userInfo?.mobile }}</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
<q-item>
|
||||||
|
<q-item-section>
|
||||||
|
<q-item-label caption>注册时间:</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
<q-item-section avatar>
|
||||||
|
<q-item-label>{{ userInfo?.register_time }}</q-item-label>
|
||||||
|
</q-item-section>
|
||||||
|
</q-item>
|
||||||
|
</q-list>
|
||||||
|
</q-card-section>
|
||||||
|
|
||||||
|
<q-card-actions align="right">
|
||||||
|
<q-btn flat label="确定" color="primary" @click="closeShowInfo" />
|
||||||
|
</q-card-actions>
|
||||||
|
</q-card>
|
||||||
|
</q-dialog>
|
||||||
</q-layout>
|
</q-layout>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from 'vue';
|
import { ref, reactive } from 'vue';
|
||||||
import EssentialLink, {
|
import SysMenu from 'src/components/SysMenu.vue';
|
||||||
EssentialLinkProps,
|
// import { useRouter } from 'vue-router';
|
||||||
} from 'components/EssentialLink.vue';
|
import { clearJwtToken } from 'src/configs/TokenManage';
|
||||||
|
import { Dialog } from 'quasar';
|
||||||
|
|
||||||
defineOptions({
|
// const router = useRouter();
|
||||||
name: 'MainLayout',
|
|
||||||
});
|
|
||||||
const linksList: EssentialLinkProps[] = [
|
|
||||||
{
|
|
||||||
title: 'Docs',
|
|
||||||
caption: 'quasar.dev',
|
|
||||||
icon: 'school',
|
|
||||||
link: 'https://quasar.dev',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Github',
|
|
||||||
caption: 'github.com/quasarframework',
|
|
||||||
icon: 'code',
|
|
||||||
link: 'https://github.com/quasarframework',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Discord Chat Channel',
|
|
||||||
caption: 'chat.quasar.dev',
|
|
||||||
icon: 'chat',
|
|
||||||
link: 'https://chat.quasar.dev',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Forum',
|
|
||||||
caption: 'forum.quasar.dev',
|
|
||||||
icon: 'record_voice_over',
|
|
||||||
link: 'https://forum.quasar.dev',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Twitter',
|
|
||||||
caption: '@quasarframework',
|
|
||||||
icon: 'rss_feed',
|
|
||||||
link: 'https://twitter.quasar.dev',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Facebook',
|
|
||||||
caption: '@QuasarFramework',
|
|
||||||
icon: 'public',
|
|
||||||
link: 'https://facebook.quasar.dev',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Quasar Awesome',
|
|
||||||
caption: 'Community Quasar projects',
|
|
||||||
icon: 'favorite',
|
|
||||||
link: 'https://awesome.quasar.dev',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const leftDrawerOpen = ref(false);
|
const leftDrawerOpen = ref(false);
|
||||||
|
|
||||||
function toggleLeftDrawer() {
|
function toggleLeftDrawer() {
|
||||||
leftDrawerOpen.value = !leftDrawerOpen.value;
|
leftDrawerOpen.value = !leftDrawerOpen.value;
|
||||||
|
onResize();
|
||||||
|
}
|
||||||
|
const scrollHeight = ref(100);
|
||||||
|
const scrollWidth = ref(100);
|
||||||
|
function onResize() {
|
||||||
|
scrollHeight.value = window.innerHeight - headerSize.height;
|
||||||
|
scrollWidth.value =
|
||||||
|
window.innerWidth - (leftDrawerOpen.value ? leftDrawerSize.width : 0);
|
||||||
|
}
|
||||||
|
const headerSize = reactive({} as { width: number; height: number });
|
||||||
|
function onHeaderResize(size: { width: number; height: number }) {
|
||||||
|
headerSize.width = size.width;
|
||||||
|
headerSize.height = size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
const leftDrawerSize = reactive({} as { width: number; height: number });
|
||||||
|
function onLeftResize(size: { width: number; height: number }) {
|
||||||
|
leftDrawerSize.width = size.width;
|
||||||
|
leftDrawerSize.height = size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
const showInfo = ref(false);
|
||||||
|
const userInfo = null;
|
||||||
|
function showUserInfo() {
|
||||||
|
showInfo.value = true;
|
||||||
|
}
|
||||||
|
function closeShowInfo() {
|
||||||
|
showInfo.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function logOut() {
|
||||||
|
Dialog.create({
|
||||||
|
title: '登出确认',
|
||||||
|
message: '确认是否登出?',
|
||||||
|
cancel: true,
|
||||||
|
persistent: true,
|
||||||
|
}).onOk(() => {
|
||||||
|
clearJwtToken();
|
||||||
|
// router.push({ name: 'login' });
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function getRoleName(list: { id: number; name: string }[] | undefined) {
|
||||||
|
let name = '';
|
||||||
|
if (list && list.length > 0) {
|
||||||
|
const arr = list.map((item) => {
|
||||||
|
return item.name;
|
||||||
|
});
|
||||||
|
name = arr.join(',');
|
||||||
|
}
|
||||||
|
return name;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -3,7 +3,17 @@ import { RouteRecordRaw } from 'vue-router';
|
|||||||
const routes: RouteRecordRaw[] = [
|
const routes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: '/',
|
path: '/',
|
||||||
component: () => import('layouts/DrawLayout.vue'),
|
redirect: '/home',
|
||||||
|
meta: {
|
||||||
|
hidden: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/home',
|
||||||
|
component: () => import('layouts/MainLayout.vue'),
|
||||||
|
meta: {
|
||||||
|
hidden: true,
|
||||||
|
},
|
||||||
// children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
|
// children: [{ path: '', component: () => import('pages/IndexPage.vue') }],
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -11,11 +21,17 @@ const routes: RouteRecordRaw[] = [
|
|||||||
// but you can also remove it
|
// but you can also remove it
|
||||||
{
|
{
|
||||||
path: '/:catchAll(.*)*',
|
path: '/:catchAll(.*)*',
|
||||||
|
meta: {
|
||||||
|
hidden: true,
|
||||||
|
},
|
||||||
component: () => import('pages/ErrorNotFound.vue'),
|
component: () => import('pages/ErrorNotFound.vue'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/cctvPainting',
|
path: '/cctvPainting',
|
||||||
name: 'cctvPainting',
|
name: 'cctvPainting',
|
||||||
|
meta: {
|
||||||
|
label: 'CCTV绘制',
|
||||||
|
},
|
||||||
component: () => import('layouts/CCTVDrawLayout.vue'),
|
component: () => import('layouts/CCTVDrawLayout.vue'),
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
Loading…
Reference in New Issue
Block a user