mirror of
https://github.com/yangjian102621/geekai.git
synced 2026-03-04 03:04:28 +08:00
AI对话页面增加显示AI思考中
This commit is contained in:
@@ -7,7 +7,14 @@
|
||||
</div>
|
||||
|
||||
<div class="chat-item">
|
||||
<div class="content-wrapper" v-html="md.render(processContent(data.content))"></div>
|
||||
<div
|
||||
class="content-wrapper"
|
||||
v-html="md.render(processContent(data.content))"
|
||||
v-if="data.content"
|
||||
></div>
|
||||
<div class="content-wrapper flex justify-start items-center" v-else>
|
||||
<span class="mr-2">AI 思考中</span> <Thinking :duration="1.5" />
|
||||
</div>
|
||||
<div class="bar flex text-gray-500" v-if="data.created_at">
|
||||
<span class="bar-item text-sm">{{ dateFormat(data.created_at) }}</span>
|
||||
<!-- <span class="bar-item">tokens: {{ data.tokens }}</span> -->
|
||||
@@ -65,7 +72,14 @@
|
||||
</div>
|
||||
<div class="chat-item">
|
||||
<div class="content-wrapper">
|
||||
<div class="content" v-html="md.render(processContent(data.content))"></div>
|
||||
<div
|
||||
class="content"
|
||||
v-html="md.render(processContent(data.content))"
|
||||
v-if="data.content"
|
||||
></div>
|
||||
<div class="content flex justify-start items-center" v-else>
|
||||
<span class="mr-2">AI 思考中</span> <Thinking :duration="1.5" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="bar text-gray-500" v-if="data.created_at">
|
||||
<span class="bar-item text-sm"> {{ dateFormat(data.created_at) }}</span>
|
||||
@@ -124,6 +138,7 @@ import MarkdownIt from 'markdown-it'
|
||||
import emoji from 'markdown-it-emoji'
|
||||
import mathjaxPlugin from 'markdown-it-mathjax3'
|
||||
import { ref } from 'vue'
|
||||
import Thinking from './Thinking.vue'
|
||||
// eslint-disable-next-line no-undef,no-unused-vars
|
||||
const props = defineProps({
|
||||
data: {
|
||||
|
||||
77
web/src/components/Thinking.vue
Normal file
77
web/src/components/Thinking.vue
Normal file
@@ -0,0 +1,77 @@
|
||||
<template>
|
||||
<div class="loading-container" :style="containerStyle">
|
||||
<div
|
||||
v-for="i in 3"
|
||||
:key="i"
|
||||
class="dot"
|
||||
:style="[dotStyle, { animationDelay: `${(i - 1) * 0.2}s` }]"
|
||||
></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
// 点的大小(px)
|
||||
size: {
|
||||
type: Number,
|
||||
default: 8,
|
||||
},
|
||||
// 点之间的间距(px)
|
||||
spacing: {
|
||||
type: Number,
|
||||
default: 4,
|
||||
},
|
||||
// 动画持续时间(秒)
|
||||
duration: {
|
||||
type: Number,
|
||||
default: 1.4,
|
||||
},
|
||||
})
|
||||
|
||||
// 计算样式
|
||||
const containerStyle = computed(() => ({
|
||||
height: `${props.size * 2}px`,
|
||||
}))
|
||||
|
||||
const dotStyle = computed(() => ({
|
||||
width: `${props.size}px`,
|
||||
height: `${props.size}px`,
|
||||
margin: `0 ${props.spacing}px`,
|
||||
background: `var(--el-text-color-regular)`,
|
||||
animationDuration: `${props.duration}s`,
|
||||
}))
|
||||
</script>
|
||||
<style scoped>
|
||||
.loading-container {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.dot {
|
||||
border-radius: 50%;
|
||||
display: inline-block;
|
||||
animation: loading ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes loading {
|
||||
0% {
|
||||
opacity: 0.2;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
20% {
|
||||
opacity: 1;
|
||||
transform: scale(1.2);
|
||||
}
|
||||
40% {
|
||||
opacity: 0.2;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
100% {
|
||||
opacity: 0.2;
|
||||
transform: scale(0.8);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -1,24 +1,31 @@
|
||||
<template>
|
||||
<div class="mobile-message-reply">
|
||||
<div class="chat-icon">
|
||||
<van-image :src="icon"/>
|
||||
<van-image :src="icon" />
|
||||
</div>
|
||||
|
||||
<div class="chat-item">
|
||||
<div class="triangle"></div>
|
||||
<div class="content-box" ref="contentRef">
|
||||
<div :data-clipboard-text="orgContent" class="content content-mobile" v-html="content"></div>
|
||||
<div
|
||||
:data-clipboard-text="orgContent"
|
||||
class="content content-mobile"
|
||||
v-html="content"
|
||||
v-if="content"
|
||||
></div>
|
||||
<div class="content content-mobile flex justify-start items-center" v-else>
|
||||
<span class="mr-2">AI 思考中</span> <Thinking :duration="1.5" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {nextTick, onMounted, ref} from "vue"
|
||||
|
||||
import {showImagePreview} from "vant";
|
||||
import { onMounted, ref } from 'vue'
|
||||
|
||||
import { showImagePreview } from 'vant'
|
||||
import Thinking from '../Thinking.vue'
|
||||
const props = defineProps({
|
||||
content: {
|
||||
type: String,
|
||||
@@ -31,8 +38,8 @@ const props = defineProps({
|
||||
icon: {
|
||||
type: String,
|
||||
default: '/images/gpt-icon.png',
|
||||
}
|
||||
});
|
||||
},
|
||||
})
|
||||
|
||||
const contentRef = ref(null)
|
||||
onMounted(() => {
|
||||
@@ -43,7 +50,7 @@ onMounted(() => {
|
||||
}
|
||||
imgs[i].addEventListener('click', (e) => {
|
||||
e.stopPropagation()
|
||||
showImagePreview([imgs[i].src]);
|
||||
showImagePreview([imgs[i].src])
|
||||
})
|
||||
}
|
||||
})
|
||||
@@ -221,4 +228,4 @@ onMounted(() => {
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user