forked from fanruan/design
Browse Source
* commit '79da1e36da825bfa007876b3124f208c9a5f2b75': (176 commits) 代码修改 REPORT-54355 ReuFilter 远程兼容问题 REPORT-54361 组件复用-合入主版本-接触点优化-MarkReadMap为true&&clickedWidgetLib为false时,点套用组件入口,没弹出已合入主版本的提示;点组件库,可以弹出@kerry REPORT-54308 模板缺失插件设计改进设计器提供配置 REPORT-54306 【稳定共创】在“配置工作目录”界面,切换远程后没有消息提醒 REPORT-54332 mac设计器:帆软通行证在插件管理打开时的提示文本被插件管理遮挡 REPORT-54317 登录页面优化-密码登录-UI问题 REPORT-54252 登录页面-手机区号无法下拉选择 REPORT-54301 点击模板商城支持单点登录 REPORT-54277 消息推送-消息中心-看不到推送的消息 REPORT-54277 消息推送-消息中心-看不到推送的消息 REPORT-54277 消息推送-消息中心-看不到推送的消息 REPORT-53647 下载路由修改 REPORT-51958 设计器通知中心调整 REPORT-53625 设计器用户登录策略调整-登录触发页面显示不全 代码修改 代码修改 增加username参数 REPORT-53647【组件复用涉及到登录相关功能】设计器本身是没有登录的,换成最新的nightly后,打开设计器后无论是否登录,下载在线组件都会提示失败@lanla REPORT-53775 条件属性弹窗概率性 关闭不了 ...persist/10.0 10.0.17.2021.06.24
superman
3 years ago
458 changed files with 42415 additions and 3711 deletions
@ -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.login.AbstractDesignerSSO; |
||||||
|
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 AbstractDesignerSSO { |
||||||
|
|
||||||
|
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 String getJumpUrl() { |
||||||
|
ComponentCollector.getInstance().collectTepMenuEnterClick(); |
||||||
|
return CloudCenter.getInstance().acquireUrlByKind("design.market.template", "https://market.fanruan.com/template"); |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,240 @@ |
|||||||
|
package com.fr.design.dialog; |
||||||
|
|
||||||
|
|
||||||
|
import com.fr.concurrent.NamedThreadFactory; |
||||||
|
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.notification.Notification; |
||||||
|
import com.fr.design.notification.NotificationCenter; |
||||||
|
import com.fr.module.ModuleContext; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
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 java.util.concurrent.ScheduledExecutorService; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
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 static final String HIDE_MSG = "HIDE_MSG_TIMER"; |
||||||
|
private UILabel messageText; |
||||||
|
private NotificationDialogAction notificationDialogAction; |
||||||
|
private ScheduledExecutorService TIMER; |
||||||
|
|
||||||
|
public NotificationDialog(Frame owner, String title, boolean isModal, int messageType, String message, NotificationDialogAction action) { |
||||||
|
super(owner); |
||||||
|
setTitle(title); |
||||||
|
initComponents(StringUtils.EMPTY, messageType, message, isModal, action); |
||||||
|
} |
||||||
|
|
||||||
|
public NotificationDialog(Builder builder) { |
||||||
|
super(builder.owner); |
||||||
|
setTitle(builder.title); |
||||||
|
initComponents(builder.messageId, builder.messageType, builder.message, builder.modal, builder.action); |
||||||
|
} |
||||||
|
|
||||||
|
public void initComponents(String messageId, int messageType, String message, boolean isModal, NotificationDialogAction action) { |
||||||
|
NotificationCenter.getInstance().addNotification(new Notification(messageId, messageType, message, action)); |
||||||
|
notificationDialogAction = action; |
||||||
|
setModal(isModal); |
||||||
|
setFocusable(false); |
||||||
|
setAutoRequestFocus(false); |
||||||
|
setResizable(false); |
||||||
|
JPanel body = FRGUIPaneFactory.createBorderLayout_L_Pane(); |
||||||
|
body.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); |
||||||
|
|
||||||
|
//消息内容
|
||||||
|
UILabel icon = new UILabel(getIconForType(messageType)); |
||||||
|
JPanel iconPanel = FRGUIPaneFactory.createBorderLayout_L_Pane(); |
||||||
|
iconPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 10, 8)); |
||||||
|
iconPanel.add(icon); |
||||||
|
body.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(8, 0, 5, 20)); |
||||||
|
JScrollPane jScrollPane = new JScrollPane(messageText, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); |
||||||
|
jScrollPane.setBorder(BorderFactory.createEmptyBorder()); |
||||||
|
centerPanel.add(jScrollPane, BorderLayout.CENTER); |
||||||
|
centerPanel.setPreferredSize(new Dimension(230, 95)); |
||||||
|
body.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); |
||||||
|
body.add(detailPanel, BorderLayout.SOUTH); |
||||||
|
|
||||||
|
detailLabel.addMouseListener(detailClickListener); |
||||||
|
messageText.addMouseListener(detailClickListener); |
||||||
|
addMouseListener(bodyMouseListener); |
||||||
|
|
||||||
|
add(body); |
||||||
|
Dimension dimension = body.getPreferredSize(); |
||||||
|
setSize(dimension.width, dimension.height); |
||||||
|
setLocation((DesignerContext.getDesignerFrame().getWidth() - dimension.width - 30 + DesignerContext.getDesignerFrame().getX()), |
||||||
|
DesignerContext.getDesignerFrame().getY() + DesignerContext.getDesignerFrame().getHeight() - dimension.height - 30); |
||||||
|
disappear(); |
||||||
|
} |
||||||
|
|
||||||
|
private MouseListener detailClickListener = new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
if (notificationDialogAction != null) { |
||||||
|
hideDialog(); |
||||||
|
notificationDialogAction.doClick(); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
private MouseListener bodyMouseListener = new MouseAdapter() { |
||||||
|
@Override |
||||||
|
public void mouseEntered(MouseEvent e) { |
||||||
|
if (TIMER != null) { |
||||||
|
TIMER.shutdownNow(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseExited(MouseEvent e) { |
||||||
|
disappear(); |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
public void disappear() { |
||||||
|
TIMER = createScheduleExecutorService(); |
||||||
|
TIMER.schedule(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
hideDialog(); |
||||||
|
} |
||||||
|
}, 10000, TimeUnit.MILLISECONDS); |
||||||
|
} |
||||||
|
|
||||||
|
private ScheduledExecutorService createScheduleExecutorService() { |
||||||
|
return ModuleContext.getExecutor().newSingleThreadScheduledExecutor(new NamedThreadFactory(HIDE_MSG)); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置通知消息 |
||||||
|
*/ |
||||||
|
public void setMessage(String message) { |
||||||
|
messageText.setText(HTML_TAG_1 + message + HTML_TAG_2); |
||||||
|
} |
||||||
|
|
||||||
|
private void hideDialog() { |
||||||
|
this.setVisible(false); |
||||||
|
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 messageId; |
||||||
|
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 messageId(String messageId) { |
||||||
|
this.messageId = messageId; |
||||||
|
return 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; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public static void defaultPopup(String messageId, String title, String body, NotificationDialogAction action) { |
||||||
|
NotificationDialog.Builder() |
||||||
|
.messageId(messageId) |
||||||
|
.owner(DesignerContext.getDesignerFrame()) |
||||||
|
.title(title) |
||||||
|
.modal(false) |
||||||
|
.messageType(NotificationDialog.NEW_MESSAGE) |
||||||
|
.message(body) |
||||||
|
.notificationDialogAction(action) |
||||||
|
.build() |
||||||
|
.setVisible(true); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,8 @@ |
|||||||
|
package com.fr.design.dialog; |
||||||
|
|
||||||
|
public interface NotificationDialogAction { |
||||||
|
|
||||||
|
String name(); |
||||||
|
|
||||||
|
void doClick(); |
||||||
|
} |
@ -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 { |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -1,8 +1,10 @@ |
|||||||
package com.fr.design.extra; |
package com.fr.design.extra; |
||||||
|
|
||||||
|
import com.fr.design.login.DesignerLoginSource; |
||||||
|
|
||||||
/** |
/** |
||||||
* Created by lp on 2016/8/16. |
* Created by lp on 2016/8/16. |
||||||
*/ |
*/ |
||||||
public interface LoginContextListener { |
public interface LoginContextListener { |
||||||
void showLoginContext(); |
void showLoginContext(DesignerLoginSource source); |
||||||
} |
} |
||||||
|
@ -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; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -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(); |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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 { |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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)); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
@ -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)); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
@ -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)); |
||||||
|
} |
||||||
|
} |
||||||
|
}; |
||||||
|
} |
||||||
|
} |
@ -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()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -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(); |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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 { |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,112 @@ |
|||||||
|
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 { |
||||||
|
pullLatestMessage(); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
}, DELAY, TimeUnit.MINUTES); |
||||||
|
service.shutdown(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private void pullLatestMessage() 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)) { |
||||||
|
parseLatestMessage(response.optJSONObject(DATA)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void parseLatestMessage(JSONObject 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.defaultPopup(messageId, title, body, new NotificationDialogAction() { |
||||||
|
@Override |
||||||
|
public String name() { |
||||||
|
return jumpTo; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doClick() { |
||||||
|
String ssoUrl = DesignerLoginUtils.generateDesignerSSOUrl(jumpTo); |
||||||
|
BrowseUtils.browser(ssoUrl); |
||||||
|
} |
||||||
|
}); |
||||||
|
} else if (notificationJumpType == NotificationJumpType.DESIGNER_MODULE) { |
||||||
|
NotificationActionType notificationActionType = NotificationActionType.valueOf(jumpTo); |
||||||
|
NotificationDialog.defaultPopup(messageId, title, body, notificationActionType.getAction()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,92 @@ |
|||||||
|
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.mainframe.BaseJForm; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.EastRegionContainerPane; |
||||||
|
import com.fr.design.mainframe.JTemplate; |
||||||
|
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.bridge.StableFactory; |
||||||
|
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 NotificationActionType { |
||||||
|
PLUGIN("PLUGIN", new NotificationDialogAction() { |
||||||
|
@Override |
||||||
|
public String name() { |
||||||
|
return "PLUGIN"; |
||||||
|
} |
||||||
|
|
||||||
|
@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 String name() { |
||||||
|
return "REUSE"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doClick() { |
||||||
|
try { |
||||||
|
BaseJForm jform = StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, BaseJForm.class); |
||||||
|
DesignerContext.getDesignerFrame().addAndActivateJTemplate((JTemplate<?, ?>) jform); |
||||||
|
EastRegionContainerPane.getInstance().showContainer(); |
||||||
|
EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_LIB); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
}), |
||||||
|
UNKNOWN(StringUtils.EMPTY, new NotificationDialogAction() { |
||||||
|
@Override |
||||||
|
public String name() { |
||||||
|
return "UNKNOWN"; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doClick() { |
||||||
|
} |
||||||
|
}); |
||||||
|
|
||||||
|
private String jumpTo; |
||||||
|
private NotificationDialogAction action; |
||||||
|
|
||||||
|
NotificationActionType(String jumpTo, NotificationDialogAction action) { |
||||||
|
this.jumpTo = jumpTo; |
||||||
|
this.action = action; |
||||||
|
} |
||||||
|
|
||||||
|
public String getJumpTo() { |
||||||
|
return jumpTo; |
||||||
|
} |
||||||
|
|
||||||
|
public NotificationDialogAction getAction() { |
||||||
|
return action; |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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; |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
@ -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); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,89 @@ |
|||||||
|
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.awt.Window; |
||||||
|
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(Window parent) { |
||||||
|
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"), |
||||||
|
parent |
||||||
|
); |
||||||
|
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)); |
||||||
|
} |
||||||
|
} |
@ -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() { |
||||||
|
if (ComponentReuseNotificationInfo.getInstance().isClickedWidgetLib()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
SnapChat snapChat = SnapChatFactory.createSnapChat(false, new SnapChatKey() { |
||||||
|
@Override |
||||||
|
public String calc() { |
||||||
|
return COMPONENT_SNAP_CHAT_KEY; |
||||||
|
} |
||||||
|
}); |
||||||
|
if (snapChat.hasRead()) { |
||||||
|
DesignerToastMsgUtil.toastPrompt(Toolkit.i18nText("Fine-Design_Component_Reuse_Merge_Prompt")); |
||||||
|
} |
||||||
|
ComponentReuseNotificationInfo.getInstance().setClickedWidgetLib(true); |
||||||
|
DesignerEnvManager.getEnvManager().saveXMLFile(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
} |
@ -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 |
||||||
|
|
||||||
|
} |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue