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.

351 lines
8.5 KiB

4 weeks ago
<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: {
3 weeks ago
...mapActions('chatStore', ['removeChat', 'moveTop','loadFriend']),
4 weeks ago
// 设置底部角标
setBadge(count) {
3 weeks ago
myCache("massageCount",count);
4 weeks ago
if (count > 0) {
uni.setTabBarBadge({
index: 3, // 根据实际tabBar索引调整
text: count + ''
3 weeks ago
});
// app清除角标的数量
//#ifdef APP-PLUS
plus.runtime.setBadgeNumber(count);
//#endif
4 weeks ago
} else {
uni.removeTabBarBadge({
index: 3
3 weeks ago
});
// app清除角标的数量
//#ifdef APP-PLUS
plus.runtime.setBadgeNumber(-1);
//#endif
4 weeks ago
}
},
// 长按打开滑动菜单
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>