diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java index bc2dfb03..d34dbf62 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/controller/ReportDashboardController.java @@ -11,6 +11,7 @@ import io.swagger.annotations.Api; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -72,21 +73,24 @@ public class ReportDashboardController { * @param reportCode * @return */ - @GetMapping("/export/{reportCode}") + @GetMapping("/export") @Permission(code = "view", name = "导出大屏") - public ResponseEntity exportDashboard(HttpServletRequest request, HttpServletResponse response, @PathVariable("reportCode") String reportCode) { - return reportDashboardService.exportDashboard(request, response, reportCode); + public ResponseEntity exportDashboard(HttpServletRequest request, HttpServletResponse response, + @RequestParam("reportCode") String reportCode, @RequestParam(value = "showDataSet",required = false, defaultValue = "1") Integer showDataSet) { + return reportDashboardService.exportDashboard(request, response, reportCode, showDataSet); } /** * 导入大屏 - * @param dto + * @param file 导入的zip文件 + * @param reportCode * @return */ - @PostMapping("/import") + @PostMapping("/import/{reportCode}") @Permission(code = "design", name = "导入大屏") - public ResponseBean importDashboard(@RequestBody ChartDto dto) { - return ResponseBean.builder().data(reportDashboardService.getChartData(dto)).build(); + public ResponseBean importDashboard(@RequestParam("file") MultipartFile file, @PathVariable("reportCode") String reportCode) { + reportDashboardService.importDashboard(file, reportCode); + return ResponseBean.builder().build(); } } diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/ReportDashboardService.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/ReportDashboardService.java index a3660b6a..2b8c1e35 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/ReportDashboardService.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/ReportDashboardService.java @@ -7,6 +7,7 @@ import com.anjiplus.template.gaea.business.modules.dashboard.controller.dto.Repo import com.anjiplus.template.gaea.business.modules.dashboard.controller.param.ReportDashboardParam; import com.anjiplus.template.gaea.business.modules.dashboard.dao.entity.ReportDashboard; import org.springframework.http.ResponseEntity; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -48,5 +49,13 @@ public interface ReportDashboardService extends GaeaBaseService exportDashboard(HttpServletRequest request, HttpServletResponse response, String reportCode); + ResponseEntity exportDashboard(HttpServletRequest request, HttpServletResponse response, String reportCode, Integer showDataSet); + + /** + * 导入大屏zip + * @param file + * @param reportCode + * @return + */ + void importDashboard(MultipartFile file, String reportCode); } diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/ReportDashboardServiceImpl.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/ReportDashboardServiceImpl.java index 0a99526f..f20529e6 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/ReportDashboardServiceImpl.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/dashboard/service/impl/ReportDashboardServiceImpl.java @@ -43,6 +43,7 @@ import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -133,7 +134,7 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi * @param dto */ @Override - @Transactional + @Transactional(rollbackFor = Exception.class) public void insertDashboard(ReportDashboardObjectDto dto) { String reportCode = dto.getReportCode(); GaeaAssert.notEmpty(reportCode, ResponseCode.PARAM_IS_NULL, "reportCode"); @@ -149,6 +150,7 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi } else { //更新 dashboard.setId(reportDashboard.getId()); + dashboard.setVersion(null); this.update(dashboard); } @@ -202,7 +204,7 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi * @return */ @Override - public ResponseEntity exportDashboard(HttpServletRequest request, HttpServletResponse response, String reportCode) { + public ResponseEntity exportDashboard(HttpServletRequest request, HttpServletResponse response, String reportCode, Integer showDataSet) { String userAgent = request.getHeader("User-Agent"); boolean isIeBrowser = userAgent.indexOf("MSIE") > 0; @@ -225,6 +227,16 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi zipLoadImage(imageAddress, path); }); + //showDataSet == 0 代表不包含数据集 + if (0 == showDataSet) { + detail.getWidgets().forEach(reportDashboardWidgetDto -> { + ReportDashboardWidgetValueDto value = reportDashboardWidgetDto.getValue(); + JSONObject data = value.getData(); + if (null != data && data.containsKey("dataType")) { + reportDashboardWidgetDto.getValue().getData().put("dataType", "staticData"); + } + }); + } //2.将大屏设计到的json文件保存 @@ -248,13 +260,101 @@ public class ReportDashboardServiceImpl implements ReportDashboardService, Initi builder.header("Content-Disposition", "attacher; filename*=UTF-8''" + reportCode + ".zip"); } + ResponseEntity body = builder.body(FileUtils.readFileToByteArray(file)); + //删除zip文件 file.delete(); //删除path临时文件夹 FileUtil.delete(path); log.info("删除临时文件:{},{}", zipPath, path); - return builder.body(FileUtils.readFileToByteArray(file)); + return body; + } + + /** + * 导入大屏zip + * + * @param file + * @param reportCode + * @return + */ + @Override + @Transactional(rollbackFor = Exception.class) + public void importDashboard(MultipartFile file, String reportCode) { + log.info("导入开始,{}", reportCode); + //1.组装临时目录,/app/disk/upload/zip/临时文件夹 + String path = dictPath + ZIP_PATH + UuidUtil.generateShortUuid(); + //2.解压 + FileUtil.decompress(file, path); + // path/uuid/ + File parentPath = new File(path); + //获取打包的第一层目录 + File firstFile = parentPath.listFiles()[0]; + + File[] files = firstFile.listFiles(); + + //定义map + Map fileMap = new HashMap<>(); + String content = ""; + + for (int i = 0; i < files.length; i++) { + File childFile = files[i]; + if (JSON_PATH.equals(childFile.getName())) { + //json文件 + content = FileUtil.readFile(childFile); + } else if ("image".equals(childFile.getName())) { + File[] imageFiles = childFile.listFiles(); + //所有需要上传的图片 + for (File imageFile : imageFiles) { + //查看是否存在此image + String name = imageFile.getName(); + String fileName = imageFile.getName().split("\\.")[0]; + //根据fileId,从gaea_file中读出filePath + LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(); + queryWrapper.eq(GaeaFile::getFileId, fileName); + GaeaFile gaeaFile = gaeaFileService.selectOne(queryWrapper); + if (null == gaeaFile) { + GaeaFile upload = gaeaFileService.upload(null, imageFile, fileName); + fileMap.put(fileName, upload.getUrlPath()); + } + } + } + + } + + + + //解析cotent + ReportDashboardObjectDto detail = JSONObject.parseObject(content, ReportDashboardObjectDto.class); + //将涉及到的图片路径替换(1.背景图,2.组件为图片的) + String backgroundImage = detail.getDashboard().getBackgroundImage(); + detail.getDashboard().setBackgroundImage(replaceUrl(backgroundImage, fileMap)); + detail.getWidgets().stream() + .filter(reportDashboardWidgetDto -> "widget-image".equals(reportDashboardWidgetDto.getType())) + .forEach(reportDashboardWidgetDto -> { + String imageAddress = reportDashboardWidgetDto.getValue().getSetup().getString("imageAdress"); + String address = replaceUrl(imageAddress, fileMap); + reportDashboardWidgetDto.getValue().getSetup().put("imageAdress", address); + reportDashboardWidgetDto.getOptions().getJSONArray("setup").getJSONObject(4).put("value", address); + }); + //将新的大屏编码赋值 + detail.setReportCode(reportCode); + + //解析结束,删除临时文件夹 + FileUtil.delete(path); + + log.info("解析成功,开始存入数据库..."); + insertDashboard(detail); + } + + + private String replaceUrl(String imageAddress, Map fileMap) { + String fileId = imageAddress.substring(imageAddress.trim().length() - 36); + String orDefault = fileMap.getOrDefault(fileId, null); + if (StringUtils.isBlank(orDefault)) { + return imageAddress; + } + return orDefault; } /** diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/controller/GaeaFileController.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/controller/GaeaFileController.java index d0d45afc..9a900159 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/controller/GaeaFileController.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/controller/GaeaFileController.java @@ -33,7 +33,7 @@ public class GaeaFileController extends BaseController { - /** * 文件上传 * * @param file * @return 文件访问路径 */ - GaeaFile upload(MultipartFile file); - + GaeaFile upload(MultipartFile multipartFile, File file, String customFileName); /** * 根据fileId显示图片或者下载文件 * diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/service/impl/GaeaFileServiceImpl.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/service/impl/GaeaFileServiceImpl.java index 9771a70b..8eaee1de 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/service/impl/GaeaFileServiceImpl.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/modules/file/service/impl/GaeaFileServiceImpl.java @@ -10,6 +10,7 @@ import com.anjiplus.template.gaea.business.modules.file.entity.GaeaFile; import com.anjiplus.template.gaea.business.modules.file.service.GaeaFileService; import com.anjiplus.template.gaea.business.modules.file.util.FileUtils; import com.anjiplus.template.gaea.business.modules.file.util.StringPatternUtil; +import com.anjiplus.template.gaea.business.util.FileUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import lombok.extern.slf4j.Slf4j; @@ -64,11 +65,18 @@ public class GaeaFileServiceImpl implements GaeaFileService { return gaeaFileMapper; } + @Override @Transactional(rollbackFor = Exception.class) - public GaeaFile upload(MultipartFile file) { + public GaeaFile upload(MultipartFile multipartFile, File file, String customFileName) { try { - String fileName = file.getOriginalFilename(); + String fileName = ""; + if (null != multipartFile) { + fileName = multipartFile.getOriginalFilename(); + }else { + fileName = file.getName(); + } + if (StringUtils.isBlank(fileName)) { throw BusinessExceptionBuilder.build(ResponseCode.FILE_EMPTY_FILENAME); } @@ -82,7 +90,12 @@ public class GaeaFileServiceImpl implements GaeaFileService { throw BusinessExceptionBuilder.build(ResponseCode.FILE_SUFFIX_UNSUPPORTED); } // 生成文件唯一性标识 - String fileId = UUID.randomUUID().toString(); + String fileId; + if (StringUtils.isBlank(customFileName)) { + fileId = UUID.randomUUID().toString(); + } else { + fileId = customFileName; + } String newFileName = fileId + suffixName; // 本地文件保存路径 String filePath = dictPath + newFileName; @@ -102,7 +115,11 @@ public class GaeaFileServiceImpl implements GaeaFileService { if (!parentFile.exists()) { parentFile.mkdirs(); } - file.transferTo(dest); + if (null != multipartFile) { + multipartFile.transferTo(dest); + }else { + FileUtil.copyFileUsingFileChannels(file, dest); + } // 将完整的http访问路径返回 return gaeaFile; } catch (Exception e) { diff --git a/report-core/src/main/java/com/anjiplus/template/gaea/business/util/FileUtil.java b/report-core/src/main/java/com/anjiplus/template/gaea/business/util/FileUtil.java index 708cf7d4..8a81f0c1 100644 --- a/report-core/src/main/java/com/anjiplus/template/gaea/business/util/FileUtil.java +++ b/report-core/src/main/java/com/anjiplus/template/gaea/business/util/FileUtil.java @@ -3,6 +3,7 @@ package com.anjiplus.template.gaea.business.util; import com.anji.plus.gaea.code.ResponseCode; import com.anji.plus.gaea.exception.BusinessExceptionBuilder; import lombok.extern.slf4j.Slf4j; +import org.springframework.web.multipart.MultipartFile; import java.io.*; import java.net.URL; @@ -90,6 +91,11 @@ public class FileUtil { public static void WriteStringToFile(String filePath, String content) { try { + //不存在创建文件 + File file = new File(filePath); + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } FileWriter fw = new FileWriter(filePath); BufferedWriter bw = new BufferedWriter(fw); bw.write(content); @@ -241,23 +247,45 @@ public class FileUtil { } } + public static void decompress(String zipFile, String dstPath) { + try { + decompress(new ZipFile(zipFile), dstPath); + } catch (IOException e) { + log.error("", e); + throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage()); + } + } + + public static void decompress(MultipartFile zipFile, String dstPath) { + try { + File file = new File(dstPath + File.separator + zipFile.getOriginalFilename()); + if (!file.getParentFile().exists()) { + file.getParentFile().mkdirs(); + } + zipFile.transferTo(file); + decompress(new ZipFile(file), dstPath); + //解压完删除 + file.delete(); + } catch (IOException e) { + log.error("", e); + throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage()); + } + } /** * 解压zip * - * @param zipFile + * @param zip * @param dstPath * @throws IOException */ - public static void decompress(String zipFile, String dstPath) { - log.info("解压zip:{},临时目录:{}", zipFile, dstPath); + public static void decompress(ZipFile zip, String dstPath) { + log.info("解压zip:{},临时目录:{}", zip.getName(), dstPath); File pathFile = new File(dstPath); if (!pathFile.exists()) { pathFile.mkdirs(); } - ZipFile zip = null; try { - zip = new ZipFile(zipFile); for (Enumeration entries = zip.entries(); entries.hasMoreElements(); ) { ZipEntry entry = (ZipEntry) entries.nextElement(); @@ -314,8 +342,30 @@ public class FileUtil { } } + /** + * 获取流文件 + * @param ins + * @param file + */ + private static void inputStreamToFile(InputStream ins, File file) { + try { + OutputStream os = new FileOutputStream(file); + int bytesRead = 0; + byte[] buffer = new byte[8192]; + while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) { + os.write(buffer, 0, bytesRead); + } + os.close(); + ins.close(); + } catch (Exception e) { + log.error("获取流文件失败", e); + throw BusinessExceptionBuilder.build(ResponseCode.FAIL_CODE, e.getMessage()); + } + } + /** * 删除文件夹 + * * @param path */ public static void delete(String path) { @@ -357,7 +407,6 @@ public class FileUtil { // FileUtil.downloadPicture("http://10.108.26.197:9095/file/download/fd20d563-00aa-45e2-b5db-aff951f814ec", "D:\\abc.png"); - // delete("D:\\aa"); } diff --git a/report-ui/src/api/bigscreen.js b/report-ui/src/api/bigscreen.js index ef090d96..69555fc0 100644 --- a/report-ui/src/api/bigscreen.js +++ b/report-ui/src/api/bigscreen.js @@ -52,7 +52,7 @@ export function exportDashboard(data) { return new Promise((resolve) =>{ axios({ method:'get', - url: process.env.BASE_API + '/reportDashboard/export/' + data, + url: process.env.BASE_API + '/reportDashboard/export', headers: { 'Authorization': getToken() }, params:data, responseType:'blob' diff --git a/report-ui/src/views/report/bigscreen/designer/index.vue b/report-ui/src/views/report/bigscreen/designer/index.vue index 3f4a6ba4..53ba99fe 100644 --- a/report-ui/src/views/report/bigscreen/designer/index.vue +++ b/report-ui/src/views/report/bigscreen/designer/index.vue @@ -59,7 +59,7 @@ :style="{ width: widthLeftForToolsHideButton + 'px' }" @click="toolIsShow = !toolIsShow" > - +
- - - - - - + + + + - + +