style(web): translate the comments in the src/views directory into English
This commit is contained in:
@@ -1,4 +1,15 @@
|
||||
import { type FC, useEffect, useState, forwardRef, useImperativeHandle } from 'react'
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:34:23
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:34:23
|
||||
*/
|
||||
/**
|
||||
* About Me Component
|
||||
* Displays user summary, personality, and core values
|
||||
*/
|
||||
|
||||
import { useEffect, useState, forwardRef, useImperativeHandle } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Skeleton } from 'antd';
|
||||
@@ -12,6 +23,9 @@ import {
|
||||
import type { AboutMeRef } from '../types'
|
||||
|
||||
|
||||
/**
|
||||
* User summary data
|
||||
*/
|
||||
interface Data {
|
||||
user_summary: string;
|
||||
personality: string;
|
||||
@@ -30,6 +44,7 @@ const AboutMe = forwardRef<AboutMeRef>((_props, ref) => {
|
||||
getData()
|
||||
}, [id])
|
||||
|
||||
/** Fetch user summary data */
|
||||
const getData = () => {
|
||||
if (!id) return
|
||||
setLoading(true)
|
||||
@@ -41,7 +56,7 @@ const AboutMe = forwardRef<AboutMeRef>((_props, ref) => {
|
||||
setLoading(false)
|
||||
})
|
||||
}
|
||||
// 暴露给父组件的方法
|
||||
/** Expose methods to parent component */
|
||||
useImperativeHandle(ref, () => ({
|
||||
getData,
|
||||
}));
|
||||
|
||||
@@ -1,16 +1,33 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:34:16
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:34:16
|
||||
*/
|
||||
import { type FC, useRef, useEffect } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
|
||||
import Loading from '@/components/Empty/Loading'
|
||||
import Empty from '@/components/Empty'
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
|
||||
/**
|
||||
* Props for ActivationMetricsPieCard component
|
||||
* @property {Array<Record<string, string | number>>} chartData - Activation value distribution data
|
||||
* @property {boolean} loading - Loading state
|
||||
*/
|
||||
interface ActivationMetricsPieCardProps {
|
||||
chartData: Array<Record<string, string | number>>;
|
||||
loading: boolean;
|
||||
}
|
||||
const Colors = ['#155EEF', '#FFB048', '#FF5D34']
|
||||
|
||||
/**
|
||||
* ActivationMetricsPieCard Component
|
||||
* Displays activation value distribution as a donut chart with legend
|
||||
* Shows percentage distribution of different activation levels
|
||||
*/
|
||||
const ActivationMetricsPieCard: FC<ActivationMetricsPieCardProps> = ({ chartData, loading }) => {
|
||||
const { t } = useTranslation()
|
||||
const chartRef = useRef<ReactEcharts>(null);
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:34:10
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:34:10
|
||||
*/
|
||||
/**
|
||||
* Card Component
|
||||
* Reusable card wrapper with theme support
|
||||
*/
|
||||
|
||||
import { type FC, type ReactNode } from 'react'
|
||||
import clsx from 'clsx'
|
||||
|
||||
/**
|
||||
* Component props
|
||||
*/
|
||||
interface CardProps {
|
||||
title?: string;
|
||||
children: ReactNode;
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:34:04
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:34:04
|
||||
*/
|
||||
/**
|
||||
* Conversation Memory Component
|
||||
* Displays RAG conversation memory content list
|
||||
*/
|
||||
|
||||
import { type FC, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Skeleton } from 'antd';
|
||||
import { Skeleton, List } from 'antd';
|
||||
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import Empty from '@/components/Empty';
|
||||
import { List } from 'antd';
|
||||
import Markdown from '@/components/Markdown'
|
||||
import {
|
||||
getRagContent
|
||||
@@ -20,6 +31,7 @@ const ConversationMemory:FC = () => {
|
||||
if (!id) return
|
||||
getList()
|
||||
}, [id])
|
||||
/** Fetch conversation memory list */
|
||||
const getList = () => {
|
||||
if (!id) return
|
||||
setLoading(true)
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:33:44
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:33:44
|
||||
*/
|
||||
import { type FC, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
|
||||
import Empty from '@/components/Empty'
|
||||
import Loading from '@/components/Empty/Loading'
|
||||
import type { Emotion } from '../pages/GraphDetail'
|
||||
|
||||
/**
|
||||
* Props for EmotionLine component
|
||||
* @property {Emotion[]} chartData - Emotion data over time
|
||||
* @property {boolean} [loading] - Loading state
|
||||
*/
|
||||
interface EmotionLineProps {
|
||||
chartData: Emotion[];
|
||||
loading?: boolean;
|
||||
@@ -12,6 +24,11 @@ interface EmotionLineProps {
|
||||
|
||||
const Colors = ['#369F21', '#155EEF', '#FF5D34']
|
||||
|
||||
/**
|
||||
* EmotionLine Component
|
||||
* Displays emotion intensity trends over time as a multi-line chart
|
||||
* Shows different emotion types with smooth lines and area fills
|
||||
*/
|
||||
const EmotionLine: FC<EmotionLineProps> = ({ chartData, loading }) => {
|
||||
const { t } = useTranslation()
|
||||
const chartRef = useRef<ReactEcharts>(null);
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:33:39
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:33:39
|
||||
*/
|
||||
import { type FC, useEffect, useState, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
@@ -8,10 +14,22 @@ import Empty from '@/components/Empty'
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import { getWordCloud } from '@/api/memory'
|
||||
|
||||
/**
|
||||
* Tag list data structure
|
||||
* @property {Array} keywords - List of keywords with emotion data
|
||||
* @property {number} total_keywords - Total number of keywords
|
||||
*/
|
||||
interface TagList {
|
||||
keywords: Array<{ keyword: string; frequency: number; emotion_type: string; avg_intensity: number; }>;
|
||||
total_keywords: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* EmotionTags Component
|
||||
* Displays emotion-tagged keywords as a word cloud
|
||||
* Each keyword is colored based on its associated emotion type
|
||||
* Shows emotion statistics summary at the bottom
|
||||
*/
|
||||
const EmotionTags: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const { id } = useParams()
|
||||
@@ -32,6 +50,11 @@ const EmotionTags: FC = () => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Get color for emotion type
|
||||
* @param {string} emotionType - Emotion type (joy, anger, sadness, etc.)
|
||||
* @returns {string} Color hex code
|
||||
*/
|
||||
const getEmotionColor = (emotionType: string) => {
|
||||
const colors: Record<string, string> = {
|
||||
joy: '#52c41a',
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:33:30
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:33:30
|
||||
*/
|
||||
/**
|
||||
* End User Profile Component
|
||||
* Displays and manages end user profile information
|
||||
*/
|
||||
|
||||
import { forwardRef, useImperativeHandle, useEffect, useState, useRef, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
@@ -11,6 +22,9 @@ import {
|
||||
import EndUserProfileModal from './EndUserProfileModal'
|
||||
import type { EndUser, EndUserProfileModalRef, EndUserProfileRef } from '../types'
|
||||
|
||||
/**
|
||||
* Component props
|
||||
*/
|
||||
interface EndUserProfileProps {
|
||||
onDataLoaded?: (data: { other_name?: string; id: string }) => void
|
||||
}
|
||||
@@ -27,6 +41,7 @@ const EndUserProfile = forwardRef<EndUserProfileRef, EndUserProfileProps>(({ onD
|
||||
getData()
|
||||
}, [id])
|
||||
|
||||
/** Fetch profile data */
|
||||
const getData = () => {
|
||||
if (!id) return
|
||||
setLoading(true)
|
||||
@@ -43,6 +58,7 @@ const EndUserProfile = forwardRef<EndUserProfileRef, EndUserProfileProps>(({ onD
|
||||
setLoading(false)
|
||||
})
|
||||
}
|
||||
/** Format profile items for display */
|
||||
const formatItems = useCallback(() => {
|
||||
return ['other_name', 'position', 'department', 'contact', 'phone', 'hire_date'].map(key => ({
|
||||
key,
|
||||
@@ -50,6 +66,7 @@ const EndUserProfile = forwardRef<EndUserProfileRef, EndUserProfileProps>(({ onD
|
||||
children: key === 'hire_date' && data?.[key] ? dayjs(data[key as keyof EndUser]).format('YYYY-MM-DD') : String(data?.[key as keyof EndUser] || '-'),
|
||||
}))
|
||||
}, [data])
|
||||
/** Open edit modal */
|
||||
const handleEdit = () => {
|
||||
if (!data) return
|
||||
endUserProfileModalRef.current?.handleOpen(data)
|
||||
|
||||
@@ -1,14 +1,28 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:33:21
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:33:21
|
||||
*/
|
||||
/**
|
||||
* End User Profile Modal
|
||||
* Modal for editing end user profile information
|
||||
*/
|
||||
|
||||
import { forwardRef, useImperativeHandle, useState } from 'react';
|
||||
import { Form, Input, App, DatePicker } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
import type { EndUser, EndUserProfileModalRef } from '../types'
|
||||
import RbModal from '@/components/RbModal'
|
||||
import { updatedEndUserProfile, } from '@/api/memory'
|
||||
import dayjs from 'dayjs';
|
||||
|
||||
const FormItem = Form.Item;
|
||||
|
||||
/**
|
||||
* Component props
|
||||
*/
|
||||
interface EndUserProfileModalProps {
|
||||
refresh: () => void;
|
||||
}
|
||||
@@ -24,13 +38,14 @@ const EndUserProfileModal = forwardRef<EndUserProfileModalRef, EndUserProfileMod
|
||||
|
||||
const values = Form.useWatch([], form);
|
||||
|
||||
// 封装取消方法,添加关闭弹窗逻辑
|
||||
/** Close modal and reset form */
|
||||
const handleClose = () => {
|
||||
setVisible(false);
|
||||
form.resetFields();
|
||||
setLoading(false)
|
||||
};
|
||||
|
||||
/** Open modal with user data */
|
||||
const handleOpen = (user: EndUser) => {
|
||||
form.setFieldsValue({
|
||||
...user,
|
||||
@@ -39,7 +54,7 @@ const EndUserProfileModal = forwardRef<EndUserProfileModalRef, EndUserProfileMod
|
||||
});
|
||||
setVisible(true);
|
||||
};
|
||||
// 封装保存方法,添加提交逻辑
|
||||
/** Save profile changes */
|
||||
const handleSave = () => {
|
||||
form
|
||||
.validateFields()
|
||||
@@ -64,7 +79,7 @@ const EndUserProfileModal = forwardRef<EndUserProfileModalRef, EndUserProfileMod
|
||||
});
|
||||
}
|
||||
|
||||
// 暴露给父组件的方法
|
||||
/** Expose methods to parent component */
|
||||
useImperativeHandle(ref, () => ({
|
||||
handleOpen,
|
||||
handleClose
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { forwardRef, useImperativeHandle, useState, useCallback } from 'react';
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:33:16
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:33:16
|
||||
*/
|
||||
import { forwardRef, useImperativeHandle, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Descriptions, Skeleton } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -9,6 +15,17 @@ import { formatDateTime } from '@/utils/format'
|
||||
import type { ExplicitDetailModalRef, EpisodicMemory, SemanticMemory } from '../pages/ExplicitDetail'
|
||||
|
||||
|
||||
/**
|
||||
* Explicit memory detail data structure
|
||||
* @property {string} memory_type - Type of memory (episodic or semantic)
|
||||
* @property {string} title - Memory title
|
||||
* @property {string} content - Memory content
|
||||
* @property {string} emotion - Associated emotion
|
||||
* @property {number} created_at - Creation timestamp
|
||||
* @property {string} name - Memory name
|
||||
* @property {string} core_definition - Core definition for semantic memory
|
||||
* @property {string} detailed_notes - Detailed notes
|
||||
*/
|
||||
interface Data {
|
||||
memory_type: 'episodic' | 'semantic';
|
||||
title: string;
|
||||
@@ -20,6 +37,12 @@ interface Data {
|
||||
core_definition: string;
|
||||
detailed_notes: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* ExplicitDetailModal Component
|
||||
* Modal dialog for displaying detailed information about explicit memories
|
||||
* Shows different fields based on memory type (episodic vs semantic)
|
||||
*/
|
||||
const ExplicitDetailModal = forwardRef<ExplicitDetailModalRef>((_props, ref) => {
|
||||
const { t } = useTranslation();
|
||||
const { id } = useParams()
|
||||
@@ -27,12 +50,18 @@ const ExplicitDetailModal = forwardRef<ExplicitDetailModalRef>((_props, ref) =>
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [data, setData] = useState<Data>({} as Data)
|
||||
|
||||
// 封装取消方法,添加关闭弹窗逻辑
|
||||
/**
|
||||
* Close modal and reset data
|
||||
*/
|
||||
const handleClose = () => {
|
||||
setVisible(false);
|
||||
setData({} as Data)
|
||||
};
|
||||
|
||||
/**
|
||||
* Open modal and load memory details
|
||||
* @param {EpisodicMemory | SemanticMemory} vo - Memory object
|
||||
*/
|
||||
const handleOpen = (vo: EpisodicMemory | SemanticMemory) => {
|
||||
setLoading(true)
|
||||
getExplicitMemoryDetails({
|
||||
@@ -48,6 +77,11 @@ const ExplicitDetailModal = forwardRef<ExplicitDetailModalRef>((_props, ref) =>
|
||||
})
|
||||
};
|
||||
|
||||
/**
|
||||
* Get color for emotion type
|
||||
* @param {string} emotionType - Emotion type
|
||||
* @returns {string} Color hex code
|
||||
*/
|
||||
const getEmotionColor = (emotionType: string) => {
|
||||
const colors: Record<string, string> = {
|
||||
joy: '#52c41a',
|
||||
@@ -60,7 +94,9 @@ const ExplicitDetailModal = forwardRef<ExplicitDetailModalRef>((_props, ref) =>
|
||||
return colors[emotionType] || '#8c8c8c'
|
||||
}
|
||||
|
||||
// 暴露给父组件的方法
|
||||
/**
|
||||
* Expose methods to parent component
|
||||
*/
|
||||
useImperativeHandle(ref, () => ({
|
||||
handleOpen,
|
||||
}));
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:33:10
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:33:10
|
||||
*/
|
||||
import { forwardRef, useImperativeHandle, useState } from 'react';
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Form, Slider } from 'antd';
|
||||
@@ -7,10 +13,19 @@ import RbModal from '@/components/RbModal'
|
||||
import { forgetTrigger } from '@/api/memory'
|
||||
import type { ForgetRefreshModalRef } from '../pages/ForgetDetail'
|
||||
|
||||
/**
|
||||
* Props for ForgetRefreshModal component
|
||||
* @property {Function} refresh - Callback function to refresh data
|
||||
*/
|
||||
interface ForgetRefreshModalProps {
|
||||
refresh: (flag: boolean) => void;
|
||||
}
|
||||
|
||||
/**
|
||||
* ForgetRefreshModal Component
|
||||
* Modal for triggering memory forgetting process with configurable parameters
|
||||
* Allows setting max merge batch size and minimum days since access
|
||||
*/
|
||||
const ForgetRefreshModal = forwardRef<ForgetRefreshModalRef, ForgetRefreshModalProps>(({
|
||||
refresh
|
||||
}, ref) => {
|
||||
@@ -21,18 +36,26 @@ const ForgetRefreshModal = forwardRef<ForgetRefreshModalRef, ForgetRefreshModalP
|
||||
const [loading, setLoading] = useState(false)
|
||||
const values = Form.useWatch([], form);
|
||||
|
||||
// 封装取消方法,添加关闭弹窗逻辑
|
||||
/**
|
||||
* Close modal and reset form
|
||||
*/
|
||||
const handleClose = () => {
|
||||
setVisible(false);
|
||||
form.resetFields();
|
||||
setLoading(false)
|
||||
};
|
||||
|
||||
/**
|
||||
* Open modal and reset form
|
||||
*/
|
||||
const handleOpen = () => {
|
||||
form.resetFields();
|
||||
setVisible(true);
|
||||
};
|
||||
// 封装保存方法,添加提交逻辑
|
||||
|
||||
/**
|
||||
* Submit form and trigger forget process
|
||||
*/
|
||||
const handleSave = () => {
|
||||
if(!id) return
|
||||
form
|
||||
@@ -56,7 +79,9 @@ const ForgetRefreshModal = forwardRef<ForgetRefreshModalRef, ForgetRefreshModalP
|
||||
});
|
||||
}
|
||||
|
||||
// 暴露给父组件的方法
|
||||
/**
|
||||
* Expose methods to parent component
|
||||
*/
|
||||
useImperativeHandle(ref, () => ({
|
||||
handleOpen,
|
||||
handleClose
|
||||
|
||||
@@ -1,13 +1,32 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:33:06
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:33:06
|
||||
*/
|
||||
import { useEffect, useState, forwardRef, useImperativeHandle } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Skeleton, Space, Progress } from 'antd';
|
||||
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import Empty from '@/components/Empty'
|
||||
import {
|
||||
getImplicitHabits,
|
||||
} from '@/api/memory'
|
||||
|
||||
/**
|
||||
* Habits item data structure
|
||||
* @property {string} habit_description - Description of the habit
|
||||
* @property {string} frequency_pattern - Frequency pattern
|
||||
* @property {string} time_context - Time context
|
||||
* @property {number} confidence_level - Confidence level percentage
|
||||
* @property {string[]} supporting_summaries - Supporting summaries
|
||||
* @property {string} first_observed - First observation date
|
||||
* @property {string} last_observed - Last observation date
|
||||
* @property {boolean} is_current - Whether habit is current
|
||||
* @property {string[]} specific_examples - Specific examples
|
||||
*/
|
||||
interface HabitsItem {
|
||||
habit_description: string;
|
||||
frequency_pattern: string;
|
||||
@@ -20,6 +39,11 @@ interface HabitsItem {
|
||||
specific_examples: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* Habits Component
|
||||
* Displays user habits with confidence levels and specific examples
|
||||
* Shows habit descriptions, time context, and supporting evidence
|
||||
*/
|
||||
const Habits = forwardRef<{ handleRefresh: () => void; }>((_props, ref) => {
|
||||
const { t } = useTranslation()
|
||||
const { id } = useParams()
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:33:01
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:33:01
|
||||
*/
|
||||
import { type FC, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
@@ -7,6 +13,14 @@ import ReactEcharts from 'echarts-for-react'
|
||||
import Empty from '@/components/Empty'
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import { getEmotionHealth } from '@/api/memory'
|
||||
/**
|
||||
* Health data structure
|
||||
* @property {number} health_score - Overall health score
|
||||
* @property {string} level - Health level
|
||||
* @property {Object} dimensions - Health dimensions (positivity, stability, resilience)
|
||||
* @property {Object} emotion_distribution - Distribution of emotions
|
||||
* @property {string} time_range - Time range for analysis
|
||||
*/
|
||||
interface Health {
|
||||
health_score: number;
|
||||
level: string;
|
||||
@@ -36,6 +50,12 @@ interface Health {
|
||||
};
|
||||
time_range: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Health Component
|
||||
* Displays emotional health score with radar chart and dimension breakdowns
|
||||
* Shows positivity rate, stability, and resilience metrics
|
||||
*/
|
||||
const Health: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const { id } = useParams()
|
||||
|
||||
@@ -1,16 +1,34 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:32:57
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:32:57
|
||||
*/
|
||||
import { type FC, useMemo } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ReactEcharts from 'echarts-for-react'
|
||||
|
||||
import Empty from '@/components/Empty'
|
||||
import Loading from '@/components/Empty/Loading'
|
||||
import type { Interaction } from '../pages/GraphDetail'
|
||||
|
||||
/**
|
||||
* Props for InteractionBar component
|
||||
* @property {Interaction[]} chartData - Interaction count data over time
|
||||
* @property {boolean} [loading] - Loading state
|
||||
*/
|
||||
interface InteractionBarProps {
|
||||
chartData: Interaction[];
|
||||
loading?: boolean;
|
||||
}
|
||||
|
||||
const Colors = ['#155EEF', '#369F21', '#FF5D34']
|
||||
|
||||
/**
|
||||
* InteractionBar Component
|
||||
* Displays user interaction counts over time as a bar chart
|
||||
* Shows daily interaction frequency
|
||||
*/
|
||||
const InteractionBar: FC<InteractionBarProps> = ({ chartData, loading }) => {
|
||||
const { t } = useTranslation()
|
||||
|
||||
|
||||
@@ -1,18 +1,43 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:32:53
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:32:53
|
||||
*/
|
||||
import { useEffect, useState, forwardRef, useImperativeHandle } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Skeleton, Progress } from 'antd';
|
||||
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import {
|
||||
getImplicitInterestAreas,
|
||||
} from '@/api/memory'
|
||||
|
||||
/**
|
||||
* Interest category item structure
|
||||
* @property {string} category_name - Category name
|
||||
* @property {number} percentage - Interest percentage
|
||||
* @property {string[]} evidence - Supporting evidence
|
||||
* @property {string | null} trending_direction - Trending direction
|
||||
*/
|
||||
interface Item {
|
||||
category_name: string;
|
||||
percentage: number;
|
||||
evidence: string[];
|
||||
trending_direction: string | null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interest areas data structure
|
||||
* @property {string} user_id - User ID
|
||||
* @property {number | string} analysis_timestamp - Analysis timestamp
|
||||
* @property {number} total_summaries_analyzed - Total summaries analyzed
|
||||
* @property {Item} tech - Technology interest
|
||||
* @property {Item} lifestyle - Lifestyle interest
|
||||
* @property {Item} music - Music interest
|
||||
* @property {Item} art - Art interest
|
||||
*/
|
||||
interface InterestAreasItem {
|
||||
user_id: string;
|
||||
analysis_timestamp: number | string;
|
||||
@@ -23,6 +48,11 @@ interface InterestAreasItem {
|
||||
art: Item;
|
||||
}
|
||||
|
||||
/**
|
||||
* InterestAreas Component
|
||||
* Displays user interest distribution across different categories
|
||||
* Shows percentage breakdown for art, music, tech, and lifestyle
|
||||
*/
|
||||
const InterestAreas = forwardRef<{ handleRefresh: () => void; }>((_props, ref) => {
|
||||
const { t } = useTranslation()
|
||||
const { id } = useParams()
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:32:47
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:32:47
|
||||
*/
|
||||
/**
|
||||
* Interest Distribution Component
|
||||
* Displays user interest distribution as pie chart with tag list
|
||||
*/
|
||||
|
||||
import { type FC, useRef, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
@@ -9,6 +20,7 @@ import Empty from '@/components/Empty';
|
||||
import Loading from '@/components/Empty/Loading';
|
||||
import RbCard from '@/components/RbCard/Card';
|
||||
|
||||
/** Chart color palette */
|
||||
const Colors = ['#155EEF', '#4DA8FF', '#03BDFF', '#31E8FF', '#AD88FF', '#FFB048']
|
||||
|
||||
const InterestDistribution: FC = () => {
|
||||
@@ -23,6 +35,7 @@ const InterestDistribution: FC = () => {
|
||||
useEffect(() => {
|
||||
getData()
|
||||
}, [id])
|
||||
/** Fetch interest distribution data */
|
||||
const getData = () => {
|
||||
setLoading(true)
|
||||
getHotMemoryTagsByUser(id as string).then(res => {
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:32:41
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:32:41
|
||||
*/
|
||||
/**
|
||||
* Memory Insight Component
|
||||
* Displays memory insights including behavior patterns, key findings, and growth trajectory
|
||||
*/
|
||||
|
||||
import { useEffect, useState, forwardRef, useImperativeHandle } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Skeleton, Space } from 'antd';
|
||||
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import Empty from '@/components/Empty';
|
||||
import {
|
||||
@@ -10,6 +22,9 @@ import {
|
||||
} from '@/api/memory'
|
||||
import type { MemoryInsightRef } from '../types'
|
||||
|
||||
/**
|
||||
* Insight data structure
|
||||
*/
|
||||
interface Data {
|
||||
memory_insight?: string;
|
||||
behavior_pattern?: string;
|
||||
@@ -30,7 +45,7 @@ const MemoryInsight = forwardRef<MemoryInsightRef>((_props, ref) => {
|
||||
getData()
|
||||
}, [id])
|
||||
|
||||
// 记忆洞察
|
||||
/** Fetch memory insight data */
|
||||
const getData = () => {
|
||||
if (!id) return
|
||||
setLoading(true)
|
||||
@@ -42,7 +57,7 @@ const MemoryInsight = forwardRef<MemoryInsightRef>((_props, ref) => {
|
||||
setLoading(false)
|
||||
})
|
||||
}
|
||||
// 暴露给父组件的方法
|
||||
/** Expose methods to parent component */
|
||||
useImperativeHandle(ref, () => ({
|
||||
getData,
|
||||
}));
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:32:35
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:32:35
|
||||
*/
|
||||
/**
|
||||
* Node Statistics Component
|
||||
* Displays memory node statistics by type with navigation to detail views
|
||||
*/
|
||||
|
||||
import { type FC, useEffect, useState } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams, useNavigate } from 'react-router-dom'
|
||||
import { Skeleton } from 'antd';
|
||||
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import {
|
||||
getNodeStatistics,
|
||||
@@ -10,6 +22,7 @@ import {
|
||||
import type { NodeStatisticsItem } from '../types'
|
||||
|
||||
|
||||
/** Background gradient list */
|
||||
const BG_LIST = [
|
||||
'rb:bg-[linear-gradient(316deg,rgba(21,94,239,0.06)_0%,rgba(251,253,255,0)_100%)]',
|
||||
'rb:bg-[linear-gradient(316deg,rgba(54,159,33,0.06)_0%,rgba(251,253,255,0)_100%)]',
|
||||
@@ -18,6 +31,7 @@ const BG_LIST = [
|
||||
'rb:bg-[linear-gradient(313deg,rgba(156,111,255,0.06)_0%,rgba(251,253,255,0)_100%)]',
|
||||
'rb:bg-[linear-gradient(332deg,rgba(54,159,33,0.06)_0%,rgba(251,253,255,0)_100%)]',
|
||||
]
|
||||
/** Memory type configuration */
|
||||
const typeList = [
|
||||
{ key: 'PERCEPTUAL_MEMORY', bg: 0 },
|
||||
{ key: 'WORKING_MEMORY', bg: 1 },
|
||||
@@ -48,6 +62,7 @@ const NodeStatistics: FC = () => {
|
||||
getData()
|
||||
}, [id])
|
||||
|
||||
/** Fetch node statistics */
|
||||
const getData = () => {
|
||||
if (!id) return
|
||||
setLoading(true)
|
||||
@@ -63,9 +78,11 @@ const NodeStatistics: FC = () => {
|
||||
setLoading(false)
|
||||
})
|
||||
}
|
||||
/** Navigate to detail page */
|
||||
const handleViewDetail = (type: string) => {
|
||||
navigate(`/user-memory/detail/${id}/${type}`)
|
||||
}
|
||||
/** Render statistics card */
|
||||
const renderCard = (key: string, bgIndex: number | null, isChild: boolean = false) => {
|
||||
const item = data.find((item) => item.type === key)
|
||||
return (
|
||||
|
||||
@@ -1,11 +1,26 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:32:30
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:32:30
|
||||
*/
|
||||
/**
|
||||
* Page Header Component
|
||||
* Header with navigation and operation buttons
|
||||
*/
|
||||
|
||||
import { type FC, type ReactNode } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Layout, Space, Button } from 'antd';
|
||||
import { Layout, Button } from 'antd';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
|
||||
import logoutIcon from '@/assets/images/logout_hover.svg'
|
||||
|
||||
const { Header } = Layout;
|
||||
|
||||
/**
|
||||
* Component props
|
||||
*/
|
||||
interface ConfigHeaderProps {
|
||||
name?: string;
|
||||
operation?: ReactNode;
|
||||
@@ -21,6 +36,7 @@ const PageHeader: FC<ConfigHeaderProps> = ({
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
/** Navigate back */
|
||||
const goBack = () => {
|
||||
if (source === 'detail') {
|
||||
navigate('/user-memory', { replace: true })
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:32:23
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:32:23
|
||||
*/
|
||||
import { type FC, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Skeleton, Space, Tooltip, Image } from 'antd';
|
||||
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import {
|
||||
getPerceptualLastVisual,
|
||||
@@ -9,6 +16,22 @@ import {
|
||||
getPerceptualLastText,
|
||||
} from '@/api/memory'
|
||||
|
||||
/**
|
||||
* 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;
|
||||
@@ -25,12 +48,20 @@ interface PerceptualLastInfoItem {
|
||||
section_count: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Field keys for different perceptual types
|
||||
*/
|
||||
const KEYS = {
|
||||
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<{ type: 'last_visual' | 'last_listen' | 'last_text' }> = ({ type }) => {
|
||||
const { t } = useTranslation()
|
||||
const { id } = useParams()
|
||||
|
||||
@@ -1,12 +1,27 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:32:18
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:32:18
|
||||
*/
|
||||
import { useEffect, useState, forwardRef, useImperativeHandle } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Skeleton, Progress } from 'antd';
|
||||
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import {
|
||||
getImplicitPortrait,
|
||||
} from '@/api/memory'
|
||||
|
||||
/**
|
||||
* Portrait dimension item structure
|
||||
* @property {string} dimension_name - Dimension name
|
||||
* @property {number} percentage - Percentage value
|
||||
* @property {string[]} evidence - Supporting evidence
|
||||
* @property {string} reasoning - Reasoning
|
||||
* @property {string} confidence_level - Confidence level
|
||||
*/
|
||||
interface Item {
|
||||
dimension_name: string;
|
||||
percentage: number;
|
||||
@@ -14,6 +29,18 @@ interface Item {
|
||||
reasoning: string;
|
||||
confidence_level: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Portrait data structure
|
||||
* @property {string} user_id - User ID
|
||||
* @property {number | string} analysis_timestamp - Analysis timestamp
|
||||
* @property {number} total_summaries_analyzed - Total summaries analyzed
|
||||
* @property {null} historical_trends - Historical trends
|
||||
* @property {Item} creativity - Creativity dimension
|
||||
* @property {Item} aesthetic - Aesthetic dimension
|
||||
* @property {Item} technology - Technology dimension
|
||||
* @property {Item} literature - Literature dimension
|
||||
*/
|
||||
interface PortraitItem {
|
||||
user_id: string;
|
||||
analysis_timestamp: number | string;
|
||||
@@ -25,6 +52,11 @@ interface PortraitItem {
|
||||
literature: Item;
|
||||
}
|
||||
|
||||
/**
|
||||
* Portrait Component
|
||||
* Displays user portrait analysis across multiple dimensions
|
||||
* Shows aesthetic, creativity, literature, and technology percentages
|
||||
*/
|
||||
const Portrait = forwardRef<{ handleRefresh: () => void; }>((_props, ref) => {
|
||||
const { t } = useTranslation()
|
||||
const { id } = useParams()
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:32:12
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:32:12
|
||||
*/
|
||||
import { useEffect, useState, useRef, useMemo, forwardRef, useImperativeHandle } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
@@ -10,6 +16,17 @@ import RbCard from '@/components/RbCard/Card'
|
||||
import { getImplicitPreferences } from '@/api/memory'
|
||||
import detailEmpty from '@/assets/images/userMemory/detail_empty.png'
|
||||
|
||||
/**
|
||||
* Preference item structure
|
||||
* @property {string} tag_name - Tag name
|
||||
* @property {number} confidence_score - Confidence score (0-1)
|
||||
* @property {string[]} supporting_evidence - Supporting evidence
|
||||
* @property {string} context_details - Context details
|
||||
* @property {number | string} created_at - Creation timestamp
|
||||
* @property {number | string} updated_at - Update timestamp
|
||||
* @property {string[]} conversation_references - Conversation references
|
||||
* @property {string} category - Category
|
||||
*/
|
||||
interface PreferenceItem {
|
||||
tag_name: string;
|
||||
confidence_score: number;
|
||||
@@ -21,8 +38,16 @@ interface PreferenceItem {
|
||||
category: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Default color palette for categories
|
||||
*/
|
||||
const DEFAULT_COLORS = ['#FF5D34', '#155EEF', '#9C6FFF', '#369F21', '#4DA8FF', '#FF8C00', '#32CD32', '#FF69B4', '#20B2AA', '#DDA0DD']
|
||||
|
||||
/**
|
||||
* Generate color mapping for categories
|
||||
* @param {string[]} categories - List of categories
|
||||
* @returns {Record<string, string>} Category to color mapping
|
||||
*/
|
||||
const generateCategoryColors = (categories: string[]) => {
|
||||
const colors: Record<string, string> = {}
|
||||
categories.forEach((category, index) => {
|
||||
@@ -31,6 +56,11 @@ const generateCategoryColors = (categories: string[]) => {
|
||||
return colors
|
||||
}
|
||||
|
||||
/**
|
||||
* Preferences Component
|
||||
* Displays user preferences as an interactive word cloud
|
||||
* Shows detailed context and evidence when a word is selected
|
||||
*/
|
||||
const Preferences = forwardRef<{ handleRefresh: () => void; }>((_props, ref) => {
|
||||
const { t } = useTranslation()
|
||||
const { id } = useParams()
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:32:07
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:32:07
|
||||
*/
|
||||
import { type FC, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import ReactEcharts from 'echarts-for-react';
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
import Empty from '@/components/Empty'
|
||||
import Loading from '@/components/Empty/Loading'
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
|
||||
/**
|
||||
* Props for RecentTrendsLineCard component
|
||||
* @property {Array<Record<string, string | number>>} chartData - Trend data over time
|
||||
* @property {string[]} seriesList - List of series keys to display
|
||||
* @property {boolean} [loading] - Loading state
|
||||
*/
|
||||
interface RecentTrendsLineCardProps {
|
||||
chartData: Array<Record<string, string | number>>;
|
||||
seriesList: string[];
|
||||
@@ -14,6 +26,11 @@ interface RecentTrendsLineCardProps {
|
||||
|
||||
const Colors = ['#155EEF', '#FF5D34']
|
||||
|
||||
/**
|
||||
* RecentTrendsLineCard Component
|
||||
* Displays forgetting trends with dual Y-axis line chart
|
||||
* Shows merged count and average activation over time
|
||||
*/
|
||||
const RecentTrendsLineCard: FC<RecentTrendsLineCardProps> = ({ chartData, seriesList, loading }) => {
|
||||
const { t } = useTranslation()
|
||||
const chartRef = useRef<ReactEcharts>(null);
|
||||
|
||||
@@ -1,11 +1,23 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:32:00
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:32:00
|
||||
*/
|
||||
/**
|
||||
* Relationship Network Component
|
||||
* Displays memory relationship graph with node details
|
||||
* Interactive force-directed graph visualization
|
||||
*/
|
||||
|
||||
import React, { type FC, useEffect, useState, useRef, useCallback } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams, useNavigate } from 'react-router-dom'
|
||||
import { Col, Row, Space, Button } from 'antd'
|
||||
import dayjs from 'dayjs'
|
||||
import ReactEcharts from 'echarts-for-react'
|
||||
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import ReactEcharts from 'echarts-for-react'
|
||||
import detailEmpty from '@/assets/images/userMemory/detail_empty.png'
|
||||
import type { Node, Edge, GraphData, StatementNodeProperties, ExtractedEntityNodeProperties } from '../types'
|
||||
import {
|
||||
@@ -14,6 +26,7 @@ import {
|
||||
import Empty from '@/components/Empty'
|
||||
import Tag from '@/components/Tag'
|
||||
|
||||
/** Node color palette */
|
||||
const colors = ['#155EEF', '#369F21', '#4DA8FF', '#FF5D34', '#9C6FFF', '#FF8A4C', '#8BAEF7', '#FFB048']
|
||||
const RelationshipNetwork:FC = () => {
|
||||
const { t } = useTranslation()
|
||||
@@ -28,7 +41,7 @@ const RelationshipNetwork:FC = () => {
|
||||
const navigate = useNavigate()
|
||||
|
||||
console.log('categories', categories)
|
||||
// 关系网络
|
||||
/** Fetch relationship network data */
|
||||
const getEdgeData = useCallback(() => {
|
||||
if (!id) return
|
||||
setSelectedNode(null)
|
||||
@@ -134,6 +147,7 @@ const RelationshipNetwork:FC = () => {
|
||||
}
|
||||
}, [nodes])
|
||||
|
||||
/** Navigate to full graph view */
|
||||
const handleViewAll = () => {
|
||||
if (!selectedNode) return
|
||||
const params = new URLSearchParams({
|
||||
@@ -343,5 +357,5 @@ const RelationshipNetwork:FC = () => {
|
||||
</Row>
|
||||
)
|
||||
}
|
||||
// 使用React.memo包装组件,避免不必要的渲染
|
||||
/** Use React.memo to avoid unnecessary renders */
|
||||
export default React.memo(RelationshipNetwork)
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:31:50
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:31:50
|
||||
*/
|
||||
import { useEffect, useState, forwardRef, useImperativeHandle } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
@@ -8,6 +14,11 @@ import { getEmotionSuggestions } from '@/api/memory'
|
||||
import RbAlert from '@/components/RbAlert'
|
||||
|
||||
|
||||
/**
|
||||
* Suggestions data structure
|
||||
* @property {string} health_summary - Overall health summary
|
||||
* @property {Array} suggestions - List of suggestions with actionable steps
|
||||
*/
|
||||
interface Suggestions {
|
||||
health_summary: string;
|
||||
suggestions: Array<{
|
||||
@@ -18,6 +29,12 @@ interface Suggestions {
|
||||
actionable_steps: string[];
|
||||
}>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Suggestions Component
|
||||
* Displays emotional health suggestions with actionable steps
|
||||
* Shows health summary and prioritized recommendations
|
||||
*/
|
||||
const Suggestions = forwardRef<{ handleRefresh: () => void; }>((_props, ref) => {
|
||||
const { t } = useTranslation()
|
||||
const { id } = useParams()
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:31:36
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:31:36
|
||||
*/
|
||||
import { type FC, useEffect, useState } from 'react'
|
||||
import clsx from 'clsx'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { Skeleton, Progress, Space, Tooltip, Divider } from 'antd';
|
||||
import { Skeleton, Space, Divider } from 'antd';
|
||||
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import {
|
||||
getPerceptualTimeline
|
||||
@@ -11,6 +17,19 @@ import { formatDateTime } from '@/utils/format';
|
||||
import Empty from '@/components/Empty'
|
||||
import Tag from '@/components/Tag'
|
||||
|
||||
/**
|
||||
* Timeline item structure
|
||||
* @property {string} id - Item ID
|
||||
* @property {number} perceptual_type - Perceptual type (1: visual, 2: audio, 3: text)
|
||||
* @property {string} file_path - File path
|
||||
* @property {string} file_name - File name
|
||||
* @property {string} summary - Content summary
|
||||
* @property {number} storage_type - Storage type
|
||||
* @property {string | number} created_time - Creation time
|
||||
* @property {string} domain - Domain
|
||||
* @property {string} topic - Topic
|
||||
* @property {string[]} keywords - Keywords
|
||||
*/
|
||||
interface TimelineItem {
|
||||
id: string;
|
||||
perceptual_type: number;
|
||||
@@ -24,18 +43,20 @@ interface TimelineItem {
|
||||
keywords: string[]
|
||||
}
|
||||
|
||||
const KEYS = {
|
||||
last_visual: ['summary', 'keywords', 'topic', 'domain', 'scene'],
|
||||
last_listen: ['summary', 'keywords', 'topic', 'domain', 'speaker_count'],
|
||||
last_text: ['summary', 'keywords', 'topic', 'domain', 'section_count'],
|
||||
}
|
||||
|
||||
/**
|
||||
* Perceptual type mapping
|
||||
*/
|
||||
const perceptual_type: Record<number, string> = {
|
||||
1: 'last_visual',
|
||||
2: 'last_listen',
|
||||
3: 'last_text',
|
||||
}
|
||||
|
||||
/**
|
||||
* Timeline Component
|
||||
* Displays chronological timeline of perceptual memories
|
||||
* Shows visual, audio, and text memories with metadata
|
||||
*/
|
||||
const Timeline: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const { id } = useParams()
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* @Author: ZhaoYing
|
||||
* @Date: 2026-02-03 18:31:24
|
||||
* @Last Modified by: ZhaoYing
|
||||
* @Last Modified time: 2026-02-03 18:31:24
|
||||
*/
|
||||
import { type FC, useEffect, useState, useMemo, useRef } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useParams } from 'react-router-dom'
|
||||
@@ -8,6 +14,11 @@ import Empty from '@/components/Empty'
|
||||
import RbCard from '@/components/RbCard/Card'
|
||||
import { getEmotionTags } from '@/api/memory'
|
||||
|
||||
/**
|
||||
* Word cloud data structure
|
||||
* @property {Array} tags - Emotion tags with statistics
|
||||
* @property {number} total_count - Total count of tags
|
||||
*/
|
||||
interface WordCloud {
|
||||
tags: Array<{
|
||||
emotion_type: string;
|
||||
@@ -17,6 +28,12 @@ interface WordCloud {
|
||||
}>;
|
||||
total_count: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* WordCloud Component
|
||||
* Displays emotion distribution as radar chart with statistics
|
||||
* Shows emotion types, counts, percentages, and average intensity
|
||||
*/
|
||||
const WordCloud: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const { id } = useParams()
|
||||
|
||||
Reference in New Issue
Block a user