Browse Source

Merge pull request #12250 in DESIGN/design from feature/x to bugfix/11.0

* commit '5619bf3f828fe962a37b7f00a277524380fcc2a3':
  REPORT-91839 模板版本管理二期 修复bug
  REPORT-91839 模板版本管理二期 多删了一部分
  REPORT-91839 模板版本管理二期 补充按钮交互,消除冗余代码
  REPORT-91839 模板版本管理二期 优化判断新老模式的逻辑,事件响应改为Config准备后进行
  REPORT-91839 模板版本管理二期 完善一下判断逻辑,增加自动保存标签设置
  REPORT-91839 模板版本管理二期 修复规范问题
  REPORT-91839 模板版本管理二期
  REPORT-86153 误传
  REPORT-86153【信创】达梦数据库适配存储过程
  REPORT-80651 模板版本管理重构一期补交
  REPORT-89867 【降本增效】插件管理优化 优化代码
  REPORT-89867 【降本增效】插件管理优化 去除两次for循环
  REPORT-89867 【降本增效】插件管理优化
  REPORT-89867 【降本增效】插件管理优化
  REPORT-89867 【降本增效】插件管理优化
  无jira任务,提交遗漏代码
  REPORT-89867 【降本增效】插件管理优化
  REPORT-89867 【降本增效】插件管理优化
  REPORT-89867 【降本增效】插件管理优化
  KERNEL-9267 feat: 平台提供的CBB组件目前过于冗杂,没法精简使用
bugfix/11.0
superman 2 years ago
parent
commit
8c39ff1f56
  1. 189
      designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java
  2. 3
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java
  3. 184
      designer-base/src/main/java/com/fr/design/extra/PluginBatchModifyDetailPane.java
  4. 69
      designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java
  5. 127
      designer-base/src/main/java/com/fr/design/extra/exe/callback/AbstractBatchModifyStatusCallback.java
  6. 43
      designer-base/src/main/java/com/fr/design/extra/exe/callback/BatchModifyStatusCallback.java
  7. 77
      designer-base/src/main/java/com/fr/design/extra/exe/callback/BatchUpdateOnlineCallback.java
  8. 9
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java
  9. 25
      designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsConfigManager.java
  10. 184
      designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java
  11. 406
      designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovePanel.java
  12. 13
      designer-base/src/main/java/com/fr/design/upm/UpmBridge.java
  13. 5
      designer-base/src/main/resources/com/fr/design/vcs/move_failed.svg
  14. 5
      designer-base/src/main/resources/com/fr/design/vcs/move_success.svg
  15. 3
      designer-base/src/main/resources/com/fr/design/vcs/vcs_move_icon.svg

189
designer-base/src/main/java/com/fr/design/actions/file/PreferencePane.java

@ -36,6 +36,7 @@ import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.mainframe.vcs.ui.VcsMovePanel;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.unit.UnitConvertUtil;
import com.fr.design.utils.gui.GUICoreUtils;
@ -54,9 +55,12 @@ import com.fr.stable.os.OperatingSystem;
import com.fr.third.apache.logging.log4j.Level;
import com.fr.transaction.Configurations;
import com.fr.transaction.Worker;
import com.fr.transaction.WorkerAdaptor;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.vcs.VcsConfig;
import com.fr.workspace.server.vcs.VcsOperator;
import com.fr.workspace.server.vcs.git.config.GcConfig;
import com.fr.workspace.server.vcs.v2.scheduler.VcsAutoCleanOperator;
import org.jetbrains.annotations.NotNull;
import javax.swing.BorderFactory;
@ -77,14 +81,7 @@ import javax.swing.UIManager;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Window;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
@ -149,6 +146,32 @@ public class PreferencePane extends BasicPane {
private static final Level[] LOG = {Level.FATAL, Level.ERROR, Level.WARN, Level.INFO, Level.DEBUG};
private static final int ONE_DAY_INT = 1;
private static final int ONE_WEEK_INT = 7;
private static final int ONE_MONTH_INT = 30;
private static final int THREE_MONTH_INT = 90;
private static final int SIX_MONTH_INT = 180;
private static final int ONE_DAY_INDEX = 0;
private static final int ONE_WEEK_INDEX = 1;
private static final int ONE_MONTH_INDEX = 2;
private static final int THREE_MONTH_INDEX = 3;
private static final int SIX_MONTH_INDEX = 4;
private static final String ONE_DAY = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_ONE_DAY");
private static final String ONE_WEEK = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_ONE_WEEK");
private static final String ONE_MONTH = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_ONE_MONTH");
private static final String THREE_MONTH = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_THREE_MONTH");
private static final String SIX_MONTH = Toolkit.i18nText("Fine-Design_Vcs_Auto_Clean_SIX_MONTH");
private static final String[] INTERVAL = {
ONE_DAY,
ONE_WEEK,
ONE_MONTH,
THREE_MONTH,
SIX_MONTH
};
private static final int DEFAULT_INDEX = 3;
private boolean languageChanged; // 是否修改了设计器语言设置
//设置是否支持undo
private UICheckBox supportUndoCheckBox;
@ -186,8 +209,20 @@ public class PreferencePane extends BasicPane {
private UICheckBox cloudAnalyticsDelayCheckBox;
private UICheckBox vcsEnableCheckBox;
private UICheckBox useVcsAutoSaveScheduleCheckBox;
private UICheckBox useVcsAutoCleanScheduleCheckBox;
private UIComboBox autoCleanIntervalComboBox;
private UIComboBox autoCleanRetainIntervalComboBox;
private IntegerEditor autoSaveIntervalEditor;
private UICheckBox saveCommitCheckBox;
private UICheckBox useIntervalCheckBox;
private VcsMovePanel movePanel;
private JPanel saveIntervalPane;
private JPanel autoCleanPane;
private UICheckBox startupPageEnabledCheckBox;
private IntegerEditor saveIntervalEditor;
private UICheckBox gcEnableCheckBox;
@ -227,13 +262,26 @@ public class PreferencePane extends BasicPane {
JPanel advancePane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
UIScrollPane adviceScrollPane = patchScroll(advancePane);
jtabPane.addTab(i18nText("Fine-Design_Basic_Advanced"), adviceScrollPane);
//初始化vcs总面板
JPanel vcsParentPane = new JPanel();
CardLayout cardLayout = new CardLayout();
vcsParentPane.setLayout(cardLayout);
//vcs配置面板
JPanel vcsPane = new JPanel(new BorderLayout());
//添加滚动条
UIScrollPane vcsScrollPane = patchScroll(vcsPane);
//配置面板作为vcs总面板的一张卡片
vcsParentPane.add(vcsScrollPane, VcsMovePanel.SETTING);
jtabPane.addTab(i18nText("Fine-Design_Vcs_Title"), vcsParentPane);
contentPane.add(jtabPane, BorderLayout.NORTH);
createFunctionPane(generalPane);
createEditPane(generalPane);
createColorSettingPane(generalPane);
createVcsSettingPane(generalPane);
// vcsPane
createVcsSettingPane(vcsPane, vcsParentPane, cardLayout);
// ConfPane
JPanel confLocationPane = FRGUIPaneFactory.createX_AXISBoxInnerContainer_S_Pane();
@ -345,21 +393,31 @@ public class PreferencePane extends BasicPane {
return generalPanelWithScroll;
}
private void createVcsSettingPane(JPanel generalPane) {
JPanel vcsPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Title"));
generalPane.add(vcsPane);
private void createVcsSettingPane(JPanel generalPane,JPanel parentPane, CardLayout cardLayout) {
//迁移面板
movePanel = createMovePane(cardLayout, parentPane);
generalPane.add(movePanel, BorderLayout.NORTH);
JPanel savePane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Save_Setting"));
JPanel vcsPane = FRGUIPaneFactory.createTopVerticalTitledBorderPane(i18nText("Fine-Design_Vcs_Clean_Setting"));
JPanel containPane = new JPanel(new GridLayout(10,1,0,8));
containPane.add(savePane);
containPane.add(vcsPane);
generalPane.add(containPane, BorderLayout.CENTER);
remindVcsLabel = new UILabel(i18nText("Fine-Design_Vcs_Remind"));
remindVcsLabel.setVisible(!VcsHelper.getInstance().needInit());
vcsEnableCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_SaveAuto"));
saveIntervalPane = createSaveIntervalPane();
saveCommitCheckBox = new UICheckBox(i18nText("Fine-Design_Vcs_No_Delete"));
saveIntervalEditor = new IntegerEditor(60);
useIntervalCheckBox = new UICheckBox();
savePane.add(vcsEnableCheckBox);
savePane.add(saveIntervalPane);
//gc面板
JPanel gcControlPane = createGcControlPane();
JPanel enableVcsPanel = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
enableVcsPanel.add(vcsEnableCheckBox);
enableVcsPanel.add(remindVcsLabel);
JPanel intervalPanel = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
final UILabel everyLabel = new UILabel(i18nText("Fine-Design_Vcs_Every"));
@ -368,6 +426,7 @@ public class PreferencePane extends BasicPane {
intervalPanel.add(everyLabel);
intervalPanel.add(saveIntervalEditor);
intervalPanel.add(delayLabel);
autoCleanPane = createAutoCleanPane();
vcsEnableCheckBox.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
@ -390,8 +449,57 @@ public class PreferencePane extends BasicPane {
vcsPane.add(enableVcsPanel);
vcsPane.add(intervalPanel);
vcsPane.add(saveCommitCheckBox);
vcsPane.add(autoCleanPane);
saveIntervalPane.setVisible(!VcsHelper.getInstance().isLegacyMode());
autoCleanPane.setVisible(!VcsHelper.getInstance().isLegacyMode());
if (VcsHelper.getInstance().isLegacyMode()) {
// 老版本时才显示gc选项
vcsPane.add(gcControlPane);
}
}
private VcsMovePanel createMovePane(CardLayout cardLayout, JPanel parentPane) {
return new VcsMovePanel(cardLayout, parentPane, new VcsMovePanel.MoveCallBack(){
@Override
public void doCallBack(boolean visible) {
saveIntervalPane.setVisible(visible);
autoCleanPane.setVisible(visible);
}
});
};
private JPanel createAutoCleanPane() {
JPanel autoCleanPane = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
useVcsAutoCleanScheduleCheckBox = new UICheckBox();
autoCleanIntervalComboBox = new UIComboBox(INTERVAL);
autoCleanIntervalComboBox.setSelectedIndex(DEFAULT_INDEX);
autoCleanRetainIntervalComboBox = new UIComboBox(INTERVAL);
autoCleanRetainIntervalComboBox.setSelectedIndex(DEFAULT_INDEX);
autoCleanPane.add(useVcsAutoCleanScheduleCheckBox);
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Every")));
autoCleanPane.add(autoCleanIntervalComboBox);
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Content")));
autoCleanPane.add(autoCleanRetainIntervalComboBox);
autoCleanPane.add(new UILabel(i18nText("Fine-Design_Vcs_Auto_Clean_Last")));
useVcsAutoCleanScheduleCheckBox.setEnabled(!VcsHelper.getInstance().isLegacyMode());
autoCleanPane.setVisible(false);
return autoCleanPane;
}
private JPanel createSaveIntervalPane() {
JPanel saveIntervalPane = new JPanel(FRGUIPaneFactory.createLeftZeroLayout());
useVcsAutoSaveScheduleCheckBox = new UICheckBox();
autoSaveIntervalEditor = new IntegerEditor(60);
saveIntervalPane.add(useVcsAutoSaveScheduleCheckBox);
saveIntervalPane.add(new UILabel(i18nText("Fine-Design_Vcs_Every")));
saveIntervalPane.add(autoSaveIntervalEditor);
saveIntervalPane.add(new UILabel(i18nText("Fine-Design_Vcs_Save_Delay")));
useVcsAutoSaveScheduleCheckBox.setEnabled(!VcsHelper.getInstance().isLegacyMode());
saveIntervalPane.setVisible(false);
return saveIntervalPane;
}
/**
* 模创建板版本gc 配置操作面板
@ -796,6 +904,10 @@ public class PreferencePane extends BasicPane {
gcEnableCheckBox.setSelected(GcConfig.getInstance().isGcEnable());
gcButton.setEnabled(gcEnableCheckBox.isSelected());
useVcsAutoSaveScheduleCheckBox.setSelected(vcsConfigManager.isUseAutoSave());
useVcsAutoCleanScheduleCheckBox.setSelected(VcsConfig.getInstance().isUseV2AutoClean());
autoSaveIntervalEditor.setValue(vcsConfigManager.getAutoSaveInterval());
gridLineColorTBButton.setColor(designerEnvManager.getGridLineColor());
paginationLineColorTBButton.setColor(designerEnvManager.getPaginationLineColor());
@ -875,6 +987,21 @@ public class PreferencePane extends BasicPane {
}
}
private int getDay(int dateIndex) {
switch (dateIndex) {
case ONE_DAY_INDEX:
return ONE_DAY_INT;
case ONE_WEEK_INDEX:
return ONE_WEEK_INT;
case ONE_MONTH_INDEX:
return ONE_MONTH_INT;
case SIX_MONTH_INDEX:
return SIX_MONTH_INT;
default:
return THREE_MONTH_INT;
}
}
/**
* The method of update.
*/
@ -920,6 +1047,17 @@ public class PreferencePane extends BasicPane {
vcsConfigManager.setVcsEnable(this.vcsEnableCheckBox.isSelected());
vcsConfigManager.setSaveCommit(this.saveCommitCheckBox.isSelected());
vcsConfigManager.setUseInterval(this.useIntervalCheckBox.isSelected());
vcsConfigManager.setUseAutoSave(this.useVcsAutoSaveScheduleCheckBox.isSelected());
vcsConfigManager.setAutoSaveInterval(this.autoSaveIntervalEditor.getValue());
Configurations.update(new WorkerAdaptor(VcsConfig.class) {
@Override
public void run() {
VcsConfig.getInstance().setUseV2AutoClean(useVcsAutoCleanScheduleCheckBox.isSelected());
VcsConfig.getInstance().setV2CleanInterval(getDay(autoCleanIntervalComboBox.getSelectedIndex()));
VcsConfig.getInstance().setV2RetainInterval(getDay(autoCleanRetainIntervalComboBox.getSelectedIndex()));
}
});
dealWithSchedule();
designerEnvManager.setStartupPageEnabled(this.startupPageEnabledCheckBox.isSelected());
Configurations.update(new Worker() {
@Override
@ -994,6 +1132,31 @@ public class PreferencePane extends BasicPane {
}
private void dealWithSchedule() {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
boolean v2FunctionSupport = VcsHelper.getInstance().checkV2FunctionSupport();
if (v2FunctionSupport) {
//如果支持V2
if (useVcsAutoSaveScheduleCheckBox.isSelected()) {
FineLoggerFactory.getLogger().info("[VcsV2] start auto save!");
VcsHelper.getInstance().startAutoSave(autoSaveIntervalEditor.getValue());
} else {
VcsHelper.getInstance().stopAutoSave();
}
if (useVcsAutoCleanScheduleCheckBox.isSelected()) {
FineLoggerFactory.getLogger().info("[VcsV2] start auto clean!");
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).addOrUpdateVcsAutoCleanJob(getDay(autoCleanIntervalComboBox.getSelectedIndex()));
} else {
WorkContext.getCurrent().get(VcsAutoCleanOperator.class).stopVcsAutoCleanJob();
}
}
return null;
}
}.execute();
}
// 如果语言设置改变了,则显示重启对话框
public void showRestartDialog() {
if (!languageChanged) {

3
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java

@ -59,7 +59,8 @@ public class ProcedureDataPane extends AbstractTableDataPane<StoreProcedure> imp
"com.microsoft.sqlserver.jdbc.SQLServerDriver",
"com.ibm.db2.jcc.DB2Driver",
"com.mysql.jdbc.Driver",
"org.gjt.mm.mysql.Driver"
"org.gjt.mm.mysql.Driver",
"dm.jdbc.driver.DmDriver"
}; // 需要隐藏面板的数据库的驱动
private static final String PREVIEW_BUTTON = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview");
private ConnectionTableProcedurePane connectionTableProcedurePane;

184
designer-base/src/main/java/com/fr/design/extra/PluginBatchModifyDetailPane.java

@ -0,0 +1,184 @@
package com.fr.design.extra;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* 插件批量处理弹窗面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/5/19
*/
public class PluginBatchModifyDetailPane {
private UILabel message = new UILabel();
private UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK"));
private UILabel uiLabel = new UILabel();
private UILabel directUiLabel = new UILabel();
private UILabel detailLabel = new UILabel();
private JPanel upPane;
private JPanel midPane;
private JPanel downPane;
private JPanel hiddenPanel;
private JTextArea jta;
private JDialog dialog;
/**
* 弹窗面板默认大小
*/
public static final Dimension DEFAULT = new Dimension(380, 150);
/**
* 弹窗面板展开大小
*/
public static final Dimension DEFAULT_PRO = new Dimension(380, 270);
public PluginBatchModifyDetailPane(Dialog parent) {
init(parent);
}
private void init(Dialog parent) {
message.setBorder(BorderFactory.createEmptyBorder(8, 5, 0, 0));
dialog = new JDialog(parent, Toolkit.i18nText("Fine-Design_Basic_Plugin_Manager"), true);
dialog.setSize(DEFAULT);
JPanel jp = new JPanel();
initUpPane();
initDownPane();
initMidPane();
initHiddenPanel();
initListener();
jp.setLayout(new BoxLayout(jp, BoxLayout.Y_AXIS));
jp.add(upPane);
jp.add(midPane);
jp.add(hiddenPanel);
jp.add(downPane);
hiddenPanel.setVisible(false);
dialog.add(jp);
dialog.setResizable(false);
dialog.setLocationRelativeTo(SwingUtilities.getWindowAncestor(parent));
}
private void initDownPane() {
downPane = new JPanel();
downPane.setLayout(new FlowLayout(FlowLayout.RIGHT, 15, 9));
downPane.add(cancelButton);
}
private void initUpPane() {
upPane = new JPanel();
uiLabel = new UILabel(UIManager.getIcon("OptionPane.errorIcon"));
upPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 10));
upPane.add(uiLabel);
upPane.add(message);
}
private void initMidPane() {
midPane = new JPanel();
midPane.add(directUiLabel);
midPane.add(detailLabel);
midPane.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 0));
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail"));
detailLabel.setForeground(Color.BLUE);
detailLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right"));
}
private void initHiddenPanel() {
hiddenPanel = new JPanel();
hiddenPanel.setLayout(new BorderLayout(2, 0));
hiddenPanel.add(new JPanel(), BorderLayout.WEST);
hiddenPanel.add(new JPanel(), BorderLayout.EAST);
JPanel borderPanel = new JPanel();
borderPanel.setLayout(new BorderLayout());
jta = new JTextArea();
JScrollPane jsp = new JScrollPane(jta);
jsp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jsp.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jta.setEditable(false);
borderPanel.add(jsp, BorderLayout.CENTER);
hiddenPanel.add(borderPanel);
}
/**
* 补充更详细的报错信息
*
* @param message 信息
*/
public void updateDetailArea(String message) {
jta.append(message + "\n");
}
private void initListener() {
detailLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (hiddenPanel.isVisible()) {
hiddenPanel.setVisible(false);
dialog.setSize(DEFAULT);
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail"));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.right"));
} else {
dialog.setSize(DEFAULT_PRO);
hiddenPanel.setVisible(true);
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Hide_Detail"));
directUiLabel.setIcon(UIManager.getIcon("OptionPane.narrow.down"));
}
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
hiddenPanel.removeAll();
dialog.dispose();
}
});
}
/**
* 更新标题
* @param title 标题
*/
public void updateTitle(String title) {
dialog.setTitle(title);
}
/**
* 更新展示信息
*
* @param failedCount 处理失败个数
* @param successCount 处理成功个数
*/
public void updateMessage(int failedCount, int successCount) {
message.setText(Toolkit.i18nText("Fine-Design_Basic_Plugin_Batch_Modify_Info", failedCount, successCount));
}
/**
* 显示面板
*/
public void show() {
dialog.setVisible(true);
}
}

69
designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java

@ -3,6 +3,8 @@ package com.fr.design.extra;
import com.fr.design.DesignerEnvManager;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.extra.exe.callback.BatchModifyStatusCallback;
import com.fr.design.extra.exe.callback.BatchUpdateOnlineCallback;
import com.fr.design.extra.exe.callback.InstallFromDiskCallback;
import com.fr.design.extra.exe.callback.InstallOnlineCallback;
import com.fr.design.extra.exe.callback.ModifyStatusCallback;
@ -28,11 +30,13 @@ import com.fr.plugin.view.PluginView;
import com.fr.plugin.xml.PluginElementName;
import com.fr.plugin.xml.PluginXmlElement;
import com.fr.stable.StringUtils;
import com.teamdev.jxbrowser.chromium.JSArray;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
import java.io.File;
import java.net.HttpURLConnection;
import java.util.ArrayList;
import java.util.List;
@ -65,12 +69,14 @@ public class PluginOperateUtils {
public static void updatePluginOnline(List<PluginMarker> pluginMarkerList, JSCallback jsCallback) {
for (int i = 0; i < pluginMarkerList.size(); i++) {
updatePluginOnline(pluginMarkerList.get(i), jsCallback);
int size = pluginMarkerList.size();
BatchUpdateOnlineCallback batchUpdateOnlineCallback = new BatchUpdateOnlineCallback(jsCallback, size);
for (int i = 0; i < size; i++) {
updatePluginOnline(pluginMarkerList.get(i), jsCallback, batchUpdateOnlineCallback);
}
}
public static void updatePluginOnline(PluginMarker pluginMarker, JSCallback jsCallback) {
private static void updatePluginOnline(PluginMarker pluginMarker, JSCallback jsCallback, BatchUpdateOnlineCallback batchUpdateOnlineCallback) {
try {
JSONObject latestPluginInfo = PluginUtils.getLatestPluginInfo(pluginMarker.getPluginID());
String latestPluginVersion = latestPluginInfo.getString("version");
@ -79,11 +85,25 @@ public class PluginOperateUtils {
//当前已经安装的相同ID插件marker
PluginMarker currentMarker = PluginMarkerAdapter.create(PluginUtils.getInstalledPluginMarkerByID(pluginMarker.getPluginID()), pluginName);
PluginTask pluginTask = PluginTask.updateTask(currentMarker, toPluginMarker);
if (!batchUpdateOnlineCallback.equals(BatchUpdateOnlineCallback.NONE)) {
batchUpdateOnlineCallback.createInnerPreTaskCallback(pluginTask, jsCallback);
PluginControllerHelper.updateOnline(currentMarker, toPluginMarker, batchUpdateOnlineCallback.getInnerPreTaskCallback(), PluginExtraInfo.newBuilder().username(DesignerEnvManager.getEnvManager().getDesignerLoginUsername()).build());
} else {
PluginControllerHelper.updateOnline(currentMarker, toPluginMarker, new UpdateOnlineCallback(pluginTask, jsCallback), PluginExtraInfo.newBuilder().username(DesignerEnvManager.getEnvManager().getDesignerLoginUsername()).build());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
/**
* 更新插件
*
* @param pluginMarker 插件marker
* @param jsCallback 回调
*/
public static void updatePluginOnline(PluginMarker pluginMarker, JSCallback jsCallback) {
updatePluginOnline(pluginMarker, jsCallback, BatchUpdateOnlineCallback.NONE);
}
@ -92,15 +112,37 @@ public class PluginOperateUtils {
}
public static void setPluginActive(String pluginInfo, JSCallback jsCallback) {
/**
* 批量启用或禁用插件
*
* @param pluginIDs 要处理的插件信息
* @param jsCallback 回调函数
*/
public static void setPluginActive(JSArray pluginIDs, JSCallback jsCallback) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
int len = pluginIDs.length();
BatchModifyStatusCallback modifyStatusCallback = new BatchModifyStatusCallback(jsCallback, len);
for (int i = 0; i < len; i++) {
String pluginInfo = pluginIDs.get(i).asString().getValue();
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
dealWithPluginActive(pluginMarker, modifyStatusCallback);
}
}
});
}
private static void dealWithPluginActive(PluginMarker pluginMarker, BatchModifyStatusCallback modifyStatusCallback) {
PluginContext plugin = PluginManager.getContext(pluginMarker);
boolean isRunning = plugin.isRunning();
PluginTaskCallback modifyStatusCallback = new ModifyStatusCallback(isRunning, jsCallback);
boolean running = plugin.isRunning();
modifyStatusCallback.updateActiveStatus(running);
changePluginActive(running, pluginMarker, modifyStatusCallback, plugin);
}
private static void changePluginActive(boolean isRunning, PluginMarker pluginMarker, PluginTaskCallback modifyStatusCallback, PluginContext plugin) {
if (isRunning) {
PluginXmlElement forbidReminder = plugin.getXml().getElement(PluginElementName.ForbidReminder);
if (forbidReminder != null && forbidReminder.getContent() != null) {
@ -123,6 +165,18 @@ public class PluginOperateUtils {
PluginManager.getController().enablePersistently(pluginMarker, modifyStatusCallback);
}
}
public static void setPluginActive(String pluginInfo, JSCallback jsCallback) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo);
PluginContext plugin = PluginManager.getContext(pluginMarker);
boolean isRunning = plugin.isRunning();
PluginTaskCallback modifyStatusCallback = new ModifyStatusCallback(isRunning, jsCallback);
changePluginActive(isRunning, pluginMarker, modifyStatusCallback, plugin);
}
});
}
@ -255,8 +309,7 @@ public class PluginOperateUtils {
private static String getPluginName(PluginContext pluginContext, PluginMarker pluginMarker) {
if (pluginContext != null) {
return pluginContext.getName();
}
else if (pluginMarker instanceof PluginMarkerAdapter) {
} else if (pluginMarker instanceof PluginMarkerAdapter) {
return ((PluginMarkerAdapter) pluginMarker).getPluginName();
}
return pluginMarker == null ? StringUtils.EMPTY : pluginMarker.getPluginID();

127
designer-base/src/main/java/com/fr/design/extra/exe/callback/AbstractBatchModifyStatusCallback.java

@ -0,0 +1,127 @@
package com.fr.design.extra.exe.callback;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.extra.PluginBatchModifyDetailPane;
import com.fr.design.extra.PluginOperateUtils;
import com.fr.design.i18n.Toolkit;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker;
import com.fr.plugin.manage.control.PluginTask;
import com.fr.plugin.manage.control.PluginTaskResult;
import com.fr.plugin.manage.control.ProgressCallback;
import com.fr.stable.StringUtils;
import javax.swing.JOptionPane;
import java.util.HashMap;
import java.util.Map;
/**
* 带进度条的批量处理的callback
* <li> content与title是处理完成后弹出的面板的内容与标题子类需要在done之前设定好对应的信息
* <li> 进度条是以 当前完成任务数/总任务数 来计算的
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/6/6
*/
public abstract class AbstractBatchModifyStatusCallback implements ProgressCallback {
protected JSCallback jsCallback;
protected Map<String, String> resultMap = new HashMap<>();
protected String content = StringUtils.EMPTY;
protected String title = StringUtils.EMPTY;
public int pluginCount = 0;
public int allPluginCount = 0;
public int successCount = 0;
public int failedCount = 0;
public static final int HUNDRED_PERCENT = 100;
public static final String PERCENT = "%";
public static final String DEFAULT = "default";
public AbstractBatchModifyStatusCallback() {
}
public AbstractBatchModifyStatusCallback(JSCallback jsCallback, int size) {
this.jsCallback = jsCallback;
this.allPluginCount = size;
}
@Override
public void done(PluginTaskResult result) {
String pluginInfo = PluginOperateUtils.getSuccessInfo(result);
if (result.isSuccess()) {
successCount++;
String modifyMessage = updateMessage(pluginInfo);
FineLoggerFactory.getLogger().info(modifyMessage);
} else {
failedCount++;
resultMap.put(getPluginName(result), pluginInfo);
}
updateProgressAndCheckCompletion();
}
/**
* 获取插件名
*
* @param result 任务结果
* @return 插件名
*/
public String getPluginName(PluginTaskResult result) {
PluginTask pluginTask = result.getCurrentTask();
if (pluginTask != null) {
PluginMarker pluginMarker = pluginTask.getToMarker();
if (pluginMarker != null) {
return pluginMarker.getPluginID();
}
}
return DEFAULT;
}
/**
* 更新当前Map状态,进度条,如果全部都更新完了就回调
*/
public void updateProgressAndCheckCompletion() {
pluginCount++;
updateProgress(StringUtils.EMPTY, (double) pluginCount / allPluginCount);
if (pluginCount == allPluginCount) {
jsCallback.execute("success");
showMessageDialog();
}
}
/**
* 展示信息面板
*/
public void showMessageDialog() {
if (failedCount == 0) {
FineJOptionPane.showMessageDialog(DesignerPluginContext.getPluginDialog(),
content,
title,
JOptionPane.INFORMATION_MESSAGE);
} else {
PluginBatchModifyDetailPane detailPane = new PluginBatchModifyDetailPane(DesignerPluginContext.getPluginDialog());
for (String key : resultMap.keySet()) {
detailPane.updateDetailArea(resultMap.get(key));
}
detailPane.updateMessage(failedCount, successCount);
detailPane.updateTitle(title);
detailPane.show();
}
}
@Override
public void updateProgress(String description, double progress) {
jsCallback.execute(progress * HUNDRED_PERCENT + PERCENT);
}
/**
* 更新处理成功返回的日志信息
*
* @return 返回的日志信息
*/
abstract public String updateMessage(String pluginInfo);
}

43
designer-base/src/main/java/com/fr/design/extra/exe/callback/BatchModifyStatusCallback.java

@ -0,0 +1,43 @@
package com.fr.design.extra.exe.callback;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.i18n.Toolkit;
/**
* 批量启用/禁用插件的Callback
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/5/18
*/
public class BatchModifyStatusCallback extends AbstractBatchModifyStatusCallback {
private boolean active;
private boolean operatorFlag = false;
public BatchModifyStatusCallback(JSCallback jsCallback, int size) {
super(jsCallback, size);
}
@Override
public String updateMessage(String pluginInfo) {
return active ? pluginInfo + Toolkit.i18nText("Fine-Design_Basic_Plugin_Has_Been_Disabled_Duplicate") : pluginInfo + Toolkit.i18nText("Fine-Design_Plugin_Has_Been_Actived_Duplicate");
}
/**
* 更新启用/禁用信息
*
* @param active
*/
public void updateActiveStatus(boolean active) {
if (!operatorFlag) {
this.active = active;
this.operatorFlag = true;
this.title = active ? Toolkit.i18nText("Fine-Design_Basic_Plugin_Stop") : Toolkit.i18nText("Fine-Design_Basic_Plugin_Start");
this.content = active ? Toolkit.i18nText("Fine-Design_Basic_Plugin_Batch_Modify_Stop_Success") : Toolkit.i18nText("Fine-Design_Basic_Plugin_Batch_Modify_Start_Success");
}
}
}

77
designer-base/src/main/java/com/fr/design/extra/exe/callback/BatchUpdateOnlineCallback.java

@ -0,0 +1,77 @@
package com.fr.design.extra.exe.callback;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.i18n.Toolkit;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.manage.control.PluginTask;
import com.fr.plugin.manage.control.PluginTaskResult;
/**
* 批量更新的callback
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/6/6
*/
public class BatchUpdateOnlineCallback extends AbstractBatchModifyStatusCallback{
public static final BatchUpdateOnlineCallback NONE = new BatchUpdateOnlineCallback();
/**
* 可自动处理前置任务的callback用来处理实际更新逻辑
*/
private InnerUpdateCallback innerPreTaskCallback;
public BatchUpdateOnlineCallback() {
}
public BatchUpdateOnlineCallback(JSCallback jsCallback, int size) {
super(jsCallback, size);
this.title = Toolkit.i18nText("Fine-Design_Basic_Plugin_Update");
this.content = Toolkit.i18nText("Fine-Design_Basic_Plugin_Update_Success");
}
/**
* 更新任务
*
* @param pluginTask 任务
* @param jsCallback callback
*/
public void createInnerPreTaskCallback(PluginTask pluginTask, JSCallback jsCallback) {
innerPreTaskCallback = new InnerUpdateCallback(pluginTask, jsCallback);
}
public InnerUpdateCallback getInnerPreTaskCallback() {
return innerPreTaskCallback;
}
@Override
public String updateMessage(String pluginInfo) {
return pluginInfo + Toolkit.i18nText("Fine-Design_Basic_Plugin_Update_Success");
}
/**
* 可自动处理前置任务的callback用来处理实际更新逻辑
*/
public class InnerUpdateCallback extends UpdateOnlineCallback {
public InnerUpdateCallback(PluginTask pluginTask, JSCallback jsCallback) {
super(pluginTask, jsCallback);
}
@Override
public void updateProgress(String description, double aProgress) {
//不进行处理
}
@Override
public void allDone(PluginTaskResult result) {
BatchUpdateOnlineCallback.this.done(result);
}
}
}

9
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrameFileDealerPane.java

@ -325,7 +325,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
if (VcsHelper.getInstance().needInit()) {
vcsAction = new VcsAction();
if (!WorkContext.getCurrent().isCluster()) {
if (!isLegacyOnCluster()) {
vcsAction.setName(Toolkit.i18nText("Fine-Design_Vcs_Title"));
} else {
vcsAction.setName(Toolkit.i18nText("Fine-Design_Vcs_NotSupportRemote"));
@ -509,7 +509,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
private void fireVcsActionChange(boolean enable) {
if (!DesignerEnvManager.getEnvManager().getVcsConfigManager().isVcsEnable()
|| VcsHelper.getInstance().isUnSelectedTemplate()
|| WorkContext.getCurrent().isCluster()) {
|| isLegacyOnCluster()) {
setEnabled(false);
return;
}
@ -810,6 +810,11 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt
}
}
private boolean isLegacyOnCluster() {
// 老模式且为集群,用于代替之前的只判断集群逻辑
return WorkContext.getCurrent().isCluster() && VcsHelper.getInstance().isLegacyMode();
}
private String doCheck (String userInput, String suffix) {
String errorMsg = StringUtils.EMPTY;
if (selectedOperation.duplicated(userInput, suffix, true)) {

25
designer-base/src/main/java/com/fr/design/mainframe/vcs/VcsConfigManager.java

@ -16,6 +16,10 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
private boolean useInterval = true;
private int saveInterval = 60;
private boolean useAutoSave = false;
private int autoSaveInterval = 15;
public static VcsConfigManager getInstance() {
return instance;
}
@ -48,6 +52,23 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
return saveInterval;
}
public int getAutoSaveInterval() {
return autoSaveInterval;
}
public void setAutoSaveInterval(int autoSaveInterval) {
this.autoSaveInterval = autoSaveInterval;
}
public boolean isUseAutoSave() {
return useAutoSave;
}
public void setUseAutoSave(boolean useAutoSave) {
this.useAutoSave = useAutoSave;
}
public void setSaveInterval(int saveInterval) {
this.saveInterval = saveInterval;
}
@ -59,6 +80,8 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
this.setSaveInterval(reader.getAttrAsInt("saveInterval", 60));
this.setUseInterval(reader.getAttrAsBoolean("useInterval", true));
this.setVcsEnable(reader.getAttrAsBoolean("vcsEnable", true));
this.setAutoSaveInterval(reader.getAttrAsInt("autoSaveInterval", 15));
this.setUseAutoSave(reader.getAttrAsBoolean("useAutoSave", false));
}
}
@ -69,6 +92,8 @@ public class VcsConfigManager implements XMLReadable, XMLWriter {
writer.attr("saveInterval", this.getSaveInterval());
writer.attr("useInterval", this.isUseInterval());
writer.attr("vcsEnable", this.isVcsEnable());
writer.attr("autoSaveInterval", this.getAutoSaveInterval());
writer.attr("useAutoSave", this.isUseAutoSave());
writer.end();
}
}

184
designer-base/src/main/java/com/fr/design/mainframe/vcs/common/VcsHelper.java

@ -2,6 +2,7 @@ package com.fr.design.mainframe.vcs.common;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.config.ConfigEvent;
import com.fr.design.DesignerEnvManager;
import com.fr.design.file.HistoryTemplateListCache;
import com.fr.design.file.TemplateTreePane;
@ -12,6 +13,9 @@ import com.fr.design.mainframe.JTemplate;
import com.fr.design.mainframe.JTemplateActionListener;
import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.mainframe.vcs.ui.FileVersionTable;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.ListenerAdaptor;
import com.fr.general.IOUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginContext;
@ -25,11 +29,14 @@ import com.fr.workspace.server.vcs.filesystem.VcsFileSystem;
import com.fr.workspace.server.vcs.git.config.GcConfig;
import javax.swing.Icon;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import java.awt.Color;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* Created by XiaXiang on 2019/4/17.
@ -55,10 +62,65 @@ public class VcsHelper implements JTemplateActionListener {
private final static String SERVICE_NAME_MOVE = "moveVcs";
private static final VcsHelper INSTANCE = new VcsHelper();
private static ScheduledExecutorService saveSchedule;
private volatile boolean legacyMode;
public static VcsHelper getInstance() {
return INSTANCE;
}
private VcsHelper() {
VcsOperator op = WorkContext.getCurrent().get(VcsOperator.class);
// 开了设计器启动页面时一开始取不到VcsOperator,通过下面的切换环境事件再取,这边判断下
if (op != null) {
legacyMode = op.isLegacyMode();
}
EventDispatcher.listen(ConfigEvent.READY, new ListenerAdaptor() {
@Override
protected void on(Event event) {
try {
legacyMode = WorkContext.getCurrent().get(VcsOperator.class).isLegacyMode();
FineLoggerFactory.getLogger().info("[VcsHelper] legacyMode:{}", legacyMode);
} catch (Exception e) {
//保险起见走老逻辑
legacyMode = true;
FineLoggerFactory.getLogger().error("[VcsHelper] get legacy failed", e.getMessage());
}
}
});
}
/**
* 开始自动保存任务
*
* @param interval 时间间隔
*/
public void startAutoSave(int interval) {
stopAutoSave();
saveSchedule = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("VcsAutoSaveSchedule"));
saveSchedule.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
FineLoggerFactory.getLogger().info("[VcsV2] start to run auto save schedule");
JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate();
if (DesignerEnvManager.getEnvManager().getVcsConfigManager().isVcsEnable() && JTemplate.isValid(template)) {
fireAutoSaveVcs(template);
}
}
}, interval, interval, TimeUnit.MINUTES);
}
/**
* 停止任务
*/
public void stopAutoSave() {
if (saveSchedule != null && !saveSchedule.isShutdown()) {
saveSchedule.shutdown();
}
}
private int containsFolderCounts() {
TemplateFileTree fileTree = TemplateTreePane.getInstance().getTemplateFileTree();
if (fileTree.getSelectionPaths() == null) {
@ -133,24 +195,21 @@ public class VcsHelper implements JTemplateActionListener {
fireVcs.execute(new Runnable() {
@Override
public void run() {
String fileName = getEditingFilename();
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
VcsEntity entity = operator.getFileVersionByIndex(fileName, 0);
boolean replace = needDeleteVersion(entity);
int latestFileVersion = 0;
if (entity != null) {
latestFileVersion = entity.getVersion();
}
if (jt.getEditingFILE() instanceof VcsCacheFileNodeFile) {
operator.saveVersionFromCache(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1);
operator.saveVersionFromCache(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1, replace);
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
FileVersionTable.getInstance().updateModel(1, WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst(VCS_FILE_SLASH, StringUtils.EMPTY)));
List<VcsEntity> updatedList = WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst(VCS_FILE_SLASH, StringUtils.EMPTY));
SwingUtilities.invokeLater(() -> FileVersionTable.getInstance().updateModel(1, updatedList));
} else {
operator.saveVersion(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1);
}
VcsEntity oldEntity = WorkContext.getCurrent().get(VcsOperator.class).getFileVersionByIndexAndUsername(fileName, getCurrentUsername(), 1);
if (needDeleteVersion(oldEntity)) {
operator.deleteVersion(oldEntity.getFilename(), oldEntity.getVersion());
operator.saveVersion(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1, replace);
}
if (GcConfig.getInstance().isGcEnable()) {
operator.gc();
@ -158,8 +217,10 @@ public class VcsHelper implements JTemplateActionListener {
}
});
if (!fireVcs.isShutdown()) {
fireVcs.shutdown();
}
}
/**
* 移动Vcs
@ -188,12 +249,85 @@ public class VcsHelper implements JTemplateActionListener {
moveVcs.shutdown();
}
/**
* 判断是否为老模式
* @return 是否为老模式
*/
public boolean isLegacyMode() {
return legacyMode;
}
/**
* 更新当前的legacyMode状态
* <li>目前用在迁移结束后更新模式为新模式</li>
*
*/
public void updateLegacyMode() {
this.legacyMode = !legacyMode;
}
@Override
public void templateOpened(JTemplate<?, ?> jt) {
try {
if (checkAutoSaveSupport()) {
startAutoSave(VcsConfigManager.getInstance().getAutoSaveInterval());
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
/**
* 响应版本管理自动保存
*
* <li>直接用template的file来保存的话相当于拿源文件来保存模板这样用户做的改动会丢失</li>
* <li>因此需要自己实现一下自动保存的逻辑将当前模板的数据导出,再拿这个Byte[]去做我们需要的保存处理</li>
* <li>保存后需要触发清理逻辑</li>
*
* @param jt 模板
*/
public void fireAutoSaveVcs(final JTemplate jt) {
String fileName = getEditingFilename();
VcsOperator operator = WorkContext.getCurrent().get(VcsOperator.class);
VcsEntity entity = operator.getFileVersionByIndex(fileName, 0);
boolean replace = needDeleteVersion(entity);
int latestFileVersion = 0;
if (entity != null) {
latestFileVersion = entity.getVersion();
}
if (JTemplate.isValid(jt)) {
doSave(jt, fileName, latestFileVersion, replace, operator);
}
}
private void doSave(JTemplate jt, String fileName, int latestFileVersion, boolean replace, VcsOperator operator) {
if (jt.getEditingFILE() instanceof VcsCacheFileNodeFile) {
operator.saveVersionFromCache(getCurrentUsername(), fileName, StringUtils.EMPTY, latestFileVersion + 1, replace);
String path = DesignerFrameFileDealerPane.getInstance().getSelectedOperation().getFilePath();
List<VcsEntity> updatedList = WorkContext.getCurrent().get(VcsOperator.class).getVersions(path.replaceFirst(VCS_FILE_SLASH, StringUtils.EMPTY));
SwingUtilities.invokeLater(() -> FileVersionTable.getInstance().updateModel(1, updatedList));
} else {
autoSave(jt, getCurrentUsername(), fileName, latestFileVersion + 1, replace, operator);
}
if (GcConfig.getInstance().isGcEnable()) {
operator.gc();
}
}
private void autoSave(JTemplate jt, String currentUsername, String fileName, int nowVersion, boolean replace, VcsOperator operator) {
try {
if (JTemplate.isValid(jt)) {
operator.autoSave(currentUsername, fileName, StringUtils.EMPTY, nowVersion, jt.exportData(), replace);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
/**
* 模板保存时 处理.
*
@ -210,6 +344,40 @@ public class VcsHelper implements JTemplateActionListener {
@Override
public void templateClosed(JTemplate<?, ?> jt) {
try {
if (checkAutoSaveSupport()) {
stopAutoSave();
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage());
}
}
/**
* 判断是否支持V2功能
*
* @return 支持返回true
*/
public boolean checkV2FunctionSupport() {
return !VcsHelper.getInstance().isLegacyMode() && (WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot());
}
/**
* 判断是否支持迁移功能
*
* @return 支持返回true
*/
public boolean checkMoveFunctionSupport() {
return VcsHelper.getInstance().isLegacyMode() && (WorkContext.getCurrent().isLocal() || WorkContext.getCurrent().isRoot());
}
/**
* 是否支持自动保存
*
* @return 支持返回true
*/
public boolean checkAutoSaveSupport() {
return VcsConfigManager.getInstance().isUseAutoSave() && !VcsHelper.getInstance().isLegacyMode();
}
}

406
designer-base/src/main/java/com/fr/design/mainframe/vcs/ui/VcsMovePanel.java

@ -0,0 +1,406 @@
package com.fr.design.mainframe.vcs.ui;
import com.fr.base.svg.IconUtils;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIRadioButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.iprogressbar.ModernUIProgressBarUI;
import com.fr.design.gui.ispinner.UISpinner;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.vcs.common.VcsHelper;
import com.fr.design.utils.DesignUtils;
import com.fr.design.widget.FRWidgetFactory;
import com.fr.general.FRFont;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.workspace.server.vcs.v2.move.VcsMoveService;
import com.fr.workspace.server.vcs.v2.move.VcsMoveStrategy;
import javax.swing.ButtonGroup;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import java.util.concurrent.ExecutionException;
/**
* 迁移面板
*
* @author Destiny.Lin
* @since 11.0
* Created on 2023/6/13
*/
public class VcsMovePanel extends BasicPane {
private static final FRFont FONT = DesignUtils
.getDefaultGUIFont()
.applySize(14)
.applyStyle(FRFont.BOLD);
private static final Color BACK_GROUND_COLOR = new Color(202,232,255);
//提示字体的颜色,直接模仿其他面板的写法
private static final Color TIP_COLOR = new Color(51, 51, 52, (int)Math.round(0.5 * 255));
private static final Color LABEL_COLOR = new Color(34,149,233);
private static final int MIN_VALUE = 1;
private static final int MAX_VALUE = 999;
private static final int STEP = 1;
private static final int DEFAULT_VALUE = 5;
public static final String SETTING = "SETTING";
public static final String PROCESS = "PROCESS";
public static final String SUCCESS = "SUCCESS";
public static final String FAILED = "FAILED";
public static boolean moving = false;
private UILabel vcsUpdateExistLabel;
private UILabel vcsUpdateFireLabel;
private BasicPane choosePane;
private CardLayout parentCard;
private JPanel parentPane;
private static final JProgressBar PROGRESS_BAR = new JProgressBar();
private JPanel progressPanel;
private UILabel tipLabel;
private UIButton successButton;
private UILabel iconLabel;
private UILabel successLabel;
private UILabel successTipLabel;
private UIButton failedButton;
private UILabel failedIconLabel;
private UILabel failedLabel;
private UILabel failedTipLabel;
//保留全部
private UIRadioButton moveAllButton;
//默认选项,保留部分
private UIRadioButton moveDefaultButton;
//全部放弃
private UIRadioButton moveNothingButton;
private UISpinner spinner;
private MoveCallBack callBack;
private JPanel updatePane;
private boolean visible = false;
public VcsMovePanel(CardLayout cardLayout, JPanel parentPane, MoveCallBack callBack) {
this.parentCard = cardLayout;
this.parentPane = parentPane;
this.callBack = callBack;
this.setLayout(new BorderLayout());
updatePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane();
updatePane.setBackground(BACK_GROUND_COLOR);
//初始化迁移的面板
initVcsLabel(updatePane);
//initVcsChoosePane
initVcsChoosePane();
//初始化listener
initListener();
this.add(updatePane);
checkVisible();
//如果已经在迁移
if (VcsMoveService.getInstance().isMoving()) {
initProcessPane();
VcsMovePanel.this.getParentCard().show(getParentPane(), PROCESS);
}
}
private void checkVisible() {
new SwingWorker<Boolean, Void>() {
@Override
protected Boolean doInBackground() throws Exception {
return VcsHelper.getInstance().checkMoveFunctionSupport();
}
@Override
protected void done() {
try {
boolean useMove = get();
VcsMovePanel.this.setVisible(useMove);
} catch (InterruptedException | ExecutionException e) {
throw new RuntimeException(e);
}
}
}.execute();
}
private void initProcessPane() {
JPanel processPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
PROGRESS_BAR.setStringPainted(true);
PROGRESS_BAR.setUI(new ModernUIProgressBarUI());
PROGRESS_BAR.setBorderPainted(false);
PROGRESS_BAR.setOpaque(false);
PROGRESS_BAR.setBorder(null);
PROGRESS_BAR.setSize(BasicDialog.MEDIUM);
body.add(PROGRESS_BAR);
body.add(new UILabel(StringUtils.BLANK));
tipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_While_Moving"));
tipLabel.setAlignmentX(CENTER_ALIGNMENT);
body.add(tipLabel);
processPane.add(body);
processPane.setLayout(FRGUIPaneFactory.createCenterLayout(body, 0.5f, 0.5f));
parentPane.add(processPane, PROCESS);
}
private void initVcsChoosePane() {
choosePane = new BasicPane() {
@Override
protected String title4PopupWindow() {
return Toolkit.i18nText("Fine-Design_Vcs_Deal_With_Entry");
}
};
VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP);
layout.setAlignLeft(true);
choosePane.setLayout(layout);
//初始化上方的文字板块
initTopDesc();
//初始化中间区域的单选框
initRadioButton();
//初始化下方的Tip描述
initTipDesc();
}
private void initTopDesc() {
UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_How_To_Deal_With_Entry"));
choosePane.add(label);
}
private void initTipDesc() {
UILabel descLabel = FRWidgetFactory.createLineWrapLabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Desc"));
descLabel.setForeground(TIP_COLOR);
choosePane.add(descLabel);
}
private void initRadioButton() {
//保留全部
moveAllButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Vcs_Move_All"));
//默认选项,保留部分
moveDefaultButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Default"));
//全部放弃
moveNothingButton = new UIRadioButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Nothing"));
// 将按钮"保留部分"设置为选中状态
moveDefaultButton.setSelected(true);
// 创建一个按钮组,添加三个按钮
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(moveAllButton);
buttonGroup.add(moveDefaultButton);
buttonGroup.add(moveNothingButton);
JPanel moveDefaultPanel = new JPanel();
JPanel moveAllPane = new JPanel();
JPanel moveNothingPane = new JPanel();
moveAllPane.add(moveAllButton);
moveDefaultPanel.add(moveDefaultButton);
moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Left")));
spinner = new UISpinner(MIN_VALUE, MAX_VALUE, STEP, DEFAULT_VALUE);
moveDefaultPanel.add(spinner);
moveDefaultPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Default_Text_Right")));
moveNothingPane.add(moveNothingButton);
choosePane.add(moveAllPane);
choosePane.add(moveDefaultPanel);
choosePane.add(moveNothingPane);
}
private void initVcsLabel(JPanel parent) {
vcsUpdateExistLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/vcs_move_icon.svg"));
vcsUpdateExistLabel.setText(Toolkit.i18nText("Fine-Design_Vcs_Can_Update"));
vcsUpdateFireLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Update"));
vcsUpdateFireLabel.setForeground(LABEL_COLOR);
vcsUpdateFireLabel.setCursor(new Cursor(Cursor.HAND_CURSOR));
parent.add(vcsUpdateExistLabel);
parent.add(vcsUpdateFireLabel);
}
private void initListener() {
vcsUpdateFireLabel.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
BasicDialog dlg = choosePane.showMediumWindow(SwingUtilities.getWindowAncestor(VcsMovePanel.this), new DialogActionAdapter() {
@Override
public void doOk() {
//进度条面板
initProcessPane();
VcsMovePanel.this.getParentCard().next(getParentPane());
VcsMoveStrategy strategy;
if (moveDefaultButton.isSelected()) {
strategy = VcsMoveStrategy.createNumStrategy((int) spinner.getValue());
} else if (moveNothingButton.isSelected()) {
strategy = VcsMoveStrategy.ALL_GIVE_UP;
} else {
strategy = VcsMoveStrategy.ALL_RETAIN;
}
new MoveWorker(strategy).execute();
}
});
dlg.setVisible(true);
}
});
}
private void initSuccessPane() {
JPanel successPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
successButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Success_Go"));
initSuccessButtonListener();
iconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/move_success.svg"));
successLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Success"));
successLabel.setFont(FONT);
successTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Success_Tip"));
initStatusPane(successTipLabel, iconLabel, successLabel, successButton, body, SUCCESS, successPane);
}
private void initSuccessButtonListener() {
successButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doAfterMove();
}
});
}
private void initFailedButtonListener() {
failedButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
doAfterMove();
}
});
}
private void doAfterMove() {
visible = !VcsHelper.getInstance().isLegacyMode();
updatePane.setVisible(!visible);
callBack.doCallBack(visible);
parentCard.show(parentPane, SETTING);
}
@Override
protected String title4PopupWindow() {
return StringUtils.EMPTY;
}
public CardLayout getParentCard() {
return parentCard;
}
public JPanel getParentPane() {
return parentPane;
}
private void initFailedPane() {
JPanel failedPane = new JPanel();
JPanel body = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
failedButton = new UIButton(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Go"));
initFailedButtonListener();
failedIconLabel = new UILabel(IconUtils.readIcon("/com/fr/design/vcs/move_failed.svg"));
failedLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed"));
failedLabel.setFont(FONT);
failedTipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Vcs_Move_Failed_Tip"));
initStatusPane(failedTipLabel, failedIconLabel, failedLabel, failedButton, body, FAILED, failedPane);
}
private void initStatusPane(UILabel tipLabel, UILabel iconLabel, UILabel label, UIButton button, JPanel body, String tag,JPanel statusPane) {
tipLabel.setForeground(TIP_COLOR);
body.add(iconLabel);
body.add(new UILabel(StringUtils.BLANK));
body.add(label);
body.add(new UILabel(StringUtils.BLANK));
body.add(tipLabel);
body.add(new UILabel(StringUtils.BLANK));
body.add(button);
statusPane.add(body);
statusPane.setLayout(FRGUIPaneFactory.createCenterLayout(body, 0.5f, 0.5f));
parentPane.add(statusPane, tag);
iconLabel.setAlignmentX(CENTER_ALIGNMENT);
label.setAlignmentX(CENTER_ALIGNMENT);
button.setAlignmentX(CENTER_ALIGNMENT);
tipLabel.setAlignmentX(CENTER_ALIGNMENT);
}
private class MoveWorker extends SwingWorker<Void, Integer> {
private VcsMoveStrategy strategy;
public MoveWorker(VcsMoveStrategy strategy) {
this.strategy = strategy;
}
@Override
protected Void doInBackground() throws Exception {
try {
//开始迁移
VcsMoveService.getInstance().startMove(new VcsMoveService.BaseMoveServiceWhileMoving() {
@Override
public void publishProgress() {
int num = VcsMoveService.getInstance().getCurrentMove();
publish(num);
}
@Override
public void prepare4Move() {
PROGRESS_BAR.setMaximum(VcsMoveService.getInstance().getTotal());
}
}, strategy);
} catch (Exception e) {
this.cancel(true);
VcsMoveService.getInstance().stopMoving();
initFailedPane();
VcsMovePanel.this.getParentCard().show(getParentPane(), FAILED);
FineLoggerFactory.getLogger().error("[VcsV2] Vcs move failed!");
}
return null;
}
@Override
protected void process(List<Integer> chunks) {
PROGRESS_BAR.setValue(chunks.get(chunks.size() - 1));
}
@Override
protected void done() {
VcsMoveService.getInstance().stopMoving();
initSuccessPane();
VcsMovePanel.this.getParentCard().show(getParentPane(), SUCCESS);
VcsHelper.getInstance().updateLegacyMode();
}
}
/**
* 迁移回调事件
*
*/
public static class MoveCallBack {
/**
* 处理回调
*/
public void doCallBack(boolean visible){}
}
}

13
designer-base/src/main/java/com/fr/design/upm/UpmBridge.java

@ -40,6 +40,7 @@ import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSArray;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
import com.teamdev.jxbrowser.chromium.JSValue;
import java.awt.Desktop;
import javax.swing.JFileChooser;
@ -291,6 +292,18 @@ public class UpmBridge {
PluginOperateUtils.setPluginActive(pluginID, jsCallback);
}
/**
* 批量修改选中的插件的活跃状态
*
* @param pluginIDs 要处理的插件ID
* @param callback 回调函数
*/
@JSBridge
public void setAllPluginActive(JSArray pluginIDs, final JSFunction callback) {
JSCallback jsCallback = new JSCallback(UpmBrowserExecutor.create(window, callback));
PluginOperateUtils.setPluginActive(pluginIDs, jsCallback);
}
/**
* 选择文件对话框
*

5
designer-base/src/main/resources/com/fr/design/vcs/move_failed.svg

@ -0,0 +1,5 @@
<svg width="64" height="65" viewBox="0 0 64 65" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M32 60.5C16.536 60.5 4 47.964 4 32.5C4 17.036 16.536 4.5 32 4.5C47.464 4.5 60 17.036 60 32.5C60 47.964 47.464 60.5 32 60.5Z" fill="#EB1D1F"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M44 24.1928L23.692 44.4995L20 40.8075L40.308 20.4995L44 24.1928Z" fill="white"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M40.308 44.5L20 24.1933L23.692 20.5L44 40.8067L40.308 44.5Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 549 B

5
designer-base/src/main/resources/com/fr/design/vcs/move_success.svg

@ -0,0 +1,5 @@
<svg width="58" height="59" viewBox="0 0 58 59" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M29 58.5C12.9837 58.5 0 45.5163 0 29.5C0 13.4837 12.9837 0.5 29 0.5C45.0163 0.5 58 13.4837 58 29.5C58 45.5163 45.0163 58.5 29 58.5Z" fill="#16C153"/>
<rect x="20.66" y="39.8213" width="32.1738" height="5.52381" transform="rotate(-45 20.66 39.8213)" fill="white"/>
<rect x="14.9535" y="26.7378" width="18.7954" height="5.52381" transform="rotate(45 14.9535 26.7378)" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 533 B

3
designer-base/src/main/resources/com/fr/design/vcs/vcs_move_icon.svg

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 8C15 4.13435 11.8656 1 8 1C4.13435 1 1 4.13435 1 8C1 11.8656 4.13435 15 8 15C11.8656 15 15 11.8656 15 8ZM7.43333 5.70798C7.27778 5.55242 7.2 5.36353 7.2 5.14131C7.2 4.91909 7.27778 4.7302 7.43333 4.57464C7.58889 4.41909 7.77778 4.34131 8 4.34131C8.22222 4.34131 8.41111 4.41909 8.56667 4.57464C8.72222 4.7302 8.8 4.91909 8.8 5.14131C8.8 5.36353 8.72222 5.55242 8.56667 5.70798C8.41111 5.86353 8.22222 5.94131 8 5.94131C7.77778 5.94131 7.58889 5.86353 7.43333 5.70798ZM8 11.7787C7.6134 11.7787 7.3 11.4653 7.3 11.0787V7.47868C7.3 7.09208 7.6134 6.77868 8 6.77868C8.3866 6.77868 8.7 7.09208 8.7 7.47868V11.0787C8.7 11.4653 8.3866 11.7787 8 11.7787Z" fill="#419BF9"/>
</svg>

After

Width:  |  Height:  |  Size: 821 B

Loading…
Cancel
Save