Browse Source

update

main
wangshaoping 7 months ago
parent
commit
c9c54344cc
  1. 2
      app.platform/build-common.gradle
  2. 2
      erm.frontend/package.json
  3. 2
      gradle.properties
  4. 2
      io.sc.engine.mv.frontend/package.json
  5. 1
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/GroovySourceCodeGenerator.java
  6. 234
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/support/processor/MathFormula.java
  7. 4
      io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/function/ArithmeticFunction.java
  8. 1
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/groovy.ftl
  9. 2
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/lib/lib.ftl
  10. 2
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/lib_groovy.ftl
  11. 2
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/model/model.ftl
  12. 4
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/MATH_FORMULA.ftl
  13. 2
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_tw_CN.properties
  14. 2
      io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_zh_CN.properties
  15. 2
      io.sc.engine.rule.frontend/package.json
  16. 2
      io.sc.engine.rule.frontend/src/components/index.ts
  17. 1
      io.sc.engine.rule.frontend/src/i18n/messages.json
  18. 1
      io.sc.engine.rule.frontend/src/i18n/messages_tw_CN.json
  19. 1
      io.sc.engine.rule.frontend/src/i18n/messages_zh_CN.json
  20. 6
      io.sc.engine.rule.frontend/src/menus/menus.json
  21. 15
      io.sc.engine.rule.frontend/src/routes/routes.json
  22. 4
      io.sc.engine.rule.frontend/src/views/functions/Functions.vue
  23. 4
      io.sc.engine.rule.frontend/src/views/lib/ProcessorGrid.vue
  24. 9
      io.sc.engine.rule.frontend/src/views/resources/designer/Processor.vue
  25. 1
      io.sc.engine.rule.server/build.gradle
  26. 17
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/testcase/service/impl/TestCaseServiceImpl.java
  27. 13
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/testcase/support/CellStyleBuilder.java
  28. 2227
      io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/引擎示例.json
  29. 2
      io.sc.engine.st.frontend/package.json
  30. 1
      io.sc.platform.core.frontend/src/platform/components/form/WForm.vue
  31. 92
      io.sc.platform.core.frontend/src/platform/components/math/context-menu/ContextMenu.vue
  32. 3
      io.sc.platform.core.frontend/src/platform/components/math/dialog/NumberEditorDialog.vue
  33. 2
      io.sc.platform.core.frontend/src/platform/components/math/dialog/VariableEditorDialog.vue
  34. 24
      io.sc.platform.core.frontend/src/platform/components/math/dialog/XmlDialog.vue
  35. 4
      io.sc.platform.core.frontend/src/platform/components/math/toolbar/Toolbar.vue
  36. 2
      io.sc.platform.core.frontend/src/platform/components/math/toolbar/actions/Xml.vue
  37. 2
      io.sc.platform.core.frontend/src/platform/components/math/toolbar/base/Addition.vue
  38. 6
      io.sc.platform.core.frontend/src/platform/components/math/toolbar/base/NumberConst.vue
  39. 7
      io.sc.platform.core.frontend/src/platform/i18n/messages.json
  40. 7
      io.sc.platform.core.frontend/src/platform/i18n/messages_tw_CN.json
  41. 7
      io.sc.platform.core.frontend/src/platform/i18n/messages_zh_CN.json
  42. 4
      io.sc.platform.core.frontend/template-project/package.json
  43. 170
      io.sc.platform.core.frontend/template-project/src/views/testcase/math/AutoCompletionManager.ts
  44. 15
      io.sc.platform.core.frontend/template-project/src/views/testcase/math/MathEditor.vue
  45. 2
      io.sc.platform.developer.frontend/package.json
  46. 2
      io.sc.platform.gradle/templates/pgp/setup/gradle.properties
  47. 2
      io.sc.platform.lcdp.frontend/package.json
  48. 1
      io.sc.platform.monitor/src/main/java/io/sc/platform/monitor/service/impl/SystemMonitorImpl.java
  49. 18
      io.sc.platform.monitor/src/main/java/io/sc/platform/monitor/service/support/ServerInfo.java
  50. 2
      io.sc.platform.mvc.frontend/package.json
  51. 2
      io.sc.platform.security.frontend/package.json
  52. 2
      io.sc.platform.system.frontend/package.json
  53. 24
      io.sc.platform.system.frontend/src/i18n/messages.json
  54. 24
      io.sc.platform.system.frontend/src/i18n/messages_tw_CN.json
  55. 2
      io.sc.platform.system.frontend/src/i18n/messages_zh_CN.json
  56. 50
      io.sc.platform.system.frontend/src/views/monitor/ServerInfo.vue
  57. 5
      io.sc.platform.system/src/main/java/io/sc/platform/system/auditlog/service/AuditLogService.java
  58. 28
      io.sc.platform.system/src/main/java/io/sc/platform/system/auditlog/service/impl/AuditLogServiceImpl.java
  59. 7
      io.sc.platform.system/src/main/java/io/sc/platform/system/monitor/controller/MetricsWebController.java
  60. 2
      io.sc.standard.frontend/package.json

2
app.platform/build-common.gradle

@ -6,7 +6,7 @@
* 2. gradle bootwar -Dtarget=undertow # undertow, target=undertow
* 3. gradle bootwar -Dtarget=jetty # jetty, target=jetty
*/
def target =System.getProperty("target") ?: "undertow";
def target =System.getProperty("target") ?: "tomcat";
System.setProperty('target',target);
// targetRuntime build.gradle

2
erm.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.275",
"platform-core": "8.1.279",
"quasar": "2.15.4",
"tailwindcss": "3.4.4",
"vue": "3.4.31",

2
gradle.properties

@ -38,7 +38,7 @@ application_version=1.0.0
platform_group=io.sc
platform_version=8.1.44
platform_plugin_version=8.1.44
platform_core_frontend_version=8.1.275
platform_core_frontend_version=8.1.279
###########################################################
# dependencies version

2
io.sc.engine.mv.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.275",
"platform-core": "8.1.279",
"quasar": "2.15.4",
"tailwindcss": "3.4.4",
"vue": "3.4.31",

1
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/GroovySourceCodeGenerator.java

@ -87,6 +87,7 @@ public class GroovySourceCodeGenerator implements CodeGenerator{
root.put("ValueType", getStaticMethod("io.sc.engine.rule.core.enums.ValueType"));
root.put("ObjectProperty", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.ObjectProperty"));
root.put("MathFormula", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.MathFormula"));
root.put("ConditionRange", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.ConditionRange"));
root.put("NumberRange", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.NumberRange"));
root.put("DecisionTable2C", getStaticMethod("io.sc.engine.rule.core.code.impl.support.processor.DecisionTable2C"));

234
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/code/impl/support/processor/MathFormula.java

@ -6,6 +6,8 @@ import io.sc.engine.rule.core.po.lib.Indicator;
import io.sc.engine.rule.core.po.lib.processor.MathFormulaIndicatorProcessor;
import io.sc.engine.rule.core.po.model.Parameter;
import io.sc.engine.rule.core.po.model.processor.MathFormulaParameterProcessor;
import io.sc.engine.rule.core.util.CodeReplacer;
import io.sc.engine.rule.core.util.ExpressionReplacer;
import org.springframework.util.StringUtils;
import javax.xml.bind.JAXBContext;
@ -15,7 +17,6 @@ import javax.xml.stream.XMLEventReader;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamReader;
import javax.xml.stream.events.Characters;
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
import java.io.Reader;
@ -24,62 +25,132 @@ import java.util.ArrayDeque;
@JsonIgnoreProperties(ignoreUnknown=true)
public class MathFormula {
public static MathType parse(String xml) throws Exception {
if(!StringUtils.hasText(xml)){
public static String generateGroovyCode(Indicator indicator, MathFormulaIndicatorProcessor processor) throws Exception {
if (indicator == null || processor == null) {
return null;
}
Reader reader = new StringReader(xml);
XMLInputFactory factory = XMLInputFactory.newInstance(); // Or newFactory()
XMLStreamReader xmlReader = factory.createXMLStreamReader(reader);
JAXBContext decodeJAXBContext =JAXBContext.newInstance(MathType.class);
Unmarshaller unmarshaller =decodeJAXBContext.createUnmarshaller();
JAXBElement<MathType> obj =unmarshaller.unmarshal(xmlReader,MathType.class);
return obj.getValue();
String mathXml =processor.getMathFormula();
if(!StringUtils.hasText(mathXml)){
return null;
}
mathXml =mathXml.trim();
if(!mathXml.startsWith("<math>") && !mathXml.endsWith("</math>")){
mathXml ="<math>" + mathXml + "</math>";
}
return ExpressionReplacer.groovy(buildGroovyCode(mathXml),null);
}
public static String generateGroovyCode(Indicator indicator, MathFormulaIndicatorProcessor processor) throws Exception {
if (indicator == null || processor == null) {
public static String generateGroovyCode(Parameter parameter, MathFormulaParameterProcessor processor) throws Exception{
if (parameter == null || processor == null) {
return null;
}
String xml =processor.getMathFormula();
if(!StringUtils.hasText(xml)){
String mathXml =processor.getMathFormula();
if(!StringUtils.hasText(mathXml)){
return null;
}
Reader reader = new StringReader(xml);
mathXml =mathXml.trim();
if(!mathXml.startsWith("<math>") && !mathXml.endsWith("</math>")){
mathXml ="<math>" + mathXml + "</math>";
}
return ExpressionReplacer.groovy(buildGroovyCode(mathXml),null);
}
private static String buildGroovyCode(String mathXml) throws Exception{
Reader reader = new StringReader(mathXml);
XMLInputFactory xmlInputFactory =XMLInputFactory.newFactory();
XMLEventReader xmlEventReader =xmlInputFactory.createXMLEventReader(reader);
StringBuilder sb =new StringBuilder();
ArrayDeque<String> tagNameDeque =new ArrayDeque<>();
while(xmlEventReader.hasNext()){
XMLEvent xmlEvent = xmlEventReader.nextEvent();
if (xmlEvent.isStartElement()){
StartElement startElement = xmlEvent.asStartElement();
if("mi".equalsIgnoreCase(startElement.getName().getLocalPart())){
String tagName =startElement.getName().getLocalPart();
tagNameDeque.push(tagName);
if("mspace".equalsIgnoreCase(tagName)){
}else if("mrow".equalsIgnoreCase(tagName)){
sb.append("(");
}else if("msqrt".equalsIgnoreCase(tagName)){
sb.append("sqrt(");
}else if("mroot".equalsIgnoreCase(tagName)){
sb.append("root(");
}else if("msup".equalsIgnoreCase(tagName)){
sb.append("pow(");
}else if("mfrac".equalsIgnoreCase(tagName)){
sb.append("div(");
}
} else if(xmlEvent.isCharacters()){
Characters characters = xmlEvent.asCharacters();
sb.append(characters.getData());
} else if(xmlEvent.isEndElement()){
EndElement endElement =xmlEvent.asEndElement();
if("mi".equalsIgnoreCase(endElement.getName().getLocalPart())) {
String text =characters.getData().trim();
String tagName =tagNameDeque.peek();
if("mi".equalsIgnoreCase(tagName)){
if("(".equalsIgnoreCase(text) || ")".equalsIgnoreCase(text)){
sb.append(text);
}else{
sb.append("${").append(text);
}
}else if("mo".equalsIgnoreCase(tagName)){
if("×".equalsIgnoreCase(text)){
sb.append("*");
}else if("≥".equalsIgnoreCase(text)){
sb.append(">=");
}else if("≤".equalsIgnoreCase(text)){
sb.append("<=");
}else if("=".equalsIgnoreCase(text)){
sb.append("==");
}else{
sb.append(text);
}
}else if("mn".equalsIgnoreCase(tagName)){
if("e".equalsIgnoreCase(text)){
sb.append("E");
}else if("π".equalsIgnoreCase(text)){
sb.append("PI");
}else{
sb.append(text);
}
return sb.toString();
}else{
sb.append(text);
}
} else if(xmlEvent.isEndElement()) {
String tagName = tagNameDeque.poll();
String previousTagName =tagNameDeque.peek();
if("mspace".equalsIgnoreCase(tagName)){
public static String generateGroovyCode(Parameter parameter, MathFormulaParameterProcessor processor) throws Exception{
if (parameter == null || processor == null) {
return null;
}else if("mi".equalsIgnoreCase(tagName)){
String lastText =sb.substring(sb.length()-1);
if("(".equalsIgnoreCase(lastText) || ")".equalsIgnoreCase(lastText)){
}else{
sb.append("}");
}
MathType math =parse(processor.getMathFormula());
if(math==null){
return null;
}else if("mrow".equalsIgnoreCase(tagName)){
sb.append(")");
if(
"msqrt".equalsIgnoreCase(previousTagName) ||
"mroot".equalsIgnoreCase(previousTagName) ||
"msup".equalsIgnoreCase(previousTagName) ||
"mfrac".equalsIgnoreCase(previousTagName)
){
sb.append(",");
}
return null;
}else if("msqrt".equalsIgnoreCase(tagName)){
sb.setLength(sb.length()-1);
sb.append(")");
}else if("mroot".equalsIgnoreCase(tagName)){
sb.setLength(sb.length()-1);
sb.append(")");
}else if("msup".equalsIgnoreCase(tagName)){
sb.setLength(sb.length()-1);
sb.append(")");
}else if("mfrac".equalsIgnoreCase(tagName)){
sb.setLength(sb.length()-1);
sb.append(")");
}
}
}
return sb.toString();
}
public static void main(String[] args)throws Exception {
@ -145,104 +216,7 @@ public class MathFormula {
" <mn>50</mn>\n" +
" <mspace/>\n" +
"</math>";
Reader reader = new StringReader(xml);
XMLInputFactory xmlInputFactory =XMLInputFactory.newFactory();
XMLEventReader xmlEventReader =xmlInputFactory.createXMLEventReader(reader);
StringBuilder sb =new StringBuilder();
ArrayDeque<String> deque =new ArrayDeque<>();
ArrayDeque<Boolean> twoPartDeque =new ArrayDeque<>();
while(xmlEventReader.hasNext()){
XMLEvent xmlEvent = xmlEventReader.nextEvent();
if (xmlEvent.isStartElement()){
StartElement startElement = xmlEvent.asStartElement();
deque.push(startElement.getName().getLocalPart());
String tagName =deque.peek();
switch (tagName){
case "mspace":
break;
case "mrow":
sb.append("(");
break;
case "mfrac":
twoPartDeque.push(true);
break;
case "msqrt":
sb.append("sqrt(");
break;
case "mroot":
twoPartDeque.push(true);
sb.append("root(");
break;
case "msup":
twoPartDeque.push(true);
sb.append("pow(");
break;
}
} else if(xmlEvent.isCharacters()){
String tagName =deque.peek();
Characters characters = xmlEvent.asCharacters();
String text =characters.getData().trim();
switch (tagName){
case "mi":
sb.append("${").append(text);
break;
case "mo":
switch (text){
case "×":
sb.append("*");
break;
case "≥":
sb.append(">=");
break;
case "≤":
sb.append("<=");
break;
case "=":
sb.append("==");
break;
default:
sb.append(text);
}
break;
case "mn":
sb.append(text);
break;
}
} else if(xmlEvent.isEndElement()) {
EndElement endElement = xmlEvent.asEndElement();
String tagName = deque.peek();
deque.pop();
switch (tagName) {
case "mi":
sb.append("}");
break;
case "mspace":
break;
case "mrow":
sb.append(")");
if (twoPartDeque.peek()!=null && twoPartDeque.peek() && deque.peek()!=null) {
switch (deque.peek()){
case "mfrac":
sb.append("/");
break;
case "mroot":
case "msup":
sb.append(",");
break;
}
twoPartDeque.pop();
}
break;
case "mfrac":
break;
case "msqrt":
case "mroot":
case "msup":
sb.append(")");
break;
}
}
}
System.out.println(sb.toString());
System.out.println(MathFormula.buildGroovyCode(xml));
}
}

4
io.sc.engine.rule.core/src/main/java/io/sc/engine/rule/core/function/ArithmeticFunction.java

@ -144,4 +144,8 @@ public class ArithmeticFunction {
public static Double root(Double x,Double y){
return Math.pow(x,1/y);
}
public static Double div(Double x, Double y){
return x/y;
}
}

1
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/groovy.ftl

@ -73,6 +73,7 @@ import static io.sc.engine.rule.core.function.ArithmeticFunction.log;
import static io.sc.engine.rule.core.function.ArithmeticFunction.ln;
import static io.sc.engine.rule.core.function.ArithmeticFunction.lg;
import static io.sc.engine.rule.core.function.ArithmeticFunction.root;
import static io.sc.engine.rule.core.function.ArithmeticFunction.div;
import static io.sc.engine.rule.core.function.ArithmeticFunction.transformSequencing;
import static io.sc.engine.rule.core.function.DateFunction.now;

2
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/lib/lib.ftl

@ -80,6 +80,8 @@ class ${CodeReplacer.className(lib.code,lib.version)}{
<#include "/processor/OBJECT_PROPERTIES.ftl"/>
<#elseif "OPTION_VALUE"==(processor.type)!>
<#include "/processor/OPTION_VALUE.ftl"/>
<#elseif "MATH_FORMULA"==(processor.type)!>
<#include "/processor/MATH_FORMULA.ftl"/>
<#elseif "ARITHMETIC"==(processor.type)!>
<#include "/processor/ARITHMETIC.ftl"/>
<#elseif "TERNARY"==(processor.type)!>

2
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/lib_groovy.ftl

@ -72,6 +72,8 @@ class ${CodeReplacer.className(lib.code,lib.version)}{
<#include "/processor/OBJECT_PROPERTIES.ftl"/>
<#elseif "OPTION_VALUE"==(processor.type)!>
<#include "/processor/OPTION_VALUE.ftl"/>
<#elseif "MATH_FORMULA"==(processor.type)!>
<#include "/processor/MATH_FORMULA.ftl"/>
<#elseif "ARITHMETIC"==(processor.type)!>
<#include "/processor/ARITHMETIC.ftl"/>
<#elseif "TERNARY"==(processor.type)!>

2
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/model/model.ftl

@ -169,6 +169,8 @@ class ${CodeReplacer.className(resource.code,resource.version)} {
<#include "/processor/OBJECT_PROPERTIES.ftl"/>
<#elseif "OPTION_VALUE"==(processor.type)!>
<#include "/processor/OPTION_VALUE.ftl"/>
<#elseif "MATH_FORMULA"==(processor.type)!>
<#include "/processor/MATH_FORMULA.ftl"/>
<#elseif "ARITHMETIC"==(processor.type)!>
<#include "/processor/ARITHMETIC.ftl"/>
<#elseif "TERNARY"==(processor.type)!>

4
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/code/template/groovy/processor/MATH_FORMULA.ftl

@ -0,0 +1,4 @@
//数学公式
${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)} =${MathFormula.generateGroovyCode(parameter,processor)};
if(log.isDebugEnabled()){log.debug(" 数学公式运算结果 : {}",${ExpressionReplacer.ARGUMENT_NAME}.${CodeReplacer.fieldName(parameter.code)});}

2
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_tw_CN.properties

@ -47,7 +47,7 @@ io.sc.engine.rule.core.enums.ParameterType.CONSTANT=\u5E38\u91CF
# \u5904\u7406\u5668\u7C7B\u578B\u679A\u4E3E
#================================================
io.sc.engine.rule.core.enums.ProcessorType.EMPTY=\u7A7A
io.sc.engine.rule.core.enums.ProcessorType.OBJECT_PROPERTIES=\u5C0D\u8C61\u5C6C\u6027
io.sc.engine.rule.core.enums.ProcessorType.OBJECT_PROPERTIES=\u5C0D\u8C61\u5C6C\u6027\u8CE6\u503C
io.sc.engine.rule.core.enums.ProcessorType.OPTION_VALUE=\u9078\u9805\u503C
io.sc.engine.rule.core.enums.ProcessorType.MATH_FORMULA=\u6578\u5B78\u516C\u5F0F
io.sc.engine.rule.core.enums.ProcessorType.ARITHMETIC=\u7B97\u6578\u904B\u7B97

2
io.sc.engine.rule.core/src/main/resources/io/sc/engine/rule/core/i18n/enums_zh_CN.properties

@ -47,7 +47,7 @@ io.sc.engine.rule.core.enums.ParameterType.CONSTANT=\u5E38\u91CF
# \u5904\u7406\u5668\u7C7B\u578B\u679A\u4E3E
#================================================
io.sc.engine.rule.core.enums.ProcessorType.EMPTY=\u7A7A
io.sc.engine.rule.core.enums.ProcessorType.OBJECT_PROPERTIES=\u5BF9\u8C61\u5C5E\u6027
io.sc.engine.rule.core.enums.ProcessorType.OBJECT_PROPERTIES=\u5BF9\u8C61\u5C5E\u6027\u8D4B\u503C
io.sc.engine.rule.core.enums.ProcessorType.OPTION_VALUE=\u9009\u9879\u503C
io.sc.engine.rule.core.enums.ProcessorType.MATH_FORMULA=\u6570\u5B66\u516C\u5F0F
io.sc.engine.rule.core.enums.ProcessorType.ARITHMETIC=\u7B97\u6570\u8FD0\u7B97

2
io.sc.engine.rule.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.275",
"platform-core": "8.1.279",
"quasar": "2.15.4",
"tailwindcss": "3.4.4",
"vue": "3.4.31",

2
io.sc.engine.rule.frontend/src/components/index.ts

@ -8,6 +8,7 @@ import component_engine_rule_authorization from '@/views/authorization/Authoriza
import component_engine_rule_workflow from '@/views/workflow/Workflow.vue';
import component_engine_rule_dictionary from '@/views/dictionary/Dictionary.vue';
import component_engine_rule_lib from '@/views/lib/Lib.vue';
import component_engine_rule_functions from '@/views/functions/Functions.vue';
import component_engine_rule_testcase from '@/views/testcase/Testcase.vue';
import component_engine_rule_migration from '@/views/migration/Migration.vue';
@ -18,6 +19,7 @@ const localComponents = {
'component.engine.rule.workflow': component_engine_rule_workflow,
'component.engine.rule.dictionary': component_engine_rule_dictionary,
'component.engine.rule.lib': component_engine_rule_lib,
'component.engine.rule.functions': component_engine_rule_functions,
'component.engine.rule.testcase': component_engine_rule_testcase,
'component.engine.rule.migration': component_engine_rule_migration,
};

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

@ -5,6 +5,7 @@
"menu.engine.rule.workflow": "Workflow",
"menu.engine.rule.dictionary": "Meta Data Manager",
"menu.engine.rule.lib": "Feature Library Manager",
"menu.engine.rule.functions": "Function Library",
"menu.engine.rule.testcase": "Test Case Manager",
"menu.engine.rule.migration": "Data Back and Migration",

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

@ -5,6 +5,7 @@
"menu.engine.rule.workflow": "流程審批",
"menu.engine.rule.dictionary": "元數據管理",
"menu.engine.rule.lib": "特征庫管理",
"menu.engine.rule.functions": "函數庫",
"menu.engine.rule.testcase": "試算用例",
"menu.engine.rule.migration": "數據備份和遷移",

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

@ -5,6 +5,7 @@
"menu.engine.rule.workflow": "流程审批",
"menu.engine.rule.dictionary": "元数据管理",
"menu.engine.rule.lib": "特征库管理",
"menu.engine.rule.functions": "函数库",
"menu.engine.rule.testcase": "试算用例管理",
"menu.engine.rule.migration": "数据备份和迁移",

6
io.sc.engine.rule.frontend/src/menus/menus.json

@ -29,9 +29,11 @@
{"type":"ROUTE", "order":400, "parentId":"menu.engine.rule", "id":"menu.engine.rule.dictionary", "titleI18nKey":"menu.engine.rule.dictionary", "icon":"bi-list-ol", "routeName":"route.engine.rule.dictionary"},
/*/*/
{"type":"ROUTE", "order":500, "parentId":"menu.engine.rule", "id":"menu.engine.rule.lib", "titleI18nKey":"menu.engine.rule.lib", "icon":"bi-folder2", "routeName":"route.engine.rule.lib"},
/*/*/
{"type":"ROUTE", "order":600, "parentId":"menu.engine.rule", "id":"menu.engine.rule.functions", "titleI18nKey":"menu.engine.rule.functions", "icon":"bi-folder2", "routeName":"route.engine.rule.functions"},
/*/*/
{"type":"ROUTE", "order":600, "parentId":"menu.engine.rule", "id":"menu.engine.rule.testcase", "titleI18nKey":"menu.engine.rule.testcase", "icon":"bi-suitcase-lg", "routeName":"route.engine.rule.testcase"},
{"type":"ROUTE", "order":700, "parentId":"menu.engine.rule", "id":"menu.engine.rule.testcase", "titleI18nKey":"menu.engine.rule.testcase", "icon":"bi-suitcase-lg", "routeName":"route.engine.rule.testcase"},
/*/*/
{"type":"ROUTE", "order":700, "parentId":"menu.engine.rule", "id":"menu.engine.rule.migration", "titleI18nKey":"menu.engine.rule.migration", "icon":"bi-share", "routeName":"route.engine.rule.migration"}
{"type":"ROUTE", "order":800, "parentId":"menu.engine.rule", "id":"menu.engine.rule.migration", "titleI18nKey":"menu.engine.rule.migration", "icon":"bi-share", "routeName":"route.engine.rule.migration"}
]

15
io.sc.engine.rule.frontend/src/routes/routes.json

@ -90,6 +90,21 @@
]
}
},
{
"name": "route.engine.rule.functions",
"path": "re/functions",
"parent": "/",
"priority": 0,
"module": "io.sc.engine.rule.frontend",
"component": "component.engine.rule.functions",
"componentPath": "@/views/functions/Functions.vue",
"redirect": null,
"meta": {
"permissions": [
"/re/functions/**/*"
]
}
},
{
"name": "route.engine.rule.testcase",
"path": "re/testcase",

4
io.sc.engine.rule.frontend/src/views/functions/Functions.vue

@ -0,0 +1,4 @@
<template>
<div>functions</div>
</template>
<script setup lang="ts"></script>

4
io.sc.engine.rule.frontend/src/views/lib/ProcessorGrid.vue

@ -453,7 +453,8 @@
colSpan: 5,
name: 'mathFormula',
label: $t('re.resources.designer.processor.grid.entity.mathFormula'),
type: 'expression',
type: 'math',
autoCompletion: autoCompletion,
showIf: (arg) => {
return 'MATH_FORMULA' === arg.form.getFieldValue('type');
},
@ -580,6 +581,7 @@
return 'NUMBER_RANGE' === arg.form.getFieldValue('type');
},
type: 'w-grid',
dbClickOperation: 'edit',
height: 300,
denseBody: true,
draggable: true,

9
io.sc.engine.rule.frontend/src/views/resources/designer/Processor.vue

@ -333,7 +333,7 @@
return row.optionCode;
} else if ('MATH_FORMULA' === type) {
return {
componentType: 'w-expression',
componentType: 'w-math',
attrs: {
modelValue: row.mathFormula,
readOnly: true,
@ -595,7 +595,8 @@
colSpan: 5,
name: 'mathFormula',
label: $t('re.resources.designer.processor.grid.entity.mathFormula'),
type: 'expression',
type: 'math',
autoCompletion: autoCompletion,
showIf: (arg) => {
return 'MATH_FORMULA' === arg.form.getFieldValue('type');
},
@ -803,9 +804,9 @@
colsNum: 4,
fields: [
{ name: 'uuid', label: 'uuid', hidden: true, colSpan: 4 },
{ name: 'min', label: $t('minValue'), type: 'number', colSpan: 3 },
{ name: 'min', label: $t('minValue'), type: 'text', colSpan: 3 },
{ name: 'minIncluded', label: $t('include'), type: 'checkbox' },
{ name: 'max', label: $t('maxValue'), type: 'number', colSpan: 3 },
{ name: 'max', label: $t('maxValue'), type: 'text', colSpan: 3 },
{ name: 'maxIncluded', label: $t('include'), type: 'checkbox' },
{ name: 'value', label: $t('value'), type: 'number', colSpan: 3 },
],

1
io.sc.engine.rule.server/build.gradle

@ -16,6 +16,7 @@ dependencies {
"org.webjars:org.webjars.codemirror:5.37.0",
"org.webjars:org.webjars.mxgraph:3.9.12",
"org.webjars:org.webjars.jquery:1.12.4",
"org.webjars:org.webjars.mathfonts:1.0.0",
)
}

17
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/testcase/service/impl/TestCaseServiceImpl.java

@ -1,12 +1,9 @@
package io.sc.engine.rule.server.testcase.service.impl;
import io.sc.engine.rule.client.Executor;
import io.sc.engine.rule.client.runtime.EngineRuntime;
import io.sc.engine.rule.client.runtime.impl.groovy.GroovyScriptEngineService;
import io.sc.engine.rule.client.runtime.impl.groovy.GroovyScriptEngineServiceImpl;
import io.sc.engine.rule.client.runtime.impl.groovy.GroovyScriptExecutor;
import io.sc.engine.rule.client.spring.service.ExecutorFactoryService;
import io.sc.engine.rule.core.code.CodeGenerator;
import io.sc.engine.rule.core.code.SourceCode;
import io.sc.engine.rule.core.code.impl.GroovySourceCodeGenerator;
import io.sc.engine.rule.core.code.impl.support.ParameterResult;
@ -48,11 +45,13 @@ import io.sc.engine.rule.server.testcase.support.CellStyleBuilder;
import io.sc.engine.rule.server.testcase.wrapper.Option;
import io.sc.engine.rule.server.testcase.wrapper.TestCaseParameterWrapper;
import io.sc.engine.rule.server.testcase.wrapper.TestCaseWrapper;
import io.sc.platform.core.Environment;
import io.sc.platform.orm.service.impl.DaoServiceImpl;
import io.sc.platform.orm.service.support.CriteriaBuilder;
import io.sc.platform.orm.service.support.QueryParameter;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.ss.util.CellRangeAddressList;
import org.apache.poi.xssf.usermodel.*;
@ -315,6 +314,7 @@ public class TestCaseServiceImpl extends DaoServiceImpl<TestCaseEntity, String,
wrappers.addAll(outputs);
XSSFWorkbook workbook = new XSSFWorkbook();
XSSFDataFormat dataFormat = workbook.createDataFormat();
XSSFSheet sheet = workbook.createSheet();
CellStyleBuilder styleBuilder =new CellStyleBuilder(workbook);
@ -460,7 +460,7 @@ public class TestCaseServiceImpl extends DaoServiceImpl<TestCaseEntity, String,
XSSFDataValidationHelper helper = new XSSFDataValidationHelper(sheet);
XSSFDataValidationConstraint constraint = (XSSFDataValidationConstraint)helper.createExplicitListConstraint(optionStrings.toArray(new String[]{}));
//参数顺序:开始行、结束行、开始列、结束列
CellRangeAddressList addressList = new CellRangeAddressList(rowIndex+1,200,colIndex-1,colIndex-1);
CellRangeAddressList addressList = new CellRangeAddressList(rowIndex+1,1000,colIndex-1,colIndex-1);
XSSFDataValidation validation = (XSSFDataValidation)helper.createValidation(constraint, addressList);
validation.setSuppressDropDownArrow(true);
validation.setShowErrorBox(true);
@ -470,6 +470,11 @@ public class TestCaseServiceImpl extends DaoServiceImpl<TestCaseEntity, String,
try{
String typeName =messageSource.getMessage(wrapper.getValueType(), null, locale);
cell.setCellValue(typeName);
if("java.lang.String".equalsIgnoreCase(wrapper.getValueType())){
XSSFCellStyle textStyle =workbook.createCellStyle();
textStyle.setDataFormat(dataFormat.getFormat("TEXT"));
sheet.setDefaultColumnStyle(colIndex-1,textStyle);
}
}catch (Exception e) {
cell.setCellValue(wrapper.getValueType());
}

13
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/testcase/support/CellStyleBuilder.java

@ -2,6 +2,7 @@ package io.sc.engine.rule.server.testcase.support;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFDataFormat;
import org.apache.poi.xssf.usermodel.XSSFFont;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.util.StringUtils;
@ -14,6 +15,7 @@ public class CellStyleBuilder {
private IndexedColors color;
private boolean border =false;
private boolean wrap =true;
private String dataFormat;
public CellStyleBuilder(XSSFWorkbook workbook){
this.workbook =workbook;
@ -60,6 +62,12 @@ public class CellStyleBuilder {
// wrap
style.setWrapText(wrap);
// data format
if(dataFormat!=null) {
XSSFDataFormat format = workbook.createDataFormat();
style.setDataFormat(format.getFormat(dataFormat));
}
return style;
}
@ -108,4 +116,9 @@ public class CellStyleBuilder {
this.wrap =false;
return this;
}
public CellStyleBuilder dataFormat(String dataFormat){
this.dataFormat =dataFormat;
return this;
}
}

2227
io.sc.engine.rule.server/src/main/resources/io/sc/engine/rule/server/sample/引擎示例.json

File diff suppressed because one or more lines are too long

2
io.sc.engine.st.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.275",
"platform-core": "8.1.279",
"quasar": "2.15.4",
"tailwindcss": "3.4.4",
"vue": "3.4.31",

1
io.sc.platform.core.frontend/src/platform/components/form/WForm.vue

@ -106,6 +106,7 @@ const fiedType = {
optionGroup: 'w-option-group',
file: 'w-file',
expression: 'w-expression',
math: 'w-math',
};
const defaultValueHandler = (field) => {

92
io.sc.platform.core.frontend/src/platform/components/math/context-menu/ContextMenu.vue

@ -1,6 +1,33 @@
<template>
<q-menu ref="contextMenuRef" context-menu>
<q-list dense style="min-width: 100px">
<q-item v-if="targetElementTagName === 'mi'" v-close-popup clickable @click="miTomn">
<q-item-section>{{ $t('math.contextMenu.miTomn') }}</q-item-section>
</q-item>
<q-item v-if="targetElementTagName === 'mn'" v-close-popup clickable @click="mnTomi">
<q-item-section>{{ $t('math.contextMenu.mnTomi') }}</q-item-section>
</q-item>
<q-separator v-if="targetElementTagName === 'mn'" inset spaced />
<q-item v-if="targetElementTagName === 'mn'" v-close-popup clickable @click="mnTo0">
<q-item-section>{{ $t('math.contextMenu.mnTo0') }}</q-item-section>
</q-item>
<q-item v-if="targetElementTagName === 'mn'" v-close-popup clickable @click="mnTo1">
<q-item-section>{{ $t('math.contextMenu.mnTo1') }}</q-item-section>
</q-item>
<q-separator v-if="targetElementTagName === 'mi' || targetElementTagName === 'mn'" inset spaced />
<q-item v-close-popup clickable @click="copy">
<q-item-section>{{ $t('copy') }}</q-item-section>
</q-item>
<q-item v-close-popup clickable @click="paste">
<q-item-section>{{ $t('paste') }}</q-item-section>
</q-item>
<q-item v-close-popup clickable @click="cut">
<q-item-section>{{ $t('cut') }}</q-item-section>
</q-item>
<q-item v-close-popup clickable @click="remove">
<q-item-section>{{ $t('delete') }}</q-item-section>
</q-item>
@ -9,30 +36,83 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { copyToClipboard } from 'quasar';
const emit = defineEmits(['changed']);
const contextMenuRef = ref();
let targetElement = null;
const targetElementRef = ref();
const targetElementTagName = ref();
const show = (element) => {
targetElement = element;
targetElementRef.value = element;
targetElementTagName.value = element.tagName;
contextMenuRef.value.show();
};
const remove = (element) => {
if (targetElement) {
const previous = targetElement.previousElementSibling;
if (targetElementRef.value) {
const previous = targetElementRef.value.previousElementSibling;
if (previous?.tagName === 'mspace') {
previous.outerHTML = '';
}
const next = targetElement.nextElementSibling;
const next = targetElementRef.value.nextElementSibling;
if (next?.tagName === 'mspace') {
next.outerHTML = '';
}
targetElement.outerHTML = '<mspace></mspace>';
targetElementRef.value.outerHTML = '<mspace></mspace>';
emit('changed');
}
};
const miTomn = () => {
if (targetElementRef.value) {
targetElementRef.value.outerHTML = '<mn>n</mn>';
emit('changed');
}
};
const mnTomi = () => {
if (targetElementRef.value) {
targetElementRef.value.outerHTML = '<mi>x</mi>';
emit('changed');
}
};
const mnTo0 = () => {
if (targetElementRef.value) {
targetElementRef.value.outerHTML = '<mn>0</mn>';
emit('changed');
}
};
const mnTo1 = () => {
if (targetElementRef.value) {
targetElementRef.value.outerHTML = '<mn>1</mn>';
emit('changed');
}
};
const copy = () => {
copyToClipboard(targetElementRef.value.outerHTML);
};
const paste = () => {
window.navigator.clipboard.readText().then((text) => {
console.log(text);
targetElementRef.value.outerHTML = text;
emit('changed');
});
};
const cut = () => {
copyToClipboard(targetElementRef.value.outerHTML);
if (targetElementRef.value.tagName === 'mrow') {
targetElementRef.value.innerHTML = '<mspace/>';
} else {
remove(targetElementRef.value);
}
emit('changed');
};
defineExpose({

3
io.sc.platform.core.frontend/src/platform/components/math/dialog/NumberEditorDialog.vue

@ -9,7 +9,8 @@
label: $t('confirm'),
noCaps: true,
click: () => {
targetElementRef.innerHTML = modelValueRef;
let string = modelValueRef;
targetElementRef.innerHTML = string.trim();
emit('changed');
close();
},

2
io.sc.platform.core.frontend/src/platform/components/math/dialog/VariableEditorDialog.vue

@ -11,7 +11,7 @@
click: () => {
let string = modelValueRef;
string = string.replace(/\$\{(.+?)\}/g, '$1');
targetElementRef.innerHTML = string;
targetElementRef.innerHTML = string.trim();
emit('changed');
close();
},

24
io.sc.platform.core.frontend/src/platform/components/math/dialog/XmlDialog.vue

@ -1,7 +1,22 @@
<template>
<w-dialog ref="dialogRef" :title="$t('xml')" width="800px" :can-maximize="false">
<w-dialog
ref="dialogRef"
:title="$t('xml')"
width="800px"
:can-maximize="false"
:buttons="[
{
label: $t('confirm'),
noCaps: true,
click: () => {
modelValueRef = xmlRef;
close();
},
},
]"
>
<div class="py-1"></div>
<w-code-mirror v-model="xmlRef" outlined :rows="20" lang="xml" line-number />
<w-code-mirror v-model="xmlRef" outlined :rows="20" lang="xml" line-number :toolbar="false" />
</w-dialog>
</template>
<script setup lang="ts">
@ -30,7 +45,12 @@ const open = () => {
dialogRef.value.show();
};
const close = () => {
dialogRef.value.hide();
};
defineExpose({
open,
close,
});
</script>

4
io.sc.platform.core.frontend/src/platform/components/math/toolbar/Toolbar.vue

@ -27,7 +27,7 @@
<q-separator vertical />
<!-- 数学 -->
<q-btn :label="$t('math.toolbar.math')" stretch flat dense padding="0px 10px" icon-right="arrow_drop_down">
<q-btn :label="$t('math.toolbar.math')" stretch flat dense no-caps padding="0px 10px" icon-right="arrow_drop_down">
<q-menu>
<q-list dense>
<q-item v-close-popup clickable>
@ -68,7 +68,7 @@
</q-btn>
<!-- 函数 -->
<q-btn :label="$t('math.toolbar.functions')" stretch flat dense padding="0px 10px" icon-right="arrow_drop_down">
<q-btn :label="$t('math.toolbar.functions')" stretch flat dense no-caps padding="0px 10px" icon-right="arrow_drop_down">
<q-menu>
<q-list>
<!-- 特殊值值处理函数 -->

2
io.sc.platform.core.frontend/src/platform/components/math/toolbar/actions/Xml.vue

@ -4,7 +4,7 @@
</template>
<script setup lang="ts">
import { ref } from 'vue';
import XmlDialog from '@/platform/components/expression/dialog/XmlDialog.vue';
import XmlDialog from '@/platform/components/math/dialog/XmlDialog.vue';
const modelValueRef = defineModel({ type: String, default: '' });

2
io.sc.platform.core.frontend/src/platform/components/math/toolbar/base/Addition.vue

@ -1,5 +1,5 @@
<template>
<q-btn :title="$t('math.toolbar.base.addition')" stretch flat size="16px" padding="0px 6px" draggable="true" @dragstart="dragstart" @click="append">
<q-btn :title="$t('math.toolbar.base.addition')" stretch flat no-caps size="16px" padding="0px 6px" draggable="true" @dragstart="dragstart" @click="append">
<math display="inline">
<mrow>
<mo>+</mo>

6
io.sc.platform.core.frontend/src/platform/components/math/toolbar/base/NumberConst.vue

@ -1,14 +1,14 @@
<template>
<q-btn :title="$t('math.toolbar.base.number')" stretch flat size="16px" padding="0px 10px" draggable="true" @dragstart="dragstart" @click="append">
<q-btn :title="$t('math.toolbar.base.number')" stretch flat no-caps size="16px" padding="0px 10px" draggable="true" @dragstart="dragstart" @click="append">
<math display="inline">
<mn>N</mn>
<mn>n</mn>
</math>
</q-btn>
</template>
<script setup lang="ts">
const xmlData = `
<mspace></mspace>
<mn>N</mn>
<mn>n</mn>
<mspace></mspace>
`;

7
io.sc.platform.core.frontend/src/platform/i18n/messages.json

@ -263,5 +263,10 @@
"math.toolbar.functions.formater.comma": "Thousandth place, leave the y digits after the x decimal point",
"math.toolbar.functions.formater.percent": "percentage, leave the y digits after the x decimal point",
"math.tools": "Tools"
"math.tools": "Tools",
"math.contextMenu.miTomn": "Variable -> Const",
"math.contextMenu.mnTomi": "Const -> Variable",
"math.contextMenu.mnTo0": "Set to 0",
"math.contextMenu.mnTo1": "Set to 1"
}

7
io.sc.platform.core.frontend/src/platform/i18n/messages_tw_CN.json

@ -263,5 +263,10 @@
"math.toolbar.functions.formater.comma": "千分位, 保留 x 小數點後 y 位",
"math.toolbar.functions.formater.percent": "百分數, 保留 x 小數點後 y 位",
"math.tools": "工具"
"math.tools": "工具",
"math.contextMenu.miTomn": "變量 -> 常量",
"math.contextMenu.mnTomi": "常量 -> 變量",
"math.contextMenu.mnTo0": "設置為 0",
"math.contextMenu.mnTo1": "設置為 1"
}

7
io.sc.platform.core.frontend/src/platform/i18n/messages_zh_CN.json

@ -263,5 +263,10 @@
"math.toolbar.functions.formater.comma": "千分位, 保留 x 小数点后 y 位",
"math.toolbar.functions.formater.percent": "百分数, 保留 x 小数点后 y 位",
"math.tools": "工具"
"math.tools": "工具",
"math.contextMenu.miTomn": "变量 -> 常量",
"math.contextMenu.mnTomi": "常量 -> 变量",
"math.contextMenu.mnTo0": "设置为 0",
"math.contextMenu.mnTo1": "设置为 1"
}

4
io.sc.platform.core.frontend/template-project/package.json

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.1.277",
"version": "8.1.279",
"description": "前端核心包,用于快速构建前端的脚手架",
"private": false,
"keywords": [],
@ -104,7 +104,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.277",
"platform-core": "8.1.279",
"quasar": "2.15.4",
"tailwindcss": "3.4.4",
"vue": "3.4.31",

170
io.sc.platform.core.frontend/template-project/src/views/testcase/math/AutoCompletionManager.ts

@ -0,0 +1,170 @@
import { Tools } from '@/platform';
class AutoCompletionManager {
parameters: object[];
valueTypes: object[];
public setParameters(parameters) {
this.parameters = parameters;
}
public setValueTypes(valueTypes) {
this.valueTypes = valueTypes;
}
public getOptions(path: string): any {
if (!path) {
return this.getParameterOptions();
}
if (path.endsWith('.')) {
path = path.substring(0, path.length - 1);
}
const names = path.split('.');
if (!names) {
return this.getParameterOptions();
}
//参数
const parameter = this.findParmeter(names[0]);
if (!parameter) {
return null;
}
const valueTypeString = parameter.valueType;
const valueTypeVersion = parameter.valueTypeVersion;
let valueType = this.findValueType(valueTypeString, valueTypeVersion);
if (!valueType || !valueType.properties || valueType.properties.length <= 0) {
return null;
}
let index = 1;
while (index < names.length) {
valueType = this.findValueTypeByProperty(valueType.code, valueType.version, names[index++]);
}
const options = [];
for (const property of valueType.properties) {
const propertyValueType = this.findValueType(property.valueType, property.valueTypeVersion);
if (!propertyValueType) {
continue;
}
const info = propertyValueType.version ? propertyValueType.name + '(V' + propertyValueType.version + ')' : propertyValueType.name;
options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', info: info });
}
return options;
}
public findParmeter(parameterName) {
for (const parameter of this.parameters) {
if (parameter.name === parameterName) {
return parameter;
}
}
return null;
}
public findValueType(valueTypeString, valueTypeVersion) {
for (const valueType of this.valueTypes) {
if (valueType.code === valueTypeString && valueType.version === valueTypeVersion) {
return valueType;
}
}
return null;
}
public findValueTypeByProperty(valueTypeString, valueTypeVersion, propertyName) {
const valueType = this.findValueType(valueTypeString, valueTypeVersion);
if (!valueType) {
return null;
}
for (const property of valueType.properties) {
if (property.name === propertyName) {
return this.findValueType(property.valueType, property.valueTypeVersion);
}
}
}
public getParameterOptions(): any {
const options = [];
for (const parameter of this.parameters) {
const valueType = this.findValueType(parameter.valueType, parameter.valueTypeVersion);
const info = valueType.version ? valueType.name + '(V' + valueType.version + ')' : valueType.name;
options.push({ label: parameter.name, type: 'variable', apply: '${' + parameter.name + '}', info: info });
}
return options;
}
public getPropertyOptions(parameterName: string): any {
let parameterType = undefined;
for (const parameter of this.parameters) {
if (parameter.name === parameterName) {
parameterType = parameter.valueType;
}
}
if (!parameterType) {
return null;
}
for (const type of this.valueTypes) {
if (type.code === parameterType) {
parameterType = type;
}
}
if (!parameterType) {
return null;
}
if (parameterType.properties && parameterType.properties.length > 0) {
const options = [];
for (const property of parameterType.properties) {
options.push({ label: property.name, type: 'property', apply: '${' + property.name + '}', detail: this.findValueTypeInfo(property.valueType) });
}
return options;
}
}
public autoCompletionParameters(to, matchedText): any {
return {
from: to,
options: this.getParameterOptions(),
validFor: /(.*)?/,
};
}
public autoCompletionProperties(to, matchedText): any {
const matchedTextReverse = Tools.reverseString(matchedText);
const regReverse = /(\.\}(.+?)\{\$)+/g; //匹配 '.}xxx{$' 模式
const matcheds = matchedTextReverse.match(regReverse);
if (Tools.isUndefinedOrNull(matcheds) || matcheds.length <= 0) {
return null;
}
const matched = Tools.reverseString(matcheds[0]);
const parameterName = matched.replace(/\$\{(.+?)\}/g, '$1');
if (Tools.isUndefinedOrNull(parameterName)) {
return null;
}
const options = this.getOptions(parameterName);
if (Tools.isUndefinedOrNull(options)) {
return null;
}
return {
from: to,
options: options,
validFor: /^(.*)?$/,
};
}
public autoCompletion(context): any {
const beforeMatched = context.matchBefore(/(.+?)/g);
if (Tools.isUndefinedOrNull(beforeMatched)) {
return null;
}
const beforeText = beforeMatched.text || '';
if (beforeText.endsWith('.')) {
//匹配属性
return this.autoCompletionProperties(beforeMatched.to, beforeText);
} else if (beforeText.endsWith(' ')) {
//匹配参数
return this.autoCompletionParameters(beforeMatched.to);
} else {
return null;
}
}
}
export { AutoCompletionManager };

15
io.sc.platform.core.frontend/template-project/src/views/testcase/math/MathEditor.vue

@ -1,11 +1,24 @@
<template>
<div>
<w-expression v-model="formulaRef" v-model:zoom="zoomRef"></w-expression>
<w-math v-model="formulaRef" v-model:zoom="zoomRef" :auto-completion="autoCompletion"></w-math>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { axios, Environment } from '@/platform';
import { AutoCompletionManager } from './AutoCompletionManager';
const autoCompletionManager = new AutoCompletionManager();
const autoCompletion = (context) => {
return autoCompletionManager.autoCompletion(context);
};
//
axios.get(Environment.apiContextPath('/api/re/common/listParameterAndValueTypeByParameterId/8153516a-a88e-4d19-b145-e49862e73b0b')).then((response) => {
autoCompletionManager.setParameters(response.data.parameters);
autoCompletionManager.setValueTypes(response.data.valueTypes);
});
const zoomRef = ref(10);
const formula = '';

2
io.sc.platform.developer.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.275",
"platform-core": "8.1.279",
"quasar": "2.15.4",
"tailwindcss": "3.4.4",
"vue": "3.4.31",

2
io.sc.platform.gradle/templates/pgp/setup/gradle.properties

@ -38,7 +38,7 @@ application_version=1.0.0
platform_group=io.sc
platform_version=8.1.44
platform_plugin_version=8.1.44
platform_core_frontend_version=8.1.275
platform_core_frontend_version=8.1.279
###########################################################
# dependencies version

2
io.sc.platform.lcdp.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.275",
"platform-core": "8.1.279",
"quasar": "2.15.4",
"tailwindcss": "3.4.4",
"vue": "3.4.31",

1
io.sc.platform.monitor/src/main/java/io/sc/platform/monitor/service/impl/SystemMonitorImpl.java

@ -2,6 +2,7 @@ package io.sc.platform.monitor.service.impl;
import io.sc.platform.monitor.service.SystemMonitor;
import io.sc.platform.monitor.service.support.ServerInfo;
import org.springframework.beans.factory.annotation.Autowired;
public class SystemMonitorImpl implements SystemMonitor {
@Override

18
io.sc.platform.monitor/src/main/java/io/sc/platform/monitor/service/support/ServerInfo.java

@ -10,6 +10,8 @@ public class ServerInfo {
private Disk disk;
private Jvm jvm;
private int onlineUserCount;
private long serviceRequestSuccessCount;
private long serviceRequestFailedCount;
public static ServerInfo info(){
SystemInfo si = new SystemInfo();
@ -79,4 +81,20 @@ public class ServerInfo {
public void setOnlineUserCount(int onlineUserCount) {
this.onlineUserCount = onlineUserCount;
}
public long getServiceRequestSuccessCount() {
return serviceRequestSuccessCount;
}
public void setServiceRequestSuccessCount(long serviceRequestSuccessCount) {
this.serviceRequestSuccessCount = serviceRequestSuccessCount;
}
public long getServiceRequestFailedCount() {
return serviceRequestFailedCount;
}
public void setServiceRequestFailedCount(long serviceRequestFailedCount) {
this.serviceRequestFailedCount = serviceRequestFailedCount;
}
}

2
io.sc.platform.mvc.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.275",
"platform-core": "8.1.279",
"quasar": "2.15.4",
"tailwindcss": "3.4.4",
"vue": "3.4.31",

2
io.sc.platform.security.frontend/package.json

@ -93,7 +93,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.275",
"platform-core": "8.1.279",
"quasar": "2.14.5",
"tailwindcss": "3.4.0",
"vue": "3.4.3",

2
io.sc.platform.system.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.275",
"platform-core": "8.1.279",
"quasar": "2.15.4",
"tailwindcss": "3.4.4",
"vue": "3.4.31",

24
io.sc.platform.system.frontend/src/i18n/messages.json

@ -161,4 +161,28 @@
"system.monitor.serverInfo.os.name":"Name",
"system.monitor.serverInfo.os.version":"Version",
"system.monitor.serverInfo.os.arch":"Architecture",
"system.monitor.serverInfo.os.manufacturer":"Manufacturer",
"system.monitor.serverInfo.os.bootTime":"Boot Time",
"system.monitor.serverInfo.os.upTime":"Up Time",
"system.monitor.serverInfo.jvm":"Java Virtual Machine",
"system.monitor.serverInfo.jvm.total":"Total Memory Used",
"system.monitor.serverInfo.jvm.max":"Max Memory Available",
"system.monitor.serverInfo.jvm.free":"Free Memory",
"system.monitor.serverInfo.jvm.version":"JDK Version",
"system.monitor.serverInfo.jvm.home":"JDK Path",
"system.monitor.serverInfo.cpu":"CPU",
"system.monitor.serverInfo.cpu.system":"System",
"system.monitor.serverInfo.cpu.user":"User",
"system.monitor.serverInfo.memory":"Memory",
"system.monitor.serverInfo.disk":"Disk",
"system.monitor.serverInfo.disk.used":"Used",
"system.monitor.serverInfo.disk.free":"Free",
"system.monitor.serverInfo.online":"Online",
"system.monitor.serverInfo.serviceRequest": "Service Request"
}

24
io.sc.platform.system.frontend/src/i18n/messages_tw_CN.json

@ -138,4 +138,28 @@
"system.monitor.serverInfo.os.name":"名稱",
"system.monitor.serverInfo.os.version":"版本",
"system.monitor.serverInfo.os.arch":"架構",
"system.monitor.serverInfo.os.manufacturer":"生產商",
"system.monitor.serverInfo.os.bootTime":"上次啟動日期",
"system.monitor.serverInfo.os.upTime":"持續運行天數",
"system.monitor.serverInfo.jvm":"Java 虛擬機",
"system.monitor.serverInfo.jvm.total":"當前佔用的內存總數",
"system.monitor.serverInfo.jvm.max":"最大可用內存總數",
"system.monitor.serverInfo.jvm.free":"空閒內存",
"system.monitor.serverInfo.jvm.version":"JDK 版本",
"system.monitor.serverInfo.jvm.home":"JDK 路徑",
"system.monitor.serverInfo.cpu":"CPU",
"system.monitor.serverInfo.cpu.system":"系統",
"system.monitor.serverInfo.cpu.user":"用戶",
"system.monitor.serverInfo.memory":"內存",
"system.monitor.serverInfo.disk":"存儲",
"system.monitor.serverInfo.disk.used":"已用",
"system.monitor.serverInfo.disk.free":"空閒",
"system.monitor.serverInfo.online":"在線用戶",
"system.monitor.serverInfo.serviceRequest": "服務請求"
}

2
io.sc.platform.system.frontend/src/i18n/messages_zh_CN.json

@ -190,4 +190,6 @@
"system.monitor.serverInfo.disk.free":"空闲",
"system.monitor.serverInfo.online":"在线用户",
"system.monitor.serverInfo.serviceRequest": "服务请求"
}

50
io.sc.platform.system.frontend/src/views/monitor/ServerInfo.vue

@ -86,14 +86,21 @@
</q-card-section>
</q-card>
</div>
<div class="col-4 px-4"></div>
<div class="col-4 px-4">
<q-card>
<q-card-section>
<div class="text-h6">{{ $t('system.monitor.serverInfo.serviceRequest') }}</div>
<w-echarts ref="serviceRequestEchartsRef" style="width: 100%; height: 250px" :option="serviceRequestOption"></w-echarts>
</q-card-section>
</q-card>
</div>
<div class="col-4 px-4"></div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, onActivated, onDeactivated } from 'vue';
import { axios, Environment, t } from 'platform-core';
import { axios, Environment, t, Formater } from 'platform-core';
const serverInfo = ref();
const cpuEchartsRef = ref();
@ -161,6 +168,40 @@ const onlineOption = {
series: [{ type: 'line', stack: 'Total', showSymbol: false, smooth: true, data: [] }],
};
const serviceRequestEchartsRef = ref();
const serviceRequestOption = {
animation: false,
legend: {},
tooltip: {
trigger: 'item',
formatter: (params) => {
return Formater.thousands()(params.value);
},
},
series: [
{
type: 'pie',
top: 50,
emphasis: {
itemStyle: {
shadowBlur: 10,
shadowOffsetX: 0,
shadowColor: 'rgba(0, 0, 0, 0.5)',
},
},
avoidLabelOverlap: false,
label: {
show: false,
position: 'center',
},
data: [
{ value: 0, name: t('failed') },
{ value: 0, name: t('success') },
],
},
],
};
const refresh = () => {
axios.get(Environment.apiContextPath('/api/monitor/metrics')).then((response) => {
const data = response.data;
@ -196,6 +237,11 @@ const refresh = () => {
onlineOption.series[0].data.shift();
}
onlineEchartsRef.value.setOption(onlineOption);
// serviceRequest
serviceRequestOption.series[0].data[0].value = data.serviceRequestFailedCount;
serviceRequestOption.series[0].data[1].value = data.serviceRequestSuccessCount;
serviceRequestEchartsRef.value.setOption(serviceRequestOption);
});
};

5
io.sc.platform.system/src/main/java/io/sc/platform/system/auditlog/service/AuditLogService.java

@ -5,4 +5,9 @@ import io.sc.platform.system.auditlog.jpa.entity.AuditLogEntity;
import io.sc.platform.system.auditlog.jpa.repository.AuditLogRepository;
public interface AuditLogService extends DaoService<AuditLogEntity, String, AuditLogRepository> {
/**
* 获取服务请求成功和失败的次数
* @return [0]: failed; [1]: success
*/
public long[] getServiceRequestSuccessAndFailedCount();
}

28
io.sc.platform.system/src/main/java/io/sc/platform/system/auditlog/service/impl/AuditLogServiceImpl.java

@ -4,9 +4,37 @@ import io.sc.platform.orm.service.impl.DaoServiceImpl;
import io.sc.platform.system.auditlog.jpa.entity.AuditLogEntity;
import io.sc.platform.system.auditlog.jpa.repository.AuditLogRepository;
import io.sc.platform.system.auditlog.service.AuditLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.sql.ResultSet;
import java.sql.SQLException;
@Service
public class AuditLogServiceImpl extends DaoServiceImpl<AuditLogEntity, String, AuditLogRepository> implements AuditLogService {
@Autowired private JdbcTemplate jdbcTemplate;
@Override
public long[] getServiceRequestSuccessAndFailedCount() {
return jdbcTemplate.query("select STATUS_ STATUS,count(*) COUNT from SYS_AUDIT_LOG group by STATUS order by STATUS", new ResultSetExtractor<long[]>(){
@Override
public long[] extractData(ResultSet rs) throws SQLException, DataAccessException {
long[] result =new long[2];
while(rs.next()){
String key =rs.getString("STATUS");
if("success".equalsIgnoreCase(key)){
result[1] =rs.getLong("COUNT");
}else if("failed".equalsIgnoreCase(key)){
result[0] =rs.getLong("COUNT");
}
}
return result;
}
});
}
}

7
io.sc.platform.system/src/main/java/io/sc/platform/system/monitor/controller/MetricsWebController.java

@ -4,6 +4,8 @@ import io.sc.platform.monitor.service.SystemMonitor;
import io.sc.platform.monitor.service.impl.SystemMonitorImpl;
import io.sc.platform.monitor.service.support.ServerInfo;
import io.sc.platform.mvc.autoconfigure.support.OnlineUserCounterInterceptor;
import io.sc.platform.system.auditlog.service.AuditLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@ -11,11 +13,16 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/monitor")
public class MetricsWebController {
@Autowired private AuditLogService auditLogService;
@GetMapping("metrics")
public ServerInfo metrics() throws Exception {
SystemMonitor monitor =new SystemMonitorImpl();
ServerInfo serverInfo =monitor.getServerInfo();
serverInfo.setOnlineUserCount(OnlineUserCounterInterceptor.count());
long[] counter =auditLogService.getServiceRequestSuccessAndFailedCount();
serverInfo.setServiceRequestFailedCount(counter[0]);
serverInfo.setServiceRequestSuccessCount(counter[1]);
return serverInfo;
}
}

2
io.sc.standard.frontend/package.json

@ -92,7 +92,7 @@
"luckyexcel": "1.0.1",
"mockjs": "1.1.0",
"pinia": "2.1.7",
"platform-core": "8.1.275",
"platform-core": "8.1.279",
"quasar": "2.15.4",
"tailwindcss": "3.4.4",
"vue": "3.4.31",

Loading…
Cancel
Save