Browse Source

基础框架发布: 8.2.43

1. 决策引擎增加输入选项的“是否作为下拉框展示”,“是否显示选项”,“不录项默认值”等属性
main
wangshaoping 3 weeks ago
parent
commit
eede2ab52a
  1. 6
      app.platform/src/main/webapp/WEB-INF/web.xml
  2. 2
      erm.frontend/src/views/kpi/Lib.vue
  3. 2
      erm.frontend/src/views/kpi/SelectIndicatorDialog.vue
  4. 14
      erm/src/main/resources/META-INF/platform/plugins/liquibase.json
  5. 0
      erm/src/main/resources/liquibase/appetite/erm.appetite_1.0.0_20221020__ERM_Appetite_Database_Data.xml
  6. 0
      erm/src/main/resources/liquibase/appetite/erm.appetite_1.0.0_20221020__ERM_Appetite_Database_Schema_DDL.xml
  7. 0
      erm/src/main/resources/liquibase/capitalplan/erm.capitalpan_1.0.0_20221020__ERM_Capital_Plan_Database_Data.xml
  8. 0
      erm/src/main/resources/liquibase/capitalplan/erm.capitalpan_1.0.0_20221020__ERM_Capital_Plan_Schema_DDL.xml
  9. 0
      erm/src/main/resources/liquibase/economiccapital/erm.capitalpan_1.0.0_20221020__ERM_Economic_Capital_Schema_DDL.xml
  10. 0
      erm/src/main/resources/liquibase/kpi/erm.kpi_1.0.0_20221020__ERM_KPI_Database_Data.xml
  11. 0
      erm/src/main/resources/liquibase/kpi/erm.kpi_1.0.0_20221020__ERM_KPI_Database_Schema_DDL.xml
  12. 32
      io.sc.engine.rule.client/src/main/resources/META-INF/platform/plugins/exportable-resources.json
  13. 13
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/ExecuteUnit4Resource.java
  14. 9
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/ParameterInOptionAddtion.java
  15. 7
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/ParameterInOptionItem.java
  16. 9
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/parameter/InOptionParameter.java
  17. 2
      io.sc.engine.rule.frontend/src/i18n/messages.json
  18. 2
      io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json
  19. 2
      io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json
  20. 28
      io.sc.engine.rule.frontend/src/views/resources/designer/Addition.vue
  21. 21
      io.sc.engine.rule.frontend/src/views/resources/designer/Option.vue
  22. 10
      io.sc.engine.rule.frontend/src/views/resources/designer/Parameter.vue
  23. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/converter/ParameterEntityConverter.java
  24. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/converter/ParameterInOptionAdditionEntityConverter.java
  25. 2
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/converter/ParameterInOptionItemEntityConverter.java
  26. 32
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/ParameterInOptionAdditionEntity.java
  27. 29
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/ParameterInOptionItemEntity.java
  28. 13
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/parameter/InOptionParameterEntity.java
  29. 9
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/ParameterInOptionAdditionVo.java
  30. 11
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/ParameterInOptionItemVo.java
  31. 10
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/parameter/InOptionParameterVo.java
  32. 5
      io.sc.engine.rule.server/src/main/resources/liquibase/RE_1.0.0_20220515__Rule_Engine_Database_Schema_DDL.xml
  33. 2
      io.sc.platform.core/src/main/resources/META-INF/platform/plugins/application-properties.json
  34. 3
      io.sc.platform.core/src/main/resources/io/sc/platform/core/config/application.properties
  35. 6
      io.sc.platform.core/src/main/resources/io/sc/platform/core/config/logback-spring.xml
  36. 4
      io.sc.platform.security.loginform/src/main/java/io/sc/platform/security/loginform/autoconfigure/WebSecurityAutoConfiguration.java
  37. 22
      io.sc.platform.security.loginform/src/main/java/io/sc/platform/security/loginform/controller/LoginWebController.java
  38. 103
      io.sc.platform.security.loginform/src/main/resources/templates/io/sc/platform/security/loginform/view/logined.html
  39. 23
      io.sc.platform.security/src/main/java/io/sc/platform/security/exception/AccountExpiredException.java
  40. 23
      io.sc.platform.security/src/main/java/io/sc/platform/security/exception/AccountLockedException.java
  41. 23
      io.sc.platform.security/src/main/java/io/sc/platform/security/exception/CredentialsExpiredException.java
  42. 15
      io.sc.platform.security/src/main/java/io/sc/platform/security/service/impl/UserDetailsServiceImpl.java
  43. 16
      io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityUser.java
  44. 1
      io.sc.platform.security/src/main/resources/io/sc/platform/security/i18n/messages.properties
  45. 3
      io.sc.platform.security/src/main/resources/io/sc/platform/security/i18n/messages_tw_CN.properties
  46. 3
      io.sc.platform.security/src/main/resources/io/sc/platform/security/i18n/messages_zh_CN.properties

6
app.platform/src/main/webapp/WEB-INF/web.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
</web-app>

2
erm.frontend/src/views/kpi/Lib.vue

@ -36,7 +36,7 @@
{ width: '100%', name: 'name', label: $t('name') }, { width: '100%', name: 'name', label: $t('name') },
{ width: 120, name: 'code', label: $t('code') }, { width: 120, name: 'code', label: $t('code') },
{ width: 100, name: 'lastModifier', label: $t('lastModifier') }, { width: 100, name: 'lastModifier', label: $t('lastModifier') },
{ width: 110, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() }, { width: 110, name: 'lastModifyDate', label: $t('lastModifyDate') },
{ width: 80, name: 'enable', label: $t('status'), align: 'center', sortable: false, format: Formater.enableTag() }, { width: 80, name: 'enable', label: $t('status'), align: 'center', sortable: false, format: Formater.enableTag() },
]" ]"
:editor="{ :editor="{

2
erm.frontend/src/views/kpi/SelectIndicatorDialog.vue

@ -15,7 +15,7 @@
}, },
]" ]"
> >
<div class="px-2"> <div class="px-2" style="height: 100%">
<w-grid <w-grid
ref="gridRef" ref="gridRef"
:title="$t('erm.kpi.shared.selectIndicator.dialog.grid.title')" :title="$t('erm.kpi.shared.selectIndicator.dialog.grid.title')"

14
erm/src/main/resources/META-INF/platform/plugins/liquibase.json

@ -16,16 +16,16 @@
"order" : 20000, "order" : 20000,
"description":"全面风险", "description":"全面风险",
"locations":[ "locations":[
"liquibase/kpi/erm.kpi_1.0.0_20221020__ERM KPI Database Schema DDL.xml", "classpath:/liquibase/kpi/erm.kpi_1.0.0_20221020__ERM_KPI_Database_Schema_DDL.xml",
"liquibase/kpi/erm.kpi_1.0.0_20221020__ERM KPI Database Data.xml", "classpath:/liquibase/kpi/erm.kpi_1.0.0_20221020__ERM_KPI_Database_Data.xml",
"liquibase/appetite/erm.appetite_1.0.0_20221020__ERM Appetite Database Schema DDL.xml", "classpath:/liquibase/appetite/erm.appetite_1.0.0_20221020__ERM_Appetite_Database_Schema_DDL.xml",
"liquibase/appetite/erm.appetite_1.0.0_20221020__ERM Appetite Database Data.xml", "classpath:/liquibase/appetite/erm.appetite_1.0.0_20221020__ERM_Appetite_Database_Data.xml",
"liquibase/capitalplan/erm.capitalpan_1.0.0_20221020__ERM Capital Plan Schema DDL.xml", "classpath:/liquibase/capitalplan/erm.capitalpan_1.0.0_20221020__ERM_Capital_Plan_Schema_DDL.xml",
"liquibase/capitalplan/erm.capitalpan_1.0.0_20221020__ERM Capital Plan Database Data.xml", "classpath:/liquibase/capitalplan/erm.capitalpan_1.0.0_20221020__ERM_Capital_Plan_Database_Data.xml",
"liquibase/economiccapital/erm.capitalpan_1.0.0_20221020__ERM Economic Capital Schema DDL.xml" "classpath:/liquibase/economiccapital/erm.capitalpan_1.0.0_20221020__ERM_Economic_Capital_Schema_DDL.xml"
] ]
} }
] ]

0
erm/src/main/resources/liquibase/appetite/erm.appetite_1.0.0_20221020__ERM Appetite Database Data.xml → erm/src/main/resources/liquibase/appetite/erm.appetite_1.0.0_20221020__ERM_Appetite_Database_Data.xml

0
erm/src/main/resources/liquibase/appetite/erm.appetite_1.0.0_20221020__ERM Appetite Database Schema DDL.xml → erm/src/main/resources/liquibase/appetite/erm.appetite_1.0.0_20221020__ERM_Appetite_Database_Schema_DDL.xml

0
erm/src/main/resources/liquibase/capitalplan/erm.capitalpan_1.0.0_20221020__ERM Capital Plan Database Data.xml → erm/src/main/resources/liquibase/capitalplan/erm.capitalpan_1.0.0_20221020__ERM_Capital_Plan_Database_Data.xml

0
erm/src/main/resources/liquibase/capitalplan/erm.capitalpan_1.0.0_20221020__ERM Capital Plan Schema DDL.xml → erm/src/main/resources/liquibase/capitalplan/erm.capitalpan_1.0.0_20221020__ERM_Capital_Plan_Schema_DDL.xml

0
erm/src/main/resources/liquibase/economiccapital/erm.capitalpan_1.0.0_20221020__ERM Economic Capital Schema DDL.xml → erm/src/main/resources/liquibase/economiccapital/erm.capitalpan_1.0.0_20221020__ERM_Economic_Capital_Schema_DDL.xml

0
erm/src/main/resources/liquibase/kpi/erm.kpi_1.0.0_20221020__ERM KPI Database Data.xml → erm/src/main/resources/liquibase/kpi/erm.kpi_1.0.0_20221020__ERM_KPI_Database_Data.xml

0
erm/src/main/resources/liquibase/kpi/erm.kpi_1.0.0_20221020__ERM KPI Database Schema DDL.xml → erm/src/main/resources/liquibase/kpi/erm.kpi_1.0.0_20221020__ERM_KPI_Database_Schema_DDL.xml

32
io.sc.engine.rule.client/src/main/resources/META-INF/platform/plugins/exportable-resources.json

@ -29,31 +29,31 @@
}, },
{ {
"type" :"file", "type" :"file",
"name" :"io.sc.engine.rule.core-8.2.34.jar", "name" :"io.sc.engine.rule.core-8.2.42.jar",
"description" :"io.sc.engine.rule.core-8.2.34.jar", "description" :"io.sc.engine.rule.core-8.2.42.jar",
"sources" :["classpath:/io/sc/engine/rule/client/jars/io.sc.engine.rule.core-8.2.34.jar"], "sources" :["classpath:/io/sc/engine/rule/client/jars/io.sc.engine.rule.core-8.2.42.jar"],
"target" :"${dir.engine.rule.classpath}/io.sc.engine.rule.core-8.2.34.jar" "target" :"${dir.engine.rule.classpath}/io.sc.engine.rule.core-8.2.42.jar"
}, },
{ {
"type" :"file", "type" :"file",
"name" :"io.sc.platform.util-8.2.34.jar", "name" :"io.sc.platform.util-8.2.42.jar",
"description" :"io.sc.platform.util-8.2.34.jar", "description" :"io.sc.platform.util-8.2.42.jar",
"sources" :["classpath:/io/sc/engine/rule/client/jars/io.sc.platform.util-8.2.34.jar"], "sources" :["classpath:/io/sc/engine/rule/client/jars/io.sc.platform.util-8.2.42.jar"],
"target" :"${dir.engine.rule.classpath}/io.sc.platform.util-8.2.34.jar" "target" :"${dir.engine.rule.classpath}/io.sc.platform.util-8.2.42.jar"
}, },
{ {
"type" :"file", "type" :"file",
"name" :"io.sc.creditreport.core-8.2.34.jar", "name" :"io.sc.creditreport.core-8.2.42.jar",
"description" :"io.sc.creditreport.core-8.2.34.jar", "description" :"io.sc.creditreport.core-8.2.42.jar",
"sources" :["classpath:/io/sc/engine/rule/client/jars/io.sc.creditreport.core-8.2.34.jar"], "sources" :["classpath:/io/sc/engine/rule/client/jars/io.sc.creditreport.core-8.2.42.jar"],
"target" :"${dir.engine.rule.classpath}/io.sc.creditreport.core-8.2.34.jar" "target" :"${dir.engine.rule.classpath}/io.sc.creditreport.core-8.2.42.jar"
}, },
{ {
"type" :"file", "type" :"file",
"name" :"io.sc.engine.rule.client.spring-8.2.34.jar", "name" :"io.sc.engine.rule.client.spring-8.2.42.jar",
"description" :"io.sc.engine.rule.client.spring-8.2.34.jar", "description" :"io.sc.engine.rule.client.spring-8.2.42.jar",
"sources" :["classpath:/io/sc/engine/rule/client/jars/io.sc.engine.rule.client.spring-8.2.34.jar"], "sources" :["classpath:/io/sc/engine/rule/client/jars/io.sc.engine.rule.client.spring-8.2.42.jar"],
"target" :"${dir.engine.rule.classpath}/io.sc.engine.rule.client.spring-8.2.34.jar" "target" :"${dir.engine.rule.classpath}/io.sc.engine.rule.client.spring-8.2.42.jar"
}, },
{ {

13
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/ExecuteUnit4Resource.java

@ -96,18 +96,29 @@ public class ExecuteUnit4Resource extends ExecuteUnit {
// 处理选项参数的选项 // 处理选项参数的选项
if(ParameterType.IN_OPTION.equals(parameter.getType())){ if(ParameterType.IN_OPTION.equals(parameter.getType())){
InOptionParameter inOptionParameter =(InOptionParameter)parameter; InOptionParameter inOptionParameter =(InOptionParameter)parameter;
//选项
List<ParameterInOptionItem> items =inOptionParameter.getOptions(); List<ParameterInOptionItem> items =inOptionParameter.getOptions();
if(items==null || items.isEmpty()) { continue; } if(items==null || items.isEmpty()) { continue; }
for(ParameterInOptionItem item : items){ for(ParameterInOptionItem item : items){
PlaceHolder placeHolder =PlaceHolder.extract(item.getConfig()); PlaceHolder placeHolder =PlaceHolder.extract(item.getCondition());
Set<String> enumRefs =placeHolder.getEnumRefs(); Set<String> enumRefs =placeHolder.getEnumRefs();
if(enumRefs==null || enumRefs.isEmpty()) { continue; } if(enumRefs==null || enumRefs.isEmpty()) { continue; }
for(String enumRef : enumRefs){
String enumValue =findEnumValue(enumRef);
if(!StringUtils.hasText(enumValue)){ continue; }
item.setCondition(item.getCondition().replace("#{" + enumRef.replace(".","}.#{") + "}",enumValue));
}
placeHolder =PlaceHolder.extract(item.getConfig());
enumRefs =placeHolder.getEnumRefs();
if(enumRefs==null || enumRefs.isEmpty()) { continue; }
for(String enumRef : enumRefs){ for(String enumRef : enumRefs){
String enumValue =findEnumValue(enumRef); String enumValue =findEnumValue(enumRef);
if(!StringUtils.hasText(enumValue)){ continue; } if(!StringUtils.hasText(enumValue)){ continue; }
item.setConfig(item.getConfig().replace("#{" + enumRef.replace(".","}.#{") + "}",enumValue)); item.setConfig(item.getConfig().replace("#{" + enumRef.replace(".","}.#{") + "}",enumValue));
} }
} }
//
} }
} }
} }

9
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/ParameterInOptionAddtion.java

@ -7,6 +7,7 @@ public class ParameterInOptionAddtion {
protected String code; protected String code;
protected String name; protected String name;
protected String description; protected String description;
protected String defaultValue;
protected String condition; protected String condition;
protected Boolean enable =true; protected Boolean enable =true;
protected Integer order; protected Integer order;
@ -55,6 +56,14 @@ public class ParameterInOptionAddtion {
this.description = description; this.description = description;
} }
public String getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
public String getCondition() { public String getCondition() {
return condition; return condition;
} }

7
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/ParameterInOptionItem.java

@ -7,6 +7,7 @@ public class ParameterInOptionItem {
protected String title;//选项显示文本 protected String title;//选项显示文本
protected String description;//描述 protected String description;//描述
protected Integer order;//排序 protected Integer order;//排序
protected String condition;//显示条件
protected String config;//配置 protected String config;//配置
public String getId() { public String getId() {
@ -45,6 +46,12 @@ public class ParameterInOptionItem {
public void setOrder(Integer order) { public void setOrder(Integer order) {
this.order = order; this.order = order;
} }
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public String getConfig() { public String getConfig() {
return config; return config;
} }

9
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/po/model/parameter/InOptionParameter.java

@ -20,6 +20,9 @@ import com.fasterxml.jackson.annotation.JsonTypeName;
public class InOptionParameter extends Parameter { public class InOptionParameter extends Parameter {
//当系统自动选择了输入选项中某一项时, 是否禁止用户选择其他项 //当系统自动选择了输入选项中某一项时, 是否禁止用户选择其他项
protected Boolean disableOnAutoSelected; protected Boolean disableOnAutoSelected;
//当参数类型是输入(选项)时,是否采用选择框呈现
protected Boolean uiSelect;
//选项列表 //选项列表
protected List<ParameterInOptionItem> options =new ArrayList<>(); protected List<ParameterInOptionItem> options =new ArrayList<>();
//不录项列表 //不录项列表
@ -36,6 +39,12 @@ public class InOptionParameter extends Parameter {
public void setDisableOnAutoSelected(Boolean disableOnAutoSelected) { public void setDisableOnAutoSelected(Boolean disableOnAutoSelected) {
this.disableOnAutoSelected = disableOnAutoSelected; this.disableOnAutoSelected = disableOnAutoSelected;
} }
public Boolean getUiSelect() {
return uiSelect;
}
public void setUiSelect(Boolean uiSelect) {
this.uiSelect = uiSelect;
}
public List<ParameterInOptionItem> getOptions() { public List<ParameterInOptionItem> getOptions() {
return options; return options;
} }

2
io.sc.engine.rule.frontend/src/i18n/messages.json

@ -98,6 +98,7 @@
"re.parameter.grid.entity.libVersion": "Library Version", "re.parameter.grid.entity.libVersion": "Library Version",
"re.parameter.grid.entity.indicatorCode": "Indicator", "re.parameter.grid.entity.indicatorCode": "Indicator",
"re.parameter.grid.entity.persistentAsIndicator": "Persistent As Indicator", "re.parameter.grid.entity.persistentAsIndicator": "Persistent As Indicator",
"re.parameter.grid.entity.uiSelect": "Is Select Component In UI",
"re.parameter.grid.entity.disableOnAutoSelected": "Disabled On System Auto Selected a Option", "re.parameter.grid.entity.disableOnAutoSelected": "Disabled On System Auto Selected a Option",
"re.parameter.grid.entity.properties": "Extension Properties", "re.parameter.grid.entity.properties": "Extension Properties",
"re.parameter.grid.entity.property.name": "Property Name", "re.parameter.grid.entity.property.name": "Property Name",
@ -121,6 +122,7 @@
"re.option.grid.entity.inputValue": "Input Value", "re.option.grid.entity.inputValue": "Input Value",
"re.option.grid.entity.value": "Value", "re.option.grid.entity.value": "Value",
"re.option.grid.entity.title": "Title", "re.option.grid.entity.title": "Title",
"re.option.grid.entity.condition": "Show Condition(Show the Option Item When Condition is true)",
"re.option.grid.entity.config": "Condition of Auto Selected(Auto Select Item When Condition is true)", "re.option.grid.entity.config": "Condition of Auto Selected(Auto Select Item When Condition is true)",
"re.addition.grid.title": "Addition Items", "re.addition.grid.title": "Addition Items",

2
io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json

@ -98,6 +98,7 @@
"re.parameter.grid.entity.libVersion": "指標庫版本", "re.parameter.grid.entity.libVersion": "指標庫版本",
"re.parameter.grid.entity.indicatorCode": "指標", "re.parameter.grid.entity.indicatorCode": "指標",
"re.parameter.grid.entity.persistentAsIndicator": "是否作為指標存儲", "re.parameter.grid.entity.persistentAsIndicator": "是否作為指標存儲",
"re.parameter.grid.entity.uiSelect": "是否採用下拉選擇框",
"re.parameter.grid.entity.disableOnAutoSelected": "當系統自動選擇了輸入選項中的某一項時, 是否禁止用戶選擇其他項", "re.parameter.grid.entity.disableOnAutoSelected": "當系統自動選擇了輸入選項中的某一項時, 是否禁止用戶選擇其他項",
"re.parameter.grid.entity.properties": "擴展屬性", "re.parameter.grid.entity.properties": "擴展屬性",
"re.parameter.grid.entity.property.name": "屬性名", "re.parameter.grid.entity.property.name": "屬性名",
@ -121,6 +122,7 @@
"re.option.grid.entity.inputValue": "輸入值", "re.option.grid.entity.inputValue": "輸入值",
"re.option.grid.entity.value": "計算值", "re.option.grid.entity.value": "計算值",
"re.option.grid.entity.title": "顯示文本", "re.option.grid.entity.title": "顯示文本",
"re.option.grid.entity.condition": "顯示條件(當條件成立時,顯示該選項)",
"re.option.grid.entity.config": "自動選擇條件(當條件滿足時,自動選中該項)", "re.option.grid.entity.config": "自動選擇條件(當條件滿足時,自動選中該項)",
"re.addition.grid.title": "補錄項", "re.addition.grid.title": "補錄項",

2
io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json

@ -98,6 +98,7 @@
"re.parameter.grid.entity.libVersion": "指标库版本", "re.parameter.grid.entity.libVersion": "指标库版本",
"re.parameter.grid.entity.indicatorCode": "指标", "re.parameter.grid.entity.indicatorCode": "指标",
"re.parameter.grid.entity.persistentAsIndicator": "是否作为指标存储", "re.parameter.grid.entity.persistentAsIndicator": "是否作为指标存储",
"re.parameter.grid.entity.uiSelect": "是否采用下拉选择框",
"re.parameter.grid.entity.disableOnAutoSelected": "当系统自动选择了输入选项中某一项时, 是否禁止用户选择其他项", "re.parameter.grid.entity.disableOnAutoSelected": "当系统自动选择了输入选项中某一项时, 是否禁止用户选择其他项",
"re.parameter.grid.entity.properties": "扩展属性", "re.parameter.grid.entity.properties": "扩展属性",
"re.parameter.grid.entity.property.name": "属性名", "re.parameter.grid.entity.property.name": "属性名",
@ -122,6 +123,7 @@
"re.option.grid.entity.inputValue": "输入值", "re.option.grid.entity.inputValue": "输入值",
"re.option.grid.entity.value": "计算值", "re.option.grid.entity.value": "计算值",
"re.option.grid.entity.title": "显示文本", "re.option.grid.entity.title": "显示文本",
"re.option.grid.entity.condition": "显示条件(当条件成立时,显示该选项)",
"re.option.grid.entity.config": "自动选择条件(当条件满足时,自动选中该项)", "re.option.grid.entity.config": "自动选择条件(当条件满足时,自动选中该项)",
"re.addition.grid.title": "补录项", "re.addition.grid.title": "补录项",

28
io.sc.engine.rule.frontend/src/views/resources/designer/Addition.vue

@ -67,12 +67,25 @@
width: 300, width: 300,
name: 'condition', name: 'condition',
label: $t('re.addition.grid.entity.condition'), label: $t('re.addition.grid.entity.condition'),
html: true,
format: (value: any, row: any) => {
return PlaceHolder.replace(value);
},
}, },
{ {
width: 100, width: 100,
name: 'description', name: 'description',
label: $t('re.addition.grid.entity.description'), label: $t('re.addition.grid.entity.description'),
}, },
{
width: 200,
name: 'defaultValue',
label: $t('defaultValue'),
html: true,
format: (value: any, row: any) => {
return PlaceHolder.replace(value);
},
},
{ {
width: 100, width: 100,
name: 'componentType', name: 'componentType',
@ -175,6 +188,20 @@
rows: 3, rows: 3,
}, },
{ colSpan: 2, name: 'enable', label: $t('enable'), type: 'w-checkbox', defaultValue: true }, { colSpan: 2, name: 'enable', label: $t('enable'), type: 'w-checkbox', defaultValue: true },
{
colSpan: 2,
name: 'defaultValue',
label: $t('defaultValue'),
type: 'w-code-mirror',
toolbar: false,
lang: 'java',
height: 30,
placeholder: true,
lineWrap: true,
lineBreak: false,
autoCompletion: autoCompletionManager.autoCompletion(),
userDefinedFunctions: userDefinedFunctionsManager.userDefinedFunctions(),
},
{ {
colSpan: 2, colSpan: 2,
name: 'condition', name: 'condition',
@ -302,6 +329,7 @@ import { Environment, Formater, CorporationAuditorEntityManager } from 'platform
import { EngineEnums } from '@/views/shared/enums/EngineEnums'; import { EngineEnums } from '@/views/shared/enums/EngineEnums';
import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager'; import { AutoCompletionManager } from '@/views/shared/AutoCompletionManager';
import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager'; import { UserDefinedFunctionsManager } from '@/views/shared/UserDefinedFunctionsManager';
import { PlaceHolder } from '@/utils/PlaceHolder';
const props = defineProps({ const props = defineProps({
fetchDataUrl: { type: String, default: '' }, fetchDataUrl: { type: String, default: '' },

21
io.sc.engine.rule.frontend/src/views/resources/designer/Option.vue

@ -50,6 +50,15 @@
{ width: 100, name: 'inputValue', label: $t('re.option.grid.entity.inputValue') }, { width: 100, name: 'inputValue', label: $t('re.option.grid.entity.inputValue') },
{ width: 100, name: 'value', label: $t('re.option.grid.entity.value') }, { width: 100, name: 'value', label: $t('re.option.grid.entity.value') },
{ width: 400, name: 'title', label: $t('re.option.grid.entity.title') }, { width: 400, name: 'title', label: $t('re.option.grid.entity.title') },
{
width: 300,
name: 'condition',
label: $t('re.option.grid.entity.condition'),
html: true,
format: (value: any, row: any) => {
return PlaceHolder.replace(value);
},
},
{ {
width: 400, width: 400,
name: 'config', name: 'config',
@ -90,6 +99,18 @@
label: $t('description'), label: $t('description'),
type: 'w-text', type: 'w-text',
}, },
{
name: 'condition',
label: $t('re.option.grid.entity.condition'),
type: 'w-code-mirror',
toolbar: false,
lang: 'java',
rows: 4,
lineWrap: true,
lineBreak: false,
placeholder: true,
autoCompletion: autoCompletionManager.autoCompletion(),
},
{ {
name: 'config', name: 'config',
label: $t('re.option.grid.entity.config'), label: $t('re.option.grid.entity.config'),

10
io.sc.engine.rule.frontend/src/views/resources/designer/Parameter.vue

@ -227,6 +227,15 @@
return 'IN_OPTION' === args.form.getFieldValue('type'); return 'IN_OPTION' === args.form.getFieldValue('type');
}, },
}, },
{
name: 'uiSelect',
label: $t('re.parameter.grid.entity.uiSelect'),
type: 'w-checkbox',
defaultValue: false,
showIf: (args: any) => {
return 'IN_OPTION' === args.form.getFieldValue('type');
},
},
{ {
name: 'properties', name: 'properties',
label: $t('re.parameter.grid.entity.properties'), label: $t('re.parameter.grid.entity.properties'),
@ -272,6 +281,7 @@
name: 'value', name: 'value',
label: $t('re.parameter.grid.entity.property.value'), label: $t('re.parameter.grid.entity.property.value'),
sortable: false, sortable: false,
html: true,
format: (value: any) => { format: (value: any) => {
return PlaceHolder.replace(value); return PlaceHolder.replace(value);
}, },

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/converter/ParameterEntityConverter.java

@ -35,6 +35,7 @@ public class ParameterEntityConverter {
InOptionParameterEntity _entity =(InOptionParameterEntity)entity; InOptionParameterEntity _entity =(InOptionParameterEntity)entity;
InOptionParameter _po =new InOptionParameter(); InOptionParameter _po =new InOptionParameter();
_po.setDisableOnAutoSelected(_entity.getDisableOnAutoSelected()); _po.setDisableOnAutoSelected(_entity.getDisableOnAutoSelected());
_po.setUiSelect(_entity.getUiSelect());
_po.setOptions(ParameterInOptionItemEntityConverter.toPo(_entity.getOptions())); _po.setOptions(ParameterInOptionItemEntityConverter.toPo(_entity.getOptions()));
_po.setAdditons(ParameterInOptionAdditionEntityConverter.toPo(_entity.getAdditions())); _po.setAdditons(ParameterInOptionAdditionEntityConverter.toPo(_entity.getAdditions()));
po =_po; po =_po;
@ -108,6 +109,7 @@ public class ParameterEntityConverter {
InOptionParameter _po =(InOptionParameter)po; InOptionParameter _po =(InOptionParameter)po;
InOptionParameterEntity _entity =new InOptionParameterEntity(); InOptionParameterEntity _entity =new InOptionParameterEntity();
_entity.setDisableOnAutoSelected(_po.getDisableOnAutoSelected()); _entity.setDisableOnAutoSelected(_po.getDisableOnAutoSelected());
_entity.setUiSelect(_po.getUiSelect());
List<ParameterInOptionItemEntity> options =ParameterInOptionItemEntityConverter.fromPo(_po.getOptions()); List<ParameterInOptionItemEntity> options =ParameterInOptionItemEntityConverter.fromPo(_po.getOptions());
if(options!=null && options.size()>0) { if(options!=null && options.size()>0) {

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/converter/ParameterInOptionAdditionEntityConverter.java

@ -22,6 +22,7 @@ public class ParameterInOptionAdditionEntityConverter {
po.setCode(entity.getCode()); po.setCode(entity.getCode());
po.setName(entity.getName()); po.setName(entity.getName());
po.setDescription(entity.getDescription()); po.setDescription(entity.getDescription());
po.setDefaultValue(entity.getDefaultValue());
po.setCondition(entity.getCondition()); po.setCondition(entity.getCondition());
po.setEnable(entity.getEnable()); po.setEnable(entity.getEnable());
po.setOrder(entity.getOrder()); po.setOrder(entity.getOrder());
@ -71,6 +72,7 @@ public class ParameterInOptionAdditionEntityConverter {
entity.setCode(po.getCode()); entity.setCode(po.getCode());
entity.setName(po.getName()); entity.setName(po.getName());
entity.setDescription(po.getDescription()); entity.setDescription(po.getDescription());
entity.setDefaultValue(po.getDefaultValue());
entity.setCondition(po.getCondition()); entity.setCondition(po.getCondition());
entity.setEnable(po.getEnable()); entity.setEnable(po.getEnable());
entity.setOrder(po.getOrder()); entity.setOrder(po.getOrder());

2
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/converter/ParameterInOptionItemEntityConverter.java

@ -24,6 +24,7 @@ public class ParameterInOptionItemEntityConverter {
po.setTitle(entity.getTitle()); po.setTitle(entity.getTitle());
po.setDescription(entity.getDescription()); po.setDescription(entity.getDescription());
po.setOrder(entity.getOrder()); po.setOrder(entity.getOrder());
po.setCondition(entity.getCondition());
po.setConfig(entity.getConfig()); po.setConfig(entity.getConfig());
return po; return po;
} }
@ -60,6 +61,7 @@ public class ParameterInOptionItemEntityConverter {
entity.setTitle(po.getTitle()); entity.setTitle(po.getTitle());
entity.setDescription(po.getDescription()); entity.setDescription(po.getDescription());
entity.setOrder(po.getOrder()); entity.setOrder(po.getOrder());
entity.setCondition(po.getCondition());
entity.setConfig(po.getConfig()); entity.setConfig(po.getConfig());
return entity; return entity;
} }

32
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/ParameterInOptionAdditionEntity.java

@ -51,6 +51,11 @@ public class ParameterInOptionAdditionEntity extends CorporationAuditorEntity<Pa
@Size(max=255) @Size(max=255)
protected String description; protected String description;
//默认值
@Column(name="DEFAULT_VALUE_", length=1024)
@Size(max=1024)
protected String defaultValue;
//触发条件 //触发条件
@Column(name="CONDITION_", length=1024) @Column(name="CONDITION_", length=1024)
@Size(max=1024) @Size(max=1024)
@ -129,6 +134,7 @@ public class ParameterInOptionAdditionEntity extends CorporationAuditorEntity<Pa
vo.setCode(this.getCode()); vo.setCode(this.getCode());
vo.setName(this.getName()); vo.setName(this.getName());
vo.setDescription(this.getDescription()); vo.setDescription(this.getDescription());
vo.setDefaultValue(this.getDefaultValue());
vo.setCondition(this.getCondition()); vo.setCondition(this.getCondition());
vo.setEnable(this.getEnable()); vo.setEnable(this.getEnable());
vo.setOrder(this.getOrder()); vo.setOrder(this.getOrder());
@ -189,6 +195,14 @@ public class ParameterInOptionAdditionEntity extends CorporationAuditorEntity<Pa
this.description = description; this.description = description;
} }
public String getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
public String getCondition() { public String getCondition() {
return condition; return condition;
} }
@ -322,9 +336,16 @@ public class ParameterInOptionAdditionEntity extends CorporationAuditorEntity<Pa
@Override @Override
public boolean replace(ParameterAndValueType parameterAndValueType, ReplaceMode mode) { public boolean replace(ParameterAndValueType parameterAndValueType, ReplaceMode mode) {
String replaced =parameterAndValueType.replace(this.condition, mode); String replaced =parameterAndValueType.replace(this.defaultValue, mode);
replaced =(replaced==null?"":replaced); replaced =(replaced==null?"":replaced);
boolean result =false; boolean result =false;
if(!replaced.equals(this.defaultValue)) {
result =true;
}
this.defaultValue =replaced;
replaced =parameterAndValueType.replace(this.condition, mode);
replaced =(replaced==null?"":replaced);
if(!replaced.equals(this.condition)) { if(!replaced.equals(this.condition)) {
result =true; result =true;
} }
@ -341,9 +362,16 @@ public class ParameterInOptionAdditionEntity extends CorporationAuditorEntity<Pa
@Override @Override
public boolean replace(Map<String, String> code2codeMapping) { public boolean replace(Map<String, String> code2codeMapping) {
String replaced = ParameterCodeReplacer.replace(this.condition, code2codeMapping); String replaced = ParameterCodeReplacer.replace(this.defaultValue, code2codeMapping);
replaced =(replaced==null?"":replaced); replaced =(replaced==null?"":replaced);
boolean result =false; boolean result =false;
if(!replaced.equals(this.defaultValue)) {
result =true;
}
this.defaultValue =replaced;
replaced = ParameterCodeReplacer.replace(this.condition, code2codeMapping);
replaced =(replaced==null?"":replaced);
if(!replaced.equals(this.condition)) { if(!replaced.equals(this.condition)) {
result =true; result =true;
} }

29
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/ParameterInOptionItemEntity.java

@ -55,7 +55,11 @@ public class ParameterInOptionItemEntity extends CorporationAuditorEntity<Parame
@Column(name="ORDER_") @Column(name="ORDER_")
protected Integer order; protected Integer order;
//配置 //显示条件
@Column(name="CONDITION_")
protected String condition;
//自动选择条件
@Column(name="CONFIG_") @Column(name="CONFIG_")
protected String config; protected String config;
@ -70,6 +74,7 @@ public class ParameterInOptionItemEntity extends CorporationAuditorEntity<Parame
vo.setTitle(this.getTitle()); vo.setTitle(this.getTitle());
vo.setDescription(this.getDescription()); vo.setDescription(this.getDescription());
vo.setOrder(this.getOrder()); vo.setOrder(this.getOrder());
vo.setCondition(this.getCondition());
vo.setConfig(this.getConfig()); vo.setConfig(this.getConfig());
return vo; return vo;
} }
@ -130,6 +135,14 @@ public class ParameterInOptionItemEntity extends CorporationAuditorEntity<Parame
this.order = order; this.order = order;
} }
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public String getConfig() { public String getConfig() {
return config; return config;
} }
@ -158,6 +171,13 @@ public class ParameterInOptionItemEntity extends CorporationAuditorEntity<Parame
result =true; result =true;
} }
this.config =replaced; this.config =replaced;
replaced =parameterAndValueType.replace(this.condition, mode);
replaced =(replaced==null?"":replaced);
if(!replaced.equals(this.condition)) {
result =true;
}
this.condition =replaced;
return result; return result;
} }
@ -170,6 +190,13 @@ public class ParameterInOptionItemEntity extends CorporationAuditorEntity<Parame
result =true; result =true;
} }
this.config =replaced; this.config =replaced;
replaced = ParameterCodeReplacer.replace(this.condition, code2codeMapping);
replaced =(replaced==null?"":replaced);
if(!replaced.equals(this.condition)) {
result =true;
}
this.condition =replaced;
return result; return result;
} }
} }

13
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/entity/parameter/InOptionParameterEntity.java

@ -24,6 +24,11 @@ public class InOptionParameterEntity extends ParameterEntity {
@Convert(converter= NumericBooleanConverter.class) @Convert(converter= NumericBooleanConverter.class)
protected Boolean disableOnAutoSelected; protected Boolean disableOnAutoSelected;
//当参数类型是输入(选项)时,是否采用选择框呈现
@Column(name="IS_UI_SELECT_")
@Convert(converter= NumericBooleanConverter.class)
protected Boolean uiSelect;
//选项列表 //选项列表
@OneToMany(mappedBy="parameter",cascade= {CascadeType.PERSIST}) @OneToMany(mappedBy="parameter",cascade= {CascadeType.PERSIST})
@OrderBy("order") @OrderBy("order")
@ -40,6 +45,7 @@ public class InOptionParameterEntity extends ParameterEntity {
super.toVo(vo); super.toVo(vo);
vo.setType(this.getType()); vo.setType(this.getType());
vo.setDisableOnAutoSelected(this.getDisableOnAutoSelected()); vo.setDisableOnAutoSelected(this.getDisableOnAutoSelected());
vo.setUiSelect(this.getUiSelect());
return vo; return vo;
} }
@ -59,6 +65,13 @@ public class InOptionParameterEntity extends ParameterEntity {
public void setDisableOnAutoSelected(Boolean disableOnAutoSelected) { public void setDisableOnAutoSelected(Boolean disableOnAutoSelected) {
this.disableOnAutoSelected = disableOnAutoSelected; this.disableOnAutoSelected = disableOnAutoSelected;
} }
public Boolean getUiSelect() {
return uiSelect;
}
public void setUiSelect(Boolean uiSelect) {
this.uiSelect = uiSelect;
}
public List<ParameterInOptionItemEntity> getOptions() { public List<ParameterInOptionItemEntity> getOptions() {
return options; return options;
} }

9
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/ParameterInOptionAdditionVo.java

@ -15,6 +15,7 @@ public class ParameterInOptionAdditionVo extends CorporationAuditorVo {
protected String code; protected String code;
protected String name; protected String name;
protected String description; protected String description;
protected String defaultValue;
protected String condition; protected String condition;
protected Boolean enable =true; protected Boolean enable =true;
protected Integer order; protected Integer order;
@ -71,6 +72,14 @@ public class ParameterInOptionAdditionVo extends CorporationAuditorVo {
this.description = description; this.description = description;
} }
public String getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
public String getCondition() { public String getCondition() {
return condition; return condition;
} }

11
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/ParameterInOptionItemVo.java

@ -28,6 +28,9 @@ public class ParameterInOptionItemVo extends CorporationAuditorVo {
//排序 //排序
protected Integer order; protected Integer order;
//显示条件
protected String condition;
//配置 //配置
protected String config; protected String config;
@ -88,6 +91,14 @@ public class ParameterInOptionItemVo extends CorporationAuditorVo {
this.order = order; this.order = order;
} }
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
public String getConfig() { public String getConfig() {
return config; return config;
} }

10
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/vo/parameter/InOptionParameterVo.java

@ -9,6 +9,8 @@ import io.sc.engine.rule.server.model.vo.ParameterVo;
public class InOptionParameterVo extends ParameterVo { public class InOptionParameterVo extends ParameterVo {
//当系统自动选择了输入选项中某一项时, 是否禁止用户选择其他项 //当系统自动选择了输入选项中某一项时, 是否禁止用户选择其他项
protected Boolean disableOnAutoSelected; protected Boolean disableOnAutoSelected;
//当参数类型是输入(选项)时,是否采用选择框呈现
protected Boolean uiSelect;
@Override @Override
public ParameterType getType() { public ParameterType getType() {
@ -22,4 +24,12 @@ public class InOptionParameterVo extends ParameterVo {
public void setDisableOnAutoSelected(Boolean disableOnAutoSelected) { public void setDisableOnAutoSelected(Boolean disableOnAutoSelected) {
this.disableOnAutoSelected = disableOnAutoSelected; this.disableOnAutoSelected = disableOnAutoSelected;
} }
public Boolean getUiSelect() {
return uiSelect;
}
public void setUiSelect(Boolean uiSelect) {
this.uiSelect = uiSelect;
}
} }

5
io.sc.engine.rule.server/src/main/resources/liquibase/RE_1.0.0_20220515__Rule_Engine_Database_Schema_DDL.xml

@ -169,6 +169,7 @@
<column name="ORDER_" type="INTEGER" remarks="排序"/> <column name="ORDER_" type="INTEGER" remarks="排序"/>
<column name="IS_PERSISTENT_AS_INDICATOR" type="SMALLINT" remarks="是否作为指标存储"/> <column name="IS_PERSISTENT_AS_INDICATOR" type="SMALLINT" remarks="是否作为指标存储"/>
<column name="DISABLE_ON_AUTO_SELECTED_" type="SMALLINT" remarks="当系统自动选择了输入选项中某一项时, 是否禁止用户选择其他项"/> <column name="DISABLE_ON_AUTO_SELECTED_" type="SMALLINT" remarks="当系统自动选择了输入选项中某一项时, 是否禁止用户选择其他项"/>
<column name="IS_UI_SELECT_" type="SMALLINT" remarks="当参数类型是输入(选项)时,是否采用选择框呈现,false:单选框; true: 下拉选择框"/>
<column name="PROPERTIES_" type="CLOB" remarks="属性"/> <column name="PROPERTIES_" type="CLOB" remarks="属性"/>
<!-- 审计字段 --> <!-- 审计字段 -->
@ -221,7 +222,8 @@
<column name="TITLE_" type="NVARCHAR(1024)" remarks="文本"/> <column name="TITLE_" type="NVARCHAR(1024)" remarks="文本"/>
<column name="DESCRIPTION_" type="NVARCHAR(1024)" remarks="描述"/> <column name="DESCRIPTION_" type="NVARCHAR(1024)" remarks="描述"/>
<column name="ORDER_" type="INTEGER" remarks="顺序"/> <column name="ORDER_" type="INTEGER" remarks="顺序"/>
<column name="CONFIG_" type="CLOB" remarks="配置"/> <column name="CONDITION_" type="CLOB" remarks="显示条件(当条件成立时,该选项被显示)"/>
<column name="CONFIG_" type="CLOB" remarks="自动选择条件(当条件成立时,该选项被自动选中)"/>
<!-- 审计字段 --> <!-- 审计字段 -->
<column name="JPA_VERSION_" type="INTEGER" remarks="JPA乐观锁版本"/> <column name="JPA_VERSION_" type="INTEGER" remarks="JPA乐观锁版本"/>
@ -265,6 +267,7 @@
<column name="CODE_" type="NVARCHAR(255)" remarks="代码"/> <column name="CODE_" type="NVARCHAR(255)" remarks="代码"/>
<column name="NAME_" type="NVARCHAR(255)" remarks="名称"/> <column name="NAME_" type="NVARCHAR(255)" remarks="名称"/>
<column name="DESCRIPTION_" type="NVARCHAR(255)" remarks="描述"/> <column name="DESCRIPTION_" type="NVARCHAR(255)" remarks="描述"/>
<column name="DEFAULT_VALUE_" type="NVARCHAR(1024)" remarks="默认值,通常指向一个指标,用于反显补录项的初始值"/>
<column name="CONDITION_" type="NVARCHAR(1024)" remarks="条件"/> <column name="CONDITION_" type="NVARCHAR(1024)" remarks="条件"/>
<column name="ENABLE_" type="SMALLINT" remarks="是否可用"/> <column name="ENABLE_" type="SMALLINT" remarks="是否可用"/>
<column name="ORDER_" type="INTEGER" remarks="排序"/> <column name="ORDER_" type="INTEGER" remarks="排序"/>

2
io.sc.platform.core/src/main/resources/META-INF/platform/plugins/application-properties.json

@ -61,7 +61,7 @@
"server.servlet.session.timeout = 30m", "server.servlet.session.timeout = 30m",
"server.servlet.session.cookie.http-only = true", "server.servlet.session.cookie.http-only = true",
"server.servlet.session.cookie.secure = true", "server.servlet.session.cookie.secure = true",
"server.servlet.session.cookie.same-site = STRICT", "server.servlet.session.cookie.same-site = LAX",
"server.error.path = /error", "server.error.path = /error",
"server.error.whitelabel.enabled = true", "server.error.whitelabel.enabled = true",
"server.error.include-exception = true", "server.error.include-exception = true",

3
io.sc.platform.core/src/main/resources/io/sc/platform/core/config/application.properties

@ -34,6 +34,9 @@ server.address =
server.port = 8080 server.port = 8080
server.servlet.context-path = / server.servlet.context-path = /
server.servlet.session.timeout = 30m server.servlet.session.timeout = 30m
server.servlet.session.cookie.http-only = true
server.servlet.session.cookie.secure = true
server.servlet.session.cookie.same-site = LAX
server.error.path = /error server.error.path = /error
server.error.whitelabel.enabled = true server.error.whitelabel.enabled = true
server.error.include-exception = true server.error.include-exception = true

6
io.sc.platform.core/src/main/resources/io/sc/platform/core/config/logback-spring.xml

@ -101,12 +101,12 @@
<!-- 数据库连接日志(ALL) --> <!-- 数据库连接日志(ALL) -->
<logger name="com.zaxxer.hikari" level="trace"> <logger name="com.zaxxer.hikari" level="trace">
<appender-ref ref="FILE_DB_ALL" /> <appender-ref ref="FILE_DB_ALL" />
<appender-ref ref="FILE_DB_ALL_ERROR" /> <appender-ref ref="FILE_DB_ERROR" />
</logger> </logger>
<!-- 数据库连接日志(WARN+) --> <!-- 数据库连接日志(WARN+) -->
<logger name="io.sc.platform.jdbc.autoconfigure" level="warn"> <logger name="io.sc.platform.jdbc.autoconfigure" level="warn">
<appender-ref ref="FILE_DB_ALL_ALL" /> <appender-ref ref="FILE_DB_ALL" />
<appender-ref ref="FILE_DB_ALL_ERROR" /> <appender-ref ref="FILE_DB_ERROR" />
</logger> </logger>
<!-- 决策引擎日志(DEBUG+) --> <!-- 决策引擎日志(DEBUG+) -->

4
io.sc.platform.security.loginform/src/main/java/io/sc/platform/security/loginform/autoconfigure/WebSecurityAutoConfiguration.java

@ -118,7 +118,9 @@ public class WebSecurityAutoConfiguration {
// 在用户名密码认证过滤器前添加 jwt 认证过滤器 // 在用户名密码认证过滤器前添加 jwt 认证过滤器
JwtUsernamePasswordAuthenticationFilter jwtUsernamePasswordAuthenticationFilter =new JwtUsernamePasswordAuthenticationFilter(jwtDecoder,securityConfigureService.getIgnoredUrlMatchers()); JwtUsernamePasswordAuthenticationFilter jwtUsernamePasswordAuthenticationFilter =new JwtUsernamePasswordAuthenticationFilter(jwtDecoder,securityConfigureService.getIgnoredUrlMatchers());
http.addFilterBefore(jwtUsernamePasswordAuthenticationFilter, UsernamePasswordAuthenticationFilter.class); http.addFilterBefore(jwtUsernamePasswordAuthenticationFilter, UsernamePasswordAuthenticationFilter.class);
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS); //http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}else{
http.sessionManagement().maximumSessions(1).expiredUrl(securityProperties.getFormLogin().getLoginPage() + "/logined");
} }
return http.build(); return http.build();
} }

22
io.sc.platform.security.loginform/src/main/java/io/sc/platform/security/loginform/controller/LoginWebController.java

@ -20,6 +20,7 @@ import java.util.Map;
public class LoginWebController { public class LoginWebController {
private static final String SPRING_THYMELEAF_PREFIX ="spring.thymeleaf.prefix"; private static final String SPRING_THYMELEAF_PREFIX ="spring.thymeleaf.prefix";
private static final String DEFAULT_LOGIN_TEMPLATE ="io/sc/platform/security/loginform/view/login.html"; private static final String DEFAULT_LOGIN_TEMPLATE ="io/sc/platform/security/loginform/view/login.html";
private static final String DEFAULT_LOGINED_TEMPLATE ="io/sc/platform/security/loginform/view/logined.html";
private static final String DEFAULT_LOGIN_ERROR_TEMPLATE ="io/sc/platform/security/loginform/view/login.html"; private static final String DEFAULT_LOGIN_ERROR_TEMPLATE ="io/sc/platform/security/loginform/view/login.html";
@Autowired ConfigurableEnvironment env; @Autowired ConfigurableEnvironment env;
@Autowired ConfigureService configureService; @Autowired ConfigureService configureService;
@ -35,6 +36,17 @@ public class LoginWebController {
return mv; return mv;
} }
@RequestMapping(value="/login/logined",method=RequestMethod.GET)
public ModelAndView logined(HttpServletRequest request, Principal principal) throws Exception{
if(principal!=null && principal.getName()!=null){
return new ModelAndView("redirect:/");
}
String loginPagetemplate =getLoginedPageTemplate();
ModelAndView mv =new ModelAndView(loginPagetemplate);
mv.addAllObjects(getModelData());
return mv;
}
@RequestMapping(value="/login-error",method=RequestMethod.GET) @RequestMapping(value="/login-error",method=RequestMethod.GET)
public ModelAndView loginError(HttpServletRequest request, Principal principal) throws Exception{ public ModelAndView loginError(HttpServletRequest request, Principal principal) throws Exception{
if(principal!=null && principal.getName()!=null){ if(principal!=null && principal.getName()!=null){
@ -57,6 +69,16 @@ public class LoginWebController {
return loginPagetemplate; return loginPagetemplate;
} }
private String getLoginedPageTemplate() throws Exception{
String loginPagetemplate =DEFAULT_LOGINED_TEMPLATE;
String thymeleafPrefix =env.getProperty(SPRING_THYMELEAF_PREFIX, String.class, "classpath:/templates/");
Resource resource =new DefaultResourceLoader().getResource(thymeleafPrefix + loginPagetemplate);
if(!resource.exists()){
loginPagetemplate =DEFAULT_LOGINED_TEMPLATE;
}
return loginPagetemplate;
}
private String getLoginErrorPageTemplate() throws Exception{ private String getLoginErrorPageTemplate() throws Exception{
String loginPagetemplate =DEFAULT_LOGIN_ERROR_TEMPLATE; String loginPagetemplate =DEFAULT_LOGIN_ERROR_TEMPLATE;
String thymeleafPrefix =env.getProperty(SPRING_THYMELEAF_PREFIX, String.class, "classpath:/templates/"); String thymeleafPrefix =env.getProperty(SPRING_THYMELEAF_PREFIX, String.class, "classpath:/templates/");

103
io.sc.platform.security.loginform/src/main/resources/templates/io/sc/platform/security/loginform/view/logined.html

@ -0,0 +1,103 @@
<!DOCTYPE html>
<html>
<head>
<title th:utext="#{application.title}"></title>
<link rel="icon" th:href="@{/favicon.svg}">
<meta http-equiv="Content-Type" content="text/html charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"/>
<link rel="stylesheet" type="text/css" th:href="@{/bootstrap/css/bootstrap.min.css}"/>
<style>
body{
height: 100vh;
background-color: #EEE;
background-size: 100% 100%;
}
.text-primary {
color: #14234a !important;
}
.bg-primary {
background-color: #14234a !important;
}
.nav-pills .nav-link.active {
background-color: #14234a;
}
.btn-primary {
background-color: #14234a;
border-color: #14234a;
}
.form-check-input:checked {
background-color: #14234a;
border-color: #14234a;
}
.btn-outline-primary {
--bs-btn-color: #14234a;
--bs-btn-border-color: #14234a;
--bs-btn-hover-color: #fff;
--bs-btn-hover-bg: #14234a;
--bs-btn-hover-border-color: #14234a;
--bs-btn-focus-shadow-rgb: 13, 110, 253;
--bs-btn-active-color: #fff;
--bs-btn-active-bg: #14234a;
--bs-btn-active-border-color: #14234a;
--bs-btn-active-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);
--bs-btn-disabled-color: #14234a;
--bs-btn-disabled-bg: transparent;
--bs-btn-disabled-border-color: #14234a;
--bs-gradient: none;
}
.progress-bar {
background-color: #14234a;
}
</style>
<script type="text/javascript" th:src="@{/bootstrap/js/bootstrap.bundle.min.js}"></script>
<script th:inline="javascript">
</script>
</head>
<body style="min-height: 782px; min-width: 600px; background-image: url(login-bg.jpg); background-position: center center; background-repeat: no-repeat; background-size: cover; background-attachment: fixed;">
<nav class="navbar bg-primary" th:style="|padding:0px;height:${theme.topper.height}px|">
<div class="container-fluid" th:style="|padding:0px;padding-left:8px;height:${theme.topper.height}px|">
<a class="navbar-brand" href="#" th:style="|height:${theme.topper.height}px;color:white;padding:0px|">
<img th:src="@{|/${theme.topper.logo}?t=${#dates.createNow().getTime()}|}" alt="Logo" th:width="|${theme.topper.logoWidth}px|" th:height="|${theme.topper.logoHeight}px|" style="pading:0px;margin-top:-6px;">
<span th:style="|font-size:1.2em;height:${theme.topper.height}px;line-height:${theme.topper.height}px;color:white;|" th:text="#{application.title}"></span>
</a>
</div>
</nav>
<div style="height:100px"></div>
<div class="container">
<div class="row">
<div class="col-md-6 col-xl-7"></div>
<div class="col-md-6 col-xl-5">
<div class="shadow-sm p-3 mb-5 bg-light rounded-3 border">
<div th:if="${error}" class="alert alert-danger" role="alert">
<span th:text="#{security.login.message.error}">认证失败!</span>
</div>
<form class="row g-3" th:action="@{${loginProcessingUrl}}" method="post">
<div class="col-12">
<label for="username" class="form-label" th:text="#{loginName}">用户名</label>
<input type="text" class="form-control" name="username" th:placeholder="#{security.login.username.placeholder}" autofocus>
</div>
<div class="col-12">
<label for="password" class="form-label" th:text="#{password}">密码</label>
<input type="password" class="form-control" name="password" th:placeholder="#{security.login.password.placeholder}">
</div>
<div class="form-group">
<div class="text-end">
<button type="submit" class="ms-2 btn btn-primary" th:text="#{login}">登录</button>
<button type="reset" class="ms-2 btn btn-success" th:text="#{reset}">重置</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
</script>
</html>

23
io.sc.platform.security/src/main/java/io/sc/platform/security/exception/AccountExpiredException.java

@ -0,0 +1,23 @@
package io.sc.platform.security.exception;
public class AccountExpiredException extends RuntimeException{
public AccountExpiredException() {
super();
}
public AccountExpiredException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public AccountExpiredException(String message, Throwable cause) {
super(message, cause);
}
public AccountExpiredException(String message) {
super(message);
}
public AccountExpiredException(Throwable cause) {
super(cause);
}
}

23
io.sc.platform.security/src/main/java/io/sc/platform/security/exception/AccountLockedException.java

@ -0,0 +1,23 @@
package io.sc.platform.security.exception;
public class AccountLockedException extends RuntimeException{
public AccountLockedException() {
super();
}
public AccountLockedException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public AccountLockedException(String message, Throwable cause) {
super(message, cause);
}
public AccountLockedException(String message) {
super(message);
}
public AccountLockedException(Throwable cause) {
super(cause);
}
}

23
io.sc.platform.security/src/main/java/io/sc/platform/security/exception/CredentialsExpiredException.java

@ -0,0 +1,23 @@
package io.sc.platform.security.exception;
public class CredentialsExpiredException extends RuntimeException{
public CredentialsExpiredException() {
super();
}
public CredentialsExpiredException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public CredentialsExpiredException(String message, Throwable cause) {
super(message, cause);
}
public CredentialsExpiredException(String message) {
super(message);
}
public CredentialsExpiredException(Throwable cause) {
super(cause);
}
}

15
io.sc.platform.security/src/main/java/io/sc/platform/security/service/impl/UserDetailsServiceImpl.java

@ -1,13 +1,13 @@
package io.sc.platform.security.service.impl; package io.sc.platform.security.service.impl;
import io.sc.platform.core.annotation.AuditLog; import io.sc.platform.security.exception.AccountExpiredException;
import io.sc.platform.core.enums.AuditLogAction; import io.sc.platform.security.exception.AccountLockedException;
import io.sc.platform.security.exception.CredentialsExpiredException;
import io.sc.platform.security.service.support.*; import io.sc.platform.security.service.support.*;
import io.sc.platform.security.support.SecurityRole; import io.sc.platform.security.support.SecurityRole;
import io.sc.platform.security.support.SecurityUser; import io.sc.platform.security.support.SecurityUser;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor; import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowMapper; import org.springframework.jdbc.core.RowMapper;
@ -61,6 +61,15 @@ public class UserDetailsServiceImpl implements UserDetailsService{
if(StringUtils.hasText(username)){ if(StringUtils.hasText(username)){
User u =jdbcTemplate.query(userQuery, userExtractor, username); User u =jdbcTemplate.query(userQuery, userExtractor, username);
if(u!=null){ if(u!=null){
if(u.getAccountLocked()){
throw new AccountLockedException();
}
if(u.getAccountExpired()){
throw new AccountExpiredException();
}
if(u.getCredentialsExpired()){
throw new CredentialsExpiredException();
}
//获取用户所属角色 //获取用户所属角色
List<Role> roles =jdbcTemplate.query(roleQuery, roleRowMapper, u.getId()); List<Role> roles =jdbcTemplate.query(roleQuery, roleRowMapper, u.getId());
//构建安全认证用户对象 //构建安全认证用户对象

16
io.sc.platform.security/src/main/java/io/sc/platform/security/support/SecurityUser.java

@ -178,4 +178,20 @@ public class SecurityUser extends User{
public void setCorporationName(String corporationName) { public void setCorporationName(String corporationName) {
this.corporationName = corporationName; this.corporationName = corporationName;
} }
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
if (!super.equals(o)) return false;
SecurityUser that = (SecurityUser) o;
return userId.equals(that.userId);
}
@Override
public int hashCode() {
int result = super.hashCode();
result = 31 * result + userId.hashCode();
return result;
}
} }

1
io.sc.platform.security/src/main/resources/io/sc/platform/security/i18n/messages.properties

@ -8,6 +8,7 @@ AdministratorInstallerItem.admin_password=Password
# login # login
security.login.title=System Authentication security.login.title=System Authentication
security.login.message.error=authentication failed! please check your user name and password. security.login.message.error=authentication failed! please check your user name and password.
security.login.message.alreadyLogin=You was logined on anther device.
security.login.username.placeholder=Please input login name security.login.username.placeholder=Please input login name
security.login.password.placeholder=Please input password security.login.password.placeholder=Please input password

3
io.sc.platform.security/src/main/resources/io/sc/platform/security/i18n/messages_tw_CN.properties

@ -6,7 +6,8 @@ AdministratorInstallerItem.admin_password=\u5BC6\u78BC
# login # login
security.login.title=\u7CFB\u7D71\u767B\u9304 security.login.title=\u7CFB\u7D71\u767B\u9304
security.login.message.error=\u8A8D\u8B49\u5931\u6557\uFF01\u8ACB\u6AA2\u67E5\u60A8\u8F38\u5165\u7684\u767B\u9678\u540D\u548C\u5BC6\u78BC\u662F\u5426\u6B63\u78BA security.login.message.error=\u8A8D\u8B49\u5931\u6557\uFF01\u8ACB\u6AA2\u67E5\u60A8\u8F38\u5165\u7684\u767B\u9678\u540D\u548C\u5BC6\u78BC\u662F\u5426\u6B63\u78BA.
security.login.message.alreadyLogin=\u60A8\u5DF2\u7D93\u5728\u5176\u4ED6\u8A2D\u5099\u4E0A\u767B\u9304\u904E\u4E86
security.login.username.placeholder=\u8ACB\u8F38\u5165\u767B\u9304\u540D security.login.username.placeholder=\u8ACB\u8F38\u5165\u767B\u9304\u540D
security.login.password.placeholder=\u8ACB\u8F38\u5165\u5BC6\u78BC security.login.password.placeholder=\u8ACB\u8F38\u5165\u5BC6\u78BC

3
io.sc.platform.security/src/main/resources/io/sc/platform/security/i18n/messages_zh_CN.properties

@ -7,7 +7,8 @@ AdministratorInstallerItem.admin_password=\u5BC6\u7801
# login # login
security.login.title=\u7CFB\u7EDF\u767B\u5F55 security.login.title=\u7CFB\u7EDF\u767B\u5F55
security.login.message.error=\u8BA4\u8BC1\u5931\u8D25! \u8BF7\u68C0\u67E5\u60A8\u8F93\u5165\u7684\u767B\u5F55\u540D\u548C\u5BC6\u7801\u662F\u5426\u6B63\u786E\u3002 security.login.message.error=\u8BA4\u8BC1\u5931\u8D25! \u8BF7\u68C0\u67E5\u60A8\u8F93\u5165\u7684\u767B\u5F55\u540D\u548C\u5BC6\u7801\u662F\u5426\u6B63\u786E.
security.login.message.alreadyLogin=\u60A8\u5DF2\u7ECF\u5728\u5176\u4ED6\u8BBE\u5907\u4E0A\u767B\u5F55\u8FC7\u4E86
security.login.username.placeholder=\u8BF7\u8F93\u5165\u767B\u5F55\u540D security.login.username.placeholder=\u8BF7\u8F93\u5165\u767B\u5F55\u540D
security.login.password.placeholder=\u8BF7\u8F93\u5165\u5BC6\u7801 security.login.password.placeholder=\u8BF7\u8F93\u5165\u5BC6\u7801

Loading…
Cancel
Save