客服聊天列表使用scroll-view原生组件,移除 z-paging 组件

pull/147/MERGE
YunaiV 2025-05-12 22:18:50 +08:00
parent f6e74b12cb
commit dd71ba7d9e
3 changed files with 48 additions and 25 deletions

View File

@ -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);
} },
}); });
// //

View File

@ -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;

View File

@ -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;