3 changed files with 613 additions and 428 deletions
@ -1,201 +1,226 @@ |
|||
<script setup> |
|||
import { ref, onMounted, watch, nextTick } from 'vue' |
|||
import { ElDialog } from 'element-plus' |
|||
import { getReplyStreamAPI } from '../api/AIxiaocaishen' |
|||
import { ref, onMounted, watch, nextTick } from "vue"; |
|||
import { ElDialog } from "element-plus"; |
|||
import { getReplyStreamAPI } from "../api/AIxiaocaishen"; |
|||
|
|||
// 随机GIF |
|||
const currentGif = ref('') |
|||
const currentGif = ref(""); |
|||
|
|||
// 新闻飘屏数据 |
|||
const newsList = ref(Array(10).fill().map((_, i) => ({ |
|||
title: `引导提出问题 ${i + 1}`, |
|||
content: `新闻 ${i + 1} 的详细内容...` |
|||
}))) |
|||
|
|||
const newsList = ref( |
|||
Array(10) |
|||
.fill() |
|||
.map((_, i) => ({ |
|||
title: `引导提出问题 ${i + 1}`, |
|||
content: `新闻 ${i + 1} 的详细内容...`, |
|||
})) |
|||
); |
|||
|
|||
// 定义自定义事件 |
|||
const emit = defineEmits(["updateMessage", "sendMessage"]); |
|||
|
|||
// 弹窗控制 |
|||
const dialogVisible = ref(false) |
|||
const currentNews = ref('') |
|||
|
|||
const dialogVisible = ref(false); |
|||
const currentNews = ref(""); |
|||
const showNews = (news) => { |
|||
currentNews.value = news |
|||
dialogVisible.value = true |
|||
} |
|||
currentNews.value = news; |
|||
dialogVisible.value = true; |
|||
// 触发自定义事件 |
|||
emit("updateMessage", news.title); |
|||
emit("sendMessage"); |
|||
}; |
|||
|
|||
// 获取消息 |
|||
const props = defineProps({ |
|||
messages: Array, |
|||
}) |
|||
messages: Array, |
|||
}); |
|||
|
|||
watch(() => props.messages, async (newVal, oldVal) => { |
|||
console.log('消息列表已更新,最新消息:', newVal[newVal.length - 1]) |
|||
watch( |
|||
() => props.messages, |
|||
async (newVal, oldVal) => { |
|||
console.log("消息列表已更新,最新消息:", newVal[newVal.length - 1]); |
|||
// 在此处添加需要执行的逻辑 |
|||
const response = await getReplyStreamAPI({ |
|||
"workflow_id": "7480464341100494863", |
|||
"parameters": { |
|||
"input": newVal[newVal.length - 1].content |
|||
} |
|||
workflow_id: "7480464341100494863", |
|||
parameters: { |
|||
input: newVal[newVal.length - 1].content, |
|||
}, |
|||
}); |
|||
const reader = response.body.getReader(); |
|||
|
|||
console.log(response, 'response') |
|||
console.log(reader, 'reader') |
|||
|
|||
}, { deep: true, immediate: true }) |
|||
console.log(response, "response"); |
|||
console.log(reader, "reader"); |
|||
}, |
|||
{ deep: true, immediate: true } |
|||
); |
|||
|
|||
// 初始化随机GIF |
|||
onMounted(() => { |
|||
const random = Math.floor(Math.random() * 4) + 1 |
|||
console.log(random, 'random') |
|||
currentGif.value = `src/assets/img/AIchat/AIgif${random}.gif` |
|||
}) |
|||
const random = Math.floor(Math.random() * 4) + 1; |
|||
console.log(random, "random"); |
|||
currentGif.value = `src/assets/img/AIchat/AIgif${random}.gif`; |
|||
}); |
|||
</script> |
|||
|
|||
<template> |
|||
<div class="chat-container"> |
|||
<!-- GIF区域 --> |
|||
<div class="gif-area"> |
|||
<img :src="currentGif" alt="AI动画"> |
|||
|
|||
<div class="marquee-container"> |
|||
<div class="marquee-row top"> |
|||
<div v-for="(news, index) in newsList.slice(0, 5)" :key="'top' + index" class="marquee-item" |
|||
@click="showNews(news)"> |
|||
{{ news.title }} |
|||
</div> |
|||
</div> |
|||
<div class="marquee-row bottom"> |
|||
<div v-for="(news, index) in newsList.slice(5, 10)" :key="'bottom' + index" class="marquee-item" |
|||
@click="showNews(news)"> |
|||
{{ news.title }} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<div class="chat-container"> |
|||
<!-- GIF区域 --> |
|||
<div class="gif-area"> |
|||
<img :src="currentGif" alt="AI动画" /> |
|||
|
|||
<div class="marquee-container"> |
|||
<div class="marquee-row top"> |
|||
<div |
|||
v-for="(news, index) in newsList.slice(0, 5)" |
|||
:key="'top' + index" |
|||
class="marquee-item" |
|||
@click="showNews(news)" |
|||
> |
|||
{{ news.title }} |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 消息区域 --> |
|||
<div class="message-area"> |
|||
<div v-for="(msg, index) in messages" :key="index" :class="['message-bubble', msg.sender]"> |
|||
{{ msg.content }} |
|||
</div> |
|||
<div class="marquee-row bottom"> |
|||
<div |
|||
v-for="(news, index) in newsList.slice(5, 10)" |
|||
:key="'bottom' + index" |
|||
class="marquee-item" |
|||
@click="showNews(news)" |
|||
> |
|||
{{ news.title }} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 新闻弹窗 --> |
|||
<el-dialog v-model="dialogVisible" title="新闻详情" width="60%"> |
|||
<p>{{ currentNews.content }}</p> |
|||
</el-dialog> |
|||
<!-- 消息区域 --> |
|||
<div class="message-area"> |
|||
<div |
|||
v-for="(msg, index) in messages" |
|||
:key="index" |
|||
:class="['message-bubble', msg.sender]" |
|||
> |
|||
{{ msg.content }} |
|||
</div> |
|||
</div> |
|||
|
|||
<!-- 新闻弹窗 --> |
|||
<el-dialog v-model="dialogVisible" title="新闻详情" width="60%"> |
|||
<p>{{ currentNews.content }}</p> |
|||
</el-dialog> |
|||
</div> |
|||
</template> |
|||
|
|||
<style scoped> |
|||
.chat-container { |
|||
display: flex; |
|||
flex-direction: column; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
|
|||
.gif-area { |
|||
/* position: relative; */ |
|||
height: 30vh; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
align-items: center; |
|||
/* position: relative; */ |
|||
height: 30vh; |
|||
display: flex; |
|||
flex-direction: column; |
|||
justify-content: center; |
|||
align-items: center; |
|||
} |
|||
|
|||
.gif-area img { |
|||
width: 30%; |
|||
/* 改为百分比单位 */ |
|||
min-width: 200px; |
|||
/* 最小尺寸 */ |
|||
max-width: 400px; |
|||
/* 最大尺寸 */ |
|||
height: auto; |
|||
left: 50%; |
|||
transition: all 0.3s; |
|||
/* 添加过渡效果 */ |
|||
|
|||
width: 30%; |
|||
/* 改为百分比单位 */ |
|||
min-width: 200px; |
|||
/* 最小尺寸 */ |
|||
max-width: 400px; |
|||
/* 最大尺寸 */ |
|||
height: auto; |
|||
left: 50%; |
|||
transition: all 0.3s; |
|||
/* 添加过渡效果 */ |
|||
} |
|||
|
|||
.marquee-container { |
|||
/* position: absolute; */ |
|||
bottom: 0; |
|||
width: 100%; |
|||
/* position: absolute; */ |
|||
bottom: 0; |
|||
width: 100%; |
|||
} |
|||
|
|||
.marquee-row { |
|||
white-space: nowrap; |
|||
overflow: visible; |
|||
padding: 8px 0; |
|||
width: 100%; |
|||
white-space: nowrap; |
|||
overflow: visible; |
|||
padding: 8px 0; |
|||
width: 100%; |
|||
} |
|||
|
|||
.marquee-item { |
|||
display: inline-block; |
|||
margin: 0 15px; |
|||
padding: 8px 20px; |
|||
background: rgba(255, 255, 255, 0.9); |
|||
/* 白色背景 */ |
|||
border-radius: 10px; |
|||
/* 圆角矩形 */ |
|||
color: #333; |
|||
/* 文字颜色改为深色 */ |
|||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
|||
/* 添加阴影 */ |
|||
transition: all 0.3s; |
|||
transition: color 0.3s; |
|||
display: inline-block; |
|||
margin: 0 15px; |
|||
padding: 8px 20px; |
|||
background: rgba(255, 255, 255, 0.9); |
|||
/* 白色背景 */ |
|||
border-radius: 10px; |
|||
/* 圆角矩形 */ |
|||
color: #333; |
|||
/* 文字颜色改为深色 */ |
|||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1); |
|||
/* 添加阴影 */ |
|||
transition: all 0.3s; |
|||
transition: color 0.3s; |
|||
} |
|||
|
|||
.top { |
|||
animation: marquee 15s linear infinite; |
|||
animation: marquee 15s linear infinite; |
|||
} |
|||
|
|||
.bottom { |
|||
animation: marquee 15s linear infinite reverse; |
|||
animation: marquee 15s linear infinite reverse; |
|||
} |
|||
|
|||
@keyframes marquee { |
|||
0% { |
|||
transform: translateX(100%); |
|||
} |
|||
0% { |
|||
transform: translateX(100%); |
|||
} |
|||
|
|||
100% { |
|||
transform: translateX(-150%); |
|||
} |
|||
100% { |
|||
transform: translateX(-150%); |
|||
} |
|||
} |
|||
|
|||
.message-area { |
|||
flex: 1; |
|||
overflow: auto; |
|||
padding: 20px; |
|||
flex: 1; |
|||
overflow: auto; |
|||
padding: 20px; |
|||
} |
|||
|
|||
.message-bubble { |
|||
max-width: 70%; |
|||
margin: 10px 20px; |
|||
padding: 15px 25px; |
|||
border-radius: 10px; |
|||
position: relative; |
|||
max-width: 70%; |
|||
margin: 10px 20px; |
|||
padding: 15px 25px; |
|||
border-radius: 10px; |
|||
position: relative; |
|||
} |
|||
|
|||
.message-bubble.user { |
|||
background: #8263f0; |
|||
color: white; |
|||
margin-left: auto; |
|||
/* border-bottom-right-radius: 5px; */ |
|||
background: #8263f0; |
|||
color: white; |
|||
margin-left: auto; |
|||
/* border-bottom-right-radius: 5px; */ |
|||
} |
|||
|
|||
.message-bubble.ai { |
|||
background: #f0f0f0; |
|||
color: #333; |
|||
margin-right: auto; |
|||
border-bottom-left-radius: 5px; |
|||
background: #f0f0f0; |
|||
color: #333; |
|||
margin-right: auto; |
|||
border-bottom-left-radius: 5px; |
|||
} |
|||
|
|||
.message-area { |
|||
flex: 1; |
|||
overflow-y: auto; |
|||
padding: 20px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 15px; |
|||
flex: 1; |
|||
overflow-y: auto; |
|||
padding: 20px; |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 15px; |
|||
} |
|||
</style> |
@ -0,0 +1,40 @@ |
|||
<script setup></script> |
|||
<template> |
|||
<el-main class="homepage-body"> |
|||
<div class="main-wrapper"> |
|||
<img |
|||
src="src\assets\img\AIchat\AIgif1.gif" |
|||
alt="图片加载失败" |
|||
class="logo1" |
|||
/> |
|||
<!-- 一段文字,水平居中,宽度为500px --> |
|||
|
|||
<div style="width: 500px; margin: 0 auto; text-align: center"> |
|||
<p> |
|||
欢迎使用AI智能问答系统,本系统基于OpenAI的GPT-3.5模型,为您提供智能问答服务。 |
|||
</p> |
|||
<p>这个是公告部分</p> |
|||
</div> |
|||
</div> |
|||
</el-main> |
|||
</template> |
|||
<style scoped> |
|||
.homepage-body { |
|||
padding: 0px; |
|||
height: calc(100% - 70px); |
|||
/* 根据底部高度调整 */ |
|||
} |
|||
.main-wrapper { |
|||
height: 100%; |
|||
display: flex; |
|||
flex-direction: column; |
|||
} |
|||
.logo1 { |
|||
/* 居中显示 30%大小 不要拉伸*/ |
|||
display: block; |
|||
width: 30%; |
|||
height: auto; |
|||
/* 水平居中 */ |
|||
margin: 0 auto; |
|||
} |
|||
</style> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue