新增公告弹窗功能,优化公告检查逻辑,支持今日不再弹出设置,提升用户体验
This commit is contained in:
@@ -45,10 +45,37 @@
|
||||
ID: {{ machineId || 'N/A' }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 公告弹窗(仅在游戏页面显示) -->
|
||||
<el-dialog
|
||||
v-model="announcementVisible"
|
||||
title="代理商公告"
|
||||
:width="'90%'"
|
||||
:before-close="handleAnnouncementClose"
|
||||
class="announcement-dialog"
|
||||
>
|
||||
<div v-if="announcement" class="announcement-content">
|
||||
<h3 class="announcement-title">{{ announcement.title }}</h3>
|
||||
<div class="announcement-text">{{ announcement.content }}</div>
|
||||
</div>
|
||||
<div v-else class="announcement-empty">
|
||||
暂无公告内容
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="announcement-footer">
|
||||
<el-checkbox v-model="dontShowToday" class="dont-show-checkbox">
|
||||
今日不再弹出
|
||||
</el-checkbox>
|
||||
<el-button type="primary" @click="handleAnnouncementClose">确定</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { onMounted, ref, watch } from 'vue'
|
||||
import { getAnnouncementByCode } from '@/api/announcement'
|
||||
export default {
|
||||
name: 'GamePage',
|
||||
props: {
|
||||
@@ -106,6 +133,94 @@ export default {
|
||||
timestamp: Date.now()
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
const announcementVisible = ref(false)
|
||||
const announcement = ref(null)
|
||||
const dontShowToday = ref(false)
|
||||
|
||||
const getStorageKey = (codeNo, announcementId) => {
|
||||
return `announcement_dismissed_${codeNo}_${announcementId}`
|
||||
}
|
||||
|
||||
const getTodayKey = (codeNo) => {
|
||||
const today = new Date().toDateString()
|
||||
return `announcement_dont_show_today_${codeNo}_${today}`
|
||||
}
|
||||
|
||||
const isDismissedPermanently = (codeNo, announcementId) => {
|
||||
const key = getStorageKey(codeNo, announcementId)
|
||||
return localStorage.getItem(key) === 'true'
|
||||
}
|
||||
|
||||
const isDontShowToday = (codeNo) => {
|
||||
const key = getTodayKey(codeNo)
|
||||
return localStorage.getItem(key) === 'true'
|
||||
}
|
||||
|
||||
const markDismissedPermanently = (codeNo, announcementId) => {
|
||||
const key = getStorageKey(codeNo, announcementId)
|
||||
localStorage.setItem(key, 'true')
|
||||
}
|
||||
|
||||
const markDontShowToday = (codeNo) => {
|
||||
const key = getTodayKey(codeNo)
|
||||
localStorage.setItem(key, 'true')
|
||||
}
|
||||
|
||||
const checkAnnouncement = async (codeNo) => {
|
||||
if (!codeNo) return
|
||||
if (isDontShowToday(codeNo)) return
|
||||
try {
|
||||
const response = await getAnnouncementByCode(codeNo)
|
||||
if (response.data && response.data.success && response.data.data && response.data.data.length > 0) {
|
||||
const announcementData = response.data.data[0]
|
||||
if (announcementData.enabled) {
|
||||
const dismissed = isDismissedPermanently(codeNo, announcementData.id)
|
||||
if (!dismissed) {
|
||||
announcement.value = announcementData
|
||||
announcementVisible.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取公告失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleAnnouncementClose = () => {
|
||||
const codeNo = props.codeNo
|
||||
const announcementData = announcement.value
|
||||
if (dontShowToday.value && codeNo) {
|
||||
markDontShowToday(codeNo)
|
||||
}
|
||||
if (announcementData && codeNo) {
|
||||
markDismissedPermanently(codeNo, announcementData.id)
|
||||
}
|
||||
announcementVisible.value = false
|
||||
dontShowToday.value = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
// 仅在进入 GamePage 时检查公告
|
||||
setTimeout(() => checkAnnouncement(props.codeNo), 1000)
|
||||
})
|
||||
|
||||
watch(
|
||||
() => props.codeNo,
|
||||
(newCode) => {
|
||||
if (newCode) {
|
||||
checkAnnouncement(newCode)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
return {
|
||||
announcementVisible,
|
||||
announcement,
|
||||
dontShowToday,
|
||||
handleAnnouncementClose
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
remainingPoints() {
|
||||
const total = this.totalPoints || 0
|
||||
@@ -235,6 +350,50 @@ export default {
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.announcement-dialog {
|
||||
:deep(.el-dialog__body) {
|
||||
padding: 16px 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.announcement-content {
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.announcement-title {
|
||||
color: #333;
|
||||
font-size: 18px;
|
||||
margin-bottom: 16px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
.announcement-text {
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
line-height: 1.6;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.announcement-empty {
|
||||
text-align: center;
|
||||
color: #999;
|
||||
padding: 20px 0;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.announcement-footer {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.dont-show-checkbox {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.tab-item {
|
||||
padding: 10px 8px;
|
||||
|
||||
Reference in New Issue
Block a user