campus-errand/miniapp/pages/message/message.vue
2026-03-20 18:09:42 +08:00

342 lines
6.9 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="custom-navbar" :style="{ paddingTop: statusBarHeight + 'px' }">
<view class="navbar-content">
<text class="navbar-title">消息</text>
</view>
</view>
<view :style="{ height: (statusBarHeight + 44) + 'px' }"></view>
<!-- 消息内容 -->
<view class="message-content">
<!-- 系统消息入口 -->
<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>
</view>
</template>
<script>
import { getUnreadCount } from '../../utils/api'
import { getConversationList, getChatInstance } from '../../utils/im'
export default {
data() {
return {
statusBarHeight: 0,
unreadCount: {
systemUnread: 0,
orderNotificationUnread: 0,
totalUnread: 0
},
// 聊天记录列表(腾讯 IM SDK 集成后从 SDK 获取)
chatList: []
}
},
onShow() {
const sysInfo = uni.getSystemInfoSync()
this.statusBarHeight = sysInfo.statusBarHeight || 0
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 获取会话列表) */
async loadChatList() {
try {
const list = await getConversationList()
this.chatList = list
} catch (e) {
console.error('[消息页] 加载聊天列表失败:', e)
}
},
/** 更新底部导航栏未读数 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) {
// IM 会话列表中没有 orderId传 targetUserId 让聊天页自行查找关联订单
uni.navigateTo({
url: `/pages/message/chat?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 {
min-height: 100vh;
background-color: #f5f5f5;
}
/* 自定义导航栏 */
.custom-navbar {
position: fixed;
top: 0;
left: 0;
width: 100%;
z-index: 999;
background: linear-gradient(to right, #FFB700, #FFD59B);
}
.navbar-content {
height: 44px;
display: flex;
align-items: center;
justify-content: center;
}
.navbar-title {
font-size: 34rpx;
font-weight: bold;
color: #363636;
}
.message-content {
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>