Kaynağa Gözat

feat: Tab2 自定义文本召回支持 URL 参数自动跳转 (?queryText=&configCode=)

- 新增 readUrlQueryText / readUrlConfigCode 工具函数
- 顶层 Tabs 根据 URL 动态决定初始 Tab(queryText → text, 否则 video)
- TextRecallTab 读 URL 初值, 挂载后 0 点击自动召回
- configCode 仅接受 CONFIG_OPTIONS 内的值, 无效回退默认 VIDEO_TOPIC
- 不传任何参数时行为完全沿用原状

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
刘立冬 3 gün önce
ebeveyn
işleme
ea6ac76b18
1 değiştirilmiş dosya ile 37 ekleme ve 5 silme
  1. 37 5
      src/pages/RecallTestPage.tsx

+ 37 - 5
src/pages/RecallTestPage.tsx

@@ -53,6 +53,22 @@ function readUrlVideoId(): number | null {
   return Number.isFinite(n) && n > 0 ? n : null
 }
 
+/** 从 URL ?queryText=xxx 读取,空值返 null */
+function readUrlQueryText(): string | null {
+  const raw = new URLSearchParams(window.location.search).get('queryText')
+  if (!raw) return null
+  const trimmed = raw.trim()
+  return trimmed.length > 0 ? trimmed : null
+}
+
+/** 从 URL ?configCode=xxx 读取并校验,只接受 CONFIG_OPTIONS 内的值,无效或缺省返 null */
+function readUrlConfigCode(): string | null {
+  const raw = new URLSearchParams(window.location.search).get('configCode')
+  if (!raw) return null
+  const upper = raw.trim().toUpperCase()
+  return CONFIG_OPTIONS.some((o) => o.value === upper) ? upper : null
+}
+
 /** 从召回结果里剔除指定视频ID, 同时刷新 modality 计数 */
 function filterOutSelf(data: RecallResultVO, excludeId: number | null): RecallResultVO {
   if (!excludeId) return data
@@ -72,10 +88,13 @@ const CONFIG_OPTIONS = [
 ]
 
 export default function RecallTestPage() {
+  // URL 上有 queryText → 默认进入 Tab2 (优先级高于 videoId,与 Grafana 跳转用例一致)
+  // 用 defaultActiveKey 而非受控 activeKey,保留用户后续手动切 Tab 的自由
+  const initialTabKey = readUrlQueryText() ? 'text' : 'video'
   return (
     <Tabs
       className="recall-main-tabs"
-      defaultActiveKey="video"
+      defaultActiveKey={initialTabKey}
       size="large"
       items={[
         {
@@ -424,13 +443,17 @@ function RecallTitle({
 // Tab2: 文本输入 → 文本召回
 // ============================================================================
 function TextRecallTab() {
-  const [queryText, setQueryText] = useState('')
-  const [configCode, setConfigCode] = useState('VIDEO_TOPIC')
+  /** URL ?queryText=xxx&configCode=yyy 落地参数,缺省走原有空白态 */
+  const urlQueryText = readUrlQueryText()
+  const urlConfigCode = readUrlConfigCode()
+
+  const [queryText, setQueryText] = useState(urlQueryText ?? '')
+  const [configCode, setConfigCode] = useState(urlConfigCode ?? 'VIDEO_TOPIC')
   const [topN, setTopN] = useState<number>(10)
   const [result, setResult] = useState<RecallResultVO | null>(null)
   const [loading, setLoading] = useState(false)
 
-  const onSubmit = async () => {
+  const onSubmit = useCallback(async () => {
     if (!queryText.trim()) {
       message.warning('请输入查询文本')
       return
@@ -445,7 +468,16 @@ function TextRecallTab() {
     } finally {
       setLoading(false)
     }
-  }
+  }, [queryText, configCode, topN])
+
+  /** URL 上有 queryText 时, 挂载后自动触发一次召回 (Grafana 跳转 0 点击) */
+  const autoSearchedRef = useRef(false)
+  useEffect(() => {
+    if (autoSearchedRef.current) return
+    if (!urlQueryText) return
+    autoSearchedRef.current = true
+    onSubmit()
+  }, [urlQueryText, onSubmit])
 
   return (
     <Space direction="vertical" size={16} style={{ width: '100%' }}>