Browse Source

加入打包环境配置;情绪大模型对接口完成;

master
宋杰 5 days ago
parent
commit
0392ed3ede
  1. 4
      .env.development
  2. 2
      .env.production
  3. 5
      build/vite/plugin/compress.js
  4. 3
      package.json
  5. 68
      src/api/AiEmotionApi.js
  6. 514
      src/views/AiEmotion.vue
  7. 4
      src/views/components/HistoryRecord.vue

4
.env.development

@ -5,8 +5,8 @@ VITE_OUTPUT_DIR = 'dev'
VITE_PUBLIC_PATH = /
#新数据接口
# VITE_APP_API_BASE_URL = "http://39.101.133.168:8828/link"
VITE_APP_API_BASE_URL = "https://api.homilychart.com/link"
VITE_APP_API_BASE_URL = "http://39.101.133.168:8828/link"
# VITE_APP_API_BASE_URL = "https://api.homilychart.com/link"
# VITE_APP_API_BASE_CAZE_URL = "http://39.101.133.168:8828/link"
VITE_APP_API_BASE_CAZE_URL = "https://api.homilychart.com/link"

2
.env.production

@ -1,6 +1,6 @@
# must start with VITE_
VITE_ENV = 'production'
VITE_OUTPUT_DIR = 'dist'
VITE_OUTPUT_DIR = 'prod'
# public path
VITE_PUBLIC_PATH = /aixiaocaishen
# VITE_PUBLIC_PATH = /

5
build/vite/plugin/compress.js

@ -8,6 +8,11 @@ export function configCompressPlugin(
compress,
deleteOriginFile = false
) {
// 如果compress为undefined或空字符串,返回空数组
if (!compress || compress === 'none') {
return []
}
const compressList = compress.split(',')
const plugins = []

3
package.json

@ -6,7 +6,8 @@
"test": "vite --mode test",
"prod": "vite --mode production",
"build": "vite build",
"build:test": "vite build --mode test",
"build:test": "vite build --mode development",
"build:prod": "vite build --mode production",
"typecheck": "vue-tsc --noEmit",
"preview": "npm run build && vite preview --port 5050",
"preview:dist": "vite preview",

68
src/api/AiEmotionApi.js

@ -5,33 +5,57 @@ const MJAPIurl = import.meta.env.VITE_APP_MJ_API_BASE_URL;
// 工作流获取用户意图接口
// export const getReplyAPI = function (params) {
// return fetch("https://api.coze.cn/v1/workflow/run", {
// method: "POST",
// body: JSON.stringify({
// workflow_id: "7512677411467001910",
// parameters: params,
// }),
// headers: {
// "Content-Type": "application/json",
// Authorization:
// "Bearer pat_D6vYu7FNXfkSJn8GpmA9oC4DY8LkcbhzrSZuJwuTHT0aYn2uqZ6P5cBfRD0kwZYR",
// },
// });
// };
export const getReplyAPI = function (params) {
return fetch("https://api.coze.cn/v1/workflow/run", {
method: "POST",
body: JSON.stringify({
workflow_id: "7512677411467001910",
parameters: params,
}),
headers: {
"Content-Type": "application/json",
Authorization:
"Bearer pat_D6vYu7FNXfkSJn8GpmA9oC4DY8LkcbhzrSZuJwuTHT0aYn2uqZ6P5cBfRD0kwZYR",
return request({
url: `${APIurl}/api/workflow/aiGodFirst`,
method: "post",
data: {
"token": localStorage.getItem("localToken"),
"language": "cn",
"marketList": "hk,cn,usa,my,sg,vi,in,gb",
"content": params.content
},
});
};
// 获取第二个工作流给出的结论
// export const getConclusionAPI = 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_D6vYu7FNXfkSJn8GpmA9oC4DY8LkcbhzrSZuJwuTHT0aYn2uqZ6P5cBfRD0kwZYR",
// },
// });
// };
export const getConclusionAPI = 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_D6vYu7FNXfkSJn8GpmA9oC4DY8LkcbhzrSZuJwuTHT0aYn2uqZ6P5cBfRD0kwZYR",
return request({
url: `${APIurl}/api/workflow/aiGodSecond`,
method: "post",
data: {
"language": "cn",
"parentId": params.parentId,
"recordId": params.recordId,
"stockId": params.stockId,
"token": localStorage.getItem("localToken")
},
});
};
};

514
src/views/AiEmotion.vue

@ -24,6 +24,7 @@
/>
<div class="message-bubble user-message">
{{ message.text }}
</div>
</div>
<!-- AI返回结果 -->
@ -152,26 +153,27 @@
<img src="@/assets/img/AiEmotion/场景应用.png" alt="场景应用标题">
<div class="bk-image">
<div class="conclusion-container" v-if="getStockConclusion(stock)">
<div class="conclusion-item" v-if="(getStockConclusion(stock).one1 || getStockConclusion(stock).one2)">
<h4 class="conclusion-title">L1: 情绪监控</h4>
<p class="conclusion-text" v-if="getStockConclusion(stock).one1">{{ getStockConclusion(stock).one1 }}</p>
<p class="conclusion-text" v-if="getStockConclusion(stock).one2">{{ getStockConclusion(stock).one2 }}</p>
<!-- 打字机效果显示的内容 -->
<div class="conclusion-item" v-if="moduleVisibility.one">
<h4 class="conclusion-title">{{ displayedTitles.one }}</h4>
<p class="conclusion-text" v-if="displayedTexts.one1">{{ displayedTexts.one1 }}</p>
<p class="conclusion-text" v-if="displayedTexts.one2">{{ displayedTexts.one2 }}</p>
</div>
<div class="conclusion-item" v-if="getStockConclusion(stock).two">
<h4 class="conclusion-title">L2: 情绪解码</h4>
<p class="conclusion-text">{{ getStockConclusion(stock).two }}</p>
<div class="conclusion-item" v-if="moduleVisibility.two">
<h4 class="conclusion-title">{{ displayedTitles.two }}</h4>
<p class="conclusion-text">{{ displayedTexts.two }}</p>
</div>
<div class="conclusion-item" v-if="getStockConclusion(stock).three">
<h4 class="conclusion-title">L3: 情绪推演</h4>
<p class="conclusion-text">{{ getStockConclusion(stock).three }}</p>
<div class="conclusion-item" v-if="moduleVisibility.three">
<h4 class="conclusion-title">{{ displayedTitles.three }}</h4>
<p class="conclusion-text">{{ displayedTexts.three }}</p>
</div>
<div class="conclusion-item" v-if="getStockConclusion(stock).four">
<h4 class="conclusion-title">L4: 情绪套利</h4>
<p class="conclusion-text">{{ getStockConclusion(stock).four }}</p>
<div class="conclusion-item" v-if="moduleVisibility.four">
<h4 class="conclusion-title">{{ displayedTitles.four }}</h4>
<p class="conclusion-text">{{ displayedTexts.four }}</p>
</div>
<!-- AI生成内容免责声明 -->
<div class="disclaimer-item" v-if="getStockConclusion(stock)">
<p class="disclaimer-text">该内容由AI生成请注意甄别</p>
<div class="disclaimer-item" v-if="moduleVisibility.disclaimer">
<p class="disclaimer-text">{{ displayedTexts.disclaimer }}</p>
</div>
</div>
<div class="conclusion-placeholder" v-else>
@ -212,6 +214,7 @@ import { Howl, Howler } from 'howler'; // 导入音频播放库
import { reactive } from 'vue';
import { marked } from 'marked'; // marked
import { useUserStore } from "../store/userPessionCode";
const APIurl = import.meta.env.VITE_APP_API_BASE_URL;
// 使Pinia store
const emotionStore = useEmotionStore();
@ -224,12 +227,26 @@ const toggleVoiceForUser = () => {
emotionAudioStore.toggleVoice();
} else {
// /
if (emotionAudioStore.currentAudioUrl || emotionAudioStore.ttsUrl) {
// /
if (emotionAudioStore.isPlaying) {
//
emotionAudioStore.togglePlayPause();
} else {
//
emotionAudioStore.toggleVoice();
//
if (emotionAudioStore.isPaused && (emotionAudioStore.currentAudioUrl || emotionAudioStore.ttsUrl)) {
//
console.log('从暂停状态继续播放');
emotionAudioStore.togglePlayPause();
} else if (parsedConclusion.value && (parsedConclusion.value.one1_url || parsedConclusion.value.two_url || parsedConclusion.value.three_url || parsedConclusion.value.four_url)) {
//
console.log('用户点击播放,重新播放音频队列');
playAudioQueue(parsedConclusion.value, false); //
} else if (emotionAudioStore.currentAudioUrl || emotionAudioStore.ttsUrl) {
// URL/
emotionAudioStore.togglePlayPause();
} else {
//
emotionAudioStore.toggleVoice();
}
}
}
};
@ -444,6 +461,13 @@ const currentConclusion = computed(() => {
});
const parsedConclusion = computed(() => {
if (!currentConclusion.value) return null;
// conclusionData
if (typeof currentConclusion.value === 'object') {
return currentConclusion.value;
}
// JSON
try {
return JSON.parse(currentConclusion.value);
} catch (error) {
@ -488,6 +512,13 @@ const getStockData2 = (stock) => {
//
const getStockConclusion = (stock) => {
if (!stock?.conclusionData) return null;
// conclusionData
if (typeof stock.conclusionData === 'object') {
return stock.conclusionData;
}
// JSON
try {
return JSON.parse(stock.conclusionData);
} catch (error) {
@ -578,7 +609,10 @@ watch(currentStock, (newStock) => {
//
if (newStock.conclusionData) {
try {
const conclusion = JSON.parse(newStock.conclusionData);
// conclusionData使JSON
const conclusion = typeof newStock.conclusionData === 'object'
? newStock.conclusionData
: JSON.parse(newStock.conclusionData);
displayedTexts.value = {
one1: conclusion.one1 || '',
one2: conclusion.one2 || '',
@ -604,7 +638,18 @@ watch(currentStock, (newStock) => {
// URL
let voiceUrl = null;
if (conclusion.url) {
// 使one1_urlURL
if (conclusion.one1_url) {
voiceUrl = conclusion.one1_url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.one2_url) {
voiceUrl = conclusion.one2_url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.two_url) {
voiceUrl = conclusion.two_url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.three_url) {
voiceUrl = conclusion.three_url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.four_url) {
voiceUrl = conclusion.four_url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.url) {
voiceUrl = conclusion.url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.audioUrl) {
voiceUrl = conclusion.audioUrl.toString().trim().replace(/[`\s]/g, '');
@ -624,7 +669,7 @@ watch(currentStock, (newStock) => {
//
}
} catch (error) {
console.error('解析结论数据失败:', error);
console.error('解析股票结论数据失败:', error);
}
}
} else {
@ -654,9 +699,23 @@ watch(currentStock, (newStock) => {
// 使URL便
if (newStock.conclusionData) {
try {
const conclusion = JSON.parse(newStock.conclusionData);
// conclusionData使JSON
const conclusion = typeof newStock.conclusionData === 'object'
? newStock.conclusionData
: JSON.parse(newStock.conclusionData);
let voiceUrl = null;
if (conclusion.url) {
// 使one1_urlURL
if (conclusion.one1_url) {
voiceUrl = conclusion.one1_url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.one2_url) {
voiceUrl = conclusion.one2_url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.two_url) {
voiceUrl = conclusion.two_url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.three_url) {
voiceUrl = conclusion.three_url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.four_url) {
voiceUrl = conclusion.four_url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.url) {
voiceUrl = conclusion.url.toString().trim().replace(/[`\s]/g, '');
} else if (conclusion.audioUrl) {
voiceUrl = conclusion.audioUrl.toString().trim().replace(/[`\s]/g, '');
@ -675,7 +734,7 @@ watch(currentStock, (newStock) => {
emotionAudioStore.setCurrentAudioUrl(voiceUrl);
}
} catch (error) {
console.error('解析结论数据失败:', error);
console.error('解析股票结论数据失败:', error);
}
}
}
@ -710,12 +769,13 @@ watch(currentStock, (newStock) => {
hasTriggeredTypewriter.value = true;
hasTriggeredAudio.value = true;
startTypewriterEffect(parsedConclusion.value);
if (!stockAudioPlayed.value.has(stockCode)) {
console.log('开始音频播放');
console.log('开始音频播放和打字机效果');
stockAudioPlayed.value.set(stockCode, true);
playAudio(audioUrl.value);
playAudioQueue(parsedConclusion.value, true);
} else {
//
startTypewriterEffect(parsedConclusion.value);
}
stockTypewriterShown.value.set(stockCode, true);
@ -777,9 +837,19 @@ watch(parsedConclusion, (newConclusion) => {
console.log('场景应用结论数据:', newConclusion);
//
// URL
// URL使
let voiceUrl = null;
if (newConclusion.url) {
if (newConclusion.one1_url) {
voiceUrl = newConclusion.one1_url.toString().trim().replace(/[`\s]/g, '');
} else if (newConclusion.one2_url) {
voiceUrl = newConclusion.one2_url.toString().trim().replace(/[`\s]/g, '');
} else if (newConclusion.two_url) {
voiceUrl = newConclusion.two_url.toString().trim().replace(/[`\s]/g, '');
} else if (newConclusion.three_url) {
voiceUrl = newConclusion.three_url.toString().trim().replace(/[`\s]/g, '');
} else if (newConclusion.four_url) {
voiceUrl = newConclusion.four_url.toString().trim().replace(/[`\s]/g, '');
} else if (newConclusion.url) {
// URL
voiceUrl = newConclusion.url.toString().trim().replace(/[`\s]/g, '');
} else if (newConclusion.audioUrl) {
@ -966,7 +1036,258 @@ function clearTypewriterTimers() {
typewriterTimers.value = [];
}
//
//
const audioQueue = ref([]);
const isPlayingQueueAudio = ref(false);
let currentPlayIndex = 0;
let isCallingPlayNext = false;
//
const audioQueueOrder = {
"one1_url": 1,
"one2_url": 2,
"two_url": 3,
"three_url": 4,
"four_url": 5,
"url": 6,
"audioUrl": 7,
"voice_url": 8,
"audio": 9,
"tts_url": 10
};
//
const playNextAudio = () => {
console.log("=== playNextAudio 被调用 ===");
console.log("当前队列状态:", {
queueLength: audioQueue.value.length,
queueItems: audioQueue.value.map((item) => item.name),
currentPlayIndex: currentPlayIndex,
isPlayingQueueAudio: isPlayingQueueAudio.value,
isCallingPlayNext: isCallingPlayNext,
audioStoreIsPlaying: emotionAudioStore.isPlaying,
});
if (
audioQueue.value.length === 0 ||
isPlayingQueueAudio.value ||
isCallingPlayNext
) {
console.log("❌ 播放条件不满足 - 队列长度:", audioQueue.value.length, "正在播放:", isPlayingQueueAudio.value, "正在调用:", isCallingPlayNext);
return;
}
//
if (currentPlayIndex >= audioQueue.value.length && audioQueue.value.length > 0) {
console.log("🔄 所有音频播放完成,重置索引从第一个开始");
currentPlayIndex = 0;
isCallingPlayNext = false; //
}
isCallingPlayNext = true;
isPlayingQueueAudio.value = true;
const audioInfo = audioQueue.value[currentPlayIndex];
console.log(`✅ 开始播放${audioInfo.name}音频 (索引:${currentPlayIndex}),队列总长度:`, audioQueue.value.length);
//
if (emotionAudioStore.nowSound && emotionAudioStore.nowSound.playing()) {
emotionAudioStore.nowSound.stop();
}
//
const audio = new Howl({
src: [audioInfo.url],
html5: true,
format: ['mp3', 'wav'],
onplay: () => {
isAudioPlaying.value = true;
isPlayingQueueAudio.value = true;
emotionAudioStore.isPlaying = true;
console.log(`开始播放${audioInfo.name}音频`);
//
if (currentPlayIndex === 0 && audioInfo.shouldStartTypewriter && parsedConclusion.value) {
console.log('🎬 第一个音频开始播放,同时启动打字机效果');
startTypewriterEffect(parsedConclusion.value, audioInfo.onComplete);
}
},
onpause: () => {
emotionAudioStore.isPaused = true;
console.log(`${audioInfo.name}音频暂停播放`);
},
onresume: () => {
emotionAudioStore.isPaused = false;
console.log(`${audioInfo.name}音频继续播放`);
},
onend: () => {
console.log(`${audioInfo.name}音频播放完成,准备播放下一个`);
emotionAudioStore.isPlaying = false;
emotionAudioStore.isPaused = false;
emotionAudioStore.playbackPosition = 0;
isAudioPlaying.value = false;
isPlayingQueueAudio.value = false;
//
currentPlayIndex++;
//
if (currentPlayIndex < audioQueue.value.length) {
console.log(`队列中还有音频,500ms后播放下一个 (索引:${currentPlayIndex})`);
setTimeout(() => {
isCallingPlayNext = false;
playNextAudio();
}, 500);
} else {
console.log("🎉 所有音频播放完成");
emotionAudioStore.nowSound = null;
isCallingPlayNext = false;
}
},
onstop: () => {
console.log(`${audioInfo.name}音频被停止`);
emotionAudioStore.isPlaying = false;
emotionAudioStore.isPaused = false;
emotionAudioStore.playbackPosition = 0;
isAudioPlaying.value = false;
isPlayingQueueAudio.value = false;
},
onerror: (error) => {
console.error(`${audioInfo.name}音频播放失败:`, error);
isAudioPlaying.value = false;
isPlayingQueueAudio.value = false;
isCallingPlayNext = false;
//
setTimeout(() => {
playNextAudio();
}, 100);
},
onload: () => {
emotionAudioStore.duration = audio.duration();
console.log(`${audioInfo.name}音频加载完成,时长:`, emotionAudioStore.duration);
}
});
// URLstore
emotionAudioStore.setCurrentAudioUrl(audioInfo.url);
emotionAudioStore.nowSound = audio;
emotionAudioStore.setAudioInstance(audio);
console.log(`尝试播放${audioInfo.name}音频`);
audio.play();
};
//
const addToAudioQueue = (url, name, shouldStartTypewriter = false, onComplete = null) => {
console.log(`=== 添加音频到队列 ===`);
console.log("URL:", url);
console.log("Name:", name);
console.log("是否启动打字机效果:", shouldStartTypewriter);
console.log("音频启用状态:", emotionAudioStore.isVoiceEnabled);
if (url && emotionAudioStore.isVoiceEnabled) {
const audioItem = {
url,
name,
order: audioQueueOrder[name] || 999,
shouldStartTypewriter, //
onComplete, //
};
audioQueue.value.push(audioItem);
//
audioQueue.value.sort((a, b) => a.order - b.order);
console.log(`音频${name}已添加到播放队列,顺序:${audioItem.order}`);
console.log("当前队列顺序:", audioQueue.value.map((item) => `${item.name}(${item.order})`));
//
if (!isPlayingQueueAudio.value && !emotionAudioStore.isPlaying && audioQueue.value.length === 1) {
console.log("✅ 条件满足:没有音频在播放且这是第一个音频,立即开始播放");
playNextAudio();
} else {
console.log("⏳ 等待条件:", {
isPlayingQueueAudio: isPlayingQueueAudio.value,
audioStoreIsPlaying: emotionAudioStore.isPlaying,
queueLength: audioQueue.value.length,
reason: audioQueue.value.length > 1 ? "队列中已有其他音频" : "有音频正在播放",
});
}
} else {
console.log("❌ 跳过添加音频:", {
hasUrl: !!url,
voiceEnabled: emotionAudioStore.isVoiceEnabled,
});
}
};
// -
function playAudioQueue(conclusionData, shouldStartTypewriter = false, onComplete = null) {
if (!conclusionData) {
console.log('没有结论数据,跳过播放');
return;
}
//
console.log('语音功能状态:', emotionAudioStore.isVoiceEnabled);
if (!emotionAudioStore.isVoiceEnabled) {
console.log('语音功能已关闭,跳过播放');
return;
}
console.log('开始处理多音频播放...', shouldStartTypewriter ? '同时启动打字机效果' : '');
try {
//
const conclusion = typeof conclusionData === 'object' ? conclusionData : JSON.parse(conclusionData);
//
audioQueue.value = [];
currentPlayIndex = 0;
isCallingPlayNext = false;
isPlayingQueueAudio.value = false;
// URL
const audioSources = [
{ key: 'one1_url', name: 'one1_url' },
{ key: 'one2_url', name: 'one2_url' },
{ key: 'two_url', name: 'two_url' },
{ key: 'three_url', name: 'three_url' },
{ key: 'four_url', name: 'four_url' },
{ key: 'url', name: 'url' },
{ key: 'audioUrl', name: 'audioUrl' },
{ key: 'voice_url', name: 'voice_url' },
{ key: 'audio', name: 'audio' },
{ key: 'tts_url', name: 'tts_url' }
];
audioSources.forEach(source => {
if (conclusion[source.key]) {
const voiceUrl = conclusion[source.key].toString().trim().replace(/[`\s]/g, '');
if (voiceUrl && voiceUrl.startsWith('http')) {
console.log(`找到音频URL: ${source.name} = ${voiceUrl}`);
addToAudioQueue(voiceUrl, source.name, shouldStartTypewriter && audioQueue.value.length === 0, onComplete);
}
}
});
if (audioQueue.value.length === 0) {
console.log('未找到有效的音频URL');
//
if (shouldStartTypewriter) {
console.log('没有音频但需要启动打字机效果');
startTypewriterEffect(conclusion, onComplete);
}
} else {
console.log(`总共找到 ${audioQueue.value.length} 个音频,准备播放`);
}
} catch (error) {
console.error('处理音频播放失败:', error);
}
}
//
function playAudio(url) {
console.log('尝试播放音频:', url);
@ -1217,37 +1538,35 @@ async function handleSendMessage(input, onComplete) {
//
const thinkingMessageRef = await showThinkingProcess();
let thinkingMessage3Ref = null;
try {
//
const params = {
content: userMessage.text,
userData: {
token: localStorage.getItem('localToken'),
language: "cn",
// brainPrivilegeState: userStore.brainPerssion,
// swordPrivilegeState: userStore.swordPerssion,
// stockForecastPrivilegeState: userStore.pricePerssion,
// spaceForecastPrivilegeState: userStore.timePerssion,
// aibullPrivilegeState: userStore.aibullPerssion,
// aigoldBullPrivilegeState: userStore.aiGnbullPerssion,
// airadarPrivilegeState: userStore.airadarPerssion,
// marketList: userStore.aiGoldMarketList,
brainPrivilegeState: '1',
swordPrivilegeState: '1',
stockForecastPrivilegeState: '1',
spaceForecastPrivilegeState: '1',
aibullPrivilegeState: '1',
aigoldBullPrivilegeState: '1',
airadarPrivilegeState: '1',
marketList: "hk,cn,usa,my,sg,vi,in,gb",
},
};
const result = await getReplyAPI(params);
const response = await result.json();
const parsedData = JSON.parse(response.data);
// const params = {
// content: userMessage.text,
// userData: {
// token: localStorage.getItem('localToken'),
// language: "cn",
// brainPrivilegeState: '1',
// swordPrivilegeState: '1',
// stockForecastPrivilegeState: '1',
// spaceForecastPrivilegeState: '1',
// aibullPrivilegeState: '1',
// aigoldBullPrivilegeState: '1',
// airadarPrivilegeState: '1',
// marketList: "hk,cn,usa,my,sg,vi,in,gb",
// },
// };
const result = await getReplyAPI({
"token": localStorage.getItem("localToken"),
"language": "cn",
"marketList": "hk,cn,usa,my,sg,vi,in,gb",
"content": userMessage.text
});
const response = result;
const parsedData = response.data;
console.log('第一个接口返回的完整数据:', parsedData);
//
if (!parsedData || !parsedData.market || !parsedData.code) {
//
@ -1283,11 +1602,9 @@ async function handleSendMessage(input, onComplete) {
//
//
let thinkingMessage3Ref = null;
if (thinkingMessageRef && parsedData.name) {
thinkingMessage3Ref = await continueThinkingProcess(thinkingMessageRef, parsedData.name);
}
//
// isLoading.value = true;
@ -1295,24 +1612,22 @@ async function handleSendMessage(input, onComplete) {
//
const conclusionParams = {
content: input.trim(),
userData: {
token: localStorage.getItem('localToken'),
language: "cn",
marketList: "hk,cn,usa,my,sg,vi,in,gb",
},
code: parsedData.code,
market: parsedData.market,
recordId: parsedData.recordId,
parentId: parsedData.parentId,
stockId: parsedData.stockId,
token: localStorage.getItem('localToken'),
language: "cn",
};
console.log('第二个接口参数:', conclusionParams);
// fetchData
const [conclusionResult, fetchDataResult] = await Promise.all([
getConclusionAPI(conclusionParams),
fetchData(parsedData.code, parsedData.market, parsedData.name || "未知股票", input.trim())
fetchData(parsedData.code, parsedData.market, parsedData.name || "未知股票", input.trim(), parsedData.stockId)
]);
//
const conclusionResponse = await conclusionResult.json();
const conclusionResponse = conclusionResult;
//
if (conclusionResponse && conclusionResponse.data && fetchDataResult) {
//
@ -1322,6 +1637,7 @@ async function handleSendMessage(input, onComplete) {
// store
conclusionData.value = conclusionResponse.data;
console.log('第二个接口返回的完整数据结构:', conclusionResponse.data);
// store
emotionStore.updateActiveStockConclusion(conclusionResponse.data);
@ -1347,11 +1663,12 @@ async function handleSendMessage(input, onComplete) {
if (isUserInitiated.value && parsedConclusion.value && audioUrl.value) {
const stockCode = currentStock.value.stockInfo?.code || currentStock.value.stockInfo?.symbol;
if (stockCode && !stockTypewriterShown.value.has(stockCode)) {
startTypewriterEffect(parsedConclusion.value, onComplete);
if (!stockAudioPlayed.value.has(stockCode)) {
stockAudioPlayed.value.set(stockCode, true);
playAudio(audioUrl.value);
playAudioQueue(parsedConclusion.value, true, onComplete);
} else {
//
startTypewriterEffect(parsedConclusion.value, onComplete);
}
stockTypewriterShown.value.set(stockCode, true);
} else {
@ -1382,7 +1699,7 @@ async function handleSendMessage(input, onComplete) {
// fetchDataResult false fetchData messages
// conclusionResponse
if (!conclusionResponse || !conclusionResponse.data) {
const aiMessage = reactive({ sender: 'ai', text: '数据加载失败,请重试' });
const aiMessage = reactive({ sender: 'ai', text: '网络加载失败,请重试' });
messages.value.push(aiMessage);
}
isRotating.value = false;
@ -1467,23 +1784,17 @@ async function handleSendMessage(input, onComplete) {
//
async function fetchData(code, market, stockName, queryText) {
async function fetchData(code, market, stockName, queryText, stockId) {
try {
const stockDataParams = {
// token: '+XgqsgdW0RLIbIG2pxnnbZi0+fEeMx8pywnIlrmTxtkSaPZ9xjSOWrxq+s0rL3RrfNhXPvGtz9srFfjwu8A',
token: localStorage.getItem('localToken'),
market: market,
code: code,
language: 'cn',
version: version1.value
"stockId": stockId
};
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',
`${APIurl}/api/workflow/getStockData`,
stockDataParams,
{
headers: {
headers: {
"Content-Type": "application/json",
},
}
@ -2150,9 +2461,36 @@ onMounted(async () => {
console.log('恢复图表数据:', currentStockData.stockInfo.name);
renderCharts(currentStockData.apiData);
//
//
if (currentStockData.conclusionData) {
conclusionData.value = currentStockData.conclusionData;
// 使
const conclusion = currentStockData.conclusionData;
displayedTexts.value = {
one1: conclusion.one1 || '',
one2: conclusion.one2 || '',
two: conclusion.two || '',
three: conclusion.three || '',
four: conclusion.four || '',
disclaimer: '该内容由AI生成,请注意甄别'
};
displayedTitles.value = {
one: conclusion.one1 || conclusion.one2 ? 'L1: 情绪监控' : '',
two: conclusion.two ? 'L2: 情绪解码' : '',
three: conclusion.three ? 'L3: 情绪推演' : '',
four: conclusion.four ? 'L4: 情绪套利' : ''
};
moduleVisibility.value = {
one: !!(conclusion.one1 || conclusion.one2),
two: !!conclusion.two,
three: !!conclusion.three,
four: !!conclusion.four,
disclaimer: true
};
//
const stockCode = currentStockData.stockInfo?.code || currentStockData.stockInfo?.symbol;
if (stockCode) {

4
src/views/components/HistoryRecord.vue

@ -16,7 +16,7 @@
<img
class="collapsed-toggle-btn"
@click="openHistory"
src=" https://d31zlh4on95l9h.cloudfront.net/images/b2d784f8607ab65081f5289459581bfe.png"
src="https://d31zlh4on95l9h.cloudfront.net/images/b2d784f8607ab65081f5289459581bfe.png"
alt="icon"
/>
</div>
@ -54,7 +54,7 @@
<img
class="toggle-btn"
@click="closeHistory"
src=" https://d31zlh4on95l9h.cloudfront.net/images/b2d784f8607ab65081f5289459581bfe.png"
src="https://d31zlh4on95l9h.cloudfront.net/images/b2d784f8607ab65081f5289459581bfe.png"
alt="icon"
/>
</div>

Loading…
Cancel
Save