diff --git a/README.md b/README.md index 61a257c..9444840 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ # open-JSD-8547 -JSD-8547 开源任务材料 \ No newline at end of file +JSD-8547 扁平主题\ +免责说明:该源码为第三方爱好者提供,不保证源码和方案的可靠性,也不提供任何形式的源码教学指导和协助!\ +仅作为开发者学习参考使用!禁止用于任何商业用途!\ +为保护开发者隐私,开发者信息已隐去!若原开发者希望公开自己的信息,可联系hugh处理。 \ No newline at end of file diff --git a/lib/finekit-10.0.jar b/lib/finekit-10.0.jar new file mode 100644 index 0000000..611c8f5 Binary files /dev/null and b/lib/finekit-10.0.jar differ diff --git a/plugin.xml b/plugin.xml new file mode 100644 index 0000000..092f3f7 --- /dev/null +++ b/plugin.xml @@ -0,0 +1,22 @@ + + com.fr.plugin.third.party.jsdifeh + + yes + 0.7 + 10.0 + 2019-01-01 + fr.open + + + + * + + + + + + + + + + diff --git a/src/main/java/com/fr/plugin/third/party/jsdifeh/components/FileDef.java b/src/main/java/com/fr/plugin/third/party/jsdifeh/components/FileDef.java new file mode 100644 index 0000000..19c68bd --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdifeh/components/FileDef.java @@ -0,0 +1,62 @@ +package com.fr.plugin.third.party.jsdifeh.components; + +import com.fanruan.api.log.LogKit; +import com.fr.decision.config.AppearanceConfig; +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 FileDef extends Component { + + public static final FileDef KEY = new FileDef(); + + private FileDef() { + } + + /** + * 返回需要引入的JS脚本路径 + * + * @param client 请求客户端描述 + * @return JS脚本路径 + */ + @Override + public ScriptPath script(RequestClient client) { + return ScriptPath.build("com/fr/plugin/third/party/jsdifeh/web/main.js"); + } + + /** + * 返回需要引入的CSS样式路径 + * + * @param client 请求客户端描述 + * @return CSS样式路径 + */ + @Override + public StylePath style(RequestClient client) { +// //如果不需要就直接返回 StylePath.EMPTY; + return StylePath.build("com/fr/plugin/third/party/jsdifeh/web/main.css"); + } + + + @Override + public Filter filter() { + return new Filter() { + public boolean accept() { + //添加认证 + if (!PluginContexts.currentContext().isAvailable()) { + LogKit.error("The jsdifeh plugin trial is over, please purchase a license"); + return false; + } + String loginPageId = AppearanceConfig.getInstance().getThemeId(); + if ("modern".equalsIgnoreCase(loginPageId)) { + return true; + } + //System.out.println(loginPageId); + return false; + } + }; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdifeh/components/WebResourceProvider.java b/src/main/java/com/fr/plugin/third/party/jsdifeh/components/WebResourceProvider.java new file mode 100644 index 0000000..957de10 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdifeh/components/WebResourceProvider.java @@ -0,0 +1,19 @@ +package com.fr.plugin.third.party.jsdifeh.components; + +import com.fr.decision.fun.impl.AbstractWebResourceProvider; +import com.fr.decision.web.MainComponent; +import com.fr.stable.fun.Authorize; +import com.fr.web.struct.Atom; + +@Authorize(callSignKey = "com.fr.plugin.third.party.jsdifeh") +public class WebResourceProvider extends AbstractWebResourceProvider { + @Override + public Atom attach() { + return MainComponent.KEY; + } + + @Override + public Atom client() { + return FileDef.KEY; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdifeh/config/CustomDataConfig.java b/src/main/java/com/fr/plugin/third/party/jsdifeh/config/CustomDataConfig.java new file mode 100644 index 0000000..9dff078 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdifeh/config/CustomDataConfig.java @@ -0,0 +1,81 @@ +package com.fr.plugin.third.party.jsdifeh.config; + + +import com.fr.config.*; +import com.fr.config.holder.Conf; +import com.fr.config.holder.factory.Holders; + +import java.awt.*; + +/** + * 配置数据保存 + */ +@Visualization(category = "扁平化主题菜单定制配置") +public class CustomDataConfig extends DefaultConfiguration { + public String getNameSpace() { + return this.getClass().getName(); + } + + private static volatile CustomDataConfig config = null; + + public static CustomDataConfig getInstance() { + if (config == null) { + config = ConfigContext.getConfigInstance(CustomDataConfig.class); + } + return config; + } + + @Identifier(value = "globalDirectoryCover", name = "全局目录封面", description = "", status = Status.SHOW) + private Conf globalDirectoryCover = Holders.simple(false); + + @Identifier(value = "fontSize", name = "字体大小", description = "", status = Status.SHOW) + private Conf fontSize = Holders.simple(12); + + @Identifier(value = "fontBold", name = "字体加粗", description = "", status = Status.SHOW) + private Conf fontBold = Holders.simple(false); + + @Identifier(value = "fontColor", name = "字体颜色", description = "", status = Status.SHOW) + private Conf fontColor = Holders.simple(Color.BLACK); + + public Boolean isGlobalDirectoryCover() { + return globalDirectoryCover.get(); + } + + public void setGlobalDirectoryCover(Boolean globalDirectoryCover) { + this.globalDirectoryCover.set(globalDirectoryCover); + } + + public Integer getFontSize() { + return fontSize.get(); + } + + public void setFontSize(Integer fontSize) { + this.fontSize.set(fontSize); + } + + public Boolean isFontBold() { + return fontBold.get(); + } + + public void setFontBold(Boolean fontBold) { + this.fontBold.set(fontBold); + } + + public Color getFontColor() { + return fontColor.get(); + } + + public void setFontColor(Color value) { + this.fontColor.set(value); + } + + @Override + public Object clone() throws CloneNotSupportedException { + CustomDataConfig cloned = (CustomDataConfig) super.clone(); + cloned.fontSize = (Conf) fontSize.clone(); + cloned.fontBold = (Conf) fontBold.clone(); + cloned.fontColor = (Conf) fontColor.clone(); + cloned.globalDirectoryCover = (Conf) globalDirectoryCover.clone(); + return cloned; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdifeh/config/DataConfigInitializeMonitor.java b/src/main/java/com/fr/plugin/third/party/jsdifeh/config/DataConfigInitializeMonitor.java new file mode 100644 index 0000000..70e7a19 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdifeh/config/DataConfigInitializeMonitor.java @@ -0,0 +1,22 @@ +package com.fr.plugin.third.party.jsdifeh.config; + +import com.fr.intelli.record.Focus; +import com.fr.intelli.record.Original; +import com.fr.plugin.context.PluginContext; +import com.fr.plugin.observer.inner.AbstractPluginLifecycleMonitor; +import com.fr.record.analyzer.EnableMetrics; + + +@EnableMetrics +public class DataConfigInitializeMonitor extends AbstractPluginLifecycleMonitor { + @Override + @Focus(id = "com.fr.plugin.third.party.jsdifeh", text = "plugin-jsd-ifeh", source = Original.PLUGIN) + public void afterRun(PluginContext pluginContext) { + CustomDataConfig.getInstance(); + } + + @Override + public void beforeStop(PluginContext pluginContext) { + + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdifeh/http/CustomConfigHttpHandler.java b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/CustomConfigHttpHandler.java new file mode 100644 index 0000000..64b8e41 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/CustomConfigHttpHandler.java @@ -0,0 +1,63 @@ +package com.fr.plugin.third.party.jsdifeh.http; + +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.json.JSONObject; +import com.fr.plugin.third.party.jsdifeh.config.CustomDataConfig; +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 java.awt.Color; + +/** + * + */ +public class CustomConfigHttpHandler extends BaseHttpHandler { + + @Override + public RequestMethod getMethod() { + return RequestMethod.GET; + } + + @Override + public String getPath() { + return "/jsdifeh/config"; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception { + res.setContentType("application/json; charset=utf-8"); + JSONObject configJson = new JSONObject(); + String fontSize = CustomDataConfig.getInstance().getFontSize() + "px"; + int fontWeight = 400; + if (CustomDataConfig.getInstance().isFontBold()) { + fontWeight = 700; + } + String fontColor = toHexColor(CustomDataConfig.getInstance().getFontColor()); + configJson.put("fontSize", fontSize); + configJson.put("fontWeight", fontWeight); + configJson.put("fontColor", fontColor); + WebUtils.printAsJSON(res, configJson); + } + + private String toHexColor(Color color) { + String value = "#" + toHex(color.getRed()) + toHex(color.getGreen()) + toHex(color.getBlue()); + value = value.toLowerCase(); + return value; + } + + private String toHex(int value) { + String hex = Integer.toHexString(value); + if (hex.length() <= 1) { + hex = "0" + hex; + } + return hex; + } + +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdifeh/http/CustomHttpHandlerProvider.java b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/CustomHttpHandlerProvider.java new file mode 100644 index 0000000..7d09577 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/CustomHttpHandlerProvider.java @@ -0,0 +1,14 @@ +package com.fr.plugin.third.party.jsdifeh.http; + +import com.fr.decision.fun.impl.AbstractHttpHandlerProvider; +import com.fr.decision.fun.impl.BaseHttpHandler; + +public class CustomHttpHandlerProvider extends AbstractHttpHandlerProvider { + @Override + public BaseHttpHandler[] registerHandlers() { + return new BaseHttpHandler[]{ + new CustomConfigHttpHandler(), + new EntryTreeHttpHandler() + }; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdifeh/http/CustomURLAliasProvider.java b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/CustomURLAliasProvider.java new file mode 100644 index 0000000..c724b79 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/CustomURLAliasProvider.java @@ -0,0 +1,15 @@ +package com.fr.plugin.third.party.jsdifeh.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 CustomURLAliasProvider extends AbstractURLAliasProvider { + @Override + public URLAlias[] registerAlias() { + return new URLAlias[]{ + URLAliasFactory.createPluginAlias("/jsdifeh/config", "/jsdifeh/config", true), + URLAliasFactory.createPluginAlias("/jsdifeh/entry/tree", "/jsdifeh/entry/tree", true) + }; + } +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdifeh/http/EntryTreeHttpHandler.java b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/EntryTreeHttpHandler.java new file mode 100644 index 0000000..9931a81 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/EntryTreeHttpHandler.java @@ -0,0 +1,97 @@ +package com.fr.plugin.third.party.jsdifeh.http; + +import com.fanruan.api.util.StringKit; +import com.fr.decision.fun.impl.BaseHttpHandler; +import com.fr.decision.webservice.bean.entry.DirectoryBean; +import com.fr.decision.webservice.bean.entry.EntryBean; +import com.fr.decision.webservice.v10.entry.EntryService; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.json.revise.EmbedJson; +import com.fr.plugin.third.party.jsdifeh.config.CustomDataConfig; +import com.fr.third.fasterxml.jackson.core.JsonProcessingException; +import com.fr.third.springframework.web.bind.annotation.RequestMethod; +import com.fr.web.controller.decision.api.config.AppearanceResource; +import com.fr.web.utils.WebUtils; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +/** + * + */ +public class EntryTreeHttpHandler extends BaseHttpHandler { + + @Override + public RequestMethod getMethod() { + return RequestMethod.GET; + } + + @Override + public String getPath() { + return "/jsdifeh/entry/tree"; + } + + @Override + public boolean isPublic() { + return true; + } + + @Override + public void handle(HttpServletRequest req, HttpServletResponse res) throws Exception { + res.setContentType("application/json; charset=utf-8"); + List entryBeans = EntryService.getInstance().getEntryTree(req); + boolean globalOption = CustomDataConfig.getInstance().isGlobalDirectoryCover(); + String coverId = ""; + if (globalOption) { + coverId = getGlobalCoverId(); + } + JSONObject dataJson = getDataJson(entryBeans, globalOption, coverId); + WebUtils.printAsJSON(res, dataJson); + //AppearanceResource + } + + private String getGlobalCoverId() throws Exception { + String coverId = ""; + List directoryBeans = EntryService.getInstance().getEntrysWithCoverIcon("decision-directory-root"); + if ((directoryBeans == null) || (directoryBeans.size() <= 0)) { + return ""; + } + String globalName = "全局目录封面"; + DirectoryBean directoryBean; + for (int i = 0, max = directoryBeans.size() - 1; i <= max; i++) { + directoryBean = directoryBeans.get(i); + if (globalName.equalsIgnoreCase(directoryBean.getText())) { + coverId = directoryBean.getCover(); + break; + } + } + if (StringKit.isEmpty(coverId)) { + coverId = ""; + } + + return coverId; + } + + private JSONObject getDataJson(List entryBeans, boolean globalOption, String coverId) throws JsonProcessingException { + JSONArray dirJsons = new JSONArray(); + JSONObject dataJson = new JSONObject(); + dataJson.put("data", dirJsons); + if ((entryBeans == null) || (entryBeans.size() <= 0)) { + return dataJson; + } + JSONObject jsonObject; + EntryBean entryBean; + for (int i = 0, max = entryBeans.size() - 1; i <= max; i++) { + entryBean = entryBeans.get(i); + jsonObject = new JSONObject(EmbedJson.MAPPER.writeValueAsString(entryBean)); + if (globalOption) { + jsonObject.put("cover", coverId); + } + dirJsons.add(jsonObject); + } + return dataJson; + } + +} diff --git a/src/main/java/com/fr/plugin/third/party/jsdifeh/http/RequestWrapper.java b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/RequestWrapper.java new file mode 100644 index 0000000..8774985 --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/RequestWrapper.java @@ -0,0 +1,56 @@ +package com.fr.plugin.third.party.jsdifeh.http; + +import com.fr.general.IOUtils; + +import javax.servlet.ReadListener; +import javax.servlet.ServletInputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import java.io.*; + +public class RequestWrapper extends HttpServletRequestWrapper { + private final String body; + + public RequestWrapper(HttpServletRequest request) throws IOException { + super(request); + try { + InputStream inputStream = request.getInputStream(); + body = IOUtils.inputStream2String(inputStream); + } catch (IOException ex) { + throw ex; + } + } + + @Override + public ServletInputStream getInputStream() throws IOException { + final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes()); + ServletInputStream servletInputStream = new ServletInputStream() { + public boolean isFinished() { + return false; + } + + public boolean isReady() { + return false; + } + + public void setReadListener(ReadListener readListener) { + } + + public int read() throws IOException { + return byteArrayInputStream.read(); + } + }; + return servletInputStream; + } + + @Override + public BufferedReader getReader() throws IOException { + return new BufferedReader(new InputStreamReader(this.getInputStream())); + } + + public String getBody() { + return this.body; + } + +} + diff --git a/src/main/java/com/fr/plugin/third/party/jsdifeh/http/SessionGlobalRequestFilterProvider.java b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/SessionGlobalRequestFilterProvider.java new file mode 100644 index 0000000..cb1869b --- /dev/null +++ b/src/main/java/com/fr/plugin/third/party/jsdifeh/http/SessionGlobalRequestFilterProvider.java @@ -0,0 +1,154 @@ +package com.fr.plugin.third.party.jsdifeh.http; + +import com.fanruan.api.log.LogKit; +import com.fanruan.api.util.StringKit; +import com.fr.decision.authority.AuthorityContext; +import com.fr.decision.authority.data.Authority; +import com.fr.decision.fun.impl.AbstractGlobalRequestFilterProvider; +import com.fr.decision.webservice.bean.entry.DirectoryBean; +import com.fr.decision.webservice.bean.entry.EntryBean; +import com.fr.decision.webservice.utils.ControllerFactory; +import com.fr.decision.webservice.v10.entry.EntryService; +import com.fr.decision.webservice.v10.user.UserService; +import com.fr.json.JSONObject; +import com.fr.plugin.third.party.jsdifeh.config.CustomDataConfig; +import com.fr.stable.web.Device; + +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.util.List; + +public class SessionGlobalRequestFilterProvider extends AbstractGlobalRequestFilterProvider { + private String globalMenuId = ""; + + @Override + public void init(FilterConfig filterConfig) { + this.globalMenuId = getGlobalMenuId(); + } + + @Override + public String filterName() { + return "com.fr.plugin.third.party.jsdifeh"; + } + + @Override + public String[] urlPatterns() { + return new String[]{"/decision", "/decision/*"}; + } + + @Override + public void doFilter(HttpServletRequest req, HttpServletResponse res, FilterChain filterChain) { + try { + String fullUrl = getRequestFullUrl(req); + String method = req.getMethod(); + LogKit.info("扁平化主题菜单定制,请求链接:" + method + " " + fullUrl); + + if (!"PUT".equals(method)) { + filterChain.doFilter(req, res); + return; + } + + String url = req.getRequestURL().toString(); + if (url.indexOf("/decision/v10/config/appearance/entry/style") < 0) { + filterChain.doFilter(req, res); + return; + } + + boolean globalOption = CustomDataConfig.getInstance().isGlobalDirectoryCover(); + if (!globalOption) { + filterChain.doFilter(req, res); + return; + } + + RequestWrapper requestWrapper = new RequestWrapper(req); + String reqBody = requestWrapper.getBody(); + if (StringKit.isEmpty(reqBody)) { + filterChain.doFilter(requestWrapper, res); + return; + } + + JSONObject bodyJson = new JSONObject(reqBody); + String menuId = bodyJson.getString("id"); + if (StringKit.isEmpty(menuId)) { + filterChain.doFilter(requestWrapper, res); + return; + } + + if (!StringKit.equalsIgnoreCase(menuId, this.globalMenuId)) { + filterChain.doFilter(requestWrapper, res); + return; + } + + String coverId = bodyJson.getString("cover"); + updateAllCover(coverId); + + filterChain.doFilter(requestWrapper, res); + } catch (Exception e) { + LogKit.error("扁平化主题菜单定制出错," + e.getMessage(), e); + } + } + + private void updateAllCover(String coverId) throws Exception { + List entryBeans = getAllEntryTree(); + EntryBean entryBean; + for (int i = 0, max = entryBeans.size() - 1; i <= max; i++) { + entryBean = entryBeans.get(i); + if (entryBean.getEntryType() == 3) { + continue; + } + editEntryCover(entryBean.getId(), coverId); + } + } + + private List getAllEntryTree() throws Exception { + String userId = UserService.getInstance().getAdminUserIdList().get(0); + return ControllerFactory.getInstance().getEntryController(userId).getEntryTree(userId, Device.PC); + } + + private void editEntryCover(String menuId, String coverId) throws Exception { + Authority var2 = (Authority) AuthorityContext.getInstance().getAuthorityController().getById(menuId); + var2.setCoverId(coverId); + AuthorityContext.getInstance().getAuthorityController().update(var2); + } + + private String getRequestFullUrl(HttpServletRequest req) { + if (req == null) { + return ""; + } + String query = req.getQueryString(); + if ("null".equalsIgnoreCase(query) || StringKit.isEmpty(query)) { + query = ""; + } else { + query = "?" + query; + } + String url = req.getRequestURL().toString() + query; + return url; + } + + private String getGlobalMenuId() { + String menuId = ""; + try { + List directoryBeans = EntryService.getInstance().getEntrysWithCoverIcon("decision-directory-root"); + if ((directoryBeans == null) || (directoryBeans.size() <= 0)) { + return ""; + } + String globalName = "全局目录封面"; + DirectoryBean directoryBean; + for (int i = 0, max = directoryBeans.size() - 1; i <= max; i++) { + directoryBean = directoryBeans.get(i); + if (globalName.equalsIgnoreCase(directoryBean.getText())) { + menuId = directoryBean.getId(); + break; + } + } + if (StringKit.isEmpty(menuId)) { + menuId = ""; + } + } catch (Exception e) { + LogKit.error("扁平化主题菜单定制,获取全局目录封面菜单ID出错," + e.getMessage()); + } + return menuId; + } +} diff --git a/src/main/resources/com/fr/plugin/third/party/jsdifeh/web/main.css b/src/main/resources/com/fr/plugin/third/party/jsdifeh/web/main.css new file mode 100644 index 0000000..65be762 --- /dev/null +++ b/src/main/resources/com/fr/plugin/third/party/jsdifeh/web/main.css @@ -0,0 +1,21 @@ +.jsdifeh-report-name{ + position: absolute; + z-index: 1000; + width: 208px !important; + top: 60px !important; + left: 5px !important; +} + +.jsdifeh-zoom-in { + width: 70px !important; +} + +.jsdifeh-tabs { + left: 70px !important; +} + + +.jsdifeh-report-name > .bi-text{ + white-space: normal !important; + text-align:center !important; +} diff --git a/src/main/resources/com/fr/plugin/third/party/jsdifeh/web/main.js b/src/main/resources/com/fr/plugin/third/party/jsdifeh/web/main.js new file mode 100644 index 0000000..dbb7e0f --- /dev/null +++ b/src/main/resources/com/fr/plugin/third/party/jsdifeh/web/main.js @@ -0,0 +1,782 @@ +Dec.Utils = Dec.Utils || {}; +Dec.Utils_jsdifeh = Dec.Utils_jsdifeh || {}; + +Dec.Utils_jsdifeh.config = {}; + +BI.extend(Dec.Utils_jsdifeh, { + getConfig: function (e) { + Dec.reqGet("/url/jsdifeh/config", "", e) + }, + getCompleteDirectoryTree: function (e) { + Dec.reqGet("/url/jsdifeh/entry/tree", "", e) + } +}); + +!(function () { + var e = BI.inherit(BI.Widget, { + props: { + $testId: "dec-frame-modern-main-cards-section", + entryName: null, + items: [], + el: { + type: "dec.frame.modern.main_cards.section.card_item", + //width: 150, + //height: 135 + width: 218, + height: 135 + }, + fontSize: "12px", + fontWeight: 400, + fontColor: "#000000" + }, + beforeRender: function (callback) { + // 在执行render创建子组件之前的钩子函数 + var i = this; + Dec.Utils_jsdifeh.getConfig(function (e) { + //debugger; + var config = e; + i.options.fontSize = config.fontSize; + i.options.fontWeight = config.fontWeight; + i.options.fontColor = config.fontColor; + callback(); + }) + }, + render: function () { + var t = this + , e = this.options; + return BI.isNull(e.entryName) ? { + type: "bi.vertical", + hgap: 10, + items: [{ + type: "bi.button_group", + chooseType: -1, + items: this._createItems(e.items), + layouts: [{ + type: "bi.left", + rgap: 10, + bgap: 10 + }], + listeners: [{ + eventName: "EVENT_CHANGE", + action: function (e) { + t.handleSelect(e) + } + }] + }] + } : { + type: "bi.vertical", + hgap: 10, + vgap: 10, + items: [{ + type: "bi.label", + text: e.entryName, + textAlign: "left", + cls: "bi-font-bold bi-border-bottom dec-frame-text dec-frame-split-border", + height: 36 + }, { + type: "bi.button_group", + chooseType: -1, + items: this._createItems(e.items), + layouts: [{ + type: "bi.left", + rgap: 10, + bgap: 10 + }], + listeners: [{ + eventName: "EVENT_CHANGE", + action: function (e) { + t.handleSelect(e) + } + }] + }] + } + }, + _createItems: function (e) { + var _i = this; + var items = BI.map(e, function (e, t) { + return BI.extend({ + footer: { + el: { + baseCls: "jsdifeh-report-name", + //cls: _i._getFontWeightBold(), + type: "bi.label", + text: t.text, + //textAlign: "center", + //whiteSpace: "normal", + css: { + "font-size": _i.options.fontSize, + "font-weight": _i.options.fontWeight, + "color": _i.options.fontColor + } + }, + height: 0 + }, + title: t.textTitle || t.text + }, + this.options.el, t) + }, this); + return items; + }, + _getFontWeightBold: function () { + if (this.options.fontWeight == 700) { + return "dec-font-weight-bold"; + } + return ""; + }, + handleSelect: function (i) { + var e = BI.find(this.options.items, function (e, t) { + return t.id === i + }); + BI.Providers.getProvider("dec.provider.tab_pane").behaviour("addCardByName", e.id, BI.extend({ + text: e.text, + value: e.id, + entry: e.entryType, + entryDetails: e, + cardType: { + src: e.iframeSrc + } + }, e)), + this.fireEvent("EVENT_CHANGE", i) + } + }); + BI.shortcut("dec.frame.modern.main_cards.section_jsdifeh", e) +})(); + +!(function () { + var e = BI.inherit(BI.BasicButton, { + props: { + cls: "dec-frame-modern-zoomer-zoom-in dec-tab-bar jsdifeh-zoom-in", + $testId: "dec-frame-modern-zoomer-zoom-in" + }, _store: function () { + return BI.Models.getModel("dec.model.frame.modern.zoomer.zoom_in_out") + }, render: function () { + this.options; + return { + //type: "bi.icon_button", + //cls: "modern-zoom-in-font", + //title: "返回目录", + type: "bi.label", + text: "返回目录", + textAlign: "center", + } + }, doClick: function () { + this.store.zoomIn(), BI.FullScreen.isFullScreen() && BI.FullScreen.exitFullScreen() + } + }); + BI.shortcut("dec.frame.modern.zoom_in_jsdifeh", e) +})(); + +!(function () { + var e = BI.inherit(BI.BasicButton, { + props: { + baseCls: "dec-frame-modern-zoom-out dec-frame-panel", + $testId: "dec-frame-modern-zoom-out", + width: 70, + height: 44 + }, _store: function () { + return BI.Models.getModel("dec.model.frame.modern.zoomer.zoom_in_out") + }, render: function () { + var e = this.options; + return { + //type: "bi.icon_label", cls: "modern-zoom-out-font", height: e.height, width: e.width + type: "bi.label", + text: "返回报表", + textAlign: "center", + height: e.height, + width: e.width + } + }, doClick: function () { + this.fireEvent("EVENT_CHANGE"), this.store.zoomOut() + } + }); + BI.shortcut("dec.frame.modern.zoom_out_jsdifeh", e) +})(); + +!(function () { + var e = function () { + this.registerCustomPanelMenu = function (e, t) { + BI.config("dec.constant.frame.modern.aside.tabs", function (e) { + return e.concat([t]) + }) + }; + var i = null; + this.$get = function () { + return BI.inherit(BI.OB, { + createCard: function (i) { + var e = BI.Constants.getConstant("dec.constant.workbench.panel.tabs"), + n = {type: "dec.frame.modern.main_cards.flatten_entry_list"}; + return BI.some(e, function (e, t) { + t.value === i && (n = BI.extend({}, t, {type: t.cardType})) + }, this), n + }, registerEntryPaneInstance: function (e) { + i = e + }, behaviour: function (e) { + var t = Array.prototype.slice.call(arguments, 1); + return i[e].apply(i, t) + }, initConfig: function (e) { + BI.config("dec.constant.menu.items", function (e) { + return BI.some(e, function (e, t) { + if ("directory" === t.value) return t.cardType = "dec.frame.modern", !0 + }), e + }), BI.config("dec.provider.tab_pane", function (e) { + // debugger; + e.registerTabPaneComponent({ + buttons: { + left: [{ + type: "dec.frame.modern.zoom_in_jsdifeh", + width: 70, + height: 30 + }] + } + }) + }) + } + }) + } + }; + BI.provider("dec.provider.frame.modern_jsdifeh", e); +})(); + + +!(function () { + var e = BI.inherit(BI.Widget, { + props: {baseCls: "dec-frame-modern", $testId: "dec-frame-modern", resizeable: !0}, _store: function () { + return BI.Models.getModel("dec.model.frame.modern") + }, watch: { + isPin: function (e) { + this.resizer.setResizeable(e) + } + }, created: function () { + BI.Providers.getProvider("dec.provider.frame.modern_jsdifeh").registerEntryPaneInstance(this) + }, render: function () { + var t = this; + this.options; + this._assertZommerRender(); + var e = BI.get(BI.Providers.getProvider("dec.provider.layout").getLayoutConfig(), "config4Frame.center"); + return { + type: "dec.common.drag_resize", + $value: "frame-modern", + ref: function (e) { + t.resizer = e + }, + resizeable: this.model.isPin, + open: this.model.isPin, + leftWidth: e.left.width || 240, + maxSize: e.left.maxSize, + minSize: e.left.minSize, + content: {type: "dec.frame.modern.main_cards", vgap: 10}, + popup: {type: "dec.frame.modern.aside", entryMode: this.model.themeConfig.entryMode}, + listeners: [{ + eventName: "EVENT_RESIZE", action: function (e) { + BI.Cache.setItem(DecCst.Web.Cache.DIRECTORY_WIDTH, e) + } + }] + } + }, _assertZommerRender: function () { + this.tabContainer = BI.createWidget({type: "dec.frame.modern.zoomer"}), BI.createWidget({ + type: "bi.absolute", + element: "#wrapper", + items: [{el: this.tabContainer, top: "100%", left: "100%"}] + }) + }, keepalive: function () { + return !0 + }, beforeDestroy: function () { + this.tabContainer && this.tabContainer.destroy(), Dec.tabPaneModel.openedTabs = [] + } + }); + BI.shortcut("dec.frame.modern_jsdifeh", e); +})(); + + +!(function () { + var i = BI.inherit(BI.Widget, { + props: {baseCls: "dec-frame-tab-pane", $testId: "dec-frame-tab-pane", buttons: {left: [], right: []}}, + _store: function () { + return BI.Models.getModel("dec.model.frame.tab_pane", this.options) + }, + watch: { + tabs: function (e) { + this._populate(e) + }, activeCard: function (e) { + BI.isNull(e) || (this.isCardExisted(e.value) || this._addCardByName(e.value, e), this._showCardByName(e.value, e)) + }, inactiveTabs: function () { + BI.each(this.model.inactiveTabs, function (e, t) { + this._deleteCardByName(t) + }, this) + } + }, + render: function () { + var t = this, e = this.options; + return { + type: "bi.absolute", items: [{ + el: { + type: "dec.frame.tab_pane.card.display", ref: function (e) { + t.cards = e + }, items: BI.isNotNull(this.model.activeCard) ? [this.model.activeCard] : [] + }, left: 0, right: 0, bottom: 0, top: 31 + }, { + el: { + type: "bi.htape", + height: 30, + cls: "dec-frame-tab-pane-tabs-container dec-frame-tab-pane-split-line", + $testId: "dec-frame-tab-pane-tabs-container", + ref: function (e) { + t.header = e + }, + items: e.buttons.left.concat([{ + type: "dec.frame.tab_pane.tabs", + baseCls: "jsdifeh-tabs", + items: this.model.tabs, + ref: function (e) { + t.tabs = e + } + }]).concat(e.buttons.right) + }, top: 0, left: 0, right: 0 + }] + } + }, + _addCardByName: function (e, t) { + this.cards.addCardByName(e, t) + }, + _showCardByName: function (e, t) { + this.cards.showCardByName(e, t), this.tabs.setValue(e) + }, + _deleteCardByName: function (e) { + this.cards.deleteCardByName(e) + }, + _populate: function (e) { + this.tabs.populate(e) + }, + _dealWithTabsFullScreen: function (e) { + var t = this, i = null; + + function n(e) { + BI.isNull(i) && (i = setTimeout(function () { + e() + }, 300)) + } + + function o() { + clearTimeout(i), i = null + } + + e ? (this.cards.element.css({top: 0}), this.header.element.css("opacity", 0), this.header.element.css({top: -29}), this.header.element.hover(function () { + o(), BI.FullScreen.isFullScreen() && n(function () { + t.header.element.css("opacity", 1), t.header.element.css({top: 0}) + }) + }, function () { + o(), n(function () { + BI.FullScreen.isFullScreen() && (t.header.element.css("opacity", 0), t.header.element.css({top: -29})) + }) + })) : (o(), this.header.element.unbind("mouseenter").unbind("mouseleave"), this.header.element.css("opacity", 1), this.header.element.css({top: 0}), this.cards.element.css({top: 31})) + }, + fullscreen: function (e) { + var t = this; + e ? BI.FullScreen.requestFullScreen(this, function (e) { + e && t._dealWithTabsFullScreen(!0) + }, function () { + t._dealWithTabsFullScreen(!1) + }) : BI.FullScreen.isFullScreen() && BI.FullScreen.exitFullScreen() + }, + isCardExisted: function (e) { + return this.cards.isCardExisted(e) + }, + getOpenedTabs: function () { + return this.model.openedTabs + }, + getActiveTab: function () { + return this.model.activeTab + }, + showCardByName: function (e, t) { + this.store.showCardByName(e, t), this.fireEvent(i.EVENT_SHOW, e) + }, + addCardByName: function (e, t) { + this.store.addCardByName(e, t), this.fireEvent(i.EVENT_ADD, e) + }, + closeTabByName: function (e) { + this.store.closeTab(e), this.fireEvent(i.EVENT_CLOSE, e, this.model.activeTab) + }, + refreshCardByName: function (e) { + this.cards.deleteCardByName(e), this._addCardByName(e, this.store.assertCard(e)), e === this.model.activeTab && this._showCardByName(e) + } + }); + i.EVENT_SHOW = "EVENT_SHOW", i.EVENT_ADD = "EVENT_ADD", i.EVENT_CLOSE = "EVENT_CLOSE", BI.shortcut("dec.frame.tab_pane_jsdifeh", i); +})(); + + +!(function () { + var e = BI.inherit(Fix.Model, { + init: function () { + this.openStateMap = {} + }, + state: function () { + return {rootEntries: []} + }, + childContext: ["isPin"], + context: ["entries", "favorites", "selectedCard", "selectedId", "activeTab", "loading", "zoomOut", "themeConfig"], + computed: { + selectedTreeId: function () { + var i = this, n = ""; + return BI.Tree.traversal(this.model.entries, function (e, t) { + if (t.id === i.model.selectedId) return n = t.id, !1 + }), n + }, selectedMenu: function () { + return Dec.globleModel.selectedMenu + }, entryMode: function () { + return this.model.themeConfig.entryMode + } + }, + watch: { + selectedId: function (e) { + BI.isEmptyString(e) && this.initDefaultShowCard() + }, activeTab: function (e) { + this.handleActiveTabChange(e) + }, selectedMenu: function (e) { + "directory" === e && this.initEntryTrees() + } + }, + actions: { + initEntryTrees: function (t) { + var i = this; + this.model.loading = !0, Dec.Utils.getFavoritesList(function (e) { + i.model.favorites = BI.Services.getService("dec.service.frame.entry").normalizeEntries(e.data, !1) + }), Dec.Utils_jsdifeh.getCompleteDirectoryTree(function (e) { + i.model.entries = BI.Tree.transformToTreeFormat(BI.Services.getService("dec.service.frame.entry").normalizeEntries(e.data)), i.initRootEntries(), i.initDefaultShowCard(), i.model.loading = !1, t && t() + }) + }, initRootEntries: function (e) { + var i = []; + BI.Tree.traversal(this.model.entries, function (e, t) { + if (t.id === DecCst.DIRECTORY_TREE_ROOT_ID) return i = t.children || [], !1 + }), this.model.rootEntries = i + }, getRootEntries: function (e) { + e(this._formatItems(this.model.rootEntries, 0)) + }, getSubFoldersByParentId: function (i, e, t) { + var n = []; + BI.Tree.traversal(this.model.entries, function (e, t) { + if (t.id === i) return n = BI.filter(t.children.slice(0), function (e, t) { + return t.entryType === DecCst.Entries.Entry_Type.FOLDER + }), !1 + }), t(this._formatItems(n, e + 1)) + }, selectEntry: function (i) { + BI.isKey(i) && BI.Tree.traversal(this.model.entries, function (e, t) { + if (t.id === i) return i = t, !1 + }), i.entryType !== DecCst.Entries.Entry_Type.FOLDER && (BI.Providers.getProvider("dec.provider.tab_pane").behaviour("addCardByName", i.id, { + text: i.text, + value: i.id, + entry: !0, + entryDetails: i, + cardType: {src: i.iframeSrc} + }), this.zoomOut()), this.model.selectedId = i.id, this.model.selectedCard = BI.extend({ + type: "dec.frame.modern.main_cards.flatten_entry_list", + items: [] + }, i) + }, initDefaultShowCard: function () { + var i = this, n = !1; + BI.Tree.traversal(this.model.entries, function (e, t) { + if (t.id === i.model.selectedId) return !(n = !0) + }), !n && BI.isEmptyObject(Dec.personal.homepage) && BI.isNotEmptyArray(this.model.rootEntries) ? this._dealFirstRootEntry() : BI.isNotNull(this.model.selectedCard.entryType) && BI.isNotEmptyArray(this.model.rootEntries) && (n || this._dealFirstRootEntry()) + }, handleActiveTabChange: function (i) { + var n, o, s = this; + BI.each(this.model.rootEntries, function (e, t) { + t.id === i && (n = !0), t.id === s.model.selectedId && t.entryType !== DecCst.Entries.Entry_Type.FOLDER && (o = !0) + }), BI.isKey(i) && i !== DecCst.Web.Frame.Tab.PLATFORM_HOME_TAB_ID ? n && (this.model.selectedId = i) : o && (this.model.selectedId = "") + }, zoomOut: function () { + this.model.zoomOut = BI.UUID() + }, expandNode: function (e) { + this.openStateMap[e] = !0 + }, collapseNode: function (e) { + this.openStateMap[e] = !1 + } + }, + _formatItems: function (e, o) { + var s = this, e = BI.deepClone(e), r = "tree" === this.model.entryMode; + return BI.each(e, function (e, t) { + var i = r && BI.some(t.children, function (e, t) { + return t.entryType === DecCst.Entries.Entry_Type.FOLDER + }); + delete t.children; + var n = { + layer: o, + $testId: "dec-common-img-icon-text-item", + $value: o + "-" + t.text, + height: DecCst.Entry_Node_Size.HEIGHT, + value: t.id, + selected: t.id === s.model.selectedId, + forceSelected: !0 + }; + BI.isNotNull(s.openStateMap[t.id]) && (n.open = !!s.openStateMap[t.id]), i ? (t.isParent = !0, n.type = "dec.common.img.select_icon_text_node") : (t.isParent = !1, n.type = "dec.common.img.icon_text_item"), n.cls = "dec-frame-platform-list-item-active dec-font-size-14", BI.extend(t, n) + }), e + }, + _dealFirstRootEntry: function () { + var e = this.model.rootEntries[0]; + e.entryType === DecCst.Entries.Entry_Type.FOLDER ? this.selectEntry(e) : this.model.selectedCard = BI.extend({ + type: "dec.frame.modern.main_cards.flatten_entry_list", + items: [] + }) + } + }); + BI.model("dec.model.frame.modern.aside.root_entry_list_jsdifeh", e) +})(); + +!(function () { + var e = BI.inherit(BI.Widget, { + props: {baseCls: "", $testId: "dec-frame-modern-aside-root-entry-list"}, _store: function () { + return BI.Models.getModel("dec.model.frame.modern.aside.root_entry_list_jsdifeh", this.options) + }, watch: { + selectedTreeId: function (e) { + this.entry.setValue(e) + }, rootEntries: function () { + this.populate() + } + }, beforeInit: function (e) { + this.store.initEntryTrees(e) + }, render: function () { + var n = this; + this.options; + return "flatten" !== this.model.entryMode && this.model.entryMode ? { + type: "bi.custom_tree", + ref: function (e) { + n.entry = e + }, + expander: {type: "bi.select_tree_expander", isDefaultInit: !1, el: {}, popup: {type: "bi.custom_tree"}}, + el: { + type: "bi.loader", + next: !1, + el: {type: "bi.button_tree", chooseType: -2, layouts: [{type: "bi.vertical"}]} + }, + itemsCreator: function (e, t) { + e.node ? n.store.getSubFoldersByParentId(e.node.id, e.node.layer, function (e) { + t(e) + }) : n.store.getRootEntries(function (e) { + t(e) + }) + }, + listeners: [{ + eventName: BI.Controller.EVENT_CHANGE, action: function (e, t, i) { + e === BI.Events.EXPAND && n.store.expandNode(t), e === BI.Events.COLLAPSE && n.store.collapseNode(t), e === BI.Events.CLICK && n.store.selectEntry(t) + } + }] + } : this._createList() + }, _createList: function () { + var i = this; + this.options; + return { + type: "bi.vertical", + cls: "bi-border-top dec-frame-split-border1", + vgap: 10, + items: [{ + el: { + type: "bi.loader", + ref: function (e) { + i.entry = e + }, + next: !1, + el: {type: "bi.button_group", layouts: [{type: "bi.vertical"}]}, + itemsCreator: function (e, t) { + i.store.getRootEntries(function (e) { + t(e) + }) + }, + listeners: [{ + eventName: BI.Controller.EVENT_CHANGE, action: function (e, t) { + i.store.selectEntry(t) + } + }] + } + }] + } + }, populate: function () { + this.entry.populate() + } + }); + BI.shortcut("dec.frame.modern.aside.root_entry_list_jsdifeh", e) +})(); + +!(function () { + + BI.config("dec.frame.modern.aside.root_entry_list", function (config) { + //config.type = "dec.frame.modern.aside.root_entry_list_jsdifeh"; + return config; + }) + + BI.config("dec.frame.tab_pane", function (config) { + config.type = "dec.frame.tab_pane_jsdifeh"; + return config; + }) + + BI.config("dec.frame.modern.main_cards.section", function (config) { + config.type = "dec.frame.modern.main_cards.section_jsdifeh"; + return config; + }); + + BI.config("dec.frame.modern.zoom_in", function (config) { + config.type = "dec.frame.modern.zoom_in_jsdifeh"; + return config; + }); + + BI.config("dec.frame.modern.zoom_out", function (config) { + config.type = "dec.frame.modern.zoom_out_jsdifeh"; + return config; + }); + + //BI.config("dec.frame.modern", function (config) { + // config.type = "dec.frame.modern_jsdifeh"; + // return config; + //}); + + //BI.config("dec.provider.tab_pane", function (e) { + // debugger; + // console.log(e); + //e.registerTabPaneComponent = registerTabPaneComponent_jsdifeh; + // }); + + + function registerTabPaneComponent_jsdifeh(e) { + //debugger; + if (e.buttons && e.buttons.left && Array.isArray(e.buttons.left) && (e.buttons.left.length >= 1) && ("dec.frame.modern.zoom_in" == e.buttons.left[0].type)) { + e.buttons.left[0].type = "dec.frame.modern.zoom_in_jsdifeh"; + e.buttons.left[0].width = 70; + } + var t = { + type: "dec.frame.tab_pane", + buttons: { + left: [], + right: [{ + type: "dec.frame.tab_pane.down_list", + width: 30, + height: 30 + }] + } + } + BI.deepExtend(t, e) + } + +})(); + + +!(function () { + var ICON_WIDTH = 35, LABEL_WIDTH = 180; + var color = BI.inherit(BI.Widget, { + props: { + //baseCls: "dec-system-extensible-parameter", + value: {} + }, + + render: function () { + var self = this, v = this.options.value; + return { + type: "bi.vertical_adapt", + items: [{ + type: "bi.label", + textAlign: "left", + cls: "dec-font-weight-bold", + text: BI.i18nText(v.name), + width: 210 + }, { + type: "bi.simple_color_chooser", + height: 22, + width: 180, + value: this._formatValue(v.value), + ref: function (_ref) { + self.colorChooser = _ref; + } + }, { + type: "dec.text.bubble.combo", + cls: "help-area", + invisible: !v.description, + text: v.description ? BI.i18nText(v.description) : "", + el: { + type: "bi.icon_button", + $point: "dec-system-normal-extensible", + cls: "detail-font", + width: 35, + height: 24 + } + } + + + /*{ + type: "bi.icon_button", + invisible: !v.description, + title: v.description ? BI.i18nText(v.description) : "", + cls: "detail-font", + width: ICON_WIDTH, + height: 24, + lgap: 116 + }*/ + ] + }; + }, + getValue: function () { + //debugger; + var value = this.colorChooser.getValue(); + var color = this._getColor(value); + color.alpha = 255; + color.transparency = 1; + color.rgb = this._getRgbValue(color.red, color.green, color.blue, color.alpha); + return color.rgb; + }, + + _getRgbValue: function (r, g, b, a) { + var v = ((a & 0xFF) << 24) | + ((r & 0xFF) << 16) | + ((g & 0xFF) << 8) | + ((b & 0xFF) << 0); + return v; + }, + _getColor: function (sColor) { + sColor = sColor.toLowerCase(); + //十六进制颜色值的正则表达式 + var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6})$/; + // 如果是16进制颜色 + if (sColor && reg.test(sColor)) { + if (sColor.length === 4) { + var sColorNew = "#"; + for (var i = 1; i < 4; i += 1) { + sColorNew += sColor.slice(i, i + 1).concat(sColor.slice(i, i + 1)); + } + sColor = sColorNew; + } + //处理六位的颜色值 + var sColorChange = []; + for (var i = 1; i < 7; i += 2) { + sColorChange.push(parseInt("0x" + sColor.slice(i, i + 2))); + } + //return "RGB(" + sColorChange.join(",") + ")"; + var color = {red: sColorChange[0], green: sColorChange[1], blue: sColorChange[2]}; + return color; + } + return sColor; + }, + _formatValue: function (v) { + //debugger; + var red = v.red; + var green = v.green; + var blue = v.blue; + var value = '#' + this._hexValue(red) + this._hexValue(green) + this._hexValue(blue); + value = value.toLowerCase(); + return value; + }, + _hexValue: function (v) { + var tempValue = v.toString(16); + if (tempValue.length <= 1) { + tempValue = '0' + tempValue; + } + return tempValue; + } + }); + BI.shortcut("dec.system.normal.extensible.color_jsdifeh", color); +})(); + + +!(function () { + + BI.config("dec.constant.system.normal.extensible.type", function (items) { + items.push({ + value: "java.awt.Color", // 新增的类型 + cardType: "dec.system.normal.extensible.color_jsdifeh" // 新增类型对应的组件 + }); + return items; + }); + +})(); \ No newline at end of file diff --git a/扁平化主题菜单定制插件.pdf b/扁平化主题菜单定制插件.pdf new file mode 100644 index 0000000..c58d66d Binary files /dev/null and b/扁平化主题菜单定制插件.pdf differ