All checks were successful
Deploy Admin Frontend / build-and-deploy (push) Successful in 13s
- 更新项目结构(反映 18 个 types 文件、33 个 API 模块、Zustand 等) - 添加环境变量说明 - 添加认证架构(httpOnly cookie 流程) - 添加部署文档(CI/CD + 服务器架构 + 手动部署) - 添加开发规范(状态管理、错误处理、TypeScript) Co-Authored-By: Claude <noreply@anthropic.com>
196 lines
6.9 KiB
Markdown
196 lines
6.9 KiB
Markdown
# 知习 Admin
|
||
|
||
企业知识管理中台 — 后台管理系统前端。
|
||
|
||
## 技术栈
|
||
|
||
| 类别 | 技术 |
|
||
|------|------|
|
||
| 框架 | React 19 + TypeScript |
|
||
| 构建 | Vite 8 |
|
||
| UI | Ant Design 5 + @ant-design/pro-components 2.8 |
|
||
| 状态管理 | @tanstack/react-query 5(服务端状态)+ Zustand(客户端偏好) |
|
||
| 路由 | react-router-dom v7 |
|
||
| 图表 | ECharts 5 + echarts-for-react 3 |
|
||
| HTTP | Axios(拦截器:cookie 认证、自动刷新、错误通知) |
|
||
| 安全 | httpOnly cookie 认证(token 不可被 JS 读取) |
|
||
|
||
## 项目结构
|
||
|
||
```
|
||
src/
|
||
├── api/ # 33 个 API 模块(纯函数,导出 API 对象 + DTO 类型)
|
||
│ └── index.ts # 统一 barrel export
|
||
├── components/ # 11 个共享组件
|
||
│ ├── ErrorBoundary # 渲染崩溃兜底
|
||
│ ├── AuthGuard # 登录鉴权
|
||
│ ├── PermissionGuard # 角色权限
|
||
│ └── ...
|
||
├── config/
|
||
│ └── menu.tsx # 侧边栏菜单树 + 角色过滤
|
||
├── constants/
|
||
│ └── roles.ts # 角色标签/颜色/层级
|
||
├── contexts/
|
||
│ └── AuthContext.tsx # 认证上下文(唯一 Context)
|
||
├── hooks/
|
||
│ └── use-auth-query.ts # 认证 TanStack Query hooks
|
||
├── layouts/
|
||
│ └── AdminLayout.tsx # ProLayout 管理后台骨架
|
||
├── lib/
|
||
│ ├── api-client.ts # Axios 实例(withCredentials, 401 刷新, 错误通知)
|
||
│ ├── token.ts # 用户信息缓存(token 在 httpOnly cookie 中)
|
||
│ ├── antd-global.ts # 全局 message/notification 引用
|
||
│ └── error-handler.ts # 统一错误格式化和 toast
|
||
├── pages/ # 39 个页面 + learning/ 子目录
|
||
│ ├── Dashboard # 数据看板
|
||
│ ├── UserManagement # 管理员 CRUD
|
||
│ ├── ImportMonitor # 文档导入监控
|
||
│ ├── AiGateway # AI 网关路由管理
|
||
│ ├── Servers # 服务器运维监控
|
||
│ ├── TaskAssistant # AI 任务助手(流式对话)
|
||
│ └── ...
|
||
├── services/
|
||
│ ├── ai-chat.ts # SSE 流式聊天
|
||
│ ├── http-client.ts # 向后兼容重导出
|
||
│ └── token-store.ts # 向后兼容重导出
|
||
├── stores/
|
||
│ ├── index.ts # Zustand store barrel
|
||
│ └── ui-store.ts # 侧边栏偏好(persist localStorage)
|
||
├── types/ # 18 个领域类型文件,~80 个类型
|
||
│ ├── index.ts # 统一 barrel export
|
||
│ ├── admin.ts # AdminUser, AuditLog, DashboardStats
|
||
│ ├── knowledge.ts # KnowledgeBase, ImportJob, Source
|
||
│ ├── learning.ts # ReadingEvent, Session, Progress
|
||
│ ├── server.ts # ServerInfo, ProcessInfo, Health
|
||
│ ├── ai.ts # AiRoute, AiProvider, FallbackEvent
|
||
│ ├── billing.ts # CostItem, CostSummary, BillingInfo
|
||
│ ├── ui.ts # TypedColumn<T>, SortState, FilterState
|
||
│ └── ...
|
||
└── vite-env.d.ts # 环境变量类型声明
|
||
```
|
||
|
||
## 快速开始
|
||
|
||
```bash
|
||
# 1. 安装依赖
|
||
npm install
|
||
|
||
# 2. 配置环境变量
|
||
cp .env.example .env
|
||
# 编辑 .env,设置 VITE_API_BASE_URL(本地开发指向 http://127.0.0.1:3000)
|
||
|
||
# 3. 启动开发服务器
|
||
npm run dev # → http://localhost:5174
|
||
|
||
# 4. 生产构建
|
||
npm run build # → dist/
|
||
```
|
||
|
||
## 环境变量
|
||
|
||
| 变量 | 必需 | 默认值 | 说明 |
|
||
|------|------|--------|------|
|
||
| `VITE_API_BASE_URL` | 否 | `https://api.longde.cloud` | API 后端地址(仅开发模式使用) |
|
||
|
||
- **本地开发**:`VITE_API_BASE_URL=http://127.0.0.1:3000`(Vite dev server 代理 /admin-api/ 到本地 API)
|
||
- **生产环境**:不需要设置,Nginx 将 `/admin-api/` 反向代理到后端
|
||
- `.env.example` 已提交到 Git,复制即可使用
|
||
- `.env` 在 `.gitignore` 中,不会被提交
|
||
|
||
## 认证架构
|
||
|
||
```
|
||
登录 POST /admin-api/auth/login
|
||
→ 后端 Set-Cookie: admin_access_token (httpOnly, Secure, SameSite=Strict)
|
||
→ 前端仅缓存 admin_user 信息到 localStorage(非敏感)
|
||
|
||
后续请求
|
||
→ axios withCredentials: true → 浏览器自动携带 cookie
|
||
→ 后端 AdminAuthGuard 从 cookie 读取 JWT
|
||
→ 401 → 自动调用 /admin-api/auth/refresh(cookie 中的 refresh token)
|
||
→ 刷新失败 → 清除缓存 → 跳转 /login
|
||
|
||
登出 POST /admin-api/auth/logout
|
||
→ 后端 Clear-Cookie
|
||
→ 前端清除 admin_user 缓存 + TanStack Query 缓存
|
||
```
|
||
|
||
## 角色体系
|
||
|
||
| 角色 | 说明 | 权限范围 |
|
||
|------|------|---------|
|
||
| `SUPER_ADMIN` | 超级管理员 | 全部权限,可管理其他管理员 |
|
||
| `ADMIN` | 管理员 | 用户管理、仪表盘、审计日志 |
|
||
| `OPERATIONS` | 运营人员 | 仪表盘、审计日志(只读) |
|
||
| `DEVELOPER` | 开发者 | 仪表盘(只读) |
|
||
| `READONLY` | 只读用户 | 仪表盘(只读) |
|
||
|
||
## 部署
|
||
|
||
### CI/CD(Gitea Actions)
|
||
|
||
推送到 `main` 分支自动触发 `.gitea/workflows/deploy.yml`:
|
||
|
||
```
|
||
git clone → npm install → npm run build → rsync dist/ → /opt/zhixi/admin/dist/ → nginx reload
|
||
```
|
||
|
||
### 生产服务器架构
|
||
|
||
```
|
||
admin.longde.cloud (Nginx)
|
||
├── / → /opt/zhixi/admin/dist/ (静态文件, SPA fallback)
|
||
├── /admin-api/ → proxy_pass http://127.0.0.1:3000
|
||
└── /assets/ → 静态资源缓存 (1年, gzip)
|
||
```
|
||
|
||
### 手动部署
|
||
|
||
```bash
|
||
npm run build
|
||
rsync -av --delete dist/ ubuntu@120.53.227.155:/opt/zhixi/admin/dist/
|
||
ssh ubuntu@120.53.227.155 'sudo systemctl reload nginx'
|
||
```
|
||
|
||
## 开发规范
|
||
|
||
### 状态管理原则
|
||
|
||
```
|
||
TanStack Query → 服务端数据(缓存、去重、refetch)
|
||
Zustand → 客户端全局状态(UI 偏好)
|
||
AuthContext → 认证(登录/登出/权限)
|
||
useState → 页面局部 UI(弹窗、表单、选中行)
|
||
```
|
||
|
||
- 不在组件内 `useEffect` + `fetch` — 一律用 `useQuery`
|
||
- 不新建 Context — 除非是真正的全局状态
|
||
- 页面局部的 `useState` 不需要提到 Store
|
||
|
||
### 错误处理
|
||
|
||
```typescript
|
||
// 异步操作中使用 toastError
|
||
try { await something() } catch (err) { toastError(err, '操作失败') }
|
||
|
||
// 全局兜底
|
||
// - ErrorBoundary 包裹所有路由(渲染崩溃不白屏)
|
||
// - TanStack Query mutation 默认 onError → toastError
|
||
// - Axios 响应拦截器 → 网络/业务错误自动 notification.error
|
||
```
|
||
|
||
### TypeScript
|
||
|
||
- `strict: true`(`noImplicitAny` 和 `strictNullChecks` 待收紧)
|
||
- 所有 API 模块有完整类型(DTO + Response)
|
||
- Table 列使用具体记录类型,不用 `(_: any, r: any)`
|
||
- 新增类型放在 `src/types/` 对应领域文件,通过 `index.ts` 导出
|
||
|
||
### 新增页面 Checklist
|
||
|
||
1. 在 `src/pages/` 创建页面组件
|
||
2. 在 `src/types/` 补充缺失的领域类型
|
||
3. 在 `src/api/` 添加对应 API 模块(如需要)
|
||
4. 在 `App.tsx` 添加路由(懒加载 + 角色守卫)
|
||
5. 在 `config/menu.tsx` 添加菜单项
|