/* * @Author: ZhaoYing * @Date: 2026-02-03 18:32:23 * @Last Modified by: ZhaoYing * @Last Modified time: 2026-03-27 14:57:34 */ import { type FC, useEffect, useState } from 'react' import { useTranslation } from 'react-i18next' import { useParams } from 'react-router-dom' import { Skeleton, Image, Flex } from 'antd'; import clsx from 'clsx' import RbCard from '@/components/RbCard/Card' import AudioPlayer from './AudioPlayer' import VideoPlayer from './VideoPlayer' import { getPerceptualLastVisual, getPerceptualLastListen, getPerceptualLastText, } from '@/api/memory' import Empty from '@/components/Empty'; /** * Perceptual last info item structure * @property {string} id - Item ID * @property {string} file_name - File name * @property {string} file_ext - File extension * @property {string} file_path - File path URL * @property {number} storage_type - Storage type * @property {string} summary - Content summary * @property {string[]} keywords - Keywords * @property {string} topic - Topic * @property {string} domain - Domain * @property {number | string} created_time - Creation time * @property {string[]} scene - Scene information * @property {number} speaker_count - Speaker count * @property {number} section_count - Section count */ interface PerceptualLastInfoItem { id: string; file_name: string; file_ext: string; file_path: string; storage_type: number; summary: string; keywords: string[]; topic: string; domain: string; created_time: number | string; scene: string[] speaker_count: number; section_count: number; } /** * Field keys for different perceptual types */ const KEYS: Record = { last_visual: ['summary', 'keywords', 'topic', 'domain', 'scene'], last_listen: ['summary', 'keywords', 'topic', 'domain', 'speaker_count'], last_text: ['summary', 'keywords', 'topic', 'domain', 'section_count'], } /** * PerceptualLastInfo Component * Displays the last perceptual memory (visual, audio, or text) * Shows file preview and metadata based on perceptual type */ const PerceptualLastInfo: FC = () => { const { t } = useTranslation() const { id } = useParams() const [loading, setLoading] = useState(false) const [data, setData] = useState({} as PerceptualLastInfoItem) const [type, setType] = useState('last_visual') const [fileSize, setFileSize] = useState('') useEffect(() => { if (!id) return getData() }, [id, type]) const getData = () => { if (!id || !type) return setLoading(true) setFileSize('') const request = type === 'last_visual' ? getPerceptualLastVisual(id) : type === 'last_listen' ? getPerceptualLastListen(id) : getPerceptualLastText(id) request.then((res) => { const response = res as PerceptualLastInfoItem setData(response) setLoading(false) if (response.file_path) { fetch(response.file_path, { method: 'GET' }) .then(r => { const bytes = Number(r.headers.get('content-length')) if (!bytes) return setFileSize(bytes < 1024 * 1024 ? `${(bytes / 1024).toFixed(1)} KB` : `${(bytes / 1024 / 1024).toFixed(1)} MB`) }) .catch(() => {}) } }) .finally(() => { setLoading(false) }) } const handleDownload = () => { if (!data.file_path) return window.open(data.file_path, '_blank') } return ( {Object.keys(KEYS).map(key => (
setType(key)} >{t(`perceptualDetail.${key}`)}
))}
{loading ? : {data.file_path ? <> {/\.(jpg|jpeg|png|gif|webp|svg)$/i.test(data.file_name) ? {data.file_name} : /\.(mp4|webm|ogg|mov)$/i.test(data.file_name) ? : /\.(mp3|wav|ogg|m4a|aac)$/i.test(data.file_name) ? :
{data.file_name}
{fileSize || '-'}
} :
} {KEYS[type].map(key => { const value = (data as any)[key] return (
{t(`perceptualDetail.${key}`)}
{typeof value === 'string' ?
{value}
: Array.isArray(value) ? {value.map((vo, index) =>
{vo}
)}
: '-' }
) })}
}
) } export default PerceptualLastInfo