docs: README 全面更新 — 环境变量 + 部署 + 认证 + 开发规范
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>
This commit is contained in:
wangdl 2026-07-04 11:29:37 +08:00
parent 176593a8c2
commit d6b1df061d

212
README.md
View File

@ -4,78 +4,192 @@
## 技术栈 ## 技术栈
- React 19 + TypeScript 6 | 类别 | 技术 |
- Vite 8 |------|------|
- Ant Design 5 + @ant-design/pro-components 2.8 | 框架 | React 19 + TypeScript |
- @tanstack/react-query 5 | 构建 | Vite 8 |
- ECharts 5 + echarts-for-react 3 | UI | Ant Design 5 + @ant-design/pro-components 2.8 |
- dayjs | 状态管理 | @tanstack/react-query 5服务端状态+ Zustand客户端偏好 |
- react-router-dom v7 | 路由 | react-router-dom v7 |
| 图表 | ECharts 5 + echarts-for-react 3 |
| HTTP | Axios拦截器cookie 认证、自动刷新、错误通知) |
| 安全 | httpOnly cookie 认证token 不可被 JS 读取) |
## 项目结构 ## 项目结构
``` ```
src/ src/
├── components/ # 共享组件 ├── api/ # 33 个 API 模块(纯函数,导出 API 对象 + DTO 类型)
│ ├── AuditLogTable # 审计日志 ProTable │ └── index.ts # 统一 barrel export
│ ├── ConfirmDangerModal # 高危操作确认弹窗 ├── components/ # 11 个共享组件
│ ├── DetailDrawer # 侧滑详情抽屉 │ ├── ErrorBoundary # 渲染崩溃兜底
│ ├── EChartsChartContainer # 图表容器 │ ├── AuthGuard # 登录鉴权
│ ├── EmptyState # 空状态占位 │ ├── PermissionGuard # 角色权限
│ ├── MetricCard # 指标卡 │ └── ...
│ ├── StatusTag # 状态标签
│ ├── AuthGuard # 登录鉴权守卫
│ ├── PageLoading # 路由懒加载 Spin
│ └── PermissionGuard # 角色权限守卫
├── config/ ├── config/
│ └── menu.tsx # 菜单树与角色过滤 │ └── menu.tsx # 侧边栏菜单树 + 角色过滤
├── constants/ ├── constants/
│ └── roles.ts # 角色标签/颜色/层级 │ └── roles.ts # 角色标签/颜色/层级
├── contexts/ ├── contexts/
│ └── AuthContext.tsx # 认证上下文 │ └── AuthContext.tsx # 认证上下文(唯一 Context
├── hooks/ ├── hooks/
│ └── use-auth-query.ts # React Query 认证 hooks │ └── use-auth-query.ts # 认证 TanStack Query hooks
├── layouts/ ├── layouts/
│ └── AdminLayout.tsx # 管理后台布局(侧边栏/顶栏/面包屑) │ └── AdminLayout.tsx # ProLayout 管理后台骨架
├── pages/ ├── lib/
│ ├── Dashboard # 数据看板(指标卡 + 图表 + 审计日志) │ ├── 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 │ ├── UserManagement # 管理员 CRUD
│ ├── Login # 登录页 │ ├── ImportMonitor # 文档导入监控
│ ├── Placeholder # 占位页 │ ├── AiGateway # AI 网关路由管理
│ ├── 403/404/500 # 错误页 │ ├── Servers # 服务器运维监控
├── routes/ │ ├── TaskAssistant # AI 任务助手(流式对话)
│ └── index.tsx # 路由配置(懒加载 + 角色要求) │ └── ...
├── services/ ├── services/
│ ├── admin-api.ts # 类型化 API 函数 │ ├── ai-chat.ts # SSE 流式聊天
│ ├── http-client.ts # Fetch 封装401 自动刷新队列) │ ├── http-client.ts # 向后兼容重导出
│ ├── token-store.ts # Token 本地存储 │ └── token-store.ts # 向后兼容重导出
│ └── mock-data.ts # DEV 模式 Mock 数据 ├── stores/
└── types/ │ ├── index.ts # Zustand store barrel
├── admin.ts # AdminUser, DashboardStats, AuditLog 等 │ └── ui-store.ts # 侧边栏偏好persist localStorage
└── api.ts # PaginatedResult, ApiError ├── 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 ```bash
# 1. 安装依赖
npm install npm install
npm run dev # 开发模式,默认 http://localhost:5173
npm run build # 生产构建 # 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/
``` ```
## 认证流程 ## 环境变量
1. `AuthGuard` 检查登录状态,未登录跳转 `/login` | 变量 | 必需 | 默认值 | 说明 |
2. `PermissionGuard` 检查角色权限,不足跳转 `/403` |------|------|--------|------|
3. HTTP 客户端自动处理 401 → refresh token → 重试请求 | `VITE_API_BASE_URL` | 否 | `https://api.longde.cloud` | API 后端地址(仅开发模式使用) |
4. refresh token 失败时强制退出到 `/login`
- **本地开发**`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/refreshcookie 中的 refresh token
→ 刷新失败 → 清除缓存 → 跳转 /login
登出 POST /admin-api/auth/logout
→ 后端 Clear-Cookie
→ 前端清除 admin_user 缓存 + TanStack Query 缓存
```
## 角色体系 ## 角色体系
| 角色 | 说明 | 权限范围 | | 角色 | 说明 | 权限范围 |
|------|------|---------| |------|------|---------|
| SUPER_ADMIN | 超级管理员 | 全部权限,可管理其他管理员 | | `SUPER_ADMIN` | 超级管理员 | 全部权限,可管理其他管理员 |
| ADMIN | 管理员 | 用户管理、仪表盘、审计日志 | | `ADMIN` | 管理员 | 用户管理、仪表盘、审计日志 |
| OPERATIONS | 运营人员 | 仪表盘、审计日志(只读) | | `OPERATIONS` | 运营人员 | 仪表盘、审计日志(只读) |
| DEVELOPER | 开发者 | 仪表盘(只读) | | `DEVELOPER` | 开发者 | 仪表盘(只读) |
| READONLY | 只读用户 | 仪表盘(只读) | | `READONLY` | 只读用户 | 仪表盘(只读) |
## 部署
### CI/CDGitea 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` 添加菜单项