# 洛天依应用管理后台 (qy-lty-admin)

洛天依 APP 配套的 Web 管理后台，基于 **Next.js 15 (App Router) + React 19 + TypeScript** 构建，搭配 Tailwind CSS 与 Radix UI/shadcn 风格组件库，为运营与研发团队提供用户、AI 模型、卡牌、内容、权限等一体化的管理能力。后端 API 由 [qy_lty](../qy_lty/) 服务器项目统一提供（位于 `C:\Users\admin\Desktop\Lila-Server\qy_lty`）。

---

## 目录

- [功能概览](#功能概览)
- [技术栈](#技术栈)
- [权限矩阵](#权限矩阵)
- [快速开始](#快速开始)
- [环境变量](#环境变量)
- [项目结构](#项目结构)
- [鉴权与路由保护](#鉴权与路由保护)
- [API 集成](#api-集成)
- [构建与部署](#构建与部署)
- [浏览器支持](#浏览器支持)
- [许可证](#许可证)

---

## 功能概览

根据左侧导航及 [lib/permissions.ts](lib/permissions.ts) 中声明的权限模块，后台分为三大功能分组：

### AI 管理
- **大模型管理** `/ai-model` — 大模型框架接入、微调、语音克隆与合成、知识库管理入口

### 内容管理
- **服装管理** `/outfits`
- **道具管理** `/props`
- **家居装饰管理** `/home-decor`
- **食物管理** `/food`
- **歌曲管理** `/songs`
- **舞蹈管理** `/dances`
- **成就管理** `/achievements`
- **好感度系统** `/affinity`

### 系统管理
- **用户管理** `/users` — 用户列表、检索、创建/编辑/删除、登录历史
- **权限管理** `/permissions` — 角色与模块访问控制
- **系统设置** `/settings`

### 仪表盘
首页 [app/page.tsx](app/page.tsx) 汇总关键指标（总用户、活跃用户、卡牌激活、对话次数）、系统概览图表与最近活动，并提供主要业务模块的快捷入口。

### 账户
- 登录 `/login`、注册 `/register`、忘记密码 `/forgot-password`

---

## 技术栈

| 类别 | 选型 |
|------|------|
| 框架 | [Next.js 15.2.4](https://nextjs.org/)（App Router、standalone 输出）|
| 语言 | TypeScript 5 |
| UI 库 | [React 19](https://react.dev/) |
| 样式 | [Tailwind CSS 3.4](https://tailwindcss.com/) + `tailwindcss-animate` |
| 组件 | [Radix UI](https://www.radix-ui.com/) + shadcn 风格封装（见 [components/ui/](components/ui/)）|
| 图标 | [Lucide React](https://lucide.dev/) |
| 图表 | [Recharts](https://recharts.org/) |
| 表单 | [React Hook Form](https://react-hook-form.com/) + [Zod](https://zod.dev/) + `@hookform/resolvers` |
| HTTP 客户端 | [Axios](https://axios-http.com/)（含请求/响应拦截器）|
| 通知 | [Sonner](https://sonner.emilkowal.ski/) + Radix Toast |
| 主题 | [next-themes](https://github.com/pacocoursey/next-themes) |
| 其他 | `js-cookie`、`date-fns`、`react-day-picker`、`embla-carousel-react`、`cmdk`、`vaul` 等 |
| 包管理 | 兼容 npm / yarn / pnpm（Dockerfile 使用 yarn + 淘宝镜像源）|

---

## 权限矩阵

基于角色 (RBAC) 控制模块访问，定义位于 [lib/permissions.ts](lib/permissions.ts)。角色信息存储在 `localStorage.user_role`，由侧边栏 [components/sidebar.tsx](components/sidebar.tsx) 在客户端根据角色过滤可见菜单。

| 模块 / 角色 | 超级管理员 | 内容管理员 | AI模型管理员 | 卡牌管理员 | 查看者 |
|------------|:----------:|:----------:|:------------:|:----------:|:------:|
| 仪表盘 | ✓ | ✓ | ✓ | ✓ | ✓ |
| 用户管理 | ✓ | | | | |
| 权限管理 | ✓ | | | | |
| AI 模型管理 | ✓ | | ✓ | | |
| 服装 / 道具 / 家居 / 食物 | ✓ | ✓ | | ✓ | |
| 歌曲 / 舞蹈 / 成就 / 好感度 | ✓ | ✓ | | | |
| 系统设置 | ✓ | | | | |

辅助 API：`getUserRole()`、`getAllowedModules()`、`hasPermission(module)`、`hasPathPermission(pathname)`。

---

## 快速开始

### 环境要求
- Node.js **22.x** 及以上（与 Dockerfile 中的 `node:22.10.0-alpine` 对齐）
- 包管理器：npm / yarn / pnpm 任意其一
- 可访问的 Lila-Server API 服务

### 本地开发

```bash
# 1. 安装依赖
pnpm install       # 或 yarn / npm install

# 2. 配置环境变量
cp .env.example .env.local
# 编辑 .env.local，填入 NEXT_PUBLIC_API_BASE_URL

# 3. 启动开发服务器（默认 http://localhost:3000）
pnpm dev           # 或 yarn dev / npm run dev
```

### 可用脚本

| 命令 | 说明 |
|------|------|
| `next dev` | 启动开发服务器（HMR）|
| `next build` | 生产构建（启用 `webpackBuildWorker` 与并行编译）|
| `next start` | 启动生产服务器 |
| `next lint` | ESLint 检查（构建时已通过 `ignoreDuringBuilds` 忽略）|

> 注意：[next.config.mjs](next.config.mjs) 中 `eslint.ignoreDuringBuilds` 与 `typescript.ignoreBuildErrors` 均为 `true`，构建不会因 lint / 类型错误而失败，务必在本地执行 `next lint` 与 `tsc --noEmit` 保证质量。

---

## 环境变量

采用 Next.js 标准的环境变量机制，加载优先级（从低到高）：

```
.env → .env.development / .env.production → .env.local
```

暴露给浏览器的变量必须以 `NEXT_PUBLIC_` 前缀声明。

| 变量 | 说明 | 默认值 |
|------|------|--------|
| `NEXT_PUBLIC_API_BASE_URL` | 后端 API 基础地址，被 [lib/api/client.ts](lib/api/client.ts) 的 axios 实例使用 | `http://localhost:8000/api` |

初始化示例（存在 `.env.example` / `.env.local.example` 时）：

```bash
cp .env.example .env
cp .env.local.example .env.local
```

---

## 项目结构

```
qy-lty-admin/
├── app/                        # Next.js App Router 页面
│   ├── page.tsx                # 仪表盘首页
│   ├── layout.tsx              # 根布局
│   ├── globals.css             # 全局样式
│   ├── login/ register/ forgot-password/
│   ├── ai-model/               # AI 模型管理
│   ├── outfits/ props/ home-decor/ food/   # 卡牌管理
│   ├── songs/ dances/ achievements/ affinity/  # 内容管理
│   ├── users/ permissions/ settings/       # 系统管理
├── components/
│   ├── ui/                     # shadcn 风格的 Radix UI 封装
│   ├── sidebar.tsx             # 带权限过滤的侧边栏
│   ├── dashboard-shell.tsx     # 后台外壳布局
│   ├── dashboard-header.tsx    # 页头
│   ├── overview.tsx            # 仪表盘图表
│   ├── recent-activity.tsx     # 最近活动列表
│   ├── stat-card.tsx           # 指标卡片
│   ├── *-dialog.tsx            # 新增 / 删除 / 发布等对话框
│   └── <module>/               # 按业务模块拆分的业务组件
├── hooks/
│   ├── use-mobile.tsx          # 响应式断点 hook
│   └── use-toast.ts            # Toast hook
├── lib/
│   ├── api/                    # 业务 API 模块（见下节）
│   ├── permissions.ts          # 角色 / 权限矩阵
│   └── utils.ts                # cn 等通用工具
├── middleware.ts               # 基于 cookie 的路由保护
├── public/                     # 静态资源
├── styles/                     # 附加样式
├── Dockerfile                  # 多阶段构建（builder + runner）
├── docker-compose.yml          # 容器编排（端口 3030→3000）
├── next.config.mjs             # standalone 输出、实验项
├── tailwind.config.ts
└── tsconfig.json
```

---

## 鉴权与路由保护

项目采用"Cookie + localStorage + 前端权限矩阵"的三层方案：

1. **Cookie (`auth_token`)** — 由 [middleware.ts](middleware.ts) 读取。受保护路径列表见 `protectedPaths`，未携带 token 时重定向至 `/login?callbackUrl=<original>`。
2. **localStorage (`auth_token`)** — 由 [lib/api/client.ts](lib/api/client.ts) 的 axios 请求拦截器在每个请求上自动附加 `Authorization: Bearer <token>`；响应拦截器捕获 `401` 时清除 token 并跳转至 `/login`。
3. **前端权限矩阵** — [lib/permissions.ts](lib/permissions.ts) + [components/sidebar.tsx](components/sidebar.tsx)，根据 `localStorage.user_role` 过滤菜单与页面入口。

> 服务端（Next.js Middleware）仅校验 token 是否存在；真正的权限校验由后端 API 在业务接口中执行，前端权限矩阵用于提升 UX 而非安全边界。

---

## API 集成

所有业务 API 模块集中在 [lib/api/](lib/api/)：

| 文件 | 职责 |
|------|------|
| `client.ts` | axios 实例、拦截器、基础 URL、Mock 辅助工具 |
| `auth.ts` | 登录 / 注册 / 登出 / Token 管理 |
| `users.ts` / `roles.ts` | 用户与角色 |
| `ai-models.ts` | AI 模型相关接口 |
| `outfits.ts` / `props.ts` / `home-decor.ts` / `food.ts` / `card.ts` | 卡牌体系 |
| `songs.ts` / `dances.ts` / `achievements.ts` / `affinity.ts` | 内容与互动 |
| `upload.ts` | 文件上传 |
| `adapters.ts` | 后端 DTO → 前端 ViewModel 转换 |
| `error-handler.ts` | 统一错误处理 |
| `token-debug.ts` | Token 调试工具 |
| `types.ts` / `song.type.ts` | 共享类型定义 |
| `index.ts` | 聚合导出与 Mock 用户 / 角色 API |

> `index.ts` 中包含 Mock 数据与 `simulateDelay`，供联调或离线开发使用；生产环境应确保实际请求打向 `NEXT_PUBLIC_API_BASE_URL`。

---

## 构建与部署

### 本地构建

```bash
pnpm build
pnpm start         # 启动生产服务器
```

`next.config.mjs` 配置了 `output: 'standalone'`，构建产物位于 `.next/standalone`，适合作为独立部署单元。

### Docker

项目提供多阶段 [Dockerfile](Dockerfile)（builder + runner，基于 `node:22.10.0-alpine`，使用淘宝 npm 镜像）与 [docker-compose.yml](docker-compose.yml)：

```bash
# 构建镜像并启动
docker-compose up -d --build

# 访问 http://<host>:3030
```

Compose 关键配置：
- 容器名：`lty-admin`
- 端口映射：宿主机 `3030` → 容器 `3000`
- 环境文件：`.env.production`
- 挂载 `./public` 以便热更新静态资源
- `restart: always` 故障自动恢复

部署前确认 `.env.production` 已正确配置 `NEXT_PUBLIC_API_BASE_URL`。

---

## 浏览器支持

最新稳定版本的 Chrome / Firefox / Safari / Edge。项目使用 React 19 与现代 CSS 特性，不再适配 IE。

---

## 许可证

[MIT](LICENSE)
