-
样本数:{wordCloud.total_count}
-
+ ?
+
+
+
+ {wordCloud.total_count}
+ {t('statementDetail.totalCount')}
+
+
+
+
{wordCloud.tags.map(item => (
-
- {t(`statementDetail.${item.emotion_type}`)}
-
{item.count} {t('statementDetail.pieces')}
+
+
+ {t(`statementDetail.${item.emotion_type}`)}
+ ( {item.count} {t('statementDetail.pieces')} )
+
+
{item.percentage.toFixed(1)}%
-
+
))}
-
-
+
+
:
}
diff --git a/web/src/views/UserMemoryDetail/pages/WorkingDetail.tsx b/web/src/views/UserMemoryDetail/pages/WorkingDetail.tsx
new file mode 100644
index 00000000..3093d1ae
--- /dev/null
+++ b/web/src/views/UserMemoryDetail/pages/WorkingDetail.tsx
@@ -0,0 +1,209 @@
+import { type FC, useEffect, useState, useMemo } from 'react'
+import clsx from 'clsx'
+import { useTranslation } from 'react-i18next'
+import { useParams } from 'react-router-dom'
+import { Row, Col, Select, Form, Space, Skeleton, Input, Button, Divider } from 'antd'
+import RbCard from '@/components/RbCard/Card'
+import {
+ getConversations,
+ getConversationMessages,
+ getConversationDetail,
+} from '@/api/memory'
+import { formatDateTime } from '@/utils/format'
+import Tag from '@/components/Tag'
+import RbAlert from '@/components/RbAlert'
+import Empty from '@/components/Empty'
+import ChatContent from '@/components/Chat/ChatContent'
+import type { ChatItem } from '@/components/Chat/types'
+import PageLoading from '@/components/Empty/PageLoading'
+
+interface Conversation {
+ title: string;
+ id: string;
+}
+interface Detail {
+ theme: string;
+ theme_intro: string;
+ summary: string;
+ question: string[];
+ takeaways: string[];
+ info_score: number;
+}
+
+const WorkingDetail: FC = () => {
+ const { t } = useTranslation()
+ const { id } = useParams()
+ const [form] = Form.useForm()
+ const [loading, setLoading] = useState
(false)
+ const [data, setData] = useState([])
+ const [messagesLoading, setMessagesLoading] = useState(false)
+ const [messages, setMessages] = useState([])
+ const [detailLoading, setDetailLoading] = useState(false)
+ const [detail, setDetail] = useState(null)
+ const [selected, setSelected] = useState(null)
+
+ useEffect(() => {
+ if (!id) return
+ getData()
+ }, [id])
+
+ const getData = () => {
+ if (!id) return
+ setLoading(true)
+ setSelected(null)
+ setDetail(null)
+ setData([])
+ getConversations(id).then((res) => {
+ const response = res as Conversation[]
+ setData(response)
+ setSelected(response[0] || null)
+ })
+ .finally(() => {
+ setLoading(false)
+ })
+ }
+
+ useEffect(() => {
+ if (!id || !selected || !selected.id) return
+ getDetail(selected.id)
+ }, [id, selected])
+
+ const getDetail = (conversationId: string) => {
+ if (!id || !conversationId) return
+
+ setDetail(null)
+ setMessages([])
+ setDetailLoading(true)
+ setMessagesLoading(true)
+ getConversationMessages(id, conversationId)
+ .then(res => {
+ setMessages(res as ChatItem[])
+ })
+ .finally(() => {
+ setMessagesLoading(false)
+ })
+ getConversationDetail(id, conversationId)
+ .then(res => {
+ setDetail(res as Detail)
+ })
+ .finally(() => {
+ setDetailLoading(false)
+ })
+ }
+ const timeRange = useMemo(() => {
+ const times = messages.filter(m => m.created_at).map(m => Number(m.created_at))
+ if (times.length === 0) return ''
+ const minTime = Math.min(...times)
+ const maxTime = Math.max(...times)
+ return `${formatDateTime(minTime, 'YYYY.MM')} - ${formatDateTime(maxTime, 'YYYY.MM')}`
+ }, [messages])
+
+ return (
+
+ {loading
+ ?
+ : data.length === 0
+ ?
+ :(
+
+
+
+ {data.map(item => (
+
+
getDetail(item.id)}
+ >
+ {item.title}
+
+
+ ))}
+
+
+ {selected && <>
+
+ {selected.title}
+ {timeRange}
+
+
+
+ getDetail(selected.id)}>{t('workingDetail.refresh')}}
+ className="rb:mt-4!"
+ headerClassName='rb:bg-[#F6F8FC]! rb:border-b! rb:border-b-[#DFE4ED]! rb:min-h-11!'
+ headerType="borderless"
+ bodyClassName="rb:h-[calc(100vh-210px)]"
+ >
+ {messagesLoading
+ ?
+ : messages.length === 0
+ ?
+ : (
+ formatDateTime(item.created_at)}
+ />
+ )
+ }
+
+
+
+
+ {detailLoading
+ ?
+ : detail
+ ? <>
+ <>
+ {t('workingDetail.successfulTitle')}
+
+ {detail.takeaways.length > 0
+ ? (
+
+ {detail.takeaways.map(vo => - {vo}
)}
+
+ )
+ :
+ }
+ >
+
+ <>
+
+ {t('workingDetail.question')}
+
+ {detail.question.length > 0
+ ? (
+
+ {detail.question.map(vo => - {vo}
)}
+
+ )
+ :
+ }
+ >
+
+ <>
+
+ {t('workingDetail.summary')}
+ {detail.summary
+ ? {detail.summary}
+ :
+ }
+ >
+ >
+ :
+ }
+
+
+
+
+ >}
+
+ )
+ }
+
+ )
+}
+export default WorkingDetail
\ No newline at end of file
diff --git a/web/src/views/UserMemoryDetail/pages/index.tsx b/web/src/views/UserMemoryDetail/pages/index.tsx
index 93468a94..e734fd44 100644
--- a/web/src/views/UserMemoryDetail/pages/index.tsx
+++ b/web/src/views/UserMemoryDetail/pages/index.tsx
@@ -11,6 +11,7 @@ import ShortTermDetail from './ShortTermDetail'
import PerceptualDetail from './PerceptualDetail'
import EpisodicDetail from './EpisodicDetail'
import ExplicitDetail from './ExplicitDetail'
+import WorkingDetail from './WorkingDetail'
import {
getEndUserProfile,
} from '@/api/memory'
@@ -63,7 +64,7 @@ const Detail: FC = () => {
{type === 'SHORT_TERM_MEMORY' && }
{type === 'PERCEPTUAL_MEMORY' && } {/** TODO */}
{type === 'EPISODIC_MEMORY' && }
- {/* {type === 'WORKING_MEMORY' && } */} {/** TODO */}
+ {type === 'WORKING_MEMORY' && } {/** TODO */}
{type === 'EXPLICIT_MEMORY' && } {/** TODO */}