Browse Source

add theme update

main
wangshaoping 1 year ago
parent
commit
b91b52adbc
  1. 1
      app.platform/build.gradle
  2. 128
      app.platform/platform.sql
  3. 127
      app.platform/platform2.sql
  4. 2
      app.platform/src/main/java/app/platform/Application.java
  5. 4
      build.gradle
  6. 5
      gradle.properties
  7. 2
      io.sc.platform.core.frontend/package.json
  8. 2
      io.sc.platform.core.frontend/src/components/index.ts
  9. 3
      io.sc.platform.core.frontend/src/i18n/messages.json
  10. 3
      io.sc.platform.core.frontend/src/i18n/messages_tw_CN.json
  11. 3
      io.sc.platform.core.frontend/src/i18n/messages_zh_CN.json
  12. 9
      io.sc.platform.core.frontend/src/menus/menus.json
  13. 58
      io.sc.platform.core.frontend/src/platform/components/grid/PlatformGrid.vue
  14. 322
      io.sc.platform.core.frontend/src/platform/components/grid/WListGrid.vue
  15. 39
      io.sc.platform.core.frontend/src/platform/components/grid/WTreeGrid.vue
  16. 3
      io.sc.platform.core.frontend/src/platform/components/index.ts
  17. 10
      io.sc.platform.core.frontend/src/platform/components/tree/WTreeGrid.vue
  18. 1
      io.sc.platform.core.frontend/src/platform/index.ts
  19. 15
      io.sc.platform.core.frontend/src/platform/plugin/manager/MenuManager.ts
  20. 1
      io.sc.platform.core.frontend/src/platform/types/MenuItemType.ts
  21. 9
      io.sc.platform.core.frontend/src/platform/utils/Tools.ts
  22. 2
      io.sc.platform.core.frontend/src/platform/utils/TreeBuilder.ts
  23. 12
      io.sc.platform.core.frontend/src/routes/routes.json
  24. 54
      io.sc.platform.core.frontend/src/views/Table.vue
  25. 48
      io.sc.platform.core.frontend/src/views/TreeGrid.vue
  26. 2
      io.sc.platform.core.frontend/template-project/.npmrc
  27. 4
      io.sc.platform.core.frontend/template-project/package.json
  28. 2
      io.sc.platform.core.frontend/template-project/src/components/index.ts
  29. 3
      io.sc.platform.core.frontend/template-project/src/i18n/messages.json
  30. 3
      io.sc.platform.core.frontend/template-project/src/i18n/messages_tw_CN.json
  31. 3
      io.sc.platform.core.frontend/template-project/src/i18n/messages_zh_CN.json
  32. 9
      io.sc.platform.core.frontend/template-project/src/menus/menus.json
  33. 12
      io.sc.platform.core.frontend/template-project/src/routes/routes.json
  34. 53
      io.sc.platform.core.frontend/template-project/src/views/Table.vue
  35. 48
      io.sc.platform.core.frontend/template-project/src/views/TreeGrid.vue
  36. 1
      io.sc.platform.core/build.gradle
  37. 4
      io.sc.platform.core/src/main/java/io/sc/platform/core/initializer/ApplicationInitializer.java
  38. 47
      io.sc.platform.core/src/main/java/io/sc/platform/core/util/IpUtil.java
  39. 124
      io.sc.platform.core/src/main/resources/io/sc/platform/core/config/logback-spring2.xml
  40. 4
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words.properties
  41. 4
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_tw_CN.properties
  42. 4
      io.sc.platform.core/src/main/resources/io/sc/platform/core/i18n/words_zh_CN.properties
  43. 2
      io.sc.platform.developer.doc/asciidoc/9999-appendix/appendix.adoc
  44. 2
      io.sc.platform.developer.doc/asciidoc/index.adoc
  45. BIN
      io.sc.platform.developer.doc/asciidoc/resources/images/getting-started/windows/install-005.png
  46. 2
      io.sc.platform.developer.frontend/.npmrc
  47. 8
      io.sc.platform.developer.frontend/package.json
  48. 2
      io.sc.platform.developer.frontend/src/components/index.ts
  49. 1
      io.sc.platform.developer.frontend/src/i18n/messages.json
  50. 1
      io.sc.platform.developer.frontend/src/i18n/messages_tw_CN.json
  51. 1
      io.sc.platform.developer.frontend/src/i18n/messages_zh_CN.json
  52. 4
      io.sc.platform.developer.frontend/src/menus/menus.json
  53. 15
      io.sc.platform.developer.frontend/src/routes/routes.json
  54. 26
      io.sc.platform.developer.frontend/src/views/plugin/Initializer.vue
  55. 31
      io.sc.platform.developer/src/main/java/io/sc/platform/developer/plugins/controller/InitializerWebController.java
  56. 67
      io.sc.platform.developer/src/main/java/io/sc/platform/developer/plugins/wrapper/InitializerWrapper.java
  57. 5
      io.sc.platform.developer/src/main/resources/META-INF/platform/plugins/components.json
  58. 98
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/api/AgentVo.java
  59. 97
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/api/ProcessVo.java
  60. 9
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/AgentWebController.java
  61. 7
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/FlowableModelerEditorWebController.java
  62. 3
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/ProcessEntityWebController.java
  63. 17
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/initializer/SampleWorkFlowSystemDictionaryInitializer.java
  64. 20
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/AgentEntity.java
  65. 11
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/ProcessEntity.java
  66. 6
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/repository/AgentRepository.java
  67. 10
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/AgentService.java
  68. 15
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/AgentServiceImpl.java
  69. 14
      io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/ProcessOperationServiceImpl.java
  70. 1
      io.sc.platform.flowable/src/main/resources/META-INF/platform/plugins/messages.json
  71. 2
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/initializer.properties
  72. 2
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/initializer_tw_CN.properties
  73. 2
      io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/initializer_zh_CN.properties
  74. 88
      io.sc.platform.flowable/src/main/resources/liquibase/PF_1.0.0_20221228__Process Manager Database Schema DDL.xml
  75. 2
      io.sc.platform.gradle/templates/pgp/app/build-common.gradle
  76. 1
      io.sc.platform.gradle/templates/pgp/app/build.gradle
  77. 3
      io.sc.platform.gradle/templates/pgp/app/src/main/java/app/platform/Application.java.txt
  78. 14
      io.sc.platform.gradle/templates/pgp/app/src/main/resources/public/configure.js
  79. 4
      io.sc.platform.gradle/templates/pgp/setup/build.gradle.txt
  80. 4
      io.sc.platform.gradle/templates/pgp/setup/gradle.properties
  81. 2
      io.sc.platform.installer/src/main/resources/templates/io/sc/platform/installer/installer.html
  82. 6
      io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExecutorAddressType.java
  83. 6
      io.sc.platform.job.manager/build.gradle
  84. 88
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/JobGroupEntity.java
  85. 12
      io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/JobGroupRepository.java
  86. 10
      io.sc.platform.job.manager/src/main/resources/META-INF/platform/plugins/liquibase.json
  87. 233
      io.sc.platform.job.manager/src/main/resources/liquibase/PF_8.0.0_20220606__Job_DDL.xml
  88. 2
      io.sc.platform.lcdp.frontend/.npmrc
  89. 8
      io.sc.platform.lcdp.frontend/package.json
  90. 9
      io.sc.platform.lcdp.frontend/webpack.config.common.cjs
  91. 4
      io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/api/Configure.java
  92. 51
      io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/api/ConfigureVo.java
  93. 3
      io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/controller/ConfigureController.java
  94. 1
      io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/controller/ConfigureJsController.java
  95. 6
      io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/initializer/ConfigureInitializer.java
  96. 17
      io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/jpa/entity/ConfigureEntity.java
  97. 7
      io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/service/impl/ConfigureServiceImpl.java
  98. 5
      io.sc.platform.lcdp/src/main/resources/META-INF/platform/plugins/messages.json
  99. 2
      io.sc.platform.lcdp/src/main/resources/io/sc/platform/lcdp/configure/i18n/initializer.properties
  100. 2
      io.sc.platform.lcdp/src/main/resources/io/sc/platform/lcdp/configure/i18n/initializer_tw_CN.properties

1
app.platform/build.gradle

@ -13,6 +13,7 @@ dependencies {
implementation ( implementation (
project(":io.sc.platform.app"), project(":io.sc.platform.app"),
project(":io.sc.platform.developer"), project(":io.sc.platform.developer"),
project(":io.sc.platform.job.manager"),
) )
} }

128
app.platform/platform.sql

@ -0,0 +1,128 @@
-- platform.xxl_job_group definition
CREATE TABLE `xxl_job_group` (
`id` int NOT NULL AUTO_INCREMENT,
`app_name` varchar(64) NOT NULL COMMENT '执行器AppName',
`title` varchar(12) NOT NULL COMMENT '执行器名称',
`address_type` tinyint NOT NULL DEFAULT '0' COMMENT '执行器地址类型:0=自动注册、1=手动录入',
`address_list` text COMMENT '执行器地址列表,多地址逗号分隔',
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- platform.xxl_job_info definition
CREATE TABLE `xxl_job_info` (
`id` int NOT NULL AUTO_INCREMENT,
`job_group` int NOT NULL COMMENT '执行器主键ID',
`job_desc` varchar(255) NOT NULL,
`add_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
`author` varchar(64) DEFAULT NULL COMMENT '作者',
`alarm_email` varchar(255) DEFAULT NULL COMMENT '报警邮件',
`schedule_type` varchar(50) NOT NULL DEFAULT 'NONE' COMMENT '调度类型',
`schedule_conf` varchar(128) DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',
`misfire_strategy` varchar(50) NOT NULL DEFAULT 'DO_NOTHING' COMMENT '调度过期策略',
`executor_route_strategy` varchar(50) DEFAULT NULL COMMENT '执行器路由策略',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
`executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
`executor_block_strategy` varchar(50) DEFAULT NULL COMMENT '阻塞处理策略',
`executor_timeout` int NOT NULL DEFAULT '0' COMMENT '任务执行超时时间,单位秒',
`executor_fail_retry_count` int NOT NULL DEFAULT '0' COMMENT '失败重试次数',
`glue_type` varchar(50) NOT NULL COMMENT 'GLUE类型',
`glue_source` mediumtext COMMENT 'GLUE源代码',
`glue_remark` varchar(128) DEFAULT NULL COMMENT 'GLUE备注',
`glue_updatetime` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
`child_jobid` varchar(255) DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
`trigger_status` tinyint NOT NULL DEFAULT '0' COMMENT '调度状态:0-停止,1-运行',
`trigger_last_time` bigint NOT NULL DEFAULT '0' COMMENT '上次调度时间',
`trigger_next_time` bigint NOT NULL DEFAULT '0' COMMENT '下次调度时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- platform.xxl_job_lock definition
CREATE TABLE `xxl_job_lock` (
`lock_name` varchar(50) NOT NULL COMMENT '锁名称',
PRIMARY KEY (`lock_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- platform.xxl_job_log definition
CREATE TABLE `xxl_job_log` (
`id` bigint NOT NULL AUTO_INCREMENT,
`job_group` int NOT NULL COMMENT '执行器主键ID',
`job_id` int NOT NULL COMMENT '任务,主键ID',
`executor_address` varchar(255) DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
`executor_handler` varchar(255) DEFAULT NULL COMMENT '执行器任务handler',
`executor_param` varchar(512) DEFAULT NULL COMMENT '执行器任务参数',
`executor_sharding_param` varchar(20) DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
`executor_fail_retry_count` int NOT NULL DEFAULT '0' COMMENT '失败重试次数',
`trigger_time` datetime DEFAULT NULL COMMENT '调度-时间',
`trigger_code` int NOT NULL COMMENT '调度-结果',
`trigger_msg` text COMMENT '调度-日志',
`handle_time` datetime DEFAULT NULL COMMENT '执行-时间',
`handle_code` int NOT NULL COMMENT '执行-状态',
`handle_msg` text COMMENT '执行-日志',
`alarm_status` tinyint NOT NULL DEFAULT '0' COMMENT '告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败',
PRIMARY KEY (`id`),
KEY `I_trigger_time` (`trigger_time`),
KEY `I_handle_code` (`handle_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- platform.xxl_job_log_report definition
CREATE TABLE `xxl_job_log_report` (
`id` int NOT NULL AUTO_INCREMENT,
`trigger_day` datetime DEFAULT NULL COMMENT '调度-时间',
`running_count` int NOT NULL DEFAULT '0' COMMENT '运行中-日志数量',
`suc_count` int NOT NULL DEFAULT '0' COMMENT '执行成功-日志数量',
`fail_count` int NOT NULL DEFAULT '0' COMMENT '执行失败-日志数量',
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `i_trigger_day` (`trigger_day`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- platform.xxl_job_logglue definition
CREATE TABLE `xxl_job_logglue` (
`id` int NOT NULL AUTO_INCREMENT,
`job_id` int NOT NULL COMMENT '任务,主键ID',
`glue_type` varchar(50) DEFAULT NULL COMMENT 'GLUE类型',
`glue_source` mediumtext COMMENT 'GLUE源代码',
`glue_remark` varchar(128) NOT NULL COMMENT 'GLUE备注',
`add_time` datetime DEFAULT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- platform.xxl_job_registry definition
CREATE TABLE `xxl_job_registry` (
`id` int NOT NULL AUTO_INCREMENT,
`registry_group` varchar(50) NOT NULL,
`registry_key` varchar(255) NOT NULL,
`registry_value` varchar(255) NOT NULL,
`update_time` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `i_g_k_v` (`registry_group`,`registry_key`,`registry_value`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- platform.xxl_job_user definition
CREATE TABLE `xxl_job_user` (
`id` int NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL COMMENT '账号',
`password` varchar(50) NOT NULL COMMENT '密码',
`role` tinyint NOT NULL COMMENT '角色:0-普通用户、1-管理员',
`permission` varchar(255) DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
PRIMARY KEY (`id`),
UNIQUE KEY `i_username` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

127
app.platform/platform2.sql

@ -0,0 +1,127 @@
-- platform2.xxl_job_group definition
CREATE TABLE `xxl_job_group` (
`ID` bigint NOT NULL AUTO_INCREMENT,
`APP_NAME` varchar(64) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`TITLE` varchar(12) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`ADDRESS_TYPE` tinyint NOT NULL DEFAULT '0',
`ADDRESS_LIST` longtext COLLATE utf8mb4_general_ci COMMENT '执行器地址列表,多地址逗号分隔',
`UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新日期',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='JOB 组表';
-- platform2.xxl_job_info definition
CREATE TABLE `xxl_job_info` (
`ID` bigint NOT NULL AUTO_INCREMENT,
`JOB_GROUP` int NOT NULL,
`JOB_DESC` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`ADD_TIME` datetime DEFAULT NULL COMMENT '创建日期',
`UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新日期',
`AUTHOR` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '作者',
`ALARM_EMAIL` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '报警邮件',
`SCHEDULE_TYPE` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'NONE',
`SCHEDULE_CONF` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '调度配置,值含义取决于调度类型',
`MISFIRE_STRATEGY` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL DEFAULT 'DO_NOTHING',
`EXECUTOR_ROUTE_STRATEGY` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '执行器路由策略',
`EXECUTOR_HANDLER` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '执行器任务handler',
`EXECUTOR_PARAM` varchar(512) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '执行器任务参数',
`EXECUTOR_BLOCK_STRATEGY` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '阻塞处理策略',
`EXECUTOR_TIMEOUT` int NOT NULL DEFAULT '0',
`EXECUTOR_FAIL_RETRY_COUNT` int NOT NULL DEFAULT '0',
`GLUE_TYPE` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 'GLUE类型',
`GLUE_SOURCE` longtext COLLATE utf8mb4_general_ci COMMENT 'GLUE源代码',
`GLUE_REMARK` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 'GLUE备注',
`GLUE_UPDATETIME` datetime DEFAULT NULL COMMENT 'GLUE更新时间',
`CHILD_JOBID` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '子任务ID,多个逗号分隔',
`TRIGGER_STATUS` tinyint NOT NULL DEFAULT '0',
`TRIGGER_LAST_TIME` bigint NOT NULL DEFAULT '0',
`TRIGGER_NEXT_TIME` bigint NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='JOB信息表';
-- platform2.xxl_job_lock definition
CREATE TABLE `xxl_job_lock` (
`LOCK_NAME` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '锁名称',
PRIMARY KEY (`LOCK_NAME`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='JOB 锁表';
-- platform2.xxl_job_log definition
CREATE TABLE `xxl_job_log` (
`ID` bigint NOT NULL AUTO_INCREMENT,
`JOB_GROUP` int NOT NULL,
`JOB_ID` int NOT NULL,
`EXECUTOR_ADDRESS` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '执行器地址,本次执行的地址',
`EXECUTOR_HANDLER` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '执行器任务handler',
`EXECUTOR_PARAM` varchar(512) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '执行器任务参数',
`EXECUTOR_SHARDING_PARAM` varchar(20) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '执行器任务分片参数,格式如 1/2',
`EXECUTOR_FAIL_RETRY_COUNT` bigint NOT NULL DEFAULT '0',
`TRIGGER_TIME` datetime DEFAULT NULL COMMENT '调度-时间',
`TRIGGER_CODE` int NOT NULL,
`TRIGGER_MSG` longtext COLLATE utf8mb4_general_ci COMMENT '调度-日志',
`HANDLE_TIME` datetime DEFAULT NULL COMMENT '执行-时间',
`HANDLE_CODE` int NOT NULL,
`HANDLE_MSG` longtext COLLATE utf8mb4_general_ci COMMENT '执行-日志',
`ALARM_STATUS` tinyint NOT NULL DEFAULT '0',
PRIMARY KEY (`ID`),
KEY `IDX_XXL_JOB_LOG_TRIGGER_TIME` (`TRIGGER_TIME`),
KEY `IDX_XXL_JOB_LOG_HANDLE_CODE` (`HANDLE_CODE`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='JOB日志表';
-- platform2.xxl_job_log_report definition
CREATE TABLE `xxl_job_log_report` (
`ID` bigint NOT NULL AUTO_INCREMENT,
`TRIGGER_DAY` datetime DEFAULT NULL COMMENT '调度-时间',
`RUNNING_COUNT` int NOT NULL DEFAULT '0',
`SUC_COUNT` int NOT NULL DEFAULT '0',
`FAIL_COUNT` int NOT NULL DEFAULT '0',
`UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新日期',
PRIMARY KEY (`ID`),
UNIQUE KEY `IDX_XXL_JOB_LOG_REPORT_TRIGGER_DAY` (`TRIGGER_DAY`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='JOB日志报告表';
-- platform2.xxl_job_logglue definition
CREATE TABLE `xxl_job_logglue` (
`ID` bigint NOT NULL AUTO_INCREMENT,
`JOB_ID` int NOT NULL,
`GLUE_TYPE` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 'GLUE类型',
`GLUE_SOURCE` longtext COLLATE utf8mb4_general_ci COMMENT 'GLUE源代码',
`GLUE_REMARK` varchar(128) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT 'GLUE备注',
`ADD_TIME` datetime DEFAULT NULL COMMENT '创建日期',
`UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新日期',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='JOB GLUE 表';
-- platform2.xxl_job_registry definition
CREATE TABLE `xxl_job_registry` (
`ID` bigint NOT NULL AUTO_INCREMENT,
`REGISTRY_GROUP` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`REGISTRY_KEY` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`REGISTRY_VALUE` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`UPDATE_TIME` datetime DEFAULT NULL COMMENT '更新日期',
PRIMARY KEY (`ID`),
UNIQUE KEY `REGISTRY_GROUP` (`REGISTRY_GROUP`,`REGISTRY_KEY`,`REGISTRY_VALUE`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='JOB 注册表';
-- platform2.xxl_job_user definition
CREATE TABLE `xxl_job_user` (
`ID` bigint NOT NULL AUTO_INCREMENT,
`USERNAME` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`PASSWORD` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL,
`ROLE` tinyint NOT NULL,
`PERMISSION` varchar(255) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '权限:执行器ID列表,多个逗号分割',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='JOB 用户表';

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

@ -6,6 +6,8 @@ import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.WebApplicationInitializer; import org.springframework.web.WebApplicationInitializer;
import java.sql.Types;
/** /**
* 应用程序入口 * 应用程序入口
*/ */

4
build.gradle

@ -371,6 +371,8 @@ subprojects {
* pnpm sync * pnpm sync
*----------------------------------------------------------------*/ *----------------------------------------------------------------*/
task frontendNpmSync(type:Exec){ task frontendNpmSync(type:Exec){
commandLine 'cd', '.'
/*
if(isFrontendProject(file('.')) && !project.name.contains("io.sc.platform.security.frontend")){ if(isFrontendProject(file('.')) && !project.name.contains("io.sc.platform.security.frontend")){
workingDir '.' workingDir '.'
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){ if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
@ -384,7 +386,7 @@ subprojects {
}else{ }else{
commandLine 'cd', '.' commandLine 'cd', '.'
} }
} }*/
} }
tasks.frontendNpmSync.doFirst { tasks.frontendNpmSync.doFirst {
if(isFrontendProject(file('.'))) { if(isFrontendProject(file('.'))) {

5
gradle.properties

@ -36,9 +36,9 @@ application_version=1.0.0
# platform # platform
########################################################### ###########################################################
platform_group=io.sc platform_group=io.sc
platform_version=8.1.13 platform_version=8.1.20
platform_plugin_version=8.1.13 platform_plugin_version=8.1.13
platform_core_frontend_version=8.1.42 platform_core_frontend_version=8.1.47
########################################################### ###########################################################
# dependencies version # dependencies version
@ -50,6 +50,7 @@ cxf_version=3.2.7
dm_hibernate_version=8.1.2.192 dm_hibernate_version=8.1.2.192
flowable_version=6.8.0 flowable_version=6.8.0
guava_version=31.1-jre guava_version=31.1-jre
ipaddress_version=5.4.0
jackson_version=2.13.5 jackson_version=2.13.5
jasypt_version=2.1.2 jasypt_version=2.1.2
jboss_logging_version=3.3.2.Final jboss_logging_version=3.3.2.Final

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

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

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

@ -6,12 +6,14 @@ import dialog from '@/views/Dialog.vue';
import codemirror from '@/views/Codemirror.vue'; import codemirror from '@/views/Codemirror.vue';
import select from '@/views/Select.vue'; import select from '@/views/Select.vue';
import treeGrid from '@/views/TreeGrid.vue'; import treeGrid from '@/views/TreeGrid.vue';
import table from '@/views/Table.vue';
const localComponents = { const localComponents = {
'component.testcase.dialog': dialog, 'component.testcase.dialog': dialog,
'component.testcase.codemirror': codemirror, 'component.testcase.codemirror': codemirror,
'component.testcase.select': select, 'component.testcase.select': select,
'component.testcase.treeGrid': treeGrid, 'component.testcase.treeGrid': treeGrid,
'component.testcase.table': table,
}; };
export default localComponents; export default localComponents;

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

@ -3,5 +3,6 @@
"menu.testcase.codemirror": "CodeMirror", "menu.testcase.codemirror": "CodeMirror",
"menu.testcase.dialog": "Dialog", "menu.testcase.dialog": "Dialog",
"menu.testcase.select": "Select", "menu.testcase.select": "Select",
"menu.testcase.treeGrid": "Tree Grid" "menu.testcase.treeGrid": "Tree Grid",
"menu.testcase.table": "Table"
} }

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

@ -3,5 +3,6 @@
"menu.testcase.codemirror": "CodeMirror", "menu.testcase.codemirror": "CodeMirror",
"menu.testcase.dialog": "Dialog", "menu.testcase.dialog": "Dialog",
"menu.testcase.select": "Select", "menu.testcase.select": "Select",
"menu.testcase.treeGrid": "Tree Grid" "menu.testcase.treeGrid": "Tree Grid",
"menu.testcase.table": "Table"
} }

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

@ -3,5 +3,6 @@
"menu.testcase.codemirror": "CodeMirror", "menu.testcase.codemirror": "CodeMirror",
"menu.testcase.dialog": "Dialog", "menu.testcase.dialog": "Dialog",
"menu.testcase.select": "Select", "menu.testcase.select": "Select",
"menu.testcase.treeGrid": "Tree Grid" "menu.testcase.treeGrid": "Tree Grid",
"menu.testcase.table": "Table"
} }

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

@ -53,5 +53,14 @@
"titleI18nKey": "menu.testcase.treeGrid", "titleI18nKey": "menu.testcase.treeGrid",
"icon": "bi-palette", "icon": "bi-palette",
"routeName": "route.testcase.treeGrid" "routeName": "route.testcase.treeGrid"
},
{
"type": "ROUTE",
"order": 400,
"parentId": "menu.testcase",
"id": "menu.testcase.table",
"titleI18nKey": "menu.testcase.table",
"icon": "bi-palette",
"routeName": "route.testcase.table"
} }
] ]

58
io.sc.platform.core.frontend/src/platform/components/grid/PlatformGrid.vue

@ -99,6 +99,14 @@
outline outline
@click="onView" @click="onView"
></q-btn> ></q-btn>
<q-btn
v-else-if="typeof btn === 'string' && btn === 'export' && index < screenShowBtnsNumComputed + screenShowSeparatorComputed"
label="导出"
icon="file_download"
unelevated
outline
@click="onExport"
></q-btn>
<q-btn <q-btn
v-else-if="typeof btn === 'object' && index < screenShowBtnsNumComputed + screenShowSeparatorComputed" v-else-if="typeof btn === 'object' && index < screenShowBtnsNumComputed + screenShowSeparatorComputed"
:label="btn.label" :label="btn.label"
@ -182,6 +190,15 @@
<q-item-label @click="onView"><q-icon :name="PlatformIconEnum.查看"></q-icon> </q-item-label> <q-item-label @click="onView"><q-icon :name="PlatformIconEnum.查看"></q-icon> </q-item-label>
</q-item-section> </q-item-section>
</q-item> </q-item>
<q-item
v-else-if="typeof btn === 'string' && btn === 'export' && index >= tableButtonsComputed.length - moreBtnListNumberComputed"
v-close-popup
clickable
>
<q-item-section>
<q-item-label @click="onExport"><q-icon name="file_download"></q-icon> </q-item-label>
</q-item-section>
</q-item>
<q-item v-else-if="typeof btn === 'object' && index >= tableButtonsComputed.length - moreBtnListNumberComputed" v-close-popup clickable> <q-item v-else-if="typeof btn === 'object' && index >= tableButtonsComputed.length - moreBtnListNumberComputed" v-close-popup clickable>
<q-item-section> <q-item-section>
<q-item-label @click="btn.click(table.selected)"><q-icon :name="btn.icon"></q-icon> {{ btn.label }}</q-item-label> <q-item-label @click="btn.click(table.selected)"><q-icon :name="btn.icon"></q-icon> {{ btn.label }}</q-item-label>
@ -356,7 +373,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, reactive, computed, onMounted, nextTick, toRaw } from 'vue'; import { ref, reactive, computed, onMounted, nextTick, toRaw } from 'vue';
import { axios, Environment } from '@/platform'; import { axios, Environment } from '@/platform';
import { useQuasar, getCssVar } from 'quasar'; import { useQuasar, getCssVar, exportFile } from 'quasar';
import PlatformDialog from '@/platform/components/dialog/PlatformDialog.vue'; import PlatformDialog from '@/platform/components/dialog/PlatformDialog.vue';
import PlatformDrawer from '@/platform/components/drawer/PlatformDrawer.vue'; import PlatformDrawer from '@/platform/components/drawer/PlatformDrawer.vue';
import PlatformInfo from '@/platform/components/panel/PlatformInfo.vue'; import PlatformInfo from '@/platform/components/panel/PlatformInfo.vue';
@ -1199,6 +1216,44 @@ const onDelete = () => {
} }
}; };
const wrapCsvValue = (val, formatFn, row) => {
let formatted = formatFn !== void 0 ? formatFn(val, row) : val;
formatted = formatted === void 0 || formatted === null ? '' : String(formatted);
formatted = formatted.split('"').join('""');
/**
* Excel accepts \n and \r in strings, but some other CSV parsers do not
* Uncomment the next two lines to escape new lines
*/
// .split('\n').join('\\n')
// .split('\r').join('\\r')
return `"${formatted}"`;
};
const onExport = () => {
const content = [props.tableColumns.map((col) => wrapCsvValue(col.label))]
.concat(
table.rows.map((row) =>
props.tableColumns
.map((col) => wrapCsvValue(typeof col.field === 'function' ? col.field(row) : row[col.field === void 0 ? col.name : col.field], col.format, row))
.join(','),
),
)
.join('\r\n');
const status = exportFile('table-export.csv', content, {
encoding: 'utf-8',
mimeType: 'text/csv',
byteOrderMark: '\uFEFF', //
});
if (status !== true) {
platformNotify($q, '导出失败', PlatformNotifyTypeEnum.错误);
}
};
const onSubmit = () => { const onSubmit = () => {
onRequest({ onRequest({
pagination: table.pagination, pagination: table.pagination,
@ -1641,7 +1696,6 @@ const onDrop = (e, scope) => {
} }
removeDragTopStyle(e); removeDragTopStyle(e);
removeDragBottomStyle(e); removeDragBottomStyle(e);
emit('rowDragDropAfter');
}; };
onMounted(() => { onMounted(() => {

322
io.sc.platform.core.frontend/src/platform/components/grid/WListGrid.vue

@ -0,0 +1,322 @@
<template>
<div>
<div class="row q-gutter-x-md q-gutter-y-sm">
<q-input label="loginName" outlined dense />
<q-input label="loginName" outlined dense :options="['ksdjlfsd', 'sdkjfklsd']" />
<q-input label="loginName" outlined dense />
<q-input label="loginName" outlined dense />
<q-input label="loginName" outlined dense />
<q-input label="loginName" outlined dense />
<q-input label="loginName" outlined dense />
<q-input label="loginName" outlined dense />
<q-input label="loginName" outlined dense />
<q-input label="loginName" outlined dense />
</div>
<TableAction title="User List" :no-action-icon="props.noActionIcon" :actions="tableActions"></TableAction>
<q-table flat bordered separator="cell" :rows="data" :columns="columns" row-key="name">
<template #header="headerProps">
<q-tr :props="headerProps">
<q-th auto-width />
<q-th v-for="col in headerProps.cols" :key="col.name" :props="headerProps">
{{ col.label }}
</q-th>
</q-tr>
</template>
<template #body="bodyProps">
<q-tr :props="bodyProps">
<q-td auto-width>
<q-checkbox v-model="bodyProps.row.selected" flat />
<q-btn size="sm" dense flat :icon="bodyProps.expand ? 'bi-dash-lg' : 'bi-plus-lg'" @click="bodyProps.expand = !bodyProps.expand" />
<q-icon name="sym_o_folder_open" size="sm"></q-icon>
</q-td>
<q-td v-for="col in bodyProps.cols" :key="col.name" :props="bodyProps">
<div v-dompurify-html="col.value"></div>
</q-td>
</q-tr>
<q-tr v-for="child in bodyProps.row.children" v-show="bodyProps.expand" :key="child.name" :props="bodyProps">
<q-td auto-width></q-td>
<q-td v-for="col in bodyProps.cols" :key="col.name" :props="bodyProps">
{{ child[col.name] }}
</q-td>
</q-tr>
</template>
</q-table>
</div>
</template>
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { axios, Tools, TreeBuilder } from '@/platform';
import TableAction from './TableAction.vue';
const props = defineProps({
tree: { type: Boolean, default: false },
title: { type: String, default: '' },
noActionIcon: { type: Boolean, default: false },
targetObjectName: { type: String, default: '' },
actions: {
type: Array,
default: () => {
return [];
},
},
columns: {
type: Array,
default: () => {
return [];
},
},
autoFetchData: { type: Boolean, default: false },
dataUrl: { type: String, default: undefined },
fetchDataUrl: { type: String, default: undefined },
addDataUrl: { type: String, default: undefined },
removeDataUrl: { type: String, default: undefined },
updateDataUrl: { type: String, default: undefined },
});
const { t } = useI18n();
const defaultTableActions = {
separator: {
separator: true,
},
query: {
name: 'query',
label: t('query'),
icon: 'bi-search',
click: () => {
console.log('query');
},
},
refresh: {
name: 'refresh',
label: t('refresh'),
icon: 'bi-arrow-clockwise',
click: () => {
console.log('refresh');
},
},
add: {
name: 'add',
label: t('addNew'),
icon: 'bi-plus-lg',
click: () => {
console.log('add');
},
},
clone: {
name: 'clone',
label: t('clone'),
icon: 'content_copy',
click: () => {
console.log('clone');
},
},
edit: {
name: 'edit',
label: t('edit'),
icon: 'bi-pencil-square',
click: () => {
console.log('edit');
},
},
remove: {
name: 'remove',
label: t('delete'),
icon: 'bi-x-lg',
click: () => {
console.log('remove');
},
},
removeAll: {
name: 'removeAll',
label: t('deleteAll'),
click: () => {
console.log('removeAll');
},
},
detail: {
name: 'detail',
label: t('detail'),
icon: 'bi-info-circle',
click: () => {
console.log('detail');
},
},
expandAll: {
name: 'expandAll',
label: t('expandAll'),
icon: 'bi-plus-square',
click: () => {
console.log('expandAll');
},
},
selectAll: {
name: 'selectAll',
label: t('selectAll'),
icon: 'bi-check-square',
click: () => {
console.log('selectAll');
},
},
addTop: {
name: 'addTop',
label: t('addTop', { object: props.targetObjectName }),
icon: 'addTop',
click: () => {
console.log('addTop');
},
},
addChild: {
name: 'addChild',
label: t('addChild', { object: props.targetObjectName }),
icon: 'addChild',
click: () => {
console.log('addChild');
},
},
};
const tableActions = [];
if (props.actions && props.actions.length > 0) {
for (const action of props.actions) {
if (Tools.isString(action)) {
tableActions.push(defaultTableActions[action]);
} else if (Tools.isObject(action)) {
tableActions.push(action);
}
}
}
const data = ref([]);
if (props.autoFetchData) {
axios.get(props.fetchDataUrl ? props.fetchDataUrl : props.dataUrl).then((response) => {
if (props.tree) {
TreeBuilder.build(response.data);
}
data.value = response.data;
});
}
const selected = ref([]);
const val2 = ref(true);
const rows = ref([
{
name: 'Frozen Yogurt',
calories: 159,
fat: 6.0,
carbs: 24,
protein: 4.0,
sodium: 87,
calcium: '14%',
iron: '1%',
selected: true,
children: [
{
name: 'Ice cream sandwich3',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
sodium: 129,
calcium: '8%',
iron: '1%',
},
],
},
{
name: 'Ice cream sandwich',
calories: 237,
fat: 9.0,
carbs: 37,
protein: 4.3,
sodium: 129,
calcium: '8%',
iron: '1%',
},
{
name: 'Eclair',
calories: 262,
fat: 16.0,
carbs: 23,
protein: 6.0,
sodium: 337,
calcium: '6%',
iron: '7%',
},
{
name: 'Cupcake',
calories: 305,
fat: 3.7,
carbs: 67,
protein: 4.3,
sodium: 413,
calcium: '3%',
iron: '8%',
},
{
name: 'Gingerbread',
calories: 356,
fat: 16.0,
carbs: 49,
protein: 3.9,
sodium: 327,
calcium: '7%',
iron: '16%',
},
{
name: 'Jelly bean',
calories: 375,
fat: 0.0,
carbs: 94,
protein: 0.0,
sodium: 50,
calcium: '0%',
iron: '0%',
},
{
name: '<span style="color: red">This should be red.</span>',
calories: 392,
fat: 0.2,
carbs: 98,
protein: 0,
sodium: 38,
calcium: '0%',
iron: '2%',
},
{
name: 'Honeycomb',
calories: 408,
fat: 3.2,
carbs: 87,
protein: 6.5,
sodium: 562,
calcium: '0%',
iron: '45%',
},
{
name: 'Donut',
calories: 452,
fat: 25.0,
carbs: 51,
protein: 4.9,
sodium: 326,
calcium: '2%',
iron: '22%',
},
{
name: 'KitKat',
calories: 518,
fat: 26.0,
carbs: 65,
protein: 7,
sodium: 54,
calcium: '12%',
iron: '6%',
},
]);
</script>

39
io.sc.platform.core.frontend/src/platform/components/grid/WTreeGrid.vue

@ -0,0 +1,39 @@
<template>
<q-table :binary-state-sort="true" column-sort-order="ad" :v-bind="attrs">
<template #top>
<div class="row">
<div class="col">{{ attrs.title }}</div>
<div class="col items-end">
<q-btn label="dksfj"></q-btn>
</div>
</div>
</template>
</q-table>
</template>
<script setup lang="ts">
import { useAttrs } from 'vue';
import { useI18n } from 'vue-i18n';
import { Tools } from '@/platform/utils/Tools';
const attrs = useAttrs();
const { t } = useI18n();
for (const column of attrs.columns) {
if (Tools.isUndefinedOrNull(column.label)) {
column.label = t(column.name);
}
if (Tools.isUndefinedOrNull(column.field)) {
column.field = column.name;
}
if (Tools.isUndefinedOrNull(column.align)) {
column.align = 'left';
}
if (Tools.isUndefinedOrNull(column.sortable)) {
column.sortable = true;
}
if (Tools.isUndefinedOrNull(column.sortOrder)) {
column.sortOrder = 'da';
}
}
</script>

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

@ -8,6 +8,7 @@ import WColorInputPalette from './widget/color/WColorInputPalette.vue';
import WPosition from './widget/position/WPosition.vue'; import WPosition from './widget/position/WPosition.vue';
import WCodemirror from './widget/codemirror/WCodemirror.vue'; import WCodemirror from './widget/codemirror/WCodemirror.vue';
import WSelect from './widget/select/WSelect.vue'; import WSelect from './widget/select/WSelect.vue';
import WListGrid from './grid/WListGrid.vue';
import WTreeGrid from './tree/WTreeGrid.vue'; import WTreeGrid from './tree/WTreeGrid.vue';
import WDialog from './dialog/WDialog.vue'; import WDialog from './dialog/WDialog.vue';
@ -28,6 +29,7 @@ export default {
app.component('WPosition', WPosition); app.component('WPosition', WPosition);
app.component('WCodemirror', WCodemirror); app.component('WCodemirror', WCodemirror);
app.component('WSelect', WSelect); app.component('WSelect', WSelect);
app.component('WListGrid', WListGrid);
app.component('WTreeGrid', WTreeGrid); app.component('WTreeGrid', WTreeGrid);
app.component('WDialog', WDialog); app.component('WDialog', WDialog);
@ -48,6 +50,7 @@ export {
WPosition, WPosition,
WCodemirror, WCodemirror,
WSelect, WSelect,
WListGrid,
WTreeGrid, WTreeGrid,
WDialog, WDialog,
PlatformDialog, PlatformDialog,

10
io.sc.platform.core.frontend/src/platform/components/tree/WTreeGrid.vue

@ -104,7 +104,7 @@ const getTicked = () => {
result.add(ticked); result.add(ticked);
} }
for (const ticked of tickeds) { for (const ticked of tickeds) {
getAllParentIds(nodesCache.get(ticked).parentId, result); getAllParentIds(nodesCache.get(ticked).parent, result);
} }
} }
return [...result]; return [...result];
@ -115,7 +115,7 @@ const getAllParentIds = (parentId, result) => {
const parent = nodesCache.get(parentId); const parent = nodesCache.get(parentId);
if (parent) { if (parent) {
result.add(parent.id); result.add(parent.id);
getAllParentIds(parent.parentId, result); getAllParentIds(parent.parent, result);
} }
} }
}; };
@ -125,9 +125,9 @@ const getCascadeParentIds = (id) => {
let node = nodesCache.get(id); let node = nodesCache.get(id);
if (node) { if (node) {
result.push(id); result.push(id);
while (node.parentId) { while (node.parent) {
result.push(node.parentId); result.push(node.parent);
node = nodesCache.get(node.parentId); node = nodesCache.get(node.parent);
} }
} }
return result; return result;

1
io.sc.platform.core.frontend/src/platform/index.ts

@ -105,6 +105,7 @@ export {
WPosition, WPosition,
WCodemirror, WCodemirror,
WSelect, WSelect,
WListGrid,
WTreeGrid, WTreeGrid,
PlatformDialog, PlatformDialog,
PlatformDrawer, PlatformDrawer,

15
io.sc.platform.core.frontend/src/platform/plugin/manager/MenuManager.ts

@ -30,23 +30,23 @@ class MenuManager {
* @returns * @returns
*/ */
public static buildMenus(remoteMenus: MenuItemType[] = []) { public static buildMenus(remoteMenus: MenuItemType[] = []) {
// 由于远程菜单的 id 和 parentId 均为 uuid, 而本地菜单的 id 和 parentId 均为 name, 需要进行统一 // 由于远程菜单的 id 和 parent 均为 uuid, 而本地菜单的 id 和 parent 均为 name, 需要进行统一
// 将远程菜单的 id 和 parentId 转换为 name // 将远程菜单的 id 和 parent 转换为 name
const remoteCache: Map<string, string> = new Map<string, string>(); const remoteCache: Map<string, string> = new Map<string, string>();
for (const menu of remoteMenus) { for (const menu of remoteMenus) {
remoteCache.set(menu.id, menu.name); remoteCache.set(menu.id, menu.name);
} }
for (const menu of remoteMenus) { for (const menu of remoteMenus) {
menu.id = menu.name; menu.id = menu.name;
if (menu.parentId) { if (menu.parent) {
const parentName = remoteCache.get(menu.parentId); const parentName = remoteCache.get(menu.parent);
if (parentName) { if (parentName) {
menu.parentId = parentName; menu.parent = parentName;
} else { } else {
menu.parentId = null; menu.parent = null;
} }
} else { } else {
menu.parentId = null; menu.parent = null;
} }
} }
@ -54,6 +54,7 @@ class MenuManager {
const mergedCache: Map<string, MenuItemType> = new Map<string, MenuItemType>(); const mergedCache: Map<string, MenuItemType> = new Map<string, MenuItemType>();
const result: MenuItemType[] = []; const result: MenuItemType[] = [];
for (const menu of MenuManager.#localMenus) { for (const menu of MenuManager.#localMenus) {
menu.parent = menu.parent || menu.parentId;
result.push(menu); result.push(menu);
mergedCache.set(menu.id, menu); mergedCache.set(menu.id, menu);
} }

1
io.sc.platform.core.frontend/src/platform/types/MenuItemType.ts

@ -1,6 +1,7 @@
export type MenuItemType = { export type MenuItemType = {
type: string; type: string;
parentId: string | null; parentId: string | null;
parent: string | null;
id: string; id: string;
name: string; name: string;
titleI18nKey: string; titleI18nKey: string;

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

@ -26,6 +26,15 @@ class Tools {
return obj == null || typeof obj == 'undefined' || obj == ''; return obj == null || typeof obj == 'undefined' || obj == '';
} }
/**
*
* @param obj
* @returns
*/
public static isString(obj: any): boolean {
return !Tools.isUndefinedOrNull(obj) && typeof obj === 'string';
}
/** /**
* *
* @param obj * @param obj

2
io.sc.platform.core.frontend/src/platform/utils/TreeBuilder.ts

@ -3,7 +3,7 @@ import { Tools } from '.';
class TreeBuilder { class TreeBuilder {
public static build( public static build(
list: any[] = [], list: any[] = [],
parentIdPropertyName: string = 'parentId', parentIdPropertyName: string = 'parent',
idPropertyName: string = 'id', idPropertyName: string = 'id',
childrenPropertyName: string = 'children', childrenPropertyName: string = 'children',
orderPropertyName: string = '', orderPropertyName: string = '',

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

@ -46,5 +46,17 @@
"meta": { "meta": {
"permissions": ["/testcase/treeGrid/**/*"] "permissions": ["/testcase/treeGrid/**/*"]
} }
},
{
"name": "route.testcase.table",
"path": "testcase/table",
"parent": "/",
"priority": 0,
"component": "component.testcase.table",
"componentPath": "@/views/Table.vue",
"redirect": null,
"meta": {
"permissions": ["/testcase/table/**/*"]
}
} }
] ]

54
io.sc.platform.core.frontend/src/views/Table.vue

@ -0,0 +1,54 @@
<template>
<w-list-grid
:tree="true"
title="User List"
:no-action-icon="true"
:target-object-name="$t('菜单')"
:actions="[
'query',
'refresh',
'expandAll',
'selectAll',
'separator',
'add',
'clone',
'edit',
'remove',
'removeAll',
'separator',
'detail',
'addTop',
'addChild',
]"
:columns="columns"
:auto-fetch-data="true"
:data-url="Environment.apiContextPath('/api/system/menu/allMenus')"
></w-list-grid>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { Environment } from '@/platform';
const { t } = useI18n();
const columns = [
{
name: 'name',
required: true,
label: 'Dessert (100g serving)',
align: 'left',
field: 'name',
sortable: true,
},
{ name: 'calories', align: 'center', label: 'Calories', field: 'calories', sortable: true },
{ name: 'fat', label: 'Fat (g)', field: 'fat', sortable: true },
{ name: 'carbs', label: 'Carbs (g)', field: 'carbs' },
{ name: 'protein', label: 'Protein (g)', field: 'protein' },
{ name: 'sodium', label: 'Sodium (mg)', field: 'sodium' },
{ name: 'calcium', label: 'Calcium (%)', field: 'calcium', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) },
{ name: 'iron', label: 'Iron (%)', field: 'iron', sortable: true, sort: (a, b) => parseInt(a, 10) - parseInt(b, 10) },
];
</script>

48
io.sc.platform.core.frontend/src/views/TreeGrid.vue

@ -1,17 +1,5 @@
<template> <template>
<div> <w-tree-grid title="Hello" :columns="columns" :rows="data"></w-tree-grid>
<w-tree-grid
ref="treeGrid"
title="机构树"
:nodes="nodes"
label-key="titleI18nKey"
label-i18n
label-empty="--------------------"
:actions="actions"
tick-strategy="leaf"
/>
<q-btn label="ok" @click="ok"></q-btn>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, toRaw, onMounted } from 'vue'; import { ref, toRaw, onMounted } from 'vue';
@ -20,39 +8,11 @@ import { Environment, axios, BackendTools } from '@/platform';
const { t } = useI18n(); const { t } = useI18n();
const treeGrid = ref(); const columns = [
const nodes = ref([]);
const selected = [];
const ticked = [];
const expanded = [];
const actions = [
{ {
name: 'refresh', name: 'loginName',
label: '刷新',
},
{
name: 'expandAll',
label: '全部展开',
},
{
name: 'selectAll',
label: '全部选择',
},
{
name: 'save',
label: '保存',
}, },
]; ];
onMounted(() => { const data = [{ loginName: 'admin' }, { loginName: 'wsp' }];
axios.get(Environment.apiContextPath('/api/system/menu?pageable=false')).then((response) => {
treeGrid.value.setNodes(response.data.content);
});
});
const ok = () => {
console.log(treeGrid.value.getCascadeParentIds(treeGrid.value.getSelected()));
console.log(treeGrid.value.getCascadeChildrenIds(treeGrid.value.getSelected()));
console.log(treeGrid.value.getSelectedNode(treeGrid.value.getSelected()));
};
</script> </script>

2
io.sc.platform.core.frontend/template-project/.npmrc

@ -8,4 +8,4 @@ email=
# 登录 npm 仓库的用户认证信息, 在 npm publish 时使用, publish 的 npm registry 在 package.json 文件中 publishConfig 部分配置 # 登录 npm 仓库的用户认证信息, 在 npm publish 时使用, publish 的 npm registry 在 package.json 文件中 publishConfig 部分配置
# _authToken 可通过以下命令获取 # _authToken 可通过以下命令获取
# curl -X PUT -H "Content-Type:application/json" -d '{"_id":"org.couchdb.user:admin","name":"admin","password":"admin"}' http://nexus.sc.io:8000/repository/npm-releases/-/user/org.couchdb.user:admin # curl -X PUT -H "Content-Type:application/json" -d '{"_id":"org.couchdb.user:admin","name":"admin","password":"admin"}' http://nexus.sc.io:8000/repository/npm-releases/-/user/org.couchdb.user:admin
//nexus.sc.io:8000/repository/npm-releases/:_authToken=NpmToken.25afcf59-9193-3068-bcfa-faf76ceadb13 //nexus.sc.io:8000/repository/npm-releases/:_authToken=NpmToken.193db44c-7ca5-3cb6-a990-d24b93fb0d10

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

@ -1,6 +1,6 @@
{ {
"name": "platform-core", "name": "platform-core",
"version": "8.1.42", "version": "8.1.47",
"description": "前端核心包,用于快速构建前端的脚手架", "description": "前端核心包,用于快速构建前端的脚手架",
"private": false, "private": false,
"keywords": [], "keywords": [],
@ -91,7 +91,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.42", "platform-core": "8.1.47",
"quasar": "2.13.0", "quasar": "2.13.0",
"tailwindcss": "3.3.5", "tailwindcss": "3.3.5",
"vue": "3.3.7", "vue": "3.3.7",

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

@ -6,12 +6,14 @@ import dialog from '@/views/Dialog.vue';
import codemirror from '@/views/Codemirror.vue'; import codemirror from '@/views/Codemirror.vue';
import select from '@/views/Select.vue'; import select from '@/views/Select.vue';
import treeGrid from '@/views/TreeGrid.vue'; import treeGrid from '@/views/TreeGrid.vue';
import table from '@/views/Table.vue';
const localComponents = { const localComponents = {
'component.testcase.dialog': dialog, 'component.testcase.dialog': dialog,
'component.testcase.codemirror': codemirror, 'component.testcase.codemirror': codemirror,
'component.testcase.select': select, 'component.testcase.select': select,
'component.testcase.treeGrid': treeGrid, 'component.testcase.treeGrid': treeGrid,
'component.testcase.table': table,
}; };
export default localComponents; export default localComponents;

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

@ -3,5 +3,6 @@
"menu.testcase.codemirror": "CodeMirror", "menu.testcase.codemirror": "CodeMirror",
"menu.testcase.dialog": "Dialog", "menu.testcase.dialog": "Dialog",
"menu.testcase.select": "Select", "menu.testcase.select": "Select",
"menu.testcase.treeGrid": "Tree Grid" "menu.testcase.treeGrid": "Tree Grid",
"menu.testcase.table": "Table"
} }

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

@ -3,5 +3,6 @@
"menu.testcase.codemirror": "CodeMirror", "menu.testcase.codemirror": "CodeMirror",
"menu.testcase.dialog": "Dialog", "menu.testcase.dialog": "Dialog",
"menu.testcase.select": "Select", "menu.testcase.select": "Select",
"menu.testcase.treeGrid": "Tree Grid" "menu.testcase.treeGrid": "Tree Grid",
"menu.testcase.table": "Table"
} }

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

@ -3,5 +3,6 @@
"menu.testcase.codemirror": "CodeMirror", "menu.testcase.codemirror": "CodeMirror",
"menu.testcase.dialog": "Dialog", "menu.testcase.dialog": "Dialog",
"menu.testcase.select": "Select", "menu.testcase.select": "Select",
"menu.testcase.treeGrid": "Tree Grid" "menu.testcase.treeGrid": "Tree Grid",
"menu.testcase.table": "Table"
} }

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

@ -53,5 +53,14 @@
"titleI18nKey": "menu.testcase.treeGrid", "titleI18nKey": "menu.testcase.treeGrid",
"icon": "bi-palette", "icon": "bi-palette",
"routeName": "route.testcase.treeGrid" "routeName": "route.testcase.treeGrid"
},
{
"type": "ROUTE",
"order": 400,
"parentId": "menu.testcase",
"id": "menu.testcase.table",
"titleI18nKey": "menu.testcase.table",
"icon": "bi-palette",
"routeName": "route.testcase.table"
} }
] ]

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

@ -46,5 +46,17 @@
"meta": { "meta": {
"permissions": ["/testcase/treeGrid/**/*"] "permissions": ["/testcase/treeGrid/**/*"]
} }
},
{
"name": "route.testcase.table",
"path": "testcase/table",
"parent": "/",
"priority": 0,
"component": "component.testcase.table",
"componentPath": "@/views/Table.vue",
"redirect": null,
"meta": {
"permissions": ["/testcase/table/**/*"]
}
} }
] ]

53
io.sc.platform.core.frontend/template-project/src/views/Table.vue

@ -0,0 +1,53 @@
<template>
<div>
<w-tree-grid ref="corporationTreeGridRef" title="法人树" label-key="name" :actions="corporationConfigure.actions" />
</div>
</template>
<script setup lang="ts">
import { ref, onMounted, toRaw } from 'vue';
import { useRoute } from 'vue-router';
import { useI18n } from 'vue-i18n';
import { Environment, axios } from '@/platform';
const route = useRoute();
const { t } = useI18n();
const corporationTreeGridRef = ref();
const corporationConfigure = {
actions: [
{
name: 'refresh',
label: t('refresh'),
click: () => {},
},
{
name: 'addRoot',
label: t('system.corporation.action.addTop'),
click: () => {},
},
{
name: 'addChild',
label: t('system.corporation.action.addChild'),
click: () => {},
},
{
name: 'edit',
label: t('edit'),
click: () => {},
},
{
name: 'delete',
label: t('delete'),
click: () => {},
},
],
};
onMounted(() => {
axios.get(Environment.apiContextPath('/api/system/corporation?pageable=false&sortBy=name')).then((response) => {
corporationTreeGridRef.value.setNodes(response.data.content);
});
});
</script>

48
io.sc.platform.core.frontend/template-project/src/views/TreeGrid.vue

@ -1,17 +1,5 @@
<template> <template>
<div> <w-tree-grid title="Hello" :columns="columns" :rows="data"></w-tree-grid>
<w-tree-grid
ref="treeGrid"
title="机构树"
:nodes="nodes"
label-key="titleI18nKey"
label-i18n
label-empty="--------------------"
:actions="actions"
tick-strategy="leaf"
/>
<q-btn label="ok" @click="ok"></q-btn>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, toRaw, onMounted } from 'vue'; import { ref, toRaw, onMounted } from 'vue';
@ -20,39 +8,11 @@ import { Environment, axios, BackendTools } from '@/platform';
const { t } = useI18n(); const { t } = useI18n();
const treeGrid = ref(); const columns = [
const nodes = ref([]);
const selected = [];
const ticked = [];
const expanded = [];
const actions = [
{ {
name: 'refresh', name: 'loginName',
label: '刷新',
},
{
name: 'expandAll',
label: '全部展开',
},
{
name: 'selectAll',
label: '全部选择',
},
{
name: 'save',
label: '保存',
}, },
]; ];
onMounted(() => { const data = [{ loginName: 'admin' }, { loginName: 'wsp' }];
axios.get(Environment.apiContextPath('/api/system/menu?pageable=false')).then((response) => {
treeGrid.value.setNodes(response.data.content);
});
});
const ok = () => {
console.log(treeGrid.value.getCascadeParentIds(treeGrid.value.getSelected()));
console.log(treeGrid.value.getCascadeChildrenIds(treeGrid.value.getSelected()));
console.log(treeGrid.value.getSelectedNode(treeGrid.value.getSelected()));
};
</script> </script>

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

@ -14,5 +14,6 @@ dependencies {
"com.google.guava:guava:${guava_version}", "com.google.guava:guava:${guava_version}",
"com.beust:jcommander:${jcommander_version}", "com.beust:jcommander:${jcommander_version}",
"net.lingala.zip4j:zip4j:${zip4j_version}", "net.lingala.zip4j:zip4j:${zip4j_version}",
"com.github.seancfoley:ipaddress:${ipaddress_version}",
) )
} }

4
io.sc.platform.core/src/main/java/io/sc/platform/core/initializer/ApplicationInitializer.java

@ -26,7 +26,7 @@ public interface ApplicationInitializer extends Ordered {
* @return 应用初始化器名称 * @return 应用初始化器名称
*/ */
public default String getName(){ public default String getName(){
return this.getClass().getSimpleName(); return this.getClass().getName() + ".name";
} }
/** /**
@ -34,7 +34,7 @@ public interface ApplicationInitializer extends Ordered {
* @return 应用初始化器描述 * @return 应用初始化器描述
*/ */
public default String getDescription(){ public default String getDescription(){
return this.getClass().getSimpleName(); return this.getClass().getName() + ".description";
} }
/** /**

47
io.sc.platform.core/src/main/java/io/sc/platform/core/util/IpUtil.java

@ -0,0 +1,47 @@
package io.sc.platform.core.util;
import javax.servlet.http.HttpServletRequest;
import inet.ipaddr.IPAddressString;
/**
* IP 地址工具类
* @author wangshaoping
*
*/
public class IpUtil {
public static final String UNKNOW_IP ="0.0.0.0";
/**
* 获取客户端 IP 地址
* @param request Http 请求
* @return 客户端 IP 地址
*/
public static String getRemoteAddress(HttpServletRequest request){
IPAddressString ipAdress =getRemoteIPAddressString(request);
if(ipAdress!=null){
return ipAdress.getAddress().toFullString();
}
return null;
}
private static IPAddressString getRemoteIPAddressString(HttpServletRequest request){
String ip =request.getHeader("x-forwarded-for");
if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip)){
ip =request.getHeader("Proxy-Client-IP");
}
if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip)){
ip =request.getHeader("WL-Proxy-Client-IP");
}
if(ip==null || ip.length()==0 || "unknown".equalsIgnoreCase(ip)){
ip =request.getRemoteAddr();
}
IPAddressString ipAdress =new IPAddressString(ip);
if(ipAdress!=null && ipAdress.isIPAddress()){
return ipAdress;
}
//当无法正确获取IP时,系统采用特殊IP地址作为IP地址
//这样可以避免因为无法获取IP而出现无法认证登录的问题
return new IPAddressString(UNKNOW_IP);
}
}

124
io.sc.platform.core/src/main/resources/io/sc/platform/core/config/logback-spring2.xml

@ -0,0 +1,124 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 自动扫描本文件,如果发生变化,则重新初始化日志系统,并设置每隔5秒钟扫描一次 -->
<configuration debug="false" scan="true" scanPeriod="5 seconds">
<!--
以下为 logback 的 spring 扩展支持的功能,即支持从 application.properties 文件中获取属性,并在此文件中采用 ${} 方式使用。
要使用此功能,必须使用 logback-ext-spring 扩展 jar 包,以 gradle 构建系统,则需要加入以下依赖
dependencies {
compile(
"org.logback-extensions:logback-ext-spring:0.1.2"
)
}
-->
<property name="homedir" value="${application.home.dir}"/>
<property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{36} - %msg%n"/>
<!-- 在控制台中输出日志 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder><pattern>${pattern}</pattern></encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 在磁盘文件中输出日志(error) -->
<appender name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder><pattern>${pattern}</pattern></encoder>
<file>${homedir}/logs/log-error.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${homedir}/logs/log-error.%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 在磁盘文件中输出日志(warning) -->
<appender name="FILE_WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder><pattern>${pattern}</pattern></encoder>
<file>${homedir}/logs/log-warn.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${homedir}/logs/log-warn.%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>WARN</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 在磁盘文件中输出日志(info) -->
<appender name="FILE_INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder><pattern>${pattern}</pattern></encoder>
<file>${homedir}/logs/log-info.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${homedir}/logs/log-info.%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 在磁盘文件中输出日志(debug) -->
<appender name="FILE_DEBUG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder><pattern>${pattern}</pattern></encoder>
<file>${homedir}/logs/log-debug.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${homedir}/logs/log-debug.%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>DEBUG</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 在磁盘文件中输出日志(trace) -->
<appender name="FILE_TRACE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder><pattern>${pattern}</pattern></encoder>
<file>${homedir}/logs/log-trace.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${homedir}/logs/log-trace.%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>TRACE</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<root level="trace">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE_ERROR" />
<appender-ref ref="FILE_WARN" />
<appender-ref ref="FILE_INFO" />
<appender-ref ref="FILE_DEBUG" />
<appender-ref ref="FILE_TRACE" />
</root>
<!-- 可对不同的日志写入不同的文件示例 -->
<!--
<appender name="RULE_ENGINE_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder><pattern>${pattern}</pattern></encoder>
<file>${homedir}/logs/rule-engine.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${homedir}/logs/rule-engine.%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<logger name="org.wsp.engine.rule.core.code" level="debug" additivity="false">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
<appender-ref ref="RULE_ENGINE_FILE" />
</logger>
-->
</configuration>

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

@ -1,7 +1,9 @@
about=About about=About
action=Action action=Action
add=Add add=Add
addChild=Add Child {object}
addNew=Add addNew=Add
addTop=Add Top {object}
alter=Alter alter=Alter
bottom-left=Bottom Left bottom-left=Bottom Left
bottom-right=Bottom Right bottom-right=Bottom Right
@ -21,7 +23,9 @@ creator=Creator
dataComeFrom=Data Come From dataComeFrom=Data Come From
deepClone=Deep Clone deepClone=Deep Clone
delete=Delete delete=Delete
deleteAll=Delete All
description=Description description=Description
detail=Detail
displayValue=Display Value displayValue=Display Value
download=Download download=Download
edit=Edit edit=Edit

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

@ -1,7 +1,9 @@
about=\u95DC\u65BC about=\u95DC\u65BC
action=\u64CD\u4F5C action=\u64CD\u4F5C
add=\u6DFB\u52A0 add=\u6DFB\u52A0
addChild=\u65B0\u589E\u5B50{object}
addNew=\u65B0\u589E addNew=\u65B0\u589E
addTop=\u65B0\u589E\u9802\u7D1A{object}
alter=\u901A\u77E5 alter=\u901A\u77E5
bottom-left=\u5DE6\u4E0B bottom-left=\u5DE6\u4E0B
bottom-right=\u53F3\u4E0B bottom-right=\u53F3\u4E0B
@ -21,7 +23,9 @@ creator=\u5275\u5EFA\u4EBA
dataComeFrom=\u6578\u64DA\u4F86\u6E90 dataComeFrom=\u6578\u64DA\u4F86\u6E90
deepClone=\u6DF1\u5EA6\u8907\u88FD deepClone=\u6DF1\u5EA6\u8907\u88FD
delete=\u522A\u9664 delete=\u522A\u9664
deleteAll=\u522A\u9664\u5168\u90E8
description=\u63CF\u8FF0 description=\u63CF\u8FF0
detail=\u8A73\u60C5
displayValue=\u986F\u793A\u503C displayValue=\u986F\u793A\u503C
download=\u4E0B\u8F09 download=\u4E0B\u8F09
edit=\u7DE8\u8F2F edit=\u7DE8\u8F2F

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

@ -1,7 +1,9 @@
about=\u5173\u4E8E about=\u5173\u4E8E
action=\u64CD\u4F5C action=\u64CD\u4F5C
add=\u6DFB\u52A0 add=\u6DFB\u52A0
addChild=\u65B0\u589E\u5B50{object}
addNew=\u65B0\u589E addNew=\u65B0\u589E
addTop=\u65B0\u589E\u9876\u7EA7{object}
alter=\u901A\u77E5 alter=\u901A\u77E5
bottom-left=\u5DE6\u4E0B bottom-left=\u5DE6\u4E0B
bottom-right=\u53F3\u4E0B bottom-right=\u53F3\u4E0B
@ -21,7 +23,9 @@ creator=\u521B\u5EFA\u4EBA
dataComeFrom=\u6570\u636E\u6765\u6E90 dataComeFrom=\u6570\u636E\u6765\u6E90
deepClone=\u6DF1\u5EA6\u590D\u5236 deepClone=\u6DF1\u5EA6\u590D\u5236
delete=\u522A\u9664 delete=\u522A\u9664
deleteAll=\u5220\u9664\u5168\u90E8
description=\u63CF\u8FF0 description=\u63CF\u8FF0
detail=\u8BE6\u60C5
displayValue=\u663E\u793A\u503C displayValue=\u663E\u793A\u503C
download=\u4E0B\u8F7D download=\u4E0B\u8F7D
edit=\u7F16\u8F91 edit=\u7F16\u8F91

2
io.sc.platform.developer.doc/asciidoc/9999-appendix/appendix.adoc

@ -1,5 +1,5 @@
include::software/software.adoc[] include::software/software.adoc[]
include::environment/environment.adoc[] #include::environment/environment.adoc[]
include::platform/platform.adoc[] include::platform/platform.adoc[]
include::docker-command/docker-command.adoc[] include::docker-command/docker-command.adoc[]
include::docker-compose/docker-compose.adoc[] include::docker-compose/docker-compose.adoc[]

2
io.sc.platform.developer.doc/asciidoc/index.adoc

@ -33,7 +33,7 @@
include::getting-started/getting-started.adoc[leveloffset=+1] include::getting-started/getting-started.adoc[leveloffset=+1]
include::yu/yu.adoc[leveloffset=+1]
include::platform-extension/platform-extension.adoc[leveloffset=+1] include::platform-extension/platform-extension.adoc[leveloffset=+1]

BIN
io.sc.platform.developer.doc/asciidoc/resources/images/getting-started/windows/install-005.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

After

Width:  |  Height:  |  Size: 699 KiB

2
io.sc.platform.developer.frontend/.npmrc

@ -8,4 +8,4 @@ email=
# 登录 npm 仓库的用户认证信息, 在 npm publish 时使用, publish 的 npm registry 在 package.json 文件中 publishConfig 部分配置 # 登录 npm 仓库的用户认证信息, 在 npm publish 时使用, publish 的 npm registry 在 package.json 文件中 publishConfig 部分配置
# _authToken 可通过以下命令获取 # _authToken 可通过以下命令获取
# curl -X PUT -H "Content-Type:application/json" -d '{"_id":"org.couchdb.user:admin","name":"admin","password":"admin"}' http://nexus.sc.io:8000/repository/npm-releases/-/user/org.couchdb.user:admin # curl -X PUT -H "Content-Type:application/json" -d '{"_id":"org.couchdb.user:admin","name":"admin","password":"admin"}' http://nexus.sc.io:8000/repository/npm-releases/-/user/org.couchdb.user:admin
//nexus.sc.io:8000/repository/npm-releases/:_authToken=NpmToken.25afcf59-9193-3068-bcfa-faf76ceadb13 //nexus.sc.io:8000/repository/npm-releases/:_authToken=NpmToken.193db44c-7ca5-3cb6-a990-d24b93fb0d10

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

@ -1,9 +1,11 @@
{ {
"name": "io.sc.platform.developer.frontend", "name": "io.sc.platform.developer.frontend",
"version": "8.1.13", "version": "8.1.19",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [
],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"scripts": { "scripts": {
@ -77,7 +79,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.42", "platform-core": "8.1.45",
"quasar": "2.13.0", "quasar": "2.13.0",
"tailwindcss": "3.3.5", "tailwindcss": "3.3.5",
"vue": "3.3.7", "vue": "3.3.7",

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

@ -12,6 +12,7 @@ import Components from '@/views/plugin/Components.vue';
import Directories from '@/views/plugin/Directories.vue'; import Directories from '@/views/plugin/Directories.vue';
import FrontendModule from '@/views/plugin/FrontendModule.vue'; import FrontendModule from '@/views/plugin/FrontendModule.vue';
import FrontendRoutes from '@/views/plugin/FrontendRoutes.vue'; import FrontendRoutes from '@/views/plugin/FrontendRoutes.vue';
import Initializer from '@/views/plugin/Initializer.vue';
import JsonSerializers from '@/views/plugin/JsonSerializers.vue'; import JsonSerializers from '@/views/plugin/JsonSerializers.vue';
import Menus from '@/views/plugin/Menus.vue'; import Menus from '@/views/plugin/Menus.vue';
import Messages from '@/views/plugin/Messages.vue'; import Messages from '@/views/plugin/Messages.vue';
@ -35,6 +36,7 @@ const localComponents = {
'component.developer.plugin.Directories': Directories, 'component.developer.plugin.Directories': Directories,
'component.developer.plugin.FrontendModule': FrontendModule, 'component.developer.plugin.FrontendModule': FrontendModule,
'component.developer.plugin.FrontendRoutes': FrontendRoutes, 'component.developer.plugin.FrontendRoutes': FrontendRoutes,
'component.developer.plugin.Initializer': Initializer,
'component.developer.plugin.JsonSerializers': JsonSerializers, 'component.developer.plugin.JsonSerializers': JsonSerializers,
'component.developer.plugin.Menus': Menus, 'component.developer.plugin.Menus': Menus,
'component.developer.plugin.Messages': Messages, 'component.developer.plugin.Messages': Messages,

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

@ -11,6 +11,7 @@
"menu.developer.plugin.applicationProperties" : "Application Properties", "menu.developer.plugin.applicationProperties" : "Application Properties",
"menu.developer.plugin.components" : "Auto Scan Components", "menu.developer.plugin.components" : "Auto Scan Components",
"menu.developer.plugin.directories" : "Directories", "menu.developer.plugin.directories" : "Directories",
"menu.developer.plugin.initializer" : "Initializer",
"menu.developer.plugin.jsonSerializers" : "Json Serializer", "menu.developer.plugin.jsonSerializers" : "Json Serializer",
"menu.developer.plugin.messages" : "I18n Messages", "menu.developer.plugin.messages" : "I18n Messages",
"menu.developer.plugin.restartProperties" : "Restart Properties", "menu.developer.plugin.restartProperties" : "Restart Properties",

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

@ -11,6 +11,7 @@
"menu.developer.plugin.applicationProperties" : "Application Properties", "menu.developer.plugin.applicationProperties" : "Application Properties",
"menu.developer.plugin.components" : "自動掃描組件", "menu.developer.plugin.components" : "自動掃描組件",
"menu.developer.plugin.directories" : "目錄", "menu.developer.plugin.directories" : "目錄",
"menu.developer.plugin.initializer" : "初始化器",
"menu.developer.plugin.jsonSerializers" : "Json 序列化器", "menu.developer.plugin.jsonSerializers" : "Json 序列化器",
"menu.developer.plugin.messages" : "國際化多語言消息", "menu.developer.plugin.messages" : "國際化多語言消息",
"menu.developer.plugin.restartProperties" : "Restart Properties", "menu.developer.plugin.restartProperties" : "Restart Properties",

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

@ -11,6 +11,7 @@
"menu.developer.plugin.applicationProperties" : "Application Properties", "menu.developer.plugin.applicationProperties" : "Application Properties",
"menu.developer.plugin.components" : "自动扫描组件", "menu.developer.plugin.components" : "自动扫描组件",
"menu.developer.plugin.directories" : "目录", "menu.developer.plugin.directories" : "目录",
"menu.developer.plugin.initializer" : "初始化器",
"menu.developer.plugin.jsonSerializers" : "Json 序列化器", "menu.developer.plugin.jsonSerializers" : "Json 序列化器",
"menu.developer.plugin.messages" : "国际化多语言消息", "menu.developer.plugin.messages" : "国际化多语言消息",
"menu.developer.plugin.restartProperties" : "Restart Properties", "menu.developer.plugin.restartProperties" : "Restart Properties",

4
io.sc.platform.developer.frontend/src/menus/menus.json

@ -31,8 +31,11 @@
{"type":"ROUTE", "order":300, "parentId":"menu.developer.springboot", "id":"menu.developer.springboot.environment", "titleI18nKey":"menu.developer.springboot.environment", "icon":"bi-patch-check", "routeName":"route.developer.springboot.environment"}, {"type":"ROUTE", "order":300, "parentId":"menu.developer.springboot", "id":"menu.developer.springboot.environment", "titleI18nKey":"menu.developer.springboot.environment", "icon":"bi-patch-check", "routeName":"route.developer.springboot.environment"},
/*/spring boot /*/ /*/spring boot /*/
{"type":"ROUTE", "order":400, "parentId":"menu.developer.springboot", "id":"menu.developer.springboot.autoconfigure", "titleI18nKey":"menu.developer.springboot.autoconfigure", "icon":"bi-recycle", "routeName":"route.developer.springboot.autoconfigure"}, {"type":"ROUTE", "order":400, "parentId":"menu.developer.springboot", "id":"menu.developer.springboot.autoconfigure", "titleI18nKey":"menu.developer.springboot.autoconfigure", "icon":"bi-recycle", "routeName":"route.developer.springboot.autoconfigure"},
/*/*/ /*/*/
{"type":"GROUP", "order":400, "parentId":"menu.developer", "id":"menu.developer.plugin", "titleI18nKey":"menu.developer.plugin", "icon":"bi-plug"}, {"type":"GROUP", "order":400, "parentId":"menu.developer", "id":"menu.developer.plugin", "titleI18nKey":"menu.developer.plugin", "icon":"bi-plug"},
/*//*/
{"type":"ROUTE", "order":50, "parentId":"menu.developer.plugin", "id":"menu.developer.plugin.initializer", "titleI18nKey":"menu.developer.plugin.initializer", "icon":"bi-list-ol", "routeName":"route.developer.plugin.initializer"},
/*//*/ /*//*/
{"type":"ROUTE", "order":100, "parentId":"menu.developer.plugin", "id":"menu.developer.plugin.parameters", "titleI18nKey":"menu.developer.plugin.parameters", "icon":"bi-list-ol", "routeName":"route.developer.plugin.parameters"}, {"type":"ROUTE", "order":100, "parentId":"menu.developer.plugin", "id":"menu.developer.plugin.parameters", "titleI18nKey":"menu.developer.plugin.parameters", "icon":"bi-list-ol", "routeName":"route.developer.plugin.parameters"},
/*//*/ /*//*/
@ -63,6 +66,7 @@
{"type":"ROUTE", "order":1400, "parentId":"menu.developer.plugin", "id":"menu.developer.plugin.p6spy", "titleI18nKey":"menu.developer.plugin.p6spy", "icon":"bi-filetype-sql", "routeName":"route.developer.plugin.p6spy"}, {"type":"ROUTE", "order":1400, "parentId":"menu.developer.plugin", "id":"menu.developer.plugin.p6spy", "titleI18nKey":"menu.developer.plugin.p6spy", "icon":"bi-filetype-sql", "routeName":"route.developer.plugin.p6spy"},
/*//Swagger*/ /*//Swagger*/
{"type":"ROUTE", "order":1500, "parentId":"menu.developer.plugin", "id":"menu.developer.plugin.swagger", "titleI18nKey":"menu.developer.plugin.swagger", "icon":"bi-filetype-html", "routeName":"route.developer.plugin.swagger"}, {"type":"ROUTE", "order":1500, "parentId":"menu.developer.plugin", "id":"menu.developer.plugin.swagger", "titleI18nKey":"menu.developer.plugin.swagger", "icon":"bi-filetype-html", "routeName":"route.developer.plugin.swagger"},
/*/*/ /*/*/
{"type":"GROUP", "order":500, "parentId":"menu.developer", "id":"menu.developer.frontend", "titleI18nKey":"menu.developer.frontend", "icon":"bi-layout-text-window"}, {"type":"GROUP", "order":500, "parentId":"menu.developer", "id":"menu.developer.frontend", "titleI18nKey":"menu.developer.frontend", "icon":"bi-layout-text-window"},
/*//*/ /*//*/

15
io.sc.platform.developer.frontend/src/routes/routes.json

@ -149,6 +149,21 @@
] ]
} }
}, },
{
"name": "route.developer.plugin.initializer",
"path": "developer/plugin/initializer",
"parent": "/",
"priority": 0,
"module": "io.sc.platform.developer.frontend",
"component": "component.developer.plugin.Initializer",
"componentPath": "@/views/plugin/Initializer.vue",
"redirect": null,
"meta": {
"permissions": [
"/system/developer/plugin/initializer/**/*"
]
}
},
{ {
"name": "route.developer.plugin.jsonSerializers", "name": "route.developer.plugin.jsonSerializers",
"path": "developer/plugin/jsonSerializers", "path": "developer/plugin/jsonSerializers",

26
io.sc.platform.developer.frontend/src/views/plugin/Initializer.vue

@ -0,0 +1,26 @@
<template>
<div class="row q-px-md q-py-md">
{{ $t('menu.developer.plugin.initializer') }}
</div>
<q-table :rows="rows" :columns="columns" row-key="id" :pagination="{ rowsPerPage: 1000 }" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
import { useI18n } from 'vue-i18n';
import { Environment, axios } from 'platform-core';
const { t } = useI18n();
const columns = [
{ width: '20%', field: 'order', label: t('order'), align: 'right' },
{ width: '40%', field: 'name', label: t('name'), format: (value) => t(value), align: 'left' },
{ width: '40%', field: 'description', label: t('description'), format: (value) => t(value), align: 'left' },
{ width: '40%', field: 'id', label: t('className'), align: 'left' },
];
const rows = ref([]);
axios.get(Environment.apiContextPath('/api/developer/plugins/initializer')).then((response) => {
rows.value = response.data;
});
</script>

31
io.sc.platform.developer/src/main/java/io/sc/platform/developer/plugins/controller/InitializerWebController.java

@ -0,0 +1,31 @@
package io.sc.platform.developer.plugins.controller;
import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice;
import io.sc.platform.core.initializer.ApplicationInitializer;
import io.sc.platform.core.util.Sorter;
import io.sc.platform.developer.plugins.wrapper.InitializerWrapper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
@Controller
@RequestMapping("/api/developer/plugins/initializer")
public class InitializerWebController {
@GetMapping("")
@ResponseBody
public List<InitializerWrapper> initializer(){
List<ApplicationInitializer> initializers =new ArrayList<>();
ServiceLoader<ApplicationInitializer> loader = ServiceLoader.load(ApplicationInitializer.class,Thread.currentThread().getContextClassLoader());
loader.iterator().forEachRemaining(item -> {
initializers.add(item);
});
Sorter.sort(initializers);
return InitializerWrapper.from(initializers);
}
}

67
io.sc.platform.developer/src/main/java/io/sc/platform/developer/plugins/wrapper/InitializerWrapper.java

@ -0,0 +1,67 @@
package io.sc.platform.developer.plugins.wrapper;
import io.sc.platform.core.initializer.ApplicationInitializer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class InitializerWrapper {
private String id;
private String name;
private String description;
private int order;
public static List<InitializerWrapper> from(List<ApplicationInitializer> initializers){
if(initializers==null || initializers.isEmpty()){
return Collections.emptyList();
}
List<InitializerWrapper> wrappers =new ArrayList<>();
for(ApplicationInitializer initializer : initializers){
wrappers.add(from(initializer));
}
return wrappers;
}
public static InitializerWrapper from(ApplicationInitializer initializer){
InitializerWrapper wrapper =new InitializerWrapper();
wrapper.setId(initializer.getId());
wrapper.setName(initializer.getName());
wrapper.setDescription(initializer.getDescription());
wrapper.setOrder(initializer.getOrder());
return wrapper;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public int getOrder() {
return order;
}
public void setOrder(int order) {
this.order = order;
}
}

5
io.sc.platform.developer/src/main/resources/META-INF/platform/plugins/components.json

@ -0,0 +1,5 @@
{
"includes":[
"io.sc.platform.developer.plugins.controller"
]
}

98
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/api/AgentVo.java

@ -0,0 +1,98 @@
package io.sc.platform.flowable.api;
import io.sc.platform.orm.api.vo.CorporationAuditorVo;
import java.util.Date;
public class AgentVo extends CorporationAuditorVo {
private String id;
private String loginName;
private String userName;
private String agentLoginName;
private String agentUserName;
private Date startDate;
private Date endDate;
private String reasons;
private Boolean effective;
private String comments;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLoginName() {
return loginName;
}
public void setLoginName(String loginName) {
this.loginName = loginName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getAgentLoginName() {
return agentLoginName;
}
public void setAgentLoginName(String agentLoginName) {
this.agentLoginName = agentLoginName;
}
public String getAgentUserName() {
return agentUserName;
}
public void setAgentUserName(String agentUserName) {
this.agentUserName = agentUserName;
}
public Date getStartDate() {
return startDate;
}
public void setStartDate(Date startDate) {
this.startDate = startDate;
}
public Date getEndDate() {
return endDate;
}
public void setEndDate(Date endDate) {
this.endDate = endDate;
}
public String getReasons() {
return reasons;
}
public void setReasons(String reasons) {
this.reasons = reasons;
}
public Boolean getEffective() {
return effective;
}
public void setEffective(Boolean effective) {
this.effective = effective;
}
public String getComments() {
return comments;
}
public void setComments(String comments) {
this.comments = comments;
}
}

97
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/api/ProcessVo.java

@ -0,0 +1,97 @@
package io.sc.platform.flowable.api;
import io.sc.platform.flowable.enums.ProcessStatus;
import io.sc.platform.orm.api.vo.CorporationAuditorVo;
public class ProcessVo extends CorporationAuditorVo {
private String id;
private String category;
private String key;
private String name;
private String description;
private String deployedId;
private Integer version;
private String xml;
private ProcessStatus status;
private Boolean canClaimTask;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDeployedId() {
return deployedId;
}
public void setDeployedId(String deployedId) {
this.deployedId = deployedId;
}
public Integer getVersion() {
return version;
}
public void setVersion(Integer version) {
this.version = version;
}
public String getXml() {
return xml;
}
public void setXml(String xml) {
this.xml = xml;
}
public ProcessStatus getStatus() {
return status;
}
public void setStatus(ProcessStatus status) {
this.status = status;
}
public Boolean getCanClaimTask() {
return canClaimTask;
}
public void setCanClaimTask(Boolean canClaimTask) {
this.canClaimTask = canClaimTask;
}
}

9
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/AgentWebController.java

@ -1,6 +1,7 @@
package io.sc.platform.flowable.controller; package io.sc.platform.flowable.controller;
import io.sc.platform.flowable.jpa.entity.Agent; import io.sc.platform.flowable.api.AgentVo;
import io.sc.platform.flowable.jpa.entity.AgentEntity;
import io.sc.platform.flowable.jpa.repository.AgentRepository; import io.sc.platform.flowable.jpa.repository.AgentRepository;
import io.sc.platform.flowable.service.AgentService; import io.sc.platform.flowable.service.AgentService;
import io.sc.platform.mvc.controller.support.RestCrudController; import io.sc.platform.mvc.controller.support.RestCrudController;
@ -13,19 +14,19 @@ import java.util.Map;
@RestController @RestController
@RequestMapping("/api/flowable/agent") @RequestMapping("/api/flowable/agent")
public class AgentWebController extends RestCrudController<Agent,String, AgentRepository, AgentService> { public class AgentWebController extends RestCrudController<AgentVo, AgentEntity,String, AgentRepository, AgentService> {
@GetMapping("getAvailableAgent") @GetMapping("getAvailableAgent")
public List<UserVo> getAvailableAgent() throws Exception{ public List<UserVo> getAvailableAgent() throws Exception{
return service.listAvailableAgentByUserId(SecurityUtil.getUserId()); return service.listAvailableAgentByUserId(SecurityUtil.getUserId());
} }
@PostMapping("agree/{id}") @PostMapping("agree/{id}")
public Agent agree(@PathVariable(name="id")String id){ public AgentEntity agree(@PathVariable(name="id")String id){
return service.agree(id); return service.agree(id);
} }
@PostMapping("reject/{id}") @PostMapping("reject/{id}")
public Agent reject(@PathVariable(name="id")String id,@RequestBody Map<String,String> data){ public AgentEntity reject(@PathVariable(name="id")String id, @RequestBody Map<String,String> data){
String comments =null; String comments =null;
if(data!=null) { if(data!=null) {
comments =data.get("comments"); comments =data.get("comments");

7
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/controller/FlowableModelerEditorWebController.java

@ -1,12 +1,10 @@
package io.sc.platform.flowable.controller; package io.sc.platform.flowable.controller;
import java.util.List; import java.util.List;
import java.util.Locale;
import java.util.Map; import java.util.Map;
import io.sc.platform.core.Environment; import io.sc.platform.core.Environment;
import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice; import io.sc.platform.core.annotation.IgnoreResponseBodyAdvice;
import io.sc.platform.core.util.LocaleUtil;
import io.sc.platform.flowable.service.FlowableModelerService; import io.sc.platform.flowable.service.FlowableModelerService;
import io.sc.platform.flowable.support.BpmnModelWrapper; import io.sc.platform.flowable.support.BpmnModelWrapper;
import io.sc.platform.flowable.support.FlowableGroupList; import io.sc.platform.flowable.support.FlowableGroupList;
@ -19,7 +17,6 @@ import io.sc.platform.system.role.service.RoleService;
import io.sc.platform.system.user.convertor.UserEntityVoConverter; import io.sc.platform.system.user.convertor.UserEntityVoConverter;
import io.sc.platform.system.user.jpa.entity.UserEntity; import io.sc.platform.system.user.jpa.entity.UserEntity;
import io.sc.platform.system.user.service.UserService; import io.sc.platform.system.user.service.UserService;
import liquibase.pro.packaged.G;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.flowable.bpmn.model.BpmnModel; import org.flowable.bpmn.model.BpmnModel;
import org.flowable.editor.language.json.converter.BpmnJsonConverter; import org.flowable.editor.language.json.converter.BpmnJsonConverter;
@ -31,14 +28,10 @@ import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.data.domain.Page; import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification; import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.JsonNode;
import javax.persistence.criteria.Join;
/** /**
* 流程设计器控制器 * 流程设计器控制器
* @author wangshaoping * @author wangshaoping

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

@ -1,5 +1,6 @@
package io.sc.platform.flowable.controller; package io.sc.platform.flowable.controller;
import io.sc.platform.flowable.api.ProcessVo;
import io.sc.platform.flowable.jpa.entity.ProcessEntity; import io.sc.platform.flowable.jpa.entity.ProcessEntity;
import io.sc.platform.flowable.jpa.repository.ProcessEntityRepository; import io.sc.platform.flowable.jpa.repository.ProcessEntityRepository;
import io.sc.platform.flowable.service.ProcessEntityService; import io.sc.platform.flowable.service.ProcessEntityService;
@ -11,7 +12,7 @@ import org.springframework.web.bind.annotation.RestController;
@RestController @RestController
@RequestMapping("/api/flowable/process") @RequestMapping("/api/flowable/process")
public class ProcessEntityWebController extends RestCrudController<ProcessEntity,String, ProcessEntityRepository, ProcessEntityService> { public class ProcessEntityWebController extends RestCrudController<ProcessVo, ProcessEntity,String, ProcessEntityRepository, ProcessEntityService> {
@PostMapping("deploy/{id}") @PostMapping("deploy/{id}")
public void deploy(@PathVariable(name="id") String id) throws Exception{ public void deploy(@PathVariable(name="id") String id) throws Exception{
service.deploy(id); service.deploy(id);

17
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/initializer/SampleWorkFlowSystemDictionaryInitializer.java

@ -15,24 +15,9 @@ public class SampleWorkFlowSystemDictionaryInitializer implements ApplicationIni
this.dictionaryService = BeanUtil.getBean(applicationContext,DictionaryService.class); this.dictionaryService = BeanUtil.getBean(applicationContext,DictionaryService.class);
} }
@Override
public String getId() {
return this.getClass().getName();
}
@Override
public String getName() {
return "Test BPM System Dictionary Initializer";
}
@Override
public String getDescription() {
return "Test BPM System Dictionary Initializer";
}
@Override @Override
public int getOrder() { public int getOrder() {
return 11000; return 10000;
} }
@Override @Override

20
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/Agent.java → io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/AgentEntity.java

@ -11,8 +11,10 @@ import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import io.sc.platform.flowable.api.AgentVo;
import io.sc.platform.orm.converter.NumericBooleanConverter; import io.sc.platform.orm.converter.NumericBooleanConverter;
import io.sc.platform.orm.entity.AuditorEntity; import io.sc.platform.orm.entity.AuditorEntity;
import io.sc.platform.orm.entity.CorporationAuditorEntity;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
/** /**
@ -20,7 +22,7 @@ import org.hibernate.annotations.GenericGenerator;
*/ */
@Entity @Entity
@Table(name="SYS_AGENT") @Table(name="SYS_AGENT")
public class Agent extends AuditorEntity implements Serializable{ public class AgentEntity extends CorporationAuditorEntity<AgentVo> {
private static final long serialVersionUID = 2228732422179849265L; private static final long serialVersionUID = 2228732422179849265L;
//主键 //主键
@ -74,6 +76,22 @@ public class Agent extends AuditorEntity implements Serializable{
@Size(max=1024) @Size(max=1024)
private String comments; private String comments;
@Override
public AgentVo toVo() {
AgentVo vo =new AgentVo();
CorporationAuditorEntity.toVo(vo,this);
vo.setId(this.getId());
vo.setLoginName(this.getLoginName());
vo.setUserName(this.getUserName());
vo.setAgentLoginName(this.getAgentLoginName());
vo.setAgentUserName(this.getAgentUserName());
vo.setStartDate(this.getStartDate());
vo.setEndDate(this.getEndDate());
vo.setReasons(this.getReasons());
vo.setEffective(this.getEffective());
return vo;
}
public String getId() { public String getId() {
return id; return id;
} }

11
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/entity/ProcessEntity.java

@ -12,9 +12,11 @@ import javax.persistence.Id;
import javax.persistence.Table; import javax.persistence.Table;
import javax.validation.constraints.Size; import javax.validation.constraints.Size;
import io.sc.platform.flowable.api.ProcessVo;
import io.sc.platform.flowable.enums.ProcessStatus; import io.sc.platform.flowable.enums.ProcessStatus;
import io.sc.platform.orm.converter.NumericBooleanConverter; import io.sc.platform.orm.converter.NumericBooleanConverter;
import io.sc.platform.orm.entity.AuditorEntity; import io.sc.platform.orm.entity.AuditorEntity;
import io.sc.platform.orm.entity.CorporationAuditorEntity;
import org.hibernate.annotations.GenericGenerator; import org.hibernate.annotations.GenericGenerator;
/** /**
@ -22,7 +24,7 @@ import org.hibernate.annotations.GenericGenerator;
*/ */
@Entity @Entity
@Table(name="SYS_PROCESS") @Table(name="SYS_PROCESS")
public class ProcessEntity extends AuditorEntity implements Serializable{ public class ProcessEntity extends CorporationAuditorEntity<ProcessVo> {
private static final long serialVersionUID = 2056614495312244260L; private static final long serialVersionUID = 2056614495312244260L;
//主键 //主键
@ -76,6 +78,13 @@ public class ProcessEntity extends AuditorEntity implements Serializable{
@Convert(converter= NumericBooleanConverter.class) @Convert(converter= NumericBooleanConverter.class)
private Boolean canClaimTask; private Boolean canClaimTask;
@Override
public ProcessVo toVo() {
ProcessVo vo =new ProcessVo();
CorporationAuditorEntity.toVo(vo,this);
return vo;
}
public String getId() { public String getId() {
return id; return id;
} }

6
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/jpa/repository/AgentRepository.java

@ -1,11 +1,11 @@
package io.sc.platform.flowable.jpa.repository; package io.sc.platform.flowable.jpa.repository;
import io.sc.platform.flowable.jpa.entity.Agent; import io.sc.platform.flowable.jpa.entity.AgentEntity;
import io.sc.platform.orm.repository.DaoRepository; import io.sc.platform.orm.repository.DaoRepository;
import java.util.List; import java.util.List;
public interface AgentRepository extends DaoRepository<Agent,String> { public interface AgentRepository extends DaoRepository<AgentEntity,String> {
public List<Agent> findByLoginNameAndEffective(String loginName,Boolean effective); public List<AgentEntity> findByLoginNameAndEffective(String loginName, Boolean effective);
} }

10
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/AgentService.java

@ -1,19 +1,19 @@
package io.sc.platform.flowable.service; package io.sc.platform.flowable.service;
import io.sc.platform.flowable.jpa.entity.Agent; import io.sc.platform.flowable.jpa.entity.AgentEntity;
import io.sc.platform.flowable.jpa.repository.AgentRepository; import io.sc.platform.flowable.jpa.repository.AgentRepository;
import io.sc.platform.orm.service.DaoService; import io.sc.platform.orm.service.DaoService;
import io.sc.platform.system.api.user.UserVo; import io.sc.platform.system.api.user.UserVo;
import java.util.List; import java.util.List;
public interface AgentService extends DaoService<Agent, String, AgentRepository> { public interface AgentService extends DaoService<AgentEntity, String, AgentRepository> {
/** /**
* 获取代理人列表 * 获取代理人列表
* @param userId 用户ID * @param userId 用户ID
* @return 该用户的代理人 * @return 该用户的代理人
*/ */
public List<Agent> getAgents(String userId); public List<AgentEntity> getAgents(String userId);
/** /**
* 获取可用的代理人列表 * 获取可用的代理人列表
@ -27,7 +27,7 @@ public interface AgentService extends DaoService<Agent, String, AgentRepository>
* @param agentId 代理人记录主键 * @param agentId 代理人记录主键
* @return 更新后的代理人对象 * @return 更新后的代理人对象
*/ */
public Agent agree(String agentId); public AgentEntity agree(String agentId);
/** /**
* 拒绝成为对方的代理人 * 拒绝成为对方的代理人
@ -35,5 +35,5 @@ public interface AgentService extends DaoService<Agent, String, AgentRepository>
* @param comments 拒绝说明 * @param comments 拒绝说明
* @return 更新后的代理人对象 * @return 更新后的代理人对象
*/ */
public Agent reject(String agentId,String comments); public AgentEntity reject(String agentId, String comments);
} }

15
io.sc.platform.flowable/src/main/java/io/sc/platform/flowable/service/impl/AgentServiceImpl.java

@ -4,11 +4,10 @@ import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import io.sc.platform.flowable.jpa.entity.Agent; import io.sc.platform.flowable.jpa.entity.AgentEntity;
import io.sc.platform.flowable.jpa.repository.AgentRepository; import io.sc.platform.flowable.jpa.repository.AgentRepository;
import io.sc.platform.flowable.service.AgentService; import io.sc.platform.flowable.service.AgentService;
import io.sc.platform.orm.service.impl.DaoServiceImpl; import io.sc.platform.orm.service.impl.DaoServiceImpl;
import io.sc.platform.system.api.role.RoleVo;
import io.sc.platform.system.api.user.UserVo; import io.sc.platform.system.api.user.UserVo;
import io.sc.platform.system.role.jpa.entity.RoleEntity; import io.sc.platform.system.role.jpa.entity.RoleEntity;
import io.sc.platform.system.role.service.RoleService; import io.sc.platform.system.role.service.RoleService;
@ -22,12 +21,12 @@ import org.springframework.stereotype.Service;
import javax.persistence.criteria.Join; import javax.persistence.criteria.Join;
@Service @Service
public class AgentServiceImpl extends DaoServiceImpl<Agent, String, AgentRepository> implements AgentService { public class AgentServiceImpl extends DaoServiceImpl<AgentEntity, String, AgentRepository> implements AgentService {
@Autowired private UserService userService; @Autowired private UserService userService;
@Autowired private RoleService roleService; @Autowired private RoleService roleService;
@Override @Override
public List<Agent> getAgents(String loginName) { public List<AgentEntity> getAgents(String loginName) {
return repository.findByLoginNameAndEffective(loginName,true); return repository.findByLoginNameAndEffective(loginName,true);
} }
@ -59,8 +58,8 @@ public class AgentServiceImpl extends DaoServiceImpl<Agent, String, AgentReposit
} }
@Override @Override
public Agent agree(String agentId) { public AgentEntity agree(String agentId) {
Agent agent =repository.getOne(agentId); AgentEntity agent =repository.getOne(agentId);
if(agent!=null) { if(agent!=null) {
agent.setEffective(true); agent.setEffective(true);
return repository.save(agent); return repository.save(agent);
@ -69,8 +68,8 @@ public class AgentServiceImpl extends DaoServiceImpl<Agent, String, AgentReposit
} }
@Override @Override
public Agent reject(String agentId, String comments) { public AgentEntity reject(String agentId, String comments) {
Agent agent =repository.getOne(agentId); AgentEntity agent =repository.getOne(agentId);
if(agent!=null) { if(agent!=null) {
agent.setEffective(false); agent.setEffective(false);
agent.setComments(comments); agent.setComments(comments);

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

@ -12,7 +12,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import io.sc.platform.flowable.exception.NoAvailableAssigneeException; import io.sc.platform.flowable.exception.NoAvailableAssigneeException;
import io.sc.platform.flowable.jpa.entity.Agent; import io.sc.platform.flowable.jpa.entity.AgentEntity;
import io.sc.platform.flowable.service.AgentService; import io.sc.platform.flowable.service.AgentService;
import io.sc.platform.flowable.service.AssigneeQueryService; import io.sc.platform.flowable.service.AssigneeQueryService;
import io.sc.platform.flowable.service.ProcessEntityService; import io.sc.platform.flowable.service.ProcessEntityService;
@ -152,7 +152,7 @@ public class ProcessOperationServiceImpl implements ProcessOperationService {
//如果新任务已经成功分配到了处理人,正常返回 //如果新任务已经成功分配到了处理人,正常返回
if(StringUtils.hasText(newTask.getAssignee())){ if(StringUtils.hasText(newTask.getAssignee())){
//查找代理人 //查找代理人
Agent agent =getAgent(newTask.getAssignee()); AgentEntity agent =getAgent(newTask.getAssignee());
if(agent!=null){ if(agent!=null){
taskService.setAssignee(newTask.getId(), agent.getAgentLoginName()); taskService.setAssignee(newTask.getId(), agent.getAgentLoginName());
} }
@ -246,7 +246,7 @@ public class ProcessOperationServiceImpl implements ProcessOperationService {
//如果新任务已经成功分配到了处理人,正常返回 //如果新任务已经成功分配到了处理人,正常返回
if(StringUtils.hasText(newTask.getAssignee())){ if(StringUtils.hasText(newTask.getAssignee())){
Agent agent =getAgent(newTask.getAssignee()); AgentEntity agent =getAgent(newTask.getAssignee());
if(agent!=null){ if(agent!=null){
taskService.setAssignee(newTask.getId(), agent.getAgentLoginName()); taskService.setAssignee(newTask.getId(), agent.getAgentLoginName());
} }
@ -287,7 +287,7 @@ public class ProcessOperationServiceImpl implements ProcessOperationService {
} }
String historyAssignee =historyTask.getAssignee(); String historyAssignee =historyTask.getAssignee();
if(StringUtils.hasText(historyAssignee)) { if(StringUtils.hasText(historyAssignee)) {
Agent agent =getAgent(historyAssignee); AgentEntity agent =getAgent(historyAssignee);
if(agent!=null){ if(agent!=null){
taskService.setAssignee(newTask.getId(), agent.getAgentLoginName()); taskService.setAssignee(newTask.getId(), agent.getAgentLoginName());
}else { }else {
@ -459,10 +459,10 @@ public class ProcessOperationServiceImpl implements ProcessOperationService {
return bean; return bean;
} }
private Agent getAgent(String loginName){ private AgentEntity getAgent(String loginName){
List<Agent> agents =agentService.getAgents(loginName); List<AgentEntity> agents =agentService.getAgents(loginName);
if(agents!=null && agents.size()>0){ if(agents!=null && agents.size()>0){
for(Agent agent : agents){ for(AgentEntity agent : agents){
Date startDate =agent.getStartDate(); Date startDate =agent.getStartDate();
Date endDate =agent.getEndDate(); Date endDate =agent.getEndDate();
Date now =new Date(); Date now =new Date();

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

@ -1,5 +1,6 @@
{ {
"includes":[ "includes":[
"io/sc/platform/flowable/i18n/initializer",
"io/sc/platform/flowable/i18n/enums" "io/sc/platform/flowable/i18n/enums"
] ]
} }

2
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/initializer.properties

@ -0,0 +1,2 @@
io.sc.platform.flowable.initializer.SampleWorkFlowSystemDictionaryInitializer.name=Sample Process Dictionary Initializer
io.sc.platform.flowable.initializer.SampleWorkFlowSystemDictionaryInitializer.description=initialize sample process dictionary if not exists

2
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/initializer_tw_CN.properties

@ -0,0 +1,2 @@
io.sc.platform.flowable.initializer.SampleWorkFlowSystemDictionaryInitializer.name=\u793A\u4F8B\u6D41\u7A0B\u6578\u64DA\u5B57\u5178\u59CB\u5316\u5668
io.sc.platform.flowable.initializer.SampleWorkFlowSystemDictionaryInitializer.description=\u7576\u7CFB\u7D71\u7F3A\u5931\u793A\u4F8B\u6D41\u7A0B\u6578\u64DA\u5B57\u5178\u6642, \u81EA\u52D5\u5275\u5EFA\u9ED8\u8A8D\u793A\u4F8B\u6D41\u7A0B\u6578\u64DA\u5B57\u5178

2
io.sc.platform.flowable/src/main/resources/io/sc/platform/flowable/i18n/initializer_zh_CN.properties

@ -0,0 +1,2 @@
io.sc.platform.flowable.initializer.SampleWorkFlowSystemDictionaryInitializer.name=\u793A\u4F8B\u6D41\u7A0B\u6570\u636E\u5B57\u5178\u521D\u59CB\u5316\u5668
io.sc.platform.flowable.initializer.SampleWorkFlowSystemDictionaryInitializer.description=\u5F53\u7CFB\u7EDF\u7F3A\u5931\u793A\u4F8B\u6D41\u7A0B\u6570\u636E\u5B57\u5178\u65F6, \u81EA\u52A8\u521B\u5EFA\u9ED8\u8BA4\u793A\u4F8B\u6D41\u7A0B\u6570\u636E\u5B57\u5178

88
io.sc.platform.flowable/src/main/resources/liquibase/PF_1.0.0_20221228__Process Manager Database Schema DDL.xml

@ -10,59 +10,67 @@
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
" "
> >
<property name="now" value="CURRENT TIMESTAMP" dbms="db2"/>
<property name="now" value="CURRENT_TIMESTAMP" dbms="h2"/>
<property name="now" value="sysdate" dbms="oracle"/>
<property name="now" value="now()" dbms="mysql"/>
<property name="now" value="now()" dbms="postgresql"/>
<property name="now" value="GETDATE()" dbms="mssql"/>
<changeSet id="PF_1.0.0_20221228__Process Manager Database Schema DDL" author="framework"> <changeSet id="PF_1.0.0_20221228__Process Manager Database Schema DDL" author="framework">
<!-- 流程定义表 --> <!-- 流程定义表 -->
<createTable tableName="SYS_PROCESS" remarks="流程定义表"> <createTable tableName="SYS_PROCESS" remarks="流程定义表">
<column name="ID_" type="java.sql.Types.NVARCHAR(36)" remarks="ID"> <column name="ID_" type="NVARCHAR(36)" remarks="ID">
<constraints primaryKey="true"/> <constraints primaryKey="true"/>
</column> </column>
<column name="CATEGORY_" type="java.sql.Types.NVARCHAR(255)" remarks="流程分类"></column> <column name="CATEGORY_" type="NVARCHAR(255)" remarks="流程分类"></column>
<column name="KEY_" type="java.sql.Types.NVARCHAR(255)" remarks="流程代码"></column> <column name="KEY_" type="NVARCHAR(255)" remarks="流程代码"></column>
<column name="NAME_" type="java.sql.Types.NVARCHAR(255)" remarks="流程名称"></column> <column name="NAME_" type="NVARCHAR(255)" remarks="流程名称"></column>
<column name="DESCRIPTION_" type="java.sql.Types.NVARCHAR(255)" remarks="描述"></column> <column name="DESCRIPTION_" type="NVARCHAR(255)" remarks="描述"></column>
<column name="VERSION_" type="java.sql.Types.INTEGER" remarks="版本"></column> <column name="VERSION_" type="INTEGER" remarks="版本"></column>
<column name="DEPLOYED_ID_" type="java.sql.Types.NVARCHAR(255)" remarks="工作流引擎中的流程定义ID"></column> <column name="DEPLOYED_ID_" type="NVARCHAR(255)" remarks="工作流引擎中的流程定义ID"></column>
<column name="XML_" type="java.sql.Types.CLOB" remarks="流程定义BPM XML内容"></column> <column name="XML_" type="CLOB" remarks="流程定义BPM XML内容"></column>
<column name="STATUS_" type="java.sql.Types.NVARCHAR(10)" remarks="流程定义状态"></column> <column name="STATUS_" type="NVARCHAR(10)" remarks="流程定义状态"></column>
<column name="CAN_CLAIM_TASK_" type="java.sql.Types.SMALLINT" remarks="是否可以领取任务"></column> <column name="CAN_CLAIM_TASK_" type="SMALLINT" remarks="是否可以领取任务"></column>
<column name="DATA_COME_FROM_" type="java.sql.Types.NVARCHAR(10)" remarks="数据来源(INPUT:手工录入,IMPORT:系统自动导入)" defaultValue="INPUT"></column> <column name="JPA_VERSION_" type="INTEGER" remarks="JPA乐观锁版本"/>
<column name="CREATOR_" type="java.sql.Types.NVARCHAR(255)" remarks="创建人"></column> <column name="DATA_COME_FROM_" type="NVARCHAR(10)" remarks="数据来源(INPUT:手工录入,IMPORT:系统自动导入)"/>
<column name="CREATE_DATE_" type="DATETIME" remarks="创建日期"></column> <column name="CREATOR_" type="NVARCHAR(255)" remarks="创建人"/>
<column name="LAST_MODIFIER_" type="java.sql.Types.NVARCHAR(255)" remarks="最后修改人"></column> <column name="CREATE_DATE_" type="DATETIME" remarks="创建日期"/>
<column name="LAST_MODIFYDATE_" type="DATETIME" remarks="最后修改日期"></column> <column name="LAST_MODIFIER_" type="NVARCHAR(255)" remarks="最后修改人"/>
<column name="CORP_CODE_" type="java.sql.Types.NVARCHAR(255)" remarks="所属法人代码" defaultValue="_PRIMARY_"> <column name="LAST_MODIFYDATE_" type="DATETIME" remarks="最后修改日期"/>
<constraints nullable="false" /> <column name="CORP_CODE_" type="NVARCHAR(255)" remarks="所属法人代码"/>
</column>
</createTable> </createTable>
<addUniqueConstraint tableName="SYS_PROCESS" columnNames="CATEGORY_,KEY_,CORP_CODE_"></addUniqueConstraint>
<addNotNullConstraint columnName="CATEGORY_" columnDataType="NVARCHAR(255)" tableName="SYS_PROCESS" constraintName="CONST_SYS_PROCESS_CATEGORY"/>
<addNotNullConstraint columnName="KEY_" columnDataType="NVARCHAR(255)" tableName="SYS_PROCESS" constraintName="CONST_SYS_PROCESS_KEY"/>
<addNotNullConstraint columnName="NAME_" columnDataType="NVARCHAR(255)" tableName="SYS_PROCESS" constraintName="CONST_SYS_PROCESS_NAME"/>
<addNotNullConstraint columnName="DATA_COME_FROM_" columnDataType="NVARCHAR(10)" tableName="SYS_PROCESS" constraintName="CONST_SYS_PROCESS_DCF"/>
<addNotNullConstraint columnName="CORP_CODE_" columnDataType="NVARCHAR(255)" tableName="SYS_PROCESS" constraintName="CONST_SYS_PROCESS_CORP"/>
<addDefaultValue columnName="DATA_COME_FROM_" columnDataType="NVARCHAR(10)" tableName="SYS_PROCESS" defaultValue="INPUT"/>
<addDefaultValue columnName="CORP_CODE_" columnDataType="NVARCHAR(255)" tableName="SYS_PROCESS" defaultValue="_PRIMARY_"/>
<!-- 代理人配置表 --> <!-- 代理人配置表 -->
<createTable tableName="SYS_AGENT" remarks="代理人配置表"> <createTable tableName="SYS_AGENT" remarks="代理人配置表">
<column name="ID_" type="java.sql.Types.NVARCHAR(36)" remarks="ID"> <column name="ID_" type="NVARCHAR(36)" remarks="ID">
<constraints primaryKey="true"/> <constraints primaryKey="true"/>
</column> </column>
<column name="LOGINNAME_" type="java.sql.Types.NVARCHAR(255)" remarks="被代理人登录名"></column> <column name="LOGINNAME_" type="NVARCHAR(255)" remarks="被代理人登录名"></column>
<column name="USERNAME_" type="java.sql.Types.NVARCHAR(255)" remarks="被代理人用户名"></column> <column name="USERNAME_" type="NVARCHAR(255)" remarks="被代理人用户名"></column>
<column name="AGENT_LOGINNAME_" type="java.sql.Types.NVARCHAR(255)" remarks="代理人登录名"></column> <column name="AGENT_LOGINNAME_" type="NVARCHAR(255)" remarks="代理人登录名"></column>
<column name="AGENT_USERNAME_" type="java.sql.Types.NVARCHAR(255)" remarks="代理人用户名"></column> <column name="AGENT_USERNAME_" type="NVARCHAR(255)" remarks="代理人用户名"></column>
<column name="START_DATE_" type="DATETIME" remarks="开始日期"></column> <column name="START_DATE_" type="DATETIME" remarks="开始日期"></column>
<column name="END_DATE_" type="DATETIME" remarks="结束日期"></column> <column name="END_DATE_" type="DATETIME" remarks="结束日期"></column>
<column name="REASONS_" type="java.sql.Types.NVARCHAR(255)" remarks="代理原因"></column> <column name="REASONS_" type="NVARCHAR(255)" remarks="代理原因"></column>
<column name="EFFECTIVE_" type="java.sql.Types.SMALLINT" remarks="是否生效"></column> <column name="EFFECTIVE_" type="SMALLINT" remarks="是否生效"></column>
<column name="COMMENTS_" type="java.sql.Types.NVARCHAR(1024)" remarks="审批意见"></column> <column name="COMMENTS_" type="NVARCHAR(1024)" remarks="审批意见"></column>
<column name="CREATOR_" type="java.sql.Types.NVARCHAR(255)" remarks="创建人"></column> <column name="JPA_VERSION_" type="INTEGER" remarks="JPA乐观锁版本"/>
<column name="CREATE_DATE_" type="DATETIME" remarks="创建日期"></column> <column name="DATA_COME_FROM_" type="NVARCHAR(10)" remarks="数据来源(INPUT:手工录入,IMPORT:系统自动导入)"/>
<column name="LAST_MODIFIER_" type="java.sql.Types.NVARCHAR(255)" remarks="最后修改人"></column> <column name="CREATOR_" type="NVARCHAR(255)" remarks="创建人"/>
<column name="LAST_MODIFYDATE_" type="DATETIME" remarks="最后修改日期"></column> <column name="CREATE_DATE_" type="DATETIME" remarks="创建日期"/>
<column name="CORP_CODE_" type="java.sql.Types.NVARCHAR(255)" remarks="所属法人代码" defaultValue="_PRIMARY_"> <column name="LAST_MODIFIER_" type="NVARCHAR(255)" remarks="最后修改人"/>
<constraints nullable="false" /> <column name="LAST_MODIFYDATE_" type="DATETIME" remarks="最后修改日期"/>
</column> <column name="CORP_CODE_" type="NVARCHAR(255)" remarks="所属法人代码"/>
</createTable> </createTable>
<addNotNullConstraint columnName="LOGINNAME_" columnDataType="NVARCHAR(255)" tableName="SYS_AGENT" constraintName="CONST_SYS_AGENT_LOGINNAME"/>
<addNotNullConstraint columnName="AGENT_LOGINNAME_" columnDataType="NVARCHAR(255)" tableName="SYS_AGENT" constraintName="CONST_SYS_AGENT_AGENT_LOGINNAME"/>
<addNotNullConstraint columnName="DATA_COME_FROM_" columnDataType="NVARCHAR(10)" tableName="SYS_AGENT" constraintName="CONST_SYS_AGENT_DCF"/>
<addNotNullConstraint columnName="CORP_CODE_" columnDataType="NVARCHAR(255)" tableName="SYS_AGENT" constraintName="CONST_SYS_AGENT_CORP"/>
<addDefaultValue columnName="DATA_COME_FROM_" columnDataType="NVARCHAR(10)" tableName="SYS_AGENT" defaultValue="INPUT"/>
<addDefaultValue columnName="CORP_CODE_" columnDataType="NVARCHAR(255)" tableName="SYS_AGENT" defaultValue="_PRIMARY_"/>
</changeSet> </changeSet>
</databaseChangeLog> </databaseChangeLog>

2
io.sc.platform.gradle/templates/pgp/app/build-common.gradle

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

1
io.sc.platform.gradle/templates/pgp/app/build.gradle

@ -13,6 +13,7 @@ dependencies {
implementation ( implementation (
project(":io.sc.platform.app"), project(":io.sc.platform.app"),
project(":io.sc.platform.developer"), project(":io.sc.platform.developer"),
//project(":io.sc.platform.job.manager"),
) )
} }

3
io.sc.platform.gradle/templates/pgp/app/src/main/java/app/platform/Application.java.txt

@ -6,11 +6,12 @@ import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.WebApplicationInitializer; import org.springframework.web.WebApplicationInitializer;
import java.sql.Types;
/** /**
* 应用程序入口 * 应用程序入口
*/ */
@SpringBootApplication(proxyBeanMethods = false) @SpringBootApplication(proxyBeanMethods = false)
@MapperScan("com.xxl.job.admin.dao")
public class Application extends PlatformSpringBootServletInitializer implements WebApplicationInitializer { public class Application extends PlatformSpringBootServletInitializer implements WebApplicationInitializer {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
ApplicationLauncher.run(Application.class,args); ApplicationLauncher.run(Application.class,args);

14
io.sc.platform.gradle/templates/pgp/app/src/main/resources/public/configure.js

@ -1,7 +1,11 @@
window.APP = {}; // 在浏览器 window 对象中新建名为 APP 的变量, 用于存放应用对象的容器 // 在浏览器 window 对象中新建名为 APP 的容器变量, 用于存放平台的全局变量
window.APP.configure ={ // 全局配置存储容器 window.APP = {};
webContextPath: '[(@{/})]'.startsWith('[')? '/' : '[(@{/})]', // 应用上下文路径 // 全局配置
window.APP.configure ={
// 应用上下文路径
webContextPath: '[(@{/})]'.startsWith('[')? '/' : '[(@{/})]',
// 默认后端 API 请求的服务地址前缀
apiContextPaths: { apiContextPaths: {
DEFAULT: '[(@{/})]'.startsWith('[') ? 'http://localhost:8080/' : '[(@{/})]', // 后端 API 请求的服务地址前缀 DEFAULT: '[(@{/})]'.startsWith('[') ? 'http://localhost:8080/' : '[(@{/})]'
} }
} };

4
io.sc.platform.gradle/templates/pgp/setup/build.gradle.txt

@ -371,6 +371,8 @@ subprojects {
* pnpm sync * pnpm sync
*----------------------------------------------------------------*/ *----------------------------------------------------------------*/
task frontendNpmSync(type:Exec){ task frontendNpmSync(type:Exec){
commandLine 'cd', '.'
/*
if(isFrontendProject(file('.')) && !project.name.contains("io.sc.platform.security.frontend")){ if(isFrontendProject(file('.')) && !project.name.contains("io.sc.platform.security.frontend")){
workingDir '.' workingDir '.'
if(org.gradle.internal.os.OperatingSystem.current().isWindows()){ if(org.gradle.internal.os.OperatingSystem.current().isWindows()){
@ -384,7 +386,7 @@ subprojects {
}else{ }else{
commandLine 'cd', '.' commandLine 'cd', '.'
} }
} }*/
} }
tasks.frontendNpmSync.doFirst { tasks.frontendNpmSync.doFirst {
if(isFrontendProject(file('.'))) { if(isFrontendProject(file('.'))) {

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

@ -36,9 +36,9 @@ application_version=1.0.0
# platform # platform
########################################################### ###########################################################
platform_group=io.sc platform_group=io.sc
platform_version=8.1.13 platform_version=8.1.19
platform_plugin_version=8.1.13 platform_plugin_version=8.1.13
platform_core_frontend_version=8.1.42 platform_core_frontend_version=8.1.45
########################################################### ###########################################################
# dependencies version # dependencies version

2
io.sc.platform.installer/src/main/resources/templates/io/sc/platform/installer/installer.html

@ -115,7 +115,7 @@
<span th:text="#{|language.${#locale}|}"></span> <span th:text="#{|language.${#locale}|}"></span>
</button> </button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li th:each="lang : ${T(io.sc.platform.system.api.i18n.I18nLanguage).values()}"><a class="dropdown-item" th:href="@{|/io.sc.platform.installer/installer.html?locale=${lang}|}" th:text="#{|language.${lang}|}">English</a></li> <li th:each="lang : ${T(io.sc.platform.core.enums.Language).values()}"><a class="dropdown-item" th:href="@{|/io.sc.platform.installer/installer.html?locale=${lang}|}" th:text="#{|language.${lang}|}">English</a></li>
</ul> </ul>
</div> </div>
</div> </div>

6
io.sc.platform.job.core/src/main/java/io/sc/platform/job/core/enums/ExecutorAddressType.java

@ -0,0 +1,6 @@
package io.sc.platform.job.core.enums;
public enum ExecutorAddressType {
AUTO, // 自动注册
MANUAL; // 手工录入
}

6
io.sc.platform.job.manager/build.gradle

@ -0,0 +1,6 @@
dependencies {
api(
project(":io.sc.platform.job.core"),
project(":io.sc.platform.mvc"),
)
}

88
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/entity/JobGroupEntity.java

@ -0,0 +1,88 @@
package io.sc.platform.job.manager.jpa.entity;
import io.sc.platform.job.core.enums.ExecutorAddressType;
import io.sc.platform.orm.converter.SetStringConverter;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.*;
import javax.validation.constraints.Size;
import java.util.Date;
import java.util.Set;
public class JobGroupEntity {
//主键
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name="ID_", length=36)
@Size(max=36)
private String id;
@Column(name="APP_NAME", length=255)
@Size(min=1,max=255)
private String appName;
@Column(name="TITLE", length=255)
@Size(min=1,max=255)
private String title;
@Column(name="ADDRESS_TYPE")
@Enumerated(EnumType.STRING)
private ExecutorAddressType addressType;
@Column(name="ADDRESS_LIST")
@Convert(converter = SetStringConverter.class)
private Set<String> addresses;
@Column(name="UPDATE_TIME")
@Temporal(TemporalType.TIMESTAMP)
private Date updateTime;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getAppName() {
return appName;
}
public void setAppName(String appName) {
this.appName = appName;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public ExecutorAddressType getAddressType() {
return addressType;
}
public void setAddressType(ExecutorAddressType addressType) {
this.addressType = addressType;
}
public Set<String> getAddresses() {
return addresses;
}
public void setAddresses(Set<String> addresses) {
this.addresses = addresses;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}

12
io.sc.platform.job.manager/src/main/java/io/sc/platform/job/manager/jpa/repository/JobGroupRepository.java

@ -0,0 +1,12 @@
package io.sc.platform.job.manager.jpa.repository;
import io.sc.platform.job.core.enums.ExecutorAddressType;
import io.sc.platform.job.manager.jpa.entity.JobGroupEntity;
import io.sc.platform.orm.repository.DaoRepository;
import org.springframework.data.repository.query.Param;
import java.util.List;
public interface JobGroupRepository extends DaoRepository<JobGroupEntity,String> {
public List<JobGroupEntity> findByAddressType(@Param("addressType") ExecutorAddressType addressType);
}

10
io.sc.platform.job.manager/src/main/resources/META-INF/platform/plugins/liquibase.json

@ -0,0 +1,10 @@
[
{
"category" : "install",
"order" : 1000,
"description":"XXL JOB 相关表",
"locations":[
"liquibase/PF_8.0.0_20220606__Job_DDL.xml"
]
}
]

233
io.sc.platform.job.manager/src/main/resources/liquibase/PF_8.0.0_20220606__Job_DDL.xml

@ -0,0 +1,233 @@
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
xsi:schemaLocation="
http://www.liquibase.org/xml/ns/dbchangelog
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-4.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
"
>
<property name="now" value="CURRENT TIMESTAMP" dbms="db2"/>
<property name="now" value="CURRENT_TIMESTAMP" dbms="h2"/>
<property name="now" value="sysdate" dbms="oracle"/>
<property name="now" value="now()" dbms="mysql"/>
<property name="now" value="now()" dbms="postgresql"/>
<property name="now" value="GETDATE()" dbms="mssql"/>
<changeSet id="PF_8.0.0_20220606__Job_DDL" author="platform">
<!-- JOB信息表 -->
<createTable tableName="XXL_JOB_INFO" remarks="JOB信息表">
<column name="ID" type="INTEGER" remarks="主键ID"/>
<column name="JOB_GROUP" type="INTEGER" remarks="执行器主键ID" />
<column name="JOB_DESC" type="NVARCHAR(255)" remarks="描述"/>
<column name="ADD_TIME" type="DATETIME" remarks="创建日期"/>
<column name="UPDATE_TIME" type="DATETIME" remarks="更新日期"/>
<column name="AUTHOR" type="NVARCHAR(255)" remarks="作者"/>
<column name="ALARM_EMAIL" type="NVARCHAR(255)" remarks="报警邮件"/>
<column name="SCHEDULE_TYPE" type="NVARCHAR(50)" remarks="调度类型"/>
<column name="SCHEDULE_CONF" type="NVARCHAR(128)" remarks="调度配置,值含义取决于调度类型"/>
<column name="MISFIRE_STRATEGY" type="NVARCHAR(50)" remarks="调度过期策略"/>
<column name="EXECUTOR_ROUTE_STRATEGY" type="NVARCHAR(50)" remarks="执行器路由策略"/>
<column name="EXECUTOR_HANDLER" type="NVARCHAR(255)" remarks="执行器任务handler"/>
<column name="EXECUTOR_PARAM" type="NVARCHAR(512)" remarks="执行器任务参数"/>
<column name="EXECUTOR_BLOCK_STRATEGY" type="NVARCHAR(50)" remarks="阻塞处理策略"/>
<column name="EXECUTOR_TIMEOUT" type="INTEGER" remarks="任务执行超时时间,单位秒"/>
<column name="EXECUTOR_FAIL_RETRY_COUNT" type="INTEGER" remarks="失败重试次数"/>
<column name="GLUE_TYPE" type="NVARCHAR(50)" remarks="GLUE类型"/>
<column name="GLUE_SOURCE" type="CLOB" remarks="GLUE源代码"/>
<column name="GLUE_REMARK" type="NVARCHAR(128)" remarks="GLUE备注"/>
<column name="GLUE_UPDATETIME" type="DATETIME" remarks="GLUE更新时间"/>
<column name="CHILD_JOBID" type="NVARCHAR(255)" remarks="子任务ID,多个逗号分隔"/>
<column name="TRIGGER_STATUS" type="TINYINT" remarks="调度状态:0-停止,1-运行"/>
<column name="TRIGGER_LAST_TIME" type="BIGINT" remarks="上次调度时间"/>
<column name="TRIGGER_NEXT_TIME" type="BIGINT" remarks="下次调度时间"/>
</createTable>
<addPrimaryKey tableName="XXL_JOB_INFO" columnNames="ID"/>
<addAutoIncrement columnName="ID" columnDataType="INTEGER" tableName="XXL_JOB_INFO" startWith="1" incrementBy="1"/>
<addNotNullConstraint columnName="JOB_GROUP" columnDataType="INTEGER" tableName="XXL_JOB_INFO" constraintName="CONST_XXL_JOB_INFO_JOB_GROUP"/>
<addNotNullConstraint columnName="JOB_DESC" columnDataType="NVARCHAR(255)" tableName="XXL_JOB_INFO" constraintName="CONST_XXL_JOB_INFO_JOB_DESC"/>
<addNotNullConstraint columnName="SCHEDULE_TYPE" columnDataType="NVARCHAR(50)" tableName="XXL_JOB_INFO" constraintName="CONST_XXL_JOB_INFO_SCHEDULE_TYPE"/>
<addDefaultValue columnName="SCHEDULE_TYPE" columnDataType="NVARCHAR(50)" tableName="XXL_JOB_INFO" defaultValue="NONE"/>
<addNotNullConstraint columnName="MISFIRE_STRATEGY" columnDataType="NVARCHAR(50)" tableName="XXL_JOB_INFO" constraintName="CONST_XXL_JOB_INFO_MISFIRE_STRATEGY"/>
<addDefaultValue columnName="MISFIRE_STRATEGY" columnDataType="NVARCHAR(50)" tableName="XXL_JOB_INFO" defaultValue="DO_NOTHING"/>
<addNotNullConstraint columnName="EXECUTOR_TIMEOUT" columnDataType="INTEGER" tableName="XXL_JOB_INFO" constraintName="CONST_XXL_JOB_INFO_EXECUTOR_TIMEOUT"/>
<addDefaultValue columnName="EXECUTOR_TIMEOUT" columnDataType="INTEGER" tableName="XXL_JOB_INFO" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="EXECUTOR_FAIL_RETRY_COUNT" columnDataType="INTEGER" tableName="XXL_JOB_INFO" constraintName="CONST_XXL_JOB_INFO_EXECUTOR_FRC"/>
<addDefaultValue columnName="EXECUTOR_FAIL_RETRY_COUNT" columnDataType="INTEGER" tableName="XXL_JOB_INFO" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="TRIGGER_STATUS" columnDataType="TINYINT" tableName="XXL_JOB_INFO" constraintName="CONST_XXL_JOB_INFO_TRIGGER_STATUS"/>
<addDefaultValue columnName="TRIGGER_STATUS" columnDataType="TINYINT" tableName="XXL_JOB_INFO" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="TRIGGER_LAST_TIME" columnDataType="BIGINT" tableName="XXL_JOB_INFO" constraintName="CONST_XXL_JOB_INFO_TRIGGER_LAST_TIME"/>
<addDefaultValue columnName="TRIGGER_LAST_TIME" columnDataType="BIGINT" tableName="XXL_JOB_INFO" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="TRIGGER_NEXT_TIME" columnDataType="BIGINT" tableName="XXL_JOB_INFO" constraintName="CONST_XXL_JOB_INFO_TRIGGER_NEXT_TIME"/>
<addDefaultValue columnName="TRIGGER_NEXT_TIME" columnDataType="BIGINT" tableName="XXL_JOB_INFO" defaultValueNumeric="0"/>
<!-- JOB日志表 -->
<createTable tableName="XXL_JOB_LOG" remarks="JOB日志表">
<column name="ID" type="BIGINT" remarks="主键ID"/>
<column name="JOB_GROUP" type="INTEGER" remarks="执行器主键ID" />
<column name="JOB_ID" type="INTEGER" remarks="任务主键ID"/>
<column name="EXECUTOR_ADDRESS" type="NVARCHAR(255)" remarks="执行器地址,本次执行的地址"/>
<column name="EXECUTOR_HANDLER" type="NVARCHAR(255)" remarks="执行器任务handler"/>
<column name="EXECUTOR_PARAM" type="NVARCHAR(512)" remarks="执行器任务参数"/>
<column name="EXECUTOR_SHARDING_PARAM" type="NVARCHAR(20)" remarks="执行器任务分片参数,格式如 1/2"/>
<column name="EXECUTOR_FAIL_RETRY_COUNT" type="INTEGER" remarks="失败重试次数"/>
<column name="TRIGGER_TIME" type="DATETIME" remarks="调度-时间"/>
<column name="TRIGGER_CODE" type="INTEGER" remarks="调度-结果"/>
<column name="TRIGGER_MSG" type="CLOB" remarks="调度-日志"/>
<column name="HANDLE_TIME" type="DATETIME" remarks="执行-时间"/>
<column name="HANDLE_CODE" type="INTEGER" remarks="执行-状态"/>
<column name="HANDLE_MSG" type="CLOB" remarks="执行-日志"/>
<column name="ALARM_STATUS" type="TINYINT" remarks="告警状态:0-默认、1-无需告警、2-告警成功、3-告警失败" defaultValueNumeric="0"/>
</createTable>
<addPrimaryKey tableName="XXL_JOB_LOG" columnNames="ID"/>
<addAutoIncrement columnName="ID" columnDataType="BIGINT" tableName="XXL_JOB_LOG" startWith="1" incrementBy="1"/>
<addNotNullConstraint columnName="JOB_GROUP" columnDataType="INTEGER" tableName="XXL_JOB_LOG" constraintName="CONST_XXL_JOB_LOG_JOB_GROUP"/>
<addNotNullConstraint columnName="JOB_ID" columnDataType="INTEGER" tableName="XXL_JOB_LOG" constraintName="CONST_XXL_JOB_LOG_JOB_ID"/>
<addNotNullConstraint columnName="EXECUTOR_FAIL_RETRY_COUNT" columnDataType="BIGINT" tableName="XXL_JOB_LOG" constraintName="CONST_XXL_JOB_LOG_EXECUTOR_FRC"/>
<addDefaultValue columnName="EXECUTOR_FAIL_RETRY_COUNT" columnDataType="BIGINT" tableName="XXL_JOB_LOG" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="TRIGGER_CODE" columnDataType="INTEGER" tableName="XXL_JOB_LOG" constraintName="CONST_XXL_JOB_LOG_TRIGGER_CODE"/>
<addNotNullConstraint columnName="HANDLE_CODE" columnDataType="INTEGER" tableName="XXL_JOB_LOG" constraintName="CONST_XXL_JOB_LOG_HANDLE_CODE"/>
<addNotNullConstraint columnName="ALARM_STATUS" columnDataType="TINYINT" tableName="XXL_JOB_LOG" constraintName="CONST_XXL_JOB_LOG_ALARM_STATUS"/>
<addDefaultValue columnName="ALARM_STATUS" columnDataType="TINYINT" tableName="XXL_JOB_LOG" defaultValueNumeric="0"/>
<createIndex tableName="XXL_JOB_LOG" indexName="IDX_XXL_JOB_LOG_TRIGGER_TIME">
<column name="TRIGGER_TIME"></column>
</createIndex>
<createIndex tableName="XXL_JOB_LOG" indexName="IDX_XXL_JOB_LOG_HANDLE_CODE">
<column name="HANDLE_CODE"></column>
</createIndex>
<!-- JOB日志报告表 -->
<createTable tableName="XXL_JOB_LOG_REPORT" remarks="JOB日志报告表">
<column name="ID" type="INTEGER" remarks="主键ID"/>
<column name="TRIGGER_DAY" type="DATETIME" remarks="调度-时间"/>
<column name="RUNNING_COUNT" type="INTEGER" remarks="运行中-日志数量" defaultValueNumeric="0"/>
<column name="SUC_COUNT" type="INTEGER" remarks="执行成功-日志数量" defaultValueNumeric="0"/>
<column name="FAIL_COUNT" type="INTEGER" remarks="执行失败-日志数量" defaultValueNumeric="0"/>
<column name="UPDATE_TIME" type="DATETIME" remarks="更新日期"></column>
</createTable>
<addPrimaryKey tableName="XXL_JOB_LOG_REPORT" columnNames="ID"/>
<addAutoIncrement columnName="ID" columnDataType="INTEGER" tableName="XXL_JOB_LOG_REPORT" startWith="1" incrementBy="1"/>
<addNotNullConstraint columnName="RUNNING_COUNT" columnDataType="INTEGER" tableName="XXL_JOB_LOG_REPORT" constraintName="CONST_XXL_JOB_LOG_REPORT_RUNNING_COUNT"/>
<addDefaultValue columnName="RUNNING_COUNT" columnDataType="INTEGER" tableName="XXL_JOB_LOG_REPORT" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="SUC_COUNT" columnDataType="INTEGER" tableName="XXL_JOB_LOG_REPORT" constraintName="CONST_XXL_JOB_LOG_REPORT_SUC_COUNT"/>
<addDefaultValue columnName="SUC_COUNT" columnDataType="INTEGER" tableName="XXL_JOB_LOG_REPORT" defaultValueNumeric="0"/>
<addNotNullConstraint columnName="FAIL_COUNT" columnDataType="INTEGER" tableName="XXL_JOB_LOG_REPORT" constraintName="CONST_XXL_JOB_LOG_REPORT_FAIL_COUNT"/>
<addDefaultValue columnName="FAIL_COUNT" columnDataType="INTEGER" tableName="XXL_JOB_LOG_REPORT" defaultValueNumeric="0"/>
<createIndex tableName="XXL_JOB_LOG_REPORT" indexName="IDX_XXL_JOB_LOG_REPORT_TRIGGER_DAY" unique="true">
<column name="TRIGGER_DAY"></column>
</createIndex>
<!-- JOB GLUE 表 -->
<createTable tableName="XXL_JOB_LOGGLUE" remarks="JOB GLUE 表">
<column name="ID" type="INTEGER" remarks="主键ID"/>
<column name="JOB_ID" type="INTEGER" remarks="任务主键ID"/>
<column name="GLUE_TYPE" type="NVARCHAR(50)" remarks="GLUE类型"/>
<column name="GLUE_SOURCE" type="CLOB" remarks="GLUE源代码"/>
<column name="GLUE_REMARK" type="NVARCHAR(128)" remarks="GLUE备注"/>
<column name="ADD_TIME" type="DATETIME" remarks="创建日期"/>
<column name="UPDATE_TIME" type="DATETIME" remarks="更新日期"/>
</createTable>
<addPrimaryKey tableName="XXL_JOB_LOGGLUE" columnNames="ID"/>
<addAutoIncrement columnName="ID" columnDataType="INTEGER" tableName="XXL_JOB_LOGGLUE" startWith="1" incrementBy="1"/>
<addNotNullConstraint columnName="JOB_ID" columnDataType="INTEGER" tableName="XXL_JOB_LOGGLUE" constraintName="CONST_XXL_JOB_LOGGLUE_JOB_ID"/>
<!-- JOB 注册表 -->
<createTable tableName="XXL_JOB_REGISTRY" remarks="JOB 注册表">
<column name="ID" type="INTEGER" remarks="主键ID"/>
<column name="REGISTRY_GROUP" type="NVARCHAR(50)" remarks=""/>
<column name="REGISTRY_KEY" type="NVARCHAR(255)" remarks=""/>
<column name="REGISTRY_VALUE" type="NVARCHAR(255)" remarks=""/>
<column name="UPDATE_TIME" type="DATETIME" remarks="更新日期"/>
</createTable>
<addPrimaryKey tableName="XXL_JOB_REGISTRY" columnNames="ID"/>
<addAutoIncrement columnName="ID" columnDataType="INTEGER" tableName="XXL_JOB_REGISTRY" startWith="1" incrementBy="1"/>
<addUniqueConstraint tableName="XXL_JOB_REGISTRY" columnNames="REGISTRY_GROUP,REGISTRY_KEY,REGISTRY_VALUE"></addUniqueConstraint>
<addNotNullConstraint columnName="REGISTRY_GROUP" columnDataType="NVARCHAR(50)" tableName="XXL_JOB_REGISTRY" constraintName="CONST_XXL_JOB_REGISTRY_REGISTRY_GROUP"/>
<addNotNullConstraint columnName="REGISTRY_KEY" columnDataType="NVARCHAR(255)" tableName="XXL_JOB_REGISTRY" constraintName="CONST_XXL_JOB_REGISTRY_REGISTRY_KEY"/>
<addNotNullConstraint columnName="REGISTRY_VALUE" columnDataType="NVARCHAR(255)" tableName="XXL_JOB_REGISTRY" constraintName="CONST_XXL_JOB_REGISTRY_REGISTRY_VALUE"/>
<!-- JOB 组表 -->
<createTable tableName="XXL_JOB_GROUP" remarks="JOB 组表">
<column name="ID" type="INTEGER" remarks="主键ID"/>
<column name="APP_NAME" type="NVARCHAR(255)" remarks="执行器AppName"/>
<column name="TITLE" type="NVARCHAR(255)" remarks="执行器名称"/>
<column name="ADDRESS_TYPE" type="TINYINT" remarks="执行器地址类型:0=自动注册、1=手动录入" defaultValueNumeric="0"/>
<column name="ADDRESS_LIST" type="CLOB" remarks="执行器地址列表,多地址逗号分隔"/>
<column name="UPDATE_TIME" type="DATETIME" remarks="更新日期"/>
</createTable>
<addPrimaryKey tableName="XXL_JOB_GROUP" columnNames="ID"/>
<addAutoIncrement columnName="ID" columnDataType="INTEGER" tableName="XXL_JOB_GROUP" startWith="1" incrementBy="1"/>
<addNotNullConstraint columnName="APP_NAME" columnDataType="NVARCHAR(64)" tableName="XXL_JOB_GROUP" constraintName="CONST_XXL_JOB_GROUP_APP_NAME"/>
<addNotNullConstraint columnName="TITLE" columnDataType="NVARCHAR(12)" tableName="XXL_JOB_GROUP" constraintName="CONST_XXL_JOB_GROUP_TITLE"/>
<addNotNullConstraint columnName="ADDRESS_TYPE" columnDataType="TINYINT" tableName="XXL_JOB_GROUP" constraintName="CONST_XXL_JOB_GROUP_ADDRESS_TYPE"/>
<addDefaultValue columnName="ADDRESS_TYPE" columnDataType="TINYINT" tableName="XXL_JOB_GROUP" defaultValueNumeric="0"/>
<!-- JOB 用户表 -->
<createTable tableName="XXL_JOB_USER" remarks="JOB 用户表">
<column name="ID" type="INTEGER" remarks="主键ID"/>
<column name="USERNAME" type="NVARCHAR(50)" remarks="账号"/>
<column name="PASSWORD" type="NVARCHAR(50)" remarks="密码"/>
<column name="ROLE" type="TINYINT" remarks="角色:0-普通用户、1-管理员"/>
<column name="PERMISSION" type="NVARCHAR(255)" remarks="权限:执行器ID列表,多个逗号分割"></column>
</createTable>
<addPrimaryKey tableName="XXL_JOB_USER" columnNames="ID"/>
<addAutoIncrement columnName="ID" columnDataType="INTEGER" tableName="XXL_JOB_USER" startWith="1" incrementBy="1"/>
<addNotNullConstraint columnName="USERNAME" columnDataType="NVARCHAR(50)" tableName="XXL_JOB_USER" constraintName="CONST_XXL_JOB_USER_USERNAME"/>
<addNotNullConstraint columnName="PASSWORD" columnDataType="NVARCHAR(50)" tableName="XXL_JOB_USER" constraintName="CONST_XXL_JOB_USER_PASSWORD"/>
<addNotNullConstraint columnName="ROLE" columnDataType="TINYINT" tableName="XXL_JOB_USER" constraintName="CONST_XXL_JOB_USER_ROLE"/>
<!-- JOB 锁表 -->
<createTable tableName="XXL_JOB_LOCK" remarks="JOB 锁表">
<column name="LOCK_NAME" type="NVARCHAR(50)" remarks="锁名称">
<constraints primaryKey="true"/>
</column>
</createTable>
<insert tableName="XXL_JOB_GROUP">
<column name="ID" valueNumeric="1"></column>
<column name="APP_NAME" value="xxl-job-executor-sample"></column>
<column name="TITLE" value="示例执行器"></column>
<column name="ADDRESS_TYPE" valueNumeric="0"></column>
<column name="UPDATE_TIME" valueDate="${now}"></column>
</insert>
<insert tableName="XXL_JOB_INFO">
<column name="ID" valueNumeric="1"></column>
<column name="JOB_GROUP" valueNumeric="1"></column>
<column name="JOB_DESC" value="测试任务1"></column>
<column name="add_time" valueDate="${now}"></column>
<column name="update_time" valueDate="${now}"></column>
<column name="author" value="XXL"></column>
<column name="alarm_email" value=""></column>
<column name="schedule_type" value="CRON"></column>
<column name="schedule_conf" value="0 0 0 * * ? *"></column>
<column name="misfire_strategy" value="DO_NOTHING"></column>
<column name="executor_route_strategy" value="FIRST"></column>
<column name="executor_handler" value="demoJobHandler"></column>
<column name="executor_param" value=""></column>
<column name="executor_block_strategy" value="SERIAL_EXECUTION"></column>
<column name="executor_timeout" valueNumeric="0"></column>
<column name="executor_fail_retry_count" valueNumeric="0"></column>
<column name="glue_type" value="BEAN"></column>
<column name="glue_source" value=""></column>
<column name="glue_remark" value="GLUE代码初始化"></column>
<column name="glue_updatetime" valueDate="${now}"></column>
<column name="child_jobid" value=""></column>
</insert>
<insert tableName="XXL_JOB_USER">
<column name="id" valueNumeric="1"></column>
<column name="username" value="admin"></column>
<column name="password" value="e10adc3949ba59abbe56e057f20f883e"></column>
<column name="role" valueNumeric="1"></column>
</insert>
<insert tableName="XXL_JOB_LOCK">
<column name="lock_name" value="schedule_lock"></column>
</insert>
</changeSet>
</databaseChangeLog>

2
io.sc.platform.lcdp.frontend/.npmrc

@ -8,4 +8,4 @@ email=
# 登录 npm 仓库的用户认证信息, 在 npm publish 时使用, publish 的 npm registry 在 package.json 文件中 publishConfig 部分配置 # 登录 npm 仓库的用户认证信息, 在 npm publish 时使用, publish 的 npm registry 在 package.json 文件中 publishConfig 部分配置
# _authToken 可通过以下命令获取 # _authToken 可通过以下命令获取
# curl -X PUT -H "Content-Type:application/json" -d '{"_id":"org.couchdb.user:admin","name":"admin","password":"admin"}' http://nexus.sc.io:8000/repository/npm-releases/-/user/org.couchdb.user:admin # curl -X PUT -H "Content-Type:application/json" -d '{"_id":"org.couchdb.user:admin","name":"admin","password":"admin"}' http://nexus.sc.io:8000/repository/npm-releases/-/user/org.couchdb.user:admin
//nexus.sc.io:8000/repository/npm-releases/:_authToken=NpmToken.25afcf59-9193-3068-bcfa-faf76ceadb13 //nexus.sc.io:8000/repository/npm-releases/:_authToken=NpmToken.193db44c-7ca5-3cb6-a990-d24b93fb0d10

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

@ -1,9 +1,11 @@
{ {
"name": "io.sc.platform.lcdp.frontend", "name": "io.sc.platform.lcdp.frontend",
"version": "8.1.13", "version": "8.1.19",
"description": "", "description": "",
"private": false, "private": false,
"keywords": [], "keywords": [
],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"scripts": { "scripts": {
@ -90,7 +92,7 @@
"luckyexcel": "1.0.1", "luckyexcel": "1.0.1",
"mockjs": "1.1.0", "mockjs": "1.1.0",
"pinia": "2.1.7", "pinia": "2.1.7",
"platform-core": "8.1.42", "platform-core": "8.1.45",
"quasar": "2.13.0", "quasar": "2.13.0",
"tailwindcss": "3.3.5", "tailwindcss": "3.3.5",
"vue": "3.3.7", "vue": "3.3.7",

9
io.sc.platform.lcdp.frontend/webpack.config.common.cjs

@ -133,6 +133,15 @@ module.exports = {
] ]
}), }),
new CopyWebpackPlugin({
patterns: [
{
from: `public/${projectName}`,
toType: 'dir',
}
]
}),
// vue loader 插件 // vue loader 插件
new VueLoaderPlugin(), new VueLoaderPlugin(),

4
io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/api/Configure.java

@ -1,6 +1,8 @@
package io.sc.platform.lcdp.configure.api; package io.sc.platform.lcdp.configure.api;
public class Configure { import io.sc.platform.orm.api.vo.CorporationAuditorVo;
public class Configure extends CorporationAuditorVo {
private Setting setting =new Setting(); private Setting setting =new Setting();
private Theme theme =new Theme(); private Theme theme =new Theme();

51
io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/api/ConfigureVo.java

@ -0,0 +1,51 @@
package io.sc.platform.lcdp.configure.api;
import io.sc.platform.orm.api.vo.CorporationAuditorVo;
public class ConfigureVo extends CorporationAuditorVo {
private String id;
private String name;
private Boolean active;
private Setting setting;
private Theme theme;
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 Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
public Setting getSetting() {
return setting;
}
public void setSetting(Setting setting) {
this.setting = setting;
}
public Theme getTheme() {
return theme;
}
public void setTheme(Theme theme) {
this.theme = theme;
}
}

3
io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/controller/ConfigureController.java

@ -1,6 +1,7 @@
package io.sc.platform.lcdp.configure.controller; package io.sc.platform.lcdp.configure.controller;
import io.sc.platform.lcdp.configure.api.Configure; import io.sc.platform.lcdp.configure.api.Configure;
import io.sc.platform.lcdp.configure.api.ConfigureVo;
import io.sc.platform.lcdp.configure.jpa.entity.ConfigureEntity; import io.sc.platform.lcdp.configure.jpa.entity.ConfigureEntity;
import io.sc.platform.lcdp.configure.jpa.repository.ConfigureRepository; import io.sc.platform.lcdp.configure.jpa.repository.ConfigureRepository;
import io.sc.platform.lcdp.configure.service.ConfigureService; import io.sc.platform.lcdp.configure.service.ConfigureService;
@ -9,7 +10,7 @@ import org.springframework.web.bind.annotation.*;
@RestController @RestController
@RequestMapping("/api/lcdp/configure") @RequestMapping("/api/lcdp/configure")
public class ConfigureController extends RestCrudController<ConfigureEntity,String, ConfigureRepository, ConfigureService> { public class ConfigureController extends RestCrudController<ConfigureVo, ConfigureEntity,String, ConfigureRepository, ConfigureService> {
@GetMapping("getActiveConfigure") @GetMapping("getActiveConfigure")
public Configure getActiveConfigure(){ public Configure getActiveConfigure(){
return service.getActiveConfigure(); return service.getActiveConfigure();

1
io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/controller/ConfigureJsController.java

@ -10,7 +10,6 @@ public class ConfigureJsController {
@RequestMapping("/configure.js") @RequestMapping("/configure.js")
public String configureJs(){ public String configureJs(){
System.out.println(">>>>>");
return "configure.js"; return "configure.js";
} }
} }

6
io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/initializer/ConfigureInitializer.java

@ -12,6 +12,11 @@ public class ConfigureInitializer implements ApplicationInitializer {
private Boolean isInitialized =null; private Boolean isInitialized =null;
private ConfigureService configureService; private ConfigureService configureService;
@Override
public int getOrder() {
return 2000;
}
@Override @Override
public void init(ApplicationContext applicationContext) { public void init(ApplicationContext applicationContext) {
this.configureService =applicationContext.getBean(ConfigureService.class); this.configureService =applicationContext.getBean(ConfigureService.class);
@ -37,6 +42,7 @@ public class ConfigureInitializer implements ApplicationInitializer {
entity.setActive(true); entity.setActive(true);
entity.setSetting(new Setting()); entity.setSetting(new Setting());
entity.setTheme(new Theme()); entity.setTheme(new Theme());
entity.setCorporationCode("_PRIMARY_");
configureService.getRepository().save(entity); configureService.getRepository().save(entity);
} }
} }

17
io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/jpa/entity/ConfigureEntity.java

@ -1,5 +1,7 @@
package io.sc.platform.lcdp.configure.jpa.entity; package io.sc.platform.lcdp.configure.jpa.entity;
import io.sc.platform.lcdp.configure.api.Configure;
import io.sc.platform.lcdp.configure.api.ConfigureVo;
import io.sc.platform.lcdp.configure.api.Setting; import io.sc.platform.lcdp.configure.api.Setting;
import io.sc.platform.lcdp.configure.api.Theme; import io.sc.platform.lcdp.configure.api.Theme;
import io.sc.platform.lcdp.configure.jpa.converter.SettingStringConverter; import io.sc.platform.lcdp.configure.jpa.converter.SettingStringConverter;
@ -16,7 +18,7 @@ import javax.validation.constraints.Size;
*/ */
@Entity @Entity
@Table(name="LCDP_CONFIGURE") @Table(name="LCDP_CONFIGURE")
public class ConfigureEntity extends CorporationAuditorEntity { public class ConfigureEntity extends CorporationAuditorEntity<ConfigureVo> {
//主键 //主键
@Id @Id
@GeneratedValue(generator = "system-uuid") @GeneratedValue(generator = "system-uuid")
@ -48,6 +50,19 @@ public class ConfigureEntity extends CorporationAuditorEntity {
this.id =id; this.id =id;
} }
@Override
public ConfigureVo toVo() {
ConfigureVo vo =new ConfigureVo();
CorporationAuditorEntity.toVo(vo,this);
vo.setId(this.getId());
vo.setName(this.getName());
vo.setActive(this.getActive());
vo.setSetting(this.getSetting());
vo.setTheme(this.getTheme());
return vo;
}
/** /**
* 获取ID * 获取ID
* @return ID * @return ID

7
io.sc.platform.lcdp/src/main/java/io/sc/platform/lcdp/configure/service/impl/ConfigureServiceImpl.java

@ -26,7 +26,12 @@ public class ConfigureServiceImpl extends DaoServiceImpl<ConfigureEntity, String
public Configure getActiveConfigure() { public Configure getActiveConfigure() {
ConfigureEntity entity =repository.findActiveConfigure(); ConfigureEntity entity =repository.findActiveConfigure();
if(entity!=null) { if(entity!=null) {
return converter.toVo(entity); Configure configure =converter.toVo(entity);
String homePage =systemParameterService.getParameter("parameter.system.homePage");
if(StringUtils.hasText(homePage)) {
configure.getSetting().setHomePage(homePage);
}
return configure;
}else{ }else{
Configure configure = new Configure(); Configure configure = new Configure();
String homePage =systemParameterService.getParameter("parameter.system.homePage"); String homePage =systemParameterService.getParameter("parameter.system.homePage");

5
io.sc.platform.lcdp/src/main/resources/META-INF/platform/plugins/messages.json

@ -0,0 +1,5 @@
{
includes:[
"io/sc/platform/lcdp/configure/i18n/initializer"
]
}

2
io.sc.platform.lcdp/src/main/resources/io/sc/platform/lcdp/configure/i18n/initializer.properties

@ -0,0 +1,2 @@
io.sc.platform.lcdp.configure.initializer.ConfigureInitializer.name=Configure Initializer
io.sc.platform.lcdp.configure.initializer.ConfigureInitializer.description=initialize default theme if not exists

2
io.sc.platform.lcdp/src/main/resources/io/sc/platform/lcdp/configure/i18n/initializer_tw_CN.properties

@ -0,0 +1,2 @@
io.sc.platform.lcdp.configure.initializer.ConfigureInitializer.name=\u4E3B\u984C\u98A8\u683C\u521D\u59CB\u5316\u5668
io.sc.platform.lcdp.configure.initializer.ConfigureInitializer.description=\u7576\u7CFB\u7D71\u7F3A\u5931\u4E3B\u984C\u98A8\u683C\u6642, \u81EA\u52D5\u5275\u5EFA\u9ED8\u8A8D\u4E3B\u984C\u98A8\u683C

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

Loading…
Cancel
Save