From d62367f37eae47e3d3f12be9b080cfc203b76992 Mon Sep 17 00:00:00 2001 From: luorijun Date: Mon, 15 Dec 2025 12:50:45 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=9E=84=E5=BB=BA=E6=96=87?= =?UTF-8?q?=E4=BB=B6=20&=20=E6=B7=BB=E5=8A=A0=E9=A1=B9=E7=9B=AE=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E6=96=87=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .dockerignore | 6 +- .github/copilot-instructions.md | 139 ++++++++++++++++++++++++++++++++ Dockerfile | 23 ++---- 3 files changed, 152 insertions(+), 16 deletions(-) create mode 100644 .github/copilot-instructions.md diff --git a/.dockerignore b/.dockerignore index a594425..91cebfc 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,6 +1,10 @@ .idea/ .vscode/ +.zed/ + +./git +./github node_modules/ .next/ -.env +.env \ No newline at end of file diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md new file mode 100644 index 0000000..70c4154 --- /dev/null +++ b/.github/copilot-instructions.md @@ -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` 类型 + +2. **Zustand Store** (`src/components/stores/*.tsx`) - 客户端状态管理 + - 异步初始化模式: 通过 Promise 传递服务端数据到客户端 + - `ProfileStoreProvider` 在根布局初始化用户资料 + - 每个 store 导出: `createXxxStore()`, `XxxStoreProvider`, `useXxxStore()` + - 示例: `profile.tsx` 使用 `profile: Promise` 实现服务端到客户端水合 + +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 ` +- 所有组件使用 `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 extends (...args: infer P) => unknown ? P[0] : never +type ExtraResp = Awaited> extends ApiResponse ? D : never + +// 使用示例 +type LoginRequest = ExtraReq +type UserProfile = ExtraResp +``` + +### 错误处理 + +- Server actions 返回 `ApiResponse`: + - 成功: `{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 管理按长短效分页 +- 后台导航结构重组 (当前过于分散) diff --git a/Dockerfile b/Dockerfile index 3cfe410..4015c94 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,37 +1,30 @@ -FROM node:22.14-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 oven/bun:1.2.19-alpine AS base # 依赖缓存阶段 FROM base AS deps WORKDIR /app -RUN apk add build-base g++ cairo-dev pango-dev giflib-dev - -COPY package.json pnpm-lock.yaml* ./ -RUN corepack enable pnpm -RUN pnpm config set registry https://registry.npmmirror.com -RUN pnpm install --frozen-lockfile +COPY package.json bun.lock ./ +RUN bun config set registry https://registry.npmmirror.com +RUN bun install --frozen-lockfile # 构建阶段 FROM base AS builder WORKDIR /app COPY --from=deps /app/node_modules ./node_modules -COPY .. . +COPY . . ENV NEXT_TELEMETRY_DISABLED=1 -RUN corepack enable pnpm -RUN pnpm run build +RUN bun run build # 生产阶段 FROM base AS runner WORKDIR /app ENV NEXT_TELEMETRY_DISABLED=1 +ENV NODE_ENV=production RUN addgroup --system --gid 1001 nodejs RUN adduser --system --uid 1001 nextjs @@ -47,4 +40,4 @@ EXPOSE 3000 ENV PORT=3000 ENV HOSTNAME="0.0.0.0" -CMD ["node", "server.js"] +CMD ["bun", "server.js"]