Browse Source

Merge pull request #4642 in DESIGN/design from feature/10.0 to bugfix/10.0

* commit 'c1cbd7844fa3b6a04fa2cf0c7bffea0e7423fb30': (147 commits)
  REPORT-53711 设计器用户登录策略调整-插件无法安装
  REPORT-53787 && REPORT-53786【第二批问题】组件复用-合入主版本-新手引导图,和视觉图有一些不符合的地方
  REPORT-51958 远程环境检测及同步
  增加对验证码长度的校验
  修复引导页面无法关闭的问题
  fix
  CHART-19525 富文本编辑框设置为可调整
  修改延迟时间
  REPORT-51360 设计器消息提醒
  REPORT-53706 关闭按钮样式调整
  REPORT-51958 远程环境检测及同步
  REPORT-51958 远程环境检测及同步
  REPORT-51958 远程环境检测及同步
  REPORT-53806【组件复用】组件生成时,数据集查询的数据集变成了内置数据集,而不是保留查询
  REPORT-53591 远程环境检测及同步-插件名称提示有误
  REPORT-53785 切换工作目录后更新本地组件库
  REPORT-53772 【智能联动】组件名/数据集名替换时,拖入失败时重新再拖入成功 有几率造成多次替换
  登录面板颜色切换
  REPORT-53710 设计器处于未登录状态,切换至远程设计变为登录状态
  视觉修改
  ...
bugfix/10.0
superman 4 years ago
parent
commit
005054b97b
  1. 4
      build.gradle
  2. 141
      designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
  3. 7
      designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java
  4. 65
      designer-base/src/main/java/com/fr/design/actions/community/BBSAction.java
  5. 60
      designer-base/src/main/java/com/fr/design/actions/community/BugAction.java
  6. 17
      designer-base/src/main/java/com/fr/design/actions/community/CenterAction.java
  7. 2
      designer-base/src/main/java/com/fr/design/actions/community/CusDemandAction.java
  8. 2
      designer-base/src/main/java/com/fr/design/actions/community/FacebookFansAction.java
  9. 72
      designer-base/src/main/java/com/fr/design/actions/community/NeedAction.java
  10. 13
      designer-base/src/main/java/com/fr/design/actions/community/QuestionAction.java
  11. 70
      designer-base/src/main/java/com/fr/design/actions/community/SignAction.java
  12. 21
      designer-base/src/main/java/com/fr/design/actions/community/TechSolutionAction.java
  13. 52
      designer-base/src/main/java/com/fr/design/actions/community/TemplateStoreAction.java
  14. 80
      designer-base/src/main/java/com/fr/design/actions/community/UpAction.java
  15. 60
      designer-base/src/main/java/com/fr/design/actions/community/VideoAction.java
  16. 9
      designer-base/src/main/java/com/fr/design/actions/community/WorkOrderCenterAction.java
  17. 6
      designer-base/src/main/java/com/fr/design/actions/file/WebPreviewUtils.java
  18. 31
      designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java
  19. 22
      designer-base/src/main/java/com/fr/design/base/clipboard/ClipboardFilter.java
  20. 35
      designer-base/src/main/java/com/fr/design/base/clipboard/ClipboardHandler.java
  21. 7
      designer-base/src/main/java/com/fr/design/bridge/exec/JSExecutor.java
  22. 3
      designer-base/src/main/java/com/fr/design/constants/UIConstants.java
  23. 298
      designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java
  24. 17
      designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java
  25. 179
      designer-base/src/main/java/com/fr/design/dialog/NotificationDialog.java
  26. 5
      designer-base/src/main/java/com/fr/design/dialog/NotificationDialogAction.java
  27. 337
      designer-base/src/main/java/com/fr/design/dialog/UIExpandDialog.java
  28. 17
      designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java
  29. 17
      designer-base/src/main/java/com/fr/design/env/RemoteWorkspace.java
  30. 4
      designer-base/src/main/java/com/fr/design/extra/LoginContextListener.java
  31. 38
      designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java
  32. 9
      designer-base/src/main/java/com/fr/design/extra/PluginFromStorePane.java
  33. 17
      designer-base/src/main/java/com/fr/design/extra/PluginOperateUtils.java
  34. 9
      designer-base/src/main/java/com/fr/design/extra/PluginUpdatePane.java
  35. 21
      designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java
  36. 5
      designer-base/src/main/java/com/fr/design/extra/UserLoginContext.java
  37. 2
      designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java
  38. 7
      designer-base/src/main/java/com/fr/design/extra/exe/PluginLoginExecutor.java
  39. 20
      designer-base/src/main/java/com/fr/design/extra/exe/callback/InstallOnlineCallback.java
  40. 13
      designer-base/src/main/java/com/fr/design/extra/exe/callback/ModifyStatusCallback.java
  41. 2
      designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java
  42. 3
      designer-base/src/main/java/com/fr/design/file/filter/ClassFilter.java
  43. 5
      designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java
  44. 38
      designer-base/src/main/java/com/fr/design/gui/controlpane/CommonShortCutHandlers.java
  45. 144
      designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java
  46. 12
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java
  47. 130
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java
  48. 550
      designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java
  49. 24
      designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java
  50. 10
      designer-base/src/main/java/com/fr/design/locale/impl/BbsRegisterMark.java
  51. 10
      designer-base/src/main/java/com/fr/design/locale/impl/BbsResetMark.java
  52. 10
      designer-base/src/main/java/com/fr/design/locale/impl/BbsSpaceMark.java
  53. 2
      designer-base/src/main/java/com/fr/design/locale/impl/BugNeedMark.java
  54. 4
      designer-base/src/main/java/com/fr/design/locale/impl/TechSupportMark.java
  55. 10
      designer-base/src/main/java/com/fr/design/locale/impl/UserInfoMark.java
  56. 6
      designer-base/src/main/java/com/fr/design/locale/impl/VideoMark.java
  57. 46
      designer-base/src/main/java/com/fr/design/login/AbstractDesignerSSO.java
  58. 280
      designer-base/src/main/java/com/fr/design/login/DesignerLoginBridge.java
  59. 101
      designer-base/src/main/java/com/fr/design/login/DesignerLoginHelper.java
  60. 42
      designer-base/src/main/java/com/fr/design/login/DesignerLoginPane.java
  61. 45
      designer-base/src/main/java/com/fr/design/login/DesignerLoginShowDialog.java
  62. 29
      designer-base/src/main/java/com/fr/design/login/DesignerLoginSource.java
  63. 29
      designer-base/src/main/java/com/fr/design/login/DesignerLoginType.java
  64. 49
      designer-base/src/main/java/com/fr/design/login/bean/BBSAccountLogin.java
  65. 226
      designer-base/src/main/java/com/fr/design/login/config/DesignerLoginConfigManager.java
  66. 30
      designer-base/src/main/java/com/fr/design/login/executor/DesignerLoginBrowserExecutor.java
  67. 45
      designer-base/src/main/java/com/fr/design/login/executor/DesignerLoginExecutor.java
  68. 45
      designer-base/src/main/java/com/fr/design/login/executor/DesignerSendCaptchaExecutor.java
  69. 47
      designer-base/src/main/java/com/fr/design/login/executor/DesignerSmsLoginExecutor.java
  70. 49
      designer-base/src/main/java/com/fr/design/login/executor/DesignerSmsRegisterExecutor.java
  71. 83
      designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideBridge.java
  72. 123
      designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java
  73. 37
      designer-base/src/main/java/com/fr/design/login/guide/DesignerGuidePane.java
  74. 35
      designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideShowDialog.java
  75. 19
      designer-base/src/main/java/com/fr/design/login/guide/utils/DesignerGuideUtils.java
  76. 120
      designer-base/src/main/java/com/fr/design/login/message/DesignerMessageHelper.java
  77. 69
      designer-base/src/main/java/com/fr/design/login/message/DesignerModuleClickType.java
  78. 31
      designer-base/src/main/java/com/fr/design/login/message/NotificationJumpType.java
  79. 167
      designer-base/src/main/java/com/fr/design/login/service/DesignerLoginClient.java
  80. 82
      designer-base/src/main/java/com/fr/design/login/service/DesignerLoginResult.java
  81. 114
      designer-base/src/main/java/com/fr/design/login/service/DesignerPassportManager.java
  82. 87
      designer-base/src/main/java/com/fr/design/login/socketio/LoginAuthServer.java
  83. 51
      designer-base/src/main/java/com/fr/design/login/task/DesignerLoginTaskWorker.java
  84. 87
      designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java
  85. 39
      designer-base/src/main/java/com/fr/design/mainframe/ComponentReuseNotifyUtil.java
  86. 15
      designer-base/src/main/java/com/fr/design/mainframe/DesignOperationEvent.java
  87. 5
      designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
  88. 8
      designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java
  89. 73
      designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java
  90. 136
      designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java
  91. 2
      designer-base/src/main/java/com/fr/design/mainframe/burying/point/AbstractPointCollector.java
  92. 2
      designer-base/src/main/java/com/fr/design/mainframe/burying/point/AbstractPointInfo.java
  93. 2
      designer-base/src/main/java/com/fr/design/mainframe/burying/point/BasePointCollector.java
  94. 2
      designer-base/src/main/java/com/fr/design/mainframe/burying/point/BasePointInfo.java
  95. 5
      designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfo.java
  96. 20
      designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfoCollector.java
  97. 6
      designer-base/src/main/java/com/fr/design/mainframe/check/CheckButton.java
  98. 87
      designer-base/src/main/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfo.java
  99. 169
      designer-base/src/main/java/com/fr/design/mainframe/reuse/ReuseGuideDialog.java
  100. 32
      designer-base/src/main/java/com/fr/design/mainframe/reuse/SnapChatKeys.java
  101. Some files were not shown because too many files have changed in this diff Show More

4
build.gradle

@ -60,6 +60,10 @@ allprojects {
implementation 'com.fr.third:jxbrowser:6.23'
implementation 'com.fr.third:jxbrowser-mac:6.23'
implementation 'com.fr.third:jxbrowser-win64:6.23'
implementation 'com.fr.third:jxbrowser-v7:7.5'
implementation 'com.fr.third:jxbrowser-mac-v7:7.5'
implementation 'com.fr.third:jxbrowser-win64-v7:7.5'
implementation 'com.fr.third:jxbrowser-swing:7.5'
implementation 'com.fr.third.server:servlet-api:3.0'
implementation 'org.swingexplorer:swexpl:2.0.1'
implementation 'org.swingexplorer:swag:1.0'

141
designer-base/src/main/java/com/fr/design/DesignerEnvManager.java

@ -17,6 +17,9 @@ import com.fr.design.env.RemoteDesignerWorkspaceInfo;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.locale.impl.ProductImproveMark;
import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo;
import com.fr.design.login.DesignerLoginType;
import com.fr.design.login.config.DesignerLoginConfigManager;
import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.notification.SnapChatConfig;
import com.fr.design.port.DesignerPortContext;
@ -192,6 +195,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
// 开启内嵌web页面的调试窗口
private boolean openDebug = false;
private ComponentReuseNotificationInfo notificationInfo = ComponentReuseNotificationInfo.getInstance();
private DesignerLoginConfigManager designerLoginConfigManager = DesignerLoginConfigManager.getInstance();
/**
* DesignerEnvManager.
*/
@ -735,6 +742,113 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
designerPushUpdateConfigManager.setAutoPushUpdateEnabled(autoPushUpdateEnabled);
}
/**
* 设计器登录相关配置
*/
public void setDesignerLoginUid(int uid) {
designerLoginConfigManager.setUid(uid);
}
public int getDesignerLoginUid() {
return designerLoginConfigManager.getUid();
}
public void setDesignerLoginUsername(String username) {
designerLoginConfigManager.setUsername(username);
}
public String getDesignerLoginUsername() {
return designerLoginConfigManager.getUsername();
}
public void setDesignerLoginAppId(String appId) {
designerLoginConfigManager.setAppId(appId);
}
public String getDesignerLoginAppId() {
return designerLoginConfigManager.getAppId();
}
public void setDesignerLoginRefreshToken(String refreshToken) {
designerLoginConfigManager.setRefreshToken(refreshToken);
}
public String getDesignerLoginRefreshToken() {
return designerLoginConfigManager.getRefreshToken();
}
public void setDesignerLoginDoNotRemind(boolean doNotRemind) {
designerLoginConfigManager.setDoNotRemind(doNotRemind);
}
public boolean isDesignerLoginDoNotRemind() {
return designerLoginConfigManager.isDoNotRemind();
}
public void setDesignerLoginDoNotRemindSelectedTime(long doNotRemindSelectedTime) {
designerLoginConfigManager.setDoNotRemindSelectedTime(doNotRemindSelectedTime);
}
public long getDesignerLoginDoNotRemindSelectedTime() {
return designerLoginConfigManager.getDoNotRemindSelectedTime();
}
public void setDesignerActivatedTime(long designerActivatedTime) {
designerLoginConfigManager.setDesignerActivatedTime(designerActivatedTime);
}
public long getDesignerActivatedTime() {
return designerLoginConfigManager.getDesignerActivatedTime();
}
public void setDesignerLastLoginTime(long lastLoginTime) {
designerLoginConfigManager.setLastLoginTime(lastLoginTime);
}
public long getDesignerLastLoginTime() {
return designerLoginConfigManager.getLastLoginTime();
}
public void setCurrentVersionFirstLaunch(boolean currentVersionFirstLaunch) {
designerLoginConfigManager.setCurrentVersionFirstLaunch(currentVersionFirstLaunch);
}
public boolean isCurrentVersionFirstLaunch() {
return designerLoginConfigManager.isCurrentVersionFirstLaunch();
}
public DesignerLoginType getLastLoginType() {
return designerLoginConfigManager.getLastLoginType();
}
public void setLastLoginType(DesignerLoginType lastLoginType) {
designerLoginConfigManager.setLastLoginType(lastLoginType);
}
public String getLastLoginAccount() {
return designerLoginConfigManager.getLastLoginAccount();
}
public void setLastLoginAccount(String lastLoginAccount) {
designerLoginConfigManager.setLastLoginAccount(lastLoginAccount);
}
public boolean isLoginRemindBeforeJumpBBS() {
return designerLoginConfigManager.isLoginRemindBeforeJumpBBS();
}
public void setLoginRemindBeforeJumpBBS(boolean loginRemindBeforeJumpBBS) {
designerLoginConfigManager.setLoginRemindBeforeJumpBBS(loginRemindBeforeJumpBBS);
}
public boolean isPluginRemindOnFirstLaunch() {
return designerLoginConfigManager.isPluginRemindOnFirstLaunch();
}
public void setPluginRemindOnFirstLaunch(boolean pluginRemindOnFirstLaunch) {
designerLoginConfigManager.setPluginRemindOnFirstLaunch(pluginRemindOnFirstLaunch);
}
/**
* 内置服务器是否使用时启动
*
@ -1566,20 +1680,29 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
readRecentColor(reader);
} else if ("OpenDebug".equals(name)) {
readOpenDebug(reader);
} else if (name.equals(ComponentReuseNotificationInfo.XML_TAG)) {
readComponentReuseNotificationInfo(reader);
} else if (name.equals(DesignerPushUpdateConfigManager.XML_TAG)) {
readDesignerPushUpdateAttr(reader);
} else if (name.equals(vcsConfigManager.XML_TAG)) {
readVcsAttr(reader);
} else if (DesignerPort.XML_TAG.equals(name)) {
readDesignerPort(reader);
}else if (name.equals(SnapChatConfig.XML_TAG)) {
} else if (name.equals(SnapChatConfig.XML_TAG)) {
readSnapChatConfig(reader);
} else if (name.equals(DesignerLoginConfigManager.XML_TAG)) {
readDesignerLoginAttr(reader);
} else {
readLayout(reader, name);
}
}
}
private void readComponentReuseNotificationInfo(XMLableReader reader){
reader.readXMLObject(this.notificationInfo);
}
private void readSnapChatConfig(XMLableReader reader) {
reader.readXMLObject(this.snapChatConfig = SnapChatConfig.getInstance());
}
@ -1800,9 +1923,17 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
writeVcsAttr(writer);
writeDesignerPort(writer);
writeSnapChatConfig(writer);
writeComponentReuseNotificationInfo(writer);
writeDesignerLoginAttr(writer);
writer.end();
}
private void writeComponentReuseNotificationInfo(XMLPrintWriter writer) {
if (this.notificationInfo != null) {
this.notificationInfo.writeXML(writer);
}
}
private void writeSnapChatConfig(XMLPrintWriter writer) {
if (this.snapChatConfig != null) {
@ -2071,6 +2202,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.vcsConfigManager = vcsConfigManager;
}
private void readDesignerLoginAttr(XMLableReader reader) {
reader.readXMLObject(designerLoginConfigManager);
}
private void writeDesignerLoginAttr(XMLPrintWriter writer) {
this.designerLoginConfigManager.writeXML(writer);
}
enum XmlHandler {
Self;
public void handle(Throwable throwable) {

7
designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java

@ -18,7 +18,7 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.DesignUtils;
import com.fr.env.CheckServiceDialog;
import com.fr.design.versioncheck.VersionCheckUtils;
import com.fr.env.EnvListPane;
import com.fr.env.RemoteWorkspaceURL;
import com.fr.env.TestConnectionResult;
@ -96,6 +96,7 @@ public class EnvChangeEntrance {
*/
public void switch2Env(final String envName) {
switch2Env(envName, PopTipStrategy.LATER);
VersionCheckUtils.showVersionCheckDialog(envName);
}
/**
@ -145,7 +146,6 @@ public class EnvChangeEntrance {
if (template != null) {
template.refreshToolArea();
}
showServiceDialog(selectedEnv);
pluginErrorRemind();
} catch (WorkspaceAuthException | RegistEditionException e) {
// String title = Toolkit.i18nText("Fine-Design_Basic_Remote_Connect_Auth_Failed");
@ -294,8 +294,7 @@ public class EnvChangeEntrance {
if(StringUtils.isEmpty(areaText)){
return;
}
CheckServiceDialog dialog = new CheckServiceDialog(DesignerContext.getDesignerFrame(), areaText, localBranch, remoteBranch);
dialog.setVisible(true);
}
}
}

65
designer-base/src/main/java/com/fr/design/actions/community/BBSAction.java

@ -1,54 +1,43 @@
package com.fr.design.actions.community;
import com.fr.base.svg.IconUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.login.AbstractDesignerSSO;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class BBSAction extends AbstractDesignerSSO {
public class BBSAction extends UpdateAction
{
public BBSAction() {
this.setMenuKeySet(BBS);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/bbs/bbs");
public BBSAction()
{
this.setMenuKeySet(BBS);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/bbs/bbs");
}
}
/**
* 动作
* @param arg0 事件
*/
@Override
public void actionPerformed(ActionEvent arg0)
{
String url = CloudCenter.getInstance().acquireUrlByKind("bbs");
BrowseUtils.browser(url);
public String getJumpUrl() {
return CloudCenter.getInstance().acquireUrlByKind("bbs", "http://bbs.fanruan.com/");
}
public static final MenuKeySet BBS = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'B';
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community_Bbs");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
public static final MenuKeySet BBS = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'B';
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community_Bbs");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
}

60
designer-base/src/main/java/com/fr/design/actions/community/BugAction.java

@ -1,50 +1,42 @@
package com.fr.design.actions.community;
import com.fr.base.svg.IconUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.login.AbstractDesignerSSO;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class BugAction extends AbstractDesignerSSO {
public class BugAction extends UpdateAction
{
public BugAction() {
this.setMenuKeySet(BUG);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/bbs/bug");
}
public BugAction()
{ this.setMenuKeySet(BUG);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/bbs/bug");
}
@Override
public void actionPerformed(ActionEvent arg0)
{
String url = CloudCenter.getInstance().acquireUrlByKind("bbs.bugs");
BrowseUtils.browser(url);
@Override
public String getJumpUrl() {
return CloudCenter.getInstance().acquireUrlByKind("bbs.bugs", "http://bbs.fanruan.com/forum-156-1.html");
}
}
public static final MenuKeySet BUG = new MenuKeySet() {
public static final MenuKeySet BUG = new MenuKeySet() {
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community_Bug");
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community_Bug");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
@Override
public char getMnemonic()
{
@Override
public char getMnemonic() {
return 'U';
}
};
return 'U';
}
};
}

17
designer-base/src/main/java/com/fr/design/actions/community/CenterAction.java

@ -1,33 +1,26 @@
package com.fr.design.actions.community;
import com.fr.base.svg.IconUtils;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
/**
* Created by XINZAI on 2018/8/23.
*/
public class CenterAction extends UpAction{
public CenterAction()
{
public class CenterAction extends UpAction {
public CenterAction() {
this.setMenuKeySet(CENTER);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/bbs/center");
}
@Override
public void actionPerformed(ActionEvent arg0)
{
String url = CloudCenter.getInstance().acquireUrlByKind("bbs.center");
BrowseUtils.browser(url);
public String getJumpUrl() {
return CloudCenter.getInstance().acquireUrlByKind("bbs.center", "http://bbs.fanruan.com/events/");
}
public static final MenuKeySet CENTER = new MenuKeySet() {
@Override
public char getMnemonic() {

2
designer-base/src/main/java/com/fr/design/actions/community/CusDemandAction.java

@ -25,7 +25,7 @@ public class CusDemandAction extends UpAction{
@Override
public void actionPerformed(ActionEvent arg0)
{
String url = CloudCenter.getInstance().acquireUrlByKind("bbs.demand");
String url = CloudCenter.getInstance().acquireUrlByKind("bbs.demand", "https://market.fanruan.com/demand");
BrowseUtils.browser(url);
}

2
designer-base/src/main/java/com/fr/design/actions/community/FacebookFansAction.java

@ -18,7 +18,7 @@ public class FacebookFansAction extends UpAction {
@Override
public void actionPerformed(ActionEvent arg0) {
BrowseUtils.browser(CloudCenter.getInstance().acquireUrlByKind("facebook.fans.tw"));
BrowseUtils.browser(CloudCenter.getInstance().acquireUrlByKind("facebook.fans.tw", "https://www.facebook.com/twfinereport"));
}
public static final MenuKeySet FACEBOOKFANS = new MenuKeySet() {

72
designer-base/src/main/java/com/fr/design/actions/community/NeedAction.java

@ -1,49 +1,41 @@
package com.fr.design.actions.community;
import com.fr.base.svg.IconUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.login.AbstractDesignerSSO;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class NeedAction extends UpdateAction
{
public NeedAction()
{
this.setMenuKeySet(NEED);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/bbs/need");
}
@Override
public void actionPerformed(ActionEvent arg0)
{
String url = CloudCenter.getInstance().acquireUrlByKind("bbs.needs");
BrowseUtils.browser(url);
}
public static final MenuKeySet NEED = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'N';
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Commuinity_Need");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
public class NeedAction extends AbstractDesignerSSO {
public NeedAction() {
this.setMenuKeySet(NEED);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/bbs/need");
}
@Override
public String getJumpUrl() {
return CloudCenter.getInstance().acquireUrlByKind("bbs.needs", "http://bbs.fanruan.com/forum-56-1.html");
}
public static final MenuKeySet NEED = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'N';
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Commuinity_Need");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
}

13
designer-base/src/main/java/com/fr/design/actions/community/QuestionAction.java

@ -1,16 +1,12 @@
package com.fr.design.actions.community;
import com.fr.base.svg.IconUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.login.AbstractDesignerSSO;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class QuestionAction extends UpdateAction {
public class QuestionAction extends AbstractDesignerSSO {
public QuestionAction() {
this.setMenuKeySet(QUESTIONS);
@ -21,9 +17,8 @@ public class QuestionAction extends UpdateAction {
}
@Override
public void actionPerformed(ActionEvent arg0) {
String url = CloudCenter.getInstance().acquireUrlByKind("bbs.questions");
BrowseUtils.browser(url);
public String getJumpUrl() {
return CloudCenter.getInstance().acquireUrlByKind("bbs.questions", "http://bbs.fanruan.com/wenda");
}
public static final MenuKeySet QUESTIONS = new MenuKeySet() {

70
designer-base/src/main/java/com/fr/design/actions/community/SignAction.java

@ -1,49 +1,41 @@
package com.fr.design.actions.community;
import com.fr.base.svg.IconUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.login.AbstractDesignerSSO;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class SignAction extends UpdateAction
{
public SignAction()
{
this.setMenuKeySet(SIGN);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/bbs/sign");
}
@Override
public void actionPerformed(ActionEvent arg0)
{
String url = CloudCenter.getInstance().acquireUrlByKind("bbs.aut");
BrowseUtils.browser(url);
}
public static final MenuKeySet SIGN = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'S';
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community_sign");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
public class SignAction extends AbstractDesignerSSO {
public SignAction() {
this.setMenuKeySet(SIGN);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/bbs/sign");
}
@Override
public String getJumpUrl() {
return CloudCenter.getInstance().acquireUrlByKind("bbs.aut", "https://bbs.fanruan.com/certification/");
}
public static final MenuKeySet SIGN = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'S';
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community_sign");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
}

21
designer-base/src/main/java/com/fr/design/actions/community/TechSolutionAction.java

@ -1,23 +1,16 @@
package com.fr.design.actions.community;
import com.fr.base.svg.IconUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.login.AbstractDesignerSSO;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
/**
* Created by XINZAI on 2018/8/23.
*/
public class TechSolutionAction extends UpdateAction{
public TechSolutionAction()
{
public class TechSolutionAction extends AbstractDesignerSSO {
public TechSolutionAction() {
this.setMenuKeySet(TSO);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
@ -26,12 +19,10 @@ public class TechSolutionAction extends UpdateAction{
}
@Override
public void actionPerformed(ActionEvent arg0)
{
String url = CloudCenter.getInstance().acquireUrlByKind("bbs.solution");
BrowseUtils.browser(url);
public String getJumpUrl() {
return CloudCenter.getInstance().acquireUrlByKind("bbs.solution", "http://bbs.fanruan.com/forum-113-1.html");
}
public static final MenuKeySet TSO = new MenuKeySet() {
@Override
public char getMnemonic() {

52
designer-base/src/main/java/com/fr/design/actions/community/TemplateStoreAction.java

@ -0,0 +1,52 @@
package com.fr.design.actions.community;
import com.fr.base.BaseUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.mainframe.share.collect.ComponentCollector;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import javax.swing.KeyStroke;
import java.awt.event.ActionEvent;
/**
* created by Harrison on 2020/03/24
**/
public class TemplateStoreAction extends UpdateAction {
public TemplateStoreAction() {
this.setMenuKeySet(TEMPLATE);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon(BaseUtils.readIcon("/com/fr/base/images/share/template_store.png"));
}
public static final MenuKeySet TEMPLATE = new MenuKeySet() {
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Template_Store");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
@Override
public char getMnemonic() {
return 'T';
}
};
@Override
public void actionPerformed(ActionEvent e) {
ComponentCollector.getInstance().collectTepMenuEnterClick();
String url = CloudCenter.getInstance().acquireUrlByKind("design.market.template", "https://market.fanruan.com/template");
BrowseUtils.browser(url);
}
}

80
designer-base/src/main/java/com/fr/design/actions/community/UpAction.java

@ -1,69 +1,41 @@
package com.fr.design.actions.community;
import com.fr.base.BaseUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.login.AbstractDesignerSSO;
import com.fr.design.menu.MenuKeySet;
import com.fr.general.CloudCenter;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javax.swing.JOptionPane;
import javax.swing.KeyStroke;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
public class UpAction extends UpdateAction
{
public class UpAction extends AbstractDesignerSSO {
public UpAction()
{
this.setMenuKeySet(UPDATE);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/update.png"));
}
public UpAction() {
this.setMenuKeySet(UPDATE);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/update.png"));
}
@Override
public void actionPerformed(ActionEvent arg0)
{
String url = CloudCenter.getInstance().acquireUrlByKind("bbs.update");
if (StringUtils.isEmpty(url)) {
FineLoggerFactory.getLogger().info("The URL is empty!");
return;
}
try {
Desktop.getDesktop().browse(new URI(url));
} catch (IOException exp) {
FineJOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Set_Default_Browser"));
FineLoggerFactory.getLogger().error(exp.getMessage(), exp);
} catch (URISyntaxException exp) {
FineLoggerFactory.getLogger().error(exp.getMessage(), exp);
} catch (Exception exp) {
FineLoggerFactory.getLogger().error(exp.getMessage(), exp);
FineLoggerFactory.getLogger().error("Can not open the browser for URL: " + url);
}
public String getJumpUrl() {
return CloudCenter.getInstance().acquireUrlByKind("bbs.update", "http://bbs.fanruan.com/forum.php?mod=collection&action=view&ctid=10");
}
public static final MenuKeySet UPDATE = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'U';
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community_Update");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
public static final MenuKeySet UPDATE = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'U';
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community_Update");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
}

60
designer-base/src/main/java/com/fr/design/actions/community/VideoAction.java

@ -1,49 +1,43 @@
package com.fr.design.actions.community;
import com.fr.base.svg.IconUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.locale.impl.VideoMark;
import com.fr.design.login.AbstractDesignerSSO;
import com.fr.design.menu.MenuKeySet;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import javax.swing.*;
import java.awt.event.ActionEvent;
public class VideoAction extends AbstractDesignerSSO {
public class VideoAction extends UpdateAction
{
public VideoAction()
{
this.setMenuKeySet(VIDEO);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/bbs/video");
}
public VideoAction() {
this.setMenuKeySet(VIDEO);
this.setName(getMenuKeySet().getMenuName());
this.setMnemonic(getMenuKeySet().getMnemonic());
this.setSmallIcon("/com/fr/design/images/bbs/video");
}
@Override
public void actionPerformed(ActionEvent arg0)
{
public String getJumpUrl() {
LocaleMark<String> localeMark = LocaleCenter.getMark(VideoMark.class);
BrowseUtils.browser(localeMark.getValue());
return localeMark.getValue();
}
public static final MenuKeySet VIDEO = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'V';
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community_Video");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
public static final MenuKeySet VIDEO = new MenuKeySet() {
@Override
public char getMnemonic() {
return 'V';
}
@Override
public String getMenuName() {
return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Community_Video");
}
@Override
public KeyStroke getKeyStroke() {
return null;
}
};
}

9
designer-base/src/main/java/com/fr/design/actions/community/WorkOrderCenterAction.java

@ -1,12 +1,8 @@
package com.fr.design.actions.community;
import com.fr.design.i18n.Toolkit;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import java.awt.event.ActionEvent;
/**
* @Description 工单中心
* @Author Henry.Wang
@ -19,8 +15,7 @@ public class WorkOrderCenterAction extends UpAction {
}
@Override
public void actionPerformed(ActionEvent arg0) {
String url = CloudCenter.getInstance().acquireUrlByKind("bbs.work.order.center");
BrowseUtils.browser(url);
public String getJumpUrl() {
return CloudCenter.getInstance().acquireUrlByKind("bbs.work.order.center", "https://service.fanruan.com/ticket");
}
}

6
designer-base/src/main/java/com/fr/design/actions/file/WebPreviewUtils.java

@ -76,7 +76,7 @@ public final class WebPreviewUtils {
browserTemplate(jt, baseRoute, map, actionType);
}
});
worker.start(jt.getTarget().getTemplateID());
worker.start(jt.getRuntimeId());
return;
}
browserTemplate(jt, baseRoute, map, actionType);
@ -97,7 +97,7 @@ public final class WebPreviewUtils {
);
if (OK_OPTION == selVal) {
CallbackSaveWorker worker = jt.saveAs();
worker.start(jt.getTarget().getTemplateID());
worker.start(jt.getRuntimeId());
worker.addSuccessCallback(new Runnable() {
@Override
public void run() {
@ -125,7 +125,7 @@ public final class WebPreviewUtils {
browseUrl(jt.getEditingFILE(), baseRoute, map, actionType, jt);
}
});
worker.start(jt.getTarget().getTemplateID());
worker.start(jt.getRuntimeId());
}
}
}

31
designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java

@ -1,12 +1,10 @@
package com.fr.design.actions.help;
import com.fr.base.svg.IconUtils;
import com.fr.design.actions.UpdateAction;
import com.fr.design.login.AbstractDesignerSSO;
import com.fr.design.menu.MenuKeySet;
import com.fr.general.CloudCenter;
import com.fr.general.GeneralContext;
import com.fr.general.http.HttpToolbox;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.CommonUtils;
import com.fr.stable.ProductConstants;
import com.fr.stable.StringUtils;
@ -15,14 +13,9 @@ import com.fr.third.org.apache.http.StatusLine;
import com.fr.third.org.apache.http.client.methods.HttpGet;
import javax.swing.KeyStroke;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.net.URI;
public class TutorialAction extends UpdateAction {
private static final String URL_FOR_TEST_NETWORK = "https://www.baidu.com";
public class TutorialAction extends AbstractDesignerSSO {
public TutorialAction() {
this.setMenuKeySet(HELP_TUTORIAL);
@ -32,29 +25,15 @@ public class TutorialAction extends UpdateAction {
this.setAccelerator(getMenuKeySet().getKeyStroke());
}
/**
* 动作
* @param evt 事件
*/
@Override
public void actionPerformed(ActionEvent evt) {
String helpURL = CloudCenter.getInstance().acquireUrlByKind(createDocKey());
// 用第三方网址去判断是否处在离线状态
if (isServerOnline(URL_FOR_TEST_NETWORK)) {
try {
Desktop.getDesktop().browse(new URI(helpURL));
return;
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
FineLoggerFactory.getLogger().warn(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Offline_Helptutorial_Msg"));
public String getJumpUrl() {
return CloudCenter.getInstance().acquireUrlByKind(createDocKey());
}
// 生成帮助文档 sitecenter key, help.zh_CN.10
protected String createDocKey() {
String locale = GeneralContext.getLocale().toString();
return CommonUtils.join(new String[]{ "help", locale, ProductConstants.MAIN_VERSION }, ".");
return CommonUtils.join(new String[]{"help", locale, ProductConstants.MAIN_VERSION}, ".");
}
// 判断是否可以访问在线文档

22
designer-base/src/main/java/com/fr/design/base/clipboard/ClipboardFilter.java

@ -4,6 +4,7 @@ import com.fr.design.ExtraDesignClassManager;
import com.fr.design.fun.ClipboardHandlerProvider;
import com.fr.plugin.injectable.PluginModule;
import java.util.HashSet;
import java.util.Set;
/**
@ -11,11 +12,25 @@ import java.util.Set;
**/
@SuppressWarnings({"rawtypes", "unchecked"})
public abstract class ClipboardFilter {
public static Set<ClipboardHandlerProvider> clipboardHandlerProviders = new HashSet();
public static void registerClipboardHandler(ClipboardHandlerProvider provider) {
if (!clipboardHandlerProviders.contains(provider)) {
clipboardHandlerProviders.add(provider);
}
}
public static void removeClipboardHandler(ClipboardHandlerProvider provider) {
if (clipboardHandlerProviders.contains(provider)) {
clipboardHandlerProviders.remove(provider);
}
}
public static <T> T cut(T selection) {
ExtraDesignClassManager manager = PluginModule.getAgent(PluginModule.ExtraDesign);
Set<ClipboardHandlerProvider> providers = manager.getArray(ClipboardHandlerProvider.XML_TAG);
providers.addAll(clipboardHandlerProviders);
for (ClipboardHandlerProvider provider : providers) {
if (provider.support(selection)) {
selection = ((ClipboardHandlerProvider<T>) provider).cut(selection);
@ -25,9 +40,9 @@ public abstract class ClipboardFilter {
}
public static <T> T copy(T selection) {
ExtraDesignClassManager manager = PluginModule.getAgent(PluginModule.ExtraDesign);
Set<ClipboardHandlerProvider> providers = manager.getArray(ClipboardHandlerProvider.XML_TAG);
providers.addAll(clipboardHandlerProviders);
for (ClipboardHandlerProvider provider : providers) {
if (provider.support(selection)) {
selection = ((ClipboardHandlerProvider<T>) provider).copy(selection);
@ -37,9 +52,10 @@ public abstract class ClipboardFilter {
}
public static <T> T paste(T selection) {
ExtraDesignClassManager manager = PluginModule.getAgent(PluginModule.ExtraDesign);
Set<ClipboardHandlerProvider> providers = manager.getArray(ClipboardHandlerProvider.XML_TAG);
providers.addAll(clipboardHandlerProviders);
for (ClipboardHandlerProvider provider : providers) {
if (provider.support(selection)) {
selection = ((ClipboardHandlerProvider<T>) provider).paste(selection);

35
designer-base/src/main/java/com/fr/design/base/clipboard/ClipboardHandler.java

@ -0,0 +1,35 @@
package com.fr.design.base.clipboard;
public interface ClipboardHandler<T> {
/**
* 剪切
*
* @param selection 选中
* @return 处理后的内容
*/
T cut(T selection);
/**
* 复制
*
* @param selection 选中
* @return 处理后的内容
*/
T copy(T selection);
/**
* 粘贴
*
* @param selection 选中
* @return 处理后的内容
*/
T paste(T selection);
/**
* 支持的类型
*
* @param selection 内容
* @return 是否
*/
boolean support(Object selection);
}

7
designer-base/src/main/java/com/fr/design/bridge/exec/JSExecutor.java

@ -7,5 +7,12 @@ public interface JSExecutor {
String CALLBACK_FUNCTION_NAME = "action";
JSExecutor DEFAULT = new JSExecutor() {
@Override
public void executor(String newValue) {
// do nothing
}
};
void executor(String newValue);
}

3
designer-base/src/main/java/com/fr/design/constants/UIConstants.java

@ -148,7 +148,8 @@ public interface UIConstants {
public static final Color TAB_BUTTON_PRESS_SELECTED = new Color(236, 236, 238);
public static final Color POPUP_TITLE_BACKGROUND = new Color(0xd8f2fd);
public static final Color LIST_ITEM_SPLIT_LINE = new Color(0xf0f0f3);
public static final Color DESIGNER_LOGIN_BACKGROUND = new Color(0xf1ad14);
public static final Color DESIGNER_LOGIN_BACKGROUND_ONCLICK = new Color(0xd89600);
public static final BufferedImage DRAG_BAR = IOUtils.readImage("com/fr/design/images/control/bar.png");
public static final BufferedImage DRAG_BAR_LIGHT = IOUtils.readImage("com/fr/design/images/control/bar-light.png");

298
designer-base/src/main/java/com/fr/design/data/datapane/preview/sql/PreviewPerformedSqlPane.java

@ -0,0 +1,298 @@
package com.fr.design.data.datapane.preview.sql;
import com.fr.base.Parameter;
import com.fr.base.ParameterHelper;
import com.fr.base.ParameterMapNameSpace;
import com.fr.data.impl.DBTableData;
import com.fr.data.impl.EscapeSqlHelper;
import com.fr.data.operator.DataOperator;
import com.fr.decision.webservice.v10.config.ConfigService;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.dialog.link.MessageWithLink;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.parameter.ParameterInputPane;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.CloudCenter;
import com.fr.general.GeneralContext;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.injectable.PluginModule;
import com.fr.script.Calculator;
import com.fr.stable.ArrayUtils;
import com.fr.stable.ParameterProvider;
import com.fr.stable.StringUtils;
import com.fr.stable.fun.TableDataProvider;
import com.fr.stable.plugin.ExtraClassManagerProvider;
import com.fr.stable.script.NameSpace;
import javax.swing.BorderFactory;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.UIManager;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultHighlighter;
import javax.swing.text.Highlighter;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Frame;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
public class PreviewPerformedSqlPane extends JDialog implements ActionListener {
private JPanel topPanel;
private JPanel centerPanel;
private JPanel bottomPanel;
private UILabel imageLabel;
public PreviewPerformedSqlPane(Frame frame, String sql) {
this(frame, sql, null, null, false);
}
public PreviewPerformedSqlPane(Frame frame, String sql, List<int[]> selectedSpecialCharIndex, String[] selectedSpecialChar, boolean highlight) {
super(frame, true);
// 提示信息
topPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
JPanel imagePanel = new JPanel();
JPanel messagePanel;
if (isShowSpecialCharSqlPane(selectedSpecialCharIndex)) {
imageLabel = new UILabel(UIManager.getIcon("OptionPane.warningIcon"));
messagePanel = new JPanel();
messagePanel.setLayout(FRGUIPaneFactory.createBorderLayout());
messagePanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0));
// 日韩取消超链,直接显示文字
if (isNotShowLink()) {
JLabel label = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql_Message") + Toolkit.i18nText("Fine-Design_Basic_Sql_Injection_Prevention") + Toolkit.i18nText("Fine-Design_Basic_Preview_Special_Char_Sql_Back_Message"));
messagePanel.add(label);
} else {
MessageWithLink message = new MessageWithLink(Toolkit.i18nText("Fine-Design_Basic_Preview_Special_Char_Sql_Front_Message"), Toolkit.i18nText("Fine-Design_Basic_Sql_Injection_Prevention"), CloudCenter.getInstance().acquireConf(Toolkit.i18nText("Fine-Design_Basic_Sql_Injection_Prevention_Help"), "https://help.fanruan.com/finereport/doc-view-2219.html"), Toolkit.i18nText("Fine-Design_Basic_Preview_Special_Char_Sql_Back_Message"));
messagePanel.add(message);
}
// 提示图标
JPanel tipPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
UILabel tipLabel = new UILabel(UIManager.getIcon("OptionPane.tipIcon"));
StringBuilder textBuilder = new StringBuilder();
textBuilder.append("<html>").append(Toolkit.i18nText("Fine-Design_Basic_Processed_Special_Char")).append("<br/>");
for (String sChar : selectedSpecialChar) {
textBuilder.append(sChar).append("<br/>");
}
textBuilder.append("</html>");
tipLabel.setToolTipText(textBuilder.toString());
tipPanel.add(tipLabel, BorderLayout.SOUTH);
topPanel.add(tipPanel, BorderLayout.EAST);
} else {
imageLabel = new UILabel(UIManager.getIcon("OptionPane.informationIcon"));
messagePanel = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true);
JLabel label = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql_Message"));
messagePanel.add(label);
}
imagePanel.add(imageLabel);
topPanel.add(imagePanel, BorderLayout.WEST);
topPanel.add(messagePanel, BorderLayout.CENTER);
topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10));
//中间的SQL面板
centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
centerPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
JScrollPane scrollPane = new JScrollPane();
JTextArea checkArea = new JTextArea(sql);
checkArea.setEditable(false);
checkArea.setCursor(new Cursor(Cursor.TEXT_CURSOR));
if (highlight) {
Highlighter highLighter = checkArea.getHighlighter();
DefaultHighlighter.DefaultHighlightPainter p = new DefaultHighlighter.DefaultHighlightPainter(Color.ORANGE);
for (int[] specialCharIndex : selectedSpecialCharIndex) {
try {
highLighter.addHighlight(specialCharIndex[0], specialCharIndex[1], p);
} catch (BadLocationException e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
scrollPane.setViewportView(checkArea);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
centerPanel.add(scrollPane);
//底部的按钮面板
UIButton okButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_OK"));
okButton.addActionListener(this);
bottomPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
bottomPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
bottomPanel.add(okButton, BorderLayout.EAST);
this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql"));
this.setResizable(false);
this.add(topPanel, BorderLayout.NORTH);
this.add(centerPanel, BorderLayout.CENTER);
this.add(bottomPanel, BorderLayout.SOUTH);
this.setSize(600, 400);
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
close();
}
});
GUICoreUtils.centerWindow(this);
}
private boolean isNotShowLink() {
return GeneralContext.getLocale().equals(Locale.JAPAN) || GeneralContext.getLocale().equals(Locale.KOREA);
}
public static void previewPerformedSql(DBTableData tableData) {
Calculator calculator = Calculator.createCalculator();
//参数
ParameterProvider[] parameters = DataOperator.getInstance().getTableDataParameters(tableData);
if (ArrayUtils.isEmpty(parameters)) {
parameters = tableData.getParameters(calculator);
}
Map<String, Object> parameterMap = new HashMap<>();
if (needInputParams(parameters)) {
showParaWindow(parameterMap, parameters);
} else {
for (ParameterProvider parameter : parameters) {
parameterMap.put(parameter.getName(), parameter.getValue());
}
}
for (ParameterProvider parameter : DataOperator.getInstance().getTableDataParameters(tableData)) {
if (parameterMap.containsKey(parameter.getName())) {
parameter.setValue(parameterMap.get(parameter.getName()));
}
}
String sql;
// 计算高亮文本位置
List<int[]> specialCharParamIndex = null;
boolean highlight = true;
NameSpace ns = ParameterMapNameSpace.create(parameterMap);
calculator.pushNameSpace(ns);
Parameter[] paras = processParameters(tableData, calculator);
// 所有被转义参数的集合
refreshEscapeSqlHelper();
Set<String> specialCharParam = EscapeSqlHelper.getInstance().getSpecialCharParam(paras);
// 将参数转义等
Set<TableDataProvider> tableDataProviders = getTableDataProviders();
for (TableDataProvider provider : tableDataProviders) {
provider.processParametersBeforeAnalyzeSQL(paras, calculator);
}
if (!specialCharParam.isEmpty()) {
specialCharParamIndex = ParameterHelper.analyzeCurrentContextTableData4Template(tableData.getQuery(), paras, specialCharParam);
}
String oldSql = ParameterHelper.analyzeCurrentContextTableData4Templatee(tableData.getQuery(), paras);
sql = processExtraSQL(paras, oldSql, calculator, tableDataProviders);
if (!StringUtils.equals(oldSql, sql)) {
highlight = false;
}
// sql内容复制到剪切板
StringSelection selection = new StringSelection(sql);
java.awt.Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection);
// 弹窗
if (isShowSpecialCharSqlPane(specialCharParamIndex)) {
showSpecialCharSqlPane(sql, specialCharParamIndex, highlight);
} else {
showNormalPreviewPane(sql);
}
}
// 埋点方法
private static void showNormalPreviewPane(String sql) {
PreviewPerformedSqlPane pane = new PreviewPerformedSqlPane(DesignerContext.getDesignerFrame(), sql);
pane.setVisible(true);
}
// 埋点方法
private static void showSpecialCharSqlPane(String sql, List<int[]> specialCharParamIndex, boolean highlight) {
PreviewPerformedSqlPane pane = new PreviewPerformedSqlPane(DesignerContext.getDesignerFrame(), sql, specialCharParamIndex, ConfigService.getInstance().getPSIConfig().getSelectedSpecialChar(), highlight);
pane.setVisible(true);
}
private static void refreshEscapeSqlHelper() {
EscapeSqlHelper.getInstance().setUseForbidWord(ConfigService.getInstance().getPSIConfig().isUseForbidWord());
EscapeSqlHelper.getInstance().setSelectedForbidWord(ConfigService.getInstance().getPSIConfig().getSelectedForbidWord());
EscapeSqlHelper.getInstance().setUseEscapeSpecialChar(ConfigService.getInstance().getPSIConfig().isUseEscapeSpecialChar());
EscapeSqlHelper.getInstance().setSelectedSpecialChar(ConfigService.getInstance().getPSIConfig().getSelectedSpecialChar());
}
private static boolean isShowSpecialCharSqlPane(List<int[]> specialCharParamIndex) {
return specialCharParamIndex != null && !specialCharParamIndex.isEmpty();
}
private static Parameter[] processParameters(DBTableData tableData, Calculator calculator) {
ParameterProvider[] parameters = tableData.getParameters();
if (parameters == null || parameters.length == 0) {
tableData.setParameters(ParameterHelper.analyze4Parameters(tableData.getQuery(), false));
return new Parameter[0];
}
return Parameter.providers2Parameter(Calculator.processParameters(calculator, parameters));
}
private static String processExtraSQL(Parameter[] ps, String sql, Calculator ca, Set<TableDataProvider> tableDataProviders) {
for (TableDataProvider provider : tableDataProviders) {
String newSql = provider.processTableDataSQL(ps, sql, ca);
if (StringUtils.isNotEmpty(newSql)) {
sql = newSql;
}
}
return sql;
}
private static boolean needInputParams(ParameterProvider[] parameters) {
if (ArrayUtils.isNotEmpty(parameters)) {
return true;
}
for (ParameterProvider parameter : parameters) {
if (parameter.getValue() == null || StringUtils.EMPTY.equals(parameter.getValue())) {
return true;
}
}
return false;
}
private static void showParaWindow(final Map<String, Object> parameterMap, ParameterProvider[] inParameters) {
final ParameterInputPane pPane = new ParameterInputPane(inParameters);
pPane.showSmallWindow(new JFrame(), new DialogActionAdapter() {
@Override
public void doOk() {
parameterMap.putAll(pPane.update());
}
}).setVisible(true);
}
private static Set<TableDataProvider> getTableDataProviders() {
ExtraClassManagerProvider classManagerProvider = PluginModule.getAgent(PluginModule.ExtraCore);
if (classManagerProvider == null) {
return new HashSet<>();
}
return classManagerProvider.getArray(TableDataProvider.XML_TAG, EscapeSqlHelper.getInstance());
}
@Override
public void actionPerformed(ActionEvent e) {
this.dispose();
}
private void close() {
this.dispose();
}
}

17
designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java

@ -16,6 +16,7 @@ import com.fr.design.constants.UIConstants;
import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane;
import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane.DoubleClickSelectedNodeOnTreeListener;
import com.fr.design.data.datapane.preview.PreviewTablePane;
import com.fr.design.data.datapane.preview.sql.PreviewPerformedSqlPane;
import com.fr.design.data.datapane.sqlpane.SQLEditPane;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
@ -35,6 +36,7 @@ import com.fr.design.menu.ToolBarDef;
import com.fr.design.utils.ParameterUtils;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import com.fr.general.IOUtils;
import com.fr.general.sql.SqlUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.script.Calculator;
@ -227,6 +229,7 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
// p:工具栏.
ToolBarDef toolBarDef = new ToolBarDef();
toolBarDef.addShortCut(new PreviewAction());
toolBarDef.addShortCut(new PreviewPerformedSQLAction());
toolBarDef.addShortCut(SeparatorDef.DEFAULT);
toolBarDef.addShortCut(new EditPageQueryAction());
dbTableDataMenuHandler = ExtraDesignClassManager.getInstance().getSingle(DBTableDataMenuHandler.MARK_STRING);
@ -368,6 +371,20 @@ public class DBTableDataPane extends AbstractTableDataPane<DBTableData> {
}
}
private class PreviewPerformedSQLAction extends UpdateAction {
public PreviewPerformedSQLAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview_Performed_Sql"));
this.setSmallIcon(IOUtils.readIcon("/com/fr/design/images/m_file/preview_sql.png"));
}
@Override
public void actionPerformed(ActionEvent e) {
checkParameter();
PreviewPerformedSqlPane.previewPerformedSql(DBTableDataPane.this.updateBean());
}
}
private class EditPageQueryAction extends UpdateAction {
public EditPageQueryAction() {
this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Layer_Page_Report_Page_Query"));

179
designer-base/src/main/java/com/fr/design/dialog/NotificationDialog.java

@ -0,0 +1,179 @@
package com.fr.design.dialog;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.notification.Notification;
import com.fr.design.notification.NotificationCenter;
import com.fr.design.utils.gui.GUICoreUtils;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
/**
* 带查看详情的简要通知框
*
*/
public class NotificationDialog extends JDialog {
public static final int ERROR_MESSAGE = 0;
public static final int NEW_MESSAGE = 1;
public static final int WARNING_MESSAGE = 2;
public static final String HTML_TAG_1 = "<html>";
public static final String HTML_TAG_2 = "</html>";
private UILabel messageText;
private NotificationDialogAction notificationDialogAction;
public NotificationDialog(Frame owner, String title, boolean isModal, int messageType, String message,NotificationDialogAction action) {
super(owner);
setTitle(title);
initComponents(messageType, message, isModal,action);
}
public NotificationDialog(Builder builder) {
super(builder.owner);
setTitle(builder.title);
initComponents(builder.messageType, builder.message, builder.modal, builder.action);
}
public void initComponents(int messageType, String message, boolean isModal,NotificationDialogAction action) {
NotificationCenter.getInstance().addNotification(new Notification(messageType,message,action));
notificationDialogAction = action;
setModal(isModal);
setResizable(false);
//消息内容
UILabel icon = new UILabel(getIconForType(messageType));
JPanel iconPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
iconPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 8));
iconPanel.add(icon);
add(iconPanel, BorderLayout.WEST);
messageText = new UILabel(HTML_TAG_1 + message + HTML_TAG_2);
messageText.setForeground(new Color(51, 51, 52));
JPanel centerPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 10));
JScrollPane jScrollPane = new JScrollPane(messageText, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
jScrollPane.setBorder(BorderFactory.createEmptyBorder());
centerPanel.add(jScrollPane, BorderLayout.CENTER);
add(centerPanel, BorderLayout.CENTER);
//查看详情
UILabel detailLabel = new UILabel();
detailLabel.setText(Toolkit.i18nText("Fine_Designer_Look_Detail"));
detailLabel.setForeground(Color.BLUE);
JPanel detailPanel = FRGUIPaneFactory.createBorderLayout_L_Pane();
detailPanel.add(detailLabel, BorderLayout.EAST);
add(detailPanel, BorderLayout.SOUTH);
setPreferredSize(new Dimension(262, 135));
detailLabel.addMouseListener(detailClickListener);
messageText.addMouseListener(detailClickListener);
pack();
if (getOwner() != null) {
GUICoreUtils.setWindowCenter(getOwner(), this);
}
}
private MouseListener detailClickListener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(notificationDialogAction != null){
hideDialog();
notificationDialogAction.doClick();
}
}
};
/**
* 设置通知消息
*/
public void setMessage(String message){
messageText.setText(HTML_TAG_1 + message + HTML_TAG_2);
}
private void hideDialog(){
this.dispose();
}
protected Icon getIconForType(int messageType) {
String propertyName;
switch (messageType) {
case 0:
propertyName = "OptionPane.circularErrorIcon";
break;
case 1:
propertyName = "OptionPane.newMessageIcon";
break;
case 2:
propertyName = "OptionPane.circularWarningIcon";
break;
default:
return null;
}
return UIManager.getIcon(propertyName);
}
public static Builder Builder() {
return new NotificationDialog.Builder();
}
public static final class Builder {
public int messageType = WARNING_MESSAGE;
public String message;
public boolean modal = true;
public Frame owner = null;
public String title;
public NotificationDialogAction action;
private Builder() {
}
public NotificationDialog build() {
return new NotificationDialog(this);
}
public Builder owner(Frame owner) {
this.owner = owner;
return this;
}
public Builder messageType(int messageType) {
this.messageType = messageType;
return this;
}
public Builder message(String message) {
this.message = message;
return this;
}
public Builder modal(boolean modal) {
this.modal = modal;
return this;
}
public Builder title(String title) {
this.title = title;
return this;
}
public Builder notificationDialogAction(NotificationDialogAction action) {
this.action = action;
return this;
}
}
}

5
designer-base/src/main/java/com/fr/design/dialog/NotificationDialogAction.java

@ -0,0 +1,5 @@
package com.fr.design.dialog;
public interface NotificationDialogAction {
void doClick();
}

337
designer-base/src/main/java/com/fr/design/dialog/UIExpandDialog.java

@ -0,0 +1,337 @@
package com.fr.design.dialog;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextarea.UITextArea;
import com.fr.design.i18n.Toolkit;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
/**
* 可展开对话框
*
* <pre>
* UIExpandDialog.Builder()
* .owner(jf)
* .title("title")
* .messageType(UIExpandDialog.WARNING_MESSAGE)
* .message("message text")
* .detail("detail")
* .expand(false)
* .modal(false)
* .dialogActionListener(new DialogActionAdapter(){
* public void doOk() {
* System.out.println("OK");
* }
* }).build().setVisible(true);
* </pre>
*
* @author vito
* @version 10.0
* Created by vito on 2021/5/19
*/
public class UIExpandDialog extends UIDialog {
public static final int MARGIN = 10;
public static final int TEXT_AREA_ROW = 5;
public static final int GAP = 5;
public static final int ERROR_MESSAGE = 0;
public static final int INFORMATION_MESSAGE = 1;
public static final int WARNING_MESSAGE = 2;
public static final int QUESTION_MESSAGE = 3;
public static final String HTML_TAG_1 = "<html>";
public static final String HTML_TAG_2 = "</html>";
private final JPanel foldBar = new JPanel();
private final JPanel expandableContentPane = new JPanel();
private final UILabel narrow = new UILabel();
private final UILabel narrowHit = new UILabel();
private final UIButton buttonOK;
private UIButton buttonCancel = null;
private JLabel msg;
private final UITextArea textArea = new UITextArea();
public UIExpandDialog(Frame owner, String title, boolean isModal,
int messageType, String message, String detail,
String okText, String cancelText, boolean isExpand) {
super(owner);
buttonOK = new UIButton(okText);
if (!StringUtils.isEmpty(cancelText)) {
buttonCancel = new UIButton(cancelText);
}
setTitle(title);
setModal(isModal);
initComponents(messageType, message, detail, isModal, isExpand, null);
}
public UIExpandDialog(Builder builder) {
super(builder.owner);
buttonOK = new UIButton(builder.okText);
if (!StringUtils.isEmpty(builder.cancelText)) {
buttonCancel = new UIButton(builder.cancelText);
}
setTitle(builder.title);
setModal(builder.modal);
initComponents(builder.messageType, builder.message, builder.detail,
builder.modal, builder.expand, builder.dialogActionListener);
}
public void initComponents(int messageType, String message, String detail,
boolean isModal, boolean isExpand, DialogActionListener l) {
applyClosingAction();
setLayout(new BorderLayout(GAP, GAP));
setResizable(false);
setModal(isModal);
getRootPane().setDefaultButton(buttonOK);
// 标题面板
UILabel icon = new UILabel(getIconForType(messageType));
msg = new JLabel(HTML_TAG_1 + message + HTML_TAG_2);
msg.setPreferredSize(new Dimension(300, 50));
JPanel mainMsg = new JPanel();
mainMsg.setLayout(new FlowLayout(FlowLayout.LEFT, MARGIN, MARGIN));
mainMsg.setPreferredSize(new Dimension(380, 60));
mainMsg.add(icon);
mainMsg.add(msg);
add(mainMsg, BorderLayout.NORTH);
// 内容面板
JPanel contentPanel = new JPanel();
contentPanel.setLayout(new BorderLayout(GAP, GAP));
foldBar.setLayout(new FlowLayout(FlowLayout.LEFT, MARGIN, 0));
foldBar.add(narrow);
foldBar.add(narrowHit);
contentPanel.add(foldBar, BorderLayout.NORTH);
textArea.setEditable(false);
textArea.setRows(TEXT_AREA_ROW);
textArea.setMargin(new Insets(GAP, GAP, GAP, GAP));
textArea.setEditable(false);
textArea.setText(detail);
UIScrollPane scrollPane = new UIScrollPane(textArea);
expandableContentPane.setLayout(new BorderLayout());
expandableContentPane.setBorder(BorderFactory.createEmptyBorder(0, MARGIN, 0, MARGIN));
expandableContentPane.add(scrollPane, BorderLayout.CENTER);
changeExpand(isExpand);
contentPanel.add(expandableContentPane, BorderLayout.CENTER);
add(contentPanel, BorderLayout.CENTER);
// 操作面板
JPanel actionPanel = new JPanel();
actionPanel.setLayout(new FlowLayout(FlowLayout.CENTER, MARGIN, MARGIN));
if (buttonCancel != null) {
actionPanel.add(buttonCancel);
}
actionPanel.add(buttonOK);
add(actionPanel, BorderLayout.SOUTH);
initListener();
if (l != null) {
addDialogActionListener(l);
}
pack();
if (getOwner() != null) {
GUICoreUtils.setWindowCenter(getOwner(), this);
}
}
private void changeExpand(boolean isExpand) {
if (isExpand) {
expandableContentPane.setVisible(true);
narrow.setIcon(UIManager.getIcon("OptionPane.narrow.down"));
narrowHit.setText(Toolkit.i18nText("Fine_Designer_Hide_Detail"));
} else {
expandableContentPane.setVisible(false);
narrow.setIcon(UIManager.getIcon("OptionPane.narrow.right"));
narrowHit.setText(Toolkit.i18nText("Fine_Designer_Look_Detail"));
}
}
private void initListener() {
foldBar.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
changeExpand(!expandableContentPane.isShowing());
pack();
}
@Override
public void mouseEntered(MouseEvent e) {
foldBar.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@Override
public void mouseExited(MouseEvent e) {
foldBar.setCursor(Cursor.getDefaultCursor());
}
});
buttonOK.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
doOK();
}
});
if (buttonCancel != null) {
buttonCancel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
doCancel();
}
});
}
}
protected Icon getIconForType(int messageType) {
if (messageType < 0 || messageType > 3)
return null;
String propertyName;
switch (messageType) {
case 0:
propertyName = "OptionPane.errorIcon";
break;
case 1:
default:
propertyName = "OptionPane.informationIcon";
break;
case 2:
propertyName = "OptionPane.warningIcon";
break;
case 3:
propertyName = "OptionPane.questionIcon";
break;
}
return UIManager.getIcon(propertyName);
}
/**
* 设置对话框主消息
*
* @param message 消息内容
*/
public void setMessage(String message) {
msg.setText(HTML_TAG_1 + message + HTML_TAG_2);
}
/**
* 设置对话框消息详情
*
* @param detail 消息详情
*/
public void setDetail(String detail) {
textArea.setText(detail);
}
/**
* 设置详情面板展开关闭
*
* @param expand 展开或关闭
*/
public void setExpand(boolean expand) {
changeExpand(expand);
}
@Override
public void setVisible(boolean b) {
super.setVisible(b);
}
public static Builder Builder() {
return new UIExpandDialog.Builder();
}
public static final class Builder {
public int messageType = ERROR_MESSAGE;
public String title;
public String message;
public String detail;
public String okText = Toolkit.i18nText("Fine-Design_Report_OK");
public String cancelText = Toolkit.i18nText("Fine-Design_Basic_Cancel");
public boolean modal = true;
public boolean expand = true;
public Frame owner = null;
public DialogActionListener dialogActionListener = null;
private Builder() {
}
public UIExpandDialog build() {
return new UIExpandDialog(this);
}
public Builder owner(Frame owner) {
this.owner = owner;
return this;
}
public Builder messageType(int messageType) {
this.messageType = messageType;
return this;
}
public Builder title(String title) {
this.title = title;
return this;
}
public Builder message(String message) {
this.message = message;
return this;
}
public Builder detail(String detail) {
this.detail = detail;
return this;
}
public Builder okText(String okText) {
this.okText = okText;
return this;
}
public Builder cancelText(String cancelText) {
this.cancelText = cancelText;
return this;
}
public Builder modal(boolean modal) {
this.modal = modal;
return this;
}
public Builder expand(boolean expand) {
this.expand = expand;
return this;
}
public Builder dialogActionListener(DialogActionListener dialogActionListener) {
this.dialogActionListener = dialogActionListener;
return this;
}
}
@Override
public void checkValid() throws Exception {
}
}

17
designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java

@ -3,13 +3,14 @@ package com.fr.design.dialog.link;
import com.fr.design.gui.ilable.UILabel;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import javax.swing.JEditorPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
import java.awt.Color;
import java.awt.Desktop;
import java.awt.Font;
import java.net.URI;
import javax.swing.JEditorPane;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;
/**
* 用来构建JOptionPane带超链的消息提示
@ -35,8 +36,16 @@ public class MessageWithLink extends JEditorPane {
this(message, linkName, link, color, LABEL.getFont());
}
public MessageWithLink(String frontMessage, String linkName, String link, String backMessage) {
this(frontMessage, linkName, link, backMessage, LABEL.getBackground(), LABEL.getFont());
}
public MessageWithLink(String message, String linkName, String link, Color color, Font font) {
super("text/html", "<html><body style=\"" + generateStyle(color, font) + "\">" + message + "<a href=\"" + link + "\">" + linkName + "</a>" + "</body></html>");
this(message, linkName, link, StringUtils.EMPTY, color, font);
}
public MessageWithLink(String frontMessage, String linkName, String link, String backMessage, Color color, Font font) {
super("text/html", "<html><body style=\"" + generateStyle(color, font) + "\">" + frontMessage + "<a href=\"" + link + "\">" + linkName + "</a>" + backMessage + "</body></html>");
initListener(link);
setEditable(false);
setBorder(null);

17
designer-base/src/main/java/com/fr/design/env/RemoteWorkspace.java vendored

@ -34,11 +34,20 @@ public class RemoteWorkspace implements Workspace {
private volatile Boolean warDeploy;
private final SwingWorker<Void,Void> swingWorker;
RemoteWorkspace(WorkspaceClient client, WorkspaceConnectionInfo connection) {
this.client = client;
this.address = connection.getUrl();
this.connection = connection;
this.swingWorker = new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
client.close();
return null;
}
};
}
@Override
@ -125,13 +134,7 @@ public class RemoteWorkspace implements Workspace {
@Override
public void close() {
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
client.close();
return null;
}
}.execute();
swingWorker.execute();
}
@Override

4
designer-base/src/main/java/com/fr/design/extra/LoginContextListener.java

@ -1,8 +1,10 @@
package com.fr.design.extra;
import com.fr.design.login.DesignerLoginSource;
/**
* Created by lp on 2016/8/16.
*/
public interface LoginContextListener {
void showLoginContext();
void showLoginContext(DesignerLoginSource source);
}

38
designer-base/src/main/java/com/fr/design/extra/LoginWebBridge.java

@ -1,13 +1,15 @@
package com.fr.design.extra;
import com.fr.base.passport.FinePassportManager;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.config.MarketConfig;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.exe.PluginLoginExecutor;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.login.service.DesignerLoginClient;
import com.fr.design.login.service.DesignerLoginResult;
import com.fr.general.CloudCenter;
import com.fr.general.http.HttpClient;
import com.fr.general.locale.LocaleCenter;
@ -80,17 +82,15 @@ public class LoginWebBridge {
*/
public void setMessageCount(int count) {
if (count == MIN_MESSAGE_COUNT) {
uiLabel.setText(MarketConfig.getInstance().getBbsUsername());
MarketConfig.getInstance().setInShowBBsName(MarketConfig.getInstance().getBbsUsername());
MarketConfig.getInstance().setInShowBBsName(DesignerEnvManager.getEnvManager().getDesignerLoginUsername());
return;
}
this.messageCount = count;
StringBuilder sb = new StringBuilder();
sb.append(StringUtils.BLANK).append(MarketConfig.getInstance().getBbsUsername())
sb.append(StringUtils.BLANK).append(DesignerEnvManager.getEnvManager().getDesignerLoginUsername())
.append("(").append(this.messageCount)
.append(")").append(StringUtils.BLANK);
MarketConfig.getInstance().setInShowBBsName(sb.toString());
uiLabel.setText(sb.toString());
}
public void setQQDialog(UIDialog qqDialog) {
@ -163,20 +163,11 @@ public class LoginWebBridge {
* @return 登录信息标志
*/
public String login(String userInfo, String password) {
if (!StringUtils.isNotBlank(userInfo) && !StringUtils.isNotBlank(password)) {
return LOGIN_INFO_EMPTY;
}
if (!testConnection()) {
return NET_FAILED;
}
int uid = 0;
try {
uid = FinePassportManager.getInstance().login(userInfo, password);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
DesignerLoginClient client = new DesignerLoginClient();
DesignerLoginResult result = client.login(userInfo, password);
int uid = result.getUid();
if (uid > 0) {
loginSuccess(MarketConfig.getInstance().getBbsUsername());
closeWindow();
}
return String.valueOf(uid);
}
@ -191,17 +182,6 @@ public class LoginWebBridge {
}
}
/**
* 关闭窗口并且重新赋值
*
* @param username 用户名
*/
private void loginSuccess(String username) {
closeWindow();
uiLabel.setText(username);
uiLabel.setBackground(LOGIN_BACKGROUND);
}
/**
* 关闭QQ授权窗口
*/

9
designer-base/src/main/java/com/fr/design/extra/PluginFromStorePane.java

@ -1,6 +1,6 @@
package com.fr.design.extra;
import com.fr.config.MarketConfig;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.extra.tradition.callback.UpdateOnlineCallback;
import com.fr.design.gui.frpane.UITabbedPane;
@ -9,6 +9,7 @@ import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker;
import com.fr.plugin.manage.PluginManager;
import com.fr.plugin.manage.control.PluginExtraInfo;
import com.fr.plugin.manage.control.PluginTaskResult;
import com.fr.plugin.manage.control.ProgressCallback;
import com.fr.plugin.view.PluginView;
@ -190,10 +191,10 @@ public class PluginFromStorePane extends PluginAbstractLoadingViewPane<List<Plug
}
private void doUpdateOnline(final PluginStatusCheckCompletePane pane) {
if (!StringUtils.isNotEmpty(MarketConfig.getInstance().getBbsUsername())) {
if (!StringUtils.isNotEmpty(DesignerEnvManager.getEnvManager().getDesignerLoginUsername())) {
LoginCheckContext.fireLoginCheckListener();
}
if (StringUtils.isNotEmpty(MarketConfig.getInstance().getBbsUsername())) {
if (StringUtils.isNotEmpty(DesignerEnvManager.getEnvManager().getDesignerLoginUsername())) {
PluginView plugin = controlPane.getSelectedPlugin();
if (plugin == null) {
FineLoggerFactory.getLogger().error("selected plugin is null");
@ -206,7 +207,7 @@ public class PluginFromStorePane extends PluginAbstractLoadingViewPane<List<Plug
JSONObject latestPluginInfo = PluginUtils.getLatestPluginInfo(id);
String latestPluginVersion = (String) latestPluginInfo.get("version");
PluginMarker toPluginMarker = PluginMarker.create(id, latestPluginVersion);
PluginManager.getController().download(pluginMarker, new UpdateOnlineCallback(pluginMarker, toPluginMarker, pane));
PluginManager.getController().download(pluginMarker, new UpdateOnlineCallback(pluginMarker, toPluginMarker, pane), PluginExtraInfo.newBuilder().username(DesignerEnvManager.getEnvManager().getDesignerLoginUsername()).build());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}

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

@ -1,6 +1,6 @@
package com.fr.design.extra;
import com.fr.config.MarketConfig;
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.InstallFromDiskCallback;
@ -9,7 +9,6 @@ import com.fr.design.extra.exe.callback.ModifyStatusCallback;
import com.fr.design.extra.exe.callback.UninstallPluginCallback;
import com.fr.design.extra.exe.callback.UpdateFromDiskCallback;
import com.fr.design.extra.exe.callback.UpdateOnlineCallback;
import com.fr.design.gui.ilable.UILabel;
import com.fr.general.CloudCenter;
import com.fr.general.http.HttpClient;
import com.fr.json.JSONArray;
@ -21,6 +20,7 @@ import com.fr.plugin.context.PluginMarker;
import com.fr.plugin.context.PluginMarkerAdapter;
import com.fr.plugin.manage.PluginManager;
import com.fr.plugin.manage.control.PluginControllerHelper;
import com.fr.plugin.manage.control.PluginExtraInfo;
import com.fr.plugin.manage.control.PluginTask;
import com.fr.plugin.manage.control.PluginTaskCallback;
import com.fr.plugin.manage.control.PluginTaskResult;
@ -43,7 +43,7 @@ public class PluginOperateUtils {
PluginMarker marker = updateMarker2Online(pluginMarker);
//下载插件
PluginTask pluginTask = PluginTask.installTask(marker);
PluginControllerHelper.installOnline(pluginMarker, new InstallOnlineCallback(pluginTask, jsCallback));
PluginControllerHelper.installOnline(pluginMarker, new InstallOnlineCallback(pluginTask, jsCallback), PluginExtraInfo.newBuilder().username(DesignerEnvManager.getEnvManager().getDesignerLoginUsername()).build());
}
public static PluginMarker updateMarker2Online(PluginMarker pluginMarker) {
@ -77,7 +77,7 @@ public class PluginOperateUtils {
//当前已经安装的相同ID插件marker
PluginMarker currentMarker = PluginMarkerAdapter.create(PluginUtils.getInstalledPluginMarkerByID(pluginMarker.getPluginID()), pluginName);
PluginTask pluginTask = PluginTask.updateTask(currentMarker, toPluginMarker);
PluginControllerHelper.updateOnline(currentMarker, toPluginMarker, new UpdateOnlineCallback(pluginTask, jsCallback));
PluginControllerHelper.updateOnline(currentMarker, toPluginMarker, new UpdateOnlineCallback(pluginTask, jsCallback), PluginExtraInfo.newBuilder().username(DesignerEnvManager.getEnvManager().getDesignerLoginUsername()).build());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
@ -193,15 +193,12 @@ public class PluginOperateUtils {
}
}
public static void getLoginInfo(JSCallback jsCallback, UILabel uiLabel) {
String username = MarketConfig.getInstance().getBbsUsername();
public static void getLoginInfo(JSCallback jsCallback) {
String username = DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
if (StringUtils.isEmpty(username)) {
jsCallback.execute(StringUtils.EMPTY);
uiLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Base_UnSignIn"));
} else {
uiLabel.setText(username);
String result = username;
jsCallback.execute(result);
jsCallback.execute(username);
}
}

9
designer-base/src/main/java/com/fr/design/extra/PluginUpdatePane.java

@ -1,6 +1,6 @@
package com.fr.design.extra;
import com.fr.config.MarketConfig;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.extra.tradition.callback.UpdateOnlineCallback;
import com.fr.design.gui.frpane.UITabbedPane;
@ -9,6 +9,7 @@ import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.plugin.context.PluginMarker;
import com.fr.plugin.manage.PluginManager;
import com.fr.plugin.manage.control.PluginExtraInfo;
import com.fr.plugin.manage.control.PluginTaskResult;
import com.fr.plugin.manage.control.ProgressCallback;
import com.fr.plugin.view.PluginView;
@ -170,17 +171,17 @@ public class PluginUpdatePane extends PluginAbstractLoadingViewPane<List<PluginV
}
private void doUpdateOnline(final PluginStatusCheckCompletePane pane) {
if (!StringUtils.isNotEmpty(MarketConfig.getInstance().getBbsUsername())) {
if (!StringUtils.isNotEmpty(DesignerEnvManager.getEnvManager().getDesignerLoginUsername())) {
LoginCheckContext.fireLoginCheckListener();
}
if (StringUtils.isNotEmpty(MarketConfig.getInstance().getBbsUsername())) {
if (StringUtils.isNotEmpty(DesignerEnvManager.getEnvManager().getDesignerLoginUsername())) {
try {
PluginView plugin = controlPane.getSelectedPlugin();
PluginMarker pluginMarker = PluginMarker.create(plugin.getID(), plugin.getVersion());
JSONObject latestPluginInfo = PluginUtils.getLatestPluginInfo(pluginMarker.getPluginID());
String latestPluginVersion = (String) latestPluginInfo.get("version");
PluginMarker toPluginMarker = PluginMarker.create(pluginMarker.getPluginID(), latestPluginVersion);
PluginManager.getController().download(pluginMarker, new UpdateOnlineCallback(pluginMarker, toPluginMarker, pane));
PluginManager.getController().download(pluginMarker, new UpdateOnlineCallback(pluginMarker, toPluginMarker, pane), PluginExtraInfo.newBuilder().username(DesignerEnvManager.getEnvManager().getDesignerLoginUsername()).build());
} catch (Exception e) {
}

21
designer-base/src/main/java/com/fr/design/extra/PluginWebBridge.java

@ -1,7 +1,7 @@
package com.fr.design.extra;
import com.fr.base.passport.FinePassportManager;
import com.fr.config.MarketConfig;
import com.fr.design.DesignerEnvManager;
import com.fr.design.RestartHelper;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.dialog.UIDialog;
@ -12,13 +12,12 @@ import com.fr.design.extra.exe.GetPluginPrefixExecutor;
import com.fr.design.extra.exe.PluginLoginExecutor;
import com.fr.design.extra.exe.ReadUpdateOnlineExecutor;
import com.fr.design.extra.exe.SearchOnlineExecutor;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.locale.impl.BbsRegisterMark;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.locale.impl.BbsSpaceMark;
import com.fr.design.login.DesignerLoginSource;
import com.fr.design.plugin.DesignerPluginContext;
import com.fr.design.utils.concurrent.ThreadFactoryBuilder;
import com.fr.general.CloudCenter;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.json.JSONObject;
@ -66,8 +65,6 @@ public class PluginWebBridge {
private Map<String, Object> config;
private WebEngine webEngine;
private UILabel uiLabel;
private ExecutorService threadPoolExecutor = new ThreadPoolExecutor(COREPOOLSIZE, MAXPOOLSIZE,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(COREPOOLSIZE),
@ -423,7 +420,7 @@ public class PluginWebBridge {
*/
public String getLoginInfo(final JSObject callback) {
registerLoginInfo(callback);
return MarketConfig.getInstance().getBbsUsername();
return DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
}
/**
@ -433,7 +430,7 @@ public class PluginWebBridge {
*/
public void registerLoginInfo(final JSObject callback) {
JSCallback jsCallback = new JSCallback(PluginJavaFxExecutor.create(webEngine, callback));
PluginOperateUtils.getLoginInfo(jsCallback, uiLabel);
PluginOperateUtils.getLoginInfo(jsCallback);
}
/**
@ -455,7 +452,7 @@ public class PluginWebBridge {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
UserLoginContext.fireLoginContextListener();
UserLoginContext.fireLoginContextListener(DesignerLoginSource.NORMAL);
}
});
}
@ -526,10 +523,6 @@ public class PluginWebBridge {
}
}
public void setUILabel(UILabel uiLabel) {
this.uiLabel = uiLabel;
}
/**
* 设计器端的用户登录
*
@ -546,7 +539,7 @@ public class PluginWebBridge {
* 通过QQ登录后通知登录
*/
public void ucsynLogin(long uid, String username, String password, final JSONObject callback) {
uiLabel.setText(username);
}
/**
@ -554,8 +547,6 @@ public class PluginWebBridge {
*/
public void clearUserInfo() {
MarketConfig.getInstance().setInShowBBsName(StringUtils.EMPTY);
FinePassportManager.getInstance().logout();
uiLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Base_UnSignIn"));
}
public void getPackInfo(final JSObject callback){

5
designer-base/src/main/java/com/fr/design/extra/UserLoginContext.java

@ -1,5 +1,6 @@
package com.fr.design.extra;
import com.fr.design.login.DesignerLoginSource;
import java.util.ArrayList;
/**
@ -11,9 +12,9 @@ public class UserLoginContext {
/**
* 触发登录框弹出的监听器
*/
public static void fireLoginContextListener() {
public static void fireLoginContextListener(DesignerLoginSource source) {
for (LoginContextListener l : fireLoginContextListener) {
l.showLoginContext();
l.showLoginContext(source);
}
}

2
designer-base/src/main/java/com/fr/design/extra/WebViewDlgHelper.java

@ -5,6 +5,7 @@ import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.dialog.UIDialog;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.mainframe.DesignerContext;
import com.fr.general.CloudCenter;
import com.fr.general.CommonIOUtils;
@ -206,6 +207,7 @@ public class WebViewDlgHelper {
UIDialog dlg = new ShopDialog(DesignerContext.getDesignerFrame(), managerPane);
PluginWebBridge.getHelper().setDialogHandle(dlg);
dlg.setVisible(true);
DesignerLoginUtils.showPluginRemindOnFirstLaunch();
} catch (Exception e) {
// ignored
FineLoggerFactory.getLogger().error(e.getMessage(), e);

7
designer-base/src/main/java/com/fr/design/extra/exe/PluginLoginExecutor.java

@ -2,6 +2,7 @@ package com.fr.design.extra.exe;
import com.fr.design.extra.LoginWebBridge;
import com.fr.design.extra.Process;
import com.fr.design.login.service.DesignerPassportManager;
/**
* @author vito
@ -34,7 +35,11 @@ public class PluginLoginExecutor implements Executor {
@Override
public void run(Process<String> process) {
result = LoginWebBridge.getHelper().login(username, password);
int uid = DesignerPassportManager.getInstance().login(username, password);
if (uid > 0) {
LoginWebBridge.getHelper().closeWindow();
}
result = String.valueOf(uid);
}
}
};

20
designer-base/src/main/java/com/fr/design/extra/exe/callback/InstallOnlineCallback.java

@ -1,6 +1,7 @@
package com.fr.design.extra.exe.callback;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.bridge.exec.JSExecutor;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.extra.PluginOperateUtils;
import com.fr.design.i18n.Toolkit;
@ -17,17 +18,22 @@ import com.fr.plugin.manage.control.PluginTaskResult;
* Created by ibm on 2017/5/26.
*/
public class InstallOnlineCallback extends AbstractDealPreTaskCallback {
protected JSCallback jsCallback;
protected JSCallback jsCallback = new JSCallback(JSExecutor.DEFAULT);
private static int HUNDRED_PERCENT = 100;
public InstallOnlineCallback(PluginTask pluginTask, JSCallback jsCallback){
public InstallOnlineCallback(PluginTask pluginTask) {
super(pluginTask);
}
public InstallOnlineCallback(PluginTask pluginTask, JSCallback jsCallback) {
super(pluginTask);
this.jsCallback = jsCallback;
}
@Override
public void updateProgress(String description, double aProgress) {
jsCallback.execute(String.valueOf(aProgress * HUNDRED_PERCENT + "%"));
jsCallback.execute(aProgress * HUNDRED_PERCENT + "%");
}
@ -37,10 +43,10 @@ public class InstallOnlineCallback extends AbstractDealPreTaskCallback {
if (result.isSuccess()) {
String switchedInfo = PluginOperateUtils.getSwitchedInfo(result);
jsCallback.execute("success");
String successInfo = pluginInfo + Toolkit.i18nText("Fine-Design_Basic_Plugin_Install_Success") + switchedInfo;
String successInfo = pluginInfo + Toolkit.i18nText("Fine-Design_Basic_Plugin_Install_Success") + switchedInfo;
FineLoggerFactory.getLogger().info(successInfo);
FineJOptionPane.showMessageDialog(null, successInfo);
} else if(result.errorCode() == PluginErrorCode.HasLowerPluginWhenInstall){
} else if (result.errorCode() == PluginErrorCode.HasLowerPluginWhenInstall) {
int rv = FineJOptionPane.showConfirmDialog(
null,
Toolkit.i18nText("Fine-Design_Basic_Plugin_Has_Install_Lower"),
@ -51,8 +57,7 @@ public class InstallOnlineCallback extends AbstractDealPreTaskCallback {
if (rv == FineJOptionPane.OK_OPTION) {
PluginMarker pluginMarker = result.getCurrentTask().getMarker();
PluginOperateUtils.updatePluginOnline(pluginMarker, jsCallback);
}
else {
} else {
jsCallback.execute("success");
}
} else {
@ -63,5 +68,4 @@ public class InstallOnlineCallback extends AbstractDealPreTaskCallback {
}
}

13
designer-base/src/main/java/com/fr/design/extra/exe/callback/ModifyStatusCallback.java

@ -1,6 +1,7 @@
package com.fr.design.extra.exe.callback;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.bridge.exec.JSExecutor;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.extra.PluginOperateUtils;
import com.fr.design.i18n.Toolkit;
@ -15,14 +16,20 @@ import javax.swing.JOptionPane;
/**
* Created by ibm on 2017/5/27.
*/
public class ModifyStatusCallback implements PluginTaskCallback{
public class ModifyStatusCallback implements PluginTaskCallback {
private boolean isActive;
private JSCallback jsCallback;
private JSCallback jsCallback = new JSCallback(JSExecutor.DEFAULT);
;
public ModifyStatusCallback (boolean isActive, JSCallback jsCallback){
public ModifyStatusCallback(boolean isActive) {
this.isActive = isActive;
}
public ModifyStatusCallback(boolean isActive, JSCallback jsCallback) {
this.isActive = isActive;
this.jsCallback = jsCallback;
}
@Override
public void done(PluginTaskResult result) {
String pluginInfo = PluginOperateUtils.getSuccessInfo(result);

2
designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java

@ -706,7 +706,7 @@ public class MutilTempalteTabPane extends JComponent {
closeTpl(specifiedTemplate);
}
});
worker.start(specifiedTemplate.getTarget().getTemplateID());
worker.start(specifiedTemplate.getRuntimeId());
} else if (returnVal == JOptionPane.NO_OPTION) {
closeTpl(specifiedTemplate);
}

3
designer-base/src/main/java/com/fr/design/file/filter/ClassFilter.java

@ -5,6 +5,8 @@ import java.util.HashSet;
import java.util.Set;
/**
* classloader查找过滤器
*
* 过滤无需遍历的jdk class
*
* @author hades
@ -26,6 +28,7 @@ public class ClassFilter implements Filter<String> {
FILTER_SET.add("java.awt.image.BufferedImage");
FILTER_SET.add("sun.awt.AppContext");
FILTER_SET.add("com.fr.poly.creator.ECBlockCreator");
FILTER_SET.add("com.fr.form.ui.ElementCaseImage");
}
@Override

5
designer-base/src/main/java/com/fr/design/gui/UILookAndFeel.java

@ -176,7 +176,12 @@ public class UILookAndFeel extends MetalLookAndFeel {
table.put("OptionPane.narrow.right", loadIcon("Icon_Narrow_Right_16x16.png", this));
table.put("OptionPane.narrow.down", loadIcon("Icon_Narrow_Down_16x16.png", this));
table.put("OptionPane.warningIcon", loadIcon("WarningIcon.png", this));
table.put("OptionPane.circularWarningIcon", loadIcon("circularWarningIcon.png", this));
table.put("OptionPane.newMessageIcon", loadIcon("newMessageIcon.png", this));
table.put("OptionPane.circularErrorIcon", loadIcon("circularErrorIcon.png", this));
table.put("OptionPane.deleteIcon", loadIcon("deleteIcon.png", this));
table.put("OptionPane.questionIcon", loadIcon("QuestionIcon.png", this));
table.put("OptionPane.tipIcon", loadIcon("TipIcon.png", this));
table.put("ScrollPane.border", new UIScrollPaneBorder());
table.put("ProgressBar.border", new UIProgressBarBorder());
table.put("Spinner.border", new UITextFieldBorder(new Insets(2, 2, 2, 2)));

38
designer-base/src/main/java/com/fr/design/gui/controlpane/CommonShortCutHandlers.java

@ -21,11 +21,9 @@ import java.util.Comparator;
*/
public class CommonShortCutHandlers {
ListControlPaneProvider listControlPane;
JNameEdList nameableList;
private CommonShortCutHandlers(ListControlPaneProvider listControlPane) {
this.listControlPane = listControlPane;
this.nameableList = listControlPane.getNameableList();
}
public static CommonShortCutHandlers newInstance(ListControlPaneProvider listControlPane) {
@ -43,19 +41,19 @@ public class CommonShortCutHandlers {
public void onRemoveItem() {
try {
nameableList.getCellEditor()
listControlPane.getNameableList().getCellEditor()
.stopCellEditing();
} catch (Exception ignored) {
}
if (GUICoreUtils.removeJListSelectedNodes(SwingUtilities
.getWindowAncestor((Component) listControlPane), nameableList)) {
.getWindowAncestor((Component) listControlPane), listControlPane.getNameableList())) {
listControlPane.checkButtonEnabled();
}
}
public void onCopyItem() {
// p:选中的值.
ListModelElement selectedValue = (ListModelElement) nameableList.getSelectedValue();
ListModelElement selectedValue = (ListModelElement) listControlPane.getNameableList().getSelectedValue();
if (selectedValue == null) {
return;
}
@ -76,47 +74,51 @@ public class CommonShortCutHandlers {
}
public void onMoveUpItem() {
int selectedIndex = nameableList.getSelectedIndex();
int selectedIndex = listControlPane.getNameableList().getSelectedIndex();
if (selectedIndex == -1) {
return;
}
// 上移
if (selectedIndex > 0) {
DefaultListModel listModel = (DefaultListModel) nameableList.getModel();
DefaultListModel listModel = (DefaultListModel) listControlPane.getNameableList().getModel();
Object selecteObj1 = listModel.get(selectedIndex - 1);
listModel.set(selectedIndex - 1, listModel.get(selectedIndex));
listModel.set(selectedIndex, selecteObj1);
nameableList.setSelectedIndex(selectedIndex - 1);
nameableList.ensureIndexIsVisible(selectedIndex - 1);
listControlPane.getNameableList().setSelectedIndex(selectedIndex - 1);
listControlPane.getNameableList().ensureIndexIsVisible(selectedIndex - 1);
}
}
public void onMoveDownItem() {
int selectedIndex = nameableList.getSelectedIndex();
int selectedIndex = listControlPane.getNameableList().getSelectedIndex();
if (selectedIndex == -1) {
return;
}
if (selectedIndex < nameableList.getModel().getSize() - 1) {
DefaultListModel listModel = (DefaultListModel) nameableList
if (selectedIndex < listControlPane.getNameableList().getModel().getSize() - 1) {
DefaultListModel listModel = (DefaultListModel) listControlPane.getNameableList()
.getModel();
Object selecteObj1 = listModel.get(selectedIndex + 1);
listModel.set(selectedIndex + 1, listModel.get(selectedIndex));
listModel.set(selectedIndex, selecteObj1);
nameableList.setSelectedIndex(selectedIndex + 1);
nameableList.ensureIndexIsVisible(selectedIndex + 1);
listControlPane.getNameableList().setSelectedIndex(selectedIndex + 1);
listControlPane.getNameableList().ensureIndexIsVisible(selectedIndex + 1);
}
}
public void onSortItem(boolean isAtoZ) {
onSortItem(isAtoZ, listControlPane.getNameableList());
}
public void onSortItem(boolean isAtoZ, JNameEdList nameEdList) {
// p:选中的值.
Object selectedValue = nameableList.getSelectedValue();
Object selectedValue = nameEdList.getSelectedValue();
DefaultListModel listModel = (DefaultListModel) nameableList
DefaultListModel listModel = (DefaultListModel) nameEdList
.getModel();
Nameable[] nameableArray = new Nameable[listModel.getSize()];
if (nameableArray.length <= 0) {
@ -156,12 +158,12 @@ public class CommonShortCutHandlers {
// p:需要选中以前的那个值.
if (selectedValue != null) {
nameableList.setSelectedValue(selectedValue, true);
nameEdList.setSelectedValue(selectedValue, true);
}
listControlPane.checkButtonEnabled();
// p:需要repaint.
nameableList.repaint();
nameEdList.repaint();
}
private String createUnrepeatedCopyName(String suffix) {

144
designer-base/src/main/java/com/fr/design/gui/controlpane/ListControlPaneHelper.java

@ -4,18 +4,41 @@ import com.fr.design.beans.BasicBeanPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ilist.JNameEdList;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.gui.ilist.UINameEdList;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.os.impl.PopupDialogSaveAction;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.form.event.Listener;
import com.fr.general.NameObject;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import com.fr.stable.os.support.OSSupportCenter;
import javax.swing.DefaultListModel;
import javax.swing.JOptionPane;
import javax.swing.JList;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 存放一些公用的方法
* Created by plough on 2018/8/13.
*/
class ListControlPaneHelper {
private static final int EDIT_RANGE = 25; // 编辑按钮的x坐标范围
private ListControlPaneProvider listControlPane;
private ListControlPaneHelper(ListControlPaneProvider listControlPane) {
@ -110,4 +133,123 @@ class ListControlPaneHelper {
}
protected void popupEditDialog(Point mousePos, UINameEdList nameableList, UIControlPane controlPane) {
int editingIndex = nameableList.getSelectedIndex();
Rectangle currentCellBounds = nameableList.getCellBounds(editingIndex, editingIndex);
if (editingIndex < 0 || (mousePos != null && !currentCellBounds.contains(mousePos))) {
return;
}
Window popupEditDialog = controlPane.getPopupEditDialog();
popupEditDialog.setLocation(getPopupDialogLocation(nameableList, popupEditDialog));
if (popupEditDialog instanceof UIControlPane.PopupEditDialog) {
((UIControlPane.PopupEditDialog) popupEditDialog).setTitle(getSelectedName());
}
popupEditDialog.setVisible(true);
PopupDialogSaveAction osBasedAction = OSSupportCenter.getAction(PopupDialogSaveAction.class);
osBasedAction.register(controlPane, popupEditDialog);
}
private Point getPopupDialogLocation(UINameEdList nameableList, Window popupEditDialog) {
Point resultPos = new Point(0, 0);
Point listPos = nameableList.getLocationOnScreen();
resultPos.x = listPos.x - popupEditDialog.getWidth();
resultPos.y = listPos.y + (nameableList.getSelectedIndex() - 1) * EDIT_RANGE;
// 当对象在屏幕上的位置比较靠下时,往下移动弹窗至与属性面板平齐
Window frame = DesignerContext.getDesignerFrame();
// 不能太低
int maxY = frame.getLocationOnScreen().y + frame.getHeight() - popupEditDialog.getHeight();
if (resultPos.y > maxY) {
resultPos.y = maxY;
}
// 也不能太高
int minY = frame.getLocationOnScreen().y + EDIT_RANGE;
if (resultPos.y < minY) {
resultPos.y = minY;
}
// 当在左侧显示不下时,在右侧弹出弹窗
if (resultPos.x < 0) {
resultPos.x = listPos.x + nameableList.getParent().getWidth();
}
// 如果右侧显示不下,可以向左移动
int maxX = frame.getLocationOnScreen().x + frame.getWidth() - popupEditDialog.getWidth() - EDIT_RANGE;
if (resultPos.x > maxX) {
resultPos.x = maxX;
}
return resultPos;
}
/*
* UINameEdList的鼠标事件
*/
protected MouseListener getListMouseListener(UINameEdList nameableList, UIControlPane controlPane) {
return new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent evt) {
nameableList.stopEditing();
if (evt.getClickCount() >= 2
&& SwingUtilities.isLeftMouseButton(evt) && evt.getX() > EDIT_RANGE) {
nameableList.editItemAt(nameableList.getSelectedIndex());
} else if (SwingUtilities.isLeftMouseButton(evt) && evt.getX() <= EDIT_RANGE) {
popupEditDialog(evt.getPoint(), nameableList, controlPane);
}
// peter:处理右键的弹出菜单
if (!SwingUtilities.isRightMouseButton(evt)) {
return;
}
// peter: 注意,在checkButtonEnabled()方法里面,设置了所有的Action的Enabled.
checkButtonEnabled();
// p:右键菜单.
JPopupMenu popupMenu = new JPopupMenu();
for (ShortCut4JControlPane sj : listControlPane.getShorts()) {
sj.getShortCut().intoJPopupMenu(popupMenu);
}
// peter: 只有弹出菜单有子菜单的时候,才需要弹出来.
GUICoreUtils.showPopupMenu(popupMenu, nameableList, evt.getX() - 1,
evt.getY() - 1);
}
@Override
public void mouseClicked(MouseEvent e) {
JList list = (JList) e.getSource();
if (list.locationToIndex(e.getPoint()) == -1 && !e.isShiftDown()
&& !isMenuShortcutKeyDown(e)) {
list.clearSelection();
}
}
private boolean isMenuShortcutKeyDown(InputEvent event) {
return (event.getModifiers() & Toolkit.getDefaultToolkit()
.getMenuShortcutKeyMask()) != 0;
}
@Override
public void mouseMoved(MouseEvent e) {
}
};
}
public Map<String, List<NameObject>> processCatalog(List<NameObject> nameObjectList) {
Map<String, List<NameObject>> map = new HashMap<>();
for (NameObject nameObject : nameObjectList) {
Listener listener = (Listener) nameObject.getObject();
if (StringUtils.isNotEmpty(listener.getName())) {
nameObject.setName(listener.getName());
}
List<NameObject> list = map.computeIfAbsent(listener.getEventName(), k -> new ArrayList<>());
list.add(nameObject);
}
return map;
}
}

12
designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java

@ -49,7 +49,7 @@ import java.awt.event.WindowEvent;
/**
* Created by plough on 2017/7/21.
*/
abstract class UIControlPane extends JControlPane {
public abstract class UIControlPane extends JControlPane {
private UIToolbar topToolBar;
protected Window popupEditDialog;
private static final int TOP_TOOLBAR_HEIGHT = 20;
@ -78,7 +78,7 @@ abstract class UIControlPane extends JControlPane {
initCardPane();
if (isNewStyle()) {
getPopupEditDialog(cardPane);
createPopupEditDialog(cardPane);
this.add(getLeftPane(), BorderLayout.CENTER);
this.setBorder(BorderFactory.createEmptyBorder(10, 10, 15, 10));
} else {
@ -100,7 +100,11 @@ abstract class UIControlPane extends JControlPane {
this.checkButtonEnabled();
}
private void getPopupEditDialog(JPanel cardPane) {
protected Window getPopupEditDialog(){
return this.popupEditDialog;
}
private void createPopupEditDialog(JPanel cardPane) {
popupEditDialog = new PopupEditDialog(cardPane);
}
@ -400,4 +404,4 @@ abstract class UIControlPane extends JControlPane {
return new Dimension(super.getPreferredSize().width, 28);
}
}
}
}

130
designer-base/src/main/java/com/fr/design/gui/controlpane/UIListControlPane.java

@ -6,32 +6,18 @@ import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilist.JNameEdList;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.gui.ilist.UINameEdList;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.os.impl.PopupDialogSaveAction;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import com.fr.stable.os.support.OSSupportCenter;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.BorderLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
@ -41,11 +27,8 @@ import java.lang.reflect.InvocationTargetException;
public abstract class UIListControlPane extends UIControlPane implements ListControlPaneProvider {
private static final String LIST_NAME = "UIControl_List";
private static final int EDIT_RANGE = 25; // 编辑按钮的x坐标范围
protected UINameEdList nameableList;
private int editingIndex;
protected String selectedName;
protected boolean isPopulating = false;
private CommonShortCutHandlers commonHandlers;
private ListControlPaneHelper helper;
@ -93,7 +76,7 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon
nameableList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
nameableList.addMouseListener(getListMouseListener());
nameableList.addMouseListener(getHelper().getListMouseListener(nameableList, this));
nameableList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
// richie:避免多次update和populate大大降低效率
@ -139,7 +122,7 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon
saveSettings();
}
};
nameEdList.setCellRenderer(new UINameableListCellRenderer(this));
nameEdList.setCellRenderer(new UINameableListCellRenderer(this.isNewStyle(), this.creators));
return nameEdList;
}
@ -181,13 +164,6 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon
}
/**
* 获取选中的名字
*/
public String getSelectedName() {
return getHelper().getSelectedName();
}
/**
* 添加 Nameable
*
@ -209,51 +185,10 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon
protected void popupEditDialog(Point mousePos) {
if (isNewStyle()) {
Rectangle currentCellBounds = nameableList.getCellBounds(editingIndex, editingIndex);
if (editingIndex < 0 || (mousePos != null && !currentCellBounds.contains(mousePos))) {
return;
}
popupEditDialog.setLocation(getPopupDialogLocation());
if (popupEditDialog instanceof PopupEditDialog) {
((PopupEditDialog)popupEditDialog).setTitle(getSelectedName());
}
popupEditDialog.setVisible(true);
PopupDialogSaveAction osBasedAction = OSSupportCenter.getAction(PopupDialogSaveAction.class);
osBasedAction.register(this, popupEditDialog);
getHelper().popupEditDialog(mousePos, nameableList, this);
}
}
private Point getPopupDialogLocation() {
Point resultPos = new Point(0, 0);
Point listPos = nameableList.getLocationOnScreen();
resultPos.x = listPos.x - popupEditDialog.getWidth();
resultPos.y = listPos.y + (nameableList.getSelectedIndex() - 1) * EDIT_RANGE;
// 当对象在屏幕上的位置比较靠下时,往下移动弹窗至与属性面板平齐
Window frame = DesignerContext.getDesignerFrame();
// 不能太低
int maxY = frame.getLocationOnScreen().y + frame.getHeight() - popupEditDialog.getHeight();
if (resultPos.y > maxY) {
resultPos.y = maxY;
}
// 也不能太高
int minY = frame.getLocationOnScreen().y + EDIT_RANGE;
if (resultPos.y < minY) {
resultPos.y = minY;
}
// 当在左侧显示不下时,在右侧弹出弹窗
if (resultPos.x < 0) {
resultPos.x = listPos.x + nameableList.getParent().getWidth();
}
// 如果右侧显示不下,可以向左移动
int maxX = frame.getLocationOnScreen().x + frame.getWidth() - popupEditDialog.getWidth() - EDIT_RANGE;
if (resultPos.x > maxX) {
resultPos.x = maxX;
}
return resultPos;
}
/**
* 生成不重复的名字
@ -301,65 +236,6 @@ public abstract class UIListControlPane extends UIControlPane implements ListCon
return getModel().getSize() > 0 && nameableList.getSelectedIndex() != -1;
}
/*
* UINameEdList的鼠标事件
*/
private MouseListener getListMouseListener() {
return new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent evt) {
nameableList.stopEditing();
if (evt.getClickCount() >= 2
&& SwingUtilities.isLeftMouseButton(evt) && evt.getX() > EDIT_RANGE) {
editingIndex = nameableList.getSelectedIndex();
selectedName = nameableList.getNameAt(editingIndex);
nameableList.editItemAt(nameableList.getSelectedIndex());
} else if (SwingUtilities.isLeftMouseButton(evt) && evt.getX() <= EDIT_RANGE) {
editingIndex = nameableList.getSelectedIndex();
selectedName = nameableList.getNameAt(editingIndex);
popupEditDialog(evt.getPoint());
}
// peter:处理右键的弹出菜单
if (!SwingUtilities.isRightMouseButton(evt)) {
return;
}
// peter: 注意,在checkButtonEnabled()方法里面,设置了所有的Action的Enabled.
checkButtonEnabled();
// p:右键菜单.
JPopupMenu popupMenu = new JPopupMenu();
for (ShortCut4JControlPane sj : getShorts()) {
sj.getShortCut().intoJPopupMenu(popupMenu);
}
// peter: 只有弹出菜单有子菜单的时候,才需要弹出来.
GUICoreUtils.showPopupMenu(popupMenu, nameableList, evt.getX() - 1,
evt.getY() - 1);
}
@Override
public void mouseClicked(MouseEvent e) {
JList list = (JList) e.getSource();
if (list.locationToIndex(e.getPoint()) == -1 && !e.isShiftDown()
&& !isMenuShortcutKeyDown(e)) {
list.clearSelection();
}
}
private boolean isMenuShortcutKeyDown(InputEvent event) {
return (event.getModifiers() & Toolkit.getDefaultToolkit()
.getMenuShortcutKeyMask()) != 0;
}
@Override
public void mouseMoved(MouseEvent e) {
}
};
}
/**
* 检查按钮可用状态 Check button enabled.

550
designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java

@ -0,0 +1,550 @@
package com.fr.design.gui.controlpane;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.constants.UIConstants;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.ilist.JNameEdList;
import com.fr.design.gui.ilist.ListModelElement;
import com.fr.design.gui.ilist.ModNameActionListener;
import com.fr.design.gui.ilist.UIList;
import com.fr.design.gui.ilist.UINameEdList;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.widget.EventCreator;
import com.fr.form.event.Listener;
import com.fr.form.ui.Widget;
import com.fr.general.NameObject;
import com.fr.report.web.util.ReportEngineEventMapping;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Nameable;
import com.fr.stable.StringUtils;
import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JPanel;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
/**
* Created by kerry on 5/31/21
*/
public abstract class UIListGroupControlPane extends UIControlPane implements ListControlPaneProvider {
private boolean isPopulating = false;
private UINameEdList selectNameEdList;
private Map<String, ListWrapperPane> nameEdListMap = new HashMap<>();
private CommonShortCutHandlers commonHandlers;
private ListControlPaneHelper helper;
private JPanel contentPane;
public JPanel getContentPane() {
return contentPane;
}
private ListControlPaneHelper getHelper() {
if (helper == null) {
helper = ListControlPaneHelper.newInstance(this);
}
return helper;
}
private CommonShortCutHandlers getCommonHandlers() {
if (commonHandlers == null) {
commonHandlers = CommonShortCutHandlers.newInstance(this);
}
return commonHandlers;
}
public boolean isPopulating() {
return isPopulating;
}
@Override
protected void initLeftPane(JPanel leftPane) {
leftPane.add(new UIScrollPane(contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 0)), BorderLayout.CENTER);
}
protected void refreshPane(Widget widget, NameableCreator[] creators) {
refreshContentPane(widget.supportedEvents());
refreshNameableCreator(creators);
populateNameObjects(widget);
}
private void refreshContentPane(String[] supportedEvents) {
for (String event : supportedEvents) {
if (nameEdListMap.containsKey(event)) {
continue;
}
UINameEdList list = createJNameList(event);
ListWrapperPane wrapperPane = new ListWrapperPane(switchLang(event), list);
if (this.selectNameEdList == null) {
this.selectNameEdList = wrapperPane.getNameEdList();
}
contentPane.add(wrapperPane);
nameEdListMap.put(event, wrapperPane);
}
contentPane.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
super.mousePressed(e);
if (selectNameEdList != null) {
selectNameEdList.stopEditing();
}
}
});
}
protected void populateNameObjects(Widget widget) {
ArrayList<NameObject> nameObjectList = new ArrayList<>();
for (int i = 0, size = widget.getListenerSize(); i < size; i++) {
Listener listener = widget.getListener(i);
if (!listener.isDefault()) {
nameObjectList.add(i, new NameObject(switchLang(listener.getEventName()) + (i + 1), listener));
}
}
populate(getHelper().processCatalog(nameObjectList));
checkButtonEnabled();
this.repaint();
}
private void populate(Map<String, List<NameObject>> map) {
isPopulating = true; // 加一个标识位,避免切换单元格时,触发 saveSettings
Iterator<Map.Entry<String, List<NameObject>>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, List<NameObject>> entry = iterator.next();
List<NameObject> valueList = entry.getValue();
ListWrapperPane eventListWrapperPane = nameEdListMap.get(entry.getKey());
populateChildNameList(eventListWrapperPane.getNameEdList(), valueList.toArray(new NameObject[valueList.size()]));
}
this.checkButtonEnabled();
refreshEventListWrapperPane();
this.checkGroupPaneSize();
isPopulating = false;
}
private void refreshEventListWrapperPane() {
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
ListWrapperPane eventListWrapperPane = entry.getValue();
UINameEdList nameEdList = eventListWrapperPane.getNameEdList();
int listSize = nameEdList.getModel().getSize();
if (this.selectNameEdList.getModel().getSize() == 0 && listSize > 0) {
this.selectNameEdList = nameEdList;
}
eventListWrapperPane.setVisible(listSize > 0);
}
if (this.selectNameEdList != null) {
this.selectNameEdList.setSelectedIndex(0);
}
this.repaint();
}
private void populateChildNameList(UINameEdList nameableList, Nameable[] nameableArray) {
nameableList.getCellEditor().stopCellEditing();
DefaultListModel listModel = (DefaultListModel) nameableList.getModel();
listModel.removeAllElements();
if (ArrayUtils.isEmpty(nameableArray)) {
isPopulating = false;
return;
}
listModel.setSize(nameableArray.length);
for (int i = 0; i < nameableArray.length; i++) {
listModel.set(i, new ListModelElement(nameableArray[i]));
}
}
private UINameEdList createJNameList(String text) {
UINameEdList nameEdList = new UINameEdList(new DefaultListModel()) {
@Override
protected void doAfterLostFocus() {
((JControlUpdatePane) controlUpdatePane).update();
}
@Override
protected void doAfterStopEditing() {
saveSettings();
}
};
nameEdList.setCellRenderer(new UINameableListCellRenderer(true, this.creators));
nameEdList.setName(text);
nameEdList.setSelectionBackground(UIConstants.ATTRIBUTE_PRESS);
nameEdList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
nameEdList.addMouseListener(new MouseAdapter() {
@Override
public void mouseReleased(MouseEvent e) {
selectNameEdList = nameEdList;
updateUINameListSelect();
}
});
nameEdList.addMouseListener(getHelper().getListMouseListener(nameEdList, this));
nameEdList.addModNameActionListener(new ModNameActionListener() {
@Override
public void nameModed(int index, String oldName, String newName) {
checkGroupPaneSize();
saveSettings();
}
});
nameEdList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
// richie:避免多次update和populate大大降低效率
if (!evt.getValueIsAdjusting()) {
// shoc 切换的时候加检验
if (hasInvalid(false)) {
return;
}
((JControlUpdatePane) UIListGroupControlPane.this.controlUpdatePane).update();
((JControlUpdatePane) UIListGroupControlPane.this.controlUpdatePane).populate();
UIListGroupControlPane.this.checkButtonEnabled();
}
}
});
nameEdList.getModel().addListDataListener(new ListDataListener() {
@Override
public void intervalAdded(ListDataEvent e) {
saveSettings();
}
@Override
public void intervalRemoved(ListDataEvent e) {
saveSettings();
}
@Override
public void contentsChanged(ListDataEvent e) {
saveSettings();
}
});
return nameEdList;
}
private void updateUINameListSelect() {
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
if (nameEdList != selectNameEdList) {
nameEdList.clearSelection();
}
}
}
@Override
public void checkButtonEnabled() {
getHelper().checkButtonEnabled();
}
private String switchLang(String eventName) {
// 在 properties 文件中找到相应的 key 值
String localeKey = ReportEngineEventMapping.getLocaleName(eventName);
return com.fr.design.i18n.Toolkit.i18nText(localeKey);
}
/**
* 生成不重复的名字
*
* @param prefix 名字前缀
* @return 名字
*/
@Override
public String createUnrepeatedName(String prefix) {
return getCommonHandlers().createUnrepeatedName(prefix);
}
private void updateSelectedNameList(NameableCreator creator) {
String eventName = ((EventCreator) creator).getEventName();
ListWrapperPane wrapperPane = nameEdListMap.get(eventName);
wrapperPane.setVisible(true);
setSelectNameEdList(wrapperPane.getNameEdList());
}
private void setSelectNameEdList(UINameEdList nameEdList) {
if (this.selectNameEdList != null) {
this.selectNameEdList.clearSelection();
}
this.selectNameEdList = nameEdList;
}
@Override
public void onAddItem(NameableCreator creator) {
updateSelectedNameList(creator);
getCommonHandlers().onAddItem(creator);
checkGroupPaneSize();
}
@Override
public void onRemoveItem() {
getCommonHandlers().onRemoveItem();
refreshEventListWrapperPane();
checkGroupPaneSize();
}
@Override
public void onCopyItem() {
getCommonHandlers().onCopyItem();
checkGroupPaneSize();
}
private void checkGroupPaneSize() {
int width = 180;
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
ListWrapperPane wrapperPane = entry.getValue();
UIList uiList = wrapperPane.getNameEdList();
width = Math.max(width, calculateUIListMaxCellWidth(uiList.getModel(), uiList.getFontMetrics(uiList.getFont())));
}
iterator = nameEdListMap.entrySet().iterator();
width += 40;
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
ListWrapperPane wrapperPane = entry.getValue();
UIList uiList = wrapperPane.getNameEdList();
uiList.setFixedCellWidth(width);
}
}
private int calculateUIListMaxCellWidth(ListModel model, FontMetrics fontMetrics) {
int width = 0;
for (int i = 0; i < model.getSize(); i++) {
Object element = model.getElementAt(i);
if (element != null) {
String text;
if (element instanceof ListModelElement) {
text = ((ListModelElement) element).wrapper.getName();
} else {
text = element.toString();
}
width = Math.max(width, fontMetrics.stringWidth(text));
}
}
return width;
}
@Override
public void onMoveUpItem() {
getCommonHandlers().onMoveUpItem();
}
@Override
public void onMoveDownItem() {
getCommonHandlers().onMoveDownItem();
}
@Override
public void onSortItem(boolean isAtoZ) {
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
getCommonHandlers().onSortItem(isAtoZ, nameEdList);
}
}
@Override
public boolean isItemSelected() {
return getModel().getSize() > 0 && getSelectedIndex() != -1;
}
@Override
protected JPanel createControlUpdatePane() {
return JControlUpdatePane.newInstance(this);
}
@Override
public Nameable[] update() {
java.util.List<Nameable> res = new java.util.ArrayList<Nameable>();
getControlUpdatePane().update();
Iterator<Map.Entry<String, ListWrapperPane>> iterator = nameEdListMap.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, ListWrapperPane> entry = iterator.next();
UINameEdList nameEdList = entry.getValue().getNameEdList();
DefaultListModel listModel = (DefaultListModel) nameEdList.getModel();
for (int i = 0, len = listModel.getSize(); i < len; i++) {
res.add(((ListModelElement) listModel.getElementAt(i)).wrapper);
}
}
return res.toArray(new Nameable[0]);
}
@Override
public abstract NameableCreator[] createNameableCreators();
@Override
public abstract void saveSettings();
public BasicBeanPane createPaneByCreators(NameableCreator creator) {
try {
return creator.getUpdatePane().newInstance();
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
public BasicBeanPane createPaneByCreators(NameableCreator creator, String string) {
Constructor constructor = null;
try {
constructor = creator.getUpdatePane().getDeclaredConstructor(new Class[]{String.class});
constructor.setAccessible(true);
return (BasicBeanPane) constructor.newInstance(string);
} catch (NoSuchMethodException e) {
throw new RuntimeException(e);
} catch (InstantiationException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
} catch (InvocationTargetException e) {
throw new RuntimeException(e);
}
}
@Override
public DefaultListModel getModel() {
if (this.selectNameEdList == null) {
return new DefaultListModel();
}
return (DefaultListModel) this.selectNameEdList.getModel();
}
/**
* 检查是否符合规范
*
* @throws Exception
*/
@Override
public void checkValid() throws Exception {
((JControlUpdatePane) this.controlUpdatePane).checkValid();
}
@Override
public boolean hasInvalid(boolean isAdd) {
return getHelper().hasInvalid(isAdd);
}
public void addNameable(Nameable nameable, int index) {
getHelper().addNameable(nameable, index);
popupEditDialog();
}
/**
* 设置选中项
*
* @param index 选中项的序列号
*/
public void setSelectedIndex(int index) {
if (this.selectNameEdList != null) {
this.selectNameEdList.setSelectedIndex(index);
}
}
@Override
public int getSelectedIndex() {
if (this.selectNameEdList == null) {
return -1;
}
return this.selectNameEdList.getSelectedIndex();
}
@Override
public ListModelElement getSelectedValue() {
if (this.selectNameEdList == null) {
return null;
}
return (ListModelElement) this.selectNameEdList.getSelectedValue();
}
@Override
public JControlUpdatePane getControlUpdatePane() {
return (JControlUpdatePane) controlUpdatePane;
}
@Override
public JNameEdList getNameableList() {
return this.selectNameEdList;
}
private void popupEditDialog() {
getHelper().popupEditDialog(null, this.selectNameEdList, this);
}
protected String getWrapperLabelText() {
return StringUtils.EMPTY;
}
private class ListWrapperPane extends JPanel {
private UINameEdList nameEdList;
public ListWrapperPane(String labelText, UINameEdList nameEdList) {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
UILabel label = new UILabel(labelText + getWrapperLabelText()) {
@Override
public void paint(Graphics g) {
((Graphics2D) g).setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.8f));
super.paint(g);
}
};
label.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0));
label.setOpaque(true);
label.setBackground(Color.WHITE);
label.setForeground(Color.decode("#333334"));
label.setFont(label.getFont().deriveFont(11F));
label.setPreferredSize(new Dimension(224, 26));
this.nameEdList = nameEdList;
this.add(label, BorderLayout.NORTH);
this.add(this.nameEdList, BorderLayout.CENTER);
}
public UINameEdList getNameEdList() {
return this.nameEdList;
}
}
}

24
designer-base/src/main/java/com/fr/design/gui/controlpane/UINameableListCellRenderer.java

@ -1,12 +1,8 @@
package com.fr.design.gui.controlpane;
import com.fr.base.BaseUtils;
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.ilist.ListModelElement;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.stable.Nameable;
import sun.swing.DefaultLookup;
@ -14,8 +10,6 @@ import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Nameable的ListCellRenerer
@ -32,12 +26,14 @@ public class UINameableListCellRenderer extends
private static final int BUTTON_WIDTH = 25;
private UILabel editButton; // "编辑按钮",实际上是一个 UILabel,由列表项(UIListControlPane)统一处理点击事件
private UILabel label;
private UIListControlPane listControlPane;
private boolean isNewStyle;
private NameableCreator[] creators;
private Color initialLabelForeground;
public UINameableListCellRenderer(UIListControlPane listControlPane) {
public UINameableListCellRenderer( boolean isNewStyle, NameableCreator[] creators) {
super();
this.listControlPane = listControlPane;
this.isNewStyle = isNewStyle;
this.creators = creators;
initComponents();
setOpaque(true);
setBorder(getNoFocusBorder());
@ -50,7 +46,7 @@ public class UINameableListCellRenderer extends
return new Dimension(BUTTON_WIDTH, BUTTON_WIDTH);
}
};
editButton.setIcon(listControlPane.isNewStyle() ? UIConstants.LIST_EDIT_ICON : UIConstants.CPT_ICON);
editButton.setIcon(isNewStyle ? UIConstants.LIST_EDIT_ICON : UIConstants.CPT_ICON);
editButton.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1, UIConstants.LIST_ITEM_SPLIT_LINE));
editButton.setHorizontalAlignment(SwingConstants.CENTER);
label = new UILabel();
@ -92,7 +88,7 @@ public class UINameableListCellRenderer extends
setBackground(bg == null ? list.getSelectionBackground() : bg);
setForeground(fg == null ? list.getSelectionForeground() : fg);
label.setForeground(Color.WHITE);
if (listControlPane.isNewStyle()) {
if (isNewStyle) {
editButton.setIcon(UIConstants.LIST_EDIT_WHITE_ICON);
}
}
@ -100,7 +96,7 @@ public class UINameableListCellRenderer extends
setBackground(list.getBackground());
setForeground(list.getForeground());
label.setForeground(initialLabelForeground);
if (listControlPane.isNewStyle()) {
if (isNewStyle) {
editButton.setIcon(UIConstants.LIST_EDIT_ICON);
}
}
@ -114,7 +110,7 @@ public class UINameableListCellRenderer extends
Nameable wrappee = ((ListModelElement) value).wrapper;
this.setText(((ListModelElement) value).wrapper.getName());
for (NameableCreator creator : listControlPane.creators()) {
for (NameableCreator creator : creators) {
if (creator.menuIcon() != null && creator.acceptObject2Populate(wrappee) != null) {
this.setToolTipText(creator.createTooltip());
break;
@ -124,4 +120,4 @@ public class UINameableListCellRenderer extends
return this;
}
}
}

10
designer-base/src/main/java/com/fr/design/locale/impl/BbsRegisterMark.java

@ -16,11 +16,11 @@ import java.util.Map;
public class BbsRegisterMark implements LocaleMark<String> {
private final Map<Locale, String> map = new HashMap<>();
private static final String BBS_REGISTER_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.register");
private static final String BBS_REGISTER_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.register");
private static final String BBS_REGISTER_EN = CloudCenter.getInstance().acquireUrlByKind("bbs.register.en_US");
private static final String BBS_REGISTER_KR = CloudCenter.getInstance().acquireUrlByKind("bbs.register.en_US");
private static final String BBS_REGISTER_JP = CloudCenter.getInstance().acquireUrlByKind("bbs.register.en_US");
private static final String BBS_REGISTER_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.register", "http://id.fanruan.com/register/register.php?clueSource=activityfr");
private static final String BBS_REGISTER_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.register", "http://id.fanruan.com/register/register.php?clueSource=activityfr");
private static final String BBS_REGISTER_EN = CloudCenter.getInstance().acquireUrlByKind("bbs.register.en_US", "https://id.fanruan.com/en/register/register.php");
private static final String BBS_REGISTER_KR = CloudCenter.getInstance().acquireUrlByKind("bbs.register.en_US", "https://id.fanruan.com/en/register/register.php");
private static final String BBS_REGISTER_JP = CloudCenter.getInstance().acquireUrlByKind("bbs.register.en_US", "https://id.fanruan.com/en/register/register.php");
public BbsRegisterMark() {
map.put(Locale.CHINA, BBS_REGISTER_CN);

10
designer-base/src/main/java/com/fr/design/locale/impl/BbsResetMark.java

@ -16,11 +16,11 @@ import java.util.Map;
public class BbsResetMark implements LocaleMark<String> {
private final Map<Locale, String> map = new HashMap<>();
private static final String BBS_RESET_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.reset");
private static final String BBS_RESET_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.reset");
private static final String BBS_RESET_EN = CloudCenter.getInstance().acquireUrlByKind("bbs.reset.en_US");
private static final String BBS_RESET_KR = CloudCenter.getInstance().acquireUrlByKind("bbs.reset.en_US");
private static final String BBS_RESET_JP = CloudCenter.getInstance().acquireUrlByKind("bbs.reset.en_US");
private static final String BBS_RESET_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.reset", "http://id.fanruan.com/forget/forget.php?clue=activityfr");
private static final String BBS_RESET_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.reset", "http://id.fanruan.com/forget/forget.php?clue=activityfr");
private static final String BBS_RESET_EN = CloudCenter.getInstance().acquireUrlByKind("bbs.reset.en_US", "https://id.fanruan.com/en/forget/forget.php");
private static final String BBS_RESET_KR = CloudCenter.getInstance().acquireUrlByKind("bbs.reset.en_US", "https://id.fanruan.com/en/forget/forget.php");
private static final String BBS_RESET_JP = CloudCenter.getInstance().acquireUrlByKind("bbs.reset.en_US", "https://id.fanruan.com/en/forget/forget.php");
public BbsResetMark() {
map.put(Locale.CHINA, BBS_RESET_CN);

10
designer-base/src/main/java/com/fr/design/locale/impl/BbsSpaceMark.java

@ -16,11 +16,11 @@ import java.util.Map;
public class BbsSpaceMark implements LocaleMark<String> {
private final Map<Locale, String> map = new HashMap<>();
private static final String BBS_SPACE_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.default");
private static final String BBS_SPACE_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.default");
private static final String BBS_SPACE_EN = CloudCenter.getInstance().acquireUrlByKind("bbs.default.en_US");
private static final String BBS_SPACE_KR = CloudCenter.getInstance().acquireUrlByKind("bbs.default.en_US");
private static final String BBS_SPACE_JP = CloudCenter.getInstance().acquireUrlByKind("bbs.default.en_US");
private static final String BBS_SPACE_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.default", "http://bbs.fanruan.com/home.php?mod=space&do=pm");
private static final String BBS_SPACE_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.default", "http://bbs.fanruan.com/home.php?mod=space&do=pm");
private static final String BBS_SPACE_EN = CloudCenter.getInstance().acquireUrlByKind("bbs.default.en_US", "https://community.finereport.com/home.php?mod=space&do=pm");
private static final String BBS_SPACE_KR = CloudCenter.getInstance().acquireUrlByKind("bbs.default.en_US", "https://community.finereport.com/home.php?mod=space&do=pm");
private static final String BBS_SPACE_JP = CloudCenter.getInstance().acquireUrlByKind("bbs.default.en_US", "https://community.finereport.com/home.php?mod=space&do=pm");
public BbsSpaceMark() {
map.put(Locale.CHINA, BBS_SPACE_CN);

2
designer-base/src/main/java/com/fr/design/locale/impl/BugNeedMark.java

@ -14,7 +14,7 @@ import java.util.Map;
*/
public class BugNeedMark implements LocaleMark<String> {
private Map<Locale, String> map = new HashMap<>();
private static final String TW_BUG_AND_NEEDS = CloudCenter.getInstance().acquireUrlByKind("bbs.bug.needs.zh_TW");
private static final String TW_BUG_AND_NEEDS = CloudCenter.getInstance().acquireUrlByKind("bbs.bug.needs.zh_TW", "https://fanruanhelp.zendesk.com/hc/zh-tw/requests/new");
public BugNeedMark() {
map.put(Locale.TAIWAN, TW_BUG_AND_NEEDS);

4
designer-base/src/main/java/com/fr/design/locale/impl/TechSupportMark.java

@ -14,8 +14,8 @@ import java.util.Map;
*/
public class TechSupportMark implements LocaleMark<String> {
private Map<Locale, String> map = new HashMap<>();
private static final String EN_TECH_SUPPORT = CloudCenter.getInstance().acquireUrlByKind("bbs.tech.support.en_US");
private static final String TW_TECH_SUPPORT = CloudCenter.getInstance().acquireUrlByKind("bbs.tech.support.zh_TW");
private static final String EN_TECH_SUPPORT = CloudCenter.getInstance().acquireUrlByKind("bbs.tech.support.en_US", "https://fanruanhelp.zendesk.com/hc/en-us");
private static final String TW_TECH_SUPPORT = CloudCenter.getInstance().acquireUrlByKind("bbs.tech.support.zh_TW", "https://fanruanhelp.zendesk.com/hc/zh-tw");
public TechSupportMark() {
map.put(Locale.US, EN_TECH_SUPPORT);

10
designer-base/src/main/java/com/fr/design/locale/impl/UserInfoMark.java

@ -15,11 +15,11 @@ import java.util.Map;
public class UserInfoMark implements LocaleMark<String> {
private Map<Locale, String> map = new HashMap<>();
private static final String CN_LOGIN_HTML = CloudCenter.getInstance().acquireUrlByKind("frlogin.cn");
private static final String EN_LOGIN_HTML = CloudCenter.getInstance().acquireUrlByKind("frlogin.en");
private static final String TW_LOGIN_HTML = CloudCenter.getInstance().acquireUrlByKind("frlogin.tw");
private static final String JP_LOGIN_HTML = CloudCenter.getInstance().acquireUrlByKind("frlogin.jp");
private static final String KR_LOGIN_HTML = CloudCenter.getInstance().acquireUrlByKind("frlogin.kr");
private static final String CN_LOGIN_HTML = CloudCenter.getInstance().acquireUrlByKind("frlogin.cn", "http://www.finereport.com/product/active?utm_source=direct&utm_medium=exe");
private static final String EN_LOGIN_HTML = CloudCenter.getInstance().acquireUrlByKind("frlogin.en", "http://www.finereport.com/en/activation");
private static final String TW_LOGIN_HTML = CloudCenter.getInstance().acquireUrlByKind("frlogin.tw", "http://www.finereport.com/tw/products/frlogin");
private static final String JP_LOGIN_HTML = CloudCenter.getInstance().acquireUrlByKind("frlogin.jp", "http://www.finereport.com/jp/trial/");
private static final String KR_LOGIN_HTML = CloudCenter.getInstance().acquireUrlByKind("frlogin.kr", "http://www.finereport.com/kr/activation/");
public UserInfoMark() {
map.put(Locale.CHINA, CN_LOGIN_HTML);

6
designer-base/src/main/java/com/fr/design/locale/impl/VideoMark.java

@ -15,9 +15,9 @@ import java.util.Map;
public class VideoMark implements LocaleMark<String> {
private Map<Locale, String> map = new HashMap<>();
private static final String VIDEO_EN = CloudCenter.getInstance().acquireUrlByKind("bbs.video.en_US");
private static final String VIDEO_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.video.zh_CN");
private static final String VIDEO_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.video.zh_TW");
private static final String VIDEO_EN = CloudCenter.getInstance().acquireUrlByKind("bbs.video.en_US", "http://www.finereport.com/en/Learning-path");
private static final String VIDEO_CN = CloudCenter.getInstance().acquireUrlByKind("bbs.video.zh_CN", "https://edu.fanruan.com/video?class1=16&class2=0");
private static final String VIDEO_TW = CloudCenter.getInstance().acquireUrlByKind("bbs.video.zh_TW", "http://www.finereport.com/tw/video");
public VideoMark() {
map.put(Locale.CHINA, VIDEO_CN);

46
designer-base/src/main/java/com/fr/design/login/AbstractDesignerSSO.java

@ -0,0 +1,46 @@
package com.fr.design.login;
import com.fr.base.FRContext;
import com.fr.design.DesignerEnvManager;
import com.fr.design.actions.UpdateAction;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.utils.BrowseUtils;
import java.awt.event.ActionEvent;
import java.util.HashMap;
import java.util.Map;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/6/7
*/
public abstract class AbstractDesignerSSO extends UpdateAction {
@Override
public void actionPerformed(ActionEvent event) {
String url = getJumpUrl();
DesignerEnvManager manager = DesignerEnvManager.getEnvManager();
int uid = manager.getDesignerLoginUid();
if (uid > 0) {
String ssoUrl = DesignerLoginUtils.generateDesignerSSOUrl(url);
BrowseUtils.browser(ssoUrl);
} else {
if (!SupportOSImpl.DESIGNER_LOGIN.support() || !FRContext.isChineseEnv()) {
BrowseUtils.browser(url);
return;
}
boolean loginRemindBeforeJumpBBS = manager.isLoginRemindBeforeJumpBBS();
if (loginRemindBeforeJumpBBS) {
Map<String, String> params = new HashMap<>();
params.put("bbsJumpUrl", url);
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.BBS_JUMP, params);
manager.setLoginRemindBeforeJumpBBS(false);
} else {
BrowseUtils.browser(url);
}
}
}
public abstract String getJumpUrl();
}

280
designer-base/src/main/java/com/fr/design/login/DesignerLoginBridge.java

@ -0,0 +1,280 @@
package com.fr.design.login;
import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.gui.ilable.ActionLabel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.locale.impl.BbsResetMark;
import com.fr.design.login.executor.DesignerLoginBrowserExecutor;
import com.fr.design.login.executor.DesignerLoginExecutor;
import com.fr.design.login.executor.DesignerSendCaptchaExecutor;
import com.fr.design.login.executor.DesignerSmsLoginExecutor;
import com.fr.design.login.executor.DesignerSmsRegisterExecutor;
import com.fr.design.login.task.DesignerLoginTaskWorker;
import com.fr.design.mainframe.toast.DesignerToastMsgUtil;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import com.fr.general.locale.LocaleCenter;
import com.fr.general.locale.LocaleMark;
import com.fr.log.FineLoggerFactory;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;
import java.util.Map;
import java.util.Set;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerLoginBridge {
private Map<String, String> params;
public static DesignerLoginBridge getBridge(Browser browser, Map<String, String> params) {
return new DesignerLoginBridge(browser, params);
}
private JSObject window;
private DesignerLoginBridge(Browser browser, Map<String, String> params) {
this.params = params;
this.window = browser.executeJavaScriptAndReturnValue("window").asObject();
Set<Map.Entry<String, String>> entries = params.entrySet();
for (Map.Entry<String, String> entry : entries) {
this.window.setProperty(entry.getKey(), entry.getValue());
}
}
@JSBridge
public String i18nText(String key) {
return Toolkit.i18nText(key);
}
@JSBridge
public void closeWindow(boolean loginSuccess) {
DesignerLoginSource source = DesignerLoginSource.valueOf(Integer.parseInt(params.get("designerLoginSource")));
if (loginSuccess) {
if (source == DesignerLoginSource.GUIDE) {
DesignerToastMsgUtil.toastPrompt(
getHyperlinkPane(
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Guide_Login_Success_Title"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Guide_Login_Success_Hyperlink_Text"),
CloudCenter.getInstance().acquireUrlByKind("designer.premium.template", "https://market.fanruan.com/template")
)
);
} else if (source == DesignerLoginSource.BBS_JUMP) {
String bbsJumpUrl = params.get("bbsJumpUrl");
BrowseUtils.browser(bbsJumpUrl);
}
DesignerLoginHelper.closeWindow();
return;
}
if (source == DesignerLoginSource.SWITCH_ACCOUNT) {
DesignerLoginHelper.closeWindow();
return;
}
if (source == DesignerLoginSource.BBS_JUMP) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String bbsJumpUrl = params.get("bbsJumpUrl");
String[] options = new String[]{
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_BBS_Go_Directly"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Login_Return_Login")
};
int rv = FineJOptionPane.showConfirmDialog(
DesignerLoginHelper.getDialog(),
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_BBS_Quit_Tip"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
options,
options[1]
);
if (rv == JOptionPane.YES_OPTION) {
BrowseUtils.browser(bbsJumpUrl);
DesignerLoginHelper.closeWindow();
}
}
});
} else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String[] options = new String[]{
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Login_Quit"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Login_Return_Login")
};
int rv = FineJOptionPane.showConfirmDialog(
DesignerLoginHelper.getDialog(),
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Login_Quit_Tip"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
options,
options[1]
);
if (rv == JOptionPane.OK_OPTION) {
DesignerLoginHelper.closeWindow();
}
}
});
}
}
/**
* 服务条款
*/
@JSBridge
public void serviceHref() {
try {
String url = CloudCenter.getInstance().acquireUrlByKind("designer.bbs.service.terms", "https://bbs.fanruan.com/thread-102821-1-1.html");
Desktop.getDesktop().browse(new URI(url));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
* 忘记密码
*/
@JSBridge
public void forgetHref() {
try {
LocaleMark<String> resetMark = LocaleCenter.getMark(BbsResetMark.class);
Desktop.getDesktop().browse(new URI(resetMark.getValue()));
} catch (Exception e) {
FineLoggerFactory.getLogger().info(e.getMessage());
}
}
/**
* 设计器端的用户登录
*
* @param username 用户名
* @param password 密码
* @param callback 回调函数
*/
@JSBridge
public void normalLogin(String username, String password, final JSFunction callback) {
DesignerLoginTaskWorker<Void> worker = new DesignerLoginTaskWorker<>(
new JSCallback(DesignerLoginBrowserExecutor.create(window, callback)),
new DesignerLoginExecutor(username, password));
worker.execute();
}
/**
* 发送短信验证码
*
* @param regionCode 区号
* @param phone 手机
* @param callback 回调函数
*/
@JSBridge
public void sendCaptcha(String regionCode, String phone, final JSFunction callback) {
DesignerLoginTaskWorker<Void> worker = new DesignerLoginTaskWorker<>(
new JSCallback(DesignerLoginBrowserExecutor.create(window, callback)),
new DesignerSendCaptchaExecutor(regionCode, phone));
worker.execute();
}
/**
* 设计器端的短信登录
*
* @param regionCode 区号
* @param phone 手机
* @param code 验证码
* @param callback 回调函数
*/
@JSBridge
public void smsLogin(String regionCode, String phone, String code, final JSFunction callback) {
DesignerLoginTaskWorker<Void> worker = new DesignerLoginTaskWorker<>(
new JSCallback(DesignerLoginBrowserExecutor.create(window, callback)),
new DesignerSmsLoginExecutor(regionCode, phone, code));
worker.execute();
}
/**
* 设计器端的用户注册
*
* @param regionCode 区号
* @param phone 手机
* @param password 密码
* @param regToken 注册令牌
* @param callback 回调函数
*/
@JSBridge
public void smsRegister(String regionCode, String phone, String password, String regToken, final JSFunction callback) {
DesignerLoginTaskWorker<Void> worker = new DesignerLoginTaskWorker<>(
new JSCallback(DesignerLoginBrowserExecutor.create(window, callback)),
new DesignerSmsRegisterExecutor(regionCode, phone, password, regToken));
worker.execute();
}
/**
* 使用系统浏览器打开网页
*
* @param url 要打开的网页
*/
@JSBridge
public void openShopUrlAtWebBrowser(String url) {
if (Desktop.isDesktopSupported()) {
try {
//创建一个URI实例,注意不是URL
URI uri = URI.create(url);
//获取当前系统桌面扩展
Desktop desktop = Desktop.getDesktop();
//判断系统桌面是否支持要执行的功能
if (desktop.isSupported(Desktop.Action.BROWSE)) {
//获取系统默认浏览器打开链接
desktop.browse(uri);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}
/**
* 调整面板大小
*
* @param width
* @param height
*/
@JSBridge
public void resize(int width, int height) {
DesignerLoginHelper.getDialog().setSize(width, height);
}
private JPanel getHyperlinkPane(String title, String hyperlinkText, String hyperlink) {
ActionLabel actionLabel = new ActionLabel(hyperlinkText);
actionLabel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
try {
Desktop.getDesktop().browse(new URI(hyperlink));
} catch (Exception ignore) {
}
}
});
JPanel panel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
panel.add(new UILabel(title));
panel.add(actionLabel);
return panel;
}
}

101
designer-base/src/main/java/com/fr/design/login/DesignerLoginHelper.java

@ -0,0 +1,101 @@
package com.fr.design.login;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.UIDialog;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.update.ui.dialog.UpdateMainDialog;
import com.fr.general.GeneralContext;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Window;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import javax.swing.JOptionPane;
import javax.swing.WindowConstants;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerLoginHelper {
private static final String MAIN_RESOURCE_PATH = "/com/fr/design/login/login.html";
private static final String JXBROWSER = "com.teamdev.jxbrowser.chromium.Browser";
private static UIDialog dialog = null;
public static String getMainResourcePath() {
return MAIN_RESOURCE_PATH;
}
public static UIDialog getDialog() {
return dialog;
}
public static void showLoginDialog(DesignerLoginSource source) {
showLoginDialog(source, new HashMap<>());
}
public static void showLoginDialog(DesignerLoginSource source, Map<String, String> params) {
showLoginDialog(source, params, DesignerContext.getDesignerFrame());
}
public static void showLoginDialog(DesignerLoginSource source, Map<String, String> params, Window window) {
if (!SupportOSImpl.DESIGNER_LOGIN.support()) {
WebViewDlgHelper.createLoginDialog(window);
return;
}
boolean hasJxBrowser = true;
try {
Class.forName(JXBROWSER);
} catch (ClassNotFoundException e) {
hasJxBrowser = false;
}
if (hasJxBrowser) {
showLoginPane(source, params, window);
} else {
showUpdatePane();
}
}
private static void showLoginPane(DesignerLoginSource source, Map<String, String> params, Window window) {
DesignerLoginPane designerLoginPane = new DesignerLoginPane(source, params);
if (dialog == null) {
if (window instanceof Dialog) {
dialog = new DesignerLoginShowDialog((Dialog) window, designerLoginPane);
} else {
dialog = new DesignerLoginShowDialog((Frame) window, designerLoginPane);
}
}
dialog.setVisible(true);
}
private static void showUpdatePane() {
JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Update_Info_Login_Message"));
if (!GeneralContext.getLocale().equals(Locale.JAPANESE) && !GeneralContext.getLocale().equals(Locale.JAPAN)
&& !Locale.getDefault().equals(Locale.JAPAN) && !Locale.getDefault().equals(Locale.JAPANESE)) {
UpdateMainDialog dialog = new UpdateMainDialog(DesignerContext.getDesignerFrame());
dialog.setAutoUpdateAfterInit();
dialog.showDialog();
}
}
public static void closeWindow() {
if (dialog != null) {
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dialog.setVisible(false);
dialog = null;
}
}
public static void main(String[] args) {
DesignerEnvManager.getEnvManager().setOpenDebug(true);
showLoginDialog(DesignerLoginSource.NORMAL);
}
}

42
designer-base/src/main/java/com/fr/design/login/DesignerLoginPane.java

@ -0,0 +1,42 @@
package com.fr.design.login;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.BasicPane;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.ui.ModernUIPane;
import com.teamdev.jxbrowser.chromium.JSValue;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import java.awt.BorderLayout;
import java.util.Map;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerLoginPane extends BasicPane {
@Override
protected String title4PopupWindow() {
return "DESIGNER_LOGIN";
}
public DesignerLoginPane(DesignerLoginSource source, Map<String, String> params) {
params.put("designerLoginSource", String.valueOf(source.getSource()));
params.put("lastLoginType", String.valueOf(DesignerEnvManager.getEnvManager().getLastLoginType().getType()));
params.put("lastLoginAccount", DesignerEnvManager.getEnvManager().getLastLoginAccount());
setLayout(new BorderLayout());
ModernUIPane<Object> modernUIPane = new ModernUIPane.Builder<>()
.prepare(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window");
window.asObject().setProperty("DesignerLoginHelper", DesignerLoginBridge.getBridge(event.getBrowser(), params));
}
})
.withEMB(DesignerLoginHelper.getMainResourcePath(), DesignerLoginUtils.renderMap())
.build();
add(modernUIPane, BorderLayout.CENTER);
}
}

45
designer-base/src/main/java/com/fr/design/login/DesignerLoginShowDialog.java

@ -0,0 +1,45 @@
package com.fr.design.login;
import com.fr.design.dialog.UIDialog;
import com.fr.design.utils.gui.GUICoreUtils;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import javax.swing.JPanel;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerLoginShowDialog extends UIDialog {
private static final Dimension DEFAULT = new Dimension(422, 478);
public DesignerLoginShowDialog(Frame frame, Component pane) {
super(frame);
init(pane);
}
public DesignerLoginShowDialog(Dialog dialog, Component pane) {
super(dialog);
init(pane);
}
private void init(Component pane) {
setUndecorated(true);
JPanel panel = (JPanel) getContentPane();
panel.setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
setSize(DEFAULT);
GUICoreUtils.centerWindow(this);
setResizable(false);
}
@Override
public void checkValid() throws Exception {
}
}

29
designer-base/src/main/java/com/fr/design/login/DesignerLoginSource.java

@ -0,0 +1,29 @@
package com.fr.design.login;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/6/7
*/
public enum DesignerLoginSource {
NORMAL(0), GUIDE(1), SWITCH_ACCOUNT(2), BBS_JUMP(3), UNKNOWN(-1);
private int source;
DesignerLoginSource(int source) {
this.source = source;
}
public int getSource() {
return source;
}
public static DesignerLoginSource valueOf(int source) {
for(DesignerLoginSource value : DesignerLoginSource.values()) {
if(value.getSource() == source) {
return value;
}
}
return UNKNOWN;
}
}

29
designer-base/src/main/java/com/fr/design/login/DesignerLoginType.java

@ -0,0 +1,29 @@
package com.fr.design.login;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/6/4
*/
public enum DesignerLoginType {
NORMAL_LOGIN(0), SMS_LOGIN(1), UNKNOWN(-1);
private int type;
DesignerLoginType(int type) {
this.type = type;
}
public int getType() {
return type;
}
public static DesignerLoginType valueOf(int type) {
for(DesignerLoginType value : DesignerLoginType.values()) {
if(value.getType() == type) {
return value;
}
}
return UNKNOWN;
}
}

49
designer-base/src/main/java/com/fr/design/login/bean/BBSAccountLogin.java

@ -0,0 +1,49 @@
package com.fr.design.login.bean;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/6/3
*/
public class BBSAccountLogin {
private int uid;
private String username;
private String appId;
private String refreshToken;
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
}

226
designer-base/src/main/java/com/fr/design/login/config/DesignerLoginConfigManager.java

@ -0,0 +1,226 @@
package com.fr.design.login.config;
import com.fr.design.login.DesignerLoginType;
import com.fr.stable.StringUtils;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLReadable;
import com.fr.stable.xml.XMLWriter;
import com.fr.stable.xml.XMLableReader;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/6/2
*/
public class DesignerLoginConfigManager implements XMLReadable, XMLWriter {
public static final String XML_TAG = "DesignerLoginConfigManager";
private static DesignerLoginConfigManager singleton;
/**
* bbs uid
*/
private int uid = -1;
/**
* bbs 用户名
*/
private String username = StringUtils.EMPTY;
/**
* bbs 应用Id
*/
private String appId = StringUtils.EMPTY;
/**
* bbs refreshToken
*/
private String refreshToken = StringUtils.EMPTY;
/**
* 登录引导页一个月内不再提醒
*/
private boolean doNotRemind = false;
/**
* 登录引导页一个月内不再提醒
*/
private long doNotRemindSelectedTime = -1L;
/**
* 设计器激活时间
*/
private long designerActivatedTime = -1L;
/**
* bbs 上次登录时间
*/
private long lastLoginTime = -1L;
/**
* bbs 上次登录方式
*/
private DesignerLoginType lastLoginType = DesignerLoginType.UNKNOWN;
/**
* bbs 上次登录账号
*/
private String lastLoginAccount = StringUtils.EMPTY;
/**
* 当前版本第一次启动
*/
private boolean currentVersionFirstLaunch = true;
/**
* bbs跳转前的登录提醒
*/
private boolean loginRemindBeforeJumpBBS = true;
/**
* 插件管理第一次启动时的提醒
*/
private boolean pluginRemindOnFirstLaunch = true;
private DesignerLoginConfigManager() {
}
public static DesignerLoginConfigManager getInstance() {
if (singleton == null) {
singleton = new DesignerLoginConfigManager();
}
return singleton;
}
@Override
public void readXML(XMLableReader reader) {
if (reader.isAttr()) {
this.setUid(reader.getAttrAsInt("uid", -1));
this.setUsername(reader.getAttrAsString("username", StringUtils.EMPTY));
this.setAppId(reader.getAttrAsString("appId", StringUtils.EMPTY));
this.setRefreshToken(reader.getAttrAsString("refreshToken", StringUtils.EMPTY));
this.setDoNotRemind(reader.getAttrAsBoolean("doNotRemind", false));
this.setDoNotRemindSelectedTime(reader.getAttrAsLong("doNotRemindSelectedTime", -1L));
this.setDesignerActivatedTime(reader.getAttrAsLong("designerActivatedTime", -1L));
this.setLastLoginTime(reader.getAttrAsLong("lastLoginTime", -1L));
this.setCurrentVersionFirstLaunch(reader.getAttrAsBoolean("currentVersionFirstLaunch", true));
this.setLastLoginType(DesignerLoginType.valueOf(reader.getAttrAsInt("lastLoginType", -1)));
this.setLastLoginAccount(reader.getAttrAsString("lastLoginAccount", StringUtils.EMPTY));
this.setLoginRemindBeforeJumpBBS(reader.getAttrAsBoolean("loginRemindBeforeJumpBBS", true));
this.setPluginRemindOnFirstLaunch(reader.getAttrAsBoolean("pluginRemindOnFirstLaunch", true));
}
}
@Override
public void writeXML(XMLPrintWriter writer) {
writer.startTAG(XML_TAG);
writer.attr("uid", uid);
writer.attr("username", username);
writer.attr("appId", appId);
writer.attr("refreshToken", refreshToken);
writer.attr("doNotRemind", doNotRemind);
writer.attr("doNotRemindSelectedTime", doNotRemindSelectedTime);
writer.attr("designerActivatedTime", designerActivatedTime);
writer.attr("lastLoginTime", lastLoginTime);
writer.attr("currentVersionFirstLaunch", currentVersionFirstLaunch);
writer.attr("lastLoginType", lastLoginType.getType());
writer.attr("lastLoginAccount", lastLoginAccount);
writer.attr("loginRemindBeforeJumpBBS", loginRemindBeforeJumpBBS);
writer.attr("pluginRemindOnFirstLaunch", pluginRemindOnFirstLaunch);
writer.end();
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public long getDoNotRemindSelectedTime() {
return doNotRemindSelectedTime;
}
public void setDoNotRemindSelectedTime(long doNotRemindSelectedTime) {
this.doNotRemindSelectedTime = doNotRemindSelectedTime;
}
public boolean isDoNotRemind() {
return doNotRemind;
}
public void setDoNotRemind(boolean doNotRemind) {
this.doNotRemind = doNotRemind;
}
public long getDesignerActivatedTime() {
return designerActivatedTime;
}
public void setDesignerActivatedTime(long designerActivatedTime) {
this.designerActivatedTime = designerActivatedTime;
}
public long getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(long lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
public boolean isCurrentVersionFirstLaunch() {
return currentVersionFirstLaunch;
}
public void setCurrentVersionFirstLaunch(boolean currentVersionFirstLaunch) {
this.currentVersionFirstLaunch = currentVersionFirstLaunch;
}
public DesignerLoginType getLastLoginType() {
return lastLoginType;
}
public void setLastLoginType(DesignerLoginType lastLoginType) {
this.lastLoginType = lastLoginType;
}
public String getLastLoginAccount() {
return lastLoginAccount;
}
public void setLastLoginAccount(String lastLoginAccount) {
this.lastLoginAccount = lastLoginAccount;
}
public boolean isLoginRemindBeforeJumpBBS() {
return loginRemindBeforeJumpBBS;
}
public void setLoginRemindBeforeJumpBBS(boolean loginRemindBeforeJumpBBS) {
this.loginRemindBeforeJumpBBS = loginRemindBeforeJumpBBS;
}
public boolean isPluginRemindOnFirstLaunch() {
return pluginRemindOnFirstLaunch;
}
public void setPluginRemindOnFirstLaunch(boolean pluginRemindOnFirstLaunch) {
this.pluginRemindOnFirstLaunch = pluginRemindOnFirstLaunch;
}
}

30
designer-base/src/main/java/com/fr/design/login/executor/DesignerLoginBrowserExecutor.java

@ -0,0 +1,30 @@
package com.fr.design.login.executor;
import com.fr.design.bridge.exec.JSExecutor;
import com.teamdev.jxbrowser.chromium.JSFunction;
import com.teamdev.jxbrowser.chromium.JSObject;
/**
* @author richie
* @version 10.0
* Created by richie on 2019-04-18
*/
public class DesignerLoginBrowserExecutor implements JSExecutor {
public static DesignerLoginBrowserExecutor create(JSObject window, JSFunction callback) {
return new DesignerLoginBrowserExecutor(window, callback);
}
private JSObject window;
private JSFunction callback;
private DesignerLoginBrowserExecutor(JSObject window, JSFunction callback) {
this.window = window;
this.callback = callback;
}
@Override
public void executor(String newValue) {
callback.invoke(window, newValue);
}
}

45
designer-base/src/main/java/com/fr/design/login/executor/DesignerLoginExecutor.java

@ -0,0 +1,45 @@
package com.fr.design.login.executor;
import com.fr.design.extra.Process;
import com.fr.design.extra.exe.Command;
import com.fr.design.extra.exe.Executor;
import com.fr.design.login.service.DesignerPassportManager;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/28
*/
public class DesignerLoginExecutor implements Executor {
private String result = "[]";
private String username;
private String password;
public DesignerLoginExecutor(String username, String password) {
this.username = username;
this.password = password;
}
@Override
public String getTaskFinishMessage() {
return result;
}
@Override
public Command[] getCommands() {
return new Command[]{
new Command() {
@Override
public String getExecuteMessage() {
return null;
}
@Override
public void run(Process<String> process) {
result = String.valueOf(DesignerPassportManager.getInstance().login(username, password));
}
}
};
}
}

45
designer-base/src/main/java/com/fr/design/login/executor/DesignerSendCaptchaExecutor.java

@ -0,0 +1,45 @@
package com.fr.design.login.executor;
import com.fr.design.extra.Process;
import com.fr.design.extra.exe.Command;
import com.fr.design.extra.exe.Executor;
import com.fr.design.login.service.DesignerPassportManager;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/28
*/
public class DesignerSendCaptchaExecutor implements Executor {
private String result = "[]";
private String regionCode;
private String phone;
public DesignerSendCaptchaExecutor(String regionCode, String phone) {
this.regionCode = regionCode;
this.phone = phone;
}
@Override
public String getTaskFinishMessage() {
return result;
}
@Override
public Command[] getCommands() {
return new Command[]{
new Command() {
@Override
public String getExecuteMessage() {
return null;
}
@Override
public void run(Process<String> process) {
result = String.valueOf(DesignerPassportManager.getInstance().sendCaptcha(regionCode, phone));
}
}
};
}
}

47
designer-base/src/main/java/com/fr/design/login/executor/DesignerSmsLoginExecutor.java

@ -0,0 +1,47 @@
package com.fr.design.login.executor;
import com.fr.design.extra.Process;
import com.fr.design.extra.exe.Command;
import com.fr.design.extra.exe.Executor;
import com.fr.design.login.service.DesignerPassportManager;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/28
*/
public class DesignerSmsLoginExecutor implements Executor {
private String result = "[]";
private String regionCode;
private String phone;
private String code;
public DesignerSmsLoginExecutor(String regionCode, String phone, String code) {
this.regionCode = regionCode;
this.phone = phone;
this.code = code;
}
@Override
public String getTaskFinishMessage() {
return result;
}
@Override
public Command[] getCommands() {
return new Command[]{
new Command() {
@Override
public String getExecuteMessage() {
return null;
}
@Override
public void run(Process<String> process) {
result = DesignerPassportManager.getInstance().smsLogin(regionCode, phone, code);
}
}
};
}
}

49
designer-base/src/main/java/com/fr/design/login/executor/DesignerSmsRegisterExecutor.java

@ -0,0 +1,49 @@
package com.fr.design.login.executor;
import com.fr.design.extra.Process;
import com.fr.design.extra.exe.Command;
import com.fr.design.extra.exe.Executor;
import com.fr.design.login.service.DesignerPassportManager;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/28
*/
public class DesignerSmsRegisterExecutor implements Executor {
private String result = "[]";
private String regionCode;
private String phone;
private String password;
private String regToken;
public DesignerSmsRegisterExecutor(String regionCode, String phone, String password, String regToken) {
this.regionCode = regionCode;
this.phone = phone;
this.password = password;
this.regToken = regToken;
}
@Override
public String getTaskFinishMessage() {
return result;
}
@Override
public Command[] getCommands() {
return new Command[]{
new Command() {
@Override
public String getExecuteMessage() {
return null;
}
@Override
public void run(Process<String> process) {
result = String.valueOf(DesignerPassportManager.getInstance().smsRegister(regionCode, phone, password, regToken));
}
}
};
}
}

83
designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideBridge.java

@ -0,0 +1,83 @@
package com.fr.design.login.guide;
import com.fr.design.DesignerEnvManager;
import com.fr.design.bridge.exec.JSBridge;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.i18n.Toolkit;
import com.fr.design.login.DesignerLoginHelper;
import com.fr.design.login.DesignerLoginSource;
import com.teamdev.jxbrowser.chromium.Browser;
import com.teamdev.jxbrowser.chromium.JSObject;
import javax.swing.JOptionPane;
import javax.swing.SwingUtilities;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerGuideBridge {
public static DesignerGuideBridge getBridge(Browser browser) {
return new DesignerGuideBridge(browser);
}
private JSObject window;
private DesignerGuideBridge(Browser browser) {
this.window = browser.executeJavaScriptAndReturnValue("window").asObject();
}
@JSBridge
public String i18nText(String key) {
return Toolkit.i18nText(key);
}
@JSBridge
public void closeWindow(boolean doNotRemind, boolean login) {
if (login) {
DesignerGuideHelper.closeWindow();
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.GUIDE);
checkDoNotRemind(doNotRemind);
} else {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
String[] options = new String[]{
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Login_Quit"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Login_Return_Login")
};
int rv = FineJOptionPane.showConfirmDialog(
DesignerGuideHelper.getDialog(),
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Login_Quit_Tip"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"),
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE,
null,
options,
options[1]
);
if (rv == JOptionPane.YES_OPTION) {
DesignerGuideHelper.closeWindow();
checkDoNotRemind(doNotRemind);
} else if (rv == JOptionPane.NO_OPTION) {
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.GUIDE);
DesignerGuideHelper.closeWindow();
checkDoNotRemind(doNotRemind);
}
}
});
}
}
/**
* 用户勾选了一个月内不再提醒
*/
private void checkDoNotRemind(boolean doNotRemind) {
DesignerEnvManager manager = DesignerEnvManager.getEnvManager();
manager.setDesignerLoginDoNotRemind(doNotRemind);
if (doNotRemind) {
manager.setDesignerLoginDoNotRemindSelectedTime(System.currentTimeMillis());
}
}
}

123
designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java

@ -0,0 +1,123 @@
package com.fr.design.login.guide;
import com.fr.base.FRContext;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.UIDialog;
import com.fr.design.event.DesignerOpenedListener;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.update.push.DesignerPushUpdateManager;
import com.fr.stable.StringUtils;
import javax.swing.WindowConstants;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerGuideHelper {
private static final String MAIN_RESOURCE_PATH = "/com/fr/design/login/guide.html";
private static final String JXBROWSER = "com.teamdev.jxbrowser.chromium.Browser";
private static final long ONE_WEEK = 7 * 24 * 3600 * 1000L;
private static final long ONE_MONTH = 30 * 24 * 3600 * 1000L;
private static final long SIX_MONTH = 6 * ONE_MONTH;
private static UIDialog dialog = null;
public static String getMainResourcePath() {
return MAIN_RESOURCE_PATH;
}
public static UIDialog getDialog() {
return dialog;
}
public static void prepareShowGuideDialog() {
// 如果存在更新升级的弹窗,则不显示引导页面
if (!SupportOSImpl.DESIGNER_LOGIN.support() || !FRContext.isChineseEnv() || DesignerPushUpdateManager.getInstance().isShouldPopUp()) {
return;
}
if (isActivatedForOneWeek()) {
if (isLogin() && !isLoginForSixMonths()) {
return;
}
if (selectedDoNotRemindInOneMonth()) {
return;
}
DesignerContext.getDesignerFrame().addDesignerOpenedListener(new DesignerOpenedListener() {
@Override
public void designerOpened() {
showGuideDialog();
}
});
}
}
/**
* 激活满一周
*/
private static boolean isActivatedForOneWeek() {
DesignerEnvManager manager = DesignerEnvManager.getEnvManager();
String key = manager.getActivationKey();
if (StringUtils.isEmpty(key)) {
return false;
}
return (System.currentTimeMillis() - manager.getDesignerActivatedTime()) > ONE_WEEK;
}
/**
* 已经登录
*/
private static boolean isLogin() {
return DesignerEnvManager.getEnvManager().getDesignerLoginUid() > 0;
}
/**
* 已经登录满六个月
*/
private static boolean isLoginForSixMonths() {
return isLogin() && (System.currentTimeMillis() - DesignerEnvManager.getEnvManager().getDesignerLastLoginTime()) > SIX_MONTH;
}
/**
* 一个月内不再提醒
*/
private static boolean selectedDoNotRemindInOneMonth() {
return DesignerEnvManager.getEnvManager().isDesignerLoginDoNotRemind()
&& (System.currentTimeMillis() - DesignerEnvManager.getEnvManager().getDesignerLoginDoNotRemindSelectedTime()) <= ONE_MONTH;
}
private static void showGuideDialog() {
boolean hasJxBrowser = true;
try {
Class.forName(JXBROWSER);
} catch (ClassNotFoundException e) {
hasJxBrowser = false;
}
if (hasJxBrowser) {
showGuidePane();
}
}
private static void showGuidePane() {
DesignerGuidePane designerGuidePane = new DesignerGuidePane();
if (dialog == null) {
dialog = new DesignerGuideShowDialog(DesignerContext.getDesignerFrame(), designerGuidePane);
}
dialog.setVisible(true);
}
public static void closeWindow() {
if (dialog != null) {
dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
dialog.setVisible(false);
dialog = null;
}
}
public static void main(String[] args) {
DesignerEnvManager.getEnvManager().setOpenDebug(true);
showGuideDialog();
}
}

37
designer-base/src/main/java/com/fr/design/login/guide/DesignerGuidePane.java

@ -0,0 +1,37 @@
package com.fr.design.login.guide;
import com.fr.design.dialog.BasicPane;
import com.fr.design.login.guide.utils.DesignerGuideUtils;
import com.fr.design.ui.ModernUIPane;
import com.teamdev.jxbrowser.chromium.JSValue;
import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter;
import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent;
import java.awt.BorderLayout;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerGuidePane extends BasicPane {
@Override
protected String title4PopupWindow() {
return "DESIGNER_GUIDE";
}
public DesignerGuidePane() {
setLayout(new BorderLayout());
ModernUIPane<Object> modernUIPane = new ModernUIPane.Builder<>()
.prepare(new ScriptContextAdapter() {
@Override
public void onScriptContextCreated(ScriptContextEvent event) {
JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window");
window.asObject().setProperty("DesignerGuideHelper", DesignerGuideBridge.getBridge(event.getBrowser()));
}
})
.withEMB(DesignerGuideHelper.getMainResourcePath(), DesignerGuideUtils.renderMap())
.build();
add(modernUIPane, BorderLayout.CENTER);
}
}

35
designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideShowDialog.java

@ -0,0 +1,35 @@
package com.fr.design.login.guide;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.UIDialog;
import com.fr.design.utils.gui.GUICoreUtils;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Frame;
import javax.swing.JPanel;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerGuideShowDialog extends UIDialog {
private static final Dimension DEFAULT = new Dimension(700, 577);
public DesignerGuideShowDialog(Frame frame, BasicPane pane) {
super(frame);
setUndecorated(true);
JPanel panel = (JPanel) getContentPane();
panel.setLayout(new BorderLayout());
add(pane, BorderLayout.CENTER);
setSize(DEFAULT);
GUICoreUtils.centerWindow(this);
setResizable(false);
}
@Override
public void checkValid() throws Exception {
}
}

19
designer-base/src/main/java/com/fr/design/login/guide/utils/DesignerGuideUtils.java

@ -0,0 +1,19 @@
package com.fr.design.login.guide.utils;
import com.fr.general.GeneralContext;
import java.util.HashMap;
import java.util.Map;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerGuideUtils {
public static Map<String, String> renderMap() {
Map<String, String> map4Tpl = new HashMap<>();
map4Tpl.put("language", GeneralContext.getLocale().toString());
return map4Tpl;
}
}

120
designer-base/src/main/java/com/fr/design/login/message/DesignerMessageHelper.java

@ -0,0 +1,120 @@
package com.fr.design.login.message;
import com.fr.concurrent.NamedThreadFactory;
import com.fr.design.DesignerEnvManager;
import com.fr.design.dialog.NotificationDialog;
import com.fr.design.dialog.NotificationDialogAction;
import com.fr.design.event.DesignerOpenedListener;
import com.fr.design.login.utils.DesignerLoginUtils;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.utils.BrowseUtils;
import com.fr.general.CloudCenter;
import com.fr.general.http.HttpToolbox;
import com.fr.json.JSON;
import com.fr.json.JSONFactory;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/6/11
*/
public class DesignerMessageHelper {
private static final long DELAY = 7L;
private static final String STATUS = "status";
private static final String DATA = "data";
private static final String SUCCESS = "success";
private static final String MESSAGE_ID = "messageId";
private static final String TITLE = "title";
private static final String BODY = "body";
private static final String JUMP_TYPE = "jumpType";
private static final String JUMP_TO = "jumpTo";
private static DesignerMessageHelper instance;
private DesignerMessageHelper() {
}
public static DesignerMessageHelper getInstance() {
if (instance == null) {
instance = new DesignerMessageHelper();
}
return instance;
}
public void prepareShowMessage() {
DesignerContext.getDesignerFrame().addDesignerOpenedListener(new DesignerOpenedListener() {
@Override
public void designerOpened() {
ScheduledExecutorService service = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("DesignerMessageHelper"));
service.schedule(new Runnable() {
@Override
public void run() {
try {
pullLatestMessageAndShow();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}, DELAY, TimeUnit.MINUTES);
service.shutdown();
}
});
}
private void pullLatestMessageAndShow() throws Exception {
String url = CloudCenter.getInstance().acquireUrlByKind("designer.message.push", "https://market.fanruan.com/api/v1/message/designer");
Map<String, String> params = new HashMap<>();
params.put("designerId", DesignerEnvManager.getEnvManager().getUUID());
String result = HttpToolbox.post(url, params);
JSONObject response = JSONFactory.createJSON(JSON.OBJECT, result);
String status = response.optString(STATUS);
if (SUCCESS.equals(status)) {
JSONObject data = response.optJSONObject(DATA);
String messageId = data.optString(MESSAGE_ID);
String title = data.optString(TITLE);
String body = data.optString(BODY);
int jumpType = data.optInt(JUMP_TYPE);
String jumpTo = data.optString(JUMP_TO);
if (StringUtils.isNotEmpty(messageId) && StringUtils.isNotEmpty(title) && StringUtils.isNotEmpty(body) && jumpType > 0 && StringUtils.isNotEmpty(jumpTo)) {
NotificationJumpType notificationJumpType = NotificationJumpType.valueOf(jumpType);
if (notificationJumpType == NotificationJumpType.WEB_URL) {
NotificationDialog.Builder()
.owner(DesignerContext.getDesignerFrame())
.title(title)
.modal(true)
.messageType(NotificationDialog.NEW_MESSAGE)
.message(body)
.notificationDialogAction(new NotificationDialogAction() {
@Override
public void doClick() {
String ssoUrl = DesignerLoginUtils.generateDesignerSSOUrl(jumpTo);
BrowseUtils.browser(ssoUrl);
}
})
.build()
.setVisible(true);
} else if (notificationJumpType == NotificationJumpType.DESIGNER_MODULE) {
DesignerModuleClickType designerModuleClickType = DesignerModuleClickType.valueOf(jumpTo);
NotificationDialog.Builder()
.owner(DesignerContext.getDesignerFrame())
.title(title)
.modal(true)
.messageType(NotificationDialog.NEW_MESSAGE)
.message(body)
.notificationDialogAction(designerModuleClickType.getAction())
.build()
.setVisible(true);
}
}
}
}
}

69
designer-base/src/main/java/com/fr/design/login/message/DesignerModuleClickType.java

@ -0,0 +1,69 @@
package com.fr.design.login.message;
import com.fr.config.ServerPreferenceConfig;
import com.fr.design.dialog.NotificationDialogAction;
import com.fr.design.extra.WebViewDlgHelper;
import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.upm.UpmFinder;
import com.fr.design.utils.DesignUtils;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.stable.os.Arch;
import com.fr.stable.os.OperatingSystem;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/6/11
*/
public enum DesignerModuleClickType {
PLUGIN("PLUGIN", new NotificationDialogAction() {
@Override
public void doClick() {
try {
if (Arch.getArch() == Arch.ARM || OperatingSystem.isLinux() || SupportOSImpl.MACOS_WEB_PLUGIN_MANAGEMENT.support()) {
DesignUtils.visitEnvServerByParameters("#management/plugin", null, null);
return;
}
if (ServerPreferenceConfig.getInstance().isUseOptimizedUPM() || SupportOSImpl.MACOS_NEW_PLUGIN_MANAGEMENT.support()) {
UpmFinder.showUPMDialog();
} else {
WebViewDlgHelper.createPluginDialog();
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}),
REUSE("REUSE", new NotificationDialogAction() {
@Override
public void doClick() {
try {
// TODO
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
}),
UNKNOWN(StringUtils.EMPTY, new NotificationDialogAction() {
@Override
public void doClick() {
}
});
private String jumpTo;
private NotificationDialogAction action;
DesignerModuleClickType(String jumpTo, NotificationDialogAction action) {
this.jumpTo = jumpTo;
this.action = action;
}
public String getJumpTo() {
return jumpTo;
}
public NotificationDialogAction getAction() {
return action;
}
}

31
designer-base/src/main/java/com/fr/design/login/message/NotificationJumpType.java

@ -0,0 +1,31 @@
package com.fr.design.login.message;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/6/11
*/
public enum NotificationJumpType {
WEB_URL(1),
DESIGNER_MODULE(2),
UNKNOWN(-1);
private int jumpType;
NotificationJumpType(int jumpType) {
this.jumpType = jumpType;
}
public int getJumpType() {
return jumpType;
}
public static NotificationJumpType valueOf(int jumpType) {
for(NotificationJumpType value : NotificationJumpType.values()) {
if(value.getJumpType() == jumpType) {
return value;
}
}
return UNKNOWN;
}
}

167
designer-base/src/main/java/com/fr/design/login/service/DesignerLoginClient.java

@ -0,0 +1,167 @@
package com.fr.design.login.service;
import com.fr.general.CloudCenter;
import com.fr.general.http.HttpToolbox;
import com.fr.general.log.MessageFormatter;
import com.fr.json.JSON;
import com.fr.json.JSONFactory;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.StringUtils;
import com.fr.third.org.apache.commons.lang3.RandomStringUtils;
import java.util.HashMap;
import java.util.UUID;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/28
*/
public class DesignerLoginClient {
private static final String LOGIN_API = CloudCenter.getInstance().acquireUrlByKind("designer.login.api", "http://api.shequ.fanruan.com/v1/user/login/");
private static final String SEND_CAPTCHA_API = CloudCenter.getInstance().acquireUrlByKind("designer.send.captcha.api", "http://api.shequ.fanruan.com/v1/code/getsmscaptcha/?location={}&phone={}&smstype={}");
private static final String SMS_LOGIN_API = CloudCenter.getInstance().acquireUrlByKind("designer.sms.login.api", "http://api.shequ.fanruan.com/v1/user/smslogin/");
private static final String SMS_REGISTER_API = CloudCenter.getInstance().acquireUrlByKind("designer.sms.register.api", "http://api.shequ.fanruan.com/v1/user/register/");
private static final String USERNAME = "username";
private static final String PASSWORD = "password";
private static final String SMS_TYPE_LOGIN_AND_REGISTER = "1";
private static final String LOCATION = "location";
private static final String PHONE = "phone";
private static final String CODE = "code";
private static final String STATUS = "status";
private static final String DATA = "data";
private static final String CLIENT = "client";
private static final String UID = "uid";
private static final String APP_ID = "appid";
private static final String REFRESH_TOKEN = "refresh_token";
private static final String REGISTER = "register";
private static final String REG_TOKEN = "regtoken";
private static final String REG_PHONE = "regphone";
private static final String DEVICE = "device";
private static final String REG_FROM = "reg_from";
private static final String PRODUCT_FINEREPORT = "product-finereport";
/**
* 服务器内部错误
*/
private static final int INTERNAL_ERROR = 0;
/**
* 未知错误
*/
private static final int UNKNOWN_ERROR = -3;
/**
* 网络连接失败
*/
private static final int NETWORK_CONNECTED_FAILED = -4;
public DesignerLoginResult login(String username, String password) {
try {
HashMap<String, Object> params = new HashMap<>();
params.put(USERNAME, username);
params.put(PASSWORD, password);
String result = HttpToolbox.post(LOGIN_API, params);
JSONObject response = JSONFactory.createJSON(JSON.OBJECT, result);
int status = response.optInt(STATUS);
if (status < 0) {
return DesignerLoginResult.create(status, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, false, StringUtils.EMPTY);
}
JSONObject data = response.optJSONObject(DATA);
if (data != null) {
JSONObject client = data.optJSONObject(CLIENT);
if (client != null) {
int uid = client.optInt(UID);
if (uid > 0) {
return DesignerLoginResult.create(uid, client.optString(USERNAME), client.optString(APP_ID), data.optString(REFRESH_TOKEN), false, StringUtils.EMPTY);
}
}
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
return DesignerLoginResult.create(NETWORK_CONNECTED_FAILED, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, false, StringUtils.EMPTY);
}
return DesignerLoginResult.create(UNKNOWN_ERROR, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, false, StringUtils.EMPTY);
}
public int sendCaptcha(String regionCode, String phone) {
try {
String url = MessageFormatter.arrayFormat(SEND_CAPTCHA_API, new String[]{regionCode, phone, SMS_TYPE_LOGIN_AND_REGISTER}).getMessage();
String result = HttpToolbox.get(url);
JSONObject response = JSONFactory.createJSON(JSON.OBJECT, result);
return response.optInt(STATUS);
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return INTERNAL_ERROR;
}
public DesignerLoginResult smsLogin(String regionCode, String phone, String code) {
try {
HashMap<String, Object> params = new HashMap<>();
params.put(LOCATION, regionCode);
params.put(PHONE, phone);
params.put(CODE, code);
String result = HttpToolbox.post(SMS_LOGIN_API, params);
JSONObject response = JSONFactory.createJSON(JSON.OBJECT, result);
int status = response.optInt(STATUS);
if (status < 0) {
return DesignerLoginResult.create(status, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, false, StringUtils.EMPTY);
}
JSONObject data = response.optJSONObject(DATA);
if (data != null) {
boolean register = data.optBoolean(REGISTER);
if (register) {
String regToken = data.optString(REG_TOKEN);
if (regToken != null) {
return DesignerLoginResult.create(status, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, true, regToken);
}
} else {
JSONObject client = data.optJSONObject(CLIENT);
if (client != null) {
int uid = client.optInt(UID);
if (uid > 0) {
return DesignerLoginResult.create(uid, client.optString(USERNAME), client.optString(APP_ID), data.optString(REFRESH_TOKEN), false, StringUtils.EMPTY);
}
}
}
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return DesignerLoginResult.create(INTERNAL_ERROR, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, false, StringUtils.EMPTY);
}
public DesignerLoginResult smsRegister(String regionCode, String phone, String password, String regToken) {
try {
HashMap<String, Object> params = new HashMap<>();
params.put(USERNAME, RandomStringUtils.randomAlphabetic(8));
params.put(PASSWORD, password);
params.put(REG_TOKEN, regToken);
params.put(LOCATION, regionCode);
params.put(REG_PHONE, phone);
params.put(DEVICE, PRODUCT_FINEREPORT);
params.put(REG_FROM, PRODUCT_FINEREPORT);
String result = HttpToolbox.post(SMS_REGISTER_API, params);
JSONObject response = JSONFactory.createJSON(JSON.OBJECT, result);
int status = response.optInt(STATUS);
if (status < 0) {
return DesignerLoginResult.create(status, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, false, StringUtils.EMPTY);
}
JSONObject data = response.optJSONObject(DATA);
if (data != null) {
JSONObject client = data.optJSONObject(CLIENT);
if (client != null) {
int uid = client.optInt(UID);
if (uid > 0) {
return DesignerLoginResult.create(uid, client.optString(USERNAME), client.optString(APP_ID), data.optString(REFRESH_TOKEN), false, StringUtils.EMPTY);
}
}
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return DesignerLoginResult.create(INTERNAL_ERROR, StringUtils.EMPTY, StringUtils.EMPTY, StringUtils.EMPTY, false, StringUtils.EMPTY);
}
}

82
designer-base/src/main/java/com/fr/design/login/service/DesignerLoginResult.java

@ -0,0 +1,82 @@
package com.fr.design.login.service;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/28
*/
public class DesignerLoginResult {
private int uid;
private String username;
private String appId;
private String refreshToken;
private boolean register;
private String regToken;
private DesignerLoginResult(int uid, String username, String appId, String refreshToken, boolean register, String regToken) {
this.uid = uid;
this.username = username;
this.appId = appId;
this.refreshToken = refreshToken;
this.regToken = regToken;
this.register = register;
}
public static DesignerLoginResult create(int uid, String username, String appId, String refreshToken, boolean register, String regToken) {
return new DesignerLoginResult(uid, username, appId, refreshToken, register, regToken);
}
public int getUid() {
return uid;
}
public void setUid(int uid) {
this.uid = uid;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAppId() {
return appId;
}
public void setAppId(String appId) {
this.appId = appId;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public boolean isRegister() {
return register;
}
public void setRegister(boolean register) {
this.register = register;
}
public String getRegToken() {
return regToken;
}
public void setRegToken(String regToken) {
this.regToken = regToken;
}
}

114
designer-base/src/main/java/com/fr/design/login/service/DesignerPassportManager.java

@ -0,0 +1,114 @@
package com.fr.design.login.service;
import com.fr.design.DesignerEnvManager;
import com.fr.design.login.DesignerLoginType;
import com.fr.design.upm.event.CertificateEvent;
import com.fr.event.EventDispatcher;
import com.fr.json.JSONObject;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/28
*/
public class DesignerPassportManager {
private static final String STATUS = "status";
private static final String REGISTER = "register";
private static final String REG_TOKEN = "regtoken";
private static volatile DesignerPassportManager instance = null;
public static DesignerPassportManager getInstance() {
if (instance == null) {
synchronized (DesignerPassportManager.class) {
if (instance == null) {
instance = new DesignerPassportManager();
}
}
}
return instance;
}
/**
* 账号密码登录帆软通行证
*
* @param username 论坛账号
* @param password 密码
*/
public int login(String username, String password) {
DesignerLoginClient client = new DesignerLoginClient();
DesignerLoginResult result = client.login(username, password);
int uid = result.getUid();
if (uid > 0) {
saveUserInfo(uid, result.getUsername(), result.getAppId(), result.getRefreshToken(), DesignerLoginType.NORMAL_LOGIN, username);
}
return uid;
}
/**
* 发送短信验证码
*
* @param regionCode 区号
* @param phone 手机
*/
public int sendCaptcha(String regionCode, String phone) {
DesignerLoginClient client = new DesignerLoginClient();
return client.sendCaptcha(regionCode, phone);
}
/**
* 短信登录帆软通行证
*
* @param regionCode 区号
* @param phone 手机
* @param code 验证码
*/
public String smsLogin(String regionCode, String phone, String code) {
DesignerLoginClient client = new DesignerLoginClient();
DesignerLoginResult result = client.smsLogin(regionCode, phone, code);
int uid = result.getUid();
if (uid > 0) {
saveUserInfo(uid, result.getUsername(), result.getAppId(), result.getRefreshToken(), DesignerLoginType.SMS_LOGIN, regionCode + "-" + phone);
}
JSONObject jo = new JSONObject();
jo.put(STATUS, result.getUid());
jo.put(REGISTER, result.isRegister());
jo.put(REG_TOKEN, result.getRegToken());
return jo.toString();
}
/**
* 注册帆软通行证
*
* @param regionCode 区号
* @param phone 手机
* @param password 密码
* @param regToken 注册令牌
*/
public int smsRegister(String regionCode, String phone, String password, String regToken) {
DesignerLoginClient client = new DesignerLoginClient();
DesignerLoginResult result = client.smsRegister(regionCode, phone, password, regToken);
int uid = result.getUid();
if (uid > 0) {
saveUserInfo(uid, result.getUsername(), result.getAppId(), result.getRefreshToken(), DesignerLoginType.SMS_LOGIN, regionCode + "-" + phone);
}
return uid;
}
/**
* 保存登录信息
*/
private void saveUserInfo(int uid, String username, String appId, String refreshToken, DesignerLoginType type, String account) {
DesignerEnvManager manager = DesignerEnvManager.getEnvManager();
manager.setDesignerLoginUid(uid);
manager.setDesignerLoginUsername(username);
manager.setDesignerLoginAppId(appId);
manager.setDesignerLoginRefreshToken(refreshToken);
manager.setDesignerLastLoginTime(System.currentTimeMillis());
manager.setLastLoginType(type);
manager.setLastLoginAccount(account);
DesignerEnvManager.getEnvManager().saveXMLFile();
EventDispatcher.fire(CertificateEvent.LOGIN, username);
}
}

87
designer-base/src/main/java/com/fr/design/login/socketio/LoginAuthServer.java

@ -0,0 +1,87 @@
package com.fr.design.login.socketio;
import com.fr.design.DesignerEnvManager;
import com.fr.design.login.DesignerLoginType;
import com.fr.design.login.bean.BBSAccountLogin;
import com.fr.design.upm.event.CertificateEvent;
import com.fr.event.EventDispatcher;
import com.fr.log.FineLoggerFactory;
import com.fr.third.socketio.AckRequest;
import com.fr.third.socketio.Configuration;
import com.fr.third.socketio.SocketIOClient;
import com.fr.third.socketio.SocketIOServer;
import com.fr.third.socketio.listener.DataListener;
import java.net.URLDecoder;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/6/3
*/
public class LoginAuthServer {
private SocketIOServer server;
private static final String HOSTNAME = "localhost";
private static final int PORT = 41925;
private static volatile LoginAuthServer instance = null;
public static LoginAuthServer getInstance() {
if (instance == null) {
synchronized (LoginAuthServer.class) {
if (instance == null) {
instance = new LoginAuthServer();
}
}
}
return instance;
}
private LoginAuthServer() {
Configuration config = new Configuration();
config.setHostname(HOSTNAME);
config.setPort(PORT);
server = new SocketIOServer(config);
initEventListener();
}
public void start() {
try {
server.start();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
public void stop() {
try {
server.stop();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
}
private void initEventListener() {
server.addEventListener("bbsAccountLogin", BBSAccountLogin.class, new DataListener<BBSAccountLogin>() {
@Override
public void onData(SocketIOClient client, BBSAccountLogin data, AckRequest ackRequest) throws Exception {
// 保存登录信息到.FineReport100配置中
int uid = data.getUid();
if (uid > 0) {
String username = URLDecoder.decode(data.getUsername(), "UTF-8");
DesignerEnvManager manager = DesignerEnvManager.getEnvManager();
manager.setDesignerLoginUid(data.getUid());
manager.setDesignerLoginUsername(username);
manager.setDesignerLoginAppId(data.getAppId());
manager.setDesignerLoginRefreshToken(data.getRefreshToken());
manager.setDesignerLastLoginTime(System.currentTimeMillis());
manager.setLastLoginType(DesignerLoginType.NORMAL_LOGIN);
manager.setLastLoginAccount(username);
DesignerEnvManager.getEnvManager().saveXMLFile();
EventDispatcher.fire(CertificateEvent.LOGIN, username);
}
}
});
}
}

51
designer-base/src/main/java/com/fr/design/login/task/DesignerLoginTaskWorker.java

@ -0,0 +1,51 @@
package com.fr.design.login.task;
import com.fr.design.bridge.exec.JSCallback;
import com.fr.design.bridge.exec.JSUtils;
import com.fr.design.extra.Process;
import com.fr.design.extra.exe.Command;
import com.fr.design.extra.exe.Executor;
import com.fr.stable.StringUtils;
import javax.swing.SwingWorker;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/27
*/
public class DesignerLoginTaskWorker<V> extends SwingWorker<V, String> {
private Executor executor;
private JSCallback callback;
public DesignerLoginTaskWorker(final JSCallback callback, final Executor executor) {
this.executor = executor;
this.callback = callback;
}
@Override
protected V doInBackground() throws Exception {
Command[] commands = executor.getCommands();
for (Command command : commands) {
String message = command.getExecuteMessage();
if (StringUtils.isNotBlank(message)) {
publish(message);
}
command.run(new Process<String>() {
@Override
public void process(String s) {
if (StringUtils.isNotBlank(s)) {
publish(JSUtils.trimText(s));
}
}
});
}
return null;
}
@Override
protected void done() {
String result = executor.getTaskFinishMessage();
callback.execute(result);
}
}

87
designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java

@ -0,0 +1,87 @@
package com.fr.design.login.utils;
import com.fr.design.DesignerEnvManager;
import com.fr.design.mainframe.toast.DesignerToastMsgUtil;
import com.fr.general.CloudCenter;
import com.fr.general.GeneralContext;
import com.fr.general.log.MessageFormatter;
import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.third.org.bouncycastle.util.encoders.Hex;
import java.security.SecureRandom;
import java.util.HashMap;
import java.util.Map;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* @author Lanlan
* @version 10.0
* Created by Lanlan on 2021/5/21
*/
public class DesignerLoginUtils {
private static final String PRODUCT_FINEREPORT = "product-finereport";
private static final String KEY = "i7hP48WAcuTrmxfN";
public static Map<String, String> renderMap() {
Map<String, String> map4Tpl = new HashMap<>();
map4Tpl.put("language", GeneralContext.getLocale().toString());
return map4Tpl;
}
public static void showPluginRemindOnFirstLaunch() {
DesignerEnvManager manager = DesignerEnvManager.getEnvManager();
int uid = manager.getDesignerLoginUid();
if (uid > 0) {
boolean pluginRemindOnFirstLaunch = manager.isPluginRemindOnFirstLaunch();
if (pluginRemindOnFirstLaunch) {
DesignerToastMsgUtil.toastWarning(
com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Plugin_Tip")
);
manager.setPluginRemindOnFirstLaunch(false);
}
}
}
public static String generateDesignerSSOUrl(String referrer) {
String ssoTemplate = CloudCenter.getInstance().acquireUrlByKind("designer.sso.api", "https://id.fanruan.com/api/app/?code={}&referrer={}");
try {
String code = generateLoginCode();
MessageFormatter.FormattingTuple tuple = MessageFormatter.arrayFormat(ssoTemplate, new String[]{code, referrer});
return tuple.getMessage();
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return referrer;
}
private static String generateLoginCode() throws Exception {
DesignerEnvManager manager = DesignerEnvManager.getEnvManager();
JSONObject jo = JSONObject.create();
jo.put("uid", manager.getDesignerLoginUid());
jo.put("username", manager.getDesignerLoginUsername());
jo.put("source", PRODUCT_FINEREPORT);
byte[] iv = randomIv();
return new String(Hex.encode(iv)) + encrypt(jo.toString(), KEY.getBytes(), iv);
}
private static byte[] randomIv() {
byte[] salt = new byte[16];
SecureRandom secureRandom = new SecureRandom();
secureRandom.setSeed(System.currentTimeMillis());
secureRandom.nextBytes(salt);
return salt;
}
private static String encrypt(String content, byte[] key, byte[] iv) throws Exception {
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
Cipher cipher = Cipher.getInstance("AES/CTR/PKCS5Padding");
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] resultBytes = cipher.doFinal(content.getBytes());
return new String(Hex.encode(resultBytes));
}
}

39
designer-base/src/main/java/com/fr/design/mainframe/ComponentReuseNotifyUtil.java

@ -0,0 +1,39 @@
package com.fr.design.mainframe;
import com.fr.design.DesignerEnvManager;
import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.reuse.ComponentReuseNotificationInfo;
import com.fr.design.mainframe.toast.DesignerToastMsgUtil;
import com.fr.design.notification.SnapChat;
import com.fr.design.notification.SnapChatFactory;
import com.fr.design.notification.SnapChatKey;
/**
* Created by kerry on 5/8/21
*/
public class ComponentReuseNotifyUtil {
private static final String COMPONENT_SNAP_CHAT_KEY = "com.fr.component.share-components";
private ComponentReuseNotifyUtil() {
}
public static void enterWidgetLibExtraAction(boolean needValidRead) {
if (ComponentReuseNotificationInfo.getInstance().isClickedWidgetLib()) {
return;
}
SnapChat snapChat = SnapChatFactory.createSnapChat(false, new SnapChatKey() {
@Override
public String calc() {
return COMPONENT_SNAP_CHAT_KEY;
}
});
if (snapChat.hasRead() && needValidRead) {
DesignerToastMsgUtil.toastPrompt(Toolkit.i18nText("Fine-Design_Component_Reuse_Merge_Prompt"));
}
ComponentReuseNotificationInfo.getInstance().setClickedWidgetLib(true);
DesignerEnvManager.getEnvManager().saveXMLFile();
}
}

15
designer-base/src/main/java/com/fr/design/mainframe/DesignOperationEvent.java

@ -0,0 +1,15 @@
package com.fr.design.mainframe;
import com.fr.event.Event;
import com.fr.event.Null;
/**
* Created by kerry on 4/28/21
*/
public enum DesignOperationEvent implements Event<Null> {
CELL_STYLE_MODIFY,
CELL_IMAGE_VALUE_MODIFY
}

5
designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java

@ -72,6 +72,7 @@ import com.fr.start.OemHandler;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import java.util.concurrent.CopyOnWriteArrayList;
import org.jetbrains.annotations.Nullable;
import javax.swing.Icon;
@ -133,7 +134,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
private static final Integer TOP_LAYER = 200;
private List<DesignerOpenedListener> designerOpenedListenerList = new ArrayList<>();
private List<DesignerOpenedListener> designerOpenedListenerList = new CopyOnWriteArrayList<>();
private ToolBarMenuDock ad;
@ -485,6 +486,8 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
if (!DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isEnabled()) {
ad.createAlphaFinePane().setVisible(false);
}
northEastPane.add(ad.createNotificationCenterPane());
OSSupportCenter.buildAction(new OSBasedAction() {
@Override
public void execute(Object... objects) {

8
designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java

@ -11,10 +11,10 @@ import com.fr.design.dialog.BasicPane;
import com.fr.design.event.TargetModifiedEvent;
import com.fr.design.event.TargetModifiedListener;
import java.awt.BorderLayout;
import java.awt.Component;
import javax.swing.JComponent;
import javax.swing.JLayeredPane;
import java.awt.BorderLayout;
import java.awt.Component;
/**
@ -53,12 +53,11 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener
// 判断是否切换设计器状态到禁止拷贝剪切
if (jt.getTarget().getAttrMark(DesignBanCopyAttrMark.XML_TAG) != null) {
DesignModeContext.switchTo(DesignerMode.BAN_COPY_AND_CUT);
} else if (!DesignModeContext.isVcsMode() && !DesignModeContext.isAuthorityEditing()){
} else if (!DesignModeContext.isVcsMode() && !DesignModeContext.isAuthorityEditing()) {
DesignModeContext.switchTo(DesignerMode.NORMAL);
}
DesignerFrameFileDealerPane.getInstance().setCurrentEditingTemplate(jt);
if (component != null) {
component.onLostFocus();
layeredPane.remove(component);
}
component = jt;
@ -69,7 +68,6 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener
repaint();
revalidate();
component.requestGridFocus();
component.onGetFocus();
}

73
designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java

@ -13,8 +13,12 @@ import com.fr.design.gui.ibutton.UIButtonUI;
import com.fr.design.gui.icontainer.UIEastResizableContainer;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.VerticalFlowLayout;
import com.fr.design.mainframe.reuse.ReuseGuideDialog;
import com.fr.design.mainframe.reuse.SnapChatKeys;
import com.fr.design.mainframe.share.collect.ComponentCollector;
import com.fr.design.menu.SnapChatUtil;
import com.fr.design.notification.SnapChat;
import com.fr.design.notification.SnapChatFactory;
import com.fr.design.ui.util.UIUtil;
import com.fr.design.utils.DesignUtils;
import com.fr.design.utils.gui.GUICoreUtils;
@ -97,6 +101,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
private JPanel defaultPane; // "无可用配置项"面板
private JPanel defaultAuthorityPane; // "该元素不支持权限编辑"
private PropertyItem selectedItem; // 当前被选中的属性配置项
private SnapChat widgetLibSnapChat;
public enum PropertyMode {
REPORT, // 报表
@ -297,9 +302,22 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
"hyperlink", new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_PARA, PropertyMode.REPORT_PARA_WIDGET, PropertyMode.REPORT_FLOAT, PropertyMode.POLY, PropertyMode.POLY_CHART},
new PropertyMode[]{PropertyMode.REPORT, PropertyMode.REPORT_FLOAT, PropertyMode.FORM_REPORT, PropertyMode.POLY_REPORT});
// 组件库
PropertyItem widgetLib = new PropertyItem(KEY_WIDGET_LIB, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Library"),
"widgetlib", new PropertyMode[]{PropertyMode.FORM},
new PropertyMode[]{PropertyMode.FORM});
widgetLibSnapChat = SnapChatFactory.createSnapChat(false, SnapChatKeys.COMPONENT);
PropertyItem widgetLib = new PropertyItem(
KEY_WIDGET_LIB,
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Library"),
"widgetlib",
new PropertyMode[]{PropertyMode.FORM},
new PropertyMode[]{PropertyMode.FORM},
getWidgetLibSnapChat(),
getWidgetLibPromptWindow(),
new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
ComponentCollector.getInstance().collectCmpBoardClick();
ComponentReuseNotifyUtil.enterWidgetLibExtraAction(true);
}
});
// 权限编辑
PropertyItem authorityEdition = new PropertyItem(KEY_AUTHORITY_EDITION, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Permissions_Edition"),
"authorityedit", new PropertyMode[]{PropertyMode.AUTHORITY_EDITION_DISABLED},
@ -514,6 +532,17 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
propertyItemMap.get(KEY_WIDGET_LIB).replaceContentPane(pane);
}
public SnapChat getWidgetLibSnapChat() {
return widgetLibSnapChat;
}
public PromptWindow getWidgetLibPromptWindow() {
if (!getWidgetLibSnapChat().hasRead()) {
return new ReuseGuideDialog(DesignerContext.getDesignerFrame());
}
return null;
}
public JComponent getWidgetLibPane() {
return propertyItemMap.get(KEY_WIDGET_LIB).getContentPane();
}
@ -595,6 +624,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
if (propertyItem.isVisible() && propertyItem.isEnabled() && !propertyItem.isPoppedOut()) {
propertyCard.show(rightPane, tabName);
propertyItem.setTabButtonSelected();
propertyItem.processSnapChat();
//从单元格菜单过来也要关闭弹出窗
hideCurrentPopupPane();
}
@ -713,19 +743,33 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
private String iconSuffix = ICON_SUFFIX_NORMAL; // normal, diabled, selected, 三者之一
private final Color selectedBtnBackground = new Color(0xF5F5F7);
private Color originBtnBackground;
private ActionListener actionListener;
public PropertyItem(String name, String title, String btnIconName, PropertyMode[] visibleModes, PropertyMode[] enableModes) {
this(name, title, btnIconName, ICON_BASE_DIR, visibleModes, enableModes, null, null);
}
public PropertyItem(String name, String title, String btnIconName, PropertyMode[] visibleModes, PropertyMode[] enableModes, SnapChat snapChat, PromptWindow promptWindow, ActionListener actionListener) {
this(name, title, btnIconName, ICON_BASE_DIR, visibleModes, enableModes, snapChat, promptWindow, actionListener);
}
public PropertyItem(String name, String title, String btnIconName, PropertyMode[] visibleModes, PropertyMode[] enableModes, ActionListener actionListener) {
this(name, title, btnIconName, ICON_BASE_DIR, visibleModes, enableModes, null, null, actionListener);
}
public PropertyItem(String name, String title, String btnIconName, String iconBaseDir, PropertyMode[] visibleModes, PropertyMode[] enableModes, SnapChat snapChat, PromptWindow promptWindow) {
this(name, title, btnIconName, iconBaseDir, visibleModes, enableModes, snapChat, promptWindow, null);
}
public PropertyItem(String name, String title, String btnIconName, String iconBaseDir, PropertyMode[] visibleModes, PropertyMode[] enableModes, SnapChat snapChat, PromptWindow promptWindow, ActionListener actionListener) {
this.name = name;
this.title = title;
this.btnIconName = btnIconName;
this.iconBaseDir = iconBaseDir;
this.snapChat = snapChat;
this.promptWindow = promptWindow;
this.actionListener = actionListener;
initButton();
initPropertyPanel();
initModes(visibleModes, enableModes);
@ -925,9 +969,6 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (snapChat != null && !snapChat.hasRead()) {
SnapChatUtil.paintPropertyItemPoint(g, getBounds());
}
}
};
button.setDisabledIcon(IconUtils.readIcon(getIconBaseDir() + btnIconName + ICON_SUFFIX_DISABLED));
@ -956,17 +997,25 @@ public class EastRegionContainerPane extends UIEastResizableContainer {
popupFixedPane();
}
setTabButtonSelected();
if (snapChat != null && !snapChat.hasRead()) {
snapChat.markRead();
if (promptWindow != null) {
promptWindow.showWindow();
}
}
processSnapChat();
}
});
if (actionListener != null) {
button.addActionListener(actionListener);
}
button.setToolTipText(title);
}
public void processSnapChat(){
if (snapChat != null && !snapChat.hasRead()) {
snapChat.markRead();
if (promptWindow != null) {
promptWindow.showWindow();
}
}
}
public UIButton getButton() {
return button;
}

136
designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java

@ -39,7 +39,6 @@ import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.chart.info.ChartInfoCollector;
import com.fr.design.mainframe.check.CheckButton;
import com.fr.design.mainframe.template.info.TemplateInfoCollector;
import com.fr.design.mainframe.template.info.TemplateProcessInfo;
import com.fr.design.mainframe.template.info.TimeConsumeTimer;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
@ -79,7 +78,6 @@ import com.fr.stable.core.UUID;
import com.fr.workspace.WorkContext;
import com.fr.workspace.server.lock.TplOperator;
import java.util.concurrent.Callable;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.JComponent;
@ -91,6 +89,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.concurrent.Callable;
/**
* 报表设计和表单设计的编辑区域(设计器编辑的IO文件)
@ -107,16 +106,34 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
protected U undoState;
protected U authorityUndoState = null;
protected T template; // 当前模板
protected TemplateProcessInfo<T> processInfo; // 模板过程的相关信息
/**
* 模板过程的相关信息
*
* @deprecated move to cloud ops plugin,left only for compatible
*/
@Deprecated
protected TemplateProcessInfo<T> processInfo;
private JComponent centerPane;
private static short currentIndex = 0;// 此变量用于多次新建模板时,让名字不重复
private DesignModelAdapter<T, ?> designModel;
private PreviewProvider previewType;
/**
* 统计模板制作耗时
*
* @deprecated move to cloud ops plugin,left only for compatible
*/
@Deprecated
protected TimeConsumeTimer consumeTimer = new TimeConsumeTimer();
private volatile boolean saving = false;
private volatile boolean opening = false;
private volatile boolean openFailed = false;
/**
* UI界面模板运行时唯一的id 不存储在模板中 仅在运行时使用 模板界面上关闭就不关注了
*/
private final String runtimeId = UUID.randomUUID().toString();
private PluginEventListener pluginListener;
public JTemplate() {
@ -161,7 +178,6 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
addCenterPane();
this.undoState = createUndoState();
consumeTimer.setEnabled(shouldInitForCollectInfo(isNewFile));
initAndStartPlugin();
}
@ -206,21 +222,22 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
/**
* @deprecated move to cloud ops pluginleft only for compatible
*/
@Deprecated
void onGetFocus() {
consumeTimer.start();
}
/**
* @deprecated move to cloud ops pluginleft only for compatible
*/
@Deprecated
void onLostFocus() {
consumeTimer.stop();
}
private boolean shouldInitForCollectInfo(boolean isNewFile) {
if (isNewFile) {
return true;
}
// 不是新建模板,但是已经在收集列表中
return TemplateInfoCollector.getInstance().contains(template.getTemplateID());
}
// 刷新右侧属性面板
public abstract void refreshEastPropertiesPane();
@ -229,30 +246,33 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
public abstract JComponent getCurrentReportComponentPane();
// 为收集模版信息作准备
private void initForCollect() {
/**
* 为另存的模板创建新的模板id
*/
private void generateNewTemplateIdForSaveAs() {
generateTemplateId();
consumeTimer.setEnabled(true);
consumeTimer.start();
}
private void collectInfo() { // 执行收集操作
collectInfo(StringUtils.EMPTY);
/**
* 收集图表信息
*/
private void collectInfo() {
ChartInfoCollector.getInstance().collectInfo(template.getTemplateID(), StringUtils.EMPTY, getProcessInfo(), 0);
}
private void collectInfo(String originID) { // 执行收集操作
/**
* 另存模板时收集图表信息
*
* @param originID 原始模板id
*/
private void collectInfoWhenSaveAs(String originID) {
ChartInfoCollector.getInstance().collectInfo(template.getTemplateID(), originID, getProcessInfo(), 0);
if (!consumeTimer.isEnabled()) {
return;
}
try {
int timeConsume = consumeTimer.popTime();
TemplateInfoCollector.getInstance().collectInfo(template.getTemplateID(), originID, getProcessInfo(), timeConsume);
} catch (Throwable th) { // 不管收集过程中出现任何异常,都不应该影响模版保存
}
consumeTimer.start(); // 准备下一次计算
}
/**
* @deprecated move to cloud ops plugin
*/
@Deprecated
public abstract TemplateProcessInfo<T> getProcessInfo();
public U getUndoState() {
@ -347,7 +367,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
/**
* 刷新内部资源
*
* <p>
* 刷新资源的同时
* CenterPane 负责监听改动
* 所以需要同步处理
@ -415,7 +435,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
protected abstract DesignModelAdapter<T, ?> createDesignModel();
protected DesignModelAdapter<T, ?> createDesignModel(Parameter[] parameters) {
protected DesignModelAdapter<T, ?> createDesignModel(Parameter[] parameters) {
// 空实现 兼容下
return null;
}
@ -675,6 +695,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
/**
* Web预览的时候需要隐藏掉除报表运行环境外的路径(C盘D盘等) isShowLoc = false
* 被云端运维插件修改用于收集埋点
*
* @param isShowLoc 是否本地
* @return 保存成功返回true
@ -767,20 +788,24 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
// 保存新模板时会进入此方法(新建模板直接保存,或者另存为)
/**
* 保存新模板时会进入此方法新建模板直接保存或者另存为
* 被云端运维插件修改用于收集埋点
*/
protected boolean saveNewFile(FILE editingFILE, String oldName) {
String originID = StringUtils.EMPTY;
if (StringUtils.isNotEmpty(this.template.getTemplateID())) {
originID = this.template.getTemplateID();
String currentId = this.template.getTemplateID();
if (StringUtils.isNotEmpty(currentId)) {
originID = currentId;
}
// 在保存之前,初始化 templateID
initForCollect();
generateNewTemplateIdForSaveAs();
this.editingFILE = editingFILE;
boolean result = this.saveToNewFile(oldName);
if (result) {
DesignerFrameFileDealerPane.getInstance().refresh();
collectInfo(originID);
collectInfoWhenSaveAs(originID);
}
return result;
}
@ -792,7 +817,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
result = result || provider.saveToNewFile(this.editingFILE.getPath(), this);
}
if (!result) {
result = result || this.saveFile();
result = this.saveFile();
//更换最近打开
DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(oldName, this.getPath());
this.refreshToolArea();
@ -871,10 +896,10 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
/**
* @return java.lang.Integer WorkBook11.cpt则返回11如果没有找到index返回null
* @Description 返回文件名中的index
* @param: prefix 前缀
* @param: fileName 文件名称全名
* @return java.lang.Integer WorkBook11.cpt则返回11如果没有找到index返回null
* @Author Henry.Wang
* @Date 2021/4/9 11:13
**/
@ -1411,8 +1436,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
CallbackSaveWorker worker = new CallbackSaveWorker(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
collectInfo();
return JTemplate.this.saveRealFile();
return saveRealFileByWorker();
}
}, this);
@ -1426,6 +1450,14 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
return worker;
}
/**
* 被云端运维插件修改用于收集埋点
*/
private boolean saveRealFileByWorker() throws Exception {
collectInfo();
return saveRealFile();
}
private void callBackForSave() {
JTemplate.this.saved = true;
JTemplate.this.authoritySaved = true;
@ -1465,9 +1497,6 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
editingFILE = fileChooser.getSelectedFILE();
}
//收集和生成templateID 因为是另存为操作 无论怎么样都需要重新生成templateID
initForCollect();
FILE finalEditingFILE = editingFILE;
CallbackSaveWorker worker = new CallbackSaveWorker(new Callable<Boolean>() {
@Override
@ -1482,7 +1511,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
callBackForSave();
// 当前打开的是正在保存的模板才刷新
if (ComparatorUtils.equals(JTemplate.this.template.getTemplateID(),
HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().template.getTemplateID())) {
HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().template.getTemplateID())) {
refreshToolArea();
}
DesignerFrameFileDealerPane.getInstance().refresh();
@ -1511,13 +1540,23 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
}
}
/**
* 另存为时在 save worker 中保存实际的文件;
* 被云端运维插件修改用于收集埋点
*/
private boolean saveNewRealFile(FILE editingFILE, String oldName) throws Exception {
consumeTimer.setEnabled(true);
consumeTimer.start();
String originID = StringUtils.EMPTY;
String currentId = this.template.getTemplateID();
if (StringUtils.isNotEmpty(currentId)) {
originID = currentId;
}
// 在保存之前,初始化 templateID
generateNewTemplateIdForSaveAs();
this.editingFILE = editingFILE;
boolean result = this.saveToNewRealFile(oldName);
if (result) {
collectInfo(this.template.getTemplateID());
collectInfoWhenSaveAs(originID);
}
return result;
}
@ -1549,13 +1588,13 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
@Override
public void saveDirectly() {
CallbackSaveWorker worker = save();
worker.start(this.template.getTemplateID());
worker.start(getRuntimeId());
}
@Override
public void saveAsDirectly() {
CallbackSaveWorker worker = saveAs();
worker.start(this.template.getTemplateID());
worker.start(getRuntimeId());
}
@Override
@ -1596,4 +1635,7 @@ public abstract class JTemplate<T extends BaseBook, U extends BaseUndoState<?>>
return !isSaving() && !isOpening() && !isOpenFailed();
}
public String getRuntimeId() {
return runtimeId;
}
}

2
designer-base/src/main/java/com/fr/design/mainframe/burying/point/AbstractPointCollector.java

@ -29,7 +29,9 @@ import java.util.concurrent.ConcurrentHashMap;
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-02-21
* @deprecated moved to Cloud Ops plugin
*/
@Deprecated
public abstract class AbstractPointCollector<T extends AbstractPointInfo> implements BasePointCollector {
protected Map<String, T> pointInfoMap;

2
designer-base/src/main/java/com/fr/design/mainframe/burying/point/AbstractPointInfo.java

@ -6,7 +6,9 @@ import java.util.List;
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-02-21
* @deprecated moved to Cloud Ops plugin
*/
@Deprecated
public abstract class AbstractPointInfo implements BasePointInfo {
protected int idleDayCount; // 到现在为止,埋点闲置的天数

2
designer-base/src/main/java/com/fr/design/mainframe/burying/point/BasePointCollector.java

@ -8,7 +8,9 @@ import com.fr.stable.xml.XMLWriter;
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-02-21
* @deprecated moved to Cloud Ops plugin
*/
@Deprecated
public interface BasePointCollector extends XMLReadable, XMLWriter {
/**

2
designer-base/src/main/java/com/fr/design/mainframe/burying/point/BasePointInfo.java

@ -10,7 +10,9 @@ import java.util.Map;
* @author Bjorn
* @version 10.0
* Created by Bjorn on 2020-02-21
* @deprecated moved to Cloud Ops plugin
*/
@Deprecated
public interface BasePointInfo extends XMLReadable, XMLWriter {
/**

5
designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfo.java

@ -5,7 +5,6 @@ import com.fr.chartx.attr.ChartProvider;
import com.fr.chartx.config.info.AbstractConfig;
import com.fr.chartx.config.info.ChartConfigInfo;
import com.fr.chartx.config.info.constant.ConfigType;
import com.fr.config.MarketConfig;
import com.fr.design.DesignModelAdapter;
import com.fr.design.DesignerEnvManager;
import com.fr.design.file.HistoryTemplateListCache;
@ -132,8 +131,8 @@ public class ChartInfo extends AbstractPointInfo implements Comparable<ChartInfo
public static ChartInfo newInstance(ChartProvider chartProvider, String createTime, boolean isNew, boolean isReuse, boolean isAutoChart) {
HashMap<String, String> chartConsumingMap = new HashMap<>();
String username = MarketConfig.getInstance().getBbsUsername();
String userId = String.valueOf(MarketConfig.getInstance().getBbsUid());
String username = DesignerEnvManager.getEnvManager().getDesignerLoginUsername();
String userId = String.valueOf(DesignerEnvManager.getEnvManager().getDesignerLoginUid());
String uuid = DesignerEnvManager.getEnvManager().getUUID();
String activityKey = DesignerEnvManager.getEnvManager().getActivationKey();
String chartId = chartProvider.getChartUuid();

20
designer-base/src/main/java/com/fr/design/mainframe/chart/info/ChartInfoCollector.java

@ -5,7 +5,6 @@ import com.fr.chartx.attr.ChartProvider;
import com.fr.chartx.config.info.AbstractConfig;
import com.fr.chartx.config.info.constant.ConfigType;
import com.fr.design.mainframe.burying.point.AbstractPointCollector;
import com.fr.design.mainframe.template.info.TemplateInfo;
import com.fr.design.mainframe.template.info.TemplateProcessInfo;
import com.fr.general.ComparatorUtils;
import com.fr.stable.StringUtils;
@ -31,6 +30,9 @@ public class ChartInfoCollector extends AbstractPointCollector<ChartInfo> {
private static final String XML_CHART_INFO_LIST = "ChartInfoList";
private static final String XML_FILE_NAME = "chart.info";
private static final int VALID_CELL_COUNT = 5; // 有效报表模板的格子数
private static final int VALID_WIDGET_COUNT = 5; // 有效报表模板的控件数
private static ChartInfoCollector instance;
private Map<String, ChartInfo> chartInfoCacheMap;
@ -217,10 +219,10 @@ public class ChartInfoCollector extends AbstractPointCollector<ChartInfo> {
int floatCount = processInfo.getFloatCount();
int blockCount = processInfo.getBlockCount();
int widgetCount = processInfo.getWidgetCount();
return TemplateInfo.isTestTemplate(reportType, cellCount, floatCount, blockCount, widgetCount);
return isTestTemplate(reportType, cellCount, floatCount, blockCount, widgetCount);
}
/**
* 更新 day_count打开设计器却未编辑图表的连续日子
*/
@ -282,4 +284,16 @@ public class ChartInfoCollector extends AbstractPointCollector<ChartInfo> {
writer.end();
}
private boolean isTestTemplate(int reportType, int cellCount, int floatCount, int blockCount, int widgetCount) {
boolean isTestTemplate;
if (reportType == 0) { // 普通报表
isTestTemplate = cellCount <= VALID_CELL_COUNT && floatCount <= 1 && widgetCount <= VALID_WIDGET_COUNT;
} else if (reportType == 1) { // 聚合报表
isTestTemplate = blockCount <= 1 && widgetCount <= VALID_WIDGET_COUNT;
} else { // 表单(reportType == 2)
isTestTemplate = widgetCount <= 1;
}
return isTestTemplate;
}
}

6
designer-base/src/main/java/com/fr/design/mainframe/check/CheckButton.java

@ -116,7 +116,7 @@ public class CheckButton extends UIButton {
startCheck(checkThread);
}
});
worker.start(jtemplate.getTarget().getTemplateID());
worker.start(jtemplate.getRuntimeId());
}
} else {
if (!jtemplate.isSaved()) {
@ -127,7 +127,7 @@ public class CheckButton extends UIButton {
startCheck(checkThread);
}
});
worker.start(jtemplate.getTarget().getTemplateID());
worker.start(jtemplate.getRuntimeId());
} else {
startCheck(checkThread);
}
@ -148,7 +148,7 @@ public class CheckButton extends UIButton {
startCheck(checkThread);
}
});
worker.start(jtemplate.getTarget().getTemplateID());
worker.start(jtemplate.getRuntimeId());
}
}
}

87
designer-base/src/main/java/com/fr/design/mainframe/reuse/ComponentReuseNotificationInfo.java

@ -0,0 +1,87 @@
package com.fr.design.mainframe.reuse;
import com.fr.design.DesignerEnvManager;
import com.fr.stable.xml.XMLPrintWriter;
import com.fr.stable.xml.XMLable;
import com.fr.stable.xml.XMLableReader;
/**
* Created by kerry on 5/8/21
*/
public class ComponentReuseNotificationInfo implements XMLable {
public static final String XML_TAG = "ComponentReuseNotificationInfo";
private static final ComponentReuseNotificationInfo INSTANCE = new ComponentReuseNotificationInfo();
public static ComponentReuseNotificationInfo getInstance() {
return INSTANCE;
}
private long lastNotifyTime = 0;
private int notifiedNumber = 0;
private boolean clickedWidgetLib = false;
private long lastGuidePopUpTime = 0;
public long getLastNotifyTime() {
return lastNotifyTime;
}
public void setLastNotifyTime(long lastNotifyTime) {
this.lastNotifyTime = lastNotifyTime;
}
public int getNotifiedNumber() {
return notifiedNumber;
}
public void setNotifiedNumber(int notifiedNumber) {
this.notifiedNumber = notifiedNumber;
}
public boolean isClickedWidgetLib() {
return clickedWidgetLib;
}
public void setClickedWidgetLib(boolean clickedWidgetLib) {
this.clickedWidgetLib = clickedWidgetLib;
}
public long getLastGuidePopUpTime() {
return lastGuidePopUpTime;
}
public void setLastGuidePopUpTime(long lastGuidePopUpTime) {
this.lastGuidePopUpTime = lastGuidePopUpTime;
}
public void updateLastGuidePopUpTime() {
this.setLastGuidePopUpTime(System.currentTimeMillis());
DesignerEnvManager.getEnvManager().saveXMLFile();
}
@Override
public void readXML(XMLableReader reader) {
this.setLastNotifyTime(reader.getAttrAsLong("lastNotifyTime", 0L));
this.setNotifiedNumber(reader.getAttrAsInt("notifiedNumber", 0));
this.setClickedWidgetLib(reader.getAttrAsBoolean("clickedWidgetLib", false));
this.setLastGuidePopUpTime(reader.getAttrAsLong("lastGuidePopUpTime", 0L));
}
@Override
public void writeXML(XMLPrintWriter writer) {
writer.startTAG("ComponentReuseNotificationInfo");
writer.attr("lastNotifyTime", this.lastNotifyTime)
.attr("notifiedNumber", this.notifiedNumber)
.attr("clickedWidgetLib", this.clickedWidgetLib)
.attr("lastGuidePopUpTime", this.lastGuidePopUpTime);
writer.end();
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}

169
designer-base/src/main/java/com/fr/design/mainframe/reuse/ReuseGuideDialog.java

@ -0,0 +1,169 @@
package com.fr.design.mainframe.reuse;
import com.fr.base.background.ColorBackground;
import com.fr.design.dialog.UIDialog;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.PromptWindow;
import com.fr.design.mainframe.share.collect.ComponentCollector;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.IOUtils;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.geom.RoundRectangle2D;
public class ReuseGuideDialog extends UIDialog implements PromptWindow {
InnerDialog innerDialog;
private static final Dimension DEFAULT = new Dimension(735, 510);
public ReuseGuideDialog(Frame parent) {
super(parent);
}
@Override
public void showWindow() {
innerDialog = new InnerDialog(this);
JPanel backGroundPane = new JPanel() {
@Override
protected void paintComponent(Graphics g) {
Image icon = IOUtils.readImage("com/fr/base/images/share/background.png");// 003.jpg是测试图片在项目的根目录下
g.drawImage(icon, 0, 0, getSize().width, getSize().height, this);// 图片会自动缩放
}
};
add(backGroundPane, BorderLayout.CENTER);
initStyle();
innerDialog.showWindow();
}
private void initStyle() {
setSize(DEFAULT);
setUndecorated(true);
setBackground(new Color(0, 0, 0, 0));
GUICoreUtils.centerWindow(this);
}
@Override
public void hideWindow() {
ComponentReuseNotificationInfo.getInstance().updateLastGuidePopUpTime();
this.setVisible(false);
if (innerDialog != null) {
innerDialog.setVisible(false);
innerDialog.dispose();
innerDialog = null;
}
this.dispose();
}
@Override
public void checkValid() {
}
class InnerDialog extends UIDialog {
private final Dimension DEFAULT = new Dimension(700, 475);
private static final int TITLE_FONT_SIZE = 20;
public InnerDialog(Dialog dialog) {
super(dialog);
}
public void showWindow() {
add(createCenterPanel(), BorderLayout.CENTER);
add(createSouthPanel(), BorderLayout.SOUTH);
add(createNorthPanel(), BorderLayout.NORTH);
showDialog();
}
private JPanel createNorthPanel() {
JPanel northPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
//右上角关闭按钮
JButton button = new JButton(new ImageIcon(IOUtils.readImage("/com/fr/base/images/share/close.png").getScaledInstance(15, 15, Image.SCALE_SMOOTH)));
button.setBorder(null);
button.setOpaque(false);
button.addActionListener(e -> ReuseGuideDialog.this.hideWindow());
northPanel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 15));
northPanel.setOpaque(false);
northPanel.add(button);
return northPanel;
}
private JPanel createCenterPanel() {
JPanel centerPanel = new JPanel(new BorderLayout());
UILabel titleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Share_Drag_And_Make_Component"));
UILabel imageLabel = new UILabel(new ImageIcon(IOUtils.readImage("com/fr/design/images/dashboard/guide.png").getScaledInstance(DEFAULT.width, DEFAULT.height, Image.SCALE_SMOOTH)));
titleLabel.setFont(new Font(titleLabel.getFont().getName(), Font.BOLD, TITLE_FONT_SIZE));
titleLabel.setBorder(BorderFactory.createEmptyBorder());
JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
panel.setOpaque(false);
panel.add(titleLabel);
centerPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0));
centerPanel.setOpaque(false);
centerPanel.add(imageLabel, BorderLayout.CENTER);
centerPanel.add(panel, BorderLayout.NORTH);
return centerPanel;
}
private JPanel createSouthPanel() {
JPanel southPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
JButton button = new JButton(Toolkit.i18nText("Fine-Design_Share_Try_Drag")) {
@Override
public void paint(Graphics g) {
ColorBackground buttonBackground = ColorBackground.getInstance(Color.decode("#419BF9"));
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
buttonBackground.paint(g2d, new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), 8, 8));
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF);
super.paint(g);
}
};
button.setBorder(null);
button.setForeground(Color.WHITE);
button.setOpaque(false);
button.addActionListener(e -> ReuseGuideDialog.this.hideWindow());
southPanel.setBorder(BorderFactory.createEmptyBorder(0, 290, 19, 290));
southPanel.setPreferredSize(new Dimension(DEFAULT.width, 51));
southPanel.setOpaque(false);
southPanel.add(button);
return southPanel;
}
/**
* 显示窗口
*/
private void showDialog() {
setSize(DEFAULT);
setUndecorated(true);
GUICoreUtils.centerWindow(this);
setModalityType(ModalityType.APPLICATION_MODAL);
ReuseGuideDialog.this.setVisible(true);
setVisible(true);
}
@Override
public void checkValid() {
}
}
}

32
designer-base/src/main/java/com/fr/design/mainframe/reuse/SnapChatKeys.java

@ -0,0 +1,32 @@
package com.fr.design.mainframe.reuse;
import com.fr.design.notification.SnapChatKey;
/**
* created by Harrison on 2020/03/24
**/
public enum SnapChatKeys implements SnapChatKey {
/**
* 组件
*/
COMPONENT("components"),
/**
* 模板
*/
TEMPLATE("template");
private String sign;
private static final String PREFIX = "com.fr.component.share";
SnapChatKeys(String sign) {
this.sign = sign;
}
@Override
public String calc() {
return PREFIX + "-" + sign;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save