From 1508e03ba6a805da6c7c6bd4c354124ff5a9dacc Mon Sep 17 00:00:00 2001 From: wangxianzhang Date: Tue, 22 Feb 2022 08:53:25 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=EF=BC=9A=201.oss=E6=8E=A5?= =?UTF-8?q?=E5=8F=97=E5=AF=BC=E5=85=A5=E4=BB=BB=E5=8A=A1=E6=8F=8F=E8=BF=B0?= =?UTF-8?q?=E6=96=87=E4=BB=B6=E7=9A=84=E6=8E=A5=E5=8F=A3=20=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=EF=BC=9A=201.=E5=B1=85=E6=B0=91=E4=BF=A1=E6=81=AF?= =?UTF-8?q?=E5=AF=BC=E5=85=A5=EF=BC=8C=E7=94=9F=E6=88=90excel=E6=96=87?= =?UTF-8?q?=E4=BB=B6=EF=BC=8C=E4=BC=A0=E9=80=81=E5=88=B0oss=EF=BC=8C?= =?UTF-8?q?=E8=80=8C=E4=B8=8D=E5=86=8D=E4=B8=8B=E8=BD=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/epmet/feign/OssFeignClient.java | 18 ++- .../fallback/OssFeignClientFallback.java | 5 + .../com/epmet/controller/OssController.java | 11 ++ .../controller/IcResiUserController.java | 38 ++++-- .../service/IcResiUserImportService.java | 3 +- .../impl/IcResiUserImportServiceImpl.java | 114 ++++++++++-------- .../service/impl/IcResiUserServiceImpl.java | 3 + 7 files changed, 129 insertions(+), 63 deletions(-) diff --git a/epmet-module/epmet-oss/epmet-oss-client/src/main/java/com/epmet/feign/OssFeignClient.java b/epmet-module/epmet-oss/epmet-oss-client/src/main/java/com/epmet/feign/OssFeignClient.java index 60697791d7..f1144b878d 100644 --- a/epmet-module/epmet-oss/epmet-oss-client/src/main/java/com/epmet/feign/OssFeignClient.java +++ b/epmet-module/epmet-oss/epmet-oss-client/src/main/java/com/epmet/feign/OssFeignClient.java @@ -14,7 +14,11 @@ import com.epmet.dto.result.UploadImgResultDTO; import com.epmet.feign.fallback.OssFeignClientFallbackFactory; import feign.codec.Encoder; import feign.form.spring.SpringFormEncoder; +import org.springframework.beans.factory.ObjectFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.http.HttpMessageConverters; import org.springframework.cloud.openfeign.FeignClient; +import org.springframework.cloud.openfeign.support.SpringEncoder; import org.springframework.context.annotation.Bean; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; @@ -64,12 +68,24 @@ public interface OssFeignClient { @GetMapping(value = "oss/file/getOssFileUrl") Result getOssFileUrl(@RequestParam String filePath, @RequestParam String privacy); + /** + * 上传任务描述文件 + * 不限制大小 + * @param file + * @return + */ + @PostMapping(value = "oss/file/importTaskDescFile/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + Result uploadImportTaskDescFile(@RequestPart("file") MultipartFile file); //@Configuration class MultipartSupportConfig { + + @Autowired + private ObjectFactory messageConverters; + @Bean public Encoder feignFormEncoder() { - return new SpringFormEncoder(); + return new SpringFormEncoder(new SpringEncoder(messageConverters)); } } diff --git a/epmet-module/epmet-oss/epmet-oss-client/src/main/java/com/epmet/feign/fallback/OssFeignClientFallback.java b/epmet-module/epmet-oss/epmet-oss-client/src/main/java/com/epmet/feign/fallback/OssFeignClientFallback.java index dc43ed7467..805c2fc492 100644 --- a/epmet-module/epmet-oss/epmet-oss-client/src/main/java/com/epmet/feign/fallback/OssFeignClientFallback.java +++ b/epmet-module/epmet-oss/epmet-oss-client/src/main/java/com/epmet/feign/fallback/OssFeignClientFallback.java @@ -50,4 +50,9 @@ public class OssFeignClientFallback implements OssFeignClient { return ModuleUtils.feignConError(ServiceConstant.EPMET_OSS_SERVER, "download", filePath,privacy); } + @Override + public Result uploadImportTaskDescFile(MultipartFile file) { + return ModuleUtils.feignConError(ServiceConstant.EPMET_OSS_SERVER, "uploadImportTaskDescFile", "MultipartFile"); + } + } diff --git a/epmet-module/epmet-oss/epmet-oss-server/src/main/java/com/epmet/controller/OssController.java b/epmet-module/epmet-oss/epmet-oss-server/src/main/java/com/epmet/controller/OssController.java index ac84d4d820..1b79042fbc 100644 --- a/epmet-module/epmet-oss/epmet-oss-server/src/main/java/com/epmet/controller/OssController.java +++ b/epmet-module/epmet-oss/epmet-oss-server/src/main/java/com/epmet/controller/OssController.java @@ -437,4 +437,15 @@ public class OssController { return new Result().ok(ossService.getOssFileUrl(filePath,privacy)); } + /** + * 上传任务描述文件 + * 不限制大小 + * @param file + * @return + */ + @PostMapping("/importTaskDescFile/upload") + public Result uploadImportTaskDescFile(@RequestPart("file") MultipartFile file) { + return ossService.uploadImg(file, null); + } + } diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/IcResiUserController.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/IcResiUserController.java index defa71958e..7e4879882c 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/IcResiUserController.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/controller/IcResiUserController.java @@ -443,26 +443,44 @@ public class IcResiUserController implements ResultDataResolver { // 记录导入任务 importTaskId = icResiUserImportService.createImportTaskRecord(operatorId, ImportTaskConstants.BIZ_TYPE_RESI); - // 开始执行导入 - Path savePath = null; + // 转储文件到临时目录 && 执行异步导入 + submitResiImportTask(customerId, operatorId, importTaskId, extension, file, response); +// ServletRequestAttributes sra = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); +// CompletableFuture.runAsync(() -> { +// RequestContextHolder.setRequestAttributes(sra, true); +// submitResiImportTask(customerId, operatorId, importTaskId, extension, file, response); +// }); + } + + /** + * 提交居民导入任务 + * @param customerId + * @param operatorId + * @param importTaskId + * @param extension + * @param file + * @param response + */ + private void submitResiImportTask(String customerId, String operatorId, String importTaskId, String extension, MultipartFile file, HttpServletResponse response) { + + Path importTempFileSavePath = null; try { String fileName = UUID.randomUUID().toString().concat(".").concat(extension); - savePath = IC_RESI_UPLOAD_DIR.resolve(fileName); + importTempFileSavePath = IC_RESI_UPLOAD_DIR.resolve(fileName); + IOUtils.copy(file.getInputStream(), new FileOutputStream(importTempFileSavePath.toString())); - IOUtils.copy(file.getInputStream(), new FileOutputStream(savePath.toString())); List formItemList = icResiUserService.listFormItems(customerId,IcFormCodeEnum.RESI_BASE_INFO.getCode()); - - icResiUserImportService.importIcResiInfoFromExcel(importTaskId, formItemList, savePath.toString(), response); + icResiUserImportService.importIcResiInfoFromExcel(importTaskId, formItemList, importTempFileSavePath.toString(), response, IC_RESI_UPLOAD_DIR); } catch (Throwable e) { String errorMsg = ExceptionUtils.getThrowableErrorStackTrace(e); log.error("【导入居民信息失败】导入失败:{}", errorMsg); - // 要将导入任务状态设置为结束但不成功。不报错即成功,没有返回值 TODO 此处要改,将oss返回的路径存储到resultDescPath中 - icResiUserImportService.finishImportTask(importTaskId, operatorId, ImportTaskConstants.PROCESS_STATUS_FINISHED_FAIL, null, null); + // 要将导入任务状态设置为结束但不成功。不报错即成功,没有返回值 + icResiUserImportService.finishImportTask(importTaskId, operatorId, ImportTaskConstants.PROCESS_STATUS_FINISHED_FAIL, "系统异常,请查看系统日志", null); } finally { try { - if (savePath != null){ - Files.delete(savePath); + if (importTempFileSavePath != null){ + Files.delete(importTempFileSavePath); } } catch (IOException e) { log.error("【导入居民信息失败】清理上传的文件失败:{}", ExceptionUtils.getErrorStackTrace(e)); diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/IcResiUserImportService.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/IcResiUserImportService.java index 8cdd76d3ab..18618dc128 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/IcResiUserImportService.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/IcResiUserImportService.java @@ -3,6 +3,7 @@ package com.epmet.service; import com.epmet.dto.result.FormItemResult; import javax.servlet.http.HttpServletResponse; +import java.nio.file.Path; import java.util.List; /** @@ -12,7 +13,7 @@ import java.util.List; */ public interface IcResiUserImportService { - void importIcResiInfoFromExcel(String importTaskId, List formItemList, String excelPathName, HttpServletResponse response); + void importIcResiInfoFromExcel(String importTaskId, List formItemList, String excelPathName, HttpServletResponse response, Path importTempPath); /** * 创建导入任务 diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java index 981db445f2..8606ffa7df 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserImportServiceImpl.java @@ -45,15 +45,19 @@ import com.google.common.cache.CacheBuilder; import lombok.Data; import lombok.extern.slf4j.Slf4j; import org.apache.commons.collections4.CollectionUtils; +import org.apache.commons.fileupload.FileItem; +import org.apache.commons.fileupload.FileItemFactory; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.lang3.StringUtils; +import org.apache.http.entity.ContentType; import org.apache.poi.ss.usermodel.Workbook; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.web.multipart.commons.CommonsMultipartFile; import javax.servlet.http.HttpServletResponse; -import java.io.File; -import java.io.IOException; -import java.net.URLEncoder; +import java.io.*; +import java.nio.file.Path; import java.util.*; import java.util.stream.Collectors; @@ -125,6 +129,8 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res @Autowired private EpmetCommonServiceOpenFeignClient commonServiceOpenFeignClient; + @Autowired + private OssFeignClient ossFeignClient; /** * 字表中不需要的列 @@ -217,7 +223,7 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res * @param response 响应对象 */ @Override - public void importIcResiInfoFromExcel(String importTaskId, List formItemList, String excelPathName, HttpServletResponse response) { + public void importIcResiInfoFromExcel(String importTaskId, List formItemList, String excelPathName, HttpServletResponse response, Path importTempPath) { String loginUserId = loginUserUtil.getLoginUserId(); String loginUserApp = loginUserUtil.getLoginUserApp(); @@ -268,26 +274,22 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res Map categoryChangedResis = newlyOrChangedResi.get().getCategoryChangedResis(); Map transferedResis = newlyOrChangedResi.get().getTransferedResis(); - log.info("类别变动居民数:{}", categoryChangedResis.size()); - log.info("调动居民数:{}", transferedResis.size()); - //保存调动或者变更记录 saveNewResiCategoryRecord(); saveResiCategoryChangedRecord(categoryChangedResis); saveTransferedResiRecord(transferedResis); - hasErrorRows = hasErrorRows(); - - try { - // todo 做了导入记录之后,这里就要判断,没有错误就不生成文件了 - downLoadResults(hasErrorRows, response); - } catch (Exception e) { - log.error("【导入IC居民附加信息】下载导入结果信息失败:{}", ExceptionUtils.getErrorStackTrace(e)); - } - - // 更新上传记录 - if (hasErrorRows) { - finishImportTask(importTaskId, loginUserId, ImportTaskConstants.PROCESS_STATUS_FINISHED_FAIL,null, null); + // 生成错误描述文件 && 更新上传记录 + LinkedList errorRows = getErrorRows(); + if (CollectionUtils.isNotEmpty(errorRows)) { + String resultDescFilePath = null; + try { + resultDescFilePath = generateResultDescFile(errorRows, importTempPath); + } catch (Exception e) { + String errorMsg = ExceptionUtils.getErrorStackTrace(e); + log.error("【居民信息导入】", errorMsg); + } + finishImportTask(importTaskId, loginUserId, ImportTaskConstants.PROCESS_STATUS_FINISHED_FAIL,null, resultDescFilePath); } else { finishImportTask(importTaskId, loginUserId, ImportTaskConstants.PROCESS_STATUS_FINISHED_SUCCESS,null, null); } @@ -314,19 +316,16 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res } /** - * 是否有错误行 + * 返回错误行 * @return */ - private Boolean hasErrorRows() { - boolean hasError = false; - Map> tableAndErrorRows = errorRows.get(); - for (Map.Entry> entry:tableAndErrorRows.entrySet()) { - if (entry.getValue().size() != 0) { - hasError = true; - } + private LinkedList getErrorRows() { + LinkedList list = new LinkedList<>(); + for (Map.Entry> entry : errorRows.get().entrySet()) { + list.addAll(entry.getValue()); } - return hasError; + return list; } /** @@ -1027,34 +1026,47 @@ public class IcResiUserImportServiceImpl implements IcResiUserImportService, Res } /** - * 下载导入结果 - * @param response + * 生成导入结果 * @throws IOException */ - public void downLoadResults(Boolean hasErrorRows, HttpServletResponse response) throws IOException { - String fileName; - - // 判断是否有错误信息,以确定文件名 - if (hasErrorRows) { - fileName = "导入失败条目清单.xls"; - } else { - fileName = "导入成功.xls"; + public String generateResultDescFile(LinkedList errorRows, Path importTempDir) throws IOException { + errorRows.forEach(row -> {row.setSheetName(IcResiUserTableEnum.getObjectByTableName(row.tableName).getTableComment());}); + Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("导入失败的数据列表","导入失败的数据列表"), + ErrorRow.class, errorRows); + + // 文件名 + String resultDescFileName = UUID.randomUUID().toString().concat(".xls"); + + FileItemFactory factory = new DiskFileItemFactory(16, null); + FileItem fileItem = factory.createItem("file", ContentType.APPLICATION_OCTET_STREAM.toString(), true, resultDescFileName); + OutputStream os = fileItem.getOutputStream(); + Result uploadResult = null; + try { + workbook.write(os); + uploadResult = ossFeignClient.uploadImportTaskDescFile(new CommonsMultipartFile(fileItem)); + } catch (Exception e) { + String errormsg = ExceptionUtils.getErrorStackTrace(e); + log.error("【居民信息导入】上传错误描述文件:{}", errormsg); + } finally { + try { + os.close(); + } catch (IOException e) { + String errormsg = ExceptionUtils.getErrorStackTrace(e); + log.error("【居民信息导入】上传错误描述文件关闭输出流:{}", errormsg); + } + try { + fileItem.delete(); + } catch (Exception e) { + String errormsg = ExceptionUtils.getErrorStackTrace(e); + log.error("【居民信息导入】上传错误描述文件删除临时文件:{}", errormsg); + } } - response.setHeader("Access-Control-Expose-Headers", "Content-Disposition"); - response.setHeader("content-Type", "application/vnd.ms-excel"); - response.setHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8")); - LinkedList list = new LinkedList<>(); - for (Map.Entry> entry : errorRows.get().entrySet()) { - list.addAll(entry.getValue()); + if (uploadResult == null || !uploadResult.success()) { + log.error("【居民信息导入】调用OSS上传结果描述文件失败"); + return null; } - - list.forEach(row -> {row.setSheetName(IcResiUserTableEnum.getObjectByTableName(row.tableName).getTableComment());}); - - Workbook workbook = ExcelExportUtil.exportExcel(new ExportParams("导入失败的列表","导入失败列表(没有数据说明全部成功)"), - ErrorRow.class, list); - - workbook.write(response.getOutputStream()); + return uploadResult.getData().getUrl(); } /** diff --git a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserServiceImpl.java b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserServiceImpl.java index 5709333e9b..c548da27b2 100644 --- a/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserServiceImpl.java +++ b/epmet-user/epmet-user-server/src/main/java/com/epmet/service/impl/IcResiUserServiceImpl.java @@ -42,8 +42,10 @@ import com.epmet.commons.tools.redis.common.CustomerStaffRedis; import com.epmet.commons.tools.redis.common.bean.AgencyInfoCache; import com.epmet.commons.tools.redis.common.bean.GridInfoCache; import com.epmet.commons.tools.security.dto.TokenDto; +import com.epmet.commons.tools.security.user.LoginUserUtil; import com.epmet.commons.tools.utils.ConvertUtils; import com.epmet.commons.tools.utils.DateUtils; +import com.epmet.commons.tools.utils.HttpContextUtils; import com.epmet.commons.tools.utils.Result; import com.epmet.constant.IcPlatformConstant; import com.epmet.constant.IcResiUserConstant; @@ -72,6 +74,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import javax.servlet.http.HttpServletRequest; import java.math.BigDecimal; import java.math.RoundingMode; import java.sql.Date;