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.
491 lines
14 KiB
491 lines
14 KiB
<template>
|
|
<div class="ai-emotion-container">
|
|
<!-- 消息显示区域 -->
|
|
<div class="user-input-display">
|
|
<div v-for="(message, index) in messages" :key="index" class="message-container">
|
|
<!-- 用户输入内容 -->
|
|
<div v-if="message.sender === 'user'" class="message-bubble user-message">
|
|
{{ message.text }}
|
|
</div>
|
|
<!-- AI返回结果 -->
|
|
<div v-if="message.sender === 'ai'" class="message-bubble ai-message">
|
|
{{ message.text }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 输入框和发送按钮 -->
|
|
<div class="input-container fixed-bottom">
|
|
<input type="text" v-model="userInput" placeholder="请输入内容..." class="input-box" />
|
|
<button @click="sendMessage" class="send-button">发送</button>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 渲染整个页面 -->
|
|
<div class="class01">
|
|
<!-- 四维矩阵图 -->
|
|
<div class="class02">
|
|
<span class="span01">房间卡方法啊付了款公交卡阿济格</span>
|
|
<span class="span02"> 2025/06/07</span>
|
|
</div>
|
|
<div class="class0201">
|
|
<img src="@/assets/img/AiEmotion/L1.png" alt="情绪监控图标">
|
|
</div>
|
|
<!-- 温度计图表 -->
|
|
<div class="class03">
|
|
|
|
</div>
|
|
<div class="class0301">
|
|
<img src="@/assets/img/AiEmotion/L2.png" alt="情绪解码图标">
|
|
</div>
|
|
<!-- 情绪解码器图表 -->
|
|
<div class="class04">
|
|
<div class="class0401">
|
|
<img src='@/assets/img/AiEmotion/emotionDecod.png' alt="情绪解码器图标">
|
|
</div>
|
|
<div class="class0402">
|
|
<emotionDecod ref="emotionDecodRef"></emotionDecod>
|
|
</div>
|
|
</div>
|
|
<div class="class0403">
|
|
<img src="@/assets/img/AiEmotion/L3.png" alt="情绪推演图标">
|
|
</div>
|
|
<!-- 情绪探底雷达图表 -->
|
|
<div class="class05">
|
|
<div class="class0502">
|
|
<img src="@/assets/img/AiEmotion/探底雷达.png" alt="探底雷达图表">
|
|
</div>
|
|
<div class="class0503">
|
|
<emotionalBottomRadar ref="emotionalBottomRadarRef"></emotionalBottomRadar>
|
|
</div>
|
|
</div>
|
|
<div class="class0501">
|
|
<img src="@/assets/img/AiEmotion/L4.png" alt="情绪套利">
|
|
</div>
|
|
<!-- 情绪能量转化器图表 -->
|
|
<div class="class06">
|
|
<div class="class0601">
|
|
<img src="@/assets/img/AiEmotion/能量转化器.png" alt="能量转化器图标">
|
|
</div>
|
|
<emoEnergyConverter ref="emoEnergyConverterRef"></emoEnergyConverter>
|
|
</div>
|
|
<!-- 核心看点 -->
|
|
<div class="class07">
|
|
|
|
</div>
|
|
<!-- 核心逻辑 -->
|
|
<div class="class0701">
|
|
<img src="@/assets/img/AiEmotion/量子神经决策树.png" alt="">
|
|
</div>
|
|
<div class="class08">
|
|
|
|
</div>
|
|
<div class="class09"></div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { ref, reactive } from 'vue';
|
|
import { getReplyAPI } from '@/api/AiEmotionApi.js'; // 导入工作流接口方法
|
|
import axios from 'axios';
|
|
import emotionDecod from '@/views/components/emotionDecod.vue'; // 导入情绪解码组件
|
|
import emotionalBottomRadar from '@/views/components/emotionalBottomRadar.vue'; // 导入情绪探底雷达图组件
|
|
import emoEnergyConverter from '@/views/components/emoEnergyConverter.vue'; // 导入情绪能量转化器组件
|
|
|
|
|
|
const emoEnergyConverterRef = ref(null)
|
|
const emotionDecodRef = ref(null)
|
|
const emotionalBottomRadarRef = ref(null)
|
|
|
|
const userInput = ref('');
|
|
const messages = ref([]);
|
|
|
|
// 请求工作流接口
|
|
async function sendMessage() {
|
|
console.log('发送内容:', userInput.value);
|
|
|
|
// 检查用户输入内容是否为空
|
|
if (userInput.value.trim()) {
|
|
const userMessage = reactive({ sender: 'user', text: userInput.value });
|
|
messages.value.push(userMessage);
|
|
userInput.value = ''; // 清空输入框
|
|
|
|
try {
|
|
// 调用工作流接口
|
|
const params = {
|
|
content: userMessage.text,
|
|
userData: {
|
|
token: '9ior41AF0xTIbIG2pRnnbZi0+fEeMx8pywnIlrmTwo5FbqJ9lWrSWOxp9MkpKiNtedtUafqvzIwpFKrwuMs',
|
|
language: 'cn',
|
|
brainPrivilegeState: '1',
|
|
swordPrivilegeState: '1',
|
|
stockForecastPrivile: '1',
|
|
spaceForecastPrivile: '1',
|
|
aibullPrivilegeState: '1',
|
|
aigoldBullPrivilegeS: '1',
|
|
airadarPrivilegeStat: '1',
|
|
marketList: 'hk,cn,usa,my,sg,vi,in,gb',
|
|
},
|
|
};
|
|
|
|
const result = await getReplyAPI(params);
|
|
const response = await result.json(); // 解析返回的 JSON 数据
|
|
console.log('工作流接口返回数据:', response);
|
|
|
|
// 解析 data 字段
|
|
const parsedData = JSON.parse(response.data); // 将字符串形式的 JSON 转换为对象
|
|
console.log('解析后的数据:', parsedData);
|
|
|
|
if (parsedData && parsedData.market && parsedData.code) {
|
|
console.log('工作流接口返回股票信息:', parsedData);
|
|
|
|
// 请求数据接口
|
|
fetchData(parsedData.code, parsedData.market);
|
|
} else {
|
|
console.error('工作流接口返回非股票信息:', parsedData.refuse);
|
|
messages.value.push({
|
|
sender: 'ai',
|
|
text: `工作流接口返回信息: ${parsedData.refuse || '未知错误'}`,
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('请求工作流接口失败:', error);
|
|
messages.value.push({
|
|
sender: 'ai',
|
|
text: '工作流接口请求失败,请稍后再试。',
|
|
});
|
|
}
|
|
} else {
|
|
console.warn('用户输入内容为空,无法发送请求');
|
|
messages.value.push({
|
|
sender: 'ai',
|
|
text: '请输入内容后再发送。',
|
|
});
|
|
}
|
|
}
|
|
|
|
// 请求数据接口
|
|
async function fetchData(code, market) {
|
|
try {
|
|
const stockDataParams = {
|
|
// token: '+XgqsgdW0RLIbIG2pxnnbZi0+fEeMx8pywnIlrmTxtkSaPZ9xjSOWrxq+s0rL3RrfNhXPvGtz9srFfjwu8A',
|
|
token: '9ior41AF0xTIbIG2pRnnbZi0+fEeMx8pywnIlrmTwo5FbqJ9lWrSWOxp9MkpKiNtedtUafqvzIwpFKrwuMs',
|
|
market: 'usa',
|
|
code: 'TSLA',
|
|
language: 'cn',
|
|
};
|
|
|
|
const stockDataResult = await axios.post(
|
|
'http://39.101.133.168:8828/link/api/aiEmotion/client/getAiEmotionData',
|
|
// 'https://api.homilychart.com/link/api/aiEmotion/client/getAiEmotionData',
|
|
stockDataParams,
|
|
{
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
}
|
|
);
|
|
|
|
const stockDataResponse = stockDataResult.data; // 获取返回的数据
|
|
console.log('图表数据接口返回数据:', stockDataResponse);
|
|
|
|
if (stockDataResponse.data) {
|
|
messages.value.push({
|
|
sender: 'ai',
|
|
text: `股票数据已成功获取: ${JSON.stringify(stockDataResponse.data)}`,
|
|
});
|
|
console.log('1111111111111111111111')
|
|
// 调用渲染图表的方法
|
|
renderCharts(stockDataResponse.data);
|
|
console.log('2222222222222222222222')
|
|
} else {
|
|
console.error('图表数据接口返回数据不完整');
|
|
messages.value.push({
|
|
sender: 'ai',
|
|
text: '图表数据接口返回数据不完整,请稍后再试。',
|
|
});
|
|
}
|
|
} catch (error) {
|
|
console.error('请求图表数据接口失败:', error);
|
|
messages.value.push({
|
|
sender: 'ai',
|
|
text: '图表数据接口请求失败,请稍后再试。',
|
|
});
|
|
}
|
|
}
|
|
|
|
// 渲染组件图表的方法
|
|
function renderCharts(data) {
|
|
nextTick(() => {
|
|
|
|
|
|
// 渲染情绪解码器图表
|
|
if (emotionDecodRef.value && data.QXJMQ) {
|
|
console.log('开始渲染情绪解码器图表');
|
|
console.log('情绪解码器数据', data.QXJMQ)
|
|
emotionDecodRef.value.initQXNLZHEcharts(data.KLine20, data.QXJMQ);
|
|
console.log('情绪解码器图表已渲染');
|
|
}
|
|
// 渲染情绪探底雷达图表
|
|
if (emotionalBottomRadarRef.value && data.QXTDLD) {
|
|
console.log('开始渲染情绪探底雷达图表');
|
|
console.log('数据', data.QXTDLD)
|
|
emotionalBottomRadarRef.value.initEmotionalBottomRadar(data.KLine20, data.QXTDLD);
|
|
console.log('情绪探底雷达图表已渲染');
|
|
}
|
|
// 渲染情绪能量转化器图表
|
|
if (emoEnergyConverterRef.value && data.QXNLZHQ) {
|
|
console.log('开始渲染情绪能量转化器图表');
|
|
console.log('KLine20:', data.KLine20);
|
|
console.log('QXNLZHQ:', data.QXNLZHQ);
|
|
emoEnergyConverterRef.value.initQXNLZHEcharts(data.KLine20, data.QXNLZHQ);
|
|
console.log('情绪能量转化器图表已渲染');
|
|
}
|
|
|
|
});
|
|
}
|
|
</script>
|
|
|
|
<style scoped>
|
|
/* .class0402 {
|
|
width: fit-content;
|
|
margin: 0 auto;
|
|
} */
|
|
|
|
.class0601 {
|
|
padding-top: 10rem;
|
|
text-align: center;
|
|
}
|
|
|
|
.class0502 {
|
|
padding-top: 10rem;
|
|
text-align: center;
|
|
}
|
|
|
|
.class0701 {
|
|
margin: 0 auto;
|
|
width: fit-content;
|
|
}
|
|
|
|
.class0501 {
|
|
margin: 0 auto;
|
|
width: fit-content;
|
|
}
|
|
|
|
.class0403 {
|
|
margin: 0 auto;
|
|
width: fit-content;
|
|
}
|
|
|
|
.class0301 {
|
|
margin: 0 auto;
|
|
width: fit-content;
|
|
}
|
|
|
|
.class0201 {
|
|
margin: 0 auto;
|
|
width: fit-content;
|
|
}
|
|
|
|
.class0401 {
|
|
padding-top: 10rem;
|
|
text-align: center;
|
|
}
|
|
|
|
.class08 {
|
|
background-image: url('@/assets/img/AiEmotion/tree.png');
|
|
/* 使用导入的背景图片 */
|
|
background-size: cover;
|
|
/* 确保背景图片完整显示 */
|
|
background-repeat: no-repeat;
|
|
/* 防止背景图片重复 */
|
|
width: 95%;
|
|
/* 设置容器宽度 */
|
|
height: auto;
|
|
/* 高度根据内容动态变化 */
|
|
min-height: 400px;
|
|
/* 设置最小高度,确保图片显示 */
|
|
margin: 0 auto;
|
|
/* margin-bottom: 10rem; */
|
|
}
|
|
|
|
.class06 {
|
|
background-image: url('@/assets/img/AiEmotion/bk03.png');
|
|
/* 使用导入的背景图片 */
|
|
background-size: cover;
|
|
/* 确保背景图片完整显示 */
|
|
background-repeat: no-repeat;
|
|
/* 防止背景图片重复 */
|
|
width: 95%;
|
|
/* 设置容器宽度 */
|
|
height: auto;
|
|
/* 高度根据内容动态变化 */
|
|
min-height: 70rem;
|
|
/* 设置最小高度,确保图片显示 */
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.class05 {
|
|
background-image: url('@/assets/img/AiEmotion/bk03.png');
|
|
/* 使用导入的背景图片 */
|
|
background-size: cover;
|
|
/* 确保背景图片完整显示 */
|
|
background-repeat: no-repeat;
|
|
/* 防止背景图片重复 */
|
|
width: 95%;
|
|
/* 设置容器宽度 */
|
|
height: auto;
|
|
/* 高度根据内容动态变化 */
|
|
min-height: 575px;
|
|
/* 设置最小高度,确保图片显示 */
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.class04 {
|
|
background-image: url('@/assets/img/AiEmotion/bk03.png');
|
|
/* 使用导入的背景图片 */
|
|
background-size: cover;
|
|
/* 确保背景图片完整显示 */
|
|
background-repeat: no-repeat;
|
|
/* 防止背景图片重复 */
|
|
width: 95%;
|
|
/* 设置容器宽度 */
|
|
height: auto;
|
|
/* 高度根据内容动态变化 */
|
|
min-height: 69rem;
|
|
/* 设置最小高度,确保图片显示 */
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.class03 {
|
|
background-image: url('@/assets/img/AiEmotion/bk03.png');
|
|
/* 使用导入的背景图片 */
|
|
background-size: cover;
|
|
/* 确保背景图片完整显示 */
|
|
background-repeat: no-repeat;
|
|
/* 防止背景图片重复 */
|
|
width: 95%;
|
|
/* 设置容器宽度 */
|
|
height: auto;
|
|
/* 高度根据内容动态变化 */
|
|
min-height: 70rem;
|
|
/* 设置最小高度,确保图片显示 */
|
|
margin: 0 auto;
|
|
}
|
|
|
|
.span01 {
|
|
background-image: url('@/assets/img/AiEmotion/bk01.png');
|
|
/* 使用导入的背景图片 */
|
|
background-size: cover;
|
|
/* 背景图片覆盖整个容器 */
|
|
background-repeat: no-repeat;
|
|
/* 防止背景图片重复 */
|
|
display: inline-block;
|
|
/* 确保容器是块级元素 */
|
|
padding: 10px;
|
|
/* 添加内边距以显示内容 */
|
|
color: #fff;
|
|
/* 设置文字颜色以确保可读性 */
|
|
border-radius: 5px;
|
|
/* 添加圆角 */
|
|
}
|
|
|
|
.class01 {
|
|
width: 90%;
|
|
/* 固定容器宽度 */
|
|
min-height: 100px;
|
|
/* 设置最小高度,确保初始显示 */
|
|
height: auto;
|
|
/* 高度根据内容动态变化 */
|
|
padding: 20px;
|
|
/* 添加内边距,确保内容与边界有间距 */
|
|
box-sizing: border-box;
|
|
/* 包括内边距在宽度和高度计算中 */
|
|
background-color: #5e81a7;
|
|
margin: 0 auto;
|
|
/* 居中容器 */
|
|
margin-bottom: 10rem;
|
|
|
|
}
|
|
|
|
.ai-emotion-container {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 20px;
|
|
position: relative;
|
|
}
|
|
|
|
.user-input-display {
|
|
margin-top: 20px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 100%;
|
|
}
|
|
|
|
.message-container {
|
|
display: flex;
|
|
margin-bottom: 10px;
|
|
}
|
|
|
|
.user-message {
|
|
background-color: #007bff;
|
|
color: #fff;
|
|
padding: 10px 15px;
|
|
border-radius: 15px;
|
|
max-width: 60%;
|
|
text-align: left;
|
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
|
align-self: flex-end;
|
|
}
|
|
|
|
.ai-message {
|
|
background-color: #f1f1f1;
|
|
color: #333;
|
|
padding: 10px 15px;
|
|
border-radius: 15px;
|
|
max-width: 60%;
|
|
text-align: left;
|
|
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
|
align-self: flex-start;
|
|
}
|
|
|
|
.input-container {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
}
|
|
|
|
.fixed-bottom {
|
|
position: fixed;
|
|
bottom: 100px;
|
|
left: 0;
|
|
width: 100%;
|
|
background-color: #f8f9fa;
|
|
padding: 10px 20px;
|
|
box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);
|
|
}
|
|
|
|
.input-box {
|
|
padding: 10px;
|
|
font-size: 16px;
|
|
border: 1px solid #ccc;
|
|
border-radius: 5px;
|
|
width: calc(100% - 120px);
|
|
}
|
|
|
|
.send-button {
|
|
padding: 10px 20px;
|
|
font-size: 16px;
|
|
color: #fff;
|
|
background-color: #007bff;
|
|
border: none;
|
|
border-radius: 5px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.send-button:hover {
|
|
background-color: #0056b3;
|
|
}
|
|
</style>
|