package jnpf.controller; import com.alibaba.fastjson.JSONObject; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameters; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jnpf.base.ActionResult; 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.FileTypeConstant; import jnpf.constant.MsgCode; import jnpf.consts.DeviceType; import jnpf.entity.FileDetail; import jnpf.entity.FileParameter; import jnpf.exception.DataException; import jnpf.model.*; import jnpf.service.FileService; import jnpf.util.*; import jnpf.utils.YozoUtils; import lombok.Cleanup; import lombok.extern.slf4j.Slf4j; import org.apache.commons.codec.binary.Base64; import org.apache.commons.io.FileUtils; import org.dromara.x.file.storage.core.FileInfo; 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 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.time.LocalDate; import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; /** * 通用控制器 * * @author JNPF开发平台组 * @version V1.2.191207 * @copyright 引迈信息技术有限公司 * @date 2019年9月26日 上午9:18 */ @Slf4j @Tag(name = "公共", description = "file") @RestController @RequestMapping("/api/file") public class UtilsController { @Autowired private ConfigValueUtil configValueUtil; @Autowired private RedisUtil redisUtil; @Autowired private DictionaryDataService dictionaryDataService; @Autowired private FileService fileService; /** * 语言列表 * * @return */ // @Operation(summary = "语言列表") // @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() @Operation(summary = "图形验证码") @GetMapping("/ImageCode/{timestamp}") @Parameters({ @Parameter(name = "timestamp", description = "时间戳", required = true), }) public void imageCode(@PathVariable("timestamp") String timestamp) { DownUtil.downCode(null); redisUtil.insert(timestamp, ServletUtil.getSession().getAttribute(CodeUtil.RANDOMCODEKEY), 120); } /** * 获取全部下载文件链接(打包下载) * * @return */ @NoDataSourceBind @Operation(summary = "获取全部下载文件链接(打包下载)") @PostMapping("/PackDownload/{type}") public ActionResult packDownloadUrl(@PathVariable("type") String type, @RequestBody List> fileInfoList) throws Exception { type = XSSEscape.escape(type); if (fileInfoList == null || fileInfoList.isEmpty()) { return ActionResult.fail(MsgCode.FA047.get()); } String zipTempFilePath = null; String zipFileId = RandomUtil.uuId() + ".zip"; List repeatName = new ArrayList<>(); for (Map fileInfoMap : fileInfoList) { String fileId = XSSEscape.escape((String) fileInfoMap.get("fileId")).trim(); String fileName = XSSEscape.escape((String) fileInfoMap.get("fileName")).trim(); if (repeatName.contains(fileName)) { fileName = fileName.substring(0, fileName.lastIndexOf(".")) + "副本" + UUID.randomUUID().toString().substring(0, 5) + fileName.substring(fileName.lastIndexOf(".")); } else { repeatName.add(fileName); } if (StringUtil.isEmpty(fileId) || StringUtil.isEmpty(fileName)) { continue; } FileParameter fileParameter = new FileParameter(type, fileId); if (FileUploadUtils.exists(fileParameter)) { // String typePath = FilePathUtil.getFilePath(type); // if (fileId.indexOf(",") >= 0) { // typePath += fileId.substring(0, fileId.lastIndexOf(",") + 1).replaceAll(",", "/"); // fileId = fileId.substring(fileId.lastIndexOf(",") + 1); // } if (zipTempFilePath == null) { zipTempFilePath = FileUploadUtils.getLocalBasePath() + FilePathUtil.getFilePath(FileTypeConstant.FILEZIPDOWNTEMPPATH); if (!new File(zipTempFilePath).exists()) { new File(zipTempFilePath).mkdirs(); } zipTempFilePath += zipFileId; } // fileParameter.setRemotePath(typePath); String finalZipTempFilePath = zipTempFilePath; String finalFileName = fileName; FileUploadUtils.downloadFile(fileParameter, inputStream -> { try { ZipUtil.fileAddToZip(finalZipTempFilePath, inputStream, finalFileName); } catch (Exception e) { throw new RuntimeException(e); } }); } } if (zipTempFilePath == null) { return ActionResult.fail(MsgCode.FA018.get()); } //将文件上传到默认文件服务器 String newFileId = zipFileId; if (!"local".equals(FileUploadUtils.getDefaultPlatform())) { //不是本地,说明是其他文件服务器,将zip文件上传到其他服务器里,方便下载 File zipFile = new File(zipTempFilePath); FileInfo fileInfo = FileUploadUtils.uploadFile(new FileParameter(FilePathUtil.getFilePath(FileTypeConstant.FILEZIPDOWNTEMPPATH), zipFileId), zipFile); zipFile.delete(); newFileId = fileInfo.getFilename(); } jnpf.base.vo.DownloadVO vo = DownloadVO.builder().name(zipFileId).url(UploaderUtil.uploaderFile(newFileId + "#" + FileTypeConstant.FILEZIPDOWNTEMPPATH)).build(); Map map = new HashMap(); map.put("downloadVo", vo); map.put("downloadName", "文件" + zipFileId); return ActionResult.success(map); } /** * 上传文件/图片 * * @return */ @NoDataSourceBind() @Operation(summary = "上传文件/图片") @PostMapping(value = "/Uploader/{type}", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) @Parameters({ @Parameter(name = "type", description = "类型", required = true) }) public ActionResult uploader(@PathVariable("type") String type, MultipartFile file, MergeChunkDto mergeChunkDto, HttpServletRequest httpServletRequest) { mergeChunkDto.setType(type); return ActionResult.success(fileService.uploadFile(mergeChunkDto, file)); } /** * 图片转成base64 * * @return */ @NoDataSourceBind() @Operation(summary = "图片转成base64") @PostMapping(value = "/Uploader/imgToBase64", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ActionResult imgToBase64(@RequestParam("file") MultipartFile file) throws IOException { String encode = cn.hutool.core.codec.Base64.encode(file.getBytes()); Object base64Name = ""; if (StringUtil.isNotEmpty(encode)) { base64Name = "data:image/jpeg;base64,"+encode; } return ActionResult.success(base64Name); } /** * 获取下载文件链接 * * @return */ @NoDataSourceBind() @Operation(summary = "获取下载文件链接") @GetMapping("/Download/{type}/{fileName}") @Parameters({ @Parameter(name = "type", description = "类型", required = true), @Parameter(name = "fileName", description = "文件名称", required = true), }) public ActionResult downloadUrl(@PathVariable("type") String type, @PathVariable("fileName") String fileName) { boolean exists = FileUploadUtils.exists(new FileParameter(type, fileName)); if (exists) { DownloadVO vo = DownloadVO.builder().name(fileName).url(UploaderUtil.uploaderFile(fileName + "#" + type)).build(); return ActionResult.success(vo); } return ActionResult.fail(MsgCode.FA018.get()); } /** * 下载文件链接 * * @return */ @NoDataSourceBind() @Operation(summary = "下载文件链接") @GetMapping("/Download") public void downloadFile(@RequestParam("encryption") String encryption, @RequestParam("name") String downName) throws DataException { fileService.downloadFile(encryption, downName); } /** * 下载文件链接 * * @return */ // @NoDataSourceBind() // @Operation(summary = "下载模板文件链接") // @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 (TicketUtil.parseTicket(token) != null) { // TicketUtil.deleteTicket(token); // String fileName = fileNameAll.split("#")[1]; // String filePath = configValueUtil.getTemplateFilePath(); // // 下载文件 // FileUploadUtils.downloadFile(new FileParameter(filePath, fileName), inputStream -> { // FileDownloadUtil.outFile(inputStream, fileName); // }); // } else { // throw new DataException(MsgCode.FA039.get()); // } // } else { // throw new DataException(MsgCode.FA039.get()); // } // } /** * 获取图片 * * @param fileName * @param type * @return */ @NoDataSourceBind() @Operation(summary = "获取图片") @GetMapping("/Image/{type}/{fileName}") @Parameters({ @Parameter(name = "type", description = "类型", required = true), @Parameter(name = "fileName", description = "名称", required = true), }) public void downLoadImg(@PathVariable("type") String type, @PathVariable("fileName") String fileName, @RequestParam(name = "s", required = false) String securityKey, @RequestParam(name = "t", required = false) String t) throws DataException { fileService.flushFile(type, fileName, securityKey, StringUtil.isEmpty(t)); } /** * 获取IM聊天图片 * 注意 后缀名前端故意把 .替换@ * * @param fileName * @return */ // @NoDataSourceBind() // @Operation(summary = "获取IM聊天图片") // @GetMapping("/IMImage/{fileName}") // @Parameters({ // @Parameter(name = "fileName", description = "名称", required = true), // }) // public void imImage(@PathVariable("fileName") String fileName) { // FileUploadUtils.downloadFile(new FileParameter(configValueUtil.getImContentFilePath(), fileName), inputStream -> { // FileDownloadUtil.flushFile(inputStream, fileName); // }); // } /** * 查看图片 * * @param type 哪个文件夹 * @param fileName 文件名称 * @return */ // @NoDataSourceBind() // @Operation(summary = "查看图片") // @GetMapping("/{type}/{fileName}") // @Parameters({ // @Parameter(name = "fileName", description = "名称", required = true), // @Parameter(name = "type", description = "类型", required = true), // }) // 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); //// } // String filePath = FilePathUtil.getFilePath(type.toLowerCase()); // if (fileName.indexOf(",") >= 0) { // filePath += fileName.substring(0, fileName.lastIndexOf(",") + 1).replaceAll(",", "/"); // fileName = fileName.substring(fileName.lastIndexOf(",") + 1); // } // //下载文件 // String finalFileName = fileName; // FileUploadUtils.downloadFile(new FileParameter(filePath, fileName), inputStream -> { // FileDownloadUtil.flushFile(inputStream, finalFileName); // }); // } /** * 获取IM聊天语音 * 注意 后缀名前端故意把 .替换@ * * @param fileName * @return */ // @NoDataSourceBind() // @Operation(summary = "获取IM聊天语音") // @GetMapping("/IMVoice/{fileName}") // @Parameters({ // @Parameter(name = "fileName", description = "名称", required = true), // }) // public void imVoice(@PathVariable("fileName") String fileName) { // fileName = fileName.replaceAll("@", "."); // String finalFileName = fileName; // FileUploadUtils.downloadFile(new FileParameter(configValueUtil.getImContentFilePath(), fileName), inputStream -> { // FileDownloadUtil.flushFile(inputStream, finalFileName); // }); // } /** * app启动获取信息 * * @param appName * @return */ @NoDataSourceBind() @Operation(summary = "app启动获取信息") @GetMapping("/AppStartInfo/{appName}") @Parameters({ @Parameter(name = "appName", description = "名称", required = true), }) 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() @Operation(summary = "获取图片") @GetMapping("/VisusalImg/{bivisualpath}/{type}/{fileName}") @Parameters({ @Parameter(name = "type", description = "类型", required = true), @Parameter(name = "bivisualpath", description = "路径", required = true), @Parameter(name = "fileName", description = "名称", required = true), }) public void downVisusalImg(@PathVariable("type") String type, @PathVariable("bivisualpath") String bivisualpath, @PathVariable("fileName") String fileName) { fileName = XSSEscape.escape(fileName); String filePath = configValueUtil.getBiVisualPath(); String finalFileName = fileName; FileUploadUtils.downloadFile(new FileParameter(filePath + type + "/", fileName), inputStream -> { FileDownloadUtil.flushFile(inputStream, finalFileName); }); } //---------------------- @NoDataSourceBind() @Operation(summary = "预览文件") @GetMapping("/Uploader/Preview") public ActionResult Preview(PreviewParams previewParams) { return ActionResult.success(MsgCode.SU000.get(), fileService.previewFile(previewParams)); } // @NoDataSourceBind() // @Operation(summary = "kk本地文件预览") // @GetMapping("/filedownload/{type}/{fileName}") // @Deprecated // public void filedownload(@PathVariable("type") String type, @PathVariable("fileName") String fileName, HttpServletResponse response) { // String typePath = FilePathUtil.getFilePath(type); // if (fileName.indexOf(",") >= 0) { // typePath += fileName.substring(0, fileName.lastIndexOf(",") + 1).replaceAll(",", "/"); // fileName = fileName.substring(fileName.lastIndexOf(",") + 1); // } // String tmpPath = typePath + fileName; // boolean b = FileUtil.fileIsFile(tmpPath); // if (!b) { // FileUploadUtils.downloadFileToLocal(new FileParameter(type, fileName).setLocaFilelPath(FileUploadUtils.getLocalBasePath() + typePath)); // } // String filePath = XSSEscape.escapePath(FileUploadUtils.getLocalBasePath() + typePath + fileName); // OutputStream os = null; // //本地取对应文件 // 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")); // @Cleanup FileInputStream fileInputStream = new FileInputStream(file); // // @Cleanup WritableByteChannel writableByteChannel = Channels.newChannel(os); // // @Cleanup 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(); // } // } // } @Operation(summary = "分片上传获取") @GetMapping("/chunk") public ActionResult checkChunk(Chunk chunk) { return ActionResult.success(fileService.checkChunk(chunk)); } @Operation(summary = "分片上传附件") @PostMapping("/chunk") public ActionResult upload(Chunk chunk, MultipartFile file) { return ActionResult.success(fileService.uploadChunk(chunk, file)); } @Operation(summary = "分片组装") @PostMapping("/merge") public ActionResult merge(MergeChunkDto mergeChunkDto) { return ActionResult.success(fileService.mergeChunk(mergeChunkDto)); } public static void main(String[] args) { String path = "../../../windows/win.ini|userAvatar/../../../../windows/win.ini"; System.out.printf(XSSEscape.escapePath(path)); } }