diff --git a/README-en.md b/README-en.md index 19ed1c4..7d12c1b 100644 --- a/README-en.md +++ b/README-en.md @@ -7,7 +7,7 @@

Cloud Mail

-

A responsive email service built with Vue 3 that supports email sending and can be deployed on Cloudflare. 🎉

+

Serverless responsive email service with sending capabilities, deployable on the Cloudflare platform 🎉

@@ -15,14 +15,12 @@ - [Online Demo](https://skymail.ink)
- [Deployment Guide](https://doc.skymail.ink/en/)
-- [Beginner’s Guide – UI Deployment](https://doc.skymail.ink/en/guide/via-ui.html) +- [UI Deployment](https://doc.skymail.ink/en/guide/via-ui.html) | ![](/doc/demo/demo1.png) | ![](/doc/demo/demo2.png) | -|--------------------------|---------------------| +|--------------------------|--------------------------| | ![](/doc/demo/demo3.png) | ![](/doc/demo/demo4.png) | -| ![](/doc/demo/demo5.png) | ![](/doc/demo/demo6.png) | -| ![](/doc/demo/demo7.png) | ![](/doc/demo/demo8.png) | ## Features @@ -34,8 +32,6 @@ - **🛡️ Admin Features**: Admins can manage users and emails, with RBAC permission control to limit access to features and resources. -- **🔀 Multiple Accounts**: Users can add multiple email accounts. - - **📦 Attachment Support**: Send and receive attachments, stored and downloaded via R2 object storage. - **🔔 Email Push**: Forward received emails to Telegram bots or other email providers. @@ -44,14 +40,8 @@ - **📈 Data Visualization**: Use Echarts to visualize system data, including user email growth. -- **⭐ Starred Emails**: Mark important emails for quick access. - - **🎨 Personalization**: Customize website title, login background, and transparency. -- **⚙️ Feature Settings**: Toggle on or off features like registration, email sending, and more, with the option to make the site private. - -- **🤖 CAPTCHA**: Integrated with Turnstile CAPTCHA to prevent automated registration. - - **📜 More Features**: Under development... ## Tech Stack @@ -62,7 +52,7 @@ - **ORM**: [Drizzle](https://orm.drizzle.team/) -- **Platform**: [Cloudflare Workers](https://developers.cloudflare.com/workers/) +- **Serverless Platform**: [Cloudflare Workers](https://developers.cloudflare.com/workers/) - **Email Service**: [Resend](https://resend.com/) @@ -75,17 +65,9 @@ ## Support - -

- - -**Special Sponsors** - -[DartNode](https://dartnode.com):Providing cloud computing service resource support. - -[![Powered by DartNode](https://dartnode.com/branding/DN-Open-Source-sm.png)](https://dartnode.com "Powered by DartNode - Free VPS for Open Source") + ## License diff --git a/README.md b/README.md index df40843..2fc608b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@

Cloud Mail

-

使用Vue3开发的响应式邮箱服务,支持邮件发送,无需服务器可部署到Cloudflare平台 🎉

+

Serverless 响应式邮箱服务,支持邮件发送,可部署到Cloudflare平台 🎉

简体中文 | English @@ -14,26 +14,24 @@ ## 项目简介 -只需要一个域名,就可以创建多个不同的邮箱,类似各大邮箱平台 QQ邮箱,谷歌邮箱等,本项目使用Cloudflare部署,Resend推送邮件,无需服务器费用,搭建自己的邮箱服务 +只需要一个域名,就可以创建多个不同的邮箱,类似各大邮箱平台,本项目可部署到 Cloudflare Workers ,降低服务器成本,搭建自己的邮箱服务 ## 项目展示 - [在线演示](https://skymail.ink)
- [部署文档](https://doc.skymail.ink)
-- [小白保姆教程-界面部署](https://doc.skymail.ink/guide/via-ui.html) +- [界面部署](https://doc.skymail.ink/guide/via-ui.html) | ![](/doc/demo/demo1.png) | ![](/doc/demo/demo2.png) | -|--------------------------|---------------------| -| ![](/doc/demo/demo3.png) | ![](/doc/demo/demo4.png) | -| ![](/doc/demo/demo5.png) | ![](/doc/demo/demo6.png) | -| ![](/doc/demo/demo7.png) | ![](/doc/demo/demo8.png) | +|-----------------------|-----------------------| +| ![](/doc/demo/demo3.png) | ![](/doc/demo/demo4.png) | ## 功能介绍 -- **💰 低成本使用**:无需服务器,部署到 Cloudflare Workers 降低使用成本 +- **💰 低成本使用**: 部署到 Cloudflare Workers 降低服务器成本 - **💻 响应式设计**:响应式布局自动适配PC和大部分手机端浏览器 @@ -41,8 +39,6 @@ - **🛡️ 管理员功能**:可以对用户,邮件进行管理,RABC权限控制对功能及使用资源限制 -- **🔀 多号模式**:开启后一个用户可以添加多个邮箱,默认一用户一邮箱,类似各大邮箱平台 - - **📦 附件收发**:支持收发附件,使用R2对象存储保存和下载文件 - **🔔 邮件推送**:接收邮件后可以转发到TG机器人或其他服务商邮箱 @@ -51,27 +47,21 @@ - **📈 数据可视化**:使用echarts对系统数据详情,用户邮件增长可视化显示 -- **⭐ 星标邮件**:标记重要邮件,以便快速查阅 - - **🎨 个性化设置**:可以自定义网站标题,登录背景,透明度 -- **⚙️ 功能设置**:可以对注册,邮件发送,添加等功能关闭和开启,设为私人站点 - -- **🤖 人机验证**:集成Turnstile人机验证,防止人机批量注册 - - **📜 更多功能**:正在开发中... ## 技术栈 -- **框架**:[Vue3](https://vuejs.org/) + [Element Plus](https://element-plus.org/) +- **前端框架**:[Vue3](https://vuejs.org/) + [Element Plus](https://element-plus.org/) - **Web框架**:[Hono](https://hono.dev/) - **ORM:**[Drizzle](https://orm.drizzle.team/) -- **平台:** [Cloudflare workers](https://developers.cloudflare.com/workers/) +- **Serverless 平台:** [Cloudflare workers](https://developers.cloudflare.com/workers/) - **邮件推送:** [Resend](https://resend.com/) @@ -84,17 +74,9 @@ ## 赞助 - -

- - -**特别赞助商** - -[DartNode](https://dartnode.com):提供云计算服务资源支持 - -[![Powered by DartNode](https://dartnode.com/branding/DN-Open-Source-sm.png)](https://dartnode.com "Powered by DartNode - Free VPS for Open Source") + ## 许可证 diff --git a/doc/demo/demo1.png b/doc/demo/demo1.png index cc48cde..bc8a7fc 100644 Binary files a/doc/demo/demo1.png and b/doc/demo/demo1.png differ diff --git a/doc/demo/demo2.png b/doc/demo/demo2.png index 559bb48..f295f53 100644 Binary files a/doc/demo/demo2.png and b/doc/demo/demo2.png differ diff --git a/doc/demo/demo3.png b/doc/demo/demo3.png index 91f7c03..d5d22a5 100644 Binary files a/doc/demo/demo3.png and b/doc/demo/demo3.png differ diff --git a/doc/demo/demo4.png b/doc/demo/demo4.png index cffc4af..565c297 100644 Binary files a/doc/demo/demo4.png and b/doc/demo/demo4.png differ diff --git a/doc/demo/demo5.png b/doc/demo/demo5.png deleted file mode 100644 index 3a004cc..0000000 Binary files a/doc/demo/demo5.png and /dev/null differ diff --git a/doc/demo/demo6.png b/doc/demo/demo6.png deleted file mode 100644 index 28eaa4d..0000000 Binary files a/doc/demo/demo6.png and /dev/null differ diff --git a/doc/demo/demo7.png b/doc/demo/demo7.png deleted file mode 100644 index adbe283..0000000 Binary files a/doc/demo/demo7.png and /dev/null differ diff --git a/doc/demo/demo8.png b/doc/demo/demo8.png deleted file mode 100644 index f1648c7..0000000 Binary files a/doc/demo/demo8.png and /dev/null differ diff --git a/doc/demo/logo.png b/doc/demo/logo.png index 0a6f4f2..0cf0378 100644 Binary files a/doc/demo/logo.png and b/doc/demo/logo.png differ diff --git a/mail-vue/src/layout/write/index.vue b/mail-vue/src/layout/write/index.vue index 62ad88a..0e34f01 100644 --- a/mail-vue/src/layout/write/index.vue +++ b/mail-vue/src/layout/write/index.vue @@ -167,12 +167,14 @@ const selectRecipientList = ref([]) const contacts = computed(() => writerStore.sendRecipientRecord.map(item => ({email: item}))) function openContacts() { - form.receiveEmail.forEach(item => { - if (writerStore.sendRecipientRecord.includes(item)) { - contactsTabRef.value.toggleRowSelection({email: item}); - } - }) showContacts.value = true + nextTick(() => { + form.receiveEmail.forEach(item => { + if (writerStore.sendRecipientRecord.includes(item)) { + contactsTabRef.value.toggleRowSelection({email: item}); + } + }) + }) } function deleteContact() { @@ -372,6 +374,8 @@ async function sendEmail() { userStore.refreshUserInfo(); + addRecipientRecord(); + if (form.draftId) { form.subject = '' form.content = '' @@ -379,8 +383,8 @@ async function sendEmail() { draftStore.setDraft = {...toRaw(form)} } - resetForm() show.value = false + resetForm(); }).catch((e) => { ElNotification({ title: t('sendFailMsg'), @@ -389,20 +393,22 @@ async function sendEmail() { position: 'bottom-right' }) show.value = true + addRecipientRecord(); }).finally(() => { percentMessage.close() percent.value = 0 sending = false - - writerStore.sendRecipientRecord = writerStore.sendRecipientRecord.filter( - email => !form.receiveEmail.includes(email) - ); - - writerStore.sendRecipientRecord.unshift(...form.receiveEmail); - writerStore.sendRecipientRecord = writerStore.sendRecipientRecord.slice(0, 500); }) } +function addRecipientRecord() { + writerStore.sendRecipientRecord = writerStore.sendRecipientRecord.filter( + email => !form.receiveEmail.includes(email) + ); + + writerStore.sendRecipientRecord.unshift(...form.receiveEmail); + writerStore.sendRecipientRecord = writerStore.sendRecipientRecord.slice(0, 500); +} function resetForm() { form.receiveEmail = [] diff --git a/mail-worker/src/service/r2-service.js b/mail-worker/src/service/r2-service.js index 40cd95f..523e48c 100644 --- a/mail-worker/src/service/r2-service.js +++ b/mail-worker/src/service/r2-service.js @@ -10,9 +10,9 @@ const r2Service = { } const setting = await settingService.query(c); - const { bucket, region, endpoint, s3AccessKey, s3SecretKey } = setting; + const { bucket, endpoint, s3AccessKey, s3SecretKey } = setting; - return !!(bucket && region && endpoint && s3AccessKey && s3SecretKey); + return !!(bucket && endpoint && s3AccessKey && s3SecretKey); }, async putObj(c, key, content, metadata) {