Files
jiapuapp/pages/notification/n01-message-center.vue
T

188 lines
5.1 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- 页面编号N-01用途读取当前账号的消息通知 -->
<template>
<view class="message-page">
<ModulePageBackground module="notification" />
<view class="page-header"><PageHeader root title="消息中心" /></view>
<view class="page-content">
<view v-if="state === 'loading'" class="state-card"
><AppLoading text="正在读取消息"
/></view>
<view v-else-if="state === 'error'" class="state-card"
><text>暂时无法读取消息</text
><AppButton
block
type="secondary"
label="重新加载"
@click="loadNotifications"
/></view>
<view v-else-if="state === 'empty'" class="state-card"
><text>暂无消息</text><text>消息列表会直接从服务端读取</text
><AppButton block label="返回我的" @click="returnToProfile"
/></view>
<view v-else class="message-list">
<text class="message-list__count"> {{ notifications.length }} 条消息</text>
<view
v-for="(item, index) in notifications"
:key="notificationKey(item, index)"
class="message-card"
>
<view class="message-card__heading"
><text>{{ notificationTitle(item) }}</text><text>消息</text></view
>
<text class="message-card__summary">{{ notificationSummary(item) }}</text>
<text v-if="notificationTime(item)" class="message-card__time">{{
notificationTime(item)
}}</text>
</view>
</view>
</view>
<AppTabbar active="profile" />
</view>
</template>
<script setup>
import { ref } from "vue";
import { onLoad, onShow, onUnload } from "@dcloudio/uni-app";
import AppButton from "@/components/AppButton.vue";
import AppLoading from "@/components/AppLoading.vue";
import AppTabbar from "@/components/AppTabbar.vue";
import ModulePageBackground from "@/components/ModulePageBackground.vue";
import PageHeader from "@/components/PageHeader.vue";
import {
appApi,
createRequestController,
isRequestCancelled,
} from "@/utils/api.js";
import { goRoot } from "@/utils/navigation.js";
const notifications = ref([]);
const state = ref("loading");
const controller = createRequestController();
let active = true;
const notificationKey = (item, index) =>
String(item?.notificationId ?? item?.id ?? index);
const notificationTitle = (item) =>
String(item?.noticeTitle ?? item?.title ?? "通知消息");
const notificationSummary = (item) =>
String(item?.noticeContent ?? item?.content ?? "点击查看消息详情");
const notificationTime = (item) =>
String(item?.publishTime ?? item?.time ?? item?.createdAt ?? "");
const loadNotifications = async () => {
controller.abort();
state.value = "loading";
try {
notifications.value = await appApi.getNotifications({
requestController: controller,
});
if (!active) return;
state.value = notifications.value.length ? "ready" : "empty";
} catch (error) {
if (!active || isRequestCancelled(error)) return;
state.value = "error";
}
};
const returnToProfile = () => goRoot("M01");
onLoad(loadNotifications);
onShow(() => {
if (state.value !== "loading") loadNotifications();
});
onUnload(() => {
active = false;
controller.abort();
});
</script>
<style scoped lang="scss">
@import "../../styles/adaptive-frame-profiles.scss";
.message-page {
display: flex;
min-height: 100vh;
flex-direction: column;
background: $paper;
}
.page-header,
.page-content {
z-index: 1;
}
.page-content {
flex: 1;
padding: 18rpx 24rpx 190rpx;
}
.state-card {
box-sizing: border-box;
min-height: 340rpx;
padding: 78rpx 52rpx 50rpx;
text-align: center;
@include adaptive-family-content;
}
.state-card text {
display: block;
}
.state-card text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: clamp(19px, 35rpx, 24px);
font-weight: 700;
}
.state-card text:nth-child(2) {
margin-top: 18rpx;
color: $ink-muted;
font-size: clamp(15px, 24rpx, 18px);
line-height: 1.65;
}
.state-card .app-button {
margin-top: 28rpx;
}
.message-list {
display: flex;
flex-direction: column;
gap: 16rpx;
}
.message-list__count {
display: block;
color: $ink-muted;
font-size: clamp(13px, 21rpx, 16px);
}
.message-card {
padding: 28rpx 34rpx;
@include adaptive-family-content;
}
.message-card__heading {
display: grid;
grid-template-columns: minmax(0, 1fr) auto;
align-items: center;
gap: 16rpx;
}
.message-card__heading text:first-child {
color: $ink;
font-family: STKaiti, KaiTi, serif;
font-size: clamp(17px, 30rpx, 22px);
font-weight: 700;
overflow-wrap: anywhere;
}
.message-card__heading text:last-child {
color: $brand-red;
font-size: clamp(13px, 21rpx, 16px);
}
.message-card__summary,
.message-card__time {
display: block;
}
.message-card__summary {
display: -webkit-box;
margin-top: 12rpx;
overflow: hidden;
color: $ink-muted;
font-size: clamp(14px, 22rpx, 17px);
line-height: 1.55;
overflow-wrap: anywhere;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
}
.message-card__time {
margin-top: 12rpx;
color: #8b7d6c;
font-size: clamp(13px, 20rpx, 16px);
}
</style>