package ink.wgink.module.activiti.service.oa.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import ink.wgink.common.base.DefaultBaseService;
import ink.wgink.exceptions.ParamsException;
import ink.wgink.exceptions.SearchException;
import ink.wgink.exceptions.base.SystemException;
import ink.wgink.module.activiti.enums.oa.SelectAssigneeTypeEnum;
import ink.wgink.module.activiti.enums.oa.TaskCommentTypeEnum;
import ink.wgink.module.activiti.enums.oa.field.FieldEditRecordEnum;
import ink.wgink.module.activiti.pojo.bos.oa.OaFormReportUnWantedValueBO;
import ink.wgink.module.activiti.pojo.bos.oa.TaskCommentBO;
import ink.wgink.module.activiti.pojo.vos.oa.OaDocNoVO;
import ink.wgink.module.activiti.pojo.vos.oa.OaFormReportRecordFieldVO;
import ink.wgink.module.activiti.pojo.vos.oa.UpdateTaskAssigneeVO;
import ink.wgink.module.activiti.service.activiti.IActivitiModelService;
import ink.wgink.module.activiti.service.oa.IOaCcService;
import ink.wgink.module.activiti.service.oa.IOaFormReportService;
import ink.wgink.module.form.enums.docno.DocNoTypeEnum;
import ink.wgink.module.form.pojo.pos.docno.DocNoPO;
import ink.wgink.module.form.service.design.IFormDesignService;
import ink.wgink.module.form.service.design.IFormFieldService;
import ink.wgink.module.form.service.docno.IDocNoService;
import ink.wgink.module.form.service.report.IFormReportService;
import ink.wgink.pojo.ListPage;
import ink.wgink.pojo.app.AppTokenUser;
import ink.wgink.pojo.bos.UserInfoBO;
import ink.wgink.pojo.result.SuccessResultList;
import ink.wgink.util.date.DateUtil;
import org.activiti.bpmn.model.*;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @ClassName: OaFormReportServiceImpl
 * @Description: oa表单上报
 * @Author: wanggeng
 * @Date: 2022/3/22 22:05
 * @Version: 1.0
 */
@Service
public class OaFormReportServiceImpl extends DefaultBaseService implements IOaFormReportService {

    @Autowired
    private IFormFieldService formFieldService;
    @Autowired
    private IFormReportService formReportService;
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private IdentityService identityService;
    @Autowired
    private ManagementService managementService;
    @Autowired
    private IActivitiModelService activitiModelService;
    @Autowired
    private IOaCcService formCcService;
    @Autowired
    private IDocNoService docNoService;

    @Override
    public void save(String processDefinitionId, String formCode, Integer formVersion, Map<String, Object> params) {
        UserInfoBO currentUser = securityComponent.getCurrentUser();
        saveByUserIdAndUserName(currentUser.getUserId(), currentUser.getUserName(), processDefinitionId, formCode, formVersion, params);
    }

    @Override
    public void saveByToken(String token, String processDefinitionId, String formCode, Integer formVersion, Map<String, Object> params) {
        AppTokenUser appTokenUser = getAppTokenUser(token);
        saveByUserIdAndUserName(appTokenUser.getId(), appTokenUser.getName(), processDefinitionId, formCode, formVersion, params);
    }

    @Override
    public void saveByUserIdAndUserName(String userId, String userName, String processDefinitionId, String formCode, Integer formVersion, Map<String, Object> params) {
        OaFormReportUnWantedValueBO oaFormReportUnWantedValueBO = getOaFormReportUnWantedValue(params);
        LOG.debug("设置文号");
        setDocNo(oaFormReportUnWantedValueBO.getOaDocNos(), formCode, formVersion, params);
        LOG.debug("保存表单");
        String uid = formReportService.saveByUserIdAndReturnId(userId, formCode, formVersion, params);
        LOG.debug("定义流程发起人");
        Map<String, Object> variables = getHashMap(2);
        variables.put(KEY_FORM_CODE, formCode);
        variables.put(KEY_FORM_VERSION, formVersion);
        variables.put(KEY_REPORT_UID, uid);
        variables.put(KEY_START_ASSIGNEE_USER, userId);
        identityService.setAuthenticatedUserId(userId);
        LOG.debug("发起流程");
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, variables);
        LOG.debug("更新表单数据的流程实例ID");
        formReportService.updateProcessInstanceId(formCode, formVersion, uid, processInstance.getProcessInstanceId());
        LOG.debug("执行第一个节点");
        Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskCandidateOrAssigned(userId).singleResult();
        if (task == null) {
            throw new SearchException("任务不存在");
        }
        // 网关条件
        if (!StringUtils.isBlank(oaFormReportUnWantedValueBO.getExc())) {
            params.put(IActivitiModelService.EXCLUSIVE_GATEWAY_CONDITION_KEY, oaFormReportUnWantedValueBO.getExc());
        }
        if (!oaFormReportUnWantedValueBO.getNextEndEvent()) {
            setFormReportAssignee(oaFormReportUnWantedValueBO.getSelectType(), oaFormReportUnWantedValueBO.getAssignees(), params);
        }
        setRecordFields(task.getProcessInstanceId(), task.getId(), oaFormReportUnWantedValueBO.getRecordFields(), userId, userName, params);
        // 保存表单日志
        taskService.complete(task.getId(), params);
        LOG.debug("保存抄送");
        formCcService.saveByUserId(userId, formCode, formVersion, processInstance.getProcessInstanceId(), uid, oaFormReportUnWantedValueBO.getCcs());
    }

    @Override
    public void update(String taskId, String formCode, Integer formVersion, Integer isNeedClaim, String uid, Map<String, Object> params) {
        UserInfoBO currentUser = securityComponent.getCurrentUser();
        updateByUserIdAndUserName(currentUser.getUserId(), currentUser.getUserName(), taskId, formCode, formVersion, isNeedClaim, uid, params);
    }

    @Override
    public void updateByToken(String token, String taskId, String formCode, Integer formVersion, Integer isNeedClaim, String uid, Map<String, Object> params) {
        AppTokenUser appTokenUser = getAppTokenUser(token);
        updateByUserIdAndUserName(appTokenUser.getId(), appTokenUser.getName(), taskId, formCode, formVersion, isNeedClaim, uid, params);
    }

    @Override
    public void updateByUserIdAndUserName(String userId, String userName, String taskId, String formCode, Integer formVersion, Integer isNeedClaim, String uid, Map<String, Object> params) {
        Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (currentTask == null) {
            throw new SearchException("任务不存在或已被处理");
        }
        OaFormReportUnWantedValueBO oaFormReportUnWantedValueBO = getOaFormReportUnWantedValue(params);
        LOG.debug("设置文号");
        setDocNo(oaFormReportUnWantedValueBO.getOaDocNos(), formCode, formVersion, params);
        formReportService.updateByUserId(userId, formCode, formVersion, uid, params);
        if (isNeedClaim == 1) {
            LOG.debug("认领任务");
            taskService.claim(taskId, userId);
        }
        // 网关条件
        if (!StringUtils.isBlank(oaFormReportUnWantedValueBO.getExc())) {
            params.put(IActivitiModelService.EXCLUSIVE_GATEWAY_CONDITION_KEY, oaFormReportUnWantedValueBO.getExc());
        }
        if (!oaFormReportUnWantedValueBO.getNextEndEvent()) {
            setFormReportAssignee(oaFormReportUnWantedValueBO.getSelectType(), oaFormReportUnWantedValueBO.getAssignees(), params);
        }
        setRecordFields(currentTask.getProcessInstanceId(), taskId, oaFormReportUnWantedValueBO.getRecordFields(), userId, userName, params);
        // 保存表单日志
        taskService.complete(taskId, params);
        LOG.debug("保存抄送");
        formCcService.saveByUserId(userId, formCode, formVersion, currentTask.getProcessInstanceId(), uid, oaFormReportUnWantedValueBO.getCcs());
    }

    @Override
    public void updateGoBack(String processInstanceId, String currentTaskId, String jumpNodeId, String reason) {
        UserInfoBO currentUser = securityComponent.getCurrentUser();
        String userId = currentUser.getUserId();
        String userName = currentUser.getUserName();
        updateGoBackByUserIdAndUserName(userId, userName, processInstanceId, currentTaskId, jumpNodeId, reason);
    }

    @Override
    public void updateGoBack(String token, String processInstanceId, String currentTaskId, String jumpNodeId, String reason) {
        AppTokenUser appTokenUser = getAppTokenUser(token);
        String userId = appTokenUser.getId();
        String userName = appTokenUser.getName();
        updateGoBackByUserIdAndUserName(userId, userName, processInstanceId, currentTaskId, jumpNodeId, reason);
    }

    @Override
    public void updateGoBackByUserIdAndUserName(String userId, String userName, String processInstanceId, String currentTaskId, String jumpNodeId, String reason) {
        LOG.debug("OA流程回退");
        Task currentTask = taskService.createTaskQuery().taskId(currentTaskId).singleResult();
        if (currentTask == null) {
            throw new SearchException("任务不存在或已被处理");
        }

        List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).list();
        BpmnModel bpmnModel = activitiModelService.getBpmnModelByProcessDefinitionId(currentTask.getProcessDefinitionId());
        LOG.debug("1. 查询当流程节点");
        UserTask currentUserTask = (UserTask) bpmnModel.getFlowElement(currentTask.getTaskDefinitionKey());
        LOG.debug("2. 查询回退的节点");
        UserTask goBackUserTask = (UserTask) bpmnModel.getFlowElement(jumpNodeId);
        LOG.debug("3. 缓存现有的下一步连线");
        List<SequenceFlow> oldOutgoingFlows = new ArrayList<>();
        oldOutgoingFlows.addAll(currentUserTask.getOutgoingFlows());
        LOG.debug("4. 创建新连线");
        currentUserTask.getOutgoingFlows().clear();
        List<SequenceFlow> newOutgoingFlows = new ArrayList<>();
        SequenceFlow newOutgoingFlow = new SequenceFlow();
        newOutgoingFlow.setId(IActivitiModelService.GO_BACK_FLOW_ID);
        newOutgoingFlow.setSourceFlowElement(currentUserTask);
        newOutgoingFlow.setTargetFlowElement(goBackUserTask);
        newOutgoingFlows.add(newOutgoingFlow);
        currentUserTask.setOutgoingFlows(newOutgoingFlows);

        try {
            LOG.debug("5 判断回退节点的类型");
            MultiInstanceLoopCharacteristics goBackUserTaskLoopCharacteristics = goBackUserTask.getLoopCharacteristics();
            Set<String> historicUserTaskUserIdSet = new HashSet<>();
            if (goBackUserTaskLoopCharacteristics == null) {
                LOG.debug("5.1 回退节点为普通节点（单实例）。");
                LOG.debug("5.1.1 查询原节点处理人");
                for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
                    if (StringUtils.equals(historicTaskInstance.getTaskDefinitionKey(), jumpNodeId)) {
                        historicUserTaskUserIdSet.add(historicTaskInstance.getAssignee());
                        break;
                    }
                }
            } else {
                LOG.debug("5.2 回退节点为会签节点（多实例）。");
                LOG.debug("5.2.1 查询会签节点代理人");
                for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
                    if (StringUtils.equals(historicTaskInstance.getTaskDefinitionKey(), jumpNodeId)) {
                        historicUserTaskUserIdSet.add(historicTaskInstance.getAssignee());
                    }
                }
            }
            LOG.debug("6. 判断当前节点类型");
            MultiInstanceLoopCharacteristics currentUserTaskLoopCharacteristics = currentUserTask.getLoopCharacteristics();
            if (currentUserTaskLoopCharacteristics == null) {
                LOG.debug("6.1 当前节点为普通节点");
            } else {
                LOG.debug("6.2 当前节点为会签节点（多实例）");
                LOG.debug("6.2.1 删除未完成的任务（当前任务除外）");
                for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
                    // 当前任务不处理
                    if (StringUtils.equals(historicTaskInstance.getId(), currentTaskId)) {
                        continue;
                    }
                    // 已经完成的不处理
                    if (historicTaskInstance.getEndTime() != null) {
                        continue;
                    }
                    /// 未完成的
                    TaskCommentBO taskCommentBO = new TaskCommentBO();
                    taskCommentBO.setType(TaskCommentTypeEnum.GO_BACK);
                    taskCommentBO.setContent("其他人回退(自动完成)");
                    taskCommentBO.setTime(DateUtil.getTime());
                    taskCommentBO.setUserId(userId);
                    taskCommentBO.setUserName(userName);
                    taskService.addComment(historicTaskInstance.getId(), processInstanceId, TaskCommentTypeEnum.GO_BACK.getValue(), JSONObject.toJSONString(taskCommentBO));
                    taskService.complete(historicTaskInstance.getId());
                }
            }
            LOG.debug("7. 开始完成任务");
            List<String> historicUserTaskUserIds = new ArrayList<>(historicUserTaskUserIdSet);
            Map<String, Object> processVariables = getHashMap(4);
            if (historicUserTaskUserIdSet.size() == 1) {
                LOG.debug("7.1 设置代理人");
                processVariables.put(IOaFormReportService.KEY_ASSIGNEE_USER, historicUserTaskUserIds.get(0));
            } else if (historicTaskInstances.size() > 1) {
                LOG.debug("7.2 设置代理人（多实例）");
                processVariables.put(IActivitiModelService.ASSIGNEE_LIST, historicUserTaskUserIds);
            } else {
                throw new SearchException("找不到回退代理人");
            }
            LOG.debug("7.3 完成任务");
            TaskCommentBO taskCommentBO = new TaskCommentBO();
            taskCommentBO.setType(TaskCommentTypeEnum.GO_BACK);
            taskCommentBO.setContent(reason);
            taskCommentBO.setTime(DateUtil.getTime());
            taskCommentBO.setUserId(userId);
            taskCommentBO.setUserName(userName);
            taskService.addComment(currentTaskId, processInstanceId, TaskCommentTypeEnum.GO_BACK.getValue(), JSONObject.toJSONString(taskCommentBO));
            taskService.complete(currentTaskId, processVariables);
        } catch (Exception e) {
            e.printStackTrace();
            throw new SystemException(e);
        } finally {
            LOG.debug("9. 恢复原有的下一步连线");
            currentUserTask.setOutgoingFlows(oldOutgoingFlows);
        }
    }

    @Override
    public void updateForcedEnd(String processInstanceId, String currentTaskId, String reason) {
        UserInfoBO currentUser = securityComponent.getCurrentUser();
        String userId = currentUser.getUserId();
        String userName = currentUser.getUserName();
        updateForcedEndByUserIdAndUserName(userId, userName, processInstanceId, currentTaskId, reason);
    }

    @Override
    public void updateForcedEnd(String token, String processInstanceId, String currentTaskId, String reason) {
        AppTokenUser appTokenUser = getAppTokenUser(token);
        String userId = appTokenUser.getId();
        String userName = appTokenUser.getName();
        updateForcedEndByUserIdAndUserName(userId, userName, processInstanceId, currentTaskId, reason);
    }

    @Override
    public void updateForcedEndByUserIdAndUserName(String userId, String userName, String processInstanceId, String currentTaskId, String reason) {
        LOG.debug("OA强制结束");
        Task currentTask = taskService.createTaskQuery().taskId(currentTaskId).singleResult();
        if (currentTask == null) {
            throw new SearchException("任务不存在或已被处理");
        }

        List<HistoricTaskInstance> historicTaskInstances = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).unfinished().list();
        BpmnModel bpmnModel = activitiModelService.getBpmnModelByProcessDefinitionId(currentTask.getProcessDefinitionId());

        LOG.debug("1. 获取当前节点");
        UserTask currentUserTask = (UserTask) bpmnModel.getFlowElement(currentTask.getTaskDefinitionKey());
        LOG.debug("2. 获取结束节点");
        List<EndEvent> endEvents = bpmnModel.getMainProcess().findFlowElementsOfType(EndEvent.class);
        LOG.debug("3. 获取当前节点输出流序列");
        List<SequenceFlow> outgoingFlows = currentUserTask.getOutgoingFlows();
        LOG.debug("4. 缓存原始输出流");
        List<SequenceFlow> oldOutgoingFlows = new ArrayList<>();
        oldOutgoingFlows.addAll(outgoingFlows);
        LOG.debug("5. 创建新序列流");
        currentUserTask.getOutgoingFlows().clear();
        List<SequenceFlow> newOutgoingFlows = new ArrayList<>();
        SequenceFlow newOutgoingFlow = new SequenceFlow();
        newOutgoingFlow.setId(IActivitiModelService.FORCED_END_FLOW_ID);
        newOutgoingFlow.setSourceFlowElement(currentUserTask);
        LOG.debug("6. 当前节点指向第一个结束节点");
        newOutgoingFlow.setTargetFlowElement(endEvents.get(0));
        newOutgoingFlows.add(newOutgoingFlow);
        currentUserTask.setOutgoingFlows(newOutgoingFlows);
        try {
            LOG.debug("7. 判断当前节点类型");
            MultiInstanceLoopCharacteristics currentUserTaskLoopCharacteristics = currentUserTask.getLoopCharacteristics();
            if (currentUserTaskLoopCharacteristics == null) {
                LOG.debug("7.1 当前节点为普通节点");
            } else {
                LOG.debug("7.2 当前节点为会签节点");
                LOG.debug("7.2.1 自动完成其它节点");
                for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
                    // 当前任务不处理
                    if (StringUtils.equals(historicTaskInstance.getId(), currentTaskId)) {
                        continue;
                    }
                    /// 未完成的
                    TaskCommentBO taskCommentBO = new TaskCommentBO();
                    taskCommentBO.setType(TaskCommentTypeEnum.FORCED_END);
                    taskCommentBO.setContent("其他人强制结束(自动完成)");
                    taskCommentBO.setTime(DateUtil.getTime());
                    taskCommentBO.setUserId(userId);
                    taskCommentBO.setUserName(userName);
                    taskService.addComment(historicTaskInstance.getId(), processInstanceId, TaskCommentTypeEnum.FORCED_END.getValue(), JSONObject.toJSONString(taskCommentBO));
                    taskService.complete(historicTaskInstance.getId());
                }
            }
            LOG.debug("7.2.2 完成当前节点");
            TaskCommentBO taskCommentBO = new TaskCommentBO();
            taskCommentBO.setType(TaskCommentTypeEnum.FORCED_END);
            taskCommentBO.setContent(reason);
            taskCommentBO.setTime(DateUtil.getTime());
            taskCommentBO.setUserId(userId);
            taskCommentBO.setUserName(userName);
            taskService.addComment(currentTaskId, processInstanceId, TaskCommentTypeEnum.FORCED_END.getValue(), JSONObject.toJSONString(taskCommentBO));
            taskService.complete(currentTaskId);
        } catch (Exception e) {
            e.printStackTrace();
            throw new SystemException(e);
        } finally {
            LOG.debug("8. 恢复连线");
            currentUserTask.setOutgoingFlows(oldOutgoingFlows);
        }
    }

    @Override
    public void updateTaskAssignee(String processInstanceId, String taskId, UpdateTaskAssigneeVO updateTaskAssigneeVO) {
        UserInfoBO currentUser = securityComponent.getCurrentUser();
        String userId = currentUser.getUserId();
        String userName = currentUser.getUserName();
        updateTaskAssigneeByUserIdAndUserName(userId, userName, processInstanceId, taskId, updateTaskAssigneeVO);
    }

    @Override
    public void updateTaskAssignee(String token, String processInstanceId, String taskId, UpdateTaskAssigneeVO updateTaskAssigneeVO) {
        AppTokenUser appTokenUser = getAppTokenUser(token);
        String userId = appTokenUser.getId();
        String userName = appTokenUser.getName();
        updateTaskAssigneeByUserIdAndUserName(userId, userName, processInstanceId, taskId, updateTaskAssigneeVO);
    }

    @Override
    public void updateTaskAssigneeByUserIdAndUserName(String userId, String userName, String processInstanceId, String taskId, UpdateTaskAssigneeVO updateTaskAssigneeVO) {
        taskService.setAssignee(taskId, updateTaskAssigneeVO.getAssignee());

        TaskCommentBO taskCommentBO = new TaskCommentBO();
        taskCommentBO.setUserId(userId);
        taskCommentBO.setUserName(userName);
        taskCommentBO.setContent(updateTaskAssigneeVO.getReason());
        taskCommentBO.setTime(DateUtil.getTime());
        taskCommentBO.setType(TaskCommentTypeEnum.TRANSFER);
        taskService.addComment(taskId, processInstanceId, TaskCommentTypeEnum.TRANSFER.getValue(), JSONObject.toJSONString(taskCommentBO));
    }

    /**
     * 设置文号
     *
     * @param oaDocNos
     * @param reportParams
     */
    private void setDocNo(List<OaDocNoVO> oaDocNos, String formCode, Integer formVersion, Map<String, Object> reportParams) {
        if (oaDocNos.isEmpty()) {
            return;
        }
        oaDocNos.forEach(oaDocNoVO -> {
            DocNoPO docNoPO = docNoService.getPO(oaDocNoVO.getDocNoId());
            if (StringUtils.equals(DocNoTypeEnum.MANUAL.getValue(), docNoPO.getType())) {
                LOG.debug("文号类型为手动生成");
                reportParams.put(oaDocNoVO.getFieldName() + IFormDesignService.SUFFIX_DOC_NO, oaDocNoVO.getDocNoText());
            } else {
                String latestDocNo = docNoService.saveAndReturnLatestDocNo(oaDocNoVO.getDocNoId(), String.format("df_%s_v%d", formCode, formVersion));
                reportParams.put(oaDocNoVO.getFieldName() + IFormDesignService.SUFFIX_DOC_NO, latestDocNo);
            }
        });
    }

    /**
     * 保存记录的字段列表
     *
     * @param processInstanceId
     * @param taskId
     * @param oaFormReportRecordFieldVOs
     * @param userId
     * @param userName
     * @param reportParams
     */
    private void setRecordFields(String processInstanceId, String taskId, List<OaFormReportRecordFieldVO> oaFormReportRecordFieldVOs, String userId, String userName, Map<String, Object> reportParams) {
        if (oaFormReportRecordFieldVOs.isEmpty()) {
            return;
        }
        String currentDay = DateUtil.getDay();
        for (OaFormReportRecordFieldVO oaFormReportRecordFieldVO : oaFormReportRecordFieldVOs) {
            Object reportRecordObject = reportParams.get(oaFormReportRecordFieldVO.getFieldName());
            String reportRecordValue = reportRecordObject == null ? "" : reportRecordObject.toString();
            // 创建批注
            if (StringUtils.equals(oaFormReportRecordFieldVO.getEditHistory(), FieldEditRecordEnum.LATEST.getValue())) {
                // 签批批注，存入流程变量， 内容、姓名、时间
                reportParams.put(oaFormReportRecordFieldVO.getFieldName() + EDIT_SIGN_KEY_SUFFIX, String.format("%s。 %s。 %s。", reportRecordValue, userName, currentDay));
                continue;
            }
            if (StringUtils.equals(oaFormReportRecordFieldVO.getEditHistory(), FieldEditRecordEnum.ALL.getValue())) {
                // 会签批注
                TaskCommentBO taskCommentBO = new TaskCommentBO();
                taskCommentBO.setUserId(userId);
                taskCommentBO.setUserName(userName);
                taskCommentBO.setContent(reportRecordValue);
                taskCommentBO.setTime(currentDay);
                taskCommentBO.setFieldName(oaFormReportRecordFieldVO.getFieldName());
                taskCommentBO.setFieldExplain(oaFormReportRecordFieldVO.getFieldExplain());
                taskCommentBO.setType(TaskCommentTypeEnum.JOINTLY_SIGN);
                taskService.addComment(taskId, processInstanceId, TaskCommentTypeEnum.JOINTLY_SIGN.getValue(), JSONObject.toJSONString(taskCommentBO));
                continue;
            }
            throw new ParamsException("记录类型错误");
        }
    }

    /**
     * 获取上报表单不需要的值
     *
     * @param reportParams
     * @return
     */
    private OaFormReportUnWantedValueBO getOaFormReportUnWantedValue(Map<String, Object> reportParams) {
        List<String> assignees = (List<String>) reportParams.get(IOaFormReportService.KEY_ASSIGNEES);
        String selectType = reportParams.get(IOaFormReportService.KEY_SELECT_TYPE).toString();
        Boolean isNextEndEvent = Boolean.parseBoolean(reportParams.get(IOaFormReportService.KEY_IS_NEXT_END_EVENT).toString());
        Object excObj = reportParams.get(IActivitiModelService.EXCLUSIVE_GATEWAY_CONDITION_KEY);
        List<OaFormReportRecordFieldVO> oaFormReportRecordFieldVOs = JSONArray.parseArray(JSON.toJSONString(reportParams.get(IOaFormReportService.KEY_RECORD_FIELDS)), OaFormReportRecordFieldVO.class);
        List<String> ccVOs = (List<String>) reportParams.get(IOaFormReportService.KEY_CCS);
        List<OaDocNoVO> docNoVOS = JSONArray.parseArray(JSONArray.toJSONString(reportParams.get(IOaFormReportService.KEY_DOC_NOS)), OaDocNoVO.class);
        // 移除无效的内容
        reportParams.remove(IOaFormReportService.KEY_ASSIGNEES);
        reportParams.remove(IOaFormReportService.KEY_SELECT_TYPE);
        reportParams.remove(IOaFormReportService.KEY_IS_NEXT_END_EVENT);
        reportParams.remove(IOaFormReportService.KEY_RECORD_FIELDS);
        reportParams.remove(IActivitiModelService.EXCLUSIVE_GATEWAY_CONDITION_KEY);
        reportParams.remove(IOaFormReportService.KEY_CCS);
        reportParams.remove(IOaFormReportService.KEY_DOC_NOS);
        // 归类到对象
        OaFormReportUnWantedValueBO oaFormReportUnWantedValueBO = new OaFormReportUnWantedValueBO();
        oaFormReportUnWantedValueBO.setAssignees(assignees);
        oaFormReportUnWantedValueBO.setSelectType(selectType);
        oaFormReportUnWantedValueBO.setNextEndEvent(isNextEndEvent);
        oaFormReportUnWantedValueBO.setExc(excObj == null ? "" : excObj.toString());
        oaFormReportUnWantedValueBO.setRecordFields(oaFormReportRecordFieldVOs);
        oaFormReportUnWantedValueBO.setCcs(ccVOs);
        oaFormReportUnWantedValueBO.setOaDocNos(docNoVOS);
        return oaFormReportUnWantedValueBO;
    }

    /**
     * 设置表单提交代理人
     *
     * @param selectType       选择类型
     * @param assignees        代理人列表
     * @param formReportParams 表单参数
     */
    private void setFormReportAssignee(String selectType, List<String> assignees, Map<String, Object> formReportParams) {
        if (StringUtils.equals(selectType, SelectAssigneeTypeEnum.CHECKBOX.getValue())) {
            formReportParams.put(IActivitiModelService.ASSIGNEE_LIST, assignees);
        } else {
            formReportParams.put(IOaFormReportService.KEY_ASSIGNEE_USER, assignees.get(0));
        }
    }

    @Override
    public Map<String, Object> get(String formCode, Integer formVersion, String uid) {
        Map<String, Object> detail = formReportService.get(formCode, formVersion, uid);
        // 查询会签列表
        String processInstanceId = detail.get(IFormDesignService.PROCESS_INSTANCE_ID).toString();
        LOG.debug("设置签批内容(流程变量)");
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().includeProcessVariables().processInstanceId(processInstanceId).singleResult();
        if (historicProcessInstance == null) {
            throw new SearchException("流程实例不存在");
        }
        Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
        for (Map.Entry<String, Object> detailKV : detail.entrySet()) {
            Object signObject = processVariables.get(detailKV.getKey() + EDIT_SIGN_KEY_SUFFIX);
            if (signObject != null) {
                detail.put(detailKV.getKey(), signObject);
            }
        }
        List<Comment> signComments = taskService.getProcessInstanceComments(processInstanceId, TaskCommentTypeEnum.SIGN.getValue());
        for (Comment comment : signComments) {
            TaskCommentBO taskCommentBO = JSONObject.parseObject(comment.getFullMessage(), TaskCommentBO.class);
            detail.put(taskCommentBO.getFieldName(), String.format("%s。 %s。 %s。", taskCommentBO.getContent(), taskCommentBO.getUserName(), taskCommentBO.getTime()));
        }

        LOG.debug("会签的内容");
        List<Comment> jointlySignComments = taskService.getProcessInstanceComments(processInstanceId, TaskCommentTypeEnum.JOINTLY_SIGN.getValue());
        Map<String, List<TaskCommentBO>> jointlySignMap = new HashMap<>(6);
        // 会签列表
        for (Comment comment : jointlySignComments) {
            TaskCommentBO taskCommentBO = JSONObject.parseObject(comment.getFullMessage(), TaskCommentBO.class);
            String mapKey = taskCommentBO.getFieldName() + EDIT_JOINTLY_SIGN_KEY_SUFFIX;
            List<TaskCommentBO> taskCommentBOs = jointlySignMap.get(mapKey);
            if (taskCommentBOs == null) {
                taskCommentBOs = new ArrayList<>();
            }
            taskCommentBOs.add(taskCommentBO);
            jointlySignMap.put(mapKey, taskCommentBOs);
        }
        detail.put("jointlySign", jointlySignMap);
        return detail;
    }

    @Override
    public Map<String, Object> getPO(String formCode, Integer formVersion, String uid) {
        return formReportService.get(formCode, formVersion, uid);
    }

    @Override
    public List<Map<String, Object>> list(String formCode, Integer formVersion, Map<String, Object> params) {
        return formReportService.list(formCode, formVersion, params);
    }

    @Override
    public List<Map<String, Object>> list(String formCode, Integer formVersion, List<String> uids) {
        Map<String, Object> params = getHashMap(6);
        params.put("uids", uids);
        return formReportService.list(formCode, formVersion, params);
    }

    @Override
    public SuccessResultList<List<Map<String, Object>>> listPage(String formCode, Integer formVersion, ListPage page) {
        return formReportService.listPage(formCode, formVersion, page);
    }
}
