diff --git a/docs/user-guide/workflow.md b/docs/user-guide/workflow.md
index 8b1378917..196b68afa 100644
--- a/docs/user-guide/workflow.md
+++ b/docs/user-guide/workflow.md
@@ -1 +1,23 @@
+# 工作流
+
+## 流程引擎后台变量
+
+* wfRt: IWorkflowRuntime类型
+* wf: IWorkflow类型
+* wfVars: IWorkflowVarSet类型,对应于`wf.getGlobalVars()`
+
+## 参数
+arg定义具有persist属性,如果设置为true,则会保存到wfVars集合中,存储到`nop_wf_var`表中。
+
+## 条件判断
+
+```xml
+
+
+
+
+```
+
+条件判断中值如果不是字符串类型,则可以用表达式语法或者前缀引导语法来标识数值类型。
+
diff --git a/nop-wf/model/nop-wf.orm.xlsx b/nop-wf/model/nop-wf.orm.xlsx
index df0f44c0a..c66c9490f 100644
Binary files a/nop-wf/model/nop-wf.orm.xlsx and b/nop-wf/model/nop-wf.orm.xlsx differ
diff --git a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/IWorkflowVarSet.java b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/IWorkflowVarSet.java
index f1037cd02..905d6b451 100644
--- a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/IWorkflowVarSet.java
+++ b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/IWorkflowVarSet.java
@@ -7,15 +7,29 @@
*/
package io.nop.wf.core;
+import io.nop.core.reflect.hook.IPropGetMissingHook;
+
import java.util.Map;
import java.util.Set;
/**
* 每个工作流实例都对应一个全局变量集合
*/
-public interface IWorkflowVarSet {
+public interface IWorkflowVarSet extends IPropGetMissingHook {
+ @Override
+ default Object prop_get(String propName) {
+ return getVar(propName);
+ }
+
+ @Override
+ default boolean prop_has(String propName) {
+ return containsVar(propName);
+ }
+
Set getVarNames();
+ boolean containsVar(String varName);
+
Object getVar(String varName);
void removeVar(String varName);
diff --git a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/NopWfCoreConstants.java b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/NopWfCoreConstants.java
index 7cba43651..e7a65b969 100644
--- a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/NopWfCoreConstants.java
+++ b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/NopWfCoreConstants.java
@@ -32,6 +32,7 @@ public interface NopWfCoreConstants extends _NopWfCoreConstants {
String VAR_WF = "wf";
String VAR_WF_RT = "wfRt";
+ String VAR_WF_VARS = "wfVars";
String VAR_WF_STEP = "wfStep";
String VAR_ACTOR_MODEL = "actorModel";
String VAR_SELECTED_ACTORS = "selectedActors";
diff --git a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WfRuntime.java b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WfRuntime.java
index dde62d895..ae00aae10 100644
--- a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WfRuntime.java
+++ b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WfRuntime.java
@@ -87,6 +87,7 @@ private IEvalScope newEvalScope() {
IEvalScope scope = serviceContext.getEvalScope().newChildScope();
scope.setLocalValue(null, NopWfCoreConstants.VAR_WF, wf);
scope.setLocalValue(null, NopWfCoreConstants.VAR_WF_RT, this);
+ scope.setLocalValue(null, NopWfCoreConstants.VAR_WF_VARS, wf.getGlobalVars());
return scope;
}
diff --git a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WorkflowEngineImpl.java b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WorkflowEngineImpl.java
index 0620e8536..711e55bd5 100644
--- a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WorkflowEngineImpl.java
+++ b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/engine/WorkflowEngineImpl.java
@@ -544,6 +544,9 @@ private void initArgs(IWorkflowArgumentsModel argsModel, Map arg
throw wfRt.newError(ERR_WF_EMPTY_ACTION_ARG)
.param(ARG_ACTION_NAME, actionName).param(ARG_ARG_NAME, name);
}
+ if (argModel.isPersist()) {
+ wf.getGlobalVars().setVar(name, args.get(name));
+ }
}
}
diff --git a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfArgVarModel.java b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfArgVarModel.java
index 9ed293d33..8e93ce862 100644
--- a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfArgVarModel.java
+++ b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfArgVarModel.java
@@ -44,6 +44,13 @@ public abstract class _WfArgVarModel extends io.nop.core.resource.component.Abst
*/
private java.lang.String _name ;
+ /**
+ *
+ * xml name: persist
+ *
+ */
+ private boolean _persist = false;
+
/**
*
* xml name: schema
@@ -52,6 +59,13 @@ public abstract class _WfArgVarModel extends io.nop.core.resource.component.Abst
*/
private io.nop.xlang.xmeta.ISchema _schema ;
+ /**
+ *
+ * xml name: type
+ *
+ */
+ private io.nop.core.type.IGenericType _type ;
+
/**
*
* xml name: description
@@ -128,6 +142,25 @@ public void setName(java.lang.String value){
}
+ /**
+ *
+ * xml name: persist
+ *
+ */
+
+ public boolean isPersist(){
+ return _persist;
+ }
+
+
+ public void setPersist(boolean value){
+ checkAllowChange();
+
+ this._persist = value;
+
+ }
+
+
/**
*
* xml name: schema
@@ -148,6 +181,25 @@ public void setSchema(io.nop.xlang.xmeta.ISchema value){
}
+ /**
+ *
+ * xml name: type
+ *
+ */
+
+ public io.nop.core.type.IGenericType getType(){
+ return _type;
+ }
+
+
+ public void setType(io.nop.core.type.IGenericType value){
+ checkAllowChange();
+
+ this._type = value;
+
+ }
+
+
@Override
public void freeze(boolean cascade){
@@ -169,7 +221,9 @@ protected void outputJson(IJsonHandler out){
out.putNotNull("displayName",this.getDisplayName());
out.putNotNull("mandatory",this.isMandatory());
out.putNotNull("name",this.getName());
+ out.putNotNull("persist",this.isPersist());
out.putNotNull("schema",this.getSchema());
+ out.putNotNull("type",this.getType());
}
public WfArgVarModel cloneInstance(){
@@ -185,7 +239,9 @@ protected void copyTo(WfArgVarModel instance){
instance.setDisplayName(this.getDisplayName());
instance.setMandatory(this.isMandatory());
instance.setName(this.getName());
+ instance.setPersist(this.isPersist());
instance.setSchema(this.getSchema());
+ instance.setType(this.getType());
}
protected WfArgVarModel newInstance(){
diff --git a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfAssignmentActorModel.java b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfAssignmentActorModel.java
index c7a5bcfba..6e3587e73 100644
--- a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfAssignmentActorModel.java
+++ b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/model/_gen/_WfAssignmentActorModel.java
@@ -16,13 +16,6 @@
"PMD.UnnecessaryFullyQualifiedName","PMD.EmptyControlStatement","java:S116","java:S101","java:S1128","java:S1161"})
public abstract class _WfAssignmentActorModel extends io.nop.core.resource.component.AbstractComponentModel {
- /**
- *
- * xml name: actionName
- *
- */
- private java.lang.String _actionName ;
-
/**
*
* xml name: actorId
@@ -37,6 +30,13 @@ public abstract class _WfAssignmentActorModel extends io.nop.core.resource.compo
*/
private java.lang.String _actorModelId ;
+ /**
+ *
+ * xml name: actorName
+ *
+ */
+ private java.lang.String _actorName ;
+
/**
*
* xml name: actorType
@@ -74,57 +74,57 @@ public abstract class _WfAssignmentActorModel extends io.nop.core.resource.compo
/**
*
- * xml name: actionName
+ * xml name: actorId
*
*/
- public java.lang.String getActionName(){
- return _actionName;
+ public java.lang.String getActorId(){
+ return _actorId;
}
- public void setActionName(java.lang.String value){
+ public void setActorId(java.lang.String value){
checkAllowChange();
- this._actionName = value;
+ this._actorId = value;
}
/**
*
- * xml name: actorId
- *
+ * xml name: actorModelId
+ * actor节点的唯一标识
*/
- public java.lang.String getActorId(){
- return _actorId;
+ public java.lang.String getActorModelId(){
+ return _actorModelId;
}
- public void setActorId(java.lang.String value){
+ public void setActorModelId(java.lang.String value){
checkAllowChange();
- this._actorId = value;
+ this._actorModelId = value;
}
/**
*
- * xml name: actorModelId
- * actor节点的唯一标识
+ * xml name: actorName
+ *
*/
- public java.lang.String getActorModelId(){
- return _actorModelId;
+ public java.lang.String getActorName(){
+ return _actorName;
}
- public void setActorModelId(java.lang.String value){
+ public void setActorName(java.lang.String value){
checkAllowChange();
- this._actorModelId = value;
+ this._actorName = value;
}
@@ -239,9 +239,9 @@ public void freeze(boolean cascade){
protected void outputJson(IJsonHandler out){
super.outputJson(out);
- out.putNotNull("actionName",this.getActionName());
out.putNotNull("actorId",this.getActorId());
out.putNotNull("actorModelId",this.getActorModelId());
+ out.putNotNull("actorName",this.getActorName());
out.putNotNull("actorType",this.getActorType());
out.putNotNull("assignForUser",this.isAssignForUser());
out.putNotNull("deptId",this.getDeptId());
@@ -258,9 +258,9 @@ public WfAssignmentActorModel cloneInstance(){
protected void copyTo(WfAssignmentActorModel instance){
super.copyTo(instance);
- instance.setActionName(this.getActionName());
instance.setActorId(this.getActorId());
instance.setActorModelId(this.getActorModelId());
+ instance.setActorName(this.getActorName());
instance.setActorType(this.getActorType());
instance.setAssignForUser(this.isAssignForUser());
instance.setDeptId(this.getDeptId());
diff --git a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/store/beans/MapVarSet.java b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/store/beans/MapVarSet.java
index 70b217567..6b32a3996 100644
--- a/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/store/beans/MapVarSet.java
+++ b/nop-wf/nop-wf-core/src/main/java/io/nop/wf/core/store/beans/MapVarSet.java
@@ -45,4 +45,9 @@ public void setVars(Map vars) {
if (vars != null)
this.vars.putAll(vars);
}
+
+ @Override
+ public boolean containsVar(String varName) {
+ return vars.containsKey(varName);
+ }
}
diff --git a/nop-wf/nop-wf-dao/src/main/java/io/nop/wf/dao/entity/_gen/_NopWfInstance.java b/nop-wf/nop-wf-dao/src/main/java/io/nop/wf/dao/entity/_gen/_NopWfInstance.java
index 4abd2d7d0..ff68aa683 100644
--- a/nop-wf/nop-wf-dao/src/main/java/io/nop/wf/dao/entity/_gen/_NopWfInstance.java
+++ b/nop-wf/nop-wf-dao/src/main/java/io/nop/wf/dao/entity/_gen/_NopWfInstance.java
@@ -2118,7 +2118,7 @@ public IOrmEntitySet getOutputs(){
}
private final OrmEntitySet _globalVars = new OrmEntitySet<>(this, PROP_NAME_globalVars,
- io.nop.wf.dao.entity.NopWfVar.PROP_NAME_wfInstance, null,io.nop.wf.dao.entity.NopWfVar.class);
+ io.nop.wf.dao.entity.NopWfVar.PROP_NAME_wfInstance, io.nop.wf.dao.entity.NopWfVar.PROP_NAME_fieldName,io.nop.wf.dao.entity.NopWfVar.class);
/**
* 。 refPropName: wfInstance, keyProp: {rel.keyProp}
diff --git a/nop-wf/nop-wf-dao/src/main/java/io/nop/wf/dao/store/KvTableVarSet.java b/nop-wf/nop-wf-dao/src/main/java/io/nop/wf/dao/store/KvTableVarSet.java
index c87498ae8..f6d39211a 100644
--- a/nop-wf/nop-wf-dao/src/main/java/io/nop/wf/dao/store/KvTableVarSet.java
+++ b/nop-wf/nop-wf-dao/src/main/java/io/nop/wf/dao/store/KvTableVarSet.java
@@ -41,6 +41,11 @@ public void removeVar(String varName) {
}
}
+ @Override
+ public boolean containsVar(String varName) {
+ return set.prop_has(varName);
+ }
+
@Override
public void setVar(String varName, Object value) {
IOrmKeyValueTable item = (IOrmKeyValueTable) set.prop_make(varName);
diff --git a/nop-wf/nop-wf-dao/src/main/resources/_vfs/nop/wf/orm/_app.orm.xml b/nop-wf/nop-wf-dao/src/main/resources/_vfs/nop/wf/orm/_app.orm.xml
index bd5fecf15..11d09d788 100644
--- a/nop-wf/nop-wf-dao/src/main/resources/_vfs/nop/wf/orm/_app.orm.xml
+++ b/nop-wf/nop-wf-dao/src/main/resources/_vfs/nop/wf/orm/_app.orm.xml
@@ -298,8 +298,9 @@
-
+
@@ -706,7 +707,7 @@
-
+
diff --git a/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/flowlong/counter-sign/v1.xwf b/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/flowlong/counter-sign/v1.xwf
index 5570cc11b..d41bb65da 100644
--- a/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/flowlong/counter-sign/v1.xwf
+++ b/nop-wf/nop-wf-service/src/test/resources/_vfs/nop/wf/flowlong/counter-sign/v1.xwf
@@ -1,8 +1,8 @@
-
-
+
+
@@ -10,7 +10,7 @@
-
+
diff --git a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfAction/_gen/_NopWfAction.view.xml b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfAction/_gen/_NopWfAction.view.xml
index ccdd60191..6512247c9 100644
--- a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfAction/_gen/_NopWfAction.view.xml
+++ b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfAction/_gen/_NopWfAction.view.xml
@@ -86,18 +86,17 @@
errCode[错误码] errMsg[错误消息]
-
-
-
+
+
+
+
+
+
@@ -134,7 +133,7 @@
-
+
diff --git a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfDefinition/_gen/_NopWfDefinition.view.xml b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfDefinition/_gen/_NopWfDefinition.view.xml
index 1e6d27972..38cd8c351 100644
--- a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfDefinition/_gen/_NopWfDefinition.view.xml
+++ b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfDefinition/_gen/_NopWfDefinition.view.xml
@@ -96,19 +96,18 @@
remark[备注]
-
-
+
+
+ i18n-en:title="Update Worflow Definition"/>
+
+
+
@@ -145,7 +144,7 @@
-
+
diff --git a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfDefinitionAuth/_gen/_NopWfDefinitionAuth.view.xml b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfDefinitionAuth/_gen/_NopWfDefinitionAuth.view.xml
index 3ed1ec13a..96cf02f33 100644
--- a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfDefinitionAuth/_gen/_NopWfDefinitionAuth.view.xml
+++ b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfDefinitionAuth/_gen/_NopWfDefinitionAuth.view.xml
@@ -97,19 +97,18 @@
remark[备注]
-
-
+
+
+ i18n-en:title="Update Workflow Definition Auth"/>
+
+
+
@@ -146,7 +145,7 @@
-
+
diff --git a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfInstance/_gen/_NopWfInstance.view.xml b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfInstance/_gen/_NopWfInstance.view.xml
index c8901f16b..9e874eca2 100644
--- a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfInstance/_gen/_NopWfInstance.view.xml
+++ b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfInstance/_gen/_NopWfInstance.view.xml
@@ -171,19 +171,18 @@
remark[备注]
-
-
+
+
+ i18n-en:title="Update Worflow Instance"/>
+
+
+
@@ -220,7 +219,7 @@
-
+
diff --git a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfLog/_gen/_NopWfLog.view.xml b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfLog/_gen/_NopWfLog.view.xml
index 225899104..68a41dc44 100644
--- a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfLog/_gen/_NopWfLog.view.xml
+++ b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfLog/_gen/_NopWfLog.view.xml
@@ -59,15 +59,16 @@
createTime[创建时间]
-
-
+
+
+
+
+
@@ -101,7 +102,7 @@
-
+
diff --git a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfOutput/_gen/_NopWfOutput.view.xml b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfOutput/_gen/_NopWfOutput.view.xml
index b74bceb63..9de06c951 100644
--- a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfOutput/_gen/_NopWfOutput.view.xml
+++ b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfOutput/_gen/_NopWfOutput.view.xml
@@ -82,19 +82,18 @@
timestampValue[时间点值]
-
-
+
+
+ i18n-en:title="Update Workflow Outputs"/>
+
+
+
@@ -131,7 +130,7 @@
-
+
diff --git a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfStatusHistory/_gen/_NopWfStatusHistory.view.xml b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfStatusHistory/_gen/_NopWfStatusHistory.view.xml
index 9cca745ca..5054a5594 100644
--- a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfStatusHistory/_gen/_NopWfStatusHistory.view.xml
+++ b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfStatusHistory/_gen/_NopWfStatusHistory.view.xml
@@ -76,19 +76,18 @@
operatorDeptId[操作者部门ID]
-
-
+
+
+ i18n-en:title="Update Workflow Status History"/>
+
+
+
@@ -125,7 +124,7 @@
-
+
diff --git a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfStepInstance/_gen/_NopWfStepInstance.view.xml b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfStepInstance/_gen/_NopWfStepInstance.view.xml
index 9629f2ecd..88e663645 100644
--- a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfStepInstance/_gen/_NopWfStepInstance.view.xml
+++ b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfStepInstance/_gen/_NopWfStepInstance.view.xml
@@ -160,19 +160,18 @@
remark[备注]
-
-
+
+
+ i18n-en:title="Update Workflow Step Instance"/>
+
+
+
@@ -209,7 +208,7 @@
-
+
diff --git a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfVar/_gen/_NopWfVar.view.xml b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfVar/_gen/_NopWfVar.view.xml
index 33e023d34..557eb24a4 100644
--- a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfVar/_gen/_NopWfVar.view.xml
+++ b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfVar/_gen/_NopWfVar.view.xml
@@ -82,19 +82,18 @@
timestampValue[时间点值]
-
-
+
+
+ i18n-en:title="Update Workflow Variables"/>
+
+
+
@@ -131,7 +130,7 @@
-
+
diff --git a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfWork/_gen/_NopWfWork.view.xml b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfWork/_gen/_NopWfWork.view.xml
index df2b3655b..ad74d946f 100644
--- a/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfWork/_gen/_NopWfWork.view.xml
+++ b/nop-wf/nop-wf-web/src/main/resources/_vfs/nop/wf/pages/NopWfWork/_gen/_NopWfWork.view.xml
@@ -99,18 +99,17 @@
remark[备注]
-
-
-
+
+
+
+
+
+
@@ -147,7 +146,7 @@
-
+
diff --git a/nop-xdefs/src/main/resources/_vfs/nop/schema/wf/wf.xdef b/nop-xdefs/src/main/resources/_vfs/nop/schema/wf/wf.xdef
index 9432ddf5f..2f6ff311a 100644
--- a/nop-xdefs/src/main/resources/_vfs/nop/schema/wf/wf.xdef
+++ b/nop-xdefs/src/main/resources/_vfs/nop/schema/wf/wf.xdef
@@ -22,7 +22,7 @@
+ displayName="string" xdef:unique-attr="name" persist="!boolean=false">
diff --git a/nop-xlang/src/main/java/io/nop/xlang/xpl/tags/FilterBeanExpressionCompiler.java b/nop-xlang/src/main/java/io/nop/xlang/xpl/tags/FilterBeanExpressionCompiler.java
index af0f68e84..7c2d1e3b5 100644
--- a/nop-xlang/src/main/java/io/nop/xlang/xpl/tags/FilterBeanExpressionCompiler.java
+++ b/nop-xlang/src/main/java/io/nop/xlang/xpl/tags/FilterBeanExpressionCompiler.java
@@ -136,7 +136,7 @@ protected Expression compileValueExpr(SourceLocation loc, Object value) {
Object jsonValue = JsonTool.parseNonStrict(loc, str.substring(2).trim());
return Literal.valueOf(loc, jsonValue);
}
- if (str.indexOf("${") > 0)
+ if (str.contains("${"))
return compiler.parseTemplateExpr(loc, str, false, ExprPhase.eval, compileScope);
return Literal.valueOf(loc, value);
} else {