角色与目标
你是一位专业的全栈Web开发工程师。你的任务是使用现代技术栈(Node.js/Express + React)创建一个完整的前后端分离项目。这个项目是一个 Cloudflare DNS 解析记录管理面板,它允许用户通过一个简洁的网页界面来查看和管理他们账户下的域名解析记录。
核心需求与工作流程
安全认证:Cloudflare API Token 必须作为环境变量存储在后端服务器,绝不能暴露给前端。后端服务器作为代理,负责接收前端请求,附加认证信息后,再转发给 Cloudflare API。
后端代理:创建一个 Express 后端,它将封装所有对 Cloudflare API 的调用。
前端界面:创建一个基于 React 的单页面应用(SPA)。
工作流程:
页面加载时,前端自动向后端请求域名列表。
后端调用 Cloudflare API 获取所有域名,并返回给前端。
前端将域名列表渲染在一个下拉选择框中。
当用户从下拉框中选择一个域名时,前端向后端请求该域名的所有 DNS 解析记录。
后端根据前端传来的 Zone ID,调用 Cloudflare API 获取解析记录,并返回给前端。
前端将解析记录以表格形式展示出来。
用户可以通过界面上的按钮对解析记录进行添加(Create)、修改(Update)和删除(Delete)操作。所有操作都通过调用后端代理 API 完成。
技术栈建议
后端: Node.js + Express.js
前端: React (使用 Vite 初始化) + Tailwind CSS (用于快速构建美观的界面)
环境变量管理: dotenv 库
项目结构建议
/cloudflare-dns-manager
├── /server // 后端 Express 应用
│ ├── node_modules/
│ ├── package.json
│ └── server.js // Express 服务器逻辑
├── /client // 前端 React 应用
│ ├── node_modules/
│ ├── public/
│ ├── src/
│ ├── package.json
│ └── ...
├── .env // 根目录下的环境变量文件
└── .gitignore
分步执行计划 (请严格按照此顺序生成代码)
第1步:创建后端 Express 服务器 (位于 server/server.js)
初始化 Express 应用,并启用 CORS,允许前端(http://localhost:5173 或其他 Vite 默认端口)访问。
使用 dotenv 库加载根目录 .env 文件中的环境变量 CLOUDFLARE_API_TOKEN。
创建一个 axios 实例,预设 Cloudflare API 的 baseURL (https://api.cloudflare.com/client/v4) 和 Authorization 请求头(值为 Bearer ${process.env.CLOUDFLARE_API_TOKEN})。
创建以下 API 代理端点:
-
GET /api/zones:调用 Cloudflare 的 GET /zones,获取所有域名列表。
-
GET /api/zones/:zoneId/dns_records:调用 Cloudflare 的 GET /zones/{zoneId}/dns_records,获取指定域名的解析记录。
-
POST /api/zones/:zoneId/dns_records:调用 Cloudflare 的 POST /zones/{zoneId}/dns_records,添加新的解析记录。
-
PUT /api/zones/:zoneId/dns_records/:recordId:调用 Cloudflare 的 PUT /zones/{zoneId}/dns_records/{recordId},修改解析记录。
-
DELETE /api/zones/:zoneId/dns_records/:recordId:调用 Cloudflare 的 DELETE /zones/{zoneId}/dns_records/{recordId},删除解析记录。
添加全局错误处理中间件,确保将来自 Cloudflare API 的错误清晰地返回给前端。
第2步:创建前端 React 应用 (位于 client/ 目录)
使用 Vite 初始化一个 React 项目。
安装并配置 Tailwind CSS。
安装 axios 用于 API 请求。
第3步:构建前端核心 UI 组件 (client/src/App.jsx)
状态管理:使用 useState 管理以下状态:
zones (域名列表)
selectedZone (当前选中的域名对象)
dnsRecords (当前域名的解析记录列表)
isLoading (加载状态)
error (错误信息)
域名选择器:
使用 useEffect 在组件首次加载时,调用后端 GET /api/zones 获取域名列表,并更新 zones 状态。
渲染一个 <select>
下拉菜单,选项为 zones 列表中的域名。
当用户选择一个新域名时,更新 selectedZone 状态。
DNS 解析记录表格:
使用另一个 useEffect,当 selectedZone 发生变化时,调用后端 GET /api/zones/${selectedZone.id}/dns_records 获取解析记录,并更新 dnsRecords 状态。
将 dnsRecords 渲染成一个表格,至少包含 Type, Name, Content, Proxied, Actions (操作按钮) 这几列。
在表格的每一行末尾,添加“修改”和“删除”按钮。
第4步:实现添加、修改、删除功能
删除功能:
为“删除”按钮绑定点击事件。
点击时,弹出一个确认框 (window.confirm)。
用户确认后,调用后端的 DELETE /api/zones/:zoneId/dns_records/:recordId接口。
成功删除后,重新获取当前域名的解析记录列表以刷新UI。
添加/修改功能 (建议使用一个模态框 Modal):
创建一个可复用的表单组件 (RecordForm),包含 Type, Name, Content, TTL, Proxied (开关) 的输入字段。
在主界面添加一个“添加新记录”的按钮,点击后打开一个空的表单模态框。
点击表格行中的“修改”按钮,打开同一个表单模态框,但表单内预先填充该行记录的数据。
表单提交时,根据是添加还是修改,调用后端的 POST 或 PUT 接口。
操作成功后,关闭模态框并重新获取解析记录列表以刷新UI。
最终输出要求
请为上述所有文件(server/server.js, client/src/App.jsx 等)提供完整、可直接运行的代码。
在代码中加入必要的注释,解释关键部分的逻辑。
提供一个 .env.example 文件示例,告知用户如何配置环境变量。
提供清晰的指令,告诉用户如何分别在 server 和 client 目录下安装依赖并启动应用。