| | |
| | | <div :class="`header-box`" v-if="hasHeader && title !== $t('hj248')"> |
| | | <mt-header :title="title"> |
| | | <mt-button icon="back" slot="left" @click="$router.go(-1)"></mt-button> |
| | | <div v-if="!is_Show"> |
| | | <template v-if="iconRight == 'search'"> |
| | | <img slot="right" class="search-right" src="./assets/ico/fangdajing.png" alt /> |
| | | </template> |
| | | <template v-else> |
| | | <mt-button icon="more" slot="right"></mt-button> |
| | | <div slot="right" class="header-right"> |
| | | <!-- 消息图标 - 始终显示(如果已登录) --> |
| | | <div class="message-icon-wrapper" @click="goToMessage" v-if="isLoggedIn"> |
| | | <svg class="message-icon" viewBox="0 0 24 24" fill="currentColor"> |
| | | <path d="M20 2H4c-1.1 0-2 .9-2 2v18l4-4h14c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm0 14H6l-2 2V4h16v12z"/> |
| | | </svg> |
| | | <span v-if="unreadCount > 0" class="message-badge">{{ unreadCount > 99 ? '99+' : unreadCount }}</span> |
| | | </div> |
| | | <!-- 其他图标 --> |
| | | <template v-if="!is_Show"> |
| | | <template v-if="iconRight == 'search'"> |
| | | <img class="search-right" src="./assets/ico/fangdajing.png" alt /> |
| | | </template> |
| | | <template v-else-if="iconRight != 'message'"> |
| | | <mt-button icon="more"></mt-button> |
| | | </template> |
| | | </template> |
| | | </div> |
| | | </mt-header> |
| | |
| | | import elalert from "@/components/elalert.vue"; |
| | | import foot from "@/components/foot.vue"; |
| | | import loginPopup from "@/components/loginDialog.vue"; |
| | | import * as api from "@/axios/api"; |
| | | //引入css |
| | | import "@/assets/iconfont/iconfont.css"; |
| | | import "@/assets/iconfont/iconfont.ttf"; |
| | |
| | | } |
| | | // this.$store.state.className = window.localStorage.getItem('styleName')?window.localStorage.getItem('styleName'):'red' |
| | | }, |
| | | data() { |
| | | return { |
| | | title: this.$t('hj224'), |
| | | hasHeader: false, |
| | | iconRight: "default", |
| | | transitionName: '', |
| | | is_Show: true, |
| | | is_foot: true, |
| | | unreadCount: 0, |
| | | messageTimer: null, |
| | | loginCheckTimer: null, |
| | | lastToken: null, |
| | | }; |
| | | }, |
| | | computed: { |
| | | isLoggedIn() { |
| | | // 实时检查登录状态 |
| | | return !!window.localStorage.getItem("USERTOKEN"); |
| | | } |
| | | }, |
| | | mounted() { |
| | | // 初始化时检查登录状态并获取消息数 |
| | | this.checkLoginAndLoadMessages(); |
| | | |
| | | // 监听localStorage变化(用于跨标签页同步) |
| | | window.addEventListener('storage', this.handleStorageChange); |
| | | |
| | | // 定期检查登录状态(处理同标签页内的登录/登出) |
| | | this.loginCheckTimer = setInterval(() => { |
| | | this.checkLoginAndLoadMessages(); |
| | | }, 1000); |
| | | }, |
| | | beforeDestroy() { |
| | | // 清除定时器 |
| | | if (this.messageTimer) { |
| | | clearInterval(this.messageTimer); |
| | | } |
| | | if (this.loginCheckTimer) { |
| | | clearInterval(this.loginCheckTimer); |
| | | } |
| | | // 移除事件监听 |
| | | window.removeEventListener('storage', this.handleStorageChange); |
| | | }, |
| | | watch: { |
| | | $route(to, from) { |
| | | let title = to.meta.title || this.$t('hj224'); |
| | |
| | | console.log("slide-right"); |
| | | this.transitionName = "slide-right"; |
| | | } |
| | | |
| | | // 路由变化时,如果已登录则刷新未读消息数 |
| | | this.checkLoginAndLoadMessages(); |
| | | } |
| | | }, |
| | | data() { |
| | | return { |
| | | title: this.$t('hj224'), |
| | | hasHeader: false, |
| | | iconRight: "default", |
| | | transitionName: '', |
| | | is_Show: true, |
| | | is_foot: true, |
| | | }; |
| | | }, |
| | | methods: { |
| | | footColse() { |
| | |
| | | }, |
| | | dialogClose() { |
| | | this.$store.commit('dialogVisible', false); |
| | | }, |
| | | // 跳转到消息页面 |
| | | goToMessage() { |
| | | this.$router.push('/notify'); |
| | | }, |
| | | // 获取未读消息数 |
| | | async getUnreadCount() { |
| | | try { |
| | | console.log('开始获取未读消息数...'); |
| | | const data = await api.getUnreadCount(); |
| | | console.log('未读消息数API响应:', data); |
| | | if (data && data.status === 0) { |
| | | this.unreadCount = data.data || 0; |
| | | console.log('未读消息数:', this.unreadCount); |
| | | } else { |
| | | console.warn('获取未读消息数失败:', data ? data.msg : '响应为空'); |
| | | this.unreadCount = 0; |
| | | } |
| | | } catch (error) { |
| | | console.error('获取未读消息数异常:', error); |
| | | this.unreadCount = 0; |
| | | } |
| | | }, |
| | | // 开始轮询未读消息数(每30秒) |
| | | startMessagePolling() { |
| | | // 如果已有定时器,先清除 |
| | | if (this.messageTimer) { |
| | | clearInterval(this.messageTimer); |
| | | } |
| | | this.messageTimer = setInterval(() => { |
| | | if (this.isLoggedIn) { |
| | | this.getUnreadCount(); |
| | | } |
| | | }, 30000); |
| | | }, |
| | | // 检查登录状态并加载消息 |
| | | checkLoginAndLoadMessages() { |
| | | const token = window.localStorage.getItem("USERTOKEN"); |
| | | const isLoggedIn = !!token; |
| | | |
| | | // 如果登录状态发生变化 |
| | | if (this.lastToken !== token) { |
| | | this.lastToken = token; |
| | | |
| | | if (isLoggedIn) { |
| | | console.log('检测到登录,开始加载消息'); |
| | | this.getUnreadCount(); |
| | | this.startMessagePolling(); |
| | | } else { |
| | | console.log('检测到登出,清除消息'); |
| | | this.unreadCount = 0; |
| | | if (this.messageTimer) { |
| | | clearInterval(this.messageTimer); |
| | | this.messageTimer = null; |
| | | } |
| | | } |
| | | } else if (isLoggedIn && !this.messageTimer) { |
| | | // 如果已登录但没有启动轮询,启动它 |
| | | this.getUnreadCount(); |
| | | this.startMessagePolling(); |
| | | } |
| | | }, |
| | | // 处理localStorage变化事件 |
| | | handleStorageChange(e) { |
| | | if (e.key === 'USERTOKEN') { |
| | | this.checkLoginAndLoadMessages(); |
| | | } |
| | | } |
| | | } |
| | | }; |
| | |
| | | color: #000; |
| | | } |
| | | |
| | | /deep/.mint-tab-container {} |
| | | |
| | | /deep/.mint-tab-item { |
| | | background: #272733; |
| | |
| | | /deep/.icon-icon_A::before { |
| | | font-size: 0.6rem !important; |
| | | } |
| | | |
| | | .header-right { |
| | | display: flex; |
| | | align-items: center; |
| | | gap: 0.2rem; |
| | | } |
| | | |
| | | .message-icon-wrapper { |
| | | position: relative; |
| | | display: inline-block; |
| | | margin-right: 0.2rem; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .message-icon { |
| | | width: 0.48rem; |
| | | height: 0.48rem; |
| | | color: rgba(255, 255, 255, 0.8); |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .message-badge { |
| | | position: absolute; |
| | | top: -0.1rem; |
| | | right: -0.1rem; |
| | | min-width: 0.32rem; |
| | | height: 0.32rem; |
| | | line-height: 0.32rem; |
| | | padding: 0 0.08rem; |
| | | background-color: #ff4444; |
| | | color: #fff; |
| | | border-radius: 0.16rem; |
| | | font-size: 0.2rem; |
| | | text-align: center; |
| | | font-weight: bold; |
| | | border: 0.02rem solid #fff; |
| | | } |
| | | |
| | | #app.red-theme { |
| | | .message-icon { |
| | | color: #212121; |
| | | } |
| | | |
| | | .message-badge { |
| | | border-color: #fff; |
| | | } |
| | | } |
| | | </style> |