更新构建文件 & 添加项目提示文档
This commit is contained in:
@@ -1,6 +1,10 @@
|
|||||||
.idea/
|
.idea/
|
||||||
.vscode/
|
.vscode/
|
||||||
|
.zed/
|
||||||
|
|
||||||
|
./git
|
||||||
|
./github
|
||||||
|
|
||||||
node_modules/
|
node_modules/
|
||||||
.next/
|
.next/
|
||||||
.env
|
.env
|
||||||
139
.github/copilot-instructions.md
vendored
Normal file
139
.github/copilot-instructions.md
vendored
Normal file
@@ -0,0 +1,139 @@
|
|||||||
|
# 蓝狐代理 (Lanhu Proxy) - AI 开发助手指南
|
||||||
|
|
||||||
|
## 项目概述
|
||||||
|
|
||||||
|
Next.js 15+ 代理服务平台,包含公开营销站点与用户管理后台。使用 Bun 运行时,React 19 Server Components,shadcn/ui 组件库。
|
||||||
|
|
||||||
|
**核心业务**: IP 代理购买、提取、白名单管理、实名认证、充值计费
|
||||||
|
|
||||||
|
## 架构模式
|
||||||
|
|
||||||
|
### 三层数据流架构
|
||||||
|
|
||||||
|
1. **Server Actions** (`src/actions/*.ts`) - 所有 API 调用统一入口
|
||||||
|
- 每个文件对应一个业务域 (auth, bill, ip, resource 等)
|
||||||
|
- 通过 `base.ts` 的三种调用模式访问后端:
|
||||||
|
- `callPublic()` - 无需认证的公开接口
|
||||||
|
- `callByDevice()` - 使用 CLIENT_ID/CLIENT_SECRET 的设备级认证
|
||||||
|
- `callByUser()` - 使用用户会话 token 的用户级认证
|
||||||
|
- 所有调用都用 `cache()` 包装以支持 React 缓存
|
||||||
|
- 返回统一的 `ApiResponse<T>` 类型
|
||||||
|
|
||||||
|
2. **Zustand Store** (`src/components/stores/*.tsx`) - 客户端状态管理
|
||||||
|
- 异步初始化模式: 通过 Promise 传递服务端数据到客户端
|
||||||
|
- `ProfileStoreProvider` 在根布局初始化用户资料
|
||||||
|
- 每个 store 导出: `createXxxStore()`, `XxxStoreProvider`, `useXxxStore()`
|
||||||
|
- 示例: `profile.tsx` 使用 `profile: Promise<User | null>` 实现服务端到客户端水合
|
||||||
|
|
||||||
|
3. **认证流程** - Token 刷新在 middleware 自动处理
|
||||||
|
- `src/proxy.ts` (middleware) 检测 `auth_token` 过期时自动调用 `refreshAuth()`
|
||||||
|
- 访问 `/admin` 路径无 token 时重定向到 `/login?redirect=`
|
||||||
|
- Cookies: `auth_token` (访问令牌), `auth_refresh` (刷新令牌)
|
||||||
|
|
||||||
|
### 路由组织
|
||||||
|
|
||||||
|
- **(home)** - 公开营销站点,包含产品介绍、文档中心、定制服务
|
||||||
|
- **(auth)** - 登录、实名认证、隐私协议、兑换码
|
||||||
|
- **admin** - 用户后台,包含仪表盘、账单、资源管理、白名单、提取功能
|
||||||
|
- **(api)/proxies** - API 端点路由
|
||||||
|
|
||||||
|
括号路由 `(group)` 不影响 URL 路径,仅用于组织布局层级。
|
||||||
|
|
||||||
|
### 验证码集成 (Cap.js)
|
||||||
|
|
||||||
|
- `src/lib/cap/index.ts` 自定义存储实现,使用 HMAC 签名的 Cookie 而非文件系统
|
||||||
|
- `getCap()` 返回配置好的 Cap 实例
|
||||||
|
- Challenge 和 token 都存储在 httpOnly cookies 中
|
||||||
|
- `sign()` / `verify()` 基于 CLIENT_SECRET 的签名验证
|
||||||
|
|
||||||
|
## 开发工作流
|
||||||
|
|
||||||
|
### 命令速查
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun install # 安装依赖
|
||||||
|
bun dev # 开发服务器 (0.0.0.0:3000 + Turbopack)
|
||||||
|
bun run build # 生产构建 (Turbopack)
|
||||||
|
bun start # 启动生产服务器
|
||||||
|
bun run lint # ESLint 自动修复
|
||||||
|
bun run check # TypeScript 类型检查
|
||||||
|
```
|
||||||
|
|
||||||
|
### 组件开发模式
|
||||||
|
|
||||||
|
**shadcn/ui 组件** (`src/components/ui/*.tsx`)
|
||||||
|
- 使用 `components.json` 配置,New York 风格
|
||||||
|
- 通过 CLI 添加: `bunx shadcn@latest add <component>`
|
||||||
|
- 所有组件使用 `merge()` (twMerge 别名) 合并类名
|
||||||
|
|
||||||
|
**业务组件** (`src/components/composites/*`)
|
||||||
|
- 复杂表单、对话框、支付组件等放在此目录
|
||||||
|
- 标记 `'use client'` 的客户端组件
|
||||||
|
- 示例: `purchase/index.tsx` 使用 URL 查询参数控制 Tab 状态
|
||||||
|
|
||||||
|
**工具函数**
|
||||||
|
- `merge(...inputs)` - 合并 Tailwind 类名 (来自 `@/lib/utils`)
|
||||||
|
- `Children` 类型 - 标准 `{children: ReactNode}` 类型别名
|
||||||
|
|
||||||
|
### MDX 文档系统
|
||||||
|
|
||||||
|
- 文档源文件: `src/docs/*.mdx`
|
||||||
|
- 配置: `next.config.ts` 集成 `@next/mdx`, `remark-gfm`, `rehype-highlight`
|
||||||
|
- 页面扩展名: `.md`, `.mdx`, `.js`, `.jsx`, `.ts`, `.tsx`
|
||||||
|
- 布局: `src/app/(home)/docs/layout.tsx` 提供面包屑和侧边栏
|
||||||
|
|
||||||
|
## 项目特定约定
|
||||||
|
|
||||||
|
### 类型定义模式
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// 从 server action 推断请求/响应类型
|
||||||
|
type ExtraReq<T> = T extends (...args: infer P) => unknown ? P[0] : never
|
||||||
|
type ExtraResp<T> = Awaited<ReturnType<T>> extends ApiResponse<infer D> ? D : never
|
||||||
|
|
||||||
|
// 使用示例
|
||||||
|
type LoginRequest = ExtraReq<typeof login>
|
||||||
|
type UserProfile = ExtraResp<typeof getProfile>
|
||||||
|
```
|
||||||
|
|
||||||
|
### 错误处理
|
||||||
|
|
||||||
|
- Server actions 返回 `ApiResponse<T>`:
|
||||||
|
- 成功: `{success: true, data: T}`
|
||||||
|
- 失败: `{success: false, status: number, message: string}`
|
||||||
|
- 使用 `sonner` (Toaster) 显示用户提示
|
||||||
|
- 预定义错误: `UnauthorizedError` (401 场景)
|
||||||
|
|
||||||
|
### 样式规范
|
||||||
|
|
||||||
|
- 主色系: `primary-*`, `card`, `primary-muted`
|
||||||
|
- 响应式断点: 使用 Tailwind 默认 (`sm:`, `md:`, `lg:`)
|
||||||
|
- 布局: 首页使用 `bg-blue-50` 背景,后台使用 `bg-card` 和圆角遮罩 (见 `admin/layout.tsx`)
|
||||||
|
|
||||||
|
## 关键文件参考
|
||||||
|
|
||||||
|
- [src/actions/base.ts](src/actions/base.ts) - API 调用核心抽象
|
||||||
|
- [src/proxy.ts](src/proxy.ts) - 认证 middleware 和 token 刷新逻辑
|
||||||
|
- [src/components/stores/profile.tsx](src/components/stores/profile.tsx) - 异步 store 初始化模式
|
||||||
|
- [src/lib/cap/index.ts](src/lib/cap/index.ts) - Cap.js 自定义存储实现
|
||||||
|
- [src/app/layout.tsx](src/app/layout.tsx) - Store providers 和异步初始化
|
||||||
|
- [next.config.ts](next.config.ts) - MDX、React Compiler、Turbopack 配置
|
||||||
|
|
||||||
|
## 环境变量
|
||||||
|
|
||||||
|
需要配置:
|
||||||
|
- `NEXT_PUBLIC_API_BASE_URL` - 后端 API 地址
|
||||||
|
- `CLIENT_ID`, `CLIENT_SECRET` - OAuth2 设备认证凭据
|
||||||
|
|
||||||
|
## 部署
|
||||||
|
|
||||||
|
- 使用 `output: 'standalone'` 模式
|
||||||
|
- Dockerfile 多阶段构建 (Bun 1.2.19 Alpine)
|
||||||
|
- 生产端口: 3000
|
||||||
|
|
||||||
|
## 待改进事项 (来自 README)
|
||||||
|
|
||||||
|
- 考虑使用 SWR/React Query 替代当前的 server cache + zustand 混合方案
|
||||||
|
- 手机端优化: 购买和提取页面需一页展示全部内容
|
||||||
|
- IP 管理按长短效分页
|
||||||
|
- 后台导航结构重组 (当前过于分散)
|
||||||
23
Dockerfile
23
Dockerfile
@@ -1,37 +1,30 @@
|
|||||||
FROM node:22.14-alpine AS base
|
FROM oven/bun:1.2.19-alpine AS base
|
||||||
|
|
||||||
# 运行时依赖
|
|
||||||
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories
|
|
||||||
RUN apk add cairo pango giflib ttf-dejavu
|
|
||||||
|
|
||||||
# 依赖缓存阶段
|
# 依赖缓存阶段
|
||||||
FROM base AS deps
|
FROM base AS deps
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
RUN apk add build-base g++ cairo-dev pango-dev giflib-dev
|
COPY package.json bun.lock ./
|
||||||
|
RUN bun config set registry https://registry.npmmirror.com
|
||||||
COPY package.json pnpm-lock.yaml* ./
|
RUN bun install --frozen-lockfile
|
||||||
RUN corepack enable pnpm
|
|
||||||
RUN pnpm config set registry https://registry.npmmirror.com
|
|
||||||
RUN pnpm install --frozen-lockfile
|
|
||||||
|
|
||||||
# 构建阶段
|
# 构建阶段
|
||||||
FROM base AS builder
|
FROM base AS builder
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
COPY --from=deps /app/node_modules ./node_modules
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY .. .
|
COPY . .
|
||||||
|
|
||||||
ENV NEXT_TELEMETRY_DISABLED=1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
|
||||||
RUN corepack enable pnpm
|
RUN bun run build
|
||||||
RUN pnpm run build
|
|
||||||
|
|
||||||
# 生产阶段
|
# 生产阶段
|
||||||
FROM base AS runner
|
FROM base AS runner
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
ENV NEXT_TELEMETRY_DISABLED=1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
ENV NODE_ENV=production
|
||||||
|
|
||||||
RUN addgroup --system --gid 1001 nodejs
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
RUN adduser --system --uid 1001 nextjs
|
RUN adduser --system --uid 1001 nextjs
|
||||||
@@ -47,4 +40,4 @@ EXPOSE 3000
|
|||||||
ENV PORT=3000
|
ENV PORT=3000
|
||||||
ENV HOSTNAME="0.0.0.0"
|
ENV HOSTNAME="0.0.0.0"
|
||||||
|
|
||||||
CMD ["node", "server.js"]
|
CMD ["bun", "server.js"]
|
||||||
|
|||||||
Reference in New Issue
Block a user