加入脑图功能

mula.liu 2025-09-16 20:05:25 +08:00
parent c7846a9f03
commit 2735697fc7
7 changed files with 77 additions and 72 deletions

BIN
.DS_Store vendored

Binary file not shown.

BIN
dist.zip

Binary file not shown.

View File

@ -17,11 +17,9 @@ function App() {
// Load user from localStorage on app start // Load user from localStorage on app start
useEffect(() => { useEffect(() => {
const savedUser = localStorage.getItem('iMeetingUser'); const savedUser = localStorage.getItem('iMeetingUser');
console.log('Saved user from localStorage:', savedUser);
if (savedUser) { if (savedUser) {
try { try {
const parsedUser = JSON.parse(savedUser); const parsedUser = JSON.parse(savedUser);
console.log('Parsed user:', parsedUser);
setUser(parsedUser); setUser(parsedUser);
} catch (error) { } catch (error) {
console.error('Error parsing saved user:', error); console.error('Error parsing saved user:', error);

View File

@ -86,8 +86,9 @@ const MindMap = ({ meetingId, meetingTitle, meeting, formatDateTime }) => {
// 线 // 线
processed = processed.replace(/^---+$/gm, ''); processed = processed.replace(/^---+$/gm, '');
// //
if (!processed.startsWith('# ')) { const hasMainTitle = processed.match(/^#+\s+.*会议总结/m);
if (!processed.startsWith('# ') && !hasMainTitle) {
processed = `# 会议总结\n\n${processed}`; processed = `# 会议总结\n\n${processed}`;
} }
@ -96,18 +97,25 @@ const MindMap = ({ meetingId, meetingTitle, meeting, formatDateTime }) => {
let i = 0; let i = 0;
while (i < lines.length) { while (i < lines.length) {
const line = lines[i].trim(); const line = lines[i];
const trimmedLine = line.trim();
if (line === '') { if (trimmedLine === '') {
i++; i++;
continue; 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 cleanTitle = cleanTitle.replace(/[*_]/g, ''); // markdown
// ""
if (cleanTitle.includes('会议总结') && !cleanTitle.startsWith('# ')) {
cleanTitle = `# ${cleanTitle.replace(/^#+\s*/, '')}`;
}
processedLines.push(cleanTitle); processedLines.push(cleanTitle);
// //
@ -119,16 +127,19 @@ const MindMap = ({ meetingId, meetingTitle, meeting, formatDateTime }) => {
// //
if (j < lines.length) { if (j < lines.length) {
const nextLine = lines[j].trim(); 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 = []; const paragraphLines = [];
while (j < lines.length) { while (j < lines.length) {
const currentLine = lines[j].trim(); const currentLine = lines[j].trim();
const currentLineOriginal = lines[j];
if (currentLine === '') { if (currentLine === '') {
j++; j++;
continue; continue;
} }
if (currentLine.match(/^#+\s+/) || currentLine.match(/^[-*+]\s+/) || currentLine.includes('|')) { //
if (currentLine.match(/^#+\s+/) || currentLine.match(/^[-*+]\s+/) || currentLineOriginal.match(/^\s+[-*+]\s+/) || currentLine.includes('|')) {
break; break;
} }
paragraphLines.push(currentLine); paragraphLines.push(currentLine);
@ -163,18 +174,21 @@ const MindMap = ({ meetingId, meetingTitle, meeting, formatDateTime }) => {
} }
} }
} }
// //
else if (line.match(/^[-*+]\s+/)) { else if (trimmedLine.match(/^[-*+]\s+/)) {
const cleanListItem = line.replace(/\*\*([^*]+)\*\*/g, '$1'); // //
processedLines.push(cleanListItem); if (!line.match(/^\s/)) {
const cleanListItem = trimmedLine.replace(/\*\*([^*]+)\*\*/g, '$1'); //
processedLines.push(cleanListItem);
}
} }
// markmap // markmap
else if (line.includes('|')) { else if (trimmedLine.includes('|')) {
processedLines.push(line); processedLines.push(trimmedLine);
} }
// //
else if (line.length > 0 && !line.match(/\*\*总字数:\d+字\*\*/)) { else if (trimmedLine.length > 0 && !trimmedLine.match(/\*\*总字数:\d+字\*\*/)) {
processedLines.push(`- ${line}`); processedLines.push(`- ${trimmedLine}`);
} }
i++; i++;
@ -193,14 +207,10 @@ const MindMap = ({ meetingId, meetingTitle, meeting, formatDateTime }) => {
try { try {
const processedMarkdown = preprocessMarkdownForMindMap(markdown); const processedMarkdown = preprocessMarkdownForMindMap(markdown);
console.log('原始markdown内容:', markdown);
console.log('预处理后的markdown:', processedMarkdown);
const transformer = new Transformer(); const transformer = new Transformer();
const { root } = transformer.transform(processedMarkdown); const { root } = transformer.transform(processedMarkdown);
console.log('转换后的思维导图数据:', root);
if (markmapRef.current) { if (markmapRef.current) {
markmapRef.current.setData(root); markmapRef.current.setData(root);
} else { } else {

View File

@ -6,8 +6,6 @@ import UserManagement from '../components/admin/UserManagement';
import SystemConfiguration from '../components/admin/SystemConfiguration'; import SystemConfiguration from '../components/admin/SystemConfiguration';
import './AdminManagement.css'; import './AdminManagement.css';
const { TabPane } = Tabs;
const AdminManagement = () => { const AdminManagement = () => {
const navigate = useNavigate(); const navigate = useNavigate();
@ -28,20 +26,22 @@ const AdminManagement = () => {
</header> </header>
<div className="admin-content"> <div className="admin-content">
<div className="admin-wrapper"> <div className="admin-wrapper">
<Tabs defaultActiveKey="userManagement" className="admin-tabs"> <Tabs
<TabPane defaultActiveKey="userManagement"
tab={<span><Users size={16} /> 用户管理</span>} className="admin-tabs"
key="userManagement" items={[
> {
<UserManagement /> key: 'userManagement',
</TabPane> label: <span><Users size={16} /> 用户管理</span>,
<TabPane children: <UserManagement />
tab={<span><Settings size={16} /> 系统配置</span>} },
key="systemConfiguration" {
> key: 'systemConfiguration',
<SystemConfiguration /> label: <span><Settings size={16} /> 系统配置</span>,
</TabPane> children: <SystemConfiguration />
</Tabs> }
]}
/>
</div> </div>
</div> </div>
</div> </div>

View File

@ -39,14 +39,10 @@ const Dashboard = ({ user, onLogout }) => {
const fetchUserData = async () => { const fetchUserData = async () => {
try { try {
setLoading(true); 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))); const userResponse = await apiClient.get(buildApiUrl(API_ENDPOINTS.USERS.DETAIL(user.user_id)));
console.log('User response:', userResponse.data);
setUserInfo(userResponse.data); setUserInfo(userResponse.data);
const meetingsResponse = await apiClient.get(buildApiUrl(`${API_ENDPOINTS.MEETINGS.LIST}?user_id=${user.user_id}`)); const meetingsResponse = await apiClient.get(buildApiUrl(`${API_ENDPOINTS.MEETINGS.LIST}?user_id=${user.user_id}`));
console.log('Meetings response:', meetingsResponse.data);
setMeetings(meetingsResponse.data); setMeetings(meetingsResponse.data);
} catch (err) { } catch (err) {

View File

@ -12,8 +12,6 @@ import MeetingSummary from '../components/MeetingSummary';
import { Tabs } from 'antd'; import { Tabs } from 'antd';
import './MeetingDetails.css'; import './MeetingDetails.css';
const { TabPane } = Tabs;
const MeetingDetails = ({ user }) => { const MeetingDetails = ({ user }) => {
const { meeting_id } = useParams(); const { meeting_id } = useParams();
const navigate = useNavigate(); const navigate = useNavigate();
@ -224,15 +222,11 @@ const MeetingDetails = ({ user }) => {
const transcriptResponse = await apiClient.get(`${baseUrl}${transcriptEndpoint}`); const transcriptResponse = await apiClient.get(`${baseUrl}${transcriptEndpoint}`);
setTranscript(transcriptResponse.data); setTranscript(transcriptResponse.data);
console.log('First transcript item:', transcriptResponse.data[0]);
// 使speaker_id // 使speaker_id
const allSpeakerIds = transcriptResponse.data const allSpeakerIds = transcriptResponse.data
.map(item => item.speaker_id) .map(item => item.speaker_id)
.filter(speakerId => speakerId !== null && speakerId !== undefined); .filter(speakerId => speakerId !== null && speakerId !== undefined);
console.log('Extracted speaker IDs:', allSpeakerIds);
const uniqueSpeakers = [...new Set(allSpeakerIds)] const uniqueSpeakers = [...new Set(allSpeakerIds)]
.map(speakerId => { .map(speakerId => {
const segment = transcriptResponse.data.find(item => item.speaker_id === 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 .sort((a, b) => a.speaker_id - b.speaker_id); // speaker_id
console.log('Final unique speakers:', uniqueSpeakers);
setSpeakerList(uniqueSpeakers); setSpeakerList(uniqueSpeakers);
// //
@ -467,9 +460,6 @@ const MeetingDetails = ({ user }) => {
const handleSpeakerEditOpen = () => { const handleSpeakerEditOpen = () => {
console.log('Opening speaker edit modal'); console.log('Opening speaker edit modal');
console.log('Current transcript:', transcript);
console.log('Current speakerList:', speakerList);
console.log('Current editingSpeakers:', editingSpeakers);
setShowSpeakerEdit(true); setShowSpeakerEdit(true);
}; };
@ -947,26 +937,37 @@ const MeetingDetails = ({ user }) => {
</section> </section>
<section className="card-section summary-tabs-section"> <section className="card-section summary-tabs-section">
<Tabs defaultActiveKey="1"> <Tabs
<TabPane tab={<span><FileText size={16} /> 会议总结</span>} key="1"> defaultActiveKey="1"
<MeetingSummary items={[
meeting={meeting} {
summaryResult={summaryResult} key: '1',
summaryHistory={summaryHistory} label: <span><FileText size={16} /> 会议总结</span>,
isCreator={isCreator} children: (
onOpenSummaryModal={openSummaryModal} <MeetingSummary
formatDateTime={formatDateTime} meeting={meeting}
/> summaryResult={summaryResult}
</TabPane> summaryHistory={summaryHistory}
<TabPane tab={<span><Brain size={16} /> 会议脑图</span>} key="2"> isCreator={isCreator}
<MindMap onOpenSummaryModal={openSummaryModal}
meetingId={meeting_id} formatDateTime={formatDateTime}
meetingTitle={meeting.title} />
meeting={meeting} )
formatDateTime={formatDateTime} },
/> {
</TabPane> key: '2',
</Tabs> label: <span><Brain size={16} /> 会议脑图</span>,
children: (
<MindMap
meetingId={meeting_id}
meetingTitle={meeting.title}
meeting={meeting}
formatDateTime={formatDateTime}
/>
)
}
]}
/>
</section> </section>
</div> </div>
</div> </div>