# api-gateway-admin **Repository Path**: jaakan/api-gateway-admin ## Basic Information - **Project Name**: api-gateway-admin - **Description**: API 网关后台管理前端,基于 SolidJS 构建。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-12 - **Last Updated**: 2026-07-12 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # API Gateway Admin API 网关后台管理前端,基于 SolidJS 构建。 ## 技术栈 - **框架**: SolidJS 1.9 + TypeScript 6.0 - **构建**: Vite 8 - **路由**: @solidjs/router 0.16 - **UI 组件**: @kobalte/core 0.13 (headless) - **包管理**: pnpm ## 启动 ```bash pnpm install pnpm dev # 开发服务器 http://localhost:5173 pnpm build # 生产构建 → dist/ pnpm preview # 预览生产构建 ``` ## 布局结构 ``` ┌──────────────────────────────────────────────────────┐ │ top-header (48px) │ ├──────────┬───────────────────────────────────────────┤ │ │ [tab1 ×][tab2 ×][tab3 ×] ← 横向滚动 │ │ menus │ (左右箭头按钮,无可见滚动条) │ │ (220px) ├───────────────────────────────────────────┤ │ 可折叠 │ │ │ │ main-body │ │ │ overflow-x: hidden; overflow-y: auto │ │ │ (子组件内部可自行横向滚动) │ └──────────┴───────────────────────────────────────────┘ ``` - CSS Grid 四区布局,`100vh` 占满视口 - 菜单可折叠,折叠时右侧布局自适应扩展 - main-body 高度 `= 100vh - header - tabs`,纵向滚动,永不横向滚动 - tab 栏横向溢出时可滚动,隐藏滚动条,左右箭头控制滚动 ## 目录结构 ``` src/ ├── App.tsx # 入口,Router + AdminShell ├── index.tsx # 渲染挂载 ├── layouts/ │ ├── AdminShell.tsx # 四区 Grid 外壳 │ ├── admin-shell.css │ ├── TopHeader.tsx # 顶部栏(菜单切换按钮) │ └── TopHeader.css ├── menu/ │ ├── types.ts # MenuData 类型定义 │ ├── fetchMenu.ts # 菜单数据获取(当前为 mock) │ ├── menuStore.ts # 菜单状态管理 │ ├── MenuPanel.tsx # 菜单面板(加载/错误/就绪) │ ├── MenuTree.tsx # 菜单树渲染(展开/折叠/高亮) │ └── menu-tree.css ├── tabs/ │ ├── tabStore.ts # 核心状态:openTabs / activeKey / close │ ├── TabBar.tsx # 页签栏(关闭按钮/箭头滚动) │ ├── TabContent.tsx # keep-alive 渲染层(不卸载非激活组件) │ ├── UrlSync.tsx # URL ↔ activeKey 单向同步 │ ├── AppInit.tsx # sessionStorage 恢复 + 持久化 │ └── tab-bar.css ├── routes/ │ ├── registry.ts # 路由 → 组件注册表(懒加载) │ ├── RouteInterfaceList.tsx # 路由/接口列表(示例页面) │ ├── PermissionUserManagement.tsx # 权限/用户管理(示例页面) │ ├── NotFound.tsx # 404 兜底 │ └── pages.css └── stores/ ├── layoutStore.ts # 菜单折叠状态 └── tabPersistence.ts # sessionStorage 读写 ``` ## 核心设计 ### 路由 + keep-alive 采用"自管挂载"方案: - `@solidjs/router` 的 `` 仅提供 URL 管理,不使用 `` 渲染业务组件 - `UrlSync` 监听 `location.pathname` 变化,通过 `syncFromUrl()` 驱动 `activeKey` - `TabContent` 遍历 `openTabs`,用 `display: none` 隐藏非激活 tab,组件永不卸载 - 用户操作(菜单/页签点击)直接调用 `navigate(route)`,不调用 `setActive` ``` 用户操作 → navigate(route) → pathname 变化 → syncFromUrl → setActive ↑ 单向,无反馈循环 ``` ### tab 列表持久化 - `openTabs` 列表(路由 key/title)写入 `sessionStorage`(key: `admin.openTabs`) - 页面刷新时从 `sessionStorage` 恢复,再由当前 URL 确定 active tab - 组件内部状态(表单草稿等)不持久化,刷新后重建 ### 菜单数据 - 前端定义 `MenuData` 类型契约(树形:`{ key, title, route?, icon?, children? }`) - 当前为 mock 实现(`fetchMenu.ts`),后端接口待对接 - 加载中显示骨架屏,失败显示错误 + 重试按钮 ## 路由注册 在 `src/routes/registry.ts` 中注册新页面: ```ts const NewPage = lazy(() => import('./NewPage')) export const routeRegistry = { '/new-page': { title: '新页面', component: NewPage }, // ... } ``` 菜单数据(`fetchMenu`)中的叶子节点 `route` 需与注册表中的 key 对应。 ## 待实现 - [ ] 后端菜单接口对接(替换 mock) - [ ] 菜单折叠状态持久化(localStorage) - [ ] 路由/接口列表业务页面 - [ ] 权限/用户管理业务页面 - [ ] 深色模式 / 主题切换