Compare commits

..

No commits in common. "87bdac8c57c715cc223b4b784d9776ec3864ef8c" and "822c1486b8790f5dc945317ca90c7d3346f6b9a0" have entirely different histories.

11 changed files with 157 additions and 214 deletions

View File

@ -1,13 +0,0 @@
export const MessageRole = {
AI: "AI",
ME: "ME",
OTHER: "OTHER"
}
export const MessageType = {
TEXT: 'TEXT',
IMAGE: 'IMAGE'
}

35
model/ChatModel.ts Normal file
View File

@ -0,0 +1,35 @@
export enum MessageRole {
AI = "AI",
ME = "ME",
OTHER = "OTHER"
}
export enum MessageType {
TEXT = 'TEXT',
IMAGE = 'IMAGE'
}
export interface TextContent {
type: MessageType;
text: string;
}
export interface ImageContent {
type: MessageType;
url: string;
}
export type MessageContent = TextContent | ImageContent;
export interface ChatModel {
msgId: string;
msgType: MessageRole;
msg: string;
msgContent?: MessageContent;
}

View File

@ -20,7 +20,7 @@
<style lang="scss" scoped> <style lang="scss" scoped>
.chat-ai { .chat-ai {
margin: 6px 12px; margin: 6px 12px;
padding: 0 12px; padding: 0 16px;
min-width: 80px; min-width: 80px;
background: rgba(255,255,255,0.4); background: rgba(255,255,255,0.4);

View File

@ -17,12 +17,14 @@
<style lang="scss" scoped> <style lang="scss" scoped>
.chat-other { .chat-other {
margin: 6px 0;
padding: 0 12px;
display: flex; display: flex;
flex-direction: column; justify-content: center;
max-width: 100%; // background-color: white;
overflow-x: hidden; // margin: 6px 12px;
padding: 8px 24px;
border-radius: 4px;
font-size: 14px;
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
text { text {
font-family: PingFang SC, PingFang SC; font-family: PingFang SC, PingFang SC;

View File

@ -22,10 +22,9 @@
<ChatTopBanner class="chat-container-top-bannar"></ChatTopBanner> <ChatTopBanner class="chat-container-top-bannar"></ChatTopBanner>
<view class="area-msg-list-content" v-for="item in chatMsgList" :key="item.msgId" :id="item.msgId"> <view class="area-msg-list-content" v-for="item in chatMsgList" :key="item.msgId" :id="item.msgId">
<template v-if="item.msgType === MessageRole.AI"> <template v-if="item.msgType === MessageRole.AI">
<ChatCardAI class="message-item-ai" :text="item.msg"> <ChatCardAI class="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>
</ChatCardAI> </ChatCardAI>
</template> </template>
@ -34,10 +33,7 @@
</ChatCardMine> </ChatCardMine>
</template> </template>
<template v-else> <template v-else>
<ChatCardOther class="message-item-other" :text="item.msg"> <ChatCardOther class="message-item-other" :text="item.msg"></ChatCardOther>
<OneFeelMK001/>
<OneFeelMK002/>
</ChatCardOther>
</template> </template>
</view> </view>
@ -47,7 +43,7 @@
<!-- 输入框区域 --> <!-- 输入框区域 -->
<view class="footer-area"> <view class="footer-area">
<ChatMoreTips @replySent="handleReply" :itemList="guideWords"></ChatMoreTips> <ChatMoreTips @replySent="handleReply"></ChatMoreTips>
<ChatQuickAccess @replySent="handleReply"></ChatQuickAccess> <ChatQuickAccess @replySent="handleReply"></ChatQuickAccess>
<ChatInputArea <ChatInputArea
v-model:inputMessage="inputMessage" v-model:inputMessage="inputMessage"
@ -60,7 +56,7 @@
</view> </view>
</template> </template>
<script setup > <script setup lang="ts">
import { onMounted, getCurrentInstance, nextTick } from 'vue' import { onMounted, getCurrentInstance, nextTick } from 'vue'
import { ref } from 'vue' import { ref } from 'vue'
import { defineEmits } from 'vue' import { defineEmits } from 'vue'
@ -79,10 +75,8 @@
import { MessageRole, ChatModel, MessageType } from '../../model/ChatModel'; import { MessageRole, ChatModel, MessageType } from '../../model/ChatModel';
import OneFeelMK001 from '../module/OneFeelMK001.vue'; import OneFeelMK001 from '../module/OneFeelMK001.vue';
import OneFeelMK002 from '../module/OneFeelMK002.vue';
import request from '../../request/base/request'; import request from '../../request/base/request';
import { agentChatStream } from '../../request/api/AgentChatStream'; import { agentChatStream } from '../../request/api/AgentChatStream';
import { mainPageData } from '../../request/api/MainPageData';
// //
const statusBarHeight = ref(20); const statusBarHeight = ref(20);
@ -91,12 +85,9 @@
const holdKeyboard = ref(false) // focus const holdKeyboard = ref(false) // focus
const holdKeyboardFlag = ref(true) // const holdKeyboardFlag = ref(true) //
const chatMsgList = ref([]) const chatMsgList = ref<ChatModel[]>([])
const inputMessage = ref('') const inputMessage = ref('')
const mainPageDataModel = ref({})
const guideWords = ref([])
// ID // ID
const lastMsgId = ref('anchor-bottom'); const lastMsgId = ref('anchor-bottom');
@ -108,7 +99,7 @@
console.log('=============打开抽屉') console.log('=============打开抽屉')
} }
const handleReply = (text) => { const handleReply = (text: string) => {
loadMessage(text) loadMessage(text)
scrollToBottom() scrollToBottom()
}; };
@ -122,29 +113,16 @@
}); });
onMounted(() => { onMounted(() => {
// getMainPageData()
initData() initData()
}) })
const getMainPageData = async() => {
mainPageDataModel.value = await mainPageData()
guideWords.value = mainPageDataModel.value.guideWords
}
const initData = () => { const initData = () => {
const msg = { const msg: ChatModel = {
msgId: `msg_${0}`, msgId: `msg_${0}`,
msgType: MessageRole.AI, msgType: MessageRole.AI,
msg: '查信息、预定下单、探索玩法、呼叫服务、我通通可以满足,快试试问我问题吧!', msg: '查信息、预定下单、探索玩法、呼叫服务、我通通可以满足,快试试问我问题吧!',
} }
chatMsgList.value.push(msg) chatMsgList.value.push(msg)
const msg1 = {
msgId: `msg_${1}`,
msgType: MessageRole.OTHER,
msg: '',
}
chatMsgList.value.push(msg1)
} }
const handleTouchEnd = () => { const handleTouchEnd = () => {
@ -169,7 +147,7 @@
} }
// //
const sendMessage = (message) => { const sendMessage = (message: string) => {
console.log("inputMessage list:", message) console.log("inputMessage list:", message)
if (!message.trim()) return; if (!message.trim()) return;
handleNoHideKeyboard() handleNoHideKeyboard()
@ -179,8 +157,8 @@
scrollToBottom() scrollToBottom()
} }
const loadMessage = (text) => { const loadMessage = (text: string) => {
const newMsg = { const newMsg: ChatModel = {
msgId: `msg_${chatMsgList.value.length}`, msgId: `msg_${chatMsgList.value.length}`,
msgType: MessageRole.ME, msgType: MessageRole.ME,
msg: text, msg: text,
@ -201,14 +179,12 @@
lastMsgId.value = `${chatMsgList.value[chatMsgList.value.length - 1].msgId}`; lastMsgId.value = `${chatMsgList.value[chatMsgList.value.length - 1].msgId}`;
// DOM // DOM
nextTick(() => { nextTick(() => {
nextTick(() => { lastMsgId.value = 'anchor-bottom';
lastMsgId.value = 'anchor-bottom';
});
}); });
} }
let loadingTimer = null; let loadingTimer: any = null;
let typeWriterTimer = null; let typeWriterTimer: any = null;
let aiMsgBuffer = ''; // let aiMsgBuffer = ''; //
let isTyping = false; // let isTyping = false; //
@ -223,7 +199,7 @@
} }
// 1. AI // 1. AI
const aiMsg = { const aiMsg: ChatModel = {
msgId: `msg_${chatMsgList.value.length}`, msgId: `msg_${chatMsgList.value.length}`,
msgType: MessageRole.AI, msgType: MessageRole.AI,
msg: '加载中.', msg: '加载中.',
@ -286,10 +262,7 @@
if (aiMsgBuffer.length > 0) { if (aiMsgBuffer.length > 0) {
chatMsgList.value[aiMsgIndex].msg += aiMsgBuffer[0]; chatMsgList.value[aiMsgIndex].msg += aiMsgBuffer[0];
aiMsgBuffer = aiMsgBuffer.slice(1); aiMsgBuffer = aiMsgBuffer.slice(1);
scrollToBottom();
nextTick(() => {
scrollToBottom();
});
typeWriterTimer = setTimeout(typeWriter, 30); typeWriterTimer = setTimeout(typeWriter, 30);
} else { } else {
// //

View File

@ -13,9 +13,7 @@
default: '' default: ''
} }
}) })
</script> </script>
<style scoped> <style>
</style> </style>

View File

@ -2,35 +2,51 @@
<view class="more-tips"> <view class="more-tips">
<view class="more-tips-scroll"> <view class="more-tips-scroll">
<view class="more-tips-item" v-for="(item, index) in itemList" :key="index"> <view class="more-tips-item" v-for="(item, index) in itemList" :key="index">
<text class="more-tips-item-title" @click="sendReply(item)">{{ item }}</text> <text class="more-tips-item-title" @click="sendReply(item.title)">{{ item.title }}</text>
</view> </view>
</view> </view>
</view> </view>
</template> </template>
<script setup> <script setup>
import { defineProps } from "vue"; import { onMounted, ref } from 'vue';
const itemList = ref([])
const emits = defineEmits(['replySent']); const emits = defineEmits(['replySent']);
defineProps({
itemList: {
type: [],
default: [
'定温泉票',
'定酒店',
'优惠套餐',
'亲子玩法',
'了解交通',
'看看酒店',
'看看美食'
]
}
})
const sendReply = (text) => { const sendReply = (text) => {
emits('replySent', text); // emits('replySent', text); //
} }
onMounted(() => {
initData()
})
const initData = () => {
itemList.value = [
{
title: '定温泉票',
},
{
title: '定酒店',
},
{
title: '优惠套餐',
},
{
title: '亲子玩法',
},
{
title: '了解交通',
},
{
title: '看看酒店',
},
{
title: '看看美食',
}
]
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -1,54 +1,76 @@
<template> <template>
<view class="container"> <view class="container">
<swiper class="swiper" circular :indicator-dots="indicatorDots" :autoplay="autoplay" :interval="interval" <view class="mk-title">
:duration="duration"> <text class="title">避世放松 能量调节</text>
<swiper-item> <image class="wave" src="@/static/wave_icon.png" mode="widthFix"/>
<view class="swiper-item uni-bg-red">A</view> </view>
</swiper-item> <view class="container-scroll">
<swiper-item> <view class="mk-card-item" v-for="(item, index) in 8" :key="index">
<view class="swiper-item uni-bg-green">B</view> <image src="/static/test/mk_img_1.png"></image>
</swiper-item> <text>#森系环境 #出工人必备-{{item}}</text>
<swiper-item> </view>
<view class="swiper-item uni-bg-blue">C</view> </view>
</swiper-item>
</swiper>
</view> </view>
</template> </template>
<script> <script setup>
</script> </script>
<style scoped lang="scss"> <style lang="scss" scoped>
.container { .container {
.uni-margin-wrap { .mk-title {
width: 690rpx; padding: 4px 0;
width: 100%; display: inline-block;
} position: relative;
.swiper { .title {
height: 300rpx; font-weight: 400;
border-radius: 8px; font-size: 16px;
} color: #000000;
.swiper-item { z-index: 2;
display: block; position: relative;
height: 300rpx; }
line-height: 300rpx; .wave {
text-align: center; position: absolute;
bottom: 2px;
left: 0;
width: 100%;
z-index: 1;
}
} }
.uni-bg-red { .container-scroll {
background-color: red; display: flex;
flex-direction: row;
overflow-x: auto;
margin-top: 4px;
/* 隐藏滚动条 */
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
.mk-card-item {
display: flex;
flex-direction: column;
width: 188px;
height: 154px;
background-color: #ffffff;
border-radius: 10px;
margin-right: 8px;
image {
width: 188px;
height: 112px;
}
text {
padding: 12px;
text-align: center;
font-weight: 500;
font-size: 12px;
color: #333333;
}
}
} }
.uni-bg-green {
background-color: green;
}
.uni-bg-blue {
background-color: blue;
}
} }
</style> </style>

View File

@ -1,76 +0,0 @@
<template>
<view class="container">
<view class="mk-title">
<text class="title">避世放松 能量调节</text>
<image class="wave" src="@/static/wave_icon.png" mode="widthFix"/>
</view>
<view class="container-scroll">
<view class="mk-card-item" v-for="(item, index) in 8" :key="index">
<image src="/static/test/mk_img_1.png"></image>
<text>#森系环境 #出工人必备-{{item}}</text>
</view>
</view>
</view>
</template>
<script setup>
</script>
<style lang="scss" scoped>
.container {
.mk-title {
padding: 4px 0;
display: inline-block;
position: relative;
.title {
font-weight: 400;
font-size: 16px;
color: #000000;
z-index: 2;
position: relative;
}
.wave {
position: absolute;
bottom: 2px;
left: 0;
width: 100%;
z-index: 1;
}
}
.container-scroll {
display: flex;
flex-direction: row;
overflow-x: auto;
margin-top: 4px;
/* 隐藏滚动条 */
scrollbar-width: none;
&::-webkit-scrollbar {
display: none;
}
.mk-card-item {
display: flex;
flex-direction: column;
width: 188px;
height: 154px;
background-color: #ffffff;
border-radius: 10px;
margin-right: 8px;
image {
width: 188px;
height: 112px;
}
text {
padding: 12px;
text-align: center;
font-weight: 500;
font-size: 12px;
color: #333333;
}
}
}
}
</style>

View File

@ -1,7 +0,0 @@
import request from "../base/request";
function mainPageData() {
return request.post('/mainScene/mainPageData');
}
export { mainPageData }

View File

@ -1,7 +0,0 @@
import request from "../base/request";
function quickBookingComponent() {
return request.post('/mainScene/quickBookingComponent');
}
export { quickBookingComponent }