fix(ai-chat): 修复聊天页面键盘弹出时导航栏上移、输入框不可见、间距问题
- 自定义导航栏 position:absolute 固定在顶部,不随键盘上移 - textarea 设置 adjust-position=false,阻止系统上推页面 - 输入框后方加 spacer 垫高层,键盘弹出时将输入框推至键盘上方 - chat-content 根据平台设置不同 top 值(MP:0 / H5:44px) - 去掉输入框多余的安全区域内边距 - scroll-view 底部 padding 随键盘高度动态调整
This commit is contained in:
@@ -68,7 +68,7 @@ export default {
|
||||
}
|
||||
return result;
|
||||
} catch (error) {
|
||||
console.error('[AI Service] Dify API请求失败,详细错误:', error);
|
||||
console.error('[AI Service] AiChat API请求失败,详细错误:', error);
|
||||
console.error('[AI Service] 错误堆栈:', error.stack);
|
||||
// 打印更多信息帮助调试
|
||||
console.error('[AI Service] store 状态:', {
|
||||
|
||||
@@ -119,9 +119,9 @@ export class CustomerService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到 AI智能客服页面(Dify)
|
||||
* 跳转到 AI智能客服页面(AiChat)
|
||||
*/
|
||||
openDifyService() {
|
||||
openAiChatService() {
|
||||
try {
|
||||
// 清除未读数(如果存在)
|
||||
if (typeof this.vm.setAiUnreadCount === 'function') {
|
||||
@@ -177,7 +177,7 @@ export class CustomerService {
|
||||
// 核心路由:根据 type 决定行为
|
||||
switch (config.type) {
|
||||
case 'aikefu':
|
||||
this.openDifyService();
|
||||
this.openAiChatService();
|
||||
break;
|
||||
case 'wxwork':
|
||||
this.openWxworkService(false, config, options);
|
||||
@@ -364,7 +364,7 @@ export class CustomerService {
|
||||
|
||||
openAliappService(config) {
|
||||
if (config.type === 'aikefu') {
|
||||
this.openDifyService();
|
||||
this.openAiChatService();
|
||||
} else if (config.type === 'third') {
|
||||
this.openThirdService(config);
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="ai-chat-container">
|
||||
<view class="ai-chat-container" :style="aiChatContainerStyle">
|
||||
<!-- 聊天消息列表 - 统一使用 scroll-into-view -->
|
||||
<scroll-view
|
||||
class="chat-messages"
|
||||
@@ -215,7 +215,7 @@
|
||||
:maxlength="500"
|
||||
:auto-height="true"
|
||||
:show-confirm-bar="false"
|
||||
:adjust-position="true"
|
||||
:adjust-position="false"
|
||||
:cursor-spacing="150"
|
||||
@confirm="sendMessage"
|
||||
@input="onInput"
|
||||
@@ -329,6 +329,9 @@
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<!-- 键盘垫高层:键盘弹出时撑开空间将输入框上推 -->
|
||||
<view v-if="keyboardHeight > 0" :style="{ height: keyboardHeight + 'px', flexShrink: 0 }"></view>
|
||||
|
||||
<!-- 语音输入面板 -->
|
||||
<view v-if="enalbeVoicePanelShow" class="voice-popup">
|
||||
<view class="voice-mask" @click="hideVoicePanel"></view>
|
||||
@@ -499,7 +502,7 @@ export default {
|
||||
// AI头像错误状态
|
||||
avatarError: false,
|
||||
|
||||
// Dify API相关
|
||||
// AiChat API相关
|
||||
currentConversationId: null,
|
||||
isAIServiceAvailable: true,
|
||||
aiServiceError: null,
|
||||
@@ -523,16 +526,17 @@ export default {
|
||||
return this.$util.img(IMAGE_CONFIG.aiAvatar);
|
||||
},
|
||||
chatMessagesStyle() {
|
||||
// 输入框在 flex 流中,scroll-view 仅在键盘弹出时需要底部padding
|
||||
// 键盘收起时:padding = 0(scroll-view 底部自然紧贴输入框顶部)
|
||||
// 键盘弹出时:padding = 键盘高度(避免最后消息被键盘遮挡)
|
||||
// 键盘弹出时增加底部padding,避免消息内容被键盘遮挡
|
||||
return {
|
||||
'padding-bottom': this.keyboardHeight > 0 ? this.keyboardHeight + 'px' : '0px'
|
||||
};
|
||||
},
|
||||
aiChatContainerStyle() {
|
||||
// 键盘高度由末尾垫高 view 处理,容器无需额外样式
|
||||
return {};
|
||||
},
|
||||
inputAreaStyle() {
|
||||
// 输入框在 flex 流中自然定位到容器底部,无需额外样式
|
||||
// 键盘弹出时由 <textarea adjust-position> 自动处理页面偏移
|
||||
// 输入框在 flex 流中自然定位,无需额外样式
|
||||
return {};
|
||||
},
|
||||
canSendMessage() {
|
||||
@@ -2212,9 +2216,14 @@ $radius-lg: 36rpx;
|
||||
|
||||
/* 页面样式 */
|
||||
.ai-chat-container {
|
||||
height: 100vh;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
box-sizing: border-box;
|
||||
background: #f8f8f8; /* 微信聊天页面背景色 */
|
||||
overflow: hidden;
|
||||
box-sizing: border-box;
|
||||
@@ -2892,8 +2901,6 @@ $radius-lg: 36rpx;
|
||||
border-top: 1rpx solid #e5e5e5;
|
||||
padding: 16rpx 24rpx;
|
||||
flex-shrink: 0;
|
||||
/* 微信小程序安全区域适配 */
|
||||
padding-bottom: calc(16rpx + env(safe-area-inset-bottom));
|
||||
box-sizing: border-box;
|
||||
|
||||
.input-tools {
|
||||
|
||||
@@ -1,23 +1,19 @@
|
||||
<template>
|
||||
<view class="container" :style="wrapperPageStyle">
|
||||
<!--自定义导航头部 - 只在微信小程序显示,H5端隐藏 -->
|
||||
<view class="wrapper">
|
||||
<!--自定义导航头部 - 绝对定位在顶部,不随键盘上移 -->
|
||||
<!-- #ifdef MP-WEIXIN -->
|
||||
<view class="custom-navbar" ref="pageHeader" v-if="showCustomNavbar">
|
||||
<view class="header-left">
|
||||
<button class="back-btn" v-show="showBackButton" @click="goBack">
|
||||
<text class="iconfont icon-back"></text>
|
||||
</button>
|
||||
<!-- 占位元素,确保布局平衡 -->
|
||||
<view v-show="!showMenuButton" class="placeholder"></view>
|
||||
</view>
|
||||
</view>
|
||||
<!-- #endif -->
|
||||
|
||||
<!-- 聊天内容区域 -->
|
||||
<view class="chat-content"
|
||||
:style="wrapperChatContentStyle"
|
||||
>
|
||||
<!-- AI聊天组件 -->
|
||||
<!-- 聊天内容区域:从导航栏下方到容器底部 -->
|
||||
<view class="chat-content">
|
||||
<ai-chat-message
|
||||
ref="chat"
|
||||
:initial-messages="initialMessages"
|
||||
@@ -131,37 +127,6 @@ export default {
|
||||
return this.globalAIKefuConfig?.aiAvatar || this.$util.img(IMAGE_CONFIG.aiAvatar)
|
||||
},
|
||||
/// ---- others ----
|
||||
containerHeight() {
|
||||
return `calc(100vh - ${this.navBarHeight + this.statusBarHeight}px)`
|
||||
},
|
||||
wrapperPageStyle() {
|
||||
// #ifdef H5
|
||||
return `top: $ {this.navBarHeight + 'px'};`
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
return `top: -1px;` // 微信小程序需要上移1px, 否则与系统导航栏出现1px的空隙
|
||||
// #endif
|
||||
|
||||
return ``
|
||||
},
|
||||
wrapperChatContentStyle() {
|
||||
// #ifdef H5
|
||||
// H5端没有自定义导航栏,不需要paddingTop
|
||||
return {
|
||||
height: this.containerHeight,
|
||||
paddingTop: '0'
|
||||
}
|
||||
// #endif
|
||||
|
||||
// #ifdef MP-WEIXIN
|
||||
// 微信小程序端根据导航栏显示情况决定
|
||||
return {
|
||||
height: this.containerHeight,
|
||||
paddingTop: this.showCustomNavbar ? '0' : (this.navBarHeight + 'px')
|
||||
}
|
||||
// #endif
|
||||
}
|
||||
},
|
||||
|
||||
async onLoad(options) {
|
||||
@@ -574,20 +539,22 @@ export default {
|
||||
@import url('/common/css/iconfont.css');
|
||||
|
||||
/* 页面样式 */
|
||||
.container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
background-color: white; /* 白色 */
|
||||
overflow: hidden;
|
||||
.wrapper {
|
||||
position: fixed;
|
||||
top: 48px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* 自定义导航头部 */
|
||||
/* 自定义导航头部:固定在wrapper顶部,不随键盘上移 */
|
||||
.custom-navbar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 88rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
@@ -667,12 +634,18 @@ export default {
|
||||
}
|
||||
}
|
||||
|
||||
/* 聊天内容区域 */
|
||||
/* 聊天内容区域:从导航栏下方到容器底部 */
|
||||
.chat-content {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
/* #ifdef MP-WEIXIN */
|
||||
top: 0;
|
||||
/* #endif */
|
||||
/* #ifndef MP-WEIXIN */
|
||||
top: 44px;
|
||||
/* #endif */
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
/* 底部tabBar占位样式 */
|
||||
|
||||
Reference in New Issue
Block a user