Files
edgeKey/README.md
2026-04-29 18:32:10 +08:00

345 lines
15 KiB
Markdown
Raw Permalink 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.
[![English](https://img.shields.io/badge/English-Click-yellow)](README-en.md)
[![中文文档](https://img.shields.io/badge/中文文档-点击查看-orange)](README.md)
# EdgeKey
EdgeKey 是一套有vike框架开发可直接部署到 Cloudflare 的一体化全栈卡密商城系统同一套代码同时包含前端页面、SSR 渲染、后端 API / 数据变更入口,并由 Cloudflare Workers 运行。
## 功能特性
- 🚀 **真正的零成本** — 不用购买服务器和域名,基于 Cloudflare 全球边缘网络运行。一键部署,即刻上线。把钱花在刀刃上,把时间还给自己。
- 🌍 **零成本运维** — 基于 Workers + D1免费额度足够满足日常运营无需担心额外的账单扣费。
- 🛍️ **商品管理** — 支持分类、商品上下架、库存模式(有限/无限)、最小/最大购买数量。
- 🔑 **卡密管理** — 批量导入卡密,支付后自动发货,支持库存实时预警。
- 📦 **订单管理** — 包含订单列表、手动补发、自动关闭过期订单及详细的支付日志。
- 💳 **多支付网关** — 内置 BEpusdt (USDT)、Epay (聚合支付),支持插件式扩展更多接口。
- 📧 **邮件通知** — 支持 SMTP / API / Cloudflare Email 三种通道,内置详细的邮件发送日志。
- ⚙️ **站点设置** — 灵活配置站点名称、Logo、公告及客服联系方式。
- 🔐 **管理后台** — 安全可靠的管理员账号体系。
> [!TIP]
> **关于 0 成本运行:** 在配合支付渠道usdt、自建等、个人邮箱 SMTP 以及免费图床的理想状态下,本项目可实现 **100% 零成本** 运营。
## 项目截图
![1](https://img.91starry.com/uploads/20260427/6286ff36cc987c47a1a27516db0d94c8.jpg)
![2](https://img.91starry.com/uploads/20260427/6072aac36a1d1db8b79cdb535d45138f.jpg)
![3](https://img.91starry.com/uploads/20260427/95dedb45c5d16d8cf69ffa058539b19d.jpg)
## 快速开始
本项目支持三种部署方式,按推荐程度排序:
| 方式 | 适合场景 | 便捷程度 |
|---|---|---|
| **一键部署**(推荐) | 首次部署,无需本地环境 | ⭐⭐⭐ 最简单,点击按钮全自动完成 |
| **Git 自动部署** | 持续迭代,代码推送自动更新 | ⭐⭐ 配置一次后全自动 |
| **手动部署** | 二开需求,细节掌控 | ⭐ 需要本地环境和命令行操作 |
详细步骤见下方各章节说明。
### 一键部署到 Cloudflare Workers
[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/34892002/edgeKey)
> **点击按钮后,会打开 Cloudflare Workers 部署向导,操作提示:**
> 1. 登录并授权 Git 账户(github、gitlab)它会自动在你的git账号创建一个新仓库。
> 2. 为了增强安全性,请在向导中修改默认的密钥( `AUTH_SECRET`)。
> 3. 如果你不绑定已有的D1数据库它会自动完成新建数据库并初始化数据管理员账号等的操作无需手动干预。
> 4. 部署成功之后在页面的日志里面可以找到 "Deployed edgekey triggers (0.38 sec) https://edgekey.你的账号.workers.dev" 这样的日志,其中 "https://edgekey.你的账号.workers.dev" 就是你的项目网址。
> 5. https://edgekey.你的账号.workers.dev/admin 为管理后台登陆地址,默认管理员账号:admin密码:admin123456切记登陆后立即修改密码
### 通过 Git 连接 Cloudflare 自动部署
如果你使用 Cloudflare Workers 的 Git 集成(连接 GitHub/GitLab 仓库自动部署),需要先完成以下前置步骤:
**0. 前置:在 Cloudflare Dashboard 创建 D1 数据库**
1. 进入 [dash.cloudflare.com](https://dash.cloudflare.com) → **Storage & Databases****D1**
2. 点击 **Create** 创建数据库,名称填 `edgekey-db`
3. 记录数据库详情页中的 `database_id`,后续部署命令中需要用到
数据库表结构和种子数据会在首次部署时由 `deploy` 脚本自动完成初始化,无需手动操作。
**1. 部署命令**
由于 `wrangler.jsonc` 中的 `database_id` 需要与你的实际 D1 数据库绑定Git 自动部署时请在 Cloudflare 的"构建配置"中将部署命令设置为:
```bash
sed -i 's/"database_name": "edgekey-db"/"database_name": "edgekey-db", "database_id": "你的database_id"/' wrangler.jsonc && bun run deploy
```
`你的database_id` 替换为你的实际 D1 数据库 ID可在 Cloudflare Dashboard → D1 → 数据库详情页找到)。
**2. 配置 AUTH_SECRET 环境变量**
在 Cloudflare Workers Git 集成的"高级设置"中:
1. 添加变量名 `AUTH_SECRET`
2. 输入你的密钥字符串作为变量值
3. 勾选"加密"选项
### 构建与部署(手动)
首次部署到 Cloudflare 前,需要先在云端创建并初始化 D1 数据库:
1. **登录并创建数据库**
```bash
bunx wrangler login
bunx wrangler d1 create edgekey-db
```
2. **绑定 Database ID**
将上一步终端输出的 `database_id` 填入 `wrangler.jsonc`。
```jsonc
"d1_databases": [
{
"binding": "DB",
"database_name": "edgekey-db",
"database_id": "这里填入你刚创建数据库的UUID", // <-- 必须添加这一行
"migrations_dir": "prisma/migrations"
}
]
```
3. **按顺序初始化云端表结构**
```bash
bun run db:migrations:remote
```
4. **初始化管理员账号与初始化种子数据**
```bash
bun run db:seed:remote
```
5. **配置 AUTH_SECRET**
输入命令执行,根据命令行提示输入你要使用的密钥字符串。```bash
bunx wrangler secret put AUTH_SECRET
```
6. **生成 Prisma Client 并一键部署**
```bash
bun run db:generate
bun run up
```
`bun run up` 等价于先构建再发布:
- `vike build`
- `wrangler deploy`
部署配置见 `wrangler.jsonc`(其中 `main` 指向 Photon 的 Cloudflare server-entry 虚拟入口)。
## 安全性说明(重要)
当前项目使用管理员账号密码登录。用于生产环境前请务必:
- Cloudflare 生产环境必须配置 `AUTH_SECRET`,未配置会抛出异常并禁止管理员登录
- 配置方式详见上方"一键部署"、"通过 Git 连接 Cloudflare 自动部署"、"构建与部署(手动)"各章节说明
- 生产环境配置AUTH_SECRET命令 `wrangler secret put AUTH_SECRET`
- 默认管理员账号为 `admin / admin123456`,首次登录后请立即修改密码
### 忘记密码?
在 Cloudflare Dashboard 中通过 D1 Console 将密码重置为 `admin123456`
1. 进入 [dash.cloudflare.com](https://dash.cloudflare.com) → **Storage & Databases** → **D1** → 点击 `edgekey-db`
2. 顶部 tab → **Console**
3. 执行以下 SQL
```sql
UPDATE Admin SET passwordHash = '$2b$10$viMe8RgcpM30gmmF9OpOcuA/QgleSIUk5VRtqjOulfSIbgK5jQCI6' WHERE username = 'admin';
```
4. 登录后台后立即修改密码
## 本地开发
推荐使用 Bun也可替换为 npm/pnpm/yarn
```bash
bun install
```
由于本项目使用了 Cloudflare D1 数据库,在首次启动本地开发服务器前,必须先初始化本地的 D1 模拟器表结构:
```bash
# 1. 生成 Prisma Client首次安装依赖后必须执行
bun run db:generate
# 2. 按顺序将所有迁移脚本应用到本地 Wrangler 模拟器
bun run db:migrations:local
# 3. 初始化管理员账号与初始化种子数据
bun run db:seed
# 4. 准备.env 文件
# 请在 `env.example` 中填写必要的环境变量,例如 `AUTH_SECRET`。
# 然后复制 `env.example` 到 `env` 文件。
# 5. 启动开发服务器
bun run dev
```
### Cloudflare D1 + Prisma 本地开发工作流
本项目使用了 Prisma ORM 与 Cloudflare D1 数据库,完全遵循 [官方 Prisma + Cloudflare D1 指南](https://www.prisma.io/docs/guides/deployment/cloudflare-d1) 的最佳实践。
### 当前运行方式
- `bun dev` 运行在 Cloudflare 风格的本地开发环境中Prisma 会通过 `env.DB` 连接到**本地 D1 模拟器**。
- `bun run up` 部署后Prisma 会通过同一个 `env.DB` 绑定连接到**远程 D1**。
- `.env` 中的 `DATABASE_URL` 仅用于 Prisma CLI / 配置层,不参与当前应用运行时的数据库连接。
- 当前 `prisma/schema.prisma` 仅保留 Cloudflare client generator运行时统一使用 `generated/prisma/client`。
- 因此,本项目当前的数据库运行模式是:**开发环境用本地 D1生产环境用远程 D1**。
### 正确的数据库开发工作流
当你需要修改数据库表结构时,请**严格按照以下流程执行**
**第一步:修改 Schema 并生成 SQL 迁移脚本**
修改 `prisma/schema.prisma` 后,不要使用常规的 `migrate dev`,而是使用 `migrate diff` 生成 SQL 脚本:
```bash
# 由于 Cloudflare D1 和普通的 MySQL 完全不同。普通的 Prisma migrate dev 依赖于一个长期运行的数据库连接来比对状态、创建 shadow database 等等,而 D1 不支持这些操作。
# 后续增量迁移(修改现有表结构时)
# 新版 Prisma 已经废弃了 --from-local-d1推荐使用 --from-migrations
bunx prisma migrate diff \
--from-migrations prisma/migrations \
--to-schema prisma/schema.prisma \
--script > prisma/migrations/0002_xxx.sql
```
说明:
- `0001_init.sql` 只用于第一次初始化,不应在后续迁移中反复覆盖。
- 后续迁移请按顺序新增文件,例如 `0002_add_foo.sql`、`0003_add_bar.sql`。
**第二步:将迁移同步到本地 D1 模拟器(用于本地开发/测试)**
```bash
bun run db:migrations:local
```
如果不执行这一步,运行 `bun dev` 访问页面时会报错 `no such table`。
**第三步:将迁移同步到 Cloudflare 线上(发布前)**
```bash
bun run db:migrations:remote
```
本地和线上需要分别执行一次。
### 日常开发命令
```bash
bun dev
```
上面的命令会启动本地开发服务器,并使用 `wrangler.jsonc` 中定义的 D1 绑定连接到**本地 D1 模拟器**。
### Telefunc 说明
- Telefunc 函数按约定放在对应页面目录下,以 `.telefunc.ts` 结尾。
- 当前 Windows + `bun dev` + `workerd` 组合下Telefunc 的开发态命名/同目录检查会触发路径兼容问题,因此在 `server/telefunc-handler.ts` 中关闭了该检查。
- 这不会影响 Telefunc 的实际加载和调用,只是跳过开发态的命名约定校验。
**⚠️ 绝对不要做的操作:**
1. **不要**假设 `bun dev` 使用的是 `prisma/db.sqlite`;当前它实际使用的是本地 D1 模拟器。
2. **不要**使用 `prisma migrate dev`,这会偏离当前 D1 迁移工作流。
3. **不要**反复覆盖 `prisma/migrations/0001_init.sql`;初始化迁移和后续增量迁移应分开维护。
## 技术栈
- 框架与渲染
- Vike文件路由 + SSR
- Vue 3前端组件
- Server / 运行时
- Hono服务端路由与中间件
- Photon将服务端入口适配到 Cloudflare
- WranglerCloudflare 部署与本地开发工具)
- 数据与变更
- Telefunc前后端同构的数据变更 RPC
- PrismaORM
- D1Cloudflare 原生 SQLite 数据库,本项目开发与部署统一使用)
- UI
- Tailwind CSS
- daisyUITailwind 组件与主题)
- 认证
- Auth.js管理员账号密码登录
## 项目结构
```
.
├─ assets/ # 静态资源
├─ components/ # 复用组件(非路由页面)
├─ pages/ # Vike 文件路由目录(页面就近放置组件/样式/类型)
│ ├─ +config.ts # 全局配置(例如 title、SSR 等)
│ ├─ +Layout.vue # 全局布局
│ ├─ +Head.vue # 全局 head 标签
│ ├─ tailwind.css # Tailwind + daisyUI 入口
│ ├─ index/+Page.vue # 前台首页(/
│ ├─ product/+Page.vue # 商品详情页(/product/:slug
│ ├─ query/+Page.vue # 订单查询页(/query
│ ├─ order/+Page.vue # 订单详情页(/order/:orderNo
│ ├─ admin/ # 管理后台(/admin
│ └─ _error/+Page.vue # 错误页
├─ server/ # 服务端入口Hono与中间件
│ ├─ entry.ts # 服务端主入口
│ ├─ authjs-handler.ts # Auth.js handler + session middleware
│ ├─ prisma-middleware.ts # Prisma D1 注入中间件
│ └─ telefunc-handler.ts # Telefunc handler
├─ lib/ # 业务逻辑库(支付适配器、发货逻辑等)
├─ modules/ # 功能模块(支付通知、订单等)
├─ scripts/ # 辅助脚本(种子数据、验证脚本)
├─ prisma/ # Prisma Schema 与迁移 SQL
│ ├─ schema.prisma
│ └─ migrations/
│ ├─ 0001_init.sql
│ └─ 0002_xxx.sql
├─ vite.config.ts # Vite 插件配置vike + vue + tailwind + telefunc
├─ wrangler.jsonc # Cloudflare Workers 配置(入口为 Photon 虚拟模块)
└─ package.json # 脚本与依赖
```
### 关于 `+` 文件Vike 约定)
`pages/` 目录下以 `+` 开头的文件是 Vike 的"约定接口文件",用于声明页面、配置与数据加载等;不带 `+` 的文件会被当作普通模块(组件、样式、类型)处理,便于页面就近组织代码。
常见 `+` 文件:
- `+Page.vue`:页面组件
- `+data.ts`页面数据获取SSR/CSR 共享)
- `+Layout.vue`:布局(包裹页面)
- `+Head.vue`head 标签
- `+config.ts`:页面/全局配置
## 日志排查
当邮件发送异常或支付回调出现问题时,可在 Cloudflare Dashboard 查看 Workers 运行日志:
1. 进入 [dash.cloudflare.com](https://dash.cloudflare.com)
2. 左侧菜单 → **Workers & Pages** → 点击 **edgekey**
3. 顶部 tab → **Observability**
4. 在搜索框输入关键词过滤日志,例如:
- `email.notify_order_paid.config_failed` — 支付后邮件配置获取失败
- `email.send.failed` — 邮件发送失败
- `email.order_paid.failed` — 支付成功后发送邮件通知失败
- `payment.notify.route_exception` — 支付回调路由异常
- `payment.notify.context_missing` — 支付回调缺少数据库上下文
- `payment.notify.diagnostic` — 支付回调校验异常诊断(签名错误、金额不匹配等)
- `bepusdt.verify_notify` — BEpusdt 回调原始 payloadinfo 级别)
## 鸣谢
感谢 [Linux.do](https://linux.do/) 、[NodeSeek](https://www.nodeseek.com/) 社区支持。
感谢下列开源项目
- [Ebpusdt](https://github.com/v03413/BEpusdt) — 加密货币交易支持
- [worker-mailer](https://github.com/zou-yu/worker-mailer) — Workers环境SMTP邮件支持
## 🏝️ 社区交流
- Telegram 群组https://t.me/edgeKeyChannel
- Telegram 频道https://t.me/edgeKeyGroup