| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- <template>
- <header class="header" :class="{ 'use-px': usePx }">
- <img :src="logo" alt="logo" class="header__logo" />
- <span class="platform-name">{{ title }}</span>
- <nav class="header__nav">
- <div
- class="header__nav--item"
- v-for="item in NAV_LIST"
- :key="item.path"
- :class="{ active: selectedKey === item.name }"
- @click="handleNavClick(item)"
- >
- <span>{{ item.meta?.title }}</span>
- </div>
- </nav>
- <SwitchTenant v-if="userStore.info.tenantId === SYS_TENANT_ID" />
- <div class="platform__right">
- <div class="platform__right__login">
- <span @click="userStore.showLogin = true" v-if="!userStore.info?.id">登录</span>
- <UserInfo v-else />
- </div>
- </div>
- </header>
- <Login v-if="userStore.showLogin" @close="userStore.showLogin = false" class="fadeIn" />
- <SwitchAccount v-if="userStore.showSwitchAccount" @close="userStore.showSwitchAccount = false" class="fadeIn" />
- <UpdatePwd v-if="userStore.showUpdatePwd || getUserInfo.isFirstLogin" @close="handleUpdatePwdClose" class="fadeIn" />
- </template>
- <script lang="ts" setup>
- import { computed } from 'vue';
- import { useRouter, useRoute } from 'vue-router';
- import UpdatePwd from '@/components/UpdatePwd.vue';
- import UserInfo from '@/components/UserInfo.vue';
- import Login from '@/components/Login/Login.vue';
- import SwitchAccount from '@/components/Login/SwitchAccount.vue';
- import SwitchTenant from '@/layout/components/SwitchTenant.vue';
- import { useUserStore } from '@/store/modules/user';
- import { useGlobSetting } from '@/hooks/setting';
- import { SYS_TENANT_ID } from '@/utils/useTargetTenantIdSetting';
- import { NAV_LIST } from '@/constant/nav';
- import logo from 'assets/images/home/comac-logo@1X.png';
- import { ElMessage } from 'element-plus';
- import { storeToRefs } from 'pinia';
- // import searchIcon from 'assets/svg/search.svg';
- const userStore = useUserStore();
- const { getUserInfo } = storeToRefs(userStore);
- // const activeNav = ref(NAV_LIST[0].name);
- const router = useRouter();
- // const searchValue = ref('');
- const props = withDefaults(defineProps<{ usePx?: boolean }>(), { usePx: false });
- const usePx = computed(() => props.usePx === true);
- // const handleSearch = () => {
- // console.log('searchValue', searchValue.value);
- // };
- const currentRoute = useRoute();
- const { title } = useGlobSetting();
- const handleNavClick = (item: { name: string; path: string; meta?: any }) => {
- if (item.meta?.isExternalLink) {
- if (item.path === '403') {
- router.replace(item.path);
- return;
- }
- window.open(item.path, '_blank');
- return;
- }
- router.push(item.path);
- };
- const handleUpdatePwdClose = () => {
- if (getUserInfo.value.isFirstLogin) {
- ElMessage({
- message: '首次登录请修改密码',
- type: 'warning',
- duration: 3000,
- });
- } else {
- userStore.showUpdatePwd = false;
- }
- };
- const selectedKey = computed(() => {
- return currentRoute.matched[0]?.name;
- });
- </script>
- <style lang="scss" scoped>
- .header {
- display: flex;
- align-items: center;
- position: relative;
- width: 100%;
- height: 78cpx;
- background: url('assets/images/home/nav-bg@1X.png') no-repeat center center / cover;
- z-index: 2;
- &__nav {
- @include flex-center;
- gap: 10cpx;
- height: 100%;
- margin-left: 32cpx;
- &--item {
- @include flex-center;
- height: 45cpx;
- padding: 10cpx 20cpx;
- gap: 8cpx;
- font-size: 18cpx;
- color: #333;
- border-radius: 4cpx;
- cursor: pointer;
- border: 1px solid transparent;
- border-radius: 4px;
- // transition: all 0.3s ease-in-out;
- &.active,
- &:hover {
- background: linear-gradient(180deg, #33afff, $primary-color);
- color: $white-color;
- }
- }
- }
- }
- .header__logo {
- width: 34cpx;
- height: 34cpx;
- margin-left: 38cpx;
- }
- .platform-name {
- font-size: 18cpx;
- font-weight: 550;
- margin-left: 9cpx;
- }
- .platform__right {
- // @include flex-center;
- // position: absolute;
- // top: 0;
- // right: 0;
- display: flex;
- flex: 1;
- justify-content: flex-end;
- height: 73cpx;
- // &__search {
- // @include flex-center;
- // width: 210cpx;
- // height: 100%;
- // padding: 28cpx 26cpx;
- // background: rgba($white-color, 0.4);
- // }
- &__login {
- @include flex-center;
- gap: 10cpx;
- height: 100%;
- // padding: 27cpx 40cpx 26cpx 40cpx;
- padding: 27cpx 10cpx 26cpx;
- font-size: 18cpx;
- color: $primary-color;
- cursor: pointer;
- }
- }
- .input-with-icon {
- :deep(.el-input__wrapper),
- :deep(.el-input-group__prepend) {
- background-color: transparent;
- box-shadow: none;
- padding: 0;
- }
- :deep(.el-input__inner) {
- width: 120cpx;
- margin-left: 5cpx;
- font-size: 16cpx;
- color: #909399;
- }
- .search-icon {
- width: 28cpx;
- height: 28cpx;
- cursor: pointer;
- }
- }
- /* 使用 px 的样式覆盖(用于固定画布布局) */
- .header.use-px {
- height: 78px;
- }
- .header.use-px .header__nav {
- gap: 14px;
- margin-left: 32px;
- }
- .header.use-px .header__nav--item {
- height: 45px;
- padding: 10px 20px;
- font-size: 18px;
- border-radius: 4px;
- }
- .header.use-px .header__logo {
- width: 34px;
- height: 34px;
- margin-left: 38px;
- }
- .header.use-px .platform-name {
- font-size: 18px;
- margin-left: 9px;
- }
- .header.use-px .platform__right {
- height: 73px;
- }
- .header.use-px .platform__right__search {
- width: 210px;
- padding: 28px 26px;
- }
- .header.use-px .platform__right__login {
- gap: 10px;
- padding: 27px 40px 26px 40px;
- font-size: 18px;
- }
- .header.use-px .input-with-icon :deep(.el-input__inner) {
- width: 120px;
- margin-left: 5px;
- font-size: 16px;
- }
- .header.use-px .input-with-icon .search-icon {
- width: 28px;
- height: 28px;
- }
- </style>
|