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="width: 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="width: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; width: 33px; height: 32px; } .text { display: inline-block; position: relative; padding: 0 10px; max-width: 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 }
将来的自己,会感谢现在不放弃的自己!