Browse Source

音频差重复播放

master^2
no99 4 days ago
parent
commit
229403829c
  1. 6
      src/store/chat.js
  2. 620
      src/views/AIchat.vue
  3. 12
      src/views/Announcement.vue
  4. 2
      src/views/Selectmodel.vue
  5. 104
      src/views/components/HistoryRecord.vue
  6. 35
      src/views/homePage.vue

6
src/store/chat.js

@ -7,8 +7,10 @@ export const useChatStore = defineStore("chat", {
UserCount: 0, UserCount: 0,
chartData: [], chartData: [],
kLineData: [], kLineData: [],
dbqbClickRecord:{},
dbqbClickRecord: {},
searchRecord: false,
currentUserIndex: null,
announcementMsg: null,
}), }),
actions: { actions: {
async getUserCount() { async getUserCount() {

620
src/views/AIchat.vue

@ -1,6 +1,6 @@
<script setup> <script setup>
import { ref, onMounted, watch, nextTick, reactive, onUnmounted } from "vue"; import { ref, onMounted, watch, nextTick, reactive, onUnmounted } from "vue";
import { ElDialog } from "element-plus";
import { ElDialog, ElMessage } from "element-plus";
import { import {
getReplyStreamAPI, getReplyStreamAPI,
getReplyAPI, getReplyAPI,
@ -37,21 +37,248 @@ const chatStore = useChatStore();
const audioStore = useAudioStore(); const audioStore = useAudioStore();
const dataStore = useDataStore(); const dataStore = useDataStore();
//
const audioQueue = ref([]);
const isPlayingAudio = ref(false);
let currentPlayIndex = 0;
let isCallingPlayNext = false;
//
const audioPreloadStatus = {
one: { loaded: false, url: null },
two: { loaded: false, url: null },
three: { loaded: false, url: null },
four: { loaded: false, url: null },
};
//
const audioQueueOrder = {
"API1-第一个": 1,
"API2-第二个": 2,
"API3-第三个": 3,
"API4-第四个": 4,
};
//
const playNextAudio = () => {
if (isCallingPlayNext) {
console.log("playNextAudio已在执行中,跳过重复调用");
return;
}
if (currentPlayIndex >= audioQueue.value.length) {
console.log("所有音频播放完成");
isPlayingAudio.value = false;
return;
}
isCallingPlayNext = true;
const audioInfo = audioQueue.value[currentPlayIndex];
if (!audioInfo || !audioInfo.url) {
console.warn(`音频信息无效,跳过索引 ${currentPlayIndex}`);
currentPlayIndex++;
isCallingPlayNext = false;
playNextAudio();
return;
}
console.log(`开始播放 ${audioInfo.name},索引: ${currentPlayIndex}`);
const audio = new Howl({
src: [audioInfo.url],
html5: true,
format: ["mp3", "acc"],
rate: 1.2,
retryCount: 0,
onplay: () => {
audioStore.isPlaying = true;
isPlayingAudio.value = true;
isCallingPlayNext = false;
console.log(`${audioInfo.name}音频开始播放`);
},
onpause: () => {
audioStore.isPlaying = false;
audioStore.isPaused = true;
audioStore.playbackPosition = audio.seek() || 0;
console.log(`${audioInfo.name}音频已暂停`);
},
onresume: () => {
audioStore.isPlaying = true;
audioStore.isPaused = false;
console.log(`${audioInfo.name}音频继续播放`);
},
onend: () => {
console.log(`${audioInfo.name}音频播放完成,准备播放下一个`);
audioStore.isPlaying = false;
audioStore.isPaused = false;
audioStore.playbackPosition = 0;
isPlayingAudio.value = false;
currentPlayIndex++;
console.log(
"currentPlayIndex",
currentPlayIndex,
"audioQueue.value.length",
audioQueue.value.length
);
if (currentPlayIndex < audioQueue.value.length) {
console.log(
`队列中还有音频,500ms后播放下一个 (索引:${currentPlayIndex})`
);
setTimeout(() => {
isCallingPlayNext = false;
playNextAudio();
}, 500);
} else {
console.log("🎉 所有音频播放完成,清除音频实例");
chatStore.messages[chatStore.currentUserIndex].audioStatus = false;
audioStore.nowSound = null;
audioStore.soundInstance = null;
// currentPlayIndex = 0;
isCallingPlayNext = false;
}
},
onstop: () => {
console.log(`${audioInfo.name}音频被停止`);
audioStore.isPlaying = false;
audioStore.isPaused = false;
audioStore.playbackPosition = 0;
},
onloaderror: (id, err) => {
console.error(`${audioInfo.name}音频播放失败:`, err);
isPlayingAudio.value = false;
isCallingPlayNext = false;
setTimeout(() => {
playNextAudio();
}, 100);
},
});
audioStore.setCurrentAudioUrl(audioInfo.url);
audioStore.nowSound = audio;
audioStore.setAudioInstance(audio);
console.log(`尝试播放${audioInfo.name}音频`);
audio.play();
};
//
const addToAudioQueue = (url, name) => {
console.log(`=== 添加音频到队列 ===`);
console.log("URL:", url);
console.log("Name:", name);
console.log("音频启用状态:", audioStore.isVoiceEnabled);
if (url && audioStore.isVoiceEnabled) {
const audioItem = {
url,
name,
order: audioQueueOrder[name] || 999,
};
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 (
!isPlayingAudio.value &&
!audioStore.isPlaying &&
audioQueue.value.length === 1
) {
console.log("✅ 条件满足:没有音频在播放且这是第一个音频,立即开始播放");
playNextAudio();
} else {
console.log("⏳ 等待条件:", {
isPlayingAudio: isPlayingAudio.value,
audioStoreIsPlaying: audioStore.isPlaying,
queueLength: audioQueue.value.length,
reason:
audioQueue.value.length > 1 ? "队列中已有其他音频" : "有音频正在播放",
});
}
} else {
console.log("❌ 跳过添加音频:", {
hasUrl: !!url,
voiceEnabled: audioStore.isVoiceEnabled,
});
}
console.log(`=== 添加音频完成 ===`);
};
// //
const toggleVoiceForUser = () => {
const toggleVoiceForUser = (index) => {
console.log(
"上一个按钮坐标",
chatStore.currentUserIndex,
"当前按钮坐标",
index
);
if (
!chatStore.messages[index].audioArray[0] ||
!chatStore.messages[index].audioArray[1] ||
!chatStore.messages[index].audioArray[2] ||
!chatStore.messages[index].audioArray[3]
) {
return;
}
//
chatStore.messages[index].audioStatus =
!chatStore.messages[index].audioStatus;
//
if (chatStore.currentUserIndex != index) {
if (chatStore.currentUserIndex != null) {
audioStore.togglePlayPause();
chatStore.messages[chatStore.currentUserIndex].audioStatus = false;
}
audioPreloadStatus.one = { loaded: false, url: null };
audioPreloadStatus.two = { loaded: false, url: null };
audioPreloadStatus.three = { loaded: false, url: null };
audioPreloadStatus.four = { loaded: false, url: null };
chatStore.currentUserIndex = index;
audioQueue.value = [];
isPlayingAudio.value = false;
audioStore.soundInstance = null;
currentPlayIndex = 0;
isCallingPlayNext = false;
addToAudioQueue(chatStore.messages[index].audioArray[0], "API1-第一个");
addToAudioQueue(chatStore.messages[index].audioArray[1], "API2-第二个");
addToAudioQueue(chatStore.messages[index].audioArray[2], "API3-第三个");
addToAudioQueue(chatStore.messages[index].audioArray[3], "API4-第四个");
if (!audioStore.isVoiceEnabled) { if (!audioStore.isVoiceEnabled) {
//
audioStore.toggleVoice(); audioStore.toggleVoice();
} else { } else {
// /
if (audioStore.currentAudioUrl || audioStore.ttsUrl) { if (audioStore.currentAudioUrl || audioStore.ttsUrl) {
// /
audioStore.togglePlayPause(); audioStore.togglePlayPause();
} else { } else {
//
audioStore.toggleVoice(); audioStore.toggleVoice();
} }
} }
} else {
if (!audioStore.isVoiceEnabled) {
console.log("1111");
audioStore.toggleVoice();
} else {
if (audioStore.currentAudioUrl || audioStore.ttsUrl) {
console.log("2222");
audioStore.togglePlayPause();
} else {
console.log("3333");
audioStore.toggleVoice();
}
}
}
}; };
// //
@ -82,11 +309,6 @@ const playAudio = (url) => {
} }
const handlePlay = () => { const handlePlay = () => {
// if (audioStore.soundInstance) {
// Howler.unload(); //
// // audioStore.soundInstance.stop()
// }
if (audioStore.isNewInstance) { if (audioStore.isNewInstance) {
const newSound = new Howl({ const newSound = new Howl({
src: [url], src: [url],
@ -142,22 +364,9 @@ const playAudio = (url) => {
// //
const pauseAudio = () => { const pauseAudio = () => {
if (audioStore.soundInstance) { if (audioStore.soundInstance) {
//
// if (/iPhone|iPad|iPod/.test(navigator.userAgent)) {
// Howler.pause(); // iOS
// } else {
// audioStore.soundInstance.pause();
// }
audioStore.soundInstance.pause(); audioStore.soundInstance.pause();
audioStore.isPlaying = false; audioStore.isPlaying = false;
// //
// nextTick(() => {
// Howler.unload();
// audioStore.soundInstance = null;
// });
} }
}; };
@ -486,6 +695,8 @@ const createTypingEffect = (message, content, speed) => {
if (message.end) { if (message.end) {
chatStore.getUserCount(); chatStore.getUserCount();
chatStore.isLoading = false; chatStore.isLoading = false;
chatStore.searchRecord = true;
console.log("打印完毕,接触输入框禁用状态");
emit("enableInput"); emit("enableInput");
} }
message.isTyping = false; message.isTyping = false;
@ -794,10 +1005,6 @@ const previousMessagesLength = ref(0);
watch( watch(
() => props.messages, () => props.messages,
async (newVal, oldVal) => { async (newVal, oldVal) => {
// console.log(newVal, 'newVal')
// console.log(oldVal, 'oldVal')
// console.log(previousMessagesLength.value, 'previousMessagesLength')
// console.log(newVal.length, 'newVal.length')
// // // //
if (!newVal?.length || newVal === previousMessagesLength.value) return; if (!newVal?.length || newVal === previousMessagesLength.value) return;
@ -805,10 +1012,13 @@ watch(
if (newVal.length > 0) { if (newVal.length > 0) {
console.log("消息列表已更新,最新消息:", newVal[newVal.length - 1]); console.log("消息列表已更新,最新消息:", newVal[newVal.length - 1]);
chatStore.messages.push(newVal[newVal.length - 1]); chatStore.messages.push(newVal[newVal.length - 1]);
console.log("消息列表已更新,最新消息:", chatMsg[chatMsg.length - 1]);
console.log("token", localStorage.getItem("localToken"));
chatStore.currentUserIndex = chatStore.messages.length - 1;
console.log(
"消息列表已更新,最新消息:",
chatStore.messages[chatStore.messages.length - 1],
"最新用户坐标",
chatStore.currentUserIndex
);
// //
const userStore = useUserStore(); const userStore = useUserStore();
@ -1010,265 +1220,12 @@ watch(
}, },
}; };
//
const audioPreloadStatus = {
one: { loaded: false, url: null },
two: { loaded: false, url: null },
three: { loaded: false, url: null },
four: { loaded: false, url: null },
};
//
const audioQueue = ref([]);
const isPlayingAudio = ref(false);
//
//
let isCallingPlayNext = false;
//
let currentPlayIndex = 0;
const playNextAudio = () => {
console.log("=== playNextAudio 被调用 ===");
console.log("当前队列状态:", {
queueLength: audioQueue.value.length,
queueItems: audioQueue.value.map((item) => item.name),
currentPlayIndex: currentPlayIndex,
isPlayingAudio: isPlayingAudio.value,
isCallingPlayNext: isCallingPlayNext,
audioStoreIsPlaying: audioStore.isPlaying,
});
if (
audioQueue.value.length === 0 ||
isPlayingAudio.value ||
isCallingPlayNext
) {
console.log(
"❌ 播放条件不满足 - 队列长度:",
audioQueue.value.length,
"正在播放:",
isPlayingAudio.value,
"正在调用:",
isCallingPlayNext
);
return;
}
//
if (
currentPlayIndex >= audioQueue.value.length &&
audioQueue.value.length > 0
) {
console.log("🔄 所有音频播放完成,重置索引从第一个开始");
currentPlayIndex = 0;
}
isCallingPlayNext = true;
isPlayingAudio.value = true;
const audioInfo = audioQueue.value[currentPlayIndex];
console.log(
`✅ 开始播放${audioInfo.name}音频 (索引:${currentPlayIndex}),队列总长度:`,
audioQueue.value.length
);
console.log(
"完整队列内容:",
audioQueue.value.map(
(item, index) =>
`${index === currentPlayIndex ? "▶️" : "⏸️"} ${item.name}`
)
);
//
if (
audioStore.nowSound &&
(audioStore.nowSound.playing() ||
audioStore.nowSound.state() === "loading")
) {
console.log("停止之前的音频实例");
audioStore.nowSound.stop();
}
const audio = new Howl({
src: [audioInfo.url],
html5: true,
format: ["mp3", "acc"],
rate: 1.2,
onplay: () => {
audioStore.isPlaying = true;
audioStore.isPaused = false;
isPlayingAudio.value = true; //
isCallingPlayNext = false; //
console.log(
`${audioInfo.name}音频开始播放,时长:`,
audio.duration()
);
console.log(
"音频播放状态确认 - isPlayingAudio:",
isPlayingAudio.value,
"audioStore.isPlaying:",
audioStore.isPlaying
);
},
onpause: () => {
audioStore.isPlaying = false;
audioStore.isPaused = true;
audioStore.playbackPosition = audio.seek() || 0;
console.log(
`${audioInfo.name}音频已暂停,位置:`,
audioStore.playbackPosition
);
},
onresume: () => {
audioStore.isPlaying = true;
audioStore.isPaused = false;
console.log(`${audioInfo.name}音频继续播放`);
},
onend: () => {
console.log(`${audioInfo.name}音频播放完成,准备播放下一个`);
console.log(
"播放完成时的状态 - 当前索引:",
currentPlayIndex,
"队列长度:",
audioQueue.value.length,
"isPlayingAudio:",
isPlayingAudio.value
);
audioStore.isPlaying = false;
audioStore.isPaused = false;
audioStore.playbackPosition = 0;
isPlayingAudio.value = false;
//
currentPlayIndex++;
//
if (currentPlayIndex < audioQueue.value.length) {
console.log(
`队列中还有音频,500ms后播放下一个 (索引:${currentPlayIndex}),当前队列:`,
audioQueue.value.map(
(item, index) =>
`${index === currentPlayIndex ? "▶️" : "⏸️"} ${
item.name
}`
)
);
setTimeout(() => {
isCallingPlayNext = false; //
playNextAudio();
}, 500);
} else {
console.log(
"🎉 所有音频播放完成,清除音频实例,队列保持完整,下次播放将从第一个开始"
);
// 使
audioStore.nowSound = null;
audioStore.soundInstance = null;
isCallingPlayNext = false; //
}
},
onstop: () => {
console.log(`${audioInfo.name}音频被停止`);
audioStore.isPlaying = false;
audioStore.isPaused = false;
audioStore.playbackPosition = 0;
// onstopisPlayingAudio.value = false
},
onloaderror: (id, err) => {
console.error(`${audioInfo.name}音频播放失败:`, err);
isPlayingAudio.value = false;
isCallingPlayNext = false; //
//
setTimeout(() => {
playNextAudio();
}, 100);
},
});
// URLstore
audioStore.setCurrentAudioUrl(audioInfo.url);
audioStore.nowSound = audio;
audioStore.setAudioInstance(audio);
console.log(`尝试播放${audioInfo.name}音频`);
audio.play();
};
//
const audioQueueOrder = {
"API1-第一个": 1,
"API2-第二个": 2,
"API3-第三个": 3,
"API4-第四个": 4,
};
//
const addToAudioQueue = (url, name) => {
console.log(`=== 添加音频到队列 ===`);
console.log("URL:", url);
console.log("Name:", name);
console.log("音频启用状态:", audioStore.isVoiceEnabled);
if (url && audioStore.isVoiceEnabled) {
const audioItem = {
url,
name,
order: audioQueueOrder[name] || 999,
};
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})`)
);
console.log("当前播放状态详情:");
console.log(" - isPlayingAudio:", isPlayingAudio.value);
console.log(" - audioStore.isPlaying:", audioStore.isPlaying);
console.log(" - audioStore.nowSound:", audioStore.nowSound);
console.log(" - isCallingPlayNext:", isCallingPlayNext);
console.log(" - 队列长度:", audioQueue.value.length);
//
if (
!isPlayingAudio.value &&
!audioStore.isPlaying &&
audioQueue.value.length === 1
) {
console.log(
"✅ 条件满足:没有音频在播放且这是第一个音频,立即开始播放"
);
playNextAudio();
} else {
console.log("⏳ 等待条件:", {
isPlayingAudio: isPlayingAudio.value,
audioStoreIsPlaying: audioStore.isPlaying,
queueLength: audioQueue.value.length,
reason:
audioQueue.value.length > 1
? "队列中已有其他音频"
: "有音频正在播放",
});
}
} else {
console.log("❌ 跳过添加音频:", {
hasUrl: !!url,
voiceEnabled: audioStore.isVoiceEnabled,
});
}
console.log(`=== 添加音频完成 ===`);
};
//
// audioStoretogglePlayPause // audioStoretogglePlayPause
const originalTogglePlayPause = audioStore.togglePlayPause; const originalTogglePlayPause = audioStore.togglePlayPause;
audioStore.togglePlayPause = () => { audioStore.togglePlayPause = () => {
console.log("主页音频控制按钮被点击");
console.log("主页音频控制按钮被点击22222");
console.log( console.log(
"当前音频状态 - isPlaying:", "当前音频状态 - isPlaying:",
audioStore.isPlaying, audioStore.isPlaying,
@ -1484,6 +1441,9 @@ watch(
// API1 // API1
if (audioPreloadStatus.one.url) { if (audioPreloadStatus.one.url) {
chatStore.messages[
chatStore.currentUserIndex
].audioArray.push(audioPreloadStatus.one.url);
addToAudioQueue(audioPreloadStatus.one.url, "API1-第一个"); addToAudioQueue(audioPreloadStatus.one.url, "API1-第一个");
console.log( console.log(
"音频队列:添加API1音频,当前队列长度:", "音频队列:添加API1音频,当前队列长度:",
@ -1754,6 +1714,9 @@ watch(
// API2 // API2
if (audioPreloadStatus.two.url) { if (audioPreloadStatus.two.url) {
chatStore.messages[
chatStore.currentUserIndex
].audioArray.push(audioPreloadStatus.two.url);
addToAudioQueue(audioPreloadStatus.two.url, "API2-第二个"); addToAudioQueue(audioPreloadStatus.two.url, "API2-第二个");
console.log( console.log(
"音频队列:添加API2音频,当前队列长度:", "音频队列:添加API2音频,当前队列长度:",
@ -1855,6 +1818,9 @@ watch(
// API3 // API3
if (audioPreloadStatus.three.url) { if (audioPreloadStatus.three.url) {
chatStore.messages[
chatStore.currentUserIndex
].audioArray.push(audioPreloadStatus.three.url);
addToAudioQueue(audioPreloadStatus.three.url, "API3-第三个"); addToAudioQueue(audioPreloadStatus.three.url, "API3-第三个");
console.log( console.log(
"音频队列:添加API3音频,当前队列长度:", "音频队列:添加API3音频,当前队列长度:",
@ -2041,6 +2007,9 @@ watch(
// API4 // API4
if (audioPreloadStatus.four.url) { if (audioPreloadStatus.four.url) {
chatStore.messages[
chatStore.currentUserIndex
].audioArray.push(audioPreloadStatus.four.url);
addToAudioQueue(audioPreloadStatus.four.url, "API4-第四个"); addToAudioQueue(audioPreloadStatus.four.url, "API4-第四个");
console.log( console.log(
"音频队列:添加API4音频,当前队列长度:", "音频队列:添加API4音频,当前队列长度:",
@ -2366,7 +2335,7 @@ watch(
} }
} }
}, },
{ deep: true }
{ deep: false }
); );
// //
@ -2387,6 +2356,7 @@ watch(
console.log("dbqbClickRecord 已清空"); console.log("dbqbClickRecord 已清空");
}, 0); }, 0);
try {
// //
chatStore.messages = []; chatStore.messages = [];
@ -2394,6 +2364,13 @@ watch(
sender: "user", sender: "user",
timestamp: clickRecord.value.createdTime, timestamp: clickRecord.value.createdTime,
content: clickRecord.value.keyword, content: clickRecord.value.keyword,
audioArray: [
clickRecord.value.wokeFlowData.One.url,
clickRecord.value.wokeFlowData.Two.url,
clickRecord.value.wokeFlowData.Three.url,
clickRecord.value.wokeFlowData.Four.url,
],
audioStatus: true,
}); });
chatStore.messages.push({ chatStore.messages.push({
@ -2630,6 +2607,10 @@ watch(
content: "该内容由AI生成,请注意甄别", content: "该内容由AI生成,请注意甄别",
end: true, end: true,
}); });
} catch (e) {
ElMessage.error("历史数据获取出错!");
console.error("e", e);
}
}, },
{ {
deep: true, // deep: true, //
@ -2643,11 +2624,11 @@ function KlineCanvsEcharts(containerId) {
return (window.innerWidth * vw) / 100; return (window.innerWidth * vw) / 100;
} }
console.log("KLine渲染: 开始处理数据, 容器ID:", containerId);
// console.log("KLine: , ID:", containerId);
// chatStore // chatStore
const messages = chatStore.messages; const messages = chatStore.messages;
console.log("KLine渲染: 获取到的消息:", messages);
// console.log("KLine: :", messages);
let klineMessageIndex = -1; let klineMessageIndex = -1;
let klineData = null; let klineData = null;
@ -2663,7 +2644,7 @@ function KlineCanvsEcharts(containerId) {
// } // }
// } // }
klineMessageIndex = containerId.split("-")[2]; klineMessageIndex = containerId.split("-")[2];
console.log("KLine渲染: 找到K线消息索引:", klineMessageIndex);
// console.log("KLine: K线:", klineMessageIndex);
if ( if (
messages[klineMessageIndex].kline && messages[klineMessageIndex].kline &&
messages[klineMessageIndex].chartData messages[klineMessageIndex].chartData
@ -2683,33 +2664,33 @@ function KlineCanvsEcharts(containerId) {
if (messages[klineMessageIndex].klineType == 1) { if (messages[klineMessageIndex].klineType == 1) {
if (!klineData) { if (!klineData) {
console.warn("六色罗盘渲染: 数据无效 - 在chatStore中找不到有效的K线数据");
// console.warn(": - chatStoreK线");
return; return;
} }
// //
const container = document.getElementById(containerId); const container = document.getElementById(containerId);
if (!container) { if (!container) {
console.error("六色罗盘渲染: 找不到容器元素:", containerId);
// console.error(": :", containerId);
return; return;
} }
// //
console.log("六色罗盘渲染: 创建图表实例");
// console.log(": ");
try { try {
// //
if (chartInstancesMap[containerId]) { if (chartInstancesMap[containerId]) {
console.log("六色罗盘渲染: 销毁已有图表实例");
// console.log(": ");
chartInstancesMap[containerId].dispose(); chartInstancesMap[containerId].dispose();
delete chartInstancesMap[containerId]; delete chartInstancesMap[containerId];
} }
// 使 // 使
chartInstancesMap[containerId] = echarts.init(container); chartInstancesMap[containerId] = echarts.init(container);
console.log("六色罗盘渲染: 图表实例创建成功");
// console.log(": ");
} catch (error) { } catch (error) {
console.error("六色罗盘渲染: 图表实例创建失败:", error);
// console.error(": :", error);
return; return;
} }
@ -2812,54 +2793,54 @@ function KlineCanvsEcharts(containerId) {
}; };
} else if (messages[klineMessageIndex].klineType == 2) { } else if (messages[klineMessageIndex].klineType == 2) {
if (!klineData || !klineData.Kline) { if (!klineData || !klineData.Kline) {
console.warn("KLine渲染: 数据无效 - 在chatStore中找不到有效的K线数据");
// console.warn("KLine: - chatStoreK线");
return; return;
} }
// //
const container = document.getElementById(containerId); const container = document.getElementById(containerId);
if (!container) { if (!container) {
console.error("KLine渲染: 找不到容器元素:", containerId);
// console.error("KLine: :", containerId);
return; return;
} }
// //
console.log("KLine渲染: 创建图表实例");
// console.log("KLine: ");
try { try {
// //
if (chartInstancesMap[containerId]) { if (chartInstancesMap[containerId]) {
console.log("KLine渲染: 销毁已有图表实例");
// console.log("KLine: ");
chartInstancesMap[containerId].dispose(); chartInstancesMap[containerId].dispose();
delete chartInstancesMap[containerId]; delete chartInstancesMap[containerId];
} }
// 使 // 使
chartInstancesMap[containerId] = echarts.init(container); chartInstancesMap[containerId] = echarts.init(container);
console.log("KLine渲染: 图表实例创建成功");
// console.log("KLine: ");
} catch (error) { } catch (error) {
console.error("KLine渲染: 图表实例创建失败:", error);
// console.error("KLine: :", error);
return; return;
} }
const data = klineData.Kline; const data = klineData.Kline;
console.log("KLine渲染: Kline数据", data);
// console.log("KLine: Kline", data);
// //
const splitData = (a) => { const splitData = (a) => {
console.log("KLine渲染: 开始数据切割");
// console.log("KLine: ");
const categoryData = []; const categoryData = [];
let values = []; let values = [];
for (let i = 0; i < a.length; i++) { for (let i = 0; i < a.length; i++) {
categoryData.push(a[i][0]); categoryData.push(a[i][0]);
values.push([a[i][1], a[i][2], a[i][3], a[i][4]]); values.push([a[i][1], a[i][2], a[i][3], a[i][4]]);
} }
console.log("KLine渲染: 日期数据点数量", categoryData.length);
console.log("KLine渲染: 值数据点数量", values.length);
// console.log("KLine: ", categoryData.length);
// console.log("KLine: ", values.length);
return { categoryData, values }; return { categoryData, values };
}; };
// //
console.log("KLine渲染: 开始配置图表选项");
// console.log("KLine: ");
const arr1 = []; const arr1 = [];
const arr2 = []; const arr2 = [];
@ -4109,13 +4090,13 @@ function KlineCanvsEcharts(containerId) {
}; };
} }
console.log("KLine渲染: 图表配置完成");
// console.log("KLine: ");
try { try {
// //
console.log("KLine渲染: 开始设置图表选项");
// console.log("KLine: ");
chartInstancesMap[containerId].setOption(KlineOption); chartInstancesMap[containerId].setOption(KlineOption);
console.log("KLine渲染: 图表选项设置成功");
// console.log("KLine: ");
// //
const resizeFunc = _.throttle( const resizeFunc = _.throttle(
@ -4150,9 +4131,9 @@ function KlineCanvsEcharts(containerId) {
window.removeEventListener("resize", window[`resize_${containerId}`]); window.removeEventListener("resize", window[`resize_${containerId}`]);
window.addEventListener("resize", window[`resize_${containerId}`]); window.addEventListener("resize", window[`resize_${containerId}`]);
console.log("KLine渲染: 图表渲染完成");
// console.log("KLine: ");
} catch (error) { } catch (error) {
console.error("KLine渲染: 图表渲染出错", error);
// console.error("KLine: ", error);
} }
} }
@ -4180,13 +4161,6 @@ watch(
} else { } else {
console.log("关闭语音播放"); console.log("关闭语音播放");
pauseAudio(); pauseAudio();
//
// Howler.stop();
// Howler.unload();
// if (audioStore.soundInstance) {
// audioStore.soundInstance.off(); //
// audioStore.soundInstance = null;
// }
} }
}, },
{ immediate: true } { immediate: true }
@ -4337,12 +4311,12 @@ onUnmounted(() => {
<!-- 用户消息容器包含喇叭按钮 --> <!-- 用户消息容器包含喇叭按钮 -->
<div v-if="msg.sender === 'user'" class="user-message-container"> <div v-if="msg.sender === 'user'" class="user-message-container">
<img <img
:src="isVoice && audioStore.isPlaying ? voiceNoActive : voice"
:src="msg.audioStatus ? voice : voiceNoActive"
class="user-message-speaker" class="user-message-speaker"
:class="{ :class="{
'speaker-active': isVoice && audioStore.isPlaying,
'speaker-active': msg.audioStatus,
}" }"
@click="toggleVoiceForUser"
@click="toggleVoiceForUser(index)"
alt="喇叭" alt="喇叭"
/> />
<div <div

12
src/views/Announcement.vue

@ -8,7 +8,8 @@ import {
import back from "../assets/img/Feedback/back.png"; import back from "../assets/img/Feedback/back.png";
import { useDataStore } from "@/store/dataList.js"; import { useDataStore } from "@/store/dataList.js";
const dataStore = useDataStore(); const dataStore = useDataStore();
import { useChatStore } from "../store/chat";
const chatStore = useChatStore();
const marketList = ref({ const marketList = ref({
usa: "美股", usa: "美股",
cn: "A股", cn: "A股",
@ -72,14 +73,11 @@ const handleVideoPlay = () => {
// //
}; };
//
const emit = defineEmits(["updateMessage", "ensureAIchat"]);
const clickCode = (code) => { const clickCode = (code) => {
console.log(code); console.log(code);
emit("updateMessage", code);
emit("ensureAIchat");
chatStore.announcementMsg = code;
console.log("chatStore.announcementMsg", chatStore.announcementMsg);
dataStore.isFeedback = false;
}; };
const feedbackBack = () => { const feedbackBack = () => {

2
src/views/Selectmodel.vue

@ -47,7 +47,9 @@ onMounted(() => {
/phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test( /phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone/i.test(
navigator.userAgent navigator.userAgent
); );
const token = getQueryVariable("token");
!isPhone && !isPhone &&
token &&
localStorage.setItem( localStorage.setItem(
"localToken", "localToken",
decodeURIComponent(String(getQueryVariable("token"))) decodeURIComponent(String(getQueryVariable("token")))

104
src/views/components/HistoryRecord.vue

@ -18,18 +18,27 @@
@click="openHistory" @click="openHistory"
src="https://d31zlh4on95l9h.cloudfront.net/images/b2d784f8607ab65081f5289459581bfe.png" src="https://d31zlh4on95l9h.cloudfront.net/images/b2d784f8607ab65081f5289459581bfe.png"
alt="icon" alt="icon"
title="打开边栏"
/> />
</div> </div>
<div v-if="isCollapsed" class="collapsed-bottom-container"> <div v-if="isCollapsed" class="collapsed-bottom-container">
<div class="collapsed-bottom-btn" @click="handleFeedbackClick">
<div
class="collapsed-bottom-btn"
@click="handleFeedbackClick"
title="用户反馈"
>
<img <img
class="collapsed-bottom-feedback" class="collapsed-bottom-feedback"
src="https://d31zlh4on95l9h.cloudfront.net/images/41d6e25c19466718d462bcee2f050140.png" src="https://d31zlh4on95l9h.cloudfront.net/images/41d6e25c19466718d462bcee2f050140.png"
alt="icon" alt="icon"
/> />
</div> </div>
<div class="collapsed-bottom-btn" @click="handleAnnouncementClick">
<div
class="collapsed-bottom-btn"
@click="handleAnnouncementClick"
title="公告"
>
<img <img
class="collapsed-bottom-announcement" class="collapsed-bottom-announcement"
src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png" src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png"
@ -55,11 +64,20 @@
@click="closeHistory" @click="closeHistory"
src="https://d31zlh4on95l9h.cloudfront.net/images/b2d784f8607ab65081f5289459581bfe.png" src="https://d31zlh4on95l9h.cloudfront.net/images/b2d784f8607ab65081f5289459581bfe.png"
alt="icon" alt="icon"
title="收起边栏"
/> />
</div> </div>
<!-- 历史记录列表 --> <!-- 历史记录列表 -->
<div class="history-list"> <div class="history-list">
<div v-for="history in categoryHistory" :key="history.name">
<!-- 空状态 -->
<div v-if="historyRecords.length === 0" class="empty-state">
<div class="empty-icon">
<el-icon class="documentDelete"><DocumentDelete /></el-icon>
</div>
<p class="empty-text">暂无历史记录</p>
</div>
<div v-else v-for="history in categoryHistory" :key="history.name">
<div class="categoryName"> <div class="categoryName">
{{ history.name }} {{ history.name }}
</div> </div>
@ -146,25 +164,17 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 空状态 -->
<div v-if="historyRecords.length === 0" class="empty-state">
<div class="empty-icon">
<el-icon class="documentDelete"><DocumentDelete /></el-icon>
</div>
<p class="empty-text">暂无历史记录</p>
</div>
</div> </div>
<div class="bottom-container"> <div class="bottom-container">
<div class="bottom-btn" @click="handleFeedbackClick">
<div class="bottom-btn" @click="handleFeedbackClick" title="用户反馈">
<img <img
class="bottom-feedback" class="bottom-feedback"
src="https://d31zlh4on95l9h.cloudfront.net/images/41d6e25c19466718d462bcee2f050140.png" src="https://d31zlh4on95l9h.cloudfront.net/images/41d6e25c19466718d462bcee2f050140.png"
alt="icon" alt="icon"
/> />
</div> </div>
<div class="bottom-btn" @click="handleAnnouncementClick">
<div class="bottom-btn" @click="handleAnnouncementClick" title="公告">
<img <img
class="bottom-announcement" class="bottom-announcement"
src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png" src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png"
@ -203,7 +213,15 @@
</div> </div>
<!-- 历史记录列表 --> <!-- 历史记录列表 -->
<div class="history-list"> <div class="history-list">
<div v-for="history in categoryHistory" :key="history.name">
<!-- 空状态 -->
<div v-if="historyRecords.length === 0" class="empty-state">
<div class="empty-icon">
<el-icon class="documentDelete"><DocumentDelete /></el-icon>
</div>
<p class="empty-text">暂无历史记录</p>
</div>
<div v-else v-for="history in categoryHistory" :key="history.name">
<div class="categoryName"> <div class="categoryName">
{{ history.name }} {{ history.name }}
</div> </div>
@ -290,18 +308,14 @@
</div> </div>
</div> </div>
</div> </div>
<!-- 空状态 -->
<div v-if="historyRecords.length === 0" class="empty-state">
<div class="empty-icon">
<el-icon class="documentDelete"><DocumentDelete /></el-icon>
</div>
<p class="empty-text">暂无历史记录</p>
</div>
</div> </div>
<div class="mobile-bottom-container"> <div class="mobile-bottom-container">
<div class="mobile-bottom-btn" @click="handleFeedbackClick">
<div
class="mobile-bottom-btn"
@click="handleFeedbackClick"
title="用户反馈"
>
<img <img
class="mobile-bottom-feedback" class="mobile-bottom-feedback"
src="https://d31zlh4on95l9h.cloudfront.net/images/41d6e25c19466718d462bcee2f050140.png" src="https://d31zlh4on95l9h.cloudfront.net/images/41d6e25c19466718d462bcee2f050140.png"
@ -309,7 +323,11 @@
/> />
<div class="mobile-bottom-text">用户反馈</div> <div class="mobile-bottom-text">用户反馈</div>
</div> </div>
<div class="mobile-bottom-btn" @click="handleAnnouncementClick">
<div
class="mobile-bottom-btn"
@click="handleAnnouncementClick"
title="公告"
>
<img <img
class="mobile-bottom-announcement" class="mobile-bottom-announcement"
src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png" src="https://d31zlh4on95l9h.cloudfront.net/images/c51c7fbb68671729801fb10d65bd7789.png"
@ -346,6 +364,9 @@ import moment from "moment";
import { ElMessage } from "element-plus"; import { ElMessage } from "element-plus";
import { useChatStore } from "../../store/chat"; import { useChatStore } from "../../store/chat";
const chatStore = useChatStore(); const chatStore = useChatStore();
import { useRouter } from "vue-router";
const router = useRouter();
// Props // Props
const props = defineProps({ const props = defineProps({
currentType: { currentType: {
@ -407,12 +428,12 @@ const getHistoryList = async (params) => {
// 2. // 2.
let todayList = remainingRecords.filter((record) => { let todayList = remainingRecords.filter((record) => {
const today = moment().format("YYYY-MM-DD"); const today = moment().format("YYYY-MM-DD");
const recordDate = moment(record.updateTime).format("YYYY-MM-DD");
const recordDate = moment(record.updatedTime).format("YYYY-MM-DD");
return recordDate === today; return recordDate === today;
}); });
remainingRecords = remainingRecords.filter((record) => { remainingRecords = remainingRecords.filter((record) => {
const today = moment().format("YYYY-MM-DD"); const today = moment().format("YYYY-MM-DD");
const recordDate = moment(record.updateTime).format("YYYY-MM-DD");
const recordDate = moment(record.updatedTime).format("YYYY-MM-DD");
return recordDate !== today; return recordDate !== today;
}); });
@ -420,13 +441,13 @@ const getHistoryList = async (params) => {
let recent3DaysList = remainingRecords.filter((record) => { let recent3DaysList = remainingRecords.filter((record) => {
const threeDaysAgo = moment().subtract(3, "days").startOf("day"); const threeDaysAgo = moment().subtract(3, "days").startOf("day");
const yesterday = moment().subtract(1, "days").endOf("day"); const yesterday = moment().subtract(1, "days").endOf("day");
const recordDate = moment(record.updateTime);
const recordDate = moment(record.updatedTime);
return recordDate.isAfter(threeDaysAgo) && recordDate.isBefore(yesterday); return recordDate.isAfter(threeDaysAgo) && recordDate.isBefore(yesterday);
}); });
remainingRecords = remainingRecords.filter((record) => { remainingRecords = remainingRecords.filter((record) => {
const threeDaysAgo = moment().subtract(3, "days").startOf("day"); const threeDaysAgo = moment().subtract(3, "days").startOf("day");
const yesterday = moment().subtract(1, "days").endOf("day"); const yesterday = moment().subtract(1, "days").endOf("day");
const recordDate = moment(record.updateTime);
const recordDate = moment(record.updatedTime);
return !( return !(
recordDate.isAfter(threeDaysAgo) && recordDate.isBefore(yesterday) recordDate.isAfter(threeDaysAgo) && recordDate.isBefore(yesterday)
); );
@ -435,24 +456,24 @@ const getHistoryList = async (params) => {
// 4. 73 // 4. 73
let recent7DaysList = remainingRecords.filter((record) => { let recent7DaysList = remainingRecords.filter((record) => {
const sevenDaysAgo = moment().subtract(7, "days").startOf("day"); const sevenDaysAgo = moment().subtract(7, "days").startOf("day");
const recordDate = moment(record.updateTime);
const recordDate = moment(record.updatedTime);
return recordDate.isAfter(sevenDaysAgo); return recordDate.isAfter(sevenDaysAgo);
}); });
remainingRecords = remainingRecords.filter((record) => { remainingRecords = remainingRecords.filter((record) => {
const sevenDaysAgo = moment().subtract(7, "days").startOf("day"); const sevenDaysAgo = moment().subtract(7, "days").startOf("day");
const recordDate = moment(record.updateTime);
const recordDate = moment(record.updatedTime);
return !recordDate.isAfter(sevenDaysAgo); return !recordDate.isAfter(sevenDaysAgo);
}); });
// 5. 30 // 5. 30
let recent30DaysList = remainingRecords.filter((record) => { let recent30DaysList = remainingRecords.filter((record) => {
const thirtyDaysAgo = moment().subtract(30, "days").startOf("day"); const thirtyDaysAgo = moment().subtract(30, "days").startOf("day");
const recordDate = moment(record.updateTime);
const recordDate = moment(record.updatedTime);
return recordDate.isAfter(thirtyDaysAgo); return recordDate.isAfter(thirtyDaysAgo);
}); });
remainingRecords = remainingRecords.filter((record) => { remainingRecords = remainingRecords.filter((record) => {
const thirtyDaysAgo = moment().subtract(30, "days").startOf("day"); const thirtyDaysAgo = moment().subtract(30, "days").startOf("day");
const recordDate = moment(record.updateTime);
const recordDate = moment(record.updatedTime);
return !recordDate.isAfter(thirtyDaysAgo); return !recordDate.isAfter(thirtyDaysAgo);
}); });
@ -523,6 +544,10 @@ const toggleCollapse = () => {
localStorage.setItem("historyRecordCollapsed", isCollapsed.value); localStorage.setItem("historyRecordCollapsed", isCollapsed.value);
}; };
const backToSelectModel = () => {
router.push("/Selectmodel");
};
const openHistory = () => { const openHistory = () => {
// getHistoryList({ // getHistoryList({
// model: props.currentType == "AIchat" ? 1 : 2, // model: props.currentType == "AIchat" ? 1 : 2,
@ -586,6 +611,19 @@ const handleFeedbackClick = () => {
emit("showFeedback"); emit("showFeedback");
}; };
watch(
() => chatStore.searchRecord,
(newVal) => {
if (chatStore.searchRecord) {
getHistoryList({
model: props.currentType == "AIchat" ? 1 : 2,
token: localStorage.getItem("localToken"),
});
chatStore.searchRecord = false;
}
}
);
// //
defineExpose({ defineExpose({
isCollapsed, isCollapsed,
@ -729,6 +767,7 @@ onMounted(() => {
/* height: 50%; */ /* height: 50%; */
display: flex; display: flex;
justify-content: center; justify-content: center;
cursor: pointer;
/* align-items: center; */ /* align-items: center; */
} }
@ -980,6 +1019,7 @@ onMounted(() => {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
cursor: pointer;
} }
.mobile-bottom-btn { .mobile-bottom-btn {

35
src/views/homePage.vue

@ -174,8 +174,31 @@ const isInputDisabled = ref(false);
// //
const updateMessage = (title) => { const updateMessage = (title) => {
message.value = title; message.value = title;
// console.log("updateMessage :", title);
console.log("updateMessage 的值:", title);
}; };
watch(
() => chatStore.announcementMsg,
(newVal) => {
console.log("监听到公告改变", chatStore.announcementMsg);
if (chatStore.announcementMsg) {
message.value = chatStore.announcementMsg;
chatStore.announcementMsg = null;
}
}
);
watch(
() => dataStore.isFeedback,
async (newVal) => {
if (!dataStore.isFeedback) {
await nextTick();
//
throttledHeightListener();
}
}
);
const sendMessage = async () => { const sendMessage = async () => {
if ( if (
localStorage.getItem("localToken") == null || localStorage.getItem("localToken") == null ||
@ -226,6 +249,8 @@ const sendMessage = async () => {
sender: "user", sender: "user",
content: messageContent, content: messageContent,
timestamp: new Date().toISOString(), timestamp: new Date().toISOString(),
audioArray: [],
audioStatus: true,
}, },
]; ];
console.log(messages.value, "messages.value"); console.log(messages.value, "messages.value");
@ -234,6 +259,7 @@ const sendMessage = async () => {
// //
const enableInput = () => { const enableInput = () => {
console.log("解除禁用");
isInputDisabled.value = false; isInputDisabled.value = false;
}; };
@ -426,16 +452,16 @@ const heightListener = () => {
if (activeTab.value === "AIchat") { if (activeTab.value === "AIchat") {
if (aftertop - befortop > 0) { if (aftertop - befortop > 0) {
// console.log('');
// console.log("");
isScrolling.value = true; isScrolling.value = true;
} else { } else {
// console.log('');
// console.log("");
isScrolling.value = true; isScrolling.value = true;
} }
// //
if (isBottom) { if (isBottom) {
// console.log('');
// console.log("");
isScrolling.value = false; isScrolling.value = false;
} }
} }
@ -607,6 +633,7 @@ onMounted(async () => {
setHeight(document.getElementById("testId")); // setHeight(document.getElementById("testId")); //
// //
await chatStore.getUserCount(); await chatStore.getUserCount();
// //
throttledSmoothScrollToBottom(); throttledSmoothScrollToBottom();
// //

Loading…
Cancel
Save