Ver código fonte

待办中心待我处理处理功能

master
CMM 1 ano atrás
pai
commit
100898743c
12 arquivos alterados com 648 adições e 84 exclusões
  1. +11
    -4
      pmapi/pom.xml
  2. +1
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/App.java
  3. +46
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/config/BeanConfig.java
  4. +65
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/config/GovDingProperties.java
  5. +25
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/util/CallBack.java
  6. +150
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/common/util/SpringContextHolder.java
  7. +28
    -6
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java
  8. +250
    -66
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java
  9. +2
    -2
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqToBeProcessedDTO.java
  10. +44
    -0
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResHandledProjectListExportDTO.java
  11. +10
    -5
      pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java
  12. +16
    -1
      pmapi/src/main/resources/application-dev.yml

+ 11
- 4
pmapi/pom.xml Ver arquivo

@@ -263,8 +263,6 @@
<artifactId>nd-zwdd-starter</artifactId>
<version>1.0.0</version>
</dependency>
<<<<<<< HEAD

<!--浙政钉-->
<dependency>
<groupId>com.alibaba.xxpt</groupId>
@@ -274,8 +272,17 @@
<systemPath>${basedir}/src/lib/zwdd-sdk-java-1.2.0.jar</systemPath>
</dependency>

=======
>>>>>>> 5a1444731ea4c918904ff265516fc5d31a7ebb36
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>

<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
<version>2.10.6</version>
</dependency>

</dependencies>
<!-- 打包 -->
<!--配置环境的profile-->


+ 1
- 0
pmapi/src/main/java/com/ningdatech/pmapi/App.java Ver arquivo

@@ -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;


+ 46
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/config/BeanConfig.java Ver arquivo

@@ -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;
}
}

+ 65
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/config/GovDingProperties.java Ver arquivo

@@ -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;
}
}

+ 25
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/util/CallBack.java Ver arquivo

@@ -0,0 +1,25 @@
package com.ningdatech.pmapi.common.util;

/**
* @author qinxianyun
* @see {@link SpringContextHolder}
* 针对某些初始化方法,在SpringContextHolder 初始化前时,<br>
* 可提交一个 提交回调任务。<br>
* 在SpringContextHolder 初始化后,进行回调使用
*/

public interface CallBack {
/**
* 回调执行方法
*/
void executor();

/**
* 本回调任务名称
* @return /
*/
default String getCallBackName() {
return Thread.currentThread().getId() + ":" + this.getClass().getName();
}
}


+ 150
- 0
pmapi/src/main/java/com/ningdatech/pmapi/common/util/SpringContextHolder.java Ver arquivo

@@ -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<CallBack> 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> T getBean(String name) {
assertContextInjected();
return (T) applicationContext.getBean(name);
}

/**
* 从静态变量applicationContext中取得Bean, 自动转型为所赋值对象的类型.
*/
public static <T> T getBean(Class<T> requiredType) {
assertContextInjected();
return applicationContext.getBean(requiredType);
}

/**
* 获取SpringBoot 配置信息
*
* @param property 属性key
* @param defaultValue 默认值
* @param requiredType 返回类型
* @return /
*/
public static <T> T getProperties(String property, T defaultValue, Class<T> 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> T getProperties(String property, Class<T> 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;
}

/**
* 获取当前启用的配置文件
* <ul>
* <li><b>生产环境:prod</b></li>
* <li><b>开发环境:dev</b></li>
* </ul>
*
* @return java.lang.String
* @author WendyYang
**/
public static String getActiveProfile() {
String[] strings = applicationContext.getEnvironment().getActiveProfiles();
return strings[0];
}

}

+ 28
- 6
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java Ver arquivo

@@ -41,9 +41,9 @@ public class TodoCenterController {
* @param param
* @return
*/
@GetMapping("/query-project-list")
public ApiResponse<PageVo<ResToBeProcessedDTO>> queryProjectList(@Valid @ModelAttribute ReqToBeProcessedDTO param){
PageVo<ResToBeProcessedDTO> result = todoCenterManage.queryProjectList(param);
@GetMapping("/query-todo-list")
public ApiResponse<PageVo<ResToBeProcessedDTO>> queryPendingProjectList(@Valid @ModelAttribute ReqToBeProcessedDTO param){
PageVo<ResToBeProcessedDTO> 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<PageVo<ResToBeProcessedDTO>> queryHandledProjectList(@Valid @ModelAttribute ReqToBeProcessedDTO param){
PageVo<ResToBeProcessedDTO> 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);
}
}

+ 250
- 66
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java Ver arquivo

@@ -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<com.ningdatech.pmapi.todocenter.model.dto.res.ResToBeProcessedDTO>
* @author CMM
* @since 2023/02/01 17:44
*/
public PageVo<ResToBeProcessedDTO> queryProjectList(ReqToBeProcessedDTO param) {
public PageVo<ResToBeProcessedDTO> 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<ResToBeProcessedDTO> page = param.page();

List<Task> taskList = taskQuery.listPage(pageSize * (pageNumber - 1), pageSize);
List<Task> taskList = taskQuery.list();
Set<String> staterUsers = new HashSet<>();
List<ResToBeProcessedDTO> resVos = taskList.stream().map(task -> {
String nodeId = task.getTaskDefinitionKey();
String instanceId = task.getProcessInstanceId();

ProcessProgressVo instanceProgress = processService.getInstanceProgress(nodeId, instanceId);
Map<String, Object> formData = instanceProgress.getFormData();
String status = instanceProgress.getStatus();
Boolean temporarySupplement = (Boolean) formData.get(ProjectDeclareConstants.BasicInformation.TEMPORARY_SUPPLEMENT);
Page<NdDeclaredProject> page = param.page();

// 将待办任务流程实例一次性取出来,减少查询次数
Map<String, HistoricProcessInstance> 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<String> processInsIds = taskList.stream().map(Task::getProcessInstanceId).collect(Collectors.toList());

LambdaQueryWrapper<NdDeclaredProject> 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<ResToBeProcessedDTO> 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<ResToBeProcessedDTO> result = null;
if (CollectionUtil.isNotEmpty(staterUsers)) {
Map<String, OrgUser> 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<ResToBeProcessedDTO> resVos = taskList.stream().map(task -> {
// String nodeId = task.getTaskDefinitionKey();
// String instanceId = task.getProcessInstanceId();
//
// ProcessProgressVo instanceProgress = processService.getInstanceProgress(nodeId, instanceId);
// Map<String, Object> 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<String, OrgUser> 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<ResToBeProcessedDTO> page =
queryProjectList(param);
public void exportPendingProjectList(HttpServletResponse response, ReqToBeProcessedDTO param) {
PageVo<ResToBeProcessedDTO> page = queryPendingProjectList(param);
List<ResToBeProcessedDTO> collect = (List<ResToBeProcessedDTO>) 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<com.ningdatech.pmapi.todocenter.model.dto.res.ResToBeProcessedDTO>
* @author CMM
* @since 2023/02/03 10:07
*/
public PageVo<ResToBeProcessedDTO> queryHandledProjectList(ReqToBeProcessedDTO param) {
// 获取登录用户ID
// long userId = LoginUserUtil.getUserId();
int userId = 381496;
// 获取入参分页信息
Integer pageSize = param.getPageSize();
Integer pageNumber = param.getPageNumber();
Page<NdDeclaredProject> 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<HistoricTaskInstance> taskInstances = taskInstanceQuery.list();

//把已办任务流程实例一次性取出来,减少查询次数
Map<String, HistoricProcessInstance> 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<String> processInsIds = taskInstances.stream().map(HistoricTaskInstance::getProcessInstanceId).collect(Collectors.toList());
LambdaQueryWrapper<NdDeclaredProject> 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<String> staterUsers = new HashSet<>();
List<ResToBeProcessedDTO> 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<ResToBeProcessedDTO> result = null;
if (CollectionUtil.isNotEmpty(staterUsers)) {
Map<String, OrgUser> 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<ResToBeProcessedDTO> page = queryHandledProjectList(param);
List<ResToBeProcessedDTO> collect = (List<ResToBeProcessedDTO>) 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);
}
}
}

+ 2
- 2
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqToBeProcessedDTO.java Ver arquivo

@@ -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;


+ 44
- 0
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResHandledProjectListExportDTO.java Ver arquivo

@@ -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;
}

+ 10
- 5
pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java Ver arquivo

@@ -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;
}

+ 16
- 1
pmapi/src/main/resources/application-dev.yml Ver arquivo

@@ -153,4 +153,19 @@ sa-token:
# token风格
token-style: uuid
# 是否输出操作日志
is-log: false
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

Carregando…
Cancelar
Salvar