diff --git a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java index 3d36e563c..b7df52c30 100644 --- a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java +++ b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java @@ -10,18 +10,16 @@ import com.fr.stable.xml.XMLPrintWriter; import com.fr.stable.xml.XMLReadable; import com.fr.stable.xml.XMLable; import com.fr.stable.xml.XMLableReader; -import java.util.Arrays; -import java.util.HashSet; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Set; -import java.util.Stack; import org.jetbrains.annotations.NotNull; -import javax.swing.*; +import javax.swing.KeyStroke; import java.util.Collections; import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.Map; +import java.util.Set; +import java.util.Stack; /** * AlphaFine配置类 @@ -54,13 +52,17 @@ public class AlphaFineConfigManager implements XMLable { */ private boolean containRecommend = true; /** - * 设置 + * 功能 */ private boolean containAction = true; /** * 帮助文档 */ private boolean containDocument = true; + /** + * 我的模板 + * */ + private boolean containMyTemplate = true; /** * 模板 */ @@ -70,7 +72,7 @@ public class AlphaFineConfigManager implements XMLable { */ private boolean containFileContent; /** - * 应用中心 + * 插件中心 */ private boolean containPlugin = true; /** @@ -95,6 +97,11 @@ public class AlphaFineConfigManager implements XMLable { */ private boolean productDynamics = true; + /** + * 模板商城是否展示 + * */ + private boolean showTemplateShop = true; + private Map actionSearchTextCache = new HashMap<>(8); private String cacheBuildNO; @@ -326,6 +333,14 @@ public class AlphaFineConfigManager implements XMLable { this.containDocument = containDocument; } + public void setContainMyTemplate(boolean containMyTemplate) { + this.containMyTemplate = containMyTemplate; + } + + public boolean isContainMyTemplate() { + return containMyTemplate; + } + public boolean isContainTemplate() { return containTemplate; } @@ -446,6 +461,14 @@ public class AlphaFineConfigManager implements XMLable { return productDynamics && FRContext.isChineseEnv(); } + public boolean hasTemplateShop() { + return showTemplateShop && FRContext.isChineseEnv(); + } + + public void setShowTemplateShop(boolean showTemplateShop) { + this.showTemplateShop = showTemplateShop; + } + public void setProductDynamics(boolean productDynamics) { this.productDynamics = productDynamics; } diff --git a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigPane.java b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigPane.java index 55d467e88..fa0f4a8f0 100644 --- a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigPane.java +++ b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigPane.java @@ -1,17 +1,29 @@ package com.fr.design.actions.help.alphafine; import com.fr.base.FRContext; +import com.fr.base.svg.IconUtils; import com.fr.design.DesignerEnvManager; import com.fr.design.dialog.BasicPane; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.imenu.UIPopupMenu; import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.utils.gui.GUICoreUtils; import com.fr.log.FineLoggerFactory; -import javax.swing.*; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.KeyStroke; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; @@ -25,14 +37,22 @@ import java.awt.event.MouseEvent; public class AlphaFineConfigPane extends BasicPane { private static final String TYPE = "pressed"; private static final String DISPLAY_TYPE = "+"; + private static final Color LABEL_TEXT = new Color(0x919193); - - private static final double COLUMN_GAP = 180; - private static final double ROW_GAP = 25; + private static final double COLUMN_WIDTH = 150; + private static final double ROW_HEIGHT = 25; private KeyStroke shortCutKeyStore = null; - private UICheckBox enabledCheckbox, searchOnlineCheckbox, needSegmentationCheckbox, needIntelligentCustomerService, productDynamicsCheckbox, containActionCheckbox, containDocumentCheckbox, containTemplateCheckbox, containPluginCheckbox, containFileContentCheckbox; + private UICheckBox enabledCheckbox, searchOnlineCheckbox, needSegmentationCheckbox; + private UICheckBox productDynamicsCheckbox, containTemplateShopCheckbox, containDocumentCheckbox, + containPluginCheckbox, containActionCheckbox, containMyTemplateCheckbox; private UITextField shortcutsField; + // 搜索范围-我的模板,相关组件 + private JPanel containMyTemplatePane; + private JButton myTemplateSearchConfigButton; + private UIPopupMenu myTemplateSearchMenu; + private UICheckBox containTemplateNameSearchCheckbox, containFileContentSearchCheckbox; + public AlphaFineConfigPane() { this.initComponents(); } @@ -45,15 +65,6 @@ public class AlphaFineConfigPane extends BasicPane { createSearchConfigPane(contentPane); this.setLayout(FRGUIPaneFactory.createBorderLayout()); this.add(contentPane, BorderLayout.NORTH); - - } - - private Component[][] initSearchRangeComponents() { - Component[][] components = new Component[][]{ - new Component[]{productDynamicsCheckbox, containActionCheckbox, containDocumentCheckbox}, - new Component[]{containTemplateCheckbox, containPluginCheckbox, containFileContentCheckbox}, - }; - return components; } private Component[][] initOnlineComponents() { @@ -63,24 +74,99 @@ public class AlphaFineConfigPane extends BasicPane { return components; } + // 搜索范围 private void createSearchConfigPane(JPanel contentPane) { - double[] rowSize = {ROW_GAP, ROW_GAP, ROW_GAP}; - - double[] columnSize = {COLUMN_GAP, COLUMN_GAP, COLUMN_GAP}; + double[] rowSize = {ROW_HEIGHT, ROW_HEIGHT, ROW_HEIGHT}; + double[] columnSize = {COLUMN_WIDTH, COLUMN_WIDTH, COLUMN_WIDTH}; JPanel northPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_AlphaFine_Search_Range")); - productDynamicsCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_Dynamics")); - containActionCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Set")); + productDynamicsCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_News")); + containActionCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Function")); containPluginCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Plugin_Addon")); containDocumentCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Community_Help")); - containTemplateCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Templates")); - containFileContentCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Templates_Content")); - needIntelligentCustomerService = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_AlphaFine_Intelligent_Customer_Service")); + containMyTemplateCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_My_Templates")); + containFileContentSearchCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Templates_Content")); + containTemplateShopCheckbox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Shop")); + containMyTemplateCheckbox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_My_Templates")); JPanel searchConfigPane = TableLayoutHelper.createTableLayoutPane(initSearchRangeComponents(), rowSize, columnSize); northPane.add(searchConfigPane); contentPane.add(northPane); } + private Component[][] initSearchRangeComponents() { + // 我的模板checkbox设置,点击后 + initMyTemplateSearchPane(); + + Component[][] components = new Component[][]{ + new Component[]{productDynamicsCheckbox, containTemplateShopCheckbox, containDocumentCheckbox}, + new Component[]{containPluginCheckbox, containActionCheckbox, containMyTemplatePane}, + }; + + for (int i = 0; i < components.length; i++) { + for (int j = 0; j < components[i].length; j++) { + if (components[i][j] instanceof UICheckBox) { + UICheckBox box = (UICheckBox) components[i][j]; + } + } + } + return components; + } + + /** + * 【搜索范围】中的复选框有无选中的 + * */ + private boolean hasSelectedSearchRangeCheckBox() { + return productDynamicsCheckbox.isSelected() || containTemplateShopCheckbox.isSelected() || containDocumentCheckbox.isSelected() + || containPluginCheckbox.isSelected() || containActionCheckbox.isSelected() || containMyTemplateCheckbox.isSelected(); + } + + // 搜索范围-我的模板 + private void initMyTemplateSearchPane() { + containMyTemplatePane = new JPanel(new FlowLayout(FlowLayout.LEFT,4,5)); + containMyTemplateCheckbox.setBorder(BorderFactory.createEmptyBorder()); + containMyTemplateCheckbox.addActionListener( + new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (containMyTemplateCheckbox.isSelected()) { + myTemplateSearchConfigButton.setVisible(true); + } else { + myTemplateSearchConfigButton.setVisible(false); + } + } + } + ); + myTemplateSearchConfigButton = new JButton(); + myTemplateSearchConfigButton.setBorder(BorderFactory.createEmptyBorder()); + myTemplateSearchConfigButton.setMargin(new Insets(0,0,0,0)); + myTemplateSearchConfigButton.setIcon(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/config.svg")); + myTemplateSearchMenu = new UIPopupMenu(); + containTemplateNameSearchCheckbox = new UICheckBox(Toolkit.i18nText("Fine-Design_AlphaFine_Config_Name_Search")); + containFileContentSearchCheckbox = new UICheckBox(Toolkit.i18nText("Fine-Design_AlphaFine_Config_Content_Search")); + containTemplateNameSearchCheckbox.setSelected(true); + containTemplateNameSearchCheckbox.setEnabled(false); + containTemplateNameSearchCheckbox.setBackground(null); + containFileContentSearchCheckbox.setBackground(null); + myTemplateSearchMenu.add(containTemplateNameSearchCheckbox); + myTemplateSearchMenu.add(containFileContentSearchCheckbox); + myTemplateSearchConfigButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + GUICoreUtils.showPopupMenu(myTemplateSearchMenu, containMyTemplatePane, containMyTemplateCheckbox.getWidth(), containMyTemplatePane.getY()); + } + + @Override + public void mouseMoved(MouseEvent e) { + super.mouseMoved(e); + myTemplateSearchMenu.setVisible(false); + } + }); + containMyTemplatePane.add("containMyTemplateCheckbox", containMyTemplateCheckbox); + containMyTemplatePane.add("myTemplateSearchConfigButton", myTemplateSearchConfigButton); + } + + private void createShortcutsPane(JPanel contentPane) { JPanel northPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_AlphaFine_Shortcut_Config")); shortcutsField = new UITextField(); @@ -91,7 +177,7 @@ public class AlphaFineConfigPane extends BasicPane { northPane.add(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Open") + ":")); northPane.add(shortcutsField); UILabel label = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_AlphaFine_SetShortcuts")); - label.setForeground(Color.RED); + label.setForeground(LABEL_TEXT); northPane.add(label); contentPane.add(northPane); } @@ -130,21 +216,21 @@ public class AlphaFineConfigPane extends BasicPane { productDynamicsCheckbox.setEnabled(false); containPluginCheckbox.setEnabled(false); containDocumentCheckbox.setEnabled(false); - needIntelligentCustomerService.setEnabled(false); + containTemplateShopCheckbox.setEnabled(false); productDynamicsCheckbox.setSelected(false); containPluginCheckbox.setSelected(false); containDocumentCheckbox.setSelected(false); - needIntelligentCustomerService.setSelected(false); + containTemplateShopCheckbox.setSelected(false); } else { productDynamicsCheckbox.setEnabled(true); containPluginCheckbox.setEnabled(true); containDocumentCheckbox.setEnabled(true); - needIntelligentCustomerService.setEnabled(true); + containTemplateShopCheckbox.setEnabled(true); } } }); - double[] rowSize = {ROW_GAP}; - double[] columnSize = {COLUMN_GAP, COLUMN_GAP, COLUMN_GAP}; + double[] rowSize = {ROW_HEIGHT}; + double[] columnSize = {COLUMN_WIDTH, COLUMN_WIDTH, COLUMN_WIDTH}; JPanel onlinePane = TableLayoutHelper.createTableLayoutPane(initOnlineComponents(), rowSize, columnSize); northPane.add(onlinePane); contentPane.add(northPane); @@ -172,8 +258,10 @@ public class AlphaFineConfigPane extends BasicPane { this.searchOnlineCheckbox.setSelected(enabled4Locale); this.containActionCheckbox.setSelected(alphaFineConfigManager.isContainAction()); - this.containTemplateCheckbox.setSelected(alphaFineConfigManager.isContainTemplate()); - this.containFileContentCheckbox.setSelected(alphaFineConfigManager.isContainFileContent()); + + this.containMyTemplateCheckbox.setSelected(alphaFineConfigManager.isContainMyTemplate()); + this.myTemplateSearchConfigButton.setVisible(alphaFineConfigManager.isContainMyTemplate()); + this.containFileContentSearchCheckbox.setSelected(alphaFineConfigManager.isContainFileContent()); this.containDocumentCheckbox.setSelected(alphaFineConfigManager.isContainDocument() && enabled4Locale); this.containDocumentCheckbox.setEnabled(enabled4Locale); @@ -184,13 +272,13 @@ public class AlphaFineConfigPane extends BasicPane { this.productDynamicsCheckbox.setSelected(alphaFineConfigManager.isProductDynamics() && enabled4Locale); this.productDynamicsCheckbox.setEnabled(enabled4Locale); + this.containTemplateShopCheckbox.setSelected(alphaFineConfigManager.hasTemplateShop() && enabled4Locale); + this.containTemplateShopCheckbox.setEnabled(enabled4Locale); + this.shortcutsField.setText(AlphaFineShortCutUtil.getDisplayShortCut(alphaFineConfigManager.getShortcuts())); this.needSegmentationCheckbox.setSelected(alphaFineConfigManager.isNeedSegmentationCheckbox()); - this.needIntelligentCustomerService.setSelected(alphaFineConfigManager.isNeedIntelligentCustomerService() && enabled4Locale); - this.needIntelligentCustomerService.setEnabled(enabled4Locale); - shortCutKeyStore = convert2KeyStroke(alphaFineConfigManager.getShortcuts()); } @@ -201,12 +289,12 @@ public class AlphaFineConfigPane extends BasicPane { alphaFineConfigManager.setContainAction(this.containActionCheckbox.isSelected()); alphaFineConfigManager.setContainDocument(this.containDocumentCheckbox.isSelected()); alphaFineConfigManager.setProductDynamics(this.productDynamicsCheckbox.isSelected()); + alphaFineConfigManager.setShowTemplateShop(this.containTemplateShopCheckbox.isSelected()); alphaFineConfigManager.setEnabled(this.enabledCheckbox.isSelected()); alphaFineConfigManager.setSearchOnLine(this.searchOnlineCheckbox.isSelected()); - alphaFineConfigManager.setContainTemplate(this.containTemplateCheckbox.isSelected()); - alphaFineConfigManager.setContainFileContent(this.containFileContentCheckbox.isSelected()); + alphaFineConfigManager.setContainMyTemplate(this.containMyTemplateCheckbox.isSelected()); + alphaFineConfigManager.setContainFileContent(this.containFileContentSearchCheckbox.isSelected()); alphaFineConfigManager.setNeedSegmentationCheckbox(this.needSegmentationCheckbox.isSelected()); - alphaFineConfigManager.setNeedIntelligentCustomerService(this.needIntelligentCustomerService.isSelected()); alphaFineConfigManager.setShortcuts(shortCutKeyStore != null ? shortCutKeyStore.toString().replace(TYPE, DISPLAY_TYPE) : this.shortcutsField.getText()); designerEnvManager.setAlphaFineConfigManager(alphaFineConfigManager); try { @@ -233,10 +321,10 @@ public class AlphaFineConfigPane extends BasicPane { } public UICheckBox getIsContainFileContentCheckbox() { - return containFileContentCheckbox; + return containFileContentSearchCheckbox; } public void setIsContainFileContentCheckbox(UICheckBox isContainFileContentCheckbox) { - this.containFileContentCheckbox = isContainFileContentCheckbox; + this.containFileContentSearchCheckbox = isContainFileContentCheckbox; } } diff --git a/designer-base/src/main/java/com/fr/design/components/tooltip/ModernToolTip.java b/designer-base/src/main/java/com/fr/design/components/tooltip/ModernToolTip.java index 0a01f8bbf..5125c0027 100644 --- a/designer-base/src/main/java/com/fr/design/components/tooltip/ModernToolTip.java +++ b/designer-base/src/main/java/com/fr/design/components/tooltip/ModernToolTip.java @@ -12,11 +12,9 @@ import javax.swing.plaf.ToolTipUI; import java.awt.Color; import java.awt.Dimension; import java.awt.FontMetrics; -import java.awt.GradientPaint; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; -import java.awt.geom.GeneralPath; import java.io.BufferedReader; import java.io.IOException; import java.io.StringReader; @@ -52,7 +50,7 @@ public class ModernToolTip extends UIToolTip { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setColor(new Color(51, 51, 52, (int) Math.round(0.7 * 255))); - g2.fillRoundRect(0, 0, width, height, 0, 0); + g2.fillRoundRect(0, 0, width, height, 4, 4); g2.setColor(Color.WHITE); if (strs != null) { diff --git a/designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java b/designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java index 67e68b969..3dbcf8187 100644 --- a/designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java +++ b/designer-base/src/main/java/com/fr/design/data/BasicTableDataTreePane.java @@ -4,7 +4,6 @@ import com.fr.base.BaseUtils; import com.fr.base.TableData; import com.fr.data.MultiResultTableData; import com.fr.data.TableDataSource; -import com.fr.data.api.StoreProcedureAssist; import com.fr.design.DesignModelAdapter; import com.fr.design.actions.UpdateAction; import com.fr.design.data.datapane.TableDataCreatorProducer; @@ -184,7 +183,7 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp private boolean isIncludeUnderline(String name) { - return ComparatorUtils.equals(name.indexOf(StoreProcedureAssist.GROUP_MARKER), -1) ? false : true; + return ComparatorUtils.equals(name.indexOf(MultiResultTableData.GROUP_MARKER), -1) ? false : true; } public abstract void addDataPane(final AbstractTableDataPane uPanel, String paneName); @@ -445,7 +444,7 @@ public abstract class BasicTableDataTreePane extends DockingView implements Resp ((MultiResultTableData) (((TableDataWrapper) data).getTableData())).resetDataModelList(); if (data instanceof MultiResultTableDataWrapper) { MultiResultTableDataWrapper oldSdw = ((MultiResultTableDataWrapper) data); - MultiResultTableDataWrapper newSdw = new MultiResultTableDataWrapper((MultiResultTableData) oldSdw.getTableData(), oldSdw.getTableDataName(), oldSdw.getTableDataName()); + MultiResultTableDataWrapper newSdw = new MultiResultTableDataWrapper((MultiResultTableData) oldSdw.getTableData(), oldSdw.getTableDataName(), oldSdw.getDataModelName()); newSdw.previewData(MultiResultTableDataWrapper.PREVIEW_ONE); } else { MultiResultTableData tableData = (MultiResultTableData) ((TableDataWrapper) data).getTableData(); diff --git a/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java b/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java index bc18dd8a3..35a539a50 100644 --- a/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java +++ b/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java @@ -9,8 +9,10 @@ import com.fr.data.TableDataSourceTailor; import com.fr.data.core.DataCoreXmlUtils; import com.fr.data.impl.EmbeddedTableData; import com.fr.data.impl.NameDataModel; +import com.fr.data.impl.storeproc.ProcedureDataModel; import com.fr.data.impl.storeproc.StoreProcedure; import com.fr.data.impl.storeproc.StoreProcedureConstants; +import com.fr.data.impl.storeproc.StoreProcedureHelper; import com.fr.data.operator.DataOperator; import com.fr.design.DesignModelAdapter; import com.fr.design.data.datapane.preview.PreviewTablePane; @@ -322,9 +324,8 @@ public abstract class DesignTableDataManager { public static java.util.Map getAllDataSetIncludingProcedure(java.util.Map resMap) { java.util.LinkedHashMap dsMap = new java.util.LinkedHashMap(); - Iterator> entryIt = resMap.entrySet().iterator(); - while (entryIt.hasNext()) { - String key = entryIt.next().getKey(); + for (Entry entry : resMap.entrySet()) { + String key = entry.getKey(); TableDataWrapper tableDataWrapper = resMap.get(key); if (tableDataWrapper.getTableData() instanceof MultiResultTableData) { MultiResultTableData tableData = (MultiResultTableData) tableDataWrapper.getTableData(); @@ -333,9 +334,10 @@ public abstract class DesignTableDataManager { TableDataWrapper tdw = new MultiResultTableDataNameWrapper(name + "_Table", tableData); boolean hasSchemaOrResult = false; + // 存储过程的特殊处理,还有其它名称 if (tableData instanceof StoreProcedure) { StoreProcedure storeProcedure = (StoreProcedure) tableData; - StoreProcedureParameter[] parameters = StoreProcedure.getSortPara(storeProcedure.getParameters()); + StoreProcedureParameter[] parameters = StoreProcedureHelper.getSortPara(storeProcedure.getParameters()); for (StoreProcedureParameter parameter : parameters) { if (parameter.getSchema() != StoreProcedureConstants.IN) { @@ -345,20 +347,21 @@ public abstract class DesignTableDataManager { hasSchemaOrResult = true; } } - } else { - for (NameDataModel nameDataModel : tableData.getDataModelList()) { - String dmName = name + "_" + nameDataModel.getName(); - dsMap.put(nameDataModel.getName(), new MultiResultTableDataWrapper(tableData, name, dmName, false)); + } /*else { + // TODO getDataModelList是空的 + for (String n : tableData.getResultNames()) { + String dmName = name + "_" + n; + dsMap.put(n, new MultiResultTableDataWrapper(tableData, name, dmName, false)); } - } + }*/ if (!resultNames.isEmpty()) { hasSchemaOrResult = true; - for (int i = 0; i < resultNames.size(); i++) { - String parameterName = name + "_" + resultNames.get(i); - TableDataWrapper newTwd = new MultiResultTableDataWrapper(tableData, name, parameterName, false); - dsMap.put(parameterName, newTwd); + for (String resultName : resultNames) { + String dmName = name + "_" + resultName; + TableDataWrapper newTwd = new MultiResultTableDataWrapper(tableData, name, dmName, false); + dsMap.put(dmName, newTwd); } } @@ -621,8 +624,8 @@ public abstract class DesignTableDataManager { XMLPrintWriter writer = XMLPrintWriter.create(out); // 把storeProcedure写成xml文件到out DataCoreXmlUtils.writeXMLStoreProcedure(writer, storeProcedure, null); - if (storeProcedure.getDataModelSize() > 0 && !storeProcedure.isFirstExpand()) { - return storeProcedure.creatLazyDataModel(); + if (storeProcedure.getDataModelList().size() > 0 && !storeProcedure.isFirstExpand()) { + return storeProcedure.getDataModelList().toArray(new ProcedureDataModel[0]); } ParameterProvider[] inParameters = DataOperator.getInstance().getStoreProcedureParameters(storeProcedure); diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java index 4219f18c4..264a93799 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java @@ -5,7 +5,6 @@ import com.fr.base.TableDataBean; import com.fr.config.RemoteConfigEvent; import com.fr.data.MultiResultTableData; import com.fr.data.TableDataSource; -import com.fr.data.api.StoreProcedureAssist; import com.fr.design.data.BasicTableDataUtils; import com.fr.design.data.DesignTableDataManager; import com.fr.design.dialog.FineJOptionPane; @@ -137,7 +136,7 @@ public class TableDataPaneListPane extends JListControlPane implements TableData } private boolean isIncludeUnderline(String name) { - return name.contains(StoreProcedureAssist.GROUP_MARKER); + return name.contains(MultiResultTableData.GROUP_MARKER); } /** diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataSourceOP.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataSourceOP.java index d9ec4bb82..61c578453 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataSourceOP.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataSourceOP.java @@ -4,9 +4,9 @@ import com.fr.base.StoreProcedureParameter; import com.fr.base.TableData; import com.fr.data.MultiResultTableData; import com.fr.data.TableDataSource; -import com.fr.data.impl.NameDataModel; import com.fr.data.impl.storeproc.StoreProcedure; import com.fr.data.impl.storeproc.StoreProcedureConstants; +import com.fr.data.impl.storeproc.StoreProcedureHelper; import com.fr.design.DesignModelAdapter; import com.fr.design.data.DesignTableDataManager; import com.fr.design.data.tabledata.wrapper.MultiResultTableDataNameWrapper; @@ -203,7 +203,7 @@ public class TableDataSourceOP implements UserObjectOP { if (tableData instanceof StoreProcedure) { StoreProcedure storeProcedure = (StoreProcedure) tableData; - StoreProcedureParameter[] parameters = StoreProcedure.getSortPara(storeProcedure.getParameters()); + StoreProcedureParameter[] parameters = StoreProcedureHelper.getSortPara(storeProcedure.getParameters()); for (StoreProcedureParameter parameter : parameters) { if (parameter.getSchema() != StoreProcedureConstants.IN) { if (!nodeName.contains(parameter.getName())) { @@ -217,7 +217,7 @@ public class TableDataSourceOP implements UserObjectOP { } } } - } else { + } /*else { if (tableData.getDataModelList().size() > 1) { for (NameDataModel nameDataModel : tableData.getDataModelList()) { if (!nodeName.contains(nameDataModel.getName())) { @@ -231,7 +231,7 @@ public class TableDataSourceOP implements UserObjectOP { } } } - } + }*/ if (!resultNames.isEmpty()) { diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTree.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTree.java index 619c02746..e8ac19fd0 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTree.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTree.java @@ -379,7 +379,7 @@ public class TableDataTree extends UserObjectRefreshJTree { return false; } Object userObject = treeNode.getUserObject(); - if (userObject instanceof NameObject && ((NameObject) userObject).getObject() instanceof AbstractTableDataWrapper) { + if (userObject instanceof NameObject && ((NameObject) userObject).getObject() instanceof TableDataWrapper) { return true; } return false; diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java index 0df8c112d..880cccd2d 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java @@ -3,7 +3,6 @@ package com.fr.design.data.datapane; import com.fr.base.TableData; import com.fr.data.MultiResultTableData; import com.fr.data.TableDataSource; -import com.fr.data.api.StoreProcedureAssist; import com.fr.data.impl.DBTableData; import com.fr.data.impl.TableDataSourceDependent; import com.fr.design.DesignModelAdapter; @@ -522,7 +521,7 @@ public class TableDataTreePane extends BasicTableDataTreePane { private boolean isIncludeUnderline(String name) { - return !ComparatorUtils.equals(name.indexOf(StoreProcedureAssist.GROUP_MARKER), -1); + return !ComparatorUtils.equals(name.indexOf(MultiResultTableData.GROUP_MARKER), -1); } @Override diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java index 330c604d5..5926dcb2d 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/preview/PreviewTablePane.java @@ -8,7 +8,6 @@ import com.fr.base.TableData; import com.fr.data.TableDataSource; import com.fr.data.impl.DBTableData; import com.fr.data.impl.EmbeddedTableData; - import com.fr.data.impl.NameDataModel; import com.fr.data.operator.DataOperator; import com.fr.design.DesignerEnvManager; @@ -65,7 +64,7 @@ import java.util.concurrent.CancellationException; */ public class PreviewTablePane extends BasicPane { private TableData tableData; - private NameDataModel dataModel; + private DataModel dataModel; private UINumberField maxPreviewNumberField; private UINumberField currentRowsField; private JTable preveiwTable; @@ -156,7 +155,7 @@ public class PreviewTablePane extends BasicPane { try { populate(tableData); if (dataModel != null) { - populateStoreDataSQL(); + setRowsLimitTableModel(); } } catch (Exception e1) { } @@ -426,6 +425,7 @@ public class PreviewTablePane extends BasicPane { * * @param storeProcedureDataModel storeProcedureDataModel */ + @Deprecated public static void previewStoreData(NameDataModel storeProcedureDataModel) { previewStoreData(storeProcedureDataModel, -1, -1); } @@ -437,13 +437,30 @@ public class PreviewTablePane extends BasicPane { * @param keyIndex 实际值 * @param valueIndex 显示值 */ + @Deprecated public static void previewStoreData(final NameDataModel storeProcedureDataModel, final int keyIndex, final int valueIndex) { + previewDataModel(storeProcedureDataModel, keyIndex, valueIndex); + } + + public static void previewDataModel(DataModel dataModel) { + previewDataModel(dataModel, -1, -1); + } + + + /** + * 直接预览数据集的结果集 + * + * @param dataModel 结果集 + * @param keyIndex + * @param valueIndex + */ + public static void previewDataModel(final DataModel dataModel, final int keyIndex, final int valueIndex) { final PreviewTablePane previewTablePane = new PreviewTablePane(); - previewTablePane.dataModel = storeProcedureDataModel; + previewTablePane.dataModel = dataModel; previewTablePane.setBorder(BorderFactory.createTitledBorder(Toolkit.i18nText("Fine-Design_Basic_Data"))); try { - previewTablePane.populateStoreDataSQL(); + previewTablePane.setRowsLimitTableModel(); previewTablePane.resetPreviewTableColumnColor(); if (keyIndex > -1) { @@ -460,27 +477,28 @@ public class PreviewTablePane extends BasicPane { previewTablePane.showWindow(new JFrame()).setVisible(true); } - /** - * 直接预览存储过程的所有返回数据集,没有实际值和显示值 - * - * @param storeProcedureDataModels storeProcedureDataModels - */ - public static void previewStoreDataWithAllDs(NameDataModel[] storeProcedureDataModels) { - UITabbedPane tabPreviewpane = new UITabbedPane(); - int tableSize = storeProcedureDataModels.length; - for (int i = 0; i < tableSize; i++) { + + public static void previewMultiDataModels(NameDataModel[] nameDataModels) { + // tab窗口 + UITabbedPane tabbedPane = new UITabbedPane(); + + for (NameDataModel nameDataModel : nameDataModels) { + // 单个结果集的展示面板 PreviewTablePane previewTablePane = new PreviewTablePane(); - previewTablePane.dataModel = storeProcedureDataModels[i]; + previewTablePane.dataModel = nameDataModel; + // 数据 previewTablePane.setBorder(BorderFactory.createTitledBorder(Toolkit.i18nText("Fine-Design_Basic_Data"))); try { - previewTablePane.populateStoreDataSQL(); + // 带行数限制的数据集结果预览对象 + previewTablePane.setRowsLimitTableModel(); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } - tabPreviewpane.addTab(storeProcedureDataModels[i].getName(), previewTablePane); + tabbedPane.addTab(nameDataModel.getName(), previewTablePane); } - BasicPane prieviewPane = new BasicPane() { + // 包含整个tab的容器窗口 + BasicPane previewPane = new BasicPane() { @Override protected String title4PopupWindow() { @@ -488,12 +506,22 @@ public class PreviewTablePane extends BasicPane { } }; - prieviewPane.setLayout(FRGUIPaneFactory.createBorderLayout()); - prieviewPane.add(tabPreviewpane, BorderLayout.CENTER); - prieviewPane.showWindow(new JFrame()).setVisible(true); + previewPane.setLayout(FRGUIPaneFactory.createBorderLayout()); + previewPane.add(tabbedPane, BorderLayout.CENTER); + previewPane.showWindow(new JFrame()).setVisible(true); + } + + /** + * 直接预览存储过程的所有返回数据集,没有实际值和显示值 + * + * @param storeProcedureDataModels storeProcedureDataModels + */ + @Deprecated + public static void previewStoreDataWithAllDs(NameDataModel[] storeProcedureDataModels) { + previewMultiDataModels(storeProcedureDataModels); } - private void populateStoreDataSQL() throws Exception { + private void setRowsLimitTableModel() throws Exception { PreviewTableModel previewModel; try { previewModel = new PreviewTableModel(dataModel, (int) maxPreviewNumberField.getValue()); diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java index dec660920..b57ca864f 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java @@ -289,16 +289,16 @@ public class ProcedureDataPane extends AbstractTableDataPane imp @Override protected Void doInBackground() throws Exception { DesignTableDataManager.setThreadLocal(DesignTableDataManager.NO_PARAMETER); - sp.setCalculating(true); + // sp.setCalculating(true); ProcedureDataModel[] dataModels = (ProcedureDataModel[]) DesignTableDataManager.createLazyDataModel(sp, false); - sp.refreshDataModelListAndResultNames(dataModels); + //sp.refreshDataModelListAndResultNames(dataModels); return null; } @Override public void done() { DesignTableDataManager.setThreadLocal(DesignTableDataManager.NO_PARAMETER); - sp.setCalculating(false); + // sp.setCalculating(false); doAfterProcudureDone(); fireDSChanged(); TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()); diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataNameWrapper.java b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataNameWrapper.java index 05c302e97..610aac3c5 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataNameWrapper.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataNameWrapper.java @@ -1,6 +1,5 @@ package com.fr.design.data.tabledata.wrapper; -import com.fr.base.BaseUtils; import com.fr.base.TableData; import com.fr.data.MultiResultTableData; import com.fr.data.impl.NameDataModel; @@ -9,6 +8,7 @@ import com.fr.design.data.datapane.TableDataCreatorProducer; import com.fr.design.data.datapane.TableDataNameObjectCreator; import com.fr.design.data.datapane.preview.PreviewTablePane; import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; +import com.fr.general.IOUtils; import com.fr.log.FineLoggerFactory; import com.fr.workspace.WorkContext; @@ -29,15 +29,15 @@ public final class MultiResultTableDataNameWrapper implements TableDataWrapper { private NameDataModel dataModel; private final String name; private final MultiResultTableData tableData; - private List columnNameList; + private List childrenList; /** - * @param name 存储过程本身名字 - * @param storeProcedure 存储过程 + * @param name 数据集名字 + * @param tableData 数据集 */ - public MultiResultTableDataNameWrapper(String name, MultiResultTableData storeProcedure) { + public MultiResultTableDataNameWrapper(String name, MultiResultTableData tableData) { this.name = name; - this.tableData = storeProcedure; + this.tableData = tableData; } /** @@ -46,6 +46,7 @@ public final class MultiResultTableDataNameWrapper implements TableDataWrapper { * @return 子节点 */ public ExpandMutableTreeNode[] load() { + // 生成多数据集结果子节点 List namelist = calculateColumnNameList(); ExpandMutableTreeNode[] res = new ExpandMutableTreeNode[namelist.size()]; for (int i = 0; i < res.length; i++) { @@ -67,17 +68,17 @@ public final class MultiResultTableDataNameWrapper implements TableDataWrapper { @Override public Icon getIcon() { - // TODO for (TableDataNameObjectCreator creator : TableDataCreatorProducer.getInstance().createReportTableDataCreator()) { - if (creator.createObject().getClass() == this.tableData.getClass()) { - return BaseUtils.readIcon(creator.getIconPath()); + if (creator.createObject().getClass().isAssignableFrom(this.tableData.getClass())) { + return IOUtils.readIcon(creator.getIconPath()); } } - return BaseUtils.readIcon("/com/fr/design/images/data/multi.png"); + return IOUtils.readIcon("/com/fr/design/images/data/multi.png"); } private void createResult(boolean needLoadingBar) { try { + // todo 啥意思? dataModel = DesignTableDataManager.createLazyDataModel(tableData, needLoadingBar)[0]; } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); @@ -92,14 +93,14 @@ public final class MultiResultTableDataNameWrapper implements TableDataWrapper { * @return 字段 */ public List calculateColumnNameList() { - if (columnNameList != null) { - return columnNameList; + if (childrenList != null) { + return childrenList; } - columnNameList = new ArrayList(); + childrenList = new ArrayList<>(); if (!WorkContext.getCurrent().isLocal()) { try { createResult(false); - columnNameList = Arrays.asList(dataModel.getColumnNames()); + childrenList = Arrays.asList(dataModel.getColumnNames()); } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } @@ -109,10 +110,10 @@ public final class MultiResultTableDataNameWrapper implements TableDataWrapper { createResult(false); } if (dataModel != null) { - columnNameList = Arrays.asList(dataModel.getColumnNames()); + childrenList = Arrays.asList(dataModel.getColumnNames()); } } - return columnNameList; + return childrenList; } /** @@ -122,7 +123,7 @@ public final class MultiResultTableDataNameWrapper implements TableDataWrapper { if (dataModel == null) { createResult(true); } - PreviewTablePane.previewStoreData(dataModel); + PreviewTablePane.previewDataModel(dataModel); } @@ -136,7 +137,7 @@ public final class MultiResultTableDataNameWrapper implements TableDataWrapper { if (dataModel == null) { createResult(true); } - PreviewTablePane.previewStoreData(dataModel, keyIndex, valueIndex); + PreviewTablePane.previewDataModel(dataModel, keyIndex, valueIndex); } /** diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataWrapper.java b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataWrapper.java index 2e351cf3c..6cce86fd2 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataWrapper.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/MultiResultTableDataWrapper.java @@ -1,6 +1,5 @@ package com.fr.design.data.tabledata.wrapper; -import com.fr.base.BaseUtils; import com.fr.base.TableData; import com.fr.data.MultiResultTableData; import com.fr.data.impl.NameDataModel; @@ -16,6 +15,7 @@ import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.general.ComparatorUtils; +import com.fr.general.IOUtils; import com.fr.log.FineLoggerFactory; import javax.swing.Icon; @@ -40,7 +40,7 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper { public static AutoProgressBar loadingBar; private NameDataModel dataModel; - private final String dsName; + private final String dataModelName; private final String tableDataName; private final MultiResultTableData tableData; private List columnNameList; @@ -49,29 +49,45 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper { private SwingWorker worker; private int previewModel; - public MultiResultTableDataWrapper(MultiResultTableData tableData, String tableDataName, String dsName) { - this(null, tableData, tableDataName, dsName, true); + /** + * @param tableData 数据集 + * @param tableDataName 数据集名称 + * @param dataModelName 数据集的一个结果的名称(全限定名称) + */ + public MultiResultTableDataWrapper(MultiResultTableData tableData, String tableDataName, String dataModelName) { + this(null, tableData, tableDataName, dataModelName, true); } - public MultiResultTableDataWrapper(MultiResultTableData tableData, String tableDataName, String dsName, boolean needLoad) { - this(null, tableData, tableDataName, dsName, needLoad); + /** + * @param tableData 数据集 + * @param tableDataName 数据集名称 + * @param dataModelName 数据集的一个结果的名称(全限定名称) + * @param needLoad 是否需要加载 + */ + public MultiResultTableDataWrapper(MultiResultTableData tableData, String tableDataName, String dataModelName, boolean needLoad) { + this(null, tableData, tableDataName, dataModelName, needLoad); } - public MultiResultTableDataWrapper(Component component, MultiResultTableData tableData, String tableDataName, String dsName) { - this(component, tableData, tableDataName, dsName, true); + /** + * @param component 父容器 + * @param tableData 数据集 + * @param tableDataName 数据集名称 + * @param dataModelName 数据集的一个结果的名称(全限定名称) + */ + public MultiResultTableDataWrapper(Component component, MultiResultTableData tableData, String tableDataName, String dataModelName) { + this(component, tableData, tableDataName, dataModelName, true); } /** * @param component loadingBar的父弹框(如果不设置父弹框的话,可能出现loadingBar隐藏在一个弹框后的情况) - * @param tableData 存储过程 - * @param tableDataName 存储过程的名字(某些情况下可以为空) - * @param dsName 存储过程一个返回数据集的名字 + * @param tableData 多结果数据集 + * @param tableDataName 多结果数据集的名字(某些情况下可以为空) + * @param dataModelName 多结果数据集一个返回数据集的名字 * @param needLoad 是否要加载 **/ - public MultiResultTableDataWrapper(Component component, MultiResultTableData tableData, String tableDataName, String dsName, boolean needLoad) { - this.dsName = dsName; + public MultiResultTableDataWrapper(Component component, MultiResultTableData tableData, String tableDataName, String dataModelName, boolean needLoad) { + this.dataModelName = dataModelName; this.tableData = tableData; - this.tableData.setCalculating(false); this.tableDataName = tableDataName; if (component == null) { component = new JFrame(); @@ -133,10 +149,11 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper { private void createResults(boolean needLoadingBar) throws Exception { + this.dataModel = null; dataModels = DesignTableDataManager.createLazyDataModel(tableData, needLoadingBar); if (dataModels != null && dataModels.length != 0) { for (NameDataModel dataModel : dataModels) { - if (ComparatorUtils.equals(this.dsName, tableDataName + "_" + dataModel.getName())) { + if (ComparatorUtils.equals(this.dataModelName, tableDataName + MultiResultTableData.GROUP_MARKER + dataModel.getName())) { this.dataModel = dataModel; break; } @@ -147,11 +164,11 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper { @Override public Icon getIcon() { for (TableDataNameObjectCreator creator : TableDataCreatorProducer.getInstance().createReportTableDataCreator()) { - if (creator.createObject().getClass() == this.tableData.getClass()) { - return BaseUtils.readIcon(creator.getIconPath()); + if (creator.createObject().getClass().isAssignableFrom(this.tableData.getClass())) { + return IOUtils.readIcon(creator.getIconPath()); } } - return BaseUtils.readIcon("/com/fr/design/images/data/multi.png"); + return IOUtils.readIcon("/com/fr/design/images/data/multi.png"); } /** @@ -179,6 +196,8 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper { loadingBar.close(); PreviewTablePane.resetPreviewTable(); connectionBar.start(); + + // 存储过程需要先测试一下连接 if (tableData instanceof StoreProcedure) { boolean status = DataOperator.getInstance().testConnection(((StoreProcedure) getTableData()).getDatabaseConnection()); if (!status) { @@ -189,6 +208,8 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper { connectionBar.close(); tableData.resetDataModelList(); + + // 获取结果 createResults(true); return null; } @@ -200,7 +221,7 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper { loadingBar.close(); switch (previewModel) { case MultiResultTableDataWrapper.PREVIEW_ALL: - PreviewTablePane.previewStoreDataWithAllDs(dataModels); + PreviewTablePane.previewMultiDataModels(dataModels); break; case MultiResultTableDataWrapper.PREVIEW_ONE: previewData(); @@ -246,12 +267,12 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper { */ @Override public void previewData(final int keyIndex, final int valueIndex) { - PreviewTablePane.previewStoreData(dataModel, keyIndex, valueIndex); + PreviewTablePane.previewDataModel(dataModel, keyIndex, valueIndex); } /** - * 预览返回的所有数据集,只有在编辑存储过程时才用到 + * 预览返回的所有数据集,只有在编辑多结果数据集时才用到 */ public void previewAllTable() { if (dataModel == null) { @@ -261,12 +282,16 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper { return; } } - PreviewTablePane.previewStoreDataWithAllDs(dataModels); + PreviewTablePane.previewMultiDataModels(dataModels); } @Override public String getTableDataName() { - return dsName; + return tableDataName; + } + + public String getDataModelName() { + return dataModelName; } @Override @@ -287,7 +312,7 @@ public final class MultiResultTableDataWrapper implements TableDataWrapper { @Override public boolean equals(Object obj) { return obj instanceof MultiResultTableDataWrapper - && ComparatorUtils.equals(this.dsName, ((MultiResultTableDataWrapper) obj).getTableDataName()) + && ComparatorUtils.equals(this.dataModelName, ((MultiResultTableDataWrapper) obj).getTableDataName()) && ComparatorUtils.equals(this.tableData, ((MultiResultTableDataWrapper) obj).getTableData()) && ComparatorUtils.equals(this.tableDataName, ((MultiResultTableDataWrapper) obj).getTableDataName()); diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java index 1960fed7c..9eb09376e 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java @@ -76,7 +76,7 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { public StoreProcedureDataWrapper(Component component, StoreProcedure storeProcedure, String storeprocedureName, String dsName, boolean needLoad) { this.dsName = dsName; this.storeProcedure = storeProcedure; - this.storeProcedure.setCalculating(false); + /*this.storeProcedure.setCalculating(false);*/ this.storeprocedureName = storeprocedureName; if (component == null) { component = new JFrame(); diff --git a/designer-base/src/main/java/com/fr/design/deeplink/DeepLinkCore.java b/designer-base/src/main/java/com/fr/design/deeplink/DeepLinkCore.java index 55a45709b..8fed6e80d 100644 --- a/designer-base/src/main/java/com/fr/design/deeplink/DeepLinkCore.java +++ b/designer-base/src/main/java/com/fr/design/deeplink/DeepLinkCore.java @@ -10,6 +10,7 @@ import com.fr.event.Null; import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; import com.fr.stable.os.OperatingSystem; +import com.fr.start.common.DesignerStartupContext; import com.fr.third.org.apache.http.NameValuePair; import com.fr.web.URLUtils; @@ -131,7 +132,19 @@ public class DeepLinkCore { } private boolean canConsumePendingURL() { - return StringUtils.isNotEmpty(this.pendingURL) && isDesignerStartupCompleted; + return StringUtils.isNotEmpty(this.pendingURL) && isAvailableConsumingTime(); + } + + /** + * 是否是可用的消耗时机 + * 满足任一即可 + * 1-设计器已经启动 + * 2-出在设计器启动页页面 + * + * @return 是/否 + */ + private boolean isAvailableConsumingTime() { + return isDesignerStartupCompleted || DesignerStartupContext.getInstance().isOnWaiting(); } private void consumePendingURL() { diff --git a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java b/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java index 61093401f..d5a288afc 100644 --- a/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java +++ b/designer-base/src/main/java/com/fr/design/file/HistoryTemplateListCache.java @@ -97,8 +97,13 @@ public class HistoryTemplateListCache implements CallbackEvent { FineLoggerFactory.getLogger().error(e.getMessage(), e); } } - - + + + /** + * 需要使用 {@link JTemplate#isValid(JTemplate)} 来判断空 + * + * @return 当前正在编辑的模板 + */ @Nullable public JTemplate getCurrentEditingTemplate() { return this.editingTemplate; diff --git a/designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java b/designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java index 3a2e56d22..ce8fdaa9d 100644 --- a/designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java +++ b/designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java @@ -153,7 +153,7 @@ public class FRGUIPaneFactory { } public static LayoutManager createCenterLayout(JComponent centerBody) { - return createCenterLayout(centerBody, 0.3d); + return createCenterLayout(centerBody, 0.5d, 0.3d); } /** @@ -162,7 +162,7 @@ public class FRGUIPaneFactory { * @param centerBody 中心组件 * @return 布局方式 */ - public static LayoutManager createCenterLayout(JComponent centerBody, double factor) { + public static LayoutManager createCenterLayout(JComponent centerBody, double factorX, double factorY) { return new LayoutManager() { @@ -188,8 +188,8 @@ public class FRGUIPaneFactory { // 这个时候大小是不确定的 int bodyWidth = centerBody.getPreferredSize().width; int bodyHeight = centerBody.getPreferredSize().height; - int labelX = (width - bodyWidth) / 2; - int labelY = (int) ((height - bodyHeight) * factor); + int labelX = (int) ((width - bodyWidth) * factorX); + int labelY = (int) ((height - bodyHeight) * factorY); centerBody.setBounds(labelX, labelY, bodyWidth, bodyHeight); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java index 20c8c580a..0e06cc87a 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/CenterRegionContainerPane.java @@ -156,7 +156,7 @@ public class CenterRegionContainerPane extends JPanel { private void addExtraButtons() { JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (jt == null) { + if (!JTemplate.isValid(jt)) { return; } @@ -172,7 +172,7 @@ public class CenterRegionContainerPane extends JPanel { private void addCheckButton() { JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (jt == null) { + if (!JTemplate.isValid(jt)) { return; } combineUp.addSeparator(new Dimension(2, 16)); @@ -185,7 +185,7 @@ public class CenterRegionContainerPane extends JPanel { private void addShareButton() { JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (jt == null) { + if (!JTemplate.isValid(jt)) { return; } @@ -205,7 +205,7 @@ public class CenterRegionContainerPane extends JPanel { protected void checkCombineUp(boolean flag, ArrayList al) { //Yvan: 检查当前是否为WORK_SHEET状态,因为只有WORK_SHEET中含有格式刷组件,此时是不需要进行checkComponentsByNames的 JTemplate jTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (jTemplate != null) { + if (JTemplate.isValid(jTemplate)) { // 第一个条件满足后还需要添加一重判断,判断是编辑报表块还是参数面板,编辑报表块时则直接return if (jTemplate.getMenuState() == DesignState.WORK_SHEET && !jTemplate.isUpMode()) { return; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/utils/DefaultThemedTemplateCellElementCase.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/utils/DefaultThemedTemplateCellElementCase.java index 64aaeb9c0..123875eef 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/utils/DefaultThemedTemplateCellElementCase.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/utils/DefaultThemedTemplateCellElementCase.java @@ -33,7 +33,7 @@ public class DefaultThemedTemplateCellElementCase { private static DefaultTemplateCellElement themingCellElement(DefaultTemplateCellElement cellElement) { JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (template != null) { + if (JTemplate.isValid(template)) { TemplateTheme theme = template.getTemplateTheme(); ThemedCellStyle themedCellStyle = theme.getCellStyleList().getUse4Default(); if (themedCellStyle != null) { diff --git a/designer-base/src/main/java/com/fr/design/utils/ColorUtils.java b/designer-base/src/main/java/com/fr/design/utils/ColorUtils.java index 7c0daa111..f189ccc30 100644 --- a/designer-base/src/main/java/com/fr/design/utils/ColorUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/ColorUtils.java @@ -27,6 +27,38 @@ public class ColorUtils { } } } + + /** + * 递归的同步颜色,如何组件的背景颜色等于默认颜色的话,变更为 replaceColor + * + * @param component 组件 + * @param replaceColor 替换颜色 + * @param defaultColor 默认颜色 + */ + public static void syncBackgroundIfAbsent(Component component, Color replaceColor, Color defaultColor) { + + if (component.getBackground() != defaultColor) { + return; + } + component.setBackground(replaceColor); + if (component instanceof Container) { + Container container = (Container) component; + Component[] components = container.getComponents(); + if (components != null) { + Arrays.stream(components).forEach((e) -> syncBackgroundIfAbsent(e, replaceColor, defaultColor)); + } + } + } + + /** + * 使背景透明 + * + * @param component 组件 + */ + public static void transparentBackground(Component component) { + + syncBackgroundIfAbsent(component, new Color(0,0,0,0), ThemeUtils.BACK_COLOR); + } public static boolean isDarkColor(Color color) { if(color == null) { diff --git a/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java b/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java index 67fb91866..47690bba9 100644 --- a/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java @@ -25,7 +25,7 @@ import com.fr.stable.StringUtils; import com.fr.stable.os.OperatingSystem; import com.fr.start.ServerStarter; import com.fr.start.common.DesignerStartupContext; -import com.fr.startup.ui.StartupPageModel; +import com.fr.start.common.DesignerStartupUtil; import com.fr.value.NotNullLazyValue; import com.fr.workspace.WorkContext; import org.jetbrains.annotations.NotNull; @@ -48,7 +48,6 @@ import java.net.URI; import java.nio.charset.StandardCharsets; import java.util.Enumeration; import java.util.Locale; -import java.util.Optional; import java.util.concurrent.Callable; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -216,18 +215,9 @@ public class DesignUtils { @Override public void run() { DesignerStartupContext context = DesignerStartupContext.getInstance(); + // 如果在启动页展示中 - if (context.isOnWaiting()) { - FileFILE fileFILE = new FileFILE(f); - // 设置上一次启动模板为 - DesignerEnvManager.getEnvManager().setLastOpenFile(fileFILE.getPath()); - StartupPageModel model = context.getStartupPageModel(); - Optional.ofNullable(model) - .ifPresent((e) -> { - // 执行上一次模板的启动 - Runnable openLastTemplateRunnable = e.getOpenLastTemplateRunnable(); - openLastTemplateRunnable.run(); - }); + if (DesignerStartupUtil.openTemplateIfOnWaiting(f)) { return; } // 如果是在启动中 diff --git a/designer-base/src/main/java/com/fr/start/BaseDesigner.java b/designer-base/src/main/java/com/fr/start/BaseDesigner.java index 68cb616e1..7dadc636f 100644 --- a/designer-base/src/main/java/com/fr/start/BaseDesigner.java +++ b/designer-base/src/main/java/com/fr/start/BaseDesigner.java @@ -35,6 +35,7 @@ import com.fr.start.common.DesignerStartupContext; import com.fr.start.common.DesignerStartupUtil; import com.fr.start.event.LazyStartupEvent; import com.fr.workspace.base.WorkspaceStatus; +import org.jetbrains.annotations.Nullable; import java.awt.Window; import java.lang.reflect.Method; @@ -126,7 +127,7 @@ public abstract class BaseDesigner extends ToolBarMenuDock { if (args != null && args.length > 0) { file = DesignerStartupUtil.convertArgs2FILE(args); } else { - file = FILEFactory.createFILE(FILEFactory.ENV_PREFIX + DesignerEnvManager.getEnvManager().getLastOpenFile()); + file = getLastOpenFile(); } DesignerFrame df = DesignerContext.getDesignerFrame(); isException = openFile(df, isException, file); @@ -141,7 +142,17 @@ public abstract class BaseDesigner extends ToolBarMenuDock { } } } - + + @Nullable + private FILE getLastOpenFile() { + + FILE file = DesignerStartupContext.getInstance().getStartingTemplateFile(); + if (file == null) { + file = FILEFactory.createFILE(FILEFactory.ENV_PREFIX + DesignerEnvManager.getEnvManager().getLastOpenFile()); + } + return file; + } + private boolean openFile(final DesignerFrame df, boolean isException, FILE file) { AtomicBoolean isExWrapper = new AtomicBoolean(isException); diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java b/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java index 89aeedc60..7f4a0eeb9 100644 --- a/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java +++ b/designer-base/src/main/java/com/fr/start/common/DesignerOpenEmptyPanel.java @@ -70,7 +70,7 @@ public class DesignerOpenEmptyPanel extends JPanel { this.body.add(createIcon, BorderLayout.NORTH); this.body.add(createButtonPanel, BorderLayout.SOUTH); - setLayout(FRGUIPaneFactory.createCenterLayout(this.body, 0.4d)); + setLayout(FRGUIPaneFactory.createCenterLayout(this.body, 0.4d, 0.4d)); ColorUtils.syncBackground(this, Color.WHITE); diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerStartupContext.java b/designer-base/src/main/java/com/fr/start/common/DesignerStartupContext.java index a59711e28..c78469b45 100644 --- a/designer-base/src/main/java/com/fr/start/common/DesignerStartupContext.java +++ b/designer-base/src/main/java/com/fr/start/common/DesignerStartupContext.java @@ -3,6 +3,7 @@ package com.fr.start.common; import com.fr.design.DesignerEnvManager; import com.fr.design.env.DesignerWorkspaceInfo; import com.fr.design.env.DesignerWorkspaceType; +import com.fr.file.FileFILE; import com.fr.start.module.StartupArgs; import com.fr.startup.metric.DesignerMetrics; import com.fr.startup.ui.StartupPageModel; @@ -64,6 +65,11 @@ public class DesignerStartupContext { */ private boolean createNew; + /** + * 启动的模板 + */ + private FileFILE startingTemplateFile; + /** * 时间记录 */ @@ -72,7 +78,7 @@ public class DesignerStartupContext { public static DesignerStartupContext getInstance() { return StartupContextHolder.INSTANCE; } - + private static class StartupContextHolder { private static final DesignerStartupContext INSTANCE = new DesignerStartupContext(); } @@ -87,6 +93,14 @@ public class DesignerStartupContext { /* 启动模式 */ + public FileFILE getStartingTemplateFile() { + return startingTemplateFile; + } + + public void setStartingTemplateFile(FileFILE startingTemplateFile) { + this.startingTemplateFile = startingTemplateFile; + } + /** * 展示启动页 * 1. 判断当前的工作目录数量 diff --git a/designer-base/src/main/java/com/fr/start/common/DesignerStartupUtil.java b/designer-base/src/main/java/com/fr/start/common/DesignerStartupUtil.java index 5bc55e80c..1bcf8be95 100644 --- a/designer-base/src/main/java/com/fr/start/common/DesignerStartupUtil.java +++ b/designer-base/src/main/java/com/fr/start/common/DesignerStartupUtil.java @@ -6,16 +6,44 @@ import com.fr.file.FILE; import com.fr.file.FILEFactory; import com.fr.file.FileFILE; import com.fr.general.ComparatorUtils; +import com.fr.startup.ui.StartupPageModel; import org.jetbrains.annotations.Nullable; import java.io.File; +import java.util.Optional; /** * created by Harrison on 2022/07/09 **/ public class DesignerStartupUtil { - @Nullable + /** + * 如果是在启动页中 + * + * @param file 文件 + * @return 成功/失败 + */ + public static boolean openTemplateIfOnWaiting(File file) { + + DesignerStartupContext context = DesignerStartupContext.getInstance(); + // 如果在启动页展示中 + if (context.isOnWaiting()) { + FileFILE fileFILE = new FileFILE(file); + // 设置上一次启动模板为当前模板 + DesignerStartupContext.getInstance().setStartingTemplateFile(fileFILE); + StartupPageModel model = context.getStartupPageModel(); + Optional.ofNullable(model) + .ifPresent((e) -> { + // 执行上一次模板的启动 + Runnable openLastTemplateRunnable = e.getOpenLastTemplateRunnable(); + openLastTemplateRunnable.run(); + }); + return true; + } + return false; + } + + @Nullable public static FILE convertArgs2FILE(String[] args) { // p:需要打开这个报表文件,这个代码不能删除. diff --git a/designer-base/src/main/java/com/fr/startup/metric/DesignerMetrics.java b/designer-base/src/main/java/com/fr/startup/metric/DesignerMetrics.java index 58c67079e..aa7391df7 100644 --- a/designer-base/src/main/java/com/fr/startup/metric/DesignerMetrics.java +++ b/designer-base/src/main/java/com/fr/startup/metric/DesignerMetrics.java @@ -19,4 +19,5 @@ public class DesignerMetrics { public DesignerStartupPageStatistic getStatistic() { return statistic; } + } diff --git a/designer-base/src/main/java/com/fr/startup/metric/DesignerStartupPageStatistic.java b/designer-base/src/main/java/com/fr/startup/metric/DesignerStartupPageStatistic.java index 412ee434c..b68ea7335 100644 --- a/designer-base/src/main/java/com/fr/startup/metric/DesignerStartupPageStatistic.java +++ b/designer-base/src/main/java/com/fr/startup/metric/DesignerStartupPageStatistic.java @@ -1,5 +1,13 @@ package com.fr.startup.metric; +import com.fr.stable.StringUtils; +import com.fr.start.common.DesignerStartupContext; +import com.fr.startup.ui.StartupPageModel; +import com.fr.startup.ui.StartupWorkspaceBean; + +import java.util.ArrayDeque; +import java.util.Deque; + /** * 设计器启动页使用数据 * @@ -7,65 +15,185 @@ package com.fr.startup.metric; **/ public class DesignerStartupPageStatistic { + private final Deque operations = new ArrayDeque<>(); + /** - * operate:0-双击工作目录进入 或 点击蓝色箭头进入;1-切换其他工作目录;2-点击展开全部;3-点击工作目录中的模版直接打开 或 直接点击蓝色箭头进入 + * 见 {@link OperationType} 的注释 */ - private int operate; + public void recordOpenEmptyTemplate() { + + Operation operation = OperationType.DO_OPEN_EMPTY_TEMPLATE.create(); + StartupPageModel pageModel = DesignerStartupContext.getInstance().getStartupPageModel(); + operation.setWorkspace(pageModel.getSelectWorkspaceInfo().getName()); + operation.setWorkspaceNum(pageModel.getWorkspaceInfos().size()); + pushOperation(operation); + } /** - * workplace:工作目录名称,当operate为 0或1时记录 + * 见 {@link OperationType} 的注释 */ - private String workspace; + public void recordSwitchWorkspace(StartupWorkspaceBean lastWorkspaceInfo, StartupWorkspaceBean currentWorkspace) { + + if (lastWorkspaceInfo != null && StringUtils.equals(lastWorkspaceInfo.getName(), currentWorkspace.getName())) { + return; + } + Operation operation = OperationType.DO_SWITCH_WORKSPACE.create(); + StartupPageModel pageModel = DesignerStartupContext.getInstance().getStartupPageModel(); + operation.setWorkspace(currentWorkspace.getName()); + operation.setWorkspaceNum(pageModel.getWorkspaceInfos().size()); + pushOperation(operation); + } /** - * workplaceNumber:工作目录的个数,当operate为 0或1或2或3时记录 + * 见 {@link OperationType} 的注释 */ - private String workspaceNum; + public void recordShowAllAction() { + + Operation operation = OperationType.DO_SHOW_ALL_ACTION.create(); + StartupPageModel pageModel = DesignerStartupContext.getInstance().getStartupPageModel(); + operation.setWorkspaceNum(pageModel.getWorkspaceInfos().size()); + pushOperation(operation); + } /** - * template:模板名称,当operate为 3时记录 + * 见 {@link OperationType} 的注释 */ - private String template; + public void recordOpenLastTemplate(String lastOpenFile) { - public DesignerStartupPageStatistic(int operate, String workspace, String workspaceNum, String template) { - this.operate = operate; - this.workspace = workspace; - this.workspaceNum = workspaceNum; - this.template = template; + Operation operation = OperationType.DO_OPEN_LAST_TEMPLATE_ACTION.create(); + StartupPageModel pageModel = DesignerStartupContext.getInstance().getStartupPageModel(); + operation.setWorkspaceNum(pageModel.getWorkspaceInfos().size()); + operation.setTemplate(lastOpenFile); + pushOperation(operation); } - public DesignerStartupPageStatistic() { - } + /** + * 添加操作 + * + * @param operation 操作 + */ + public void pushOperation(Operation operation) { - public int getOperate() { - return operate; + this.operations.push(operation); } - public void setOperate(int operate) { - this.operate = operate; - } + /** + * 获取操作 + * + * @return 操作 + */ + public Deque getOperations() { - public String getWorkspace() { - return workspace; + return this.operations; } - public void setWorkspace(String workspace) { - this.workspace = workspace; - } + public enum OperationType { - public String getWorkspaceNum() { - return workspaceNum; - } + /** + * 双击工作目录进入 或 点击蓝色箭头进入 + */ + DO_OPEN_EMPTY_TEMPLATE(0), - public void setWorkspaceNum(String workspaceNum) { - this.workspaceNum = workspaceNum; - } + /** + * 切换其他工作目录 + */ + DO_SWITCH_WORKSPACE(1), + + /** + * 点击展开全部 + */ + DO_SHOW_ALL_ACTION(2), + + /** + * 点击工作目录中的模版直接打开 或 直接点击蓝色箭头进入 + */ + DO_OPEN_LAST_TEMPLATE_ACTION(3); + + private final int sign; - public String getTemplate() { - return template; + OperationType(int sign) { + this.sign = sign; + } + + public int getSign() { + return sign; + } + + public Operation create() { + + Operation operation = new Operation(); + operation.setOperateType(this); + return operation; + } } - public void setTemplate(String template) { - this.template = template; + public static class Operation { + + /** + * operate:0-双击工作目录进入 或 点击蓝色箭头进入;1-切换其他工作目录;2-点击展开全部;3-点击工作目录中的模版直接打开 或 直接点击蓝色箭头进入 + */ + private int operate; + + /** + * workplace:工作目录名称,当operate为 0或1时记录 + */ + private String workspace; + + /** + * workplaceNumber:工作目录的个数,当operate为 0或1或2或3时记录 + */ + private int workspaceNum; + + /** + * template:模板名称,当operate为 3时记录 + */ + private String template; + + public Operation(int operate, String workspace, int workspaceNum, String template) { + this.operate = operate; + this.workspace = workspace; + this.workspaceNum = workspaceNum; + this.template = template; + } + + public Operation() { + } + + public int getOperate() { + return operate; + } + + public void setOperateType(OperationType operateType) { + this.operate = operateType.getSign(); + } + + public void setOperate(int operate) { + this.operate = operate; + } + + public String getWorkspace() { + return workspace; + } + + public void setWorkspace(String workspace) { + this.workspace = workspace; + } + + public int getWorkspaceNum() { + return workspaceNum; + } + + public void setWorkspaceNum(int workspaceNum) { + this.workspaceNum = workspaceNum; + } + + public String getTemplate() { + return template; + } + + public void setTemplate(String template) { + this.template = template; + } } + } diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageConstants.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageConstants.java index ae27e1a9e..8c414cecf 100644 --- a/designer-base/src/main/java/com/fr/startup/ui/StartupPageConstants.java +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupPageConstants.java @@ -1,5 +1,7 @@ package com.fr.startup.ui; +import java.awt.Color; + /** * created by Harrison on 2022/07/07 **/ @@ -14,4 +16,14 @@ public class StartupPageConstants { * 内容宽度 */ public static final int CONTENT_WIDTH = 850; + + /** + * 边框的颜色 + */ + public static final Color BORDER_COLOR = Color.WHITE; + + /** + * 透明的颜色 + */ + public static final Color TRANSPARENT_COLOR = new Color(0, 0, 0, 0); } diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageModel.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageModel.java index c345c8991..a461ee33b 100644 --- a/designer-base/src/main/java/com/fr/startup/ui/StartupPageModel.java +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupPageModel.java @@ -45,7 +45,8 @@ public class StartupPageModel { DesignerWorkspaceInfo workspaceInfo = envManager.getWorkspaceInfo(e); if (workspaceInfo.getType() == DesignerWorkspaceType.Remote) { WorkspaceConnectionInfo connection = workspaceInfo.getConnection(); - return new StartupWorkspaceBean(e, connection.getUrl(), workspaceInfo.getType()); + String remoteAddress = StartupPageUtil.getRemoteAddress(connection.getUrl()); + return new StartupWorkspaceBean(e, remoteAddress, workspaceInfo.getType()); } else { return new StartupWorkspaceBean(e, workspaceInfo.getPath(), workspaceInfo.getType()); } diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageUtil.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageUtil.java index 896b42595..153aa4ce0 100644 --- a/designer-base/src/main/java/com/fr/startup/ui/StartupPageUtil.java +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupPageUtil.java @@ -2,14 +2,22 @@ package com.fr.startup.ui; import com.fr.base.svg.SVGIcon; import com.fr.design.env.DesignerWorkspaceType; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; import javax.swing.Icon; +import javax.swing.JComponent; +import javax.swing.JRootPane; +import java.net.URL; /** * created by Harrison on 2022/07/11 **/ public class StartupPageUtil { + public static final int INVALID_PORT = -1; + public static final String COLON = ":"; + /** * 获取最近区域的 ICON * @@ -37,4 +45,42 @@ public class StartupPageUtil { } return SVGIcon.readSVGIcon("/com/fr/design/startup/remote_server_background_28.svg", 28, 28); } + + /** + * 返回 ip : port + * + * @param urlStr 完整的 url 值,例如 https://localhost:3090/xxx + * @return localhost:3090 + */ + public static String getRemoteAddress(String urlStr) { + + try { + if (StringUtils.isEmpty(urlStr)) { + return StringUtils.EMPTY; + } + URL url = new URL(urlStr); + String host = url.getHost(); + int port = url.getPort(); + if (port == INVALID_PORT) { + return host; + } + return host + COLON + port; + } catch (Exception e) { + FineLoggerFactory.getLogger().debug(e.getMessage(), e); + return urlStr; + } + } + + /** + * 透明的背景,需要从根节点重绘 + * + * @param component 组件 + */ + public static void repaintAll(JComponent component) { + + JRootPane rootPane = component.getRootPane(); + if (rootPane != null) { + rootPane.repaint(); + } + } } diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java index b73d13d9f..cb0442abd 100644 --- a/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupPageWindow.java @@ -11,12 +11,15 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.VerticalFlowLayout; import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.ColorUtils; -import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.design.utils.ThemeUtils; import com.fr.exit.DesignerExiter; import com.fr.general.GeneralUtils; +import com.fr.general.IOUtils; import com.fr.log.FineLoggerFactory; import com.fr.stable.ProductConstants; import com.fr.stable.collections.CollectionUtils; +import com.fr.start.common.DesignerStartupContext; +import com.fr.startup.metric.DesignerMetrics; import org.jetbrains.annotations.NotNull; import javax.swing.BorderFactory; @@ -44,6 +47,7 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; +import java.awt.image.BufferedImage; import java.util.List; import java.util.Map; @@ -68,7 +72,7 @@ public class StartupPageWindow extends JFrame { private static final int TITLE_FONT_SIZE = 24; private static final int ITEM_VERTICAL_GAP = 5; - private static final Dimension SCREEN_SIZE = new Dimension(1600, 820); + private static final Dimension SCREEN_SIZE = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); private StartupPageWorkspacePanel workspacePanel; @@ -96,6 +100,7 @@ public class StartupPageWindow extends JFrame { setLayout(new BorderLayout()); this.body = FRGUIPaneFactory.createBorderLayout_S_Pane(); + this.body.setBackground(new Color(0, 0, 0, 0)); // Header UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Startup_Page_Select_Workspace")); Font font = label.getFont(); @@ -105,6 +110,7 @@ public class StartupPageWindow extends JFrame { LayoutManager centerFlowLayout = FRGUIPaneFactory.createCenterFlowLayout(); headerPanel.setLayout(centerFlowLayout); headerPanel.add(label); + headerPanel.setBackground(new Color(0, 0, 0, 0)); this.body.add(headerPanel, BorderLayout.NORTH); // Workspace-description @@ -126,7 +132,14 @@ public class StartupPageWindow extends JFrame { this.recentOpenPanel = generateRecentOpenPanel(pageModel); this.body.add(recentOpenPanel, BorderLayout.SOUTH); - this.contentPane = new JPanel(); + this.contentPane = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + BufferedImage image = IOUtils.readImage("com/fr/design/startup/startup_page_background.jpg"); + g.drawImage(image, 0, 0, SCREEN_SIZE.width, SCREEN_SIZE.height, this); + } + }; this.contentPane.setLayout(getCenterLayout(body)); this.contentPane.add(this.body, BorderLayout.CENTER); this.contentPane.setPreferredSize(this.body.getPreferredSize()); @@ -147,7 +160,14 @@ public class StartupPageWindow extends JFrame { validate(); revalidate(); - GUICoreUtils.centerWindow(this); + setFullScreen(); + } + + private void setFullScreen() { + + Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); + this.setLocation(0, 0); + this.setSize(screenSize.width, screenSize.height); } private void addDefaultListeners() { @@ -296,6 +316,7 @@ public class StartupPageWindow extends JFrame { recentOpenWrapperPanel.setBorder(new EmptyBorder(0, 0, 0, 20)); recentOpenWrapperPanel.add(recentOpenPanel, BorderLayout.CENTER); + ColorUtils.syncBackgroundIfAbsent(recentOpenWrapperPanel, new Color(0,0,0,0), ThemeUtils.BACK_COLOR); return recentOpenWrapperPanel; } @@ -324,17 +345,18 @@ public class StartupPageWindow extends JFrame { @Override public void mouseEntered(MouseEvent e) { recentFileLabel.setForeground(HOVER_COLOR); + StartupPageUtil.repaintAll(recentOpenGroupPanel); } @Override public void mouseExited(MouseEvent e) { recentFileLabel.setForeground(recentFileLabelForeground); + StartupPageUtil.repaintAll(recentOpenGroupPanel); } @Override public void mouseClicked(MouseEvent e) { - DesignerEnvManager.getEnvManager().setLastOpenFile(recentFile); - pageModel.getOpenLastTemplateRunnable().run(); + doOpenLastTemplateAction(recentFile, pageModel); } }); Dimension preferredSize = recentItemPanel.getPreferredSize(); @@ -357,8 +379,10 @@ public class StartupPageWindow extends JFrame { } private StartupPageWorkspacePanel generateWorkspacePanel(StartupPageModel pageModel) { - - return new StartupPageWorkspacePanel(pageModel); + + StartupPageWorkspacePanel startupPageWorkspacePanel = new StartupPageWorkspacePanel(pageModel); + ColorUtils.syncBackgroundIfAbsent(startupPageWorkspacePanel, new Color(0, 0, 0, 0), ThemeUtils.BACK_COLOR); + return startupPageWorkspacePanel; } protected LayoutManager getCenterLayout(JComponent centerBody) { @@ -366,4 +390,13 @@ public class StartupPageWindow extends JFrame { return FRGUIPaneFactory.createCenterLayout(centerBody); } + private void doOpenLastTemplateAction(String recentFile, StartupPageModel pageModel) { + + DesignerEnvManager.getEnvManager().setLastOpenFile(recentFile); + pageModel.getOpenLastTemplateRunnable().run(); + + DesignerMetrics designerMetrics = DesignerStartupContext.getInstance().getDesignerMetrics(); + designerMetrics.getStatistic().recordOpenLastTemplate(recentFile); + } + } diff --git a/designer-base/src/main/java/com/fr/startup/ui/StartupPageWorkspacePanel.java b/designer-base/src/main/java/com/fr/startup/ui/StartupPageWorkspacePanel.java index 5251509d3..ced2aa376 100644 --- a/designer-base/src/main/java/com/fr/startup/ui/StartupPageWorkspacePanel.java +++ b/designer-base/src/main/java/com/fr/startup/ui/StartupPageWorkspacePanel.java @@ -7,6 +7,8 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.utils.ColorUtils; +import com.fr.start.common.DesignerStartupContext; +import com.fr.startup.metric.DesignerMetrics; import com.fr.third.guava.collect.Lists; import org.jetbrains.annotations.NotNull; @@ -89,6 +91,7 @@ public class StartupPageWorkspacePanel extends JPanel { public StartupPageWorkspacePanel(StartupPageModel pageModel) { this.setLayout(new BorderLayout(0, 0)); + this.setBorder(new EmptyBorder(15, 0, 20, 0)); this.pageModel = pageModel; @@ -127,8 +130,12 @@ public class StartupPageWorkspacePanel extends JPanel { private JComponent generateUnLimitContentPanel(List> partitions) { + JPanel workspaceDescWrapper = new JPanel(); + workspaceDescWrapper.setLayout(new BorderLayout(0, 0)); + workspaceDescWrapper.setBorder(new EmptyBorder(0, 0, 0, 0)); + JPanel workspaceDescPanel = new JPanel(); - workspaceDescPanel.setLayout(new GridLayout(partitions.size(), 1, 0, ITEM_VERTICAL_GAP)); + workspaceDescPanel.setLayout(new GridLayout(partitions.size(), 1, 0, 0)); for (List partition : partitions) { JPanel partitionPanel = generatePartitionPanel(partition); workspaceDescPanel.add(partitionPanel); @@ -139,14 +146,18 @@ public class StartupPageWorkspacePanel extends JPanel { UIScrollPane scrollPane = new UIScrollPane(workspaceDescPanel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setBorder(new EmptyBorder(10, 0, 0, 0)); scrollPane.setPreferredSize(new Dimension(CONTENT_WIDTH, SCROLL_HEIGHT)); - return scrollPane; + workspaceDescWrapper.add(scrollPane, BorderLayout.CENTER); + return workspaceDescWrapper; } - return workspaceDescPanel; + workspaceDescWrapper.add(workspaceDescPanel, BorderLayout.CENTER); + + ColorUtils.transparentBackground(workspaceDescWrapper); + return workspaceDescWrapper; } private JPanel generateLimitContentPanel(List> partitions) { - JPanel workspaceDescPanel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEFT, 0, ITEM_VERTICAL_GAP); + JPanel workspaceDescPanel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEFT, 0, 0); int limit = 2; for (int i = 0; i < partitions.size(); i++) { if (i >= limit) { @@ -157,22 +168,38 @@ public class StartupPageWorkspacePanel extends JPanel { JPanel partitionPanel = generatePartitionPanel(partition); workspaceDescPanel.add(partitionPanel); } + + ColorUtils.transparentBackground(workspaceDescPanel); + return workspaceDescPanel; } @NotNull private JPanel generateTailPanel() { + + AtomicReference hoverBackColorRef = new AtomicReference<>(); JPanel tailPanel = new JPanel(); { tailPanel.setLayout(new FlowLayout(FlowLayout.RIGHT)); tailPanel.setBorder(new EmptyBorder(0, 0, 0, 20)); - JPanel showAllPanel = new JPanel(); + JPanel showAllPanel = new JPanel() { + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + if (hoverBackColorRef.get() != null) { + g.setColor(hoverBackColorRef.get()); + Dimension preferredSize = getPreferredSize(); + g.fillRoundRect(0, 0, preferredSize.width, preferredSize.height, 5, 5); + } + } + }; showAllPanel.setLayout(new BorderLayout(5, 0)); showAllPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); UILabel fontLabel = new UILabel(Toolkit.i18nText("Fine-Design_Startup_Page_Expand_All")); fontLabel.setForeground(HOVER_COLOR); + showAllPanel.setBackground(new Color(0, 0, 0, 0)); showAllPanel.add(fontLabel, BorderLayout.WEST); UILabel iconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/startup/show_more.svg")); @@ -183,28 +210,21 @@ public class StartupPageWorkspacePanel extends JPanel { showAllPanel.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { - Color hoverColor = new Color(217, 235, 254); - showAllPanel.setBackground(hoverColor); + Color hoverBackColor = new Color(217, 235, 254); + hoverBackColorRef.set(hoverBackColor); + repaintAll(); } @Override public void mouseExited(MouseEvent e) { + hoverBackColorRef.set(null); ColorUtils.syncBackground(showAllPanel, showAllBackground); + repaintAll(); } @Override public void mousePressed(MouseEvent e) { - if (showMore) { - fontLabel.setText(Toolkit.i18nText("Fine-Design_Startup_Page_Collapse_Workspace")); - iconLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/show_less.svg")); - showMoreContent(); - showMore = !showMore; - } else { - fontLabel.setText(Toolkit.i18nText("Fine-Design_Startup_Page_Expand_All")); - iconLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/show_more.svg")); - showLessContent(); - showMore = !showMore; - } + doShowAllAction(fontLabel, iconLabel); } }); tailPanel.add(showAllPanel); @@ -217,7 +237,11 @@ public class StartupPageWorkspacePanel extends JPanel { @NotNull private JPanel generatePartitionPanel(List partition) { - JPanel partitionPanel = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 20, 0);; + JPanel partitionPanelWrapper = new JPanel(); + partitionPanelWrapper.setBorder(new EmptyBorder(10,0,10,0)); + partitionPanelWrapper.setLayout(new BorderLayout()); + + JPanel partitionPanel = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 20, 0); partitionPanel.setName("partitionPanel"); for (StartupWorkspaceBean workspaceInfo : partition) { @@ -233,7 +257,9 @@ public class StartupPageWorkspacePanel extends JPanel { Dimension preferredSize = partitionPanel.getPreferredSize(); partitionPanel.setPreferredSize(new Dimension(CONTENT_WIDTH, (int) preferredSize.getHeight())); } - return partitionPanel; + + partitionPanelWrapper.add(partitionPanel, BorderLayout.CENTER); + return partitionPanelWrapper; } private void layoutSelectWorkspacePanel(StartupWorkspaceBean workspaceInfo, JPanel workspaceItemDesc) { @@ -298,8 +324,8 @@ public class StartupPageWorkspacePanel extends JPanel { int roundOffset = 15; // 画一个圆角 int fixRoundWidth = getWidth() - rectOffset; - int fixRoundHeight = getHeight() - BORDER_THIN * 2; - g2d.drawRoundRect(BORDER_THIN, BORDER_THIN, fixRoundWidth, fixRoundHeight, ARC_DIAMETER, ARC_DIAMETER); + int fixRoundHeight = getHeight() - BORDER_THIN; + g2d.drawRoundRect(strokeOffset, strokeOffset, fixRoundWidth, fixRoundHeight, ARC_DIAMETER, ARC_DIAMETER); g2d.setColor(backColor); @@ -313,9 +339,9 @@ public class StartupPageWorkspacePanel extends JPanel { g2d.fillRect(fixedX, BORDER_THIN, coverWidth, coverHeight); g2d.setColor(borderColor); - g2d.drawLine(getWidth() / 2, BORDER_THIN, getWidth(), BORDER_THIN); - g2d.drawLine(getWidth() / 2, getHeight() - BORDER_THIN, getWidth(), getHeight() - BORDER_THIN); - g2d.drawLine(getWidth() - strokeOffset, BORDER_THIN, getWidth() - strokeOffset, getHeight() - BORDER_THIN); + g2d.drawLine(getWidth() / 2, strokeOffset, getWidth(), strokeOffset); + g2d.drawLine(getWidth() / 2, getHeight() - strokeOffset, getWidth(), getHeight() - strokeOffset); + g2d.drawLine(getWidth() - strokeOffset, strokeOffset, getWidth() - strokeOffset, getHeight() - strokeOffset); } } }; @@ -366,7 +392,7 @@ public class StartupPageWorkspacePanel extends JPanel { borderColorRef.set(hoverColor); nameLabel.setForeground(hoverColor); pathLabel.setForeground(hoverColor ); - selectWorkspacePanel.getParent().repaint(); + repaintAll(); } @Override @@ -374,7 +400,7 @@ public class StartupPageWorkspacePanel extends JPanel { borderColorRef.set(Color.WHITE); nameLabel.setForeground(nameForeground); pathLabel.setForeground(pathColor); - selectWorkspacePanel.getParent().repaint(); + repaintAll(); } @Override @@ -382,13 +408,10 @@ public class StartupPageWorkspacePanel extends JPanel { int clickCount = e.getClickCount(); if (clickCount == DOUBLE_CLICK_COUNT) { - pageModel.setSelectWorkspaceInfo(workspaceInfo); - openEmptyTemplateRunnable.run(); + doOpenEmptyTemplate(workspaceInfo); return; } - // selectWorkspaceRunnable - pageModel.setSelectWorkspaceInfo(workspaceInfo); - selectWorkspaceRunnable.run(); + doSwitchWorkspace(workspaceInfo); } }; @@ -415,7 +438,7 @@ public class StartupPageWorkspacePanel extends JPanel { @Override public void mousePressed(MouseEvent e) { - openEmptyTemplateRunnable.run(); + doOpenEmptyTemplate(workspaceInfo); } }); descPanel.add(arrowLabel, BorderLayout.EAST); @@ -462,16 +485,15 @@ public class StartupPageWorkspacePanel extends JPanel { int borderOffset = BORDER_THIN * 2; // 画画的笔触需要调整一下 - //g2d.drawRoundRect(strokeOffset, strokeOffset, getWidth() - rectOffset, getHeight() - BORDER_THIN, 0, 0); - g2d.drawRoundRect(BORDER_THIN, BORDER_THIN, getWidth() - borderOffset, getHeight() - borderOffset, ARC_DIAMETER, ARC_DIAMETER); + g2d.drawRoundRect(strokeOffset, strokeOffset, getWidth() - borderOffset, getHeight() - BORDER_THIN, ARC_DIAMETER, ARC_DIAMETER); g2d.setColor(backColor); int fillWidth = 15; g2d.fillRect(0, 0, fillWidth, getHeight()); g2d.setColor(borderColor); - g2d.drawLine(BORDER_THIN, BORDER_THIN, fillWidth, BORDER_THIN); - g2d.drawLine(BORDER_THIN, getHeight() - BORDER_THIN, fillWidth, getHeight() - BORDER_THIN); - g2d.drawLine(BORDER_THIN, BORDER_THIN, BORDER_THIN, getHeight() - BORDER_THIN); + g2d.drawLine(strokeOffset, strokeOffset, fillWidth, strokeOffset); + g2d.drawLine(strokeOffset, getHeight() - strokeOffset, fillWidth, getHeight() - strokeOffset); + g2d.drawLine(strokeOffset, strokeOffset, strokeOffset, getHeight() - strokeOffset); } } @@ -488,15 +510,15 @@ public class StartupPageWorkspacePanel extends JPanel { @Override public void mouseEntered(MouseEvent e) { borderColorRef.set(HOVER_COLOR); - selectAndCreatePanel.getParent().repaint(); label.setIcon(IconUtils.readIcon("/com/fr/design/standard/system/add_hover.svg")); + repaintAll(); } @Override public void mouseExited(MouseEvent e) { borderColorRef.set(null); - selectAndCreatePanel.getParent().repaint(); label.setIcon(IconUtils.readIcon("/com/fr/design/standard/system/add.svg")); + repaintAll(); } @Override public void mousePressed(MouseEvent e) { @@ -515,4 +537,47 @@ public class StartupPageWorkspacePanel extends JPanel { this.selectWorkspaceRunnable = selectWorkspaceRunnable; } + private void doOpenEmptyTemplate(StartupWorkspaceBean workspaceInfo) { + + pageModel.setSelectWorkspaceInfo(workspaceInfo); + openEmptyTemplateRunnable.run(); + + DesignerMetrics designerMetrics = DesignerStartupContext.getInstance().getDesignerMetrics(); + designerMetrics.getStatistic().recordOpenEmptyTemplate(); + } + + private void doSwitchWorkspace(StartupWorkspaceBean workspaceInfo) { + + StartupWorkspaceBean lastWorkspaceInfo = pageModel.getSelectWorkspaceInfo(); + // selectWorkspaceRunnable + pageModel.setSelectWorkspaceInfo(workspaceInfo); + selectWorkspaceRunnable.run(); + + DesignerMetrics designerMetrics = DesignerStartupContext.getInstance().getDesignerMetrics(); + designerMetrics.getStatistic().recordSwitchWorkspace(lastWorkspaceInfo, workspaceInfo); + } + + private void doShowAllAction(UILabel fontLabel, UILabel iconLabel) { + + if (showMore) { + fontLabel.setText(Toolkit.i18nText("Fine-Design_Startup_Page_Collapse_Workspace")); + iconLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/show_less.svg")); + showMoreContent(); + showMore = !showMore; + } else { + fontLabel.setText(Toolkit.i18nText("Fine-Design_Startup_Page_Expand_All")); + iconLabel.setIcon(IconUtils.readIcon("/com/fr/design/startup/show_more.svg")); + showLessContent(); + showMore = !showMore; + } + DesignerMetrics designerMetrics = DesignerStartupContext.getInstance().getDesignerMetrics(); + designerMetrics.getStatistic().recordShowAllAction(); + + repaintAll(); + } + + private void repaintAll() { + + this.getRootPane().repaint(); + } } diff --git a/designer-base/src/main/resources/com/fr/design/startup/startup_page_background.jpg b/designer-base/src/main/resources/com/fr/design/startup/startup_page_background.jpg new file mode 100755 index 000000000..ad0c5de36 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/startup/startup_page_background.jpg differ diff --git a/designer-base/src/test/java/com/fr/startup/ui/StartupPageUtilTest.java b/designer-base/src/test/java/com/fr/startup/ui/StartupPageUtilTest.java new file mode 100644 index 000000000..fe69541e3 --- /dev/null +++ b/designer-base/src/test/java/com/fr/startup/ui/StartupPageUtilTest.java @@ -0,0 +1,21 @@ +package com.fr.startup.ui; + +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.*; + +public class StartupPageUtilTest { + + @Test + public void testGetRemoteAddress() throws Exception { + String remoteAddress = StartupPageUtil.getRemoteAddress("https://localhost:9090/webroot"); + Assert.assertEquals("localhost:9090", remoteAddress); + + String remoteAddress1 = StartupPageUtil.getRemoteAddress("https://localhost/webroot"); + Assert.assertEquals("localhost", remoteAddress1); + + String remoteAddress2 = StartupPageUtil.getRemoteAddress(null); + Assert.assertEquals("", remoteAddress2); + } +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java index dbffab21a..0353d53dd 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java @@ -35,6 +35,7 @@ import com.fr.general.act.BorderPacker; import com.fr.general.ComparatorUtils; import com.fr.general.FRFont; import com.fr.general.cardtag.DefaultTemplateStyle; +import com.fr.stable.StringUtils; import javax.swing.border.Border; import java.awt.*; @@ -132,14 +133,16 @@ public class XWCardTagLayout extends XWHorizontalBoxLayout { } int index = this.cardLayout.toData().getWidgetCount(); - //新加一个card - String widgetName = tagName + getTabNameIndex(); + //新加一个card,命名规则是tabxy,x为tablayout中tab的index,y为模板中tablayout 的index + String widgetName = tagName + getTabNameIndex() + getCardLayoutSuffix(cardLayout.toData().getWidgetName(), cardLayout.createDefaultName()); WTabFitLayout fitLayout = new WTabFitLayout(widgetName, tabFitIndex, currentCard); fitLayout.setTabNameIndex(getTabNameIndex()); XWTabFitLayout tabFitLayout = new XWTabFitLayout(fitLayout, new Dimension()); FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - ModelUtil.renameWidgetName(formDesigner.getTarget(), tabFitLayout); + if (formDesigner.getTarget().isNameExist(widgetName)) { + ModelUtil.renameWidgetName(formDesigner.getTarget(), tabFitLayout); + } WCardTagLayout layout = (WCardTagLayout) this.toData(); if(!ComparatorUtils.equals(layout.getTemplateStyle().getStyle(), DefaultTemplateStyle.DEFAULT_TEMPLATE_STYLE)){ @@ -154,6 +157,13 @@ public class XWCardTagLayout extends XWHorizontalBoxLayout { cardLayout.showCard(); } + private String getCardLayoutSuffix(String cardLayoutName, String defaultName){ + if (StringUtils.isEmpty(cardLayoutName) || StringUtils.isEmpty(defaultName) || !cardLayoutName.contains(defaultName)){ + return StringUtils.EMPTY; + } + return cardLayoutName.substring(defaultName.length()); + } + @Override protected String getIconName() { diff --git a/designer-realize/src/main/java/com/fr/design/actions/server/WidgetManagerAction.java b/designer-realize/src/main/java/com/fr/design/actions/server/WidgetManagerAction.java index ff8352e28..d04dc7697 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/server/WidgetManagerAction.java +++ b/designer-realize/src/main/java/com/fr/design/actions/server/WidgetManagerAction.java @@ -1,16 +1,15 @@ package com.fr.design.actions.server; -import com.fr.base.svg.IconUtils; import com.fr.design.DesignModelAdapter; import com.fr.design.actions.UpdateAction; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.mainframe.JTemplate; import com.fr.design.menu.MenuKeySet; import com.fr.design.webattr.WidgetManagerPane; import com.fr.form.ui.WidgetInfoConfig; - import com.fr.transaction.CallBackAdaptor; import com.fr.transaction.Configurations; import com.fr.transaction.WorkerFacade; @@ -61,7 +60,10 @@ public class WidgetManagerAction extends UpdateAction { if (model != null) { model.widgetConfigChanged(); } - designerFrame.getSelectedJTemplate().refreshToolArea(); + JTemplate jt = designerFrame.getSelectedJTemplate(); + if (JTemplate.isValid(jt)) { + jt.refreshToolArea(); + } } })); } diff --git a/designer-realize/src/main/java/com/fr/design/deeplink/FileOpen4MacDeepLink.java b/designer-realize/src/main/java/com/fr/design/deeplink/FileOpen4MacDeepLink.java index 5709aabd6..6eb3ea366 100644 --- a/designer-realize/src/main/java/com/fr/design/deeplink/FileOpen4MacDeepLink.java +++ b/designer-realize/src/main/java/com/fr/design/deeplink/FileOpen4MacDeepLink.java @@ -4,6 +4,7 @@ import com.fr.design.mainframe.DesignerContext; import com.fr.file.FileFILE; import com.fr.stable.StringUtils; import com.fr.stable.os.OperatingSystem; +import com.fr.start.common.DesignerStartupUtil; import java.io.File; import java.util.Map; @@ -23,6 +24,9 @@ public class FileOpen4MacDeepLink extends DeepLink { public void run(String url, String host, String path, Map params) { File file = new File(url); if (file.exists()) { + if (DesignerStartupUtil.openTemplateIfOnWaiting(file)) { + return; + } DesignerContext.getDesignerFrame().openTemplate(new FileFILE(file)); } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePaneDelegate.java b/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePaneDelegate.java index 5cc095cfa..66f97093e 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePaneDelegate.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/ElementCasePaneDelegate.java @@ -86,7 +86,7 @@ public class ElementCasePaneDelegate extends ElementCasePane { QuickEditorRegion.getInstance().populate(getCurrentEditor()); JTemplate editingTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); // 模板初始化完成后,才能初始化超级链接面板 - if (editingTemplate != null && !editingTemplate.isUpMode()) { + if (JTemplate.isValid(editingTemplate) && !editingTemplate.isUpMode()) { Selection editingSelection = getSelection(); // 获取超级链接面板并刷新显示 HyperlinkGroupPane hyperlinkGroupPane = editingTemplate.getHyperLinkPane(HyperlinkGroupPaneActionImpl.getInstance()); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java index 8de2a0d63..935d2d0e3 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java @@ -5,8 +5,9 @@ import com.fr.base.svg.IconUtils; import com.fr.design.i18n.Toolkit; import com.fr.design.utils.DesignUtils; import com.fr.general.CloudCenter; - import com.fr.general.IOUtils; + +import javax.swing.Icon; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; @@ -14,7 +15,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.LinkedHashSet; import java.util.Set; -import javax.swing.Icon; /** @@ -81,6 +81,8 @@ public class AlphaFineConstants { public static final Color WHITE = new Color(0xf9f9f9); + public static final Color LABEL_SELECTED = new Color(0x419bf9); + public static final Color GRAY = new Color(0xd2d2d2); public static final Color LIGHT_GRAY = new Color(0xcccccc); @@ -154,9 +156,21 @@ public class AlphaFineConstants { public static final String ALPHA_PREVIEW = CloudCenter.getInstance().acquireUrlByKind("af.preview"); - public static final String ALPHA_CID = CloudCenter.getInstance().acquireUrlByKind("af.cid", "https://cid.fanruan.com/api/nav/alphafine"); + public static final String ALPHA_CID = CloudCenter.getInstance().acquireUrlByKind("af.cid.new"); + + public static final String ALPHA_CID_USER_GROUP_INFO = CloudCenter.getInstance().acquireUrlByKind("af.cid.user.group.info"); + + public static final String SEARCH_BY_ID = "?id="; + + private static final String QUICK_START_URL = CloudCenter.getInstance().acquireUrlByKind("af.help.quick.start"); + private static final String REPORT_LEARNING_PATH = CloudCenter.getInstance().acquireUrlByKind("af.help.report.learning.path"); + private static final String PARAMETER_LEARNING_PATH = CloudCenter.getInstance().acquireUrlByKind("af.help.param.learning.path"); + private static final String FILL_LEARNING_PATH = CloudCenter.getInstance().acquireUrlByKind("af.help.fill.learning.path"); + private static final String API_SUMMARY = CloudCenter.getInstance().acquireUrlByKind("af.help.api.summary"); + private static final String MONTHLY_DOCUMENT = CloudCenter.getInstance().acquireUrlByKind("af.help.monthly.document"); + - private static final String DEFAULT_RECOMMEND = "[ { \"name\":\"快速入门指南\", \"link\":\"https://help.fanruan.com/finereport/doc-view-1335.html?source=3\" }, { \"name\":\"报表应用学习路径\", \"link\":\"https://help.fanruan.com/finereport/doc-view-1336.html?source=3\" }, { \"name\":\"参数应用学习路径\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4219.html?source=3\" }, { \"name\":\"填报学习路径\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4103.html?source=3\" }, { \"name\":\"API接口汇总\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4327.html?source=3\" }, { \"name\":\"文档月刊\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4613.html?source=3\" } ]"; + private static final String DEFAULT_RECOMMEND = "[ { \"name\":\"快速入门指南\", \"link\":\"" + QUICK_START_URL + "\" }, { \"name\":\"报表应用学习路径\", \"link\":\"" + REPORT_LEARNING_PATH + "\" }, { \"name\":\"参数应用学习路径\", \"link\":\"" + PARAMETER_LEARNING_PATH + "\" }, { \"name\":\"填报学习路径\", \"link\":\"" + FILL_LEARNING_PATH + "\" }, { \"name\":\"API接口汇总\", \"link\":\"" + API_SUMMARY + "\" }, { \"name\":\"文档月刊\", \"link\":\"" + MONTHLY_DOCUMENT + "\" } ]"; public static final String ALPHA_HELP_RECOMMEND = CloudCenter.getInstance().acquireUrlByKind("af.recommend", DEFAULT_RECOMMEND); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/CellType.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/CellType.java index c558ee584..fc01f668d 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/CellType.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/CellType.java @@ -17,7 +17,8 @@ public enum CellType { RECOMMEND_ROBOT(8), BOTTOM(9), ROBOT(10), - PRODUCT_NEWS(11, "productNews", "productNewsResult", true); + PRODUCT_NEWS(11, "productNews", "productNewsResult", true, false), + TEMPLATE_SHOP(12, "templateShop", "templateShop", false, true); private int typeValue; @@ -35,11 +36,19 @@ public enum CellType { private boolean needNetWork = true; - CellType(int type, String flagStr4None, String flagStr4Result, boolean needNetWork) { + private boolean canLocalSearch = false; + + + CellType(int type, String flagStr4None, String flagStr4Result, boolean needNetWork, boolean canLocalSearch) { this.typeValue = type; this.flagStr4None = flagStr4None; this.flagStr4Result = flagStr4Result; this.needNetWork = needNetWork; + this.canLocalSearch = canLocalSearch; + } + + CellType(int type, String flagStr4None, String flagStr4Result, boolean needNetWork) { + this(type, flagStr4None, flagStr4Result, needNetWork, false); } CellType(int type) { @@ -75,5 +84,8 @@ public enum CellType { public boolean isNeedNetWork() { return needNetWork; } -} + public boolean isCanLocalSearch() { + return canLocalSearch; + } +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/action/StartUseAction.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/action/StartUseAction.java new file mode 100644 index 000000000..0afd89308 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/action/StartUseAction.java @@ -0,0 +1,29 @@ +package com.fr.design.mainframe.alphafine.action; + +import com.fr.design.mainframe.alphafine.model.TemplateResourceDetail; +import com.fr.design.mainframe.alphafine.search.helper.FineMarketClientHelper; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + + +/** + * alphaFine - 模板资源 - 二级界面 - 开始使用按钮的绑定事件 + * + * 点击后跳转至帆软市场下载对应模板资源 + * + * TODO:可以参考mini组件商城的下载@ComponentsPackageInstallation#install + * */ +public class StartUseAction implements ActionListener { + + TemplateResourceDetail resourceDetail; + + public StartUseAction(TemplateResourceDetail detail) { + this.resourceDetail = detail; + } + + @Override + public void actionPerformed(ActionEvent e) { + FineMarketClientHelper.getInstance().openBrowserAndDownload(resourceDetail.getRoot()); + } +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java index b6819f56c..d653fae95 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java @@ -22,20 +22,34 @@ import com.fr.design.mainframe.alphafine.preview.NoResultPane; import com.fr.design.mainframe.alphafine.preview.NoResultWithLinkPane; import com.fr.design.mainframe.alphafine.preview.SearchLoadingPane; import com.fr.design.mainframe.alphafine.preview.SimpleRightSearchResultPane; +import com.fr.design.mainframe.alphafine.preview.TemplateShopPane; import com.fr.design.mainframe.alphafine.question.QuestionWindow; import com.fr.design.mainframe.alphafine.search.ProductNewsSearchWorkerManager; import com.fr.design.mainframe.alphafine.search.SearchTextBean; import com.fr.design.mainframe.alphafine.search.SearchWorkerManager; +import com.fr.design.mainframe.alphafine.search.TemplateResourceSearchWorkerManager; import com.fr.design.mainframe.alphafine.search.manager.impl.ActionSearchManager; import com.fr.design.mainframe.alphafine.search.manager.impl.DocumentSearchManager; import com.fr.design.mainframe.alphafine.search.manager.impl.FileSearchManager; import com.fr.design.mainframe.alphafine.search.manager.impl.PluginSearchManager; import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager; import com.fr.design.mainframe.alphafine.search.manager.impl.SegmentationManager; +import com.fr.design.mainframe.alphafine.search.manager.impl.TemplateResourceSearchManager; import com.fr.design.utils.DesignUtils; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.ComparatorUtils; import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JPopupMenu; +import javax.swing.SwingConstants; +import javax.swing.Timer; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; @@ -62,16 +76,6 @@ import java.util.List; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; -import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.JButton; -import javax.swing.JFrame; -import javax.swing.JPanel; -import javax.swing.JPopupMenu; -import javax.swing.SwingConstants; -import javax.swing.Timer; -import javax.swing.event.PopupMenuEvent; -import javax.swing.event.PopupMenuListener; /** * @author hades @@ -98,7 +102,7 @@ public class AlphaFineFrame extends JFrame { private static final String PLACE_HOLDER = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine"); - private static final String SETTING = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Set"); + private static final String FUNCTION = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Function"); private static final String NO_RESULT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_No_Result"); @@ -110,7 +114,7 @@ public class AlphaFineFrame extends JFrame { private static final String GO_FORUM = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Go_Forum"); - private static final String TEMPLATES = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Templates"); + private static final String MY_TEMPLATES = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_My_Templates"); public static final String PRODUCT_NEWS = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_News"); @@ -122,7 +126,7 @@ public class AlphaFineFrame extends JFrame { private static final String NO_SEARCH_RESULT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_NO_Result"); - private static final String PRODUCT_DYNAMICS = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_Dynamics"); + private static final String TEMPLATE_SHOP = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Shop"); private static final Image SEARCH_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/search.svg"); @@ -152,7 +156,19 @@ public class AlphaFineFrame extends JFrame { private JPanel tabPane; - private CellType selectedType; + private JPanel labelPane; + + private JPanel labelContentPane; + + private JPanel labelEastPane; + + private JPanel labelWestPane; + + private UILabel tabLabel; + + private UILabel readLabel; + + private SelectedLabel selectedTab; private String beforeSearchStr = StringUtils.EMPTY; @@ -168,15 +184,38 @@ public class AlphaFineFrame extends JFrame { private ProductNewsSearchWorkerManager productNewsSearchWorkerManager; + private TemplateResourceSearchWorkerManager templateResourceSearchWorkerManager; + public AlphaFineFrame() { this.setTitle(AlphaFineConstants.TITLE); + //去掉边框 setUndecorated(true); - setSize(AlphaFineConstants.FIELD_SIZE); + setSize(AlphaFineConstants.FULL_SIZE); initComponents(); centerWindow(this); initSearchManager(); } + public void showResult(String flag) { + cardLayout.show(resultPane, flag); + } + + public void addResult(JPanel panel, String flag) { + resultPane.add(panel, flag); + } + + public void removeSearchResultPane(JPanel panel) { + resultPane.remove(panel); + } + + public String getSearchText() { + return searchTextField.getText(); + } + + public CellType getSelectedType() { + return selectedTab.getCellType(); + } + private void initSearchManager() { this.productNewsSearchWorkerManager = new ProductNewsSearchWorkerManager( @@ -213,20 +252,26 @@ public class AlphaFineFrame extends JFrame { new LoadingRightSearchResultPane() ); + this.templateResourceSearchWorkerManager = new TemplateResourceSearchWorkerManager( + CellType.TEMPLATE_SHOP, + searchTextBean -> { + return TemplateResourceSearchManager.getInstance().getSearchResult(searchTextBean.getSearchText()); + }, + this + ); + } /** * 初始化全部组件 */ private void initComponents() { - add(createTopPane(), BorderLayout.NORTH); initSearchTextField(); add(createSearchPane(), BorderLayout.CENTER); add(createShowPane(), BorderLayout.SOUTH); this.getContentPane().setBackground(Color.WHITE); - this.setIconImage(SEARCH_IMAGE); - this.setSize(AlphaFineConstants.FULL_SIZE); + this.setIconImage(SEARCH_IMAGE); // 应用图标 } private JPanel createTopPane() { @@ -289,7 +334,6 @@ public class AlphaFineFrame extends JFrame { } }; - private JPopupMenu createTipPop() { JPanel panel = new JPanel(new BorderLayout()); String toolTip = AlphaFineShortCutUtil.getDisplayShortCut(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Short_Cut", DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getShortcuts())); @@ -372,29 +416,39 @@ public class AlphaFineFrame extends JFrame { return searchPane; } + /** + * showPane,内容展示区,分为三个小区,tab区,label区,内容区 + * */ private JPanel createShowPane() { JPanel showPane = new JPanel(new BorderLayout()); + + // 内容区,card layout resultPane.add(new DefaultProductNewsPane(), CellType.PRODUCT_NEWS.getFlagStr4None()); resultPane.add(new NoResultWithLinkPane(GO_FORUM, AlphaFineConstants.NO_RESULT_ICON), CellType.NO_RESULT.getFlagStr4None()); resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.ACTION.getFlagStr4None()); resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.FILE.getFlagStr4None()); resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.PLUGIN.getFlagStr4None()); resultPane.add(new HelpDocumentNoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.DOCUMENT.getFlagStr4None()); + resultPane.add(TemplateShopPane.getInstance(), CellType.TEMPLATE_SHOP.getFlagStr4None()); resultPane.add(new NetWorkFailedPane(this::reSearch), AlphaFineConstants.NETWORK_ERROR); - JPanel labelPane = new JPanel(new BorderLayout()); + + // label区,border layout + labelPane = new JPanel(new BorderLayout()); labelPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 20)); labelPane.setBackground(Color.WHITE); - JPanel labelContentPane = new JPanel(new BorderLayout()); - UILabel tabLabel = new UILabel(PRODUCT_DYNAMICS); + labelContentPane = new JPanel(new BorderLayout()); + tabLabel = new UILabel(PRODUCT_NEWS); tabLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); tabLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); - tabLabel.setPreferredSize(new Dimension(100, 30)); - JPanel westPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); - westPane.add(tabLabel); - labelContentPane.add(westPane, BorderLayout.WEST); - JPanel eastPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); - UILabel readLabel = new UILabel(ONE_CLICK_READ); + tabLabel.setPreferredSize(new Dimension(60, 30)); + tabLabel.setForeground(AlphaFineConstants.LABEL_SELECTED); + labelWestPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + labelWestPane.add(tabLabel); + labelContentPane.add(labelWestPane, BorderLayout.WEST); + labelEastPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); + // 一键已读 + readLabel = new UILabel(ONE_CLICK_READ); readLabel.setHorizontalAlignment(SwingConstants.RIGHT); readLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));; readLabel.setPreferredSize(new Dimension(100, 30)); @@ -406,24 +460,30 @@ public class AlphaFineFrame extends JFrame { showPane.repaint(); } }); - eastPane.add(readLabel); - labelContentPane.add(eastPane, BorderLayout.EAST); + labelEastPane.add(readLabel); + labelContentPane.add(labelEastPane, BorderLayout.EAST); labelContentPane.setBackground(new Color(245, 245, 247)); labelPane.add(labelContentPane); labelPane.setPreferredSize(new Dimension(AlphaFineConstants.FULL_SIZE.width, 30)); + // tab区 flow layout tabPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 10)); tabPane.setBackground(Color.WHITE); List selectedLabelList = createSelectedLabelList(); - selectedType = selectedLabelList.get(0).getCellType(); - // 第一个tab 非产品动态 - if (selectedType != CellType.PRODUCT_NEWS) { - tabLabel.setText(selectedLabelList.get(0).getText()); + selectedTab = null; + for (SelectedLabel label : selectedLabelList) { + if (label.isSelected()) { + selectedTab = label; + break; + } + } + if (this.selectedTab.getCellType() != CellType.PRODUCT_NEWS) { + tabLabel.setText(this.selectedTab.getText()); readLabel.setVisible(false); } - for (SelectedLabel selectedLabel : selectedLabelList) { - selectedLabel.addMouseListener(createMouseListener(selectedLabelList, selectedLabel, tabPane, tabLabel, readLabel)); - tabPane.add(selectedLabel); + for (SelectedLabel label : selectedLabelList) { + label.addMouseListener(createMouseListener(selectedLabelList, label, tabPane, tabLabel, readLabel)); + tabPane.add(label); } showPane.add(tabPane, BorderLayout.NORTH); showPane.add(labelPane, BorderLayout.CENTER); @@ -431,46 +491,47 @@ public class AlphaFineFrame extends JFrame { return showPane; } + public JPanel getLabelWestPane() { + return labelWestPane; + } + + public UILabel getTabLabel() { + return tabLabel; + } + private MouseAdapter createMouseListener(List selectedLabelList, SelectedLabel selectedLabel, JPanel tabPane, UILabel tabLabel, UILabel readLabel) { return new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { + // tab栏里的label全设置为没选中,并设置颜色为灰色 for (SelectedLabel label : selectedLabelList) { label.setSelected(false); label.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8); } + // 选中 selectedLabel.setSelected(true); + AlphaFineFrame.this.selectedTab = selectedLabel; + // 处理产品动态 tab与下方文字展示不一致 if (ComparatorUtils.equals(selectedLabel.getText().trim(), PRODUCT_NEWS)) { - tabLabel.setText(PRODUCT_DYNAMICS); + tabLabel.setText(PRODUCT_NEWS); } else { tabLabel.setText(selectedLabel.getText()); } + + // 刷新westlabelpane + refreshLabelPane(); + + // 将已读设置不可见 readLabel.setVisible(false); + + // tab栏重新绘制 tabPane.repaint(); - switch (selectedLabel.getCellType()) { - case PRODUCT_NEWS: - readLabel.setVisible(true); - switchType(CellType.PRODUCT_NEWS); - break; - case ACTION: - currentSearchWorkerManager = settingSearchWorkerManager; - switchType(CellType.ACTION); - break; - case FILE: - currentSearchWorkerManager = fileSearchWorkerManager; - switchType(CellType.FILE); - break; - case DOCUMENT: - currentSearchWorkerManager = documentWorkerManager; - switchType(CellType.DOCUMENT); - break; - case PLUGIN: - currentSearchWorkerManager = pluginSearchWorkerManager; - switchType(CellType.PLUGIN); - break; - } + + // 选中事件 + switchTab(selectedLabel.getCellType(), readLabel); + if (currentSearchWorkerManager != null) { AlphaFineList alphaFineList = currentSearchWorkerManager.getSearchResultList(); if (alphaFineList != null) { @@ -494,17 +555,51 @@ public class AlphaFineFrame extends JFrame { }; } + + // 方便记埋点 + private void switchTab(CellType cellType, UILabel readLabel) { + switch (cellType) { + case PRODUCT_NEWS: + readLabel.setVisible(true); + switchType(CellType.PRODUCT_NEWS); + break; + case ACTION: + currentSearchWorkerManager = settingSearchWorkerManager; + switchType(CellType.ACTION); + break; + case FILE: + currentSearchWorkerManager = fileSearchWorkerManager; + switchType(CellType.FILE); + break; + case DOCUMENT: + currentSearchWorkerManager = documentWorkerManager; + switchType(CellType.DOCUMENT); + break; + case PLUGIN: + currentSearchWorkerManager = pluginSearchWorkerManager; + switchType(CellType.PLUGIN); + break; + case TEMPLATE_SHOP: + TemplateShopPane.getInstance().showPagePane(); + switchType(CellType.TEMPLATE_SHOP); + break; + } + } + + private void refreshLabelPane() { + labelWestPane.removeAll(); + labelWestPane.add(tabLabel); + } + private List createSelectedLabelList() { List selectedLabelList = new ArrayList<>(); AlphaFineConfigManager alphaFineConfigManager = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager(); if (alphaFineConfigManager.isProductDynamics()) { - selectedLabelList.add(new SelectedLabel(PRODUCT_NEWS, CellType.PRODUCT_NEWS, true)); + selectedLabelList.add(new SelectedLabel(PRODUCT_NEWS, CellType.PRODUCT_NEWS)); } - if (alphaFineConfigManager.isContainAction()) { - selectedLabelList.add(new SelectedLabel(SETTING, CellType.ACTION)); - } - if (alphaFineConfigManager.isContainFileContent() || alphaFineConfigManager.isContainTemplate()) { - selectedLabelList.add(new SelectedLabel(TEMPLATES, CellType.FILE)); + // 默认选中模板商城 + if (alphaFineConfigManager.hasTemplateShop()) { + selectedLabelList.add(new SelectedLabel(TEMPLATE_SHOP, CellType.TEMPLATE_SHOP, true)); } if (alphaFineConfigManager.isContainDocument()) { selectedLabelList.add(new SelectedLabel(HELP, CellType.DOCUMENT)); @@ -512,6 +607,19 @@ public class AlphaFineFrame extends JFrame { if (alphaFineConfigManager.isContainPlugin()) { selectedLabelList.add(new SelectedLabel(PLUGIN, CellType.PLUGIN)); } + if (alphaFineConfigManager.isContainAction()) { + selectedLabelList.add(new SelectedLabel(FUNCTION, CellType.ACTION)); + } + if (alphaFineConfigManager.isContainMyTemplate()) { + selectedLabelList.add(new SelectedLabel(MY_TEMPLATES, CellType.FILE)); + } + + + // 如果不展示模板商城,则list中第一个被选中 + if (!alphaFineConfigManager.hasTemplateShop() && !selectedLabelList.isEmpty()) { + selectedLabelList.get(0).setSelected(true); + } + return selectedLabelList; } @@ -524,7 +632,6 @@ public class AlphaFineFrame extends JFrame { } private void switchType(CellType cellType) { - this.selectedType = cellType; if (StringUtils.isEmpty(searchTextField.getText())) { cardLayout.show(resultPane, cellType.getFlagStr4None()); } else { @@ -541,8 +648,7 @@ public class AlphaFineFrame extends JFrame { if (checkNetworkError()) { return; } - - cardLayout.show(resultPane, cellType.getFlagStr4Result()); + showResult(cellType.getFlagStr4Result()); checkSearchResult(); } @@ -550,23 +656,23 @@ public class AlphaFineFrame extends JFrame { private boolean checkNetworkError() { boolean networkError; - if (selectedType == CellType.PRODUCT_NEWS) { + if (selectedTab.getCellType() == CellType.PRODUCT_NEWS) { networkError = productNewsSearchWorkerManager.isNetWorkError(); } else { networkError = currentSearchWorkerManager.isNetWorkError(); } - cardLayout.show(resultPane, AlphaFineConstants.NETWORK_ERROR); + showResult(AlphaFineConstants.NETWORK_ERROR); return networkError; } private boolean checkSearchLoading() { boolean searchOver; - if (selectedType == CellType.PRODUCT_NEWS) { + if (selectedTab.getCellType() == CellType.PRODUCT_NEWS) { searchOver = productNewsSearchWorkerManager.isSearchOver(); } else { searchOver = currentSearchWorkerManager.isSearchOver(); } - cardLayout.show(resultPane, AlphaFineConstants.LOADING); + showResult(AlphaFineConstants.LOADING); return searchOver; } @@ -587,14 +693,14 @@ public class AlphaFineFrame extends JFrame { searchResultList.requestFocus(); } boolean hasSearchResult = true; - if (selectedType == CellType.PRODUCT_NEWS) { + if (selectedTab.getCellType() == CellType.PRODUCT_NEWS) { hasSearchResult = productNewsSearchWorkerManager.hasSearchResult(); } else { hasSearchResult = currentSearchWorkerManager.hasSearchResult(); } if (!hasSearchResult) { - cardLayout.show(resultPane, CellType.NO_RESULT.getFlagStr4None()); + showResult(CellType.NO_RESULT.getFlagStr4None()); } } @@ -608,7 +714,6 @@ public class AlphaFineFrame extends JFrame { searchTextField.setBorder(null); } - private void initTextFieldListener() { searchTextField.addKeyListener(new KeyAdapter() { @Override @@ -659,20 +764,24 @@ public class AlphaFineFrame extends JFrame { } + /** + * 控制搜索tip框弹出收起 + * 不断地刷新tab页,并防止tab页显示错误 + * */ private void startSearchTextFieldTimer() { Timer timer = new Timer(TIMER_DELAY, e -> { // 坑 isShowing返回false 即使textField有内容 getText返回的也是空 if (searchTextField.isShowing() && StringUtils.isEmpty(searchTextField.getText())) { SearchTooltipPopup.getInstance().hide(); clearLabel.setVisible(false); - switchType(selectedType); + switchType(selectedTab.getCellType()); + TemplateShopPane.getInstance().quitSearchResultPane(); beforeSearchStr = StringUtils.EMPTY; } else if (searchTextField.hasFocus()) { clearLabel.setVisible(true); SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane); } tabPane.repaint(); - }); timer.start(); } @@ -751,21 +860,8 @@ public class AlphaFineFrame extends JFrame { } } - public void showResult(String flag) { - cardLayout.show(resultPane, flag); - } - - public void addResult(JPanel panel, String flag) { - resultPane.add(panel, flag); - } - - public void removeSearchResultPane(JPanel panel) { - resultPane.remove(panel); - } - - - private void doSearch(String text) { + refreshLabelPane(); initSearchLoadingPane(); SearchTextBean searchTextBean = generateSearchTextBean(text); this.productNewsSearchWorkerManager.doSearch(searchTextBean); @@ -773,6 +869,7 @@ public class AlphaFineFrame extends JFrame { this.fileSearchWorkerManager.doSearch(searchTextBean); this.documentWorkerManager.doSearch(searchTextBean); this.pluginSearchWorkerManager.doSearch(searchTextBean); + this.templateResourceSearchWorkerManager.doSearch(searchTextBean); } private SearchTextBean generateSearchTextBean(String searchText) { @@ -806,25 +903,15 @@ public class AlphaFineFrame extends JFrame { this.pluginSearchWorkerManager.doSearch(searchTextBean); } + /** + * 所有tab页搜索通用的加载panel + * */ private void initSearchLoadingPane() { if (searchLoadingPane == null) { searchLoadingPane = new SearchLoadingPane(); } resultPane.add(searchLoadingPane, AlphaFineConstants.LOADING); - cardLayout.show(resultPane, AlphaFineConstants.LOADING); - } - - public String getSearchText() { - return searchTextField.getText(); - } - - - public CellType getSelectedType() { - return selectedType; - } - - public void setStoreText(String storeText) { - this.storeText = storeText; + showResult(AlphaFineConstants.LOADING); } /** @@ -839,6 +926,9 @@ public class AlphaFineFrame extends JFrame { return storeText; } + public void setStoreText(String storeText) { + this.storeText = storeText; + } /** * 去除特殊字符,空格等 @@ -894,6 +984,7 @@ public class AlphaFineFrame extends JFrame { @Override public void setVisible(boolean b) { super.setVisible(b); + switchTab(selectedTab.getCellType(), readLabel); QuestionWindow.getInstance().setVisible(!b); if (!b) { AlphaFineHelper.resetAlphaFineDialog(); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsList.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsList.java index 1a8e0a2a2..48dfa4b86 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsList.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsList.java @@ -5,18 +5,15 @@ import com.fr.design.mainframe.alphafine.AlphaFineConstants; import com.fr.design.mainframe.alphafine.AlphaFineHelper; import com.fr.design.mainframe.alphafine.model.ProductNews; import com.fr.design.utils.BrowseUtils; -import com.fr.log.FineLoggerFactory; +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.ListModel; import java.awt.Cursor; -import java.awt.Desktop; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; -import java.net.URI; -import javax.swing.DefaultListModel; -import javax.swing.JList; -import javax.swing.ListModel; /** * @author hades @@ -64,11 +61,16 @@ public class ProductNewsList extends JList { private void dealWithClick() { ProductNews productNews = getSelectedValue(); - BrowseUtils.browser(productNews.getUrl()); + openNewsInBrowser(productNews.getUrl()); DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet().add(productNews.getId()); AlphaFineHelper.getAlphaFineDialog().repaint(); } + // 方便埋点 + private void openNewsInBrowser(String url) { + BrowseUtils.browser(url); + } + public int getHoverIndex() { return hoverIndex; } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/RecommendSearchPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/RecommendSearchPane.java new file mode 100644 index 000000000..a0b0ef4bf --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/RecommendSearchPane.java @@ -0,0 +1,74 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.model.TemplateResource; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.FlowLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; + +public class RecommendSearchPane extends TemplateResourcePanel { + + private static final Color BORDER_WHITE = new Color(0xe8e8e9); + private static final Color RECOMMEND_SEARCH_KEY_BLUE = new Color(0x419bf9); + + public RecommendSearchPane(TemplateResource templateResource) { + super(); + setTemplateResource(templateResource); + initComponent(); + this.setLayout(new BorderLayout()); + + this.setBorder(BorderFactory.createLineBorder(BORDER_WHITE, 1)); + this.add(getNorthPane(), BorderLayout.NORTH); + this.add(getSouthPane(), BorderLayout.SOUTH); + } + + private void initComponent() { + createNorthPane(); + createSouthPane(); + } + + + private void createSouthPane() { + setSouthPane(new JPanel(new FlowLayout(FlowLayout.LEFT))); + JPanel southPane = getSouthPane(); + southPane.setBackground(Color.WHITE); + JLabel recommend = new JLabel(Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Resource_Recommend_For_You")); + southPane.add(recommend); + + List searchKeys = getTemplateResource().getRecommendSearchKey(); + + for (String key : searchKeys) { + JLabel keyLabel = new SearchKeyLabel(key); + southPane.add(keyLabel); + } + } + + + class SearchKeyLabel extends JLabel { + String searchKey; + + SearchKeyLabel(String searchKey) { + this.searchKey = searchKey; + setText(searchKey); + setBackground(Color.WHITE); + setForeground(RECOMMEND_SEARCH_KEY_BLUE); + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + AlphaFineHelper.getAlphaFineDialog().fireSearch(searchKey); + } + }); + } + + + } + +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/TemplateResourceImagePanel.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/TemplateResourceImagePanel.java new file mode 100644 index 000000000..13d29d76f --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/TemplateResourceImagePanel.java @@ -0,0 +1,74 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.base.GraphHelper; +import com.fr.design.mainframe.alphafine.model.TemplateResource; +import com.fr.third.jodd.util.StringUtil; + +import javax.swing.JPanel; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; + + +public class TemplateResourceImagePanel extends JPanel { + + private static final int BACKGROUND_HEIGHT = 20; + + private static final Color BACKGROUND_COLOR = new Color(116, 181, 249); + + private static final Color COVER_COLOR = new Color(116, 181, 249, 26); + + private TemplateResource templateResource; + + private int width = 200; + private int height = 100; + + public TemplateResourceImagePanel(TemplateResource templateResource) { + this.templateResource = templateResource; + } + + public TemplateResourceImagePanel(TemplateResource templateResource, int width, int height) { + this(templateResource); + this.width = width; + this.height = height; + } + + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + Color defaultColor = g2.getColor(); + + Image image = templateResource.getImage(); + if (image != null) { + g2.drawImage(templateResource.getImage(), 0, 0, getWidth(), getHeight(), this); + } else { + g2.setColor(COVER_COLOR); + g2.fillRect(0, 0, getWidth(), getHeight()); + } + + String tagName = templateResource.getType().getName(); + + if (!StringUtil.isEmpty(tagName)) { + g2.setColor(BACKGROUND_COLOR); + g2.fillRect(0, getHeight() - BACKGROUND_HEIGHT, getWidth(), BACKGROUND_HEIGHT); + g2.setColor(Color.WHITE); + int x = (getWidth() - GraphHelper.getWidth(tagName, g2.getFont())) / 2; + g2.drawString(tagName, x, getHeight() - 5); + } + g2.setColor(defaultColor); + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(width, height); + } + + +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/TemplateResourcePageGridPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/TemplateResourcePageGridPane.java new file mode 100644 index 000000000..2bafebc56 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/TemplateResourcePageGridPane.java @@ -0,0 +1,225 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.base.svg.IconUtils; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.alphafine.model.TemplateResource; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Label; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * 卡片布局,每个卡片里塞了scrollpanel + * */ +public class TemplateResourcePageGridPane extends JPanel { + + private List data; + private CardLayout cardLayout; + private List pages; + private int totalPage; + + List scrollPanes = new ArrayList<>(); + + private static final int PAGE_MAX_SIZE = 12; + private static final int TABLE_MAX_ROW_COUNT = 4; + private static final int TABLE_COL_COUNT = 3; + private static final int TABLE_VGAP = 15; + private static final int TABLE_HGAP = 15; + private static final int RESOURCE_WIDTH = 197; + private static final int RESOURCE_HEIGHT = 128; + + public TemplateResourcePageGridPane(List templateResourceList) { + this.data = templateResourceList; + totalPage = (int) Math.ceil((double)data.size() / PAGE_MAX_SIZE); + createPages(); + initComponents(); + this.setBackground(Color.WHITE); + this.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 20)); + switchPage(1); + } + + private void initComponents() { + cardLayout = new CardLayout(); + this.setLayout(cardLayout); + this.setBackground(Color.WHITE); + for (int i = 0; i < pages.size(); i++) { + UIScrollPane scrollPane = new UIScrollPane(pages.get(i)); + scrollPanes.add(scrollPane); + this.add(scrollPane, String.valueOf(i + 1)); + } + } + + + /** + * 构建分页,将资源切分到每一页,并在每一页尾部添加分页按钮 + * */ + private void createPages() { + int dataCnt = data.size(); + List[] slice = new ArrayList[totalPage]; + for (int i = 0; i < dataCnt; i++) { + int index = i / PAGE_MAX_SIZE; + if (slice[index] == null) { + slice[index] = new ArrayList<>(); + } + slice[index].add(data.get(i)); + } + pages = new ArrayList<>(); + for (int i = 0; i < totalPage; i++) { + pages.add(new Page(slice[i], i + 1)); + } + } + + + private void switchPage(int pageNumber) { + if (pageNumber < 1 || pageNumber > this.totalPage) { + return; + } + cardLayout.show(TemplateResourcePageGridPane.this, String.valueOf(pageNumber)); + scrollPanes.get(pageNumber - 1).getVerticalScrollBar().setValue(0); + // 坑,切换页面会刷新失败,需要手动滚动一下才能刷新 + scrollPanes.get(pageNumber - 1).getVerticalScrollBar().setValue(1); + scrollPanes.get(pageNumber - 1).getVerticalScrollBar().setValue(0); + } + + + /** + * 分页panel,borderlayout布局,north为信息页,south为分页按钮区 + * */ + private class Page extends JPanel { + List pageData; + Component[][] comps; + + JPanel contentPane; + + JPanel pageButtonPane; + JButton prev, next; + JTextField pageNumberField; + JLabel pageCnt; + + int pageNumber; + + Page(List pageData, int pageNumber) { + super(); + this.pageData = pageData; + this.pageNumber = pageNumber; + initComponents(); + this.setLayout(new BorderLayout()); + this.add(contentPane, BorderLayout.NORTH); + if (totalPage > 1) { + this.add(pageButtonPane, BorderLayout.SOUTH); + } + this.setBackground(Color.WHITE); + } + + private void initComponents() { + createContentPane(); + createPageButtonPane(); + } + + void createContentPane() { + int dataCnt = pageData.size(); + int rowCnt = (int) Math.ceil((double)dataCnt / 3); + double[] rowHeight = new double[rowCnt]; + double[] colWidth = new double[TABLE_COL_COUNT]; + Arrays.fill(rowHeight, RESOURCE_HEIGHT); + Arrays.fill(colWidth, RESOURCE_WIDTH); + comps = new Component[rowCnt][TABLE_COL_COUNT]; + + for (int i = 0; i < rowCnt; i++) { + for (int j = 0; j < TABLE_COL_COUNT; j++) { + int which = i * 3 + j; + if (which >= dataCnt) { + Label empty = new Label(); + empty.setPreferredSize(new Dimension(RESOURCE_WIDTH, RESOURCE_HEIGHT)); + empty.setVisible(false); + comps[i][j] = empty; + } else { + TemplateResourcePanel resource = TemplateResourcePanel.create(pageData.get(which)); + resource.setPreferredSize(new Dimension(RESOURCE_WIDTH, RESOURCE_HEIGHT)); + comps[i][j] = resource; + } + } + } + contentPane = TableLayoutHelper.createGapTableLayoutPane(comps, rowHeight, colWidth, TABLE_HGAP, TABLE_VGAP); + contentPane.setBackground(Color.WHITE); + } + + void createPageButtonPane() { + prev = new JButton(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/prev.svg")); + next = new JButton(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/next.svg")); + pageNumberField = new JTextField((int) Math.log10(totalPage) + 1); + pageNumberField.setText(String.valueOf(this.pageNumber)); + pageCnt = new JLabel("/ " + totalPage); + + pageButtonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + pageButtonPane.add(prev); + pageButtonPane.add(pageNumberField); + pageButtonPane.add(pageCnt); + pageButtonPane.add(next); + + addPageAction(); + } + + // 添加翻页按钮事件 + void addPageAction() { + addPrevPageAction(); + addNextPageAction(); + addGotoPageAction(); + } + + void addPrevPageAction() { + prev.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (pageNumber > 1) { + switchPage(pageNumber - 1); + } + } + }); + }; + void addNextPageAction() { + next.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (pageNumber < totalPage) { + switchPage(pageNumber + 1); + } + } + }); + + } + void addGotoPageAction() { + pageNumberField.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + super.keyPressed(e); + String numb = pageNumberField.getText(); + if (numb != null && !numb.equals(pageNumber)) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + switchPage(Integer.parseInt(numb)); + } + } + } + }); + } + } +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/TemplateResourcePanel.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/TemplateResourcePanel.java new file mode 100644 index 000000000..4eba18c63 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/TemplateResourcePanel.java @@ -0,0 +1,122 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.alphafine.model.TemplateResource; +import com.fr.design.mainframe.alphafine.preview.TemplateShopPane; +import com.fr.design.utils.BrowseUtils; +import com.fr.log.FineLoggerFactory; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + + +public class TemplateResourcePanel extends JPanel { + + private JPanel northPane; + private JPanel southPane; + private TemplateResource templateResource; + + private static final Color PANEL_BORDER_COLOR = new Color(0xe8e8e9); + private static final Color DEMO_LABEL_FOREGROUND = new Color(0x419bf9); + + protected TemplateResourcePanel() { + + } + + protected TemplateResourcePanel(TemplateResource templateResource) { + this.templateResource = templateResource; + initComponent(); + this.setLayout(new BorderLayout()); + this.setBorder(BorderFactory.createLineBorder(PANEL_BORDER_COLOR, 1)); + this.add(northPane, BorderLayout.NORTH); + this.add(southPane, BorderLayout.SOUTH); + addAction(); + } + + private void addAction() { + this.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + TemplateShopPane.getInstance().searchAndShowDetailPane(templateResource); + } + }); + } + + public static TemplateResourcePanel create(TemplateResource templateResource) { + if (TemplateResource.Type.RECOMMEND_SEARCH.equals(templateResource.getType())) { + return new RecommendSearchPane(templateResource); + } else { + return new TemplateResourcePanel(templateResource); + } + } + + public JPanel getNorthPane() { + return northPane; + } + public JPanel getSouthPane() { + return southPane; + } + public TemplateResource getTemplateResource() { + return templateResource; + } + + public void setNorthPane(JPanel northPane) { + this.northPane = northPane; + } + + public void setSouthPane(JPanel southPane) { + this.southPane = southPane; + } + + public void setTemplateResource(TemplateResource templateResource) { + this.templateResource = templateResource; + } + + private void initComponent() { + createNorthPane(); + createSouthPane(); + } + + protected void createNorthPane() { + northPane = new TemplateResourceImagePanel(templateResource); + } + + private void createSouthPane() { + JLabel nameLabel = new JLabel(templateResource.getName()); + nameLabel.setBackground(Color.WHITE); + nameLabel.setBorder(BorderFactory.createEmptyBorder()); + + JLabel demoLabel = new JLabel(); + if (templateResource.hasDemoUrl()) { + demoLabel.setText(Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Resource_Demo")); + demoLabel.setForeground(DEMO_LABEL_FOREGROUND); + demoLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + try { + BrowseUtils.browser(templateResource.getDemoUrl()); + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex, ex.getMessage()); + } + } + }); + } + + southPane = new JPanel(new BorderLayout()); + southPane.setBackground(Color.WHITE); + southPane.add(nameLabel, BorderLayout.WEST); + southPane.add(demoLabel, BorderLayout.EAST); + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(180, 90); + } +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/ProductNews.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/ProductNews.java index aea152da2..1673f3bb8 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/ProductNews.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/ProductNews.java @@ -1,8 +1,12 @@ package com.fr.design.mainframe.alphafine.model; import com.fr.design.i18n.Toolkit; + import java.awt.Image; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; +import java.util.List; /** * 产品动态 @@ -17,7 +21,9 @@ public class ProductNews { private String title; private Tag tag; - private Target target; + + // 推送对象,对象为 list<用户组id> + private List target; private Status status; private String url; @@ -26,6 +32,8 @@ public class ProductNews { private Date pushDate; + public static final String ALL_USER_TARGET = "0"; + /** * 创建cid的用户 */ @@ -58,11 +66,11 @@ public class ProductNews { return this; } - public Target getTarget() { + public List getTarget() { return target; } - public ProductNews setTarget(Target target) { + public ProductNews setTarget(List target) { this.target = target; return this; } @@ -172,29 +180,18 @@ public class ProductNews { } } - public enum Target { - ALL_USER(0); - - private final int code; - - Target(int code) { - this.code = code; - } - - public int getCode() { - return code; - } - - public static Target parseCode(int code) { - for (Target target : values()) { - if (target.code == code) { - return target; - } - } - throw new IllegalArgumentException(); + /** + * 将接口中的target字段转换一下 + * 原始数据是字符串,例如:"1,2,3,4" + * 转换为 List{1,2,3,4} + * */ + public static List ParseTarget(String s) { + List list = new ArrayList<>(); + if (s != null) { + String[] targets = s.split(","); + list.addAll(Arrays.asList(targets)); } - + return list; } - } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/TemplateResource.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/TemplateResource.java new file mode 100644 index 000000000..93d1f4d0a --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/TemplateResource.java @@ -0,0 +1,191 @@ +package com.fr.design.mainframe.alphafine.model; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.alphafine.search.manager.impl.TemplateResourceSearchManager; +import com.fr.general.IOUtils; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.third.jodd.util.StringUtil; + +import java.awt.Image; +import java.util.ArrayList; +import java.util.List; + + +/** + * 模板资源数据 + */ +public class TemplateResource { + + /*** + * 模板资源类型:模板,解决方案,推荐搜索 + */ + public enum Type { + SINGLE_TEMPLATE(Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Resource_Single_Template")), + SCENARIO_SOLUTION(Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Resource_Scenario_Solution")), + RECOMMEND_SEARCH; + + private String name; + + Type() { + } + + Type(String name) { + this.name = name; + } + + public String getName() { + return name; + } + } + + // 模板资源搜索接口返回值字段名 + public static final String ID = "id"; + public static final String UUID = "uuid"; + public static final String NAME = "name"; + public static final String IMAGE_URL = "pic"; + public static final String DEMO_URL = "demoUrl"; + public static final String PKG_SIZE = "pkgsize"; + private static final String RECOMMEND_SEARCH_IMG_URL = "com/fr/design/mainframe/alphafine/images/more.png"; + + + // 模板资源属性 + private String id; + private String uuid; + private Type type; + private String imageUrl; + private Image image; + private String name; + private String demoUrl; + private int pkgSize; + private List recommendSearchKey; + + public static List createByJson(JSONArray jsonArray) { + List list = new ArrayList<>(); + if (jsonArray != null) { + for (int i = jsonArray.length() - 1; i >= 0; i--) { + list.add(createByJson(jsonArray.getJSONObject(i))); + } + } + return list; + } + + + public static TemplateResource createByJson(JSONObject jsonObject) { + + TemplateResource templateResource = new TemplateResource().setId(jsonObject.getString(ID)).setUuid(jsonObject.getString(UUID)).setName(jsonObject.getString(NAME)) + .setDemoUrl(jsonObject.getString(DEMO_URL)).setPkgSize(jsonObject.getInt(PKG_SIZE)); + int pkgSize = templateResource.getPkgSize(); + if (pkgSize == 0) { + templateResource.type = Type.SINGLE_TEMPLATE; + } else { + templateResource.type = Type.SCENARIO_SOLUTION; + } + + templateResource.setImageUrl(parseUrl(jsonObject)); + + templateResource.setImage(IOUtils.readImage(templateResource.imageUrl)); + return templateResource; + } + + /** + * 商城接口传过来的图片url是特殊格式,需要特殊处理下 + * */ + static String parseUrl(JSONObject jsonObject) { + String imgUrl = jsonObject.getString(IMAGE_URL); + int index = imgUrl.indexOf(","); + if (index != -1) { + imgUrl = imgUrl.substring(0, imgUrl.indexOf(",")); + } + return imgUrl; + } + + public static TemplateResource getRecommendSearch() { + TemplateResource recommend = new TemplateResource(); + recommend.setType(Type.RECOMMEND_SEARCH); + recommend.setImageUrl(RECOMMEND_SEARCH_IMG_URL); + recommend.setImage(IOUtils.readImage(RECOMMEND_SEARCH_IMG_URL)); + recommend.setRecommendSearchKey(TemplateResourceSearchManager.getInstance().getRecommendSearchKeys()); + return recommend; + } + + + public Type getType() { + return type; + } + + public void setType(Type type) { + this.type = type; + } + + public List getRecommendSearchKey() { + return recommendSearchKey; + } + + public void setRecommendSearchKey(List recommendSearchKey) { + this.recommendSearchKey = recommendSearchKey; + } + + public TemplateResource setImage(Image image) { + this.image = image; + return this; + } + + public Image getImage() { + return image; + } + + public TemplateResource setImageUrl(String imageUrl) { + this.imageUrl = imageUrl; + return this; + } + + public String getName() { + return name; + } + + public TemplateResource setName(String name) { + this.name = name; + return this; + } + + public String getDemoUrl() { + return demoUrl; + } + + public boolean hasDemoUrl() { + return !StringUtil.isEmpty(demoUrl); + } + + public TemplateResource setDemoUrl(String demoUrl) { + this.demoUrl = demoUrl; + return this; + } + + public int getPkgSize() { + return pkgSize; + } + + public TemplateResource setPkgSize(int pkgSize) { + this.pkgSize = pkgSize; + return this; + } + + public String getId() { + return id; + } + + public TemplateResource setId(String id) { + this.id = id; + return this; + } + + public String getUuid() { + return uuid; + } + + public TemplateResource setUuid(String uuid) { + this.uuid = uuid; + return this; + } +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/TemplateResourceDetail.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/TemplateResourceDetail.java new file mode 100644 index 000000000..74b470d53 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/TemplateResourceDetail.java @@ -0,0 +1,208 @@ +package com.fr.design.mainframe.alphafine.model; + + +import com.fr.design.mainframe.alphafine.search.helper.FineMarketClientHelper; +import com.fr.design.mainframe.alphafine.search.manager.impl.TemplateResourceSearchManager; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 模板资源详细数据 + */ +public class TemplateResourceDetail { + + // 与对应的模板资源关联 + private final TemplateResource root; + private String info; + private String vendor; + private List detailInfo; + private String[] tagsId; + private List tagsName; + private double price; + private String parentPkgName; + private String resourceUrl; + + public static final String ID = "id"; + public static final String INFO = "description"; + public static final String VENDOR = "vendor"; + public static final String DETAIL_INFO = "text"; + public static final String TAGS_ID = "cid"; + public static final String PRICE = "price"; + public static final String NAME = "name"; + public static final String PARENT_NAME = "parentName"; + public static final String TAGS_NAME = "tagsName"; + public static final String URL = "url"; + + + + public TemplateResourceDetail(TemplateResource resource) { + this.root = resource; + } + + + public String getVendor() { + return vendor; + } + + public void setVendor(String vendor) { + this.vendor = vendor; + } + + public TemplateResource getRoot() { + return root; + } + + public String getInfo() { + return info; + } + + public void setInfo(String info) { + this.info = info; + } + + public List getDetailInfo() { + return detailInfo; + } + + public void setDetailInfo(List detailInfo) { + this.detailInfo = detailInfo; + } + + public String[] getTagsId() { + return tagsId; + } + + public void setTagsId(String[] tagsId) { + this.tagsId = tagsId; + } + + public List getTagsName() { + return tagsName; + } + + public void setTagsName(List tagsName) { + this.tagsName = tagsName; + } + + public double getPrice() { + return price; + } + + public void setPrice(double price) { + this.price = price; + } + + public String getParentPkgName() { + return parentPkgName; + } + + public void setParentPkgName(String parentPkgName) { + if (StringUtils.isEmpty(parentPkgName)) { + this.parentPkgName = ""; + } else { + this.parentPkgName = parentPkgName; + } + } + + public String getResourceUrl() { + return resourceUrl; + } + + public void setResourceUrl(String resourceUrl) { + this.resourceUrl = resourceUrl; + } + + + public static TemplateResourceDetail createByTemplateResource(TemplateResource root) { + return Builder.buildByResource(root); + } + + public static TemplateResourceDetail createFromEmbedResource(TemplateResource root) { + return Builder.buildFromEmbedResource(root); + } + + static class Builder { + + static FineMarketClientHelper helper = FineMarketClientHelper.getInstance(); + + static TemplateResourceDetail buildFromEmbedResource(TemplateResource templateResource) { + TemplateResourceDetail detail = new TemplateResourceDetail(templateResource); + String resourceId = templateResource.getId(); + JSONArray embedResources = TemplateResourceSearchManager.getInstance().getEmbedResourceJSONArray(); + for (int i = 0; i < embedResources.length(); i++) { + JSONObject resource = embedResources.getJSONObject(i); + if (resourceId.equals(resource.getString(ID))) { + detail.setInfo(resource.getString(INFO)); + detail.setDetailInfo(parseDetailInfo(resource.getString(DETAIL_INFO))); + detail.setVendor(resource.getString(VENDOR)); + detail.setPrice(resource.getDouble(PRICE)); + detail.setResourceUrl(resource.getString(URL)); + detail.setParentPkgName(resource.getString(PARENT_NAME)); + detail.setTagsName(Arrays.asList(resource.getString(TAGS_NAME).split(","))); + break; + } + } + return detail; + } + + static TemplateResourceDetail buildByResource(TemplateResource templateResource) { + TemplateResourceDetail detail = new TemplateResourceDetail(templateResource); + String resourceId = templateResource.getId(); + + // 获取模板详情页的信息一共需要三次请求 + try { + // 1请求详细信息 + JSONObject info = helper.getTemplateInfoById(resourceId); + detail.setInfo(info.getString(INFO)); + detail.setDetailInfo(parseDetailInfo(info.getString(DETAIL_INFO))); + detail.setVendor(info.getString(VENDOR)); + detail.setTagsId(info.getString(TAGS_ID).split(",")); + detail.setPrice(info.getDouble(PRICE)); + detail.setResourceUrl(helper.getTemplateUrlById(templateResource.getId())); + + // 2请求所属模板包信息 + JSONObject parentPkginfo = helper.getTemplateParentPackageByTemplateId(resourceId); + if (parentPkginfo != null) { + detail.setParentPkgName(parentPkginfo.getString(NAME)); + } + + // 3请求标签信息 + detail.setTagsName(helper.getTemplateTagsByTemplateTagIds(detail.getTagsId())); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e, e.getMessage()); + } + + return detail; + } + + /** + * 这里做下数据转换 + * 原始数据是html标签写的,如下 + * "
  1. 该模板需用10.0及以上版本设计器预览

  2. 该模板为库存场景解决方案的部分内容,全部内容可下载库存场景解决方案查看

  3. 为保障模板预览效果,建议安装新自适应插件(FR11.0版本插件已内置,无需手动安装),有使用需求或疑问,请联系帆软技术支持咨询

", + * + * 转换的后的数据 是原始数据中所有

标签内的(包括标签)的字符串(List),如上字符串会转为如下 + * List [

该模板需用10.0及以上版本设计器预览

, + *

该模板为库存场景解决方案的部分内容,全部内容可下载库存场景解决方案查看

, + *

为保障模板预览效果,建议安装新自适应插件(FR11.0版本插件已内置,无需手动安装),有使用需求或疑问,请联系帆软技术支持咨询

+ * ] + * */ + static final Pattern htmlPattern = Pattern.compile("

(.+?)

"); + static List parseDetailInfo(String htmlDetailInfo) { + List infos = new ArrayList<>(); + Matcher matcher = htmlPattern.matcher(htmlDetailInfo); + while (matcher.find()) { + infos.add(matcher.group()); + } + return infos; + } + } + +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/TemplateResourceDetailPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/TemplateResourceDetailPane.java new file mode 100644 index 000000000..fe2e1bbc5 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/TemplateResourceDetailPane.java @@ -0,0 +1,196 @@ +package com.fr.design.mainframe.alphafine.preview; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.alphafine.action.StartUseAction; +import com.fr.design.mainframe.alphafine.component.TemplateResourceImagePanel; +import com.fr.design.mainframe.alphafine.model.TemplateResourceDetail; +import com.fr.design.utils.BrowseUtils; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; + +public class TemplateResourceDetailPane extends JPanel { + + + private TemplateResourceDetail data; + + private TemplateResourceImagePanel imagePane; + private JPanel contentPane; + private UIScrollPane infoScrollPane; + private JPanel operatePane; + private UIScrollPane detailInfoPane; + + + private static final int IMAGE_HEIGHT = 170; + private static final int IMAGE_WIDTH= 310; + private static final int SCROLL_PANE_WIDTH = 320; + private static final int SCROLL_PANE_HEIGHT = 150; + private static final int CONTENT_PANE_WIDTH = 320; + private static final int CONTENT_PANE_HEIGHT = 180; + private static final int DETAIL_PANE_HEIGHT = 110; + private static final int TEXT_SCROLL_PANE_HEIGHT = 500; + private static final int PANE_WIDTH = 640; + + private static final String GOTO_DETAIL = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Detail_GOTO_DETAIL"); + private static final String START_USE = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Detail_START_USE"); + private static final String VENDOR = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Detail_Vendor"); + private static final String TAGS = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Detail_Tags"); + private static final String PARENT_PACKAGE = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Detail_Parent_Package"); + private static final String DETAIL_INFO = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Detail_Info"); + private static final String FREE = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Detail_Price_Free"); + private static final String SPACE = " "; + private static final String LF = "
"; + private static final String RMB = "¥"; + + + private static final Color INFO_PANE_BACKGROUND = new Color(0xf9f9f9); + private static final Color INFO_PANE_FOREGROUND = new Color(0x5b5b5c); + + + public TemplateResourceDetailPane(TemplateResourceDetail detail) { + this.data = detail; + initComponent(); + this.setLayout(new FlowLayout(FlowLayout.LEFT)); + this.setBorder(BorderFactory.createEmptyBorder(10,20,0,20)); + this.add(imagePane); + this.add(contentPane); + this.add(detailInfoPane); + this.setBackground(Color.WHITE); + } + + public void refresh() { + + } + + private void initComponent() { + createImagePane(); + createContentPane(); + createDetailInfoPane(); + } + + private void createContentPane() { + createInfoScrollPane(); + createOperatePane(); + contentPane = new JPanel(); + contentPane.setLayout(new FlowLayout(FlowLayout.LEFT)); + contentPane.setPreferredSize(new Dimension(CONTENT_PANE_WIDTH, CONTENT_PANE_HEIGHT)); + contentPane.add(infoScrollPane); + contentPane.add(operatePane); + contentPane.setBackground(Color.WHITE); + } + + private void createOperatePane() { + operatePane = new JPanel(new FlowLayout(FlowLayout.LEFT)); + + JLabel emptyLabel = new JLabel(); + emptyLabel.setPreferredSize(new Dimension(140, 25)); + JLabel priceLabel = new JLabel(); + priceLabel.setForeground(Color.RED); + if (data.getPrice() == 0) { + priceLabel.setText(FREE); + } else { + priceLabel.setText(RMB + SPACE + data.getPrice()); + } + + operatePane.add(createLinkLabel()); + operatePane.add(emptyLabel); + operatePane.add(priceLabel); + operatePane.add(createStartUseButton()); + operatePane.setBackground(Color.WHITE); + + } + + JLabel createLinkLabel() { + JLabel linkLabel = new JLabel(GOTO_DETAIL); + linkLabel.setBackground(Color.WHITE); + linkLabel.setForeground(Color.BLUE); + linkLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + openResourceUrl(data.getResourceUrl()); + } + }); + return linkLabel; + } + + // 方便埋点 + void openResourceUrl(String url) { + BrowseUtils.browser(url); + } + + UIButton createStartUseButton() { + UIButton starUseButton = new UIButton(START_USE); + starUseButton.addActionListener(new StartUseAction(data)); + return starUseButton; + } + + + private void createInfoScrollPane() { + JLabel content = new JLabel(); + content.setHorizontalAlignment(SwingConstants.LEFT); + content.setVerticalAlignment(SwingConstants.TOP); + StringBuilder sb = new StringBuilder(); + sb.append("

"); + + sb.append(VENDOR + data.getVendor() + LF); + + List tags = data.getTagsName(); + sb.append(TAGS); + for (String tag : tags) { + sb.append(tag + SPACE); + } + sb.append(LF); + + sb.append(PARENT_PACKAGE + data.getParentPkgName() + LF); + sb.append(data.getInfo()); + sb.append("

"); + content.setText(sb.toString()); + content.setBackground(INFO_PANE_BACKGROUND); + content.setForeground(INFO_PANE_FOREGROUND); + content.setPreferredSize(new Dimension(SCROLL_PANE_WIDTH - 10, TEXT_SCROLL_PANE_HEIGHT)); + infoScrollPane = new UIScrollPane(content); + infoScrollPane.setPreferredSize(new Dimension(SCROLL_PANE_WIDTH, SCROLL_PANE_HEIGHT - 25)); + infoScrollPane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); + } + + + + private void createImagePane() { + imagePane = new TemplateResourceImagePanel(data.getRoot(), IMAGE_WIDTH, IMAGE_HEIGHT); + } + + private void createDetailInfoPane() { + + JLabel content = new JLabel(); + content.setHorizontalAlignment(SwingConstants.LEFT); + content.setVerticalAlignment(SwingConstants.TOP); + + StringBuilder sb = new StringBuilder(); + sb.append("

"); + sb.append(DETAIL_INFO + LF); + + List detailInfos = data.getDetailInfo(); + for (String info : detailInfos) { + sb.append(info); + } + sb.append("

"); + content.setText(sb.toString()); + content.setPreferredSize(new Dimension(PANE_WIDTH - 20, TEXT_SCROLL_PANE_HEIGHT)); + content.setBackground(Color.WHITE); + detailInfoPane = new UIScrollPane(content); + detailInfoPane.setPreferredSize(new Dimension(PANE_WIDTH, DETAIL_PANE_HEIGHT)); + detailInfoPane.setBackground(Color.WHITE); + detailInfoPane.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); + } +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/TemplateShopPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/TemplateShopPane.java new file mode 100644 index 000000000..7acb30537 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/TemplateShopPane.java @@ -0,0 +1,158 @@ +package com.fr.design.mainframe.alphafine.preview; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.component.TemplateResourcePageGridPane; +import com.fr.design.mainframe.alphafine.model.TemplateResource; +import com.fr.design.mainframe.alphafine.model.TemplateResourceDetail; +import com.fr.design.mainframe.alphafine.search.manager.impl.TemplateResourceSearchManager; +import com.fr.log.FineLoggerFactory; +import com.fr.third.apache.logging.log4j.util.Strings; + +import javax.swing.JPanel; +import javax.swing.SwingWorker; +import java.awt.CardLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; + +public class TemplateShopPane extends JPanel { + + private static final TemplateShopPane INSTANCE = new TemplateShopPane(); + public static TemplateShopPane getInstance() { + return INSTANCE; + } + + // public 方便埋点 + public static final String DEFAULT_PAGE_PANEL = "defaultPagePane"; + public static final String PAGE_PANEL = "pagePane"; + public static final String DETAIL_PANEL = "detailPane"; + public static final String LOADING_PANEL = "loadingPane"; + private String currentCard = Strings.EMPTY; + private static final String SLASH = "/"; + + private CardLayout cardLayout = new CardLayout(); + private JPanel defaultPagePane; + private JPanel pagePane; + private JPanel detailPane; + private JPanel loadingPane; + + private TemplateShopPane() { + setLayout(cardLayout); + initComponents(); + this.add(defaultPagePane, DEFAULT_PAGE_PANEL); + this.add(loadingPane, LOADING_PANEL); + this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE); + switchCard(DEFAULT_PAGE_PANEL); + } + + private void switchCard(String flag) { + cardLayout.show(this, flag); + currentCard = flag; + } + + private void initComponents() { + defaultPagePane = createDefaultResourcePane(); + loadingPane = createLoadingPane(); + } + + public void refreshPagePane(List resourceList) { + pagePane = createContentPane(resourceList); + this.add(pagePane, PAGE_PANEL); + switchCard(PAGE_PANEL); + } + + public void quitSearchResultPane() { + if (currentCard.equals(PAGE_PANEL)) { + switchCard(DEFAULT_PAGE_PANEL); + } + } + + public void showPagePane() { + switchCard(PAGE_PANEL); + } + + // 打开二级页面,显示详细信息 + public void searchAndShowDetailPane(TemplateResource resource) { + + changeLabel(resource.getName()); + + switchCard(LOADING_PANEL); + + new SwingWorker() { + @Override + protected TemplateResourceDetail doInBackground(){ + // 搜搜 + TemplateResourceDetail detail = TemplateResourceSearchManager.getInstance().getDetailSearchResult(resource); + return detail; + } + + @Override + protected void done() { + TemplateResourceDetail detail = null; + try { + detail = get(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e, e.getMessage()); + } + // detailpane初始化 + detailPane = new TemplateResourceDetailPane(detail); + // 切换 + INSTANCE.add(detailPane, DETAIL_PANEL); + switchCard(DETAIL_PANEL); + } + }.execute(); + + } + + + + private void changeLabel(String resourceName) { + JPanel labelNamePane = AlphaFineHelper.getAlphaFineDialog().getLabelWestPane(); + UILabel tabLabel = AlphaFineHelper.getAlphaFineDialog().getTabLabel(); + tabLabel.setForeground(AlphaFineConstants.DARK_GRAY); + + UILabel slash = new UILabel(SLASH); + slash.setForeground(AlphaFineConstants.DARK_GRAY); + + UILabel resourceLabel = new UILabel(resourceName); + resourceLabel.setForeground(AlphaFineConstants.LABEL_SELECTED); + + labelNamePane.add(slash); + labelNamePane.add(resourceLabel); + + + tabLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + switchCard(PAGE_PANEL); + tabLabel.setForeground(AlphaFineConstants.LABEL_SELECTED); + labelNamePane.remove(slash); + labelNamePane.remove(resourceLabel); + } + }); + } + + // 方便埋点,勿删 + public String getCurrentCard() { + return currentCard; + } + + private JPanel createContentPane(List templateResources) { + return new TemplateResourcePageGridPane(templateResources); + } + + private JPanel createDefaultResourcePane() { + return createContentPane(TemplateResourceSearchManager.getInstance().getDefaultResourceList()); + } + + + private JPanel createLoadingPane() { + return new SearchLoadingPane(); + } + + + +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/TemplateResourceSearchWorkerManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/TemplateResourceSearchWorkerManager.java new file mode 100644 index 000000000..ac1ef39a7 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/TemplateResourceSearchWorkerManager.java @@ -0,0 +1,109 @@ +package com.fr.design.mainframe.alphafine.search; + +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.CellType; +import com.fr.design.mainframe.alphafine.component.AlphaFineFrame; +import com.fr.design.mainframe.alphafine.model.TemplateResource; +import com.fr.design.mainframe.alphafine.preview.TemplateShopPane; +import com.fr.log.FineLoggerFactory; + +import javax.swing.SwingWorker; +import java.util.List; +import java.util.function.Function; + +public class TemplateResourceSearchWorkerManager implements SearchManager { + + private final CellType cellType; + + private SwingWorker, Void> searchWorker; + + private Function> searchFunction; + + private AlphaFineFrame alphaFineFrame; + + private volatile boolean searchResult = true; + + private volatile boolean searchOver = false; + + private volatile boolean networkError = false; + + public TemplateResourceSearchWorkerManager(CellType cellType, Function> searchFunction, AlphaFineFrame alphaFineFrame) { + this.cellType = cellType; + this.searchFunction = searchFunction; + this.alphaFineFrame = alphaFineFrame; + } + + @Override + public void doSearch(SearchTextBean searchTextBean) { + checkSearchWork(); + searchOver = false; + networkError = false; + + this.searchWorker = new SwingWorker, Void>() { + @Override + protected List doInBackground() { + List list; + if (!AlphaFineHelper.isNetworkOk() && cellType.isNeedNetWork()) { + networkError = true; + FineLoggerFactory.getLogger().warn("alphaFine network error"); + } + list = searchFunction.apply(searchTextBean); + return list; + } + + @Override + protected void done() { + searchOver = true; + if (!isCancelled()) { + try { + List list = get(); + searchResult = !list.isEmpty(); + showResult(list); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + }; + this.searchWorker.execute(); + } + + void showResult(List list) { + if (networkError && !searchResult) { + alphaFineFrame.showResult(AlphaFineConstants.NETWORK_ERROR); + return; + } + + if (alphaFineFrame.getSelectedType() == cellType) { + if (!searchResult) { + alphaFineFrame.showResult(CellType.NO_RESULT.getFlagStr4None()); + } else { + TemplateShopPane.getInstance().refreshPagePane(list); + AlphaFineHelper.getAlphaFineDialog().showResult(cellType.getFlagStr4None()); + } + } + } + + @Override + public boolean hasSearchResult() { + return searchResult; + } + + @Override + public boolean isSearchOver() { + return searchOver; + } + + private void checkSearchWork() { + if (this.searchWorker != null && !this.searchWorker.isDone()) { + this.searchWorker.cancel(true); + this.searchWorker = null; + } + } + + @Override + public boolean isNetWorkError() { + return networkError; + } +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/helper/FineMarketClientHelper.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/helper/FineMarketClientHelper.java new file mode 100644 index 000000000..81a165ca0 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/helper/FineMarketClientHelper.java @@ -0,0 +1,178 @@ +package com.fr.design.mainframe.alphafine.search.helper; + +import com.fr.design.mainframe.alphafine.model.TemplateResource; +import com.fr.design.utils.BrowseUtils; +import com.fr.general.CloudCenter; +import com.fr.general.http.HttpToolbox; +import com.fr.json.JSONArray; +import com.fr.json.JSONObject; +import org.jetbrains.annotations.Nullable; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class FineMarketClientHelper { + private static final FineMarketClientHelper INSTANCE = new FineMarketClientHelper(); + public static FineMarketClientHelper getInstance() { + return INSTANCE; + } + + public static final String FINE_MARKET_TEMPLATE_INFO = CloudCenter.getInstance().acquireUrlByKind("market.template.info"); + public static final String FINE_MARKET_TEMPLATE_URL = CloudCenter.getInstance().acquireUrlByKind("market.template.url"); + public static final String LOGIN_FINE_CLUB_AND_REDIRECT_SHOP = CloudCenter.getInstance().acquireUrlByKind("af.login.redirect.market"); + public static final String FILE_DOWNLOAD = "file/"; + public static final String PACKAGE_DOWNLOAD = "package/download/"; + public static final String TEMPLATES_PARENT_PACKAGE = "parent/"; + public static final String TEMPLATES_TAGS = "filter"; + public static final String NAME_SEARCH = "?searchKeyword="; + + public static final String RESPONSE_STATE = "state"; + public static final String RESPONSE_SUCCESS = "ok"; + public static final String RESPONSE_RESULT = "result"; + public static final String TAGS_KEY = "key"; + public static final String TAGS_ITEMS = "items"; + public static final String TAG_NAME = "name"; + public static final String TAG_ID = "id"; + + // 缓存下所有tag标签 + private Map tags; + + + /** + * 获取模板资源的下载链接 + * */ + public String getResourceDownloadUrl(TemplateResource templateResource) { + if (TemplateResource.Type.SCENARIO_SOLUTION.equals(templateResource.getType())) { + return getPackageDownloadUrl(templateResource.getId()); + } else { + return getFileDownLoadUrl(templateResource.getId()); + } + + } + + public void openBrowserAndDownload(TemplateResource templateResource) { + String url = LOGIN_FINE_CLUB_AND_REDIRECT_SHOP; + if (TemplateResource.Type.SCENARIO_SOLUTION.equals(templateResource.getType())) { + url += getPackageDownloadUrl(templateResource.getId()); + } else { + url += getFileDownLoadUrl(templateResource.getId()); + } + BrowseUtils.browser(url); + } + + /** + * 暂时没有package的下载接口,需要用户在浏览器点击下载 + * */ + private String getPackageDownloadUrl(String id) { + return getTemplateUrlById(id); + } + + /** + * 打开浏览器,下载单一模板 + * */ + private String getFileDownLoadUrl(String id) { + return FINE_MARKET_TEMPLATE_INFO + FILE_DOWNLOAD + id; + } + + + + /** + * 获取帆软市场模板资源页面链接 + * */ + public String getFineMarketTemplateUrl() { + return FINE_MARKET_TEMPLATE_URL; + } + + public @Nullable JSONObject getTemplateInfoById(String id) throws IOException { + String url = FINE_MARKET_TEMPLATE_INFO + id; + String jsonString = HttpToolbox.get(url); + JSONObject jsonObject = new JSONObject(jsonString); + String responseState = (String) jsonObject.get(RESPONSE_STATE); + if (RESPONSE_SUCCESS.equals(responseState)) { + return jsonObject.getJSONObject(RESPONSE_RESULT); + } else { + return null; + } + } + + public @Nullable JSONArray getTemplateInfoByName(String name) throws IOException { + String url = FINE_MARKET_TEMPLATE_INFO + NAME_SEARCH + name; + String jsonString = HttpToolbox.get(url); + JSONObject jsonObject = new JSONObject(jsonString); + String responseState = (String) jsonObject.get(RESPONSE_STATE); + if (RESPONSE_SUCCESS.equals(responseState)) { + return jsonObject.getJSONArray(RESPONSE_RESULT); + } + return null; + } + + public String getTemplateUrlById(String id) { + return FINE_MARKET_TEMPLATE_URL + id; + } + + public @Nullable JSONObject getTemplateParentPackageByTemplateId(String id) throws IOException { + String url = FINE_MARKET_TEMPLATE_INFO + TEMPLATES_PARENT_PACKAGE + id; + String jsonString = HttpToolbox.get(url); + JSONObject jsonObject = new JSONObject(jsonString); + String responseState = (String) jsonObject.get(RESPONSE_STATE); + if (RESPONSE_SUCCESS.equals(responseState)) { + JSONArray jsonArray = jsonObject.getJSONArray(RESPONSE_RESULT); + if (!jsonArray.isEmpty()) { + return jsonObject.getJSONArray(RESPONSE_RESULT).getJSONObject(0); + } + } + return null; + + } + + + /** + * 根据模板资源的tagid,获取tagName + * */ + public List getTemplateTagsByTemplateTagIds(String[] tagIds) throws IOException { + List list = new ArrayList<>(); + + initTags(); + + if (tagIds != null) { + for (String tagId : tagIds) { + String tagName = tags.get(tagId); + if (tagName != null) { + list.add(tagName); + } + } + } + + return list; + } + + /** + * 请求帆软市场,获取所有tag信息,并构建tagid - tagname的map + * */ + private void initTags() throws IOException { + tags = new HashMap<>(); + String url = FINE_MARKET_TEMPLATE_INFO + TEMPLATES_TAGS; + String jsonString = HttpToolbox.get(url); + JSONObject jsonObject = new JSONObject(jsonString); + String responseState = (String) jsonObject.get(RESPONSE_STATE); + if (RESPONSE_SUCCESS.equals(responseState)) { + JSONArray resultArray = jsonObject.getJSONArray(RESPONSE_RESULT); + for (int i = 1; i < resultArray.size(); i++) { + JSONObject result = resultArray.getJSONObject(i); + String key = result.getString(TAGS_KEY); + key = key.substring(key.indexOf('@') + 1); + JSONArray items = result.getJSONArray(TAGS_ITEMS); + for (int j = 0; j < items.length(); j++) { + JSONObject item = items.getJSONObject(j); + String id = item.getString(TAG_ID); + String name = item.getString(TAG_NAME); + tags.put(key + '-' + id, name); + } + } + } + } + +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ProductNewsSearchManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ProductNewsSearchManager.java index 205735ab3..deee28c35 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ProductNewsSearchManager.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ProductNewsSearchManager.java @@ -1,6 +1,7 @@ package com.fr.design.mainframe.alphafine.search.manager.impl; import com.fr.concurrent.NamedThreadFactory; +import com.fr.design.DesignerEnvManager; import com.fr.design.mainframe.alphafine.AlphaFineConstants; import com.fr.design.mainframe.alphafine.AlphaFineHelper; import com.fr.design.mainframe.alphafine.model.ProductNews; @@ -12,17 +13,19 @@ import com.fr.json.JSONObject; import com.fr.log.FineLoggerFactory; import org.jetbrains.annotations.Nullable; +import javax.imageio.ImageIO; import java.awt.Image; import java.net.URL; import java.util.ArrayList; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; +import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; -import javax.imageio.ImageIO; public class ProductNewsSearchManager { @@ -91,7 +94,7 @@ public class ProductNewsSearchManager { setImage(getCoverImage(obj.getString("pic"))). setUrl(obj.getString("url")).setTag(ProductNews.Tag.parseCode(obj.getInt("tag"))). setStatus(ProductNews.Status.parseCode(obj.getInt("status"))).setTarget( - ProductNews.Target.parseCode(obj.getInt("target"))). + ProductNews.ParseTarget(obj.getString("target"))). setCreator(obj.getInt("creator")).setPushDate(new Date(obj.getLong("push_time"))); Date currentDate = new Date(System.currentTimeMillis()); // 推送时间check @@ -100,9 +103,70 @@ public class ProductNewsSearchManager { idSet.add(productNews.getId()); } } + + filterByDesignerId(productNewsList); + return productNewsList; } + + /** + * 将productNews根据设计器id进行过滤 + * productNews有个target字段,代表推送对象用户组,检查设计器id是否在用户组中来进行过滤 + * */ + private List filterByDesignerId(List list) { + //设计器id + String designId = DesignerEnvManager.getEnvManager().getUUID(); + + HashMap> userGroupInfoCache = new HashMap<>(); + //遍历资源,获取target下的所有用户组信息,检查是否包含设计器id + Iterator iterator = list.iterator(); + while (iterator.hasNext()) { + List targets = iterator.next().getTarget(); + + boolean targetsContainDesignerId = false; + + // 每条推送可能推送至多个用户组,需要逐一判断 + for (String userGroupId : targets) { + // 没有记录的用户组信息需要请求一下 + if (!userGroupInfoCache.containsKey(userGroupId)) { + userGroupInfoCache.put(userGroupId, searchUserGroupInfo(userGroupId)); + } + + // 判断设计器id是否在这个用户组中,在则退出判断,不在则继续 + if (userGroupInfoCache.get(userGroupId).contains(designId) || userGroupId.equals(ProductNews.ALL_USER_TARGET)) { + targetsContainDesignerId = true; + break; + } + } + + + if (!targetsContainDesignerId) { + iterator.remove(); + } + } + return list; + } + + /** + * 根据用户组id,查询用户组信息(改用户组中的所有设计器id) + * */ + private Set searchUserGroupInfo(String userGroupId) { + String url = AlphaFineConstants.ALPHA_CID_USER_GROUP_INFO + AlphaFineConstants.SEARCH_BY_ID + userGroupId; + Set idSet = new HashSet<>(); + try { + String jsonStr = HttpToolbox.get(url); + JSONObject jsonObject = new JSONObject(jsonStr); + JSONArray idArray = jsonObject.getJSONArray("data"); + for (int i = 0; i < idArray.length(); i++) { + idSet.add(idArray.getJSONObject(i).getString("userid")); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e, e.getMessage()); + } + return idSet; + } + public List getCachedProductNewsList() { return productNewsList; } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/TemplateResourceSearchManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/TemplateResourceSearchManager.java new file mode 100644 index 000000000..2a8c76751 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/TemplateResourceSearchManager.java @@ -0,0 +1,100 @@ +package com.fr.design.mainframe.alphafine.search.manager.impl; + + +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.model.TemplateResource; +import com.fr.design.mainframe.alphafine.model.TemplateResourceDetail; +import com.fr.design.mainframe.alphafine.search.helper.FineMarketClientHelper; +import com.fr.general.CloudCenter; +import com.fr.general.IOUtils; +import com.fr.json.JSONArray; + +import java.util.ArrayList; +import java.util.List; + +public class TemplateResourceSearchManager { + + private static final TemplateResourceSearchManager INSTANCE = new TemplateResourceSearchManager(); + public static TemplateResourceSearchManager getInstance() { + return INSTANCE; + } + + public static final String LOCAL_RESOURCE_URL = "/com/fr/design/mainframe/alphafine/template_resource/local_templates.json"; + private static final FineMarketClientHelper helper = FineMarketClientHelper.getInstance(); + + + /** + * 帆软市场暂时没有分页搜索接口,先全量搜,分页展示 + * */ + public List getSearchResult(String searchText) { + List resourceList = new ArrayList<>(); + + // 联网搜索 + try { + JSONArray jsonArray = helper.getTemplateInfoByName(searchText); + if (jsonArray != null && !jsonArray.isEmpty()) { + resourceList.addAll(TemplateResource.createByJson(jsonArray)); + } + } catch (Exception e) { + + } + + // 本地搜索 + if (resourceList.isEmpty()) { + List localResource = getEmbedResourceList(); + localResource.stream().forEach(resource->{ + if (resource.getName().toLowerCase().contains(searchText)) { + resourceList.add(resource); + } + }); + } + return resourceList; + } + + + /** + * 返回默认资源 + * */ + public List getDefaultResourceList() { + List resourceList = getEmbedResourceList(); + // 添加推荐搜索卡片 + resourceList.add(TemplateResource.getRecommendSearch()); + return resourceList; + } + + /** + * 返回内置资源 + * */ + public List getEmbedResourceList() { + List resourceList = new ArrayList<>(); + JSONArray jsonArray = getEmbedResourceJSONArray(); + for (int i = 0; i < jsonArray.size(); i++) { + resourceList.add(TemplateResource.createByJson(jsonArray.getJSONObject(i))); + } + return resourceList; + } + + public JSONArray getEmbedResourceJSONArray() { + String jsonString = IOUtils.readResourceAsString(LOCAL_RESOURCE_URL); + return new JSONArray(jsonString); + } + + public List getRecommendSearchKeys() { + List searchKey = new ArrayList<>(); + String[] keys = CloudCenter.getInstance().acquireConf("alphafine.tempalte.recommend", "跑马灯,填报,地图").split(","); + for (String k : keys) { + searchKey.add(k); + } + return searchKey; + } + + + public TemplateResourceDetail getDetailSearchResult(TemplateResource resource) { + if (AlphaFineHelper.isNetworkOk()) { + return TemplateResourceDetail.createByTemplateResource(resource); + } else { + return TemplateResourceDetail.createFromEmbedResource(resource); + } + } + +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/start/MainDesigner.java b/designer-realize/src/main/java/com/fr/start/MainDesigner.java index 67e3b4937..7e450c7d4 100644 --- a/designer-realize/src/main/java/com/fr/start/MainDesigner.java +++ b/designer-realize/src/main/java/com/fr/start/MainDesigner.java @@ -240,8 +240,13 @@ public class MainDesigner extends BaseDesigner { if (WorkContext.getCurrent().isRoot()) { menuDef.addShortCut( - new ServerConfigManagerAction(), - new TemplateThemeManagerAction(), + new ServerConfigManagerAction() + ); + JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (JTemplate.isValid(jt)) { + menuDef.addShortCut(new TemplateThemeManagerAction()); + } + menuDef.addShortCut( new WidgetManagerAction() ); menuDef.addShortCut(new ChartPreStyleAction(), new ChartEmptyDataStyleAction(),new ChartMapEditorAction()); @@ -403,7 +408,7 @@ public class MainDesigner extends BaseDesigner { @Override protected void refreshLargeToolbarState() { JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (jt == null) { + if (!JTemplate.isValid(jt)) { return; } saveButton.setEnabled(!jt.isSaved() && !DesignModeContext.isVcsMode() && jt.checkEnable()); diff --git a/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java b/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java index 1f7ba5113..9e590a3e1 100644 --- a/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/optimized/DesignerStartupPageActivator.java @@ -139,8 +139,9 @@ public class DesignerStartupPageActivator extends Activator { } private void recordStartupEnd(StopWatch stopWatch) { - - DesignerMetrics designerMetrics = DesignerStartupContext.getInstance().getDesignerMetrics(); + + DesignerStartupContext context = DesignerStartupContext.getInstance(); + DesignerMetrics designerMetrics = context.getDesignerMetrics(); DesignerStartupModel model = designerMetrics.getModel(); model.setStartingTime(stopWatch.getTime(TimeUnit.MILLISECONDS)); model.fill(); diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bottom.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bottom.svg new file mode 100644 index 000000000..ef489cdce --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bottom.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bottom_disable.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bottom_disable.svg new file mode 100644 index 000000000..e924fcb81 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bottom_disable.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/config.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/config.svg new file mode 100644 index 000000000..f322cde88 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/config.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/down.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/down.svg new file mode 100644 index 000000000..9bc79b1c0 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/down.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/down_disable.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/down_disable.svg new file mode 100644 index 000000000..ec61156a0 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/down_disable.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template1.png b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template1.png new file mode 100644 index 000000000..203701cba Binary files /dev/null and b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template1.png differ diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template2.png b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template2.png new file mode 100644 index 000000000..a16f0dc40 Binary files /dev/null and b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template2.png differ diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template3.png b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template3.png new file mode 100644 index 000000000..89fd1386d Binary files /dev/null and b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template3.png differ diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template4.png b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template4.png new file mode 100644 index 000000000..fd30a4b7b Binary files /dev/null and b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/local_template4.png differ diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/more.png b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/more.png new file mode 100644 index 000000000..e49b1c96f Binary files /dev/null and b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/more.png differ diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/next.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/next.svg new file mode 100644 index 000000000..ba63a3d99 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/next.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/prev.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/prev.svg new file mode 100644 index 000000000..b70a6199a --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/prev.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/top.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/top.svg new file mode 100644 index 000000000..b82ae8475 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/top.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/top_disable.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/top_disable.svg new file mode 100644 index 000000000..b507888ef --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/top_disable.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/up.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/up.svg new file mode 100644 index 000000000..625153a57 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/up.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/up_disable.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/up_disable.svg new file mode 100644 index 000000000..d84b3b3c5 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/up_disable.svg @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/template_resource/local_templates.json b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/template_resource/local_templates.json new file mode 100644 index 000000000..4e9265b14 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/template_resource/local_templates.json @@ -0,0 +1,110 @@ +[ + { + "id": 20000770, + "name": "PDCA销售运营闭环管理方案", + "uuid": "7975ad73-9aea-4634-96f1-d33ec1b4283c", + "vendor": "Victoria.", + "sellerId": 202, + "cid": "industry-3,purpose-2,purpose-16,purpose-15", + "tag": null, + "pic": "com/fr/design/mainframe/alphafine/images/local_template1.png", + "price": 0, + "fileLoca": null, + "text": "
  1. 此方案共包括14张模板,其中12张可视化分析看板、1张分析报表以及1张填报表,需在10.0及以上版本设计器中预览;

  2. 了解方案详情,可移步-数据分析与可视化指南

  3. 如果您希望在线体验当前方案,可移步-官方DEMO系统:业务场景应用->营销管理

  4. 如果您对此方案感兴趣,希望更加深入了解,可以填写此表单:方案需求录入;后续会有帆软行业顾问将与您联系。

", + "description": "将PDCA循环嵌入销售运营管理的全流程中,从决策层、管理层与执行层三个层级,对目标制定、执行过程、复盘分析、问题跟踪进行全方位精细化管理。", + "updateTime": "2022-06-15T06:36:39.000Z", + "downloadTimes": 1152, + "state": 1, + "designVersion": "10.0", + "involvePlugins": null, + "uploadTime": "2022-06-15T06:36:39.000Z", + "style": null, + "link": "template", + "sellerName": "Victoria.", + "pluginName": [], + "pkgsize": 14, + "material": "方案附件.rar", + "tagsName": "制造加工,营销,组织,管理,经营汇报" + }, + { + "id": 20000733, + "name": "库存场景解决方案", + "uuid": "43d1c14b-1a73-41e6-adcc-aaf2872bc8d4", + "vendor": "Victoria.", + "sellerId": 202, + "cid": "industry-3,purpose-5", + "tag": null, + "pic": "com/fr/design/mainframe/alphafine/images/local_template2.png", + "price": 0, + "fileLoca": null, + "text": "

当前库存管理面临的现状:库存成本劣势明显、库存周转差距较大。如果对此没有合理有效的解决方案,往往会导致企业库存越来越混乱,经营、资金、成本等问题丛生。

库存管理解决方案从:“盘”、“析”、“管”三个方向开展,彻底解决库存量大、结构复杂、管理混乱等常见问题

", + "description": "库存管理解决方案即从:“盘”、“析”、“管”三个方向开展,对导致库存管理问题的原因逐一击破。", + "updateTime": "2022-05-05T03:53:55.000Z", + "downloadTimes": 816, + "state": 1, + "designVersion": "10.0", + "involvePlugins": null, + "uploadTime": "2022-05-05T03:53:55.000Z", + "style": null, + "link": "template", + "sellerName": "Victoria.", + "pluginName": [], + "pkgsize": 11, + "material": "", + "tagsName":"制造加工,库存" + }, + { + "id": 20000581, + "name": "采购场景解决方案", + "uuid": "7994b01f-5069-4554-83cf-9d3506e30767", + "vendor": "Victoria.", + "sellerId": 202, + "cid": "industry-3,purpose-3", + "tag": null, + "pic": "com/fr/design/mainframe/alphafine/images/local_template3.png", + "price": 0, + "fileLoca": null, + "text": "

采购场景方案具体细节可参考:可视化指南-采购场景应用

", + "description": "采购解决方案采用:“自上而下”的分析思路,针对采购相关的不同角色层级及其不同角度发数据分析需求,产出不同的内容", + "updateTime": "2022-03-10T03:50:17.000Z", + "downloadTimes": 2353, + "state": 1, + "designVersion": "10.0", + "involvePlugins": null, + "uploadTime": "2022-03-10T03:50:18.000Z", + "style": null, + "link": "template", + "sellerName": "Victoria.", + "pluginName": [], + "pkgsize": 6, + "material": "", + "tagsName": "制造加工,采购" + }, + { + "id": 20000747, + "name": "费用预算系统解决方案", + "uuid": "0776533469c3401a8da78706856b6b02", + "vendor": "finereport", + "sellerId": 1, + "cid": "template_type-1,terminal-1,industry-13,purpose-1", + "tag": null, + "pic": "com/fr/design/mainframe/alphafine/images/local_template4.png", + "price": 0, + "fileLoca": "费用预算系统解决方案.zip", + "text": "

模板中使用了数据查询数据集,如果要在本地打开,需要在自己的数据库中建表,并修改数据连接。

1)建表语句见附件文件夹:SQL语句与表。


2)数据连接默认为 FRDemo,如果用户表所在的数据库连接不是 FRDemo,将模板中数据连接修改为用户默认的数据连接。


3)模板中 SQL 语句为 MYSQL 数据库,若用户使用中数据库语句不匹配,可对应修改为匹配的语句。


4)模板中有大量的超链接,用户存在本地后,预览时注意修改超链接。


5)费用预算系统的平台沿用人事管理系统的平台配置,如果要在本地体验效果,可先下载人事管理系统部署:人事管理系统

模板中图标等背景样式见背景附件。 如果数据替换麻烦,可直接使用内置数据集模板,但内置模板只提供了样式,控件、数据等不能联动。如何制作,可查看帮助文档:费用预算系统

", + "description": "费用预算系统是通过 FineReport 填报功能和平台功能结合实现的审批流程系统。能够在线采集数据,提供标准数据模板,解决不同部门、子公司之间数据不统一的问题,\n实现记录预算审批与更改的操作,审批与更改记录留痕等。\n详细内容可查看帮助文档:费用预算系统", + "updateTime": "2022-05-15T05:34:45.000Z", + "downloadTimes": 141, + "state": 1, + "designVersion": "10.0", + "involvePlugins": null, + "uploadTime": "2022-05-15T05:34:45.000Z", + "style": "简约清新", + "link": "template", + "sellerName": "finereport", + "pluginName": [], + "pkgsize": 1, + "material": null, + "tagsName": "IT互联网,财务" + } +] \ No newline at end of file