| 
 | 1 | +export type ChapterItem = {  | 
 | 2 | +  // 标题  | 
 | 3 | +  text: string;  | 
 | 4 | +  // 链接  | 
 | 5 | +  link: string;  | 
 | 6 | +  // 初始时是否折叠, 如果未指定,侧边栏组不可折叠  | 
 | 7 | +  collapsed?: boolean;  | 
 | 8 | +  // 子项,元素顺序影响页面、章节顺序  | 
 | 9 | +  items?: ChapterItem[];  | 
 | 10 | +  // 返回上级章节  | 
 | 11 | +  goback?: boolean;  | 
 | 12 | +};  | 
 | 13 | + | 
 | 14 | +// 章节路由,注意,首尾都要有 `/`  | 
 | 15 | +// 不在其中的章节不会正确生成目录  | 
 | 16 | +export enum Chapters {  | 
 | 17 | +  // xrobot 分章  | 
 | 18 | +  xrobot = "/xrobot/",  | 
 | 19 | +  xrobot_device = "/xrobot/device/",  | 
 | 20 | +  xrobot_api = "/xrobot/api/",  | 
 | 21 | +  xrobot_faq = "/xrobot/faq/",  | 
 | 22 | +  xrobot_guide = "/xrobot/guide",  | 
 | 23 | +  xrobot_guide_mp = "/xrobot/guide/mini-program",  | 
 | 24 | +}  | 
 | 25 | + | 
 | 26 | +// 判断一个link 字符串是否是章节link  | 
 | 27 | +export function isChapter<T extends Record<string, string>>(  | 
 | 28 | +  link: string  | 
 | 29 | +): link is T[keyof T] {  | 
 | 30 | +  return Object.values(Chapters).includes(link as Chapters);  | 
 | 31 | +}  | 
 | 32 | + | 
 | 33 | +// 给 ChapterItem 的 link 字段追加当前章节的 link 前缀  | 
 | 34 | +function apply_prefix(item: ChapterItem, prefix: Chapters) {  | 
 | 35 | +  if (item?.link.startsWith("/") && prefix.endsWith("/")) {  | 
 | 36 | +    return { ...item, link: prefix.slice(0, -1) + item.link };  | 
 | 37 | +  } else if (!item.link.startsWith("/") && !prefix.endsWith("/")) {  | 
 | 38 | +    return { ...item, link: prefix + "/" + item.link };  | 
 | 39 | +  }  | 
 | 40 | +  return { ...item, link: prefix + item.link };  | 
 | 41 | +}  | 
 | 42 | + | 
 | 43 | +const items_xrobot_api = [  | 
 | 44 | +  {  | 
 | 45 | +    text: "API参考",  | 
 | 46 | +    items: [  | 
 | 47 | +      { text: "用户API", link: "user" },  | 
 | 48 | +      { text: "智能体API", link: "agent" },  | 
 | 49 | +      { text: "设备API", link: "device" },  | 
 | 50 | +      { text: "音色克隆API", link: "voice-clone" },  | 
 | 51 | +    ].map((item) => apply_prefix(item, Chapters.xrobot_api)),  | 
 | 52 | +    collapsed: false,  | 
 | 53 | +    link: Chapters.xrobot_api,  | 
 | 54 | +  },  | 
 | 55 | +];  | 
 | 56 | + | 
 | 57 | +const items_xrobot_device = [  | 
 | 58 | +  {  | 
 | 59 | +    text: "设备使用",  | 
 | 60 | +    items: [  | 
 | 61 | +      { text: "设备使用指南", link: "device-intro" },  | 
 | 62 | +      { text: "设备绑定", link: "device-bind" },  | 
 | 63 | +      { text: "设备服务通信协议", link: "device-protocol" },  | 
 | 64 | +      { text: "智能体连接指南", link: "device-connection" },  | 
 | 65 | +    ].map((item) => apply_prefix(item, Chapters.xrobot_device)),  | 
 | 66 | +    link: Chapters.xrobot_device,  | 
 | 67 | +    collapsed: true,  | 
 | 68 | +  },  | 
 | 69 | +  // 子章节  | 
 | 70 | +];  | 
 | 71 | + | 
 | 72 | +const items_xrobot_faq = [  | 
 | 73 | +  {  | 
 | 74 | +    text: "常见问题",  | 
 | 75 | +    items: [{ text: "FAQ", link: "faq" }].map((item) =>  | 
 | 76 | +      apply_prefix(item, Chapters.xrobot_faq)  | 
 | 77 | +    ),  | 
 | 78 | +    link: Chapters.xrobot_faq,  | 
 | 79 | +    // collapsed: false,  | 
 | 80 | +  },  | 
 | 81 | +  // 子章节  | 
 | 82 | +];  | 
 | 83 | + | 
 | 84 | +const items_xrobot_guide_mp = [  | 
 | 85 | +  {  | 
 | 86 | +    text: "微信小程序",  | 
 | 87 | +    link: Chapters.xrobot_guide_mp,  | 
 | 88 | +    collapsed: true,  | 
 | 89 | +    items: [  | 
 | 90 | +      { text: "智能体管理", link: "agent-management" },  | 
 | 91 | +      { text: "角色配置", link: "role-config" },  | 
 | 92 | +      { text: "设备管理", link: "device-management" },  | 
 | 93 | +      { text: "设备配网", link: "device-net-config" },  | 
 | 94 | +    ].map((item) => apply_prefix(item, Chapters.xrobot_guide_mp)),  | 
 | 95 | +  },  | 
 | 96 | +];  | 
 | 97 | + | 
 | 98 | +const items_xrobot_guide = [  | 
 | 99 | +  {  | 
 | 100 | +    text: "操作指南",  | 
 | 101 | +    link: Chapters.xrobot_guide,  | 
 | 102 | +    collapsed: false,  | 
 | 103 | +    items: [...items_xrobot_guide_mp, ...items_xrobot_device],  | 
 | 104 | +  },  | 
 | 105 | +];  | 
 | 106 | + | 
 | 107 | +// xrobot章节整体  | 
 | 108 | +const items_xrobot = [  | 
 | 109 | +  {  | 
 | 110 | +    text: "",  | 
 | 111 | +    items: [  | 
 | 112 | +      ...items_xrobot_guide,  | 
 | 113 | +      ...items_xrobot_api,  | 
 | 114 | +      // ...items_xrobot_device,  | 
 | 115 | +      ...items_xrobot_faq,  | 
 | 116 | +    ],  | 
 | 117 | +    link: Chapters.xrobot,  | 
 | 118 | +    // collapsed: false,  | 
 | 119 | +  },  | 
 | 120 | +];  | 
 | 121 | + | 
 | 122 | +function gobackItem(chapter: Chapters) {  | 
 | 123 | +  return {  | 
 | 124 | +    text: "返回上级",  | 
 | 125 | +    link: chapter,  | 
 | 126 | +    goback: true,  | 
 | 127 | +  };  | 
 | 128 | +}  | 
 | 129 | + | 
 | 130 | +// todo: 把子章节从ChapterItems中抽离出来  | 
 | 131 | +export const ChapterItems: Record<Chapters, ChapterItem[]> = {  | 
 | 132 | +  [Chapters.xrobot]: items_xrobot,  | 
 | 133 | +  [Chapters.xrobot_device]: [  | 
 | 134 | +    gobackItem(Chapters.xrobot),  | 
 | 135 | +    ...items_xrobot_device,  | 
 | 136 | +  ],  | 
 | 137 | +  [Chapters.xrobot_api]: [gobackItem(Chapters.xrobot), ...items_xrobot_api],  | 
 | 138 | +  [Chapters.xrobot_faq]: [gobackItem(Chapters.xrobot), ...items_xrobot_faq],  | 
 | 139 | +  [Chapters.xrobot_guide]: [gobackItem(Chapters.xrobot), ...items_xrobot_guide],  | 
 | 140 | +  [Chapters.xrobot_guide_mp]: [  | 
 | 141 | +    gobackItem(Chapters.xrobot_guide),  | 
 | 142 | +    ...items_xrobot_guide_mp,  | 
 | 143 | +  ],  | 
 | 144 | +};  | 
0 commit comments