roger
2 years ago
15 changed files with 763 additions and 28 deletions
@ -0,0 +1,194 @@ |
|||||||
|
package com.fr.design.mainframe.toast; |
||||||
|
|
||||||
|
import com.fr.concurrent.NamedThreadFactory; |
||||||
|
import com.fr.design.dialog.UIDialog; |
||||||
|
import com.fr.design.gui.ilable.UILabel; |
||||||
|
import com.fr.design.layout.FRGUIPaneFactory; |
||||||
|
import com.fr.module.ModuleContext; |
||||||
|
|
||||||
|
import javax.swing.BorderFactory; |
||||||
|
import javax.swing.Icon; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import javax.swing.SwingUtilities; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Point; |
||||||
|
import java.awt.Window; |
||||||
|
import java.util.concurrent.ScheduledExecutorService; |
||||||
|
import java.util.concurrent.TimeUnit; |
||||||
|
|
||||||
|
/** |
||||||
|
* toast弹窗 |
||||||
|
* */ |
||||||
|
public class SimpleToast extends UIDialog { |
||||||
|
private static final int MIN_HEIGHT = 36; |
||||||
|
private static final String TOAST_MSG_TIMER = "TOAST_MSG_TIMER"; |
||||||
|
private static final long DEFAULT_DISAPPEAR_DELAY = 5000; |
||||||
|
private static final TimeUnit DEFAULT_TIME_UNIT = TimeUnit.MILLISECONDS; |
||||||
|
|
||||||
|
|
||||||
|
private ScheduledExecutorService timer; |
||||||
|
private int hideHeight = 0; |
||||||
|
private JPanel contentPane; |
||||||
|
private boolean show = false; |
||||||
|
private Window parent; |
||||||
|
private boolean autoDisappear; |
||||||
|
|
||||||
|
public SimpleToast(Window parent, Icon icon, String text, boolean autoDisappear) { |
||||||
|
super(parent); |
||||||
|
this.parent = parent; |
||||||
|
this.autoDisappear = autoDisappear; |
||||||
|
JPanel panel = createContentPane(icon, text); |
||||||
|
init(panel); |
||||||
|
} |
||||||
|
|
||||||
|
private JPanel createContentPane(Icon icon, String text) { |
||||||
|
JPanel pane = FRGUIPaneFactory.createBorderLayout_S_Pane(); |
||||||
|
|
||||||
|
UILabel iconLabel = new UILabel(icon); |
||||||
|
iconLabel.setVerticalAlignment(SwingConstants.TOP); |
||||||
|
iconLabel.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); |
||||||
|
|
||||||
|
|
||||||
|
UILabel textLabel = new UILabel(text); |
||||||
|
pane.add(iconLabel, BorderLayout.WEST); |
||||||
|
pane.add(textLabel, BorderLayout.CENTER); |
||||||
|
pane.setBorder(BorderFactory.createEmptyBorder(8, 15, 8, 15)); |
||||||
|
|
||||||
|
return pane; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void init(JPanel panel) { |
||||||
|
setFocusable(false); |
||||||
|
setAutoRequestFocus(false); |
||||||
|
setUndecorated(true); |
||||||
|
contentPane = panel; |
||||||
|
initComponent(); |
||||||
|
} |
||||||
|
|
||||||
|
private void initComponent() { |
||||||
|
this.getContentPane().setLayout(null); |
||||||
|
this.getContentPane().add(contentPane); |
||||||
|
Dimension dimension = calculatePreferSize(); |
||||||
|
hideHeight = dimension.height; |
||||||
|
setSize(new Dimension(dimension.width, 0)); |
||||||
|
contentPane.setSize(dimension); |
||||||
|
setRelativeLocation(dimension); |
||||||
|
if (autoDisappear) { |
||||||
|
disappear(contentPane); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void setRelativeLocation(Dimension dimension) { |
||||||
|
int positionX = parent.getLocationOnScreen().x + (parent.getWidth() - dimension.width) / 2; |
||||||
|
int positionY = parent.getLocationOnScreen().y + 10; |
||||||
|
this.setLocation(positionX, positionY); |
||||||
|
} |
||||||
|
|
||||||
|
private Dimension calculatePreferSize() { |
||||||
|
Dimension contentDimension = contentPane.getPreferredSize(); |
||||||
|
int height = Math.max(MIN_HEIGHT, contentDimension.height); |
||||||
|
return new Dimension(contentDimension.width, height); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public void display(JPanel outerPanel) { |
||||||
|
show = true; |
||||||
|
outerPanel.setLocation(0, -hideHeight); |
||||||
|
ScheduledExecutorService tipToolTimer = createToastScheduleExecutorService(); |
||||||
|
tipToolTimer.scheduleAtFixedRate(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
SwingUtilities.invokeLater(()->{ |
||||||
|
displayStep(outerPanel, tipToolTimer); |
||||||
|
}); |
||||||
|
} |
||||||
|
}, 0, 50, TimeUnit.MILLISECONDS); |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
void displayStep(JPanel outerPanel, ScheduledExecutorService timer) { |
||||||
|
Point point = outerPanel.getLocation(); |
||||||
|
if (point.y >= 0 && !timer.isShutdown()) { |
||||||
|
timer.shutdown(); |
||||||
|
} |
||||||
|
int showDistance = 5 + point.y < 0 ? 5 : -point.y; |
||||||
|
outerPanel.setLocation(point.x, point.y + showDistance); |
||||||
|
Dimension dimension = SimpleToast.this.getSize(); |
||||||
|
SimpleToast.this.setSize(new Dimension(dimension.width, dimension.height + showDistance)); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private void disappear(JPanel outerPanel, long delay, TimeUnit timeUnit) { |
||||||
|
timer = createToastScheduleExecutorService(); |
||||||
|
timer.schedule(new DisappearMotion(outerPanel), delay, timeUnit); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* toast消失的动画效果 |
||||||
|
* */ |
||||||
|
class DisappearMotion implements Runnable { |
||||||
|
JPanel panel; |
||||||
|
|
||||||
|
DisappearMotion(JPanel panel) { |
||||||
|
this.panel = panel; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
ScheduledExecutorService tipToolTimer = createToastScheduleExecutorService(); |
||||||
|
tipToolTimer.scheduleAtFixedRate(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
SwingUtilities.invokeLater(()->{ |
||||||
|
disappearStep(tipToolTimer); |
||||||
|
}); |
||||||
|
} |
||||||
|
}, 0, 50, TimeUnit.MILLISECONDS); |
||||||
|
} |
||||||
|
|
||||||
|
void disappearStep(ScheduledExecutorService timer) { |
||||||
|
Point point = panel.getLocation(); |
||||||
|
if (point.y <= -hideHeight && !timer.isShutdown()) { |
||||||
|
timer.shutdown(); |
||||||
|
SimpleToast.this.setVisible(false); |
||||||
|
SimpleToast.this.dispose(); |
||||||
|
SimpleToast.this.show = false; |
||||||
|
} |
||||||
|
panel.setLocation(point.x, point.y - 5); |
||||||
|
Dimension dimension = SimpleToast.this.getSize(); |
||||||
|
SimpleToast.this.setSize(new Dimension(dimension.width, dimension.height - 5)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void disappear(JPanel outerPanel) { |
||||||
|
disappear(outerPanel, DEFAULT_DISAPPEAR_DELAY, DEFAULT_TIME_UNIT); |
||||||
|
} |
||||||
|
|
||||||
|
private ScheduledExecutorService createToastScheduleExecutorService() { |
||||||
|
return ModuleContext.getExecutor().newSingleThreadScheduledExecutor(new NamedThreadFactory(TOAST_MSG_TIMER)); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void checkValid() throws Exception { |
||||||
|
} |
||||||
|
|
||||||
|
public void setVisible(boolean visible) { |
||||||
|
super.setVisible(visible); |
||||||
|
if (visible) { |
||||||
|
display(contentPane); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void dispose() { |
||||||
|
super.dispose(); |
||||||
|
} |
||||||
|
|
||||||
|
} |
@ -0,0 +1,10 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.download; |
||||||
|
|
||||||
|
public class FineMarketConstants { |
||||||
|
|
||||||
|
public static final String REPORTLETS = "/reportlets"; |
||||||
|
public static final String ZIP = ".zip"; |
||||||
|
public static final String RAR = ".rar"; |
||||||
|
public static final String CPT = ".cpt"; |
||||||
|
public static final String FRM = ".frm"; |
||||||
|
} |
@ -0,0 +1,149 @@ |
|||||||
|
package com.fr.design.mainframe.alphafine.download; |
||||||
|
|
||||||
|
import com.fr.base.svg.IconUtils; |
||||||
|
import com.fr.common.util.Strings; |
||||||
|
import com.fr.design.DesignerEnvManager; |
||||||
|
import com.fr.design.extra.Process; |
||||||
|
import com.fr.design.i18n.Toolkit; |
||||||
|
import com.fr.design.login.DesignerLoginHelper; |
||||||
|
import com.fr.design.login.DesignerLoginSource; |
||||||
|
import com.fr.design.mainframe.alphafine.AlphaFineHelper; |
||||||
|
import com.fr.design.mainframe.alphafine.model.TemplateResource; |
||||||
|
import com.fr.design.mainframe.alphafine.search.helper.FineMarketClientHelper; |
||||||
|
import com.fr.design.mainframe.toast.SimpleToast; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.third.jodd.io.ZipUtil; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
|
||||||
|
import javax.swing.SwingUtilities; |
||||||
|
import java.awt.Window; |
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
import java.util.HashMap; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 在这里统一管理帆软市场的下载 |
||||||
|
* 下载的流程控制尽量都在这个类内部完成 |
||||||
|
* 通过Process类来实现下载流程控制 |
||||||
|
* */ |
||||||
|
public class FineMarketDownloadManager { |
||||||
|
|
||||||
|
private static final FineMarketDownloadManager INSTANCE = new FineMarketDownloadManager(); |
||||||
|
public static final FineMarketDownloadManager getInstance() { |
||||||
|
return INSTANCE; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public static final double PROCESS_SUCCESS = 1d; |
||||||
|
public static final double PROCESS_FAILED = -1d; |
||||||
|
public static final double OPENING_FILE = 2d; |
||||||
|
|
||||||
|
private static final String OPENING_PLEASE_WAIT = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Resource_Opening"); |
||||||
|
private static final String DOWNLOAD_FAILED = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Template_Resource_Download_Failed_Check_Network"); |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 下载资源并解压 |
||||||
|
* */ |
||||||
|
public String installResource(TemplateResource resource, Window parentWindow){ |
||||||
|
// 验证登录
|
||||||
|
String token = DesignerEnvManager.getEnvManager().getDesignerLoginRefreshToken(); |
||||||
|
if (Strings.isEmpty(token)) { |
||||||
|
DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL, new HashMap<>(), AlphaFineHelper.getAlphaFineDialog()); |
||||||
|
return null; |
||||||
|
} |
||||||
|
return install(resource, parentWindow); |
||||||
|
} |
||||||
|
|
||||||
|
private String install(TemplateResource resource, Window parentWindow) { |
||||||
|
// 获取报表录作为下载位置
|
||||||
|
String workDir = WorkContext.getCurrent().getPath() + FineMarketConstants.REPORTLETS; |
||||||
|
File destDir = new File(workDir); |
||||||
|
|
||||||
|
DownloadProcess downloadProcess = new DownloadProcess(parentWindow); |
||||||
|
String fileName = null; |
||||||
|
try { |
||||||
|
fileName = FineMarketClientHelper.getInstance().download(resource, destDir, downloadProcess); |
||||||
|
unzip(fileName, downloadProcess); |
||||||
|
return fileName; |
||||||
|
} catch (Exception e) { |
||||||
|
downloadProcess.process(FineMarketDownloadManager.PROCESS_FAILED); |
||||||
|
FineLoggerFactory.getLogger().error(e, e.getMessage()); |
||||||
|
} |
||||||
|
return null; |
||||||
|
} |
||||||
|
|
||||||
|
void unzip(String fileName, DownloadProcess process) throws IOException { |
||||||
|
process.process(OPENING_FILE); |
||||||
|
|
||||||
|
if (fileName.endsWith(FineMarketConstants.ZIP)) { |
||||||
|
File file = new File(fileName); |
||||||
|
File parentDir = file.getParentFile(); |
||||||
|
ZipUtil.unzip(file, parentDir); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 下载流程控制,主要控制ui的显示 |
||||||
|
* */ |
||||||
|
class DownloadProcess implements Process<Double> { |
||||||
|
|
||||||
|
SimpleToast downloadingToast; |
||||||
|
SimpleToast openingToast; |
||||||
|
SimpleToast failedToast; |
||||||
|
Window parent; |
||||||
|
|
||||||
|
public DownloadProcess(Window parentWindow) { |
||||||
|
this.parent = parentWindow; |
||||||
|
init(); |
||||||
|
} |
||||||
|
|
||||||
|
void init() { |
||||||
|
showLoadingToast(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void process(Double aDouble) { |
||||||
|
SwingUtilities.invokeLater(()->{ |
||||||
|
if (aDouble == PROCESS_FAILED) { |
||||||
|
downloadFailed(); |
||||||
|
} else if (aDouble == PROCESS_SUCCESS) { |
||||||
|
downloadSuccess(); |
||||||
|
} else if (aDouble == OPENING_FILE) { |
||||||
|
openingFile(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public void downloadFailed() { |
||||||
|
downloadingToast.setVisible(false); |
||||||
|
showFailedToast(); |
||||||
|
} |
||||||
|
|
||||||
|
public void downloadSuccess() { |
||||||
|
downloadingToast.setVisible(false); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private void openingFile() { |
||||||
|
downloadingToast.setVisible(false); |
||||||
|
openingToast = new SimpleToast(AlphaFineHelper.getAlphaFineDialog(), IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/loading.svg"), OPENING_PLEASE_WAIT, true); |
||||||
|
openingToast.setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
private void showLoadingToast() { |
||||||
|
downloadingToast = new SimpleToast(AlphaFineHelper.getAlphaFineDialog(), IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/loading.svg"), OPENING_PLEASE_WAIT, false); |
||||||
|
downloadingToast.setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
private void showFailedToast() { |
||||||
|
failedToast = new SimpleToast(AlphaFineHelper.getAlphaFineDialog(), IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/caution.svg"), DOWNLOAD_FAILED, true); |
||||||
|
failedToast.setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,67 @@ |
|||||||
|
package com.fr.market.key; |
||||||
|
|
||||||
|
import com.fr.general.IOUtils; |
||||||
|
import com.fr.io.utils.ResourceIOUtils; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream; |
||||||
|
import java.io.IOException; |
||||||
|
import java.io.InputStream; |
||||||
|
import java.util.HashMap; |
||||||
|
import java.util.Map; |
||||||
|
import java.util.Properties; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Link |
||||||
|
* @version 11.0 |
||||||
|
* Created by Yvan on 2022/8/25 |
||||||
|
*/ |
||||||
|
public class FineMarketDefaultKeyProperties { |
||||||
|
|
||||||
|
private Properties properties = new Properties(); |
||||||
|
|
||||||
|
private Map<String, String> publicKeyMap = new HashMap<>(); |
||||||
|
|
||||||
|
private String propertyPath; |
||||||
|
|
||||||
|
private FineMarketDefaultKeyProperties(String propertyPath) { |
||||||
|
this.propertyPath = propertyPath; |
||||||
|
load(); |
||||||
|
} |
||||||
|
|
||||||
|
public static FineMarketDefaultKeyProperties create(String propertyPath) { |
||||||
|
return new FineMarketDefaultKeyProperties(propertyPath); |
||||||
|
} |
||||||
|
|
||||||
|
private void load() { |
||||||
|
try (InputStream inputStream = IOUtils.readResource(getPropertyPath())) { |
||||||
|
byte[] data = ResourceIOUtils.inputStream2Bytes(inputStream); |
||||||
|
properties.load(new ByteArrayInputStream(data)); |
||||||
|
trims(properties); |
||||||
|
publicKeyMap.put(FineMarketPublicKeyConstants.DEFAULT_KEY_KEY, properties.getProperty(FineMarketPublicKeyConstants.DEFAULT_KEY_KEY)); |
||||||
|
} catch (IOException e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private String getPropertyPath() { |
||||||
|
return this.propertyPath; |
||||||
|
} |
||||||
|
|
||||||
|
public String getPublicKey() { |
||||||
|
return publicKeyMap.get(FineMarketPublicKeyConstants.DEFAULT_KEY_KEY); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 去除properties中value末尾的空格 |
||||||
|
* @param properties |
||||||
|
*/ |
||||||
|
public static void trims(Properties properties) { |
||||||
|
for (String key : properties.stringPropertyNames()) { |
||||||
|
String value = properties.getProperty(key); |
||||||
|
if (value != null) { |
||||||
|
properties.put(key, value.trim()); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,29 @@ |
|||||||
|
package com.fr.market.key; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @author Link |
||||||
|
* @version 11.0 |
||||||
|
* Created by Link on 2022/8/25 |
||||||
|
*/ |
||||||
|
public class FineMarketPublicKeyConstants { |
||||||
|
|
||||||
|
public static final String DEFAULT_KEY_KEY = "defaultKey"; |
||||||
|
|
||||||
|
public static final String DEFAULT_KEY_DIRECTORY = "/com/fr/market/key"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 公钥第一段 |
||||||
|
*/ |
||||||
|
public static final String FIRST_PROPERTY = "76c1/default"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 公钥第二段 |
||||||
|
*/ |
||||||
|
public static final String SECOND_PROPERTY = "943f/default"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 公钥第三段 |
||||||
|
*/ |
||||||
|
public static final String THIRD_PROPERTY = "d8a3/default"; |
||||||
|
} |
@ -0,0 +1,48 @@ |
|||||||
|
package com.fr.market.key; |
||||||
|
|
||||||
|
import com.fr.stable.StableUtils; |
||||||
|
|
||||||
|
/** |
||||||
|
* 帆软市场公钥Holder |
||||||
|
* @author Link |
||||||
|
* @version 10.0 |
||||||
|
* Created by Link on 2022/8/25 |
||||||
|
*/ |
||||||
|
public class FineMarketPublicKeyHolder { |
||||||
|
|
||||||
|
private static FineMarketPublicKeyHolder instance = null; |
||||||
|
|
||||||
|
private String defaultKey; |
||||||
|
|
||||||
|
public static FineMarketPublicKeyHolder getInstance() { |
||||||
|
|
||||||
|
if (instance == null) { |
||||||
|
synchronized (FineMarketPublicKeyHolder.class) { |
||||||
|
if (instance == null) { |
||||||
|
instance = new FineMarketPublicKeyHolder(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
return instance; |
||||||
|
} |
||||||
|
|
||||||
|
private FineMarketPublicKeyHolder() { |
||||||
|
init(); |
||||||
|
} |
||||||
|
|
||||||
|
private void init() { |
||||||
|
// 读取三个default.properties文件,组成公钥
|
||||||
|
String firstPart = FineMarketDefaultKeyProperties.create(StableUtils.pathJoin(FineMarketPublicKeyConstants.DEFAULT_KEY_DIRECTORY, FineMarketPublicKeyConstants.FIRST_PROPERTY)).getPublicKey(); |
||||||
|
String secondPart = FineMarketDefaultKeyProperties.create(StableUtils.pathJoin(FineMarketPublicKeyConstants.DEFAULT_KEY_DIRECTORY, FineMarketPublicKeyConstants.SECOND_PROPERTY)).getPublicKey(); |
||||||
|
String thirdPart = FineMarketDefaultKeyProperties.create(StableUtils.pathJoin(FineMarketPublicKeyConstants.DEFAULT_KEY_DIRECTORY, FineMarketPublicKeyConstants.THIRD_PROPERTY)).getPublicKey(); |
||||||
|
this.defaultKey = firstPart + secondPart + thirdPart; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取默认公钥 |
||||||
|
* @return 公钥 |
||||||
|
*/ |
||||||
|
public String getDefaultKey() { |
||||||
|
return this.defaultKey; |
||||||
|
} |
||||||
|
} |
After Width: | Height: | Size: 820 B |
After Width: | Height: | Size: 936 B |
@ -0,0 +1 @@ |
|||||||
|
defaultKey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtsz62CPSWXZE/IYZRiAuTSZkw |
@ -0,0 +1 @@ |
|||||||
|
defaultKey=1WOwer8+JFktK0uKLAUuQoBr+UjAMFtRA8W7JgKMDwZy/2liEAiXEOSPU/hrdV8D |
Loading…
Reference in new issue