Browse Source

Pull request #9842: REPORT-78647【运营产品化二期】单模板目前点击立即使用未下载

Merge in DESIGN/design from ~LINK.ZHAO/design:feature/x to feature/x

* commit 'd77fd0fca1e10971837a39c337a62fd1b3f089a0':
  REPORT-78647【运营产品化二期】单模板目前点击立即使用未下载 1、修改pr
  REPORT-78647【运营产品化二期】单模板目前点击立即使用未下载 1、修改pr
  REPORT-78647【运营产品化二期】单模板目前点击立即使用未下载 1、修改pr
  REPORT-78647【运营产品化二期】单模板目前点击立即使用未下载 1、修改pr
  REPORT-78647【运营产品化二期】单模板目前点击立即使用未下载 1、浏览器下载实现不了,改用设计器内部下载 2、下载到工作目录下
feature/x
Link.Zhao 2 years ago
parent
commit
c4dbb5dc57
  1. 5
      designer-base/src/main/java/com/fr/design/dialog/UIDialog.java
  2. 194
      designer-base/src/main/java/com/fr/design/mainframe/toast/SimpleToast.java
  3. 63
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/action/StartUseAction.java
  4. 10
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/download/FineMarketConstants.java
  5. 149
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/download/FineMarketDownloadManager.java
  6. 20
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/TemplateResource.java
  7. 195
      designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/helper/FineMarketClientHelper.java
  8. 67
      designer-realize/src/main/java/com/fr/market/key/FineMarketDefaultKeyProperties.java
  9. 29
      designer-realize/src/main/java/com/fr/market/key/FineMarketPublicKeyConstants.java
  10. 48
      designer-realize/src/main/java/com/fr/market/key/FineMarketPublicKeyHolder.java
  11. 5
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/caution.svg
  12. 3
      designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/loading.svg
  13. 1
      designer-realize/src/main/resources/com/fr/market/key/76c1/default
  14. 1
      designer-realize/src/main/resources/com/fr/market/key/943f/default
  15. 1
      designer-realize/src/main/resources/com/fr/market/key/d8a3/default

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

@ -18,6 +18,7 @@ import java.awt.BorderLayout;
import java.awt.Dialog; import java.awt.Dialog;
import java.awt.FlowLayout; import java.awt.FlowLayout;
import java.awt.Frame; import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.awt.event.KeyEvent; import java.awt.event.KeyEvent;
@ -44,6 +45,10 @@ public abstract class UIDialog extends JDialog {
super(parent); super(parent);
} }
public UIDialog(Window parent) {
super(parent);
}
public UIDialog(Frame parent, BasicPane pane) { public UIDialog(Frame parent, BasicPane pane) {
this(parent, pane, true); this(parent, pane, true);

194
designer-base/src/main/java/com/fr/design/mainframe/toast/SimpleToast.java

@ -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();
}
}

63
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/action/StartUseAction.java

@ -1,10 +1,20 @@
package com.fr.design.mainframe.alphafine.action; package com.fr.design.mainframe.alphafine.action;
import com.fr.common.util.Strings;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.alphafine.AlphaFineHelper;
import com.fr.design.mainframe.alphafine.download.FineMarketConstants;
import com.fr.design.mainframe.alphafine.download.FineMarketDownloadManager;
import com.fr.design.mainframe.alphafine.model.TemplateResourceDetail; import com.fr.design.mainframe.alphafine.model.TemplateResourceDetail;
import com.fr.design.mainframe.alphafine.search.helper.FineMarketClientHelper; import com.fr.file.FileFILE;
import com.fr.log.FineLoggerFactory;
import javax.swing.SwingWorker;
import java.awt.Desktop;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
import java.awt.event.ActionListener; import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
/** /**
@ -24,6 +34,53 @@ public class StartUseAction implements ActionListener {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
FineMarketClientHelper.getInstance().openBrowserAndDownload(resourceDetail.getRoot()); new SwingWorker<String, Void>() {
@Override
protected String doInBackground() throws Exception {
return FineMarketDownloadManager.getInstance().installResource(resourceDetail.getRoot(), AlphaFineHelper.getAlphaFineDialog());
}
@Override
protected void done() {
try {
open(get());
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
super.done();
}
}.execute();
}
void open(String fileName) throws IOException {
if (Strings.isEmpty(fileName)) {
return;
}
File fileNeedOpen = new File(fileName);
if (fileName.endsWith(FineMarketConstants.ZIP)) {
File[] files = fileNeedOpen.listFiles();
fileNeedOpen = getFirstCptOrFrm(files);
} else if (fileName.endsWith(FineMarketConstants.RAR)) {
// rar直接打开系统文件夹
File parentDir = new File(fileName).getParentFile();
Desktop.getDesktop().open(parentDir);
return;
}
openInDesigner(fileNeedOpen);
}
void openInDesigner(File file) {
DesignerContext.getDesignerFrame().openTemplate(new FileFILE(file));
}
private File getFirstCptOrFrm(File[] files) {
for (File f : files) {
if (f.getName().endsWith(FineMarketConstants.CPT) || f.getName().endsWith(FineMarketConstants.FRM)) {
return f;
}
}
return null;
} }
} }

10
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/download/FineMarketConstants.java

@ -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";
}

149
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/download/FineMarketDownloadManager.java

@ -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);
}
}
}

20
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/TemplateResource.java

@ -1,6 +1,8 @@
package com.fr.design.mainframe.alphafine.model; package com.fr.design.mainframe.alphafine.model;
import com.fr.common.util.Strings;
import com.fr.design.i18n.Toolkit; import com.fr.design.i18n.Toolkit;
import com.fr.design.mainframe.alphafine.download.FineMarketConstants;
import com.fr.design.mainframe.alphafine.search.manager.impl.TemplateResourceSearchManager; import com.fr.design.mainframe.alphafine.search.manager.impl.TemplateResourceSearchManager;
import com.fr.general.IOUtils; import com.fr.general.IOUtils;
import com.fr.json.JSONArray; import com.fr.json.JSONArray;
@ -46,6 +48,7 @@ public class TemplateResource {
public static final String IMAGE_URL = "pic"; public static final String IMAGE_URL = "pic";
public static final String DEMO_URL = "demoUrl"; public static final String DEMO_URL = "demoUrl";
public static final String PKG_SIZE = "pkgsize"; public static final String PKG_SIZE = "pkgsize";
public static final String FILE_NAME = "fileLoca";
private static final String RECOMMEND_SEARCH_IMG_URL = "com/fr/design/mainframe/alphafine/images/more.png"; private static final String RECOMMEND_SEARCH_IMG_URL = "com/fr/design/mainframe/alphafine/images/more.png";
@ -57,6 +60,7 @@ public class TemplateResource {
private Image image; private Image image;
private String name; private String name;
private String demoUrl; private String demoUrl;
private String fileName;
private int pkgSize; private int pkgSize;
private List<String> recommendSearchKey; private List<String> recommendSearchKey;
@ -74,7 +78,7 @@ public class TemplateResource {
public static TemplateResource createByJson(JSONObject jsonObject) { public static TemplateResource createByJson(JSONObject jsonObject) {
TemplateResource templateResource = new TemplateResource().setId(jsonObject.getString(ID)).setUuid(jsonObject.getString(UUID)).setName(jsonObject.getString(NAME)) TemplateResource templateResource = new TemplateResource().setId(jsonObject.getString(ID)).setUuid(jsonObject.getString(UUID)).setName(jsonObject.getString(NAME))
.setDemoUrl(jsonObject.getString(DEMO_URL)).setPkgSize(jsonObject.getInt(PKG_SIZE)); .setDemoUrl(jsonObject.getString(DEMO_URL)).setPkgSize(jsonObject.getInt(PKG_SIZE)).setFileName(jsonObject.getString(FILE_NAME));
int pkgSize = templateResource.getPkgSize(); int pkgSize = templateResource.getPkgSize();
if (pkgSize == 0) { if (pkgSize == 0) {
templateResource.type = Type.SINGLE_TEMPLATE; templateResource.type = Type.SINGLE_TEMPLATE;
@ -110,6 +114,20 @@ public class TemplateResource {
} }
public String getFileName() {
return fileName;
}
public TemplateResource setFileName(String fileName) {
if (Strings.isEmpty(fileName)) {
this.fileName = getName() + FineMarketConstants.ZIP;
} else {
this.fileName = fileName;
}
return this;
}
public Type getType() { public Type getType() {
return type; return type;
} }

195
designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/helper/FineMarketClientHelper.java

@ -1,18 +1,42 @@
package com.fr.design.mainframe.alphafine.search.helper; package com.fr.design.mainframe.alphafine.search.helper;
import com.fr.design.DesignerEnvManager;
import com.fr.design.extra.PluginConstants;
import com.fr.design.mainframe.alphafine.download.FineMarketDownloadManager;
import com.fr.design.mainframe.alphafine.model.TemplateResource; import com.fr.design.mainframe.alphafine.model.TemplateResource;
import com.fr.design.utils.BrowseUtils; import com.fr.file.FileCommonUtils;
import com.fr.general.CloudCenter; import com.fr.general.CloudCenter;
import com.fr.general.http.HttpToolbox; import com.fr.general.http.HttpToolbox;
import com.fr.json.JSONArray; import com.fr.json.JSONArray;
import com.fr.json.JSONObject; import com.fr.json.JSONObject;
import com.fr.log.FineLoggerFactory;
import com.fr.market.key.FineMarketPublicKeyHolder;
import com.fr.security.SecurityToolbox;
import com.fr.stable.StableUtils;
import com.fr.third.org.apache.http.HttpEntity;
import com.fr.third.org.apache.http.HttpException;
import com.fr.third.org.apache.http.HttpStatus;
import com.fr.third.org.apache.http.client.config.CookieSpecs;
import com.fr.third.org.apache.http.client.config.RequestConfig;
import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse;
import com.fr.third.org.apache.http.client.methods.HttpUriRequest;
import com.fr.third.org.apache.http.client.methods.RequestBuilder;
import com.fr.third.org.apache.http.impl.client.BasicCookieStore;
import com.fr.third.org.apache.http.impl.client.CloseableHttpClient;
import com.fr.third.org.apache.http.impl.client.HttpClients;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class FineMarketClientHelper { public class FineMarketClientHelper {
private static final FineMarketClientHelper INSTANCE = new FineMarketClientHelper(); private static final FineMarketClientHelper INSTANCE = new FineMarketClientHelper();
@ -20,10 +44,10 @@ public class FineMarketClientHelper {
return INSTANCE; return INSTANCE;
} }
private static final String CERTIFICATE_PUBLIC_KEY = FineMarketPublicKeyHolder.getInstance().getDefaultKey();
public static final String FINE_MARKET_TEMPLATE_INFO = CloudCenter.getInstance().acquireUrlByKind("market.template.info"); public static final String FINE_MARKET_TEMPLATE_INFO = CloudCenter.getInstance().acquireUrlByKind("market.template.info");
public static final String FINE_MARKET_TEMPLATE_URL = CloudCenter.getInstance().acquireUrlByKind("market.template.url"); public static final String FINE_MARKET_TEMPLATE_URL = CloudCenter.getInstance().acquireUrlByKind("market.template.url");
public static final String LOGIN_FINE_CLUB_AND_REDIRECT_SHOP = CloudCenter.getInstance().acquireUrlByKind("af.login.redirect.market"); public static final String FILE_DOWNLOAD = "file/download/";
public static final String FILE_DOWNLOAD = "file/";
public static final String PACKAGE_DOWNLOAD = "package/download/"; public static final String PACKAGE_DOWNLOAD = "package/download/";
public static final String TEMPLATES_PARENT_PACKAGE = "parent/"; public static final String TEMPLATES_PARENT_PACKAGE = "parent/";
public static final String TEMPLATES_TAGS = "filter"; public static final String TEMPLATES_TAGS = "filter";
@ -46,44 +70,167 @@ public class FineMarketClientHelper {
* */ * */
public String getResourceDownloadUrl(TemplateResource templateResource) { public String getResourceDownloadUrl(TemplateResource templateResource) {
if (TemplateResource.Type.SCENARIO_SOLUTION.equals(templateResource.getType())) { if (TemplateResource.Type.SCENARIO_SOLUTION.equals(templateResource.getType())) {
return getPackageDownloadUrl(templateResource.getId()); return getPackageDownloadUrl();
} else { } else {
return getFileDownLoadUrl(templateResource.getId()); return getFileDownLoadUrl();
} }
} }
public void openBrowserAndDownload(TemplateResource templateResource) { private String getPackageDownloadUrl() {
String url = LOGIN_FINE_CLUB_AND_REDIRECT_SHOP; return FINE_MARKET_TEMPLATE_INFO + PACKAGE_DOWNLOAD;
if (TemplateResource.Type.SCENARIO_SOLUTION.equals(templateResource.getType())) { }
url += getPackageDownloadUrl(templateResource.getId());
private String getFileDownLoadUrl() {
return FINE_MARKET_TEMPLATE_INFO + FILE_DOWNLOAD;
}
public String download(TemplateResource resource, File destDir, com.fr.design.extra.Process<Double> process) throws Exception {
String resourceId = resource.getId();
CloseableHttpResponse fileRes = getFileResponse(resource, resourceId);
if (fileRes.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
File destFile = createDestFile(destDir, resource);
StableUtils.makesureFileExist(destFile);
InputStream content = null;
FileOutputStream writer = null;
try {
writer = new FileOutputStream(FileCommonUtils.getAbsolutePath(destFile));
HttpEntity entity = fileRes.getEntity();
long totalSize = entity.getContentLength();
content = entity.getContent();
byte[] data = new byte[PluginConstants.BYTES_NUM];
int bytesRead;
int totalBytesRead = 0;
while ((bytesRead = content.read(data)) > 0) {
writer.write(data, 0, bytesRead);
data = new byte[PluginConstants.BYTES_NUM];
totalBytesRead += bytesRead;
process.process(totalBytesRead / (double) totalSize);
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
} finally {
content.close();
writer.flush();
writer.close();
}
FineLoggerFactory.getLogger().info("download resource{} success", resourceId);
process.process(FineMarketDownloadManager.PROCESS_SUCCESS);
return FileCommonUtils.getAbsolutePath(destFile);
} else { } else {
url += getFileDownLoadUrl(templateResource.getId()); FineLoggerFactory.getLogger().info("download resource{} failed", resourceId);
process.process(FineMarketDownloadManager.PROCESS_FAILED);
throw new HttpException();
} }
BrowseUtils.browser(url);
} }
/**
* 暂时没有package的下载接口需要用户在浏览器点击下载 private CloseableHttpResponse getFileResponse(TemplateResource resource, String resourceId) throws Exception {
* */ CloseableHttpResponse fileRes = postDownloadHttpResponse(getResourceDownloadUrl(resource), resourceId);
private String getPackageDownloadUrl(String id) { if (fileRes.getStatusLine().getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY) {
return getTemplateUrlById(id); fileRes = getDownloadHttpResponse(fileRes.getHeaders("Location")[0].getValue());
}
return fileRes;
} }
/** /**
* 打开浏览器下载单一模板 * 在目标路径下destDir创建与资源名称相同的文件夹 (finalDir)
* 将资源下载到 destDir/finalDir
* 如果文件重复则在文件名前加自增id
* */ * */
private String getFileDownLoadUrl(String id) { private File createDestFile(File destDir, TemplateResource resource) {
return FINE_MARKET_TEMPLATE_INFO + FILE_DOWNLOAD + id; String fileName = resource.getName();
try {
File finalDir = new File(StableUtils.pathJoin(FileCommonUtils.getAbsolutePath(destDir), fileName));
if (!finalDir.exists()) {
finalDir.mkdir();
}
// 获取文件名(含后缀)
fileName = resource.getFileName();
// 处理重复文件名
String fileNameFormat = "(%d)" + fileName;
Pattern pattern = Pattern.compile("\\((\\d)\\)" + fileName);
int cnt = 0;
File[] files = finalDir.listFiles();
for (File f : files) {
Matcher matcher = pattern.matcher(f.getName());
if (matcher.find()) {
cnt = Math.max(cnt, Integer.parseInt(matcher.group(1)));
}
}
cnt++;
fileName = String.format(fileNameFormat, cnt);
File destFile = new File(StableUtils.pathJoin(FileCommonUtils.getAbsolutePath(finalDir), fileName));
destFile.createNewFile();
return destFile;
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
}
return null;
} }
private static CloseableHttpResponse getDownloadHttpResponse(String url) throws Exception {
//先登录一下。不然可能失败
CloseableHttpClient client = createClient();
HttpUriRequest file = RequestBuilder.get()
.setUri(url)
.build();
return client.execute(file);
}
private static CloseableHttpResponse postDownloadHttpResponse(String url, String id) throws Exception {
return postDownloadHttpResponse(url, id, new HashMap<>());
}
/** private static CloseableHttpResponse postDownloadHttpResponse(String url, String id, Map<String, String> params) throws Exception {
* 获取帆软市场模板资源页面链接 //先登录一下。不然可能失败
* */ CloseableHttpClient client = createClient();
public String getFineMarketTemplateUrl() { FineLoggerFactory.getLogger().info("login fr-market");
return FINE_MARKET_TEMPLATE_URL; FineLoggerFactory.getLogger().info("start download resource {}", id);
RequestBuilder builder = RequestBuilder.post()
.setHeader("User-Agent", "Mozilla/5.0")
.setUri(url)
.addParameter("id", SecurityToolbox.encrypt(id, CERTIFICATE_PUBLIC_KEY))
.addParameter("userId", String.valueOf(DesignerEnvManager.getEnvManager().getDesignerLoginUid()));
if (params != null) {
Set<String> keys = params.keySet();
for (String key: keys) {
builder.addParameter(key, params.get(key));
}
}
return client.execute(builder.build());
}
private static CloseableHttpClient createClient() {
BasicCookieStore cookieStore = new BasicCookieStore();
return HttpClients.custom()
.setDefaultRequestConfig(RequestConfig.custom()
.setCookieSpec(CookieSpecs.STANDARD).build())
.setDefaultCookieStore(cookieStore)
.build();
} }
public @Nullable JSONObject getTemplateInfoById(String id) throws IOException { public @Nullable JSONObject getTemplateInfoById(String id) throws IOException {

67
designer-realize/src/main/java/com/fr/market/key/FineMarketDefaultKeyProperties.java

@ -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());
}
}
}
}

29
designer-realize/src/main/java/com/fr/market/key/FineMarketPublicKeyConstants.java

@ -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";
}

48
designer-realize/src/main/java/com/fr/market/key/FineMarketPublicKeyHolder.java

@ -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;
}
}

5
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/caution.svg

@ -0,0 +1,5 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15 8C15 11.8656 11.8656 15 8 15C4.13435 15 1 11.8656 1 8C1 4.13435 4.13435 1 8 1C11.8656 1 15 4.13435 15 8Z" fill="#FBB03B"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.43328 10.292C7.27773 10.4476 7.19995 10.6365 7.19995 10.8587C7.19995 11.0809 7.27773 11.2698 7.43328 11.4254C7.58884 11.5809 7.77773 11.6587 7.99995 11.6587C8.22217 11.6587 8.41106 11.5809 8.56662 11.4254C8.72217 11.2698 8.79995 11.0809 8.79995 10.8587C8.79995 10.6365 8.72217 10.4476 8.56662 10.292C8.41106 10.1365 8.22217 10.0587 7.99995 10.0587C7.77773 10.0587 7.58884 10.1365 7.43328 10.292Z" fill="white"/>
<rect x="7.30005" y="4.22144" width="1.4" height="5" rx="0.7" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 820 B

3
designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/loading.svg

@ -0,0 +1,3 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M7.99997 0.615356C3.92156 0.615356 0.615356 3.92156 0.615356 7.99997C0.615356 9.00517 0.816197 9.96346 1.17994 10.8369L2.32206 10.3771C2.0155 9.64576 1.84613 8.84265 1.84613 7.99997C1.84613 4.6013 4.6013 1.84613 7.99997 1.84613C8.58656 1.84613 9.15398 1.9282 9.69137 2.08148L8.55836 4.00142H12.6779C12.678 4.00154 12.6781 4.00165 12.6782 4.00176H14.2096C12.8951 1.96429 10.605 0.615356 7.99997 0.615356ZM14.7714 5.04894L13.6568 5.57321C13.9767 6.31781 14.1538 7.1382 14.1538 7.99997C14.1538 11.3986 11.3986 14.1538 7.99997 14.1538C7.43089 14.1538 6.87986 14.0766 6.35677 13.932L7.49691 12L6.62743 12L3.3233 12L1.79146 12C3.10622 14.0364 5.39566 15.3846 7.99997 15.3846C12.0784 15.3846 15.3846 12.0784 15.3846 7.99997C15.3846 6.95082 15.1658 5.95276 14.7714 5.04894Z" fill="#419BF9"/>
</svg>

After

Width:  |  Height:  |  Size: 936 B

1
designer-realize/src/main/resources/com/fr/market/key/76c1/default

@ -0,0 +1 @@
defaultKey=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCtsz62CPSWXZE/IYZRiAuTSZkw

1
designer-realize/src/main/resources/com/fr/market/key/943f/default

@ -0,0 +1 @@
defaultKey=1WOwer8+JFktK0uKLAUuQoBr+UjAMFtRA8W7JgKMDwZy/2liEAiXEOSPU/hrdV8D

1
designer-realize/src/main/resources/com/fr/market/key/d8a3/default

@ -0,0 +1 @@
defaultKey=tT541LnGi1X/hXiRwuttPWYN3L2GYm/d5blU+FBNwghBIrdAxXTzYBc6P4KL/oYXnMdTIrkz8tYkG3QoFQIDAQAB
Loading…
Cancel
Save