hookehuyr

feat(消息发送): 添加发送状态控制和自动回复提示

- 添加 isSending 状态防止重复发送
- 发送中禁用按钮并显示加载状态
- 立即清空输入框提升用户体验
- 添加自动回复提示消息
- 优化发送失败时的输入框恢复逻辑
......@@ -58,11 +58,11 @@
<!-- 输入框区域 -->
<view class="chat-input-area">
<view class="input-container">
<nut-textarea v-model="inputMessage" placeholder="请输入回复内容..." :rows="2" :max-length="500"
<textarea v-model="inputMessage" placeholder="请输入回复内容..." :rows="2" :max-length="500"
:cursorSpacing="100" class="message-input" @focus="handleInputFocus" />
<nut-button type="primary" size="small" color="orange" @click="sendMessage"
:disabled="!inputMessage.trim()" class="send-button">
发送
:disabled="!inputMessage.trim() || isSending" class="send-button">
{{ isSending ? '发送中...' : '发送' }}
</nut-button>
</view>
</view>
......@@ -114,6 +114,8 @@ const visible = computed({
// 输入消息内容
const inputMessage = ref('')
// 发送状态标记
const isSending = ref(false)
// 滚动相关
const scrollTop = ref(0)
......@@ -229,6 +231,11 @@ const sendMessage = async () => {
return
}
// 防止重复发送
if (isSending.value) {
return
}
// 只有聊天类型才能发送消息
if (props.conversation?.type !== 'chat') {
Taro.showToast({
......@@ -240,6 +247,11 @@ const sendMessage = async () => {
const messageContent = inputMessage.value.trim()
// 设置发送状态并立即清空输入框
isSending.value = true
inputMessage.value = ''
await nextTick() // 确保输入框立即清空
try {
// 先添加到本地显示(新消息添加到末尾)
const newMessage = {
......@@ -252,9 +264,6 @@ const sendMessage = async () => {
}
messages.value.push(newMessage)
// 清空输入框
inputMessage.value = ''
// 滚动到底部
await nextTick()
scrollToBottom()
......@@ -271,6 +280,25 @@ const sendMessage = async () => {
newMessage.id = response.data.id
}
// 添加自动回复提示消息
setTimeout(() => {
const autoReplyMessage = {
type: 'received',
content: '您的消息已发送,我们会尽快回复您,请耐心等待。',
time: new Date().toLocaleTimeString('zh-CN', {
hour: '2-digit',
minute: '2-digit'
}),
isAutoReply: true // 标记为自动回复消息
}
messages.value.push(autoReplyMessage)
// 滚动到底部显示新消息
nextTick(() => {
scrollToBottom()
})
}, 1000) // 延迟1秒显示自动回复
// 触发发送消息事件,通知父组件更新列表
emit('sendMessage', {
conversation: props.conversation,
......@@ -284,6 +312,9 @@ const sendMessage = async () => {
} else {
// 发送失败,移除本地消息
messages.value.pop()
// 只在真正失败时才恢复输入框内容,避免闪烁
await nextTick()
inputMessage.value = messageContent
Taro.showToast({
title: response.msg || '发送失败',
icon: 'error'
......@@ -293,10 +324,16 @@ const sendMessage = async () => {
console.error('发送消息失败:', error)
// 发送失败,移除本地消息
messages.value.pop()
// 只在真正失败时才恢复输入框内容,避免闪烁
await nextTick()
inputMessage.value = messageContent
Taro.showToast({
title: '发送失败',
icon: 'error'
})
} finally {
// 重置发送状态
isSending.value = false
}
}
......