Compare commits
19
Commits
ebc1748498
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dde912a392 | ||
|
|
d875e62ee6 | ||
|
|
4d4663e405 | ||
|
|
ab5d895ca1 | ||
|
|
5a3df648a2 | ||
|
|
5d6023a628 | ||
|
|
0ac267316b | ||
|
|
c72a374f21 | ||
|
|
594eb23979 | ||
|
|
12b21004b3 | ||
|
|
84ba8ceb06 | ||
|
|
30ac68ad5c | ||
|
|
3f9b966880 | ||
|
|
6d323146ff | ||
|
|
e5f0cb1870 | ||
|
|
68ea448688 | ||
|
|
8e71ee682c | ||
|
|
58f0db1b1d | ||
|
|
4dc2760f8a |
@@ -0,0 +1 @@
|
|||||||
|
.idea
|
||||||
@@ -1,2 +1,142 @@
|
|||||||
# send-mail
|
# Mini Email Sender
|
||||||
|
|
||||||
|
一个简易的邮件发送应用,用户可以通过前端界面填写邮件信息并发送邮件。
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
## 项目介绍
|
||||||
|
|
||||||
|
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
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea/modules.xml
|
||||||
|
.idea/jarRepositories.xml
|
||||||
|
.idea/compiler.xml
|
||||||
|
.idea/libraries/
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### Eclipse ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
|
|
||||||
|
### Mac OS ###
|
||||||
|
.DS_Store
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>cn.hezhaohui</groupId>
|
||||||
|
<artifactId>backend</artifactId>
|
||||||
|
<version>1.0-SNAPSHOT</version>
|
||||||
|
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>3.3.1</version>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<maven.compiler.source>21</maven.compiler.source>
|
||||||
|
<maven.compiler.target>21</maven.compiler.target>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-mail</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
package cn.hezhaohui.mail;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class SendMailApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(SendMailApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
package cn.hezhaohui.mail.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.mail.javamail.JavaMailSender;
|
||||||
|
import org.springframework.mail.javamail.JavaMailSenderImpl;
|
||||||
|
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class MailConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JavaMailSender getJavaMailSender() {
|
||||||
|
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
||||||
|
mailSender.setHost("smtp.163.com");
|
||||||
|
mailSender.setPort(465);
|
||||||
|
|
||||||
|
mailSender.setUsername("hezhaohui0807@163.com");
|
||||||
|
mailSender.setPassword("AMaauzQZQMnkSfZi");
|
||||||
|
|
||||||
|
Properties properties = mailSender.getJavaMailProperties();
|
||||||
|
properties.put("mail.transport.protocol", "smtp");
|
||||||
|
properties.put("mail.smtp.auth", "true");
|
||||||
|
properties.put("mail.smtp.ssl.enable", "true");
|
||||||
|
properties.put("mail.smtp.starttls.enable", "true");
|
||||||
|
properties.put("mail.debug", "true");
|
||||||
|
|
||||||
|
return mailSender;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package cn.hezhaohui.mail.service;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.springframework.mail.SimpleMailMessage;
|
||||||
|
import org.springframework.mail.javamail.JavaMailSender;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class MailService {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private JavaMailSender emailSender;
|
||||||
|
|
||||||
|
public void sendMessage(String to, String subject, String text) {
|
||||||
|
SimpleMailMessage message = new SimpleMailMessage();
|
||||||
|
message.setFrom("hezhaohui0807@163.com");
|
||||||
|
message.setTo(to);
|
||||||
|
message.setSubject(subject);
|
||||||
|
message.setText(text);
|
||||||
|
emailSender.send(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
package cn.hezhaohui.mail.service;
|
||||||
|
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class MailServiceTest {
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private MailService mailService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void sendMessage() {
|
||||||
|
mailService.sendMessage("2311719626@qq.com", "你好", "Test");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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,9 @@
|
|||||||
|
<script setup>
|
||||||
|
import EmailSender from './components/EmailSender.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<EmailSender />
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped></style>
|
||||||
@@ -0,0 +1,171 @@
|
|||||||
|
<template>
|
||||||
|
<div class="email-sender">
|
||||||
|
<h2>Mini Email Sender</h2>
|
||||||
|
<el-form
|
||||||
|
:model="emailForm"
|
||||||
|
:rules="rules"
|
||||||
|
ref="formRef"
|
||||||
|
label-width="100px"
|
||||||
|
@submit.prevent="submitForm"
|
||||||
|
>
|
||||||
|
<!-- 收件人 -->
|
||||||
|
<el-form-item label="收件人" prop="to">
|
||||||
|
<el-input
|
||||||
|
v-model="emailForm.to"
|
||||||
|
placeholder="请输入收件人邮箱地址"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 邮件标题 -->
|
||||||
|
<el-form-item label="标题" prop="subject">
|
||||||
|
<el-input
|
||||||
|
v-model="emailForm.subject"
|
||||||
|
placeholder="请输入邮件标题"
|
||||||
|
clearable
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
<!-- 邮件内容 -->
|
||||||
|
<el-form-item label="内容" prop="content">
|
||||||
|
<el-input
|
||||||
|
v-model="emailForm.content"
|
||||||
|
type="textarea"
|
||||||
|
placeholder="请输入邮件内容"
|
||||||
|
:rows="6"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 提交按钮 -->
|
||||||
|
<el-form-item>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
@click="submitForm"
|
||||||
|
:loading="submitting"
|
||||||
|
:disabled="submitting"
|
||||||
|
>
|
||||||
|
{{ submitting ? '发送中...' : '发送邮件' }}
|
||||||
|
</el-button>
|
||||||
|
<el-button @click="resetForm">重置</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<!-- 状态提示 -->
|
||||||
|
<el-alert
|
||||||
|
v-if="message"
|
||||||
|
:title="message"
|
||||||
|
:type="messageType"
|
||||||
|
show-icon
|
||||||
|
closable
|
||||||
|
style="margin-top: 20px;"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref, reactive } from 'vue'
|
||||||
|
import { ElForm, ElFormItem, ElInput, ElButton, ElAlert } from 'element-plus'
|
||||||
|
import axios from 'axios'
|
||||||
|
|
||||||
|
// 表单引用
|
||||||
|
const formRef = ref()
|
||||||
|
|
||||||
|
// 表单数据
|
||||||
|
const emailForm = reactive({
|
||||||
|
to: '',
|
||||||
|
subject: '',
|
||||||
|
content: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
// 提交状态
|
||||||
|
const submitting = ref(false)
|
||||||
|
|
||||||
|
// 消息提示
|
||||||
|
const message = ref('')
|
||||||
|
const messageType = ref('success')
|
||||||
|
|
||||||
|
// 表单验证规则
|
||||||
|
const rules = {
|
||||||
|
to: [
|
||||||
|
{ required: true, message: '请输入收件人邮箱地址', trigger: 'blur' },
|
||||||
|
{ type: 'email', message: '请输入正确的邮箱地址', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
subject: [
|
||||||
|
{ required: true, message: '请输入邮件标题', trigger: 'blur' }
|
||||||
|
],
|
||||||
|
content: [
|
||||||
|
{ required: true, message: '请输入邮件内容', trigger: 'blur' }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 重置表单
|
||||||
|
const resetForm = () => {
|
||||||
|
formRef.value.resetFields()
|
||||||
|
message.value = ''
|
||||||
|
}
|
||||||
|
|
||||||
|
// 提交表单
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 验证表单
|
||||||
|
if (!formRef.value) return
|
||||||
|
|
||||||
|
try {
|
||||||
|
await formRef.value.validate()
|
||||||
|
|
||||||
|
// 构建发送数据
|
||||||
|
const formData = new FormData()
|
||||||
|
formData.append('to', emailForm.to)
|
||||||
|
formData.append('subject', emailForm.subject)
|
||||||
|
formData.append('content', emailForm.content)
|
||||||
|
|
||||||
|
submitting.value = true
|
||||||
|
message.value = ''
|
||||||
|
|
||||||
|
// 发送请求
|
||||||
|
const response = await axios.post('http://localhost:8080/api/email/send', formData, {
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'multipart/form-data'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 处理响应
|
||||||
|
if (response.data.status === 200) {
|
||||||
|
messageType.value = 'success'
|
||||||
|
message.value = '邮件已成功发送'
|
||||||
|
resetForm()
|
||||||
|
} else {
|
||||||
|
messageType.value = 'error'
|
||||||
|
message.value = response.data.message || '邮件发送失败'
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('发送邮件错误:', error)
|
||||||
|
messageType.value = 'error'
|
||||||
|
message.value = error.response?.data?.message || '邮件发送失败,请检查网络连接'
|
||||||
|
} finally {
|
||||||
|
submitting.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.email-sender {
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-sender h2 {
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-sender .el-form-item {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.email-sender .el-alert {
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import { createApp } from 'vue'
|
||||||
|
import App from './App.vue'
|
||||||
|
import ElementPlus from 'element-plus'
|
||||||
|
import 'element-plus/dist/index.css'
|
||||||
|
|
||||||
|
createApp(App).use(ElementPlus).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