185 lines
5.1 KiB
Vue
185 lines
5.1 KiB
Vue
<template>
|
||
<view class="content column">
|
||
<view class="row" style="width: 90%; margin: 100rpx auto 0; justify-content: space-between;">
|
||
<image src="/static/back.png" style="width: 40rpx; height: 40rpx;" @click="goBack()" mode=""></image>
|
||
<text style="font-size: 30rpx;">我的消息</text>
|
||
<view style="width: 40rpx;"></view>
|
||
</view>
|
||
|
||
<view class="row" style="width: 100%; margin-top: 40rpx; margin-left: 56rpx;">
|
||
<view class="center" @click="clickTab(index)"
|
||
style="margin-right: 20rpx; width: 134rpx; height: 48rpx; font-size: 26rpx; border-radius: 34rpx;"
|
||
:style="setBgColor(index)" v-for="(item,index) in teabList">
|
||
{{item}}
|
||
</view>
|
||
</view>
|
||
|
||
<view class="" style="width: 100%; height: 1rpx; background-color: #EBEBEB; margin-top: 20rpx;"></view>
|
||
|
||
<view class="column"
|
||
style="width: 100%; flex: 1; margin-top: 20rpx; overflow-y: auto;">
|
||
<!-- 消息列表 -->
|
||
<view class="column" v-for="(item,index) in messageList" :key="item.id"
|
||
style="width: 686rpx; margin: 0rpx auto 30rpx; background-color: white; border-radius: 32rpx; padding: 22rpx 30rpx 10rpx;">
|
||
<!-- 消息标题 -->
|
||
<view class="row" style="align-items: center; justify-content: space-between;">
|
||
<text style="font-size: 32rpx; font-weight: bold;">{{ item.title || '无标题' }}</text>
|
||
<!-- 未读标识 -->
|
||
<view v-if="!item.isRead"
|
||
style="width: 16rpx; height: 16rpx; background-color: #FF3B30; border-radius: 50%;"></view>
|
||
</view>
|
||
|
||
<!-- 消息正文 -->
|
||
<text style="font-size: 28rpx; margin-top: 10rpx; color: #666; line-height: 1.6;">
|
||
{{ item.content || '暂无内容' }}
|
||
</text>
|
||
|
||
<!-- 消息时间 -->
|
||
<text style="font-size: 24rpx; margin-top: 20rpx; margin-left: auto; color: #999;">
|
||
{{ formatTime(item.createTime) }}
|
||
</text>
|
||
</view>
|
||
|
||
<!-- 空数据提示 -->
|
||
<view v-if="!loading && messageList.length === 0"
|
||
class="column center" style="width: 100%; padding-top: 200rpx;">
|
||
<image src="/static/no_content.png" style="width: 200rpx; height: 200rpx;" mode=""></image>
|
||
<text style="font-size: 28rpx; color: #999; margin-top: 30rpx;">暂无消息</text>
|
||
</view>
|
||
|
||
<!-- 加载提示 -->
|
||
<view v-if="loading" class="center" style="width: 100%; padding: 40rpx 0;">
|
||
<text style="font-size: 28rpx; color: #999;">加载中...</text>
|
||
</view>
|
||
</view>
|
||
|
||
|
||
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import { getMessageList, markAllAsRead } from '@/common/server/interface/message.js'
|
||
|
||
export default {
|
||
data() {
|
||
return {
|
||
currentIndex: 0,
|
||
teabList: ["全部", "私信"],
|
||
messageList: [],
|
||
pageIndex: 1,
|
||
pageSize: 20,
|
||
loading: false,
|
||
hasMore: true
|
||
}
|
||
},
|
||
onLoad() {
|
||
// 页面加载时获取消息列表
|
||
this.loadMessageList();
|
||
// 标记所有消息为已读
|
||
this.markMessagesRead();
|
||
},
|
||
methods: {
|
||
// 返回上一页
|
||
goBack() {
|
||
uni.navigateBack({
|
||
delta: 1
|
||
})
|
||
},
|
||
|
||
setBgColor(index) {
|
||
if (this.currentIndex == index) {
|
||
return {
|
||
backgroundColor: '#C4FFDF',
|
||
color: '#00AC4E',
|
||
border: 'solid 1rpx #00AC4E',
|
||
}
|
||
} else {
|
||
return {
|
||
backgroundColor: '#FFFFFF',
|
||
color: '#000000',
|
||
border: 'solid 1rpx #EBEBEB',
|
||
}
|
||
}
|
||
},
|
||
|
||
clickTab(index) {
|
||
this.currentIndex = index;
|
||
// 切换标签时重新加载消息列表
|
||
this.pageIndex = 1;
|
||
this.hasMore = true;
|
||
this.loadMessageList();
|
||
},
|
||
|
||
/**
|
||
* 加载消息列表
|
||
*/
|
||
async loadMessageList() {
|
||
if (this.loading) return;
|
||
|
||
try {
|
||
this.loading = true;
|
||
// messageType: 0=全部,1=私信
|
||
const messageType = this.currentIndex;
|
||
const data = await getMessageList(this.pageIndex, this.pageSize, messageType);
|
||
|
||
if (this.pageIndex === 1) {
|
||
this.messageList = data || [];
|
||
} else {
|
||
this.messageList = [...this.messageList, ...(data || [])];
|
||
}
|
||
|
||
// 判断是否还有更多数据
|
||
this.hasMore = data && data.length >= this.pageSize;
|
||
|
||
} catch (error) {
|
||
console.error('获取消息列表失败:', error);
|
||
uni.showToast({
|
||
title: '获取消息失败',
|
||
icon: 'none'
|
||
});
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 标记所有消息为已读
|
||
*/
|
||
async markMessagesRead() {
|
||
try {
|
||
await markAllAsRead();
|
||
} catch (error) {
|
||
console.error('标记已读失败:', error);
|
||
}
|
||
},
|
||
|
||
/**
|
||
* 格式化时间显示
|
||
*/
|
||
formatTime(createTime) {
|
||
if (!createTime) return '';
|
||
// 如果是时间戳,转换为日期字符串
|
||
if (typeof createTime === 'number') {
|
||
const date = new Date(createTime);
|
||
const year = date.getFullYear();
|
||
const month = String(date.getMonth() + 1).padStart(2, '0');
|
||
const day = String(date.getDate()).padStart(2, '0');
|
||
const hour = String(date.getHours()).padStart(2, '0');
|
||
const minute = String(date.getMinutes()).padStart(2, '0');
|
||
return `${year}/${month}/${day} ${hour}:${minute}`;
|
||
}
|
||
// 如果已经是格式化字符串,直接返回
|
||
return createTime.replace(/-/g, '/');
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.content {
|
||
width: 100%;
|
||
height: 100vh;
|
||
background: #F7F7F7;
|
||
}
|
||
</style> |