From 100898743c9f8cd97cf83d81c434463e9d9e82bb Mon Sep 17 00:00:00 2001 From: CMM <2198256324@qq.com> Date: Sun, 5 Feb 2023 20:02:32 +0800 Subject: [PATCH] =?UTF-8?q?=E5=BE=85=E5=8A=9E=E4=B8=AD=E5=BF=83=E5=BE=85?= =?UTF-8?q?=E6=88=91=E5=A4=84=E7=90=86=E5=A4=84=E7=90=86=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pmapi/pom.xml | 15 +- pmapi/src/main/java/com/ningdatech/pmapi/App.java | 1 + .../ningdatech/pmapi/common/config/BeanConfig.java | 46 +++ .../pmapi/common/config/GovDingProperties.java | 65 +++++ .../com/ningdatech/pmapi/common/util/CallBack.java | 25 ++ .../pmapi/common/util/SpringContextHolder.java | 150 ++++++++++ .../controller/TodoCenterController.java | 34 ++- .../pmapi/todocenter/manage/TodoCenterManage.java | 316 ++++++++++++++++----- .../model/dto/req/ReqToBeProcessedDTO.java | 4 +- .../dto/res/ResHandledProjectListExportDTO.java | 44 +++ .../model/dto/res/ResToBeProcessedDTO.java | 15 +- pmapi/src/main/resources/application-dev.yml | 17 +- 12 files changed, 648 insertions(+), 84 deletions(-) create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/common/config/BeanConfig.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/common/config/GovDingProperties.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/common/util/CallBack.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/common/util/SpringContextHolder.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResHandledProjectListExportDTO.java diff --git a/pmapi/pom.xml b/pmapi/pom.xml index f1761d7..39c8cc2 100644 --- a/pmapi/pom.xml +++ b/pmapi/pom.xml @@ -263,8 +263,6 @@ nd-zwdd-starter 1.0.0 -<<<<<<< HEAD - com.alibaba.xxpt @@ -274,8 +272,17 @@ ${basedir}/src/lib/zwdd-sdk-java-1.2.0.jar -======= ->>>>>>> 5a1444731ea4c918904ff265516fc5d31a7ebb36 + + org.apache.httpcomponents + httpclient + + + + joda-time + joda-time + 2.10.6 + + diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/App.java b/pmapi/src/main/java/com/ningdatech/pmapi/App.java index 39024fd..55f6281 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/App.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/App.java @@ -3,6 +3,7 @@ package com.ningdatech.pmapi; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableScheduling; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/common/config/BeanConfig.java b/pmapi/src/main/java/com/ningdatech/pmapi/common/config/BeanConfig.java new file mode 100644 index 0000000..93bfd09 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/common/config/BeanConfig.java @@ -0,0 +1,46 @@ +package com.ningdatech.pmapi.common.config; + +import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient; +import com.ningdatech.pmapi.common.util.SpringContextHolder; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.DependsOn; + +/** + * @author CMM + * @since 2023/02/03 09:24 + */ +@Configuration +@Slf4j +public class BeanConfig { + @Bean + public SpringContextHolder springContextHolder() { + return new SpringContextHolder(); + } + + @Bean("authExecutableClient") + @DependsOn(value = "govDingProperties") + public ExecutableClient executableAuthClientInit() { + ExecutableClient executableClient = ExecutableClient.getInstance(); + executableClient.setAccessKey(GovDingProperties.appAuthkey); + executableClient.setSecretKey(GovDingProperties.appAuthsecret); + executableClient.setDomainName(GovDingProperties.domain); + executableClient.setProtocal("https"); + executableClient.init(); + return executableClient; + } + + @Bean("executableClient") + @DependsOn(value = "govDingProperties") + public ExecutableClient executableClientInit() { + ExecutableClient executableClient = new ExecutableClient(); + executableClient.setAccessKey(GovDingProperties.appkey); + executableClient.setSecretKey(GovDingProperties.appsecret); + executableClient.setDomainName(GovDingProperties.domain); + executableClient.setProtocal("https"); + executableClient.init(); + return executableClient; + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/common/config/GovDingProperties.java b/pmapi/src/main/java/com/ningdatech/pmapi/common/config/GovDingProperties.java new file mode 100644 index 0000000..34ccd97 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/common/config/GovDingProperties.java @@ -0,0 +1,65 @@ +package com.ningdatech.pmapi.common.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import lombok.Data; + +/** + * @description: 浙政钉配置 + * @author: liushuai + * @date: 2022/5/5 15:10 + */ +@Data +@Component +public class GovDingProperties { + public static String appkey; + public static String appsecret; + public static String appAuthkey; + public static String appAuthsecret; + + public static String appSsoAuthkey; + public static String appSsoAuthsecret; + public static Long tenantId; + + public static String domain; + + @Value("${ding.app-key}") + public void setPrivateKey(String appkey) { + GovDingProperties.appkey = appkey; + } + + @Value("${ding.app-secret}") + public void setAppsecret(String appsecret) { + GovDingProperties.appsecret = appsecret; + } + + @Value("${ding.app-auth-key}") + public void setAppAuthKey(String appAuthkey) { + GovDingProperties.appAuthkey = appAuthkey; + } + + @Value("${ding.app-auth-secret}") + public void setAppAuthsecret(String appAuthsecret) { + GovDingProperties.appAuthsecret = appAuthsecret; + } + + @Value("${ding.app-sso-auth-key}") + public void setAppSsoAuthKey(String appSsoAuthkey) { + GovDingProperties.appSsoAuthkey = appSsoAuthkey; + } + + @Value("${ding.app-sso-auth-secret}") + public void setAppSsoAuthsecret(String appSsoAuthsecret) { + GovDingProperties.appSsoAuthsecret = appSsoAuthsecret; + } + + @Value("${ding.tenantId}") + public void setTenantId(Long tenantId) { + GovDingProperties.tenantId = tenantId; + } + @Value("${ding.domain}") + public void setDomain(String domain) { + GovDingProperties.domain = domain; + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/common/util/CallBack.java b/pmapi/src/main/java/com/ningdatech/pmapi/common/util/CallBack.java new file mode 100644 index 0000000..c82d6c0 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/common/util/CallBack.java @@ -0,0 +1,25 @@ +package com.ningdatech.pmapi.common.util; + +/** + * @author qinxianyun + * @see {@link SpringContextHolder} + * 针对某些初始化方法,在SpringContextHolder 初始化前时,
+ * 可提交一个 提交回调任务。
+ * 在SpringContextHolder 初始化后,进行回调使用 + */ + +public interface CallBack { + /** + * 回调执行方法 + */ + void executor(); + + /** + * 本回调任务名称 + * @return / + */ + default String getCallBackName() { + return Thread.currentThread().getId() + ":" + this.getClass().getName(); + } +} + diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/common/util/SpringContextHolder.java b/pmapi/src/main/java/com/ningdatech/pmapi/common/util/SpringContextHolder.java new file mode 100644 index 0000000..ebd0e3b --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/common/util/SpringContextHolder.java @@ -0,0 +1,150 @@ +package com.ningdatech.pmapi.common.util; + +import java.util.ArrayList; +import java.util.List; + + +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.env.Environment; +import org.springframework.lang.NonNull; + +import lombok.extern.slf4j.Slf4j; + +/** + * @author qinxianyun + */ +@Slf4j +public class SpringContextHolder implements ApplicationContextAware, DisposableBean { + + private static ApplicationContext applicationContext = null; + private static final List CALL_BACKS = new ArrayList<>(); + private static boolean addCallback = true; + + /** + * 针对 某些初始化方法,在SpringContextHolder 未初始化时 提交回调方法。 + * 在SpringContextHolder 初始化后,进行回调使用 + * + * @param callBack 回调函数 + */ + public synchronized static void addCallBacks(CallBack callBack) { + if (addCallback) { + SpringContextHolder.CALL_BACKS.add(callBack); + } else { + log.warn("CallBack:{} 已无法添加!立即执行", callBack.getCallBackName()); + callBack.executor(); + } + } + + /** + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + @SuppressWarnings("unchecked") + public static T getBean(String name) { + assertContextInjected(); + return (T) applicationContext.getBean(name); + } + + /** + * 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型. + */ + public static T getBean(Class requiredType) { + assertContextInjected(); + return applicationContext.getBean(requiredType); + } + + /** + * 获取SpringBoot 配置信息 + * + * @param property 属性key + * @param defaultValue 默认值 + * @param requiredType 返回类型 + * @return / + */ + public static T getProperties(String property, T defaultValue, Class requiredType) { + T result = defaultValue; + try { + result = getBean(Environment.class).getProperty(property, requiredType); + } catch (Exception ignored) { + } + return result; + } + + /** + * 获取SpringBoot 配置信息 + * + * @param property 属性key + * @return / + */ + public static String getProperties(String property) { + return getProperties(property, null, String.class); + } + + /** + * 获取SpringBoot 配置信息 + * + * @param property 属性key + * @param requiredType 返回类型 + * @return / + */ + public static T getProperties(String property, Class requiredType) { + return getProperties(property, null, requiredType); + } + + /** + * 检查ApplicationContext不为空. + */ + private static void assertContextInjected() { + if (applicationContext == null) { + throw new IllegalStateException("applicationContext属性未注入, 请在applicationContext" + + ".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder."); + } + } + + /** + * 清除SpringContextHolder中的ApplicationContext为Null. + */ + private static void clearHolder() { + log.debug("清除SpringContextHolder中的ApplicationContext:" + + applicationContext); + applicationContext = null; + } + + @Override + public void destroy() { + SpringContextHolder.clearHolder(); + } + + @Override + public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException { + if (SpringContextHolder.applicationContext != null) { + log.warn("SpringContextHolder中的ApplicationContext被覆盖, 原有ApplicationContext为:" + SpringContextHolder.applicationContext); + } + SpringContextHolder.applicationContext = applicationContext; + if (addCallback) { + for (CallBack callBack : SpringContextHolder.CALL_BACKS) { + callBack.executor(); + } + CALL_BACKS.clear(); + } + SpringContextHolder.addCallback = false; + } + + /** + * 获取当前启用的配置文件 + *
    + *
  • 生产环境:prod
  • + *
  • 开发环境:dev
  • + *
+ * + * @return java.lang.String + * @author WendyYang + **/ + public static String getActiveProfile() { + String[] strings = applicationContext.getEnvironment().getActiveProfiles(); + return strings[0]; + } + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java index 1b5863d..89136be 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java @@ -41,9 +41,9 @@ public class TodoCenterController { * @param param * @return */ - @GetMapping("/query-project-list") - public ApiResponse> queryProjectList(@Valid @ModelAttribute ReqToBeProcessedDTO param){ - PageVo result = todoCenterManage.queryProjectList(param); + @GetMapping("/query-todo-list") + public ApiResponse> queryPendingProjectList(@Valid @ModelAttribute ReqToBeProcessedDTO param){ + PageVo result = todoCenterManage.queryPendingProjectList(param); return ApiResponse.ofSuccess(result); } @@ -54,9 +54,9 @@ public class TodoCenterController { * @param response * @return void */ - @GetMapping("/export") - public void exportProjectList(ReqToBeProcessedDTO param, HttpServletResponse response){ - ExcelDownUtil.downXlsx(response,param,todoCenterManage::exportProjectList); + @GetMapping("/exportPending") + public void exportPendingProjectList(ReqToBeProcessedDTO param, HttpServletResponse response){ + ExcelDownUtil.downXlsx(response,param,todoCenterManage::exportPendingProjectList); } /** @@ -81,4 +81,26 @@ public class TodoCenterController { todoCenterManage.handler(param); return ApiResponse.ofSuccess(); } + + /** + * 待办中心-待我处理项目列表查询 + * @param param + * @return + */ + @GetMapping("/query-do-list") + public ApiResponse> queryHandledProjectList(@Valid @ModelAttribute ReqToBeProcessedDTO param){ + PageVo result = todoCenterManage.queryHandledProjectList(param); + return ApiResponse.ofSuccess(result); + } + /** + * 待办中心-我已处理项目列表导出 + * + * @param param + * @param response + * @return void + */ + @GetMapping("/exportHandled") + public void exportHandledProjectList(ReqToBeProcessedDTO param, HttpServletResponse response){ + ExcelDownUtil.downXlsx(response,param,todoCenterManage::exportHandledProjectList); + } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java index c7f4225..1d4cbc3 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java @@ -10,6 +10,7 @@ import com.alibaba.xxpt.gateway.shared.api.request.OapiMessageWorkNotificationRe import com.alibaba.xxpt.gateway.shared.api.response.OapiMessageWorkNotificationResponse; import com.alibaba.xxpt.gateway.shared.client.http.ExecutableClient; import com.alibaba.xxpt.gateway.shared.client.http.IntelligentGetClient; +import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.toolkit.Wrappers; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; @@ -30,6 +31,7 @@ import com.ningdatech.pmapi.todocenter.enums.ProcessStatusEnum; import com.ningdatech.pmapi.todocenter.extension.cmd.BackToHisApprovalNodeCmd; import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; import com.ningdatech.pmapi.todocenter.model.dto.req.ReqToBeProcessedDTO; +import com.ningdatech.pmapi.todocenter.model.dto.res.ResHandledProjectListExportDTO; import com.ningdatech.pmapi.todocenter.model.dto.res.ResToBeProcessedDTO; import com.ningdatech.pmapi.todocenter.model.dto.res.ResToBeProjectListExportDTO; import com.ningdatech.pmapi.todocenter.zwdd.model.MessageContent; @@ -38,13 +40,16 @@ import com.ningdatech.pmapi.user.entity.UserInfo; import com.ningdatech.pmapi.user.service.IUserInfoService; import com.ningdatech.pmapi.user.util.LoginUserUtil; import com.wflow.bean.do_.UserDo; +import com.wflow.bean.entity.NdDeclaredProject; import com.wflow.bean.entity.WflowCcTasks; import com.wflow.bean.entity.WflowModelHistorys; import com.wflow.bean.entity.WflowModels; import com.wflow.exception.BusinessException; import com.wflow.mapper.WflowCcTasksMapper; import com.wflow.mapper.WflowModelHistorysMapper; +import com.wflow.service.NdDeclaredProjectService; import com.wflow.service.OrgRepositoryService; +import com.wflow.utils.UserUtil; import com.wflow.workflow.bean.dto.ProcessInstanceOwnerDto; import com.wflow.workflow.bean.process.OrgUser; import com.wflow.workflow.bean.process.ProcessNode; @@ -52,6 +57,7 @@ import com.wflow.workflow.bean.process.enums.ApprovalModeEnum; import com.wflow.workflow.bean.process.enums.NodeTypeEnum; import com.wflow.workflow.bean.process.form.Form; import com.wflow.workflow.bean.process.props.ApprovalProps; +import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; import com.wflow.workflow.bean.vo.ProcessProgressVo; import com.wflow.workflow.bean.vo.ProcessTaskVo; import com.wflow.workflow.config.WflowGlobalVarDef; @@ -72,9 +78,13 @@ import org.flowable.engine.runtime.Execution; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.flowable.task.api.TaskQuery; +import org.flowable.task.api.history.HistoricTaskInstance; +import org.flowable.task.service.history.NativeHistoricTaskInstanceQuery; import org.flowable.variable.api.history.HistoricVariableInstance; +import org.springframework.beans.BeanUtils; import org.springframework.stereotype.Component; +import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.*; @@ -103,19 +113,21 @@ public class TodoCenterManage { private final WflowModelHistorysMapper modelHistorysMapper; private final ProcessNodeCatchService nodeCatchService; private final OrgRepositoryService orgRepositoryService; - private final ProcessTaskService processTaskService; private final WflowCcTasksMapper ccTasksMapper; private final ProcessModelService processModelService; private final IUserInfoService userInfoService; - private final ExecutableClient CLIENT; + + private final NdDeclaredProjectService declaredProjectService; + @Resource(name = "executableClient") + private ExecutableClient client; /** - * 待办中心项目列表查询 + * 待办中心待我处理项目列表查询 * @param param * @return com.ningdatech.basic.model.PageVo * @author CMM * @since 2023/02/01 17:44 */ - public PageVo queryProjectList(ReqToBeProcessedDTO param) { + public PageVo queryPendingProjectList(ReqToBeProcessedDTO param) { // 获取登录用户ID // long userId = LoginUserUtil.getUserId(); int userId = 381496; @@ -125,68 +137,128 @@ public class TodoCenterManage { TaskQuery taskQuery = taskService.createTaskQuery(); taskQuery.active().taskCandidateOrAssigned(String.valueOf(userId)).orderByTaskCreateTime().desc(); - Page page = param.page(); - List taskList = taskQuery.listPage(pageSize * (pageNumber - 1), pageSize); + List taskList = taskQuery.list(); Set staterUsers = new HashSet<>(); - List resVos = taskList.stream().map(task -> { - String nodeId = task.getTaskDefinitionKey(); - String instanceId = task.getProcessInstanceId(); - - ProcessProgressVo instanceProgress = processService.getInstanceProgress(nodeId, instanceId); - Map formData = instanceProgress.getFormData(); - String status = instanceProgress.getStatus(); - Boolean temporarySupplement = (Boolean) formData.get(ProjectDeclareConstants.BasicInformation.TEMPORARY_SUPPLEMENT); + Page page = param.page(); + + // 将待办任务流程实例一次性取出来,减少查询次数 + Map instanceMap = CollectionUtil.isNotEmpty(taskList) ? + historyService.createHistoricProcessInstanceQuery().processInstanceIds(taskList.stream() + .map(Task::getProcessInstanceId).collect(Collectors.toSet())) + .list().stream().collect(Collectors.toMap(HistoricProcessInstance::getId, v -> v)) : new HashMap<>(); + List processInsIds = taskList.stream().map(Task::getProcessInstanceId).collect(Collectors.toList()); + + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(NdDeclaredProject.class); + wrapper.like(StrUtil.isNotBlank(param.getProjectName()),NdDeclaredProject::getProjectName,param.getProjectName()) + .like(StrUtil.isNotBlank(param.getOrgName()),NdDeclaredProject::getOrgName,param.getOrgName()) + .eq(Objects.nonNull(param.getProjectYear()),NdDeclaredProject::getProjectYear,param.getProjectYear()) + .ge(Objects.nonNull(param.getProcessLaunchStartTime()),NdDeclaredProject::getCreateOn,param.getProcessLaunchStartTime()) + .le(Objects.nonNull(param.getProcessLaunchEndTime()),NdDeclaredProject::getCreateOn,param.getProcessLaunchEndTime()); + declaredProjectService.page(page,wrapper); + + List resVos = page.getRecords().stream().filter(d -> processInsIds.contains(d.getProcInsId())).map(d -> { + ResToBeProcessedDTO res = new ResToBeProcessedDTO(); - temporarySupplement = true; - if (temporarySupplement.equals(param.getIsSupplement())) { - ProcessDefinition processDef = repositoryService.createProcessDefinitionQuery() - .processDefinitionId(task.getProcessDefinitionId()) - .singleResult(); - //从缓存取 - ProcessInstanceOwnerDto owner = runtimeService.getVariable(task.getExecutionId(), "owner", ProcessInstanceOwnerDto.class); - ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult(); - staterUsers.add(owner.getOwner()); - ProcessTaskVo processTaskVo = ProcessTaskVo.builder() - .taskId(task.getId()) - .taskName(task.getName()) - .taskDefKey(task.getTaskDefinitionKey()) - .processDefId(task.getProcessDefinitionId()) - .executionId(task.getExecutionId()) - .nodeId(nodeId) - .deployId(processDef.getDeploymentId()) - .processDefName(processDef.getName()) - .version(processDef.getVersion()) - .instanceId(instanceId) - .ownerId(processInstance.getStartUserId()) - .ownerDeptId(owner.getOwnerDeptId()) - .ownerDeptName(owner.getOwnerDeptName()) - .createTime(processInstance.getStartTime()) - .taskCreateTime(task.getCreateTime()) - .build(); - res.setProcessTaskInfo(processTaskVo); - String projectName = (String) formData.get(ProjectDeclareConstants.BasicInformation.PROJECT_NAME); - res.setProjectName(projectName); - res.setReportUnitId(owner.getOwnerDeptId()); - res.setReportUnitName(owner.getOwnerDeptName()); - res.setReportAmount((Integer) formData.get(ProjectDeclareConstants.FundDeclareInfo.DECLARE_AMOUNT)); - res.setBudgetYear((Integer) formData.get(ProjectDeclareConstants.BasicInformation.BUDGET_YEAR)); - res.setProcessStatus(ProcessStatusEnum.getCodeByDesc(status)); - res.setProcessStatusName(status); - res.setProcessLaunchTime(NdDateUtils.date2LocalDateTime(processInstance.getStartTime())); - } + BeanUtils.copyProperties(d, res); + res.setProcessStatusName(ProcessStatusEnum.getDescByCode(d.getProcessStatus())); + res.setProcessLaunchTime(d.getCreateOn()); + + HistoricTaskInstance task = historyService.createHistoricTaskInstanceQuery().processInstanceId(d.getProcInsId()).singleResult(); + HistoricProcessInstance instance = instanceMap.get(task.getProcessInstanceId()); + HistoricVariableInstance variableInstance = historyService.createHistoricVariableInstanceQuery() + .processInstanceId(instance.getId()).variableName("approve_" + task.getId()).singleResult(); + //从缓存取 + staterUsers.add(instance.getStartUserId()); + ProcessTaskVo processTaskVo = ProcessTaskVo.builder() + .taskId(task.getId()) + .taskName(task.getName()) + .taskDefKey(task.getTaskDefinitionKey()) + .processDefId(task.getProcessDefinitionId()) + .executionId(task.getExecutionId()) + .nodeId(task.getTaskDefinitionKey()) + .deployId(instance.getDeploymentId()) + .processDefName(instance.getProcessDefinitionName()) + .version(instance.getProcessDefinitionVersion()) + .instanceId(task.getProcessInstanceId()) + .ownerId(instance.getStartUserId()) + .createTime(instance.getStartTime()) + .taskCreateTime(task.getCreateTime()) + .taskEndTime(task.getEndTime()) + .taskResult(String.valueOf(Objects.nonNull(variableInstance) ? + variableInstance.getValue() : ProcessHandlerParamsVo.Action.recall)) + .build(); + res.setProcessTaskInfo(processTaskVo); return res; - }).filter(v -> StringUtils.isBlank(param.getProjectName()) || v.getProjectName().contains(param.getProjectName())) - .filter(v -> StringUtils.isBlank(param.getReportUnitName()) || v.getReportUnitName().contains(param.getReportUnitName())) - .filter(v -> Objects.isNull(param.getBudgetYear()) || v.getBudgetYear().equals(param.getBudgetYear())) - .filter(v -> Objects.isNull(param.getProcessLaunchStartTime()) || v.getProcessLaunchTime().isBefore(param.getProcessLaunchStartTime())) - .filter(v -> Objects.isNull(param.getProcessLaunchEndTime()) || v.getProcessLaunchTime().isAfter(param.getProcessLaunchEndTime())) - .collect(Collectors.toList()); + }).collect(Collectors.toList()); + //取用户信息,减少数据库查询,一次构建 + List result = null; if (CollectionUtil.isNotEmpty(staterUsers)) { Map userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); - page.setRecords(resVos.stream().peek(v -> v.getProcessTaskInfo().setOwner(userMap.get(v.getProcessTaskInfo().getOwnerId()))).collect(Collectors.toList())); + result = resVos.stream().peek(v -> v.getProcessTaskInfo() + .setOwner(userMap.get(v.getProcessTaskInfo().getOwnerId()))) + .collect(Collectors.toList()); } - return PageVo.of(resVos,resVos.size()); + return PageVo.of(result,page.getTotal()); + + //List resVos = taskList.stream().map(task -> { + // String nodeId = task.getTaskDefinitionKey(); + // String instanceId = task.getProcessInstanceId(); + // + // ProcessProgressVo instanceProgress = processService.getInstanceProgress(nodeId, instanceId); + // Map formData = instanceProgress.getFormData(); + // String status = instanceProgress.getStatus(); + // Boolean temporarySupplement = (Boolean) formData.get(ProjectDeclareConstants.BasicInformation.TEMPORARY_SUPPLEMENT); + // ResToBeProcessedDTO res = new ResToBeProcessedDTO(); + // temporarySupplement = true; + // if (temporarySupplement.equals(param.getIsSupplement())) { + // ProcessDefinition processDef = repositoryService.createProcessDefinitionQuery() + // .processDefinitionId(task.getProcessDefinitionId()) + // .singleResult(); + // //从缓存取 + // ProcessInstanceOwnerDto owner = runtimeService.getVariable(task.getExecutionId(), "owner", ProcessInstanceOwnerDto.class); + // ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult(); + // staterUsers.add(owner.getOwner()); + // ProcessTaskVo processTaskVo = ProcessTaskVo.builder() + // .taskId(task.getId()) + // .taskName(task.getName()) + // .taskDefKey(task.getTaskDefinitionKey()) + // .processDefId(task.getProcessDefinitionId()) + // .executionId(task.getExecutionId()) + // .nodeId(nodeId) + // .deployId(processDef.getDeploymentId()) + // .processDefName(processDef.getName()) + // .version(processDef.getVersion()) + // .instanceId(instanceId) + // .ownerId(processInstance.getStartUserId()) + // .ownerDeptId(owner.getOwnerDeptId()) + // .ownerDeptName(owner.getOwnerDeptName()) + // .createTime(processInstance.getStartTime()) + // .taskCreateTime(task.getCreateTime()) + // .build(); + // res.setProcessTaskInfo(processTaskVo); + // String projectName = (String) formData.get(ProjectDeclareConstants.BasicInformation.PROJECT_NAME); + // res.setProjectName(projectName); + // res.setReportUnitId(owner.getOwnerDeptId()); + // res.setReportUnitName(owner.getOwnerDeptName()); + // res.setReportAmount((Integer) formData.get(ProjectDeclareConstants.FundDeclareInfo.DECLARE_AMOUNT)); + // res.setBudgetYear((Integer) formData.get(ProjectDeclareConstants.BasicInformation.BUDGET_YEAR)); + // res.setProcessStatus(ProcessStatusEnum.getCodeByDesc(status)); + // res.setProcessStatusName(status); + // res.setProcessLaunchTime(NdDateUtils.date2LocalDateTime(processInstance.getStartTime())); + // } + // return res; + //}).filter(v -> StringUtils.isBlank(param.getProjectName()) || v.getProjectName().contains(param.getProjectName())) + // .filter(v -> StringUtils.isBlank(param.getReportUnitName()) || v.getReportUnitName().contains(param.getReportUnitName())) + // .filter(v -> Objects.isNull(param.getBudgetYear()) || v.getBudgetYear().equals(param.getBudgetYear())) + // .filter(v -> Objects.isNull(param.getProcessLaunchStartTime()) || v.getProcessLaunchTime().isBefore(param.getProcessLaunchStartTime())) + // .filter(v -> Objects.isNull(param.getProcessLaunchEndTime()) || v.getProcessLaunchTime().isAfter(param.getProcessLaunchEndTime())) + // .collect(Collectors.toList()); + //if (CollectionUtil.isNotEmpty(staterUsers)) { + // Map userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); + // page.setRecords(resVos.stream().peek(v -> v.getProcessTaskInfo().setOwner(userMap.get(v.getProcessTaskInfo().getOwnerId()))).collect(Collectors.toList())); + //} + //return PageVo.of(resVos,resVos.size()); } /** * 待办中心列表导出 @@ -196,15 +268,14 @@ public class TodoCenterManage { * @author CMM * @since 2023/02/01 17:44 */ - public void exportProjectList(HttpServletResponse response, ReqToBeProcessedDTO param) { - PageVo page = - queryProjectList(param); + public void exportPendingProjectList(HttpServletResponse response, ReqToBeProcessedDTO param) { + PageVo page = queryPendingProjectList(param); List collect = (List) page.getRecords(); String fileName = null; if (param.getIsSupplement()){ - fileName = "增补项目列表"; + fileName = "待办中心_待我处理_增补项目列表"; }else { - fileName = "非增补项目列表"; + fileName = "待办中心_待我处理_非增补项目列表"; } ExcelDownUtil.setFileName(fileName,response); //数据导出处理函数 @@ -344,7 +415,15 @@ public class TodoCenterManage { } taskService.complete(param.getTaskId(), var); } - + /** + * 给流程发起人发送工作通知 + * @param task 当前任务 + * @param projectName 项目名称 + * @param rootNode 流程发起节点 + * @return void + * @author CMM + * @since 2023/02/03 10:05 + */ private void sendWorkNoticeToStartUser(Task task, String projectName, FlowNode rootNode) { String startUserId = getRootUserId(rootNode); UserInfo startUserInfo = userInfoService.getById(Long.valueOf(startUserId)); @@ -444,7 +523,7 @@ public class TodoCenterManage { private void sendWorkNotice(UserInfo auditUserInfo, String msg) { // TODO 获取浙政钉唯一标识 String dingKey = null; - IntelligentGetClient intelligentGetClient = CLIENT.newIntelligentGetClient(DingConstant.WORKING_NOTICE); + IntelligentGetClient intelligentGetClient = client.newIntelligentGetClient(DingConstant.WORKING_NOTICE); OapiMessageWorkNotificationRequest request = new OapiMessageWorkNotificationRequest(); //消息体(参考下文示例消息格式) MessageText messageText = new MessageText(); @@ -691,4 +770,109 @@ public class TodoCenterManage { //根据流程遍历后续节点,期间要穿越后续包含并行网关和条件网关的节点 return Collections.emptyList(); } + /** + * 待办中心我已处理项目列表查询 + * @param param + * @return com.ningdatech.basic.model.PageVo + * @author CMM + * @since 2023/02/03 10:07 + */ + public PageVo queryHandledProjectList(ReqToBeProcessedDTO param) { + // 获取登录用户ID + // long userId = LoginUserUtil.getUserId(); + int userId = 381496; + // 获取入参分页信息 + Integer pageSize = param.getPageSize(); + Integer pageNumber = param.getPageNumber(); + Page page = param.page(); + + //自定义sql查询所有已办的任务 + String nativeSql = "SELECT aht.* FROM `ACT_HI_TASKINST` AS aht LEFT JOIN `ACT_HI_VARINST` AS ahv ON SUBSTRING(ahv.NAME_, 9) = aht.ID_ \n" + + "AND ahv.NAME_ LIKE 'approve_%' WHERE aht.ASSIGNEE_ = '" + userId + "' AND ahv.NAME_ IS NOT NULL ORDER BY aht.END_TIME_ DESC"; + + NativeHistoricTaskInstanceQuery taskInstanceQuery = historyService.createNativeHistoricTaskInstanceQuery().sql(nativeSql); + List taskInstances = taskInstanceQuery.list(); + + //把已办任务流程实例一次性取出来,减少查询次数 + Map instanceMap = CollectionUtil.isNotEmpty(taskInstances) ? + historyService.createHistoricProcessInstanceQuery().processInstanceIds(taskInstances.stream() + .map(HistoricTaskInstance::getProcessInstanceId).collect(Collectors.toSet())) + .list().stream().collect(Collectors.toMap(HistoricProcessInstance::getId, v -> v)) : new HashMap<>(); + + List processInsIds = taskInstances.stream().map(HistoricTaskInstance::getProcessInstanceId).collect(Collectors.toList()); + LambdaQueryWrapper wrapper = Wrappers.lambdaQuery(NdDeclaredProject.class); + wrapper.like(StrUtil.isNotBlank(param.getProjectName()),NdDeclaredProject::getProjectName,param.getProjectName()) + .like(StrUtil.isNotBlank(param.getOrgName()),NdDeclaredProject::getOrgName,param.getOrgName()) + .eq(Objects.nonNull(param.getProjectYear()),NdDeclaredProject::getProjectYear,param.getProjectYear()) + .ge(Objects.nonNull(param.getProcessLaunchStartTime()),NdDeclaredProject::getCreateOn,param.getProcessLaunchStartTime()) + .le(Objects.nonNull(param.getProcessLaunchEndTime()),NdDeclaredProject::getCreateOn,param.getProcessLaunchEndTime()); + declaredProjectService.page(page,wrapper); + Set staterUsers = new HashSet<>(); + List resVos = page.getRecords().stream().filter(d -> processInsIds.contains(d.getProcInsId())).map(d -> { + + ResToBeProcessedDTO res = new ResToBeProcessedDTO(); + BeanUtils.copyProperties(d, res); + res.setProcessStatusName(ProcessStatusEnum.getDescByCode(d.getProcessStatus())); + res.setProcessLaunchTime(d.getCreateOn()); + res.setProcessHandleTime(d.getUpdateOn()); + + HistoricTaskInstance task = historyService.createHistoricTaskInstanceQuery().processInstanceId(d.getProcInsId()).singleResult(); + HistoricProcessInstance instance = instanceMap.get(task.getProcessInstanceId()); + HistoricVariableInstance variableInstance = historyService.createHistoricVariableInstanceQuery() + .processInstanceId(instance.getId()).variableName("approve_" + task.getId()).singleResult(); + //从缓存取 + staterUsers.add(instance.getStartUserId()); + ProcessTaskVo processTaskVo = ProcessTaskVo.builder() + .taskId(task.getId()) + .taskName(task.getName()) + .taskDefKey(task.getTaskDefinitionKey()) + .processDefId(task.getProcessDefinitionId()) + .executionId(task.getExecutionId()) + .nodeId(task.getTaskDefinitionKey()) + .deployId(instance.getDeploymentId()) + .processDefName(instance.getProcessDefinitionName()) + .version(instance.getProcessDefinitionVersion()) + .instanceId(task.getProcessInstanceId()) + .ownerId(instance.getStartUserId()) + .createTime(instance.getStartTime()) + .taskCreateTime(task.getCreateTime()) + .taskEndTime(task.getEndTime()) + .taskResult(String.valueOf(Objects.nonNull(variableInstance) ? + variableInstance.getValue() : ProcessHandlerParamsVo.Action.recall)) + .build(); + res.setProcessTaskInfo(processTaskVo); + return res; + }).collect(Collectors.toList()); + //取用户信息,减少数据库查询,一次构建 + List result = null; + if (CollectionUtil.isNotEmpty(staterUsers)) { + Map userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); + result = resVos.stream().peek(v -> v.getProcessTaskInfo() + .setOwner(userMap.get(v.getProcessTaskInfo().getOwnerId()))) + .collect(Collectors.toList()); + } + return PageVo.of(result,page.getTotal()); + } + + public void exportHandledProjectList(HttpServletResponse response, ReqToBeProcessedDTO param) { + PageVo page = queryHandledProjectList(param); + List collect = (List) page.getRecords(); + String fileName = null; + if (param.getIsSupplement()){ + fileName = "待办中心_我已处理_增补项目列表"; + }else { + fileName = "待办中心_我已处理_非增补项目列表"; + } + ExcelDownUtil.setFileName(fileName,response); + //数据导出处理函数 + try { + EasyExcel.write(response.getOutputStream(), ResHandledProjectListExportDTO.class) + .autoCloseStream(false) + .registerWriteHandler(ExcelExportStyle.formalStyle()) + .sheet(fileName) + .doWrite(collect); + } catch (IOException e) { + throw new RuntimeException(e); + } + } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqToBeProcessedDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqToBeProcessedDTO.java index 8e8f96e..906695d 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqToBeProcessedDTO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqToBeProcessedDTO.java @@ -26,10 +26,10 @@ public class ReqToBeProcessedDTO extends PagePo implements Serializable { private String projectName; @ApiModelProperty("申报单位名称") - private String reportUnitName; + private String orgName; @ApiModelProperty("预算年度") - private Integer budgetYear; + private Integer projectYear; @ApiModelProperty("流程发起开始时间") private LocalDateTime processLaunchStartTime; diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResHandledProjectListExportDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResHandledProjectListExportDTO.java new file mode 100644 index 0000000..8e3503a --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResHandledProjectListExportDTO.java @@ -0,0 +1,44 @@ +package com.ningdatech.pmapi.todocenter.model.dto.res; + +import java.io.Serializable; +import java.time.LocalDateTime; + +import com.alibaba.excel.annotation.ExcelProperty; + +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 待办中心我已处理项目列表导出实体 + * + * @author CMM + * @since 2023/01/19 16:42 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ResHandledProjectListExportDTO implements Serializable { + private static final long serialVersionUID = 1L; + + @ExcelProperty("项目名称") + private String projectName; + + @ExcelProperty("申报单位") + private String reportUnitName; + + @ExcelProperty("申报金额") + private Integer reportAmount; + + @ExcelProperty("预算年度") + private Integer budgetYear; + + @ExcelProperty("流程状态") + private String processStatusName; + + @ExcelProperty("发起时间") + private LocalDateTime processLaunchTime; + + @ExcelProperty("处理时间") + private LocalDateTime processHandleTime; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java index 0df7691..b985515 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java @@ -1,7 +1,9 @@ package com.ningdatech.pmapi.todocenter.model.dto.res; import java.io.Serializable; +import java.math.BigDecimal; import java.time.LocalDateTime; +import java.util.List; import com.wflow.workflow.bean.vo.ProcessTaskVo; import io.swagger.annotations.ApiModelProperty; @@ -22,22 +24,22 @@ public class ResToBeProcessedDTO implements Serializable { private static final long serialVersionUID = 1L; @ApiModelProperty("项目ID") - private String projectId; + private String procInsId; @ApiModelProperty("项目名称") private String projectName; @ApiModelProperty("申报单位ID") - private String reportUnitId; + private String orgCode; @ApiModelProperty("申报单位名称") - private String reportUnitName; + private String orgName; @ApiModelProperty("申报金额") - private Integer reportAmount; + private BigDecimal approvedAmount; @ApiModelProperty("预算年度") - private Integer budgetYear; + private Integer projectYear; @ApiModelProperty("流程状态") private Integer processStatus; @@ -48,6 +50,9 @@ public class ResToBeProcessedDTO implements Serializable { @ApiModelProperty("流程发起时间") private LocalDateTime processLaunchTime; + @ApiModelProperty("流程处理时间") + private LocalDateTime processHandleTime; + @ApiModelProperty("流程任务信息") private ProcessTaskVo processTaskInfo; } diff --git a/pmapi/src/main/resources/application-dev.yml b/pmapi/src/main/resources/application-dev.yml index 8892203..96fe00f 100644 --- a/pmapi/src/main/resources/application-dev.yml +++ b/pmapi/src/main/resources/application-dev.yml @@ -153,4 +153,19 @@ sa-token: # token风格 token-style: uuid # 是否输出操作日志 - is-log: false \ No newline at end of file + is-log: false + +#专有钉钉 +ding: + #扫码 + app-auth-key: file-manage_dingoa-zte2LbiAfIj + app-auth-secret: H794aFZf271QbfUr50pbBpBTlXSrWIP71q9RTR34 + #扫码 + app-sso-auth-key: fgdn_wjlzjkxt_hz + app-sso-auth-secret: dafe1e6f7d424032acb81f5c2a797a1f + #免登/获取信息 + app-key: file-manage-4Mjx9358wuxjyYFjY3 + app-secret: hE41938wqyQ5LOpc1QDRA9e7gb5YugoClWD3nY4O + #专有钉钉在开发管理工作台,右键查看网页源码realmId: '31141',浙政钉固定196729 + tenantId: 31141 + domain: openplatform.dg-work.cn \ No newline at end of file