| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453 |
- package jnpf.service.impl;
- import cn.hutool.core.util.URLUtil;
- import jnpf.base.UserInfo;
- import jnpf.config.ConfigValueUtil;
- import jnpf.constant.FileTypeConstant;
- import jnpf.constant.GlobalConst;
- import jnpf.constant.MsgCode;
- import jnpf.consts.DeviceType;
- import jnpf.entity.FileParameter;
- import jnpf.exception.DataException;
- import jnpf.model.*;
- import jnpf.service.FileService;
- import jnpf.util.*;
- 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.stereotype.Service;
- import org.springframework.web.multipart.MultipartFile;
- import java.io.File;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.InputStream;
- import java.time.LocalDate;
- import java.time.format.DateTimeFormatter;
- import java.util.*;
- import java.util.stream.Collectors;
- @Slf4j
- @Service
- public class FileServiceImpl implements FileService {
- private List<String> whiteImageFolder = Arrays.asList(FileTypeConstant.USERAVATAR.toLowerCase(), FileTypeConstant.BIVISUALPATH.toLowerCase());
- @Autowired
- private ConfigValueUtil configValueUtil;
- // @Autowired
- // private YozoUtils yozoUtils;
- @Override
- public String getPath(String type) {
- return FilePathUtil.getFilePath(type);
- }
- @Override
- public String getLocalBasePath() {
- return FileUploadUtils.getLocalBasePath();
- }
- @Override
- public UploaderVO uploadFile(MergeChunkDto mergeChunkDto, MultipartFile file) {
- String fileType = UpUtil.getFileType(file);
- if (StringUtil.isEmpty(fileType)) {
- fileType = mergeChunkDto.getFileType();
- }
- //验证类型
- if (!OptimizeUtil.fileType(configValueUtil.getAllowUploadFileType(), fileType)) {
- throw new DataException(MsgCode.FA017.get());
- }
- PathTypeModel pathTypeModel = new PathTypeModel();
- pathTypeModel.setPathType(mergeChunkDto.getPathType());
- pathTypeModel.setTimeFormat(mergeChunkDto.getTimeFormat());
- pathTypeModel.setSortRule(mergeChunkDto.getSortRule());
- pathTypeModel.setFolder(mergeChunkDto.getFolder());
- // String orgFileName = file.getOriginalFilename();
- // if (OptimizeUtil.fileSize(file.getSize(), 1024000)) {
- // return ActionResult.fail("上传失败,文件大小超过1M");
- // }
- // if ("mail".equals(type)) {
- // type = "temporary";
- // }
- if ("selfPath".equals(pathTypeModel.getPathType())) {
- if (StringUtil.isNotEmpty(pathTypeModel.getFolder())) {
- String folder = pathTypeModel.getFolder();
- folder = folder.replaceAll("\\\\", "/");
- // String regex = "^[a-z0-9A-Z\\u4e00-\\u9fa5\\\\\\/]+$";
- //文件夹名以字母或数字开头,由字母、数字、下划线和连字符组成,长度不超过100个字符
- String regex = "^[a-zA-Z0-9][a-zA-Z0-9_\\-\\\\\\/]{0,99}$";
- if (!folder.matches(regex)) {
- throw new DataException(MsgCode.FA038.get());
- }
- }
- }
- //实际文件名
- String fileName = DateUtil.dateNow("yyyyMMdd") + "_" + RandomUtil.uuId() + "." + fileType;
- //文件上传路径
- // String filePath = FilePathUtil.getFilePath(type.toLowerCase());
- String type = mergeChunkDto.getType();
- //文件自定义路径相对路径
- String relativeFilePath = "";
- if (pathTypeModel != null && "selfPath".equals(pathTypeModel.getPathType()) && pathTypeModel.getSortRule() != null) {
- // 按路径规则顺序构建生成目录
- String sortRule = pathTypeModel.getSortRule();
- List<String> rules = null;
- if (sortRule.contains("[")) {
- rules = JsonUtil.getJsonToList(sortRule, String.class);
- } else {
- rules = Arrays.asList(pathTypeModel.getSortRule().split(","));
- }
- for (String rule : rules) {
- // 按用户存储
- if ("1".equals(rule)) {
- UserInfo userInfo = UserProvider.getUser();
- relativeFilePath += userInfo.getUserAccount() + "/";
- }
- // 按照时间格式
- else if (StringUtil.isNotEmpty(pathTypeModel.getTimeFormat()) && "2".equals(rule)) {
- String timeFormat = pathTypeModel.getTimeFormat();
- timeFormat = timeFormat.replaceAll("YYYY", "yyyy");
- timeFormat = timeFormat.replaceAll("DD", "dd");
- LocalDate currentDate = LocalDate.now();
- DateTimeFormatter formatter = DateTimeFormatter.ofPattern(timeFormat);
- String currentDateStr = currentDate.format(formatter);
- relativeFilePath += currentDateStr;
- if (!currentDateStr.endsWith("/")) {
- relativeFilePath += "/";
- }
- }
- // 按自定义目录
- else if (StringUtil.isNotEmpty(pathTypeModel.getFolder()) && "3".equals(rule)) {
- String folder = pathTypeModel.getFolder();
- folder = folder.replaceAll("\\\\", "/");
- relativeFilePath += folder;
- if (!folder.endsWith("/")) {
- relativeFilePath += "/";
- }
- }
- }
- if (StringUtil.isNotEmpty(relativeFilePath)) {
- relativeFilePath = StringUtil.replaceMoreStrToOneStr(relativeFilePath, "/");
- if (relativeFilePath.startsWith("/")) {
- relativeFilePath = relativeFilePath.substring(1);
- }
- //filePath += relativeFilePath;
- fileName = relativeFilePath.replaceAll("/", ",") + fileName;
- }
- }
- UploaderVO vo = UploaderVO.builder().fileSize(file.getSize()).fileExtension(fileType).build();
- // //上传文件
- // if ("im".equalsIgnoreCase(type)){
- // type = "imfile";
- // }
- FileInfo fileInfo = FileUploadUtils.uploadFile(new FileParameter(type, fileName).setThumbnail(true), file);
- fileName = fileInfo.getFilename();
- String thFilename = fileInfo.getThFilename();
- if (!StringUtil.isNotEmpty(thFilename)) {
- //小图没有压缩直接用原图
- thFilename = fileName;
- }
- //自定义文件实际文件名
- if (StringUtil.isNotEmpty(relativeFilePath)) {
- fileName = relativeFilePath.replaceAll("/", ",") + fileName;
- thFilename = relativeFilePath.replaceAll("/", ",") + thFilename;
- }
- vo.setName(fileName);
- vo.setUrl(UploaderUtil.uploaderImg("/api/file/Image/" + type + "/", fileName));
- vo.setThumbUrl(UploaderUtil.uploaderImg("/api/file/Image/" + type + "/", thFilename));
- //上传到永中
- if ("yozo".equals(configValueUtil.getPreviewType())) {
- // try {
- // @Cleanup InputStream inputStream = file.getInputStream();
- // String s = yozoUtils.uploadFileInPreview(inputStream, orgFileName);
- // Map<String, Object> map = JsonUtil.stringToMap(s);
- // if ("操作成功".equals(map.get("message"))) {
- // Map<String, Object> 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;
- }
- @Override
- public ChunkRes checkChunk(Chunk chunk) {
- String type = chunk.getExtension();
- if (!OptimizeUtil.fileType(configValueUtil.getAllowUploadFileType(), type)) {
- throw new DataException(MsgCode.FA017.get());
- }
- String identifier = chunk.getIdentifier();
- String path = getPath(FileTypeConstant.TEMPORARY);
- String filePath = XSSEscape.escapePath(path + identifier);
- List<File> chunkFiles = FileUtil.getFile(new File(FileUploadUtils.getLocalBasePath() + filePath));
- List<Integer> existsChunk = chunkFiles.stream().filter(f -> {
- if (f.getName().endsWith(".tmp")) {
- FileUtils.deleteQuietly(f);
- return false;
- } else {
- return f.getName().startsWith(identifier);
- }
- }).map(f -> Integer.parseInt(f.getName().replace(chunk.getIdentifier().concat("-"), ""))).collect(Collectors.toList());
- ChunkRes chunkRes = ChunkRes.builder().merge(chunk.getTotalChunks().equals(existsChunk.size())).chunkNumbers(existsChunk).build();
- return chunkRes;
- }
- @Override
- public ChunkRes uploadChunk(Chunk chunk, MultipartFile file) {
- String type = chunk.getExtension();
- if (!OptimizeUtil.fileType(configValueUtil.getAllowUploadFileType(), type)) {
- throw new DataException(MsgCode.FA017.get());
- }
- ChunkRes chunkRes = ChunkRes.builder().build();
- chunkRes.setMerge(false);
- File chunkFile = null;
- File chunkTmpFile = null;
- try {
- String filePath = FileUploadUtils.getLocalBasePath() + getPath(FileTypeConstant.TEMPORARY);
- Integer chunkNumber = chunk.getChunkNumber();
- String identifier = XSSEscape.escapePath(chunk.getIdentifier());
- String chunkTempPath = XSSEscape.escapePath(filePath + identifier);
- File path = new File(chunkTempPath);
- if (!path.exists()) {
- path.mkdirs();
- }
- String chunkName = XSSEscape.escapePath(identifier.concat("-") + chunkNumber);
- String chunkTmpName = XSSEscape.escapePath(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);
- }
- int existsSize = (int) FileUtil.getFile(new File(chunkTempPath)).stream().filter(f ->
- f.getName().startsWith(identifier) && !f.getName().endsWith(".tmp")
- ).count();
- chunkRes.setMerge(Objects.equals(existsSize, chunk.getTotalChunks()));
- } catch (Exception e) {
- try {
- FileUtils.deleteQuietly(chunkTmpFile);
- FileUtils.deleteQuietly(chunkFile);
- } catch (Exception ee) {
- e.printStackTrace();
- }
- System.out.println("上传异常:" + e);
- throw new DataException(MsgCode.FA033.get());
- }
- return chunkRes;
- }
- @Override
- public UploaderVO mergeChunk(MergeChunkDto mergeChunkDto) {
- String identifier = XSSEscape.escapePath(mergeChunkDto.getIdentifier());
- String path = FileUploadUtils.getLocalBasePath() + getPath(FileTypeConstant.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<File> 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);
- vo = uploadFile(mergeChunkDto, multipartFile);
- FileUtil.deleteTmp(multipartFile);
- }
- } catch (Exception e) {
- log.error("合并分片失败: {}", e.getMessage());
- throw new DataException(MsgCode.FA033.get());
- } finally {
- FileUtils.deleteQuietly(new File(filePath));
- FileUtils.deleteQuietly(new File(partFile));
- }
- return vo;
- }
- @Override
- public void downloadFile(String encryption, String downName) {
- String fileNameAll = DesUtil.aesDecode(encryption);
- if (!StringUtil.isEmpty(fileNameAll)) {
- fileNameAll = fileNameAll.replaceAll("\n", "");
- String[] data = fileNameAll.split("#");
- String cacheKEY = data.length > 0 ? data[0] : "";
- String fileName = XSSEscape.escapePath(data.length > 1 ? data[1] : "");
- String type = data.length > 2 ? data[2] : "";
- Object ticketObj = TicketUtil.parseTicket(cacheKEY);
- //下载文件
- // String typePath = FilePathUtil.getFilePath(type.toLowerCase());
- // if (fileName.indexOf(",") >= 0) {
- // typePath += fileName.substring(0, fileName.lastIndexOf(",") + 1).replaceAll(",", "/");
- // fileName = fileName.substring(fileName.lastIndexOf(",") + 1);
- // }
- fileName = URLUtil.decode(fileName, GlobalConst.DEFAULT_CHARSET);
- FileParameter fileParameter = new FileParameter(type, fileName);
- //验证缓存
- if (ticketObj != null) {
- boolean nodelete = false;
- //某些手机浏览器下载后会有提示窗口, 会访问两次下载地址
- if (UserProvider.getDeviceForAgent().equals(DeviceType.APP) && "".equals(ticketObj)) {
- TicketUtil.updateTicket(cacheKEY, "1", 30L);
- nodelete = true;
- } else {
- TicketUtil.deleteTicket(cacheKEY);
- }
- FileUploadUtils.downloadFile(fileParameter, inputStream -> {
- FileDownloadUtil.outFile(inputStream, downName);
- });
- if (FileTypeConstant.FILEZIPDOWNTEMPPATH.equals(type) && !nodelete) { //删除打包的临时文件,释放存储
- FileUploadUtils.deleteFileByPathAndFileName(fileParameter);
- }
- } else {
- if (FileTypeConstant.FILEZIPDOWNTEMPPATH.equals(type)) { //删除打包的临时文件,释放存储
- FileUploadUtils.deleteFileByPathAndFileName(fileParameter);
- }
- throw new DataException(MsgCode.FA039.get());
- }
- }
- }
- @Override
- public boolean fileExists(String path, String fileName) {
- return FileUploadUtils.exists(new FileParameter(path, fileName));
- }
- @Override
- public String previewFile(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)) {
- throw new DataException(MsgCode.FA040.get());
- }
- //解析文件url 获取类型
- String type = null;
- String fileNameAll = previewParams.getFileDownloadUrl();
- if (!StringUtil.isEmpty(fileNameAll)) {
- String[] data = fileNameAll.split("/");
- if (data.length > 4) {
- type = data[4];
- } else {
- type = "";
- }
- }
- // type = getPath(FileTypeConstant.ANNEXPIC);
- String url;
- //文件预览策略
- if ("yozo".equals(configValueUtil.getPreviewType())) {
- // if (StringUtil.isEmpty(previewParams.getFileVersionId())) {
- // throw new DataException(MsgCode.FA041.get());
- // }
- //
- // String fileVersionId = XSSEscape.escape(previewParams.getFileVersionId());
- //
- // //获取签名
- // Map<String, String[]> parameter = new HashMap<String, String[]>();
- // 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;
- url = "";
- } else {
- // String[] split = fileNameAll.split("/");
- // if (split.length > 5) {
- // type = FilePathUtil.getFilePath(type);
- // String fName = split[5];
- // if (fName.contains(",")) {
- // fName = fName.replaceAll(",", "/");
- // type += fName.substring(0, fName.lastIndexOf("/") + 1);
- // fileName = fName.substring(fName.lastIndexOf("/") + 1);
- // }
- // }
- // url = configValueUtil.getApiDomain() + UploaderUtil.uploaderFile(fileName + "#" + type) + "&name=" + fileName + "&fullfilename=" + fileName;
- String downFileName = fileName;
- if (downFileName.contains(",")) {
- downFileName = downFileName.substring(downFileName.lastIndexOf(",") + 1);
- }
- url = configValueUtil.getApiDomain() + "/api/file/Image/" + type + "/" + fileName + "?fullfilename=" + downFileName + "&s=" + UserProvider.getUser().getSecurityKey();// + "&name=" + fileName + "&fullfilename=" + fileName;
- //encode编码
- String fileUrl = Base64.encodeBase64String(url.getBytes());
- url = configValueUtil.getKkFileUrl() + "onlinePreview?url=" + fileUrl;
- }
- return url;
- }
- @Override
- public void flushFile(String type, String fileName, String securityKey, boolean redirect) {
- //目录校验, 开放UserAvatar、BiVisualPath
- if (!whiteImageFolder.contains(type.toLowerCase())) {
- if (StringUtil.isEmpty(securityKey)) {
- throw new DataException(MsgCode.FA039.get());
- }
- String ticket = DesUtil.aesOrDecode(securityKey, false, true);
- String token = TicketUtil.parseTicket(ticket);
- if (token == null) {
- throw new DataException(MsgCode.FA039.get());
- }
- UserInfo user = UserProvider.getUser(token);
- if (user.getUserId() == null) {
- TicketUtil.deleteTicket(ticket);
- throw new DataException(MsgCode.FA039.get());
- }
- }
- if (StringUtil.isNotEmpty(securityKey) && redirect) {
- String downName = fileName;
- if (downName.contains(",")) {
- downName = downName.substring(downName.lastIndexOf(",") + 1);
- }
- String urlEncodeFileName = URLUtil.encode(fileName, GlobalConst.DEFAULT_CHARSET);
- String urlEncodeDownName = URLUtil.encode(downName, GlobalConst.DEFAULT_CHARSET);
- String url = configValueUtil.getApiDomain() + UploaderUtil.uploaderFile(urlEncodeFileName + "#" + type) + "&name=" + urlEncodeDownName + "&fullfilename=" + urlEncodeDownName;
- try {
- ServletUtil.getResponse().sendRedirect(url);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- } else {
- FileUploadUtils.downloadFile(new FileParameter(type, fileName), inputStream -> {
- FileDownloadUtil.flushFile(inputStream, fileName);
- });
- }
- }
- }
|