Browse Source
Merge branch 'ds' of http://39.101.133.168:8807/hongxilin/AIxiaocaishen into ds
ds_hxl
Merge branch 'ds' of http://39.101.133.168:8807/hongxilin/AIxiaocaishen into ds
ds_hxl
11 changed files with 346 additions and 19 deletions
-
3.env.development
-
6src/api/AIxiaocaishen.js
-
76src/api/AiEmotionApi.js
-
BINsrc/assets/img/AiEmotion/round01.jpg
-
BINsrc/assets/img/AiEmotion/round02.jpg
-
BINsrc/assets/img/homePage/AI情绪大模型小图标.png
-
BINsrc/assets/img/homePage/bk01.jpg
-
BINsrc/assets/img/homePage/夺宝奇兵大模型小图标.png
-
6src/router/index.js
-
225src/views/AiEmotion.vue
-
37src/views/homePage.vue
@ -0,0 +1,76 @@ |
|||||
|
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", |
||||
|
parameters: params, |
||||
|
}), |
||||
|
headers: { |
||||
|
"Content-Type": "application/json", |
||||
|
Authorization: |
||||
|
"Bearer pat_lK1fvhLn9LnWCRETP7yFeR6xQ0niwQdcHJ5ZqpnUk8BdiUWCraPLSzWhiQNp2zOl", |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
// 获取回复接口流式
|
||||
|
export const getReplyStreamAPI = function (params) { |
||||
|
return fetch(`https://api.coze.cn/v1/workflow/stream_run`, { |
||||
|
method: "POST", |
||||
|
body: JSON.stringify({ |
||||
|
workflow_id: "7481159261435854860", |
||||
|
parameters: params, |
||||
|
}), |
||||
|
headers: { |
||||
|
"Content-Type": "application/json", |
||||
|
Authorization: |
||||
|
"Bearer pat_lK1fvhLn9LnWCRETP7yFeR6xQ0niwQdcHJ5ZqpnUk8BdiUWCraPLSzWhiQNp2zOl", |
||||
|
}, |
||||
|
}); |
||||
|
}; |
||||
|
|
||||
|
|
||||
|
// 反馈前台-用户提交反馈接口
|
||||
|
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", |
||||
|
}, |
||||
|
}); |
||||
|
}; |
After Width: 672 | Height: 554 | Size: 22 KiB |
After Width: 694 | Height: 550 | Size: 31 KiB |
After Width: 42 | Height: 42 | Size: 4.0 KiB |
After Width: 750 | Height: 6060 | Size: 98 KiB |
After Width: 43 | Height: 42 | Size: 3.4 KiB |
@ -0,0 +1,225 @@ |
|||||
|
<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"> |
||||
|
<!-- 用户输入内容 --> |
||||
|
<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"> |
||||
|
<div v-if="message.chartData" id="kline-chart" style="width: 100%; height: 300px;"></div> |
||||
|
<div v-else> |
||||
|
{{ message.response }} |
||||
|
</div> |
||||
|
</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> |
||||
|
</template> |
||||
|
|
||||
|
<script setup> |
||||
|
import { ref, reactive, nextTick } from 'vue'; |
||||
|
import { getReplyAPI } from '@/api/AiEmotionApi.js'; // 导入工作流接口方法 |
||||
|
import * as echarts from 'echarts'; // 引入 ECharts |
||||
|
|
||||
|
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秒 |
||||
|
|
||||
|
// 准备调用接口的参数 |
||||
|
const params = { |
||||
|
content: userInput.value, |
||||
|
userData: { |
||||
|
token: localStorage.getItem('localToken'), |
||||
|
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', |
||||
|
}, |
||||
|
}; |
||||
|
|
||||
|
// 调用工作流接口 |
||||
|
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); |
||||
|
|
||||
|
// 渲染 K 线图 |
||||
|
nextTick(() => { |
||||
|
renderKLineChart(response.chartData); |
||||
|
}); |
||||
|
} else { |
||||
|
const aiMessage = reactive({ sender: 'ai', response: 'AI思考失败,请稍后再试...' }); |
||||
|
messages.value.push(aiMessage); |
||||
|
} |
||||
|
} catch (error) { |
||||
|
console.error('请求失败:', error); |
||||
|
const errorMessage = reactive({ sender: 'ai', response: '请求失败,请稍后重试' }); |
||||
|
messages.value.push(errorMessage); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
function renderKLineChart(chartData) { |
||||
|
const chartDom = document.getElementById('kline-chart'); |
||||
|
const myChart = echarts.init(chartDom); |
||||
|
|
||||
|
const option = { |
||||
|
title: { |
||||
|
text: 'K线图', |
||||
|
left: 'center', |
||||
|
}, |
||||
|
tooltip: { |
||||
|
trigger: 'axis', |
||||
|
}, |
||||
|
xAxis: { |
||||
|
type: 'category', |
||||
|
data: chartData.dates, |
||||
|
}, |
||||
|
yAxis: { |
||||
|
type: 'value', |
||||
|
}, |
||||
|
series: [ |
||||
|
{ |
||||
|
type: 'candlestick', |
||||
|
data: chartData.values, |
||||
|
}, |
||||
|
], |
||||
|
}; |
||||
|
|
||||
|
myChart.setOption(option); |
||||
|
} |
||||
|
</script> |
||||
|
|
||||
|
<style scoped> |
||||
|
.ai-emotion-container { |
||||
|
display: flex; |
||||
|
flex-direction: column; |
||||
|
align-items: center; |
||||
|
justify-content: center; |
||||
|
padding: 20px; |
||||
|
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%; |
||||
|
} |
||||
|
|
||||
|
.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; |
||||
|
/* AI消息靠左 */ |
||||
|
} |
||||
|
|
||||
|
.input-container { |
||||
|
display: flex; |
||||
|
align-items: center; |
||||
|
gap: 10px; |
||||
|
} |
||||
|
|
||||
|
.fixed-bottom { |
||||
|
position: fixed; |
||||
|
bottom: 100px; |
||||
|
/* 向上移动10px */ |
||||
|
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> |
Write
Preview
Loading…
Cancel
Save
Reference in new issue