From 9709ddf7896ad4d02859d755fb8ef1a28599b587 Mon Sep 17 00:00:00 2001 From: 이민희 <mhlee@maprex.co.kr> Date: 화, 25 1월 2022 18:50:00 +0900 Subject: [PATCH] 일반 이메일 전송시 첨부 파일 추가 --- src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java | 6 src/main/webapp/views/issue/issueCommonSendMail.html | 47 +++++++++ src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js | 161 +++++++++++++++++++++++++++++++- src/main/java/kr/wisestone/owl/service/impl/SystemEmailServiceImpl.java | 21 ++- src/main/java/kr/wisestone/owl/service/IssueService.java | 2 src/main/webapp/scripts/components/issue/issue.service.js | 9 + src/main/java/kr/wisestone/owl/service/SystemEmailService.java | 3 src/main/java/kr/wisestone/owl/web/controller/IssueController.java | 7 8 files changed, 232 insertions(+), 24 deletions(-) diff --git a/src/main/java/kr/wisestone/owl/service/IssueService.java b/src/main/java/kr/wisestone/owl/service/IssueService.java index 1221d84..8d3b264 100644 --- a/src/main/java/kr/wisestone/owl/service/IssueService.java +++ b/src/main/java/kr/wisestone/owl/service/IssueService.java @@ -114,5 +114,5 @@ void makeIssueMapToIssue(Issue issue, Map<String, Object> issueMap); - void sendCommonEmail(EmailCommonForm make); + void sendCommonEmail(EmailCommonForm make, List<MultipartFile> files); } diff --git a/src/main/java/kr/wisestone/owl/service/SystemEmailService.java b/src/main/java/kr/wisestone/owl/service/SystemEmailService.java index fe43241..8dd6e5c 100644 --- a/src/main/java/kr/wisestone/owl/service/SystemEmailService.java +++ b/src/main/java/kr/wisestone/owl/service/SystemEmailService.java @@ -5,6 +5,7 @@ import kr.wisestone.owl.domain.User; import kr.wisestone.owl.domain.enumType.EmailType; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.web.multipart.MultipartFile; import java.util.List; import java.util.Locale; @@ -14,7 +15,7 @@ void directEmail(String[] sendUsers, EmailType emailType, Map<String, Object> content, String toUser); - void sendEmail(String subject, String content, String[] to, String[] filePaths); + void sendEmail(String subject, String content, String[] to, String[] filePaths, List<MultipartFile> multipartFiles); List<String> notificationUserChange(List<User> totalUsers, List<User> targetUsers); diff --git a/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java b/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java index 765ab69..dbb2790 100644 --- a/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java +++ b/src/main/java/kr/wisestone/owl/service/impl/IssueServiceImpl.java @@ -3869,14 +3869,14 @@ for(int i=0; i < sendMails.length; i++) { sendMails[i] = CommonUtil.decryptAES128(sendMails[i]); } - this.systemEmailService.sendEmail(emailTemplateForm.getTitle(), emailTemplateForm.getTemplate(), sendMails, null); + this.systemEmailService.sendEmail(emailTemplateForm.getTitle(), emailTemplateForm.getTemplate(), sendMails, null, null); this.issueHistoryService.detectSendIssueMail(IssueHistoryType.SEND, emailTemplateForm.getSendEmails(), sb); this.issueHistoryService.addIssueHistory(issue, IssueHistoryType.SEND, sb.toString()); } @Override - public void sendCommonEmail(EmailCommonForm emailCommonForm) { + public void sendCommonEmail(EmailCommonForm emailCommonForm, List<MultipartFile> multipartFiles) { if (emailCommonForm.getSendEmails().size() < 1) { throw new OwlRuntimeException( this.messageAccessor.getMessage(MsgConstants.ISSUE_NOT_SEND_USER)); @@ -3900,7 +3900,7 @@ for(int i=0; i < sendMails.length; i++) { sendMails[i] = CommonUtil.decryptAES128(sendMails[i]); } - this.systemEmailService.sendEmail(emailCommonForm.getTitle(), emailCommonForm.getDescription(), sendMails, null); + this.systemEmailService.sendEmail(emailCommonForm.getTitle(), emailCommonForm.getDescription(), sendMails, null, multipartFiles); if (issue != null) { this.issueHistoryService.detectSendIssueMail(IssueHistoryType.SEND, emailCommonForm.getSendEmails(), sb); diff --git a/src/main/java/kr/wisestone/owl/service/impl/SystemEmailServiceImpl.java b/src/main/java/kr/wisestone/owl/service/impl/SystemEmailServiceImpl.java index 992923b..2398cb2 100644 --- a/src/main/java/kr/wisestone/owl/service/impl/SystemEmailServiceImpl.java +++ b/src/main/java/kr/wisestone/owl/service/impl/SystemEmailServiceImpl.java @@ -22,6 +22,7 @@ import kr.wisestone.owl.service.UserService; import kr.wisestone.owl.util.*; import org.apache.commons.io.FilenameUtils; +import org.flywaydb.core.internal.util.scanner.filesystem.FileSystemResource; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -38,12 +39,11 @@ import javax.activation.DataSource; import javax.activation.FileDataSource; import javax.mail.SendFailedException; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeUtility; +import javax.mail.internet.*; import java.io.IOException; import java.util.*; +import org.springframework.web.multipart.MultipartFile; import org.thymeleaf.context.Context; import org.thymeleaf.spring5.SpringTemplateEngine; @@ -224,7 +224,7 @@ break; } - this.sendEmail(this.messageAccessor.message(mailConstants.getTitle(), locale), content, sendUsers, filePaths); + this.sendEmail(this.messageAccessor.message(mailConstants.getTitle(), locale), content, sendUsers, filePaths, null); } // �씠硫붿씪 �뀥�뵆由� 李얘린 @@ -262,7 +262,7 @@ // �씠硫붿씪�쓣 諛쒖넚�븳�떎. @Override @Transactional(readOnly = true) - public void sendEmail(String subject, String content, String[] to, String[] filePaths) { + public void sendEmail(String subject, String content, String[] to, String[] filePaths, List<MultipartFile> multipartFiles) { MimeMessage message = this.javaMailSender.createMimeMessage(); try { @@ -272,6 +272,13 @@ messageHelper.setText(content, true); messageHelper.setFrom(from); messageHelper.setTo(to); + + if (multipartFiles != null && multipartFiles.size() > 0) { + for (MultipartFile file : multipartFiles) { + // �뙆�씪 泥⑤� + messageHelper.addAttachment(file.getOriginalFilename(), file); + } + } if (filePaths != null && filePaths.length > 0) { for (String filePath : filePaths) { @@ -413,7 +420,7 @@ // �궡�슜�씠 �엳�쑝硫� 諛쒖넚 if (!StringUtils.isEmpty(emailBuilder.toString())) { // �씠硫붿씪�쓣 諛쒖넚�븳�떎. - this.sendEmail(this.messageAccessor.message(MsgConstants.RESERVATION_EMAIL_TITLE, locale), emailBuilder.toString(), new String[]{CommonUtil.decryptAES128(sendUser)}, null); + this.sendEmail(this.messageAccessor.message(MsgConstants.RESERVATION_EMAIL_TITLE, locale), emailBuilder.toString(), new String[]{CommonUtil.decryptAES128(sendUser)}, null, null); this.systemEmailRepository.saveAll(systemEmails); } } @@ -444,7 +451,7 @@ // �궡�슜�씠 �엳�쑝硫� 諛쒖넚 if (!StringUtils.isEmpty(emailBuilder.toString())) { // �씠硫붿씪�쓣 諛쒖넚�븳�떎. - this.sendEmail(this.messageAccessor.message(MsgConstants.REALTIME_EMAIL_TITLE, locale), emailBuilder.toString(), new String[]{CommonUtil.decryptAES128(sendUser)}, null); + this.sendEmail(this.messageAccessor.message(MsgConstants.REALTIME_EMAIL_TITLE, locale), emailBuilder.toString(), new String[]{CommonUtil.decryptAES128(sendUser)}, null, null); this.systemEmailRepository.saveAll(systemEmails); } } diff --git a/src/main/java/kr/wisestone/owl/web/controller/IssueController.java b/src/main/java/kr/wisestone/owl/web/controller/IssueController.java index 7a7dfbb..6c36f47 100644 --- a/src/main/java/kr/wisestone/owl/web/controller/IssueController.java +++ b/src/main/java/kr/wisestone/owl/web/controller/IssueController.java @@ -248,15 +248,14 @@ // �씪諛� 硫붿씪 諛쒖넚 (�궗�슜�옄 吏곸젒 �옉�꽦) - @RequestMapping(value = "/issue/sendCommonEmail", produces = MediaType.APPLICATION_JSON_VALUE) + @RequestMapping(value = "/issue/sendCommonEmail", method = RequestMethod.POST) public @ResponseBody - Map<String, Object> sendCommonEmail(@RequestBody Map<String, Map<String, Object>> params) { + Map<String, Object> sendCommonEmail(MultipartHttpServletRequest request) { Map<String, Object> resJsonData = new HashMap<>(); - this.issueService.sendCommonEmail(EmailCommonForm.make(params.get(Constants.REQ_KEY_CONTENT))); + this.issueService.sendCommonEmail(EmailCommonForm.make(ConvertUtil.convertJsonToMap(request.getParameter(Constants.REQ_KEY_CONTENT))), request.getFiles("file")); return this.setSuccessMessage(resJsonData); } - // api 湲곕줉 議고쉶 @RequestMapping(value = "/api/findHistory", produces = MediaType.APPLICATION_JSON_VALUE) diff --git a/src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js b/src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js index 6440824..086643f 100644 --- a/src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js +++ b/src/main/webapp/scripts/app/issue/issueCommonSendMail.controller.js @@ -12,7 +12,11 @@ formSubmit : formSubmit, // �뤌 �쟾�넚 formCheck : formCheck, // �뤌 泥댄겕 addInput : addInput, - removeInput : removeInput + removeInput : removeInput, + onFileSelect : onFileSelect, // �뙆�씪 泥⑤� + removeUploadFile : removeUploadFile, // �뾽濡쒕뱶�븯�젮�뒗 �듅�젙 �뙆�씪�쓣 �궘�젣 + imageUpload : imageUpload, // �꽟癒몃끂�듃 �씠誘몄� �뾽濡쒕뱶 + }; $scope.vm = { @@ -22,6 +26,8 @@ description: "", inputs : [0], emails : {}, // �엯�젰�맂 �궗�슜�옄 �씠硫붿씪 + files : [], // �뾽濡쒕뱶 �뙆�씪 + attachedFiles : [], // �꽟癒몃끂�듃濡� �뙆�씪 �뾽濡쒕뱶瑜� �븷 寃쎌슦 �꽌踰꾩뿉�꽌 pk瑜� �뵲怨� issue id�� �뿰�룞 �옉�뾽�씠 �븘�슂�븯�떎. }, userName : "", autoCompletePage : { @@ -38,6 +44,133 @@ return true; } return false; + } + + // �꽟癒몃끂�듃 �씠誘몄� �뾽濡쒕뱶 + function imageUpload($files) { + var listFiles = []; + var uploadFileSize = 0; + + for (var count in $files) { + var $file = $files[count]; + + if (typeof ($file) == "object") { + uploadFileSize += $file.size; + + // �뙆�씪�떦 �슜�웾 �젣�븳 10MB + if ($file.size > $rootScope.fileByte.image) { + SweetAlert.error($filter("translate")("issue.capacityExceededImageFile"), $filter("translate")("issue.attachedOnlyImageFiles10mb")); // "�씠誘몄� �뙆�씪 �슜�웾 珥덇낵", "10MB �씠�븯�쓽 �씠誘몄� �뙆�씪留� 泥⑤�媛� 媛��뒫�빀�땲�떎." + listFiles = []; + break; + } + + // �뿬�윭嫄댁쓽 �뙆�씪�쓣 �븳踰덉뿉 �뾽濡쒕뱶�븷 寃쎌슦 �젣�븳 300MB + if (uploadFileSize > $rootScope.fileByte.file) { + SweetAlert.error($filter("translate")("issue.capacityExceededImageFile"), $filter("translate")("issue.attachedMultipleImageFiles100mb")); // "�씠誘몄� �뙆�씪 �슜�웾 珥덇낵", "�뿬�윭 嫄댁쓽 �씠誘몄�瑜� �븳踰덉뿉 泥⑤��븷 寃쎌슦 100MB �씠�븯源뚯�留� 泥⑤�媛� 媛��뒫�빀�땲�떎." + listFiles = []; + break; + } + + if (!$rootScope.checkImageType($file)) { + SweetAlert.error($filter("translate")("issue.limitImageFile"), $filter("translate")("issue.canBeUploadedOnlyImageFiles")); // "�씠誘몄� �뙆�씪 �젣�븳", "�씠誘몄� �뙆�씪留� �뾽濡쒕뱶 媛��뒫�빀�땲�떎. - bmp, jpg, jpeg, png, tif" + listFiles = []; + break; + } + + if (!angular.isDefined($file.name)) { + var fileType = $file.type.split("/"); + var imageType = ""; + + if (fileType[0] === "image") { + imageType = "." + fileType[1]; + } + + $file.name = new Date().getTime() + imageType; + } + else { + if ($file.name.indexOf(';') !== -1) { + SweetAlert.error($filter("translate")("issue.nameErrorImageFile"), $filter("translate")("issue.cannotUploadFileNameSpecialCharacters")); // "�씠誘몄� �뙆�씪紐� �삤瑜�", "�뙆�씪紐낆뿉 �듅�닔臾몄옄(;)媛� �뱾�뼱媛�硫� �뾽濡쒕뱶 �븷 �닔 �뾾�뒿�땲�떎." + listFiles = []; + break; + } + } + + listFiles.push($file); + } + } + + // �뙆�씪 �뾽濡쒕뱶 寃�利앹쓣 嫄곗튇 �뙆�씪�씠 1媛쒖씠�긽 議댁옱�븷 寃쎌슦�뿉留� �떎�뻾 + if (listFiles.length > 0) { + AttachedFile.add({ + method : "POST", + file : listFiles, + // data �냽�꽦�쑝濡� 蹂꾨룄�쓽 �뜲�씠�꽣 �쟾�넚 + fields : { + content : { + workspaceId : $rootScope.user.lastWorkspaceId + } + }, + fileFormDataName : "file" + }) + .then(function (result) { + if (result.data.message.status === "success") { + angular.forEach(result.data.attachedFiles, function (fileInfo) { + $scope.vm.summerNote.editor.summernote("editor.insertImage", fileInfo.path); + $scope.vm.form.attachedFiles.push(fileInfo); + }); + } + else { + SweetAlert.error($filter("translate")("issue.errorFileUpload"), result.data.message.message); // �뙆�씪 �뾽濡쒕뱶 �삤瑜� + } + }); + } + } + + // �뙆�씪 �뾽濡쒕뱶�뿉 �궗�슜 + function onFileSelect($files) { + var uploadFileSize = 0; + + // �씠�쟾�뿉 泥⑤��븳 �뙆�씪�씠 �엳�쓣 寃쎌슦 �쟾泥� �뾽濡쒕뱶 �슜�웾�뿉 �룷�븿 + angular.forEach($scope.vm.form.files, function ($file) { + uploadFileSize += $file.size; + }); + + for (var count in $files) { + var $file = $files[count]; + + if (typeof ($file) == "object") { + uploadFileSize += $file.size; + + // �뙆�씪�떦 �슜�웾 �젣�븳 300MB + if (($file.size > $rootScope.fileByte.file) || (uploadFileSize > $rootScope.fileByte.file)) { + SweetAlert.error($filter("translate")("issue.attachmentCapacityExceeded"), $filter("translate")("issue.canAttachFileUpTo100mb")); // "泥⑤� �뙆�씪 �슜�웾 珥덇낵", "100MB �씠�븯源뚯�留� �뙆�씪 泥⑤�媛� 媛��뒫�빀�땲�떎." + break; + } + + // �뙆�씪�쓣 �뾽濡쒕뱶�븷 �븣 �뙆�씪 �쑀�삎�쓣 �솗�씤�빐二쇰뒗 湲곕뒫 - �뿀�슜�릺吏� �븡�� �솗�옣�옄�씪 �븣�뒗 泥⑤� 湲덉� + if (!$rootScope.checkFileType($file)) { + SweetAlert.error($filter("translate")("issue.limitAttachmentExtensions"), $filter("translate")("issue.notAllowedAttachment")); // "泥⑤� �뙆�씪 �솗�옣�옄 �젣�븳", "泥⑤�媛� �뿀�슜�릺吏� �븡�뒗 �뙆�씪�엯�땲�떎." + break; + } + + if ($file.name.indexOf(';') !== -1) { + SweetAlert.error($filter("translate")("issue.nameErrorAttachment"), $filter("translate")("issue.cannotUploadFileNameSpecialCharacters")); // "泥⑤� �뙆�씪紐� �삤瑜�", "�뙆�씪紐낆뿉 �듅�닔臾몄옄(;)媛� �뱾�뼱媛�硫� �뾽濡쒕뱶 �븷 �닔 �뾾�뒿�땲�떎." + break; + } + + $file.index = count; + $scope.vm.form.files.push($file); + } + } + } + + // �뾽濡쒕뱶 �뙆�씪 �궘�젣 + function removeUploadFile(index) { + $scope.vm.form.files.splice(index, 1); + + angular.forEach($scope.vm.form.files, function (file, index) { + file.index = index; + }); } // 硫붿씪 二쇱냼 input 李� 異붽� 踰꾪듉 @@ -78,13 +211,29 @@ }); return sendEmails; - })() + })(), + attachedFileIds : (function () { + var attachedFileIds = []; + + angular.forEach($scope.vm.form.attachedFiles, function (attachedFile) { + if ($scope.vm.form.description.indexOf(attachedFile.path) !== -1) { + attachedFileIds.push(attachedFile.id); + } + }); + + return attachedFileIds; + })(), }; - Issue.sendCommonEmail($resourceProvider.getContent( - content, - $resourceProvider.getPageContent(0, 10))).then(function (result) { - + Issue.sendCommonEmail({ + method : "POST", + file : $scope.vm.form.files, + // data �냽�꽦�쑝濡� 蹂꾨룄�쓽 �뜲�씠�꽣 �쟾�넚 + fields : { + content : content + }, + fileFormDataName : "file" + }).then(function (result) { if (result.data.message.status === "success") { SweetAlert.success($filter("translate")("issue.succeededIssueMail"), $filter("translate")("issue.sentToTheSelectedUser")); // "�씠�뒋 硫붿씪 諛쒖넚 �셿猷�" $scope.fn.cancel(); diff --git a/src/main/webapp/scripts/components/issue/issue.service.js b/src/main/webapp/scripts/components/issue/issue.service.js index d9f9086..6c5a77c 100644 --- a/src/main/webapp/scripts/components/issue/issue.service.js +++ b/src/main/webapp/scripts/components/issue/issue.service.js @@ -146,11 +146,16 @@ }); }, sendCommonEmail : function (conditions) { - return $http.post("issue/sendCommonEmail", conditions).then(function (response) { + conditions.url = "issue/sendCommonEmail"; + return $upload.upload(conditions).progress(function (evt) { + // �뙆�씪 �뾽濡쒕뱶 吏꾪뻾�쑉�쓣 �몴�떆�빐以��떎. + fileUploadProgress(evt); + + }).then(function (response) { $log.debug("�씠�뒋 �씠硫붿씪 諛쒖넚 寃곌낵 : ", response); return response; }); - } + }, } } ]) diff --git a/src/main/webapp/views/issue/issueCommonSendMail.html b/src/main/webapp/views/issue/issueCommonSendMail.html index c2f3ab4..e75e828 100644 --- a/src/main/webapp/views/issue/issueCommonSendMail.html +++ b/src/main/webapp/views/issue/issueCommonSendMail.html @@ -55,6 +55,53 @@ target=".note-editable"></summernote> </div> <small class="mt-1" translate="common.sendToPerson">�떎瑜� �궗�슜�옄�뿉寃� 硫붿씪�쓣 蹂대깄�땲�떎.</small> + + <div class="form-group mgb5 mt-10"> + <label class="issue-label"><span translate="common.attachFiles">�뙆�씪 泥⑤�</span></label> + <div class="filebox input-group"> + <input class="upload-name form-control" + placeholder="{{'users.pleaseSelectFile' | translate}}" + tabindex="-1" + disabled="disabled"> + <label for="uploadFileField"><span + translate="common.selectFile">�뙆�씪�꽑�깮</span></label> + <input id="uploadFileField" + tabindex="-1" + type="file" + class="form-control" + multiple + ng-file-select="fn.onFileSelect($files)"> + </div> + + <div class="select2-selection__choicediv"> + <div class="select2-selection__choice2" ng-repeat="file in vm.form.files"> + <div class="select2-selection__choice2__remove" ng-click="fn.removeUploadFile($index)"> + 횞 + </div> + <div class="ssg-items ssg-items-blocks"> + <div class="ssg-item"> + <div class="item-icon"> + <!-- 臾몄꽌 --> + <i class="os-icon os-icon-file-text" ng-if="file.fileType == 'DOC'"></i> + <!-- 誘몃뵒�뼱 --> + <i class="os-icon os-icon-film" ng-if="file.fileType == 'MEDIA'"></i> + <!-- �씠誘몄�(�뾽濡쒕뱶 �쟾) --> + <i class="os-icon os-icon-documents-07" + ng-if="file.fileType == 'IMAGE'"></i> + <!-- 湲고� --> + <i class="os-icon os-icon-ui-51" ng-if="file.fileType == 'ETC'"></i> + </div> + <div class="item-name"> + <small>{{file.name}}</small> + </div> + <div class="item-amount"> + ({{file.size/1024/1024 | number:2}} MB) + </div> + </div> + </div> + </div> + </div> + </div> </form> </div> -- Gitblit v1.8.0