From 8ab9e36bdecf2619c1d55723f18372b65897b5a2 Mon Sep 17 00:00:00 2001 From: no99 <17663930442@163.com> Date: Fri, 15 Aug 2025 15:38:47 +0800 Subject: [PATCH] =?UTF-8?q?1.=E4=BF=AE=E6=94=B9=E7=94=A8=E6=88=B7=E5=8F=8D?= =?UTF-8?q?=E9=A6=88=E5=92=8C=E5=85=AC=E5=91=8A=E7=9A=84=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=EF=BC=9B=202.=E5=9C=A8=E6=9C=89=E5=8E=86=E5=8F=B2=E7=BA=AA?= =?UTF-8?q?=E5=BD=95=E7=9A=84=E6=83=85=E5=86=B5=E4=B8=8B=EF=BC=8C=E6=89=93?= =?UTF-8?q?=E5=BC=80=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95=EF=BC=9B=203.?= =?UTF-8?q?=E7=BD=AE=E9=A1=B6=E5=86=85=E5=AE=B9=E7=BB=99=E4=B8=80=E4=B8=AA?= =?UTF-8?q?=E7=BD=AE=E9=A1=B6=E6=A0=87=E5=BF=97=EF=BC=9B=204.=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E8=AE=B0=E5=BD=95=E5=8A=A0=E4=B8=80=E4=B8=AA=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E6=95=88=E6=9E=9C=EF=BC=9B=205.=E6=97=B6=E9=97=B4?= =?UTF-8?q?=E6=94=B9=E7=94=A8createdTime=E8=80=8C=E4=B8=8D=E6=98=AFupdated?= =?UTF-8?q?Time=EF=BC=9B=206.=E9=87=91=E7=89=9B=E5=9B=BE=E6=A0=87dataZoom?= =?UTF-8?q?=E4=B8=8D=E4=B8=8E=E6=97=A5=E6=9C=9F=E9=87=8D=E5=8F=A0=EF=BC=9B?= =?UTF-8?q?=207.=E6=90=9C=E7=B4=A2=E5=86=85=E5=AE=B9=E5=9C=A8=E6=84=8F?= =?UTF-8?q?=E5=9B=BE=E8=AF=86=E5=88=AB=E6=88=90=E5=8A=9F=E5=90=8E=E5=8A=A0?= =?UTF-8?q?=E5=85=A5=E5=88=B0=E5=8E=86=E5=8F=B2=E8=AE=B0=E5=BD=95=E5=BD=93?= =?UTF-8?q?=E4=B8=AD=208.=E7=94=9F=E6=88=90=E6=8A=A5=E5=91=8A=E8=BF=87?= =?UTF-8?q?=E7=A8=8B=E4=B8=AD=EF=BC=8C=E7=82=B9=E5=87=BB=E5=8E=86=E5=8F=B2?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E5=90=8E=E4=B8=8D=E5=86=8D=E5=9C=A8=E5=8E=86?= =?UTF-8?q?=E5=8F=B2=E8=AE=B0=E5=BD=95=E6=95=B0=E6=8D=AE=E4=B8=8B=E6=96=B9?= =?UTF-8?q?=E7=BB=A7=E7=BB=AD=E6=89=93=E5=8D=B0=E6=9C=AA=E6=89=93=E5=8D=B0?= =?UTF-8?q?=E7=9A=84=E5=86=85=E5=AE=B9=209.=E5=9B=BE=E6=A0=87=E6=97=A5?= =?UTF-8?q?=E6=9C=9F=E5=B1=95=E7=A4=BA=E4=B8=8D=E5=85=A8=2010.=E7=AC=AC?= =?UTF-8?q?=E4=B8=80=E6=AC=A1=E7=82=B9=E5=87=BB=E8=AF=AD=E9=9F=B3=E6=92=AD?= =?UTF-8?q?=E6=8A=A5=E4=BC=9A=E6=BB=91=E5=88=B0=E5=BA=95=E9=83=A8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=2011.=E8=BE=93=E5=85=A5=E6=A1=86=E7=A6=81?= =?UTF-8?q?=E7=94=A8=E8=BF=87=E7=A8=8B=E4=B8=AD=E6=97=A0=E6=B3=95=E5=8F=91?= =?UTF-8?q?=E9=80=81=E6=B6=88=E6=81=AF=2012.=E4=BB=8E=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=8F=8D=E9=A6=88=E9=A1=B5=E9=9D=A2=E5=92=8C=E5=85=AC=E5=91=8A?= =?UTF-8?q?=E9=A1=B5=E9=9D=A2=E8=BF=94=E5=9B=9E=E6=97=B6=EF=BC=8C=E6=A0=87?= =?UTF-8?q?=E7=AD=BE=E6=A0=8F=E9=80=89=E4=B8=AD=E7=8A=B6=E6=80=81=E6=B6=88?= =?UTF-8?q?=E5=A4=B1=E7=9A=84=E9=97=AE=E9=A2=98=2013.=E4=BB=8E=E6=83=85?= =?UTF-8?q?=E7=BB=AA=E5=A4=A7=E6=A8=A1=E5=9E=8B=E5=88=B0=E5=A4=BA=E5=AE=9D?= =?UTF-8?q?=E5=A5=87=E5=85=B5=E5=A4=A7=E6=A8=A1=E5=9E=8B=E6=97=B6=E4=BC=9A?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E5=88=B0=E5=BA=95=E9=83=A8=E7=9A=84=E9=97=AE?= =?UTF-8?q?=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/views/AIchat.vue | 117 +++++++++++++++++-------- src/views/components/HistoryRecord.vue | 156 +++++++++++++++++++++++---------- src/views/homePage.vue | 16 ++-- 3 files changed, 200 insertions(+), 89 deletions(-) diff --git a/src/views/AIchat.vue b/src/views/AIchat.vue index f84eb9e..7493739 100644 --- a/src/views/AIchat.vue +++ b/src/views/AIchat.vue @@ -145,7 +145,7 @@ const playNextAudio = () => { setTimeout(() => { isCallingPlayNext = false; playNextAudio(); - }, 500); + }, 200); } else { console.log("🎉 所有音频播放完成,清除音频实例"); chatStore.messages[chatStore.currentUserIndex].audioStatus = false; @@ -748,7 +748,6 @@ const createTypingEffect = (message, content, speed) => { if (message.end) { chatStore.getUserCount(); chatStore.isLoading = false; - chatStore.searchRecord = true; console.log("打印完毕,接触输入框禁用状态"); emit("enableInput"); } @@ -1101,6 +1100,8 @@ watch( console.log(codeData.value, "codeData"); // 根据意图识别结果判断 if (result.code == 200) { + // 意图识别成功后,更新历史记录状态 + chatStore.searchRecord = true; // 获取到股票名称后,继续思考过程 if (thinkingMessageRef && codeData.value.name) { await continueThinkingProcess( @@ -2417,6 +2418,12 @@ watch( return; } try { + // 解开输入框 + emit("enableInput"); + // 清除打字机队列和状态 + typingQueue.value = []; + isTypingInProgress.value = false; + // 清空聊天框内容 chatStore.messages = []; @@ -3286,10 +3293,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, @@ -3324,10 +3331,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, @@ -3339,11 +3346,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, }, }, }, @@ -3359,10 +3366,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, @@ -3374,11 +3381,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, }, }, }, @@ -3465,53 +3472,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, }, @@ -3556,6 +3566,7 @@ function KlineCanvsEcharts(containerId) { axisLabel: { show: true, interval: "auto", + fontSize: window.innerWidth > 768 ? 12 : 9, }, }, ], @@ -3652,11 +3663,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: [ @@ -4092,6 +4107,11 @@ function KlineCanvsEcharts(containerId) { type: "solid", }, data: [{ yAxis: 20 }], + label: { + normal: { + fontSize: window.innerWidth > 768 ? 12 : 9, + }, + }, }, }, { @@ -4109,6 +4129,11 @@ function KlineCanvsEcharts(containerId) { type: "solid", }, data: [{ yAxis: 50 }], + label: { + normal: { + fontSize: window.innerWidth > 768 ? 12 : 9, + }, + }, }, }, { @@ -4126,6 +4151,11 @@ function KlineCanvsEcharts(containerId) { type: "solid", }, data: [{ yAxis: 80 }], + label: { + normal: { + fontSize: window.innerWidth > 768 ? 12 : 9, + }, + }, }, }, { @@ -4144,6 +4174,11 @@ function KlineCanvsEcharts(containerId) { type: "solid", }, data: [{ yAxis: 100 }], + label: { + normal: { + fontSize: window.innerWidth > 768 ? 12 : 9, + }, + }, }, }, ], @@ -4465,7 +4500,7 @@ onUnmounted(() => {
-
+

暂无数据

@@ -4951,6 +4986,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 14e4298..cf28e82 100644 --- a/src/views/components/HistoryRecord.vue +++ b/src/views/components/HistoryRecord.vue @@ -25,23 +25,23 @@
icon
@@ -95,9 +95,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") }}
@@ -167,17 +185,17 @@
-
+
-
+
icon
@@ -239,9 +257,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") }}
@@ -313,27 +349,27 @@
-
用户反馈
+
公告
icon -
公告
+
用户反馈
@@ -415,12 +451,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); @@ -428,12 +476,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; }); @@ -441,13 +489,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) ); @@ -456,24 +504,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); }); @@ -573,28 +621,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); @@ -651,6 +699,7 @@ defineExpose({ isCollapsed, toggleCollapse, getHistoryList, + selectedRecordId, }); // 生命周期 @@ -702,6 +751,7 @@ onMounted(() => { } .mobileCollapsed { + /* max-width: 400px */ width: 80vw; } @@ -909,6 +959,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%; @@ -935,6 +989,14 @@ onMounted(() => { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; + display: flex; +} + +.top-icon { + margin-left: 5px; + color: white; + height: auto; + width: 15px; } .record-time { 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页面不执行自动滚动,避免刷新后滚动到底部