| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- <script setup lang="ts">
- import { useNav } from "@/layout/hooks/useNav";
- import LaySearch from "../lay-search/index.vue";
- import LayNotice from "../lay-notice/index.vue";
- import LayNavMix from "../lay-sidebar/NavMix.vue";
- import { useTranslationLang } from "@/layout/hooks/useTranslationLang";
- import LaySidebarFullScreen from "../lay-sidebar/components/SidebarFullScreen.vue";
- import LaySidebarBreadCrumb from "../lay-sidebar/components/SidebarBreadCrumb.vue";
- import GlobalizationIcon from "@/assets/svg/globalization.svg?component";
- import AccountSettingsIcon from "~icons/ri/user-settings-line";
- import LogoutCircleRLine from "~icons/ri/logout-circle-r-line";
- import Setting from "~icons/ri/settings-3-line";
- import Check from "~icons/ep/check";
- import Location from "~icons/ri/map-pin-line";
- import { getStationList } from "@/api/station";
- import { reactive, computed, onMounted } from "vue";
- const {
- layout,
- device,
- logout,
- onPanel,
- username,
- userAvatar,
- avatarsStyle,
- toAccountSettings,
- getDropdownItemStyle,
- getDropdownItemClass
- } = useNav();
- const { t, locale, translationCh, translationEn } = useTranslationLang();
- // Session 工具
- const Session = {
- get: (key: string) => {
- const value = sessionStorage.getItem(key);
- return value ? JSON.parse(value) : null;
- },
- set: (key: string, value: any) => {
- sessionStorage.setItem(key, JSON.stringify(value));
- }
- };
- const state = reactive({
- stationList: [] as any[],
- currentStationId: null as string | null,
- currentStationName: '' as string
- });
- // 加载站点列表
- const loadStationList = () => {
- getStationList({ pageNum: 1, pageSize: 1024 }).then((res: any) => {
- const list = res?.data?.list || res?.list || res?.data || res || [];
- state.stationList = list;
-
- // 获取当前选中的站点
- const savedStationId = Session.get("currentStationId");
- if (savedStationId && list.length > 0) {
- const currentStation = list.find((s: any) => s.stationId === savedStationId);
- if (currentStation) {
- state.currentStationId = currentStation.stationId;
- state.currentStationName = currentStation.stationName;
- } else {
- // 如果保存的站点不在列表中,选择第一个
- state.currentStationId = list[0]?.stationId;
- state.currentStationName = list[0]?.stationName;
- }
- } else if (list.length > 0) {
- // 默认选择第一个站点
- state.currentStationId = list[0]?.stationId;
- state.currentStationName = list[0]?.stationName;
- }
- }).catch(() => {
- console.warn('站点列表加载失败');
- });
- };
- // 切换站点
- const handleStationChange = (station: any) => {
- state.currentStationId = station.stationId;
- state.currentStationName = station.stationName;
- Session.set("currentStationId", station.stationId);
-
- // 刷新页面以加载新站点数据
- setTimeout(() => {
- window.location.reload();
- }, 300);
- };
- onMounted(() => {
- loadStationList();
- });
- </script>
- <template>
- <div class="navbar bg-[#fff] shadow-xs shadow-[rgba(0,21,41,0.08)]">
- <LaySidebarBreadCrumb
- v-if="layout !== 'mix' && device !== 'mobile'"
- class="breadcrumb-container"
- />
- <LayNavMix v-if="layout === 'mix'" />
- <div v-if="layout === 'vertical'" class="vertical-header-right">
- <!-- 站点切换 -->
- <el-dropdown id="header-station" trigger="click" @command="handleStationChange">
- <div class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden flex items-center">
- <IconifyIconOffline :icon="Location" style="margin-right: 5px;" />
- <span class="dark:text-white truncate max-w-[150px]">{{ state.currentStationName || '选择站点' }}</span>
- </div>
- <template #dropdown>
- <el-dropdown-menu>
- <el-dropdown-item
- v-for="station in state.stationList"
- :key="station.stationId"
- :command="station"
- :disabled="state.currentStationId === station.stationId"
- >
- {{ station.stationName }}
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
-
- <!-- 菜单搜索 -->
- <LaySearch id="header-search" />
- <!-- 国际化 -->
- <el-dropdown id="header-translation" trigger="click">
- <GlobalizationIcon
- class="navbar-bg-hover w-[40px] h-[48px] p-[11px] cursor-pointer outline-hidden"
- />
- <template #dropdown>
- <el-dropdown-menu class="translation">
- <el-dropdown-item
- :style="getDropdownItemStyle(locale, 'zh')"
- :class="['dark:text-white!', getDropdownItemClass(locale, 'zh')]"
- @click="translationCh"
- >
- <IconifyIconOffline
- v-show="locale === 'zh'"
- class="check-zh"
- :icon="Check"
- />
- 简体中文
- </el-dropdown-item>
- <el-dropdown-item
- :style="getDropdownItemStyle(locale, 'en')"
- :class="['dark:text-white!', getDropdownItemClass(locale, 'en')]"
- @click="translationEn"
- >
- <span v-show="locale === 'en'" class="check-en">
- <IconifyIconOffline :icon="Check" />
- </span>
- English
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- <!-- 全屏 -->
- <LaySidebarFullScreen id="full-screen" />
- <!-- 消息通知 -->
- <LayNotice id="header-notice" />
- <!-- 退出登录 -->
- <el-dropdown trigger="click">
- <span class="el-dropdown-link navbar-bg-hover select-none">
- <img :src="userAvatar" :style="avatarsStyle" />
- <p v-if="username" class="dark:text-white">{{ username }}</p>
- </span>
- <template #dropdown>
- <el-dropdown-menu class="logout">
- <el-dropdown-item @click="toAccountSettings">
- <IconifyIconOffline
- :icon="AccountSettingsIcon"
- style="margin: 5px"
- />
- {{ t("buttons.pureAccountSettings") }}
- </el-dropdown-item>
- <el-dropdown-item @click="logout">
- <IconifyIconOffline
- :icon="LogoutCircleRLine"
- style="margin: 5px"
- />
- {{ t("buttons.pureLoginOut") }}
- </el-dropdown-item>
- </el-dropdown-menu>
- </template>
- </el-dropdown>
- <span
- class="set-icon navbar-bg-hover"
- :title="t('buttons.pureOpenSystemSet')"
- @click="onPanel"
- >
- <IconifyIconOffline :icon="Setting" />
- </span>
- </div>
- </div>
- </template>
- <style lang="scss" scoped>
- .navbar {
- width: 100%;
- height: 48px;
- overflow: hidden;
- .hamburger-container {
- float: left;
- height: 100%;
- line-height: 48px;
- cursor: pointer;
- }
- .vertical-header-right {
- display: flex;
- align-items: center;
- justify-content: flex-end;
- min-width: 280px;
- height: 48px;
- color: #000000d9;
- .el-dropdown-link {
- display: flex;
- align-items: center;
- justify-content: space-around;
- height: 48px;
- padding: 10px;
- color: #000000d9;
- cursor: pointer;
- p {
- font-size: 14px;
- }
- img {
- width: 22px;
- height: 22px;
- border-radius: 50%;
- }
- }
- }
- .breadcrumb-container {
- float: left;
- margin-left: 16px;
- }
- }
- .translation {
- ::v-deep(.el-dropdown-menu__item) {
- padding: 5px 40px;
- }
- .check-zh {
- position: absolute;
- left: 20px;
- }
- .check-en {
- position: absolute;
- left: 20px;
- }
- }
- .logout {
- width: 120px;
- ::v-deep(.el-dropdown-menu__item) {
- display: inline-flex;
- flex-wrap: wrap;
- min-width: 100%;
- }
- }
- </style>
|