package com.zjsgfa.project.zjsgfa.controller;

import com.zjsgfa.common.utils.DateUtils;
import com.zjsgfa.common.utils.SecurityUtils;
import com.zjsgfa.common.utils.ServletUtils;
import com.zjsgfa.common.utils.StringUtils;
import com.zjsgfa.framework.web.domain.AjaxResult;
import com.zjsgfa.project.system.domain.SysDept;
import com.zjsgfa.project.system.mapper.SysDeptMapper;
import com.zjsgfa.project.system.service.ISysUserService;
import com.zjsgfa.project.zjsgfa.domain.BizTodoItem;
import com.zjsgfa.project.zjsgfa.domain.SjDjjc;
import com.zjsgfa.project.zjsgfa.mapper.SjDjjcMapper;
import com.zjsgfa.project.zjsgfa.service.IBizTodoItemService;
import com.zjsgfa.project.zjsgfa.service.ProcessService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.xml.ws.soap.Addressing;
import java.util.*;
import java.util.stream.Collectors;

import static com.zjsgfa.framework.web.domain.AjaxResult.success;

@RestController
@RequestMapping("/sjdjlc")
public class DjjcLcController
{



    //流程id
    private String processDefinitionKey="_e666525e-07bb-11f1-9537-803049cc3d25";
    //钻井液
    private String processDefinitionKeyZjy="_f2e34959-07db-11f1-9537-803049cc3d25";


    private String processTrend = "flowTrend";
    /** 流程节点 任务书编辑 参数名 */
    private String taskEditParamName = "editor";

    private String Complete_Module = "system/sjdjlc";
    /** 流程节点 审核节点 审核人 参数名 */
    private String paramName_audit_user = "assigneeList";


    public static final String GC_AQSP = "gc_aqsp";

    /**
     * 工程_站长审批
     */
    public static final String GC_ZZSP = "gc_zzsp";

    /**
     * 工程_专家审批
     */
    public static final String GC_ZJSP = "gc_zjsp";
    public static final String GC_ZJSPHB = "gc_zjsphb";
    public static final String GC_ZJSP_YYY_NDY = "gc_zjsp_yyy_ndy";

    /**
     * 工程_首席专家
     */
    public static final String GC_SXZJ = "gc_sxzj";
    public static final String GC_SXZJ_CZJ = "gc_sxzj_czj";
    public static final String GC_SXZJ_YYY = "gc_sxzj_yyy";
    public static final String GC_SXZJ_SCJ = "gc_sxzj_scj";



    /**
     * 工程_分管领导
     */
    public static final String GC_FGLD = "gc_fgld";


    /**
     * 钻井液_安全审批
     */
    public static final String ZJY_AQSP = "zjy_aqsp";

    /**
     * 钻井液_站长审批
     */
    public static final String ZJY_ZZSP = "zjy_zzsp";

    /**
     * 钻井液_专家审批
     */
    public static final String ZJY_ZJSP = "zjy_zjsp";

    /**
     * 钻井液_首席专家
     */
    public static final String ZJY_SXZJ = "zjy_sxzj";

    /**
     * 钻井液_分管领导
     */
    public static final String ZJY_FGLD = "zjy_fgld";
    


    @Autowired
    private SjDjjcMapper sjDjjcMapper;

    @Autowired
    RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysDeptMapper sysDeptMapper;

    @Autowired
    private IBizTodoItemService bizTodoItemService;

    @Autowired
    private ProcessService processService;


    /**
     * 根据流程id查询详情
     * @param instanceId
     * @return
     */
    @GetMapping("/getInfo/{instanceId}")
    public AjaxResult getInfo(@PathVariable("instanceId") String instanceId)
    {
        SjDjjc sjDjjc = sjDjjcMapper.selectSjDjjcByinstanceId(instanceId);
        return success(sjDjjc);
    }

    /**
     * 根据流程id查询详情
     * @param instanceId
     * @return
     */
    @GetMapping("/getInfoZjy/{instanceId}")
    public AjaxResult getInfoZjy(@PathVariable("instanceId") String instanceId)
    {
        SjDjjc sjDjjc = sjDjjcMapper.selectSjDjjcByinstanceIdZjy(instanceId);
        return success(sjDjjc);
    }




    @GetMapping("/submitApply")
    @Transactional
    public AjaxResult getDjjcLc(Long ID)
    {

        SjDjjc sjDjjc = sjDjjcMapper.selectSjDjjcById(ID);


        String businessKey = sjDjjc.getId().toString();
        String applyUserId=SecurityUtils.getUsername();

        String itemName = "工程方案审核";
        String itemContent = sjDjjc.getJh()+"工程方案审核";
        Map<String,Object> variables=new HashMap<>();

        // 设置下一节点处理人
        // 下一节点任务书编辑 处理人为提交者
        variables.put(taskEditParamName, applyUserId); // 设置下一节点审核人 设置userId


        // 启动流程时设置业务 key
        ProcessInstance instance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variables);

        String processInstanceId = instance.getId();
        sjDjjc.setInstanceId(processInstanceId); // 建立双向关系
        sjDjjc.setApplyUser(applyUserId);
        sjDjjc.setApplyTime(DateUtils.getNowDate());
        sjDjjc.setProcessStatus("审核中");//流程状态1 已经提交
        sjDjjc.setType(processDefinitionKey);//流程定义key
        sjDjjcMapper.updateSjDjjc(sjDjjc);

        String comment = "";
        // 下一节点处理人待办事项
        bizTodoItemService.insertTodoItem(instance.getProcessInstanceId(), itemName, itemContent, Complete_Module,comment);


        autoCompleteFirstSubmit(applyUserId, processDefinitionKey, processInstanceId, sjDjjc);

        return success();
    }





    /**
     * 完成任务
     * @param sjDjjc
     * @return
     */
    @PostMapping("/complete")
    @Transactional
    public AjaxResult complete(@RequestBody SjDjjc sjDjjc) {

        try {
            SjDjjc entity = sjDjjcMapper.selectSjDjjcByinstanceId(sjDjjc.getInstanceId());
            String taskId = sjDjjc.getTaskId();
            String instanceId = sjDjjc.getInstanceId();


            // 使用任务ID，查询任务对象
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            // 获取当前节点 活动id
            String act_id = task.getTaskDefinitionKey();
            // 获取审核用户选择的走向 同意 退修 驳回
            String flowTrendOption = sjDjjc.getFlowTrendOption();

            // 流程的显示标题 取课题名称接后缀任务书审核

            String itemName = "工程方案审核";
            String itemContent = entity.getJh()+"工程方案审核";

            // 审核节点每次提交，需要更新业务表信息
            SjDjjc tmpProject = new SjDjjc();
            tmpProject.setId(entity.getId());

            // 获取流程发起人、和所属部门id
            String applyUserId = entity.getApplyUser();
            Long applyUserDeptId = userService.selectUserByLoginName(applyUserId).getDeptId();
            SysDept sysDept = sysDeptMapper.selectDeptById(applyUserDeptId);

            Long secondaryUnit = getSecondaryUnit(applyUserDeptId, sysDept.getAncestors());
            if(secondaryUnit==null){
                secondaryUnit=applyUserDeptId;
            }
            //查询二级单位下所有的单位
            List<SysDept> sysDeptList=sysDeptMapper.selectDeptListByParentId(secondaryUnit);

            Map<String,Object> variables =new HashMap<>();

            String ndxsjg = entity.getNdxsjg();
            if(StringUtils.isEmpty(ndxsjg)){
                ndxsjg="3";
            }

            // 先判断走向
            if ("back".equals(flowTrendOption)) { // 退修
                variables.put(processTrend, "退修");
                // 下一节点任务书编辑 处理人为提交者
                variables.put(taskEditParamName, entity.getApplyUser()); // 设置下一节点审核人 设置userId
                // 更新 驳回原因字段 存放退修原因
                tmpProject.setRefuseContent(sjDjjc.getP_COM_comment());
                tmpProject.setProcessStatus("退修");
                sjDjjcMapper.updateSjDjjcById(tmpProject);
            } else if ("true".equals(flowTrendOption)) { // 同意
                variables.put(processTrend, "同意");
                // 根据当前不同的节点，下一节点不同，需要设置的处理人不同
                // 下一节点审核节点 处理人为根据角色code取多人 一人处理即可通过
                if (GC_AQSP.equals(act_id)) {//当前节点 安全审批
                    //判断发起人的部门
                    List<String> assignee=new ArrayList<>();
                    assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(applyUserDeptId,GC_ZZSP));
                    //侧钻井站（侧钻井站长和华北站的都可以审批）
                    if(sysDept.getDeptId()==116L){
                        //查询华北站审批人
                        SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 119L).findFirst().orElse(null);
                        if(sysDept1!=null){
                            assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),GC_ZZSP));
                        }
                    }else if(sysDept.getDeptId()==124L || sysDept.getDeptId()==125L){
                        //生产井和探井
                        SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 125L).findFirst().orElse(null);
                        if(sysDept1!=null){
                            assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),GC_ZZSP));
                        }
                        SysDept sysDept2 = sysDeptList.stream().filter(item -> item.getDeptId() == 124L).findFirst().orElse(null);
                        if(sysDept2!=null){
                            assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept2.getDeptId(),GC_ZZSP));
                        }

                    }else {
                        assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(applyUserDeptId,GC_ZZSP));
                    }

                    if(assignee.size()==0){
                        assignee.add("chenggq58");
                    }
                    variables.put(paramName_audit_user, assignee.stream().distinct().collect(Collectors.toList()));
                }else if (GC_ZZSP.equals(act_id)) {//当前节点 站长审批

                    if(ndxsjg.equals("3")){
                        variables.put(processTrend, "结束");
                        tmpProject.setProcessStatus("通过");
                        sjDjjcMapper.updateSjDjjcById(tmpProject);
                    }else {
                        List<String> assignee=new ArrayList<>();
                        //侧钻井+生产井、探井
                        if(sysDept.getDeptId()==116L || sysDept.getDeptId()==124L || sysDept.getDeptId()==125L){
                            //查询华北站审批人
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 115L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),GC_ZJSP));
                            }
                        }else if(sysDept.getDeptId()==119L){
                            //华北
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 128L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),GC_ZJSPHB));
                            }
                        }else if(sysDept.getDeptId()==126L || sysDept.getDeptId()==122L){
                            //页岩油+难动用
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 128L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),GC_ZJSP_YYY_NDY));
                            }
                        }

                        if(assignee.size()==0){
                            assignee.add("chenggq58");
                        }
                        variables.put(paramName_audit_user, assignee.stream().distinct().collect(Collectors.toList()));
                    }
                }else if (GC_ZJSP.equals(act_id)) {//当前节点 专家审批

                    if(ndxsjg.equals("5")){
                        variables.put(processTrend, "结束");
                        tmpProject.setProcessStatus("通过");
                        sjDjjcMapper.updateSjDjjcById(tmpProject);
                    }else {
                        List<String> assignee=new ArrayList<>();
                        if(sysDept.getDeptId()==122L){
                            //难动用
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 121L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),GC_SXZJ));
                            }
                        }else   if(sysDept.getDeptId()==116L){
                            //侧钻井
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 121L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),GC_SXZJ_CZJ));
                            }
                        }else   if(sysDept.getDeptId()==126L){
                            //页岩油
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 121L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),GC_SXZJ_YYY));
                            }
                        }else   if(sysDept.getDeptId()==124L || sysDept.getDeptId()==125L){
                            //生产井、探井
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 121L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),GC_SXZJ_SCJ));
                            }
                        }
                        if(assignee.size()==0){
                            assignee.add("chenggq58");
                        }
                        variables.put(paramName_audit_user, assignee.stream().distinct().collect(Collectors.toList()));
                    }
                }else if (GC_SXZJ.equals(act_id)) {//当前节点 首席专家审批

                    if(ndxsjg.equals("7")){
                        variables.put(processTrend, "结束");
                        tmpProject.setProcessStatus("通过");
                        sjDjjcMapper.updateSjDjjcById(tmpProject);
                    }else {
                        List<String> assignee =new ArrayList<>();
                        assignee = userService.selectUserLoginNamesByRoleKeyDept(118L,GC_FGLD);
                        if(assignee.size()==0){
                            assignee.add("chenggq58");
                        }
                        variables.put(paramName_audit_user, assignee.stream().distinct().collect(Collectors.toList()));
                    }
                }else if (GC_FGLD.equals(act_id)) {//当前节点 站长审批
                    tmpProject.setProcessStatus("通过");
                    sjDjjcMapper.updateSjDjjcById(tmpProject);
                }
            }
            String comment="";
            if ("true".equals(flowTrendOption)) {
                comment = "【同意】" + sjDjjc.getP_COM_comment();
            } else if ("back".equals(flowTrendOption)) {
                comment = "【退修】" + sjDjjc.getP_COM_comment();
            } else if ("reject".equals(flowTrendOption)) {
                comment = "【驳回】" + sjDjjc.getP_COM_comment();
            } else {
                comment = "【提交】" + sjDjjc.getP_COM_comment();
            }

            processService.complete(sjDjjc.getTaskId(), instanceId, itemName, itemContent, Complete_Module, variables, ServletUtils.getRequest(),comment);
        } catch (Exception e) {
            return AjaxResult.error("办理失败");
        }

        return success();
    }




    @GetMapping("/submitApplyZjy")
    @Transactional
    public AjaxResult submitApplyZjy(Long ID)
    {

        try {
            SjDjjc sjDjjc = sjDjjcMapper.selectSjDjjcById(ID);


            String businessKey = sjDjjc.getId().toString();
            String applyUserId=SecurityUtils.getUsername();

            String itemName = "钻井液方案审核";
            String itemContent = sjDjjc.getJh()+"钻井液方案审核";
            Map<String,Object> variables=new HashMap<>();

            // 设置下一节点处理人
            // 下一节点任务书编辑 处理人为提交者
            variables.put(taskEditParamName, applyUserId); // 设置下一节点审核人 设置userId


            // 启动流程时设置业务 key
            ProcessInstance instance = runtimeService.startProcessInstanceByKey(processDefinitionKeyZjy, businessKey, variables);

            String processInstanceId = instance.getId();
            sjDjjc.setZjyinstanceId(processInstanceId); // 建立双向关系
            sjDjjc.setZjyapplyUser(applyUserId);
            sjDjjc.setZjyapplyTime(DateUtils.getNowDate());
            sjDjjc.setZjyprocessStatus("审核中");//流程状态1 已经提交
            sjDjjc.setZjytype(processDefinitionKeyZjy);//流程定义key
            sjDjjcMapper.updateSjDjjc(sjDjjc);

            String comment = "";
            // 下一节点处理人待办事项
            bizTodoItemService.insertTodoItem(instance.getProcessInstanceId(), itemName, itemContent, Complete_Module,comment);


            autoCompleteFirstSubmitZjy(applyUserId, processDefinitionKeyZjy, processInstanceId, sjDjjc);

            return success();
        } catch (Exception e) {

            return AjaxResult.error("提交失败");
        }
    }


    /**
     * 完成任务
     * @param sjDjjc
     * @return
     */
    @PostMapping("/completeZjy")
    @Transactional
    public AjaxResult completeZjy(@RequestBody SjDjjc sjDjjc) {

        try {
            SjDjjc entity = sjDjjcMapper.selectSjDjjcByinstanceIdZjy(sjDjjc.getInstanceId());
            String taskId = sjDjjc.getTaskId();
            String instanceId = sjDjjc.getInstanceId();


            // 使用任务ID，查询任务对象
            Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
            // 获取当前节点 活动id
            String act_id = task.getTaskDefinitionKey();
            // 获取审核用户选择的走向 同意 退修 驳回
            String flowTrendOption = sjDjjc.getFlowTrendOption();

            // 流程的显示标题 取课题名称接后缀任务书审核

            String itemName = "钻井液方案审核";
            String itemContent = entity.getJh()+"钻井液方案审核";

            // 审核节点每次提交，需要更新业务表信息
            SjDjjc tmpProject = new SjDjjc();
            tmpProject.setId(entity.getId());

            // 获取流程发起人、和所属部门id
            String applyUserId = entity.getZjyapplyUser();
            Long applyUserDeptId = userService.selectUserByLoginName(applyUserId).getDeptId();
            SysDept sysDept = sysDeptMapper.selectDeptById(applyUserDeptId);

            Long secondaryUnit = getSecondaryUnit(applyUserDeptId, sysDept.getAncestors());
            if(secondaryUnit==null){
                secondaryUnit=applyUserDeptId;
            }
            //查询二级单位下所有的单位
            List<SysDept> sysDeptList=sysDeptMapper.selectDeptListByParentId(secondaryUnit);
            Map<String,Object> variables =new HashMap<>();

            String ndxsjg = entity.getNdxsjg();
            if(StringUtils.isEmpty(ndxsjg)){
                ndxsjg="3";
            }

            // 先判断走向
            if ("back".equals(flowTrendOption)) { // 退修
                variables.put(processTrend, "退修");
                // 下一节点任务书编辑 处理人为提交者
                variables.put(taskEditParamName, entity.getApplyUser()); // 设置下一节点审核人 设置userId
                // 更新 驳回原因字段 存放退修原因
                tmpProject.setZjyrefuseContent(sjDjjc.getP_COM_comment());
                tmpProject.setZjyprocessStatus("退修");
                sjDjjcMapper.updateSjDjjcById(tmpProject);
            } else if ("true".equals(flowTrendOption)) { // 同意
                variables.put(processTrend, "同意");
                // 根据当前不同的节点，下一节点不同，需要设置的处理人不同
                // 下一节点审核节点 处理人为根据角色code取多人 一人处理即可通过
                if (ZJY_AQSP.equals(act_id)) {//当前节点 安全审批
                    List<String> assignee=new ArrayList<>();

                    assignee = userService.selectUserLoginNamesByRoleKeyDept(secondaryUnit,ZJY_ZZSP);
                    if(sysDept.getDeptId()==124L || sysDept.getDeptId()==125L){
                        //生产井和探井
                        SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 125L).findFirst().orElse(null);
                        if(sysDept1!=null){
                            assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),ZJY_ZZSP));
                        }
                        SysDept sysDept2 = sysDeptList.stream().filter(item -> item.getDeptId() == 124L).findFirst().orElse(null);
                        if(sysDept2!=null){
                            assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept2.getDeptId(),ZJY_ZZSP));
                        }

                    }

                    if(assignee.size()==0){
                        assignee.add("chenggq58");
                    }
                    variables.put(paramName_audit_user, assignee.stream().distinct().collect(Collectors.toList()));
                }else if (ZJY_ZZSP.equals(act_id)) {//当前节点 站长审批

                    if(ndxsjg.equals("3")){
                        variables.put(processTrend, "结束");
                        tmpProject.setZjyprocessStatus("通过");
                        sjDjjcMapper.updateSjDjjcById(tmpProject);
                    }else {
                        List<String> assignee=new ArrayList<>();
                        if(sysDept.getDeptId()==116L || sysDept.getDeptId()==122L){
                            //侧钻井+难动用
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 127L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),ZJY_ZJSP));
                            }
                        }else if(sysDept.getDeptId()==126L){
                            //页岩油
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 126L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),ZJY_ZJSP));
                            }
                        }else if(sysDept.getDeptId()==124L || sysDept.getDeptId()==125L){
                            //生产井、探井
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 129L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),ZJY_ZJSP));
                            }
                        }else if(sysDept.getDeptId()==119L ){
                            //华北站
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 119L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                assignee.addAll(userService.selectUserLoginNamesByRoleKeyDept(sysDept1.getDeptId(),ZJY_ZJSP));
                            }
                        }

                        if(assignee.size()==0){
                            assignee.add("chenggq58");
                        }
                        variables.put(paramName_audit_user, assignee.stream().distinct().collect(Collectors.toList()));
                    }
                }else if (ZJY_ZJSP.equals(act_id)) {//当前节点 专家审批

                    if(ndxsjg.equals("5")){
                        variables.put(processTrend, "结束");
                        tmpProject.setZjyprocessStatus("通过");
                        sjDjjcMapper.updateSjDjjcById(tmpProject);
                    }else {
                        //分管领导
                        List<String> assignee = userService.selectUserLoginNamesByRoleKeyDept(118L,ZJY_SXZJ);
                        variables.put(paramName_audit_user, assignee.stream().distinct().collect(Collectors.toList()));
                    }
                }else if (ZJY_SXZJ.equals(act_id)) {//当前节点 首席专家审批

                    if(ndxsjg.equals("7")){
                        variables.put(processTrend, "结束");
                        tmpProject.setZjyprocessStatus("通过");
                        sjDjjcMapper.updateSjDjjcById(tmpProject);
                    }else {
                        List<String> assignee = userService.selectUserLoginNamesByRoleKeyDept(118L,ZJY_FGLD);
                        variables.put(paramName_audit_user, assignee.stream().distinct().collect(Collectors.toList()));
                    }
                }else if (ZJY_FGLD.equals(act_id)) {//当前节点 分管领导审批
                    tmpProject.setZjyprocessStatus("通过");
                    sjDjjcMapper.updateSjDjjcById(tmpProject);
                }
            }
            String comment="";
            if ("true".equals(flowTrendOption)) {
                comment = "【同意】" + sjDjjc.getP_COM_comment();
            } else if ("back".equals(flowTrendOption)) {
                comment = "【退修】" + sjDjjc.getP_COM_comment();
            } else if ("reject".equals(flowTrendOption)) {
                comment = "【驳回】" + sjDjjc.getP_COM_comment();
            } else {
                comment = "【提交】" + sjDjjc.getP_COM_comment();
            }

            processService.complete(sjDjjc.getTaskId(), instanceId, itemName, itemContent, Complete_Module, variables, ServletUtils.getRequest(),comment);
        } catch (Exception e) {
            return AjaxResult.error("办理失败");
        }

        return success();
    }




    /**
     * 获取流程历史
     * @param instanceId
     * @return
     */
    @GetMapping("/getLcls/{instanceId}")
     public AjaxResult getLcls(@PathVariable("instanceId") String instanceId) {
        Map<String, Object> resultMap = new HashMap<>();
        
        // 获取审批历史表格数据
        List<BizTodoItem> bizTodoItems = getApprovalHistory(instanceId);
        resultMap.put("table", bizTodoItems);

        // 获取最后一个开始之后的审批历史
        List<BizTodoItem> lastHistoryTodoItemsList = bizTodoItemService.lastHistoryByInstanceId(instanceId);

        if (bizTodoItems.isEmpty()) {
            return success(resultMap);
        }
        
        String type = bizTodoItems.get(0).getItemName();
        boolean isEngineeringType = "工程方案审核".equals(type);
        
        // 获取审批相关信息
        ApprovalInfo approvalInfo = getApprovalInfo(instanceId, isEngineeringType);
        String ndjg = StringUtils.isEmpty(approvalInfo.getNdxsjg()) ? "3" : approvalInfo.getNdxsjg();
        
        // 构建流程节点列表
        List<Map<String, Object>> jdList = buildProcessNodes(isEngineeringType, ndjg, approvalInfo.getApplyUserName());
        
        // 查询审批人员并设置节点状态
        populateNodeUserInfo(jdList, bizTodoItems, approvalInfo.getSecondaryUnit(),approvalInfo.applyUserDeptId,isEngineeringType, lastHistoryTodoItemsList);
        
        resultMap.put("jdList", jdList);
        return success(resultMap);
    }


    @PostMapping("/tjch")
    public  AjaxResult tjch(@RequestBody  SjDjjc sjDjjc){
        String chtype=sjDjjc.getChtype();
        String instanceId=sjDjjc.getInstanceId();

        if("钻井液方案审核".equals(chtype)){
            SjDjjc item = sjDjjcMapper.selectSjDjjcByinstanceIdZjy(instanceId);

            sjDjjcMapper.updateSjDjjcLcZjy(item.getId());
        }else if("工程方案审核".equals(chtype)){
            SjDjjc item = sjDjjcMapper.selectSjDjjcByinstanceId(instanceId);
            sjDjjcMapper.updateSjDjjcLc(item.getId());
        }
        //删除流程
        sjDjjcMapper.deleteLc(instanceId);

        return AjaxResult.success("撤回成功");
    }








    /**
     * 撤回任务
     *
     * @return
     */
    @RequestMapping(value = "/chrw/{taskId}/{ID}", method = {RequestMethod.POST, RequestMethod.GET})
    @ResponseBody
    public AjaxResult chrw(@PathVariable("taskId") String taskId,@PathVariable("ID") Long ID, HttpServletRequest request) {
        SjDjjc entity = sjDjjcMapper.selectSjDjjcById(ID);
        entity.setP_B_approved("false");
        entity.setP_COM_comment("不同意");
//        zyZlNdjhService.chrw(taskId, entity, processDefinitionKey, new HashMap<>(), request);

        // 流程的显示标题
        String itemName = "工程方案审核";
        String itemContent = entity.getJh()+"工程方案审核";

        // 审核节点每次提交，需要更新业务表信息
        SjDjjc tmpProject = new SjDjjc();
        tmpProject.setId(entity.getId());
        Map<String,Object> variables =new HashMap<>();
        // 获取流程发起人、和所属部门id
        String applyUserId = entity.getApplyUser();

        variables.put(processTrend, "退修");
        // 下一节点任务书编辑 处理人为提交者
        variables.put(taskEditParamName, applyUserId); // 设置下一节点审核人 设置userId
        processService.ch(taskId, entity.getInstanceId(), itemName, itemContent, Complete_Module, variables, request);

        return success("任务已撤回");
    }


    
    /**
     * 获取审批历史记录
     */
    private List<BizTodoItem> getApprovalHistory(String instanceId) {
        BizTodoItem bizTodoItem = new BizTodoItem();
        bizTodoItem.setInstanceId(instanceId);
        List<BizTodoItem> bizTodoItems = bizTodoItemService.selectBizTodoItemList2(bizTodoItem);
        return bizTodoItems;
    }
    
    /**
     * 审批信息封装类
     */
    private static class ApprovalInfo {
        private String ndxsjg;
        private String applyUserName;
        private Long secondaryUnit;
        private Long applyUserDeptId;

        // getters and setters
        public String getNdxsjg() { return ndxsjg; }
        public void setNdxsjg(String ndxsjg) { this.ndxsjg = ndxsjg; }
        public String getApplyUserName() { return applyUserName; }
        public void setApplyUserName(String applyUserName) { this.applyUserName = applyUserName; }
        public Long getSecondaryUnit() { return secondaryUnit; }
        public void setSecondaryUnit(Long secondaryUnit) { this.secondaryUnit = secondaryUnit; }

        public Long getApplyUserDeptId() { return applyUserDeptId; }
        public void setApplyUserDeptId(Long applyUserDeptId) { this.applyUserDeptId = applyUserDeptId; }
    }
    
    /**
     * 获取审批相关信息
     */
    private ApprovalInfo getApprovalInfo(String instanceId, boolean isEngineeringType) {
        ApprovalInfo info = new ApprovalInfo();
        SjDjjc sjDjjc = isEngineeringType ? 
            sjDjjcMapper.selectSjDjjcByinstanceId(instanceId) : 
            sjDjjcMapper.selectSjDjjcByinstanceIdZjy(instanceId);
            
        info.setNdxsjg(sjDjjc.getNdxsjg());
        
        String applyUserId = isEngineeringType ? sjDjjc.getApplyUser() : sjDjjc.getZjyapplyUser();
        info.setApplyUserName(isEngineeringType ? sjDjjc.getApplyUserName() : sjDjjc.getZjyapplyUserName());
        
        // 获取二级单位
        Long applyUserDeptId = userService.selectUserByLoginName(applyUserId).getDeptId();
        SysDept sysDept = sysDeptMapper.selectDeptById(applyUserDeptId);
        Long secondaryUnit = getSecondaryUnit(applyUserDeptId, sysDept.getAncestors());
        info.setSecondaryUnit(secondaryUnit != null ? secondaryUnit : applyUserDeptId);
        info.setApplyUserDeptId(applyUserDeptId);

        return info;
    }
    
    /**
     * 构建流程节点列表
     */
    private List<Map<String, Object>> buildProcessNodes(boolean isEngineeringType, String ndjg, String applyUserName) {
        List<Map<String, Object>> jdList = new ArrayList<>();
        
        // 开始节点
        jdList.add(createNode("开始", isEngineeringType ? GC_AQSP : ZJY_AQSP, Arrays.asList(applyUserName)));
        
        // 安全审批节点
        jdList.add(createNode("安全审批", isEngineeringType ? GC_AQSP : ZJY_AQSP, null));
        
        // 站长审批节点
        jdList.add(createNode("站长审批", isEngineeringType ? GC_ZZSP : ZJY_ZZSP, null));
        
        // 根据ndjg值添加相应节点
        switch (ndjg) {
            case "5": 
                jdList.add(createNode("专家审批", isEngineeringType ? GC_ZJSP : ZJY_ZJSP, null));
                break;
            case "7": 
                jdList.add(createNode("专家审批", isEngineeringType ? GC_ZJSP : ZJY_ZJSP, null));
                jdList.add(createNode("首席专家", isEngineeringType ? GC_SXZJ : ZJY_SXZJ, null));
                break;
            case "8": 
                jdList.add(createNode("专家审批", isEngineeringType ? GC_ZJSP : ZJY_ZJSP, null));
                jdList.add(createNode("首席专家", isEngineeringType ? GC_SXZJ : ZJY_SXZJ, null));
                jdList.add(createNode("分管领导", isEngineeringType ? GC_FGLD : ZJY_FGLD, null));
                break;
        }
        
        return jdList;
    }
    
    /**
     * 创建节点
     */
    private Map<String, Object> createNode(String name, String roleKey, List<String> userList) {
        Map<String, Object> node = new HashMap<>();
        node.put("name", name);
        node.put("roleKye", roleKey);
        if (userList != null) {
            node.put("userList", userList);
        }
        return node;
    }
    
    /**
     * 填充节点用户信息和状态
     */
    private void populateNodeUserInfo(List<Map<String, Object>> jdList, List<BizTodoItem> bizTodoItems, Long secondaryUnit,Long applyUserDeptId,Boolean isEngineeringType, List<BizTodoItem> lastHistoryTodoItemsList) {
        List<SysDept> sysDeptList=sysDeptMapper.selectDeptListByParentId(secondaryUnit);
        SysDept sysDept = sysDeptMapper.selectDeptById(applyUserDeptId);
        for (Map<String, Object> it : jdList) {
            String nodeName = it.get("name").toString();

            // 设置审批人员（除开始节点外）
            if (!"开始".equals(nodeName)) {
                String roleKey = it.get("roleKye").toString();
                List<String> userList= new ArrayList<>();
                //设置人员
                if(isEngineeringType){
                    //安全
                    if(roleKey.equals(GC_AQSP)){
                        userList = userService.selectUserLoginNamesByRoleKeyDept2(132L, GC_AQSP);
                    }else if(roleKey.equals(GC_ZZSP)){
                        userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(applyUserDeptId,GC_ZZSP));
                        //侧钻井站（侧钻井站长和华北站的都可以审批）
                        if(sysDept.getDeptId()==116L){
                            //查询华北站审批人
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 119L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),GC_ZZSP));
                            }
                        }else if(sysDept.getDeptId()==124L || sysDept.getDeptId()==125L){
                            //生产井和探井
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 125L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),GC_ZZSP));
                            }
                            SysDept sysDept2 = sysDeptList.stream().filter(item -> item.getDeptId() == 124L).findFirst().orElse(null);
                            if(sysDept2!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept2.getDeptId(),GC_ZZSP));
                            }

                        }else {
                            userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(applyUserDeptId,GC_ZZSP));
                        }


                    }else if(roleKey.equals(GC_ZJSP)){
                        //侧钻井+生产井、探井
                        if(sysDept.getDeptId()==116L || sysDept.getDeptId()==124L || sysDept.getDeptId()==125L){
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 115L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),GC_ZJSP));
                            }
                        }else if(sysDept.getDeptId()==119L){
                            //华北
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 128L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),GC_ZJSPHB));
                            }
                        }else if(sysDept.getDeptId()==126L || sysDept.getDeptId()==122L){
                            //页岩油+难动用
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 128L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),GC_ZJSP_YYY_NDY));
                            }
                        }

                    }else if(roleKey.equals(GC_SXZJ)){
                        if(sysDept.getDeptId()==122L){
                            //难动用
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 121L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),GC_SXZJ));
                            }
                        }else   if(sysDept.getDeptId()==116L){
                            //侧钻井
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 121L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),GC_SXZJ_CZJ));
                            }
                        }else   if(sysDept.getDeptId()==126L){
                            //页岩油
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 121L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),GC_SXZJ_YYY));
                            }
                        }else   if(sysDept.getDeptId()==124L || sysDept.getDeptId()==125L){
                            //生产井、探井
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 121L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),GC_SXZJ_SCJ));
                            }
                        }

                    }else if(roleKey.equals(GC_FGLD)){
                        userList = userService.selectUserLoginNamesByRoleKeyDept2(118L,GC_FGLD);
                    }

                }else {
                    //钻井液
                    if(roleKey.equals(ZJY_AQSP)){
                        userList = userService.selectUserLoginNamesByRoleKeyDept2(132L, ZJY_AQSP);

                    }else if(roleKey.equals(ZJY_ZZSP)){
                        userList = userService.selectUserLoginNamesByRoleKeyDept2(sysDept.getDeptId(),ZJY_ZZSP);
                        if(sysDept.getDeptId()==124L || sysDept.getDeptId()==125L){
                            //生产井和探井
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 125L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),ZJY_ZZSP));
                            }
                            SysDept sysDept2 = sysDeptList.stream().filter(item -> item.getDeptId() == 124L).findFirst().orElse(null);
                            if(sysDept2!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept2.getDeptId(),ZJY_ZZSP));
                            }

                        }
                    }else if(roleKey.equals(ZJY_ZJSP)){
                        if(sysDept.getDeptId()==116L || sysDept.getDeptId()==122L){
                            //侧钻井+难动用
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 127L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),ZJY_ZJSP));
                            }
                        }else if(sysDept.getDeptId()==126L){
                            //页岩油
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 126L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),ZJY_ZJSP));
                            }
                        }else if(sysDept.getDeptId()==124L || sysDept.getDeptId()==125L){
                            //生产井、探井
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 129L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),ZJY_ZJSP));
                            }
                        }else if(sysDept.getDeptId()==119L ){
                            //华北站
                            SysDept sysDept1 = sysDeptList.stream().filter(item -> item.getDeptId() == 119L).findFirst().orElse(null);
                            if(sysDept1!=null){
                                userList.addAll(userService.selectUserLoginNamesByRoleKeyDept2(sysDept1.getDeptId(),ZJY_ZJSP));
                            }
                        }
                    }else if(roleKey.equals(ZJY_SXZJ)  ){
                        userList = userService.selectUserLoginNamesByRoleKeyDept2(118L,ZJY_SXZJ);
                    }else if(roleKey.equals(ZJY_FGLD) ){
                        userList = userService.selectUserLoginNamesByRoleKeyDept2(118L,ZJY_FGLD);
                    }

                }
                if(userList.size()==0){
                    userList.add("成冠琪");
                }
//                userList = userService.selectUserLoginNamesByRoleKeyDept2(secondaryUnit, roleKey);
                it.put("userList", userList.stream().distinct().collect(Collectors.toList()));
                // 设置节点执行状态
                boolean isExecuted = lastHistoryTodoItemsList.stream()
                        .anyMatch(todo -> todo.getNodeName().equals(nodeName) && "1".equals(todo.getIsHandle()));
                it.put("jdxz", isExecuted);
            }else {
                it.put("jdxz", true);
            }
            

        }
    }



    /**
     * 特殊化
     * 自动完成第一个节点(任务书填报)的提交
     */
    private void autoCompleteFirstSubmit(String userId, String key, String processInstanceId, SjDjjc entity) {

        // 根据当前人的ID查询
        List<Task> todoList = taskService
                .createTaskQuery()
                .processDefinitionKey(key)
                .taskAssignee(userId)
                .processInstanceId(processInstanceId)
                .list();

        // 获取task
        if(todoList.size() <= 0) {//没有待办 流程实例异常
            System.out.println("\n流程实例异常！没有生成Task数据。autoCompleteFirstSubmit()方法。\n");
            return;
        }
        Task task = todoList.get(0);
        String taskId = task.getId();

        // 流程的显示标题 取课题名称接后缀任务书审核
        String itemName = "工程方案审核";
        String itemContent = entity.getJh()+"工程方案审核";

        // 获取流程发起人、和所属部门id
        String applyUserId = entity.getApplyUser();
        Long applyUserDeptId = userService.selectUserByLoginName(applyUserId).getDeptId();
        SysDept sysDept = sysDeptMapper.selectDeptById(applyUserDeptId);
        //获取到黄河钻井公司
        Long secondaryUnit = getSecondaryUnit(applyUserDeptId, sysDept.getAncestors());
        //获取安全审批站点人员
        // 设置下一节点处理人
        Map<String, Object> variables = new HashMap<>();
        List<String> assignee = userService.selectUserLoginNamesByRoleKeyDept(132L, GC_AQSP);
//        List<String> assignee = userService.selectUserLoginNamesByRoleKeyAndDeptId(secondaryUnit, GC_AQSP,"安全审批");
        // 下一节点审核节点 处理人为根据角色code取多人 一人处理即可通过
        variables.put(paramName_audit_user, assignee); // 设置下一节点审核人 设置userId

        String comment = "【提交】";


        processService.complete(taskId, processInstanceId, itemName, itemContent, Complete_Module, variables, ServletUtils.getRequest(),comment);
    }




    /**
     * 特殊化
     * 自动完成第一个节点(任务书填报)的提交
     */
    private void autoCompleteFirstSubmitZjy(String userId, String key, String processInstanceId, SjDjjc entity) {

        // 根据当前人的ID查询
        List<Task> todoList = taskService
                .createTaskQuery()
                .processDefinitionKey(key)
                .taskAssignee(userId)
                .processInstanceId(processInstanceId)
                .list();

        // 获取task
        if(todoList.size() <= 0) {//没有待办 流程实例异常
            System.out.println("\n流程实例异常！没有生成Task数据。autoCompleteFirstSubmit()方法。\n");
            return;
        }
        Task task = todoList.get(0);
        String taskId = task.getId();

        // 流程的显示标题 取课题名称接后缀任务书审核
        String itemName = "钻井液方案审核";
        String itemContent = entity.getJh()+"钻井液方案审核";

        // 获取流程发起人、和所属部门id
        String applyUserId = entity.getZjyapplyUser();
        Long applyUserDeptId = userService.selectUserByLoginName(applyUserId).getDeptId();
        SysDept sysDept = sysDeptMapper.selectDeptById(applyUserDeptId);

        Long secondaryUnit = getSecondaryUnit(applyUserDeptId, sysDept.getAncestors());
        // 设置下一节点处理人
        Map<String, Object> variables = new HashMap<>();
        List<String> assignee = userService.selectUserLoginNamesByRoleKeyDept(132L, ZJY_AQSP);
//        List<String> assignee = userService.selectUserLoginNamesByRoleKeyAndDeptId(secondaryUnit, ZJY_AQSP,"安全审批");

        // 下一节点审核节点 处理人为根据角色code取多人 一人处理即可通过
        variables.put(paramName_audit_user, assignee); // 设置下一节点审核人 设置userId

        String comment = "【提交】";


        processService.complete(taskId, processInstanceId, itemName, itemContent, Complete_Module, variables, ServletUtils.getRequest(),comment);
    }


    /**
     * 根据传入的 deptId 和 ancestors 字符串，获取对应的二级单位 ID
     *
     * @param deptId    当前部门ID
     * @param ancestors 祖先部门ID字符串，以逗号分隔，如 "0,100,101" 或 "0,100"
     * @return 二级单位ID：
     *         - 若 ancestors 长度大于2（即包含超过2个ID），则返回第三个ID（索引为2）
     *         - 若 ancestors 长度等于2，则返回 deptId
     *         - 若 ancestors 格式不合法，则返回 null
     */
    public static Long getSecondaryUnit(Long deptId, String ancestors) {
        if (ancestors == null || ancestors.isEmpty()) {
            return null;
        }

        // 1. 分割字符串并转换为数字列表
        List<Long> ancestorList = Arrays.stream(ancestors.split(","))
                .map(String::trim)
                .filter(s -> !s.isEmpty())
                .map(Long::parseLong)
                .collect(Collectors.toList());

        // 2. 根据列表长度判断返回值
        if (ancestorList.size() > 2) {
            // 祖先列表长度大于2，返回第三个元素（索引2）
            return ancestorList.get(2);
        } else if (ancestorList.size() == 2) {
            // 祖先列表长度等于2，返回传入的 deptId
            return deptId;
        } else {
            // 格式不合法，返回null
            return null;
        }
    }
}
