From 5daa101fccd0588e2b900ffa66cf1681aebff6d5 Mon Sep 17 00:00:00 2001 From: bawei <95887577@qq.com> Date: Wed, 1 Mar 2023 16:53:47 +0800 Subject: [PATCH] =?UTF-8?q?DevUtils=E6=96=87=E4=BB=B6=E4=B8=8A=E4=BC=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../jnpf/controller/DevUtilsController.java | 552 ++++++++++++++++++ 1 file changed, 552 insertions(+) create mode 100644 SC-boot/linkage-file/src/main/java/jnpf/controller/DevUtilsController.java diff --git a/SC-boot/linkage-file/src/main/java/jnpf/controller/DevUtilsController.java b/SC-boot/linkage-file/src/main/java/jnpf/controller/DevUtilsController.java new file mode 100644 index 00000000..c575cb1f --- /dev/null +++ b/SC-boot/linkage-file/src/main/java/jnpf/controller/DevUtilsController.java @@ -0,0 +1,552 @@ +package jnpf.controller; + +import com.alibaba.fastjson.JSONObject; +import io.swagger.annotations.Api; +import io.swagger.annotations.ApiOperation; +import jnpf.base.ActionResult; +import jnpf.base.NoDataSourceBind; +import jnpf.base.UserInfo; +import jnpf.base.entity.DictionaryDataEntity; +import jnpf.base.service.DictionaryDataService; +import jnpf.base.util.OptimizeUtil; +import jnpf.base.vo.DownloadVO; +import jnpf.base.vo.ListVO; +import jnpf.config.ConfigValueUtil; +import jnpf.constant.MsgCode; +import jnpf.exception.DataException; +import jnpf.model.*; +import jnpf.util.*; +import jnpf.util.enums.FileTypeEnum; +import jnpf.util.file.StorageType; +import jnpf.util.file.UploadUtil; +import jnpf.util.minio.MinioUploadUtil; +import jnpf.utils.YozoUtils; +import lombok.Cleanup; +import org.apache.commons.io.FileUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.*; +import java.nio.channels.Channels; +import java.nio.channels.FileChannel; +import java.nio.channels.WritableByteChannel; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +/** + * @Author: WangChuang + * @Date: 1/3/2023 下午3:03 + * @Description //注释: + * @Version 1.0 + */ +@Api(tags = "公共", value = "file") +@RestController +@RequestMapping("/dev/api/file") +public class DevUtilsController { + + @Autowired + private ConfigValueUtil configValueUtil; + @Autowired + private RedisUtil redisUtil; + @Autowired + private UserProvider userProvider; + @Autowired + private DictionaryDataService dictionaryDataService; + @Autowired + private YozoUtils yozoUtils; + @Autowired + private MinioUploadUtil minioUploadUtil; + + /** + * 语言列表 + * + * @return + */ + @ApiOperation("语言列表") + @GetMapping("/Language") + public ActionResult> getList() { + String dictionaryTypeId = "dc6b2542d94b407cac61ec1d59592901"; + List list = dictionaryDataService.getList(dictionaryTypeId); + List language = JsonUtil.getJsonToList(list, LanguageVO.class); + ListVO vo = new ListVO(); + vo.setList(language); + return ActionResult.success(vo); + } + + /** + * 图形验证码 + * + * @return + */ + @NoDataSourceBind() + @ApiOperation("图形验证码") + @GetMapping("/ImageCode/{timestamp}") + public void imageCode(@PathVariable("timestamp") String timestamp) { + DownUtil.downCode(null); + redisUtil.insert(timestamp, ServletUtil.getSession().getAttribute(CodeUtil.RANDOMCODEKEY), 120); + } + + /** + * 上传文件/图片 + * + * @return + */ + @NoDataSourceBind() + @ApiOperation("上传文件/图片") + @PostMapping(value = "/Uploader/{type}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) + public ActionResult uploader(@RequestPart("file") MultipartFile file, @PathVariable("type") String type) throws IOException { + String fileType = UpUtil.getFileType(file); + //验证类型 + if (!OptimizeUtil.fileType(configValueUtil.getAllowUploadFileType(), fileType)) { + return ActionResult.fail(MsgCode.FA017.get()); + } + UploaderVO vo = uploaderVO(file, type); + + return ActionResult.success(vo); + } + + /** + * 获取下载文件链接 + * + * @return + */ + @NoDataSourceBind() + @ApiOperation("获取下载文件链接") + @GetMapping("/Download/{type}/{fileName}") + public ActionResult downloadUrl(@PathVariable("type") String type, @PathVariable("fileName") String fileName) { + type = XSSEscape.escape(type); + fileName = XSSEscape.escape(fileName); + UserInfo userInfo = userProvider.get(); + if (!configValueUtil.getFileType().equals(StorageType.STORAGE)) { + DownloadVO vo = DownloadVO.builder().name(fileName).url(UploaderUtil.uploaderFile(userInfo.getId() + "#" + fileName + "#" + type)).build(); + return ActionResult.success(vo); + } + String filePath = FilePathUtil.getFilePath(type) + fileName; + if (FileUtil.fileIsFile(filePath)) { + DownloadVO vo = DownloadVO.builder().name(fileName).url(UploaderUtil.uploaderFile(userInfo.getId() + "#" + fileName + "#" + type)).build(); + return ActionResult.success(vo); + } + return ActionResult.fail(MsgCode.FA018.get()); + } + + /** + * 下载文件链接 + * + * @return + */ + @NoDataSourceBind() + @ApiOperation("下载文件链接") + @GetMapping("/Download") + public void downloadFile() throws DataException { + HttpServletRequest request = ServletUtil.getRequest(); + String reqJson = request.getParameter("encryption"); + String name = request.getParameter("name"); + String fileNameAll = DesUtil.aesDecode(reqJson); + if (!StringUtil.isEmpty(fileNameAll)) { + String[] data = fileNameAll.split("#"); + String token = data.length > 0 ? data[0] : ""; + //验证token + if (redisUtil.exists(token)) { + String fileName = data.length > 1 ? data[1] : ""; + String type = data.length > 2 ? data[2] : ""; + String filePath = FilePathUtil.getFilePath(type.toLowerCase()); + //下载文件 + UploadUtil.downFile(configValueUtil.getFileType(), fileName, type, filePath, name); + } else { + throw new DataException("token验证失败"); + } + } + } + + /** + * 下载文件链接 + * + * @return + */ + @NoDataSourceBind() + @ApiOperation("下载模板文件链接") + @GetMapping("/DownloadModel") + public void downloadModel() throws DataException { + HttpServletRequest request = ServletUtil.getRequest(); + String reqJson = request.getParameter("encryption"); + String fileNameAll = DesUtil.aesDecode(reqJson); + if (!StringUtil.isEmpty(fileNameAll)) { + String token = fileNameAll.split("#")[0]; + if (redisUtil.exists(token)) { + String fileName = fileNameAll.split("#")[1]; + String filePath = configValueUtil.getTemplateFilePath(); + //下载文件 + UploadUtil.downFile(configValueUtil.getFileType(), fileName, FileTypeEnum.TEMPLATEFILE, filePath, null); + } + } + } + + + /** + * 获取图片 + * + * @param fileName + * @param type + * @return + */ + @NoDataSourceBind() + @ApiOperation("获取图片") + @GetMapping("/Image/{type}/{fileName}") + public void downLoadImg(@PathVariable("type") String type, @PathVariable("fileName") String fileName) { + String filePath = FilePathUtil.getFilePath(type.toLowerCase()); + if (FileTypeEnum.IM.equalsIgnoreCase(type)) { + type = "imfile"; + } else if (FileTypeEnum.ANNEX.equalsIgnoreCase(type)) { + type = FileTypeEnum.ANNEXPIC; + } + //下载文件 + UploadUtil.writeImage(configValueUtil.getFileType(), fileName, type.toLowerCase(), filePath); + } + + /** + * 获取IM聊天图片 + * 注意 后缀名前端故意把 .替换@ + * + * @param fileName + * @return + */ + @NoDataSourceBind() + @ApiOperation("获取IM聊天图片") + @GetMapping("/IMImage/{fileName}") + public void imImage(@PathVariable("fileName") String fileName) { + //下载文件 + UploadUtil.downFile(configValueUtil.getFileType(), fileName, "imfile", FilePathUtil.getFilePath(FileTypeEnum.IM) + fileName, null); + } + + /** + * 查看图片 + * + * @param type 哪个文件夹 + * @param fileName 文件名称 + * @return + */ + @NoDataSourceBind() + @ApiOperation("查看图片") + @GetMapping("/{type}/{fileName}") + public void img(@PathVariable("type") String type, @PathVariable("fileName") String fileName) { + String filePath = configValueUtil.getBiVisualPath() + type + File.separator; + if (StorageType.MINIO.equals(configValueUtil.getFileType())) { + fileName = "/" + type + "/" + fileName; + filePath = configValueUtil.getBiVisualPath().substring(0, configValueUtil.getBiVisualPath().length() - 1); + } + //下载文件 + UploadUtil.downFile(configValueUtil.getFileType(), fileName, FileTypeEnum.BIVISUALPATH, filePath, null); + } + + /** + * 获取IM聊天语音 + * 注意 后缀名前端故意把 .替换@ + * + * @param fileName + * @return + */ + @NoDataSourceBind() + @ApiOperation("获取IM聊天语音") + @GetMapping("/IMVoice/{fileName}") + public void imVoice(@PathVariable("fileName") String fileName) { + String paths = FilePathUtil.getFilePath(FileTypeEnum.IM) + fileName.replaceAll("@", "."); + UploadUtil.downFile(configValueUtil.getFileType(), fileName, "imfile", paths, null); + } + + /** + * app启动获取信息 + * + * @param appName + * @return + */ + @NoDataSourceBind() + @ApiOperation("app启动获取信息") + @GetMapping("/AppStartInfo/{appName}") + public ActionResult getAppStartInfo(@PathVariable("appName") String appName) { + appName = XSSEscape.escape(appName); + JSONObject object = new JSONObject(); + object.put("AppVersion", configValueUtil.getAppVersion()); + object.put("AppUpdateContent", configValueUtil.getAppUpdateContent()); + return ActionResult.success(object); + } + + //----------大屏图片下载--------- + @NoDataSourceBind() + @ApiOperation("获取图片") + @GetMapping("/VisusalImg/{type}/{fileName}") + public void downVisusalImg(@PathVariable("type") String type, @PathVariable("fileName") String fileName) { + type = XSSEscape.escape(type); + fileName = XSSEscape.escape(fileName); + String filePath = FilePathUtil.getFilePath(FileTypeEnum.BIVISUALPATH) + type + File.separator; + if (StorageType.MINIO.equals(configValueUtil.getFileType())) { + fileName = "/" + type + "/" + fileName; + } + UploadUtil.downFile(configValueUtil.getFileType(), fileName, FileTypeEnum.BIVISUALPATH, filePath, null); + } + + //---------------------- + +// @NoDataSourceBind() +// @ApiOperation("预览文件") +// @GetMapping("/Uploader/Preview") +// public ActionResult Preview(PreviewParams previewParams) { +// //读取允许文件预览类型 +// String allowPreviewType = configValueUtil.getAllowPreviewFileType(); +// String[] fileType = allowPreviewType.split(","); +// +// String fileName = XSSEscape.escape(previewParams.getFileName()); +// +// //文件预览类型检验 +// String docType = fileName.substring(fileName.lastIndexOf(".") + 1); +// String s = Arrays.asList(fileType).stream().filter(type -> type.equals(docType)).findFirst().orElse(null); +// +// if (StringUtil.isEmpty(s)) { +// return ActionResult.fail("预览失败,请检查文件类型是否规范"); +// } +// +// //解析文件url 获取类型 +// String type = FileTypeEnum.ANNEX; +// +// String fileNameAll = previewParams.getFileDownloadUrl(); +// if (!StringUtil.isEmpty(fileNameAll)) { +// String[] data = fileNameAll.split("/"); +// type = data.length > 4 ? data[4] : ""; +// } +// +// String url; +// //文件预览策略 +// if ("yozo".equals(configValueUtil.getPreviewType())) { +// if (StringUtil.isEmpty(previewParams.getFileVersionId())) { +// return ActionResult.fail("预览失败,请重新上传文件"); +// } +// +// String fileVersionId = XSSEscape.escape(previewParams.getFileVersionId()); +// +// //获取签名 +// Map parameter = new HashMap(); +// parameter.put("appId", new String[]{YozoParams.APP_ID}); +// parameter.put("fileVersionId", new String[]{fileVersionId}); +// String sign = yozoUtils.generateSign(YozoParams.APP_ID, YozoParams.APP_KEY, parameter).getData(); +// url = "http://eic.yozocloud.cn/api/view/file?fileVersionId=" +// + fileVersionId +// + "&appId=" +// + YozoParams.APP_ID +// + "&sign=" +// + sign; +// } else { +// if ("local".equals(configValueUtil.getFileType())) { +// url = YozoParams.JNPF_DOMAINS + "/api/file/filedownload/" + type + "/" + previewParams.getFileName(); +// } else { +// url = minioUploadUtil.getFile(fileName, type); +// } +// //encode编码 +// String fileUrl = Base64.encodeBase64String(url.getBytes()); +// url = configValueUtil.getKkFileUrl() + "onlinePreview?url=" + fileUrl; +// } +// return ActionResult.success(MsgCode.SU000.get(), url); +// } + + @NoDataSourceBind() + @ApiOperation("kk本地文件预览") + @GetMapping("/filedownload/{type}/{fileName}") + public void filedownload(@PathVariable("type") String type, @PathVariable("fileName") String fileName, HttpServletResponse response) { + String filePath = FilePathUtil.getFilePath(type) + fileName; + OutputStream os = null; + if ("local".equals(configValueUtil.getFileType())) { + //本地取对应文件 + File file = new File(filePath); + try { + os = response.getOutputStream(); + String contentType = Files.probeContentType(Paths.get(file.getAbsolutePath())); + response.setHeader("Content-Type", contentType); + response.setHeader("Content-Dispostion", "attachment;filename=" + new String(file.getName().getBytes("utf-8"), "ISO8859-1")); + FileInputStream fileInputStream = new FileInputStream(file); + + WritableByteChannel writableByteChannel = Channels.newChannel(os); + + FileChannel channel = fileInputStream.getChannel(); + channel.transferTo(0, channel.size(), writableByteChannel); + channel.close(); + os.flush(); + writableByteChannel.close(); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (os != null) { + os.close(); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + } + } + + @NoDataSourceBind() + @ApiOperation("分片上传获取") + @GetMapping("/chunk") + public ActionResult checkChunk(Chunk chunk) { + String type = chunk.getExtension(); + if(!OptimizeUtil.fileType(configValueUtil.getAllowUploadFileType(),type)){ + return ActionResult.fail(MsgCode.FA017.get()); + } + String identifier = chunk.getIdentifier(); + String path = FilePathUtil.getFilePath(FileTypeEnum.TEMPORARY); + String filePath = XSSEscape.escapePath(path + identifier); + List chunkFiles = FileUtil.getFile(new File(filePath)); + List existsChunk = chunkFiles.stream().filter(f->{ + if(f.getName().endsWith(".tmp")){ + FileUtils.deleteQuietly(f); + return false; + }else{ + return true; + } + }).map(f->Integer.parseInt(f.getName().replace(chunk.getIdentifier().concat("-"), ""))).collect(Collectors.toList()); + ChunkRes chunkRes = ChunkRes.builder().merge(false).chunkNumbers(existsChunk).build(); + return ActionResult.success(chunkRes); + } + + + @NoDataSourceBind() + @ApiOperation("分片上传附件") + @PostMapping("/chunk") + public ActionResult upload(Chunk chunk, @RequestParam("file") MultipartFile file) { + String type = chunk.getExtension(); + if(!OptimizeUtil.fileType(configValueUtil.getAllowUploadFileType(),type)){ + return ActionResult.fail(MsgCode.FA017.get()); + } + ChunkRes chunkRes = ChunkRes.builder().build(); + chunkRes.setMerge(false); + File chunkFile = null; + File chunkTmpFile = null; + try { + String filePath = FilePathUtil.getFilePath(FileTypeEnum.TEMPORARY); + Integer chunkNumber = chunk.getChunkNumber(); + String identifier = chunk.getIdentifier(); + String chunkTempPath = filePath + identifier; + File path = new File(chunkTempPath); + if (!path.exists()) { + path.mkdirs(); + } + String chunkName = identifier.concat("-") + chunkNumber; + String chunkTmpName = chunkName.concat(".tmp"); + chunkFile = new File(chunkTempPath, chunkName); + chunkTmpFile = new File(chunkTempPath, chunkTmpName); + if (chunkFile.exists() && chunkFile.length() == chunk.getCurrentChunkSize()) { + System.out.println("该分块已经上传:" + chunkFile.getName()); + } else { + @Cleanup InputStream inputStream = file.getInputStream(); + FileUtils.copyInputStreamToFile(inputStream, chunkTmpFile); + chunkTmpFile.renameTo(chunkFile); + } + chunkRes.setMerge(chunk.getChunkNumber().equals(chunk.getTotalChunks())); + } catch (Exception e) { + try{ + FileUtils.deleteQuietly(chunkTmpFile); + FileUtils.deleteQuietly(chunkFile); + }catch (Exception ee){ + e.printStackTrace(); + } + System.out.println("上传异常:" + e); + return ActionResult.fail("上传异常"); + } + return ActionResult.success(chunkRes); + } + + @NoDataSourceBind() + @ApiOperation("分片组装") + @PostMapping("/merge") + public ActionResult merge(MergeChunkDto mergeChunkDto) { + String identifier = mergeChunkDto.getIdentifier(); + String path = FilePathUtil.getFilePath(FileTypeEnum.TEMPORARY); + String filePath = XSSEscape.escapePath(path + identifier); + String uuid = RandomUtil.uuId(); + String partFile = XSSEscape.escapePath(path + uuid + "." + mergeChunkDto.getExtension()); + UploaderVO vo = UploaderVO.builder().build(); + try { + List mergeFileList = FileUtil.getFile(new File(filePath)); + @Cleanup FileOutputStream destTempfos = new FileOutputStream(partFile, true); + for (int i = 0; i < mergeFileList.size(); i++) { + String chunkName = identifier.concat("-") + (i + 1); + File files = new File(filePath, chunkName); + if (files.exists()) { + FileUtils.copyFile(files, destTempfos); + } + } + File partFiles = new File(partFile); + if (partFiles.exists()) { + MultipartFile multipartFile = FileUtil.createFileItem(partFiles); + String type = mergeChunkDto.getType(); + vo = uploaderVO(multipartFile, type); + FileUtil.deleteTmp(multipartFile); + } + } catch (Exception e) { + System.out.println("合并分片失败:" + e); + }finally { + FileUtils.deleteQuietly(new File(filePath)); + FileUtils.deleteQuietly(new File(partFile)); + } + return ActionResult.success(vo); + } + + /** + * 封装上传附件 + * + * @param file + * @param type + * @return + * @throws IOException + */ + private UploaderVO uploaderVO(MultipartFile file, String type) throws IOException { + String orgFileName = file.getOriginalFilename(); + String fileType = UpUtil.getFileType(file); +// if (OptimizeUtil.fileSize(file.getSize(), 1024000)) { +// return ActionResult.fail("上传失败,文件大小超过1M"); +// } + String fileName = DateUtil.dateNow("yyyyMMdd") + "_" + RandomUtil.uuId() + "." + fileType; + if (type.equals(FileTypeEnum.MAIL)) { + type = FileTypeEnum.TEMPORARY; + } + String filePath = FilePathUtil.getFilePath(type.toLowerCase()); + UploaderVO vo = UploaderVO.builder().name(fileName).build(); + //上传文件 + UploadUtil.uploadFile(configValueUtil.getFileType(), type, fileName, file, filePath); + if (type.equalsIgnoreCase(FileTypeEnum.USERAVATAR)) { + vo.setUrl(UploaderUtil.uploaderImg(fileName)); + } else if (type.equalsIgnoreCase(FileTypeEnum.ANNEX)) { +// UserInfo userInfo = userProvider.get(); +// vo.setUrl(UploaderUtil.uploaderFile(userInfo.getId() + "#" + fileName + "#" + type)); + vo.setUrl(UploaderUtil.uploaderImg("/api/file/Image/annex/", fileName)); + } else if (type.equalsIgnoreCase(FileTypeEnum.ANNEXPIC)) { + vo.setUrl(UploaderUtil.uploaderImg("/api/file/Image/annex/", fileName)); + }else { + vo.setUrl(UploaderUtil.uploaderImg("/api/file/Image/"+type.toLowerCase()+"/", fileName)); + } + + //上传到永中 + if ("yozo".equals(configValueUtil.getAllowPreviewFileType())) { + try { + @Cleanup InputStream inputStream = file.getInputStream(); + String s = yozoUtils.uploadFileInPreview(inputStream, orgFileName); + Map map = JsonUtil.stringToMap(s); + if ("操作成功".equals(map.get("message"))) { + Map dataMap = JsonUtil.stringToMap(String.valueOf(map.get("data"))); + String verId = String.valueOf(dataMap.get("fileVersionId")); + vo.setFileVersionId(verId); + } + } catch (Exception e) { + System.out.println("上传到永中失败"); + e.printStackTrace(); + } + } + return vo; + } +}