diff --git a/src/views/AIchat.vue b/src/views/AIchat.vue index 7039163..c8b2d7e 100644 --- a/src/views/AIchat.vue +++ b/src/views/AIchat.vue @@ -149,7 +149,7 @@ const playNextAudio = () => { setTimeout(() => { isCallingPlayNext = false; playNextAudio(); - }, 500); + }, 200); } else { console.log("🎉 所有音频播放完成,清除音频实例"); chatStore.messages[chatStore.currentUserIndex].audioStatus = false; @@ -752,7 +752,6 @@ const createTypingEffect = (message, content, speed) => { if (message.end) { chatStore.getUserCount(); chatStore.isLoading = false; - chatStore.searchRecord = true; console.log("打印完毕,接触输入框禁用状态"); emit("enableInput"); } @@ -1102,6 +1101,8 @@ watch( console.log(codeData.value, "codeData"); // 根据意图识别结果判断 if (result.code == 200) { + // 意图识别成功后,更新历史记录状态 + chatStore.searchRecord = true; // 获取到股票名称后,继续思考过程 if (thinkingMessageRef && codeData.value.name) { await continueThinkingProcess( @@ -2418,6 +2419,12 @@ watch( return; } try { + // 解开输入框 + emit("enableInput"); + // 清除打字机队列和状态 + typingQueue.value = []; + isTypingInProgress.value = false; + // 清空聊天框内容 chatStore.messages = []; @@ -3287,10 +3294,10 @@ function KlineCanvsEcharts(containerId) { { textStyle: { color: "black", - fontSize: window.innerWidth > 768 ? 15 : vwToPx(1.8), + fontSize: window.innerWidth > 768 ? 12 : 9, }, width: "100%", - top: window.innerWidth > 768 ? "0%" : "-1%", + top: window.innerWidth > 768 ? "5%" : "4%", left: "center", itemGap: window.innerWidth > 768 ? 20 : 10, itemWidth: 10, @@ -3325,10 +3332,10 @@ function KlineCanvsEcharts(containerId) { { textStyle: { color: "black", - fontSize: window.innerWidth > 768 ? 15 : vwToPx(1.8), + fontSize: window.innerWidth > 768 ? 12 : 9, }, orient: "horizontal", - top: window.innerWidth > 768 ? "3%" : "2%", + top: window.innerWidth > 768 ? "8%" : "7%", width: "100%", left: "center", itemGap: 15, @@ -3340,11 +3347,11 @@ function KlineCanvsEcharts(containerId) { rich: { green: { color: "green", - fontSize: window.innerWidth > 768 ? 20 : 10, + fontSize: window.innerWidth > 768 ? 12 : 9, }, red: { color: "red", - fontSize: window.innerWidth > 768 ? 20 : 10, + fontSize: window.innerWidth > 768 ? 12 : 9, }, }, }, @@ -3360,10 +3367,10 @@ function KlineCanvsEcharts(containerId) { { textStyle: { color: "black", - fontSize: window.innerWidth > 768 ? 15 : vwToPx(1.8), + fontSize: window.innerWidth > 768 ? 12 : 9, }, orient: "horizontal", - top: window.innerWidth > 768 ? "68%" : "64%", + top: window.innerWidth > 768 ? "62%" : "60%", width: "100%", left: "center", itemGap: 15, @@ -3375,11 +3382,11 @@ function KlineCanvsEcharts(containerId) { rich: { green: { color: "green", - fontSize: window.innerWidth > 768 ? 20 : 10, + fontSize: window.innerWidth > 768 ? 12 : 9, }, red: { color: "red", - fontSize: window.innerWidth > 768 ? 20 : 10, + fontSize: window.innerWidth > 768 ? 12 : 9, }, }, }, @@ -3466,53 +3473,56 @@ function KlineCanvsEcharts(containerId) { }, grid: [ { + top: window.innerWidth > 768 ? "12%" : "10%", left: window.innerWidth > 1024 - ? "70vw" + ? "14%" : window.innerWidth > 768 - ? "65vw" - : "55vw", + ? "18%" + : "20%", right: window.innerWidth > 1024 - ? "40vw" + ? "9%" : window.innerWidth > 768 - ? "30vw" - : "40vw", - top: window.innerWidth > 768 ? "8%" : "5%", - height: window.innerWidth > 768 ? "34%" : "34%", + ? "12%" + : "14%", + + height: window.innerWidth > 768 ? "27%" : "29%", containLabel: false, }, { + top: window.innerWidth > 768 ? "42%" : "42%", left: window.innerWidth > 1024 - ? "70vw" + ? "14%" : window.innerWidth > 768 - ? "65vw" - : "55vw", + ? "18%" + : "20%", right: window.innerWidth > 1024 - ? "40vw" + ? "9%" : window.innerWidth > 768 - ? "30vw" - : "40vw", - top: window.innerWidth > 768 ? "45%" : "42%", - height: window.innerWidth > 768 ? "22%" : "22%", + ? "12%" + : "14%", + + height: window.innerWidth > 768 ? "20%" : "18%", containLabel: false, }, { + top: window.innerWidth > 768 ? "66%" : "64%", left: window.innerWidth > 1024 - ? "70vw" + ? "14%" : window.innerWidth > 768 - ? "65vw" - : "55vw", + ? "18%" + : "20%", right: window.innerWidth > 1024 - ? "40vw" + ? "9%" : window.innerWidth > 768 - ? "30vw" - : "40vw", - top: window.innerWidth > 768 ? "73%" : "70%", + ? "12%" + : "14%", + height: window.innerWidth > 768 ? "20%" : "22%", containLabel: false, }, @@ -3557,6 +3567,7 @@ function KlineCanvsEcharts(containerId) { axisLabel: { show: true, interval: "auto", + fontSize: window.innerWidth > 768 ? 12 : 9, }, }, ], @@ -3653,11 +3664,15 @@ function KlineCanvsEcharts(containerId) { show: true, xAxisIndex: [0, 1, 2], type: "slider", - top: window.innerWidth > 768 ? "95%" : "96%", + top: window.innerWidth > 768 ? "90%" : "91%", // left: window.innerWidth > 768 ? "10%" : "8%", // right: window.innerWidth > 768 ? "4%" : "8%", + height: 20, start: 98, end: 100, + textStyle: { + fontSize: window.innerWidth > 768 ? 12 : 9, + }, }, ], visualMap: [ @@ -4093,6 +4108,11 @@ function KlineCanvsEcharts(containerId) { type: "solid", }, data: [{ yAxis: 20 }], + label: { + normal: { + fontSize: window.innerWidth > 768 ? 12 : 9, + }, + }, }, }, { @@ -4110,6 +4130,11 @@ function KlineCanvsEcharts(containerId) { type: "solid", }, data: [{ yAxis: 50 }], + label: { + normal: { + fontSize: window.innerWidth > 768 ? 12 : 9, + }, + }, }, }, { @@ -4127,6 +4152,11 @@ function KlineCanvsEcharts(containerId) { type: "solid", }, data: [{ yAxis: 80 }], + label: { + normal: { + fontSize: window.innerWidth > 768 ? 12 : 9, + }, + }, }, }, { @@ -4145,6 +4175,11 @@ function KlineCanvsEcharts(containerId) { type: "solid", }, data: [{ yAxis: 100 }], + label: { + normal: { + fontSize: window.innerWidth > 768 ? 12 : 9, + }, + }, }, }, ], @@ -4466,7 +4501,7 @@ onUnmounted(() => {
-
+

暂无数据

@@ -4952,6 +4987,14 @@ p { width: 90%; } +.kline-container .chart-mount-pointJN { + display: flex; + justify-content: center; + align-items: center; + height: 100%; + width: 100%; +} + /* AI消息容器样式 */ .ai-message-container { display: flex; diff --git a/src/views/components/HistoryRecord.vue b/src/views/components/HistoryRecord.vue index 0c367bd..fceb264 100644 --- a/src/views/components/HistoryRecord.vue +++ b/src/views/components/HistoryRecord.vue @@ -25,23 +25,23 @@
icon
@@ -96,11 +96,27 @@
- {{ record.stockName || record.stockCode }} + {{ record.stockName }} ({{ record.stockCode }}) +
+ + + +
- {{ moment(record.updatedTime).format("YYYY-MM-DD HH:mm:ss") }} + {{ moment(record.createdTime).format("YYYY-MM-DD HH:mm:ss") }}
@@ -170,17 +186,17 @@
-
+
-
+
icon
@@ -242,9 +258,27 @@ />
-
{{ record.stockCode }}
+
+ {{ record.stockCode }} +
+ + + +
+
- {{ moment(record.updatedTime).format("YYYY-MM-DD HH:mm:ss") }} + {{ moment(record.createdTime).format("YYYY-MM-DD HH:mm:ss") }}
@@ -316,27 +350,27 @@
-
用户反馈
+
公告
icon -
公告
+
用户反馈
@@ -418,12 +452,24 @@ const closeDeleteDialog = () => { const historyRecords = ref([]); const categoryHistory = ref([]); +let firstFlag = false; const getHistoryList = async (params) => { try { const result = await getHistoryListAPI(params); historyRecords.value = result.data; let remainingRecords = result.data; // 复制原数组 - + console.log("result", result.data, "firstFlag", firstFlag); + if (result.data.length != 0 && !firstFlag) { + const userAgent = navigator.userAgent; + if ( + !/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test( + userAgent + ) + ) { + isCollapsed.value = false; + } + firstFlag = true; + } // 1. 筛选置顶记录 let topList = remainingRecords.filter((record) => record.isTop === 1); remainingRecords = remainingRecords.filter((record) => record.isTop !== 1); @@ -431,12 +477,12 @@ const getHistoryList = async (params) => { // 2. 筛选今日记录 let todayList = remainingRecords.filter((record) => { const today = moment().format("YYYY-MM-DD"); - const recordDate = moment(record.updatedTime).format("YYYY-MM-DD"); + const recordDate = moment(record.createdTime).format("YYYY-MM-DD"); return recordDate === today; }); remainingRecords = remainingRecords.filter((record) => { const today = moment().format("YYYY-MM-DD"); - const recordDate = moment(record.updatedTime).format("YYYY-MM-DD"); + const recordDate = moment(record.createdTime).format("YYYY-MM-DD"); return recordDate !== today; }); @@ -444,13 +490,13 @@ const getHistoryList = async (params) => { let recent3DaysList = remainingRecords.filter((record) => { const threeDaysAgo = moment().subtract(3, "days").startOf("day"); const yesterday = moment().subtract(1, "days").endOf("day"); - const recordDate = moment(record.updatedTime); + const recordDate = moment(record.createdTime); return recordDate.isAfter(threeDaysAgo) && recordDate.isBefore(yesterday); }); remainingRecords = remainingRecords.filter((record) => { const threeDaysAgo = moment().subtract(3, "days").startOf("day"); const yesterday = moment().subtract(1, "days").endOf("day"); - const recordDate = moment(record.updatedTime); + const recordDate = moment(record.createdTime); return !( recordDate.isAfter(threeDaysAgo) && recordDate.isBefore(yesterday) ); @@ -459,24 +505,24 @@ const getHistoryList = async (params) => { // 4. 筛选近7日记录(不包括今日和近3日) let recent7DaysList = remainingRecords.filter((record) => { const sevenDaysAgo = moment().subtract(7, "days").startOf("day"); - const recordDate = moment(record.updatedTime); + const recordDate = moment(record.createdTime); return recordDate.isAfter(sevenDaysAgo); }); remainingRecords = remainingRecords.filter((record) => { const sevenDaysAgo = moment().subtract(7, "days").startOf("day"); - const recordDate = moment(record.updatedTime); + const recordDate = moment(record.createdTime); return !recordDate.isAfter(sevenDaysAgo); }); // 5. 筛选近30日记录(不包括前面已筛选的) let recent30DaysList = remainingRecords.filter((record) => { const thirtyDaysAgo = moment().subtract(30, "days").startOf("day"); - const recordDate = moment(record.updatedTime); + const recordDate = moment(record.createdTime); return recordDate.isAfter(thirtyDaysAgo); }); remainingRecords = remainingRecords.filter((record) => { const thirtyDaysAgo = moment().subtract(30, "days").startOf("day"); - const recordDate = moment(record.updatedTime); + const recordDate = moment(record.createdTime); return !recordDate.isAfter(thirtyDaysAgo); }); @@ -579,28 +625,28 @@ const selectRecord = async (record) => { parentId: record.parentId, recordId: record.id, }); - + if (result && result.data) { historyData.value = result.data; chatStore.dbqbClickRecord = historyData.value; // 构造股票数据对象,保持与现有结构一致 const stockData = { - queryText: record.stockCode || record.stockName || '', // 使用记录中的股票代码或名称作为查询文本 + queryText: record.stockCode || record.stockName || "", // 使用记录中的股票代码或名称作为查询文本 stockInfo: { - name: result.data.stockData?.stockName || record.stockName || '', - code: record.stockCode || '', - market: record.stockMarket || 'cn' + name: result.data.stockData?.stockName || record.stockName || "", + code: record.stockCode || "", + market: record.stockMarket || "cn", }, apiData: result.data.stockData || {}, // 图表数据 conclusionData: result.data.wokeFlowData?.One || {}, // 场景应用的结论和音频 - timestamp: new Date().toISOString() + timestamp: new Date().toISOString(), }; - + // 通过emit将数据传递给父组件 - emit('selectRecord', stockData); - console.log('历史记录数据已发送给父组件:', stockData); + emit("selectRecord", stockData); + console.log("历史记录数据已发送给父组件:", stockData); } else { - console.error('历史记录数据格式不正确:', result); + console.error("历史记录数据格式不正确:", result); } } catch (e) { console.error("获取历史记录数据失败", e); @@ -657,6 +703,7 @@ defineExpose({ isCollapsed, toggleCollapse, getHistoryList, + selectedRecordId, }); // 生命周期 @@ -708,6 +755,7 @@ onMounted(() => { } .mobileCollapsed { + /* max-width: 400px */ width: 80vw; } @@ -915,6 +963,10 @@ onMounted(() => { background: rgba(255, 255, 255, 0.1); } +.history-item.active { + background: rgba(255, 255, 255, 0.5); +} + .record-content { display: flex; width: 100%; @@ -938,9 +990,16 @@ onMounted(() => { margin-bottom: 6px; overflow: hidden; text-overflow: ellipsis; - display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; + display: flex; +} + +.top-icon { + margin-left: 5px; + color: white; + height: auto; + width: 15px; } .stock-name { diff --git a/src/views/homePage.vue b/src/views/homePage.vue index 8d15129..c9518fd 100644 --- a/src/views/homePage.vue +++ b/src/views/homePage.vue @@ -181,7 +181,7 @@ watch( () => chatStore.announcementMsg, (newVal) => { console.log("监听到公告改变", chatStore.announcementMsg); - if (chatStore.announcementMsg) { + if (chatStore.announcementMsg && !isInputDisabled.value) { message.value = chatStore.announcementMsg; chatStore.announcementMsg = null; } @@ -192,6 +192,8 @@ watch( () => dataStore.isFeedback, async (newVal) => { if (!dataStore.isFeedback) { + // 重置公告页面显示状态 + isAnnouncementVisible.value = false; await nextTick(); // 监听页面高度 throttledHeightListener(); @@ -217,6 +219,10 @@ const sendMessage = async () => { // 注意:历史记录会在消息发送后自动更新,无需手动添加 + // 取消历史记录选中状态 + if (historyRecordRef) { + historyRecordRef.value.selectedRecordId = null; + } // 判断当前是否为 AiEmotion 组件 if (activeTab.value === "AiEmotion") { // 禁用输入框 @@ -353,7 +359,7 @@ const throttledSmoothScrollToBottom = _.throttle(smoothScrollToBottom, 300, { }); watch( - () => chatStore.messages, + () => chatStore.messages.length, () => { // console.log('messages变化了') // 只有在AIchat页面时才执行自动滚动 @@ -362,7 +368,7 @@ watch( } // setTimeout(throttledSmoothScrollToBottom, 100); }, - { deep: true, immediate: true } + { deep: false, immediate: true } ); watch( @@ -382,7 +388,7 @@ watch( console.log("activeTab变化了", activeTab.value); if (activeTab.value == "AIchat" || activeTab.value == "AiEmotion") { if (historyRecordRef.value && historyRecordRef.value.getHistoryList) { - historyRecordRef.value.getHistoryList({ + const result = historyRecordRef.value.getHistoryList({ model: activeTab.value == "AIchat" ? 1 : 2, token: localStorage.getItem("localToken"), }); @@ -392,7 +398,7 @@ watch( if (activeTab.value === "AIchat") { isScrolling.value = false; //回复滚动到底部方法 setTimeout(() => { - throttledSmoothScrollToBottom(); + // throttledSmoothScrollToBottom(); }, 100); } // AiEmotion页面不执行自动滚动,避免刷新后滚动到底部