Compare commits

...
8 Commits
Author SHA1 Message Date
wonder dde912a392 📝Docs: 增加图片 2025-10-08 00:45:15 +08:00
wonder d875e62ee6 📝Docs: Final 2025-10-08 00:43:15 +08:00
wonder 4d4663e405 🐛Fix: 修复前后端数据格式不一致问题 2025-10-08 00:40:21 +08:00
wonder ab5d895ca1 🐛Fix: 修复请求路径错误 2025-10-08 00:30:40 +08:00
wonder 5a3df648a2 🔄Update: 配置了跨域 2025-10-08 00:21:48 +08:00
wonder 5d6023a628 🔧Chore: 删除冗余导入 2025-10-08 00:18:26 +08:00
wonder 0ac267316b 🔄Update: 完成邮件发送接口 2025-10-08 00:17:22 +08:00
wonder c72a374f21 🔄Update: 删除附件功能 2025-10-08 00:17:05 +08:00
9 changed files with 199 additions and 231 deletions
-167
View File
@@ -1,167 +0,0 @@
# Mini Email Sender(PRD)
## **1. 项目名称**
**Email Sender Mini App (简称:Mini Email)**
---
## **2. 项目目标**
构建一个**简易的邮件发送应用**,用户可以通过前端界面填写相关邮件信息(收件人、标题、内容、附件)并提交,后端负责接收这些信息并实际发送邮件。此应用适用于企业、教育机构或个人用户,用于快速发送简要的邮件通知或信息。
---
## **3. 用户角色**
| 角色 | 说明 |
|--------------|---------------------------------------|
| 用户 | 使用系统发送邮件的人,可以是管理员或普通用户 |
| 管理员 | 系统的维护人员,负责配置邮件服务器相关参数 |
---
## **4. 功能需求**
### 4.1 基础功能
#### 4.1.1 邮件发送功能
- **功能描述**:用户填写收件人邮箱地址、邮件标题、邮件内容,选择附件(可选),提交按钮发送邮件。
- **输入字段**:
- 收件人邮箱(必填)
- 邮件标题(必填)
- 邮件正文(必填)
- 附件(可选,支持常见格式如 PDF, JPG, PNG)
- **提交方式**:通过 AJAX 提交,不刷新页面
- **发送效果**:
- 成功发送邮件后显示成功提示
- 发送失败时显示错误信息(如网络问题、邮箱格式错误)
#### 4.1.2 邮件发送状态反馈
- **功能描述**:后端处理完成邮件发送后,返回状态码和提示信息,前端展示结果。
- **成功状态**:状态码 200 + “邮件发送成功”
- **失败状态**:状态码 500 + “邮件发送失败,请检查网络或邮箱设置”
#### 4.1.3 邮件配置(后端)
- **功能描述**:后端支持 SMTP 配置,包括端口、服务器地址、账号、密码、发送邮箱等。
- **配置方式**:
- 后端支持通过配置文件(如 `application.yml`)配置 SMTP
- 管理员可以通过系统配置界面动态调整 SMTP 配置(可选)
### 4.2 可选功能(扩展)
| 功能描述 | 说明 |
|------------------|--------------------------------|
| 批量发送邮件 | 支持多名收件人一起发送 |
| 邮件模板管理 | 预设邮件模板,供用户选择或编辑 |
| 历史邮件记录 | 存储已发送邮件的记录(可选) |
| 邮件日志查看 | 管理员可查看发送日志(可选) |
---
## **5. 非功能需求**
| 类别 | 描述 |
|--------------|--------------------------------------|
| 性能 | 邮件发送处理时间应小于 3 秒 |
| 安全性 | 邮件发送接口需设置访问权限(如 API Key 或 JWT) |
| 可靠性 | 系统应能处理 1000 个并发请求的小型负载 |
| 可扩展性 | 系统应易于扩展,如加入邮件模板、日志等功能 |
| 可用性 | 邮件发送失败时需向用户反馈清晰错误信息 |
---
## **6. 技术选型**
### 6.1 前端(Vue)
- **框架**:Vue 3 + Vite(轻量、性能优化)
- **组件库**:Element Plus(UI 组件库)
- **HTTP 请求库**:Axios
- **样式**:Scss + Custom CSS
- **部署方式**:Nginx 或 Vercel
### 6.2 后端(Spring Boot)
- **框架**:Spring Boot 3.x
- **邮件发送功能**:Spring Mail + JavaMail
- **通信协议**:REST API
- **邮件配置支持**:YAML / Properties 配置
- **部署方式**:JAR/WAR(Docker 容器化可选)
---
## **7. 界面设计说明**
### 7.1 前端页面(Vue)
| 页面 | 说明 |
|--------------|--------------------------|
| 登录页面 | 系统可选登录功能(可选) |
| 邮件发送页 | 提供邮件发送表单(收件人、标题、内容、附件) |
| 邮件列表页 | 显示已发送邮件(可选) |
#### 邮件发送页界面元素(示例):
- 输入框(收件人)
- 输入框(标题)
- 富文本编辑器(正文)
- 上传按钮(附件)
- 提交按钮
- 提示信息区域(成功/失败)
### 7.2 状态提示示例
- **成功**:
```text
邮件已成功发送至:example@example.com
```
- **失败**:
```text
邮件发送失败:请检查邮箱地址或网络连接。
```
---
## **8. 接口设计(后端 API)**
### 8.1 发送邮件接口
| 方法 | 路径 | 请求体(JSON) | 响应体(JSON) |
|------|------------------|---------------------------|-------------------------|
| POST | `/api/email/send` | { "to": "xxx@xxx.com", "subject": "test", "content": "hello", "attachments": [] } | { "status": 200, "message": "success" } |
#### 拓展字段(附件):
- 使用 MultipartFile 上传附件,在后端接收时处理。
---
## **9. 备注**
- 本系统为**简易应用**,不涉及复杂邮件管理。
- 附件上传需采用 multipart/form-data 格式。
- 后端需配置 SMTP 服务器参数、邮箱认证(如 QQ 邮、163 邮等)。
- 若未配置 SMTP,则系统应默认提示“配置错误”。
---
## **10. 项目后续扩展建议**
- 集成邮件发送状态跟踪(如是否被送达、是否阅读)
- 添加定时发送邮件功能
- 支持 HTML 格式邮件内容
- 集成 SMTP 配置管理后台
---
## **附录**
### 附件上传限制(示例):
- 最大附件大小:10MB
- 支持格式:.jpg, .png, .pdf, .docx
- 文件命名方式:用户上传时的原始名称 + 时间戳
+140 -16
View File
@@ -1,18 +1,142 @@
# send-mail
# Mini Email Sender
一个简易的邮件发送应用,用户可以通过前端界面填写邮件信息并发送邮件。
![alt text](image.png)
## 项目介绍
Mini Email Sender 是一个前后端分离的邮件发送应用,采用现代化的技术栈构建。用户可以通过直观的前端界面快速发送邮件,后端负责处理邮件发送逻辑。
## 技术栈
### 后端 (Spring Boot)
- **框架**: Spring Boot 3.x
- **语言**: Java 21
- **邮件发送**: Spring Mail + JavaMail
- **构建工具**: Maven
### 前端 (Vue.js)
- **框架**: Vue 3 + Vite
- **UI组件库**: Element Plus
- **HTTP客户端**: Axios
- **样式**: Scss + Custom CSS
## 项目结构
```
.
├── backend/ # 后端代码
│ ├── src/main/java/cn/hezhaohui/mail/
│ │ ├── controller/ # 控制器层
│ │ ├── service/ # 服务层
│ │ ├── config/ # 配置类
│ │ └── entity/ # 实体类
│ └── pom.xml # Maven配置文件
├── frontend/ # 前端代码
│ ├── src/
│ │ ├── components/ # 组件目录
│ │ │ └── EmailSender.vue # 邮件发送组件
│ │ ├── App.vue # 根组件
│ │ └── main.js # 应用入口
│ └── package.json # 前端依赖配置
└── README.md # 项目说明文档
```
## 功能特性
### 前端功能
- 邮件发送表单(收件人、标题、内容)
- 表单验证(邮箱格式、必填项)
- 响应式UI界面
- 发送状态提示
- 重置表单功能
### 后端功能
- RESTful API接口
- 邮件发送服务
- 基本的错误处理
- 日志记录
## 快速开始
### 环境要求
- Java 21
- Node.js 16+
- Maven 3.6+
### 后端启动
1. 进入后端目录:
```bash
cd backend
```
2. 编译项目:
```bash
mvn clean compile
```
3. 运行应用:
```bash
mvn spring-boot:run
```
默认端口:`8080`
### 前端启动
1. 进入前端目录:
```bash
cd frontend
```
2. 安装依赖:
```bash
npm install
```
3. 启动开发服务器:
```bash
npm run dev
```
默认端口:`3000`
## API接口
### 发送邮件
- **URL**: `/api/email/send`
- **方法**: `POST`
- **参数**:
- `to` (string, 必填): 收件人邮箱地址
- `subject` (string, 必填): 邮件标题
- `content` (string, 必填): 邮件内容
- **响应**:
```json
{
"status": 200,
"message": "success"
}
```
## 配置说明
### 后端邮件配置
需要在 `application.properties` 或 `application.yml` 中配置SMTP服务器信息:
```yaml
spring:
mail:
host: smtp.example.com
port: 587
username: your-email@example.com
password: your-password
properties:
mail:
smtp:
auth: true
starttls:
enable: true
```
## 任务清单
| **任务编号** | **任务内容** |
|--------------|------------------------------------------------------------------------------|
| ✅T01 | 搭建 Vue 3 前端项目(使用 Vite) |
| ✅T02 | 开发邮件发送页面(含表单和附件上传功能) |
| ✅T03 | 集成 Axios 实现 AJAX 提交邮件数据 |
| T04 | 创建 Spring Boot 后端项目,集成 Spring Mail 发送邮件功能 |
| T05 | 开发 `/api/email/send` 接口,支持附件上传 |
| T06 | 配置 SMTP 参数(YAML/Properties) |
| T07 | 实现接口安全控制(API Key 或 JWT) |
| T08 | 处理附件上传逻辑(格式校验、大小限制、命名规则) |
| T09 | 邮件发送错误处理与格式验证(邮箱、SMTP 配置等) |
| T10 | 配置部署前端(Nginx / Vercel) |
| T11 | 部署后端服务(JAR/WAR 或 Docker) |
| T12 | 进行性能测试 |
+5
View File
@@ -35,6 +35,11 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
@@ -1,7 +1,5 @@
package cn.hezhaohui.mail;
import cn.hezhaohui.mail.service.MailService;
import jakarta.annotation.Resource;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@@ -0,0 +1,19 @@
package cn.hezhaohui.mail.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**") // 应用到所有路径
.allowedOrigins("http://localhost:5173") // 允许前端开发服务器的源
.allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") // 允许的HTTP方法
.allowedHeaders("*") // 允许所有header
.allowCredentials(true) // 允许发送凭证信息(如cookies)
.maxAge(3600); // 预检请求的有效期,单位为秒
}
}
@@ -0,0 +1,23 @@
package cn.hezhaohui.mail.controller;
import cn.hezhaohui.mail.entity.Response;
import cn.hezhaohui.mail.service.MailService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
@RestController
@RequestMapping("/api/email")
@Slf4j
public class MailController {
@Resource
private MailService mailService;
@PostMapping("/send")
public Response sendMail(@RequestParam String to, @RequestParam String subject, @RequestParam String content) {
mailService.sendMessage(to, subject, content);
log.info("[To]: {}\n[Subject]: {}\n[Content]: {}\n", to, subject, content);
return new Response(200, "success");
}
}
@@ -0,0 +1,10 @@
package cn.hezhaohui.mail.entity;
import lombok.Data;
@Data
public class Response {
final private int status;
final private String message;
}
+2 -46
View File
@@ -36,26 +36,6 @@
/>
</el-form-item>
<!-- 附件 -->
<el-form-item label="附件">
<el-upload
v-model:file-list="fileList"
action="/api/upload"
:auto-upload="false"
:on-change="handleFileChange"
:on-remove="handleFileRemove"
multiple
:limit="5"
:on-exceed="handleExceed"
>
<el-button type="primary">选择文件</el-button>
<template #tip>
<div class="el-upload__tip">
支持格式:.jpg, .png, .pdf, .docx,最多5个文件,每个文件不超过10MB
</div>
</template>
</el-upload>
</el-form-item>
<!-- 提交按钮 -->
<el-form-item>
@@ -85,7 +65,7 @@
<script setup>
import { ref, reactive } from 'vue'
import { ElForm, ElFormItem, ElInput, ElButton, ElUpload, ElAlert } from 'element-plus'
import { ElForm, ElFormItem, ElInput, ElButton, ElAlert } from 'element-plus'
import axios from 'axios'
// 表单引用
@@ -98,9 +78,6 @@ const emailForm = reactive({
content: ''
})
// 文件列表
const fileList = ref([])
// 提交状态
const submitting = ref(false)
@@ -122,26 +99,10 @@ const rules = {
]
}
// 处理文件变化
const handleFileChange = (file, fileList) => {
// 可以在这里添加文件验证逻辑
console.log('文件变化:', file, fileList)
}
// 处理文件移除
const handleFileRemove = (file, fileList) => {
console.log('文件移除:', file, fileList)
}
// 处理文件超出限制
const handleExceed = () => {
ElMessage.warning('最多只能上传5个文件')
}
// 重置表单
const resetForm = () => {
formRef.value.resetFields()
fileList.value = []
message.value = ''
}
@@ -159,16 +120,11 @@ const submitForm = async () => {
formData.append('subject', emailForm.subject)
formData.append('content', emailForm.content)
// 添加附件
fileList.value.forEach(file => {
formData.append('attachments', file.raw)
})
submitting.value = true
message.value = ''
// 发送请求
const response = await axios.post('http:localhost:8080/api/email/send', formData, {
const response = await axios.post('http://localhost:8080/api/email/send', formData, {
headers: {
'Content-Type': 'multipart/form-data'
}
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 116 KiB