Files
YGChatCS/pages/chat/ChatMainList.vue
2025-07-21 19:42:57 +08:00

209 lines
5.8 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="chat-container" @touchend="handleTouchEnd">
<!-- 顶部的背景 -->
<ChatTopBgImg class="chat-container-bg"></ChatTopBgImg>
<view class="chat-content">
<!-- 顶部自定义导航栏 -->
<view class="nav-bar-container" :style="{
paddingTop: statusBarHeight + 'px',
}">
<ChatTopNavBar @openDrawer="openDrawer"></ChatTopNavBar>
</view>
<!-- 消息列表可滚动区域 -->
<scroll-view
scroll-y
:scroll-into-view="lastMsgId"
:scroll-with-animation="true"
class="area-msg-list"
>
<!-- logo栏 -->
<ChatTopBanner class="chat-container-top-bannar"></ChatTopBanner>
<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">
<CommandWrapper text="ssss"/>
<template v-if="item.msgType === MessageRole.AI">
<ChatCardAI class="message-item message-item-ai" :text="item.msg">
<image v-if="item.msgContent && item.msgContent.type === MessageType.IMAGE" src="/static/logo.png" style="width: 100px;height: 100px;"></image>
<OneFeelMK001></OneFeelMK001>
</ChatCardAI>
</template>
<template v-else-if="item.msgType === MessageRole.ME">
<ChatCardMine class="message-item message-item-mine" :text="item.msg">
</ChatCardMine>
</template>
<template v-else>
<text class="message-item message-item-other">{{item.msg}}</text>
</template>
</view>
<!-- 底部锚点用于滚动到底部 -->
<view :id="lastMsgId"></view>
</scroll-view>
<!-- 输入框区域 -->
<view class="footer-area">
<ChatMoreTips @replySent="handleReply"></ChatMoreTips>
<ChatQuickAccess @replySent="handleReply"></ChatQuickAccess>
<ChatInputArea
v-model:inputMessage="inputMessage"
:holdKeyboard="holdKeyboard"
@send="sendMessage"
@noHideKeyboard="handleNoHideKeyboard"
/>
</view>
</view>
</view>
</template>
<script setup lang="ts">
import { onMounted, getCurrentInstance, nextTick } from 'vue'
import { ref } from 'vue'
import { defineEmits } from 'vue'
import { onLoad } from '@dcloudio/uni-app';
import ChatTopBanner from './ChatTopBanner.vue';
import ChatTopBgImg from './ChatTopBgImg.vue';
import ChatTopNavBar from './ChatTopNavBar.vue';
import ChatCardAI from './ChatCardAI.vue';
import ChatCardMine from './ChatCardMine.vue';
import ChatQuickAccess from './ChatQuickAccess.vue';
import ChatMoreTips from './ChatMoreTips.vue';
import ChatInputArea from './ChatInputArea.vue'
import CommandWrapper from '@/components/CommandWrapper/index.vue'
import { MessageRole, ChatModel, MessageType } from '../../model/ChatModel';
import OneFeelMK001 from '../module/OneFeelMK001.vue';
// 导航栏相关
const statusBarHeight = ref(20);
const timer = ref(null)
const holdKeyboard = ref(false) // focus时点击页面的时候不收起键盘
const holdKeyboardFlag = ref(true) // 是否在键盘弹出,点击界面时关闭键盘
const chatMsgList = ref<ChatModel[]>([])
const inputMessage = ref('')
// 锚点ID控制滚动位置
const lastMsgId = ref('anchor-bottom');
// 打开抽屉
const emits = defineEmits(['openDrawer'])
const openDrawer = () => {
emits('openDrawer')
console.log('=============打开抽屉')
}
const handleReply = (text: string) => {
loadMessage(text)
scrollToBottom()
};
onLoad(() => {
uni.getSystemInfo({
success: (res) => {
statusBarHeight.value = res.statusBarHeight || 20;
}
});
});
onMounted(() => {
initData()
})
const initData = () => {
const msg: ChatModel = {
msgId: `msg_${0}`,
msgType: MessageRole.AI,
msg: '查信息、预定下单、探索玩法、呼叫服务、我通通可以满足,快试试问我问题吧!',
}
chatMsgList.value.push(msg)
}
const handleTouchEnd = () => {
// #ifdef MP-WEIXIN
clearTimeout(timer.value)
timer.value = setTimeout(() => {
// 键盘弹出时点击界面则关闭键盘
if (handleNoHideKeyboard) {
uni.hideKeyboard()
}
holdKeyboardFlag.value = true
}, 50)
// #endif
}
// 点击输入框、发送按钮时,不收键盘
const handleNoHideKeyboard = () => {
// #ifdef MP-WEIXIN
holdKeyboardFlag.value = false
// #endif
}
// 发送消息
const sendMessage = (message: string) => {
console.log("inputMessage list:", message)
if (!message.trim()) return;
handleNoHideKeyboard()
// 发送消息代码
loadMessage(message)
inputMessage.value = ''
scrollToBottom()
}
const loadMessage = (text: string) => {
const newMsg: ChatModel = {
msgId: `msg_${chatMsgList.value.length}`,
msgType: MessageRole.ME,
msg: text,
msgContent: {
type: MessageType.TEXT,
text: text
}
}
chatMsgList.value.push(newMsg)
let type = chatMsgList.value.length % 3 === 0
const newMsgAI: ChatModel = {
msgId: `msg_${chatMsgList.value.length}`,
msgType: MessageRole.AI,
msg: `我是ai,你输入的内容是:${text}`,
msgContent: {
type: type ? MessageType.IMAGE : MessageType.TEXT,
url: ''
}
}
chatMsgList.value.push(newMsgAI)
console.log("发送的新消息:",JSON.stringify(newMsg))
}
const scrollToBottom = () => {
// 短暂指向最新消息的ID触发滚动
lastMsgId.value = `${chatMsgList.value[chatMsgList.value.length - 1].msgId}`;
// 等待DOM更新后切回底部锚点确保下次能继续滚动到底
nextTick(() => {
lastMsgId.value = 'anchor-bottom';
});
}
</script>
<style lang="scss" scoped>
@import "styles/ChatMainList.scss";
</style>