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