From 1094e82e88b0458e9c9dc76a2d1d9b645c4aa8cc Mon Sep 17 00:00:00 2001 From: fish Date: Sun, 10 May 2026 16:31:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=93=81=E7=A7=8D=E6=89=93=E5=88=86=E7=BB=93?= =?UTF-8?q?=E6=9E=9C=E5=8D=A1=E5=A2=9E=E5=8A=A0AI=E5=88=86=E6=9E=90?= =?UTF-8?q?=E5=85=A5=E5=8F=A3=EF=BC=8C=E6=89=93=E5=AE=8C=E5=88=86=E5=8F=AF?= =?UTF-8?q?=E7=9B=B4=E6=8E=A5=E9=97=AEAI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web/frontend/src/views/ScoresView.vue | 64 +++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/web/frontend/src/views/ScoresView.vue b/web/frontend/src/views/ScoresView.vue index 0631f19..2e88785 100644 --- a/web/frontend/src/views/ScoresView.vue +++ b/web/frontend/src/views/ScoresView.vue @@ -74,6 +74,40 @@ function signalIcon(s: string) { return '' } +// AI 分析 +const aiLoading = ref(false) +const aiContent = ref('') +const aiError = ref('') +let aiES: EventSource | null = null + +function closeAI() { + aiES?.close() + aiES = null + aiLoading.value = false +} + +async function askAI() { + if (!scoreResult.value) return + closeAI() + aiLoading.value = true + aiContent.value = '' + aiError.value = '' + + const ts = encodeURIComponent(scoreResult.value.ts_code) + const td = encodeURIComponent(scoreResult.value.trade_date) + aiES = new EventSource(`/api/v1/ai/analyze?ts_code=${ts}&trade_date=${td}`) + aiES.addEventListener('token', (e) => { aiContent.value += e.data }) + aiES.addEventListener('error', (e) => { + aiError.value = (e as any)?.data || '请求失败' + closeAI() + }) + aiES.addEventListener('done', () => closeAI()) + aiES.onerror = () => { + if (!aiContent.value) aiError.value = '连接中断' + closeAI() + } +} + // 历史查询(折叠) const showHistory = ref(false) const historyFilter = reactive<{ @@ -325,6 +359,36 @@ onMounted(async () => { .result-card { margin-top: 4px; } +.ai-section { + margin-top: 12px; +} +.ai-card { + border: 1px solid var(--el-border-color); + border-radius: 6px; + margin-top: 8px; + overflow: hidden; +} +.ai-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 8px 12px; + background: var(--el-fill-color-light); + font-weight: 600; +} +.ai-body { + padding: 12px; +} +.ai-text { + line-height: 1.8; + white-space: pre-wrap; +} +.ai-error { + color: var(--el-color-danger); +} +.ai-loading { + color: var(--el-text-color-secondary); +} .history-header { display: flex; align-items: center;