From af7205981ff281b2b4568cffa7cc6b516248a25a Mon Sep 17 00:00:00 2001 From: zhangbinhub Date: Thu, 15 May 2025 17:47:35 +0800 Subject: [PATCH 1/3] v6.8.0 --- README.md | 6 +- .../admin/common/api/WorkFlowApi.kt | 17 +- .../admin/common/constant/DbConstant.kt | 1 + .../admin/common/constant/WorkFlowConstant.kt | 46 +- ...esourceServerComponentAutoConfiguration.kt | 8 +- .../server/feign/CommonOauthServer.kt | 45 +- .../resource/server/feign/WorkFlowServer.kt | 103 +- .../hystrix/CommonOauthServerHystrix.kt | 36 +- .../server/hystrix/WorkFlowServerHystrix.kt | 67 +- .../resource/server/po/MyProcessQueryPo.kt | 19 + .../resource/server/po/ProcessHandlingPo.kt | 27 +- .../resource/server/po/ProcessQueryPo.kt | 18 +- .../resource/server/po/ProcessStartPo.kt | 24 +- .../resource/server/po/ProcessTaskQueryPo.kt | 11 + .../server/po/ProcessTerminationPo.kt | 16 +- .../admin/resource/server/tools/TokenTools.kt | 12 +- .../resource/server/vo/OrganizationVo.kt | 5 +- .../resource/server/vo/ProcessDefinitionVo.kt | 20 +- .../server/vo/ProcessHighlightElementVo.kt | 11 - .../server/vo/ProcessHighlightLineVo.kt | 13 - .../server/vo/ProcessHighlightNodeVo.kt | 19 - ...storyActivityVo.kt => ProcessHisTaskVo.kt} | 54 +- .../resource/server/vo/ProcessInstanceVo.kt | 34 +- .../admin/resource/server/vo/ProcessTaskVo.kt | 62 +- .../admin/resource/server/vo/RoleVo.kt | 11 +- .../admin/resource/server/vo/UserVo.kt | 3 + .../admin/common/base/BaseController.kt | 4 - .../admin/common/base/BaseQueryPo.kt | 4 - .../zhangbinhub/admin/common/po/QueryParam.kt | 4 - doc/nacos_config_export_dev.zip | Bin 4442 -> 4518 bytes doc/version_history.md | 10 + gradle/dependencies.gradle | 5 +- gradle/moduleVersion.gradle | 20 +- .../admin/gateway/conf/RouteConfiguration.kt | 28 +- .../admin/oauth/base/OauthBaseService.kt | 9 + .../oauth/controller/api/OrgController.kt | 7 +- .../oauth/controller/api/RoleController.kt | 2 +- .../controller/inner/InnerOrgController.kt | 2 +- .../openinner/OpenInnerOrgController.kt | 25 +- .../openinner/OpenInnerRoleController.kt | 40 + .../openinner/OpenInnerUserController.kt | 15 +- .../zhangbinhub/admin/oauth/entity/Menu.kt | 3 +- .../admin/oauth/entity/ModuleFunc.kt | 3 +- .../admin/oauth/entity/Organization.kt | 6 +- .../zhangbinhub/admin/oauth/entity/Role.kt | 9 +- .../zhangbinhub/admin/oauth/entity/User.kt | 9 +- .../oauth/service/OrganizationService.kt | 21 +- .../admin/oauth/service/RoleService.kt | 22 +- .../admin/oauth/service/UserService.kt | 4 + .../admin/oauth/vo/OrganizationVo.kt | 33 - .../zhangbinhub/admin/oauth/vo/RoleVo.kt | 42 - modules/workflow-server/README.md | 56 +- modules/workflow-server/build.gradle | 3 +- .../workflow/WorkFlowServerApplication.kt | 4 - .../admin/workflow/base/BaseWorkFlowNotify.kt | 12 +- .../workflow/base/BaseWorkFlowService.kt | 36 +- .../component/WorkFlowGlobalListener.kt | 210 ++++ .../workflow/component/WorkFlowListener.kt | 135 --- .../component/WorkFlowPermissionHandler.kt | 54 + .../component/WorkFlowSelectService.kt | 168 +++ .../workflow/conf/MybatisFlexConfiguration.kt | 24 + .../workflow/constant/WorkFlowConstant.kt | 8 +- .../workflow/constant/WorkFlowExpression.kt | 4 - .../workflow/constant/WorkFlowParamKey.kt | 25 - .../controller/api/WorkFlowController.kt | 322 +++--- .../api/WorkFlowDefinitionController.kt | 110 +- .../openinner/OpenInnerWorkFlowController.kt | 109 +- .../workflow/entity/MyProcessInstance.kt | 2 +- .../workflow/entity/WorkFlowDefinition.kt | 57 - .../admin/workflow/init/DataInitialization.kt | 39 + .../notify/LogPendingCreatedNotify.kt | 14 +- .../notify/LogPendingFinishedNotify.kt | 14 +- .../admin/workflow/po/ProcessDefinitionPo.kt | 20 + ...QueryPo.kt => ProcessDefinitionQueryPo.kt} | 14 +- .../admin/workflow/po/WorkFlowDefinitionPo.kt | 19 - .../repo/MyProcessInstanceRepository.kt | 2 +- .../repo/WorkFlowDefinitionRepository.kt | 12 - .../service/WorkFlowDefinitionService.kt | 226 ++-- .../admin/workflow/service/WorkFlowService.kt | 1027 +++++++++-------- .../src/main/resources/application.yaml | 3 +- .../init-sql/mysql/warm-flow-all.sql | 149 +++ 81 files changed, 2034 insertions(+), 1859 deletions(-) create mode 100644 common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/MyProcessQueryPo.kt create mode 100644 common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessTaskQueryPo.kt delete mode 100644 common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightElementVo.kt delete mode 100644 common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightLineVo.kt delete mode 100644 common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightNodeVo.kt rename common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/{ProcessHistoryActivityVo.kt => ProcessHisTaskVo.kt} (43%) create mode 100644 modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerRoleController.kt delete mode 100644 modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/vo/OrganizationVo.kt delete mode 100644 modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/vo/RoleVo.kt create mode 100644 modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowGlobalListener.kt delete mode 100644 modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowListener.kt create mode 100644 modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowPermissionHandler.kt create mode 100644 modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowSelectService.kt create mode 100644 modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/conf/MybatisFlexConfiguration.kt delete mode 100644 modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/entity/WorkFlowDefinition.kt create mode 100644 modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/init/DataInitialization.kt create mode 100644 modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/ProcessDefinitionPo.kt rename modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/{WorkFlowDefinitionQueryPo.kt => ProcessDefinitionQueryPo.kt} (54%) delete mode 100644 modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/WorkFlowDefinitionPo.kt delete mode 100644 modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/repo/WorkFlowDefinitionRepository.kt create mode 100644 modules/workflow-server/src/main/resources/init-sql/mysql/warm-flow-all.sql diff --git a/README.md b/README.md index b85da720..66316565 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # acp-admin-cloud -###### v6.7.3 [版本更新日志](doc/version_history.md) +###### v6.8.0 [版本更新日志](doc/version_history.md) - 使用Application Construction Platform 应用构建平台作为脚手架 - 基于 Spring Cloud 的微服务版本,基于 Spring Boot @@ -9,9 +9,9 @@ ## 相关组件版本 -- [Spring Boot 3.4.4](https://projects.spring.io/spring-boot) +- [Spring Boot 3.4.5](https://projects.spring.io/spring-boot) - [Spring Boot Admin 3.4.5](https://github.com/codecentric/spring-boot-admin) -- [Acp 2025.2.1](https://gitee.com/zhangbinhub/acp) +- [Acp 2025.4.0](https://gitee.com/zhangbinhub/acp) - [sensitive](https://github.com/houbb/sensitive) ## 技术栈 diff --git a/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/api/WorkFlowApi.kt b/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/api/WorkFlowApi.kt index f8adc781..7d8825c9 100644 --- a/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/api/WorkFlowApi.kt +++ b/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/api/WorkFlowApi.kt @@ -1,24 +1,23 @@ package io.gitee.zhangbinhub.admin.common.api -/** - * @author zhang by 10/06/2019 - * @since JDK 11 - */ object WorkFlowApi { const val basePath = "/workflow" const val definition = "/definition" - const val definitionDeploy = "$definition/deploy" + const val definitionPublish = "$definition/publish" + const val definitionActive = "$definition/active" + const val definitionImport = "$definition/import" + const val definitionExport = "$definition/export" const val start = "/start" const val pending = "/pending" const val distribute = "/distribute" - const val claim = "/claim" const val transfer = "/transfer" - const val delegate = "/delegate" + const val depute = "/depute" + const val addSignature = "/addSignature" + const val reductionSignature = "/reductionSignature" const val process = "/process" const val history = "/history" const val instance = "/instance" - const val instanceDefinition = "/instance-definition" - const val instanceHighlight = "/instance-highlight" + const val instanceChart = "/instance-chart" const val termination = "$instance/termination" const val myProcess = "$instance/my-process" const val task = "/task" diff --git a/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/constant/DbConstant.kt b/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/constant/DbConstant.kt index 1f6c89bc..c7df8fb3 100644 --- a/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/constant/DbConstant.kt +++ b/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/constant/DbConstant.kt @@ -1,5 +1,6 @@ package io.gitee.zhangbinhub.admin.common.constant object DbConstant { + const val SCHEMA_PATH = "init-sql" const val ORDER_NAME_PATTERN = "^[a-zA-Z0-9,`]+$" } \ No newline at end of file diff --git a/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/constant/WorkFlowConstant.kt b/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/constant/WorkFlowConstant.kt index fe8f3aa8..743608d1 100644 --- a/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/constant/WorkFlowConstant.kt +++ b/common/acp-admin-cloud-constant/src/main/kotlin/io/gitee/zhangbinhub/admin/common/constant/WorkFlowConstant.kt @@ -1,45 +1,9 @@ package io.gitee.zhangbinhub.admin.common.constant object WorkFlowConstant { - /** - * 工作流任务自定义字段 - */ - //当前任务是否可撤销 - const val termination = "isTermination" - - //当前任务是否可以转办(任务处理人变更,处理完毕后进入下一节点) - const val transfer = "isTransfer" - - //当前任务是否可以委派他人办理(任务处理人变更,处理完毕后返回至当前处理人继续办理) - const val delegate = "isDelegate" - - //是否手动选择分配处理人(或候选人) - const val selectUser = "selectUser" - - //待发送用户部门级别,负数|零|正数;0-当前用户所在部门,-1上一级部门,-2上两级部门...依次类推,1下一级部门,2下两级部门...依次类推,多个code时使用“,”分隔 - const val orgLevel = "orgLevel" - - //待发送用户所属角色code,多个code时使用“,”分隔 - const val roleCode = "roleCode" - - //下一节点是否使用候选人模式 - const val candidate = "isCandidate" - - //任务编码,用于自定义判断任务处理方式 - const val taskCode = "taskCode" - - //当前任务是否允许驳回 - const val reject = "isReject" - - //驳回至目标任务的定义ID,多个值时使用“,”分隔 - const val rejectToTask = "rejectToTask" - - /** - * 工作流自定义参数 - */ - //节点任务候选人ID(一人或多人),多个候选人时使用“,”分隔;任务处理完成后需修改(变更为下一节点人或置空) - const val candidateUser = "candidateUser" - - //节点任务处理人ID(只能一人);任务处理完成后需修改(变更为下一节点人或置空) - const val assigneeUser = "assigneeUser" + const val PERMISSION_ROLE_PREFIX = "ROLE:" + const val PERMISSION_DEPT_PREFIX = "DEPT:" + const val NODE_EXT_START_TIME = "开始时间" + const val NODE_EXT_FINISH_TIME = "完成时间" + const val NODE_EXT_APPROVAL = "办理人" } \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/AcpAdminResourceServerComponentAutoConfiguration.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/AcpAdminResourceServerComponentAutoConfiguration.kt index e058e450..5a3ed18f 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/AcpAdminResourceServerComponentAutoConfiguration.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/AcpAdminResourceServerComponentAutoConfiguration.kt @@ -6,13 +6,9 @@ import io.gitee.zhangbinhub.admin.resource.server.tools.TokenTools import org.springframework.boot.autoconfigure.AutoConfiguration import org.springframework.context.annotation.Bean -/** - * @author zhang by 30/07/2019 - * @since JDK 11 - */ @AutoConfiguration class AcpAdminResourceServerComponentAutoConfiguration { @Bean - fun tokenTools(logAdapter: LogAdapter, objectMapper: ObjectMapper): TokenTools = - TokenTools(logAdapter, objectMapper) + fun tokenTools(objectMapper: ObjectMapper): TokenTools = + TokenTools(objectMapper) } \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/feign/CommonOauthServer.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/feign/CommonOauthServer.kt index 3c1a2b24..1621a4d4 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/feign/CommonOauthServer.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/feign/CommonOauthServer.kt @@ -59,15 +59,6 @@ interface CommonOauthServer { @PathVariable(name = "moduleFuncCode") moduleFuncCode: String ): BooleanInfoVo - /** - * 获取所有机构列表 - */ - @GetMapping( - value = [CommonPath.openInnerBasePath + OauthApi.orgConfig], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) - fun orgList(): List - /** * 获取所属机构及其所有子机构列表(所属机构) */ @@ -155,6 +146,15 @@ interface CommonOauthServer { ) fun findUserList(@RequestBody idList: List): List + /** + * 获取用户列表 + */ + @GetMapping( + value = [CommonPath.openInnerBasePath + OauthApi.userList], + produces = [MediaType.APPLICATION_JSON_VALUE] + ) + fun findUserList(): List + /** * 获取用户列表 */ @@ -209,4 +209,31 @@ interface CommonOauthServer { ) fun findRuntimeConfigMap(): Map + @GetMapping( + value = [CommonPath.openInnerBasePath + OauthApi.orgConfig + "/{orgId}"], + produces = [MediaType.APPLICATION_JSON_VALUE] + ) + fun findOrgById(@PathVariable(name = "orgId") orgId: String): OrganizationVo + + /** + * 获取所有机构列表 + */ + @GetMapping( + value = [CommonPath.openInnerBasePath + OauthApi.orgConfig], + produces = [MediaType.APPLICATION_JSON_VALUE] + ) + fun orgList(): List + + @GetMapping( + value = [CommonPath.openInnerBasePath + OauthApi.roleConfig + "/{roleId}"], + produces = [MediaType.APPLICATION_JSON_VALUE] + ) + fun findRoleById(@PathVariable(name = "roleId") roleId: String): RoleVo + + @GetMapping( + value = [CommonPath.openInnerBasePath + OauthApi.roleConfig], + produces = [MediaType.APPLICATION_JSON_VALUE] + ) + fun roleList(): List + } \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/feign/WorkFlowServer.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/feign/WorkFlowServer.kt index 16f14a34..d635f4ee 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/feign/WorkFlowServer.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/feign/WorkFlowServer.kt @@ -7,17 +7,23 @@ import io.gitee.zhangbinhub.admin.resource.server.hystrix.WorkFlowServerHystrix import io.gitee.zhangbinhub.admin.resource.server.po.ProcessHandlingPo import io.gitee.zhangbinhub.admin.resource.server.po.ProcessStartPo import io.gitee.zhangbinhub.admin.resource.server.po.ProcessTerminationPo -import io.gitee.zhangbinhub.admin.resource.server.vo.* +import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessInstanceVo +import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessTaskVo import org.springframework.cloud.openfeign.FeignClient import org.springframework.http.MediaType import org.springframework.web.bind.annotation.* -/** - * @author zhang by 20/12/2019 - * @since JDK 11 - */ @FeignClient(value = "workflow-server", fallbackFactory = WorkFlowServerHystrix::class) interface WorkFlowServer { + /** + * 获取任务信息 + */ + @GetMapping( + value = [CommonPath.openInnerBasePath + WorkFlowApi.task + "/{taskId}"], + produces = [MediaType.APPLICATION_JSON_VALUE] + ) + fun getTaskInfoOpen(@PathVariable(name = "taskId") taskId: String): ProcessTaskVo? + /** * 启动流程 */ @@ -81,96 +87,9 @@ interface WorkFlowServer { ) fun getInstance(@PathVariable(name = "processInstanceId") processInstanceId: String): ProcessInstanceVo? - /** - * 获取任务信息 - */ - @GetMapping( - value = [CommonPath.openInnerBasePath + WorkFlowApi.task + "/{taskId}"], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) - fun getTaskInfoOpen(@PathVariable(name = "taskId") taskId: String): ProcessTaskVo? - - @GetMapping( - value = [CommonPath.openInnerBasePath + WorkFlowApi.instanceDefinition + "/{processInstanceId}"], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) - fun getInstanceDefinition(@PathVariable(name = "processInstanceId") processInstanceId: String): ProcessDefinitionVo? - - @GetMapping( - value = [CommonPath.openInnerBasePath + WorkFlowApi.instanceHighlight + "/{processInstanceId}"], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) - fun getInstanceHighlight(@PathVariable(name = "processInstanceId") processInstanceId: String): ProcessHighlightElementVo? - /** * 启动流程 */ @PutMapping(value = [WorkFlowApi.basePath + WorkFlowApi.start], produces = [MediaType.APPLICATION_JSON_VALUE]) fun start(@RequestBody processStartPo: ProcessStartPo): InnerInfoVo - - /** - * 领取任务 - */ - @PatchMapping( - value = [WorkFlowApi.basePath + WorkFlowApi.claim + "/{taskId}"], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) - fun claim(@PathVariable(name = "taskId") taskId: String): InnerInfoVo - - /** - * 转办任务 - */ - @PatchMapping( - value = [WorkFlowApi.basePath + WorkFlowApi.transfer + "/{taskId}/{userId}"], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) - fun transfer( - @PathVariable(name = "taskId") taskId: String, - @PathVariable(name = "userId") userId: String - ): InnerInfoVo - - /** - * 委托任务 - */ - @PatchMapping( - value = [WorkFlowApi.basePath + WorkFlowApi.delegate + "/{taskId}/{acceptUserId}"], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) - fun delegate( - @PathVariable(name = "taskId") taskId: String, - @PathVariable(name = "acceptUserId") acceptUserId: String - ): InnerInfoVo - - /** - * 流程处理 - */ - @PostMapping(value = [WorkFlowApi.basePath + WorkFlowApi.process], produces = [MediaType.APPLICATION_JSON_VALUE]) - fun process(@RequestBody processHandlingPo: ProcessHandlingPo): InnerInfoVo - - /** - * 强制终止流程实例 - */ - @DeleteMapping( - value = [WorkFlowApi.basePath + WorkFlowApi.termination], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) - fun termination(@RequestBody processTerminationPo: ProcessTerminationPo): InnerInfoVo - - /** - * 获取流程处理记录 - */ - @GetMapping( - value = [WorkFlowApi.basePath + WorkFlowApi.history + "/{processInstanceId}"], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) - fun getHistoryActivity(@PathVariable(name = "processInstanceId") processInstanceId: String): List - - /** - * 获取任务信息 - */ - @GetMapping( - value = [WorkFlowApi.basePath + WorkFlowApi.task + "/{taskId}"], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) - fun getTaskInfo(@PathVariable(name = "taskId") taskId: String): ProcessTaskVo? } \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/hystrix/CommonOauthServerHystrix.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/hystrix/CommonOauthServerHystrix.kt index bd01c3d2..cabbeaf7 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/hystrix/CommonOauthServerHystrix.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/hystrix/CommonOauthServerHystrix.kt @@ -70,12 +70,6 @@ class CommonOauthServerHystrix(logAdapter: LogAdapter, objectMapper: ObjectMappe return BooleanInfoVo(result = false) } - override fun orgList(): List { - val errMsg = "获取机构列表失败" - logAdapter.error(errMsg) - return listOf() - } - override fun currAndAllChildrenForOrg(): List { val errMsg = "获取机构列表失败" logAdapter.error(errMsg) @@ -148,6 +142,12 @@ class CommonOauthServerHystrix(logAdapter: LogAdapter, objectMapper: ObjectMappe return listOf() } + override fun findUserList(): List { + val errMsg = "获取用户列表失败" + logAdapter.error(errMsg) + return listOf() + } + override fun findUserList(orgCode: String, roleCode: String): List { val errMsg = "找不到对应的用户信息【org=$orgCode,role=$roleCode】" logAdapter.error(errMsg) @@ -175,6 +175,30 @@ class CommonOauthServerHystrix(logAdapter: LogAdapter, objectMapper: ObjectMappe logAdapter.error("获取运行参数失败") return mapOf() } + + override fun findOrgById(orgId: String): OrganizationVo { + val errMsg = "找不到对应的机构信息" + logAdapter.error(errMsg) + return OrganizationVo(id = orgId) + } + + override fun orgList(): List { + val errMsg = "获取机构列表失败" + logAdapter.error(errMsg) + return listOf() + } + + override fun findRoleById(roleId: String): RoleVo { + val errMsg = "找不到对应的角色信息" + logAdapter.error(errMsg) + return RoleVo(id = roleId) + } + + override fun roleList(): List { + val errMsg = "获取角色列表失败" + logAdapter.error(errMsg) + return listOf() + } } } } \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/hystrix/WorkFlowServerHystrix.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/hystrix/WorkFlowServerHystrix.kt index b918dd55..3658a5bd 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/hystrix/WorkFlowServerHystrix.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/hystrix/WorkFlowServerHystrix.kt @@ -20,6 +20,12 @@ class WorkFlowServerHystrix(logAdapter: LogAdapter, objectMapper: ObjectMapper) logAdapter.error("调用 workflow-server 异常: " + cause?.message, cause) val message = getErrorMessage(cause) return object : WorkFlowServer { + override fun getTaskInfoOpen(taskId: String): ProcessTaskVo? { + val errMsg = "获取任务信息失败:$message" + logAdapter.error(errMsg) + return null + } + override fun startInner(processStartPo: ProcessStartPo): InnerInfoVo { val errMsg = "流程启动失败:$message" logAdapter.error(errMsg) @@ -56,72 +62,11 @@ class WorkFlowServerHystrix(logAdapter: LogAdapter, objectMapper: ObjectMapper) return InnerInfoVo(success = false, message = errMsg) } - override fun claim(taskId: String): InnerInfoVo { - val errMsg = "任务领取失败:$message" - logAdapter.error(errMsg) - return InnerInfoVo(success = false, message = errMsg) - } - - override fun transfer(taskId: String, userId: String): InnerInfoVo { - val errMsg = "任务转办失败:$message" - logAdapter.error(errMsg) - return InnerInfoVo(success = false, message = errMsg) - } - - override fun delegate(taskId: String, acceptUserId: String): InnerInfoVo { - val errMsg = "任务委托办理失败:$message" - logAdapter.error(errMsg) - return InnerInfoVo(success = false, message = errMsg) - } - - override fun process(processHandlingPo: ProcessHandlingPo): InnerInfoVo { - val errMsg = "任务处理失败:$message" - logAdapter.error(errMsg) - return InnerInfoVo(success = false, message = errMsg) - } - - override fun termination(processTerminationPo: ProcessTerminationPo): InnerInfoVo { - val errMsg = "强制终止流程实例失败:$message" - logAdapter.error(errMsg) - return InnerInfoVo(success = false, message = errMsg) - } - override fun getInstance(processInstanceId: String): ProcessInstanceVo? { val errMsg = "获取流程实例失败:$message" logAdapter.error(errMsg) return null } - - override fun getTaskInfoOpen(taskId: String): ProcessTaskVo? { - val errMsg = "获取任务信息失败:$message" - logAdapter.error(errMsg) - return null - } - - override fun getInstanceDefinition(processInstanceId: String): ProcessDefinitionVo? { - val errMsg = "获取流程定义失败:$message" - logAdapter.error(errMsg) - return null - } - - override fun getInstanceHighlight(processInstanceId: String): ProcessHighlightElementVo? { - val errMsg = "获取流程高亮元素失败:$message" - logAdapter.error(errMsg) - return null - } - - override fun getHistoryActivity(processInstanceId: String): List { - val errMsg = "获取流程处理记录失败:$message" - logAdapter.error(errMsg) - return listOf() - } - - override fun getTaskInfo(taskId: String): ProcessTaskVo? { - val errMsg = "获取任务信息失败:$message" - logAdapter.error(errMsg) - return null - } - } } } \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/MyProcessQueryPo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/MyProcessQueryPo.kt new file mode 100644 index 00000000..3b6a19c5 --- /dev/null +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/MyProcessQueryPo.kt @@ -0,0 +1,19 @@ +package io.gitee.zhangbinhub.admin.resource.server.po + +import io.gitee.zhangbinhub.admin.common.base.BaseQueryPo +import io.swagger.v3.oas.annotations.media.Schema + +data class MyProcessQueryPo( + @Schema(description = "流程定义键") + var processDefinitionKeys: MutableList? = null, + @Schema(description = "流程实例ID") + var processInstanceIds: MutableList? = null, + @Schema(description = "业务键") + var processBusinessKey: String? = null, + @Schema(description = "发起人") + var startUserId: String? = null, + @Schema(description = "匹配创建时间(开始)") + var startTime: Long? = null, + @Schema(description = "匹配创建时间(结束)") + var endTime: Long? = null +) : BaseQueryPo() \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessHandlingPo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessHandlingPo.kt index b7312551..805d21a0 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessHandlingPo.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessHandlingPo.kt @@ -1,29 +1,18 @@ package io.gitee.zhangbinhub.admin.resource.server.po import io.swagger.v3.oas.annotations.media.Schema -import jakarta.validation.constraints.NotBlank import jakarta.validation.constraints.NotNull -/** - * @author zhang by 14/06/2019 - * @since JDK 11 - */ @Schema(description = "流程任务处理参数") data class ProcessHandlingPo( - @Schema(description = "任务id", requiredMode = Schema.RequiredMode.REQUIRED) - @get:NotBlank(message = "任务id不能为空") - var taskId: String? = null, - - @Schema(description = "处理结果", requiredMode = Schema.RequiredMode.REQUIRED) - @get:NotNull(message = "处理结果不能为空") + @Schema(description = "任务id", required = true) + @field:NotNull(message = "任务id不能为空") + var taskId: Long? = null, + @Schema(description = "处理结果", required = true) + @field:NotNull(message = "处理结果不能为空") var pass: Boolean? = null, - - @Schema(description = "处理意见", requiredMode = Schema.RequiredMode.REQUIRED) - var comment: String? = null, - + @Schema(description = "处理意见", required = true) + var message: String? = null, @Schema(description = "自定义流程参数") - var params: MutableMap = mutableMapOf(), - - @Schema(description = "自定义本地参数") - var localParams: MutableMap = mutableMapOf() + var params: MutableMap = mutableMapOf() ) diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessQueryPo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessQueryPo.kt index 6f445ec5..cc703a62 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessQueryPo.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessQueryPo.kt @@ -3,23 +3,13 @@ package io.gitee.zhangbinhub.admin.resource.server.po import io.gitee.zhangbinhub.admin.common.base.BaseQueryPo import io.swagger.v3.oas.annotations.media.Schema -/** - * @author zhang by 20/12/2019 - * @since JDK 11 - */ data class ProcessQueryPo( - @Schema(description = "流程定义键") - var processDefinitionKeys: MutableList? = null, @Schema(description = "流程实例ID") - var processInstanceIds: MutableList? = null, + var processInstanceId: Long? = null, @Schema(description = "业务键") var processBusinessKey: String? = null, + @Schema(description = "流程状态") + var flowStatus: String? = null, @Schema(description = "发起人") - var startUserId: String? = null, - @Schema(description = "匹配创建时间(开始)") - var startTime: Long? = null, - @Schema(description = "匹配创建时间(结束)") - var endTime: Long? = null, - @Schema(description = "流程是否已结束") - var finished: Boolean? = null + var startUserId: String? = null ) : BaseQueryPo() \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessStartPo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessStartPo.kt index d3b7cb6a..c516f078 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessStartPo.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessStartPo.kt @@ -3,28 +3,20 @@ package io.gitee.zhangbinhub.admin.resource.server.po import io.swagger.v3.oas.annotations.media.Schema import jakarta.validation.constraints.NotBlank -/** - * @author zhang by 14/06/2019 - * @since JDK 11 - */ @Schema(description = "启动流程参数") data class ProcessStartPo( - @Schema(description = "流程定义键", requiredMode = Schema.RequiredMode.REQUIRED) - @get:NotBlank(message = "流程定义键不能为空") + @Schema(description = "流程定义键", required = true) + @field:NotBlank(message = "流程定义键不能为空") var processDefinitionKey: String? = null, - - @Schema(description = "业务键", requiredMode = Schema.RequiredMode.REQUIRED) - @get:NotBlank(message = "业务键不能为空") + @Schema(description = "业务键", required = true) + @field:NotBlank(message = "业务键不能为空") var businessKey: String? = null, - - @Schema(description = "标题", requiredMode = Schema.RequiredMode.REQUIRED) - @get:NotBlank(message = "标题不能为空") + @Schema(description = "标题", required = true) + @field:NotBlank(message = "标题不能为空") var title: String? = null, - - @Schema(description = "流程描述", requiredMode = Schema.RequiredMode.REQUIRED) - @get:NotBlank(message = "流程描述不能为空") + @Schema(description = "流程描述", required = true) + @field:NotBlank(message = "流程描述不能为空") var description: String? = null, - @Schema(description = "自定义参数") var params: MutableMap = mutableMapOf() ) diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessTaskQueryPo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessTaskQueryPo.kt new file mode 100644 index 00000000..1dd350e9 --- /dev/null +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessTaskQueryPo.kt @@ -0,0 +1,11 @@ +package io.gitee.zhangbinhub.admin.resource.server.po + +import io.gitee.zhangbinhub.admin.common.base.BaseQueryPo +import io.swagger.v3.oas.annotations.media.Schema + +data class ProcessTaskQueryPo( + @Schema(description = "流程实例ID") + var processInstanceId: Long? = null, + @Schema(description = "业务键") + var processBusinessKey: String? = null +) : BaseQueryPo() \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessTerminationPo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessTerminationPo.kt index 00f22195..5267f712 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessTerminationPo.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/po/ProcessTerminationPo.kt @@ -2,18 +2,14 @@ package io.gitee.zhangbinhub.admin.resource.server.po import io.swagger.v3.oas.annotations.media.Schema import jakarta.validation.constraints.NotBlank +import jakarta.validation.constraints.NotNull -/** - * @author zhang by 14/06/2019 - * @since JDK 11 - */ @Schema(description = "强制终止流程实例参数") data class ProcessTerminationPo( - @Schema(description = "流程实例ID", requiredMode = Schema.RequiredMode.REQUIRED) - @get:NotBlank(message = "流程实例ID不能为空") - var processInstanceId: String? = null, - - @Schema(description = "原因", requiredMode = Schema.RequiredMode.REQUIRED) - @get:NotBlank(message = "原因不能为空") + @Schema(description = "流程实例ID", required = true) + @field:NotNull(message = "流程实例ID不能为空") + var processInstanceId: Long? = null, + @Schema(description = "原因", required = true) + @field:NotBlank(message = "原因不能为空") var reason: String? = null ) diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/tools/TokenTools.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/tools/TokenTools.kt index 6a60ae0f..025cc0a4 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/tools/TokenTools.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/tools/TokenTools.kt @@ -12,10 +12,7 @@ import org.springframework.security.oauth2.core.OAuth2ErrorCodes import org.springframework.security.oauth2.server.resource.authentication.BearerTokenAuthentication import org.springframework.security.oauth2.server.resource.introspection.OAuth2IntrospectionAuthenticatedPrincipal -class TokenTools( - private val logAdapter: LogAdapter, - private val objectMapper: ObjectMapper -) { +class TokenTools(private val objectMapper: ObjectMapper) { @Throws(OAuth2AuthenticationException::class) fun encryptUserInfo(userInfoVo: TokenUserInfoVo): String = try { Base64.toBase64String(objectMapper.writeValueAsBytes(userInfoVo)) @@ -40,11 +37,6 @@ class TokenTools( (getAuthenticatedPrincipal(bearerTokenAuthentication).getClaim( AcpCloudResourceServerConstant.TOKEN_CLAIMS_USER_INFO ) as? String)?.let { claimValue -> - try { - decryptUserInfo(claimValue) - } catch (e: Exception) { - logAdapter.error(e.message, e) - TokenUserInfoVo() - } + decryptUserInfo(claimValue) } ?: TokenUserInfoVo() } \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/OrganizationVo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/OrganizationVo.kt index 15cc3928..6c1690dd 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/OrganizationVo.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/OrganizationVo.kt @@ -25,6 +25,9 @@ data class OrganizationVo( var parentId: String? = null, @Schema(description = "序号") - var sort: Int = 0 + var sort: Int = 0, + + @Schema(description = "关联用户ID") + var userIds: MutableList = mutableListOf() ) diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessDefinitionVo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessDefinitionVo.kt index 296505c1..13333c15 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessDefinitionVo.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessDefinitionVo.kt @@ -6,8 +6,22 @@ import io.swagger.v3.oas.annotations.media.Schema data class ProcessDefinitionVo( @Schema(description = "流程定义id") var id: String? = null, - @Schema(description = "名称") - var name: String? = null, + @Schema(description = "流程编码") + var flowCode: String? = null, + @Schema(description = "流程名称") + var flowName: String? = null, + @Schema(description = "流程版本") + var version: String? = null, + @Schema(description = "流程类别") + var category: String? = null, @Schema(description = "定义内容") - var content: String? = null + var content: String? = null, + @Schema(description = "创建时间") + var createTime: Long = System.currentTimeMillis(), + @Schema(description = "最后更新时间") + var updateTime: Long = System.currentTimeMillis(), + @Schema(description = "发布状态") + var publishStatus: Int? = null, + @Schema(description = "激活状态") + var activityStatus: Int? = null ) \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightElementVo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightElementVo.kt deleted file mode 100644 index daa81189..00000000 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightElementVo.kt +++ /dev/null @@ -1,11 +0,0 @@ -package io.gitee.zhangbinhub.admin.resource.server.vo - -import io.swagger.v3.oas.annotations.media.Schema - -@Schema(description = "工作流高亮元素") -data class ProcessHighlightElementVo( - @Schema(description = "高亮节点列表") - var highlightNodeList: MutableList = mutableListOf(), - @Schema(description = "高亮连线列表") - var highlightLineList: MutableList = mutableListOf() -) \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightLineVo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightLineVo.kt deleted file mode 100644 index afec144f..00000000 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightLineVo.kt +++ /dev/null @@ -1,13 +0,0 @@ -package io.gitee.zhangbinhub.admin.resource.server.vo - -import io.swagger.v3.oas.annotations.media.Schema - -@Schema(description = "高亮连线") -data class ProcessHighlightLineVo( - @Schema(description = "元素id") - var id: String? = null, - @Schema(description = "起始元素id") - var sourceId: String? = null, - @Schema(description = "目标元素id") - var targetId: String? = null -) \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightNodeVo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightNodeVo.kt deleted file mode 100644 index 5082e09e..00000000 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHighlightNodeVo.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.gitee.zhangbinhub.admin.resource.server.vo - -import io.swagger.v3.oas.annotations.media.Schema - -@Schema(description = "高亮节点") -data class ProcessHighlightNodeVo( - @Schema(description = "元素id") - var id: String? = null, - @Schema(description = "元素类型") - var type: String? = null, - @Schema(description = "元素名称") - var name: String? = null, - @Schema(description = "开始时间") - var startTime: Long? = null, - @Schema(description = "完成时间") - var endTime: Long? = null, - @Schema(description = "是否完成") - var complete: Boolean? = null -) \ No newline at end of file diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHistoryActivityVo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHisTaskVo.kt similarity index 43% rename from common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHistoryActivityVo.kt rename to common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHisTaskVo.kt index 5474eeb3..41ed9869 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHistoryActivityVo.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessHisTaskVo.kt @@ -2,48 +2,32 @@ package io.gitee.zhangbinhub.admin.resource.server.vo import io.swagger.v3.oas.annotations.media.Schema -/** - * @author zhang by 14/06/2019 - * @since JDK 11 - */ @Schema(description = "流程历史记录") -data class ProcessHistoryActivityVo( +data class ProcessHisTaskVo( @Schema(description = "流程实例id") var processInstanceId: String? = null, - - @Schema(description = "活动id") - var activityId: String? = null, - - @Schema(description = "活动名称") - var activityName: String? = null, - + @Schema(description = "流程定义键") + var processDefinitionKey: String? = null, + @Schema(description = "流程名称") + var flowName: String? = null, @Schema(description = "任务id") var taskId: String? = null, - - @Schema(description = "任务定义键") - var taskDefinitionKey: String? = null, - - @Schema(description = "执行实例id") - var executionId: String? = null, - + @Schema(description = "节点编码") + var nodeCode: String? = null, + @Schema(description = "节点名称") + var nodeName: String? = null, @Schema(description = "业务键") var businessKey: String? = null, - - @Schema(description = "处理人") - var user: UserVo? = null, - - @Schema(description = "审批意见") - var comment: String? = null, - - @Schema(description = "审批是否通过") - var pass: Boolean? = null, - @Schema(description = "流程自定义参数") var params: MutableMap = mutableMapOf(), - - @Schema(description = "开始时间") - var startTime: Long = 0, - - @Schema(description = "结束时间") - var endTime: Long? = null + @Schema(description = "任务创建时间") + var createTime: Long = 0, + @Schema(description = "审批完成时间") + var updateTime: Long? = null, + @Schema(description = "审批人") + var user: UserVo? = null, + @Schema(description = "审批意见") + var message: String? = null, + @Schema(description = "流转类型") + var skipType: String? = null ) diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessInstanceVo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessInstanceVo.kt index 6b2dca3b..974e3060 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessInstanceVo.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessInstanceVo.kt @@ -2,48 +2,38 @@ package io.gitee.zhangbinhub.admin.resource.server.vo import io.swagger.v3.oas.annotations.media.Schema -/** - * @author zhang by 14/06/2019 - * @since JDK 11 - */ @Schema(description = "流程实例") data class ProcessInstanceVo( @Schema(description = "流程实例id") var processInstanceId: String? = null, - @Schema(description = "流程定义键") var processDefinitionKey: String? = null, - @Schema(description = "业务键") var businessKey: String? = null, - @Schema(description = "流程名称") var flowName: String? = null, - @Schema(description = "标题") var title: String? = null, - @Schema(description = "流程描述") var description: String? = null, - @Schema(description = "发起人") var startUser: UserVo? = null, - @Schema(description = "当前处理人") var activityUser: MutableList = mutableListOf(), - @Schema(description = "自定义参数") var params: MutableMap = mutableMapOf(), - - @Schema(description = "流程是否已结束") - var finished: Boolean = false, - + @Schema(description = "流程节点编码") + var nodeCode: String? = null, + @Schema(description = "流程节点名称") + var nodeName: String? = null, @Schema(description = "开始时间") var startTime: Long = 0, - - @Schema(description = "结束时间") - var endTime: Long? = null, - - @Schema(description = "流程删除原因") - var deleteReason: String? = null + @Schema(description = "更新时间") + var updateTime: Long = 0, + @Schema(description = "激活状态(0挂起 1激活)") + var activityStatus: Int? = null, + @Schema(description = "流程状态(0待提交 1审批中 2 审批通过 3自动通过 4终止 5作废 6撤销 7取回 8已完成 9已退回 10失效)") + var status: String? = null, + @Schema(description = "流程是否结束") + var finished: Boolean = false ) diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessTaskVo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessTaskVo.kt index 29309857..d0b16445 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessTaskVo.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/ProcessTaskVo.kt @@ -1,79 +1,33 @@ package io.gitee.zhangbinhub.admin.resource.server.vo import io.swagger.v3.oas.annotations.media.Schema -import jakarta.validation.constraints.NotBlank -/** - * @author zhang by 14/06/2019 - * @since JDK 11 - */ @Schema(description = "流程任务") data class ProcessTaskVo( @Schema(description = "流程实例id") var processInstanceId: String? = null, - - @Schema(description = "任务名称") - var name: String? = null, - + @Schema(description = "流程定义键") + var processDefinitionKey: String? = null, + @Schema(description = "流程名称") + var flowName: String? = null, @Schema(description = "任务id") var taskId: String? = null, - - @Schema(description = "任务定义键") - var taskDefinitionKey: String? = null, - - @Schema(description = "父任务id") - var parentTaskId: String? = null, - - @Schema(description = "执行实例id") - var executionId: String? = null, - + @Schema(description = "节点编码") + var nodeCode: String? = null, + @Schema(description = "节点名称") + var nodeName: String? = null, @Schema(description = "业务键") var businessKey: String? = null, - - @Schema(description = "是否未被认领") - var unClaimed: Boolean = true, - - @Schema(description = "处理人") - var user: UserVo? = null, - @Schema(description = "流程自定义参数") var params: MutableMap = mutableMapOf(), - - @Schema(description = "本地自定义参数") - var localParams: MutableMap = mutableMapOf(), - - @Schema(description = "任务表单字段") - var formFields: MutableMap = mutableMapOf(), - - @Schema(description = "任务自定义属性") - var properties: MutableMap = mutableMapOf(), - @Schema(description = "任务创建时间") var createTime: Long = 0, - - @Schema(description = "流程定义键") - var processDefinitionKey: String? = null, - - @Schema(description = "流程名称") - @get:NotBlank(message = "流程名称不能为空") - var flowName: String? = null, - @Schema(description = "标题") - @get:NotBlank(message = "标题不能为空") var title: String? = null, - @Schema(description = "流程描述") var description: String? = null, - @Schema(description = "流程发起人") var startUser: UserVo? = null, - - @Schema(description = "任务拥有者") - var taskOwnerUser: UserVo? = null, - - @Schema(description = "任务是否已委派") - var delegated: Boolean = false, - @Schema(description = "待办人列表") var pendingUserList: List = mutableListOf() ) diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/RoleVo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/RoleVo.kt index c5482265..edae651d 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/RoleVo.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/RoleVo.kt @@ -28,5 +28,14 @@ data class RoleVo( var sort: Int = 0, @Schema(description = "类型") - var type: Int? = null + var type: Int? = null, + + @Schema(description = "关联用户ID") + var userIds: MutableList = mutableListOf(), + + @Schema(description = "关联菜单ID") + var menuIds: MutableList = mutableListOf(), + + @Schema(description = "关联模块功能ID") + var moduleFuncIds: MutableList = mutableListOf() ) diff --git a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/UserVo.kt b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/UserVo.kt index 3abdacb4..74ce1872 100644 --- a/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/UserVo.kt +++ b/common/acp-admin-cloud-dependencies-resource-server/src/main/kotlin/io/gitee/zhangbinhub/admin/resource/server/vo/UserVo.kt @@ -30,6 +30,9 @@ data class UserVo( @Schema(description = "序号") var sort: Int = 0, + @Schema(description = "备注") + var remark: String? = null, + @Schema(description = "所属机构") var organizationSet: MutableSet = mutableSetOf(), diff --git a/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/base/BaseController.kt b/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/base/BaseController.kt index 10663967..25c23de7 100644 --- a/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/base/BaseController.kt +++ b/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/base/BaseController.kt @@ -3,10 +3,6 @@ package io.gitee.zhangbinhub.admin.common.base import io.gitee.zhangbinhub.acp.core.common.CalendarTools import org.joda.time.DateTime -/** - * @author zhang by 15/01/2019 - * @since JDK 11 - */ abstract class BaseController { /** diff --git a/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/base/BaseQueryPo.kt b/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/base/BaseQueryPo.kt index 6d22ed34..6d7cdf63 100644 --- a/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/base/BaseQueryPo.kt +++ b/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/base/BaseQueryPo.kt @@ -5,10 +5,6 @@ import io.swagger.v3.oas.annotations.media.Schema import jakarta.validation.Valid import jakarta.validation.constraints.NotNull -/** - * @author zhang by 26/11/2019 - * @since JDK 11 - */ abstract class BaseQueryPo { @Schema(description = "分页查询参数", requiredMode = Schema.RequiredMode.REQUIRED) @get:NotNull(message = "分页查询参数不能为空") diff --git a/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/po/QueryParam.kt b/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/po/QueryParam.kt index 7b966d7e..0e62e321 100644 --- a/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/po/QueryParam.kt +++ b/common/acp-admin-cloud-dependencies/src/main/kotlin/io/gitee/zhangbinhub/admin/common/po/QueryParam.kt @@ -6,10 +6,6 @@ import io.swagger.v3.oas.annotations.media.Schema import jakarta.validation.constraints.Min import jakarta.validation.constraints.NotNull -/** - * @author zhang by 11/01/2019 - * @since JDK 11 - */ @Schema(description = "分页查询参数") class QueryParam { @Schema(description = "当前页号", requiredMode = Schema.RequiredMode.REQUIRED) diff --git a/doc/nacos_config_export_dev.zip b/doc/nacos_config_export_dev.zip index 1b53820553b0c2332086d3c655f001b7c0358e92..0579f609990aedbbb80fd6d7144dc7abb339a032 100644 GIT binary patch delta 936 zcmcbmv`m>dz?+#xgn@&DgFz!{{YG9bCT1YL*^0@S5zHuH&SC{K?s6nTL>#%4z>LXh z+rOPgCD%W_CR=~=?$m_R(w}9_FAg+o zq#ly?+A3RY8MByEV*%UMwgpB-)10%D-sj1#nJBv?h+~PG$*Ck;wqv*Z14;!JZF{iT zfNkBzb%B-zlb7yLW^MC5yWpa)!x!O%($yPp?=3$oGVSxU&u3Eq+cjO#T`kh(wU_I` z7M3Lv0;)?j7cyqNtv}<&Xt+XKBj}9o7mae|^^1aM{z^@opZC+1`CpaiDqhE>ae`Yi zI9R_}hy`6eB)6kPOJV8mMW0nC$=c7`KmW<(yQ?4Xee>w@o8u|}O7*LMRepP$Q)YQC zt}do#rrt97XYKx<%GcM|)lc=mA2(Otbgk!-Bse3m5@eIyo zlV|_b5AbH^2#7mVyNi*5p`VF?0VO3&cH|P>T)@lASPx7NQ4C0c7s%GjO)W`GNi0d! ztIW+=d%>FTkO2?Fg}K2MuSNJKNN*@$*EU-!a6ItQwpVXC6;#@|LRTz)`{bu`jz`7| zem;Ze#$440Cd77FO>&;3D9bR<-|vZH)_bk#o!!dw`nbJvuI_s=!*+`gch1S)iqJ%} ziBl)@b|y3bZaVVrtibgL3twOR8GUt2uY2&%9+?oA%io{u-<=cRWZ@qB&Cd6C_8xPq z?49w8&S}4kyB;9(_SgLXK##F=e3-H2$pWCuCxAW5$Rxr5PxO;j_?1=CT1YL*^0@S5zHuH&SC{K?s6nTL>#%4z>LXh z+&+E0pSEiZw>`lJ9|9nT{>7QliUVZI9`{<>8y(h;5-x8+He90GIPO?2c zSL65M`ioCXs=ohAHuV0!ZqNStwKJMF$fT_A*e|s`e@lI3t%$6J0OMU@PUXudLV0-q zn>0$CVQW=%5?u8_$xkYvs@7q<$5%1FEqruw>7%f(KQ0S|6|YZ-DtE|b&l0k| z_VrcEk`-T-&aUzO&D;1#$*SFCQ$L%KxMRO+@v)YLDF=U>tkH>du%EUh*mDB++^Cus z?#trM&z)?0HkbASwZJL@5 zbU*;m%>mwwOd<^M#5y^L-wBj7CvW6;2Gig9y}-1KfGe1m6_lR5TtJf# - exchange.mutate().request(exchange.request.mutate().headers { httpHeaders: HttpHeaders -> - httpHeaders.add(GateWayConstant.GATEWAY_HEADER_REQUEST_TIME, System.currentTimeMillis().toString()) - }.build()).build().let { serverWebExchange -> - chain!!.filter(serverWebExchange.also { - routeLogBridge.sendMessage(routeLogService.createRouteLogMessage(it)) - }) + fun customerRequestFilter(): GlobalFilter = object : GlobalFilter, Ordered { + override fun filter( + exchange: ServerWebExchange, + chain: GatewayFilterChain? + ): Mono? { + exchange.mutate().request(exchange.request.mutate().headers { httpHeaders: HttpHeaders -> + httpHeaders.add(GateWayConstant.GATEWAY_HEADER_REQUEST_TIME, System.currentTimeMillis().toString()) + }.build()).build().let { serverWebExchange -> + return chain!!.filter(serverWebExchange) + } + } + + override fun getOrder(): Int { + return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1 } } + @Bean + fun logRequestFilter(routeLogBridge: RouteLogBridge): GlobalFilter = GlobalFilter { exchange, chain -> + chain!!.filter(exchange.also { + routeLogBridge.sendMessage(routeLogService.createRouteLogMessage(it)) + }) + } + @Bean fun logResponseFilter(routeLogBridge: RouteLogBridge): GlobalFilter = object : GlobalFilter, Ordered { override fun filter(exchange: ServerWebExchange?, chain: GatewayFilterChain?): Mono { diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/base/OauthBaseService.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/base/OauthBaseService.kt index f87f6fcc..70c159ed 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/base/OauthBaseService.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/base/OauthBaseService.kt @@ -35,6 +35,15 @@ abstract class OauthBaseService(protected val userRepository: UserRepository) : }.toMutableSet() } + fun getUserInfoById(userId: String, initLazy: Boolean = false): User? = + userRepository.findById(userId).orElse(null)?.apply { + if (initLazy) { + Hibernate.initialize(this.organizationSet) + Hibernate.initialize(this.organizationMngSet) + Hibernate.initialize(this.roleSet) + } + } + fun getUserInfoByLoginNo(loginNo: String, initLazy: Boolean = false): User? = userRepository.findByLoginNo(loginNo).orElse(null)?.apply { if (initLazy) { diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/api/OrgController.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/api/OrgController.kt index 098f6da6..fe443213 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/api/OrgController.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/api/OrgController.kt @@ -7,12 +7,13 @@ import io.gitee.zhangbinhub.acp.core.common.CommonTools import io.gitee.zhangbinhub.admin.common.api.OauthApi import io.gitee.zhangbinhub.admin.common.vo.InfoVo import io.gitee.zhangbinhub.admin.oauth.constant.OrgConfigExpression -import io.gitee.zhangbinhub.admin.oauth.service.OrganizationService import io.gitee.zhangbinhub.admin.oauth.entity.Organization import io.gitee.zhangbinhub.admin.oauth.po.OrganizationPo -import io.gitee.zhangbinhub.admin.oauth.vo.OrganizationVo +import io.gitee.zhangbinhub.admin.oauth.service.OrganizationService import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController -import io.swagger.v3.oas.annotations.* +import io.gitee.zhangbinhub.admin.resource.server.vo.OrganizationVo +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter import io.swagger.v3.oas.annotations.responses.ApiResponse import io.swagger.v3.oas.annotations.responses.ApiResponses import io.swagger.v3.oas.annotations.tags.Tag diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/api/RoleController.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/api/RoleController.kt index 429d3061..c53846ae 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/api/RoleController.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/api/RoleController.kt @@ -12,8 +12,8 @@ import io.gitee.zhangbinhub.admin.oauth.constant.RoleConfigExpression import io.gitee.zhangbinhub.admin.oauth.service.RoleService import io.gitee.zhangbinhub.admin.oauth.entity.Role import io.gitee.zhangbinhub.admin.oauth.po.RolePo -import io.gitee.zhangbinhub.admin.oauth.vo.RoleVo import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController +import io.gitee.zhangbinhub.admin.resource.server.vo.RoleVo import io.swagger.v3.oas.annotations.* import io.swagger.v3.oas.annotations.responses.ApiResponse import io.swagger.v3.oas.annotations.responses.ApiResponses diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/inner/InnerOrgController.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/inner/InnerOrgController.kt index 1e94eedd..9eb7e9d9 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/inner/InnerOrgController.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/inner/InnerOrgController.kt @@ -7,7 +7,7 @@ import io.gitee.zhangbinhub.admin.common.api.OauthApi import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController import io.gitee.zhangbinhub.admin.oauth.service.OrganizationService import io.gitee.zhangbinhub.admin.oauth.entity.Organization -import io.gitee.zhangbinhub.admin.oauth.vo.OrganizationVo +import io.gitee.zhangbinhub.admin.resource.server.vo.OrganizationVo import io.swagger.v3.oas.annotations.* import io.swagger.v3.oas.annotations.tags.Tag import org.springframework.beans.BeanUtils diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerOrgController.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerOrgController.kt index 67148dee..5a5f4e62 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerOrgController.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerOrgController.kt @@ -1,27 +1,31 @@ package io.gitee.zhangbinhub.admin.oauth.controller.openinner +import io.gitee.zhangbinhub.acp.boot.exceptions.WebException import io.gitee.zhangbinhub.acp.boot.log.LogAdapter import io.gitee.zhangbinhub.admin.common.api.CommonPath import io.gitee.zhangbinhub.admin.common.api.OauthApi -import io.gitee.zhangbinhub.admin.oauth.service.OrganizationService +import io.gitee.zhangbinhub.admin.oauth.constant.OrgConfigExpression import io.gitee.zhangbinhub.admin.oauth.entity.Organization +import io.gitee.zhangbinhub.admin.oauth.service.OrganizationService import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController import io.gitee.zhangbinhub.admin.resource.server.vo.OrganizationVo import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter +import io.swagger.v3.oas.annotations.responses.ApiResponse +import io.swagger.v3.oas.annotations.responses.ApiResponses import io.swagger.v3.oas.annotations.tags.Tag +import jakarta.validation.constraints.NotBlank import org.springframework.beans.BeanUtils import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.MediaType import org.springframework.http.ResponseEntity +import org.springframework.security.access.prepost.PreAuthorize import org.springframework.validation.annotation.Validated import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RestController -/** - * @author zhang by 16/01/2019 - * @since JDK 11 - */ @Validated @RestController @RequestMapping(CommonPath.openInnerBasePath) @@ -42,4 +46,15 @@ constructor( @GetMapping(value = [OauthApi.orgConfig], produces = [MediaType.APPLICATION_JSON_VALUE]) fun orgList(): ResponseEntity> = ResponseEntity.ok(listToVo(organizationService.getAllOrgList())) + + @Operation(summary = "获取机构详细信息") + @GetMapping(value = [OauthApi.orgConfig + "/{orgId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) + @Throws(WebException::class) + fun orgInfo( + @Parameter(description = "机构id", required = true) + @NotBlank(message = "机构id不能为空") + @PathVariable(name = "orgId") + orgId: String + ): ResponseEntity = + ResponseEntity.ok(organizationService.getOrgInfo(orgId)) } \ No newline at end of file diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerRoleController.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerRoleController.kt new file mode 100644 index 00000000..4828f043 --- /dev/null +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerRoleController.kt @@ -0,0 +1,40 @@ +package io.gitee.zhangbinhub.admin.oauth.controller.openinner + +import io.gitee.zhangbinhub.acp.boot.exceptions.WebException +import io.gitee.zhangbinhub.acp.boot.log.LogAdapter +import io.gitee.zhangbinhub.admin.common.api.CommonPath +import io.gitee.zhangbinhub.admin.common.api.OauthApi +import io.gitee.zhangbinhub.admin.oauth.service.RoleService +import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController +import io.gitee.zhangbinhub.admin.resource.server.vo.RoleVo +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.tags.Tag +import org.springframework.beans.factory.annotation.Autowired +import org.springframework.http.MediaType +import org.springframework.http.ResponseEntity +import org.springframework.validation.annotation.Validated +import org.springframework.web.bind.annotation.GetMapping +import org.springframework.web.bind.annotation.PathVariable +import org.springframework.web.bind.annotation.RequestMapping +import org.springframework.web.bind.annotation.RestController + +@Validated +@RestController +@RequestMapping(CommonPath.openInnerBasePath) +@Tag(name = "角色信息(内部开放接口)") +class OpenInnerRoleController @Autowired +constructor( + logAdapter: LogAdapter, + private val roleService: RoleService +) : BaseResourceServerController(logAdapter) { + @Operation(summary = "获取角色详细信息") + @GetMapping(value = [OauthApi.roleConfig + "/{roleId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) + @Throws(WebException::class) + fun roleInfo(@PathVariable(name = "roleId") roleId: String): ResponseEntity = + ResponseEntity.ok(roleService.getRoleInfo(roleId)) + + @Operation(summary = "获取角色列表", description = "查询所有角色列表") + @GetMapping(value = [OauthApi.roleConfig], produces = [MediaType.APPLICATION_JSON_VALUE]) + @Throws(WebException::class) + fun roleList(): ResponseEntity> = ResponseEntity.ok(roleService.getRoleVoList()) +} \ No newline at end of file diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerUserController.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerUserController.kt index 74637daf..d72c74ca 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerUserController.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/controller/openinner/OpenInnerUserController.kt @@ -5,6 +5,7 @@ import io.gitee.zhangbinhub.acp.boot.log.LogAdapter import io.gitee.zhangbinhub.admin.common.api.CommonPath import io.gitee.zhangbinhub.admin.common.api.OauthApi import io.gitee.zhangbinhub.admin.common.vo.InfoVo +import io.gitee.zhangbinhub.admin.oauth.constant.UserConfigExpression import io.gitee.zhangbinhub.admin.oauth.service.UserService import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController import io.gitee.zhangbinhub.admin.resource.server.vo.UserVo @@ -18,13 +19,10 @@ import jakarta.validation.constraints.NotNull import org.springframework.beans.factory.annotation.Autowired import org.springframework.http.MediaType import org.springframework.http.ResponseEntity +import org.springframework.security.access.prepost.PreAuthorize import org.springframework.validation.annotation.Validated import org.springframework.web.bind.annotation.* -/** - * @author zhang by 01/02/2019 - * @since JDK 11 - */ @Validated @RestController @RequestMapping(CommonPath.openInnerBasePath) @@ -83,6 +81,15 @@ constructor( ): ResponseEntity = ResponseEntity.ok(userService.getUserVoByLoginNo(loginNo)) + @Operation(summary = "查询用户列表") + @GetMapping( + value = [OauthApi.userList], + params = ["!loginNo", "!orgLevel", "!orgCode", "!roleCode"], + produces = [MediaType.APPLICATION_JSON_VALUE] + ) + @Throws(WebException::class) + fun getUserList(): ResponseEntity> = ResponseEntity.ok(userService.getUserVoList()) + @Operation(summary = "通过机构编码和角色编码,查询用户列表") @GetMapping( value = [OauthApi.userList], diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Menu.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Menu.kt index 7ae32f6a..46425a2d 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Menu.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Menu.kt @@ -39,7 +39,8 @@ data class Menu( @JsonIgnore @ManyToMany(fetch = FetchType.LAZY, cascade = [CascadeType.REFRESH]) @JoinTable( name = "t_role_menu_set", joinColumns = [JoinColumn(name = "menuId", referencedColumnName = "id")], - inverseJoinColumns = [JoinColumn(name = "roleId", referencedColumnName = "id")] + inverseJoinColumns = [JoinColumn(name = "roleId", referencedColumnName = "id")], + foreignKey = ForeignKey(ConstraintMode.NO_CONSTRAINT) ) var roleSet: MutableSet = mutableSetOf() ) : OauthBaseTreeEntity() { override fun equals(other: Any?): Boolean { diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/ModuleFunc.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/ModuleFunc.kt index 6331d29b..297785d8 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/ModuleFunc.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/ModuleFunc.kt @@ -42,7 +42,8 @@ data class ModuleFunc( @JoinTable( name = "t_role_module_func_set", joinColumns = [JoinColumn(name = "moduleId", referencedColumnName = "id")], - inverseJoinColumns = [JoinColumn(name = "roleId", referencedColumnName = "id")] + inverseJoinColumns = [JoinColumn(name = "roleId", referencedColumnName = "id")], + foreignKey = ForeignKey(ConstraintMode.NO_CONSTRAINT) ) var roleSet: MutableSet = mutableSetOf() ) : OauthBaseTreeEntity() { diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Organization.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Organization.kt index b84603d1..c2faffc4 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Organization.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Organization.kt @@ -47,7 +47,8 @@ data class Organization( @JoinTable( name = "t_user_organization_set", joinColumns = [JoinColumn(name = "organizationId", referencedColumnName = "id")], - inverseJoinColumns = [JoinColumn(name = "userId", referencedColumnName = "id")] + inverseJoinColumns = [JoinColumn(name = "userId", referencedColumnName = "id")], + foreignKey = ForeignKey(ConstraintMode.NO_CONSTRAINT) ) var userSet: MutableSet = mutableSetOf(), @@ -56,7 +57,8 @@ data class Organization( @JoinTable( name = "t_user_organization_mng_set", joinColumns = [JoinColumn(name = "organizationId", referencedColumnName = "id")], - inverseJoinColumns = [JoinColumn(name = "userId", referencedColumnName = "id")] + inverseJoinColumns = [JoinColumn(name = "userId", referencedColumnName = "id")], + foreignKey = ForeignKey(ConstraintMode.NO_CONSTRAINT) ) var adminUserSet: MutableSet = mutableSetOf() ) : OauthBaseTreeEntity() { diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Role.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Role.kt index aab3a0f4..19084831 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Role.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/Role.kt @@ -48,7 +48,8 @@ data class Role( @JoinTable( name = "t_user_role_set", joinColumns = [JoinColumn(name = "roleId", referencedColumnName = "id")], - inverseJoinColumns = [JoinColumn(name = "userId", referencedColumnName = "id")] + inverseJoinColumns = [JoinColumn(name = "userId", referencedColumnName = "id")], + foreignKey = ForeignKey(ConstraintMode.NO_CONSTRAINT) ) var userSet: MutableSet = mutableSetOf(), @@ -57,7 +58,8 @@ data class Role( @JoinTable( name = "t_role_menu_set", joinColumns = [JoinColumn(name = "roleId", referencedColumnName = "id")], - inverseJoinColumns = [JoinColumn(name = "menuId", referencedColumnName = "id")] + inverseJoinColumns = [JoinColumn(name = "menuId", referencedColumnName = "id")], + foreignKey = ForeignKey(ConstraintMode.NO_CONSTRAINT) ) var menuSet: MutableSet = mutableSetOf(), @@ -66,7 +68,8 @@ data class Role( @JoinTable( name = "t_role_module_func_set", joinColumns = [JoinColumn(name = "roleId", referencedColumnName = "id")], - inverseJoinColumns = [JoinColumn(name = "moduleId", referencedColumnName = "id")] + inverseJoinColumns = [JoinColumn(name = "moduleId", referencedColumnName = "id")], + foreignKey = ForeignKey(ConstraintMode.NO_CONSTRAINT) ) var moduleFuncSet: MutableSet = mutableSetOf() ) { diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/User.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/User.kt index d30ad2d2..0eca46bd 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/User.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/entity/User.kt @@ -53,7 +53,8 @@ data class User( @JoinTable( name = "t_user_organization_set", joinColumns = [JoinColumn(name = "userId", referencedColumnName = "id")], - inverseJoinColumns = [JoinColumn(name = "organizationId", referencedColumnName = "id")] + inverseJoinColumns = [JoinColumn(name = "organizationId", referencedColumnName = "id")], + foreignKey = ForeignKey(ConstraintMode.NO_CONSTRAINT) ) @Schema(description = "所属机构") var organizationSet: MutableSet = mutableSetOf(), @@ -62,7 +63,8 @@ data class User( @JoinTable( name = "t_user_organization_mng_set", joinColumns = [JoinColumn(name = "userId", referencedColumnName = "id")], - inverseJoinColumns = [JoinColumn(name = "organizationId", referencedColumnName = "id")] + inverseJoinColumns = [JoinColumn(name = "organizationId", referencedColumnName = "id")], + foreignKey = ForeignKey(ConstraintMode.NO_CONSTRAINT) ) @Schema(description = "可管理的机构") var organizationMngSet: MutableSet = mutableSetOf(), @@ -71,7 +73,8 @@ data class User( @JoinTable( name = "t_user_role_set", joinColumns = [JoinColumn(name = "userId", referencedColumnName = "id")], - inverseJoinColumns = [JoinColumn(name = "roleId", referencedColumnName = "id")] + inverseJoinColumns = [JoinColumn(name = "roleId", referencedColumnName = "id")], + foreignKey = ForeignKey(ConstraintMode.NO_CONSTRAINT) ) @Schema(description = "所属角色") var roleSet: MutableSet = mutableSetOf(), diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/OrganizationService.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/OrganizationService.kt index 56bb3912..4d725132 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/OrganizationService.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/OrganizationService.kt @@ -7,7 +7,7 @@ import io.gitee.zhangbinhub.admin.oauth.entity.User import io.gitee.zhangbinhub.admin.oauth.po.OrganizationPo import io.gitee.zhangbinhub.admin.oauth.repo.OrganizationRepository import io.gitee.zhangbinhub.admin.oauth.repo.UserRepository -import io.gitee.zhangbinhub.admin.oauth.vo.OrganizationVo +import io.gitee.zhangbinhub.admin.resource.server.vo.OrganizationVo import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional @@ -49,15 +49,16 @@ constructor(userRepository: UserRepository, private val organizationRepository: private fun doSave(userInfo: User, organization: Organization, organizationPo: OrganizationPo): Organization = userRepository.findAllById(organizationPo.userIds).toMutableSet().let { userSetPo -> if (validateModifyUserSet(userInfo, organization.userSet, userSetPo)) { - organizationRepository.save(organization.copy( - name = organizationPo.name!!, - code = organizationPo.code!!, - area = organizationPo.area!!, - sort = organizationPo.sort, - userSet = userSetPo - ).apply { - parentId = organizationPo.parentId!! - }) + organizationRepository.save( + organization.copy( + name = organizationPo.name!!, + code = organizationPo.code!!, + area = organizationPo.area!!, + sort = organizationPo.sort, + userSet = userSetPo + ).apply { + parentId = organizationPo.parentId!! + }) } else { throw WebException("不合法的操作,不允许修改更高级别的用户列表!") } diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/RoleService.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/RoleService.kt index 7517d16e..45fc40da 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/RoleService.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/RoleService.kt @@ -10,15 +10,11 @@ import io.gitee.zhangbinhub.admin.oauth.repo.MenuRepository import io.gitee.zhangbinhub.admin.oauth.repo.ModuleFuncRepository import io.gitee.zhangbinhub.admin.oauth.repo.RoleRepository import io.gitee.zhangbinhub.admin.oauth.repo.UserRepository -import io.gitee.zhangbinhub.admin.oauth.vo.RoleVo +import io.gitee.zhangbinhub.admin.resource.server.vo.RoleVo import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional -/** - * @author zhang by 16/01/2019 - * @since JDK 11 - */ @Service @Transactional(readOnly = true) class RoleService @Autowired @@ -32,6 +28,22 @@ constructor( @Throws(WebException::class) fun getRoleList(): MutableList = roleRepository.findAllByOrderBySortAsc() + @Throws(WebException::class) + fun getRoleVoList(): MutableList = getRoleList().map { item -> + RoleVo( + id = item.id, + appId = item.appId, + code = item.code, + levels = item.levels, + name = item.name, + sort = item.sort, + type = item.type, + userIds = item.userSet.map { it.id }.toMutableList(), + menuIds = item.menuSet.map { it.id }.toMutableList(), + moduleFuncIds = item.moduleFuncSet.map { it.id }.toMutableList() + ) + }.toMutableList() + @Throws(WebException::class) fun getRoleListByAppId(loginNo: String, appId: String): List { val user = getUserInfoByLoginNo(loginNo) ?: throw WebException("无法获取当前用户信息") diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/UserService.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/UserService.kt index 07411d79..b3181777 100644 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/UserService.kt +++ b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/service/UserService.kt @@ -267,6 +267,10 @@ constructor( formatUserVo(it.get()) } + @Throws(WebException::class) + fun getUserVoList(): MutableList = + userRepository.findAll().map { item -> formatUserVo(item) }.toMutableList() + /** * 根据ID查询用户信息 */ diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/vo/OrganizationVo.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/vo/OrganizationVo.kt deleted file mode 100644 index dfcdd907..00000000 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/vo/OrganizationVo.kt +++ /dev/null @@ -1,33 +0,0 @@ -package io.gitee.zhangbinhub.admin.oauth.vo - -import io.swagger.v3.oas.annotations.media.Schema - -/** - * @author zhang by 17/01/2019 - * @since JDK 11 - */ -@Schema(description = "机构详细信息") -data class OrganizationVo( - - @Schema(description = "机构ID") - var id: String? = null, - - @Schema(description = "机构名称") - var name: String? = null, - - @Schema(description = "机构区域") - var area: String? = null, - - @Schema(description = "机构编码") - var code: String? = null, - - @Schema(description = "上级机构ID") - var parentId: String? = null, - - @Schema(description = "序号") - var sort: Int = 0, - - @Schema(description = "关联用户ID") - var userIds: MutableList = mutableListOf() - -) diff --git a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/vo/RoleVo.kt b/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/vo/RoleVo.kt deleted file mode 100644 index 27df214e..00000000 --- a/modules/oauth-server/src/main/kotlin/io/gitee/zhangbinhub/admin/oauth/vo/RoleVo.kt +++ /dev/null @@ -1,42 +0,0 @@ -package io.gitee.zhangbinhub.admin.oauth.vo - -import io.swagger.v3.oas.annotations.media.Schema - -/** - * @author zhangbin by 2018-1-17 16:53 - * @since JDK 11 - */ -@Schema(description = "角色详细信息") -data class RoleVo( - - @Schema(description = "角色ID") - var id: String? = null, - - @Schema(description = "应用ID") - var appId: String? = null, - - @Schema(description = "角色名称") - var name: String? = null, - - @Schema(description = "角色编码") - var code: String? = null, - - @Schema(description = "角色级别") - var levels: Int = 1, - - @Schema(description = "序号") - var sort: Int = 0, - - @Schema(description = "类型") - var type: Int? = null, - - @Schema(description = "关联用户ID") - var userIds: MutableList = mutableListOf(), - - @Schema(description = "关联菜单ID") - var menuIds: MutableList = mutableListOf(), - - @Schema(description = "关联模块功能ID") - var moduleFuncIds: MutableList = mutableListOf() - -) diff --git a/modules/workflow-server/README.md b/modules/workflow-server/README.md index bd13c277..5bf9fe17 100644 --- a/modules/workflow-server/README.md +++ b/modules/workflow-server/README.md @@ -1,82 +1,42 @@ ### workflow-server -工作流服务,集成[Camunda 7](https://docs.camunda.org/manual/7.21/) +工作流服务,集成[warm-flow(国产)](https://warm-flow.dromara.org/) ##### 一、接口说明 - 1、工作流服务目前已封装如下接口,接口详情请在浏览器中访问 /doc.html 页面 - - 启动流程 - - 获取用户待办任务列表 - - 分配任务 - - 领取任务 - - 转办任务 - - 委托办理任务 - - 流程处理 - - 流程强制结束 - - 获取流程实例 - - 获取我处理过的流程实例 - - 流程处理历史查询 - - 获取流程任务信息 - - 获取流程定义 - - 获取流程定义高亮元素 - 2、需动态配置路由策略。 ##### 二、固定必要的流程变量,自定义变量不能与之重复 - startUserId - 流程发起人 -- businessKey - 业务键 -- flowName - 流程名称 - title - 流程标题 - description - 流程描述 -- pass - 处理结果:true-通过,false-不通过 -- comment - 处理意见 -- candidateUser:String ,节点任务候选人ID(一人或多人),多个候选人时使用“,”分隔;任务处理完成后需修改(变更为下一节点人或置空) -- assigneeUser:String ,节点任务处理人ID(只能一人);任务处理完成后需修改(变更为下一节点人或置空) -##### 三、内置任务动态表单字段 - -- isTermination:Boolean ,当前任务节点是否可以进行终止操作(流程强制结束) -- isTransfer:Boolean ,当前任务是否可以转办(任务处理人变更,处理完毕后进入下一节点) -- isDelegate:Boolean ,当前任务是否可以委派他人办理(任务处理人变更,处理完毕后返回至当前处理人继续办理) -- selectUser:Boolean ,是否手动选择分配处理人(或候选人) -- orgLevel:Int ,待发送用户部门级别,负数|零|正数;0-当前用户所在部门,-1上一级部门,-2上两级部门...依次类推,1下一级部门,2下两级部门...依次类推,多个code时使用“,”分隔 -- roleCode:String ,待发送用户所属角色code,多个code时使用“,”分隔 -- taskCode:String ,任务编码,用于自定义判断任务处理方式 -- isReject:Boolean ,当前任务是否允许驳回 -- rejectToTask:String ,驳回至目标任务的定义ID,多个值时使用“,”分隔 - -##### 四、自定义待办通知开发 +##### 三、自定义待办通知开发 ###### 待办生成通知 -新建通知处理类,包名io.gitee.zhangbinhub.admin.workflow.notify,继承```io.gitee.zhangbinhub.admin.workflow.base.PendingCreatedNotify``` +新建通知处理类,包名io.gitee.zhangbinhub.admin.workflow.notify,继承 +```io.gitee.zhangbinhub.admin.base.PendingCreatedNotify``` ,实现方法 ``` @Throws(WebException::class) - fun doTaskNotify( - businessKey: String, - task: Task, - processDefinition: ProcessDefinition, - userIdList: List - ) + fun doTaskNotify(definition: Definition, instance: Instance, task: Task, userIdList: List) ``` 参考[LogPendingCreatedNotify](src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/notify/LogPendingCreatedNotify.kt) ###### 待办完成通知 -新建通知处理类,包名io.gitee.zhangbinhub.admin.workflow.notify,继承```io.gitee.zhangbinhub.admin.workflow.base.PendingFinishedNotify``` +新建通知处理类,包名io.gitee.zhangbinhub.admin.workflow.notify,继承 +```io.gitee.zhangbinhub.admin.base.PendingFinishedNotify``` ,实现方法 ``` @Throws(WebException::class) - fun doTaskNotify( - businessKey: String, - task: Task, - processDefinition: ProcessDefinition, - userIdList: List - ) + fun doTaskNotify(definition: Definition, instance: Instance, task: Task, userIdList: List) ``` 参考[LogPendingFinishedNotify](src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/notify/LogPendingFinishedNotify.kt) \ No newline at end of file diff --git a/modules/workflow-server/build.gradle b/modules/workflow-server/build.gradle index 95b619ee..49c41a20 100644 --- a/modules/workflow-server/build.gradle +++ b/modules/workflow-server/build.gradle @@ -5,8 +5,7 @@ dependencies { implementation "org.springframework.boot:spring-boot-starter-data-jpa" implementation "com.mysql:mysql-connector-j:$versions.mysql" - implementation "org.camunda.bpm.springboot:camunda-bpm-spring-boot-starter:$versions.camunda" - implementation "org.slf4j:jcl-over-slf4j" + implementation "io.gitee.zhangbinhub.acp:acp-spring-boot-warm-flow-mybatis-flex" testImplementation "org.springframework.boot:spring-boot-starter-test" } \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/WorkFlowServerApplication.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/WorkFlowServerApplication.kt index 54a4ffa4..2898241d 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/WorkFlowServerApplication.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/WorkFlowServerApplication.kt @@ -3,10 +3,6 @@ package io.gitee.zhangbinhub.admin.workflow import io.gitee.zhangbinhub.acp.cloud.resource.server.annotation.AcpCloudResourceServerApplication import org.springframework.boot.runApplication -/** - * @author zhangbin by 09/04/2018 16:11 - * @since JDK 11 - */ @AcpCloudResourceServerApplication class WorkFlowServerApplication diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/base/BaseWorkFlowNotify.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/base/BaseWorkFlowNotify.kt index dbf84f63..0d9a355f 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/base/BaseWorkFlowNotify.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/base/BaseWorkFlowNotify.kt @@ -1,15 +1,11 @@ package io.gitee.zhangbinhub.admin.workflow.base import io.gitee.zhangbinhub.acp.boot.exceptions.WebException -import org.camunda.bpm.engine.repository.ProcessDefinition -import org.camunda.bpm.engine.task.Task +import org.dromara.warm.flow.core.entity.Definition +import org.dromara.warm.flow.core.entity.Instance +import org.dromara.warm.flow.core.entity.Task interface BaseWorkFlowNotify { @Throws(WebException::class) - fun doTaskNotify( - businessKey: String, - task: Task, - processDefinition: ProcessDefinition, - userIdList: List - ) + fun doTaskNotify(definition: Definition, instance: Instance, task: Task, userIdList: List) } \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/base/BaseWorkFlowService.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/base/BaseWorkFlowService.kt index 8ef3552f..86d7b477 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/base/BaseWorkFlowService.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/base/BaseWorkFlowService.kt @@ -1,5 +1,39 @@ package io.gitee.zhangbinhub.admin.workflow.base +import com.mybatisflex.core.paginate.Page +import com.mybatisflex.core.query.QueryChain +import com.mybatisflex.core.table.TableInfoFactory +import io.gitee.zhangbinhub.acp.core.common.CommonTools import io.gitee.zhangbinhub.admin.common.base.BaseService +import io.gitee.zhangbinhub.admin.common.po.QueryParam +import io.gitee.zhangbinhub.admin.common.vo.CustomerQueryPageVo -abstract class BaseWorkFlowService : BaseService() \ No newline at end of file +abstract class BaseWorkFlowService : BaseService() { + protected inline fun doPageQuery( + queryParam: QueryParam, + queryChain: QueryChain, + withRelations: Boolean = false + ): CustomerQueryPageVo { + if (!CommonTools.isNullStr(queryParam.orderName)) { + val tableInfo = TableInfoFactory.ofEntityClass(T::class.java) + queryParam.orderName!!.split(",").forEach { orderProperty -> + queryChain.orderBy( + tableInfo.getQueryColumnByProperty(orderProperty), + queryParam.orderCommand.equals("asc", true) + ) + } + } + return (if (withRelations) { + queryChain.withRelations().page(Page(queryParam.currPage, queryParam.pageSize)) + } else { + queryChain.page(Page(queryParam.currPage, queryParam.pageSize)) + }).let { pageResult -> + CustomerQueryPageVo( + content = pageResult.records, + totalElements = pageResult.totalRow, + currPage = queryParam.currPage!!, + pageSize = queryParam.pageSize!! + ) + } + } +} \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowGlobalListener.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowGlobalListener.kt new file mode 100644 index 00000000..c14ea4bd --- /dev/null +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowGlobalListener.kt @@ -0,0 +1,210 @@ +package io.gitee.zhangbinhub.admin.workflow.component + +import io.gitee.zhangbinhub.acp.boot.exceptions.WebException +import io.gitee.zhangbinhub.acp.boot.log.LogAdapter +import io.gitee.zhangbinhub.acp.core.common.CalendarTools +import io.gitee.zhangbinhub.acp.core.common.task.BaseAsyncTask +import io.gitee.zhangbinhub.acp.core.common.task.threadpool.ThreadPoolService +import io.gitee.zhangbinhub.admin.common.constant.WorkFlowConstant +import io.gitee.zhangbinhub.admin.resource.server.feign.CommonOauthServer +import io.gitee.zhangbinhub.admin.workflow.base.PendingCreatedNotify +import io.gitee.zhangbinhub.admin.workflow.base.PendingFinishedNotify +import io.gitee.zhangbinhub.admin.workflow.conf.WorkFlowCustomerConfiguration +import org.dromara.warm.flow.core.FlowEngine +import org.dromara.warm.flow.core.dto.DefJson +import org.dromara.warm.flow.core.entity.Instance +import org.dromara.warm.flow.core.entity.Task +import org.dromara.warm.flow.core.enums.NodeType +import org.dromara.warm.flow.core.listener.GlobalListener +import org.dromara.warm.flow.core.listener.ListenerVariable +import org.dromara.warm.flow.core.service.DefService +import org.dromara.warm.flow.core.service.InsService +import org.dromara.warm.flow.core.service.UserService +import org.joda.time.DateTime +import org.springframework.stereotype.Component + +/** + * 流程启动 + * start -》 assignment -》 finish -》 create( listenerVariable.getNextNodes().forEach ) + * + * 办理人变更 + * start -》 入库 -》 finish + * + * 办理 + * start -》 assignment -》 入库 -》 finish -》 create( listenerVariable.getNextNodes().forEach ) + */ +@Component +class WorkFlowGlobalListener( + private val logAdapter: LogAdapter, + private val workFlowCustomerConfiguration: WorkFlowCustomerConfiguration, + private val workFlowPermissionHandler: WorkFlowPermissionHandler, + private val pendingCreatedNotifyList: MutableList, + private val pendingFinishedNotifyList: MutableList, + private val commonOauthServer: CommonOauthServer, + private val defService: DefService, + private val insService: InsService, + private val userService: UserService +) : GlobalListener { + private fun begin(listenerVariable: ListenerVariable, newTask: Task) { + val disList = newTask.userList.flatMap { workFlowPermissionHandler.userIdList(listOf(it.processedBy)) } + FlowEngine.jsonConvert.strToBean(listenerVariable.instance.defJson, DefJson::class.java)?.let { defJson -> + for (nodeJson in defJson.nodeList) { + if (nodeJson.nodeCode == newTask.nodeCode) { + if (disList.isNotEmpty()) { + nodeJson.extMap[WorkFlowConstant.NODE_EXT_APPROVAL] = + disList.mapNotNull { commonOauthServer.findUserById(it).name } + .joinToString(separator = ",") + } + if (nodeJson.extMap[WorkFlowConstant.NODE_EXT_START_TIME] == null) { + nodeJson.extMap[WorkFlowConstant.NODE_EXT_START_TIME] = + DateTime(newTask.createTime.time).toString(CalendarTools.DATETIME_FORMAT) + } + } + } + listenerVariable.instance.setDefJson(FlowEngine.jsonConvert.objToStr(defJson)) + } + insService.updateById(listenerVariable.instance) + notifyPending(listenerVariable, newTask, listOf(), disList) + } + + private fun complete(listenerVariable: ListenerVariable) { + val oriList: List = listenerVariable.task.userList + ?.flatMap { workFlowPermissionHandler.userIdList(listOf(it.processedBy)) } ?: listOf() + var disList: List = listOf() + if (listenerVariable.flowParams == null) { + // 无跳转仅修改办理人时,通知新的办理人 + disList = userService.getByAssociateds(listOf(listenerVariable.task.id)).flatMap { + workFlowPermissionHandler.userIdList(listOf(it.processedBy)) + } + FlowEngine.jsonConvert.strToBean(listenerVariable.instance.defJson, DefJson::class.java)?.let { defJson -> + for (nodeJson in defJson.nodeList) { + if (nodeJson.nodeCode == listenerVariable.node.nodeCode) { + if (disList.isNotEmpty()) { + nodeJson.extMap[WorkFlowConstant.NODE_EXT_APPROVAL] = + disList.mapNotNull { commonOauthServer.findUserById(it).name } + .joinToString(separator = ",") + } else { + nodeJson.extMap.remove(WorkFlowConstant.NODE_EXT_APPROVAL) + } + } + } + listenerVariable.instance.setDefJson(FlowEngine.jsonConvert.objToStr(defJson)) + } + } else { + FlowEngine.jsonConvert.strToBean(listenerVariable.instance.defJson, DefJson::class.java)?.let { defJson -> + for (nodeJson in defJson.nodeList) { + if (nodeJson.nodeCode == listenerVariable.node.nodeCode) { + nodeJson.extMap[WorkFlowConstant.NODE_EXT_FINISH_TIME] = + DateTime(listenerVariable.instance.updateTime.time).toString(CalendarTools.DATETIME_FORMAT) + nodeJson.extMap[WorkFlowConstant.NODE_EXT_APPROVAL] = + commonOauthServer.findUserById(listenerVariable.flowParams.handler).name + } + } + listenerVariable.instance.setDefJson(FlowEngine.jsonConvert.objToStr(defJson)) + } + } + insService.updateById(listenerVariable.instance) + notifyPending(listenerVariable, listenerVariable.task, oriList, disList) + } + + override fun finish(listenerVariable: ListenerVariable) { + if (listenerVariable.node.nodeType == NodeType.START.key) { + listenerVariable.nextTasks?.forEach { task -> + if (task.nodeType == NodeType.BETWEEN.key) { + logAdapter.debug("收到工作流任务【${task.nodeName}】创建事件") + begin(listenerVariable, task) + } + } + } else if (listenerVariable.node.nodeType == NodeType.BETWEEN.key && listenerVariable.task != null) { + logAdapter.debug("收到工作流任务【${listenerVariable.task.nodeName}】完成事件") + complete(listenerVariable) + listenerVariable.nextTasks?.forEach { task -> + if (task.nodeType == NodeType.BETWEEN.key) { + logAdapter.debug("收到工作流任务【${task.nodeName}】创建事件") + begin(listenerVariable, task) + } + } + } + } + + private fun notifyPending( + listenerVariable: ListenerVariable, + task: Task, + orgList: List, + disList: List + ) { + orgList.filterNot { disList.contains(it) }.let { + if (it.isNotEmpty()) { + notifyPendingFinished(listenerVariable.instance, task, it) + } + } + disList.filterNot { orgList.contains(it) }.let { + if (it.isNotEmpty()) { + notifyPendingCreated(listenerVariable.instance, task, it) + } + } + } + + /** + * 生成待办通知 + * @param instance 流程实例 + * @param task 任务 + * @param userIdList 用户ID + */ + @Throws(WebException::class) + fun notifyPendingCreated(instance: Instance, task: Task, userIdList: List) { + if (workFlowCustomerConfiguration.notifyPendingCreated) { + logAdapter.debug("进行待办通知...") + logAdapter.debug("userIdList --> $userIdList") + defService.getById(instance.definitionId)?.also { definition -> + if (userIdList.isNotEmpty()) { + logAdapter.debug("【${definition.flowCode}】【${definition.flowName}】【instanceId:${instance.id}】【businessId:${instance.businessId}】【taskId:${task.id}】开始待办通知处理,通知处理器数量【${pendingCreatedNotifyList.size}】...") + logAdapter.debug("处理器:${pendingCreatedNotifyList}") + pendingCreatedNotifyList.forEach { handle -> + ThreadPoolService.getInstance(5, 5, Int.MAX_VALUE, "create-pending-pool") + .addTask(object : BaseAsyncTask("create-pending") { + override fun afterExecuteFun(result: Any) {} + override fun beforeExecuteFun(): Boolean = true + override fun executeFun(): Any { + handle.doTaskNotify(definition, instance, task, userIdList) + return true + } + }) + } + } + } + ?: throw WebException("获取流程定义失败!【instanceId:${instance.id}】【businessId:${instance.businessId}】【taskId:${task.id}】") + } + } + + /** + * 完成待办通知 + * @param instance 流程实例 + * @param task 任务 + * @param userIdList 用户ID + */ + @Throws(WebException::class) + fun notifyPendingFinished(instance: Instance, task: Task, userIdList: List) { + if (workFlowCustomerConfiguration.notifyPendingFinished) { + logAdapter.debug("删除待办通知...") + logAdapter.debug("userIdList --> $userIdList") + defService.getById(instance.definitionId)?.also { definition -> + if (userIdList.isNotEmpty()) { + logAdapter.debug("【${definition.flowCode}】【${definition.flowName}】【instanceId:${instance.id}】【businessId:${instance.businessId}】【taskId:${task.id}】开始删除待办通知处理,通知处理器数量【${pendingFinishedNotifyList.size}】...") + logAdapter.debug("处理器:${pendingFinishedNotifyList}") + pendingFinishedNotifyList.forEach { handle -> + ThreadPoolService.getInstance(5, 5, Int.MAX_VALUE, "delete-pending-pool") + .addTask(object : BaseAsyncTask("delete-pending") { + override fun afterExecuteFun(result: Any) {} + override fun beforeExecuteFun(): Boolean = true + override fun executeFun(): Any { + handle.doTaskNotify(definition, instance, task, userIdList) + return true + } + }) + } + } + } ?: throw WebException("获取流程实例失败:taskId【${task.id}】") + } + } +} \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowListener.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowListener.kt deleted file mode 100644 index b5d760ed..00000000 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowListener.kt +++ /dev/null @@ -1,135 +0,0 @@ -package io.gitee.zhangbinhub.admin.workflow.component - -import io.gitee.zhangbinhub.acp.boot.exceptions.WebException -import io.gitee.zhangbinhub.acp.boot.log.LogAdapter -import io.gitee.zhangbinhub.acp.core.common.CommonTools -import io.gitee.zhangbinhub.acp.core.common.task.BaseAsyncTask -import io.gitee.zhangbinhub.acp.core.common.task.threadpool.ThreadPoolService -import io.gitee.zhangbinhub.admin.resource.server.feign.CommonOauthServer -import io.gitee.zhangbinhub.admin.workflow.base.PendingCreatedNotify -import io.gitee.zhangbinhub.admin.workflow.base.PendingFinishedNotify -import io.gitee.zhangbinhub.admin.workflow.conf.WorkFlowCustomerConfiguration -import org.camunda.bpm.engine.RepositoryService -import org.camunda.bpm.engine.impl.persistence.entity.TaskEntity -import org.camunda.bpm.engine.task.IdentityLink -import org.camunda.bpm.engine.task.IdentityLinkType -import org.camunda.bpm.engine.task.Task -import org.springframework.context.event.EventListener -import org.springframework.stereotype.Component - -@Component -class WorkFlowListener( - private val logAdapter: LogAdapter, - private val commonOauthServer: CommonOauthServer, - private val workFlowCustomerConfiguration: WorkFlowCustomerConfiguration, - private val pendingCreatedNotifyList: List, - private val pendingFinishedNotifyList: List, - private val repositoryService: RepositoryService -) { - fun getIdentityLinkUserId(identityLinkList: List): List = - identityLinkList.filter { identityLink -> - identityLink.type == IdentityLinkType.ASSIGNEE && !CommonTools.isNullStr(identityLink.userId) - }.map { identityLink -> identityLink.userId }.ifEmpty { - identityLinkList.filter { identityLink -> - identityLink.type == IdentityLinkType.CANDIDATE - }.flatMap { identityLink -> - mutableListOf().apply { - if (!CommonTools.isNullStr(identityLink.userId)) { - this.add(identityLink.userId) - } - if (!CommonTools.isNullStr(identityLink.groupId)) { - this.addAll(commonOauthServer.findUserList(identityLink.groupId).map { userVo -> - if (!CommonTools.isNullStr(userVo.id)) { - userVo.id!! - } else { - "" - } - }) - } - } - } - }.toSet().filter { userId -> !CommonTools.isNullStr(userId) }.toList() - - @EventListener - fun onTaskEvent(taskEntity: TaskEntity) { - try { - logAdapter.debug("收到工作流任务【${taskEntity.id}】事件【${taskEntity.eventName}】") - if (taskEntity.eventName == "create") { - notifyPendingCreated( - taskEntity.processInstance.businessKey, taskEntity, - if (CommonTools.isNullStr(taskEntity.assignee)) { - getIdentityLinkUserId(taskEntity.identityLinks) - } else { - listOf(taskEntity.assignee) - } - ) - } - } catch (e: Exception) { - logAdapter.error(e.message, e) - } - } - - /** - * 生成待办通知 - * @param businessKey 业务键 - * @param task 任务 - * @param userIdList 用户ID,默认null;当用户ID为null时,自动取运行时任务所有待办人员 - */ - @Throws(WebException::class) - fun notifyPendingCreated(businessKey: String, task: Task, userIdList: List) { - if (workFlowCustomerConfiguration.notifyPendingCreated) { - logAdapter.debug("进行待办通知...") - logAdapter.debug("userIdList --> $userIdList") - repositoryService.createProcessDefinitionQuery().processDefinitionId(task.processDefinitionId) - .singleResult()?.also { processDefinition -> - if (userIdList.isNotEmpty()) { - logAdapter.debug("开始待办通知处理【${processDefinition.key}】【${task.processInstanceId}】【$businessKey】,通知处理器数量【${pendingCreatedNotifyList.size}】...") - logAdapter.debug("处理器:${pendingCreatedNotifyList}") - pendingCreatedNotifyList.forEach { handle -> - ThreadPoolService.getInstance(5, 5, Int.MAX_VALUE, "create-pending-pool") - .addTask(object : BaseAsyncTask("create-pending") { - override fun afterExecuteFun(result: Any) {} - override fun beforeExecuteFun(): Boolean = true - override fun executeFun(): Any { - handle.doTaskNotify(businessKey, task, processDefinition, userIdList) - return true - } - }) - } - } - } ?: throw WebException("获取流程实例失败:taskId【${task.id}】") - } - } - - /** - * 完成待办通知 - * @param businessKey 业务键 - * @param task 任务 - * @param userIdList 用户ID,默认null;当用户ID为null时,自动取任务所有待办人员 - */ - @Throws(WebException::class) - fun notifyPendingFinished(businessKey: String, task: Task, userIdList: List) { - if (workFlowCustomerConfiguration.notifyPendingFinished) { - logAdapter.debug("删除待办通知...") - logAdapter.debug("userIdList --> $userIdList") - repositoryService.createProcessDefinitionQuery().processDefinitionId(task.processDefinitionId) - .singleResult()?.also { processDefinition -> - if (userIdList.isNotEmpty()) { - logAdapter.debug("开始删除待办通知处理【${processDefinition.key}】【${task.processInstanceId}】【$businessKey】,通知处理器数量【${pendingFinishedNotifyList.size}】...") - logAdapter.debug("处理器:${pendingFinishedNotifyList}") - pendingFinishedNotifyList.forEach { handle -> - ThreadPoolService.getInstance(5, 5, Int.MAX_VALUE, "delete-pending-pool") - .addTask(object : BaseAsyncTask("delete-pending") { - override fun afterExecuteFun(result: Any) {} - override fun beforeExecuteFun(): Boolean = true - override fun executeFun(): Any { - handle.doTaskNotify(businessKey, task, processDefinition, userIdList) - return true - } - }) - } - } - } ?: throw WebException("获取流程实例失败:taskId【${task.id}】") - } - } -} \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowPermissionHandler.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowPermissionHandler.kt new file mode 100644 index 00000000..7701e894 --- /dev/null +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowPermissionHandler.kt @@ -0,0 +1,54 @@ +package io.gitee.zhangbinhub.admin.workflow.component + +import io.gitee.zhangbinhub.acp.core.common.CommonTools +import io.gitee.zhangbinhub.admin.common.constant.WorkFlowConstant +import io.gitee.zhangbinhub.admin.resource.server.feign.CommonOauthServer +import org.dromara.warm.flow.core.handler.PermissionHandler +import org.springframework.security.core.context.SecurityContextHolder +import org.springframework.stereotype.Component + +@Component +class WorkFlowPermissionHandler(private val commonOauthServer: CommonOauthServer) : PermissionHandler { + fun userIdList(permissionList: List): Set = permissionList.map { permission -> + when { + permission.startsWith(WorkFlowConstant.PERMISSION_ROLE_PREFIX) -> { + permission.substring(WorkFlowConstant.PERMISSION_ROLE_PREFIX.length).let { roleId -> + commonOauthServer.findRoleById(roleId).userIds + } + } + + permission.startsWith(WorkFlowConstant.PERMISSION_DEPT_PREFIX) -> { + permission.substring(WorkFlowConstant.PERMISSION_DEPT_PREFIX.length).let { organizationId -> + commonOauthServer.findOrgById(organizationId).userIds + } + } + + else -> listOf(permission.trim()) + } + }.flatten().toSet() + + fun permissions(userIdList: List): Set = commonOauthServer.findUserList(userIdList).map { user -> + mutableListOf().apply { + this.add(user.id!!) + user.roleSet.forEach { role -> + this.add("${WorkFlowConstant.PERMISSION_ROLE_PREFIX}${role.id}") + } + user.organizationSet.forEach { organization -> + this.add("${WorkFlowConstant.PERMISSION_DEPT_PREFIX}${organization.id}") + } + } + }.flatten().toSet() + + override fun permissions(): MutableList = mutableListOf().apply { + commonOauthServer.findUserByLoginNo(SecurityContextHolder.getContext().authentication.name).let { + if (!CommonTools.isNullStr(it.id)) { + permissions(listOf(it.id!!)) + } else { + mutableListOf() + } + } + } + + override fun getHandler(): String? = + commonOauthServer.findUserByLoginNo(SecurityContextHolder.getContext().authentication.name).id +} \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowSelectService.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowSelectService.kt new file mode 100644 index 00000000..7bd4910b --- /dev/null +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/component/WorkFlowSelectService.kt @@ -0,0 +1,168 @@ +package io.gitee.zhangbinhub.admin.workflow.component + +import io.gitee.zhangbinhub.acp.core.common.CommonTools +import io.gitee.zhangbinhub.admin.common.constant.WorkFlowConstant +import io.gitee.zhangbinhub.admin.resource.server.feign.CommonOauthServer +import io.gitee.zhangbinhub.admin.resource.server.vo.OrganizationVo +import io.gitee.zhangbinhub.admin.resource.server.vo.RoleVo +import io.gitee.zhangbinhub.admin.resource.server.vo.UserVo +import org.dromara.warm.flow.ui.dto.HandlerFunDto +import org.dromara.warm.flow.ui.dto.HandlerQuery +import org.dromara.warm.flow.ui.dto.TreeFunDto +import org.dromara.warm.flow.ui.service.HandlerSelectService +import org.dromara.warm.flow.ui.vo.HandlerFeedBackVo +import org.dromara.warm.flow.ui.vo.HandlerSelectVo +import org.springframework.stereotype.Component + +@Component +class WorkFlowSelectService(private val commonOauthServer: CommonOauthServer) : HandlerSelectService { + override fun getHandlerType(): MutableList { + return mutableListOf("用户", "角色", "部门") + } + + override fun getHandlerSelect(query: HandlerQuery): HandlerSelectVo = + when (query.handlerType) { + "角色" -> getRole(query) + "部门" -> getDept(query) + "用户" -> getUser(query) + else -> HandlerSelectVo() + } + + private fun getRole(query: HandlerQuery): HandlerSelectVo = + commonOauthServer.roleList().let { roleList -> + if (!CommonTools.isNullStr(query.handlerCode)) { + roleList.filter { role -> role.code!!.contains(query.handlerCode) } + } else { + roleList + } + }.let { roleList -> + if (!CommonTools.isNullStr(query.handlerName)) { + roleList.filter { role -> role.name!!.contains(query.handlerName) } + } else { + roleList + } + }.let { roleList -> + val handlerFunDto = HandlerFunDto(roleList, roleList.size.toLong()) + .setStorageId { role -> "${WorkFlowConstant.PERMISSION_ROLE_PREFIX}${role.id}" } + .setHandlerCode(RoleVo::code) // 权限编码 + .setHandlerName(RoleVo::name) // 权限名称 + getHandlerSelectVo(handlerFunDto) + } + + private fun getDept(query: HandlerQuery): HandlerSelectVo = + commonOauthServer.orgList().let { organizationList -> + if (!CommonTools.isNullStr(query.handlerCode)) { + organizationList.filter { organization -> organization.code!!.contains(query.handlerCode) } + } else { + organizationList + } + }.let { organizationList -> + if (!CommonTools.isNullStr(query.handlerName)) { + organizationList.filter { organization -> organization.name!!.contains(query.handlerName) } + } else { + organizationList + } + }.let { organizationList -> + val handlerFunDto = HandlerFunDto(organizationList, organizationList.size.toLong()) + .setStorageId { organization -> "${WorkFlowConstant.PERMISSION_DEPT_PREFIX}${organization.id}" } + .setHandlerCode(OrganizationVo::code) // 权限编码 + .setHandlerName(OrganizationVo::name) // 权限名称 + getHandlerSelectVo(handlerFunDto) + } + + private fun getUser(query: HandlerQuery): HandlerSelectVo { + val userList = commonOauthServer.findUserList().let { userVos -> + if (!CommonTools.isNullStr(query.handlerCode)) { + userVos.filter { userVo -> userVo.loginNo!!.contains(query.handlerCode) } + } else { + userVos + } + }.let { userVos -> + if (!CommonTools.isNullStr(query.handlerName)) { + userVos.filter { userVo -> userVo.name!!.contains(query.handlerName) } + } else { + userVos + } + }.let { userVos -> + mutableListOf().apply { + userVos.forEach { userVo -> + if (userVo.organizationSet.isEmpty()) { + this.add(userVo) + } else { + userVo.organizationSet.forEach { organizationVo -> + this.add(UserVo().also { + it.id = userVo.id + it.name = userVo.name + it.organizationMngSet = mutableSetOf(organizationVo) + }) + } + } + } + } + } + val organizationList = commonOauthServer.orgList() + + // 业务系统数据,转成组件内部能够显示的数据, total是业务数据总数,用于分页显示 + val handlerFunDto = HandlerFunDto(userList, userList.size.toLong()) + .setStorageId { user -> user.id } + .setHandlerCode(UserVo::loginNo) // 权限编码 + .setHandlerName(UserVo::name) // 权限名称 + .setGroupName { user -> + if (user.organizationSet.isNotEmpty()) { + user.organizationSet.first().name + } else { + "" + } + } + + // 业务系统机构,转成组件内部左侧树列表能够显示的数据 + val treeFunDto: TreeFunDto = TreeFunDto(organizationList) + .setId { dept -> dept.id } // 左侧树ID + .setName(OrganizationVo::name) // 左侧树名称 + .setParentId { dept -> dept.parentId } // 左侧树父级ID + + return getHandlerSelectVo(handlerFunDto, treeFunDto) + } + + override fun handlerFeedback(storageIds: MutableList?): MutableList { + val handlerFeedBackVos: MutableList = mutableListOf() + // 遍历storageIds,按照原本的顺序回显名称 + if (!storageIds.isNullOrEmpty()) { + for (storageId in storageIds) { + handlerFeedBackVos.add( + HandlerFeedBackVo().apply { + this.storageId = storageId + this.handlerName = when { + storageId.startsWith(WorkFlowConstant.PERMISSION_ROLE_PREFIX) -> { + try { + commonOauthServer.findRoleById(storageId.substring(WorkFlowConstant.PERMISSION_ROLE_PREFIX.length)).name + ?: "" + } catch (e: Exception) { + "" + } + } + + storageId.startsWith(WorkFlowConstant.PERMISSION_DEPT_PREFIX) -> { + try { + commonOauthServer.findOrgById(storageId.substring(WorkFlowConstant.PERMISSION_DEPT_PREFIX.length)).name + ?: "" + } catch (e: Exception) { + "" + } + } + + else -> { + try { + commonOauthServer.findUserById(storageId).name ?: "" + } catch (e: Exception) { + "" + } + } + } + } + ) + } + } + return handlerFeedBackVos + } +} \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/conf/MybatisFlexConfiguration.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/conf/MybatisFlexConfiguration.kt new file mode 100644 index 00000000..ea621b85 --- /dev/null +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/conf/MybatisFlexConfiguration.kt @@ -0,0 +1,24 @@ +package io.gitee.zhangbinhub.admin.workflow.conf + +import com.mybatisflex.core.FlexGlobalConfig +import com.mybatisflex.core.keygen.IKeyGenerator +import com.mybatisflex.core.keygen.KeyGeneratorFactory +import com.mybatisflex.spring.boot.MyBatisFlexCustomizer +import io.gitee.zhangbinhub.acp.core.common.CommonTools +import org.springframework.context.annotation.Configuration + +/** + * 自定义Mybatis-Flex配置 + */ +@Configuration +class MybatisFlexConfiguration : MyBatisFlexCustomizer { + class AcpUUIDKeyGenerator : IKeyGenerator { + override fun generate(entity: Any, keyColumn: String): Any { + return CommonTools.getUuid() + } + } + + override fun customize(flexGlobalConfig: FlexGlobalConfig) { + KeyGeneratorFactory.register("AcpUUID", AcpUUIDKeyGenerator()) + } +} \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowConstant.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowConstant.kt index 79339f4d..c4d60f93 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowConstant.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowConstant.kt @@ -1,10 +1,6 @@ package io.gitee.zhangbinhub.admin.workflow.constant -/** - * @author zhang by 20/12/2019 - * @since JDK 11 - */ object WorkFlowConstant { - const val resourceSuffix = ".bpmn20.xml" - const val upLoadTempPath = "files/download" + const val SCHEMA_FILE = "warm-flow-all.sql" + const val DOWNLOAD_TEMP_PATH = "files/download" } \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowExpression.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowExpression.kt index 5d1af644..e077c0e9 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowExpression.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowExpression.kt @@ -3,10 +3,6 @@ package io.gitee.zhangbinhub.admin.workflow.constant import io.gitee.zhangbinhub.admin.common.constant.ModuleFuncCode import io.gitee.zhangbinhub.admin.common.constant.RoleCode -/** - * @author zhang by 14/06/2019 - * @since JDK 11 - */ object WorkFlowExpression { /** * 流程定义 diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowParamKey.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowParamKey.kt index 97ccbf4b..1da4f9a7 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowParamKey.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/constant/WorkFlowParamKey.kt @@ -1,26 +1,11 @@ package io.gitee.zhangbinhub.admin.workflow.constant -/** - * @author zhang by 14/06/2019 - * @since JDK 11 - * 流程变量key - */ object WorkFlowParamKey { /** * 流程发起人 */ const val startUserId = "startUserId" - /** - * 业务键 - */ - const val businessKey = "businessKey" - - /** - * 流程名称 - */ - const val flowName = "flowName" - /** * 流程标题 */ @@ -30,14 +15,4 @@ object WorkFlowParamKey { * 流程描述 */ const val description = "description" - - /** - * 处理结果 - */ - const val pass = "pass" - - /** - * 处理意见 - */ - const val comment = "comment" } \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/api/WorkFlowController.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/api/WorkFlowController.kt index 06025a1c..92bd9db0 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/api/WorkFlowController.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/api/WorkFlowController.kt @@ -2,28 +2,23 @@ package io.gitee.zhangbinhub.admin.workflow.controller.api import io.gitee.zhangbinhub.acp.boot.exceptions.WebException import io.gitee.zhangbinhub.acp.boot.log.LogAdapter -import io.gitee.zhangbinhub.acp.cloud.annotation.AcpCloudDuplicateSubmission import io.gitee.zhangbinhub.acp.core.common.CommonTools import io.gitee.zhangbinhub.admin.common.api.WorkFlowApi import io.gitee.zhangbinhub.admin.common.constant.ModuleFuncCode import io.gitee.zhangbinhub.admin.common.vo.CustomerQueryPageVo import io.gitee.zhangbinhub.admin.common.vo.InfoVo import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController -import io.gitee.zhangbinhub.admin.resource.server.po.ProcessHandlingPo -import io.gitee.zhangbinhub.admin.resource.server.po.ProcessQueryPo -import io.gitee.zhangbinhub.admin.resource.server.po.ProcessStartPo -import io.gitee.zhangbinhub.admin.resource.server.po.ProcessTerminationPo +import io.gitee.zhangbinhub.admin.resource.server.po.* import io.gitee.zhangbinhub.admin.resource.server.tools.TokenTools -import io.gitee.zhangbinhub.admin.resource.server.vo.* +import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessHisTaskVo +import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessInstanceVo +import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessTaskVo import io.gitee.zhangbinhub.admin.workflow.constant.WorkFlowExpression import io.gitee.zhangbinhub.admin.workflow.service.WorkFlowService -import io.swagger.v3.oas.annotations.* -import io.swagger.v3.oas.annotations.responses.ApiResponse -import io.swagger.v3.oas.annotations.responses.ApiResponses +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter import io.swagger.v3.oas.annotations.tags.Tag -import jakarta.validation.Valid import org.springframework.beans.factory.annotation.Autowired -import org.springframework.http.HttpStatus import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.security.access.prepost.PreAuthorize @@ -31,252 +26,239 @@ import org.springframework.security.oauth2.server.resource.authentication.Bearer import org.springframework.validation.annotation.Validated import org.springframework.web.bind.annotation.* -/** - * @author zhang by 10/06/2019 - * @since JDK 11 - */ @Validated @RestController @RequestMapping(WorkFlowApi.basePath) @Tag(name = "工作流引擎") class WorkFlowController @Autowired constructor( - logAdapter: LogAdapter, private val tokenTools: TokenTools, private val workFlowService: WorkFlowService + logAdapter: LogAdapter, + private val tokenTools: TokenTools, + private val workFlowService: WorkFlowService ) : BaseResourceServerController(logAdapter) { @Operation(summary = "启动流程", description = "启动指定的流程,并关联唯一业务主键") - @ApiResponses(ApiResponse(responseCode = "201", description = "流程启动成功")) @PutMapping(value = [WorkFlowApi.start], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission @Throws(WebException::class) fun start( - @Parameter(hidden = true) bearerTokenAuthentication: BearerTokenAuthentication, - @RequestBody @Valid processStartPo: ProcessStartPo - ): ResponseEntity = tokenTools.getUserInfoFromToken(bearerTokenAuthentication).let { tokenUserInfoVo -> - if (CommonTools.isNullStr(tokenUserInfoVo.id)) { - throw WebException("获取当前登录用户信息失败!") - } - workFlowService.startFlow(processStartPo, tokenUserInfoVo.id).let { - ResponseEntity.status(HttpStatus.CREATED).body(InfoVo(message = it)) + bearerTokenAuthentication: BearerTokenAuthentication, + @RequestBody @Validated processStartPo: ProcessStartPo + ): ResponseEntity = + tokenTools.getUserInfoFromToken(bearerTokenAuthentication).let { user -> + if (CommonTools.isNullStr(user.id)) { + throw WebException("找不到用户信息") + } + ResponseEntity.ok(InfoVo(message = workFlowService.startFlow(processStartPo, user.id).id.toString())) } - } @Operation(summary = "查询流程任务列表") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @PreAuthorize(WorkFlowExpression.flowAdmin) @GetMapping(value = [WorkFlowApi.taskList + "/{processInstanceId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) @Throws(WebException::class) - fun taskList(@PathVariable(name = "processInstanceId") processInstanceId: String): ResponseEntity> = - workFlowService.findTaskList(processInstanceId).let { - ResponseEntity.ok(it) - } + fun taskList(@PathVariable(name = "processInstanceId") processInstanceId: Long): ResponseEntity> = + ResponseEntity.ok(workFlowService.findTaskList(processInstanceId)) @Operation(summary = "查询待办任务", description = "获取当前用户的待办任务列表") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @PreAuthorize(WorkFlowExpression.flowPending) @PostMapping(value = [WorkFlowApi.pending], produces = [MediaType.APPLICATION_JSON_VALUE]) @Throws(WebException::class) - fun pending(@RequestBody @Valid processQueryPo: ProcessQueryPo): ResponseEntity> = - workFlowService.findTaskList(processQueryPo).let { - ResponseEntity.ok(it) + fun pending( + bearerTokenAuthentication: BearerTokenAuthentication, + @RequestBody @Validated processTaskQueryPo: ProcessTaskQueryPo + ): ResponseEntity> = + ResponseEntity.ok(workFlowService.findTaskList(bearerTokenAuthentication.name, processTaskQueryPo)) + + @Operation(summary = "转办任务", description = "转办指定的任务") + @PreAuthorize(WorkFlowExpression.flowProcess) + @PatchMapping( + value = [WorkFlowApi.transfer + "/{taskId}/{userId}"], + produces = [MediaType.APPLICATION_JSON_VALUE] + ) + @Throws(WebException::class) + fun transfer( + bearerTokenAuthentication: BearerTokenAuthentication, + @Parameter(name = "任务ID", required = true) + @PathVariable(name = "taskId") taskId: Long, + @Parameter(name = "目标userId", required = true) + @PathVariable(name = "userId") userId: String + ): ResponseEntity = + workFlowService.transfer(bearerTokenAuthentication.name, taskId, userId).let { + ResponseEntity.ok(InfoVo(message = "任务已转办")) } - @Operation(summary = "分配任务", description = "将任务指定给用户签收") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) + @Operation(summary = "转办任务", description = "转办指定的任务") @PreAuthorize(WorkFlowExpression.flowAdmin) @PatchMapping( - value = [WorkFlowApi.distribute + "/{taskId}/{userId}"], produces = [MediaType.APPLICATION_JSON_VALUE] + value = [WorkFlowApi.distribute + "/{taskId}/{userId}"], + produces = [MediaType.APPLICATION_JSON_VALUE] ) - @AcpCloudDuplicateSubmission @Throws(WebException::class) - fun distribute( - @Parameter(description = "任务ID", required = true) - @PathVariable(name = "taskId") taskId: String, - @Parameter(description = "用户ID", required = true) + fun transferAdmin( + bearerTokenAuthentication: BearerTokenAuthentication, + @Parameter(name = "任务ID", required = true) + @PathVariable(name = "taskId") taskId: Long, + @Parameter(name = "目标userId", required = true) @PathVariable(name = "userId") userId: String - ): ResponseEntity = workFlowService.claimTask(taskId, userId).let { - ResponseEntity.ok(InfoVo(message = "任务已分配")) - } + ): ResponseEntity = + workFlowService.transferAdmin(bearerTokenAuthentication.name, taskId, userId).let { + ResponseEntity.ok(InfoVo(message = "任务已转办")) + } - @Operation(summary = "领取任务", description = "签收指定的任务") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) + @Operation(summary = "委托办理任务", description = "委托办理指定的任务") @PreAuthorize(WorkFlowExpression.flowProcess) - @PatchMapping(value = [WorkFlowApi.claim + "/{taskId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission + @PatchMapping( + value = [WorkFlowApi.depute + "/{taskId}/{acceptUserId}"], + produces = [MediaType.APPLICATION_JSON_VALUE] + ) @Throws(WebException::class) - fun claim( - @Parameter( - description = "任务ID", required = true - ) @PathVariable(name = "taskId") taskId: String - ): ResponseEntity = workFlowService.claimTask(taskId).let { - ResponseEntity.ok(InfoVo(message = "任务已签收")) + fun depute( + bearerTokenAuthentication: BearerTokenAuthentication, + @Parameter(name = "任务ID", required = true) + @PathVariable(name = "taskId") taskId: Long, + @Parameter(name = "接收userId", required = true) + @PathVariable(name = "acceptUserId") acceptUserId: String + ): ResponseEntity = workFlowService.depute(bearerTokenAuthentication.name, taskId, acceptUserId).let { + ResponseEntity.ok(InfoVo(message = "任务已委托办理")) } - @Operation(summary = "转办任务", description = "转办指定的任务") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) + @Operation(summary = "任务加签") @PreAuthorize(WorkFlowExpression.flowProcess) - @PatchMapping(value = [WorkFlowApi.transfer + "/{taskId}/{userId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission + @PatchMapping( + value = [WorkFlowApi.addSignature + "/{taskId}/{acceptUserId}"], + produces = [MediaType.APPLICATION_JSON_VALUE] + ) @Throws(WebException::class) - fun transfer( - @Parameter(description = "任务ID", required = true) - @PathVariable(name = "taskId") taskId: String, - @Parameter(description = "目标userId", required = true) - @PathVariable(name = "userId") userId: String - ): ResponseEntity = workFlowService.turnTask(taskId, userId).let { - ResponseEntity.ok(InfoVo(message = "任务已转办")) + fun addSignature( + bearerTokenAuthentication: BearerTokenAuthentication, + @Parameter(name = "任务ID", required = true) + @PathVariable(name = "taskId") taskId: Long, + @Parameter(name = "加签userId", required = true) + @PathVariable(name = "acceptUserId") acceptUserId: String + ): ResponseEntity = workFlowService.addSignature(bearerTokenAuthentication.name, taskId, acceptUserId).let { + ResponseEntity.ok(InfoVo(message = "任务已加签")) } - @Operation(summary = "委托办理任务", description = "委托办理指定的任务") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) + @Operation(summary = "任务减签") @PreAuthorize(WorkFlowExpression.flowProcess) @PatchMapping( - value = [WorkFlowApi.delegate + "/{taskId}/{acceptUserId}"], produces = [MediaType.APPLICATION_JSON_VALUE] + value = [WorkFlowApi.reductionSignature + "/{taskId}/{acceptUserId}"], + produces = [MediaType.APPLICATION_JSON_VALUE] ) - @AcpCloudDuplicateSubmission @Throws(WebException::class) - fun delegate( - @Parameter(description = "任务ID", required = true) - @PathVariable(name = "taskId") taskId: String, - @Parameter(description = "接收userId", required = true) + fun reductionSignature( + bearerTokenAuthentication: BearerTokenAuthentication, + @Parameter(name = "任务ID", required = true) + @PathVariable(name = "taskId") taskId: Long, + @Parameter(name = "减签userId", required = true) @PathVariable(name = "acceptUserId") acceptUserId: String - ): ResponseEntity = workFlowService.delegateTask(taskId, acceptUserId).let { - ResponseEntity.ok(InfoVo(message = "任务已委托办理")) - } + ): ResponseEntity = + workFlowService.reductionSignature(bearerTokenAuthentication.name, taskId, acceptUserId).let { + ResponseEntity.ok(InfoVo(message = "任务已减签")) + } @Operation(summary = "流程处理", description = "可选通过或不通过") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @PreAuthorize(WorkFlowExpression.flowProcess) @PostMapping(value = [WorkFlowApi.process], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission @Throws(WebException::class) fun process( - @Parameter(hidden = true) bearerTokenAuthentication: BearerTokenAuthentication, - @RequestBody @Valid processHandlingPo: ProcessHandlingPo - ): ResponseEntity = tokenTools.getUserInfoFromToken(bearerTokenAuthentication).let { tokenUserInfoVo -> - if (CommonTools.isNullStr(tokenUserInfoVo.id)) { - throw WebException("获取当前登录用户信息失败!") + bearerTokenAuthentication: BearerTokenAuthentication, + @RequestBody @Validated processHandlingPo: ProcessHandlingPo + ): ResponseEntity = tokenTools.getUserInfoFromToken(bearerTokenAuthentication).let { user -> + if (CommonTools.isNullStr(user.id)) { + throw WebException("找不到用户信息") } - workFlowService.processTask(processHandlingPo, tokenUserInfoVo.id!!).let { + workFlowService.skip(processHandlingPo, user.id!!).let { ResponseEntity.ok(InfoVo(message = "流程处理完成")) } } @Operation(summary = "流程强制结束") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @PreAuthorize(WorkFlowExpression.flowProcess) @DeleteMapping(value = [WorkFlowApi.termination], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission @Throws(WebException::class) fun termination( - @Parameter(hidden = true) bearerTokenAuthentication: BearerTokenAuthentication, - @RequestBody @Valid processTerminationPo: ProcessTerminationPo - ): ResponseEntity = tokenTools.getUserInfoFromToken(bearerTokenAuthentication).let { tokenUserInfoVo -> - if (CommonTools.isNullStr(tokenUserInfoVo.id)) { - throw WebException("获取当前登录用户信息失败!") - } - workFlowService.findProcessInstance(processTerminationPo.processInstanceId!!).let { instance -> - if (instance.finished) { - false - } else { - when { - hasAuthentication(bearerTokenAuthentication, mutableListOf(ModuleFuncCode.flowAdmin)) -> { - true - } + bearerTokenAuthentication: BearerTokenAuthentication, + @RequestBody @Validated processTerminationPo: ProcessTerminationPo + ): ResponseEntity = + tokenTools.getUserInfoFromToken(bearerTokenAuthentication).let { user -> + if (CommonTools.isNullStr(user.id)) { + throw WebException("找不到用户信息") + } + workFlowService.findProcessInstance(processTerminationPo.processInstanceId!!).let { instance -> + if (instance.finished) { + false + } else { + when { + hasAuthentication(bearerTokenAuthentication, mutableListOf(ModuleFuncCode.flowAdmin)) -> { + true + } - else -> { - instance.startUser != null && !CommonTools.isNullStr(instance.startUser!!.id) && instance.startUser!!.id == tokenUserInfoVo.id + else -> { + instance.startUser != null && !CommonTools.isNullStr(instance.startUser!!.id) && instance.startUser!!.id == user.id + } } } - } - }.let { - if (it) { - workFlowService.deleteProcessInstance( - processTerminationPo, tokenUserInfoVo.id - ).let { - ResponseEntity.ok(InfoVo(message = "强制结束流程实例成功")) + }.let { + if (it) { + workFlowService.terminationFlow(processTerminationPo, user.id).let { + ResponseEntity.ok(InfoVo(message = "强制结束流程实例成功")) + } + } else { + throw WebException("流程已结束或当前登录人不是流程发起人,无法终止该流程!") } - } else { - throw WebException("流程已结束或当前登录人不是流程发起人,无法终止该流程!") } } - } @Operation(summary = "获取流程实例", description = "获取指定流程实例") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @GetMapping(value = [WorkFlowApi.instance + "/{processInstanceId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) @Throws(WebException::class) fun queryInstance( - @Parameter(description = "流程实例id", required = true) - @PathVariable(name = "processInstanceId") processInstanceId: String - ): ResponseEntity = workFlowService.findProcessInstance(processInstanceId).let { - ResponseEntity.ok(it) - } + @Parameter(name = "流程实例id", required = true) + @PathVariable(name = "processInstanceId") processInstanceId: Long + ): ResponseEntity = ResponseEntity.ok(workFlowService.findProcessInstance(processInstanceId)) @Operation(summary = "获取流程实例", description = "获取流程实例") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @PostMapping(value = [WorkFlowApi.instance], produces = [MediaType.APPLICATION_JSON_VALUE]) @Throws(WebException::class) - fun queryInstance(@RequestBody @Valid processQueryPo: ProcessQueryPo): ResponseEntity> = - workFlowService.findProcessInstance(processQueryPo).let { - ResponseEntity.ok(it) - } + fun queryInstance(@RequestBody @Validated processQueryPo: ProcessQueryPo): ResponseEntity> = + ResponseEntity.ok(workFlowService.findProcessInstance(processQueryPo)) @Operation(summary = "获取我处理过的流程实例", description = "获取我处理过的流程实例") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @PostMapping(value = [WorkFlowApi.myProcess], produces = [MediaType.APPLICATION_JSON_VALUE]) @Throws(WebException::class) - fun queryInstanceForMyProcess(@RequestBody @Valid processQueryPo: ProcessQueryPo): ResponseEntity> = - workFlowService.findProcessInstanceForMyProcess(processQueryPo).let { - ResponseEntity.ok(it) - } + fun queryInstanceForMyProcess( + bearerTokenAuthentication: BearerTokenAuthentication, + @RequestBody @Validated myProcessQueryPo: MyProcessQueryPo + ): ResponseEntity> = + ResponseEntity.ok( + workFlowService.findProcessInstanceForMyProcess( + bearerTokenAuthentication.name, + myProcessQueryPo + ) + ) @Operation(summary = "获取流程历史记录", description = "获取指定流程实例的历史处理记录") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @GetMapping(value = [WorkFlowApi.history + "/{processInstanceId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) @Throws(WebException::class) - fun queryHistoryActivity( - @Parameter(description = "流程实例id", required = true) - @PathVariable(name = "processInstanceId") processInstanceId: String - ): ResponseEntity> = workFlowService.findHistoryActivity(processInstanceId).let { - ResponseEntity.ok(it) - } + fun queryHisTask( + @Parameter(name = "流程实例id", required = true) + @PathVariable(name = "processInstanceId") processInstanceId: Long + ): ResponseEntity> = ResponseEntity.ok(workFlowService.findHistoryTask(processInstanceId)) @Operation(summary = "获取流程任务信息", description = "获取指定流程任务") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @PreAuthorize(WorkFlowExpression.flowProcess) @GetMapping(value = [WorkFlowApi.task + "/{taskId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) @Throws(WebException::class) fun queryTaskInfo( - @Parameter(description = "流程任务ID", required = true) - @PathVariable(name = "taskId") taskId: String - ): ResponseEntity = workFlowService.findTaskById(taskId).let { - ResponseEntity.ok(it) - } + bearerTokenAuthentication: BearerTokenAuthentication, + @Parameter(name = "流程任务ID", required = true) + @PathVariable(name = "taskId") taskId: Long + ): ResponseEntity = + ResponseEntity.ok(workFlowService.findTaskById(bearerTokenAuthentication.name, taskId)) - @Operation(summary = "获取流程定义", description = "获取指定流程定义") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) - @GetMapping( - value = [WorkFlowApi.instanceDefinition + "/{processInstanceId}"], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) + @Operation(summary = "获取流程图", description = "获取指定流程定义高亮元素") + @GetMapping(value = [WorkFlowApi.instanceChart + "/{processInstanceId}"], produces = [MediaType.TEXT_PLAIN_VALUE]) @Throws(WebException::class) - fun queryInstanceDefinition( - @Parameter(description = "流程实例id", required = true) - @PathVariable(name = "processInstanceId") processInstanceId: String - ): ResponseEntity = workFlowService.findProcessDefinition(processInstanceId).let { - ResponseEntity.ok(it) - } - - @Operation(summary = "获取流程定义高亮元素", description = "获取指定流程定义高亮元素") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) - @GetMapping( - value = [WorkFlowApi.instanceHighlight + "/{processInstanceId}"], - produces = [MediaType.APPLICATION_JSON_VALUE] - ) - @Throws(WebException::class) - fun queryInstanceHighlight( - @Parameter(description = "流程实例id", required = true) - @PathVariable(name = "processInstanceId") processInstanceId: String - ): ResponseEntity = workFlowService.findHighlightElement(processInstanceId).let { - ResponseEntity.ok(it) - } + fun queryFlowChart( + @Parameter(name = "流程实例id", required = true) + @PathVariable(name = "processInstanceId") processInstanceId: Long + ): ResponseEntity = ResponseEntity.ok(workFlowService.chartFlow(processInstanceId)) } diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/api/WorkFlowDefinitionController.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/api/WorkFlowDefinitionController.kt index 0a7dc8ea..381a535b 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/api/WorkFlowDefinitionController.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/api/WorkFlowDefinitionController.kt @@ -2,20 +2,17 @@ package io.gitee.zhangbinhub.admin.workflow.controller.api import io.gitee.zhangbinhub.acp.boot.exceptions.WebException import io.gitee.zhangbinhub.acp.boot.log.LogAdapter -import io.gitee.zhangbinhub.acp.cloud.annotation.AcpCloudDuplicateSubmission -import io.gitee.zhangbinhub.acp.core.common.CommonTools import io.gitee.zhangbinhub.admin.common.api.WorkFlowApi import io.gitee.zhangbinhub.admin.common.vo.CustomerQueryPageVo import io.gitee.zhangbinhub.admin.common.vo.InfoVo import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController +import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessDefinitionVo import io.gitee.zhangbinhub.admin.workflow.constant.WorkFlowExpression +import io.gitee.zhangbinhub.admin.workflow.po.ProcessDefinitionPo +import io.gitee.zhangbinhub.admin.workflow.po.ProcessDefinitionQueryPo import io.gitee.zhangbinhub.admin.workflow.service.WorkFlowDefinitionService -import io.gitee.zhangbinhub.admin.workflow.entity.WorkFlowDefinition -import io.gitee.zhangbinhub.admin.workflow.po.WorkFlowDefinitionPo -import io.gitee.zhangbinhub.admin.workflow.po.WorkFlowDefinitionQueryPo -import io.swagger.v3.oas.annotations.* -import io.swagger.v3.oas.annotations.responses.ApiResponse -import io.swagger.v3.oas.annotations.responses.ApiResponses +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter import io.swagger.v3.oas.annotations.tags.Tag import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse @@ -23,18 +20,12 @@ import jakarta.validation.Valid import jakarta.validation.constraints.NotEmpty import jakarta.validation.constraints.NotNull import org.springframework.beans.factory.annotation.Autowired -import org.springframework.data.domain.Page -import org.springframework.http.HttpStatus import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.security.access.prepost.PreAuthorize import org.springframework.validation.annotation.Validated import org.springframework.web.bind.annotation.* -/** - * @author zhang by 11/01/2019 - * @since JDK 11 - */ @Validated @RestController @RequestMapping(WorkFlowApi.basePath) @@ -46,18 +37,15 @@ constructor( ) : BaseResourceServerController(logAdapter) { @Operation(summary = "新建工作流信息") - @ApiResponses(ApiResponse(responseCode = "201", description = "创建成功")) @PreAuthorize(WorkFlowExpression.flowDefinition) @PutMapping(value = [WorkFlowApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission @Throws(WebException::class) - fun create(@RequestBody @Valid workFlowDefinitionPo: WorkFlowDefinitionPo): ResponseEntity = - workFlowDefinitionService.doCreate(workFlowDefinitionPo).let { - ResponseEntity.status(HttpStatus.CREATED).body(it) + fun create(@RequestBody @Valid processDefinitionPo: ProcessDefinitionPo): ResponseEntity = + workFlowDefinitionService.create(processDefinitionPo).let { + ResponseEntity.ok(InfoVo(message = "创建成功")) } @Operation(summary = "删除指定的工作流信息") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;")) @PreAuthorize(WorkFlowExpression.flowDefinition) @DeleteMapping(value = [WorkFlowApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE]) fun delete( @@ -65,52 +53,78 @@ constructor( @NotEmpty(message = "id不能为空") @NotNull(message = "id不能为空") @RequestBody - idList: MutableList - ): ResponseEntity = - workFlowDefinitionService.doDelete(idList).let { - ResponseEntity.ok(InfoVo(message = "删除成功")) - } + idList: MutableList + ): ResponseEntity = workFlowDefinitionService.delete(idList).let { + ResponseEntity.ok(InfoVo(message = "删除成功")) + } @Operation(summary = "更新指定的工作流信息") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;配置ID不能为空;找不到信息;")) @PreAuthorize(WorkFlowExpression.flowDefinition) @PatchMapping(value = [WorkFlowApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission @Throws(WebException::class) - fun update(@RequestBody @Valid workFlowDefinitionPo: WorkFlowDefinitionPo): ResponseEntity { - if (CommonTools.isNullStr(workFlowDefinitionPo.id)) { + fun update(@RequestBody @Valid processDefinitionPo: ProcessDefinitionPo): ResponseEntity { + if (processDefinitionPo.id == null) { throw WebException("ID不能为空") } - return workFlowDefinitionService.doUpdate(workFlowDefinitionPo).let { - ResponseEntity.ok(it) + return workFlowDefinitionService.update(processDefinitionPo).let { + ResponseEntity.ok(InfoVo(message = "更新成功")) } } @Operation(summary = "查询工作流信息列表") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;")) @PreAuthorize(WorkFlowExpression.flowDefinition) @PostMapping(value = [WorkFlowApi.definition], produces = [MediaType.APPLICATION_JSON_VALUE]) @Throws(WebException::class) - fun query(@RequestBody @Valid workFlowDefinitionQueryPo: WorkFlowDefinitionQueryPo): ResponseEntity> = - ResponseEntity.ok(workFlowDefinitionService.doQuery(workFlowDefinitionQueryPo)) + fun query(@RequestBody @Valid processDefinitionQueryPo: ProcessDefinitionQueryPo): ResponseEntity> = + ResponseEntity.ok(workFlowDefinitionService.query(processDefinitionQueryPo)) + + @Operation(summary = "发布工作流") + @PreAuthorize(WorkFlowExpression.flowDefinition) + @PostMapping(value = [WorkFlowApi.definitionPublish + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE]) + @Throws(WebException::class) + fun publish(@PathVariable(name = "id") id: Long): ResponseEntity = + workFlowDefinitionService.publish(id).let { + ResponseEntity.ok(InfoVo(message = "发布成功")) + } + + @Operation(summary = "取消发布工作流") + @PreAuthorize(WorkFlowExpression.flowDefinition) + @DeleteMapping(value = [WorkFlowApi.definitionPublish + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE]) + @Throws(WebException::class) + fun unPublish(@PathVariable(name = "id") id: Long): ResponseEntity = + workFlowDefinitionService.unPublish(id).let { + ResponseEntity.ok(InfoVo(message = "取消发布成功")) + } + + @Operation(summary = "激活工作流") + @PreAuthorize(WorkFlowExpression.flowDefinition) + @PostMapping(value = [WorkFlowApi.definitionActive + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE]) + @Throws(WebException::class) + fun active(@PathVariable(name = "id") id: Long): ResponseEntity = workFlowDefinitionService.active(id).let { + ResponseEntity.ok(InfoVo(message = "激活成功")) + } - @Operation(summary = "部署工作流") - @ApiResponses(ApiResponse(responseCode = "201", description = "部署成功")) + @Operation(summary = "挂起工作流") @PreAuthorize(WorkFlowExpression.flowDefinition) - @PutMapping(value = [WorkFlowApi.definitionDeploy + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission + @DeleteMapping(value = [WorkFlowApi.definitionActive + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE]) @Throws(WebException::class) - fun deploy(@PathVariable(name = "id") id: String): ResponseEntity = - ResponseEntity.status(HttpStatus.CREATED).body(workFlowDefinitionService.doDeploy(id)) + fun unActive(@PathVariable(name = "id") id: Long): ResponseEntity = + workFlowDefinitionService.unActive(id).let { + ResponseEntity.ok(InfoVo(message = "挂起成功")) + } + + @Operation(summary = "流程定义文件导入") + @PostMapping(value = [WorkFlowApi.definitionImport], produces = [MediaType.APPLICATION_JSON_VALUE]) + @Throws(WebException::class) + fun import(@RequestBody processDefinitionPo: ProcessDefinitionPo): ResponseEntity = + workFlowDefinitionService.import(processDefinitionPo).let { + ResponseEntity.ok(InfoVo(message = "导入成功")) + } - @Operation(summary = "流程定义文件下载") - @ApiResponses(ApiResponse(responseCode = "200", description = "请求成功,进行文件下载;")) - @GetMapping(value = [WorkFlowApi.definition + "/file/{id}"], produces = [MediaType.ALL_VALUE]) + @Operation(summary = "流程定义文件导出") + @GetMapping(value = [WorkFlowApi.definitionExport + "/{id}"], produces = [MediaType.APPLICATION_JSON_VALUE]) @Throws(WebException::class) - fun downloadFile( - request: HttpServletRequest, response: HttpServletResponse, - @PathVariable(name = "id") id: String - ) { - workFlowDefinitionService.doDownLoadFile(request, response, id) + fun export(request: HttpServletRequest, response: HttpServletResponse, @PathVariable(name = "id") id: Long) { + workFlowDefinitionService.export(request, response, id) } } diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/openinner/OpenInnerWorkFlowController.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/openinner/OpenInnerWorkFlowController.kt index eadaf4ed..99ea3301 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/openinner/OpenInnerWorkFlowController.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/controller/openinner/OpenInnerWorkFlowController.kt @@ -1,36 +1,26 @@ -package io.gitee.zhangbinhub.admin.workflow.controller.openinner +package io.gitee.zhangbinhub.admin.controller.openinner import io.gitee.zhangbinhub.acp.boot.exceptions.WebException import io.gitee.zhangbinhub.acp.boot.log.LogAdapter -import io.gitee.zhangbinhub.acp.cloud.annotation.AcpCloudDuplicateSubmission import io.gitee.zhangbinhub.admin.common.api.CommonPath import io.gitee.zhangbinhub.admin.common.api.WorkFlowApi +import io.gitee.zhangbinhub.admin.common.base.BaseController import io.gitee.zhangbinhub.admin.common.vo.InfoVo -import io.gitee.zhangbinhub.admin.resource.server.base.BaseResourceServerController import io.gitee.zhangbinhub.admin.resource.server.po.ProcessHandlingPo import io.gitee.zhangbinhub.admin.resource.server.po.ProcessStartPo import io.gitee.zhangbinhub.admin.resource.server.po.ProcessTerminationPo -import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessDefinitionVo -import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessHighlightElementVo import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessInstanceVo import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessTaskVo import io.gitee.zhangbinhub.admin.workflow.service.WorkFlowService -import io.swagger.v3.oas.annotations.* -import io.swagger.v3.oas.annotations.responses.ApiResponse -import io.swagger.v3.oas.annotations.responses.ApiResponses +import io.swagger.v3.oas.annotations.Operation +import io.swagger.v3.oas.annotations.Parameter import io.swagger.v3.oas.annotations.tags.Tag -import jakarta.validation.Valid import org.springframework.beans.factory.annotation.Autowired -import org.springframework.http.HttpStatus import org.springframework.http.MediaType import org.springframework.http.ResponseEntity import org.springframework.validation.annotation.Validated import org.springframework.web.bind.annotation.* -/** - * @author zhang by 01/02/2019 - * @since JDK 11 - */ @Validated @RestController @RequestMapping(CommonPath.openInnerBasePath) @@ -39,123 +29,84 @@ class OpenInnerWorkFlowController @Autowired constructor( private val logAdapter: LogAdapter, private val workFlowService: WorkFlowService -) : BaseResourceServerController(logAdapter) { +) : BaseController() { @Operation(summary = "获取流程任务信息", description = "获取指定流程任务") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @GetMapping(value = [WorkFlowApi.task + "/{taskId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) @Throws(WebException::class) fun queryTaskInfo( @Parameter(description = "流程任务ID", required = true) - @PathVariable(name = "taskId") taskId: String - ): ResponseEntity = - workFlowService.findTaskByIdOpen(taskId).let { - ResponseEntity.ok(it) - } + @PathVariable(name = "taskId") taskId: Long + ): ResponseEntity = ResponseEntity.ok(workFlowService.findTaskByIdOpen(taskId)) @Operation(summary = "启动流程", description = "启动指定的流程,并关联唯一业务主键") - @ApiResponses(ApiResponse(responseCode = "201", description = "流程启动成功")) @PutMapping(value = [WorkFlowApi.start], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission @Throws(WebException::class) - fun start(@RequestBody @Valid processStartPo: ProcessStartPo): ResponseEntity = - workFlowService.startFlow(processStartPo).let { - ResponseEntity.status(HttpStatus.CREATED).body(InfoVo(message = it)) - } + fun start(@RequestBody @Validated processStartPo: ProcessStartPo): ResponseEntity = + ResponseEntity.ok(InfoVo(message = workFlowService.startFlow(processStartPo).id.toString())) @Operation(summary = "启动流程", description = "启动指定的流程,并关联唯一业务主键") - @ApiResponses(ApiResponse(responseCode = "201", description = "流程启动成功")) @PutMapping(value = [WorkFlowApi.start + "/{userId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission @Throws(WebException::class) fun startByUser( @PathVariable(name = "userId") userId: String, - @RequestBody @Valid processStartPo: ProcessStartPo + @RequestBody @Validated processStartPo: ProcessStartPo ): ResponseEntity = - workFlowService.startFlow(processStartPo, userId).let { - ResponseEntity.status(HttpStatus.CREATED).body(InfoVo(message = it)) - } + ResponseEntity.ok(InfoVo(message = workFlowService.startFlow(processStartPo, userId).id.toString())) @Operation(summary = "流程处理", description = "可选通过或不通过") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @PostMapping(value = [WorkFlowApi.process + "/{userId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission @Throws(WebException::class) fun processByUser( @PathVariable(name = "userId") userId: String, - @RequestBody @Valid processHandlingPo: ProcessHandlingPo - ): ResponseEntity = - workFlowService.processTask(processHandlingPo, userId).let { - ResponseEntity.ok(InfoVo(message = "流程处理完成")) - } + @RequestBody @Validated processHandlingPo: ProcessHandlingPo + ): ResponseEntity = workFlowService.skip(processHandlingPo, userId).let { + ResponseEntity.ok(InfoVo(message = "流程处理完成")) + } @Operation(summary = "查询待办任务") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @GetMapping( value = [WorkFlowApi.pending + "/{processInstanceId}/{userId}"], produces = [MediaType.APPLICATION_JSON_VALUE] ) @Throws(WebException::class) fun pendingByUser( - @PathVariable(name = "processInstanceId") processInstanceId: String, + @PathVariable(name = "processInstanceId") processInstanceId: Long, @PathVariable(name = "userId") userId: String - ): ResponseEntity> = - workFlowService.findTaskList(processInstanceId, userId).let { - ResponseEntity.ok(it) - } + ): ResponseEntity> = ResponseEntity.ok(workFlowService.findTaskList(processInstanceId, userId)) @Operation(summary = "流程强制结束") - @ApiResponses(ApiResponse(responseCode = "400", description = "系统异常")) @DeleteMapping(value = [WorkFlowApi.termination], produces = [MediaType.APPLICATION_JSON_VALUE]) - @AcpCloudDuplicateSubmission @Throws(WebException::class) - fun termination(@RequestBody @Valid processTerminationPo: ProcessTerminationPo): ResponseEntity = + fun termination(@RequestBody @Validated processTerminationPo: ProcessTerminationPo): ResponseEntity = workFlowService.findProcessInstance(processTerminationPo.processInstanceId!!).let { instance -> if (instance.finished) { logAdapter.warn("流程已结束,无法再次终止该流程!") } - workFlowService.deleteProcessInstance(processTerminationPo).let { + workFlowService.terminationFlow(processTerminationPo).let { ResponseEntity.ok(InfoVo(message = "强制结束流程实例成功")) } } @Operation(summary = "获取流程实例", description = "获取指定流程实例") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) - @GetMapping(value = [WorkFlowApi.instance + "/{processInstanceId}"], produces = [MediaType.APPLICATION_JSON_VALUE]) - @Throws(WebException::class) - fun queryInstance( - @Parameter(description = "流程实例id", required = true) - @PathVariable(name = "processInstanceId") - processInstanceId: String - ): ResponseEntity = - workFlowService.findProcessInstance(processInstanceId).let { - ResponseEntity.ok(it) - } - - @Operation(summary = "获取流程定义", description = "获取指定流程定义") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) @GetMapping( - value = [WorkFlowApi.instanceDefinition + "/{processInstanceId}"], + value = [WorkFlowApi.instance + "/{processInstanceId}"], produces = [MediaType.APPLICATION_JSON_VALUE] ) @Throws(WebException::class) - fun queryInstanceDefinition( + fun queryInstance( @Parameter(description = "流程实例id", required = true) - @PathVariable(name = "processInstanceId") processInstanceId: String - ): ResponseEntity = workFlowService.findProcessDefinition(processInstanceId).let { - ResponseEntity.ok(it) - } + @PathVariable(name = "processInstanceId") + processInstanceId: Long + ): ResponseEntity = ResponseEntity.ok(workFlowService.findProcessInstance(processInstanceId)) - @Operation(summary = "获取流程定义高亮元素", description = "获取指定流程定义高亮元素") - @ApiResponses(ApiResponse(responseCode = "400", description = "参数校验不通过;系统异常")) + @Operation(summary = "获取流程图", description = "获取指定流程定义高亮元素") @GetMapping( - value = [WorkFlowApi.instanceHighlight + "/{processInstanceId}"], - produces = [MediaType.APPLICATION_JSON_VALUE] + value = [WorkFlowApi.instanceChart + "/{processInstanceId}"], + produces = [MediaType.TEXT_PLAIN_VALUE] ) @Throws(WebException::class) - fun queryInstanceHighlight( + fun queryFlowChart( @Parameter(description = "流程实例id", required = true) - @PathVariable(name = "processInstanceId") processInstanceId: String - ): ResponseEntity = workFlowService.findHighlightElement(processInstanceId).let { - ResponseEntity.ok(it) - } + @PathVariable(name = "processInstanceId") processInstanceId: Long + ): ResponseEntity = ResponseEntity.ok(workFlowService.chartFlow(processInstanceId)) } diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/entity/MyProcessInstance.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/entity/MyProcessInstance.kt index 0d9b18d9..88a73bed 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/entity/MyProcessInstance.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/entity/MyProcessInstance.kt @@ -26,7 +26,7 @@ data class MyProcessInstance( @Column(nullable = false) @Schema(description = "流程实例id") - var processInstanceId: String = "", + var processInstanceId: Long = 0, @Column(nullable = false) @Schema(description = "流程定义键") diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/entity/WorkFlowDefinition.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/entity/WorkFlowDefinition.kt deleted file mode 100644 index a2babe6b..00000000 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/entity/WorkFlowDefinition.kt +++ /dev/null @@ -1,57 +0,0 @@ -package io.gitee.zhangbinhub.admin.workflow.entity - -import io.swagger.v3.oas.annotations.media.Schema -import jakarta.persistence.* - -/** - * @author zhang by 20/12/2019 - * @since JDK 11 - */ -@Entity -@Table(name = "t_workflow_definition") -@Schema(description = "工作流定义信息") -data class WorkFlowDefinition( - @Id - @GeneratedValue(strategy = GenerationType.UUID) - @Column(length = 36, nullable = false) - @Schema(description = "ID") - var id: String = "", - - @Column(nullable = false) - @Schema(description = "流程定义键") - var processKey: String = "", - - @Column(nullable = false) - @Schema(description = "流程名称") - var name: String = "", - - @Lob - @Column(length = 16777215) - @Schema(description = "流程定义内容") - var content: String = "", - - @Column(nullable = false) - @Schema(description = "版本号") - var version: Int = 0, - - @Schema(description = "备注") - var remarks: String? = null, - - @Column(nullable = false) - @Schema(description = "创建时间") - var createTime: Long = System.currentTimeMillis(), - - @Column(nullable = false) - @Schema(description = "最后更新时间") - var modifyTime: Long = System.currentTimeMillis(), - - @Schema(description = "部署时间") - var deployTime: Long? = null, - - @Schema(description = "部署ID") - var deploymentId: String? = null, - - @Column(nullable = false) - @Schema(description = "是否启用") - var enabled: Boolean = true -) \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/init/DataInitialization.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/init/DataInitialization.kt new file mode 100644 index 00000000..c7bf062d --- /dev/null +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/init/DataInitialization.kt @@ -0,0 +1,39 @@ +package io.gitee.zhangbinhub.admin.workflow.init + +import io.gitee.zhangbinhub.acp.boot.init.AcpInitialization +import io.gitee.zhangbinhub.acp.core.common.CommonTools +import io.gitee.zhangbinhub.admin.common.constant.DbConstant +import io.gitee.zhangbinhub.admin.workflow.constant.WorkFlowConstant +import org.springframework.core.io.ClassPathResource +import org.springframework.jdbc.core.JdbcTemplate +import org.springframework.stereotype.Component +import java.nio.file.Files + +@Component +class DataInitialization(private val jdbcTemplate: JdbcTemplate) : AcpInitialization { + override val name: String + get() = "Data Initialization" + + override val order: Int + get() = 1 + + private fun initTable() { + ClassPathResource( + "${DbConstant.SCHEMA_PATH}/${ + jdbcTemplate.dataSource?.connection?.metaData?.databaseProductName?.lowercase() + }/${WorkFlowConstant.SCHEMA_FILE}" + ).let { resource -> + Files.readString(resource.file.toPath(), CommonTools.getDefaultCharset()) + }.apply { + for (sql in this.split(";")) { + if (sql.trim { it <= ' ' }.length > 10) { + jdbcTemplate.execute(sql) + } + } + } + } + + override fun doInit() { + initTable() + } +} \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/notify/LogPendingCreatedNotify.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/notify/LogPendingCreatedNotify.kt index 5c693ffb..2795c446 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/notify/LogPendingCreatedNotify.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/notify/LogPendingCreatedNotify.kt @@ -3,19 +3,15 @@ package io.gitee.zhangbinhub.admin.workflow.notify import io.gitee.zhangbinhub.acp.boot.exceptions.WebException import io.gitee.zhangbinhub.acp.boot.log.LogAdapter import io.gitee.zhangbinhub.admin.workflow.base.PendingCreatedNotify -import org.camunda.bpm.engine.repository.ProcessDefinition -import org.camunda.bpm.engine.task.Task +import org.dromara.warm.flow.core.entity.Definition +import org.dromara.warm.flow.core.entity.Instance +import org.dromara.warm.flow.core.entity.Task import org.springframework.stereotype.Component @Component class LogPendingCreatedNotify(private val logAdapter: LogAdapter) : PendingCreatedNotify() { @Throws(WebException::class) - override fun doTaskNotify( - businessKey: String, - task: Task, - processDefinition: ProcessDefinition, - userIdList: List - ) { - logAdapter.debug("待办生成通知:taskId【${task.id}】processInstanceId【${task.processInstanceId}】processDefinitionId【${task.processDefinitionId}】businessKey【$businessKey】,userId:$userIdList") + override fun doTaskNotify(definition: Definition, instance: Instance, task: Task, userIdList: List) { + logAdapter.debug("【${definition.flowCode}】【${definition.flowName}】待办生成通知:taskId【${task.id}】processInstanceId【${task.instanceId}】processDefinitionId【${definition.id}】businessKey【${instance.businessId}】,userId:$userIdList") } } \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/notify/LogPendingFinishedNotify.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/notify/LogPendingFinishedNotify.kt index 90d1a98b..eb968399 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/notify/LogPendingFinishedNotify.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/notify/LogPendingFinishedNotify.kt @@ -3,19 +3,15 @@ package io.gitee.zhangbinhub.admin.workflow.notify import io.gitee.zhangbinhub.acp.boot.exceptions.WebException import io.gitee.zhangbinhub.acp.boot.log.LogAdapter import io.gitee.zhangbinhub.admin.workflow.base.PendingFinishedNotify -import org.camunda.bpm.engine.repository.ProcessDefinition -import org.camunda.bpm.engine.task.Task +import org.dromara.warm.flow.core.entity.Definition +import org.dromara.warm.flow.core.entity.Instance +import org.dromara.warm.flow.core.entity.Task import org.springframework.stereotype.Component @Component class LogPendingFinishedNotify(private val logAdapter: LogAdapter) : PendingFinishedNotify() { @Throws(WebException::class) - override fun doTaskNotify( - businessKey: String, - task: Task, - processDefinition: ProcessDefinition, - userIdList: List - ) { - logAdapter.debug("待办完成通知:taskId【${task.id}】processInstanceId【${task.processInstanceId}】processDefinitionId【${task.processDefinitionId}】businessKey【$businessKey】,userId:$userIdList") + override fun doTaskNotify(definition: Definition, instance: Instance, task: Task, userIdList: List) { + logAdapter.debug("【${definition.flowCode}】【${definition.flowName}】待办完成通知:taskId【${task.id}】processInstanceId【${task.instanceId}】processDefinitionId【${definition.id}】businessKey【${instance.businessId}】,userId:$userIdList") } } \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/ProcessDefinitionPo.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/ProcessDefinitionPo.kt new file mode 100644 index 00000000..c7f93871 --- /dev/null +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/ProcessDefinitionPo.kt @@ -0,0 +1,20 @@ +package io.gitee.zhangbinhub.admin.workflow.po + +import io.swagger.v3.oas.annotations.media.Schema +import jakarta.validation.constraints.NotBlank + +@Schema(description = "流程定义信息参数") +data class ProcessDefinitionPo( + @Schema(description = "流程定义id") + var id: Long? = null, + @Schema(description = "流程编码", required = true) + @field:NotBlank(message = "流程编码不能为空") + var flowCode: String? = null, + @Schema(description = "流程名称", required = true) + @field:NotBlank(message = "流程名称不能为空") + var flowName: String? = null, + @Schema(description = "流程类别") + var category: String? = null, + @Schema(description = "流程定义内容") + var content: String? = null +) \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/WorkFlowDefinitionQueryPo.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/ProcessDefinitionQueryPo.kt similarity index 54% rename from modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/WorkFlowDefinitionQueryPo.kt rename to modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/ProcessDefinitionQueryPo.kt index f65bf74f..bc10f782 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/WorkFlowDefinitionQueryPo.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/ProcessDefinitionQueryPo.kt @@ -3,14 +3,12 @@ package io.gitee.zhangbinhub.admin.workflow.po import io.gitee.zhangbinhub.admin.common.base.BaseQueryPo import io.swagger.v3.oas.annotations.media.Schema -/** - * @author zhang by 20/12/2019 - * @since JDK 11 - */ @Schema(description = "工作流定义信息查询") -data class WorkFlowDefinitionQueryPo( - @Schema(description = "流程定义键") - var processKey: String? = null, +data class ProcessDefinitionQueryPo( + @Schema(description = "流程编码") + var flowCode: String? = null, @Schema(description = "流程名称") - var name: String? = null + var flowName: String? = null, + @Schema(description = "流程类别") + var category: String? = null ) : BaseQueryPo() \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/WorkFlowDefinitionPo.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/WorkFlowDefinitionPo.kt deleted file mode 100644 index b51aa267..00000000 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/po/WorkFlowDefinitionPo.kt +++ /dev/null @@ -1,19 +0,0 @@ -package io.gitee.zhangbinhub.admin.workflow.po - -import io.swagger.v3.oas.annotations.media.Schema -import jakarta.validation.constraints.NotBlank - -/** - * @author zhang by 20/12/2019 - * @since JDK 11 - */ -@Schema(description = "工作流定义信息参数") -data class WorkFlowDefinitionPo( - @Schema(description = "ID") - var id: String? = null, - @Schema(description = "流程配置信息") - @get:NotBlank(message = "流程配置信息不能为空") - var content: String? = null, - @Schema(description = "备注") - var remarks: String? = null -) \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/repo/MyProcessInstanceRepository.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/repo/MyProcessInstanceRepository.kt index c1532d98..decd9dd5 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/repo/MyProcessInstanceRepository.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/repo/MyProcessInstanceRepository.kt @@ -5,5 +5,5 @@ import io.gitee.zhangbinhub.admin.workflow.entity.MyProcessInstance import java.util.* interface MyProcessInstanceRepository : BaseRepository { - fun findByUserIdAndProcessInstanceId(userId: String, processInstanceId: String): Optional + fun findByUserIdAndProcessInstanceId(userId: String, processInstanceId: Long): Optional } \ No newline at end of file diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/repo/WorkFlowDefinitionRepository.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/repo/WorkFlowDefinitionRepository.kt deleted file mode 100644 index 737b171f..00000000 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/repo/WorkFlowDefinitionRepository.kt +++ /dev/null @@ -1,12 +0,0 @@ -package io.gitee.zhangbinhub.admin.workflow.repo - -import io.gitee.zhangbinhub.admin.workflow.base.BaseRepository -import io.gitee.zhangbinhub.admin.workflow.entity.WorkFlowDefinition - -/** - * @author zhangbin by 2018-1-17 17:44 - * @since JDK 11 - */ -interface WorkFlowDefinitionRepository : BaseRepository { - fun findAllByProcessKeyOrderByVersionDesc(processKey: String): MutableList -} diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/service/WorkFlowDefinitionService.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/service/WorkFlowDefinitionService.kt index f5ff3073..3d1886f2 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/service/WorkFlowDefinitionService.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/service/WorkFlowDefinitionService.kt @@ -3,160 +3,154 @@ package io.gitee.zhangbinhub.admin.workflow.service import io.gitee.zhangbinhub.acp.boot.component.FileDownLoadHandle import io.gitee.zhangbinhub.acp.boot.exceptions.WebException import io.gitee.zhangbinhub.acp.core.common.CommonTools -import io.gitee.zhangbinhub.admin.common.base.BaseService import io.gitee.zhangbinhub.admin.common.vo.CustomerQueryPageVo import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessDefinitionVo +import io.gitee.zhangbinhub.admin.workflow.base.BaseWorkFlowService import io.gitee.zhangbinhub.admin.workflow.constant.WorkFlowConstant -import io.gitee.zhangbinhub.admin.workflow.entity.WorkFlowDefinition -import io.gitee.zhangbinhub.admin.workflow.po.WorkFlowDefinitionPo -import io.gitee.zhangbinhub.admin.workflow.po.WorkFlowDefinitionQueryPo -import io.gitee.zhangbinhub.admin.workflow.repo.WorkFlowDefinitionRepository -import jakarta.persistence.criteria.Predicate +import io.gitee.zhangbinhub.admin.workflow.po.ProcessDefinitionPo +import io.gitee.zhangbinhub.admin.workflow.po.ProcessDefinitionQueryPo import jakarta.servlet.http.HttpServletRequest import jakarta.servlet.http.HttpServletResponse -import org.camunda.bpm.engine.RepositoryService -import org.camunda.bpm.model.bpmn.Bpmn -import org.camunda.bpm.model.bpmn.instance.Process -import org.springframework.beans.factory.annotation.Autowired -import org.springframework.data.domain.Page +import org.dromara.warm.flow.core.FlowEngine +import org.dromara.warm.flow.core.dto.DefJson +import org.dromara.warm.flow.core.entity.Definition +import org.dromara.warm.flow.core.service.DefService +import org.dromara.warm.flow.core.utils.page.Page import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional -import java.io.ByteArrayInputStream -/** - * @author zhang by 11/01/2019 - * @since JDK 11 - */ @Service @Transactional(readOnly = true) -class WorkFlowDefinitionService @Autowired constructor( - private val repositoryService: RepositoryService, - private val workFlowDefinitionRepository: WorkFlowDefinitionRepository, +class WorkFlowDefinitionService( + private val defService: DefService, private val fileDownLoadHandle: FileDownLoadHandle -) : BaseService() { - +) : BaseWorkFlowService() { @Throws(WebException::class) - private fun parseProcessDefinition(content: String): ProcessDefinitionVo = try { - Bpmn.readModelFromStream(ByteArrayInputStream(content.toByteArray(CommonTools.getDefaultCharset()))) - .let { modelInstance -> - val processType = modelInstance.model.getType(Process::class.java) - val elementList = modelInstance.getModelElementsByType(processType) - val modelElementInstance = elementList.first() - val id = modelElementInstance.getAttributeValue("id") - val name = modelElementInstance.getAttributeValue("name") - if (CommonTools.isNullStr(id)) { - throw WebException("没有配置流程id") - } - if (CommonTools.isNullStr(name)) { - throw WebException("没有配置流程名称") - } - ProcessDefinitionVo(id, name, content) - } + private fun parseProcessDefinition(content: String): DefJson = try { + FlowEngine.jsonConvert.strToBean(content, DefJson::class.java) } catch (e: Exception) { throw WebException(e.message) } + private fun definitionToVo(definition: Definition): ProcessDefinitionVo = ProcessDefinitionVo().apply { + this.id = definition.id.toString() + this.flowCode = definition.flowCode + this.flowName = definition.flowName + this.version = definition.version + this.category = definition.category + this.createTime = definition.createTime.time + this.updateTime = definition.updateTime.time + this.publishStatus = definition.isPublish + this.activityStatus = definition.activityStatus + if (definition.id != null) { + this.content = defService.exportJson(definition.id) + } + } + @Transactional @Throws(WebException::class) - fun doDeploy(id: String): WorkFlowDefinition = workFlowDefinitionRepository.getReferenceById(id).apply { - if (this.deployTime != null) { - throw WebException("流程【${this.name}】版本【${this.version}】已部署,不能重复部署!") + fun publish(id: Long) { + if (!defService.publish(id)) { + throw WebException("流程发布失败!") } - val deployment = repositoryService.createDeployment().name(name).addInputStream( - "${name}_${version}${WorkFlowConstant.resourceSuffix}", - ByteArrayInputStream(content.toByteArray(CommonTools.getDefaultCharset())) - ).deploy() ?: throw WebException("流程部署失败!") - deployTime = deployment.deploymentTime.time - deploymentId = deployment.id - }.let { - workFlowDefinitionRepository.save(it) } @Transactional @Throws(WebException::class) - fun doCreate(workFlowDefinitionPo: WorkFlowDefinitionPo): WorkFlowDefinition = - parseProcessDefinition(workFlowDefinitionPo.content!!).let { processDefinitionVo -> - WorkFlowDefinition( - processKey = processDefinitionVo.id!!, - name = processDefinitionVo.name!!, - version = (workFlowDefinitionRepository.findAllByProcessKeyOrderByVersionDesc(processDefinitionVo.id!!) - .maxOfOrNull { it.version } ?: 0) + 1, - remarks = workFlowDefinitionPo.remarks, - content = workFlowDefinitionPo.content!!, - enabled = true - ).let { - workFlowDefinitionRepository.save(it) - } + fun unPublish(id: Long) { + if (!defService.unPublish(id)) { + throw WebException("流程取消发布失败!") } + } @Transactional @Throws(WebException::class) - fun doUpdate(workFlowDefinitionPo: WorkFlowDefinitionPo): WorkFlowDefinition = - workFlowDefinitionRepository.getReferenceById(workFlowDefinitionPo.id!!).apply { - if (this.deployTime == null) { - val processDefinitionVo = parseProcessDefinition(workFlowDefinitionPo.content!!) - this.processKey = processDefinitionVo.id!! - this.name = processDefinitionVo.name!! - this.remarks = workFlowDefinitionPo.remarks - this.content = workFlowDefinitionPo.content!! - this.modifyTime = System.currentTimeMillis() - } - this.remarks = workFlowDefinitionPo.remarks - }.let { - workFlowDefinitionRepository.save(it) + fun active(id: Long) { + if (!defService.active(id)) { + throw WebException("流程激活失败!") } + } @Transactional - fun doDelete(idList: MutableList) = - workFlowDefinitionRepository.findAllById(idList).forEach { workFlowDefinition -> - if (workFlowDefinition.deployTime != null) { - workFlowDefinitionRepository.save(workFlowDefinition.apply { - this.enabled = false - }) - } else { - workFlowDefinitionRepository.delete(workFlowDefinition) - } + @Throws(WebException::class) + fun unActive(id: Long) { + if (!defService.unActive(id)) { + throw WebException("流程挂起失败!") } + } - fun doQuery(workFlowDefinitionQueryPo: WorkFlowDefinitionQueryPo): CustomerQueryPageVo = - workFlowDefinitionRepository.findAll({ root, _, criteriaBuilder -> - val predicateList: MutableList = mutableListOf() - predicateList.add(criteriaBuilder.equal(root.get("enabled"), true)) - if (!CommonTools.isNullStr(workFlowDefinitionQueryPo.name)) { - predicateList.add( - criteriaBuilder.like( - root.get("name").`as`(String::class.java), "%" + workFlowDefinitionQueryPo.name + "%" - ) - ) + @Transactional + @Throws(WebException::class) + fun create(processDefinitionPo: ProcessDefinitionPo) { + FlowEngine.newDef().apply { + this.flowCode = processDefinitionPo.flowCode + this.flowName = processDefinitionPo.flowName + this.category = processDefinitionPo.category + if (!defService.saveAndInitNode(this)) { + throw WebException("流程创建失败!") } - if (!CommonTools.isNullStr(workFlowDefinitionQueryPo.processKey)) { - predicateList.add( - criteriaBuilder.like( - root.get("processKey").`as`(String::class.java), - "%" + workFlowDefinitionQueryPo.processKey + "%" - ) - ) + } + } + + @Transactional + @Throws(WebException::class) + fun update(processDefinitionPo: ProcessDefinitionPo) { + defService.getById(processDefinitionPo.id).apply { + this.flowCode = processDefinitionPo.flowCode + this.flowName = processDefinitionPo.flowName + this.category = processDefinitionPo.category + if (!defService.updateById(this)) { + throw WebException("流程更新失败!") } - criteriaBuilder.and(*predicateList.toTypedArray()) - }, buildPageRequest(workFlowDefinitionQueryPo.queryParam!!)).let { page -> + } + } + + @Transactional + fun delete(idList: MutableList) { + defService.removeDef(idList) + } + + fun query(processDefinitionQueryPo: ProcessDefinitionQueryPo): CustomerQueryPageVo = + defService.orderByCreateTime().desc().page( + DefJson.copyDef(DefJson().apply { + this.flowCode = processDefinitionQueryPo.flowCode + this.flowName = processDefinitionQueryPo.flowName + this.category = processDefinitionQueryPo.category + }), + Page( + processDefinitionQueryPo.queryParam!!.currPage!!, + processDefinitionQueryPo.queryParam!!.pageSize!! + ) + ).let { pageResult -> CustomerQueryPageVo( - currPage = workFlowDefinitionQueryPo.queryParam!!.currPage!!, - pageSize = workFlowDefinitionQueryPo.queryParam!!.pageSize!!, - totalElements = page.totalElements, - content = page.content + totalElements = pageResult.total, + currPage = pageResult.pageNum, + pageSize = pageResult.pageSize, + content = pageResult.list.map { definitionToVo(it) } ) } + @Transactional + @Throws(WebException::class) + fun import(processDefinitionPo: ProcessDefinitionPo) { + if (!CommonTools.isNullStr(processDefinitionPo.content)) { + defService.importJson(processDefinitionPo.content!!) + } else { + throw WebException("导入内容不能为空!") + } + } + @Throws(WebException::class) - fun doDownLoadFile(request: HttpServletRequest, response: HttpServletResponse, id: String) { - val workFlowDefinition = workFlowDefinitionRepository.getReferenceById(id) - val targetFile = CommonTools.contentWriteToFile( - WorkFlowConstant.upLoadTempPath + "/${workFlowDefinition.name}_${workFlowDefinition.version}${WorkFlowConstant.resourceSuffix}", - workFlowDefinition.content - ) ?: throw WebException("生成文件失败") - val foldPath = targetFile.parentFile.canonicalPath - fileDownLoadHandle.downLoadFile( - request, response, targetFile.canonicalPath, listOf("$foldPath/.*"), true, 120000 - ) + fun export(request: HttpServletRequest, response: HttpServletResponse, id: Long) { + defService.getById(id).let { definition -> + val targetFile = CommonTools.contentWriteToFile( + WorkFlowConstant.DOWNLOAD_TEMP_PATH + "/${definition.flowName}_${definition.flowCode}_${definition.version}.json", + defService.exportJson(id) + ) + val foldPath = targetFile.parentFile.canonicalPath + fileDownLoadHandle.downLoadFile( + request, response, targetFile.canonicalPath, listOf("$foldPath/.*"), true, 120000 + ) + } } } diff --git a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/service/WorkFlowService.kt b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/service/WorkFlowService.kt index e7099b6a..060ce42b 100644 --- a/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/service/WorkFlowService.kt +++ b/modules/workflow-server/src/main/kotlin/io/gitee/zhangbinhub/admin/workflow/service/WorkFlowService.kt @@ -1,212 +1,180 @@ package io.gitee.zhangbinhub.admin.workflow.service +import com.mybatisflex.core.query.QueryChain +import com.mybatisflex.core.table.TableInfoFactory import io.gitee.zhangbinhub.acp.boot.exceptions.WebException import io.gitee.zhangbinhub.acp.boot.log.LogAdapter import io.gitee.zhangbinhub.acp.core.common.CommonTools import io.gitee.zhangbinhub.admin.common.vo.CustomerQueryPageVo +import io.gitee.zhangbinhub.admin.workflow.component.WorkFlowGlobalListener +import io.gitee.zhangbinhub.admin.workflow.component.WorkFlowPermissionHandler import io.gitee.zhangbinhub.admin.resource.server.feign.CommonOauthServer -import io.gitee.zhangbinhub.admin.resource.server.po.ProcessHandlingPo -import io.gitee.zhangbinhub.admin.resource.server.po.ProcessQueryPo -import io.gitee.zhangbinhub.admin.resource.server.po.ProcessStartPo -import io.gitee.zhangbinhub.admin.resource.server.po.ProcessTerminationPo -import io.gitee.zhangbinhub.admin.resource.server.vo.* +import io.gitee.zhangbinhub.admin.resource.server.po.* +import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessHisTaskVo +import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessInstanceVo +import io.gitee.zhangbinhub.admin.resource.server.vo.ProcessTaskVo +import io.gitee.zhangbinhub.admin.resource.server.vo.UserVo import io.gitee.zhangbinhub.admin.workflow.base.BaseWorkFlowService -import io.gitee.zhangbinhub.admin.workflow.component.WorkFlowListener import io.gitee.zhangbinhub.admin.workflow.constant.WorkFlowParamKey import io.gitee.zhangbinhub.admin.workflow.entity.MyProcessInstance import io.gitee.zhangbinhub.admin.workflow.repo.MyProcessInstanceRepository import jakarta.persistence.criteria.Predicate -import org.camunda.bpm.engine.* -import org.camunda.bpm.engine.history.HistoricActivityInstance -import org.camunda.bpm.engine.history.HistoricProcessInstance -import org.camunda.bpm.engine.history.HistoricVariableUpdate -import org.camunda.bpm.engine.runtime.ProcessInstance -import org.camunda.bpm.engine.task.DelegationState -import org.camunda.bpm.engine.task.Task -import org.camunda.bpm.model.bpmn.Bpmn -import org.camunda.bpm.model.bpmn.instance.BaseElement -import org.camunda.bpm.model.bpmn.instance.SequenceFlow -import org.camunda.bpm.model.bpmn.instance.camunda.CamundaProperties -import org.joda.time.DateTime -import org.springframework.beans.factory.annotation.Autowired +import org.dromara.warm.flow.core.FlowEngine +import org.dromara.warm.flow.core.chart.BetweenChart +import org.dromara.warm.flow.core.dto.DefJson +import org.dromara.warm.flow.core.dto.FlowParams +import org.dromara.warm.flow.core.entity.HisTask +import org.dromara.warm.flow.core.entity.Instance +import org.dromara.warm.flow.core.entity.Task +import org.dromara.warm.flow.core.enums.CooperateType +import org.dromara.warm.flow.core.enums.NodeType +import org.dromara.warm.flow.core.enums.SkipType +import org.dromara.warm.flow.core.enums.UserType +import org.dromara.warm.flow.core.service.* +import org.dromara.warm.flow.core.utils.page.Page +import org.dromara.warm.flow.orm.entity.FlowDefinition +import org.dromara.warm.flow.orm.entity.FlowTask +import org.dromara.warm.flow.orm.entity.FlowUser +import org.dromara.warm.flow.orm.mapper.FlowTaskMapper import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional +import java.awt.Color + -/** - * @author zhang by 10/06/2019 - * @since JDK 11 - */ @Service @Transactional(readOnly = true) -class WorkFlowService @Autowired constructor( +class WorkFlowService( private val logAdapter: LogAdapter, - private val workFlowListener: WorkFlowListener, + private val myProcessInstanceRepository: MyProcessInstanceRepository, private val commonOauthServer: CommonOauthServer, - private val formService: FormService, - private val identityService: IdentityService, - private val runtimeService: RuntimeService, + private val defService: DefService, + private val insService: InsService, private val taskService: TaskService, - private val repositoryService: RepositoryService, - private val historyService: HistoryService, - private val myProcessInstanceRepository: MyProcessInstanceRepository + private val userService: UserService, + private val hisTaskService: HisTaskService, + private val chartService: ChartService, + private val flowTaskMapper: FlowTaskMapper, + private val workFlowPermissionHandler: WorkFlowPermissionHandler, + private val workFlowGlobalListener: WorkFlowGlobalListener ) : BaseWorkFlowService() { - private val anonymousUserId = "anonymousUser" - - private fun getUserById(id: String?): UserVo = if (CommonTools.isNullStr(id) || id == anonymousUserId) { + @Throws(WebException::class) + private fun getUserById(id: String?): UserVo = if (CommonTools.isNullStr(id)) { UserVo() } else { - commonOauthServer.findUserById(id!!) - } - - private fun getExtensionProperties(processDefinitionId: String, elementId: String): MutableMap = - repositoryService.getBpmnModelInstance(processDefinitionId) - .getModelElementById(elementId)?.extensionElements?.elementsQuery?.filterByType( - CamundaProperties::class.java - )?.list()?.flatMap { it.camundaProperties }?.associate { it.camundaName to it.camundaValue }?.toMutableMap() - ?: mutableMapOf() - - /** - * 获取待办人员ID - */ - private fun getPendingUserId(task: Task): List = - if (CommonTools.isNullStr(task.assignee)) { - workFlowListener.getIdentityLinkUserId(taskService.getIdentityLinksForTask(task.id)) - } else { - listOf(task.assignee) + commonOauthServer.findUserById(id!!).also { + if (it.loginNo == null) { + throw WebException("获取当前登录用户信息失败!") + } } - + } /** * 获取待办人员 */ - private fun getPendingUser(task: Task): List = - commonOauthServer.findUserList(getPendingUserId(task)) - - @Throws(WebException::class) - private fun findRuntimeProcessInstance(processInstanceId: String): ProcessInstance = try { - runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId) - .singleResult() ?: throw WebException("流程实例不存在!") - } catch (e: Exception) { - logAdapter.error(e.message, e) - throw WebException(e.message) + private fun getPendingUser(task: Task): List = task.userList.flatMap { flowUser -> + workFlowPermissionHandler.userIdList(listOf(flowUser.processedBy)).map { userId -> + getUserById(userId).apply { + this.remark = UserType.getValueByKey(flowUser.type) + } + } } /** * 任务实体转换 * - * @param task 任务对象 + * @param flowTask 任务对象 * @return 转换后任务对象 */ @Throws(WebException::class) - private fun taskToVo(task: Task) = - historyService.createHistoricProcessInstanceQuery().processInstanceId(task.processInstanceId) - .singleResult()?.let { processInstance -> - val params = runtimeService.createVariableInstanceQuery() - .processInstanceIdIn(task.processInstanceId).list() - .associate { - it.name to it.value - }.toMutableMap() - ProcessTaskVo( - processInstanceId = task.processInstanceId, - name = task.name, - taskId = task.id, - taskDefinitionKey = task.taskDefinitionKey, - parentTaskId = task.parentTaskId, - executionId = task.executionId, - params = params, - businessKey = processInstance.businessKey ?: "", - unClaimed = task.assignee == null, - user = getUserById(task.assignee), - localParams = runtimeService.getVariablesLocal(task.executionId).toMutableMap(), - formFields = formService.getTaskFormData(task.id).formFields - .associate { it.label to it.value.value }.toMutableMap(), - properties = getExtensionProperties(processInstance.processDefinitionId, task.taskDefinitionKey), - createTime = task.createTime.time, - processDefinitionKey = processInstance.processDefinitionKey, - flowName = processInstance.processDefinitionName, - title = params[WorkFlowParamKey.title]?.toString() ?: "", - description = params[WorkFlowParamKey.description]?.toString() ?: "", - startUser = getUserById(processInstance.startUserId), - taskOwnerUser = getUserById(task.owner), - delegated = task.delegationState == DelegationState.PENDING, - pendingUserList = getPendingUser(task) - ) - } ?: throw WebException("获取流程实例失败") + private fun taskToVo(flowTask: Task): ProcessTaskVo = insService.getById(flowTask.instanceId).let { flowInstance -> + val params = flowInstance.variableMap + val defJson = FlowEngine.jsonConvert.strToBean(flowInstance.defJson, DefJson::class.java) + if (flowTask.userList == null) { + flowTask.userList = userService.list(FlowEngine.newUser().setAssociated(flowTask.id)) + } + return ProcessTaskVo( + processInstanceId = flowTask.instanceId.toString(), + processDefinitionKey = defService.getById(flowTask.definitionId).flowCode, + flowName = defJson.flowName, + taskId = flowTask.id.toString(), + nodeCode = flowTask.nodeCode, + nodeName = flowTask.nodeName, + businessKey = flowTask.businessId, + params = params, + createTime = flowTask.createTime.time, + title = params[WorkFlowParamKey.title]?.toString() ?: "", + description = params[WorkFlowParamKey.description]?.toString() ?: "", + startUser = getUserById(flowInstance.createBy), + pendingUserList = getPendingUser(flowTask) + ) + } /** * 历史记录实例转换 * - * @param historicActivityInstance 历史记录 + * @param flowHisTask 历史记录 * @return 转换后对象 */ - private fun actToVo( - historicActivityInstance: HistoricActivityInstance, businessKey: String - ): ProcessHistoryActivityVo = - historyService.createHistoricDetailQuery().activityInstanceId(historicActivityInstance.id).variableUpdates() - .orderByTime().asc().list().let { historicDetailList -> - val params: MutableMap = mutableMapOf() - historicDetailList.forEach { historicDetail -> - val name = (historicDetail as HistoricVariableUpdate).variableName - if (params.containsKey(name) && WorkFlowParamKey.comment == name) { - params[name] = "${params[name].toString()}\n------\n${historicDetail.value}" - } else { - params[name] = historicDetail.value - } - } - historyService.createHistoricTaskInstanceQuery().taskId(historicActivityInstance.taskId).singleResult() - ?.let { - ProcessHistoryActivityVo( - processInstanceId = historicActivityInstance.processInstanceId, - activityId = historicActivityInstance.activityId, - activityName = historicActivityInstance.activityName, - taskId = historicActivityInstance.taskId, - taskDefinitionKey = it.taskDefinitionKey, - executionId = historicActivityInstance.executionId, - businessKey = businessKey, - user = getUserById(historicActivityInstance.assignee), - pass = params[WorkFlowParamKey.pass]?.let { pass -> pass as Boolean }, - comment = params[WorkFlowParamKey.comment]?.toString(), - params = params, - startTime = historicActivityInstance.startTime.time, - endTime = historicActivityInstance.endTime?.time - ) - } ?: throw WebException("获取任务信息失败!") - } + private fun hisTaskToVo(flowHisTask: HisTask): ProcessHisTaskVo = + insService.getById(flowHisTask.instanceId).let { flowInstance -> + val params = flowInstance.variableMap + val defJson = FlowEngine.jsonConvert.strToBean(flowInstance.defJson, DefJson::class.java) + return ProcessHisTaskVo( + processInstanceId = flowHisTask.instanceId.toString(), + processDefinitionKey = defService.getById(flowHisTask.definitionId).flowCode, + flowName = defJson.flowName, + taskId = flowHisTask.id.toString(), + nodeCode = flowHisTask.nodeCode, + nodeName = flowHisTask.nodeName, + businessKey = flowHisTask.businessId, + params = params, + createTime = flowHisTask.createTime.time, + updateTime = flowHisTask.updateTime.time, + user = getUserById(flowHisTask.approver), + message = flowHisTask.message, + skipType = flowHisTask.skipType + ) + } /** * 流程实例转换 - * @param processInstance 流程实例 + * @param flowInstance 流程实例 * @return 转换后的对象 */ @Throws(WebException::class) - private fun instanceToVo(processInstance: HistoricProcessInstance): ProcessInstanceVo { - val params = historyService.createHistoricVariableInstanceQuery() - .processInstanceIdIn(processInstance.id).list() - .associate { - it.name to it.value - }.toMutableMap() + private fun instanceToVo(flowInstance: Instance): ProcessInstanceVo { + val params = flowInstance.variableMap + val defJson = FlowEngine.jsonConvert.strToBean(flowInstance.defJson, DefJson::class.java) return ProcessInstanceVo( - processInstanceId = processInstance.id, - finished = processInstance.endTime != null, - processDefinitionKey = processInstance.processDefinitionKey, - businessKey = processInstance.businessKey, - flowName = processInstance.processDefinitionName, + processInstanceId = flowInstance.id.toString(), + processDefinitionKey = defService.getById(flowInstance.definitionId).flowCode, + businessKey = flowInstance.businessId, + flowName = defJson.flowName, title = params[WorkFlowParamKey.title]?.toString() ?: "", description = params[WorkFlowParamKey.description]?.toString() ?: "", - startUser = getUserById(processInstance.startUserId), - activityUser = taskService.createTaskQuery().processInstanceId(processInstance.id).list() - .flatMap { task -> - getPendingUser(task) - }.toMutableList(), + startUser = getUserById(flowInstance.createBy), + activityUser = taskService.list(FlowEngine.newTask().apply { + this.instanceId = flowInstance.id + }).flatMap { flowTask -> + getPendingUser(flowTask.apply { + flowTask.userList = userService.list(FlowEngine.newUser().setAssociated(flowTask.id)) + }) + }.toMutableList(), params = params, - startTime = processInstance.startTime!!.time, - endTime = processInstance.endTime?.time, - deleteReason = processInstance.deleteReason + nodeCode = flowInstance.nodeCode, + nodeName = flowInstance.nodeName, + startTime = flowInstance.createTime!!.time, + updateTime = flowInstance.updateTime!!.time, + activityStatus = flowInstance.activityStatus, + status = flowInstance.flowStatus, + finished = NodeType.isEnd(flowInstance.nodeType) ) } @Throws(WebException::class) - private fun getTask(taskId: String): Task = taskService.createTaskQuery().taskId(taskId).singleResult() ?: run { + private fun getTask(taskId: Long): Task = taskService.getById(taskId)?.apply { + this.userList = userService.list(FlowEngine.newUser().setAssociated(taskId)) + } ?: run { logAdapter.error("流程任务【$taskId】不存在!") throw WebException("流程任务不存在!") } @@ -220,27 +188,17 @@ class WorkFlowService @Autowired constructor( */ @Transactional @Throws(WebException::class) - fun startFlow(processStartPo: ProcessStartPo, userId: String? = null): String = try { - val params = processStartPo.params - repositoryService.createProcessDefinitionQuery().processDefinitionKey(processStartPo.processDefinitionKey) - .orderByProcessDefinitionVersion().desc().list().apply { - if (this.isEmpty()) { - throw WebException("找不到对应的流程定义【${processStartPo.processDefinitionKey}】") - } - params[WorkFlowParamKey.flowName] = this[0].name - } - params[WorkFlowParamKey.businessKey] = processStartPo.businessKey!! - params[WorkFlowParamKey.title] = processStartPo.title!! - params[WorkFlowParamKey.description] = processStartPo.description!! + fun startFlow(processStartPo: ProcessStartPo, userId: String? = null): Instance = try { + val flowParams = FlowParams().variable(processStartPo.params).flowCode(processStartPo.processDefinitionKey) + flowParams.variable[WorkFlowParamKey.title] = processStartPo.title!! + flowParams.variable[WorkFlowParamKey.description] = processStartPo.description!! userId?.apply { - params[WorkFlowParamKey.startUserId] = this - identityService.setAuthenticatedUserId(this) + flowParams.variable[WorkFlowParamKey.startUserId] = this + flowParams.handler(this) } - runtimeService.startProcessInstanceByKey( - processStartPo.processDefinitionKey, processStartPo.businessKey, params - ).id.also { + insService.start(processStartPo.businessKey, flowParams).also { logAdapter.info( - "流程启动成功:流程定义【${processStartPo.processDefinitionKey}】流程实例ID【$it】业务KEY【${processStartPo.businessKey}】启动人【${ + "流程启动成功:流程定义【${processStartPo.processDefinitionKey}】流程实例ID【${it.id}】业务KEY【${it.businessId}】启动人【${ getUserById( userId ).loginNo @@ -252,134 +210,179 @@ class WorkFlowService @Autowired constructor( throw WebException(e.message) } - /** - * 获取任务信息 - * - * @param taskId 任务ID - * @return 任务信息 - */ + @Transactional @Throws(WebException::class) - fun findTaskById(taskId: String): ProcessTaskVo = try { - commonOauthServer.userInfo()?.let { userInfo -> - taskService.createTaskQuery().or() - .taskAssignee(userInfo.id) - .taskCandidateUser(userInfo.id).includeAssignedTasks() - .taskCandidateGroupIn(userInfo.roleSet.map { role -> role.code }.toList()).includeAssignedTasks() - .endOr() - .taskId(taskId).singleResult()?.let { - taskToVo(it) - } ?: throw WebException("找不到信息") - } ?: throw WebException("获取当前登录用户信息失败!") + fun terminationFlow(processTerminationPo: ProcessTerminationPo, userId: String? = null): Instance = try { + val flowParams = FlowParams().message(processTerminationPo.reason).ignore(true) + userId?.apply { + flowParams.handler(this) + } + taskService.terminationByInsId(processTerminationPo.processInstanceId, flowParams).also { instance -> + logAdapter.info( + "任务终止成功:流程实例ID【${instance.id}】操作人【${ + getUserById( + userId + ).loginNo + }】" + ) + } } catch (e: Exception) { logAdapter.error(e.message, e) throw WebException(e.message) } - /** - * 获取任务信息(开放的) - * - * @param taskId 任务ID - * @return 任务信息 - */ + @Transactional @Throws(WebException::class) - fun findTaskByIdOpen(taskId: String): ProcessTaskVo = try { - taskToVo(getTask(taskId)) + fun terminationTask( + processTerminationPo: ProcessTerminationPo, taskId: Long, userId: String? = null + ): Instance = try { + val flowParams = FlowParams().message(processTerminationPo.reason).ignore(true) + userId?.apply { + flowParams.handler(this) + } + taskService.termination(taskId, flowParams).also { instance -> + logAdapter.info( + "任务终止成功:流程实例ID【${instance.id}】操作人【${ + getUserById( + userId + ).loginNo + }】" + ) + } } catch (e: Exception) { logAdapter.error(e.message, e) throw WebException(e.message) } /** - * 获取待办任务 - * @param processInstanceId 流程实例ID - * @param userId 用户ID + * 转办 + * + * @param taskId 任务id */ + @Transactional @Throws(WebException::class) - fun findTaskList(processInstanceId: String, userId: String? = null): List = try { - taskService.createTaskQuery().processInstanceId(processInstanceId).apply { - if (!CommonTools.isNullStr(userId)) { - this.taskAssignee(userId) + fun transferAdmin(loginNo: String, taskId: Long, acceptUserId: String) { + try { + commonOauthServer.findUserByLoginNo(loginNo).let { userInfo -> + if (userInfo.id == null) { + throw WebException("获取当前登录用户信息失败!") + } + val task = getTask(taskId) + if (taskService.updateHandler( + taskId, + FlowParams().handler(userInfo.id) + .addHandlers(listOf(acceptUserId)) + .reductionHandlers(task.userList.map { it.processedBy }) + .cooperateType(CooperateType.TRANSFER.key) + .message("任务转办").ignore(true) + ) + ) { + workFlowGlobalListener.notifyPendingFinished( + insService.getById(task.instanceId), + task, + getPendingUser(task).mapNotNull { it.id } + ) + logAdapter.info( + "任务转办成功:流程实例ID【${task.instanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】新办理人【${ + getUserById( + acceptUserId + ).loginNo + }】" + ) + } else { + logAdapter.info( + "任务转办失败:流程实例ID【${task.instanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】" + ) + } } - }.list().map { - taskToVo(it) + } catch (e: Exception) { + logAdapter.error(e.message, e) + throw WebException(e.message) } - } catch (e: Exception) { - logAdapter.error(e.message, e) - throw WebException(e.message) } /** - * 获取待办任务 + * 转办 * - * @return 任务列表 + * @param taskId 任务id */ + @Transactional @Throws(WebException::class) - fun findTaskList(processQueryPo: ProcessQueryPo): CustomerQueryPageVo = try { - val firstResult = (processQueryPo.queryParam!!.currPage!! - 1) * processQueryPo.queryParam!!.pageSize!! - val maxResult = processQueryPo.queryParam!!.pageSize!! - commonOauthServer.userInfo()?.let { userInfo -> - val taskQuery = taskService.createTaskQuery().or() - .taskAssignee(userInfo.id) - .taskCandidateUser(userInfo.id).includeAssignedTasks() - .taskCandidateGroupIn(userInfo.roleSet.map { role -> role.code }.toList()).includeAssignedTasks() - .endOr() - if (processQueryPo.processDefinitionKeys != null && processQueryPo.processDefinitionKeys!!.isNotEmpty()) { - taskQuery.processDefinitionKeyIn(*processQueryPo.processDefinitionKeys!!.toTypedArray()) - } - if (processQueryPo.processInstanceIds != null && processQueryPo.processInstanceIds!!.isNotEmpty()) { - taskQuery.processInstanceIdIn(*processQueryPo.processInstanceIds!!.toTypedArray()) - } - if (!CommonTools.isNullStr(processQueryPo.processBusinessKey)) { - taskQuery.processInstanceBusinessKeyLike(processQueryPo.processBusinessKey) - } - if (processQueryPo.startTime != null) { - taskQuery.taskCreatedAfter(DateTime(processQueryPo.startTime!!).toDate()) - } - if (processQueryPo.endTime != null) { - taskQuery.taskCreatedBefore(DateTime(processQueryPo.endTime!!).toDate()) + fun transfer(loginNo: String, taskId: Long, acceptUserId: String) { + try { + commonOauthServer.findUserByLoginNo(loginNo).let { userInfo -> + if (userInfo.id == null) { + throw WebException("获取当前登录用户信息失败!") + } + val task = getTask(taskId) + if (taskService.transfer( + taskId, FlowParams().handler(userInfo.id) + .permissionFlag( + workFlowPermissionHandler.permissions(listOf(userInfo.id!!)).toMutableList() + ) + .addHandlers(listOf(acceptUserId)).message("任务转办") + ) + ) { + workFlowGlobalListener.notifyPendingFinished( + insService.getById(task.instanceId), task, listOf(userInfo.id!!) + ) + logAdapter.info( + "任务转办成功:流程实例ID【${task.instanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】新办理人【${ + getUserById( + acceptUserId + ).loginNo + }】" + ) + } else { + logAdapter.info( + "任务转办失败:流程实例ID【${task.instanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】" + ) + } } - val total = taskQuery.list().count() - val list = taskQuery.orderByTaskCreateTime().asc() - .listPage(firstResult, maxResult).map { task -> taskToVo(task) } - CustomerQueryPageVo( - currPage = processQueryPo.queryParam!!.currPage!!, - pageSize = processQueryPo.queryParam!!.pageSize!!, - totalElements = total.toLong(), - content = list - ) - } ?: throw WebException("获取当前登录用户信息失败!") - } catch (e: Exception) { - logAdapter.error(e.message, e) - throw WebException(e.message) + } catch (e: Exception) { + logAdapter.error(e.message, e) + throw WebException(e.message) + } } /** - * 签收任务 + * 委派 * * @param taskId 任务id */ @Transactional @Throws(WebException::class) - fun claimTask(taskId: String, userId: String? = null) { + fun depute(loginNo: String, taskId: Long, acceptUserId: String) { try { - (if (CommonTools.isNullStr(userId)) { - commonOauthServer.userInfo()?.id ?: throw WebException("获取当前登录用户信息失败!") - } else { - userId!! - }).let { targetUserId -> - identityService.setAuthenticatedUserId(targetUserId) + commonOauthServer.findUserByLoginNo(loginNo).let { userInfo -> + if (userInfo.id == null) { + throw WebException("获取当前登录用户信息失败!") + } val task = getTask(taskId) - val processInstance = findRuntimeProcessInstance(task.processInstanceId) - workFlowListener.notifyPendingFinished(processInstance.businessKey, task, getPendingUserId(task)) - taskService.claim(taskId, targetUserId) - workFlowListener.notifyPendingCreated(processInstance.businessKey, task, listOf(targetUserId)) - logAdapter.info( - "任务签收成功:流程实例ID【${task.processInstanceId}】任务ID【$taskId】签收人【${ - getUserById( - targetUserId - ).loginNo - }】" - ) + if (taskService.depute( + taskId, + FlowParams().handler(userInfo.id) + .permissionFlag( + workFlowPermissionHandler.permissions(listOf(userInfo.id!!)).toMutableList() + ) + .addHandlers(listOf(acceptUserId)).message("任务委派") + ) + ) { + workFlowGlobalListener.notifyPendingFinished( + insService.getById(task.instanceId), task, listOf(userInfo.id!!) + ) + logAdapter.info( + "任务委派成功:流程实例ID【${task.instanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】新办理人【${ + getUserById( + acceptUserId + ).loginNo + }】" + ) + } else { + logAdapter.info( + "任务委派失败:流程实例ID【${task.instanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】" + ) + } } } catch (e: Exception) { logAdapter.error(e.message, e) @@ -388,29 +391,41 @@ class WorkFlowService @Autowired constructor( } /** - * 转办任务 + * 加签 * * @param taskId 任务id */ @Transactional @Throws(WebException::class) - fun turnTask(taskId: String, acceptUserId: String) { + fun addSignature(loginNo: String, taskId: Long, acceptUserId: String) { try { - commonOauthServer.userInfo()?.let { userInfo -> - identityService.setAuthenticatedUserId(userInfo.id) + commonOauthServer.findUserByLoginNo(loginNo).let { userInfo -> + if (userInfo.id == null) { + throw WebException("获取当前登录用户信息失败!") + } val task = getTask(taskId) - val processInstance = findRuntimeProcessInstance(task.processInstanceId) - workFlowListener.notifyPendingFinished(processInstance.businessKey, task, getPendingUserId(task)) - taskService.setAssignee(taskId, acceptUserId) - workFlowListener.notifyPendingCreated(processInstance.businessKey, task, listOf(acceptUserId)) - logAdapter.info( - "任务转办成功:流程实例ID【${task.processInstanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】新办理人【${ - getUserById( - acceptUserId - ).loginNo - }】" - ) - } ?: throw WebException("获取当前登录用户信息失败!") + if (taskService.addSignature( + taskId, + FlowParams().handler(userInfo.id) + .permissionFlag( + workFlowPermissionHandler.permissions(listOf(userInfo.id!!)).toMutableList() + ) + .addHandlers(listOf(acceptUserId)).message("任务加签") + ) + ) { + logAdapter.info( + "任务加签成功:流程实例ID【${task.instanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】新增办理人【${ + getUserById( + acceptUserId + ).loginNo + }】" + ) + } else { + logAdapter.info( + "任务加签失败:流程实例ID【${task.instanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】" + ) + } + } } catch (e: Exception) { logAdapter.error(e.message, e) throw WebException(e.message) @@ -418,34 +433,44 @@ class WorkFlowService @Autowired constructor( } /** - * 委派任务 + * 减签 * * @param taskId 任务id */ @Transactional @Throws(WebException::class) - fun delegateTask(taskId: String, acceptUserId: String) { + fun reductionSignature(loginNo: String, taskId: Long, acceptUserId: String) { try { - commonOauthServer.userInfo()?.let { userInfo -> - identityService.setAuthenticatedUserId(userInfo.id) - val task = taskService.createTaskQuery().taskId(taskId).singleResult() - if (task == null) { - logAdapter.error("流程任务【$taskId】不存在!") - throw WebException("流程任务不存在!") + commonOauthServer.findUserByLoginNo(loginNo).let { userInfo -> + if (userInfo.id == null) { + throw WebException("获取当前登录用户信息失败!") } - taskService.setOwner(taskId, userInfo.id) - val processInstance = findRuntimeProcessInstance(task.processInstanceId) - workFlowListener.notifyPendingFinished(processInstance.businessKey, task, listOf(userInfo.id!!)) - taskService.delegateTask(taskId, acceptUserId) - workFlowListener.notifyPendingCreated(processInstance.businessKey, task, listOf(acceptUserId)) - logAdapter.info( - "任务委派成功:流程实例ID【${task.processInstanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】新办理人【${ - getUserById( - acceptUserId - ).loginNo - }】" - ) - } ?: throw WebException("获取当前登录用户信息失败!") + val task = getTask(taskId) + if (taskService.reductionSignature( + taskId, + FlowParams().handler(userInfo.id) + .permissionFlag( + workFlowPermissionHandler.permissions(listOf(userInfo.id!!)).toMutableList() + ) + .reductionHandlers(listOf(acceptUserId)).message("任务减签") + ) + ) { + workFlowGlobalListener.notifyPendingFinished( + insService.getById(task.instanceId), task, listOf(acceptUserId) + ) + logAdapter.info( + "任务减签成功:流程实例ID【${task.instanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】删除办理人【${ + getUserById( + acceptUserId + ).loginNo + }】" + ) + } else { + logAdapter.info( + "任务减签失败:流程实例ID【${task.instanceId}】任务ID【$taskId】操作人【${userInfo.loginNo}】" + ) + } + } } catch (e: Exception) { logAdapter.error(e.message, e) throw WebException(e.message) @@ -459,174 +484,209 @@ class WorkFlowService @Autowired constructor( */ @Transactional @Throws(WebException::class) - fun processTask(processHandlingPo: ProcessHandlingPo, userId: String) { - try { - identityService.setAuthenticatedUserId(userId) - val task = taskService.createTaskQuery().taskId(processHandlingPo.taskId).singleResult() - if (task == null) { - logAdapter.error("流程任务【${processHandlingPo.taskId}】不存在!") - throw WebException("流程任务不存在!") - } - val params: MutableMap = mutableMapOf() - processHandlingPo.params.forEach { (key, value) -> - if (!params.containsKey(key)) { - params[key] = value - } + fun skip(processHandlingPo: ProcessHandlingPo, userId: String): Instance = try { + commonOauthServer.findUserById(userId).let { userInfo -> + if (userInfo.loginNo == null) { + throw WebException("获取当前登录用户信息失败!") } val comment = if (processHandlingPo.pass!!) { - if (CommonTools.isNullStr(processHandlingPo.comment)) { + if (CommonTools.isNullStr(processHandlingPo.message)) { "通过" } else { - processHandlingPo.comment!! + processHandlingPo.message!! } } else { - if (CommonTools.isNullStr(processHandlingPo.comment)) { + if (CommonTools.isNullStr(processHandlingPo.message)) { "不通过" } else { - processHandlingPo.comment!! + processHandlingPo.message!! } } - params[WorkFlowParamKey.comment] = if (task.delegationState == DelegationState.PENDING) { - (getUserById(userId).name ?: "") + ":" + comment - } else { - comment - } - params[WorkFlowParamKey.pass] = processHandlingPo.pass!! - runtimeService.setVariablesLocal(task.executionId, processHandlingPo.localParams) - val processInstance = findRuntimeProcessInstance(task.processInstanceId) - if (task.delegationState == DelegationState.PENDING) { - workFlowListener.notifyPendingFinished(processInstance.businessKey, task, listOf(userId)) - taskService.resolveTask(task.id, params) - workFlowListener.notifyPendingCreated(processInstance.businessKey, task, listOf(task.owner)) - } else { - workFlowListener.notifyPendingFinished(processInstance.businessKey, task, listOf(userId)) - taskService.setAssignee(task.id, userId) - taskService.complete(task.id, params) - } - logAdapter.info( - "任务处理完成:流程实例ID【${task.processInstanceId}】任务ID【${processHandlingPo.taskId}】操作人【${ - getUserById( - userId - ).loginNo - }】意见【$comment】" - ) - // 添加至我处理过的流程实例 - myProcessInstanceRepository.findByUserIdAndProcessInstanceId(userId, task.processInstanceId).let { - if (!it.isPresent) { - val processInstanceVo = findProcessInstance(task.processInstanceId) - myProcessInstanceRepository.save( - MyProcessInstance( - processInstanceId = processInstanceVo.processInstanceId!!, - processDefinitionKey = processInstanceVo.processDefinitionKey!!, - businessKey = processInstanceVo.businessKey!!, - startUserId = processInstanceVo.startUser?.id, - userId = userId, - startTime = processInstanceVo.startTime + val task = getTask(processHandlingPo.taskId!!) + taskService.skip( + FlowParams().handler(userInfo.id) + .permissionFlag(workFlowPermissionHandler.permissions(listOf(userInfo.id!!)).toMutableList()) + .skipType(if (processHandlingPo.pass!!) SkipType.PASS.key else SkipType.REJECT.key) + .variable(processHandlingPo.params).message(comment), task + ).also { instance -> + logAdapter.info( + "任务处理完成:流程实例ID【${task.instanceId}】任务ID【${processHandlingPo.taskId}】操作人【${ + getUserById( + userId + ).loginNo + }】意见【$comment】" + ) + // 添加至我处理过的流程实例 + myProcessInstanceRepository.findByUserIdAndProcessInstanceId(userId, instance.id).let { + if (it.isEmpty) { + val processInstanceVo = findProcessInstance(instance.id) + myProcessInstanceRepository.save( + MyProcessInstance( + processInstanceId = instance.id, + processDefinitionKey = processInstanceVo.processDefinitionKey!!, + businessKey = instance.businessId, + startUserId = processInstanceVo.startUser?.id, + userId = userId, + startTime = processInstanceVo.startTime + ) ) - ) + } } } - } catch (e: Exception) { - logAdapter.error(e.message, e) - throw WebException(e.message) - } + } ?: throw WebException("获取当前登录用户信息失败!") + } catch (e: Exception) { + logAdapter.error(e.message, e) + throw WebException(e.message) } - @Transactional + @Throws(WebException::class) - fun deleteProcessInstance(processTerminationPo: ProcessTerminationPo, userId: String? = null) { - val processInstance = findRuntimeProcessInstance(processTerminationPo.processInstanceId!!) - taskService.createTaskQuery().processInstanceId(processTerminationPo.processInstanceId).list() - .let { taskList -> - taskList.forEach { task -> - workFlowListener.notifyPendingFinished(processInstance.businessKey, task, getPendingUserId(task)) - } - runtimeService.deleteProcessInstance( - processTerminationPo.processInstanceId, processTerminationPo.reason - ) - logAdapter.info( - "流程删除成功:流程实例ID【${processTerminationPo.processInstanceId}】操作人【${ - getUserById( - userId - ).loginNo - }】" - ) + fun findProcessInstance(processInstanceId: Long): ProcessInstanceVo = try { + insService.getById(processInstanceId)?.let { instanceToVo(it) } ?: throw WebException("流程实例不存在!") + } catch (e: Exception) { + logAdapter.error(e.message, e) + throw WebException(e.message) + } + + /** + * 查询流程实例 + */ + @Throws(WebException::class) + fun findProcessInstance(processQueryPo: ProcessQueryPo): CustomerQueryPageVo = try { + insService.orderByCreateTime().desc().page(FlowEngine.newIns().apply { + if (processQueryPo.processInstanceId != null) { + this.id = processQueryPo.processInstanceId + } + if (!CommonTools.isNullStr(processQueryPo.processBusinessKey)) { + this.businessId = processQueryPo.processBusinessKey } + if (!CommonTools.isNullStr(processQueryPo.flowStatus)) { + this.flowStatus = processQueryPo.flowStatus + } + if (!CommonTools.isNullStr(processQueryPo.startUserId)) { + this.createBy = processQueryPo.startUserId + } + }, Page().apply { + this.pageNum = processQueryPo.queryParam!!.currPage!! + this.pageSize = processQueryPo.queryParam!!.pageSize!! + }).let { result -> + CustomerQueryPageVo( + content = result.list.map { instanceToVo(it) }, + totalElements = result.total, + currPage = result.pageNum, + pageSize = result.pageSize + ) + } + } catch (e: Exception) { + logAdapter.error(e.message, e) + throw WebException(e.message) } + /** + * 获取任务信息 + * + * @param taskId 任务ID + * @return 任务信息 + */ @Throws(WebException::class) - fun findProcessDefinition(processInstanceId: String): ProcessDefinitionVo = try { - historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId) - .singleResult()?.let { instance -> - repositoryService.getBpmnModelInstance(instance.processDefinitionId)?.let { modelInstance -> - ProcessDefinitionVo( - id = instance.processDefinitionId, - name = instance.processDefinitionName, - content = Bpmn.convertToString(modelInstance) - ) + fun findTaskById(loginNo: String, taskId: Long): ProcessTaskVo = try { + commonOauthServer.findUserByLoginNo(loginNo).let { userInfo -> + if (userInfo.id == null) { + throw WebException("获取当前登录用户信息失败!") + } + getTask(taskId).let { task -> + if (getPendingUser(task).map { it.id }.contains(userInfo.id)) { + taskToVo(task) + } else { + throw WebException("找不到任务信息") } - } ?: throw WebException("流程实例不存在!") + } + } } catch (e: Exception) { logAdapter.error(e.message, e) throw WebException(e.message) } + /** + * 获取任务信息(开放的) + * + * @param taskId 任务ID + * @return 任务信息 + */ @Throws(WebException::class) - fun findProcessInstance(processInstanceId: String): ProcessInstanceVo = try { - historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId) - .singleResult()?.let { instance -> - instanceToVo(instance) - } ?: throw WebException("流程实例不存在!") + fun findTaskByIdOpen(taskId: Long): ProcessTaskVo = try { + taskToVo(getTask(taskId)) } catch (e: Exception) { logAdapter.error(e.message, e) throw WebException(e.message) } /** - * 查询流程实例 + * 获取待办任务 + * @param processInstanceId 流程实例ID + * @param userId 用户ID */ @Throws(WebException::class) - fun findProcessInstance(processQueryPo: ProcessQueryPo): CustomerQueryPageVo = try { - val firstResult = (processQueryPo.queryParam!!.currPage!! - 1) * processQueryPo.queryParam!!.pageSize!! - val maxResult = processQueryPo.queryParam!!.pageSize!! - val processInstanceQuery = historyService.createHistoricProcessInstanceQuery() - if (processQueryPo.processDefinitionKeys != null && processQueryPo.processDefinitionKeys!!.isNotEmpty()) { - processInstanceQuery.processDefinitionKeyIn(*processQueryPo.processDefinitionKeys!!.toTypedArray()) - } - if (processQueryPo.processInstanceIds != null && processQueryPo.processInstanceIds!!.isNotEmpty()) { - processInstanceQuery.processInstanceIds(processQueryPo.processInstanceIds!!.toSet()) - } - if (!CommonTools.isNullStr(processQueryPo.processBusinessKey)) { - processInstanceQuery.processInstanceBusinessKeyLike(processQueryPo.processBusinessKey) - } - if (!CommonTools.isNullStr(processQueryPo.startUserId)) { - processInstanceQuery.startedBy(processQueryPo.startUserId) - } - if (processQueryPo.startTime != null) { - processInstanceQuery.startedAfter(DateTime(processQueryPo.startTime!!).toDate()) - } - if (processQueryPo.endTime != null) { - processInstanceQuery.startedBefore(DateTime(processQueryPo.endTime!!).toDate()) - } - if (processQueryPo.finished != null && processQueryPo.finished!!) { - processInstanceQuery.finished() + fun findTaskList(processInstanceId: Long, userId: String? = null): List = try { + val permissions = if (!CommonTools.isNullStr(userId)) { + workFlowPermissionHandler.permissions(listOf(userId!!)) } else { - processInstanceQuery.unfinished() + listOf() } - val total = processInstanceQuery.list().count() - val list = processInstanceQuery.orderByProcessInstanceStartTime().desc().listPage(firstResult, maxResult) - .map { instance -> instanceToVo(instance) } - CustomerQueryPageVo( - currPage = processQueryPo.queryParam!!.currPage!!, - pageSize = processQueryPo.queryParam!!.pageSize!!, - totalElements = total.toLong(), - content = list - ) + QueryChain.of(flowTaskMapper).select(*(TableInfoFactory.ofEntityClass(FlowTask::class.java).allColumns)) + .from(FlowTask::class.java).where(FlowTask::getInstanceId).eq(processInstanceId).and(FlowTask::getId).`in`( + QueryChain.of(FlowUser::class.java).select(FlowUser::getAssociated).from(FlowUser::class.java) + .where(FlowUser::getProcessedBy).`in`(permissions), permissions.isNotEmpty() + ).orderBy(FlowTask::getCreateTime).asc().orderBy(FlowTask::getId).asc().list().map { + taskToVo(it) + } } catch (e: Exception) { logAdapter.error(e.message, e) throw WebException(e.message) } + /** + * 获取待办任务 + * + * @return 任务列表 + */ + @Throws(WebException::class) + fun findTaskList(loginNo: String, processTaskQueryPo: ProcessTaskQueryPo): CustomerQueryPageVo = + try { + commonOauthServer.findUserByLoginNo(loginNo).let { userInfo -> + if (userInfo.id == null) { + throw WebException("获取当前登录用户信息失败!") + } + val permissions = workFlowPermissionHandler.permissions(listOf(userInfo.id!!)) + QueryChain.of(flowTaskMapper) + .select(*(TableInfoFactory.ofEntityClass(FlowTask::class.java).allColumns.map { "t.$it" } + .toTypedArray())).from(FlowTask::class.java).`as`("t").leftJoin(FlowDefinition::class.java) + .`as`("d").on(FlowTask::getDefinitionId, FlowDefinition::getId).where(FlowTask::getInstanceId) + .eq(processTaskQueryPo.processInstanceId, processTaskQueryPo.processInstanceId != null) + .and(FlowDefinition::getFlowCode).eq( + processTaskQueryPo.processBusinessKey, + !CommonTools.isNullStr(processTaskQueryPo.processBusinessKey) + ).and(FlowTask::getId).`in`( + QueryChain.of(FlowUser::class.java).select(FlowUser::getAssociated).from(FlowUser::class.java) + .where(FlowUser::getProcessedBy).`in`(permissions), permissions.isNotEmpty() + ).orderBy(FlowTask::getCreateTime).asc().orderBy(FlowTask::getId).asc().let { queryChain -> + doPageQuery( + processTaskQueryPo.queryParam!!.apply { this.orderName = null }, queryChain, true + ) + }.let { result -> + CustomerQueryPageVo( + content = result.content.map { taskToVo(it) }, + totalElements = result.totalElements, + currPage = result.currPage, + pageSize = result.pageSize + ) + } + } + } catch (e: Exception) { + logAdapter.error(e.message, e) + throw WebException(e.message) + } + /** * 查询指定流程的历史信息 * @@ -634,32 +694,26 @@ class WorkFlowService @Autowired constructor( * @return 流程历史信息 */ @Throws(WebException::class) - fun findHistoryActivity(processInstanceId: String): List = try { - val historicProcessInstance = - historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult() - if (historicProcessInstance == null) { - logAdapter.error("流程实例【$processInstanceId】不存在") - throw WebException("流程实例不存在!") - } - historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId) - .orderByHistoricActivityInstanceStartTime().asc().list() - .filter { historicActivityInstance -> !CommonTools.isNullStr(historicActivityInstance.taskId) } - .map { historicActivityInstance -> - actToVo( - historicActivityInstance, historicProcessInstance.businessKey - ) - }.filter { processHistoryActivityVo -> !CommonTools.isNullStr(processHistoryActivityVo.comment) } + fun findHistoryTask(processInstanceId: Long): List = try { + hisTaskService.orderByUpdateTime().list(FlowEngine.newHisTask().apply { + this.instanceId = processInstanceId + }).map { hisTaskToVo(it) } } catch (e: Exception) { logAdapter.error(e.message, e) throw WebException(e.message) } /** - * 查询当前用户处理过的流程实例 + * 查询用户已办的流程实例 */ @Throws(WebException::class) - fun findProcessInstanceForMyProcess(processQueryPo: ProcessQueryPo): CustomerQueryPageVo = try { - commonOauthServer.userInfo()?.let { userInfo -> + fun findProcessInstanceForMyProcess( + loginNo: String, myProcessQueryPo: MyProcessQueryPo + ): CustomerQueryPageVo = try { + commonOauthServer.findUserByLoginNo(loginNo).let { userInfo -> + if (userInfo.id == null) { + throw WebException("获取当前登录用户信息失败!") + } myProcessInstanceRepository.findAll({ root, _, criteriaBuilder -> val predicateList: MutableList = mutableListOf() predicateList.add( @@ -667,91 +721,74 @@ class WorkFlowService @Autowired constructor( root.get("userId").`as`(String::class.java), userInfo.id ) ) - if (processQueryPo.processDefinitionKeys != null && processQueryPo.processDefinitionKeys!!.isNotEmpty()) { + if (myProcessQueryPo.processDefinitionKeys != null && myProcessQueryPo.processDefinitionKeys!!.isNotEmpty()) { predicateList.add( root.get("processDefinitionKey").`as`(String::class.java) - .`in`(processQueryPo.processDefinitionKeys) + .`in`(myProcessQueryPo.processDefinitionKeys) ) } - if (!CommonTools.isNullStr(processQueryPo.processBusinessKey)) { + if (myProcessQueryPo.processInstanceIds != null && myProcessQueryPo.processInstanceIds!!.isNotEmpty()) { + predicateList.add( + root.get("processInstanceId").`as`(String::class.java) + .`in`(myProcessQueryPo.processInstanceIds) + ) + } + if (!CommonTools.isNullStr(myProcessQueryPo.processBusinessKey)) { predicateList.add( criteriaBuilder.equal( - root.get("businessKey").`as`(String::class.java), processQueryPo.processBusinessKey + root.get("businessKey").`as`(String::class.java), myProcessQueryPo.processBusinessKey ) ) } - if (!CommonTools.isNullStr(processQueryPo.startUserId)) { + if (!CommonTools.isNullStr(myProcessQueryPo.startUserId)) { predicateList.add( criteriaBuilder.equal( - root.get("startUserId").`as`(String::class.java), processQueryPo.startUserId + root.get("startUserId").`as`(String::class.java), myProcessQueryPo.startUserId ) ) } - if (processQueryPo.startTime != null) { + if (myProcessQueryPo.startTime != null) { predicateList.add( criteriaBuilder.ge( - root.get("startTime").`as`(Long::class.java), processQueryPo.startTime + root.get("startTime").`as`(Long::class.java), myProcessQueryPo.startTime ) ) } - if (processQueryPo.endTime != null) { + if (myProcessQueryPo.endTime != null) { predicateList.add( criteriaBuilder.le( - root.get("startTime").`as`(Long::class.java), processQueryPo.endTime + root.get("startTime").`as`(Long::class.java), myProcessQueryPo.endTime ) ) } criteriaBuilder.and(*predicateList.toTypedArray()) - }, buildPageRequest(processQueryPo.queryParam!!)).let { + }, buildPageRequest(myProcessQueryPo.queryParam!!)).let { CustomerQueryPageVo( - currPage = processQueryPo.queryParam!!.currPage!!, - pageSize = processQueryPo.queryParam!!.pageSize!!, + currPage = myProcessQueryPo.queryParam!!.currPage!!, + pageSize = myProcessQueryPo.queryParam!!.pageSize!!, totalElements = it.totalElements, content = it.content.map { instance -> findProcessInstance(instance.processInstanceId) }) } - } ?: throw WebException("获取当前登录用户信息失败!") + } } catch (e: Exception) { logAdapter.error(e.message, e) throw WebException(e.message) } @Throws(WebException::class) - fun findHighlightElement(processInstanceId: String): ProcessHighlightElementVo = try { - historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult() - ?.let { historicProcessInstance -> - val highlightNodeList = historyService.createHistoricActivityInstanceQuery() - .processInstanceId(processInstanceId) - .orderByHistoricActivityInstanceStartTime().asc() - .list().map { historicActivityInstance -> - ProcessHighlightNodeVo( - id = historicActivityInstance.activityId, - type = historicActivityInstance.activityType, - name = historicActivityInstance.activityName, - startTime = historicActivityInstance.startTime?.time, - endTime = historicActivityInstance.endTime?.time, - complete = historicActivityInstance.endTime != null - ) - }.toMutableList() - val highlightNodeIdList = highlightNodeList.map { it.id } - ProcessHighlightElementVo( - highlightNodeList = highlightNodeList, - highlightLineList = repositoryService.getBpmnModelInstance(historicProcessInstance.processDefinitionId) - .getModelElementsByType(SequenceFlow::class.java).filter { sequenceFlow -> - highlightNodeIdList.contains(sequenceFlow.source?.id) && - highlightNodeIdList.contains(sequenceFlow.target?.id) - }.map { sequenceFlow -> - ProcessHighlightLineVo( - id = sequenceFlow.id, - sourceId = sequenceFlow.source?.id, - targetId = sequenceFlow.target?.id - ) - }.toMutableList() - ) - } ?: throw WebException("获取流程实例失败!") - } catch (e: Exception) { - logAdapter.error(e.message, e) - throw WebException(e.message) + fun chartFlow(processInstanceId: Long): String = chartService.chartIns(processInstanceId) { flowChartChain -> + flowChartChain.flowChartList.forEach { flowChart -> + if (flowChart is BetweenChart) { + // 给节点顶部增加文字说明 + // flowChart.topText("办理时间: 2025-02-08 12:12:12", Color.red); + flowChart.nodeJson.extMap.forEach { (key, value) -> + // 给节点中追加文字 + flowChart.addText("$key: ", Color.blue) + flowChart.addText("$value", Color.blue) + } + } + } } } diff --git a/modules/workflow-server/src/main/resources/application.yaml b/modules/workflow-server/src/main/resources/application.yaml index d05884fd..3673df41 100644 --- a/modules/workflow-server/src/main/resources/application.yaml +++ b/modules/workflow-server/src/main/resources/application.yaml @@ -58,4 +58,5 @@ acp: log-type: WORKFLOW resource-server: permit-all-path: - - /workflow/definition/file/** + - /warm-flow-ui/** + - /workflow/definition/export/** diff --git a/modules/workflow-server/src/main/resources/init-sql/mysql/warm-flow-all.sql b/modules/workflow-server/src/main/resources/init-sql/mysql/warm-flow-all.sql new file mode 100644 index 00000000..7dead0aa --- /dev/null +++ b/modules/workflow-server/src/main/resources/init-sql/mysql/warm-flow-all.sql @@ -0,0 +1,149 @@ +CREATE TABLE IF NOT EXISTS `flow_definition` +( + `id` bigint NOT NULL COMMENT '主键id', + `flow_code` varchar(40) NOT NULL COMMENT '流程编码', + `flow_name` varchar(100) NOT NULL COMMENT '流程名称', + `category` varchar(100) DEFAULT NULL COMMENT '流程类别', + `version` varchar(20) NOT NULL COMMENT '流程版本', + `is_publish` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否发布(0未发布 1已发布 9失效)', + `form_custom` char(1) DEFAULT 'N' COMMENT '审批表单是否自定义(Y是 N否)', + `form_path` varchar(100) DEFAULT NULL COMMENT '审批表单路径', + `activity_status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '流程激活状态(0挂起 1激活)', + `listener_type` varchar(100) DEFAULT NULL COMMENT '监听器类型', + `listener_path` varchar(400) DEFAULT NULL COMMENT '监听器路径', + `ext` varchar(500) DEFAULT NULL COMMENT '业务详情 存业务表对象json字符串', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', + `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB COMMENT ='流程定义表'; + +CREATE TABLE IF NOT EXISTS `flow_node` +( + `id` bigint NOT NULL COMMENT '主键id', + `node_type` tinyint(1) NOT NULL COMMENT '节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)', + `definition_id` bigint NOT NULL COMMENT '流程定义id', + `node_code` varchar(100) NOT NULL COMMENT '流程节点编码', + `node_name` varchar(100) DEFAULT NULL COMMENT '流程节点名称', + `permission_flag` varchar(200) DEFAULT NULL COMMENT '权限标识(权限类型:权限标识,可以多个,用逗号隔开)', + `node_ratio` decimal(6, 3) DEFAULT NULL COMMENT '流程签署比例值', + `coordinate` varchar(100) DEFAULT NULL COMMENT '坐标', + `any_node_skip` varchar(100) DEFAULT NULL COMMENT '任意结点跳转', + `listener_type` varchar(100) DEFAULT NULL COMMENT '监听器类型', + `listener_path` varchar(400) DEFAULT NULL COMMENT '监听器路径', + `handler_type` varchar(100) DEFAULT NULL COMMENT '处理器类型', + `handler_path` varchar(400) DEFAULT NULL COMMENT '处理器路径', + `form_custom` char(1) DEFAULT 'N' COMMENT '审批表单是否自定义(Y是 N否)', + `form_path` varchar(100) DEFAULT NULL COMMENT '审批表单路径', + `version` varchar(20) NOT NULL COMMENT '版本', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `ext` text COMMENT '扩展属性', + `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', + `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB COMMENT ='流程节点表'; + +CREATE TABLE IF NOT EXISTS `flow_skip` +( + `id` bigint NOT NULL COMMENT '主键id', + `definition_id` bigint NOT NULL COMMENT '流程定义id', + `now_node_code` varchar(100) NOT NULL COMMENT '当前流程节点的编码', + `now_node_type` tinyint(1) DEFAULT NULL COMMENT '当前节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)', + `next_node_code` varchar(100) NOT NULL COMMENT '下一个流程节点的编码', + `next_node_type` tinyint(1) DEFAULT NULL COMMENT '下一个节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)', + `skip_name` varchar(100) DEFAULT NULL COMMENT '跳转名称', + `skip_type` varchar(40) DEFAULT NULL COMMENT '跳转类型(PASS审批通过 REJECT退回)', + `skip_condition` varchar(200) DEFAULT NULL COMMENT '跳转条件', + `coordinate` varchar(100) DEFAULT NULL COMMENT '坐标', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', + `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB COMMENT ='节点跳转关联表'; + +CREATE TABLE IF NOT EXISTS `flow_instance` +( + `id` bigint NOT NULL COMMENT '主键id', + `definition_id` bigint NOT NULL COMMENT '对应flow_definition表的id', + `business_id` varchar(40) NOT NULL COMMENT '业务id', + `node_type` tinyint(1) NOT NULL COMMENT '节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)', + `node_code` varchar(40) NOT NULL COMMENT '流程节点编码', + `node_name` varchar(100) DEFAULT NULL COMMENT '流程节点名称', + `variable` text COMMENT '任务变量', + `flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)', + `activity_status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '流程激活状态(0挂起 1激活)', + `def_json` text COMMENT '流程定义json', + `create_by` varchar(64) DEFAULT '' COMMENT '创建者', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `ext` varchar(500) DEFAULT NULL COMMENT '扩展字段,预留给业务系统使用', + `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', + `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB COMMENT ='流程实例表'; + +CREATE TABLE IF NOT EXISTS `flow_task` +( + `id` bigint NOT NULL COMMENT '主键id', + `definition_id` bigint NOT NULL COMMENT '对应flow_definition表的id', + `instance_id` bigint NOT NULL COMMENT '对应flow_instance表的id', + `node_code` varchar(100) NOT NULL COMMENT '节点编码', + `node_name` varchar(100) DEFAULT NULL COMMENT '节点名称', + `node_type` tinyint(1) NOT NULL COMMENT '节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)', + `flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)', + `form_custom` char(1) DEFAULT 'N' COMMENT '审批表单是否自定义(Y是 N否)', + `form_path` varchar(100) DEFAULT NULL COMMENT '审批表单路径', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', + `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB COMMENT ='待办任务表'; + +CREATE TABLE IF NOT EXISTS `flow_his_task` +( + `id` bigint(20) NOT NULL COMMENT '主键id', + `definition_id` bigint(20) NOT NULL COMMENT '对应flow_definition表的id', + `instance_id` bigint(20) NOT NULL COMMENT '对应flow_instance表的id', + `task_id` bigint(20) NOT NULL COMMENT '对应flow_task表的id', + `node_code` varchar(100) DEFAULT NULL COMMENT '开始节点编码', + `node_name` varchar(100) DEFAULT NULL COMMENT '开始节点名称', + `node_type` tinyint(1) DEFAULT NULL COMMENT '开始节点类型(0开始节点 1中间节点 2结束节点 3互斥网关 4并行网关)', + `target_node_code` varchar(200) DEFAULT NULL COMMENT '目标节点编码', + `target_node_name` varchar(200) DEFAULT NULL COMMENT '结束节点名称', + `approver` varchar(40) DEFAULT NULL COMMENT '审批者', + `cooperate_type` tinyint(1) NOT NULL DEFAULT '0' COMMENT '协作方式(1审批 2转办 3委派 4会签 5票签 6加签 7减签)', + `collaborator` varchar(40) DEFAULT NULL COMMENT '协作人', + `skip_type` varchar(10) NOT NULL COMMENT '流转类型(PASS通过 REJECT退回 NONE无动作)', + `flow_status` varchar(20) NOT NULL COMMENT '流程状态(0待提交 1审批中 2审批通过 4终止 5作废 6撤销 8已完成 9已退回 10失效 11拿回)', + `form_custom` char(1) DEFAULT 'N' COMMENT '审批表单是否自定义(Y是 N否)', + `form_path` varchar(100) DEFAULT NULL COMMENT '审批表单路径', + `message` varchar(500) DEFAULT NULL COMMENT '审批意见', + `variable` TEXT DEFAULT NULL COMMENT '任务变量', + `ext` varchar(500) DEFAULT NULL COMMENT '业务详情 存业务表对象json字符串', + `create_time` datetime DEFAULT NULL COMMENT '任务开始时间', + `update_time` datetime DEFAULT NULL COMMENT '审批完成时间', + `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', + `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', + PRIMARY KEY (`id`) USING BTREE +) ENGINE = InnoDB COMMENT ='历史任务记录表'; + +CREATE TABLE IF NOT EXISTS `flow_user` +( + `id` bigint NOT NULL COMMENT '主键id', + `type` char(1) NOT NULL COMMENT '人员类型(1待办任务的审批人权限 2待办任务的转办人权限 3待办任务的委托人权限)', + `processed_by` varchar(80) DEFAULT NULL COMMENT '权限人', + `associated` bigint NOT NULL COMMENT '任务表id', + `create_time` datetime DEFAULT NULL COMMENT '创建时间', + `create_by` varchar(80) DEFAULT NULL COMMENT '创建人', + `update_time` datetime DEFAULT NULL COMMENT '更新时间', + `del_flag` char(1) DEFAULT '0' COMMENT '删除标志', + `tenant_id` varchar(40) DEFAULT NULL COMMENT '租户id', + PRIMARY KEY (`id`) USING BTREE, + KEY `user_processed_type` (`processed_by`, `type`), + KEY `user_associated` (`associated`) USING BTREE +) ENGINE = InnoDB COMMENT ='流程用户表'; + -- Gitee From 0e302a9d065f9047845de44fc15f07a817c73080 Mon Sep 17 00:00:00 2001 From: zhangbinhub Date: Thu, 15 May 2025 18:10:21 +0800 Subject: [PATCH 2/3] =?UTF-8?q?[Upgrade]=20=E6=96=B0=E5=A2=9E=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=E8=B7=AF=E7=94=B1=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/version_history.md | 2 ++ .../admin/route/init/DataInitialization.kt | 7 ++++- .../admin/route/service/InitDataService.kt | 31 +++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/doc/version_history.md b/doc/version_history.md index 3b9e41fb..69a1f258 100644 --- a/doc/version_history.md +++ b/doc/version_history.md @@ -9,6 +9,8 @@ - [Upgrade] 工作流切换至warmFlow,依赖`acp-spring-boot-warm-flow-mybatis-flex` - gateway-server - [Upgrade] 调整路由日志过滤器 +- route-server + - [Upgrade] 新增初始化路由数据 ##### v6.7.3 diff --git a/modules/route-server/src/main/kotlin/io/gitee/zhangbinhub/admin/route/init/DataInitialization.kt b/modules/route-server/src/main/kotlin/io/gitee/zhangbinhub/admin/route/init/DataInitialization.kt index 0f7134ec..639fea1b 100644 --- a/modules/route-server/src/main/kotlin/io/gitee/zhangbinhub/admin/route/init/DataInitialization.kt +++ b/modules/route-server/src/main/kotlin/io/gitee/zhangbinhub/admin/route/init/DataInitialization.kt @@ -19,7 +19,12 @@ class DataInitialization( get() = 1 override fun doInit() { - routeService.getRouteListByRouteIdList(listOf(InitDataService.WORK_FLOW_SERVER_API_ROUTE_ID)).let { routeList -> + val innerRouteIdList = listOf( + InitDataService.WORK_FLOW_SERVER_API_ROUTE_ID, + InitDataService.WORK_FLOW_UI_ROUTE_ID, + InitDataService.WORK_FLOW_UI_SERVER_ROUTE_ID + ) + routeService.getRouteListByRouteIdList(innerRouteIdList).let { routeList -> if (routeList.isEmpty()) { logAdapter.info(">>>>>>>>>>>>>>>>>>>> begin init route data...") initDataService.doInitRoute() diff --git a/modules/route-server/src/main/kotlin/io/gitee/zhangbinhub/admin/route/service/InitDataService.kt b/modules/route-server/src/main/kotlin/io/gitee/zhangbinhub/admin/route/service/InitDataService.kt index 9f65b845..c5173cac 100644 --- a/modules/route-server/src/main/kotlin/io/gitee/zhangbinhub/admin/route/service/InitDataService.kt +++ b/modules/route-server/src/main/kotlin/io/gitee/zhangbinhub/admin/route/service/InitDataService.kt @@ -15,6 +15,8 @@ class InitDataService @Autowired constructor( ) { companion object { const val WORK_FLOW_SERVER_API_ROUTE_ID = "workflow-server-api" + const val WORK_FLOW_UI_ROUTE_ID = "workflow-ui" + const val WORK_FLOW_UI_SERVER_ROUTE_ID = "workflow-ui-server" } @Transactional @@ -27,10 +29,39 @@ class InitDataService @Autowired constructor( uri = "lb://workflow-server", predicates = "[\"Path=/api/workflow/**\"]", filters = "[\"StripPrefix=1\"]", + metadata = "{}", remarks = "工作流服务接口" ) ).also { route -> logAdapter.info("Init Route ${route.remarks}[${route.routeId}]") } + routeRepository.save( + Route( + routeId = WORK_FLOW_UI_ROUTE_ID, + enabled = true, + orderNum = 0, + uri = "lb://workflow-server", + predicates = "[\"Path=/api/warm-flow-ui/**\"]", + filters = "[\"StripPrefix=1\"]", + metadata = "{}", + remarks = "工作流设计器" + ) + ).also { route -> + logAdapter.info("Init Route ${route.remarks}[${route.routeId}]") + } + routeRepository.save( + Route( + routeId = WORK_FLOW_UI_SERVER_ROUTE_ID, + enabled = true, + orderNum = 0, + uri = "lb://workflow-server", + predicates = "[\"Path=/api/warm-flow/**\"]", + filters = "[\"StripPrefix=1\"]", + metadata = "{}", + remarks = "工作流设计器服务" + ) + ).also { route -> + logAdapter.info("Init Route ${route.remarks}[${route.routeId}]") + } } } \ No newline at end of file -- Gitee From 1b7a52ca8d3e48d008e1b14ad17937db4731ae12 Mon Sep 17 00:00:00 2001 From: zhangbinhub Date: Thu, 15 May 2025 18:13:35 +0800 Subject: [PATCH 3/3] =?UTF-8?q?[Upgrade]=20=E6=9B=B4=E6=96=B0=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- doc/nacos_config_export_dev.zip | Bin 4518 -> 4552 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/doc/nacos_config_export_dev.zip b/doc/nacos_config_export_dev.zip index 0579f609990aedbbb80fd6d7144dc7abb339a032..fb0a2ff1a75a47bd7d692969613aabf8d0f50988 100644 GIT binary patch delta 1046 zcmZ3cd_tKgz?+#xgn@&DgQ0ukL>{gBpxA6-N0Hk1>m>v}DZEKb{@C0auxRCv01lOx z{4?h6y*an6Jk8oT`mSB5hS-%Phvbk~%>uf=5?*JQ z`}~Y$`8pq#)W+Q{7eqt$|1p-hl2anR;&N2}{m8%m)A~iH*@&{7suu8aeX@x6zH;82 zll5y)tPRV)o_DLy&a}Mp=FY&QDjPS*2XAw7(lH2B2$OucuPn+x^!%>SgDW59D$Frd zShdcDYpUF`z-(z3=?(Xj0>j=v^l)-*x^PslH?iG#g}KVnt9~7k0!dMxswGz0Y?*5^ zEe;#*@F-aKY$=O(<$Uh@u3Sqre>P?LcDw9Km9(gTxY5=>c{1Z9w) zQ75IV=D?EvjDMl2+?}O@caEhL+rCWN`BI79@~YG>D|_ww1mC#^yWN*QQu-||^6`LC z;Mr)g!{2|VMC`dUf8IQi_T4{UWLQ;NOYb@7F5i7{W80A*jiOSzr;pD(dg;dHl#j}ZR+;t=RIR@e!1QM@_YYJ$KQXtcyG=BjBjcAjK6E<%;zszA^-cl zNwxM-pTMb+w_2xi_&IoqUzItonJ%I;&9*7GqsRKx+XgL$>g9L1bow_Le0}rt+s#y_ zC(YB@_A>-{vvb5;wb;SS#K54=%mCyg(#vK`CKE=c?unc8nX_3z^c{{QFyDbo8BC{g zGcf_hCp&P7ZLa6#1&K}W+fb5b5JS$xhl_+MjRnZa1uGuJTtwBTG$qZ>|@i*hC|JIo|= zO-uB>&;9KMCxRwt&s-^6;^|v$l6#5URaUt*jbC!Yo5?@V#CIRbwOR2YyGs9zkjM85 zmLRT8dwwpRf2Az^<^2~rKg;-x-tP!%Ts8guA8U}8b7lvgp3A_%FdOLY0B=Sn5e8T$ zSs#T6j>+Zx<{&?9;Fns8`lto{$1h!k5zqUmqNsx-$r+; z&&@1;x5DGsp7(l!MV(jl?8Kan-Dle+++u)@-;Nx7j26 z>;cP`7ebmXaa)uEUd@{@&)Y=n_NOKJCYs!5I-)Fu6YDD{E<0m(>T}N1V@z98Hk}F9 zHgnMDJ7<1i$%AihCuY64|BZPMXHK#0tA<-8oz8Q-rpClwIVB%)SjFev4=?VSe|WiE z=HFWJP5<-9-#KRI;@>Sh?*8*%nVF?WdVcrC*EydI=RE` z&GZz^UgCDC$|P(3vih4JoXa-NTpzD8W4%Vw`X~k@zzbyS<))S-rX-dm z>Q(0Eti52(cgTQ;;lkYDiq|516Qnm3uxpzw6*wOFXxpo|oC+#!T%ju#zkTvkImaX8 z1wWs`b7QXR0~2C9tR^{6Qj}$w=kNDKG3&k7^v-VOd41eoIal|+m|?rchdbwFZ$)Um z*~F=nc{`Jte>WX@cUIu~gN3iJ{fxf4rPn?9XOB#X%jNG+_V3P#Z?bTY{buL;JA040 zRrb#KMd!5N#a$1OdHZYre_#Nxb9|Vw<;en|%O`*Xgpo;v0hT$|Mv*%Fe(bfuc%x@_T-DP#8)G$S@{PHWkoQ0BN|s=}M^#Fb?hlu@s7i z3mlULIb|jr2=ah**$K)pnoK?=paHffAnr`