mirror of
https://github.com/ialley-workshop-open/uni-halo.git
synced 2026-09-12 16:40:40 +08:00
629b1f9219
- 拆分维护接口类型,新增notice和description字段区分纯文本说明与富文本详情 - 重构useMaintenanceIntercept钩子,统一维护拦截逻辑 - 新增维护详情弹窗组件,优化维护页UI与交互 - 修复按钮布局、滚动置顶黑名单等细节问题 - 优化公告弹窗组件样式与代码结构
138 lines
3.9 KiB
Vue
138 lines
3.9 KiB
Vue
<script lang="ts" setup>
|
||
import { onMounted, ref } from 'vue'
|
||
import { getNoticeLatest } from '@/api/uni-halo'
|
||
import { getCache, setCache } from '@/utils/storage'
|
||
import type { INoticeListVo } from '@/api/types/uni-halo'
|
||
|
||
const HIDDEN_KEY_PREFIX = 'notice_latest_hidden'
|
||
|
||
const isShow = ref(false)
|
||
const notice = ref<INoticeListVo | null>(null)
|
||
const checking = ref(false)
|
||
|
||
function todayKey(name: string): string {
|
||
const date = new Date()
|
||
const pad = (n: number) => String(n).padStart(2, '0')
|
||
return `${HIDDEN_KEY_PREFIX}_${name}_${date.getFullYear()}${pad(date.getMonth() + 1)}${pad(date.getDate())}`
|
||
}
|
||
|
||
function formatDate(value?: string): string {
|
||
if (!value)
|
||
return ''
|
||
const date = new Date(value)
|
||
if (Number.isNaN(date.getTime()))
|
||
return ''
|
||
const pad = (n: number) => String(n).padStart(2, '0')
|
||
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
|
||
}
|
||
|
||
async function handleCheckLatest() {
|
||
if (checking.value)
|
||
return
|
||
checking.value = true
|
||
try {
|
||
const res = await getNoticeLatest()
|
||
const latest = res.data
|
||
if (!latest?.name || !latest.title)
|
||
return
|
||
// 今日已看过则不再打扰
|
||
if (getCache<string>(todayKey(latest.name)))
|
||
return
|
||
notice.value = latest
|
||
isShow.value = true
|
||
}
|
||
catch (err) {
|
||
console.error('获取最新公告失败', err)
|
||
}
|
||
finally {
|
||
checking.value = false
|
||
}
|
||
}
|
||
|
||
/** 仅关闭(不记录,下次进入可再弹) */
|
||
function handleClose() {
|
||
isShow.value = false
|
||
}
|
||
|
||
/** 今日不再提醒:记录后关闭 */
|
||
function handleDismissForever() {
|
||
if (notice.value?.name) {
|
||
setCache(todayKey(notice.value.name), '1')
|
||
}
|
||
isShow.value = false
|
||
}
|
||
|
||
/** 查看全文:记录今日已看并跳公告详情页 */
|
||
function handleViewAll() {
|
||
if (notice.value?.name) {
|
||
setCache(todayKey(notice.value.name), '1')
|
||
const detailName = notice.value.name
|
||
isShow.value = false
|
||
uni.navigateTo({ url: `/pages-blog/notice/detail?name=${detailName}` })
|
||
}
|
||
}
|
||
|
||
onMounted(() => {
|
||
handleCheckLatest()
|
||
})
|
||
</script>
|
||
|
||
<template>
|
||
<wd-popup
|
||
v-model="isShow"
|
||
position="center"
|
||
custom-class="rounded-xl"
|
||
z-index="9999"
|
||
@close="handleClose"
|
||
>
|
||
<view v-if="notice" class="box-border w-[80vw] p-6">
|
||
<!-- 头部:标题 + 关闭 -->
|
||
<view class="flex items-center justify-between">
|
||
<view class="flex items-center gap-2">
|
||
<text class="text-sm">
|
||
📢
|
||
</text>
|
||
<text class="text-md font-bold text-gray-900">
|
||
最新公告
|
||
</text>
|
||
<view
|
||
v-if="notice.typeDisplayName"
|
||
class="rounded px-1.5 py-0.5 text-xs"
|
||
:style="{
|
||
color: notice.typeColor || '#f83856',
|
||
backgroundColor: notice.typeColor ? `${notice.typeColor}1a` : '#fdeef1',
|
||
}"
|
||
>
|
||
{{ notice.typeDisplayName }}
|
||
</view>
|
||
</view>
|
||
<view class="flex h-8 w-8 items-center justify-center text-gray-500" @click="handleClose">
|
||
<wd-icon name="close" size="16px" />
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 内容 -->
|
||
<view class="mt-4">
|
||
<view class="text-[32rpx] font-bold leading-snug text-[#222]">
|
||
{{ notice.title }}
|
||
</view>
|
||
<view v-if="notice.summary" class="mt-3 text-[26rpx] leading-relaxed text-gray-500">
|
||
{{ notice.summary }}
|
||
</view>
|
||
<view v-if="notice.publishTime" class="mt-3 text-[22rpx] text-gray-400">
|
||
日期:{{ formatDate(notice.publishTime) }}
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 操作 -->
|
||
<view class="box-border mt-4 flex items-center justify-between pt-4">
|
||
<view class="text-xs text-gray-600 " @click="handleDismissForever">
|
||
今日不再提醒
|
||
</view>
|
||
<uh-button custom-class="font-semibold text-xs" @click="handleViewAll">
|
||
查看全文 →
|
||
</uh-button>
|
||
</view>
|
||
</view>
|
||
</wd-popup>
|
||
</template> |