• dialog-实现滚动聊天窗口


    未完待续...

    1.实现的vue

    <!--聊天窗口-->
    <template>
      <div class="soundRecordDialog">
        <el-dialog
          title="聊天窗口"
          :visible="soundVisible"
          :close-on-click-modal="false"
          :close-on-press-escape="false"
          center
          @close="closeAudioWindow()"
        >
          <audio :src="audioUrl" style=" 85%;outline:0;" controls></audio>
          <!-- <iframe :src="audioUrl" width="100%" height="140px" frameborder="0"></iframe> -->
          <div class="dialog-box">
          <div class="dialog-main">
            <div class="dialog-content">
              <img slot="reference" class="dialog-content-sub" src="@/assets/callingResult/callingResult_phone.png" />
              <span class="dialog-content-sub"> {{ detailName }}</span>
              <span class="dialog-content-sub">{{ detailPhone }}</span>
              <span class="dialog-content-sub">{{ detailCallingStatus }}</span>
            </div>
          </div>
          <div class="dialog-message" id="scroll">
            <ul class="position-box">
              <li v-for="item in detailList" :key="item.index">
                <div class="main">
                  <div v-if="item.sRobotSpeech || item.sRobotSpeechId" class="dialog-robot">
                    <img class="avatar" src="@/assets/callingResult/callingResult_system_icon.png" />
                    <div class="text" v-html="handleRobotText(item)" style="text-align:left"></div>
                  </div>
                  <div v-if="item.sCustomerSpeech || item.sIntentionId || item.sIntention" class="dialog-self">
                    <img class="avatar" src="@/assets/callingResult/callingResult_self_icon.png" />
                    <div class="text" style="text-align: center" v-html="handleCustomPeopleText(item)"></div>
                  </div>
                </div>
              </li>
            </ul>
              <div style="text-align: center;height:25px;" v-if="callLoading">
                <img src="@/assets/loading.gif" style="20px; height:20px;">
              </div>
              <div v-if="!loadMore" style="text-align: center;height:30px;">
                {{ handleLoadMoreText(loadMore, this.detailList) }}
              </div>
            </div>
          </div>
        </el-dialog>
      </div>
    </template>
    <script>
    import { setRobotText, setCustomPeopleText, setLoadMoreText, hanldPhoneFormatToValue } from '@/utils/common'
    export default {
      name: 'soundRecord',
      data () {
        return {
          callLoading: true,
          loadMore: true, // 加载更多,默认Yes
          detailName: '',
          detailPhone: '',
          detailCallingStatus: '',
          detailParams: {
            pageNum: 1,
            pageSize: 10,
            callId: ''
          },
          soundCallList: [],
          detailCallResData: [], // 列表
          detailList: [] // 列表
        }
      },
      props: {
        audioUrl: {
          default: '',
          type: String
        },
        callSoundData: {
          default: null,
          type: Object
        },
        soundVisible: {
          default: false,
          type: Boolean
        }
      },
      async created () {
        if (this.callSoundData && this.callSoundData.callId && this.callSoundData.callId.length > 0) {
          this.detailParams.callId = this.callSoundData.callId
          this.detailParams.pageNum = 1
          this.detailName = this.callSoundData.customerName
          this.detailPhone = this.hanlePhoneFormat(this.callSoundData.customerPhone)
          this.detailCallingStatus = this.callSoundData.callState
          await this.callDetaiList()
          this.detailList = this.detailCallResData
          if (this.detailList.length > 0) {
            this.$nextTick(() => {
              this.detailParams.pageNum = 1
              document.getElementById('scroll').scrollTop = 0
              if (this.detailParams.pageNum === 1 && this.detailList && this.detailList.length < 10) {
                this.callDetailListLoadMoreFlag(false)
                return
              } else if (document.getElementById('scroll').clientHeight === document.getElementById('scroll').scrollHeight) {
                this.handleScroll()
                return
              } else {
                this.callDetailListLoadMoreFlag(true)
              }
              document.getElementById('scroll').addEventListener('scroll', this.handleScroll)
            })
          } else {
            this.callDetailListLoadMoreFlag(false)
          }
        }
      },
      methods: {
        // 关闭录音
        closeAudioWindow () {
          this.$emit('close')
        },
        // 处理机器人话术
        handleRobotText (item) {
          return setRobotText(item)
        },
        handleCustomPeopleText (item) {
          return setCustomPeopleText(item)
        },
        // 处理没有更多数据了文字
        handleLoadMoreText (loadMore, soundCallList) {
          return setLoadMoreText(loadMore, soundCallList)
        },
        // 明细列表
        async callDetaiList () {
          await this.$store.dispatch('callResultDetailList', this.detailParams).then(res => {
            this.detailCallResData = res.data.detailLists
          })
        },
        // 处理电话显示
        hanlePhoneFormat (phone) {
          return hanldPhoneFormatToValue(phone)
        },
        // 处理更多
        callDetailListLoadMoreFlag (flag) {
          this.loadMore = flag
          this.callLoading = flag
        },
        // 处理滚动到底部的事件
        handleScroll () {
          if (this.detailParams.pageNum === 1 && this.detailList && this.detailList.length < 10) {
            this.callDetailListLoadMoreFlag(false)
            this.removeCallDetailScrollLiten()
            return
          }
          var clientHeight = document.getElementById('scroll').clientHeight // 客户区大小
          var scrollHeight = document.getElementById('scroll').scrollHeight // 没用滚动条的情况下,元素内容的总高度
          var scrollTop = document.getElementById('scroll').scrollTop // 被隐藏在内容区域上方的像素数
          if (scrollTop + clientHeight + 0.5 >= scrollHeight && this.loadMore) {
            this.onPullingUp()
          }
          if (!this.loadMore) {
            this.callDetailListLoadMoreFlag(false)
            this.removeCallDetailScrollLiten()
          }
        },
        // 删除明细滚动监听
        removeCallDetailScrollLiten () {
          document.getElementById('scroll').removeEventListener('scroll', this.handleScroll)
        },
        async onPullingUp () {
          this.detailCallResData = []
          this.detailParams.pageNum++
          this.callLoading = true
          await this.callDetaiList()
          if (this.detailCallResData && this.detailCallResData.length > 0) {
            this.detailList = this.detailList.concat(this.detailCallResData)
            console.log('--detailCallResData--', this.detailList)
            if (this.detailCallResData.length < 10) {
              this.callDetailListLoadMoreFlag(false)
              this.removeCallDetailScrollLiten()
            }
          } else {
            this.callDetailListLoadMoreFlag(false)
            this.removeCallDetailScrollLiten()
          }
        }
      }
    }
    </script>
    <style lang="scss">
      .soundRecordDialog {
        display: flex;
        justify-content: center;
        align-items: Center;
        overflow: hidden;
        .el-dialog {
          margin: 60px auto !important;
          height: 90%;
          overflow: hidden;
          .el-dialog__header {
            text-align: left;
          }
          .el-dialog__body {
            padding: 20px 0px 20px 0px;
            position: absolute;
            left: 0;
            top: 54px;
            bottom: 0;
            right: 0;
            padding: 0;
            z-index: 1;
            overflow: hidden;
            text-align: center;
            .dialog-box {
            .dialog-main {
              background: #fef7ea;
              height: 40px;
              .dialog-content {
                padding: 11px 20px 8px 11px;
                font-size: #686A76;
                float:left;
                .dialog-content-sub {
                  margin-right: 2px;
                }
              }
            }
            .dialog-message {
                overflow-y: scroll;
                position: absolute;
                top: 104px;
                bottom:0;
                right: 0;
                left: 0;
                .position-box {
                  margin-top: 60px;
                  padding-left: 20px;
                  .main {
                    text-align: left;
                  }
                ul {
                  margin-left: -20px;
                }
                li {
                  list-style-type: none;
                  margin-bottom: 15px;
                }
                .avatar {
                  float: left;
                  margin: 0 10px 0 0;
                  border-radius: 3px;
                   33px;
                  height: 32px;
                }
                .text {
                  display: inline-block;
                  position: relative;
                  padding: 0 10px;
                  max- calc(100% - 120px);
                  min-height: 30px;
                  line-height: 30px;
                  font-size: 12px;
                  text-align: left;
                  word-break: break-all;
                  background-color: #fafafa;
                  border-radius: 4px;
                  &:before {
                    content: " ";
                    position: absolute;
                    top: 9px;
                    right: 100%;
                    border: 6px solid transparent;
                    border-right-color: #fafafa;
                  }
                }
              .dialog-robot {
                display: inline;
                text-align: left;
              }
              .dialog-self {
                  text-align: right;
                  margin-top: 20px;
                  .avatar {
                    float: right;
                    margin: 0 20px 0 10px;
                  }
                  .text {
                    background-color: #b2e281;
                    &:before {
                      right: inherit;
                      left: 100%;
                      border-right-color: transparent;
                      border-left-color: #b2e281;
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    </style>

    2. 调用的方法

    // 处理聊天人A
    export function setRobotText(item) {
      if (item.sRobotSpeechId && item.sRobotSpeechId.length) {
        return `<span style="font-weight: bolder;font-size: 13px;">${item.sRobotSpeechId}:</span>${item.sRobotSpeech}`
      }
      return item.sRobotSpeech
    }
    // 处理聊天人B
    export function setCustomPeopleText(item) {
      if (item.sIntentionDetail && item.sIntentionDetail.length) {
        if (item.sIntention && item.sIntention.length > 0) {
          if (item.sCustomerSpeech && item.sCustomerSpeech.length > 0) {
            return `<span style="font-weight: bolder;font-size: 13px;">${item.sIntention}-${item.sIntentionDetail}:</span>${item.sCustomerSpeech}`
          }else {
            return `<span style="font-weight: bolder;font-size: 13px;">${item.sIntention}-${item.sIntentionDetail}`
          }
        } else if (item.sCustomerSpeech && item.sCustomerSpeech.length > 0) {
          return `<span style="font-weight: bolder;font-size: 13px;">${item.sIntentionDetail}:</span>${item.sCustomerSpeech}`
        } else {
          return `<span style="font-weight: bolder;font-size: 13px;">${item.sIntentionDetail}</span>`
        }
      } else if (item.sIntention && item.sIntention.length) {
        if (item.sCustomerSpeech && item.sCustomerSpeech.length > 0) {
          return `<span style="font-weight: bolder;font-size: 13px;">${item.sIntention}:</span>${item.sCustomerSpeech}`
        } else {
          return `<span style="font-weight: bolder;font-size: 13px;">${item.sIntention}</span>`
        }
      }
      return item.sCustomerSpeech
    }
    export function setLoadMoreText(loadMore, detailList) {
      let text = '没有更多数据了'
      if (!loadMore && detailList && detailList.length > 0) {
        let item = detailList[detailList.length-1]
        if (item.robotId) {
          return `${item.robotId}聊天结束`
        }
        return text
      }
      return text
    }
  • 相关阅读:
    Objective C中提供了线程同步和异常处理
    iOS singleton单例模式的实现
    转:IOS UITableView中行的操作
    Javascript 函数
    ios category类别的使用
    vmware Ubuntu非法关机后启动不起来
    C++ Socket编程步骤
    C/C++ 笔试、面试题目大汇总(转)
    Linux下基于C/C++的Socket编程基础
    C++经典面试题
  • 原文地址:https://www.cnblogs.com/TheYouth/p/14213080.html
Copyright © 2020-2023  润新知