Browse Source

基础框架发布: 8.2.33

1) 修复首页我的已办的时间显示错误
  2) 增加异步任务功能和数据存储功能

前端核心发布: 8.2.126
 1) 增加异步任务
main
wangshaoping 4 weeks ago
parent
commit
f88e8af5a7
  1. 32
      README.adoc
  2. 4
      cips.frontend/package.json
  3. 4
      erm.frontend/package.json
  4. 4
      gradle.properties
  5. 4
      io.sc.engine.mv.frontend/package.json
  6. 4
      io.sc.engine.rule.frontend/package.json
  7. 2
      io.sc.engine.rule.frontend/src/views/resources/designer/Parameter.vue
  8. 1
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/initializer/RuleEngineWorkFlowInitializer.java
  9. 16
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/controller/ParameterInOptionItemWebController.java
  10. 4
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/ParameterInOptionItemService.java
  11. 10
      io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/impl/ParameterInOptionItemServiceImpl.java
  12. 4
      io.sc.engine.st.frontend/package.json
  13. 4
      io.sc.platform.ai.frontend/package.json
  14. 2
      io.sc.platform.core.frontend/package.json
  15. 11
      io.sc.platform.core.frontend/src/platform/components/grid/ts/toolbar/buttons/Export.ts
  16. 3
      io.sc.platform.core.frontend/src/platform/i18n/messages.json
  17. 3
      io.sc.platform.core.frontend/src/platform/i18n/messages_tw_CN.json
  18. 3
      io.sc.platform.core.frontend/src/platform/i18n/messages_zh_CN.json
  19. 129
      io.sc.platform.core.frontend/src/platform/layout/sub-layout/AsyncTaskDialog.vue
  20. 38
      io.sc.platform.core.frontend/src/platform/layout/sub-layout/Topper.vue
  21. 2
      io.sc.platform.core.frontend/src/platform/views/home/MyDoneTask.vue
  22. 201
      io.sc.platform.core.frontend/src/views/testcase/form/form.vue
  23. 4
      io.sc.platform.core.frontend/template-project/package.json
  24. 201
      io.sc.platform.core.frontend/template-project/src/views/testcase/form/form.vue
  25. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties
  26. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties
  27. 1
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties
  28. 4
      io.sc.platform.developer.doc/package.json
  29. 4
      io.sc.platform.developer.frontend/package.json
  30. 4
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/extension/listener/start/ProcessStartListener.java
  31. 9
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/BusinessKeyAndDescriptionWrapper.java
  32. 1
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/BusinessKeyAndDescriptionWrapperMapper.java
  33. 9
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/ProcessTaskWrapper.java
  34. 1
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/support/ProcessTaskWrapperMapper.java
  35. 1
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/DoneTask.sql
  36. 1
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/FinishedTask.sql
  37. 1
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/MyDoneTasks.sql
  38. 1
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/MyFinishedTasks.sql
  39. 1
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/MyTasks.sql
  40. 1
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/service/impl/sql/Task.sql
  41. 1
      io.sc.platform.flowable/src/main/resources/liquibase/io.sc.platform.flowable_8.0.0_20220606__Process_Manager_Database_Schema_DDL.xml
  42. 4
      io.sc.platform.lcdp.frontend/package.json
  43. 3
      io.sc.platform.lcdp.frontend/src/i18n/messages.json
  44. 3
      io.sc.platform.lcdp.frontend/src/i18n/messages_tw_CN.json
  45. 3
      io.sc.platform.lcdp.frontend/src/i18n/messages_zh_CN.json
  46. 2
      io.sc.platform.lcdp.frontend/src/views/Theme.vue
  47. 1
      io.sc.platform.lcdp.frontend/src/views/bpm/Bpm.vue
  48. 10
      io.sc.platform.lcdp.frontend/src/views/theme/Topper.vue
  49. 3
      io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/api/Topper.java
  50. 4
      io.sc.platform.license.keygen.frontend/package.json
  51. 29
      io.sc.platform.license.keygen/src/main/java/io/sc/platform/license/keygen/controller/LicenseKeyGeneratorWebController.java
  52. 4
      io.sc.platform.mvc.frontend/package.json
  53. 6
      io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/DownloaderController.java
  54. 23
      io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/support/RestCrudController.java
  55. 22
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/DaoService.java
  56. 153
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/impl/DaoServiceImpl.java
  57. 31
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/support/DataExportTemplateConfigure.java
  58. 77
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/support/ExportExcelThread.java
  59. 10
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/storage/service/StorageService.java
  60. 107
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/storage/service/impl/StorageServiceImpl.java
  61. 31
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/ExportTask.java
  62. 171
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/Task.java
  63. 6
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/TaskExecuteMode.java
  64. 11
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/TaskStatus.java
  65. 8
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/TaskType.java
  66. 14
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/service/TaskService.java
  67. 99
      io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/service/impl/TaskServiceImpl.java
  68. 4
      io.sc.platform.orm/src/main/resources/META-INF/platform/plugins/components.json
  69. 6
      io.sc.platform.orm/src/main/resources/META-INF/platform/plugins/messages.json
  70. 22
      io.sc.platform.orm/src/main/resources/META-INF/platform/plugins/parameters.json
  71. 2
      io.sc.platform.orm/src/main/resources/io/sc/platform/orm/i18n/parameter.properties
  72. 2
      io.sc.platform.orm/src/main/resources/io/sc/platform/orm/i18n/parameter_tw_CN.properties
  73. 2
      io.sc.platform.orm/src/main/resources/io/sc/platform/orm/i18n/parameter_zh_CN.properties
  74. 9
      io.sc.platform.orm/src/main/resources/io/sc/platform/orm/task/i18n/task.properties
  75. 9
      io.sc.platform.orm/src/main/resources/io/sc/platform/orm/task/i18n/task_tw_CN.properties
  76. 9
      io.sc.platform.orm/src/main/resources/io/sc/platform/orm/task/i18n/task_zh_CN.properties
  77. 4
      io.sc.platform.scheduler.manager.frontend/package.json
  78. 3
      io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/menu/MenuGroupVo.java
  79. 24
      io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/storage/DatabaseStorageVo.java
  80. 4
      io.sc.platform.system.frontend/package.json
  81. 2
      io.sc.platform.system.frontend/src/components/index.ts
  82. 6
      io.sc.platform.system.frontend/src/i18n/messages.json
  83. 28
      io.sc.platform.system.frontend/src/i18n/messages_tw_CN.json
  84. 6
      io.sc.platform.system.frontend/src/i18n/messages_zh_CN.json
  85. 6
      io.sc.platform.system.frontend/src/menus/menus.json
  86. 13
      io.sc.platform.system.frontend/src/routes/routes.json
  87. 45
      io.sc.platform.system.frontend/src/views/task/Task.vue
  88. 1
      io.sc.platform.system.frontend/src/views/workbench/MyDoneTask.vue
  89. 1
      io.sc.platform.system.frontend/src/views/workbench/MyFinishedTask.vue
  90. 1
      io.sc.platform.system.frontend/src/views/workbench/MyTask.vue
  91. 15
      io.sc.platform.system/src/main/java/io/sc/platform/system/storage/controller/DatabaseStorageWebController.java
  92. 49
      io.sc.platform.system/src/main/java/io/sc/platform/system/storage/jpa/entity/DatabaseStorageEntity.java
  93. 10
      io.sc.platform.system/src/main/java/io/sc/platform/system/storage/jpa/repository/DatabaseStorageRepository.java
  94. 9
      io.sc.platform.system/src/main/java/io/sc/platform/system/storage/service/DatabaseStorageService.java
  95. 12
      io.sc.platform.system/src/main/java/io/sc/platform/system/storage/service/impl/DatabaseStorageServiceImpl.java
  96. 25
      io.sc.platform.system/src/main/java/io/sc/platform/system/task/controller/TaskWebController.java
  97. 17
      io.sc.platform.system/src/main/java/io/sc/platform/system/task/jpa/entity/EmptyTaskEntity.java
  98. 57
      io.sc.platform.system/src/main/java/io/sc/platform/system/task/jpa/entity/ExportTaskEntity.java
  99. 249
      io.sc.platform.system/src/main/java/io/sc/platform/system/task/jpa/entity/TaskEntity.java
  100. 10
      io.sc.platform.system/src/main/java/io/sc/platform/system/task/jpa/repository/TaskRepository.java

32
README.adoc

@ -13,3 +13,35 @@ ALTER TABLE RE_MODEL_PARAMETER_ADDITION ADD MAX_VALUE_ varchar(255) NULL COMMENT
2. 给 RE_MODEL_PARAMETER 表增加字段 2. 给 RE_MODEL_PARAMETER 表增加字段
ALTER TABLE RE_MODEL_PARAMETER ADD DISABLE_ON_AUTO_SELECTED_ SMALLINT NULL COMMENT '当系统自动选择了输入选项中某一项时, 是否禁止用户选择其他项'; ALTER TABLE RE_MODEL_PARAMETER ADD DISABLE_ON_AUTO_SELECTED_ SMALLINT NULL COMMENT '当系统自动选择了输入选项中某一项时, 是否禁止用户选择其他项';
3. 创建 SYS_TASK 表
CREATE TABLE SYS_TASK (
`ID_` varchar(36) NOT NULL COMMENT 'ID',
`TYPE_` varchar(20) NOT NULL,
`EXECUTE_MODE_` varchar(20) DEFAULT NULL COMMENT '执行模式(SYNCHRONOUS:同步; ASYNCHRONOUS:异步)',
`STATUS_` varchar(20) DEFAULT NULL COMMENT '状态(CREATED:已创建; STARTED:已启动; COMPLETED:已完成; CANCELED:已取消; EXCEPTIONED:发生错误)',
`NAME_` varchar(255) DEFAULT NULL COMMENT '名称',
`CREATOR_` varchar(255) DEFAULT NULL COMMENT '创建人',
`CREATE_DATE_` datetime DEFAULT NULL COMMENT '创建日期',
`COMPLETED_DATE_` datetime DEFAULT NULL COMMENT '完成日期',
`CANCELED_DATE_` datetime DEFAULT NULL COMMENT '取消日期',
`TOTAL_WEIGHT_` int DEFAULT NULL COMMENT '总计需要执行的数量',
`CURRENT_WEIGHT_` int DEFAULT NULL COMMENT '当前已经执行的数量',
`MESSAGE_` varchar(255) DEFAULT NULL COMMENT '执行进度消息',
`EXCEPTION_` varchar(255) DEFAULT NULL COMMENT '执行抛出的违例类名称',
`EXCEPTION_MESSAGE_` varchar(1024) DEFAULT NULL COMMENT '执行抛出的违例消息',
`EXCEPTION_STACK_TRACE_` longtext COMMENT '执行抛出的违例栈',
`EXPORT_RESOURCE_NAME_` varchar(255) DEFAULT NULL COMMENT '导出资源名称',
`EXPORT_RESOURCE_URL_` varchar(1024) DEFAULT NULL COMMENT '导出资源URL',
PRIMARY KEY (`ID_`),
KEY `IDX_SYS_TASK_CREATOR` (`CREATOR_`)
) ENGINE=InnoDB DEFAULT COMMENT='任务表';
4. 创建 SYS_STORAGE 表
CREATE TABLE SYS_STORAGE (
`ID_` varchar(36) NOT NULL COMMENT 'ID',
`PATH_` varchar(1024) DEFAULT NULL COMMENT '资源路径',
`BYTES_` blob COMMENT '数据文件二进制',
PRIMARY KEY (`ID_`),
KEY `IDX_SYS_STORAGE_PATH` (`PATH_`)
) ENGINE=InnoDB DEFAULT COMMENT='持久化存储表';

4
cips.frontend/package.json

@ -1,6 +1,6 @@
{ {
"name": "cips.frontend", "name": "cips.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -113,7 +113,7 @@
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"pinia-undo": "0.2.4", "pinia-undo": "0.2.4",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

4
erm.frontend/package.json

@ -1,6 +1,6 @@
{ {
"name": "erm.frontend", "name": "erm.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -113,7 +113,7 @@
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"pinia-undo": "0.2.4", "pinia-undo": "0.2.4",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

4
gradle.properties

@ -37,9 +37,9 @@ application_version=1.0.0
# platform # platform
########################################################### ###########################################################
platform_group=io.sc platform_group=io.sc
platform_version=8.2.32 platform_version=8.2.33
platform_plugin_version=8.2.10 platform_plugin_version=8.2.10
platform_core_frontend_version=8.2.123 platform_core_frontend_version=8.2.126
########################################################### ###########################################################
# dependencies version # dependencies version

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.engine.mv.frontend", "name": "io.sc.engine.mv.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -113,7 +113,7 @@
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"pinia-undo": "0.2.4", "pinia-undo": "0.2.4",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.engine.rule.frontend", "name": "io.sc.engine.rule.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -113,7 +113,7 @@
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"pinia-undo": "0.2.4", "pinia-undo": "0.2.4",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

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

@ -518,8 +518,6 @@
}, },
onBeforeEditorDataSubmit: (args) => { onBeforeEditorDataSubmit: (args) => {
args.callback(normalize(args.data)); args.callback(normalize(args.data));
// console.log(args);
// Tools.mergeObject(args.data, normalize(args.data));
}, },
}, },
], ],

1
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/common/initializer/RuleEngineWorkFlowInitializer.java

@ -61,6 +61,7 @@ public class RuleEngineWorkFlowInitializer implements ApplicationInitializer{
entity.setBusinessDescriptionSql( entity.setBusinessDescriptionSql(
"select\n" + "select\n" +
" CONCAT(CODE_,':',VERSION_) BUSINESS_KEY,\n" + " CONCAT(CODE_,':',VERSION_) BUSINESS_KEY,\n" +
" NULL BUSINESS_TYPE,\n" +
" NAME_ CUST_NO,\n" + " NAME_ CUST_NO,\n" +
" CONCAT('V',VERSION_) CUST_NAME,\n" + " CONCAT('V',VERSION_) CUST_NAME,\n" +
" NULL PROCESS_STATUS\n" + " NULL PROCESS_STATUS\n" +

16
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/controller/ParameterInOptionItemWebController.java

@ -4,19 +4,17 @@ import io.sc.engine.rule.server.model.entity.ParameterInOptionItemEntity;
import io.sc.engine.rule.server.model.repository.ParameterInOptionItemRepository; import io.sc.engine.rule.server.model.repository.ParameterInOptionItemRepository;
import io.sc.engine.rule.server.model.service.ParameterInOptionItemService; import io.sc.engine.rule.server.model.service.ParameterInOptionItemService;
import io.sc.engine.rule.server.model.vo.ParameterInOptionItemVo; import io.sc.engine.rule.server.model.vo.ParameterInOptionItemVo;
import io.sc.engine.rule.server.model.vo.ParameterValidatorVo;
import io.sc.platform.mvc.controller.support.RestCrudController; import io.sc.platform.mvc.controller.support.RestCrudController;
import io.sc.platform.orm.service.support.QueryParameter; import io.sc.platform.orm.service.support.QueryParameter;
import io.sc.platform.orm.service.support.QueryResult; import io.sc.platform.orm.service.support.QueryResult;
import io.sc.platform.orm.util.EntityVoUtil;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.management.Query; import java.util.Locale;
import java.util.Collections;
import java.util.List;
/** /**
* 模型参数选项 Controller * 模型参数选项 Controller
@ -25,10 +23,10 @@ import java.util.List;
@RequestMapping("/api/re/model/parameter/option") @RequestMapping("/api/re/model/parameter/option")
public class ParameterInOptionItemWebController extends RestCrudController<ParameterInOptionItemVo,ParameterInOptionItemEntity,String,ParameterInOptionItemRepository,ParameterInOptionItemService> { public class ParameterInOptionItemWebController extends RestCrudController<ParameterInOptionItemVo,ParameterInOptionItemEntity,String,ParameterInOptionItemRepository,ParameterInOptionItemService> {
@GetMapping("findByParameterId") @GetMapping("findByParameterId")
public Page<ParameterInOptionItemVo> findByParameterId(@RequestParam(name="parameterId",required = false)String parameterId, QueryParameter queryParameter) throws Exception { public Page<ParameterInOptionItemVo> findByParameterId(@RequestParam(name="parameterId",required = false)String parameterId, QueryParameter queryParameter, Locale locale) throws Exception {
if(!StringUtils.hasText(parameterId)){ if(!StringUtils.hasText(parameterId)){
return QueryResult.emptyPage(); return QueryResult.emptyPage();
} }
return service.findByParameterId(parameterId, queryParameter); return service.findByParameterId(parameterId, queryParameter,locale);
} }
} }

4
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/ParameterInOptionItemService.java

@ -8,6 +8,7 @@ import io.sc.platform.orm.service.support.QueryParameter;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import java.util.List; import java.util.List;
import java.util.Locale;
/** /**
* 输入参数选项服务接口 * 输入参数选项服务接口
@ -17,8 +18,9 @@ public interface ParameterInOptionItemService extends DaoService<ParameterInOpti
* 通过参数ID查找选项 * 通过参数ID查找选项
* @param parameterId 参数ID * @param parameterId 参数ID
* @param queryParameter 查询参数 * @param queryParameter 查询参数
* @param locale 区域
* @return 选项列表 * @return 选项列表
* @throws Exception 违例 * @throws Exception 违例
*/ */
public Page<ParameterInOptionItemVo> findByParameterId(String parameterId, QueryParameter queryParameter) throws Exception; public Page<ParameterInOptionItemVo> findByParameterId(String parameterId, QueryParameter queryParameter,Locale locale) throws Exception;
} }

10
io.sc.engine.rule.server/src/main/java/io/sc/engine/rule/server/model/service/impl/ParameterInOptionItemServiceImpl.java

@ -40,13 +40,19 @@ public class ParameterInOptionItemServiceImpl extends DaoServiceImpl<ParameterIn
@Autowired private ParameterAndValueTypeService parameterAndValueTypeService; @Autowired private ParameterAndValueTypeService parameterAndValueTypeService;
@Override @Override
public Page<ParameterInOptionItemVo> findByParameterId(String parameterId, QueryParameter queryParameter) throws Exception { public Page<ParameterInOptionItemVo> findByParameterId(String parameterId, QueryParameter queryParameter,Locale locale) throws Exception {
Equals equalsCriteria =new Equals(); Equals equalsCriteria =new Equals();
equalsCriteria.setFieldName("parameter"); equalsCriteria.setFieldName("parameter");
equalsCriteria.setValue(parameterId); equalsCriteria.setValue(parameterId);
queryParameter.addCriteria(equalsCriteria); queryParameter.addCriteria(equalsCriteria);
return EntityVoUtil.toVo(super.query(queryParameter));
Page<ParameterInOptionItemEntity> page =super.query(queryParameter);
if(page.getContent()!=null && !page.getContent().isEmpty()){
ParameterAndValueType parameterAndValueType =parameterAndValueTypeService.findByParameterId(parameterId,locale);
VariableCodeAndNameReplacer.replace(page.getContent(),parameterAndValueType, ReplaceMode.CODE_TO_NAME);
}
return EntityVoUtil.toVo(page);
} }
@Override @Override

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.engine.st.frontend", "name": "io.sc.engine.st.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -113,7 +113,7 @@
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"pinia-undo": "0.2.4", "pinia-undo": "0.2.4",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.ai.frontend", "name": "io.sc.platform.ai.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -113,7 +113,7 @@
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"pinia-undo": "0.2.4", "pinia-undo": "0.2.4",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

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

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

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

@ -1,4 +1,4 @@
import { $t, axios, Downloader, Tools } from '@/platform'; import { $t, axios, Environment, Downloader, Tools } from '@/platform';
import { PropsType, TableType } from '../../index'; import { PropsType, TableType } from '../../index';
import { Button } from '../Button'; import { Button } from '../Button';
@ -20,7 +20,14 @@ export class Export extends Button {
if (!Tools.isEmpty(this.tools?.props.title)) { if (!Tools.isEmpty(this.tools?.props.title)) {
url = url + '?downloadFileName=' + encodeURIComponent(this.tools?.props.title); url = url + '?downloadFileName=' + encodeURIComponent(this.tools?.props.title);
} }
Downloader.get(url, { params: urlSearchParams }); axios.get(url, { params: urlSearchParams }).then((response) => {
const task = response.data;
if (task && task.executeMode === 'ASYNCHRONOUS') {
Environment.executeAction('openAsyncTaskDialog');
} else {
Downloader.get(Environment.apiContextPath(task.exportResourceUrl));
}
});
} }
getButtonConfig() { getButtonConfig() {

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

@ -18,6 +18,9 @@
"collapseSiderMenu": "Collapse Sider Menu", "collapseSiderMenu": "Collapse Sider Menu",
"confirm": "Confirm", "confirm": "Confirm",
"expandSiderMenu": "Expand Sider Menu", "expandSiderMenu": "Expand Sider Menu",
"asyncTasks": "Async Tasks",
"cleanAsyncTasksTip": "Are you sure to clean the task list?",
"removeAsyncTaskTip": "Are you sure to remove the task?",
"fullScreen": "Full Screen", "fullScreen": "Full Screen",
"fullScreenExit": "Exit Full Screen", "fullScreenExit": "Exit Full Screen",
"help": "Help", "help": "Help",

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

@ -18,6 +18,9 @@
"collapseSiderMenu": "收起邊欄菜單", "collapseSiderMenu": "收起邊欄菜單",
"confirm": "確定", "confirm": "確定",
"expandSiderMenu": "展開邊欄菜單", "expandSiderMenu": "展開邊欄菜單",
"asyncTasks": "異步任務",
"cleanAsyncTasksTip": "您確定要清空異步任務列表?",
"removeAsyncTaskTip": "您確定要刪除該異步任務?",
"fullScreen": "全屏", "fullScreen": "全屏",
"fullScreenExit": "退出全屏", "fullScreenExit": "退出全屏",
"help": "幫助", "help": "幫助",

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

@ -18,6 +18,9 @@
"collapseSiderMenu": "收起边栏菜单", "collapseSiderMenu": "收起边栏菜单",
"confirm": "确定", "confirm": "确定",
"expandSiderMenu": "展开边栏菜单", "expandSiderMenu": "展开边栏菜单",
"asyncTasks": "异步任务",
"cleanAsyncTasksTip": "您确定要清空异步任务列表?",
"removeAsyncTaskTip": "您确定要删除该异步任务?",
"fullScreen": "全屏", "fullScreen": "全屏",
"fullScreenExit": "退出全屏", "fullScreenExit": "退出全屏",
"help": "帮助", "help": "帮助",

129
io.sc.platform.core.frontend/src/platform/layout/sub-layout/AsyncTaskDialog.vue

@ -0,0 +1,129 @@
<template>
<q-dialog ref="seamlessDialogRef" v-model="show" seamless position="top" @before-show="onShow" @hide="onHide">
<q-card style="width: 600px">
<q-toolbar class="bg-secondary text-white" style="height: 20px">
<q-toolbar-title class="text-subtitle2">{{ $t('asyncTasks') }}</q-toolbar-title>
<q-space />
<q-btn flat round icon="delete_outline" size="sm" @click="clean">
<q-tooltip :delay="1000">{{ $t('clean') }}</q-tooltip>
</q-btn>
<q-btn v-close-popup flat round icon="close" size="sm">
<q-tooltip :delay="1000">{{ $t('close') }}</q-tooltip>
</q-btn>
</q-toolbar>
<q-card-section v-for="task in tasksRef" :key="task.id" class="row items-center no-wrap" style="padding: 4px 10px 4px 10px">
<q-icon v-if="task.status === 'COMPLETED'" name="check_circle_outline" size="26px" color="green" class="cursor-pointer">
<q-tooltip :delay="1000">{{ $t('io.sc.platform.system.enums.TaskStatus.COMPLETED') }}</q-tooltip>
</q-icon>
<q-icon v-if="task.status === 'CANCELED'" name="pause_circle_outline" size="26px" color="orange" class="cursor-pointer">
<q-tooltip :delay="1000">{{ $t('io.sc.platform.system.enums.TaskStatus.CANCELED') }}</q-tooltip>
</q-icon>
<q-icon v-if="task.status === 'ERROR'" name="error_outline" size="26px" color="red" class="cursor-pointer">
<q-tooltip :delay="1000">
{{ $t('io.sc.platform.system.enums.TaskStatus.ERROR') + '!' }} <br />
{{ task.exception ? $t('task.exception') : task.exceptionMessage }} <br />
</q-tooltip>
</q-icon>
<div>
<q-knob
v-if="task.status === 'STARTED'"
:model-value="(100 * task.currentWeight) / task.totalWeight"
show-value
size="26px"
:thickness="0.3"
color="green"
track-color="grey-5"
>
</q-knob>
<q-tooltip :delay="1000">{{ $t('running') + ' : ' + (100 * task.currentWeight) / task.totalWeight + ' %' }}</q-tooltip>
</div>
<div class="pl-2">
<a v-if="task.status === 'COMPLETED'" href="javascript:void(0);" class="text-primary underline" @click="handle(task)">
<div class="truncate" style="width: 350px; max-width: 350px">{{ task.name }}</div>
</a>
<div v-if="task.status !== 'COMPLETED'" class="truncate" style="width: 350px; max-width: 350px">{{ task.name }}</div>
<div v-if="task.status === 'STARTED'" class="truncate" style="width: 350px; max-width: 350px; font-size: 0.8em">{{ task.message }}</div>
<div v-if="task.status === 'ERROR'" class="truncate text-red-500" style="width: 350px; max-width: 350px; font-size: 0.8em">
{{ task.exception ? $t(task.exception) : task.exceptionMessage }}
</div>
</div>
<q-space />
<!-- 创建日期 -->
<div class="truncate" style="width: 70px; max-width: 70px; font-size: 0.8em">
{{ task.createDateAndNowDiff + $t(task.createDateAndNowDiffUnit) + $t('before') }}
<q-tooltip :delay="1000">{{ task.createDate }}</q-tooltip>
</div>
<q-btn v-if="task.status === 'STARTED'" flat round icon="pause" color="primary" size="sm">
<q-tooltip :delay="1000">{{ $t('cancel') }}</q-tooltip>
</q-btn>
<q-btn v-if="task.status !== 'STARTED'" flat round icon="delete_outline" color="primary" size="sm" @click="remove(task)">
<q-tooltip :delay="1000">{{ $t('remove') }}</q-tooltip>
</q-btn>
</q-card-section>
</q-card>
</q-dialog>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useInterval } from 'quasar';
import { $t, axios, Environment, DialogManager, Downloader } from '@/platform';
const { registerInterval, removeInterval } = useInterval();
const seamlessDialogRef = ref();
const show = ref(false);
const tasksRef = ref([]);
const open = () => {
show.value = true;
};
const close = () => {
seamlessDialogRef.value.hide();
};
const onShow = () => {
refresh();
registerInterval(refresh, 2000);
};
const onHide = () => {
removeInterval();
};
const clean = () => {
DialogManager.confirm($t('cleanAsyncTasksTip'), () => {
axios.post(Environment.apiContextPath('/api/system/task/cleanMyAsyncTaskList')).then((response) => {
refresh();
});
});
};
const remove = (task) => {
DialogManager.confirm($t('removeAsyncTaskTip'), () => {
axios.post(Environment.apiContextPath('/api/system/task/removeAsyncTask/' + task.id)).then((response) => {
refresh();
});
});
};
const refresh = () => {
console.log('refresh');
axios.get(Environment.apiContextPath('/api/system/task?page=1&size=10&pageable=true&sortBy=-createDate')).then((response) => {
tasksRef.value = response.data.content;
});
};
const handle = (task: any) => {
if (task.type === 'EXPORT') {
Downloader.get(Environment.apiContextPath(task.exportResourceUrl));
}
};
defineExpose({
open,
close,
});
</script>

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

@ -32,16 +32,8 @@
<q-btn v-if="gc.theme.topper.actions['ai-chat'].enable" stretch flat icon="bi-chat-dots" :title="t('aiChat')" :to="{ name: 'route.ai.chatNoMenuRoute' }"> <q-btn v-if="gc.theme.topper.actions['ai-chat'].enable" stretch flat icon="bi-chat-dots" :title="t('aiChat')" :to="{ name: 'route.ai.chatNoMenuRoute' }">
</q-btn> </q-btn>
<!-- fullscreen action --> <!-- asyncTaskDialog -->
<q-btn <q-btn v-if="gc.theme.topper.actions['async-task'].enable" stretch flat icon="bi-clock-history" :title="t('asyncTasks')" @click="openAsyncTaskDialog">
v-if="gc.theme.topper.actions['full-screen'].enable"
stretch
flat
size="md"
:icon="quasar.fullscreen.isActive ? 'bi-fullscreen-exit' : 'bi-fullscreen'"
:title="quasar.fullscreen.isActive ? t('fullScreenExit') : t('fullScreen')"
@click="fullScreen"
>
</q-btn> </q-btn>
<!-- messages dropdown action--> <!-- messages dropdown action-->
@ -138,6 +130,18 @@
</q-popup-proxy> </q-popup-proxy>
</q-btn> </q-btn>
<!-- fullscreen action -->
<q-btn
v-if="gc.theme.topper.actions['full-screen'].enable"
stretch
flat
size="md"
:icon="quasar.fullscreen.isActive ? 'bi-fullscreen-exit' : 'bi-fullscreen'"
:title="quasar.fullscreen.isActive ? t('fullScreenExit') : t('fullScreen')"
@click="fullScreen"
>
</q-btn>
<!-- profile dropdown action--> <!-- profile dropdown action-->
<q-btn stretch flat no-caps stack> <q-btn stretch flat no-caps stack>
<div class="row items-center no-wrap"> <div class="row items-center no-wrap">
@ -247,7 +251,8 @@
<ChangeRoleDialog ref="changeRoleDialog"></ChangeRoleDialog> <ChangeRoleDialog ref="changeRoleDialog"></ChangeRoleDialog>
<UserMessageDialog ref="userMessageDialogRef" @close="findUnReadedNotifications"></UserMessageDialog> <UserMessageDialog ref="userMessageDialogRef" @close="findUnReadedNotifications"></UserMessageDialog>
<SystemMessageDialog ref="systemMessageDialogRef" @close="findUnReadedNotifications"></SystemMessageDialog> <SystemMessageDialog ref="systemMessageDialogRef" @close="findUnReadedNotifications"></SystemMessageDialog>
<AnnouncementDialog ref="announcementDialogDialogRef" @close="findUnReadedAnnouncements"></AnnouncementDialog> <AnnouncementDialog ref="announcementDialogRef" @close="findUnReadedAnnouncements"></AnnouncementDialog>
<AsyncTaskDialog ref="asyncTaskDialogRef"></AsyncTaskDialog>
<div style="width: 0px; height: 0px"> <div style="width: 0px; height: 0px">
<component :is="componentRef" style="width: 1px; height: 1px"></component> <component :is="componentRef" style="width: 1px; height: 1px"></component>
</div> </div>
@ -278,6 +283,7 @@ import ChangeRoleDialog from './ChangeRoleDialog.vue';
import UserMessageDialog from '@/platform/views/home/UserMessageDialog.vue'; import UserMessageDialog from '@/platform/views/home/UserMessageDialog.vue';
import SystemMessageDialog from '@/platform/views/home/SystemMessageDialog.vue'; import SystemMessageDialog from '@/platform/views/home/SystemMessageDialog.vue';
import AnnouncementDialog from '@/platform/views/home/AnnouncementDialog.vue'; import AnnouncementDialog from '@/platform/views/home/AnnouncementDialog.vue';
import AsyncTaskDialog from './AsyncTaskDialog.vue';
const { registerInterval } = useInterval(); const { registerInterval } = useInterval();
const gc = Environment.getConfigure(); const gc = Environment.getConfigure();
@ -290,7 +296,8 @@ const changePasswordDialog = ref();
const changeRoleDialog = ref(); const changeRoleDialog = ref();
const userMessageDialogRef = ref(); const userMessageDialogRef = ref();
const systemMessageDialogRef = ref(); const systemMessageDialogRef = ref();
const announcementDialogDialogRef = ref(); const announcementDialogRef = ref();
const asyncTaskDialogRef = ref();
const { t } = useI18n(); const { t } = useI18n();
const componentRef = ref(); const componentRef = ref();
const unCompletedTasksRef = ref([]); const unCompletedTasksRef = ref([]);
@ -333,6 +340,10 @@ const about = () => {
aboutDialog.value.open(); aboutDialog.value.open();
}; };
const openAsyncTaskDialog = () => {
asyncTaskDialogRef.value.open();
};
const changePassword = () => { const changePassword = () => {
changePasswordDialog.value.open(); changePasswordDialog.value.open();
}; };
@ -489,10 +500,11 @@ const handleMessage = (item: any) => {
}; };
const handleAnnouncement = (item) => { const handleAnnouncement = (item) => {
announcementDialogDialogRef.value.open(item); announcementDialogRef.value.open(item);
}; };
Environment.registAction('about', about); Environment.registAction('about', about);
Environment.registAction('openAsyncTaskDialog', openAsyncTaskDialog);
Environment.registAction('changePassword', changePassword); Environment.registAction('changePassword', changePassword);
Environment.registAction('changeRole', changeRole); Environment.registAction('changeRole', changeRole);
Environment.registAction('openLoginDialog', openLoginDialog); Environment.registAction('openLoginDialog', openLoginDialog);

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

@ -45,7 +45,7 @@
</td> </td>
<td width="78px" style="font-size: 0.8em; padding: 0px 4px" align="right"> <td width="78px" style="font-size: 0.8em; padding: 0px 4px" align="right">
<div class="truncate" style="width: 70px; max-width: 70px"> <div class="truncate" style="width: 70px; max-width: 70px">
{{ $t(item.startTimeAndNowDiffUnit) + $t('before') }} {{ item.startTimeAndNowDiff + $t(item.startTimeAndNowDiffUnit) + $t('before') }}
</div> </div>
<q-tooltip :delay="1000">{{ item.startTime }}</q-tooltip> <q-tooltip :delay="1000">{{ item.startTime }}</q-tooltip>
</td> </td>

201
io.sc.platform.core.frontend/src/views/testcase/form/form.vue

@ -1,49 +1,46 @@
<template> <template>
<q-splitter :model-value="60" class="w-full" style="height: 100%">
<template #before>
<div class="pr-1" style="height: 100%">
<w-grid <w-grid
ref="roleGridRef" ref="userGridRef"
:title="$t('system.role.grid.title')" :title="$t('system.user.grid.title')"
:config-button="true" :config-button="true"
selection="multiple" selection="multiple"
db-click-operation="edit"
:checkbox-selection="true" :checkbox-selection="true"
:data-url="Environment.apiContextPath('/api/system/role')" :data-url="Environment.apiContextPath('/api/system/user')"
:sort-by="['name']" :sort-by="['loginName']"
:query-form-cols-num="3" :query-form-cols-num="3"
:query-form-fields="[ :query-form-fields="[
{ name: 'code', label: $t('code'), type: 'w-text' }, { name: 'loginName', label: $t('loginName'), type: 'w-text' },
{ name: 'name', label: $t('name'), type: 'w-text' }, { name: 'userName', label: $t('userName'), type: 'w-text' },
{ name: 'enable', label: $t('isEnable'), type: 'w-select', options: Options.yesNo() }, { name: 'enable', label: $t('isEnable'), type: 'w-select', options: Options.yesNo(), queryOperator: 'equals' },
]" ]"
:toolbar-configure="{ noIcon: false }" :toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view', 'separator', 'export']" :toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view', 'separator', 'export']"
:columns="[ :columns="[
{ width: 150, name: 'code', label: $t('code') }, { width: 200, name: 'loginName', label: $t('loginName') },
{ width: '100%', name: 'name', label: $t('name') }, { width: '100%', name: 'userName', label: $t('userName') },
{ width: 80, name: 'enable', label: $t('status'), format: Formater.enableTag() },
{ width: 100, name: 'corporationCode', label: $t('corporation'), hidden: !SessionManager.isPrimaryCorporation() },
{ width: 120, name: 'lastModifier', label: $t('lastModifier') },
{ width: 120, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
]" ]"
:editor="{ :editor="{
dialog: { dialog: {
width: '600px', width: '800px',
}, },
form: { form: {
colsNum: 1, colsNum: 4,
fields: [ fields: [
{ name: 'code', label: $t('code'), type: 'w-text', required: true }, { name: 'loginName', label: $t('loginName'), type: 'w-text', requiredIf: true, colSpan: 2 },
{ name: 'name', label: $t('name'), type: 'w-text', required: true }, { name: 'userName', label: $t('userName'), type: 'w-text', requiredIf: true, colSpan: 2 },
{ name: 'description', label: $t('description'), type: 'w-textarea', rows: 1 }, { name: 'description', label: $t('description'), type: 'w-textarea', rows: 1, colSpan: 2 },
{ name: 'enable', label: $t('enable'), type: 'w-checkbox', defaultValue: true }, { name: 'password', label: $t('password'), type: 'w-password', colSpan: 2 },
{ { name: 'mobile', label: $t('mobile'), type: 'w-text', colSpan: 2 },
name: 'corporationCode', { name: 'phone', label: $t('phone'), type: 'w-text', colSpan: 2 },
label: $t('corporation'), { name: 'email', label: $t('email'), type: 'w-text', colSpan: 2 },
type: 'tree-select', { name: 'weixin', label: $t('weixin'), type: 'w-text', colSpan: 2 },
options: optionRef, { name: 'qq', label: $t('qq'), type: 'w-text', colSpan: 2 },
required: true,
}, { name: 'enable', label: $t('enable'), type: 'w-checkbox', defaultValue: true, colsFirst: true },
{ name: 'accountExpired', label: $t('accountExpired'), type: 'w-checkbox', defaultValue: false },
{ name: 'accountLocked', label: $t('accountLocked'), type: 'w-checkbox', defaultValue: false },
{ name: 'credentialsExpired', label: $t('credentialsExpired'), type: 'w-checkbox', defaultValue: false },
], ],
}, },
}" }"
@ -52,10 +49,18 @@
columnNum: 1, columnNum: 1,
fields: [ fields: [
{ name: 'id', label: $t('id') }, { name: 'id', label: $t('id') },
{ name: 'code', label: $t('code') }, { name: 'loginName', label: $t('loginName') },
{ name: 'name', label: $t('name') }, { name: 'userName', label: $t('userName') },
{ name: 'description', label: $t('description') }, { name: 'description', label: $t('description') },
{ name: 'enable', label: $t('enable'), format: Formater.none() }, { name: 'enable', label: $t('enable'), format: Formater.none() },
{ name: 'accountExpired', label: $t('accountExpired') },
{ name: 'accountLocked', label: $t('accountLocked') },
{ name: 'credentialsExpired', label: $t('credentialsExpired') },
{ name: 'email', label: $t('email') },
{ name: 'phone', label: $t('phone') },
{ name: 'mobile', label: $t('mobile') },
{ name: 'weixin', label: $t('weixin') },
{ name: 'qq', label: $t('qq') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') }, { name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') }, { name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') }, { name: 'createDate', label: $t('createDate') },
@ -65,144 +70,14 @@
], ],
}, },
}" }"
@row-click=" ></w-grid>
(evt, row, index) => {
refreshRelationshipComponents(row.id);
}
"
@before-request-data="
() => {
refreshRelationshipComponents('');
}
"
>
</w-grid>
</div>
</template>
<template #after>
<div class="pl-1" style="height: 100%">
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0" no-caps>
<q-tab name="menu" icon="bi-menu-app" :label="$t('menu')" />
<q-tab name="user" icon="bi-person" :label="$t('user')" />
</q-tabs>
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive style="height: calc(100% - 48px)">
<q-tab-panel name="menu" class="px-0 pb-0" style="height: 100%; padding-left: 0px; padding-right: 0px; padding-bottom: 0px">
<SelectMenuTreeGrid
ref="menuTreeGridRef"
:fetch-data-url="Environment.apiContextPath('/api/system/menu/listAllMenusWithSelectedStatusByRole')"
foreign-key="roleId"
:foreign-value="currentSelectedRoleId"
@update="update"
></SelectMenuTreeGrid>
</q-tab-panel>
<q-tab-panel name="user" class="px-0 pb-0" style="height: 100%; padding-left: 0px; padding-right: 0px; padding-bottom: 0px">
<SelectUserGrid
ref="userGridRef"
:fetch-data-url="Environment.apiContextPath('/api/system/user/queryUsersByRole')"
:fetch-other-data-url="Environment.apiContextPath('/api/system/user/queryOtherUsersByRole')"
foreign-key="roleId"
:foreign-value="currentSelectedRoleId"
@select-in="selectIn"
@select-out="selectOut"
@select-all-in="selectAllIn"
@select-all-out="selectAllOut"
>
</SelectUserGrid>
</q-tab-panel>
</q-tab-panels>
</div>
</template>
</q-splitter>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import { Environment, SessionManager, axios, Options, Formater } from '@/platform'; import { Environment, SessionManager, axios, Options, Formater, EnumTools } from '@/platform';
import SelectUserGrid from './shared/SelectUserGrid.vue'; import SelectUserGrid from './shared/SelectUserGrid.vue';
import SelectMenuTreeGrid from './shared/SelectMenuTreeGrid.vue'; import SelectMenuTreeGrid from './shared/SelectMenuTreeGrid.vue';
import { onMounted } from 'vue'; import { onMounted } from 'vue';
const roleGridRef = ref();
const userGridRef = ref(); const userGridRef = ref();
const menuTreeGridRef = ref();
const selectedTabRef = ref('menu');
const currentSelectedRoleId = ref('');
const optionRef = ref([]);
const refreshRelationshipComponents = (id) => {
currentSelectedRoleId.value = id;
menuTreeGridRef.value?.refresh();
userGridRef.value?.refresh();
};
const selectIn = (ids: string[], gridComponent, dialogComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/addUsers'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent?.refresh();
dialogComponent?.close();
});
};
const selectOut = (ids, gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/removeUsers'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent?.refresh();
});
};
const selectAllIn = (gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/addAllUsers'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: [],
})
.then(() => {
gridComponent?.refresh();
});
};
const selectAllOut = (gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/removeAllUsers'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: [],
})
.then(() => {
gridComponent?.refresh();
});
};
const update = (ids, gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/updateMenus'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent.refresh();
});
};
onMounted(() => {
axios.get(Environment.apiContextPath('/api/system/corporation')).then((response) => {
const options = [];
if (response.data?.content && response.data?.content.length > 0) {
for (const item of response.data.content) {
options.push({ label: item.name, value: item.code });
}
}
optionRef.value = options;
});
});
</script> </script>

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

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

201
io.sc.platform.core.frontend/template-project/src/views/testcase/form/form.vue

@ -1,49 +1,46 @@
<template> <template>
<q-splitter :model-value="60" class="w-full" style="height: 100%">
<template #before>
<div class="pr-1" style="height: 100%">
<w-grid <w-grid
ref="roleGridRef" ref="userGridRef"
:title="$t('system.role.grid.title')" :title="$t('system.user.grid.title')"
:config-button="true" :config-button="true"
selection="multiple" selection="multiple"
db-click-operation="edit"
:checkbox-selection="true" :checkbox-selection="true"
:data-url="Environment.apiContextPath('/api/system/role')" :data-url="Environment.apiContextPath('/api/system/user')"
:sort-by="['name']" :sort-by="['loginName']"
:query-form-cols-num="3" :query-form-cols-num="3"
:query-form-fields="[ :query-form-fields="[
{ name: 'code', label: $t('code'), type: 'w-text' }, { name: 'loginName', label: $t('loginName'), type: 'w-text' },
{ name: 'name', label: $t('name'), type: 'w-text' }, { name: 'userName', label: $t('userName'), type: 'w-text' },
{ name: 'enable', label: $t('isEnable'), type: 'w-select', options: Options.yesNo() }, { name: 'enable', label: $t('isEnable'), type: 'w-select', options: Options.yesNo(), queryOperator: 'equals' },
]" ]"
:toolbar-configure="{ noIcon: false }" :toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view', 'separator', 'export']" :toolbar-actions="['query', 'refresh', 'separator', 'add', 'clone', 'edit', 'remove', 'separator', 'view', 'separator', 'export']"
:columns="[ :columns="[
{ width: 150, name: 'code', label: $t('code') }, { width: 200, name: 'loginName', label: $t('loginName') },
{ width: '100%', name: 'name', label: $t('name') }, { width: '100%', name: 'userName', label: $t('userName') },
{ width: 80, name: 'enable', label: $t('status'), format: Formater.enableTag() },
{ width: 100, name: 'corporationCode', label: $t('corporation'), hidden: !SessionManager.isPrimaryCorporation() },
{ width: 120, name: 'lastModifier', label: $t('lastModifier') },
{ width: 120, name: 'lastModifyDate', label: $t('lastModifyDate'), format: Formater.dateOnly() },
]" ]"
:editor="{ :editor="{
dialog: { dialog: {
width: '600px', width: '800px',
}, },
form: { form: {
colsNum: 1, colsNum: 4,
fields: [ fields: [
{ name: 'code', label: $t('code'), type: 'w-text', required: true }, { name: 'loginName', label: $t('loginName'), type: 'w-text', requiredIf: true, colSpan: 2 },
{ name: 'name', label: $t('name'), type: 'w-text', required: true }, { name: 'userName', label: $t('userName'), type: 'w-text', requiredIf: true, colSpan: 2 },
{ name: 'description', label: $t('description'), type: 'w-textarea', rows: 1 }, { name: 'description', label: $t('description'), type: 'w-textarea', rows: 1, colSpan: 2 },
{ name: 'enable', label: $t('enable'), type: 'w-checkbox', defaultValue: true }, { name: 'password', label: $t('password'), type: 'w-password', colSpan: 2 },
{ { name: 'mobile', label: $t('mobile'), type: 'w-text', colSpan: 2 },
name: 'corporationCode', { name: 'phone', label: $t('phone'), type: 'w-text', colSpan: 2 },
label: $t('corporation'), { name: 'email', label: $t('email'), type: 'w-text', colSpan: 2 },
type: 'tree-select', { name: 'weixin', label: $t('weixin'), type: 'w-text', colSpan: 2 },
options: optionRef, { name: 'qq', label: $t('qq'), type: 'w-text', colSpan: 2 },
required: true,
}, { name: 'enable', label: $t('enable'), type: 'w-checkbox', defaultValue: true, colsFirst: true },
{ name: 'accountExpired', label: $t('accountExpired'), type: 'w-checkbox', defaultValue: false },
{ name: 'accountLocked', label: $t('accountLocked'), type: 'w-checkbox', defaultValue: false },
{ name: 'credentialsExpired', label: $t('credentialsExpired'), type: 'w-checkbox', defaultValue: false },
], ],
}, },
}" }"
@ -52,10 +49,18 @@
columnNum: 1, columnNum: 1,
fields: [ fields: [
{ name: 'id', label: $t('id') }, { name: 'id', label: $t('id') },
{ name: 'code', label: $t('code') }, { name: 'loginName', label: $t('loginName') },
{ name: 'name', label: $t('name') }, { name: 'userName', label: $t('userName') },
{ name: 'description', label: $t('description') }, { name: 'description', label: $t('description') },
{ name: 'enable', label: $t('enable'), format: Formater.none() }, { name: 'enable', label: $t('enable'), format: Formater.none() },
{ name: 'accountExpired', label: $t('accountExpired') },
{ name: 'accountLocked', label: $t('accountLocked') },
{ name: 'credentialsExpired', label: $t('credentialsExpired') },
{ name: 'email', label: $t('email') },
{ name: 'phone', label: $t('phone') },
{ name: 'mobile', label: $t('mobile') },
{ name: 'weixin', label: $t('weixin') },
{ name: 'qq', label: $t('qq') },
{ name: 'dataComeFrom', label: $t('dataComeFrom') }, { name: 'dataComeFrom', label: $t('dataComeFrom') },
{ name: 'creator', label: $t('creator') }, { name: 'creator', label: $t('creator') },
{ name: 'createDate', label: $t('createDate') }, { name: 'createDate', label: $t('createDate') },
@ -65,144 +70,14 @@
], ],
}, },
}" }"
@row-click=" ></w-grid>
(evt, row, index) => {
refreshRelationshipComponents(row.id);
}
"
@before-request-data="
() => {
refreshRelationshipComponents('');
}
"
>
</w-grid>
</div>
</template>
<template #after>
<div class="pl-1" style="height: 100%">
<q-tabs v-model="selectedTabRef" inline-label align="left" :breakpoint="0" no-caps>
<q-tab name="menu" icon="bi-menu-app" :label="$t('menu')" />
<q-tab name="user" icon="bi-person" :label="$t('user')" />
</q-tabs>
<q-tab-panels v-model="selectedTabRef" animated swipeable keep-alive style="height: calc(100% - 48px)">
<q-tab-panel name="menu" class="px-0 pb-0" style="height: 100%; padding-left: 0px; padding-right: 0px; padding-bottom: 0px">
<SelectMenuTreeGrid
ref="menuTreeGridRef"
:fetch-data-url="Environment.apiContextPath('/api/system/menu/listAllMenusWithSelectedStatusByRole')"
foreign-key="roleId"
:foreign-value="currentSelectedRoleId"
@update="update"
></SelectMenuTreeGrid>
</q-tab-panel>
<q-tab-panel name="user" class="px-0 pb-0" style="height: 100%; padding-left: 0px; padding-right: 0px; padding-bottom: 0px">
<SelectUserGrid
ref="userGridRef"
:fetch-data-url="Environment.apiContextPath('/api/system/user/queryUsersByRole')"
:fetch-other-data-url="Environment.apiContextPath('/api/system/user/queryOtherUsersByRole')"
foreign-key="roleId"
:foreign-value="currentSelectedRoleId"
@select-in="selectIn"
@select-out="selectOut"
@select-all-in="selectAllIn"
@select-all-out="selectAllOut"
>
</SelectUserGrid>
</q-tab-panel>
</q-tab-panels>
</div>
</template>
</q-splitter>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref } from 'vue'; import { ref } from 'vue';
import { Environment, SessionManager, axios, Options, Formater } from '@/platform'; import { Environment, SessionManager, axios, Options, Formater, EnumTools } from '@/platform';
import SelectUserGrid from './shared/SelectUserGrid.vue'; import SelectUserGrid from './shared/SelectUserGrid.vue';
import SelectMenuTreeGrid from './shared/SelectMenuTreeGrid.vue'; import SelectMenuTreeGrid from './shared/SelectMenuTreeGrid.vue';
import { onMounted } from 'vue'; import { onMounted } from 'vue';
const roleGridRef = ref();
const userGridRef = ref(); const userGridRef = ref();
const menuTreeGridRef = ref();
const selectedTabRef = ref('menu');
const currentSelectedRoleId = ref('');
const optionRef = ref([]);
const refreshRelationshipComponents = (id) => {
currentSelectedRoleId.value = id;
menuTreeGridRef.value?.refresh();
userGridRef.value?.refresh();
};
const selectIn = (ids: string[], gridComponent, dialogComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/addUsers'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent?.refresh();
dialogComponent?.close();
});
};
const selectOut = (ids, gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/removeUsers'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent?.refresh();
});
};
const selectAllIn = (gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/addAllUsers'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: [],
})
.then(() => {
gridComponent?.refresh();
});
};
const selectAllOut = (gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/removeAllUsers'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: [],
})
.then(() => {
gridComponent?.refresh();
});
};
const update = (ids, gridComponent) => {
axios
.post(Environment.apiContextPath('/api/system/role/updateMenus'), {
one: roleGridRef.value.getSelectedRows()[0].id,
many: ids,
})
.then(() => {
gridComponent.refresh();
});
};
onMounted(() => {
axios.get(Environment.apiContextPath('/api/system/corporation')).then((response) => {
const options = [];
if (response.data?.content && response.data?.content.length > 0) {
for (const item of response.data.content) {
options.push({ label: item.name, value: item.code });
}
}
optionRef.value = options;
});
});
</script> </script>

1
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties

@ -270,3 +270,4 @@ defaultRoleName=Default Role Name
async=Asynchronous async=Asynchronous
valueScale=Value Scale valueScale=Value Scale
scale=Scale scale=Scale
clean=Clean

1
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties

@ -270,3 +270,4 @@ defaultRoleName=\u9ED8\u8A8D\u89D2\u8272\u540D\u7A31
async=\u7570\u6B65 async=\u7570\u6B65
valueScale=\u503C\u7CBE\u5EA6 valueScale=\u503C\u7CBE\u5EA6
scale=\u7CBE\u5EA6 scale=\u7CBE\u5EA6
clean=\u6E05\u9664

1
io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties

@ -270,3 +270,4 @@ defaultRoleName=\u9ED8\u8BA4\u89D2\u8272\u540D\u79F0
async=\u5F02\u6B65 async=\u5F02\u6B65
valueScale=\u503C\u7CBE\u5EA6 valueScale=\u503C\u7CBE\u5EA6
scale=\u7CBE\u5EA6 scale=\u7CBE\u5EA6
clean=\u6E05\u9664

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

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

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.developer.frontend", "name": "io.sc.platform.developer.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -113,7 +113,7 @@
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"pinia-undo": "0.2.4", "pinia-undo": "0.2.4",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

4
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/extension/listener/start/ProcessStartListener.java

@ -44,7 +44,7 @@ public class ProcessStartListener implements ExecutionListener {
if(wrapper==null){ if(wrapper==null){
return; return;
} }
jdbcTemplate.update("insert into SYS_PROCESS_INST_EXT(PROC_INST_ID_,CUST_NO_,CUST_NAME_) values(?,?,?)",processInstanceId,wrapper.getCustNo(),wrapper.getCustName()); jdbcTemplate.update("insert into SYS_PROCESS_INST_EXT(PROC_INST_ID_,BUSINESS_TYPE_,CUST_NO_,CUST_NAME_) values(?,?,?,?)",processInstanceId,wrapper.getBusinessType(),wrapper.getCustNo(),wrapper.getCustName());
} }
private void insertProcInsExtByDefinitionKey(String processDefinitionKey,String processInstanceId,String businessKey){ private void insertProcInsExtByDefinitionKey(String processDefinitionKey,String processInstanceId,String businessKey){
@ -64,6 +64,6 @@ public class ProcessStartListener implements ExecutionListener {
if(wrapper==null){ if(wrapper==null){
return; return;
} }
jdbcTemplate.update("insert into SYS_PROCESS_INST_EXT(PROC_INST_ID_,CUST_NO_,CUST_NAME_) values(?,?,?)",processInstanceId,wrapper.getCustNo(),wrapper.getCustName()); jdbcTemplate.update("insert into SYS_PROCESS_INST_EXT(PROC_INST_ID_,BUSINESS_TYPE_,CUST_NO_,CUST_NAME_) values(?,?,?,?)",processInstanceId,wrapper.getBusinessType(),wrapper.getCustNo(),wrapper.getCustName());
} }
} }

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

@ -7,11 +7,20 @@ import java.time.temporal.ChronoUnit;
import java.util.Date; import java.util.Date;
public class BusinessKeyAndDescriptionWrapper { public class BusinessKeyAndDescriptionWrapper {
private String businessType;
private String businessKey; private String businessKey;
private String custNo; private String custNo;
private String custName; private String custName;
private String processStatus; private String processStatus;
public String getBusinessType() {
return businessType;
}
public void setBusinessType(String businessType) {
this.businessType = businessType;
}
public String getBusinessKey() { public String getBusinessKey() {
return businessKey; return businessKey;
} }

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

@ -9,6 +9,7 @@ public class BusinessKeyAndDescriptionWrapperMapper implements RowMapper<Busines
@Override @Override
public BusinessKeyAndDescriptionWrapper mapRow(ResultSet rs, int rowNum) throws SQLException { public BusinessKeyAndDescriptionWrapper mapRow(ResultSet rs, int rowNum) throws SQLException {
BusinessKeyAndDescriptionWrapper wrapper =new BusinessKeyAndDescriptionWrapper(); BusinessKeyAndDescriptionWrapper wrapper =new BusinessKeyAndDescriptionWrapper();
wrapper.setBusinessKey(rs.getString("BUSINESS_TYPE"));
wrapper.setBusinessKey(rs.getString("BUSINESS_KEY")); wrapper.setBusinessKey(rs.getString("BUSINESS_KEY"));
wrapper.setCustNo(rs.getString("CUST_NO")); wrapper.setCustNo(rs.getString("CUST_NO"));
wrapper.setCustName(rs.getString("CUST_NAME")); wrapper.setCustName(rs.getString("CUST_NAME"));

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

@ -45,6 +45,7 @@ public class ProcessTaskWrapper {
private String taskHandFrontendComponentName; private String taskHandFrontendComponentName;
private String taskHandFrontendComponentProperties; private String taskHandFrontendComponentProperties;
private String businessType;
private String custNo; private String custNo;
private String custName; private String custName;
private String processStatus; private String processStatus;
@ -326,6 +327,14 @@ public class ProcessTaskWrapper {
this.taskHandFrontendComponentProperties = taskHandFrontendComponentProperties; this.taskHandFrontendComponentProperties = taskHandFrontendComponentProperties;
} }
public String getBusinessType() {
return businessType;
}
public void setBusinessType(String businessType) {
this.businessType = businessType;
}
public String getCustNo() { public String getCustNo() {
return custNo; return custNo;
} }

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

@ -49,6 +49,7 @@ public class ProcessTaskWrapperMapper implements RowMapper<ProcessTaskWrapper> {
wrapper.setTaskHandFrontendComponentName(rs.getString("taskHandFrontendComponentName")); wrapper.setTaskHandFrontendComponentName(rs.getString("taskHandFrontendComponentName"));
wrapper.setTaskHandFrontendComponentProperties(rs.getString("taskHandFrontendComponentProperties")); wrapper.setTaskHandFrontendComponentProperties(rs.getString("taskHandFrontendComponentProperties"));
wrapper.setBusinessType(rs.getString("businessType"));
wrapper.setCustNo(rs.getString("custNo")); wrapper.setCustNo(rs.getString("custNo"));
wrapper.setCustName(rs.getString("custName")); wrapper.setCustName(rs.getString("custName"));
wrapper.setProcessStatus(rs.getString("processStatus")); wrapper.setProcessStatus(rs.getString("processStatus"));

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

@ -32,6 +32,7 @@ select * from (
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName, PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName, PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties, PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.BUSINESS_TYPE_ as businessType,
PROCESS_EXT.CUST_NO_ as custNo, PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName, PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus, PROCESS_EXT.PROCESS_STATUS_ as processStatus,

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

@ -34,6 +34,7 @@ select * from (
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName, PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName, PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties, PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.BUSINESS_TYPE_ as businessType,
PROCESS_EXT.CUST_NO_ as custNo, PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName, PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus, PROCESS_EXT.PROCESS_STATUS_ as processStatus,

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

@ -33,6 +33,7 @@ select * from (
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName, PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName, PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties, PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.BUSINESS_TYPE_ as businessType,
PROCESS_EXT.CUST_NO_ as custNo, PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName, PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus, PROCESS_EXT.PROCESS_STATUS_ as processStatus,

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

@ -35,6 +35,7 @@ select * from (
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName, PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName, PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties, PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.BUSINESS_TYPE_ as businessType,
PROCESS_EXT.CUST_NO_ as custNo, PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName, PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus, PROCESS_EXT.PROCESS_STATUS_ as processStatus,

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

@ -32,6 +32,7 @@ select * from (
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName, PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName, PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties, PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.BUSINESS_TYPE_ as businessType,
PROCESS_EXT.CUST_NO_ as custNo, PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName, PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus PROCESS_EXT.PROCESS_STATUS_ as processStatus

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

@ -31,6 +31,7 @@ select
PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName, PROCESS.TASK_HAND_FE_MODEL_NAME_ as taskHandFrontendModelName,
PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName, PROCESS.TASK_HAND_FE_COMP_NAME_ as taskHandFrontendComponentName,
PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties, PROCESS.TASK_HAND_FE_COMP_PROPS_ as taskHandFrontendComponentProperties,
PROCESS_EXT.BUSINESS_TYPE_ as businessType,
PROCESS_EXT.CUST_NO_ as custNo, PROCESS_EXT.CUST_NO_ as custNo,
PROCESS_EXT.CUST_NAME_ as custName, PROCESS_EXT.CUST_NAME_ as custName,
PROCESS_EXT.PROCESS_STATUS_ as processStatus PROCESS_EXT.PROCESS_STATUS_ as processStatus

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

@ -55,6 +55,7 @@
</column> </column>
<column name="PROC_DEF_ID_" type="NVARCHAR(255)" remarks="流程定义ID"></column> <column name="PROC_DEF_ID_" type="NVARCHAR(255)" remarks="流程定义ID"></column>
<column name="BUSINESS_TYPE_" type="NVARCHAR(255)" remarks="业务类型"></column>
<column name="CUST_NO_" type="NVARCHAR(255)" remarks="客户号"></column> <column name="CUST_NO_" type="NVARCHAR(255)" remarks="客户号"></column>
<column name="CUST_NAME_" type="NVARCHAR(255)" remarks="客户名称"></column> <column name="CUST_NAME_" type="NVARCHAR(255)" remarks="客户名称"></column>
<column name="PROCESS_STATUS_" type="NVARCHAR(255)" remarks="流程状态"></column> <column name="PROCESS_STATUS_" type="NVARCHAR(255)" remarks="流程状态"></column>

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.lcdp.frontend", "name": "io.sc.platform.lcdp.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -113,7 +113,7 @@
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"pinia-undo": "0.2.4", "pinia-undo": "0.2.4",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

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

@ -61,6 +61,9 @@
"theme.topper.actions.ai-chat": "AI Chat", "theme.topper.actions.ai-chat": "AI Chat",
"theme.topper.actions.ai-chat.yes": "AI Chat (enabled)", "theme.topper.actions.ai-chat.yes": "AI Chat (enabled)",
"theme.topper.actions.ai-chat.no": "AI Chat (disabled)", "theme.topper.actions.ai-chat.no": "AI Chat (disabled)",
"theme.topper.actions.async-task": "Asynchronous Task",
"theme.topper.actions.async-task.yes": "Asynchronous Task (enabled)",
"theme.topper.actions.async-task.no": "Asynchronous Task (disabled)",
"theme.topper.actions.full-screen": "Full screen", "theme.topper.actions.full-screen": "Full screen",
"theme.topper.actions.full-screen.yes": "Full screen(enabled)", "theme.topper.actions.full-screen.yes": "Full screen(enabled)",
"theme.topper.actions.full-screen.no": "Full screen(disabled)", "theme.topper.actions.full-screen.no": "Full screen(disabled)",

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

@ -61,6 +61,9 @@
"theme.topper.actions.ai-chat": "AI 對話", "theme.topper.actions.ai-chat": "AI 對話",
"theme.topper.actions.ai-chat.yes": "AI 對話 (启用)", "theme.topper.actions.ai-chat.yes": "AI 對話 (启用)",
"theme.topper.actions.ai-chat.no": "AI 對話 (禁用)", "theme.topper.actions.ai-chat.no": "AI 對話 (禁用)",
"theme.topper.actions.async-task": "異步任務",
"theme.topper.actions.async-task.yes": "異步任務(启用)",
"theme.topper.actions.async-task.no": "異步任務(禁用)",
"theme.topper.actions.full-screen": "全屏", "theme.topper.actions.full-screen": "全屏",
"theme.topper.actions.full-screen.yes": "全屏 (启用)", "theme.topper.actions.full-screen.yes": "全屏 (启用)",
"theme.topper.actions.full-screen.no": "全屏 (禁用)", "theme.topper.actions.full-screen.no": "全屏 (禁用)",

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

@ -61,6 +61,9 @@
"theme.topper.actions.ai-chat": "AI 对话", "theme.topper.actions.ai-chat": "AI 对话",
"theme.topper.actions.ai-chat.yes": "AI 对话 (启用)", "theme.topper.actions.ai-chat.yes": "AI 对话 (启用)",
"theme.topper.actions.ai-chat.no": "AI 对话 (禁用)", "theme.topper.actions.ai-chat.no": "AI 对话 (禁用)",
"theme.topper.actions.async-task": "异步任务",
"theme.topper.actions.async-task.yes": "异步任务(启用)",
"theme.topper.actions.async-task.no": "异步任务(禁用)",
"theme.topper.actions.full-screen": "全屏", "theme.topper.actions.full-screen": "全屏",
"theme.topper.actions.full-screen.yes": "全屏 (启用)", "theme.topper.actions.full-screen.yes": "全屏 (启用)",
"theme.topper.actions.full-screen.no": "全屏 (禁用)", "theme.topper.actions.full-screen.no": "全屏 (禁用)",

2
io.sc.platform.lcdp.frontend/src/views/Theme.vue

@ -196,11 +196,9 @@ const saveTheme = () => {
persistent: true, persistent: true,
}) })
.onOk(() => { .onOk(() => {
console.log('>>>>>>>');
const data = {}; const data = {};
Tools.mergeObject(data, configureMap.get(selectedTheme.value)); Tools.mergeObject(data, configureMap.get(selectedTheme.value));
data.theme = Environment.getConfigure().theme; data.theme = Environment.getConfigure().theme;
console.log(data);
axios.put(Environment.apiContextPath('/api/lcdp/configure/') + selectedTheme.value, data).then((response) => { axios.put(Environment.apiContextPath('/api/lcdp/configure/') + selectedTheme.value, data).then((response) => {
NotifyManager.info(t('success')); NotifyManager.info(t('success'));

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

@ -256,6 +256,7 @@
let sql = ''; let sql = '';
sql += 'select\n'; sql += 'select\n';
sql += ' CONCAT(CODE_,\':\',VERSION_) BUSINESS_KEY,\n'; sql += ' CONCAT(CODE_,\':\',VERSION_) BUSINESS_KEY,\n';
sql += ' NULL BUSINESS_TYPE,\n';
sql += ' NAME_ CUST_NO,\n'; sql += ' NAME_ CUST_NO,\n';
sql += ' CONCAT(\'V\',VERSION_) CUST_NAME,\n'; sql += ' CONCAT(\'V\',VERSION_) CUST_NAME,\n';
sql += ' NULL PROCESS_STATUS\n'; sql += ' NULL PROCESS_STATUS\n';

10
io.sc.platform.lcdp.frontend/src/views/theme/Topper.vue

@ -68,8 +68,8 @@
:color="$gc.theme.dark ? 'white' : 'primary'" :color="$gc.theme.dark ? 'white' : 'primary'"
/> />
<q-toggle <q-toggle
v-model="$gc.theme.topper.actions['full-screen'].enable" v-model="$gc.theme.topper.actions['async-task'].enable"
:label="$gc.theme.topper.actions['full-screen'].enable ? $t('theme.topper.actions.full-screen.yes') : $t('theme.topper.actions.full-screen.no')" :label="$gc.theme.topper.actions['async-task'].enable ? $t('theme.topper.actions.async-task.yes') : $t('theme.topper.actions.async-task.no')"
class="p-1" class="p-1"
:color="$gc.theme.dark ? 'white' : 'primary'" :color="$gc.theme.dark ? 'white' : 'primary'"
/> />
@ -79,6 +79,12 @@
class="p-1" class="p-1"
:color="$gc.theme.dark ? 'white' : 'primary'" :color="$gc.theme.dark ? 'white' : 'primary'"
/> />
<q-toggle
v-model="$gc.theme.topper.actions['full-screen'].enable"
:label="$gc.theme.topper.actions['full-screen'].enable ? $t('theme.topper.actions.full-screen.yes') : $t('theme.topper.actions.full-screen.no')"
class="p-1"
:color="$gc.theme.dark ? 'white' : 'primary'"
/>
</div> </div>
<div class="row"> <div class="row">
<div class="col-lg-4 col-md-6 col-sm-8 col-xs-10"> <div class="col-lg-4 col-md-6 col-sm-8 col-xs-10">

3
io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/api/Topper.java

@ -20,8 +20,9 @@ public class Topper {
public Topper(){ public Topper(){
this.actions.put("ai-chat",new TopperAction()); this.actions.put("ai-chat",new TopperAction());
this.actions.put("full-screen",new TopperAction()); this.actions.put("async-task",new TopperAction());
this.actions.put("notifier",new TopperAction()); this.actions.put("notifier",new TopperAction());
this.actions.put("full-screen",new TopperAction());
} }
public int getHeight() { public int getHeight() {

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.license.keygen.frontend", "name": "io.sc.platform.license.keygen.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -113,7 +113,7 @@
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"pinia-undo": "0.2.4", "pinia-undo": "0.2.4",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

29
io.sc.platform.license.keygen/src/main/java/io/sc/platform/license/keygen/controller/LicenseKeyGeneratorWebController.java

@ -1,6 +1,5 @@
package io.sc.platform.license.keygen.controller; package io.sc.platform.license.keygen.controller;
import io.sc.platform.core.License;
import io.sc.platform.core.annotation.AuditLog; import io.sc.platform.core.annotation.AuditLog;
import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice; import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice;
import io.sc.platform.core.annotation.LicenseVerify; import io.sc.platform.core.annotation.LicenseVerify;
@ -8,21 +7,18 @@ import io.sc.platform.core.enums.AuditLogAction;
import io.sc.platform.core.response.ValidateException; import io.sc.platform.core.response.ValidateException;
import io.sc.platform.core.util.ValidatorUtil; import io.sc.platform.core.util.ValidatorUtil;
import io.sc.platform.license.keygen.jpa.entity.LicenseEntity; import io.sc.platform.license.keygen.jpa.entity.LicenseEntity;
import io.sc.platform.license.keygen.jpa.repository.LicenseRepository;
import io.sc.platform.license.keygen.jpa.vo.LicenseVo; import io.sc.platform.license.keygen.jpa.vo.LicenseVo;
import io.sc.platform.license.keygen.service.LicenseKeyGeneratorService; import io.sc.platform.license.keygen.service.LicenseKeyGeneratorService;
import io.sc.platform.license.keygen.service.LicenseService; import io.sc.platform.license.keygen.service.LicenseService;
import io.sc.platform.mvc.controller.support.RestCrudController;
import io.sc.platform.mvc.support.FileDownloader; import io.sc.platform.mvc.support.FileDownloader;
import io.sc.platform.orm.entity.BaseEntity; import io.sc.platform.orm.entity.BaseEntity;
import io.sc.platform.orm.service.support.DataExportConfigure; import io.sc.platform.orm.service.support.DataExportTemplateConfigure;
import io.sc.platform.orm.service.support.QueryParameter; import io.sc.platform.orm.service.support.QueryParameter;
import io.sc.platform.orm.service.support.QueryResult; 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.Criteria;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageImpl;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult; import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -33,7 +29,6 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Date;
import java.util.List; import java.util.List;
@RestController @RestController
@ -128,16 +123,16 @@ public class LicenseKeyGeneratorWebController {
@GetMapping("exportExcel") @GetMapping("exportExcel")
public void _exportExcel(HttpServletRequest request,HttpServletResponse response,LicenseEntity entity,QueryParameter queryParameter) throws Exception{ public void _exportExcel(HttpServletRequest request,HttpServletResponse response,LicenseEntity entity,QueryParameter queryParameter) throws Exception{
List<Criteria> criterias =licenseService.buildCriteriaFromEntity(request.getParameterNames(),entity); // List<Criteria> criterias =licenseService.buildCriteriaFromEntity(request.getParameterNames(),entity);
if(criterias!=null && !criterias.isEmpty()){ // if(criterias!=null && !criterias.isEmpty()){
queryParameter.addCriterias(criterias); // queryParameter.addCriterias(criterias);
} // }
ByteArrayOutputStream outputStream =new ByteArrayOutputStream(); // ByteArrayOutputStream outputStream =new ByteArrayOutputStream();
DataExportConfigure cofigure =licenseService.export(queryParameter,outputStream,null); // DataExportTemplateConfigure cofigure =licenseService.export(queryParameter,outputStream,null);
if(cofigure==null){ // if(cofigure==null){
return; // return;
} // }
InputStream inputStream =new ByteArrayInputStream(outputStream.toByteArray()); // InputStream inputStream =new ByteArrayInputStream(outputStream.toByteArray());
FileDownloader.download(request, response, cofigure.getDownloadFileName(), inputStream); // FileDownloader.download(request, response, cofigure.getDownloadFileName(), inputStream);
} }
} }

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.mvc.frontend", "name": "io.sc.platform.mvc.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -113,7 +113,7 @@
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"pinia-undo": "0.2.4", "pinia-undo": "0.2.4",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

6
io.sc.platform.mvc/src/main/java/io/sc/platform/mvc/controller/DownloaderController.java

@ -1,7 +1,10 @@
package io.sc.platform.mvc.controller; package io.sc.platform.mvc.controller;
import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice; import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice;
import io.sc.platform.mvc.service.SystemParameterService;
import io.sc.platform.mvc.support.FileDownloader; import io.sc.platform.mvc.support.FileDownloader;
import io.sc.platform.orm.storage.service.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller; import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.GetMapping;
@ -12,14 +15,17 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileOutputStream;
@Controller("io.sc.platform.mvc.controller.DownloaderController") @Controller("io.sc.platform.mvc.controller.DownloaderController")
@RequestMapping("/api/mvc") @RequestMapping("/api/mvc")
public class DownloaderController { public class DownloaderController {
@Autowired private StorageService storageService;
@GetMapping(value="download") @GetMapping(value="download")
@IgnoreResponseBodyAdvice @IgnoreResponseBodyAdvice
public void download(@RequestParam("filePath") String filePath,@RequestParam(value = "exportName",required = false) String exportName,HttpServletRequest request,HttpServletResponse response) throws Exception{ public void download(@RequestParam("filePath") String filePath,@RequestParam(value = "exportName",required = false) String exportName,HttpServletRequest request,HttpServletResponse response) throws Exception{
storageService.write(filePath,filePath);
File file =new File(filePath); File file =new File(filePath);
if(file.isFile() && file.exists()) { if(file.isFile() && file.exists()) {
if(StringUtils.hasText(exportName)) { if(StringUtils.hasText(exportName)) {

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

@ -5,15 +5,14 @@ import io.sc.platform.core.annotation.LicenseVerify;
import io.sc.platform.core.enums.AuditLogAction; import io.sc.platform.core.enums.AuditLogAction;
import io.sc.platform.core.response.ValidateException; import io.sc.platform.core.response.ValidateException;
import io.sc.platform.core.util.ValidatorUtil; import io.sc.platform.core.util.ValidatorUtil;
import io.sc.platform.mvc.support.FileDownloader;
import io.sc.platform.orm.api.vo.BaseVo; import io.sc.platform.orm.api.vo.BaseVo;
import io.sc.platform.orm.entity.BaseEntity; import io.sc.platform.orm.entity.BaseEntity;
import io.sc.platform.orm.repository.DaoRepository; import io.sc.platform.orm.repository.DaoRepository;
import io.sc.platform.orm.service.DaoService; import io.sc.platform.orm.service.DaoService;
import io.sc.platform.orm.service.support.DataExportConfigure;
import io.sc.platform.orm.service.support.QueryParameter; import io.sc.platform.orm.service.support.QueryParameter;
import io.sc.platform.orm.service.support.QueryResult; 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.Criteria;
import io.sc.platform.orm.task.Task;
import io.sc.platform.orm.util.EntityVoUtil; import io.sc.platform.orm.util.EntityVoUtil;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
@ -24,9 +23,8 @@ import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid; import javax.validation.Valid;
import java.io.*; import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; import java.util.List;
public abstract class RestCrudController<V extends BaseVo, E extends BaseEntity<V>, ID extends Serializable, R extends DaoRepository<E,ID>, S extends DaoService<E,ID,R>> { public abstract class RestCrudController<V extends BaseVo, E extends BaseEntity<V>, ID extends Serializable, R extends DaoRepository<E,ID>, S extends DaoService<E,ID,R>> {
@ -234,19 +232,20 @@ public abstract class RestCrudController<V extends BaseVo, E extends BaseEntity<
@GetMapping("exportExcel") @GetMapping("exportExcel")
@ResponseBody @ResponseBody
@LicenseVerify @LicenseVerify
public void _exportExcel(HttpServletRequest request,HttpServletResponse response,E entity,QueryParameter queryParameter) throws Exception{ public Task _exportExcel(HttpServletRequest request, HttpServletResponse response, E entity, QueryParameter queryParameter) throws Exception{
List<Criteria> criterias =service.buildCriteriaFromEntity(request.getParameterNames(),entity); List<Criteria> criterias =service.buildCriteriaFromEntity(request.getParameterNames(),entity);
if(criterias!=null && !criterias.isEmpty()){ if(criterias!=null && !criterias.isEmpty()){
queryParameter.addCriterias(criterias); queryParameter.addCriterias(criterias);
} }
exportExcel(request,response,queryParameter); return exportExcel(request,response,queryParameter);
} }
protected void exportExcel(HttpServletRequest request,HttpServletResponse response,QueryParameter queryParameter) throws Exception{ protected Task exportExcel(HttpServletRequest request,HttpServletResponse response,QueryParameter queryParameter) throws Exception{
String downloadFileName =request.getParameter("downloadFileName"); String exportResourceName =request.getParameter("downloadFileName");
ByteArrayOutputStream outputStream =new ByteArrayOutputStream(); return service.export(queryParameter,exportResourceName);
DataExportConfigure cofigure =service.export(queryParameter,outputStream,downloadFileName); // ByteArrayOutputStream outputStream =new ByteArrayOutputStream();
InputStream inputStream =new ByteArrayInputStream(outputStream.toByteArray()); // DataExportTemplateConfigure cofigure =service.export(queryParameter,outputStream,exportName);
FileDownloader.download(request, response, cofigure.getDownloadFileName(), inputStream); // InputStream inputStream =new ByteArrayInputStream(outputStream.toByteArray());
// FileDownloader.download(request, response, cofigure.getDownloadFileName(), inputStream);
} }
} }

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

@ -2,18 +2,19 @@ package io.sc.platform.orm.service;
import io.sc.platform.orm.repository.DaoRepository; import io.sc.platform.orm.repository.DaoRepository;
import io.sc.platform.orm.service.support.DaoExceptionProvider; import io.sc.platform.orm.service.support.DaoExceptionProvider;
import io.sc.platform.orm.service.support.DataExportConfigure; import io.sc.platform.orm.service.support.DataExportTemplateConfigure;
import io.sc.platform.orm.service.support.QueryParameter; import io.sc.platform.orm.service.support.QueryParameter;
import io.sc.platform.orm.service.support.criteria.Criteria; import io.sc.platform.orm.service.support.criteria.Criteria;
import io.sc.platform.poi.generator.UniverTemplate; import io.sc.platform.orm.storage.service.StorageService;
import io.sc.platform.orm.task.Task;
import io.sc.platform.orm.task.service.TaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort; import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import javax.servlet.http.HttpServletRequest; import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.io.Serializable; import java.io.Serializable;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.List; import java.util.List;
@ -23,6 +24,8 @@ import java.util.stream.Stream;
public interface DaoService<E,ID extends Serializable,R extends DaoRepository<E,ID>>{ public interface DaoService<E,ID extends Serializable,R extends DaoRepository<E,ID>>{
public R getRepository(); public R getRepository();
public DaoExceptionProvider<E,ID> getExceptionProvider(); public DaoExceptionProvider<E,ID> getExceptionProvider();
public StorageService getStorageService();
public TaskService getTaskService();
public E findById(ID id); public E findById(ID id);
public E findByUniqueKey(E entity); public E findByUniqueKey(E entity);
@ -46,6 +49,8 @@ public interface DaoService<E,ID extends Serializable,R extends DaoRepository<E,
public List<Criteria> buildCriteriaFromEntity(Enumeration<String> parameterNames, E entity) throws Exception; public List<Criteria> buildCriteriaFromEntity(Enumeration<String> parameterNames, E entity) throws Exception;
public Specification<E> buildSpecification(QueryParameter queryParameter); public Specification<E> buildSpecification(QueryParameter queryParameter);
public long count(QueryParameter queryParameter) throws Exception;
public List<E> list(QueryParameter queryParameter) throws Exception; public List<E> list(QueryParameter queryParameter) throws Exception;
public List<E> list(QueryParameter queryParameter,Specification<E> specification) throws Exception; public List<E> list(QueryParameter queryParameter,Specification<E> specification) throws Exception;
public List<E> list(Specification<E> specification, Sort sort) throws Exception; public List<E> list(Specification<E> specification, Sort sort) throws Exception;
@ -64,6 +69,9 @@ public interface DaoService<E,ID extends Serializable,R extends DaoRepository<E,
public Stream<E> stream(QueryParameter queryParameter, Specification<E> specification) throws Exception; public Stream<E> stream(QueryParameter queryParameter, Specification<E> specification) throws Exception;
public Stream<E> stream(Specification<E> specification, Sort sort) throws Exception; public Stream<E> stream(Specification<E> specification, Sort sort) throws Exception;
public DataExportConfigure getExportConfigure(); public DataExportTemplateConfigure getExportTemplateConfigure();
public DataExportConfigure export(QueryParameter queryParameter, OutputStream outputStream,String downloadFileName) throws Exception; public byte[] getTemplateBytes(DataExportTemplateConfigure configure) throws IOException;
public Task export(QueryParameter queryParameter, String exportResourceName) throws Exception;
public long getSynchronousExportMaxCount();
} }

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

@ -15,12 +15,14 @@ import io.sc.platform.orm.service.support.criteria.Criteria;
import io.sc.platform.orm.service.support.criteria.impl.Equals; import io.sc.platform.orm.service.support.criteria.impl.Equals;
import io.sc.platform.orm.service.support.criteria.impl.IContains; import io.sc.platform.orm.service.support.criteria.impl.IContains;
import io.sc.platform.orm.service.support.criteria.impl.IsNull; import io.sc.platform.orm.service.support.criteria.impl.IsNull;
import io.sc.platform.poi.generator.UniverTemplate; import io.sc.platform.orm.storage.service.StorageService;
import io.sc.platform.poi.generator.UniverExcelGenerator; import io.sc.platform.orm.task.ExportTask;
import io.sc.platform.orm.task.Task;
import io.sc.platform.orm.task.TaskExecuteMode;
import io.sc.platform.orm.task.TaskType;
import io.sc.platform.orm.task.service.TaskService;
import io.sc.platform.security.util.SecurityUtil; import io.sc.platform.security.util.SecurityUtil;
import io.sc.platform.util.ByteUtil; import io.sc.platform.util.ByteUtil;
import io.sc.platform.util.ResourceUtil;
import io.sc.platform.util.StringUtil;
import org.jxls.common.Context; import org.jxls.common.Context;
import org.jxls.util.JxlsHelper; import org.jxls.util.JxlsHelper;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@ -35,14 +37,13 @@ import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.repository.core.EntityInformation; import org.springframework.data.repository.core.EntityInformation;
import org.springframework.data.repository.support.Repositories; import org.springframework.data.repository.support.Repositories;
import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper; import org.springframework.data.util.DirectFieldAccessFallbackBeanWrapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils; import org.springframework.util.StringUtils;
import javax.persistence.criteria.Predicate; import javax.persistence.criteria.Predicate;
import javax.persistence.metamodel.PluralAttribute; import javax.persistence.metamodel.PluralAttribute;
import javax.persistence.metamodel.SingularAttribute; import javax.persistence.metamodel.SingularAttribute;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*; import java.io.*;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.*; import java.util.*;
@ -57,6 +58,9 @@ public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepo
@Autowired protected ConversionService conversionService; @Autowired protected ConversionService conversionService;
@Autowired protected DesensitizerAuthorizerService desensitizerAuthorizerService; @Autowired protected DesensitizerAuthorizerService desensitizerAuthorizerService;
@Autowired protected JxlsTemplateService jxlsTemplateService; @Autowired protected JxlsTemplateService jxlsTemplateService;
@Autowired protected StorageService storageService;
@Autowired protected TaskService taskService;
@Autowired protected JdbcTemplate jdbcTemplate;
protected DaoExceptionProvider<E,ID> exceptionProvider =getExceptionProvider(); protected DaoExceptionProvider<E,ID> exceptionProvider =getExceptionProvider();
@Override @Override
@ -69,6 +73,16 @@ public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepo
return new DaoExceptionProvider<E, ID>(){}; return new DaoExceptionProvider<E, ID>(){};
} }
@Override
public StorageService getStorageService() {
return storageService;
}
@Override
public TaskService getTaskService() {
return taskService;
}
@Override @Override
@Transactional @Transactional
public E findById(ID id) { public E findById(ID id) {
@ -410,6 +424,16 @@ public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepo
}; };
} }
@Override
public long count(QueryParameter queryParameter) throws Exception {
if(queryParameter!=null) {
Specification<E> specification =buildSpecification(queryParameter);
return repository.count(specification);
}else{
return repository.count();
}
}
@Override @Override
public List<E> list(QueryParameter queryParameter) throws Exception { public List<E> list(QueryParameter queryParameter) throws Exception {
if(queryParameter!=null) { if(queryParameter!=null) {
@ -625,54 +649,63 @@ public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepo
} }
@Override @Override
public DataExportConfigure getExportConfigure() { public DataExportTemplateConfigure getExportTemplateConfigure() {
String entityClassName =repository.getJpaEntityInformation().getJavaType().getName(); String entityClassName =repository.getJpaEntityInformation().getJavaType().getName();
DataExportConfigure configure =new DataExportConfigure();
DataExportTemplateConfigure configure =new DataExportTemplateConfigure();
// 设置实体类名
configure.setJxlsTemplateJpaEntityClass(entityClassName);
// 设置模版类路径
configure.setJxlsTemplateClassPath(entityClassName.replace('.','/') + ".xlsx"); configure.setJxlsTemplateClassPath(entityClassName.replace('.','/') + ".xlsx");
configure.setJxlsTemplateJpaEntityClass(repository.getJpaEntityInformation().getJavaType().getName());
configure.setOutputFilePath(DirectoryManager.getInstance().getByName("dir.work.web.export") + "/" + UUID.randomUUID().toString() + ".xlsx");
configure.setDownloadFileName(repository.getJpaEntityInformation().getJavaType().getSimpleName() + ".xlsx");
return configure; return configure;
} }
@Override @Override
public DataExportConfigure export(QueryParameter queryParameter, OutputStream outputStream,String downloadFileName) throws Exception { public Task export(QueryParameter queryParameter, String exportResourceName) throws Exception {
DataExportConfigure dataExportConfigure =this.getExportConfigure(); DataExportTemplateConfigure dataExportTemplateConfigure =this.getExportTemplateConfigure();
if(dataExportConfigure==null){ if(dataExportTemplateConfigure==null){
return null; return null;
} }
if(StringUtils.hasText(downloadFileName)){
dataExportConfigure.setDownloadFileName(downloadFileName + ".xlsx");
}
String templateClassPath =dataExportConfigure.getJxlsTemplateClassPath(); String exportResourceFileName =exportResourceName + ".xlsx";
String templateCode =dataExportConfigure.getJxlsTemplateCode();
String templateJpaEntityClass =dataExportConfigure.getJxlsTemplateJpaEntityClass(); byte[] templateBytes =getTemplateBytes(dataExportTemplateConfigure);
JxlsTemplate template =null; if(templateBytes==null){
if(StringUtils.hasText(templateCode)) { return null;
template =jxlsTemplateService.findTemplateByCode(templateCode);
}else if(StringUtils.hasText(templateClassPath)) {
Resource resource =new DefaultResourceLoader().getResource("classpath:/" + templateClassPath);
if(resource!=null && resource.exists()){
try(InputStream inputStream =resource.getInputStream();){
template =new JxlsTemplate();
template.setBytes(ByteUtil.read(inputStream));
}
} }
}else if(StringUtils.hasText(templateJpaEntityClass)){
template =jxlsTemplateService.findTemplateByJpaEntityClass(templateJpaEntityClass); ExportTask task =new ExportTask();
task.setName("导出" + exportResourceName);
task.setType(TaskType.EXPORT);
task.setCreateDate(new Date());
task.setOutputPath(DirectoryManager.getInstance().getByName("dir.work.web.export") + "/" + UUID.randomUUID().toString() + ".xlsx");
task.setExportResourceName(exportResourceFileName);
task.setExportResourceUrl("/api/mvc/download?filePath=" + task.getOutputPath() + "&exportName=" + exportResourceFileName);
long count =this.count(queryParameter);
task.setTotalWeight(count);
if(count <= getSynchronousExportMaxCount()){
task.setExecuteMode(TaskExecuteMode.SYNCHRONOUS);
}else{
task.setExecuteMode(TaskExecuteMode.ASYNCHRONOUS);
} }
if(template==null){ ExportExcelThread thread =new ExportExcelThread(task,this,queryParameter);
return null; if(TaskExecuteMode.SYNCHRONOUS.equals(task.getExecuteMode())){
thread.run();
}else{
thread.startExportTask();
thread.start();
}
return task;
} }
Context context = new Context(); @Override
context.putVar("list", this.list(queryParameter)); public long getSynchronousExportMaxCount() {
try(InputStream inputStream =new ByteArrayInputStream(template.getBytes());){ Map<String,Object> row =jdbcTemplate.queryForMap("select VALUE_ from SYS_PARAMETER where CODE_=?","parameter.orm.exportExcel.synchronousExportMaxCount");
JxlsHelper.getInstance().setEvaluateFormulas(true).processTemplate(inputStream, outputStream,context); if(row==null || row.isEmpty()){
return 1000;
} }
return dataExportConfigure; return Long.parseLong(row.get("VALUE_").toString());
} }
@Override @Override
@ -799,4 +832,46 @@ public abstract class DaoServiceImpl<E,ID extends Serializable,R extends DaoRepo
} }
} }
} }
/**
* 获取导出JXLS模版
* @param configure 模版配置
* @return 模版
* @throws IOException 违例
*/
@Override
public byte[] getTemplateBytes(DataExportTemplateConfigure configure) throws IOException {
if(configure==null){
return null;
}
// 先查找 JXLS 模版中匹配的 code 的模版
String templateCode =configure.getJxlsTemplateCode();
if(StringUtils.hasText(templateCode)) {
JxlsTemplate template =jxlsTemplateService.findTemplateByCode(templateCode);
if(template!=null){
return template.getBytes();
}
}
// 再查找 JXLS 模版中匹配的实体类名的模版
String templateJpaEntityClass =configure.getJxlsTemplateJpaEntityClass();
if(StringUtils.hasText(templateJpaEntityClass)) {
JxlsTemplate template =jxlsTemplateService.findTemplateByJpaEntityClass(templateJpaEntityClass);
if(template!=null){
return template.getBytes();
}
}
// 最后查找预定义的模版类路径
String templateClassPath =configure.getJxlsTemplateClassPath();
if(StringUtils.hasText(templateClassPath)) {
Resource resource = new DefaultResourceLoader().getResource("classpath:/" + templateClassPath);
if (resource != null && resource.exists()) {
try (InputStream inputStream = resource.getInputStream();) {
return ByteUtil.read(inputStream);
}
}
}
return null;
}
} }

31
io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/support/DataExportConfigure.java → io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/support/DataExportTemplateConfigure.java

@ -3,21 +3,10 @@ package io.sc.platform.orm.service.support;
/** /**
* 数据导出配置类 * 数据导出配置类
*/ */
public class DataExportConfigure { public class DataExportTemplateConfigure {
private boolean async; //是否异步执行
private String jxlsTemplateClassPath; //JXLS模版 classpath
private String jxlsTemplateCode; //JXLS模版代码 private String jxlsTemplateCode; //JXLS模版代码
private String jxlsTemplateClassPath; //JXLS模版 classpath
private String jxlsTemplateJpaEntityClass; //JXLS模版JPA实体类 private String jxlsTemplateJpaEntityClass; //JXLS模版JPA实体类
private String outputFilePath; //导出文件路径
private String downloadFileName; //用于下载的文件名
public boolean isAsync() {
return async;
}
public void setAsync(boolean async) {
this.async = async;
}
public String getJxlsTemplateClassPath() { public String getJxlsTemplateClassPath() {
return jxlsTemplateClassPath; return jxlsTemplateClassPath;
@ -42,20 +31,4 @@ public class DataExportConfigure {
public void setJxlsTemplateJpaEntityClass(String jxlsTemplateJpaEntityClass) { public void setJxlsTemplateJpaEntityClass(String jxlsTemplateJpaEntityClass) {
this.jxlsTemplateJpaEntityClass = jxlsTemplateJpaEntityClass; this.jxlsTemplateJpaEntityClass = jxlsTemplateJpaEntityClass;
} }
public String getOutputFilePath() {
return outputFilePath;
}
public void setOutputFilePath(String outputFilePath) {
this.outputFilePath = outputFilePath;
}
public String getDownloadFileName() {
return downloadFileName;
}
public void setDownloadFileName(String downloadFileName) {
this.downloadFileName = downloadFileName;
}
} }

77
io.sc.platform.orm/src/main/java/io/sc/platform/orm/service/support/ExportExcelThread.java

@ -0,0 +1,77 @@
package io.sc.platform.orm.service.support;
import io.sc.platform.orm.service.DaoService;
import io.sc.platform.orm.task.ExportTask;
import io.sc.platform.orm.task.TaskStatus;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.jxls.common.Context;
import org.jxls.util.JxlsHelper;
import java.io.ByteArrayInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
public class ExportExcelThread extends Thread {
protected ExportTask task;
protected DaoService daoService;
protected QueryParameter queryParameter;
public ExportExcelThread(ExportTask task, DaoService daoService,QueryParameter queryParameter){
this.task =task;
this.daoService =daoService;
this.queryParameter =queryParameter;
}
@Override
public void run() {
try {
//获取模版
byte[] templateBytes = daoService.getTemplateBytes(daoService.getExportTemplateConfigure());
//导出
String outputFilePath = task.getOutputPath();
Context context = new Context();
context.putVar("list", daoService.list(queryParameter));
changeCurrentWeight(task.getTotalWeight()/2);
try (
InputStream inputStream = new ByteArrayInputStream(templateBytes);
FileOutputStream outputStream = new FileOutputStream(outputFilePath);
) {
JxlsHelper.getInstance().setEvaluateFormulas(true).processTemplate(inputStream, outputStream, context);
}
//存储到存储服务中
daoService.getStorageService().add(outputFilePath, outputFilePath);
complete();
} catch (Exception e) {
error(e.getClass().getName(),e.getMessage(), ExceptionUtils.getStackTrace(e));
throw new RuntimeException(e);
}
}
public void startExportTask(){
String id =daoService.getTaskService().create(task);
task.setId(id);
}
public void create(){
daoService.getTaskService().create(task);
}
public void changeStatus(TaskStatus status){
daoService.getTaskService().changeStatus(task.getId(),status);
}
public void changeCurrentWeight(long currentWeight){
daoService.getTaskService().changeCurrentWeight(task.getId(),currentWeight);
}
public void changeMessage(String message){
daoService.getTaskService().changeMessage(task.getId(),message);
}
public void error(String exception,String exceptionMessage,String exceptionStackTrace){
daoService.getTaskService().error(task.getId(),exception,exceptionMessage,exceptionStackTrace);
}
public void complete(){
daoService.getTaskService().complete(task.getId());
}
public boolean isCanceled(){
return daoService.getTaskService().isCanceled(task.getId());
}
}

10
io.sc.platform.orm/src/main/java/io/sc/platform/orm/storage/service/StorageService.java

@ -0,0 +1,10 @@
package io.sc.platform.orm.storage.service;
import java.io.OutputStream;
public interface StorageService {
public void add(String path, String sourcePath) throws Exception ;
public void remove(String path) throws Exception ;
public void update(String path,String sourcePath) throws Exception ;
public void write(String path,String targetPath) throws Exception ;
}

107
io.sc.platform.orm/src/main/java/io/sc/platform/orm/storage/service/impl/StorageServiceImpl.java

@ -0,0 +1,107 @@
package io.sc.platform.orm.storage.service.impl;
import io.sc.platform.orm.storage.service.StorageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.support.AbstractLobCreatingPreparedStatementCallback;
import org.springframework.jdbc.core.support.AbstractLobStreamingResultSetExtractor;
import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.UUID;
@Service("io.sc.platform.orm.storage.service.impl.StorageServiceImpl")
public class StorageServiceImpl implements StorageService {
@Autowired private JdbcTemplate jdbcTemplate;
@Override
@Transactional
public void add(String path, String sourcePath) throws Exception {
if(!StringUtils.hasText(path) || !StringUtils.hasText(sourcePath)){
return;
}
if(!storageTypeIsDatabase()){
return;
}
FileInputStream inputStream =new FileInputStream(sourcePath);
LobHandler lobHandler = new DefaultLobHandler();
jdbcTemplate.execute("insert into SYS_STORAGE(ID_,PATH_,BYTES_) values (?,?,?)",new AbstractLobCreatingPreparedStatementCallback(lobHandler){
@Override
protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException, DataAccessException {
ps.setString(1, UUID.randomUUID().toString());
ps.setString(2,path);
ps.setBlob(3,inputStream);
}
});
}
@Override
@Transactional
public void remove(String path) throws Exception {
if(!StringUtils.hasText(path)){
return;
}
if(!storageTypeIsDatabase()){
return;
}
jdbcTemplate.update("delete from SYS_STORAGE where PATH_=?",path);
}
@Override
@Transactional
public void update(String path, String sourcePath) throws Exception {
if(!StringUtils.hasText(path) || !StringUtils.hasText(sourcePath)){
return;
}
if(!storageTypeIsDatabase()){
return;
}
FileInputStream inputStream =new FileInputStream(sourcePath);
LobHandler lobHandler = new DefaultLobHandler();
jdbcTemplate.execute("update SYS_STORAGE set BYTES_=? where PATH_=?",new AbstractLobCreatingPreparedStatementCallback(lobHandler){
@Override
protected void setValues(PreparedStatement ps, LobCreator lobCreator) throws SQLException, DataAccessException {
ps.setString(2,path);
ps.setBlob(1,inputStream);
}
});
}
@Override
public void write(String path, String targetPath) throws Exception {
if(!StringUtils.hasText(path)){
return;
}
if(!storageTypeIsDatabase()){
return;
}
jdbcTemplate.query("select BYTES_ from SYS_STORAGE where PATH_=?",new Object[]{path},new AbstractLobStreamingResultSetExtractor(){
@Override
protected void streamData(ResultSet rs) throws SQLException, IOException, DataAccessException {
LobHandler lobHandler = new DefaultLobHandler();
FileCopyUtils.copy(lobHandler.getBlobAsBinaryStream(rs, 1), new FileOutputStream(targetPath));
}
});
}
private boolean storageTypeIsDatabase() {
Map<String,Object> row =jdbcTemplate.queryForMap("select VALUE_ from SYS_PARAMETER where CODE_=?","parameter.orm.exportExcel.persistence.type");
if(row==null || row.isEmpty()){
return false;
}
return "DATABASE".equals(row.get("VALUE_").toString());
}
}

31
io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/ExportTask.java

@ -0,0 +1,31 @@
package io.sc.platform.orm.task;
public class ExportTask extends Task {
protected String outputPath;
protected String exportResourceName;
protected String exportResourceUrl;
public String getOutputPath() {
return outputPath;
}
public void setOutputPath(String outputPath) {
this.outputPath = outputPath;
}
public String getExportResourceName() {
return exportResourceName;
}
public void setExportResourceName(String exportResourceName) {
this.exportResourceName = exportResourceName;
}
public String getExportResourceUrl() {
return exportResourceUrl;
}
public void setExportResourceUrl(String exportResourceUrl) {
this.exportResourceUrl = exportResourceUrl;
}
}

171
io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/Task.java

@ -0,0 +1,171 @@
package io.sc.platform.orm.task;
import io.sc.platform.orm.api.vo.BaseVo;
import io.sc.platform.util.DateUtil;
import io.sc.platform.util.support.DateDiff;
import java.time.temporal.ChronoUnit;
import java.util.Date;
public class Task extends BaseVo {
protected String id;
protected String name;
protected TaskExecuteMode executeMode;
protected TaskType type;
protected TaskStatus status;
protected String creator;
protected Date createDate;
protected Date completedDate;
protected Date canceledDate;
protected Long totalWeight;
protected Long currentWeight;
protected String message;
protected String exception;
protected String exceptionMessage;
protected String exceptionStackTrace;
private long createDateAndNowDiff;
private ChronoUnit createDateAndNowDiffUnit;
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 TaskExecuteMode getExecuteMode() {
return executeMode;
}
public void setExecuteMode(TaskExecuteMode executeMode) {
this.executeMode = executeMode;
}
public TaskType getType() {
return type;
}
public void setType(TaskType type) {
this.type = type;
}
public TaskStatus getStatus() {
return status;
}
public void setStatus(TaskStatus status) {
this.status = status;
}
public String getCreator() {
return creator;
}
public void setCreator(String creator) {
this.creator = creator;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
if(this.createDate!=null) {
Date now = new Date();
DateDiff dateDiff = DateUtil.dateDiff(this.createDate, now);
this.createDateAndNowDiff = dateDiff.getAmount();
this.createDateAndNowDiffUnit = dateDiff.getUnit();
}
}
public Date getCompletedDate() {
return completedDate;
}
public void setCompletedDate(Date completedDate) {
this.completedDate = completedDate;
}
public Date getCanceledDate() {
return canceledDate;
}
public void setCanceledDate(Date canceledDate) {
this.canceledDate = canceledDate;
}
public Long getTotalWeight() {
return totalWeight;
}
public void setTotalWeight(Long totalWeight) {
this.totalWeight = totalWeight;
}
public Long getCurrentWeight() {
return currentWeight;
}
public void setCurrentWeight(Long currentWeight) {
this.currentWeight = currentWeight;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getException() {
return exception;
}
public void setException(String exception) {
this.exception = exception;
}
public String getExceptionMessage() {
return exceptionMessage;
}
public void setExceptionMessage(String exceptionMessage) {
this.exceptionMessage = exceptionMessage;
}
public String getExceptionStackTrace() {
return exceptionStackTrace;
}
public void setExceptionStackTrace(String exceptionStackTrace) {
this.exceptionStackTrace = exceptionStackTrace;
}
public long getCreateDateAndNowDiff() {
return createDateAndNowDiff;
}
public void setCreateDateAndNowDiff(long createDateAndNowDiff) {
this.createDateAndNowDiff = createDateAndNowDiff;
}
public ChronoUnit getCreateDateAndNowDiffUnit() {
return createDateAndNowDiffUnit;
}
public void setCreateDateAndNowDiffUnit(ChronoUnit createDateAndNowDiffUnit) {
this.createDateAndNowDiffUnit = createDateAndNowDiffUnit;
}
}

6
io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/TaskExecuteMode.java

@ -0,0 +1,6 @@
package io.sc.platform.orm.task;
public enum TaskExecuteMode {
SYNCHRONOUS, //同步
ASYNCHRONOUS; //异步
}

11
io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/TaskStatus.java

@ -0,0 +1,11 @@
package io.sc.platform.orm.task;
/**
* 任务状态
*/
public enum TaskStatus {
STARTED, //已启动
COMPLETED, //已完成
CANCELED, //已取消
ERROR; //发生错误
}

8
io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/TaskType.java

@ -0,0 +1,8 @@
package io.sc.platform.orm.task;
/**
* 任务类型
*/
public enum TaskType {
EXPORT; //数据导出
}

14
io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/service/TaskService.java

@ -0,0 +1,14 @@
package io.sc.platform.orm.task.service;
import io.sc.platform.orm.task.Task;
import io.sc.platform.orm.task.TaskStatus;
public interface TaskService {
public String create(Task task);
public void changeStatus(String taskId,TaskStatus status);
public void changeCurrentWeight(String taskId,long currentWeight);
public void changeMessage(String taskId,String message);
public void error(String taskId,String exception,String exceptionMessage,String exceptionStackTrace);
public void complete(String taskId);
public boolean isCanceled(String taskId);
}

99
io.sc.platform.orm/src/main/java/io/sc/platform/orm/task/service/impl/TaskServiceImpl.java

@ -0,0 +1,99 @@
package io.sc.platform.orm.task.service.impl;
import io.sc.platform.orm.task.ExportTask;
import io.sc.platform.orm.task.Task;
import io.sc.platform.orm.task.TaskStatus;
import io.sc.platform.orm.task.TaskType;
import io.sc.platform.orm.task.service.TaskService;
import io.sc.platform.security.util.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.Map;
import java.util.UUID;
@Service("io.sc.platform.orm.task.service.impl.TaskServiceImpl")
public class TaskServiceImpl implements TaskService {
@Autowired private JdbcTemplate jdbcTemplate;
@Override
@Transactional
public String create(Task task) {
String id =UUID.randomUUID().toString();
String taskSql ="insert into SYS_TASK(ID_,NAME_,TYPE_,EXECUTE_MODE_,STATUS_,CREATOR_,CREATE_DATE_,TOTAL_WEIGHT_,CURRENT_WEIGHT_,MESSAGE_) values(?,?,?,?,?,?,?,?,?,?)";
String exportTaskSql ="insert into SYS_TASK(ID_,NAME_,TYPE_,EXECUTE_MODE_,STATUS_,CREATOR_,CREATE_DATE_,TOTAL_WEIGHT_,CURRENT_WEIGHT_,MESSAGE_,EXPORT_RESOURCE_NAME_,EXPORT_RESOURCE_URL_) values(?,?,?,?,?,?,?,?,?,?,?,?)";
if(TaskType.EXPORT.equals(task.getType())){
ExportTask exportTask =(ExportTask)task;
jdbcTemplate.update(exportTaskSql,
id,
task.getName(),
task.getType().name(),
task.getExecuteMode().name(),
TaskStatus.STARTED.name(),
SecurityUtil.getLoginName(),
new Date(),
task.getTotalWeight(),
task.getCurrentWeight(),
task.getMessage(),
exportTask.getExportResourceName(),
exportTask.getExportResourceUrl()
);
}else{
jdbcTemplate.update(exportTaskSql,
id,
task.getName(),
task.getType().name(),
task.getExecuteMode().name(),
TaskStatus.STARTED.name(),
SecurityUtil.getLoginName(),
new Date(),task.getTotalWeight(),
task.getCurrentWeight(),
task.getMessage()
);
}
return id;
}
@Override
@Transactional
public void changeStatus(String taskId, TaskStatus status) {
jdbcTemplate.update("update SYS_TASK set STATUS_=? where ID_=?",status.name(),taskId);
}
@Override
@Transactional
public void changeCurrentWeight(String taskId, long currentWeight) {
jdbcTemplate.update("update SYS_TASK set CURRENT_WEIGHT_=? where ID_=?",currentWeight,taskId);
}
@Override
@Transactional
public void changeMessage(String taskId, String message) {
jdbcTemplate.update("update SYS_TASK set MESSAGE_=? where ID_=?",message,taskId);
}
@Override
@Transactional
public void error(String taskId, String exception, String exceptionMessage, String exceptionStackTrace) {
jdbcTemplate.update("update SYS_TASK set STATUS_=?,EXCEPTION_=?,EXCEPTION_MESSAGE_=?,EXCEPTION_STACK_TRACE_=? where ID_=?",TaskStatus.ERROR.name(), exception,exceptionMessage,exceptionStackTrace,taskId);
}
@Override
@Transactional
public void complete(String taskId) {
jdbcTemplate.update("update SYS_TASK set STATUS_=?,COMPLETED_DATE_=? where ID_=?",TaskStatus.COMPLETED.name(),new Date(),taskId);
}
@Override
public boolean isCanceled(String taskId) {
Map<String,Object> row =jdbcTemplate.queryForMap("select CANCELED_DATE_ from SYS_TASK where ID_=?",taskId);
if(row==null || row.isEmpty()){
return false;
}
Object canceledDate =row.get("CANCELED_DATE_");
return canceledDate==null? false : true;
}
}

4
io.sc.platform.orm/src/main/resources/META-INF/platform/plugins/components.json

@ -2,6 +2,8 @@
"includes":[ "includes":[
"io.sc.platform.orm.jpa.model.access.service.impl", "io.sc.platform.orm.jpa.model.access.service.impl",
"io.sc.platform.orm.jpa.service.impl", "io.sc.platform.orm.jpa.service.impl",
"io.sc.platform.orm.service.impl" "io.sc.platform.orm.service.impl",
"io.sc.platform.orm.storage.service.impl",
"io.sc.platform.orm.task.service.impl"
] ]
} }

6
io.sc.platform.orm/src/main/resources/META-INF/platform/plugins/messages.json

@ -0,0 +1,6 @@
{
"includes":[
"io/sc/platform/orm/i18n/parameter",
"io/sc/platform/orm/task/i18n/task"
]
}

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

@ -0,0 +1,22 @@
[
/*/ Excel */
{
"id" :"parameter.orm.exportExcel.synchronousExportMaxCount",
"parentId" :"parameter.system",
"code" :"parameter.orm.exportExcel.synchronousExportMaxCount",
"defaultValue" :"1000",
"order" : 1500
},
/*/ Excel */
{
"id" :"parameter.orm.exportExcel.persistence.type",
"parentId" :"parameter.system",
"code" :"parameter.orm.exportExcel.persistence.type",
"defaultValue" :"DISK",
"order" : 1600,
"options" :{
"DATABASE" : "parameter.system.attachment.persistence.type.DATABASE",
"DISK" : "parameter.system.attachment.persistence.type.DISK"
}
}
]

2
io.sc.platform.orm/src/main/resources/io/sc/platform/orm/i18n/parameter.properties

@ -0,0 +1,2 @@
parameter.orm.exportExcel.persistence.type=Export Excel Persistence Type
parameter.orm.exportExcel.synchronousExportMaxCount=Max Row Count Run In Synchronous

2
io.sc.platform.orm/src/main/resources/io/sc/platform/orm/i18n/parameter_tw_CN.properties

@ -0,0 +1,2 @@
parameter.orm.exportExcel.persistence.type=\u5C0E\u51FA Excel \u5B58\u5132\u985E\u578B
parameter.orm.exportExcel.synchronousExportMaxCount=\u540C\u6B65\u5C0E\u51FA\u6700\u5927\u8A18\u9304\u6578

2
io.sc.platform.orm/src/main/resources/io/sc/platform/orm/i18n/parameter_zh_CN.properties

@ -0,0 +1,2 @@
parameter.orm.exportExcel.persistence.type=\u5BFC\u51FA Excel \u5B58\u50A8\u7C7B\u578B
parameter.orm.exportExcel.synchronousExportMaxCount=\u540C\u6B65\u5BFC\u51FA\u6700\u5927\u8BB0\u5F55\u6570

9
io.sc.platform.orm/src/main/resources/io/sc/platform/orm/task/i18n/task.properties

@ -0,0 +1,9 @@
io.sc.platform.orm.task.TaskType.EXPORT=Export
io.sc.platform.orm.task.TaskExecuteMode.SYNCHRONOUS=Synchronous
io.sc.platform.orm.task.TaskExecuteMode.ASYNCHRONOUS=Asynchronous
io.sc.platform.orm.task.TaskStatus.STARTED=Started
io.sc.platform.orm.task.TaskStatus.COMPLETED=Completed
io.sc.platform.orm.task.TaskStatus.CANCELED=Canceled
io.sc.platform.orm.task.TaskStatus.ERROR=Error Occur

9
io.sc.platform.orm/src/main/resources/io/sc/platform/orm/task/i18n/task_tw_CN.properties

@ -0,0 +1,9 @@
io.sc.platform.orm.task.TaskType.EXPORT=\u5C0E\u51FA
io.sc.platform.orm.task.TaskExecuteMode.SYNCHRONOUS=\u540C\u6B65
io.sc.platform.orm.task.TaskExecuteMode.ASYNCHRONOUS=\u7570\u6B65
io.sc.platform.orm.task.TaskStatus.STARTED=\u5DF2\u555F\u52D5
io.sc.platform.orm.task.TaskStatus.COMPLETED=\u5DF2\u5B8C\u6210
io.sc.platform.orm.task.TaskStatus.CANCELED=\u5DF2\u53D6\u6D88
io.sc.platform.orm.task.TaskStatus.ERROR=\u767C\u751F\u932F\u8AA4

9
io.sc.platform.orm/src/main/resources/io/sc/platform/orm/task/i18n/task_zh_CN.properties

@ -0,0 +1,9 @@
io.sc.platform.orm.task.TaskType.EXPORT=\u5BFC\u51FA
io.sc.platform.orm.task.TaskExecuteMode.SYNCHRONOUS=\u540C\u6B65
io.sc.platform.orm.task.TaskExecuteMode.ASYNCHRONOUS=\u5F02\u6B65
io.sc.platform.orm.task.TaskStatus.STARTED=\u5DF2\u542F\u52A8
io.sc.platform.orm.task.TaskStatus.COMPLETED=\u5DF2\u5B8C\u6210
io.sc.platform.orm.task.TaskStatus.CANCELED=\u5DF2\u53D6\u6D88
io.sc.platform.orm.task.TaskStatus.ERROR=\u53D1\u751F\u9519\u8BEF

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.scheduler.manager.frontend", "name": "io.sc.platform.scheduler.manager.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -113,7 +113,7 @@
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"pinia-undo": "0.2.4", "pinia-undo": "0.2.4",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

3
io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/menu/MenuGroupVo.java

@ -1,8 +1,5 @@
package io.sc.platform.system.api.menu; package io.sc.platform.system.api.menu;
import java.util.ArrayList;
import java.util.List;
public class MenuGroupVo extends MenuVo { public class MenuGroupVo extends MenuVo {
private boolean asRoot; private boolean asRoot;

24
io.sc.platform.system.api/src/main/java/io/sc/platform/system/api/storage/DatabaseStorageVo.java

@ -0,0 +1,24 @@
package io.sc.platform.system.api.storage;
import io.sc.platform.orm.api.vo.BaseVo;
public class DatabaseStorageVo extends BaseVo {
protected String id;
protected String path;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}

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

@ -1,6 +1,6 @@
{ {
"name": "io.sc.platform.system.frontend", "name": "io.sc.platform.system.frontend",
"version": "8.2.32", "version": "8.2.33",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -112,7 +112,7 @@
"mockjs": "1.1.0", "mockjs": "1.1.0",
"node-sql-parser": "5.3.6", "node-sql-parser": "5.3.6",
"pinia": "2.3.0", "pinia": "2.3.0",
"platform-core": "8.2.123", "platform-core": "8.2.126",
"quasar": "2.17.6", "quasar": "2.17.6",
"sort-array": "5.0.0", "sort-array": "5.0.0",
"svg-path-commander": "2.1.7", "svg-path-commander": "2.1.7",

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

@ -23,6 +23,7 @@ import component_system_Dictionary from '@/views/dictionary/Dictionary.vue';
import component_system_Desensitizer from '@/views/desensitizer/Desensitizer.vue'; import component_system_Desensitizer from '@/views/desensitizer/Desensitizer.vue';
import component_system_I18n from '@/views/i18n/I18n.vue'; import component_system_I18n from '@/views/i18n/I18n.vue';
import component_system_datasource from '@/views/datasource/Datasource.vue'; import component_system_datasource from '@/views/datasource/Datasource.vue';
import component_system_task from '@/views/task/Task.vue';
import component_system_monitor_AuditLog from '@/views/monitor/AuditLog.vue'; import component_system_monitor_AuditLog from '@/views/monitor/AuditLog.vue';
import component_system_monitor_Log from '@/views/monitor/Log.vue'; import component_system_monitor_Log from '@/views/monitor/Log.vue';
import component_system_monitor_ServerInfo from '@/views/monitor/ServerInfo.vue'; import component_system_monitor_ServerInfo from '@/views/monitor/ServerInfo.vue';
@ -49,6 +50,7 @@ const localComponents = {
'component.system.Desensitizer': component_system_Desensitizer, 'component.system.Desensitizer': component_system_Desensitizer,
'component.system.I18n': component_system_I18n, 'component.system.I18n': component_system_I18n,
'component.system.datasource': component_system_datasource, 'component.system.datasource': component_system_datasource,
'component.system.task': component_system_task,
'component.system.monitor.AuditLog': component_system_monitor_AuditLog, 'component.system.monitor.AuditLog': component_system_monitor_AuditLog,
'component.system.monitor.Log': component_system_monitor_Log, 'component.system.monitor.Log': component_system_monitor_Log,
'component.system.monitor.ServerInfo': component_system_monitor_ServerInfo, 'component.system.monitor.ServerInfo': component_system_monitor_ServerInfo,

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

@ -22,6 +22,7 @@
"menu.system.desensitizer": "Desensitizer", "menu.system.desensitizer": "Desensitizer",
"menu.system.i18n": "I18n Messages", "menu.system.i18n": "I18n Messages",
"menu.system.datasource": "DataSource", "menu.system.datasource": "DataSource",
"menu.system.task": "Task Manager",
"menu.system.monitor": "Monitor", "menu.system.monitor": "Monitor",
"menu.system.monitor.auditlog": "Audit Log", "menu.system.monitor.auditlog": "Audit Log",
"menu.system.monitor.log": "Log", "menu.system.monitor.log": "Log",
@ -169,6 +170,10 @@
"system.datasource.hikari.leakDetectionThreshold": "Leak Detection Threshold(default:0-not check,minimal:2000)", "system.datasource.hikari.leakDetectionThreshold": "Leak Detection Threshold(default:0-not check,minimal:2000)",
"system.datasource.hikari.schema": "Schema", "system.datasource.hikari.schema": "Schema",
"system.task.grid.title": "Task List",
"system.task.grid.entity.completedDate": "Completed Date",
"system.task.grid.entity.canceledDate": "Canceled Date",
"system.monitor.auditlog.grid.title": "Audit Logs List", "system.monitor.auditlog.grid.title": "Audit Logs List",
"system.monitor.log.tab.view": "Log View", "system.monitor.log.tab.view": "Log View",
@ -217,6 +222,7 @@
"settings.shortcutMenus.entity.menuIconColor": "Icon Color", "settings.shortcutMenus.entity.menuIconColor": "Icon Color",
"workbench.grid.entity.processDefinitionName": "Process Name", "workbench.grid.entity.processDefinitionName": "Process Name",
"workbench.grid.entity.businessType": "Business Type",
"workbench.grid.entity.businessKey": "Business Key", "workbench.grid.entity.businessKey": "Business Key",
"workbench.grid.entity.businessDescription": "Business Description", "workbench.grid.entity.businessDescription": "Business Description",
"workbench.grid.entity.custNo": "Customer No.", "workbench.grid.entity.custNo": "Customer No.",

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

@ -22,6 +22,7 @@
"menu.system.desensitizer": "數據脫敏", "menu.system.desensitizer": "數據脫敏",
"menu.system.i18n": "國際化多語言", "menu.system.i18n": "國際化多語言",
"menu.system.datasource": "數據源管理", "menu.system.datasource": "數據源管理",
"menu.system.task": "任務管理",
"menu.system.monitor": "系統監控", "menu.system.monitor": "系統監控",
"menu.system.monitor.auditlog": "審計日誌", "menu.system.monitor.auditlog": "審計日誌",
"menu.system.monitor.log": "系統日誌", "menu.system.monitor.log": "系統日誌",
@ -146,6 +147,32 @@
"system.datasource.grid.entity.databaseType": "數據庫類型", "system.datasource.grid.entity.databaseType": "數據庫類型",
"system.datasource.grid.entity.jdbcDriver": "JDBC 驅動程序", "system.datasource.grid.entity.jdbcDriver": "JDBC 驅動程序",
"system.datasource.grid.entity.jdbcUrl": "JDBC URL", "system.datasource.grid.entity.jdbcUrl": "JDBC URL",
"system.datasource.hikari.autoCommit": "是否自動提交(默認值:true)",
"system.datasource.hikari.connectionTimeout": "連接超時(單位:毫秒,默認值:30000,最小值:250)",
"system.datasource.hikari.idleTimeout": "空閒超時(單位:毫秒,默認值:600000,最小值:10000)",
"system.datasource.hikari.maxLifetime": "最大活動時間(單位:毫秒,默認值:1800000)",
"system.datasource.hikari.connectionTestQuery": "連接測試查詢(JDBC4 無需填寫)",
"system.datasource.hikari.minimumIdle": "最小空閒,默認值:池最大尺寸",
"system.datasource.hikari.maximumPoolSize": "池最大尺寸,默認值:10",
"system.datasource.hikari.metricRegistry": "監控指標註冊器",
"system.datasource.hikari.healthCheckRegistry": "健康檢查註冊器",
"system.datasource.hikari.poolName": "連接池名稱",
"system.datasource.hikari.initializationFailTimeout": "初始化失敗超時",
"system.datasource.hikari.isolateInternalQueries": "內部查詢是否被隔離,默認值:false",
"system.datasource.hikari.allowPoolSuspension": "是否允許池暫停,默認值:false",
"system.datasource.hikari.readOnly": "是否只讀,默認值:false",
"system.datasource.hikari.registerMbeans": "是否註冊為 MBean,默認值:false",
"system.datasource.hikari.catalog": "目錄",
"system.datasource.hikari.connectionInitSql": "連接初始化 sql",
"system.datasource.hikari.driverClassName": "JDBC 驅動類名稱",
"system.datasource.hikari.transactionIsolation": "事務隔離度",
"system.datasource.hikari.validationTimeout": "驗證超時(單位:毫秒,默認值:5000)",
"system.datasource.hikari.leakDetectionThreshold": "洩漏檢測閾值(單位:毫秒,默認值:0-不進行洩漏檢查,最小值:2000)",
"system.datasource.hikari.schema": "方案",
"system.task.grid.title": "任務列表",
"system.task.grid.entity.completedDate": "完成日期",
"system.task.grid.entity.canceledDate": "取消日期",
"system.monitor.auditlog.grid.title": "審計日誌列表", "system.monitor.auditlog.grid.title": "審計日誌列表",
@ -195,6 +222,7 @@
"settings.shortcutMenus.entity.menuIconColor": "圖標顏色", "settings.shortcutMenus.entity.menuIconColor": "圖標顏色",
"workbench.grid.entity.processDefinitionName": "流程名稱", "workbench.grid.entity.processDefinitionName": "流程名稱",
"workbench.grid.entity.businessType": "業務類型",
"workbench.grid.entity.businessKey": "業務流水號", "workbench.grid.entity.businessKey": "業務流水號",
"workbench.grid.entity.businessDescription": "業務描述", "workbench.grid.entity.businessDescription": "業務描述",
"workbench.grid.entity.custNo": "客戶編號", "workbench.grid.entity.custNo": "客戶編號",

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

@ -22,6 +22,7 @@
"menu.system.desensitizer": "数据脱敏", "menu.system.desensitizer": "数据脱敏",
"menu.system.i18n": "国际化多语言", "menu.system.i18n": "国际化多语言",
"menu.system.datasource": "数据源管理", "menu.system.datasource": "数据源管理",
"menu.system.task": "任务管理",
"menu.system.monitor": "系统监控", "menu.system.monitor": "系统监控",
"menu.system.monitor.auditlog": "审计日志", "menu.system.monitor.auditlog": "审计日志",
"menu.system.monitor.log": "系统日志", "menu.system.monitor.log": "系统日志",
@ -169,6 +170,10 @@
"system.datasource.hikari.leakDetectionThreshold": "泄漏检测阈值(单位:毫秒,默认值:0-不进行泄漏检查,最小值:2000)", "system.datasource.hikari.leakDetectionThreshold": "泄漏检测阈值(单位:毫秒,默认值:0-不进行泄漏检查,最小值:2000)",
"system.datasource.hikari.schema": "方案", "system.datasource.hikari.schema": "方案",
"system.task.grid.title": "任务列表",
"system.task.grid.entity.completedDate": "完成日期",
"system.task.grid.entity.canceledDate": "取消日期",
"system.monitor.auditlog.grid.title": "审计日志列表", "system.monitor.auditlog.grid.title": "审计日志列表",
"system.monitor.log.tab.view": "日志查看", "system.monitor.log.tab.view": "日志查看",
@ -225,6 +230,7 @@
"settings.shortcutMenus.entity.menuIconColor": "图标颜色", "settings.shortcutMenus.entity.menuIconColor": "图标颜色",
"workbench.grid.entity.processDefinitionName": "流程名称", "workbench.grid.entity.processDefinitionName": "流程名称",
"workbench.grid.entity.businessType": "业务类型",
"workbench.grid.entity.businessKey": "业务流水号", "workbench.grid.entity.businessKey": "业务流水号",
"workbench.grid.entity.businessDescription": "业务描述", "workbench.grid.entity.businessDescription": "业务描述",
"workbench.grid.entity.custNo": "客户编号", "workbench.grid.entity.custNo": "客户编号",

6
io.sc.platform.system.frontend/src/menus/menus.json

@ -71,10 +71,12 @@
{"type":"SEPARATOR", "order":1800, "parentId":"menu.system"}, {"type":"SEPARATOR", "order":1800, "parentId":"menu.system"},
/*/*/ /*/*/
{"type":"ROUTE", "order":1900, "parentId":"menu.system", "id":"menu.system.datasource", "titleI18nKey":"menu.system.datasource", "icon":"bi-database", "routeName":"route.system.datasource"}, {"type":"ROUTE", "order":1900, "parentId":"menu.system", "id":"menu.system.datasource", "titleI18nKey":"menu.system.datasource", "icon":"bi-database", "routeName":"route.system.datasource"},
/*/*/
{"type":"ROUTE", "order":2000, "parentId":"menu.system", "id":"menu.system.task", "titleI18nKey":"menu.system.task", "icon":"bi-clock", "routeName":"route.system.task"},
/*/*/ /*/*/
{"type":"SEPARATOR", "order":2000, "parentId":"menu.system"}, {"type":"SEPARATOR", "order":2100, "parentId":"menu.system"},
/*/*/ /*/*/
{"type":"GROUP", "order":2100, "parentId":"menu.system", "id":"menu.system.monitor", "titleI18nKey":"menu.system.monitor", "icon":"bi-speedometer2"}, {"type":"GROUP", "order":2200, "parentId":"menu.system", "id":"menu.system.monitor", "titleI18nKey":"menu.system.monitor", "icon":"bi-speedometer2"},
/*//*/ /*//*/
{"type":"ROUTE", "order":100, "parentId":"menu.system.monitor", "id":"menu.system.monitor.auditlog", "titleI18nKey":"menu.system.monitor.auditlog", "icon":"bi-card-list", "routeName":"route.system.monitor.auditlog","authorizeExpression":"'database'.equals(T(org.wsp.framework.core.Environment).getAuditLogType())"}, {"type":"ROUTE", "order":100, "parentId":"menu.system.monitor", "id":"menu.system.monitor.auditlog", "titleI18nKey":"menu.system.monitor.auditlog", "icon":"bi-card-list", "routeName":"route.system.monitor.auditlog","authorizeExpression":"'database'.equals(T(org.wsp.framework.core.Environment).getAuditLogType())"},
/*//*/ /*//*/

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

@ -280,6 +280,19 @@
"permissions": ["/system/datasource/**/*"] "permissions": ["/system/datasource/**/*"]
} }
}, },
{
"parent": "/",
"name": "route.system.task",
"path": "system/task",
"priority": 0,
"module": "io.sc.platform.system.frontend",
"component": "component.system.task",
"componentPath": "@/views/task/Task.vue",
"redirect": null,
"meta": {
"permissions": ["/system/task/**/*"]
}
},
{ {
"parent": "/", "parent": "/",
"name": "route.system.monitor.auditlog", "name": "route.system.monitor.auditlog",

45
io.sc.platform.system.frontend/src/views/task/Task.vue

@ -0,0 +1,45 @@
<template>
<div style="height: 100%">
<w-grid
ref="gridRef"
:title="$t('system.task.grid.title')"
:config-button="true"
selection="multiple"
db-click-operation="view"
:checkbox-selection="true"
:data-url="Environment.apiContextPath('/api/system/task')"
:sort-by="['-createDate']"
:toolbar-configure="{ noIcon: false }"
:toolbar-actions="['query', 'refresh', 'separator', 'view']"
:query-form-cols-num="5"
:query-form-fields="[
{ width: 100, name: 'status', label: $t('status'), type: 'w-select', clearable: true, options: Options.enum(Enums.TaskStatus, false) },
{ width: 100, name: 'type', label: $t('type'), type: 'w-select', clearable: true, options: Options.enum(Enums.TaskType, false) },
{ width: 200, name: 'name', label: $t('name'), type: 'w-text', clearable: true },
{ width: 100, name: 'creator', label: $t('creator'), type: 'w-text', clearable: true },
]"
:columns="[
{
width: 100,
name: 'status',
label: $t('status'),
format: Formater.enum(Enums.TaskStatus),
},
{ width: 100, name: 'type', label: $t('type'), format: Formater.enum(Enums.TaskType) },
{ width: 200, name: 'name', label: $t('name') },
{ width: 100, name: 'creator', label: $t('creator') },
{ width: 120, name: 'createDate', label: $t('createDate') },
{ width: 120, name: 'completedDate', label: $t('system.task.grid.entity.completedDate') },
{ width: 120, name: 'canceledDate', label: $t('system.task.grid.entity.canceledDate') },
{ width: 200, name: 'exception', label: $t('exception') },
{ width: 200, name: 'exceptionMessage', label: $t('exceptionMessage') },
{ width: 200, name: 'exceptionStackTrace', label: $t('exceptionStackTrace') },
]"
></w-grid>
</div>
</template>
<script setup lang="ts">
import { Environment, axios, EnumTools, Formater, Options } from 'platform-core';
const Enums = await EnumTools.fetch(['io.sc.platform.system.enums.TaskType', 'io.sc.platform.system.enums.TaskStatus']);
</script>

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

@ -60,6 +60,7 @@
label: $t('workbench.grid.entity.custNo'), label: $t('workbench.grid.entity.custNo'),
}, },
{ width: '100%', name: 'custName', label: $t('workbench.grid.entity.custName') }, { width: '100%', name: 'custName', label: $t('workbench.grid.entity.custName') },
{ width: 150, name: 'businessType', label: $t('workbench.grid.entity.businessType') },
{ {
width: 200, width: 200,
name: 'processDefinitionKey', name: 'processDefinitionKey',

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

@ -60,6 +60,7 @@
label: $t('workbench.grid.entity.custNo'), label: $t('workbench.grid.entity.custNo'),
}, },
{ width: '100%', name: 'custName', label: $t('workbench.grid.entity.custName') }, { width: '100%', name: 'custName', label: $t('workbench.grid.entity.custName') },
{ width: 150, name: 'businessType', label: $t('workbench.grid.entity.businessType') },
{ {
width: 200, width: 200,
name: 'processDefinitionKey', name: 'processDefinitionKey',

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

@ -60,6 +60,7 @@
label: $t('workbench.grid.entity.custNo'), label: $t('workbench.grid.entity.custNo'),
}, },
{ width: '100%', name: 'custName', label: $t('workbench.grid.entity.custName') }, { width: '100%', name: 'custName', label: $t('workbench.grid.entity.custName') },
{ width: 150, name: 'businessType', label: $t('workbench.grid.entity.businessType') },
{ {
width: 200, width: 200,
name: 'processDefinitionKey', name: 'processDefinitionKey',

15
io.sc.platform.system/src/main/java/io/sc/platform/system/storage/controller/DatabaseStorageWebController.java

@ -0,0 +1,15 @@
package io.sc.platform.system.storage.controller;
import io.sc.platform.mvc.controller.support.RestCrudController;
import io.sc.platform.system.api.storage.DatabaseStorageVo;
import io.sc.platform.system.storage.jpa.entity.DatabaseStorageEntity;
import io.sc.platform.system.storage.jpa.repository.DatabaseStorageRepository;
import io.sc.platform.system.storage.service.DatabaseStorageService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController("io.sc.platform.system.storage.controller.DatabaseStorageWebController")
@RequestMapping("/api/storage")
public class DatabaseStorageWebController extends RestCrudController<DatabaseStorageVo, DatabaseStorageEntity, String, DatabaseStorageRepository, DatabaseStorageService> {
}

49
io.sc.platform.system/src/main/java/io/sc/platform/system/storage/jpa/entity/DatabaseStorageEntity.java

@ -0,0 +1,49 @@
package io.sc.platform.system.storage.jpa.entity;
import io.sc.platform.orm.entity.BaseEntity;
import io.sc.platform.system.api.storage.DatabaseStorageVo;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import javax.validation.constraints.Size;
@Entity
@Table(name="SYS_STORAGE")
public class DatabaseStorageEntity extends BaseEntity<DatabaseStorageVo> {
//主键
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name="ID_", length=36)
@Size(max=36)
protected String id;
@Column(name="PATH_")
protected String path;
@Override
public DatabaseStorageVo toVo() {
DatabaseStorageVo vo =new DatabaseStorageVo();
super.toVo(vo);
vo.setId(this.getId());
vo.setPath(this.getPath());
return vo;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
}

10
io.sc.platform.system/src/main/java/io/sc/platform/system/storage/jpa/repository/DatabaseStorageRepository.java

@ -0,0 +1,10 @@
package io.sc.platform.system.storage.jpa.repository;
import io.sc.platform.orm.repository.DaoRepository;
import io.sc.platform.system.storage.jpa.entity.DatabaseStorageEntity;
import org.springframework.stereotype.Repository;
@Repository("io.sc.platform.system.storage.jpa.repository.DatabaseStorageRepository")
public interface DatabaseStorageRepository extends DaoRepository<DatabaseStorageEntity,String> {
}

9
io.sc.platform.system/src/main/java/io/sc/platform/system/storage/service/DatabaseStorageService.java

@ -0,0 +1,9 @@
package io.sc.platform.system.storage.service;
import io.sc.platform.orm.service.DaoService;
import io.sc.platform.system.storage.jpa.entity.DatabaseStorageEntity;
import io.sc.platform.system.storage.jpa.repository.DatabaseStorageRepository;
public interface DatabaseStorageService extends DaoService<DatabaseStorageEntity, String, DatabaseStorageRepository> {
}

12
io.sc.platform.system/src/main/java/io/sc/platform/system/storage/service/impl/DatabaseStorageServiceImpl.java

@ -0,0 +1,12 @@
package io.sc.platform.system.storage.service.impl;
import io.sc.platform.orm.service.impl.DaoServiceImpl;
import io.sc.platform.system.storage.jpa.entity.DatabaseStorageEntity;
import io.sc.platform.system.storage.jpa.repository.DatabaseStorageRepository;
import io.sc.platform.system.storage.service.DatabaseStorageService;
import org.springframework.stereotype.Service;
@Service("io.sc.platform.system.storage.service.impl.DatabaseStorageServiceImpl")
public class DatabaseStorageServiceImpl extends DaoServiceImpl<DatabaseStorageEntity, String, DatabaseStorageRepository> implements DatabaseStorageService {
}

25
io.sc.platform.system/src/main/java/io/sc/platform/system/task/controller/TaskWebController.java

@ -0,0 +1,25 @@
package io.sc.platform.system.task.controller;
import io.sc.platform.mvc.controller.support.RestCrudController;
import io.sc.platform.orm.task.Task;
import io.sc.platform.system.task.jpa.entity.TaskEntity;
import io.sc.platform.system.task.jpa.repository.TaskRepository;
import io.sc.platform.system.task.service.TaskService;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController("io.sc.platform.system.task.controller.TaskWebController")
@RequestMapping("/api/system/task")
public class TaskWebController extends RestCrudController<Task, TaskEntity, String, TaskRepository, TaskService> {
@PostMapping("cleanMyAsyncTaskList")
public void cleanMyAsyncTaskList(){
service.cleanMyAsyncTaskList();
}
@PostMapping("removeAsyncTask/{taskId}")
public void removeAsyncTask(@PathVariable("taskId")String taskId){
service.removeAsyncTask(taskId);
}
}

17
io.sc.platform.system/src/main/java/io/sc/platform/system/task/jpa/entity/EmptyTaskEntity.java

@ -0,0 +1,17 @@
package io.sc.platform.system.task.jpa.entity;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
/**
* 空任务实体类
*/
@Entity
@DiscriminatorValue("EMPTY")
public class EmptyTaskEntity extends TaskEntity {
public EmptyTaskEntity() {}
public EmptyTaskEntity(String id) {
this.id =id;
}
}

57
io.sc.platform.system/src/main/java/io/sc/platform/system/task/jpa/entity/ExportTaskEntity.java

@ -0,0 +1,57 @@
package io.sc.platform.system.task.jpa.entity;
import io.sc.platform.orm.task.ExportTask;
import io.sc.platform.orm.task.Task;
import javax.persistence.Column;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.validation.constraints.Size;
/**
* 空任务实体类
*/
@Entity
@DiscriminatorValue("EXPORT")
public class ExportTaskEntity extends TaskEntity {
//导出资源名称
@Column(name="EXPORT_RESOURCE_NAME_", length=255)
@Size(max=255)
protected String exportResourceName;
//导出资源URL
@Column(name="EXPORT_RESOURCE_URL_", length=1024)
@Size(max=1024)
protected String exportResourceUrl;
public ExportTaskEntity() {}
public ExportTaskEntity(String id) {
this.id =id;
}
@Override
public Task toVo() {
ExportTask vo =new ExportTask();
super.toVo(vo);
vo.setExportResourceName(this.getExportResourceName());
vo.setExportResourceUrl(this.getExportResourceUrl());
return vo;
}
public String getExportResourceName() {
return exportResourceName;
}
public void setExportResourceName(String exportResourceName) {
this.exportResourceName = exportResourceName;
}
public String getExportResourceUrl() {
return exportResourceUrl;
}
public void setExportResourceUrl(String exportResourceUrl) {
this.exportResourceUrl = exportResourceUrl;
}
}

249
io.sc.platform.system/src/main/java/io/sc/platform/system/task/jpa/entity/TaskEntity.java

@ -0,0 +1,249 @@
package io.sc.platform.system.task.jpa.entity;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonSubTypes;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import io.sc.platform.orm.entity.BaseEntity;
import io.sc.platform.orm.task.Task;
import io.sc.platform.orm.task.TaskExecuteMode;
import io.sc.platform.orm.task.TaskStatus;
import io.sc.platform.orm.task.TaskType;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.Date;
/**
* 任务实体类
*/
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="TYPE_",discriminatorType=DiscriminatorType.STRING,length=20)
@JsonIgnoreProperties(ignoreUnknown=true)
@Table(name="SYS_TASK")
@JsonTypeInfo(use=JsonTypeInfo.Id.NAME, include=JsonTypeInfo.As.PROPERTY, property="type",visible=true,defaultImpl = EmptyTaskEntity.class )
@JsonSubTypes({
@JsonSubTypes.Type(value = EmptyTaskEntity.class, name = "EMPTY"),
@JsonSubTypes.Type(value = ExportTaskEntity.class, name = "EXPORT")
})
public class TaskEntity extends BaseEntity<Task> {
//主键
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name="ID_", length=36)
@Size(max=36)
protected String id;
//名称
@Column(name="NAME_", length=255)
@Size(max=255)
protected String name;
//类型
@Column(name="TYPE_", length=20, insertable=false,updatable=false)
@Enumerated(EnumType.STRING)
protected TaskType type;
//执行模式
@Column(name="EXECUTE_MODE_", length=20)
@Enumerated(EnumType.STRING)
protected TaskExecuteMode executeMode;
//状态
@Column(name="STATUS_", length=20)
@Enumerated(EnumType.STRING)
protected TaskStatus status;
//创建人(登录名)
@Column(name="CREATOR_", length=255, nullable=false)
protected String creator;
//创建日期
@Column(name="CREATE_DATE_", nullable=false)
@Temporal(TemporalType.TIMESTAMP)
protected Date createDate;
//完成日期
@Column(name="COMPLETED_DATE_")
@Temporal(TemporalType.TIMESTAMP)
protected Date completedDate;
//取消日期
@Column(name="CANCELED_DATE_")
@Temporal(TemporalType.TIMESTAMP)
protected Date canceledDate;
//总计需要执行的数量
@Column(name="TOTAL_WEIGHT_")
private Long totalWeight;
//当前已经执行的数量
@Column(name="CURRENT_WEIGHT_")
private Long currentWeight;
//执行进度消息
@Column(name="MESSAGE_")
private String message;
//执行抛出的违例类名称
@Column(name="EXCEPTION_",length=255)
@Size(max=255)
protected String exception;
//执行抛出的违例消息
@Column(name="EXCEPTION_MESSAGE_",length=1024)
@Size(max=1024)
protected String exceptionMessage;
//执行抛出的违例栈
@Column(name="EXCEPTION_STACK_TRACE_")
protected String exceptionStackTrace;
public TaskEntity() {}
public TaskEntity(String id) {
this.id =id;
}
@Override
public void toVo(Task vo) {
super.toVo(vo);
vo.setId(this.getId());
vo.setName(this.getName());
vo.setType(this.getType());
vo.setExecuteMode(this.getExecuteMode());
vo.setStatus(this.getStatus());
vo.setCreator(this.getCreator());
vo.setCreateDate(this.getCreateDate());
vo.setCompletedDate(this.getCompletedDate());
vo.setCanceledDate(this.getCanceledDate());
vo.setTotalWeight(this.getTotalWeight());
vo.setCurrentWeight(this.getCurrentWeight());
vo.setMessage(this.getMessage());
vo.setException(this.getException());
vo.setExceptionMessage(this.getExceptionMessage());
vo.setExceptionStackTrace(this.getExceptionStackTrace());
}
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 TaskType getType() {
return type;
}
public void setType(TaskType type) {
this.type = type;
}
public TaskExecuteMode getExecuteMode() {
return executeMode;
}
public void setExecuteMode(TaskExecuteMode executeMode) {
this.executeMode = executeMode;
}
public TaskStatus getStatus() {
return status;
}
public void setStatus(TaskStatus status) {
this.status = status;
}
public String getCreator() {
return creator;
}
public void setCreator(String creator) {
this.creator = creator;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getCompletedDate() {
return completedDate;
}
public void setCompletedDate(Date completedDate) {
this.completedDate = completedDate;
}
public Date getCanceledDate() {
return canceledDate;
}
public void setCanceledDate(Date canceledDate) {
this.canceledDate = canceledDate;
}
public Long getTotalWeight() {
return totalWeight;
}
public void setTotalWeight(Long totalWeight) {
this.totalWeight = totalWeight;
}
public Long getCurrentWeight() {
return currentWeight;
}
public void setCurrentWeight(Long currentWeight) {
this.currentWeight = currentWeight;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getException() {
return exception;
}
public void setException(String exception) {
this.exception = exception;
}
public String getExceptionMessage() {
return exceptionMessage;
}
public void setExceptionMessage(String exceptionMessage) {
this.exceptionMessage = exceptionMessage;
}
public String getExceptionStackTrace() {
return exceptionStackTrace;
}
public void setExceptionStackTrace(String exceptionStackTrace) {
this.exceptionStackTrace = exceptionStackTrace;
}
}

10
io.sc.platform.system/src/main/java/io/sc/platform/system/task/jpa/repository/TaskRepository.java

@ -0,0 +1,10 @@
package io.sc.platform.system.task.jpa.repository;
import io.sc.platform.orm.repository.DaoRepository;
import io.sc.platform.system.task.jpa.entity.TaskEntity;
import org.springframework.stereotype.Repository;
@Repository("io.sc.platform.system.task.jpa.repository.TaskRepository")
public interface TaskRepository extends DaoRepository<TaskEntity,String> {
}

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save