!84 新增 支持压缩包密码 修复压缩包LINUX下中文乱码 解压支持文件目录 统一JQ文件 精简一些代码

Merge pull request !84 from 高雄/master
pull/85/MERGE
kailing 2023-04-10 03:32:42 +00:00 committed by Gitee
commit 195f56e9b9
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
18 changed files with 418 additions and 738 deletions

View File

@ -31,7 +31,7 @@
<opencv.version>4.1.2-1.5.2</opencv.version>
<openblas.version>0.3.6-1.5.1</openblas.version>
<ffmpeg.version>4.2.1-1.5.2</ffmpeg.version>
<itext.version>2.1.7</itext.version>
<itextpdf.version>5.5.13.3</itextpdf.version>
<httpclient.version>3.1</httpclient.version>
<commons-cli.version>1.2</commons-cli.version>

View File

@ -244,10 +244,10 @@
<classifier>windows-x86_64</classifier>
</dependency>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>${itext.version}</version>
</dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>${itextpdf.version}</version>
</dependency>
<dependency>
<groupId>javax.media</groupId>
@ -338,4 +338,4 @@
</plugin>
</plugins>
</build>
</project>
</project>

View File

@ -2,31 +2,22 @@ package cn.keking.service;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileType;
import cn.keking.utils.FileHeaderRar;
import cn.keking.utils.KkFileUtils;
import cn.keking.utils.RarUtils;
import cn.keking.web.filter.BaseUrlFilter;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.junrar.Archive;
import com.github.junrar.exception.RarException;
import com.github.junrar.rarfile.FileHeader;
import net.sf.sevenzipjbinding.*;
import net.sf.sevenzipjbinding.ExtractOperationResult;
import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException;
import net.sf.sevenzipjbinding.impl.RandomAccessFileInStream;
import net.sf.sevenzipjbinding.simple.ISimpleInArchive;
import net.sf.sevenzipjbinding.simple.ISimpleInArchiveItem;
import org.apache.commons.io.IOUtils;
import org.springframework.stereotype.Component;
import java.io.*;
import java.math.BigDecimal;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.text.CollationKey;
import java.text.Collator;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.ArrayList;
import java.util.List;
/**
* @author yudian-it
@ -34,171 +25,61 @@ import java.util.stream.Collectors;
*/
@Component
public class CompressFileReader {
private static final Pattern pattern = Pattern.compile("^\\d+");
private final FileHandlerService fileHandlerService;
private final String fileDir = ConfigConstants.getFileDir();
private final ExecutorService executors = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
public CompressFileReader(FileHandlerService fileHandlerService) {
this.fileHandlerService = fileHandlerService;
}
public static byte[] getUTF8BytesFromGBKString(String gbkStr) {
int n = gbkStr.length();
byte[] utfBytes = new byte[3 * n];
int k = 0;
for (int i = 0; i < n; i++) {
int m = gbkStr.charAt(i);
if (m < 128 && m >= 0) {
utfBytes[k++] = (byte) m;
continue;
}
utfBytes[k++] = (byte) (0xe0 | (m >> 12));
utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f));
utfBytes[k++] = (byte) (0x80 | (m & 0x3f));
}
if (k < utfBytes.length) {
byte[] tmp = new byte[k];
System.arraycopy(utfBytes, 0, tmp, 0, k);
return tmp;
}
return utfBytes;
}
public String getUtf8String(String str) {
if (str != null && str.length() > 0) {
String needEncodeCode = "ISO-8859-1";
String neeEncodeCode = "ISO-8859-2";
String gbkEncodeCode = "GBK";
try {
if (Charset.forName(needEncodeCode).newEncoder().canEncode(str)) {
str = new String(str.getBytes(needEncodeCode), StandardCharsets.UTF_8);
}
if (Charset.forName(neeEncodeCode).newEncoder().canEncode(str)) {
str = new String(str.getBytes(neeEncodeCode), StandardCharsets.UTF_8);
}
if (Charset.forName(gbkEncodeCode).newEncoder().canEncode(str)) {
str = new String(getUTF8BytesFromGBKString(str), StandardCharsets.UTF_8);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return str;
}
/**
*
*/
private static boolean isChinese(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
if (ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS) {
return true;
}
return false;
}
public static boolean judge(char c){
if((c >='0' && c<='9')||(c >='a' && c<='z' || c >='A' && c<='Z')){
return true;
}
return false;
}
public static boolean isMessyCode(String strName) {
//去除字符串中的空格 制表符 换行 回车
Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*");
Matcher m = p.matcher(strName);
String after = m.replaceAll("").replaceAll("\\+", "").replaceAll("#", "").replaceAll("&", "");
//去除字符串中的标点符号
String temp = after.replaceAll("\\p{P}", "");
//处理之后转换成字符数组
char[] ch = temp.trim().toCharArray();
for (int i = 0; i < ch.length; i++) {
char c = ch[i];
//判断是否是数字或者英文字符
if (!judge(c)) {
//判断是否是中日韩文
if (!isChinese(c)) {
//如果不是数字或者英文字符也不是中日韩文则表示是乱码返回true
return true;
}
}
}
//表示不是乱码 返回false
return false;
}
public String unRar(String filePath, String fileKey) {
Map<String, FileNode> appender = new HashMap<>();
public String unRar(String paths, String passWord, String fileName) throws Exception {
List<String> imgUrls = new ArrayList<>();
String baseUrl = BaseUrlFilter.getBaseUrl();
try {
List<FileHeaderRar> items = getRar4Paths(filePath);
String archiveFileName = fileHandlerService.getFileNameFromPath(filePath);
List<Map<String, FileHeaderRar>> headersToBeExtract = new ArrayList<>();
for (FileHeaderRar header : items) {
String fullName = header.getFileNameW();
String originName = getLastFileName(fullName);
String childName = originName;
boolean directory = header.getDirectory();
if (!directory) {
childName = archiveFileName + "_" + originName;
headersToBeExtract.add(Collections.singletonMap(childName, header));
}
String parentName = getLast2FileName(fullName, archiveFileName);
FileType type = FileType.typeFromUrl(childName);
if (type.equals(FileType.PICTURE)) {
imgUrls.add(baseUrl + childName);
}
FileNode node =
new FileNode(originName, childName, parentName, new ArrayList<>(), directory, fileKey);
addNodes(appender, parentName, node);
appender.put(childName, node);
}
fileHandlerService.putImgCache(fileKey, imgUrls);
executors.submit(new RarExtractorWorker(headersToBeExtract, filePath));
return new ObjectMapper().writeValueAsString(appender.get(""));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public List<FileHeaderRar> getRar4Paths(String paths) {
String archiveFileName = fileHandlerService.getFileNameFromPath(paths);
RandomAccessFile randomAccessFile = null;
IInArchive inArchive = null;
List<FileHeaderRar> itemPath = null;
try {
randomAccessFile = new RandomAccessFile(paths, "r");
inArchive = SevenZip.openInArchive(null, new RandomAccessFileInStream(randomAccessFile));
String folderName = paths.substring(paths.lastIndexOf(File.separator) + 1);
String extractPath = paths.substring(0, paths.lastIndexOf(folderName));
inArchive.extract(null, false, new ExtractCallback(inArchive, extractPath, folderName + "_"));
ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
itemPath = Arrays.stream(simpleInArchive.getArchiveItems()).map(o -> {
try {
String path = getUtf8String(o.getPath());
if (isMessyCode(path)){
path = new String(o.getPath().getBytes(StandardCharsets.ISO_8859_1), "GBK");
}
return new FileHeaderRar(path, o.isFolder());
} catch (SevenZipException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return null;
})
.collect(Collectors.toList())
.stream()
.sorted(Comparator.comparing(FileHeaderRar::getFileNameW))
.collect(Collectors.toList());
ISimpleInArchive simpleInArchive = inArchive.getSimpleInterface();
final String[] str = {null};
for (final ISimpleInArchiveItem item : simpleInArchive.getArchiveItems()) {
if (!item.isFolder()) {
ExtractOperationResult result;
result = item.extractSlow(data -> {
try {
str[0] = RarUtils.getUtf8String(item.getPath());
if (RarUtils.isMessyCode(str[0])){
str[0] = new String(item.getPath().getBytes(StandardCharsets.ISO_8859_1), "gbk");
}
str[0] = str[0].replace("\\", File.separator); //Linux 下路径错误
String str1 = str[0].substring(0, str[0].lastIndexOf(File.separator)+ 1);
File file = new File(extractPath, folderName + "_" + File.separator + str1);
if (!file.exists()) {
file.mkdirs();
}
OutputStream out = new FileOutputStream( extractPath+ folderName + "_" + File.separator + str[0], true);
IOUtils.write(data, out);
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return data.length;
}, passWord);
if (result == ExtractOperationResult.OK) {
FileType type = FileType.typeFromUrl(str[0]);
if (type.equals(FileType.PICTURE)) {
// System.out.println( baseUrl +folderName + "_" + str[0]);
imgUrls.add(baseUrl +folderName + "_/" + str[0].replace("\\", "/"));
}
fileHandlerService.putImgCache(fileName, imgUrls);
} else {
return null;
}
}
}
return archiveFileName + "_";
} catch (Exception e) {
System.err.println("Error occurs: " + e);
throw new Exception(e);
} finally {
if (inArchive != null) {
try {
@ -215,276 +96,6 @@ public class CompressFileReader {
}
}
}
return itemPath;
}
private void addNodes(Map<String, FileNode> appender, String parentName, FileNode node) {
if (appender.containsKey(parentName)) {
appender.get(parentName).getChildList().add(node);
appender.get(parentName).getChildList().sort(sortComparator);
} else {
// 根节点
FileNode nodeRoot = new FileNode(parentName, parentName, "", new ArrayList<>(), true);
nodeRoot.getChildList().add(node);
appender.put("", nodeRoot);
appender.put(parentName, nodeRoot);
}
}
private static String getLast2FileName(String fullName, String rootName) {
if (fullName.endsWith(File.separator)) {
fullName = fullName.substring(0, fullName.length() - 1);
}
// 1.获取剩余部分
int endIndex = fullName.lastIndexOf(File.separator);
String leftPath = fullName.substring(0, endIndex == -1 ? 0 : endIndex);
if (leftPath.length() > 1) {
// 2.获取倒数第二个
return getLastFileName(leftPath);
} else {
return rootName;
}
}
private static String getLastFileName(String fullName) {
if (fullName.endsWith(File.separator)) {
fullName = fullName.substring(0, fullName.length() - 1);
}
String newName = fullName;
if (fullName.contains(File.separator)) {
newName = fullName.substring(fullName.lastIndexOf(File.separator) + 1);
}
return newName;
}
public static Comparator<FileNode> sortComparator = new Comparator<FileNode>() {
final Collator cmp = Collator.getInstance(Locale.US);
@Override
public int compare(FileNode o1, FileNode o2) {
// 判断两个对比对象是否是开头包含数字,如果包含数字则获取数字并按数字真正大小进行排序
BigDecimal num1, num2;
if (null != (num1 = isStartNumber(o1))
&& null != (num2 = isStartNumber(o2))) {
return num1.subtract(num2).intValue();
}
CollationKey c1 = cmp.getCollationKey(o1.getOriginName());
CollationKey c2 = cmp.getCollationKey(o2.getOriginName());
return cmp.compare(c1.getSourceString(), c2.getSourceString());
}
};
private static BigDecimal isStartNumber(FileNode src) {
Matcher matcher = pattern.matcher(src.getOriginName());
if (matcher.find()) {
return new BigDecimal(matcher.group());
}
return null;
}
public static class FileNode {
private String originName;
private String fileName;
private String parentFileName;
private boolean directory;
//用于图片预览时寻址
private String fileKey;
private List<FileNode> childList;
public FileNode(String originName, String fileName, String parentFileName, List<FileNode> childList, boolean directory) {
this.originName = originName;
this.fileName = fileName;
this.parentFileName = parentFileName;
this.childList = childList;
this.directory = directory;
}
public FileNode(String originName, String fileName, String parentFileName, List<FileNode> childList, boolean directory, String fileKey) {
this.originName = originName;
this.fileName = fileName;
this.parentFileName = parentFileName;
this.childList = childList;
this.directory = directory;
this.fileKey = fileKey;
}
public String getFileKey() {
return fileKey;
}
public void setFileKey(String fileKey) {
this.fileKey = fileKey;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getParentFileName() {
return parentFileName;
}
public void setParentFileName(String parentFileName) {
this.parentFileName = parentFileName;
}
public List<FileNode> getChildList() {
return childList;
}
public void setChildList(List<FileNode> childList) {
this.childList = childList;
}
@Override
public String toString() {
try {
return new ObjectMapper().writeValueAsString(this);
} catch (JsonProcessingException e) {
e.printStackTrace();
return "";
}
}
public String getOriginName() {
return originName;
}
public void setOriginName(String originName) {
this.originName = originName;
}
public boolean isDirectory() {
return directory;
}
public void setDirectory(boolean directory) {
this.directory = directory;
}
}
class RarExtractorWorker implements Runnable {
private final List<Map<String, FileHeader>> headersToBeExtracted;
private final List<Map<String, FileHeaderRar>> headersToBeExtract;
private final Archive archive;
/**
*
*/
private final String filePath;
public RarExtractorWorker(
List<Map<String, FileHeader>> headersToBeExtracted, Archive archive, String filePath) {
this.headersToBeExtracted = headersToBeExtracted;
this.archive = archive;
this.filePath = filePath;
headersToBeExtract = null;
}
public RarExtractorWorker(
List<Map<String, FileHeaderRar>> headersToBeExtract, String filePath) {
this.headersToBeExtract = headersToBeExtract;
this.filePath = filePath;
archive = null;
headersToBeExtracted = null;
}
@Override
public void run() {
for (Map<String, FileHeader> entryMap : headersToBeExtracted) {
String childName = entryMap.keySet().iterator().next();
extractRarFile(childName, entryMap.values().iterator().next(), archive);
}
try {
archive.close();
} catch (IOException e) {
e.printStackTrace();
}
KkFileUtils.deleteFileByPath(filePath);
}
private void extractRarFile(String childName, FileHeader header, Archive archive) {
String outPath = fileDir + childName;
try (OutputStream ot = new FileOutputStream(outPath)) {
archive.extractFile(header, ot);
} catch (IOException | RarException e) {
e.printStackTrace();
}
}
}
private static class ExtractCallback implements IArchiveExtractCallback {
private final IInArchive inArchive;
private final String extractPath;
private final String folderName;
public ExtractCallback(IInArchive inArchive, String extractPath, String folderName) {
this.inArchive = inArchive;
if (!extractPath.endsWith("/") && !extractPath.endsWith("\\")) {
extractPath += File.separator;
}
this.extractPath = extractPath;
this.folderName = folderName;
}
@Override
public void setTotal(long total) {
}
@Override
public void setCompleted(long complete) {
}
@Override
public ISequentialOutStream getStream(int index, ExtractAskMode extractAskMode) throws SevenZipException {
String filePath = inArchive.getStringProperty(index, PropID.PATH);
String real = folderName + filePath.substring(filePath.lastIndexOf(File.separator) + 1);
File f = new File(extractPath + real);
f.delete();
return data -> {
FileOutputStream fos = null;
try {
File path = new File(extractPath + real);
if (!path.getParentFile().exists()) {
path.getParentFile().mkdirs();
}
if (!path.exists()) {
path.createNewFile();
}
fos = new FileOutputStream(path, true);
fos.write(data);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (fos != null) {
fos.flush();
fos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return data.length;
};
}
@Override
public void prepareOperation(ExtractAskMode extractAskMode) {
}
@Override
public void setOperationResult(ExtractOperationResult extractOperationResult) {
}
}
}

View File

@ -27,6 +27,8 @@ import org.springframework.util.StringUtils;
import javax.servlet.http.HttpServletRequest;
import java.awt.image.BufferedImage;
import java.io.*;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@ -273,6 +275,14 @@ public class FileHandlerService {
FileType type;
String fileName;
String fullFileName = WebUtils.getUrlParameterReg(url, "fullfilename");
String urlStrr = null;
URL urll;
try {
urll = new URL(url);
urlStrr = URLDecoder.decode(urll.getPath(), "UTF-8");
} catch (Exception e) {
}
if (StringUtils.hasText(fullFileName)) {
fileName = fullFileName;
type = FileType.typeFromFileName(fullFileName);
@ -283,8 +293,10 @@ public class FileHandlerService {
suffix = WebUtils.suffixFromUrl(url);
}
if (url.contains("?fileKey=")) {
fileName=urlStrr;
attribute.setSkipDownLoad(true);
}
// System.out.println(fileName);
url = WebUtils.encodeUrlFileName(url);
fileName = KkFileUtils.htmlEscape(fileName); //文件名处理
attribute.setType(type);

View File

@ -0,0 +1,20 @@
package cn.keking.service;
import java.util.List;
public class ZtreeNodeVo {
public String id;
public String pid;
public String name;
public List<ZtreeNodeVo> children;
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setPid(String pid) {
this.pid = pid;
}
public void setChildren(List<ZtreeNodeVo> children) {
this.children = children;
}
}

View File

@ -7,10 +7,15 @@ import cn.keking.service.FilePreview;
import cn.keking.utils.DownloadUtils;
import cn.keking.service.FileHandlerService;
import cn.keking.service.CompressFileReader;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.poi.EncryptedDocumentException;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import java.io.IOException;
/**
* Created by kl on 2018/1/17.
* Content :
@ -21,7 +26,7 @@ public class CompressFilePreviewImpl implements FilePreview {
private final FileHandlerService fileHandlerService;
private final CompressFileReader compressFileReader;
private final OtherFilePreviewImpl otherFilePreview;
private static final String Rar_PASSWORD_MSG = "password";
public CompressFilePreviewImpl(FileHandlerService fileHandlerService, CompressFileReader compressFileReader, OtherFilePreviewImpl otherFilePreview) {
this.fileHandlerService = fileHandlerService;
this.compressFileReader = compressFileReader;
@ -31,7 +36,8 @@ public class CompressFilePreviewImpl implements FilePreview {
@Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
String fileName=fileAttribute.getName();
String fileTree;
String filePassword = fileAttribute.getFilePassword();
String fileTree = null;
// 判断文件名是否存在(redis缓存读取)
if (!StringUtils.hasText(fileHandlerService.getConvertedFile(fileName)) || !ConfigConstants.isCacheEnabled()) {
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
@ -39,21 +45,32 @@ public class CompressFilePreviewImpl implements FilePreview {
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
}
String filePath = response.getContent();
fileTree = compressFileReader.unRar(filePath, fileName);
if (fileTree != null && !"null".equals(fileTree)) {
try {
fileTree = compressFileReader.unRar(filePath, filePassword,fileName);
} catch (Exception e) {
Throwable[] throwableArray = ExceptionUtils.getThrowables(e);
for (Throwable throwable : throwableArray) {
if (throwable instanceof IOException || throwable instanceof EncryptedDocumentException) {
if (e.getMessage().toLowerCase().contains(Rar_PASSWORD_MSG)) {
model.addAttribute("needFilePassword", true);
return EXEL_FILE_PREVIEW_PAGE;
}
}
}
}
if (!ObjectUtils.isEmpty(fileTree)) {
if (ConfigConstants.isCacheEnabled()) {
// 加入缓存
fileHandlerService.addConvertedFile(fileName, fileTree);
}
}else {
return otherFilePreview.notSupportedFile(model, fileAttribute, "压缩文件密码错误! 压缩文件损坏! 压缩文件类型不受支持!");
}
} else {
fileTree = fileHandlerService.getConvertedFile(fileName);
}
if (fileTree != null && !"null".equals(fileTree)) {
model.addAttribute("fileName", fileName);
model.addAttribute("fileTree", fileTree);
return COMPRESS_FILE_PREVIEW_PAGE;
} else {
return otherFilePreview.notSupportedFile(model, fileAttribute, "压缩文件类型不受支持");
}
}
}

View File

@ -3,13 +3,11 @@ package cn.keking.service.impl;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse;
import cn.keking.service.FileHandlerService;
import cn.keking.service.FilePreview;
import cn.keking.utils.ConvertPicUtil;
import cn.keking.utils.DownloadUtils;
import cn.keking.utils.WebUtils;
import cn.keking.web.filter.BaseUrlFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
@ -27,72 +25,64 @@ import java.util.List;
@Service
public class TiffFilePreviewImpl implements FilePreview {
private final static Logger logger = LoggerFactory.getLogger(TiffFilePreviewImpl.class);
private final PictureFilePreviewImpl pictureFilePreview;
private static final String INITIALIZE_MEMORY_SIZE = "initializeMemorySize";
//默认初始化 50MB 内存
private static final long INITIALIZE_MEMORY_SIZE_VALUE_DEFAULT = 1024L * 1024 * 50;
private final String fileDir = ConfigConstants.getFileDir();
public TiffFilePreviewImpl(PictureFilePreviewImpl pictureFilePreview) {
this.pictureFilePreview = pictureFilePreview;
private final FileHandlerService fileHandlerService;
private final OtherFilePreviewImpl otherFilePreview;
public TiffFilePreviewImpl(FileHandlerService fileHandlerService,OtherFilePreviewImpl otherFilePreview) {
this.fileHandlerService = fileHandlerService;
this.otherFilePreview = otherFilePreview;
}
private final String fileDir = ConfigConstants.getFileDir();
@Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
String fileName = fileAttribute.getName();
String baseUrl = BaseUrlFilter.getBaseUrl();
String tifPreviewType = ConfigConstants.getTifPreviewType();
String tifOnLinePreviewType = fileAttribute.getTifPreviewType();
if (StringUtils.hasText(tifOnLinePreviewType)) {
tifPreviewType = tifOnLinePreviewType;
}
if ("tif".equalsIgnoreCase(tifPreviewType)) {
pictureFilePreview.filePreviewHandle(url, model, fileAttribute);
String fileSize = WebUtils.getUrlParameterReg(url, INITIALIZE_MEMORY_SIZE);
if (StringUtils.hasText(fileSize)) {
model.addAttribute(INITIALIZE_MEMORY_SIZE, fileSize);
} else {
model.addAttribute(INITIALIZE_MEMORY_SIZE, Long.toString(INITIALIZE_MEMORY_SIZE_VALUE_DEFAULT));
}
model.addAttribute("currentUrl", url);
return TIFF_FILE_PREVIEW_PAGE;
} else if ("jpg".equalsIgnoreCase(tifPreviewType) || "pdf".equalsIgnoreCase(tifPreviewType)) {
String inputFileName = url.substring(url.lastIndexOf("/") + 1);
String inputFileNamePrefix = inputFileName.substring(0, inputFileName.lastIndexOf("."));
String strLocalTif = fileDir + inputFileName;
File fileTiff = new File(strLocalTif);
// 如果本地不存在这个tif文件则下载
if (!fileTiff.exists()) {
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, inputFileName);
if (response.isFailure()) {
return NOT_SUPPORTED_FILE_PAGE;
}
}
String baseUrl = BaseUrlFilter.getBaseUrl();
String pdfName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "pdf";
String jpgName = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "jpg";
String strLocalTif = fileDir + fileName;
String outFilePath = fileDir + pdfName;
if ("pdf".equalsIgnoreCase(tifPreviewType)) {
// 以PDF模式预览的过程
File filePdf = new File(fileDir + inputFileNamePrefix + ".pdf");
// 如果本地不存在对应的pdf则调用转换过程。否则直接用现有的pdf文件
if (!filePdf.exists()) {
filePdf = ConvertPicUtil.convertTif2Pdf(strLocalTif, fileDir + inputFileNamePrefix + ".pdf");
}
// 如果pdf已经存在则将url路径加入到对象中返回给页面
assert filePdf != null;
if (filePdf.exists()) {
String pdfUrl = baseUrl + inputFileNamePrefix + ".pdf";
model.addAttribute("pdfUrl", pdfUrl);
//当文件不存在时,就去下载
if (!fileHandlerService.listConvertedFiles().containsKey(pdfName) || !ConfigConstants.isCacheEnabled()) {
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
if (response.isFailure()) {
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
}
String filePath = response.getContent();
if (ConfigConstants.isCacheEnabled()) {
// 加入缓存
fileHandlerService.addConvertedFile(pdfName, fileHandlerService.getRelativePath(outFilePath));
}
if(ConvertPicUtil.convertJpg2Pdf(filePath, outFilePath)){
model.addAttribute("pdfUrl", pdfName);
return PDF_FILE_PREVIEW_PAGE;
}
}
else {
model.addAttribute("pdfUrl", pdfName);
return PDF_FILE_PREVIEW_PAGE;
}
} else {
File fileTiff = new File(strLocalTif);
// 如果本地不存在这个tif文件则下载
if (!fileTiff.exists()) {
ReturnResponse<String> response = DownloadUtils.downLoad(fileAttribute, fileName);
if (response.isFailure()) {
return otherFilePreview.notSupportedFile(model, fileAttribute, response.getMsg());
}
strLocalTif = response.getContent();
}
// 以JPG模式预览的过程
String strJpgFilePathName = fileDir + inputFileNamePrefix + ".jpg";
String strJpgFilePathName = fileDir + jpgName;
// 将tif转换为jpg返回转换后的文件路径、文件名的list
List<String> listPic2Jpg = ConvertPicUtil.convertTif2Jpg(strLocalTif, strJpgFilePathName);
// 将返回页面的图片url的list对象
@ -101,19 +91,11 @@ public class TiffFilePreviewImpl implements FilePreview {
for (String strJpg : listPic2Jpg) {
listImageUrls.add(baseUrl + strJpg);
}
model.addAttribute("imgUrls", listImageUrls);
model.addAttribute("currentUrl", listImageUrls.get(0));
}
// 转换后的tif没用了可以删掉了
if (fileTiff.exists() && !fileTiff.delete()) {
logger.error("{} 清理失败", strLocalTif);
}
return PICTURE_FILE_PREVIEW_PAGE;
}
return NOT_SUPPORTED_FILE_PAGE;
}
}

View File

@ -1,16 +1,17 @@
package cn.keking.utils;
import com.lowagie.text.Document;
import com.lowagie.text.Image;
import com.lowagie.text.Rectangle;
import com.lowagie.text.pdf.PdfWriter;
import com.lowagie.text.pdf.RandomAccessFileOrArray;
import com.lowagie.text.pdf.codec.TiffImage;
import cn.keking.config.ConfigConstants;
import com.sun.media.jai.codec.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.io.FileChannelRandomAccessSource;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.RandomAccessFileOrArray;
import com.itextpdf.text.pdf.codec.TiffImage;
import javax.media.jai.JAI;
import javax.media.jai.RenderedOp;
import java.awt.image.RenderedImage;
@ -18,13 +19,14 @@ import java.awt.image.renderable.ParameterBlock;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.List;
public class ConvertPicUtil {
private final static Logger logger = LoggerFactory.getLogger(ConvertPicUtil.class);
private final static String fileDir = ConfigConstants.getFileDir();
/**
* Tif JPG
*
@ -42,25 +44,21 @@ public class ConvertPicUtil {
logger.info("找不到文件【" + strInputFile + "】");
return null;
}
strInputFile = strInputFile.replaceAll("\\\\", "/");
strOutputFile = strOutputFile.replaceAll("\\\\", "/");
FileSeekableStream fileSeekStream = null;
try {
JPEGEncodeParam jpegEncodeParam = new JPEGEncodeParam();
TIFFEncodeParam tiffEncodeParam = new TIFFEncodeParam();
tiffEncodeParam.setCompression(TIFFEncodeParam.COMPRESSION_GROUP4);
tiffEncodeParam.setLittleEndian(false);
String strFilePrefix = strInputFile.substring(strInputFile.lastIndexOf("/") + 1, strInputFile.lastIndexOf("."));
String jpgname = strInputFile.replace(fileDir.replace("\\","/"), "");
int index = jpgname.lastIndexOf(".");
String strFilePrefix = jpgname.substring(0, index);
fileSeekStream = new FileSeekableStream(strInputFile);
ImageDecoder imageDecoder = ImageCodec.createImageDecoder("TIFF", fileSeekStream, null);
int intTifCount = imageDecoder.getNumPages();
logger.info("该tif文件共有【" + intTifCount + "】页");
String strJpgPath;
String strJpgUrl;
if (intTifCount == 1) {
@ -87,9 +85,7 @@ public class ConvertPicUtil {
strJpg = strJpgPath + "/" + i + ".jpg";
strJpgUrl = strFilePrefix + "/" + i + ".jpg";
}
File fileJpg = new File(strJpg);
// 如果文件不存在,则生成
if (!fileJpg.exists()) {
RenderedImage renderedImage = imageDecoder.decodeAsRenderedImage(i);
@ -98,13 +94,11 @@ public class ConvertPicUtil {
pb.add(fileJpg.toString());
pb.add("JPEG");
pb.add(jpegEncodeParam);
RenderedOp renderedOp = JAI.create("filestore", pb);
renderedOp.dispose();
logger.info("每页分别保存至: " + fileJpg.getCanonicalPath());
} else {
logger.info("JPG文件已存在 " + fileJpg.getCanonicalPath());
// logger.info("JPG文件已存在 " + fileJpg.getCanonicalPath());
}
listImageFiles.add(strJpgUrl);
@ -131,101 +125,45 @@ public class ConvertPicUtil {
* @param strJpgFile jpg
* @param strPdfFile pdf
*/
public static void convertJpg2Pdf(String strJpgFile, String strPdfFile) {
Document document = new Document();
// 设置文档页边距
document.setMargins(0, 0, 0, 0);
FileOutputStream fos = null;
private static final int FIT_WIDTH = 500;
private static final int FIT_HEIGHT = 900;
public static boolean convertJpg2Pdf(String strJpgFile, String strPdfFile) {
Document document= null;
RandomAccessFileOrArray rafa = null;
try {
fos = new FileOutputStream(strPdfFile);
PdfWriter.getInstance(document, fos);
// 打开文档
document = new Document();
PdfWriter.getInstance(document, new FileOutputStream(strPdfFile));
document.open();
// 获取图片的宽高
Image image = Image.getInstance(strJpgFile);
float floatImageHeight = image.getScaledHeight();
float floatImageWidth = image.getScaledWidth();
// 设置页面宽高与图片一致
Rectangle rectangle = new Rectangle(floatImageWidth, floatImageHeight);
document.setPageSize(rectangle);
// 图片居中
image.setAlignment(Image.ALIGN_CENTER);
//新建一页添加图片
document.newPage();
document.add(image);
} catch (Exception ioe) {
ioe.printStackTrace();
} finally {
//关闭文档
rafa = new RandomAccessFileOrArray(new FileChannelRandomAccessSource(new RandomAccessFile(strJpgFile, "r").getChannel()));
int pages = TiffImage.getNumberOfPages(rafa);
Image image;
for (int i = 1; i <= pages; i++) {
try {
image = TiffImage.getTiffImage(rafa, i);
image.scaleToFit(FIT_WIDTH, FIT_HEIGHT);
document.add(image);
} catch (Exception e) {
document.close();
rafa.close();
e.printStackTrace();
}
}
document.close();
rafa.close();
return true;
}
catch (Exception e)
{
System.out.println("错误:"+ e.getMessage());
}
finally {
document.close();
try {
assert fos != null;
fos.flush();
fos.close();
rafa.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return false;
}
/**
* TifPdfTif
*
* @param strTifFile tif
* @param strPdfFile pdf
* @return File
*/
public static File convertTif2Pdf(String strTifFile, String strPdfFile) {
try {
RandomAccessFileOrArray rafa = new RandomAccessFileOrArray(strTifFile);
Document document = new Document();
// 设置文档页边距
document.setMargins(0, 0, 0, 0);
PdfWriter.getInstance(document, new FileOutputStream(strPdfFile));
document.open();
int intPages = TiffImage.getNumberOfPages(rafa);
Image image;
File filePDF;
if (intPages == 1) {
String strJpg = strTifFile.substring(0, strTifFile.lastIndexOf(".")) + ".jpg";
File fileJpg = new File(strJpg);
List<String> listPic2Jpg = convertTif2Jpg(strTifFile, strJpg);
if (listPic2Jpg != null && fileJpg.exists()) {
convertJpg2Pdf(strJpg, strPdfFile);
}
} else {
for (int i = 1; i <= intPages; i++) {
image = TiffImage.getTiffImage(rafa, i);
// 设置页面宽高与图片一致
Rectangle pageSize = new Rectangle(image.getScaledWidth(), image.getScaledHeight());
document.setPageSize(pageSize);
// 图片居中
image.setAlignment(Image.ALIGN_CENTER);
//新建一页添加图片
document.newPage();
document.add(image);
}
document.close();
}
rafa.close();
filePDF = new File(strPdfFile);
return filePDF;
} catch (Exception e) {
logger.error(e.getMessage(), e);
}
return null;
}
}

View File

@ -3,16 +3,17 @@ package cn.keking.utils;
import cn.keking.config.ConfigConstants;
import cn.keking.model.FileAttribute;
import cn.keking.model.ReturnResponse;
import cn.keking.service.FileHandlerService;
import io.mola.galimatias.GalimatiasParseException;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
import org.springframework.web.util.HtmlUtils;
import java.io.*;
import java.net.*;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.UUID;
import static cn.keking.utils.KkFileUtils.isFtpUrl;
@ -36,13 +37,24 @@ public class DownloadUtils {
*/
public static ReturnResponse<String> downLoad(FileAttribute fileAttribute, String fileName) {
// 忽略ssl证书
String urlStr = null;
String urlStrr = null;
URL urll;
try {
SslUtils.ignoreSsl();
urlStr = fileAttribute.getUrl().replaceAll("\\+", "%20");
urll = new URL(urlStr);
urlStrr = URLDecoder.decode(urll.getPath(), "UTF-8");
} catch (Exception e) {
logger.error("忽略SSL证书异常:", e);
}
String urlStr = fileAttribute.getUrl().replaceAll("\\+", "%20");
ReturnResponse<String> response = new ReturnResponse<>(0, "下载成功!!!", "");
assert urlStr != null;
if (urlStr.contains("?fileKey=")) {
response.setContent(fileDir + urlStrr);
response.setMsg(fileName);
return response;
}
String realPath = DownloadUtils.getRelFilePath(fileName, fileAttribute);
if(!StringUtils.hasText(realPath)){
response.setCode(1);

View File

@ -0,0 +1,130 @@
package cn.keking.utils;
import cn.keking.config.ConfigConstants;
import cn.keking.service.ZtreeNodeVo;
import java.io.File;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author : Gao
* create : 2023-04-08
**/
public class RarUtils {
private static final String fileDir = ConfigConstants.getFileDir();
public static byte[] getUTF8BytesFromGBKString(String gbkStr) {
int n = gbkStr.length();
byte[] utfBytes = new byte[3 * n];
int k = 0;
for (int i = 0; i < n; i++) {
int m = gbkStr.charAt(i);
if (m < 128 && m >= 0) {
utfBytes[k++] = (byte) m;
continue;
}
utfBytes[k++] = (byte) (0xe0 | (m >> 12));
utfBytes[k++] = (byte) (0x80 | ((m >> 6) & 0x3f));
utfBytes[k++] = (byte) (0x80 | (m & 0x3f));
}
if (k < utfBytes.length) {
byte[] tmp = new byte[k];
System.arraycopy(utfBytes, 0, tmp, 0, k);
return tmp;
}
return utfBytes;
}
public static String getUtf8String(String str) {
if (str != null && str.length() > 0) {
String needEncodeCode = "ISO-8859-1";
String neeEncodeCode = "ISO-8859-2";
String gbkEncodeCode = "GBK";
try {
if (Charset.forName(needEncodeCode).newEncoder().canEncode(str)) {
str = new String(str.getBytes(needEncodeCode), StandardCharsets.UTF_8);
}
if (Charset.forName(neeEncodeCode).newEncoder().canEncode(str)) {
str = new String(str.getBytes(neeEncodeCode), StandardCharsets.UTF_8);
}
if (Charset.forName(gbkEncodeCode).newEncoder().canEncode(str)) {
str = new String(getUTF8BytesFromGBKString(str), StandardCharsets.UTF_8);
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return str;
}
/**
*
*/
private static boolean isChinese(char c) {
Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
return ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
|| ub == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
|| ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
|| ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
|| ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS;
}
public static boolean judge(char c){
return (c >= '0' && c <= '9') || (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z');
}
public static boolean isMessyCode(String strName) {
//去除字符串中的空格 制表符 换行 回车
Pattern p = Pattern.compile("\\s*|\t*|\r*|\n*");
Matcher m = p.matcher(strName);
String after = m.replaceAll("").replaceAll("\\+", "").replaceAll("#", "").replaceAll("&", "");
//去除字符串中的标点符号
String temp = after.replaceAll("\\p{P}", "");
//处理之后转换成字符数组
char[] ch = temp.trim().toCharArray();
for (char c : ch) {
//判断是否是数字或者英文字符
if (!judge(c)) {
//判断是否是中日韩文
if (!isChinese(c)) {
//如果不是数字或者英文字符也不是中日韩文则表示是乱码返回true
return true;
}
}
}
//表示不是乱码 返回false
return false;
}
/**
*
*/
public static List<ZtreeNodeVo> getTree(String rootPath) {
List<ZtreeNodeVo> nodes = new ArrayList<>();
File file = new File(fileDir+rootPath);
ZtreeNodeVo node = traverse(file);
nodes.add(node);
return nodes;
}
private static ZtreeNodeVo traverse(File file) {
ZtreeNodeVo pathNodeVo = new ZtreeNodeVo();
pathNodeVo.setId(file.getAbsolutePath().replace(fileDir, "").replace("\\", "/"));
pathNodeVo.setName(file.getName());
pathNodeVo.setPid(file.getParent().replace(fileDir, "").replace("\\", "/"));
if (file.isDirectory()) {
List<ZtreeNodeVo> subNodeVos = new ArrayList<>();
File[] subFiles = file.listFiles();
if (subFiles == null) {
return pathNodeVo;
}
for (File subFile : subFiles) {
ZtreeNodeVo subNodeVo = traverse(subFile);
subNodeVos.add(subNodeVo);
}
pathNodeVo.setChildren(subNodeVos);
}
return pathNodeVo;
}
}

View File

@ -3,6 +3,7 @@ package cn.keking.web.controller;
import cn.keking.config.ConfigConstants;
import cn.keking.model.ReturnResponse;
import cn.keking.utils.KkFileUtils;
import cn.keking.utils.RarUtils;
import cn.keking.utils.WebUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -20,12 +21,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.*;
/**
* @author yudian-it
@ -162,6 +158,21 @@ public class FileController {
return ReturnResponse.success(fileName);
}
@GetMapping("/directory")
public Object directory(String urls) {
String fileUrl;
try {
fileUrl = WebUtils.decodeUrl(urls);
} catch (Exception ex) {
String errorMsg = String.format(BASE64_DECODE_ERROR_MSG, "url");
return ReturnResponse.failure(errorMsg);
}
if (KkFileUtils.isIllegalFileName(fileUrl)) {
return ReturnResponse.failure("不允许访问的路径:");
}
return RarUtils.getTree(fileUrl);
}
private boolean existsFile(String fileName) {
File file = new File(fileDir + demoPath + fileName);
return file.exists();

View File

@ -1,8 +1 @@
/**
* Minified by jsDelivr using Terser v5.3.5.
* Original file: /npm/js-base64@3.6.0/base64.js
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):function(){const r=e.Base64,o=t();o.noConflict=()=>(e.Base64=r,o),e.Meteor&&(Base64=o),e.Base64=o}()}("undefined"!=typeof self?self:"undefined"!=typeof window?window:"undefined"!=typeof global?global:this,(function(){"use strict";const e="3.6.0",t="function"==typeof atob,r="function"==typeof btoa,o="function"==typeof Buffer,n="function"==typeof TextDecoder?new TextDecoder:void 0,a="function"==typeof TextEncoder?new TextEncoder:void 0,f=[..."ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="],i=(e=>{let t={};return e.forEach(((e,r)=>t[e]=r)),t})(f),c=/^(?:[A-Za-z\d+\/]{4})*?(?:[A-Za-z\d+\/]{2}(?:==)?|[A-Za-z\d+\/]{3}=?)?$/,u=String.fromCharCode.bind(String),s="function"==typeof Uint8Array.from?Uint8Array.from.bind(Uint8Array):(e,t=(e=>e))=>new Uint8Array(Array.prototype.slice.call(e,0).map(t)),d=e=>e.replace(/[+\/]/g,(e=>"+"==e?"-":"_")).replace(/=+$/m,""),l=e=>e.replace(/[^A-Za-z0-9\+\/]/g,""),h=e=>{let t,r,o,n,a="";const i=e.length%3;for(let i=0;i<e.length;){if((r=e.charCodeAt(i++))>255||(o=e.charCodeAt(i++))>255||(n=e.charCodeAt(i++))>255)throw new TypeError("invalid character found");t=r<<16|o<<8|n,a+=f[t>>18&63]+f[t>>12&63]+f[t>>6&63]+f[63&t]}return i?a.slice(0,i-3)+"===".substring(i):a},p=r?e=>btoa(e):o?e=>Buffer.from(e,"binary").toString("base64"):h,y=o?e=>Buffer.from(e).toString("base64"):e=>{let t=[];for(let r=0,o=e.length;r<o;r+=4096)t.push(u.apply(null,e.subarray(r,r+4096)));return p(t.join(""))},A=(e,t=!1)=>t?d(y(e)):y(e),b=e=>{if(e.length<2)return(t=e.charCodeAt(0))<128?e:t<2048?u(192|t>>>6)+u(128|63&t):u(224|t>>>12&15)+u(128|t>>>6&63)+u(128|63&t);var t=65536+1024*(e.charCodeAt(0)-55296)+(e.charCodeAt(1)-56320);return u(240|t>>>18&7)+u(128|t>>>12&63)+u(128|t>>>6&63)+u(128|63&t)},g=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g,B=e=>e.replace(g,b),x=o?e=>Buffer.from(e,"utf8").toString("base64"):a?e=>y(a.encode(e)):e=>p(B(e)),C=(e,t=!1)=>t?d(x(e)):x(e),m=e=>C(e,!0),U=/[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g,F=e=>{switch(e.length){case 4:var t=((7&e.charCodeAt(0))<<18|(63&e.charCodeAt(1))<<12|(63&e.charCodeAt(2))<<6|63&e.charCodeAt(3))-65536;return u(55296+(t>>>10))+u(56320+(1023&t));case 3:return u((15&e.charCodeAt(0))<<12|(63&e.charCodeAt(1))<<6|63&e.charCodeAt(2));default:return u((31&e.charCodeAt(0))<<6|63&e.charCodeAt(1))}},w=e=>e.replace(U,F),S=e=>{if(e=e.replace(/\s+/g,""),!c.test(e))throw new TypeError("malformed base64.");e+="==".slice(2-(3&e.length));let t,r,o,n="";for(let a=0;a<e.length;)t=i[e.charAt(a++)]<<18|i[e.charAt(a++)]<<12|(r=i[e.charAt(a++)])<<6|(o=i[e.charAt(a++)]),n+=64===r?u(t>>16&255):64===o?u(t>>16&255,t>>8&255):u(t>>16&255,t>>8&255,255&t);return n},E=t?e=>atob(l(e)):o?e=>Buffer.from(e,"base64").toString("binary"):S,v=o?e=>s(Buffer.from(e,"base64")):e=>s(E(e),(e=>e.charCodeAt(0))),D=e=>v(z(e)),R=o?e=>Buffer.from(e,"base64").toString("utf8"):n?e=>n.decode(v(e)):e=>w(E(e)),z=e=>l(e.replace(/[-_]/g,(e=>"-"==e?"+":"/"))),T=e=>R(z(e)),Z=e=>({value:e,enumerable:!1,writable:!0,configurable:!0}),j=function(){const e=(e,t)=>Object.defineProperty(String.prototype,e,Z(t));e("fromBase64",(function(){return T(this)})),e("toBase64",(function(e){return C(this,e)})),e("toBase64URI",(function(){return C(this,!0)})),e("toBase64URL",(function(){return C(this,!0)})),e("toUint8Array",(function(){return D(this)}))},I=function(){const e=(e,t)=>Object.defineProperty(Uint8Array.prototype,e,Z(t));e("toBase64",(function(e){return A(this,e)})),e("toBase64URI",(function(){return A(this,!0)})),e("toBase64URL",(function(){return A(this,!0)}))},O={version:e,VERSION:"3.6.0",atob:E,atobPolyfill:S,btoa:p,btoaPolyfill:h,fromBase64:T,toBase64:C,encode:C,encodeURI:m,encodeURL:m,utob:B,btou:w,decode:T,isValid:e=>{if("string"!=typeof e)return!1;const t=e.replace(/\s+/g,"").replace(/=+$/,"");return!/[^\s0-9a-zA-Z\+/]/.test(t)||!/[^\s0-9a-zA-Z\-_]/.test(t)},fromUint8Array:A,toUint8Array:D,extendString:j,extendUint8Array:I,extendBuiltins:()=>{j(),I()},Base64:{}};return Object.keys(O).forEach((e=>O.Base64[e]=O[e])),O}));
//# sourceMappingURL=/sm/8bca8602e2256d240cef904e1c1df432ccfdd2a2a73f6911c60be79e526e3e1e.map
(function(global,factory){typeof exports==="object"&&typeof module!=="undefined"?module.exports=factory(global):typeof define==="function"&&define.amd?define(factory):factory(global)}((typeof self!=="undefined"?self:typeof window!=="undefined"?window:typeof global!=="undefined"?global:this),function(global){global=global||{};var _Base64=global.Base64;var version="2.6.3";var b64chars="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";var b64tab=function(bin){var t={};for(var i=0,l=bin.length;i<l;i++){t[bin.charAt(i)]=i}return t}(b64chars);var fromCharCode=String.fromCharCode;var cb_utob=function(c){if(c.length<2){var cc=c.charCodeAt(0);return cc<128?c:cc<2048?(fromCharCode(192|(cc>>>6))+fromCharCode(128|(cc&63))):(fromCharCode(224|((cc>>>12)&15))+fromCharCode(128|((cc>>>6)&63))+fromCharCode(128|(cc&63)))}else{var cc=65536+(c.charCodeAt(0)-55296)*1024+(c.charCodeAt(1)-56320);return(fromCharCode(240|((cc>>>18)&7))+fromCharCode(128|((cc>>>12)&63))+fromCharCode(128|((cc>>>6)&63))+fromCharCode(128|(cc&63)))}};var re_utob=/[\uD800-\uDBFF][\uDC00-\uDFFFF]|[^\x00-\x7F]/g;var utob=function(u){return u.replace(re_utob,cb_utob)};var cb_encode=function(ccc){var padlen=[0,2,1][ccc.length%3],ord=ccc.charCodeAt(0)<<16|((ccc.length>1?ccc.charCodeAt(1):0)<<8)|((ccc.length>2?ccc.charCodeAt(2):0)),chars=[b64chars.charAt(ord>>>18),b64chars.charAt((ord>>>12)&63),padlen>=2?"=":b64chars.charAt((ord>>>6)&63),padlen>=1?"=":b64chars.charAt(ord&63)];return chars.join("")};var btoa=global.btoa&&typeof global.btoa=="function"?function(b){return global.btoa(b)}:function(b){if(b.match(/[^\x00-\xFF]/)){throw new RangeError("The string contains invalid characters.")}return b.replace(/[\s\S]{1,3}/g,cb_encode)};var _encode=function(u){return btoa(utob(String(u)))};var mkUriSafe=function(b64){return b64.replace(/[+\/]/g,function(m0){return m0=="+"?"-":"_"}).replace(/=/g,"")};var encode=function(u,urisafe){return urisafe?mkUriSafe(_encode(u)):_encode(u)};var encodeURI=function(u){return encode(u,true)};var fromUint8Array;if(global.Uint8Array){fromUint8Array=function(a,urisafe){var b64="";for(var i=0,l=a.length;i<l;i+=3){var a0=a[i],a1=a[i+1],a2=a[i+2];var ord=a0<<16|a1<<8|a2;b64+=b64chars.charAt(ord>>>18)+b64chars.charAt((ord>>>12)&63)+(typeof a1!="undefined"?b64chars.charAt((ord>>>6)&63):"=")+(typeof a2!="undefined"?b64chars.charAt(ord&63):"=")}return urisafe?mkUriSafe(b64):b64}}var re_btou=/[\xC0-\xDF][\x80-\xBF]|[\xE0-\xEF][\x80-\xBF]{2}|[\xF0-\xF7][\x80-\xBF]{3}/g;var cb_btou=function(cccc){switch(cccc.length){case 4:var cp=((7&cccc.charCodeAt(0))<<18)|((63&cccc.charCodeAt(1))<<12)|((63&cccc.charCodeAt(2))<<6)|(63&cccc.charCodeAt(3)),offset=cp-65536;return(fromCharCode((offset>>>10)+55296)+fromCharCode((offset&1023)+56320));case 3:return fromCharCode(((15&cccc.charCodeAt(0))<<12)|((63&cccc.charCodeAt(1))<<6)|(63&cccc.charCodeAt(2)));default:return fromCharCode(((31&cccc.charCodeAt(0))<<6)|(63&cccc.charCodeAt(1)))}};var btou=function(b){return b.replace(re_btou,cb_btou)};var cb_decode=function(cccc){var len=cccc.length,padlen=len%4,n=(len>0?b64tab[cccc.charAt(0)]<<18:0)|(len>1?b64tab[cccc.charAt(1)]<<12:0)|(len>2?b64tab[cccc.charAt(2)]<<6:0)|(len>3?b64tab[cccc.charAt(3)]:0),chars=[fromCharCode(n>>>16),fromCharCode((n>>>8)&255),fromCharCode(n&255)];chars.length-=[0,0,2,1][padlen];return chars.join("")};var _atob=global.atob&&typeof global.atob=="function"?function(a){return global.atob(a)}:function(a){return a.replace(/\S{1,4}/g,cb_decode)};var atob=function(a){return _atob(String(a).replace(/[^A-Za-z0-9\+\/]/g,""))};var _decode=function(a){return btou(_atob(a))};var _fromURI=function(a){return String(a).replace(/[-_]/g,function(m0){return m0=="-"?"+":"/"}).replace(/[^A-Za-z0-9\+\/]/g,"")};var decode=function(a){return _decode(_fromURI(a))};var toUint8Array;if(global.Uint8Array){toUint8Array=function(a){return Uint8Array.from(atob(_fromURI(a)),function(c){return c.charCodeAt(0)})}}var noConflict=function(){var Base64=global.Base64;global.Base64=_Base64;return Base64};global.Base64={VERSION:version,atob:atob,btoa:btoa,fromBase64:decode,toBase64:encode,utob:utob,encode:encode,encodeURI:encodeURI,btou:btou,decode:decode,noConflict:noConflict,fromUint8Array:fromUint8Array,toUint8Array:toUint8Array};if(typeof Object.defineProperty==="function"){var noEnum=function(v){return{value:v,enumerable:false,writable:true,configurable:true}};global.Base64.extendString=function(){Object.defineProperty(String.prototype,"fromBase64",noEnum(function(){return decode(this)}));Object.defineProperty(String.prototype,"toBase64",noEnum(function(urisafe){return encode(this,urisafe)}));Object.defineProperty(String.prototype,"toBase64URI",noEnum(function(){return encode(this,true)}))}}if(global["Meteor"]){Base64=global.Base64}if(typeof module!=="undefined"&&module.exports){module.exports.Base64=global.Base64}else{if(typeof define==="function"&&define.amd){define([],function(){return global.Base64})}}return{Base64:global.Base64}}));

View File

@ -25685,7 +25685,7 @@
if (!e)
return t;
if (!g || "" == y) {
var r, i = 10, o = l(e.pages);
var r, i = e.pages.length, o = l(e.pages);
try {
for (o.s(); !(r = o.n()).done; ) {
var a = r.value

File diff suppressed because one or more lines are too long

View File

@ -10,18 +10,15 @@
<meta name=keywords content="Xmind,mindmap,mind map,mind mapping,mind mapping software,free mind mapping software,work from home,WFH,remote">
<link rel=stylesheet href=css/bootstrap-customized-2821153174.min.css>
<link rel=stylesheet href=css/index-5376440060.css>
<script src=js/jquery-3-c9f5aeeca3.2.1.min.js> </script>
<script src="../js/jquery-3.6.1.min.js"></script>
<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">
<link rel=stylesheet href=css/share-embed-39eba5407f.css> </head>
<body>
<script>
window.manifests={snowbrush:"js/snowbrush.js"},window.metadataString=""
</script>
<script src=js/text-autospace-fed758f4a6.min.js> </script>
<script src=js/polyfill-45b9836beb.min.js> </script>
<script src=js/js-cookie-a978ac7394.js> </script>
<script src=js/popper-135fa9e662.min.js> </script>
<script src=js/bootstrap-26779614c4.min.js> </script>
<script src=js/base.61517cade8.js> </script>
<script src=js/share-embed.68f7476360.js> </script>
</body>

File diff suppressed because one or more lines are too long

View File

@ -1,108 +1,71 @@
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
<#include "*/commonHeader.ftl">
<script src="js/jquery-3.6.1.min.js" type="text/javascript"></script>
<link href="css/zTreeStyle.css" rel="stylesheet" type="text/css">
<script src="js/base64.min.js" type="text/javascript"></script>
<style type="text/css">
<meta charset="utf-8"/>
<title></title>
<script src="js/jquery-3.6.1.min.js"></script>
<#include "*/commonHeader.ftl">
<script src="js/base64.min.js" type="text/javascript"></script>
<link href="css/zTreeStyle.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="js/jquery.ztree.core.js"></script>
<style type="text/css">
body {
background-color: #404040;
}
h1, h2, h3, h4, h5, h6 {color: #2f332a;font-weight: bold;font-family: Helvetica, Arial, sans-serif;padding-bottom: 5px;}
h1 {font-size: 24px;line-height: 34px;text-align: center;}
h2 {font-size: 14px;line-height: 24px;padding-top: 5px;}
h6 {font-weight: normal;font-size: 12px;letter-spacing: 1px;line-height: 24px;text-align: center;}
a {color:#3C6E31;text-decoration: underline;}
a:hover {background-color:#3C6E31;color:white;}
code {color: #2f332a;}
div.zTreeDemoBackground {width:600px;text-align:center;margin: 0 auto;background-color: #ffffff;}
div.zTreeDemoBackground {
max-width: 880px;
text-align:center;
margin:0 auto;
border-radius:3px;
box-shadow:rgba(0,0,0,0.15) 0 0 8px;
background:#FBFBFB;
border:1px solid #ddd;
margin:1px auto;
padding:5px;
}
</style>
</head>
<body>
<div class="zTreeDemoBackground left">
<h1>kkFileView</h1>
<ul id="treeDemo" class="ztree"></ul>
</div>
<script type="text/javascript" src="js/jquery.ztree.core.js"></script>
<script type="text/javascript">
const data = JSON.parse('${fileTree}');
var baseUrl = "${baseUrl}";
var setting = {
view: {
fontCss : {"color":"blue"},
showLine: true
},
<script>
var settings = {
data: {
key: {
children: 'childList',
name: 'originName'
simpleData: {
enable: true, //true 、 false 分别表示 使用 、 不使用 简单数据模式
idKey: "id", //节点数据中保存唯一标识的属性名称
pIdKey: "pid", //节点数据中保存其父节点唯一标识的属性名称
rootPId: ""
}
},
callback:{
beforeClick:function (treeId, treeNode, clickFlag) {
console.log("节点参数treeId-" + treeId + "treeNode-"
+ JSON.stringify(treeNode) + "clickFlag-" + clickFlag);
},
onClick:function (event, treeId, treeNode) {
if (!treeNode.directory) {
/**实现窗口最大化**/
var fulls = "left=0,screenX=0,top=0,screenY=0,scrollbars=1"; //定义弹出窗口的参数
if (window.screen) {
var ah = screen.availHeight - 30;
var aw = (screen.availWidth - 10) / 2;
fulls += ",height=" + ah;
fulls += ",innerHeight=" + ah;
fulls += ",width=" + aw;
fulls += ",innerWidth=" + aw;
fulls += ",resizable"
} else {
fulls += ",resizable"; // 对于不支持screen属性的浏览器可以手工进行最大化。 manually
}
var previewUrl = baseUrl + treeNode.fileName +"?fileKey="+ treeNode.fileKey;
window.open("onlinePreview?url=" + encodeURIComponent(Base64.encode(previewUrl)), "_blank",fulls);
}
}
callback: {
onClick: chooseNode,
}
};
var height = 0;
$(document).ready(function(){
var treeObj = $.fn.zTree.init($("#treeDemo"), setting, data);
treeObj.expandAll(true);
height = getZtreeDomHeight();
$(".zTreeDemoBackground").css("height", height);
function chooseNode(event, treeId, treeNode) {
var path = '${baseUrl}' + treeNode.id +"?fileKey="+'${fileName}';
location.href = "${baseUrl}onlinePreview?url=" + encodeURIComponent(Base64.encode(path));
}
$(document).ready(function () {
var url = '${fileTree}';
$.ajax({
type: "get",
url: "${baseUrl}directory?urls="+encodeURIComponent(Base64.encode(url)),
success: function (res) {
zTreeObj = $.fn.zTree.init($("#treeDemo"), settings, res); //初始化树
zTreeObj.expandAll(true); //true 节点全部展开、false节点收缩
}
});
});
/*初始化水印*/
window.onload = function() {
initWaterMark();
}
/**
* ztreedom
*/
function getZtreeDomHeight() {
return $("#treeDemo").height() > window.document.documentElement.clientHeight - 1
? $("#treeDemo").height() : window.document.documentElement.clientHeight - 1;
}
/**
*
*/
window.onresize = function(){
height = getZtreeDomHeight();
$(".zTreeDemoBackground").css("height", height);
}
/**
*
*/
window.onscroll = function(){
height = getZtreeDomHeight();
$(".zTreeDemoBackground").css("height", height);
}
</script>
</body>
</html>
</html>

View File

@ -80,7 +80,7 @@
</div>
<!-- JavaSript ================================================== -->
<script src="pptx/jquery-3.5.1.min.js"></script>
<script src="js/jquery-3.6.1.min.js"></script>
<script src="pptx/jquery.contextMenu.js?v=11.2.5_20210128"></script>
<script src="pptx/idocv/idocv_common.min.js"></script>
<script src="pptx/jquery.mobile-events.min.js"></script>