<template>
|
<view class="message-container">
|
<view class="message-header">
|
<view class="header-title">消息中心</view>
|
</view>
|
|
<scroll-view class="message-list-scroll" scroll-y="true">
|
<view class="message-list">
|
<!-- 未读消息在前 -->
|
<view
|
class="message-item"
|
v-for="message in sortedMessages"
|
:key="message.messageId"
|
@click="viewMessageDetail(message)"
|
>
|
<view class="message-main">
|
<view class="message-title">
|
<text class="title-text">{{ getMessageTypeText(message.messageType) }}</text>
|
<view class="unread-dot" v-if="message.isRead === '0'"></view>
|
</view>
|
<view class="message-content">{{ message.messageContent }}</view>
|
<view class="message-time">{{ message.createTime }}</view>
|
</view>
|
</view>
|
|
<view class="no-data" v-if="sortedMessages.length === 0">
|
<uni-icons type="info" size="40" color="#ccc"></uni-icons>
|
<text>暂无消息</text>
|
</view>
|
</view>
|
</scroll-view>
|
</view>
|
</template>
|
|
<script>
|
import { getMyMessages, markAsRead } from '@/api/message'
|
|
export default {
|
data() {
|
return {
|
// 消息列表
|
messages: [],
|
loading: false
|
}
|
},
|
computed: {
|
// 按未读/已读排序,未读的在前面
|
sortedMessages() {
|
return [...this.messages].sort((a, b) => {
|
if (a.isRead === b.isRead) {
|
// 相同状态按时间倒序
|
return new Date(b.createTime) - new Date(a.createTime);
|
}
|
// 未读的排在前面
|
return a.isRead === '0' ? -1 : 1;
|
});
|
}
|
},
|
onLoad() {
|
this.loadMessages()
|
},
|
onShow() {
|
// 每次显示页面时刷新消息
|
this.loadMessages()
|
// 更新TabBar徽标
|
this.updateTabBarBadge()
|
},
|
onPullDownRefresh() {
|
this.loadMessages().then(() => {
|
uni.stopPullDownRefresh()
|
})
|
},
|
methods: {
|
// 加载消息列表
|
async loadMessages() {
|
try {
|
this.loading = true
|
const response = await getMyMessages()
|
if (response.code === 200) {
|
this.messages = response.data || []
|
} else {
|
this.$modal.showToast(response.msg || '加载消息失败')
|
}
|
} catch (error) {
|
console.error('加载消息失败:', error)
|
this.$modal.showToast('加载消息失败')
|
} finally {
|
this.loading = false
|
}
|
},
|
|
// 获取消息类型文本
|
getMessageTypeText(type) {
|
const typeMap = {
|
'CREATE': '创建成功',
|
'PUSH': '任务推送',
|
'STATUS': '状态变更',
|
'ASSIGN': '任务分配'
|
}
|
return typeMap[type] || '系统消息';
|
},
|
|
// 查看消息详情(跳转到任务详情)
|
async viewMessageDetail(message) {
|
try {
|
// 校验消息对象
|
if (!message || !message.messageId) {
|
console.error('消息数据异常:', message)
|
this.$modal.showToast('消息数据异常')
|
return
|
}
|
|
// 标记为已读
|
if (message.isRead === '0') {
|
await markAsRead(message.messageId)
|
message.isRead = '1'
|
// 更新徽标
|
this.updateTabBarBadge()
|
}
|
|
// 跳转到任务详情页面
|
if (message.taskId) {
|
this.$tab.navigateTo(`/pages/task/detail?id=${message.taskId}`)
|
} else {
|
this.$modal.showToast('无法找到关联任务')
|
}
|
} catch (error) {
|
console.error('标记消息已读失败:', error)
|
// 即使标记失败,也允许跳转
|
if (message && message.taskId) {
|
this.$tab.navigateTo(`/pages/task/detail?id=${message.taskId}`)
|
}
|
}
|
},
|
|
// 更新TabBar徽标
|
updateTabBarBadge() {
|
const unreadCount = this.messages.filter(msg => msg.isRead === '0').length
|
console.log('未读消息数量:', unreadCount)
|
|
if (unreadCount > 0) {
|
uni.setTabBarBadge({
|
index: 3, // 消息页面在tabBar中的索引
|
text: unreadCount > 99 ? '99+' : unreadCount.toString()
|
})
|
} else {
|
uni.removeTabBarBadge({
|
index: 3
|
})
|
}
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss">
|
.message-container {
|
padding: 20rpx;
|
background-color: #f5f5f5;
|
height: 100vh;
|
display: flex;
|
flex-direction: column;
|
// 隐藏滚动条但保持滚动功能
|
::-webkit-scrollbar {
|
display: none;
|
width: 0 !important;
|
height: 0 !important;
|
background: transparent;
|
}
|
|
// Firefox滚动条隐藏
|
* {
|
scrollbar-width: none; /* Firefox */
|
}
|
|
// IE/Edge滚动条隐藏
|
* {
|
-ms-overflow-style: none; /* IE 10+ */
|
}
|
}
|
|
.message-header {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
padding: 20rpx 0;
|
flex-shrink: 0; // 防止收缩
|
|
.header-title {
|
font-size: 36rpx;
|
font-weight: bold;
|
}
|
}
|
|
.message-list-scroll {
|
flex: 1;
|
// 隐藏滚动条但保持滚动功能
|
::-webkit-scrollbar {
|
display: none;
|
width: 0 !important;
|
height: 0 !important;
|
background: transparent;
|
}
|
|
// Firefox滚动条隐藏
|
* {
|
scrollbar-width: none; /* Firefox */
|
}
|
|
// IE/Edge滚动条隐藏
|
* {
|
-ms-overflow-style: none; /* IE 10+ */
|
}
|
}
|
|
.message-list {
|
.message-item {
|
background-color: white;
|
border-radius: 15rpx;
|
margin-bottom: 20rpx;
|
padding: 30rpx;
|
box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05);
|
|
.message-main {
|
.message-title {
|
display: flex;
|
justify-content: space-between;
|
align-items: center;
|
margin-bottom: 20rpx;
|
|
.title-text {
|
font-size: 32rpx;
|
font-weight: bold;
|
color: #333;
|
}
|
|
.unread-dot {
|
width: 16rpx;
|
height: 16rpx;
|
border-radius: 50%;
|
background-color: #ff4d4f;
|
}
|
}
|
|
.message-content {
|
font-size: 28rpx;
|
color: #666;
|
margin-bottom: 20rpx;
|
line-height: 1.5;
|
}
|
|
.message-time {
|
font-size: 24rpx;
|
color: #999;
|
text-align: right;
|
}
|
}
|
}
|
|
.no-data {
|
text-align: center;
|
padding: 100rpx 0;
|
color: #999;
|
|
text {
|
display: block;
|
margin-top: 20rpx;
|
}
|
}
|
}
|
</style>
|