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.
 
 
 
 
 
 

398 lines
12 KiB

<template>
<view>
<!-- <view class="socket-status pd-10 im-flex justify-between im-align-items-center" v-if="!socketStatus">
<view class="cuIcon-infofill text-red f-18"></view>
<view class="c-666 f-12"> WS通信已断开检查网络设置是否正常</view>
<view @tap="reconnect()">重连</view>
</view> -->
<view class="pr-10 pl-10 text-gray bg-white im-flex im-space-between im-align-items-center cu-bar fixed" :style="[{top:CustomBar + 'px'}]">
<im-tab class="mr-10" :values="values" @change="changeChat"></im-tab>
<view class="im-flex im-justify-content-start im-align-items-center" v-if="multiport && socketStatus">
<view class=" iconfont icon-web f-16 ml-5"></view>
<view class="f-14 ml-5">电脑在线</view>
</view>
<view class="socket-status pd-5 im-flex justify-between im-align-items-center radius-10 im-flex1" v-if="!socketStatus">
<view class="cuIcon-infofill text-red f-18"></view>
<view class="c-666 f-12">通信断开</view>
<view class="cuIcon-refresh" @tap="reconnect()"></view>
</view>
</view>
<view class="im-message-list" style="margin-top:100rpx">
<scroll-view class="scroll_height" scroll-y :refresher-enabled="true" :refresher-triggered="refreshStatus" @refresherrefresh="onRefresh">
<uni-notice-bar :speed="60" show-icon scrollable showClose :text="noticeContent.title" style="margin: 0;" @tap="openChat('admin_notice')" v-if="noticeContent.title" @close="closeNotice"/>
<view class="cu-list menu-avatar" :style="{paddingBottom: paddingB+'px'}" v-if="msgsIn.length>0">
<view class="cu-item second" :class="[modalName=='move-box-'+ index?'move-cur':'',item.is_top==1 ? 'top-contacts' : '']" v-for="(item, index) in msgsIn" :key="index"
@touchstart="ListTouchStart" @touchmove="ListTouchMove" @touchend="ListTouchEnd" @tap="openChat(item.id)" :data-target="'move-box-' + index">
<block v-for="(items,indexs) in imglist" :key="indexs" v-if="network_log == 'none'">
<view class="cu-avatar lg" v-if="item.imgname === items.name" :class="appSetting.circleAvatar?'round':'radius'" :style="[{backgroundImage:'url('+ items.path +')'}]">
<view class="online-status" v-if="item.is_online && item.is_group==0 && globalConfig.chatInfo.online==1"></view>
</view>
</block>
<view v-else class="cu-avatar lg" :class="appSetting.circleAvatar?'round':'radius'" :style="[{backgroundImage:'url('+ item.avatar +')'}]">
<view class="online-status" v-if="item.is_online && item.is_group==0 && globalConfig.chatInfo.online==1"></view>
</view>
<view class="content">
<view class="c-333">
<view class="text-overflow f-16" style="width:80%">
{{item.displayName}}
</view>
</view>
<view class="im-flex im-justify-content-start im-align-items-start lh-20x" style="height: 50rpx;overflow:hidden">
<view class="text-red f-12 mr-5" v-if="item.is_at">[有{{item.is_at}}人@我] </view>
<mp-html :content="emojiToHtml(item.lastContent)" class="im-flex f-12 text-gray text-overflow no-click"/>
</view>
</view>
<view class="action">
<view class="text-grey text-xs" >{{from_time(item.lastSendTime)}}</view>
<view class="cu-tag round sm" :class="item.is_notice ? 'bg-red' : 'bg-notremind'" v-if="item.unread>0">{{item.unread}}</view>
<view class="c-999" v-if="item.is_notice==0 && item.unread==0">
<text class="cuIcon-musicforbidfill"></text>
</view>
</view>
<view class="move second">
<view class="bg-grey" v-if="item.is_top==1" @tap="btnTap(0,item)">取消置顶</view>
<view class="bg-blue" v-else @tap="btnTap(0,item)">置顶聊天</view>
<view class="bg-orange" v-if="item.is_notice==1" @tap="btnTap(2,item)">免扰</view>
<view class="bg-orange" v-else @tap="btnTap(2,item)">取消免扰</view>
</view>
</view>
</view>
<Empty v-else noDatatext="暂无聊天" textcolor="#999" />
</scroll-view>
</view>
</view>
</template>
<script>
import statusPoint from '@/components/status.vue'
import imTab from '@/components/message/im-tab.vue'
import emoji from '@/utils/emoji.js'
import { storeToRefs } from 'pinia';
import { useMsgStore } from '@/store/message';
import { useloginStore } from '@/store/login'
import pinia from '@/store/index'
// #ifdef APP-PLUS
import {getSavedImages} from '@/utils/LocalFileSystemURL.js'
// #endif
const msgStore = useMsgStore(pinia)
const {contacts,unread,msgAt,network_log} = storeToRefs(msgStore);
const userStore = useloginStore(pinia);
const {multiport} = storeToRefs(userStore);
export default {
components: {
statusPoint,imTab
},
data() {
return {
navCurrent: 0,
msgs: contacts,
pageLoading: true,
multiport:multiport,
socketStatus:true,
damping : 0.29,
moveIndex : -1,
touchStart:false,
modalName: null,
listTouchStart: 0,
listTouchDirection: null,
emojiMap:[],
chatStatus:true,
paddingB:0,
msgAt:msgStore.msgAt,
appSetting:userStore.appSetting,
globalConfig:userStore.globalConfig,
active:0,
triggered:true,
noticeContent:{},
network_log:network_log,
refreshStatus: false,
values:[
{
id:1,
name:'所有',
count:0
},
{
id:2,
name:'未读',
count:unread
},
{
id:3,
name:'@我',
count:msgAt
}
],
imglist:[]
}
},
computed:{
msgsIn(){
// #ifdef APP-PLUS
this.getImagePath()
// #endif
let index=this.active;
let contactList = [];
if(index==1){
contactList = this.msgs.filter(obj => obj.unread>0);
}else if(index==2){
contactList = this.msgs.filter(obj => obj.is_at>0);
}else{
contactList = this.msgs.filter(obj => obj.lastContent);
}
// console.log('无网络测试',contactList);
return contactList;
}
},
mounted(){
this.moveIndex = -1;
uni.$on('getPositonsOrder',(res) => {
let message=res.data;
switch (res['type']) {
case "simple":
this.getNotice();
break;
case "updateConfig":
this.globalConfig=message;
break;
}
})
// 监听ws网路连接状况
uni.$on('socketStatus',(e)=>{
if(!e){
this.multiport=false;
}
this.socketStatus=e;
})
},
created:function(){
this.getNotice()
let emojiMap=[];
// 解析所有表情
emoji.forEach(function (item) {
let child=item.children;
if(child.length>0){
child.forEach(function (val) {
let name=val.name;
let src=val.src;
emojiMap[name]=src;
})
}
});
this.emojiMap=emojiMap;
// #ifdef H5
this.paddingB=this.inlineTools;
// #endif
// #ifndef H5
this.paddingB=this.navBarHeight+this.inlineTools;
// #endif
// #ifdef APP-PLUS
this.getImagePath()
// #endif
},
methods: {
async getImagePath(){
this.imglist = await getSavedImages()
this.imglist.map(item => {
item.path = plus.io.convertLocalFileSystemURL(item.path)
});
// console.info('读取地址',this.imglist);
},
onRefresh(){
this.refreshStatus = true;
this.initContacts()
},
initContacts(){
uni.$emit('initContacts',true)
this.triggered = true;
setTimeout(() => {
this.triggered = false;
this.refreshStatus = false;
}, 1000)
},
getNotice(){
this.$api.msgApi.getAdminNotice().then(res => {
if (res.code == 0) {
let data=res.data;
let oldNotice=uni.getStorageSync('notice_'+data.create_time);
if(!oldNotice){
this.noticeContent=data;
}
}
});
},
closeNotice(){
uni.setStorageSync('notice_'+this.noticeContent.create_time,this.noticeContent);
},
changeChat(item,index){
this.active=index;
},
btnTap: function(index, contact) {
// 第一个按钮被点击 置顶、取消置顶消息
if (index == 0) {
contact.is_top=contact.is_top==0 ? 1 : 0;
this.$api.msgApi.setChatTopAPI({
id: contact.id,
is_top:contact.is_top,
is_group: contact.is_group
}).then(res => {
if (res.code == 0) {
msgStore.updateContacts(contact);
}
});
}
// 第三个按钮被打开 [ 删除消息 ]
else if (index == 1) {
uni.showModal({
title: '确定要删除吗?',
success: e => {
if (e.confirm) {
// this.$api.msgApi.delChatAPI({
// id: contact.id,
// is_group: contact.is_group
// }).then(res => {
// if (res.code == 0) {
// msgStore.deleteContacts(contact);
// }
// });
}
}
});
}
// 消息免打扰
else if (index == 2) {
contact.is_notice=contact.is_notice==0 ? 1 : 0;
this.$api.msgApi.isNoticeAPI({
id: contact.id,
is_notice:contact.is_notice,
is_group: contact.is_group
}).then(res => {
if (res.code == 0) {
msgStore.updateContacts(contact);
}
});
}
},
reconnect(){
uni.showLoading({
title:'重连中...'
})
this.socketIo.connectSocketInit({type:'ping'});
setTimeout(()=>{
uni.hideLoading()
},1500)
},
// 自动解析消息中的表情
emojiToHtml(str){
if(!str){
return;
}
let emojiMap=this.emojiMap;
return str.replace(/\[!(\w+)\]/gi, function (str, match) {
var file = match;
return emojiMap[file] ? "<img class='mr-5' style=\"width:18px;height:18px\" emoji-name=\"".concat(match, "\" src=\"").concat(emojiMap[file], "\" />") : "[!".concat(match, "]");
});
},
// ListTouch触摸开始
ListTouchStart(e) {
this.listTouchStart = e.touches[0].pageX
},
// ListTouch计算方向
ListTouchMove(e) {
let cux=e.touches[0].pageX;
let direction=cux- this.listTouchStart;
// 左滑的距离需要达到100才能滑动出菜单,否则在页面自然滚动的时候就会吧菜单给拖出来了
if(Math.abs(direction)>100 && direction<0){
this.listTouchDirection='left';
}else{
this.listTouchDirection='right';
}
},
// ListTouch计算滚动
ListTouchEnd(e) {
if (this.listTouchDirection == 'left') {
this.modalName = e.currentTarget.dataset.target
this.chatStatus=false;
} else {
this.modalName = null
}
this.listTouchDirection = null
},
openChat(id){
// 如果左滑工具栏在开启的情况下不能够点击进入聊天
if(this.chatStatus){
uni.navigateTo({
url:"/pages/message/chat?id=" + id,
// url:"/pages/message/chat1?id=" + id,
animationType:"slide-in-right"
})
uni.setStorageSync('tabid',id)
}else{
this.chatStatus=true;
}
},
from_time(time){
return this.$util.timeFormat(time);
},
}
}
</script>
<style lang="scss">
.scroll_height{
height: calc(100vh - 148px);
}
.container {
padding: 20px;
font-size: 14px;
line-height: 24px;
}
.border-b{
border-bottom: 1px solid #eee;
}
.socket-status{
background-color: #fde0de;
height:72rpx;
border-radius: 36rpx;
padding:10rpx 16rpx;
}
.text-overflow ::v-deep uni-text , .text-overflow ::v-deep uni-text span{
overflow: hidden !important;
text-overflow: ellipsis;
white-space: nowrap !important;
width:300rpx;
}
.top-contacts{
background-color: #f5f5f5 !important;
}
.cu-list.menu-avatar>.cu-item{
padding-right:30rpx;
.content{
line-height: unset;
}
}
.no-click{
pointer-events:none;
height:50rpx;
flex:1;
}
.text-overflow ::v-deep ._block ._a{
color: #aaaaaa !important;
}
.bg-notremind{
background-color: #d1d1d1;
color: #ffffff;
}
.cu-bar.fixed, .nav.fixed{
z-index:900;
}
</style>