# 万象口袋 — 前端文档

**技术栈**：React 18 · React Router 6 · Tailwind CSS v4 · axios · Vite 6

**包名**：`infogenie-frontend`（见 `package.json`）

---

## 命令

| 命令 | 说明 |
|------|------|
| `npm run dev` / `npm start` | 开发服务器（默认端口 3000） |
| `npm run build` | 生产构建，输出 `dist/` |
| `npm run preview` | 本地预览 `dist/` 构建结果 |

---

## 项目结构（关键文件）

```
infogenie-frontend/
├── index.html            ← Vite HTML 入口（根目录，非 public/）
├── vite.config.js        ← Vite 配置（React 插件、Tailwind 插件、路径别名）
├── package.json
├── .env.development      ← 开发环境变量
├── .env.production       ← 生产环境变量
├── public/               ← 静态资源（不参与构建，直接复制到 dist/）
│   ├── assets/logo.png
│   ├── icons/
│   ├── aimodelapp/       ← AI 小应用静态页
│   ├── smallgame/        ← 小游戏静态页
│   └── toolbox/          ← 工具箱静态页
└── src/
    ├── index.js          ← React 根挂载
    ├── App.js            ← 路由、布局、全局 Provider
    ├── components/       ← 公共组件
    ├── pages/            ← 页面组件
    ├── contexts/         ← 全局 Context
    ├── hooks/            ← 自定义 Hooks
    ├── utils/            ← Axios 封装、可见性过滤等
    ├── config/           ← 环境变量解析、路由/内容配置
    └── styles/
        ├── index.css     ← Tailwind 入口 + 全局 base 样式 + 自定义动画
        └── shared.js     ← 设计系统组件（Tailwind 函数组件）
```

---

## Vite 配置（`vite.config.js`）

| 特性 | 说明 |
|------|------|
| `@vitejs/plugin-react` | React Fast Refresh + JSX 转换（含 `.js` 扩展名支持） |
| `@tailwindcss/vite` | Tailwind CSS v4 Vite 插件，零配置文件 |
| `treat-js-as-jsx` | 内联插件，使 `.js` 文件中的 JSX 正常编译 |
| `resolve.alias['@']` | `@/` 映射到 `src/` |
| `base: '/'` | 部署根路径 |
| `server.port: 3000` | 开发服务器端口 |

---

## 环境变量（`src/config/env.js`）

变量名使用 Vite 规范的 `VITE_` 前缀（通过 `import.meta.env` 访问）：

| 变量 | 作用 | 开发默认 / 生产默认 |
|------|------|---------------------|
| `VITE_API_URL` | 万象口袋 **Go 后端** 根地址 | dev：`http://127.0.0.1:5002`；prod：`https://infogenie.api.shumengya.top` |
| `VITE_AUTH_URL` | 认证中心 **页面** 域名 | `https://auth.shumengya.top` |
| `VITE_AUTH_API_URL` | 认证中心 **API** 根地址 | `https://auth.api.shumengya.top` |
| `VITE_DEBUG` | 调试开关 | `'true'` 开启 |

运行时可通过 `window.ENV_CONFIG` 查看解析结果。

> **迁移注意**：从 CRA 迁移时原 `REACT_APP_*` 变量已全部重命名为 `VITE_*`。

---

## 主应用结构（`src/`）

### 路由（`src/App.js`）

| 路径 | 页面 |
|------|------|
| `/` | 首页 |
| `/login` | 登录 |
| `/auth/callback` | 认证回调 |
| `/60sapi` · `/60sapi/:itemId` | 60s API 列表与详情 |
| `/smallgame` | 休闲游戏 |
| `/toolbox` | 工具箱 |
| `/aimodel` | AI 应用（需登录） |
| `/profile` | 个人中心 |
| `/admin` | 管理 |
| `*` | 重定向首页 |

### 关键组件

- **`RandomSiteBackground`**：全站随机背景（`https://randbg.api.smyhub.com/api/random?format=json`），毛玻璃模糊，会话级缓存。
- **`Header` / `Footer`**：半透明绿 + `backdrop-filter`；**移动端 `Navigation`** 底栏为不透明渐变 + 圆角顶。
- **`FullscreenEmbed`**：全屏 iframe（游戏、工具箱、AI 静态页），支持注入 token、加载超时提示。
- **`ParticleEffect`**：全局点击粒子动画。

---

## 样式系统（`src/styles/`）

### Tailwind CSS v4

- **入口**：`src/styles/index.css`，顶部 `@import "tailwindcss"`
- **配置**：Tailwind v4 CSS-first，无独立 `tailwind.config.js`，自定义动画通过 `@theme` 块定义

自定义动画（可直接在 className 中使用）：

| 类名 | 效果 | 用途 |
|------|------|------|
| `animate-page-enter` | `opacity: 0→1, translateY: 20px→0, 0.8s` | 页面进入 |
| `animate-fade-up` | `opacity: 0→1, translateY: 12px→0, 0.35s` | 卡片网格出现 |

### 设计系统（`src/styles/shared.js`）

所有组件均为 **React 函数组件**，接受 `className` prop（可与额外 Tailwind 类合并）：

- **`PageWrapper`**：页面容器，带 `animate-page-enter` 入场动画
- **`Container`**：最大宽度容器，`$narrow`（800px）/ 默认（1200px）
- **`FeatureGrid`**：响应式 5→4→3→2 列网格，带 `animate-fade-up`
- **`CatalogCard`** / **`FeatureCard`**：统一卡片样式，顶条渐变色动态注入（`$c` prop）
- **`FeatureCardUseCount`**：卡片右上角点击次数角标
- **`ModuleCard`**：首页大模块横向卡片（包装 `react-router-dom` `Link`）
- **`accentFromGradient`**：工具函数，从 gradient 字符串提取首色

> 动态样式（渐变色、动态 grid 列数等）通过 inline `style` prop 注入，Tailwind 负责静态部分。

---

## HTTP（`src/utils/api.js`）

- axios 实例默认 `baseURL = ENV_CONFIG.API_URL`，请求头自动带 `Bearer token`
- `import.meta.env.DEV` 控制仅开发环境打印 URL
- 支持 `skipErrorToast: true`，用于静默失败场景（如点击统计）

---

## 静态资源（`public/`）

与 Vite 主站并列的大量**免构建**页面：

- **`public/aimodelapp/<应用名>/`**：AI 小应用（HTML + `script.js` + 可选 `env.js`）。
  - 统一聊天入口：**`public/aimodelapp/shared/ai-chat.js`** 的 `AiChat.complete()`。
  - **优先**请求 **`POST /api/aimodelapp/chat/stream`**（SSE），失败或无内容时回退 **`POST /api/aimodelapp/chat`**。
- **`public/smallgame/`**、**`public/toolbox/`**：独立小游戏与工具页，由 `FullscreenEmbed` 打开。

各 `aimodelapp` 子目录的 **`env.js`** / **`API_CONFIG`** 需指向与主站一致的 Go 后端地址（通常与 `VITE_API_URL` 同源或同网段）。

---

## 与后端协作要点

1. **登录**：token 存 `localStorage`，AI 与受保护接口依赖 JWT。
2. **AI**：静态页通过 **同源或配置的 API** 调 Go 的 `/api/aimodelapp/*`；流式响应类型为 **`text/event-stream`**。
3. **站点开关**：60s / AI 应用显隐由 `GET /api/site/*-disabled` 等驱动（见后端文档）。
4. **卡片统计**：四大板块列表页的 `CatalogCard` 已接 `feature-card-clicks` 接口。

---

## 其他文档

- **Go 后端 API 与表结构**：[`infogenie-backend-go/后端文档.md`](../infogenie-backend-go/后端文档.md)
- **仓库与工具说明**：[`../.claude/README.md`](../.claude/README.md)
