Files
juip-web/.github/copilot-instructions.md
2026-08-13 18:28:20 +08:00

159 lines
5.8 KiB
Markdown
Raw 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.
# juip-web - AI 开发助手指南
## 项目概述
Vite + React 19 纯 SPA 代理服务站点,包含公开营销页与用户管理后台。使用 Bun 运行时、react-router-dom 7 路由、Tailwind CSS 4、shadcn/ui (radix-nova 风格)、sonner 提示、biome 代码规范。
**核心业务**: IP 代理产品展示与购买、订单支付、短信验证码注册登录、后台资源/通道/白名单管理
## 架构模式
### 三层数据流架构
1. **API 层** (`src/api/*.ts`) - 所有后端调用统一入口
- 每个文件对应一个业务域 (auth, order, product, verify, captcha)
- 通过 `base.ts` 的三种调用模式访问后端:
- `callPublic()` - 无需认证的公开接口
- `callByDevice()` - 使用 CLIENT_ID/CLIENT_SECRET 的设备级认证
- `callByUser()` - 使用用户会话 token 的用户级认证
- 所有调用返回统一的 `ApiResponse<T>` 类型
- 后端存在两套响应约定,`base.ts` 自动识别:
- 裸 JSON (OAuth2 接口、`/script/linedata/*.php` 等) - 原样返回
- 会员接口信封 `{Code, Message, Data}` - 顶层有 `Code` 字段时自动解包: `Code === 10000` 成功返回 `Data`/`data`,否则转 `success: false` + `Message`
2. **会话状态** (`src/api/token.ts`) - 令牌存取唯一入口
- 登录后 token/userInfo 由后端 Set-Cookie 下发,经 `apiLogin` 镜像到 localStorage
- `setSession()` / `clearSession()` 统一派发 `auth-change` 事件驱动 UI 重渲染
- UI 组件 (header/authGuard) 通过 `isAuthed()` 读取登录态,禁止直接读 localStorage
- 401 时 user 模式自动 `clearSession()`device 模式自动清缓存重取设备令牌
3. **UI 层** - 业务域 API 函数供组件直接调用
- 公开页组件位于 `src/home/*`,后台位于 `src/admin/*`
- `/admin` 路由由 `AuthGuard` 保护,未登录重定向 `/login?redirect=`
### API 层使用示例
```typescript
// 业务域文件: src/api/xxx.ts
import type { ApiResponse } from "@/lib/api"
import { callByUser, callPublic } from "./base"
// 1. 公开接口 (GET 自动并发去重)
const resp = await callPublic<{ token: string; base64: string }>(
"/api/captcha/get",
undefined,
"GET",
)
// 2. 设备级认证 (client_credentials 令牌模块内单飞缓存,提前 60s 过期)
const resp2 = await callByDevice<{ access_token: string }>(
"/api/auth/token",
{ grant_type: "client_credentials" },
)
// 3. 用户级认证 (读取会话 token401 自动清会话)
const resp3 = await callByUser<CreateOrderData>("/product/CreateOrder", data)
const resp4 = await callByUser<number>(
`/product/IsPay?orderNo=${orderNo}`,
undefined,
"GET",
)
// 4. Code 信封接口 (顶层有 Code 字段自动解包Code === 10000 成功)
const resp5 = await callPublic("/user/ApiLogin", {
Logincode: "xxx",
Password: "xxx",
})
const resp6 = await callPublic<ProductItem[]>(
"/product/ApiProductActive",
undefined,
"GET",
)
// 5. 统一响应处理
if (resp.success) {
console.log(resp.data) // 强类型 T
} else {
console.error(resp.status, resp.message)
}
```
### 组件调用示例
```typescript
import { fetchProducts } from "@/api/product"
import { toast } from "sonner"
const result = await fetchProducts()
if (result.success) {
setProducts(result.data)
} else {
toast.error(result.message)
}
```
## 路由组织
- `/` - 公开站点 (LayoutPage 统一头部/底部): 首页、`/product`(+`/buy`/`/http`/`/routeros`)、`/ipline``/softdownload``/help``/client`
- `/login` - 登录/注册 (tab 状态经 `location.state.tab` 切换)
- `/admin` - 用户后台 (AuthGuard 保护): dashboard、channels、whitelist、funds、product/long、product/short
路由定义集中在 `src/routers/index.tsx`
## 开发工作流
### 命令速查
```bash
bun install # 安装依赖
bun dev # 开发服务器 (vite --host)
bun run build # 生产构建 (tsc -b && vite build)
bun run lint # biome 检查并自动修复
```
### 代码规范 (biome)
- 无分号、双引号、2 空格缩进、单参数箭头函数省略括号
- import 自动排序 (organizeImports)
- `noNonNullAssertion` 为 error禁用 `!` 断言
- 提交前运行 `bun run lint`
### 组件开发模式
**shadcn/ui 组件** (`src/components/ui/*.tsx`)
- 通过 CLI 添加: `bunx shadcn@latest add <component>`
- 类名合并使用 `cn()` (来自 `@/lib/utils`)
**业务组件**
- `src/components/composites/*` - 复杂对话框等
- `src/components/*` - 通用组件 (wrap 布局容器、authGuard 路由守卫、data-table、page)
**表单**: react-hook-form + zod 校验
**提示**: 统一使用 sonner (`toast.success / toast.error`)
## 项目特定约定
### 类型定义
- 后端响应统一为 `ApiResponse<T>` (定义于 `src/lib/api.ts`):
- 成功: `{success: true, data: T}`
- 失败: `{success: false, status?: number, message: string}`
- 请求/响应业务类型定义在对应业务域 API 文件中 (如 `src/api/order.ts``CreateOrderRequest`)
- UI 展示模型位于 `src/lib/models/*`
### 环境变量 (见 `.env`)
- `VITE_API_BASE_URL` - 后端地址 (留空表示同源,登录 Cookie 自动携带)
- `VITE_CLIENT_ID` / `VITE_CLIENT_SECRET` - OAuth2 设备认证凭据 (当前均为 `web`)
## 关键文件参考
- [src/api/base.ts](src/api/base.ts) - API 调用核心 (三模式 + Code 信封适配 + GET 去重 + 设备令牌缓存)
- [src/api/token.ts](src/api/token.ts) - 会话状态存取与 auth-change 事件
- [src/api/auth.ts](src/api/auth.ts) - 登录/注册/退出业务域
- [src/lib/api.ts](src/lib/api.ts) - ApiResponse 类型与后端配置
- [src/routers/index.tsx](src/routers/index.tsx) - 全部路由定义
- [src/components/authGuard.tsx](src/components/authGuard.tsx) - 后台路由守卫
- [src/home/header.tsx](src/home/header.tsx) - 登录态响应式更新 (auth-change/focus 事件)