package com.yeejoin.amos.latentdanger.business.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.base.Joiner;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.yeejoin.amos.boot.biz.common.bo.DepartmentBo;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.bo.RoleBo;
import com.yeejoin.amos.boot.biz.common.enums.RuleTypeEnum;
import com.yeejoin.amos.boot.biz.common.service.impl.WorkflowExcuteServiceImpl;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.biz.common.workflow.feign.WorkflowFeignService;
import com.yeejoin.amos.boot.module.common.api.feign.EquipFeignClient;
import com.yeejoin.amos.boot.module.common.api.feign.SupervisionFeignClient;
import com.yeejoin.amos.component.feign.model.FeignClientResult;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.feign.privilege.model.DepartmentModel;
import com.yeejoin.amos.feign.systemctl.Systemctl;
import com.yeejoin.amos.feign.systemctl.model.DictionarieValueModel;
import com.yeejoin.amos.latentdanger.business.constants.Constants;
import com.yeejoin.amos.latentdanger.business.dao.mapper.LatentDangerFlowRecordMapper;
import com.yeejoin.amos.latentdanger.business.dao.mapper.LatentDangerMapper;
import com.yeejoin.amos.latentdanger.business.dao.mapper.LatentDangerPatrolMapper;
import com.yeejoin.amos.latentdanger.business.dto.DangerExecuteSubmitDto;
import com.yeejoin.amos.latentdanger.business.dto.ExecuteSubmitDto;
import com.yeejoin.amos.latentdanger.business.entity.mybatis.DangerResultBo;
import com.yeejoin.amos.latentdanger.business.entity.mybatis.DictBo;
import com.yeejoin.amos.latentdanger.business.entity.mybatis.extend.LatentDangerBo;
import com.yeejoin.amos.latentdanger.business.entity.mybatis.extend.LatentDangerFlowRecordBo;
import com.yeejoin.amos.latentdanger.business.entity.mybatis.extend.LatentDangerNoticeBo;
import com.yeejoin.amos.latentdanger.business.entity.mybatis.extend.LatentDangerPatrolBo;
import com.yeejoin.amos.latentdanger.business.feign.JcsFeignClient;
import com.yeejoin.amos.latentdanger.business.param.LatentDangerDto;
import com.yeejoin.amos.latentdanger.business.param.LatentDangerExecuteParam;
import com.yeejoin.amos.latentdanger.business.param.LatentDangerListParam;
import com.yeejoin.amos.latentdanger.business.param.PageParam;
import com.yeejoin.amos.latentdanger.business.service.intfc.ILatentDangerService;
import com.yeejoin.amos.latentdanger.business.util.CommonResponse;
import com.yeejoin.amos.latentdanger.business.util.CommonResponseUtil;
import com.yeejoin.amos.latentdanger.business.util.DateUtil;
import com.yeejoin.amos.latentdanger.business.util.RandomUtil;
import com.yeejoin.amos.latentdanger.business.vo.DangerTimeAxisVo;
import com.yeejoin.amos.latentdanger.business.vo.LatentDangerDetailRiskVo;
import com.yeejoin.amos.latentdanger.business.vo.LatentDangerDetailVo;
import com.yeejoin.amos.latentdanger.business.vo.LatentDangerListVo;
import com.yeejoin.amos.latentdanger.common.enums.*;
import com.yeejoin.amos.latentdanger.common.remote.RemoteSpcService;
import com.yeejoin.amos.latentdanger.common.remote.RemoteWebSocketServer;
import com.yeejoin.amos.latentdanger.common.remote.RemoteWorkFlowService;
import com.yeejoin.amos.latentdanger.core.async.AsyncTask;
import com.yeejoin.amos.latentdanger.core.common.request.LatentDangerResultPushSpcRequest;
import com.yeejoin.amos.latentdanger.core.common.response.DangerListResponse;
import com.yeejoin.amos.latentdanger.dao.entity.LatentDanger;
import com.yeejoin.amos.latentdanger.dao.entity.LatentDangerFlowRecord;
import com.yeejoin.amos.latentdanger.exception.YeeException;
import com.yeejoin.amos.latentdanger.feign.RemoteSecurityService;
import com.yeejoin.amos.latentdanger.mqtt.WebMqttComponent;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageImpl;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.Bean;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.utils.ResponseHelper;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

import static com.yeejoin.amos.latentdanger.business.util.RandomUtil.buildOrderNo;
import static org.typroject.tyboot.core.foundation.context.RequestContext.getProduct;

//import com.yeejoin.amos.latentdanger.core.util.StringUtil;

//import org.springframework.data.domain.Page;
//import org.springframework.data.domain.PageImpl;

//import com.yeejoin.amos.latentdanger.business.feign.Business;

//import com.yeejoin.amos.latentdanger.business.feign.EquipFeign;

@Service("latentDangerService")
public class LatentDangerServiceImpl extends BaseService<LatentDangerBo, LatentDanger, LatentDangerMapper> implements ILatentDangerService {

    private static final String permissionType = "SUBMENU";
    private static final String acctivePermissionType = "activitiItem";
    private static final String path = "AppNormalLatentDangerReview";
    private final Logger logger = LoggerFactory.getLogger(LatentDangerServiceImpl.class);
    @Autowired
    EquipFeignClient equipFeign;
    @Autowired
    SupervisionFeignClient supervisionFeignClient;
    @Autowired
    JcsFeignClient jcsFeignClient;
    @Autowired
    private RemoteWorkFlowService remoteWorkFlowService;
    @Autowired
    private RemoteSecurityService remoteSecurityService;
    @Autowired
    private LatentDangerMapper latentDangerMapper;
    @Autowired
    private LatentDangerFlowRecordMapper latentDangerFlowRecordMapper;
    @Autowired
    private LatentDangerPatrolMapper latentDangerPatrolMapper;
    @Autowired
    private RemoteSpcService remoteSpcService;
    @Autowired
    private AsyncTask asyncTask;
    @Autowired
    private RuleDangerService ruleDangerService;
    //    @Autowired
//    private Business business;
    @Autowired
    private RemoteWebSocketServer remoteWebSocketServer;
    @Autowired
    private LatentDangerFlowRecordServiceImpl latentDangerFlowRecordService;
    @Value("${file.url}")
    private String fileServerAddress;
    @Value("${params.work.flow.processDefinitionKey}")
    private String processDefinitionKey;
    @Value("${amosRefresh.danger.topic}")
    private String dangerTopic;
    @Autowired
    private WebMqttComponent webMqttComponent;
    @Value("${danger.biz.type}")
    private String bizType;
    @Value("${workflow.process.definition.key}")
    private String workflowProcessDefinitionKey;
    @Autowired
    private RedisUtils redisUtils;
    @Autowired
    private WorkflowExcuteServiceImpl workflowExecuteService;
    @Autowired
    private WorkflowFeignService workflowFeignService;
    // 有启动后执行现场确认的角色名称
    @Value("${onSite.confirm.roleName}")
    private String onSiteConfirmRole;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public CommonResponse saveNormal(LatentDangerDto latentDangerDto, String userId, String userRealName,
                                     String departmentId, String departmentName, String companyId, String orgCode, RoleBo role) {

        LatentDangerLevelEnum dangerLevelEnum = LatentDangerLevelEnum.getEnumByCode(latentDangerDto.getDangerLevel());
        if (ValidationUtil.isEmpty(dangerLevelEnum)) {
            return CommonResponseUtil.failure("隐患等级有误");
        }

        String businessKey = buildOrderNo();

        LatentDangerDto latentDto = new LatentDangerDto();
        Bean.copyExistPropertis(latentDangerDto, latentDto);
        LatentDanger latentDanger = saveLatentDanger(latentDto, userId, departmentId, businessKey, orgCode, LatentDangerTypeEnum.随手拍);

        // 更新p_check_input表state字段
//        updateCheckInputDangerState(latentDanger.getBizId(), DangerHandleStateEnum.HANDLE.getCode());
        Long dangerId = latentDanger.getId();
        Date startDate = new Date();
        JSONObject jsonObject = remoteWorkFlowService.startNew(dangerId, businessKey, processDefinitionKey);
        Date endDate = new Date();
        logger.info("-------------------------提交隐患时间" + (endDate.getTime() - startDate.getTime()));
        if (jsonObject == null) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return CommonResponseUtil.failure("启动流程失败");
        }
        JSONObject instance = jsonObject.getJSONObject("data");
        if (instance == null) {
            return CommonResponseUtil.failure("无提交隐患权限");
        }
        latentDanger.setInstanceId(instance.getString("id"));
        JSONObject flowJson = new JSONObject();
        flowJson.put("photoUrls", latentDangerDto.getPhotoUrl());
        LatentDangerFlowRecord record = saveFlowRecord(instance.getString("id"), "提交隐患", userId, departmentId,
                flowJson, dangerId, role, LatentDangerExecuteTypeEnum.填写隐患完成.getName(), latentDangerDto.getRemark(),
                userRealName, departmentName, latentDanger.getDangerState(), 0);
        latentDanger.setCurrentFlowRecordId(record.getId());
        latentDangerMapper.updateById(latentDanger);
        sendMessage(latentDanger, LatentDangerExecuteTypeEnum.填写隐患完成, null,
                "隐患排查与治理", this.getNextExecuteUsers(latentDanger.getInstanceId()), userRealName, departmentName);
        try {
            webMqttComponent.publish(dangerTopic, "");
        } catch (Exception e) {
            logger.error("隐患提交数字换流站页面推送失败-----------" + e.getMessage());
        }
        return CommonResponseUtil.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public List<LatentDanger> savePatrol(List<LatentDangerDto> latentDangerDtoList, String userId,
                                         String userRealName,
                                         String departmentId, String departmentName, String companyId, String orgCode, RoleBo role) throws Exception {
        if (ValidationUtil.isEmpty(latentDangerDtoList)) {
            throw new Exception("参数有误");
        }

        // 获取业务类型枚举
        LatentDangerBizTypeEnum bizTypeEnum =
                LatentDangerBizTypeEnum.getByCode(bizType);
        if (ValidationUtil.isEmpty(bizTypeEnum)) {
            throw new Exception("业务类型有误");
        }

        List<LatentDanger> dangerList = Lists.newArrayList();
        for (LatentDangerDto param : latentDangerDtoList) {
            String businessKey = RandomUtil.buildOrderNo();
            LatentDangerLevelEnum levelEnum = LatentDangerLevelEnum.getEnumByCode(param.getDangerLevel());
            if (levelEnum == null) {
                throw new Exception("隐患等级参数有误");
            }

            LatentDangerTypeEnum dangerTypeEnum =
                    LatentDangerTypeEnum.getByCode(latentDangerDtoList.get(0).getCheckMode());
            if (ValidationUtil.isEmpty(dangerTypeEnum)) {
                throw new Exception("检查类型参数有误");
            }

            // 保存隐患
            LatentDanger latentDanger = saveLatentDanger(param, userId, departmentId, businessKey, orgCode,
                    dangerTypeEnum);

            JSONObject instance = new JSONObject();
            // 巡检业务需要在填写隐患后直接开启工作流
            if (bizTypeEnum == LatentDangerBizTypeEnum.巡检) {
                // 更新巡检p_check_input表state字段
                updateCheckInputDangerState(latentDanger.getBizId(), DangerHandleStateEnum.HANDLE.getCode());

                Long dangerId = latentDanger.getId();
                Date startDate = new Date();
                JSONObject jsonObject = remoteWorkFlowService.startNew(dangerId, businessKey, processDefinitionKey);
                Date endDate = new Date();
                logger.info("-------------------------提交隐患时间" + (endDate.getTime() - startDate.getTime()));
                if (jsonObject == null) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    throw new Exception("启动流程失败");
                }
                instance = jsonObject.getJSONObject("data");
                if (instance == null) {
                    throw new Exception("无提交隐患权限");
                }
            }

            JSONObject flowJson = new JSONObject();
            if (!ValidationUtil.isEmpty(param.getPhotoUrl())) {
                flowJson.put("photoUrls", Joiner.on(",").join(param.getPhotoUrl()));
            }
            if (ValidationUtil.isEmpty(param.getId())) {
                // 第一次保存隐患提交记录
                LatentDangerFlowRecord inputRecord = saveFlowRecord(instance.getString("id"), "提交隐患", userId, departmentId,
                        flowJson, latentDanger.getId(), role, LatentDangerExecuteTypeEnum.填写隐患完成.getName(),
                        latentDanger.getRemark(), userRealName, departmentName, latentDanger.getDangerState(), ExecuteTypeEnum.通过.getCode());
                latentDanger.setCurrentFlowRecordId(inputRecord.getId());
                latentDanger.setInstanceId(instance.getString("id"));
                latentDangerMapper.updateById(latentDanger);
                ruleDangerService.addLatentDangerRule(latentDanger, RuleTypeEnum.隐患第一次提交.getCode(), onSiteConfirmRole);
            }

            // TODO 使用远程调用替换
//            LatentDangerPatrolBo patrolBo = latentDangerPatrolMapper.getByDangerId(latentDanger.getId());
//            sendMessage(latentDanger, LatentDangerExecuteTypeEnum.填写隐患完成, patrolBo,
//                    "巡检隐患排查与治理", this.getNextExecuteUsers(latentDanger.getInstanceId()), userRealName, departmentName);
//            try {
//                webMqttComponent.publish(dangerTopic, "");
//            } catch (Exception e) {
//                logger.error("巡检隐患提交数字换流站页面推送失败-----------" + e.getMessage());
//            }

            dangerList.add(latentDanger);
        }
        return dangerList;
    }

    // TODO 使用远程调用替换
//    private void updateMeasuresContentStatus(Long riskFactorId, Long measuresContentId, String evaluateId, RiskFactorsCmStatusEnum riskFactorsCmStatusEnum) {
//        Map<String, Object> map = Maps.newHashMap();
//        map.put("riskFactorId", riskFactorId);
//        map.put("measuresContentId", measuresContentId);
//        map.put("evaluateId", evaluateId);
//        map.put("status", riskFactorsCmStatusEnum.getCode());
//        riskFactorCmMapper.updateStatusByMap(map);
//        RiskFactorBo riskFactorBo = new RiskFactorBo();
//        riskFactorBo.setId(riskFactorId);
//        Long outControlNumber = riskFactorCmMapper.countOutControl(map);
//        if (outControlNumber.equals(0L)) {
//            riskFactorBo.setControlStatus(RiskFactorsCmStatusEnum.Control.getName());
//        } else {
//            riskFactorBo.setControlStatus(RiskFactorsCmStatusEnum.outOfControl.getName());
//        }
//        riskFactorMapper.updateControlStatus(riskFactorBo);
//    }

    // TODO 使用远程调用替换
    private void updateCheckInputDangerState(Long id, int code) {
        latentDangerMapper.updateCheckInputDangerState(id, code);
    }

//    public LatentDanger saveLatentDanger(String bizType, String instanceId, String problemDescription, String remark,
//                                           String userId, String departmentId, String businessKey, String orgCode,
//                                           String dangerName, String level, String position,
//                                           LatentDangerTypeEnum dangerTypeEnum, List<String> photoUrls,
//                                           Long checkInputId, Long structureId, String structureName,
//                                           String instanceKey, String longitude, String latitude) {
//        LatentDanger latentDanger = new LatentDanger();
//        latentDanger.setBizType(bizType);
//        latentDanger.setInstanceId(instanceId);
//        latentDanger.setProblemDescription(problemDescription);
//        latentDanger.setRemark(remark);
//        latentDanger.setDangerState(LatentDangerStateEnum.待评审.getCode().toString());
//        latentDanger.setDiscovererUserId(userId);
//        latentDanger.setDiscovererDepartmentId(departmentId);
//        latentDanger.setBusinessKey(businessKey);
//        latentDanger.setOrgCode(orgCode);
//        latentDanger.setDangerName(dangerName);
//        latentDanger.setDangerLevel(level);
//        latentDanger.setDangerPosition(position);
//        latentDanger.setDangerType(dangerTypeEnum.getCode().toString());
//        latentDanger.setLongitude(longitude);
//        latentDanger.setLatitude(latitude);
//        latentDanger.setPhotoUrls(Joiner.on(",").join(photoUrls));
//        latentDanger.setBizId(checkInputId);
//        latentDanger.setStructureId(structureId);
//        latentDanger.setStructureName(structureName);
//        latentDanger.setInstanceKey(instanceKey);
//        this.saveOrUpdate(latentDanger);
//        return latentDanger;
//    }

    public LatentDanger saveLatentDanger(LatentDangerDto dangerDto, String userId,
                                         String departmentId, String businessKey, String orgCode,
                                         LatentDangerTypeEnum dangerTypeEnum) {
        LatentDanger latentDanger = new LatentDanger();
        Bean.copyExistPropertis(dangerDto, latentDanger);
        if (ValidationUtil.isEmpty(dangerDto.getId())) {
            // 新增
            latentDanger.setBusinessKey(businessKey);
            latentDanger.setDiscovererDepartmentId(departmentId);
            latentDanger.setDiscovererUserId(userId);
            latentDanger.setOrgCode(orgCode);
            latentDanger.setDangerType(dangerTypeEnum.getCode());
            latentDanger.setDangerTypeName(dangerTypeEnum.getName());
            if (LatentDangerBizTypeEnum.防火监督.getCode().equals(bizType)) {
                latentDanger.setDangerState(LatentDangerState.SupervisionDangerStateEnum.提交隐患.getCode());
                latentDanger.setDangerStateName(LatentDangerState.SupervisionDangerStateEnum.提交隐患.getName());
            } else if (LatentDangerBizTypeEnum.巡检.getCode().equals(bizType)) {
                latentDanger.setDangerState(LatentDangerState.PatrolDangerStateEnum.待评审.getCode());
                latentDanger.setDangerStateName(LatentDangerState.PatrolDangerStateEnum.待评审.getName());
            }
            if (ValidationUtil.isEmpty(dangerDto.getDangerName())) {
                latentDanger.setDangerName(dangerDto.getInputItemName());
            }
        }
        if (!ValidationUtil.isEmpty(dangerDto.getPhotoUrl())) {
            latentDanger.setPhotoUrls(Joiner.on(",").join(dangerDto.getPhotoUrl()));
        }
        this.saveOrUpdate(latentDanger);
        return latentDanger;
    }

    public LatentDangerFlowRecord saveFlowRecord(String taskId, String taskName, String userId, String departmentId,
                                                 JSONObject flowJson, Long dangerId, RoleBo role,
                                                 String executeResult, String remark, String userName,
                                                 String departmentName, String dangerState, Integer executeState) {
        LatentDangerFlowRecord record = new LatentDangerFlowRecord();
        record.setFlowTaskId(taskId);
        record.setExecuteUserId(userId);
        record.setExecuteUserName(userName);
        record.setExecuteDepartmentId(departmentId);
        record.setExecuteDepartmentName(departmentName);
        record.setFlowJson(flowJson != null ? flowJson.toJSONString() : null);
        record.setFlowTaskName(taskName);
        record.setDangerId(dangerId);
        record.setExecuteState(executeState);
        record.setExecuteResult(executeResult);
        record.setActionFlag(dangerState);
        record.setRemark(remark);
        record.setUpdateDate(new Date());
        latentDangerFlowRecordService.saveOrUpdate(record);
        return record;
    }

    public LatentDangerFlowRecordBo saveFlowRecord(String taskId, String userIds, String taskName,
                                                   String taskDefinitionKey, Long dangerId) {
        LatentDangerFlowRecordBo record = new LatentDangerFlowRecordBo();
        record.setFlowTaskId(taskId);
        record.setFlowTaskUserIds(userIds);
        record.setFlowTaskName(taskName);
        record.setActionFlag(taskDefinitionKey);
        record.setDangerId(dangerId);
        record.setUpdateDate(new Date());
        latentDangerFlowRecordMapper.save(record);
        return record;
    }

    public void updateFlowRecord(LatentDangerFlowRecordBo flowRecordBo, LatentDangerExecuteTypeEnum executeTypeEnum,
                                 String userId, String departmentId, String remark, JSONObject flowJson) {
        flowRecordBo.setExecuteState(executeTypeEnum.getExecuteState().getCode());
        flowRecordBo.setExcuteDepartmentId(departmentId);
        flowRecordBo.setExecuteUserId(userId);
        flowRecordBo.setExecuteResult(executeTypeEnum.getName());
        if (!StringUtils.isEmpty(remark)) {
            flowRecordBo.setRemark(remark);
        }
        if (flowJson != null) {
            flowRecordBo.setFlowJson(flowJson.toJSONString());
        }
        latentDangerFlowRecordMapper.update(flowRecordBo);
    }

    private Set<String> getUserIdsStrByTypeAndDefKey(String definitionKey) {
        List<AgencyUserModel> users = remoteSecurityService.listUserByMenuCode(acctivePermissionType, definitionKey);
        if (CollectionUtils.isEmpty(users)) {
            return Sets.newHashSet();
        } else {
            return Sets.newHashSet(Lists.transform(users, AgencyUserModel::getUserId));
        }
    }

    private Set<String> getUserIdsStrByPerTypeAndDefKey(JSONObject jsonObject) {
        String taskDefinitionKey = jsonObject.getString("taskDefinitionKey");
//        List<UserModel> users = remoteSecurityService.listUserByMenuCode(acctivePermissionType, taskDefinitionKey);
//        if (CollectionUtils.isEmpty(users)) {
//            return Sets.newHashSet();
//        } else {
//            return Sets.newHashSet(Lists.transform(users, UserModel::getUserId));
//        }
        return getUserIdsStrByTypeAndDefKey(taskDefinitionKey);
    }

    private Map<String, Object> buildQueryMapForList(LatentDangerListParam latentDangerListParam, String userId) {
        Map<String, Object> map = Maps.newHashMap();
        Long offset = latentDangerListParam.getOffset();
        map.put("offset", offset);
        map.put("limit", latentDangerListParam.getPageSize());
        if (latentDangerListParam.getIsHandle() != null) {
            List<String> states = Lists.newArrayList();
            if (latentDangerListParam.getIsHandle()) {
                states.add(LatentDangerStateEnum.治理完毕.getCode());
                states.add(LatentDangerStateEnum.已撤销.getCode());
            } else {
                states.add(LatentDangerStateEnum.待验证.getCode());
                states.add(LatentDangerStateEnum.延期治理申请.getCode());
                states.add(LatentDangerStateEnum.安措计划中.getCode());
                states.add(LatentDangerStateEnum.待治理.getCode());
                states.add(LatentDangerStateEnum.待评审.getCode());
                states.add(LatentDangerStateEnum.延期治理申请待车间部门审核.getCode());
                states.add(LatentDangerStateEnum.延期治理申请待公司审核.getCode());
            }
            map.put("states", states);
        }
        if (!latentDangerListParam.getBelongType().equals(0)) {
            map.put("userId", userId);
        }
        if (!latentDangerListParam.getDangerLevel().equals(-1)) {
            map.put("dangerLevel", latentDangerListParam.getDangerLevel());
        }
        if (!latentDangerListParam.getDangerState().equals(0)) {
            map.put("dangerState", latentDangerListParam.getDangerState());
        }
        if (!StringUtils.isEmpty(latentDangerListParam.getDangerName())) {
            map.put("dangerName", latentDangerListParam.getDangerName());
        }
        return map;
    }

    @Override
    public CommonResponse list(String toke, String product, String appKey, LatentDangerListParam latentDangerListParam, AgencyUserModel user, String loginOrgCode, String deptId) {
        JSONObject respBody;
        Date startDate = new Date();
        if (latentDangerListParam.getIsHandle()) {
            respBody = remoteWorkFlowService.completedPageTask(user.getUserName(), latentDangerListParam.getBelongType());
        } else {
            respBody = remoteWorkFlowService.pageTask(user.getUserId(), latentDangerListParam.getBelongType());
        }
        Date endDate = new Date();
        logger.info("-------------------------工作流列表时间" + (endDate.getTime() - startDate.getTime()));
        JSONArray taskJsonList = respBody.getJSONArray("data");
        List<JSONObject> taskList = JSONObject.parseArray(taskJsonList.toJSONString(), JSONObject.class);
        List<String> bussinessKeys = new ArrayList<>();
        for (JSONObject json : taskList) {
            bussinessKeys.add(json.getString("businessKey"));
        }
        if (0 == latentDangerListParam.getBelongType()) {
            latentDangerListParam.setUserId(null);
        }
        if (null == latentDangerListParam.getDangerLevel()) {
            latentDangerListParam.setDangerLevel(null);
        }
        if ("0" == latentDangerListParam.getDangerState()) {
            latentDangerListParam.setDangerState(null);
        }
        Date startDate1 = new Date();
        int dangerListSize = latentDangerMapper.countByBathBusinessKeys(bussinessKeys, latentDangerListParam);
        List<LatentDangerBo> dangerList = latentDangerMapper.getByBathBusinessKeys(bussinessKeys, latentDangerListParam);
        Date endDate1 = new Date();
        logger.info("-------------------------sql时间" + (endDate1.getTime() - startDate1.getTime()));
//        Map<String, Object> map = buildQueryMapForList(latentDangerListParam, userId);
//        map.put("org_code", loginOrgCode);
//        map.put("discoverer_department_id", deptId);
//        String permissions = hasProcessBPermission(userId, acctivePermissionType);
//        map.put("permissions", permissions);
//        List<LatentDangerBo> list = latentDangerMapper.listByMap(map);
//        Long count = 0L;
        List<LatentDangerListVo> voList = Lists.newArrayList();
        Date date = new Date();
        if (!CollectionUtils.isEmpty(dangerList)) {
            Set<String> userIds = Sets.newHashSet();
            dangerList.forEach(e -> userIds.add(e.getDiscovererUserId()));
            String userIdsStr = Joiner.on(",").join(userIds);
            List<AgencyUserModel> users = remoteSecurityService.listUserByUserIds(toke, product, appKey, userIdsStr);
            Map<String, AgencyUserModel> userMap = Maps.uniqueIndex(users, AgencyUserModel::getUserId);
            for (LatentDangerBo bo : dangerList) {
                JSONObject task = taskList.stream().filter(t -> t.getString("businessKey").equals(bo.getBusinessKey())).collect(Collectors.toList()).get(0);
                LatentDangerListVo vo = new LatentDangerListVo();
                vo.setTaskId(task.getString("id"));
                vo.setDangerId(bo.getId());
                vo.setOvertimeState(bo.getOvertimeState());
                vo.setDangerName(bo.getDangerName());
                vo.setDiscovererUserName(userMap.get(bo.getDiscovererUserId()).getRealName());
                vo.setLevel(bo.getDangerLevel());
                LatentDangerLevelEnum levelEnum = LatentDangerLevelEnum.getEnumByCode(bo.getDangerLevel());
                if (levelEnum != null) {
                    vo.setLevelDesc(levelEnum.getName());
                }
                vo.setState(bo.getDangerState());
                LatentDangerStateEnum stateEnum = LatentDangerStateEnum.getByCode(bo.getDangerState());
                if (stateEnum != null) {
                    vo.setStateDesc(stateEnum.getName());
                }
                vo.setLimitDesc(getLimitDesc(bo, date));
                voList.add(vo);
            }
//            count = latentDangerMapper.countByMap(map);
        }
//        return CommonResponseUtil.success(new PageImpl<>(newList, latentDangerListParam, respBody.getLong("total")));
        return CommonResponseUtil.success(new PageImpl<>(voList, latentDangerListParam, dangerListSize));
    }

    /**
     * 获取指定用户具有隐患权限的code
     *
     * @param userId         指定用户id
     * @param permissionType “activitiItem”
     * @return permissions 具有隐患权限的code（逗号分割）
     */
    private String hasProcessBPermission(String userId, String permissionType) {
        String permissions = "";
        // 根据用户id和许可类型获取用户所有的授权操作菜单路径（"B"、"B_1"、"G_1_1"、"A"、"A_1"、"C".....）
        JSONArray jsonArray = remoteSecurityService.getMenuPathByUserIdAndPermissionType(userId, permissionType);
        if (CollectionUtils.isEmpty(jsonArray)) {
            return "";
        }
        // 过滤出隐患权限菜单路径（"B_1,B_2.....B_10"）
        Object obj = jsonArray.stream().filter(i -> i.toString().matches("^B_\\d+")).collect(Collectors.toList());
        if (!ValidationUtil.isEmpty(obj) && ((List<String>) obj).size() > 0) {
            permissions = Joiner.on(",").join((List<String>) obj);
        }
        return permissions;
    }

    private String getLimitDesc(LatentDangerBo bo, Date start) {
        String dangerState = bo.getDangerState();
        if (LatentDangerStateEnum.已撤销.getCode().equals(dangerState) || LatentDangerStateEnum.治理完毕.getCode().equals(dangerState)) {
            if (bo.getOvertimeState().equals(LatentDangerOvertimeStateEnum.已逾期.getCode())) {
                return "逾期治理";
            } else {
                return "按期治理";
            }
        } else {
            Date end = bo.getReformLimitDate();
            if (end == null) {
                return "";
            }
            if (bo.getOvertimeState().equals(LatentDangerOvertimeStateEnum.已逾期.getCode())) {
                return "逾期未治理";
            } else {
                long betweenSecond = (end.getTime() - start.getTime()) / 1000;
                if (betweenSecond < 0) {
                    return "逾期未治理";
                } else {
                    String str = "";
                    if (betweenSecond > 3600) {
                        long hour = betweenSecond / 3600;
                        str += hour + "时";
                        betweenSecond = betweenSecond % 3600;
                    }
                    if (betweenSecond > 60) {
                        long minute = betweenSecond / 60;
                        str += minute + "分";
                        betweenSecond = betweenSecond % 60;
                    }
                    if (betweenSecond > 0) {
                        str += betweenSecond + "秒";
                    }
                    return str;
                }
            }
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public DangerExecuteSubmitDto execute(LatentDangerExecuteParam latentDangerExecuteParam, String userId, String userRealName, String departmentId, String departmentName, ReginParams reginParams) throws Exception {

        DangerExecuteSubmitDto executeSubmitDto = new DangerExecuteSubmitDto();
        LatentDanger latentDanger = latentDangerMapper.selectById(latentDangerExecuteParam.getDangerId());
        if (ValidationUtil.isEmpty(latentDanger)) {
            executeSubmitDto.setIsOk(false);
            executeSubmitDto.setMsg("隐患不存在");
            return executeSubmitDto;
        }

        DangerExecuteSubmitDto dangerExecuteSubmitDto = executeSubmit(latentDangerExecuteParam, latentDanger, userId,
                userRealName, departmentId, departmentName, executeSubmitDto, reginParams);
        try {
            if (dangerExecuteSubmitDto.getIsOk()) {
                webMqttComponent.publish(dangerTopic, "");
            } else {
                throw new Exception(executeSubmitDto.getMsg());
            }
        } catch (Exception e) {
            logger.error("隐患执行结果推送失败-----------" + e.getMessage());
        }

        return dangerExecuteSubmitDto;
    }

    @Override
    public ResponseModel<LatentDangerDetailVo> detail(Long dangerId, String userId, boolean isFinish) {
        LatentDanger latentDanger = this.baseMapper.selectById(dangerId);
//        JSONObject jsonObject;
//        if (isFinish) {
//            jsonObject = remoteWorkFlowService.queryFinishTaskDetail(id);
//        } else {
//            jsonObject = remoteWorkFlowService.queryTaskDetail(id);
//        }
//
//        JSONObject task = jsonObject.getJSONObject("data");
//        LatentDangerBo latentDangerBo = latentDangerMapper.getByBusinessKey(task.getString("businessKey"));

//        LatentDangerBo latentDangerBo = latentDangerMapper.getByBusinessKey("20210923163838164");

        LatentDangerDetailVo detailVo = new LatentDangerDetailVo();
        if (latentDanger != null) {
            Bean.copyExistPropertis(latentDanger, detailVo);
            LatentDangerTypeEnum dangerTypeEnum = LatentDangerTypeEnum.getByCode(latentDanger.getDangerType());
            if (dangerTypeEnum != null) {
                detailVo.setDangerTypeName(dangerTypeEnum.getName());
            }
            if (StringUtils.isEmpty(latentDanger.getDangerPosition())) {
                detailVo.setDangerPosition(latentDanger.getStructureName());
            } else {
                detailVo.setDangerPosition(latentDanger.getStructureName() + "·" + latentDanger.getDangerPosition());
            }

            LatentDangerStateEnum dangerStateEnum = LatentDangerStateEnum.getByCode(latentDanger.getDangerState());
            if (dangerStateEnum != null) {
                detailVo.setDangerStateName(dangerStateEnum.getName());
            }
            detailVo.setDangerName(latentDanger.getDangerName());
            LatentDangerLevelEnum levelEnum = LatentDangerLevelEnum.getEnumByCode(latentDanger.getDangerLevel());
            if (levelEnum != null) {
                detailVo.setDangerLevelName(levelEnum.getName());
            }
            if (latentDanger.getReformType() != null) {
                LatentDangerReformTypeEnum typeEnum = LatentDangerReformTypeEnum.getEnumByCode(latentDanger.getReformType());
                if (typeEnum != null) {
                    detailVo.setReformTypeName(typeEnum.getName());
                }
            }
            if (!StringUtils.isEmpty(latentDanger.getReformJson())) {
                detailVo.setReformJson(latentDanger.getReformJson());
            }
            if (!StringUtils.isEmpty(latentDanger.getPhotoUrls())) {
                List<String> photoUrls = Lists.newArrayList(latentDanger.getPhotoUrls().split(","));
                detailVo.setPhotoUrl(photoUrls);
            }

            List<LatentDangerFlowRecordBo> records = latentDangerFlowRecordMapper.listByDangerId(latentDanger.getId());
            if (!CollectionUtils.isEmpty(records)) {
                for (LatentDangerFlowRecordBo recordBo : records) {
                    recordBo.setExecuteTime(DateUtil.date2Str(recordBo.getCreateDate(), DateUtil.DATETIME_DEFAULT_FORMAT));
                }
                detailVo.setRecords(records);
            }

            if (bizType.equals(LatentDangerBizTypeEnum.巡检.getCode())) {
//                buildOfDifferentDangerType(latentDangerBo, detailVo);
            }

//            detailVo.setTaskId(task.getString("id"));
        }
        return ResponseHelper.buildResponse(detailVo);
    }

    /**
     * 根据隐患类型填充隐患对象属性（计划检查和无计划检查填充图片及风险点信息）
     *
     * @param latentDangerBo
     * @param detailVo
     */
    private void buildOfDifferentDangerType(LatentDangerBo latentDangerBo, LatentDangerDetailVo detailVo) {
        if (latentDangerBo.getDangerType().equals(LatentDangerTypeEnum.计划检查.getCode())
                || latentDangerBo.getDangerType().equals(LatentDangerTypeEnum.无计划检查.getCode())) {
            // TODO 使用远程调用替换
            LatentDangerPatrolBo patrolBo = latentDangerPatrolMapper.getByDangerId(latentDangerBo.getId());
            if (patrolBo != null) {
                LatentDangerDetailRiskVo riskVo = new LatentDangerDetailRiskVo();
                List<String> basis = new ArrayList<>();
                if (!StringUtils.isEmpty(patrolBo.getItemBasis())) {
                    basis.add(patrolBo.getItemBasis());
                }
                riskVo.setBasis(basis);
                riskVo.setPointName(patrolBo.getPointName());
                riskVo.setPointNo(patrolBo.getPointNo());
                riskVo.setPointLevel(!ValidationUtil.isEmpty(patrolBo.getPointLevel()) ? patrolBo.getPointLevel() : "");
                riskVo.setPlanName(patrolBo.getPlanName());
                riskVo.setCheckTime(patrolBo.getCheckTime());
                AgencyUserModel checkUser = remoteSecurityService.getUserById(RequestContext.getToken(), getProduct(), RequestContext.getAppKey(), patrolBo.getCheckUserId());
                if (!ValidationUtil.isEmpty(checkUser)) {
                    riskVo.setCheckUser(checkUser.getRealName());
                }
                // TODO 使用远程调用替换
//                RiskFactorBo riskFactorBo = !ValidationUtil.isEmpty(patrolBo.getClassifyOriginalId()) ? riskFactorMapper.getById(Long.valueOf(patrolBo.getClassifyOriginalId())) : null;
//                if (riskFactorBo != null && riskFactorBo.getEquipmentDepartmentId() != null) {
//                    DepartmentModel department = remoteSecurityService.getDepartmentByDeptId(RequestContext.getToken(), getProduct(), RequestContext.getAppKey(), riskFactorBo.getEquipmentDepartmentId().toString());
//                    if (department != null) {
//                        riskVo.setBelongDepartmentName(department.getDepartmentName());
//                    }
//                }
//                List<CheckShot> checkShots = iCheckShotDao.findAllByCheckIdAndCheckInputId(patrolBo.getCheckId(),
//                        latentDangerBo.getCheckInputId());
//                if (!CollectionUtils.isEmpty(checkShots)) {
//                    List<String> photos = Lists.transform(checkShots, e -> {
//                        if (e != null) {
//                            return fileServerAddress + e.getPhotoData().replaceAll("\\\\", "/");
//                        } else {
//                            return "";
//                        }
//                    });
//                    detailVo.setPhotoUrls(photos);
//                }
                detailVo.setRiskInfo(riskVo);
            }
        }
    }

    @Override
    public CommonResponse getByInstanceId(String instanceId) {
        LatentDangerBo latentDangerBo = latentDangerMapper.getByInstanceId(instanceId);
        if (latentDangerBo == null) {
            return CommonResponseUtil.failure("隐患不存在");
        }
        JSONObject result = new JSONObject();
        JSONObject baseInfo = new JSONObject();
        JSONObject reviewInfo = new JSONObject();
        JSONObject dangerInfo = new JSONObject();
        Set<String> userIds = Sets.newHashSet();
        userIds.add(latentDangerBo.getDiscovererUserId());
        LatentDangerPatrolBo patrolBo = null;
        if (latentDangerBo.getDangerType().equals(LatentDangerTypeEnum.计划检查.getCode())) {
            patrolBo = latentDangerPatrolMapper.getByDangerId(latentDangerBo.getId());
            JSONArray checkTypeArray = remoteSecurityService.listDictionaryByDictCode(RequestContext.getToken(), getProduct(),
                    RequestContext.getAppKey(), Constants.CHECK_TYPE);
            Map<String, String> checkTypeMap = Maps.newHashMap();
            for (int i = 0; i < checkTypeArray.size(); i++) {
                JSONObject categoryJson = checkTypeArray.getJSONObject(i);
                checkTypeMap.put(categoryJson.getString("dictDataKey"), categoryJson.getString("dictDataValue"));
            }
            if (patrolBo != null) {
                // TODO 使用远程调用替换
//                PointClassify classify = iPointClassifyDao.getOne(patrolBo.getPointClassifyId());
//                RiskFactorBo riskFactorBo = riskFactorMapper.getById(Long.valueOf(classify.getOriginalId()));
                String jsonStr = patrolBo.getItemBasis();
                String itemBasis = "";
                if (!StringUtils.isEmpty(jsonStr)) {
                    StringBuilder itemBasisBuilder = new StringBuilder();
                    JSONArray arr = JSONArray.parseArray(jsonStr);
                    for (int i = 0; i < arr.size(); i++) {
                        JSONObject object = arr.getJSONObject(i);
                        itemBasisBuilder.append(object.getString("name")).append(",");
                    }
                    itemBasis = itemBasisBuilder.length() > 0 ? itemBasisBuilder.substring(0, itemBasisBuilder.length() - 1) : itemBasis;
                }
//                if (riskFactorBo != null) {
                if (true) {
                    userIds.add(patrolBo.getCheckUserId());
                    dangerInfo.put("type", "设备设施类");
                    // TODO 使用远程调用替换
//                    dangerInfo.put("equipmentCode", riskFactorBo.getEquipmentCode());
                    dangerInfo.put("isCheckWithPlan", "是");
                    dangerInfo.put("planName", patrolBo.getPlanName());
                    dangerInfo.put("planType", checkTypeMap.get(patrolBo.getCheckType()));
                    dangerInfo.put("routeName", patrolBo.getRouteName());
                    dangerInfo.put("classifyName", patrolBo.getClassifyName());
                    dangerInfo.put("itemName", patrolBo.getItemName());
                    dangerInfo.put("itemBasis", itemBasis);
                    dangerInfo.put("itemRemark", patrolBo.getItemRemark());
                    dangerInfo.put("checkTime", DateUtil.str2Date(patrolBo.getCheckTime(), DateUtil.DATETIME_DEFAULT_FORMAT));
                }
            }
        }
        LatentDangerFlowRecordBo reviewRecordBo = latentDangerFlowRecordMapper.getByDangerIdAndActionFlag(latentDangerBo.getId(), "B_2");
        LatentDangerFlowRecordBo reformRecordBo = latentDangerFlowRecordMapper.getByDangerIdAndActionFlag(latentDangerBo.getId(), "B_3");
        if (reviewRecordBo != null) {
            userIds.add(reviewRecordBo.getExecuteUserId());
        }
        if (reformRecordBo != null) {
            userIds.add(reformRecordBo.getExecuteUserId());
        }
        userIds.removeAll(Collections.singleton(null));
        List<AgencyUserModel> userModels = remoteSecurityService.listUserByUserIds(Joiner.on(",").join(userIds));
        Map<String, AgencyUserModel> userMap = Maps.uniqueIndex(userModels, AgencyUserModel::getUserId);
        AgencyUserModel user = userMap.get(latentDangerBo.getDiscovererUserId());
        baseInfo.put("orderNo", latentDangerBo.getBusinessKey());
        baseInfo.put("startTime", latentDangerBo.getCreateDate());
        if (user != null) {
            baseInfo.put("userName", user.getRealName());
        }
        DepartmentBo departmentBo = remoteSecurityService.getDepartmentByDeptId(latentDangerBo.getDiscovererDepartmentId());
        if (departmentBo != null) {
            baseInfo.put("department", departmentBo.getDepartmentName());
        }
        LatentDangerLevelEnum levelEnum = LatentDangerLevelEnum.getEnumByCode(latentDangerBo.getDangerLevel());
        if (levelEnum != null) {
            dangerInfo.put("latentDangerLevel", levelEnum.getName());
        }
        dangerInfo.put("latentDangerName", latentDangerBo.getDangerName());
        if (!StringUtils.isEmpty(latentDangerBo.getReformJson())) {
            String str = JSONObject.parseObject(latentDangerBo.getReformJson()).getString("rectMeasures");
            dangerInfo.put("reformJson", str.replace("\\n", "\\\\n"));
        }
        dangerInfo.put("reformLimitDate", latentDangerBo.getReformLimitDate());
        if (reformRecordBo != null) {
            AgencyUserModel reformUser = userMap.get(reformRecordBo.getExecuteUserId());
            if (reformUser != null) {
                dangerInfo.put("reformUserName", reformUser.getRealName());
            }
        }
        if (patrolBo != null) {
            if (patrolBo.getCheckUserId() != null) {
                AgencyUserModel checkUser = userMap.get(patrolBo.getCheckUserId());
                if (checkUser != null) {
                    dangerInfo.put("checkUserName", checkUser.getRealName());
                }
            }
            if (patrolBo.getCheckDepartmentId() != null) {
                DepartmentBo checkDepartment = remoteSecurityService.getDepartmentByDeptId(patrolBo.getCheckDepartmentId());
                if (checkDepartment != null) {
                    dangerInfo.put("checkUserDeptName", checkDepartment.getDepartmentName());
                }
            }
        }
        if (reviewRecordBo != null) {
            AgencyUserModel reviewUser = userMap.get(reviewRecordBo.getExecuteUserId());
            reviewInfo.put("reviewUserName", !ValidationUtil.isEmpty(reviewUser) ? reviewUser.getRealName() : "");
            reviewInfo.put("reviewDate", !ValidationUtil.isEmpty(reviewUser) ? reviewRecordBo.getUpdateDate() : "");
            reviewInfo.put("reviewResult", !ValidationUtil.isEmpty(reviewUser) ? reviewRecordBo.getExecuteResult() : "");
        }
        result.put("baseInfo", baseInfo);
        result.put("dangerInfo", dangerInfo);
        result.put("reviewInfo", reviewInfo);
        result.put("latentDangerType", latentDangerBo.getDangerType());
        LatentDangerTypeEnum typeEnum = LatentDangerTypeEnum.getByCode(latentDangerBo.getDangerType());
        if (typeEnum != null) {
            result.put("latentDangerTypeDesc", typeEnum.getName());
        }
        return CommonResponseUtil.success(result);
    }

    @Transactional
    @Override
    public DangerExecuteSubmitDto executeCallBack(String instanceId, Integer actionType, String remark, String token,
                                                  String userId, String userRealName, String departmentId, String departmentName) {
        DangerExecuteSubmitDto executeSubmitDto = new DangerExecuteSubmitDto();
        executeSubmitDto.setIsOk(true);
        LatentDanger latentDanger =
                latentDangerMapper.selectOne(new LambdaQueryWrapper<LatentDanger>().eq(LatentDanger::getInstanceId,
                        instanceId));
        if (latentDanger != null) {
            LatentDangerFlowRecordBo currentRecord = latentDangerFlowRecordMapper.getById(latentDanger.getCurrentFlowRecordId());
            if (actionType.equals(1)) {
                //通过
                LatentDangerExecuteTypeEnum executeTypeEnum = LatentDangerExecuteTypeEnum.公司负责人审核通过;
                updateFlowRecord(currentRecord, executeTypeEnum, userId, departmentId, remark, null);
                JSONObject flowJson = remoteWorkFlowService.allTasksInProcessInstanceId(latentDanger.getInstanceId());
                if (flowJson == null) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return executeSubmitDto;
                }
                LatentDangerPatrolBo patrolBo = null;
                String userIds;
                if (latentDanger.getDangerType().equals(LatentDangerTypeEnum.计划检查.getCode())) {
                    patrolBo = latentDangerPatrolMapper.getByDangerId(latentDanger.getId());
                    userIds = Joiner.on(",").join(getUserIdsStrByPerTypeAndDefKey(flowJson));
                } else {
                    LatentDangerFlowRecordBo recordBo = latentDangerFlowRecordMapper.getByDangerIdAndActionFlag(latentDanger.getId(), "B_8");
                    userIds = recordBo.getFlowTaskUserIds();
                }
                LatentDangerFlowRecordBo record = saveFlowRecord(flowJson.getString("id"), userIds,
                        flowJson.getString("name"), flowJson.getString("taskDefinitionKey"), latentDanger.getId());
                latentDanger.setCurrentFlowRecordId(record.getId());
                latentDanger.setDangerState(executeTypeEnum.getNextState().getCode().toString());
                latentDangerMapper.updateById(latentDanger);
                ///web推送刷新消息
//                dangerStateChangeWebSockte(latentDangerBo);
//                Set<String> nextExecuteUserIds = Sets.newHashSet(Arrays.asList(userIds.split(",")));
                sendMessage(latentDanger, executeTypeEnum, patrolBo, currentRecord.getFlowTaskName(), this.getNextExecuteUsers(latentDanger.getInstanceId()), userRealName, departmentName);
            } else if (actionType.equals(2)) {
                //终止
                latentDanger.setDangerState(LatentDangerStateEnum.已撤销.getCode().toString());
                latentDangerMapper.updateById(latentDanger);
                if (latentDanger.getDangerType().equals(LatentDangerTypeEnum.计划检查.getCode())) {
                    LatentDangerPatrolBo patrolBo = latentDangerPatrolMapper.getByDangerId(latentDanger.getId());
                    if (patrolBo.getClassifyOriginalId() != null && patrolBo.getItemOriginalId() != null) {
//                        updateMeasuresContentStatus(Long.valueOf(patrolBo.getClassifyOriginalId()), Long.valueOf(patrolBo.getItemOriginalId()),
//                                patrolBo.getRiskFactorFlowId(), RiskFactorsCmStatusEnum.Control);
                    }
                    LatentDangerLevelEnum levelEnum = LatentDangerLevelEnum.getEnumByCode(latentDanger.getDangerLevel());
                    if (levelEnum != null) {
                        updateRiskSourceDangerState(false, Long.valueOf(patrolBo.getPointOriginalId()), levelEnum, patrolBo.getPointId(), latentDanger.getId());
                    }
                    executeSubmitDto.setDangerId(latentDanger.getId());
                    executeSubmitDto.setDangerName(latentDanger.getDangerName());
                    executeSubmitDto.setPointOriginalId(patrolBo.getPointOriginalId());
                    executeSubmitDto.setPointId(patrolBo.getPointId());
                    executeSubmitDto.setExecuteTypeEnum(LatentDangerExecuteTypeEnum.隐患评审拒绝);
                }
            } else if (actionType.equals(3)) {
                //拒绝
                LatentDangerExecuteTypeEnum executeTypeEnum = LatentDangerExecuteTypeEnum.公司负责人审核拒绝;
                updateFlowRecord(currentRecord, executeTypeEnum, userId, departmentId, remark, null);
                JSONObject flowJson = remoteWorkFlowService.allTasksInProcessInstanceId(latentDanger.getInstanceId());
                if (flowJson == null) {
                    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
                    return executeSubmitDto;
                }
                LatentDangerPatrolBo patrolBo = null;
                String userIds;
                if (latentDanger.getDangerType().equals(LatentDangerTypeEnum.计划检查.getCode())) {
                    patrolBo = latentDangerPatrolMapper.getByDangerId(latentDanger.getId());
                    userIds = Joiner.on(",").join(getUserIdsStrByPerTypeAndDefKey(flowJson));
                } else {
                    LatentDangerFlowRecordBo recordBo = latentDangerFlowRecordMapper.getByDangerIdAndActionFlag(latentDanger.getId(), "B_3");
                    userIds = recordBo.getFlowTaskUserIds();
                }
                LatentDangerFlowRecordBo record = saveFlowRecord(flowJson.getString("id"), userIds,
                        flowJson.getString("name"), flowJson.getString("taskDefinitionKey"), latentDanger.getId());
                latentDanger.setCurrentFlowRecordId(record.getId());
                latentDanger.setDangerState(executeTypeEnum.getNextState().getCode().toString());
                latentDangerMapper.updateById(latentDanger);
                ///web推送刷新消息
//                dangerStateChangeWebSocket(latentDangerBo);
//                Set<String> nextExecuteUserIds = Sets.newHashSet(Arrays.asList(userIds.split(",")));
                sendMessage(latentDanger, executeTypeEnum, patrolBo, currentRecord.getFlowTaskName(), this.getNextExecuteUsers(latentDanger.getInstanceId()), userRealName, departmentName);
            }
        }
        return executeSubmitDto;
    }

    @Override
    public void updateDangerStateOfOvertime() {
        logger.info("修改治理过期隐患的逾期状态");
        String dangerState = "2,3,4";
        if (LatentDangerBizTypeEnum.巡检.getCode().equals(bizType)) {
            dangerState = "2,3,4";
        } else if (LatentDangerBizTypeEnum.防火监督.getCode().equals(bizType)) {
            dangerState = "taskDispatch,governFileSubmit,governLeaderConfirm,governChargerConfirm," +
                    "governLeadershipConfirm,governLeaderReviewConfirm,governSecondReviewConfirm";
        }
        List<String> dangerStateList = Lists.newArrayList(dangerState.split(","));
        List<LatentDangerBo> overtimeList = latentDangerMapper.listOfOvertime(dangerStateList);
        LambdaQueryWrapper<LatentDanger> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper
        List<LatentDanger> overtimeDangerList = this.baseMapper.selectList(queryWrapper);
        for (LatentDangerBo latentDangerBo : overtimeList) {
            latentDangerBo.setOvertimeState(LatentDangerOvertimeStateEnum.已逾期.getCode());
            latentDangerMapper.update(latentDangerBo);

            if (LatentDangerBizTypeEnum.巡检.getCode().equals(bizType) &&
                    latentDangerBo.getDangerType().equals(LatentDangerTypeEnum.计划检查.getCode())) {
                // TODO 远程调用修改
                LatentDangerPatrolBo patrolBo = latentDangerPatrolMapper.getByDangerId(latentDangerBo.getId());
                LatentDangerResultPushSpcRequest spcRequest = new LatentDangerResultPushSpcRequest();
                spcRequest.setProcessingTime(DateUtil.date2Str(new Date(), DateUtil.DATETIME_DEFAULT_FORMAT));
                spcRequest.setHiddenTroubleName(latentDangerBo.getDangerName());
                spcRequest.setRiskSourceId(patrolBo.getPointOriginalId());
                spcRequest.setHiddenTroubleStatus("治理逾期");
                spcRequest.setTroubleList(getTroubleList(patrolBo.getPointId()));
                remoteSpcService.pushLatentDangerExecuteResult(spcRequest);
            }
        }
        // TODO 推送页面刷新
//        remoteWebSocketServer.wsDataRefresh("dangerOverdue");

        // 即将逾期的隐患发送消息提醒用户
        List<LatentDangerNoticeBo> needNoticeDangerList = latentDangerMapper.listNeedNoticeDanger(dangerState);
        if (!CollectionUtils.isEmpty(needNoticeDangerList)) {
            logger.info("隐患治理即将逾期通知》》》》");
            needNoticeDangerList.forEach(danger -> {
                asyncTask.pushLatentDangerReformLimitDateExpireMessage(this.getNextExecuteUsers(danger.getInstanceId()),
                        danger.getOrgCode(),
                        danger.getDangerName(), DateUtil.date2Str(danger.getReformLimitDate(), DateUtil.DATETIME_DEFAULT_FORMAT),
                        danger.getDangerId(),
                        danger.getDangerState(), "");
            });
        }
    }

    /**
     * web安全态势预控 （ 隐患按车间/部门统计） 模块推送刷新消息
     */
    private void dangerStateChangeWebSocket(LatentDangerBo latentDangerBo) {
        String state = latentDangerBo.getDangerState();
        String type = latentDangerBo.getDangerType();
        if (LatentDangerTypeEnum.计划检查.getCode().equals(type)
                || LatentDangerTypeEnum.无计划检查.getCode().equals(type)) {
            if (LatentDangerStateEnum.待治理.getCode().equals(state)
//                    || LatentDangerStateEnum.安措计划中.getCode().equals(state)
                    || LatentDangerStateEnum.待验证.getCode().equals(state)) {
                remoteWebSocketServer.wsDataRefresh("dangerExecute");
            }
        }
    }

    @Override
    public LatentDangerDetailVo listFlowRecord(String token, String product, String appKey, Long id) throws Exception {
        LatentDangerBo latentDangerBo = latentDangerMapper.getById(id);
        if (latentDangerBo == null) {
            throw new Exception("隐患不存在");
        }
        LatentDangerDetailVo detailVo = new LatentDangerDetailVo();

        detailVo.setDangerName(latentDangerBo.getDangerName());
        detailVo.setDangerLevel(latentDangerBo.getDangerLevel());
        detailVo.setDangerPosition(latentDangerBo.getStructureName());
        LatentDangerLevelEnum levelEnum = LatentDangerLevelEnum.getEnumByCode(latentDangerBo.getDangerLevel());
        if (levelEnum != null) {
            detailVo.setDangerLevelName(levelEnum.getName());
        }
        List<LatentDangerFlowRecordBo> records = latentDangerFlowRecordMapper.listByDangerId(latentDangerBo.getId());
        if (!CollectionUtils.isEmpty(records)) {
            Set<String> userIds = Sets.newHashSet();
            Set<String> deptIds = Sets.newHashSet();
            records.forEach(e -> {
                if (!StringUtils.isEmpty(e.getExecuteUserId())) {
                    userIds.add(e.getExecuteUserId());
                }
                if (!StringUtils.isEmpty(e.getExcuteDepartmentId())) {
                    deptIds.add(e.getExcuteDepartmentId());
                }
            });
            List<DepartmentModel> departmentBos = remoteSecurityService.getlistDepartmentByDeptIds(token, product, appKey, Joiner.on(",").join(deptIds));
            List<AgencyUserModel> userModels = remoteSecurityService.listUserByUserIds(token, product, appKey, Joiner.on(",").join(userIds));
            Map<String, AgencyUserModel> userMap = Maps.uniqueIndex(userModels, AgencyUserModel::getUserId);
            Map<Long, DepartmentModel> departmentBoMap = Maps.uniqueIndex(departmentBos, DepartmentModel::getSequenceNbr);
            for (LatentDangerFlowRecordBo recordBo : records) {
                AgencyUserModel user = userMap.get(recordBo.getExecuteUserId());
                if (user != null) {
                    recordBo.setExecuteUserName(user.getRealName());
                }
                DepartmentModel departmentBo = departmentBoMap.get(recordBo.getExcuteDepartmentId());
                if (departmentBo != null) {
                    recordBo.setExecuteDepartmentName(departmentBo.getDepartmentName());
                }
                recordBo.setExecuteTime(DateUtil.date2Str(recordBo.getCreateDate(), DateUtil.DATETIME_DEFAULT_FORMAT));
            }
            detailVo.setRecords(records);
        }
        return detailVo;
    }

    /**
     * 工作流执行节点操作
     *
     * @param param
     * @param latentDanger
     * @param userId
     * @param userRealName
     * @param departmentId
     * @param departmentName
     * @param executeSubmitDto
     * @return
     */
    public DangerExecuteSubmitDto executeSubmit(LatentDangerExecuteParam param,
                                                LatentDanger latentDanger,
                                                String userId,
                                                String userRealName,
                                                String departmentId,
                                                String departmentName,
                                                DangerExecuteSubmitDto executeSubmitDto,
                                                ReginParams reginParams) throws Exception {
        // 根据业务类型不同执行不同逻辑
        if (LatentDangerBizTypeEnum.防火监督.getCode().equals(bizType)) {
            // 防火监督业务
            executeSupervisionBiz(param, latentDanger, userId, userRealName, departmentId, departmentName,
                    executeSubmitDto, reginParams);
        } else if (LatentDangerBizTypeEnum.巡检.getCode().equals(bizType)) {
            // 巡检业务
            executePatrolBiz(param, latentDanger, userId, userRealName, departmentId, departmentName,
                    executeSubmitDto, reginParams);
        }

        return executeSubmitDto;
    }

    @Transactional(rollbackFor = Exception.class)
    DangerExecuteSubmitDto executeSupervisionBiz(LatentDangerExecuteParam param, LatentDanger latentDanger,
                                                 String userId, String userRealName, String departmentId,
                                                 String departmentName,
                                                 DangerExecuteSubmitDto executeSubmitDto,
                                                 ReginParams reginParams) throws Exception {
        // 隐患的巡查信息
        JSONObject bizInfo = latentDanger.getBizInfo();
        if (ValidationUtil.isEmpty(bizInfo) || ValidationUtil.isEmpty(bizInfo.get("planType")) || ValidationUtil.isEmpty(bizInfo.get("accompanyingUserId"))) {
            executeSubmitDto.setIsOk(false);
            executeSubmitDto.setMsg("业务信息错误");
            return executeSubmitDto;
        }
        String planType = bizInfo.get("planType").toString();
        AgencyUserModel userModel = jcsFeignClient.getAmosIdByUserId((String) bizInfo.get("accompanyingUserId")).getResult();
        if (ValidationUtil.isEmpty(userModel)) {
            executeSubmitDto.setIsOk(false);
            executeSubmitDto.setMsg("业务信息错误");
            return executeSubmitDto;
        }
        // 工作流中使用平台用户名称，因此这里取userName
        String checkLeaderId = userModel.getUserName();

        String processInstanceId = latentDanger.getInstanceId();
        String currentDangerState = latentDanger.getDangerState();
        LatentDangerState.SupervisionDangerStateEnum currentStateEnum =
                LatentDangerState.SupervisionDangerStateEnum.getEnumByCode(currentDangerState);
        String executeResultMsg = "";
        String condition;

        // 日志信息
        LatentDangerFlowRecord record;

        // 第一次处于待现场确认时，启动工作流
        if (ValidationUtil.isEmpty(processInstanceId)) {
            // 1、校验是否有启动后执行现场确认的权限
            // 获取当前登录用户的所有角色
            Set<String> roleNameSet = Sets.newHashSet();
            if (!ValidationUtil.isEmpty(reginParams.getUserModel().getOrgRoles())) {
                reginParams.getUserModel().getOrgRoles().values().forEach(i -> {
                    i.forEach(e -> {
                        roleNameSet.add(e.getRoleName());
                    });
                });
            }
            if (!roleNameSet.contains(onSiteConfirmRole)) {
                executeSubmitDto.setIsOk(false);
                executeSubmitDto.setMsg("没有执行权限");
                return executeSubmitDto;
            }
            // 2、开启工作流
            JSONObject body = new JSONObject();
            body.put("businessKey", latentDanger.getBusinessKey());
            body.put("processDefinitionKey", workflowProcessDefinitionKey);
            JSONObject result = workflowFeignService.startByVariable(body);
            if (result == null || ValidationUtil.isEmpty(result.get("data"))) {
                executeSubmitDto.setIsOk(false);
                executeSubmitDto.setMsg("启动工作流失败");
                return executeSubmitDto;
            }
            Map resultData = (Map) result.get("data");
            latentDanger.setInstanceId((String) resultData.get("id"));
            latentDanger.setUpdateDate(new Date());
            latentDanger.setDangerState(LatentDangerState.SupervisionDangerStateEnum.现场确认.getCode());
            latentDanger.setDangerStateName(LatentDangerState.SupervisionDangerStateEnum.现场确认.getName());

            // 3、执行一步现场确认
            boolean executeResult = workflowExecuteService.excuteTask(latentDanger.getInstanceId(), planType);
            if (!executeResult) {
                this.updateById(latentDanger);
                executeSubmitDto.setIsOk(false);
                executeSubmitDto.setMsg("任务执行失败");
                return executeSubmitDto;
            }

            // 4、在执行完节点后需要将检查组长id设置为下个节点执行人
            Object resultObj = workflowExecuteService.setTaskAssign(latentDanger.getInstanceId(), checkLeaderId);
            executeSubmitDto.setCheckLeaderId(userModel.getUserId());

            if (!(Boolean) resultObj) {
                executeSubmitDto.setIsOk(false);
                executeSubmitDto.setMsg("设置节点执行人失败");
                return executeSubmitDto;
            }

            // 5、保存日志信息
            executeResultMsg = latentDanger.getDangerStateName() + ExecuteTypeEnum.通过.getName();
            record = saveFlowRecord("", latentDanger.getDangerStateName(), userId, departmentId, latentDanger.getFlowJson(),
                    latentDanger.getId(), reginParams.getRole(), executeResultMsg, "", userRealName, departmentName,
                    latentDanger.getDangerState(), 0);
            LatentDangerState.SupervisionDangerStateEnum curEnum =
                    LatentDangerState.SupervisionDangerStateEnum.getEnumByCode(latentDanger.getDangerState());
            LatentDangerState.SupervisionDangerStateEnum nextEnum =
                    LatentDangerState.SupervisionDangerStateEnum.getEnumByCode(curEnum.getNext());
            latentDanger.setDangerState(nextEnum.getCode());
            latentDanger.setDangerStateName(nextEnum.getName());
            latentDanger.setCurrentFlowRecordId(record.getId());
            this.updateById(latentDanger);

            executeSubmitDto.setIsOk(true);
            executeSubmitDto.setMsg(executeResultMsg);
            return executeSubmitDto;
        }

        // 查询上一步流程信息，如果为拒绝，则又回到了现场确认，此时需要重新设置condition为计划类型
        List<LatentDangerFlowRecord> recordList =
                latentDangerFlowRecordService.list(new LambdaQueryWrapper<LatentDangerFlowRecord>().eq(LatentDangerFlowRecord::getDangerId, latentDanger.getId()).orderByDesc(LatentDangerFlowRecord::getCreateDate));
        LatentDangerFlowRecord preRecord = recordList.get(0);
        if (LatentDangerState.SupervisionDangerStateEnum.现场确认.getCode().equals(latentDanger.getDangerState()) &&
                !ValidationUtil.isEmpty(latentDanger.getInstanceId()) && ExecuteTypeEnum.驳回.getCode().equals(preRecord.getExecuteState())) {
            condition = planType;
        } else {
            ExecuteTypeEnum executeTypeEnum = ExecuteTypeEnum.getByCode(param.getExecuteType());
            condition = executeTypeEnum.getCondition();
        }

        // 执行任务(带权限校验)
        boolean executeResult = workflowExecuteService.CompleteTask(processInstanceId, condition, reginParams);
        if (!executeResult) {
            executeSubmitDto.setIsOk(false);
            executeSubmitDto.setMsg("任务执行失败");
            return executeSubmitDto;
        }

        String nextState = "";
        String nextStateName = "";
        if (ExecuteTypeEnum.通过.getCode().equals(param.getExecuteType())) {
            // 执行成功更新隐患状态
            LatentDangerState.SupervisionDangerStateEnum nextStateEnum =
                    LatentDangerState.SupervisionDangerStateEnum.getEnumByCode(currentStateEnum.getNext());
            // 单位检查提交整改资料的下一节点需特殊处理
            if ("supervised".equals(planType)) {
                if (LatentDangerState.SupervisionDangerStateEnum.提交整改资料.getCode().equals(currentDangerState)) {
                    nextStateEnum = LatentDangerState.SupervisionDangerStateEnum.整改检查组长确认;
                }
                if (LatentDangerState.SupervisionDangerStateEnum.整改检查组长确认.getCode().equals(currentDangerState)) {
                    nextStateEnum = LatentDangerState.SupervisionDangerStateEnum.整改检查负责人确认;
                }
                if (LatentDangerState.SupervisionDangerStateEnum.整改检查负责人确认.getCode().equals(currentDangerState)) {
                    nextStateEnum = LatentDangerState.SupervisionDangerStateEnum.整改检查分管领导确认;
                }
            }
            nextState = nextStateEnum.getCode();
            nextStateName = nextStateEnum.getName();

            if (("supervised".equals(planType) &&
                    LatentDangerState.SupervisionDangerStateEnum.整改检查分管领导确认.getCode().equals(currentDangerState))
                    || LatentDangerState.SupervisionDangerStateEnum.整改二次审核确认.getCode().equals(currentDangerState)) {
                nextState = LatentDangerState.SupervisionDangerStateEnum.整改完毕.getCode();
                nextStateName = LatentDangerState.SupervisionDangerStateEnum.整改完毕.getName();
            }
            executeResultMsg = currentStateEnum.getName() + ExecuteTypeEnum.通过.getName();
        } else {
            LatentDangerState.SupervisionDangerStateEnum nextStateEnum =
                    LatentDangerState.SupervisionDangerStateEnum.getEnumByCode(currentStateEnum.getRejectNext());
            nextState = nextStateEnum.getCode();
            nextStateName = nextStateEnum.getName();
            executeResultMsg = currentStateEnum.getName() + ExecuteTypeEnum.驳回.getName();
        }
        latentDanger.setDangerState(nextState);
        latentDanger.setDangerStateName(nextStateName);

        // 当隐患状态当前节点是整改任务分配时，在执行完节点后需要将整改分配责任人设置为下个节点执行人
        if (LatentDangerState.SupervisionDangerStateEnum.整改任务分配.getCode().equals(currentStateEnum.getCode())) {
            if (ValidationUtil.isEmpty(param.getReformLeaderId())) {
                executeSubmitDto.setIsOk(false);
                executeResultMsg = "整改责任人不能为空";
                executeSubmitDto.setMsg(executeResultMsg);
                return executeSubmitDto;
            }
            AgencyUserModel checkLeader = jcsFeignClient.getAmosIdByUserId(param.getReformLeaderId()).getResult();
            Object result = workflowExecuteService.setTaskAssign(processInstanceId, checkLeader.getUserName());
            if (!(Boolean) result) {
                executeSubmitDto.setIsOk(false);
                executeResultMsg = "设置节点执行人失败";
                executeSubmitDto.setMsg(executeResultMsg);
                return executeSubmitDto;
            }
        }

        // 当为提交资料节点时，保存提交的资料
        if (LatentDangerState.SupervisionDangerStateEnum.提交整改资料.getCode().equals(currentStateEnum.getCode())) {
            latentDanger.setFlowJson(param.getReformJson());
        }

        // 当计划为单位检查且隐患状态当前节点是提交整改资料时，在执行完节点后需要将整改资料审核人id（检查组长）设置为下个节点执行人
        if ("supervised".equals(planType) && LatentDangerState.SupervisionDangerStateEnum.提交整改资料.getCode().equals(currentStateEnum.getCode())) {
            Object result = workflowExecuteService.setTaskAssign(processInstanceId, checkLeaderId);
            if (!(Boolean) result) {
                executeSubmitDto.setIsOk(false);
                executeResultMsg = "设置节点执行人失败";
            }
        }
        // 当计划为公司专项或日常检查且隐患状态当前节点是整改分管领导审核（二级审核）时，
        // 在执行完节点后需要将整改三级审核人id（检查组长）设置为下个节点执行人
        if (!"supervised".equals(planType) && LatentDangerState.SupervisionDangerStateEnum.整改检查分管领导确认.getCode().equals(currentStateEnum.getCode())) {
            Object result = workflowExecuteService.setTaskAssign(processInstanceId, checkLeaderId);
            if (!(Boolean) result) {
                executeSubmitDto.setIsOk(false);
                executeResultMsg = "设置节点执行人失败";
            }
        }

        record = saveFlowRecord("", currentStateEnum.getName(), userId, departmentId, latentDanger.getFlowJson(),
                latentDanger.getId(), reginParams.getRole(), executeResultMsg, "", userRealName, departmentName,
                currentStateEnum.getCode(), param.getExecuteType());
        latentDanger.setCurrentFlowRecordId(record.getId());
        this.updateById(latentDanger);

        executeSubmitDto.setIsOk(true);
        executeSubmitDto.setMsg(executeResultMsg);

        return executeSubmitDto;
    }

    private DangerExecuteSubmitDto executePatrolBiz(LatentDangerExecuteParam param, LatentDanger latentDanger,
                                                    String userId, String userRealName, String departmentId,
                                                    String departmentName, DangerExecuteSubmitDto executeSubmitDto,
                                                    ReginParams reginParams) {
        if (!ValidationUtil.isEmpty(param.getReformLimitDate())) {
            param.setReformLimitDate(param.getReformLimitDate() + " 23:59:59");
        }
        LatentDangerExecuteTypeEnum executeTypeEnum = LatentDangerExecuteTypeEnum.getByCode(param.getExecuteType());
        if (executeTypeEnum == null) {
            executeSubmitDto.setIsOk(false);
            executeSubmitDto.setMsg("执行类型有误");
            return executeSubmitDto;
        }

        // 延期治理时，根据用户选择是否需要公司来构造参数调用工作流
        if (!ValidationUtil.isEmpty(param.getNeedCompanyVerify())
                && executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患延期治理车间部门审核通过)) {
            String requestBody = "";
            if (param.getNeedCompanyVerify() == 0) {// 延期治理申请 不需要公司审核
                requestBody = "{\"needCompanyApproval\": \"否\",\"approveResult\": \"通过\"}";
            } else {// 延期治理申请 需要公司审核
                requestBody = "{\"needCompanyApproval\": \"是\",\"approveResult\": \"通过\"}";
            }
            executeTypeEnum.setRequestBody(requestBody);
        }
        // 延期治理选择的延期日期不能早于整改日期校验
        if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患延期治理)) {
            if (latentDanger.getReformLimitDate().compareTo(DateUtil.longStr2Date(param.getDelayLimitDate())) >= 0) {
                executeSubmitDto.setIsOk(false);
                executeSubmitDto.setMsg("延期日期不能早于整改期限");
                return executeSubmitDto;
            }
        }

        JSONObject executeJson = remoteWorkFlowService.execute(param.getTaskId(), executeTypeEnum.getRequestBody());
        if (executeJson == null) {
            executeSubmitDto.setIsOk(false);
            executeSubmitDto.setMsg("执行失败");
            return executeSubmitDto;
        }
        LatentDangerPatrolBo patrolBo = null;
        if (latentDanger.getDangerType().equals(LatentDangerTypeEnum.计划检查.getCode())) {
            patrolBo = latentDangerPatrolMapper.getByDangerId(latentDanger.getId());
        }
        JSONObject data = executeJson.getJSONObject("data");
        if (executeTypeEnum.getNextState().equals(LatentDangerStateEnum.已撤销)) {
            latentDanger.setDangerState(executeTypeEnum.getNextState().getCode());
            saveFlowRecord(executeJson.getString("id"), data.getString("name"), userId, departmentId,
                    param.getFlowJson(), param.getDangerId(), reginParams.getRole(), executeTypeEnum.getName(),
                    param.getRemark(), userRealName, departmentName, latentDanger.getDangerState(), 0);
        } else if (executeTypeEnum.getNextState().equals(LatentDangerStateEnum.治理完毕)) {
            latentDanger.setDangerState(executeTypeEnum.getNextState().getCode());
            saveFlowRecord(executeJson.getString("id"), data.getString("name"), userId, departmentId,
                    param.getFlowJson(), param.getDangerId(), reginParams.getRole(), executeTypeEnum.getName(),
                    param.getRemark(), userRealName, departmentName, latentDanger.getDangerState(), 0);
        } else {
            LatentDangerFlowRecord flowRecord = saveFlowRecord(executeJson.getString("id"), data.getString("name"), userId, departmentId,
                    param.getFlowJson(), param.getDangerId(), reginParams.getRole(), executeTypeEnum.getName(),
                    param.getRemark(), userRealName, departmentName, latentDanger.getDangerState(), 0);
            latentDanger.setCurrentFlowRecordId(flowRecord.getId());
            latentDanger.setDangerState(executeTypeEnum.getNextState().getCode());
            if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患常规治理)) {
                latentDanger.setReformType(LatentDangerReformTypeEnum.常规整改.getCode());
                latentDanger.setReformJson(param.getFlowJson());
                latentDanger.setInferOtherThings(param.getInferOtherThings());
                latentDanger.setProblemDescription(param.getReasonAnalysis());
                latentDanger.setReasonAnalysis(param.getRemark());
            } else if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患延期治理)) {
                latentDanger.setReformType(LatentDangerReformTypeEnum.延期治理.getCode());
                latentDanger.setReformJson(param.getFlowJson());
                latentDanger.setInferOtherThings(param.getInferOtherThings());
                latentDanger.setProblemDescription(param.getReasonAnalysis());
                latentDanger.setReasonAnalysis(param.getRemark());
                latentDanger.setDelayLimitDate(DateUtil.str2Date(param.getDelayLimitDate(), DateUtil.DATETIME_DEFAULT_FORMAT));
            }
            if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患评审通过)) {
                latentDanger.setReformLimitDate(DateUtil.str2Date(param.getReformLimitDate(), DateUtil.DATETIME_DEFAULT_FORMAT));
                latentDanger.setDangerLevel(param.getDangerLevel());
            }
        }
        if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患延期治理车间部门审核通过)) {
            // 延期治理评审通过且 不需要 公司审核
            if (param.getNeedCompanyVerify() == 0) {
                latentDanger.setDangerState(LatentDangerStateEnum.延期治理申请.getCode());
                latentDanger.setReformLimitDate(latentDanger.getDelayLimitDate());
            } else {// 延期治理评审通过且 需要 公司审核
                latentDanger.setDangerState(LatentDangerStateEnum.延期治理申请待公司审核.getCode());
                LatentDangerFlowRecordBo recordBo =
                        latentDangerFlowRecordMapper.getByDangerIdAndCreate(latentDanger.getId());
                String flowJsonStr = recordBo.getFlowJson();
                JSONObject flowJson = JSONObject.parseObject(flowJsonStr);
                flowJson.put("needCompanyVerify", param.getNeedCompanyVerify());
                recordBo.setFlowJson(flowJson.toJSONString());
                latentDangerFlowRecordMapper.update(recordBo);
            }
        } else if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患延期治理车间部门审核拒绝)) {
            latentDanger.setDangerState(LatentDangerStateEnum.待治理.getCode());
        } else if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患延期治理公司审核通过)) {
            latentDanger.setDangerState(LatentDangerStateEnum.延期治理申请.getCode());
            latentDanger.setReformLimitDate(latentDanger.getDelayLimitDate());
        } else if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患延期治理公司审核拒绝)) {
            latentDanger.setDangerState(LatentDangerStateEnum.延期治理申请待车间部门审核.getCode());
        }
        latentDangerMapper.updateById(latentDanger);
        if (patrolBo != null) {
            executeSubmitDto.setPointOriginalId(patrolBo.getPointOriginalId());
            executeSubmitDto.setPointId(patrolBo.getPointId());
        }
        executeSubmitDto.setIsOk(true);
        executeSubmitDto.setExecuteTypeEnum(executeTypeEnum);
        executeSubmitDto.setDangerName(latentDanger.getDangerName());
        executeSubmitDto.setDangerId(latentDanger.getId());
        sendMessage(latentDanger, executeTypeEnum, patrolBo, executeTypeEnum.getName(), this.getNextExecuteUsers(latentDanger.getInstanceId()), userRealName, departmentName);
        return executeSubmitDto;
    }

    private void sendMessage(LatentDanger latentDanger, LatentDangerExecuteTypeEnum executeTypeEnum,
                             LatentDangerPatrolBo patrolBo, String flowTaskName, String informerList,
                             String userRealName, String departmentName) {
        if (LatentDangerBizTypeEnum.巡检.getCode().equals(latentDanger.getBizType())) {
            // 巡检流程消息处理
            sendPatrolDangerMessage(latentDanger, executeTypeEnum, patrolBo, flowTaskName, informerList, userRealName, departmentName);
        } else if (LatentDangerBizTypeEnum.防火监督.getCode().equals(latentDanger.getBizType())) {
            // TODO 防火监督消息处理
            sendSupervisionDangerMessage(latentDanger, executeTypeEnum, patrolBo, flowTaskName, informerList, userRealName, departmentName);
        }
    }

    // 巡检流程消息处理
    private void sendPatrolDangerMessage(LatentDanger latentDanger, LatentDangerExecuteTypeEnum executeTypeEnum, LatentDangerPatrolBo patrolBo, String flowTaskName, String informerList, String userRealName, String departmentName) {
        try {
            if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患评审拒绝)) {
                String pointName = null;
                if (patrolBo != null) {
                    pointName = patrolBo.getPointName();
                }
                Set<String> sendUserIds = Sets.newHashSet(latentDanger.getDiscovererUserId());
                asyncTask.pushLatentDangerExecuteMessage(informerList, latentDanger.getOrgCode(),
                        latentDanger.getDangerName(), pointName,
                        departmentName, latentDanger.getId(), userRealName,
                        flowTaskName, ExecuteStateEnum.驳回.getName(),
                        DateUtil.date2Str(new Date(), DateUtil.DATETIME_DEFAULT_FORMAT),
                        Integer.valueOf(latentDanger.getDangerState()));
            } else if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患验证通过)) {
                if (patrolBo != null) {
                    // 更新p_check_input表state字段
                    updateCheckInputDangerState(latentDanger.getBizId(), DangerHandleStateEnum.COMPLETED.getCode());
                    DangerResultBo dangerResultBo = new DangerResultBo();
                    try {
//                        business.processProtalDataFromDanger(dangerResultBo);
                    } catch (Exception e) {
                        throw new RuntimeException("隐患治理完成调用站端接口出错！");
                    }
                }
            } else {
                String pointName = null;
                if (patrolBo != null) {
                    pointName = patrolBo.getPointName();
                }
                asyncTask.pushLatentDangerExecuteMessage(informerList, latentDanger.getOrgCode(),
                        latentDanger.getDangerName(), pointName,
                        departmentName, latentDanger.getId(), userRealName,
                        flowTaskName, executeTypeEnum.getExecuteState().getName(),
                        DateUtil.date2Str(new Date(), DateUtil.DATETIME_DEFAULT_FORMAT),
                        Integer.valueOf(latentDanger.getDangerState()));
                if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患评审通过)) {
                    // 隐患治理到期时间为当天，则立即提示消息
                    Date reformLimitDate = latentDanger.getReformLimitDate();
                    if (DateUtil.getDateFormat(new Date()).equals(DateUtil.getDateFormat(reformLimitDate))) {
                        asyncTask.pushLatentDangerReformLimitDateExpireMessage(informerList,
                                latentDanger.getOrgCode(), latentDanger.getDangerName(),
                                DateUtil.date2Str(latentDanger.getReformLimitDate(), DateUtil.DATETIME_DEFAULT_FORMAT),
                                latentDanger.getId(),
                                Integer.valueOf(latentDanger.getDangerState()), userRealName);
                    }
                }
            }
        } catch (Exception e) {
            logger.error("隐患执行发送消息失败", e);
        }
    }

    // 防火监督流程消息处理
    private void sendSupervisionDangerMessage(LatentDanger latentDanger, LatentDangerExecuteTypeEnum executeTypeEnum,
                                              LatentDangerPatrolBo patrolBo, String flowTaskName, String informerList, String userRealName, String departmentName) {
    }

    @Async
    @Override
    public void sendLatentDangerExecuteResult(DangerExecuteSubmitDto executeSubmitDto) {
        LatentDangerExecuteTypeEnum executeTypeEnum = executeSubmitDto.getExecuteTypeEnum();
        String dangerName = executeSubmitDto.getDangerName();
        String pointOriginalId = executeSubmitDto.getPointOriginalId();
        Long pointId = executeSubmitDto.getPointId();
        String status = null;
        if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患评审通过)) {
            status = "隐患评审通过";
        } else if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患评审拒绝)) {
            status = "隐患评审不通过";
        } else if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患验证拒绝)) {
            status = "治理验证不通过";
        } else if (executeTypeEnum.equals(LatentDangerExecuteTypeEnum.隐患验证通过)) {
            status = "治理验证完成";
        }
        if (status != null) {
            LatentDangerResultPushSpcRequest spcRequest = new LatentDangerResultPushSpcRequest();
            spcRequest.setProcessingTime(DateUtil.date2Str(new Date(), DateUtil.DATETIME_DEFAULT_FORMAT));
            spcRequest.setHiddenTroubleName(dangerName);
            spcRequest.setRiskSourceId(pointOriginalId);
            spcRequest.setHiddenTroubleStatus(status);
            spcRequest.setTroubleList(getTroubleList(pointId));
            remoteSpcService.pushLatentDangerExecuteResult(spcRequest);
        }
    }

    // TODO 远程调用修改；巡检业务需要
    private List<String> getTroubleList(Long pointId) {
        List<String> troubleList = Lists.newArrayList();
        List<LatentDangerPatrolBo> patrolList = latentDangerPatrolMapper.listByPointId(pointId);
        if (!CollectionUtils.isEmpty(patrolList)) {
            List<Long> dangerIds = Lists.transform(patrolList, LatentDangerPatrolBo::getLatentDangerId);
            List<LatentDangerFlowRecordBo> flowRecordBos = latentDangerFlowRecordMapper.listNewestRecordByDangerIds(dangerIds);
            flowRecordBos.forEach(l -> {
                String status = null;
                if (l.getDangerState().equals(LatentDangerStateEnum.待治理.getCode())
                        && l.getDangerOvertimeState().equals(LatentDangerOvertimeStateEnum.已逾期.getCode())) {
                    status = "治理逾期";
                } else {
                    if (l.getExecuteResult().equals(LatentDangerExecuteTypeEnum.隐患评审通过.getName())) {
                        status = "隐患评审通过";
                    } else if (l.getExecuteResult().equals(LatentDangerExecuteTypeEnum.隐患评审拒绝.getName())) {
                        status = "隐患评审不通过";
                    } else if (l.getExecuteResult().equals(LatentDangerExecuteTypeEnum.隐患验证拒绝.getName())) {
                        status = "治理验证不通过";
                    } else if (l.getExecuteResult().equals(LatentDangerExecuteTypeEnum.隐患验证通过.getName())) {
                        status = "治理验证完成";
                    }
                }
                if (status != null) {
                    troubleList.add(status);
                }
            });
        }
        return troubleList;
    }

    private void updateRiskSourceDangerState(Boolean isSave, Long riskSourceId, LatentDangerLevelEnum
            levelEnum, Long pointId, Long dangerId) {
//        RiskSourceBo riskSourceBo = riskSourceMapper.getById(riskSourceId);
//        if (riskSourceBo != null) {
//            if (isSave) {
//                //添加隐患
//                riskSourceBo.setIsDanger(true);
//                if (riskSourceBo.getDangerLevel() == null) {
//                    riskSourceBo.setDangerLevel(levelEnum.getRiskSourceDangerLevelCode());
//                } else {
////                    if (riskSourceBo.getDangerLevel().equals(LatentDangerLevelEnum.一般隐患.getRiskSourceDangerLevelCode())
////                            && levelEnum.equals(LatentDangerLevelEnum.重大隐患)) {
////                        riskSourceBo.setDangerLevel(levelEnum.getRiskSourceDangerLevelCode());
////                    }
//                    if (Integer.parseInt(riskSourceBo.getDangerLevel()) < Integer.parseInt(levelEnum.getRiskSourceDangerLevelCode())) {
//                        riskSourceBo.setDangerLevel(levelEnum.getRiskSourceDangerLevelCode());
//                    }
//                }
//            } else {
//                //撤销、完成隐患
//                HashMap<String, Object> params = new HashMap<>();
//                params.put("pointId", pointId);
//                params.put("dangerId", dangerId);
//                List<LatentDangerBo> latentDangerBos = latentDangerMapper.listNotFinishByPointId(params);
//                if (CollectionUtils.isEmpty(latentDangerBos)) {
//                    riskSourceBo.setIsDanger(false);
//                } else {
//                    riskSourceBo.setIsDanger(true);
//                    String dangerLevel = checkHasSeriousDanger(latentDangerBos);
//                    riskSourceBo.setDangerLevel(dangerLevel);
//                }
//            }
//            riskSourceMapper.updateDangerState(riskSourceBo);
//        }
    }

    private String checkHasSeriousDanger(List<LatentDangerBo> latentDangerBos) {
        String dangerLevel;
        List<LatentDangerLevelEnum> levelEnums = Lists.newArrayList();
        Map<String, List<LatentDangerBo>> map =
                latentDangerBos.stream().collect(Collectors.groupingBy(LatentDangerBo::getDangerLevel));
        map.keySet().forEach(l -> levelEnums.add(LatentDangerLevelEnum.getEnumByCode(l)));
        int order = levelEnums.stream().mapToInt(LatentDangerLevelEnum::getOrder).max().getAsInt();
        dangerLevel = Objects.requireNonNull(LatentDangerLevelEnum.getEnumByOrder(order)).getRiskSourceDangerLevelCode();
        return dangerLevel;
    }

    @Override
    public void freshRiskJudgmentLangerCount(LatentDangerExecuteParam latentDangerExecuteParam) {
        // TODO 使用远程调用替换
//        Long currentFlowRecordId = latentDangerExecuteParam.getFlowRecordId();
//        LatentDangerFlowRecordBo currentRecord = latentDangerFlowRecordMapper.getById(currentFlowRecordId);
//        if (currentRecord == null) {
//            return;
//        }
//        LatentDangerBo latentDangerBo = latentDangerMapper.getById(currentRecord.getDangerId());
//        if (latentDangerBo == null) {
//            return;
//        }
//        LatentDangerPatrolBo patrolBo = latentDangerPatrolMapper.getByDangerId(latentDangerBo.getId());
//        if (patrolBo != null && !ValidationUtil.isEmpty(patrolBo.getPointOriginalId())) {
//            iRiskJudgmentTaskService.freshRiskJudgmentLangerCount(Long.parseLong(patrolBo.getPointOriginalId()));
//        }
    }

    @Override
    public List<DictionarieValueModel> getDangerLevel() {
        String dictCode = LatentDangerLevelEnum.dictCode;
        if (!ValidationUtil.isEmpty(bizType)) {
            dictCode = bizType + dictCode;
        }
        FeignClientResult<List<DictionarieValueModel>> result = Systemctl.dictionarieClient.dictValues(dictCode);
        return result.getResult();
    }

    @Override
    public List<Map<String, String>> getAllDangerLevel() {
        List<LatentDangerLevelEnum> levelEnums = Lists.newArrayList(LatentDangerLevelEnum.values());
        List<Map<String, String>> levelList = Lists.newArrayList();
        levelEnums.forEach(level -> {
            Map<String, String> l = Maps.newHashMap();
            l.put("code", level.getCode());
            l.put("name", level.getName());
            levelList.add(l);
        });
        return levelList;
    }

    @Override
    public List<Map<String, String>> getAllDangerGovernance() {
        List<LatentDangerReformTypeEnum> levelEnums = Lists.newArrayList(LatentDangerReformTypeEnum.values());
        List<Map<String, String>> levelList = Lists.newArrayList();
        levelEnums.forEach(level -> {
            Map<String, String> l = Maps.newHashMap();
            l.put("code", level.getCode());
            l.put("name", level.getName());
            levelList.add(l);
        });
        return levelList;
    }

    @Override
    public List<DictionarieValueModel> getDangerGovernance() {
        String dictCode = LatentDangerReformTypeEnum.dictCode;
        if (!ValidationUtil.isEmpty(bizType)) {
            dictCode = bizType + dictCode;
        }
        FeignClientResult<List<DictionarieValueModel>> result = Systemctl.dictionarieClient.dictValues(dictCode);

        return result.getResult();
    }

    @Override
    public List<Map<String, String>> getAllDangerState() {
        List<Map<String, String>> levelList = Lists.newArrayList();
        List<LatentDangerState.SupervisionDangerStateEnum> supervisionDangerStateList = Lists.newArrayList(LatentDangerState.SupervisionDangerStateEnum.values());
        List<LatentDangerState.PatrolDangerStateEnum> patrolDangerStateEnumList = Lists.newArrayList(LatentDangerState.PatrolDangerStateEnum.values());
        supervisionDangerStateList.forEach(level -> {
            Map<String, String> l = Maps.newHashMap();
            l.put("code", level.getCode());
            l.put("name", level.getName());
            levelList.add(l);
        });
        patrolDangerStateEnumList.forEach(level -> {
            Map<String, String> l = Maps.newHashMap();
            l.put("code", level.getCode());
            l.put("name", level.getName());
            levelList.add(l);
        });
        return levelList;
    }

//    @Override
//    public JSONObject getDangerLevelJsonObject(String dangerLevelStr, String token, String product, String appKey, String dictCode) {
//        JSONArray dangerLevelList = (JSONArray) this.getDangerLevel(token, product, appKey, dictCode);
//        JSONObject dangerLevel = new JSONObject();
//        List<Object> objs =
//                dangerLevelList.stream().filter(level -> ((JSONObject) level).get("dictDataKey").equals(dangerLevelStr)).collect(Collectors.toList());
//        if (!CollectionUtils.isEmpty(objs)) {
//            dangerLevel = (JSONObject) objs.get(0);
//        }
//        return dangerLevel;
//    }

    @Override
    public JSONObject getReviewInfo(Long dangerId) {
        List<HashMap<String, Object>> result = latentDangerMapper.getReViewInfo(dangerId);
        Set<String> userIdSet = Sets.newHashSet();
        result.forEach(r -> {
            userIdSet.add((String) r.get("executeUserId"));
            if (!ValidationUtil.isEmpty(r.get("handleUserIds"))) {
                List<String> handleUserIds = Arrays.asList(r.get("handleUserIds").toString().split(","));
                userIdSet.addAll(handleUserIds);
            }
        });
        userIdSet.removeAll(Collections.singleton(null));

        List<AgencyUserModel> userModels = remoteSecurityService.listUserByUserIds(Joiner.on(",").join(userIdSet));
        if (!ValidationUtil.isEmpty(userModels)) {
            Map<String, AgencyUserModel> userMap = Maps.uniqueIndex(userModels, AgencyUserModel::getUserId);
            result.forEach(r -> {
                r.put("executeUserName", !ValidationUtil.isEmpty(r.get("executeUserId")) ? userMap.get(r.get(
                        "executeUserId")).getRealName() : "");
                List<String> handleUserNames = Lists.newArrayList();
                if (!ValidationUtil.isEmpty(r.get("handleUserIds"))) {
                    List<String> handleUserIds = Arrays.asList(r.get("handleUserIds").toString().split(","));
                    handleUserIds.forEach(id -> handleUserNames.add(userMap.get(id).getRealName()));
                }
                r.put("handleUserName", Joiner.on(",").join(handleUserNames));
            });
        }
        JSONObject resultObjJson = new JSONObject();
        result.forEach(r -> {
            r.put("flowJson", JSON.parseObject((String) r.get("flowJson")));
            resultObjJson.put((String) r.get("actionFlag"), JSONObject.toJSON(r));
        });
        return resultObjJson;
    }

    public List<Object> getBuildTree() {
        ResponseModel<Object> response = equipFeign.getBuildingTree();
        if (200 == response.getStatus() && ObjectUtils.isNotEmpty(response.getResult())) {
            return JSONArray.parseArray(JSON.toJSONString(response.getResult()));
        }
        return null;
    }

    @Override
    public IPage<LatentDanger> pageListDanger(PageParam pageParam) throws Exception {
        List allTaskList;
        String idsStr = (String) pageParam.get("dangerIds");
        List<String> dangerIdList = Lists.newArrayList();
        if (!ValidationUtil.isEmpty(idsStr)) {
            // 查询指定隐患
            dangerIdList = Lists.newArrayList(idsStr.split(","));
        }
        if (OwerEnum.MY.getCode().equals(pageParam.get("my"))) {
            // 不指定隐患id-我的任务
            JSONObject allTaskResult = workflowFeignService.getCurrentUserAllTaskList(workflowProcessDefinitionKey);
            allTaskList = (List) allTaskResult.get("data");
            List<String> instanceIdList = Lists.newArrayList();
            List<LatentDanger> dangers;
            if (!ValidationUtil.isEmpty(allTaskList)) {
                allTaskList.forEach(m -> instanceIdList.add(((Map) m).get("processInstanceId").toString()));
                dangers =
                        this.baseMapper.selectList(new LambdaQueryWrapper<LatentDanger>().in(LatentDanger::getInstanceId, instanceIdList));
                List<String> finalDangerIdList = dangerIdList;
                dangers.forEach(d -> finalDangerIdList.add(d.getId().toString()));
            }

            // 没设置隐患状态，说明查询 '我的任务' 或 所有是 '提交隐患' 状态的任务
            if (ValidationUtil.isEmpty(pageParam.get("dangerState"))) {
                if (LatentDangerBizTypeEnum.防火监督.getCode().equals(bizType)) {
                    pageParam.put("dangerState", LatentDangerState.SupervisionDangerStateEnum.提交隐患.getCode());
                } else if (LatentDangerBizTypeEnum.巡检.getCode().equals(bizType)) {
                    pageParam.put("dangerState", LatentDangerState.PatrolDangerStateEnum.待评审.getCode());
                }
            }
        }
        // 获取隐患地点的子节点
        Object structureId = pageParam.get("structureId");
        List<Long> structureIdList;
        if (structureId != null && structureId.toString().trim().length() > 0) {
            ResponseModel<Object> response = equipFeign.getBuildingTree();
            List<Map<String, Object>> buildingTree = (List<Map<String, Object>>) response.getResult();
            Map<String, Object> node = getAllNodes(buildingTree).stream().filter(map -> structureId.equals(map.get("id"))).findFirst().orElse(null);
            if (node != null) {
                structureIdList = findBuildChildrenIds(node);
                pageParam.put("structureIdList", structureIdList);
            }
        }

        if (!ValidationUtil.isEmpty(pageParam.get("dangerState")) || pageParam.get("dangerState") == "") {
            if (ValidationUtil.isEmpty(pageParam.get("dangerState"))) {
                pageParam.put("dangerState", null);
            } else {
                List<String> state = Lists.newArrayList(((String) pageParam.get("dangerState")).split(","));
                pageParam.put("dangerState", state);
            }
        }
        if (!ValidationUtil.isEmpty(dangerIdList)) {
            pageParam.put("dangerIds", dangerIdList);
        }

        if (ValidationUtil.isEmpty(pageParam.get("order"))) {
            pageParam.put("order", "1");
        }

        Page page = new Page(pageParam.getParamPageCurrent(), pageParam.getParamPageSize());
        IPage<LatentDanger> iPage = this.baseMapper.selectPageByParam(page, (Map<String, Object>) pageParam);
        if (iPage.getCurrent() != pageParam.getParamPageCurrent()) {
            iPage.setRecords(Lists.newArrayList());
            iPage.setTotal(0);
            iPage.setCurrent(pageParam.getParamPageCurrent());
            return iPage;
        }
        Map<String, Object> buildingAbsolutePositionMap = new HashMap<>();
        if (!ValidationUtil.isEmpty(iPage.getRecords())) {
            try {
                buildingAbsolutePositionMap = equipFeign.getBuildingAbsolutePosition().getResult();
                if (ValidationUtil.isEmpty(buildingAbsolutePositionMap)) {
                    throw new YeeException("获取建筑树出错");
                }
            } catch (Exception e) {
            }
            Map<String, Object> finalBuildingAbsolutePositionMap = buildingAbsolutePositionMap;
            iPage.getRecords().forEach(danger -> {
                if (!ValidationUtil.isEmpty(danger.getStructureId()) && !ValidationUtil.isEmpty(finalBuildingAbsolutePositionMap.get(danger.getStructureId().toString()))) {
                    danger.setStructureName(finalBuildingAbsolutePositionMap.get(danger.getStructureId().toString()).toString());
                }
                LatentDangerBizTypeEnum bizTypeEnum = LatentDangerBizTypeEnum.getByCode(danger.getBizType());
                if (bizType.equals(danger.getBizType())) {
                    LatentDangerState.SupervisionDangerStateEnum dangerStateEnum = LatentDangerState.SupervisionDangerStateEnum.getEnumByCode(danger.getDangerState());
                    danger.setProcessState(dangerStateEnum.getProcessState());
                    LatentDangerProcessStateEnum processStateEnum = LatentDangerProcessStateEnum.getByCode(danger.getProcessState());
                    danger.setProcessStateName(processStateEnum.getName());
                }
                if (LatentDangerBizTypeEnum.巡检.getCode().equals(danger.getBizType())) {
                    // 巡检隐患等级
                    LatentDangerLevelEnum levelEnum = Arrays.stream(LatentDangerLevelEnum.values()).filter(l -> l.getCode().equals(danger.getDangerLevel())).findFirst().get();
                    danger.setDangerLevelName(levelEnum.getName());
                    // 巡检整改方式
                    if (!ValidationUtil.isEmpty(danger.getReformType())) {
                        LatentDangerReformTypeEnum reformTypeEnum = Arrays.stream(LatentDangerReformTypeEnum.values()).filter(l -> l.getCode().equals(danger.getReformType())).findFirst().get();
                        danger.setReformTypeName(reformTypeEnum.getName());
                    }
                    // 巡检隐患状态
                    LatentDangerState.PatrolDangerStateEnum patrolDangerStateEnum = Arrays.stream(LatentDangerState.PatrolDangerStateEnum.values()).filter(l -> l.getCode().equals(danger.getDangerState())).findFirst().get();
                    danger.setDangerStateName(patrolDangerStateEnum.getName());
                    // 巡检隐患来源
                    danger.setDangerTypeName(LatentDangerTypeEnum.getEnumName(danger.getDangerType()));
                }
                danger.setBizTypeName(bizTypeEnum.getName());
            });
        }

        return iPage;
    }

    private List<Map<String, Object>> getAllNodes(List<Map<String, Object>> buildingTree) {
        List<Map<String, Object>> res = new LinkedList<>();
        if (buildingTree != null && !buildingTree.isEmpty()) {
            res.addAll(buildingTree);
            buildingTree.forEach(building -> {
                List<Map<String, Object>> childrenTree = (List<Map<String, Object>>) building.get("children");
                res.addAll(getAllNodes(childrenTree));
            });
        }
        return res;
    }

    private List<Long> findBuildChildrenIds(Map<String, Object> building) {
        List<Map<String, Object>> buildingTree = getAllNodes(Collections.singletonList(building));
        return buildingTree.stream().map(build -> Long.valueOf(build.get("id").toString())).collect(Collectors.toList());
    }

    @Override
    public List<DangerListResponse> export(PageParam pageParam) {
        String idsStr = (String) pageParam.get("dangerIds");
        if (!ValidationUtil.isEmpty(idsStr)) {
            List<String> dangerIdList = Lists.newArrayList(idsStr.split(","));
            pageParam.put("dangerIds", dangerIdList);
        }
        List<DangerListResponse> dangerListResponseList = latentDangerMapper.dangerListByMap(pageParam);
        return dangerList(dangerListResponseList);
    }

    @Override
    public List<DangerTimeAxisVo> queryExecuteLog(Integer dateTime) {
        Map<String, Object> param = new HashMap<>();
        String beginTime = "";
        if (dateTime != null && dateTime == 7) {
            beginTime = com.yeejoin.amos.latentdanger.core.util.DateUtil.getIntervalDateStr(new Date(), -7, "yyyy-MM-dd");
        } else if (dateTime != null && dateTime == 30) {
            beginTime = com.yeejoin.amos.latentdanger.core.util.DateUtil.getIntervalDateStr(new Date(), -30, "yyyy-MM-dd");
        } else {
            beginTime = com.yeejoin.amos.latentdanger.core.util.DateUtil.getShortCurrentDate();
        }
        param.put("beginTime", beginTime + " 00:00:00");
        List<DangerTimeAxisVo> list = latentDangerFlowRecordMapper.listExecuteLog(param);
        String d;
        if (0 < list.size()) {
            for (DangerTimeAxisVo vo : list) {
                AgencyUserModel userModel = remoteSecurityService.getUserById(RequestContext.getToken(), getProduct(), RequestContext.getAppKey(), vo.getExecuteUserId().toString());
                vo.setUserName(userModel.getRealName());
                vo.setDangerState(LatentDangerStateEnum.getEnumName(vo.getDangerState()));
                vo.setXAxis(null == vo.getUpdateDate() ? DateUtil.getDateFormat(new Date(), DateUtil.DATETIME_DEFAULT_FORMAT) : DateUtil.getDateFormat(vo.getUpdateDate(), DateUtil.DATETIME_DEFAULT_FORMAT));
                vo.setRow1(vo.getUserName() + "-" + vo.getDangerState() + "-" + vo.getDangerName());
                if ("3".equals(vo.getReformType())) {
                    d = null == vo.getDelayLimitDate() ? "无" : DateUtil.getDateFormat(vo.getDelayLimitDate(), DateUtil.DATETIME_DEFAULT_FORMAT);
                } else {
                    d = null == vo.getReformLimitDate() ? "无" : DateUtil.getDateFormat(vo.getReformLimitDate(), DateUtil.DATETIME_DEFAULT_FORMAT);
                }
                vo.setRow2(vo.getStructureName() + "-" + d);
            }
        }
        return list;
    }

    private List<DangerListResponse> dangerList(List<DangerListResponse> dangerListResponseList) {
        JSONArray array = remoteSecurityService.listDictionaryByDictCode(RequestContext.getToken(), getProduct(), RequestContext.getAppKey(),
                DictTypeEnum.DANGERLEVEL.getCode());
        List<DictBo> dangerLevelList = JSONArray.parseArray(array.toJSONString(), DictBo.class);
        for (DangerListResponse e : dangerListResponseList) {
            e.setDangerState(LatentDangerStateEnum.getEnumName(e.getDangerState()));
            DictBo dangerLevel =
                    dangerLevelList.stream().filter(item -> item.getDictDataKey().equals(e.getDangerLevel())).collect(Collectors.toList()).get(0);
            e.setDangerLevel(dangerLevel.getDictDataValue());
            e.setReformType(!!ValidationUtil.isEmpty(e.getReformType()) ? "" :
                    LatentDangerReformTypeEnum.getEnumByCode(e.getReformType()).getName());
            e.setOvertimeState("0".equals(e.getOvertimeState()) ? "否" : "是");
            e.setDangerTypeName(LatentDangerTypeEnum.getEnumName(e.getDangerType()));
            e.setDeadline(null == e.getDeadlineDate() ? "" : DateUtil.getLongDate(e.getDeadlineDate()));
        }
        return dangerListResponseList;
    }

    // TODO 获取下一节点需要发消息的用户信息
    private String getNextExecuteUsers(String instanceId) {
        String informerList = "";
        JSONObject object = remoteWorkFlowService.getChildNodeDetail(instanceId);
        if (object != null) {
            JSONArray array = object.getJSONArray("data");
            if (array.size() > 0) {
                JSONObject workFlowDetail = array.getJSONObject(0);
                informerList = workFlowDetail.getString("informerList");
            }
        }
        return informerList;
    }

    @Override
    public List<LatentDanger> listAllDanger(LatentDangerListParam searchParam) {
        LambdaQueryWrapper<LatentDanger> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(LatentDanger::getBizType, bizType);
        lambdaQueryWrapper.eq(LatentDanger::getDeleted, false);
        lambdaQueryWrapper.eq(!ValidationUtil.isEmpty(searchParam.getDangerState()), LatentDanger::getDangerState,
                searchParam.getDangerState());
        lambdaQueryWrapper.like(!ValidationUtil.isEmpty(searchParam.getDangerName()), LatentDanger::getDangerName,
                searchParam.getDangerName());
        lambdaQueryWrapper.eq(!ValidationUtil.isEmpty(searchParam.getDangerLevel()), LatentDanger::getDangerLevel,
                searchParam.getDangerLevel());
        if (!ValidationUtil.isEmpty(searchParam.getDangerIds())) {
            lambdaQueryWrapper.in(LatentDanger::getId, Lists.newArrayList(searchParam.getDangerIds().split(",")));
        }
        if (!ValidationUtil.isEmpty(searchParam.getEndTime())) {
            // 防火监督报告查询需要根据t1(startTime),t2(endTime)时间来查询
            if (!ValidationUtil.isEmpty(searchParam.getStartTime())) {
                lambdaQueryWrapper.gt(LatentDanger::getCreateDate, searchParam.getStartTime());
            }
            lambdaQueryWrapper.le(LatentDanger::getCreateDate, searchParam.getEndTime());
        }
        lambdaQueryWrapper.and(o ->
            o.likeRight(LatentDanger::getOrgCode, searchParam.getOrgCode() + "*")
            .or().likeRight(LatentDanger::getOrgCode, searchParam.getOrgCode() + "-")
            .or().eq(LatentDanger::getOrgCode, searchParam.getOrgCode()));
        List<LatentDanger> latentDangerList = this.baseMapper.selectList(lambdaQueryWrapper);
        if (!ValidationUtil.isEmpty(latentDangerList)) {
            // 防火监督报告用该字段（复核执行人名称）
            latentDangerList.forEach(danger -> {
                List<LatentDangerFlowRecordBo> recordList = latentDangerFlowRecordMapper.listByDangerId(danger.getId());
                if (!ValidationUtil.isEmpty(recordList)) {
                    List<LatentDangerState.SupervisionDangerStateEnum> stateEnums =
                            LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.待复核.getCode());
                    Set<String> stateSet = Sets.newHashSet();
                    List<String> stateList = Lists.transform(stateEnums,
                            LatentDangerState.SupervisionDangerStateEnum::getCode);
                    stateSet.addAll(stateList);
                    List<LatentDangerFlowRecordBo> firstRecord =
                             recordList.stream().filter(r -> LatentDangerState.SupervisionDangerStateEnum.提交隐患.getCode().equals(r.getActionFlag())).collect(Collectors.toList());
                    danger.setCheckUserName(firstRecord.get(0).getExecuteUserName());
                    recordList =
                            recordList.stream().filter(r -> stateSet.contains(r.getDangerState())).collect(Collectors.toList());
                    Set<String> nameSet = Sets.newHashSet();
                    nameSet.addAll(Lists.transform(recordList, LatentDangerFlowRecordBo::getExecuteUserName));
                    danger.setExecuteUserName(Joiner.on(",").join(nameSet));
                }
            });
        }
        return latentDangerList;
    }

    @Override
    public Boolean delete(String ids) throws Exception {
        List<Long> dangerIdList =
                Arrays.stream(ids.split(",")).mapToLong(Long::parseLong).boxed().collect(Collectors.toList());
        LambdaQueryWrapper<LatentDanger> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(LatentDanger::getId, dangerIdList).isNull(LatentDanger::getInstanceId);
        List<LatentDanger> dangerList = this.baseMapper.selectList(queryWrapper);
        if (dangerIdList.size() != dangerList.size()) {
            throw new Exception("执行中隐患不能删除");
        }

        LambdaQueryWrapper<LatentDangerFlowRecord> recordQueryWrapper = new LambdaQueryWrapper<>();
        recordQueryWrapper.in(LatentDangerFlowRecord::getDangerId, dangerIdList);
        List<LatentDangerFlowRecord> recordList = latentDangerFlowRecordService.list(recordQueryWrapper);
        if (!ValidationUtil.isEmpty(recordList)) {
            recordList.forEach(r -> r.setDeleted(true));
        }
        latentDangerFlowRecordService.saveOrUpdateBatch(recordList);

        LambdaQueryWrapper<LatentDanger> dangerQueryWrapper = new LambdaQueryWrapper<>();
        dangerQueryWrapper.in(LatentDanger::getId, dangerIdList);
        List<LatentDanger> dangers = this.list(dangerQueryWrapper);
        if (!ValidationUtil.isEmpty(dangers)) {
            dangers.forEach(r -> r.setDeleted(true));
        }

        return this.saveOrUpdateBatch(dangers);
    }

    @Override
    public List<Map<String, String>> getDangerState() {
        if (LatentDangerBizTypeEnum.防火监督.getCode().equals(bizType)) {
            return LatentDangerState.SupervisionDangerStateEnum.getEnumList();
        } else {
            return LatentDangerState.PatrolDangerStateEnum.getEnumList();
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public ExecuteSubmitDto dangerAudit(LatentDangerDto latentDangerDto, Integer executeType, String userId, String userName,
                                        String deptId, String deptName, ReginParams reginParams) throws Exception {
        LatentDanger latentDanger = this.baseMapper.selectById(latentDangerDto.getId());
        if (ValidationUtil.isEmpty(latentDanger)) {
            throw new Exception("隐患不存");
        }
        latentDangerDto.setDangerPosition(null);
        Bean.copyExistPropertis(latentDangerDto, latentDanger);
        if (!ValidationUtil.isEmpty(latentDangerDto.getPhotoUrl())) {
            latentDanger.setPhotoUrls(Joiner.on(",").join(latentDangerDto.getPhotoUrl()));
        }
        this.updateById(latentDanger);
        DangerExecuteSubmitDto executeSubmitDto = new DangerExecuteSubmitDto();
        LatentDangerExecuteParam executeParam = new LatentDangerExecuteParam();
        if (ValidationUtil.isEmpty(executeType) ||
                (LatentDangerState.SupervisionDangerStateEnum.整改任务分配.getCode().equals(latentDangerDto.getDangerState())
                        && ValidationUtil.isEmpty(latentDangerDto.getReformLeaderId()))) {
            executeSubmitDto.setIsOk(false);
            executeSubmitDto.setMsg("执行参数有误");
            return executeSubmitDto;
        }
        if (LatentDangerState.SupervisionDangerStateEnum.提交整改资料.getCode().equals(latentDangerDto.getDangerState())) {
            executeParam.setReformJson(latentDangerDto.getReformJson());
        }
        executeParam.setExecuteType(executeType);
        executeParam.setReformLeaderId(latentDangerDto.getReformLeaderId());

        executeSubmit(executeParam, latentDanger, userId, userName, deptId, deptName, executeSubmitDto, reginParams);

        if (!executeSubmitDto.getIsOk()) {
            throw new Exception(executeSubmitDto.getMsg());
        }
        List<String> userIds = workflowExecuteService.getUserIdsByWorkflow(latentDanger.getInstanceId(), executeSubmitDto.getCheckLeaderId());
        ruleDangerService.addDangerSubmitRule(latentDanger, userIds, RuleTypeEnum.隐患审核.getCode(), ExecuteTypeEnum.getNameByCode(executeType));
        return executeSubmitDto;
    }

    @Override
    public IPage<LatentDanger> reviewListDanger(PageParam pageParam) throws Exception {
        String type = pageParam.get("type").toString();
        if ("audit".equals(type)) {
            List<LatentDangerState.SupervisionDangerStateEnum> stateEnums =
                    LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.待审核.getCode());
            List<String> dangerState = stateEnums.stream().map(stateEnum -> stateEnum != null ?
                    stateEnum.getCode() : null).collect(Collectors.toList());
            dangerState.add(LatentDangerState.SupervisionDangerStateEnum.提交隐患.getCode());
            // 审核状态
            pageParam.put("dangerState", Joiner.on(",").join(dangerState));
        } else if ("review".equals(type)) {
            List<LatentDangerState.SupervisionDangerStateEnum> stateEnums =
                    LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.待复核.getCode());
            List<String> dangerState = stateEnums.stream().map(stateEnum -> stateEnum != null ? stateEnum.getCode() : null).collect(Collectors.toList());
            // 复核状态
            pageParam.put("dangerState", Joiner.on(",").join(dangerState));
        }
        pageParam.put("bizType", bizType);
        return pageListDanger(pageParam);
    }

    @Override
    public Integer getUnFinishedDangerCount() {
        LambdaQueryWrapper<LatentDanger> queryWrapper = new LambdaQueryWrapper<>();
        // 巡检隐患未关闭状态集合
        List<LatentDangerState.PatrolDangerStateEnum> pDangerStateEnumList = Lists.newArrayList();
        pDangerStateEnumList.add(LatentDangerState.PatrolDangerStateEnum.治理完毕);
        pDangerStateEnumList.add(LatentDangerState.PatrolDangerStateEnum.待评审);
        pDangerStateEnumList.add(LatentDangerState.PatrolDangerStateEnum.已撤销);
        // 防火监督未关闭隐患状态集合
        List<LatentDangerState.SupervisionDangerStateEnum> sDangerStateEnumList = Lists.newArrayList();
        sDangerStateEnumList.addAll(LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.未审核.getCode()));
        sDangerStateEnumList.addAll(LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.待审核.getCode()));
        sDangerStateEnumList.addAll(LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.治理完毕.getCode()));

        return this.baseMapper.selectUnFinishedCount(pDangerStateEnumList.stream().map(LatentDangerState.PatrolDangerStateEnum::getCode).collect(Collectors.toList()), sDangerStateEnumList.stream().map(LatentDangerState.SupervisionDangerStateEnum::getCode).collect(Collectors.toList()));
    }

    @Override
    public Object getSupervisionReviewInfo(String orgCode, Date t1, Date t2) {
        LatentDangerListParam param = new LatentDangerListParam();
        param.setOrgCode(orgCode);
        param.setStartTime(t1);
        param.setEndTime(t2);

        List<LatentDanger> dangerList = listAllDanger(param);

        Map<String, List<LatentDanger>> map = Maps.newHashMap();
        List<LatentDangerState.SupervisionDangerStateEnum> reviewEnum1 =
                LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.待整改资料提交.getCode());
        List<LatentDangerState.SupervisionDangerStateEnum> reviewEnum2 =
                LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.待复核.getCode());
        Set<String> reviewStateNameSet = Sets.newHashSet();
        Set<String> finishStateNameSet = Sets.newHashSet();

        // 复查隐患指的是在本次在T1至 T2时间段内，提交隐患整改资料，并进入隐患整改审核流程 的隐患
        reviewStateNameSet.addAll(reviewEnum1.stream().map(supervisionDangerStateEnum ->
                supervisionDangerStateEnum != null ? supervisionDangerStateEnum.getCode() : null).collect(Collectors.toList()));
        reviewStateNameSet.addAll(reviewEnum2.stream().map(supervisionDangerStateEnum ->
                supervisionDangerStateEnum != null ? supervisionDangerStateEnum.getCode() : null).collect(Collectors.toList()));
        // 复查已整改隐患指的是在本次在T1至 T2时间段内，已经审核通过（全部审核流程通过）的隐患
        List<LatentDangerState.SupervisionDangerStateEnum> reviewEnum3 =
                LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.治理完毕.getCode());
        finishStateNameSet.addAll(reviewEnum3.stream().map(supervisionDangerStateEnum ->
                supervisionDangerStateEnum != null ? supervisionDangerStateEnum.getCode() : null).collect(Collectors.toList()));

        // 复查隐患
        map.put("reviewDangerList", dangerList.stream().filter(d -> reviewStateNameSet.contains(d.getDangerState())).collect(Collectors.toList()));
        // 复查已整改隐患
        map.put("reviewReformedList", dangerList.stream().filter(d -> finishStateNameSet.contains(d.getDangerState())).collect(Collectors.toList()));

        // 遗留隐患问题：指的是截止T2时间，尚未提交隐患整改资料的 隐患数量。
        param.setStartTime(null);
        List<LatentDanger> dangerList2 = listAllDanger(param);
        Set<String> remainingStateNameSet = Sets.newHashSet();
        List<LatentDangerState.SupervisionDangerStateEnum> reviewEnum4 =
                LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.未审核.getCode());
        List<LatentDangerState.SupervisionDangerStateEnum> reviewEnum5 =
                LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.待审核.getCode());
        List<LatentDangerState.SupervisionDangerStateEnum> reviewEnum6 =
                LatentDangerState.SupervisionDangerStateEnum.getEnumListByProcessState(LatentDangerProcessStateEnum.待整改.getCode());
        remainingStateNameSet.addAll(reviewEnum4.stream().map(supervisionDangerStateEnum ->
                supervisionDangerStateEnum != null ? supervisionDangerStateEnum.getCode() : null).collect(Collectors.toList()));
        remainingStateNameSet.addAll(reviewEnum5.stream().map(supervisionDangerStateEnum ->
                supervisionDangerStateEnum != null ? supervisionDangerStateEnum.getCode() : null).collect(Collectors.toList()));
        remainingStateNameSet.addAll(reviewEnum6.stream().map(supervisionDangerStateEnum ->
                supervisionDangerStateEnum != null ? supervisionDangerStateEnum.getCode() : null).collect(Collectors.toList()));
        map.put("remainingList", dangerList2.stream().filter(d -> remainingStateNameSet.contains(d.getDangerState())).collect(Collectors.toList()));

        return map;
    }
}
