忽略 unpackage 目录
This commit is contained in:
107
pages/chat/ChatInputArea.vue
Normal file
107
pages/chat/ChatInputArea.vue
Normal file
@@ -0,0 +1,107 @@
|
||||
<template>
|
||||
<view class="area-input">
|
||||
<!-- 发送语音 -->
|
||||
<view class="input-container-voice">
|
||||
<image src='/static/input_voice_icon.png'></image>
|
||||
</view>
|
||||
<!-- 输入框 -->
|
||||
<textarea
|
||||
class="textarea"
|
||||
type="text"
|
||||
placeholder="快速订票,呼叫服务"
|
||||
cursor-spacing="65"
|
||||
confirm-type='done'
|
||||
v-model="inputMessage"
|
||||
@confirm="sendMessage"
|
||||
@touchend="handleNoHideKeyboard"
|
||||
:confirm-hold="true"
|
||||
auto-height
|
||||
:show-confirm-bar='false'
|
||||
:hold-keyboard="holdKeyboard"
|
||||
maxlength="300"
|
||||
/>
|
||||
<view class="input-container-send" @click="sendMessage">
|
||||
<image src='/static/input_send_icon.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
inputMessage: String,
|
||||
holdKeyboard: Boolean
|
||||
})
|
||||
const emit = defineEmits(['update:inputMessage', 'send', 'noHideKeyboard'])
|
||||
|
||||
const inputMessage = ref(props.inputMessage || '')
|
||||
|
||||
// 保持和父组件同步
|
||||
watch(() => props.inputMessage, (val) => {
|
||||
inputMessage.value = val
|
||||
})
|
||||
|
||||
const sendMessage = () => {
|
||||
if (!inputMessage.value.trim()) return;
|
||||
emit('send', inputMessage.value)
|
||||
inputMessage.value = ''
|
||||
emit('update:inputMessage', inputMessage.value)
|
||||
}
|
||||
|
||||
const handleNoHideKeyboard = () => {
|
||||
emit('noHideKeyboard')
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.area-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 22px;
|
||||
background-color: #FFFFFF;
|
||||
box-shadow: 0px 0px 20px 0px rgba(52,25,204,0.05);
|
||||
margin: 0 12px;
|
||||
|
||||
.input-container-voice {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
flex-shrink: 0;
|
||||
align-self: flex-end;
|
||||
|
||||
image {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-container-send {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
flex-shrink: 0;
|
||||
align-self: flex-end;
|
||||
|
||||
image {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.textarea {
|
||||
flex: 1;
|
||||
max-height: 92px;
|
||||
min-height: 22px;
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
margin-bottom: 2px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,19 +1,15 @@
|
||||
<template>
|
||||
<view class="chat-container" @touchend="handleTouchEnd">
|
||||
<!-- 顶部的背景 -->
|
||||
<chat-top-bg-img class="chat-container-bg"></chat-top-bg-img>
|
||||
|
||||
<!-- 顶部自定义导航栏 -->
|
||||
<view class="nav-bar-container" :style="{
|
||||
paddingTop: statusBarHeight + 'px',
|
||||
backgroundColor: navBgColor,
|
||||
}">
|
||||
<chat-top-nav-bar @openDrawer="openDrawer"></chat-top-nav-bar>
|
||||
</view>
|
||||
<ChatTopBgImg class="chat-container-bg"></ChatTopBgImg>
|
||||
|
||||
<view class="chat-container-msg-list">
|
||||
<!-- logo栏 -->
|
||||
<chat-top-banner class="chat-container-top-bannar"></chat-top-banner>
|
||||
<!-- 顶部自定义导航栏 -->
|
||||
<view class="nav-bar-container" :style="{
|
||||
paddingTop: statusBarHeight + 'px',
|
||||
}">
|
||||
<ChatTopNavBar @openDrawer="openDrawer"></ChatTopNavBar>
|
||||
</view>
|
||||
|
||||
<!-- 消息列表(可滚动区域) -->
|
||||
<scroll-view
|
||||
@@ -22,17 +18,12 @@
|
||||
:scroll-with-animation="true"
|
||||
class="area-msg-list"
|
||||
>
|
||||
<!-- logo栏 -->
|
||||
<ChatTopBanner class="chat-container-top-bannar"></ChatTopBanner>
|
||||
|
||||
<view style="padding: 6px 12px;">
|
||||
<OneFeelMK001></OneFeelMK001>
|
||||
</view>
|
||||
<view style="padding: 6px 12px;">
|
||||
<OneFeelMK001></OneFeelMK001>
|
||||
</view>
|
||||
<view style="padding: 6px 12px;">
|
||||
<OneFeelMK001></OneFeelMK001>
|
||||
</view>
|
||||
|
||||
<ChatCardAI class="message-item message-item-ai" text="查信息、预定下单、探索玩法、呼叫服务、我通通可以满足,快试试问我问题吧!">
|
||||
|
||||
</ChatCardAI>
|
||||
|
||||
<view class="area-msg-list-content" v-for="item in chatMsgList" :key="item.msgId" :id="item.msgId">
|
||||
<template v-if="item.msgType === MessageRole.AI">
|
||||
@@ -59,32 +50,12 @@
|
||||
<view class="footer-area">
|
||||
<ChatMoreTips @replySent="handleReply"></ChatMoreTips>
|
||||
<ChatQuickAccess @replySent="handleReply"></ChatQuickAccess>
|
||||
|
||||
<view class="area-input">
|
||||
<!-- 发送语音 -->
|
||||
<view class="input-container-voice">
|
||||
<image src='/static/input_voice_icon.png'></image>
|
||||
</view>
|
||||
<!-- 输入框 -->
|
||||
<textarea
|
||||
class="textarea"
|
||||
type="text"
|
||||
placeholder="快速订票,呼叫服务"
|
||||
cursor-spacing="65"
|
||||
confirm-type='done'
|
||||
v-model="inputMessage"
|
||||
@confirm="sendMessage"
|
||||
@touchend="handleNoHideKeyboard"
|
||||
:confirm-hold="true"
|
||||
auto-height
|
||||
:show-confirm-bar='false'
|
||||
:hold-keyboard="holdKeyboard"
|
||||
maxlength="300"
|
||||
<ChatInputArea
|
||||
v-model:inputMessage="inputMessage"
|
||||
:holdKeyboard="holdKeyboard"
|
||||
@send="sendMessage"
|
||||
@noHideKeyboard="handleNoHideKeyboard"
|
||||
/>
|
||||
<view class="input-container-send" @click="sendMessage">
|
||||
<image src='/static/input_send_icon.png'></image>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -92,7 +63,7 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, getCurrentInstance, nextTick } from 'vue'
|
||||
import { ref, watch } from 'vue'
|
||||
import { ref } from 'vue'
|
||||
import { defineEmits } from 'vue'
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
import ChatTopBanner from './ChatTopBanner.vue';
|
||||
@@ -102,19 +73,15 @@
|
||||
import ChatCardMine from './ChatCardMine.vue';
|
||||
import ChatQuickAccess from './ChatQuickAccess.vue';
|
||||
import ChatMoreTips from './ChatMoreTips.vue';
|
||||
|
||||
import ChatInputArea from './ChatInputArea.vue'
|
||||
|
||||
import { MessageRole, ChatModel, MessageType } from '../../model/ChatModel';
|
||||
|
||||
import OneFeelMK001 from '../module/OneFeelMK001.vue';
|
||||
|
||||
|
||||
const instance = getCurrentInstance(); // 获取当前组件实例
|
||||
|
||||
|
||||
// 导航栏相关
|
||||
const statusBarHeight = ref(20);
|
||||
const navBgColor = ref('rgba(66, 173, 249, 0)');
|
||||
const navOpacity = ref(0);
|
||||
|
||||
|
||||
const timer = ref(null)
|
||||
const holdKeyboard = ref(false) // focus时,点击页面的时候不收起键盘
|
||||
const holdKeyboardFlag = ref(true) // 是否在键盘弹出,点击界面时关闭键盘
|
||||
@@ -124,27 +91,8 @@
|
||||
|
||||
// 锚点ID(控制滚动位置)
|
||||
const lastMsgId = ref('anchor-bottom');
|
||||
|
||||
// 针对小程序键盘收起问题处理
|
||||
// #ifdef MP-WEIXIN
|
||||
holdKeyboard.value = true
|
||||
// #endif
|
||||
|
||||
|
||||
// 滚动临界值(根据实际banner高度调整)
|
||||
const SCROLL_THRESHOLD = 200;
|
||||
const handleScroll = (e) => {
|
||||
const scrollTopVal = e.detail.scrollTop;
|
||||
// 计算透明度 (0-1之间)
|
||||
let opacity = Math.min(scrollTopVal / SCROLL_THRESHOLD, 1);
|
||||
// 如果滚动到接近顶部,透明度设为0
|
||||
if (scrollTopVal < 10) {
|
||||
opacity = 0;
|
||||
}
|
||||
navOpacity.value = opacity;
|
||||
navBgColor.value = `rgba(66, 173, 249, ${opacity})`;
|
||||
};
|
||||
|
||||
// 打开抽屉
|
||||
const emits = defineEmits(['openDrawer'])
|
||||
const openDrawer = () => {
|
||||
@@ -167,7 +115,6 @@
|
||||
|
||||
onMounted(() => {
|
||||
initData()
|
||||
|
||||
})
|
||||
|
||||
const initData = () => {
|
||||
@@ -201,11 +148,12 @@
|
||||
}
|
||||
|
||||
// 发送消息
|
||||
const sendMessage = () => {
|
||||
if (!inputMessage.value.trim()) return;
|
||||
const sendMessage = (message: string) => {
|
||||
console.log("inputMessage list:", message)
|
||||
if (!message.trim()) return;
|
||||
handleNoHideKeyboard()
|
||||
// 发送消息代码
|
||||
loadMessage(inputMessage.value)
|
||||
loadMessage(message)
|
||||
inputMessage.value = ''
|
||||
scrollToBottom()
|
||||
}
|
||||
@@ -252,169 +200,5 @@
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.chat-container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #E9F3F7;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden !important;
|
||||
position: relative;
|
||||
|
||||
.chat-container-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 0;
|
||||
height: 270px;
|
||||
background: linear-gradient( 180deg, #42ADF9 0%, #6CD1FF 51%, #E9F3F7 99%);
|
||||
}
|
||||
|
||||
/* 顶部导航栏样式 */
|
||||
.nav-bar-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 999;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.chat-container-msg-list {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
z-index: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chat-container-top-bannar {
|
||||
width: 100vw;
|
||||
flex-shrink: 0;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.area-msg-list {
|
||||
width: 100vw;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
padding: 4px 0 0;
|
||||
overscroll-behavior: contain; /* 阻止滚动穿透 */
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.area-msg-list-content {
|
||||
/* 隐藏滚动条 */
|
||||
scrollbar-width: none;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.message-item {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.message-item-ai {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.message-item-mine {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.message-item-other {
|
||||
justify-content: center;
|
||||
background-color: white;
|
||||
margin: 6px 12px;
|
||||
padding: 8px 24px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
|
||||
text {
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer-area {
|
||||
width: 100vw;
|
||||
flex-shrink: 0;
|
||||
padding: 4px 0 24px 0;
|
||||
background-color: #E9F3F7;
|
||||
touch-action: pan-x; /* 仅允许横向触摸滚动 */
|
||||
overflow-x: auto; /* 允许横向滚动 */
|
||||
overflow-y: hidden; /* 禁止垂直滚动 */
|
||||
}
|
||||
|
||||
.area-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 22px;
|
||||
background-color: #FFFFFF;
|
||||
box-shadow: 0px 0px 20px 0px rgba(52,25,204,0.05);
|
||||
margin: 0 12px;
|
||||
|
||||
.input-container-voice {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
flex-shrink: 0;
|
||||
align-self: flex-end;
|
||||
|
||||
image {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-container-send {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
flex-shrink: 0;
|
||||
align-self: flex-end;
|
||||
|
||||
image {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.textarea {
|
||||
flex: 1;
|
||||
max-height: 92px;
|
||||
min-height: 22px;
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
margin-bottom: 2px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
-webkit-appearance: none;
|
||||
background: transparent;
|
||||
color: transparent;
|
||||
}
|
||||
|
||||
@import "styles/ChatMainList.scss";
|
||||
</style>
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<view class="top-bg-content" :style="{marginTop: marginContentTop + 'px'}">
|
||||
<view class="top-bg-content">
|
||||
<view class="top-item1">
|
||||
<view class="top-item1-left">
|
||||
<image src="/static/hello_xiaomu_icon@2x.png"></image>
|
||||
@@ -13,20 +13,6 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref } from 'vue';
|
||||
import { onLoad } from '@dcloudio/uni-app';
|
||||
|
||||
const statusBarHeight = ref(20);
|
||||
const marginContentTop = ref(44)
|
||||
|
||||
onLoad(() => {
|
||||
uni.getSystemInfo({
|
||||
success: (res) => {
|
||||
statusBarHeight.value = res.statusBarHeight || 20;
|
||||
marginContentTop.value += statusBarHeight.value;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
154
pages/chat/styles/ChatMainList.scss
Normal file
154
pages/chat/styles/ChatMainList.scss
Normal file
@@ -0,0 +1,154 @@
|
||||
.chat-container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #E9F3F7;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden !important;
|
||||
position: relative;
|
||||
|
||||
.chat-container-bg {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 0;
|
||||
height: 270px;
|
||||
background: linear-gradient( 180deg, #42ADF9 0%, #6CD1FF 51%, #E9F3F7 99%);
|
||||
}
|
||||
|
||||
.chat-container-msg-list {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
z-index: 1;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.chat-container-top-bannar {
|
||||
width: 100vw;
|
||||
flex-shrink: 0;
|
||||
touch-action: none;
|
||||
}
|
||||
|
||||
.area-msg-list {
|
||||
width: 100vw;
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
min-height: 0;
|
||||
padding: 4px 0 0;
|
||||
overscroll-behavior: contain; /* 阻止滚动穿透 */
|
||||
-webkit-overflow-scrolling: touch;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.area-msg-list-content {
|
||||
/* 隐藏滚动条 */
|
||||
scrollbar-width: none;
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.message-item {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.message-item-ai {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
|
||||
.message-item-mine {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.message-item-other {
|
||||
justify-content: center;
|
||||
background-color: white;
|
||||
margin: 6px 12px;
|
||||
padding: 8px 24px;
|
||||
border-radius: 4px;
|
||||
font-size: 14px;
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
|
||||
|
||||
text {
|
||||
font-family: PingFang SC, PingFang SC;
|
||||
font-weight: 400;
|
||||
font-size: 14px;
|
||||
color: #333333;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.footer-area {
|
||||
width: 100vw;
|
||||
flex-shrink: 0;
|
||||
padding: 4px 0 24px 0;
|
||||
background-color: #E9F3F7;
|
||||
touch-action: pan-x; /* 仅允许横向触摸滚动 */
|
||||
overflow-x: auto; /* 允许横向滚动 */
|
||||
overflow-y: hidden; /* 禁止垂直滚动 */
|
||||
}
|
||||
|
||||
.area-input {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 22px;
|
||||
background-color: #FFFFFF;
|
||||
box-shadow: 0px 0px 20px 0px rgba(52,25,204,0.05);
|
||||
margin: 0 12px;
|
||||
|
||||
.input-container-voice {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
flex-shrink: 0;
|
||||
align-self: flex-end;
|
||||
|
||||
image {
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
}
|
||||
}
|
||||
|
||||
.input-container-send {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
flex-shrink: 0;
|
||||
align-self: flex-end;
|
||||
|
||||
image {
|
||||
width: 28px;
|
||||
height: 28px;
|
||||
}
|
||||
}
|
||||
|
||||
.textarea {
|
||||
flex: 1;
|
||||
max-height: 92px;
|
||||
min-height: 22px;
|
||||
font-size: 16px;
|
||||
line-height: 22px;
|
||||
margin-bottom: 2px;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
::-webkit-scrollbar {
|
||||
display: none;
|
||||
width: 0 !important;
|
||||
height: 0 !important;
|
||||
-webkit-appearance: none;
|
||||
background: transparent;
|
||||
color: transparent;
|
||||
}
|
||||
Reference in New Issue
Block a user