{
protected void done() {
okButton.setEnabled(true);
try {
-
TestConnectionResult result = TestConnectionResult.parse(get(), connection);
- if (result == TestConnectionResult.Fully_Success) {
- message.setText(Toolkit.i18nText("Fine-Design_Basic_Remote_Connect_Successful"));
- uiLabel.setIcon(UIManager.getIcon("OptionPane.informationIcon"));
- }
-
- if (result == TestConnectionResult.Partly_Sucess) {
- message.setText(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Version_Inconsistence_Test"));
- uiLabel.setIcon(UIManager.getIcon("OptionPane.warningIcon"));
- }
-
- if (result == TestConnectionResult.Fully_Failed) {
- message.setText(Toolkit.i18nText("Fine-Design_Basic_Remote_Connect_Failed"));
- uiLabel.setIcon(UIManager.getIcon("OptionPane.errorIcon"));
- }
-
- if (result == TestConnectionResult.Auth_Failed) {
- message.setText(Toolkit.i18nText("Fine-Design_Basic_Remote_Connect_Auth_Failed"));
- uiLabel.setIcon(UIManager.getIcon("OptionPane.errorIcon"));
- }
+ message.setText(result.getText());
+ uiLabel.setIcon(result.getIcon());
} catch (InterruptedException | ExecutionException e) {
FineLoggerFactory.getLogger().error(e, e.getMessage());
message.setText(Toolkit.i18nText("Fine-Design_Basic_Remote_Connect_Failed"));
diff --git a/designer-base/src/main/java/com/fr/env/TestConnectionResult.java b/designer-base/src/main/java/com/fr/env/TestConnectionResult.java
index 357d4f38cb..5362dbbd83 100644
--- a/designer-base/src/main/java/com/fr/env/TestConnectionResult.java
+++ b/designer-base/src/main/java/com/fr/env/TestConnectionResult.java
@@ -1,62 +1,104 @@
package com.fr.env;
+import com.fr.design.i18n.Toolkit;
import com.fr.log.FineLoggerFactory;
import com.fr.stable.AssistUtils;
import com.fr.workspace.WorkContext;
import com.fr.workspace.connect.WorkspaceConnectionInfo;
import com.fr.workspace.engine.channel.http.FunctionalHttpRequest;
+import javax.swing.Icon;
+import javax.swing.UIManager;
+
/**
* 测试连接的结果。
* 不改变原有逻辑的情况下,加入一层转化。
* 根据这里的转化结果,判断需要提示哪些内容。
- *
+ *
* created by Harrison on 2018/12/20
**/
public enum TestConnectionResult {
/**
* 完全成功, 版本匹配,测试连接成功。
*/
- Fully_Success,
+ FULLY_SUCCESS {
+ @Override
+ public Icon getIcon() {
+ return UIManager.getIcon("OptionPane.informationIcon");
+ }
+
+ @Override
+ public String getText() {
+ return Toolkit.i18nText("Fine-Design_Basic_Remote_Connect_Successful");
+ }
+ },
/**
* 不完全成功,版本不匹配,但测试连接成功。
*/
- Partly_Sucess,
+ PARTLY_SUCCESS {
+ @Override
+ public Icon getIcon() {
+ return UIManager.getIcon("OptionPane.warningIcon");
+ }
+
+ @Override
+ public String getText() {
+ return Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Version_Inconsistence_Test");
+ }
+ },
/**
* 完全失败,直接没连上
*/
- Fully_Failed,
+ FULLY_FAILED {
+ @Override
+ public Icon getIcon() {
+ return UIManager.getIcon("OptionPane.errorIcon");
+ }
+
+ @Override
+ public String getText() {
+ return Toolkit.i18nText("Fine-Design_Basic_Remote_Connect_Failed");
+ }
+ },
/**
* 验证 Token 失败
*/
- Auth_Failed;
+ AUTH_FAILED {
+ @Override
+ public Icon getIcon() {
+ return UIManager.getIcon("OptionPane.errorIcon");
+ }
+
+ @Override
+ public String getText() {
+ return Toolkit.i18nText("Fine-Design_Basic_Remote_Connect_Auth_Failed");
+ }
+ };
+
+ public abstract Icon getIcon();
+
+ public abstract String getText();
public static TestConnectionResult parse(Boolean value, WorkspaceConnectionInfo info) {
if (value == null) {
- return Auth_Failed;
+ return AUTH_FAILED;
}
-
if (!value) {
- return Fully_Failed;
+ return FULLY_FAILED;
}
try {
-
String serverVersion = new FunctionalHttpRequest(info).getServerVersion();
if (AssistUtils.equals(serverVersion, WorkContext.getVersion())) {
- return Fully_Success;
+ return FULLY_SUCCESS;
}
-
- return Partly_Sucess;
+ return PARTLY_SUCCESS;
} catch (Exception e) {
-
// 发生异常,说明没连接上。返回完全失败。
FineLoggerFactory.getLogger().error(e.getMessage());
- return Fully_Failed;
+ return FULLY_FAILED;
}
-
-
}
}
diff --git a/designer-base/src/main/java/com/fr/start/OemHandler.java b/designer-base/src/main/java/com/fr/start/OemHandler.java
new file mode 100644
index 0000000000..b127e07f43
--- /dev/null
+++ b/designer-base/src/main/java/com/fr/start/OemHandler.java
@@ -0,0 +1,14 @@
+package com.fr.start;
+
+import com.fr.design.fun.OemProcessor;
+import com.fr.stable.bridge.StableFactory;
+
+/**
+ * OEM处理中心
+ */
+public class OemHandler {
+
+ public static OemProcessor findOem() {
+ return StableFactory.getMarkedInstanceObjectFromClass(OemProcessor.MARK_STRING, OemProcessor.class);
+ }
+}
\ No newline at end of file
diff --git a/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java b/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java
index 2d08b286d5..0955c16e57 100644
--- a/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java
+++ b/designer-base/src/main/java/com/fr/start/server/FineEmbedServerActivator.java
@@ -6,6 +6,7 @@ import com.fr.log.FineLoggerFactory;
import com.fr.module.Activator;
import com.fr.module.ModuleRole;
import com.fr.stable.EncodeConstants;
+import com.fr.stable.ProductConstants;
import com.fr.startup.FineWebApplicationInitializer;
import com.fr.third.springframework.web.SpringServletContainerInitializer;
import com.fr.third.springframework.web.context.support.AnnotationConfigWebApplicationContext;
@@ -62,6 +63,8 @@ public class FineEmbedServerActivator extends Activator {
// 设置解码uri使用的字符编码
tomcat.getConnector().setURIEncoding(EncodeConstants.ENCODING_UTF_8);
String docBase = new File(WorkContext.getCurrent().getPath()).getParent();
+ //内置的上下文是自己定的,这里把WEB_APP_NAME一并设置了,否则下面appName是/null
+ ProductConstants.setWebAppName(ProductConstants.getAppFolderName());
String appName = "/" + FRContext.getCommonOperator().getAppName();
Context context = tomcat.addContext(appName, docBase);
Tomcat.initWebappDefaults(context);
diff --git a/designer-base/src/main/resources/com/fr/aspectj/designerbase/TemplateProcessTracker.aj b/designer-base/src/main/resources/com/fr/aspectj/designerbase/TemplateProcessTracker.aj
deleted file mode 100644
index 1ab23100b1..0000000000
--- a/designer-base/src/main/resources/com/fr/aspectj/designerbase/TemplateProcessTracker.aj
+++ /dev/null
@@ -1,58 +0,0 @@
-package com.fr.aspectj.designerbase;
-
-/**
- * 记录模板过程
- * Created by plough on 2017/3/3.
- */
-
-import org.aspectj.lang.reflect.SourceLocation;
-
-import java.awt.event.ActionEvent;
-import java.awt.event.MouseEvent;
-
-public aspect TemplateProcessTracker {
- //声明一个pointcut,匹配你需要的方法
- pointcut onMouseClicked(MouseEvent e):
- execution(* mouseClicked(MouseEvent)) && args(e);
- pointcut onMousePressed(MouseEvent e):
- execution(* mousePressed(MouseEvent)) && args(e);
- pointcut onMouseReleased(MouseEvent e):
- execution(* mouseReleased(MouseEvent)) && args(e);
- pointcut onActionPerformed(ActionEvent e):
- execution(* actionPerformed(ActionEvent)) && args(e);
- pointcut onSetValueAt(Object v, int r, int c):
- execution(* setValueAt(java.lang.Object, int, int)) && args(v, r, c);
-
- //before表示之前的意思
- //这整个表示在MouseAdapter的public void mouseXXX(MouseEvent)方法调用之前,你想要执行的代码
- before(MouseEvent e): onMouseClicked(e) || onMousePressed(e) || onMouseReleased(e) {
- SourceLocation sl = thisJoinPoint.getSourceLocation();//切面对应的代码位置
-
- //String log = String.format("%s:\n%s\n%s\n%s\n\n", new Date(), sl, e, e.getSource());
- String log = "";
- //TemplateInfoCollector.appendProcess(log);
- }
- //同上
- before(ActionEvent e): onActionPerformed(e) {
- SourceLocation sl = thisJoinPoint.getSourceLocation();
- // !within(LogHandlerBar) 没用, 手动过滤
- if (e != null && e.getSource().toString().contains("javax.swing.Timer")) {
- return;
- }
-
- //String log = String.format("%s:\n%s\n%s\n%s\n\n", new Date(), sl, e, e.getSource());
- String log = "";
- //TemplateInfoCollector.appendProcess(log);
-
- }
- //同上
- before(Object v, int r, int c): onSetValueAt(v, r, c) {
- SourceLocation sl = thisJoinPoint.getSourceLocation();
-
- //String log getSourceLocation= String.format("%s:\n%s\nset value: %s at (%d, %d)\n\n", new Date(), sl, v, r, c);
- String log = "";
- // TemplateInfoCollector.appendProcess(log);
- }
-
-
-}
diff --git a/designer-base/src/main/resources/com/fr/design/dcm/index.js b/designer-base/src/main/resources/com/fr/design/dcm/index.js
new file mode 100644
index 0000000000..5f6220c748
--- /dev/null
+++ b/designer-base/src/main/resources/com/fr/design/dcm/index.js
@@ -0,0 +1,2 @@
+!function(e){var t={};function i(s){if(t[s])return t[s].exports;var o=t[s]={i:s,l:!1,exports:{}};return e[s].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=e,i.c=t,i.d=function(e,t,s){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:s})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var s=Object.create(null);if(i.r(s),Object.defineProperty(s,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)i.d(s,o,function(t){return e[t]}.bind(null,o));return s},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=0)}([function(e,t,i){BI.DOM.ready(()=>{const e=i(5).default;BI.createWidget({type:e,element:"body"})})},function(e,t,i){},function(e,t){const i=BI.Constants.getConstant("dec.constant.database.conf.connect.form.redis.value"),s=BI.inherit(BI.Widget,{render:()=>({type:"bi.vertical",cls:"bi-plugin-redis",bgap:10,items:[{type:"bi.left",height:30,items:[{type:"bi.label",text:"数据库地址:",height:24,width:115,textAlign:"left"},{type:"bi.label",text:i.url,height:24}]},{type:"bi.left",height:30,items:[{type:"bi.label",text:"端口:",height:24,width:115,textAlign:"left"},{type:"bi.label",text:i.port,height:24}]},{type:"bi.left",height:30,items:[{type:"bi.label",text:"密码:",height:24,width:115,textAlign:"left"},{type:"bi.label",text:"********",height:24}]}]})});BI.shortcut("fr.plugin.redis.preview",s),BI.constant("dec.constant.database.conf.connect.form.redis.preview","fr.plugin.redis.preview")},function(e,t){const i=BI.inherit(BI.Widget,{render(){const{maxActive:e,maxIdle:t,numActive:i,numIdle:s}=this.options;return{type:"bi.left",items:[{type:"bi.left",cls:"right-status-item",items:[{type:"bi.vertical",cls:"right-status-board",items:[{type:"bi.vertical",cls:"right-status-board-item",items:[{type:"bi.label",cls:"right-status-text",extraCls:"card-font1",text:i},{type:"bi.label",cls:"right-status-text",text:"/"},{type:"bi.label",cls:"right-status-text",text:e}]},{type:"bi.label",text:"Redis连接数"}]}]}]}}});BI.shortcut("fr.plugin.redis.pool",i),BI.constant("dec.constant.database.conf.connect.form.redis.pool","fr.plugin.redis.pool")},function(e,t,i){},function(e,t,i){"use strict";i.r(t);const s="bi.icon_label",o="bi.label",r="bi.button",n="bi.editor",l="bi.vtape",a="bi.htape",c="bi.layout",d="bi.vertical",h="bi.left",p=[],m={childContext:["tab","linkList","linkSelected","linkUpdate","moreLinkSelected","statusSelected","connectionNameErr"],state:()=>({tab:"数据连接管理",linkList:p,linkSelected:{},linkUpdate:{},moreLinkSelected:"",statusSelected:"",connectionNameErr:""}),computed:{},actions:{setLinkList(e){this.model.linkList=e}}};BI.model("fr.model.main",BI.inherit(Fix.Model,m));const b=BI.inherit(Fix.Model,{context:["tab"],actions:{setTab(e){this.model.tab=e}}});BI.model("fr.model.title.item",b);function u(e,t){return e===t?{color:"#3685f2","border-bottom":"solid 2px #3685f2"}:{color:"#3d4d66","border-bottom":"none"}}const g=BI.inherit(BI.Widget,{props:{text:""},_store:()=>BI.Models.getModel("fr.model.title.item"),watch:{tab(e){const{text:t}=this.options;this.element.css(u(t,e))}},render(){const{text:e}=this.options;return{type:o,cls:"title-item",text:e}},mounted(){const{text:e}=this.options;this.element.css(u("数据连接管理",e)),this.element.on("click",()=>{this.store.setTab(e)})}});BI.shortcut("fr.title.item",g);const y={data:[{connectionId:"8c1c52f1-3d0a-429e-b35f-ee1e085a8b72",database:"",connectionName:"FRDemo",driver:"org.sqlite.JDBC",url:"jdbc:sqlite://${ENV_HOME}/../help/FRDemo.db",user:"",password:"",queryType:"",newCharsetName:"null",originalCharsetName:"",validationQuery:"",schema:"",testOnBorrow:!0,maxActive:50,options:"null",port:0,authType:"",creator:"designer",principal:"",keyPath:"",databaseType:"designer",privilegeDetailBeanList:"null"}]},f=window.parent.Dec,v=window.PluginHelper;const x=["数据连接管理","连接池状态"],I={render(){return{type:h,cls:"title",items:[...BI.map(x,(e,t)=>({type:"fr.title.item",text:t})),{type:"bi.icon_button",cls:"close-button",handler(){!function(){if(v)return v.closeWindow();console.log("关闭窗口")}()},invisible:!0,ref:e=>{this.CloseButton=e}}]}},mounted(){v&&v.isDesigner()&&this.CloseButton.setVisible(!0)}};BI.shortcut("fr.title",BI.inherit(BI.Widget,I));const k="dec.constant.database.conf.connect.list",B=["APACHE KYLIN","DERBY","HP Vertica","IBM DB2","INFORMIX","Microsoft SQL Server","MySQL","Oracle","Privotal Greenplum Database","Postgresql","GaussDB 200"];BI.constant(k,[]);var E=k;const w=[{text:"APACHE KYLIN",databaseType:"apache-kylin",driver:"org.apache.kylin.jdbc.Driver",url:"jdbc:kylin://:/"},{text:"DERBY",databaseType:"derby",driver:"org.apache.derby.jdbc.ClientDriver",url:"jdbc:derby://localhost:1527/"},{text:"HP Vertica",databaseType:"hp-vertica",driver:"com.vertica.jdbc.Driver",url:"jdbc:vertica://ip:port/databaseName"},{text:"IBM DB2",databaseType:"ibm-db2",driver:"com.ibm.db2.jcc.DB2Driver",url:"jdbc:db2://hostname:port/dbname"},{text:"INFORMIX",databaseType:"informix",driver:"com.informix.jdbc.IfxDriver",url:"jdbc:informix-sqli://{host}:{port}/{database}:INFORMIXSERVER={server}"},{text:"Microsoft SQL Server",databaseType:"sql-server",driver:"com.microsoft.sqlserver.jdbc.SQLServerDriver",url:"jdbc:sqlserver://localhost:1433;databaseName="},{text:"Oracle",databaseType:"oracle",driver:"oracle.jdbc.driver.OracleDriver",url:"jdbc:oracle:thin:@localhost:1521:databaseName"},{text:"Privotal Greenplum Database",databaseType:"pivotal-greenplum-database",driver:"org.postgresql.Driver",url:"jdbc:postgresql://hostname:port/dbname"},{text:"Postgresql",databaseType:"postgresql",driver:"org.postgresql.Driver",url:"jdbc:postgresql://hostname:port/dbname"},{text:"GaussDB 200",databaseType:"hw-libr-a",driver:"org.postgresql.Driver",url:"jdbc:postgresql://hostname:port/dbname"},{text:"MySQL",databaseType:"mysql",driver:"com.mysql.jdbc.Driver",drivers:["com.mysql.jdbc.Driver","org.gjt.mm.mysql.Driver"],url:"jdbc:mysql://localhost/dbname"},{text:"其他",databaseType:"other",driver:"org.h2.Driver",drivers:["org.h2.Driver","com.fr.third.org.hsqldb.jdbcDriver","org.sqlite.JDBC"],url:"jdbc:h2://${ENV_HOME}/../databaseName"},{text:"ADS",databaseType:"ads",driver:"com.mysql.jdbc.Driver",url:"jdbc:mysql://hostname:port/my_ads_db"},{text:"Amazon Redshift",databaseType:"amazon-redshift",driver:"com.amazon.redshift.jdbc4.Driver",drivers:["com.amazon.redshift.jdbc4.Driver","com.amazon.redshift.jdbc41.Driver"],url:"jdbc:redshift://endpoint:port/database"},{text:"APACHE IMPALA",databaseType:"apache-impala",driver:"com.cloudera.impala.jdbc41.Driver",url:"jdbc:impala://hostname:port/_impala_builtins"},{text:"APACHE KYLIN",databaseType:"apache-kylin",driver:"org.apache.kylin.jdbc.Driver",url:"jdbc:kylin://:/"},{text:"APACHE Phoenix",databaseType:"apache-phoenix",driver:"org.apache.phoenix.jdbc.PhoenixDriver",url:"jdbc:phoenix:hostname:port/dbname"},{text:"DERBY",databaseType:"derby",driver:"org.apache.derby.jdbc.ClientDriver",url:"jdbc:derby://localhost:1527/"},{text:"Gbase 8A",databaseType:"gbase-8a",driver:"com.gbase.jdbc.Driver",url:"jdbc:gbase://hostname:port/dbname"},{text:"Gbase 8S",databaseType:"gbase-8s",driver:"com.gbasedbt.jdbc.IfxDriver",url:"jdbc:gbasedbt-sqli://{host}:{port}/{database}"},{text:"Gbase 8T",databaseType:"gbase-8t",driver:"com.informix.jdbc.IfxDriver",url:"jdbc:informix-sqli://{host}:{port}/{database}:INFORMIXSERVER={server}"},{text:"H2",databaseType:"h2",driver:"org.h2.Driver",url:"jdbc:h2://${ENV_HOME}/../databaseName"},{text:"华为云DWS",databaseType:"hw-dws",driver:"org.postgresql.Driver",url:"jdbc:postgresql://hostname:port/dbname"},{text:"FusionInsight elk",databaseType:"hw-elk",driver:"org.postgresql.Driver",url:"jdbc:postgresql://hostname:port/dbname"},{text:"FusionInsight HD",databaseType:"hw-fusioninsight-hd",driver:"org.apache.hive.jdbc.HiveDriver",url:"jdbc:hive2://10.135.0.110:24002,10.135.0.67:24002,10.135.0.66:24002/;serviceDiscoveryMode=zooKeeper;zooKeeperNamespace=hiveserver2;sasl.qop=auth-conf;auth=KERBEROS;zk.principal=zookeeper/hadoop;principal=hive/hadoop.hadoop.com@HADOOP.COM;"},{text:"GaussDB 200",databaseType:"hw-libr-a",driver:"org.postgresql.Driver",url:"jdbc:postgresql://hostname:port/dbname"},{text:"Hadoop Hive",databaseType:"hadoop-hive",driver:"org.apache.hive.jdbc.HiveDriver",url:"jdbc:hive2://hostname:port/databasename"},{text:"Hbase",databaseType:"hbase",driver:"org.apache.phoenix.jdbc.PhoenixDriver",url:"jdbc:phoenix:hostname:port/dbname"},{text:"HP Vertica",databaseType:"hp-vertica",driver:"com.vertica.jdbc.Driver",url:"jdbc:vertica://ip:port/databaseName"},{text:"Hsql",databaseType:"hsql",driver:"com.fr.third.org.hsqldb.jdbcDriver",url:"jdbc:hsqldb:file:[PATH_TO_DB_FILES]"},{text:"IBM DB2",databaseType:"ibm-db2",driver:"com.ibm.db2.jcc.DB2Driver",url:"jdbc:db2://hostname:port/dbname"},{text:"INFORMIX",databaseType:"informix",driver:"com.informix.jdbc.IfxDriver",url:"jdbc:informix-sqli://{host}:{port}/{database}:INFORMIXSERVER={server}"},{text:"KINGBASE",databaseType:"kingbase",driver:"com.kingbase.Driver",url:"jdbc:kingbase://hostname:port"},{text:"Microsoft SQL Server",databaseType:"sql-server",driver:"com.microsoft.sqlserver.jdbc.SQLServerDriver",url:"jdbc:sqlserver://localhost:1433;databaseName="},{text:"MySQL",databaseType:"mysql",driver:"com.mysql.jdbc.Driver",drivers:["com.mysql.jdbc.Driver","org.gjt.mm.mysql.Driver"],url:"jdbc:mysql://localhost/dbname"},{text:"Oracle",databaseType:"oracle",driver:"oracle.jdbc.driver.OracleDriver",url:"jdbc:oracle:thin:@localhost:1521:databaseName"},{text:"Pivotal Greenplum Database",databaseType:"pivotal-greenplum-database",driver:"org.postgresql.Driver",url:"jdbc:postgresql://hostname:port/dbname"},{text:"Postgresql",databaseType:"postgresql",driver:"org.postgresql.Driver",url:"jdbc:postgresql://hostname:port/dbname"},{text:"Presto",databaseType:"presto",driver:"com.facebook.presto.jdbc.PrestoDriver",url:"jdbc:presto://host:port/catalog"},{text:"SAP HANA",databaseType:"sap-hana",driver:"com.sap.db.jdbc.Driver",url:"jdbc:sap://hostname:port?reconnect=true"},{text:"SAP Sybase",databaseType:"sap-sybase",driver:"com.sybase.jdbc4.jdbc.SybDriver",url:"jdbc:sybase:Tds:hostname:2638/databasename"},{text:"SPARK",databaseType:"spark",driver:"org.apache.hive.jdbc.HiveDriver",url:"jdbc:hive2://hostname:port/databasename"},{text:"Sqlite",databaseType:"sqlite",driver:"org.sqlite.JDBC",url:"jdbc:sqlite:[PATH_TO_DB_FILES]"},{text:"TeraData",databaseType:"teradata",driver:"com.ncr.teradata.TeraDriver",url:"jdbc:teradata://localhost/CLIENT_CHARSET=EUC_CN,TMODE=TERA,CHARSET=ASCII,LOB_SUPPORT"},{text:"TRANSWARP INCEPTOR",databaseType:"transwarp-inceptor",driver:"org.apache.hive.jdbc.HiveDriver",url:"jdbc:hive2://hostname:port/databasename"}],N=(e,t)=>{const i=BI.Constants.getConstant(E);let s=0;const o=t.replace(/[0-9]/g,""),r=BI.some(i,(e,t)=>t===o)?o:"数据连接";return e.forEach(e=>{if(e.isSelected=!1,e.connectionName.startsWith(r)){const t=e.connectionName.replace(r,"0"),i=parseInt(t,10)+1;i>s&&(s=i)}}),`${r}${s>0?s:""}`};var T=new class{confirm(e,t){const i=BI.UUID();return BI.Popovers.create(i,{type:"bi.bar_popover",size:"normal",header:"提示",width:450,height:220,body:{type:"bi.left",cls:"comfirm-content",items:[{type:"bi.layout",cls:"comfirm-icon",width:50,height:50},{type:"bi.label",text:e}]},listeners:[{eventName:"EVENT_CONFIRM",action(){t&&t(!0)}},{eventName:"EVENT_CANCEL",action(){t&&t(!1)}}]}).open(i),i}loading(e){const t={type:"bi.center_adapt",cls:"show-content",items:[{type:d,items:[{type:"bi.layout",cls:"loading-icon",width:100,height:100},{type:o,text:e}]}]};return this.show(t)}success(e){const t={type:"bi.center_adapt",cls:"show-content",items:[{type:d,items:[{type:"bi.layout",cls:"success-icon",width:100,height:100},{type:o,text:e}]}]};return this.show(t,1e3)}error(e){const t={type:"bi.center_adapt",cls:"show-content",items:[{type:d,items:[{type:"bi.layout",cls:"error-icon",width:100,height:100},{type:o,text:e}]}]};return this.show(t,2e3)}linkFail(e,t,i){let s=null,n=null;const l=BI.UUID(),a=this,p={type:d,items:[{type:"bi.center_adapt",cls:"show-content",tgap:10,items:[{type:d,items:[{type:c,cls:"error-icon",width:100,height:100},{type:o,text:e},{type:h,cls:"buttons",items:[{type:r,text:"详细信息",level:"ignore",handler(){const e="详细信息"===this.getText();s.element.css({height:e?"290":"220"}),n.setVisible(e),this.setText(e?"收起信息":"详细信息")}},{type:r,text:"返回",level:"ignore",handler(){a.close(l)}},{type:r,text:"重新连接",handler(){a.close(l),i&&i()}}]}]}]},{type:o,cls:"show-more",text:t,invisible:!0,ref(e){n=e}}]};return BI.Popovers.create(l,{type:"bi.popover",cls:"popover-notitle",extraCls:"bi-custom-show",size:"normal",width:450,height:220,body:p,ref(e){s=e}}).open(l),l}close(e){BI.Popovers.close(e)}show(e,t=0){const i=BI.UUID();return BI.Popovers.create(i,{type:"bi.popover",cls:"popover-notitle",extraCls:"bi-custom-show",size:"normal",width:450,height:220,body:e}).open(i),t>0&&setTimeout(()=>{this.close(i)},t),i}};function C(e){return e.connectionId?new Promise((t,i)=>{try{!function(e,t){console.log("%cdata: ","color: MidnightBlue; background: Aquamarine;",e),f?f.reqPost("/v10/config/connection",e,e=>{t(e.data)}):t("success")}(e,e=>{t(e)})}catch(e){i(e)}}):new Promise((t,i)=>{try{!function(e,t){console.log("%cdata: ","color: MidnightBlue; background: Aquamarine;",e),f?f.reqPut("/v10/config/connection",e,e=>{t(e.data)}):t("success")}(e,e=>{t(e)})}catch(e){i(e)}})}const S={context:["tab","linkList","linkSelected","linkUpdate","connectionNameErr"],actions:{setLinkSelected(e){this.noSaveConfirm(()=>{this._setLinkSelected(e)})},_setLinkSelected(e){this.model.linkList.forEach(t=>{t.isSelected=t.connectionName===e,t.connectionName===e&&(this.model.linkSelected=Object.assign({},t,{isSelected:!1}))}),this.model.linkList=[...this.model.linkList],this.model.linkUpdate=this.model.linkSelected},onIconClick(e,t){switch(e){case"删除":!function(e,t){console.log("%cid: ","color: MidnightBlue; background: Aquamarine;",e),f?f.reqDeleta(`/v10/config/connection/${e}`,e=>{t(e.data)}):t("success")}(t,()=>{this.model.linkList=[...this.model.linkList.filter(e=>e.connectionId!==t)],this.model.linkSelected={},this.model.linkUpdate={}});break;case"测试连接":this._textLink(t);break;case"复制":this.noSaveConfirm(()=>{this.copyLink(t)})}},_textLink(e){const t=T.loading("正在测试连接,请稍候..."),i=this.model.linkList.find(t=>t.connectionId===e);var s,o;s=i,o=(s=>{T.close(t),s&&s.errorCode?T.linkFail(`${i.connectionName}测试连接失败`,s.errorMsg,()=>{this._textLink(e)}):T.success("连接成功")}),console.log("%cdata: ","color: MidnightBlue; background: Aquamarine;",s),f?f.reqPost("/v10/config/connection/test",s,e=>{o(e)}):setTimeout(()=>{o({errorCode:"500",errorMsg:"createConnectionThread not start!"})},2e3)},copyLink(e){const t=BI.find(this.model.linkList,(t,i)=>i.connectionId===e).connectionName,i=N(this.model.linkList,t);let s={};this.model.linkList.forEach(t=>{t.connectionId===e&&(s=t)});const o=Object.assign({},s,{isSelected:!0,connectionName:i,connectionId:""});this.model.linkList=[o,...this.model.linkList],this.model.linkSelected=Object.assign({},o),this.model.linkUpdate=Object.assign({},o)},setLinkUpdate(e){this.model.linkUpdate=e},setEdit(e){this.model.linkSelected=Object.assign({},this.model.linkSelected,{isSelected:e}),this.model.linkUpdate=this.model.linkSelected},setCancel(){const e=this.model.linkSelected,t=this.model.linkList;e.connectionId?this.setEdit(!1):(this.model.linkList=[...t.filter(e=>!!e.connectionId)],this.model.linkList.length>0?(this.model.linkList[0].isSelected=!0,this.model.linkSelected=Object.assign({},this.model.linkList[0],{isSelected:!1})):this.model.linkSelected={},this.model.linkUpdate=this.model.linkSelected)},setNewLink(e){w.some(t=>t.text===e)||BI.Constants.getConstant(`dec.constant.database.conf.connect.form.${e.toLowerCase()}.edit`)?this.noSaveConfirm(()=>{this._setNewLink(e)}):T.error("找不到该连接的配置信息")},_setNewLink(e){const t=N(this.model.linkList,e);let i={};w.forEach(t=>{t.text===e&&(i=t)}),this.model.linkList=[Object.assign({connectionName:t,isSelected:!0},i,{text:e}),...this.model.linkList],this.model.linkSelected=Object.assign({},i,{connectionName:t,isSelected:!0,text:e}),this.model.linkUpdate=Object.assign({},i,{connectionName:t,text:e})},setConnectionNameErr(e){this.model.connectionNameErr=e},noSaveConfirm(e){this.model.linkSelected&&this.model.linkSelected.isSelected?T.confirm("当前设置尚未保存,是否保存?",t=>{t?this.saveLink():this.setCancel(),e()}):e()},saveLink(){const e=this.model.linkUpdate.text?BI.Constants.getConstant(`dec.constant.database.conf.connect.form.${this.model.linkUpdate.text.toLowerCase()}.value`):{};C(Object.assign({},this.model.linkUpdate,e)).then(()=>{this.setEdit(!1)})}}};BI.model("fr.model.linkset",BI.inherit(Fix.Model,S));var j="fr.model.linkset";const _={_store:()=>BI.Models.getModel(j),render(){const{cls:e,title:t,id:i}=this.options,o=this;let r=null,n=null;return"删除"===t?{type:"bi.bubble_combo",direction:"bottom",ref(){n=this},el:{type:s,cls:e,extraCls:"action-icon",height:24,width:26,title:t,ref(e){r=e}},popup:{type:"bi.text_bubble_bar_popup_view",text:"确定删除该数据连接?",listeners:[{eventName:BI.BubblePopupBarView.EVENT_CLICK_TOOLBAR_BUTTON,action(e){n.hideView(),e&&o.store.onIconClick(t,i)}}]},listeners:[{eventName:BI.BubbleCombo.EVENT_EXPAND,action(){r.element.css({visibility:"visible"})}},{eventName:BI.BubbleCombo.EVENT_AFTER_HIDEVIEW,action(){r.element.css({visibility:"hidden"})}}]}:{type:s,cls:e,extraCls:"action-icon",height:24,width:26,title:t}},mounted(){const{title:e,id:t}=this.options;"删除"!==e?this.element.on("click",i=>{i.stopPropagation(),this.store.onIconClick(e,t)}):this.element.on("click",e=>{e.stopPropagation()})}};BI.shortcut("fr.component.linkSet.left.item.icon",BI.inherit(BI.Widget,_));const L={props:{title:"",id:"",creator:""},_store:()=>BI.Models.getModel(j),render(){const{title:e,extraCls:t,creator:i,text:r,id:n}=this.options;return{type:h,cls:"left-item",extraCls:t,items:[{type:s,cls:"link-font",height:24,width:26,text:"连接",title:e},{type:o,cls:"link-title",textAlign:"left",text:e,title:e},{type:h,cls:"icons",items:[{type:"fr.component.linkSet.left.item.icon",cls:"link-text-font",title:"测试连接",id:n},{type:"fr.component.linkSet.left.item.icon",cls:"copy-font",title:"复制",id:n},{type:"fr.component.linkSet.left.item.icon",cls:"info-font",title:`类型:${"DESIGNER"===r?"其他":r} \r\n创建者:${i}`,id:n},{type:"fr.component.linkSet.left.item.icon",cls:"delete-font",title:"删除",id:n}]}]}},mounted(){const{title:e}=this.options;this.element.on("click",()=>{this.store.setLinkSelected(e)})}};BI.shortcut("fr.component.linkSet.left.item",BI.inherit(BI.Widget,L));let D=null;const A={_store:()=>BI.Models.getModel(j),watch:{linkList(e){D.populate(BI.createItems((e=>{const t=[];return e.forEach(e=>{t.push({type:"fr.component.linkSet.left.item",extraCls:e.isSelected?"left-item-selected":"",title:e.connectionName,id:e.connectionId,creator:e.creator,text:e.text?e.text:"默认"})}),t})(e)))}},render:()=>({type:d,ref(e){D=e}})};BI.shortcut("fr.component.linkset.left",BI.inherit(BI.Widget,A));const M={render(){const{text:e,name:t,selected:i}=this.options;return{type:d,cls:"link-item",width:120,height:117,items:[{type:"bi.img",width:120,height:90,src:`./img/${t}.jpg`},{type:c,cls:"selected",invisible:!i,width:30,height:30},{type:o,cls:"text",text:e}]}},mounted(){const{text:e}=this.options;this.element.on("click",()=>{this.fireEvent("EVENT_SELECT",e)})}};BI.shortcut("fr.component.linkSet.morelink.item",BI.inherit(BI.Widget,M));let O=null;const U={render:()=>({type:l,cls:"more-link",items:[{el:{type:d,items:[{type:"bi.search_editor",width:300,watermark:"搜索"}]},height:30},{type:h,cls:"more-link-item",ref(e){O=e}}]}),mounted(){this._renderItems()},_renderItems(e=""){const t=w.slice(12,45),i=[],s=this;t.forEach(t=>{i.push({type:"fr.component.linkSet.morelink.item",text:t.text,name:t.databaseType,selected:e===t.text,listeners:[{eventName:"EVENT_SELECT",action(e){s._renderItems(e),s.fireEvent("EVENT_SELECT",e)}}]})}),O.populate(BI.createItems(i))}};BI.shortcut("fr.component.linkSet.morelink",BI.inherit(BI.Widget,U));let q=null,V="";const P={_store:()=>BI.Models.getModel(j),render(){let e=null;return{type:"bi.combo",cls:"select",trigger:"click",adjustYOffset:4,el:{type:"bi.button",text:"新建数据连接",height:24},popup:{el:{type:"bi.button_group",cls:"database-link-items",items:[...BI.map([...B,...BI.Constants.getConstant(E)],(e,t)=>({type:"bi.text_item",height:24,width:152,text:t,title:t,value:t})),{type:"bi.text_item",cls:"link-item",height:24,width:152,text:"更多数据连接...",title:"更多数据连接...",value:"more"},{type:"bi.text_item",cls:"link-item",height:24,width:152,text:"其他",title:"其他",value:"其他"}],layouts:[{type:d}]},maxHeight:400},listeners:[{eventName:"EVENT_CHANGE",action:t=>{"more"===t?(e=>{const t=BI.UUID();let i=null;BI.Popovers.create(t,{type:"bi.bar_popover",size:"normal",header:"更多数据连接",width:550,height:500,body:{type:"fr.component.linkSet.morelink",listeners:[{eventName:"EVENT_SELECT",action(e){V=e,q.setEnable(!0)}}]},footer:{type:"bi.right_vertical_adapt",lgap:10,items:[{type:"bi.button",text:"取消",value:1,level:"ignore",handler(e){i.close(e)}},{type:"bi.button",text:"确定",disabled:!0,value:0,ref(e){q=e},handler(t){i.close(t),e&&e(V)}}]},ref(e){i=e}}).open(t)})(e=>{this.store.setNewLink(e)}):this.store.setNewLink(t),e.hideView()}}],ref(){e=this}}}};BI.shortcut("fr.linkset.select",BI.inherit(BI.Widget,P));const H={render:()=>({type:"bi.center_adapt",items:[{type:d,width:260,height:180,items:[{type:c,cls:"data-connection-background",width:260,height:130},{type:o,cls:"bi-tips",height:20,text:"请选择左侧数据连接或点击新建数据连接"},{type:o,cls:"bi-tips",height:20,text:"平台仅支持使用JDBC的数据连接的管理"}]}]})};BI.shortcut("fr.component.right.nothing",BI.inherit(BI.Widget,H));const R={_store:()=>BI.Models.getModel(j),render(){const e=this.model.linkSelected,t=this.model.linkList,i=this,{isEdit:s}=this.options;return{type:h,height:40,cls:"right-title",items:[{type:o,cls:"right-title-text",text:`数据连接(${e.text?e.text:"默认"})`},{type:r,cls:"right-title-button",invisible:s,text:"编辑",handler(){i.store.setEdit(!0)}},{type:r,cls:"right-title-button",invisible:!s,text:"保存",handler(){BI.find(t,(e,t)=>i.model.linkUpdate.connectionName===t.connectionName&&t.connectionId!==i.model.linkUpdate.connectionId)?i.store.setConnectionNameErr("数据连接名已存在"):i.store.saveLink()}},{type:r,cls:"right-title-button",invisible:!s,level:"ignore",text:"取消",handler(){i.store.setCancel()}}]}}};BI.shortcut("fr.component.right.title",BI.inherit(BI.Widget,R));const G="fr.shared.component.both.side",W={render(){const{leftText:e,rightText:t}=this.options;return{type:a,cls:"both-side",height:24,items:[{el:{type:o,cls:"left",textAlign:"left",text:e},width:115},{type:o,textAlign:"left",text:t}]}}};BI.shortcut(G,BI.inherit(BI.Widget,W));var F=G;const $={render(){const{text:e}=this.options;return{type:o,cls:"shared-component-title",textAlign:"left",text:e}}};BI.shortcut("fr.shared.component.title",BI.inherit(BI.Widget,$));const Q={_store:()=>BI.Models.getModel(j),render(){const e=this.model.linkSelected;return{type:d,cls:"right-show",items:[{type:F,leftText:"数据连接名",rightText:e.connectionName},{type:F,leftText:"驱动器",rightText:e.driver},{type:F,leftText:"URL",rightText:e.url},{type:F,leftText:"编码",rightText:""===e.originalCharsetName?"自动":e.originalCharsetName},{type:F,leftText:"用户名",rightText:e.user},{type:F,leftText:"密码",rightText:e.password},{type:"fr.shared.component.title",text:"连接池属性"},{type:F,leftText:"SQL验证查询",rightText:e.validationQuery},{type:F,leftText:"获取连接前校验",rightText:e.testOnBorrow?"是":"否"},{type:F,leftText:"最大连接数量",rightText:e.maxActive}]}}};BI.shortcut("fr.component.right.show",BI.inherit(BI.Widget,Q));BI.constant("bi.constant.database.conf.charset.list",[{text:"自动",value:""},{text:"GBK",value:"GBK"},{text:"BIG5",value:"BIG5"},{text:"ISO-8859-1",value:"ISO-8859-1"},{text:"UTF-8",value:"UTF-8"},{text:"UTF-16",value:"UTF-16"},{text:"EUC_JP",value:"EUC_JP"},{text:"EUC_KR",value:"EUC_KR"},{text:"CP850",value:"CP850"}]);const z={render(){const{text:e,form:t,hint:i,height:s}=this.options;return{type:a,cls:"both-side",height:s||24,items:[{el:{type:o,cls:"left",textAlign:"left",text:e},width:115},t,{type:o,cls:"hint",textAlign:"left",text:i}]}}};BI.shortcut("fr.shared.component.form.item",BI.inherit(BI.Widget,z));var K="fr.shared.component.form.item";function X(e){const t=[];return e.drivers&&e.drivers.length>0?e.drivers.forEach(e=>{t.push({text:e,value:e})}):t.push({text:e.driver,value:e.driver}),t}let Y=null;const J={_store:()=>BI.Models.getModel(j),watch:{connectionNameErr(e){e?BI.Bubbles.show("singleBubble",e,Y,{level:"error"}):BI.Bubbles.hide("singleBubble")}},render(){const e=this.model.linkSelected,t=this;return{type:d,cls:"right-show",items:[{type:K,text:"数据连接名",hint:"*修改数据连接名会影响相关数据表和仪表板",form:{type:n,cls:"bi-border",width:300,value:e.connectionName,ref(e){Y=e},listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{connectionName:this.getValue()}))}},{eventName:BI.Editor.EVENT_FOCUS,action(){t.store.setConnectionNameErr("")}}]}},{type:K,text:"第一步",height:400,form:{type:d,cls:"right-form",items:[{type:K,text:"驱动器",form:{type:"bi.text_value_combo",cls:"bi-border",width:300,text:e.driver,items:X(e),listeners:[{eventName:BI.TextValueCombo.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{driver:this.getValue()[0]}))}}]}},{type:K,text:"URL",form:{type:n,cls:"bi-border",watermark:"请输入",width:300,value:e.url,listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{url:this.getValue()}))}}]}},{type:K,text:"编码",form:{type:"bi.text_value_combo",cls:"bi-border",width:300,text:""===e.originalCharsetName?"自动":e.originalCharsetName,items:BI.Constants.getConstant("bi.constant.database.conf.charset.list"),listeners:[{eventName:BI.TextValueCombo.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{originalCharsetName:this.getValue()[0]}))}}]}},{type:K,text:"用户名",form:{type:n,cls:"bi-border",allowBlank:!0,watermark:"请输入",width:300,value:e.user,listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{user:this.getValue()}))}}]}},{type:K,text:"密码",form:{type:n,cls:"bi-border",inputType:"password",allowBlank:!0,watermark:"请输入",width:300,value:e.password,listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{password:this.getValue()}))}}]}},{type:"fr.shared.component.title",text:"连接池属性"},{type:K,text:"SQL验证查询",height:100,form:{type:"bi.textarea_editor",cls:"bi-border",allowBlank:!0,watermark:"请输入",width:300,height:100,value:e.validationQuery,listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{validationQuery:this.getValue()}))}}]}},{type:K,text:"获取连接前校验",form:{type:"bi.multi_select_item",text:"是",selected:e.testOnBorrow,width:60,listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{testOnBorrow:this.isSelected()}))}}]}},{type:K,text:"最大活动连接数",form:{type:n,cls:"bi-border",allowBlank:!0,watermark:"请输入",width:60,value:e.maxActive,errorText:"请输入有效的正整数",validationChecker:e=>!!/^\+?[1-9][0-9]*$/.test(e),listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{maxActive:this.getValue()}))}}]}}]}},{type:K,text:"第二步",form:{type:r,text:"测试连接",level:"ignore"}},{type:K,text:"第三步",form:{type:K,text:"模式",form:{type:n,cls:"bi-border",width:300,disabled:!0}}}]}}};BI.shortcut("fr.component.right.edit",BI.inherit(BI.Widget,J));const Z={_store:()=>BI.Models.getModel(j),render(){const e=this.model.linkSelected,t=this;return{type:d,cls:"right-show",items:[{type:K,text:"数据连接名",hint:"*修改数据连接名会影响相关数据表和仪表板",form:{type:n,cls:"bi-border",width:300,value:e.connectionName,listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{connectionName:this.getValue()}))}}]}},{type:K,text:"驱动器",form:{type:"bi.text_value_combo",cls:"bi-border",width:300,text:e.driver,items:X(e),listeners:[{eventName:BI.TextValueCombo.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{driver:this.getValue()[0]}))}}]}},{type:K,text:"URL",form:{type:n,cls:"bi-border",watermark:"请输入",width:300,value:e.url,listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{url:this.getValue()}))}}]}},{type:K,text:"编码",form:{type:"bi.text_value_combo",cls:"bi-border",width:300,text:""===e.originalCharsetName?"自动":e.originalCharsetName,items:BI.Constants.getConstant("bi.constant.database.conf.charset.list"),listeners:[{eventName:BI.TextValueCombo.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{originalCharsetName:this.getValue()[0]}))}}]}},{type:K,text:"用户名",form:{type:n,cls:"bi-border",allowBlank:!0,watermark:"请输入",width:300,value:e.user,listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{user:this.getValue()}))}}]}},{type:K,text:"密码",form:{type:n,cls:"bi-border",inputType:"password",allowBlank:!0,watermark:"请输入",width:300,value:e.password,listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{password:this.getValue()}))}}]}},{type:"fr.shared.component.title",text:"连接池属性"},{type:K,text:"SQL验证查询",height:100,form:{type:"bi.textarea_editor",cls:"bi-border",allowBlank:!0,watermark:"请输入",width:300,height:100,value:e.validationQuery,listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{validationQuery:this.getValue()}))}}]}},{type:K,text:"获取连接前校验",form:{type:"bi.multi_select_item",text:"是",selected:e.testOnBorrow,width:60,listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{testOnBorrow:this.isSelected()}))}}]}},{type:K,text:"最大活动连接数",form:{type:n,cls:"bi-border",allowBlank:!0,watermark:"请输入",width:60,value:e.maxActive,errorText:"请输入有效的正整数",validationChecker:e=>!!/^\+?[1-9][0-9]*$/.test(e),listeners:[{eventName:BI.Editor.EVENT_CHANGE,action(){t.store.setLinkUpdate(Object.assign({},t.model.linkUpdate,{maxActive:this.getValue()}))}}]}},{type:K,text:"测试连接",form:{type:r,text:"测试连接",level:"ignore"}}]}}};BI.shortcut("fr.component.right.edit.mysql",BI.inherit(BI.Widget,Z));let ee=null;const te=e=>{const t=BI.Constants.getConstant(E),i=BI.some(t,(t,i)=>i===e.text);let s="mysql"===e.databaseType?"fr.component.right.edit.mysql":"fr.component.right.edit";i&&(s=BI.Constants.getConstant(`dec.constant.database.conf.connect.form.${e.text.toLowerCase()}.edit`));const o=i?BI.Constants.getConstant(`dec.constant.database.conf.connect.form.${e.text.toLowerCase()}.preview`):"fr.component.right.show";ee.populate(BI.createItems([{type:"fr.component.right.title",isEdit:e.isSelected,linkSelected:e},{type:e.isSelected?s:o,linkSelected:e}]))},ie={_store:()=>BI.Models.getModel(j),watch:{linkSelected(e){te(e)}},render:()=>({type:d,cls:"right-content",ref(e){ee=e}}),mounted(){const e=this.model.linkSelected;te(e)}};BI.shortcut("fr.component.right.detail",BI.inherit(BI.Widget,ie));let se=null;const oe={_store:()=>BI.Models.getModel(j),watch:{linkSelected(e){se.populate(BI.createItems([{type:e&&e.connectionName?"fr.component.right.detail":"fr.component.right.nothing"}]))}},render:()=>({type:d,cls:"database-right",ref(e){se=e}}),mounted(){se.populate(BI.createItems([{type:"fr.component.right.nothing"}]))}};BI.shortcut("fr.component.right",BI.inherit(BI.Widget,oe));const re={_store:()=>BI.Models.getModel(j),watch:{tab(e){this.setVisible("数据连接管理"===e)}},render:()=>({type:a,cls:"linkset",items:[{el:{type:l,cls:"database-left",items:[{el:{type:h,cls:"select-group",items:[{type:"fr.linkset.select"}]},height:40},{type:"fr.component.linkset.left",cls:"left-list"}]},width:280},{type:"fr.component.right"}]})};BI.shortcut("fr.linkset",BI.inherit(BI.Widget,re));BI.model("fr.model.linkstatus",BI.inherit(Fix.Model,{context:["tab","linkList"],actions:{}}));const ne={context:["tab","linkList","statusSelected"],state:()=>({selected:""}),actions:{setStatusSelected(e){this.model.statusSelected=e}}};BI.model("fr.model.linkstatus.left",BI.inherit(Fix.Model,ne));const le={props:{title:"",id:"",creator:""},_store:()=>BI.Models.getModel("fr.model.linkstatus.left"),render(){const{title:e,extraCls:t,creator:i,text:s,id:r}=this.options;return{type:h,cls:"left-item",extraCls:t,items:[{type:o,cls:"link-title",textAlign:"left",text:e,title:e}]}},mounted(){const{title:e}=this.options;this.element.on("click",()=>{this.store.setStatusSelected(e)})}};BI.shortcut("fr.component.linkStatus.left.item",BI.inherit(BI.Widget,le));let ae=null;const ce={_store:()=>BI.Models.getModel("fr.model.linkstatus.left"),watch:{linkList(e){const t=e.length>0?e[0].connectionName:"";this.store.setStatusSelected(t)},statusSelected(e){const t=this.model.linkList;ae.populate(BI.createItems(((e,t="")=>{const i=[];return e.forEach(e=>{i.push({type:"fr.component.linkStatus.left.item",extraCls:e.connectionName===t?"left-item-selected":"",title:e.connectionName,id:e.connectionId,creator:e.creator,text:e.text?e.text:"默认"})}),i})(t,e)))}},render:()=>({type:d,ref(e){ae=e}})};BI.shortcut("fr.component.linkStatus.left",BI.inherit(BI.Widget,ce));const de={context:["linkList","statusSelected"],state:()=>({selected:""}),actions:{}};BI.model("fr.model.linkstatus.right",BI.inherit(Fix.Model,de));const he={render(){const{maxActive:e,maxIdle:t,numActive:i,numIdle:s}=this.options;return{type:h,items:[{type:h,cls:"right-status-item",items:[{type:d,cls:"right-status-board",items:[{type:d,cls:"right-status-board-item",items:[{type:o,cls:"right-status-text",extraCls:"card-font1",text:i},{type:o,cls:"right-status-text",text:"/"},{type:o,cls:"right-status-text",text:e}]},{type:o,height:20,text:"活动连接数"}]}]},{type:h,cls:"right-status-right",items:[{type:d,cls:"right-status-board",items:[{type:d,cls:"right-status-board-item",items:[{type:o,cls:"right-status-text",extraCls:"card-font2",text:s},{type:o,cls:"right-status-text",text:"/"},{type:o,cls:"right-status-text",text:t}]},{type:o,height:20,text:"空闲连接数"}]}]}]}}};BI.shortcut("fr.component.linkStatus.right.card",BI.inherit(BI.Widget,he));let pe=null,me=null;const be={_store:()=>BI.Models.getModel("fr.model.linkstatus.right"),watch:{statusSelected(e){const t=BI.find(this.model.linkList,(t,i)=>i.connectionName===e),i=BI.Constants.getConstant(E),s=t.text&&BI.some(i,(e,i)=>i===t.text)?BI.Constants.getConstant(`dec.constant.database.conf.connect.form.${t.text.toLowerCase()}.pool`):"fr.component.linkStatus.right.card";!function(e,t){console.log("%cname: ","color: MidnightBlue; background: Aquamarine;",e),f?f.reqDeleta(`/v10/config/connection/pool/info?connectionName=${e}`,e=>{t(e.data)}):t({maxActive:50,maxIdle:10,numActive:0,numIdle:0})}(name,e=>{me.populate(BI.createItems([Object.assign({type:s},e)]))}),pe.setText(`数据连接(${e})`)}},render:()=>({type:d,cls:"database-right",items:[{type:h,height:40,cls:"right-status-title",items:[{type:o,text:"数据连接"}],ref(e){pe=e}},{type:d,cls:"right-status-body",ref(e){me=e}}]}),mounted(){}};BI.shortcut("fr.component.linkStatus.right",BI.inherit(BI.Widget,be));const ue={_store:()=>BI.Models.getModel("fr.model.linkstatus"),watch:{tab(e){this.setVisible("连接池状态"===e)}},render:()=>({type:a,cls:"linkStatus",items:[{el:{type:l,cls:"database-left",items:[{el:{type:h,cls:"select-group",items:[{type:o,cls:"status-title",text:"数据连接"}]},height:40},{type:"fr.component.linkStatus.left",cls:"left-list"}]},width:280},{type:"fr.component.linkStatus.right"}]}),mounted(){this.setVisible(!1)}};BI.shortcut("fr.linkstatus",BI.inherit(BI.Widget,ue));i(1);const ge={url:"192.168.1.22",port:6379,password:"123456"},ye=BI.inherit(BI.Widget,{render:()=>({type:"bi.vertical",cls:"bi-plugin-redis",bgap:10,items:[{type:"bi.left",height:30,items:[{type:"bi.label",text:"数据库地址:",height:24,width:115,textAlign:"left"},{type:"bi.editor",cls:"bi-border",watermark:"数据库地址",value:ge.url,allowBlank:!0,width:300,height:24}]},{type:"bi.left",height:30,items:[{type:"bi.label",text:"端口:",height:24,width:115,textAlign:"left"},{type:"bi.editor",cls:"bi-border",watermark:"端口",allowBlank:!0,width:300,height:24,value:ge.port,errorText:"请输入有效的正整数",validationChecker:e=>!!/^\+?[1-9][0-9]*$/.test(e)}]},{type:"bi.left",height:30,items:[{type:"bi.label",text:"密码:",height:24,width:115,textAlign:"left"},{type:"bi.editor",cls:"bi-border",inputType:"password",value:ge.password,allowBlank:!0,width:300,height:24}]}]})});BI.shortcut("fr.plugin.redis.edit",ye);BI.config("dec.constant.database.conf.connect.list",e=>[...e,"Redis"]),BI.constant("dec.constant.database.conf.connect.form.redis.value",ge),BI.constant("dec.constant.database.conf.connect.form.redis.edit","fr.plugin.redis.edit");i(2),i(3),i(4);const fe=BI.inherit(BI.Widget,{_store:()=>BI.Models.getModel("fr.model.main"),render:()=>({type:l,cls:"database-connection-layout",items:[{el:{type:"fr.title"},height:40},{type:"fr.linkset"},{type:"fr.linkstatus"}]}),mounted(){var e;e=(e=>{this.store.setLinkList(e)}),f?f.reqGet("/v10/config/connection/list","getInstalledPlugins",t=>{e(t.data)}):e(y.data)}});BI.shortcut("fr.main",fe);t.default="fr.main"}]);
+//# sourceMappingURL=index.js.map
\ No newline at end of file
diff --git a/designer-base/src/main/resources/com/fr/design/dcm/style.css b/designer-base/src/main/resources/com/fr/design/dcm/style.css
new file mode 100644
index 0000000000..5208edfa3b
--- /dev/null
+++ b/designer-base/src/main/resources/com/fr/design/dcm/style.css
@@ -0,0 +1,276 @@
+.bi-plugin-redis {
+ padding: 20px; }
+
+.database-connection-layout {
+ width: 100%;
+ height: 100%;
+ background-color: #f7f8fa; }
+ .database-connection-layout .title {
+ background-color: #fff;
+ border-bottom: 1px solid #e8eaed; }
+ .database-connection-layout .title .title-item {
+ height: 39px;
+ line-height: 39px;
+ padding-left: 15px;
+ padding-right: 15px;
+ text-align: center;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ position: relative;
+ flex-shrink: 0;
+ font-weight: 700;
+ cursor: pointer; }
+ .database-connection-layout .title .close-button {
+ position: absolute !important;
+ right: 5px;
+ top: 5px;
+ width: 30px;
+ height: 30px;
+ cursor: pointer;
+ background-image: url(./img/icon_close9x9_normal.png);
+ background-repeat: no-repeat;
+ background-position: center; }
+ .database-connection-layout .linkset {
+ margin: 10px;
+ bottom: 0px;
+ background-color: #ffffff; }
+ .database-connection-layout .linkStatus {
+ margin: 10px;
+ top: 40px;
+ background-color: #ffffff; }
+
+.database-left {
+ border-right: 1px solid #e8eaed; }
+ .database-left .select-group {
+ border-bottom: 1px solid #e8eaed; }
+ .database-left .select-group .select {
+ margin: 10px; }
+ .database-left .select-group .select .database-link-items {
+ padding-left: 10px; }
+ .database-left .select-group .select .database-link-items .link-item {
+ border-top: 1px solid #e8eaed; }
+ .database-left .select-group .status-title {
+ font-weight: 700;
+ margin-left: 12px;
+ margin-top: 12px; }
+ .database-left .left-list {
+ margin: 10px; }
+ .database-left .left-list .left-item {
+ height: 24px;
+ line-height: 24px;
+ cursor: pointer; }
+ .database-left .left-list .left-item:hover {
+ background-color: rgba(54, 133, 242, 0.05); }
+ .database-left .left-list .left-item:hover .icons .action-icon {
+ visibility: visible !important; }
+ .database-left .left-list .left-item .icons {
+ float: right !important; }
+ .database-left .left-list .left-item .icons .action-icon {
+ visibility: hidden; }
+ .database-left .left-list .left-item .icons .b-font {
+ font-size: 16px; }
+ .database-left .left-list .left-item-selected {
+ background-color: rgba(54, 133, 242, 0.05); }
+ .database-left .left-list .left-item-selected .link-title {
+ color: #3685f2; }
+
+.database-right {
+ min-width: 400px;
+ overflow: auto; }
+ .database-right .bi-flex-center-adapt-layout {
+ height: 100%; }
+ .database-right .bi-flex-center-adapt-layout .data-connection-background {
+ background: url(./img/resources.png) center center no-repeat;
+ background-size: contain; }
+ .database-right .right-status-title {
+ border-bottom: 1px solid #e8eaed;
+ color: #3d4d66;
+ line-height: 40px;
+ padding-left: 10px;
+ font-weight: 700; }
+ .database-right .right-status-body {
+ margin: 10px 30px 0px 30px;
+ height: 50%; }
+ .database-right .right-status-body .right-status-item {
+ height: 150px;
+ width: 50%;
+ top: 0;
+ left: 0;
+ position: absolute !important; }
+ .database-right .right-status-body .right-status-item .right-status-board {
+ margin-left: 25px;
+ position: relative !important;
+ left: -25px; }
+ .database-right .right-status-body .right-status-right {
+ height: 150px;
+ width: 50%;
+ top: 0;
+ right: 0;
+ position: absolute !important; }
+ .database-right .right-status-body .right-status-right .right-status-board {
+ margin-right: 25px;
+ position: relative !important;
+ left: 25px; }
+ .database-right .right-status-body .right-status-board {
+ background-color: #f7f8fa;
+ color: #3d4d66;
+ width: 100%;
+ height: 100%; }
+ .database-right .right-status-body .right-status-board .right-status-board-item {
+ text-align: center;
+ margin-top: 38px; }
+ .database-right .right-status-body .right-status-board .right-status-board-item .right-status-text {
+ display: inline-block; }
+ .database-right .right-status-body .right-status-board .right-status-board-item .card-font1 {
+ color: #13CD66;
+ font-size: 32px; }
+ .database-right .right-status-body .right-status-board .right-status-board-item .card-font2 {
+ color: #3685F2;
+ font-size: 32px; }
+ .database-right .right-content {
+ height: 100%; }
+ .database-right .right-content .right-title {
+ border-bottom: 1px solid #e8eaed;
+ color: #3d4d66;
+ line-height: 40px;
+ padding-left: 10px; }
+ .database-right .right-content .right-title .right-title-text {
+ font-weight: 700; }
+ .database-right .right-content .right-title .right-title-button {
+ float: right !important;
+ margin-right: 10px;
+ margin-top: 8px; }
+ .database-right .right-content .right-show {
+ margin: 10px; }
+ .database-right .right-content .right-show .right-form {
+ width: 100%; }
+
+.both-side {
+ line-height: 24px;
+ margin-bottom: 10px; }
+ .both-side .left {
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ position: relative;
+ flex-shrink: 0;
+ font-weight: 700; }
+ .both-side .hint {
+ padding-left: 5px;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ position: relative;
+ flex-shrink: 0;
+ margin-left: 5px;
+ color: #9ea6b2; }
+
+.shared-component-title {
+ height: 24px;
+ line-height: 24px;
+ margin-bottom: 10px;
+ color: #9ea6b2;
+ border-bottom: 1px solid #e8eaed; }
+
+.comfirm-content {
+ margin-top: 40px;
+ margin-left: 20px; }
+ .comfirm-content .comfirm-icon {
+ background-image: url(./img/warning.png);
+ background-size: contain;
+ margin-right: 12px; }
+ .comfirm-content .bi-text {
+ height: 50px;
+ line-height: 50px;
+ margin-left: 12px; }
+
+.more-link .more-link-item {
+ width: 538px;
+ overflow: hidden auto;
+ left: -10px !important;
+ right: 0px;
+ top: 10px;
+ bottom: 0px;
+ position: absolute;
+ height: 380px; }
+ .more-link .more-link-item .link-item {
+ margin-left: 10px;
+ margin-bottom: 10px;
+ cursor: pointer;
+ border: solid 1px #fff; }
+ .more-link .more-link-item .link-item:hover {
+ border: solid 1px #3480f2; }
+ .more-link .more-link-item .link-item .selected {
+ position: absolute !important;
+ right: -1px;
+ top: -1px;
+ height: 30px;
+ width: 30px;
+ background: url(./img/database-selected.png) center center no-repeat;
+ background-size: contain; }
+ .more-link .more-link-item .link-item .text {
+ height: 27px;
+ line-height: 27px;
+ padding-left: 2px;
+ padding-right: 2px;
+ text-align: center;
+ white-space: nowrap;
+ background: #F0F3F7; }
+
+.popover-notitle .bi-header-background {
+ display: none; }
+
+.popover-notitle .bi-absolute-layout {
+ top: 0px !important; }
+
+.bi-custom-show .show-content {
+ text-align: center; }
+ .bi-custom-show .show-content .loading-icon {
+ display: block;
+ background: url(./img/loading.gif) center center no-repeat;
+ background-size: contain;
+ margin: 0 auto;
+ margin-bottom: 18px; }
+ .bi-custom-show .show-content .success-icon {
+ display: block;
+ background: url(./img/success.png) center center no-repeat;
+ background-size: contain;
+ margin: 0 auto;
+ margin-bottom: 18px; }
+ .bi-custom-show .show-content .error-icon {
+ display: block;
+ background: url(./img/error.png) center center no-repeat;
+ background-size: contain;
+ margin: 0 auto;
+ margin-bottom: 18px; }
+ .bi-custom-show .show-content .buttons {
+ margin-top: 18px; }
+ .bi-custom-show .show-content .buttons div {
+ margin: 0 4px; }
+
+.bi-custom-show .show-more {
+ text-align: left !important;
+ height: 73px;
+ background: #F2F4F7;
+ margin-bottom: 10px;
+ padding: 5px;
+ margin-top: 10px; }
+
+.link-font .b-font:before {
+ content: "\e759";
+ color: inherit; }
+
+.link-text-font .b-font:before {
+ content: "\e763";
+ color: inherit; }
+
+.info-font .b-font:before {
+ content: "\e63c";
+ color: inherit; }
+
+.delete-font .b-font:before {
+ content: "\e6c4";
+ color: inherit; }
+
+
+/*# sourceMappingURL=style.css.map*/
\ No newline at end of file
diff --git a/designer-base/src/main/resources/com/fr/design/images/bbs/facebook.png b/designer-base/src/main/resources/com/fr/design/images/bbs/facebook.png
new file mode 100644
index 0000000000..9e5dc8af2c
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/bbs/facebook.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_back_normal@2x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_back_normal@2x.png
new file mode 100644
index 0000000000..bb3fd50cdc
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_back_normal@2x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_delete.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_delete.png
new file mode 100755
index 0000000000..6fb2baac51
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_delete.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_delete@2x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_delete@2x.png
new file mode 100755
index 0000000000..b98c9f4cd2
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_delete@2x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_edit.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_edit.png
new file mode 100755
index 0000000000..7206039bf6
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_edit.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_edit@2x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_edit@2x.png
new file mode 100755
index 0000000000..5993e43897
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_edit@2x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_filter@1x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_filter@1x.png
new file mode 100755
index 0000000000..7a8ec6287b
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_filter@1x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_filter@2x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_filter@2x.png
new file mode 100755
index 0000000000..9b3a132a77
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_filter@2x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_disabled.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_disabled.png
new file mode 100644
index 0000000000..5325682ff8
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_disabled.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_disabled@2x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_disabled@2x.png
new file mode 100644
index 0000000000..619551cc86
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_disabled@2x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_normal@2x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_normal@2x.png
new file mode 100644
index 0000000000..a400bffeca
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_list_normal@2x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_revert.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_revert.png
new file mode 100755
index 0000000000..993ba3c21b
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_revert.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_revert@2x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_revert@2x.png
new file mode 100755
index 0000000000..5f26df54c0
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_revert@2x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_disabled.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_disabled.png
new file mode 100644
index 0000000000..3e164a0ebf
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_disabled.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_disabled@2x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_disabled@2x.png
new file mode 100644
index 0000000000..70db7bcc49
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_disabled@2x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_normal@2x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_normal@2x.png
new file mode 100644
index 0000000000..34e94cb270
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_save_normal@2x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_user@1x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_user@1x.png
new file mode 100755
index 0000000000..7af8db5727
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_user@1x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/icon_user@2x.png b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_user@2x.png
new file mode 100755
index 0000000000..872351544a
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/icon_user@2x.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/vcs_back.png b/designer-base/src/main/resources/com/fr/design/images/vcs/vcs_back.png
new file mode 100644
index 0000000000..6b3a61b894
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/vcs_back.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/vcs_list.png b/designer-base/src/main/resources/com/fr/design/images/vcs/vcs_list.png
new file mode 100644
index 0000000000..df6cd02de6
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/vcs_list.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/images/vcs/vcs_save.png b/designer-base/src/main/resources/com/fr/design/images/vcs/vcs_save.png
new file mode 100644
index 0000000000..6783204cf8
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/vcs/vcs_save.png differ
diff --git a/designer-base/src/main/resources/com/fr/design/ui/InitNameSpace.js b/designer-base/src/main/resources/com/fr/design/ui/InitNameSpace.js
index 0274d5fa50..03b2bb32ae 100644
--- a/designer-base/src/main/resources/com/fr/design/ui/InitNameSpace.js
+++ b/designer-base/src/main/resources/com/fr/design/ui/InitNameSpace.js
@@ -1,6 +1,6 @@
-var arr ="%s".split(".").reverse();
-var create = function (obj, names) {
- var name = names.pop();
+let arr ="%s".split(".").reverse();
+let create = function (obj, names) {
+ let name = names.pop();
if (!name) {
return;
}
diff --git a/designer-base/src/main/resources/com/fr/design/ui/update/push/pushUpdate.css b/designer-base/src/main/resources/com/fr/design/ui/update/push/pushUpdate.css
new file mode 100644
index 0000000000..58c03ecba5
--- /dev/null
+++ b/designer-base/src/main/resources/com/fr/design/ui/update/push/pushUpdate.css
@@ -0,0 +1,88 @@
+body {
+ padding-left: 30px;
+ padding-top: 30px;
+ color: white;
+ background-size: 100% 100% !important;
+ -moz-background-size: 100% 100% !important;
+
+ font-family: "PingFang SC", "Microsoft YaHei", "Myriad Pro", "OpenSans", Verdana, SimSun, sans-serif !important;
+}
+
+.close-btn {
+ position: fixed !important;
+ font-size: 15px !important;
+ color: white !important;
+ top: 8px;
+ right: 10px;
+ width: 19px;
+}
+
+.close-btn .b-font {
+ height: 19px !important;
+ line-height: 19px !important;
+}
+
+.close-btn .b-font:before {
+ color: white !important;
+}
+
+.font-bold {
+ font-weight: 500;
+}
+
+.title {
+ font-size: 24px;
+ letter-spacing: 1.5px;
+ line-height: 24px;
+}
+
+.version {
+ font-size: 12px;
+ line-height: 14px;
+ margin-top: 6px;
+}
+
+.desc {
+ margin-top: 40px;
+ font-size: 13px;
+ width: 82%;
+ margin-left: 19px;
+ text-indent: -19px;
+ overflow: visible !important;
+}
+
+.desc .bi-label {
+ overflow: visible !important;
+}
+
+.moreInfo {
+ margin-top: 20px;
+ font-size: 13px;
+ text-decoration: underline;
+}
+
+.buttonGroup {
+ position: absolute !important;
+ bottom: 60px;
+}
+
+.buttonGroup .bi-button {
+ font-weight: 600;
+ font-size: 11px;
+ text-align: center;
+ line-height: 12px;
+ box-shadow: 0 2px 4px 0 rgba(0,82,169,0.20);
+ border-radius: 12px;
+}
+
+.buttonGroup .button-ignore {
+ background-color: white !important;
+ border: 1px solid white !important;
+ color: #51A6FF;
+}
+
+.buttonGroup .button-common {
+ background-color: #51A6FF !important;
+ border: 1px solid #51A6FF !important;
+}
+
diff --git a/designer-base/src/main/resources/com/fr/design/ui/update/push/pushUpdate.js b/designer-base/src/main/resources/com/fr/design/ui/update/push/pushUpdate.js
new file mode 100644
index 0000000000..f42fb1ac7b
--- /dev/null
+++ b/designer-base/src/main/resources/com/fr/design/ui/update/push/pushUpdate.js
@@ -0,0 +1,143 @@
+var MAX_DESC_NUM = 5; // 最多显示5条信息
+
+function i18nText(key) {
+ return Pool.data.i18nText(key);
+}
+
+function getDescArea(descList) {
+ var descItems = [];
+ for (var i in descList) {
+ var num = parseInt(i) + 1;
+ if (num > MAX_DESC_NUM) {
+ break;
+ }
+ descItems.push({
+ type: "bi.label",
+ text: num + ")" + descList[i],
+ whiteSpace: "pre-wrap",
+ textAlign: "left"
+ })
+ }
+
+ return BI.createWidget({
+ type: "bi.vertical",
+ cls: "desc",
+ items: descItems
+ });
+}
+
+function getTitleArea() {
+ return BI.createWidget({
+ type: "bi.vertical",
+ items: [
+ {
+ type: "bi.label",
+ text: i18nText("Fine-Design_Find_New_Version"),
+ cls: "title font-bold",
+ textAlign: "left"
+ },
+ {
+ type: "bi.label",
+ text: Pool.data.getVersion(),
+ cls: "version font-bold",
+ textAlign: "left"
+ }
+ ]
+ });
+}
+
+function getButtonGroup() {
+ return BI.createWidget({
+ type: 'bi.left',
+ cls: "buttonGroup",
+ items: [
+ {
+ type: 'bi.button',
+ text: i18nText("Fine-Design_Update_Now"),
+ level: 'common',
+ height: 24,
+ handler: function () {
+ Pool.data.updateNow();
+ }
+ },
+ {
+ el: {
+ type: 'bi.button',
+ text: i18nText("Fine-Design_Remind_Me_Next_Time"),
+ level: 'ignore',
+ height: 24,
+ handler: function () {
+ Pool.data.remindNextTime();
+ }
+ },
+ lgap: 10
+ },
+ {
+ el: {
+ type: 'bi.button',
+ text: i18nText("Fine-Design_Skip_This_Version"),
+ level: 'ignore',
+ height: 24,
+ handler: function () {
+ Pool.data.skipThisVersion();
+ }
+ },
+ lgap: 10
+ }
+ ]
+ });
+}
+
+function getMoreInfo() {
+ return BI.createWidget({
+ type: "bi.text_button",
+ text: i18nText("Fine-Design_See_More_New_Features"),
+ cls: "moreInfo",
+ textAlign: "left",
+ handler: function () {
+ // 为了使用系统的浏览器,只能从 Java 那边打开网页
+ Pool.data.browseMoreInfoUrl();
+ }
+ });
+}
+
+function getCloseButton() {
+ return BI.createWidget({
+ type: "bi.button",
+ text: "",
+ iconCls: "close-font",
+ cls: "close-btn",
+ clear: true,
+ handler: function () {
+ Pool.data.closeWindow();
+ }
+ });
+}
+
+function getShowItems() {
+ var title = getTitleArea();
+
+ var closeButton = getCloseButton();
+
+ var descList = Pool.data.getContent().split("\n");
+ var descArea = getDescArea(descList);
+
+ var moreInfo = getMoreInfo();
+
+ var buttonGroup = getButtonGroup();
+
+ return [title, closeButton, descArea, moreInfo, buttonGroup];
+}
+
+window.addEventListener("load", function (ev) {
+ var showItems = getShowItems();
+
+ var container = BI.createWidget({
+ type:"bi.vertical",
+ element: "body",
+ cls: "container",
+ items: showItems
+ });
+
+ container.element.css("background", "url(" + Pool.data.getBackgroundUrl() + ")");
+});
\ No newline at end of file
diff --git a/designer-base/src/main/resources/com/fr/design/upm/warn.js b/designer-base/src/main/resources/com/fr/design/upm/warn.js
new file mode 100644
index 0000000000..be4b069097
--- /dev/null
+++ b/designer-base/src/main/resources/com/fr/design/upm/warn.js
@@ -0,0 +1,61 @@
+window.onload = function () {
+ let label = BI.createWidget({
+ type: "bi.label",
+ text: PluginHelper.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Resource_Warn"),
+ height: 30
+ });
+ let callback = function(status, text) {
+ download.setValue(text);
+ };
+ let buttonOK = BI.createWidget({
+ type: "bi.button",
+ text: PluginHelper.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download"),
+ level: 'common',
+ height: 30,
+ handler: function () {
+ PluginHelper.startDownload(callback);
+ }
+ });
+ let buttonClose = BI.createWidget({
+ type: "bi.button",
+ text: PluginHelper.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Close"),
+ level: 'warning',
+ height: 30,
+ handler: function () {
+ PluginHelper.closeWindow();
+ }
+ });
+
+ let download = BI.createWidget({
+ type: "bi.label",
+ height: 30
+ });
+ let left = 300;
+ let top = 200;
+ BI.createWidget({
+ type: "bi.absolute",
+ element: "body",
+ items: [
+ {
+ el: label,
+ left: left,
+ top: top
+ },
+ {
+ el : buttonOK,
+ left : left,
+ top : top + 40
+ },
+ {
+ el : buttonClose,
+ left : left + 100,
+ top : top + 40
+ },
+ {
+ el : download,
+ left : left,
+ top : top + 80
+ }
+ ]
+ });
+};
\ No newline at end of file
diff --git a/designer-base/src/test/java/com/fr/design/mainframe/template/info/DesignerOpenHistoryTest.java b/designer-base/src/test/java/com/fr/design/mainframe/template/info/DesignerOpenHistoryTest.java
new file mode 100644
index 0000000000..3e95cfec77
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/mainframe/template/info/DesignerOpenHistoryTest.java
@@ -0,0 +1,120 @@
+package com.fr.design.mainframe.template.info;
+
+import com.fr.invoke.Reflect;
+import com.fr.stable.StringUtils;
+import com.fr.stable.xml.XMLPrintWriter;
+import com.fr.stable.xml.XMLableReader;
+import com.fr.third.javax.xml.stream.XMLStreamException;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+/**
+ * Created by plough on 2019/4/21.
+ */
+public class DesignerOpenHistoryTest {
+ private DesignerOpenHistory openHistory;
+ private String[] mockHistory = new String[] {
+ "2019-04-08", "2019-04-03", "2019-03-29"
+ };
+
+ @Before
+ public void setUp() {
+ openHistory = DesignerOpenHistory.getInstance();
+ Reflect.on(openHistory).set("history", mockHistory);
+ }
+
+ @Test
+ public void testReadAndWrite() throws XMLStreamException {
+ // 写入 xml
+ StringWriter sw = new StringWriter();
+ XMLPrintWriter writer = XMLPrintWriter.create(new PrintWriter(sw));
+ openHistory.writeXML(writer);
+ writer.flush();
+ writer.close();
+
+ String xmlText = sw.getBuffer().toString();
+
+ // 临时修改配置
+ Reflect.on(openHistory).set("history", new String[] {"", "", ""});
+
+ // 从 xml 中读取
+ StringReader sr = new StringReader(xmlText);
+ XMLableReader xmlReader = XMLableReader.createXMLableReader(sr);
+ xmlReader.readXMLObject(openHistory);
+
+ // 验证:与写入时的配置一致
+ assertArrayEquals(mockHistory, (String[])Reflect.on(openHistory).field("history").get());
+ }
+
+ @Test
+ public void testToString() {
+ assertEquals("2019-04-08,2019-04-03,2019-03-29", openHistory.toString());
+ }
+
+ @Test
+ public void testParseString() {
+ String[] mockDates = {"2020-04-08", "2019-04-03", "2016-03-29"};
+ Reflect.on(openHistory).call("parseString", StringUtils.join(",", mockDates));
+ assertArrayEquals(mockDates, (String[])Reflect.on(openHistory).field("history").get());
+ }
+
+ @Test
+ public void testGetHistorySpanDayCount() {
+ assertEquals(11, openHistory.getHistorySpanDayCount());
+
+ Reflect.on(openHistory).set("history", new String[] {"2019-05-03", "2019-05-02", ""});
+ assertEquals(2, openHistory.getHistorySpanDayCount());
+
+ Reflect.on(openHistory).set("history", new String[] {"2019-05-03", "", ""});
+ assertEquals(1, openHistory.getHistorySpanDayCount());
+
+ try {
+ Reflect.on(openHistory).set("history", new String[] {"", "", ""});
+ fail("should not be here");
+ } catch (AssertionError ignore) {
+ }
+ }
+
+ @Test
+ public void testOpenEnoughTimesInPeriod() {
+ assertTrue(openHistory.isOpenEnoughTimesInPeriod(15));
+ assertFalse(openHistory.isOpenEnoughTimesInPeriod(3));
+
+ Reflect.on(openHistory).set("history", new String[] {"2019-05-03", "2019-05-02", ""});
+ assertFalse(openHistory.isOpenEnoughTimesInPeriod(15));
+
+ Reflect.on(openHistory).set("history", new String[] {"2019-05-03", "", ""});
+ assertFalse(openHistory.isOpenEnoughTimesInPeriod(15));
+ }
+
+ @Test
+ public void testHasOpenedToday() {
+ assertFalse(openHistory.hasOpenedToday());
+
+ Reflect.on(openHistory).set("history", new String[] {getToday(), "2019-02-02", ""});
+ assertTrue(openHistory.hasOpenedToday());
+ }
+
+ @Test
+ public void testUpdate() {
+ openHistory.update();
+ String[] arr = { getToday(), "2019-04-08", "2019-04-03" };
+ assertArrayEquals(arr, (String[])Reflect.on(openHistory).field("history").get());
+ }
+
+ private String getToday() {
+ return new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime());
+ }
+}
diff --git a/designer-base/src/test/java/com/fr/design/mainframe/template/info/SendHelperTest.java b/designer-base/src/test/java/com/fr/design/mainframe/template/info/SendHelperTest.java
new file mode 100644
index 0000000000..fb89143d8d
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/mainframe/template/info/SendHelperTest.java
@@ -0,0 +1,35 @@
+package com.fr.design.mainframe.template.info;
+
+import com.fr.invoke.Reflect;
+import com.fr.stable.xml.XMLableReader;
+import com.fr.third.javax.xml.stream.XMLStreamException;
+
+import java.io.StringReader;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Created by plough on 2019/4/25.
+ */
+public class SendHelperTest {
+ private static final String CONSUMING_URL = "http://cloud.fanruan.com/api/monitor/record_of_reports_consuming/single";
+ private static final String PROCESS_URL = "http://cloud.fanruan.com/api/monitor/record_of_reports_process/single";
+
+ private static final String NORMAL_INFO = "\n" +
+ "\n" +
+ "\n" +
+ "";
+
+ // 只在调试的时候运行,不需要每次都自动运行
+ public static void main(String[] args) throws XMLStreamException {
+ StringReader sr = new StringReader(NORMAL_INFO);
+ XMLableReader xmlReader = XMLableReader.createXMLableReader(sr);
+ TemplateInfo templateInfo = TemplateInfo.newInstanceByRead(xmlReader);
+
+ boolean res = Reflect.on(SendHelper.class).call("sendSingleTemplateInfo", CONSUMING_URL, templateInfo.getConsumingMapJsonString()).get();
+ assertTrue(res);
+
+ boolean res2 = Reflect.on(SendHelper.class).call("sendSingleTemplateInfo", PROCESS_URL, templateInfo.getProcessMapJsonString()).get();
+ assertTrue(res2);
+ }
+}
diff --git a/designer-base/src/test/java/com/fr/design/mainframe/template/info/TemplateInfoCollectorTest.java b/designer-base/src/test/java/com/fr/design/mainframe/template/info/TemplateInfoCollectorTest.java
new file mode 100644
index 0000000000..e83a523fc4
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/mainframe/template/info/TemplateInfoCollectorTest.java
@@ -0,0 +1,195 @@
+package com.fr.design.mainframe.template.info;
+
+import com.fr.config.MarketConfig;
+import com.fr.general.GeneralUtils;
+import com.fr.invoke.Reflect;
+import com.fr.stable.ProductConstants;
+import com.fr.stable.StringUtils;
+import com.fr.third.org.apache.commons.io.FileUtils;
+import org.easymock.EasyMock;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+
+import static com.fr.design.mainframe.template.info.TemplateInfoTestHelper.assertJsonStringEquals;
+import static com.fr.design.mainframe.template.info.TemplateInfoTestHelper.setUpMockForNewInstance;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Created by plough on 2019/4/18.
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({ProductConstants.class, MarketConfig.class, ProductConstants.class, GeneralUtils.class})
+public class TemplateInfoCollectorTest {
+ private String filePath;
+ private String initialFileContent;
+ private TemplateProcessInfo mockProcessInfo;
+
+ @Before
+ public void setUp() throws IOException {
+ PowerMock.mockStatic(ProductConstants.class);
+
+ filePath = getClass().getResource("tpl.info").getPath();
+ String dirPath = filePath.substring(0, filePath.indexOf("tpl.info"));
+ EasyMock.expect(ProductConstants.getEnvHome()).andReturn(dirPath).anyTimes();
+ EasyMock.replay();
+ PowerMock.replayAll();
+
+ mockProcessInfo = EasyMock.mock(TemplateProcessInfo.class);
+ EasyMock.expect(mockProcessInfo.getBlockCount()).andReturn(3).anyTimes();
+ EasyMock.expect(mockProcessInfo.getCellCount()).andReturn(13).anyTimes();
+ EasyMock.expect(mockProcessInfo.getFloatCount()).andReturn(1).anyTimes();
+ EasyMock.expect(mockProcessInfo.getReportType()).andReturn(0).anyTimes();
+ EasyMock.expect(mockProcessInfo.getWidgetCount()).andReturn(0).anyTimes();
+ EasyMock.replay(mockProcessInfo);
+
+ // 缓存 tpl.info
+ initialFileContent = FileUtils.readFileToString(new File(filePath), "utf-8");
+
+ Reflect.on(TemplateInfoCollector.class).set("instance", null);
+ }
+
+ @After
+ public void tearDown() throws IOException {
+ // 恢复 tpl.info
+ FileUtils.writeStringToFile(new File(filePath), initialFileContent, "utf-8");
+ }
+
+ @Test
+ public void testReadXML() {
+ assertEquals(",,", DesignerOpenHistory.getInstance().toString());
+
+ TemplateInfoCollector collector = TemplateInfoCollector.getInstance();
+ assertEquals(7, ((Map) Reflect.on(collector).field("templateInfoMap").get()).size());
+
+ assertEquals("2019-04-08,2019-04-03,2019-03-29", DesignerOpenHistory.getInstance().toString());
+ }
+
+ @Test
+ public void testCollectInfo() {
+ TemplateInfoCollector collector = TemplateInfoCollector.getInstance();
+
+ String templateID = "16a988ce-8529-42f5-b17c-2ee849355071";
+ int timeConsume = 200;
+
+ collector.collectInfo(templateID, StringUtils.EMPTY, mockProcessInfo, timeConsume);
+
+ // 检查是否写入成功
+ collector.loadFromFile();
+ TemplateInfo templateInfo = collector.getOrCreateTemplateInfoByID(templateID);
+
+ assertJsonStringEquals("{\"process\":\"\",\"float_count\":1,\"widget_count\":0," +
+ "\"cell_count\":13,\"block_count\":3,\"report_type\":0," +
+ "\"templateID\":\"16a988ce-8529-42f5-b17c-2ee849355071\"}",templateInfo.getProcessMapJsonString());
+
+ assertJsonStringEquals("{\"activitykey\":\"2e0ea413-fa9c241e0-9723-4354fce51e81\"," +
+ "\"jar_time\":\"不是安装版本\",\"create_time\":\"2019-03-26 16:13\"," +
+ "\"templateID\":\"16a988ce-8529-42f5-b17c-2ee849355071\",\"originID\":\"\"," +
+ "\"uuid\":\"476ca2cc-f789-4c5d-8e89-ef146580775c\",\"time_consume\":329,\"originTime\":0," +
+ "\"version\":\"10.0\",\"username\":\"plough\"}", templateInfo.getConsumingMapJsonString());
+ }
+
+ @Test
+ public void testCollectInfoForNewTemplate() throws Exception {
+ setUpMockForNewInstance();
+
+ TemplateInfoCollector collector = TemplateInfoCollector.getInstance();
+
+ String templateID = "73a97777-8jnk-47cd-b57c-2ee89991279796";
+ int timeConsume = 200;
+
+ collector.collectInfo(templateID, StringUtils.EMPTY, mockProcessInfo, timeConsume);
+
+ // 检查是否写入成功
+ collector.loadFromFile();
+ assertTrue(collector.contains(templateID));
+
+ TemplateInfo templateInfo = collector.getOrCreateTemplateInfoByID(templateID);
+ assertEquals(templateID, templateInfo.getTemplateID());
+
+ assertJsonStringEquals("{\"process\":\"\",\"float_count\":1,\"widget_count\":0," +
+ "\"cell_count\":13,\"block_count\":3,\"report_type\":0," +
+ "\"templateID\":\"73a97777-8jnk-47cd-b57c-2ee89991279796\"}",templateInfo.getProcessMapJsonString());
+
+ Map consumingMap = Reflect.on(templateInfo).field("consumingMap").get();
+ assertEquals(templateID, consumingMap.get("templateID"));
+ assertEquals(StringUtils.EMPTY, consumingMap.get("originID"));
+ assertEquals(200, consumingMap.get("time_consume"));
+ assertEquals(0, consumingMap.get("originTime"));
+ }
+
+ @Test
+ public void testCollectInfoWhenSaveAs() throws Exception {
+ setUpMockForNewInstance();
+
+ TemplateInfoCollector collector = TemplateInfoCollector.getInstance();
+
+ String templateID = "423238d4-5223-22vj-vlsj-42jc49245iw3";
+ String originID = "16a988ce-8529-42f5-b17c-2ee849355071";
+ int timeConsume = 200;
+
+ collector.collectInfo(templateID, originID, mockProcessInfo, timeConsume);
+
+ // 检查是否写入成功
+ collector.loadFromFile();
+ TemplateInfo templateInfo = collector.getOrCreateTemplateInfoByID(templateID);
+
+ assertJsonStringEquals("{\"process\":\"\",\"float_count\":1,\"widget_count\":0," +
+ "\"cell_count\":13,\"block_count\":3,\"report_type\":0," +
+ "\"templateID\":\"423238d4-5223-22vj-vlsj-42jc49245iw3\"}", templateInfo.getProcessMapJsonString());
+
+ Map consumingMap = Reflect.on(templateInfo).field("consumingMap").get();
+ assertEquals(templateID, consumingMap.get("templateID"));
+ assertEquals(originID, consumingMap.get("originID"));
+ assertEquals(329, consumingMap.get("time_consume"));
+ assertEquals(129, consumingMap.get("originTime"));
+ }
+
+ @Test
+ public void testCollectInfoWhenSaveAsWithNoTrackOriginID() throws Exception {
+ setUpMockForNewInstance();
+
+ TemplateInfoCollector collector = TemplateInfoCollector.getInstance();
+
+ String templateID = "423238d4-5223-22vj-vlsj-42jc49245iw3";
+ String originID = "3kha8jcs-31xw-42f5-h2ww-2ee84935312z";
+ int timeConsume = 200;
+
+ collector.collectInfo(templateID, originID, mockProcessInfo, timeConsume);
+
+ TemplateInfo templateInfo = collector.getOrCreateTemplateInfoByID(templateID);
+ assertEquals(templateID, templateInfo.getTemplateID());
+ assertEquals(originID, templateInfo.getOriginID());
+
+ Map consumingMap = Reflect.on(templateInfo).field("consumingMap").get();
+ assertEquals(templateID, consumingMap.get("templateID"));
+ assertEquals(originID, consumingMap.get("originID"));
+ assertEquals(200, consumingMap.get("time_consume"));
+ assertEquals(0, consumingMap.get("originTime"));
+ }
+
+ @Test
+ public void testAddIdleDateCount() {
+ String templateID = "16a988ce-8529-42f5-b17c-2ee849355071";
+ TemplateInfoCollector collecter = TemplateInfoCollector.getInstance();
+ TemplateInfo templateInfo = collecter.getOrCreateTemplateInfoByID(templateID);
+
+ assertEquals(9, templateInfo.getIdleDayCount());
+
+ Reflect.on(collecter).call("addIdleDayCount");
+ assertEquals(10, templateInfo.getIdleDayCount());
+
+ // 同一天内多次调用无效
+ Reflect.on(collecter).call("addIdleDayCount");
+ assertEquals(10, templateInfo.getIdleDayCount());
+ }
+}
diff --git a/designer-base/src/test/java/com/fr/design/mainframe/template/info/TemplateInfoTest.java b/designer-base/src/test/java/com/fr/design/mainframe/template/info/TemplateInfoTest.java
new file mode 100644
index 0000000000..19f6066ff8
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/mainframe/template/info/TemplateInfoTest.java
@@ -0,0 +1,125 @@
+package com.fr.design.mainframe.template.info;
+
+import com.fr.config.MarketConfig;
+import com.fr.general.GeneralUtils;
+import com.fr.invoke.Reflect;
+import com.fr.stable.ProductConstants;
+import com.fr.stable.StringUtils;
+import com.fr.stable.xml.XMLableReader;
+import com.fr.third.javax.xml.stream.XMLStreamException;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import java.io.StringReader;
+import java.util.Map;
+
+import static com.fr.design.mainframe.template.info.TemplateInfoTestHelper.assertJsonStringEquals;
+import static com.fr.design.mainframe.template.info.TemplateInfoTestHelper.setUpMockForNewInstance;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Created by plough on 2019/4/19.
+ */
+@RunWith(PowerMockRunner.class)
+@PrepareForTest({MarketConfig.class, ProductConstants.class, GeneralUtils.class})
+public class TemplateInfoTest {
+
+ private static final String NORMAL_INFO = "\n" +
+ "\n" +
+ "\n" +
+ "";
+
+ private static final String SAVE_AS_INFO = "\n" +
+ "\n" +
+ "\n" +
+ "";
+
+ private TemplateInfo templateInfo;
+ private TemplateInfo templateInfoSaveAs; // 另存为的模版记录
+
+ @Before
+ public void setUp() throws XMLStreamException {
+ templateInfo = createTemplateInfo(NORMAL_INFO);
+ templateInfoSaveAs = createTemplateInfo(SAVE_AS_INFO);
+ }
+
+ @Test
+ public void testNewInstance() throws Exception {
+ setUpMockForNewInstance();
+
+ String templateID = "24avc8n2-1iq8-iuj2-wx24-8yy0i8132302";
+ TemplateInfo templateInfo = TemplateInfo.newInstance(templateID);
+ assertEquals(templateID, templateInfo.getTemplateID());
+ assertEquals(StringUtils.EMPTY, Reflect.on(templateInfo).field("originID").get());
+ assertEquals(0, Reflect.on(templateInfo).field("idleDayCount").get());
+ assertEquals("{}", templateInfo.getProcessMapJsonString());
+
+ Map consumingMap = Reflect.on(templateInfo).field("consumingMap").get();
+ assertEquals(templateID, consumingMap.get("templateID"));
+ assertEquals(0, consumingMap.get("originTime"));
+ assertEquals(StringUtils.EMPTY, consumingMap.get("originID"));
+ assertEquals(0, consumingMap.get("time_consume"));
+ assertEquals("不是安装版本", consumingMap.get("jar_time"));
+ assertEquals("plough", consumingMap.get("username"));
+ assertEquals("10.0", consumingMap.get("version"));
+ }
+
+ @Test
+ public void testNewInstanceWithMoreArgs() throws Exception {
+ setUpMockForNewInstance();
+
+ String templateID = "24121212-u2c8-ncd2-82nx-8ud0i8138888";
+ String originID = "24avc8n2-1iq8-iuj2-wx24-8yy0i8132302";
+ int originTime = 100;
+ TemplateInfo templateInfo = TemplateInfo.newInstance(templateID, originID, originTime);
+ assertEquals(templateID, templateInfo.getTemplateID());
+ assertEquals(originID, Reflect.on(templateInfo).field("originID").get());
+ assertEquals(0, Reflect.on(templateInfo).field("idleDayCount").get());
+ assertEquals("{}", templateInfo.getProcessMapJsonString());
+
+ Map consumingMap = Reflect.on(templateInfo).field("consumingMap").get();
+ assertEquals(templateID, consumingMap.get("templateID"));
+ assertEquals(originTime, consumingMap.get("originTime"));
+ assertEquals(originID, consumingMap.get("originID"));
+ assertEquals(originTime, consumingMap.get("time_consume"));
+ assertEquals("不是安装版本", consumingMap.get("jar_time"));
+ assertEquals("plough", consumingMap.get("username"));
+ assertEquals("10.0", consumingMap.get("version"));
+ }
+
+ @Test
+ public void testGetTemplateID() {
+ assertEquals("16a988ce-8529-42f5-b17c-2ee849355071", templateInfo.getTemplateID());
+ assertEquals("49avd2c4-1104-92j2-wx24-3dd0k2136080", templateInfoSaveAs.getTemplateID());
+ }
+
+ @Test
+ public void testGetConsumingMapJsonString() {
+ assertJsonStringEquals("{\"activitykey\":\"2e0ea413-fa9c241e0-9723-4354fce51e81\",\"jar_time\":\"不是安装版本\"," +
+ "\"create_time\":\"2019-03-26 16:13\",\"templateID\":\"16a988ce-8529-42f5-b17c-2ee849355071\",\"originID\":\"\"," +
+ "\"uuid\":\"476ca2cc-f789-4c5d-8e89-ef146580775c\",\"time_consume\":129,\"originTime\":0,\"version\":\"10.0\"," +
+ "\"username\":\"plough\"}", templateInfo.getConsumingMapJsonString());
+
+ assertJsonStringEquals("{\"activitykey\":\"2e0ea413-fa9c241e0-9723-4354fce51e81\",\"jar_time\":\"不是安装版本\"," +
+ "\"create_time\":\"2019-03-26 16:13\",\"templateID\":\"49avd2c4-1104-92j2-wx24-3dd0k2136080\",\"originID\":\"16a988ce-8529-42f5-b17c-2ee849355071\"," +
+ "\"uuid\":\"476ca2cc-f789-4c5d-8e89-ef146580775c\",\"time_consume\":429,\"originTime\":129,\"version\":\"10.0\"," +
+ "\"username\":\"plough\"}", templateInfoSaveAs.getConsumingMapJsonString());
+ }
+
+ @Test
+ public void testGetProcessMapJsonString() {
+ assertJsonStringEquals("{\"process\":\"\",\"float_count\":0,\"widget_count\":0,\"cell_count\":1," +
+ "\"block_count\":0,\"report_type\":0,\"templateID\":\"16a988ce-8529-42f5-b17c-2ee849355071\"}", templateInfo.getProcessMapJsonString());
+ assertJsonStringEquals("{\"process\":\"\",\"float_count\":0,\"widget_count\":0,\"cell_count\":1," +
+ "\"block_count\":0,\"report_type\":0,\"templateID\":\"49avd2c4-1104-92j2-wx24-3dd0k2136080\"}", templateInfoSaveAs.getProcessMapJsonString());
+ }
+
+ private TemplateInfo createTemplateInfo(String xmlContent) throws XMLStreamException {
+ StringReader sr = new StringReader(xmlContent);
+ XMLableReader xmlReader = XMLableReader.createXMLableReader(sr);
+ return TemplateInfo.newInstanceByRead(xmlReader);
+ }
+}
diff --git a/designer-base/src/test/java/com/fr/design/mainframe/template/info/TemplateInfoTestHelper.java b/designer-base/src/test/java/com/fr/design/mainframe/template/info/TemplateInfoTestHelper.java
new file mode 100644
index 0000000000..be2b589892
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/mainframe/template/info/TemplateInfoTestHelper.java
@@ -0,0 +1,49 @@
+package com.fr.design.mainframe.template.info;
+
+import com.fr.config.MarketConfig;
+import com.fr.general.ComparatorUtils;
+import com.fr.general.GeneralUtils;
+import com.fr.json.JSONObject;
+import com.fr.stable.ProductConstants;
+import org.easymock.EasyMock;
+import org.powermock.api.easymock.PowerMock;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Created by plough on 2019/4/19.
+ */
+class TemplateInfoTestHelper {
+ static void assertJsonStringEquals(String jo1, String jo2) {
+ // HashMap 是无序的,所以不能直接比较它生成的 json 字符串
+ assertTrue(ComparatorUtils.equals(new JSONObject(jo1), new JSONObject(jo2)));
+ }
+
+ private static void setFinalStatic(Field field, Object newValue) throws Exception {
+ field.setAccessible(true);
+ // remove final modifier from field
+ Field modifiersField = Field.class.getDeclaredField("modifiers");
+ modifiersField.setAccessible(true);
+ modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
+ field.set(null, newValue);
+ }
+
+ static void setUpMockForNewInstance() throws Exception {
+ MarketConfig mockMarketConfig = EasyMock.mock(MarketConfig.class);
+ EasyMock.expect(mockMarketConfig.getBbsUsername()).andReturn("plough").anyTimes();
+
+ PowerMock.mockStatic(MarketConfig.class);
+ EasyMock.expect(MarketConfig.getInstance()).andReturn(mockMarketConfig).anyTimes();
+
+ PowerMock.mockStatic(GeneralUtils.class);
+ EasyMock.expect(GeneralUtils.readBuildNO()).andReturn("不是安装版本").anyTimes();
+
+ setFinalStatic(ProductConstants.class.getDeclaredField("VERSION"), "10.0");
+
+ EasyMock.replay(mockMarketConfig);
+ PowerMock.replayAll();
+ }
+}
diff --git a/designer-base/src/test/java/com/fr/design/mainframe/template/info/TimeConsumeTimerTest.java b/designer-base/src/test/java/com/fr/design/mainframe/template/info/TimeConsumeTimerTest.java
new file mode 100644
index 0000000000..5dcf60e7f6
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/mainframe/template/info/TimeConsumeTimerTest.java
@@ -0,0 +1,62 @@
+package com.fr.design.mainframe.template.info;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Created by plough on 2019/4/19.
+ */
+public class TimeConsumeTimerTest {
+
+ @Test
+ public void testNotEnabled() throws InterruptedException {
+ TimeConsumeTimer consumeTimer = new TimeConsumeTimer();
+ consumeTimer.start();
+ Thread.sleep(1100);
+ consumeTimer.stop();
+ assertEquals(0, consumeTimer.popTime());
+ }
+
+ @Test
+ public void testEnabled() throws InterruptedException {
+ TimeConsumeTimer consumeTimer = new TimeConsumeTimer();
+ consumeTimer.setEnabled(true);
+ consumeTimer.start();
+ Thread.sleep(1100);
+ consumeTimer.stop();
+ assertEquals(1, consumeTimer.popTime());
+ assertEquals(0, consumeTimer.popTime());
+ }
+
+ @Test
+ public void testMultiTimes() throws InterruptedException {
+ TimeConsumeTimer consumeTimer = new TimeConsumeTimer();
+ consumeTimer.setEnabled(true);
+
+ consumeTimer.start();
+ Thread.sleep(1010);
+ consumeTimer.stop();
+
+ Thread.sleep(2000);
+
+ consumeTimer.start();
+ Thread.sleep(1010);
+ assertEquals(2, consumeTimer.popTime());
+ }
+
+ @Test
+ public void testStartMultiTime() throws InterruptedException {
+ TimeConsumeTimer consumeTimer = new TimeConsumeTimer();
+ consumeTimer.setEnabled(true);
+
+ consumeTimer.start();
+ Thread.sleep(1010);
+ consumeTimer.start();
+ Thread.sleep(1010);
+ consumeTimer.start();
+ Thread.sleep(1010);
+
+ assertEquals(3, consumeTimer.popTime());
+ }
+}
diff --git a/designer-base/src/test/java/com/fr/design/update/push/DesignerPushUpdateConfigManagerTest.java b/designer-base/src/test/java/com/fr/design/update/push/DesignerPushUpdateConfigManagerTest.java
new file mode 100644
index 0000000000..17831b0b74
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/update/push/DesignerPushUpdateConfigManagerTest.java
@@ -0,0 +1,72 @@
+package com.fr.design.update.push;
+
+import com.fr.stable.StringUtils;
+import com.fr.stable.xml.XMLPrintWriter;
+import com.fr.stable.xml.XMLableReader;
+import com.fr.third.javax.xml.stream.XMLStreamException;
+import org.junit.Test;
+
+import java.io.PrintWriter;
+import java.io.StringReader;
+import java.io.StringWriter;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
+
+
+/**
+ * Created by plough on 2019/4/8.
+ */
+public class DesignerPushUpdateConfigManagerTest {
+
+ @Test
+ public void testSingleton() {
+ DesignerPushUpdateConfigManager m1 = DesignerPushUpdateConfigManager.getInstance();
+ DesignerPushUpdateConfigManager m2 = DesignerPushUpdateConfigManager.getInstance();
+ assertSame(m1, m2);
+ }
+
+ @Test
+ public void testDefaultValue() throws XMLStreamException {
+ DesignerPushUpdateConfigManager configManager = DesignerPushUpdateConfigManager.getInstance();
+ XMLableReader xmlReader = XMLableReader.createXMLableReader(new StringReader(""));
+ xmlReader.readXMLObject(configManager);
+
+ assertEquals(StringUtils.EMPTY, configManager.getLastIgnoredVersion());
+ assertTrue(configManager.isAutoPushUpdateEnabled());
+ }
+
+ @Test
+ public void testReadAndWrite() throws XMLStreamException {
+ final String initLastIngnoredVersion = "1.1.2";
+ final boolean initAutoPushEnabled = false;
+
+ DesignerPushUpdateConfigManager configManager = DesignerPushUpdateConfigManager.getInstance();
+
+ configManager.setLastIgnoredVersion(initLastIngnoredVersion);
+ configManager.setAutoPushUpdateEnabled(initAutoPushEnabled);
+
+ // 写入 xml
+ StringWriter sw = new StringWriter();
+ XMLPrintWriter writer = XMLPrintWriter.create(new PrintWriter(sw));
+ configManager.writeXML(writer);
+ writer.flush();
+ writer.close();
+
+ String xml_str = sw.getBuffer().toString();
+
+ // 临时修改配置
+ configManager.setAutoPushUpdateEnabled(true);
+ configManager.setLastIgnoredVersion("0.20.1");
+
+ // 从 xml 中读取
+ StringReader sr = new StringReader(xml_str);
+ XMLableReader xmlReader = XMLableReader.createXMLableReader(sr);
+ xmlReader.readXMLObject(configManager);
+
+ // 验证:与写入时的配置一致
+ assertEquals(initLastIngnoredVersion, configManager.getLastIgnoredVersion());
+ assertEquals(initAutoPushEnabled, configManager.isAutoPushUpdateEnabled());
+ }
+}
diff --git a/designer-base/src/test/java/com/fr/design/update/push/DesignerPushUpdateDialogTest.java b/designer-base/src/test/java/com/fr/design/update/push/DesignerPushUpdateDialogTest.java
new file mode 100644
index 0000000000..bc194fe063
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/update/push/DesignerPushUpdateDialogTest.java
@@ -0,0 +1,23 @@
+package com.fr.design.update.push;
+
+import com.fr.design.DesignerEnvManager;
+import com.fr.json.JSONObject;
+
+/**
+ * Created by plough on 2019/4/10.
+ */
+public class DesignerPushUpdateDialogTest {
+
+ public static void main(String[] args) {
+ DesignerEnvManager.getEnvManager().setOpenDebug(true);
+
+ JSONObject jo = JSONObject.create();
+ jo.put("version", "2019.03.06.04.02.43.6");
+ jo.put("content", "设计器改进:去除右击弹框,让操作过程更流畅;增加报表块缩放功能,利于从全局角度整体设计报表\n插件重构:插件支持热部署,即装即用,不再需要重启服务器;\nsapbw:可用于bwcube和bwquery;\n私有云认证:可在客户本地部署私有云认证服务器,业务服务器可到此服务器进行认证;\n开放:打通简道云,可以在简道云里创建项目,并将数据同步到客户的私有库\nshould not display");
+ jo.put("more", "http://baidu.com");
+ jo.put("background", "http://updateten.finereport.com/fr.png");
+ DesignerUpdateInfo mockUpdateInfo = new DesignerUpdateInfo("111.22.11", "2211.231.1", "11.23.1", jo);
+
+ DesignerPushUpdateDialog.createAndShow(null, mockUpdateInfo);
+ }
+}
diff --git a/designer-base/src/test/java/com/fr/design/update/push/DesignerPushUpdateManagerTest.java b/designer-base/src/test/java/com/fr/design/update/push/DesignerPushUpdateManagerTest.java
new file mode 100644
index 0000000000..333580f1a6
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/update/push/DesignerPushUpdateManagerTest.java
@@ -0,0 +1,76 @@
+package com.fr.design.update.push;
+
+import com.fr.design.event.DesignerOpenedListener;
+import com.fr.design.mainframe.DesignerContext;
+import com.fr.design.mainframe.DesignerFrame;
+import com.fr.invoke.Reflect;
+import com.fr.stable.StringUtils;
+import org.easymock.EasyMock;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.powermock.api.easymock.PowerMock;
+import org.powermock.core.classloader.annotations.PrepareForTest;
+import org.powermock.modules.junit4.PowerMockRunner;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+
+/**
+ * Created by plough on 2019/4/8.
+ */
+@RunWith(value = PowerMockRunner.class)
+@PrepareForTest(DesignerContext.class)
+public class DesignerPushUpdateManagerTest {
+
+ @BeforeClass
+ public static void setUp() {
+ DesignerFrame mockFrame = EasyMock.mock(DesignerFrame.class);
+ mockFrame.addDesignerOpenedListener(EasyMock.anyObject(DesignerOpenedListener.class));
+ EasyMock.replay(mockFrame);
+
+ PowerMock.mockStatic(DesignerContext.class);
+ EasyMock.expect(DesignerContext.getDesignerFrame()).andReturn(mockFrame).anyTimes();
+ PowerMock.replayAll();
+ }
+
+ @Test
+ public void testSingleton() {
+ DesignerPushUpdateManager m1 = DesignerPushUpdateManager.getInstance();
+ DesignerPushUpdateManager m2 = DesignerPushUpdateManager.getInstance();
+ assertSame(m1, m2);
+ }
+
+ @Test
+ public void testIsAutoPushUpdateSupported() {
+ // 中文环境 + 本地设计 -> true
+ DesignerPushUpdateManager pushUpdateManager = DesignerPushUpdateManager.getInstance();
+ assertEquals(true, Reflect.on(pushUpdateManager).call("isAutoPushUpdateSupported", true, true).get());
+
+ // 非中文环境 || 远程设计 -> false
+ assertEquals(false, Reflect.on(pushUpdateManager).call("isAutoPushUpdateSupported", false, true).get());
+ assertEquals(false, Reflect.on(pushUpdateManager).call("isAutoPushUpdateSupported", true, false).get());
+ assertEquals(false, Reflect.on(pushUpdateManager).call("isAutoPushUpdateSupported", false, false).get());
+ }
+
+ @Test
+ public void testSkipCurrentPushVersion() {
+ DesignerPushUpdateManager pushUpdateManager = DesignerPushUpdateManager.getInstance();
+
+ // 1. updateInfo 为 null 的情况
+ pushUpdateManager.skipCurrentPushVersion();
+ assertEquals(StringUtils.EMPTY, DesignerPushUpdateConfigManager.getInstance().getLastIgnoredVersion());
+
+
+ // 2. updateInfo 有值的情况
+ final String PUSH_VERSION = "stable-2019.02.03.12.44.22";
+ DesignerUpdateInfo mockInfo = EasyMock.mock(DesignerUpdateInfo.class);
+ EasyMock.expect(mockInfo.getPushVersion()).andReturn(PUSH_VERSION).anyTimes();
+ Reflect.on(pushUpdateManager).set("updateInfo", mockInfo);
+ EasyMock.replay(mockInfo);
+
+ pushUpdateManager.skipCurrentPushVersion();
+ assertEquals(PUSH_VERSION, DesignerPushUpdateConfigManager.getInstance().getLastIgnoredVersion());
+ }
+
+}
diff --git a/designer-base/src/test/java/com/fr/design/update/push/DesignerUpdateInfoTest.java b/designer-base/src/test/java/com/fr/design/update/push/DesignerUpdateInfoTest.java
new file mode 100644
index 0000000000..14f986e8e5
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/update/push/DesignerUpdateInfoTest.java
@@ -0,0 +1,97 @@
+package com.fr.design.update.push;
+
+import com.fr.json.JSONObject;
+import com.fr.stable.StringUtils;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.security.InvalidParameterException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * Created by plough on 2019/4/9.
+ */
+public class DesignerUpdateInfoTest {
+ private static final String CURRENT_VERSION = "2018.09.03.xx";
+ private static final String LATEST_VERSION = "2019.04.03.yy";
+ private static final String LAST_IGNORED_VERSION = "2019.02.03.yy";
+ private static final String PUSH_VERSION = "2019.01.03.21.11";
+ private static final String PUSH_CONTENT = "the update desc content";
+ private static final String PUSH_BACKGROUND = "http://image.fr.com/123.jpg";
+ private static final String PUSH_MORE = "http://help.finereport.com/xxx";
+ private DesignerUpdateInfo updateInfo;
+
+ @Before
+ public void setUp() {
+ JSONObject pushData = JSONObject.create();
+
+ pushData.put("version", PUSH_VERSION);
+ pushData.put("content", PUSH_CONTENT);
+ pushData.put("background", PUSH_BACKGROUND);
+ pushData.put("more", PUSH_MORE);
+
+ updateInfo = new DesignerUpdateInfo(CURRENT_VERSION, LATEST_VERSION, LAST_IGNORED_VERSION, pushData);
+ }
+
+ @Test
+ public void testGetters() {
+ assertEquals(CURRENT_VERSION, updateInfo.getCurrentVersion());
+ assertEquals(LATEST_VERSION, updateInfo.getLatestVersion());
+ assertEquals(LAST_IGNORED_VERSION, updateInfo.getLastIgnoredVersion());
+ assertEquals(PUSH_VERSION, updateInfo.getPushVersion());
+ assertEquals(PUSH_CONTENT, updateInfo.getPushContent());
+ assertEquals(PUSH_BACKGROUND, updateInfo.getBackgroundUrl());
+ assertEquals(PUSH_MORE, updateInfo.getMoreInfoUrl());
+ }
+
+ @Test
+ public void testHasNewPushVersion() {
+ // (1)最近被跳过的维护版本号 X0;
+ // (2)本地版本号 Y;
+ // (3)最新的推送版本号 X;
+ // (4)最新的版本号 Z
+ // 必须满足:Y < X <= Z && X > X0,才返回 true
+
+ // 1 true
+ assertTrue(hasNewVersion("2019.01.03.xx", "2018.05.03.xx", "2019.04.03.yy", "2018.05.03.xx"));
+ assertTrue(hasNewVersion("2019.01.03.xx", "2018.05.03.xx", "2019.04.03.yy", null));
+ assertTrue(hasNewVersion("2019.01.03.xx", "2018.05.03.xx", "2019.04.03.yy", StringUtils.EMPTY));
+
+ // 2 false
+ // 2.1 X <= Y && X > X0
+ assertFalse(hasNewVersion("2019.01.03.xx", "2019.03.03.xx", "2019.04.03.yy", "2018.05.03.xx"));
+ assertFalse(hasNewVersion("2019.03.03.xx", "2019.03.03.xx", "2019.04.03.yy", "2018.05.03.xx"));
+
+ // 2.2 X > Z && X > X0
+ assertFalse(hasNewVersion("2020.01.03.xx", "2019.03.03.xx", "2019.04.03.yy", "2018.05.03.xx"));
+
+ // 2.3 Y < X <= Z && X <= X0
+ assertFalse(hasNewVersion("2019.01.03.xx", "2018.05.03.xx", "2019.04.03.yy", "2019.02.03.xx"));
+ assertFalse(hasNewVersion("2019.01.03.xx", "2018.05.03.xx", "2019.04.03.yy", "2019.01.03.xx"));
+ }
+
+
+ private boolean hasNewVersion(String X, String Y, String Z, String X0) {
+ JSONObject pushData = JSONObject.create();
+ pushData.put("version", X);
+ pushData.put("content", PUSH_CONTENT);
+ pushData.put("background", PUSH_BACKGROUND);
+ pushData.put("more", PUSH_MORE);
+ DesignerUpdateInfo updateInfo = new DesignerUpdateInfo(Y, Z, X0, pushData);
+ return updateInfo.hasNewPushVersion();
+ }
+
+ @Test
+ public void testParameterValidation() {
+ try {
+ DesignerUpdateInfo updateInfo = new DesignerUpdateInfo(null, null, null, new JSONObject());
+ Assert.fail("should not reach here!");
+ } catch (InvalidParameterException e) {
+ // do nothing
+ }
+ }
+}
diff --git a/designer-base/src/test/resources/com/fr/design/mainframe/template/info/tpl.info b/designer-base/src/test/resources/com/fr/design/mainframe/template/info/tpl.info
new file mode 100644
index 0000000000..eae77630fa
--- /dev/null
+++ b/designer-base/src/test/resources/com/fr/design/mainframe/template/info/tpl.info
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/designer-base/src/test/resources/com/fr/design/ui/demo.html b/designer-base/src/test/resources/com/fr/design/ui/demo.html
index 2beae25a78..9e5211c89e 100644
--- a/designer-base/src/test/resources/com/fr/design/ui/demo.html
+++ b/designer-base/src/test/resources/com/fr/design/ui/demo.html
@@ -10,6 +10,12 @@
return Pool.data;
};
+
测试页面,请点击最下面的按钮
diff --git a/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java b/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java
index 3a8abb56e5..1255d87d5a 100644
--- a/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java
+++ b/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java
@@ -41,6 +41,7 @@ import com.fr.design.module.DesignModuleFactory;
import com.fr.form.ui.ChartEditor;
import com.fr.general.GeneralContext;
import com.fr.general.IOUtils;
+import com.fr.locale.InterProviderFactory;
import com.fr.plugin.chart.PiePlot4VanChart;
import com.fr.plugin.chart.area.VanChartAreaPlot;
import com.fr.plugin.chart.bubble.VanChartBubblePlot;
@@ -99,7 +100,8 @@ import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
-import static com.fr.chart.charttypes.ChartTypeManager.CHART_PRIORITY;
+import static com.fr.chart.charttypes.ChartTypeManager.DEFAULT_PRIORITY;
+import static com.fr.chart.charttypes.ChartTypeManager.DEPRECATED_CHART_PRIORITY;
import static com.fr.chart.charttypes.ChartTypeManager.VAN_CHART_PRIORITY;
/**
@@ -165,7 +167,7 @@ public class ChartTypeInterfaceManager implements ExtraChartDesignClassManagerPr
}
String iconPath = ChartTypeInterfaceManager.getInstance().getIconPath(plotID);
Icon icon = IOUtils.readIcon(iconPath);
- child[index] = new ChartWidgetOption(com.fr.design.i18n.Toolkit.i18nText(bean.getName()), icon, ChartEditor.class, plotID);
+ child[index] = new ChartWidgetOption(InterProviderFactory.getProvider().getLocText(bean.getName()), icon, ChartEditor.class, plotID);
index++;
}
@@ -198,23 +200,23 @@ public class ChartTypeInterfaceManager implements ExtraChartDesignClassManagerPr
private static void readDefault() {
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.COLUMN_CHART, new ColumnIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.LINE_CHART, new LineIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.BAR_CHART, new BarIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.PIE_CHART, new PieIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.AREA_CHART, new AreaIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.SCATTER_CHART, new XYScatterIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.BUBBLE_CHART, new BubbleIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.RADAR_CHART, new RadarIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.STOCK_CHART, new StockIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.METER_CHART, new MeterIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.RANGE_CHART, new RangeIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.CUSTOM_CHART, new CustomIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.GANTT_CHART, new GanttIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.DONUT_CHART, new DonutIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.MAP_CHART, new MapIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.GIS_CHAER, new GisMapIndependentChartInterface());
- addChartTypeInterface(CHART_PRIORITY, ChartConstants.FUNNEL_CHART, new FunnelIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.COLUMN_CHART, new ColumnIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.LINE_CHART, new LineIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.BAR_CHART, new BarIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.PIE_CHART, new PieIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.AREA_CHART, new AreaIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.SCATTER_CHART, new XYScatterIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.BUBBLE_CHART, new BubbleIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.RADAR_CHART, new RadarIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.STOCK_CHART, new StockIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.METER_CHART, new MeterIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.RANGE_CHART, new RangeIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.CUSTOM_CHART, new CustomIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.GANTT_CHART, new GanttIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.DONUT_CHART, new DonutIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.MAP_CHART, new MapIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.GIS_CHAER, new GisMapIndependentChartInterface());
+ addChartTypeInterface(DEPRECATED_CHART_PRIORITY, ChartConstants.FUNNEL_CHART, new FunnelIndependentChartInterface());
}
private static void addChartTypeInterface(String priority, String plotID, IndependentChartUIProvider provider) {
@@ -462,7 +464,7 @@ public class ChartTypeInterfaceManager implements ExtraChartDesignClassManagerPr
public void mount(PluginSingleInjection injection) {
if (isIndependentChartUIProvider(injection)) {
- String priority = injection.getAttribute("priority", CHART_PRIORITY);
+ String priority = injection.getAttribute("priority", DEFAULT_PRIORITY);
String plotID = injection.getAttribute("plotID");
IndependentChartUIProvider instance = (IndependentChartUIProvider) injection.getObject();
addChartTypeInterface(priority, plotID, instance);
@@ -474,7 +476,7 @@ public class ChartTypeInterfaceManager implements ExtraChartDesignClassManagerPr
public void demount(PluginSingleInjection injection) {
if (isIndependentChartUIProvider(injection)) {
- String priority = injection.getAttribute("priority", CHART_PRIORITY);
+ String priority = injection.getAttribute("priority", DEFAULT_PRIORITY);
String plotID = injection.getAttribute("plotID");
removeChartTypeInterface(priority, plotID);
}
diff --git a/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java b/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java
index de7d08a2b0..d914a81e8b 100644
--- a/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java
+++ b/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java
@@ -16,6 +16,7 @@ import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.license.exception.RegistEditionException;
import com.fr.license.function.VT4FR;
+import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import javax.swing.BorderFactory;
@@ -67,7 +68,7 @@ public class ChartTypePane extends ChartCommonWizardPane {
mainTypeList = new JList(defaultListModel);
for (int i = 0; i < typeName.length; i++) {
- defaultListModel.insertElementAt(com.fr.design.i18n.Toolkit.i18nText(typeName[i].getName()), i);
+ defaultListModel.insertElementAt(InterProviderFactory.getProvider().getLocText(typeName[i].getName()), i);
}
mainTypeList.addListSelectionListener(listSelectionListener);
diff --git a/designer-chart/src/main/java/com/fr/design/chart/axis/MinMaxValuePane.java b/designer-chart/src/main/java/com/fr/design/chart/axis/MinMaxValuePane.java
index a84cfd693e..79323d73de 100644
--- a/designer-chart/src/main/java/com/fr/design/chart/axis/MinMaxValuePane.java
+++ b/designer-chart/src/main/java/com/fr/design/chart/axis/MinMaxValuePane.java
@@ -35,9 +35,9 @@ public class MinMaxValuePane extends JPanel {
minValueField = new UITextField(6);
maxCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Custom_Max_Value"));
maxValueField = new UITextField(6);
- isCustomMainUnitBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Custom_Main_Graduation_Unit"));
+ isCustomMainUnitBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Custom_Main_Type"));
mainUnitField = new UITextField(6);
- isCustomSecUnitBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Custom_Second_Graduation_Unit"));
+ isCustomSecUnitBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Custom_Second_Type"));
secUnitField = new UITextField(6);
double p = TableLayout.PREFERRED;
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/AreaPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/AreaPlotPane.java
index 42667ee9d9..425f508070 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/AreaPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/AreaPlotPane.java
@@ -8,6 +8,8 @@ import com.fr.chart.chartattr.Chart;
import com.fr.chart.chartattr.Plot;
import com.fr.chart.chartglyph.ConditionCollection;
import com.fr.chart.charttypes.AreaIndependentChart;
+import com.fr.design.i18n.Toolkit;
+import com.fr.locale.InterProviderFactory;
/**
@@ -33,10 +35,10 @@ public class AreaPlotPane extends AbstractChartTypePane{
@Override
protected String[] getTypeTipName() {
- String area = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Area");
- String stack = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Stacked");
- String percent = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Use_Percent");
- String td = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_3D");
+ String area = InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Area");
+ String stack = Toolkit.i18nText("Fine-Design_Chart_Stacked");
+ String percent = Toolkit.i18nText("Fine-Design_Chart_Use_Percent");
+ String td = Toolkit.i18nText("Fine-Design_Chart_3D");
return new String[]{
stack + area,
percent + stack + area,
@@ -139,7 +141,7 @@ public class AreaPlotPane extends AbstractChartTypePane{
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Area");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Area");
}
public Chart getDefaultChart() {
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/BarPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/BarPlotPane.java
index 280fca724c..cd5e1b4d66 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/BarPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/BarPlotPane.java
@@ -6,6 +6,8 @@ import com.fr.chart.chartattr.BarPlot;
import com.fr.chart.chartattr.Chart;
import com.fr.chart.chartattr.Plot;
import com.fr.chart.charttypes.BarIndependentChart;
+import com.fr.design.i18n.Toolkit;
+import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
@@ -31,16 +33,16 @@ public class BarPlotPane extends AbstractBarPane{
@Override
protected String[] getTypeTipName() {
- String bar = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Bar");
- String stack = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Stacked");
- String percent = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Use_Percent");
- String td = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_3D");
+ String bar = InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Bar");
+ String stack = Toolkit.i18nText("Fine-Design_Chart_Stacked");
+ String percent = Toolkit.i18nText("Fine-Design_Chart_Use_Percent");
+ String td = Toolkit.i18nText("Fine-Design_Chart_3D");
return new String[]{
bar,
stack + bar,
percent + stack + bar,
td + bar,
- td + bar + "(" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Direction_Horizontal") + ")",
+ td + bar + "(" + Toolkit.i18nText("Fine-Design_Chart_Direction_Horizontal") + ")",
td + stack + bar,
td + percent + stack + bar
};
@@ -65,8 +67,8 @@ public class BarPlotPane extends AbstractBarPane{
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Bar");
- }
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Bar");
+ }
protected Plot getSelectedClonedPlot(){
Chart[] barChart = BarIndependentChart.barChartTypes;
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/BubblePlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/BubblePlotPane.java
index 103dbd1940..b3e7cd34ae 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/BubblePlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/BubblePlotPane.java
@@ -4,6 +4,7 @@ import com.fr.chart.base.ChartConstants;
import com.fr.chart.chartattr.BubblePlot;
import com.fr.chart.chartattr.Chart;
import com.fr.chart.charttypes.BubbleIndependentChart;
+import com.fr.locale.InterProviderFactory;
/**
@@ -25,9 +26,9 @@ public class BubblePlotPane extends AbstractChartTypePane {
@Override
protected String[] getTypeTipName() {
return new String[]{
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Bubble_Chart")
+ InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Bubble_Chart")
};
- }
+ }
@Override
protected String[] getTypeLayoutPath() {
@@ -44,7 +45,7 @@ public class BubblePlotPane extends AbstractChartTypePane {
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Bubble_Chart");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Bubble_Chart");
}
/**
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/ColumnPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/ColumnPlotPane.java
index 5f290d5926..55de24714b 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/ColumnPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/ColumnPlotPane.java
@@ -5,6 +5,8 @@ import com.fr.chart.chartattr.BarPlot;
import com.fr.chart.chartattr.Chart;
import com.fr.chart.chartattr.Plot;
import com.fr.chart.charttypes.ColumnIndependentChart;
+import com.fr.design.i18n.Toolkit;
+import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
@@ -30,16 +32,16 @@ public class ColumnPlotPane extends AbstractBarPane{
@Override
protected String[] getTypeTipName() {
- String column = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Column");
- String stack = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Stacked");
- String percent = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Use_Percent");
- String td = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_3D");
+ String column = InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Column");
+ String stack = Toolkit.i18nText("Fine-Design_Chart_Stacked");
+ String percent = Toolkit.i18nText("Fine-Design_Chart_Use_Percent");
+ String td = Toolkit.i18nText("Fine-Design_Chart_3D");
return new String[]{
column,
stack + column,
percent + stack + column,
td + column,
- td + column + "(" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Direction_Horizontal") + ")",
+ td + column + "(" + Toolkit.i18nText("Fine-Design_Chart_Direction_Horizontal") + ")",
td + stack + column,
td + percent + stack + column
};
@@ -63,8 +65,8 @@ public class ColumnPlotPane extends AbstractBarPane{
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Column");
- }
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Column");
+ }
protected Plot getSelectedClonedPlot(){
Chart[] barChart = ColumnIndependentChart.columnChartTypes;
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/CustomPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/CustomPlotPane.java
index d6a46df458..8e367444f3 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/CustomPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/CustomPlotPane.java
@@ -3,6 +3,7 @@ package com.fr.design.mainframe.chart.gui.type;
import com.fr.chart.base.ChartConstants;
import com.fr.chart.chartattr.Chart;
import com.fr.chart.charttypes.CustomIndependentChart;
+import com.fr.locale.InterProviderFactory;
/**
@@ -26,9 +27,9 @@ public class CustomPlotPane extends AbstractChartTypePane {
@Override
protected String[] getTypeTipName() {
return new String[]{
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Combine_Chart")
+ InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Combine")
};
- }
+ }
@Override
protected String[] getTypeLayoutPath() {
@@ -45,7 +46,7 @@ public class CustomPlotPane extends AbstractChartTypePane {
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Combine_Chart");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Combine");
}
/**
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/DonutPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/DonutPlotPane.java
index e8643c34ff..c1cd47d78f 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/DonutPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/DonutPlotPane.java
@@ -10,10 +10,11 @@ import com.fr.chart.chartattr.Donut3DPlot;
import com.fr.chart.chartattr.Plot;
import com.fr.chart.chartglyph.ConditionCollection;
import com.fr.chart.charttypes.DonutIndependentChart;
-
+import com.fr.design.i18n.Toolkit;
+import com.fr.locale.InterProviderFactory;
import com.fr.stable.Constants;
-import java.awt.*;
+import java.awt.Color;
import java.text.DecimalFormat;
/**
@@ -35,10 +36,10 @@ public class DonutPlotPane extends AbstractChartTypePane{
@Override
protected String[] getTypeTipName() {
- String donut = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Donut_Chart");
+ String donut = InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Donut");
return new String[]{
donut,
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_3D") + donut
+ Toolkit.i18nText("Fine-Design_Chart_3D") + donut
};
}
@@ -103,8 +104,8 @@ public class DonutPlotPane extends AbstractChartTypePane{
* @return 标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Donut_Chart");
- }
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Donut");
+ }
/**
* 是否有坐标轴
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/FunnelPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/FunnelPlotPane.java
index 8f31c8c555..2de685cb82 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/FunnelPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/FunnelPlotPane.java
@@ -7,7 +7,7 @@ import com.fr.chart.chartattr.Chart;
import com.fr.chart.chartattr.FunnelPlot;
import com.fr.chart.chartattr.Plot;
import com.fr.chart.charttypes.FunnelIndependentChart;
-
+import com.fr.locale.InterProviderFactory;
import java.text.DecimalFormat;
@@ -31,7 +31,7 @@ public class FunnelPlotPane extends AbstractChartTypePane{
@Override
protected String[] getTypeTipName() {
return new String[]{
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Funnel")
+ InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Funnel")
};
}
@@ -50,7 +50,7 @@ public class FunnelPlotPane extends AbstractChartTypePane{
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Funnel");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Funnel");
}
/**
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/GanttPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/GanttPlotPane.java
index 537fa46289..b1845bfe4c 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/GanttPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/GanttPlotPane.java
@@ -3,6 +3,7 @@ package com.fr.design.mainframe.chart.gui.type;
import com.fr.chart.base.ChartConstants;
import com.fr.chart.chartattr.Chart;
import com.fr.chart.charttypes.GanttIndependentChart;
+import com.fr.locale.InterProviderFactory;
/**
@@ -24,9 +25,9 @@ public class GanttPlotPane extends AbstractChartTypePane{
@Override
protected String[] getTypeTipName() {
return new String[]{
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Gantt_Chart")
+ InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Gantt")
};
- }
+ }
@Override
protected String getPlotTypeID() {
@@ -47,7 +48,7 @@ public class GanttPlotPane extends AbstractChartTypePane{
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Gantt_Chart");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Gantt");
}
/**
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/GisMapPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/GisMapPlotPane.java
index 25d2fa48f2..9911ce4fbf 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/GisMapPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/GisMapPlotPane.java
@@ -11,11 +11,12 @@ import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
+import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
-
-import javax.swing.*;
-import java.awt.*;
+import javax.swing.JPanel;
+import java.awt.BorderLayout;
+import java.awt.Component;
public class GisMapPlotPane extends AbstractChartTypePane{
@@ -72,9 +73,9 @@ public class GisMapPlotPane extends AbstractChartTypePane{
@Override
protected String[] getTypeTipName() {
return new String[]{
- "gis"+com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Map_Map")
+ InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_GIS_Map")
};
- }
+ }
@Override
protected String getPlotTypeID() {
@@ -172,7 +173,7 @@ public class GisMapPlotPane extends AbstractChartTypePane{
* @return 标题
*/
public String title4PopupWindow() {
- return "gis"+com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Map_Map");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_GIS_Map");
}
/**
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/LinePlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/LinePlotPane.java
index 5afd3e2177..0f93938bb0 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/LinePlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/LinePlotPane.java
@@ -5,6 +5,7 @@ import com.fr.chart.chartattr.Chart;
import com.fr.chart.chartattr.LinePlot;
import com.fr.chart.chartattr.Plot;
import com.fr.chart.charttypes.LineIndependentChart;
+import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
@@ -21,9 +22,9 @@ public class LinePlotPane extends AbstractChartTypePane{
@Override
protected String[] getTypeTipName() {
return new String[]{
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Line_Chart")
+ InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Line")
};
- }
+ }
@Override
protected String[] getTypeLayoutPath() {
@@ -83,7 +84,7 @@ public class LinePlotPane extends AbstractChartTypePane{
}
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Line_Chart");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Line");
}
public Chart getDefaultChart() {
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/MapPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/MapPlotPane.java
index 6f9a55ab56..d761be3712 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/MapPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/MapPlotPane.java
@@ -10,6 +10,7 @@ import com.fr.chart.charttypes.MapIndependentChart;
import com.fr.design.chart.series.PlotSeries.MapGroupExtensionPane;
import com.fr.design.chart.series.PlotStyle.ChartSelectDemoPane;
import com.fr.design.layout.FRGUIPaneFactory;
+import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
import javax.swing.JPanel;
@@ -71,7 +72,7 @@ public class MapPlotPane extends AbstractChartTypePane {
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Map_Map");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_SVG_MAP");
}
/**
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/MeterPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/MeterPlotPane.java
index 811053641a..10293b68c7 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/MeterPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/MeterPlotPane.java
@@ -6,6 +6,8 @@ import com.fr.chart.chartattr.MeterPlot;
import com.fr.chart.chartattr.Plot;
import com.fr.chart.chartglyph.MeterStyle;
import com.fr.chart.charttypes.MeterIndependentChart;
+import com.fr.design.i18n.Toolkit;
+import com.fr.locale.InterProviderFactory;
import com.fr.log.FineLoggerFactory;
@@ -31,9 +33,9 @@ public class MeterPlotPane extends AbstractChartTypePane {
@Override
protected String[] getTypeTipName() {
- String meter = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Gauge");
+ String meter = InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Meter");
return new String[]{
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Mode_Custom") + meter,
+ Toolkit.i18nText("Fine-Design_Chart_Mode_Custom") + meter,
meter + "1",
meter + "2"
};
@@ -77,13 +79,13 @@ public class MeterPlotPane extends AbstractChartTypePane {
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Gauge");
- }
-
- /**
- * 保存界面属性
- */
- public void updateBean(Chart chart) {
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Meter");
+ }
+
+ /**
+ * 保存界面属性
+ */
+ public void updateBean(Chart chart) {
if(needsResetChart(chart)){
resetChart(chart);
}
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/PiePlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/PiePlotPane.java
index 98ccb0e533..eeccd2246e 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/PiePlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/PiePlotPane.java
@@ -10,10 +10,10 @@ import com.fr.chart.chartattr.PiePlot;
import com.fr.chart.chartattr.Plot;
import com.fr.chart.chartglyph.ConditionCollection;
import com.fr.chart.charttypes.PieIndependentChart;
-
+import com.fr.locale.InterProviderFactory;
import com.fr.stable.Constants;
-import java.awt.*;
+import java.awt.Color;
import java.text.DecimalFormat;
/**
@@ -36,11 +36,11 @@ public class PiePlotPane extends AbstractChartTypePane{
@Override
protected String[] getTypeTipName() {
- String pie = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Pie");
+ String pie = InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Pie");
return new String[]{
- pie,
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_3D") + pie
- };
+ pie,
+ com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_3D") + pie
+ };
}
@Override
@@ -63,7 +63,7 @@ public class PiePlotPane extends AbstractChartTypePane{
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_New_Pie");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Pie");
}
private void createPieCondition(Plot plot) {
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/RadarPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/RadarPlotPane.java
index 631a4d9d46..50e4a756eb 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/RadarPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/RadarPlotPane.java
@@ -3,6 +3,7 @@ package com.fr.design.mainframe.chart.gui.type;
import com.fr.chart.base.ChartConstants;
import com.fr.chart.chartattr.Chart;
import com.fr.chart.charttypes.RadarIndependentChart;
+import com.fr.locale.InterProviderFactory;
/**
@@ -24,9 +25,9 @@ public class RadarPlotPane extends AbstractChartTypePane{
@Override
protected String[] getTypeTipName() {
return new String[]{
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Radar_Chart")
+ InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Radar")
};
- }
+ }
@Override
protected String getPlotTypeID() {
@@ -48,7 +49,7 @@ public class RadarPlotPane extends AbstractChartTypePane{
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Radar_Chart");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Radar");
}
/**
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/RangePlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/RangePlotPane.java
index 405f9aa4fc..f87c6074d4 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/RangePlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/RangePlotPane.java
@@ -4,6 +4,7 @@ import com.fr.chart.base.ChartConstants;
import com.fr.chart.chartattr.Chart;
import com.fr.chart.chartattr.RangePlot;
import com.fr.chart.charttypes.RangeIndependentChart;
+import com.fr.locale.InterProviderFactory;
/**
@@ -25,9 +26,9 @@ public class RangePlotPane extends AbstractChartTypePane{
@Override
protected String[] getTypeTipName() {
return new String[]{
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Range_Chart")
+ InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Range")
};
- }
+ }
@Override
protected String getPlotTypeID() {
@@ -49,7 +50,7 @@ public class RangePlotPane extends AbstractChartTypePane{
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Range_Chart");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Range");
}
/**
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/StockPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/StockPlotPane.java
index 567595703c..63f4ead335 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/StockPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/StockPlotPane.java
@@ -3,6 +3,7 @@ package com.fr.design.mainframe.chart.gui.type;
import com.fr.chart.base.ChartConstants;
import com.fr.chart.chartattr.Chart;
import com.fr.chart.charttypes.StockIndependentChart;
+import com.fr.locale.InterProviderFactory;
/**
@@ -24,9 +25,9 @@ public class StockPlotPane extends AbstractChartTypePane {
@Override
protected String[] getTypeTipName() {
return new String[]{
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Stock_Chart")
+ InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Stock")
};
- }
+ }
@Override
protected String getPlotTypeID() {
@@ -48,7 +49,7 @@ public class StockPlotPane extends AbstractChartTypePane {
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Stock_Chart");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_Stock");
}
/**
diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/XYScatterPlotPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/XYScatterPlotPane.java
index 0effae28e1..46a5b13c07 100644
--- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/XYScatterPlotPane.java
+++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/type/XYScatterPlotPane.java
@@ -6,7 +6,7 @@ import com.fr.chart.chartattr.Chart;
import com.fr.chart.chartattr.XYScatterPlot;
import com.fr.chart.chartglyph.ConditionAttr;
import com.fr.chart.charttypes.XYScatterIndependentChart;
-
+import com.fr.locale.InterProviderFactory;
import com.fr.stable.Constants;
/**
@@ -28,9 +28,9 @@ public class XYScatterPlotPane extends AbstractChartTypePane{
@Override
protected String[] getTypeTipName() {
return new String[]{
- com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_I_XYScatterStyle_Marker")
+ InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_XYScatter")
};
- }
+ }
@Override
protected String[] getTypeLayoutPath() {
@@ -47,7 +47,7 @@ public class XYScatterPlotPane extends AbstractChartTypePane{
* @return 界面标题
*/
public String title4PopupWindow() {
- return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_I_XYScatterStyle_Marker");
+ return InterProviderFactory.getProvider().getLocText("Fine-Engine_Chart_Type_XYScatter");
}
/**
diff --git a/designer-chart/src/main/java/com/fr/extended/chart/ExtendedOtherPane.java b/designer-chart/src/main/java/com/fr/extended/chart/ExtendedOtherPane.java
index 31aa2d0033..6fba552b76 100644
--- a/designer-chart/src/main/java/com/fr/extended/chart/ExtendedOtherPane.java
+++ b/designer-chart/src/main/java/com/fr/extended/chart/ExtendedOtherPane.java
@@ -11,6 +11,7 @@ import com.fr.design.mainframe.chart.AbstractChartAttrPane;
import com.fr.design.mainframe.chart.PaneTitleConstants;
import com.fr.van.chart.designer.TableLayout4VanChartHelper;
+import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@@ -138,4 +139,10 @@ public class ExtendedOtherPane extends AbstractChartAtt
return PaneTitleConstants.CHART_OTHER_TITLE;
}
+ @Override
+ protected void initContentPane() {
+ leftContentPane = createContentPane();
+ leftContentPane.setBorder(BorderFactory.createMatteBorder(10, 3, 0, 10, original));
+ this.add(leftContentPane, BorderLayout.CENTER);
+ }
}
diff --git a/designer-chart/src/main/resources/com/fr/aspectj/designerchart/TemplateProcessTracker.aj b/designer-chart/src/main/resources/com/fr/aspectj/designerchart/TemplateProcessTracker.aj
index 89ed91033f..a2d2fb7b48 100644
--- a/designer-chart/src/main/resources/com/fr/aspectj/designerchart/TemplateProcessTracker.aj
+++ b/designer-chart/src/main/resources/com/fr/aspectj/designerchart/TemplateProcessTracker.aj
@@ -4,13 +4,10 @@ package com.fr.aspectj.designerchart;
* Created by plough on 2017/3/3.
*/
import com.fr.chart.chartattr.Chart;
-import com.fr.design.mainframe.templateinfo.TemplateInfoCollector;
import org.aspectj.lang.reflect.SourceLocation;
-import javax.swing.event.ListSelectionEvent;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
-import java.util.Date;
public aspect TemplateProcessTracker {
//声明一个pointcut,匹配你需要的方法
diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XTreeEditor.java b/designer-form/src/main/java/com/fr/design/designer/creator/XTreeEditor.java
index c5672b389f..bde83a176b 100644
--- a/designer-form/src/main/java/com/fr/design/designer/creator/XTreeEditor.java
+++ b/designer-form/src/main/java/com/fr/design/designer/creator/XTreeEditor.java
@@ -73,7 +73,7 @@ public class XTreeEditor extends XWidgetCreator {
crp = (CRPropertyDescriptor[]) ArrayUtils.add(crp, new CRPropertyDescriptor("ajax", this.data.getClass()).setI18NName(
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Load_By_Async")).putKeyValue(XCreatorConstants.PROPERTY_CATEGORY,
- "Advanced"));
+ "Fine-Design_Basic_Advanced"));
crp = this.addAllowEdit(crp);
crp = this.addCustomData(crp);
diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java
index c9b55b298f..8d3d75a358 100644
--- a/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java
+++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java
@@ -1,15 +1,5 @@
package com.fr.design.designer.creator;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.Rectangle;
-import java.awt.Toolkit;
-import java.awt.event.ContainerEvent;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.adapters.layout.FRFitLayoutAdapter;
import com.fr.design.designer.beans.location.Direction;
@@ -24,17 +14,25 @@ import com.fr.design.mainframe.WidgetPropertyPane;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.form.ui.PaddingMargin;
import com.fr.form.ui.Widget;
+import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
import com.fr.form.ui.container.WBodyLayoutType;
import com.fr.form.ui.container.WFitLayout;
import com.fr.form.ui.container.WLayout;
import com.fr.general.FRLogger;
import com.fr.general.FRScreen;
-import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
-
import com.fr.stable.ArrayUtils;
import edu.emory.mathcs.backport.java.util.Arrays;
import javax.swing.JOptionPane;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Rectangle;
+import java.awt.Toolkit;
+import java.awt.event.ContainerEvent;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
/**
diff --git a/designer-form/src/main/java/com/fr/design/designer/properties/mobile/BodyMobilePropertyUI.java b/designer-form/src/main/java/com/fr/design/designer/properties/mobile/BodyMobilePropertyUI.java
index 5175b30dce..401f7d2f2d 100644
--- a/designer-form/src/main/java/com/fr/design/designer/properties/mobile/BodyMobilePropertyUI.java
+++ b/designer-form/src/main/java/com/fr/design/designer/properties/mobile/BodyMobilePropertyUI.java
@@ -1,8 +1,7 @@
package com.fr.design.designer.properties.mobile;
import com.fr.design.designer.creator.XCreator;
-import com.fr.design.designer.creator.XWAbsoluteBodyLayout;
-import com.fr.design.designer.creator.XWFitLayout;
+import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.dialog.BasicPane;
import com.fr.design.fun.impl.AbstractWidgetPropertyUIProvider;
import com.fr.design.gui.itable.AbstractPropertyTable;
@@ -16,19 +15,19 @@ public class BodyMobilePropertyUI extends AbstractWidgetPropertyUIProvider {
private XCreator xCreator;
- public BodyMobilePropertyUI(XWFitLayout xwFitLayout) {
+ public BodyMobilePropertyUI(XLayoutContainer xwFitLayout) {
this.xCreator = xwFitLayout;
}
- public BodyMobilePropertyUI(XWAbsoluteBodyLayout xwAbsoluteBodyLayout) {
- this.xCreator = xwAbsoluteBodyLayout;
- }
-
@Override
public AbstractPropertyTable createWidgetAttrTable() {
return null;
}
+ public XCreator getxCreator() {
+ return xCreator;
+ }
+
@Override
public BasicPane createWidgetAttrPane() {
return new BodyMobileDefinePane(xCreator);
diff --git a/designer-form/src/main/java/com/fr/design/form/util/FormDesignerUtils.java b/designer-form/src/main/java/com/fr/design/form/util/FormDesignerUtils.java
new file mode 100644
index 0000000000..d976816f56
--- /dev/null
+++ b/designer-form/src/main/java/com/fr/design/form/util/FormDesignerUtils.java
@@ -0,0 +1,28 @@
+package com.fr.design.form.util;
+
+import com.fr.design.mainframe.FormDesigner;
+import com.fr.form.ui.container.WFitLayout;
+
+public class FormDesignerUtils {
+ /**
+ * body布局是否设置了手机重布局
+ *
+ * @param designer
+ * @return
+ */
+ public static boolean isAppRelayout(FormDesigner designer) {
+ return ((WFitLayout) designer.getRootComponent().toData()).isAppRelayout();
+ }
+
+ /**
+ * body布局是否设置了绝对布局
+ *
+ * @param designer
+ * @return
+ */
+ public static boolean isBodyAbsolute(FormDesigner designer) {
+ WFitLayout root = ((WFitLayout) designer.getRootComponent().toData());
+ return root.getBodyLayoutType() == com.fr.form.ui.container.WBodyLayoutType.ABSOLUTE;
+ }
+
+}
\ No newline at end of file
diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java b/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java
index 670c2fa489..090969d348 100644
--- a/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java
+++ b/designer-form/src/main/java/com/fr/design/mainframe/FormModelAdapter.java
@@ -78,6 +78,10 @@ public class FormModelAdapter extends DesignModelAdapter