<template>
|
<div id="app" :class="`${$state.theme === 'red' ? 'red-theme' : 'black-theme'}`">
|
<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 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>
|
</div>
|
<div class="body-box">
|
<transition :name="transitionName">
|
<router-view></router-view>
|
</transition>
|
</div>
|
<foot v-if="$route.meta.show !== true" @close="footColse"></foot>
|
<elalert></elalert>
|
<!-- <loginPopup @close="dialogClose" /> -->
|
</div>
|
</template>
|
|
<script>
|
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";
|
|
export default {
|
components: {
|
foot,
|
elalert,
|
loginPopup
|
},
|
name: "App",
|
created() {
|
this.$state.theme = "red";
|
console.log(this.$state.theme, "asdasdasd")
|
let title = this.$route.meta.title || this.$t('hj224');
|
this.title = title;
|
if (this.$route.meta.is_Show) {
|
this.is_Show = this.$route.meta.is_Show;
|
} else {
|
this.is_Show = true;
|
}
|
if (this.$route.meta.hasHeader) {
|
this.hasHeader = true;
|
} else {
|
this.hasHeader = false;
|
}
|
if (this.$route.meta.iconRight) {
|
this.iconRight = this.$route.meta.iconRight;
|
} else {
|
this.iconRight = "default";
|
}
|
// 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');
|
this.title = title;
|
if (to.meta.iconRight) {
|
this.iconRight = to.meta.iconRight;
|
} else {
|
this.iconRight = "default";
|
}
|
if (to.meta.hasHeader) {
|
this.hasHeader = true;
|
} else {
|
this.hasHeader = false;
|
}
|
|
if (to.meta.index > from.meta.index) {
|
console.log("slide-left");
|
//设置动画名称
|
this.transitionName = "slide-left";
|
} else {
|
console.log("slide-right");
|
this.transitionName = "slide-right";
|
}
|
|
// 路由变化时,如果已登录则刷新未读消息数
|
this.checkLoginAndLoadMessages();
|
}
|
},
|
methods: {
|
footColse() {
|
this.$store.commit('dialogVisible', true);
|
},
|
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();
|
}
|
}
|
}
|
};
|
</script>
|
|
<style lang="less" scoped>
|
// 全局隐藏滚动条
|
/deep/ html,
|
/deep/ body {
|
scrollbar-width: none; /* Firefox */
|
-ms-overflow-style: none; /* IE and Edge */
|
&::-webkit-scrollbar {
|
display: none; /* Chrome, Safari, Opera */
|
width: 0;
|
height: 0;
|
}
|
}
|
|
/deep/ .van-list__finished-text {
|
line-height: 1.925926rem !important;
|
}
|
|
/deep/ .van-list__error-text {
|
line-height: 1.925926rem !important;
|
}
|
|
#app {
|
width: 100vw;
|
height: 100vh;
|
overflow: hidden;
|
font-family: "rubik";
|
|
.header-box {
|
width: 100%;
|
height: 1.4rem;
|
|
/deep/.mint-header {
|
height: 100%;
|
background-color: #16171d;
|
|
// background-color: rgba(20, 45, 55, 0.3);
|
.is-left {
|
.mintui {
|
font-size: 20px;
|
}
|
}
|
|
.mint-header-title {
|
font-size: 0.36rem;
|
color: rgba(255, 255, 255, 1);
|
}
|
}
|
|
button {
|
outline: none;
|
}
|
}
|
|
.body-box {
|
width: 100%;
|
height: 100%;
|
// height: calc(100% - 1rem);
|
box-sizing: border-box;
|
overflow-y: auto;
|
// 隐藏滚动条
|
scrollbar-width: none; /* Firefox */
|
-ms-overflow-style: none; /* IE and Edge */
|
&::-webkit-scrollbar {
|
display: none; /* Chrome, Safari, Opera */
|
width: 0;
|
height: 0;
|
}
|
}
|
|
&.red-theme {
|
background: #fff;
|
color: #000;
|
|
/deep/.mint-header {
|
background: none;
|
|
.mint-header-title {
|
font-size: 0.42rem;
|
color: #212121;
|
}
|
|
.mintui {
|
color: #212121;
|
}
|
}
|
|
/deep/.van-swipe-item {
|
color: #000;
|
}
|
|
/deep/.navs_content {
|
background: #fff !important;
|
}
|
|
/deep/.fo_content {
|
background: #fff;
|
}
|
|
/deep/.news-tab {
|
background: #fff;
|
}
|
|
/deep/.mint-tab-item-label {
|
color: #000;
|
font-size: .26rem;
|
|
}
|
|
/deep/.top_title {
|
color: #000;
|
}
|
|
/deep/.titContent {
|
color: #000;
|
}
|
|
/deep/.mint-navbar {
|
background: #fff;
|
}
|
|
/deep/.mint-tab-item {
|
background: #fff;
|
border: none;
|
}
|
|
/deep/.footCss {
|
background: #f5f5f5;
|
}
|
|
/deep/.newDetail-tits {
|
color: #aaa;
|
}
|
|
/deep/.van-skeleton__row,
|
.van-skeleton__title {
|
background-color: #fff !important;
|
}
|
}
|
|
&.black-theme {
|
// background: #16171d;
|
// background: rgb(14, 14, 15);
|
background: rgb(33, 33, 43);
|
|
/deep/.navs_content {
|
background: #272733;
|
}
|
|
/deep/.fo_content {
|
background: #272733;
|
}
|
|
/deep/.news-tab {
|
background: #272733;
|
}
|
|
/deep/.mint-navbar {
|
background: #272733;
|
}
|
|
/deep/.mint-tab-item-label {
|
color: #fff;
|
font-size: .26rem;
|
|
}
|
|
/deep/.titContent {
|
color: #000;
|
}
|
|
|
/deep/.mint-tab-item {
|
background: #272733;
|
}
|
|
/deep/.van-swipe-item {
|
color: #000;
|
}
|
|
/deep/.footCss {
|
background: rgb(33, 33, 43);
|
}
|
|
/deep/.newDetail-tits {
|
color: #999;
|
}
|
}
|
}
|
|
.search-right {
|
width: 0.3rem;
|
height: 0.3rem;
|
}
|
|
.mint-search-list {
|
position: relative !important;
|
}
|
|
.topLeft {}
|
|
/deep/.el-alert {
|
width: 75% !important;
|
height: 1.1rem !important;
|
position: absolute !important;
|
top: 0 !important;
|
bottom: 0 !important;
|
left: 0 !important;
|
right: 0 !important;
|
margin: auto !important;
|
font-size: 0.36rem !important;
|
}
|
|
/deep/.el-alert__title {
|
font-size: 0.36rem !important;
|
}
|
|
/deep/.el-icon-close::before {
|
display: none;
|
}
|
|
/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>
|
|
<style lang="less">
|
/* 全局隐藏滚动条 - 确保整个项目都不显示滚动条 */
|
html,
|
body {
|
scrollbar-width: none; /* Firefox */
|
-ms-overflow-style: none; /* IE and Edge */
|
}
|
|
html::-webkit-scrollbar,
|
body::-webkit-scrollbar {
|
display: none; /* Chrome, Safari, Opera */
|
width: 0;
|
height: 0;
|
}
|
|
/* 隐藏所有元素的滚动条 */
|
* {
|
scrollbar-width: none; /* Firefox */
|
-ms-overflow-style: none; /* IE and Edge */
|
}
|
|
*::-webkit-scrollbar {
|
display: none; /* Chrome, Safari, Opera */
|
width: 0;
|
height: 0;
|
}
|
</style>
|