mrr.sj.front/pages/notice/notice_list.vue

213 lines
5.0 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.

<template>
<view class="notice-page">
<!-- 自定义顶部导航组件 -->
<custom-navbar title="公告通知" :showBack="true" backgroundColor="#FFFFFF" :show-headle="true"
headleSrc="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/51ebca5d-95c5-4fb8-8aa3-560a79100d25.png"
@onHeadleClick="goToSearch" class="nav-img-size" />
<view class="page-content">
<!-- 加载状态 -->
<view v-if="loading" class="loading-container">
<view class="loading-icon"></view>
<text class="loading-text">加载中...</text>
</view>
<!-- 公告列表 -->
<view v-else-if="noticeList.length > 0" class="notice-list">
<NoticeCard v-for="item in noticeList" :key="item.id" :item="item" @click="goToDetail" />
<!-- 加载更多状态 -->
<view v-if="loadingMore" class="load-more">
<text>加载更多...</text>
</view>
<view v-else-if="!hasMore && noticeList.length > 0" class="no-more">
<text>没有更多了</text>
</view>
</view>
<!-- 空状态 -->
<view v-else class="empty-container">
<image class="empty-img"
src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/8c5e7b2a-3d4f-4b1e-9a7c-6e8f2d1b4a5c.png"
mode="aspectFit"></image>
<text class="empty-text">暂无公告通知</text>
</view>
</view>
</view>
</template>
<script>
import CustomNavbar from '@/components/custom-navbar/custom-navbar.vue';
import NoticeCard from '@/pages/home/components/notice-card.vue';
import request from '@/utils/request';
export default {
components: {
CustomNavbar,
NoticeCard // 注册组件
},
data() {
return {
loading: false,
loadingMore: false,
noticeList: [],
page: 1,
limit: 10,
total: 0,
hasMore: true
};
},
onLoad() {
this.fetchNoticeList(true);
},
onPullDownRefresh() {
this.fetchNoticeList(true);
},
onReachBottom() {
if (!this.loadingMore && this.hasMore && !this.loading) {
this.fetchNoticeList(false);
}
},
methods: {
// 跳转搜索页
goToSearch() {
uni.navigateTo({
url: '/pages/search_common/search?type=notice'
});
},
// 获取公告列表
fetchNoticeList(reset = true) {
if (reset) {
this.page = 1;
this.hasMore = true;
this.loading = true;
} else {
if (!this.hasMore) return;
this.loadingMore = true;
// 非重置时页码+1
this.page++;
}
request.post('/sj/notice/list', {
page: this.page,
limit: this.limit
}).then(res => {
if (res.code === 200 && res.data) {
const list = res.data.list || [];
const total = res.data.total || 0;
this.total = total;
if (reset) {
this.noticeList = list;
} else {
this.noticeList = [...this.noticeList, ...list];
}
// 判断是否还有更多数据
this.hasMore = this.noticeList.length < total;
} else {
if (reset) this.noticeList = [];
this.hasMore = false;
// 非重置且请求失败时回滚页码
if (!reset && this.page > 1) this.page--;
}
}).catch(err => {
console.error('获取公告列表失败:', err);
if (!reset && this.page > 1) this.page--; // 回滚页码
uni.showToast({
title: '加载失败,请稍后重试',
icon: 'none'
});
}).finally(() => {
this.loading = false;
this.loadingMore = false;
if (reset) {
uni.stopPullDownRefresh();
}
});
},
// 跳转到详情页(接收 NoticeCard 组件 $emit 传递的 item
goToDetail(item) {
if (item.id) {
uni.navigateTo({
url: `/pages/notice/detail?id=${item.id}`
});
}
}
}
};
</script>
<style lang="scss" scoped>
.notice-page {
min-height: 100vh;
background-color: #f5f6f8;
}
.page-content {
padding: 20rpx 20rpx 40rpx;
}
.loading-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 120rpx 0;
.loading-icon {
width: 60rpx;
height: 60rpx;
border: 4rpx solid #e0e0e0;
border-top-color: #FF4767;
border-radius: 50%;
animation: spin 0.8s linear infinite;
margin-bottom: 20rpx;
}
.loading-text {
font-size: 26rpx;
color: #999;
}
}
@keyframes spin {
to {
transform: rotate(360deg);
}
}
.load-more,
.no-more {
text-align: center;
padding: 30rpx 0;
font-size: 24rpx;
color: #999;
}
.empty-container {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
padding: 150rpx 0;
.empty-img {
width: 200rpx;
height: 200rpx;
margin-bottom: 30rpx;
opacity: 0.6;
}
.empty-text {
font-size: 28rpx;
color: #999;
}
}
.nav-img-size::v-deep .icon-headle {
width: 36rpx !important;
height: 36rpx !important;
}
</style>