diff --git a/pages/assistant/assistant.vue b/pages/assistant/assistant.vue index 5f6cdd8..ccb1776 100644 --- a/pages/assistant/assistant.vue +++ b/pages/assistant/assistant.vue @@ -191,31 +191,54 @@ export default { sendMessage() { if (!this.inputMessage.trim() || this.isThinking) return + // 保存用户输入内容 + const userInput = this.inputMessage + // 添加用户消息 const userMessage = { type: 'user', - content: this.inputMessage, + content: userInput, time: this.getCurrentTime() } this.messageList.push(userMessage) + // 清空输入框 + this.inputMessage = '' + // 开始AI思考 this.isThinking = true - this.scrollToBottom() + + // 确保DOM更新后再滚动到思考状态 + this.$nextTick(() => { + this.forceScrollToBottom() + // 在思考过程中持续滚动,确保思考动画可见 + setTimeout(() => { + this.forceScrollToBottom() + }, 200) + setTimeout(() => { + this.forceScrollToBottom() + }, 500) + }) // 模拟AI回复 setTimeout(() => { const aiMessage = { type: 'ai', - content: this.getAIResponse(this.inputMessage), + content: this.getAIResponse(userInput), time: this.getCurrentTime() } this.messageList.push(aiMessage) this.isThinking = false - this.scrollToBottom() - }, 1500 + Math.random() * 1000) // 1.5-2.5秒随机延迟 - this.inputMessage = '' + // AI回复完成后强制滚动到底部 + this.$nextTick(() => { + this.forceScrollToBottom() + // 延迟再次滚动,确保消息完全显示 + setTimeout(() => { + this.forceScrollToBottom() + }, 100) + }) + }, 1500 + Math.random() * 1000) // 1.5-2.5秒随机延迟 }, getAIResponse(question) { @@ -245,6 +268,17 @@ export default { }) }, + // 强制滚动到底部,用于确保消息可见 + forceScrollToBottom() { + this.$nextTick(() => { + // 使用时间戳确保每次滚动都能触发 + this.scrollTop = Date.now() + setTimeout(() => { + this.scrollTop = 999999 + }, 50) + }) + }, + startVoiceInput() { uni.showToast({ title: '语音功能开发中', @@ -555,10 +589,8 @@ export default { } .chat-input-area { - background: rgba(255, 255, 255, 0.95); backdrop-filter: blur(20rpx); padding: 16rpx 20rpx; - //padding-bottom: calc(16rpx + env(safe-area-inset-bottom)); border-top: 1rpx solid rgba(255, 255, 255, 0.2); } @@ -566,48 +598,131 @@ export default { display: flex; align-items: center; gap: 16rpx; + margin-bottom: 0 !important; .input-wrapper { flex: 1; - background: rgba(255, 255, 255, 0.9); border-radius: 28rpx; padding: 0 20rpx; - backdrop-filter: blur(10rpx); - border: 1rpx solid rgba(255, 255, 255, 0.3); + backdrop-filter: blur(15rpx); + border: 3rpx solid rgba(255, 255, 255, 0.98); height: 56rpx; display: flex; align-items: center; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.02) 100%); + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + box-shadow: + 0 0 0 1rpx rgba(255, 255, 255, 0.4), + 0 2rpx 8rpx rgba(255, 255, 255, 0.15), + 0 4rpx 16rpx rgba(255, 255, 255, 0.1), + inset 0 1rpx 0 rgba(255, 255, 255, 0.2); + position: relative; + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 25rpx; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.1) 0%, transparent 50%, rgba(255, 255, 255, 0.05) 100%); + pointer-events: none; + } + + &:focus-within { + border-color: rgba(255, 255, 255, 1); + box-shadow: + 0 0 0 2rpx rgba(255, 255, 255, 0.6), + 0 0 20rpx rgba(255, 255, 255, 0.3), + 0 4rpx 12rpx rgba(255, 255, 255, 0.2), + 0 8rpx 24rpx rgba(255, 255, 255, 0.15), + inset 0 1rpx 0 rgba(255, 255, 255, 0.3); + transform: translateY(-2rpx); + } .message-input { width: 100%; height: 100%; font-size: 28rpx; - color: #333333; + color: #ffffff; border: none; outline: none; background: transparent; + position: relative; + z-index: 1; + + &::placeholder { + color: rgba(255, 255, 255, 0.95); + font-weight: 400; + text-shadow: 0 1rpx 2rpx rgba(255, 255, 255, 0.1); + } } } .send-button { - padding: 12rpx 20rpx; + height: 56rpx; + padding: 0 20rpx; border-radius: 24rpx; - background: rgba(200, 200, 200, 0.5); - transition: all 0.3s ease; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%); + border: 3rpx solid rgba(255, 255, 255, 0.85); + transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1); + display: flex; + align-items: center; + justify-content: center; + position: relative; + backdrop-filter: blur(10rpx); + box-shadow: + 0 0 0 1rpx rgba(255, 255, 255, 0.3), + 0 2rpx 6rpx rgba(255, 255, 255, 0.12), + 0 4rpx 12rpx rgba(255, 255, 255, 0.08), + inset 0 1rpx 0 rgba(255, 255, 255, 0.15); + + &::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + border-radius: 21rpx; + background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, transparent 50%, rgba(255, 255, 255, 0.03) 100%); + pointer-events: none; + } + + &:active { + transform: scale(0.96) translateY(1rpx); + } .send-text { font-size: 28rpx; - color: #666666; + color: rgba(255, 255, 255, 0.9); font-weight: 500; + position: relative; + z-index: 1; + text-shadow: 0 1rpx 2rpx rgba(255, 255, 255, 0.1); } } .send-button.active { - background: linear-gradient(135deg, #FF8A80 0%, #FFB6C1 100%); - box-shadow: 0 4rpx 16rpx rgba(255, 138, 128, 0.4); + background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.04) 100%); + border: 3rpx solid rgba(255, 255, 255, 0.98); + box-shadow: + 0 0 0 2rpx rgba(255, 255, 255, 0.5), + 0 0 16rpx rgba(255, 255, 255, 0.25), + 0 4rpx 10rpx rgba(255, 255, 255, 0.18), + 0 6rpx 20rpx rgba(255, 255, 255, 0.12), + inset 0 1rpx 0 rgba(255, 255, 255, 0.25); + transform: translateY(-2rpx); + + &::before { + background: linear-gradient(135deg, rgba(255, 255, 255, 0.12) 0%, transparent 50%, rgba(255, 255, 255, 0.06) 100%); + } .send-text { - color: #ffffff; + color: rgba(255, 255, 255, 0.98); + font-weight: 600; + text-shadow: 0 1rpx 3rpx rgba(255, 255, 255, 0.15); } } }