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
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>
|