feat: agent对话
This commit is contained in:
@@ -8,13 +8,14 @@
|
||||
<SvgIcon name="equal" color="#0d0d0d" size="24" />
|
||||
</div>
|
||||
<div class="agent-body flex-1 flex flex-col">
|
||||
<List />
|
||||
<Input :is-agent-mode="true" @send="handleSendMessage" />
|
||||
<List :message-list="messageList" />
|
||||
<Input is-agent-mode @send="handleSendMessage" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive } from 'vue'
|
||||
import List from './List.vue'
|
||||
import Input from '../../components/Input.vue'
|
||||
|
||||
@@ -27,8 +28,74 @@
|
||||
}
|
||||
)
|
||||
|
||||
const messageList = ref([
|
||||
{ id: 1, text: 'Hello', isUser: true },
|
||||
{
|
||||
id: 2,
|
||||
text: 'Hey, I am your design assistant FiDA. I noticed that you want to design a yellow sofa. I can help you! Tell me what else you need?'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
text: 'Please design a vintage-inspired sofa with smooth, flowing lines and a sculptural silhouette. The sofa features a retro aesthetic combined with elegant curves, creating a timeless and refined look.',
|
||||
isUser: true
|
||||
}
|
||||
])
|
||||
|
||||
const handleSendMessage = (message: string) => {
|
||||
console.log('Message sent:', message)
|
||||
messageList.value.push({
|
||||
id: messageList.value.length + 1,
|
||||
text: message,
|
||||
isUser: true
|
||||
})
|
||||
|
||||
// Add AI loading message
|
||||
const aiMessage = reactive({
|
||||
id: messageList.value.length + 1,
|
||||
text: '',
|
||||
isUser: false,
|
||||
loading: true,
|
||||
thinking: false,
|
||||
thinkingText: '',
|
||||
thinkingCollapsed: false,
|
||||
streaming: false
|
||||
})
|
||||
messageList.value.push(aiMessage)
|
||||
|
||||
// Simulate AI response
|
||||
setTimeout(() => {
|
||||
aiMessage.loading = false
|
||||
aiMessage.thinking = true
|
||||
aiMessage.thinkingText = '思考中...'
|
||||
|
||||
// Simulate thinking process
|
||||
setTimeout(() => {
|
||||
aiMessage.thinkingText = '分析用户需求:设计复古风格沙发,强调流畅线条和雕塑轮廓。'
|
||||
}, 1000)
|
||||
|
||||
setTimeout(() => {
|
||||
aiMessage.thinkingText += '\n考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素考虑颜色方案:黄色基调,结合复古元素。'
|
||||
}, 2000)
|
||||
|
||||
setTimeout(() => {
|
||||
aiMessage.thinkingText += '\n生成设计草图...'
|
||||
aiMessage.thinking = false
|
||||
aiMessage.streaming = true
|
||||
|
||||
// Simulate streaming response
|
||||
const response = '根据您的描述,我为您设计了一个复古风格的沙发。这个沙发采用黄色皮革材质,线条流畅,轮廓雕塑感强。整体造型优雅,结合了现代舒适与复古美学。'
|
||||
let index = 0
|
||||
const interval = setInterval(() => {
|
||||
if (index < response.length) {
|
||||
aiMessage.text += response[index]
|
||||
index++
|
||||
} else {
|
||||
clearInterval(interval)
|
||||
aiMessage.streaming = false
|
||||
}
|
||||
}, 50)
|
||||
}, 3000)
|
||||
}, 1000)
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
<template>
|
||||
<div class="agent-item">
|
||||
<div class="message-wrapper flex align-center" :class="{ 'is-user': content.isUser }">
|
||||
<div class="message-wrapper flex" :class="{ 'is-user': content.isUser }">
|
||||
<div class="thumb">
|
||||
<img :src="content.isUser ? userThumb : agentThumb" class="thumb-icon" />
|
||||
</div>
|
||||
<div class="message-context">
|
||||
<div class="message-context" v-show="!content.loading && !content.thinking && !content.streaming">
|
||||
<div class="message-txt">{{ content.text }}</div>
|
||||
<div class="operate flex" :class="{ 'is-user': content.isUser }">
|
||||
<template v-if="content.isUser">
|
||||
@@ -22,13 +22,33 @@
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class="message-context" v-show="content.loading">
|
||||
<div class="generating">
|
||||
Generating...
|
||||
</div>
|
||||
</div>
|
||||
<div class="message-context" v-show="content.thinking">
|
||||
<div class="thinking">
|
||||
<div class="thinking-header flex align-center" @click="toggleThinkingCollapsed">
|
||||
<span>思考中</span>
|
||||
<!-- <SvgIcon :name="content.thinkingCollapsed ? 'arrowDown' : 'arrowUp'" size="16" color="#666" /> -->
|
||||
</div>
|
||||
<div class="thinking-content" v-show="!content.thinkingCollapsed">
|
||||
<pre>{{ content.thinkingText }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="message-context" v-show="content.streaming">
|
||||
<div class="message-txt">{{ content.text }}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import gsap from 'gsap'
|
||||
import userThumb from '@/assets/images/user-thumb.jpg'
|
||||
import agentThumb from '@/assets/images/agent-thumb.jpg'
|
||||
|
||||
@@ -65,6 +85,8 @@
|
||||
}
|
||||
])
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
const handleCopyText = () => {
|
||||
navigator.clipboard
|
||||
.writeText(props.content.text)
|
||||
@@ -85,6 +107,16 @@
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
const toggleThinkingCollapsed = () => {
|
||||
props.content.thinkingCollapsed = !props.content.thinkingCollapsed
|
||||
}
|
||||
|
||||
const playLoadingAnimate = () => {}
|
||||
|
||||
onMounted(() => {
|
||||
// playLoadingAnimate()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
@@ -97,6 +129,7 @@
|
||||
font-size: 1.4rem;
|
||||
.message-wrapper {
|
||||
column-gap: 0.9rem;
|
||||
// align-items: flex-start;
|
||||
&.is-user {
|
||||
text-align: right;
|
||||
flex-direction: row-reverse;
|
||||
@@ -124,4 +157,54 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.generating {
|
||||
font-family: 'GeneralBold';
|
||||
font-weight: 600;
|
||||
font-size: 1.55rem;
|
||||
background: linear-gradient(45deg, #f2ab4a, #ff6b75, #fe3b55);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
background-clip: text;
|
||||
text-fill-color: transparent;
|
||||
}
|
||||
|
||||
.thinking {
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 8px;
|
||||
padding: 1rem;
|
||||
background-color: #f9f9f9;
|
||||
|
||||
.thinking-header {
|
||||
cursor: pointer;
|
||||
font-weight: bold;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.thinking-content {
|
||||
margin-top: 0.5rem;
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
font-family: inherit;
|
||||
font-size: 1.2rem;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @supports (-webkit-mask-image: url(#mask)) or (mask-image: url(#mask)) {
|
||||
// .generating::after {
|
||||
// content: '';
|
||||
// position: absolute;
|
||||
// top: 0;
|
||||
// left: 0;
|
||||
// width: 100%;
|
||||
// height: 100%;
|
||||
// background: url('path-to-noise-texture.png'); /* Replace with a noise texture image sized appropriately (e.g., small grain at 0.03 scale) */
|
||||
// opacity: 1; /* 100% density */
|
||||
// mix-blend-mode: color; /* Approximate duotone blending */
|
||||
// -webkit-mask-image: -webkit-linear-gradient(#c05f20, #290d99);
|
||||
// mask-image: linear-gradient(#c05f20, #290d99);
|
||||
// }
|
||||
// }
|
||||
</style>
|
||||
|
||||
@@ -8,18 +8,9 @@
|
||||
import { ref } from 'vue'
|
||||
import Item from './Item.vue'
|
||||
|
||||
const messageList = ref([
|
||||
{ id: 1, text: 'Hello', isUser: true },
|
||||
{
|
||||
id: 2,
|
||||
text: 'Hey, I am your design assistant FiDA. I noticed that you want to design a yellow sofa. I can help you! Tell me what else you need?'
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
text: 'Please design a vintage-inspired sofa with smooth, flowing lines and a sculptural silhouette. The sofa features a retro aesthetic combined with elegant curves, creating a timeless and refined look.',
|
||||
isUser: true
|
||||
}
|
||||
])
|
||||
const props = defineProps<{
|
||||
messageList: Array<any>
|
||||
}>()
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
Reference in New Issue
Block a user