feat: 顶部右侧内容移除冗余代码,封装为组件
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
|||||||
clearMenuItem,
|
clearMenuItem,
|
||||||
MenuDataItem,
|
MenuDataItem,
|
||||||
} from 'antdv-pro-layout';
|
} from 'antdv-pro-layout';
|
||||||
import RightContent from './components/RightContent.vue';
|
import HeaderContentRight from './components/HeaderContentRight/HeaderContentRight.vue';
|
||||||
import Tabs from './components/Tabs.vue';
|
import Tabs from './components/Tabs.vue';
|
||||||
import GlobalMask from '@/components/GlobalMask/index.vue';
|
import GlobalMask from '@/components/GlobalMask/index.vue';
|
||||||
import ForcePasswdChange from '@/components/ForcePasswdChange/index.vue';
|
import ForcePasswdChange from '@/components/ForcePasswdChange/index.vue';
|
||||||
@@ -68,19 +68,6 @@ watch(
|
|||||||
);
|
);
|
||||||
|
|
||||||
// 动态路由添加到菜单面板
|
// 动态路由添加到菜单面板
|
||||||
// const rootRoute = router.getRoutes().find(r => r.name === 'Root');
|
|
||||||
// if (rootRoute) {
|
|
||||||
// const children = routerStore.setRootRouterData(rootRoute.children);
|
|
||||||
// const buildRouterData = routerStore.buildRouterData;
|
|
||||||
// if (buildRouterData.length > 0) {
|
|
||||||
// rootRoute.children = children.concat(buildRouterData);
|
|
||||||
// } else {
|
|
||||||
// rootRoute.children = children;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const { menuData } = getMenuData(clearMenuItem(router.getRoutes()));
|
|
||||||
//
|
|
||||||
const menuData = computed(() => {
|
const menuData = computed(() => {
|
||||||
const rootRoute = router.getRoutes().find(r => r.name === 'Root');
|
const rootRoute = router.getRoutes().find(r => r.name === 'Root');
|
||||||
if (rootRoute) {
|
if (rootRoute) {
|
||||||
@@ -151,10 +138,13 @@ tabsStore.clear();
|
|||||||
|
|
||||||
// LOGO地址
|
// LOGO地址
|
||||||
const logoUrl = computed(() => {
|
const logoUrl = computed(() => {
|
||||||
let url =
|
let url = parseUrlPath(appStore.filePathIcon);
|
||||||
appStore.logoType === 'brand'
|
if (appStore.logoType === 'brand') {
|
||||||
? parseUrlPath(appStore.filePathBrand)
|
url = parseUrlPath(appStore.filePathBrand);
|
||||||
: parseUrlPath(appStore.filePathIcon);
|
}
|
||||||
|
if (layoutState.collapsed) {
|
||||||
|
url = parseUrlPath(appStore.filePathIcon);
|
||||||
|
}
|
||||||
|
|
||||||
if (url.indexOf('{language}') === -1) {
|
if (url.indexOf('{language}') === -1) {
|
||||||
return url;
|
return url;
|
||||||
@@ -294,13 +284,17 @@ onUnmounted(() => {
|
|||||||
:alt="appStore.appName"
|
:alt="appStore.appName"
|
||||||
:title="appStore.appName"
|
:title="appStore.appName"
|
||||||
/>
|
/>
|
||||||
<h1 class="app-name" :title="appStore.appName">
|
<h1
|
||||||
|
class="app-name"
|
||||||
|
:title="appStore.appName"
|
||||||
|
v-show="!layoutState.collapsed"
|
||||||
|
>
|
||||||
<span class="marquee app-name_scrollable">
|
<span class="marquee app-name_scrollable">
|
||||||
{{ appStore.appName }}
|
{{ appStore.appName }}
|
||||||
</span>
|
</span>
|
||||||
</h1>
|
</h1>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="appStore.logoType === 'brand'">
|
<template v-else-if="appStore.logoType === 'brand'">
|
||||||
<img
|
<img
|
||||||
class="logo-brand"
|
class="logo-brand"
|
||||||
:src="logoUrl"
|
:src="logoUrl"
|
||||||
@@ -316,7 +310,7 @@ onUnmounted(() => {
|
|||||||
|
|
||||||
<!--插槽-渲染顶部内容右端区域-->
|
<!--插槽-渲染顶部内容右端区域-->
|
||||||
<template #headerContentRightRender>
|
<template #headerContentRightRender>
|
||||||
<RightContent />
|
<HeaderContentRight />
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<!--插槽-导航标签项-->
|
<!--插槽-导航标签项-->
|
||||||
|
|||||||
124
src/layouts/components/HeaderContentRight/HeaderContentRight.vue
Normal file
124
src/layouts/components/HeaderContentRight/HeaderContentRight.vue
Normal file
@@ -0,0 +1,124 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import svgLight from '@/assets/svg/light.svg';
|
||||||
|
import svgDark from '@/assets/svg/dark.svg';
|
||||||
|
import { viewTransitionTheme } from 'antdv-pro-layout';
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { useFullscreen } from '@vueuse/core';
|
||||||
|
import { hasPermissions } from '@/plugins/auth-user';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import useLayoutStore from '@/store/modules/layout';
|
||||||
|
import useAppStore from '@/store/modules/app';
|
||||||
|
import useAlarmStore from '@/store/modules/alarm';
|
||||||
|
import LockScreen from './components/LockScreen.vue';
|
||||||
|
import UserProfile from './components/UserProfile.vue';
|
||||||
|
import NetCoreSelect from './components/NetCoreSelect.vue';
|
||||||
|
const { isFullscreen, toggle } = useFullscreen();
|
||||||
|
const { t, changeLocale, optionsLocale, currentLocale } = useI18n();
|
||||||
|
const layoutStore = useLayoutStore();
|
||||||
|
const appStore = useAppStore();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
/**告警数按钮提示跳转 */
|
||||||
|
function fnClickAlarm() {
|
||||||
|
router.push({ name: 'ActiveAlarm_2088' });
|
||||||
|
}
|
||||||
|
|
||||||
|
/**改变主题色 */
|
||||||
|
function fnClickTheme(e: any) {
|
||||||
|
viewTransitionTheme(isDarkMode => {
|
||||||
|
layoutStore.changeConf('theme', isDarkMode ? 'light' : 'dark');
|
||||||
|
}, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**改变多语言 */
|
||||||
|
function fnChangeLocale(e: any) {
|
||||||
|
changeLocale(e.key);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-space :size="12" align="center">
|
||||||
|
<!-- 切换核心网 -->
|
||||||
|
<NetCoreSelect></NetCoreSelect>
|
||||||
|
|
||||||
|
<!-- 告警气泡 -->
|
||||||
|
<a-tooltip placement="bottomRight">
|
||||||
|
<template #title>{{ t('loayouts.rightContent.alarm') }}</template>
|
||||||
|
<a-button type="text" style="color: inherit" @click="fnClickAlarm">
|
||||||
|
<template #icon>
|
||||||
|
<a-badge
|
||||||
|
:count="useAlarmStore().activeAlarmTotal"
|
||||||
|
:overflow-count="99"
|
||||||
|
status="warning"
|
||||||
|
style="color: inherit"
|
||||||
|
>
|
||||||
|
<BellOutlined />
|
||||||
|
</a-badge>
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
|
||||||
|
<!-- 锁屏操作 -->
|
||||||
|
<LockScreen></LockScreen>
|
||||||
|
|
||||||
|
<!-- 全屏操作 -->
|
||||||
|
<a-tooltip placement="bottomRight">
|
||||||
|
<template #title>{{ t('loayouts.rightContent.fullscreen') }}</template>
|
||||||
|
<a-button type="text" style="color: inherit" @click="toggle">
|
||||||
|
<template #icon>
|
||||||
|
<FullscreenExitOutlined v-if="isFullscreen" />
|
||||||
|
<FullscreenOutlined v-else />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
|
||||||
|
<!-- 明暗主题操作 -->
|
||||||
|
<a-tooltip placement="bottomRight">
|
||||||
|
<template #title>{{ t('loayouts.rightContent.theme') }}</template>
|
||||||
|
<a-button type="text" @click="fnClickTheme">
|
||||||
|
<template #icon>
|
||||||
|
<img
|
||||||
|
v-if="layoutStore.proConfig.theme === 'dark'"
|
||||||
|
:src="svgDark"
|
||||||
|
class="theme-icon"
|
||||||
|
/>
|
||||||
|
<img v-else :src="svgLight" class="theme-icon" />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
</a-tooltip>
|
||||||
|
|
||||||
|
<!-- 多语言操作 -->
|
||||||
|
<a-dropdown
|
||||||
|
placement="bottomRight"
|
||||||
|
trigger="click"
|
||||||
|
v-if="appStore.i18nOpen && hasPermissions(['system:setting:i18n'])"
|
||||||
|
>
|
||||||
|
<a-button type="text" style="color: inherit">
|
||||||
|
<template #icon> <TranslationOutlined /> </template>
|
||||||
|
</a-button>
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu @click="fnChangeLocale">
|
||||||
|
<a-menu-item
|
||||||
|
v-for="opt in optionsLocale"
|
||||||
|
:key="opt.value"
|
||||||
|
:disabled="opt.value == currentLocale"
|
||||||
|
>
|
||||||
|
{{ opt.label }}
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
|
||||||
|
<!-- 用户信息操作 -->
|
||||||
|
<UserProfile></UserProfile>
|
||||||
|
</a-space>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
.theme-icon {
|
||||||
|
width: 18px;
|
||||||
|
height: 18px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
color: inherit;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
|
import { ProModal } from 'antdv-pro-modal';
|
||||||
|
import useMaskStore from '@/store/modules/mask';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
const maskStore = useMaskStore();
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
/**锁屏确认 */
|
||||||
|
const lockConfirm = ref<boolean>(false);
|
||||||
|
/**锁屏密码 */
|
||||||
|
const lockPasswd = ref<string>('');
|
||||||
|
|
||||||
|
/**锁屏按钮提示 */
|
||||||
|
function fnClickLock() {
|
||||||
|
lockConfirm.value = true;
|
||||||
|
lockPasswd.value = '';
|
||||||
|
maskStore.lockPasswd = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
/**锁屏确认跳转锁屏页面 */
|
||||||
|
function fnClickLockToPage() {
|
||||||
|
lockConfirm.value = false;
|
||||||
|
maskStore.lockPasswd = lockPasswd.value;
|
||||||
|
maskStore.handleMaskType('lock');
|
||||||
|
router.push({ name: 'LockScreen', query: { redirect: route.path } });
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<span v-perms:has="['system:setting:lock']">
|
||||||
|
<a-tooltip placement="bottomRight">
|
||||||
|
<template #title>{{ t('loayouts.rightContent.lock') }}</template>
|
||||||
|
<a-button type="text" style="color: inherit" @click="fnClickLock()">
|
||||||
|
<template #icon>
|
||||||
|
<LockOutlined />
|
||||||
|
</template>
|
||||||
|
</a-button>
|
||||||
|
<ProModal
|
||||||
|
:drag="true"
|
||||||
|
:center-y="true"
|
||||||
|
:width="400"
|
||||||
|
:minHeight="200"
|
||||||
|
:mask-closable="false"
|
||||||
|
v-model:open="lockConfirm"
|
||||||
|
:title="t('loayouts.rightContent.lockTip')"
|
||||||
|
@ok="fnClickLockToPage()"
|
||||||
|
>
|
||||||
|
<a-space>
|
||||||
|
{{ t('loayouts.rightContent.lockPasswd') }}:
|
||||||
|
<a-input-password
|
||||||
|
v-model:value="lockPasswd"
|
||||||
|
:placeholder="t('common.inputPlease')"
|
||||||
|
>
|
||||||
|
<template #prefix>
|
||||||
|
<a-tooltip
|
||||||
|
:title="t('loayouts.rightContent.lockPasswdTip')"
|
||||||
|
placement="topLeft"
|
||||||
|
>
|
||||||
|
<UnlockOutlined />
|
||||||
|
</a-tooltip>
|
||||||
|
</template>
|
||||||
|
</a-input-password>
|
||||||
|
</a-space>
|
||||||
|
</ProModal>
|
||||||
|
</a-tooltip>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
|
||||||
|
import useCoreStore from '@/store/modules/core';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
import { handleError, ref } from 'vue';
|
||||||
|
const coreStore = useCoreStore();
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const coreValue = ref(coreStore.current);
|
||||||
|
const coreName = ref();
|
||||||
|
|
||||||
|
function handleSearch(v: string) {
|
||||||
|
coreValue.value = v;
|
||||||
|
coreStore.setCurrent(v);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-select
|
||||||
|
v-model:value="coreValue"
|
||||||
|
:options="coreStore.getCoreOptions"
|
||||||
|
style="width: 200px"
|
||||||
|
>
|
||||||
|
<template #option="{ value, label }">
|
||||||
|
<span>{{ label }} - {{ value }}</span>
|
||||||
|
</template>
|
||||||
|
<template #dropdownRender="{ menuNode: menu }">
|
||||||
|
<div style="display: flex; justify-content: space-between">
|
||||||
|
<span style="color: currentColor; font-weight: 700">Core</span>
|
||||||
|
<a-button type="text" size="small" @click="handleSearch('Global')">
|
||||||
|
<template #icon> <HomeOutlined /> </template>
|
||||||
|
Global
|
||||||
|
</a-button>
|
||||||
|
</div>
|
||||||
|
<a-input-search
|
||||||
|
v-model:value="coreName"
|
||||||
|
placeholder="Search Core Name"
|
||||||
|
style="width: 100%; margin: 4px 0"
|
||||||
|
enter-button
|
||||||
|
@search="handleSearch"
|
||||||
|
/>
|
||||||
|
<a-divider style="margin: 4px 0" />
|
||||||
|
<component :is="menu" />
|
||||||
|
</template>
|
||||||
|
</a-select>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
<script lang="ts" setup>
|
||||||
|
import { useRouter } from 'vue-router';
|
||||||
|
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
|
||||||
|
import useUserStore from '@/store/modules/user';
|
||||||
|
import useI18n from '@/hooks/useI18n';
|
||||||
|
const userStore = useUserStore();
|
||||||
|
const router = useRouter();
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
/**头像展开项点击 */
|
||||||
|
function fnClick({ key }: MenuInfo) {
|
||||||
|
switch (key) {
|
||||||
|
case 'settings':
|
||||||
|
router.push({ name: 'Settings' });
|
||||||
|
break;
|
||||||
|
case 'profile':
|
||||||
|
router.push({ name: 'Profile' });
|
||||||
|
break;
|
||||||
|
case 'logout':
|
||||||
|
userStore.fnLogOut().finally(() => router.push({ name: 'Login' }));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<a-dropdown placement="bottomRight" trigger="click">
|
||||||
|
<div class="user">
|
||||||
|
<a-avatar
|
||||||
|
shape="circle"
|
||||||
|
size="default"
|
||||||
|
:src="userStore.getAvatar"
|
||||||
|
:alt="userStore.userName"
|
||||||
|
></a-avatar>
|
||||||
|
<span class="nick">
|
||||||
|
{{ userStore.nickName }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<template #overlay>
|
||||||
|
<a-menu @click="fnClick">
|
||||||
|
<!-- <a-menu-item key="profile">
|
||||||
|
<template #icon>
|
||||||
|
<UserOutlined />
|
||||||
|
</template>
|
||||||
|
<span>{{ t('loayouts.rightContent.profile') }}</span>
|
||||||
|
</a-menu-item> -->
|
||||||
|
<a-menu-item key="settings">
|
||||||
|
<template #icon>
|
||||||
|
<SettingOutlined />
|
||||||
|
</template>
|
||||||
|
<span>{{ t('loayouts.rightContent.settings') }}</span>
|
||||||
|
</a-menu-item>
|
||||||
|
<a-menu-divider />
|
||||||
|
<a-menu-item key="logout">
|
||||||
|
<template #icon>
|
||||||
|
<LogoutOutlined />
|
||||||
|
</template>
|
||||||
|
<span>{{ t('loayouts.rightContent.logout') }}</span>
|
||||||
|
</a-menu-item>
|
||||||
|
</a-menu>
|
||||||
|
</template>
|
||||||
|
</a-dropdown>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.user {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: flex-start;
|
||||||
|
align-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
.nick {
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
max-width: 164px;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-align: start;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,241 +0,0 @@
|
|||||||
<script setup lang="ts">
|
|
||||||
import svgLight from '@/assets/svg/light.svg';
|
|
||||||
import svgDark from '@/assets/svg/dark.svg';
|
|
||||||
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
|
|
||||||
import { viewTransitionTheme } from 'antdv-pro-layout';
|
|
||||||
import { ProModal } from 'antdv-pro-modal';
|
|
||||||
import { ref } from 'vue';
|
|
||||||
import { useRoute, useRouter } from 'vue-router';
|
|
||||||
import { useFullscreen } from '@vueuse/core';
|
|
||||||
import { hasPermissions } from '@/plugins/auth-user';
|
|
||||||
import useI18n from '@/hooks/useI18n';
|
|
||||||
import useLayoutStore from '@/store/modules/layout';
|
|
||||||
import useAppStore from '@/store/modules/app';
|
|
||||||
import useUserStore from '@/store/modules/user';
|
|
||||||
import useAlarmStore from '@/store/modules/alarm';
|
|
||||||
import useMaskStore from '@/store/modules/mask';
|
|
||||||
const { isFullscreen, toggle } = useFullscreen();
|
|
||||||
const { t, changeLocale, optionsLocale } = useI18n();
|
|
||||||
const layoutStore = useLayoutStore();
|
|
||||||
const maskStore = useMaskStore();
|
|
||||||
const userStore = useUserStore();
|
|
||||||
const appStore = useAppStore();
|
|
||||||
const route = useRoute();
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
/**头像展开项点击 */
|
|
||||||
function fnClick({ key }: MenuInfo) {
|
|
||||||
switch (key) {
|
|
||||||
case 'settings':
|
|
||||||
router.push({ name: 'Settings' });
|
|
||||||
break;
|
|
||||||
case 'profile':
|
|
||||||
router.push({ name: 'Profile' });
|
|
||||||
break;
|
|
||||||
case 'logout':
|
|
||||||
userStore.fnLogOut().finally(() => router.push({ name: 'Login' }));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**锁屏确认 */
|
|
||||||
const lockConfirm = ref<boolean>(false);
|
|
||||||
/**锁屏密码 */
|
|
||||||
const lockPasswd = ref<string>('');
|
|
||||||
|
|
||||||
/**锁屏按钮提示 */
|
|
||||||
function fnClickLock() {
|
|
||||||
lockConfirm.value = true;
|
|
||||||
lockPasswd.value = '';
|
|
||||||
maskStore.lockPasswd = '';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**锁屏确认跳转锁屏页面 */
|
|
||||||
function fnClickLockToPage() {
|
|
||||||
lockConfirm.value = false;
|
|
||||||
maskStore.lockPasswd = lockPasswd.value;
|
|
||||||
maskStore.handleMaskType('lock');
|
|
||||||
router.push({ name: 'LockScreen', query: { redirect: route.path } });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**告警数按钮提示跳转 */
|
|
||||||
function fnClickAlarm() {
|
|
||||||
router.push({ name: 'ActiveAlarm_2088' });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**改变主题色 */
|
|
||||||
function fnClickTheme(e: any) {
|
|
||||||
viewTransitionTheme(isDarkMode => {
|
|
||||||
layoutStore.changeConf('theme', isDarkMode ? 'light' : 'dark');
|
|
||||||
}, e);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**改变多语言 */
|
|
||||||
function fnChangeLocale(e: any) {
|
|
||||||
changeLocale(e.key);
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<a-space :size="12" align="center">
|
|
||||||
<a-tooltip placement="bottomRight">
|
|
||||||
<template #title>{{ t('loayouts.rightContent.alarm') }}</template>
|
|
||||||
<a-button type="text" style="color: inherit" @click="fnClickAlarm">
|
|
||||||
<template #icon>
|
|
||||||
<a-badge
|
|
||||||
:count="useAlarmStore().activeAlarmTotal"
|
|
||||||
:overflow-count="99"
|
|
||||||
status="warning"
|
|
||||||
style="color: inherit"
|
|
||||||
>
|
|
||||||
<BellOutlined />
|
|
||||||
</a-badge>
|
|
||||||
</template>
|
|
||||||
</a-button>
|
|
||||||
</a-tooltip>
|
|
||||||
|
|
||||||
<!-- 锁屏操作 -->
|
|
||||||
<span v-perms:has="['system:setting:lock']">
|
|
||||||
<a-tooltip placement="bottomRight">
|
|
||||||
<template #title>{{ t('loayouts.rightContent.lock') }}</template>
|
|
||||||
<a-button type="text" style="color: inherit" @click="fnClickLock()">
|
|
||||||
<template #icon>
|
|
||||||
<LockOutlined />
|
|
||||||
</template>
|
|
||||||
</a-button>
|
|
||||||
<ProModal
|
|
||||||
:drag="true"
|
|
||||||
:center-y="true"
|
|
||||||
:width="400"
|
|
||||||
:minHeight="200"
|
|
||||||
:mask-closable="false"
|
|
||||||
v-model:open="lockConfirm"
|
|
||||||
:title="t('loayouts.rightContent.lockTip')"
|
|
||||||
@ok="fnClickLockToPage()"
|
|
||||||
>
|
|
||||||
<a-space>
|
|
||||||
{{ t('loayouts.rightContent.lockPasswd') }}:
|
|
||||||
<a-input-password
|
|
||||||
v-model:value="lockPasswd"
|
|
||||||
:placeholder="t('common.inputPlease')"
|
|
||||||
>
|
|
||||||
<template #prefix>
|
|
||||||
<a-tooltip
|
|
||||||
:title="t('loayouts.rightContent.lockPasswdTip')"
|
|
||||||
placement="topLeft"
|
|
||||||
>
|
|
||||||
<UnlockOutlined />
|
|
||||||
</a-tooltip>
|
|
||||||
</template>
|
|
||||||
</a-input-password>
|
|
||||||
</a-space>
|
|
||||||
</ProModal>
|
|
||||||
</a-tooltip>
|
|
||||||
</span>
|
|
||||||
|
|
||||||
<a-tooltip placement="bottomRight">
|
|
||||||
<template #title>{{ t('loayouts.rightContent.fullscreen') }}</template>
|
|
||||||
<a-button type="text" style="color: inherit" @click="toggle">
|
|
||||||
<template #icon>
|
|
||||||
<FullscreenExitOutlined v-if="isFullscreen" />
|
|
||||||
<FullscreenOutlined v-else />
|
|
||||||
</template>
|
|
||||||
</a-button>
|
|
||||||
</a-tooltip>
|
|
||||||
|
|
||||||
<a-tooltip placement="bottomRight">
|
|
||||||
<template #title>{{ t('loayouts.rightContent.theme') }}</template>
|
|
||||||
<a-button type="text" @click="fnClickTheme">
|
|
||||||
<template #icon>
|
|
||||||
<img
|
|
||||||
v-if="layoutStore.proConfig.theme === 'dark'"
|
|
||||||
:src="svgDark"
|
|
||||||
class="theme-icon"
|
|
||||||
/>
|
|
||||||
<img v-else :src="svgLight" class="theme-icon" />
|
|
||||||
</template>
|
|
||||||
</a-button>
|
|
||||||
</a-tooltip>
|
|
||||||
|
|
||||||
<a-dropdown
|
|
||||||
placement="bottomRight"
|
|
||||||
trigger="click"
|
|
||||||
v-if="appStore.i18nOpen && hasPermissions(['system:setting:i18n'])"
|
|
||||||
>
|
|
||||||
<a-button type="text" style="color: inherit">
|
|
||||||
<template #icon> <TranslationOutlined /> </template>
|
|
||||||
</a-button>
|
|
||||||
<template #overlay>
|
|
||||||
<a-menu @click="fnChangeLocale">
|
|
||||||
<a-menu-item v-for="opt in optionsLocale" :key="opt.value">
|
|
||||||
{{ opt.label }}
|
|
||||||
</a-menu-item>
|
|
||||||
</a-menu>
|
|
||||||
</template>
|
|
||||||
</a-dropdown>
|
|
||||||
|
|
||||||
<a-dropdown placement="bottomRight" trigger="click">
|
|
||||||
<div class="user">
|
|
||||||
<a-avatar
|
|
||||||
shape="circle"
|
|
||||||
size="default"
|
|
||||||
:src="userStore.getAvatar"
|
|
||||||
:alt="userStore.userName"
|
|
||||||
></a-avatar>
|
|
||||||
<span class="nick">
|
|
||||||
{{ userStore.nickName }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<template #overlay>
|
|
||||||
<a-menu @click="fnClick">
|
|
||||||
<!-- <a-menu-item key="profile">
|
|
||||||
<template #icon>
|
|
||||||
<UserOutlined />
|
|
||||||
</template>
|
|
||||||
<span>{{ t('loayouts.rightContent.profile') }}</span>
|
|
||||||
</a-menu-item> -->
|
|
||||||
<a-menu-item key="settings">
|
|
||||||
<template #icon>
|
|
||||||
<SettingOutlined />
|
|
||||||
</template>
|
|
||||||
<span>{{ t('loayouts.rightContent.settings') }}</span>
|
|
||||||
</a-menu-item>
|
|
||||||
<a-menu-divider />
|
|
||||||
<a-menu-item key="logout">
|
|
||||||
<template #icon>
|
|
||||||
<LogoutOutlined />
|
|
||||||
</template>
|
|
||||||
<span>{{ t('loayouts.rightContent.logout') }}</span>
|
|
||||||
</a-menu-item>
|
|
||||||
</a-menu>
|
|
||||||
</template>
|
|
||||||
</a-dropdown>
|
|
||||||
</a-space>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="less" scoped>
|
|
||||||
.user {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-start;
|
|
||||||
align-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
.nick {
|
|
||||||
padding-left: 8px;
|
|
||||||
padding-right: 16px;
|
|
||||||
font-size: 16px;
|
|
||||||
max-width: 164px;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-align: start;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-icon {
|
|
||||||
width: 18px;
|
|
||||||
height: 18px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
31
src/store/modules/core.ts
Normal file
31
src/store/modules/core.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { defineStore } from 'pinia';
|
||||||
|
|
||||||
|
/**核心网信息类型 */
|
||||||
|
type Core = {
|
||||||
|
/**当前选择 */
|
||||||
|
current: string;
|
||||||
|
/**核心网选择 */
|
||||||
|
coreOptions: Record<string, any>[];
|
||||||
|
};
|
||||||
|
|
||||||
|
const useCoreStore = defineStore('core', {
|
||||||
|
state: (): Core => ({
|
||||||
|
current: 'Global',
|
||||||
|
coreOptions: [
|
||||||
|
{ label: 'Core', value: 'Core' },
|
||||||
|
{ label: 'Core2', value: 'Core2' },
|
||||||
|
],
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
getCoreOptions(): Record<string, any>[] {
|
||||||
|
return this.coreOptions;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
actions: {
|
||||||
|
setCurrent(value: string = 'Global') {
|
||||||
|
this.current = value;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default useCoreStore;
|
||||||
@@ -70,9 +70,9 @@ const proRender = (render: any) => (render === false ? false : undefined);
|
|||||||
const proConfigLocal: LayoutStore['proConfig'] = localGetJSON(
|
const proConfigLocal: LayoutStore['proConfig'] = localGetJSON(
|
||||||
CACHE_LOCAL_PROCONFIG
|
CACHE_LOCAL_PROCONFIG
|
||||||
) || {
|
) || {
|
||||||
layout: 'mix',
|
layout: 'side',
|
||||||
theme: 'light',
|
theme: 'light',
|
||||||
menuTheme: 'light',
|
menuTheme: 'dark',
|
||||||
fixSiderbar: true,
|
fixSiderbar: true,
|
||||||
fixedHeader: true,
|
fixedHeader: true,
|
||||||
splitMenus: true,
|
splitMenus: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user