campus-errand/miniapp/pages/message/message.vue
2026-03-12 18:12:10 +08:00

294 lines
5.8 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="message-page">
<!-- 系统消息入口 -->
<view class="entry-item" @click="goSystemMsg">
<view class="entry-icon system-icon">
<text class="icon-text">📢</text>
</view>
<view class="entry-info">
<text class="entry-title">系统消息</text>
<text class="entry-desc">平台公告和重要通知</text>
</view>
<view class="entry-right">
<view v-if="unreadCount.systemUnread > 0" class="badge">
{{ unreadCount.systemUnread > 99 ? '99+' : unreadCount.systemUnread }}
</view>
<text class="arrow"></text>
</view>
</view>
<!-- 订单通知入口 -->
<view class="entry-item" @click="goOrderNotify">
<view class="entry-icon order-icon">
<text class="icon-text">📋</text>
</view>
<view class="entry-info">
<text class="entry-title">订单通知</text>
<text class="entry-desc">订单状态变更通知</text>
</view>
<view class="entry-right">
<view v-if="unreadCount.orderNotificationUnread > 0" class="badge">
{{ unreadCount.orderNotificationUnread > 99 ? '99+' : unreadCount.orderNotificationUnread }}
</view>
<text class="arrow"></text>
</view>
</view>
<!-- 聊天记录用户列表 -->
<view class="section-title" v-if="chatList.length > 0">聊天记录</view>
<view
class="chat-item"
v-for="item in chatList"
:key="item.orderId"
@click="goChat(item)"
>
<image class="chat-avatar" :src="item.avatarUrl || '/static/logo.png'" mode="aspectFill"></image>
<view class="chat-info">
<view class="chat-top">
<text class="chat-name">{{ item.nickname || '用户' }}</text>
<text class="chat-time">{{ formatTime(item.lastMessageTime) }}</text>
</view>
<text class="chat-msg">{{ item.lastMessage || '' }}</text>
</view>
</view>
<!-- 空状态 -->
<view v-if="chatList.length === 0" class="empty-chat">
<text class="empty-text">暂无聊天记录</text>
</view>
</view>
</template>
<script>
import { getUnreadCount } from '../../utils/api'
export default {
data() {
return {
unreadCount: {
systemUnread: 0,
orderNotificationUnread: 0,
totalUnread: 0
},
// 聊天记录列表(腾讯 IM SDK 集成后从 SDK 获取)
chatList: []
}
},
onShow() {
this.loadUnreadCount()
this.loadChatList()
this.updateTabBarBadge()
},
methods: {
/** 加载未读消息数 */
async loadUnreadCount() {
try {
const res = await getUnreadCount()
this.unreadCount = {
systemUnread: res.systemUnread || 0,
orderNotificationUnread: res.orderNotificationUnread || 0,
totalUnread: res.totalUnread || 0
}
this.updateTabBarBadge()
} catch (e) {
// 静默处理
}
},
/** 加载聊天记录列表(腾讯 IM SDK 集成后替换) */
loadChatList() {
// TODO: 集成腾讯 IM SDK 后,从 SDK 获取会话列表
// 当前为占位实现
},
/** 更新底部导航栏未读数 badge */
updateTabBarBadge() {
const total = this.unreadCount.totalUnread
if (total > 0) {
uni.setTabBarBadge({
index: 2,
text: total > 99 ? '99+' : String(total)
})
} else {
uni.removeTabBarBadge({ index: 2 })
}
},
/** 跳转系统消息页 */
goSystemMsg() {
uni.navigateTo({ url: '/pages/message/system-msg' })
},
/** 跳转订单通知页 */
goOrderNotify() {
uni.navigateTo({ url: '/pages/message/order-notify' })
},
/** 跳转聊天页 */
goChat(item) {
uni.navigateTo({
url: `/pages/message/chat?orderId=${item.orderId}&targetUserId=${item.targetUserId}`
})
},
/** 格式化时间显示 */
formatTime(dateStr) {
if (!dateStr) return ''
const date = new Date(dateStr)
const now = new Date()
const isToday = date.toDateString() === now.toDateString()
const pad = (n) => String(n).padStart(2, '0')
if (isToday) {
return `${pad(date.getHours())}:${pad(date.getMinutes())}`
}
return `${pad(date.getMonth() + 1)}-${pad(date.getDate())}`
}
}
}
</script>
<style scoped>
.message-page {
padding: 20rpx 24rpx;
}
.entry-item {
display: flex;
align-items: center;
background-color: #ffffff;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
}
.entry-icon {
width: 80rpx;
height: 80rpx;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
margin-right: 24rpx;
flex-shrink: 0;
}
.system-icon {
background-color: #e8f4fd;
}
.order-icon {
background-color: #fff3e0;
}
.icon-text {
font-size: 40rpx;
}
.entry-info {
flex: 1;
}
.entry-title {
font-size: 30rpx;
color: #333333;
font-weight: 500;
display: block;
}
.entry-desc {
font-size: 24rpx;
color: #999999;
margin-top: 6rpx;
display: block;
}
.entry-right {
display: flex;
align-items: center;
flex-shrink: 0;
}
.badge {
background-color: #ff4d4f;
color: #ffffff;
font-size: 22rpx;
min-width: 36rpx;
height: 36rpx;
line-height: 36rpx;
text-align: center;
border-radius: 18rpx;
padding: 0 10rpx;
margin-right: 12rpx;
}
.arrow {
font-size: 36rpx;
color: #cccccc;
}
.section-title {
font-size: 28rpx;
color: #999999;
margin: 30rpx 0 16rpx;
}
.chat-item {
display: flex;
align-items: center;
background-color: #ffffff;
border-radius: 16rpx;
padding: 24rpx 30rpx;
margin-bottom: 16rpx;
}
.chat-avatar {
width: 88rpx;
height: 88rpx;
border-radius: 50%;
margin-right: 24rpx;
flex-shrink: 0;
}
.chat-info {
flex: 1;
overflow: hidden;
}
.chat-top {
display: flex;
justify-content: space-between;
align-items: center;
}
.chat-name {
font-size: 30rpx;
color: #333333;
font-weight: 500;
}
.chat-time {
font-size: 22rpx;
color: #cccccc;
}
.chat-msg {
font-size: 26rpx;
color: #999999;
margin-top: 8rpx;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block;
}
.empty-chat {
text-align: center;
padding: 80rpx 0;
}
.empty-text {
font-size: 28rpx;
color: #cccccc;
}
</style>