加入脑图功能
parent
c7846a9f03
commit
2735697fc7
|
|
@ -17,11 +17,9 @@ function App() {
|
|||
// Load user from localStorage on app start
|
||||
useEffect(() => {
|
||||
const savedUser = localStorage.getItem('iMeetingUser');
|
||||
console.log('Saved user from localStorage:', savedUser);
|
||||
if (savedUser) {
|
||||
try {
|
||||
const parsedUser = JSON.parse(savedUser);
|
||||
console.log('Parsed user:', parsedUser);
|
||||
setUser(parsedUser);
|
||||
} catch (error) {
|
||||
console.error('Error parsing saved user:', error);
|
||||
|
|
|
|||
|
|
@ -86,8 +86,9 @@ const MindMap = ({ meetingId, meetingTitle, meeting, formatDateTime }) => {
|
|||
// 移除分隔线
|
||||
processed = processed.replace(/^---+$/gm, '');
|
||||
|
||||
// 如果没有主标题,添加一个
|
||||
if (!processed.startsWith('# ')) {
|
||||
// 检查是否已经有一级标题,如果没有才添加
|
||||
const hasMainTitle = processed.match(/^#+\s+.*会议总结/m);
|
||||
if (!processed.startsWith('# ') && !hasMainTitle) {
|
||||
processed = `# 会议总结\n\n${processed}`;
|
||||
}
|
||||
|
||||
|
|
@ -96,18 +97,25 @@ const MindMap = ({ meetingId, meetingTitle, meeting, formatDateTime }) => {
|
|||
let i = 0;
|
||||
|
||||
while (i < lines.length) {
|
||||
const line = lines[i].trim();
|
||||
const line = lines[i];
|
||||
const trimmedLine = line.trim();
|
||||
|
||||
if (line === '') {
|
||||
if (trimmedLine === '') {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// 处理标题行
|
||||
if (line.match(/^#+\s+/)) {
|
||||
if (trimmedLine.match(/^#+\s+/)) {
|
||||
// 清理标题格式,移除粗体和多余符号
|
||||
let cleanTitle = line.replace(/\*\*([^*]+)\*\*/g, '$1'); // 移除粗体
|
||||
let cleanTitle = trimmedLine.replace(/\*\*([^*]+)\*\*/g, '$1'); // 移除粗体
|
||||
cleanTitle = cleanTitle.replace(/[*_]/g, ''); // 移除其他markdown符号
|
||||
|
||||
// 如果是包含"会议总结"的标题,且不是一级标题,调整为一级标题
|
||||
if (cleanTitle.includes('会议总结') && !cleanTitle.startsWith('# ')) {
|
||||
cleanTitle = `# ${cleanTitle.replace(/^#+\s*/, '')}`;
|
||||
}
|
||||
|
||||
processedLines.push(cleanTitle);
|
||||
|
||||
// 查看下一个非空行
|
||||
|
|
@ -119,16 +127,19 @@ const MindMap = ({ meetingId, meetingTitle, meeting, formatDateTime }) => {
|
|||
// 如果下一行不是标题、列表或表格,将段落内容转换为列表项
|
||||
if (j < lines.length) {
|
||||
const nextLine = lines[j].trim();
|
||||
if (!nextLine.match(/^#+\s+/) && !nextLine.match(/^[-*+]\s+/) && !nextLine.includes('|') && nextLine.length > 0) {
|
||||
const nextLineOriginal = lines[j];
|
||||
if (!nextLine.match(/^#+\s+/) && !nextLine.match(/^[-*+]\s+/) && !nextLineOriginal.match(/^\s+[-*+]\s+/) && !nextLine.includes('|') && nextLine.length > 0) {
|
||||
// 收集段落内容直到下一个标题、列表或表格
|
||||
const paragraphLines = [];
|
||||
while (j < lines.length) {
|
||||
const currentLine = lines[j].trim();
|
||||
const currentLineOriginal = lines[j];
|
||||
if (currentLine === '') {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
if (currentLine.match(/^#+\s+/) || currentLine.match(/^[-*+]\s+/) || currentLine.includes('|')) {
|
||||
// 遇到标题、任何列表(包括缩进列表)或表格就停止
|
||||
if (currentLine.match(/^#+\s+/) || currentLine.match(/^[-*+]\s+/) || currentLineOriginal.match(/^\s+[-*+]\s+/) || currentLine.includes('|')) {
|
||||
break;
|
||||
}
|
||||
paragraphLines.push(currentLine);
|
||||
|
|
@ -163,18 +174,21 @@ const MindMap = ({ meetingId, meetingTitle, meeting, formatDateTime }) => {
|
|||
}
|
||||
}
|
||||
}
|
||||
// 处理列表项
|
||||
else if (line.match(/^[-*+]\s+/)) {
|
||||
const cleanListItem = line.replace(/\*\*([^*]+)\*\*/g, '$1'); // 移除粗体
|
||||
processedLines.push(cleanListItem);
|
||||
// 处理列表项,只保留顶级列表项(没有缩进的第一层)
|
||||
else if (trimmedLine.match(/^[-*+]\s+/)) {
|
||||
// 检查原始行是否有缩进(以空格或制表符开头)
|
||||
if (!line.match(/^\s/)) {
|
||||
const cleanListItem = trimmedLine.replace(/\*\*([^*]+)\*\*/g, '$1'); // 移除粗体
|
||||
processedLines.push(cleanListItem);
|
||||
}
|
||||
}
|
||||
// 保持表格原样,让markmap自己处理
|
||||
else if (line.includes('|')) {
|
||||
processedLines.push(line);
|
||||
else if (trimmedLine.includes('|')) {
|
||||
processedLines.push(trimmedLine);
|
||||
}
|
||||
// 处理其他普通段落(如果前面没有被处理)
|
||||
else if (line.length > 0 && !line.match(/\*\*总字数:\d+字\*\*/)) {
|
||||
processedLines.push(`- ${line}`);
|
||||
else if (trimmedLine.length > 0 && !trimmedLine.match(/\*\*总字数:\d+字\*\*/)) {
|
||||
processedLines.push(`- ${trimmedLine}`);
|
||||
}
|
||||
|
||||
i++;
|
||||
|
|
@ -193,14 +207,10 @@ const MindMap = ({ meetingId, meetingTitle, meeting, formatDateTime }) => {
|
|||
|
||||
try {
|
||||
const processedMarkdown = preprocessMarkdownForMindMap(markdown);
|
||||
console.log('原始markdown内容:', markdown);
|
||||
console.log('预处理后的markdown:', processedMarkdown);
|
||||
|
||||
const transformer = new Transformer();
|
||||
const { root } = transformer.transform(processedMarkdown);
|
||||
|
||||
console.log('转换后的思维导图数据:', root);
|
||||
|
||||
if (markmapRef.current) {
|
||||
markmapRef.current.setData(root);
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ import UserManagement from '../components/admin/UserManagement';
|
|||
import SystemConfiguration from '../components/admin/SystemConfiguration';
|
||||
import './AdminManagement.css';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
const AdminManagement = () => {
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
|
@ -28,20 +26,22 @@ const AdminManagement = () => {
|
|||
</header>
|
||||
<div className="admin-content">
|
||||
<div className="admin-wrapper">
|
||||
<Tabs defaultActiveKey="userManagement" className="admin-tabs">
|
||||
<TabPane
|
||||
tab={<span><Users size={16} /> 用户管理</span>}
|
||||
key="userManagement"
|
||||
>
|
||||
<UserManagement />
|
||||
</TabPane>
|
||||
<TabPane
|
||||
tab={<span><Settings size={16} /> 系统配置</span>}
|
||||
key="systemConfiguration"
|
||||
>
|
||||
<SystemConfiguration />
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
<Tabs
|
||||
defaultActiveKey="userManagement"
|
||||
className="admin-tabs"
|
||||
items={[
|
||||
{
|
||||
key: 'userManagement',
|
||||
label: <span><Users size={16} /> 用户管理</span>,
|
||||
children: <UserManagement />
|
||||
},
|
||||
{
|
||||
key: 'systemConfiguration',
|
||||
label: <span><Settings size={16} /> 系统配置</span>,
|
||||
children: <SystemConfiguration />
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -39,14 +39,10 @@ const Dashboard = ({ user, onLogout }) => {
|
|||
const fetchUserData = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
console.log('Fetching user data for user_id:', user.user_id);
|
||||
|
||||
const userResponse = await apiClient.get(buildApiUrl(API_ENDPOINTS.USERS.DETAIL(user.user_id)));
|
||||
console.log('User response:', userResponse.data);
|
||||
setUserInfo(userResponse.data);
|
||||
|
||||
const meetingsResponse = await apiClient.get(buildApiUrl(`${API_ENDPOINTS.MEETINGS.LIST}?user_id=${user.user_id}`));
|
||||
console.log('Meetings response:', meetingsResponse.data);
|
||||
setMeetings(meetingsResponse.data);
|
||||
|
||||
} catch (err) {
|
||||
|
|
|
|||
|
|
@ -12,8 +12,6 @@ import MeetingSummary from '../components/MeetingSummary';
|
|||
import { Tabs } from 'antd';
|
||||
import './MeetingDetails.css';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
|
||||
const MeetingDetails = ({ user }) => {
|
||||
const { meeting_id } = useParams();
|
||||
const navigate = useNavigate();
|
||||
|
|
@ -224,15 +222,11 @@ const MeetingDetails = ({ user }) => {
|
|||
const transcriptResponse = await apiClient.get(`${baseUrl}${transcriptEndpoint}`);
|
||||
setTranscript(transcriptResponse.data);
|
||||
|
||||
console.log('First transcript item:', transcriptResponse.data[0]);
|
||||
|
||||
// 现在使用speaker_id字段进行分组
|
||||
const allSpeakerIds = transcriptResponse.data
|
||||
.map(item => item.speaker_id)
|
||||
.filter(speakerId => speakerId !== null && speakerId !== undefined);
|
||||
|
||||
console.log('Extracted speaker IDs:', allSpeakerIds);
|
||||
|
||||
const uniqueSpeakers = [...new Set(allSpeakerIds)]
|
||||
.map(speakerId => {
|
||||
const segment = transcriptResponse.data.find(item => item.speaker_id === speakerId);
|
||||
|
|
@ -243,7 +237,6 @@ const MeetingDetails = ({ user }) => {
|
|||
})
|
||||
.sort((a, b) => a.speaker_id - b.speaker_id); // 按speaker_id数值排序
|
||||
|
||||
console.log('Final unique speakers:', uniqueSpeakers);
|
||||
setSpeakerList(uniqueSpeakers);
|
||||
|
||||
// 初始化编辑状态
|
||||
|
|
@ -467,9 +460,6 @@ const MeetingDetails = ({ user }) => {
|
|||
|
||||
const handleSpeakerEditOpen = () => {
|
||||
console.log('Opening speaker edit modal');
|
||||
console.log('Current transcript:', transcript);
|
||||
console.log('Current speakerList:', speakerList);
|
||||
console.log('Current editingSpeakers:', editingSpeakers);
|
||||
setShowSpeakerEdit(true);
|
||||
};
|
||||
|
||||
|
|
@ -947,26 +937,37 @@ const MeetingDetails = ({ user }) => {
|
|||
</section>
|
||||
|
||||
<section className="card-section summary-tabs-section">
|
||||
<Tabs defaultActiveKey="1">
|
||||
<TabPane tab={<span><FileText size={16} /> 会议总结</span>} key="1">
|
||||
<MeetingSummary
|
||||
meeting={meeting}
|
||||
summaryResult={summaryResult}
|
||||
summaryHistory={summaryHistory}
|
||||
isCreator={isCreator}
|
||||
onOpenSummaryModal={openSummaryModal}
|
||||
formatDateTime={formatDateTime}
|
||||
/>
|
||||
</TabPane>
|
||||
<TabPane tab={<span><Brain size={16} /> 会议脑图</span>} key="2">
|
||||
<MindMap
|
||||
meetingId={meeting_id}
|
||||
meetingTitle={meeting.title}
|
||||
meeting={meeting}
|
||||
formatDateTime={formatDateTime}
|
||||
/>
|
||||
</TabPane>
|
||||
</Tabs>
|
||||
<Tabs
|
||||
defaultActiveKey="1"
|
||||
items={[
|
||||
{
|
||||
key: '1',
|
||||
label: <span><FileText size={16} /> 会议总结</span>,
|
||||
children: (
|
||||
<MeetingSummary
|
||||
meeting={meeting}
|
||||
summaryResult={summaryResult}
|
||||
summaryHistory={summaryHistory}
|
||||
isCreator={isCreator}
|
||||
onOpenSummaryModal={openSummaryModal}
|
||||
formatDateTime={formatDateTime}
|
||||
/>
|
||||
)
|
||||
},
|
||||
{
|
||||
key: '2',
|
||||
label: <span><Brain size={16} /> 会议脑图</span>,
|
||||
children: (
|
||||
<MindMap
|
||||
meetingId={meeting_id}
|
||||
meetingTitle={meeting.title}
|
||||
meeting={meeting}
|
||||
formatDateTime={formatDateTime}
|
||||
/>
|
||||
)
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in New Issue