Files
geg-gas-pcitc/xjrsoft-common/xjrsoft-common-advice/src/main/java/com.xjrsoft.advice/WorkflowResponseBodyAdvice.java

329 lines
14 KiB
Java
Raw Normal View History

2025-02-08 17:51:37 +08:00
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;
}
}