mall_client/zyhs3_uniapp/pages/interaction/message.vue

381 lines
11 KiB
Vue

<template>
<view>
<scroll-view scroll-y="true" :style="{height: swiperHeight+'px;'}">
<!-- 聊天列表 -->
<view class="cu-list menu-avatar" style="height: 100%;">
<!-- 平台客服 -->
<block v-if="customerList.length > 0">
<text class="title">平台客服</text>
<block v-for="(item, index) in customerList" :key="index+99">
<view class="cu-item" @click="skipToSingleChat(item.imAccount, 1, true, index, null)" v-if="userInfo.imAccount !== item.imAccount">
<image :src="filterImg(item.headPortrait)" class="cu-avatar round lg" mode=""></image>
<view class="content" style="background-color: #ffffff;padding-top: 0upx;">
<view class="text-grey">{{item.nickname}}</view>
<view class="text-gray text-sm">
<text class="line">{{item | filterContent}}</text>
</view>
</view>
<view class="action" style="width: 200rpx;">
<view class="text-grey text-xs">
{{item.createTime | filterTime}}
</view>
<view class="cu-tag round bg-red sm" v-if="item.localUnreadNumber">{{item.localUnreadNumber}}</view>
</view>
</view>
</block>
<view class="tb"></view>
</block>
<block v-for="(item,index) in lists" :key="index" >
<view class="cu-item" :class="modalName=='move-box-'+ index?'move-cur':''" :data-target="'move-box-' + index"
@click="skipToSingleChat(item.toImAccount, item.type, false, index, item.toConversationId)">
<image :src="filterImg(item.toType === 3 ? item.storeLogoImage : item.headPortrait)" class="cu-avatar round lg" mode=""></image>
<view class="content" style="background-color: #ffffff;padding-top: 0upx;width: 55%">
<view class="text-grey">
<text class="tips bg-base" v-if="item.toType === 2">配送员</text>
<text class="tips yellow" v-if="item.toType === 3">商家</text>
<text class="tips green" v-if="item.toType === 4">配送员用户</text>
<text class="tips redd" v-if="item.toType === 5">店铺客户</text>
{{item.toType === 3 ? item.storeName : item.nickname}}
</view>
<view class="text-gray text-sm">
<text class="line">{{item | filterContent}}</text>
</view>
</view>
<view class="action" style="width: 200rpx;">
<view class="text-grey text-xs">
{{item.createTime | filterTime}}
</view>
<view class="cu-tag round bg-red sm" v-if="item.localUnreadNumber">{{item.localUnreadNumber}}</view>
</view>
<view class="move">
<view class="bg-red" @tap.stop="deleteConversation(item, index)">删除</view>
<view class="bg-grey" @tap.stop="touchLongByXiaoXiFalse(index)">取消</view>
</view>
</view>
</block>
</view>
<view class="flex flex-center">
<uni-load-more :status="loadingType"></uni-load-more>
</view>
</scroll-view>
</view>
</template>
<script>
import { mapState, mapMutations } from "vuex"
import url from "@/common/http/url.js"
import imUtils from "@/common/im/imTools.js"
import publics from "@/common/utils/public.js"
// #ifdef APP-PLUS
import { selectInformationType, pullSQL, deleteInformationType, updateSessionInformation } from "@/common/im/db.js"
// #endif
// #ifndef APP-PLUS
import { selectInformationType, pullSQL, deleteInformationType, updateSessionInformation } from "@/common/im/db-h5.js"
// #endif
import uniLoadMore from '@/components/uni-load-more/uni-load-more.vue';
import vTabs from "@/components/v-tabs/v-tabs.vue"
export default {
components: { uniLoadMore, vTabs },
data(){
return {
swiperHeight: 0,
modalName: null,
lists: [],
listTouchStart: 0,
listTouchDirection: null,
loadModal: false,
loadingType: 'nomore', //加载更多状态
customerList: [],
isChatBack: false,
isCustomer: false,
listIndex: 0,
lastMsg: {}
}
},
filters:{
filterTime(val){
if (!val) return
return imUtils.fromTimer(val);
},
filterContent(data){
if (data.msgType === false) return ""
switch(data.msgType) {
case 0:
return data.content.text;
case 1:
return "[图片]";
case 2:
return "[语音]";
case 3:
return "[位置]";
case 4:
return "[视频]";
case 5:
return "[视频/语音通话]";
case 6:
return "[商品配送]";
case 7:
return "[商品退款]";
case 8:
return "[商品下单]";
default:
return ""
}
},
},
computed: {
...mapState(["isHandNewMsg", "userInfo"])
},
watch:{
isHandNewMsg(val){
if (val) {
this.init()
this.setHandNewMsg(false)
}
}
},
onShow() {
this.setHandNewMsg(false)
this.swiperHeight = uni.getSystemInfoSync().windowHeight
if (this.isChatBack) {
let name = null
if (this.isCustomer) {
name = "customerList"
} else {
name = "lists"
}
this[name][this.listIndex].msgType = this.lastMsg.msgType
this[name][this.listIndex].content = this.lastMsg.content
this[name][this.listIndex].createTime = this.lastMsg.createTime
// 如果是第一条则不用重新排序
if (this.listIndex && !this.isCustomer) {
let data = {}
this[name].forEach((v, i) => {
if (i === this.listIndex) {
data = v
return
}
})
this[name].splice(this.listIndex, 1)
this[name].unshift(data)
}
}
},
onLoad() {
this.init()
},
methods: {
...mapMutations(["setHandNewMsg"]),
init(){
this.$http("GET", url.common.customerService).then(res => {
this.customerList = JSON.parse(JSON.stringify(res.data.im))
this.getList()
})
},
// 从本地数据库中获取会话列表,默认按照会话的最后一条消息的时间,降序排列
async getList() {
uni.stopPullDownRefresh();
let that = this
let res = await selectInformationType(null)
console.log(".....res", res)
if (res.length === 0) return
let data = JSON.parse(JSON.stringify(res))
let conversationUnReadData = publics.getConversationUnReadNum()
let array = []
let localUnreadNumberTotal = 0
for(let i = 0; i<data.length; i++) {
let e = data[i]
e.localUnreadNumber = conversationUnReadData["c_"+e.id] || 0
await updateSessionInformation(e, 'id', e.id)
localUnreadNumberTotal = localUnreadNumberTotal + e.localUnreadNumber
if (e.storeLogoImage === "null") {
e.storeLogoImage = null
}
if (e.storeName === "null") {
e.storeName = null
}
let isHas = false
let customerIndex = 0
this.customerList.forEach((v, i) => {
if (v.imAccount === e.toImAccount) {
isHas = true
customerIndex = i
return
}
})
let doc = await pullSQL(null, 'conversationId', e.id, 0, 1, 'desc')
console.log(doc)
if (doc.length > 0) {
let chatObj = doc[0]
e.createTime = chatObj.createTime
e.msgType = chatObj.msgType
e.content = JSON.parse(chatObj.content)
} else {
e.createTime = 0
e.msgType = false
e.content = null
}
if (isHas) {
this.customerList[customerIndex].localUnreadNumber = e.localUnreadNumber
this.customerList[customerIndex].conversationId = e.id
this.customerList[customerIndex].createTime = e.createTime
this.customerList[customerIndex].msgType = e.msgType
this.customerList[customerIndex].content = e.content
this.$forceUpdate()
} else {
array.push(e)
}
}
array.sort(function(a, b){return b.createTime - a.createTime}) // 时间排序
this.lists = array
// #ifdef APP-PLUS
plus.runtime.setBadgeNumber(localUnreadNumberTotal)
// #endif
},
deleteConversation(item,index) {
let that = this;
uni.showModal({
title: '提示',
content: '确定将 '+item.nickname+' 的会话消息删除吗?',
success: res => {
if(res.confirm){
that.lists.splice(index, 1)
deleteInformationType('sessionList', 'id', item.id)
}
that.touchLongByXiaoXiFalse(0);
}
});
},
touchLongByXiaoXiFalse(index){
this.listTouchStart = 0;
this.listTouchDirection = "right";
this.modalName = null;
},
touchLongByXiaoXi(index){
this.listTouchStart = 200;
this.listTouchDirection = "left";
this.modalName = "move-box-"+index;
},
/**
* 创建会话
* @param {String} imAccount 对方的imAccount
* @param {Number} type 会话类型 1-用户 2-配送员 3-商家
* @param {Bool} isCustomer 是否是客服
* @param {Number} index 索引
* @@param {Number} toConversationId 对方会话ID
* */
skipToSingleChat(imAccount, type, isCustomer, index, toConversationId) {
this.$navigateTo('im-chat?pages=message&&id='+imAccount+"&&type="+type+"&&isCustomer="+isCustomer+"&&listIndex="+index+(isCustomer?"":"&&toConversationId="+toConversationId))
if (isCustomer) {
this.customerList[index].localUnreadNumber = 0
} else {
this.lists[index].localUnreadNumber = 0
}
this.isChatBack = false
},
filterImg(img){
if (img) {
return publics.filterImgUrl(img, 1)
} else {
return this.$staticUrl + "user/avatar.png"
}
},
isHasUnSendMsg(id){
if (!id) return ""
let value = publics.getUnsendMsg(id)
return value
}
}
}
</script>
<style scoped lang="scss">
.cu-list {
display: flex;
flex-direction: column;
.title{
border-left: 8rpx solid #F8D247;
padding-left: 26rpx;
font-size: 28rpx;
color: #777;
margin-bottom: 20rpx;
margin-left: 30rpx;
}
.tb{
width: 750rpx;
height: 20rpx;
background-color: #F8F8F8;
}
.cu-item {
display: flex;
flex-direction: row;
align-items: center;
transition: all .6s ease-in-out 0s;
transform: translateX(0upx);
background-color: #FFFFFF;
&:after {
position: absolute;
top: 0;
left: 0;
box-sizing: border-box;
width: 200%;
height: 200%;
border-bottom: 1px solid #ddd;
border-radius: inherit;
content: " ";
transform: scale(.5);
transform-origin: 0 0;
pointer-events: none
}
&:last-child::after {
border-bottom: none;
}
.tips{
font-size: 20upx;
padding: 5upx 8upx;
border-radius: 15%;
margin-right: 5upx;
line-height: 30upx;
color: white;
}
.yellow{
background: linear-gradient(to bottom, #b69700 0%, #c66d00 100%);
}
.green{
background: linear-gradient(to bottom, #38b948 0%, #238300 100%);
}
.redd{
background: linear-gradient(to bottom, #dc4839 0%, #e20b3b 100%);
}
}
&.menu {
margin-top: 30rpx;
.cu-item {
padding: 30rpx;
.icon{
img,image{
width: 50rpx;
}
}
.content {
margin-left: 20rpx;
font-size: 32rpx;
}
}
}
}
</style>
<style scoped lang="scss">
@import "../../common/main.css";
/* @import url('https://hejiume-public.oss-cn-chengdu.aliyuncs.com/app/resources/main.css'); */
</style>