package com.yeejoin.amos.boot.module.jg.biz.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.boot.biz.common.utils.RedisKey;
import com.yeejoin.amos.boot.biz.common.utils.RedisUtils;
import com.yeejoin.amos.boot.module.jg.api.dto.*;
import com.yeejoin.amos.boot.module.jg.api.entity.*;
import com.yeejoin.amos.boot.module.jg.api.enums.BusinessTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.WorkFlowStatusEnum;
import com.yeejoin.amos.boot.module.jg.api.mapper.*;
import com.yeejoin.amos.boot.module.jg.api.service.IJgChangeRegistrationNameService;
import com.yeejoin.amos.boot.module.jg.biz.feign.TzsServiceFeignClient;
import com.yeejoin.amos.boot.module.jg.biz.service.ICmWorkflowService;
import com.yeejoin.amos.boot.module.jg.flc.api.fegin.WorkFlowFeignService;
import com.yeejoin.amos.boot.module.ymt.api.common.StringUtil;
import com.yeejoin.amos.boot.module.ymt.api.entity.TzBaseEnterpriseInfo;
import com.yeejoin.amos.boot.module.ymt.api.enums.ApplicationFormTypeEnum;
import com.yeejoin.amos.boot.module.ymt.api.enums.FlowStatusEnum;
import com.yeejoin.amos.boot.module.ymt.api.mapper.TzBaseEnterpriseInfoMapper;
import com.yeejoin.amos.boot.module.ymt.flc.api.entity.RegUnitInfo;
import com.yeejoin.amos.boot.module.ymt.flc.api.feign.AccessFeignService;
import com.yeejoin.amos.boot.module.ymt.flc.api.mapper.RegUnitInfoMapper;
import com.yeejoin.amos.component.feign.config.InnerInvokException;
import com.yeejoin.amos.feign.privilege.Privilege;
import com.yeejoin.amos.feign.systemctl.model.TaskV2Model;
import com.yeejoin.amos.feign.workflow.model.ActWorkflowBatchDTO;
import com.yeejoin.amos.feign.workflow.model.ActWorkflowStartDTO;
import com.yeejoin.amos.feign.workflow.model.ProcessTaskDTO;
import com.yeejoin.amos.feign.workflow.model.TaskResultDTO;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.typroject.tyboot.core.foundation.context.RequestContext;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import org.typroject.tyboot.core.rdbms.service.BaseService;
import org.typroject.tyboot.core.restful.exception.instance.BadRequest;
import org.typroject.tyboot.core.restful.utils.ResponseModel;

import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 更名变更登记服务实现类
 *
 * @author system_generator
 * @date 2023-12-25
 */
@Service
public class JgChangeRegistrationNameServiceImpl extends BaseService<JgChangeRegistrationNameDto, JgChangeRegistrationName, JgChangeRegistrationNameMapper> implements IJgChangeRegistrationNameService {

    @Autowired
    private JgChangeRegistrationNameEqServiceImpl jgChangeRegistrationNameEqService;

    @Autowired
    RedisUtils redisUtils;

    @Autowired
    JgChangeRegistrationNameMapper jgChangeRegistrationNameMapper;

    @Autowired
    TzsServiceFeignClient tzsServiceFeignClient;

    @Autowired
    WorkFlowFeignService workFlowFeignService;

    @Autowired
    private JgChangeRegistrationReformEqMapper jgChangeRegistrationReformEqMapper;

    @Autowired
    private JgChangeRegistrationTransferEqMapper jgChangeRegistrationTransferEqMapper;

    @Autowired
    private JgUseRegistrationEqMapper jgUseRegistrationEqMapper;

    @Autowired
    private JgChangeRegistrationUnitEqMapper jgChangeRegistrationUnitEqMapper;

    @Autowired
    private JgChangeRegistrationNameEqMapper jgChangeRegistrationNameEqMapper;

    @Autowired
    private RegUnitInfoMapper regUnitInfoMapper;

    @Autowired
    private TzBaseEnterpriseInfoMapper tzBaseEnterpriseInfoMapper;

    @Autowired
    AccessFeignService accessFeignService;

    @Autowired
    CommonServiceImpl commonService;

    @Autowired
    ICmWorkflowService cmWorkflowService;

    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    TzBaseEnterpriseInfoMapper baseEnterpriseInfoMapper;

    private static String template = "来自企业（%s）的业务办理，【申请单号：%s】";

    public static String  JG_COMAPNY_TYPE = "监管机构";


    @Transactional(rollbackFor = Exception.class)
    public List<JgChangeRegistrationName> save2(String submitType, JSONObject requestParam) {
        Map<String, JSONObject> jgRegistrationInfoMap = (Map<String, JSONObject>) JSONObject.parseObject(JSONObject.toJSONString(requestParam), Map.class);
        return Collections.singletonList(this.save(submitType, jgRegistrationInfoMap));
    }


    public JgChangeRegistrationName save(String submitType, Map<String, JSONObject> jgRegistrationInfoMap) {
        ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        String[] taskName = new String[]{"流程结束"};
        JSONObject jgRegistrationInfo = jgRegistrationInfoMap.get("jgRegistrationInfo");
        JgChangeRegistrationNameDto model = JSON.parseObject(jgRegistrationInfo.toJSONString(), JgChangeRegistrationNameDto.class);
        // 获取告知单号
        ResponseModel<List<String>> listResponseModel = tzsServiceFeignClient.applicationFormCode(ApplicationFormTypeEnum.GMBG.getCode(), 1);
        if (!ObjectUtils.isEmpty(listResponseModel) && listResponseModel.getStatus() != HttpStatus.OK.value()) {
            log.error(" 获取告知单号失败");
            throw new RuntimeException();
        }
        List<String> applyNoList = listResponseModel.getResult();
        if (CollectionUtils.isEmpty(applyNoList)) {
            return null;
        }
        List<ProcessTaskDTO> processTasks = new ArrayList<>();
        // 判断当前是否为提交
        String instanceId = "";
        String nextTaskId = "";
        List<String> roleListNext = new ArrayList<>();
        List<String> roleListAll = new ArrayList<>();
        String applyNo = applyNoList.get(0);
        String nextUserIds = "";
        if ("1".equals(submitType)) {
            // 发起流程
            ActWorkflowBatchDTO actWorkflowBatchDTO = new ActWorkflowBatchDTO();
            List<ActWorkflowStartDTO> list = new ArrayList<>();
            ActWorkflowStartDTO dto = new ActWorkflowStartDTO();
            dto.setProcessDefinitionKey("unitRename");
            dto.setBusinessKey(applyNo);
            dto.setCompleteFirstTask(true);
            // 启动并执行下一步人单位传接收单位的code
            dto.setNextExecuteUserCompanyCode(this.getReceiveCompanyCode(model));
            list.add(dto);
            actWorkflowBatchDTO.setProcess(list);
            processTasks = cmWorkflowService.startBatch(actWorkflowBatchDTO);
            this.buildRoleList(processTasks, roleListNext, roleListAll);
            instanceId = processTasks.get(0).getProcessInstance().getId();
            nextTaskId = processTasks.get(0).getNextTask().get(0).getId();
            taskName[0] = processTasks.get(0).getNextTask().get(0).getName();
            List<WorkflowResultDto> workflowResultDtos = commonService.buildWorkFlowInfo(processTasks);
            nextUserIds = workflowResultDtos.get(0).getNextExecutorUserIds();
        }
        JgChangeRegistrationName dto = new JgChangeRegistrationName();
        // 字段转换
        convertField(model);
        BeanUtils.copyProperties(model, dto);
        dto.setApplyNo(applyNo);
        dto.setCreateDate(new Date());
        dto.setNextExecutorIds(String.join(",", roleListNext));
        dto.setInstanceStatus(String.join(",", roleListAll));
        dto.setPromoter(reginParams.getUserModel().getUserId());
        if (!StringUtils.isEmpty(instanceId)) {
            dto.setInstanceId(instanceId);
            dto.setNextTaskId(nextTaskId);
            dto.setNextExecuteUserIds(nextUserIds);
            dto.setAuditStatus(String.valueOf(WorkFlowStatusEnum.UNIT_RENAME_RECEIVE.getPass()));
        } else {
            dto.setAuditStatus(String.valueOf(WorkFlowStatusEnum.UNIT_RENAME_SUBMIT.getPass()));
        }
        dto.setUseUnitCreditCode(reginParams.getCompany().getCompanyCode());
        dto.setUseUnitName(reginParams.getCompany().getCompanyName());
        dto.setCreateUserId(RequestContext.getExeUserId());
        dto.setCreateUserName(reginParams.getUserModel().getRealName());
        this.save(dto);
        // 创建代办
        this.createTaskModel(dto, taskName[0], submitType, nextUserIds);
        if(StringUtil.isNotEmpty(dto.getInstanceId())){
            commonService.saveExecuteFlowData2Redis(dto.getInstanceId(), this.buildInstanceRuntimeData(dto));
        }
        return dto;
    }

    private String getReceiveCompanyCode(JgChangeRegistrationNameDto model) {
        String receiveOrgId = model.getReceiveOrgCode();
        if (!ObjectUtils.isEmpty(receiveOrgId)) {
            String[] receiveOrgIdList = receiveOrgId.split("_");
            if (receiveOrgIdList.length > 1) {
                return receiveOrgIdList[0];
            }
        }
        return null;
    }

    private void buildRoleList(List<ProcessTaskDTO> processTasks, List<String> roleListNext, List<String> roleListAll) {
        processTasks.forEach(p -> {
            p.getNextCandidateGroups().values().forEach(e -> {
                roleListNext.addAll(e);
                roleListAll.addAll(e);
            });
            roleListAll.addAll(p.getCandidateGroups());
        });
    }

    private void createTaskModel(JgChangeRegistrationName dto, String taskName, String submitType, String nextUserIds) {
        ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        // 提交创建待办逻辑
        if ("1".equals(submitType)) {
            //提交时先删除之前的暂存待办数据
            commonService.deleteTaskModel(dto.getSequenceNbr() + "");
            // 创建待办
            TaskModelDto taskModelDto = new TaskModelDto();
            taskModelDto.setFlowCreateDate(dto.getApplyDate());
            taskModelDto.setTaskName(taskName);
            taskModelDto.setTaskCode(dto.getApplyNo());
            taskModelDto.setTaskContent(this.buildTaskContent(dto));
            taskModelDto.setTaskDesc("");
            taskModelDto.setTaskType(BusinessTypeEnum.JG_NAME_CHANGE_REGISTRATION.getCode());
            taskModelDto.setTaskTypeLabel(BusinessTypeEnum.JG_NAME_CHANGE_REGISTRATION.getName());
            taskModelDto.setRelationId(dto.getInstanceId());
            taskModelDto.setExecuteUserIds(nextUserIds);
            FlowStatusEnum flowStatusEnum = this.getTaskStatus(submitType);
            taskModelDto.setTaskStatus(flowStatusEnum.getCode());
            taskModelDto.setTaskStatusLabel(flowStatusEnum.getName());
            taskModelDto.setFlowStatus(this.getTaskStatusByName(dto.getAuditStatus()));
            taskModelDto.setFlowStatusLabel(dto.getAuditStatus());
            taskModelDto.setStartUserId(dto.getCreateUserId());
            taskModelDto.setFlowCode(dto.getNextTaskId());
            taskModelDto.setStartUser(reginParams.getUserModel().getRealName());
            taskModelDto.setStartUserCompanyName(dto.getUseUnitName());
            taskModelDto.setNextExecuteUser(dto.getNextExecutorIds());
            taskModelDto.setStartDate(dto.getCreateDate());
            TaskMessageDto taskMessageDto = new TaskMessageDto();
            BeanUtil.copyProperties(dto, taskMessageDto);
            taskModelDto.setModel(taskMessageDto);
            commonService.buildTaskModel(Collections.singletonList(taskModelDto));
        }
        // 暂存创建待办逻辑
        if ("0".equals(submitType)) {
            // 暂存 创建待办逻辑
            TaskModelDto taskModelDto = new TaskModelDto();
            //行数据
            //附件太大赋空
            dto.setChangeCertificate(null);
            taskModelDto.setModel(dto);
            //摘要 按原有规则组装
            taskModelDto.setTaskContent(buildTaskContent(dto) + "待提交");
            //申请单号
            taskModelDto.setTaskCode(dto.getApplyNo());
            //业务类型枚举code值
            taskModelDto.setTaskType(BusinessTypeEnum.JG_NAME_CHANGE_REGISTRATION.getCode());
            //业务主键
            taskModelDto.setRelationId(dto.getSequenceNbr() + "");
            commonService.buildTaskModel(Collections.singletonList(taskModelDto));
        }
    }

    private Integer getTaskCodeByName(String auditStatus) {
        return commonService.getDictionaryCodeByName(auditStatus);
    }

    /**
     * 摘要构建
     *
     * @param dto 业务
     * @return 摘要
     */
    private String buildTaskContent(JgChangeRegistrationName dto) {
        return String.format(template, dto.getUseUnitCreditCode(), dto.getApplyNo());
    }


    @Transactional(rollbackFor = Exception.class)
    public JgChangeRegistrationNameDto updateInfo(String submitType, JgChangeRegistrationNameDto jgChangeRegistrationNameDto, String op) {
        if (Objects.isNull(jgChangeRegistrationNameDto) || StringUtils.isEmpty(submitType)) {
            throw new IllegalArgumentException("参数不能为空");
        }
        // 字段转换
        this.convertField(jgChangeRegistrationNameDto);
        List<String> roleListNext = new ArrayList<>();
        List<String> roleListAll = new ArrayList<>();
        JgChangeRegistrationName jgChangeRegistrationName = this.getById(jgChangeRegistrationNameDto.getSequenceNbr());
        BeanUtil.copyProperties(jgChangeRegistrationNameDto, jgChangeRegistrationName);
        if ("1".equals(submitType)) {
            //发起流程
            if (!StringUtils.hasText(jgChangeRegistrationName.getInstanceId())) {

                List<ProcessTaskDTO> processTasks = new ArrayList<>();
                ActWorkflowBatchDTO actWorkflowBatchDTO = new ActWorkflowBatchDTO();
                List<ActWorkflowStartDTO> list = new ArrayList<>();
                ActWorkflowStartDTO dto = new ActWorkflowStartDTO();
                dto.setProcessDefinitionKey("unitRename");
                dto.setBusinessKey(jgChangeRegistrationName.getApplyNo());
                dto.setCompleteFirstTask(true);
                // 启动并执行下一步人单位传接收单位的code
                dto.setNextExecuteUserCompanyCode(jgChangeRegistrationName.getReceiveCompanyCode());
                list.add(dto);
                actWorkflowBatchDTO.setProcess(list);
                processTasks = cmWorkflowService.startBatch(actWorkflowBatchDTO);
                String instanceId = processTasks.get(0).getProcessInstance().getId();
                String nextTaskId = processTasks.get(0).getNextTask().get(0).getId();
                String taskName = processTasks.get(0).getNextTask().get(0).getName();
                this.buildRoleList(processTasks, roleListNext, roleListAll);
                List<WorkflowResultDto> workflowResultDtos = commonService.buildWorkFlowInfo(processTasks);
                String nextUserIds = workflowResultDtos.get(0).getNextExecutorUserIds();
                jgChangeRegistrationName.setInstanceStatus(String.join(",", roleListAll));
                jgChangeRegistrationName.setInstanceId(instanceId);
                jgChangeRegistrationName.setNextExecutorIds(String.join(",", roleListNext));
                jgChangeRegistrationName.setNextTaskId(nextTaskId);
                jgChangeRegistrationName.setNextExecuteUserIds(nextUserIds);
                jgChangeRegistrationName.setAuditStatus(WorkFlowStatusEnum.UNIT_RENAME_RECEIVE.getPass());
                // 创建待办
                createTaskModel(jgChangeRegistrationName, taskName, "1", nextUserIds);
            } else {
                // 执行一步
                ProcessTaskDTO processTaskDTO = submit(op, jgChangeRegistrationName);
                String nextTaskId = processTaskDTO.getNextTask().get(0).getId();
                String taskName = processTaskDTO.getNextTask().get(0).getName();
                this.buildRoleList(Collections.singletonList(processTaskDTO), roleListNext, roleListAll);
                List<WorkflowResultDto> workflowResultDtos = commonService.buildWorkFlowInfo(Collections.singletonList(processTaskDTO));
                String nextUserIds = workflowResultDtos.get(0).getNextExecutorUserIds();
                // 查询下节点任务
                if (!ObjectUtils.isEmpty(jgChangeRegistrationName.getInstanceStatus())) {
                    jgChangeRegistrationName.setInstanceStatus(jgChangeRegistrationName.getInstanceStatus() + "," + String.join("", roleListNext));
                } else {
                    jgChangeRegistrationName.setInstanceStatus(String.join(",", roleListAll));
                }
                jgChangeRegistrationName.setPromoter(RequestContext.getExeUserId());
                jgChangeRegistrationName.setNextExecutorIds(String.join(",", roleListNext));
                jgChangeRegistrationName.setAuditStatus(WorkFlowStatusEnum.UNIT_RENAME_RECEIVE.getPass());
                jgChangeRegistrationName.setNextTaskId(nextTaskId);
                // 更新下一步可执行人
                jgChangeRegistrationName.setNextExecuteUserIds(nextUserIds);
                executeOneStep(jgChangeRegistrationName, taskName, nextUserIds, op);
            }
            this.updateById(jgChangeRegistrationName);
            commonService.saveExecuteFlowData2Redis(jgChangeRegistrationName.getInstanceId(), this.buildInstanceRuntimeData(jgChangeRegistrationName));
        } else {
            // 暂存逻辑
            createTaskModel(jgChangeRegistrationName, null, "0", null);
            this.updateById(jgChangeRegistrationName);
        }
        return jgChangeRegistrationNameDto;
    }

    private void executeOneStep(JgChangeRegistrationName jgChangeRegistrationName, String taskName, String nextUserIds, String operate) {
        // 先更新之前的待办
        TaskV2Model taskV2Model = updateTaskModel(jgChangeRegistrationName, operate);
        taskV2Model.setTaskDesc("");
        taskV2Model.setTaskContent(this.buildTaskContent(jgChangeRegistrationName));
        taskV2Model.setTaskName(taskName);
        taskV2Model.setTaskDesc("");
        taskV2Model.setTaskCode(jgChangeRegistrationName.getApplyNo());
        taskV2Model.setExecuteUserIds(nextUserIds);
        taskV2Model.setRelationId(jgChangeRegistrationName.getInstanceId());
        FlowStatusEnum flowStatusEnum = this.getTaskStatus(operate);
        taskV2Model.setTaskStatus(flowStatusEnum.getCode());
        taskV2Model.setTaskStatusLabel(flowStatusEnum.getName());
        taskV2Model.setFlowStatus(this.getTaskStatusByName(jgChangeRegistrationName.getAuditStatus()));
        taskV2Model.setFlowStatusLabel(jgChangeRegistrationName.getAuditStatus());
        taskV2Model.setTaskType(BusinessTypeEnum.JG_NAME_CHANGE_REGISTRATION.getCode());
        taskV2Model.setStartUser(jgChangeRegistrationName.getCreateUserName());
        taskV2Model.setTaskTypeLabel(BusinessTypeEnum.JG_NAME_CHANGE_REGISTRATION.getName());
        taskV2Model.setStartDate(jgChangeRegistrationName.getCreateDate());
        taskV2Model.setStartUserId(jgChangeRegistrationName.getCreateUserId());
        taskV2Model.setStartUserCompanyName(jgChangeRegistrationName.getUseUnitName());
        taskV2Model.setExecuteUserIds(nextUserIds);
        taskV2Model.setFlowCode(jgChangeRegistrationName.getNextTaskId());
        TaskModelDto modelDto = new TaskModelDto();
        BeanUtil.copyProperties(taskV2Model, modelDto);
        modelDto.setNextExecuteUser(jgChangeRegistrationName.getNextExecutorIds());
        TaskMessageDto taskMessageDto = new TaskMessageDto();
        BeanUtil.copyProperties(jgChangeRegistrationName, taskMessageDto);
        modelDto.setModel(taskMessageDto);
        modelDto.setPageType(this.getPageTypeForReject(operate, jgChangeRegistrationName.getAuditStatus()));
        // 再插入新代办、数据待定
        commonService.buildTaskModel(Collections.singletonList(modelDto));
    }

    private String getPageTypeForReject(String operate, String auditStatus) {
        // 驳回
        if ("1".equals(operate)) {
            // 且驳回到的节点为使用单位提交 则可编辑
            if (WorkFlowStatusEnum.UNIT_RENAME_SUBMIT.getPass().equals(auditStatus) ||
                    WorkFlowStatusEnum.UNIT_RENAME_SUBMIT.getReject().equals(auditStatus) ||
                    WorkFlowStatusEnum.UNIT_RENAME_SUBMIT.getRollBack().equals(auditStatus)
            ) {
                // urlInfo.json 文件的 pageType
                return "edit";
            }
            return "look";
        }
        return "look";
    }


    public ProcessTaskDTO submit(String operate, JgChangeRegistrationName jgChangeRegistrationName) {
        //组装信息
        TaskResultDTO dto = new TaskResultDTO();
        dto.setResultCode("approvalStatus");
        dto.setTaskId(jgChangeRegistrationName.getNextTaskId());
        dto.setComment("提交流程");
        dto.setNextExecuteUserCompanyCode(this.getNextUserOrgCode(operate, jgChangeRegistrationName));
        HashMap<String, Object> map = new HashMap<>();
        map.put("approvalStatus", operate);
        dto.setVariable(map);
        return cmWorkflowService.completeOrReject(jgChangeRegistrationName.getNextTaskId(), dto, operate);
    }

    private void convertField(JgChangeRegistrationNameDto model) {
        // 处理文件1
        if (!ValidationUtil.isEmpty(model.getChangeCertificateList())) {
            model.setChangeCertificate(JSON.toJSONString(model.getChangeCertificateList()));
        }
        String receiveOrgId = model.getReceiveOrgCode();
        if (!ObjectUtils.isEmpty(receiveOrgId)) {
            String[] receiveOrgIdList = receiveOrgId.split("_");
            if (receiveOrgIdList.length > 1) {
                model.setReceiveOrgCode(receiveOrgIdList[0]);
                model.setReceiveCompanyCode(receiveOrgIdList[0]);
                model.setReceiveOrgName(receiveOrgIdList[1]);
            }
        }
    }


    @Transactional(rollbackFor = Exception.class)
    public void deleteBatch(List<Long> ids) {
        // 删除待办
        this.deleteTaskBatch(ids);
        // 删除业务数据
        JgChangeRegistrationName jgChangeRegistrationName = new JgChangeRegistrationName();
        jgChangeRegistrationName.setIsDelete(true);
        LambdaQueryWrapper<JgChangeRegistrationName> lambda = new QueryWrapper<JgChangeRegistrationName>().lambda();
        lambda.in(JgChangeRegistrationName::getSequenceNbr, ids);
        this.update(jgChangeRegistrationName, lambda);
    }

    private void deleteTaskBatch(List<Long> ids) {
        ids.forEach(id-> commonService.deleteTaskModel(id + ""));
    }


    public void revocation(String instanceId, String taskId) {
        String lockKey = CommonServiceImpl.buildJgExecuteLockKey(instanceId);
        RLock lock = redissonClient.getLock(lockKey);
        try {
            boolean isLocked = lock.tryLock(0, 180, TimeUnit.SECONDS);
            // 解决并发问题：多个人同时操作一个流程（并发执行通过、驳回）
            if(!isLocked){
                throw new BadRequest("当前流程已经被执行！请重新打开页面查看并执行！");
            }
            commonService.checkForRevocationFlow(taskId, instanceId);
            // 执行流程
            String taskCode = FlowStatusEnum.TO_BE_FINISHED.getName();
            JgChangeRegistrationName jgChangeRegistrationName = new JgChangeRegistrationName();
            LambdaQueryWrapper<JgChangeRegistrationName> lambda = new QueryWrapper<JgChangeRegistrationName>().lambda();
            lambda.eq(JgChangeRegistrationName::getInstanceId, instanceId);
            jgChangeRegistrationName = this.getOne(lambda);
            List<String> roleListNext = new ArrayList<>();
            List<String> roleListAll = new ArrayList<>();
            ProcessTaskDTO processTaskDTO = cmWorkflowService.rollBack(instanceId);
            String nextTaskId = processTaskDTO.getNextTask().get(0).getId();
            this.buildRoleList(Collections.singletonList(processTaskDTO), roleListNext, roleListAll);
            // 待调整
            taskCode = processTaskDTO.getNextTask().get(0).getKey();
            if (!FlowStatusEnum.TO_BE_FINISHED.getName().equals(taskCode)) {
                jgChangeRegistrationName.setAuditStatus(WorkFlowStatusEnum.getMessage(taskCode).getRollBack());
            }
            jgChangeRegistrationName.setPromoter(RequestContext.getExeUserId());
            jgChangeRegistrationName.setNextExecutorIds(String.join(",", roleListNext));
            jgChangeRegistrationName.setNextTaskId(nextTaskId);
            List<WorkflowResultDto> workflowResultDtos = commonService.buildWorkFlowInfo(Collections.singletonList(processTaskDTO));
            // 更新下一步可执行人
            String nextUserIds = workflowResultDtos.get(0).getNextExecutorUserIds();
            jgChangeRegistrationName.setNextExecuteUserIds(nextUserIds);
            this.updateById(jgChangeRegistrationName);
            // 删除待办
            JSONObject jsonObject = JSONObject.parseObject(JSONObject.toJSONString(jgChangeRegistrationName));
            jsonObject.put("nextExecuteUser", jgChangeRegistrationName.getNextExecutorIds());
            jsonObject.put("taskType", BusinessTypeEnum.JG_NAME_CHANGE_REGISTRATION.getCode());
            jsonObject.put("flowStatus", this.getTaskCodeByName(jgChangeRegistrationName.getAuditStatus()));
            jsonObject.put("flowStatusLabel", jgChangeRegistrationName.getAuditStatus());
            jsonObject.put("changeCertificate", null);
            // 判断撤回后当前的节点，如果当前节点为提交节点则页面可编辑
            jsonObject.put("pageType", this.getPageTypeByCurrentNode(jgChangeRegistrationName.getAuditStatus()));
            commonService.rollbackTask(instanceId, jsonObject);

            // 保存redis最新流程数据
            commonService.saveExecuteFlowData2Redis(jgChangeRegistrationName.getInstanceId(), this.buildInstanceRuntimeData(jgChangeRegistrationName));
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if(lock.isHeldByCurrentThread()){
                lock.unlock();
            }
        }

    }

    private String getPageTypeByCurrentNode(String auditStatus) {
        if (WorkFlowStatusEnum.UNIT_RENAME_SUBMIT.getPass().equals(auditStatus) ||
                WorkFlowStatusEnum.UNIT_RENAME_SUBMIT.getReject().equals(auditStatus) ||
                WorkFlowStatusEnum.UNIT_RENAME_SUBMIT.getRollBack().equals(auditStatus)
        ) {
            // urlInfo.json 文件的 pageType
            return "edit";
        } else {
            // urlInfo.json 文件的 pageType
            return "look";
        }
    }


    public void flowExecute(Long id, String instanceId, String operate, String comment, String nextTaskId) {
        String lockKey = CommonServiceImpl.buildJgExecuteLockKey(instanceId);
        RLock lock = redissonClient.getLock(lockKey);
        try {
            boolean isLocked = lock.tryLock(0, 180, TimeUnit.SECONDS);
            // 解决并发问题：多个人同时操作一个流程（并发执行通过、驳回）
            if(!isLocked){
                throw new BadRequest("当前流程已经被执行！请重新打开页面查看并执行！");
            }
            // 流程执行时，状态及权限校验
            commonService.checkForExecuteFlow(nextTaskId, instanceId);

            JgChangeRegistrationName jgChangeRegistrationName = this.getBaseMapper().selectById(id);
            String taskId = jgChangeRegistrationName.getNextTaskId();
            // 组装信息
            TaskResultDTO dto = new TaskResultDTO();
            dto.setResultCode("approvalStatus");
            dto.setTaskId(taskId);
            dto.setComment(comment);
            dto.setNextExecuteUserCompanyCode(this.getNextUserOrgCode(operate, jgChangeRegistrationName));
            HashMap<String, Object> map = new HashMap<>();
            map.put("approvalStatus", operate);
            if (!ObjectUtils.isEmpty(jgChangeRegistrationName.getInstanceStatus()) &&
                    (jgChangeRegistrationName.getAuditStatus().equals(WorkFlowStatusEnum.UNIT_RENAME_SUBMIT.getReject()) ||
                            jgChangeRegistrationName.getAuditStatus().equals(WorkFlowStatusEnum.UNIT_RENAME_SUBMIT.getRollBack()))) {
                map.put("approvalStatus", "提交");
            }
            dto.setVariable(map);
            //执行流程
            ProcessTaskDTO processTaskDTO = cmWorkflowService.completeOrReject(taskId, dto, operate);
            // 更新下一步执行人、创建待办
            updateExecuteIds(instanceId, id, operate, processTaskDTO);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if(lock.isHeldByCurrentThread()){
                lock.unlock();
            }
        }
    }



    private String getNextUserOrgCode(String operate, JgChangeRegistrationName jgChangeRegistrationName) {
        if ("0".equals(operate)) {
            // 执行通过节点，单位code为接收机构单位信息
            return jgChangeRegistrationName.getReceiveCompanyCode();
        }
        if (jgChangeRegistrationName.getAuditStatus().equals(WorkFlowStatusEnum.UNIT_RENAME_RECEIVE.getPass())
                || jgChangeRegistrationName.getAuditStatus().equals(WorkFlowStatusEnum.UNIT_RENAME_RECEIVE.getReject())
                || jgChangeRegistrationName.getAuditStatus().equals(WorkFlowStatusEnum.UNIT_RENAME_RECEIVE.getRollBack())) {
            // 驳回且当前节点为一键节点时，单位code为发起人单位信息
            return jgChangeRegistrationName.getUseUnitCreditCode();
        }
        // 2、3级驳回时，单位code为接收单位code
        return jgChangeRegistrationName.getReceiveCompanyCode();
    }

    public void updateExecuteIds(String instanceId, Long sequenceNbr, String operate, ProcessTaskDTO processTaskDTO) {
        List<String> roleListNext = new ArrayList<>();
        List<String> roleListAll = new ArrayList<>();
        String taskCode = FlowStatusEnum.TO_BE_FINISHED.getName();
        String taskName = "";
        String nextTaskId = "";
        JgChangeRegistrationName jgChangeRegistrationName = this.getBaseMapper().selectById(sequenceNbr);
        if (processTaskDTO != null && processTaskDTO.getNextTask() != null && processTaskDTO.getNextTask().size() > 0) {
            taskCode = processTaskDTO.getNextTask().get(0).getKey();
            taskName = processTaskDTO.getNextTask().get(0).getName();
            nextTaskId = processTaskDTO.getNextTask().get(0).getId();
        }
        if (!FlowStatusEnum.TO_BE_FINISHED.getName().equals(taskCode)) {
            this.buildRoleList(Collections.singletonList(processTaskDTO), roleListNext, roleListAll);
            List<WorkflowResultDto> workflowResultDtos = commonService.buildWorkFlowInfo(Collections.singletonList(processTaskDTO));
            String nextUserIds = workflowResultDtos.get(0).getNextExecutorUserIds();
            jgChangeRegistrationName.setNextExecutorIds(String.join(",", roleListNext));
            jgChangeRegistrationName.setPromoter(RequestContext.getExeUserId());
            jgChangeRegistrationName.setInstanceId(instanceId);
            jgChangeRegistrationName.setNextTaskId(nextTaskId);
            // 更新下一步可执行人
            jgChangeRegistrationName.setNextExecuteUserIds(nextUserIds);
            if (!ObjectUtils.isEmpty(jgChangeRegistrationName.getInstanceStatus())) {
                jgChangeRegistrationName.setInstanceStatus(jgChangeRegistrationName.getInstanceStatus() + "," + String.join(",", roleListNext));
            } else {
                jgChangeRegistrationName.setInstanceStatus(String.join(",", roleListNext));
            }
            if ("0".equals(operate)) {
                // 通过操作
                jgChangeRegistrationName.setAuditStatus(WorkFlowStatusEnum.getMessage(taskCode).getPass());
            } else {
                // 驳回操作
                jgChangeRegistrationName.setAuditStatus(WorkFlowStatusEnum.getMessage(taskCode).getReject());
                jgChangeRegistrationName.setPromoter(null);
            }
            // 更新上一步待办、创建待办
            executeOneStep(jgChangeRegistrationName, taskName, nextUserIds, operate);
        } else {
            jgChangeRegistrationName.setAuditStatus(FlowStatusEnum.TO_BE_FINISHED.getName());
            jgChangeRegistrationName.setAuditPassDate(new Date());
            // 完成时 下一步骤可执行人清空
            jgChangeRegistrationName.setNextExecuteUserIds("");
            jgChangeRegistrationName.setNextTaskId(nextTaskId);
            // 修改业务信息
            updateInfoOther(jgChangeRegistrationName);
            // 更新代办
            updateTaskModel(jgChangeRegistrationName, operate);
        }
        // 保存redis最新流程数据
        commonService.saveExecuteFlowData2Redis(jgChangeRegistrationName.getInstanceId(), this.buildInstanceRuntimeData(jgChangeRegistrationName));
        this.getBaseMapper().updateById(jgChangeRegistrationName);
    }

    public InstanceRuntimeData buildInstanceRuntimeData(JgChangeRegistrationName jgChangeRegistrationName) {
        return InstanceRuntimeData.builder()
                .nextExecuteUserIds(jgChangeRegistrationName.getNextExecuteUserIds())
                .promoter(jgChangeRegistrationName.getPromoter())
                .nextTaskId(jgChangeRegistrationName.getNextTaskId())
                .build();
    }

    private TaskV2Model updateTaskModel(JgChangeRegistrationName jgChangeRegistrationName, String operate) {
        Map<String, Object> params = new HashMap<>();
        FlowStatusEnum flowStatusEnum = this.getTaskStatus(operate);
        params.put("relationId", jgChangeRegistrationName.getInstanceId());
        params.put("taskStatus", flowStatusEnum.getCode());
        params.put("taskStatusLabel", flowStatusEnum.getName());
        params.put("flowStatus", this.getTaskStatusByName(jgChangeRegistrationName.getAuditStatus()));
        params.put("flowStatusLabel", jgChangeRegistrationName.getAuditStatus());
        params.put("model", jgChangeRegistrationName);
        return commonService.updateTaskModelNew(params);
    }


    private FlowStatusEnum getTaskStatus(String operate) {
        if ("0".equals(operate)) {
            return FlowStatusEnum.TO_BE_FINISHED;
        } else {
            return FlowStatusEnum.REJECTED;
        }
    }


    private Integer getTaskStatusByName(String auditStatus) {
        return commonService.getDictionaryCodeByName(auditStatus);
    }

    public void updateInfoOther(JgChangeRegistrationName jgChangeRegistrationName) {
        LambdaQueryWrapper<JgChangeRegistrationNameEq> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(JgChangeRegistrationNameEq::getNameChangeRegistrationId, jgChangeRegistrationName.getSequenceNbr());
        List<String> collect = jgChangeRegistrationNameEqService.list(wrapper).stream().map(JgChangeRegistrationNameEq::getEquId).collect(Collectors.toList());
        if (CollUtil.isNotEmpty(collect)) {
            LambdaUpdateWrapper<JgChangeRegistrationReformEq> updateWrapper1 = new LambdaUpdateWrapper<>();
            updateWrapper1.in(JgChangeRegistrationReformEq::getEquId, collect);
            updateWrapper1.ne(JgChangeRegistrationReformEq::getEquipTransferId, jgChangeRegistrationName.getSequenceNbr());
            JgChangeRegistrationReformEq jgChangeRegistrationReformEq = new JgChangeRegistrationReformEq();
            jgChangeRegistrationReformEq.setIsInvalid(Boolean.TRUE);
            jgChangeRegistrationReformEqMapper.update(jgChangeRegistrationReformEq, updateWrapper1);

            LambdaUpdateWrapper<JgChangeRegistrationTransferEq> updateWrapper2 = new LambdaUpdateWrapper<>();
            updateWrapper2.in(JgChangeRegistrationTransferEq::getEquId, collect);
            updateWrapper2.ne(JgChangeRegistrationTransferEq::getEquipTransferId, jgChangeRegistrationName.getSequenceNbr());
            JgChangeRegistrationTransferEq jgChangeRegistrationTransferEq = new JgChangeRegistrationTransferEq();
            jgChangeRegistrationReformEq.setIsInvalid(Boolean.TRUE);
            jgChangeRegistrationTransferEqMapper.update(jgChangeRegistrationTransferEq, updateWrapper2);

            LambdaUpdateWrapper<JgUseRegistrationEq> updateWrapper3 = new LambdaUpdateWrapper<>();
            updateWrapper3.in(JgUseRegistrationEq::getEquId, collect);
            updateWrapper3.ne(JgUseRegistrationEq::getEquipTransferId, jgChangeRegistrationName.getSequenceNbr());
            JgUseRegistrationEq jgUseRegistrationEq = new JgUseRegistrationEq();
            jgUseRegistrationEq.setIsInvalid(Boolean.TRUE);
            jgUseRegistrationEqMapper.update(jgUseRegistrationEq, updateWrapper3);

            LambdaUpdateWrapper<JgChangeRegistrationUnitEq> updateWrapper4 = new LambdaUpdateWrapper<>();
            updateWrapper4.in(JgChangeRegistrationUnitEq::getEquId, collect);
            updateWrapper4.ne(JgChangeRegistrationUnitEq::getUnitChangeRegistrationId, jgChangeRegistrationName.getSequenceNbr());
            JgChangeRegistrationUnitEq jgChangeRegistrationUnitEq = new JgChangeRegistrationUnitEq();
            jgChangeRegistrationUnitEq.setIsInvalid("1");
            jgChangeRegistrationUnitEqMapper.update(jgChangeRegistrationUnitEq, updateWrapper4);

            LambdaUpdateWrapper<JgChangeRegistrationNameEq> updateWrapper5 = new LambdaUpdateWrapper<>();
            updateWrapper5.in(JgChangeRegistrationNameEq::getEquId, collect);
            updateWrapper5.ne(JgChangeRegistrationNameEq::getNameChangeRegistrationId, jgChangeRegistrationName.getSequenceNbr());
            JgChangeRegistrationNameEq jgChangeRegistrationNameEq = new JgChangeRegistrationNameEq();
            jgChangeRegistrationNameEq.setIsInvalid("1");
            jgChangeRegistrationNameEqMapper.update(jgChangeRegistrationNameEq, updateWrapper5);
        }

        LambdaUpdateWrapper<RegUnitInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(RegUnitInfo::getUnitCode, jgChangeRegistrationName.getUseUnitCreditCode());
        RegUnitInfo regUnitInfo = new RegUnitInfo();
        regUnitInfo.setName(jgChangeRegistrationName.getNewUseUnitName());
        regUnitInfoMapper.update(regUnitInfo, updateWrapper);

        LambdaUpdateWrapper<TzBaseEnterpriseInfo> updateWrapper2 = new LambdaUpdateWrapper<>();
        updateWrapper2.eq(TzBaseEnterpriseInfo::getUseCode, jgChangeRegistrationName.getUseUnitCreditCode());
        TzBaseEnterpriseInfo tzBaseEnterpriseInfo = new TzBaseEnterpriseInfo();
        regUnitInfo.setName(jgChangeRegistrationName.getNewUseUnitName());
        tzBaseEnterpriseInfoMapper.update(tzBaseEnterpriseInfo, updateWrapper2);
        //修改平台机构名称
        try {
            Privilege.companyClient.updateCompanyName(jgChangeRegistrationName.getUseUnitCreditCode(), jgChangeRegistrationName.getNewUseUnitName());
        } catch (InnerInvokException e) {
            throw new RuntimeException();
        }
    }

    public Map<String, Object> queryBySequenceNbr(Long sequenceNbr) {
        ReginParams reginParams = JSON.parseObject(redisUtils.get(RedisKey.buildReginKey(RequestContext.getExeUserId(), RequestContext.getToken())).toString(), ReginParams.class);
        Map<String, Object> resultMap = accessFeignService.getData(reginParams.getCompany().getCompanyCode()).getResult();
        String unitName = String.valueOf(resultMap.getOrDefault("unitName", ""));
        JgChangeRegistrationName jgChangeRegistrationName = new JgChangeRegistrationName();
        Map<String, Object> dtoMap = new HashMap<>();
        Map<String, Object> map = new HashMap<>();
        if (!Objects.isNull(sequenceNbr)) {
            jgChangeRegistrationName = this.baseMapper.selectById(sequenceNbr);
            jgChangeRegistrationName.setReceiveOrgCode(jgChangeRegistrationName.getReceiveCompanyCode() + "_" + jgChangeRegistrationName.getReceiveOrgName());
            // 页面可编辑（当前登录人是发起人）且符合这个 监管机构 false
            if(!JG_COMAPNY_TYPE.equals(reginParams.getCompany().getCompanyType())){
                dtoMap.put("isInProvince", this.justIsInProvince(reginParams.getCompany().getCompanyCode()));
            } else {
                dtoMap.put("isInProvince", false);
            }
        } else {
            jgChangeRegistrationName.setUseUnitCreditCode(reginParams.getCompany().getCompanyCode());
            jgChangeRegistrationName.setNewUseUnitName(unitName);
            jgChangeRegistrationName.setUseUnitName(reginParams.getCompany().getCompanyName());
            // 初始时：返回当前登录人的公司信息，用来判断是否新名称是否可编辑
            dtoMap.put("isInProvince", this.justIsInProvince(reginParams.getCompany().getCompanyCode()));
        }
        BeanUtil.copyProperties(jgChangeRegistrationName, dtoMap);
        dtoMap.put("changeCertificate", JSON.parseArray(jgChangeRegistrationName.getChangeCertificate()));
        dtoMap.put("otherAccessories", JSON.parseArray(jgChangeRegistrationName.getOtherAccessories()));
        map.put("jgRegistrationInfo", dtoMap);
        return map;
    }

    private Boolean justIsInProvince(String companyCode){
        TzBaseEnterpriseInfo baseEnterpriseInfo = baseEnterpriseInfoMapper.selectOne(new LambdaQueryWrapper<TzBaseEnterpriseInfo>().eq(TzBaseEnterpriseInfo::getUseCode, companyCode));
        if(baseEnterpriseInfo == null ){
            log.warn(companyCode + "无企业信息");
            return false;
        }
        String dataSource = baseEnterpriseInfo.getDataSources();
        String registerType = baseEnterpriseInfo.getRegisterType();
        String[] disabledDataSource =  {"企业注册", "陕西省内企业"};
        String[] disabledRegisterType = {"企业单位"};
        // 省内的企业且类型为企业时
        return Arrays.asList(disabledDataSource).contains(dataSource) && Arrays.asList(disabledRegisterType).contains(registerType);
    }


    public Page<Map<String, Object>> getList(JgChangeRegistrationNameDto dto, Page<Map<String, Object>> page, List<String> roleIds, String companyCode) {
        if (org.apache.commons.lang3.StringUtils.isNotBlank(dto.getReceiveOrgCode())) {
            String[] receiveOrgIdList = dto.getReceiveOrgCode().split("_");
            if (receiveOrgIdList.length > 1) {
                dto.setReceiveOrgCode(receiveOrgIdList[0]);
                dto.setReceiveCompanyCode(receiveOrgIdList[0]);
            }
        }
        return this.baseMapper.getListPage(page, dto, roleIds, companyCode, RequestContext.getExeUserId());
    }
}