From d7ad0624b7b4a08595827d4d2d9d6d78d32131c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=91=A3=E5=AE=8F=E5=87=AF?= Date: Wed, 15 Jul 2026 16:13:03 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=8F=90=E4=BA=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- = | 0 frontend-web/.env.development | 2 +- frontend-web/public/runtime-config.js | 4 +- .../workspace/skill-display-sources.tsx | 182 +++++++++- frontend-web/src/core/auth/dashboard-input.ts | 245 ++----------- .../strategy-components/api/task-reports.ts | 85 +++++ .../task-components/sq-report-mock-data.ts | 92 ++--- frontend-web/src/utils/request.ts | 6 +- offline-backend-20260512/.env | 2 +- offline-backend-20260512/backend/CLAUDE.md | 13 +- offline-backend-20260512/backend/README.md | 9 + .../backend/app/gateway/app.py | 46 ++- .../backend/app/gateway/auth_middleware.py | 2 +- .../backend/app/gateway/csrf_middleware.py | 2 +- .../backend/app/gateway/deps.py | 14 +- .../app/gateway/routers/task_reports.py | 266 ++++++++++++++ .../app/gateway/routers/taskcop_tasks.py | 336 ++++++++++++++++++ .../app/gateway/routers/weknora_sources.py | 147 ++++++++ .../backend/extensions_config.json | 26 +- .../deerflow/persistence/models/__init__.py | 4 + .../persistence/task_reports/__init__.py | 22 ++ .../deerflow/persistence/task_reports/base.py | 47 +++ .../persistence/task_reports/memory.py | 56 +++ .../persistence/task_reports/model.py | 33 ++ .../deerflow/persistence/task_reports/sql.py | 96 +++++ .../persistence/taskcop_tasks/__init__.py | 22 ++ .../persistence/taskcop_tasks/base.py | 60 ++++ .../persistence/taskcop_tasks/memory.py | 151 ++++++++ .../persistence/taskcop_tasks/model.py | 41 +++ .../deerflow/persistence/taskcop_tasks/sql.py | 182 ++++++++++ .../backend/离线镜像部署简明指南.md | 172 +++++++++ scripts/env.sh | 5 +- scripts/setup-wsl-docker.sh | 42 +++ weknora-rerank-adapter/Dockerfile | 9 + weknora-rerank-adapter/app.py | 57 +++ weknora-rerank-adapter/requirements.txt | 3 + 36 files changed, 2194 insertions(+), 287 deletions(-) create mode 100644 = create mode 100644 frontend-web/src/strategy-components/api/task-reports.ts create mode 100644 offline-backend-20260512/backend/app/gateway/routers/task_reports.py create mode 100644 offline-backend-20260512/backend/app/gateway/routers/taskcop_tasks.py create mode 100644 offline-backend-20260512/backend/app/gateway/routers/weknora_sources.py create mode 100644 offline-backend-20260512/backend/packages/harness/deerflow/persistence/task_reports/__init__.py create mode 100644 offline-backend-20260512/backend/packages/harness/deerflow/persistence/task_reports/base.py create mode 100644 offline-backend-20260512/backend/packages/harness/deerflow/persistence/task_reports/memory.py create mode 100644 offline-backend-20260512/backend/packages/harness/deerflow/persistence/task_reports/model.py create mode 100644 offline-backend-20260512/backend/packages/harness/deerflow/persistence/task_reports/sql.py create mode 100644 offline-backend-20260512/backend/packages/harness/deerflow/persistence/taskcop_tasks/__init__.py create mode 100644 offline-backend-20260512/backend/packages/harness/deerflow/persistence/taskcop_tasks/base.py create mode 100644 offline-backend-20260512/backend/packages/harness/deerflow/persistence/taskcop_tasks/memory.py create mode 100644 offline-backend-20260512/backend/packages/harness/deerflow/persistence/taskcop_tasks/model.py create mode 100644 offline-backend-20260512/backend/packages/harness/deerflow/persistence/taskcop_tasks/sql.py create mode 100644 offline-backend-20260512/backend/离线镜像部署简明指南.md create mode 100644 scripts/setup-wsl-docker.sh create mode 100644 weknora-rerank-adapter/Dockerfile create mode 100644 weknora-rerank-adapter/app.py create mode 100644 weknora-rerank-adapter/requirements.txt diff --git a/= b/= new file mode 100644 index 00000000..e69de29b diff --git a/frontend-web/.env.development b/frontend-web/.env.development index ac6db962..3837c075 100644 --- a/frontend-web/.env.development +++ b/frontend-web/.env.development @@ -5,7 +5,7 @@ VITE_USE_REAL_DATA=true # 任务详情(登录深链 cop-task-detail)数据源:默认真实接口;改成 true 走本地假数据(consumer 外网不可达时调试用)。 -VITE_MOCK_COP_TASK_DETAIL=flase +VITE_MOCK_COP_TASK_DETAIL=true # 研判情报报告(大屏绘制智能体深链 selectSqReport)数据源:true 走本地样例假数据(真实接口未就绪时调试用);联调通过后置 false。 VITE_MOCK_SQ_REPORT=true diff --git a/frontend-web/public/runtime-config.js b/frontend-web/public/runtime-config.js index f44dd78f..e6f21405 100644 --- a/frontend-web/public/runtime-config.js +++ b/frontend-web/public/runtime-config.js @@ -85,8 +85,8 @@ window.__CM_RUNTIME_CONFIG__ = { // 登录深链任务详情是否使用本地 mock:false=真实接口;true=本地 mock。 VITE_MOCK_COP_TASK_DETAIL: "false", - // 大屏绘制 selectSqReport 是否使用本地 mock:false=真实接口;true=本地 mock。 - VITE_MOCK_SQ_REPORT: "false", + // 大屏绘制 selectSqReport 是否使用本地 mock:不在运行时强制覆盖, + // 由各环境的 .env 文件决定(开发环境为 true,生产环境为 false)。 // 静态站点模式开关;一般部署业务系统时保持 false。 VITE_STATIC_WEBSITE_ONLY: "false", diff --git a/frontend-web/src/components/workspace/skill-display-sources.tsx b/frontend-web/src/components/workspace/skill-display-sources.tsx index 8fc2f344..3993f022 100644 --- a/frontend-web/src/components/workspace/skill-display-sources.tsx +++ b/frontend-web/src/components/workspace/skill-display-sources.tsx @@ -1,4 +1,4 @@ -import { ExternalLinkIcon } from "lucide-react"; +import { ExternalLinkIcon, FileTextIcon, LoaderCircle } from "lucide-react"; import { Button } from "@/components/ui/button"; import { @@ -9,10 +9,12 @@ import { DialogTitle, } from "@/components/ui/dialog"; import type { RuntimeDisplaySource } from "@/core/skill-display/runtime"; +import { apiFetch } from "@/core/api/fetch-client"; +import { getBackendBaseURL } from "@/core/config"; import { useLocalSettings } from "@/core/settings"; import { useCitationDisplaySettings } from "@/core/system-settings/hooks"; import { cn } from "@/lib/utils"; -import { useState } from "react"; +import { useEffect, useState } from "react"; export function SkillDisplaySources({ highlightedReferenceId, @@ -51,6 +53,9 @@ export function SourceCard({ referenceTarget?: boolean; }) { const [open, setOpen] = useState(false); + const [context, setContext] = useState(null); + const [contextLoading, setContextLoading] = useState(false); + const [contextError, setContextError] = useState(null); const [settings] = useLocalSettings(); const { data: citationDisplay } = useCitationDisplaySettings(); const cleanupWords = @@ -73,6 +78,44 @@ export function SourceCard({ ].filter(Boolean); const isCitation = source.mode === "citation"; const showReferenceNumber = isCitation; + const previewTarget = parseWeKnoraPreviewUrl(source.url); + + useEffect(() => { + if (!open || !previewTarget) { + return; + } + let cancelled = false; + setContext(null); + setContextError(null); + setContextLoading(true); + const params = new URLSearchParams({ + knowledge_base_id: previewTarget.knowledgeBaseId, + chunk_id: previewTarget.chunkId, + }); + void apiFetch(`${getBackendBaseURL()}/api/weknora/source-context?${params}`) + .then(async (response) => { + const payload = (await response.json().catch(() => null)) as unknown; + if (!response.ok || !isWeKnoraSourceContextResponse(payload)) { + throw new Error(readPreviewError(payload, response.status)); + } + if (!cancelled) { + setContext(payload.data); + } + }) + .catch((error: unknown) => { + if (!cancelled) { + setContextError(error instanceof Error ? error.message : "无法加载原文上下文"); + } + }) + .finally(() => { + if (!cancelled) { + setContextLoading(false); + } + }); + return () => { + cancelled = true; + }; + }, [open, previewTarget?.chunkId, previewTarget?.knowledgeBaseId]); return ( <> @@ -114,7 +157,14 @@ export function SourceCard({ )} {source.url && ( - + previewTarget ? ( + + + 查看原文 + + ) : ( + + ) )} @@ -141,7 +191,7 @@ export function SourceCard({ )} - {source.url && ( + {source.url && !previewTarget && (