162 lines
7.1 KiB
Markdown
162 lines
7.1 KiB
Markdown
# 萌邮 MengPost · 多邮箱管理面板
|
||
|
||
基于 **SMTP / IMAP** 协议的轻量多邮箱管理后台。
|
||
|
||
- 前端: React 18 + Vite + React Router
|
||
- 后端: Go 1.22 + Gin + SQLite (`modernc.org/sqlite`, 纯 Go, 无需 CGO)
|
||
- 邮件: `gopkg.in/gomail.v2` (SMTP)、`github.com/emersion/go-imap` (IMAP)
|
||
- UI: 文档风、简洁, 自适应手机 / 电脑
|
||
- 鉴权: 打开站点时若本地未保存密钥,先显示 **访问密钥** 输入框(与后端 `MP_TOKEN` 一致,默认 `shumengya520`);通过后写入浏览器本地存储,后续请求带 `X-Auth-Token`
|
||
|
||
## 目录结构
|
||
|
||
```
|
||
mengpost/
|
||
dev.bat / dev.sh # 一键本地开发 (双窗口启动前后端)
|
||
build.bat / build.sh # 构建前端
|
||
mengpost-backend/ # Go + Gin 后端
|
||
config/ # 配置(端口/DB/token)
|
||
database/ # SQLite 初始化 & 迁移
|
||
models/ # 数据模型 (accounts / sent_logs)
|
||
services/ # smtp.go / imap.go
|
||
middleware/ # token 鉴权中间件
|
||
handlers/ # HTTP 处理器
|
||
router/ # 路由聚合
|
||
main.go # 入口
|
||
mengpost-frontend/ # React + Vite 前端
|
||
public/ # favicon.ico、logo.png 等静态资源
|
||
src/
|
||
api/ # 统一 fetch 封装, token 存 localStorage
|
||
components/ # AccessGate / MainLayout(侧栏) / Topbar
|
||
pages/ # Home / Admin / Accounts / Mailbox / Compose
|
||
styles/global.css
|
||
scripts/ # publish-gitea:用 tea 创建远端仓库的辅助脚本
|
||
```
|
||
|
||
## 本地开发
|
||
|
||
依赖:
|
||
- Go ≥ 1.22、Node.js ≥ 18 (SQLite 使用纯 Go 实现, **无需 CGO / gcc**)
|
||
|
||
```bash
|
||
# Windows
|
||
dev.bat
|
||
|
||
# macOS / Linux
|
||
chmod +x dev.sh && ./dev.sh
|
||
```
|
||
|
||
- 前端: http://127.0.0.1:5173
|
||
- 后端: http://127.0.0.1:8787 (Vite 已代理 `/api`)
|
||
|
||
## 构建
|
||
|
||
```bash
|
||
# Windows
|
||
build.bat
|
||
|
||
# macOS / Linux
|
||
./build.sh
|
||
```
|
||
|
||
产物在 `mengpost-frontend/dist`。`npm run preview` 已配置与开发环境相同的 `/api` 代理。
|
||
|
||
若静态文件与后端**不同源**部署,构建前设置 `VITE_API_URL` 指向后端根地址(如 `http://127.0.0.1:8787`),再执行 `build`。
|
||
|
||
## 环境变量
|
||
|
||
| 变量名 | 默认值 | 说明 |
|
||
| ---- | ---- | ---- |
|
||
| `MP_PORT` | `8787` | 后端 HTTP 端口 |
|
||
| `MP_DB` | `mengpost.db` | SQLite 文件路径 |
|
||
| `MP_TOKEN` | `shumengya520` | 访问密钥(与前端输入一致) |
|
||
| `MP_LOG` | `info` | 日志级别 |
|
||
|
||
### 前端 (Vite)
|
||
|
||
| 变量名 | 说明 |
|
||
| ---- | ---- |
|
||
| `VITE_API_URL` | 可选。留空时请求相对路径 `/api`(开发 / preview 走 Vite 代理)。独立部署静态站时设为后端地址。 |
|
||
|
||
## 使用
|
||
|
||
1. 用 `dev.bat` / `dev.sh` 启动后,浏览器打开 **http://127.0.0.1:5173**(勿用 `file://` 打开构建产物)。
|
||
2. 首次访问输入 **访问密钥**(与 `MP_TOKEN` 相同);顶部可 **登出** 清除本地密钥。
|
||
3. 在「账户」页新增邮箱 (SMTP / IMAP 与授权码)。
|
||
4. 「收件箱」拉取邮件;「写信」发信。
|
||
|
||
### 常见问题
|
||
|
||
- **未启动后端** 或端口不是 8787:密钥验证会失败或提示无法连接。
|
||
- **未通过 Vite 访问**:直接双击 `dist/index.html` 没有 `/api` 代理,需 `npm run preview` 或配置 `VITE_API_URL` 后重新构建。
|
||
- **使用了 `@vitejs/plugin-pwa` / Workbox**:勿让 Service Worker 缓存 `/api/*`。开发时可在 DevTools → Application → Service Workers 勾选 **Bypass for network** 或先 **Unregister** 再刷新。
|
||
|
||
## 常见邮箱参考
|
||
|
||
| 服务商 | SMTP | IMAP |
|
||
| ---- | ---- | ---- |
|
||
| QQ | `smtp.qq.com:465` | `imap.qq.com:993` |
|
||
| 163 | `smtp.163.com:465` | `imap.163.com:993` |
|
||
| Gmail | `smtp.gmail.com:465` | `imap.gmail.com:993` |
|
||
| Outlook / Hotmail(微软个人邮箱) | `smtp.office365.com:587`(STARTTLS) | `outlook.office365.com:993`(SSL) |
|
||
|
||
> 使用 **应用专用密码 / 授权码**, 不要直接使用邮箱登录密码。
|
||
|
||
### 微软 Outlook / Hotmail / Live(2026说明)
|
||
|
||
- **IMAP 默认关闭**:登录 [outlook.live.com](https://outlook.live.com) → 设置 → 邮件 → 同步电子邮件,开启 **IMAP**(不同界面可能为「POP和 IMAP」)。
|
||
- **服务器**:收信 `outlook.office365.com:993`(SSL/TLS),发信 `smtp.office365.com:587`(**STARTTLS**,勿填 465 除非你知道在做什么)。萌邮账户弹窗内可点 **「微软 Outlook / Hotmail」** 一键填入。
|
||
- **身份验证**:微软正推动 **新式验证(OAuth 2.0)**,传统 **用户名+密码(基础认证)** 在 **SMTP AUTH** 等场景将逐步停用(约 2026 年)。当前萌邮仍使用「应用密码 / 仍有效的账户密码」走基础认证;若发信被拒,需改用支持微软 OAuth 的客户端,或等待后续版本接入 OAuth。
|
||
- **后端**:对 `@outlook.com`、`@hotmail.com`、`@live.com`、`@msn.com` 会自动使用合适的 TLS `ServerName`,并在 IMAP/SMTP 报错时附加简要排查说明。
|
||
|
||
## API 一览
|
||
|
||
所有受保护接口均需要请求头 `X-Auth-Token: <token>`。
|
||
|
||
```
|
||
POST /api/auth/verify # 校验 token
|
||
GET /api/accounts # 列出账户
|
||
POST /api/accounts # 新增
|
||
PUT /api/accounts/:id # 更新 (password 为空则保留)
|
||
DELETE /api/accounts/:id # 删除
|
||
GET /api/accounts/:id/mailboxes # IMAP 邮件夹
|
||
GET /api/accounts/:id/messages # 列出邮件摘要 ?mailbox=&limit=
|
||
GET /api/accounts/:id/messages/:uid # 邮件详情
|
||
POST /api/accounts/:id/send # 发送邮件
|
||
GET /api/accounts/:id/sent # 发送日志
|
||
```
|
||
|
||
## 推送到自建 Gitea(tea CLI)
|
||
|
||
前置:安装 [tea](https://gitea.com/gitea/tea/releases),在 Gitea **设置 → 应用 → 生成令牌** 创建访问令牌。
|
||
|
||
```bash
|
||
# 1. 添加登录(只需一次;将 URL、令牌换成你的实例)
|
||
tea login add --url https://你的Gitea地址 --token <访问令牌> --name mygitea
|
||
tea login default mygitea
|
||
tea whoami
|
||
```
|
||
|
||
在本项目**根目录**执行:
|
||
|
||
```bash
|
||
# 2. 在 Gitea 上创建空仓库(名称可改;若已存在同名库请先删除或换名)
|
||
tea repos create --name mengpost --description "萌邮 MengPost:基于 SMTP/IMAP 的多邮箱管理面板(React + Vite + Go + Gin + SQLite)"
|
||
|
||
# 3. 添加远程并推送(将下面 URL 换成 Gitea 仓库页的 HTTPS 克隆地址)
|
||
git remote add origin https://你的Gitea/用户名/mengpost.git
|
||
git branch -M main
|
||
git push -u origin main
|
||
```
|
||
|
||
若本地已有 `origin`,可改为:`git remote set-url origin <HTTPS 地址>` 再 `git push -u origin main`。
|
||
|
||
**辅助脚本**(仅执行第 2 步 `tea repos create`,推送仍需手动 `git remote` + `git push`):
|
||
|
||
- Windows: `powershell -ExecutionPolicy Bypass -File scripts/publish-gitea.ps1`
|
||
- Linux / macOS: `chmod +x scripts/publish-gitea.sh && ./scripts/publish-gitea.sh`
|
||
|
||
## 许可
|
||
|
||
内部自用项目, 请按需修改。
|