chore: sync local changes to Gitea
Some checks failed
🚀 Deploy cloud-mail to Cloudflare Workers / 🏗️ Build and Deploy (push) Has been cancelled

This commit is contained in:
shumengya
2026-06-24 22:10:22 +08:00
parent 80a0cb65a5
commit 498ffe1b18
11 changed files with 14871 additions and 244 deletions

356
README.md
View File

@@ -3,156 +3,324 @@
<h1 align="center">Cloud Mail</h1>
<p align="center">基于 Cloudflare 的简约响应式邮箱服务,支持邮件发送、附件收发 🎉</p>
<p align="center">
简体中文 | <a href="/README-en.md" style="margin-left: 5px">English </a>
简体中文 | <a href="/README-en.md">English</a>
</p>
<p align="center">
<a href="https://github.com/maillab/cloud-mail/tree/main?tab=MIT-1-ov-file" target="_blank" >
<img src="https://img.shields.io/badge/license-MIT-green" />
<a href="https://github.com/maillab/cloud-mail/blob/main/LICENSE" target="_blank">
<img src="https://img.shields.io/badge/license-MIT-green" alt="license" />
</a>
<a href="https://github.com/maillab/cloud-mail/releases" target="_blank" >
<a href="https://github.com/maillab/cloud-mail/releases" target="_blank">
<img src="https://img.shields.io/github/v/release/maillab/cloud-mail" alt="releases" />
</a>
<a href="https://github.com/maillab/cloud-mail/issues" >
<a href="https://github.com/maillab/cloud-mail/issues" target="_blank">
<img src="https://img.shields.io/github/issues/maillab/cloud-mail" alt="issues" />
</a>
<a href="https://github.com/maillab/cloud-mail/stargazers" target="_blank">
<img src="https://img.shields.io/github/stars/maillab/cloud-mail" alt="stargazers" />
</a>
<a href="https://github.com/maillab/cloud-mail/forks" target="_blank" >
<a href="https://github.com/maillab/cloud-mail/network/members" target="_blank">
<img src="https://img.shields.io/github/forks/maillab/cloud-mail" alt="forks" />
</a>
</p>
<p align="center">
<a href="https://trendshift.io/repositories/20459" target="_blank" >
<img src="https://trendshift.io/api/badge/repositories/20459" alt="trendshift" >
<a href="https://trendshift.io/repositories/20459" target="_blank">
<img src="https://trendshift.io/api/badge/repositories/20459" alt="trendshift" />
</a>
</p>
</p>
---
## 项目简介
## 📖 项目简介
只需一个域名,就可以创建多个不同的邮箱,类似各大邮箱平台,本项目支持署到 Cloudflare Workers ,降低服务器成本,搭建自己的邮箱服务
Cloud Mail 是一个基于 Cloudflare 生态构建的轻量级邮箱服务。只需一个域名,即可创建多个邮箱账号,实现类似 Gmail、QQ 邮箱等主流平台的收发邮件功能。
## 项目展示
本项目采用前后端分离架构,后端部署在 Cloudflare Workers前端为 Vue3 单页应用,无需传统服务器,大幅降低运维成本。
- [在线演示](https://skymail.ink)<br>
- [部署文档](https://doc.skymail.ink)<br>
- 🌐 [在线演示](https://skymail.ink)
- 📚 [部署文档](https://doc.skymail.ink)
- 💬 [Telegram 交流群](https://t.me/cloud_mail_tg)
| ![](/doc/demo/demo1.png) | ![](/doc/demo/demo2.png) |
|-----------------------|-----------------------|
| ![](/doc/demo/demo3.png) | ![](/doc/demo/demo4.png) |
## 📸 项目展示
| ![首页](doc/demo/demo1.png) | ![收件箱](doc/demo/demo2.png) |
|:--:|:--:|
| ![写邮件](doc/demo/demo3.png) | ![管理后台](doc/demo/demo4.png) |
## ✨ 功能特性
- **💰 零成本部署** - 基于 Cloudflare 免费套餐,无需购买服务器
- **💻 响应式设计** - 完美适配 PC、平板和移动设备
- **📧 邮件收发** - 集成 Resend 实现邮件发送,支持群发、附件、内嵌图片
- **📦 附件管理** - 使用 Cloudflare R2 存储附件,支持大文件上传下载
- **🛡️ 权限管理** - RBAC 权限控制,支持用户分级和资源限制
- **🔔 消息推送** - 邮件到达后自动推送到 Telegram 机器人
- **📡 开放 API** - 提供 RESTful API支持批量操作用户和邮件
- **🔢 验证码识别** - 集成 Workers AI 自动识别邮件中的验证码
- **📊 数据可视化** - 使用 ECharts 展示系统数据和使用统计
- **🎨 个性化** - 支持自定义网站标题、登录页背景、透明度等
- **🤖 人机验证** - 集成 Cloudflare Turnstile 防止恶意注册
## 功能介绍
## 🚀 快速开始
- **💰 低成本使用** 可部署到 Cloudflare Workers 降低服务器成本
### 环境要求
- **💻 响应式设计**响应式布局自动适配PC和大部分手机端浏览器
- [Node.js](https://nodejs.org/) 18+
- [npm](https://www.npmjs.com/) 或 [pnpm](https://pnpm.io/)
- [Cloudflare 账号](https://dash.cloudflare.com/)
- [Resend 账号](https://resend.com/)(用于发送邮件)
- **📧 邮件发送**集成Resend发送邮件支持群发内嵌图片和附件发送发送状态查看
### 安装依赖
- **🛡️ 管理员功能**可以对用户邮件进行管理RABC权限控制对功能及使用资源限制
```bash
# 克隆项目
git clone https://github.com/maillab/cloud-mail.git
cd cloud-mail
- **📦 附件收发**支持收发附件使用R2对象存储保存和下载文件
# 安装后端依赖
cd mail-worker
npm install
- **🔔 邮件推送**接收邮件后可以转发到TG机器人或其他服务商邮箱
# 安装前端依赖
cd ../mail-vue
npm install
```
- **📡 开放API**支持使用API批量生成用户多条件查询邮件
### 本地开发
- **🔢 验证码识别**使用Workers AI自动识别邮件验证码
**1. 配置后端**
- **📈 数据可视化**使用ECharts对系统数据详情用户邮件增长可视化显示
```bash
cd mail-worker
- **🎨 个性化设置**:可以自定义网站标题,登录背景,透明度
# 创建开发环境配置
cp wrangler.toml.example wrangler-dev.toml
- **🤖 人机验证**集成Turnstile人机验证防止人机批量注册
# 编辑配置(填入你的 Cloudflare 账号信息)
# 参见下方「配置说明」章节
```
- **📜 更多功能**:正在开发中...
**2. 启动后端开发服务器**
```bash
npm run dev
# 或使用 wrangler 命令
wrangler dev --config wrangler-dev.toml
```
**3. 启动前端开发服务器**
## 技术栈
```bash
cd mail-vue
npm run dev
```
- **平台**[Cloudflare Workers](https://developers.cloudflare.com/workers/)
前端默认运行在 `http://localhost:5173`,后端在 `http://localhost:8787`
- **Web框架**[Hono](https://hono.dev/)
## 🛠️ 技术栈
- **ORM**[Drizzle](https://orm.drizzle.team/)
| 层级 | 技术 | 说明 |
|:---|:---|:---|
| **运行平台** | [Cloudflare Workers](https://workers.cloudflare.com/) | 边缘计算平台 |
| **Web 框架** | [Hono](https://hono.dev/) | 轻量级 Web 框架 |
| **ORM** | [Drizzle ORM](https://orm.drizzle.team/) | 类型安全的 ORM |
| **数据库** | [Cloudflare D1](https://developers.cloudflare.com/d1/) | SQLite 边缘数据库 |
| **缓存** | [Cloudflare KV](https://developers.cloudflare.com/kv/) | 键值存储 |
| **文件存储** | [Cloudflare R2](https://developers.cloudflare.com/r2/) | 对象存储 |
| **前端框架** | [Vue 3](https://vuejs.org/) | 渐进式 JS 框架 |
| **UI 组件** | [Element Plus](https://element-plus.org/) | Vue 3 组件库 |
| **状态管理** | [Pinia](https://pinia.vuejs.org/) | Vue 官方状态管理 |
| **图表** | [ECharts](https://echarts.apache.org/) | 数据可视化 |
| **邮件服务** | [Resend](https://resend.com/) | 现代化邮件 API |
- **前端框架**[Vue3](https://vuejs.org/)
- **UI框架**[Element Plus](https://element-plus.org/)
- **邮件推送:** [Resend](https://resend.com/)
- **缓存**[Cloudflare KV](https://developers.cloudflare.com/kv/)
- **数据库**[Cloudflare D1](https://developers.cloudflare.com/d1/)
- **文件存储**[Cloudflare R2](https://developers.cloudflare.com/r2/)
## 目录结构
## 📁 项目结构
```
cloud-mail
├── mail-worker # worker后端项目
│ ├── src
│ │ ├── api # api接口层
│ │ ├── const # 项目常量
│ │ ├── dao # 数据访问层
│ │ ├── email # 邮件处理接收
│ │ ├── entity # 数据库实体
│ │ ├── error # 自定义异常
│ │ ├── hono # web框架配置、拦截器、全局异常等
│ │ ├── i18n # 语言国际化
│ │ ├── init # 数据库缓存初始化
│ │ ├── model # 响应体数据封装
│ │ ├── security # 身份权限认证
│ │ ├── service # 业务服务
│ │ ├── template # 消息模板
│ │ ├── utils # 工具
│ │ └── index.js # 入口文件
│ ├── pageckge.json # 项目依赖
│ └── wrangler.toml # 项目配置
cloud-mail/
├── mail-worker/ # 后端 Worker 项目
│ ├── src/
│ │ ├── api/ # API 接口层
│ │ ├── const/ # 常量定义
│ │ ├── dao/ # 数据访问层
│ │ ├── email/ # 邮件收发处理
│ │ ├── entity/ # 数据库实体
│ │ ├── error/ # 异常定义
│ │ ├── hono/ # Web 框架配置
│ │ ├── i18n/ # 国际化
│ │ ├── init/ # 初始化逻辑
│ │ ├── model/ # 数据模型
│ │ ├── security/ # 权限认证
│ │ ├── service/ # 业务逻辑
│ │ ├── template/ # 邮件模板
│ │ ├── utils/ # 工具函数
│ │ └── index.js # 入口文件
│ ├── package.json
│ └── wrangler.toml # 部署配置
├── mail-vue # vue前端项目
│ ├── src
│ │ ├── axios # axios配置
│ │ ├── components # 自定义组件
│ │ ├── echarts # echarts组件导入
│ │ ├── i18n # 语言国际化
│ │ ├── init # 入站初始化
│ │ ├── layout # 主体布局组件
│ │ ├── perm # 权限认证
│ │ ├── request # api接口
│ │ ├── router # 路由配置
│ │ ├── store # 全局状态管理
│ │ ├── utils # 工具
│ │ ├── views # 页面组件
│ │ ├── app.vue # 入口组件
│ │ ├── main.js # 入口js
│ │ └── style.css # 全局css
│ ├── package.json # 项目依赖
└── └── env.release # 项目配置
├── mail-vue/ # 前端 Vue 项目
│ ├── src/
│ │ ├── axios/ # Axios 配置
│ │ ├── components/ # 公共组件
│ │ ├── echarts/ # 图表组件
│ │ ├── i18n/ # 国际化
│ │ ├── init/ # 初始化
│ │ ├── layout/ # 布局组件
│ │ ├── perm/ # 权限管理
│ │ ├── request/ # API 请求封装
│ │ ├── router/ # 路由配置
│ │ ├── store/ # 状态管理
│ │ ├── utils/ # 工具函数
│ │ ├── views/ # 页面视图
│ │ ├── app.vue # 组件
│ │ ├── main.js # 入口文件
│ │ └── style.css # 全局样式
│ ├── package.json
└── vite.config.js # Vite 配置
├── doc/ # 文档和演示图片
├── LICENSE # MIT 许可证
└── README.md # 本文件
```
## 赞助
## ⚙️ 配置说明
<a href="https://doc.skymail.ink/support.html" >
<img width="170px" src="./doc/images/support.png" alt="">
### 后端配置 (mail-worker/wrangler.toml)
```toml
name = "cloud-mail"
main = "src/index.js"
compatibility_date = "2024-01-01"
# D1 数据库绑定
[[d1_databases]]
binding = "DB"
database_name = "cloud-mail-db"
database_id = "your-database-id"
# KV 缓存绑定
[[kv_namespaces]]
binding = "CACHE"
id = "your-kv-id"
# R2 存储绑定
[[r2_buckets]]
binding = "STORAGE"
bucket_name = "cloud-mail-storage"
# 环境变量
[vars]
RESEND_API_KEY = "your-resend-api-key"
JWT_SECRET = "your-jwt-secret"
ADMIN_EMAIL = "admin@yourdomain.com"
```
### 前端配置 (mail-vue/.env)
```env
# 开发环境
VITE_API_BASE_URL=http://localhost:8787
# 生产环境
VITE_API_BASE_URL=https://your-worker.your-subdomain.workers.dev
```
## 🚢 部署指南
### 部署后端
```bash
cd mail-worker
# 测试环境部署
npm run test
# 生产环境部署
npm run deploy
```
### 部署前端
前端需要构建后部署到任意静态托管服务(如 Cloudflare Pages、Vercel、Netlify 等):
```bash
cd mail-vue
# 构建生产版本
npm run build
# 构建结果在 dist/ 目录,可直接部署
```
### 推荐使用 Cloudflare Pages 部署前端
1. 在 Cloudflare Dashboard 创建 Pages 项目
2. 连接 GitHub 仓库
3. 构建设置:
- 构建命令:`cd mail-vue && npm run build`
- 构建输出目录:`mail-vue/dist`
4. 添加环境变量(参考上方配置说明)
## 📝 开发脚本
### 后端 (mail-worker)
| 命令 | 说明 |
|:---|:---|
| `npm run dev` | 本地开发模式 |
| `npm run start` | 启动开发服务器(同 dev |
| `npm run test` | 部署到测试环境 |
| `npm run deploy` | 部署到生产环境 |
### 前端 (mail-vue)
| 命令 | 说明 |
|:---|:---|
| `npm run dev` | 本地开发模式 |
| `npm run remote` | 使用远程 API 开发 |
| `npm run build` | 构建生产版本 |
| `npm run eo` | 构建 EO 环境 |
| `npm run preview` | 预览构建结果 |
## 🤝 贡献指南
欢迎提交 Issue 和 Pull Request
1. Fork 本仓库
2. 创建特性分支:`git checkout -b feature/amazing-feature`
3. 提交更改:`git commit -m 'Add amazing feature'`
4. 推送分支:`git push origin feature/amazing-feature`
5. 创建 Pull Request
## ❓ 常见问题
**Q: 项目完全免费吗?**
A: 基于 Cloudflare 免费套餐可以运行基本功能,但如果邮件量大或附件多,可能需要升级到付费套餐。
**Q: 支持自定义域名吗?**
A: 支持,可以在 Cloudflare 中为 Workers 和 Pages 绑定自定义域名。
**Q: 如何接收邮件?**
A: 需要在域名 DNS 中添加 MX 记录指向 Cloudflare Email Routing具体参见部署文档。
## 💖 赞助支持
如果本项目对你有帮助,欢迎赞助支持开发者:
<a href="https://doc.skymail.ink/support.html">
<img width="170px" src="./doc/images/support.png" alt="赞助" />
</a>
## 许可证
## 📄 许可证
本项目采用 [MIT](LICENSE) 许可证
本项目基于 [MIT](LICENSE) 许可证开源。
## 💬 社区交流
## 交流
[Telegram](https://t.me/cloud_mail_tg)
- [Telegram 群组](https://t.me/cloud_mail_tg)
- [GitHub Issues](https://github.com/maillab/cloud-mail/issues)
---
<p align="center">
Made with ❤️ by Cloud Mail Team
</p>

View File

@@ -6,7 +6,7 @@
<meta name="theme-color" content="#F1F1F1" id="theme-color-meta">
<meta name="description" content="Cloud Mail 是一个 Serverless 响应式邮箱服务,支持邮件发送,可部署到 Cloudflare 平台降低服务器成本。Cloud Mail is a serverless responsive email service that supports email sending and can be deployed on Cloudflare to reduce server costs.">
<title>Cloud Mail</title>
<link rel="icon" href="/public/mail.png" type="image/png">
<link rel="icon" href="/favicon.ico" type="image/x-icon">
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<script>
@@ -129,7 +129,7 @@
<body>
<div id="loading-first" >
<div class="loading-icon">
<img class="loading-image" src="/mail-pwa.png" alt="Cloud Mail">
<img class="loading-image" src="/logo.png" alt="Cloud Mail">
<div class="loading-progress" aria-hidden="true"></div>
</div>
</div>

8095
mail-vue/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

BIN
mail-vue/public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

BIN
mail-vue/public/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

View File

@@ -2,7 +2,7 @@
<el-scrollbar class="scroll">
<div>
<div class="title" >
<Icon icon="mdi:email-outline" width="24" height="24" />
<img class="logo" src="/logo.png" alt="" width="24" height="24" />
<div>{{settingStore.settings.title}}</div>
</div>
<el-menu :collapse="false" text-color="#fff" active-text-color="#fff" style="margin-top: 10px">
@@ -105,6 +105,11 @@ const route = useRoute();
max-width: calc(240px - 20px - 30px);
}
.logo {
flex-shrink: 0;
object-fit: contain;
}
:deep(.el-icon) {
flex-shrink: 0;
font-size: 20px;

View File

@@ -25,7 +25,7 @@ export default defineConfig(({mode}) => {
theme_color: '#FFFFFF',
icons: [
{
src: 'mail-pwa.png',
src: 'logo.png',
sizes: '192x192',
type: 'image/png',
}

6501
mail-worker/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,53 +0,0 @@
name = "${NAME}"
main = "src/index.js"
compatibility_date = "2025-06-04"
[observability]
enabled = true
[[routes]]
pattern = "${CUSTOM_DOMAIN}"
custom_domain = true
[[d1_databases]]
binding = "db"
database_name = "cloud-mail"
database_id = "${D1_DATABASE_ID}"
[[kv_namespaces]]
binding = "kv"
id = "${KV_NAMESPACE_ID}"
[[r2_buckets]]
binding = "r2"
bucket_name = "${R2_BUCKET_NAME}"
[ai]
binding = "ai"
[assets]
binding = "assets"
directory = "./dist"
not_found_handling = "single-page-application"
run_worker_first = true
[triggers]
crons = ["*/30 * * * *", "0 16 * * *"]
[vars]
ai_model = "${AI_MODEL}"
analysis_cache = "${ANALYSIS_CACHE}"
#orm_log = false
domain = "${DOMAIN}"
admin = "${ADMIN}"
jwt_secret = "${JWT_SECRET}"
project_link = "${PROJECT_LINK}"
linuxdo_client_id = "${LINUXDO_CLIENT_ID}"
linuxdo_client_secret = "${LINUXDO_CLIENT_SECRET}"
linuxdo_callback_url = "${LINUXDO_CALLBACK_URL}"
linuxdo_switch = "${LINUXDO_SWITCH}"
[build]
command = "pnpm --prefix ../mail-vue install && pnpm --prefix ../mail-vue run build"

View File

@@ -1,44 +0,0 @@
name = "cloud-mail-dev"
main = "src/index.js"
compatibility_date = "2025-06-04"
keep_vars = true
[observability]
enabled = true
[dev]
ip = "0.0.0.0"
[[d1_databases]]
binding = "db"
database_name = "email"
database_id = "a4c1a63a-6ef5-4e6d-8e8c-b6d9e8feb810"
[[kv_namespaces]]
binding = "kv"
id = "2io01d4b299e481b9de060ece9e7785c"
#[[r2_buckets]]
#binding = "r2"
#bucket_name = "email"
#[ai]
#binding = "ai"
[assets]
binding = "assets"
directory = "./dist"
not_found_handling = "single-page-application"
run_worker_first = true
#[[send_email]]
#name = "email"
[vars]
ai_model = ""
analysis_cache = false
orm_log = false
domain = ["example.com", "example2.com", "example3.com", "example4.com"]
admin = "admin@example.com"
jwt_secret = "b7f29a1d-18e2-4d3b-941f-f6b2c97c02fd"

View File

@@ -1,45 +0,0 @@
name = "test-mail"
main = "src/index.js"
compatibility_date = "2025-06-04"
keep_vars = true
[observability]
enabled = true
[[d1_databases]]
binding = "db" #d1数据库绑定名默认不可修改
database_name = "test-email" #d1数据库名字
database_id = "e65f099d-796d-4eaa-8dff-529b368b20db" #d1数据库id
[[kv_namespaces]]
binding = "kv" #kv绑定名默认不可修改
id = "9be10cd058e04c55b526f8c0c116f50c" #kv数据库id
#(可选)
#[[r2_buckets]]
#binding = "r2" #r2对象存储绑定名默认不可修改
#bucket_name = "test-email" #r2对象存储桶的名字
[ai]
binding = "ai"
[assets]
binding = "assets" #静态资源绑定名默认不可修改
directory = "./dist" #前端vue项目打包的静态资源存放位置,默认dist
not_found_handling = "single-page-application"
run_worker_first = true
[triggers]
crons = ["*/30 * * * *", "0 16 * * *"] #每30分钟刷新分析缓存每天晚上12点执行每日任务
[vars]
ai_model = "" #ai模型,不填默认使用@cf/meta/llama-3.1-8b-instruct
analysis_cache = false #是否开启分析数据缓存
orm_log = false #是否sql日志
domain = ["example.com"] #邮件域名可可配置多个 示例: ["example1.com","example2.com"]
admin = "admin@example.com" #管理员的邮箱 示例: admin@example.com
jwt_secret = "b7f29a1d-18e2-4d3b-941f-f6b2c97c02fd" #jwt令牌的密钥,随便填一串字符串
[build]
command = "pnpm --prefix ../mail-vue install && pnpm --prefix ../mail-vue run build"