Browse Source

Pull request #11228: REPORT-82899 数据脱敏三期

Merge in DESIGN/design from ~LEO.QIN/design:feature/x to feature/x

* commit '5bb7f1ac93204f145ecf60f932d125f6f61c628b':
  REPORT-82899 数据脱敏三期 修改增加单元格脱敏属性的实现方式
  数据脱敏三期 【问题原因】rt 【改动思路】rt 顺便过一下开发文档 https://kms.fineres.com/pages/viewpage.action?pageId=576039082
feature/x
Leo.Qin-覃宇攀 1 year ago
parent
commit
fc1d8b47bd
  1. 32
      designer-base/src/main/java/com/fr/design/gui/icombocheckbox/UIComboCheckBox.java
  2. 54
      designer-base/src/main/java/com/fr/design/gui/itableeditorpane/UITableEditorPane.java
  3. 96
      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. 122
      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
  12. 1
      designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellDSColumnEditor.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.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
@ -32,6 +29,9 @@ import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
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 static final String DEFAULT_VALUE_SPERATOR = ",";
private static final String OMIT_TEXT = "...";
protected static final String OMIT_TEXT = "...";
private UIObserverListener uiObserverListener;
private GlobalNameListener globalNameListener = null;
@ -60,6 +60,7 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
private boolean showOmitText = true;
private boolean supportSelectAll = true;
private String placeHolder = StringUtils.EMPTY;
public UIComboCheckBox(Object[] value) {
this(value, DEFAULT_VALUE_SPERATOR, true);
@ -138,6 +139,14 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
return editor;
}
public String getPlaceHolder() {
return placeHolder;
}
public void setPlaceHolder(String placeHolder) {
this.placeHolder = placeHolder;
}
public UIButton getArrowButton() {
return arrowButton;
}
@ -191,6 +200,9 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
@Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
attributeChange();
if (uiObserverListener != null) {
uiObserverListener.doChange();
}
}
@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;
//计算加省略号后的文本
editor.setText(this.showOmitText ? omitEditorText(editor, text) : text);
// 添加placeHolder
setEditorPlaceHolder(editor);
// tooltips显示原值
setEditorToolTipText(editor, text);
}
/**
* 为为添加placeholder
* @param editor
*/
protected void setEditorPlaceHolder(UITextField editor) {
// 默认空实现
}
/**
* 为UITextField设置悬浮提示值
*
@ -311,7 +333,7 @@ public class UIComboCheckBox extends JComponent implements UIObserver, GlobalNam
* @param text
* @return 省略后的文字
*/
private static String omitEditorText(UITextField textEditor, String text) {
protected String omitEditorText(UITextField textEditor, String text) {
char[] omitChars = OMIT_TEXT.toCharArray();
//获取字体的大小
FontMetrics fontMetrics = textEditor.getFontMetrics(textEditor.getFont());

54
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.layout.FRGUIPaneFactory;
import javax.swing.*;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.event.TableModelListener;
import java.awt.*;
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.util.List;
/**
@ -31,25 +33,25 @@ public class UITableEditorPane<T> extends BasicPane {
private String leftLabelName;
private JPanel buttonPane;
public UITableEditorPane(UITableModelAdapter<T> model) {
this.tableModel = model;
this.initComponent(model.createAction());
}
public UITableEditorPane(UITableModelAdapter<T> model) {
this.tableModel = model;
this.initComponent(model.createAction());
}
public UITableEditorPane(UITableModelAdapter<T> model, String s) {
leftLabelName = s;
this.tableModel = model;
this.initComponent(model.createAction());
}
public UITableEditorPane(UITableModelAdapter<T> model, String s) {
leftLabelName = s;
this.tableModel = model;
this.initComponent(model.createAction());
}
private void initComponent(UITableEditAction[] action) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel pane = new JPanel(new BorderLayout(4, 4));
this.add(pane, BorderLayout.CENTER);
protected void initComponent(UITableEditAction[] action) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel pane = new JPanel(new BorderLayout(4, 4));
this.add(pane, BorderLayout.CENTER);
UILabel l = new UILabel(leftLabelName);
editTable = tableModel.createTable();
editTable.getTableHeader().setBackground(UIConstants.DEFAULT_BG_RULER);
UILabel l = new UILabel(leftLabelName);
editTable = tableModel.createTable();
editTable.getTableHeader().setBackground(UIConstants.DEFAULT_BG_RULER);
UIScrollPane scrollPane = new UIScrollPane(editTable);
scrollPane.setBorder(new UIRoundedBorder(UIConstants.TITLED_BORDER_COLOR, 1, UIConstants.ARC));
@ -62,11 +64,11 @@ public class UITableEditorPane<T> extends BasicPane {
}
public UITableModelAdapter<T> getTableModel(){
public UITableModelAdapter<T> getTableModel() {
return tableModel;
}
private void initbuttonPane(UITableEditAction[] action) {
protected void initbuttonPane(UITableEditAction[] action) {
buttonPane = new JPanel();
if (action != null) {
@ -146,6 +148,14 @@ public class UITableEditorPane<T> extends BasicPane {
return buttonPane;
}
public JTable getEditTable() {
return editTable;
}
public void setEditTable(JTable editTable) {
this.editTable = editTable;
}
/**
* 停止编辑
*/
@ -157,7 +167,7 @@ public class UITableEditorPane<T> extends BasicPane {
/**
* 设置表头是否可以改变大小
*/
public void setHeaderResizing(boolean resizingAllowed){
public void setHeaderResizing(boolean resizingAllowed) {
editTable.getTableHeader().setResizingAllowed(resizingAllowed);
}

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

@ -219,57 +219,69 @@ public abstract class UITableModelAdapter<T> extends AbstractTableModel implemen
protected class DeleteAction extends UITableEditAction {
private Component component = null;
// 删除时界面显示的提示语,可自定义
private String deleteTipText;
public DeleteAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Delete"));
this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/remove.png"));
}
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"));
}
public DeleteAction(Component component){
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Delete"));
this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/cell/control/remove.png"));
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.component = component;
}
@Override
public void actionPerformed(ActionEvent e) {
int[] selectedRow = table.getSelectedRows();
if (ismultiSelected()) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(),com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multiple_Select_Warn_Text"));
return;
}
if (table.getCellEditor() != null) {
try {
table.getCellEditor().stopCellEditing();
} catch (Exception ee) {
int[] selectedRow = table.getSelectedRows();
if (ismultiSelected()) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Multiple_Select_Warn_Text"));
return;
}
if (table.getCellEditor() != null) {
try {
table.getCellEditor().stopCellEditing();
} catch (Exception ee) {
FineLoggerFactory.getLogger().error(ee.getMessage(), ee);
}
}
if (getRowCount() < 1) {
return;
}
if(component == null){
component = DesignerContext.getDesignerFrame();
}
int val = FineJOptionPane.showConfirmDialog(component,
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"),
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (val != JOptionPane.OK_OPTION) {
return;
}
for (int i = 0; i < selectedRow.length; i++) {
if (selectedRow[i] - i < 0) {
continue;
}
removeRow(selectedRow[i] - i);
}
fireTableDataChanged();
int selection = selectedRow[0] > table.getRowCount() ? table.getRowCount() - 1
: (selectedRow[0] > 1 ? selectedRow[0] - 1 : 0);
table.getSelectionModel().setSelectionInterval(selection, selection);
}
}
}
if (getRowCount() < 1) {
return;
}
if (component == null) {
component = DesignerContext.getDesignerFrame();
}
int val = FineJOptionPane.showConfirmDialog(component, getDeleteTipText()
, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Remove"),
JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
if (val != JOptionPane.OK_OPTION) {
return;
}
for (int i = 0; i < selectedRow.length; i++) {
if (selectedRow[i] - i < 0) {
continue;
}
removeRow(selectedRow[i] - i);
}
fireTableDataChanged();
int selection = selectedRow[0] > table.getRowCount() ? table.getRowCount() - 1
: (selectedRow[0] > 1 ? selectedRow[0] - 1 : 0);
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();
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;
}
/**
* 创建垂直流布局水平填充面板
*
* @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
*

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;
/**
* true: 水平填充组件
*
* @see #isHfill()
* @see #setHfill(boolean)
*/
protected boolean hfill;
/**
* Constructs a new <code>FlowLayout</code> with a centered alignment and a
* default 5-unit horizontal and vertical gap.
@ -135,6 +144,14 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
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.
* 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 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
public void addLayoutComponent(String name, Component comp) {
}
@ -379,6 +421,7 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
Insets insets = target.getInsets();
int maxlen = getMaxLen4LayoutContainer(target, insets);
int maxwidth = target.getWidth() - (insets.left + insets.right);
int nmembers = target.getComponentCount();
int x = getX4LayoutContainer(insets), y = getY4LayoutContainer(insets);
int roww = 0, start = 0;
@ -390,6 +433,9 @@ public class VerticalFlowLayout implements LayoutManager, java.io.Serializable {
Component m = target.getComponent(i);
if (m.isVisible()) {
Dimension d = getPreferredSize(target, m);
if (hfill) {
d.width = maxwidth;
}
m.setSize(d.width, d.height);
rs = dealWithDim4LayoutContainer(target, insets, d, x, y, roww, start, maxlen, i, ltr);

122
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.design.constants.LayoutConstants;
import com.fr.design.constants.UIConstants;
import com.fr.design.dialog.link.MessageWithLink;
import com.fr.design.editor.ValueEditorPane;
import com.fr.design.editor.ValueEditorPaneFactory;
import com.fr.design.file.HistoryTemplateListPane;
@ -21,12 +22,14 @@ import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.EastRegionContainerPane;
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.utils.gui.UIComponentUtils;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRFont;
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.CellInsertPolicyAttr;
import com.fr.report.cell.cellattr.CellPageAttr;
@ -45,10 +48,12 @@ import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
/**
* @author zhou
@ -117,23 +122,85 @@ public class CellOtherSetPane extends AbstractCellAttrPane {
private JPanel insertRowPolicyPane;
private JPanel defaultValuePane;
// 数据脱敏
private UILabel scopeLabel;
private UIRadioButton exportButton;
private UIRadioButton previewAndExportButton;
private UIRadioButton[] desensitizationButtons;
private CellDesensitizationGroupsPane groupsPane;
private final int EXPORT_SCOPE = CellDesensitizationAttr.EXPORT_SCOPE;
private final int PREVIEW_AND_EXPORT_SCOPE = CellDesensitizationAttr.PREVIEW_AND_EXPORT_SCOPE;
private static final Color TIPS_FONT_COLOR = new Color(0x8f8f92);
/**
* 初始化
*
* @return 面板
*/
public JPanel createContentPane() {
JPanel downPane = new JPanel(new BorderLayout());
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);
JPanel contentPane = new JPanel(new BorderLayout(0, 0));
contentPane.add(new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Basic"), HEAD_WDITH, HEAD_HEIGTH, basicPane()), BorderLayout.NORTH);
contentPane.add(downPane, BorderLayout.CENTER);
initAllNames();
JPanel contentPane = FRGUIPaneFactory.createVerticalFlowLayout_F_Pane(true, VerticalFlowLayout.TOP, 0, 0, true);
contentPane.add(new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Basic"), HEAD_WDITH, HEAD_HEIGTH, basicPane()));
contentPane.add(new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Advaced"), HEAD_WDITH, HEAD_HEIGTH, seniorPane()));
contentPane.add(new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Pagination"), HEAD_WDITH, HEAD_HEIGTH, pagePane()));
contentPane.add(new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Desensitization"), HEAD_WDITH, HEAD_HEIGTH, desensitizePane()));
// 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;
}
/**
* 脱敏设置应用范围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() {
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"));
@ -211,7 +278,7 @@ public class CellOtherSetPane extends AbstractCellAttrPane {
double[] rowSize = {p, p, p};
double[] columnSize = {f};
Component[][] components = new Component[][] {
Component[][] components = new Component[][]{
new Component[]{insertRowPolicyLabel},
new Component[]{insertRowPolicyButtonGroup},
new Component[]{insertRowPane},
@ -220,7 +287,7 @@ public class CellOtherSetPane extends AbstractCellAttrPane {
} else {
double[] rowSize = {p, p};
double[] columnSize = {f, BUTTON_GROUP_WIDTH};
Component[][] components = new Component[][] {
Component[][] components = new Component[][]{
new Component[]{insertRowPolicyLabel, insertRowPolicyButtonGroup},
new Component[]{null, insertRowPane},
};
@ -243,7 +310,7 @@ public class CellOtherSetPane extends AbstractCellAttrPane {
int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}};
JPanel fileNamePane = createNormal();
fileNamePane.setBorder(BorderFactory.createEmptyBorder(0,12,0,0));
fileNamePane.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0));
UILabel showContentLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Show_Content"), SwingConstants.LEFT);
UIComponentUtils.setLineWrap(showContentLabel);
@ -389,9 +456,9 @@ public class CellOtherSetPane extends AbstractCellAttrPane {
currentPageFixedRowDataTipLabel.setBorder(UIConstants.CELL_ATTR_ZEROBORDER);
currentPageFixedRowDataTipLabel.setForeground(TIPS_FONT_COLOR);
double p = TableLayout.PREFERRED;
double[] rowSize = {p, p, p, p, p, p, p, p, p, p, p,p};
double[] rowSize = {p, p, p, p, p, p, p, p, p, p, p, p};
double[] columnSize = {p};
int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},{1,1},{1,1}};
int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}};
Component[][] components = new Component[][]{
new Component[]{null},
new Component[]{pageBeforeRowCheckBox},
@ -622,6 +689,19 @@ public class CellOtherSetPane extends AbstractCellAttrPane {
if (!jTemplate.isJWorkBook()) { //表单中报表块编辑屏蔽掉 插入行策略
insertRowPolicyPane.setVisible(false);
}
populateDesensitizationBean(cellElement);
}
private void populateDesensitizationBean(TemplateCellElement cellElement) {
CellDesensitizationAttr cellDesensitizationAttr = cellElement.getCellAttr(CellDesensitizationAttr.ATTR_TAG);
if (cellDesensitizationAttr == null) {
cellDesensitizationAttr = new CellDesensitizationAttr();
}
boolean exportSelected = cellDesensitizationAttr.getScope() == EXPORT_SCOPE;
exportButton.setSelected(exportSelected);
previewAndExportButton.setSelected(!exportSelected);
groupsPane.populate(cellDesensitizationAttr.getDesensitizationBeans());
}
/**
@ -714,6 +794,24 @@ public class CellOtherSetPane extends AbstractCellAttrPane {
cellElement.setCellGUIAttr(cellGUIAttr);
}
updatePageAttr(cellElement);
updateDesensitizationAttr(cellElement);
}
/**
* 更新数据脱敏设置
*
* @param cellElement
*/
private void updateDesensitizationAttr(TemplateCellElement cellElement) {
CellDesensitizationAttr cellDesensitizationAttr = cellElement.getCellAttr(CellDesensitizationAttr.XML_TAG);
if (cellDesensitizationAttr == null) {
cellDesensitizationAttr = new CellDesensitizationAttr();
}
cellDesensitizationAttr.setScope(exportButton.isSelected() ? EXPORT_SCOPE : PREVIEW_AND_EXPORT_SCOPE);
cellDesensitizationAttr.setDesensitizationBeans(new ArrayList<>(groupsPane.update()));
cellElement.addCellAttr(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();
}
}

1
designer-realize/src/main/java/com/fr/quickeditor/cellquick/CellDSColumnEditor.java

@ -1064,7 +1064,6 @@ public class CellDSColumnEditor extends CellQuickEditor {
@Override
public void refreshMultipleDetails() {
tabsHeaderIconPane.setVisible(tc.isSelectedOneCell());
cellDSColumnAdvancedPane.setVisible(tc.isSelectedOneCell());
cellDSColumnBasicPane.setMultipleVisible(tc.isSelectedOneCell());
}

Loading…
Cancel
Save