Your Name
2022-07-13 656696be4b70513e94f1341db8d1c2d3f43b3e6d
src/layout/navBars/breadcrumb/user.vue
@@ -1,79 +1,85 @@
<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">
@@ -89,210 +95,219 @@
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>