|
|
@@ -0,0 +1,570 @@
|
|
|
+<template>
|
|
|
+ <div class="conatiner">
|
|
|
+ <div class="content" v-if="!Customer">
|
|
|
+ <div class="title">
|
|
|
+ 选择登录客服
|
|
|
+ </div>
|
|
|
+ <div class="customerList">
|
|
|
+
|
|
|
+ <div class="customerItem" v-for="item in customerList" @click="useCustomer(item)">
|
|
|
+ <img :src="item.icon+'?x-oss-process=image/resize,m_mfit,h_120,w_120'" style="border-radius:100%;width:120px;height:120px" />
|
|
|
+ <div class="name">{{item.serviceName}}</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <el-pagination v-if="totalNumber>pageSize" style="margin-top:50px" background @current-change="currentPageChange" :current-page="currentPage" :page-size="pageSize" layout="total, prev, pager, next" :total="totalNumber">
|
|
|
+ </el-pagination>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="chatContent" v-else>
|
|
|
+ <div class="top">
|
|
|
+ <img class="icon" :src="myStoreInfo.icon+'?x-oss-process=image/resize,m_fill,h_50,w_50'" alt="">
|
|
|
+ <span style="font-weight:bold;">{{myStoreInfo.storeName}}</span>
|
|
|
+ <span style="font-size:14px;margin-left:20px;">客服{{Customer.username}}</span>
|
|
|
+ <img style="margin-left:5px" :src="Customer.icon+'?x-oss-process=image/resize,m_fill,h_30,w_30'" alt="">
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="chatmain">
|
|
|
+ <div class="left">
|
|
|
+ <div class="left-content">
|
|
|
+ <div class="left-item" :class="{active:chatUserId==item.userId}" v-for="(item,index) in storeConversationList" @click="readAll(item)">
|
|
|
+ <img class="icon" :src="item.storeInfo.icon+'?x-oss-process=image/resize,m_fill,h_40,w_40'" alt="">
|
|
|
+ <div class="chatName">
|
|
|
+ <div class="name">{{item.storeInfo.storeName}}</div>
|
|
|
+ <div class="subtitle" v-if="item.chatInfo">{{item.chatInfo.content}}</div>
|
|
|
+ </div>
|
|
|
+ <div class="time" v-if="item.amount">
|
|
|
+ <el-badge :value="item.amount" :hidden='item.amount?false:true' class='item'>
|
|
|
+ </el-badge>
|
|
|
+ <span>{{getTime(item.updateTime)}}</span>
|
|
|
+ </div>
|
|
|
+ <div class="close" @click.stop='del(item,index)'>
|
|
|
+ <i class="el-icon-error"></i>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="right" v-if="chatUserId">
|
|
|
+ <div class="chatList" ref='chatList'>
|
|
|
+ <div class="chat-item" v-for="item in orderedHistory" :style="{flexDirection:item.typeFlag?'row-reverse':'row'}">
|
|
|
+ <img class="icon" :src="(item.typeFlag?myStoreInfo.icon:item.icon)+'?x-oss-process=image/resize,m_fill,h_40,w_40'" alt="">
|
|
|
+ <div class="chatInfo">{{item.content}}</div>
|
|
|
+ <span class="serviceName" v-if="item.typeFlag">{{item.serviceName}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="inputContent">
|
|
|
+ <el-input type="textarea" maxlength="200" resize='none' :autosize="{ minRows:6}" placeholder="请输入内容" v-model="textarea3">
|
|
|
+ </el-input>
|
|
|
+
|
|
|
+ <el-button type="primary" class="submit" @click="send">发送</el-button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<script>
|
|
|
+import { mapState } from 'vuex'
|
|
|
+import orderItem from '../components/OrderItem'
|
|
|
+import moment from 'moment'
|
|
|
+import 'moment/locale/zh-cn'
|
|
|
+import eventBus from '../eventBus'
|
|
|
+export default {
|
|
|
+ name: 'order',
|
|
|
+ created() {
|
|
|
+ eventBus.$on('receiveMessage', this.onReceiveMessage)
|
|
|
+ if (this.$route.query.chatUserId) {
|
|
|
+ this.chatUserId = this.$route.query.chatUserId
|
|
|
+ }
|
|
|
+ },
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ customerList: [],
|
|
|
+ totalNumber: 0,
|
|
|
+ totalPage: 10,
|
|
|
+ currentPage: 1,
|
|
|
+ pageSize: 5,
|
|
|
+ Customer: null,
|
|
|
+ chatUserId: null,
|
|
|
+ chatCurrent: 1,
|
|
|
+ chatFlag: false,
|
|
|
+ chatList: [],
|
|
|
+ textarea3: ''
|
|
|
+ }
|
|
|
+ },
|
|
|
+ computed: {
|
|
|
+ ...mapState(['userInfo', 'myStoreInfo', 'storeConversationList']),
|
|
|
+ orderedHistory() {
|
|
|
+ return this.chatList.sort((a, b) => {
|
|
|
+ return a.time - b.time
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ mounted() {
|
|
|
+ this.getData()
|
|
|
+
|
|
|
+ },
|
|
|
+ beforeDestroy() {
|
|
|
+ eventBus.$off('receiveMessage', this.onReceiveMessage)
|
|
|
+ },
|
|
|
+ methods: {
|
|
|
+ getCustomer() {
|
|
|
+ this.$http.get({
|
|
|
+ url: '/customerService/all',
|
|
|
+ data: {
|
|
|
+ storeId: this.myStoreInfo.id,
|
|
|
+ useFlag: 'Y'
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (res.success) {
|
|
|
+ this.customerList = res.data
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getData() {
|
|
|
+
|
|
|
+ var data = {
|
|
|
+ currentPage: this.currentPage,
|
|
|
+ pageNumber: this.pageSize,
|
|
|
+ storeId: this.userInfo.storeInfo.id,
|
|
|
+ useFlag: 'Y'
|
|
|
+ }
|
|
|
+ this.$http.get({
|
|
|
+ url: '/customerService/page',
|
|
|
+ data: data
|
|
|
+ }).then(res => {
|
|
|
+ if (res.success) {
|
|
|
+ this.totalNumber = res.data.page.totalNumber;
|
|
|
+ this.customerList = res.data.pp;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ currentPageChange(page) {
|
|
|
+ this.currentPage = page;
|
|
|
+ this.getData();
|
|
|
+ },
|
|
|
+ useCustomer(item) {
|
|
|
+ this.Customer = item
|
|
|
+ this.$http.get({
|
|
|
+ url: '/rong/getToken',
|
|
|
+ data: {
|
|
|
+ rongKey: item.username,
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (res.appKey && res.token) {
|
|
|
+ this.$IM.init(res.appKey, res.token)
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ this.$http.get({
|
|
|
+ url: '/usersSession/all',
|
|
|
+ data: {
|
|
|
+ storeId: this.myStoreInfo.id,
|
|
|
+ type: 0
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (res.success) {
|
|
|
+ this.$store.commit('updateStoreConversationList', res.data)
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ console.log(e)
|
|
|
+ })
|
|
|
+
|
|
|
+ if (this.chatUserId) {
|
|
|
+ this.getChatInfo(this.chatUserId)
|
|
|
+ this.goBottom()
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ },
|
|
|
+ readAll(item, type) {
|
|
|
+ this.$http.get({
|
|
|
+ url: '/chatInfo/readAll',
|
|
|
+ data: {
|
|
|
+ storeId: item.storeId,
|
|
|
+ userId: item.userId,
|
|
|
+ typeFlag: 0
|
|
|
+ }
|
|
|
+ })
|
|
|
+ if (type) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ this.chatUserId = item.userId
|
|
|
+ this.getChatInfo(item.userId)
|
|
|
+ this.goBottom()
|
|
|
+ },
|
|
|
+ getChatInfo(id) {
|
|
|
+ this.chatList = []
|
|
|
+ this.chatCurrent = 1
|
|
|
+ this.getPageChat()
|
|
|
+ },
|
|
|
+ getPageChat() {
|
|
|
+ this.chatFlag = false
|
|
|
+ this.$http.get({
|
|
|
+ url: '/chatInfo/page',
|
|
|
+ data: {
|
|
|
+ currentPage: this.chatCurrent,
|
|
|
+ pageNumber: 10,
|
|
|
+ storeId: this.myStoreInfo.id,
|
|
|
+ userId: this.chatUserId
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (res.success) {
|
|
|
+ res.data.pp.forEach(item => {
|
|
|
+ this.chatList.push(item)
|
|
|
+ });
|
|
|
+
|
|
|
+ if (res.data.currentPage < res.data.totalPage) {
|
|
|
+ this.chatFlag = true
|
|
|
+ }
|
|
|
+
|
|
|
+ if (this.chatList.length == 0) {
|
|
|
+ setTimeout(() => {
|
|
|
+ this.$http.post({
|
|
|
+ url: '/chatInfo/save',
|
|
|
+ data: {
|
|
|
+ 'content': '您好,感谢您在' + this.storeInfo.storeName + '店铺下的订单。',
|
|
|
+ 'contentType': 0,
|
|
|
+ 'state': 0,
|
|
|
+ 'storeId': this.myStoreInfo.id,
|
|
|
+ 'userId': this.chatUserId,
|
|
|
+ 'typeFlag': 1
|
|
|
+ }
|
|
|
+ }).then(res2 => {
|
|
|
+ if (res2.success) {
|
|
|
+ this.chatList.push(res2.data)
|
|
|
+ this.updateList()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }, 1000)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ console.log(e)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ getTime(str) {
|
|
|
+ var time = ''
|
|
|
+ if (str) {
|
|
|
+ time = moment(str).fromNow()
|
|
|
+ }
|
|
|
+ return time
|
|
|
+ },
|
|
|
+ del(item, index) {
|
|
|
+ console.log(item)
|
|
|
+
|
|
|
+ if (item.id == this.chatUserId) {
|
|
|
+ this.chatUserId = ''
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ this.$http.post({
|
|
|
+ url: '/usersSession/del',
|
|
|
+ data: {
|
|
|
+ id: item.id
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (res.success) {
|
|
|
+ var list = [...this.storeConversationList]
|
|
|
+ list.splice(index, 1)
|
|
|
+ this.$store.commit('updateStoreConversationList', list);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ goBottom() {
|
|
|
+ setTimeout(() => {
|
|
|
+ if (this.$refs.chatList) {
|
|
|
+ this.$refs.chatList.scrollTop = this.$refs.chatList.scrollHeight
|
|
|
+ }
|
|
|
+
|
|
|
+ }, 50)
|
|
|
+
|
|
|
+ },
|
|
|
+ send() {
|
|
|
+
|
|
|
+ this.$IM.sendMessage({
|
|
|
+ target: this.myStoreInfo.id,
|
|
|
+ content: {
|
|
|
+ content: this.textarea3,
|
|
|
+ extra: {
|
|
|
+ storeId: this.myStoreInfo.id,
|
|
|
+ typeFlag: "1",
|
|
|
+ userId: this.chatUserId
|
|
|
+ }
|
|
|
+ },
|
|
|
+ userId: this.chatUserId.toString(),
|
|
|
+ typeFlag: 1,
|
|
|
+ customer: this.Customer.username,
|
|
|
+ success: (res) => {
|
|
|
+ this.textarea3 = ''
|
|
|
+ console.log(res)
|
|
|
+ this.chatList.push(res)
|
|
|
+ this.goBottom()
|
|
|
+ this.updateList()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ },
|
|
|
+ onReceiveMessage(message) {
|
|
|
+ console.log(message)
|
|
|
+ if (this.chatUserId == message.userId) {
|
|
|
+ message.icon = this.chatList[0].icon
|
|
|
+ this.chatList.push(message)
|
|
|
+ this.goBottom()
|
|
|
+ this.readAll({
|
|
|
+ storeId: message.storeId,
|
|
|
+ userId: message.userId,
|
|
|
+ }, 1)
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ this.$http.get({
|
|
|
+ url: '/usersSession/all',
|
|
|
+ data: {
|
|
|
+ storeId: this.myStoreInfo.id,
|
|
|
+ type: 0
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (res.success) {
|
|
|
+ this.$store.commit('updateStoreConversationList', res.data)
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ console.log(e)
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ },
|
|
|
+ updateList(){
|
|
|
+ this.$http.get({
|
|
|
+ url: '/usersSession/all',
|
|
|
+ data: {
|
|
|
+ storeId: this.myStoreInfo.id,
|
|
|
+ type: 0
|
|
|
+ }
|
|
|
+ }).then(res => {
|
|
|
+ if (res.success) {
|
|
|
+ this.$store.commit('updateStoreConversationList', res.data)
|
|
|
+ }
|
|
|
+ }).catch(e => {
|
|
|
+ console.log(e)
|
|
|
+ })
|
|
|
+ }
|
|
|
+ },
|
|
|
+ components: {
|
|
|
+ orderItem
|
|
|
+ }
|
|
|
+}
|
|
|
+</script>
|
|
|
+
|
|
|
+<style lang="less" scoped>
|
|
|
+.conatiner {
|
|
|
+ background-color: rgba(0, 0, 0, 0.4);
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ left: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+}
|
|
|
+.content {
|
|
|
+ width: 1190px;
|
|
|
+ height: 610px;
|
|
|
+ background-color: #fff;
|
|
|
+ margin: 100px auto;
|
|
|
+ border: 1px solid #ebebeb;
|
|
|
+ border-radius: 4px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ justify-content: center;
|
|
|
+ align-items: center;
|
|
|
+ .title {
|
|
|
+ font-size: 30px;
|
|
|
+ font-weight: bold;
|
|
|
+ color: #000;
|
|
|
+ margin-bottom: 50px;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.customerList {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ justify-content: space-around;
|
|
|
+ min-width: 500px;
|
|
|
+ .customerItem {
|
|
|
+ padding: 20px;
|
|
|
+ cursor: pointer;
|
|
|
+ .name {
|
|
|
+ text-align: center;
|
|
|
+ font-size: 24px;
|
|
|
+ line-height: 30px;
|
|
|
+ font-weight: bold;
|
|
|
+ margin-top: 5px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ opacity: 0.9;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+.chatContent {
|
|
|
+ width: 1190px;
|
|
|
+ height: 610px;
|
|
|
+ background-color: #fff;
|
|
|
+ margin: 100px auto;
|
|
|
+ // border: 1px solid #ebebeb;
|
|
|
+ border-radius: 4px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+
|
|
|
+ .top {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ padding: 10px 20px;
|
|
|
+ background: linear-gradient(151deg, rgba(27, 184, 172, 1) 0%, rgba(0, 142, 205, 1) 100%);
|
|
|
+ box-shadow: 0px 1px 3px 0px rgba(0, 0, 0, 0.2);
|
|
|
+ border-radius: 4px;
|
|
|
+ min-height: 50px;
|
|
|
+
|
|
|
+ img {
|
|
|
+ border-radius: 100%;
|
|
|
+ margin-right: 20px;
|
|
|
+ }
|
|
|
+
|
|
|
+ span {
|
|
|
+ font-size: 16px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .chatmain {
|
|
|
+ flex-grow: 1;
|
|
|
+ display: flex;
|
|
|
+ align-self: stretch;
|
|
|
+ .left {
|
|
|
+ width: 25%;
|
|
|
+ overflow: auto;
|
|
|
+ border-right: 1px solid #ebebeb;
|
|
|
+
|
|
|
+ .left-item {
|
|
|
+ padding: 10px;
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ cursor: pointer;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ background-color: #ebebeb;
|
|
|
+ }
|
|
|
+
|
|
|
+ .icon {
|
|
|
+ border-radius: 100%;
|
|
|
+ min-width: 40px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .chatName {
|
|
|
+ flex-grow: 1;
|
|
|
+ margin-left: 5px;
|
|
|
+ overflow: hidden;
|
|
|
+ .name {
|
|
|
+ font-size: 16px;
|
|
|
+ color: #333;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ .subtitle {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #999;
|
|
|
+ margin-top: 5px;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .time {
|
|
|
+ font-size: 12px;
|
|
|
+ color: #999;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ text-align: right;
|
|
|
+ min-width: 60px;
|
|
|
+ }
|
|
|
+
|
|
|
+ // &:not(:last-child) {
|
|
|
+ border-bottom: 1px solid #ebebeb;
|
|
|
+ // }
|
|
|
+
|
|
|
+ .close {
|
|
|
+ color: #999;
|
|
|
+ display: none;
|
|
|
+ margin-left: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ .close {
|
|
|
+ display: block;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .right {
|
|
|
+ width: 75%;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ .chatList {
|
|
|
+ // height: 425px;
|
|
|
+ overflow: auto;
|
|
|
+ // border-bottom: 1px solid #ebebeb;
|
|
|
+ padding-bottom: 20px;
|
|
|
+ flex-grow: 1;
|
|
|
+ }
|
|
|
+ .inputContent {
|
|
|
+ position: relative;
|
|
|
+ .submit {
|
|
|
+ position: absolute;
|
|
|
+ bottom: 16px;
|
|
|
+ right: 23px;
|
|
|
+ width: 93px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .chat-item {
|
|
|
+ display: flex;
|
|
|
+ align-items: flex-start;
|
|
|
+ margin-top: 10px;
|
|
|
+ padding: 0 15px;
|
|
|
+ position: relative;
|
|
|
+ .serviceName {
|
|
|
+ position: absolute;
|
|
|
+ right: 35px;
|
|
|
+ bottom: 0;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #666;
|
|
|
+ width: 40px;
|
|
|
+ text-align: center;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+ .icon {
|
|
|
+ min-width: 40px;
|
|
|
+ margin: 0 20px;
|
|
|
+ border-radius: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ .chatInfo {
|
|
|
+ // flex-grow: 1;
|
|
|
+
|
|
|
+ padding: 10px 20px;
|
|
|
+ font-size: 14px;
|
|
|
+ font-weight: 400;
|
|
|
+ color: rgb(12, 4, 4);
|
|
|
+ line-height: 20px;
|
|
|
+ border: 1px solid #979797;
|
|
|
+ border-radius: 4px;
|
|
|
+ margin-top: 18px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|