| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- import { useMemo, useState } from 'react'
- import { flatDetailItems, isFinalKnowledge, itemBrief, itemMediaUrl } from './model.js'
- const PLATFORM_FILTERS = [
- ['all', '全部'],
- ['weixin', '微信'],
- ['xiaohongshu', '小红书'],
- ['douyin', '抖音'],
- ]
- export default function SearchResultColumn({ selected, detail, loading, error, onKnowledgeClick }) {
- const [platformFilter, setPlatformFilter] = useState('all')
- const allItems = useMemo(() => {
- return selected ? [...flatDetailItems(detail)].sort((a, b) => {
- const ak = isFinalKnowledge(a) ? 0 : 1
- const bk = isFinalKnowledge(b) ? 0 : 1
- if (ak !== bk) return ak - bk
- return (a.platform || '').localeCompare(b.platform || '') || (a.title || '').localeCompare(b.title || '')
- }) : []
- }, [detail, selected])
- const platformCounts = useMemo(() => {
- return allItems.reduce((counts, item) => {
- counts[item.platform] = (counts[item.platform] || 0) + 1
- return counts
- }, {})
- }, [allItems])
- const items = platformFilter === 'all'
- ? allItems
- : allItems.filter((item) => item.platform === platformFilter)
- const totalCount = allItems.length
- const selectedFilterLabel = PLATFORM_FILTERS.find(([key]) => key === platformFilter)?.[1] || '全部'
- return (
- <div className="axcol qresult-col">
- <div className="axhd qresult-hd">
- <div className="qresult-title-row">
- <div className="axis-title">
- <span className="query-search-icon">帖</span>
- <span>
- 搜索结果{selected ? `(${platformFilter === 'all' ? totalCount : `${selectedFilterLabel} ${items.length}/${totalCount}`}贴)` : ''}
- </span>
- </div>
- <div className="platform-filter" aria-label="按平台筛选搜索结果">
- {PLATFORM_FILTERS.map(([key, label]) => {
- const count = key === 'all' ? totalCount : platformCounts[key] || 0
- return (
- <button
- className={platformFilter === key ? 'on' : ''}
- disabled={!selected || count === 0}
- key={key}
- type="button"
- onClick={() => setPlatformFilter(key)}
- >
- {label}<span>{count}</span>
- </button>
- )
- })}
- </div>
- </div>
- <div className="qresult-sub">
- {selected ? selected.query : '选择 Query 查看帖子'}
- </div>
- </div>
- <div className="qresult-list">
- {!selected && <div className="qresult-empty">点击左侧 Query 词后,这里展示本次搜到的帖子。</div>}
- {selected && loading && <div className="qresult-empty">加载搜索结果...</div>}
- {selected && error && <div className="qresult-empty error">{error}</div>}
- {selected && !loading && !error && allItems.length === 0 && (
- <div className="qresult-empty">这个 Query 暂无搜索结果。若后台还在运行,请等待数据写入。</div>
- )}
- {selected && !loading && !error && allItems.length > 0 && items.length === 0 && (
- <div className="qresult-empty">当前筛选下没有{selectedFilterLabel}帖子。</div>
- )}
- {items.map((item) => {
- const knowledge = isFinalKnowledge(item)
- const cover = itemMediaUrl(item)
- const confidence = item.classification?.confidence
- return (
- <article className={`result-mini ${knowledge ? 'knowledge' : ''}`} key={item.id}>
- <button
- className="result-mini-click"
- type="button"
- onClick={() => { window.location.hash = `/item/${item.id}` }}
- >
- {cover && <img src={cover} alt="" loading="lazy" />}
- <div className="result-mini-main">
- <div className="result-mini-title">{item.title || '无标题'}</div>
- <div className="result-mini-tags">
- <span className={`platform-mini ${item.platform_tone}`}>{item.platform_label}</span>
- <span className={knowledge ? 'knowledge-mini yes' : 'knowledge-mini'}>{knowledge ? '创作知识' : '未形成知识'}</span>
- {typeof confidence === 'number' && <span className="score-mini">{confidence.toFixed(2)}</span>}
- </div>
- {itemBrief(item) && <div className="result-mini-text">{itemBrief(item)}</div>}
- </div>
- </button>
- <div className="result-mini-actions">
- <button
- className="mini-detail-btn detail"
- type="button"
- onClick={() => { window.location.hash = `/item/${item.id}` }}
- >
- 查看详情
- </button>
- {knowledge && (
- <button
- className="mini-detail-btn knowledge"
- type="button"
- onClick={() => onKnowledgeClick?.(item.id)}
- >
- 查看创作知识
- </button>
- )}
- </div>
- </article>
- )
- })}
- </div>
- </div>
- )
- }
|