Browse Source

合并代码

ds_hxl
宋杰 4 weeks ago
parent
commit
7372e283b0
  1. 53
      src/api/AiEmotionApi.js
  2. BIN
      src/assets/img/AiEmotion/L1.png
  3. BIN
      src/assets/img/AiEmotion/L2.png
  4. BIN
      src/assets/img/AiEmotion/L3.png
  5. BIN
      src/assets/img/AiEmotion/L4.png
  6. BIN
      src/assets/img/AiEmotion/bk01.png
  7. BIN
      src/assets/img/AiEmotion/bk02.png
  8. BIN
      src/assets/img/AiEmotion/bk03.png
  9. BIN
      src/assets/img/AiEmotion/tree.png
  10. BIN
      src/assets/img/AiEmotion/探底雷达.png
  11. BIN
      src/assets/img/AiEmotion/温度计.png
  12. BIN
      src/assets/img/AiEmotion/能量转化器.png
  13. BIN
      src/assets/img/AiEmotion/量子神经决策树.png
  14. BIN
      src/assets/img/AiEmotion/金轮.png
  15. 342
      src/views/AiEmotion.vue

53
src/api/AiEmotionApi.js

@ -3,29 +3,13 @@ import request from "../utils/request";
const APIurl = import.meta.env.VITE_APP_API_BASE_URL;
const MJAPIurl = import.meta.env.VITE_APP_MJ_API_BASE_URL;
//数据接口
export const dataListAPI = function (params) {
// URLSearchParams只接受全部字符串的数据
// 将传入数据转化成字符串
const StringParams = new URLSearchParams(
Object.entries(params).map(([key, value]) => [key, String(value)])
);
return request({
url: `${APIurl}/api/brain/data`,
method: "post",
data: StringParams,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});
};
// 获取回复接口
// 工作流获取用户意图接口
export const getReplyAPI = function (params) {
return fetch("https://api.coze.cn/v1/workflow/run", {
method: "POST",
body: JSON.stringify({
workflow_id: "7509384582975897650",
workflow_id: "7512677411467001910",
parameters: params,
}),
headers: {
@ -35,12 +19,13 @@ export const getReplyAPI = function (params) {
},
});
};
// 获取回复接口流式
export const getReplyStreamAPI = function (params) {
return fetch(`https://api.coze.cn/v1/workflow/stream_run`, {
// 获取第二个工作流给出的结论
export const getConclusion = function (params) {
return fetch("https://api.coze.cn/v1/workflow/run", {
method: "POST",
body: JSON.stringify({
workflow_id: "7481159261435854860",
workflow_id: "7509384582975897650",
parameters: params,
}),
headers: {
@ -50,27 +35,3 @@ export const getReplyStreamAPI = function (params) {
},
});
};
// 反馈前台-用户提交反馈接口
export const addFeedbackAPI = function (params) {
return request({
url: `${APIurl}/api/ai_god/feedback/add`,
method: "POST",
data: new URLSearchParams(params),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});
};
// 反馈前台-查询该用户提交的全部反馈内容
export const getFeedbackAPI = function (params) {
return request({
url: `${APIurl}/api/ai_god/feedback/select`,
method: "POST",
data: new URLSearchParams(params),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
});
};

BIN
src/assets/img/AiEmotion/L1.png

After

Width: 603  |  Height: 64  |  Size: 32 KiB

BIN
src/assets/img/AiEmotion/L2.png

After

Width: 603  |  Height: 64  |  Size: 33 KiB

BIN
src/assets/img/AiEmotion/L3.png

After

Width: 603  |  Height: 64  |  Size: 34 KiB

BIN
src/assets/img/AiEmotion/L4.png

After

Width: 603  |  Height: 64  |  Size: 32 KiB

BIN
src/assets/img/AiEmotion/bk01.png

After

Width: 407  |  Height: 75  |  Size: 15 KiB

BIN
src/assets/img/AiEmotion/bk02.png

After

Width: 630  |  Height: 468  |  Size: 196 KiB

BIN
src/assets/img/AiEmotion/bk03.png

After

Width: 630  |  Height: 593  |  Size: 238 KiB

BIN
src/assets/img/AiEmotion/tree.png

After

Width: 568  |  Height: 319  |  Size: 312 KiB

BIN
src/assets/img/AiEmotion/探底雷达.png

After

Width: 157  |  Height: 137  |  Size: 41 KiB

BIN
src/assets/img/AiEmotion/温度计.png

After

Width: 154  |  Height: 144  |  Size: 36 KiB

BIN
src/assets/img/AiEmotion/能量转化器.png

After

Width: 157  |  Height: 138  |  Size: 37 KiB

BIN
src/assets/img/AiEmotion/量子神经决策树.png

After

Width: 213  |  Height: 33  |  Size: 5.5 KiB

BIN
src/assets/img/AiEmotion/金轮.png

After

Width: 592  |  Height: 576  |  Size: 462 KiB

342
src/views/AiEmotion.vue

@ -1,10 +1,6 @@
<template>
<div class="ai-emotion-container">
<!-- 居中的图片 -->
<img src="@/assets/img/AiEmotion/round01.jpg" alt="AI情绪图片" class="center-image"
:class="{ rotating: isRotating }" />
<!-- 显示消息内容 -->
<!-- 消息显示区域 -->
<div class="user-input-display">
<div v-for="(message, index) in messages" :key="index" class="message-container">
<!-- 用户输入内容 -->
@ -13,10 +9,7 @@
</div>
<!-- AI返回结果 -->
<div v-if="message.sender === 'ai'" class="message-bubble ai-message">
<div v-if="message.chartData" id="kline-chart" style="width: 100%; height: 300px;"></div>
<div v-else>
{{ message.response }}
</div>
{{ message.text }}
</div>
</div>
</div>
@ -27,100 +20,298 @@
<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>
<img src="@/assets/img/AiEmotion/L1.png" alt="情绪监控">
<!-- 温度计图表 -->
<div class="class03">
</div>
<img src="@/assets/img/AiEmotion/L2.png" alt="情绪解码">
<!-- 情绪解码器图表 -->
<div class="class04">
<emotionDecod ref="emotionDecodRef"></emotionDecod>
</div>
<img src="@/assets/img/AiEmotion/L3.png" alt="情绪推演">
<!-- 情绪探底雷达图表 -->
<div class="class05">
<emotionalBottomRadar ref="emotionalBottomRadarRef"></emotionalBottomRadar>
</div>
<img src="@/assets/img/AiEmotion/L4.png" alt="情绪套利">
<!-- 情绪能量转化器图表 -->
<div class="class06">
<emoEnergyConverter ref="emoEnergyConverterRef"></emoEnergyConverter>
</div>
<!-- 核心看点 -->
<div class="class07">
</div>
<!-- 核心逻辑 -->
<img src="@/assets/img/AiEmotion/量子神经决策树.png" alt="">
<div class="class08">
</div>
<div class="class09"></div>
</div>
</template>
<script setup>
import { ref, reactive, nextTick } from 'vue';
import { ref, reactive } from 'vue';
import { getReplyAPI } from '@/api/AiEmotionApi.js'; //
import * as echarts from 'echarts'; // ECharts
import axios from 'axios';
import emotionDecod from '@/views/components/emotionDecod.vue'; //
import emotionalBottomRadar from '@/views/components/emotionalBottomRadar.vue'; //
import emoEnergyConverter from '@/views/components/emotionalBottomRadar.vue'; //
const emoEnergyConverterRef = ref(null)
const emotionDecodRef = ref(null)
const emotionalBottomRadarRef = ref(null)
const userInput = ref('');
const isRotating = ref(false);
const messages = ref([]);
//
async function sendMessage() {
console.log('发送内容:', userInput.value);
//
isRotating.value = true;
setTimeout(() => {
isRotating.value = false; //
}, 2000); // 2
//
if (userInput.value.trim()) {
const userMessage = reactive({ sender: 'user', text: userInput.value });
messages.value.push(userMessage);
userInput.value = ''; //
//
try {
//
const params = {
content: userInput.value,
content: userMessage.text,
userData: {
token: localStorage.getItem('localToken'),
token: '9ior41AF0xTIbIG2pRnnbZi0+fEeMx8pywnIlrmTwo5FbqJ9lWrSWOxp9MkpKiNtedtUafqvzIwpFKrwuMs',
language: 'cn',
brainPrivilegeState: "1",
swordPrivilegeState: "1",
stockForecastPrivile: "1",
spaceForecastPrivile: "1",
aibullPrivilegeState: "1",
aigoldBullPrivilegeS: "1",
airadarPrivilegeStat: "1",
brainPrivilegeState: '1',
swordPrivilegeState: '1',
stockForecastPrivile: '1',
spaceForecastPrivile: '1',
aibullPrivilegeState: '1',
aigoldBullPrivilegeS: '1',
airadarPrivilegeStat: '1',
marketList: 'hk,cn,usa,my,sg,vi,in,gb',
},
};
//
try {
const result = await getReplyAPI(params);
const response = await result.json(); // JSON
console.log('工作流接口返回数据:', response);
if (response && response.chartData) {
const aiMessage = reactive({ sender: 'ai', chartData: response.chartData });
messages.value.push(aiMessage);
// data
const parsedData = JSON.parse(response.data); // JSON
console.log('解析后的数据:', parsedData);
// K 线
nextTick(() => {
renderKLineChart(response.chartData);
});
if (parsedData && parsedData.market && parsedData.code) {
console.log('工作流接口返回股票信息:', parsedData);
//
fetchData(parsedData.code, parsedData.market);
} else {
const aiMessage = reactive({ sender: 'ai', response: 'AI思考失败,请稍后再试...' });
messages.value.push(aiMessage);
console.error('工作流接口返回非股票信息:', parsedData.refuse);
messages.value.push({
sender: 'ai',
text: `工作流接口返回信息: ${parsedData.refuse || '未知错误'}`,
});
}
} catch (error) {
console.error('请求失败:', error);
const errorMessage = reactive({ sender: 'ai', response: '请求失败,请稍后重试' });
messages.value.push(errorMessage);
console.error('请求工作流接口失败:', error);
messages.value.push({
sender: 'ai',
text: '工作流接口请求失败,请稍后再试。',
});
}
} else {
console.warn('用户输入内容为空,无法发送请求');
messages.value.push({
sender: 'ai',
text: '请输入内容后再发送。',
});
}
}
function renderKLineChart(chartData) {
const chartDom = document.getElementById('kline-chart');
const myChart = echarts.init(chartDom);
//
async function fetchData(code, market) {
try {
const stockDataParams = {
token: '9ior41AF0xTIbIG2pRnnbZi0+fEeMx8pywnIlrmTwo5FbqJ9lWrSWOxp9MkpKiNtedtUafqvzIwpFKrwuMs',
market: market,
code: code,
language: 'cn',
};
const option = {
title: {
text: 'K线图',
left: 'center',
},
tooltip: {
trigger: 'axis',
},
xAxis: {
type: 'category',
data: chartData.dates,
},
yAxis: {
type: 'value',
},
series: [
const stockDataResult = await axios.post(
'http://39.101.133.168:8828/link/api/aiEmotion/client/getAiEmotionData',
stockDataParams,
{
type: 'candlestick',
data: chartData.values,
headers: {
'Content-Type': 'application/json',
},
],
};
}
);
const stockDataResponse = stockDataResult.data; //
console.log('图表数据接口返回数据:', stockDataResponse);
myChart.setOption(option);
if (stockDataResponse.data) {
messages.value.push({
sender: 'ai',
text: `股票数据已成功获取: ${JSON.stringify(stockDataResponse.data)}`,
});
} 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 (emoEnergyConverterRef.value && data.QXNLZHQ) {
emoEnergyConverterRef.value.initQXNLZHEcharts(data.KLine20, data.QXNLZHQ);
}
//
if (emotionDecodRef.value && data.QXJMQ) {
emotionDecodRef.value.initQXNLZHEcharts(data.KLine20, data.QXJMQ);
}
//
if (emotionalBottomRadarRef.value && data.QXTDLD) {
emotionalBottomRadarRef.value.initEmotionalBottomRadar(data.KLine20, data.QXTDLD);
}
});
}
</script>
<style scoped>
.class08 {
background-image: url('@/assets/img/AiEmotion/tree.png');
/* 使用导入的背景图片 */
background-size: cover;
/* 确保背景图片完整显示 */
background-repeat: no-repeat;
/* 防止背景图片重复 */
width: 100%;
/* 设置容器宽度 */
height: auto;
/* 高度根据内容动态变化 */
min-height: 400px;
/* 设置最小高度,确保图片显示 */
}
.class06 {
background-image: url('@/assets/img/AiEmotion/bk03.png');
/* 使用导入的背景图片 */
background-size: cover;
/* 确保背景图片完整显示 */
background-repeat: no-repeat;
/* 防止背景图片重复 */
width: 100%;
/* 设置容器宽度 */
height: auto;
/* 高度根据内容动态变化 */
min-height: 575px;
/* 设置最小高度,确保图片显示 */
}
.class05 {
background-image: url('@/assets/img/AiEmotion/bk03.png');
/* 使用导入的背景图片 */
background-size: cover;
/* 确保背景图片完整显示 */
background-repeat: no-repeat;
/* 防止背景图片重复 */
width: 100%;
/* 设置容器宽度 */
height: auto;
/* 高度根据内容动态变化 */
min-height: 575px;
/* 设置最小高度,确保图片显示 */
}
.class04 {
background-image: url('@/assets/img/AiEmotion/bk03.png');
/* 使用导入的背景图片 */
background-size: cover;
/* 确保背景图片完整显示 */
background-repeat: no-repeat;
/* 防止背景图片重复 */
width: 100%;
/* 设置容器宽度 */
height: auto;
/* 高度根据内容动态变化 */
min-height: 575px;
/* 设置最小高度,确保图片显示 */
}
.class03 {
background-image: url('@/assets/img/AiEmotion/bk02.png');
/* 使用导入的背景图片 */
background-size: cover;
/* 确保背景图片完整显示 */
background-repeat: no-repeat;
/* 防止背景图片重复 */
width: 100%;
/* 设置容器宽度 */
height: auto;
/* 高度根据内容动态变化 */
min-height: 460px;
/* 设置最小高度,确保图片显示 */
}
.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: 60%;
/* 固定容器宽度 */
min-height: 100px;
/* 设置最小高度,确保初始显示 */
height: auto;
/* 高度根据内容动态变化 */
padding: 20px;
/* 添加内边距,确保内容与边界有间距 */
box-sizing: border-box;
/* 包括内边距在宽度和高度计算中 */
}
.ai-emotion-container {
display: flex;
flex-direction: column;
@ -130,25 +321,8 @@ function renderKLineChart(chartData) {
position: relative;
}
.center-image {
max-width: 20%;
/* 缩小为原大小的50% */
height: auto;
margin-bottom: 20px;
border-radius: 100%;
/* 将图片变成圆角 */
transition: transform 2s ease-out;
/* 添加旋转动画 */
}
.center-image.rotating {
transform: rotate(360deg);
/* 旋转360度 */
}
.user-input-display {
margin-top: 20px;
/* 添加与图片的间距 */
display: flex;
flex-direction: column;
width: 100%;
@ -168,7 +342,6 @@ function renderKLineChart(chartData) {
text-align: left;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
align-self: flex-end;
/* 用户消息靠右 */
}
.ai-message {
@ -180,7 +353,6 @@ function renderKLineChart(chartData) {
text-align: left;
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
align-self: flex-start;
/* AI消息靠左 */
}
.input-container {
@ -192,7 +364,6 @@ function renderKLineChart(chartData) {
.fixed-bottom {
position: fixed;
bottom: 100px;
/* 向上移动10px */
left: 0;
width: 100%;
background-color: #f8f9fa;
@ -206,7 +377,6 @@ function renderKLineChart(chartData) {
border: 1px solid #ccc;
border-radius: 5px;
width: calc(100% - 120px);
/* 适配按钮宽度 */
}
.send-button {

Loading…
Cancel
Save