10.10综合交易所原始源码_移动端
1
admin
2026-01-06 03043192ddf00f9a36b7454799a9152cd1b50a0b
src/views/customerService/index - 副本1.vue
New file
@@ -0,0 +1,377 @@
<template>
   <div class="service-box flex flex-col pb-40">
      <iframe height="100%" src="https://cdn.chat20gm.cfd/chat_online/index?channelId=1958101585091772416"></iframe>
   </div>
</template>
<script setup>
   import {
      Uploader,
      showImagePreview
   } from 'vant'
   import {
      _getMsg,
      _getUnreadMsg,
      _sendMsg
   } from '@/service/im.api'
   import {
      _uploadImage
   } from '@/service/upload.api'
   import {
      ref,
      onMounted,
      onUnmounted,
      onBeforeMount
   } from "vue";
   import {
      useI18n
   } from "vue-i18n";
   import {
      throttle
   } from '@/utils/index'
   import {
      closeToast,
      showToast,
      showLoadingToast
   } from "vant";
   import {
      useRoute,
      useRouter
   } from 'vue-router';
   import {
      getc2cOrder
   } from "@/service/recharge.api.js";
   import {
      useHomesStore
   } from "@/store/homes.store";
   import {
      SET_KEFU
   } from "@/store/types.store";
   import {
      useUserStore
   } from '@/store/user';
   import dayjs from 'dayjs';
   import duration from 'dayjs/plugin/duration';
   dayjs.extend(duration);
   const userStore = useUserStore()
   const {
      t
   } = useI18n()
   const homesStore = useHomesStore();
   const router = useRouter()
   const route = useRoute()
   const list = ref([])
   const message = ref('')
   const lastMsgId = ref('')
   const interval = ref(null)
   const unread = ref(0)
   const finished = ref(false)
   const isScrollBottom = ref(true)
   const currentScrollTop = ref(0)
   const androidAttrs = ref(null)
   const navEl = ref(null);
   const boxScrollEl = ref(null);
   const navHeight = ref(0);
   const payInfo = ref({})
   const remainingTime = ref(0)
   let state = ref(null)
   let orderNo = ""
   let partyId = ""
   onMounted(() => {
      // 美洽客服
      // const _ll="&id="+_id.value+"&name="+_name.value
      // const _ll=""
      // console.log(_ll)
      // const _uull='https://cdn.chat20gm.cfd/chat_online/index?channelId=1958101585091772416'+_ll;
      // window.location.href=_uull
   })
   // onMounted_bak(() => {
   //   orderNo = ""
   //   partyId = ""
   //   navHeight.value = navEl.value.$el.getBoundingClientRect().height
   //   if (route.query.order_no) {
   //     getc2cOrderDetails(route.query.order_no, (data) => {
   //       console.log("getc2cOrderDetails = " + JSON.stringify(data))
   //       orderNo = data.orderNo;
   //       partyId = data.partyId;
   //       fetchList()
   //     })
   //   } else {
   //     if (!homesStore.kefu_url) {
   //       fetchList()
   //     }
   //   }
   //   setInterval(() => {
   //     getCountdown()
   //   }, 1000)
   //   const model = navigator.userAgent;
   //   // 判断是否是安卓手机,是则是true
   //   androidAttrs.value = model.indexOf('Android') > -1 || model.indexOf('Linux') > -1
   //   window.addEventListener('scroll', handleScroll, true)
   // })
   onBeforeMount(() => {
      homesStore[SET_KEFU]()
   })
   //获取订单详情
   const getc2cOrderDetails = (orderNo, call) => {
      getc2cOrder({
         order_no: orderNo
      }).then((res) => {
         payInfo.value = res
         state.value = payInfo.value.state
         remainingTime.value = res.autoCancelTimeRemain
         if (call) {
            call(res)
         }
      })
   }
   //第三方客服带用户id
   const generateExtranetLink = () => {
      let extranetLink = ''
      if (userStore.userInfo && userStore.userInfo.usercode) {
         const userData = encodeURIComponent(JSON.stringify({
            name: userStore.userInfo.usercode,
            comment: ''
         }))
         let params = `&clientid=${userStore.userInfo.usercode}&metadata=${userData}`;
         extranetLink = homesStore.kefu_url + params;
      } else {
         extranetLink = homesStore.kefu_url
      }
      // extranetLink = homesStore.kefu_url + params;
      console.log('generateExtranetLink', extranetLink)
      // console.log('extranetLink',extranetLink)
      return extranetLink;
   }
   const throttleSend = throttle((message) => {
      send('text', message)
   }, 500)
   const onOversize = (file) => {
      showToast(t('fileMaxLimit'));
   }
   const onPreview = (url) => { // 预览
      showImagePreview([url])
   }
   const showTime = (index) => { // 时间显示
      if (index === 0) {
         return true
      }
      if (index === list.value.length - 1) {
         return false
      }
      if (list.value[index].createtime.split(' ')[0] === list.value[index + 1].createtime.split(' ')[1]) {
         return false
      }
   }
   const afterRead = (file) => { // 文件上传
      showLoadingToast({
         duration: 0
      })
      _uploadImage(file, (percent) => {
         console.log(percent)
      }).then(data => {
         closeToast()
         send('img', data)
      }).catch(() => {
         showToast(t('失败'))
      })
   }
   const fetchList = async (message_id = '') => { // 获取消息列表
      console.log("orderNo = " + orderNo);
      console.log("partyId = " + partyId);
      _getMsg({
         message_id
      }, orderNo, partyId).then(data => { //
         if (!lastMsgId.value) {
            lastMsgId.value = data.length && data[data.length - 1]['id']
         }
         if (data.length) {
            if (message_id) { // 加载更多
               lastMsgId.value = data[data.length - 1]['id']
               list.value = [...data.reverse(), ...list.value]
            } else {
               list.value = [...list.value, ...data.reverse()]
               let hash = {};
               list.value = list.value.reduce(function(preVal, curVal) {
                  hash[curVal.id] ? ' ' : hash[curVal.id] = true && preVal.push(curVal);
                  return preVal
               }, []);
               list.value.forEach((item, index) => {
                  data.forEach((item2, index2) => {
                     if (item.id === item2.id) {
                        item.delete_status = item2.delete_status
                     }
                  })
               })
            }
            if (isScrollBottom.value) {
               boxScrollEl.value.scrollTop = boxScrollEl.value.scrollHeight - boxScrollEl.value
                  .offsetHeight
            }
            currentScrollTop.value = boxScrollEl.value.scrollTop;
            if (data.length < 10) {
               finished.value = true
            }
         }
         if (!message_id) {
            clearIntervalTimer()
            interval.value = setInterval(() => {
               fetchList()
            }, 1000)
         }
      })
   }
   const handleScroll = () => {
      if (boxScrollEl.value) {
         if (boxScrollEl.value.scrollTop === currentScrollTop.value) {
            isScrollBottom.value = true
         } else {
            isScrollBottom.value = false
         }
      }
   }
   const onMore = () => { // 加载更多
      fetchList(lastMsgId.value)
   }
   const clearIntervalTimer = () => {
      if (interval.value) {
         clearInterval(interval.value)
         interval.value = null
      }
   }
   const fetchUnread = () => { // 获取未读
      _getUnreadMsg(orderNo, partyId).then(data => {
         unread.value = data
      })
   }
   const onClickLeft = () => { // 返回
      router.go(-1);
   }
   const send = (type = 'text', content = '') => { // 发送消息, img 也当消息text
      if (!content) {
         showToast(t('entryMessageContent'))
         return
      }
      _sendMsg(type, content, orderNo, partyId).then(async data => {
         message.value = ''
         isScrollBottom.value = true
         // document.getElementById('bottom').click()
         // await fetchList()
      })
   }
   const getCountdown = () => {
      if (remainingTime.value > 0) {
         remainingTime.value = remainingTime.value - 1
      } else {
         remainingTime.value = 0
      }
   }
   onUnmounted(() => {
      clearIntervalTimer()
   })
</script>
<style lang="scss" scoped>
   .service-box {
      font-size: 14px;
      width: 100%;
      height: 100vh;
      box-sizing: border-box;
      background: $mainBgColor;
      overflow: hidden;
      :deep(.van-hairline--bottom::after) {
         border-color: $mainBgColor;
      }
   }
   .break-word {
      word-wrap: break-word;
      white-space: pre-wrap;
   }
   .max-w-230 {
      max-width: 115px;
   }
   .responser {
      position: relative;
      &::after {
         content: '';
         width: 0;
         height: 0;
         border-top: 5px solid transparent;
         border-bottom: 5px solid transparent;
         border-right: 10px solid $input_background;
         position: absolute;
         left: -10px;
         top: 10px;
      }
   }
   .borderTop {
      border-top: 1px solid $border_color;
   }
   .bottomBox {
      height: 65px;
   }
   .white {
      color: $text_color;
   }
   .chatBg {
      background: $input_background;
      height: 36px;
      padding: 8px 18px;
      border-radius: 18px;
      color: $text_color;
      font-size: 14px;
      border: 1px solid $chat-border;
   }
   .right-chatBg {
      position: relative;
      background: $color_main;
      color: $text_color;
      &::after {
         content: '';
         width: 0;
         height: 0;
         border-top: 5px solid transparent;
         border-bottom: 5px solid transparent;
         border-left: 10px solid $color_main;
         position: absolute;
         right: -8px;
         top: 14px;
      }
   }
   .left-chatBg {
      background: $input_background;
   }
   .localKefu {
      overflow: auto;
      flex-direction: column;
   }
   .van-nav-bar--fixed {
      position: relative !important;
   }
</style>