Compare commits
4
Commits
ebc1748498
...
68ea448688
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
68ea448688 | ||
|
|
8e71ee682c | ||
|
|
58f0db1b1d | ||
|
|
4dc2760f8a |
@@ -0,0 +1 @@
|
|||||||
|
.idea
|
||||||
@@ -0,0 +1,167 @@
|
|||||||
|
# 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
|
||||||
|
- 文件命名方式:用户上传时的原始名称 + 时间戳
|
||||||
@@ -1,2 +1,19 @@
|
|||||||
# send-mail
|
# send-mail
|
||||||
|
|
||||||
|
## 任务清单
|
||||||
|
|
||||||
|
| **任务编号** | **任务内容** |
|
||||||
|
|--------------|------------------------------------------------------------------------------|
|
||||||
|
| T01 | 搭建 Vue 3 前端项目(使用 Vite) |
|
||||||
|
| T02 | 开发邮件发送页面(含表单和附件上传功能) |
|
||||||
|
| T03 | 集成 Axios 实现 AJAX 提交邮件数据 |
|
||||||
|
| T04 | 实现邮件发送状态提示(成功/失败) |
|
||||||
|
| T05 | 创建 Spring Boot 后端项目,集成 Spring Mail 发送邮件功能 |
|
||||||
|
| T06 | 开发 `/api/email/send` 接口,支持附件上传 |
|
||||||
|
| T07 | 配置 SMTP 参数(YAML/Properties) |
|
||||||
|
| T08 | 实现接口安全控制(API Key 或 JWT) |
|
||||||
|
| T09 | 处理附件上传逻辑(格式校验、大小限制、命名规则) |
|
||||||
|
| T10 | 邮件发送错误处理与格式验证(邮箱、SMTP 配置等) |
|
||||||
|
| T11 | 配置部署前端(Nginx / Vercel) |
|
||||||
|
| T12 | 部署后端服务(JAR/WAR 或 Docker) |
|
||||||
|
| T14 | 进行性能测试 |
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
[*.{js,jsx,mjs,cjs,ts,tsx,mts,cts,vue,css,scss,sass,less,styl}]
|
||||||
|
charset = utf-8
|
||||||
|
indent_size = 2
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
end_of_line = lf
|
||||||
|
max_line_length = 100
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
* text=auto eol=lf
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Logs
|
||||||
|
logs
|
||||||
|
*.log
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
pnpm-debug.log*
|
||||||
|
lerna-debug.log*
|
||||||
|
|
||||||
|
node_modules
|
||||||
|
.DS_Store
|
||||||
|
dist
|
||||||
|
dist-ssr
|
||||||
|
coverage
|
||||||
|
*.local
|
||||||
|
|
||||||
|
/cypress/videos/
|
||||||
|
/cypress/screenshots/
|
||||||
|
|
||||||
|
# Editor directories and files
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/extensions.json
|
||||||
|
.idea
|
||||||
|
*.suo
|
||||||
|
*.ntvs*
|
||||||
|
*.njsproj
|
||||||
|
*.sln
|
||||||
|
*.sw?
|
||||||
|
|
||||||
|
*.tsbuildinfo
|
||||||
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"recommendations": [
|
||||||
|
"Vue.volar",
|
||||||
|
"dbaeumer.vscode-eslint",
|
||||||
|
"EditorConfig.EditorConfig"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { defineConfig, globalIgnores } from 'eslint/config'
|
||||||
|
import globals from 'globals'
|
||||||
|
import js from '@eslint/js'
|
||||||
|
import pluginVue from 'eslint-plugin-vue'
|
||||||
|
|
||||||
|
export default defineConfig([
|
||||||
|
{
|
||||||
|
name: 'app/files-to-lint',
|
||||||
|
files: ['**/*.{js,mjs,jsx,vue}'],
|
||||||
|
},
|
||||||
|
|
||||||
|
globalIgnores(['**/dist/**', '**/dist-ssr/**', '**/coverage/**']),
|
||||||
|
|
||||||
|
{
|
||||||
|
languageOptions: {
|
||||||
|
globals: {
|
||||||
|
...globals.browser,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
js.configs.recommended,
|
||||||
|
...pluginVue.configs['flat/essential'],
|
||||||
|
])
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<link rel="icon" href="/favicon.ico">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Vite App</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="app"></div>
|
||||||
|
<script type="module" src="/src/main.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["./src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
||||||
Generated
+4494
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"name": "frontend",
|
||||||
|
"version": "0.0.0",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"engines": {
|
||||||
|
"node": "^20.19.0 || >=22.12.0"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vite",
|
||||||
|
"build": "vite build",
|
||||||
|
"preview": "vite preview",
|
||||||
|
"lint": "eslint . --fix"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "^1.12.2",
|
||||||
|
"element-plus": "^2.11.4",
|
||||||
|
"vue": "^3.5.22"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.33.0",
|
||||||
|
"@vitejs/plugin-vue": "^6.0.1",
|
||||||
|
"eslint": "^9.33.0",
|
||||||
|
"eslint-plugin-vue": "~10.4.0",
|
||||||
|
"globals": "^16.3.0",
|
||||||
|
"vite": "^7.1.7",
|
||||||
|
"vite-plugin-vue-devtools": "^8.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
@@ -0,0 +1,7 @@
|
|||||||
|
<script setup></script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<h1>Hello World</h1>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
|
||||||
|
createApp(App).mount('#app')
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { fileURLToPath, URL } from 'node:url'
|
||||||
|
|
||||||
|
import { defineConfig } from 'vite'
|
||||||
|
import vue from '@vitejs/plugin-vue'
|
||||||
|
import vueDevTools from 'vite-plugin-vue-devtools'
|
||||||
|
|
||||||
|
// https://vite.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
vue(),
|
||||||
|
vueDevTools(),
|
||||||
|
],
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
'@': fileURLToPath(new URL('./src', import.meta.url))
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
Reference in New Issue
Block a user