# zmail **Repository Path**: cpsoft13/zmail ## Basic Information - **Project Name**: zmail - **Description**: 在线邮件客户端 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-06-06 - **Last Updated**: 2026-06-11 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # z-mail > Email 客户端库,作为微服务嵌入到第三方系统中。 ## 定位 z-mail 本身**不是**一个独立邮件系统。它是一个 **library crate + React 组件库**,供调用方微服务嵌入使用,提供邮件接收/发送能力。 ## 架构 ``` 调用方微服务 └── z-mail-client (公共 API,唯一入口) ├── z-mail-ports (trait 抽象层) │ ├── EmailReceiver ← 收信接口 │ ├── EmailSender ← 发信接口 │ └── AuthProvider ← 认证接口 ├── z-mail-core (domain 模型 + 错误类型) └── 适配器 crates ├── z-mail-imap (IMAP/SMTP) └── z-mail-gmail (Gmail API, 待开发) ``` 调用方只需要依赖 `z-mail-client` 一个 crate。 ## 快速开始 ### 1. Rust 库集成 **添加依赖** (`Cargo.toml`): ```toml [dependencies] z-mail-client = { git = "https://gitee.com/cpsoft13/zmail.git" } ``` **连接阿里云企业邮箱**: ```rust use z_mail_client::AliyunPreset; use z_mail_ports::receiver::EmailReceiver; use z_mail_ports::sender::{EmailSender, OutgoingMessage}; #[tokio::main] async fn main() -> Result<(), Box> { // 阿里云企业版邮箱(一行创建) let client = AliyunPreset::enterprise( "user@company.com", "三方客户端安全密码", // ⚠️ 不是网页登录密码 )?; // 列出邮箱文件夹 let mailboxes = client.list_mailboxes().await?; for mb in &mailboxes { println!("{} — {} 封({} 未读)", mb.name, mb.total_messages, mb.unread_messages); } // 发送邮件 let msg = OutgoingMessage::simple( z_mail_core::EmailAddress::new("to@example.com"), "主题", "邮件正文", ); client.send(msg).await?; Ok(()) } ``` **通用 IMAP/SMTP 连接**(非阿里云): ```rust use z_mail_client::MailClient; let client = MailClient::builder() .imap_host("imap.example.com", 993) .smtp_host("smtp.example.com", 587) .smtp_encryption(z_mail_client::SmtpEncryption::StartTls) .password_auth("user@example.com", "password") .build()?; ``` **阿里云预设变体**: | 方法 | 适用场景 | IMAP 服务器 | |------|---------|-------------| | `AliyunPreset::personal()` | 个人版 | `imap.aliyun.com` | | `AliyunPreset::enterprise()` | 企业版 | `imap.qiye.aliyun.com` | | `AliyunPreset::hk()` | 香港节点 | `imaphk.qiye.aliyun.com` | | `AliyunPreset::legacy()` | 旧版 (mxhichina) | `imap.mxhichina.com` | > ⚠️ **安全提示**:阿里云邮箱要求使用"三方客户端安全密码"(在网页邮箱设置中生成),不能使用网页登录密码。 ### 2. React 组件集成 **安装**: ```bash npm install @z-mail/react ``` **使用 EmailViewer 展示邮件**: ```tsx import { EmailViewer } from '@z-mail/react'; import type { SafeEmailMessage } from '@z-mail/react'; function MyEmailPage() { const [email, setEmail] = useState(null); useEffect(() => { fetch('/api/emails/123') .then(r => r.json()) .then(setEmail); }, []); if (!email) return

加载中…

; return ( downloadFile(att.id), }} /> ); } ``` **EmailViewer Props**: | 属性 | 类型 | 说明 | |------|------|------| | `email` | `SafeEmailMessage` | 必需,sanitize 后的邮件数据 | | `config` | `EmailViewerConfig` | 可选配置 | | `className` | `string` | 外层 class 覆盖 | | `style` | `CSSProperties` | 外层样式覆盖 | **EmailViewerConfig**: | 配置项 | 类型 | 默认值 | 说明 | |--------|------|--------|------| | `allowExternalImages` | `boolean` | `false` | 是否加载外部图片 | | `hideHeader` | `boolean` | `false` | 隐藏邮件头 | | `borderless` | `boolean` | `false` | 无边框模式(嵌入使用) | | `locale` | `string` | 自动 | 日期格式化 locale | | `dateFormat` | `Intl.DateTimeFormatOptions` | — | 日期格式覆盖 | | `onAttachmentClick` | `(att) => void` | — | 附件点击回调 | | `theme` | `Partial` | — | 主题色覆盖 | **使用 ComposeDialog 写邮件**: ```tsx import { ComposeDialog } from '@z-mail/react'; import type { ComposeMode, ComposeData } from '@z-mail/react'; setOpen(false)} onSend={async (data: ComposeData) => { // data: { to, cc, bcc, subject, bodyText, bodyHtml, attachments } await fetch('/api/send', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data), }); }} /> ``` **SafeEmailMessage 类型**(与 Rust `z-mail-web` 序列化对应): ```typescript interface SafeEmailMessage { id: string; // 邮件唯一 ID(复合格式 "mailbox/uid") threadId?: string; from: { email: string; displayName?: string }; to: { email: string; displayName?: string }[]; cc?: { email: string; displayName?: string }[]; subject: string; bodyHtml: string | null; // HTML 正文(已 sanitize) bodyText: string | null; // 纯文本正文 attachments?: SafeAttachment[]; date: string; // ISO 8601 isRead: boolean; hasAttachments: boolean; labels?: string[]; } ``` **主题定制**:可传递 `theme` 对象给 EmailViewer,或在父元素上覆盖 CSS 变量: ```css .my-email-container { --ev-background: #fafafa; --ev-text: #1e293b; --ev-border: #e2e8f0; --ev-link: #2563eb; --ev-shadow-sm: 0 2px 8px rgba(0, 0, 0, 0.08); --ev-radius-md: 6px; /* … 完整变量列表见 src/styles/variables.css */ } ``` ### 3. Demo 服务器 API Demo 提供标准 REST API,可作为集成参考。 **启动**: ```bash ALIYUN_EMAIL=user@company.com ALIYUN_PASSWORD=xxx \ cargo run -p z-mail-demo ``` 服务监听 `http://localhost:3000`。 **API 端点**: | 方法 | 路径 | 说明 | |------|------|------| | `GET` | `/api/status` | 健康检查 + 当前用户信息 | | `GET` | `/api/mailboxes` | 列出邮箱文件夹 | | `GET` | `/api/emails?mailbox=INBOX&page=1&page_size=20` | 邮件列表(轻量,不含正文) | | `GET` | `/api/emails/:id` | 邮件详情(含正文 bodyHtml/bodyText) | | `POST` | `/api/send` | 发送邮件 | | `POST` | `/api/emails/:id/delete` | 删除邮件 | | `PATCH` | `/api/emails/:id/read` | 标记已读/未读 | | `POST` | `/api/emails/:id/move` | 移动到指定文件夹 | | `POST` | `/api/copy-sent-to-inbox` | 将已发送邮件复制到 INBOX | **Status 响应**: ```json { "status": "ok", "user_email": "zhuhao@company.com", "can_receive": true, "can_send": true } ``` **Send 请求体**: ```json { "to": ["recipient@example.com"], "cc": [], "bcc": [], "subject": "邮件主题", "body_text": "纯文本正文", "body_html": "

HTML 正文

", "attachments": [ { "filename": "report.pdf", "mime_type": "application/pdf", "data_base64": "..." } ] } ``` > **注意**:列表接口 (`GET /api/emails`) 出于性能考虑不返回邮件正文。前端应在用户展开邮件时调用详情接口 (`GET /api/emails/:id`) 懒加载正文。 ## 项目结构 ``` z-mail/ ├── crates/ │ ├── z-mail-client/ # 公共 API(唯一入口) │ ├── z-mail-ports/ # trait 抽象层 │ ├── z-mail-core/ # domain 模型 + 错误类型 │ ├── z-mail-imap/ # IMAP/SMTP 适配器 │ ├── z-mail-web/ # HTML sanitize → SafeEmailMessage │ └── z-mail-demo/ # Demo HTTP 服务器 ├── web-components/ │ └── z-mail-react/ # React 组件库 │ ├── src/ │ │ ├── components/ │ │ │ ├── EmailViewer/ # 邮件展示 │ │ │ ├── ComposeDialog/ # 写邮件/回复/转发 │ │ │ ├── ConversationList/ # 对话聚合列表 │ │ │ ├── EmailHeader/ # 邮件头部 │ │ │ ├── EmailBody/ # 邮件正文 │ │ │ └── AttachmentList/ # 附件列表 │ │ ├── styles/variables.css # CSS 变量(主题定制入口) │ │ └── types/ # TypeScript 类型定义 │ └── demo/ # 前端 Demo App └── wiki/ # 文档 ├── 10-WALKTHROUGH/ # Walkthrough 记录 ├── 09-PLANNING/ # 任务规划 + Feature SSoT └── 11-REFERENCE/ # 工程标准 ``` ## Rust 编译要求 - Rust 1.75+ - `cargo build` 即可编译 ## React 组件开发 ```bash cd web-components/z-mail-react # 安装依赖 npm install # 启动 demo(需要先启动 Rust 后端) cd demo npx vite # 类型检查 npx tsc --noEmit ``` ## 许可 MIT