新增 drawio 绘图预览

This commit is contained in:
gaoxiongzaq
2023-04-20 16:14:42 +08:00
parent 83e20ac83c
commit 57a9dc78ab
104 changed files with 198774 additions and 1 deletions

View File

@@ -22,6 +22,7 @@
20. 支持 mp3,wav,mp4,flv 等音视频格式文件 20. 支持 mp3,wav,mp4,flv 等音视频格式文件
21. 支持 avi,mov,rm,webm,ts,rm,mkv,mpeg,ogg,mpg,rmvb,wmv,3gp,ts,swf 等视频格式转码预览 21. 支持 avi,mov,rm,webm,ts,rm,mkv,mpeg,ogg,mpg,rmvb,wmv,3gp,ts,swf 等视频格式转码预览
22. 支持 dcm 等医疗数位影像预览 22. 支持 dcm 等医疗数位影像预览
23. 支持 drawio 绘图预览
> 基于当前良好的架构模式支持的文件类型在进一步丰富中 > 基于当前良好的架构模式支持的文件类型在进一步丰富中
### 项目特性 ### 项目特性

View File

@@ -26,6 +26,7 @@ Document online preview project solution, built using the popular Spring Boot fr
20. Supports `mp3`,`wav`,`mp4`,`flv` . 20. Supports `mp3`,`wav`,`mp4`,`flv` .
21. Supports many audio and video format files such as `avi`, `mov`, `wmv`, `mkv`, `3gp`, and `rm`. 21. Supports many audio and video format files such as `avi`, `mov`, `wmv`, `mkv`, `3gp`, and `rm`.
22. Supports for `dcm` . 22. Supports for `dcm` .
23. Supports for `drawio` .
### Features ### Features
- Build with the popular frame spring boot - Build with the popular frame spring boot

View File

@@ -31,7 +31,8 @@ public enum FileType {
SVG("svgFilePreviewImpl"), SVG("svgFilePreviewImpl"),
Epub("epubFilePreviewImpl"), Epub("epubFilePreviewImpl"),
BPMN("bpmnFilePreviewImpl"), BPMN("bpmnFilePreviewImpl"),
DCM("dcmFilePreviewImpl"); DCM("dcmFilePreviewImpl"),
DRAWUI("drawioFilePreviewImpl");
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"}; 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"};
private static final String[] PICTURE_TYPES = {"jpg", "jpeg", "png", "gif", "bmp", "ico", "jfif", "webp"}; private static final String[] PICTURE_TYPES = {"jpg", "jpeg", "png", "gif", "bmp", "ico", "jfif", "webp"};
@@ -41,6 +42,7 @@ public enum FileType {
private static final String[] XMIND_TYPES = {"xmind"}; private static final String[] XMIND_TYPES = {"xmind"};
private static final String[] Epub_TYPES = {"epub"}; private static final String[] Epub_TYPES = {"epub"};
private static final String[] DCM_TYPES = {"dcm"}; private static final String[] DCM_TYPES = {"dcm"};
private static final String[] DRAWUI_TYPES = {"drawio"};
private static final String[] TIFF_TYPES = {"tif", "tiff"}; private static final String[] TIFF_TYPES = {"tif", "tiff"};
private static final String[] OFD_TYPES = {"ofd"}; private static final String[] OFD_TYPES = {"ofd"};
private static final String[] SVG_TYPES = {"svg"}; private static final String[] SVG_TYPES = {"svg"};
@@ -100,6 +102,9 @@ public enum FileType {
for (String dcm : DCM_TYPES) { for (String dcm : DCM_TYPES) {
FILE_TYPE_MAPPER.put(dcm, FileType.DCM); FILE_TYPE_MAPPER.put(dcm, FileType.DCM);
} }
for (String drawio : DRAWUI_TYPES) {
FILE_TYPE_MAPPER.put(drawio, FileType.DRAWUI);
}
FILE_TYPE_MAPPER.put("md", FileType.MARKDOWN); FILE_TYPE_MAPPER.put("md", FileType.MARKDOWN);
FILE_TYPE_MAPPER.put("xml", FileType.XML); FILE_TYPE_MAPPER.put("xml", FileType.XML);
FILE_TYPE_MAPPER.put("pdf", FileType.PDF); FILE_TYPE_MAPPER.put("pdf", FileType.PDF);

View File

@@ -30,6 +30,7 @@ public interface FilePreview {
String MARKDOWN_FILE_PREVIEW_PAGE = "markdown"; String MARKDOWN_FILE_PREVIEW_PAGE = "markdown";
String BPMN_FILE_PREVIEW_PAGE = "bpmn"; String BPMN_FILE_PREVIEW_PAGE = "bpmn";
String DCM_FILE_PREVIEW_PAGE = "dcm"; String DCM_FILE_PREVIEW_PAGE = "dcm";
String DRAWUI_FILE_PREVIEW_PAGE = "drawio";
String NOT_SUPPORTED_FILE_PAGE = "fileNotSupported"; String NOT_SUPPORTED_FILE_PAGE = "fileNotSupported";
String filePreviewHandle(String url, Model model, FileAttribute fileAttribute); String filePreviewHandle(String url, Model model, FileAttribute fileAttribute);

View File

@@ -0,0 +1,25 @@
package cn.keking.service.impl;
import cn.keking.model.FileAttribute;
import cn.keking.service.FilePreview;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
/**
* Drawio 文件处理
*/
@Service
public class DrawioFilePreviewImpl implements FilePreview {
private final CommonPreviewImpl commonPreview;
public DrawioFilePreviewImpl(CommonPreviewImpl commonPreview) {
this.commonPreview = commonPreview;
}
@Override
public String filePreviewHandle(String url, Model model, FileAttribute fileAttribute) {
commonPreview.filePreviewHandle(url,model,fileAttribute);
return DRAWUI_FILE_PREVIEW_PAGE;
}
}

View File

@@ -0,0 +1,313 @@
<!--[if IE]><meta http-equiv="X-UA-Compatible" content="IE=5" ><![endif]-->
<!DOCTYPE html>
<html>
<head>
<title>drawio文件预览</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=yes, initial-scale=1.0">
<script type="text/javascript">
var urlParams = (function()
{
var result = new Object();
var params = window.location.search.slice(1).split('&');
for (var i = 0; i < params.length; i++)
{
var idx = params[i].indexOf('=');
if (idx > 0)
{
result[params[i].substring(0, idx)] = params[i].substring(idx + 1);
}
}
return result;
})();
if (window.location.hash != null && window.location.hash.substring(0, 2) == '#P')
{
try
{
urlParams = JSON.parse(decodeURIComponent(window.location.hash.substring(2)));
if (urlParams.hash != null)
{
window.location.hash = urlParams.hash;
}
}
catch (e)
{
// ignore
}
}
// Global variable for desktop
var mxIsElectron = window && window.process && window.process.type;
/**
* Synchronously adds scripts to the page.
*/
function mxscript(src, onLoad, id, dataAppKey, noWrite, onError)
{
var defer = onLoad == null && !noWrite;
if ((urlParams['dev'] != '1' && typeof document.createElement('canvas').getContext === "function") ||
onLoad != null || noWrite)
{
var s = document.createElement('script');
s.setAttribute('type', 'text/javascript');
s.setAttribute('defer', 'true');
s.setAttribute('src', src);
if (id != null)
{
s.setAttribute('id', id);
}
if (onLoad != null)
{
var r = false;
s.onload = s.onreadystatechange = function()
{
if (!r && (!this.readyState || this.readyState == 'complete'))
{
r = true;
onLoad();
}
};
}
if (onError != null)
{
s.onerror = function(e)
{
onError('Failed to load ' + src, e);
};
}
var t = document.getElementsByTagName('script')[0];
if (t != null)
{
t.parentNode.insertBefore(s, t);
}
}
};
/**
* Asynchronously adds scripts to the page.
*/
function mxinclude(src)
{
var g = document.createElement('script');
g.type = 'text/javascript';
g.async = true;
g.src = src;
var s = document.getElementsByTagName('script')[0];
s.parentNode.insertBefore(g, s);
};
// Checks for local storage
var isLocalStorage = false;
try
{
isLocalStorage = urlParams['local'] != '1' && typeof(localStorage) != 'undefined';
}
catch (e)
{
// ignored
}
var mxScriptsLoaded = false, mxWinLoaded = false;
function checkAllLoaded()
{
if (mxScriptsLoaded && mxWinLoaded)
{
App.main();
}
};
var t0 = new Date();
// Changes paths for local development environment
if (urlParams['dev'] == '1')
{
mxForceIncludes = false;
mxscript(drawDevUrl + 'js/PreConfig.js');
mxscript(drawDevUrl + 'js/diagramly/Init.js');
mxscript(geBasePath + '/Init.js');
mxscript(mxBasePath + '/mxClient.js');
mxscript(drawDevUrl + 'js/PostConfig.js');
}
else
{
(function()
{
var hostName = window.location.hostname;
// Supported domains are *.draw.io and the packaged version in Quip
var supportedDomain = (hostName.substring(hostName.length - 8, hostName.length) === '.draw.io') ||
(hostName.substring(hostName.length - 13, hostName.length) === '.kkview.cn');
function loadAppJS()
{
mxscript('js/app.min.js', function()
{
mxScriptsLoaded = true;
checkAllLoaded();
// Electron
if (mxIsElectron)
{
mxscript('js/diagramly/DesktopLibrary.js', function()
{
mxscript('js/diagramly/ElectronApp.js', function()
{
mxscript('js/extensions.min.js', function()
{
mxscript('js/stencils.min.js', function()
{
mxscript('js/shapes-14-6-5.min.js', function()
{
mxscript('js/PostConfig.js');
});
});
});
});
});
}
else if (!supportedDomain)
{
mxscript('js/PostConfig.js');
}
});
};
if (!supportedDomain || mxIsElectron)
{
mxscript('js/PreConfig.js', loadAppJS);
}
else
{
loadAppJS();
}
})();
}
// Adds basic error handling
window.onerror = function()
{
var status = document.getElementById('geStatus');
if (status != null)
{
status.innerHTML = 'Page could not be loaded. Please try refreshing.';
}
};
</script>
<link rel="stylesheet" type="text/css" href="styles/grapheditor.css">
<link rel="shortcut icon" href="favicon.ico">
<style type="text/css">
body { overflow:hidden; }
div.picker { z-index: 10007; }
.geSidebarContainer .geTitle input {
font-size:8pt;
color:#606060;
}
.geBlock {
z-index:-3;
margin:100px;
margin-top:40px;
margin-bottom:30px;
padding:20px;
text-align:center;
min-width:50%;
}
.geBlock h1, .geBlock h2 {
margin-top:0px;
padding-top:0px;
}
.geEditor *:not(.geScrollable)::-webkit-scrollbar {
width:10px;
height:10px;
}
.geEditor ::-webkit-scrollbar-track {
background-clip:padding-box;
border:solid transparent;
border-width:1px;
}
.geEditor ::-webkit-scrollbar-corner {
background-color:transparent;
}
.geEditor ::-webkit-scrollbar-thumb {
background-color:rgba(0,0,0,.1);
background-clip:padding-box;
border:solid transparent;
border-radius:10px;
}
.geEditor ::-webkit-scrollbar-thumb:hover {
background-color:rgba(0,0,0,.4);
}
.geTemplate {
border:1px solid transparent;
display:inline-block;
_display:inline;
vertical-align:top;
border-radius:3px;
overflow:hidden;
font-size:14pt;
cursor:pointer;
margin:5px;
}
</style>
<!-- Workaround for binary XHR in IE 9/10, see App.loadUrl -->
<!--[if (IE 9)|(IE 10)]><!-->
<script type="text/vbscript">
Function mxUtilsBinaryToArray(Binary)
Dim i
ReDim byteArray(LenB(Binary))
For i = 1 To LenB(Binary)
byteArray(i-1) = AscB(MidB(Binary, i, 1))
Next
mxUtilsBinaryToArray = byteArray
End Function
</script>
<!--<![endif]-->
</head>
<body class="geEditor">
<script type="text/javascript">
/**
* Main
*/
if (urlParams['dev'] != '1' && typeof document.createElement('canvas').getContext === "function")
{
window.addEventListener('load', function()
{
mxWinLoaded = true;
checkAllLoaded();
});
}
else
{
App.main();
}
</script>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
/**
* Copyright (c) 2006-2020, JGraph Ltd
* Copyright (c) 2006-2020, draw.io AG
*/
// null'ing of global vars need to be after init.js
window.VSD_CONVERT_URL = null;
window.EMF_CONVERT_URL = null;
window.ICONSEARCH_PATH = null;

View File

@@ -0,0 +1,13 @@
/**
* Copyright (c) 2006-2020, JGraph Ltd
* Copyright (c) 2006-2020, draw.io AG
*/
// Overrides of global vars need to be pre-loaded
window.EXPORT_URL = 'REPLACE_WITH_YOUR_IMAGE_SERVER';
window.PLANT_URL = 'REPLACE_WITH_YOUR_PLANTUML_SERVER';
window.DRAWIO_BASE_URL = null; // Replace with path to base of deployment, e.g. https://www.example.com/folder
window.DRAWIO_VIEWER_URL = null; // Replace your path to the viewer js, e.g. https://www.example.com/js/viewer.min.js
window.DRAWIO_LIGHTBOX_URL = null; // Replace with your lightbox URL, eg. https://www.example.com
window.DRAW_MATH_URL = 'math/es5';
window.DRAWIO_CONFIG = null; // Replace with your custom draw.io configurations. For more details, https://www.diagrams.net/doc/faq/configure-diagram-editor
urlParams['sync'] = 'manual';

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,146 @@
div.mxRubberband {
position: absolute;
overflow: hidden;
border-style: solid;
border-width: 1px;
border-color: #0000FF;
background: #0077FF;
}
.mxCellEditor {
background: url(data:image/gif;base64,R0lGODlhMAAwAIAAAP///wAAACH5BAEAAAAALAAAAAAwADAAAAIxhI+py+0Po5y02ouz3rz7D4biSJbmiabqyrbuC8fyTNf2jef6zvf+DwwKh8Si8egpAAA7);
_background: url('../images/transparent.gif');
border-color: transparent;
border-style: solid;
display: inline-block;
position: absolute;
overflow: visible;
word-wrap: normal;
border-width: 0;
min-width: 1px;
resize: none;
padding: 0px;
margin: 0px;
}
.mxPlainTextEditor * {
padding: 0px;
margin: 0px;
}
div.mxWindow {
-webkit-box-shadow: 3px 3px 12px #C0C0C0;
-moz-box-shadow: 3px 3px 12px #C0C0C0;
box-shadow: 3px 3px 12px #C0C0C0;
background: url(data:image/gif;base64,R0lGODlhGgAUAIAAAOzs7PDw8CH5BAAAAAAALAAAAAAaABQAAAIijI+py70Ao5y02lud3lzhD4ZUR5aPiKajyZbqq7YyB9dhAQA7);
_background: url('../images/window.gif');
border:1px solid #c3c3c3;
position: absolute;
overflow: hidden;
z-index: 1;
}
table.mxWindow {
border-collapse: collapse;
table-layout: fixed;
font-family: Arial;
font-size: 8pt;
}
td.mxWindowTitle {
background: url(data:image/gif;base64,R0lGODlhFwAXAMQAANfX18rKyuHh4c7OzsDAwMHBwc/Pz+Li4uTk5NHR0dvb2+jo6O/v79/f3/n5+dnZ2dbW1uPj44yMjNPT0+Dg4N3d3ebm5szMzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH5BAAAAAAALAAAAAAXABcAAAWQICESxWiW5Ck6bOu+MMvMdG3f86LvfO/rlqBwSCwaj8ikUohoOp/QaDNCrVqvWKpgezhsv+AwmEIum89ocmPNbrvf64p8Tq/b5Yq8fs/v5x+AgYKDhIAAh4iJiouHEI6PkJGSjhOVlpeYmZUJnJ2en6CcBqMDpaanqKgXq6ytrq+rAbKztLW2shK5uru8vbkhADs=) repeat-x;
_background: url('../images/window-title.gif') repeat-x;
text-overflow: ellipsis;
white-space: nowrap;
text-align: center;
font-weight: bold;
overflow: hidden;
height: 13px;
padding: 2px;
padding-top: 4px;
padding-bottom: 6px;
color: black;
}
td.mxWindowPane {
vertical-align: top;
padding: 0px;
}
div.mxWindowPane {
overflow: hidden;
position: relative;
}
img.mxToolbarItem {
margin-right: 6px;
margin-bottom: 6px;
border-width: 1px;
}
select.mxToolbarCombo {
vertical-align: top;
border-style: inset;
border-width: 2px;
}
div.mxToolbarComboContainer {
padding: 2px;
}
img.mxToolbarMode {
margin: 2px;
margin-right: 4px;
margin-bottom: 4px;
border-width: 0px;
}
img.mxToolbarModeSelected {
margin: 0px;
margin-right: 2px;
margin-bottom: 2px;
border-width: 2px;
border-style: inset;
}
div.mxTooltip {
-webkit-box-shadow: 3px 3px 12px #C0C0C0;
-moz-box-shadow: 3px 3px 12px #C0C0C0;
box-shadow: 3px 3px 12px #C0C0C0;
background: #FFFFCC;
border-style: solid;
border-width: 1px;
border-color: black;
font-family: Arial;
font-size: 8pt;
position: absolute;
cursor: default;
padding: 4px;
color: black;
}
div.mxPopupMenu {
-webkit-box-shadow: 3px 3px 12px #C0C0C0;
-moz-box-shadow: 3px 3px 12px #C0C0C0;
box-shadow: 3px 3px 12px #C0C0C0;
background: url(data:image/gif;base64,R0lGODlhGgAUAIAAAOzs7PDw8CH5BAAAAAAALAAAAAAaABQAAAIijI+py70Ao5y02lud3lzhD4ZUR5aPiKajyZbqq7YyB9dhAQA7);
_background: url('../images/window.gif');
position: absolute;
border-style: solid;
border-width: 1px;
border-color: black;
}
table.mxPopupMenu {
border-collapse: collapse;
margin-top: 1px;
margin-bottom: 1px;
}
tr.mxPopupMenuItem {
color: black;
cursor: pointer;
}
tr.mxPopupMenuItemHover {
background-color: #000066;
color: #FFFFFF;
cursor: pointer;
}
td.mxPopupMenuItem {
padding: 2px 30px 2px 10px;
white-space: nowrap;
font-family: Arial;
font-size: 8pt;
}
td.mxPopupMenuIcon {
background-color: #D0D0D0;
padding: 2px 4px 2px 4px;
}
.mxDisabled {
opacity: 0.2 !important;
cursor:default !important;
}

View File

@@ -0,0 +1,18 @@
div.mxTooltip {
filter:progid:DXImageTransform.Microsoft.DropShadow(OffX=4, OffY=4,
Color='#A2A2A2', Positive='true');
}
div.mxPopupMenu {
filter:progid:DXImageTransform.Microsoft.DropShadow(OffX=4, OffY=4,
Color='#C0C0C0', Positive='true');
}
div.mxWindow {
_filter:progid:DXImageTransform.Microsoft.DropShadow(OffX=4, OffY=4,
Color='#C0C0C0', Positive='true');
}
td.mxWindowTitle {
_height: 23px;
}
.mxDisabled {
filter:alpha(opacity=20) !important;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 877 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 907 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 843 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 845 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 146 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 425 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 275 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 75 B

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

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

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

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

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More