You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

148 lines
2.9 KiB

<template>
<div
class="message-item"
:class="{
'user-message': msg.sender === 'user',
'ai-message': msg.sender === 'ai',
[msg.class]: msg.class
}"
>
<div v-if="msg.type === 'kline'" class="kline-container">
<div :id="'kline-container-' + index" class="chart-mount-point">
<div v-if="!msg.hasValidData" class="no-data-message">
<p>暂无K线数据</p>
</div>
</div>
</div>
<div v-else-if="msg.type == 'ing'" class="ai-message-container">
<thinking-gif
v-if="msg.gif"
:type="getGifType(msg.gif)"
/>
<div class="ai-message-content" :class="{ fourStep: msg.nowrap }">
<div v-if="msg.flag">
<span>{{ msg.content }}</span>
<span class="loading-dots">
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
<span class="dot">.</span>
</span>
</div>
<div v-else v-html="msg.content"></div>
</div>
</div>
<div v-else class="message-content" v-html="msg.content"></div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import ThinkingGif from './ThinkingGif.vue';
import thinkingGif from "@/assets/img/gif/思考.gif";
import analyzeGif from "@/assets/img/gif/解析.gif";
import generateGif from "@/assets/img/gif/生成.gif";
const props = defineProps({
msg: {
type: Object,
required: true
},
index: {
type: Number,
required: true
}
});
// 根据GIF路径确定类型
const getGifType = (gifPath) => {
if (gifPath === thinkingGif) return 'thinking';
if (gifPath === analyzeGif) return 'analyze';
if (gifPath === generateGif) return 'generate';
return 'thinking';
};
</script>
<style scoped>
.message-item {
margin-bottom: 15px;
padding: 10px;
border-radius: 8px;
}
.user-message {
background-color: #e6f7ff;
margin-left: 20%;
}
.ai-message {
background-color: #f5f5f5;
margin-right: 20%;
}
.kline-container {
width: 100%;
height: 400px;
}
.chart-mount-point {
width: 100%;
height: 100%;
}
.no-data-message {
display: flex;
justify-content: center;
align-items: center;
height: 100%;
color: #999;
}
.ai-message-container {
display: flex;
flex-direction: column;
}
.ai-message-content {
padding: 10px;
}
.loading-dots .dot {
animation: loading 1.4s infinite;
display: inline-block;
opacity: 0;
}
.loading-dots .dot:nth-child(1) {
animation-delay: 0s;
}
.loading-dots .dot:nth-child(2) {
animation-delay: 0.2s;
}
.loading-dots .dot:nth-child(3) {
animation-delay: 0.4s;
}
.loading-dots .dot:nth-child(4) {
animation-delay: 0.6s;
}
.loading-dots .dot:nth-child(5) {
animation-delay: 0.8s;
}
.loading-dots .dot:nth-child(6) {
animation-delay: 1s;
}
@keyframes loading {
0% {
opacity: 0;
}
50% {
opacity: 1;
}
100% {
opacity: 0;
}
}
</style>