Files
geg-gas-pcitc/xjrsoft-common/xjrsoft-common-advice/src/main/java/com.xjrsoft.advice/WorkflowResponseBodyAdvice.java
2025-02-08 17:51:37 +08:00

329 lines
14 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package com.xjrsoft.advice;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.*;
import cn.hutool.db.Entity;
import cn.hutool.extra.servlet.ServletUtil;
import com.xjrsoft.common.core.domain.page.PageOutput;
import com.xjrsoft.common.core.domain.result.R;
import com.xjrsoft.common.core.exception.MyException;
import com.xjrsoft.common.redis.service.RedisUtil;
import com.xjrsoft.workflow.client.IHistoryClient;
import com.xjrsoft.workflow.client.ITaskClient;
import com.xjrsoft.workflow.client.IWorkflowFormRelationClient;
import com.xjrsoft.workflow.client.IWorkflowSchemaClient;
import com.xjrsoft.workflow.entity.WorkflowFormRelation;
import com.xjrsoft.workflow.entity.WorkflowSchema;
import com.xjrsoft.workflow.model.WorkflowListResult;
import com.xjrsoft.workflow.vo.HistoryProcessInstanceVo;
import com.xjrsoft.workflow.vo.TaskInstanceVo;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.javassist.*;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpRequest;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.*;
import java.util.stream.Collectors;
/**
* 工作流 模板 绑定菜单 返回值新增工作流的相关属性
*
* @Author: tzx
* @Date: 2023/3/27 14:24
*/
@Slf4j
@RestControllerAdvice
@AllArgsConstructor
public class WorkflowResponseBodyAdvice implements ResponseBodyAdvice<Object> {
private RedisUtil redisUtil;
private IWorkflowFormRelationClient formRelationClient;
private IWorkflowSchemaClient workflowSchemaClient;
private IHistoryClient historyClient;
private ITaskClient taskClient;
private static final Map<String, Constructor<?>> cacheClass = new HashMap<>();
private static final String FORM_ID_KEY = "FormId";
private static final String KEY_VALUE_KEY = "PK";
private static final String FIELD_STRING = "private Object workflowData;";
private static final String GET_MOTHOD_STRING = "public Object getWorkflowData(){ return this.workflowData; }";
private static final String RESULT_KEY = "workflowData";
@Override
public boolean supports(@NonNull MethodParameter returnType, @NonNull Class converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, @NonNull MethodParameter returnType, @NonNull MediaType selectedContentType, @NonNull Class selectedConverterType, @NonNull ServerHttpRequest request, @NonNull ServerHttpResponse response) {
if (!(body instanceof R)) {
return body;
}
if (((R) body).getData() == null) {
return body;
}
//先从header里面获取formId 如果能获取到 就证明是自定义表单
String headerFormId = ServletUtil.getHeader(((ServletServerHttpRequest) request).getServletRequest(), FORM_ID_KEY, CharsetUtil.UTF_8);
String headerKey = ServletUtil.getHeader(((ServletServerHttpRequest) request).getServletRequest(), KEY_VALUE_KEY, CharsetUtil.UTF_8);
//如果是自定义表单 需要获取 工作流数据
if (StrUtil.isNotBlank(headerFormId)) {
if (ClassUtil.equals(((R) body).getData().getClass(), PageOutput.class.getName(), true)) {
return formTemplateGetWorkflowDataHandler(body, headerFormId, headerKey);
}
}
String formId = ((ServletServerHttpRequest) request).getServletRequest().getParameter(FORM_ID_KEY);
if (StrUtil.isBlank(formId)) {
return body;
}
String key = ((ServletServerHttpRequest) request).getServletRequest().getParameter(KEY_VALUE_KEY);
if (StrUtil.isBlank(key)) {
return body;
}
//如果是代码生成器表单 需要获取 工作流数据
return codeGetWorkflowDataHandler(body, formId, key);
}
private Object formTemplateGetWorkflowDataHandler(Object body, String headerFormId, String headerKey) {
List<Object> keyValueFormList = new ArrayList<>();
List<?> listData = null;
if (ClassUtil.equals(((R) body).getData().getClass(), PageOutput.class.getName(), true)) {
Object result = Convert.convert(R.class, body).getData();
PageOutput<?> pageOutput = Convert.convert(PageOutput.class, result);
listData = pageOutput.getList();
if (listData == null || listData.size() == 0) {
return body;
}
} else if (ClassUtil.equals(((R) body).getData().getClass(), ArrayList.class.getName(), true)) {
Object result = Convert.convert(R.class, body).getData();
listData = Convert.convert(List.class, result);
if (listData == null || listData.size() == 0) {
return body;
}
} else {
return body;
}
for (Object data : listData) {
Entity rowValue = Convert.convert(Entity.class, data);
Object keyValue = rowValue.get(headerKey);
keyValueFormList.add(keyValue);
}
WorkflowSchema schema = workflowSchemaClient.getWorkflowSchemaByFormIdFeign(Long.parseLong(headerFormId));
//获取到所有关联的 流程id
List<WorkflowFormRelation> relations = formRelationClient.getWorkflowFormRelationBatchFeign(Long.parseLong(headerFormId), keyValueFormList);
Set<String> processIds = relations.stream().map(WorkflowFormRelation::getProcessId).collect(Collectors.toSet());
List<HistoryProcessInstanceVo> processInstanceList = historyClient.getProcessInstanceListFeign(processIds);
//找到当前所有流程的 所在执行的任务list
String[] processIdArrays = relations.stream().map(WorkflowFormRelation::getProcessId).toArray(String[]::new);
List<TaskInstanceVo> activeTaskInstanceList = taskClient.getActiveTaskInstanceListFeign(processIdArrays);
for (Object data : listData) {
Entity rowValue = Convert.convert(Entity.class, data);
Object keyValue = rowValue.get(headerKey);
Optional<WorkflowFormRelation> thisRelationOp = relations.stream().filter(x -> x.getFormKeyValue().equals(keyValue)).findFirst();
WorkflowListResult workflowListResult = new WorkflowListResult();
thisRelationOp.ifPresent(r -> {
HistoryProcessInstanceVo historicProcessInstance = processInstanceList.stream().filter(p -> p.getId().equals(r.getProcessId())).findFirst().orElse(null);
if (ObjectUtil.isNotNull(historicProcessInstance)) {
assert historicProcessInstance != null;
workflowListResult.setStatus(historicProcessInstance.getState());
workflowListResult.setProcessId(historicProcessInstance.getId());
}
//获取到当前数据 所关联的 的流程 正在执行的 任务
List<TaskInstanceVo> thisDataTask = activeTaskInstanceList.stream().filter(x -> x.getProcessInstanceId().equals(r.getProcessId())).collect(Collectors.toList());
if (thisDataTask.size() > 0) {
workflowListResult.setTaskIds(thisDataTask.stream().map(TaskInstanceVo::getId).collect(Collectors.toList()));
}
});
if (ObjectUtil.isNotNull(schema)) {
workflowListResult.setSchemaId(schema.getId());
} else {
workflowListResult.setEnabled(Boolean.FALSE);
}
rowValue.set(RESULT_KEY, workflowListResult);
}
return body;
}
private Object codeGetWorkflowDataHandler(Object body, String formId, String key) {
WorkflowSchema schema = workflowSchemaClient.getWorkflowSchemaByFormIdFeign(Long.parseLong(formId));
List<Object> keyValueList = new ArrayList<>();
List<?> listData;
//判断是否为分页返回值
boolean isPage = ClassUtil.equals(((R) body).getData().getClass(), PageOutput.class.getName(), true);
R r = Convert.convert(R.class, body);
Object resultData = r.getData();
if (isPage) {
PageOutput<?> pageOutput = Convert.convert(PageOutput.class, resultData);
listData = pageOutput.getList();
if (listData == null || listData.size() == 0) {
return body;
}
for (Object data : listData) {
Object keyValue = ReflectUtil.getFieldValue(data, key);
keyValueList.add(keyValue.toString());
}
}
//判断是否为不分页列表返回值
else if (ClassUtil.equals(((R) body).getData().getClass(), ArrayList.class.getName(), true)) {
listData = Convert.convert(List.class, resultData);
if (listData == null || listData.size() == 0) {
return body;
}
for (Object data : listData) {
Object keyValue = ReflectUtil.getFieldValue(data, key);
keyValueList.add(keyValue.toString());
}
} else {
return body;
}
//获取到所有关联的 流程id
List<WorkflowFormRelation> relations = formRelationClient.getWorkflowFormRelationBatchFeign(Long.parseLong(formId), keyValueList);
// if (relations.size() == 0) {
// return body;
// }
Set<String> processIds = relations.stream().map(WorkflowFormRelation::getProcessId).collect(Collectors.toSet());
List<HistoryProcessInstanceVo> processInstanceList = historyClient.getProcessInstanceListFeign(processIds);
//找到当前所有流程的 所在执行的任务list
String[] processIdArrays = relations.stream().map(WorkflowFormRelation::getProcessId).toArray(String[]::new);
List<TaskInstanceVo> activeTaskInstanceList = taskClient.getActiveTaskInstanceListFeign(processIdArrays);
ClassPool pool = new ClassPool(true);
pool.appendClassPath(new LoaderClassPath(Thread.currentThread().getContextClassLoader()));
List<Object> result = new ArrayList<>();
try {
CtClass ctClass = pool.get(listData.get(0).getClass().getName());
try {
CtField workflowField = CtField.make(FIELD_STRING, ctClass);
ctClass.addField(workflowField);
CtMethod workflowMethod = CtMethod.make(GET_MOTHOD_STRING, ctClass);
ctClass.addMethod(workflowMethod);
} catch (CannotCompileException e) {
e.printStackTrace();
}
Constructor<?> declaredConstructor;
if (!cacheClass.containsKey(ctClass.getName())) {
declaredConstructor = ctClass.toClass().getDeclaredConstructor();
cacheClass.put(ctClass.getName(), declaredConstructor);
} else {
declaredConstructor = cacheClass.get(ctClass.getName());
}
for (Object data : listData) {
Object keyValue = ReflectUtil.getFieldValue(data, key);
//keyValue.toString是采购申请时使用的因为采购表存的id是Long类型的
Optional<WorkflowFormRelation> thisRelationOp = relations.stream().filter(x -> x.getFormKeyValue().equals(keyValue) || x.getFormKeyValue().equals(keyValue.toString())).findFirst();
Object newObject = declaredConstructor.newInstance();
result.add(newObject);
BeanUtil.copyProperties(data, newObject);
WorkflowListResult workflowListResult = new WorkflowListResult();
thisRelationOp.ifPresent(relation -> {
HistoryProcessInstanceVo historicProcessInstance = processInstanceList.stream().filter(p -> p.getId().equals(relation.getProcessId())).findFirst().orElse(null);
if (ObjectUtil.isNotNull(historicProcessInstance)) {
assert historicProcessInstance != null;
workflowListResult.setStatus(historicProcessInstance.getState());
workflowListResult.setProcessId(historicProcessInstance.getId());
}
//获取到当前数据 所关联的 的流程 正在执行的 任务
List<TaskInstanceVo> thisDataTask = activeTaskInstanceList.stream().filter(x -> x.getProcessInstanceId().equals(relation.getProcessId())).collect(Collectors.toList());
if (thisDataTask.size() > 0) {
workflowListResult.setTaskIds(thisDataTask.stream().map(TaskInstanceVo::getId).collect(Collectors.toList()));
}
});
if (ObjectUtil.isNotNull(schema)) {
workflowListResult.setSchemaId(schema.getId());
} else {
workflowListResult.setEnabled(Boolean.FALSE);
}
ReflectUtil.setFieldValue(newObject, RESULT_KEY, workflowListResult);
}
ctClass.detach();
} catch (NotFoundException | CannotCompileException | NoSuchMethodException | InvocationTargetException |
InstantiationException | IllegalAccessException e) {
e.printStackTrace();
throw new MyException("表单发起流程数据转换出错,请联系管理员!");
}
if (isPage) {
((PageOutput) (r.getData())).setList(result);
} else {
r.put("data", result);
}
return body;
}
}