添加看板导入功能

This commit is contained in:
datagear 2020-01-11 16:23:13 +08:00
parent 3c5b4894f2
commit 5fc31b13f4
11 changed files with 341 additions and 17 deletions

View File

@ -3,8 +3,6 @@
*/
package org.datagear.analysis;
import org.datagear.util.StringUtil;
/**
* 模板看板部件
* <p>
@ -17,9 +15,11 @@ import org.datagear.util.StringUtil;
public abstract class TemplateDashboardWidget<T extends RenderContext> extends AbstractIdentifiable
implements DashboardWidget<T>
{
public static final String DEFAULT_TEMPLATE_ENCODING = "UTF-8";
private String template;
private String templateEncoding = "UTF-8";
private String templateEncoding = DEFAULT_TEMPLATE_ENCODING;
public TemplateDashboardWidget()
{
@ -42,11 +42,6 @@ public abstract class TemplateDashboardWidget<T extends RenderContext> extends A
this.template = template;
}
public boolean hasTemplateEncoding()
{
return !StringUtil.isEmpty(this.templateEncoding);
}
public String getTemplateEncoding()
{
return templateEncoding;

View File

@ -112,6 +112,20 @@ public class DashboardWidgetResManager
}
}
/**
* 获取指定看板部件的主目录
* <p>
* 如果目录不存在则会自动创建
* </p>
*
* @param id
* @return
*/
public File getDirectory(String id)
{
return FileUtil.getDirectory(this.rootDirectory, id, true);
}
/**
* 获取目录
* <p>

View File

@ -391,7 +391,7 @@ public abstract class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext
if (!templateFile.exists())
return new StringReader("");
if (dashboardWidget.hasTemplateEncoding())
if (!StringUtil.isEmpty(dashboardWidget.getTemplateEncoding()))
return IOUtil.getReader(templateFile, dashboardWidget.getTemplateEncoding());
else
return IOUtil.getReader(templateFile);
@ -411,7 +411,7 @@ public abstract class HtmlTplDashboardWidgetRenderer<T extends HtmlRenderContext
{
File templateFile = getTemplateFile(dashboardWidget);
if (dashboardWidget.hasTemplateEncoding())
if (!StringUtil.isEmpty(dashboardWidget.getTemplateEncoding()))
return IOUtil.getWriter(templateFile, dashboardWidget.getTemplateEncoding());
else
return IOUtil.getWriter(templateFile);

View File

@ -225,6 +225,7 @@ CREATE TABLE DATAGEAR_HTML_DASHBOARD
HD_ID VARCHAR(50) NOT NULL,
HD_NAME VARCHAR(100) NOT NULL,
HD_TEMPLATE VARCHAR(100) NOT NULL,
HD_TEMPLATE_ENCODING VARCHAR(50),
HD_CREATE_USER_ID VARCHAR(50),
HD_CREATE_TIME TIMESTAMP,
PRIMARY KEY (HD_ID)

View File

@ -6,12 +6,12 @@
<insert id="insert">
INSERT INTO DATAGEAR_HTML_DASHBOARD
(
HD_ID, HD_NAME, HD_TEMPLATE, HD_CREATE_USER_ID,
HD_ID, HD_NAME, HD_TEMPLATE, HD_TEMPLATE_ENCODING, HD_CREATE_USER_ID,
HD_CREATE_TIME
)
VALUES
(
#{entity.id}, #{entity.name}, #{entity.template}, #{entity.createUser.id},
#{entity.id}, #{entity.name}, #{entity.template}, #{entity.templateEncoding}, #{entity.createUser.id},
#{entity.createTime}
)
</insert>
@ -19,7 +19,8 @@
<update id="update">
UPDATE DATAGEAR_HTML_DASHBOARD SET
HD_NAME = #{entity.name},
HD_TEMPLATE = #{entity.template}
HD_TEMPLATE = #{entity.template},
HD_TEMPLATE_ENCODING = #{entity.templateEncoding}
WHERE
HD_ID = #{entity.id}
</update>
@ -136,6 +137,7 @@
A.HD_ID AS ${_iq_}id${_iq_},
A.HD_NAME AS ${_iq_}name${_iq_},
A.HD_TEMPLATE AS ${_iq_}template${_iq_},
A.HD_TEMPLATE_ENCODING AS ${_iq_}templateEncoding${_iq_},
<include refid="common.fieldsForCreateUser" />,
A.HD_CREATE_TIME AS ${_iq_}createTime${_iq_}
FROM

View File

@ -67,6 +67,7 @@ public class ChartPluginController extends AbstractChartPluginAwareController
DirectoryHtmlChartPluginManager directoryHtmlChartPluginManager, File tempDirectory)
{
super(messageSource, classDataConverter, directoryHtmlChartPluginManager);
this.tempDirectory = tempDirectory;
}
public File getTempDirectory()

View File

@ -6,12 +6,15 @@ package org.datagear.web.controller;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.io.Writer;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.zip.ZipInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@ -31,6 +34,7 @@ import org.datagear.management.domain.User;
import org.datagear.management.service.HtmlTplDashboardWidgetEntityService;
import org.datagear.persistence.PagingData;
import org.datagear.persistence.PagingQuery;
import org.datagear.util.FileUtil;
import org.datagear.util.IDUtil;
import org.datagear.util.IOUtil;
import org.datagear.util.StringUtil;
@ -44,6 +48,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.multipart.MultipartFile;
/**
* 看板控制器
@ -58,15 +63,20 @@ public class DashboardController extends AbstractDataAnalysisController
@Autowired
private HtmlTplDashboardWidgetEntityService htmlTplDashboardWidgetEntityService;
@Autowired
private File tempDirectory;
public DashboardController()
{
super();
}
public DashboardController(HtmlTplDashboardWidgetEntityService htmlTplDashboardWidgetEntityService)
public DashboardController(HtmlTplDashboardWidgetEntityService htmlTplDashboardWidgetEntityService,
File tempDirectory)
{
super();
this.htmlTplDashboardWidgetEntityService = htmlTplDashboardWidgetEntityService;
this.tempDirectory = tempDirectory;
}
public HtmlTplDashboardWidgetEntityService getHtmlTplDashboardWidgetEntityService()
@ -80,12 +90,29 @@ public class DashboardController extends AbstractDataAnalysisController
this.htmlTplDashboardWidgetEntityService = htmlTplDashboardWidgetEntityService;
}
public File getTempDirectory()
{
return tempDirectory;
}
public void setTempDirectory(File tempDirectory)
{
this.tempDirectory = tempDirectory;
}
@RequestMapping("/add")
public String add(HttpServletRequest request, org.springframework.ui.Model model)
{
HtmlTplDashboardWidgetEntity dashboard = new HtmlTplDashboardWidgetEntity();
dashboard.setTemplate(HtmlTplDashboardWidgetEntity.DEFAULT_TEMPLATE);
dashboard.setTemplateEncoding(HtmlTplDashboardWidget.DEFAULT_TEMPLATE_ENCODING);
String templateContent = "<!DOCTYPE html>\n<html>\n<head>\n<meta charset=\"" + dashboard.getTemplateEncoding()
+ "\">\n</head>\n<body>\n</body>\n</html>";
model.addAttribute("dashboard", dashboard);
model.addAttribute("templateContent", templateContent);
model.addAttribute(KEY_TITLE_MESSAGE_KEY, "dashboard.addDashboard");
model.addAttribute(KEY_FORM_ACTION, "saveAdd");
@ -100,8 +127,6 @@ public class DashboardController extends AbstractDataAnalysisController
{
User user = WebUtils.getUser(request, response);
dashboard.setTemplate(HtmlTplDashboardWidgetEntity.DEFAULT_TEMPLATE);
checkSaveEntity(dashboard);
dashboard.setId(IDUtil.uuid());
@ -142,7 +167,8 @@ public class DashboardController extends AbstractDataAnalysisController
{
User user = WebUtils.getUser(request, response);
dashboard.setTemplate(HtmlTplDashboardWidgetEntity.DEFAULT_TEMPLATE);
if (isEmpty(dashboard.getTemplate()))
dashboard.setTemplate(HtmlTplDashboardWidgetEntity.DEFAULT_TEMPLATE);
checkSaveEntity(dashboard);
@ -154,6 +180,124 @@ public class DashboardController extends AbstractDataAnalysisController
return buildOperationMessageSaveSuccessResponseEntity(request);
}
@RequestMapping("/import")
public String impt(HttpServletRequest request, org.springframework.ui.Model model)
{
return "/analysis/dashboard/dashboard_import";
}
@RequestMapping(value = "/uploadFile", produces = CONTENT_TYPE_JSON)
@ResponseBody
public Map<String, Object> uploadFile(HttpServletRequest request, HttpServletResponse response,
@RequestParam("file") MultipartFile multipartFile) throws Exception
{
String dashboardFileName = "";
String template = "";
String templateEncoding = "";
File tmpDirectory = FileUtil.generateUniqueDirectory(this.tempDirectory);
dashboardFileName = tmpDirectory.getName();
String fileName = multipartFile.getOriginalFilename();
if (FileUtil.isExtension(fileName, "zip"))
{
ZipInputStream in = IOUtil.getZipInputStream(multipartFile.getInputStream());
try
{
IOUtil.unzip(in, tmpDirectory);
}
finally
{
IOUtil.close(in);
}
File[] files = tmpDirectory.listFiles();
if (files != null)
{
for (File file : files)
{
if (file.isDirectory())
continue;
String name = file.getName();
if (FileUtil.isExtension(name, "html") || FileUtil.isExtension(name, "htm"))
{
template = name;
if (template.equalsIgnoreCase("index.html") || template.equalsIgnoreCase("index.htm"))
break;
}
}
}
}
else
{
File file = FileUtil.getFile(tmpDirectory, fileName);
InputStream in = null;
OutputStream out = null;
try
{
in = multipartFile.getInputStream();
out = IOUtil.getOutputStream(file);
IOUtil.write(in, out);
}
finally
{
IOUtil.close(in);
IOUtil.close(out);
}
template = fileName;
}
Map<String, Object> results = new HashMap<String, Object>();
results.put("dashboardFileName", dashboardFileName);
results.put("template", template);
results.put("templateEncoding", templateEncoding);
return results;
}
@RequestMapping(value = "/saveImport", produces = CONTENT_TYPE_JSON)
@ResponseBody
public ResponseEntity<OperationMessage> saveImport(HttpServletRequest request, HttpServletResponse response,
@RequestParam("name") String name,
@RequestParam("template") String template, @RequestParam("templateEncoding") String templateEncoding,
@RequestParam("dashboardFileName") String dashboardFileName)
throws Exception
{
File uploadDirectory = FileUtil.getDirectory(this.tempDirectory, dashboardFileName, false);
if (!uploadDirectory.exists())
throw new IllegalInputException();
User user = WebUtils.getUser(request, response);
HtmlTplDashboardWidgetEntity dashboard = new HtmlTplDashboardWidgetEntity();
dashboard.setTemplate(template);
dashboard.setTemplateEncoding(templateEncoding);
dashboard.setName(name);
checkSaveEntity(dashboard);
dashboard.setId(IDUtil.uuid());
dashboard.setCreateUser(user);
this.htmlTplDashboardWidgetEntityService.add(user, dashboard);
DashboardWidgetResManager dashboardWidgetResManager = this.htmlTplDashboardWidgetEntityService
.getHtmlTplDashboardWidgetRenderer().getDashboardWidgetResManager();
File dashboardResDirectory = dashboardWidgetResManager.getDirectory(dashboard.getId());
IOUtil.copy(uploadDirectory, dashboardResDirectory, false);
return buildOperationMessageSaveSuccessResponseEntity(request);
}
@RequestMapping("/view")
public String view(HttpServletRequest request, HttpServletResponse response, org.springframework.ui.Model model,
@RequestParam("id") String id) throws Exception
@ -242,6 +386,13 @@ public class DashboardController extends AbstractDataAnalysisController
if (dashboardWidget == null)
throw new RecordNotFoundException();
String responseEncoding = dashboardWidget.getTemplateEncoding();
if (StringUtil.isEmpty(responseEncoding))
responseEncoding = Charset.defaultCharset().name();
response.setCharacterEncoding(responseEncoding);
Writer out = response.getWriter();
DefaultHtmlRenderContext renderContext = new DefaultHtmlRenderContext(createWebContext(request), out);

View File

@ -649,11 +649,17 @@ dashboard.addDashboard=\u6DFB\u52A0\u770B\u677F
dashboard.editDashboard=\u7F16\u8F91\u770B\u677F
dashboard.viewDashboard=\u67E5\u770B\u770B\u677F
dashboard.selectDashboard=\u9009\u62E9\u770B\u677F
dashboard.importDashboard=\u5BFC\u5165\u770B\u677F
dashboard.name=\u540D\u79F0
dashboard.template=HTML\u6A21\u677F
dashboard.templateEncoding=HTML\u6A21\u677F\u7F16\u7801
dashboard.templateName=HTML\u6A21\u677F\u6587\u4EF6\u540D
dashboard.createUser=\u521B\u5EFA\u7528\u6237
dashboard.createTime=\u521B\u5EFA\u65F6\u95F4
dashboard.show=\u5C55\u793A
dashboard.import.selectFile=\u9009\u62E9\u6587\u4EF6
dashboard.import.desc=\u6587\u4EF6\u683C\u5F0F\u5E94\u4E3A\uFF1A*.html\u3001*.htm\u3001*.zip
dashboard.import.validation.importDashboardFileRequired=\u8BF7\u9009\u62E9\u770B\u677F\u6587\u4EF6
#Chart plugin
chartPlugin.manageChartPlugin=\u7BA1\u7406\u56FE\u8868\u63D2\u4EF6

View File

@ -19,6 +19,8 @@ readonly 是否只读操作允许为null
<div class="form-head"></div>
<div class="form-content">
<input type="hidden" name="id" value="${(dashboard.id)!''?html}" />
<input type="hidden" name="template" value="${(dashboard.template)!''?html}" />
<input type="hidden" name="templateEncoding" value="${(dashboard.templateEncoding)!''?html}" />
<div class="form-item">
<div class="form-item-label">
<label><@spring.message code='dashboard.name' /></label>

View File

@ -25,6 +25,7 @@ selectonly 是否选择操作允许为null
<input name="viewButton" type="button" value="<@spring.message code='view' />" />
<#else>
<input name="addButton" type="button" value="<@spring.message code='add' />" />
<input name="importButton" type="button" value="<@spring.message code='import' />" />
<input name="editButton" type="button" value="<@spring.message code='edit' />" />
<input name="viewButton" type="button" value="<@spring.message code='view' />" />
<input name="showButton" type="button" value="<@spring.message code='dashboard.show' />" />
@ -74,6 +75,20 @@ selectonly 是否选择操作允许为null
});
});
po.element("input[name=importButton]").click(function()
{
po.open(po.url("import"),
{
pageParam :
{
afterSave : function()
{
po.refresh();
}
}
});
});
po.element("input[name=editButton]").click(function()
{
po.executeOnSelect(function(row)

View File

@ -0,0 +1,137 @@
<#include "../../include/import_global.ftl">
<#include "../../include/html_doctype.ftl">
<html>
<head>
<#include "../../include/html_head.ftl">
<title><#include "../../include/html_title_app_name.ftl"><@spring.message code='dashboard.importDashboard' /></title>
</head>
<body>
<div id="${pageId}" class="page-form page-form-importDashboard">
<form id="${pageId}-form" action="${contextPath}/analysis/dashboard/saveImport" method="POST">
<div class="form-head"></div>
<div class="form-content">
<input type="hidden" name="dashboardFileName" value="" />
<div class="form-item">
<div class="form-item-label">
<label><@spring.message code='dashboard.import.selectFile' /></label>
</div>
<div class="form-item-value">
<input type="hidden" name="inputForValidate" value="" />
<div class="fileinput-button" title="<@spring.message code='dashboard.import.desc' />">
<@spring.message code='select' /><input type="file" accept=".html, .htm, .zip" class="ignore">
</div>
<div class="upload-file-info"></div>
</div>
</div>
<div class="form-item">
<div class="form-item-label">
<label><@spring.message code='dashboard.name' /></label>
</div>
<div class="form-item-value">
<input type="text" name="name" value="" class="ui-widget ui-widget-content" />
</div>
</div>
<div class="form-item">
<div class="form-item-label">
<label><@spring.message code='dashboard.templateName' /></label>
</div>
<div class="form-item-value">
<input type="text" name="template" value="" class="ui-widget ui-widget-content" />
</div>
</div>
<div class="form-item">
<div class="form-item-label">
<label><@spring.message code='dashboard.templateEncoding' /></label>
</div>
<div class="form-item-value">
<input type="text" name="templateEncoding" value="" class="ui-widget ui-widget-content" />
</div>
</div>
</div>
<div class="form-foot" style="text-align:center;">
<input type="submit" value="<@spring.message code='save' />" class="recommended" />
</div>
</form>
</div>
<#include "../../include/page_js_obj.ftl" >
<#include "../../include/page_obj_form.ftl">
<script type="text/javascript">
(function(po)
{
po.element("input:submit, input:button, input:reset, button, .fileinput-button").button();
po.url = function(action)
{
return "${contextPath}/analysis/dashboard/" + action;
};
po.fileUploadInfo = function(){ return this.element(".upload-file-info"); };
po.element(".fileinput-button").fileupload(
{
url : po.url("uploadFile"),
paramName : "file",
success : function(uploadResult, textStatus, jqXHR)
{
$.fileuploadsuccessHandlerForUploadInfo(po.fileUploadInfo(), false);
po.element("input[name='dashboardFileName']").val(uploadResult.dashboardFileName);
po.element("input[name='template']").val(uploadResult.template);
po.element("input[name='templateEncoding']").val(uploadResult.templateEncoding);
}
})
.bind('fileuploadadd', function (e, data)
{
po.element("input[name='dashboardFileName']").val("");
$.fileuploadaddHandlerForUploadInfo(e, data, po.fileUploadInfo());
})
.bind('fileuploadprogressall', function (e, data)
{
$.fileuploadprogressallHandlerForUploadInfo(e, data, po.fileUploadInfo());
});
$.validator.addMethod("uploadDashboardFileRequired", function(value, element)
{
var thisForm = $(element).closest("form");
var dashboardFileName = $("input[name='dashboardFileName']", thisForm).val();
return dashboardFileName.length > 0;
});
po.form().validate(
{
ignore : ".ignore",
rules :
{
name : "required",
inputForValidate : "uploadDashboardFileRequired",
template : "required"
},
messages :
{
name : "<@spring.message code='validation.required' />",
inputForValidate : "<@spring.message code='dashboard.import.validation.importDashboardFileRequired' />",
template : "<@spring.message code='validation.required' />"
},
submitHandler : function(form)
{
$(form).ajaxSubmit(
{
success : function()
{
var close = (po.pageParamCall("afterSave") != false);
if(close)
po.close();
}
});
},
errorPlacement : function(error, element)
{
error.appendTo(element.closest(".form-item-value"));
}
});
})
(${pageId});
</script>
</body>
</html>