|  | @@ -0,0 +1,252 @@
 | 
	
		
			
				|  |  | +<template>
 | 
	
		
			
				|  |  | +  <div class="chatting">
 | 
	
		
			
				|  |  | +    <div class="top-info">
 | 
	
		
			
				|  |  | +      <div class="user-info d-flex align-center">
 | 
	
		
			
				|  |  | +        <p class="d-flex align-center float-left">
 | 
	
		
			
				|  |  | +          <span class="name">钟女士</span>
 | 
	
		
			
				|  |  | +          <span>广州市番禺区洛浦街道12号</span>
 | 
	
		
			
				|  |  | +          <span class="septal-line"></span>
 | 
	
		
			
				|  |  | +          <span>负责人</span>
 | 
	
		
			
				|  |  | +        </p>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +      <div class="position-content">
 | 
	
		
			
				|  |  | +        <span class="color-222">无责4k电话客服+朝九晚六+不加班</span>
 | 
	
		
			
				|  |  | +        <span class="salary mx-4">4-8k</span>
 | 
	
		
			
				|  |  | +        <span class="color-333">广州</span>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +    <div class="chat-record mt-3">
 | 
	
		
			
				|  |  | +      <div class="message-box" @scroll="handleScroll" ref="chatRef">
 | 
	
		
			
				|  |  | +        <div v-for="(val, i) in items" :key="i" :id="val.id">
 | 
	
		
			
				|  |  | +          <div class="time-box">{{ val.time }}</div>
 | 
	
		
			
				|  |  | +          <div :class="['message-view_item', val.userId === myUserId ? 'is-self' : 'is-other']">
 | 
	
		
			
				|  |  | +            <div style="width: 40px; height: 40px;"><v-img :src="val.avatar" :width="40" height="40" rounded></v-img></div>
 | 
	
		
			
				|  |  | +            <div class="message-text">{{ val.text }}</div>
 | 
	
		
			
				|  |  | +          </div>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +    <div class="bottom-info">
 | 
	
		
			
				|  |  | +      <v-divider></v-divider>
 | 
	
		
			
				|  |  | +      <div class="px-5 py-3">
 | 
	
		
			
				|  |  | +        <v-text-field  v-model="inputVal" label="请输入消息" color="primary" density="comfortable" variant="plain"></v-text-field>
 | 
	
		
			
				|  |  | +        <div class="d-flex align-center justify-end bottom-send">
 | 
	
		
			
				|  |  | +          <div class="color-ccc font-size-14 mr-5">按Enter键发送</div>
 | 
	
		
			
				|  |  | +          <v-btn color="primary" size="small" :disabled="!inputVal">发送</v-btn>
 | 
	
		
			
				|  |  | +        </div>
 | 
	
		
			
				|  |  | +      </div>
 | 
	
		
			
				|  |  | +    </div>
 | 
	
		
			
				|  |  | +  </div>
 | 
	
		
			
				|  |  | +</template>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<script setup>
 | 
	
		
			
				|  |  | +defineOptions({ name: 'message-chatting'})
 | 
	
		
			
				|  |  | +import { ref, nextTick, onMounted } from 'vue'
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const chatRef = ref()
 | 
	
		
			
				|  |  | +const inputVal = ref()
 | 
	
		
			
				|  |  | +const pullDowning = ref(false) // 下拉中
 | 
	
		
			
				|  |  | +const pulldownFinished = ref(false) // 下拉完成
 | 
	
		
			
				|  |  | +const myUserId = 1
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const items = ref([
 | 
	
		
			
				|  |  | +  { userId: 1, text: '你好', avatar: 'https://minio.citupro.com/dev/menduner/tx1.jpg', time: '11:15', id: 1 },
 | 
	
		
			
				|  |  | +  { userId: 2, text: '你好', avatar: 'https://minio.citupro.com/dev/menduner/tx1.jpg', time: '11:15', id: 2 },
 | 
	
		
			
				|  |  | +  { userId: 2, text: '你好', avatar: 'https://minio.citupro.com/dev/menduner/tx1.jpg', time: '11:15', id: 3 },
 | 
	
		
			
				|  |  | +  { userId: 1, text: '你好', avatar: 'https://minio.citupro.com/dev/menduner/tx1.jpg', time: '11:15', id: 4 },
 | 
	
		
			
				|  |  | +  { userId: 1, text: '你好', avatar: 'https://minio.citupro.com/dev/menduner/tx1.jpg', time: '11:15', id: 5 },
 | 
	
		
			
				|  |  | +  { userId: 2, text: '你好', avatar: 'https://minio.citupro.com/dev/menduner/tx1.jpg', time: '11:15', id: 6 },
 | 
	
		
			
				|  |  | +  { userId: 1, text: '你好', avatar: 'https://minio.citupro.com/dev/menduner/tx1.jpg', time: '11:15', id: 7 },
 | 
	
		
			
				|  |  | +  { userId: 1, text: '你好', avatar: 'https://minio.citupro.com/dev/menduner/tx1.jpg', time: '11:15', id: 8 },
 | 
	
		
			
				|  |  | +  { userId: 2, text: '你好', avatar: 'https://minio.citupro.com/dev/menduner/tx1.jpg', time: '11:15', id: 9 },
 | 
	
		
			
				|  |  | +  { userId: 1, text: '你好', avatar: 'https://minio.citupro.com/dev/menduner/tx1.jpg', time: '11:15', id: 10 },
 | 
	
		
			
				|  |  | +  { userId: 2, text: '你好', avatar: 'https://minio.citupro.com/dev/menduner/tx1.jpg', time: '11:15', id: 11 }
 | 
	
		
			
				|  |  | +])
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// 滚动到底部
 | 
	
		
			
				|  |  | +const scrollBottom = () => {
 | 
	
		
			
				|  |  | +  const chat = chatRef.value
 | 
	
		
			
				|  |  | +  if (chat) {
 | 
	
		
			
				|  |  | +    nextTick(function () {
 | 
	
		
			
				|  |  | +      chat.scrollTop = chat.scrollHeight
 | 
	
		
			
				|  |  | +    })
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +onMounted(() => {
 | 
	
		
			
				|  |  | +  nextTick(() => {
 | 
	
		
			
				|  |  | +    scrollBottom()
 | 
	
		
			
				|  |  | +  })
 | 
	
		
			
				|  |  | +})
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +// const pullDown = async () => {
 | 
	
		
			
				|  |  | +//   if (messages.value.length == 0) {
 | 
	
		
			
				|  |  | +//     return
 | 
	
		
			
				|  |  | +//   }
 | 
	
		
			
				|  |  | +//   const firstMsg = messages.value[0]
 | 
	
		
			
				|  |  | +//   if (firstMsg.messageSeq == 1) {
 | 
	
		
			
				|  |  | +//     pulldownFinished.value = true
 | 
	
		
			
				|  |  | +//     return
 | 
	
		
			
				|  |  | +//   }
 | 
	
		
			
				|  |  | +//   const limit = 15
 | 
	
		
			
				|  |  | +//   const msgs = await WKSDK.shared().chatManager.syncMessages(to.value, {
 | 
	
		
			
				|  |  | +//     limit: limit,
 | 
	
		
			
				|  |  | +//     startMessageSeq: firstMsg.messageSeq - 1,
 | 
	
		
			
				|  |  | +//     endMessageSeq: 0,
 | 
	
		
			
				|  |  | +//     pullMode: PullMode.Down,
 | 
	
		
			
				|  |  | +//   })
 | 
	
		
			
				|  |  | +//   if (msgs.length < limit) {
 | 
	
		
			
				|  |  | +//     pulldownFinished.value = true;
 | 
	
		
			
				|  |  | +//   }
 | 
	
		
			
				|  |  | +//   if (msgs && msgs.length > 0) {
 | 
	
		
			
				|  |  | +//     msgs.reverse().forEach((m) => {
 | 
	
		
			
				|  |  | +//       messages.value.unshift(m)
 | 
	
		
			
				|  |  | +//     })
 | 
	
		
			
				|  |  | +//   }
 | 
	
		
			
				|  |  | +//   nextTick(function () {
 | 
	
		
			
				|  |  | +//     const chat = chatRef.value
 | 
	
		
			
				|  |  | +//     const firstMsgEl = document.getElementById(firstMsg.clientMsgNo)
 | 
	
		
			
				|  |  | +//     if (firstMsgEl) {
 | 
	
		
			
				|  |  | +//       chat.scrollTop = firstMsgEl.offsetTop
 | 
	
		
			
				|  |  | +//     }
 | 
	
		
			
				|  |  | +//   })
 | 
	
		
			
				|  |  | +// }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +const handleScroll = (e) => {
 | 
	
		
			
				|  |  | +  const targetScrollTop = e.target.scrollTop;
 | 
	
		
			
				|  |  | +  if (targetScrollTop <= 250) {
 | 
	
		
			
				|  |  | +    // 下拉
 | 
	
		
			
				|  |  | +    if (pullDowning.value || pulldownFinished.value) {
 | 
	
		
			
				|  |  | +      return
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    console.log('下拉')
 | 
	
		
			
				|  |  | +    pullDowning.value = true
 | 
	
		
			
				|  |  | +    // pullDown().then(() => {
 | 
	
		
			
				|  |  | +    //   pullDowning.value = false
 | 
	
		
			
				|  |  | +    // }).catch(() => {
 | 
	
		
			
				|  |  | +    //   pullDowning.value = false
 | 
	
		
			
				|  |  | +    // })
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +</script>
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +<style scoped lang="scss">
 | 
	
		
			
				|  |  | +.chatting {
 | 
	
		
			
				|  |  | +  position: relative;
 | 
	
		
			
				|  |  | +  height: 100%;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.top-info {
 | 
	
		
			
				|  |  | +  height: 104px;
 | 
	
		
			
				|  |  | +  .user-info {
 | 
	
		
			
				|  |  | +    position: relative;
 | 
	
		
			
				|  |  | +    height: 48px;
 | 
	
		
			
				|  |  | +    justify-content: space-between;
 | 
	
		
			
				|  |  | +    padding: 0 30px;
 | 
	
		
			
				|  |  | +    span {
 | 
	
		
			
				|  |  | +      font-size: 14px;
 | 
	
		
			
				|  |  | +      font-weight: 400;
 | 
	
		
			
				|  |  | +      color: var(--color-666);
 | 
	
		
			
				|  |  | +      line-height: 22px;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .name {
 | 
	
		
			
				|  |  | +      line-height: 25px;
 | 
	
		
			
				|  |  | +      margin-right: 20px;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +  .position-content {
 | 
	
		
			
				|  |  | +    position: relative;
 | 
	
		
			
				|  |  | +    padding: 16px;
 | 
	
		
			
				|  |  | +    border-radius: 12px;
 | 
	
		
			
				|  |  | +    margin: auto;
 | 
	
		
			
				|  |  | +    width: 760px;
 | 
	
		
			
				|  |  | +    background: linear-gradient(90deg, #f5fcfc, #fcfbfa);
 | 
	
		
			
				|  |  | +    .salary {
 | 
	
		
			
				|  |  | +      font-size: 20px;
 | 
	
		
			
				|  |  | +      font-family: 'Franklin Gothic Medium', 'Arial Narrow', Arial, sans-serif;
 | 
	
		
			
				|  |  | +      color: var(--v-error-base);
 | 
	
		
			
				|  |  | +      line-height: 24px;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.chat-record {
 | 
	
		
			
				|  |  | +  
 | 
	
		
			
				|  |  | +  padding-bottom: 30px;
 | 
	
		
			
				|  |  | +  .message-box {
 | 
	
		
			
				|  |  | +    height: 525px;
 | 
	
		
			
				|  |  | +    padding: 0 30px 20px;
 | 
	
		
			
				|  |  | +    overflow-y: auto;
 | 
	
		
			
				|  |  | +    .time-box {
 | 
	
		
			
				|  |  | +      user-select: none;
 | 
	
		
			
				|  |  | +      position: relative;
 | 
	
		
			
				|  |  | +      top: 8px;
 | 
	
		
			
				|  |  | +      margin: 20px 0;
 | 
	
		
			
				|  |  | +      max-height: 20px;
 | 
	
		
			
				|  |  | +      text-align: center;
 | 
	
		
			
				|  |  | +      font-weight: 400;
 | 
	
		
			
				|  |  | +      font-size: 12px;
 | 
	
		
			
				|  |  | +      color: var(--color-time-divider);
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .message-view_item {
 | 
	
		
			
				|  |  | +      display: flex;
 | 
	
		
			
				|  |  | +      flex-direction: row;
 | 
	
		
			
				|  |  | +      align-items: center;
 | 
	
		
			
				|  |  | +      margin: 8px 0;
 | 
	
		
			
				|  |  | +      position: relative;
 | 
	
		
			
				|  |  | +      .message-text {
 | 
	
		
			
				|  |  | +        background-color: #f0f2f5;
 | 
	
		
			
				|  |  | +        border-radius: 6px;
 | 
	
		
			
				|  |  | +        max-width: 85%;
 | 
	
		
			
				|  |  | +        padding: 10px;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .is-self {
 | 
	
		
			
				|  |  | +      flex-direction: row-reverse;
 | 
	
		
			
				|  |  | +      display: flex;
 | 
	
		
			
				|  |  | +      .message-text {
 | 
	
		
			
				|  |  | +        margin-right: 10px;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    .is-other {
 | 
	
		
			
				|  |  | +      .message-text {
 | 
	
		
			
				|  |  | +        margin-left: 10px;
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +.bottom-info {
 | 
	
		
			
				|  |  | +  position: absolute;
 | 
	
		
			
				|  |  | +  bottom: 0;
 | 
	
		
			
				|  |  | +  width: 100%;
 | 
	
		
			
				|  |  | +  height: 160px;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +input {
 | 
	
		
			
				|  |  | +  outline: none;
 | 
	
		
			
				|  |  | +  width: 748px;
 | 
	
		
			
				|  |  | +  height: 60px; 
 | 
	
		
			
				|  |  | +  max-width: 748px; 
 | 
	
		
			
				|  |  | +  overflow: auto;
 | 
	
		
			
				|  |  | +  white-space: pre-wrap;
 | 
	
		
			
				|  |  | +  &:focus {
 | 
	
		
			
				|  |  | +    border: none;
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +/* 滚动条样式 */
 | 
	
		
			
				|  |  | +::-webkit-scrollbar {
 | 
	
		
			
				|  |  | +  -webkit-appearance: none;
 | 
	
		
			
				|  |  | +  width: 0px;
 | 
	
		
			
				|  |  | +  height: 0px;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +/* 滚动条内的轨道 */
 | 
	
		
			
				|  |  | +::-webkit-scrollbar-track {
 | 
	
		
			
				|  |  | +  background: rgba(0, 0, 0, 0.1);
 | 
	
		
			
				|  |  | +  border-radius: 0;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +/* 滚动条内的滑块 */
 | 
	
		
			
				|  |  | +::-webkit-scrollbar-thumb {
 | 
	
		
			
				|  |  | +  cursor: pointer;
 | 
	
		
			
				|  |  | +  border-radius: 5px;
 | 
	
		
			
				|  |  | +  background: rgba(0, 0, 0, 0.15);
 | 
	
		
			
				|  |  | +  transition: color 0.2s ease;
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  | +</style>
 |