Files

131 lines
5.0 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# OpenDance Studio 管理端(opendance-admin)
基于 **React 18 + TypeScript + Vite** 的管理后台,对接 `web-server` 的 NestJS API。
接口契约以 [`../contracts/rest-api.yaml`](../contracts/rest-api.yaml)(rest-api 0.1.0)为准,
字段语义见 [`../contracts/data-models.md`](../contracts/data-models.md)。
界面语言为简体中文;无任何 UI 组件框架,全部样式集中在 `src/styles.css`。
## 快速开始
```bash
npm install # 或 pnpm install
npm run dev # 开发服务器 http://localhost:5173
npm run build # 生产构建(tsc -b && vite build)-> dist/
npm run preview # 本地预览 dist/
npm run typecheck # 只做类型检查(tsc --noEmit)
```
> 管理端请求的是**同源**的 `/api/**` 与 `/health`,不含任何硬编码域名。
## 开发代理(dev proxy)
`vite.config.ts` 已把 `/api` 与 `/health` 代理到 `http://localhost:3000`:
```ts
server: {
port: 5173,
proxy: {
'/api': { target: 'http://localhost:3000', changeOrigin: true },
'/health': { target: 'http://localhost:3000', changeOrigin: true },
},
}
```
因此本地只需先启动服务端,再 `npm run dev` 即可,无需配置 CORS。
## `VITE_API_BASE`
`src/api/client.ts` 的基址取自:
```ts
const BASE_URL = import.meta.env.VITE_API_BASE?? '';
```
- **不设置(默认,空串)**:同源请求 -- 开发期走上面的 vite 代理,生产期走 nginx 反代。**推荐**。
- **设置**:例如服务端在另一台机器上:
```bash
#.env.local(不要提交)
VITE_API_BASE=http://192.0.2.10:3000
```
此时浏览器会直接跨域请求该地址,需要服务端开启 CORS。
构建期注入:`VITE_API_BASE=https://api.example.com npm run build`。
## 生产构建与部署
```bash
npm run build # 产物在 dist/
```
`vite.config.ts` 使用 `base: './'`,产物使用相对路径引用,可挂在任意子路径下。
**生产部署(业务服务自带管理端,不需要反代托管静态文件)**
构建产物 `dist/` 会被安装到 `$APP_DIR/admin`,并由 **NestJS 服务自身**托管
(含 SPA 深链接回退)。因此反向代理只需要把请求**整体转发**到后端端口即可,
不需要在代理层再配置静态站点或 `try_files`。
```bash
# 仓库根目录,一键部署后端(含管理端)
bash deploy/install.sh
```
- 后端通过 `ADMIN_DIR` 定位管理端产物,默认 `../admin`
- 反代配置样例:`deploy/proxy/nginx.conf.example`(nginx)、
`deploy/proxy/web.config.example`(IIS)
- 完整说明:`deploy/proxy/README.md`
## 目录结构
```
src/
main.tsx 入口(BrowserRouter)
App.tsx 路由表
styles.css 全部样式
api/
client.ts fetch 封装(ApiError / 分页 / multipart)
types.ts 契约类型(与 rest-api.yaml 一一对应)
endpoints.ts 契约端点封装
components/
Layout.tsx 左侧导航骨架
ui.tsx 通用组件(表格/弹窗/分页/来源五元组展示与表单...)
VrmPreview.tsx three + @pixiv/three-vrm 的 3D 预览(懒加载分包)
lib/
labels.ts 枚举中文文案
format.ts 时间/字节/时长格式化
validation.ts 客户端校验(来源五元组等)
useAsync.ts 加载/错误/重试 hook
pages/
Dashboard.tsx 概览
Songs.tsx 歌曲管理 T-WEB-008
Models.tsx 模型管理 T-WEB-009
Motions.tsx 动作管理 T-WEB-004/006
Reviews.tsx 审核 T-WEB-007
```
## 页面与任务对照
| 路由 | 说明 | 任务 |
|--|--|--|
| `/` | 概览:三类资产按状态计数、契约版本与目录指纹、健康检查、API 不可达告警 | - |
| `/songs` | 歌曲管理:分页/搜索/筛选、来源五元组必填、音频上传、软删除 | T-WEB-008 |
| `/models` | 模型管理:VRM 优先、来源五元组完整展示、设为默认、3D 预览 | T-WEB-009 |
| `/motions` | 动作管理:上传、预处理、关键点 NDJSON 下载 | T-WEB-004/006 |
| `/reviews` | 审核:待审列表 + 审核流水,通过/驳回(驳回必填意见) | T-WEB-007 |
所有页面都显式处理**加载中 / 空数据 / 请求失败**三种状态,请求失败不会白屏。
## 3D 预览说明
`src/components/VrmPreview.tsx`:`GLTFLoader` + `VRMLoaderPlugin`(来自 `@pixiv/three-vrm`),
- 依据 `vrm.meta.metaVersion` 区分 VRM 0.x / 1.0,0.x 自动执行 `VRMUtils.rotateVRM0`;
- 自实现鼠标拖拽旋转与滚轮缩放(未引入 OrbitControls);
- `requestAnimationFrame` 循环内调用 `vrm.update(delta)`,并按包围盒自动取景;
- 卸载时取消 RAF、断开 ResizeObserver、释放 renderer / geometry / material / texture;
- 无 WebGL 上下文时降级为错误提示,不会让页面崩溃。
`three` + `@pixiv/three-vrm`(约 750 kB)通过 `React.lazy` 单独分包,仅进入模型页时加载。