Compare commits

...

4 Commits

17 changed files with 473 additions and 164 deletions

View File

@ -28,7 +28,11 @@
<artifactId>jaxb-api</artifactId>
<version>2.1</version>
</dependency>
<!-- 数据库代码生成器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- 数据库代码生成器 - 新版 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
@ -39,6 +43,7 @@
<artifactId>velocity-engine-core</artifactId>
<version>2.3</version>
</dependency>
<!-- 数据库代码生成器 - 旧版 -->
<!-- <dependency> -->
<!-- <groupId>com.baomidou</groupId> -->
<!-- <artifactId>mybatis-plus-generator</artifactId> -->

View File

@ -0,0 +1,159 @@
package cn.bunny.common.utils;
import cn.bunny.entity.email.EmailSend;
import cn.bunny.entity.email.EmailSendInit;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.multipart.MultipartFile;
import java.util.Objects;
public class MailSenderHelper {
private final String username;
private final JavaMailSenderImpl javaMailSender;
/**
* 初始化构造函数进行当前类赋值
*/
public MailSenderHelper(EmailSendInit emailSendInit) {
JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();
javaMailSender.setHost(emailSendInit.getHost());
javaMailSender.setPort(emailSendInit.getPort());
javaMailSender.setUsername(emailSendInit.getUsername());
javaMailSender.setPassword(emailSendInit.getPassword());
javaMailSender.setProtocol("smtps");
javaMailSender.setDefaultEncoding("UTF-8");
this.username = emailSendInit.getUsername();
this.javaMailSender = javaMailSender;
}
/**
* 发送邮件-简单
*
* @param emailSend 邮件消息
*/
public void sendSimpleEmail(EmailSend emailSend) {
// 创建邮件消息体 SimpleMailMessage 发送简单邮件
SimpleMailMessage mailMessage = new SimpleMailMessage();
// 设置邮件发送人
mailMessage.setFrom(username);
// 设置邮件接受者
mailMessage.setTo(emailSend.getSendTo());
// 设置邮件主题
mailMessage.setSubject(emailSend.getSubject());
// 设置邮件消息
mailMessage.setText(emailSend.getMessage());
javaMailSender.send(mailMessage);
}
/**
* 发送带附件邮件
*
* @param emailSend 邮件消息
*/
public void sendAttachmentEmail(EmailSend emailSend, MultipartFile file, boolean isRich) throws MessagingException {
// 创建 MimeMessage 对象用户发送附件或者是富文本内容
MimeMessage mailMessage = javaMailSender.createMimeMessage();
// 创建 MimeMessageHelper
MimeMessageHelper helper = new MimeMessageHelper(mailMessage, true);
// 奢姿邮件发送人
helper.setFrom(username);
// 设置邮件接受者
helper.setTo(emailSend.getSendTo());
// 设置邮件消息
helper.setText(emailSend.getMessage(), isRich);
// 设置邮件主题
helper.setSubject(emailSend.getSubject());
// 邮件添加附件
helper.addAttachment(Objects.requireNonNull(file.getOriginalFilename()), file);
// 发送邮件
javaMailSender.send(mailMessage);
}
/**
* 发送富文本邮件
*
* @param emailSend 邮件消息
*/
public void sendRichText(EmailSend emailSend, boolean isRich) throws MessagingException {
// 创建 MimeMessage 对象用户发送附件或者是富文本内容
MimeMessage mailMessage = javaMailSender.createMimeMessage();
// 创建 MimeMessageHelper
MimeMessageHelper helper = new MimeMessageHelper(mailMessage, true);
// 设置邮件发送者
helper.setFrom(username);
// 设置邮件接受者
helper.setTo(emailSend.getSendTo());
// 设置邮件主题
helper.setSubject(emailSend.getSubject());
// 设置邮件富文本后面跟true 表示HTML格式发送
helper.setText(emailSend.getMessage(), isRich);
// 发送邮件
javaMailSender.send(mailMessage);
}
/**
* 发送带抄送的邮件
*
* @param emailSend 邮件消息
*/
public void sendCC(EmailSend emailSend, boolean isRich) throws MessagingException {
// 创建 MimeMessage 对象用于发送邮件富文本或者附件
MimeMessage message = javaMailSender.createMimeMessage();
// 创建 MimeMessageHelper
MimeMessageHelper helper = new MimeMessageHelper(message, true);
// 设置发送人
helper.setFrom(username);
// 设置邮件接受者
helper.setTo(emailSend.getSendTo());
// 设置邮件主题
helper.setSubject(emailSend.getSubject());
// 设置发送消息 为富文本
helper.setText(emailSend.getMessage(), isRich);
// 设置抄送人
helper.setCc(emailSend.getCcParam().split(","));
// 发送邮件
javaMailSender.send(message);
}
/**
* 综合邮箱发送
*
* @param emailSend 邮件消息
*/
public void sendEmail(EmailSend emailSend) throws MessagingException {
// 创建 MimeMessage 对象用于发送邮件富文本或者附件
MimeMessage message = javaMailSender.createMimeMessage();
// 创建 MimeMessageHelper
MimeMessageHelper helper = new MimeMessageHelper(message, true);
// 设置发送人
helper.setFrom(username);
// 设置邮件接受者
helper.setTo(emailSend.getSendTo());
// 设置邮件主题
helper.setSubject(emailSend.getSubject());
// 设置发送消息 为富文本
helper.setText(emailSend.getMessage(), emailSend.getIsRichText());
// 设置抄送人
helper.setCc(emailSend.getCcParam().split(","));
// 邮件添加附件
MultipartFile file = emailSend.getFile();
helper.addAttachment(Objects.requireNonNull(file.getOriginalFilename()), file);
// 发送邮件
javaMailSender.send(message);
}
}

View File

@ -0,0 +1,26 @@
package cn.bunny.entity.email;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.web.multipart.MultipartFile;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class EmailSend {
// 给谁发送
private String sendTo;
// 发送主题
private String subject;
// 是否为富文本
private Boolean isRichText;
// 发送内容
private String message;
// 抄送人
private String ccParam;
// 发送的文件
private MultipartFile file;
}

View File

@ -0,0 +1,20 @@
package cn.bunny.entity.email;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 邮箱发送初始化参数
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class EmailSendInit {
private Integer port;
private String host;
private String username;
private String password;
}

View File

@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.5</version>
<version>3.2.3</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.bunny</groupId>

View File

@ -1,70 +0,0 @@
package cn.bunny.service.Bunny;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import java.time.LocalDateTime;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Accessors;
/**
* <p>
* 菜单表
* </p>
*
* @author Bunny
* @since 2024-05-06
*/
@Getter
@Setter
@Accessors(chain = true)
@TableName("sys_menu")
@ApiModel(value = "SysMenu对象", description = "菜单表")
public class SysMenu implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty("编号")
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@ApiModelProperty("所属上级")
private Long parentId;
@ApiModelProperty("名称")
private String name;
@ApiModelProperty("类型(0:目录,1:菜单,2:按钮)")
private Byte type;
@ApiModelProperty("路由地址")
private String path;
@ApiModelProperty("组件路径")
private String component;
@ApiModelProperty("权限标识")
private String perms;
@ApiModelProperty("图标")
private String icon;
@ApiModelProperty("排序")
private Integer sortValue;
@ApiModelProperty("状态(0:禁止,1:正常)")
private Byte status;
@ApiModelProperty("创建时间")
private LocalDateTime createTime;
@ApiModelProperty("更新时间")
private LocalDateTime updateTime;
@ApiModelProperty("删除标记0:不可用 1:可用)")
private Byte isDeleted;
}

View File

@ -1,4 +1,4 @@
package cn.bunny.service.annotation;
package cn.bunny.service.aop.annotation;
import cn.bunny.enums.OperationType;

View File

@ -0,0 +1,27 @@
package cn.bunny.service.aop.aspect;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
@Pointcut("execution(* cn.bunny.service.*.*(..))")
public void autoFillPointcut() {
}
/**
* 之前操作
*
* @param joinPoint 参数
*/
@Before("autoFillPointcut()")
public void autoFill(JoinPoint joinPoint) {
log.info("开始进行自动填充");
}
}

View File

@ -1,74 +0,0 @@
package cn.bunny.service.aspect;
import cn.bunny.common.constant.SQLAutoFillConstant;
import cn.bunny.common.service.context.BaseContext;
import cn.bunny.enums.OperationType;
import cn.bunny.service.annotation.AutoFill;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.time.LocalDateTime;
@Aspect
@Component
@Slf4j
public class AutoFillAspect {
@Pointcut("execution(* cn.bunny.service.*.*(..))")
public void autoFillPointcut() {
}
/**
* 之前操作
*
* @param joinPoint 参数
*/
@Before("autoFillPointcut()")
public void autoFill(JoinPoint joinPoint) {
log.info("开始进行自动填充");
// 获取当前被拦截数据库操作
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
AutoFill autoFill = signature.getMethod().getAnnotation(AutoFill.class);
OperationType operationType = autoFill.value();
// 获取实体对象
Object[] args = joinPoint.getArgs();
if (args == null || args.length == 0) {
return;
}
Object entity = args[0];
// 准备赋值数据
LocalDateTime localDateTime = LocalDateTime.now();
Long id = BaseContext.getUserId();
// 根据当前不同的操作类型为对应属性来反射赋值
if (operationType == OperationType.INSERT) {
try {
Method setCreateTime = entity.getClass().getDeclaredMethod(SQLAutoFillConstant.SET_CREATE_TIME, LocalDateTime.class);
Method setCreateUser = entity.getClass().getDeclaredMethod(SQLAutoFillConstant.SET_CREATE_USER, Long.class);
Method setUpdateTime = entity.getClass().getMethod(SQLAutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setUpdateUser = entity.getClass().getMethod(SQLAutoFillConstant.SET_UPDATE_USER, Long.class);
setCreateTime.invoke(entity, localDateTime);
setCreateUser.invoke(entity, id);
setUpdateTime.invoke(entity, localDateTime);
setUpdateUser.invoke(entity, id);
} catch (Exception e) {
e.printStackTrace();
}
} else if (operationType == OperationType.UPDATE) {
try {
Method setUpdateTime = entity.getClass().getDeclaredMethod(SQLAutoFillConstant.SET_UPDATE_TIME, LocalDateTime.class);
Method setUpdateUser = entity.getClass().getDeclaredMethod(SQLAutoFillConstant.SET_UPDATE_USER, Long.class);
setUpdateTime.invoke(entity, localDateTime);
setUpdateUser.invoke(entity, id);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}

View File

@ -0,0 +1,58 @@
package cn.bunny.service.controller;
import cn.bunny.common.result.Result;
import cn.bunny.entity.email.EmailSend;
import cn.bunny.service.service.EmailService;
import com.alibaba.fastjson2.JSON;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
@Tag(name = "发送邮件")
@RequestMapping("/test/mail")
@Slf4j
public class MailController {
@Autowired
private EmailService emailService;
@Operation(summary = "发送简单邮件", description = "发送简单邮件")
@PostMapping("/send-text")
public Result<String> sendText(@RequestBody EmailSend emailSend) {
log.info("发送简单邮件");
emailService.sendSimpleEmail(emailSend);
return Result.success();
}
@Operation(summary = "发送带附件邮件", description = "发送带附件邮件")
@PostMapping("send-attachment")
public Result<String> sendAttachment(@RequestBody MultipartFile file, String emailSend) {
log.info("发送带附件邮件");
EmailSend send = JSON.parseObject(emailSend, EmailSend.class);
boolean isSuccess = emailService.sendAttachmentEmail(send, file);
return isSuccess ? Result.success() : Result.error();
}
@Operation(summary = "发送富文本邮件", description = "发送富文本邮件")
@PostMapping("send-rich")
public Result<String> sendRich(@RequestBody EmailSend emailSend) {
log.info("发送富文本邮件");
boolean isSuccess = emailService.sendRich(emailSend);
return isSuccess ? Result.success() : Result.error();
}
@Operation(summary = "发送带抄送的邮件", description = "发送带抄送的邮件")
@PostMapping("send-cc")
public Result<String> sendCC(@RequestBody EmailSend emailSend) {
log.info("发送带抄送的邮件");
boolean isSuccess = emailService.sendCC(emailSend);
return isSuccess ? Result.success() : Result.error();
}
}

View File

@ -1,6 +1,6 @@
package cn.bunny.service.mapper;
import cn.bunny.service.Bunny.SysMenu;
import cn.bunny.entity.system.SysMenu;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
/**

View File

@ -0,0 +1,38 @@
package cn.bunny.service.service;
import cn.bunny.entity.email.EmailSend;
import org.springframework.web.multipart.MultipartFile;
public interface EmailService {
/**
* 发送邮件-简单
*
* @param emailSend 邮件消息
*/
void sendSimpleEmail(EmailSend emailSend);
/**
* 发送带附件邮件
*
* @param emailSend 邮件消息
* @return 是否成功
*/
boolean sendAttachmentEmail(EmailSend emailSend, MultipartFile file);
/**
* 发送富文本邮件
*
* @param emailSend 邮件消息
* @return 是否成功
*/
boolean sendRich(EmailSend emailSend);
/**
* 发送带抄送的邮件
*
* @param emailSend 邮件消息
* @return 是否成功
*/
boolean sendCC(EmailSend emailSend);
}

View File

@ -1,6 +1,6 @@
package cn.bunny.service.service;
import cn.bunny.service.Bunny.SysMenu;
import cn.bunny.entity.system.SysMenu;
import com.baomidou.mybatisplus.extension.service.IService;
/**

View File

@ -0,0 +1,99 @@
package cn.bunny.service.service.impl;
import cn.bunny.common.utils.MailSenderHelper;
import cn.bunny.entity.email.EmailSend;
import cn.bunny.entity.email.EmailSendInit;
import cn.bunny.service.service.EmailService;
import jakarta.mail.MessagingException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
@Service
@Slf4j
public class EmailServiceImpl implements EmailService {
/**
* 发送邮件-简单
*
* @param emailSend 邮件消息
*/
@Override
public void sendSimpleEmail(EmailSend emailSend) {
EmailSendInit emailSendInit = new EmailSendInit();
emailSendInit.setHost("smtp.qq.com");
emailSendInit.setPort(465);
emailSendInit.setUsername("3324855376@qq.com");
emailSendInit.setPassword("axyqbvfuxkdqdaai");
MailSenderHelper mailSenderHelper = new MailSenderHelper(emailSendInit);
mailSenderHelper.sendSimpleEmail(emailSend);
}
/**
* 发送带附件邮件
*
* @param emailSend 邮件消息
* @return 是否成功
*/
@Override
public boolean sendAttachmentEmail(EmailSend emailSend, MultipartFile file) {
try {
EmailSendInit emailSendInit = new EmailSendInit();
emailSendInit.setHost("smtp.qq.com");
emailSendInit.setPort(465);
emailSendInit.setUsername("3324855376@qq.com");
emailSendInit.setPassword("axyqbvfuxkdqdaai");
MailSenderHelper mailSenderHelper = new MailSenderHelper(emailSendInit);
mailSenderHelper.sendAttachmentEmail(emailSend, file, true);
return true;
} catch (MessagingException e) {
return false;
}
}
/**
* 发送富文本邮件
*
* @param emailSend 邮件消息
* @return 是否成功
*/
@Override
public boolean sendRich(EmailSend emailSend) {
try {
EmailSendInit emailSendInit = new EmailSendInit();
emailSendInit.setHost("smtp.qq.com");
emailSendInit.setPort(465);
emailSendInit.setUsername("3324855376@qq.com");
emailSendInit.setPassword("axyqbvfuxkdqdaai");
MailSenderHelper mailSenderHelper = new MailSenderHelper(emailSendInit);
mailSenderHelper.sendRichText(emailSend, true);
return true;
} catch (MessagingException e) {
return false;
}
}
/**
* 发送带抄送的邮件
*
* @param emailSend 邮件消息
*/
@Override
public boolean sendCC(EmailSend emailSend) {
try {
EmailSendInit emailSendInit = new EmailSendInit();
emailSendInit.setHost("smtp.qq.com");
emailSendInit.setPort(465);
emailSendInit.setUsername("3324855376@qq.com");
emailSendInit.setPassword("axyqbvfuxkdqdaai");
MailSenderHelper mailSenderHelper = new MailSenderHelper(emailSendInit);
mailSenderHelper.sendCC(emailSend, true);
return true;
} catch (MessagingException e) {
return false;
}
}
}

View File

@ -1,6 +1,6 @@
package cn.bunny.service.service.impl;
import cn.bunny.service.Bunny.SysMenu;
import cn.bunny.entity.system.SysMenu;
import cn.bunny.service.mapper.SysMenuMapper;
import cn.bunny.service.service.SysMenuService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

View File

@ -35,6 +35,28 @@ spring:
name: user
password: 1
mail:
host: smtp.qq.com # 邮箱地址
port: 465 # 邮箱端口号
username: 3324855376@qq.com # 设置发送邮箱
password: axyqbvfuxkdqdaai # 如果是纯数字要加引号
default-encoding: UTF-8 # 设置编码格式
protocol: smtps
properties:
mail:
debug: true # 是否开启debug模式发送邮件
smtp:
auth: true
connectionTimeout: 5000 # 设置连接延迟
timeout: 5000 # 延迟时间
writeTimeout: 5000 # 写入邮箱延迟
allow8BitMime: true
sendPartial: true
ssl:
enabled: true # 是否开启SSL连接
socketFactory:
class: javax.net.ssl.SSLSocketFactory # 必要设置!!!
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
configuration:

View File

@ -3,20 +3,19 @@
<mapper namespace="cn.bunny.service.mapper.SysMenuMapper">
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="cn.bunny.service.Bunny.SysMenu">
<id column="id" property="id" />
<result column="parent_id" property="parentId" />
<result column="name" property="name" />
<result column="type" property="type" />
<result column="path" property="path" />
<result column="component" property="component" />
<result column="perms" property="perms" />
<result column="icon" property="icon" />
<result column="sort_value" property="sortValue" />
<result column="status" property="status" />
<result column="create_time" property="createTime" />
<result column="update_time" property="updateTime" />
<result column="is_deleted" property="isDeleted" />
<resultMap id="BaseResultMap" type="cn.bunny.entity.system.SysMenu">
<id column="id" property="id"/>
<result column="parent_id" property="parentId"/>
<result column="name" property="name"/>
<result column="type" property="type"/>
<result column="path" property="path"/>
<result column="component" property="component"/>
<result column="perms" property="perms"/>
<result column="icon" property="icon"/>
<result column="status" property="status"/>
<result column="create_time" property="createTime"/>
<result column="update_time" property="updateTime"/>
<result column="is_deleted" property="isDeleted"/>
</resultMap>
<!-- 通用查询结果列 -->