outline.parser.ts 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. /**
  2. * 大纲解析器
  3. * 容错解析LLM返回的大纲JSON
  4. */
  5. export interface OutlineData {
  6. mainTheme: string;
  7. structureLogic: string;
  8. chapters: Array<{
  9. number: number;
  10. title: string;
  11. summary: string;
  12. keyPoints: string[];
  13. estimatedWords: number;
  14. }>;
  15. }
  16. export function parseOutline(jsonStr: string): OutlineData | null {
  17. if (!jsonStr || typeof jsonStr !== 'string') {
  18. console.error('[OutlineParser] 输入为空或非字符串');
  19. return null;
  20. }
  21. try {
  22. let data: any;
  23. // 策略1:直接解析(最理想情况,LLM 直接输出纯 JSON)
  24. try {
  25. data = JSON.parse(jsonStr.trim());
  26. } catch {
  27. // 策略2:提取 JSON 对象(处理 LLM 加了 markdown 标记或多余文字)
  28. const match = jsonStr.match(/\{[\s\S]*\}/);
  29. if (!match) {
  30. console.error('[OutlineParser] 未找到 JSON 对象');
  31. return null;
  32. }
  33. try {
  34. data = JSON.parse(match[0]);
  35. } catch (parseErr) {
  36. console.error('[OutlineParser] JSON 解析失败:', parseErr);
  37. return null;
  38. }
  39. }
  40. // 验证必要字段
  41. if (!data || typeof data !== 'object') {
  42. console.error('[OutlineParser] 解析结果非对象');
  43. return null;
  44. }
  45. if (!Array.isArray(data.chapters)) {
  46. console.error('[OutlineParser] chapters 字段缺失或非数组');
  47. // 尝试兼容:若顶层就是章节数组
  48. if (Array.isArray(data)) {
  49. data = { chapters: data };
  50. } else {
  51. return null;
  52. }
  53. }
  54. return {
  55. mainTheme: data.mainTheme || '主题待定',
  56. structureLogic: data.structureLogic || '由浅入深',
  57. chapters: data.chapters.map((c: any, i: number) => ({
  58. number: c.number || i + 1,
  59. title: c.title || `第${i + 1}章`,
  60. summary: typeof c.summary === 'string' ? c.summary : '',
  61. keyPoints: Array.isArray(c.keyPoints) ? c.keyPoints : [],
  62. estimatedWords: typeof c.estimatedWords === 'number' ? c.estimatedWords : 1000,
  63. })),
  64. };
  65. } catch (err) {
  66. console.error('[OutlineParser] 未知错误:', err);
  67. return null;
  68. }
  69. }