package com.junmp.junmpProcess.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PageUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.junmp.junmpProcess.common.utils.HttpStatus;
import com.junmp.junmpProcess.common.utils.ResponseResult;
import com.junmp.junmpProcess.common.utils.ReturnMsg;
import com.junmp.junmpProcess.dto.*;
import com.junmp.junmpProcess.dto.json.UserInfo;
import com.junmp.junmpProcess.entity.ProcessTemplates;
import com.junmp.junmpProcess.mapper.QuickSuggestionsMapper;
import com.junmp.junmpProcess.redis.FlowRedisCache;
import com.junmp.junmpProcess.service.IFlowInstanceService;
import com.junmp.junmpProcess.service.IFlowTaskService;
import com.junmp.junmpProcess.service.Repository.ProcessTemplateService;
import com.junmp.junmpProcess.utils.CreateNullData;
import com.junmp.junmpProcess.utils.DateTimeUtil;
import com.junmp.junmpProcess.vo.*;
import com.junmp.jyzb.api.bean.query.BussinessOrderDetialReq;
import com.junmp.jyzb.api.bean.query.QueryOrderLogReq;
import com.junmp.jyzb.api.bean.req.InventorySummaryReq;
import com.junmp.jyzb.api.bean.req.UpdateBusFormReq;
import com.junmp.jyzb.api.bean.req.UpdateOrderDetailReq;
import com.junmp.jyzb.api.exception.JYZBAppException;
import com.junmp.jyzb.api.exception.enums.InventoryExceptionEnum;
import com.junmp.v2.auth.api.context.LoginContext;
import com.junmp.v2.common.bean.response.ApiRes;
import com.junmp.v2.db.api.factory.PageResultFactory;
import com.junmp.v2.db.api.page.PageResult;
import com.junmp.v2.message.api.MessageApi;
import com.junmp.v2.message.api.bean.req.MessageReq;
import com.junmp.v2.message.api.bean.req.MessageSendReq;
import com.junmp.v2.message.api.bean.res.MessageRes;
import com.junmp.v2.message.api.enums.MsgReadStateEnum;
import com.junmp.v2.sys.user.entity.SysUser;
import com.junmp.v2.sys.user.service.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.FlowElement;
import org.flowable.bpmn.model.Process;
import org.flowable.bpmn.model.UserTask;
import org.flowable.common.engine.impl.identity.Authentication;
import org.flowable.engine.HistoryService;
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.HistoricProcessInstance;
import org.flowable.engine.history.HistoricProcessInstanceQuery;
import org.flowable.engine.impl.persistence.entity.CommentEntity;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.engine.task.Attachment;
import org.flowable.engine.task.Comment;
import org.flowable.task.api.DelegationState;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.api.history.HistoricTaskInstanceQuery;
import org.flowable.variable.api.history.HistoricVariableInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.io.InputStream;
import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

import static com.junmp.junmpProcess.common.CommonConstants.*;
import static com.junmp.junmpProcess.common.CommonConstants.NOTE;

@Service
@Slf4j
public class FlowTaskServiceImpl  implements IFlowTaskService {

    @Resource
    private SysUserService sysUserService;
    @Resource
    private FlowRedisCache redisCache;
    @Resource
    private MessageApi messageApi;
    @Autowired
    private ProcessTemplateService processTemplateService;
    @Autowired
    private IFlowInstanceService flowInstanceService;

    @Resource
    private QuickSuggestionsMapper quickSuggestionsMapper;

    @Resource
    protected HistoryService historyService;

    @Resource
    private TaskService taskService;

    @Resource
    private RuntimeService runtimeService;

    @Resource
    private RepositoryService repositoryService;


    @Override
    @Transactional
    public ResponseResult agree(HandleDataDTO handleDataDTO) {
        SysUser StartUser=new SysUser();
        if (handleDataDTO.getCurrentUserInfo().getUserId()!=null)//优先拿接口中的信息，方便调试
        {
            StartUser = sysUserService.getById(handleDataDTO.getCurrentUserInfo().getUserId());

        }
        else
        {
            StartUser= sysUserService.getById(LoginContext.getContext().getLoginUser());
        }
        List<AttachmentDTO> attachments = handleDataDTO.getAttachments();
        String comments = handleDataDTO.getComments();
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        String processInstanceId=handleDataDTO.getProcessInstanceId();

        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        if (task!=null)//task为空则说明当前任务可能已结束
        {
            taskService.setVariableLocal(taskId,"taskStatusWrapper", TASK_STATUS_1);//设置当前节点任务状态

            Map<String, Object> map = new HashMap<>();
            if (formData != null && formData.size() > 0) {
                Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
                });
                map.putAll(formValue);
                map.put(FORM_VAR, formData);
            }

            runtimeService.setVariables(task.getProcessInstanceId(), map);//设置进入当前流程

            Authentication.setAuthenticatedUserId(StartUser.getUserId().toString());
            if (StringUtils.isNotBlank(comments)) {
                taskService.addComment(task.getId(), task.getProcessInstanceId(), "opinion", comments);
            }else {
                //默认同意
                taskService.addComment(task.getId(), task.getProcessInstanceId(), "opinion", "同意");
            }
            if (attachments != null && attachments.size() > 0) {
                for (AttachmentDTO attachment : attachments) {
                    taskService.createAttachment("option", taskId, task.getProcessInstanceId(), attachment.getName(), attachment.getName(), attachment.getUrl());
                }
            }

            taskService.complete(task.getId());
            HistoricTaskInstance historicTask = historyService
                    .createHistoricTaskInstanceQuery()
                    .taskId(taskId)
                    .singleResult();

            if (historicTask.getEndTime()!=null)//EndTime为空，说明任务已结束，需要往消息队列中进行消息传递
            {
                HistoricProcessInstance historicProcessInstance= historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId)
                        .includeProcessVariables().singleResult();//拿到历史中的表单信息
                Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
                JSONObject jsonObject = (JSONObject) processVariables.get(FORM_VAR);


            }
            else
            {
//                HistoricVariableInstance orderType = historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId).variableName("orderType").list().get(0);
//                if (orderType.equals("workOrder"))
//                {
//                    Object assigneeObject = runtimeService.getVariable(processInstanceId, "currentAssignee");
//
//                    if (assigneeObject instanceof List) {
//                        List<String> assigneeList = (List<String>) assigneeObject;
//
//                        String assigneeString = String.join(",", assigneeList);
//                        orgUserMapper.UpdateOrder("bussiness_order_main",processInstanceId,assigneeString);
//                        // 现在 assigneeString 中包含了集合元素用逗号拼接的字符串
//                    }
//                }
            }
        //点击后消除已读消息,暂时不用，依赖前端处理
//        MessageReq reqmsg=new MessageReq();
//        reqmsg.setBizId(Long.valueOf(processInstanceId));
//        reqmsg.setReceiveUserId(StartUser.getUserId());
//        reqmsg.setReadFlag(0);
//        List<MessageRes> msgRes= messageApi.queryList(reqmsg);
//        if (msgRes.size()>0)
//        {
//            // 使用流将 id 取出，并用逗号拼接成字符串
//            String ids = msgRes.stream()
//                    .map(MessageRes::getMsgId)
//                    .map(String::valueOf) // 将 id 转换为字符串
//                    .collect(Collectors.joining(","));
////            messageApi.batchReadFlagByMessageIds(ids, MsgReadStateEnum.READ);
//        }
//            String objJson= redisCache.get(processInstanceId);
//            redisCache.remove(processInstanceId);
//
//            List<MessageSendReq> msgs= JSONObject.parseArray(objJson,MessageSendReq.class);
//            if (CollectionUtil.isNotEmpty(msgs)){
//                msgs.forEach(msg->
//                        {
//                            messageApi.sendMessageNoToken(msg);
//                        }
//
//                );
//            }

            return new ResponseResult(HttpStatus.SUCCESS, ReturnMsg.PASS,ReturnMsg.PASS);

        }
        else {
            return new ResponseResult(HttpStatus.PROCESS_WAS_END,ReturnMsg.PROCESS_WAS_END,"");

        }
    }

    @Override
    @Transactional
    public ResponseResult refuse(HandleDataDTO handleDataDTO) {
        SysUser StartUser=new SysUser();
        if (handleDataDTO.getCurrentUserInfo().getUserId()!=null)//优先拿接口中的信息，方便调试
        {
            StartUser = sysUserService.getById(handleDataDTO.getCurrentUserInfo().getUserId());

        }
        else
        {
            StartUser= sysUserService.getById(LoginContext.getContext().getLoginUser());
        }
        Authentication.setAuthenticatedUserId(StartUser.getUserId().toString());
        List<AttachmentDTO> attachments = handleDataDTO.getAttachments();
        String comments = handleDataDTO.getComments();
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        if (ObjectUtil.isNotNull(taskId) && !taskId.trim().isEmpty()){
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            Map<String, Object> map = new HashMap<>();
            if (formData != null && formData.size() > 0) {
                Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
                });
                map.putAll(formValue);
                map.put(FORM_VAR, formData);
            }
            redisCache.remove(task.getProcessInstanceId());
            map.put(PROCESS_STATUS, BUSINESS_STATUS_3);
            taskService.setVariableLocal(taskId,"taskStatusWrapper", TASK_STATUS_2);//设置节点中的当前操作
            runtimeService.setVariables(task.getProcessInstanceId(), map);
            if (StringUtils.isBlank(comments)) {
                //默认拒绝
                comments="拒绝";
            }
            taskService.addComment(task.getId(), task.getProcessInstanceId(), "opinion", comments);
            if (attachments != null && attachments.size() > 0) {
                for (AttachmentDTO attachment : attachments) {
                    taskService.createAttachment("option", taskId, task.getProcessInstanceId(), attachment.getName(), attachment.getName(), attachment.getUrl());
                }
            }

            if (StringUtils.isNotBlank(handleDataDTO.getSignInfo())) {
                taskService.addComment(task.getId(), task.getProcessInstanceId(), "sign", handleDataDTO.getSignInfo());
            }
            //点击后消除已读消息,暂时不用，依赖前端处理
            //拒绝后同层的人员的信息进行已读装备
            MessageReq reqmsg=new MessageReq();
            reqmsg.setBizId(Long.valueOf(task.getProcessInstanceId()));
            reqmsg.setReceiveUserId(StartUser.getUserId());
            reqmsg.setReadFlag(0);
            List<MessageRes> msgRes= messageApi.queryList(reqmsg);
            if (msgRes.size()>0)
            {
                // 使用流将 id 取出，并用逗号拼接成字符串
                String ids = msgRes.stream()
                        .map(MessageRes::getMsgId)
                        .map(String::valueOf) // 将 id 转换为字符串
                        .collect(Collectors.joining(","));
                messageApi.batchReadFlagByMessageIds(ids, MsgReadStateEnum.READ);
            }

            //消息推送（推送给发起人）
            MessageSendReq sendReq = new MessageSendReq();
            Process mainProcess = repositoryService.getBpmnModel(task.getProcessDefinitionId()).getMainProcess();
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().includeProcessVariables().processInstanceId(task.getProcessInstanceId()).singleResult();
            String startUser= MapUtil.getStr(processInstance.getProcessVariables(),START_USER_INFO);
            UserInfo user=  JSONObject.parseObject(startUser, UserInfo.class);
            String Types= MapUtil.getStr(processInstance.getProcessVariables(),TYPE_ORDER);
            String bussinessType= MapUtil.getStr(processInstance.getProcessVariables(),BUSSINESS_TYPE);
            sendReq.setReceiveUserIds(String.valueOf(user.getUserId()));
//            sendReq.setBizId(Long.valueOf(processInstance.getProcessInstanceId()));
            sendReq.setMsgTitle("您的申请被驳回");
            sendReq.setBizType("refuse/"+Types);
            sendReq.setBizId(Long.valueOf(task.getProcessInstanceId()));
            sendReq.setMsgContent("您提交的审批【"+mainProcess.getName()+"】被驳回，原因:"+comments);
            sendReq.setPriority("0");
            sendReq.setSendTime(DateTime.now());
            messageApi.sendMessageNoToken(sendReq);
            runtimeService.deleteProcessInstance(task.getProcessInstanceId(), "拒绝");
            switch (Types){
                case "workOrder":
                case "quickOrder":
                    //更新出入库单
                    //将销毁数加回来
//                    if (bussinessType.equals("destruction")){
//                        List<UpdateOrderDetailReq> list=quickSuggestionsMapper.getOrderMainDetail(task.getProcessInstanceId());
//                        boolean b = addOrRevokeAgentDestructionNum(list);
//                    }
                    quickSuggestionsMapper.updateOrderMain(task.getProcessInstanceId());
                    break;
                case "bussinessOrder":
                    if (bussinessType.equals("remove")){
                        //更新业务单
                        UpdateBusFormReq req=quickSuggestionsMapper.getBusForm(task.getProcessInstanceId());
                        List<BussinessOrderDetialReq> list = JSON.parseArray(req.getDetailList(), BussinessOrderDetialReq.class);
                        List<Object[]> searchItem=new ArrayList<>();
                        for (BussinessOrderDetialReq detialReq:list) {
                            //我先去数据库查询summary表中的数据
                            Object[] item=new Object[]{req.getOrgId(),detialReq.getLocationId(),detialReq.getTypeId(),detialReq.getSizeId(),detialReq.getPrice()};
                            searchItem.add(item);
                        }
                        //查询库存
                        List<InventorySummaryReq> inventorySummaryList=quickSuggestionsMapper.selectSumByItems(searchItem);
                        for (BussinessOrderDetialReq detialReq:list) {
                            for (InventorySummaryReq is:inventorySummaryList) {
                                if (ObjectUtil.isNull(is.getAgentBrokenNum())){
                                    is.setAgentBrokenNum(0);
                                }
                                if (detialReq.getLocationId().equals(is.getLocationId()) && detialReq.getTypeId().equals(is.getTypeId())
                                        && detialReq.getSizeId().equals(is.getSizeId()) && detialReq.getPrice().compareTo(is.getUnitPrice())==0){

                                    //直接将在审核中的数量修改为审核之前的状态
                                    is.setAgentBrokenNum(is.getAgentBrokenNum()-detialReq.getPlanNum());

                                }
                                break;
                            }

                        }
                        //更新库存汇总信息
                        quickSuggestionsMapper.updateInventorySum(inventorySummaryList);

                    }
                    quickSuggestionsMapper.updateBusForm(task.getProcessInstanceId());
                    break;
                case "reassignment":
                    quickSuggestionsMapper.updateReassignment(task.getProcessInstanceId());
                    break;
            }

            //将拒绝的单子创建日志
            addOrderLog(StartUser,comments);

        }else {
            runtimeService.deleteProcessInstance(taskId, "拒绝");
        }


        return new ResponseResult(HttpStatus.SUCCESS, ReturnMsg.PASS,ReturnMsg.PASS);
    }

    private Boolean addOrderLog(SysUser sysUser,String comments){
        QueryOrderLogReq orderLog = new QueryOrderLogReq();
        orderLog.setId(UUID.randomUUID().toString());
        orderLog.setHistoryMsg(StringUtils.isNotBlank(comments)?comments:"拒绝");
        orderLog.setCreateUser(sysUser.getAccount());
        orderLog.setProcessType("refuseOrder");
        orderLog.setCreateTime(DateTimeUtil.getCurrentDateTime());
        return quickSuggestionsMapper.addOrderLog(orderLog);
    }

    @Override
    public ResponseResult revoke(HandleDataDTO handleDataDTO) {
        SysUser StartUser=new SysUser();
        if (handleDataDTO.getCurrentUserInfo().getUserId()!=null)//优先拿接口中的信息，方便调试
        {
            StartUser = sysUserService.getById(handleDataDTO.getCurrentUserInfo().getUserId());

        }
        else
        {
            StartUser= sysUserService.getById(LoginContext.getContext().getLoginUser());
        }
        Authentication.setAuthenticatedUserId(StartUser.getUserId().toString());
        List<AttachmentDTO> attachments = handleDataDTO.getAttachments();
        String comments = handleDataDTO.getComments();
        JSONObject formData = handleDataDTO.getFormData();
        String taskId = handleDataDTO.getTaskId();
        HistoricTaskInstance task = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
        Map<String,Object> map=new HashMap<>();
        if(formData!=null &&formData.size()>0){
            Map formValue = JSONObject.parseObject(formData.toJSONString(), new TypeReference<Map>() {
            });
            map.putAll(formValue);
            map.put(FORM_VAR,formData);
        }
        map.put(PROCESS_STATUS,BUSINESS_STATUS_2);
        taskService.setVariableLocal(taskId,"taskStatusWrapper", TASK_STATUS_3);//设置节点中的当前操作
        runtimeService.setVariables(task.getProcessInstanceId(),map);
        if(StringUtils.isNotBlank(comments)){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),"opinion",comments);
        }else {
            taskService.addComment(task.getId(),task.getProcessInstanceId(),"opinion","撤销");
        }
        if(attachments!=null && attachments.size()>0){
            for (AttachmentDTO attachment : attachments) {
                taskService.createAttachment("option",taskId,task.getProcessInstanceId(),attachment.getName(),attachment.getName(),attachment.getUrl());
            }
        }

        if(StringUtils.isNotBlank(handleDataDTO.getSignInfo())){
            taskService.addComment(task.getId(),task.getProcessInstanceId(),"sign",handleDataDTO.getSignInfo());
        }
        runtimeService.deleteProcessInstance(task.getProcessInstanceId(),"撤销");
        return new ResponseResult(HttpStatus.SUCCESS,ReturnMsg.PASS,"");
    }

    @Override
    public PageResult<TaskVO> toDoList(TaskDTO taskDTO) {
        SysUser StartUser=new SysUser();
        if (taskDTO.getCurrentUserInfo().getUserId()!=null)//优先拿接口中的信息，方便调试
        {
            StartUser = sysUserService.getById(taskDTO.getCurrentUserInfo().getUserId());

        }
        else
        {
            StartUser= sysUserService.getById(LoginContext.getContext().getLoginUser());
        }
        String a=taskDTO.getProcessId();
        TaskQuery taskQuery;
        if (ObjectUtil.isNotEmpty(taskDTO.getColumn()) && taskDTO.getColumn().equals("startTime") && taskDTO.getOrder().equals("asc")){
            taskQuery = taskService.createTaskQuery().taskAssignee(StartUser.getUserId().toString())
                    .includeProcessVariables().taskCreatedAfter(taskDTO.getStartTime()).taskCreatedBefore(taskDTO.getEndTime())
                    .orderByTaskCreateTime().asc();
        } else if (ObjectUtil.isNotEmpty(taskDTO.getColumn()) && taskDTO.getColumn().equals("startTime") && taskDTO.getOrder().equals("desc")) {
            taskQuery = taskService.createTaskQuery().taskAssignee(StartUser.getUserId().toString())
                    .includeProcessVariables().taskCreatedAfter(taskDTO.getStartTime()).taskCreatedBefore(taskDTO.getEndTime())
                    .orderByTaskCreateTime().desc();
        }else {
            taskQuery = taskService.createTaskQuery().taskAssignee(StartUser.getUserId().toString())
                    .includeProcessVariables().taskCreatedAfter(taskDTO.getStartTime()).taskCreatedBefore(taskDTO.getEndTime())
                    .orderByTaskCreateTime().desc();
        }


        //条件查询（流程名称，开始时间，结束时间,发物单位，装备名称）
        if (ObjectUtil.isNotNull(taskDTO.getProcessDefinitionName()) && ! taskDTO.getProcessDefinitionName().trim().isEmpty()){
            taskQuery = taskQuery.processDefinitionNameLike("%"+taskDTO.getProcessDefinitionName()+"%");
        }


        //装备名称
        if (ObjectUtil.isNotNull(taskDTO.getTypeName()) && ! taskDTO.getTypeName().trim().isEmpty()){
            taskQuery=taskQuery.processVariableValueLike(INVLIST,"%"+taskDTO.getTypeName()+"%");
        }

        //流程id
        if (ObjectUtil.isNotNull(taskDTO.getProcessId()) && ! taskDTO.getProcessId().trim().isEmpty()){
            taskQuery=  taskQuery.processInstanceId(taskDTO.getProcessId());
        }
        //流程状态
        if (!ObjectUtil.isNull(taskDTO.getBusinessStatus()) && taskDTO.getBusinessStatus().equals("正在处理")){
            taskQuery=taskQuery.processVariableValueEquals(PROCESS_STATUS,taskDTO.getBusinessStatus());
        }else if (!ObjectUtil.isNull(taskDTO.getBusinessStatus()) && taskDTO.getBusinessStatus().equals("撤销")){
            taskQuery=taskQuery.processVariableValueEquals(PROCESS_STATUS,taskDTO.getBusinessStatus());
        }else if (!ObjectUtil.isNull(taskDTO.getBusinessStatus()) && taskDTO.getBusinessStatus().equals("驳回")){
            taskQuery=taskQuery.processVariableValueEquals(PROCESS_STATUS,taskDTO.getBusinessStatus());
        }else if (!ObjectUtil.isNull(taskDTO.getBusinessStatus()) && taskDTO.getBusinessStatus().equals("已结束")){
            taskQuery=taskQuery.processVariableValueEquals(PROCESS_STATUS,taskDTO.getBusinessStatus());
        }
        //申请人
        if (ObjectUtil.isNotNull(taskDTO.getStartUser())){
            taskQuery=taskQuery.processVariableValueLike(AGENT_NAME,"%"+taskDTO.getStartUser()+"%");
        }

        boolean conditionAdded = false;
        //发物单位
        if (ObjectUtil.isNotNull(taskDTO.getStartOrgName()) && ! taskDTO.getStartOrgName().trim().isEmpty()){
            taskQuery = taskQuery.or().processVariableValueLike(START_ORG_NAME,"%"+taskDTO.getStartOrgName()+"%")
                    .processVariableValueLike(START_USER_NAME,"%"+taskDTO.getStartOrgName()+"%");

            conditionAdded = true;

        }
        if (ObjectUtil.isNotNull(taskDTO.getEndOrgName()) && ! taskDTO.getEndOrgName().trim().isEmpty()){

            if (conditionAdded) {
                taskQuery.endOr(); // 结束上一个 or()
            }
            taskQuery = taskQuery.or().processVariableValueLike(END_ORG_NAME,"%"+taskDTO.getEndOrgName()+"%")
                    .processVariableValueLike(END_USER_NAME,"%"+taskDTO.getEndOrgName()+"%");
        }

//        taskQuery.
        List<Task> tasks = taskQuery.listPage((taskDTO.getPageNo() - 1) * taskDTO.getPageSize(), taskDTO.getPageSize());
        //根据条件查询符合条件的数据并统计数量条数
        long count = taskQuery.count();
//        long count = taskService.createTaskQuery().taskAssignee(StartUser.getUserId().toString()).count();
        List<TaskVO> taskVOS= new ArrayList<>();
        Page<TaskVO> page =new Page<>();
        for (Task task : tasks) {
            ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();

            BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
            Map<String, Object> processVariables = task.getProcessVariables();
            TaskVO taskVO=new TaskVO();
            taskVO.setTaskId(task.getId());
            taskVO.setProcessInstanceId(task.getProcessInstanceId());
            taskVO.setProcessDefinitionName(bpmnModel.getMainProcess().getName());
//            taskVO.setStartUser(JSONObject.parseObject(MapUtil.getStr(processVariables, START_USER_INFO), new TypeReference<ProcessUser>() {
//            }).getUserInfo());
            String s = (String) processVariables.get(START_USER_INFO);
            taskVO.setStartUser(JSONObject.parseObject(s, UserInfo.class));
            taskVO.setStartUserName(MapUtil.getStr(processVariables,START_USER_NAME));
            taskVO.setEndUserName(MapUtil.getStr(processVariables,END_USER_NAME));
            taskVO.setOrderId(MapUtil.getStr(processVariables, ORDER_ID));
            taskVO.setTypeOrder(MapUtil.getStr(processVariables, TYPE_ORDER));
            taskVO.setStartTime(processInstance.getStartTime());
            taskVO.setCurrentActivityName(getCurrentName(processInstance.getId(),false,processInstance.getProcessDefinitionId()));
            taskVO.setBusinessStatus(MapUtil.getStr(processVariables,PROCESS_STATUS));
            taskVO.setType(MapUtil.getStr(processVariables,TYPE));
            taskVO.setStartOrgName(MapUtil.getStr(processVariables,START_ORG_NAME));
            taskVO.setEndOrgName(MapUtil.getStr(processVariables,END_ORG_NAME));
            taskVO.setInvList(MapUtil.getStr(processVariables,INVLIST));
            taskVO.setBusinessType(MapUtil.getStr(processVariables,BUSSINESS_TYPE));
            taskVO.setOutInState(MapUtil.getStr(processVariables,OUT_IN_STATE));
            taskVO.setDName(MapUtil.getStr(processVariables,D_NAME));

            taskVO.setTaskCreatedTime(task.getCreateTime());
            DelegationState delegationState = task.getDelegationState();
            if(delegationState!=null){
                taskVO.setDelegationState(delegationState);
            }
            taskVOS.add(taskVO);
        }

        //判断是否需要添加空数据
        if(taskDTO.getIsCreateNullDate()==null || taskDTO.getIsCreateNullDate()){
            Class<TaskVO> taskVO = TaskVO.class;
            List<TaskVO> nullData = CreateNullData.createNullData(count, Long.valueOf(taskDTO.getPageNo()),Long.valueOf(taskDTO.getPageSize()), taskVO);
            taskVOS.addAll(nullData);
        }

        page.setRecords(taskVOS);
        page.setTotal(count);
        page.setCurrent(taskDTO.getPageNo());
        page.setSize(taskDTO.getPageSize());
        return PageResultFactory.createPageResult(page);
    }

    @Override
    public PageResult<TaskVO> doneList(TaskDTO taskDTO) {
        SysUser StartUser=new SysUser();
        if (taskDTO.getCurrentUserInfo().getUserId()!=null)//优先拿接口中的信息，方便调试
        {
            StartUser = sysUserService.getById(taskDTO.getCurrentUserInfo().getUserId());
        }
        else
        {
            StartUser= sysUserService.getById(LoginContext.getContext().getLoginUser());
        }
        HistoricTaskInstanceQuery historicTaskQuery  = historyService.createHistoricTaskInstanceQuery()
                .taskAssignee(StartUser.getUserId().toString())
                .finished().taskCreatedAfter(taskDTO.getStartTime()).taskCreatedBefore(taskDTO.getEndTime())
                .includeCaseVariables().includeProcessVariables().includeTaskLocalVariables().includeIdentityLinks()
                .orderByTaskCreateTime().desc();

        historicTaskQuery = historicTaskQuery.processVariableValueNotEquals(TYPE_ORDER,"stocktakeOrder");
        //根据条件查询（流程名称，开始时间，结束时间）
        if (ObjectUtil.isNotNull(taskDTO.getProcessDefinitionName()) && ! taskDTO.getProcessDefinitionName().trim().isEmpty()){
            historicTaskQuery = historicTaskQuery.processDefinitionNameLike("%"+taskDTO.getProcessDefinitionName()+"%");
        }

        //装备名称
        if (ObjectUtil.isNotNull(taskDTO.getTypeName()) && ! taskDTO.getTypeName().trim().isEmpty()){
            historicTaskQuery=historicTaskQuery.processVariableValueLike(INVLIST,"%"+taskDTO.getTypeName()+"%");

        }

        //流程id
        if (ObjectUtil.isNotNull(taskDTO.getProcessId()) && ! taskDTO.getProcessId().trim().isEmpty()){
            historicTaskQuery=historicTaskQuery.processInstanceId(taskDTO.getProcessId());
        }
        //流程状态
        if (!ObjectUtil.isNull(taskDTO.getBusinessStatus()) && taskDTO.getBusinessStatus().equals("正在处理")){
            historicTaskQuery=historicTaskQuery.processVariableValueEquals(PROCESS_STATUS,taskDTO.getBusinessStatus());
        }else if (!ObjectUtil.isNull(taskDTO.getBusinessStatus()) && taskDTO.getBusinessStatus().equals("撤销")){
            historicTaskQuery=historicTaskQuery.processVariableValueEquals(PROCESS_STATUS,taskDTO.getBusinessStatus());
        }else if (!ObjectUtil.isNull(taskDTO.getBusinessStatus()) && taskDTO.getBusinessStatus().equals("驳回")){
            historicTaskQuery=historicTaskQuery.processVariableValueEquals(PROCESS_STATUS,taskDTO.getBusinessStatus());
        }else if (!ObjectUtil.isNull(taskDTO.getBusinessStatus()) && taskDTO.getBusinessStatus().equals("已结束")){
            historicTaskQuery=historicTaskQuery.processVariableValueEquals(PROCESS_STATUS,taskDTO.getBusinessStatus());
        }
        //申请人
        if (ObjectUtil.isNotNull(taskDTO.getStartUser()) ){
            historicTaskQuery=historicTaskQuery.processVariableValueLike(AGENT_NAME,"%"+taskDTO.getStartUser()+"%");
        }
        boolean conditionAdded = false;

        //发物单位
        if (ObjectUtil.isNotNull(taskDTO.getStartOrgName()) && ! taskDTO.getStartOrgName().trim().isEmpty()){
            historicTaskQuery = historicTaskQuery.or().processVariableValueLike(START_ORG_NAME,"%"+taskDTO.getStartOrgName()+"%")
                    .processVariableValueLike(START_USER_NAME,"%"+taskDTO.getStartOrgName()+"%");
            conditionAdded = true;
        }

        if (ObjectUtil.isNotNull(taskDTO.getEndOrgName()) && ! taskDTO.getEndOrgName().trim().isEmpty()){

            if (conditionAdded) {
                historicTaskQuery.endOr(); // 结束上一个 or()
            }
            historicTaskQuery = historicTaskQuery.or().processVariableValueLike(END_ORG_NAME,"%"+taskDTO.getEndOrgName()+"%")
                    .processVariableValueLike(END_USER_NAME,"%"+taskDTO.getEndOrgName()+"%");

        }

//        List<HistoricTaskInstance> tasks = historicTaskQuery.list();
        List<HistoricTaskInstance> tasks = historicTaskQuery.listPage((taskDTO.getPageNo() - 1) * taskDTO.getPageSize(), taskDTO.getPageSize());
        long count = historicTaskQuery.count();
//        long count = historyService.createHistoricTaskInstanceQuery()
//                .taskAssignee(StartUser.getUserId().toString()).count();
        List<TaskVO> taskVOS = new ArrayList<>();
        Page<TaskVO> page = new Page<>();
        for (HistoricTaskInstance task : tasks) {
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();
            Boolean flag = historicProcessInstance.getEndTime() == null ? false : true;

            BpmnModel bpmnModel = null;
            try {
                bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId());
            } catch (Exception e) {
                // 处理获取BpmnModel异常的情况
                e.printStackTrace(); // 可以将异常信息打印到日志中
                // 可以在这里设置默认的BpmnModel或采取其他处理措施
            }

            Map<String, Object> processVariables = task.getProcessVariables();
            TaskVO taskVO = new TaskVO();
            taskVO.setTaskId(task.getId());
            taskVO.setProcessInstanceId(task.getProcessInstanceId());
            if (bpmnModel!=null)
            {
                taskVO.setProcessDefinitionName(bpmnModel.getMainProcess().getName());
            }
//            taskVO.setStartUser(JSONObject.parseObject(MapUtil.getStr(processVariables, START_USER_INFO), new TypeReference<ProcessUser>() {
//            }).getUserInfo());
            String s = (String) processVariables.get(START_USER_INFO);
            taskVO.setStartUser(JSONObject.parseObject(s, UserInfo.class));
            taskVO.setStartUserName(MapUtil.getStr(processVariables,START_USER_NAME));
            taskVO.setEndUserName(MapUtil.getStr(processVariables,END_USER_NAME));
            taskVO.setOrderId(MapUtil.getStr(processVariables, ORDER_ID));
            taskVO.setType(MapUtil.getStr(processVariables,TYPE));
            taskVO.setTypeOrder(MapUtil.getStr(processVariables, TYPE_ORDER));
            taskVO.setStartTime(historicProcessInstance.getStartTime());
            taskVO.setCurrentActivityName(getCurrentName(task.getProcessInstanceId(), flag, task.getProcessDefinitionId()));
            taskVO.setBusinessStatus(MapUtil.getStr(processVariables, PROCESS_STATUS));
            taskVO.setEndTime(task.getEndTime());
            taskVO.setStartOrgName(MapUtil.getStr(processVariables,START_ORG_NAME));
            taskVO.setEndOrgName(MapUtil.getStr(processVariables,END_ORG_NAME));
            taskVO.setInvList(MapUtil.getStr(processVariables,INVLIST));
            taskVO.setBusinessType(MapUtil.getStr(processVariables,BUSSINESS_TYPE));
            taskVO.setDName(MapUtil.getStr(processVariables,D_NAME));
            taskVO.setOutInState(MapUtil.getStr(processVariables,OUT_IN_STATE));
            long totalTimes = task.getEndTime() == null ?
                    (Calendar.getInstance().getTimeInMillis() - task.getStartTime().getTime()) :
                    (task.getEndTime().getTime() - task.getStartTime().getTime());
            long dayCount = totalTimes / (1000 * 60 * 60 * 24);//计算天
            long restTimes = totalTimes % (1000 * 60 * 60 * 24);//剩下的时间用于计于小时
            long hourCount = restTimes / (1000 * 60 * 60);//小时
            restTimes = restTimes % (1000 * 60 * 60);
            long minuteCount = restTimes / (1000 * 60);
            String spendTimes = dayCount + "天" + hourCount + "小时" + minuteCount + "分";
            taskVO.setDuration(spendTimes);
            taskVOS.add(taskVO);
        }

        //判断是否需要添加空数据
        if(taskDTO.getIsCreateNullDate()==null || taskDTO.getIsCreateNullDate()){
            Class<TaskVO> taskVO = TaskVO.class;
            List<TaskVO> nullData = CreateNullData.createNullData(count, Long.valueOf(taskDTO.getPageNo()),Long.valueOf(taskDTO.getPageSize()), taskVO);
            taskVOS.addAll(nullData);
        }

        page.setRecords(taskVOS);
        page.setCurrent(taskDTO.getPageNo());
        page.setSize(taskDTO.getPageSize());
        page.setTotal(count);

        return PageResultFactory.createPageResult(page);
    }

    @Override
    public PageResult<HistoryProcessInstanceVO> applyList(ApplyDTO applyDTO) {
        SysUser StartUser=new SysUser();
        if (applyDTO.getCurrentUserInfo().getUserId()!=null)//优先拿接口中的信息，方便调试
        {
            StartUser = sysUserService.getById(applyDTO.getCurrentUserInfo().getUserId());
        }
        else
        {
            StartUser= sysUserService.getById(LoginContext.getContext().getLoginUser());
        }
        PageResult<HistoryProcessInstanceVO> pageResult=new  PageResult<HistoryProcessInstanceVO>();
        HistoricProcessInstanceQuery desc = historyService.createHistoricProcessInstanceQuery()
                .includeProcessVariables().processInstanceId(applyDTO.getProcessId())
                .startedBy(StartUser.getUserId().toString())
                .orderByProcessInstanceStartTime().desc();

        //根据条件查询（流程名称，开始时间，结束时间）
        if (ObjectUtil.isNotNull(applyDTO.getProcessDefinitionName()) && ! applyDTO.getProcessDefinitionName().trim().isEmpty()){
            List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery()
                    .processDefinitionNameLike("%" + applyDTO.getProcessDefinitionName() + "%")
                    .list();

            List<String> processDefinitionKeys = processDefinitions.stream()
                    .map(ProcessDefinition::getKey)
                    .collect(Collectors.toList());

            desc.processDefinitionKeyIn(processDefinitionKeys);
        }
        if (ObjectUtil.isNotNull(applyDTO.getStartTime())) {
            desc = desc.startedAfter(applyDTO.getStartTime());
        }
        if (ObjectUtil.isNotNull(applyDTO.getEndTime())) {
            desc = desc.startedBefore(applyDTO.getEndTime());
        }
        desc = desc.variableValueNotEquals(TYPE_ORDER,"stocktakeOrder");

        //装备名称
        if (ObjectUtil.isNotNull(applyDTO.getTypeName()) && ! applyDTO.getTypeName().trim().isEmpty()){
            desc=desc.variableValueLike(INVLIST,"%"+applyDTO.getTypeName()+"%");
        }

        //流程id
        if (ObjectUtil.isNotNull(applyDTO.getProcessId()) && ! applyDTO.getProcessId().trim().isEmpty()){
            desc=desc.processInstanceId(applyDTO.getProcessId());
        }
        //流程状态
        if (!ObjectUtil.isNull(applyDTO.getBusinessStatus()) && applyDTO.getBusinessStatus().equals("正在处理")){
            desc=desc.variableValueEquals(PROCESS_STATUS,applyDTO.getBusinessStatus());
        }else if (!ObjectUtil.isNull(applyDTO.getBusinessStatus()) && applyDTO.getBusinessStatus().equals("撤销")){
            desc=desc.variableValueEquals(PROCESS_STATUS,applyDTO.getBusinessStatus());
        }else if (!ObjectUtil.isNull(applyDTO.getBusinessStatus()) && applyDTO.getBusinessStatus().equals("驳回")){
            desc=desc.variableValueEquals(PROCESS_STATUS,applyDTO.getBusinessStatus());
        }else if (!ObjectUtil.isNull(applyDTO.getBusinessStatus()) && applyDTO.getBusinessStatus().equals("已结束")){
            desc=desc.variableValueEquals(PROCESS_STATUS,applyDTO.getBusinessStatus());
        }

        //申请人
        if (ObjectUtil.isNotNull(applyDTO.getStartUser())){
            desc=desc.variableValueLike(AGENT_NAME,"%"+applyDTO.getStartUser()+"%");
        }
        boolean conditionAdded = false;
        //发物单位
        if (ObjectUtil.isNotNull(applyDTO.getStartOrgName()) && ! applyDTO.getStartOrgName().trim().isEmpty()){
            desc = desc.or().variableValueLike(START_ORG_NAME,"%"+applyDTO.getStartOrgName()+"%")
                    .variableValueLike(START_USER_NAME,"%"+applyDTO.getStartOrgName()+"%");
            conditionAdded = true;
        }
        if (ObjectUtil.isNotNull(applyDTO.getEndOrgName()) && ! applyDTO.getEndOrgName().trim().isEmpty()){
            if (conditionAdded) {
                desc.endOr(); // 结束上一个 or()
            }
            desc = desc.or().variableValueLike(END_ORG_NAME,"%"+applyDTO.getEndOrgName()+"%")
                    .variableValueLike(END_USER_NAME,"%"+applyDTO.getEndOrgName()+"%");
        }
//        desc = desc.variableValueEquals(NOTE, null);
//.variableValueNotEquals(NOTE, "系统自动生成").or().


        List<HistoricProcessInstance> historicProcessInstances = desc.listPage((applyDTO.getPageNo() - 1) * applyDTO.getPageSize(), applyDTO.getPageSize());
//        long count = desc.count();
//        long count = historyService.createHistoricProcessInstanceQuery()
//                .startedBy(StartUser.getUserId().toString()).count();
        List<HistoryProcessInstanceVO> historyProcessInstanceVOS = new ArrayList<>();
        Page<HistoryProcessInstanceVO> page = new Page<>();
        for (HistoricProcessInstance historicProcessInstance : historicProcessInstances) {
            Map<String, Object> processVariables = historicProcessInstance.getProcessVariables();
            HistoryProcessInstanceVO historyProcessInstanceVO = new HistoryProcessInstanceVO();
            historyProcessInstanceVO.setProcessInstanceId(historicProcessInstance.getId());

            BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId());

            String Name= bpmnModel.getMainProcess().getName();

            historyProcessInstanceVO.setOrderId(MapUtil.getStr(processVariables, ORDER_ID));
            historyProcessInstanceVO.setTypeOrder(MapUtil.getStr(processVariables, TYPE_ORDER));
            historyProcessInstanceVO.setType(MapUtil.getStr(processVariables,TYPE));
            historyProcessInstanceVO.setProcessDefinitionName(historicProcessInstance.getProcessDefinitionName());
//            historyProcessInstanceVO.setStartUser(JSONObject.parseObject(MapUtil.getStr(processVariables, START_USER_INFO), new TypeReference<ProcessUser>() {
//            }).getUserInfo());
            String s = (String) processVariables.get(START_USER_INFO);
            historyProcessInstanceVO.setStartUser(JSONObject.parseObject(s, UserInfo.class));
            historyProcessInstanceVO.setStartUserName(MapUtil.getStr(processVariables,START_USER_NAME));
            historyProcessInstanceVO.setEndUserName(MapUtil.getStr(processVariables,END_USER_NAME));
            historyProcessInstanceVO.setStartTime(historicProcessInstance.getStartTime());
            historyProcessInstanceVO.setEndTime(historicProcessInstance.getEndTime());
            Boolean flag = historicProcessInstance.getEndTime() == null ? false : true;
            historyProcessInstanceVO.setCurrentActivityName(getCurrentName(historicProcessInstance.getId(), flag, historicProcessInstance.getProcessDefinitionId()));
            historyProcessInstanceVO.setBusinessStatus(MapUtil.getStr(processVariables, PROCESS_STATUS));
            historyProcessInstanceVO.setStartOrgName(MapUtil.getStr(processVariables,START_ORG_NAME));
            historyProcessInstanceVO.setEndOrgName(MapUtil.getStr(processVariables,END_ORG_NAME));
            historyProcessInstanceVO.setInvList(MapUtil.getStr(processVariables,INVLIST));
            historyProcessInstanceVO.setDName(MapUtil.getStr(processVariables,D_NAME));
            historyProcessInstanceVO.setNote(MapUtil.getStr(processVariables,NOTE));
            historyProcessInstanceVO.setBussinessType(MapUtil.getStr(processVariables,BUSSINESS_TYPE));
            historyProcessInstanceVO.setOutInState(MapUtil.getStr(processVariables,OUT_IN_STATE));
            //表单内容
            historyProcessInstanceVO.setFormData(MapUtil.getStr(processVariables,FORM_VAR));
            long totalTimes = historicProcessInstance.getEndTime() == null ?
                    (Calendar.getInstance().getTimeInMillis() - historicProcessInstance.getStartTime().getTime()) :
                    (historicProcessInstance.getEndTime().getTime() - historicProcessInstance.getStartTime().getTime());
            long dayCount = totalTimes / (1000 * 60 * 60 * 24);//计算天
            long restTimes = totalTimes % (1000 * 60 * 60 * 24);//剩下的时间用于计于小时
            long hourCount = restTimes / (1000 * 60 * 60);//小时
            restTimes = restTimes % (1000 * 60 * 60);
            long minuteCount = restTimes / (1000 * 60);

            String spendTimes = dayCount + "天" + hourCount + "小时" + minuteCount + "分";
            historyProcessInstanceVO.setDuration(spendTimes);
            historyProcessInstanceVOS.add(historyProcessInstanceVO);
        }

//将有备注的单据，且备注信息是系统自动生成的进行过滤

        List<HistoryProcessInstanceVO> collect = historyProcessInstanceVOS.stream().filter(historyProcessInstanceVO ->
                        !"系统自动生成".equals(ObjectUtil.isNotEmpty(historyProcessInstanceVO.getNote()) ? historyProcessInstanceVO.getNote() : ""))
                .collect(Collectors.toList());
        //判断是否需要添加空数据
        if(applyDTO.getIsCreateNullDate()==null || applyDTO.getIsCreateNullDate()){
            Class<HistoryProcessInstanceVO> historyProcessInstanceVO = HistoryProcessInstanceVO.class;
            List<HistoryProcessInstanceVO> nullData = CreateNullData.createNullData((long)collect.size(), Long.valueOf(applyDTO.getPageNo()), Long.valueOf(applyDTO.getPageSize()),historyProcessInstanceVO);
            historyProcessInstanceVOS.addAll(nullData);
        }
        pageResult.setRecords(collect);
//        pageResult.setTotalRows(Long.valueOf(applyDTO.getPageNo()));
        pageResult.setTotalRows((long)collect.size());
        pageResult.setTotalPage(PageUtil.totalPage(collect.size(), Convert.toInt(pageResult.getPageSize())));
        pageResult.setPageSize(Long.valueOf(applyDTO.getPageSize()));
        pageResult.setPageNo(Long.valueOf(applyDTO.getPageNo()));
        return  pageResult;
    }

    @Override
    public ApiRes<RecordVO> record(String processInstanceId,String userId) {
        SysUser StartUser=new SysUser();
        if (userId!=null)//优先拿接口中的信息，方便调试
        {
            StartUser = sysUserService.getById(userId);

        }
        else
        {
            StartUser= sysUserService.getById(LoginContext.getContext().getLoginUser());
        }
        TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(StartUser.getUserId().toString())
                .processInstanceId(processInstanceId)
                .orderByTaskCreateTime().desc();
       List<Task> tasks= taskQuery.list();
        RecordVO vo=new RecordVO();
        if (tasks.size()>0)
        {
            vo.setTaskId(tasks.get(0).getId());
        }
        //点击后消除已读消息,暂时不用，依赖前端处理
//        MessageReq reqmsg=new MessageReq();
//        reqmsg.setBizId(Long.valueOf(processInstanceId));
//        reqmsg.setReceiveUserId(StartUser.getUserId());
//        reqmsg.setReadFlag(0);
//        List<MessageRes> msgRes= messageApi.queryList(reqmsg);
//        if (msgRes.size()>0)
//        {
//            // 使用流将 id 取出，并用逗号拼接成字符串
//            String ids = msgRes.stream()
//                    .map(MessageRes::getMsgId)
//                    .map(String::valueOf) // 将 id 转换为字符串
//                    .collect(Collectors.joining(","));
//            messageApi.batchReadFlagByMessageIds(ids, MsgReadStateEnum.READ);
//        }

        String tempID= flowInstanceService.getFormIdByInstanceId(processInstanceId);//先拿到表单id，然后通过表单拿到初始表结构
        ProcessTemplates processTemplates = processTemplateService.getById(tempID);
        Object formJson= processTemplates.getProcessJson();

        List<Comment> processInstanceComments = taskService.getProcessInstanceComments(processInstanceId);

        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .includeProcessVariables()
                .singleResult();
            String deployId = historicProcessInstance.getDeploymentId();
        Map<String, Object> result= Test(processInstanceId,deployId);
        vo.setResult(result);

        String detailJson= MapUtil.getStr(historicProcessInstance.getProcessVariables(),FORM_VAR);
        vo.setDetailJson(JSON.parseObject(detailJson));
        //设置类型
        vo.setType(MapUtil.getStr(historicProcessInstance.getProcessVariables(),TYPE));

        Map<String, List<Comment>> commentsMap = processInstanceComments.stream()
                .collect(Collectors.groupingBy(Comment::getTaskId, Collectors.toList()));
        List<Attachment> processInstanceAttachments = taskService.getProcessInstanceAttachments(processInstanceId);
        Map<String, List<Attachment>> attachmentMap = processInstanceAttachments.stream()
                .collect(Collectors.groupingBy(Attachment::getTaskId));
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).orderByHistoricActivityInstanceStartTime().asc().list();
        List<TaskDetailVO> taskDetailVOS= new ArrayList<>();
        String userStart = historicProcessInstance.getStartUserId();
        for (HistoricActivityInstance historicActivityInstance : list) {
            if("startEvent".equals(historicActivityInstance.getActivityType())){

                TaskDetailVO taskDetailVO= new TaskDetailVO();
                taskDetailVO.setTaskId(historicActivityInstance.getTaskId());
                taskDetailVO.setActivityId(historicActivityInstance.getActivityId());
                taskDetailVO.setName("发起人");
                taskDetailVO.setTaskStatusWrapper("发起");
                taskDetailVO.setDName(MapUtil.getStr(historicProcessInstance.getProcessVariables(),D_NAME));
                taskDetailVO.setCreateTime(historicActivityInstance.getStartTime());
                taskDetailVO.setEndTime(historicActivityInstance.getEndTime());
                if (userStart!=null||!userStart.isEmpty())
                {
                    SysUser user=   sysUserService.getById(userStart);
                    taskDetailVO.setUserId(user.getUserId().toString());
                    taskDetailVO.setUserName(user.getRealName());
                }

                taskDetailVOS.add(taskDetailVO);

            }
            else if("endEvent".equals(historicActivityInstance.getActivityType())){
                TaskDetailVO taskDetailVO= new TaskDetailVO();
                taskDetailVO.setTaskId(historicActivityInstance.getTaskId());
                taskDetailVO.setActivityId(historicActivityInstance.getActivityId());
                taskDetailVO.setName("流程结束");
                taskDetailVO.setTaskStatusWrapper("结束");
                taskDetailVO.setCreateTime(historicActivityInstance.getStartTime());
                taskDetailVO.setEndTime(historicActivityInstance.getEndTime());

                taskDetailVOS.add(taskDetailVO);
            }
            else if("userTask".equals(historicActivityInstance.getActivityType())){
                List<Comment> comments = commentsMap.get(historicActivityInstance.getTaskId());
                if(CollUtil.isNotEmpty(comments)){
//                    comments.add("同意");
                    for (Comment comment : comments) {
                        if("opinion".equals(comment.getType())){
                            TaskDetailVO taskDetailVO= new TaskDetailVO();
                            taskDetailVO.setTaskId(historicActivityInstance.getTaskId());
                            List<HistoricVariableInstance> taskStatusWrapper = historyService.createHistoricVariableInstanceQuery().taskId(historicActivityInstance.getTaskId()).list();

                            if (taskStatusWrapper.size()>0)
                            {
                                taskDetailVO.setTaskStatusWrapper(taskStatusWrapper.get(0).getValue().toString());
                            }
                            if (historicActivityInstance.getAssignee()!=null)
                            {
                                SysUser user=   sysUserService.getById(historicActivityInstance.getAssignee());
                                taskDetailVO.setUserId(user.getUserId().toString());
                                taskDetailVO.setUserName(user.getRealName());}
                            taskDetailVO.setActivityId(historicActivityInstance.getActivityId());
                            taskDetailVO.setName(historicActivityInstance.getActivityName());
                            taskDetailVO.setCreateTime(historicActivityInstance.getStartTime());
                            taskDetailVO.setEndTime(historicActivityInstance.getEndTime());
                            List<Attachment> attachments = attachmentMap.get(historicActivityInstance.getTaskId());
                            List<AttachmentVO> attachmentVOList = new ArrayList<>();

                            if (attachments!=null)
                            {
                                for (Attachment attachment : attachments) {
                                    AttachmentVO attachmentVO = new AttachmentVO();
                                    attachmentVO.setId(attachment.getId());
                                    attachmentVO.setName(attachment.getName());
                                    attachmentVO.setUrl(attachment.getUrl());
                                    attachmentVOList.add(attachmentVO);
                                }
                            }


                            for (Comment comment1 : comments) {
                                if("sign".equals(comment1.getType())){
                                    taskDetailVO.setSignImage(comment1.getFullMessage());
                                }
                            }
                            CommentEntity commentTransfer = (CommentEntity) comment;

                            taskDetailVO.setComment(commentTransfer.getMessage());
                            taskDetailVO.setAttachmentVOList(attachmentVOList);
                            taskDetailVOS.add(taskDetailVO);
                        }
                    }
                }else {
                    TaskDetailVO taskDetailVO= new TaskDetailVO();
                    taskDetailVO.setTaskId(historicActivityInstance.getTaskId());
                    taskDetailVO.setActivityId(historicActivityInstance.getActivityId());
                    taskDetailVO.setName("自动跳过");
                    taskDetailVO.setTaskStatusWrapper("已同意");
                    taskDetailVO.setCreateTime(historicActivityInstance.getStartTime());
                    taskDetailVO.setEndTime(historicActivityInstance.getEndTime());

                    taskDetailVOS.add(taskDetailVO);
                }
            }


        }
        // 查询流程定义信息
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deployId)
                .singleResult();

        // 获取所有任务节点信息
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
        Collection<FlowElement> flowElements = bpmnModel.getMainProcess().getFlowElements();

        // 遍历所有任务节点和结束节点，如果不在已有任务列表中，则添加到结果中
        for (FlowElement flowElement : flowElements) {
            Object aa=flowElement.getId().toString();
            if (flowElement instanceof UserTask && !flowElement.getId().toString().equals("root")&&
                    !taskDetailVOS.stream().anyMatch(task -> task.getActivityId().equals(flowElement.getId()))) {
                TaskDetailVO taskDetailVO = new TaskDetailVO();
                taskDetailVO.setActivityId(flowElement.getId());
                taskDetailVO.setName(flowElement.getName());
                // 其他属性的设置，根据需要进行修改

                // 将任务节点或结束节点添加到结果列表
                taskDetailVOS.add(taskDetailVO);
            }
        }
        // 根据 processInstanceId 查询正在执行的任务
        List<Task> list1 = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)
                .list();
        if (list1.size()>0) {
            Task currentTask =list1.get(0);
            // 使用 Stream API 进行过滤和修改
            taskDetailVOS.stream()
                    .filter(taskDetail -> taskDetail.getActivityId().equals(currentTask.getTaskDefinitionKey()))
                    .findFirst()
                    .ifPresent(matchingTask -> matchingTask.setTaskStatusWrapper("待审核"));
        }

        JSONObject jsonForm = JSON.parseObject(formJson.toString());

        JSONArray jsonArray2 = new JSONArray(Collections.singletonList(taskDetailVOS));
        JSONObject formJsonObj= matchAndMergeData(jsonForm,jsonArray2);
        vo.setFormJson(formJsonObj);
        vo.setTaskVo(taskDetailVOS);
        return ApiRes.success(vo);
    }

    private static JSONObject  matchAndMergeData(JSONObject data1, JSONArray data2) {
        if (data1.containsKey("id") && data1.containsKey("childNode")) {
            String id1 = data1.getString("id");
            // 获取第一条数据
            JSONArray jsonArray = data2.getJSONArray(0);
            // 查找匹配的数据
            TaskDetailVO matchingData = jsonArray.stream()
                    .filter(item -> item instanceof TaskDetailVO)
                    .map(item -> (TaskDetailVO) item)
                    .filter(item -> id1.equals(removeNodePrefix(item.getActivityId())))
                    .findFirst()
                    .orElse(null);
            // 如果找到匹配的数据，则将匹配的值设置到 data1 中
            if (matchingData != null) {
                if (matchingData.getTaskStatusWrapper()==null)
                {
                    data1.put("status", "未进行");
                }
                else
                {
                    data1.put("status", matchingData.getTaskStatusWrapper());
                }

            }

            // 递归处理子节点
            if (data1.containsKey("childNode") && data1.get("childNode") instanceof JSONObject) {
                matchAndMergeData(data1.getJSONObject("childNode"), data2);
            }

        }
        return data1;
    }
    private static String removeNodePrefix(String activityId) {
        // 移除前缀"Node_"
        return activityId.startsWith("Node_") ? activityId.substring(5) : activityId;
    }






private  Map<String, Object>  Test(String procInsId,String deployId)
{
    try {
    List<FlowViewerDto> flowViewerList = new ArrayList<>();
    // 获取已经完成的节点
    List<HistoricActivityInstance> listFinished = historyService.createHistoricActivityInstanceQuery()
            .processInstanceId(procInsId)
            .finished()
            .list();

    // 保存已经完成的流程节点编号
    listFinished.forEach(s -> {
        FlowViewerDto flowViewerDto = new FlowViewerDto();
        flowViewerDto.setKey(s.getActivityId());
        flowViewerDto.setCompleted(true);
        flowViewerList.add(flowViewerDto);
    });

    // 获取代办节点
    List<HistoricActivityInstance> listUnFinished = historyService.createHistoricActivityInstanceQuery()
            .processInstanceId(procInsId)
            .unfinished()
            .list();

    // 保存需要代办的节点编号
    listUnFinished.forEach(s -> {
        FlowViewerDto flowViewerDto = new FlowViewerDto();
        flowViewerDto.setKey(s.getActivityId());
        flowViewerDto.setCompleted(false);
        flowViewerList.add(flowViewerDto);
    });
    Map<String, Object> result = new HashMap();
    // xmlData 数据
    ProcessDefinition definition = repositoryService.createProcessDefinitionQuery().deploymentId(deployId).singleResult();
    InputStream inputStream = repositoryService.getResourceAsStream(definition.getDeploymentId(), definition.getResourceName());
    String xmlData = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
    result.put("nodeData", flowViewerList);
    result.put("xmlData", xmlData);
    return  result;
    } catch (Exception e) {
return  null;
    }
}

    /**
     * @Author: Zhaojw
     * @Description: 为用户赋值
     * @DateTime: 2023/9/27 16:00
     * @Params:
     * @Return
     */
    private UserInfo SetUser(SysUser sysUser)
    {
        UserInfo userInfo=new UserInfo();
        userInfo.setUserId(sysUser.getUserId());
        userInfo.setId(sysUser.getUserId().toString());
        userInfo.setName(sysUser.getRealName());
        userInfo.setSex(sysUser.getSex());
        return  userInfo;
    }
    private String getCurrentName(String processInstanceId, Boolean flag, String processDefinitionId) {
        if (flag) {
            return "流程已结束";
        }
        List<ActivityInstance> list = runtimeService.createActivityInstanceQuery().processInstanceId(processInstanceId).activityType("userTask").unfinished().orderByActivityInstanceStartTime().desc().list();
        if(CollUtil.isEmpty(list)){
            return "";
        }
        else{
            String activityId = list.get(0).getActivityId();
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
            FlowElement flowElement = bpmnModel.getMainProcess().getFlowElement(activityId);
            return flowElement.getName();
        }
//        Execution execution = runtimeService.createExecutionQuery().executionId(processInstanceId).singleResult();
//        String activityId = execution.getActivityId();
//        if (StringUtils.isBlank(activityId)) {
//            return "";
//        } else {
//            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
//            FlowElement flowElement = bpmnModel.getMainProcess().getFlowElement(activityId);
//            return flowElement.getName();
//        }

    }

    public boolean addOrRevokeAgentDestructionNum(List<UpdateOrderDetailReq> list){
        List<Object[]> searchItem=new ArrayList<>();
        for (UpdateOrderDetailReq detialReq:list) {
            //我先去数据库查询summary表中的数据

            Object[] item=new Object[]{detialReq.getOrgId(),detialReq.getWarehouseId(),detialReq.getTypeId(),detialReq.getSizeId(),detialReq.getPrice()};
            searchItem.add(item);
        }
        List<InventorySummaryReq> inventorySummaryList = quickSuggestionsMapper.selectSumByItems(searchItem);
        String msg="";
        for (UpdateOrderDetailReq detialReq:list) {
            for (InventorySummaryReq is:inventorySummaryList) {

                if (detialReq.getWarehouseId().equals(is.getLocationId()) && detialReq.getTypeId().equals(is.getTypeId())
                        && detialReq.getSizeId().equals(is.getSizeId()) && new BigDecimal(detialReq.getPrice()).compareTo(is.getUnitPrice())==0){

                    if (ObjectUtil.isNull(is.getDestructionNumber())){
                        is.setDestructionNumber(0);
                    }
                    if (is.getNumber()-detialReq.getPlanNum()<0){
//                        is.setDestructionNumber(is.getDestructionNumber()+is.getNumber());
//                        is.setNumber(0);
                        msg=msg+"装备：" +detialReq.getTypeName()+"号型："+detialReq.getSizeName()+"装备销毁数小于库存数,库存数为："+is.getNumber()+"\n";
                    }else {
                        is.setDestructionNumber(is.getDestructionNumber() - detialReq.getPlanNum());
                        is.setNumber(is.getNumber() + detialReq.getPlanNum());
                        is.setStockNumber(is.getStockNumber() + detialReq.getPlanNum());
                        is.setPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getNumber())));
                        is.setDestructionPrice(is.getUnitPrice().multiply(BigDecimal.valueOf(is.getDestructionNumber())));
                    }
                    break;
                }
            }

        }
        if (!msg.trim().isEmpty()){
            throw new JYZBAppException(InventoryExceptionEnum.EQUIPMENT_NOT_EXIST, msg);
        }

        return quickSuggestionsMapper.updateDesNum(inventorySummaryList);
    }
}
