This commit is contained in:
feng0207
2026-08-11 22:22:10 +08:00
commit 5e312c1266
6985 changed files with 1061169 additions and 0 deletions
+433
View File
@@ -0,0 +1,433 @@
<template>
<div class="container">
<lay-out @goBottom="goBottom" @goTop="goTop" @refresherrefresh="refresherrefresh"
:refresherTriggered="refresherTriggered" @refresherrestore="refresherrestore"
@refresherabort="refresherabort" :scroll-top="scrollTop">
<div slot="header">
<!-- 搜索框 -->
<div class="content_search">
<div class="content_search_box">
<div class="icon" @click="searchUser"><span class="iconfont">&#xe6bf;</span></div>
<div class="input">
<input class="uni-input" @confirm="searchUser" @focus="searchFocus" @blur="searchBlur"
v-model="nickname" type="text" placeholder="搜索用户名称" />
</div>
</div>
</div>
</div>
<div slot="content" class="content">
<!-- 聊天列表 -->
<div class="content_userMessgae">
<uni-swipe-action>
<uni-swipe-action-item v-for="(item, index) in userList" :right-options="options"
@click="deleteUserRecord($event, index)" :key="item.id">
<div :id="`content_userMessgae_item${item.id}`" class="content_userMessgae_item"
@click="connentServerForUser(item)">
<div class="content_userMessgae_item_avar">
<image :src="item.avatar" mode="widthFix"></image>
<span class="online_status" :class="{ off: item.online }"></span>
</div>
<div class="content_userMessgae_item_value">
<div class="content_userMessgae_item_value_user">
<div class="content_userMessgae_item_value_user_nickName">{{ item.nickname }}
</div>
<div class="content_userMessgae_item_value_user_form" v-if="item.type"
:class="formType[item.type].className">
<span>{{ formType[item.type].label }}</span>
</div>
</div>
<!-- 用户消息 -->
<div class="content_userMessgae_item_value_message">
<span>{{ item.message }}</span>
</div>
<!-- 用户消息结束 -->
</div>
<!-- 聊天时间 -->
<div class="content_userMessgae_item_createTime">
<div class="content_userMessgae_item_createTime_value">
<span>{{ item.update_time | toDay }}</span>
</div>
<div class="content_userMessgae_item_createTime_count" v-if="item.mssage_num">
<span>{{ item.mssage_num }}</span>
</div>
</div>
<!-- 聊天时间结束 -->
<div class="content_userMessgae_item_del">删除</div>
</div>
</uni-swipe-action-item>
</uni-swipe-action>
</div>
<!-- <div v-if="!userList.length" class="no_message">
<span>暂无客户!</span>
</div> -->
<!-- 聊天列表结束 -->
</div>
</lay-out>
<div class="fixed_model" v-if="showSearchModel"></div>
<download-progress v-show='download' @clearAbort='clearAbort' :percent='percent'></download-progress>
</div>
</template>
<script>
import {
navigateTo,
Modal,
formatDate,
Toast,
parseToObject
} from 'pages/utils/uniApi.js';
import http from 'pages/api/index';
import api from 'pages/api/api.js';
import {
mapState
} from 'vuex';
import DownloadProgress from '../../../components/DownloadProgress.vue';
export default {
filters: {
toDay(value) {
if (!value) return '';
return formatDate(value * 1000, 'M月d日 hh:mm');
}
},
components: {
DownloadProgress
},
data() {
return {
selectOnlineStatus: 1,
onlineStatus: [{
label: '在线',
value: 1
},
{
label: '下线',
value: 0
}
],
customerServerHandleModel: false, // 客服操作开关
customerServerData: {},
pageData: {
page: 1,
limit: 15
},
formType: {
0: {
className: 'pc',
label: 'pc端'
},
1: {
className: 'gozhonghao',
label: '公众号'
},
2: {
className: 'wchat',
label: '小程序'
},
3: {
className: 'h5',
label: 'H5'
}
},
refresherTriggered: false, // 下拉刷新状态
nickname: '',
is_tourist: '',
userList: [], // 用户列表
audioFun: '', // 音频对象
showSearchModel: false,
lastTapTime: 0,
scrollTop: 0,
count: 0,
userListTemp: {},
options: [{
text: '取消',
style: {
backgroundColor: '#007aff'
}
}, {
text: '删除',
style: {
backgroundColor: '#dd524d'
}
}],
download: false,
percent: 0
};
},
watch: {
chatInfo(data) {
if (data.id) {
let ids = [];
this.userList.map(item => {
ids.push(item.id);
});
if (ids.indexOf(data.id) === -1) {
this.userList.unshift(data);
}
this.$store.commit('setChatInfo', {});
}
}
},
onLoad(opt) {
this.initSocket();
this.userList = this.$store.getters.userRecord.userList;
this.appVersionLevel();
},
onShow(opt) {
this.pageData.page = 1;
// this.initData(this.pageData.page > 1 ? 'concat' : '');
this.initData();
this.getKefuInfo();
this.updataUserCount();
},
onUnload() {
uni.$off('mssage_num', this.mssageNumEvent);
uni.$off('rm_transfer', this.rmTransferEvent);
uni.$off('transfer', this.transferEvent)
},
onTabItemTap(e) {
},
onNavigationBarButtonTap(e) {
this.handleScanCode(); // 吊起相机,扫描二维码
},
computed: {
...mapState(['chatInfo', 'kefuInfo', 'config', 'userRecord', 'userLists'])
},
methods: {
appVersionLevel() {
// #ifdef APP-PLUS
let that = this;
plus.runtime.getProperty(plus.runtime.appid, ({
version,
name
}) => {
//升级过一次就不要在提醒
if (this.$cache.get('update_' + version)) {
return;
}
http(api.appVersion, {
version,
name
}).then(data => {
if (data.update === false) {
return;
}
uni.showModal({
title: '检测到新版本',
content: data.info,
confirmText: '立即升级',
success: (res) => {
if (res.confirm && data.update && data.url) {
that.downloadFile(data.url);
}
},
complete: () => {
this.$cache.set('update_' + version, 1);
}
})
}).catch(res => {})
});
// #endif
},
downloadFile(url) {
this.downloadTask = uni.downloadFile({
url: url,
success: (res) => {
if (res.statusCode === 200) {
plus.runtime.install(
res.tempFilePath, {
force: false
}, () => {
plus.runtime.restart();
}, err => {
console.error(err);
});
}
},
complete: () => {
this.download = false
this.percent = 0;
}
});
this.download = true;
this.downloadTask.onProgressUpdate(res => {
this.percent = res.progress
});
},
clearAbort() {
if (this.downloadTask) {
this.downloadTask.abort();
this.downloadTask = null;
}
},
// 删除聊天列表用户
deleteUserRecord(e, index) {
if (e.index == 1) {
this.$store.dispatch('deleteUserRecord', {
id: this.userList[index].id
}).then(res => {
this.userList.splice(index, 1);
});
}
},
mssageNumEvent(data) {
console.log('mssage_num', data);
this.getMssageNum(data);
},
//被转走事件
rmTransferEvent(data) {
let rmIndex = -1;
this.userList.map((item, index) => {
if (item.id === data.recored.id) {
rmIndex = index;
}
});
if (rmIndex !== -1) {
this.userList.splice(rmIndex, 1);
this.updataUserCount();
}
},
//转接到当前客服事件
transferEvent(data) {
let pushIndex = -1;
this.userList.map((item, index) => {
if (item.id === data.recored.id) {
pushIndex = index;
}
});
if (pushIndex === -1) {
this.userList.unshift(data.recored);
this.updataUserCount();
}
},
initSocket() {
uni.$on('mssage_num', this.mssageNumEvent);
uni.$on('rm_transfer', this.rmTransferEvent);
uni.$on('transfer', this.transferEvent);
},
getKefuInfo() {
this.$store.dispatch('getKeufuInfo').then(res => {
uni.setNavigationBarTitle({
title: res.site_title
});
});
},
// 搜索框获得焦点
searchFocus() {
this.showSearchModel = true;
},
// 搜索框失去焦点
searchBlur() {
this.searchUser();
this.showSearchModel = false;
},
// 搜索用户
searchUser() {
this.pageData.page = 1;
this.initData();
},
// 获取客户列表, 客服信息
initData(type) {
this.pageData.limit = 10;
this.$store.dispatch('getUserRecord', {
nickname: this.nickname,
pageData: this.pageData,
is_tourist: this.is_tourist
}).then(res => {
if (res.length > 0) {
this.pageData.page++;
}
if (type == 'concat') {
this.userList = this.userList.concat(res);
} else {
this.userList = res;
// this.$set(this.userListTemp, this.pageData.page, res);
}
if (this.refresherTriggered) {
this.refresherTriggered = false;
}
});
},
// 下拉刷新被触发
refresherrefresh() {
if (this.refresherTriggered) {
this.refresherTriggered = false;
return;
}
if (!this.refresherTriggered) {
this.refresherTriggered = true;
}
// this.refresherTriggered = true;
this.pageData.page = 1;
this.initData();
},
// 下拉刷新复位
refresherrestore() {
this.refresherTriggered = false;
},
//
refresherabort() {
this.refresherTriggered = false;
},
// 滑动到页面底部
goBottom() {
this.initData('concat');
},
goTop() {
this.pageData.page = 1;
this.initData();
},
updataUserCount() {
this.$store.dispatch('updataUserCount').then(res => {
this.scoket.setBadgeNumber(res.count);
});
},
// 通过sockect连接收取新的消息
getMssageNum(data) {
if (data.num < 1) {
return;
}
this.userList.forEach((item, index) => {
// 如果发送方的user_id 与 列表中的 to_uid 一致
if (item.to_user_id == data.user_id) {
this.userList.splice(index, 1);
}
});
this.userList.unshift(data.recored);
this.updataUserCount();
},
// 扫描二维码
handleScanCode() {
// let str = "http://192.168.31.192:8081/pages/users/scan_login/index?key=463aca66113f65396dc28e3f0041a2f2";
uni.scanCode({
onlyFromCamera: true, // 是否只允许相机扫码,不允许相机选择图片
success(res) {
console.log(res);
navigateTo(1, '/pages/view/authorizedLogin/index', {
key: res.result.split('=')[1]
});
},
fail: () => {}
});
},
connentServerForUser(item) {
item.mssage_num = 0;
navigateTo(1, '/pages/view/customerServer/index', {
to_user_id: item.to_user_id
});
}
}
};
</script>
<style lang="less" scoped>
@import './less/messageList.less';
</style>
@@ -0,0 +1,305 @@
.header {
background: @primaryBgColor;
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 15rpx;
position: relative;
height: 116rpx;
&_customer {
display: flex;
align-items: center;
&_avar {
margin-right: 10rpx;
border-radius: 50%;
overflow: hidden;
width: 80rpx;
height: 80rpx;
image {
width: 100%;
height: 100%;
}
}
&_status {
color: rgba(255, 255, 255, 0.8);
font-size: 14px;
display: flex;
align-items: center;
&_name {
margin-right: 10rpx;
}
&_item {
&_value {
display: flex;
align-items: center;
.tip_primary {
display: inline-block;
width: 12rpx;
height: 12rpx;
background: linear-gradient(143deg, #27f2cb 0%, #14e3b4 100%);
border-radius: 50%;
margin-right: 6rpx;
}
.tip_danger {
background: #f74c31 !important;
}
.tip_type {
font-size: 20rpx;
white-space: nowrap;
}
}
}
}
}
&_handle {
display: flex;
color: rgba(255, 255, 255, 0.8);
align-items: center;
.font {
// display: inline-block;
// width: 38rpx;
// height: 38rpx;
// background: rgba(255, 255, 255, 0.22);
text-align: center;
line-height: 38rpx;
margin-right: 8rpx;
font-size: 16px;
// border-radius: 50%;
}
.loginOut {
font-size: 14px;
}
}
&_checkout_status {
position: absolute;
width: 214rpx;
height: 173rpx;
background: #434343;
top: 140rpx;
left: 43rpx;
z-index: 90;
border-radius: 10px;
&_sanjiao {
background: #434343;
position: absolute;
top: -15rpx;
left: 30rpx;
width: 30rpx;
height: 30rpx;
transform: rotate(45deg);
}
&_select {
display: flex;
flex-direction: column;
justify-content: space-between;
height: 100%;
&_item {
flex: 1;
display: flex;
align-items: center;
justify-content: space-between;
color: #fff;
padding: 0 30rpx;
border-bottom: 1px solid #fff;
&_tip {
width: 12rpx;
height: 12rpx;
border-radius: 50%;
background: linear-gradient(180deg, #bcbcbc 0%, #919191 100%);
}
.tip_select {
background: linear-gradient(143deg, #27f2cb 0%, #14e3b4 100%);
}
.tip_select_outline {
background: #f74c31;
}
&_status {
flex: 1;
padding-left: 15rpx;
font-size: 14px;
}
&_icon {
color: #b9b9b9;
}
}
&_line {
height: 1px;
width: 100%;
background: #f0f1f2;
}
}
}
}
// 内容部分样式
.content {
&_search {
padding: 20rpx 30rpx;
border-bottom: 1px solid #eceff8;
background: #fff;
display: flex;
align-items: center;
&_box {
flex: 1;
// margin-right: 20rpx;
display: flex;
padding: 14rpx 22rpx;
background: #f5f6f9;
border-radius: 39rpx;
.icon {
margin-right: 12rpx;
color: #c4c4c4;
}
.input {
width: 100%;
align-items: center;
input {
font-size: 14px;
}
}
}
.reload {
}
}
// 聊天内容
&_userMessgae {
padding: 0 30rpx;
background: #fff;
&_item {
position: relative;
display: flex;
padding: 28rpx 0;
border-bottom: 1px solid #f6f6f6;
transition: transform 0.3s;
&_avar {
border-radius: 50%;
// overflow: hidden;
width: 96rpx;
height: 96rpx;
margin-right: 22rpx;
// border: 1px solid rgba(0, 0, 0, 0.1);
// background: @primaryBgColor;
position: relative;
image {
width: 100%;
}
.online_status {
position: absolute;
right: 0rpx;
bottom: 0rpx;
z-index: 10;
display: inline-block;
width: 15rpx;
height: 15rpx;
background: #ccc;
border-radius: 50%;
}
.off {
background: linear-gradient(143deg, #27f2cb 0%, #14e3b4 100%);
}
}
&_value {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
overflow: hidden;
padding-top: 8rpx;
&_user {
display: flex;
align-items: center;
&_nickName {
font-size: 14px;
color: rgba(0, 0, 0, 0.7);
font-weight: 600;
margin-right: 16rpx;
}
&_form {
font-size: 26rpx;
padding: 0 10rpx;
}
.wchat {
background: rgba(56, 117, 234, 0.14);
color: rgba(56, 117, 234, 1);
}
.h5 {
background: rgba(255, 162, 0, 0.18);
color: #d08800;
}
.gozhonghao {
background: rgba(0, 186, 100, 0.14);
color: #00a219;
}
.pc {
color: #820adb;
background: rgba(133, 64, 227, 0.14);
}
}
// 用户消息
&_message {
color: rgba(159, 159, 159, 1);
font-size: 24rpx;
width: 100%;
.overText;
}
}
// 聊天时间
&_createTime {
display: flex;
flex-direction: column;
justify-content: space-between;
padding-top: 8rpx;
&_value {
color: rgba(159, 159, 159, 1);
font-size: 22rpx;
}
&_count {
align-self: flex-end;
display: inline-block;
width: 38rpx;
height: 38rpx;
line-height: 38rpx;
text-align: center;
background: rgba(247, 76, 49, 1);
color: #fff;
border-radius: 50%;
font-size: 24rpx;
}
}
&_del {
position: absolute;
top: 0;
right: -30rpx;
bottom: 0;
display: flex;
justify-content: center;
align-items: center;
width: 100rpx;
background-color: rgba(255, 0, 0, 1);
font-size: 28rpx;
color: rgba(255, 255, 255, 1);
transform: translateX(100%);
}
&.on {
transform: translateX(-100rpx);
}
}
}
}
.no_message {
text-align: center;
padding: 60rpx 0;
font-size: 14px;
color: #ccc;
}