mirror of
https://gitee.com/kekingcn/file-online-preview.git
synced 2026-09-13 16:34:53 +00:00
Compare commits
3 Commits
release/5.
...
pr731
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6df85be1b | ||
|
|
1568b3023d | ||
|
|
f97ed04ab0 |
@@ -46,6 +46,12 @@ public class WebConfig implements WebMvcConfigurer {
|
|||||||
filterUri.add("/onlinePreview");
|
filterUri.add("/onlinePreview");
|
||||||
filterUri.add("/picturesPreview");
|
filterUri.add("/picturesPreview");
|
||||||
filterUri.add("/getCorsFile");
|
filterUri.add("/getCorsFile");
|
||||||
|
filterUri.add("/addTask");
|
||||||
|
filterUri.add("/pdfjs/web/viewer.html");
|
||||||
|
filterUri.add("/msg/index.html");
|
||||||
|
filterUri.add("/eml/index.html");
|
||||||
|
filterUri.add("/heic/index.html");
|
||||||
|
filterUri.add("/drawio/index.html");
|
||||||
TrustHostFilter filter = new TrustHostFilter();
|
TrustHostFilter filter = new TrustHostFilter();
|
||||||
FilterRegistrationBean<TrustHostFilter> registrationBean = new FilterRegistrationBean<>();
|
FilterRegistrationBean<TrustHostFilter> registrationBean = new FilterRegistrationBean<>();
|
||||||
registrationBean.setFilter(filter);
|
registrationBean.setFilter(filter);
|
||||||
@@ -59,6 +65,7 @@ public class WebConfig implements WebMvcConfigurer {
|
|||||||
filterUri.add("/onlinePreview");
|
filterUri.add("/onlinePreview");
|
||||||
filterUri.add("/picturesPreview");
|
filterUri.add("/picturesPreview");
|
||||||
filterUri.add("/getCorsFile");
|
filterUri.add("/getCorsFile");
|
||||||
|
filterUri.add("/addTask");
|
||||||
TrustDirFilter filter = new TrustDirFilter();
|
TrustDirFilter filter = new TrustDirFilter();
|
||||||
FilterRegistrationBean<TrustDirFilter> registrationBean = new FilterRegistrationBean<>();
|
FilterRegistrationBean<TrustDirFilter> registrationBean = new FilterRegistrationBean<>();
|
||||||
registrationBean.setFilter(filter);
|
registrationBean.setFilter(filter);
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ public enum FileType {
|
|||||||
|
|
||||||
private static final String[] OFFICE_TYPES = {"docx", "wps", "doc", "docm", "xls", "xlsx", "csv" ,"xlsm", "ppt", "pptx", "vsd", "rtf", "odt", "wmf", "emf", "dps", "et", "ods", "ots", "tsv", "odp", "otp", "sxi", "ott", "vsdx", "fodt", "fods", "xltx","tga","psd","dotm","ett","xlt","xltm","wpt","dot","xlam","dotx","xla","pages", "eps", "pptm"};
|
private static final String[] OFFICE_TYPES = {"docx", "wps", "doc", "docm", "xls", "xlsx", "csv" ,"xlsm", "ppt", "pptx", "vsd", "rtf", "odt", "wmf", "emf", "dps", "et", "ods", "ots", "tsv", "odp", "otp", "sxi", "ott", "vsdx", "fodt", "fods", "xltx","tga","psd","dotm","ett","xlt","xltm","wpt","dot","xlam","dotx","xla","pages", "eps", "pptm"};
|
||||||
private static final String[] PICTURE_TYPES = {"jpg", "jpeg", "png", "gif", "bmp", "ico", "jfif", "webp", "heic", "avif", "heif"};
|
private static final String[] PICTURE_TYPES = {"jpg", "jpeg", "png", "gif", "bmp", "ico", "jfif", "webp", "heic", "avif", "heif"};
|
||||||
private static final String[] ARCHIVE_TYPES = {"rar", "zip", "jar", "7-zip", "tar", "gzip", "7z"};
|
private static final String[] ARCHIVE_TYPES = {"rar", "zip", "jar", "7-zip", "tar", "gzip", "7z", "tgz"};
|
||||||
private static final String[] ONLINE3D_TYPES = {"obj", "3ds", "stl", "ply", "off", "3dm", "fbx", "dae", "wrl", "3mf", "ifc","glb","o3dv","gltf","stp","bim","fcstd","step","iges","brep"};
|
private static final String[] ONLINE3D_TYPES = {"obj", "3ds", "stl", "ply", "off", "3dm", "fbx", "dae", "wrl", "3mf", "ifc","glb","o3dv","gltf","stp","bim","fcstd","step","iges","brep"};
|
||||||
private static final String[] EML_TYPES = {"eml"};
|
private static final String[] EML_TYPES = {"eml"};
|
||||||
private static final String[] MSG_TYPES = {"msg"};
|
private static final String[] MSG_TYPES = {"msg"};
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ package cn.keking.service;
|
|||||||
import cn.keking.model.FileAttribute;
|
import cn.keking.model.FileAttribute;
|
||||||
import cn.keking.model.FileType;
|
import cn.keking.model.FileType;
|
||||||
import cn.keking.service.cache.CacheService;
|
import cn.keking.service.cache.CacheService;
|
||||||
|
import cn.keking.web.filter.TrustDirFilter;
|
||||||
|
import cn.keking.web.filter.TrustHostFilter;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@@ -58,6 +60,10 @@ public class FileConvertQueueTask {
|
|||||||
try {
|
try {
|
||||||
url = cacheService.takeQueueTask();
|
url = cacheService.takeQueueTask();
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
|
if (!TrustHostFilter.isTrustedSourceUrl(url) || !TrustDirFilter.isTrustedFileUrl(url)) {
|
||||||
|
logger.warn("拒绝处理不受信任的预览转换任务,url:{}", url);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
FileAttribute fileAttribute = fileHandlerService.getFileAttribute(url, null);
|
FileAttribute fileAttribute = fileHandlerService.getFileAttribute(url, null);
|
||||||
FileType fileType = fileAttribute.getType();
|
FileType fileType = fileAttribute.getType();
|
||||||
logger.info("正在处理预览转换任务,url:{},预览类型:{}", url, fileType);
|
logger.info("正在处理预览转换任务,url:{},预览类型:{}", url, fileType);
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import java.io.InputStream;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.file.DirectoryStream;
|
import java.nio.file.DirectoryStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.InvalidPathException;
|
||||||
import java.nio.file.Path;
|
import java.nio.file.Path;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.attribute.BasicFileAttributes;
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
@@ -147,6 +148,28 @@ public class FileController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Path getDemoBasePath() {
|
||||||
|
return Paths.get(fileDir, demoDir).toAbsolutePath().normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path resolveDemoPath(String path) {
|
||||||
|
Path demoBasePath = getDemoBasePath();
|
||||||
|
try {
|
||||||
|
if (ObjectUtils.isEmpty(path)) {
|
||||||
|
return demoBasePath;
|
||||||
|
}
|
||||||
|
Path normalizedPath = demoBasePath.resolve(path).normalize();
|
||||||
|
if (!normalizedPath.startsWith(demoBasePath)) {
|
||||||
|
logger.warn("检测到非法目录访问,path:{}", path);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return normalizedPath;
|
||||||
|
} catch (InvalidPathException e) {
|
||||||
|
logger.warn("解析目录路径失败,path:{}", path, e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@PostMapping("/fileUpload")
|
@PostMapping("/fileUpload")
|
||||||
public ReturnResponse<Object> fileUpload(@RequestParam("file") MultipartFile file,
|
public ReturnResponse<Object> fileUpload(@RequestParam("file") MultipartFile file,
|
||||||
@RequestParam(value = "path", defaultValue = "") String path) {
|
@RequestParam(value = "path", defaultValue = "") String path) {
|
||||||
@@ -341,17 +364,20 @@ public class FileController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ==================== 2. 构建路径和验证 ====================
|
// ==================== 2. 构建路径和验证 ====================
|
||||||
String basePath = fileDir + demoPath;
|
Path resolvedPath = resolveDemoPath(path);
|
||||||
if (!ObjectUtils.isEmpty(path)) {
|
if (resolvedPath == null) {
|
||||||
basePath += path + File.separator;
|
result.put("total", 0);
|
||||||
|
result.put("data", Collections.emptyList());
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
File currentDir = new File(basePath);
|
File currentDir = resolvedPath.toFile();
|
||||||
if (!currentDir.exists() || !currentDir.isDirectory()) {
|
if (!currentDir.exists() || !currentDir.isDirectory()) {
|
||||||
result.put("total", 0);
|
result.put("total", 0);
|
||||||
result.put("data", Collections.emptyList());
|
result.put("data", Collections.emptyList());
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
String basePath = resolvedPath.toString();
|
||||||
|
|
||||||
// ==================== 3. 收集所有文件路径 ====================
|
// ==================== 3. 收集所有文件路径 ====================
|
||||||
List<Path> allPaths = new ArrayList<>();
|
List<Path> allPaths = new ArrayList<>();
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import cn.keking.service.FilePreviewFactory;
|
|||||||
import cn.keking.service.cache.CacheService;
|
import cn.keking.service.cache.CacheService;
|
||||||
import cn.keking.service.impl.OtherFilePreviewImpl;
|
import cn.keking.service.impl.OtherFilePreviewImpl;
|
||||||
import cn.keking.utils.*;
|
import cn.keking.utils.*;
|
||||||
|
import cn.keking.web.filter.TrustDirFilter;
|
||||||
|
import cn.keking.web.filter.TrustHostFilter;
|
||||||
import fr.opensagres.xdocreport.core.io.IOUtils;
|
import fr.opensagres.xdocreport.core.io.IOUtils;
|
||||||
import org.apache.commons.codec.binary.Base64;
|
import org.apache.commons.codec.binary.Base64;
|
||||||
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
import org.apache.hc.client5.http.impl.classic.CloseableHttpClient;
|
||||||
@@ -231,6 +233,11 @@ public class OnlinePreviewController {
|
|||||||
logger.info("{},url:{}", errorMsg, fileUrls);
|
logger.info("{},url:{}", errorMsg, fileUrls);
|
||||||
return errorMsg;
|
return errorMsg;
|
||||||
}
|
}
|
||||||
|
if (!TrustHostFilter.isTrustedSourceUrl(fileUrls) || !TrustDirFilter.isTrustedFileUrl(fileUrls)) {
|
||||||
|
String errorMsg = "访问不合法:来源地址不受信任!";
|
||||||
|
logger.info("{},url:{}", errorMsg, fileUrls);
|
||||||
|
return errorMsg;
|
||||||
|
}
|
||||||
logger.info("添加转码队列url:{}", fileUrls);
|
logger.info("添加转码队列url:{}", fileUrls);
|
||||||
cacheService.addQueueTask(fileUrls);
|
cacheService.addQueueTask(fileUrls);
|
||||||
return "success";
|
return "success";
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ import java.util.Locale;
|
|||||||
public class TrustDirFilter implements Filter {
|
public class TrustDirFilter implements Filter {
|
||||||
|
|
||||||
private String notTrustDirView;
|
private String notTrustDirView;
|
||||||
private final Logger logger = LoggerFactory.getLogger(TrustDirFilter.class);
|
private static final Logger logger = LoggerFactory.getLogger(TrustDirFilter.class);
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -59,6 +59,47 @@ public class TrustDirFilter implements Filter {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isTrustedFileUrl(String urlPath) {
|
||||||
|
// 判断URL是否合法
|
||||||
|
if (KkFileUtils.isIllegalFileName(urlPath) || !StringUtils.hasText(urlPath) || !WebUtils.isValidUrl(urlPath)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
URL url = WebUtils.normalizedURL(urlPath);
|
||||||
|
|
||||||
|
if ("file".equals(url.getProtocol().toLowerCase(Locale.ROOT))) {
|
||||||
|
String filePath = URLDecoder.decode(url.getPath(), StandardCharsets.UTF_8.name());
|
||||||
|
// 将文件路径转换为File对象
|
||||||
|
File targetFile = new File(filePath);
|
||||||
|
// 将配置目录也转换为File对象
|
||||||
|
File fileDir = new File(ConfigConstants.getFileDir());
|
||||||
|
File localPreviewDir = new File(ConfigConstants.getLocalPreviewDir());
|
||||||
|
try {
|
||||||
|
// 获取规范路径
|
||||||
|
String canonicalFilePath = targetFile.getCanonicalPath();
|
||||||
|
String canonicalFileDir = fileDir.getCanonicalPath();
|
||||||
|
String canonicalLocalPreviewDir = localPreviewDir.getCanonicalPath();
|
||||||
|
return isSubDirectory(canonicalFileDir, canonicalFilePath) || isSubDirectory(canonicalLocalPreviewDir, canonicalFilePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
LoggerFactory.getLogger(TrustDirFilter.class).warn("获取规范路径失败,使用原始路径比较", e);
|
||||||
|
String absFilePath = targetFile.getAbsolutePath();
|
||||||
|
String absFileDir = fileDir.getAbsolutePath();
|
||||||
|
String absLocalPreviewDir = localPreviewDir.getAbsolutePath();
|
||||||
|
absFilePath = absFilePath.replace('\\', '/');
|
||||||
|
absFileDir = absFileDir.replace('\\', '/');
|
||||||
|
absLocalPreviewDir = absLocalPreviewDir.replace('\\', '/');
|
||||||
|
if (!absFileDir.endsWith("/")) absFileDir += "/";
|
||||||
|
if (!absLocalPreviewDir.endsWith("/")) absLocalPreviewDir += "/";
|
||||||
|
return absFilePath.startsWith(absFileDir) || absFilePath.startsWith(absLocalPreviewDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
} catch (IOException | GalimatiasParseException e) {
|
||||||
|
LoggerFactory.getLogger(TrustDirFilter.class).error("解析URL异常,url:{}", urlPath, e);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean allowPreview(String urlPath) {
|
private boolean allowPreview(String urlPath) {
|
||||||
// 判断URL是否合法
|
// 判断URL是否合法
|
||||||
if (KkFileUtils.isIllegalFileName(urlPath) || !StringUtils.hasText(urlPath) || !WebUtils.isValidUrl(urlPath)) {
|
if (KkFileUtils.isIllegalFileName(urlPath) || !StringUtils.hasText(urlPath) || !WebUtils.isValidUrl(urlPath)) {
|
||||||
@@ -107,7 +148,7 @@ public class TrustDirFilter implements Filter {
|
|||||||
/**
|
/**
|
||||||
* 检查子路径是否在父路径下(跨平台)
|
* 检查子路径是否在父路径下(跨平台)
|
||||||
*/
|
*/
|
||||||
private boolean isSubDirectory(String parentDir, String childPath) {
|
private static boolean isSubDirectory(String parentDir, String childPath) {
|
||||||
try {
|
try {
|
||||||
File parent = new File(parentDir);
|
File parent = new File(parentDir);
|
||||||
File child = new File(childPath);
|
File child = new File(childPath);
|
||||||
|
|||||||
@@ -48,7 +48,10 @@ public class TrustHostFilter implements Filter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
|
||||||
String url = WebUtils.getSourceUrl(request);
|
String url = request.getParameter("file");
|
||||||
|
if (url == null || url.trim().isEmpty()) {
|
||||||
|
url = WebUtils.getSourceUrl(request);
|
||||||
|
}
|
||||||
String host = WebUtils.getHost(url);
|
String host = WebUtils.getHost(url);
|
||||||
if (isNotTrustHost(host) || !WebUtils.isValidUrl(url)) {
|
if (isNotTrustHost(host) || !WebUtils.isValidUrl(url)) {
|
||||||
String currentHost = host == null ? "UNKNOWN" : host;
|
String currentHost = host == null ? "UNKNOWN" : host;
|
||||||
@@ -67,6 +70,14 @@ public class TrustHostFilter implements Filter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static boolean isTrustedSourceUrl(String url) {
|
||||||
|
if (!WebUtils.isValidUrl(url)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
String host = WebUtils.getHost(url);
|
||||||
|
return !new TrustHostFilter().isNotTrustHost(host);
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isNotTrustHost(String host) {
|
public boolean isNotTrustHost(String host) {
|
||||||
if (host == null || host.trim().isEmpty()) {
|
if (host == null || host.trim().isEmpty()) {
|
||||||
logger.warn("主机名为空或无效,拒绝访问");
|
logger.warn("主机名为空或无效,拒绝访问");
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,302 +0,0 @@
|
|||||||
|
|
||||||
<div id="IconMenuPanel">
|
|
||||||
<div id="rdialogx_d" class="float_dialog2_fixed">
|
|
||||||
<div id="icon_menu_panel" style="border:1" class="div_icon_menu_panel" >
|
|
||||||
|
|
||||||
<table id="savelinksHeaderTable" width="270" border="0" cellspacing="0" border-spacing="0" id="savelinks_table">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link2">
|
|
||||||
<div id="dummy_header" class="tagSaveLinkHeader" style="text-indent: 1em;">Location Setup</div>
|
|
||||||
<div style="float:right;margin-right:-34px;margin-top:-24px;" id="CloseObjectMenuX"></div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<table id="savelinksTable" width="270" border="0" cellspacing="0" border-spacing="0">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="dummy">
|
|
||||||
<canvas width="5" height="5"></canvas>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
xxxx
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="save_drawing">
|
|
||||||
<img id="save_drawing_image" class="icon_img" src="../app/images/tools/SaveChanges_240x22_Inactive.png" border="0">
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="dummy">
|
|
||||||
<canvas width="5" height="5"></canvas>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<div id="link_tags_table">
|
|
||||||
|
|
||||||
<table id="savelinksTable_select" width="270" border="0" cellspacing="0" border-spacing="0" id="savelinks_table">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
____
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="unlink_location" class="select_link_text">Unlink Location</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="done_editing_location" class="select_link_text"></div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="edit_cancel_location" class="select_link_text">Edit Fields</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="dummy">
|
|
||||||
<canvas width="5" height="5"></canvas>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<div id="location_text_dynamic">
|
|
||||||
|
|
||||||
<table id="locationTagsTable2" width="270" border="0" cellspacing="0" border-spacing="0">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link10_id_datalayer_name">
|
|
||||||
<div id="loc_text" class="location_text">Connector</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link11" class="dropdown">
|
|
||||||
<span class="dropdown-toggle" role="button" data-toggle="dropdown" href="#" data-target="#" id="drop_link_spaces">None Selected<b class="caret"></b></span>
|
|
||||||
<ul id="spaces_drawing" class="dropdown-menu" role="menu" aria-labelledby="drop_link_spaces">
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<canvas width="10" height="10"></canvas>
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link12A">
|
|
||||||
<div id="layer_text" class="location_text">Layer</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link13A">
|
|
||||||
<input id="layer_tag" type="text" class="input_tags" value=""/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link12">
|
|
||||||
<div id="loc_text" class="location_text">Type</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link13">
|
|
||||||
<input id="type_tag" type="text" class="input_tags" value=""/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link14">
|
|
||||||
<div id="loc_text" class="location_text">Occupancy</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<input id="occupancy_tag" type="text" class="input_tags" value=""/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td VALIGN=TOP>
|
|
||||||
<div id="loc_text" class="location_text_tags">Tags</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link16">
|
|
||||||
<textarea id="other_tags" class="styled_text_area"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="location_text_static">
|
|
||||||
|
|
||||||
<table id="locationTagsTable" width="270" border="0" cellspacing="0" border-spacing="0" >
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link10_s">
|
|
||||||
<div id="loc_text" class="location_text">Name</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link11_s" class="location_text">
|
|
||||||
<div id="location_s" class="location_text2">None Selected</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link12A_s">
|
|
||||||
<div id="loc_text" class="location_text">Layer</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link13A_s">
|
|
||||||
<div id="layer_s" class="location_text2">-</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link12_s">
|
|
||||||
<div id="loc_text" class="location_text">Type</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link13_s">
|
|
||||||
<div id="type_s" class="location_text2">-</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link14_s">
|
|
||||||
<div id="loc_text" class="location_text">Occupancy</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link15_s">
|
|
||||||
|
|
||||||
<div id="occupancy_s" class="location_text2">-</div>
|
|
||||||
|
|
||||||
</div
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td VALIGN=TOP>
|
|
||||||
<div id="cv_link16_s">
|
|
||||||
<div id="loc_text" class="location_text_tags2">Tags</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link17_s">
|
|
||||||
<div id="tags_s" class="location_text2">-</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,308 +0,0 @@
|
|||||||
|
|
||||||
<div id="IconMenuPanel">
|
|
||||||
<div id="rdialogx_d" class="float_dialog2_fixed">
|
|
||||||
<div id="icon_menu_panel" style="border:1" class="div_icon_menu_panel" >
|
|
||||||
|
|
||||||
<table id="savelinksHeaderTable" width="270" border="0" cellspacing="0" border-spacing="0" id="savelinks_table">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link2">
|
|
||||||
<div id="dummy_header" class="tagSaveLinkHeader" style="text-indent: 1em;">Location Setup</div>
|
|
||||||
<div style="float:right;margin-right:-34px;margin-top:-24px;" id="CloseObjectMenuX"></div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<table id="savelinksTable" width="270" border="0" cellspacing="0" border-spacing="0">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="dummy">
|
|
||||||
<canvas width="5" height="5"></canvas>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
xxxx
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="save_drawing">
|
|
||||||
<img id="save_drawing_image" class="icon_img" src="../app/images/tools/SaveChanges_240x22_Inactive.png" border="0">
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="dummy">
|
|
||||||
<canvas width="5" height="5"></canvas>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
</table>
|
|
||||||
|
|
||||||
|
|
||||||
<div id="link_tags_table">
|
|
||||||
|
|
||||||
<table id="savelinksTable_select" width="270" border="0" cellspacing="0" border-spacing="0" id="savelinks_table">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
____
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="unlink_location" class="select_link_text">Unlink Location</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="done_editing_location" class="select_link_text"></div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="edit_cancel_location" class="select_link_text">Edit Fields</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="dummy">
|
|
||||||
<canvas width="5" height="5"></canvas>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
<div id="location_text_dynamic">
|
|
||||||
|
|
||||||
<table id="locationTagsTable2" width="270" border="0" cellspacing="0" border-spacing="0">
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link10_id_datalayer_name">
|
|
||||||
<div id="loc_text" class="location_text">Connector</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link11" class="dropdown">
|
|
||||||
<span class="dropdown-toggle" role="button" data-toggle="dropdown" href="#" data-target="#" id="drop_link_spaces">None Selected<b class="caret"></b></span>
|
|
||||||
<ul id="spaces_drawing" class="dropdown-menu" role="menu" aria-labelledby="drop_link_spaces">
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div id="cv_link11_B2">
|
|
||||||
<input id="spaces_manual_tag" type="text" class="input_tags" value=""/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link11_B3">
|
|
||||||
<canvas width="10" height="10"></canvas>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link12A">
|
|
||||||
<div id="layer_text" class="location_text">Layer</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link13A">
|
|
||||||
<input id="layer_tag" type="text" class="input_tags" value=""/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link12">
|
|
||||||
<div id="loc_text" class="location_text">Type</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link13">
|
|
||||||
<input id="type_tag" type="text" class="input_tags" value=""/>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link14">
|
|
||||||
<div id="loc_text" class="location_text">Occupancy</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<input id="occupancy_tag" type="text" class="input_tags" value=""/>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td VALIGN=TOP>
|
|
||||||
<div id="loc_text" class="location_text_tags">Tags</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link16">
|
|
||||||
<textarea id="other_tags" class="styled_text_area"></textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="location_text_static">
|
|
||||||
|
|
||||||
<table id="locationTagsTable" width="270" border="0" cellspacing="0" border-spacing="0" >
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link10_s">
|
|
||||||
<div id="loc_text" class="location_text">Name</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link11_s" class="location_text">
|
|
||||||
<div id="location_s" class="location_text2">None Selected</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link12A_s">
|
|
||||||
<div id="loc_text" class="location_text">Layer</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link13A_s">
|
|
||||||
<div id="layer_s" class="location_text2">-</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link12_s">
|
|
||||||
<div id="loc_text" class="location_text">Type</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link13_s">
|
|
||||||
<div id="type_s" class="location_text2">-</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link14_s">
|
|
||||||
<div id="loc_text" class="location_text">Occupancy</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link15_s">
|
|
||||||
|
|
||||||
<div id="occupancy_s" class="location_text2">-</div>
|
|
||||||
|
|
||||||
</div
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
|
||||||
<td VALIGN=TOP>
|
|
||||||
<div id="cv_link16_s">
|
|
||||||
<div id="loc_text" class="location_text_tags2">Tags</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div class="whiteUnderbar">
|
|
||||||
_
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
<td>
|
|
||||||
<div id="cv_link17_s">
|
|
||||||
<div id="tags_s" class="location_text2">-</div>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
</table>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
120722
server/src/main/resources/static/drawio/js/app.min.js
vendored
120722
server/src/main/resources/static/drawio/js/app.min.js
vendored
File diff suppressed because one or more lines are too long
2
server/src/main/resources/static/js/jquery-3.7.1.min.js
vendored
Normal file
2
server/src/main/resources/static/js/jquery-3.7.1.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -23083,7 +23083,7 @@ initCom(PDFViewerApplication);
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
const HOSTED_VIEWER_ORIGINS = new Set(["null", "http://mozilla.github.io", "https://mozilla.github.io"]);
|
const HOSTED_VIEWER_ORIGINS = new Set(["null", "http://mozilla.github.io", "https://mozilla.github.io"]);
|
||||||
var validateFileURL = function (file) {
|
var validateFileURL = function (file) {
|
||||||
if (!file) {
|
if (!file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -23091,6 +23091,7 @@ initCom(PDFViewerApplication);
|
|||||||
if (HOSTED_VIEWER_ORIGINS.has(viewerOrigin)) {
|
if (HOSTED_VIEWER_ORIGINS.has(viewerOrigin)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/* 注释掉跨域检查
|
||||||
const fileOrigin = URL.parse(file, window.location)?.origin;
|
const fileOrigin = URL.parse(file, window.location)?.origin;
|
||||||
if (fileOrigin === viewerOrigin) {
|
if (fileOrigin === viewerOrigin) {
|
||||||
return;
|
return;
|
||||||
@@ -23100,7 +23101,8 @@ initCom(PDFViewerApplication);
|
|||||||
message: ex.message
|
message: ex.message
|
||||||
});
|
});
|
||||||
throw ex;
|
throw ex;
|
||||||
};
|
*/
|
||||||
|
};
|
||||||
var onFileInputChange = function (evt) {
|
var onFileInputChange = function (evt) {
|
||||||
if (this.pdfViewer?.isInPresentationMode) {
|
if (this.pdfViewer?.isInPresentationMode) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
|
|
||||||
<!-- modeler distro -->
|
<!-- modeler distro -->
|
||||||
<script src="bpmn/bpmn-modeler.development.js"></script>
|
<script src="bpmn/bpmn-modeler.development.js"></script>
|
||||||
<script src="js/jquery-3.6.1.min.js"></script>
|
<script src="js/jquery-3.7.1.min.js"></script>
|
||||||
|
|
||||||
<!-- app -->
|
<!-- app -->
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<link href="cadviewer/app/css/jquery-ui-1.13.2.min.css" media="screen" rel="stylesheet" type="text/css" />
|
<link href="cadviewer/app/css/jquery-ui-1.13.2.min.css" media="screen" rel="stylesheet" type="text/css" />
|
||||||
|
|
||||||
<!-- 核心脚本 - 最小化依赖 -->
|
<!-- 核心脚本 - 最小化依赖 -->
|
||||||
<script src="js/jquery-3.6.1.min.js" type="text/javascript"></script>
|
<script src="js/jquery-3.7.1.min.js" type="text/javascript"></script>
|
||||||
<script src="cadviewer/app/js/jquery-ui-1.13.2.min.js" type="text/javascript"></script>
|
<script src="cadviewer/app/js/jquery-ui-1.13.2.min.js" type="text/javascript"></script>
|
||||||
<script src="cadviewer/app/js/eve.js" type="text/javascript"></script>
|
<script src="cadviewer/app/js/eve.js" type="text/javascript"></script>
|
||||||
<script src="cadviewer/app/js/xml2json.min.js" type="text/javascript"></script>
|
<script src="cadviewer/app/js/xml2json.min.js" type="text/javascript"></script>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
||||||
<title>${file.name}代码预览</title>
|
<title>${file.name}代码预览</title>
|
||||||
<#include "*/commonHeader.ftl">
|
<#include "*/commonHeader.ftl">
|
||||||
<script src="js/jquery-3.6.1.min.js" type="text/javascript"></script>
|
<script src="js/jquery-3.7.1.min.js" type="text/javascript"></script>
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||||
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
||||||
<link rel="stylesheet" href="highlight/default.min.css">
|
<link rel="stylesheet" href="highlight/default.min.css">
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<title>${file.name}压缩包预览</title>
|
<title>${file.name}压缩包预览</title>
|
||||||
<script src="js/jquery-3.6.1.min.js"></script>
|
<script src="js/jquery-3.7.1.min.js"></script>
|
||||||
<#include "*/commonHeader.ftl">
|
<#include "*/commonHeader.ftl">
|
||||||
<script src="js/base64.min.js" type="text/javascript"></script>
|
<script src="js/base64.min.js" type="text/javascript"></script>
|
||||||
<link href="css/zTreeStyle.css" rel="stylesheet" type="text/css">
|
<link href="css/zTreeStyle.css" rel="stylesheet" type="text/css">
|
||||||
|
|||||||
@@ -1,43 +1,79 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
|
<html lang="zh">
|
||||||
<html lang="en">
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
||||||
<title>drawio文件预览</title>
|
<title>draw.io 文件预览</title>
|
||||||
<#include "*/commonHeader.ftl">
|
<#include "*/commonHeader.ftl">
|
||||||
<script src="js/base64.min.js" type="text/javascript"></script>
|
<script src="js/base64.min.js" type="text/javascript"></script>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
iframe {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<iframe src="" width="100%" frameborder="0"></iframe>
|
<iframe id="drawioFrame" title="draw.io 预览"></iframe>
|
||||||
|
|
||||||
<#if currentUrl?contains("http://") || currentUrl?contains("https://")>
|
<#if currentUrl?contains("http://") || currentUrl?contains("https://")>
|
||||||
<#assign finalUrl="${currentUrl}">
|
<#assign finalUrl = "${currentUrl}">
|
||||||
<#else>
|
<#else>
|
||||||
<#assign finalUrl="${baseUrl}${currentUrl}">
|
<#assign finalUrl = "${baseUrl}${currentUrl}">
|
||||||
</#if>
|
</#if>
|
||||||
<script>
|
|
||||||
var url = '${finalUrl}';
|
<script>
|
||||||
|
(function() {
|
||||||
|
// 获取最终文件地址
|
||||||
|
var fileUrl = '${finalUrl}';
|
||||||
var kkagent = '${kkagent}';
|
var kkagent = '${kkagent}';
|
||||||
var baseUrl = '${baseUrl}'.endsWith('/') ? '${baseUrl}' : '${baseUrl}' + '/';
|
var baseUrl = '${baseUrl}';
|
||||||
if (kkagent === 'true' || !url.startsWith(baseUrl)) {
|
if (!baseUrl.endsWith('/')) baseUrl += '/';
|
||||||
url = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(Base64.encode(url))+ "&key=${kkkey}";
|
|
||||||
}
|
// 跨域或代理处理
|
||||||
document.getElementsByTagName('iframe')[0].src = "${baseUrl}drawio/index.html?lightbox=1&gapi=0&db=0&od=0&tr=0&gh=0&gl=0&edit=_blank&lang=zh#U"+ encodeURIComponent(url)+"";
|
if (kkagent === 'true' || !fileUrl.startsWith(baseUrl)) {
|
||||||
document.getElementsByTagName('iframe')[0].height = document.documentElement.clientHeight - 10;
|
fileUrl = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(Base64.encode(fileUrl)) + "&key=${kkkey}";
|
||||||
/**
|
|
||||||
* 页面变化调整高度
|
|
||||||
*/
|
|
||||||
window.onresize = function () {
|
|
||||||
var fm = document.getElementsByTagName("iframe")[0];
|
|
||||||
fm.height = window.document.documentElement.clientHeight - 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var encodedUrl = encodeURIComponent(fileUrl);
|
||||||
|
var drawioBase = baseUrl + "drawio/index.html";
|
||||||
|
|
||||||
/*初始化水印*/
|
// 构建查询参数(保留原有所有参数,增加 file=)
|
||||||
window.onload = function () {
|
var params = new URLSearchParams({
|
||||||
initWaterMark();
|
lightbox: '1',
|
||||||
|
gapi: '0',
|
||||||
|
db: '0',
|
||||||
|
od: '0',
|
||||||
|
tr: '0',
|
||||||
|
gh: '0',
|
||||||
|
gl: '0',
|
||||||
|
edit: '_blank',
|
||||||
|
lang: 'zh',
|
||||||
|
file: fileUrl // 新增 ?file= 参数
|
||||||
|
});
|
||||||
|
|
||||||
|
// 最终 URL:查询参数 + 原有的 #Uhash
|
||||||
|
var iframeSrc = drawioBase + '?' + params.toString() + '#Uhttp://127.0.0.1/1.drawio';
|
||||||
|
|
||||||
|
var iframe = document.getElementById('drawioFrame');
|
||||||
|
iframe.src = iframeSrc;
|
||||||
|
iframe.height = document.documentElement.clientHeight - 10;
|
||||||
|
|
||||||
|
// 窗口大小变化时调整 iframe 高度
|
||||||
|
window.addEventListener('resize', function() {
|
||||||
|
iframe.height = document.documentElement.clientHeight - 10;
|
||||||
|
});
|
||||||
|
|
||||||
|
// 可选:初始化水印(假设 initWaterMark 已定义)
|
||||||
|
if (typeof initWaterMark === 'function') {
|
||||||
|
window.addEventListener('load', initWaterMark);
|
||||||
}
|
}
|
||||||
</script>
|
})();
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
@@ -1,44 +1,159 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="UTF-8">
|
||||||
<style type="text/css">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>暂不支持预览</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0 auto;
|
font-family: 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
|
||||||
width: 900px;
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
background-color: #CCB;
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.error-card {
|
||||||
width: 700px;
|
max-width: 600px;
|
||||||
height: 700px;
|
width: 100%;
|
||||||
margin: 0 auto;
|
background: #ffffff;
|
||||||
|
border-radius: 32px;
|
||||||
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px 32px 48px;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
.error-card:hover {
|
||||||
width: auto;
|
transform: translateY(-4px);
|
||||||
height: auto;
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
padding-bottom: 36px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
.icon-container {
|
||||||
display: block;
|
margin-bottom: 24px;
|
||||||
font-size: 20px;
|
}
|
||||||
color: blue;
|
|
||||||
|
.icon-container img {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1e293b;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.file-type-badge {
|
||||||
|
background: #f1f5f9;
|
||||||
|
color: #0f172a;
|
||||||
|
font-weight: 600;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 6px 16px;
|
||||||
|
border-radius: 40px;
|
||||||
|
font-size: 14px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reason-box {
|
||||||
|
background: #fef2f2;
|
||||||
|
border-left: 4px solid #dc2626;
|
||||||
|
padding: 16px 20px;
|
||||||
|
border-radius: 16px;
|
||||||
|
margin: 20px 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reason-label {
|
||||||
|
font-weight: 600;
|
||||||
|
color: #991b1b;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.reason-message {
|
||||||
|
color: #1e293b;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.5;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-link {
|
||||||
|
background: #f8fafc;
|
||||||
|
border-radius: 24px;
|
||||||
|
padding: 16px 20px;
|
||||||
|
margin-top: 28px;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-link p {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #334155;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-link a {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
background: #3b82f6;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 10px 24px;
|
||||||
|
border-radius: 40px;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-link a:hover {
|
||||||
|
background: #2563eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-note {
|
||||||
|
margin-top: 24px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #94a3b8;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="error-card">
|
||||||
<img src="images/sorry.jpg"/>
|
<div class="icon-container">
|
||||||
<span>
|
<!-- Base64 内嵌 SVG:文档 + 问号,表示不支持 -->
|
||||||
该(${fileType})文件,系统暂不支持在线预览,具体原因如下:
|
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2Y1OTAwYiIgd2lkdGg9IjEyMCIgaGVpZ2h0PSIxMjAiPgogIDxwYXRoIGQ9Ik0yMCA2aC04bC0yLTJINGMyLTEuMSAwLTEgMCAwdjE0YzAgMS4xLjkgMiAyIDJoMTZjMS4xIDAgMi0uOSAyLTJWN2MwLTEuMS0uOS0yLTItMnptLTIgMTJINlY4aDQuMjFsMiAySDE4djh6bS01LTRoLTR2LTJoNHYyem0wLTNoLTRWOWg0djJ6Ii8+Cjwvc3ZnPg==" alt="不支持预览">
|
||||||
<p style="color: red;">${msg}</p>
|
</div>
|
||||||
</span>
|
<h1>暂不支持在线预览</h1>
|
||||||
<p>有任何疑问,请加入kk开源社区知识星球咨询:<a href="https://t.zsxq.com/09ZHSXbsQ">https://t.zsxq.com/09ZHSXbsQ</a><br></p>
|
<div class="file-type-badge">
|
||||||
|
📄 文件类型:${fileType}
|
||||||
|
</div>
|
||||||
|
<div class="reason-box">
|
||||||
|
<div class="reason-label">
|
||||||
|
⚠️ 具体原因
|
||||||
|
</div>
|
||||||
|
<div class="reason-message">
|
||||||
|
${msg}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="community-link">
|
||||||
|
<p>有任何疑问,欢迎加入 kk 开源社区知识星球咨询</p>
|
||||||
|
<a href="https://t.zsxq.com/09ZHSXbsQ" target="_blank" rel="noopener noreferrer">
|
||||||
|
🔗 加入知识星球
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="footer-note">
|
||||||
|
系统暂不支持此格式在线查看,建议下载后使用本地软件打开
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
||||||
<title>JSON文件预览</title>
|
<title>JSON文件预览</title>
|
||||||
<#include "*/commonHeader.ftl">
|
<#include "*/commonHeader.ftl">
|
||||||
<script src="js/jquery-3.6.1.min.js" type="text/javascript"></script>
|
<script src="js/jquery-3.7.1.min.js" type="text/javascript"></script>
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||||
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
||||||
<script src="js/base64.min.js" type="text/javascript"></script>
|
<script src="js/base64.min.js" type="text/javascript"></script>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||||
<link rel="stylesheet" href="bootstrap-table/bootstrap-table.min.css"/>
|
<link rel="stylesheet" href="bootstrap-table/bootstrap-table.min.css"/>
|
||||||
<link rel="stylesheet" href="css/theme.css"/>
|
<link rel="stylesheet" href="css/theme.css"/>
|
||||||
<script type="text/javascript" src="js/jquery-3.6.1.min.js"></script>
|
<script type="text/javascript" src="js/jquery-3.7.1.min.js"></script>
|
||||||
<script type="text/javascript" src="js/jquery.form.min.js"></script>
|
<script type="text/javascript" src="js/jquery.form.min.js"></script>
|
||||||
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
||||||
<script type="text/javascript" src="bootstrap-table/bootstrap-table.min.js"></script>
|
<script type="text/javascript" src="bootstrap-table/bootstrap-table.min.js"></script>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||||
<link rel="stylesheet" href="css/theme.css"/>
|
<link rel="stylesheet" href="css/theme.css"/>
|
||||||
<script type="text/javascript" src="js/jquery-3.6.1.min.js"></script>
|
<script type="text/javascript" src="js/jquery-3.7.1.min.js"></script>
|
||||||
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||||
<link rel="stylesheet" href="css/theme.css"/>
|
<link rel="stylesheet" href="css/theme.css"/>
|
||||||
<script type="text/javascript" src="js/jquery-3.6.1.min.js"></script>
|
<script type="text/javascript" src="js/jquery-3.7.1.min.js"></script>
|
||||||
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||||
<link rel="stylesheet" href="css/theme.css"/>
|
<link rel="stylesheet" href="css/theme.css"/>
|
||||||
<script type="text/javascript" src="js/jquery-3.6.1.min.js"></script>
|
<script type="text/javascript" src="js/jquery-3.7.1.min.js"></script>
|
||||||
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
<script type="text/javascript" src="bootstrap/js/bootstrap.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
||||||
<title>${file.name}文本预览</title>
|
<title>${file.name}文本预览</title>
|
||||||
<#include "*/commonHeader.ftl">
|
<#include "*/commonHeader.ftl">
|
||||||
<script src="js/jquery-3.6.1.min.js" type="text/javascript"></script>
|
<script src="js/jquery-3.7.1.min.js" type="text/javascript"></script>
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||||
<link rel="stylesheet" href="css/index.css"/>
|
<link rel="stylesheet" href="css/index.css"/>
|
||||||
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<#setting classic_compatible=true>
|
<#setting classic_compatible=true>
|
||||||
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
<link rel="icon" href="./favicon.ico" type="image/x-icon">
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||||
<script src="js/jquery-3.6.1.min.js" type="text/javascript"></script>
|
<script src="js/jquery-3.7.1.min.js" type="text/javascript"></script>
|
||||||
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
||||||
<script src="js/bootbox.min.js" type="text/javascript"></script>
|
<script src="js/bootbox.min.js" type="text/javascript"></script>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -1,42 +1,131 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="UTF-8">
|
||||||
<style type="text/css">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>访问受限 - 未授信目录</title>
|
||||||
|
<style>
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0 auto;
|
font-family: 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
|
||||||
width: 900px;
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
background-color: #CCB;
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.error-card {
|
||||||
width: 700px;
|
max-width: 600px;
|
||||||
height: 700px;
|
width: 100%;
|
||||||
margin: 0 auto;
|
background: #ffffff;
|
||||||
|
border-radius: 32px;
|
||||||
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px 32px 48px;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
.error-card:hover {
|
||||||
width: auto;
|
transform: translateY(-4px);
|
||||||
height: auto;
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
padding-bottom: 36px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
.icon-container {
|
||||||
display: block;
|
margin-bottom: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon-container img {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1e293b;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-message {
|
||||||
|
background: #fef2f2;
|
||||||
|
border-left: 4px solid #dc2626;
|
||||||
|
padding: 20px;
|
||||||
|
border-radius: 16px;
|
||||||
|
margin: 24px 0;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1e293b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.warning-message::before {
|
||||||
|
content: "🚫 ";
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
color: blue;
|
}
|
||||||
|
|
||||||
|
.community-link {
|
||||||
|
background: #f8fafc;
|
||||||
|
border-radius: 24px;
|
||||||
|
padding: 16px 20px;
|
||||||
|
margin-top: 20px;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-link p {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #334155;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-link a {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
background: #3b82f6;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 10px 24px;
|
||||||
|
border-radius: 40px;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-link a:hover {
|
||||||
|
background: #2563eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-note {
|
||||||
|
margin-top: 28px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #94a3b8;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="error-card">
|
||||||
<img src="images/sorry.jpg" />
|
<div class="icon-container">
|
||||||
<p>
|
<!-- Base64 内嵌 SVG:文件夹加禁止符号 -->
|
||||||
预览源文件来自未授信的目录,请停止访问!<br>
|
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2RjMjYyNiIgd2lkdGg9IjEyMCIgaGVpZ2h0PSIxMjAiPgogIDxwYXRoIGQ9Ik0yMCA2aC04bC0yLTJINGMyLTEuMSAwLTEgMCAwdjE0YzAgMS4xLjkgMiAyIDJoMTZjMS4xIDAgMi0uOSAyLTJWN2MwLTEuMS0uOS0yLTItMnptLTUgN2gtNHYtMmg0djJ6bTAtM2gtNFY4aDR2MnoiLz4KICA8Y2lyY2xlIGN4PSIxMiIgY3k9IjE2IiByPSI0IiBmaWxsPSIjZmZmIiBzdHJva2U9IiNkYzI2MjYiIHN0cm9rZS13aWR0aD0iMS41Ii8+CiAgPHBhdGggZD0iTTE2IDhsMi0yIDIgMi0yIDJ6IiBmaWxsPSIjZmZmIi8+Cjwvc3ZnPg==" alt="目录未授信">
|
||||||
有任何疑问,请加入kk开源社区知识星球咨询:<a href="https://t.zsxq.com/09ZHSXbsQ">https://t.zsxq.com/09ZHSXbsQ</a><br>
|
</div>
|
||||||
</p>
|
<h1>访问被拒绝</h1>
|
||||||
|
<div class="warning-message">
|
||||||
|
预览源文件来自未授信的目录,请停止访问!
|
||||||
|
</div>
|
||||||
|
<div class="community-link">
|
||||||
|
<p>有任何疑问,欢迎加入 kk 开源社区知识星球咨询</p>
|
||||||
|
<a href="https://t.zsxq.com/09ZHSXbsQ" target="_blank" rel="noopener noreferrer">
|
||||||
|
🔗 加入知识星球
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="footer-note">
|
||||||
|
如果您确信该目录安全,请联系管理员将其添加到信任目录列表中
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,42 +1,148 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>访问受限 - 不受信任的站点</title>
|
||||||
<style type="text/css">
|
<style type="text/css">
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0 auto;
|
font-family: 'Segoe UI', Roboto, 'Helvetica Neue', sans-serif;
|
||||||
width: 900px;
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||||||
background-color: #CCB;
|
min-height: 100vh;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.error-card {
|
||||||
width: 700px;
|
max-width: 600px;
|
||||||
height: 700px;
|
width: 100%;
|
||||||
margin: 0 auto;
|
background: #ffffff;
|
||||||
|
border-radius: 32px;
|
||||||
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px 32px 48px;
|
||||||
|
transition: transform 0.2s ease;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
.error-card:hover {
|
||||||
width: auto;
|
transform: translateY(-4px);
|
||||||
height: auto;
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
padding-bottom: 36px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
.icon-container {
|
||||||
display: block;
|
margin-bottom: 24px;
|
||||||
font-size: 20px;
|
}
|
||||||
color: blue;
|
|
||||||
|
.icon-container img {
|
||||||
|
width: 120px;
|
||||||
|
height: 120px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-size: 28px;
|
||||||
|
font-weight: 700;
|
||||||
|
color: #1e293b;
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.host-warning {
|
||||||
|
background: #fef2f2;
|
||||||
|
border-left: 4px solid #dc2626;
|
||||||
|
padding: 14px 20px;
|
||||||
|
border-radius: 16px;
|
||||||
|
margin: 24px 0;
|
||||||
|
font-size: 18px;
|
||||||
|
font-weight: 500;
|
||||||
|
color: #1e293b;
|
||||||
|
}
|
||||||
|
|
||||||
|
.host-warning span {
|
||||||
|
color: #dc2626;
|
||||||
|
font-weight: 700;
|
||||||
|
background: #fff0f0;
|
||||||
|
padding: 4px 12px;
|
||||||
|
border-radius: 40px;
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 4px;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message {
|
||||||
|
color: #475569;
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 1.5;
|
||||||
|
margin-bottom: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-link {
|
||||||
|
background: #f8fafc;
|
||||||
|
border-radius: 24px;
|
||||||
|
padding: 16px 20px;
|
||||||
|
margin-top: 8px;
|
||||||
|
border: 1px solid #e2e8f0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-link p {
|
||||||
|
font-size: 15px;
|
||||||
|
color: #334155;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-link a {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
background: #3b82f6;
|
||||||
|
color: white;
|
||||||
|
text-decoration: none;
|
||||||
|
padding: 10px 24px;
|
||||||
|
border-radius: 40px;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: background 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.community-link a:hover {
|
||||||
|
background: #2563eb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer-note {
|
||||||
|
margin-top: 28px;
|
||||||
|
font-size: 13px;
|
||||||
|
color: #94a3b8;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="error-card">
|
||||||
<img src="images/sorry.jpg" />
|
<div class="icon-container">
|
||||||
<p>
|
<!-- Base64 内嵌 SVG:安全盾牌 + 感叹号,风格简洁现代 -->
|
||||||
预览源文件来自不受信任的站点:<span style="color: red; display: inline;">${current_host}</span> 请联系管理员!<br>
|
<img src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0iI2RjMjYyNiIgd2lkdGg9IjEyMCIgaGVpZ2h0PSIxMjAiPgogIDxwYXRoIGQ9Ik0xMiAyTDMgN3Y3YzAgNC41MSAzLjgyIDguNDUgOSAxMC4yNSA1LjE4LTEuOCA5LTUuNzQgOS0xMC4yNVY3bC05LTV6bS0yIDEzaC00di0yaDR2MnptMC0zaC00VjloNHYzek0xNiAxM2gtNHYtMmg0djJ6bTAtM2gtNFY4aDR2MnoiLz4KPC9zdmc+" alt="安全警告">
|
||||||
有任何疑问,请加入kk开源社区知识星球咨询:<a href="https://t.zsxq.com/09ZHSXbsQ">https://t.zsxq.com/09ZHSXbsQ</a><br>
|
</div>
|
||||||
</p>
|
<h1>访问被拒绝</h1>
|
||||||
|
<div class="host-warning">
|
||||||
|
⚠️ 预览源文件来自不受信任的站点:<span>${current_host}</span>
|
||||||
|
</div>
|
||||||
|
<div class="message">
|
||||||
|
该站点不在系统信任列表中,为了您的数据安全,已阻止本次访问。<br>
|
||||||
|
</div>
|
||||||
|
<div class="community-link">
|
||||||
|
<p>有任何疑问,欢迎加入 kk 开源社区知识星球咨询</p>
|
||||||
|
<a href="https://t.zsxq.com/09ZHSXbsQ" target="_blank" rel="noopener noreferrer">
|
||||||
|
🔗 加入知识星球
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
<div class="footer-note">
|
||||||
|
如有误判,请联系系统管理员更新信任主机配置
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -4,50 +4,178 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
||||||
<title>${file.name}OFD预览</title>
|
<title>${file.name} OFD预览</title>
|
||||||
<#include "*/commonHeader.ftl">
|
<#include "*/commonHeader.ftl">
|
||||||
<script src="js/base64.min.js" type="text/javascript"></script>
|
<script src="js/base64.min.js" type="text/javascript"></script>
|
||||||
|
|
||||||
|
<!-- OFD 阅读器所需样式和脚本(相对路径,请确保文件存在) -->
|
||||||
|
<link rel="stylesheet" href="ofd/css/element-ui.css">
|
||||||
|
<link rel="stylesheet" href="ofd/css/cnofd.css">
|
||||||
|
<script src="ofd/js/jquery-3.6.0.min.js"></script>
|
||||||
|
<script src="ofd/js/jszip-utils-0.1.0.min.js"></script>
|
||||||
|
<script src="ofd/js/Typr.js"></script>
|
||||||
|
<script src="ofd/js/Typr.U.js"></script>
|
||||||
|
<script src="ofd/js/openjpeg.js"></script>
|
||||||
|
<script src="ofd/js/cnofd.umd.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
|
||||||
<#if currentUrl?contains("http://") || currentUrl?contains("https://")>
|
<#if currentUrl?contains("http://") || currentUrl?contains("https://")>
|
||||||
<#assign finalUrl="${currentUrl}">
|
<#assign finalUrl="${currentUrl}">
|
||||||
<#else>
|
<#else>
|
||||||
<#assign finalUrl="${baseUrl}${currentUrl}">
|
<#assign finalUrl="${baseUrl}${currentUrl}">
|
||||||
</#if>
|
</#if>
|
||||||
<iframe src="" width="100%" frameborder="0"></iframe>
|
<body>
|
||||||
</body>
|
<!-- OFD 阅读器 DOM 结构(直接嵌入,不再使用 iframe) -->
|
||||||
<script type="text/javascript">
|
<noscript>
|
||||||
var url = '${finalUrl}';
|
<strong>很抱歉,因为没有启用JavaScript,cnofd.js无法正常工作。请启用它以继续。</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app">
|
||||||
|
<section class="el-container is-vertical" style="width: 100vw; height: 100vh;">
|
||||||
|
<header class="el-header"
|
||||||
|
style="height: 32px; background: rgb(71, 71, 71); display: flex; border: 0px solid rgb(232, 232, 232); align-items: center;">
|
||||||
|
<div id="openFile" title="打开" class="btn-icon">
|
||||||
|
<svg viewbox="64 64 896 896" focusable="false" width="1em" height="1em" fill="currentColor"
|
||||||
|
aria-hidden="true">
|
||||||
|
<path
|
||||||
|
d="M928 444H820V330.4c0-17.7-14.3-32-32-32H473L355.7 186.2a8.15 8.15 0 0 0-5.5-2.2H96c-17.7 0-32 14.3-32 32v592c0 17.7 14.3 32 32 32h698c13 0 24.8-7.9 29.7-20l134-332c1.5-3.8 2.3-7.9 2.3-12 0-17.7-14.3-32-32-32zM136 256h188.5l119.6 114.4H748V444H238c-13 0-24.8 7.9-29.7 20L136 643.2V256zm635.3 512H159l103.3-256h612.4L771.3 768z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
<input id="file" type="file" accept=".ofd" class="hidden" />
|
||||||
|
</div>
|
||||||
|
<div style="background: rgb(71, 71, 71); display: flex; align-items: center;">
|
||||||
|
<div id="separator1" class="horizontalToolbarSeparator"></div>
|
||||||
|
<div id="zoomIn" title="放大" class="btn-icon">
|
||||||
|
<svg viewbox="64 64 896 896" focusable="false" width="1em" height="1em" fill="currentColor"
|
||||||
|
aria-hidden="true">
|
||||||
|
<path
|
||||||
|
d="M637 443H519V309c0-4.4-3.6-8-8-8h-60c-4.4 0-8 3.6-8 8v134H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h118v134c0 4.4 3.6 8 8 8h60c4.4 0 8-3.6 8-8V519h118c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8zm284 424L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11zM696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div id="zoomSelect" class="select-icon" title="缩放比例">
|
||||||
|
<select id="zoomValue">
|
||||||
|
<option value="width">适合页宽</option>
|
||||||
|
<option value="4.0">400%</option>
|
||||||
|
<option value="3.0">300%</option>
|
||||||
|
<option value="2.0">200%</option>
|
||||||
|
<option value="1.5">150%</option>
|
||||||
|
<option value="1.2">120%</option>
|
||||||
|
<option value="1.1">110%</option>
|
||||||
|
<option value="1.0" selected="selected">100%</option>
|
||||||
|
<option value="0.9">90%</option>
|
||||||
|
<option value="0.8">80%</option>
|
||||||
|
<option value="0.6">60%</option>
|
||||||
|
<option value="0.5">50%</option>
|
||||||
|
<option value="0.25">25%</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div id="zoomOut" title="缩小" class="btn-icon">
|
||||||
|
<svg viewbox="64 64 896 896" focusable="false" width="1em" height="1em" fill="currentColor"
|
||||||
|
aria-hidden="true">
|
||||||
|
<path
|
||||||
|
d="M637 443H325c-4.4 0-8 3.6-8 8v60c0 4.4 3.6 8 8 8h312c4.4 0 8-3.6 8-8v-60c0-4.4-3.6-8-8-8zm284 424L775 721c122.1-148.9 113.6-369.5-26-509-148-148.1-388.4-148.1-537 0-148.1 148.6-148.1 389 0 537 139.5 139.6 360.1 148.1 509 26l146 146c3.2 2.8 8.3 2.8 11 0l43-43c2.8-2.7 2.8-7.8 0-11zM696 696c-118.8 118.7-311.2 118.7-430 0-118.7-118.8-118.7-311.2 0-430 118.8-118.7 311.2-118.7 430 0 118.7 118.8 118.7 311.2 0 430z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div id="firstPage" title="首页" class="btn-icon">
|
||||||
|
<svg viewbox="64 64 896 896" focusable="false" width="1em" height="1em" fill="currentColor"
|
||||||
|
aria-hidden="true">
|
||||||
|
<path
|
||||||
|
d="M347.6 528.95l383.2 301.02c14.25 11.2 35.2 1.1 35.2-16.95V210.97c0-18.05-20.95-28.14-35.2-16.94L347.6 495.05a21.53 21.53 0 0 0 0 33.9M330 864h-64a8 8 0 0 1-8-8V168a8 8 0 0 1 8-8h64a8 8 0 0 1 8 8v688a8 8 0 0 1-8 8">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div id="prePage" title="上一页" class="btn-icon">
|
||||||
|
<svg viewbox="64 64 896 896" focusable="false" width="1em" height="1em" fill="currentColor"
|
||||||
|
aria-hidden="true">
|
||||||
|
<path
|
||||||
|
d="M689 165.1L308.2 493.5c-10.9 9.4-10.9 27.5 0 37L689 858.9c14.2 12.2 35 1.2 35-18.5V183.6c0-19.7-20.8-30.7-35-18.5z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div id="pageInfo" class="btn-icon">1/0</div>
|
||||||
|
<div id="nextPage" title="下一页" class="btn-icon">
|
||||||
|
<svg viewbox="64 64 896 896" focusable="false" width="1em" height="1em" fill="currentColor"
|
||||||
|
aria-hidden="true">
|
||||||
|
<path
|
||||||
|
d="M715.8 493.5L335 165.1c-14.2-12.2-35-1.2-35 18.5v656.8c0 19.7 20.8 30.7 35 18.5l380.8-328.4c10.9-9.4 10.9-27.6 0-37z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div id="lastPage" title="尾页" class="btn-icon">
|
||||||
|
<svg viewbox="64 64 896 896" focusable="false" width="1em" height="1em" fill="currentColor"
|
||||||
|
aria-hidden="true">
|
||||||
|
<path
|
||||||
|
d="M676.4 528.95L293.2 829.97c-14.25 11.2-35.2 1.1-35.2-16.95V210.97c0-18.05 20.95-28.14 35.2-16.94l383.2 301.02a21.53 21.53 0 0 1 0 33.9M694 864h64a8 8 0 0 0 8-8V168a8 8 0 0 0-8-8h-64a8 8 0 0 0-8 8v688a8 8 0 0 0 8 8">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
<div id="separator2" class="horizontalToolbarSeparator"></div>
|
||||||
|
<div id="print" title="打印" class="btn-icon">
|
||||||
|
<svg viewbox="64 64 896 896" focusable="false" data-icon="printer" width="1em" height="1em"
|
||||||
|
fill="currentColor" aria-hidden="true">
|
||||||
|
<path
|
||||||
|
d="M820 436h-40c-4.4 0-8 3.6-8 8v40c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-40c0-4.4-3.6-8-8-8zm32-104H732V120c0-4.4-3.6-8-8-8H300c-4.4 0-8 3.6-8 8v212H172c-44.2 0-80 35.8-80 80v328c0 17.7 14.3 32 32 32h168v132c0 4.4 3.6 8 8 8h424c4.4 0 8-3.6 8-8V772h168c17.7 0 32-14.3 32-32V412c0-44.2-35.8-80-80-80zM360 180h304v152H360V180zm304 664H360V568h304v276zm200-140H732V500H292v204H160V412c0-6.6 5.4-12 12-12h680c6.6 0 12 5.4 12 12v292z">
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main class="el-main" id="main" style="height: auto; background: rgb(242, 242, 242); padding: 0px;">
|
||||||
|
<div id="leftMenu" class="left-section"></div>
|
||||||
|
<div id="content" class="main-section"></div>
|
||||||
|
<div id="loading"
|
||||||
|
style="position:absolute; z-index:999; display:none; top:50%; left:50%; transform:translate(-50%,-50%);">
|
||||||
|
<img src="ofd/img/loading.gif" alt="" />
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
</section>
|
||||||
|
</div>
|
||||||
|
<!-- cnofd 视图脚本(必须放在 DOM 之后) -->
|
||||||
|
<script src="ofd/js/cnofd-view.js"></script>
|
||||||
|
<script type="text/javascript">
|
||||||
|
// ========== 整合后端变量,直接指定 OFD 文件地址 ==========
|
||||||
|
// 后端传入的原始 URL(可能未经过代理)
|
||||||
|
var rawUrl = '${finalUrl}';
|
||||||
var kkagent = '${kkagent}';
|
var kkagent = '${kkagent}';
|
||||||
var baseUrl = '${baseUrl}'.endsWith('/') ? '${baseUrl}' : '${baseUrl}' + '/';
|
var baseUrl = '${baseUrl}'.endsWith('/') ? '${baseUrl}' : '${baseUrl}' + '/';
|
||||||
|
var pageNum = '${page}'; // 可选,用于跳转到指定页
|
||||||
|
|
||||||
if (kkagent === 'true' || !url.startsWith(baseUrl)) {
|
// 根据代理标志计算最终的文件地址(与原 iframe 逻辑完全一致)
|
||||||
|
var finalOfdUrl = rawUrl;
|
||||||
|
if (kkagent === 'true' || !finalOfdUrl.startsWith(baseUrl)) {
|
||||||
url = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(Base64.encode(url))+ "&key=${kkkey}";
|
url = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(Base64.encode(url))+ "&key=${kkkey}";
|
||||||
}
|
}
|
||||||
if(IsPhone()){
|
console.log("Hello, world!");
|
||||||
document.getElementsByTagName('iframe')[0].src = "${baseUrl}ofd/index.html?file=" + encodeURIComponent(url)+"&scale=width"+"&page=${page}";
|
console.log(finalOfdUrl);
|
||||||
}else{
|
|
||||||
document.getElementsByTagName('iframe')[0].src = "${baseUrl}ofd/index.html?file="+ encodeURIComponent(url)+"&page=${page}";
|
|
||||||
}
|
|
||||||
document.getElementsByTagName('iframe')[0].height = document.documentElement.clientHeight - 10;
|
|
||||||
/**
|
|
||||||
* 页面变化调整高度
|
|
||||||
*/
|
|
||||||
window.onresize = function () {
|
|
||||||
var fm = document.getElementsByTagName("iframe")[0];
|
|
||||||
fm.height = window.document.documentElement.clientHeight - 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
function IsPhone() {
|
// 页面加载完成后自动加载 OFD 文件
|
||||||
var info = navigator.userAgent;
|
$(document).ready(function() {
|
||||||
//通过正则表达式的test方法判断是否包含“Mobile”字符串
|
// 延迟确保 cnofd 库完全初始化
|
||||||
var isPhone = /mobile/i.test(info);
|
setTimeout(function() {
|
||||||
//如果包含“Mobile”(是手机设备)则返回true
|
if (typeof loadOfdFile === 'function') {
|
||||||
return isPhone;
|
loadOfdFile(finalOfdUrl);
|
||||||
|
// 如果传入了页码参数,加载后跳转到指定页
|
||||||
|
if (pageNum && !isNaN(pageNum) && pageNum > 1) {
|
||||||
|
setTimeout(function() {
|
||||||
|
// 等待渲染完成后再跳页
|
||||||
|
if (typeof kkPage === 'function') {
|
||||||
|
kkPage(); // 此函数需要提前定义,或使用类似逻辑
|
||||||
|
} else {
|
||||||
|
console.warn('未找到 kkPage 函数,无法跳转到指定页');
|
||||||
}
|
}
|
||||||
/*初始化水印*/
|
}, 1000);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error("cnofd 库未加载完成,请检查路径:ofd/js/cnofd-view.js");
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
});
|
||||||
|
// 保留水印初始化(原模板中的逻辑)
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
|
if (typeof initWaterMark === 'function') {
|
||||||
initWaterMark();
|
initWaterMark();
|
||||||
}
|
}
|
||||||
</script>
|
};
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -7,45 +7,175 @@
|
|||||||
<title>${file.name}3D预览</title>
|
<title>${file.name}3D预览</title>
|
||||||
<script src="js/base64.min.js" type="text/javascript"></script>
|
<script src="js/base64.min.js" type="text/javascript"></script>
|
||||||
<#include "*/commonHeader.ftl">
|
<#include "*/commonHeader.ftl">
|
||||||
|
<!-- 引入 jQuery 和 3D Viewer 核心样式/脚本 -->
|
||||||
|
<script src="js/jquery-3.7.1.min.js"></script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/website/build/website_dev/o3dv.website.min.css">
|
||||||
|
<script type="text/javascript" src="/website/build/website_dev/o3dv.website.min.js"></script>
|
||||||
|
<style>
|
||||||
|
/* 提示样式 */
|
||||||
|
.toast {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 20px;
|
||||||
|
background: #323232;
|
||||||
|
color: #fff;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 20px;
|
||||||
|
font-size: 12px;
|
||||||
|
z-index: 10001;
|
||||||
|
font-family: monospace;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<#if currentUrl?contains("http://") || currentUrl?contains("https://") || currentUrl?contains("file://")>
|
<#-- 根据变量计算最终模型 URL(与原有逻辑保持一致) -->
|
||||||
|
<#if currentUrl?contains("http://") || currentUrl?contains("https://") || currentUrl?contains("file://")>
|
||||||
<#assign finalUrl="${currentUrl}">
|
<#assign finalUrl="${currentUrl}">
|
||||||
<#elseif currentUrl?contains("ftp://") >
|
<#elseif currentUrl?contains("ftp://") >
|
||||||
<#assign finalUrl="${currentUrl}">
|
<#assign finalUrl="${currentUrl}">
|
||||||
<#else>
|
<#else>
|
||||||
<#assign finalUrl="${baseUrl}${currentUrl}">
|
<#assign finalUrl="${baseUrl}${currentUrl}">
|
||||||
</#if>
|
</#if>
|
||||||
<body>
|
|
||||||
<iframe src="" width="100%" frameborder="0"></iframe>
|
|
||||||
</body>
|
|
||||||
<script type="text/javascript">
|
|
||||||
var url = '${finalUrl}';
|
|
||||||
var kkagent = '${kkagent}';
|
|
||||||
var baseUrl = '${baseUrl}'.endsWith('/') ? '${baseUrl}' : '${baseUrl}' + '/';
|
|
||||||
if (kkagent === 'true' || !url.startsWith(baseUrl)) {
|
|
||||||
url = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(Base64.encode(url))+ "&key=${kkkey}";
|
|
||||||
document.getElementsByTagName('iframe')[0].src = "${baseUrl}website/index.html#model="+ url + "&fullfilename=/${file.name}";
|
|
||||||
}else{
|
|
||||||
document.getElementsByTagName('iframe')[0].src = "${baseUrl}website/index.html#model="+ url;
|
|
||||||
}
|
|
||||||
|
|
||||||
document.getElementsByTagName('iframe')[0].height = document.documentElement.clientHeight - 10;
|
<body>
|
||||||
/**
|
<!-- 3D Viewer 的 DOM 结构(从原示例中精简,保留核心容器) -->
|
||||||
* 页面变化调整高度
|
<input type="file" id="open_file" style="display:none;" multiple>
|
||||||
*/
|
<div class="header" id="header">
|
||||||
window.onresize = function () {
|
<div class="title">
|
||||||
var fm = document.getElementsByTagName("iframe")[0];
|
<div class="title_left"></div>
|
||||||
fm.height = window.document.documentElement.clientHeight - 10;
|
<div class="title_right" id="header_buttons"></div>
|
||||||
}
|
<div class="main_file_name only_full_width" id="main_file_name"></div>
|
||||||
</script>
|
</div>
|
||||||
|
<div class="toolbar" id="toolbar"></div>
|
||||||
|
</div>
|
||||||
|
<div class="main" id="main">
|
||||||
|
<div class="main_left_container only_full_width" id="main_left_container">
|
||||||
|
<div class="main_navigator ov_panel_set_container" id="main_navigator"></div>
|
||||||
|
<div class="main_splitter" id="main_navigator_splitter"></div>
|
||||||
|
</div>
|
||||||
|
<div class="main_viewer" id="main_viewer"></div>
|
||||||
|
<div class="main_right_container only_full_width" id="main_right_container">
|
||||||
|
<div class="main_splitter" id="main_sidebar_splitter"></div>
|
||||||
|
<div class="main_sidebar ov_panel_set_right_container" id="main_sidebar"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="intro ov_thin_scrollbar" id="intro">
|
||||||
|
<div class="intro_content" id="intro_content">
|
||||||
|
<div class="intro_formats">
|
||||||
|
<div class="intro_formats_title" id="intro_formats_title"></div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
/*初始化水印*/
|
// 保留原有事件处理
|
||||||
if (!!window.ActiveXObject || "ActiveXObject" in window)
|
OV.SetWebsiteEventHandler((eventName, eventLabel, eventParams) => {
|
||||||
{
|
console.log({ eventName, eventLabel, eventParams });
|
||||||
}else{
|
});
|
||||||
|
|
||||||
|
// 自定义加载逻辑(使用 fetch + Blob + ImportFiles)
|
||||||
|
(function($) {
|
||||||
|
// 从后端变量获取模型最终地址
|
||||||
|
const MODEL_URL = '${finalUrl}';
|
||||||
|
const kkagent = '${kkagent}';
|
||||||
|
const baseUrl = '${baseUrl}'.endsWith('/') ? '${baseUrl}' : '${baseUrl}' + '/';
|
||||||
|
if (kkagent === 'true' || !MODEL_URL.startsWith(baseUrl)) {
|
||||||
|
MODEL_URL = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(Base64.encode(MODEL_URL))+ "&key=${kkkey}";
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMessage(msg, isError = false) {
|
||||||
|
let toast = $('<div class="toast">' + msg + '</div>');
|
||||||
|
if (isError) toast.css('background', '#d32f2f');
|
||||||
|
$('body').append(toast);
|
||||||
|
setTimeout(() => toast.fadeOut(300, () => toast.remove()), 3000);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadModelFromUrl(modelUrl) {
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(modelUrl, { mode: 'cors', credentials: 'same-origin' });
|
||||||
|
if (!response.ok) throw new Error(`HTTP ${response.status}`);
|
||||||
|
const blob = await response.blob();
|
||||||
|
const fileName = modelUrl.split('/').pop() || 'model.bin';
|
||||||
|
const file = new File([blob], fileName, { type: blob.type || 'application/octet-stream' });
|
||||||
|
|
||||||
|
const dataTransfer = new DataTransfer();
|
||||||
|
dataTransfer.items.add(file);
|
||||||
|
const fileList = dataTransfer.files;
|
||||||
|
|
||||||
|
let imported = false;
|
||||||
|
if (OV.Website && typeof OV.Website.ImportFiles === 'function') {
|
||||||
|
OV.Website.ImportFiles(fileList);
|
||||||
|
imported = true;
|
||||||
|
} else if (OV.Website && typeof OV.Website.LoadFiles === 'function') {
|
||||||
|
OV.Website.LoadFiles(fileList);
|
||||||
|
imported = true;
|
||||||
|
} else {
|
||||||
|
let viewer = null;
|
||||||
|
if (OV.ViewerManager && typeof OV.ViewerManager.getViewer === 'function') {
|
||||||
|
viewer = OV.ViewerManager.getViewer();
|
||||||
|
} else {
|
||||||
|
const viewerElem = document.getElementById('main_viewer');
|
||||||
|
if (viewerElem && viewerElem.__viewer) viewer = viewerElem.__viewer;
|
||||||
|
}
|
||||||
|
if (viewer && typeof viewer.ImportFiles === 'function') {
|
||||||
|
viewer.ImportFiles(fileList);
|
||||||
|
imported = true;
|
||||||
|
} else if (viewer && typeof viewer.LoadFiles === 'function') {
|
||||||
|
viewer.LoadFiles(fileList);
|
||||||
|
imported = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!imported) {
|
||||||
|
const fileInput = document.getElementById('open_file');
|
||||||
|
if (fileInput) {
|
||||||
|
const dt = new DataTransfer();
|
||||||
|
dt.items.add(file);
|
||||||
|
fileInput.files = dt.files;
|
||||||
|
fileInput.dispatchEvent(new Event('change', { bubbles: true }));
|
||||||
|
imported = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imported) {
|
||||||
|
showMessage(`✅ 已加载: ${fileName}`);
|
||||||
|
} else {
|
||||||
|
throw new Error('无法将文件传递给查看器');
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
showMessage(`❌ 加载失败: ${err.message}`, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$(window).on('load', function() {
|
||||||
|
// 等待查看器核心初始化完成后再加载模型
|
||||||
|
setTimeout(() => {
|
||||||
|
console.log('[自动加载] 固定模型:', MODEL_URL);
|
||||||
|
if (MODEL_URL && MODEL_URL !== '') {
|
||||||
|
loadModelFromUrl(MODEL_URL);
|
||||||
|
} else {
|
||||||
|
showMessage('❌ 模型地址为空', true);
|
||||||
|
}
|
||||||
|
}, 600);
|
||||||
|
});
|
||||||
|
})(jQuery);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
// 启动 3D Viewer(注意:必须在 DOM 加载后执行,但脚本位置已在 body 底部)
|
||||||
|
OV.StartWebsite();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
/* 初始化水印(保留原逻辑) */
|
||||||
|
if (!!window.ActiveXObject || "ActiveXObject" in window) {
|
||||||
|
// IE 不支持水印
|
||||||
|
} else {
|
||||||
initWaterMark();
|
initWaterMark();
|
||||||
}
|
}
|
||||||
</script>
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,55 +1,92 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="zh-CN">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8"/>
|
<meta charset="utf-8"/>
|
||||||
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
||||||
<title>PDF预览</title>
|
<title>PDF预览</title>
|
||||||
<#include "*/commonHeader.ftl">
|
<#include "*/commonHeader.ftl">
|
||||||
<script src="js/base64.min.js" type="text/javascript"></script>
|
<script src="js/base64.min.js" type="text/javascript"></script>
|
||||||
|
<style>
|
||||||
|
/* 简单全屏布局,无滚动条 */
|
||||||
|
html, body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
iframe {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: none;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.img-preview {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 20px;
|
||||||
|
right: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
z-index: 999;
|
||||||
|
width: 48px;
|
||||||
|
height: 48px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
|
||||||
<#if pdfUrl?contains("http://") || pdfUrl?contains("https://")>
|
<#if pdfUrl?contains("http://") || pdfUrl?contains("https://")>
|
||||||
<#assign finalUrl="${pdfUrl}">
|
<#assign finalUrl="${pdfUrl}">
|
||||||
<#else>
|
<#else>
|
||||||
<#assign finalUrl="${baseUrl}${pdfUrl}">
|
<#assign finalUrl="${baseUrl}${pdfUrl}">
|
||||||
</#if>
|
</#if>
|
||||||
<iframe src="" width="100%" frameborder="0"></iframe>
|
|
||||||
|
<iframe id="pdfFrame" src="about:blank"></iframe>
|
||||||
|
|
||||||
<#if "false" == switchDisabled>
|
<#if "false" == switchDisabled>
|
||||||
<img src="images/jpg.svg" width="48" height="48" style="position: fixed; cursor: pointer; top: 40%; right: 48px; z-index: 999;" alt="使用图片预览" title="使用图片预览" onclick="goForImage()"/>
|
<img class="img-preview" src="images/jpg.svg" alt="使用图片预览" title="使用图片预览" onclick="goForImage()"/>
|
||||||
</#if>
|
</#if>
|
||||||
</body>
|
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
// 计算最终 PDF 地址(支持代理)
|
||||||
var url = '${finalUrl}';
|
var url = '${finalUrl}';
|
||||||
var kkagent = '${kkagent}';
|
var kkagent = '${kkagent}';
|
||||||
var baseUrl = '${baseUrl}'.endsWith('/') ? '${baseUrl}' : '${baseUrl}' + '/';
|
var baseUrl = '${baseUrl}'.endsWith('/') ? '${baseUrl}' : '${baseUrl}' + '/';
|
||||||
if (kkagent === 'true' || !url.startsWith(baseUrl)) {
|
if (kkagent === 'true' || !url.startsWith(baseUrl)) {
|
||||||
url = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(Base64.encode(url))+ "&key=${kkkey}";
|
url = baseUrl + 'getCorsFile?urlPath=' + encodeURIComponent(Base64.encode(url)) + "&key=${kkkey}";
|
||||||
}
|
|
||||||
document.getElementsByTagName('iframe')[0].src = "${baseUrl}pdfjs/web/viewer.html?file=" + encodeURIComponent(url) + "&disablepresentationmode=${pdfPresentationModeDisable}&disableopenfile=${pdfOpenFileDisable}&disableprint=${pdfPrintDisable}&disabledownload=${pdfDownloadDisable}&disablebookmark=${pdfBookmarkDisable}&disableediting=${pdfDisableEditing}";
|
|
||||||
document.getElementsByTagName('iframe')[0].height = document.documentElement.clientHeight - 10;
|
|
||||||
/**
|
|
||||||
* 页面变化调整高度
|
|
||||||
*/
|
|
||||||
window.onresize = function () {
|
|
||||||
var fm = document.getElementsByTagName("iframe")[0];
|
|
||||||
fm.height = window.document.documentElement.clientHeight - 10;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 构建 viewer 地址,传递所有参数
|
||||||
|
var viewerUrl = baseUrl + "pdfjs/web/viewer.html?file=" + encodeURIComponent(url);
|
||||||
|
viewerUrl += "&disablepresentationmode=${pdfPresentationModeDisable}";
|
||||||
|
viewerUrl += "&disableopenfile=${pdfOpenFileDisable}";
|
||||||
|
viewerUrl += "&disableprint=${pdfPrintDisable}";
|
||||||
|
viewerUrl += "&disabledownload=${pdfDownloadDisable}";
|
||||||
|
viewerUrl += "&disablebookmark=${pdfBookmarkDisable}";
|
||||||
|
viewerUrl += "&disableediting=${pdfDisableEditing}";
|
||||||
|
// 可选:高亮关键词和水印(如果后端有传)
|
||||||
|
viewerUrl += "&pdfhighlightall=${pdfhighlightAll}";
|
||||||
|
viewerUrl += "&watermarktxt=${watermarkTxt}";
|
||||||
|
|
||||||
|
// 设置 iframe 地址
|
||||||
|
var iframe = document.getElementById('pdfFrame');
|
||||||
|
iframe.src = viewerUrl;
|
||||||
|
|
||||||
|
// 图片预览切换
|
||||||
function goForImage() {
|
function goForImage() {
|
||||||
var url = window.location.href
|
var href = window.location.href;
|
||||||
if (url.indexOf("officePreviewType=pdf") != -1) {
|
if (href.indexOf("officePreviewType=pdf") !== -1) {
|
||||||
url = url.replace("officePreviewType=pdf", "officePreviewType=image");
|
href = href.replace("officePreviewType=pdf", "officePreviewType=image");
|
||||||
} else {
|
} else {
|
||||||
url = url + "&officePreviewType=image";
|
href += (href.indexOf('?') === -1 ? '?' : '&') + "officePreviewType=image";
|
||||||
}
|
}
|
||||||
window.location.href = url;
|
window.location.href = href;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*初始化水印*/
|
// 水印初始化(保持原有逻辑)
|
||||||
window.onload = function () {
|
window.onload = function () {
|
||||||
|
if (typeof initWaterMark === 'function') {
|
||||||
initWaterMark();
|
initWaterMark();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -80,7 +80,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- JavaSript ================================================== -->
|
<!-- JavaSript ================================================== -->
|
||||||
<script src="js/jquery-3.6.1.min.js"></script>
|
<script src="js/jquery-3.7.1.min.js"></script>
|
||||||
<script src="pptx/jquery.contextMenu.js?v=11.2.5_20210128"></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/idocv/idocv_common.min.js"></script>
|
||||||
<script src="pptx/jquery.mobile-events.min.js"></script>
|
<script src="pptx/jquery.mobile-events.min.js"></script>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no" />
|
||||||
<#include "*/commonHeader.ftl">
|
<#include "*/commonHeader.ftl">
|
||||||
<script src="js/jquery-3.6.1.min.js" type="text/javascript"></script>
|
<script src="js/jquery-3.7.1.min.js" type="text/javascript"></script>
|
||||||
<script src="js/base64.min.js"></script>
|
<script src="js/base64.min.js"></script>
|
||||||
<style>
|
<style>
|
||||||
#container {
|
#container {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
||||||
<title>${file.name}普通文本预览</title>
|
<title>${file.name}普通文本预览</title>
|
||||||
<#include "*/commonHeader.ftl">
|
<#include "*/commonHeader.ftl">
|
||||||
<script src="js/jquery-3.6.1.min.js" type="text/javascript"></script>
|
<script src="js/jquery-3.7.1.min.js" type="text/javascript"></script>
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||||
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
||||||
<script src="js/base64.min.js" type="text/javascript"></script>
|
<script src="js/base64.min.js" type="text/javascript"></script>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
|
||||||
<title>XML预览器</title>
|
<title>XML预览器</title>
|
||||||
<#include "*/commonHeader.ftl">
|
<#include "*/commonHeader.ftl">
|
||||||
<script src="js/jquery-3.6.1.min.js" type="text/javascript"></script>
|
<script src="js/jquery-3.7.1.min.js" type="text/javascript"></script>
|
||||||
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css"/>
|
||||||
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
<script src="bootstrap/js/bootstrap.min.js" type="text/javascript"></script>
|
||||||
<link rel="stylesheet" href="css/xmlTreeViewer.css"/>
|
<link rel="stylesheet" href="css/xmlTreeViewer.css"/>
|
||||||
|
|||||||
Reference in New Issue
Block a user