|
|
@@ -0,0 +1,1067 @@
|
|
|
+package com.storlead.mail;
|
|
|
+
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+
|
|
|
+import com.storlead.framework.common.util.RandomGenerateHelper;
|
|
|
+import com.storlead.framework.common.util.encryptor.AccessKeyEncryptor;
|
|
|
+import com.storlead.framework.util.LoginUserUtil;
|
|
|
+import com.storlead.framework.common.constant.CommonConstant;
|
|
|
+import com.storlead.framework.common.result.Result;
|
|
|
+import com.storlead.sales.mail.entity.*;
|
|
|
+import com.storlead.sales.mail.enums.EmailBoxEnum;
|
|
|
+import com.storlead.sales.mail.enums.SendStatus;
|
|
|
+import com.storlead.sales.mail.pojo.*;
|
|
|
+import com.storlead.sales.mail.properties.MailFileProperties;
|
|
|
+import com.storlead.sales.mail.service.*;
|
|
|
+import com.storlead.sales.mail.util.FileHelper;
|
|
|
+import com.storlead.sales.mail.util.ZipUtility;
|
|
|
+import io.swagger.annotations.Api;
|
|
|
+import io.swagger.annotations.ApiOperation;
|
|
|
+import io.swagger.annotations.ApiResponse;
|
|
|
+import io.swagger.annotations.ApiResponses;
|
|
|
+import lombok.extern.log4j.Log4j2;
|
|
|
+import ma.glasnost.orika.impl.DefaultMapperFactory;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.core.env.Environment;
|
|
|
+import org.springframework.util.CollectionUtils;
|
|
|
+import org.springframework.util.ObjectUtils;
|
|
|
+import org.springframework.util.StringUtils;
|
|
|
+import org.springframework.web.bind.annotation.*;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import javax.activation.DataHandler;
|
|
|
+import javax.activation.DataSource;
|
|
|
+import javax.activation.FileDataSource;
|
|
|
+import javax.annotation.Resource;
|
|
|
+import javax.mail.*;
|
|
|
+import javax.mail.internet.*;
|
|
|
+import javax.servlet.ServletOutputStream;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.*;
|
|
|
+import java.net.URLEncoder;
|
|
|
+import java.nio.file.Files;
|
|
|
+import java.nio.file.Path;
|
|
|
+import java.nio.file.Paths;
|
|
|
+import java.nio.file.StandardCopyOption;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @program: sp-sales-platform
|
|
|
+ * @description:
|
|
|
+ * @author: chenkq
|
|
|
+ * @create: 2024-05-29 16:02
|
|
|
+ */
|
|
|
+@RestController
|
|
|
+@RequestMapping("/mail")
|
|
|
+@Api(tags = "020.邮件管理相关接口")
|
|
|
+@Log4j2
|
|
|
+public class MailApiController {
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private EmailsService emailsService;
|
|
|
+ @Resource
|
|
|
+ private MailFileProperties mailFileProperties;
|
|
|
+ @Resource
|
|
|
+ private MailAttachmentService mailAttachmentService;
|
|
|
+ @Resource
|
|
|
+ private SmtpPopSettingsService smtpPopSettingsService;
|
|
|
+ @Resource
|
|
|
+ private MailServerPortConfigService serverPortConfigService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private MailTempAttachmentService tempAttachmentService;
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private UserMailTrackRecordService mailTrackRecordService;
|
|
|
+
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private Environment environment;
|
|
|
+
|
|
|
+ @PostMapping(value = "/send_mail")
|
|
|
+ @ApiOperation(value = "发送邮件")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result<?> sendMail(SendMailDTO dto) {
|
|
|
+
|
|
|
+ Long currentUserId = LoginUserUtil.getCurrentUserId();
|
|
|
+ SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
|
|
|
+ AccessKeyEncryptor accessKeyEncryptor = AccessKeyEncryptor.getAccessKeyEncryptor("");
|
|
|
+ String pass = accessKeyEncryptor.decrypt(smtpPop.getEmailPassword());
|
|
|
+ smtpPop.setEmailPassword(pass);
|
|
|
+ if (Objects.isNull(currentUserId) && Objects.nonNull(smtpPop)) {
|
|
|
+ return Result.result(null);
|
|
|
+ }
|
|
|
+ SendStatus result = emailsService.sendEmail(dto, smtpPop);
|
|
|
+ if (result.code == SendStatus.SUCCESS.code || result.code == SendStatus.PARTIAL_SUCCESS.code) {
|
|
|
+ return Result.ok();
|
|
|
+ } else {
|
|
|
+ return Result.error(result.getDesc());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/asyn_send_mail")
|
|
|
+ @ApiOperation(value = "发送邮件")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result<?> asynSendMail(SendMailDTO dto) {
|
|
|
+
|
|
|
+ Long currentUserId = LoginUserUtil.getCurrentUserId();
|
|
|
+ SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
|
|
|
+ AccessKeyEncryptor accessKeyEncryptor = AccessKeyEncryptor.getAccessKeyEncryptor("");
|
|
|
+ String pass = accessKeyEncryptor.decrypt(smtpPop.getEmailPassword());
|
|
|
+ smtpPop.setEmailPassword(pass);
|
|
|
+ if (Objects.isNull(currentUserId) && Objects.nonNull(smtpPop)) {
|
|
|
+ return Result.result(null);
|
|
|
+ }
|
|
|
+ emailsService.sendEmail(dto, smtpPop);
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/save_draft")
|
|
|
+ @ApiOperation(value = "保存草稿")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result<?> saveDraft(SendMailDTO dto) {
|
|
|
+ Long currentUserId = LoginUserUtil.getCurrentUserId();
|
|
|
+ SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
|
|
|
+ if (Objects.isNull(currentUserId) || Objects.isNull(smtpPop)) {
|
|
|
+ return Result.error("请先设置邮箱账号!");
|
|
|
+ }
|
|
|
+ EmailsEntity entity = new EmailsEntity();
|
|
|
+ if (!CollectionUtils.isEmpty(dto.getRecipientls())) {
|
|
|
+ entity.setRecipient(org.apache.commons.lang3.StringUtils.join(dto.getRecipientls(), ","));
|
|
|
+ }
|
|
|
+ if (!CollectionUtils.isEmpty(dto.getRecipientCcls())) {
|
|
|
+ entity.setRecipientCc(org.apache.commons.lang3.StringUtils.join(dto.getRecipientCcls(), ","));
|
|
|
+ }
|
|
|
+ if (!CollectionUtils.isEmpty(dto.getRecipientBccls())) {
|
|
|
+ entity.setRecipientBcc(org.apache.commons.lang3.StringUtils.join(dto.getRecipientBccls(), ","));
|
|
|
+ }
|
|
|
+ if (Objects.nonNull(dto.getId())) {
|
|
|
+ entity.setId(dto.getId());
|
|
|
+ }
|
|
|
+
|
|
|
+ entity.setSubject(dto.getSubject());
|
|
|
+ entity.setContent(dto.getContent());
|
|
|
+ entity.setReplyMsgId(dto.getReplyMsgId());
|
|
|
+ entity.setOwnerBy(currentUserId);
|
|
|
+ entity.setSmtpPopId(smtpPop.getId());
|
|
|
+ entity.setFolder(EmailBoxEnum.DRAFT.code);
|
|
|
+ entity.setEmailSize(Long.valueOf(entity.getContent().length()));
|
|
|
+
|
|
|
+ emailsService.saveOrUpdate(entity);
|
|
|
+ if (!CollectionUtils.isEmpty(dto.getFileIds())) {
|
|
|
+ LambdaUpdateWrapper<MailTempAttachmentEntity> fileWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ fileWrapper.set(MailTempAttachmentEntity::getEmailId, entity.getId());
|
|
|
+ fileWrapper.in(MailTempAttachmentEntity::getId, dto.getFileIds());
|
|
|
+ tempAttachmentService.update(fileWrapper);
|
|
|
+ }
|
|
|
+ if (!CollectionUtils.isEmpty(dto.getOldfileIds())) {
|
|
|
+ LambdaUpdateWrapper<MailAttachmentEntity> fileWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ fileWrapper.in(MailAttachmentEntity::getId, dto.getOldfileIds());
|
|
|
+ List<MailAttachmentEntity> mailAttachments = mailAttachmentService.list(fileWrapper);
|
|
|
+ if (!CollectionUtils.isEmpty(mailAttachments)) {
|
|
|
+ List<MailTempAttachmentEntity> files = new ArrayList<>();
|
|
|
+ for(MailAttachmentEntity attachment : mailAttachments) {
|
|
|
+ MailTempAttachmentEntity tempAttachment = new MailTempAttachmentEntity();
|
|
|
+ BeanUtils.copyProperties(attachment,tempAttachment);
|
|
|
+ tempAttachment.setId(entity.getId());
|
|
|
+ tempAttachment.setOwnerBy(entity.getOwnerBy());
|
|
|
+ files.add(tempAttachment);
|
|
|
+ }
|
|
|
+ if (!CollectionUtils.isEmpty(files)) {
|
|
|
+ tempAttachmentService.saveBatch(files);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/receive_mail")
|
|
|
+ @ApiOperation(value = "接收邮件")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result<?> receiveMail() {
|
|
|
+ Long currentUserId = LoginUserUtil.getCurrentUserId();
|
|
|
+ SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
|
|
|
+ if (Objects.isNull(currentUserId) || Objects.isNull(smtpPop)) {
|
|
|
+ return Result.error("请先设置邮箱账号!");
|
|
|
+ }
|
|
|
+ AccessKeyEncryptor accessKeyEncryptor = AccessKeyEncryptor.getAccessKeyEncryptor("");
|
|
|
+ String pass = accessKeyEncryptor.decrypt(smtpPop.getEmailPassword());
|
|
|
+ smtpPop.setEmailPassword(pass);
|
|
|
+ emailsService.receiveEmails(smtpPop);
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/download_mail_eml_zip")
|
|
|
+ @ApiOperation(value = "下载邮件")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public void downloadMailEmlZip(MailDTO dto, HttpServletResponse response) throws MessagingException {
|
|
|
+ Long currentUserId = LoginUserUtil.getCurrentUserId();
|
|
|
+
|
|
|
+ if (CollectionUtils.isEmpty(dto.getMailIds())) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ List<EmailsEntity> entities = emailsService.list(new LambdaQueryWrapper<EmailsEntity>().in(EmailsEntity::getId, dto.getMailIds()));
|
|
|
+ if (CollectionUtils.isEmpty(entities)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String zipFilePath = mailFileProperties.getPath().getPath() + "temp_eml_files";
|
|
|
+ File tempDir = new File(zipFilePath + File.separator + "temp");
|
|
|
+// if (tempDir.exists()) {
|
|
|
+//
|
|
|
+// }
|
|
|
+ if (!tempDir.exists()) {
|
|
|
+ tempDir.mkdirs();
|
|
|
+ }
|
|
|
+
|
|
|
+ List<Message> messages = new ArrayList<>();
|
|
|
+
|
|
|
+ entities.forEach(e -> {
|
|
|
+ Message message = mailVoToMessages(e);
|
|
|
+ if (Objects.nonNull(message)) {
|
|
|
+ messages.add(message);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ for (int i = 0; i < messages.size(); i++) {
|
|
|
+ Message message = messages.get(i);
|
|
|
+ String subject = StrUtil.isNotBlank(message.getSubject()) ? message.getSubject() : "未命名";
|
|
|
+ ZipUtility.saveEmlFile(messages.get(i), tempDir.getPath() + "/" + subject + (i + 1) + ".eml");
|
|
|
+ }
|
|
|
+ File downloadFile = new File(tempDir.getPath());
|
|
|
+ if (!downloadFile.exists()) {
|
|
|
+ downloadFile.mkdirs();
|
|
|
+ }
|
|
|
+ File zipFile = new File(zipFilePath + File.separator + "emails" + currentUserId + ".zip");
|
|
|
+ try {
|
|
|
+ ZipUtility.zipFiles(tempDir, zipFile);
|
|
|
+ } catch (IOException e) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ FileInputStream inStream = new FileInputStream(zipFile);
|
|
|
+ // 设置响应头
|
|
|
+ response.setContentType("application/zip");
|
|
|
+ response.setContentLength((int) zipFile.length());
|
|
|
+ response.setHeader("Content-Disposition", "attachment; filename=\"" + zipFile.getName() + "\"");
|
|
|
+ // 获取输出流
|
|
|
+ OutputStream outStream = response.getOutputStream();
|
|
|
+ byte[] buffer = new byte[1024];
|
|
|
+ int bytesRead;
|
|
|
+
|
|
|
+ // 写入响应输出流
|
|
|
+ while ((bytesRead = inStream.read(buffer)) != -1) {
|
|
|
+ outStream.write(buffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("Error occurred while downloading the file: ", e);
|
|
|
+ } finally {
|
|
|
+ ZipUtility.deleteDirectory(tempDir);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @PostMapping(value = "/download_mail_eml")
|
|
|
+ @ApiOperation(value = "下载邮件")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public void downloadMail(MailDTO dto, HttpServletResponse response) throws MessagingException {
|
|
|
+ if (Objects.isNull(dto.getMailId())) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ EmailsEntity entitie = emailsService.getById(dto.getMailId());
|
|
|
+ if (Objects.isNull(entitie)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String zipFilePath = mailFileProperties.getPath().getPath() + "temp_eml_files";
|
|
|
+ File tempDir = new File(zipFilePath + File.separator + "temp");
|
|
|
+ if (!tempDir.exists()) {
|
|
|
+ tempDir.mkdirs();
|
|
|
+ }
|
|
|
+
|
|
|
+ Message message = mailVoToMessages(entitie);
|
|
|
+ String subject = StrUtil.isNotBlank(message.getSubject()) ? message.getSubject() : "未命名";
|
|
|
+ String tempPath = tempDir.getPath() + "/" + subject + ".eml";
|
|
|
+ ZipUtility.saveEmlFile(message, tempPath);
|
|
|
+
|
|
|
+ File downloadFile = new File(tempPath);
|
|
|
+ if (!downloadFile.exists()) {
|
|
|
+ downloadFile.mkdirs();
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ FileInputStream inStream = new FileInputStream(downloadFile);
|
|
|
+ // 设置响应头
|
|
|
+ response.reset();
|
|
|
+ response.setContentType("application/octet-stream;charset=utf-8");
|
|
|
+ /*
|
|
|
+ * 跨域配置
|
|
|
+ * */
|
|
|
+ response.addHeader("Access-Control-Allow-Origin", "*");
|
|
|
+ response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
|
|
|
+ response.addHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
|
+// String filename = "测试.docx";
|
|
|
+ String filename = downloadFile.getName();
|
|
|
+ response.addHeader("content-disposition",
|
|
|
+ "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")
|
|
|
+ + ";filename*=utf-8''" + URLEncoder.encode(filename, "UTF-8"));
|
|
|
+// response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
|
|
|
+ byte[] b = new byte[1024];
|
|
|
+ int len;
|
|
|
+//从输入流中读取一定数量的字节,并将其存储在缓冲区字节数组中,读到末尾返回-1
|
|
|
+ ServletOutputStream outputStream = response.getOutputStream();
|
|
|
+ while ((len = inStream.read(b)) > 0) {
|
|
|
+ outputStream.write(b, 0, len);
|
|
|
+ }
|
|
|
+ inStream.close();
|
|
|
+ outputStream.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("Error occurred while downloading the file: ", e);
|
|
|
+ } finally {
|
|
|
+ ZipUtility.deleteDirectory(tempDir);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public Message mailVoToMessages(EmailsEntity emails) {
|
|
|
+ try {
|
|
|
+ List<String> recipientls = new ArrayList<>();
|
|
|
+ if (StrUtil.isNotBlank(emails.getRecipient())) {
|
|
|
+ recipientls = Arrays.asList(emails.getRecipient().split(","));
|
|
|
+ }
|
|
|
+
|
|
|
+ List<String> recipientCcls = new ArrayList<>();
|
|
|
+ if (StrUtil.isNotBlank(emails.getRecipientCc())) {
|
|
|
+ recipientCcls = Arrays.asList(emails.getRecipientCc().split(","));
|
|
|
+ }
|
|
|
+ List<String> recipientBccls = new ArrayList<>();
|
|
|
+ if (StrUtil.isNotBlank(emails.getRecipientBcc())) {
|
|
|
+ recipientBccls = Arrays.asList(emails.getRecipientBcc().split(","));
|
|
|
+ }
|
|
|
+
|
|
|
+ String fromAddress = emails.getFrom();
|
|
|
+
|
|
|
+ InternetAddress[] froms = new InternetAddress[recipientls.size()];
|
|
|
+ for (int i = 0; i < recipientls.size(); i++) {
|
|
|
+ froms[i] = new InternetAddress(recipientls.get(i));
|
|
|
+ }
|
|
|
+ InternetAddress[] fromsCC = new InternetAddress[recipientCcls.size()];
|
|
|
+ for (int i = 0; i < recipientCcls.size(); i++) {
|
|
|
+ fromsCC[i] = new InternetAddress(recipientCcls.get(i));
|
|
|
+ }
|
|
|
+ InternetAddress[] fromsBCC = new InternetAddress[recipientBccls.size()];
|
|
|
+ for (int i = 0; i < recipientBccls.size(); i++) {
|
|
|
+ fromsBCC[i] = new InternetAddress(recipientBccls.get(i));
|
|
|
+ }
|
|
|
+
|
|
|
+ Message message = new MimeMessage(Session.getDefaultInstance(new Properties()));
|
|
|
+ if (Objects.nonNull(froms) && froms.length > 0) {
|
|
|
+ message.setRecipients(Message.RecipientType.TO, froms);
|
|
|
+ }
|
|
|
+ if (Objects.nonNull(fromsCC) && fromsCC.length > 0) {
|
|
|
+ message.setRecipients(Message.RecipientType.CC, fromsCC);
|
|
|
+ }
|
|
|
+ if (Objects.nonNull(fromsBCC) && fromsBCC.length > 0) {
|
|
|
+ message.setRecipients(Message.RecipientType.BCC, fromsBCC);
|
|
|
+ }
|
|
|
+
|
|
|
+ LambdaQueryWrapper fileWrapper = new LambdaQueryWrapper<MailTempAttachmentEntity>().in(MailTempAttachmentEntity::getEmailId, emails.getId());
|
|
|
+ List<MailTempAttachmentEntity> tempAttachment = tempAttachmentService.list(fileWrapper);
|
|
|
+ if (CollectionUtils.isEmpty(tempAttachment)) {
|
|
|
+ message.setFrom(new InternetAddress(fromAddress));
|
|
|
+ message.setSubject(emails.getSubject());
|
|
|
+ message.setContent(emails.getContent(), "text/html; charset=UTF-8");
|
|
|
+ } else {
|
|
|
+ message.setFrom(new InternetAddress(fromAddress));
|
|
|
+ message.setDescription(emails.getRemark());
|
|
|
+ // 设置邮件主题
|
|
|
+ message.setSubject(emails.getSubject());
|
|
|
+ // 创建消息部分
|
|
|
+ Multipart multipart = new MimeMultipart();
|
|
|
+// // 消息正文
|
|
|
+ BodyPart messageBodyPart1 = new MimeBodyPart();
|
|
|
+ messageBodyPart1.setContent(emails.getContent(), "text/html; charset=UTF-8");
|
|
|
+ multipart.addBodyPart(messageBodyPart1);
|
|
|
+// message.add(dto.getContent(), "UTF-8","text/html");
|
|
|
+ // 创建一个多部分消息
|
|
|
+
|
|
|
+ // 设置文本消息部分
|
|
|
+ for (MailTempAttachmentEntity attachment : tempAttachment) {
|
|
|
+ BodyPart messageBodyPart = new MimeBodyPart();
|
|
|
+ String filePath = mailFileProperties.getPath().getPath() + attachment.getFilePath();
|
|
|
+ messageBodyPart = new MimeBodyPart();
|
|
|
+ String fileName = attachment.getFileName() + "." + attachment.getFileExt();
|
|
|
+ DataSource fileSource = new FileDataSource(filePath);
|
|
|
+ messageBodyPart.setDataHandler(new DataHandler(fileSource));
|
|
|
+ messageBodyPart.setFileName(fileName);
|
|
|
+ multipart.addBodyPart(messageBodyPart);
|
|
|
+ }
|
|
|
+ // 发送完整的消息部分
|
|
|
+ message.setContent(multipart);
|
|
|
+ // 获取邮件大小
|
|
|
+ }
|
|
|
+ return message;
|
|
|
+ } catch (Exception e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/mv_mail_box")
|
|
|
+ @ApiOperation(value = "移动邮件")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result<?> mvMailBox(MailMoveDTO dto) {
|
|
|
+ if (Objects.isNull(dto.getEmailId()) || Objects.isNull(dto.getBoxCode())) {
|
|
|
+ return Result.error("参数错误!");
|
|
|
+ }
|
|
|
+ Long currentUserId = LoginUserUtil.getCurrentUserId();
|
|
|
+ EmailBoxEnum boxEnum = EmailBoxEnum.getEnumByCode(dto.getBoxCode());
|
|
|
+ if (Objects.isNull(boxEnum)) {
|
|
|
+ return Result.error("参数错误!");
|
|
|
+ }
|
|
|
+ EmailsEntity entity = emailsService.getById(dto.getEmailId());
|
|
|
+ if (Objects.nonNull(entity) && entity.getOwnerBy().equals(currentUserId)) {
|
|
|
+ entity.setFolder(boxEnum.code);
|
|
|
+ entity.setUpdateBy(currentUserId);
|
|
|
+ emailsService.updateById(entity);
|
|
|
+ return Result.ok();
|
|
|
+ } else {
|
|
|
+ return Result.error("参数错误!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ @PostMapping(value = "/mark_trash")
|
|
|
+ @ApiOperation(value = "垃圾箱")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result<?> mvTrashBox(MailMoveDTO dto) {
|
|
|
+ if (Objects.isNull(dto.getEmailId()) && StringUtils.isEmpty(dto.getEmailIds())) {
|
|
|
+ return Result.error("参数错误!");
|
|
|
+ }
|
|
|
+ Long currentUserId = LoginUserUtil.getCurrentUserId();
|
|
|
+ LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ uWrapper.set(EmailsEntity::getIsTrash, dto.getIsTrash());
|
|
|
+ uWrapper.eq(EmailsEntity::getOwnerBy, currentUserId);
|
|
|
+ if (Objects.nonNull(dto.getEmailId())) {
|
|
|
+ uWrapper.eq(EmailsEntity::getId, dto.getEmailId());
|
|
|
+ } else {
|
|
|
+ uWrapper.in(EmailsEntity::getId, dto.getEmailIds());
|
|
|
+ }
|
|
|
+ emailsService.update(uWrapper);
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "彻底删除")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = Result.class)
|
|
|
+ })
|
|
|
+ @PostMapping("/deleteIds")
|
|
|
+ public Result<?> deleteIds(Long[] ids) {
|
|
|
+ if (Objects.isNull(ids)) {
|
|
|
+ return Result.error("参数错误");
|
|
|
+ }
|
|
|
+ LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ uWrapper.set(EmailsEntity::getIsDelete, Integer.valueOf(1));
|
|
|
+ uWrapper.in(EmailsEntity::getId, Arrays.asList(ids));
|
|
|
+ emailsService.update(uWrapper);
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @ApiOperation(value = "彻底删除草稿")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = Result.class)
|
|
|
+ })
|
|
|
+ @PostMapping("/deleteDraftIds")
|
|
|
+ public Result<?> deleteDraftIds(Long[] ids) {
|
|
|
+ if (Objects.isNull(ids)) {
|
|
|
+ return Result.error("删除草稿");
|
|
|
+ }
|
|
|
+ LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ uWrapper.in(EmailsEntity::getId, Arrays.asList(ids));
|
|
|
+ emailsService.remove(uWrapper);
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/get_mail_detial")
|
|
|
+ @ApiOperation(value = "获取详情接口")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result<?> getMailDetial(Long mailId) {
|
|
|
+ if (Objects.isNull(mailId)) {
|
|
|
+ return Result.error("参数错误!");
|
|
|
+ }
|
|
|
+ EmailsEntity email = emailsService.getById(mailId);
|
|
|
+ if (Objects.nonNull(email) && EmailBoxEnum.DRAFT.code.equals(email.getFolder())) {
|
|
|
+ List<MailTempAttachmentEntity> atts = tempAttachmentService.list(new LambdaQueryWrapper<MailTempAttachmentEntity>().eq(MailTempAttachmentEntity::getEmailId, mailId));
|
|
|
+ if (!CollectionUtils.isEmpty(atts)) {
|
|
|
+ atts.forEach(e -> {
|
|
|
+ e.setFileSizeName(FileHelper.formatFileSize(e.getFileSize()));
|
|
|
+ });
|
|
|
+ }
|
|
|
+ email.setAttachments(atts);
|
|
|
+ } else {
|
|
|
+ List<MailAttachmentEntity> atts = mailAttachmentService.list(new LambdaQueryWrapper<MailAttachmentEntity>().eq(MailAttachmentEntity::getEmailId, mailId));
|
|
|
+ if (!CollectionUtils.isEmpty(atts)) {
|
|
|
+ atts.forEach(e -> {
|
|
|
+ e.setFileSizeName(FileHelper.formatFileSize(e.getFileSize()));
|
|
|
+ });
|
|
|
+ }
|
|
|
+ email.setAttachments(atts);
|
|
|
+ }
|
|
|
+
|
|
|
+ return Result.result(email);
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/mv_custom_folder")
|
|
|
+ @ApiOperation(value = "迁移邮件到自定义文件夹", notes = "迁移邮件到自定义文件夹")
|
|
|
+ public Result getMailPortConfig(Long[] mailIds, Long folderId) {
|
|
|
+ if (Objects.isNull(mailIds) || Objects.isNull(folderId)) {
|
|
|
+ return Result.error("参数错误");
|
|
|
+ }
|
|
|
+ LambdaUpdateWrapper<EmailsEntity> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ updateWrapper.set(EmailsEntity::getCustomFolderId, folderId);
|
|
|
+ updateWrapper.in(EmailsEntity::getId, Arrays.asList(mailIds));
|
|
|
+ emailsService.update(updateWrapper);
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/del_custom_folder_mail")
|
|
|
+ @ApiOperation(value = "获取邮箱端口配置", notes = "获取邮箱端口配置")
|
|
|
+ public Result delCustomFolderMail(Long[] mailIds) {
|
|
|
+ if (Objects.isNull(mailIds)) {
|
|
|
+ return Result.error("参数错误");
|
|
|
+ }
|
|
|
+ LambdaUpdateWrapper<EmailsEntity> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ updateWrapper.in(EmailsEntity::getId, Arrays.asList(mailIds));
|
|
|
+ updateWrapper.set(EmailsEntity::getCustomFolderId, null);
|
|
|
+ emailsService.update(updateWrapper);
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/mark_star")
|
|
|
+ @ApiOperation(value = "星标")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result<?> takeStar(MailMoveDTO dto) {
|
|
|
+ if (Objects.isNull(dto.getEmailId()) && StringUtils.isEmpty(dto.getEmailIds())) {
|
|
|
+ return Result.error("参数错误!");
|
|
|
+ }
|
|
|
+ Long currentUserId = LoginUserUtil.getCurrentUserId();
|
|
|
+ LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ uWrapper.set(EmailsEntity::getIsStar, dto.getIsStar());
|
|
|
+ uWrapper.eq(EmailsEntity::getOwnerBy, currentUserId);
|
|
|
+ if (Objects.nonNull(dto.getEmailId())) {
|
|
|
+ uWrapper.eq(EmailsEntity::getId, dto.getEmailId());
|
|
|
+ } else {
|
|
|
+ uWrapper.in(EmailsEntity::getId, dto.getEmailIds());
|
|
|
+ }
|
|
|
+ emailsService.update(uWrapper);
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/mark_read")
|
|
|
+ @ApiOperation(value = "已读未读标记")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result<?> markRead(MailMoveDTO dto) {
|
|
|
+ if (Objects.isNull(dto.getEmailId()) && StringUtils.isEmpty(dto.getEmailIds())) {
|
|
|
+ return Result.error("参数错误!");
|
|
|
+ }
|
|
|
+ LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ uWrapper.set(EmailsEntity::getIsRead, dto.getIsRead());
|
|
|
+ if (Objects.nonNull(dto.getEmailId())) {
|
|
|
+ uWrapper.eq(EmailsEntity::getId, dto.getEmailId());
|
|
|
+ } else {
|
|
|
+ uWrapper.in(EmailsEntity::getId, dto.getEmailIds());
|
|
|
+ }
|
|
|
+ emailsService.update(uWrapper);
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/mark_reply_msg_id")
|
|
|
+ @ApiOperation(value = "标记陌生客户回复不回复")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result<?> markReplyMsgId(MailMoveDTO dto) {
|
|
|
+ if (Objects.isNull(dto.getEmailId()) && StringUtils.isEmpty(dto.getEmailIds())) {
|
|
|
+ return Result.error("参数错误!");
|
|
|
+ }
|
|
|
+ LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ uWrapper.set(EmailsEntity::getReplyMsgId, dto.getReplyMsgId());
|
|
|
+ if (Objects.nonNull(dto.getEmailId())) {
|
|
|
+ uWrapper.eq(EmailsEntity::getId, dto.getEmailId());
|
|
|
+ } else {
|
|
|
+ uWrapper.in(EmailsEntity::getId, dto.getEmailIds());
|
|
|
+ }
|
|
|
+ emailsService.update(uWrapper);
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/mark_all_read")
|
|
|
+ @ApiOperation(value = "已读未读标记")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result<?> markAllRead() {
|
|
|
+ Long currentUserId = LoginUserUtil.getCurrentUserId();
|
|
|
+ if (Objects.isNull(currentUserId)) {
|
|
|
+ return Result.error("登录失效,请重新登陆!");
|
|
|
+ }
|
|
|
+ LambdaUpdateWrapper<EmailsEntity> uWrapper = new LambdaUpdateWrapper<>();
|
|
|
+ uWrapper.set(EmailsEntity::getIsRead, Integer.valueOf(1));
|
|
|
+ uWrapper.eq(EmailsEntity::getOwnerBy, currentUserId);
|
|
|
+ uWrapper.eq(EmailsEntity::getIsRead, Integer.valueOf(0));
|
|
|
+ emailsService.update(uWrapper);
|
|
|
+ return Result.ok();
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/list_mail_attachment")
|
|
|
+ @ApiOperation(value = "邮件附件")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public Result listMailAttachment(AttachmentDTO dto) {
|
|
|
+
|
|
|
+ Long currentUserId = LoginUserUtil.getCurrentUserId();
|
|
|
+ SmtpPopSettingsEntity emailPop = smtpPopSettingsService.getDefaultSmtpPop(currentUserId);
|
|
|
+ if (Objects.isNull(emailPop)) {
|
|
|
+ return Result.result(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ QueryWrapper<MailAttachmentEntity> queryWrapper = new QueryWrapper();
|
|
|
+ queryWrapper.eq("att.smtp_pop_id", emailPop.getId());
|
|
|
+
|
|
|
+ if (StrUtil.isNotBlank(dto.getFileExt())) {
|
|
|
+ if ("png".equals(dto.getFileExt())) {
|
|
|
+ queryWrapper.in("att.file_ext", Arrays.asList("png", "jpg"));
|
|
|
+ } else if ("video".equals(dto.getFileExt())) {
|
|
|
+ queryWrapper.in("att.file_ext", Arrays.asList("mp4", "video"));
|
|
|
+ } else if ("zip".equals(dto.getFileExt())) {
|
|
|
+ queryWrapper.in("att.file_ext", Arrays.asList("zip", "rar", "7z"));
|
|
|
+ } else if ("txt".equals(dto.getFileExt())) {
|
|
|
+ queryWrapper.in("att.file_ext", Arrays.asList("pdf", "word", "excel"));
|
|
|
+ } else {
|
|
|
+ queryWrapper.eq("att.file_ext", dto.getFileExt());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Page<MailAttachmentEntity> page = new Page<>(dto.getPageIndex(), dto.getPageSize());
|
|
|
+
|
|
|
+ queryWrapper.eq("att.is_delete", CommonConstant.DEL_FLAG_0);
|
|
|
+ queryWrapper.eq("e.smtp_pop_id", emailPop.getId());
|
|
|
+
|
|
|
+ queryWrapper.orderByDesc("e.sent_date");
|
|
|
+
|
|
|
+ IPage<MailAttachmentEntity> pageList = mailAttachmentService.pateList(page, queryWrapper);
|
|
|
+
|
|
|
+ Map<Long, String> emailMap = new HashMap<>();
|
|
|
+ if (!CollectionUtils.isEmpty(pageList.getRecords())) {
|
|
|
+ List<Long> mailIds = pageList.getRecords().stream().map(MailAttachmentEntity::getEmailId).collect(Collectors.toList());
|
|
|
+ LambdaQueryWrapper<EmailsEntity> eQueryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ eQueryWrapper.in(EmailsEntity::getId, mailIds);
|
|
|
+ List<EmailsEntity> emails = emailsService.list(eQueryWrapper);
|
|
|
+ if (!CollectionUtils.isEmpty(emails)) {
|
|
|
+ emailMap = emails.stream().collect(Collectors.toMap(EmailsEntity::getId, EmailsEntity::getSubject));
|
|
|
+ }
|
|
|
+ Map<Long, String> finalEmailMap = emailMap;
|
|
|
+ pageList.getRecords().forEach(e -> {
|
|
|
+ e.setFileSizeName(FileHelper.formatFileSize(e.getFileSize()));
|
|
|
+ e.setSubject(finalEmailMap.get(e.getEmailId()));
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return Result.result(pageList);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @PostMapping(value = "/download_zip")
|
|
|
+ @ApiOperation(value = "打包下载")
|
|
|
+ @ApiResponses({
|
|
|
+ @ApiResponse(code = 200, message = "", response = SmtpPopSettingsEntity.class)
|
|
|
+ })
|
|
|
+ public void downloadZip(AttachmentDTO dto, HttpServletResponse response) {
|
|
|
+ if (Objects.isNull(dto.getMailId()) && CollectionUtils.isEmpty(dto.getAttachmentIds())) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String zipFilePath = mailFileProperties.getPath().getPath() + System.currentTimeMillis() + RandomGenerateHelper.generateRandomString(6) + ".zip";
|
|
|
+ List<MailAttachmentEntity> attachments;
|
|
|
+ if (Objects.nonNull(dto.getMailId())) {
|
|
|
+ attachments = mailAttachmentService.list(new LambdaQueryWrapper<MailAttachmentEntity>().eq(MailAttachmentEntity::getEmailId, dto.getMailId()).eq(MailAttachmentEntity::getDownload, Integer.valueOf(1)));
|
|
|
+ } else {
|
|
|
+ attachments = mailAttachmentService.list(new LambdaQueryWrapper<MailAttachmentEntity>().in(MailAttachmentEntity::getId, dto.getAttachmentIds()).eq(MailAttachmentEntity::getDownload, Integer.valueOf(1)));
|
|
|
+ }
|
|
|
+ if (CollectionUtils.isEmpty(attachments)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ ZipUtility.zipFiles(attachments, zipFilePath, mailFileProperties);
|
|
|
+ } catch (IOException e) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ File downloadFile = new File(zipFilePath);
|
|
|
+ try {
|
|
|
+ FileInputStream inStream = new FileInputStream(downloadFile);
|
|
|
+ // 设置响应头
|
|
|
+ response.setContentType("application/zip");
|
|
|
+ response.setContentLength((int) downloadFile.length());
|
|
|
+ response.setHeader("Content-Disposition", "attachment; filename=\"" + downloadFile.getName() + "\"");
|
|
|
+ // 获取输出流
|
|
|
+ OutputStream outStream = response.getOutputStream();
|
|
|
+ byte[] buffer = new byte[1024];
|
|
|
+ int bytesRead;
|
|
|
+
|
|
|
+ // 写入响应输出流
|
|
|
+ while ((bytesRead = inStream.read(buffer)) != -1) {
|
|
|
+ outStream.write(buffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("Error occurred while downloading the file: ", e);
|
|
|
+ } finally {
|
|
|
+ // 下载完成后删除临时ZIP文件
|
|
|
+ if (downloadFile.exists()) {
|
|
|
+ if (!downloadFile.delete()) {
|
|
|
+ System.err.println("Failed to delete the temporary file: " + zipFilePath);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/download_url")
|
|
|
+ @ApiOperation(value = "下载", notes = "下载")
|
|
|
+ public Result downloadUrl(Long attachmentId) throws IOException {
|
|
|
+ try {
|
|
|
+ if (attachmentId == null) {
|
|
|
+ return Result.error("附未找到");
|
|
|
+ }
|
|
|
+ MailAttachmentEntity attachment = mailAttachmentService.getById(attachmentId);
|
|
|
+ if (attachment == null) {
|
|
|
+ return Result.error("附未找到");
|
|
|
+ }
|
|
|
+
|
|
|
+ String url = mailFileProperties.getPath().getPath() + File.separator + attachment.getFilePath();
|
|
|
+
|
|
|
+
|
|
|
+ // String newFileName = attachment.getFilePath().replace("."+attachment.getFileCode(),"");
|
|
|
+ File exportDir;
|
|
|
+ String active = environment.getProperty("spring.profiles.active");
|
|
|
+ String port = environment.getProperty("server.port");
|
|
|
+ if (active.equals("dev")) {
|
|
|
+ exportDir = new File("D:\\mail\\tempfiles");
|
|
|
+ } else {
|
|
|
+ url = url.replace("\\", "/");
|
|
|
+ exportDir = new File("/app/tempfiles");
|
|
|
+ }
|
|
|
+ Path filePath = Paths.get(url);
|
|
|
+ if (!exportDir.exists()) {
|
|
|
+ exportDir.mkdirs();
|
|
|
+ }
|
|
|
+
|
|
|
+ Path targetPath1;
|
|
|
+ if (StrUtil.isNotBlank(attachment.getFileCode())) {
|
|
|
+ targetPath1 = Paths.get(url.replace("."+attachment.getFileCode(),""));
|
|
|
+ } else {
|
|
|
+ targetPath1 = Paths.get(url);
|
|
|
+ }
|
|
|
+ String fileName = targetPath1.getFileName().toString();
|
|
|
+
|
|
|
+ Path target = Paths.get(exportDir.getAbsolutePath());
|
|
|
+ // 创建目标目录(如果不存在)
|
|
|
+ if (!Files.exists(target.getParent())) {
|
|
|
+ Files.createDirectories(target.getParent());
|
|
|
+ }
|
|
|
+ Path targetPath = target.resolve(fileName);
|
|
|
+ Files.copy(filePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
|
|
+
|
|
|
+ // 2. 拼接 URL(这里假设映射后访问路径是 /export/)
|
|
|
+ String fileUrl = "/static/file/" + targetPath.getFileName();
|
|
|
+
|
|
|
+ String domainUrl = "";
|
|
|
+ if(active.equals("prod")) {
|
|
|
+ domainUrl = "https://sales.storlead.com"+fileUrl;
|
|
|
+ } else if (active.equals("test")){
|
|
|
+ domainUrl = "https://sales.test.storlead.com"+fileUrl;
|
|
|
+ } else if (active.equals("dev")){
|
|
|
+ domainUrl = "http://localhost:"+port+fileUrl;
|
|
|
+ }
|
|
|
+ return Result.result(domainUrl);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("download--error", e);
|
|
|
+ return Result.error("附未找到");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/draft_download_url")
|
|
|
+ @ApiOperation(value = "下载", notes = "下载")
|
|
|
+ public Result draft_download(Long attachmentId) throws IOException {
|
|
|
+ try {
|
|
|
+ if (attachmentId == null) {
|
|
|
+ return Result.error("附未找到");
|
|
|
+ }
|
|
|
+ MailTempAttachmentEntity attachment = tempAttachmentService.getById(attachmentId);
|
|
|
+ if (attachment == null) {
|
|
|
+ return Result.error("附未找到");
|
|
|
+ }
|
|
|
+
|
|
|
+ String url = mailFileProperties.getPath().getPath() + File.separator + attachment.getFilePath();
|
|
|
+
|
|
|
+ File exportDir;
|
|
|
+ String active = environment.getProperty("spring.profiles.active");
|
|
|
+ String port = environment.getProperty("server.port");
|
|
|
+ if (active.equals("dev")) {
|
|
|
+ exportDir = new File("D:\\mail\\tempfiles");
|
|
|
+ } else {
|
|
|
+ url = url.replace("\\", "/");
|
|
|
+ exportDir = new File("/app/tempfiles");
|
|
|
+ }
|
|
|
+ Path filePath = Paths.get(url);
|
|
|
+ if (!exportDir.exists()) {
|
|
|
+ exportDir.mkdirs();
|
|
|
+ }
|
|
|
+ Path targetPath1;
|
|
|
+ if (StrUtil.isNotBlank(attachment.getFileCode())) {
|
|
|
+ targetPath1 = Paths.get(url.replace("."+attachment.getFileCode(),""));
|
|
|
+ } else {
|
|
|
+ targetPath1 = Paths.get(url);
|
|
|
+ }
|
|
|
+ String fileName = targetPath1.getFileName().toString();
|
|
|
+
|
|
|
+ Path target = Paths.get(exportDir.getAbsolutePath());
|
|
|
+ // 创建目标目录(如果不存在)
|
|
|
+ if (!Files.exists(target.getParent())) {
|
|
|
+ Files.createDirectories(target.getParent());
|
|
|
+ }
|
|
|
+ Path targetPath = target.resolve(fileName);
|
|
|
+ Files.copy(filePath, targetPath, StandardCopyOption.REPLACE_EXISTING);
|
|
|
+
|
|
|
+ // 2. 拼接 URL(这里假设映射后访问路径是 /export/)
|
|
|
+ String fileUrl = "/static/file/" + targetPath.getFileName();
|
|
|
+
|
|
|
+ String domainUrl = "";
|
|
|
+ if(active.equals("prod")) {
|
|
|
+ domainUrl = "https://sales.storlead.com"+fileUrl;
|
|
|
+ } else if (active.equals("test")){
|
|
|
+ domainUrl = "https://sales.test.storlead.com"+fileUrl;
|
|
|
+ } else if (active.equals("dev")){
|
|
|
+ domainUrl = "http://localhost:"+port+fileUrl;
|
|
|
+ }
|
|
|
+ return Result.result(domainUrl);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("download--error", e);
|
|
|
+ return Result.error("附未找到");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/draft_download")
|
|
|
+ @ApiOperation(value = "下载", notes = "下载")
|
|
|
+ public void draft_download(Long attachmentId, HttpServletResponse response) throws IOException {
|
|
|
+ try {
|
|
|
+ if (attachmentId == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ MailTempAttachmentEntity attachment = tempAttachmentService.getById(attachmentId);
|
|
|
+ if (attachment == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ InputStream inputStream;
|
|
|
+ String url = mailFileProperties.getPath().getPath() + attachment.getFilePath();
|
|
|
+ inputStream = new BufferedInputStream(new FileInputStream(url));
|
|
|
+ response.reset();
|
|
|
+ response.setContentType("application/octet-stream;charset=utf-8");
|
|
|
+ /*
|
|
|
+ * 跨域配置
|
|
|
+ * */
|
|
|
+ response.addHeader("Access-Control-Allow-Origin", "*");
|
|
|
+ response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
|
|
|
+ response.addHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
|
+// String filename = "测试.docx";
|
|
|
+ String filename = attachment.getFileName() + "." + attachment.getFileExt();
|
|
|
+ response.addHeader("content-disposition",
|
|
|
+ "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")
|
|
|
+ + ";filename*=utf-8''" + URLEncoder.encode(filename, "UTF-8"));
|
|
|
+// response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
|
|
|
+ byte[] b = new byte[1024];
|
|
|
+ int len;
|
|
|
+//从输入流中读取一定数量的字节,并将其存储在缓冲区字节数组中,读到末尾返回-1
|
|
|
+ ServletOutputStream outputStream = response.getOutputStream();
|
|
|
+ while ((len = inputStream.read(b)) > 0) {
|
|
|
+ outputStream.write(b, 0, len);
|
|
|
+ }
|
|
|
+ inputStream.close();
|
|
|
+ outputStream.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("download--error", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @RequestMapping(value = "/download")
|
|
|
+ @ApiOperation(value = "下载", notes = "下载")
|
|
|
+ public void download(Long attachmentId, HttpServletResponse response) throws IOException {
|
|
|
+ try {
|
|
|
+ if (attachmentId == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ MailAttachmentEntity attachment = mailAttachmentService.getById(attachmentId);
|
|
|
+ if (attachment == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ InputStream inputStream;
|
|
|
+ String url = mailFileProperties.getPath().getPath() + attachment.getFilePath();
|
|
|
+ if (Integer.valueOf(0).equals(attachment.getDownload())) {
|
|
|
+ if (new File(url).exists()) {
|
|
|
+ LambdaUpdateWrapper<MailAttachmentEntity> attachmentUpdate = new LambdaUpdateWrapper<>();
|
|
|
+ attachmentUpdate.set(MailAttachmentEntity::getDownload, Integer.valueOf(1));
|
|
|
+ attachmentUpdate.eq(MailAttachmentEntity::getId, attachment.getId());
|
|
|
+ mailAttachmentService.update(attachmentUpdate);
|
|
|
+ }
|
|
|
+ //没有下载
|
|
|
+ EmailsEntity email = emailsService.getById(attachment.getEmailId());
|
|
|
+ SmtpPopSettingsEntity smtpPop = smtpPopSettingsService.getById(email.getSmtpPopId());
|
|
|
+ inputStream = emailsService.loadEmailsFile(smtpPop, email, attachment.getFileName() + "." + attachment.getFileExt());
|
|
|
+ if (Objects.isNull(inputStream)) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ String path = mailFileProperties.getPath().getPath() + attachment.getFilePath();
|
|
|
+ File file = new File(path);
|
|
|
+ try (FileOutputStream output = new FileOutputStream(file)) {
|
|
|
+ inputStream.transferTo(output);
|
|
|
+ }
|
|
|
+ LambdaUpdateWrapper<MailAttachmentEntity> attachmentUpdate = new LambdaUpdateWrapper<>();
|
|
|
+ attachmentUpdate.set(MailAttachmentEntity::getDownload, Integer.valueOf(1));
|
|
|
+ attachmentUpdate.set(MailAttachmentEntity::getFileSize, file.length());
|
|
|
+ attachmentUpdate.eq(MailAttachmentEntity::getId, attachment.getId());
|
|
|
+ mailAttachmentService.update(attachmentUpdate);
|
|
|
+ }
|
|
|
+ inputStream = new BufferedInputStream(new FileInputStream(url));
|
|
|
+ response.reset();
|
|
|
+ /*
|
|
|
+ * 跨域配置
|
|
|
+ * */
|
|
|
+ response.addHeader("Access-Control-Allow-Origin", "*");
|
|
|
+ response.addHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE");
|
|
|
+ response.addHeader("Access-Control-Allow-Headers", "Content-Type");
|
|
|
+// String filename = "测试.docx";
|
|
|
+ String filename = attachment.getFileName() + "." + attachment.getFileExt();
|
|
|
+
|
|
|
+ String ext = attachment.getFileExt().toLowerCase();
|
|
|
+ boolean inline = ext.equals("pdf")
|
|
|
+ || ext.equals("png")
|
|
|
+ || ext.equals("jpg")
|
|
|
+ || ext.equals("jpeg")
|
|
|
+ || ext.equals("gif");
|
|
|
+ if (inline) {
|
|
|
+ if ("pdf".equals(ext)) {
|
|
|
+ response.setContentType("application/pdf");
|
|
|
+ } else {
|
|
|
+ response.setContentType("image/" + ext);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+// response.setContentType("application/octet-stream");
|
|
|
+ response.setContentType("application/octet-stream;charset=utf-8");
|
|
|
+ }
|
|
|
+ String dispositionType = inline ? "inline" : "attachment";
|
|
|
+ response.setHeader(
|
|
|
+ "Content-Disposition",
|
|
|
+ dispositionType + "; filename=" + URLEncoder.encode(filename, "UTF-8")
|
|
|
+ + ";filename*=utf-8''" + URLEncoder.encode(filename, "UTF-8"));
|
|
|
+
|
|
|
+// response.addHeader("content-disposition",
|
|
|
+// "attachment;filename=" + URLEncoder.encode(filename, "UTF-8")
|
|
|
+// + ";filename*=utf-8''" + URLEncoder.encode(filename, "UTF-8"));
|
|
|
+// response.addHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(filename, "UTF-8"));
|
|
|
+ byte[] b = new byte[1024];
|
|
|
+ int len;
|
|
|
+//从输入流中读取一定数量的字节,并将其存储在缓冲区字节数组中,读到末尾返回-1
|
|
|
+ ServletOutputStream outputStream = response.getOutputStream();
|
|
|
+ while ((len = inputStream.read(b)) > 0) {
|
|
|
+ outputStream.write(b, 0, len);
|
|
|
+ }
|
|
|
+ inputStream.close();
|
|
|
+ outputStream.close();
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("download--error", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 读取 InputStream 并计算其大小
|
|
|
+ public int getAttachmentSize(InputStream inputStream) throws Exception {
|
|
|
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
|
+ byte[] buffer = new byte[4096];
|
|
|
+ int bytesRead;
|
|
|
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
|
+ byteArrayOutputStream.write(buffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+ return byteArrayOutputStream.size();
|
|
|
+ }
|
|
|
+
|
|
|
+ public InputStream copyInputStream(InputStream original) throws IOException {
|
|
|
+ ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
|
|
+ byte[] buffer = new byte[4096];
|
|
|
+ int bytesRead;
|
|
|
+ while ((bytesRead = original.read(buffer)) != -1) {
|
|
|
+ byteArrayOutputStream.write(buffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+ // 生成的字节数组可以用来创建多个 InputStream 副本
|
|
|
+ return new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping(value = "/mail_port_config")
|
|
|
+ @ApiOperation(value = "获取邮箱端口配置", notes = "获取邮箱端口配置")
|
|
|
+ public Result getMailPortConfig(String mailAccount) throws IOException {
|
|
|
+ if (StrUtil.isBlank(mailAccount)) {
|
|
|
+ return Result.result("参数错误");
|
|
|
+ }
|
|
|
+ LambdaQueryWrapper<MailServerPortConfigEntity> queryWrapper = new LambdaQueryWrapper<>();
|
|
|
+ queryWrapper.eq(MailServerPortConfigEntity::getMailServerSuffix, EmailServiceChecker.getEmailService(mailAccount));
|
|
|
+ queryWrapper.last("limit 1");
|
|
|
+ MailServerPortConfigEntity portConfig = serverPortConfigService.getOne(queryWrapper);
|
|
|
+ return Result.result(portConfig);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private static String formatDate(Date date) {
|
|
|
+ if (date == null) return "N/A";
|
|
|
+ SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
+ return sdf.format(date);
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String decodeAddresses(Address[] addresses) throws MessagingException {
|
|
|
+ try {
|
|
|
+ if (addresses == null) return "[]";
|
|
|
+ String[] decodedAddresses = new String[addresses.length];
|
|
|
+ for (int i = 0; i < addresses.length; i++) {
|
|
|
+ decodedAddresses[i] = MimeUtility.decodeText(addresses[i].toString());
|
|
|
+ }
|
|
|
+ return Arrays.toString(decodedAddresses);
|
|
|
+ } catch (Exception e) {
|
|
|
+ return "";
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private Path saveTempFile(MultipartFile file) throws IOException {
|
|
|
+ Path tempFilePath = Files.createTempFile("upload", ".zip");
|
|
|
+ file.transferTo(tempFilePath.toFile());
|
|
|
+ return tempFilePath;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|