Browse Source

open

master
pioneer 2 years ago
commit
890213df6b
  1. 6
      README.md
  2. BIN
      doc/JSD-9922-配置使用文档.docx
  3. BIN
      doc/JSD-9922-需求确认书V1.docx
  4. BIN
      lib/bcprov-jdk15on-1.69.jar
  5. BIN
      lib/finekit-10.0.jar
  6. BIN
      lib/hutool-core-5.7.9.jar
  7. BIN
      lib/hutool-crypto-5.7.9.jar
  8. 42
      plugin.xml
  9. 85
      src/main/java/com/fr/plugin/tabledataservice/ConfigTableDataService.java
  10. 22
      src/main/java/com/fr/plugin/tabledataservice/Constants.java
  11. 31
      src/main/java/com/fr/plugin/tabledataservice/LocaleFinder.java
  12. 183
      src/main/java/com/fr/plugin/tabledataservice/exporter/JSONExporter.java
  13. 140
      src/main/java/com/fr/plugin/tabledataservice/request/ReportDataHandler.java
  14. 46
      src/main/java/com/fr/plugin/tabledataservice/request/RequestHandlerBridge.java
  15. 185
      src/main/java/com/fr/plugin/tabledataservice/request/TableDataHandler.java
  16. 42
      src/main/java/com/fr/plugin/tabledataservice/request/URLAliasBridge.java
  17. 32
      src/main/java/com/fr/plugin/tabledataservice/toolbar/JSONExport.java
  18. 53
      src/main/java/com/fr/plugin/tabledataservice/toolbar/JSONExportOperate.java
  19. 39
      src/main/java/com/fr/plugin/tabledataservice/toolbar/JSONExportToolbarUI.java
  20. 74
      src/main/java/com/fr/plugin/tabledataservice/toolbar/JSONExtensionButton.java
  21. 178
      src/main/java/com/fr/plugin/tabledataservice/utils/FuncUtils.java
  22. 39
      src/main/java/com/fr/plugin/tabledataservice/web/JavaScriptFile.java
  23. BIN
      src/main/resources/com/fr/plugin/tabledataservice/images/json16.png
  24. 22
      src/main/resources/com/fr/plugin/tabledataservice/locale/lang.properties
  25. 22
      src/main/resources/com/fr/plugin/tabledataservice/locale/lang_zh_CN.properties
  26. 35
      src/main/resources/com/fr/plugin/tabledataservice/web/JSONExporter.js

6
README.md

@ -0,0 +1,6 @@
# open-JSD-9922
JSD-9922 使用国密加密算法对外提供接口数据\
免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\
仅作为开发者学习参考使用!禁止用于任何商业用途!\
为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。

BIN
doc/JSD-9922-配置使用文档.docx

Binary file not shown.

BIN
doc/JSD-9922-需求确认书V1.docx

Binary file not shown.

BIN
lib/bcprov-jdk15on-1.69.jar

Binary file not shown.

BIN
lib/finekit-10.0.jar

Binary file not shown.

BIN
lib/hutool-core-5.7.9.jar

Binary file not shown.

BIN
lib/hutool-crypto-5.7.9.jar

Binary file not shown.

42
plugin.xml

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?>
<plugin>
<id>com.fr.plugin.tabledataservice.haeo</id>
<name><![CDATA[jsd8155-数据json服务api]]></name>
<active>yes</active>
<version>1.3</version>
<env-version>11.0</env-version>
<jartime>2021-10-01</jartime>
<vendor>fr.open</vendor>
<description><![CDATA[jsd8155-报表、数据集输出JSON服务API]]></description>
<change-notes><![CDATA[
[2022-03-31]功能适配FR11.0。<br/>
[2021-09-30]国密加密功能。<br/>
[2021-03-31]修复工具栏JSON导出问题。<br/>
版本1.0主要功能:<br/>
1.模板数据集输出JSON服务API功能。<br/>
2.报表结果输出JSON服务API功能。<br/>
3.报表页面导出JSON文件下载功能。<br/>
]]></change-notes>
<main-package>com.fr.plugin.tabledataservice</main-package>
<prefer-packages>
<prefer-package>com.fanruan.api</prefer-package>
</prefer-packages>
<extra-core>
<LocaleFinder class="com.fr.plugin.tabledataservice.LocaleFinder"/>
</extra-core>
<extra-report>
<ExportOperateProvider class="com.fr.plugin.tabledataservice.toolbar.JSONExport"/>
<ExtensionButtonProvider class="com.fr.plugin.tabledataservice.toolbar.JSONExtensionButton"/>
<JavaScriptFileHandler class="com.fr.plugin.tabledataservice.web.JavaScriptFile"/>
</extra-report>
<extra-designer>
<ToolbarItemProvider class="com.fr.plugin.tabledataservice.toolbar.JSONExportToolbarUI"/>
</extra-designer>
<extra-decision>
<HttpHandlerProvider class="com.fr.plugin.tabledataservice.request.RequestHandlerBridge"/>
<URLAliasProvider class="com.fr.plugin.tabledataservice.request.URLAliasBridge"/>
</extra-decision>
<function-recorder class="com.fr.plugin.tabledataservice.request.TableDataHandler"/>
<function-recorder class="com.fr.plugin.tabledataservice.request.ReportDataHandler"/>
<function-recorder class="com.fr.plugin.tabledataservice.exporter.JSONExporter"/>
</plugin>

85
src/main/java/com/fr/plugin/tabledataservice/ConfigTableDataService.java

@ -0,0 +1,85 @@
/*
* Copyright (C), 2015-2019
* FileName: ConfigSln4062
* Author: xx
* Date: 2019/6/5 16:13
* Description: ConfigSln4062
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice;
import com.fanruan.api.util.StringKit;
import com.fr.config.*;
import com.fr.config.holder.Conf;
import com.fr.config.holder.factory.Holders;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.stable.StringUtils;
/**
* Function Description<br>
* ConfigSln4062
*
* @author xx
* @since 1.0.0
*/
@Visualization(category = "Plugin-tabledataservice_Group")
public class ConfigTableDataService extends DefaultConfiguration {
public static final String DEFAULT_APPKEY = StringUtils.EMPTY;
private static volatile ConfigTableDataService config = null;
@Identifier(value = "appKey", name = "Plugin-tabledataservice_Config_AppKey", description = "Plugin-tabledataservice_Config_AppKey_Description", status = Status.SHOW)
private final Conf<String> appKey = Holders.simple(DEFAULT_APPKEY);
//弹性平台sm2公钥
@Identifier(value = "iqbPublicKey", name = "Plugin-tabledataservice_Config_IqbPublicKey", description = "Plugin-tabledataservice_Config_IqbPublicKey_Description", status = Status.SHOW)
private final Conf<String> iqbPublicKey = Holders.simple(StringKit.EMPTY);
//可视化sm2私钥
@Identifier(value = "visualPrivateKey", name = "Plugin-tabledataservice_Config_VisualPrivateKey", description = "Plugin-tabledataservice_Config_VisualPrivateKey_Description", status = Status.SHOW)
private final Conf<String> visualPrivateKey = Holders.simple(StringKit.EMPTY);
// 可视化appId
@Identifier(value = "visualAppId", name = "Plugin-tabledataservice_Config_VisualAppId", description = "Plugin-tabledataservice_Config_VisualAppId_Description", status = Status.SHOW)
private final Conf<String> visualAppId = Holders.simple(StringKit.EMPTY);
@Focus(id = Constants.PLUGIN_ID, text = "Plugin-tabledataservice", source = Original.PLUGIN)
public static ConfigTableDataService getInstance() {
if (config == null) {
config = ConfigContext.getConfigInstance(ConfigTableDataService.class);
}
return config;
}
public String getAppKey() {
return appKey.get();
}
public void setAppKey(String appKey) {
this.appKey.set(appKey);
}
public String getIqbPublicKey() {
return iqbPublicKey.get();
}
public void setIqbPublicKey(String iqbPublicKey) {
this.iqbPublicKey.set(iqbPublicKey);
}
public String getVisualPrivateKey() {
return visualPrivateKey.get();
}
public void setVisualPrivateKey(String visualPrivateKey) {
this.visualPrivateKey.set(visualPrivateKey);
}
public String getVisualAppId() {
return visualAppId.get();
}
public void setVisualAppId(String visualAppId) {
this.visualAppId.set(visualAppId);
}
}

22
src/main/java/com/fr/plugin/tabledataservice/Constants.java

@ -0,0 +1,22 @@
/*
* Copyright (C), 2015-2019
* FileName: Constants
* Author: xx
* Date: 2019/5/16 16:09
* Description: Constants
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice;
/**
* Function Description<br>
* Constants
*
* @author xx
* @since 1.0.0
*/
public class Constants {
public static final String PLUGIN_ID = "com.fr.plugin.tabledataservice.haeo";
public static final String ICON_PATH = "/com/fr/plugin/tabledataservice/images/json16.png";
}

31
src/main/java/com/fr/plugin/tabledataservice/LocaleFinder.java

@ -0,0 +1,31 @@
/*
* Copyright (C), 2015-2019
* FileName: LocaleFinder
* Author: xx
* Date: 2019/6/5 16:20
* Description: LocaleFinder
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice;
import com.fr.stable.fun.impl.AbstractLocaleFinder;
/**
* Function Description<br>
* LocaleFinder
*
* @author xx
* @since 1.0.0
*/
public class LocaleFinder extends AbstractLocaleFinder {
@Override
public String find() {
return "com/fr/plugin/tabledataservice/locale/lang";
}
@Override
public int currentAPILevel() {
return CURRENT_LEVEL;
}
}

183
src/main/java/com/fr/plugin/tabledataservice/exporter/JSONExporter.java

@ -0,0 +1,183 @@
/*
* Copyright (C), 2015-2019
* FileName: JSONExporter
* Author: xx
* Date: 2019/8/26 16:39
* Description: JSONExporter
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice.exporter;
import com.fr.base.ResultFormula;
import com.fr.base.Style;
import com.fr.general.GeneralUtils;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.io.core.ExporterUtils;
import com.fr.io.exporter.AbstractAppExporter;
import com.fr.json.JSONArray;
import com.fr.json.JSONObject;
import com.fr.main.workbook.ResultWorkBook;
import com.fr.page.ClippedPageProvider;
import com.fr.page.PageSetProvider;
import com.fr.page.PaperSettingProvider;
import com.fr.page.ReportPageProvider;
import com.fr.plugin.tabledataservice.Constants;
import com.fr.plugin.tabledataservice.utils.FuncUtils;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.report.cell.CellElement;
import com.fr.report.cell.cellattr.CellGUIAttr;
import com.fr.report.core.ReportUtils;
import com.fr.report.elementcase.ElementGetter;
import com.fr.stable.ColumnRow;
import com.fr.stable.EncodeConstants;
import com.fr.stable.StringUtils;
import java.io.*;
import java.util.Iterator;
import java.util.List;
/**
* Function Description<br>
* 数据导出功能JSONExporter
* 参考TextExporter PageSetProvider CSVExporter ResultWorkBook WriteRWorkBook
*
* @author xx
* @since 1.0.0
*/
@EnableMetrics
public class JSONExporter extends AbstractAppExporter {
private JSONObject exporterObject;
private int startPageNo;
private int endPageNo;
@Override
@Focus(id= Constants.PLUGIN_ID, text = "Plugin-tabledataservice", source = Original.PLUGIN)
public void export(OutputStream outputStream, ResultWorkBook resultWorkBook) throws Exception {
if (resultWorkBook == null) {
throw new Exception("Report can not be null!");
}
JSONArray dataArray = this.export(resultWorkBook);
printAsJSON(outputStream, dataArray);
}
private JSONArray export(ResultWorkBook resultWorkBook) {
JSONArray reportsArray = JSONArray.create();
if (resultWorkBook == null) {
return reportsArray;
}
List<PaperSettingProvider> paperSettingList = ReportUtils.getPaperSettingListFromWorkBook(resultWorkBook);
PageSetProvider pageSetProvider = resultWorkBook.generateReportPageSet(paperSettingList).traverse4Export();
if (this.exporterObject != null) {
this.exporterObject.put("total_page_number", pageSetProvider.size());
}
if (startPageNo <= 0 || endPageNo <= 0) {
startPageNo = 1;
endPageNo = pageSetProvider.size();
}
reportsArray = this.exportPages(pageSetProvider);
return reportsArray;
}
@Override
public void export(OutputStream outputStream, PageSetProvider pageSetProvider) throws Exception {
JSONArray dataPagesArray = JSONArray.create();
for(int i = 0; i < pageSetProvider.size(); ++i) {
ReportPageProvider reportPageProvider = pageSetProvider.getPage(i);
ClippedPageProvider clippedPageProvider = ExporterUtils.support(reportPageProvider);
if (clippedPageProvider == null) {
break;
}
dataPagesArray.put(this.exportReport((ElementGetter)clippedPageProvider, 0, ((ElementGetter)clippedPageProvider).getRowCount()));
}
printAsJSON(outputStream, dataPagesArray);
}
public JSONArray exportPages(PageSetProvider pageSetProvider) {
JSONArray pagesArray = JSONArray.create();
for(int i = (startPageNo - 1); i <= (endPageNo -1) && i < pageSetProvider.size(); ++i) {
ReportPageProvider reportPageProvider = pageSetProvider.getPage(i);
ClippedPageProvider clippedPageProvider = ExporterUtils.support(reportPageProvider);
if (clippedPageProvider == null) {
break;
}
pagesArray.put(this.exportReport((ElementGetter)clippedPageProvider, 0, ((ElementGetter)clippedPageProvider).getRowCount()));
}
return pagesArray;
}
public JSONObject exportReport(ElementGetter reportCase, int start, int end) {
JSONObject pageJSON = JSONObject.create();
for(int row = start; row < end; ++row) {
Iterator iterator = reportCase.getRow(row);
String cellText;
while(iterator.hasNext()) {
CellElement cell = (CellElement)iterator.next();
Object value = this.getCellValue(cell);
Style style = cell.getStyle();
if (style != null){
cellText = Style.valueToText(value, style.getFormat());
}else{
cellText = GeneralUtils.objectToString(value);
}
ColumnRow columnRow = ColumnRow.valueOf(cell.getColumn(),cell.getRow());
if (reportCase.getColumnWidth(cell.getColumn()).less_than_or_equal_zero()
|| reportCase.getRowHeight(cell.getRow()).less_than_or_equal_zero()){
continue;
}
pageJSON.put(columnRow.toString(), cellText);
}
}
return pageJSON;
}
private Object getCellValue(CellElement cell) {
if(cell == null){
return null;
}
Object value = cell.getShowValue();
if (value instanceof ResultFormula){
value = ((ResultFormula) value).getResult();
}
CellGUIAttr gui = cell.getCellGUIAttr();
if (gui != null && !gui.isPrintContent()) {
value = StringUtils.EMPTY;
}
return value == null ? StringUtils.EMPTY : value;
}
/**
* JSON数据输出到前端
* @param outPutStream
* @param data
* @throws UnsupportedEncodingException
*/
private void printAsJSON(OutputStream outPutStream, Object data) throws UnsupportedEncodingException {
PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outPutStream, EncodeConstants.ENCODING_UTF_8)));
if (this.exporterObject != null) {
JSONObject result = this.exporterObject;
FuncUtils.encryptData(String.valueOf(data), result);
writer.print(result);
} else {
writer.print(data.toString());
}
writer.flush();
writer.close();
}
/**
* 设置导出参数
*
* @param params
*/
public void setExporterObject(JSONObject params) {
this.startPageNo = params.getInt("start_page");
this.endPageNo = params.getInt("end_page");
JSONObject exporter = JSONObject.create();
exporter.put("err_code", 0).put("err_msg", "")
.put("start_page", this.startPageNo)
.put("end_page", this.endPageNo);
this.exporterObject = exporter;
}
}

140
src/main/java/com/fr/plugin/tabledataservice/request/ReportDataHandler.java

@ -0,0 +1,140 @@
/*
* Copyright (C), 2015-2019
* FileName: ReportDataHandler
* Author: xx
* Date: 2019/8/22 8:34
* Description: ReportDataHandler
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice.request;
import com.fanruan.api.i18n.I18nKit;
import com.fanruan.api.log.LogKit;
import com.fanruan.api.report.ActorKit;
import com.fr.base.Parameter;
import com.fr.decision.fun.impl.BaseHttpHandler;
import com.fr.general.ComparatorUtils;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.io.TemplateWorkBookIO;
import com.fr.json.JSONArray;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.main.TemplateWorkBook;
import com.fr.main.workbook.ResultWorkBook;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.tabledataservice.ConfigTableDataService;
import com.fr.plugin.tabledataservice.Constants;
import com.fr.plugin.tabledataservice.exporter.JSONExporter;
import com.fr.plugin.tabledataservice.utils.FuncUtils;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.stable.ActorConstants;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.third.springframework.web.bind.annotation.RequestMethod;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
/**
* Function Description<br>
* ReportDataHandler
*
* @author xx
* @since 1.0.0
*/
@EnableMetrics
public class ReportDataHandler extends BaseHttpHandler {
public static final String API_REPORT = "/api/report";
@Override
public RequestMethod getMethod() {
return RequestMethod.POST;
}
@Override
public String getPath() {
return API_REPORT;
}
@Override
public boolean isPublic() {
return true;
}
@Override
@Focus(id = Constants.PLUGIN_ID, text = "Plugin-tabledataservice", source = Original.PLUGIN)
public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception {
if (!PluginContexts.currentContext().isAvailable()) {
LogKit.error(I18nKit.getLocText("Plugin-tabledataservice_Licence_Expired"));
FuncUtils.printErrorJSON(res, 21);
return;
}
JSONObject params = FuncUtils.getParams(req);
FineLoggerFactory.getLogger().info("tabledataservice-ReportDataHandler:handle-params, {}", params.toString());
if (isErrorParams(res, params)) {
return;
}
TemplateWorkBook workBook = TemplateWorkBookIO.readTemplateWorkBook(params.getString("report_path"));
if (workBook == null) {
FuncUtils.printErrorJSON(res, 14);
return;
}
JSONArray paramsJSON = params.has("parameters") ? params.getJSONArray("parameters") : null;
ResultWorkBook resultWorkBook = workBook.execute(getParameters(paramsJSON), ActorKit.getActor(ActorConstants.TYPE_PAGE));
JSONExporter jsonExporter = new JSONExporter();
jsonExporter.setExporterObject(params);
jsonExporter.export(res.getOutputStream(), resultWorkBook);
}
private HashMap<String, Object> getParameters(JSONArray param) {
if (param == null) {
return null;
}
ParameterProvider[] parameters = new ParameterProvider[param.size()];
for (int i = 0; i < param.size(); i++) {
parameters[i] = Parameter.getParameterFromJson(param.getJSONObject(i));
}
HashMap<String, Object> parametersMap = new HashMap<String, Object>();
addPara2Map(parametersMap, parameters);
return parametersMap;
}
private void addPara2Map(Map<String, Object> parametersMap, ParameterProvider[] parameters) {
if (parameters == null) {
return;
}
for (ParameterProvider parameter : parameters) {
if (parameter == null || parameter.getName() == null) {
return;
}
parametersMap.put(parameter.getName().toUpperCase(), parameter.getValue());
}
}
private boolean isErrorParams(HttpServletResponse res, JSONObject params) throws Exception {
if (!params.has("report_path") || StringUtils.isEmpty(params.getString("report_path"))) {
FuncUtils.printErrorJSON(res, 10);
return true;
}
if (!params.has("start_page") || ComparatorUtils.equals(params.getInt("start_page"), 0)) {
FuncUtils.printErrorJSON(res, 16);
return true;
}
if (!params.has("end_page") || ComparatorUtils.equals(params.getInt("end_page"), 0)) {
FuncUtils.printErrorJSON(res, 17);
return true;
}
String appKey = ConfigTableDataService.getInstance().getAppKey();
if (StringUtils.isNotEmpty(appKey)
&& !FuncUtils.validateMD5(appKey, params)) {
FuncUtils.printErrorJSON(res, 15);
return true;
}
return false;
}
}

46
src/main/java/com/fr/plugin/tabledataservice/request/RequestHandlerBridge.java

@ -0,0 +1,46 @@
/*
* Copyright (C), 2015-2019
* FileName: RequestHandlerBridge
* Author: xx
* Date: 2019/8/17 22:20
* Description: RequestHandlerBridge
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice.request;
import com.fanruan.api.i18n.I18nKit;
import com.fanruan.api.log.LogKit;
import com.fr.decision.fun.impl.AbstractHttpHandlerProvider;
import com.fr.decision.fun.impl.BaseHttpHandler;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.tabledataservice.ConfigTableDataService;
import com.fr.plugin.tabledataservice.Constants;
import com.fr.stable.fun.Authorize;
/**
* Function Description<br>
* RequestHandlerBridge
*
* @author xx
* @since 1.0.0
*/
@Authorize(callSignKey = Constants.PLUGIN_ID)
public class RequestHandlerBridge extends AbstractHttpHandlerProvider {
public RequestHandlerBridge() {
ConfigTableDataService.getInstance();
}
@Override
public BaseHttpHandler[] registerHandlers() {
if (PluginContexts.currentContext().isAvailable()) {
return new BaseHttpHandler[]{
new TableDataHandler(),
new ReportDataHandler()
};
} else {
LogKit.error(I18nKit.getLocText("Plugin-tabledataservice_Licence_Expired"));
return new BaseHttpHandler[]{};
}
}
}

185
src/main/java/com/fr/plugin/tabledataservice/request/TableDataHandler.java

@ -0,0 +1,185 @@
/*
* Copyright (C), 2015-2019
* FileName: TableDataHandler
* Author: xx
* Date: 2019/8/17 22:28
* Description: PublicHttpHandler
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice.request;
import com.fanruan.api.i18n.I18nKit;
import com.fanruan.api.log.LogKit;
import com.fr.base.Parameter;
import com.fr.base.TableData;
import com.fr.data.impl.ConditionTableData;
import com.fr.decision.fun.impl.BaseHttpHandler;
import com.fr.general.ComparatorUtils;
import com.fr.general.data.DataModel;
import com.fr.intelli.record.Focus;
import com.fr.intelli.record.Original;
import com.fr.io.TemplateWorkBookIO;
import com.fr.json.JSONArray;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.main.TemplateWorkBook;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.tabledataservice.ConfigTableDataService;
import com.fr.plugin.tabledataservice.Constants;
import com.fr.plugin.tabledataservice.utils.FuncUtils;
import com.fr.record.analyzer.EnableMetrics;
import com.fr.script.Calculator;
import com.fr.stable.StringUtils;
import com.fr.third.springframework.web.bind.annotation.RequestMethod;
import com.fr.web.utils.WebUtils;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Function Description<br>
* TableDataHandler
*
* @author xx
* @since 1.0.0
*/
@EnableMetrics
public class TableDataHandler extends BaseHttpHandler {
public static final int TOTAL_PAGE_NUMBER = 1;
public static final int START_ROW = 0;
@Override
public RequestMethod getMethod() {
return RequestMethod.POST;
}
@Override
public String getPath() {
return "/api/data";
}
@Override
public boolean isPublic() {
return true;
}
@Override
@Focus(id = Constants.PLUGIN_ID, text = "Plugin-tabledataservice", source = Original.PLUGIN)
public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception {
if (!PluginContexts.currentContext().isAvailable()) {
LogKit.error(I18nKit.getLocText("Plugin-tabledataservice_Licence_Expired"));
FuncUtils.printErrorJSON(res, 21);
return;
}
JSONObject params = FuncUtils.getParams(req);
FineLoggerFactory.getLogger().info("tabledataservice:handle-params, {}", params.toString());
if (isErrorParams(res, params)) {
return;
}
TemplateWorkBook workBook = TemplateWorkBookIO.readTemplateWorkBook(params.getString("report_path"));
if (workBook == null) {
FuncUtils.printErrorJSON(res, 14);
return;
}
TableData tableData = workBook.getTableData(params.getString("datasource_name"));
if (tableData == null) {
FuncUtils.printErrorJSON(res, 20);
return;
}
if (params.has("parameters")) {
if (tableData instanceof ConditionTableData) {
((ConditionTableData) tableData).setDefineParameters(getParameters(params.getJSONArray("parameters")));
} else {
tableData.setParameters(getParameters(params.getJSONArray("parameters")));
}
}
JSONObject resultJSON = tableDataToJSON(tableData, params.getInt("page_number"), params.getInt("page_size"));
WebUtils.printAsJSON(res, resultJSON);
}
private Parameter[] getParameters(JSONArray param) {
if (param == null) {
return null;
}
Parameter[] parameters = new Parameter[param.size()];
for (int i = 0; i < param.size(); i++) {
parameters[i] = Parameter.getParameterFromJson(param.getJSONObject(i));
}
return parameters;
}
private boolean isErrorParams(HttpServletResponse res, JSONObject params) throws Exception {
if (!params.has("report_path") || StringUtils.isEmpty(params.getString("report_path"))) {
FuncUtils.printErrorJSON(res, 10);
return true;
}
if (!params.has("datasource_name") || StringUtils.isEmpty(params.getString("datasource_name"))) {
FuncUtils.printErrorJSON(res, 11);
return true;
}
if (!params.has("page_number") || ComparatorUtils.equals(params.getInt("page_number"), 0)) {
FuncUtils.printErrorJSON(res, 12);
return true;
}
if (!params.has("page_size") || ComparatorUtils.equals(params.getInt("page_size"), 0)) {
FuncUtils.printErrorJSON(res, 13);
return true;
}
String appKey = ConfigTableDataService.getInstance().getAppKey();
if (StringUtils.isNotEmpty(appKey)
&& !FuncUtils.validateMD5(appKey, params)) {
FuncUtils.printErrorJSON(res, 15);
return true;
}
return false;
}
/**
* tableData转为JSON
* 参考函数 ReportUtils.tableDataToFlexgridObject4WebPreview()修改
*
* @param tableData
* @param pageNumber
* @param pageSize
* @return
* @throws Exception
*/
private JSONObject tableDataToJSON(TableData tableData, int pageNumber, int pageSize) throws Exception {
JSONObject resultJSON = JSONObject.create();
DataModel dataModel = null;
try {
dataModel = tableData.createDataModel(Calculator.createCalculator());
int rowCount = dataModel.getRowCount();
int totalPageNumber = TOTAL_PAGE_NUMBER;
int startRow = START_ROW;
int endRow = rowCount - 1;
if (pageNumber > 0 && pageSize > 0) {
totalPageNumber = (rowCount + pageSize - 1) / pageSize;
startRow = (pageNumber - 1) * pageSize;
endRow = (pageNumber * pageSize) - 1;
}
resultJSON.put("err_code", 0).put("err_msg", "")
.put("total_page_number", totalPageNumber)
.put("page_number", pageNumber)
.put("page_size", pageSize);
JSONArray data = JSONArray.create();
for (int row = startRow; row <= endRow && row < rowCount; row++) {
JSONObject rowObject = JSONObject.create();
for (int col = 0; col < dataModel.getColumnCount(); col++) {
rowObject.put(dataModel.getColumnName(col), dataModel.getValueAt(row, col));
}
data.put(rowObject);
}
FuncUtils.encryptData(data.encode(), resultJSON);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} finally {
if (dataModel != null) {
dataModel.release();
}
}
return resultJSON;
}
}

42
src/main/java/com/fr/plugin/tabledataservice/request/URLAliasBridge.java

@ -0,0 +1,42 @@
/*
* Copyright (C), 2015-2019
* FileName: URLAliasBridge
* Author: xx
* Date: 2019/8/17 22:21
* Description: URLAliasBridge
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice.request;
import com.fanruan.api.i18n.I18nKit;
import com.fanruan.api.log.LogKit;
import com.fr.decision.fun.impl.AbstractURLAliasProvider;
import com.fr.decision.webservice.url.alias.URLAlias;
import com.fr.decision.webservice.url.alias.URLAliasFactory;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.tabledataservice.Constants;
import com.fr.stable.fun.Authorize;
/**
* Function Description<br>
* URLAliasBridge
*
* @author xx
* @since 1.0.0
*/
@Authorize(callSignKey = Constants.PLUGIN_ID)
public class URLAliasBridge extends AbstractURLAliasProvider {
@Override
public URLAlias[] registerAlias() {
if (PluginContexts.currentContext().isAvailable()) {
return new URLAlias[]{
URLAliasFactory.createPluginAlias("/api/data", "/api/data", true),
URLAliasFactory.createPluginAlias("/api/report", "/api/report", true),
};
} else {
LogKit.error(I18nKit.getLocText("Plugin-tabledataservice_Licence_Expired"));
return new URLAlias[]{};
}
}
}

32
src/main/java/com/fr/plugin/tabledataservice/toolbar/JSONExport.java

@ -0,0 +1,32 @@
/*
* Copyright (C), 2015-2019
* FileName: JSONExport
* Author: xx
* Date: 2019/8/29 16:52
* Description: JSONExport
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice.toolbar;
import com.fr.report.fun.impl.AbstractExportOperateProvider;
import com.fr.web.core.reserve.Operate;
/**
* Function Description<br>
* JSONExport
*
* @author xx
* @since 1.0.0
*/
public class JSONExport extends AbstractExportOperateProvider {
@Override
public Operate operate() {
return new JSONExportOperate();
}
@Override
public String markType() {
return "json";
}
}

53
src/main/java/com/fr/plugin/tabledataservice/toolbar/JSONExportOperate.java

@ -0,0 +1,53 @@
/*
* Copyright (C), 2015-2019
* FileName: JSONExportOperate
* Author: xx
* Date: 2019/8/29 16:24
* Description: JSONExportOperate
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice.toolbar;
import com.fanruan.api.i18n.I18nKit;
import com.fanruan.api.log.LogKit;
import com.fr.general.DeclareRecordType;
import com.fr.io.collection.ExportCollection;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.tabledataservice.exporter.JSONExporter;
import com.fr.web.core.ReportSessionIDInfor;
import com.fr.web.core.reserve.DefaultOperate;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Function Description<br>
* JSONExportOperate
*
* @author xx
* @since 1.0.0
*/
public class JSONExportOperate extends DefaultOperate {
@Override
public void setContent(HttpServletRequest req, HttpServletResponse res, String fileName, boolean isEmbed) {
if (!PluginContexts.currentContext().isAvailable()) {
LogKit.error(I18nKit.getLocText("Plugin-tabledataservice_Licence_Expired"));
return;
}
res.setContentType("application/octet-stream");
res.setHeader("extension", "json");
res.setHeader("Content-disposition", "attachment; filename=" + fileName + ".json");
}
@Override
public ExportCollection createCollection(HttpServletRequest req, HttpServletResponse res, ReportSessionIDInfor sessionIDInfor, String fileName) {
if (!PluginContexts.currentContext().isAvailable()) {
return ExportCollection.create();
}
ExportCollection collection = ExportCollection.create();
collection.setExporter(new JSONExporter());
collection.setRecordType(DeclareRecordType.EXPORT_TYPE_CSV);
return collection;
}
}

39
src/main/java/com/fr/plugin/tabledataservice/toolbar/JSONExportToolbarUI.java

@ -0,0 +1,39 @@
/*
* Copyright (C), 2015-2019
* FileName: JSONExportToolbarUI
* Author: xx
* Date: 2019/8/29 16:15
* Description: JSONExportToolbarUI
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice.toolbar;
import com.fr.design.fun.impl.AbstractToolbarItem;
import com.fr.form.ui.Widget;
import com.fr.locale.InterProviderFactory;
import com.fr.plugin.tabledataservice.Constants;
/**
* Function Description<br>
* JSONExportToolbarUI
*
* @author xx
* @since 1.0.0
*/
public class JSONExportToolbarUI extends AbstractToolbarItem {
@Override
public Class<? extends Widget> classForWidget() {
return JSONExtensionButton.class;
}
@Override
public String iconPathForWidget() {
return Constants.ICON_PATH;
}
@Override
public String nameForWidget() {
return InterProviderFactory.getProvider().getLocText("Plugin-tabledataservice_Export");
}
}

74
src/main/java/com/fr/plugin/tabledataservice/toolbar/JSONExtensionButton.java

@ -0,0 +1,74 @@
/*
* Copyright (C), 2015-2019
* FileName: JSONExtensionButton
* Author: xx
* Date: 2019/8/28 17:16
* Description: JSONExtensionButton
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice.toolbar;
import com.fr.form.ui.WebContentUtils;
import com.fr.form.ui.Widget;
import com.fr.js.JavaScriptImpl;
import com.fr.locale.InterProviderFactory;
import com.fr.plugin.tabledataservice.utils.FuncUtils;
import com.fr.report.fun.impl.AbstractExtensionButton;
import com.fr.stable.web.Repository;
/**
* Function Description<br>
* JSONExtensionButton
*
* @author xx
* @since 1.0.0
*/
public class JSONExtensionButton extends AbstractExtensionButton {
public JSONExtensionButton() {
super(InterProviderFactory.getProvider().getLocText("Plugin-tabledataservice_Export"), FuncUtils.loadIcon());
}
public JSONExtensionButton(String text) {
super(text);
}
public JSONExtensionButton(String text, String iconName) {
super(text, iconName);
}
@Override
public Class<? extends Widget> classForDirectoryButton() {
return this.getClass();
}
@Override
public String getParentDirectory() {
return null;
}
@Override
public String getType() {
return "JSONExport.class";
}
@Override
public String getRelatedCheckBoxTitle() {
return null;
}
@Override
public boolean isSelected() {
return false;
}
@Override
public void setSelected(boolean b) {
}
@Override
protected JavaScriptImpl clickAction(Repository repository) {
return new JavaScriptImpl(WebContentUtils.getContentPanel(repository) + ".exportReportToJSON()");
}
}

178
src/main/java/com/fr/plugin/tabledataservice/utils/FuncUtils.java

@ -0,0 +1,178 @@
/*
* Copyright (C), 2015-2019
* FileName: FuncUtils
* Author: xx
* Date: 2019/8/22 15:05
* Description: FuncUtils
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice.utils;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.Mode;
import cn.hutool.crypto.Padding;
import cn.hutool.crypto.asymmetric.KeyType;
import cn.hutool.crypto.asymmetric.SM2;
import cn.hutool.crypto.symmetric.SM4;
import com.fanruan.api.json.JSONKit;
import com.fr.base.Icon;
import com.fr.base.IconManager;
import com.fr.data.NetworkHelper;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.io.utils.MD5Calculator;
import com.fr.json.JSONObject;
import com.fr.locale.InterProviderFactory;
import com.fr.plugin.tabledataservice.ConfigTableDataService;
import com.fr.web.utils.WebUtils;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.security.Security;
import java.util.*;
import static com.fr.plugin.tabledataservice.Constants.ICON_PATH;
/**
* Function Description<br>
* FuncUtils
*
* @author xx
* @since 1.0.0
*/
public class FuncUtils {
static {
//如果是PKCS7Padding填充方式,则必须加上下面这行
Security.addProvider(new BouncyCastleProvider());
}
/**
* 数据加密和签名
*
* @param bizData 业务数据
* @param result
* @return
*/
public static void encryptData(String bizData, JSONObject result) {
//弹性平台sm2公钥
String iqbPublicKey = ConfigTableDataService.getInstance().getIqbPublicKey();
//可视化sm2私钥
String visualPrivateKey = ConfigTableDataService.getInstance().getVisualPrivateKey();
//可视化appId
String appId = ConfigTableDataService.getInstance().getVisualAppId();
String aesPw = RandomUtil.randomString(16);//明文sm4key
String aesIv = RandomUtil.randomString(16); //sm4iv
//对请求参数 sm4加密
String encryptData = sm4Encrypt(bizData, aesPw, aesIv);
//对明文aesPw sm2加密
String key = sm2Encrypt(aesPw, iqbPublicKey);
//组装请求参数
HashMap<String, Object> encryptReqMap = new HashMap<>();
encryptReqMap.put("appId", appId);
encryptReqMap.put("time", DateUtil.format(new Date(), "yyyyMMddHHmmss"));
encryptReqMap.put("data", encryptData);
encryptReqMap.put("key", key);
encryptReqMap.put("iv", aesIv);
encryptReqMap.put("requestNo", IdUtil.getSnowflake(2, 1).nextIdStr() + IdUtil.getSnowflake(2, 1).nextIdStr());
//获取待签名请求参数并用可视化私钥签名
String waitSign = getSignContent(encryptReqMap);
String signature = sign(waitSign, visualPrivateKey);
//签名附加到请求参数
result.put("appId", encryptReqMap.get("appId"));
result.put("time", encryptReqMap.get("time"));
result.put("data", encryptReqMap.get("data"));
result.put("key", encryptReqMap.get("key"));
result.put("iv", encryptReqMap.get("iv"));
result.put("requestNo", encryptReqMap.get("requestNo"));
result.put("sign", signature);
}
//SM2非对称加密
private static String sm2Encrypt(String data, String publicKey) {
return new SM2(null, publicKey).encryptBase64(data, KeyType.PublicKey);
}
//SM4对称加密
private static String sm4Encrypt(String bizData, String key, String iv) {
return cn.hutool.core.codec.Base64.encode(new SM4(Mode.CBC, Padding.PKCS5Padding, key.getBytes(), iv.getBytes()).encrypt(bizData));
}
//获取待签名数据
private static String getSignContent(HashMap<String, Object> paramMap) {
paramMap.remove("sign");
Map<String, Object> stringObjectMap = sortMapByKey(paramMap);
return JSONKit.create(stringObjectMap).encode();
}
/**
* 根据map的key进行字典升序排序
*
* @param map
* @return map
*/
private static Map<String, Object> sortMapByKey(Map<String, Object> map) {
Map<String, Object> treemap = new TreeMap<>(map);
List<Map.Entry<String, Object>> list = new ArrayList<>(treemap.entrySet());
list.sort(Map.Entry.comparingByKey());
return treemap;
}
// 签名
private static String sign(String data, String privateKey) {
return cn.hutool.core.codec.Base64.encode(new SM2(privateKey, null).sign(data.getBytes(StandardCharsets.UTF_8)));
}
/**
* MD5验证key报表路径时间戳计算
*
* @param appKey
* @param params
* @return
*/
public static Boolean validateMD5(String appKey, JSONObject params) {
StringBuffer str = new StringBuffer();
str.append(appKey);
str.append(params.getString("report_path"));
str.append(params.getString("timestamp"));
String token = MD5Calculator.calculateMD5(str.toString().getBytes());
return ComparatorUtils.equals(token, params.getString("sign"));
}
public static void printErrorJSON(HttpServletResponse res, int code) throws Exception {
JSONObject errorJSON = JSONObject.create();
errorJSON.put("err_code", code)
.put("err_msg", InterProviderFactory.getProvider().getLocText("Plugin-tabledataservice_Error_" + code));
WebUtils.printAsJSON(res, errorJSON);
}
public static JSONObject getParams(HttpServletRequest req) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(NetworkHelper.getRequestInputStream(req), "utf-8"));
StringBuilder sb = new StringBuilder();
String temp;
while ((temp = br.readLine()) != null) {
sb.append(temp);
}
br.close();
return new JSONObject(sb.toString());
}
public static String loadIcon() {
Icon icon = new Icon("json", IOUtils.readImage(ICON_PATH));
IconManager.getIconManager().addIcon(icon, true);
return icon.getName();
}
}

39
src/main/java/com/fr/plugin/tabledataservice/web/JavaScriptFile.java

@ -0,0 +1,39 @@
/*
* Copyright (C), 2015-2019
* FileName: JavaScriptFile
* Author: xx
* Date: 2019/8/29 16:33
* Description: JavaScriptFile
* History:
* <author> <time> <version> <desc>
*/
package com.fr.plugin.tabledataservice.web;
import com.fanruan.api.i18n.I18nKit;
import com.fanruan.api.log.LogKit;
import com.fr.plugin.context.PluginContexts;
import com.fr.plugin.tabledataservice.Constants;
import com.fr.stable.fun.Authorize;
import com.fr.stable.fun.impl.AbstractJavaScriptFileHandler;
/**
* Function Description<br>
* JavaScriptFile
*
* @author xx
* @since 1.0.0
*/
@Authorize(callSignKey = Constants.PLUGIN_ID)
public class JavaScriptFile extends AbstractJavaScriptFileHandler {
@Override
public String[] pathsForFiles() {
if (PluginContexts.currentContext().isAvailable()) {
return new String[]{
"/com/fr/plugin/tabledataservice/web/JSONExporter.js"
};
} else {
LogKit.error(I18nKit.getLocText("Plugin-tabledataservice_Licence_Expired"));
return new String[]{};
}
}
}

BIN
src/main/resources/com/fr/plugin/tabledataservice/images/json16.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

22
src/main/resources/com/fr/plugin/tabledataservice/locale/lang.properties

@ -0,0 +1,22 @@
Plugin-tabledataservice=JSON Service API
Plugin-tabledataservice_Group=Plugin JSON Service API
Plugin-tabledataservice_Error_10=report_path parameter error
Plugin-tabledataservice_Error_11=datasource_name parameter error
Plugin-tabledataservice_Error_12=page_number parameter error
Plugin-tabledataservice_Error_13=page_size parameter error
Plugin-tabledataservice_Error_14=template file not exist
Plugin-tabledataservice_Error_15=signature error
Plugin-tabledataservice_Error_16=start_page parameter error
Plugin-tabledataservice_Error_17=end_page parameter error
Plugin-tabledataservice_Error_20=dataset is empty
Plugin-tabledataservice_Error_21=TableDataService Plugin Licence Expired
Plugin-tabledataservice_Config_AppKey=FR App Key
Plugin-tabledataservice_Config_AppKey_Description=App Key
Plugin-tabledataservice_Export=JSON
Plugin-tabledataservice_Licence_Expired=JSON Service API Plugin Licence Expired
Plugin-tabledataservice_Config_IqbPublicKey=Iqb Public Key
Plugin-tabledataservice_Config_IqbPublicKey_Description=Iqb Public Key
Plugin-tabledataservice_Config_VisualPrivateKey=Visual Private Key
Plugin-tabledataservice_Config_VisualPrivateKey_Description=Visual Private Key
Plugin-tabledataservice_Config_VisualAppId=Visual App Id
Plugin-tabledataservice_Config_VisualAppId_Description=Visual App Id

22
src/main/resources/com/fr/plugin/tabledataservice/locale/lang_zh_CN.properties

@ -0,0 +1,22 @@
Plugin-tabledataservice=JSON\u670D\u52A1\u63A5\u53E3
Plugin-tabledataservice_Group=JSON\u670D\u52A1\u63A5\u53E3\u63D2\u4EF6
Plugin-tabledataservice_Error_10=report_path\u53C2\u6570\u503C\u4E0D\u6B63\u786E
Plugin-tabledataservice_Error_11=datasource_name\u53C2\u6570\u503C\u4E0D\u6B63\u786E
Plugin-tabledataservice_Error_12=page_number\u53C2\u6570\u503C\u4E0D\u6B63\u786E
Plugin-tabledataservice_Error_13=page_size\u53C2\u6570\u503C\u4E0D\u6B63\u786E
Plugin-tabledataservice_Error_14=\u62A5\u8868\u6A21\u677F\u6587\u4EF6\u4E0D\u5B58\u5728
Plugin-tabledataservice_Error_15=\u5B89\u5168\u7B7E\u540D\u4E0D\u6B63\u786E
Plugin-tabledataservice_Error_16=start_page\u53C2\u6570\u503C\u4E0D\u6B63\u786E
Plugin-tabledataservice_Error_17=end_page\u53C2\u6570\u503C\u4E0D\u6B63\u786E
Plugin-tabledataservice_Error_20=\u62A5\u8868\u6570\u636E\u96C6\u4E3A\u7A7A
Plugin-tabledataservice_Error_21=JSON\u670D\u52A1\u63A5\u53E3\u63D2\u4EF6\u8BB8\u53EF\u8FC7\u671F
Plugin-tabledataservice_Config_AppKey=\u5E06\u8F6F\u5E73\u53F0\u79D8\u94A5
Plugin-tabledataservice_Config_AppKey_Description=\u79D8\u94A5
Plugin-tabledataservice_Export=JSON\u5BFC\u51FA
Plugin-tabledataservice_Licence_Expired=JSON\u670D\u52A1\u63A5\u53E3\u63D2\u4EF6\u8BB8\u53EF\u8FC7\u671F
Plugin-tabledataservice_Config_IqbPublicKey=\u5F39\u6027\u5E73\u53F0sm2\u516C\u94A5
Plugin-tabledataservice_Config_IqbPublicKey_Description=\u5F39\u6027\u5E73\u53F0sm2\u516C\u94A5
Plugin-tabledataservice_Config_VisualPrivateKey=\u53EF\u89C6\u5316sm2\u79C1\u94A5
Plugin-tabledataservice_Config_VisualPrivateKey_Description=\u53EF\u89C6\u5316sm2\u79C1\u94A5
Plugin-tabledataservice_Config_VisualAppId=\u53EF\u89C6\u5316appId
Plugin-tabledataservice_Config_VisualAppId_Description=\u53EF\u89C6\u5316appId

35
src/main/resources/com/fr/plugin/tabledataservice/web/JSONExporter.js

@ -0,0 +1,35 @@
(function($){
$.extend(FR.WritePane.prototype, {
exportReportToJSON : function() {
if (this.fireEvent("beforejson") === false) {
return;
}
var self = this;
this.saveReport(function () {
window.location = FR.servletURL + "?op=export&sessionID=" + self.currentSessionID + "&format=json";
FR.progressBar(self.currentSessionID,"json");
self.fireEvent("afterjson");
});
}
});
$.extend(FR.PagePane.prototype, {
exportReportToJSON : function() {
if (this.fireEvent("beforejson") === false) {
return;
}
window.location = FR.servletURL + "?op=export&sessionID=" + this.currentSessionID + "&format=json";
FR.progressBar(this.currentSessionID, "json");
this.fireEvent("afterjson");
}
});
$.extend(FR.ViewPane.prototype, {
exportReportToJSON: function () {
if (this.fireEvent("beforejson") === false) {
return;
}
window.location = FR.servletURL + "?op=export&sessionID=" + this.currentSessionID + "&format=json";
FR.progressBar(this.currentSessionID, "json");
this.fireEvent("afterjson");
}
});
})(jQuery);
Loading…
Cancel
Save