You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

340 lines
8.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<template>
<view class="page">
<!-- 页面头部 -->
<view class="page-header" :style="{ paddingTop: geStatusBarHeight() + 8 + 'px' }">
<view class="text-center">消息</view>
<uni-icons type="staff-filled" size="30" color="#ffffff" @click="gotoContacts"></uni-icons>
</view>
<view class="wrapcon">
<!-- 暂无消息 -->
<view v-if="chats.length === 0 && loadStatus === 'nomore'" class="nodata">暂无消息~</view>
<!-- 列表 -->
<view class="listcell">
<u-swipe-action
ref="swipeRef"
:options="options"
v-for="(chat, index) in chats"
:key="chat.id || index"
style="min-width: 600rpx;"
@click="actionClick(chat, index)"
>
<view class="lcon" @click="gotoChat(chat, index)" @longpress="handleLongPress(index)">
<view class="limg">
<image class="img" :src="chat.headImage || '/static/image/girl.png'" mode="aspectFill"></image>
</view>
<view class="lright">
<view class="lrow">
<view class="pname">{{ chat.showName || '未知' }}</view>
<view class="ptime">{{ changeTime(chat.lastSendTime) }}</view>
</view>
<view class="lrow">
<view class="pnr">
{{ chat.lastContent || '' }}
</view>
<view class="lnum" v-if="chat.unreadCount > 0">
{{ chat.unreadCount }}
</view>
</view>
</view>
</view>
</u-swipe-action>
</view>
<!-- 加载状态 -->
<u-loadmore v-if="chats.length === 0 && loadStatus === 'loading'" :status="loadStatus" :marginTop="20"></u-loadmore>
</view>
<!-- 提示信息弹窗 -->
<uni-popup ref="message" type="message">
<uni-popup-message :type="msgType" :message="messageText" :duration="2000"></uni-popup-message>
</uni-popup>
</view>
</template>
<script>
import { mapState, mapActions, mapGetters } from 'vuex'
import dateTime from '@/common/dateTime.js'
import {myCache} from "../../utils/utils";
export default {
data() {
return {
loadStatus: 'loadmore',
options: [
{
text: '删除',
style: {
backgroundColor: '#ed2a28'
}
}
],
messageText: '',
msgType: 'error'
}
},
computed: {
...mapState('chatStore', ['chats']),
...mapGetters('chatStore', ['isLoading']),
// 未读消息总数(用于角标)
unreadCount() {
let count = 0
this.chats.forEach(chat => {
if (!chat.delete) {
count += chat.unreadCount
}
})
return count
},
// 是否正在加载用于显示loading状态
loading() {
return this.isLoading()
}
},
watch: {
unreadCount(newVal) {
this.setBadge(newVal)
}
},
onShow() {
console.log("this.chats列表.......",this.chats)
this.loadStatus = 'nomore'
this.setBadge(this.unreadCount)
},
onPullDownRefresh() {
// 下拉刷新仅刷新角标数据由全局WebSocket维护
this.setBadge(this.unreadCount)
setTimeout(() => {
uni.stopPullDownRefresh()
}, 500)
},
methods: {
...mapActions('chatStore', ['removeChat', 'moveTop']),
// 设置底部角标
setBadge(count) {
if (count > 0) {
uni.setTabBarBadge({
index: 3, // 根据实际tabBar索引调整
text: count + ''
})
} else {
uni.removeTabBarBadge({
index: 3
})
}
},
// 长按打开滑动菜单
handleLongPress(index) {
this.$refs.swipeRef[index].open()
},
// 滑动菜单点击(删除)
actionClick(chat, index) {
const that = this
uni.showModal({
title: '提示',
content: '确定要删除此聊天记录吗?',
success: res => {
if (res.confirm) {
that.$refs.swipeRef[index].close()
that.removeChat(index) // 调用 Vuex action
}
}
})
},
// 跳转到聊天页面
gotoChat(chat, index) {
// 清除该会话的未读由chat页面处理
// 构造跳转参数(与原有逻辑兼容)
let info = {}
if (chat.type === 'PRIVATE') {
info = {
chatId: chat.id || `privatechat-${chat.targetId}`,
chatName: chat.showName,
chatAvatar: chat.headImage,
friendId: chat.targetId,
minId: chat.hotMinIdx || 0,
sort: 'privatechat',
from: 'message'
}
} else if (chat.type === 'GROUP') {
info = {
chatId: chat.id || `groupchat-${chat.targetId}`,
groupId: chat.targetId,
chatName: chat.showName,
chatAvatar: chat.headImage,
minId: chat.hotMinIdx || 0,
sort: 'groupchat',
from: 'message'
}
}
const data = encodeURIComponent(JSON.stringify(info))
uni.navigateTo({ url: `/pages/chatbox/chat-box?chatIdx=${index}` });
},
// 跳转到通讯录
gotoContacts() {
uni.navigateTo({
url: '/pages/message/contact'
})
},
// 时间格式化
changeTime(time) {
return dateTime.dateTime(time)
},
// 获取状态栏高度
geStatusBarHeight() {
return uni.getSystemInfoSync().statusBarHeight
}
}
}
</script>
<style lang="scss" scoped>
.page {
padding: 0;
position: relative;
background-image: url('@/static/image/bg.jpg');
background-attachment: fixed;
background-size: cover;
background-position: center center;
min-height: calc(100vh - var(--window-top) - var(--window-bottom));
}
.page-header {
position: fixed;
width: 100%;
z-index: 999;
padding: 40rpx 30rpx 30rpx 30rpx;
display: flex;
color: #fff;
font-size: 36rpx;
background-color: #00a89b;
.text-center {
width: 100%;
text-align: center;
}
.edit {
position: absolute;
top: 50%;
transform: translateY(-50%);
right: 30rpx;
font-size: 32rpx;
}
}
.wrapcon {
padding: 0;
width: 100%;
position: relative;
margin: 180rpx 0 0 0;
min-height: calc(100vh - 180rpx);
/* #ifdef H5 */
margin: calc(110rpx + var(--window-top)) 0 0 0;
min-height: calc(100vh - var(--window-top) - var(--window-bottom) - 180rpx);
/* #endif */
overflow-y: auto;
}
.listcell {
background: #fff;
margin: 0;
width: 100%;
min-width: 750rpx;
.lcon {
border-bottom: 1rpx solid #eee;
padding-top: 20rpx;
padding-bottom: 20rpx;
display: flex;
flex-direction: row;
align-items: center;
width: 100%;
min-width: 750rpx;
.limg {
width: 100rpx;
height: 100rpx;
margin-right: 20rpx;
margin-left: 20rpx;
display: flex;
flex-direction: row;
flex-wrap: wrap;
align-items: center;
justify-content: center;
border-radius: 50%;
.img {
width: 100rpx;
height: 100rpx;
border-radius: 50%;
}
}
.lright {
display: flex;
flex: 1;
flex-direction: column;
}
.lrow {
display: flex;
flex-direction: row;
margin-bottom: 20rpx;
margin-right: 20rpx;
}
.pname {
display: flex;
flex: 1;
line-height: 50rpx;
font-size: 32rpx;
font-weight: 600;
color: #000000;
}
.ptime {
line-height: 50rpx;
font-size: 24rpx;
font-weight: 500;
color: #595959;
}
.pnr {
display: flex;
flex: 1;
font-size: 24rpx;
font-weight: 400;
color: #595959;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 40rpx;
max-height: 40rpx;
}
.lnum {
background-color: #de0000;
padding: 0 10rpx;
min-width: 32rpx;
height: 32rpx;
line-height: 32rpx;
color: #fff;
font-size: 24rpx;
border-radius: 28rpx;
text-align: center;
}
}
}
.nodata {
background-image: url('../../static/image/nomsg.png');
background-repeat: no-repeat;
background-position: center center;
background-size: 100%;
height: 376rpx;
width: 256rpx;
color: #00a89b;
display: flex;
align-items: center;
justify-content: flex-end;
flex-direction: column;
padding-bottom: 40rpx;
margin: 100rpx auto;
}
</style>