chore: 初步聊天布局展示
This commit is contained in:
@@ -774,7 +774,10 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
/* 引入图标字体 */
|
||||||
|
@import url('/common/css/iconfont.css');
|
||||||
|
|
||||||
|
/* 页面样式 */
|
||||||
.ai-chat-container {
|
.ai-chat-container {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -1,14 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<view class="ai-chat-page">
|
<view class="ai-chat-page" :style="{ top: navBarHeight + 'px' }">
|
||||||
<!-- 页面头部 -->
|
<!-- 页面头部 -->
|
||||||
<view class="page-header">
|
<view class="page-header" ref="pageHeader">
|
||||||
<view class="header-left">
|
<view class="header-left">
|
||||||
<button class="back-btn" @click="goBack">
|
<button class="back-btn" @click="goBack">
|
||||||
<text class="iconfont icon-back"></text>
|
<text class="iconfont icon-back"></text>
|
||||||
</button>
|
</button>
|
||||||
</view>
|
</view>
|
||||||
<view class="header-center">
|
<view class="header-center">
|
||||||
<text class="header-title">AI智能客服</text>
|
|
||||||
<text class="header-subtitle">在线为您服务</text>
|
<text class="header-subtitle">在线为您服务</text>
|
||||||
</view>
|
</view>
|
||||||
<view class="header-right">
|
<view class="header-right">
|
||||||
@@ -19,7 +18,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 聊天内容区域 -->
|
<!-- 聊天内容区域 -->
|
||||||
<view class="chat-content">
|
<view class="chat-content" :style="chatContentStyle">
|
||||||
<!-- AI聊天组件 -->
|
<!-- AI聊天组件 -->
|
||||||
<ai-chat-message
|
<ai-chat-message
|
||||||
ref="chat"
|
ref="chat"
|
||||||
@@ -41,7 +40,7 @@
|
|||||||
</view>
|
</view>
|
||||||
|
|
||||||
<!-- 底部tabBar占位 -->
|
<!-- 底部tabBar占位 -->
|
||||||
<!-- <view class="page-bottom" :style="{ height: computedTabBarHeight }"></view> -->
|
<view v-if="showTabBar" class="page-bottom" :style="{ height: computedTabBarHeight }"></view>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -64,7 +63,16 @@ export default {
|
|||||||
],
|
],
|
||||||
userAvatar: '/static/images/user-avatar.png',
|
userAvatar: '/static/images/user-avatar.png',
|
||||||
aiAvatar: '/static/images/ai-avatar.png',
|
aiAvatar: '/static/images/ai-avatar.png',
|
||||||
tabBarHeight: '56px'
|
|
||||||
|
// 是否显示底部tabBar
|
||||||
|
showTabBar: false,
|
||||||
|
tabBarHeight: '56px',
|
||||||
|
|
||||||
|
// 页面头部高度
|
||||||
|
headerHeight: 0,
|
||||||
|
|
||||||
|
// uni-page-head 导航栏高度
|
||||||
|
navBarHeight: 44 // 默认高度为44px
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -72,15 +80,150 @@ export default {
|
|||||||
// 获取底部栏高度
|
// 获取底部栏高度
|
||||||
computedTabBarHeight() {
|
computedTabBarHeight() {
|
||||||
return this.tabBarHeight || '56px'
|
return this.tabBarHeight || '56px'
|
||||||
|
},
|
||||||
|
|
||||||
|
// 计算聊天内容区域高度
|
||||||
|
chatContentHeight() {
|
||||||
|
if (this.headerHeight === 0 || this.navBarHeight === 0) {
|
||||||
|
return 'calc(100vh - 120rpx)' // 默认高度
|
||||||
|
}
|
||||||
|
|
||||||
|
// 直接使用获取到的像素高度进行计算
|
||||||
|
const headerHeightPx = this.headerHeight
|
||||||
|
const tabBarHeightPx = this.showTabBar ? parseInt(this.tabBarHeight) : 0
|
||||||
|
|
||||||
|
// 计算剩余高度,使用px单位确保一致性(页面已经设置了top值,不需要再减去navBar高度)
|
||||||
|
const remainingHeight = `calc(100vh - ${headerHeightPx}px - ${tabBarHeightPx}px)`
|
||||||
|
return remainingHeight
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoad() {
|
onLoad() {
|
||||||
|
// 设置页面标题
|
||||||
|
this.$langConfig.title('AI智能客服');
|
||||||
// 页面加载时初始化
|
// 页面加载时初始化
|
||||||
this.initChat()
|
this.initChat()
|
||||||
},
|
},
|
||||||
|
|
||||||
|
onReady() {
|
||||||
|
// 页面渲染完成后获取头部高度
|
||||||
|
// 使用更长的延迟确保DOM完全渲染完成
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$forceUpdate()
|
||||||
|
this.getNavBarHeight()
|
||||||
|
this.getHeaderHeight()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
onShow() {
|
||||||
|
// 页面显示时再次获取高度,确保布局正确
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.$forceUpdate()
|
||||||
|
this.getNavBarHeight()
|
||||||
|
this.getHeaderHeight()
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
|
// 获取页面头部高度
|
||||||
|
getHeaderHeight(retryCount = 0) {
|
||||||
|
// 使用Vue ref方式获取元素高度
|
||||||
|
const query = uni.createSelectorQuery().in(this)
|
||||||
|
query.select(this.$refs.pageHeader).boundingClientRect(data => {
|
||||||
|
if (data && data.height > 0) {
|
||||||
|
this.headerHeight = data.height
|
||||||
|
console.log('页面头部高度:', this.headerHeight + 'px')
|
||||||
|
|
||||||
|
// 高度获取成功后,强制更新视图
|
||||||
|
this.$forceUpdate()
|
||||||
|
|
||||||
|
// 延迟一段时间后再次检查,确保布局稳定
|
||||||
|
setTimeout(() => {
|
||||||
|
this.checkLayoutStability()
|
||||||
|
}, 100)
|
||||||
|
} else {
|
||||||
|
// 如果获取失败,重试最多3次
|
||||||
|
if (retryCount < 3) {
|
||||||
|
console.log('获取头部高度失败,第' + (retryCount + 1) + '次重试')
|
||||||
|
setTimeout(() => {
|
||||||
|
this.getHeaderHeight(retryCount + 1)
|
||||||
|
}, 300)
|
||||||
|
} else {
|
||||||
|
console.log('获取头部高度失败,使用默认高度')
|
||||||
|
// 使用默认高度
|
||||||
|
this.headerHeight = 60 // 假设默认高度为60px
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).exec()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 检查布局稳定性
|
||||||
|
checkLayoutStability() {
|
||||||
|
// 再次获取头部高度,确保布局稳定
|
||||||
|
const query = uni.createSelectorQuery().in(this)
|
||||||
|
query.select(this.$refs.pageHeader).boundingClientRect(data => {
|
||||||
|
if (data && data.height > 0 && data.height !== this.headerHeight) {
|
||||||
|
console.log('布局发生变化,更新高度:', data.height + 'px')
|
||||||
|
this.headerHeight = data.height
|
||||||
|
this.$forceUpdate()
|
||||||
|
}
|
||||||
|
}).exec()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取uni-page-head导航栏高度
|
||||||
|
getNavBarHeight(retryCount = 0) {
|
||||||
|
// 使用选择器获取uni-page-head元素高度
|
||||||
|
const query = uni.createSelectorQuery().in(this)
|
||||||
|
query.select('.uni-page-head').boundingClientRect(data => {
|
||||||
|
if (data && data.height > 0) {
|
||||||
|
this.navBarHeight = data.height
|
||||||
|
console.log('uni-page-head高度:', this.navBarHeight + 'px')
|
||||||
|
|
||||||
|
// 高度获取成功后,强制更新视图
|
||||||
|
this.$forceUpdate()
|
||||||
|
} else {
|
||||||
|
// 如果获取失败,重试最多3次
|
||||||
|
if (retryCount < 3) {
|
||||||
|
console.log('获取uni-page-head高度失败,第' + (retryCount + 1) + '次重试')
|
||||||
|
setTimeout(() => {
|
||||||
|
this.getNavBarHeight(retryCount + 1)
|
||||||
|
}, 300)
|
||||||
|
} else {
|
||||||
|
console.log('获取uni-page-head高度失败,使用默认高度')
|
||||||
|
// 使用默认高度(uni-app导航栏默认高度通常为44px)
|
||||||
|
this.navBarHeight = 44
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).exec()
|
||||||
|
},
|
||||||
|
|
||||||
|
// 获取uni-page-head导航栏高度
|
||||||
|
getNavBarHeight(retryCount = 0) {
|
||||||
|
// 使用选择器获取uni-page-head元素高度
|
||||||
|
const query = uni.createSelectorQuery().in(this)
|
||||||
|
query.select('.uni-page-head').boundingClientRect(data => {
|
||||||
|
if (data && data.height > 0) {
|
||||||
|
this.navBarHeight = data.height
|
||||||
|
console.log('uni-page-head高度:', this.navBarHeight + 'px')
|
||||||
|
|
||||||
|
// 高度获取成功后,强制更新视图
|
||||||
|
this.$forceUpdate()
|
||||||
|
} else {
|
||||||
|
// 如果获取失败,重试最多3次
|
||||||
|
if (retryCount < 3) {
|
||||||
|
console.log('获取uni-page-head高度失败,第' + (retryCount + 1) + '次重试')
|
||||||
|
setTimeout(() => {
|
||||||
|
this.getNavBarHeight(retryCount + 1)
|
||||||
|
}, 300)
|
||||||
|
} else {
|
||||||
|
console.log('获取uni-page-head高度失败,使用默认高度')
|
||||||
|
// 使用默认高度(uni-app导航栏默认高度通常为44px)
|
||||||
|
this.navBarHeight = 44
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}).exec()
|
||||||
|
},
|
||||||
|
|
||||||
// 初始化聊天
|
// 初始化聊天
|
||||||
initChat() {
|
initChat() {
|
||||||
// 可以在这里加载历史消息
|
// 可以在这里加载历史消息
|
||||||
@@ -322,22 +465,18 @@ export default {
|
|||||||
|
|
||||||
/* 页面样式 */
|
/* 页面样式 */
|
||||||
.ai-chat-page {
|
.ai-chat-page {
|
||||||
height: 100vh;
|
height: calc(100vh - var(--nav-bar-height, 44px));
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background-color: #f8f8f8;
|
background-color: #f8f8f8;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 聊天内容区域 */
|
/* 页面头部 */
|
||||||
.chat-content {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
overflow: hidden;
|
|
||||||
height: calc(100vh - 120rpx); /* 减去头部高度 */
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-header {
|
.page-header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@@ -346,10 +485,10 @@ export default {
|
|||||||
background-color: white;
|
background-color: white;
|
||||||
border-bottom: 2rpx solid #eeeeee;
|
border-bottom: 2rpx solid #eeeeee;
|
||||||
|
|
||||||
.header-left, .header-right {
|
.header-left {
|
||||||
flex: 1;
|
flex: 0 0 auto;
|
||||||
|
|
||||||
.back-btn, .menu-btn {
|
.back-btn {
|
||||||
width: 60rpx;
|
width: 60rpx;
|
||||||
height: 60rpx;
|
height: 60rpx;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
@@ -366,28 +505,53 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header-center {
|
.header-center {
|
||||||
flex: 2;
|
flex: 1;
|
||||||
text-align: center;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 20rpx;
|
||||||
|
|
||||||
.header-title {
|
.header-title {
|
||||||
display: block;
|
|
||||||
font-size: 36rpx;
|
font-size: 36rpx;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-subtitle {
|
.header-subtitle {
|
||||||
display: block;
|
|
||||||
font-size: 24rpx;
|
font-size: 24rpx;
|
||||||
color: #999;
|
color: #999;
|
||||||
margin-top: 5rpx;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.header-right {
|
.header-right {
|
||||||
text-align: right;
|
flex: 0 0 auto;
|
||||||
|
|
||||||
|
.menu-btn {
|
||||||
|
width: 60rpx;
|
||||||
|
height: 60rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #f8f8f8;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.iconfont {
|
||||||
|
font-size: 32rpx;
|
||||||
|
color: #666;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 聊天内容区域 */
|
||||||
|
.chat-content {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* 底部tabBar占位样式 */
|
/* 底部tabBar占位样式 */
|
||||||
.page-bottom {
|
.page-bottom {
|
||||||
|
|||||||
Reference in New Issue
Block a user