@@ -0,0 +1,37 @@ | |||||
package com.hz.pm.api.common.config; | |||||
import com.hz.pm.api.scheduler.listener.TaskCreatedListener; | |||||
import lombok.RequiredArgsConstructor; | |||||
import org.assertj.core.util.Lists; | |||||
import org.flowable.common.engine.api.delegate.event.FlowableEventListener; | |||||
import org.flowable.spring.SpringProcessEngineConfiguration; | |||||
import org.flowable.spring.boot.EngineConfigurationConfigurer; | |||||
import org.springframework.context.annotation.Configuration; | |||||
import java.util.List; | |||||
/** | |||||
* <p> | |||||
* FlowableConfig | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 12:16 2024/3/12 | |||||
*/ | |||||
@RequiredArgsConstructor | |||||
@Configuration("customFlowableConfig") | |||||
public class CustomFlowableConfig implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> { | |||||
private final TaskCreatedListener taskCreatedListener; | |||||
@Override | |||||
public void configure(SpringProcessEngineConfiguration engineConfiguration) { | |||||
List<FlowableEventListener> listeners = engineConfiguration.getEventListeners(); | |||||
if (listeners == null) { | |||||
engineConfiguration.setEventListeners(Lists.newArrayList(taskCreatedListener)); | |||||
} else { | |||||
engineConfiguration.getEventListeners().add(taskCreatedListener); | |||||
} | |||||
} | |||||
} |
@@ -1,13 +1,19 @@ | |||||
package com.hz.pm.api.common.helper; | package com.hz.pm.api.common.helper; | ||||
import com.wflow.workflow.service.ProcessInstanceService; | |||||
import lombok.RequiredArgsConstructor; | import lombok.RequiredArgsConstructor; | ||||
import org.flowable.bpmn.model.Activity; | |||||
import org.flowable.bpmn.model.BpmnModel; | import org.flowable.bpmn.model.BpmnModel; | ||||
import org.flowable.bpmn.model.Process; | import org.flowable.bpmn.model.Process; | ||||
import org.flowable.bpmn.model.UserTask; | import org.flowable.bpmn.model.UserTask; | ||||
import org.flowable.engine.HistoryService; | import org.flowable.engine.HistoryService; | ||||
import org.flowable.engine.RepositoryService; | import org.flowable.engine.RepositoryService; | ||||
import org.flowable.engine.RuntimeService; | |||||
import org.flowable.engine.TaskService; | |||||
import org.flowable.engine.history.HistoricActivityInstance; | import org.flowable.engine.history.HistoricActivityInstance; | ||||
import org.flowable.engine.history.HistoricActivityInstanceQuery; | |||||
import org.flowable.engine.history.HistoricProcessInstance; | import org.flowable.engine.history.HistoricProcessInstance; | ||||
import org.flowable.task.api.Task; | |||||
import org.flowable.variable.api.history.HistoricVariableInstance; | import org.flowable.variable.api.history.HistoricVariableInstance; | ||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
@@ -29,6 +35,28 @@ public class WflowHelper { | |||||
private final HistoryService historyService; | private final HistoryService historyService; | ||||
private final RepositoryService repositoryService; | private final RepositoryService repositoryService; | ||||
private final TaskService taskService; | |||||
public boolean isOrUserTask(String procDefId, String activityId) { | |||||
List<Process> processes = repositoryService.getBpmnModel(procDefId) | |||||
.getProcesses(); | |||||
if (processes.isEmpty()) { | |||||
return false; | |||||
} | |||||
List<UserTask> userTasks = processes.get(0).findFlowElementsOfType(UserTask.class); | |||||
for (UserTask userTask : userTasks) { | |||||
if (userTask.getId().equals(activityId)) { | |||||
return userTask.getLoopCharacteristics().isSequential(); | |||||
} | |||||
} | |||||
return false; | |||||
} | |||||
public List<Task> listUnFinishedTasks(String activityId) { | |||||
return taskService.createTaskQuery() | |||||
.taskDefinitionKey(activityId) | |||||
.list(); | |||||
} | |||||
/** | /** | ||||
* 所有流程是否完成(审核通过) | * 所有流程是否完成(审核通过) | ||||
@@ -3,8 +3,11 @@ package com.hz.pm.api.external; | |||||
import cn.hutool.core.date.LocalDateTimeUtil; | import cn.hutool.core.date.LocalDateTimeUtil; | ||||
import cn.hutool.core.lang.TypeReference; | import cn.hutool.core.lang.TypeReference; | ||||
import cn.hutool.http.HttpUtil; | import cn.hutool.http.HttpUtil; | ||||
import cn.hutool.json.JSONObject; | |||||
import cn.hutool.json.JSONUtil; | import cn.hutool.json.JSONUtil; | ||||
import com.hz.pm.api.external.model.dto.*; | import com.hz.pm.api.external.model.dto.*; | ||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.omg.CORBA.TIMEOUT; | |||||
import org.springframework.beans.factory.annotation.Value; | import org.springframework.beans.factory.annotation.Value; | ||||
import org.springframework.stereotype.Component; | import org.springframework.stereotype.Component; | ||||
@@ -21,18 +24,27 @@ import static cn.hutool.core.date.DatePattern.NORM_DATETIME_FORMATTER; | |||||
* @author WendyYang | * @author WendyYang | ||||
* @since 20:41 2023/12/20 | * @since 20:41 2023/12/20 | ||||
*/ | */ | ||||
@Slf4j | |||||
@Component | @Component | ||||
public class MhApiClient { | public class MhApiClient { | ||||
@Value("${mh.api-host:}") | @Value("${mh.api-host:}") | ||||
private String mhApiHost; | private String mhApiHost; | ||||
@Value("${mh.zwdd-work-notice.client-id:}") | |||||
private String zwddWorkNoticeClientId; | |||||
@Value("${mh.zwdd-work-notice.client-secret:}") | |||||
private String zwddWorkNoticeClientSecret; | |||||
private static final String UNIT_URL = "/sync/unit"; | private static final String UNIT_URL = "/sync/unit"; | ||||
private static final String USER_URL = "/sync/user"; | private static final String USER_URL = "/sync/user"; | ||||
private static final String EXPERT_URL = "/sync/expert"; | private static final String EXPERT_URL = "/sync/expert"; | ||||
private static final String COMPANY_URL = "/sync/company"; | private static final String COMPANY_URL = "/sync/company"; | ||||
private static final String PROJECT_URL = "/project_info/getProjectInfoList"; | private static final String PROJECT_URL = "/project_info/getProjectInfoList"; | ||||
private static final String ZWDD_MSG_URL = "/message/send"; | |||||
public MhRetDTO<List<MhUnitDTO>> queryUnits() { | public MhRetDTO<List<MhUnitDTO>> queryUnits() { | ||||
String requestUrl = mhApiHost + UNIT_URL; | String requestUrl = mhApiHost + UNIT_URL; | ||||
@@ -77,4 +89,17 @@ public class MhApiClient { | |||||
}, false); | }, false); | ||||
} | } | ||||
public boolean sendZwddWorkNotice(MhZwddWorkNoticeDTO notice) { | |||||
notice.setClientId(zwddWorkNoticeClientId); | |||||
notice.setClientSecret(zwddWorkNoticeClientSecret); | |||||
String retBody = HttpUtil.post(mhApiHost + ZWDD_MSG_URL, JSONUtil.toJsonStr(notice)); | |||||
JSONObject retObj = JSONUtil.parseObj(retBody); | |||||
if (retObj.containsKey("code") && retObj.getInt("code") == 200) { | |||||
return Boolean.TRUE; | |||||
} | |||||
log.warn("发送浙政钉工作通知失败:{}", retObj); | |||||
return Boolean.FALSE; | |||||
} | |||||
} | } |
@@ -0,0 +1,40 @@ | |||||
package com.hz.pm.api.external.model.dto; | |||||
import lombok.Data; | |||||
/** | |||||
* <p> | |||||
* MhZwddWorkNoticeDTO | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 21:52 2024/3/12 | |||||
*/ | |||||
@Data | |||||
public class MhZwddWorkNoticeDTO { | |||||
private String clientId; | |||||
private String clientSecret; | |||||
/** | |||||
* 消息标题 | |||||
*/ | |||||
private String title; | |||||
/** | |||||
* 消息内容 | |||||
*/ | |||||
private String content; | |||||
/** | |||||
* 消息发送人 | |||||
*/ | |||||
private String sourceUser; | |||||
/** | |||||
* 消息接收人 | |||||
*/ | |||||
private String targetUser; | |||||
} |
@@ -0,0 +1,135 @@ | |||||
package com.hz.pm.api.external.todo; | |||||
import cn.hutool.core.util.StrUtil; | |||||
import cn.hutool.http.HttpRequest; | |||||
import cn.hutool.http.HttpResponse; | |||||
import cn.hutool.http.HttpUtil; | |||||
import cn.hutool.http.Method; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.alibaba.fastjson.JSONObject; | |||||
import com.alibaba.fastjson.TypeReference; | |||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | |||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; | |||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers; | |||||
import com.hz.pm.api.common.model.constant.BizConst; | |||||
import com.hz.pm.api.external.todo.dto.AddSingleWkHandleDTO; | |||||
import com.hz.pm.api.external.todo.dto.MhTodoRetDTO; | |||||
import com.hz.pm.api.external.todo.enumerization.MHTodoTypeEnum; | |||||
import com.hz.pm.api.sys.entity.MhTodoRecord; | |||||
import com.hz.pm.api.sys.service.IMhTodoRecordService; | |||||
import com.hz.pm.api.user.model.entity.UserInfo; | |||||
import com.hz.pm.api.user.security.model.UserFullInfoDTO; | |||||
import com.ningdatech.basic.exception.BizException; | |||||
import com.ningdatech.basic.util.CollUtils; | |||||
import lombok.RequiredArgsConstructor; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.stereotype.Component; | |||||
import org.springframework.transaction.annotation.Transactional; | |||||
import java.util.*; | |||||
/** | |||||
* @author 王仁康 | |||||
* @date 2024-01-02 16:55:51 | |||||
*/ | |||||
@Slf4j | |||||
@Component | |||||
@RequiredArgsConstructor | |||||
public class MHTodoClient { | |||||
/** | |||||
* 外部系统域名 | |||||
*/ | |||||
@Value("${sms.client-url:}") | |||||
private String todoUrl; | |||||
/** | |||||
* 发送待办接口地址 | |||||
*/ | |||||
private static final String TODO_ADD = "/single_wk_handle/addWkhandle"; | |||||
/** | |||||
* 完成待办接口地址 | |||||
*/ | |||||
private static final String TODO_COMPLETE = "/single_wk_handle/completeHandle"; | |||||
private final IMhTodoRecordService todoRecordService; | |||||
@Transactional(rollbackFor = Exception.class) | |||||
public void addTodo(Object paramObj, UserFullInfoDTO receiver, MHTodoTypeEnum type, String bizId, String content) { | |||||
String url = todoUrl + TODO_ADD; | |||||
Map<String, Object> map = new HashMap<>(8); | |||||
String paramObjs = JSON.toJSONString(paramObj); | |||||
map.put("params", paramObjs); | |||||
map.put("wkContent", content); | |||||
map.put("wkType", type.name()); | |||||
map.put("wkUser", receiver.getMhUserId()); | |||||
log.info("添加新创待办:{}", map); | |||||
String responseResult = HttpUtil.post(url, JSON.toJSONString(map)); | |||||
MhTodoRetDTO retData = JSON.parseObject(responseResult, new TypeReference<MhTodoRetDTO>() { | |||||
}); | |||||
if (retData.getCode() != 0 || StrUtil.isBlank(retData.getData())) { | |||||
log.warn("发送待办失败:{}", map); | |||||
throw BizException.wrap("发送待办失败"); | |||||
} | |||||
MhTodoRecord todo = new MhTodoRecord(); | |||||
todo.setMhTodoId(retData.getData()); | |||||
todo.setContent(content); | |||||
todo.setParamObj(paramObjs); | |||||
todo.setBizId(bizId); | |||||
todo.setType(type.name()); | |||||
todo.setUserId(receiver.getUserId()); | |||||
todo.setToMhUserId(receiver.getMhUserId()); | |||||
todo.setStatus(MhTodoRecord.TodoStatusEnum.PENDING.getCode()); | |||||
todoRecordService.save(todo); | |||||
} | |||||
/** | |||||
* 完成待办 | |||||
* | |||||
* @param wkhandleId 待办ID | |||||
*/ | |||||
public void complete(String wkhandleId) { | |||||
String url = todoUrl + TODO_COMPLETE; | |||||
HashMap<String, Object> map = new HashMap<>(); | |||||
map.put("wkhandleId", wkhandleId); | |||||
// 发送PUT请求 | |||||
HttpRequest request = HttpUtil.createRequest(Method.PUT, url) | |||||
.form("wkhandleId", wkhandleId); | |||||
try (HttpResponse response = request.execute()) { | |||||
MhTodoRetDTO retData = JSON.parseObject(response.body(), new TypeReference<MhTodoRetDTO>() { | |||||
}); | |||||
boolean state = Boolean.parseBoolean(retData.getData()); | |||||
if (!state) { | |||||
log.error("待办完成失败:{} {}", wkhandleId, retData); | |||||
} | |||||
} | |||||
} | |||||
public void completeTodo(MHTodoTypeEnum todoType, Collection<String> bizIds) { | |||||
LambdaQueryWrapper<MhTodoRecord> query = Wrappers.lambdaQuery(MhTodoRecord.class) | |||||
.eq(MhTodoRecord::getType, todoType.name()) | |||||
.in(MhTodoRecord::getBizId, bizIds) | |||||
.eq(MhTodoRecord::getStatus, MhTodoRecord.TodoStatusEnum.PENDING.getCode()); | |||||
List<MhTodoRecord> todos = todoRecordService.list(query); | |||||
if (todos.isEmpty()) { | |||||
return; | |||||
} | |||||
for (MhTodoRecord todo : todos) { | |||||
complete(todo.getMhTodoId()); | |||||
} | |||||
LambdaUpdateWrapper<MhTodoRecord> update = Wrappers.lambdaUpdate(MhTodoRecord.class) | |||||
.in(MhTodoRecord::getId, CollUtils.fieldList(todos, MhTodoRecord::getId)) | |||||
.set(MhTodoRecord::getStatus, MhTodoRecord.TodoStatusEnum.HANDED.getCode()); | |||||
todoRecordService.update(update); | |||||
} | |||||
public void completeTodo(MHTodoTypeEnum todoType, String bizId) { | |||||
completeTodo(todoType, Collections.singletonList(bizId)); | |||||
} | |||||
} |
@@ -1,79 +0,0 @@ | |||||
package com.hz.pm.api.external.todo; | |||||
import cn.hutool.http.HttpRequest; | |||||
import cn.hutool.http.HttpResponse; | |||||
import cn.hutool.http.HttpUtil; | |||||
import cn.hutool.http.Method; | |||||
import com.alibaba.fastjson.JSON; | |||||
import com.alibaba.fastjson.JSONObject; | |||||
import com.alibaba.fastjson.TypeReference; | |||||
import com.hz.pm.api.external.todo.dto.AddSingleWkHandleDTO; | |||||
import com.hz.pm.api.external.todo.dto.TodoDTO; | |||||
import lombok.RequiredArgsConstructor; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.springframework.beans.factory.annotation.Value; | |||||
import org.springframework.stereotype.Component; | |||||
import java.util.HashMap; | |||||
import java.util.Map; | |||||
/** | |||||
* @author 王仁康 | |||||
* @date 2024-01-02 16:55:51 | |||||
*/ | |||||
@Slf4j | |||||
@Component | |||||
@RequiredArgsConstructor | |||||
public class TodoServiceClient { | |||||
/** | |||||
* 外部系统域名 | |||||
*/ | |||||
@Value("${sms.client-url:}") | |||||
private String todoUrl; | |||||
// 发送待办 | |||||
public static final String TODO_ADD = "/single_wk_handle/addWkhandle"; | |||||
// 完成待办 | |||||
public static final String TODO_COMPLETE = "/single_wk_handle/completeHandle"; | |||||
/** | |||||
* 添加待办方法 | |||||
* @param addSingleWkHandleDTO | |||||
* @return 接口返回待办ID | |||||
*/ | |||||
public TodoDTO addTodo(AddSingleWkHandleDTO addSingleWkHandleDTO) { | |||||
String url = todoUrl + TODO_ADD; | |||||
Map<String,Object> map = new HashMap<>(); | |||||
JSONObject json = (JSONObject) JSONObject.toJSON(addSingleWkHandleDTO.getParams()); | |||||
String jsonString = JSON.toJSONString(json); | |||||
map.put("params", jsonString); | |||||
map.put("wkContent",addSingleWkHandleDTO.getWkContent()); | |||||
map.put("wkType",addSingleWkHandleDTO.getWkType()); | |||||
map.put("wkUser",addSingleWkHandleDTO.getWkUser()); | |||||
String responseResult = HttpUtil.post(url, JSON.toJSONString(map)); | |||||
return JSON.parseObject(responseResult, new TypeReference<TodoDTO>() { | |||||
}); | |||||
} | |||||
/** | |||||
* 完成待办 | |||||
* @param wkhandleId 待办ID | |||||
*/ | |||||
public TodoDTO completeTodo(String wkhandleId){ | |||||
String url = todoUrl + TODO_COMPLETE; | |||||
HashMap<String,Object> map = new HashMap<>(); | |||||
map.put("wkhandleId",wkhandleId); | |||||
// 发送PUT请求 | |||||
HttpRequest request = HttpUtil.createRequest(Method.PUT,url) | |||||
.form("wkhandleId",wkhandleId); | |||||
HttpResponse response = request.execute(); | |||||
String responseBody = response.body(); | |||||
return JSON.parseObject(responseBody, new TypeReference<TodoDTO>() { | |||||
}); | |||||
} | |||||
} |
@@ -3,15 +3,13 @@ package com.hz.pm.api.external.todo.dto; | |||||
import lombok.AllArgsConstructor; | import lombok.AllArgsConstructor; | ||||
import lombok.Data; | import lombok.Data; | ||||
import java.io.Serializable; | |||||
/** | /** | ||||
* @author 王仁康 | * @author 王仁康 | ||||
* @date 2024-01-02 17:04:09 | * @date 2024-01-02 17:04:09 | ||||
*/ | */ | ||||
@AllArgsConstructor | @AllArgsConstructor | ||||
@Data | @Data | ||||
public class TodoDTO { | |||||
public class MhTodoRetDTO { | |||||
private Integer code; | private Integer code; | ||||
@@ -0,0 +1,25 @@ | |||||
package com.hz.pm.api.external.todo.enumerization; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Getter; | |||||
/** | |||||
* <p> | |||||
* MHTodoTypeEnum | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 10:09 2024/3/12 | |||||
*/ | |||||
@Getter | |||||
@AllArgsConstructor | |||||
public enum MHTodoTypeEnum { | |||||
FINAL_INSPECT_AUDIT("终验审批"), | |||||
XCFHX_INSPECT_AUDIT("信创符合性审查审批"), | |||||
DECLARED_RECORD_AUDIT("立项备案审批"); | |||||
private final String val; | |||||
} |
@@ -40,13 +40,11 @@ import java.util.stream.Collectors; | |||||
@Component | @Component | ||||
@RequiredArgsConstructor | @RequiredArgsConstructor | ||||
public class EarlyWarningListener { | public class EarlyWarningListener { | ||||
private final HistoryService historyService; | private final HistoryService historyService; | ||||
private final IProjectInstService projectInstService; | private final IProjectInstService projectInstService; | ||||
private final IProjectService projectService; | private final IProjectService projectService; | ||||
private final EarlyWarningManage earlyWarningManage; | private final EarlyWarningManage earlyWarningManage; | ||||
private final IProjectEarlyWarningService projectEarlyWarningService; | private final IProjectEarlyWarningService projectEarlyWarningService; | ||||
@Async | @Async | ||||
@@ -68,12 +68,6 @@ public class ProcessEndListener { | |||||
private final NoticeManage noticeManage; | private final NoticeManage noticeManage; | ||||
private final IJoinReviewProvincialBureauService joinReviewProvincialBureauService; | |||||
private final IProjectApplicationService projectApplicationService; | |||||
private final FileService fileService; | |||||
@Value("${spring.profiles.active}") | @Value("${spring.profiles.active}") | ||||
private String active; | private String active; | ||||
@@ -27,19 +27,17 @@ import java.util.Objects; | |||||
* 工作流开始 事件监听 | * 工作流开始 事件监听 | ||||
* | * | ||||
* @author ZPF | * @author ZPF | ||||
* @return | |||||
* @since 2023/04/14 14:19 | * @since 2023/04/14 14:19 | ||||
*/ | */ | ||||
@Slf4j | @Slf4j | ||||
@Component | @Component | ||||
@RequiredArgsConstructor | @RequiredArgsConstructor | ||||
public class ProcessStartListener { | public class ProcessStartListener { | ||||
private final TaskService taskService; | private final TaskService taskService; | ||||
private final HistoryService historyService; | private final HistoryService historyService; | ||||
private final IProjectInstService projectInstService; | private final IProjectInstService projectInstService; | ||||
private final IProjectService projectService; | private final IProjectService projectService; | ||||
private final StateMachineUtil stateMachineUtil; | private final StateMachineUtil stateMachineUtil; | ||||
@Async | @Async | ||||
@@ -0,0 +1,164 @@ | |||||
package com.hz.pm.api.scheduler.listener; | |||||
import cn.hutool.core.text.CharSequenceUtil; | |||||
import cn.hutool.core.util.StrUtil; | |||||
import cn.hutool.extra.spring.SpringUtil; | |||||
import cn.hutool.json.JSONObject; | |||||
import com.hz.pm.api.common.enumeration.ProjectProcessStageEnum; | |||||
import com.hz.pm.api.common.helper.UserInfoHelper; | |||||
import com.hz.pm.api.common.helper.WflowHelper; | |||||
import com.hz.pm.api.external.MhApiClient; | |||||
import com.hz.pm.api.external.model.dto.MhZwddWorkNoticeDTO; | |||||
import com.hz.pm.api.external.todo.MHTodoClient; | |||||
import com.hz.pm.api.external.todo.enumerization.MHTodoTypeEnum; | |||||
import com.hz.pm.api.projectlib.model.entity.Project; | |||||
import com.hz.pm.api.projectlib.model.entity.ProjectInst; | |||||
import com.hz.pm.api.projectlib.service.IProjectInstService; | |||||
import com.hz.pm.api.projectlib.service.IProjectService; | |||||
import com.hz.pm.api.user.security.model.UserFullInfoDTO; | |||||
import com.ningdatech.basic.util.CollUtils; | |||||
import com.wflow.bean.entity.WflowModelHistorys; | |||||
import com.wflow.workflow.service.ProcessModelHistorysService; | |||||
import lombok.RequiredArgsConstructor; | |||||
import lombok.extern.slf4j.Slf4j; | |||||
import org.flowable.common.engine.api.delegate.event.FlowableEngineEntityEvent; | |||||
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType; | |||||
import org.flowable.common.engine.api.delegate.event.FlowableEvent; | |||||
import org.flowable.common.engine.api.delegate.event.FlowableEventListener; | |||||
import org.flowable.task.api.Task; | |||||
import org.flowable.task.api.TaskInfo; | |||||
import org.flowable.task.service.impl.persistence.entity.TaskEntity; | |||||
import org.springframework.stereotype.Component; | |||||
import java.util.List; | |||||
import java.util.Optional; | |||||
import java.util.Set; | |||||
/** | |||||
* <p> | |||||
* TaskCreatedListener | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 10:38 2024/3/12 | |||||
*/ | |||||
@Slf4j | |||||
@Component | |||||
@RequiredArgsConstructor | |||||
public class TaskCreatedListener implements FlowableEventListener { | |||||
private final IProjectService projectService; | |||||
private final IProjectInstService projectInstService; | |||||
private final ProcessModelHistorysService processModelHistorysService; | |||||
private final MHTodoClient mhTodoClient; | |||||
private final MhApiClient mhApiClient; | |||||
private final UserInfoHelper userInfoHelper; | |||||
@Override | |||||
public void onEvent(FlowableEvent event) { | |||||
if (event.getType().equals(FlowableEngineEventType.TASK_CREATED)) { | |||||
FlowableEngineEntityEvent entityEvent = (FlowableEngineEntityEvent) event; | |||||
String procDefId = entityEvent.getProcessDefinitionId(); | |||||
String procInstId = entityEvent.getProcessInstanceId(); | |||||
WflowModelHistorys models = processModelHistorysService.getByProcessDefId(procDefId); | |||||
Optional<ProjectProcessStageEnum> procType = ProjectProcessStageEnum.get(models.getProcessType()); | |||||
TaskEntity taskEntity = (TaskEntity) entityEvent.getEntity(); | |||||
UserFullInfoDTO assignee = userInfoHelper.getUserFullInfo(taskEntity.getAssignee()); | |||||
if (assignee == null || CharSequenceUtil.isBlank(assignee.getMhUserId())) { | |||||
return; | |||||
} | |||||
ProjectInst projectInst = projectInstService.getByInstCode(procInstId); | |||||
if (projectInst == null) { | |||||
return; | |||||
} | |||||
Project project = projectService.getById(projectInst.getProjectId()); | |||||
if (!procType.isPresent()) { | |||||
return; | |||||
} | |||||
switch (procType.get()) { | |||||
case XC_APPROVAL_PROCESS: | |||||
case PROJECT_RECORD_APPROVAL_PROCESS: | |||||
case ACCEPTANCE_DECLARATION_APPROVAL_PROCESS: | |||||
// 发送信产平台待办 | |||||
MHTodoTypeEnum todoType = getMhTodoTypeEnum(procType.get()); | |||||
JSONObject paramObj = new JSONObject(); | |||||
paramObj.set("projectId", projectInst.getProjectId()); | |||||
paramObj.set("instId", taskEntity.getProcessInstanceId()); | |||||
paramObj.set("taskId", taskEntity.getId()); | |||||
String content = String.format("【%s】的【%s】需要您审核,请及时处理。", | |||||
project.getProjectName(), procType.get().getDesc()); | |||||
mhTodoClient.addTodo(paramObj, assignee, todoType, taskEntity.getId(), content); | |||||
// 发送浙政钉工作通知 | |||||
if (assignee.getAccountId() != null) { | |||||
MhZwddWorkNoticeDTO notice = new MhZwddWorkNoticeDTO(); | |||||
notice.setContent(content); | |||||
notice.setTitle(todoType.getVal()); | |||||
notice.setTargetUser(assignee.getMhUserId()); | |||||
mhApiClient.sendZwddWorkNotice(notice); | |||||
} | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} else if (event.getType().equals(FlowableEngineEventType.TASK_COMPLETED)) { | |||||
FlowableEngineEntityEvent entityEvent = (FlowableEngineEntityEvent) event; | |||||
String procDefId = entityEvent.getProcessDefinitionId(); | |||||
WflowModelHistorys models = processModelHistorysService.getByProcessDefId(procDefId); | |||||
Optional<ProjectProcessStageEnum> procType = ProjectProcessStageEnum.get(models.getProcessType()); | |||||
if (!procType.isPresent()) { | |||||
return; | |||||
} | |||||
TaskEntity taskEntity = (TaskEntity) entityEvent.getEntity(); | |||||
WflowHelper wflowHelper = SpringUtil.getBean(WflowHelper.class); | |||||
boolean orUserTask = wflowHelper.isOrUserTask(procDefId, taskEntity.getTaskDefinitionId()); | |||||
switch (procType.get()) { | |||||
case XC_APPROVAL_PROCESS: | |||||
case PROJECT_RECORD_APPROVAL_PROCESS: | |||||
case ACCEPTANCE_DECLARATION_APPROVAL_PROCESS: | |||||
MHTodoTypeEnum todoType = getMhTodoTypeEnum(procType.get()); | |||||
if (orUserTask) { | |||||
List<Task> tasks = wflowHelper.listUnFinishedTasks(taskEntity.getTaskDefinitionId()); | |||||
Set<String> taskIds = CollUtils.fieldSet(tasks, TaskInfo::getId); | |||||
taskIds.add(taskEntity.getId()); | |||||
mhTodoClient.completeTodo(todoType, taskIds); | |||||
} else { | |||||
mhTodoClient.completeTodo(todoType, taskEntity.getId()); | |||||
} | |||||
break; | |||||
default: | |||||
break; | |||||
} | |||||
} | |||||
} | |||||
private MHTodoTypeEnum getMhTodoTypeEnum(ProjectProcessStageEnum procType) { | |||||
MHTodoTypeEnum todoType; | |||||
switch (procType) { | |||||
case XC_APPROVAL_PROCESS: | |||||
todoType = MHTodoTypeEnum.XCFHX_INSPECT_AUDIT; | |||||
break; | |||||
case PROJECT_RECORD_APPROVAL_PROCESS: | |||||
todoType = MHTodoTypeEnum.DECLARED_RECORD_AUDIT; | |||||
break; | |||||
default: | |||||
todoType = MHTodoTypeEnum.FINAL_INSPECT_AUDIT; | |||||
break; | |||||
} | |||||
return todoType; | |||||
} | |||||
@Override | |||||
public boolean isFailOnException() { | |||||
return false; | |||||
} | |||||
@Override | |||||
public boolean isFireOnTransactionLifecycleEvent() { | |||||
return false; | |||||
} | |||||
@Override | |||||
public String getOnTransaction() { | |||||
return null; | |||||
} | |||||
} |
@@ -0,0 +1,18 @@ | |||||
package com.hz.pm.api.sys.controller; | |||||
import org.springframework.web.bind.annotation.RequestMapping; | |||||
import org.springframework.stereotype.Controller; | |||||
/** | |||||
* <p> | |||||
* 信产待办发送记录 前端控制器 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2024-03-12 | |||||
*/ | |||||
@Controller | |||||
@RequestMapping("/api.sys/mhTodoRecord") | |||||
public class MhTodoRecordController { | |||||
} |
@@ -0,0 +1,78 @@ | |||||
package com.hz.pm.api.sys.entity; | |||||
import com.baomidou.mybatisplus.annotation.IdType; | |||||
import com.baomidou.mybatisplus.annotation.TableId; | |||||
import com.baomidou.mybatisplus.annotation.TableName; | |||||
import java.io.Serializable; | |||||
import java.time.LocalDateTime; | |||||
import java.util.Arrays; | |||||
import java.util.Optional; | |||||
import io.swagger.annotations.ApiModel; | |||||
import io.swagger.annotations.ApiModelProperty; | |||||
import lombok.AllArgsConstructor; | |||||
import lombok.Data; | |||||
import lombok.Getter; | |||||
/** | |||||
* <p> | |||||
* 信产待办发送记录 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2024-03-12 | |||||
*/ | |||||
@Data | |||||
@TableName("MH_TODO_RECORD") | |||||
@ApiModel(value = "信产待办发送记录") | |||||
public class MhTodoRecord implements Serializable { | |||||
private static final long serialVersionUID = 1L; | |||||
@TableId(value = "ID", type = IdType.AUTO) | |||||
private Long id; | |||||
@ApiModelProperty("待办用户ID(信产)") | |||||
private String toMhUserId; | |||||
private Long userId; | |||||
@ApiModelProperty("待办内容") | |||||
private String content; | |||||
@ApiModelProperty("参数") | |||||
private String paramObj; | |||||
@ApiModelProperty("待办ID") | |||||
private String mhTodoId; | |||||
@ApiModelProperty("待办类型") | |||||
private String type; | |||||
private LocalDateTime createOn; | |||||
@ApiModelProperty("处理状态:1 待处理、2 已处理") | |||||
private Integer status; | |||||
@ApiModelProperty("对应的业务ID") | |||||
private String bizId; | |||||
@Getter | |||||
@AllArgsConstructor | |||||
public enum TodoStatusEnum { | |||||
PENDING(1, "待处理"), | |||||
HANDED(2, "已处理"); | |||||
private final Integer code; | |||||
private final String val; | |||||
public static Optional<TodoStatusEnum> get(Integer code) { | |||||
return Arrays.stream(values()).filter(w -> w.getCode().equals(code)).findFirst(); | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,16 @@ | |||||
package com.hz.pm.api.sys.mapper; | |||||
import com.hz.pm.api.sys.entity.MhTodoRecord; | |||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper; | |||||
/** | |||||
* <p> | |||||
* 信产待办发送记录 Mapper 接口 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2024-03-12 | |||||
*/ | |||||
public interface MhTodoRecordMapper extends BaseMapper<MhTodoRecord> { | |||||
} |
@@ -0,0 +1,5 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> | |||||
<mapper namespace="com.hz.pm.api.sys.mapper.MhTodoRecordMapper"> | |||||
</mapper> |
@@ -0,0 +1,16 @@ | |||||
package com.hz.pm.api.sys.service; | |||||
import com.hz.pm.api.sys.entity.MhTodoRecord; | |||||
import com.baomidou.mybatisplus.extension.service.IService; | |||||
/** | |||||
* <p> | |||||
* 信产待办发送记录 服务类 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2024-03-12 | |||||
*/ | |||||
public interface IMhTodoRecordService extends IService<MhTodoRecord> { | |||||
} |
@@ -0,0 +1,20 @@ | |||||
package com.hz.pm.api.sys.service.impl; | |||||
import com.hz.pm.api.sys.entity.MhTodoRecord; | |||||
import com.hz.pm.api.sys.mapper.MhTodoRecordMapper; | |||||
import com.hz.pm.api.sys.service.IMhTodoRecordService; | |||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; | |||||
import org.springframework.stereotype.Service; | |||||
/** | |||||
* <p> | |||||
* 信产待办发送记录 服务实现类 | |||||
* </p> | |||||
* | |||||
* @author WendyYang | |||||
* @since 2024-03-12 | |||||
*/ | |||||
@Service | |||||
public class MhTodoRecordServiceImpl extends ServiceImpl<MhTodoRecordMapper, MhTodoRecord> implements IMhTodoRecordService { | |||||
} |
@@ -315,7 +315,7 @@ public class FlowableTest extends AppTests { | |||||
@Test | @Test | ||||
public void test() { | public void test() { | ||||
wflowHelper.allInstancesFinished(Sets.newSet("dd21cb84-dfb8-11ee-a578-02426daa406d")); | |||||
System.out.println(wflowHelper.isOrUserTask("9c05e0a3-e045-11ee-8427-02426daa406d","")); | |||||
} | } | ||||
} | } |
@@ -55,7 +55,7 @@ public class CodeGen { | |||||
} | } | ||||
public static void main(String[] args) { | public static void main(String[] args) { | ||||
generate("WendyYang", "projectlib", PATH_YYD, "nd_project_gov_system_replace_infos"); | |||||
generate("WendyYang", "sys", PATH_YYD, "mh_todo_record"); | |||||
} | } | ||||
} | } |