package org.springblade.flow.engine.custom.behavior.impl;

import static org.springblade.flow.base.util.BpmnModelUtils.getAttributeValueByTaskDefinitionKey;
import static org.springblade.flow.base.util.BpmnModelUtils.getBpmnModelMainProcess;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.APPLY_USER_ID;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.APPLY_USER_NAME;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.BILL_CODE;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.BUSINESS_KEY;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.BUSINESS_TITLE;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.CALL_ACTIVITY_FLAG;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.FLOW_ENGINE_ID;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.FLOW_URGENT;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.FORM_INFO_JSON;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.PROCESS_CATEGORY;
import static org.springblade.flow.engine.custom.constants.GlobalProcessVariableConstants.PROCESS_STATUS;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.CallActivity;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.IOParameter;
import org.flowable.bpmn.model.Process;
import org.flowable.common.engine.api.FlowableException;
import org.flowable.common.engine.api.delegate.Expression;
import org.flowable.common.engine.api.delegate.event.FlowableEngineEventType;
import org.flowable.common.engine.api.delegate.event.FlowableEventDispatcher;
import org.flowable.common.engine.api.scope.ScopeTypes;
import org.flowable.common.engine.impl.el.ExpressionManager;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.event.impl.FlowableEventBuilder;
import org.flowable.engine.impl.bpmn.behavior.CallActivityBehavior;
import org.flowable.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.EntityLinkUtil;
import org.flowable.engine.impl.util.ProcessDefinitionUtil;
import org.flowable.engine.interceptor.StartSubProcessInstanceAfterContext;
import org.flowable.engine.interceptor.StartSubProcessInstanceBeforeContext;
import org.flowable.engine.repository.ProcessDefinition;
import org.springblade.flow.base.UserInfo;
import org.springblade.flow.base.service.BillRuleService;
import org.springblade.flow.base.util.FlowDataUtil;
import org.springblade.flow.base.util.FlowNature;
import org.springblade.flow.base.util.FormCloumnUtil;
import org.springblade.flow.base.util.SpringContextHolder;
import org.springblade.flow.database.model.DbLinkEntity;
import org.springblade.flow.engine.assembly.CallActivityExPropertyDTO;
import org.springblade.flow.engine.assembly.GlobalExPropertyDTO;
import org.springblade.flow.engine.custom.constants.BasicActivitiConstants;
import org.springblade.flow.engine.custom.variables.entity.FormDataInfo;
import org.springblade.flow.engine.entity.FlowEngineEntity;
import org.springblade.flow.engine.entity.FlowTaskEntity;
import org.springblade.flow.engine.enums.FlowTaskStatusEnum;
import org.springblade.flow.engine.model.flowengine.FlowModel;
import org.springblade.flow.engine.model.flowengine.shuntjson.childnode.FlowAssignModel;
import org.springblade.flow.engine.model.flowtask.FlowTableModel;
import org.springblade.flow.engine.service.FlowEngineService;
import org.springblade.flow.exception.WorkFlowException;
import org.springblade.flow.model.FormAllModel;
import org.springblade.flow.model.FormEnum;
import org.springblade.flow.model.visiual.FormDataModel;
import org.springblade.flow.model.visiual.JnpfKeyConsts;
import org.springblade.flow.model.visiual.fields.FieldsModel;
import org.springblade.flow.permission.service.User4FlowService;
import org.springblade.flow.util.JsonUtil;
import org.springblade.flow.util.RandomUtil;
import org.springblade.flow.util.ReflectionUtil;
import org.springblade.flow.util.StringUtil;
import org.springblade.flow.util.UserProvider;
import org.springblade.flow.util.context.SpringContext;
import org.springblade.flow.visual.onlinedev.common.dynamic.DataSourceService;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.map.MapUtil;
import lombok.extern.slf4j.Slf4j;

/**
 * @author LoveMyOrange
 * @create 2022-02-02 12:08
 * @desc 子流程的bug  为以后接入子流程做准备
 */
@Slf4j
public class CustomCallActivityActivityBehavior extends CallActivityBehavior {

	private static final long serialVersionUID = 1L;

	public CustomCallActivityActivityBehavior(CallActivity callActivity) {
		super(callActivity);
	}

	@Override
	public void execute(DelegateExecution execution) {
		String subProcessBusinessKey = RandomUtil.uuId();
//        super.execute(execution);
		// 项目接入子流程的准备
		FlowEngineService flowEngineService = SpringContextHolder.getBean(FlowEngineService.class);
		UserProvider userProvider = SpringContextHolder.getBean(UserProvider.class);
		User4FlowService userService = SpringContextHolder.getBean(User4FlowService.class);
		//
		String currentActivityId = execution.getCurrentActivityId();
		CallActivity callActivity = (CallActivity) execution.getCurrentFlowElement();
		// 1.1获取主流程变量信息
		DelegateExecution parent = execution.getParent();
		Map<String, Object> processVariables = parent.getVariables();
		FormDataInfo formDataInfo = MapUtil.get(processVariables, FORM_INFO_JSON, FormDataInfo.class);
		String formDataJson = formDataInfo.getFormDataJson();
		HashMap<String, Object> paramMap = JSONObject.parseObject(formDataJson,
				new TypeReference<HashMap<String, Object>>() {
				});
		// 1.2 获取主流程的数据传递规则
		Process process = getBpmnModelMainProcess(execution.getProcessDefinitionId());
		String taskProperty = getAttributeValueByTaskDefinitionKey(process, callActivity.getId(), "callActivity");
		CallActivityExPropertyDTO callActivityExPropertyDTO = JSONObject.parseObject(taskProperty.toString(),
				new TypeReference<CallActivityExPropertyDTO>() {
				});
		List<FlowAssignModel> assignList = callActivityExPropertyDTO.getAssignList();

		String calledElement = callActivity.getCalledElement();

		// 设置子流程的信息
		String flowId = calledElement.replace(BasicActivitiConstants.activitiPrefix, "");
		FlowEngineEntity flowEngineEntity = flowEngineService.getInfoByEnCode(flowId);
//
		FlowModel flowModel = new FlowModel();
		// 主流程的表单数据
		flowModel.setFormData(paramMap);
		flowModel.setProcessId(subProcessBusinessKey);
		// 做出来子流程的表单数据
		Map<String, Object> data = childData(flowEngineEntity, flowModel, assignList);
		UserInfo userInfo = userProvider.get();
		String title = userInfo.getUserName() + "的" + flowEngineEntity.getFullName() + "(子流程)";

		handleCallActivityInfo(execution, subProcessBusinessKey, title);

		// 组装数据计算流水号
		FlowModel nextFlowModel = this.assignment(data, flowEngineEntity, title);
		nextFlowModel.setProcessId(subProcessBusinessKey);
		nextFlowModel.setUserId(userInfo.getUserId());
		nextFlowModel.setFlowTitle(title);
		data.put("flowTitle", title);// 流程标题
		data.put("flowUrgent", 0);// 流程紧急程度
		nextFlowModel.setFormData(data);
		nextFlowModel.setFlowId(flowEngineEntity.getId());

		ExecutionEntity executionEntity = (ExecutionEntity) execution;
		// 获取到了调用活动的相关信息
		ExecutionEntity subProcessInstance = executionEntity.getSubProcessInstance();
		String subProcessDefinitionId = subProcessInstance.getProcessDefinitionId();
		Process subProcess = getBpmnModelMainProcess(subProcessDefinitionId);
		String property = getAttributeValueByTaskDefinitionKey(subProcess, "", "global");
		GlobalExPropertyDTO exPropertyDTO = JSONObject.parseObject(property, new TypeReference<GlobalExPropertyDTO>() {
		});

		FlowTaskEntity flowTaskEntity = new FlowTaskEntity();
		flowTaskEntity.setFlowForm(exPropertyDTO.getFormData());
		flowTaskEntity.setProcessId(nextFlowModel.getProcessId());
		flowTaskEntity.setFieldSet(exPropertyDTO.getFieldSet());
		flowTaskEntity.setProcessInstanceId(subProcessInstance.getProcessInstanceId());
		this.createData(flowEngineEntity, flowTaskEntity, nextFlowModel);
//
		Map<String, Object> variablesMap = new HashMap<>();
		// 设置流程需要的变量?
		variablesMap.put(BILL_CODE, flowModel.getBillNo());// 单据控件的编码
		variablesMap.put(FLOW_URGENT, flowModel.getFlowUrgent());// 流程实例紧急程度
		variablesMap.put(FLOW_ENGINE_ID, flowEngineEntity.getId());// 流程引擎表id
		variablesMap.put(PROCESS_STATUS, FlowTaskStatusEnum.Handle.getCode());// 流程状态
		variablesMap.put(APPLY_USER_ID, userInfo.getUserId());//
		variablesMap.put(APPLY_USER_NAME, userInfo.getUserName());
		variablesMap.put(PROCESS_CATEGORY, flowEngineEntity.getCategory());// 流程分类
		variablesMap.put(BUSINESS_TITLE, title);// 流程标题
		variablesMap.put(BUSINESS_KEY, flowModel.getProcessId());// 业务表的主键
		RuntimeService runtimeService = SpringContextHolder.getBean(RuntimeService.class);
		variablesMap.put(CALL_ACTIVITY_FLAG, true);// 当前流程是在子流程中的标志
		runtimeService.setVariables(subProcessInstance.getProcessInstanceId(), variablesMap);
//        runtimeService.setProcessInstanceName(subProcessInstance.getProcessInstanceId(),flowModel.getFlowTitle());
	}

	private void handleCallActivityInfo(DelegateExecution execution, String subProcessBusinessKey,
			String businessTitle) {

		// 官方处理
		// 1>获取到当前执行实例
		ExecutionEntity executionEntity = (ExecutionEntity) execution;
		// 2>获取到当前元素
		CallActivity callActivity = (CallActivity) executionEntity.getCurrentFlowElement();
		// 3>获取到命令上下文
		CommandContext commandContext = CommandContextUtil.getCommandContext();
		// 4>获取到流程引擎配置类
		ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil
				.getProcessEngineConfiguration(commandContext);
		// 5>通过调用活动元素里面配的是 通过流程定义id找到流程定义还是流程key找到 流程定义对象
		ProcessDefinition processDefinition = getProcessDefinition(execution, callActivity, processEngineConfiguration);
		// 6>获取Process元素对象
		Process subProcess = ProcessDefinitionUtil.getProcess(processDefinition.getId());
		// 7>如果没获取到报错
		if (subProcess == null) {
			throw new FlowableException("Cannot start a sub process instance. Process model "
					+ processDefinition.getName() + " (id = " + processDefinition.getId() + ") could not be found");
		}
		// 8>获取调用活动的第一个节点
		FlowElement initialFlowElement = subProcess.getInitialFlowElement();
		if (initialFlowElement == null) {
			throw new FlowableException("No start element found for process definition " + processDefinition.getId());
		}
		// 9>判断流程定义是不是挂起的
		if (ProcessDefinitionUtil.isProcessDefinitionSuspended(processDefinition.getId())) {
			throw new FlowableException("Cannot start process instance. Process definition "
					+ processDefinition.getName() + " (id = " + processDefinition.getId() + ") is suspended");
		}
		// 10>获取到执行实例表的Mapper对象
		ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
		// 11获取到表达式管理器
		ExpressionManager expressionManager = processEngineConfiguration.getExpressionManager();
		// 12>获取 节点上配置的 businessKey
		String businessKey = null;
//        if (!StringUtils.isEmpty(callActivity.getBusinessKey())) {
//            Expression expression = expressionManager.createExpression(callActivity.getBusinessKey());
//            businessKey = expression.getValue(execution).toString();
//
//        } else if (callActivity.isInheritBusinessKey()) {
//            ExecutionEntity processInstance = executionEntityManager.findById(execution.getProcessInstanceId());
//            businessKey = processInstance.getBusinessKey();
//        }

		// 13扩展> 目前业务绝对不会进入上述 if 和else if 我们应该在这里把子业务的businessKey set进来
		businessKey = subProcessBusinessKey;

		// 14>流程变量
		Map<String, Object> variables = new HashMap<>();
		// 15>准备启动调用活动
		StartSubProcessInstanceBeforeContext instanceBeforeContext = new StartSubProcessInstanceBeforeContext(
				businessKey, callActivity.getProcessInstanceName(), variables, executionEntity,
				callActivity.getInParameters(), callActivity.isInheritVariables(), initialFlowElement.getId(),
				initialFlowElement, subProcess, processDefinition);

		if (processEngineConfiguration.getStartProcessInstanceInterceptor() != null) {
			processEngineConfiguration.getStartProcessInstanceInterceptor()
					.beforeStartSubProcessInstance(instanceBeforeContext);
		}
		// 16>插入到DB
		ExecutionEntity subProcessInstance = processEngineConfiguration.getExecutionEntityManager()
				.createSubprocessInstance(instanceBeforeContext.getProcessDefinition(),
						instanceBeforeContext.getCallActivityExecution(), instanceBeforeContext.getBusinessKey(),
						instanceBeforeContext.getInitialActivityId());
		// 17>转发事件
		FlowableEventDispatcher eventDispatcher = processEngineConfiguration.getEventDispatcher();
		if (eventDispatcher != null && eventDispatcher.isEnabled()) {
			processEngineConfiguration.getEventDispatcher().dispatchEvent(
					FlowableEventBuilder.createEntityEvent(FlowableEngineEventType.PROCESS_CREATED, subProcessInstance),
					processEngineConfiguration.getEngineCfgKey());
		}

		// 18>先把调用活动中的 dataObject设置到变量中
		subProcessInstance.setVariables(processDataObjects(subProcess.getDataObjects()));
		// 19>判断是否继承父流程变量
		if (instanceBeforeContext.isInheritVariables()) {
			Map<String, Object> executionVariables = execution.getVariables();
			for (Map.Entry<String, Object> entry : executionVariables.entrySet()) {
				instanceBeforeContext.getVariables().put(entry.getKey(), entry.getValue());
			}
		}

		// 20>处理输入变量
		for (IOParameter inParameter : instanceBeforeContext.getInParameters()) {

			Object value = null;
			if (StringUtils.isNotEmpty(inParameter.getSourceExpression())) {
				Expression expression = expressionManager.createExpression(inParameter.getSourceExpression().trim());
				value = expression.getValue(execution);

			} else {
				value = execution.getVariable(inParameter.getSource());
			}

			String variableName = null;
			if (StringUtils.isNotEmpty(inParameter.getTargetExpression())) {
				Expression expression = expressionManager.createExpression(inParameter.getTargetExpression());
				Object variableNameValue = expression.getValue(execution);
				if (variableNameValue != null) {
					variableName = variableNameValue.toString();
				} else {
					log.warn(
							"In parameter target expression {} did not resolve to a variable name, this is most likely a programmatic error",
							inParameter.getTargetExpression());
				}

			} else if (StringUtils.isNotEmpty(inParameter.getTarget())) {
				variableName = inParameter.getTarget();

			}

			instanceBeforeContext.getVariables().put(variableName, value);
		}

		if (!instanceBeforeContext.getVariables().isEmpty()) {
			initializeVariables(subProcessInstance, instanceBeforeContext.getVariables());
		}

		// Process instance name is resolved after setting the variables on the process
		// instance, so they can be used in the expression
		// 21>设置流程实例名称
		String processInstanceName = null;
//        if (StringUtils.isNotEmpty(instanceBeforeContext.getProcessInstanceName())) {
//            Expression processInstanceNameExpression = expressionManager.createExpression(instanceBeforeContext.getProcessInstanceName());
//            processInstanceName = processInstanceNameExpression.getValue(subProcessInstance).toString();
//            subProcessInstance.setName(processInstanceName);
//        }
		processInstanceName = businessTitle;
		subProcessInstance.setName(processInstanceName);
		// 22>转发事件
		if (eventDispatcher != null && eventDispatcher.isEnabled()) {
			eventDispatcher.dispatchEvent(FlowableEventBuilder
					.createEntityEvent(FlowableEngineEventType.ENTITY_INITIALIZED, subProcessInstance),
					processEngineConfiguration.getEngineCfgKey());
		}
		// 23>act_ru_entitylink表数据
		if (processEngineConfiguration.isEnableEntityLinks()) {
			EntityLinkUtil.createEntityLinks(execution.getProcessInstanceId(), executionEntity.getId(),
					callActivity.getId(), subProcessInstance.getId(), ScopeTypes.BPMN);
		}
		// 24>处理变量
		if (StringUtils.isNotEmpty(callActivity.getProcessInstanceIdVariableName())) {
			Expression expression = expressionManager.createExpression(callActivity.getProcessInstanceIdVariableName());
			String idVariableName = (String) expression.getValue(execution);
			if (StringUtils.isNotEmpty(idVariableName)) {
				execution.setVariable(idVariableName, subProcessInstance.getId());
			}
		}

		// Create the first execution that will visit all the process definition
		// elements
		ExecutionEntity subProcessInitialExecution = executionEntityManager.createChildExecution(subProcessInstance);
		subProcessInitialExecution.setCurrentFlowElement(instanceBeforeContext.getInitialFlowElement());

		if (processEngineConfiguration.getStartProcessInstanceInterceptor() != null) {
			StartSubProcessInstanceAfterContext instanceAfterContext = new StartSubProcessInstanceAfterContext(
					subProcessInstance, subProcessInitialExecution, instanceBeforeContext.getVariables(),
					instanceBeforeContext.getCallActivityExecution(), instanceBeforeContext.getInParameters(),
					instanceBeforeContext.getInitialFlowElement(), instanceBeforeContext.getProcess(),
					instanceBeforeContext.getProcessDefinition());

			processEngineConfiguration.getStartProcessInstanceInterceptor()
					.afterStartSubProcessInstance(instanceAfterContext);
		}

		processEngineConfiguration.getActivityInstanceEntityManager().recordSubProcessInstanceStart(executionEntity,
				subProcessInstance);

		CommandContextUtil.getAgenda().planContinueProcessOperation(subProcessInitialExecution);

		if (eventDispatcher != null && eventDispatcher.isEnabled()) {
			eventDispatcher.dispatchEvent(FlowableEventBuilder.createProcessStartedEvent(subProcessInitialExecution,
					instanceBeforeContext.getVariables(), false), processEngineConfiguration.getEngineCfgKey());
		}

	}

	/**
	 * 插入数据
	 *
	 * @param engine    引擎
	 * @param flowModel 提交数据
	 */
	private Map<String, Object> createData(FlowEngineEntity engine, FlowTaskEntity taskEntity, FlowModel flowModel)
			throws WorkFlowException {
		DataSourceService dblinkService = SpringContextHolder.getBean(DataSourceService.class);
		FlowDataUtil flowDataUtil = SpringContextHolder.getBean(FlowDataUtil.class);
		RuntimeService runtimeService = SpringContextHolder.getBean(RuntimeService.class);
		Map<String, Object> resultData = new HashMap<>(16);
		try {
			Map<String, Object> data = flowModel.getFormData();
			if (FlowNature.CUSTOM.equals(engine.getFormType())) {
				List<FlowTableModel> tableList = JsonUtil.getJsonToList(engine.getTables(), FlowTableModel.class);
				// 获取属性
				DbLinkEntity dbLink = null;
				if (StringUtil.isNotEmpty(engine.getDbLinkId())) {
					dbLink = dblinkService.getInfo(engine.getDbLinkId());
				}
				FormDataModel formData = JsonUtil.getJsonToBean(taskEntity.getFlowForm(), FormDataModel.class);
				List<FieldsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieldsModel.class);
				if (StringUtil.isNotEmpty(flowModel.getId())) {
					// 更新
					resultData = flowDataUtil.update(data, list, tableList, taskEntity.getProcessId(), dbLink);
				} else {
					// 新增
					resultData = flowDataUtil.create(data, list, tableList, taskEntity.getProcessId(),
							new HashMap<>(16), dbLink);
				}

				FormDataInfo formDataInfo = new FormDataInfo();
				formDataInfo.setFormDataJson(JsonUtil.getObjectToString(resultData));

				Map<String, Object> variablesMap = new HashMap<>();
				HashMap<String, Object> sequenceFlowConditionMap = new HashMap<>();
				variablesMap.put(FORM_INFO_JSON, formDataInfo);
				Set<String> fieldSet = taskEntity.getFieldSet();
				if (fieldSet != null && !fieldSet.isEmpty()) {
					Set<String> set = resultData.keySet();
					Collection<String> intersection = CollectionUtil.intersection(set, fieldSet);
					for (String s : set) {
						if (CollectionUtil.contains(intersection, s)) {
							sequenceFlowConditionMap.put(s, resultData.get(s));
						}
					}
					// 需要进行条件判断的字段放入流程变量
					variablesMap.putAll(sequenceFlowConditionMap);
				}

				runtimeService.setVariables(taskEntity.getProcessInstanceId(), variablesMap);

			} else {
				// 系统表单
				String dataAll = JsonUtil.getObjectToString(data);
				if (engine.getType() != 1) {
					String coed = engine.getEnCode();
					this.formData(coed, flowModel.getProcessId(), dataAll);

					Map<String, Object> variablesMap = new HashMap<>();
					FormDataInfo formDataInfo = new FormDataInfo();
					formDataInfo.setFormDataJson(dataAll);
					variablesMap.put(FORM_INFO_JSON, formDataInfo);
					HashMap<String, Object> sequenceFlowConditionMap = new HashMap<>();
					Set<String> fieldSet = taskEntity.getFieldSet();
					if (fieldSet != null && !fieldSet.isEmpty()) {
						Set<String> set = data.keySet();
						Collection<String> intersection = CollectionUtil.intersection(set, fieldSet);
						for (String s : set) {
							if (CollectionUtil.contains(intersection, s)) {
								sequenceFlowConditionMap.put(s, data.get(s));
							}
						}
						// 需要进行条件判断的字段放入流程变量
						variablesMap.putAll(sequenceFlowConditionMap);
					}
					runtimeService.setVariables(taskEntity.getProcessInstanceId(), variablesMap);

				}
			}
		} catch (Exception e) {
			throw new WorkFlowException("新增数据失败");
		}
		return resultData;
	}

	/**
	 * 修改系统表单数据
	 *
	 * @param code 编码
	 * @param id   主键id
	 * @param data 数据
	 * @throws WorkFlowException
	 */
	private void formData(String code, String id, String data) throws WorkFlowException {
		Map<String, Object> objectData = JsonUtil.stringToMap(data);
		if (objectData.size() > 0) {
			try {
				Class[] types = new Class[] { String.class, String.class };
				Object[] datas = new Object[] { id, data };
				Object service = SpringContext.getBean(code + "ServiceImpl");
				ReflectionUtil.invokeMethod(service, "data", types, datas);
			} catch (Exception e) {
				throw new WorkFlowException("系统表单反射失败");
			}
		}
	}

	/**
	 * 赋值
	 *
	 * @param data     数据
	 * @param engine   引擎
	 * @return
	 */
	private FlowModel assignment(Map<String, Object> data, FlowEngineEntity engine, String title) {
		BillRuleService billRuleService = SpringContextHolder.getBean(BillRuleService.class);
		FlowModel flowModel = new FlowModel();
		String billNo = "单据规则不存在";
		if (FlowNature.CUSTOM.equals(engine.getFormType())) {
			FormDataModel formData = JsonUtil.getJsonToBean(engine.getFormData(), FormDataModel.class);
			List<FieldsModel> list = JsonUtil.getJsonToList(formData.getFields(), FieldsModel.class);
			List<FormAllModel> formAllModel = new ArrayList<>();
			FormCloumnUtil.recursionForm(list, formAllModel);
			List<FormAllModel> mastForm = formAllModel.stream()
					.filter(t -> FormEnum.mast.getMessage().equals(t.getJnpfKey())).collect(Collectors.toList());
			FormAllModel formModel = mastForm.stream()
					.filter(t -> JnpfKeyConsts.BILLRULE
							.equals(t.getFormColumnModel().getFieLdsModel().getConfig().getJnpfKey()))
					.findFirst().orElse(null);
			try {
				if (flowModel != null) {
					FieldsModel fieLdsModel = formModel.getFormColumnModel().getFieLdsModel();
					String ruleKey = fieLdsModel.getConfig().getRule();
					billNo = billRuleService.getBillNumber(ruleKey, false);
				}
			} catch (Exception e) {
				throw new WorkFlowException("处理失败");
			}
		}
		flowModel.setFormData(data);
		flowModel.setBillNo(billNo);
		flowModel.setFlowTitle(title);
		return flowModel;
	}

	/**
	 * 子表表单赋值
	 *
	 * @param engine     子表引擎
	 * @param flowModel  提交数据
	 * @param assignList 数据传递
	 * @return
	 */
	private Map<String, Object> childData(FlowEngineEntity engine, FlowModel flowModel,
			List<FlowAssignModel> assignList) {
		Map<String, Object> result = new HashMap<>(16);
		if (engine != null) {
			Map<String, Object> formData = flowModel.getFormData();
			if (assignList != null) {
				for (FlowAssignModel assignMode : assignList) {
					String childField = assignMode.getChildField();
					String parentField = assignMode.getParentField();
					result.put(childField, formData.get(parentField));
				}
			}
		}
		return result;
	}

}
