/** * MeetingImporter — 将会议纪要文本导入知识图谱 * * 创建 Event:meeting 节点,关联参与者(PARTICIPATED 边) */ const { getGraphStore } = require('../../db/GraphStore'); class MeetingImporter { constructor() { this.store = getGraphStore(); } /** * 导入会议纪要 * * @param {object} params * @param {string} params.title - 会议标题 * @param {string} params.date - 会议日期 (YYYY-MM-DD) * @param {string} params.summary - 会议摘要(必填) * @param {string} [params.rawText] - 原始会议纪要全文 * @param {string[]} [params.participants] - 参与者姓名或节点 id 列表 * @returns {{eventId: string, linkedParticipants: string[], skippedParticipants: string[]}} */ importMeetingNotes(params) { const { title, date, summary, rawText, participants = [], } = params; if (!summary) { throw new Error('importMeetingNotes: summary 为必填字段'); } const g = this.store; // 创建 Event:meeting 节点 const eventNode = g.createNode('Event', { type: 'meeting', title: title || '未命名会议', summary, date: date || new Date().toISOString().slice(0, 10), rawText: rawText || null, }); const linkedParticipants = []; const skippedParticipants = []; // 关联参与者 for (const p of participants) { // 先精确查 id,再按名称模糊查 let person = g.getNode(p); if (!person || person._type !== 'Person') { const results = g.findByName(p, 'Person'); person = results[0] || null; } if (person) { g.createEdge(person.id, eventNode.id, 'PARTICIPATED'); linkedParticipants.push(person.name || person.id); } else { skippedParticipants.push(p); } } return { eventId: eventNode.id, linkedParticipants, skippedParticipants, }; } } module.exports = { MeetingImporter };