客服聊天列表使用scroll-view原生组件,移除 z-paging 组件
							parent
							
								
									f6e74b12cb
								
							
						
					
					
						commit
						dd71ba7d9e
					
				|  | @ -19,13 +19,13 @@ | |||
|       class="sicon-edit" | ||||
|       :class="{ 'is-active': toolsMode === 'tools' }" | ||||
|       @tap.stop="onTools('tools')" | ||||
|     ></text> | ||||
|     /> | ||||
|     <button | ||||
|       v-if="message" | ||||
|       class="ss-reset-button send-btn" | ||||
|       @tap="sendMessage" | ||||
|       :disabled="isDisabled || sending" | ||||
|       :class="{ 'disabled': isDisabled || sending }" | ||||
|       :class="{ disabled: isDisabled || sending }" | ||||
|     > | ||||
|       <text v-if="sending">发送中</text> | ||||
|       <text v-else>发送</text> | ||||
|  | @ -52,18 +52,18 @@ | |||
|     // 是否自动获取焦点 | ||||
|     autoFocus: { | ||||
|       type: Boolean, | ||||
|       default: false | ||||
|       default: false, | ||||
|     }, | ||||
|     // 最大字数限制 | ||||
|     maxLength: { | ||||
|       type: Number, | ||||
|       default: 500 | ||||
|       default: 500, | ||||
|     }, | ||||
|     // 是否显示字数统计 | ||||
|     showCharCount: { | ||||
|       type: Boolean, | ||||
|       default: true | ||||
|     } | ||||
|       default: true, | ||||
|     }, | ||||
|   }); | ||||
| 
 | ||||
|   const emits = defineEmits(['update:modelValue', 'onTools', 'sendMessage']); | ||||
|  | @ -74,7 +74,7 @@ | |||
|     }, | ||||
|     set(newValue) { | ||||
|       emits(`update:modelValue`, newValue); | ||||
|     } | ||||
|     }, | ||||
|   }); | ||||
| 
 | ||||
|   // 控制发送状态 | ||||
|  |  | |||
|  | @ -1,19 +1,34 @@ | |||
| <template> | ||||
|   <!--  聊天列表使用scroll-view原生组件,整体倒置  --> | ||||
|   <scroll-view :scroll-top="scroll.top" class="chat-scroll-view" scroll-y :refresher-enabled="false" | ||||
|                @scroll="onScroll" @scrolltolower="loadMoreHistory" style="transform: scaleY(-1);"> | ||||
|   <scroll-view | ||||
|     :scroll-top="scroll.top" | ||||
|     class="chat-scroll-view" | ||||
|     scroll-y | ||||
|     :refresher-enabled="false" | ||||
|     @scroll="onScroll" | ||||
|     @scrolltolower="loadMoreHistory" | ||||
|     style="transform: scaleY(-1)" | ||||
|   > | ||||
|     <!-- 消息列表容器 --> | ||||
|     <view class="message-container"> | ||||
|       <!-- 加载更多提示 --> | ||||
|       <view v-if="isLoading" class="loading-more" style="transform: scaleY(-1);"> | ||||
|       <view v-if="isLoading" class="loading-more" style="transform: scaleY(-1)"> | ||||
|         <text>加载中...</text> | ||||
|       </view> | ||||
|       <!-- 消息列表 --> | ||||
|       <view class="message-list"> | ||||
|         <view v-for="(item, index) in messageList" :key="item.id" class="message-item" | ||||
|               style="transform: scaleY(-1);"> | ||||
|         <view | ||||
|           v-for="(item, index) in messageList" | ||||
|           :key="item.id" | ||||
|           class="message-item" | ||||
|           style="transform: scaleY(-1)" | ||||
|         > | ||||
|           <!--  消息渲染  --> | ||||
|           <MessageListItem :message="item" :message-index="index" :message-list="messageList"></MessageListItem> | ||||
|           <MessageListItem | ||||
|             :message="item" | ||||
|             :message-index="index" | ||||
|             :message-list="messageList" | ||||
|           ></MessageListItem> | ||||
|         </view> | ||||
|       </view> | ||||
|     </view> | ||||
|  | @ -22,7 +37,9 @@ | |||
|   <!-- 底部聊天输入框 --> | ||||
|   <su-fixed bottom> | ||||
|     <view v-if="showTip" class="back-top ss-flex ss-row-center ss-m-b-10" @tap="scrollToTop"> | ||||
|       <text class="back-top-item ss-flex ss-row-center">{{ showNewMessageTip ? '有新消息' : '回到底部' }}</text> | ||||
|       <text class="back-top-item ss-flex ss-row-center"> | ||||
|         {{ showNewMessageTip ? '有新消息' : '回到底部' }} | ||||
|       </text> | ||||
|     </view> | ||||
|     <slot name="bottom"></slot> | ||||
|   </su-fixed> | ||||
|  | @ -33,7 +50,7 @@ | |||
|   import { onMounted, reactive, ref, computed } from 'vue'; | ||||
|   import KeFuApi from '@/sheep/api/promotion/kefu'; | ||||
|   import { isEmpty } from '@/sheep/helper/utils'; | ||||
|   import { formatDate } from '@/sheep/util'; | ||||
|   import { formatDate } from '@/sheep/helper/utils'; | ||||
|   import sheep from '@/sheep'; | ||||
| 
 | ||||
|   const { safeAreaInsets } = sheep.$platform.device; | ||||
|  | @ -95,8 +112,8 @@ | |||
|         } | ||||
| 
 | ||||
|         // 过滤掉已存在的消息 | ||||
|         const historyMessages = data.filter(msg => | ||||
|           !messageList.value.some(existing => existing.id === msg.id), | ||||
|         const historyMessages = data.filter( | ||||
|           (msg) => !messageList.value.some((existing) => existing.id === msg.id), | ||||
|         ); | ||||
| 
 | ||||
|         if (historyMessages.length > 0) { | ||||
|  | @ -187,10 +204,16 @@ | |||
|     // H5环境 | ||||
|     window.addEventListener('resize', () => { | ||||
|       // 窗口大小变化可能是由键盘引起的 | ||||
|       if (document.activeElement && (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA')) { | ||||
|       if ( | ||||
|         document.activeElement && | ||||
|         (document.activeElement.tagName === 'INPUT' || | ||||
|           document.activeElement.tagName === 'TEXTAREA') | ||||
|       ) { | ||||
|         // 估算键盘高度,实际上是窗口高度变化 | ||||
|         const currentHeight = window.innerHeight; | ||||
|         const viewportHeight = window.visualViewport ? window.visualViewport.height : window.innerHeight; | ||||
|         const viewportHeight = window.visualViewport | ||||
|           ? window.visualViewport.height | ||||
|           : window.innerHeight; | ||||
|         const keyboardHeight = currentHeight - viewportHeight; | ||||
|         setKeyboardHeight(keyboardHeight > 0 ? keyboardHeight : 0); | ||||
|       } else { | ||||
|  | @ -213,7 +236,7 @@ | |||
|     scroll.value = { | ||||
|       top: 0, | ||||
|       oldTop: 0, | ||||
|     } | ||||
|     }; | ||||
|     getMessageList(); | ||||
|     setupKeyboardListeners(); | ||||
|   }); | ||||
|  |  | |||
|  | @ -44,7 +44,7 @@ | |||
|           " | ||||
|           mode="aspectFill" | ||||
|           lazy-load | ||||
|         ></image> | ||||
|         /> | ||||
|         <!-- 内容 --> | ||||
|         <template v-if="message.contentType === KeFuMessageContentTypeEnum.TEXT"> | ||||
|           <view class="message-box" :class="{ admin: message.senderType === UserTypeEnum.ADMIN }"> | ||||
|  | @ -66,7 +66,7 @@ | |||
|               :height="200" | ||||
|               :width="200" | ||||
|               mode="aspectFill" | ||||
|             ></su-image> | ||||
|             /> | ||||
|           </view> | ||||
|         </template> | ||||
|         <template v-if="message.contentType === KeFuMessageContentTypeEnum.PRODUCT"> | ||||
|  | @ -145,7 +145,7 @@ | |||
|   // 缓存表情映射 | ||||
|   const emojiMap = computed(() => { | ||||
|     const map = new Map(); | ||||
|     emojiList.forEach(emoji => { | ||||
|     emojiList.forEach((emoji) => { | ||||
|       map.set(emoji.name, emoji.file); | ||||
|     }); | ||||
|     return map; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 YunaiV
						YunaiV