| | |
| | | <template> |
| | | <div class="layout-navbars-breadcrumb-user pr15" :style="{ flex: layoutUserFlexNum }"> |
| | | <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onComponentSizeChange"> |
| | | <div class="layout-navbars-breadcrumb-user-icon"> |
| | | <i class="iconfont icon-ziti" :title="$t('message.user.title0')"></i> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item command="large" :disabled="disabledSize === 'large'">{{ $t('message.user.dropdownLarge') }}</el-dropdown-item> |
| | | <el-dropdown-item command="default" :disabled="disabledSize === 'default'">{{ $t('message.user.dropdownDefault') }}</el-dropdown-item> |
| | | <el-dropdown-item command="small" :disabled="disabledSize === 'small'">{{ $t('message.user.dropdownSmall') }}</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onLanguageChange"> |
| | | <div class="layout-navbars-breadcrumb-user-icon"> |
| | | <i class="iconfont" :class="disabledI18n === 'en' ? 'icon-fuhao-yingwen' : 'icon-fuhao-zhongwen'" :title="$t('message.user.title1')"></i> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item command="zh-cn" :disabled="disabledI18n === 'zh-cn'">简体中文</el-dropdown-item> |
| | | <el-dropdown-item command="en" :disabled="disabledI18n === 'en'">English</el-dropdown-item> |
| | | <el-dropdown-item command="zh-tw" :disabled="disabledI18n === 'zh-tw'">繁體中文</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | <div class="layout-navbars-breadcrumb-user-icon" @click="onSearchClick"> |
| | | <el-icon :title="$t('message.user.title2')"> |
| | | <ele-Search /> |
| | | </el-icon> |
| | | </div> |
| | | <div class="layout-navbars-breadcrumb-user-icon" @click="onLayoutSetingClick"> |
| | | <i class="icon-skin iconfont" :title="$t('message.user.title3')"></i> |
| | | </div> |
| | | <div class="layout-navbars-breadcrumb-user-icon"> |
| | | <el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false"> |
| | | <template #reference> |
| | | <el-badge :is-dot="true"> |
| | | <el-icon :title="$t('message.user.title4')"> |
| | | <ele-Bell /> |
| | | </el-icon> |
| | | </el-badge> |
| | | </template> |
| | | <template #default> |
| | | <UserNews /> |
| | | </template> |
| | | </el-popover> |
| | | </div> |
| | | <div class="layout-navbars-breadcrumb-user-icon mr10" @click="onScreenfullClick"> |
| | | <i |
| | | class="iconfont" |
| | | :title="isScreenfull ? $t('message.user.title6') : $t('message.user.title5')" |
| | | :class="!isScreenfull ? 'icon-fullscreen' : 'icon-tuichuquanping'" |
| | | ></i> |
| | | </div> |
| | | <el-dropdown :show-timeout="70" :hide-timeout="50" @command="onHandleCommandClick"> |
| | | <span class="layout-navbars-breadcrumb-user-link"> |
| | | <img :src="userInfos.photo" class="layout-navbars-breadcrumb-user-link-photo mr5" /> |
| | | {{ userInfos.userName }} |
| | | <el-icon class="el-icon--right"> |
| | | <ele-ArrowDown /> |
| | | </el-icon> |
| | | </span> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item command="/home">{{ $t('message.user.dropdown1') }}</el-dropdown-item> |
| | | <el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item> |
| | | <el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item> |
| | | <el-dropdown-item command="/404">{{ $t('message.user.dropdown3') }}</el-dropdown-item> |
| | | <el-dropdown-item command="/401">{{ $t('message.user.dropdown4') }}</el-dropdown-item> |
| | | <el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | <Search ref="searchRef" /> |
| | | </div> |
| | | <div class="layout-navbars-breadcrumb-user pr15" :style="{ flex: layoutUserFlexNum }"> |
| | | <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onComponentSizeChange"> |
| | | <div class="layout-navbars-breadcrumb-user-icon"> |
| | | <i class="iconfont icon-ziti" :title="$t('message.user.title0')"></i> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item command="large" :disabled="disabledSize === 'large'">{{ $t('message.user.dropdownLarge') }}</el-dropdown-item> |
| | | <el-dropdown-item command="default" :disabled="disabledSize === 'default'">{{ |
| | | $t('message.user.dropdownDefault') |
| | | }}</el-dropdown-item> |
| | | <el-dropdown-item command="small" :disabled="disabledSize === 'small'">{{ $t('message.user.dropdownSmall') }}</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | <el-dropdown :show-timeout="70" :hide-timeout="50" trigger="click" @command="onLanguageChange"> |
| | | <div class="layout-navbars-breadcrumb-user-icon"> |
| | | <i |
| | | class="iconfont" |
| | | :class="disabledI18n === 'en' ? 'icon-fuhao-yingwen' : 'icon-fuhao-zhongwen'" |
| | | :title="$t('message.user.title1')" |
| | | ></i> |
| | | </div> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item command="zh-cn" :disabled="disabledI18n === 'zh-cn'">简体中文</el-dropdown-item> |
| | | <el-dropdown-item command="en" :disabled="disabledI18n === 'en'">English</el-dropdown-item> |
| | | <el-dropdown-item command="zh-tw" :disabled="disabledI18n === 'zh-tw'">繁體中文</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | <div class="layout-navbars-breadcrumb-user-icon" @click="onSearchClick"> |
| | | <el-icon :title="$t('message.user.title2')"> |
| | | <ele-Search /> |
| | | </el-icon> |
| | | </div> |
| | | <div class="layout-navbars-breadcrumb-user-icon" @click="onLayoutSetingClick"> |
| | | <i class="icon-skin iconfont" :title="$t('message.user.title3')"></i> |
| | | </div> |
| | | <div class="layout-navbars-breadcrumb-user-icon"> |
| | | <el-popover placement="bottom" trigger="click" transition="el-zoom-in-top" :width="300" :persistent="false"> |
| | | <template #reference> |
| | | <el-badge :is-dot="true"> |
| | | <el-icon :title="$t('message.user.title4')"> |
| | | <ele-Bell /> |
| | | </el-icon> |
| | | </el-badge> |
| | | </template> |
| | | <template #default> |
| | | <UserNews /> |
| | | </template> |
| | | </el-popover> |
| | | </div> |
| | | <div class="layout-navbars-breadcrumb-user-icon mr10" @click="onScreenfullClick"> |
| | | <i |
| | | class="iconfont" |
| | | :title="isScreenfull ? $t('message.user.title6') : $t('message.user.title5')" |
| | | :class="!isScreenfull ? 'icon-fullscreen' : 'icon-tuichuquanping'" |
| | | ></i> |
| | | </div> |
| | | <el-dropdown :show-timeout="70" :hide-timeout="50" @command="onHandleCommandClick"> |
| | | <span class="layout-navbars-breadcrumb-user-link"> |
| | | <img :src="userInfos.photo" class="layout-navbars-breadcrumb-user-link-photo mr5" /> |
| | | {{ userInfos.userName }} |
| | | <el-icon class="el-icon--right"> |
| | | <ele-ArrowDown /> |
| | | </el-icon> |
| | | </span> |
| | | <template #dropdown> |
| | | <el-dropdown-menu> |
| | | <el-dropdown-item command="/homeMenu">{{ $t('message.user.dropdown1') }}</el-dropdown-item> |
| | | <!-- <el-dropdown-item command="wareHouse">{{ $t('message.user.dropdown6') }}</el-dropdown-item>--> |
| | | <el-dropdown-item command="/personal">{{ $t('message.user.dropdown2') }}</el-dropdown-item> |
| | | <!-- <el-dropdown-item command="/404">{{ $t('message.user.dropdown3') }}</el-dropdown-item>--> |
| | | <!-- <el-dropdown-item command="/401">{{ $t('message.user.dropdown4') }}</el-dropdown-item>--> |
| | | <el-dropdown-item divided command="logOut">{{ $t('message.user.dropdown5') }}</el-dropdown-item> |
| | | </el-dropdown-menu> |
| | | </template> |
| | | </el-dropdown> |
| | | <Search ref="searchRef" /> |
| | | </div> |
| | | </template> |
| | | |
| | | <script lang="ts"> |
| | |
| | | import { Session, Local } from '/@/utils/storage'; |
| | | import UserNews from '/@/layout/navBars/breadcrumb/userNews.vue'; |
| | | import Search from '/@/layout/navBars/breadcrumb/search.vue'; |
| | | import { useLoginApi } from '/@/api/login'; |
| | | |
| | | export default defineComponent({ |
| | | name: 'layoutBreadcrumbUser', |
| | | components: { UserNews, Search }, |
| | | setup() { |
| | | const { t } = useI18n(); |
| | | const { proxy } = <any>getCurrentInstance(); |
| | | const router = useRouter(); |
| | | const stores = useUserInfo(); |
| | | const storesThemeConfig = useThemeConfig(); |
| | | const { userInfos } = storeToRefs(stores); |
| | | const { themeConfig } = storeToRefs(storesThemeConfig); |
| | | const searchRef = ref(); |
| | | const state = reactive({ |
| | | isScreenfull: false, |
| | | disabledI18n: 'zh-cn', |
| | | disabledSize: 'large', |
| | | }); |
| | | // 设置分割样式 |
| | | const layoutUserFlexNum = computed(() => { |
| | | let num: string | number = ''; |
| | | const { layout, isClassicSplitMenu } = themeConfig.value; |
| | | const layoutArr: string[] = ['defaults', 'columns']; |
| | | if (layoutArr.includes(layout) || (layout === 'classic' && !isClassicSplitMenu)) num = '1'; |
| | | else num = ''; |
| | | return num; |
| | | }); |
| | | // 全屏点击时 |
| | | const onScreenfullClick = () => { |
| | | if (!screenfull.isEnabled) { |
| | | ElMessage.warning('暂不不支持全屏'); |
| | | return false; |
| | | } |
| | | screenfull.toggle(); |
| | | screenfull.on('change', () => { |
| | | if (screenfull.isFullscreen) state.isScreenfull = true; |
| | | else state.isScreenfull = false; |
| | | }); |
| | | }; |
| | | // 布局配置 icon 点击时 |
| | | const onLayoutSetingClick = () => { |
| | | proxy.mittBus.emit('openSetingsDrawer'); |
| | | }; |
| | | // 下拉菜单点击时 |
| | | const onHandleCommandClick = (path: string) => { |
| | | if (path === 'logOut') { |
| | | ElMessageBox({ |
| | | closeOnClickModal: false, |
| | | closeOnPressEscape: false, |
| | | title: t('message.user.logOutTitle'), |
| | | message: t('message.user.logOutMessage'), |
| | | showCancelButton: true, |
| | | confirmButtonText: t('message.user.logOutConfirm'), |
| | | cancelButtonText: t('message.user.logOutCancel'), |
| | | buttonSize: 'default', |
| | | beforeClose: (action, instance, done) => { |
| | | if (action === 'confirm') { |
| | | instance.confirmButtonLoading = true; |
| | | instance.confirmButtonText = t('message.user.logOutExit'); |
| | | setTimeout(() => { |
| | | done(); |
| | | setTimeout(() => { |
| | | instance.confirmButtonLoading = false; |
| | | }, 300); |
| | | }, 700); |
| | | } else { |
| | | done(); |
| | | } |
| | | }, |
| | | }) |
| | | .then(async () => { |
| | | Session.clear(); // 清除缓存/token等 |
| | | // 使用 reload 时,不需要调用 resetRoute() 重置路由 |
| | | window.location.reload(); |
| | | }) |
| | | .catch(() => {}); |
| | | } else if (path === 'wareHouse') { |
| | | window.open('https://gitee.com/lyt-top/vue-next-admin'); |
| | | } else { |
| | | router.push(path); |
| | | } |
| | | }; |
| | | // 菜单搜索点击 |
| | | const onSearchClick = () => { |
| | | searchRef.value.openSearch(); |
| | | }; |
| | | // 组件大小改变 |
| | | const onComponentSizeChange = (size: string) => { |
| | | Local.remove('themeConfig'); |
| | | themeConfig.value.globalComponentSize = size; |
| | | Local.set('themeConfig', themeConfig.value); |
| | | initComponentSize(); |
| | | window.location.reload(); |
| | | }; |
| | | // 语言切换 |
| | | const onLanguageChange = (lang: string) => { |
| | | Local.remove('themeConfig'); |
| | | themeConfig.value.globalI18n = lang; |
| | | Local.set('themeConfig', themeConfig.value); |
| | | proxy.$i18n.locale = lang; |
| | | initI18n(); |
| | | other.useTitle(); |
| | | }; |
| | | // 设置 element plus 组件的国际化 |
| | | const setI18nConfig = (locale: string) => { |
| | | proxy.mittBus.emit('getI18nConfig', proxy.$i18n.messages[locale]); |
| | | }; |
| | | // 初始化言语国际化 |
| | | const initI18n = () => { |
| | | switch (Local.get('themeConfig').globalI18n) { |
| | | case 'zh-cn': |
| | | state.disabledI18n = 'zh-cn'; |
| | | setI18nConfig('zh-cn'); |
| | | break; |
| | | case 'en': |
| | | state.disabledI18n = 'en'; |
| | | setI18nConfig('en'); |
| | | break; |
| | | case 'zh-tw': |
| | | state.disabledI18n = 'zh-tw'; |
| | | setI18nConfig('zh-tw'); |
| | | break; |
| | | } |
| | | }; |
| | | // 初始化全局组件大小 |
| | | const initComponentSize = () => { |
| | | switch (Local.get('themeConfig').globalComponentSize) { |
| | | case 'large': |
| | | state.disabledSize = 'large'; |
| | | break; |
| | | case 'default': |
| | | state.disabledSize = 'default'; |
| | | break; |
| | | case 'small': |
| | | state.disabledSize = 'small'; |
| | | break; |
| | | } |
| | | }; |
| | | // 页面加载时 |
| | | onMounted(() => { |
| | | if (Local.get('themeConfig')) { |
| | | initI18n(); |
| | | initComponentSize(); |
| | | } |
| | | }); |
| | | return { |
| | | userInfos, |
| | | onLayoutSetingClick, |
| | | onHandleCommandClick, |
| | | onScreenfullClick, |
| | | onSearchClick, |
| | | onComponentSizeChange, |
| | | onLanguageChange, |
| | | searchRef, |
| | | layoutUserFlexNum, |
| | | ...toRefs(state), |
| | | }; |
| | | }, |
| | | name: 'layoutBreadcrumbUser', |
| | | components: { UserNews, Search }, |
| | | setup() { |
| | | const { t } = useI18n(); |
| | | const { proxy } = <any>getCurrentInstance(); |
| | | const router = useRouter(); |
| | | const stores = useUserInfo(); |
| | | const storesThemeConfig = useThemeConfig(); |
| | | const { userInfos } = storeToRefs(stores); |
| | | const { themeConfig } = storeToRefs(storesThemeConfig); |
| | | const searchRef = ref(); |
| | | const state = reactive({ |
| | | isScreenfull: false, |
| | | disabledI18n: 'zh-cn', |
| | | disabledSize: 'large' |
| | | }); |
| | | // 设置分割样式 |
| | | const layoutUserFlexNum = computed(() => { |
| | | let num: string | number = ''; |
| | | const { layout, isClassicSplitMenu } = themeConfig.value; |
| | | const layoutArr: string[] = ['defaults', 'columns']; |
| | | if (layoutArr.includes(layout) || (layout === 'classic' && !isClassicSplitMenu)) num = '1'; |
| | | else num = ''; |
| | | return num; |
| | | }); |
| | | // 全屏点击时 |
| | | const onScreenfullClick = () => { |
| | | if (!screenfull.isEnabled) { |
| | | ElMessage.warning('暂不不支持全屏'); |
| | | return false; |
| | | } |
| | | screenfull.toggle(); |
| | | screenfull.on('change', () => { |
| | | if (screenfull.isFullscreen) state.isScreenfull = true; |
| | | else state.isScreenfull = false; |
| | | }); |
| | | }; |
| | | // 布局配置 icon 点击时 |
| | | const onLayoutSetingClick = () => { |
| | | proxy.mittBus.emit('openSetingsDrawer'); |
| | | }; |
| | | // 下拉菜单点击时 |
| | | const onHandleCommandClick = (path: string) => { |
| | | if (path === 'logOut') { |
| | | ElMessageBox({ |
| | | closeOnClickModal: false, |
| | | closeOnPressEscape: false, |
| | | title: t('message.user.logOutTitle'), |
| | | message: t('message.user.logOutMessage'), |
| | | showCancelButton: true, |
| | | confirmButtonText: t('message.user.logOutConfirm'), |
| | | cancelButtonText: t('message.user.logOutCancel'), |
| | | buttonSize: 'default', |
| | | beforeClose: (action, instance, done) => { |
| | | if (action === 'confirm') { |
| | | instance.confirmButtonLoading = true; |
| | | instance.confirmButtonText = t('message.user.logOutExit'); |
| | | setTimeout(() => { |
| | | done(); |
| | | setTimeout(() => { |
| | | instance.confirmButtonLoading = false; |
| | | }, 300); |
| | | }, 700); |
| | | } else { |
| | | done(); |
| | | } |
| | | } |
| | | }) |
| | | .then(async () => { |
| | | let res = await useLoginApi().signOut(); |
| | | if (res.data.code === '200') { |
| | | Session.clear(); // 清除缓存/token等 |
| | | // 使用 reload 时,不需要调用 resetRoute() 重置路由 |
| | | window.location.reload(); |
| | | } else { |
| | | ElMessage({ |
| | | type: 'warning', |
| | | message: res.data.msg |
| | | }); |
| | | } |
| | | }) |
| | | .catch(() => {}); |
| | | } else if (path === 'wareHouse') { |
| | | window.open('https://gitee.com/lyt-top/vue-next-admin'); |
| | | } else { |
| | | router.push(path); |
| | | } |
| | | }; |
| | | // 菜单搜索点击 |
| | | const onSearchClick = () => { |
| | | searchRef.value.openSearch(); |
| | | }; |
| | | // 组件大小改变 |
| | | const onComponentSizeChange = (size: string) => { |
| | | Local.remove('themeConfig'); |
| | | themeConfig.value.globalComponentSize = size; |
| | | Local.set('themeConfig', themeConfig.value); |
| | | initComponentSize(); |
| | | window.location.reload(); |
| | | }; |
| | | // 语言切换 |
| | | const onLanguageChange = (lang: string) => { |
| | | Local.remove('themeConfig'); |
| | | themeConfig.value.globalI18n = lang; |
| | | Local.set('themeConfig', themeConfig.value); |
| | | proxy.$i18n.locale = lang; |
| | | initI18n(); |
| | | other.useTitle(); |
| | | }; |
| | | // 设置 element plus 组件的国际化 |
| | | const setI18nConfig = (locale: string) => { |
| | | proxy.mittBus.emit('getI18nConfig', proxy.$i18n.messages[locale]); |
| | | }; |
| | | // 初始化言语国际化 |
| | | const initI18n = () => { |
| | | switch (Local.get('themeConfig').globalI18n) { |
| | | case 'zh-cn': |
| | | state.disabledI18n = 'zh-cn'; |
| | | setI18nConfig('zh-cn'); |
| | | break; |
| | | case 'en': |
| | | state.disabledI18n = 'en'; |
| | | setI18nConfig('en'); |
| | | break; |
| | | case 'zh-tw': |
| | | state.disabledI18n = 'zh-tw'; |
| | | setI18nConfig('zh-tw'); |
| | | break; |
| | | } |
| | | }; |
| | | // 初始化全局组件大小 |
| | | const initComponentSize = () => { |
| | | switch (Local.get('themeConfig').globalComponentSize) { |
| | | case 'large': |
| | | state.disabledSize = 'large'; |
| | | break; |
| | | case 'default': |
| | | state.disabledSize = 'default'; |
| | | break; |
| | | case 'small': |
| | | state.disabledSize = 'small'; |
| | | break; |
| | | } |
| | | }; |
| | | // 页面加载时 |
| | | onMounted(() => { |
| | | if (Local.get('themeConfig')) { |
| | | initI18n(); |
| | | initComponentSize(); |
| | | } |
| | | }); |
| | | return { |
| | | userInfos, |
| | | onLayoutSetingClick, |
| | | onHandleCommandClick, |
| | | onScreenfullClick, |
| | | onSearchClick, |
| | | onComponentSizeChange, |
| | | onLanguageChange, |
| | | searchRef, |
| | | layoutUserFlexNum, |
| | | ...toRefs(state) |
| | | }; |
| | | } |
| | | }); |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .layout-navbars-breadcrumb-user { |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: flex-end; |
| | | &-link { |
| | | height: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | white-space: nowrap; |
| | | &-photo { |
| | | width: 25px; |
| | | height: 25px; |
| | | border-radius: 100%; |
| | | } |
| | | } |
| | | &-icon { |
| | | padding: 0 10px; |
| | | cursor: pointer; |
| | | color: var(--next-bg-topBarColor); |
| | | height: 50px; |
| | | line-height: 50px; |
| | | display: flex; |
| | | align-items: center; |
| | | &:hover { |
| | | background: var(--next-color-user-hover); |
| | | i { |
| | | display: inline-block; |
| | | animation: logoAnimation 0.3s ease-in-out; |
| | | } |
| | | } |
| | | } |
| | | ::v-deep(.el-dropdown) { |
| | | color: var(--next-bg-topBarColor); |
| | | } |
| | | ::v-deep(.el-badge) { |
| | | height: 40px; |
| | | line-height: 40px; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | ::v-deep(.el-badge__content.is-fixed) { |
| | | top: 12px; |
| | | } |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: flex-end; |
| | | &-link { |
| | | height: 100%; |
| | | display: flex; |
| | | align-items: center; |
| | | white-space: nowrap; |
| | | &-photo { |
| | | width: 25px; |
| | | height: 25px; |
| | | border-radius: 100%; |
| | | } |
| | | } |
| | | &-icon { |
| | | padding: 0 10px; |
| | | cursor: pointer; |
| | | color: var(--next-bg-topBarColor); |
| | | height: 50px; |
| | | line-height: 50px; |
| | | display: flex; |
| | | align-items: center; |
| | | &:hover { |
| | | background: var(--next-color-user-hover); |
| | | i { |
| | | display: inline-block; |
| | | animation: logoAnimation 0.3s ease-in-out; |
| | | } |
| | | } |
| | | } |
| | | ::v-deep(.el-dropdown) { |
| | | color: var(--next-bg-topBarColor); |
| | | } |
| | | ::v-deep(.el-badge) { |
| | | height: 40px; |
| | | line-height: 40px; |
| | | display: flex; |
| | | align-items: center; |
| | | } |
| | | ::v-deep(.el-badge__content.is-fixed) { |
| | | top: 12px; |
| | | } |
| | | } |
| | | </style> |