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

298 lines
7.4 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="addAddress">
</custom-navbar>
<!-- 主要内容区域 -->
<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">
<view
class="notice-item"
v-for="(item, index) in noticeList"
:key="item.id"
@tap="goToDetail(item)"
>
<view class="item-main">
<text class="item-title line-2">{{ item.title }}</text>
<view class="item-time">
<text class="time-text">发布时间:{{ formatTime(item.create_time) }}</text>
</view>
</view>
<!-- <image class="arrow-icon" src="https://mrrplus.oss-cn-beijing.aliyuncs.com/photo/system/ee119e24-1cb2-43df-86e6-61af8e9fd0ad.png" mode="aspectFit"></image> -->
</view>
<!-- 加载更多状态 -->
<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 request from '@/utils/request';
export default {
components: {
CustomNavbar
},
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: {
// 获取公告列表
fetchNoticeList(reset = true) {
if (reset) {
this.page = 1;
this.hasMore = true;
this.loading = true;
} else {
if (!this.hasMore) return;
this.loadingMore = true;
}
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;
// 如果还有更多数据页码加1
if (this.hasMore && !reset) {
this.page++;
}
} else {
if (reset) this.noticeList = [];
this.hasMore = false;
}
}).catch(err => {
console.error('获取公告列表失败:', err);
if (reset) this.noticeList = [];
uni.showToast({
title: '加载失败,请稍后重试',
icon: 'none'
});
}).finally(() => {
this.loading = false;
this.loadingMore = false;
// 停止下拉刷新
if (reset) {
uni.stopPullDownRefresh();
}
});
},
// 格式化时间
formatTime(timeStr) {
if (!timeStr) return '--:--:--';
// 处理多种时间格式2026-06-10 15:00:00 或 2026.06.1015:00:00
let formatted = timeStr;
// 如果是点分隔的格式,转换为标准格式
if (timeStr.includes('.') && !timeStr.includes('-')) {
formatted = timeStr.replace(/\./g, '-');
// 处理日期和时间连在一起的情况,如 "2026.06.1015:00:00" -> "2026-06-10 15:00:00"
if (formatted.match(/\d{4}-\d{2}-\d{2}\d{2}:\d{2}:\d{2}/)) {
formatted = formatted.replace(/(\d{4}-\d{2}-\d{2})(\d{2}:\d{2}:\d{2})/, '$1 $2');
}
}
// 如果已经是标准格式,直接返回
if (formatted.includes('-') && formatted.includes(':')) {
return formatted;
}
return timeStr;
},
// 跳转到详情页
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); }
}
// 公告列表
.notice-list {
.notice-item {
display: flex;
align-items: center;
justify-content: space-between;
background: #ffffff;
border-radius: 20rpx;
padding: 30rpx;
margin-bottom: 20rpx;
// box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.04);
transition: all 0.2s ease;
.item-main {
flex: 1;
min-width: 0; // 防止文字溢出
.item-title {
font-size: 30rpx;
font-weight: 500;
color: #101010;
line-height: 42rpx;
margin-bottom: 16rpx;
}
.item-time {
display: flex;
align-items: center;
.time-icon {
width: 24rpx;
height: 24rpx;
margin-right: 8rpx;
opacity: 0.6;
}
.time-text {
font-size: 22rpx;
color: #999;
line-height: 30rpx;
}
}
}
}
}
// 加载更多
.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;
}
}
// 多行省略
.line-2 {
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 2;
overflow: hidden;
word-break: break-all;
}
::v-deep .icon-headle {
width: 32rpx !important;
height: 32rpx !important;
}
</style>