<template>
|
<div class="service-box pb-150 flex flex-col">
|
<van-nav-bar
|
:title="$t('在线客服')"
|
left-arrow
|
@click-left="onClickLeft"
|
fixed
|
/>
|
<!-- <div class="flex-1" v-if="kefu_url">
|
<iframe
|
:src="kefu_url"
|
width="100%"
|
height="100%"
|
frameborder="0"
|
></iframe>
|
</div> -->
|
<!-- <div v-else class="localKefu flex-1 flex"> -->
|
<div class="localKefu flex-1 flex">
|
<div
|
class="flex flex-col px-32 box-border flex-1"
|
ref="boxScroll"
|
style="overflow: auto"
|
>
|
<div
|
class="w-full py-10 text-grey text-center pt-10"
|
@click="onMore"
|
:style="{ visibility: finished ? 'hidden' : 'visiable' }"
|
>
|
{{ $t("历史消息") }}
|
</div>
|
<ul class="flex flex-col pt-20">
|
<li
|
v-for="(item, index) in list"
|
:key="item.id"
|
class="flex flex-col mt-20"
|
v-if="item.delete_status == 0"
|
>
|
<p class="font-26 text-center py-20 text-grey">
|
{{ item.createtime }}
|
</p>
|
<div
|
class="flex"
|
:class="item.send_receive === 'send' ? 'justify-end' : ''"
|
>
|
<template v-if="item.send_receive === 'receive'">
|
<img
|
src="@/assets/image/assets-center/logo.png"
|
class="w-81 h-81 mr-40"
|
/>
|
<div
|
class="responser px-50 py-35 font-30 rounded-lg font-26 chatBg"
|
>
|
<p
|
class="break-word textColor"
|
style="max-width: 230px"
|
v-if="item.type === 'text'"
|
>
|
{{ item.content }}
|
</p>
|
<img
|
v-else
|
:src="item.content"
|
class="w-200 h-200"
|
@click="onPreview(item.content)"
|
/>
|
</div>
|
</template>
|
<div
|
class="py-25 px-50 responser-two rounded-lg flex flex-col chatBg"
|
v-else
|
>
|
<img
|
:src="`${item.content}`"
|
class="w-200 h-200"
|
v-if="item.type === 'img'"
|
@click="onPreview(item.content)"
|
/>
|
<p class="break-word textColor" v-else style="max-width: 230px">
|
{{ item.content }}
|
</p>
|
</div>
|
</div>
|
</li>
|
</ul>
|
</div>
|
<div
|
class="bottom flex justify-between h-130 items-center w-full fixed bottom-0 borderTop px-32 box-border bgBottom"
|
>
|
<van-uploader
|
:max-size="10000 * 1024"
|
@oversize="onOversize"
|
:after-read="afterRead"
|
>
|
<img src="@/assets/image/service/photo.png" class="w-72 h-72" />
|
</van-uploader>
|
<input
|
type="text"
|
v-model="value"
|
:placeholder="$t('请输入您的消息...')"
|
class="flex-1 mx-20 h-full border-none bgBottom textColor"
|
/>
|
<span @click="send('text', value)">
|
<img src="@/assets/image/service/send.png" class="w-72 h-72" />
|
</span>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
import { mapGetters } from "vuex";
|
import { _getMsg, _getUnreadMsg, _sendMsg } from "@/API/im.api";
|
import { _uploadImage } from "@/API/fund.api";
|
import { Uploader, ImagePreview } from "vant";
|
export default {
|
name: "CustomerService",
|
components: {
|
[Uploader.name]: Uploader,
|
},
|
data() {
|
return {
|
list: [],
|
value: "",
|
lastMsgId: "",
|
interval: null,
|
unread: 0,
|
finished: false, // 没有历史消息
|
currentScrollTop: 0,
|
isScrollBottom: false,
|
};
|
},
|
computed: {
|
...mapGetters("home", ["kefu_url"]),
|
},
|
created() {
|
this.fetchList();
|
},
|
mounted() {
|
window.addEventListener("scroll", this.handleScroll, true);
|
},
|
methods: {
|
onOversize(file) {
|
console.log(file);
|
this.$toast(this.$t("文件大小不能超过10m"));
|
},
|
onPreview(url) {
|
// 预览
|
ImagePreview([url]);
|
},
|
showTime(index) {
|
// 时间显示
|
if (index === 0) {
|
return true;
|
}
|
if (index === this.list.length - 1) {
|
return false;
|
}
|
if (
|
this.list[index].createtime.split(" ")[0] ===
|
this.list[index + 1].createtime.split(" ")[1]
|
) {
|
return false;
|
}
|
},
|
afterRead(file) {
|
// 文件上传
|
this.$toast.loading({ duration: 0 });
|
_uploadImage(file, (percent) => {
|
console.log(percent);
|
})
|
.then((data) => {
|
this.$toast.clear();
|
this.send("img", data);
|
})
|
.catch(() => {
|
this.$toast.clear();
|
file.status = "failed";
|
file.message = this.$t("图片上传失败");
|
});
|
},
|
fetchList(message_id = "") {
|
// 获取消息列表
|
_getMsg({ message_id }).then((data) => {
|
// this.lastMsgId
|
if (!this.lastMsgId) {
|
this.lastMsgId = data.length && data[data.length - 1]["id"];
|
}
|
if (data.length) {
|
if (message_id) {
|
// 加载更多
|
this.lastMsgId = data[data.length - 1]["id"];
|
this.list = [...data.reverse(), ...this.list];
|
} else {
|
let list = [...this.list, ...data.reverse()];
|
let hash = {};
|
list = list.reverse().reduce(function (preVal, curVal) {
|
hash[curVal.id]
|
? " "
|
: (hash[curVal.id] = true && preVal.push(curVal));
|
return preVal;
|
}, []);
|
this.list = list.reverse();
|
}
|
if (this.isScrollBottom) {
|
this.$refs.boxScroll.scrollTop =
|
this.$refs.boxScroll.scrollHeight -
|
this.$refs.boxScroll.offsetHeight;
|
}
|
this.currentScrollTop = this.$refs.boxScroll.scrollTop;
|
if (data.length < 10) {
|
this.finished = true;
|
}
|
}
|
|
// else {
|
// this.list = [{ id: '1', send_receive: 'receive', content: this.$t('你好,欢迎来到我们的数字货币平台!'), type: 'text'}]
|
// }
|
if (!message_id) {
|
this.clearInterval();
|
this.interval = setInterval(() => {
|
this.fetchList();
|
}, 1000);
|
}
|
});
|
},
|
handleScroll() {
|
if (this.$refs.boxScroll.scrollTop == this.currentScrollTop) {
|
this.isScrollBottom = true;
|
} else {
|
this.isScrollBottom = false;
|
}
|
},
|
onMore() {
|
// 加载更多
|
this.fetchList(this.lastMsgId);
|
},
|
clearInterval() {
|
if (this.interval) {
|
clearInterval(this.interval);
|
this.interval = null;
|
}
|
},
|
fetchUnread() {
|
// 获取未读
|
_getUnreadMsg().then((data) => {
|
this.unread = data;
|
});
|
},
|
onClickLeft() {
|
// 返回
|
this.$router.go(-1);
|
},
|
send(type = "text", content = "") {
|
// 发送消息, img 也当消息text
|
if (!content) {
|
this.$toast(this.$t("请输入消息内容"));
|
return;
|
}
|
_sendMsg(type, content).then((data) => {
|
console.log(data);
|
this.isScrollBottom = true;
|
this.value = "";
|
// document.getElementById('bottom').click()
|
});
|
},
|
},
|
beforeDestroy() {
|
this.clearInterval();
|
},
|
activated() {
|
window.addEventListener("scroll", this.handleScroll, true);
|
},
|
deactivated() {
|
this.clearInterval();
|
window.removeEventListener("scroll", this.handleScroll);
|
},
|
destroyed() {
|
window.removeEventListener("scroll", this.handleScroll);
|
},
|
};
|
</script>
|
<style lang="scss" scoped>
|
.service-box {
|
width: 100%;
|
height: 100%;
|
box-sizing: border-box;
|
|
::v-deep .van-hairline--bottom::after {
|
@include themify() {
|
border-color: themed("border_color");
|
}
|
}
|
}
|
|
.break-word {
|
word-wrap: break-word;
|
white-space: pre-wrap;
|
}
|
|
.max-w-230 {
|
max-width: 230px;
|
}
|
|
.responser {
|
position: relative;
|
|
&::after {
|
content: "";
|
width: 0;
|
height: 0;
|
border-top: 10px solid transparent;
|
border-bottom: 10px solid transparent;
|
|
@include themify() {
|
border-right: 2px solid themed("chat_bg");
|
}
|
|
position: absolute;
|
left: -20px;
|
top: 20px;
|
}
|
}
|
|
.responser-two {
|
position: relative;
|
|
&::after {
|
content: "";
|
width: 0;
|
height: 0;
|
border-bottom: 10px solid transparent;
|
border-top: 10px solid transparent;
|
|
@include themify() {
|
border-left: 20px solid themed("chat_bg");
|
}
|
|
position: absolute;
|
right: -19px;
|
top: 20px;
|
}
|
}
|
|
.borderTop {
|
@include themify() {
|
border-top: 1px solid themed("border_color");
|
}
|
}
|
|
.localKefu {
|
overflow: auto;
|
padding-bottom: 40px;
|
}
|
|
.van-nav-bar--fixed {
|
position: relative !important;
|
}
|
|
.bottom {
|
margin-bottom: constant(safe-area-inset-bottom);
|
margin-bottom: env(safe-area-inset-bottom);
|
}
|
</style>
|