Browse Source

基础框架发布: 8.2.31

1) 修复 orm BetweenInclusive 日期bug
  2)工作流增加流程实例属性扩展表

前端核心发布: 8.2.121
 1) 修改默认导出功能,导出文件名默认为列表的标题.xlsx
main
wangshaoping 1 month ago
parent
commit
70de570905
  1. 113
      app.platform/src/main/java/app/platform/Application.java
  2. 5
      cips.frontend/package.json
  3. 5
      erm.frontend/package.json
  4. 5
      gradle.properties
  5. 5
      io.sc.engine.mv.frontend/package.json
  6. 5
      io.sc.engine.rule.frontend/package.json
  7. 5
      io.sc.engine.st.frontend/package.json
  8. 5
      io.sc.platform.ai.frontend/package.json
  9. 2
      io.sc.platform.core.frontend/package.json
  10. 2
      io.sc.platform.core.frontend/src/components/index.ts
  11. 1
      io.sc.platform.core.frontend/src/i18n/messages.json
  12. 1
      io.sc.platform.core.frontend/src/i18n/messages_tw_CN.json
  13. 1
      io.sc.platform.core.frontend/src/i18n/messages_zh_CN.json
  14. 10
      io.sc.platform.core.frontend/src/menus/menus.json
  15. 7
      io.sc.platform.core.frontend/src/platform/components/grid/ts/toolbar/buttons/Export.ts
  16. 1
      io.sc.platform.core.frontend/src/platform/i18n/messages.json
  17. 1
      io.sc.platform.core.frontend/src/platform/i18n/messages_tw_CN.json
  18. 1
      io.sc.platform.core.frontend/src/platform/i18n/messages_zh_CN.json
  19. 4
      io.sc.platform.core.frontend/src/platform/layout/sub-layout/Topper.vue
  20. 12
      io.sc.platform.core.frontend/src/platform/utils/Tools.ts
  21. 40
      io.sc.platform.core.frontend/src/platform/views/Home.vue
  22. 2
      io.sc.platform.core.frontend/src/platform/views/home/AnnouncementDialog.vue
  23. 32
      io.sc.platform.core.frontend/src/platform/views/home/MyDoneTask.vue
  24. 32
      io.sc.platform.core.frontend/src/platform/views/home/MyFinishedTask.vue
  25. 61
      io.sc.platform.core.frontend/src/platform/views/home/MyTask.vue
  26. 2
      io.sc.platform.core.frontend/src/platform/views/home/SystemMessageDialog.vue
  27. 2
      io.sc.platform.core.frontend/src/platform/views/home/UserMessageDialog.vue
  28. 13
      io.sc.platform.core.frontend/src/routes/routes.json
  29. 142
      io.sc.platform.core.frontend/src/views/testcase/bpm/Bpm.vue
  30. 4
      io.sc.platform.core.frontend/template-project/package.json
  31. 2
      io.sc.platform.core.frontend/template-project/src/components/index.ts
  32. 1
      io.sc.platform.core.frontend/template-project/src/i18n/messages.json
  33. 1
      io.sc.platform.core.frontend/template-project/src/i18n/messages_tw_CN.json
  34. 1
      io.sc.platform.core.frontend/template-project/src/i18n/messages_zh_CN.json
  35. 10
      io.sc.platform.core.frontend/template-project/src/menus/menus.json
  36. 13
      io.sc.platform.core.frontend/template-project/src/routes/routes.json
  37. 142
      io.sc.platform.core.frontend/template-project/src/views/testcase/bpm/Bpm.vue
  38. 4
      io.sc.platform.developer.doc/package.json
  39. 5
      io.sc.platform.developer.frontend/package.json
  40. 22
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessEntityWebController.java
  41. 19
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessQueryWebController.java
  42. 17
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/repository/ProcessEntityRepository.java
  43. 24
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/ProcessQueryService.java
  44. 4
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/ProcessEntityServiceImpl.java
  45. 52
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/ProcessOperationServiceImpl.java
  46. 650
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/ProcessQueryServiceImpl.java
  47. 968
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/ProcessQueryServiceImpl2.java
  48. 46
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/BusinessKeyAndDescriptionWrapper.java
  49. 18
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/BusinessKeyAndDescriptionWrapperMapper.java
  50. 60
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/ProcessTaskAssigneeWrapper.java
  51. 20
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/ProcessTaskAssigneeWrapperMapper.java
  52. 179
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/ProcessTaskWrapper.java
  53. 26
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/ProcessTaskWrapperMapper.java
  54. 3
      io.sc.platform.flowable/src/main/resources/META-INF/platform/plugins/messages.json
  55. 22
      io.sc.platform.flowable/src/main/resources/META-INF/platform/plugins/parameters.json
  56. 3
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/parameters.properties
  57. 3
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/parameters_tw_CN.properties
  58. 3
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/parameters_zh_CN.properties
  59. 46
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/DoneTask.sql
  60. 48
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/FinishedTask.sql
  61. 52
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/MyDoneTasks.sql
  62. 64
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/MyFinishedTasks.sql
  63. 44
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/MyTasks.sql
  64. 16
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/ProcessPrefixAssignee.sql
  65. 43
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/Task.sql
  66. 20
      io.sc.platform.flowable/src/main/resources/liquibase/io.sc.platform.flowable_8.0.0_20220606__Process_Manager_Database_Schema_DDL.xml
  67. 5
      io.sc.platform.lcdp.frontend/package.json
  68. 4
      io.sc.platform.lcdp.frontend/src/i18n/messages.json
  69. 4
      io.sc.platform.lcdp.frontend/src/i18n/messages_tw_CN.json
  70. 4
      io.sc.platform.lcdp.frontend/src/i18n/messages_zh_CN.json
  71. 76
      io.sc.platform.lcdp.frontend/src/views/bpm/Bpm.vue
  72. 5
      io.sc.platform.license.keygen.frontend/package.json
  73. 5
      io.sc.platform.mvc.frontend/package.json
  74. 3
      io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/support/RestCrudController.java
  75. 21
      io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/plugins/item/Parameter.java
  76. 2
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/DaoService.java
  77. 5
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/impl/DaoServiceImpl.java
  78. 4
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/support/criteria/impl/BetweenInclusive.java
  79. 1
      io.sc.platform.poi/build.gradle
  80. 5
      io.sc.platform.scheduler.manager.frontend/package.json
  81. 9
      io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/parameter/ParameterVo.java
  82. 5
      io.sc.platform.system.frontend/package.json
  83. 37
      io.sc.platform.system.frontend/src/i18n/messages.json
  84. 37
      io.sc.platform.system.frontend/src/i18n/messages_tw_CN.json
  85. 37
      io.sc.platform.system.frontend/src/i18n/messages_zh_CN.json
  86. 25
      io.sc.platform.system.frontend/src/views/parameter/Parameter.vue
  87. 101
      io.sc.platform.system.frontend/src/views/workbench/MyDoneTask.vue
  88. 94
      io.sc.platform.system.frontend/src/views/workbench/MyFinishedTask.vue
  89. 99
      io.sc.platform.system.frontend/src/views/workbench/MyTask.vue
  90. 1
      io.sc.platform.system/src/main/java/io/sc/platform/system/parameter/controller/ParameterWebController.java
  91. 5
      io.sc.standard.frontend/package.json
  92. 4
      io.sc.website/package.json
  93. 5
      wra.report.frontend/package.json

113
app.platform/src/main/java/app/platform/Application.java

@ -17,5 +17,118 @@ import java.util.List;
public class Application extends PlatformSpringBootServletInitializer implements WebApplicationInitializer {
public static void main(String[] args) throws Exception {
ApplicationLauncher.run(Application.class,args);
String xml ="<?xml version='1.0' encoding='UTF-8'?>\n" +
" <definitions xmlns=\"http://www.omg.org/spec/BPMN/20100524/MODEL\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:flowable=\"http://flowable.org/bpmn\" xmlns:bpmndi=\"http://www.omg.org/spec/BPMN/20100524/DI\" xmlns:omgdc=\"http://www.omg.org/spec/DD/20100524/DC\" xmlns:omgdi=\"http://www.omg.org/spec/DD/20100524/DI\" typeLanguage=\"http://www.w3.org/2001/XMLSchema\" expressionLanguage=\"http://www.w3.org/1999/XPath\" targetNamespace=\"http://www.flowable.org/processdef\" exporter=\"Flowable Open Source Modeler\" exporterVersion=\"6.8.0\">\n" +
" <process id=\"SAMPLE\" name=\"示例流程\" isExecutable=\"true\">\n" +
" <dataObject id=\"assignment-strategy\" name=\"分配策略\" itemSubjectRef=\"xsd:string\">\n" +
" <extensionElements>\n" +
" <flowable:value>{\"A2\":\"platformAssigneeQueryService\"}</flowable:value>\n" +
" </extensionElements>\n" +
" </dataObject>\n" +
" <startEvent id=\"start\" name=\"开始\" flowable:formFieldValidation=\"true\"/>\n" +
" <userTask id=\"A1\" name=\"提交申请\" flowable:assignee=\"${assignee}\" flowable:candidateGroups=\"admin\" flowable:formFieldValidation=\"true\" flowable:skipExpression=\"${execution.getVariable('skipFirst') == true}\">\n" +
" <extensionElements>\n" +
" <modeler:group-info-name-admin xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n" +
" <modeler:activiti-idm-candidate-group xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n" +
" <modeler:initiator-can-complete xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[false]]></modeler:initiator-can-complete>\n" +
" </extensionElements>\n" +
" </userTask>\n" +
" <userTask id=\"A2\" name=\"复核\" flowable:assignee=\"${assignee}\" flowable:candidateGroups=\"admin\" flowable:formFieldValidation=\"true\">\n" +
" <extensionElements>\n" +
" <flowable:taskListener event=\"assignment\" delegateExpression=\"${flowableSendMailListener}\">\n" +
" <flowable:field name=\"title\">\n" +
" <flowable:string><![CDATA[您有一个 [示例] 流程的 [复核] 任务等待处理]]></flowable:string>\n" +
" </flowable:field>\n" +
" <flowable:field name=\"content\">\n" +
" <flowable:string><![CDATA[${assignee},您好! 您有一个 [示例] 流程的 [复核] 任务等待处理,详情参见: http://localhost:8080]]></flowable:string>\n" +
" </flowable:field>\n" +
" </flowable:taskListener>\n" +
" <modeler:group-info-name-admin xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n" +
" <modeler:activiti-idm-candidate-group xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n" +
" <modeler:initiator-can-complete xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[false]]></modeler:initiator-can-complete>\n" +
" </extensionElements>\n" +
" </userTask>\n" +
" <endEvent id=\"end\" name=\"结束\"/>\n" +
" <sequenceFlow id=\"sid-452257DA-C9ED-41BB-A95A-899D5F7FD363\" sourceRef=\"start\" targetRef=\"A1\"/>\n" +
" <sequenceFlow id=\"sid-EC4C37D8-A419-4DD1-9569-DD93AE964688\" sourceRef=\"A1\" targetRef=\"A2\"/>\n" +
" <userTask id=\"A3\" name=\"认定\" default=\"sid-95DCA487-E110-49BB-86F9-C623692DD8BA\" flowable:assignee=\"${assignee}\" flowable:candidateGroups=\"admin\" flowable:formFieldValidation=\"true\">\n" +
" <extensionElements>\n" +
" <modeler:group-info-name-admin xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n" +
" <modeler:activiti-idm-candidate-group xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n" +
" <modeler:initiator-can-complete xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[false]]></modeler:initiator-can-complete>\n" +
" </extensionElements>\n" +
" </userTask>\n" +
" <sequenceFlow id=\"sid-60D2D382-C039-4E2F-BC47-348DB6E9A02A\" sourceRef=\"A2\" targetRef=\"A3\"/>\n" +
" <userTask id=\"A4\" name=\"最终认定\" flowable:assignee=\"${assignee}\" flowable:candidateGroups=\"admin\" flowable:formFieldValidation=\"true\">\n" +
" <extensionElements>\n" +
" <modeler:group-info-name-admin xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n" +
" <modeler:activiti-idm-candidate-group xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n" +
" <modeler:initiator-can-complete xmlns:modeler=\"http://flowable.org/modeler\"><![CDATA[false]]></modeler:initiator-can-complete>\n" +
" </extensionElements>\n" +
" </userTask>\n" +
" <sequenceFlow id=\"sid-87E440E2-0998-4C95-B4A4-444397ADB79C\" sourceRef=\"A4\" targetRef=\"end\"/>\n" +
" <sequenceFlow id=\"sid-95DCA487-E110-49BB-86F9-C623692DD8BA\" sourceRef=\"A3\" targetRef=\"A4\"/>\n" +
" <sequenceFlow id=\"sid-74A758E1-9AB1-4E1C-9D03-EF323869EB4E\" name=\"退回给复核岗\" sourceRef=\"A3\" targetRef=\"A2\">\n" +
" <conditionExpression xsi:type=\"tFormalExpression\"><![CDATA[${goback == -1}]]></conditionExpression>\n" +
" </sequenceFlow>\n" +
" <sequenceFlow id=\"sid-8C796912-0699-4ADA-9F3F-91154970C7E2\" name=\"退回给申请人\" sourceRef=\"A3\" targetRef=\"A1\">\n" +
" <conditionExpression xsi:type=\"tFormalExpression\"><![CDATA[${goback == -2}]]></conditionExpression>\n" +
" </sequenceFlow>\n" +
" </process>\n" +
" <bpmndi:BPMNDiagram id=\"BPMNDiagram_SAMPLE\">\n" +
" <bpmndi:BPMNPlane bpmnElement=\"SAMPLE\" id=\"BPMNPlane_SAMPLE\">\n" +
" <bpmndi:BPMNShape bpmnElement=\"start\" id=\"BPMNShape_start\">\n" +
" <omgdc:Bounds height=\"30.0\" width=\"30.0\" x=\"60.0\" y=\"168.5\"/>\n" +
" </bpmndi:BPMNShape>\n" +
" <bpmndi:BPMNShape bpmnElement=\"A1\" id=\"BPMNShape_A1\">\n" +
" <omgdc:Bounds height=\"40.0\" width=\"96.0\" x=\"120.0\" y=\"160.5\"/>\n" +
" </bpmndi:BPMNShape>\n" +
" <bpmndi:BPMNShape bpmnElement=\"A2\" id=\"BPMNShape_A2\">\n" +
" <omgdc:Bounds height=\"40.0\" width=\"81.0\" x=\"255.0\" y=\"160.5\"/>\n" +
" </bpmndi:BPMNShape>\n" +
" <bpmndi:BPMNShape bpmnElement=\"end\" id=\"BPMNShape_end\">\n" +
" <omgdc:Bounds height=\"28.0\" width=\"28.0\" x=\"615.0\" y=\"166.5\"/>\n" +
" </bpmndi:BPMNShape>\n" +
" <bpmndi:BPMNShape bpmnElement=\"A3\" id=\"BPMNShape_A3\">\n" +
" <omgdc:Bounds height=\"42.0\" width=\"82.0\" x=\"375.0\" y=\"159.5\"/>\n" +
" </bpmndi:BPMNShape>\n" +
" <bpmndi:BPMNShape bpmnElement=\"A4\" id=\"BPMNShape_A4\">\n" +
" <omgdc:Bounds height=\"40.0\" width=\"92.0\" x=\"495.0\" y=\"160.5\"/>\n" +
" </bpmndi:BPMNShape>\n" +
" <bpmndi:BPMNEdge bpmnElement=\"sid-74A758E1-9AB1-4E1C-9D03-EF323869EB4E\" id=\"BPMNEdge_sid-74A758E1-9AB1-4E1C-9D03-EF323869EB4E\" flowable:sourceDockerX=\"41.0\" flowable:sourceDockerY=\"21.0\" flowable:targetDockerX=\"40.0\" flowable:targetDockerY=\"20.0\">\n" +
" <omgdi:waypoint x=\"416.0\" y=\"159.0\"/>\n" +
" <omgdi:waypoint x=\"416.0\" y=\"77.0\"/>\n" +
" <omgdi:waypoint x=\"295.0\" y=\"77.0\"/>\n" +
" <omgdi:waypoint x=\"295.0\" y=\"160.0\"/>\n" +
" </bpmndi:BPMNEdge>\n" +
" <bpmndi:BPMNEdge bpmnElement=\"sid-95DCA487-E110-49BB-86F9-C623692DD8BA\" id=\"BPMNEdge_sid-95DCA487-E110-49BB-86F9-C623692DD8BA\" flowable:sourceDockerX=\"41.0\" flowable:sourceDockerY=\"21.0\" flowable:targetDockerX=\"46.0\" flowable:targetDockerY=\"20.0\">\n" +
" <omgdi:waypoint x=\"456.0\" y=\"180.0\"/>\n" +
" <omgdi:waypoint x=\"494.0\" y=\"180.0\"/>\n" +
" </bpmndi:BPMNEdge>\n" +
" <bpmndi:BPMNEdge bpmnElement=\"sid-60D2D382-C039-4E2F-BC47-348DB6E9A02A\" id=\"BPMNEdge_sid-60D2D382-C039-4E2F-BC47-348DB6E9A02A\" flowable:sourceDockerX=\"40.0\" flowable:sourceDockerY=\"20.0\" flowable:targetDockerX=\"41.0\" flowable:targetDockerY=\"21.0\">\n" +
" <omgdi:waypoint x=\"335.0\" y=\"180.0\"/>\n" +
" <omgdi:waypoint x=\"375.0\" y=\"180.0\"/>\n" +
" </bpmndi:BPMNEdge>\n" +
" <bpmndi:BPMNEdge bpmnElement=\"sid-8C796912-0699-4ADA-9F3F-91154970C7E2\" id=\"BPMNEdge_sid-8C796912-0699-4ADA-9F3F-91154970C7E2\" flowable:sourceDockerX=\"41.0\" flowable:sourceDockerY=\"21.0\" flowable:targetDockerX=\"48.0\" flowable:targetDockerY=\"20.0\">\n" +
" <omgdi:waypoint x=\"416.0\" y=\"201.0\"/>\n" +
" <omgdi:waypoint x=\"416.0\" y=\"284.0\"/>\n" +
" <omgdi:waypoint x=\"168.0\" y=\"284.0\"/>\n" +
" <omgdi:waypoint x=\"168.0\" y=\"200.0\"/>\n" +
" </bpmndi:BPMNEdge>\n" +
" <bpmndi:BPMNEdge bpmnElement=\"sid-87E440E2-0998-4C95-B4A4-444397ADB79C\" id=\"BPMNEdge_sid-87E440E2-0998-4C95-B4A4-444397ADB79C\" flowable:sourceDockerX=\"46.0\" flowable:sourceDockerY=\"20.0\" flowable:targetDockerX=\"14.0\" flowable:targetDockerY=\"14.0\">\n" +
" <omgdi:waypoint x=\"586.0\" y=\"180.0\"/>\n" +
" <omgdi:waypoint x=\"615.0\" y=\"180.0\"/>\n" +
" </bpmndi:BPMNEdge>\n" +
" <bpmndi:BPMNEdge bpmnElement=\"sid-EC4C37D8-A419-4DD1-9569-DD93AE964688\" id=\"BPMNEdge_sid-EC4C37D8-A419-4DD1-9569-DD93AE964688\" flowable:sourceDockerX=\"48.0\" flowable:sourceDockerY=\"20.0\" flowable:targetDockerX=\"40.0\" flowable:targetDockerY=\"20.0\">\n" +
" <omgdi:waypoint x=\"215.0\" y=\"180.0\"/>\n" +
" <omgdi:waypoint x=\"254.0\" y=\"180.0\"/>\n" +
" </bpmndi:BPMNEdge>\n" +
" <bpmndi:BPMNEdge bpmnElement=\"sid-452257DA-C9ED-41BB-A95A-899D5F7FD363\" id=\"BPMNEdge_sid-452257DA-C9ED-41BB-A95A-899D5F7FD363\" flowable:sourceDockerX=\"15.0\" flowable:sourceDockerY=\"15.0\" flowable:targetDockerX=\"48.0\" flowable:targetDockerY=\"20.0\">\n" +
" <omgdi:waypoint x=\"89.0\" y=\"183.0\"/>\n" +
" <omgdi:waypoint x=\"120.0\" y=\"182.0\"/>\n" +
" </bpmndi:BPMNEdge>\n" +
" </bpmndi:BPMNPlane>\n" +
" </bpmndi:BPMNDiagram>\n" +
" </definitions>";
}
}

5
cips.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "cips.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

5
erm.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "erm.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

5
gradle.properties

@ -37,9 +37,9 @@ application_version=1.0.0
# platform
###########################################################
platform_group=io.sc
platform_version=8.2.30
platform_version=8.2.31
platform_plugin_version=8.2.10
platform_core_frontend_version=8.2.117
platform_core_frontend_version=8.2.121
###########################################################
# dependencies version
@ -52,6 +52,7 @@ checker_version=3.43.0
commons_compress_version=1.25.0
commons_fileupload_version=1.4
commons_io_version=2.16.1
commons_jexl3_version=3.2
commons_text_version=1.12.0
curvesapi_version=1.08
cxf_version=3.2.7

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

@ -1,6 +1,6 @@
{
"name": "io.sc.engine.mv.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

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

@ -1,6 +1,6 @@
{
"name": "io.sc.engine.rule.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

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

@ -1,6 +1,6 @@
{
"name": "io.sc.engine.st.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

5
io.sc.platform.ai.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.ai.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

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

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.2.117",
"version": "8.2.121",
"description": "前端核心包,用于快速构建前端的脚手架",
"//main": "库的主文件",
"main": "dist/platform-core.js",

2
io.sc.platform.core.frontend/src/components/index.ts

@ -13,6 +13,7 @@ import component_testcase_excel from '@/views/testcase/excel/Excel.vue';
import component_testcase_word from '@/views/testcase/word/Word.vue';
import component_testcase_maxgraph from '@/views/testcase/maxgraph/Maxgraph.vue';
import component_testcase_ai from '@/views/testcase/ai/Ai.vue';
import component_testcase_bpm from '@/views/testcase/bpm/Bpm.vue';
import component_testcase_likmDialog from '@/views/likm/Dialog.vue';
import component_testcase_likmDrawer from '@/views/likm/Drawer.vue';
import component_testcase_likmForm from '@/views/likm/Form.vue';
@ -35,6 +36,7 @@ const localComponents = {
'component.testcase.word': component_testcase_word,
'component.testcase.maxgraph': component_testcase_maxgraph,
'component.testcase.ai': component_testcase_ai,
'component.testcase.bpm': component_testcase_bpm,
'component.testcase.likmDialog': component_testcase_likmDialog,
'component.testcase.likmDrawer': component_testcase_likmDrawer,
'component.testcase.likmForm': component_testcase_likmForm,

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

@ -12,6 +12,7 @@
"menu.testcase.word": "Word",
"menu.testcase.maxgraph": "Graph Editor",
"menu.testcase.ai": "AI",
"menu.testcase.bpm": "BPM",
"route.testcase.noMenuRoute": "No Menu Route"
}

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

@ -12,6 +12,7 @@
"menu.testcase.word": "Word",
"menu.testcase.maxgraph": "图形编辑器",
"menu.testcase.ai": "AI",
"menu.testcase.bpm": "BPM",
"route.testcase.noMenuRoute": "無關聯菜單路由"
}

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

@ -12,6 +12,7 @@
"menu.testcase.word": "Word",
"menu.testcase.maxgraph": "图形编辑器",
"menu.testcase.ai": "AI",
"menu.testcase.bpm": "BPM",
"route.testcase.noMenuRoute": "无关联菜单路由"
}

10
io.sc.platform.core.frontend/src/menus/menus.json

@ -127,7 +127,15 @@
"icon": "bi-palette",
"routeName": "route.testcase.ai"
},
{
"type": "ROUTE",
"order": 800,
"parentId": "menu.testcase",
"id": "menu.testcase.bpm",
"titleI18nKey": "menu.testcase.bpm",
"icon": "bi-palette",
"routeName": "route.testcase.bpm"
},
{ "type": "GROUP", "order": 30000, "id": "menu.testcase.likm", "titleI18nKey": "测试用例-likm", "icon": "home" },
{
"type": "ROUTE",

7
io.sc.platform.core.frontend/src/platform/components/grid/ts/toolbar/buttons/Export.ts

@ -1,4 +1,4 @@
import { $t, axios, Downloader } from '@/platform';
import { $t, axios, Downloader, Tools } from '@/platform';
import { PropsType, TableType } from '../../index';
import { Button } from '../Button';
@ -16,7 +16,10 @@ export class Export extends Button {
async click(args) {
const reqParams: any = { pageable: false };
const urlSearchParams = this.tools?.criteriaFM.buildURLSearchParams(reqParams);
const url = this.table?.url.exportDataUrl || this.table.url.dataUrl + '/exportExcel';
let url = this.table?.url.exportDataUrl || this.table.url.dataUrl + '/exportExcel';
if (!Tools.isEmpty(this.tools?.props.title)) {
url = url + '?downloadFileName=' + encodeURIComponent(this.tools?.props.title);
}
Downloader.get(url, { params: urlSearchParams });
}

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

@ -331,6 +331,7 @@
"home.card.task.tip.routeOrComponentNotSetting": "Action Operator NOT Setting!",
"home.card.task.tip.remoteComponentLoadError": "Action Component Loading Failed!",
"home.card.task.tip.taskNotExists": "Task NOT Exists, Can NOT Open Handler Dialog!",
"home.card.myTask.title": "My Tasks",
"home.card.myTask.action.list": "all my tasks",

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

@ -331,6 +331,7 @@
"home.card.task.tip.routeOrComponentNotSetting": "任務辦理動作未設置, 無法執行!",
"home.card.task.tip.remoteComponentLoadError": "任務辦理組件加載失敗, 無法執行!",
"home.card.task.tip.taskNotExists": "未找到任務, 無法打開任務處理對話框!",
"home.card.myTask.title": "待辦任務",
"home.card.myTask.action.list": "顯示所有",

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

@ -332,6 +332,7 @@
"home.card.task.tip.routeOrComponentNotSetting": "任务办理动作未设置, 无法执行!",
"home.card.task.tip.remoteComponentLoadError": "任务办理组件加载失败, 无法执行!",
"home.card.task.tip.taskNotExists": "未找到任务, 无法打开任务处理对话框!",
"home.card.myTask.title": "待办任务",
"home.card.myTask.action.list": "显示所有",

4
io.sc.platform.core.frontend/src/platform/layout/sub-layout/Topper.vue

@ -77,8 +77,8 @@
<q-item-section side top>
<q-item-label caption>
{{ item.createTimeAndNowDiff }}{{ $t(item.createTimeAndNowDiffUnit) }}{{ $t('before') }}
<q-tooltip :delay="1000">{{ item.createTime }}</q-tooltip>
{{ item.startTimeAndNowDiff }}{{ $t(item.startTimeAndNowDiffUnit) }}{{ $t('before') }}
<q-tooltip :delay="1000">{{ item.startTime }}</q-tooltip>
</q-item-label>
<q-item-label caption>{{ item.previousAssignee }}</q-item-label>
</q-item-section>

12
io.sc.platform.core.frontend/src/platform/utils/Tools.ts

@ -1099,6 +1099,18 @@ class Tools {
html = html.replace(/>/g, '&gt;');
return html;
}
/**
*
* @param str
* @returns
*/
public static lengthB(str: string) {
if (Tools.isNill(str)) {
return 0;
}
return new TextEncoder().encode(str).length;
}
}
export { Tools };

40
io.sc.platform.core.frontend/src/platform/views/Home.vue

@ -7,11 +7,11 @@
</div>
<div class="row p-2">
<div class="col-7 pr-2">
<MyTask ref="myTaskRef" @after-refresh="afterMyTaskRefresh"></MyTask>
<MyTask ref="myTaskRef" :task-id="taskIdRef" @after-refresh="afterMyTaskRefresh"></MyTask>
<div style="height: 10px"></div>
<MyDoneTask ref="myDoneTaskRef"></MyDoneTask>
<MyDoneTask ref="myDoneTaskRef" :task-id="doneTaskIdRef"></MyDoneTask>
<div style="height: 10px"></div>
<MyFinishedTask ref="myFinishedTaskRef"></MyFinishedTask>
<MyFinishedTask ref="myFinishedTaskRef" :task-id="finishedTaskIdRef"></MyFinishedTask>
</div>
<div class="col-5 pl-2">
<MyMessage ref="myMessageRef"></MyMessage>
@ -24,6 +24,7 @@
<script setup lang="ts">
import { ref } from 'vue';
import { useRoute, onBeforeRouteUpdate } from 'vue-router';
import { axios, Environment, SessionManager, I18nMessageManager, AuthenticationManager, Tools } from '@/platform';
import MyShortcutMenu from './home/MyShortcutMenu.vue';
import MyTask from './home/MyTask.vue';
@ -33,6 +34,7 @@ import MyMessage from './home/MyMessage.vue';
import MyAnnouncement from './home/MyAnnouncement.vue';
import { onActivated } from 'vue';
const route = useRoute();
const myShortcutMenuRef = ref();
const myTaskRef = ref();
const myDoneTaskRef = ref();
@ -40,6 +42,14 @@ const myFinishedTaskRef = ref();
const myMessageRef = ref();
const myAnnouncementRef = ref();
const taskIdRef = ref(); //ID
const doneTaskIdRef = ref(); //ID
const finishedTaskIdRef = ref(); //ID
onBeforeRouteUpdate((to, from) => {
handRouteQuery();
});
onActivated(() => {
myShortcutMenuRef?.value.refresh();
myTaskRef?.value.refresh();
@ -54,4 +64,28 @@ const afterMyTaskRefresh = () => {
myFinishedTaskRef?.value?.refresh();
myMessageRef?.value?.refresh();
};
const handRouteQuery = () => {
//
const routeQuery = route.query;
const taskId = routeQuery.taskId; /* 任务ID */
const type = routeQuery.type; /* 任务类型, task:待办; doneTask:已办; finishedTask:办结 */
const action = routeQuery.action; /* 操作 */
if (type === 'task') {
taskIdRef.value = taskId;
doneTaskIdRef.value = null;
finishedTaskIdRef.value = null;
} else if (type === 'doneTask') {
taskIdRef.value = null;
doneTaskIdRef.value = taskId;
finishedTaskIdRef.value = null;
} else {
taskIdRef.value = null;
doneTaskIdRef.value = null;
finishedTaskIdRef.value = taskId;
}
};
handRouteQuery();
</script>

2
io.sc.platform.core.frontend/src/platform/views/home/AnnouncementDialog.vue

@ -1,7 +1,7 @@
<template>
<w-dialog
ref="dialogRef"
:title="$t('home.card.announcement.title')"
:title="$t('home.card.myAnnouncement.title')"
:can-maximize="false"
:maximized="false"
body-padding="2px 2px 2px 2px"

32
io.sc.platform.core.frontend/src/platform/views/home/MyDoneTask.vue

@ -40,14 +40,14 @@
<q-tooltip :delay="1000">{{ item.name }}</q-tooltip>
</td>
<td width="60px" style="font-size: 0.8em; padding: 0px 4px">
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.previousAssignee }}</div>
<q-tooltip :delay="1000">{{ item.previousAssignee }}</q-tooltip>
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.assigneeName }}</div>
<q-tooltip :delay="1000">{{ item.assigneeName + '(' + item.assignee + ')' }}</q-tooltip>
</td>
<td width="70px" style="font-size: 0.8em; padding: 0px 4px" align="right">
<div class="truncate" style="width: 62px; max-width: 62px">
{{ item.createTimeAndNowDiff + $t(item.createTimeAndNowDiffUnit) + $t('before') }}
<td width="78px" style="font-size: 0.8em; padding: 0px 4px" align="right">
<div class="truncate" style="width: 70px; max-width: 70px">
{{ 999 + $t(item.startTimeAndNowDiffUnit) + $t('before') }}
</div>
<q-tooltip :delay="1000">{{ item.createTime }}</q-tooltip>
<q-tooltip :delay="1000">{{ item.startTime }}</q-tooltip>
</td>
</tr>
</tbody>
@ -60,10 +60,12 @@
</div>
</template>
<script setup lang="ts">
import { h, ref, defineAsyncComponent, nextTick } from 'vue';
import { h, ref, defineAsyncComponent, nextTick, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager } from '@/platform';
const props = defineProps({ taskId: { type: String, default: null } });
const router = useRouter();
const cardRef = ref();
const cardHeightRef = ref(200);
@ -77,7 +79,7 @@ const componentRef = ref();
const changeFirstColMaxWidth = () => {
//card width
let width = Math.ceil(cardRef.value.$el.clientWidth);
width = width - 8 /* card-section padding width */ - 12 /* td padding width */ - 290 /* other tds width*/ - 20 /* scroll bar width */;
width = width - 8 /* card-section padding width */ - 12 /* td padding width */ - 298 /* other tds width*/ - 20 /* scroll bar width */;
//min width
width = width >= 100 ? width : 100;
firstColMaxWidthRef.value = width;
@ -122,7 +124,19 @@ const handle = async (item: any) => {
}
};
refresh();
onMounted(() => {
if (props.taskId) {
axios.get(Environment.apiContextPath('/api/flowable/process/query/myDoneTaskById/' + props.taskId)).then((response: any) => {
const data = response?.data;
if (data) {
handle(data);
} else {
NotifyManager.error($t('home.card.task.tip.taskNotExists'));
}
});
}
refresh();
});
defineExpose({
refresh,

32
io.sc.platform.core.frontend/src/platform/views/home/MyFinishedTask.vue

@ -40,14 +40,14 @@
<q-tooltip :delay="1000">{{ item.name }}</q-tooltip>
</td>
<td width="60px" style="font-size: 0.8em; padding: 0px 4px">
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.previousAssignee }}</div>
<q-tooltip :delay="1000">{{ item.previousAssignee }}</q-tooltip>
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.assigneeName }}</div>
<q-tooltip :delay="1000">{{ item.assigneeName + '(' + item.assignee + ')' }}</q-tooltip>
</td>
<td width="70px" style="font-size: 0.8em; padding: 0px 4px" align="right">
<div class="truncate" style="width: 62px; max-width: 62px">
{{ item.createTimeAndNowDiff + $t(item.createTimeAndNowDiffUnit) + $t('before') }}
<td width="78px" style="font-size: 0.8em; padding: 0px 4px" align="right">
<div class="truncate" style="width: 70px; max-width: 70px">
{{ item.endTimeAndNowDiff + $t(item.endTimeAndNowDiffUnit) + $t('before') }}
</div>
<q-tooltip :delay="1000">{{ item.createTime }}</q-tooltip>
<q-tooltip :delay="1000">{{ item.endTime }}</q-tooltip>
</td>
</tr>
</tbody>
@ -60,10 +60,12 @@
</div>
</template>
<script setup lang="ts">
import { h, ref, defineAsyncComponent, nextTick } from 'vue';
import { h, ref, defineAsyncComponent, nextTick, onMounted } from 'vue';
import { useRouter } from 'vue-router';
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager } from '@/platform';
const props = defineProps({ taskId: { type: String, default: null } });
const router = useRouter();
const cardRef = ref();
const cardHeightRef = ref(200);
@ -77,7 +79,7 @@ const componentRef = ref();
const changeFirstColMaxWidth = () => {
//card width
let width = Math.ceil(cardRef.value.$el.clientWidth);
width = width - 8 /* card-section padding width */ - 12 /* td padding width */ - 290 /* other tds width*/ - 20 /* scroll bar width */;
width = width - 8 /* card-section padding width */ - 12 /* td padding width */ - 298 /* other tds width*/ - 20 /* scroll bar width */;
//min width
width = width >= 100 ? width : 100;
firstColMaxWidthRef.value = width;
@ -122,7 +124,19 @@ const handle = async (item: any) => {
}
};
refresh();
onMounted(() => {
if (props.taskId) {
axios.get(Environment.apiContextPath('/api/flowable/process/query/myFinishedTaskById/' + props.taskId)).then((response: any) => {
const data = response?.data;
if (data) {
handle(data);
} else {
NotifyManager.error($t('home.card.task.tip.taskNotExists'));
}
});
}
refresh();
});
defineExpose({
refresh,

61
io.sc.platform.core.frontend/src/platform/views/home/MyTask.vue

@ -15,37 +15,6 @@
</q-btn>
</div>
</q-card-section>
<!--<q-card-section style="padding: 0px 0px 0px 0px">
<div :style="{ width: '100%', height: tableHeightRef + 'px' }">
<w-grid
ref="i18nGridRef"
:config-button="false"
db-click-operation="edit"
:checkbox-selection="false"
dense
:hide-header="true"
separator="none"
:pageable="false"
:data-url="Environment.apiContextPath('/api/flowable/process/query/myTask?page=1&size=10&pageable=true')"
:toolbar-configure="{ noIcon: true }"
:columns="[
{ width: '100%', name: 'businessDescription' },
{ width: 100, name: 'processDefinitionName' },
{ width: 60, name: 'name' },
{ width: 60, name: 'previousAssignee' },
{
width: 70,
name: 'createTime',
format: (value, row) => {
return row.createTimeAndNowDiff + $t(row.createTimeAndNowDiffUnit) + $t('before');
},
},
]"
@row-click="(evt, row, index) => {}"
></w-grid>
</div>
</q-card-section>
-->
<q-card-section style="padding: 0px 6px 0px 6px">
<q-markup-table flat dense separator="none" :style="{ width: '100%', height: tableHeightRef + 'px', overflowY: 'auto' }">
<tbody>
@ -71,14 +40,14 @@
<q-tooltip :delay="1000">{{ item.name }}</q-tooltip>
</td>
<td width="60px" style="font-size: 0.8em; padding: 0px 4px">
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.previousAssignee }}</div>
<q-tooltip :delay="1000">{{ item.previousAssignee }}</q-tooltip>
<div class="truncate" style="width: 52px; max-width: 52px">{{ item.previousAssigneeName }}</div>
<q-tooltip :delay="1000">{{ item.previousAssigneeName + '(' + item.previousAssignee + ')' }}</q-tooltip>
</td>
<td width="70px" style="font-size: 0.8em; padding: 0px 4px" align="right">
<div class="truncate" style="width: 62px; max-width: 62px">
{{ item.createTimeAndNowDiff + $t(item.createTimeAndNowDiffUnit) + $t('before') }}
<td width="78px" style="font-size: 0.8em; padding: 0px 4px" align="right">
<div class="truncate" style="width: 70px; max-width: 70px">
{{ item.startTimeAndNowDiff + $t(item.startTimeAndNowDiffUnit) + $t('before') }}
</div>
<q-tooltip :delay="1000">{{ item.createTime }}</q-tooltip>
<q-tooltip :delay="1000">{{ item.startTime }}</q-tooltip>
</td>
</tr>
</tbody>
@ -94,7 +63,9 @@
import { h, ref, defineAsyncComponent, nextTick } from 'vue';
import { useRouter } from 'vue-router';
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager, QuasarTools } from '@/platform';
import { onMounted } from 'vue';
const props = defineProps({ taskId: { type: String, default: null } });
const emit = defineEmits(['afterRefresh']);
const router = useRouter();
@ -110,7 +81,7 @@ const componentRef = ref();
const changeFirstColMaxWidth = () => {
//card width
let width = Math.ceil(cardRef.value.$el.clientWidth);
width = width - 8 /* card-section padding width */ - 12 /* td padding width */ - 290 /* other tds width*/ - 20 /* scroll bar width */;
width = width - 8 /* card-section padding width */ - 12 /* td padding width */ - 298 /* other tds width*/ - 20 /* scroll bar width */;
//min width
width = width >= 100 ? width : 100;
firstColMaxWidthRef.value = width;
@ -156,7 +127,19 @@ const handle = async (item: any) => {
}
};
refresh();
onMounted(() => {
if (props.taskId) {
axios.get(Environment.apiContextPath('/api/flowable/process/query/myTaskById/' + props.taskId)).then((response: any) => {
const data = response?.data;
if (data) {
handle(data);
} else {
NotifyManager.error($t('home.card.task.tip.taskNotExists'));
}
});
}
refresh();
});
defineExpose({
refresh,

2
io.sc.platform.core.frontend/src/platform/views/home/SystemMessageDialog.vue

@ -1,7 +1,7 @@
<template>
<w-dialog
ref="dialogRef"
:title="$t('home.card.message.systemMessageDialog.title')"
:title="$t('home.card.myMessage.systemMessageDialog.title')"
:can-maximize="false"
:maximized="false"
body-padding="2px 2px 2px 2px"

2
io.sc.platform.core.frontend/src/platform/views/home/UserMessageDialog.vue

@ -1,7 +1,7 @@
<template>
<w-dialog
ref="dialogRef"
:title="$t('home.card.message.chatDialog.title', { sender: senderRef })"
:title="$t('home.card.myMessage.chatDialog.title', { sender: senderRef })"
:can-maximize="false"
:maximized="false"
body-padding="2px 2px 2px 2px"

13
io.sc.platform.core.frontend/src/routes/routes.json

@ -141,6 +141,19 @@
}
},
{
"name": "route.testcase.bpm",
"path": "testcase/bpm",
"parent": "/",
"priority": 0,
"component": "component.testcase.bpm",
"componentPath": "@/views/testcase/bpm/Bpm.vue",
"redirect": null,
"meta": {
"permissions": ["/testcase/bpm/**/*"]
}
},
{
"name": "route.testcase.likm.dialog",
"path": "testcase/likm/dialog",

142
io.sc.platform.core.frontend/src/views/testcase/bpm/Bpm.vue

@ -0,0 +1,142 @@
<template>
<div ref="containerRef"></div>
</template>
<script setup lang="ts">
/*
import { ref, onMounted } from 'vue';
import BpmnViewer from 'bpmn-js';
const containerRef = ref();
let viewer;
const xml =
"<?xml version='1.0' encoding='UTF-8'?>\n" +
' <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef" exporter="Flowable Open Source Modeler" exporterVersion="6.8.0">\n' +
' <process id="SAMPLE" name="示例流程" isExecutable="true">\n' +
' <dataObject id="assignment-strategy" name="分配策略" itemSubjectRef="xsd:string">\n' +
' <extensionElements>\n' +
' <flowable:value>{"A2":"platformAssigneeQueryService"}</flowable:value>\n' +
' </extensionElements>\n' +
' </dataObject>\n' +
' <startEvent id="start" name="开始" flowable:formFieldValidation="true"/>\n' +
' <userTask id="A1" name="提交申请" flowable:assignee="${assignee}" flowable:candidateGroups="admin" flowable:formFieldValidation="true" flowable:skipExpression="${execution.getVariable(\'skipFirst\') == true}">\n' +
' <extensionElements>\n' +
' <modeler:group-info-name-admin xmlns:modeler="http://flowable.org/modeler"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n' +
' <modeler:activiti-idm-candidate-group xmlns:modeler="http://flowable.org/modeler"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n' +
' <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>\n' +
' </extensionElements>\n' +
' </userTask>\n' +
' <userTask id="A2" name="复核" flowable:assignee="${assignee}" flowable:candidateGroups="admin" flowable:formFieldValidation="true">\n' +
' <extensionElements>\n' +
' <flowable:taskListener event="assignment" delegateExpression="${flowableSendMailListener}">\n' +
' <flowable:field name="title">\n' +
' <flowable:string><![CDATA[您有一个 [示例] 流程的 [复核] 任务等待处理]]></flowable:string>\n' +
' </flowable:field>\n' +
' <flowable:field name="content">\n' +
' <flowable:string><![CDATA[${assignee},您好! 您有一个 [示例] 流程的 [复核] 任务等待处理,详情参见: http://localhost:8080]]></flowable:string>\n' +
' </flowable:field>\n' +
' </flowable:taskListener>\n' +
' <modeler:group-info-name-admin xmlns:modeler="http://flowable.org/modeler"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n' +
' <modeler:activiti-idm-candidate-group xmlns:modeler="http://flowable.org/modeler"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n' +
' <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>\n' +
' </extensionElements>\n' +
' </userTask>\n' +
' <endEvent id="end" name="结束"/>\n' +
' <sequenceFlow id="sid-452257DA-C9ED-41BB-A95A-899D5F7FD363" sourceRef="start" targetRef="A1"/>\n' +
' <sequenceFlow id="sid-EC4C37D8-A419-4DD1-9569-DD93AE964688" sourceRef="A1" targetRef="A2"/>\n' +
' <userTask id="A3" name="认定" default="sid-95DCA487-E110-49BB-86F9-C623692DD8BA" flowable:assignee="${assignee}" flowable:candidateGroups="admin" flowable:formFieldValidation="true">\n' +
' <extensionElements>\n' +
' <modeler:group-info-name-admin xmlns:modeler="http://flowable.org/modeler"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n' +
' <modeler:activiti-idm-candidate-group xmlns:modeler="http://flowable.org/modeler"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n' +
' <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>\n' +
' </extensionElements>\n' +
' </userTask>\n' +
' <sequenceFlow id="sid-60D2D382-C039-4E2F-BC47-348DB6E9A02A" sourceRef="A2" targetRef="A3"/>\n' +
' <userTask id="A4" name="最终认定" flowable:assignee="${assignee}" flowable:candidateGroups="admin" flowable:formFieldValidation="true">\n' +
' <extensionElements>\n' +
' <modeler:group-info-name-admin xmlns:modeler="http://flowable.org/modeler"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n' +
' <modeler:activiti-idm-candidate-group xmlns:modeler="http://flowable.org/modeler"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n' +
' <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>\n' +
' </extensionElements>\n' +
' </userTask>\n' +
' <sequenceFlow id="sid-87E440E2-0998-4C95-B4A4-444397ADB79C" sourceRef="A4" targetRef="end"/>\n' +
' <sequenceFlow id="sid-95DCA487-E110-49BB-86F9-C623692DD8BA" sourceRef="A3" targetRef="A4"/>\n' +
' <sequenceFlow id="sid-74A758E1-9AB1-4E1C-9D03-EF323869EB4E" name="退回给复核岗" sourceRef="A3" targetRef="A2">\n' +
' <conditionExpression xsi:type="tFormalExpression"><![CDATA[${goback == -1}]]></conditionExpression>\n' +
' </sequenceFlow>\n' +
' <sequenceFlow id="sid-8C796912-0699-4ADA-9F3F-91154970C7E2" name="退回给申请人" sourceRef="A3" targetRef="A1">\n' +
' <conditionExpression xsi:type="tFormalExpression"><![CDATA[${goback == -2}]]></conditionExpression>\n' +
' </sequenceFlow>\n' +
' </process>\n' +
' <bpmndi:BPMNDiagram id="BPMNDiagram_SAMPLE">\n' +
' <bpmndi:BPMNPlane bpmnElement="SAMPLE" id="BPMNPlane_SAMPLE">\n' +
' <bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">\n' +
' <omgdc:Bounds height="30.0" width="30.0" x="60.0" y="168.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNShape bpmnElement="A1" id="BPMNShape_A1">\n' +
' <omgdc:Bounds height="40.0" width="96.0" x="120.0" y="160.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNShape bpmnElement="A2" id="BPMNShape_A2">\n' +
' <omgdc:Bounds height="40.0" width="81.0" x="255.0" y="160.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">\n' +
' <omgdc:Bounds height="28.0" width="28.0" x="615.0" y="166.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNShape bpmnElement="A3" id="BPMNShape_A3">\n' +
' <omgdc:Bounds height="42.0" width="82.0" x="375.0" y="159.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNShape bpmnElement="A4" id="BPMNShape_A4">\n' +
' <omgdc:Bounds height="40.0" width="92.0" x="495.0" y="160.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-74A758E1-9AB1-4E1C-9D03-EF323869EB4E" id="BPMNEdge_sid-74A758E1-9AB1-4E1C-9D03-EF323869EB4E" flowable:sourceDockerX="41.0" flowable:sourceDockerY="21.0" flowable:targetDockerX="40.0" flowable:targetDockerY="20.0">\n' +
' <omgdi:waypoint x="416.0" y="159.0"/>\n' +
' <omgdi:waypoint x="416.0" y="77.0"/>\n' +
' <omgdi:waypoint x="295.0" y="77.0"/>\n' +
' <omgdi:waypoint x="295.0" y="160.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-95DCA487-E110-49BB-86F9-C623692DD8BA" id="BPMNEdge_sid-95DCA487-E110-49BB-86F9-C623692DD8BA" flowable:sourceDockerX="41.0" flowable:sourceDockerY="21.0" flowable:targetDockerX="46.0" flowable:targetDockerY="20.0">\n' +
' <omgdi:waypoint x="456.0" y="180.0"/>\n' +
' <omgdi:waypoint x="494.0" y="180.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-60D2D382-C039-4E2F-BC47-348DB6E9A02A" id="BPMNEdge_sid-60D2D382-C039-4E2F-BC47-348DB6E9A02A" flowable:sourceDockerX="40.0" flowable:sourceDockerY="20.0" flowable:targetDockerX="41.0" flowable:targetDockerY="21.0">\n' +
' <omgdi:waypoint x="335.0" y="180.0"/>\n' +
' <omgdi:waypoint x="375.0" y="180.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-8C796912-0699-4ADA-9F3F-91154970C7E2" id="BPMNEdge_sid-8C796912-0699-4ADA-9F3F-91154970C7E2" flowable:sourceDockerX="41.0" flowable:sourceDockerY="21.0" flowable:targetDockerX="48.0" flowable:targetDockerY="20.0">\n' +
' <omgdi:waypoint x="416.0" y="201.0"/>\n' +
' <omgdi:waypoint x="416.0" y="284.0"/>\n' +
' <omgdi:waypoint x="168.0" y="284.0"/>\n' +
' <omgdi:waypoint x="168.0" y="200.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-87E440E2-0998-4C95-B4A4-444397ADB79C" id="BPMNEdge_sid-87E440E2-0998-4C95-B4A4-444397ADB79C" flowable:sourceDockerX="46.0" flowable:sourceDockerY="20.0" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0">\n' +
' <omgdi:waypoint x="586.0" y="180.0"/>\n' +
' <omgdi:waypoint x="615.0" y="180.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-EC4C37D8-A419-4DD1-9569-DD93AE964688" id="BPMNEdge_sid-EC4C37D8-A419-4DD1-9569-DD93AE964688" flowable:sourceDockerX="48.0" flowable:sourceDockerY="20.0" flowable:targetDockerX="40.0" flowable:targetDockerY="20.0">\n' +
' <omgdi:waypoint x="215.0" y="180.0"/>\n' +
' <omgdi:waypoint x="254.0" y="180.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-452257DA-C9ED-41BB-A95A-899D5F7FD363" id="BPMNEdge_sid-452257DA-C9ED-41BB-A95A-899D5F7FD363" flowable:sourceDockerX="15.0" flowable:sourceDockerY="15.0" flowable:targetDockerX="48.0" flowable:targetDockerY="20.0">\n' +
' <omgdi:waypoint x="89.0" y="183.0"/>\n' +
' <omgdi:waypoint x="120.0" y="182.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' </bpmndi:BPMNPlane>\n' +
' </bpmndi:BPMNDiagram>\n' +
' </definitions>';
onMounted(() => {
viewer = new BpmnViewer({
container: containerRef.value,
});
viewer
.importXML(xml)
.then((result) => {
const { warnings } = result;
console.log('success !', warnings);
viewer.get('canvas').zoom('fit-viewport');
})
.catch(function (err) {
const { warnings, message } = err;
console.log('something went wrong:', warnings, message);
});
});
*/
</script>

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

@ -1,6 +1,6 @@
{
"name": "platform-core",
"version": "8.2.117",
"version": "8.2.121",
"description": "前端核心包,用于快速构建前端的脚手架",
"private": false,
"keywords": [],
@ -111,7 +111,7 @@
"mockjs": "1.1.0",
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

2
io.sc.platform.core.frontend/template-project/src/components/index.ts

@ -13,6 +13,7 @@ import component_testcase_excel from '@/views/testcase/excel/Excel.vue';
import component_testcase_word from '@/views/testcase/word/Word.vue';
import component_testcase_maxgraph from '@/views/testcase/maxgraph/Maxgraph.vue';
import component_testcase_ai from '@/views/testcase/ai/Ai.vue';
import component_testcase_bpm from '@/views/testcase/bpm/Bpm.vue';
import component_testcase_likmDialog from '@/views/likm/Dialog.vue';
import component_testcase_likmDrawer from '@/views/likm/Drawer.vue';
import component_testcase_likmForm from '@/views/likm/Form.vue';
@ -35,6 +36,7 @@ const localComponents = {
'component.testcase.word': component_testcase_word,
'component.testcase.maxgraph': component_testcase_maxgraph,
'component.testcase.ai': component_testcase_ai,
'component.testcase.bpm': component_testcase_bpm,
'component.testcase.likmDialog': component_testcase_likmDialog,
'component.testcase.likmDrawer': component_testcase_likmDrawer,
'component.testcase.likmForm': component_testcase_likmForm,

1
io.sc.platform.core.frontend/template-project/src/i18n/messages.json

@ -12,6 +12,7 @@
"menu.testcase.word": "Word",
"menu.testcase.maxgraph": "Graph Editor",
"menu.testcase.ai": "AI",
"menu.testcase.bpm": "BPM",
"route.testcase.noMenuRoute": "No Menu Route"
}

1
io.sc.platform.core.frontend/template-project/src/i18n/messages_tw_CN.json

@ -12,6 +12,7 @@
"menu.testcase.word": "Word",
"menu.testcase.maxgraph": "图形编辑器",
"menu.testcase.ai": "AI",
"menu.testcase.bpm": "BPM",
"route.testcase.noMenuRoute": "無關聯菜單路由"
}

1
io.sc.platform.core.frontend/template-project/src/i18n/messages_zh_CN.json

@ -12,6 +12,7 @@
"menu.testcase.word": "Word",
"menu.testcase.maxgraph": "图形编辑器",
"menu.testcase.ai": "AI",
"menu.testcase.bpm": "BPM",
"route.testcase.noMenuRoute": "无关联菜单路由"
}

10
io.sc.platform.core.frontend/template-project/src/menus/menus.json

@ -127,7 +127,15 @@
"icon": "bi-palette",
"routeName": "route.testcase.ai"
},
{
"type": "ROUTE",
"order": 800,
"parentId": "menu.testcase",
"id": "menu.testcase.bpm",
"titleI18nKey": "menu.testcase.bpm",
"icon": "bi-palette",
"routeName": "route.testcase.bpm"
},
{ "type": "GROUP", "order": 30000, "id": "menu.testcase.likm", "titleI18nKey": "测试用例-likm", "icon": "home" },
{
"type": "ROUTE",

13
io.sc.platform.core.frontend/template-project/src/routes/routes.json

@ -141,6 +141,19 @@
}
},
{
"name": "route.testcase.bpm",
"path": "testcase/bpm",
"parent": "/",
"priority": 0,
"component": "component.testcase.bpm",
"componentPath": "@/views/testcase/bpm/Bpm.vue",
"redirect": null,
"meta": {
"permissions": ["/testcase/bpm/**/*"]
}
},
{
"name": "route.testcase.likm.dialog",
"path": "testcase/likm/dialog",

142
io.sc.platform.core.frontend/template-project/src/views/testcase/bpm/Bpm.vue

@ -0,0 +1,142 @@
<template>
<div ref="containerRef"></div>
</template>
<script setup lang="ts">
/*
import { ref, onMounted } from 'vue';
import BpmnViewer from 'bpmn-js';
const containerRef = ref();
let viewer;
const xml =
"<?xml version='1.0' encoding='UTF-8'?>\n" +
' <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef" exporter="Flowable Open Source Modeler" exporterVersion="6.8.0">\n' +
' <process id="SAMPLE" name="示例流程" isExecutable="true">\n' +
' <dataObject id="assignment-strategy" name="分配策略" itemSubjectRef="xsd:string">\n' +
' <extensionElements>\n' +
' <flowable:value>{"A2":"platformAssigneeQueryService"}</flowable:value>\n' +
' </extensionElements>\n' +
' </dataObject>\n' +
' <startEvent id="start" name="开始" flowable:formFieldValidation="true"/>\n' +
' <userTask id="A1" name="提交申请" flowable:assignee="${assignee}" flowable:candidateGroups="admin" flowable:formFieldValidation="true" flowable:skipExpression="${execution.getVariable(\'skipFirst\') == true}">\n' +
' <extensionElements>\n' +
' <modeler:group-info-name-admin xmlns:modeler="http://flowable.org/modeler"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n' +
' <modeler:activiti-idm-candidate-group xmlns:modeler="http://flowable.org/modeler"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n' +
' <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>\n' +
' </extensionElements>\n' +
' </userTask>\n' +
' <userTask id="A2" name="复核" flowable:assignee="${assignee}" flowable:candidateGroups="admin" flowable:formFieldValidation="true">\n' +
' <extensionElements>\n' +
' <flowable:taskListener event="assignment" delegateExpression="${flowableSendMailListener}">\n' +
' <flowable:field name="title">\n' +
' <flowable:string><![CDATA[您有一个 [示例] 流程的 [复核] 任务等待处理]]></flowable:string>\n' +
' </flowable:field>\n' +
' <flowable:field name="content">\n' +
' <flowable:string><![CDATA[${assignee},您好! 您有一个 [示例] 流程的 [复核] 任务等待处理,详情参见: http://localhost:8080]]></flowable:string>\n' +
' </flowable:field>\n' +
' </flowable:taskListener>\n' +
' <modeler:group-info-name-admin xmlns:modeler="http://flowable.org/modeler"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n' +
' <modeler:activiti-idm-candidate-group xmlns:modeler="http://flowable.org/modeler"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n' +
' <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>\n' +
' </extensionElements>\n' +
' </userTask>\n' +
' <endEvent id="end" name="结束"/>\n' +
' <sequenceFlow id="sid-452257DA-C9ED-41BB-A95A-899D5F7FD363" sourceRef="start" targetRef="A1"/>\n' +
' <sequenceFlow id="sid-EC4C37D8-A419-4DD1-9569-DD93AE964688" sourceRef="A1" targetRef="A2"/>\n' +
' <userTask id="A3" name="认定" default="sid-95DCA487-E110-49BB-86F9-C623692DD8BA" flowable:assignee="${assignee}" flowable:candidateGroups="admin" flowable:formFieldValidation="true">\n' +
' <extensionElements>\n' +
' <modeler:group-info-name-admin xmlns:modeler="http://flowable.org/modeler"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n' +
' <modeler:activiti-idm-candidate-group xmlns:modeler="http://flowable.org/modeler"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n' +
' <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>\n' +
' </extensionElements>\n' +
' </userTask>\n' +
' <sequenceFlow id="sid-60D2D382-C039-4E2F-BC47-348DB6E9A02A" sourceRef="A2" targetRef="A3"/>\n' +
' <userTask id="A4" name="最终认定" flowable:assignee="${assignee}" flowable:candidateGroups="admin" flowable:formFieldValidation="true">\n' +
' <extensionElements>\n' +
' <modeler:group-info-name-admin xmlns:modeler="http://flowable.org/modeler"><![CDATA[系统管理员]]></modeler:group-info-name-admin>\n' +
' <modeler:activiti-idm-candidate-group xmlns:modeler="http://flowable.org/modeler"><![CDATA[true]]></modeler:activiti-idm-candidate-group>\n' +
' <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>\n' +
' </extensionElements>\n' +
' </userTask>\n' +
' <sequenceFlow id="sid-87E440E2-0998-4C95-B4A4-444397ADB79C" sourceRef="A4" targetRef="end"/>\n' +
' <sequenceFlow id="sid-95DCA487-E110-49BB-86F9-C623692DD8BA" sourceRef="A3" targetRef="A4"/>\n' +
' <sequenceFlow id="sid-74A758E1-9AB1-4E1C-9D03-EF323869EB4E" name="退回给复核岗" sourceRef="A3" targetRef="A2">\n' +
' <conditionExpression xsi:type="tFormalExpression"><![CDATA[${goback == -1}]]></conditionExpression>\n' +
' </sequenceFlow>\n' +
' <sequenceFlow id="sid-8C796912-0699-4ADA-9F3F-91154970C7E2" name="退回给申请人" sourceRef="A3" targetRef="A1">\n' +
' <conditionExpression xsi:type="tFormalExpression"><![CDATA[${goback == -2}]]></conditionExpression>\n' +
' </sequenceFlow>\n' +
' </process>\n' +
' <bpmndi:BPMNDiagram id="BPMNDiagram_SAMPLE">\n' +
' <bpmndi:BPMNPlane bpmnElement="SAMPLE" id="BPMNPlane_SAMPLE">\n' +
' <bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">\n' +
' <omgdc:Bounds height="30.0" width="30.0" x="60.0" y="168.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNShape bpmnElement="A1" id="BPMNShape_A1">\n' +
' <omgdc:Bounds height="40.0" width="96.0" x="120.0" y="160.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNShape bpmnElement="A2" id="BPMNShape_A2">\n' +
' <omgdc:Bounds height="40.0" width="81.0" x="255.0" y="160.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">\n' +
' <omgdc:Bounds height="28.0" width="28.0" x="615.0" y="166.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNShape bpmnElement="A3" id="BPMNShape_A3">\n' +
' <omgdc:Bounds height="42.0" width="82.0" x="375.0" y="159.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNShape bpmnElement="A4" id="BPMNShape_A4">\n' +
' <omgdc:Bounds height="40.0" width="92.0" x="495.0" y="160.5"/>\n' +
' </bpmndi:BPMNShape>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-74A758E1-9AB1-4E1C-9D03-EF323869EB4E" id="BPMNEdge_sid-74A758E1-9AB1-4E1C-9D03-EF323869EB4E" flowable:sourceDockerX="41.0" flowable:sourceDockerY="21.0" flowable:targetDockerX="40.0" flowable:targetDockerY="20.0">\n' +
' <omgdi:waypoint x="416.0" y="159.0"/>\n' +
' <omgdi:waypoint x="416.0" y="77.0"/>\n' +
' <omgdi:waypoint x="295.0" y="77.0"/>\n' +
' <omgdi:waypoint x="295.0" y="160.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-95DCA487-E110-49BB-86F9-C623692DD8BA" id="BPMNEdge_sid-95DCA487-E110-49BB-86F9-C623692DD8BA" flowable:sourceDockerX="41.0" flowable:sourceDockerY="21.0" flowable:targetDockerX="46.0" flowable:targetDockerY="20.0">\n' +
' <omgdi:waypoint x="456.0" y="180.0"/>\n' +
' <omgdi:waypoint x="494.0" y="180.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-60D2D382-C039-4E2F-BC47-348DB6E9A02A" id="BPMNEdge_sid-60D2D382-C039-4E2F-BC47-348DB6E9A02A" flowable:sourceDockerX="40.0" flowable:sourceDockerY="20.0" flowable:targetDockerX="41.0" flowable:targetDockerY="21.0">\n' +
' <omgdi:waypoint x="335.0" y="180.0"/>\n' +
' <omgdi:waypoint x="375.0" y="180.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-8C796912-0699-4ADA-9F3F-91154970C7E2" id="BPMNEdge_sid-8C796912-0699-4ADA-9F3F-91154970C7E2" flowable:sourceDockerX="41.0" flowable:sourceDockerY="21.0" flowable:targetDockerX="48.0" flowable:targetDockerY="20.0">\n' +
' <omgdi:waypoint x="416.0" y="201.0"/>\n' +
' <omgdi:waypoint x="416.0" y="284.0"/>\n' +
' <omgdi:waypoint x="168.0" y="284.0"/>\n' +
' <omgdi:waypoint x="168.0" y="200.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-87E440E2-0998-4C95-B4A4-444397ADB79C" id="BPMNEdge_sid-87E440E2-0998-4C95-B4A4-444397ADB79C" flowable:sourceDockerX="46.0" flowable:sourceDockerY="20.0" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0">\n' +
' <omgdi:waypoint x="586.0" y="180.0"/>\n' +
' <omgdi:waypoint x="615.0" y="180.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-EC4C37D8-A419-4DD1-9569-DD93AE964688" id="BPMNEdge_sid-EC4C37D8-A419-4DD1-9569-DD93AE964688" flowable:sourceDockerX="48.0" flowable:sourceDockerY="20.0" flowable:targetDockerX="40.0" flowable:targetDockerY="20.0">\n' +
' <omgdi:waypoint x="215.0" y="180.0"/>\n' +
' <omgdi:waypoint x="254.0" y="180.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' <bpmndi:BPMNEdge bpmnElement="sid-452257DA-C9ED-41BB-A95A-899D5F7FD363" id="BPMNEdge_sid-452257DA-C9ED-41BB-A95A-899D5F7FD363" flowable:sourceDockerX="15.0" flowable:sourceDockerY="15.0" flowable:targetDockerX="48.0" flowable:targetDockerY="20.0">\n' +
' <omgdi:waypoint x="89.0" y="183.0"/>\n' +
' <omgdi:waypoint x="120.0" y="182.0"/>\n' +
' </bpmndi:BPMNEdge>\n' +
' </bpmndi:BPMNPlane>\n' +
' </bpmndi:BPMNDiagram>\n' +
' </definitions>';
onMounted(() => {
viewer = new BpmnViewer({
container: containerRef.value,
});
viewer
.importXML(xml)
.then((result) => {
const { warnings } = result;
console.log('success !', warnings);
viewer.get('canvas').zoom('fit-viewport');
})
.catch(function (err) {
const { warnings, message } = err;
console.log('something went wrong:', warnings, message);
});
});
*/
</script>

4
io.sc.platform.developer.doc/package.json

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.developer.doc",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"main": "index.js",
"scripts": {
@ -28,7 +28,7 @@
"vuepress": "2.0.0-rc.15"
},
"dependencies": {
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"vue": "3.5.13",
"vue-i18n": "11.0.1"

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

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.developer.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

22
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessEntityWebController.java

@ -7,10 +7,11 @@ import io.sc.platform.flowable.jpa.entity.ProcessEntity;
import io.sc.platform.flowable.jpa.repository.ProcessEntityRepository;
import io.sc.platform.flowable.service.ProcessEntityService;
import io.sc.platform.mvc.controller.support.RestCrudController;
import io.sc.platform.orm.util.EntityVoUtil;
import org.flowable.bpmn.model.UserTask;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.*;
@RestController("io.sc.platform.flowable.controller.ProcessEntityWebController")
@RequestMapping("/api/flowable/process")
@ -20,9 +21,22 @@ public class ProcessEntityWebController extends RestCrudController<ProcessVo, Pr
service.deploy(id);
}
@GetMapping("findAllDeployedProcessDefines")
public List<ProcessVo> findAllDeployedProcessDefines() throws Exception {
return service.findAllDeployedProcessDefines();
@PostMapping("findByProcessDefineKeysExcludes")
public Map<String,String> findByProcessDefineKeysExcludes(@RequestBody Set<String> excludes) throws Exception {
List<ProcessEntity> entities =null;
if(excludes==null || excludes.isEmpty()){
entities =service.getRepository().findByProcessDefineKeys();
}else {
entities =service.getRepository().findByProcessDefineKeysExcludes(excludes);
}
if(entities==null || entities.isEmpty()){
return Collections.emptyMap();
}
Map<String,String> restult =new LinkedHashMap<>();
for(ProcessEntity entity : entities){
restult.put(entity.getKey(),entity.getName());
}
return restult;
}
@GetMapping("findUserTasksByProcessDeployId/{deployId}")

19
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessQueryWebController.java

@ -63,15 +63,30 @@ public class ProcessQueryWebController {
return service.queryProcessTasks(queryParameter);
}
@GetMapping("myTaskById/{taskId}")
public ProcessTaskWrapper myTaskById(@PathVariable("taskId")String taskId) throws Exception {
return service.queryProcessTaskById(taskId);
}
@GetMapping("myDoneTask")
public Page<ProcessTaskWrapper> doneTask(QueryParameter queryParameter) throws Exception {
public Page<ProcessTaskWrapper> myDoneTask(QueryParameter queryParameter) throws Exception {
return service.queryDoneProcessTasks(queryParameter);
}
@GetMapping("myDoneTaskById/{taskId}")
public ProcessTaskWrapper myDoneTaskById(@PathVariable("taskId")String taskId) throws Exception {
return service.queryDoneProcessTaskById(taskId);
}
@GetMapping("myFinishedTask")
public Page<ProcessTaskWrapper> finishedTask(QueryParameter queryParameter) throws Exception {
public Page<ProcessTaskWrapper> myFinishedTask(QueryParameter queryParameter) throws Exception {
return service.queryFinishedProcessTasks(queryParameter);
}
@GetMapping("myFinishedTaskById/{taskId}")
public ProcessTaskWrapper myFinishedTaskById(@PathVariable("taskId")String taskId) throws Exception {
return service.queryFinishedProcessTaskById(taskId);
}
@GetMapping("variable")
public List<VariableWrapper> variableQuery(@RequestParam(name="procInstId",required=false) String procInstId) throws Exception{

17
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/repository/ProcessEntityRepository.java

@ -3,9 +3,12 @@ package io.sc.platform.flowable.jpa.repository;
import io.sc.platform.flowable.jpa.entity.ProcessEntity;
import io.sc.platform.flowable.enums.ProcessStatus;
import io.sc.platform.orm.repository.DaoRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Set;
@Repository("io.sc.platform.flowable.jpa.repository.ProcessEntityRepository")
public interface ProcessEntityRepository extends DaoRepository<ProcessEntity,String> {
@ -30,6 +33,14 @@ public interface ProcessEntityRepository extends DaoRepository<ProcessEntity,Str
* @return 流程定义实体
*/
public ProcessEntity findByDeployedId(String deployedId);
/**
* 通过流程Key和状态获取流程定义实体
* @param key 流程定义 Key
* @param status 流程发布状态
* @return 流程定义实体
*/
public ProcessEntity findByKeyAndStatus(String key, ProcessStatus status);
/**
* 查询流程定义实体
@ -54,4 +65,10 @@ public interface ProcessEntityRepository extends DaoRepository<ProcessEntity,Str
* @return 流程定义实体
*/
public List<ProcessEntity> findByStatusOrderByVersion(ProcessStatus status);
@Query("select e from io.sc.platform.flowable.jpa.entity.ProcessEntity e where e.key not in (:excludes) order by e.name")
public List<ProcessEntity> findByProcessDefineKeysExcludes(@Param("excludes")Set<String> excludes);
@Query("select e from io.sc.platform.flowable.jpa.entity.ProcessEntity e order by e.name")
public List<ProcessEntity> findByProcessDefineKeys();
}

24
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/ProcessQueryService.java

@ -48,6 +48,14 @@ public interface ProcessQueryService {
*/
public Page<ProcessTaskWrapper> queryProcessTasks(QueryParameter queryParameter) throws Exception;
/**
* 查询任务(代办)
* @param taskId 任务ID
* @return 任务
* @throws Exception 违例
*/
public ProcessTaskWrapper queryProcessTaskById(String taskId) throws Exception;
/**
* 查询任务(已办)
* @param queryParameter 查询参数
@ -56,6 +64,14 @@ public interface ProcessQueryService {
*/
public Page<ProcessTaskWrapper> queryDoneProcessTasks(QueryParameter queryParameter) throws Exception;
/**
* 查询任务(已办)
* @param taskId 任务ID
* @return 任务
* @throws Exception 违例
*/
public ProcessTaskWrapper queryDoneProcessTaskById(String taskId) throws Exception;
/**
* 查询任务(办结)
* @param queryParameter 查询参数
@ -64,6 +80,14 @@ public interface ProcessQueryService {
*/
public Page<ProcessTaskWrapper> queryFinishedProcessTasks(QueryParameter queryParameter) throws Exception;
/**
* 查询任务(办结)
* @param taskId 任务ID
* @return 任务
* @throws Exception 违例
*/
public ProcessTaskWrapper queryFinishedProcessTaskById(String taskId) throws Exception;
/**
* 查询流程实例变量集

4
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/ProcessEntityServiceImpl.java

@ -35,7 +35,7 @@ public class ProcessEntityServiceImpl extends DaoServiceImpl<ProcessEntity, Stri
@Override
public boolean canClaimTask(String deployedId) {
ProcessEntity entity =repository.findByDeployedId(deployedId);
if(entity.getCanClaimTask()==null){
if(entity==null || entity.getCanClaimTask()==null){
return false;
}
return entity.getCanClaimTask();
@ -44,7 +44,7 @@ public class ProcessEntityServiceImpl extends DaoServiceImpl<ProcessEntity, Stri
@Override
public boolean isForceSelectAssignee(String deployedId) {
ProcessEntity entity =repository.findByDeployedId(deployedId);
if(entity.getForceSelectAssignee()==null){
if(entity==null || entity.getForceSelectAssignee()==null){
return false;
}
return entity.getForceSelectAssignee();

52
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/ProcessOperationServiceImpl.java

@ -11,8 +11,10 @@ import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import io.sc.platform.flowable.enums.ProcessStatus;
import io.sc.platform.flowable.exception.NoAvailableAssigneeException;
import io.sc.platform.flowable.jpa.entity.AgentEntity;
import io.sc.platform.flowable.jpa.entity.ProcessEntity;
import io.sc.platform.flowable.service.AgentService;
import io.sc.platform.flowable.service.AssigneeQueryService;
import io.sc.platform.flowable.service.ProcessEntityService;
@ -20,6 +22,7 @@ import io.sc.platform.flowable.service.ProcessOperationService;
import io.sc.platform.flowable.support.*;
import io.sc.platform.flowable.support.command.JumpTaskCommand;
import io.sc.platform.security.util.SecurityUtil;
import io.sc.platform.util.StringUtil;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.SequenceFlow;
@ -39,6 +42,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
@ -52,6 +56,7 @@ public class ProcessOperationServiceImpl implements ProcessOperationService {
private static final Pattern GO_BACK_VARIABLE_PATTERN = Pattern.compile(FrameworkVariableNames.GO_BACK + "\\s*==\\s*([-]?\\d*)");
private static final String DEFAULT_ASSIGNMENT_STRATEGY_SPRING_BEAN_NAME ="io.sc.platform.flowable.service.impl.AssigneeQueryServiceImpl";
private static final String ASSIGNMENT_STRATEGY_DATA_OBJECT_ID ="assignment-strategy";
@Autowired private JdbcTemplate jdbcTemplate;
@Autowired private RuntimeService runtimeService;
@Autowired private HistoryService historyService;
@Autowired private RepositoryService repositoryService;
@ -76,12 +81,14 @@ public class ProcessOperationServiceImpl implements ProcessOperationService {
ProcessInstanceBuilder builder =runtimeService.createProcessInstanceBuilder();
builder.processDefinitionKey(processDefinitionKey);
builder.businessKey(bussinessKey);
//builder.name(getNameByProcessDefinitionKey(processDefinitionKey,bussinessKey));
if(variables!=null){
builder.variables(variables);
}
builder.transientVariables(convertTransientVariables(variables,transientVariables));
ProcessInstance processInstance =builder.start();
insertProcInsExtByDefinitionKey(processDefinitionKey,processInstance.getId(),bussinessKey);
return startProcess(processInstance,variables,transientVariables,autoCompleteFirstTask);
}
@ -98,6 +105,7 @@ public class ProcessOperationServiceImpl implements ProcessOperationService {
ProcessInstanceBuilder builder =runtimeService.createProcessInstanceBuilder();
builder.processDefinitionId(processDefinitionId);
builder.businessKey(bussinessKey);
//builder.name(getNameByProcessDefinitionId(processDefinitionId,bussinessKey));
if(variables!=null){
builder.variables(variables);
}
@ -105,6 +113,7 @@ public class ProcessOperationServiceImpl implements ProcessOperationService {
builder.transientVariables(convertTransientVariables(variables,transientVariables));
ProcessInstance processInstance =builder.start();
insertProcInsExtByDefinitionId(processDefinitionId,processInstance.getId(),bussinessKey);
return startProcess(processInstance,variables,transientVariables,autoCompleteFirstTask);
}
@ -420,6 +429,49 @@ public class ProcessOperationServiceImpl implements ProcessOperationService {
public void jumpTask(String taskId, String targetActivityId, String targetAssignee) throws Exception {
managementService.executeCommand(new JumpTaskCommand(taskId,targetActivityId,targetAssignee));
}
@Transactional
private void insertProcInsExtByDefinitionKey(String processDefinitionKey,String processInstanceId,String businessKey){
if(!StringUtils.hasText(processDefinitionKey) || !StringUtils.hasText(processInstanceId) || !StringUtils.hasText(businessKey)){
return;
}
ProcessEntity entity =processEntityService.getRepository().findByKeyAndStatus(processDefinitionKey, ProcessStatus.RELEASE);
if(entity==null || !StringUtils.hasText(entity.getBusinessDescriptionSql())){
return;
}
Map<String,Object> variables =new HashMap<>();
variables.put("businessKey",StringUtil.escapeSqlSpecialChar(businessKey));
String sql =StringUtil.format(entity.getBusinessDescriptionSql(),variables);
BusinessKeyAndDescriptionWrapper wrapper =jdbcTemplate.queryForObject(sql,new BusinessKeyAndDescriptionWrapperMapper());
if(wrapper==null){
return;
}
jdbcTemplate.update("insert into SYS_PROCESS_INST_EXT(PROC_INST_ID_,CUST_NO_,CUST_NAME_) values(?,?,?)",processInstanceId,wrapper.getCustNo(),wrapper.getCustName());
}
@Transactional
private void insertProcInsExtByDefinitionId(String processDefinitionId, String processInstanceId, String businessKey){
if(!StringUtils.hasText(processDefinitionId) || !StringUtils.hasText(processInstanceId) || !StringUtils.hasText(businessKey)){
return;
}
ProcessEntity entity =processEntityService.getRepository().findByDeployedId(processDefinitionId);
if(entity==null || !StringUtils.hasText(entity.getBusinessDescriptionSql())){
return;
}
Map<String,Object> variables =new HashMap<>();
variables.put("businessKey",StringUtil.escapeSqlSpecialChar(businessKey));
String sql =StringUtil.format(entity.getBusinessDescriptionSql(),variables);
BusinessKeyAndDescriptionWrapper wrapper =jdbcTemplate.queryForObject(sql,new BusinessKeyAndDescriptionWrapperMapper());
if(wrapper==null){
return;
}
jdbcTemplate.update("insert into SYS_PROCESS_INST_EXT(PROC_INST_ID_,CUST_NO_,CUST_NAME_) values(?,?,?)",processInstanceId,wrapper.getCustNo(),wrapper.getCustName());
}
private AssigneeQueryService getAssignmentStrategySpringBean(BpmnModel model,ProcessInstance processInstance,UserTask taskDefine) {
String beanName =DEFAULT_ASSIGNMENT_STRATEGY_SPRING_BEAN_NAME;

650
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/ProcessQueryServiceImpl.java

@ -1,6 +1,5 @@
package io.sc.platform.flowable.service.impl;
import io.sc.platform.flowable.jpa.entity.ProcessEntity;
import io.sc.platform.flowable.service.AssigneeQueryService;
import io.sc.platform.flowable.service.ProcessEntityService;
import io.sc.platform.flowable.service.ProcessQueryService;
@ -10,11 +9,10 @@ import io.sc.platform.lcdp.form.service.JdbcTemplateService;
import io.sc.platform.orm.service.support.QueryParameter;
import io.sc.platform.orm.service.support.QueryResult;
import io.sc.platform.orm.service.support.criteria.Criteria;
import io.sc.platform.orm.service.support.criteria.impl.Contains;
import io.sc.platform.orm.service.support.criteria.impl.Equals;
import io.sc.platform.security.util.SecurityUtil;
import io.sc.platform.util.CollectionUtil;
import io.sc.platform.util.DateUtil;
import io.sc.platform.util.FileUtil;
import io.sc.platform.util.StringUtil;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.EndEvent;
@ -24,14 +22,13 @@ import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.image.impl.DefaultProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
@ -42,6 +39,7 @@ import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
@ -61,7 +59,31 @@ public class ProcessQueryServiceImpl implements ProcessQueryService {
@Autowired private Dialect dialect;
@Autowired private JdbcTemplate jdbcTemplate;
@Override
private static final String PROCESS_TASK_SQL;
private static final String PROCESS_PREFIX_ASSIGNEE_SQL;
private static final String DONE_TASK_SQL;
private static final String FINISHED_TASK_SQL;
private static final String PROCESS_TASK_BY_ID_SQL;
private static final String DONE_TASK_BY_ID_SQL;
private static final String FINISHED_TASK_BY_ID_SQL;
static {
try {
PROCESS_TASK_SQL = FileUtil.readString("classpath:/io/sc/platform/flowable/service/impl/sql/MyTasks.sql");
PROCESS_PREFIX_ASSIGNEE_SQL = FileUtil.readString("classpath:/io/sc/platform/flowable/service/impl/sql/ProcessPrefixAssignee.sql");
DONE_TASK_SQL = FileUtil.readString("classpath:/io/sc/platform/flowable/service/impl/sql/MyDoneTasks.sql");
FINISHED_TASK_SQL = FileUtil.readString("classpath:/io/sc/platform/flowable/service/impl/sql/MyFinishedTasks.sql");
PROCESS_TASK_BY_ID_SQL = FileUtil.readString("classpath:/io/sc/platform/flowable/service/impl/sql/Task.sql");
DONE_TASK_BY_ID_SQL = FileUtil.readString("classpath:/io/sc/platform/flowable/service/impl/sql/DoneTask.sql");
FINISHED_TASK_BY_ID_SQL = FileUtil.readString("classpath:/io/sc/platform/flowable/service/impl/sql/FinishedTask.sql");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public ProcessDefinition queryProcessDefinition(String processDefinitionId) {
return repositoryService.getProcessDefinition(processDefinitionId);
}
@ -209,574 +231,152 @@ public class ProcessQueryServiceImpl implements ProcessQueryService {
}
return new PageImpl<ProcessInstanceWrapper>(wrappers,pageable,total);
}
@Override
public Page<ProcessTaskWrapper> queryProcessTasks(QueryParameter queryParameter) throws Exception {
TaskQuery query =taskService.createTaskQuery();
if(queryParameter!=null && queryParameter.existsCriteria()){
// 流程定义ID
Criteria processDefinitionIdCriteria =queryParameter.getCriteriaByFieldName("processDefinitionId");
if(processDefinitionIdCriteria!=null && processDefinitionIdCriteria instanceof Equals){
Equals _processDefinitionIdCriteria =(Equals)processDefinitionIdCriteria;
query.processDefinitionId(_processDefinitionIdCriteria.getValue());
}
// 流程实例ID
Criteria processInstanceIdCriteria =queryParameter.getCriteriaByFieldName("processInstanceId");
if(processInstanceIdCriteria!=null && processInstanceIdCriteria instanceof Equals){
Equals _processInstanceIdCriteria =(Equals)processInstanceIdCriteria;
query.processInstanceId(_processInstanceIdCriteria.getValue());
}
// 业务ID
Criteria businessKeyCriteria =queryParameter.getCriteriaByFieldName("businessKey");
if(businessKeyCriteria!=null && businessKeyCriteria instanceof Equals){
Equals _businessKeyCriteria =(Equals)businessKeyCriteria;
query.processInstanceBusinessKeyLike("%" + _businessKeyCriteria.getValue() + "%");
}
// 处理人
Criteria assigneeCriteria =queryParameter.getCriteriaByFieldName("assignee");
if(assigneeCriteria!=null && assigneeCriteria instanceof Equals){
Equals _assigneeCriteria =(Equals)assigneeCriteria;
query.taskAssignee(_assigneeCriteria.getValue());
}
// 任务节点 KEY
Criteria taskDefinitionKeyCriteria =queryParameter.getCriteriaByFieldName("taskDefinitionKey");
if(taskDefinitionKeyCriteria!=null && taskDefinitionKeyCriteria instanceof Equals){
Equals _taskDefinitionKeyCriteria =(Equals)taskDefinitionKeyCriteria;
query.taskDefinitionKey(_taskDefinitionKeyCriteria.getValue());
}
// 任务描述
Criteria taskDescriptionCriteria =queryParameter.getCriteriaByFieldName("description");
if(taskDescriptionCriteria!=null && taskDescriptionCriteria instanceof Contains){
Contains _taskDescriptionCriteria =(Contains)taskDescriptionCriteria;
query.taskDescriptionLike("%" + StringUtil.escapeSqlSpecialChar(_taskDescriptionCriteria.getValue()) + "%");
}
}
if(queryParameter!=null && queryParameter.existsSortBy()){
Order order =queryParameter.getFirstSort();
String propertyName =order.getProperty();
if("id".equals(propertyName)){
if(order.isDescending()){
query.orderByTaskId().desc();
}else {
query.orderByTaskId().asc();
}
}else if("assignee".equals(propertyName)){
if(order.isDescending()){
query.orderByTaskAssignee().desc();
}else {
query.orderByTaskAssignee().asc();
}
}else if("createTime".equals(propertyName)){
if(order.isDescending()){
query.orderByTaskCreateTime().desc();
}else {
query.orderByTaskCreateTime().asc();
}
}else if("owner".equals(propertyName)){
if(order.isDescending()){
query.orderByTaskOwner().desc();
}else {
query.orderByTaskOwner().asc();
}
}else if("name".equals(propertyName)){
if(order.isDescending()){
query.orderByTaskName().desc();
}else {
query.orderByTaskName().asc();
}
}
}else{
query.orderByTaskCreateTime().desc();
}
Pageable pageable =queryParameter.getJpaPageable();
long total =query.count();
List<Task> items =query.listPage((int)pageable.getOffset(),pageable.getPageSize());
if(!CollectionUtil.hasElements(items)){
public Page<ProcessTaskWrapper> queryProcessTasks(QueryParameter queryParameter) throws Exception {
runtimeService.createProcessInstanceQuery().processInstanceId("").list();
Map<String,Class<?>> fieldTypeMap =new HashMap<>();
fieldTypeMap.put("processDefinitionId",String.class);
fieldTypeMap.put("processInstanceId",String.class);
fieldTypeMap.put("businessKey",String.class);
fieldTypeMap.put("assignee",String.class);
fieldTypeMap.put("taskDefinitionKey",String.class);
fieldTypeMap.put("businessDescription",String.class);
String sql =PROCESS_TASK_SQL.replace("\r"," ").replace("\n"," ");
Map<String, Object> page =jdbcTemplateService.listBySql(queryParameter,sql,fieldTypeMap,new ProcessTaskWrapperMapper());
if(page==null || page.isEmpty()){
return QueryResult.emptyPage();
}
List<ProcessTaskWrapper> wrappers =new ArrayList<>();
Set<String> processIntanceIds =new HashSet<>();
Map<String,Map<String, BusinessKeyAndDescription>> processDefineAndInstanceAndBusinessMap =new HashMap<>();
for(Task item : items){
ProcessTaskWrapper wrapper =new ProcessTaskWrapper();
wrapper.setId(item.getId());
wrapper.setName(item.getName());
wrapper.setDescription(item.getDescription());
wrapper.setPriority(item.getPriority());
wrapper.setOwner(item.getOwner());
wrapper.setAssignee(item.getAssignee());
wrapper.setProcessInstanceId(item.getProcessInstanceId());
wrapper.setExecutionId(item.getExecutionId());
wrapper.setProcessDefinitionId(item.getProcessDefinitionId());
wrapper.setScopeId(item.getScopeId());
wrapper.setSubScopeId(item.getSubScopeId());
wrapper.setScopeType(item.getScopeType());
wrapper.setScopeDefinitionId(item.getScopeDefinitionId());
wrapper.setCreateTime(item.getCreateTime());
wrapper.setTaskDefinitionKey(item.getTaskDefinitionKey());
wrapper.setDueDate(item.getDueDate());
wrapper.setCategory(item.getCategory());
wrapper.setParentTaskId(item.getParentTaskId());
wrapper.setTenantId(item.getTenantId());
wrapper.setFormKey(item.getFormKey());
wrapper.setClaimTime(item.getClaimTime());
wrappers.add(wrapper);
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(item.getProcessDefinitionId());
if(processInstanceAndBusinessMap==null){
processInstanceAndBusinessMap =new HashMap<>();
processDefineAndInstanceAndBusinessMap.put(item.getProcessDefinitionId(),processInstanceAndBusinessMap);
}
processInstanceAndBusinessMap.put(item.getProcessInstanceId(),new BusinessKeyAndDescription());
processIntanceIds.add(item.getProcessInstanceId());
List<ProcessTaskWrapper> wrappers =(List<ProcessTaskWrapper>)page.get("content");
if(wrappers==null || wrappers.isEmpty()){
return QueryResult.emptyPage();
}
// 建立流程实例和业务Key的关系
List<ProcessInstance> processInstances =runtimeService.createProcessInstanceQuery().processInstanceIds(processIntanceIds).list();
if(CollectionUtil.hasElements(processInstances)) {
for (ProcessInstance processInstance : processInstances) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processInstance.getProcessDefinitionId());
if(processInstanceAndBusinessMap!=null){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstance.getId());
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setProcessDefinitionName(processInstance.getProcessDefinitionName());
businessKeyAndDescription.setProcessDefinitionVersion(processInstance.getProcessDefinitionVersion());
businessKeyAndDescription.setBusinessKey(processInstance.getBusinessKey());
businessKeyAndDescription.setBusinessDescription(processInstance.getProcessDefinitionName());
List<HistoricTaskInstance> historicTaskInstances =historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstance.getId()).finished().orderByHistoricTaskInstanceEndTime().desc().list();
if(CollectionUtil.hasElements(historicTaskInstances)){
businessKeyAndDescription.setPreviousAssignee(historicTaskInstances.get(0).getAssignee());
}
}
}
}
//以下用于设置前一个处理人
List<String> processInstanceIds =new ArrayList<>();
for(ProcessTaskWrapper wrapper : wrappers) {
processInstanceIds.add("'" + wrapper.getProcessInstanceId() + "'");
}
for(String processDefineId : processDefineAndInstanceAndBusinessMap.keySet()) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processDefineId);
if(processInstanceAndBusinessMap==null || processInstanceAndBusinessMap.size()<=0){
continue;
}
ProcessEntity processEntity =processEntityService.getRepository().findByDeployedId(processDefineId);
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setTaskHandFrontendRouteName(processEntity.getTaskHandFrontendRouteName());
businessKeyAndDescription.setTaskHandFrontendModelName(processEntity.getTaskHandFrontendModelName());
businessKeyAndDescription.setTaskHandFrontendComponentName(processEntity.getTaskHandFrontendComponentName());
businessKeyAndDescription.setTaskHandFrontendComponentProperties(processEntity.getTaskHandFrontendComponentProperties());
}
}
if(processEntity==null){
continue;
}
String sql =processEntity.getBusinessDescriptionSql();
if(!StringUtils.hasText(sql)){
continue;
}
Set<String> businessKeys =new HashSet<>();
for(Map.Entry<String,BusinessKeyAndDescription> entry: processInstanceAndBusinessMap.entrySet()){
businessKeys.add(entry.getValue().getBusinessKey());
}
if(!CollectionUtil.hasElements(businessKeys)){
continue;
}
Map<String,Object> variables =new HashMap<>();
variables.put("bussinessKeys","'" + StringUtil.combine("','",businessKeys) + "'");
sql =StringUtil.format(sql,variables);
List<Map<String,Object>> result =jdbcTemplate.queryForList(sql);
if(!CollectionUtil.hasElements(result)){
continue;
}
for(Map<String,Object> row : result){
String bussinessKey =row.get("BUSSINESS_KEY").toString();
String bussinessDescription =row.get("BUSSINESS_DESCRIPTION").toString();
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription.getBusinessKey().equals(bussinessKey)){
businessKeyAndDescription.setBusinessDescription(bussinessDescription);
break;
String ins =StringUtil.combine(",",processInstanceIds);
sql =StringUtil.format(PROCESS_PREFIX_ASSIGNEE_SQL,ins).replace("\r"," ").replace("\n"," ");
List<ProcessTaskAssigneeWrapper> list =jdbcTemplate.query(sql,new ProcessTaskAssigneeWrapperMapper());
if(list!=null && !list.isEmpty()){
Map<String,ProcessTaskAssigneeWrapper> prefixAssigneeNames =new HashMap<>();
for(ProcessTaskAssigneeWrapper item : list){
prefixAssigneeNames.put(item.getProcessInstanceId(),item);
}
for(ProcessTaskWrapper wrapper : wrappers) {
if(!StringUtils.hasText(wrapper.getPreviousAssignee())){
wrapper.setPreviousAssignee(SecurityUtil.getLoginName());
wrapper.setPreviousAssigneeName(SecurityUtil.getUserName());
}else {
ProcessTaskAssigneeWrapper item = prefixAssigneeNames.get(wrapper.getProcessInstanceId());
if (item != null) {
wrapper.setPreviousAssignee(item.getAssignee());
wrapper.setPreviousAssigneeName(item.getAssigneeName());
}
}
}
}
//合并
for(ProcessTaskWrapper wrapper : wrappers){
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(wrapper.getProcessDefinitionId());
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(wrapper.getProcessInstanceId());
wrapper.setPreviousAssignee(businessKeyAndDescription.getPreviousAssignee());
wrapper.setBusinessKey(businessKeyAndDescription.getBusinessKey());
wrapper.setBusinessDescription(businessKeyAndDescription.getBusinessDescription());
wrapper.setProcessDefinitionName(businessKeyAndDescription.getProcessDefinitionName());
wrapper.setProcessDefinitionVersion(businessKeyAndDescription.getProcessDefinitionVersion());
wrapper.setTaskHandFrontendRouteName(businessKeyAndDescription.getTaskHandFrontendRouteName());
wrapper.setTaskHandFrontendModelName(businessKeyAndDescription.getTaskHandFrontendModelName());
wrapper.setTaskHandFrontendComponentName(businessKeyAndDescription.getTaskHandFrontendComponentName());
wrapper.setTaskHandFrontendComponentProperties(businessKeyAndDescription.getTaskHandFrontendComponentProperties());
}
//构建结果返回
Pageable pageable =queryParameter.getJpaPageable();
long total =Long.parseLong(page.get("totalElements").toString());
return new PageImpl<ProcessTaskWrapper>(wrappers,pageable,total);
}
@Override
public ProcessTaskWrapper queryProcessTaskById(String taskId) throws Exception {
String sql =PROCESS_TASK_BY_ID_SQL.replace("\r"," ").replace("\n"," ");
sql =StringUtil.format(sql,StringUtil.escapeSqlSpecialChar(taskId),SecurityUtil.getLoginName());
List<ProcessTaskWrapper> wrappers =jdbcTemplate.query(sql,new ProcessTaskWrapperMapper());
if(wrappers==null || wrappers.isEmpty()){
return null;
}
return wrappers.get(0);
}
public Page<ProcessTaskWrapper> queryDoneProcessTasks(QueryParameter queryParameter) throws Exception {
String loginName =SecurityUtil.getLoginName();
String taskSql ="" +
"select * from (\n" +
" select * from (\n" +
" select\n" +
" T.ID_ as id,\n" +
" T.NAME_ as name,\n" +
" T.DESCRIPTION_ as description,\n" +
" T.PRIORITY_ as priority,\n" +
" T.OWNER_ as owner,\n" +
" T.ASSIGNEE_ as assignee,\n" +
" T.PROC_INST_ID_ as processInstanceId,\n" +
" T.EXECUTION_ID_ as executionId,\n" +
" T.PROC_DEF_ID_ as processDefinitionId,\n" +
" T.SCOPE_ID_ as scopeId,\n" +
" T.SUB_SCOPE_ID_ as subScopeId,\n" +
" T.SCOPE_TYPE_ as scopeType,\n" +
" T.SCOPE_DEFINITION_ID_ as scopeDefinitionId,\n" +
" T.CREATE_TIME_ as createTime,\n" +
" T.TASK_DEF_KEY_ as taskDefinitionKey,\n" +
" T.DUE_DATE_ as dueDate,\n" +
" T.CATEGORY_ as category,\n" +
" T.PARENT_TASK_ID_ as parentTaskId,\n" +
" T.TENANT_ID_ as tenantId,\n" +
" T.FORM_KEY_ as formKey,\n" +
" T.CLAIM_TIME_ as claimTime,\n" +
" \n" +
" RP.NAME_ as processDefinitionName,\n" +
" RP.VERSION_ as processDefinitionVersion,\n" +
" \n" +
" E.BUSINESS_KEY_ \t as businessKey,\n" +
" \n" +
" HT.START_TIME_ as START_TIME,\n" +
" HT.END_TIME_ as END_TIME,\n" +
" \n" +
" row_number() over(partition by HT.PROC_INST_ID_ order by HT.END_TIME_ desc) as RK\n" +
" from ACT_HI_TASKINST HT\n" +
" join ACT_RU_TASK T on T.PROC_INST_ID_ = HT.PROC_INST_ID_\n" +
" join ACT_RU_EXECUTION E on T.PROC_INST_ID_ = E.ID_\n" +
" left join ACT_RE_PROCDEF RP on HT.PROC_DEF_ID_ = RP.ID_\n" +
" left join SYS_USER U on T.ASSIGNEE_ = U.LOGINNAME_\n" +
" where \n" +
" HT.ASSIGNEE_ ='" + loginName + "' \n" +
" and T.ASSIGNEE_ <> '" + loginName + "' \n" +
" and HT.END_TIME_ is not null\n" +
" ) TMP where TMP.RK = 1\n" +
") t";
Map<String,Class<?>> fieldTypeMap =new HashMap<>();
fieldTypeMap.put("processDefinitionId",String.class);
fieldTypeMap.put("processInstanceId",String.class);
fieldTypeMap.put("businessKey",String.class);
fieldTypeMap.put("assignee",String.class);
fieldTypeMap.put("taskDefinitionKey",String.class);
fieldTypeMap.put("description",String.class);
Map<String, Object> page =jdbcTemplateService.listBySql(queryParameter,taskSql,fieldTypeMap,new ProcessTaskWrapperMapper());
List<ProcessTaskWrapper> wrappers =new ArrayList<>();
Set<String> processIntanceIds =new HashSet<>();
Map<String,Map<String, BusinessKeyAndDescription>> processDefineAndInstanceAndBusinessMap =new HashMap<>();
fieldTypeMap.put("businessDescription",String.class);
String sql =StringUtil.format(DONE_TASK_SQL,SecurityUtil.getLoginName()).replace("\r"," ").replace("\n"," ");
Map<String, Object> page =jdbcTemplateService.listBySql(queryParameter,sql,fieldTypeMap,new ProcessTaskWrapperMapper());
if(page==null || page.isEmpty()){
return QueryResult.emptyPage();
}
List<ProcessTaskWrapper> items =(List<ProcessTaskWrapper>)page.get("content");
if(items==null || items.isEmpty()){
List<ProcessTaskWrapper> wrappers =(List<ProcessTaskWrapper>)page.get("content");
if(wrappers==null || wrappers.isEmpty()){
return QueryResult.emptyPage();
}
for(ProcessTaskWrapper item : items){
ProcessTaskWrapper wrapper =item;
wrappers.add(wrapper);
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(wrapper.getProcessDefinitionId());
if(processInstanceAndBusinessMap==null){
processInstanceAndBusinessMap =new HashMap<>();
processDefineAndInstanceAndBusinessMap.put(wrapper.getProcessDefinitionId(),processInstanceAndBusinessMap);
}
processInstanceAndBusinessMap.put(wrapper.getProcessInstanceId(),new BusinessKeyAndDescription());
processIntanceIds.add(wrapper.getProcessInstanceId());
}
// 建立流程实例和业务Key的关系
List<ProcessInstance> processInstances =runtimeService.createProcessInstanceQuery().processInstanceIds(processIntanceIds).list();
if(CollectionUtil.hasElements(processInstances)) {
for (ProcessInstance processInstance : processInstances) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processInstance.getProcessDefinitionId());
if(processInstanceAndBusinessMap!=null){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstance.getId());
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setProcessDefinitionName(processInstance.getProcessDefinitionName());
businessKeyAndDescription.setProcessDefinitionVersion(processInstance.getProcessDefinitionVersion());
businessKeyAndDescription.setBusinessKey(processInstance.getBusinessKey());
businessKeyAndDescription.setBusinessDescription(processInstance.getProcessDefinitionName());
//构建结果返回
Pageable pageable =queryParameter.getJpaPageable();
long total =Long.parseLong(page.get("totalElements").toString());
return new PageImpl<ProcessTaskWrapper>(wrappers,pageable,total);
}
List<HistoricTaskInstance> historicTaskInstances =historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstance.getId()).finished().orderByHistoricTaskInstanceEndTime().desc().list();
if(CollectionUtil.hasElements(historicTaskInstances)){
businessKeyAndDescription.setPreviousAssignee(historicTaskInstances.get(0).getAssignee());
}
}
}
}
@Override
public ProcessTaskWrapper queryDoneProcessTaskById(String taskId) throws Exception {
if(!StringUtils.hasText(taskId)){
return null;
}
for(String processDefineId : processDefineAndInstanceAndBusinessMap.keySet()) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processDefineId);
if(processInstanceAndBusinessMap==null || processInstanceAndBusinessMap.size()<=0){
continue;
}
ProcessEntity processEntity =processEntityService.getRepository().findByDeployedId(processDefineId);
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setTaskHandFrontendRouteName(processEntity.getTaskHandFrontendRouteName());
businessKeyAndDescription.setTaskHandFrontendModelName(processEntity.getTaskHandFrontendModelName());
businessKeyAndDescription.setTaskHandFrontendComponentName(processEntity.getTaskHandFrontendComponentName());
businessKeyAndDescription.setTaskHandFrontendComponentProperties(processEntity.getTaskHandFrontendComponentProperties());
}
}
if(processEntity==null){
continue;
}
String sql =processEntity.getBusinessDescriptionSql();
if(!StringUtils.hasText(sql)){
continue;
}
Set<String> businessKeys =new HashSet<>();
for(Map.Entry<String,BusinessKeyAndDescription> entry: processInstanceAndBusinessMap.entrySet()){
businessKeys.add(entry.getValue().getBusinessKey());
}
if(!CollectionUtil.hasElements(businessKeys)){
continue;
}
Map<String,Object> variables =new HashMap<>();
variables.put("bussinessKeys","'" + StringUtil.combine("','",businessKeys) + "'");
sql =StringUtil.format(sql,variables);
List<Map<String,Object>> result =jdbcTemplate.queryForList(sql);
if(!CollectionUtil.hasElements(result)){
continue;
}
for(Map<String,Object> row : result){
String bussinessKey =row.get("BUSSINESS_KEY").toString();
String bussinessDescription =row.get("BUSSINESS_DESCRIPTION").toString();
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription.getBusinessKey().equals(bussinessKey)){
businessKeyAndDescription.setBusinessDescription(bussinessDescription);
break;
}
}
}
List<HistoricTaskInstance> hisTasks =historyService.createHistoricTaskInstanceQuery().taskId(taskId).list();
if(hisTasks==null || hisTasks.isEmpty()){
return null;
}
//合并
for(ProcessTaskWrapper wrapper : wrappers){
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(wrapper.getProcessDefinitionId());
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(wrapper.getProcessInstanceId());
wrapper.setPreviousAssignee(businessKeyAndDescription.getPreviousAssignee());
wrapper.setBusinessKey(businessKeyAndDescription.getBusinessKey());
wrapper.setBusinessDescription(businessKeyAndDescription.getBusinessDescription());
wrapper.setProcessDefinitionName(businessKeyAndDescription.getProcessDefinitionName());
wrapper.setProcessDefinitionVersion(businessKeyAndDescription.getProcessDefinitionVersion());
wrapper.setTaskHandFrontendRouteName(businessKeyAndDescription.getTaskHandFrontendRouteName());
wrapper.setTaskHandFrontendModelName(businessKeyAndDescription.getTaskHandFrontendModelName());
wrapper.setTaskHandFrontendComponentName(businessKeyAndDescription.getTaskHandFrontendComponentName());
wrapper.setTaskHandFrontendComponentProperties(businessKeyAndDescription.getTaskHandFrontendComponentProperties());
HistoricTaskInstance hisTask =hisTasks.get(0);
String sql =DONE_TASK_BY_ID_SQL.replace("\r"," ").replace("\n"," ");
sql =StringUtil.format(sql,StringUtil.escapeSqlSpecialChar(hisTask.getProcessInstanceId()));
List<ProcessTaskWrapper> wrappers =jdbcTemplate.query(sql,new ProcessTaskWrapperMapper());
if(wrappers==null || wrappers.isEmpty()){
return null;
}
Pageable pageable =queryParameter.getJpaPageable();
long total =Long.parseLong(page.get("totalElements").toString());
return new PageImpl<ProcessTaskWrapper>(wrappers,pageable,total);
return wrappers.get(0);
}
@Override
public Page<ProcessTaskWrapper> queryFinishedProcessTasks(QueryParameter queryParameter) throws Exception {
String loginName =SecurityUtil.getLoginName();
String taskSql ="" +
"select * from (\n" +
" select * from (\n" +
" select \n" +
" ht.ID_ as id,\n" +
" ht.NAME_ as name,\n" +
" ht.DESCRIPTION_ as description,\n" +
" ht.PRIORITY_ as priority,\n" +
" ht.OWNER_ as owner,\n" +
" ht.ASSIGNEE_ as assignee,\n" +
" ht.PROC_INST_ID_ as processInstanceId,\n" +
" ht.EXECUTION_ID_ as executionId,\n" +
" ht.PROC_DEF_ID_ as processDefinitionId,\n" +
" ht.SCOPE_ID_ as scopeId,\n" +
" ht.SUB_SCOPE_ID_ as subScopeId,\n" +
" ht.SCOPE_TYPE_ as scopeType,\n" +
" ht.SCOPE_DEFINITION_ID_ as scopeDefinitionId,\n" +
" -- ht.CREATE_TIME_ as createTime,\n" +
" ht.TASK_DEF_KEY_ as taskDefinitionKey,\n" +
" ht.DUE_DATE_ as dueDate,\n" +
" ht.CATEGORY_ as category,\n" +
" ht.PARENT_TASK_ID_ as parentTaskId,\n" +
" ht.TENANT_ID_ as tenantId,\n" +
" ht.FORM_KEY_ as formKey,\n" +
" ht.CLAIM_TIME_ as claimTime,\n" +
" \n" +
" ht.START_TIME_ as createTime,\n" +
" ht.END_TIME_ as END_TIME,\n" +
" \n" +
" rp.NAME_ as processDefinitionName,\n" +
" rp.VERSION_ as processDefinitionVersion,\n" +
" \n" +
" e.BUSINESS_KEY_ \t as businessKey,\n" +
" \n" +
" row_number() over(partition by ht.proc_inst_id_ order by ht.end_time_ desc) as rk\n" +
" from ACT_HI_TASKINST ht\n" +
" left join ACT_RE_PROCDEF rp on ht.proc_def_id_ = rp.id_\n" +
" join ACT_HI_PROCINST e on ht.proc_inst_id_ = e.PROC_INST_ID_\n" +
" left join sys_user u on ht.assignee_ = u.loginname_\n" +
" where \n" +
" exists (\n" +
" select 1 from ACT_HI_TASKINST aht \n" +
" where \n" +
" aht.ASSIGNEE_ = '" + loginName + "' \n" +
" and aht.end_time_ is not null\n" +
" and exists (\n" +
" select 1 from ACT_HI_PROCINST hp \n" +
" where \n" +
" hp.end_time_ is not null \n" +
" and hp.end_act_id_ is not null \n" +
" and hp.proc_inst_id_ = ht.proc_inst_id_\n" +
" ) \n" +
" and aht.proc_inst_id_ = ht.proc_inst_id_\n" +
" )\n" +
" ) tmp where tmp.rk = 1\n" +
") t";
Map<String,Class<?>> fieldTypeMap =new HashMap<>();
fieldTypeMap.put("processDefinitionId",String.class);
fieldTypeMap.put("processInstanceId",String.class);
fieldTypeMap.put("businessKey",String.class);
fieldTypeMap.put("assignee",String.class);
fieldTypeMap.put("taskDefinitionKey",String.class);
fieldTypeMap.put("description",String.class);
Map<String, Object> page =jdbcTemplateService.listBySql(queryParameter,taskSql,fieldTypeMap,new ProcessTaskWrapperMapper());
List<ProcessTaskWrapper> wrappers =new ArrayList<>();
Set<String> processIntanceIds =new HashSet<>();
Map<String,Map<String, BusinessKeyAndDescription>> processDefineAndInstanceAndBusinessMap =new HashMap<>();
fieldTypeMap.put("businessDescription",String.class);
String sql =StringUtil.format(FINISHED_TASK_SQL,SecurityUtil.getLoginName()).replace("\r"," ").replace("\n"," ");
Map<String, Object> page =jdbcTemplateService.listBySql(queryParameter,sql,fieldTypeMap,new ProcessTaskWrapperMapper());
if(page==null || page.isEmpty()){
return QueryResult.emptyPage();
}
List<ProcessTaskWrapper> items =(List<ProcessTaskWrapper>)page.get("content");
if(items==null || items.isEmpty()){
List<ProcessTaskWrapper> wrappers =(List<ProcessTaskWrapper>)page.get("content");
if(wrappers==null || wrappers.isEmpty()){
return QueryResult.emptyPage();
}
for(ProcessTaskWrapper item : items){
ProcessTaskWrapper wrapper =item;
wrappers.add(wrapper);
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(wrapper.getProcessDefinitionId());
if(processInstanceAndBusinessMap==null){
processInstanceAndBusinessMap =new HashMap<>();
processDefineAndInstanceAndBusinessMap.put(wrapper.getProcessDefinitionId(),processInstanceAndBusinessMap);
}
processInstanceAndBusinessMap.put(wrapper.getProcessInstanceId(),new BusinessKeyAndDescription());
processIntanceIds.add(wrapper.getProcessInstanceId());
}
// 建立流程实例和业务Key的关系
List<HistoricProcessInstance> processInstances =historyService.createHistoricProcessInstanceQuery().processInstanceIds(processIntanceIds).list();
if(CollectionUtil.hasElements(processInstances)) {
for (HistoricProcessInstance processInstance : processInstances) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processInstance.getProcessDefinitionId());
if(processInstanceAndBusinessMap!=null){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstance.getId());
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setProcessDefinitionName(processInstance.getProcessDefinitionName());
businessKeyAndDescription.setProcessDefinitionVersion(processInstance.getProcessDefinitionVersion());
businessKeyAndDescription.setBusinessKey(processInstance.getBusinessKey());
businessKeyAndDescription.setBusinessDescription(processInstance.getProcessDefinitionName());
//构建结果返回
Pageable pageable =queryParameter.getJpaPageable();
long total =Long.parseLong(page.get("totalElements").toString());
return new PageImpl<ProcessTaskWrapper>(wrappers,pageable,total);
}
List<HistoricTaskInstance> historicTaskInstances =historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstance.getId()).finished().orderByHistoricTaskInstanceEndTime().desc().list();
if(CollectionUtil.hasElements(historicTaskInstances)){
businessKeyAndDescription.setPreviousAssignee(historicTaskInstances.get(0).getAssignee());
}
}
}
}
@Override
public ProcessTaskWrapper queryFinishedProcessTaskById(String taskId) throws Exception {
if(!StringUtils.hasText(taskId)){
return null;
}
for(String processDefineId : processDefineAndInstanceAndBusinessMap.keySet()) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processDefineId);
if(processInstanceAndBusinessMap==null || processInstanceAndBusinessMap.size()<=0){
continue;
}
ProcessEntity processEntity =processEntityService.getRepository().findByDeployedId(processDefineId);
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setTaskHandFrontendRouteName(processEntity.getTaskHandFrontendRouteName());
businessKeyAndDescription.setTaskHandFrontendModelName(processEntity.getTaskHandFrontendModelName());
businessKeyAndDescription.setTaskHandFrontendComponentName(processEntity.getTaskHandFrontendComponentName());
businessKeyAndDescription.setTaskHandFrontendComponentProperties(processEntity.getTaskHandFrontendComponentProperties());
}
}
if(processEntity==null){
continue;
}
String sql =processEntity.getBusinessDescriptionSql();
if(!StringUtils.hasText(sql)){
continue;
}
Set<String> businessKeys =new HashSet<>();
for(Map.Entry<String,BusinessKeyAndDescription> entry: processInstanceAndBusinessMap.entrySet()){
businessKeys.add(entry.getValue().getBusinessKey());
}
if(!CollectionUtil.hasElements(businessKeys)){
continue;
}
Map<String,Object> variables =new HashMap<>();
variables.put("bussinessKeys","'" + StringUtil.combine("','",businessKeys) + "'");
sql =StringUtil.format(sql,variables);
List<Map<String,Object>> result =jdbcTemplate.queryForList(sql);
if(!CollectionUtil.hasElements(result)){
continue;
}
for(Map<String,Object> row : result){
String bussinessKey =row.get("BUSSINESS_KEY").toString();
String bussinessDescription =row.get("BUSSINESS_DESCRIPTION").toString();
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription.getBusinessKey().equals(bussinessKey)){
businessKeyAndDescription.setBusinessDescription(bussinessDescription);
break;
}
}
}
List<HistoricTaskInstance> hisTasks =historyService.createHistoricTaskInstanceQuery().taskId(taskId).list();
if(hisTasks==null || hisTasks.isEmpty()){
return null;
}
//合并
for(ProcessTaskWrapper wrapper : wrappers){
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(wrapper.getProcessDefinitionId());
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(wrapper.getProcessInstanceId());
wrapper.setPreviousAssignee(businessKeyAndDescription.getPreviousAssignee());
wrapper.setBusinessKey(businessKeyAndDescription.getBusinessKey());
wrapper.setBusinessDescription(businessKeyAndDescription.getBusinessDescription());
wrapper.setProcessDefinitionName(businessKeyAndDescription.getProcessDefinitionName());
wrapper.setProcessDefinitionVersion(businessKeyAndDescription.getProcessDefinitionVersion());
wrapper.setTaskHandFrontendRouteName(businessKeyAndDescription.getTaskHandFrontendRouteName());
wrapper.setTaskHandFrontendModelName(businessKeyAndDescription.getTaskHandFrontendModelName());
wrapper.setTaskHandFrontendComponentName(businessKeyAndDescription.getTaskHandFrontendComponentName());
wrapper.setTaskHandFrontendComponentProperties(businessKeyAndDescription.getTaskHandFrontendComponentProperties());
HistoricTaskInstance hisTask =hisTasks.get(0);
String sql =FINISHED_TASK_BY_ID_SQL.replace("\r"," ").replace("\n"," ");
sql =StringUtil.format(sql,StringUtil.escapeSqlSpecialChar(hisTask.getProcessInstanceId()));
List<ProcessTaskWrapper> wrappers =jdbcTemplate.query(sql,new ProcessTaskWrapperMapper());
if(wrappers==null || wrappers.isEmpty()){
return null;
}
Pageable pageable =queryParameter.getJpaPageable();
long total =Long.parseLong(page.get("totalElements").toString());
return new PageImpl<ProcessTaskWrapper>(wrappers,pageable,total);
return wrappers.get(0);
}
@Override

968
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/ProcessQueryServiceImpl2.java

@ -0,0 +1,968 @@
package io.sc.platform.flowable.service.impl;
import io.sc.platform.flowable.jpa.entity.ProcessEntity;
import io.sc.platform.flowable.service.AssigneeQueryService;
import io.sc.platform.flowable.service.ProcessEntityService;
import io.sc.platform.flowable.service.ProcessQueryService;
import io.sc.platform.flowable.support.*;
import io.sc.platform.jdbc.sql.dialect.Dialect;
import io.sc.platform.lcdp.form.service.JdbcTemplateService;
import io.sc.platform.orm.service.support.QueryParameter;
import io.sc.platform.orm.service.support.QueryResult;
import io.sc.platform.orm.service.support.criteria.Criteria;
import io.sc.platform.orm.service.support.criteria.impl.Contains;
import io.sc.platform.orm.service.support.criteria.impl.Equals;
import io.sc.platform.security.util.SecurityUtil;
import io.sc.platform.util.CollectionUtil;
import io.sc.platform.util.FileUtil;
import io.sc.platform.util.StringUtil;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.EndEvent;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.runtime.ProcessInstanceQuery;
import org.flowable.image.impl.DefaultProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Order;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;
//@Service("io.sc.platform.flowable.service.impl.ProcessQueryServiceImpl")
public class ProcessQueryServiceImpl2 implements ProcessQueryService {
@Autowired private RepositoryService repositoryService;
@Autowired private TaskService taskService;
@Autowired private ProcessEntityService processEntityService;
@Autowired private HistoryService historyService;
@Autowired private RuntimeService runtimeService;
@Autowired private JdbcTemplateService jdbcTemplateService;
@Autowired
@Qualifier("io.sc.platform.flowable.service.impl.AssigneeQueryServiceImpl")
private AssigneeQueryService assigneeQueryService;
@Autowired private Dialect dialect;
@Autowired private JdbcTemplate jdbcTemplate;
private static final String PROCESS_TASK_SQL;
private static final String PROCESS_PREFIX_ASSIGNEE_SQL;
private static final String DONE_TASK_SQL;
private static final String FINISHED_TASK_SQL;
static {
try {
PROCESS_TASK_SQL = FileUtil.readString("classpath:/io/sc/platform/flowable/service/impl/sql/MyTasks.sql");
PROCESS_PREFIX_ASSIGNEE_SQL = FileUtil.readString("classpath:/io/sc/platform/flowable/service/impl/sql/ProcessPrefixAssignee.sql");
DONE_TASK_SQL = FileUtil.readString("classpath:/io/sc/platform/flowable/service/impl/sql/MyDoneTasks.sql");
FINISHED_TASK_SQL = FileUtil.readString("classpath:/io/sc/platform/flowable/service/impl/sql/MyFinishedTasks.sql");
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public ProcessDefinition queryProcessDefinition(String processDefinitionId) {
return repositoryService.getProcessDefinition(processDefinitionId);
}
@Override
public InputStream showProcessDiagramByInstanceId(String processInstanceId) throws Exception {
List<Task> tasks =taskService.createTaskQuery().processInstanceId(processInstanceId).list();
return showProcessDiagram(tasks);
}
@Override
public InputStream showProcessDiagramByTaskId(String taskId) throws Exception {
List<Task> tasks =taskService.createTaskQuery().taskId(taskId).list();
return showProcessDiagram(tasks);
}
private InputStream showProcessDiagram(List<Task> tasks) {
if(tasks!=null && tasks.size()>0){
String procDefinitionId =tasks.get(0).getProcessDefinitionId();
BpmnModel model = repositoryService.getBpmnModel(procDefinitionId);
List<String> taskDefinitionKeys =new ArrayList<String>();
for(Task task : tasks) {
taskDefinitionKeys.add(task.getTaskDefinitionKey());
}
List<String> highLightedActivities =getHighLightedActivities(model,taskDefinitionKeys);
DefaultProcessDiagramGenerator defaultProcessDiagramGenerator = new DefaultProcessDiagramGenerator();
return defaultProcessDiagramGenerator.generateDiagram(model,"PNG",highLightedActivities,Collections.<String>emptyList(),"宋体","宋体","宋体",null,1.0,true);
}
return null;
}
private List<String> getHighLightedActivities(BpmnModel model,List<String> taskDefinitionKeys){
if(model!=null && taskDefinitionKeys!=null) {
List<String> result =new ArrayList<String>();
Collection<FlowElement> elements =model.getMainProcess().getFlowElements();
if(elements!=null && elements.size()>0){
for(FlowElement element : elements){
for(String taskDefinitionKey : taskDefinitionKeys) {
if(taskDefinitionKey.equals(element.getId())){
result.add(element.getId());
break;
}
}
}
}
return result;
}
return Collections.<String>emptyList();
}
@Override
public Page<ProcessInstanceWrapper> queryProcessInstances(QueryParameter queryParameter) throws Exception {
ProcessInstanceQuery query =runtimeService.createProcessInstanceQuery();
if(queryParameter!=null && queryParameter.existsCriteria()){
// 流程定义ID
Criteria processDefinitionIdCriteria =queryParameter.getCriteriaByFieldName("processDefinitionId");
if(processDefinitionIdCriteria!=null && processDefinitionIdCriteria instanceof Equals){
Equals _processDefinitionIdCriteria =(Equals)processDefinitionIdCriteria;
query.processDefinitionId(_processDefinitionIdCriteria.getValue());
}
// 流程实例ID
Criteria processInstanceIdCriteria =queryParameter.getCriteriaByFieldName("processInstanceId");
if(processInstanceIdCriteria!=null && processInstanceIdCriteria instanceof Equals){
Equals _processInstanceIdCriteria =(Equals)processInstanceIdCriteria;
query.processInstanceId(_processInstanceIdCriteria.getValue());
}
// 业务ID
Criteria businessKeyCriteria =queryParameter.getCriteriaByFieldName("businessKey");
if(businessKeyCriteria!=null && businessKeyCriteria instanceof Equals){
Equals _businessKeyCriteria =(Equals)businessKeyCriteria;
query.processInstanceBusinessKeyLike("%" + _businessKeyCriteria.getValue() + "%");
}
// 创建人
Criteria startUserIdCriteria =queryParameter.getCriteriaByFieldName("startUserId");
if(startUserIdCriteria!=null && startUserIdCriteria instanceof Equals){
Equals _startUserIdCriteria =(Equals)startUserIdCriteria;
query.startedBy(_startUserIdCriteria.getValue());
}
// 是否挂起
Criteria suspendedCriteria =queryParameter.getCriteriaByFieldName("suspended");
if(suspendedCriteria!=null && suspendedCriteria instanceof Equals){
Equals _suspendedCriteria =(Equals)suspendedCriteria;
if("true".equals(_suspendedCriteria.getValue())) {
query.suspended();
}
}
}
if(queryParameter!=null && queryParameter.existsSortBy()){
Order order =queryParameter.getFirstSort();
String propertyName =order.getProperty();
if("id".equals(propertyName)){
if(order.isDescending()){
query.orderByProcessInstanceId().desc();
}else {
query.orderByProcessInstanceId().asc();
}
}else if("processDefinitionId".equals(propertyName)){
if(order.isDescending()){
query.orderByProcessDefinitionId().desc();
}else {
query.orderByProcessDefinitionId().asc();
}
}else if("processDefinitionKey".equals(propertyName)){
if(order.isDescending()){
query.orderByProcessDefinitionKey().desc();
}else {
query.orderByProcessDefinitionKey().asc();
}
}else if("startTime".equals(propertyName)){
if(order.isDescending()){
query.orderByStartTime().desc();
}else {
query.orderByStartTime().asc();
}
}
}
Pageable pageable =queryParameter.getJpaPageable();
long total =query.count();
List<ProcessInstance> items =query.listPage((int)pageable.getOffset(),pageable.getPageSize());
if(!CollectionUtil.hasElements(items)){
return QueryResult.emptyPage();
}
List<ProcessInstanceWrapper> wrappers =new ArrayList<>();
for(ProcessInstance item : items){
ProcessInstanceWrapper wrapper =new ProcessInstanceWrapper();
wrapper.setId(item.getId());
wrapper.setName(item.getName());
wrapper.setLocalizedName(item.getLocalizedName());
wrapper.setDescription(item.getDescription());
wrapper.setLocalizedDescription(item.getLocalizedDescription());
wrapper.setBusinessKey(item.getBusinessKey());
wrapper.setStartTime(item.getStartTime());
wrapper.setStartUserId(item.getStartUserId());
wrapper.setSuspended(item.isSuspended());
wrapper.setCallbackId(item.getCallbackId());
wrapper.setCallbackType(item.getCallbackType());
wrapper.setProcessVariables(item.getProcessVariables());
wrapper.setProcessDefinitionId(item.getProcessDefinitionId());
wrapper.setProcessDefinitionName(item.getProcessDefinitionName());
wrapper.setProcessDefinitionKey(item.getProcessDefinitionKey());
wrapper.setProcessDefinitionVersion(item.getProcessDefinitionVersion());
wrappers.add(wrapper);
}
return new PageImpl<ProcessInstanceWrapper>(wrappers,pageable,total);
}
public Page<ProcessTaskWrapper> queryProcessTasks(QueryParameter queryParameter) throws Exception {
runtimeService.createProcessInstanceQuery().processInstanceId("").list();
Map<String,Class<?>> fieldTypeMap =new HashMap<>();
fieldTypeMap.put("processDefinitionId",String.class);
fieldTypeMap.put("processInstanceId",String.class);
fieldTypeMap.put("businessKey",String.class);
fieldTypeMap.put("assignee",String.class);
fieldTypeMap.put("taskDefinitionKey",String.class);
fieldTypeMap.put("businessDescription",String.class);
String sql =PROCESS_TASK_SQL.replace("\r"," ").replace("\n"," ");
Map<String, Object> page =jdbcTemplateService.listBySql(queryParameter,sql,fieldTypeMap,new ProcessTaskWrapperMapper());
if(page==null || page.isEmpty()){
return QueryResult.emptyPage();
}
List<ProcessTaskWrapper> wrappers =(List<ProcessTaskWrapper>)page.get("content");
if(wrappers==null || wrappers.isEmpty()){
return QueryResult.emptyPage();
}
//以下用于设置前一个处理人
List<String> processInstanceIds =new ArrayList<>();
for(ProcessTaskWrapper wrapper : wrappers) {
processInstanceIds.add("'" + wrapper.getProcessInstanceId() + "'");
}
String ins =StringUtil.combine(",",processInstanceIds);
sql =StringUtil.format(PROCESS_PREFIX_ASSIGNEE_SQL,ins).replace("\r"," ").replace("\n"," ");
List<ProcessTaskAssigneeWrapper> list =jdbcTemplate.query(sql,new ProcessTaskAssigneeWrapperMapper());
if(list!=null && !list.isEmpty()){
Map<String,ProcessTaskAssigneeWrapper> prefixAssigneeNames =new HashMap<>();
for(ProcessTaskAssigneeWrapper item : list){
prefixAssigneeNames.put(item.getProcessInstanceId(),item);
}
for(ProcessTaskWrapper wrapper : wrappers) {
if(!StringUtils.hasText(wrapper.getPreviousAssignee())){
wrapper.setPreviousAssignee(SecurityUtil.getLoginName());
wrapper.setPreviousAssigneeName(SecurityUtil.getUserName());
}else {
ProcessTaskAssigneeWrapper item = prefixAssigneeNames.get(wrapper.getProcessInstanceId());
if (item != null) {
wrapper.setPreviousAssignee(item.getAssignee());
wrapper.setPreviousAssigneeName(item.getAssigneeName());
}
}
}
}
//构建结果返回
Pageable pageable =queryParameter.getJpaPageable();
long total =Long.parseLong(page.get("totalElements").toString());
return new PageImpl<ProcessTaskWrapper>(wrappers,pageable,total);
}
public Page<ProcessTaskWrapper> queryProcessTasks2(QueryParameter queryParameter) throws Exception {
TaskQuery query =taskService.createTaskQuery();
if(queryParameter!=null && queryParameter.existsCriteria()){
// 流程定义ID
Criteria processDefinitionIdCriteria =queryParameter.getCriteriaByFieldName("processDefinitionId");
if(processDefinitionIdCriteria!=null && processDefinitionIdCriteria instanceof Equals){
Equals _processDefinitionIdCriteria =(Equals)processDefinitionIdCriteria;
query.processDefinitionId(_processDefinitionIdCriteria.getValue());
}
// 流程实例ID
Criteria processInstanceIdCriteria =queryParameter.getCriteriaByFieldName("processInstanceId");
if(processInstanceIdCriteria!=null && processInstanceIdCriteria instanceof Equals){
Equals _processInstanceIdCriteria =(Equals)processInstanceIdCriteria;
query.processInstanceId(_processInstanceIdCriteria.getValue());
}
// 业务ID
Criteria businessKeyCriteria =queryParameter.getCriteriaByFieldName("businessKey");
if(businessKeyCriteria!=null && businessKeyCriteria instanceof Equals){
Equals _businessKeyCriteria =(Equals)businessKeyCriteria;
query.processInstanceBusinessKeyLike("%" + _businessKeyCriteria.getValue() + "%");
}
// 处理人
Criteria assigneeCriteria =queryParameter.getCriteriaByFieldName("assignee");
if(assigneeCriteria!=null && assigneeCriteria instanceof Equals){
Equals _assigneeCriteria =(Equals)assigneeCriteria;
query.taskAssignee(_assigneeCriteria.getValue());
}
// 任务节点 KEY
Criteria taskDefinitionKeyCriteria =queryParameter.getCriteriaByFieldName("taskDefinitionKey");
if(taskDefinitionKeyCriteria!=null && taskDefinitionKeyCriteria instanceof Equals){
Equals _taskDefinitionKeyCriteria =(Equals)taskDefinitionKeyCriteria;
query.taskDefinitionKey(_taskDefinitionKeyCriteria.getValue());
}
// 任务描述
Criteria taskDescriptionCriteria =queryParameter.getCriteriaByFieldName("description");
if(taskDescriptionCriteria!=null && taskDescriptionCriteria instanceof Contains){
Contains _taskDescriptionCriteria =(Contains)taskDescriptionCriteria;
query.taskDescriptionLike("%" + StringUtil.escapeSqlSpecialChar(_taskDescriptionCriteria.getValue()) + "%");
}
}
if(queryParameter!=null && queryParameter.existsSortBy()){
Order order =queryParameter.getFirstSort();
String propertyName =order.getProperty();
if("id".equals(propertyName)){
if(order.isDescending()){
query.orderByTaskId().desc();
}else {
query.orderByTaskId().asc();
}
}else if("assignee".equals(propertyName)){
if(order.isDescending()){
query.orderByTaskAssignee().desc();
}else {
query.orderByTaskAssignee().asc();
}
}else if("createTime".equals(propertyName)){
if(order.isDescending()){
query.orderByTaskCreateTime().desc();
}else {
query.orderByTaskCreateTime().asc();
}
}else if("owner".equals(propertyName)){
if(order.isDescending()){
query.orderByTaskOwner().desc();
}else {
query.orderByTaskOwner().asc();
}
}else if("name".equals(propertyName)){
if(order.isDescending()){
query.orderByTaskName().desc();
}else {
query.orderByTaskName().asc();
}
}
}else{
query.orderByTaskCreateTime().desc();
}
Pageable pageable =queryParameter.getJpaPageable();
long total =query.count();
List<Task> items =query.listPage((int)pageable.getOffset(),pageable.getPageSize());
if(!CollectionUtil.hasElements(items)){
return QueryResult.emptyPage();
}
List<ProcessTaskWrapper> wrappers =new ArrayList<>();
Set<String> processIntanceIds =new HashSet<>();
Map<String,Map<String, BusinessKeyAndDescription>> processDefineAndInstanceAndBusinessMap =new HashMap<>();
for(Task item : items){
ProcessTaskWrapper wrapper =new ProcessTaskWrapper();
wrapper.setId(item.getId());
wrapper.setName(item.getName());
wrapper.setDescription(item.getDescription());
wrapper.setPriority(item.getPriority());
wrapper.setOwner(item.getOwner());
wrapper.setAssignee(item.getAssignee());
wrapper.setProcessInstanceId(item.getProcessInstanceId());
wrapper.setExecutionId(item.getExecutionId());
wrapper.setProcessDefinitionId(item.getProcessDefinitionId());
wrapper.setScopeId(item.getScopeId());
wrapper.setSubScopeId(item.getSubScopeId());
wrapper.setScopeType(item.getScopeType());
wrapper.setScopeDefinitionId(item.getScopeDefinitionId());
wrapper.setStartTime(item.getCreateTime());
wrapper.setTaskDefinitionKey(item.getTaskDefinitionKey());
wrapper.setDueDate(item.getDueDate());
wrapper.setCategory(item.getCategory());
wrapper.setParentTaskId(item.getParentTaskId());
wrapper.setTenantId(item.getTenantId());
wrapper.setFormKey(item.getFormKey());
wrapper.setClaimTime(item.getClaimTime());
wrappers.add(wrapper);
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(item.getProcessDefinitionId());
if(processInstanceAndBusinessMap==null){
processInstanceAndBusinessMap =new HashMap<>();
processDefineAndInstanceAndBusinessMap.put(item.getProcessDefinitionId(),processInstanceAndBusinessMap);
}
processInstanceAndBusinessMap.put(item.getProcessInstanceId(),new BusinessKeyAndDescription());
processIntanceIds.add(item.getProcessInstanceId());
}
// 建立流程实例和业务Key的关系
List<ProcessInstance> processInstances =runtimeService.createProcessInstanceQuery().processInstanceIds(processIntanceIds).list();
if(CollectionUtil.hasElements(processInstances)) {
for (ProcessInstance processInstance : processInstances) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processInstance.getProcessDefinitionId());
if(processInstanceAndBusinessMap!=null){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstance.getId());
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setProcessDefinitionName(processInstance.getProcessDefinitionName());
businessKeyAndDescription.setProcessDefinitionVersion(processInstance.getProcessDefinitionVersion());
businessKeyAndDescription.setBusinessKey(processInstance.getBusinessKey());
businessKeyAndDescription.setBusinessDescription(processInstance.getProcessDefinitionName());
List<HistoricTaskInstance> historicTaskInstances =historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstance.getId()).finished().orderByHistoricTaskInstanceEndTime().desc().list();
if(CollectionUtil.hasElements(historicTaskInstances)){
businessKeyAndDescription.setPreviousAssignee(historicTaskInstances.get(0).getAssignee());
}
}
}
}
}
for(String processDefineId : processDefineAndInstanceAndBusinessMap.keySet()) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processDefineId);
if(processInstanceAndBusinessMap==null || processInstanceAndBusinessMap.size()<=0){
continue;
}
ProcessEntity processEntity =processEntityService.getRepository().findByDeployedId(processDefineId);
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setTaskHandFrontendRouteName(processEntity.getTaskHandFrontendRouteName());
businessKeyAndDescription.setTaskHandFrontendModelName(processEntity.getTaskHandFrontendModelName());
businessKeyAndDescription.setTaskHandFrontendComponentName(processEntity.getTaskHandFrontendComponentName());
businessKeyAndDescription.setTaskHandFrontendComponentProperties(processEntity.getTaskHandFrontendComponentProperties());
}
}
if(processEntity==null){
continue;
}
String sql =processEntity.getBusinessDescriptionSql();
if(!StringUtils.hasText(sql)){
continue;
}
Set<String> businessKeys =new HashSet<>();
for(Map.Entry<String,BusinessKeyAndDescription> entry: processInstanceAndBusinessMap.entrySet()){
businessKeys.add(entry.getValue().getBusinessKey());
}
if(!CollectionUtil.hasElements(businessKeys)){
continue;
}
Map<String,Object> variables =new HashMap<>();
variables.put("bussinessKeys","'" + StringUtil.combine("','",businessKeys) + "'");
sql =StringUtil.format(sql,variables);
List<Map<String,Object>> result =jdbcTemplate.queryForList(sql);
if(!CollectionUtil.hasElements(result)){
continue;
}
for(Map<String,Object> row : result){
String bussinessKey =row.get("BUSSINESS_KEY").toString();
String bussinessDescription =row.get("BUSSINESS_DESCRIPTION").toString();
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription.getBusinessKey().equals(bussinessKey)){
businessKeyAndDescription.setBusinessDescription(bussinessDescription);
break;
}
}
}
}
//合并
for(ProcessTaskWrapper wrapper : wrappers){
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(wrapper.getProcessDefinitionId());
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(wrapper.getProcessInstanceId());
wrapper.setPreviousAssignee(businessKeyAndDescription.getPreviousAssignee());
wrapper.setBusinessKey(businessKeyAndDescription.getBusinessKey());
wrapper.setBusinessDescription(businessKeyAndDescription.getBusinessDescription());
wrapper.setProcessDefinitionName(businessKeyAndDescription.getProcessDefinitionName());
wrapper.setProcessDefinitionVersion(businessKeyAndDescription.getProcessDefinitionVersion());
wrapper.setTaskHandFrontendRouteName(businessKeyAndDescription.getTaskHandFrontendRouteName());
wrapper.setTaskHandFrontendModelName(businessKeyAndDescription.getTaskHandFrontendModelName());
wrapper.setTaskHandFrontendComponentName(businessKeyAndDescription.getTaskHandFrontendComponentName());
wrapper.setTaskHandFrontendComponentProperties(businessKeyAndDescription.getTaskHandFrontendComponentProperties());
}
return new PageImpl<ProcessTaskWrapper>(wrappers,pageable,total);
}
public Page<ProcessTaskWrapper> queryDoneProcessTasks(QueryParameter queryParameter) throws Exception {
Map<String,Class<?>> fieldTypeMap =new HashMap<>();
fieldTypeMap.put("processDefinitionId",String.class);
fieldTypeMap.put("processInstanceId",String.class);
fieldTypeMap.put("businessKey",String.class);
fieldTypeMap.put("assignee",String.class);
fieldTypeMap.put("taskDefinitionKey",String.class);
fieldTypeMap.put("businessDescription",String.class);
String sql =StringUtil.format(DONE_TASK_SQL,SecurityUtil.getLoginName()).replace("\r"," ").replace("\n"," ");
Map<String, Object> page =jdbcTemplateService.listBySql(queryParameter,sql,fieldTypeMap,new ProcessTaskWrapperMapper());
if(page==null || page.isEmpty()){
return QueryResult.emptyPage();
}
List<ProcessTaskWrapper> wrappers =(List<ProcessTaskWrapper>)page.get("content");
if(wrappers==null || wrappers.isEmpty()){
return QueryResult.emptyPage();
}
//构建结果返回
Pageable pageable =queryParameter.getJpaPageable();
long total =Long.parseLong(page.get("totalElements").toString());
return new PageImpl<ProcessTaskWrapper>(wrappers,pageable,total);
}
//@Override
public Page<ProcessTaskWrapper> queryDoneProcessTasks2(QueryParameter queryParameter) throws Exception {
String loginName =SecurityUtil.getLoginName();
String taskSql ="" +
"select * from (\n" +
" select * from (\n" +
" select\n" +
" T.ID_ as id,\n" +
" T.NAME_ as name,\n" +
" T.DESCRIPTION_ as description,\n" +
" T.PRIORITY_ as priority,\n" +
" T.OWNER_ as owner,\n" +
" T.ASSIGNEE_ as assignee,\n" +
" T.PROC_INST_ID_ as processInstanceId,\n" +
" T.EXECUTION_ID_ as executionId,\n" +
" T.PROC_DEF_ID_ as processDefinitionId,\n" +
" T.SCOPE_ID_ as scopeId,\n" +
" T.SUB_SCOPE_ID_ as subScopeId,\n" +
" T.SCOPE_TYPE_ as scopeType,\n" +
" T.SCOPE_DEFINITION_ID_ as scopeDefinitionId,\n" +
" T.CREATE_TIME_ as createTime,\n" +
" T.TASK_DEF_KEY_ as taskDefinitionKey,\n" +
" T.DUE_DATE_ as dueDate,\n" +
" T.CATEGORY_ as category,\n" +
" T.PARENT_TASK_ID_ as parentTaskId,\n" +
" T.TENANT_ID_ as tenantId,\n" +
" T.FORM_KEY_ as formKey,\n" +
" T.CLAIM_TIME_ as claimTime,\n" +
" \n" +
" RP.NAME_ as processDefinitionName,\n" +
" RP.VERSION_ as processDefinitionVersion,\n" +
" \n" +
" E.BUSINESS_KEY_ \t as businessKey,\n" +
" \n" +
" HT.START_TIME_ as START_TIME,\n" +
" HT.END_TIME_ as END_TIME,\n" +
" \n" +
" row_number() over(partition by HT.PROC_INST_ID_ order by HT.END_TIME_ desc) as RK\n" +
" from ACT_HI_TASKINST HT\n" +
" join ACT_RU_TASK T on T.PROC_INST_ID_ = HT.PROC_INST_ID_\n" +
" join ACT_RU_EXECUTION E on T.PROC_INST_ID_ = E.ID_\n" +
" left join ACT_RE_PROCDEF RP on HT.PROC_DEF_ID_ = RP.ID_\n" +
" left join SYS_USER U on T.ASSIGNEE_ = U.LOGINNAME_\n" +
" where \n" +
" HT.ASSIGNEE_ ='" + loginName + "' \n" +
" and T.ASSIGNEE_ <> '" + loginName + "' \n" +
" and HT.END_TIME_ is not null\n" +
" ) TMP where TMP.RK = 1\n" +
") t";
Map<String,Class<?>> fieldTypeMap =new HashMap<>();
fieldTypeMap.put("processDefinitionId",String.class);
fieldTypeMap.put("processInstanceId",String.class);
fieldTypeMap.put("businessKey",String.class);
fieldTypeMap.put("assignee",String.class);
fieldTypeMap.put("taskDefinitionKey",String.class);
fieldTypeMap.put("description",String.class);
Map<String, Object> page =jdbcTemplateService.listBySql(queryParameter,taskSql,fieldTypeMap,new ProcessTaskWrapperMapper());
List<ProcessTaskWrapper> wrappers =new ArrayList<>();
Set<String> processIntanceIds =new HashSet<>();
Map<String,Map<String, BusinessKeyAndDescription>> processDefineAndInstanceAndBusinessMap =new HashMap<>();
if(page==null || page.isEmpty()){
return QueryResult.emptyPage();
}
List<ProcessTaskWrapper> items =(List<ProcessTaskWrapper>)page.get("content");
if(items==null || items.isEmpty()){
return QueryResult.emptyPage();
}
for(ProcessTaskWrapper item : items){
ProcessTaskWrapper wrapper =item;
wrappers.add(wrapper);
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(wrapper.getProcessDefinitionId());
if(processInstanceAndBusinessMap==null){
processInstanceAndBusinessMap =new HashMap<>();
processDefineAndInstanceAndBusinessMap.put(wrapper.getProcessDefinitionId(),processInstanceAndBusinessMap);
}
processInstanceAndBusinessMap.put(wrapper.getProcessInstanceId(),new BusinessKeyAndDescription());
processIntanceIds.add(wrapper.getProcessInstanceId());
}
// 建立流程实例和业务Key的关系
List<ProcessInstance> processInstances =runtimeService.createProcessInstanceQuery().processInstanceIds(processIntanceIds).list();
if(CollectionUtil.hasElements(processInstances)) {
for (ProcessInstance processInstance : processInstances) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processInstance.getProcessDefinitionId());
if(processInstanceAndBusinessMap!=null){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstance.getId());
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setProcessDefinitionName(processInstance.getProcessDefinitionName());
businessKeyAndDescription.setProcessDefinitionVersion(processInstance.getProcessDefinitionVersion());
businessKeyAndDescription.setBusinessKey(processInstance.getBusinessKey());
businessKeyAndDescription.setBusinessDescription(processInstance.getProcessDefinitionName());
List<HistoricTaskInstance> historicTaskInstances =historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstance.getId()).finished().orderByHistoricTaskInstanceEndTime().desc().list();
if(CollectionUtil.hasElements(historicTaskInstances)){
businessKeyAndDescription.setPreviousAssignee(historicTaskInstances.get(0).getAssignee());
}
}
}
}
}
for(String processDefineId : processDefineAndInstanceAndBusinessMap.keySet()) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processDefineId);
if(processInstanceAndBusinessMap==null || processInstanceAndBusinessMap.size()<=0){
continue;
}
ProcessEntity processEntity =processEntityService.getRepository().findByDeployedId(processDefineId);
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setTaskHandFrontendRouteName(processEntity.getTaskHandFrontendRouteName());
businessKeyAndDescription.setTaskHandFrontendModelName(processEntity.getTaskHandFrontendModelName());
businessKeyAndDescription.setTaskHandFrontendComponentName(processEntity.getTaskHandFrontendComponentName());
businessKeyAndDescription.setTaskHandFrontendComponentProperties(processEntity.getTaskHandFrontendComponentProperties());
}
}
if(processEntity==null){
continue;
}
String sql =processEntity.getBusinessDescriptionSql();
if(!StringUtils.hasText(sql)){
continue;
}
Set<String> businessKeys =new HashSet<>();
for(Map.Entry<String,BusinessKeyAndDescription> entry: processInstanceAndBusinessMap.entrySet()){
businessKeys.add(entry.getValue().getBusinessKey());
}
if(!CollectionUtil.hasElements(businessKeys)){
continue;
}
Map<String,Object> variables =new HashMap<>();
variables.put("bussinessKeys","'" + StringUtil.combine("','",businessKeys) + "'");
sql =StringUtil.format(sql,variables);
List<Map<String,Object>> result =jdbcTemplate.queryForList(sql);
if(!CollectionUtil.hasElements(result)){
continue;
}
for(Map<String,Object> row : result){
String bussinessKey =row.get("BUSSINESS_KEY").toString();
String bussinessDescription =row.get("BUSSINESS_DESCRIPTION").toString();
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription.getBusinessKey().equals(bussinessKey)){
businessKeyAndDescription.setBusinessDescription(bussinessDescription);
break;
}
}
}
}
//合并
for(ProcessTaskWrapper wrapper : wrappers){
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(wrapper.getProcessDefinitionId());
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(wrapper.getProcessInstanceId());
wrapper.setPreviousAssignee(businessKeyAndDescription.getPreviousAssignee());
wrapper.setBusinessKey(businessKeyAndDescription.getBusinessKey());
wrapper.setBusinessDescription(businessKeyAndDescription.getBusinessDescription());
wrapper.setProcessDefinitionName(businessKeyAndDescription.getProcessDefinitionName());
wrapper.setProcessDefinitionVersion(businessKeyAndDescription.getProcessDefinitionVersion());
wrapper.setTaskHandFrontendRouteName(businessKeyAndDescription.getTaskHandFrontendRouteName());
wrapper.setTaskHandFrontendModelName(businessKeyAndDescription.getTaskHandFrontendModelName());
wrapper.setTaskHandFrontendComponentName(businessKeyAndDescription.getTaskHandFrontendComponentName());
wrapper.setTaskHandFrontendComponentProperties(businessKeyAndDescription.getTaskHandFrontendComponentProperties());
}
Pageable pageable =queryParameter.getJpaPageable();
long total =Long.parseLong(page.get("totalElements").toString());
return new PageImpl<ProcessTaskWrapper>(wrappers,pageable,total);
}
@Override
public Page<ProcessTaskWrapper> queryFinishedProcessTasks(QueryParameter queryParameter) throws Exception {
Map<String,Class<?>> fieldTypeMap =new HashMap<>();
fieldTypeMap.put("processDefinitionId",String.class);
fieldTypeMap.put("processInstanceId",String.class);
fieldTypeMap.put("businessKey",String.class);
fieldTypeMap.put("assignee",String.class);
fieldTypeMap.put("taskDefinitionKey",String.class);
fieldTypeMap.put("businessDescription",String.class);
String sql =StringUtil.format(FINISHED_TASK_SQL,SecurityUtil.getLoginName()).replace("\r"," ").replace("\n"," ");
Map<String, Object> page =jdbcTemplateService.listBySql(queryParameter,sql,fieldTypeMap,new ProcessTaskWrapperMapper());
if(page==null || page.isEmpty()){
return QueryResult.emptyPage();
}
List<ProcessTaskWrapper> wrappers =(List<ProcessTaskWrapper>)page.get("content");
if(wrappers==null || wrappers.isEmpty()){
return QueryResult.emptyPage();
}
//构建结果返回
Pageable pageable =queryParameter.getJpaPageable();
long total =Long.parseLong(page.get("totalElements").toString());
return new PageImpl<ProcessTaskWrapper>(wrappers,pageable,total);
}
//@Override
public Page<ProcessTaskWrapper> queryFinishedProcessTasks2(QueryParameter queryParameter) throws Exception {
String loginName =SecurityUtil.getLoginName();
String taskSql ="" +
"select * from (\n" +
" select * from (\n" +
" select \n" +
" ht.ID_ as id,\n" +
" ht.NAME_ as name,\n" +
" ht.DESCRIPTION_ as description,\n" +
" ht.PRIORITY_ as priority,\n" +
" ht.OWNER_ as owner,\n" +
" ht.ASSIGNEE_ as assignee,\n" +
" ht.PROC_INST_ID_ as processInstanceId,\n" +
" ht.EXECUTION_ID_ as executionId,\n" +
" ht.PROC_DEF_ID_ as processDefinitionId,\n" +
" ht.SCOPE_ID_ as scopeId,\n" +
" ht.SUB_SCOPE_ID_ as subScopeId,\n" +
" ht.SCOPE_TYPE_ as scopeType,\n" +
" ht.SCOPE_DEFINITION_ID_ as scopeDefinitionId,\n" +
" -- ht.CREATE_TIME_ as createTime,\n" +
" ht.TASK_DEF_KEY_ as taskDefinitionKey,\n" +
" ht.DUE_DATE_ as dueDate,\n" +
" ht.CATEGORY_ as category,\n" +
" ht.PARENT_TASK_ID_ as parentTaskId,\n" +
" ht.TENANT_ID_ as tenantId,\n" +
" ht.FORM_KEY_ as formKey,\n" +
" ht.CLAIM_TIME_ as claimTime,\n" +
" \n" +
" ht.START_TIME_ as createTime,\n" +
" ht.END_TIME_ as END_TIME,\n" +
" \n" +
" rp.NAME_ as processDefinitionName,\n" +
" rp.VERSION_ as processDefinitionVersion,\n" +
" \n" +
" e.BUSINESS_KEY_ \t as businessKey,\n" +
" \n" +
" row_number() over(partition by ht.proc_inst_id_ order by ht.end_time_ desc) as rk\n" +
" from ACT_HI_TASKINST ht\n" +
" left join ACT_RE_PROCDEF rp on ht.proc_def_id_ = rp.id_\n" +
" join ACT_HI_PROCINST e on ht.proc_inst_id_ = e.PROC_INST_ID_\n" +
" left join sys_user u on ht.assignee_ = u.loginname_\n" +
" where \n" +
" exists (\n" +
" select 1 from ACT_HI_TASKINST aht \n" +
" where \n" +
" aht.ASSIGNEE_ = '" + loginName + "' \n" +
" and aht.end_time_ is not null\n" +
" and exists (\n" +
" select 1 from ACT_HI_PROCINST hp \n" +
" where \n" +
" hp.end_time_ is not null \n" +
" and hp.end_act_id_ is not null \n" +
" and hp.proc_inst_id_ = ht.proc_inst_id_\n" +
" ) \n" +
" and aht.proc_inst_id_ = ht.proc_inst_id_\n" +
" )\n" +
" ) tmp where tmp.rk = 1\n" +
") t";
Map<String,Class<?>> fieldTypeMap =new HashMap<>();
fieldTypeMap.put("processDefinitionId",String.class);
fieldTypeMap.put("processInstanceId",String.class);
fieldTypeMap.put("businessKey",String.class);
fieldTypeMap.put("assignee",String.class);
fieldTypeMap.put("taskDefinitionKey",String.class);
fieldTypeMap.put("description",String.class);
Map<String, Object> page =jdbcTemplateService.listBySql(queryParameter,taskSql,fieldTypeMap,new ProcessTaskWrapperMapper());
List<ProcessTaskWrapper> wrappers =new ArrayList<>();
Set<String> processIntanceIds =new HashSet<>();
Map<String,Map<String, BusinessKeyAndDescription>> processDefineAndInstanceAndBusinessMap =new HashMap<>();
if(page==null || page.isEmpty()){
return QueryResult.emptyPage();
}
List<ProcessTaskWrapper> items =(List<ProcessTaskWrapper>)page.get("content");
if(items==null || items.isEmpty()){
return QueryResult.emptyPage();
}
for(ProcessTaskWrapper item : items){
ProcessTaskWrapper wrapper =item;
wrappers.add(wrapper);
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(wrapper.getProcessDefinitionId());
if(processInstanceAndBusinessMap==null){
processInstanceAndBusinessMap =new HashMap<>();
processDefineAndInstanceAndBusinessMap.put(wrapper.getProcessDefinitionId(),processInstanceAndBusinessMap);
}
processInstanceAndBusinessMap.put(wrapper.getProcessInstanceId(),new BusinessKeyAndDescription());
processIntanceIds.add(wrapper.getProcessInstanceId());
}
// 建立流程实例和业务Key的关系
List<HistoricProcessInstance> processInstances =historyService.createHistoricProcessInstanceQuery().processInstanceIds(processIntanceIds).list();
if(CollectionUtil.hasElements(processInstances)) {
for (HistoricProcessInstance processInstance : processInstances) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processInstance.getProcessDefinitionId());
if(processInstanceAndBusinessMap!=null){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstance.getId());
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setProcessDefinitionName(processInstance.getProcessDefinitionName());
businessKeyAndDescription.setProcessDefinitionVersion(processInstance.getProcessDefinitionVersion());
businessKeyAndDescription.setBusinessKey(processInstance.getBusinessKey());
businessKeyAndDescription.setBusinessDescription(processInstance.getProcessDefinitionName());
List<HistoricTaskInstance> historicTaskInstances =historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstance.getId()).finished().orderByHistoricTaskInstanceEndTime().desc().list();
if(CollectionUtil.hasElements(historicTaskInstances)){
businessKeyAndDescription.setPreviousAssignee(historicTaskInstances.get(0).getAssignee());
}
}
}
}
}
for(String processDefineId : processDefineAndInstanceAndBusinessMap.keySet()) {
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(processDefineId);
if(processInstanceAndBusinessMap==null || processInstanceAndBusinessMap.size()<=0){
continue;
}
ProcessEntity processEntity =processEntityService.getRepository().findByDeployedId(processDefineId);
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription!=null){
businessKeyAndDescription.setTaskHandFrontendRouteName(processEntity.getTaskHandFrontendRouteName());
businessKeyAndDescription.setTaskHandFrontendModelName(processEntity.getTaskHandFrontendModelName());
businessKeyAndDescription.setTaskHandFrontendComponentName(processEntity.getTaskHandFrontendComponentName());
businessKeyAndDescription.setTaskHandFrontendComponentProperties(processEntity.getTaskHandFrontendComponentProperties());
}
}
if(processEntity==null){
continue;
}
String sql =processEntity.getBusinessDescriptionSql();
if(!StringUtils.hasText(sql)){
continue;
}
Set<String> businessKeys =new HashSet<>();
for(Map.Entry<String,BusinessKeyAndDescription> entry: processInstanceAndBusinessMap.entrySet()){
businessKeys.add(entry.getValue().getBusinessKey());
}
if(!CollectionUtil.hasElements(businessKeys)){
continue;
}
Map<String,Object> variables =new HashMap<>();
variables.put("bussinessKeys","'" + StringUtil.combine("','",businessKeys) + "'");
sql =StringUtil.format(sql,variables);
List<Map<String,Object>> result =jdbcTemplate.queryForList(sql);
if(!CollectionUtil.hasElements(result)){
continue;
}
for(Map<String,Object> row : result){
String bussinessKey =row.get("BUSSINESS_KEY").toString();
String bussinessDescription =row.get("BUSSINESS_DESCRIPTION").toString();
for(String processInstanceId : processInstanceAndBusinessMap.keySet()){
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(processInstanceId);
if(businessKeyAndDescription.getBusinessKey().equals(bussinessKey)){
businessKeyAndDescription.setBusinessDescription(bussinessDescription);
break;
}
}
}
}
//合并
for(ProcessTaskWrapper wrapper : wrappers){
Map<String,BusinessKeyAndDescription> processInstanceAndBusinessMap =processDefineAndInstanceAndBusinessMap.get(wrapper.getProcessDefinitionId());
BusinessKeyAndDescription businessKeyAndDescription =processInstanceAndBusinessMap.get(wrapper.getProcessInstanceId());
wrapper.setPreviousAssignee(businessKeyAndDescription.getPreviousAssignee());
wrapper.setBusinessKey(businessKeyAndDescription.getBusinessKey());
wrapper.setBusinessDescription(businessKeyAndDescription.getBusinessDescription());
wrapper.setProcessDefinitionName(businessKeyAndDescription.getProcessDefinitionName());
wrapper.setProcessDefinitionVersion(businessKeyAndDescription.getProcessDefinitionVersion());
wrapper.setTaskHandFrontendRouteName(businessKeyAndDescription.getTaskHandFrontendRouteName());
wrapper.setTaskHandFrontendModelName(businessKeyAndDescription.getTaskHandFrontendModelName());
wrapper.setTaskHandFrontendComponentName(businessKeyAndDescription.getTaskHandFrontendComponentName());
wrapper.setTaskHandFrontendComponentProperties(businessKeyAndDescription.getTaskHandFrontendComponentProperties());
}
Pageable pageable =queryParameter.getJpaPageable();
long total =Long.parseLong(page.get("totalElements").toString());
return new PageImpl<ProcessTaskWrapper>(wrappers,pageable,total);
}
@Override
public List<VariableWrapper> queryVariables(String processInstId) throws Exception {
if(StringUtils.hasText(processInstId)){
String sql ="select * from ACT_RU_VARIABLE where PROC_INST_ID_=? order by NAME_";
return jdbcTemplate.query(sql,new VariableWrapperRowMapper(),processInstId);
}
return null;
}
@Override
public List<UserTaskDefinitionWrapper> queryUserTaskDefinition(String taskId) throws Exception {
if(StringUtils.hasText(taskId)) {
List<Task> tasks =taskService.createTaskQuery().taskId(taskId).list();
if(tasks!=null && tasks.size()>0){
String procDefinitionId =tasks.get(0).getProcessDefinitionId();
BpmnModel model = repositoryService.getBpmnModel(procDefinitionId);
Collection<FlowElement> elements =model.getMainProcess().getFlowElements();
if(elements!=null && elements.size()>0){
List<UserTaskDefinitionWrapper> result =new ArrayList<UserTaskDefinitionWrapper>();
//添加用户任务
for(FlowElement element : elements){
if((element instanceof UserTask)) {
result.add(new UserTaskDefinitionWrapper(element.getId(),element.getName()));
}
}
//添加结束节点
for(FlowElement element : elements){
if((element instanceof EndEvent)) {
result.add(new UserTaskDefinitionWrapper(element.getId(),element.getName()));
}
}
return result;
}
}
}
return null;
}
@Override
public List<Assignee> queryCandidate(String taskId,String activityId) throws Exception {
if(StringUtils.hasText(taskId) && StringUtils.hasText(activityId)) {
List<Task> tasks =taskService.createTaskQuery().taskId(taskId).list();
if(tasks!=null && tasks.size()>0){
String procDefinitionId =tasks.get(0).getProcessDefinitionId();
BpmnModel model = repositoryService.getBpmnModel(procDefinitionId);
Collection<FlowElement> elements =model.getMainProcess().getFlowElements();
if(elements!=null && elements.size()>0){
for(FlowElement element : elements){
if((element instanceof UserTask) && element.getId().equals(activityId)) {
return assigneeQueryService.query((UserTask)element);
}
}
}
}
}
return null;
}
@Override
public ProcessTaskWrapper queryProcessTaskById(String taskId) throws Exception {
return null;
}
@Override
public ProcessTaskWrapper queryDoneProcessTaskById(String taskId) throws Exception {
return null;
}
@Override
public ProcessTaskWrapper queryFinishedProcessTaskById(String taskId) throws Exception {
return null;
}
}

46
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/BusinessKeyAndDescriptionWrapper.java

@ -0,0 +1,46 @@
package io.sc.platform.flowable.support;
import io.sc.platform.util.DateUtil;
import io.sc.platform.util.support.DateDiff;
import java.time.temporal.ChronoUnit;
import java.util.Date;
public class BusinessKeyAndDescriptionWrapper {
private String businessKey;
private String custNo;
private String custName;
private String processStatus;
public String getBusinessKey() {
return businessKey;
}
public void setBusinessKey(String businessKey) {
this.businessKey = businessKey;
}
public String getCustNo() {
return custNo;
}
public void setCustNo(String custNo) {
this.custNo = custNo;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getProcessStatus() {
return processStatus;
}
public void setProcessStatus(String processStatus) {
this.processStatus = processStatus;
}
}

18
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/BusinessKeyAndDescriptionWrapperMapper.java

@ -0,0 +1,18 @@
package io.sc.platform.flowable.support;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BusinessKeyAndDescriptionWrapperMapper implements RowMapper<BusinessKeyAndDescriptionWrapper> {
@Override
public BusinessKeyAndDescriptionWrapper mapRow(ResultSet rs, int rowNum) throws SQLException {
BusinessKeyAndDescriptionWrapper wrapper =new BusinessKeyAndDescriptionWrapper();
wrapper.setBusinessKey(rs.getString("BUSINESS_KEY"));
wrapper.setCustNo(rs.getString("CUST_NO"));
wrapper.setCustName(rs.getString("CUST_NAME"));
wrapper.setProcessStatus(rs.getString("PROCESS_STATUS"));
return wrapper;
}
}

60
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/ProcessTaskAssigneeWrapper.java

@ -0,0 +1,60 @@
package io.sc.platform.flowable.support;
import java.util.Date;
public class ProcessTaskAssigneeWrapper {
private String id;
private String name;
private String processInstanceId;
private Date endTime;
private String assignee;
private String assigneeName;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProcessInstanceId() {
return processInstanceId;
}
public void setProcessInstanceId(String processInstanceId) {
this.processInstanceId = processInstanceId;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public String getAssignee() {
return assignee;
}
public void setAssignee(String assignee) {
this.assignee = assignee;
}
public String getAssigneeName() {
return assigneeName;
}
public void setAssigneeName(String assigneeName) {
this.assigneeName = assigneeName;
}
}

20
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/ProcessTaskAssigneeWrapperMapper.java

@ -0,0 +1,20 @@
package io.sc.platform.flowable.support;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
import java.sql.SQLException;
public class ProcessTaskAssigneeWrapperMapper implements RowMapper<ProcessTaskAssigneeWrapper> {
@Override
public ProcessTaskAssigneeWrapper mapRow(ResultSet rs, int rowNum) throws SQLException {
ProcessTaskAssigneeWrapper wrapper =new ProcessTaskAssigneeWrapper();
wrapper.setId(rs.getString("id"));
wrapper.setName(rs.getString("name"));
wrapper.setProcessInstanceId(rs.getString("processInstanceId"));
wrapper.setEndTime(rs.getTimestamp("endTime"));
wrapper.setAssignee(rs.getString("assignee"));
wrapper.setAssigneeName(rs.getString("assigneeName"));
return wrapper;
}
}

179
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/ProcessTaskWrapper.java

@ -10,7 +10,6 @@ import java.time.temporal.ChronoUnit;
import java.util.Date;
public class ProcessTaskWrapper {
//流程任务信息
private String id;
private String name;
private String description;
@ -18,7 +17,7 @@ public class ProcessTaskWrapper {
private String owner;
private String assignee;
private String assigneeName;
private String processInstanceId;
private String executionId;
private String processDefinitionId;
@ -26,7 +25,8 @@ public class ProcessTaskWrapper {
private String subScopeId;
private String scopeType;
private String scopeDefinitionId;
private Date createTime;
private Date startTime;
private Date endTime;
private String taskDefinitionKey;
private Date dueDate;
private String category;
@ -35,7 +35,7 @@ public class ProcessTaskWrapper {
private String formKey;
private Date claimTime;
private String previousAssignee;
private String processDefinitionKey;
private String processDefinitionName;
private Integer processDefinitionVersion;
private String businessKey;
@ -45,157 +45,227 @@ public class ProcessTaskWrapper {
private String taskHandFrontendComponentName;
private String taskHandFrontendComponentProperties;
private long createTimeAndNowDiff;
private ChronoUnit createTimeAndNowDiffUnit;
private String custNo;
private String custName;
private String processStatus;
private String previousAssignee;
private String previousAssigneeName;
private long startTimeAndNowDiff;
private ChronoUnit startTimeAndNowDiffUnit;
private long endTimeAndNowDiff;
private ChronoUnit endTimeAndNowDiffUnit;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getPriority() {
return priority;
}
public void setPriority(int priority) {
this.priority = priority;
}
public String getOwner() {
return owner;
}
public void setOwner(String owner) {
this.owner = owner;
}
public String getAssignee() {
return assignee;
}
public void setAssignee(String assignee) {
this.assignee = assignee;
}
public String getAssigneeName() {
return assigneeName;
}
public void setAssigneeName(String assigneeName) {
this.assigneeName = assigneeName;
}
public String getProcessInstanceId() {
return processInstanceId;
}
public void setProcessInstanceId(String processInstanceId) {
this.processInstanceId = processInstanceId;
}
public String getExecutionId() {
return executionId;
}
public void setExecutionId(String executionId) {
this.executionId = executionId;
}
public String getProcessDefinitionId() {
return processDefinitionId;
}
public void setProcessDefinitionId(String processDefinitionId) {
this.processDefinitionId = processDefinitionId;
}
public String getScopeId() {
return scopeId;
}
public void setScopeId(String scopeId) {
this.scopeId = scopeId;
}
public String getSubScopeId() {
return subScopeId;
}
public void setSubScopeId(String subScopeId) {
this.subScopeId = subScopeId;
}
public String getScopeType() {
return scopeType;
}
public void setScopeType(String scopeType) {
this.scopeType = scopeType;
}
public String getScopeDefinitionId() {
return scopeDefinitionId;
}
public void setScopeDefinitionId(String scopeDefinitionId) {
this.scopeDefinitionId = scopeDefinitionId;
}
public Date getCreateTime() {
return createTime;
public Date getStartTime() {
return startTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
Date now =new Date();
DateDiff dateDiff = DateUtil.dateDiff(this.createTime,now);
this.createTimeAndNowDiff =dateDiff.getAmount();
this.createTimeAndNowDiffUnit =dateDiff.getUnit();
public void setStartTime(Date startTime) {
this.startTime = startTime;
if(this.startTime!=null) {
Date now = new Date();
DateDiff dateDiff = DateUtil.dateDiff(this.startTime, now);
this.startTimeAndNowDiff = dateDiff.getAmount();
this.startTimeAndNowDiffUnit = dateDiff.getUnit();
}
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
if(this.endTime!=null) {
Date now = new Date();
DateDiff dateDiff = DateUtil.dateDiff(this.endTime, now);
this.endTimeAndNowDiff = dateDiff.getAmount();
this.endTimeAndNowDiffUnit = dateDiff.getUnit();
}
}
public String getTaskDefinitionKey() {
return taskDefinitionKey;
}
public void setTaskDefinitionKey(String taskDefinitionKey) {
this.taskDefinitionKey = taskDefinitionKey;
}
public Date getDueDate() {
return dueDate;
}
public void setDueDate(Date dueDate) {
this.dueDate = dueDate;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getParentTaskId() {
return parentTaskId;
}
public void setParentTaskId(String parentTaskId) {
this.parentTaskId = parentTaskId;
}
public String getTenantId() {
return tenantId;
}
public void setTenantId(String tenantId) {
this.tenantId = tenantId;
}
public String getFormKey() {
return formKey;
}
public void setFormKey(String formKey) {
this.formKey = formKey;
}
public Date getClaimTime() {
return claimTime;
}
public void setClaimTime(Date claimTime) {
this.claimTime = claimTime;
}
public String getPreviousAssignee() {
return previousAssignee;
public String getProcessDefinitionKey() {
return processDefinitionKey;
}
public void setPreviousAssignee(String previousAssignee) {
this.previousAssignee = previousAssignee;
public void setProcessDefinitionKey(String processDefinitionKey) {
this.processDefinitionKey = processDefinitionKey;
}
public String getProcessDefinitionName() {
return processDefinitionName;
}
public void setProcessDefinitionName(String processDefinitionName) {
this.processDefinitionName = processDefinitionName;
}
@ -211,6 +281,7 @@ public class ProcessTaskWrapper {
public String getBusinessKey() {
return businessKey;
}
public void setBusinessKey(String businessKey) {
this.businessKey = businessKey;
}
@ -255,19 +326,75 @@ public class ProcessTaskWrapper {
this.taskHandFrontendComponentProperties = taskHandFrontendComponentProperties;
}
public long getCreateTimeAndNowDiff() {
return createTimeAndNowDiff;
public String getCustNo() {
return custNo;
}
public void setCustNo(String custNo) {
this.custNo = custNo;
}
public String getCustName() {
return custName;
}
public void setCustName(String custName) {
this.custName = custName;
}
public String getProcessStatus() {
return processStatus;
}
public void setProcessStatus(String processStatus) {
this.processStatus = processStatus;
}
public String getPreviousAssignee() {
return previousAssignee;
}
public void setPreviousAssignee(String previousAssignee) {
this.previousAssignee = previousAssignee;
}
public String getPreviousAssigneeName() {
return previousAssigneeName;
}
public void setPreviousAssigneeName(String previousAssigneeName) {
this.previousAssigneeName = previousAssigneeName;
}
public long getStartTimeAndNowDiff() {
return startTimeAndNowDiff;
}
public void setStartTimeAndNowDiff(long startTimeAndNowDiff) {
this.startTimeAndNowDiff = startTimeAndNowDiff;
}
public ChronoUnit getStartTimeAndNowDiffUnit() {
return startTimeAndNowDiffUnit;
}
public void setStartTimeAndNowDiffUnit(ChronoUnit startTimeAndNowDiffUnit) {
this.startTimeAndNowDiffUnit = startTimeAndNowDiffUnit;
}
public long getEndTimeAndNowDiff() {
return endTimeAndNowDiff;
}
public void setCreateTimeAndNowDiff(long createTimeAndNowDiff) {
this.createTimeAndNowDiff = createTimeAndNowDiff;
public void setEndTimeAndNowDiff(long endTimeAndNowDiff) {
this.endTimeAndNowDiff = endTimeAndNowDiff;
}
public ChronoUnit getCreateTimeAndNowDiffUnit() {
return createTimeAndNowDiffUnit;
public ChronoUnit getEndTimeAndNowDiffUnit() {
return endTimeAndNowDiffUnit;
}
public void setCreateTimeAndNowDiffUnit(ChronoUnit createTimeAndNowDiffUnit) {
this.createTimeAndNowDiffUnit = createTimeAndNowDiffUnit;
public void setEndTimeAndNowDiffUnit(ChronoUnit endTimeAndNowDiffUnit) {
this.endTimeAndNowDiffUnit = endTimeAndNowDiffUnit;
}
}

26
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/ProcessTaskWrapperMapper.java

@ -13,29 +13,45 @@ public class ProcessTaskWrapperMapper implements RowMapper<ProcessTaskWrapper> {
@Override
public ProcessTaskWrapper mapRow(ResultSet rs, int rowNum) throws SQLException {
ProcessTaskWrapper wrapper =new ProcessTaskWrapper();
wrapper.setId(rs.getString("id"));
wrapper.setName(rs.getString("name"));
wrapper.setDescription(rs.getString("description"));
wrapper.setPriority(rs.getInt("priority"));
wrapper.setOwner(rs.getString("owner"));
wrapper.setAssignee(rs.getString("assignee"));
wrapper.setAssigneeName(rs.getString("assigneeName"));
wrapper.setProcessInstanceId(rs.getString("processInstanceId"));
wrapper.setExecutionId(rs.getString("executionId"));
wrapper.setProcessDefinitionId(rs.getString("processDefinitionId"));
wrapper.setProcessDefinitionName(rs.getString("processDefinitionName"));
wrapper.setProcessDefinitionVersion(rs.getInt("processDefinitionVersion"));
wrapper.setScopeId(rs.getString("scopeId"));
wrapper.setSubScopeId(rs.getString("subScopeId"));
wrapper.setScopeType(rs.getString("scopeType"));
wrapper.setScopeDefinitionId(rs.getString("scopeDefinitionId"));
wrapper.setCreateTime(rs.getDate("createTime"));
wrapper.setStartTime(rs.getTimestamp("startTime"));
wrapper.setEndTime(rs.getTimestamp("endTime"));
wrapper.setTaskDefinitionKey(rs.getString("taskDefinitionKey"));
wrapper.setDueDate(rs.getDate("dueDate"));
wrapper.setDueDate(rs.getTimestamp("dueDate"));
wrapper.setCategory(rs.getString("category"));
wrapper.setParentTaskId(rs.getString("parentTaskId"));
wrapper.setTenantId(rs.getString("tenantId"));
wrapper.setFormKey(rs.getString("formKey"));
wrapper.setClaimTime(rs.getDate("claimTime"));
wrapper.setClaimTime(rs.getTimestamp("claimTime"));
wrapper.setProcessDefinitionKey(rs.getString("processDefinitionKey"));
wrapper.setProcessDefinitionName(rs.getString("processDefinitionName"));
wrapper.setProcessDefinitionVersion(rs.getInt("processDefinitionVersion"));
wrapper.setBusinessKey(rs.getString("businessKey"));
wrapper.setBusinessDescription(rs.getString("businessDescription"));
wrapper.setTaskHandFrontendRouteName(rs.getString("taskHandFrontendRouteName"));
wrapper.setTaskHandFrontendModelName(rs.getString("taskHandFrontendModelName"));
wrapper.setTaskHandFrontendComponentName(rs.getString("taskHandFrontendComponentName"));
wrapper.setTaskHandFrontendComponentProperties(rs.getString("taskHandFrontendComponentProperties"));
wrapper.setCustNo(rs.getString("custNo"));
wrapper.setCustName(rs.getString("custName"));
wrapper.setProcessStatus(rs.getString("processStatus"));
return wrapper;
}
}

3
io.sc.platform.flowable/src/main/resources/META-INF/platform/plugins/messages.json

@ -2,6 +2,7 @@
"includes":[
"io/sc/platform/flowable/i18n/initializer",
"io/sc/platform/flowable/i18n/enums",
"io/sc/platform/flowable/i18n/dictionary"
"io/sc/platform/flowable/i18n/dictionary",
"io/sc/platform/flowable/i18n/parameters"
]
}

22
io.sc.platform.flowable/src/main/resources/META-INF/platform/plugins/parameters.json

@ -0,0 +1,22 @@
[
/*/*/
{ "id": "parameter.system.workbench", "parentId": "parameter.system","order": 100 },
/*//*/
{
"id": "parameter.system.workbench.processDefines",
"parentId": "parameter.system.workbench",
"code": "parameter.system.workbench.processDefines",
"multiLineText": true,
"defaultValue": "{}",
"order": 100
},
/*//*/
{
"id": "parameter.system.workbench.processStatus",
"parentId": "parameter.system.workbench",
"code": "parameter.system.workbench.processStatus",
"multiLineText": true,
"defaultValue": "{}",
"order": 200
}
]

3
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/parameters.properties

@ -0,0 +1,3 @@
parameter.system.workbench=Workbench
parameter.system.workbench.processDefines=Process Defines Mapping
parameter.system.workbench.processStatus=Process Status Enums

3
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/parameters_tw_CN.properties

@ -0,0 +1,3 @@
parameter.system.workbench=\u5DE5\u4F5C\u53F0
parameter.system.workbench.processDefines=\u6D41\u7A0B\u5B9A\u7FA9\u6620\u5C04
parameter.system.workbench.processStatus=\u6D41\u7A0B\u72C0\u614B\u679A\u8209

3
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/parameters_zh_CN.properties

@ -0,0 +1,3 @@
parameter.system.workbench=\u5DE5\u4F5C\u53F0
parameter.system.workbench.processDefines=\u6D41\u7A0B\u5B9A\u4E49\u6620\u5C04
parameter.system.workbench.processStatus=\u6D41\u7A0B\u72B6\u6001\u679A\u4E3E

46
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/DoneTask.sql

@ -0,0 +1,46 @@
select * from (
select
T.ID_ as id,
T.NAME_ as name,
T.DESCRIPTION_ as description,
T.PRIORITY_ as priority,
T.OWNER_ as owner,
T.ASSIGNEE_ as assignee,
T.PROC_INST_ID_ as processInstanceId,
T.EXECUTION_ID_ as executionId,
T.PROC_DEF_ID_ as processDefinitionId,
T.SCOPE_ID_ as scopeId,
T.SUB_SCOPE_ID_ as subScopeId,
T.SCOPE_TYPE_ as scopeType,
T.SCOPE_DEFINITION_ID_ as scopeDefinitionId,
T.START_TIME_ as startTime,
T.END_TIME_ as endTime,
T.TASK_DEF_KEY_ as taskDefinitionKey,
T.DUE_DATE_ as dueDate,
T.CATEGORY_ as category,
T.PARENT_TASK_ID_ as parentTaskId,
T.TENANT_ID_ as tenantId,
T.FORM_KEY_ as formKey,
T.CLAIM_TIME_ as claimTime,
U.USERNAME_ as assigneeName,
DEF.KEY_ as processDefinitionKey,
DEF.NAME_ as processDefinitionName,
DEF.VERSION_ as processDefinitionVersion,
EXE.BUSINESS_KEY_ as businessKey,
CONCAT(PROCESS_EXT.CUST_NO_,PROCESS_EXT.CUST_NAME_) as businessDescription,
PROCESS.TASK_HAND_FE_ROUTE_NAME_ as taskHandFrontendRouteName,
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus,
row_number() over(partition by T.PROC_INST_ID_ order by T.END_TIME_ desc) as RK
from ACT_HI_TASKINST T
left join ACT_RE_PROCDEF DEF on DEF.ID_ = T.PROC_DEF_ID_
left join ACT_RU_EXECUTION EXE on EXE.ID_ = T.PROC_INST_ID_
left join SYS_USER U on U.LOGINNAME_ = T.ASSIGNEE_
left join SYS_PROCESS PROCESS on PROCESS.DEPLOYED_ID_ = T.PROC_DEF_ID_
left join SYS_PROCESS_INST_EXT PROCESS_EXT on PROCESS_EXT.PROC_INST_ID_ = T.PROC_INST_ID_
where T.PROC_INST_ID_ ='${0}'
) TMP where TMP.RK = 1

48
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/FinishedTask.sql

@ -0,0 +1,48 @@
select * from (
select
T.ID_ as id,
T.NAME_ as name,
T.DESCRIPTION_ as description,
T.PRIORITY_ as priority,
T.OWNER_ as owner,
T.ASSIGNEE_ as assignee,
T.PROC_INST_ID_ as processInstanceId,
T.EXECUTION_ID_ as executionId,
T.PROC_DEF_ID_ as processDefinitionId,
T.SCOPE_ID_ as scopeId,
T.SUB_SCOPE_ID_ as subScopeId,
T.SCOPE_TYPE_ as scopeType,
T.SCOPE_DEFINITION_ID_ as scopeDefinitionId,
INST.START_TIME_ as startTime,
INST.END_TIME_ as endTime,
T.TASK_DEF_KEY_ as taskDefinitionKey,
T.DUE_DATE_ as dueDate,
T.CATEGORY_ as category,
T.PARENT_TASK_ID_ as parentTaskId,
T.TENANT_ID_ as tenantId,
T.FORM_KEY_ as formKey,
T.CLAIM_TIME_ as claimTime,
U.USERNAME_ as assigneeName,
DEF.KEY_ as processDefinitionKey,
DEF.NAME_ as processDefinitionName,
DEF.VERSION_ as processDefinitionVersion,
INST.BUSINESS_KEY_ as businessKey,
CONCAT(PROCESS_EXT.CUST_NO_,PROCESS_EXT.CUST_NAME_) as businessDescription,
PROCESS.TASK_HAND_FE_ROUTE_NAME_ as taskHandFrontendRouteName,
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus,
row_number() over(partition by T.PROC_INST_ID_ order by T.END_TIME_ desc) as RK
from ACT_HI_TASKINST T
left join ACT_RE_PROCDEF DEF on DEF.ID_ = T.PROC_DEF_ID_
left join ACT_HI_PROCINST INST on T.PROC_INST_ID_ = INST.PROC_INST_ID_
left join SYS_USER U on U.LOGINNAME_ = T.ASSIGNEE_
left join SYS_PROCESS PROCESS on PROCESS.DEPLOYED_ID_ = T.PROC_DEF_ID_
left join SYS_PROCESS_INST_EXT PROCESS_EXT on PROCESS_EXT.PROC_INST_ID_ = T.PROC_INST_ID_
where T.PROC_INST_ID_ ='${0}'
) tmp where tmp.RK = 1

52
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/MyDoneTasks.sql

@ -0,0 +1,52 @@
select * from (
select * from (
select
T.ID_ as id,
T.NAME_ as name,
T.DESCRIPTION_ as description,
T.PRIORITY_ as priority,
T.OWNER_ as owner,
T.ASSIGNEE_ as assignee,
T.PROC_INST_ID_ as processInstanceId,
T.EXECUTION_ID_ as executionId,
T.PROC_DEF_ID_ as processDefinitionId,
T.SCOPE_ID_ as scopeId,
T.SUB_SCOPE_ID_ as subScopeId,
T.SCOPE_TYPE_ as scopeType,
T.SCOPE_DEFINITION_ID_ as scopeDefinitionId,
T.CREATE_TIME_ as startTime,
NULL as endTime,
T.TASK_DEF_KEY_ as taskDefinitionKey,
T.DUE_DATE_ as dueDate,
T.CATEGORY_ as category,
T.PARENT_TASK_ID_ as parentTaskId,
T.TENANT_ID_ as tenantId,
T.FORM_KEY_ as formKey,
T.CLAIM_TIME_ as claimTime,
U.USERNAME_ as assigneeName,
DEF.KEY_ as processDefinitionKey,
DEF.NAME_ as processDefinitionName,
DEF.VERSION_ as processDefinitionVersion,
EXE.BUSINESS_KEY_ as businessKey,
CONCAT(PROCESS_EXT.CUST_NO_,PROCESS_EXT.CUST_NAME_) as businessDescription,
PROCESS.TASK_HAND_FE_ROUTE_NAME_ as taskHandFrontendRouteName,
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus,
row_number() over(partition by HT.PROC_INST_ID_ order by HT.END_TIME_ desc) as RK
from ACT_HI_TASKINST HT
join ACT_RU_TASK T on T.PROC_INST_ID_ = HT.PROC_INST_ID_
join ACT_RU_EXECUTION EXE on T.PROC_INST_ID_ = EXE.ID_
left join ACT_RE_PROCDEF DEF on HT.PROC_DEF_ID_ = DEF.ID_
left join SYS_USER U on T.ASSIGNEE_ = U.LOGINNAME_
left join SYS_PROCESS PROCESS on PROCESS.DEPLOYED_ID_ = T.PROC_DEF_ID_
left join SYS_PROCESS_INST_EXT PROCESS_EXT on PROCESS_EXT.PROC_INST_ID_ = T.PROC_INST_ID_
where
HT.ASSIGNEE_ ='${0}'
and T.ASSIGNEE_ <> '${0}'
and HT.END_TIME_ is not null
) TMP where TMP.RK = 1
) R

64
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/MyFinishedTasks.sql

@ -0,0 +1,64 @@
select * from (
select * from (
select
T.ID_ as id,
T.NAME_ as name,
T.DESCRIPTION_ as description,
T.PRIORITY_ as priority,
T.OWNER_ as owner,
T.ASSIGNEE_ as assignee,
T.PROC_INST_ID_ as processInstanceId,
T.EXECUTION_ID_ as executionId,
T.PROC_DEF_ID_ as processDefinitionId,
T.SCOPE_ID_ as scopeId,
T.SUB_SCOPE_ID_ as subScopeId,
T.SCOPE_TYPE_ as scopeType,
T.SCOPE_DEFINITION_ID_ as scopeDefinitionId,
INST.START_TIME_ as startTime,
INST.END_TIME_ as endTime,
T.TASK_DEF_KEY_ as taskDefinitionKey,
T.DUE_DATE_ as dueDate,
T.CATEGORY_ as category,
T.PARENT_TASK_ID_ as parentTaskId,
T.TENANT_ID_ as tenantId,
T.FORM_KEY_ as formKey,
T.CLAIM_TIME_ as claimTime,
U.USERNAME_ as assigneeName,
DEF.KEY_ as processDefinitionKey,
DEF.NAME_ as processDefinitionName,
DEF.VERSION_ as processDefinitionVersion,
INST.BUSINESS_KEY_ as businessKey,
CONCAT(PROCESS_EXT.CUST_NO_,PROCESS_EXT.CUST_NAME_) as businessDescription,
PROCESS.TASK_HAND_FE_ROUTE_NAME_ as taskHandFrontendRouteName,
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus,
row_number() over(partition by T.PROC_INST_ID_ order by T.END_TIME_ desc) as RK
from ACT_HI_TASKINST T
left join ACT_RE_PROCDEF DEF on T.PROC_DEF_ID_ = DEF.ID_
join ACT_HI_PROCINST INST on T.PROC_INST_ID_ = INST.PROC_INST_ID_
left join SYS_USER U on U.LOGINNAME_ = T.ASSIGNEE_
left join SYS_PROCESS PROCESS on PROCESS.DEPLOYED_ID_ = T.PROC_DEF_ID_
left join SYS_PROCESS_INST_EXT PROCESS_EXT on PROCESS_EXT.PROC_INST_ID_ = T.PROC_INST_ID_
where
exists (
select 1 from ACT_HI_TASKINST AHT
where
AHT.ASSIGNEE_ = '${0}'
and AHT.END_TIME_ is not null
and exists (
select 1 from ACT_HI_PROCINST AHP
where
AHP.END_TIME_ is not null
and AHP.END_ACT_ID_ is not null
and AHP.PROC_INST_ID_ = T.PROC_INST_ID_
)
and AHT.PROC_INST_ID_ = T.PROC_INST_ID_
)
) tmp where tmp.RK = 1
) R

44
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/MyTasks.sql

@ -0,0 +1,44 @@
select * from (
select
T.ID_ as id,
T.NAME_ as name,
T.DESCRIPTION_ as description,
T.PRIORITY_ as priority,
T.OWNER_ as owner,
T.ASSIGNEE_ as assignee,
T.PROC_INST_ID_ as processInstanceId,
T.EXECUTION_ID_ as executionId,
T.PROC_DEF_ID_ as processDefinitionId,
T.SCOPE_ID_ as scopeId,
T.SUB_SCOPE_ID_ as subScopeId,
T.SCOPE_TYPE_ as scopeType,
T.SCOPE_DEFINITION_ID_ as scopeDefinitionId,
T.CREATE_TIME_ as startTime,
NULL as endTime,
T.TASK_DEF_KEY_ as taskDefinitionKey,
T.DUE_DATE_ as dueDate,
T.CATEGORY_ as category,
T.PARENT_TASK_ID_ as parentTaskId,
T.TENANT_ID_ as tenantId,
T.FORM_KEY_ as formKey,
T.CLAIM_TIME_ as claimTime,
U.USERNAME_ as assigneeName,
DEF.KEY_ as processDefinitionKey,
DEF.NAME_ as processDefinitionName,
DEF.VERSION_ as processDefinitionVersion,
EXE.BUSINESS_KEY_ as businessKey,
CONCAT(PROCESS_EXT.CUST_NO_,PROCESS_EXT.CUST_NAME_) as businessDescription,
PROCESS.TASK_HAND_FE_ROUTE_NAME_ as taskHandFrontendRouteName,
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus
from ACT_RU_TASK T
left join ACT_RE_PROCDEF DEF on DEF.ID_ = T.PROC_DEF_ID_
left join ACT_RU_EXECUTION EXE on EXE.ID_ = T.PROC_INST_ID_
left join SYS_USER U on U.LOGINNAME_ = T.ASSIGNEE_
left join SYS_PROCESS PROCESS on PROCESS.DEPLOYED_ID_ = T.PROC_DEF_ID_
left join SYS_PROCESS_INST_EXT PROCESS_EXT on PROCESS_EXT.PROC_INST_ID_ = T.PROC_INST_ID_
) R

16
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/ProcessPrefixAssignee.sql

@ -0,0 +1,16 @@
select * from (
select
HT.ID_ as id,
HT.NAME_ as name,
HT.PROC_INST_ID_ as processInstanceId,
HT.END_TIME_ as endTime,
HT.ASSIGNEE_ as assignee,
USER.USERNAME_ as assigneeName,
row_number() over(partition by PROC_INST_ID_ order by END_TIME_ desc) as RK
from ACT_HI_TASKINST HT
left join SYS_USER USER on USER.LOGINNAME_ = HT.ASSIGNEE_
where
HT.END_TIME_ is not null
and HT.PROC_INST_ID_ in (${0})
) R
where R.RK = 1

43
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/Task.sql

@ -0,0 +1,43 @@
select
T.ID_ as id,
T.NAME_ as name,
T.DESCRIPTION_ as description,
T.PRIORITY_ as priority,
T.OWNER_ as owner,
T.ASSIGNEE_ as assignee,
T.PROC_INST_ID_ as processInstanceId,
T.EXECUTION_ID_ as executionId,
T.PROC_DEF_ID_ as processDefinitionId,
T.SCOPE_ID_ as scopeId,
T.SUB_SCOPE_ID_ as subScopeId,
T.SCOPE_TYPE_ as scopeType,
T.SCOPE_DEFINITION_ID_ as scopeDefinitionId,
T.CREATE_TIME_ as startTime,
NULL as endTime,
T.TASK_DEF_KEY_ as taskDefinitionKey,
T.DUE_DATE_ as dueDate,
T.CATEGORY_ as category,
T.PARENT_TASK_ID_ as parentTaskId,
T.TENANT_ID_ as tenantId,
T.FORM_KEY_ as formKey,
T.CLAIM_TIME_ as claimTime,
U.USERNAME_ as assigneeName,
DEF.KEY_ as processDefinitionKey,
DEF.NAME_ as processDefinitionName,
DEF.VERSION_ as processDefinitionVersion,
EXE.BUSINESS_KEY_ as businessKey,
CONCAT(PROCESS_EXT.CUST_NO_,PROCESS_EXT.CUST_NAME_) as businessDescription,
PROCESS.TASK_HAND_FE_ROUTE_NAME_ as taskHandFrontendRouteName,
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus
from ACT_RU_TASK T
left join ACT_RE_PROCDEF DEF on DEF.ID_ = T.PROC_DEF_ID_
left join ACT_RU_EXECUTION EXE on EXE.ID_ = T.PROC_INST_ID_
left join SYS_USER U on U.LOGINNAME_ = T.ASSIGNEE_
left join SYS_PROCESS PROCESS on PROCESS.DEPLOYED_ID_ = T.PROC_DEF_ID_
left join SYS_PROCESS_INST_EXT PROCESS_EXT on PROCESS_EXT.PROC_INST_ID_ = T.PROC_INST_ID_
where T.ID_ ='${0}' and T.ASSIGNEE_='${1}'

20
io.sc.platform.flowable/src/main/resources/liquibase/io.sc.platform.flowable_8.0.0_20220606__Process_Manager_Database_Schema_DDL.xml

@ -49,6 +49,26 @@
<addDefaultValue columnName="CORP_CODE_" columnDataType="NVARCHAR(255)" tableName="SYS_PROCESS" defaultValue="_PRIMARY_"/>
<createTable tableName="SYS_PROCESS_INST_EXT" remarks="流程实例属性扩展表">
<column name="PROC_INST_ID_" type="NVARCHAR(64)" remarks="流程实例ID">
<constraints primaryKey="true"/>
</column>
<column name="PROC_DEF_ID_" type="NVARCHAR(255)" remarks="流程定义ID"></column>
<column name="CUST_NO_" type="NVARCHAR(255)" remarks="客户号"></column>
<column name="CUST_NAME_" type="NVARCHAR(255)" remarks="客户名称"></column>
<column name="PROCESS_STATUS_" type="NVARCHAR(255)" remarks="流程状态"></column>
</createTable>
<createIndex tableName="SYS_PROCESS_INST_EXT" indexName="IDX_SYS_PIE_CUST_NO">
<column name="CUST_NO_"></column>
</createIndex>
<createIndex tableName="SYS_PROCESS_INST_EXT" indexName="IDX_SYS_PIE_CUST_NAME">
<column name="CUST_NAME_"></column>
</createIndex>
<createIndex tableName="SYS_PROCESS_INST_EXT" indexName="IDX_SYS_PIE_PROCESS_STATUS">
<column name="PROCESS_STATUS_"></column>
</createIndex>
<!-- 代理人配置表 -->
<createTable tableName="SYS_AGENT" remarks="代理人配置表">
<column name="ID_" type="NVARCHAR(36)" remarks="ID">

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

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.lcdp.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

4
io.sc.platform.lcdp.frontend/src/i18n/messages.json

@ -170,6 +170,7 @@
"lcdp.bpm.tabs.processInstance": "Process Instance",
"lcdp.bpm.tabs.task": "Process Task",
"lcdp.bpm.tabs.tools": "Tools",
"lcdp.bpm.tabs.workbench": "Workbench",
"lcdp.bpm.processDefine.grid.title": "Process Define List",
"lcdp.bpm.processDefine.grid.toolbar.design": "Design",
@ -252,6 +253,9 @@
"lcdp.bpm.tools.action.cleanHistoryData": "Clean History Data",
"lcdp.bpm.tools.action.cleanHistoryData.tip": "Are you sure to clean the history data?",
"lcdp.bpm.task.grid.workbench.processDefine": "Process Define List",
"lcdp.bpm.task.grid.workbench.processStatus": "Process Status List",
"lcdp.jxls.template.grid.title": "Templates",
"lcdp.jxls.template.grid.action.updateAttachment": "Update Attachment",
"lcdp.jxls.template.grid.action.downloadAttachment": "Download Attachment",

4
io.sc.platform.lcdp.frontend/src/i18n/messages_tw_CN.json

@ -170,6 +170,7 @@
"lcdp.bpm.tabs.processInstance": "流程實例",
"lcdp.bpm.tabs.task": "工作任務",
"lcdp.bpm.tabs.tools": "工具",
"lcdp.bpm.tabs.workbench": "工作台",
"lcdp.bpm.processDefine.grid.title": "流程定義列表",
"lcdp.bpm.processDefine.grid.toolbar.design": "設計",
@ -252,6 +253,9 @@
"lcdp.bpm.tools.action.cleanHistoryData": "清除歷史數據",
"lcdp.bpm.tools.action.cleanHistoryData.tip": "您確定要清除歷史數據嗎?",
"lcdp.bpm.task.grid.workbench.processDefine": "流程定義列表",
"lcdp.bpm.task.grid.workbench.processStatus": "流程狀態列表",
"lcdp.jxls.template.grid.title": "JXLS 模版列表",
"lcdp.jxls.template.grid.action.updateAttachment": "上傳模版",
"lcdp.jxls.template.grid.action.downloadAttachment": "下載模版",

4
io.sc.platform.lcdp.frontend/src/i18n/messages_zh_CN.json

@ -170,6 +170,7 @@
"lcdp.bpm.tabs.processInstance": "流程实例",
"lcdp.bpm.tabs.task": "工作任务",
"lcdp.bpm.tabs.tools": "工具",
"lcdp.bpm.tabs.workbench": "工作台",
"lcdp.bpm.processDefine.grid.title": "流程定义列表",
"lcdp.bpm.processDefine.grid.toolbar.design": "设计",
@ -252,6 +253,9 @@
"lcdp.bpm.tools.action.cleanHistoryData": "清除历史数据",
"lcdp.bpm.tools.action.cleanHistoryData.tip": "您确定要清除历史数据吗?",
"lcdp.bpm.task.grid.workbench.processDefine": "流程定义列表",
"lcdp.bpm.task.grid.workbench.processStatus": "流程状态列表",
"lcdp.jxls.template.grid.title": "JXLS 模版列表",
"lcdp.jxls.template.grid.action.updateAttachment": "上传模版",
"lcdp.jxls.template.grid.action.downloadAttachment": "下载模版",

76
io.sc.platform.lcdp.frontend/src/views/bpm/Bpm.vue

@ -7,6 +7,7 @@
<q-tab name="processInstance" icon="bi-sliders" :label="$t('lcdp.bpm.tabs.processInstance')" />
<q-tab name="task" icon="bi-receipt" :label="$t('lcdp.bpm.tabs.task')" />
<q-tab name="tools" icon="bi-wrench-adjustable" :label="$t('lcdp.bpm.tabs.tools')" />
<q-tab name="workbench" icon="bi-layers" :label="$t('lcdp.bpm.tabs.workbench')" />
</q-tabs>
</template>
<template #after>
@ -233,6 +234,7 @@
rule: [],
},
{
colSpan: 2,
name: 'forceSelectAssignee',
label: $t('lcdp.bpm.processDefine.grid.entity.forceSelectAssignee'),
type: 'w-checkbox',
@ -240,7 +242,7 @@
rule: [],
},
{
colSpan: 2,
colSpan: 3,
type: 'w-form-group',
align: 'right',
fields: [
@ -252,11 +254,16 @@
noCaps: true,
style: 'width:100px',
onClick: (args: any) => {
let sql = 'select\n';
sql += '\tbusinessKeyFieldName BUSSINESS_KEY,\n';
sql += '\tbusinessDescriptionFieldName BUSSINESS_DESCRIPTION\n';
sql += 'from bussinessTable\n';
sql += 'where businessKeyFieldName in (${bussinessKeys})';
let sql = '';
sql += 'select\n';
sql += ' CONCAT(CODE_,\':\',VERSION_) BUSINESS_KEY,\n';
sql += ' NAME_ CUST_NO,\n';
sql += ' CONCAT(\'V\',VERSION_) CUST_NAME,\n';
sql += 'from RE_RESOURCE\n';
sql += 'where CONCAT(CODE_,\':\',VERSION_) = \'${businessKey}\'\n';
sql += '\n';
sql += '\n';
sql += '\n';
processDefineGridRef.getEditorForm().setFieldValue('businessDescriptionSql', sql);
},
},
@ -697,6 +704,60 @@
<q-btn :label="$t('lcdp.bpm.tools.action.cleanHistoryData')" color="primary" no-caps @click="cleanHistoryData"></q-btn>
</div>
</q-tab-panel>
<q-tab-panel name="workbench" class="pl-1 pr-0 pb-0" style="height: 100%">
<w-splitter :model-value="50" horizontal style="height: 100%">
<template #before>
<w-grid
ref="workbenchProcessDefineGridRef"
:title="$t('lcdp.bpm.task.grid.workbench.processDefine')"
dense
:data-url="Environment.apiContextPath('/api/flowable/process/query/task')"
:auto-fetch-data="true"
:pageable="false"
:sort-by="[]"
:toolbar-actions="['refresh', 'separator', 'add', 'edit', 'remove', 'separator', 'view']"
:columns="[
{ width: '50%', name: 'code', label: $t('code'), sortable: false },
{ width: '50%', name: 'name', label: $t('name') },
]"
:editor="{
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [],
},
}"
></w-grid>
</template>
<template #after>
<w-grid
ref="workbenchProcessStatusGridRef"
:title="$t('lcdp.bpm.task.grid.workbench.processStatus')"
dense
:data-url="Environment.apiContextPath('/api/flowable/process/query/task')"
:auto-fetch-data="true"
:pageable="false"
:sort-by="[]"
:toolbar-actions="['refresh', 'separator', 'add', 'edit', 'remove', 'separator', 'view']"
:columns="[
{ width: '50%', name: 'code', label: $t('code'), sortable: false },
{ width: '50%', name: 'name', label: $t('name') },
]"
:editor="{
dialog: {
width: '600px',
},
form: {
colsNum: 1,
fields: [],
},
}"
></w-grid>
</template>
</w-splitter>
</q-tab-panel>
</q-tab-panels>
</template>
</q-splitter>
@ -727,6 +788,9 @@ const selectedTabRef = ref('processDefine');
const processDefineGridRef = ref();
const processInstanceGridRef = ref();
const taskGridRef = ref();
const workbenchProcessDefineGridRef = ref();
const workbenchProcessStatusGridRef = ref();
const variableDialogRef = ref();
const completeTaskDialogRef = ref();
const jumpTaskDialogRef = ref();

5
io.sc.platform.license.keygen.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.license.keygen.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

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

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.mvc.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

3
io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/support/RestCrudController.java

@ -243,8 +243,9 @@ public abstract class RestCrudController<V extends BaseVo, E extends BaseEntity<
}
protected void exportExcel(HttpServletRequest request,HttpServletResponse response,QueryParameter queryParameter) throws Exception{
String downloadFileName =request.getParameter("downloadFileName");
ByteArrayOutputStream outputStream =new ByteArrayOutputStream();
DataExportConfigure cofigure =service.export(queryParameter,outputStream);
DataExportConfigure cofigure =service.export(queryParameter,outputStream,downloadFileName);
InputStream inputStream =new ByteArrayInputStream(outputStream.toByteArray());
FileDownloader.download(request, response, cofigure.getDownloadFileName(), inputStream);
}

21
io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/plugins/item/Parameter.java

@ -12,6 +12,7 @@ public class Parameter {
protected Integer priority =0;
protected String description;
protected Map<String, String> options;
protected Boolean multiLineText;
//附加属性
private String configurationFileUrl; //菜单贡献项配置文件位置
@ -80,6 +81,14 @@ public class Parameter {
this.options = options;
}
public Boolean getMultiLineText() {
return multiLineText;
}
public void setMultiLineText(Boolean multiLineText) {
this.multiLineText = multiLineText;
}
public String getConfigurationFileUrl() {
return configurationFileUrl;
}
@ -87,16 +96,4 @@ public class Parameter {
public void setConfigurationFileUrl(String configurationFileUrl) {
this.configurationFileUrl = configurationFileUrl;
}
@Override
public String toString() {
return "SystemParameterContributionItem [id=" + id
+ ", parentId=" + parentId
+ ", code=" + code
+ ", defaultValue=" + defaultValue
+ ", order=" + order
+ ", priority=" + priority
+ ", description=" + description
+ ", configurationFileUrl=" + configurationFileUrl + "]";
}
}

2
io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/DaoService.java

@ -65,5 +65,5 @@ public interface DaoService<E,ID extends Serializable,R extends DaoRepository<E,
public Stream<E> stream(Specification<E> specification, Sort sort) throws Exception;
public DataExportConfigure getExportConfigure();
public DataExportConfigure export(QueryParameter queryParameter, OutputStream outputStream) throws Exception;
public DataExportConfigure export(QueryParameter queryParameter, OutputStream outputStream,String downloadFileName) throws Exception;
}

5
io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/impl/DaoServiceImpl.java

@ -636,11 +636,14 @@ public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepo
}
@Override
public DataExportConfigure export(QueryParameter queryParameter, OutputStream outputStream) throws Exception {
public DataExportConfigure export(QueryParameter queryParameter, OutputStream outputStream,String downloadFileName) throws Exception {
DataExportConfigure dataExportConfigure =this.getExportConfigure();
if(dataExportConfigure==null){
return null;
}
if(StringUtils.hasText(downloadFileName)){
dataExportConfigure.setDownloadFileName(downloadFileName + ".xlsx");
}
String templateClassPath =dataExportConfigure.getJxlsTemplateClassPath();
String templateCode =dataExportConfigure.getJxlsTemplateCode();

4
io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/support/criteria/impl/BetweenInclusive.java

@ -57,14 +57,14 @@ public class BetweenInclusive<E> extends Between<E> {
if(pStart==null && pEnd==null){
return condition;
}else if(pStart!=null && pEnd!=null){
condition.setWhere(StringUtil.format("${0} >= ${1} and ${0} <= ${2}",fieldName,nStart, nEnd));
condition.setWhere(StringUtil.format("${0} >= ${1} and ${0} < ${2}",fieldName,nStart, nEnd));
condition.getParameters().put(nStart.substring(1),pStart);
condition.getParameters().put(nEnd.substring(1),pEnd);
}else if(pStart!=null){
condition.setWhere(StringUtil.format("${0} >= ${1}",fieldName,nStart));
condition.getParameters().put(nStart.substring(1),pStart);
}else {
condition.setWhere(StringUtil.format("${0} <= ${1}",fieldName,nEnd));
condition.setWhere(StringUtil.format("${0} < ${1}",fieldName,nEnd));
condition.getParameters().put(nEnd.substring(1),pEnd);
}
return condition;

1
io.sc.platform.poi/build.gradle

@ -7,5 +7,6 @@ dependencies {
"org.jxls:jxls:${jxls_version}",
"org.jxls:jxls-poi:${jxls_version}",
"org.apache.commons:commons-jexl3:${commons_jexl3_version}",
)
}

5
io.sc.platform.scheduler.manager.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.scheduler.manager.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

9
io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/parameter/ParameterVo.java

@ -14,6 +14,7 @@ public class ParameterVo extends CorporationAuditorVo {
private Integer order;
private String defaultValue;
private Map<String,String> options;
private Boolean multiLineText;
private String parent;
public String getId() {
@ -64,6 +65,14 @@ public class ParameterVo extends CorporationAuditorVo {
this.options = options;
}
public Boolean getMultiLineText() {
return multiLineText;
}
public void setMultiLineText(Boolean multiLineText) {
this.multiLineText = multiLineText;
}
public String getParent() {
return parent;
}

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

@ -1,6 +1,6 @@
{
"name": "io.sc.platform.system.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -111,7 +112,7 @@
"mockjs": "1.1.0",
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

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

@ -212,33 +212,26 @@
"settings.shortcutMenus.entity.shortcutMenuName": "Shortcut Menu Name",
"settings.shortcutMenus.entity.menuIconColor": "Icon Color",
"workbench.grid.entity.processDefinitionName": "Process Name",
"workbench.grid.entity.businessKey": "Business Key",
"workbench.grid.entity.businessDescription": "Business Description",
"workbench.grid.entity.custNo": "Customer No.",
"workbench.grid.entity.custName": "Customer Name",
"workbench.grid.entity.taskType": "Task Type",
"workbench.grid.entity.processStatus": "Process Status",
"workbench.grid.entity.activityName": "Activity Name",
"workbench.grid.entity.previousAssignee": "Previous Assignee",
"workbench.grid.entity.currentAssignee": "Current Assignee",
"workbench.grid.entity.lastAssignee": "Last Assignee",
"workbench.grid.entity.startTime": "Task Start Time",
"workbench.grid.entity.endTime": "Task End Time",
"workbench.myTask.grid.title": "My Tasks",
"workbench.myTask.grid.action.process": "Process",
"workbench.myTask.grid.entity.businessKey": "Business Key",
"workbench.myTask.grid.entity.businessDescription": "Business Description",
"workbench.myTask.grid.entity.processDefinitionName": "Process Name",
"workbench.myTask.grid.entity.activityName": "Activity Name",
"workbench.myTask.grid.entity.taskDescription": "Task Description",
"workbench.myTask.grid.entity.prefixAssignee": "Prefix Assignee",
"workbench.myTask.grid.entity.createTime": "Task Create Time",
"workbench.myDoneTask.grid.title": "My Done Tasks",
"workbench.myDoneTask.grid.action.view": "View",
"workbench.myDoneTask.grid.entity.businessKey": "Business Key",
"workbench.myDoneTask.grid.entity.businessDescription": "Business Description",
"workbench.myDoneTask.grid.entity.processDefinitionName": "Process Name",
"workbench.myDoneTask.grid.entity.activityName": "Activity Name",
"workbench.myDoneTask.grid.entity.taskDescription": "Task Description",
"workbench.myDoneTask.grid.entity.prefixAssignee": "Prefix Assignee",
"workbench.myDoneTask.grid.entity.createTime": "Task Create Time",
"workbench.myFinishedTask.grid.title": "My Finished Tasks",
"workbench.myFinishedTask.grid.action.view": "View",
"workbench.myFinishedTask.grid.entity.businessKey": "Business Key",
"workbench.myFinishedTask.grid.entity.businessDescription": "Business Description",
"workbench.myFinishedTask.grid.entity.processDefinitionName": "Process Name",
"workbench.myFinishedTask.grid.entity.activityName": "Activity Name",
"workbench.myFinishedTask.grid.entity.taskDescription": "Task Description",
"workbench.myFinishedTask.grid.entity.prefixAssignee": "Prefix Assignee",
"workbench.myFinishedTask.grid.entity.createTime": "Task Create Time"
"workbench.myFinishedTask.grid.action.view": "View"
}

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

@ -190,33 +190,26 @@
"settings.shortcutMenus.entity.shortcutMenuName": "快捷菜單名稱",
"settings.shortcutMenus.entity.menuIconColor": "圖標顏色",
"workbench.grid.entity.processDefinitionName": "流程名稱",
"workbench.grid.entity.businessKey": "業務流水號",
"workbench.grid.entity.businessDescription": "業務描述",
"workbench.grid.entity.custNo": "客戶編號",
"workbench.grid.entity.custName": "客戶名稱",
"workbench.grid.entity.taskType": "任務類型",
"workbench.grid.entity.processStatus": "流程狀態",
"workbench.grid.entity.activityName": "任務節點",
"workbench.grid.entity.previousAssignee": "前一處理人",
"workbench.grid.entity.currentAssignee": "當前處理人",
"workbench.grid.entity.lastAssignee": "最後處理人",
"workbench.grid.entity.startTime": "任務開始時間",
"workbench.grid.entity.endTime": "任務結束時間",
"workbench.myTask.grid.title": "待辦任務",
"workbench.myTask.grid.action.process": "辦理",
"workbench.myTask.grid.entity.businessKey": "業務流水號",
"workbench.myTask.grid.entity.businessDescription": "業務描述",
"workbench.myTask.grid.entity.processDefinitionName": "流程名稱",
"workbench.myTask.grid.entity.activityName": "任務節點",
"workbench.myTask.grid.entity.taskDescription": "任務描述",
"workbench.myTask.grid.entity.prefixAssignee": "前一處理人",
"workbench.myTask.grid.entity.createTime": "任務開始日期",
"workbench.myDoneTask.grid.title": "辦理中任務",
"workbench.myDoneTask.grid.action.view": "查看",
"workbench.myDoneTask.grid.entity.businessKey": "業務流水號",
"workbench.myDoneTask.grid.entity.businessDescription": "業務描述",
"workbench.myDoneTask.grid.entity.processDefinitionName": "流程名稱",
"workbench.myDoneTask.grid.entity.activityName": "任務節點",
"workbench.myDoneTask.grid.entity.taskDescription": "任務描述",
"workbench.myDoneTask.grid.entity.prefixAssignee": "前一處理人",
"workbench.myDoneTask.grid.entity.createTime": "任務開始日期",
"workbench.myFinishedTask.grid.title": "已完成任務",
"workbench.myFinishedTask.grid.action.view": "查看",
"workbench.myFinishedTask.grid.entity.businessKey": "業務流水號",
"workbench.myFinishedTask.grid.entity.businessDescription": "業務描述",
"workbench.myFinishedTask.grid.entity.processDefinitionName": "流程名稱",
"workbench.myFinishedTask.grid.entity.activityName": "任務節點",
"workbench.myFinishedTask.grid.entity.taskDescription": "任務描述",
"workbench.myFinishedTask.grid.entity.prefixAssignee": "前一處理人",
"workbench.myFinishedTask.grid.entity.createTime": "任務開始日期"
"workbench.myFinishedTask.grid.action.view": "查看"
}

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

@ -220,33 +220,26 @@
"settings.shortcutMenus.entity.shortcutMenuName": "快捷菜单名称",
"settings.shortcutMenus.entity.menuIconColor": "图标颜色",
"workbench.grid.entity.processDefinitionName": "流程名称",
"workbench.grid.entity.businessKey": "业务流水号",
"workbench.grid.entity.businessDescription": "业务描述",
"workbench.grid.entity.custNo": "客户编号",
"workbench.grid.entity.custName": "客户名称",
"workbench.grid.entity.taskType": "任务类型",
"workbench.grid.entity.processStatus": "流程状态",
"workbench.grid.entity.activityName": "任务节点",
"workbench.grid.entity.previousAssignee": "前一处理人",
"workbench.grid.entity.currentAssignee": "当前处理人",
"workbench.grid.entity.lastAssignee": "最后处理人",
"workbench.grid.entity.startTime": "任务开始时间",
"workbench.grid.entity.endTime": "任务结束时间",
"workbench.myTask.grid.title": "待办任务",
"workbench.myTask.grid.action.process": "办理",
"workbench.myTask.grid.entity.businessKey": "业务流水号",
"workbench.myTask.grid.entity.businessDescription": "业务描述",
"workbench.myTask.grid.entity.processDefinitionName": "流程名称",
"workbench.myTask.grid.entity.activityName": "任务节点",
"workbench.myTask.grid.entity.taskDescription": "任务描述",
"workbench.myTask.grid.entity.prefixAssignee": "前一处理人",
"workbench.myTask.grid.entity.createTime": "任务开始日期",
"workbench.myDoneTask.grid.title": "办理中任务",
"workbench.myDoneTask.grid.action.view": "查看",
"workbench.myDoneTask.grid.entity.businessKey": "业务流水号",
"workbench.myDoneTask.grid.entity.businessDescription": "业务描述",
"workbench.myDoneTask.grid.entity.processDefinitionName": "流程名称",
"workbench.myDoneTask.grid.entity.activityName": "任务节点",
"workbench.myDoneTask.grid.entity.taskDescription": "任务描述",
"workbench.myDoneTask.grid.entity.prefixAssignee": "前一处理人",
"workbench.myDoneTask.grid.entity.createTime": "任务开始日期",
"workbench.myFinishedTask.grid.title": "已完成任务",
"workbench.myFinishedTask.grid.action.view": "查看",
"workbench.myFinishedTask.grid.entity.businessKey": "业务流水号",
"workbench.myFinishedTask.grid.entity.businessDescription": "业务描述",
"workbench.myFinishedTask.grid.entity.processDefinitionName": "流程名称",
"workbench.myFinishedTask.grid.entity.activityName": "任务节点",
"workbench.myFinishedTask.grid.entity.taskDescription": "任务描述",
"workbench.myFinishedTask.grid.entity.prefixAssignee": "前一处理人",
"workbench.myFinishedTask.grid.entity.createTime": "任务开始日期"
"workbench.myFinishedTask.grid.action.view": "查看"
}

25
io.sc.platform.system.frontend/src/views/parameter/Parameter.vue

@ -104,7 +104,18 @@
label: $t('value'),
type: 'w-text',
showIf: (arg) => {
return !isExistsOptions();
return !isExistsOptions() && !isMultiLineText();
},
},
{
name: 'valueCodeMirror',
label: $t('value'),
type: 'w-code-mirror',
lang: 'json',
toolbar: false,
rows: 10,
showIf: (arg) => {
return !isExistsOptions() && isMultiLineText();
},
},
{
@ -154,6 +165,8 @@
treeGridRef.getEditorForm().setFieldValue('title', t(args.data.code));
if (isExistsOptions()) {
treeGridRef.getEditorForm().setFieldValue('valueSelect', args.data.value);
} else if (isMultiLineText()) {
treeGridRef.getEditorForm().setFieldValue('valueCodeMirror', args.data.value);
} else {
treeGridRef.getEditorForm().setFieldValue('valueInput', args.data.value);
}
@ -163,6 +176,8 @@
(args) => {
if (isExistsOptions()) {
args.data.value = treeGridRef.getEditorForm().getFieldValue('valueSelect');
} else if (isMultiLineText()) {
args.data.value = treeGridRef.getEditorForm().getFieldValue('valueCodeMirror');
} else {
args.data.value = treeGridRef.getEditorForm().getFieldValue('valueInput');
}
@ -198,4 +213,12 @@ const isExistsOptions = () => {
}
return false;
};
const isMultiLineText = () => {
const row = treeGridRef.value.getSelectedRow();
if (row) {
return row.multiLineText ? true : false;
}
return false;
};
</script>

101
io.sc.platform.system.frontend/src/views/workbench/MyDoneTask.vue

@ -5,40 +5,30 @@
:title="$t('workbench.myDoneTask.grid.title')"
:config-button="true"
:checkbox-selection="false"
db-click-operation="edit"
:sort-no="true"
db-click-operation="taskView"
:sort-no="false"
:data-url="Environment.apiContextPath('/api/flowable/process/query/myDoneTask')"
:sort-by="['-createTime']"
:sort-by="['-startTime']"
:query-form-cols-num="4"
:query-form-fields="[
{ name: 'businessKey', label: $t('workbench.myDoneTask.grid.entity.businessKey'), type: 'w-text' },
{
name: 'processDefinitionId',
label: $t('workbench.myDoneTask.grid.entity.processDefinitionName'),
type: 'w-select',
options: processDefinitionsRef,
onUpdateValue: async (args: any) => {
const form = gridRef.getQueryForm();
form.setFieldValue('taskDefinitionKey', undefined);
const field = form.getFields().taskDefinitionKey;
let options = [];
if (args?.value) {
const response = await axios.get(Environment.apiContextPath('/api/flowable/process/findUserTasksByProcessDeployId/' + args.value));
if (response) {
options = response.data;
}
}
field.options = options;
},
name: 'custNo',
label: $t('workbench.grid.entity.custNo'),
type: 'w-text',
rules: [FormValidators.lengthRange(0, 60)],
},
{
name: 'custName',
label: $t('workbench.grid.entity.custName'),
type: 'w-text',
rules: [FormValidators.lengthRange(0, 200)],
},
{
name: 'taskDefinitionKey',
label: $t('workbench.myDoneTask.grid.entity.activityName'),
name: 'processDefinitionKey',
label: $t('workbench.grid.entity.taskType'),
type: 'w-select',
options: [],
queryOperator: 'equals',
options: processDefinitionOptionsRef,
},
{ name: 'description', label: $t('workbench.myDoneTask.grid.entity.taskDescription'), type: 'w-text' },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
@ -52,7 +42,7 @@
},
'separator',
{
name: 'process',
name: 'taskView',
icon: 'bi-caret-right',
label: $t('workbench.myDoneTask.grid.action.view'),
enableIf: (args) => {
@ -64,20 +54,37 @@
},
]"
:columns="[
{ width: 150, name: 'businessKey', label: $t('workbench.myDoneTask.grid.entity.businessKey'), sortable: false },
{ width: '100%', name: 'businessDescription', label: $t('workbench.myDoneTask.grid.entity.businessDescription'), sortable: false },
{
width: 150,
name: 'processDefinitionName',
label: $t('workbench.myDoneTask.grid.entity.processDefinitionName'),
name: 'custNo',
label: $t('workbench.grid.entity.custNo'),
},
{ width: '100%', name: 'custName', label: $t('workbench.grid.entity.custName') },
{
width: 200,
name: 'processDefinitionKey',
label: $t('workbench.grid.entity.taskType'),
format: (value, row) => {
return processDefinitionsRef[value];
},
},
{
width: 100,
name: 'processStatus',
label: $t('workbench.grid.entity.processStatus'),
format: (value, row) => {
return processStatusRef[value];
},
},
{
width: 150,
name: 'assignee',
label: $t('workbench.grid.entity.currentAssignee'),
format: (value, row) => {
return value + '_V' + row.processDefinitionVersion;
return row.assigneeName + '(' + row.assignee + ')';
},
},
{ width: 100, name: 'name', label: $t('workbench.myDoneTask.grid.entity.activityName') },
{ width: 100, name: 'description', label: $t('workbench.myDoneTask.grid.entity.taskDescription') },
{ width: 100, name: 'assignee', label: $t('workbench.myDoneTask.grid.entity.prefixAssignee') },
{ width: 150, name: 'createTime', label: $t('workbench.myDoneTask.grid.entity.createTime') },
{ width: 100, name: 'name', label: $t('workbench.grid.entity.activityName') },
]"
></w-grid>
<div style="width: 0px; height: 0px">
@ -88,11 +95,13 @@
<script setup lang="ts">
import { h, ref, defineAsyncComponent, nextTick } from 'vue';
import { useRouter } from 'vue-router';
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager, Formater } from 'platform-core';
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager, Formater, FormValidators } from 'platform-core';
const router = useRouter();
const gridRef = ref();
const processDefinitionsRef = ref([]);
const processDefinitionOptionsRef = ref([]);
const processDefinitionsRef = ref({});
const processStatusRef = ref({});
const componentRef = ref();
const handle = async (item: any) => {
@ -120,12 +129,20 @@ const refresh = () => {
gridRef.value.refresh();
};
const response = await axios.get(Environment.apiContextPath('/api/flowable/process/findAllDeployedProcessDefines'));
const response = await axios.get(
Environment.apiContextPath('/api/parameter/list?codes=parameter.system.workbench.processDefines&codes=parameter.system.workbench.processStatus'),
);
if (response) {
const processDefinesJson = response?.data['parameter.system.workbench.processDefines'] || '{}';
const processDefines = Tools.json2Object(processDefinesJson);
const options: any[] = [];
for (const item of response.data) {
options.push({ label: item.name, value: item.deployedId });
for (const item in processDefines) {
options.push({ label: $t(processDefines[item]), value: item });
}
processDefinitionsRef.value = options;
processDefinitionsRef.value = processDefines;
processDefinitionOptionsRef.value = options;
const processStatusJson = response?.data['parameter.system.workbench.processStatus'] || '{}';
processStatusRef.value = Tools.json2Object(processStatusJson);
}
</script>

94
io.sc.platform.system.frontend/src/views/workbench/MyFinishedTask.vue

@ -5,40 +5,30 @@
:title="$t('workbench.myFinishedTask.grid.title')"
:config-button="true"
:checkbox-selection="false"
db-click-operation="edit"
:sort-no="true"
db-click-operation="taskView"
:sort-no="false"
:data-url="Environment.apiContextPath('/api/flowable/process/query/myFinishedTask')"
:sort-by="['-createTime']"
:sort-by="['-startTime']"
:query-form-cols-num="4"
:query-form-fields="[
{ name: 'businessKey', label: $t('workbench.myFinishedTask.grid.entity.businessKey'), type: 'w-text' },
{
name: 'processDefinitionId',
label: $t('workbench.myFinishedTask.grid.entity.processDefinitionName'),
type: 'w-select',
options: processDefinitionsRef,
onUpdateValue: async (args: any) => {
const form = gridRef.getQueryForm();
form.setFieldValue('taskDefinitionKey', undefined);
const field = form.getFields().taskDefinitionKey;
let options = [];
if (args?.value) {
const response = await axios.get(Environment.apiContextPath('/api/flowable/process/findUserTasksByProcessDeployId/' + args.value));
if (response) {
options = response.data;
}
}
field.options = options;
},
name: 'custNo',
label: $t('workbench.grid.entity.custNo'),
type: 'w-text',
rules: [FormValidators.lengthRange(0, 60)],
},
{
name: 'custName',
label: $t('workbench.grid.entity.custName'),
type: 'w-text',
rules: [FormValidators.lengthRange(0, 200)],
},
{
name: 'taskDefinitionKey',
label: $t('workbench.myFinishedTask.grid.entity.activityName'),
name: 'processDefinitionKey',
label: $t('workbench.grid.entity.taskType'),
type: 'w-select',
options: [],
queryOperator: 'equals',
options: processDefinitionOptionsRef,
},
{ name: 'description', label: $t('workbench.myFinishedTask.grid.entity.taskDescription'), type: 'w-text' },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
@ -52,7 +42,7 @@
},
'separator',
{
name: 'process',
name: 'taskView',
icon: 'bi-caret-right',
label: $t('workbench.myFinishedTask.grid.action.view'),
enableIf: (args) => {
@ -64,20 +54,30 @@
},
]"
:columns="[
{ width: 150, name: 'businessKey', label: $t('workbench.myFinishedTask.grid.entity.businessKey'), sortable: false },
{ width: '100%', name: 'businessDescription', label: $t('workbench.myFinishedTask.grid.entity.businessDescription'), sortable: false },
{
width: 150,
name: 'processDefinitionName',
label: $t('workbench.myFinishedTask.grid.entity.processDefinitionName'),
name: 'custNo',
label: $t('workbench.grid.entity.custNo'),
},
{ width: '100%', name: 'custName', label: $t('workbench.grid.entity.custName') },
{
width: 200,
name: 'processDefinitionKey',
label: $t('workbench.grid.entity.taskType'),
format: (value, row) => {
return value + '_V' + row.processDefinitionVersion;
return processDefinitionsRef[value];
},
},
{ width: 100, name: 'name', label: $t('workbench.myFinishedTask.grid.entity.activityName') },
{ width: 100, name: 'description', label: $t('workbench.myFinishedTask.grid.entity.taskDescription') },
{ width: 100, name: 'assignee', label: $t('workbench.myFinishedTask.grid.entity.prefixAssignee') },
{ width: 150, name: 'createTime', label: $t('workbench.myFinishedTask.grid.entity.createTime') },
{
width: 100,
name: 'processStatus',
label: $t('workbench.grid.entity.processStatus'),
format: (value, row) => {
return processStatusRef[value];
},
},
{ width: 150, name: 'startTime', label: $t('workbench.grid.entity.startTime') },
{ width: 150, name: 'endTime', label: $t('workbench.grid.entity.endTime') },
]"
></w-grid>
<div style="width: 0px; height: 0px">
@ -88,11 +88,13 @@
<script setup lang="ts">
import { h, ref, defineAsyncComponent, nextTick } from 'vue';
import { useRouter } from 'vue-router';
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager, Formater } from 'platform-core';
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager, Formater, FormValidators, EnumTools } from 'platform-core';
const router = useRouter();
const gridRef = ref();
const processDefinitionsRef = ref([]);
const processDefinitionOptionsRef = ref([]);
const processDefinitionsRef = ref({});
const processStatusRef = ref({});
const componentRef = ref();
const handle = async (item: any) => {
@ -120,12 +122,20 @@ const refresh = () => {
gridRef.value.refresh();
};
const response = await axios.get(Environment.apiContextPath('/api/flowable/process/findAllDeployedProcessDefines'));
const response = await axios.get(
Environment.apiContextPath('/api/parameter/list?codes=parameter.system.workbench.processDefines&codes=parameter.system.workbench.processStatus'),
);
if (response) {
const processDefinesJson = response?.data['parameter.system.workbench.processDefines'] || '{}';
const processDefines = Tools.json2Object(processDefinesJson);
const options: any[] = [];
for (const item of response.data) {
options.push({ label: item.name, value: item.deployedId });
for (const item in processDefines) {
options.push({ label: $t(processDefines[item]), value: item });
}
processDefinitionsRef.value = options;
processDefinitionsRef.value = processDefines;
processDefinitionOptionsRef.value = options;
const processStatusJson = response?.data['parameter.system.workbench.processStatus'] || '{}';
processStatusRef.value = Tools.json2Object(processStatusJson);
}
</script>

99
io.sc.platform.system.frontend/src/views/workbench/MyTask.vue

@ -5,40 +5,30 @@
:title="$t('workbench.myTask.grid.title')"
:config-button="true"
:checkbox-selection="false"
db-click-operation="edit"
:sort-no="true"
db-click-operation="process"
:sort-no="false"
:data-url="Environment.apiContextPath('/api/flowable/process/query/myTask')"
:sort-by="['-createTime']"
:sort-by="['-startTime']"
:query-form-cols-num="4"
:query-form-fields="[
{ name: 'businessKey', label: $t('workbench.myTask.grid.entity.businessKey'), type: 'w-text' },
{
name: 'processDefinitionId',
label: $t('workbench.myTask.grid.entity.processDefinitionName'),
type: 'w-select',
options: processDefinitionsRef,
onUpdateValue: async (args: any) => {
const form = gridRef.getQueryForm();
form.setFieldValue('taskDefinitionKey', undefined);
const field = form.getFields().taskDefinitionKey;
let options = [];
if (args?.value) {
const response = await axios.get(Environment.apiContextPath('/api/flowable/process/findUserTasksByProcessDeployId/' + args.value));
if (response) {
options = response.data;
}
}
field.options = options;
},
name: 'custNo',
label: $t('workbench.grid.entity.custNo'),
type: 'w-text',
rules: [FormValidators.lengthRange(0, 60)],
},
{
name: 'custName',
label: $t('workbench.grid.entity.custName'),
type: 'w-text',
rules: [FormValidators.lengthRange(0, 200)],
},
{
name: 'taskDefinitionKey',
label: $t('workbench.myTask.grid.entity.activityName'),
name: 'processDefinitionKey',
label: $t('workbench.grid.entity.taskType'),
type: 'w-select',
options: [],
queryOperator: 'equals',
options: processDefinitionOptionsRef,
},
{ name: 'description', label: $t('workbench.myTask.grid.entity.taskDescription'), type: 'w-text' },
]"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="[
@ -64,20 +54,37 @@
},
]"
:columns="[
{ width: 150, name: 'businessKey', label: $t('workbench.myTask.grid.entity.businessKey'), sortable: false },
{ width: '100%', name: 'businessDescription', label: $t('workbench.myTask.grid.entity.businessDescription'), sortable: false },
{
width: 150,
name: 'processDefinitionName',
label: $t('workbench.myTask.grid.entity.processDefinitionName'),
name: 'custNo',
label: $t('workbench.grid.entity.custNo'),
},
{ width: '100%', name: 'custName', label: $t('workbench.grid.entity.custName') },
{
width: 200,
name: 'processDefinitionKey',
label: $t('workbench.grid.entity.taskType'),
format: (value, row) => {
return value + '_V' + row.processDefinitionVersion;
return processDefinitionsRef[value];
},
},
{ width: 100, name: 'name', label: $t('workbench.myTask.grid.entity.activityName') },
{ width: 100, name: 'description', label: $t('workbench.myTask.grid.entity.taskDescription') },
{ width: 100, name: 'assignee', label: $t('workbench.myTask.grid.entity.prefixAssignee') },
{ width: 150, name: 'createTime', label: $t('workbench.myTask.grid.entity.createTime') },
{
width: 100,
name: 'processStatus',
label: $t('workbench.grid.entity.processStatus'),
format: (value, row) => {
return processStatusRef[value];
},
},
// {
// width: 150,
// name: 'assignee',
// label: $t('workbench.grid.entity.previousAssignee'),
// format: (value, row) => {
// return row.previousAssigneeName + '(' + row.previousAssignee + ')';
// },
// },
{ width: 150, name: 'startTime', label: $t('workbench.grid.entity.startTime') },
]"
></w-grid>
<div style="width: 0px; height: 0px">
@ -88,11 +95,13 @@
<script setup lang="ts">
import { h, ref, defineAsyncComponent, nextTick } from 'vue';
import { useRouter } from 'vue-router';
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager, Formater } from 'platform-core';
import { $t, axios, Environment, ComponentManager, Tools, NotifyManager, FormValidators } from 'platform-core';
const router = useRouter();
const gridRef = ref();
const processDefinitionsRef = ref([]);
const processDefinitionsRef = ref({});
const processDefinitionOptionsRef = ref([]);
const processStatusRef = ref({});
const componentRef = ref();
const handle = async (item: any) => {
@ -120,12 +129,20 @@ const refresh = () => {
gridRef.value.refresh();
};
const response = await axios.get(Environment.apiContextPath('/api/flowable/process/findAllDeployedProcessDefines'));
const response = await axios.get(
Environment.apiContextPath('/api/parameter/list?codes=parameter.system.workbench.processDefines&codes=parameter.system.workbench.processStatus'),
);
if (response) {
const processDefinesJson = response?.data['parameter.system.workbench.processDefines'] || '{}';
const processDefines = Tools.json2Object(processDefinesJson);
const options: any[] = [];
for (const item of response.data) {
options.push({ label: item.name, value: item.deployedId });
for (const item in processDefines) {
options.push({ label: $t(processDefines[item]), value: item });
}
processDefinitionsRef.value = options;
processDefinitionsRef.value = processDefines;
processDefinitionOptionsRef.value = options;
const processStatusJson = response?.data['parameter.system.workbench.processStatus'] || '{}';
processStatusRef.value = Tools.json2Object(processStatusJson);
}
</script>

1
io.sc.platform.system/src/main/java/io/sc/platform/system/parameter/controller/ParameterWebController.java

@ -68,6 +68,7 @@ public class ParameterWebController extends RestCrudController<ParameterVo, Para
if (parameter.getOptions() != null) {
vo.setOptions(parameter.getOptions());
}
vo.setMultiLineText(parameter.getMultiLineText());
}
}
}

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

@ -1,6 +1,6 @@
{
"name": "io.sc.standard.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -112,7 +113,7 @@
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"pinia-undo": "0.2.4",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

4
io.sc.website/package.json

@ -1,6 +1,6 @@
{
"name": "io.sc.website",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"main": "index.js",
"scripts": {
@ -28,6 +28,6 @@
},
"dependencies": {
"vue": "3.5.13",
"platform-core": "8.2.117"
"platform-core": "8.2.121"
}
}

5
wra.report.frontend/package.json

@ -1,6 +1,6 @@
{
"name": "wra.report.frontend",
"version": "8.2.28",
"version": "8.2.31",
"description": "",
"private": false,
"keywords": [],
@ -102,6 +102,7 @@
"@univerjs/ui": "0.5.4",
"@vueuse/core": "12.4.0",
"axios": "1.8.2",
"bpmn-js": "18.6.2",
"codemirror": "6.0.1",
"dayjs": "1.11.13",
"echarts": "5.6.0",
@ -111,7 +112,7 @@
"mockjs": "1.1.0",
"node-sql-parser": "5.3.6",
"pinia": "2.3.0",
"platform-core": "8.2.117",
"platform-core": "8.2.121",
"quasar": "2.17.6",
"sort-array": "5.0.0",
"svg-path-commander": "2.1.7",

Loading…
Cancel
Save