@ -0,0 +1,203 @@ |
|||||||
|
package com.fr.design.data.tabledata.datacenter; |
||||||
|
|
||||||
|
import com.fr.base.BaseFormula; |
||||||
|
import com.fr.datacenters.tabledata.bean.DCFilterQueryBean; |
||||||
|
import com.fr.datacenters.tabledata.bean.DCTableDataBean; |
||||||
|
import com.fr.datacenters.tabledata.filter.DCFilter; |
||||||
|
import com.fr.design.bridge.exec.JSBridge; |
||||||
|
import com.fr.design.dialog.DialogActionListener; |
||||||
|
import com.fr.design.dialog.UIDialog; |
||||||
|
import com.fr.design.formula.FormulaFactory; |
||||||
|
import com.fr.design.formula.UIFormula; |
||||||
|
import com.fr.design.jxbrowser.JxUIPane; |
||||||
|
import com.fr.json.revise.EmbedJson; |
||||||
|
import com.fr.locale.InterProviderFactory; |
||||||
|
import com.fr.log.FineLoggerFactory; |
||||||
|
import com.fr.script.Calculator; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.third.antlr.ANTLRException; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
import com.teamdev.jxbrowser.js.JsAccessible; |
||||||
|
import com.teamdev.jxbrowser.js.JsFunction; |
||||||
|
import com.teamdev.jxbrowser.js.JsObject; |
||||||
|
|
||||||
|
import javax.swing.SwingUtilities; |
||||||
|
import java.awt.Window; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
import java.util.concurrent.CompletableFuture; |
||||||
|
import java.util.stream.Collectors; |
||||||
|
|
||||||
|
/** |
||||||
|
* 数据中心JS对象方法桥接类 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/6/17 |
||||||
|
*/ |
||||||
|
@JsAccessible |
||||||
|
public class DatacentersJSBridge { |
||||||
|
private static final String EVENT_FORMULA_UPDATE = "OK"; |
||||||
|
private static final String EVENT_FORMULA_CANCEL = "CANCEL"; |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取数据中心JS对象方法桥接实例 |
||||||
|
* |
||||||
|
* @param window js环境的window对象 |
||||||
|
* @return 桥接实例 |
||||||
|
*/ |
||||||
|
public static DatacentersJSBridge getBridge(JsObject window) { |
||||||
|
return new DatacentersJSBridge(window); |
||||||
|
} |
||||||
|
|
||||||
|
private final JsObject window; |
||||||
|
|
||||||
|
|
||||||
|
private DatacentersJSBridge(JsObject window) { |
||||||
|
this.window = window; |
||||||
|
} |
||||||
|
|
||||||
|
private static DatacentersPane relationPanel; |
||||||
|
|
||||||
|
/** |
||||||
|
* 设置窗口,用于打开对话框的层级 |
||||||
|
* |
||||||
|
* @param panel 面板 |
||||||
|
*/ |
||||||
|
public static void relationPanel(DatacentersPane panel) { |
||||||
|
relationPanel = panel; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* i18n方法 |
||||||
|
* |
||||||
|
* @param text key文本 |
||||||
|
* @return 国际化文本 |
||||||
|
* @throws Exception 异常 |
||||||
|
*/ |
||||||
|
@JSBridge |
||||||
|
public void i18nText(String text, final JsFunction callback) { |
||||||
|
JxUIPane.DEFAULT_EXECUTOR.submit(() -> |
||||||
|
callback.invoke(window, InterProviderFactory.getProvider().getLocText(text))); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 获取登录的凭证 token |
||||||
|
* 同步方法,非耗时方法 |
||||||
|
*/ |
||||||
|
@JSBridge |
||||||
|
public String fetchToken() { |
||||||
|
return WorkContext.getCurrent().getConnection().getToken(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 判断是否远程环境 |
||||||
|
* |
||||||
|
* @return 是远程环境返回true,反之false |
||||||
|
*/ |
||||||
|
@JSBridge |
||||||
|
public boolean isRemote() { |
||||||
|
return !WorkContext.getCurrent().isLocal(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 判断是否设计器环境 |
||||||
|
* |
||||||
|
* @return 是设计器环境返回true,反之false |
||||||
|
*/ |
||||||
|
@JSBridge |
||||||
|
public boolean isDesigner() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 调用公式面板 |
||||||
|
*/ |
||||||
|
@JSBridge |
||||||
|
public void showFormulaPane(String content, final JsFunction callback) { |
||||||
|
final UIFormula formulaPane = FormulaFactory.createFormulaPaneWhenReserveFormula(); |
||||||
|
formulaPane.populate(BaseFormula.createFormulaBuilder().build(StringUtils.alwaysNotNull(content))); |
||||||
|
formulaPane.showLargeWindow(SwingUtilities.getWindowAncestor(relationPanel), new DialogActionListener() { |
||||||
|
@Override |
||||||
|
public void doOk() { |
||||||
|
BaseFormula formula = formulaPane.update(); |
||||||
|
SwingUtilities.invokeLater(() -> callback.invoke(window, EVENT_FORMULA_UPDATE, formula.getPureContent())); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doCancel() { |
||||||
|
SwingUtilities.invokeLater(() -> callback.invoke(window, EVENT_FORMULA_CANCEL)); |
||||||
|
} |
||||||
|
}).setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 解析公式参数 |
||||||
|
*/ |
||||||
|
@JSBridge |
||||||
|
public void parseFormulaParameters(String content, final JsFunction callback) { |
||||||
|
|
||||||
|
JxUIPane.DEFAULT_EXECUTOR.submit(() -> { |
||||||
|
try { |
||||||
|
List<String> list = Arrays.stream(Calculator.relatedParameters(content)) |
||||||
|
.map(p -> p.substring(1)) |
||||||
|
.collect(Collectors.toList()); |
||||||
|
callback.invoke(window, EmbedJson.encode(list)); |
||||||
|
} catch (ANTLRException e) { |
||||||
|
throw new RuntimeException(e); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 解析过滤结构 |
||||||
|
*/ |
||||||
|
@JSBridge |
||||||
|
public void transFilter4Query(String tableData, final JsFunction callback) { |
||||||
|
|
||||||
|
JxUIPane.DEFAULT_EXECUTOR.submit(() -> { |
||||||
|
try { |
||||||
|
DCTableDataBean decoded = EmbedJson.decodeValue(tableData, DCTableDataBean.class); |
||||||
|
DCFilter dcFilter = decoded.getFilter().evalValue(decoded.getParameters(), Calculator.createCalculator()); |
||||||
|
DCFilterQueryBean queryBean = dcFilter.toQueryBean(); |
||||||
|
String encode = EmbedJson.encode(queryBean); |
||||||
|
callback.invoke(window, encode); |
||||||
|
} catch (Exception e) { |
||||||
|
callback.invoke(window, EmbedJson.encode(new DCFilterQueryBean())); |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 对话框确定动作 |
||||||
|
*/ |
||||||
|
@JSBridge |
||||||
|
public void okAction() { |
||||||
|
CompletableFuture |
||||||
|
.runAsync(() -> relationPanel.updateNamePane()) |
||||||
|
.thenRunAsync(() -> { |
||||||
|
Window ancestor = SwingUtilities.getWindowAncestor(relationPanel); |
||||||
|
if (ancestor instanceof UIDialog) { |
||||||
|
try { |
||||||
|
((UIDialog) ancestor).doOK(); |
||||||
|
} catch (Exception e) { |
||||||
|
FineLoggerFactory.getLogger().error(e.getMessage(), e); |
||||||
|
} |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 对话框取消动作 |
||||||
|
*/ |
||||||
|
@JSBridge |
||||||
|
public void cancelAction() { |
||||||
|
Window ancestor = SwingUtilities.getWindowAncestor(relationPanel); |
||||||
|
if (ancestor instanceof UIDialog) { |
||||||
|
((UIDialog) ancestor).doCancel(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,128 @@ |
|||||||
|
package com.fr.design.data.tabledata.datacenter; |
||||||
|
|
||||||
|
import com.fr.datacenters.tabledata.DCTableData; |
||||||
|
import com.fr.datacenters.tabledata.bean.DCNameBean; |
||||||
|
import com.fr.datacenters.tabledata.bean.DCTableDataBean; |
||||||
|
import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane; |
||||||
|
import com.fr.design.dialog.DialogActionListener; |
||||||
|
import com.fr.design.dialog.UIDialog; |
||||||
|
import com.fr.design.jxbrowser.JxEngine; |
||||||
|
import com.fr.design.jxbrowser.JxUIPane; |
||||||
|
import com.fr.json.revise.EmbedJson; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
import com.fr.third.guava.collect.ImmutableMap; |
||||||
|
import com.fr.workspace.WorkContext; |
||||||
|
|
||||||
|
import javax.swing.SwingUtilities; |
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Window; |
||||||
|
|
||||||
|
/** |
||||||
|
* 数据中心数据集面板 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/6/17 |
||||||
|
*/ |
||||||
|
public class DatacentersPane extends AbstractTableDataPane<DCTableData> { |
||||||
|
|
||||||
|
private static final JxEngine JX_ENGINE = JxEngine.newInstance(false); |
||||||
|
|
||||||
|
private static final String DATA_CENTER = "dc"; |
||||||
|
private static final String DATA_CENTER_HELPER = "dcHelper"; |
||||||
|
private final JxUIPane<String> dataCenterJxUIPane; |
||||||
|
private JxTableDataNamePane namePane; |
||||||
|
// 用于复制粘贴场景
|
||||||
|
private DCTableData dcTableData; |
||||||
|
|
||||||
|
/** |
||||||
|
* 借用,只运行一次 |
||||||
|
*/ |
||||||
|
private void addDialogActionListener() { |
||||||
|
|
||||||
|
// 保证在窗口加载完成后执行
|
||||||
|
SwingUtilities.invokeLater(() -> { |
||||||
|
Window ancestor = SwingUtilities.getWindowAncestor(DatacentersPane.this); |
||||||
|
if (ancestor instanceof UIDialog) { |
||||||
|
((UIDialog) ancestor).addDialogActionListener(new DialogActionListener() { |
||||||
|
@Override |
||||||
|
public void doOk() { |
||||||
|
dataCenterJxUIPane.disposeBrowser(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void doCancel() { |
||||||
|
dataCenterJxUIPane.disposeBrowser(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
public DatacentersPane() { |
||||||
|
setLayout(new BorderLayout()); |
||||||
|
dataCenterJxUIPane = getJxUIPane(); |
||||||
|
add(dataCenterJxUIPane, BorderLayout.CENTER); |
||||||
|
dataCenterJxUIPane.addXHRHeaders(ImmutableMap.of("Authorization", |
||||||
|
WorkContext.getCurrent().getConnection().getToken())); |
||||||
|
} |
||||||
|
|
||||||
|
private static JxUIPane<String> getJxUIPane() { |
||||||
|
return new JxUIPane.Builder<String>() |
||||||
|
.engine(JX_ENGINE) |
||||||
|
.namespace(DATA_CENTER) |
||||||
|
.bindWindow(DATA_CENTER_HELPER, DatacentersJSBridge::getBridge) |
||||||
|
.withEMB("com/fr/design/data/tabledata/datacenter/web/data-choose.prod.html", |
||||||
|
ImmutableMap.of("fineServletURL", getDatacentersUrl())) |
||||||
|
.build(); |
||||||
|
} |
||||||
|
|
||||||
|
private static String getDatacentersUrl() { |
||||||
|
if (!WorkContext.getCurrent().isLocal()) { |
||||||
|
String path = WorkContext.getCurrent().getPath(); |
||||||
|
return path.endsWith("/") ? path + "bi" : path + "/bi"; |
||||||
|
} |
||||||
|
return StringUtils.EMPTY; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public NamePane asNamePane() { |
||||||
|
return namePane = new JxTableDataNamePane(this); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public void populateBean(DCTableData ob) { |
||||||
|
DatacentersJSBridge.relationPanel(this); |
||||||
|
dcTableData = ob; |
||||||
|
dataCenterJxUIPane.populate(EmbedJson.encode(ob.toBean())); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
@Override |
||||||
|
public DCTableData updateBean() { |
||||||
|
String data = dataCenterJxUIPane.update(); |
||||||
|
if (StringUtils.isNotEmpty(data)) { |
||||||
|
DCTableDataBean tableDataBean = EmbedJson.decodeValue(data, DCTableDataBean.class); |
||||||
|
namePane.setObjectName(tableDataBean.getDsName()); |
||||||
|
return DCTableData.fromBean(tableDataBean); |
||||||
|
} else { |
||||||
|
// 复制的场景下,不打开界面需要返回数据集
|
||||||
|
return dcTableData; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 为了兼容之前的面板,编辑时更新模板的数据集,需要在updateBean之前更新到名称 |
||||||
|
*/ |
||||||
|
public void updateNamePane() { |
||||||
|
String data = dataCenterJxUIPane.update(); |
||||||
|
DCNameBean nameBean = EmbedJson.decodeValue(data, DCNameBean.class); |
||||||
|
namePane.setObjectName(nameBean.getDsName()); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected String title4PopupWindow() { |
||||||
|
return ""; |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,72 @@ |
|||||||
|
package com.fr.design.data.tabledata.datacenter; |
||||||
|
|
||||||
|
import com.fr.design.dialog.BasicDialog; |
||||||
|
import com.fr.design.dialog.BasicPane; |
||||||
|
import com.fr.design.dialog.BasicPane.NamePane; |
||||||
|
import com.fr.design.dialog.DialogActionListener; |
||||||
|
import com.fr.design.mainframe.DesignerContext; |
||||||
|
import com.fr.design.mainframe.DesignerFrame; |
||||||
|
import com.fr.stable.StringUtils; |
||||||
|
|
||||||
|
import java.awt.BorderLayout; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Window; |
||||||
|
|
||||||
|
/** |
||||||
|
* 1. 覆盖namePane里面的名字组件 |
||||||
|
* 2. 重写Dialog组件大小 |
||||||
|
* |
||||||
|
* @author vito |
||||||
|
* @since 11.0 |
||||||
|
* Created on 2024/7/20 |
||||||
|
*/ |
||||||
|
public class JxTableDataNamePane extends NamePane { |
||||||
|
// 持有窗口对象,操作按钮状态
|
||||||
|
private BasicDialog dialog; |
||||||
|
private String dsName = StringUtils.EMPTY; |
||||||
|
|
||||||
|
public JxTableDataNamePane(BasicPane tableDataPane) { |
||||||
|
super(tableDataPane); |
||||||
|
setLayout(new BorderLayout()); |
||||||
|
add(tableDataPane, BorderLayout.CENTER); |
||||||
|
} |
||||||
|
|
||||||
|
public String getObjectName() { |
||||||
|
return dsName; |
||||||
|
} |
||||||
|
|
||||||
|
public void setObjectName(String name) { |
||||||
|
dsName = name; |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* 显示窗口,重写尺寸 |
||||||
|
* |
||||||
|
* @param window 窗口 |
||||||
|
* @param l 对话框监听器 |
||||||
|
* @return 对话框 |
||||||
|
*/ |
||||||
|
@Override |
||||||
|
public BasicDialog showLargeWindow(Window window, DialogActionListener l) { |
||||||
|
this.dialog = showWindowWithCustomSize(window, l, calculatePaneDimension(), false); |
||||||
|
return this.dialog; |
||||||
|
} |
||||||
|
|
||||||
|
private static final int MIN_WIDTH = 1000; |
||||||
|
private static final int MIN_HEIGHT = 600; |
||||||
|
|
||||||
|
/** |
||||||
|
* 计算数据集窗口大小 |
||||||
|
* 宽:80%,高:90% |
||||||
|
* |
||||||
|
* @return 宽高 |
||||||
|
*/ |
||||||
|
public static Dimension calculatePaneDimension() { |
||||||
|
DesignerFrame parent = DesignerContext.getDesignerFrame(); |
||||||
|
int width = Math.max((int) (parent.getWidth() * 0.8), MIN_WIDTH); |
||||||
|
int height = Math.max((int) (parent.getHeight() * 0.9), MIN_HEIGHT); |
||||||
|
return new Dimension(width, height); |
||||||
|
} |
||||||
|
} |
||||||
|
|
After Width: | Height: | Size: 800 B |
After Width: | Height: | Size: 804 B |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 834 B |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 45 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 588 B |
After Width: | Height: | Size: 600 B |
After Width: | Height: | Size: 582 B |
After Width: | Height: | Size: 588 B |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 829 B |
After Width: | Height: | Size: 829 B |
After Width: | Height: | Size: 829 B |
After Width: | Height: | Size: 617 B |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 7.2 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 4.6 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 182 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 182 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 9.0 KiB |
After Width: | Height: | Size: 9.1 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 9.4 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 931 B |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 17 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 983 B |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 737 B |
After Width: | Height: | Size: 6.0 KiB |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 13 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 4.8 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 4.1 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 5.0 KiB |
After Width: | Height: | Size: 6.5 KiB |
After Width: | Height: | Size: 5.2 KiB |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 242 B |
After Width: | Height: | Size: 6.9 KiB |