commit 278842462b43178cc38e614421ab771b2a2ab12e Author: pioneer Date: Fri Apr 7 15:36:41 2023 +0800 open diff --git a/README.md b/README.md new file mode 100644 index 0000000..e83a3c1 --- /dev/null +++ b/README.md @@ -0,0 +1,9 @@ +# open-JSD-11759 + +JSD-11759 +1.日期控件可以选择起止日期 \ +2.保存常用参数优化 \ +3.图表导出参数优化 \ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系【pioneer】处理。 diff --git a/lib/finekit-10.0-20220729.jar b/lib/finekit-10.0-20220729.jar new file mode 100644 index 0000000..617e565 Binary files /dev/null and b/lib/finekit-10.0-20220729.jar differ diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..33a59dc --- /dev/null +++ b/plugin.xml @@ -0,0 +1,24 @@ + + + com.eco.plugin.xx.nav.topp + + yes + 0.0.3 + 10.0 + 2021-02-10 + fr.open + com.fr.plugin + + + + 2023-1-3 15:31:15 + + + + + + + + \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/FunctionRecoder.java b/src/main/java/com/fr/plugin/FunctionRecoder.java new file mode 100644 index 0000000..963ca84 --- /dev/null +++ b/src/main/java/com/fr/plugin/FunctionRecoder.java @@ -0,0 +1,12 @@ +package com.fr.plugin; + +import com.fr.plugin.transform.ExecuteFunctionRecord; +import com.fr.plugin.transform.FunctionRecorder; + +@FunctionRecorder +public class FunctionRecoder { + @ExecuteFunctionRecord + public void exe(){ + System.out.println("插件功能埋点,虽然不会执行,除非上架应用"); + } +} diff --git a/src/main/java/com/fr/plugin/TOPPConfig.java b/src/main/java/com/fr/plugin/TOPPConfig.java new file mode 100644 index 0000000..0203173 --- /dev/null +++ b/src/main/java/com/fr/plugin/TOPPConfig.java @@ -0,0 +1,33 @@ +package com.fr.plugin; + +import com.fr.config.*; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; + +@Visualization(category = "顶部菜单插件_EK配置") +public class TOPPConfig extends DefaultConfiguration { + + private static volatile TOPPConfig config = null; + + public static TOPPConfig getInstance() { + if (config == null) { + config = ConfigContext.getConfigInstance(TOPPConfig.class); + } + return config; + } + @Identifier(value = "topNav", name = "顶部菜单目录名", description = "描述", status = Status.SHOW) + private Conf topNav = Holders.simple("头部专用目录"); + public String getTopNav() { + return topNav.get(); + } + public void setTopNav(String topNav) { + this.topNav.set(topNav); + } + @Override + public Object clone() throws CloneNotSupportedException { + TOPPConfig cloned = (TOPPConfig) super.clone(); + cloned.topNav = (Conf) this.topNav.clone(); + return cloned; + } + +} \ No newline at end of file diff --git a/src/main/java/com/fr/plugin/TOPPLifeCycleMonitor.java b/src/main/java/com/fr/plugin/TOPPLifeCycleMonitor.java new file mode 100644 index 0000000..c9c21f1 --- /dev/null +++ b/src/main/java/com/fr/plugin/TOPPLifeCycleMonitor.java @@ -0,0 +1,18 @@ +package com.fr.plugin; + +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; +import com.fr.stable.fun.Authorize; + +@Authorize +public class TOPPLifeCycleMonitor extends AbstractPluginLifecycleMonitor { + @Override + public void afterRun(PluginContext pluginContext) { + TOPPConfig.getInstance(); + } + + @Override + public void beforeStop(PluginContext pluginContext) { + + } +} diff --git a/src/main/java/com/fr/plugin/http/TOPPHttpHandler.java b/src/main/java/com/fr/plugin/http/TOPPHttpHandler.java new file mode 100644 index 0000000..8126de6 --- /dev/null +++ b/src/main/java/com/fr/plugin/http/TOPPHttpHandler.java @@ -0,0 +1,16 @@ +package com.fr.plugin.http; + +import com.fr.decision.fun.HttpHandler; +import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; +import com.fr.plugin.http.handler.*; + +public class TOPPHttpHandler extends AbstractHttpHandlerProvider { + HttpHandler[] actions = new HttpHandler[]{ + new GETGetTopMenu1Handler(), + }; + + @Override + public HttpHandler[] registerHandlers() { + return actions; + } +} diff --git a/src/main/java/com/fr/plugin/http/TOPPUrlAliasProvider.java b/src/main/java/com/fr/plugin/http/TOPPUrlAliasProvider.java new file mode 100644 index 0000000..4b22a91 --- /dev/null +++ b/src/main/java/com/fr/plugin/http/TOPPUrlAliasProvider.java @@ -0,0 +1,14 @@ +package com.fr.plugin.http; + +import com.fr.decision.fun.impl.AbstractURLAliasProvider; +import com.fr.decision.webservice.url.alias.URLAlias; +import com.fr.decision.webservice.url.alias.URLAliasFactory; + +public class TOPPUrlAliasProvider extends AbstractURLAliasProvider { + @Override + public URLAlias[] registerAlias() { + return new URLAlias[]{ + URLAliasFactory.createPluginAlias("/getTopMenu", "/getTopMenu", false), + }; + } +} diff --git a/src/main/java/com/fr/plugin/http/handler/GETGetTopMenu1Handler.java b/src/main/java/com/fr/plugin/http/handler/GETGetTopMenu1Handler.java new file mode 100644 index 0000000..c84a94d --- /dev/null +++ b/src/main/java/com/fr/plugin/http/handler/GETGetTopMenu1Handler.java @@ -0,0 +1,72 @@ +package com.fr.plugin.http.handler; + + +import com.fr.decision.webservice.bean.entry.EntryBean; +import com.fr.decision.webservice.v10.entry.EntryService; +import com.fr.decision.webservice.v10.login.LoginService; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.json.JSONArray; +import com.fr.log.FineLoggerFactory; +import com.fanruan.api.log.LogKit; +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.plugin.TOPPConfig; +import com.fr.stable.StringUtils; +import com.fr.third.fasterxml.jackson.databind.ObjectMapper; +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; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.BufferedReader; +import java.util.ArrayList; +import java.util.List; + +public class GETGetTopMenu1Handler extends BaseHttpHandler { + @Override + public RequestMethod getMethod() { + return RequestMethod.GET; + } + + @Override + public String getPath() { + return "/getTopMenu"; + } + + @Override + public boolean isPublic() { + return false; + } + + @Override + public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception { + EntryService instance = EntryService.getInstance(); + String username = LoginService.getInstance().getUserNameFromRequest(req); + String currentUserId = UserService.getInstance().getCurrentUserId(username); + List allEntries = instance.getAllEntries(currentUserId); + //找出配置的root + TOPPConfig config = TOPPConfig.getInstance(); + String topNav = config.getTopNav(); + EntryBean top=null; + for (EntryBean allEntry : allEntries) { + if (StringUtils.equals(topNav,allEntry.getText())) { + top=allEntry; + break; + } + } + List result = new ArrayList<>(); + if(top!=null){ + //找他的儿子 + for (EntryBean allEntry : allEntries) { + if (StringUtils.equals(allEntry.getpId(),top.getId())) { + result.add(allEntry); + } + } + } + ObjectMapper mapper = new ObjectMapper(); + String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(result); + WebUtils.printAsJSON(res, new JSONArray(json)); + } + +} diff --git a/src/main/java/com/fr/plugin/web/RNavComponent.java b/src/main/java/com/fr/plugin/web/RNavComponent.java new file mode 100644 index 0000000..6c4e1e9 --- /dev/null +++ b/src/main/java/com/fr/plugin/web/RNavComponent.java @@ -0,0 +1,50 @@ +package com.fr.plugin.web; + +import com.fr.plugin.context.PluginContexts; +import com.fr.web.struct.Component; +import com.fr.web.struct.Filter; +import com.fr.web.struct.browser.RequestClient; +import com.fr.web.struct.category.ScriptPath; +import com.fr.web.struct.category.StylePath; + +public class RNavComponent extends Component { + public static final RNavComponent KEY = new RNavComponent(); + /** + * 返回需要引入的JS脚本路径 + * @param client 请求客户端描述 + * @return JS脚本路径 + */ + public ScriptPath script( RequestClient client ) { + if (PluginContexts.currentContext().isAvailable()) { + // 做认证通过的事情 + return ScriptPath.build("com/fr/plugin/web/js/RNavweb.js"); + } else { + // 做认证未通过的事情 + return ScriptPath.build("com/fr/plugin/web/js/webnuy.js"); + } + } + + /** + * 返回需要引入的CSS样式路径 + * @param client 请求客户端描述 + * @return CSS样式路径 + */ + public StylePath style( RequestClient client ) { + //如果不需要就直接返回 StylePath.EMPTY; + return StylePath.build("com/fr/plugin/web/css/RNavweb.css"); + } + + /** + * 通过给定的资源过滤器控制是否加载这个资源 + * @return 资源过滤器 + */ + public Filter filter() { + return new Filter(){ + @Override + public boolean accept() { + //任何情况下我们都在平台组件加载时加载我们的组件 + return true; + } + }; + } +} diff --git a/src/main/java/com/fr/plugin/web/TOPPRNav1WebResourceProvider.java b/src/main/java/com/fr/plugin/web/TOPPRNav1WebResourceProvider.java new file mode 100644 index 0000000..5bbe5d9 --- /dev/null +++ b/src/main/java/com/fr/plugin/web/TOPPRNav1WebResourceProvider.java @@ -0,0 +1,30 @@ +package com.fr.plugin.web; + +import com.fr.decision.fun.impl.AbstractWebResourceProvider; +import com.fr.decision.web.MainComponent; +import com.fr.decision.web.LoginComponent; +import com.fr.web.struct.Atom; + +public class TOPPRNav1WebResourceProvider extends AbstractWebResourceProvider { + + /** + * 需要附加到的主组件 + * + * @return 主组件 + */ + + @Override + public Atom attach() { + return MainComponent.KEY; + } + + /** + * 客户端所需的组件 + * + * @return 组件 + */ + @Override + public Atom client() { + return RNavComponent.KEY; + } +} diff --git a/src/main/resources/com/fr/plugin/web/css/RNavweb.css b/src/main/resources/com/fr/plugin/web/css/RNavweb.css new file mode 100644 index 0000000..fe3e1d8 --- /dev/null +++ b/src/main/resources/com/fr/plugin/web/css/RNavweb.css @@ -0,0 +1,3 @@ +.iconttt{ + color: #ffffff; +} \ No newline at end of file diff --git a/src/main/resources/com/fr/plugin/web/js/RNavweb.js b/src/main/resources/com/fr/plugin/web/js/RNavweb.js new file mode 100644 index 0000000..7fff6ef --- /dev/null +++ b/src/main/resources/com/fr/plugin/web/js/RNavweb.js @@ -0,0 +1,153 @@ +console.info("RNav加载成功") +//不需要可以删除下面的代码 + +function syncAjax(e) { + e = e || {}; + var t = ""; + t = Dec.fineServletURL ? Dec.fineServletURL + e.url : "http://localhost:9002/webroot/decision" + e.url; + var i = BI.Cache.getCookie(DecCst.Cookie.TOKEN); + i && (e.headers = e.headers || {}, e.headers.Authorization = "Bearer " + i), $.support.cors = !0, NProgress.start(), $.ajax({ + url: t, + headers: e.headers, + type: e.type, + contentType: "application/json", + data: JSON.stringify(e.data), + dataType: "json", + cache: !1, + async: !1, + error: function () { + BI.Msg.toast("ajax error !", "warning") + }, + complete: function (t, i) { + NProgress.done(), "success" === i && BI.isFunction(e.success) && e.success(BI.jsonDecode(t.responseText)), BI.isFunction(e.complete) && e.complete(BI.jsonDecode(t.responseText), i) + } + }) +} +!(function() { + var e; + e = BI.inherit(BI.Widget, { + props: { + baseCls: "dec-common-icon-item", + $testId: "dec-common-icon-item", + icon: "", + title:"", + iconWidth: null, + iconHeight: null + }, + render: function() { + var e = this + , t = this.options; + BI.createWidget({ + type: "bi.center_adapt", + element: this, + height: t.height, + width: t.width, + items: [{ + type: "bi.icon", + title:BI.i18nText(t.title), + cls: "icon-container", + ref: function(t) { + e.icon = t + }, + width: t.iconWidth, + height: t.iconHeight + }] + }), + this.setIcon(t.icon) + }, + _setCls: function(e) { + BI.isObject(this.options.icon) && this.icon.element.css({ + backgroundImage: "" + }), + this.element.removeClass(this.options.icon).addClass(e), + this.options.icon = e + }, + _setBackground: function(e) { + BI.isKey(this.options.icon) && this.element.removeClass(this.options.icon), + this.icon.element.css(e), + this.options.icon = e + }, + setIcon: function(e) { + BI.isKey(e) ? this._setCls(e) : this._setBackground(e) + } + }), + BI.shortcut("dec..common.icon_item", e) +})(); +!(function () { + BI.Plugin.config(function (type, options) { + }, function (type, object) { + object.element.attr("类型", object.options.type); + }); + BI.config("dec.constant.header.items", function (items) { + items.unshift({ + type: "dec.header.alink", + }); + return items; + }); + +// 组件实现,效果为使用绝对布局组件放置了一个iframe + var Wid = BI.inherit(BI.Widget, { + + props: { + baseCls: "" + }, + beforeInit:function (render){ + var that=this; + syncAjax({ + url:"/url/getTopMenu", + success:function (e){ + that.models=e; + render(); + } + }) + }, + isAttachId: function(e) { + return /^holder/.test(e) + }, + getComputedIcon: function(e) { + if(!e){ + return 'dir-panel-template-font' + } + return this.isAttachId(e) ? { + backgroundImage: "url(" + Dec.Utils.buildImgUrlByAttachId(e, !0) + ")" + } : e + }, + render: function () { + var that=this + var items=BI.map(this.models,function (i,v){ + return { + type: "dec..common.icon_item", + iconWidth: 16, + cls:"cursor-pointer iconttt", + iconHeight: 16, + width: 24, + text:v.text, + title:v.text, + ref:function (e){ + $(e.element).click(function (){ + var url = ""; + if(v.entryType===102){ + url+=Dec.fineServletURL+"/v10/entry/access/"+v.id + }else if(v.entryType===5){ + url=v.path + } + window.open(url) + }); + }, + icon: that.getComputedIcon(v.icon), + height: 20 + } + }); + return { + type: "bi.vertical_adapt", + height:40, + rgap:10, + width:(27*this.models.length), + items: items + }; + } + }); + BI.shortcut("dec.header.alink", Wid); + +})(); +