fix(customer-service): 修复在线客服功能使其可用

- 在微信客服按钮补全必要属性 sessionFrom、onContact、showMessageCard 和 sendMessageTitle
- 将按钮样式由 Tailwind 类改为内联样式,避免 border-0 干扰原生按钮渲染
- 添加真机预览测试提示,解决开发者工具无法使用问题
- `ShopChatMessage` 和相关接口新增 conversationId 字段支持消息会话关联
- 消息发送时补全 conversationId 和发送人 ID,保证消息关联准确
- 将会话列表中引用的不存在字段 lastMessage 替换为 content
- 移除无用的 useReachBottom,改用 ScrollView 的 onScrollToLower 事件加载历史消息
- 删除未使用的 scrollToBottom ref
- 增加条件守卫避免非历史展开时加载更多消息
This commit is contained in:
2026-07-14 20:49:28 +08:00
parent 78abab1364
commit 889a0f983e
3 changed files with 83 additions and 16 deletions

View File

@@ -1,13 +1,13 @@
import React, { useEffect, useState, useCallback, useRef } from 'react'
import { View, Text, Button, Input, ScrollView } from '@tarojs/components'
import Taro, { useReachBottom } from '@tarojs/taro'
import Taro from '@tarojs/taro'
import NavBar from '@/components/NavBar'
import LoadMore from '@/components/common/LoadMore'
import EmptyState from '@/components/common/EmptyState'
import { pageShopChatConversation, addShopChatConversation } from '@/api/shop/shopChatConversation'
import { pageShopChatMessage, addShopChatMessage } from '@/api/shop/shopChatMessage'
import type { ShopChatConversation, ShopChatConversationParam } from '@/api/shop/shopChatConversation/model'
import type { ShopChatMessage } from '@/api/shop/shopChatMessage/model'
import type { ShopChatMessage, ShopChatMessageParam } from '@/api/shop/shopChatMessage/model'
import type { PageResult } from '@/api'
definePageConfig({
@@ -29,7 +29,6 @@ const CustomerServicePage: React.FC = () => {
const [hasMore, setHasMore] = useState(true)
const [msgPage, setMsgPage] = useState(1)
const [showHistory, setShowHistory] = useState(false)
const scrollToBottom = useRef(false)
const isOnline = () => {
const now = new Date()
@@ -37,6 +36,12 @@ const CustomerServicePage: React.FC = () => {
return h >= 9 && h < 21
}
// 获取当前用户ID
const getCurrentUserId = (): number | undefined => {
const id = Taro.getStorageSync('UserId')
return id || undefined
}
// 加载会话列表
const loadConversations = useCallback(async () => {
setLoading(true)
@@ -68,19 +73,19 @@ const CustomerServicePage: React.FC = () => {
const loadMessages = useCallback(async (conversationId: number, pageNum: number = 1, isLoadMore = false) => {
if (isLoadMore) setLoadingMore(true)
try {
const result = await pageShopChatMessage({
const params: ShopChatMessageParam = {
conversationId,
page: pageNum,
limit: 20,
order: 'asc',
sort: 'createTime',
} as any)
}
const result = await pageShopChatMessage(params)
if (result?.list) {
if (isLoadMore) {
setMessages(prev => [...result.list!, ...prev])
} else {
setMessages(result.list)
scrollToBottom.current = true
}
setHasMore((result.list.length ?? 0) >= 20)
setMsgPage(pageNum)
@@ -97,11 +102,12 @@ const CustomerServicePage: React.FC = () => {
loadConversations()
}, [loadConversations])
useReachBottom(() => {
if (hasMore && currentConversation && !loadingMore) {
// ScrollView 滚动到底部加载更多历史消息
const handleScrollToLower = () => {
if (hasMore && currentConversation && !loadingMore && showHistory) {
loadMessages(currentConversation.id!, msgPage + 1, true)
}
})
}
// 创建新会话
const ensureConversation = async (): Promise<ShopChatConversation | null> => {
@@ -140,18 +146,21 @@ const CustomerServicePage: React.FC = () => {
return
}
const userId = getCurrentUserId()
await addShopChatMessage({
conversationId: conv.id,
content: text,
type: 'text',
formUserId: userId,
toUserId: 0, // 发送给客服(服务端路由)
} as any)
})
// 消息发送成功后刷新消息列表
await loadMessages(conv.id, 1, false)
// 同步更新会话列表 lastMessage
// 同步更新会话列表 content 字段
setConversations(prev => prev.map(c =>
c.id === conv.id ? { ...c, lastMessage: text, updateTime: new Date().toISOString() } : c
c.id === conv.id ? { ...c, content: text, updateTime: new Date().toISOString() } : c
))
} catch (e: any) {
console.error('发送消息失败:', e)
@@ -162,6 +171,11 @@ const CustomerServicePage: React.FC = () => {
}
}
// 微信客服回调 - 用户从客服会话返回时触发
const handleContact = (e: any) => {
console.log('客服会话回调:', e.detail)
}
// 拨打热线
const handleCallHotline = () => {
Taro.makePhoneCall({ phoneNumber: SERVICE_HOTLINE })
@@ -205,7 +219,12 @@ const CustomerServicePage: React.FC = () => {
<View className="flex flex-col min-h-screen bg-gray-100">
<NavBar title="在线客服" />
<ScrollView scrollY className="flex-1">
<ScrollView
scrollY
className="flex-1"
onScrollToLower={handleScrollToLower}
lowerThreshold={50}
>
{/* 客服状态栏 */}
<View className="bg-white px-4 py-3 flex items-center justify-between">
<View className="flex items-center gap-2">
@@ -222,11 +241,25 @@ const CustomerServicePage: React.FC = () => {
<View className="px-4 py-3 bg-white border-t border-gray-50">
<Button
openType="contact"
className="w-full h-12 rounded-lg text-white font-medium text-base border-0"
style={{ backgroundColor: '#07c160', lineHeight: '48px' }}
sessionFrom="customer_service"
onContact={handleContact}
showMessageCard
sendMessageTitle="欢迎咨询"
className="w-full rounded-lg text-white font-medium text-base"
style={{
backgroundColor: '#07c160',
lineHeight: '48px',
height: '48px',
borderRadius: '8px',
border: 'none',
padding: '0',
}}
>
线
</Button>
<Text className="text-xs text-gray-400 block text-center mt-2">
</Text>
</View>
{/* 消息记录入口 */}
@@ -276,7 +309,7 @@ const CustomerServicePage: React.FC = () => {
>
<View className="flex justify-between items-center">
<Text className="text-sm text-gray-700" style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
{conv.content || conv.lastMessage || '暂无消息'}
{conv.content || '暂无消息'}
</Text>
<Text className="text-xs text-gray-400 ml-2">{formatTime(conv.updateTime)}</Text>
</View>