内嵌查询代替LEFT JOIN导致的重复问题以及修改邮件不能发送图片和附件的问题
This commit is contained in:
19
pom.xml
19
pom.xml
@@ -338,12 +338,19 @@
|
||||
<version>${ruoyi-flowable-plus.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- SMS短信模块 -->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-sms</artifactId>
|
||||
<version>${ruoyi-flowable-plus.version}</version>
|
||||
</dependency>
|
||||
<!-- SMS短信模块 -->
|
||||
<dependency>
|
||||
<groupId>com.ruoyi</groupId>
|
||||
<artifactId>ruoyi-sms</artifactId>
|
||||
<version>${ruoyi-flowable-plus.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- 邮件发送相关依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
<version>${spring-boot.version}</version>
|
||||
</dependency>
|
||||
|
||||
<!-- demo模块 -->
|
||||
<dependency>
|
||||
|
||||
@@ -51,6 +51,12 @@
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
|
||||
<!-- 邮件发送相关依赖 -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-mail</artifactId>
|
||||
</dependency>
|
||||
|
||||
</dependencies>
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.ruoyi.oa.config;
|
||||
|
||||
import com.ruoyi.oa.domain.OaEmailAccount;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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;
|
||||
|
||||
/**
|
||||
* 动态邮件配置类
|
||||
* 支持根据不同的邮箱账号动态配置邮件发送器
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Configuration
|
||||
public class DynamicMailConfig {
|
||||
|
||||
/**
|
||||
* 根据邮箱账号创建JavaMailSender
|
||||
*
|
||||
* @param account 邮箱账号信息
|
||||
* @return JavaMailSender
|
||||
*/
|
||||
public JavaMailSender createMailSender(OaEmailAccount account) {
|
||||
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
|
||||
|
||||
// 设置SMTP服务器
|
||||
mailSender.setHost(account.getSmtpHost());
|
||||
mailSender.setPort(account.getSmtpPort() == null ? 465 : account.getSmtpPort().intValue());
|
||||
mailSender.setUsername(account.getEmail());
|
||||
mailSender.setPassword(account.getPassword());
|
||||
|
||||
// 设置邮件属性
|
||||
Properties props = mailSender.getJavaMailProperties();
|
||||
props.put("mail.transport.protocol", "smtp");
|
||||
props.put("mail.smtp.auth", "true");
|
||||
props.put("mail.smtp.starttls.enable", "true");
|
||||
props.put("mail.smtp.ssl.enable", "true");
|
||||
props.put("mail.smtp.connectiontimeout", "10000");
|
||||
props.put("mail.smtp.timeout", "10000");
|
||||
props.put("mail.smtp.writetimeout", "10000");
|
||||
props.put("mail.debug", "false");
|
||||
|
||||
return mailSender;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据邮箱类型获取默认配置
|
||||
*
|
||||
* @param type 邮箱类型 0=网易 1=QQ 2=阿里云 3=飞书
|
||||
* @return 默认配置
|
||||
*/
|
||||
public OaEmailAccount getDefaultConfig(int type) {
|
||||
OaEmailAccount config = new OaEmailAccount();
|
||||
|
||||
switch (type) {
|
||||
case 0: // 网易邮箱
|
||||
config.setSmtpHost("smtp.163.com");
|
||||
config.setSmtpPort(465L);
|
||||
break;
|
||||
case 1: // QQ邮箱
|
||||
config.setSmtpHost("smtp.qq.com");
|
||||
config.setSmtpPort(465L);
|
||||
break;
|
||||
case 2: // 阿里云邮箱
|
||||
config.setSmtpHost("smtp.aliyun.com");
|
||||
config.setSmtpPort(465L);
|
||||
break;
|
||||
case 3: // 飞书邮箱
|
||||
config.setSmtpHost("smtp.feishu.cn");
|
||||
config.setSmtpPort(465L);
|
||||
break;
|
||||
default:
|
||||
config.setSmtpHost("smtp.163.com");
|
||||
config.setSmtpPort(465L);
|
||||
break;
|
||||
}
|
||||
|
||||
return config;
|
||||
}
|
||||
}
|
||||
@@ -16,4 +16,8 @@ public class EmailSendRequest {
|
||||
private String subject;
|
||||
/** 邮件正文 */
|
||||
private String content;
|
||||
/** 附件文件路径列表 */
|
||||
private List<String> attachmentPaths;
|
||||
/** 内嵌图片路径列表 */
|
||||
private List<String> inlineImagePaths;
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import com.ruoyi.oa.domain.SysOaTask;
|
||||
import com.ruoyi.oa.domain.UserMonthlyData;
|
||||
import com.ruoyi.oa.domain.bo.SysOaTaskBo;
|
||||
import com.ruoyi.oa.domain.vo.SysOaTaskVo;
|
||||
import com.ruoyi.oa.domain.vo.SysOaTaskItemVo;
|
||||
import com.ruoyi.common.core.mapper.BaseMapperPlus;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
@@ -50,4 +51,9 @@ public interface SysOaTaskMapper extends BaseMapperPlus<SysOaTaskMapper, SysOaTa
|
||||
*/
|
||||
List<SysOaTaskVo> queryListPlus(SysOaTaskBo bo);
|
||||
|
||||
/**
|
||||
* 嵌套查询:根据任务ID获取报工单元列表
|
||||
*/
|
||||
List<SysOaTaskItemVo> selectTaskItemsByTaskId(Long taskId);
|
||||
|
||||
}
|
||||
|
||||
@@ -26,8 +26,8 @@ import com.ruoyi.oa.domain.OaEmailAccount;
|
||||
import com.ruoyi.oa.mapper.OaEmailAccountMapper;
|
||||
import com.ruoyi.oa.service.IOaEmailAccountService;
|
||||
import com.ruoyi.oa.domain.request.EmailSendRequest;
|
||||
import cn.hutool.extra.mail.MailAccount;
|
||||
import cn.hutool.extra.mail.MailUtil;
|
||||
import com.ruoyi.oa.utils.EmailUtil;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.List;
|
||||
@@ -45,6 +45,9 @@ import java.util.Collection;
|
||||
public class OaEmailAccountServiceImpl implements IOaEmailAccountService {
|
||||
|
||||
private final OaEmailAccountMapper baseMapper;
|
||||
|
||||
@Autowired
|
||||
private EmailUtil emailUtil;
|
||||
|
||||
/**
|
||||
* 查询发件人邮箱账号管理
|
||||
@@ -138,26 +141,60 @@ public class OaEmailAccountServiceImpl implements IOaEmailAccountService {
|
||||
int success = 0, fail = 0;
|
||||
StringBuilder failList = new StringBuilder();
|
||||
|
||||
if (type == 0 || type == 1) {
|
||||
// 网易/QQ邮箱 SMTP方式(已实现)
|
||||
MailAccount mailAccount = new MailAccount();
|
||||
mailAccount.setHost(account.getSmtpHost());
|
||||
mailAccount.setPort(account.getSmtpPort() == null ? 465 : account.getSmtpPort().intValue());
|
||||
mailAccount.setAuth(true);
|
||||
mailAccount.setFrom(account.getEmail());
|
||||
mailAccount.setUser(account.getEmail());
|
||||
mailAccount.setPass(account.getPassword());
|
||||
mailAccount.setSslEnable(true);
|
||||
if (type == 0 || type == 1) {
|
||||
// 网易/QQ邮箱 SMTP方式
|
||||
for (String to : request.getToList()) {
|
||||
try {
|
||||
MailUtil.send(mailAccount, to, request.getSubject(), request.getContent(), false);
|
||||
// 判断是否为HTML内容
|
||||
boolean isHtml = request.getContent() != null &&
|
||||
(request.getContent().contains("<html") ||
|
||||
request.getContent().contains("<div") ||
|
||||
request.getContent().contains("<p>"));
|
||||
|
||||
// 检查是否有附件
|
||||
boolean hasAttachments = request.getAttachmentPaths() != null && !request.getAttachmentPaths().isEmpty();
|
||||
// 检查是否有内嵌图片
|
||||
boolean hasInlineImages = request.getInlineImagePaths() != null && !request.getInlineImagePaths().isEmpty();
|
||||
|
||||
if (hasAttachments && hasInlineImages) {
|
||||
// 既有附件又有内嵌图片
|
||||
if (isHtml) {
|
||||
String processedContent = emailUtil.processHtmlWithInlineImages(request.getContent(), request.getInlineImagePaths());
|
||||
emailUtil.sendHtmlMailWithAttachmentsAndDynamicConfig(account, to, request.getSubject(), processedContent, request.getAttachmentPaths());
|
||||
} else {
|
||||
// 纯文本不支持内嵌图片,只发送附件
|
||||
emailUtil.sendMailWithAttachmentAndDynamicConfig(account, to, request.getSubject(), request.getContent(), request.getAttachmentPaths().get(0));
|
||||
}
|
||||
} else if (hasAttachments) {
|
||||
// 只有附件
|
||||
if (isHtml) {
|
||||
emailUtil.sendHtmlMailWithAttachmentsAndDynamicConfig(account, to, request.getSubject(), request.getContent(), request.getAttachmentPaths());
|
||||
} else {
|
||||
emailUtil.sendMailWithAttachmentAndDynamicConfig(account, to, request.getSubject(), request.getContent(), request.getAttachmentPaths().get(0));
|
||||
}
|
||||
} else if (hasInlineImages) {
|
||||
// 只有内嵌图片
|
||||
if (isHtml) {
|
||||
emailUtil.sendHtmlMailWithInlineImagesAndDynamicConfig(account, to, request.getSubject(), request.getContent(), request.getInlineImagePaths());
|
||||
} else {
|
||||
// 纯文本不支持内嵌图片
|
||||
emailUtil.sendMailWithDynamicConfig(account, to, request.getSubject(), request.getContent());
|
||||
}
|
||||
} else {
|
||||
// 无附件无内嵌图片
|
||||
if (isHtml) {
|
||||
emailUtil.sendHtmlMailWithDynamicConfig(account, to, request.getSubject(), request.getContent());
|
||||
} else {
|
||||
emailUtil.sendMailWithDynamicConfig(account, to, request.getSubject(), request.getContent());
|
||||
}
|
||||
}
|
||||
success++;
|
||||
} catch (Exception e) {
|
||||
fail++;
|
||||
failList.append(to).append(", ");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == 2) {
|
||||
// 阿里云邮件推送API
|
||||
for (String to : request.getToList()) {
|
||||
|
||||
358
ruoyi-oa/src/main/java/com/ruoyi/oa/utils/EmailUtil.java
Normal file
358
ruoyi-oa/src/main/java/com/ruoyi/oa/utils/EmailUtil.java
Normal file
@@ -0,0 +1,358 @@
|
||||
package com.ruoyi.oa.utils;
|
||||
|
||||
import com.ruoyi.oa.domain.OaEmailAccount;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.mail.SimpleMailMessage;
|
||||
import org.springframework.mail.javamail.JavaMailSender;
|
||||
import org.springframework.mail.javamail.MimeMessageHelper;
|
||||
import org.springframework.stereotype.Component;
|
||||
import com.ruoyi.oa.config.DynamicMailConfig;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 邮件发送工具类
|
||||
*
|
||||
* @author ruoyi
|
||||
*/
|
||||
@Component
|
||||
public class EmailUtil {
|
||||
|
||||
@Autowired
|
||||
private JavaMailSender javaMailSender;
|
||||
|
||||
@Autowired
|
||||
private DynamicMailConfig dynamicMailConfig;
|
||||
|
||||
/**
|
||||
* 发送纯文本邮件
|
||||
*
|
||||
* @param from 发件人邮箱
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param text 纯文本内容
|
||||
*/
|
||||
public void sendMail(String from, String to, String subject, String text) {
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setFrom(from);
|
||||
message.setTo(to);
|
||||
message.setSubject(subject);
|
||||
message.setText(text);
|
||||
javaMailSender.send(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用动态配置发送纯文本邮件
|
||||
*
|
||||
* @param account 邮箱账号信息
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param text 纯文本内容
|
||||
*/
|
||||
public void sendMailWithDynamicConfig(OaEmailAccount account, String to, String subject, String text) {
|
||||
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setFrom(account.getEmail());
|
||||
message.setTo(to);
|
||||
message.setSubject(subject);
|
||||
message.setText(text);
|
||||
dynamicMailSender.send(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送纯文本邮件(批量)
|
||||
*
|
||||
* @param from 发件人邮箱
|
||||
* @param toList 收件人邮箱列表
|
||||
* @param subject 邮件主题
|
||||
* @param text 纯文本内容
|
||||
*/
|
||||
public void sendMailBatch(String from, List<String> toList, String subject, String text) {
|
||||
SimpleMailMessage message = new SimpleMailMessage();
|
||||
message.setFrom(from);
|
||||
message.setTo(toList.toArray(new String[0]));
|
||||
message.setSubject(subject);
|
||||
message.setText(text);
|
||||
javaMailSender.send(message);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送富文本邮件
|
||||
*
|
||||
* @param from 发件人邮箱
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param htmlContent HTML内容
|
||||
*/
|
||||
public void sendHtmlMail(String from, String to, String subject, String htmlContent) throws MessagingException {
|
||||
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
|
||||
helper.setFrom(from);
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(htmlContent, true); // 第二个参数true表示这是HTML内容
|
||||
javaMailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用动态配置发送富文本邮件
|
||||
*
|
||||
* @param account 邮箱账号信息
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param htmlContent HTML内容
|
||||
*/
|
||||
public void sendHtmlMailWithDynamicConfig(com.ruoyi.oa.domain.OaEmailAccount account, String to, String subject, String htmlContent) throws MessagingException {
|
||||
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
|
||||
MimeMessage mimeMessage = dynamicMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
|
||||
helper.setFrom(account.getEmail());
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(htmlContent, true);
|
||||
dynamicMailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送富文本邮件(批量)
|
||||
*
|
||||
* @param from 发件人邮箱
|
||||
* @param toList 收件人邮箱列表
|
||||
* @param subject 邮件主题
|
||||
* @param htmlContent HTML内容
|
||||
*/
|
||||
public void sendHtmlMailBatch(String from, List<String> toList, String subject, String htmlContent) throws MessagingException {
|
||||
for (String to : toList) {
|
||||
sendHtmlMail(from, to, subject, htmlContent);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送带附件的邮件
|
||||
*
|
||||
* @param from 发件人邮箱
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param text 邮件内容
|
||||
* @param filePath 附件文件路径
|
||||
*/
|
||||
public void sendMailWithAttachment(String from, String to, String subject, String text, String filePath) throws MessagingException {
|
||||
File attachment = new File(filePath);
|
||||
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
|
||||
helper.setFrom(from);
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(text);
|
||||
helper.addAttachment(attachment.getName(), attachment);
|
||||
javaMailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用动态配置发送带附件的邮件
|
||||
*
|
||||
* @param account 邮箱账号信息
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param text 邮件内容
|
||||
* @param filePath 附件文件路径
|
||||
*/
|
||||
public void sendMailWithAttachmentAndDynamicConfig(com.ruoyi.oa.domain.OaEmailAccount account, String to, String subject, String text, String filePath) throws MessagingException {
|
||||
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
|
||||
File attachment = new File(filePath);
|
||||
MimeMessage mimeMessage = dynamicMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
|
||||
helper.setFrom(account.getEmail());
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(text);
|
||||
helper.addAttachment(attachment.getName(), attachment);
|
||||
dynamicMailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送带附件的富文本邮件
|
||||
*
|
||||
* @param from 发件人邮箱
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param htmlContent HTML内容
|
||||
* @param filePath 附件文件路径
|
||||
*/
|
||||
public void sendHtmlMailWithAttachment(String from, String to, String subject, String htmlContent, String filePath) throws MessagingException {
|
||||
File attachment = new File(filePath);
|
||||
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
|
||||
helper.setFrom(from);
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(htmlContent, true);
|
||||
helper.addAttachment(attachment.getName(), attachment);
|
||||
javaMailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用动态配置发送带附件的富文本邮件
|
||||
*
|
||||
* @param account 邮箱账号信息
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param htmlContent HTML内容
|
||||
* @param filePath 附件文件路径
|
||||
*/
|
||||
public void sendHtmlMailWithAttachmentAndDynamicConfig(com.ruoyi.oa.domain.OaEmailAccount account, String to, String subject, String htmlContent, String filePath) throws MessagingException {
|
||||
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
|
||||
File attachment = new File(filePath);
|
||||
MimeMessage mimeMessage = dynamicMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
|
||||
helper.setFrom(account.getEmail());
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(htmlContent, true);
|
||||
helper.addAttachment(attachment.getName(), attachment);
|
||||
dynamicMailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送带多个附件的邮件
|
||||
*
|
||||
* @param from 发件人邮箱
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param htmlContent HTML内容
|
||||
* @param filePaths 附件文件路径列表
|
||||
*/
|
||||
public void sendHtmlMailWithAttachments(String from, String to, String subject, String htmlContent, List<String> filePaths) throws MessagingException {
|
||||
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
|
||||
helper.setFrom(from);
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(htmlContent, true);
|
||||
|
||||
for (String filePath : filePaths) {
|
||||
File attachment = new File(filePath);
|
||||
if (attachment.exists()) {
|
||||
helper.addAttachment(attachment.getName(), attachment);
|
||||
}
|
||||
}
|
||||
|
||||
javaMailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用动态配置发送带多个附件的邮件
|
||||
*
|
||||
* @param account 邮箱账号信息
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param htmlContent HTML内容
|
||||
* @param filePaths 附件文件路径列表
|
||||
*/
|
||||
public void sendHtmlMailWithAttachmentsAndDynamicConfig(com.ruoyi.oa.domain.OaEmailAccount account, String to, String subject, String htmlContent, List<String> filePaths) throws MessagingException {
|
||||
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
|
||||
MimeMessage mimeMessage = dynamicMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
|
||||
helper.setFrom(account.getEmail());
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(htmlContent, true);
|
||||
|
||||
for (String filePath : filePaths) {
|
||||
File attachment = new File(filePath);
|
||||
if (attachment.exists()) {
|
||||
helper.addAttachment(attachment.getName(), attachment);
|
||||
}
|
||||
}
|
||||
|
||||
dynamicMailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送带内嵌图片的邮件
|
||||
*
|
||||
* @param from 发件人邮箱
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param htmlContent HTML内容(包含cid:xxx的图片引用)
|
||||
* @param imagePaths 内嵌图片路径列表
|
||||
*/
|
||||
public void sendHtmlMailWithInlineImages(String from, String to, String subject, String htmlContent, List<String> imagePaths) throws MessagingException {
|
||||
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
|
||||
helper.setFrom(from);
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(htmlContent, true);
|
||||
|
||||
for (int i = 0; i < imagePaths.size(); i++) {
|
||||
String imagePath = imagePaths.get(i);
|
||||
File imageFile = new File(imagePath);
|
||||
if (imageFile.exists()) {
|
||||
String cid = "image" + i;
|
||||
helper.addInline(cid, imageFile);
|
||||
}
|
||||
}
|
||||
|
||||
javaMailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用动态配置发送带内嵌图片的邮件
|
||||
*
|
||||
* @param account 邮箱账号信息
|
||||
* @param to 收件人邮箱
|
||||
* @param subject 邮件主题
|
||||
* @param htmlContent HTML内容(包含cid:xxx的图片引用)
|
||||
* @param imagePaths 内嵌图片路径列表
|
||||
*/
|
||||
public void sendHtmlMailWithInlineImagesAndDynamicConfig(OaEmailAccount account, String to, String subject, String htmlContent, List<String> imagePaths) throws MessagingException {
|
||||
JavaMailSender dynamicMailSender = dynamicMailConfig.createMailSender(account);
|
||||
MimeMessage mimeMessage = dynamicMailSender.createMimeMessage();
|
||||
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8");
|
||||
helper.setFrom(account.getEmail());
|
||||
helper.setTo(to);
|
||||
helper.setSubject(subject);
|
||||
helper.setText(htmlContent, true);
|
||||
|
||||
for (int i = 0; i < imagePaths.size(); i++) {
|
||||
String imagePath = imagePaths.get(i);
|
||||
File imageFile = new File(imagePath);
|
||||
if (imageFile.exists()) {
|
||||
String cid = "image" + i;
|
||||
helper.addInline(cid, imageFile);
|
||||
}
|
||||
}
|
||||
|
||||
dynamicMailSender.send(mimeMessage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理HTML内容中的图片,将外链图片转为内嵌
|
||||
*
|
||||
* @param htmlContent 原始HTML内容
|
||||
* @param imagePaths 图片路径列表
|
||||
* @return 处理后的HTML内容
|
||||
*/
|
||||
public String processHtmlWithInlineImages(String htmlContent, List<String> imagePaths) {
|
||||
if (imagePaths == null || imagePaths.isEmpty()) {
|
||||
return htmlContent;
|
||||
}
|
||||
|
||||
String processedHtml = htmlContent;
|
||||
for (int i = 0; i < imagePaths.size(); i++) {
|
||||
String imagePath = imagePaths.get(i);
|
||||
String cid = "image" + i;
|
||||
// 这里可以根据需要替换图片URL为cid引用
|
||||
// 例如:将 <img src="path/to/image.jpg"> 替换为 <img src="cid:image0">
|
||||
processedHtml = processedHtml.replace("image" + i + ".jpg", "cid:" + cid);
|
||||
processedHtml = processedHtml.replace("image" + i + ".png", "cid:" + cid);
|
||||
}
|
||||
|
||||
return processedHtml;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="content" column="content"/>
|
||||
<result property="remark" column="remark"/>
|
||||
<result property="state" column="state"/>
|
||||
<result property="status" column="status"/>
|
||||
<result property="taskRank" column="task_rank"/>
|
||||
<result property="ownRank" column="own_rank"/>
|
||||
<result property="timeGap" column="time_gap"/>
|
||||
<result property="tempTime" column="temp_time"/>
|
||||
<result property="createBy" column="create_by"/>
|
||||
<result property="createTime" column="create_time"/>
|
||||
<result property="completedTime" column="completed_time"/>
|
||||
@@ -23,20 +28,17 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<result property="workerNickName" column="workerNickName"/>
|
||||
<result property="postponements" column="postponements"/>
|
||||
<result property="accessory" column="accessory"/>
|
||||
<result property="projectName" column="project_name"/>
|
||||
<result property="projectNum" column="project_num"/>
|
||||
<result property="overDays" column="overDays"/>
|
||||
<result property="itemId" column="item_id"/>
|
||||
<result property="files" column="files"/>
|
||||
|
||||
<collection property="taskItemVoList" ofType="com.ruoyi.oa.domain.vo.SysOaTaskItemVo" javaType="list">
|
||||
<result property="itemId" column="item_id"/>
|
||||
<result property="content" column="itemContent"/>
|
||||
<result property="signTime" column="sign_time"/>
|
||||
<result property="status" column="itemStatus"/>
|
||||
<result property="beginTime" column="itemBeginTime"/>
|
||||
<result property="endTime" column="itemEndTime"/>
|
||||
<result property="remark" column="itemRemark"/>
|
||||
<result property="completedTime" column="itemCompletedTime"/>
|
||||
<result property="files" column="files"/>
|
||||
|
||||
|
||||
</collection>
|
||||
<collection property="taskItemVoList"
|
||||
ofType="com.ruoyi.oa.domain.vo.SysOaTaskItemVo"
|
||||
javaType="list"
|
||||
select="selectTaskItemsByTaskId"
|
||||
column="task_id"/>
|
||||
</resultMap>
|
||||
|
||||
|
||||
@@ -57,27 +59,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
sot.task_type,
|
||||
sot.task_grade,
|
||||
sot.collaborator,
|
||||
COALESCE(sot.finish_time, soti.end_time) AS finish_time,
|
||||
COALESCE(sot.temp_time, soti.temp_time) AS temp_time,
|
||||
sot.finish_time,
|
||||
sot.temp_time,
|
||||
sot.begin_time,
|
||||
sot.origin_finish_time,
|
||||
sot.postponements,
|
||||
sot.completed_time,
|
||||
CASE
|
||||
WHEN sot.completed_time IS NULL
|
||||
THEN DATEDIFF(
|
||||
NOW(),
|
||||
COALESCE(
|
||||
sot.finish_time,
|
||||
(SELECT a.end_time
|
||||
FROM sys_oa_task_item a
|
||||
WHERE a.task_id = sot.task_id
|
||||
AND a.completed_time IS NULL
|
||||
LIMIT 1)
|
||||
)
|
||||
)
|
||||
ELSE 0
|
||||
END AS overDays,
|
||||
sot.rank_number,
|
||||
sot.remark,
|
||||
sot.task_rank,
|
||||
@@ -91,7 +78,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
sot.del_flag,
|
||||
sot.own_rank,
|
||||
sop.project_name,
|
||||
soti.item_id,
|
||||
sop.project_num,
|
||||
su1.nick_name AS createUserNickName,
|
||||
su2.nick_name AS workerNickName
|
||||
@@ -99,12 +85,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
LEFT JOIN sys_user su1 ON su1.user_id = sot.create_user_id
|
||||
LEFT JOIN sys_user su2 ON su2.user_id = sot.worker_id
|
||||
LEFT JOIN sys_oa_project sop ON sop.project_id = sot.project_id
|
||||
LEFT JOIN sys_oa_task_item soti
|
||||
ON soti.task_id = sot.task_id
|
||||
AND soti.completed_time IS NULL
|
||||
|
||||
${ew.getCustomSqlSegment}
|
||||
|
||||
</select>
|
||||
|
||||
|
||||
@@ -116,7 +97,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
sot.task_title,
|
||||
sot.task_type,
|
||||
sot.task_grade,
|
||||
sot.accessory,
|
||||
sot.accessory,
|
||||
COALESCE(
|
||||
sot.finish_time,
|
||||
(SELECT a.end_time
|
||||
@@ -142,7 +123,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
su1.nick_name AS createUserNickName,
|
||||
su2.nick_name AS workerNickName,
|
||||
|
||||
|
||||
sot.rank_number,
|
||||
sot.remark,
|
||||
sot.task_rank,
|
||||
@@ -158,14 +138,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
sop.project_name,
|
||||
sop.project_num,
|
||||
|
||||
soti.item_id,
|
||||
soti.content AS itemContent,
|
||||
soti.sign_time,
|
||||
soti.status AS itemStatus,
|
||||
soti.begin_time AS itemBeginTime,
|
||||
soti.completed_time AS itemCompletedTime,
|
||||
soti.end_time AS itemEndTime,
|
||||
soti.remark AS itemRemark,
|
||||
CASE
|
||||
WHEN sot.completed_time IS NULL
|
||||
THEN DATEDIFF(
|
||||
@@ -180,19 +152,30 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
)
|
||||
)
|
||||
ELSE 0
|
||||
END AS overDays,
|
||||
soti.files
|
||||
END AS overDays
|
||||
FROM sys_oa_task sot
|
||||
LEFT JOIN sys_user su1
|
||||
ON su1.user_id = sot.create_user_id
|
||||
LEFT JOIN sys_user su1 ON su1.user_id = sot.create_user_id
|
||||
LEFT JOIN sys_user su2 ON su2.user_id = sot.worker_id
|
||||
LEFT JOIN sys_oa_project sop ON sop.project_id = sot.project_id
|
||||
LEFT JOIN sys_oa_task_item soti ON soti.task_id = sot.task_id
|
||||
LEFT JOIN sys_oss so2 ON FIND_IN_SET(so2.oss_id, soti.files)
|
||||
WHERE
|
||||
sot.task_id = #{taskId}
|
||||
WHERE sot.task_id = #{taskId}
|
||||
AND sot.del_flag = '0'
|
||||
</select>
|
||||
|
||||
<!-- 嵌套查询:根据任务ID获取报工单元列表 -->
|
||||
<select id="selectTaskItemsByTaskId" resultType="com.ruoyi.oa.domain.vo.SysOaTaskItemVo">
|
||||
SELECT soti.item_id,
|
||||
soti.content,
|
||||
soti.sign_time,
|
||||
soti.status,
|
||||
soti.begin_time,
|
||||
soti.completed_time,
|
||||
soti.end_time,
|
||||
soti.remark,
|
||||
soti.files
|
||||
FROM sys_oa_task_item soti
|
||||
WHERE soti.task_id = #{task_id}
|
||||
AND soti.del_flag = '0'
|
||||
ORDER BY soti.create_time DESC
|
||||
</select>
|
||||
|
||||
<select id="getMonthlyData"
|
||||
|
||||
Reference in New Issue
Block a user