diff --git a/JSD-8210 -需求确认书V1.1.docx b/JSD-8210 -需求确认书V1.1.docx new file mode 100644 index 0000000..56060e3 Binary files /dev/null and b/JSD-8210 -需求确认书V1.1.docx differ diff --git a/README.md b/README.md index 57fa753..f2914a1 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # open-JSD-8210 -JSD-8210开源任务材料 \ No newline at end of file +JSD-8210 开源任务材料\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 \ No newline at end of file diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..a135ecd --- /dev/null +++ b/plugin.xml @@ -0,0 +1,26 @@ + + com.fr.plugin.xxx.report + + yes + 1.3.4 + 10.0~10.0 + fr.open + 2018-04-01 + + + com.fr.plugin.xxx.report + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/xxx/report/Alias.java b/src/main/java/com/fr/plugin/xxx/report/Alias.java new file mode 100644 index 0000000..6c6cadb --- /dev/null +++ b/src/main/java/com/fr/plugin/xxx/report/Alias.java @@ -0,0 +1,19 @@ +package com.fr.plugin.xxx.report; + +import com.fr.decision.fun.impl.AbstractURLAliasProvider; +import com.fr.decision.webservice.url.alias.URLAlias; +import com.fr.decision.webservice.url.alias.URLAliasFactory; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-17 + **/ +public class Alias extends AbstractURLAliasProvider { + @Override + public URLAlias[] registerAlias() { + return new URLAlias[]{ + URLAliasFactory.createPluginAlias( Server.URI, Server.URI, true), + }; + } +} diff --git a/src/main/java/com/fr/plugin/xxx/report/CSSImporter.java b/src/main/java/com/fr/plugin/xxx/report/CSSImporter.java new file mode 100644 index 0000000..9534327 --- /dev/null +++ b/src/main/java/com/fr/plugin/xxx/report/CSSImporter.java @@ -0,0 +1,17 @@ +package com.fr.plugin.xxx.report; + +import com.fr.stable.fun.impl.AbstractCssFileHandler; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-03 + **/ +public class CSSImporter extends AbstractCssFileHandler { + @Override + public String[] pathsForFiles() { + return new String[]{ + "/com/fr/plugin/deqing/report/main.css" + }; + } +} diff --git a/src/main/java/com/fr/plugin/xxx/report/Init.java b/src/main/java/com/fr/plugin/xxx/report/Init.java new file mode 100644 index 0000000..eccc7cf --- /dev/null +++ b/src/main/java/com/fr/plugin/xxx/report/Init.java @@ -0,0 +1,23 @@ +package com.fr.plugin.xxx.report; + +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-01 + **/ +public class Init extends AbstractPluginLifecycleMonitor { + + public Init(){ + } + + @Override + public void afterRun(PluginContext pluginContext) { + } + + @Override + public void beforeStop(PluginContext pluginContext) { + } +} diff --git a/src/main/java/com/fr/plugin/xxx/report/JSImporter.java b/src/main/java/com/fr/plugin/xxx/report/JSImporter.java new file mode 100644 index 0000000..f451139 --- /dev/null +++ b/src/main/java/com/fr/plugin/xxx/report/JSImporter.java @@ -0,0 +1,22 @@ +package com.fr.plugin.xxx.report; + +import com.fr.plugin.transform.ExecuteFunctionRecord; +import com.fr.plugin.transform.FunctionRecorder; +import com.fr.stable.fun.impl.AbstractJavaScriptFileHandler; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-01 + **/ +@FunctionRecorder +public class JSImporter extends AbstractJavaScriptFileHandler { + + @Override + @ExecuteFunctionRecord + public String[] pathsForFiles() { + return new String[]{ + "/com/fr/plugin/xxx/report/main.js" + }; + } +} diff --git a/src/main/java/com/fr/plugin/xxx/report/Server.java b/src/main/java/com/fr/plugin/xxx/report/Server.java new file mode 100644 index 0000000..7654c7a --- /dev/null +++ b/src/main/java/com/fr/plugin/xxx/report/Server.java @@ -0,0 +1,71 @@ +package com.fr.plugin.xxx.report; + +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.main.TemplateWorkBook; +import com.fr.plugin.xxx.report.core.DsUtils; +import com.fr.script.Calculator; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.web.core.ReportSessionIDInfor; +import com.fr.web.core.SessionPoolManager; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-17 + **/ +public class Server extends BaseHttpHandler { + + public final static String URI = "/sheet/info"; + + @Override + public RequestMethod getMethod() { + return RequestMethod.GET; + } + + @Override + public String getPath() { + return URI; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception { + FineLoggerFactory.getLogger().info("##### /sheet/info start..."); + String sid = WebUtils.getHTTPRequestParameter(req,"sessionId"); + FineLoggerFactory.getLogger().info("##### sid={}",sid); + ReportSessionIDInfor info = SessionPoolManager.getSessionIDInfor(sid, ReportSessionIDInfor.class); + Calculator cal = info.createSessionCalculator(req,res); + TemplateWorkBook book = info.getWorkBookDefine(); + FineLoggerFactory.getLogger().info("##### book={}",book.toString()); + Map relation = DsUtils.getRelation("CONF_SHEET","id","name", book,cal); + JSONArray result = JSONArray.create(); + FineLoggerFactory.getLogger().info("##### book.length={}",book.getReportCount()); + for( int i=0,len=book.getReportCount();i relation = DsUtils.getRelation("CONF_SHEET_GROUP", "id", "group", book, request); + String groupId = (String) request.getParameter("__sheet_group__"); + String [] group = split( relation.get(groupId), ","); + if( 0 == group.length ){ + return array; + } + JSONArray result = JSONArray.create(); + for (int i = 0; i < array.size(); i++) { + JSONObject obj = array.getJSONObject(i); + if(!obj.has("title")){ + continue; + } + if(ArrayUtils.contains(group,obj.getString("title")) ){ + result.add(obj); + } + } + return result; + } + + protected String[] split( String record , String sep ){ + if( StringUtils.isEmpty( record ) ){ + return new String[0]; + } + String [] group = new String[]{record}; + if( record.contains(sep) ){ + group = record.split(sep); + } + return group; + } +} diff --git a/src/main/java/com/fr/plugin/xxx/report/core/BuilderProvider.java b/src/main/java/com/fr/plugin/xxx/report/core/BuilderProvider.java new file mode 100644 index 0000000..366e44b --- /dev/null +++ b/src/main/java/com/fr/plugin/xxx/report/core/BuilderProvider.java @@ -0,0 +1,21 @@ +package com.fr.plugin.xxx.report.core; + +import com.fr.main.TemplateWorkBook; +import com.fr.web.request.ReportletRequest; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-01 + **/ +public abstract class BuilderProvider { + + /** + * 通过这个方法对模板的不同部分进行调整 + * @param book + * @param request + */ + public abstract void build(TemplateWorkBook book, ReportletRequest request )throws Exception; + + +} diff --git a/src/main/java/com/fr/plugin/xxx/report/core/DsUtils.java b/src/main/java/com/fr/plugin/xxx/report/core/DsUtils.java new file mode 100644 index 0000000..b558673 --- /dev/null +++ b/src/main/java/com/fr/plugin/xxx/report/core/DsUtils.java @@ -0,0 +1,93 @@ +package com.fr.plugin.xxx.report.core; + +import com.fr.base.ParameterMapNameSpace; +import com.fr.base.SynchronizedLiveDataModelUtils; +import com.fr.base.TableData; +import com.fr.data.TableDataSource; +import com.fr.data.api.TableDataAssist; +import com.fr.general.data.DataModel; +import com.fr.main.TemplateWorkBook; +import com.fr.script.Calculator; +import com.fr.stable.ParameterProvider; +import com.fr.web.request.ReportletRequest; + +import java.util.HashMap; +import java.util.Map; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-01 + **/ +public final class DsUtils { + private DsUtils(){} + + private final static Calculator initCalculator(TemplateWorkBook book){ + Calculator calculator = Calculator.createCalculator(); + calculator.setAttribute(TableDataSource.KEY,book); + return calculator; + } + + private final static void initParameter(Calculator calculator,TableData ds,ReportletRequest request){ + Map parameters = new HashMap(); + ParameterProvider[] ps = ds.getParameters(calculator); + for( ParameterProvider p : ps ){ + String pname = p.getName(); + Object v = request.getParameter(pname); + if( null != v ){ + parameters.put(pname, v); + } + } + ParameterMapNameSpace space = ParameterMapNameSpace.create(parameters); + calculator.pushNameSpace(space); + } + + public static DataModel getDataModel(TemplateWorkBook book, ReportletRequest request, String dsName ){ + Calculator calculator = initCalculator(book); + TableData ds = TableDataAssist.getTableData(calculator, dsName); + initParameter(calculator,ds,request); + DataModel dm = SynchronizedLiveDataModelUtils.getSELiveDataModel4Share(calculator, dsName); + if ( null == dm ) { + dm = ds == null ? null : ds.createDataModel(calculator); + } + return dm; + } + + public static DataModel getDataModel(TemplateWorkBook book, Calculator calculator, String dsName ){ + TableData ds = TableDataAssist.getTableData(calculator, dsName); + DataModel dm = SynchronizedLiveDataModelUtils.getSELiveDataModel4Share(calculator, dsName); + if ( null == dm ) { + dm = ds == null ? null : ds.createDataModel(calculator); + } + return dm; + } + + public static Map getRelation(String dsName, String keyCol, String valueCol, TemplateWorkBook book, Calculator cal){ + Map rt = new HashMap(); + try{ + DataModel dm = getDataModel(book,cal,dsName); + int vIdx = dm.getColumnIndex(valueCol); + int kIdx = dm.getColumnIndex(keyCol); + for( int i=0,len=dm.getRowCount();i getRelation(String dsName, String keyCol, String valueCol, TemplateWorkBook book, ReportletRequest request){ + Map rt = new HashMap(); + try{ + DataModel dm = getDataModel(book,request,dsName); + int vIdx = dm.getColumnIndex(valueCol); + int kIdx = dm.getColumnIndex(keyCol); + for( int i=0,len=dm.getRowCount();i relation)throws Exception; + + @Override + public void build(TemplateWorkBook book, ReportletRequest request )throws Exception{ + if( !accept(book,request) ){ + return; + } + Map relation = DsUtils.getRelation(dsName, colKey, colValue, book, request); + build(book,request,relation); + } + + protected String[] split( String record , String sep ){ + if( StringUtils.isEmpty( record ) ){ + return new String[0]; + } + String [] group = new String[]{record}; + if( record.contains(sep) ){ + group = record.split(sep); + } + return group; + } +} diff --git a/src/main/java/com/fr/plugin/xxx/report/core/SPTemplateReportlet.java b/src/main/java/com/fr/plugin/xxx/report/core/SPTemplateReportlet.java new file mode 100644 index 0000000..06dc3a9 --- /dev/null +++ b/src/main/java/com/fr/plugin/xxx/report/core/SPTemplateReportlet.java @@ -0,0 +1,36 @@ +package com.fr.plugin.xxx.report.core; + +import com.fr.main.TemplateWorkBook; +import com.fr.web.WebletException; +import com.fr.web.reportlet.TemplateReportlet; +import com.fr.web.request.ReportletRequest; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-01 + **/ +public class SPTemplateReportlet extends TemplateReportlet { + + public SPTemplateReportlet(String path) { + super(path); + } + + private final static BuilderProvider[] builders = new BuilderProvider[]{ + new ViewSheetBuilder("CONF_SHEET_GROUP","id","group"), + new ViewWidgetBuilder("CONF_WIDGET","id","group")//, + //new SheetNameBuilder("CONF_SHEET","id","name") + }; + + @Override + public TemplateWorkBook createReport( ReportletRequest request ) throws WebletException{ + TemplateWorkBook book = super.createReport(request); + for( BuilderProvider builder : builders ){ + try{ + builder.build(book,request); + }catch(Exception e){ + } + } + return book; + } +} diff --git a/src/main/java/com/fr/plugin/xxx/report/core/SheetNameBuilder.java b/src/main/java/com/fr/plugin/xxx/report/core/SheetNameBuilder.java new file mode 100644 index 0000000..9ee7044 --- /dev/null +++ b/src/main/java/com/fr/plugin/xxx/report/core/SheetNameBuilder.java @@ -0,0 +1,38 @@ +package com.fr.plugin.xxx.report.core; + +import com.fr.main.TemplateWorkBook; +import com.fr.web.request.ReportletRequest; + +import java.util.Map; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-01 + * 设置每个sheet的名称的构建适配器 + **/ +public class SheetNameBuilder extends RelationBuilder { + + public SheetNameBuilder(String dsName, String colKey, String colValue) { + super(dsName, colKey, colValue); + } + + @Override + protected boolean accept(TemplateWorkBook book, ReportletRequest request) throws Exception { + return true; + } + + @Override + protected void build(TemplateWorkBook book, ReportletRequest request, Map relation) throws Exception { + if( relation.isEmpty() ){ + return; + } + for(int i=0,len=book.getReportCount();i relation) throws Exception { + String groupId = (String)request.getParameter("__SHEET_GROUP__"); + String [] group = split( relation.get(groupId), ","); + if( 0 == group.length ){ + return; + } + List dels = new ArrayList(); + for(int i=0,len=book.getReportCount();i relation) throws Exception { + String groupId = (String)request.getParameter("__WIDGET_GROUP__"); + String [] group = split( relation.get(groupId), ","); + if( 0 == group.length ){ + return; + } + int count = book.getReportCount(); + for( int i=0; i cells = sheet.cellIterator(); + while (cells.hasNext() ){ + AbstractWidgetCellElement cell = cells.next(); + Widget widget = cell.getWidget(); + if( null != widget && !ArrayUtils.contains(group,widget.getWidgetName())){ + cell.setWidget(null); + } + } + } +} diff --git a/src/main/java/com/fr/plugin/xxx/report/creator/SPReportletCreator.java b/src/main/java/com/fr/plugin/xxx/report/creator/SPReportletCreator.java new file mode 100644 index 0000000..1d814dd --- /dev/null +++ b/src/main/java/com/fr/plugin/xxx/report/creator/SPReportletCreator.java @@ -0,0 +1,37 @@ +package com.fr.plugin.xxx.report.creator; + +import com.fr.data.NetworkHelper; +import com.fr.general.ComparatorUtils; +import com.fr.plugin.xxx.report.core.SPTemplateReportlet; +import com.fr.plugin.xxx.report.link.ReportletCreator; +import com.fr.stable.web.TemplatePathNode; +import com.fr.stable.web.Weblet; +import com.fr.web.reportlet.OldWeblet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-01 + **/ +public class SPReportletCreator extends ReportletCreator { + public static final SPReportletCreator KEY = new SPReportletCreator(); + + @Override + public Weblet createWebletByRequest(HttpServletRequest req, HttpServletResponse res){ + TemplatePathNode pathNode = queryPath(req); + String reportlet = pathNode.getPath(); + if (oldWebletOrServletCheck(req, pathNode)) { + return OldWeblet.asOldReportlet(reportlet); + } + // 暂时兼容cptx从cpt格式中读取 + if (ComparatorUtils.equals(NetworkHelper.getHTTPRequestParameter(req, FORMAT), X)) { + return new SPTemplateReportlet(reportlet + X); + } + return new SPTemplateReportlet(reportlet); + } + + +} diff --git a/src/main/java/com/fr/plugin/xxx/report/link/ReportletCreator.java b/src/main/java/com/fr/plugin/xxx/report/link/ReportletCreator.java new file mode 100644 index 0000000..6911f56 --- /dev/null +++ b/src/main/java/com/fr/plugin/xxx/report/link/ReportletCreator.java @@ -0,0 +1,90 @@ +package com.fr.plugin.xxx.report.link; + +import com.fr.base.extension.FileExtension; +import com.fr.data.NetworkHelper; +import com.fr.general.ComparatorUtils; +import com.fr.stable.ActorConstants; +import com.fr.stable.ActorFactory; +import com.fr.stable.web.*; +import com.fr.web.reportlet.EmbeddedTplReportlet; +import com.fr.web.reportlet.OldWeblet; +import com.fr.web.reportlet.TemplateReportlet; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.Map; + +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-01 + **/ +public class ReportletCreator extends AbstractWebletCreator { + + public static final ReportletCreator KEY = new ReportletCreator(); + /** + * hugh:直接把10.0的report-engine的ReportletCreator的代码复制过来,把构造改成public即可 + * 以后如果产品的ReportletCreator发生了变更,同样要copy过来 + */ + public ReportletCreator() { + + } + + @Override + public TemplatePathMarker[] queryPathMarker() { + return new TemplatePathMarker[]{PathMarkerImpl.VIEWLET, PathMarkerImpl.REPORTLET}; + } + + @Override + public FileExtension suffix() { + return FileExtension.CPT; + } + + /** + * 通过http请求构造Weblet + * + * @param req http请求 + * @param res http应答 + * @return 构造的Weblet + * @throws Exception + */ + @Override + public Weblet createWebletByRequest(HttpServletRequest req, HttpServletResponse res) { + TemplatePathNode pathNode = queryPath(req); + String reportlet = pathNode.getPath(); + if (oldWebletOrServletCheck(req, pathNode)) { + return OldWeblet.asOldReportlet(reportlet); + } + // 暂时兼容cptx从cpt格式中读取 + if (ComparatorUtils.equals(NetworkHelper.getHTTPRequestParameter(req, FORMAT), X)) { + return new TemplateReportlet(reportlet + X); + } + return new TemplateReportlet(reportlet); + } + + /** + * 根据模板路径生成合适的Weblet + * + * @param tplPath 模板路径模板名 + * @param parameterMap 参数 + * @return 构造的Weblet + * @throws Exception + */ + @Override + public Weblet createEmbeddedWeblet(String tplPath, Map parameterMap) { + if (tplPath == null || !matchReportTpl(tplPath)) { + return null; + } + return new EmbeddedTplReportlet(tplPath, ActorFactory.getActor(ActorConstants.TYPE_PAGE), parameterMap); + } + + /** + * 是否是报表模板 + * + * @param tplPath 模板路径 + * @return 如果是报表模板返回true,否则false + */ + private boolean matchReportTpl(String tplPath) { + return FileExtension.CPT.matchExtension(tplPath); + } +} diff --git a/src/main/resources/com/fr/plugin/xxx/report/main.css b/src/main/resources/com/fr/plugin/xxx/report/main.css new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/com/fr/plugin/xxx/report/main.js b/src/main/resources/com/fr/plugin/xxx/report/main.js new file mode 100644 index 0000000..aaec606 --- /dev/null +++ b/src/main/resources/com/fr/plugin/xxx/report/main.js @@ -0,0 +1,143 @@ +/** + * @author 秃破天际 + * @version 10.0 + * Created by 秃破天际 on 2020-04-01 + **/ +!(function () { + window.onload = function(){ + var getQueryVariable = function(variable) { + var query = window.location.search.substring(1); + var vars = query.split("&"); + for (var i=0;i").addClass("hg-list-item").addClass(lv) + .append($("").html(item.name)); + $item.click(function (e) { + FR.SheetController.selectSheetByID(item.id); + setActive(idx); + }); + return $item; + }; + $.extend(FR,{SheetController:{ + /** + * 通过sheet名称切换到指定sheet + * @param name + */ + selectSheetByID: function ( id ) { + var self = this; + if( isWritePlus() ){ + var list = getSheetList(); + list.forEach(function(item,index){ + if( item.id == id ){ + _g().sheetContainer.selectSheet(index); + } + }); + }else{ + _g().$contentPane.data("TabPane").selectTabByName(id); + } + }, + init:function () { + debugger; + var list = getSheetList(); + if( typeof list == "undefined" || list.length <= 1 ){ + return ; + } + var $wrap = $("
").addClass("hg-sheet-ctrl-wrap").appendTo("body"); + var $sideBtn = $("
").addClass("hg-side-hotspot").appendTo($wrap); + var $guidepost = $("
").addClass("hg-guidepost").appendTo($wrap); + var $list = $("
").addClass("hg-list").addClass("hg-card").appendTo($wrap); + $list.hide(); + var showList = function (e) { + var idx = getActiveSheet(); + setActive(idx); + $list.show(); + $guidepost.hide(); + }; + var hideList = function (e) { + $list.hide(); + $guidepost.show(); + }; + $sideBtn.mousemove(showList); + $guidepost.click(showList); + $list.mouseleave(hideList); + var item_height = parseInt(document.body.clientHeight/list.length); + list.forEach(function(item,index){ + var $item = initSheetItem(item,item_height,index).appendTo($list); + items.push($item); + $item.click(hideList); + }); + } + }}); + FR.SheetController.init(); + }; +})(); \ No newline at end of file