Browse Source

数据脱敏三期

【问题原因】rt
【改动思路】rt
顺便过一下开发文档 https://kms.fineres.com/pages/viewpage.action?pageId=576039082
feature/x
Leo.Qin 2 years ago
parent
commit
a2d20f2553
  1. 32
      designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java
  2. 20
      designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableEditorPane.java
  3. 16
      designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableModelAdapter.java
  4. 18
      designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java
  5. 46
      designer-base/src/main/java/com/fr/design/layout/VerticalFlowLayout.java
  6. 112
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java
  7. 127
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/CellDesensitizationGroupsPane.java
  8. 109
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/model/CellDesensitizationTableModel.java
  9. 43
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/model/DesensitizationCellEditor.java
  10. 304
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/model/DesensitizationCellPane.java
  11. 49
      designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/model/DesensitizationCellRender.java

32
designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java

@ -17,9 +17,6 @@ import javax.swing.JFrame;
import javax.swing.JPanel; import javax.swing.JPanel;
import javax.swing.event.PopupMenuEvent; import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener; import javax.swing.event.PopupMenuListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.awt.BorderLayout; import java.awt.BorderLayout;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
@ -32,6 +29,9 @@ import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent; import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter; import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/** /**
* 设计器下拉复选框组件 * 设计器下拉复选框组件
@ -52,7 +52,7 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
//选中的值之间显示的分隔符 //选中的值之间显示的分隔符
private String valueSperator; private String valueSperator;
private static final String DEFAULT_VALUE_SPERATOR = ","; private static final String DEFAULT_VALUE_SPERATOR = ",";
private static final String OMIT_TEXT = "..."; protected static final String OMIT_TEXT = "...";
private UIObserverListener uiObserverListener; private UIObserverListener uiObserverListener;
private GlobalNameListener globalNameListener = null; private GlobalNameListener globalNameListener = null;
@ -60,6 +60,7 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
private boolean showOmitText = true; private boolean showOmitText = true;
private boolean supportSelectAll = true; private boolean supportSelectAll = true;
private String placeHolder = StringUtils.EMPTY;
public UIComboCheckBox(Object[] value) { public UIComboCheckBox(Object[] value) {
this(value, DEFAULT_VALUE_SPERATOR, true); this(value, DEFAULT_VALUE_SPERATOR, true);
@ -138,6 +139,14 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
return editor; return editor;
} }
public String getPlaceHolder() {
return placeHolder;
}
public void setPlaceHolder(String placeHolder) {
this.placeHolder = placeHolder;
}
public UIButton getArrowButton() { public UIButton getArrowButton() {
return arrowButton; return arrowButton;
} }
@ -191,6 +200,9 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
@Override @Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
attributeChange(); attributeChange();
if (uiObserverListener != null) {
uiObserverListener.doChange();
}
} }
@Override @Override
@ -290,10 +302,20 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
String text = builder.length() > 0 ? builder.substring(0, builder.length() - 1) : StringUtils.EMPTY; String text = builder.length() > 0 ? builder.substring(0, builder.length() - 1) : StringUtils.EMPTY;
//计算加省略号后的文本 //计算加省略号后的文本
editor.setText(this.showOmitText ? omitEditorText(editor, text) : text); editor.setText(this.showOmitText ? omitEditorText(editor, text) : text);
// 添加placeHolder
setEditorPlaceHolder(editor);
// tooltips显示原值 // tooltips显示原值
setEditorToolTipText(editor, text); setEditorToolTipText(editor, text);
} }
/**
* 为为添加placeholder
* @param editor
*/
protected void setEditorPlaceHolder(UITextField editor) {
// 默认空实现
}
/** /**
* 为UITextField设置悬浮提示值 * 为UITextField设置悬浮提示值
* *
@ -311,7 +333,7 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
* @param text * @param text
* @return 省略后的文字 * @return 省略后的文字
*/ */
private static String omitEditorText(UITextField textEditor, String text) { protected String omitEditorText(UITextField textEditor, String text) {
char[] omitChars = OMIT_TEXT.toCharArray(); char[] omitChars = OMIT_TEXT.toCharArray();
//获取字体的大小 //获取字体的大小
FontMetrics fontMetrics = textEditor.getFontMetrics(textEditor.getFont()); FontMetrics fontMetrics = textEditor.getFontMetrics(textEditor.getFont());

20
designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableEditorPane.java

@ -8,10 +8,12 @@ import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.FRGUIPaneFactory;
import javax.swing.JPanel;
import javax.swing.*; import javax.swing.JTable;
import javax.swing.event.TableModelListener; import javax.swing.event.TableModelListener;
import java.awt.*; import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.util.List; import java.util.List;
/** /**
@ -42,7 +44,7 @@ public class UITableEditorPane<T> extends BasicPane {
this.initComponent(model.createAction()); this.initComponent(model.createAction());
} }
private void initComponent(UITableEditAction[] action) { protected void initComponent(UITableEditAction[] action) {
this.setLayout(FRGUIPaneFactory.createBorderLayout()); this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel pane = new JPanel(new BorderLayout(4, 4)); JPanel pane = new JPanel(new BorderLayout(4, 4));
this.add(pane, BorderLayout.CENTER); this.add(pane, BorderLayout.CENTER);
@ -66,7 +68,7 @@ public class UITableEditorPane<T> extends BasicPane {
return tableModel; return tableModel;
} }
private void initbuttonPane(UITableEditAction[] action) { protected void initbuttonPane(UITableEditAction[] action) {
buttonPane = new JPanel(); buttonPane = new JPanel();
if (action != null) { if (action != null) {
@ -146,6 +148,14 @@ public class UITableEditorPane<T> extends BasicPane {
return buttonPane; return buttonPane;
} }
public JTable getEditTable() {
return editTable;
}
public void setEditTable(JTable editTable) {
this.editTable = editTable;
}
/** /**
* 停止编辑 * 停止编辑
*/ */

16
designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableModelAdapter.java

@ -219,13 +219,17 @@ public abstract class UITableModelAdapter<T> extends AbstractTableModel implemen
protected class DeleteAction extends UITableEditAction { protected class DeleteAction extends UITableEditAction {
private Component component = null; private Component component = null;
// 删除时界面显示的提示语,可自定义
private String deleteTipText;
public DeleteAction() { public DeleteAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Delete")); this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Delete"));
this.setDeleteTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + "?");
this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/remove.png")); this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/remove.png"));
} }
public DeleteAction(Component component){ public DeleteAction(Component component){
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Delete")); this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Delete"));
this.setDeleteTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + "?");
this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/remove.png")); this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/remove.png"));
this.component = component; this.component = component;
} }
@ -251,8 +255,8 @@ public abstract class UITableModelAdapter<T> extends AbstractTableModel implemen
if (component == null) { if (component == null) {
component = DesignerContext.getDesignerFrame(); component = DesignerContext.getDesignerFrame();
} }
int val = FineJOptionPane.showConfirmDialog(component, int val = FineJOptionPane.showConfirmDialog(component, getDeleteTipText()
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + "?", com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove"), , com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove"),
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (val != JOptionPane.OK_OPTION) { if (val != JOptionPane.OK_OPTION) {
return; return;
@ -269,6 +273,14 @@ public abstract class UITableModelAdapter<T> extends AbstractTableModel implemen
table.getSelectionModel().setSelectionInterval(selection, selection); table.getSelectionModel().setSelectionInterval(selection, selection);
} }
public String getDeleteTipText() {
return deleteTipText;
}
public void setDeleteTipText(String deleteTipText) {
this.deleteTipText = deleteTipText;
}
private boolean ismultiSelected() { private boolean ismultiSelected() {
int[] selectedRow = table.getSelectedRows(); int[] selectedRow = table.getSelectedRows();
return (selectedRow.length == 1 && (selectedRow[0] > table.getRowCount() - 1 || selectedRow[0] < 0)) || selectedRow.length == 0; return (selectedRow.length == 1 && (selectedRow[0] > table.getRowCount() - 1 || selectedRow[0] < 0)) || selectedRow.length == 0;

18
designer-base/src/main/java/com/fr/design/layout/FRGUIPaneFactory.java

@ -607,6 +607,24 @@ public class FRGUIPaneFactory {
return jp; return jp;
} }
/**
* 创建垂直流布局水平填充面板
*
* @param isAlignLeft 是否左对齐
* @param align the alignment value
* @param hgap the horizontal gap between components
* @param vgap the vertical gap between components
* @param hfill 水平填充组件
* @return JPanel对象
*/
public static JPanel createVerticalFlowLayout_F_Pane(boolean isAlignLeft, int align, int hgap, int vgap, boolean hfill) {
JPanel jp = new JPanel();
VerticalFlowLayout layout = new VerticalFlowLayout(align, hgap, vgap, hfill);
layout.setAlignLeft(isAlignLeft);
jp.setLayout(layout);
return jp;
}
/** /**
* 创建边框面板L * 创建边框面板L
* *

46
designer-base/src/main/java/com/fr/design/layout/VerticalFlowLayout.java

@ -95,6 +95,15 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
*/ */
protected int vgap; protected int vgap;
/**
* true: 水平填充组件
*
* @see #isHfill()
* @see #setHfill(boolean)
*/
protected boolean hfill;
/** /**
* Constructs a new <code>FlowLayout</code> with a centered alignment and a * Constructs a new <code>FlowLayout</code> with a centered alignment and a
* default 5-unit horizontal and vertical gap. * default 5-unit horizontal and vertical gap.
@ -135,6 +144,14 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
setAlignment(align); setAlignment(align);
} }
public VerticalFlowLayout(int align, int hgap, int vgap, boolean fill) {
this.hgap = hgap;
this.vgap = vgap;
this.hfill = fill;
setAlignment(align);
}
/** /**
* Gets the alignment for this layout. * Gets the alignment for this layout.
* Possible values are <code>FlowLayout.TOP</code>, * Possible values are <code>FlowLayout.TOP</code>,
@ -219,6 +236,31 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
* @param name the name of the component * @param name the name of the component
* @param comp the component to be added * @param comp the component to be added
*/ */
/**
* Gets the horizontal filling of components in the
* <code>Container</code>.The default is false.
*
* @return the horizontal filling of components in the
* <code>Container</code>
* @see #setHfill(boolean)
*/
public boolean isHfill() {
return hfill;
}
/**
* Sets the horizontal filling of components in the
* <code>Container</code>.The default is false.
*
* @param hfill the horizontal filling of components in the
* <code>Container</code>
* @see #isHfill()
*/
public void setHfill(boolean hfill) {
this.hfill = hfill;
}
@Override @Override
public void addLayoutComponent(String name, Component comp) { public void addLayoutComponent(String name, Component comp) {
} }
@ -379,6 +421,7 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
Insets insets = target.getInsets(); Insets insets = target.getInsets();
int maxlen = getMaxLen4LayoutContainer(target, insets); int maxlen = getMaxLen4LayoutContainer(target, insets);
int maxwidth = target.getWidth() - (insets.left + insets.right);
int nmembers = target.getComponentCount(); int nmembers = target.getComponentCount();
int x = getX4LayoutContainer(insets), y = getY4LayoutContainer(insets); int x = getX4LayoutContainer(insets), y = getY4LayoutContainer(insets);
int roww = 0, start = 0; int roww = 0, start = 0;
@ -390,6 +433,9 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
Component m = target.getComponent(i); Component m = target.getComponent(i);
if (m.isVisible()) { if (m.isVisible()) {
Dimension d = getPreferredSize(target, m); Dimension d = getPreferredSize(target, m);
if (hfill) {
d.width = maxwidth;
}
m.setSize(d.width, d.height); m.setSize(d.width, d.height);
rs = dealWithDim4LayoutContainer(target, insets, d, x, y, roww, start, maxlen, i, ltr); rs = dealWithDim4LayoutContainer(target, insets, d, x, y, roww, start, maxlen, i, ltr);

112
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java

@ -3,6 +3,7 @@ package com.fr.design.mainframe.cell.settingpane;
import com.fr.base.Style; import com.fr.base.Style;
import com.fr.design.constants.LayoutConstants; import com.fr.design.constants.LayoutConstants;
import com.fr.design.constants.UIConstants; import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.link.MessageWithLink;
import com.fr.design.editor.ValueEditorPane; import com.fr.design.editor.ValueEditorPane;
import com.fr.design.editor.ValueEditorPaneFactory; import com.fr.design.editor.ValueEditorPaneFactory;
import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.file.HistoryTemplateListPane;
@ -11,6 +12,7 @@ import com.fr.design.gui.ibutton.UIButtonGroup;
import com.fr.design.gui.ibutton.UIRadioButton; import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.MultilineLabel;
import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ispinner.UISpinner; import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.gui.itextfield.UITextField; import com.fr.design.gui.itextfield.UITextField;
@ -21,12 +23,14 @@ import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.layout.VerticalFlowLayout; import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.EastRegionContainerPane; import com.fr.design.mainframe.EastRegionContainerPane;
import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.cell.settingpane.desensitization.CellDesensitizationGroupsPane;
import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase; import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase;
import com.fr.design.utils.gui.UIComponentUtils; import com.fr.design.utils.gui.UIComponentUtils;
import com.fr.design.widget.FRWidgetFactory; import com.fr.design.widget.FRWidgetFactory;
import com.fr.general.ComparatorUtils; import com.fr.general.ComparatorUtils;
import com.fr.general.FRFont; import com.fr.general.FRFont;
import com.fr.report.cell.TemplateCellElement; import com.fr.report.cell.TemplateCellElement;
import com.fr.report.cell.cellattr.CellDesensitizationAttr;
import com.fr.report.cell.cellattr.CellGUIAttr; import com.fr.report.cell.cellattr.CellGUIAttr;
import com.fr.report.cell.cellattr.CellInsertPolicyAttr; import com.fr.report.cell.cellattr.CellInsertPolicyAttr;
import com.fr.report.cell.cellattr.CellPageAttr; import com.fr.report.cell.cellattr.CellPageAttr;
@ -45,10 +49,12 @@ import java.awt.CardLayout;
import java.awt.Color; import java.awt.Color;
import java.awt.Component; import java.awt.Component;
import java.awt.Dimension; import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets; import java.awt.Insets;
import java.awt.Rectangle; import java.awt.Rectangle;
import java.awt.event.ItemEvent; import java.awt.event.ItemEvent;
import java.awt.event.ItemListener; import java.awt.event.ItemListener;
import java.util.ArrayList;
/** /**
* @author zhou * @author zhou
@ -117,23 +123,85 @@ public class CellOtherSetPane extends AbstractCellAttrPane {
private JPanel insertRowPolicyPane; private JPanel insertRowPolicyPane;
private JPanel defaultValuePane; private JPanel defaultValuePane;
// 数据脱敏
private UILabel scopeLabel;
private UIRadioButton exportButton;
private UIRadioButton previewAndExportButton;
private UIRadioButton[] desensitizationButtons;
private CellDesensitizationGroupsPane groupsPane;
private final int EXPORT_SCOPE = 0;
private final int PREVIEW_AND_EXPORT_SCOPE = 1;
private static final Color TIPS_FONT_COLOR = new Color(0x8f8f92); private static final Color TIPS_FONT_COLOR = new Color(0x8f8f92);
/** /**
* 初始化 * 初始化
* *
* @return 面板 * @return 面板
*/ */
public JPanel createContentPane() { public JPanel createContentPane() {
JPanel downPane = new JPanel(new BorderLayout()); JPanel contentPane = FRGUIPaneFactory.createVerticalFlowLayout_F_Pane(true, VerticalFlowLayout.TOP, 0, 0, true);
downPane.add(new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advaced"), HEAD_WDITH, HEAD_HEIGTH, seniorPane()), BorderLayout.NORTH);
downPane.add(new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Pagination"), HEAD_WDITH, HEAD_HEIGTH, pagePane()), BorderLayout.CENTER); contentPane.add(new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Basic"), HEAD_WDITH, HEAD_HEIGTH, basicPane()));
JPanel contentPane = new JPanel(new BorderLayout(0, 0)); contentPane.add(new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Advaced"), HEAD_WDITH, HEAD_HEIGTH, seniorPane()));
contentPane.add(new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Basic"), HEAD_WDITH, HEAD_HEIGTH, basicPane()), BorderLayout.NORTH); contentPane.add(new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Pagination"), HEAD_WDITH, HEAD_HEIGTH, pagePane()));
contentPane.add(downPane, BorderLayout.CENTER); contentPane.add(new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Desensitization"), HEAD_WDITH, HEAD_HEIGTH, desensitizePane()));
initAllNames(); // VerticalFlowLayout 与 实现的滚动条有冲突,因此再加一层panel
JPanel jPanel = new JPanel();
jPanel.add(contentPane);
return jPanel;
}
private JPanel desensitizePane() {
JPanel scopePane = initScopePane();
// 带超链的提示信息
UILabel label = new UILabel();
MessageWithLink hyperlink = new MessageWithLink(
Toolkit.i18nText("Fine-Design_Report_Desensitization_Tip"),
Toolkit.i18nText("Fine-Design_Report_Desensitization_Hyperlink"),
Toolkit.i18nText("Fine-Design_Report_Desensitization_Help_Document_Url"),
StringUtils.EMPTY,
label.getBackground(),
label.getFont(),
Color.LIGHT_GRAY
);
groupsPane = new CellDesensitizationGroupsPane(this);
JPanel contentPane = FRGUIPaneFactory.createVerticalFlowLayout_F_Pane(true, VerticalFlowLayout.TOP, 0, 0, true);
contentPane.add(scopePane);
contentPane.add(hyperlink);
contentPane.add(groupsPane);
return contentPane; return contentPane;
} }
/**
* 脱敏设置应用范围panel
* @return
*/
private JPanel initScopePane() {
scopeLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Scope"));
exportButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Report_Desensitization_Export"));
previewAndExportButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Report_Desensitization_Preview_Export"));
desensitizationButtons = new UIRadioButton[]{
exportButton, previewAndExportButton
};
ButtonGroup buttonGroup = new ButtonGroup();
for (UIRadioButton radioButton : desensitizationButtons) {
buttonGroup.add(radioButton);
}
JPanel head = new JPanel();
head.setLayout(new FlowLayout(FlowLayout.LEFT));
head.add(scopeLabel);
head.add(exportButton);
head.add(previewAndExportButton);
return head;
}
private JPanel basicPane() { private JPanel basicPane() {
defaultAutoRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Follow_Paper_Settings")); defaultAutoRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Follow_Paper_Settings"));
noAutoRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_No_Auto_Adjust")); noAutoRadioButton = new UIRadioButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_No_Auto_Adjust"));
@ -622,6 +690,19 @@ public class CellOtherSetPane extends AbstractCellAttrPane {
if (!jTemplate.isJWorkBook()) { //表单中报表块编辑屏蔽掉 插入行策略 if (!jTemplate.isJWorkBook()) { //表单中报表块编辑屏蔽掉 插入行策略
insertRowPolicyPane.setVisible(false); insertRowPolicyPane.setVisible(false);
} }
populateDesensitizationBean(cellElement);
}
private void populateDesensitizationBean(TemplateCellElement cellElement) {
CellDesensitizationAttr cellDesensitizationAttr = cellElement.getCellDesensitizationAttr();
if (cellDesensitizationAttr == null) {
cellDesensitizationAttr = new CellDesensitizationAttr();
}
boolean exportSelected = cellDesensitizationAttr.getScope() == 0;
exportButton.setSelected(exportSelected);
previewAndExportButton.setSelected(!exportSelected);
groupsPane.populate(cellDesensitizationAttr.getDesensitizationBeans());
} }
/** /**
@ -714,6 +795,23 @@ public class CellOtherSetPane extends AbstractCellAttrPane {
cellElement.setCellGUIAttr(cellGUIAttr); cellElement.setCellGUIAttr(cellGUIAttr);
} }
updatePageAttr(cellElement); updatePageAttr(cellElement);
updateDesensitizationAttr(cellElement);
}
/**
* 更新数据脱敏设置
*
* @param cellElement
*/
private void updateDesensitizationAttr(TemplateCellElement cellElement) {
CellDesensitizationAttr cellDesensitizationAttr = cellElement.getCellDesensitizationAttr();
if (cellDesensitizationAttr == null) {
cellDesensitizationAttr = new CellDesensitizationAttr();
}
cellDesensitizationAttr.setScope(exportButton.isSelected() ? EXPORT_SCOPE : PREVIEW_AND_EXPORT_SCOPE);
cellDesensitizationAttr.setDesensitizationBeans(new ArrayList<>(groupsPane.update()));
cellElement.setCellDesensitizationAttr(cellDesensitizationAttr);
} }

127
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/CellDesensitizationGroupsPane.java

@ -0,0 +1,127 @@
package com.fr.design.mainframe.cell.settingpane.desensitization;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itableeditorpane.UITableEditorPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.cell.settingpane.AbstractCellAttrPane;
import com.fr.design.mainframe.cell.settingpane.desensitization.model.CellDesensitizationTableModel;
import com.fr.report.cell.desensitization.CellDesensitizationBean;
import javax.swing.JPanel;
import javax.swing.JTable;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.util.List;
import java.util.Objects;
/**
* 数据脱敏规则设置面板
*
* @author Leo.Qin
* @version 11.0
* Created by Leo.Qin on 2022/11/15
*/
public class CellDesensitizationGroupsPane extends JPanel {
private final CellDesensitizationTableModel model;
// 规则编辑面板
UITableEditorPane<CellDesensitizationBean> editorPane;
// 添加规则按钮面板
private JPanel addRulePane;
public CellDesensitizationGroupsPane(AbstractCellAttrPane pane) {
model = new CellDesensitizationTableModel(pane, this);
initComponent();
}
private void initComponent() {
this.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 10, true));
addRulePane = initAddPane(model);
editorPane = initEditorPane(model);
this.add(addRulePane);
this.add(editorPane);
}
/**
* 初始化添加脱敏设置面板
*
* @param model
* @return
*/
private JPanel initAddPane(CellDesensitizationTableModel model) {
UIButton addButton = new UIButton(model.getAction());
UILabel addLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Desensitization_Setting"));
double p = TableLayout.PREFERRED;
double f = TableLayout.FILL;
double[] columnSize = {p, f};
double[] rowSize = {p, p};
Component[][] components = new Component[][]{
new Component[]{addLabel, addButton}
};
return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, 20, 0);
}
/**
* 初始化脱敏设置编辑面板
*
* @param model
* @return
*/
private UITableEditorPane<CellDesensitizationBean> initEditorPane(CellDesensitizationTableModel model) {
UITableEditorPane<CellDesensitizationBean> tableEditorPane = new UITableEditorPane<CellDesensitizationBean>(model) {
@Override
protected void initComponent(UITableEditAction[] action) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JTable editTable = getTableModel().createTable();
editTable.getTableHeader().setBackground(UIConstants.DEFAULT_BG_RULER);
setEditTable(editTable);
initbuttonPane(action);
getbuttonPane().setBackground(UIConstants.DEFAULT_BG_RULER);
JPanel controlPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
controlPane.setBackground(Color.WHITE);
controlPane.add(getbuttonPane(), BorderLayout.WEST);
JPanel pane = new JPanel(new BorderLayout(4, 4));
pane.add(editTable, BorderLayout.CENTER);
pane.add(controlPane, BorderLayout.NORTH);
this.add(pane, BorderLayout.CENTER);
}
};
return tableEditorPane;
}
/**
* 更新数据
*/
public List<CellDesensitizationBean> update() {
return editorPane.update();
}
/**
* 填充数据
*/
public void populate(List<CellDesensitizationBean> desensitizationBeans) {
if (Objects.nonNull(desensitizationBeans)) {
editorPane.populate(desensitizationBeans.toArray(new CellDesensitizationBean[]{}));
}
}
}

109
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/model/CellDesensitizationTableModel.java

@ -0,0 +1,109 @@
package com.fr.design.mainframe.cell.settingpane.desensitization.model;
import com.fr.design.gui.itableeditorpane.UITableEditAction;
import com.fr.design.gui.itableeditorpane.UITableModelAdapter;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.cell.settingpane.AbstractCellAttrPane;
import com.fr.report.cell.desensitization.CellDesensitizationBean;
import com.fr.stable.StringUtils;
import java.awt.Component;
import java.awt.event.ActionEvent;
/**
* 单元格数据脱敏model
*
* @author Leo.Qin
* @version 11.0
* Created by Leo.Qin on 2023/1/4
*/
public class CellDesensitizationTableModel extends UITableModelAdapter<CellDesensitizationBean> {
private final int ROW_HEIGHT = 60;
/**
* 属性面板
*/
private AbstractCellAttrPane attrPane;
/**
* 添加脱敏设置action
*/
private AddDesensitizationAction action;
public CellDesensitizationTableModel(AbstractCellAttrPane attrPane, Component parent) {
super(new String[]{StringUtils.EMPTY});
this.attrPane = attrPane;
this.action = new AddDesensitizationAction();
this.table.getTableHeader().setVisible(false);
this.table.setRowHeight(ROW_HEIGHT);
setColumnClass(new Class[]{
DesensitizationCellEditor.class
});
this.setDefaultEditor(DesensitizationCellEditor.class, new DesensitizationCellEditor(parent, this));
this.setDefaultRenderer(DesensitizationCellEditor.class, new DesensitizationCellRender(parent, this));
}
@Override
public UITableEditAction[] createAction() {
return new UITableEditAction[]{
new MoveUpAction(),
new MoveDownAction(),
new DeleteDesensitizationAction()
};
}
public AddDesensitizationAction getAction() {
return action;
}
/**
* 添加脱敏规则action
*/
public class AddDesensitizationAction extends AddTableRowAction {
public AddDesensitizationAction() {
this.setName(StringUtils.EMPTY);
}
@Override
public void actionPerformed(ActionEvent e) {
super.actionPerformed(e);
// 添加一条空白数据
addRow(CellDesensitizationBean.createEmptyBean());
table.getSelectionModel().setSelectionInterval(table.getRowCount() - 1, table.getRowCount() - 1);
fireTableDataChanged();
}
}
private class DeleteDesensitizationAction extends DeleteAction {
public DeleteDesensitizationAction() {
super();
this.setDeleteTipText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Remove_Tip"));
}
}
@Override
public Object getValueAt(int rowIndex, int columnIndex) {
CellDesensitizationBean desensitizationBean = getList().get(rowIndex);
if (desensitizationBean == null) {
desensitizationBean = CellDesensitizationBean.createEmptyBean();
}
return desensitizationBean;
}
@Override
public boolean isCellEditable(int row, int col) {
return true;
}
/**
* 手动触发模版变化用于更新单元格脱敏设置属性
*/
public void fireAttrChanged() {
attrPane.attributeChanged();
}
}

43
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/model/DesensitizationCellEditor.java

@ -0,0 +1,43 @@
package com.fr.design.mainframe.cell.settingpane.desensitization.model;
import com.fr.report.cell.desensitization.CellDesensitizationBean;
import javax.swing.AbstractCellEditor;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.border.LineBorder;
import javax.swing.table.TableCellEditor;
import java.awt.Color;
import java.awt.Component;
/**
* 脱敏规则设置cellEditor
* @author Leo.Qin
* @version 11.0
* Created by Leo.Qin on 2023/1/4
*/
public class DesensitizationCellEditor extends AbstractCellEditor implements TableCellEditor {
private final DesensitizationCellPane editPane;
DesensitizationCellEditor(Component parent, CellDesensitizationTableModel model) {
editPane = new DesensitizationCellPane(parent, model);
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
editPane.populate((CellDesensitizationBean) value, row);
JPanel editPanel = editPane.getEditPanel();
editPanel.setBorder(new LineBorder(Color.LIGHT_GRAY));
return editPanel;
}
@Override
public Object getCellEditorValue() {
return editPane.getCellEditorValue();
}
}

304
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/model/DesensitizationCellPane.java

@ -0,0 +1,304 @@
package com.fr.design.mainframe.cell.settingpane.desensitization.model;
import com.fr.data.desensitize.rule.DesensitizationRuleManager;
import com.fr.data.desensitize.rule.base.DesensitizationRule;
import com.fr.data.desensitize.rule.base.DesensitizationRuleStatus;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.data.datapane.preview.desensitization.TableDataPreviewDesensitizeManager;
import com.fr.design.data.datapane.preview.desensitization.view.rule.DesensitizationRulePane;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.event.UIObserverListener;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icombocheckbox.UIComboCheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.report.cell.desensitization.CellDesensitizationBean;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.collections4.map.HashedMap;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.FontMetrics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
/**
* 单元格脱敏规则设置面板
*
* @author Leo.Qin
* @version 11.0
* Created by Leo.Qin on 2023/1/5
*/
public class DesensitizationCellPane extends BasicBeanPane {
private Component parent;
private JPanel editPanel;
private UILabel label;
private UITextField emptyTextField;
private UIButton ruleButton;
private UITextField ruleTextField;
private UIComboCheckBox rolesComboBox;
private static final String APOSTROPHE = "...";
private Map<String, String> roleMap;
private DesensitizationRule rule;
private CellDesensitizationTableModel model;
DesensitizationCellPane(Component parent, CellDesensitizationTableModel model) {
this.parent = parent;
this.model = model;
initComponent();
addListener();
}
private void initComponent() {
editPanel = new JPanel();
editPanel.setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 0, true));
label = new UILabel();
label.setEnabled(false);
editPanel.add(label);
ruleButton = new UIButton(APOSTROPHE);
ruleTextField = new UITextField();
ruleTextField.setEnabled(true);
ruleTextField.setEditable(false);
ruleTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Report_Desensitization_Rule_Place_Holder"));
roleMap = new HashedMap<>();
rolesComboBox = new RuleUIComboCheckBox();
rolesComboBox.setPlaceHolder(Toolkit.i18nText("Fine-Design_Report_Desensitization_Role_Place_Holder"));
rolesComboBox.setEnabled(true);
emptyTextField = new UITextField();
emptyTextField.setEnabled(false);
emptyTextField.setOpaque(false);
editPanel.add(initTableCellPanel());
}
/**
* 初始化单元格中的panel
*/
private JPanel initTableCellPanel() {
double f = TableLayout.FILL;
double p = TableLayout.PREFERRED;
double[] rowSize = new double[]{f, f};
double[] columnSize = new double[]{p, f};
Component[][] components = new Component[][]{
new Component[]{ruleButton, ruleTextField},
new Component[]{emptyTextField, rolesComboBox}
};
return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, 0, 0);
}
private void addListener() {
ruleButton.addActionListener(chooseRuleListener);
rolesComboBox.registerChangeListener(uiObserverListener);
}
private final UIObserverListener uiObserverListener = new UIObserverListener() {
@Override
public void doChange() {
CellDesensitizationBean selectBean = model.getSelectedValue();
Set<String> roleIds = generateRolesIdsBySelectedValues();
if (Objects.nonNull(selectBean) && !selectBean.getRoleIds().equals(roleIds)) {
selectBean.setRoleIds(generateRolesIdsBySelectedValues());
model.fireAttrChanged();
}
}
};
private final ActionListener chooseRuleListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
CellDesensitizationBean selectBean = model.getSelectedValue();
DesensitizationRulePane rulePane = new DesensitizationRulePane();
BasicDialog ruleDialog = rulePane.showWindowWithCustomSize(SwingUtilities.getWindowAncestor(parent), new DialogActionAdapter() {
@Override
public void doOk() {
rule = rulePane.updateBean();
if (Objects.nonNull(selectBean) && Objects.nonNull(rule) && !selectBean.getDesensitizationRule().equals(rule)) {
selectBean.setDesensitizationRule(rule);
ruleTextField.setText(rule.getRuleName());
// 非正常状态需要颜色修改为红色
refreshRuleState(selectBean);
model.fireAttrChanged();
}
rule = null;
}
}, BasicDialog.DEFAULT);
ruleDialog.setVisible(true);
}
};
/**
* 根据当前的规则配置信息生成选中的rolesMap用来展示
*/
public Map<Object, Boolean> generateRolesCheckBoxSelectedValues(CellDesensitizationBean bean) {
Map<Object, Boolean> result = new HashMap<>(roleMap.size());
for (Map.Entry<String, String> roleEntry : roleMap.entrySet()) {
String roleId = roleEntry.getKey();
String roleName = roleEntry.getValue();
result.put(roleName, bean.getRoleIds().contains(roleId));
}
return result;
}
/**
* 根据当前的RoleName选择项生成其对应的RoleId的set存入规则配置信息
*/
public Set<String> generateRolesIdsBySelectedValues() {
Set<String> result = new LinkedHashSet<>();
Object[] selectedValues = rolesComboBox.getSelectedValues();
for (Object selectedValue : selectedValues) {
String selectedRoleName = (String) selectedValue;
if (roleMap.containsValue(selectedRoleName)) {
Optional<Map.Entry<String, String>> matchedEntry = roleMap.entrySet().stream().filter(entry -> StringUtils.equals(entry.getValue(), selectedRoleName)).findFirst();
matchedEntry.ifPresent(stringStringEntry -> result.add(stringStringEntry.getKey()));
}
}
return result;
}
public JPanel getEditPanel() {
return editPanel;
}
/**
* 填充数据
*/
public void populate(CellDesensitizationBean value, int row) {
refreshRoles();
String ruleName = value.getDesensitizationRule().getRuleName();
ruleTextField.setText(ruleName);
// 非正常状态需要颜色修改为红色
refreshRuleState(value);
Map<Object, Boolean> map = generateRolesCheckBoxSelectedValues(value);
rolesComboBox.setSelectedValues(map);
label.setText(Toolkit.i18nText("Fine-Design_Report_Desensitization_Setting") + row);
}
private void refreshRoles() {
Map<String, String> roles = TableDataPreviewDesensitizeManager.getInstance().getAllRoles();
if (!roleMap.equals(roles)) {
roleMap = roles;
rolesComboBox.refreshCombo(roles.values().toArray());
}
}
private void refreshRuleState(CellDesensitizationBean value) {
DesensitizationRuleStatus ruleStatus = DesensitizationRuleManager.getInstance().getRuleStatus(value.getDesensitizationRule());
if (value.equals(CellDesensitizationBean.createEmptyBean())) {
ruleTextField.setForeground(Color.GRAY);
} else if (ruleStatus != DesensitizationRuleStatus.NORMAL) {
ruleTextField.setForeground(Color.RED);
} else {
ruleTextField.setForeground(Color.BLACK);
}
}
@Deprecated
@Override
public void populateBean(Object ob) {
}
@Deprecated
@Override
public Object updateBean() {
return null;
}
@Deprecated
@Override
protected String title4PopupWindow() {
return null;
}
public Object getCellEditorValue() {
return ruleTextField.getText();
}
private class RuleUIComboCheckBox extends UIComboCheckBox {
public RuleUIComboCheckBox() {
super(DesensitizationCellPane.this.roleMap.values().toArray(), true);
}
@Override
protected void setLayoutAndAddComponents() {
// 使用BorderLayout,否则默认使用的FlowLayout会让整个下拉选框使用最小Size,然后TableCell这边会出现空白
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.add(getEditor(), BorderLayout.CENTER);
this.add(getArrowButton(), BorderLayout.EAST);
}
@Override
protected void setEditorToolTipText(JComponent editor, String text) {
// 选项过多时,已选中的值会做省略显示处理,此处添加一个Tooltips,显示完整值
if (text != null) {
editor.setToolTipText(text);
}
}
@Override
protected void setEditorPlaceHolder(UITextField editor) {
editor.setPlaceholder(this.getPlaceHolder());
}
@Override
protected String omitEditorText(UITextField textEditor, String text) {
char[] omitChars = OMIT_TEXT.toCharArray();
//获取字体的大小
FontMetrics fontMetrics = textEditor.getFontMetrics(textEditor.getFont());
//计算省略号的长度
int omitLength = fontMetrics.charsWidth(omitChars, 0, omitChars.length);
String omitText = StringUtils.EMPTY;
char[] chars = text.toCharArray();
for (int i = 1; i <= chars.length; i++) {
//如果原文本+省略号长度超过文本框
int width = textEditor.getWidth();
if (width != 0 && fontMetrics.charsWidth(chars, 0, i) + omitLength > width) {
//从第i-1的位置截断再拼上省略号
omitText = text.substring(0, i - 2) + OMIT_TEXT;
break;
}
}
return omitText.equals(StringUtils.EMPTY) ? text : omitText;
}
}
}

49
designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/desensitization/model/DesensitizationCellRender.java

@ -0,0 +1,49 @@
package com.fr.design.mainframe.cell.settingpane.desensitization.model;
import com.fr.report.cell.desensitization.CellDesensitizationBean;
import javax.swing.BorderFactory;
import javax.swing.JTable;
import javax.swing.border.LineBorder;
import javax.swing.table.DefaultTableCellRenderer;
import java.awt.Color;
import java.awt.Component;
/**
* 脱敏规则设置cellRenderer
*
* @author Leo.Qin
* @version 11.0
* Created by Leo.Qin on 2023/1/4
*/
public class DesensitizationCellRender extends DefaultTableCellRenderer {
private final DesensitizationCellPane editPane;
DesensitizationCellRender(Component parent, CellDesensitizationTableModel model) {
editPane = new DesensitizationCellPane(parent, model);
}
public Object getCellEditorValue() {
return editPane.getCellEditorValue();
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
editPane.populate((CellDesensitizationBean) value, row);
if (table.isCellSelected(row, column)) {
// 设置选中框
editPane.getEditPanel().setBorder(new LineBorder(Color.LIGHT_GRAY));
} else {
editPane.getEditPanel().setBorder(BorderFactory.createEmptyBorder());
}
return editPane.getEditPanel();
}
}
Loading…
Cancel
Save