mall_client/zyhs3_uniapp/pages/chat/index.vue

622 lines
17 KiB
Vue
Raw Permalink Normal View History

2026-03-13 07:50:35 +00:00
<template>
<view class="container-conversation">
<!-- 顶部适配 -->
<u-navbar height="0">
<view class="u-nav-slot" slot="left"></view>
</u-navbar>
<!-- 标题栏 -->
<view class="topIcon">
消息
<view class="msgRt">
<!-- <view class="msgBox" @click="$navigateTo('/pages/im/application/application')">
<u-icon name="man-add-fill" color="#A6ADBB" size="22"></u-icon>
<text class="tips" v-if="unreadCount">{{unreadCount>99?'99+':unreadCount}}</text>
</view> -->
<view>
<u-icon @click="addBtn" name="plus-people-fill" color="#A6ADBB" size="22"></u-icon>
<view class="boxPopBg" v-if="false">
<text>
<u-icon name="photo" color="#fff"></u-icon>
</text>
<text>
<u-icon name="photo" color="#fff"></u-icon>
</text>
</view>
</view>
</view>
</view>
<u-search placeholder="搜索" v-model="searchKey" :show-action="false" v-if="false"></u-search>
<view class="imgBar" @click="handleRouter" v-if="false">
<view>
<image src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/images/imgBar/haoyou.png"></image>
<text>粉丝</text>
</view>
<view>
<image src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/images/imgBar/zan.png"></image>
<text></text>
</view>
<view>
<image src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/images/imgBar/shafa.png"></image>
<text>动态</text>
</view>
<view>
<image src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/images/imgBar/chakan.png"></image>
<text>系统通知</text>
</view>
</view>
<!-- 通知 -->
<view class="notice" v-if="false">
<image src="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/images/imgBar/tixing.png"></image>
<view>
开启消息通知
<text>第一时间收到Ta的私信消息</text>
</view>
<text @click="handleRouter">去开启</text>
</view>
<!-- 消息 -->
<view class="scroll-box">
<view class="uni-list margintop-bar">
<view v-if="conversationList.length > 0">
<u-swipe-action>
<u-swipe-action-item :threshold="60" :options="item.isPinned ? (item.messageRemindType == 'AcceptNotNotify' ? options4 : options1) : item.messageRemindType == 'AcceptNotNotify' ? options3 : options2" v-for="item of conversationList" :key="item.conversationID" :autoClose="true" @click="deleteConversationList($event, item.conversationID)">
<scroll-view scroll-y="true" class="scroll-Y">
<view class="swipe-action u-border-top u-border-bottom" @tap="handleRoute(item.conversationID)">
<view class="swipe-action__content">
<TUI-conversation-item class="swipe-action__content__text" :data-type="item.type" :conversation="item"></TUI-conversation-item>
</view>
</view>
</scroll-view>
</u-swipe-action-item>
</u-swipe-action>
</view>
<u-empty v-else text="暂无会话" marginTop="30" :customStyle="{height: '80vh'}" icon="https://jw-uniapp.oss-cn-beijing.aliyuncs.com/static/images/moreImg.png"></u-empty>
</view>
</view>
</view>
</template>
<!-- 这里有个加载的补丁逻辑待优化页面向SDK请求conversationList的时候会有时延
造成页面的一个抖动这里加一个if逻辑打一个补丁后续继续优化 -->
<script>
import TUIConversationItem from '@/components/tui-conversation/conversation-item/index';
import {destroy_group} from '@/common/http/tim.js'
export default {
data() {
return {
show: false,
options1: [
{
text: '恢复',
style: {
backgroundColor: '#3c9cff',
},
},
{
text: '删除',
style: {
backgroundColor: '#f56c6c',
},
},
{
text: '免打扰',
style: {
backgroundColor: '#ffaa00',
},
},
],
options4: [
{
text: '恢复',
style: {
backgroundColor: '#3c9cff',
},
},
{
text: '删除',
style: {
backgroundColor: '#f56c6c',
},
},
{
text: '提醒',
style: {
backgroundColor: '#ffaa00',
},
},
],
options2: [
{
text: '顶置',
style: {
backgroundColor: '#3c9cff',
},
},
{
text: '删除',
style: {
backgroundColor: '#f56c6c',
},
},
{
text: '免打扰',
style: {
backgroundColor: '#ffaa00',
},
},
],
options3: [
{
text: '顶置',
style: {
backgroundColor: '#3c9cff',
},
},
{
text: '删除',
style: {
backgroundColor: '#f56c6c',
},
},
{
text: '提醒',
style: {
backgroundColor: '#ffaa00',
},
},
],
conversationID: '',
searchKey: '',
conversationList: [],
showSelectTag: false,
unreadCount:0,
};
},
components: {
TUIConversationItem,
},
computed: {
isLogin() {
console.log(this.$store.state);
return this.$store.state.isLogin;
},
},
watch: {
isLogin(val) {
if (val) {
// 登入后拉去会话列表
this.getConversationList();
uni.$TUIKit.on(uni.$TUIKitEvent.CONVERSATION_LIST_UPDATED, this.onConversationListUpdated);
}
},
},
mounted() {
console.log("mounted聊天首页");
if (this.isLogin) {
// 登入后拉去会话列表
console.log("拉数据去了");
this.getFriendApplicationList();
this.getConversationList();
uni.$TUIKit.on(uni.$TUIKitEvent.CONVERSATION_LIST_UPDATED, this.onConversationListUpdated);
/* 申请列表更新时触发*/
uni.$TUIKit.on(uni.$TUIKitEvent.FRIEND_APPLICATION_LIST_UPDATED,this.onUnreadCount)
}
},
/**
* 生命周期函数--监听页面加载
*/
onShow() {
},
/**
* 生命周期函数--监听页面卸载
*/
onUnload() {
// uni.$TUIKit.off(uni.$TUIKitEvent.SDK_READY, this.onConversationListUpdated);
},
methods: {
getFriendApplicationList(){
let promise = uni.$TUIKit.getFriendApplicationList();
promise.then((imResponse)=> {
// friendApplicationList - 好友申请列表 - [FriendApplication]
// unreadCount - 好友申请的未读数
const { friendApplicationList, unreadCount } = imResponse.data;
this.unreadCount = unreadCount;
})
},
deleteConversationList: function (e, value) {
console.log(e,value);
if (e.index == '0') {
const list = this.conversationList;
const show = list.map(item => {
return item.isPinned;
});
for (var item of list) {
if (item.conversationID == value) {
if (show[list.indexOf(item)] === false) {
// 置顶会话v2.14.0起支持
uni.$TUIKit
.pinConversation({
conversationID: value,
isPinned: true,
})
.then(imResponse => {
// 置顶会话成功
const { conversationID } = imResponse.data; // 被置顶的会话 ID
console.log(conversationID);
})
.catch(function (imError) {
console.warn('pinConversation error:', imError); // 置顶会话失败的相关信息
});
}
if (show[list.indexOf(item)] === true) {
// 取消置顶会话v2.14.0起支持
uni.$TUIKit
.pinConversation({
conversationID: value,
isPinned: false,
})
.then(imResponse => {
// 取消置顶会话成功
const { conversationID } = imResponse.data; // 被取消置顶的会话 ID
})
.catch(function (imError) {
console.warn('pinConversation error:', imError); // 取消置顶会话失败的相关信息
});
}
}
}
}
if (e.index == '1') {
uni.$TUIKit
.deleteConversation(value)
.then(function (imResponse) {
//删除成功。
const { conversationID } = imResponse.data; // 被删除的会话 ID。
})
.catch(function (imError) {
console.warn('deleteConversation error:', imError); // 删除会话失败的相关信息
});
}
if (e.index == '2') {
const list = this.conversationList;
const show = list.map(item => {
return item.conversationID;
});
const num = value.substring(0, 3);
if (num === 'C2C') {
const user = value.slice(3);
if (list[show.indexOf(value)].messageRemindType === 'AcceptNotNotify') {
uni.$TUIKit
.setMessageRemindType({
userIDList: [user],
messageRemindType: this.TIM.TYPES.MSG_REMIND_ACPT_AND_NOTE,
})
.then(function (imResponse) {
// 设置成功后 SDK 会触发 TIM.EVENT.CONVERSATION_LIST_UPDATED 事件(遍历列表,并读取 Conversation.messageRemindType
const { successUserIDList, failureUserIDList } = imResponse.data;
})
.catch(function (imError) {
console.warn('setMessageRemindType error:', imError);
});
}
if (list[show.indexOf(value)].messageRemindType === 'AcceptAndNotify') {
uni.$TUIKit
.setMessageRemindType({
userIDList: [user],
messageRemindType: this.TIM.TYPES.MSG_REMIND_ACPT_NOT_NOTE,
})
.then(function (imResponse) {
// 设置成功后 SDK 会触发 TIM.EVENT.CONVERSATION_LIST_UPDATED 事件(遍历列表,并读取 Conversation.messageRemindType
const { successUserIDList, failureUserIDList } = imResponse.data;
})
.catch(function (imError) {
console.warn('setMessageRemindType error:', imError);
});
}
if (list[show.indexOf(value)].messageRemindType === '') {
list[show.indexOf(value)].messageRemindType = 'AcceptNotNotify';
}
}
if (num === 'GRO') {
const groupID = value.slice(5);
if (list[show.indexOf(value)].messageRemindType === 'AcceptNotNotify') {
uni.$TUIKit
.setMessageRemindType({
groupID: groupID,
messageRemindType: this.TIM.TYPES.MSG_REMIND_ACPT_AND_NOTE,
})
.then(function (imResponse) {})
.catch(function (imError) {
console.warn('setMessageRemindType error:', imError);
});
}
if (list[show.indexOf(value)].messageRemindType === 'AcceptAndNotify') {
uni.$TUIKit
.setMessageRemindType({
groupID: groupID,
messageRemindType: this.TIM.TYPES.MSG_REMIND_ACPT_NOT_NOTE,
})
.then(function (imResponse) {})
.catch(function (imError) {
console.warn('setMessageRemindType error:', imError);
});
}
}
}
},
handleRouter() {
destroy_group('GROUP12').then((res)=>{
console.log(res);
}).catch((err)=>{
console.log(err);
})
uni.showToast({
title: '跳转',
icon: 'none',
});
},
addBtn() {
uni.showActionSheet({
itemList:[... ['添加好友', '创建群聊', '加入群聊', '扫一扫','通讯录'],`新的好友`],
success: res => {
// /pages/im/application/application
switch (res.tapIndex + 1) {
case 1:
uni.navigateTo({
url: '/pages/im/conversation/create-conversation/create',
});
break;
case 2:
uni.navigateTo({
url: '/pages/im/group/create-group/create',
});
break;
case 3:
uni.navigateTo({
url: '/pages/im/group/join-group/join',
});
break;
case 4:
uni.scanCode({
success: function (res) {
console.log('条码类型:' + res.scanType);
console.log('条码内容:' + res.result);
},
});
break;
case 5:
uni.navigateTo({
url: '../chat/list',
});
break;
case 6:
uni.navigateTo({
url: '/pages/im/application/application',
});
break;
default:
break;
}
},
fail: res => {
console.log(res.errMsg);
},
});
},
handleRoute(id) {
uni.navigateTo({
url: `/pages/im/chat/chat?conversationID=${id}`,
});
},
onUnreadCount(event){
const { friendApplicationList, unreadCount } = event.data;
this.unreadCount = unreadCount;
},
onConversationListUpdated(event) {
this.conversationList = event.data;
},
pullDownRefresh(){
console.log("pullDownRefresh刷新聊天首页");
if (this.isLogin) {
// 登入后拉去会话列表
console.log("拉数据去了");
this.getFriendApplicationList();
this.getConversationList();
uni.$TUIKit.on(uni.$TUIKitEvent.CONVERSATION_LIST_UPDATED, this.onConversationListUpdated);
setTimeout(()=>{
uni.stopPullDownRefresh()
},2500)
}
},
getConversationList() {
console.log(789);
uni.$TUIKit.getConversationList().then(imResponse => {
console.log(imResponse);
this.conversationList = imResponse.data.conversationList;
});
},
},
};
</script>
<style lang="scss">
.container-conversation {
display: flex;
flex-direction: column;
box-sizing: border-box;
background-color: #fff;
width: 100%;
padding: 0 30rpx;
.boxPopBg {
position: absolute;
right: 20rpx;
top: 10rpx;
background: #303133;
width: 230rpx;
height: auto;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border-radius: 6rpx;
> text {
width: 100%;
height: 80rpx;
display: flex;
justify-content: center;
align-items: center;
color: #fff;
border-bottom: 1rpx solid #fff;
font-size: 30rpx;
}
.topTag {
position: absolute;
width: 0;
height: 0;
border-bottom: solid 5px #303133;
border-right: solid 5px transparent;
border-left: solid 5px transparent;
right: 15px;
top: 0px;
z-index: 999;
}
}
.notice {
display: flex;
align-items: center;
justify-content: space-evenly;
height: 130rpx;
background: #ffffff;
box-shadow: 0px 4rpx 27rpx 11rpx rgba(80, 15, 101, 0.09);
border-radius: 19rpx;
margin-bottom: 30rpx;
> image {
width: 56rpx;
height: 56rpx;
}
> view {
display: flex;
flex-direction: column;
font-size: 28rpx;
font-weight: bold;
color: #333333;
text {
font-size: 24rpx;
font-weight: bold;
color: #999999;
}
}
> text {
width: 138rpx;
height: 57rpx;
background: linear-gradient(99deg, #fd8be0 0%, #48c5fe 100%);
border-radius: 29rpx;
font-size: 30rpx;
font-weight: bold;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
}
}
.imgBar {
padding: 40rpx 0;
display: flex;
justify-content: space-between;
view {
display: flex;
flex-direction: column;
align-items: center;
image {
width: 90rpx;
height: 90rpx;
}
text {
margin-top: 20rpx;
font-size: 30rpx;
color: #333;
}
}
}
.topIcon {
display: flex;
justify-content: space-between;
font-size: 40rpx;
height: 80rpx;
align-items: center;
margin-bottom: 30rpx;
font-weight: bold;
z-index: 99999;
margin-top: 10rpx;
/* #ifdef APP-PLUS */
margin-top: 90rpx;
/* #endif */
/* #ifdef MP-WEIXIN */
.msgRt {
margin-right: 200rpx;
}
/* #endif */
.msgBox{
position: relative;
.tips{
position: absolute;
right: -20rpx;
top: -10rpx;
color: white;
font-size: 20rpx;
padding: 0 14rpx;
border-radius: 50rpx;
z-index: 9;
background-color: #CA0400;
}
}
view {
display: flex;
align-items: center;
.u-icon {
margin-left: 30rpx;
}
}
}
}
.scroll-box {
height: calc(100vh - 220rpx);
}
.margintop-bar {
margin-bottom: 160 rpx;
}
.btn-show-more {
display: flex;
width: 160rpx;
height: 160rpx;
padding-left: 3rpx;
}
.picker {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 96rpx;
}
</style>