
// This file is auto-generated, don't edit it. Thanks.
package com.zbf.system.config;

import cn.hutool.json.JSONUtil;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponseBody;
import com.aliyun.dingtalkworkflow_1_0.models.*;
import com.aliyun.tea.*;
import com.aliyun.teautil.models.RuntimeOptions;
import com.dingtalk.open.app.api.GenericEventListener;
import com.dingtalk.open.app.api.OpenDingTalkStreamClientBuilder;
import com.dingtalk.open.app.api.message.GenericOpenDingTalkEvent;
import com.dingtalk.open.app.api.security.AuthClientCredential;
import com.dingtalk.open.app.stream.protocol.event.EventAckStatus;
import com.zbf.common.core.domain.entity.SysDictData;
import com.zbf.common.core.domain.entity.SysUser;
import com.zbf.common.core.redis.RedisCache;
import com.zbf.common.utils.StringUtils;
import com.zbf.system.domain.OutBound;
import com.zbf.system.domain.TCkOrders;
import com.zbf.system.domain.vo.D_Instance;
import com.zbf.system.domain.vo.GoodsToD;
import com.zbf.system.domain.vo.GoodsVo;
import com.zbf.system.mapper.OutBoundMapper;
import com.zbf.system.mapper.SysDictDataMapper;
import com.zbf.system.service.ISysUserService;
import com.zbf.system.service.ITCkOrdersService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
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.stereotype.Component;
import shade.com.alibaba.fastjson2.JSONArray;
import shade.com.alibaba.fastjson2.JSONObject;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Component
public class D_Service {
    private static final Logger logger = LoggerFactory.getLogger(D_Service.class);

    @Value("${appkey}")
    private String appkey;
    @Value("${appSecret}")
    private String appSecret;

    @Autowired
    private RedisCache redisCache;
    private  com.aliyun.dingtalkoauth2_1_0.Client oauth2Client;
    private com.aliyun.dingtalkworkflow_1_0.Client workflowClient;

    @Autowired
    private TaskService taskService;
    @Autowired
    private ISysUserService userService;
    @Autowired
    private ITCkOrdersService tCkOrdersService;
    @Resource
    private OutBoundMapper outBoundMapper;
    @Resource
    private SysDictDataMapper sysDictDataMapper;
    private static final String processCode = "PROC-9AF1A940-43F0-4DA7-A8E4-97D0754971B9";
/**
     * 使用 Token 初始化账号Client
     * @return Client
     * @throws Exception*/



    public com.aliyun.dingtalkoauth2_1_0.Client createOauth2Client() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkoauth2_1_0.Client(config);
    }

    public void createWorkFlowClient() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        this.workflowClient = new com.aliyun.dingtalkworkflow_1_0.Client(config);
    }
/*
*
     * 初始化获取token并存入redis
     * @param*/


    // @PostConstruct
    public void initToken()  {
        try {
            oauth2Client = createOauth2Client();
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("createClient 异常：{}",e.getMessage());
            return;
        }

        com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest getAccessTokenRequest = new com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest()
                .setAppKey(appkey)
                .setAppSecret(appSecret);
        try {
            GetAccessTokenResponse accessToken = oauth2Client.getAccessToken(getAccessTokenRequest);
            if(accessToken.statusCode == 200){
                GetAccessTokenResponseBody body = accessToken.getBody();
                String accessToken1 = body.getAccessToken();
                System.out.println(accessToken1);
                logger.info("获取token：{}",accessToken1);
                redisCache.setCacheObject(CommonConfig.dd_key,accessToken1,7200, TimeUnit.SECONDS);
            }
            //这个接口需要2小时调用一次，确保缓存中的taken一直为有效数据
            //可以通过redis缓存，过期自动删除，进行调用时候，获取不到则重新访问接口

        } catch (TeaException err) {
            err.printStackTrace();
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                logger.error("获取token异常：{},{}",err.code,err.getMessage());
            }

        } catch (Exception _err) {

            _err.printStackTrace();
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                logger.error("获取token异常：{},{}",err.code,err.getMessage());
            }

        }

        //监听事件回调启动
        try {
            startCallBack();
            logger.info("创建钉钉 callback 成功");
        } catch (Exception e) {
            logger.info("监听回调失败 异常：{}",e.getMessage());
            e.printStackTrace();
        }

        try {
            createWorkFlowClient();
            logger.info("创建钉钉 createWorkFlowClient 成功");
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("createWorkFlowClient 异常：{}",e.getMessage());
            e.printStackTrace();
        }

    }

/*
*
     * 获取token
     * @return
*/


    public String getToken(){
        if(!redisCache.hasKey(CommonConfig.dd_key)){
            initToken();
        }
        return redisCache.getCacheObject(CommonConfig.dd_key);
    }

    public String createInstance(OutBound outBound){
        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceHeaders startProcessInstanceHeaders = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceHeaders();
        startProcessInstanceHeaders.xAcsDingtalkAccessToken = getToken();
        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues formComponentValues0 = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues()
                .setName("领料单号")
                .setValue(outBound.getDeliveryId());
        SysUser user = userService.selectUserByUserName(outBound.getApplyer());
        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues formComponentValues1 = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues()
                .setName("申请人")
                .setValue(user.getNickName());
        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues formComponentValues2 = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues()
                .setName("申请时间")
                .setValue(outBound.getApplyTime());
        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues formComponentValues3 = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        formComponentValues3.setName("出库仓库");
        if(StringUtils.isNotBlank(outBound.getStorageId())){
            formComponentValues3.setValue(outBound.getStorageId());
        }else{
            formComponentValues3.setValue("空");
        }

        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues formComponentValues4 = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues();
        formComponentValues4.setName("出库类型");
        if(StringUtils.isNotBlank(outBound.getCkType())){
            List<SysDictData> outbound_type = sysDictDataMapper.selectDictDataByType("outbound_type");
            List<SysDictData> collect = outbound_type.stream()
                    .filter(obj -> obj.getDictValue().contains(outBound.getCkType()))
                    .collect(Collectors.toList());
            formComponentValues4.setValue(collect.size() == 0 ? "空" : collect.get(0).getDictLabel());
        }else{
            formComponentValues4.setValue("空");
        }

        //明细
        List<GoodsVo> list = JSONUtil.toList(outBound.getItemList(), GoodsVo.class);
        //组装Goods
        List<List<GoodsToD>> goodsToAllList = new ArrayList<>();

        for(GoodsVo vo : list){
            List<GoodsToD> goodsToDS = new ArrayList<>();
           //物料名称
            GoodsToD goodsName = new GoodsToD();
            goodsName.setName("物料名称");
            if(StringUtils.isNotBlank(vo.getGoodsName())){
                goodsName.setValue(vo.getGoodsName());
            }else {
                goodsName.setValue("无");
            }
            goodsToDS.add(goodsName);

            //物料编号
            GoodsToD goodId = new GoodsToD();
            goodId.setName("物料编号");
            goodId.setValue(vo.getGoodsId());
            goodsToDS.add(goodId);

            //规格型号
            GoodsToD specification = new GoodsToD();
            specification.setName("规格型号");
            if(StringUtils.isNotBlank(vo.getSpecification())){
                specification.setValue(vo.getSpecification());
            }else{
                specification.setValue("无");
            }

            goodsToDS.add(specification);

            //物料描述

            GoodsToD recoil = new GoodsToD();
            recoil.setName("物料描述");
            if(StringUtils.isBlank(vo.getRecoil())) {
                recoil.setValue("空");
            }else{
                recoil.setValue(vo.getRecoil());
            }
            goodsToDS.add(recoil);
            //价格
            GoodsToD price = new GoodsToD();
            price.setName("价格");
            if(vo.getPrice() != null){
                price.setValue(String.valueOf(vo.getPrice()));
            }else{
                price.setValue("无");
            }

            goodsToDS.add(price);
            //单位
            GoodsToD unit =new GoodsToD();
            unit.setName("单位");
            if(StringUtils.isNotBlank(vo.getUnit())){
                unit.setValue(vo.getUnit());
            }else{
                unit.setValue("无");
            }

            goodsToDS.add(unit);

            //库存数量
            GoodsToD total =new GoodsToD();
            total.setName("库存数量");
            total.setValue(String.valueOf(vo.getTotal()));
            goodsToDS.add(total);
            //需求数量
            GoodsToD shelvesNum =new GoodsToD();
            shelvesNum.setName("需求数量");
            if(vo.getShelvesNum() != null) {
                shelvesNum.setValue(String.valueOf(vo.getShelvesNum()));
            }else{
                shelvesNum.setValue("无");
            }
            goodsToDS.add(shelvesNum);
            //物资流向
            GoodsToD supplier =new GoodsToD();
            supplier.setName("物资流向");
            if(StringUtils.isNotBlank(vo.getGoodsTo())){
                supplier.setValue(vo.getGoodsTo());
            }else{
                supplier.setValue("无");
            }
            goodsToDS.add(supplier);

            //库级
            GoodsToD levelType =new GoodsToD();
            levelType.setName("库级");
            if(StringUtils.isNotBlank(vo.getLevelType())) {
                if("1".equals(vo.getLevelType())){
                    levelType.setValue("一级库");
                }else{
                    levelType.setValue("起始库");
                }

            }else{
                levelType.setValue("无");
            }

            goodsToDS.add(levelType);
            //备注

            GoodsToD remark = new GoodsToD();
            remark.setName("备注");

            if(StringUtils.isNotBlank(vo.getRemark())){
                remark.setValue(vo.getRemark());
            }else{
                remark.setValue("无");
            }
            goodsToDS.add(remark);

            goodsToAllList.add(goodsToDS);

        }

        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues formComponentValuesArrays = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestFormComponentValues()
                .setName("领料明细")
                .setComponentType("TableField")
                .setValue(JSONUtil.toJsonStr(goodsToAllList));
        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestApprovers approvers0 = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestApprovers()
                .setActionType("NONE") //单人审批1
                .setUserIds(java.util.Arrays.asList(
                       outBound.getDeptmanager()
                ));
        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestApprovers approvers1 = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestApprovers()
                .setActionType("NONE") //单人审批2
                .setUserIds(java.util.Arrays.asList(
                        outBound.getManagerName()
                ));
        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestApprovers approvers2 = null;
       if(StringUtils.isNotBlank(outBound.getCrossDeptManager())) {
           approvers2 = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest.StartProcessInstanceRequestApprovers()
                   .setActionType("NONE") //单人审批2
                   .setUserIds(java.util.Arrays.asList(
                           outBound.getCrossDeptManager()
                   ));
       }
        List<StartProcessInstanceRequest.StartProcessInstanceRequestApprovers> startProcessInstanceRequestApprovers =null;
       if(approvers2 != null){
           startProcessInstanceRequestApprovers = Arrays.asList(
                   approvers0,
                   approvers1,
                   approvers2
           );
       }else{
           startProcessInstanceRequestApprovers = Arrays.asList(
                   approvers0,
                   approvers1
           );
       }

        com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest startProcessInstanceRequest = new com.aliyun.dingtalkworkflow_1_0.models.StartProcessInstanceRequest()
                .setApprovers(startProcessInstanceRequestApprovers)

//                .setCcList(java.util.Arrays.asList(
//                        "mayu"
//                ))
                .setCcPosition("FINISH")
                .setOriginatorUserId(outBound.getApplyer())
                .setProcessCode(processCode)
                .setFormComponentValues(java.util.Arrays.asList(
                        formComponentValues0,
                        formComponentValues1,
                        formComponentValues2,
                        formComponentValues3,
                        formComponentValues4,
                        formComponentValuesArrays
                ));
        StartProcessInstanceResponse response = null;
        try {
            if(workflowClient == null){
                logger.error("获取workflowClient为空异常！");
                return null;
            }
            response =  workflowClient.startProcessInstanceWithOptions(startProcessInstanceRequest, startProcessInstanceHeaders, new com.aliyun.teautil.models.RuntimeOptions());
            if(response.getStatusCode() == 200){
                return response.getBody().instanceId;
            }else{
                logger.error("返回错误码：{}",response.getStatusCode());
                return null;
            }
        } catch (TeaException err) {
            err.printStackTrace();
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                logger.error("创建实例 异常：{},{}",err.code,err.getMessage());
            }

        } catch (Exception _err) {
            _err.printStackTrace();
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                logger.error("创建实例 异常：{},{}",err.code,err.getMessage());
            }

        }


        return null;
    }

    public void startCallBack() throws Exception {
        OpenDingTalkStreamClientBuilder
                .custom()
                .credential(new AuthClientCredential(appkey, appSecret))
                //注册事件监听
                .registerAllEventListener(new GenericEventListener() {
                    public EventAckStatus onEvent(GenericOpenDingTalkEvent event) {
                        try {

                            //事件唯一Id
                            String eventId = event.getEventId();

                            //事件类型
                            String eventType = event.getEventType();
                            //事件产生时间
                            Long bornTime = event.getEventBornTime();
                            //获取事件体
                            JSONObject bizData = event.getData();
                            logger.info("接收到钉钉callbak事件：{}",JSONObject.toJSONString(bizData));
                            //处理事件 只处理变更事件
                            if(eventType.equalsIgnoreCase("bpms_task_change")) {
                                //获取审批模板
                                String processCodeResult = bizData.getString("processCode");
                                if(processCode.equals(processCodeResult)){
                                    logger.info("eventType：{}",eventType);
                                    logger.warn("处理该审批模板消息====》》》》");
                                    new Thread(new Runnable() {
                                        @Override
                                        public void run() {
                                            process(bizData);
                                        }
                                    }).start();
                                }

                            }
                            logger.info("接收成功：======》》》");
                            //消费成功
                            return EventAckStatus.SUCCESS;
                        } catch (Exception e) {
                            logger.error("接收失败：{}",e.getMessage());
                            //消费失败
                            return EventAckStatus.LATER;
                        }
                    }
                })
                .build().start();
    }

    private void process(JSONObject bizData) {
        //根据实例ID获取到审核信息，并同步审核系统flwoable审批
        //获取审批模板
        String processCodeResult = bizData.getString("processCode");
        if(!processCode.equals(processCodeResult)){
            logger.warn("忽略返回的消息，非wms出库申请！");
            return;
        }
        //实例ID
        String processInstanceId1 = bizData.getString("processInstanceId");
        String userId = bizData.getString("staffId");

        //根据实例ID获取任务ID
        OutBound outBound = new OutBound();
        outBound.setInstanceId(processInstanceId1);
        List<OutBound> outBounds = outBoundMapper.selectOutBoundList(outBound);
        if (outBounds.size() == 0) {
            throw new RuntimeException("根据实例ID没有获取到系统中的后台审核信息，调用失败");
        }
        OutBound outBound1 = outBounds.get(0);


        //状态 有FINISHED
        String type = bizData.getString("type");
        if("finish".equals(type)){
            logger.info("处理消息===>>>>，{}",type);
            if(userId.equals(outBound1.getFinishName())){
                logger.warn("忽略消息，本地已审核");
                return;
            }
        }else if("start".equals(type)){
//            // 根据流程实例ID和审核人查询任务
//            List<Task> tasks = taskService.createTaskQuery()
//                    .processInstanceId(outBound1.getfInstanceId()) // 指定流程实例ID
//                    .taskAssignee(userId)              // 指定审核人
//                    .list();
//
//            if (tasks.isEmpty()) {
////                logger.error("获取运行中待审核任务为空！");
////                throw new RuntimeException("获取运行中待审核任务为空");
//            } else {
//                Task task = tasks.get(0);
//                outBound1.setTaskId(task.getId());
//                outBound1.setUpdateTime(new Date());
//                outBoundMapper.updateOutBound(outBound1);
//                logger.info("更新完成，任务号为：{}",task.getId());
//            }
            return ;
        }

        String result = bizData.getString("result");
        logger.info("获取到回调数据的result:{}", result);
        if(!"agree".equals(result) && !"refuse".equals(result)){
            logger.error("消息结果不是想要的结果，无需处理：{}",result);
            return;
        }


        String remark = bizData.getString("remark");

        if(StringUtils.isBlank(outBound1.getTaskId())){
            logger.error("没有获取到系统审批任务ID，请联系管理员确认！");
            return;
        }

        taskService.setAssignee(outBound1.getTaskId(), userId);

        //获取领料单号
        String deliveryId = outBound1.getDeliveryId();
        //存储审核结果
        Map<String, Object> variables = new HashMap<>();
        variables.put("deliveryId", deliveryId);
        if ("agree".equals(result)) {
            variables.put(userId, "true");
            variables.put("result", "true");
            variables.put("approve","true");
            variables.put("agree","true");
            variables.put("crossAgree","true");
        } else {
            variables.put(userId, "false");
            variables.put("result", "false");
            variables.put("approve","false");
            variables.put("agree","false");
            variables.put("crossAgree","false");
        }
        if(StringUtils.isNotBlank(remark)){
            variables.put("comment", remark);
        }
        SysUser user = userService.selectUserByUserName(userId);
        // 查出流程实例id
        String processInstanceId = taskService.createTaskQuery().taskId(outBound1.getTaskId()).singleResult().getProcessInstanceId();
        if (variables == null) {
            taskService.complete(outBound1.getTaskId());
        } else {
            // 添加审批意见
            String comment = StringUtils.EMPTY;
            if (variables.get("comment") != null) {
                taskService.addComment(outBound1.getTaskId(), processInstanceId, (String) variables.get("comment"));
                comment = (String) variables.get("comment");
                variables.remove("comment");
            }

            TCkOrders tCkOrders1 = tCkOrdersService.selectTCkOrdersByDeliveryId(deliveryId);
            TCkOrders tCkOrders = new TCkOrders();
            tCkOrders.setId(tCkOrders1.getId());
            String auditMan = tCkOrders1.getAuditMan();
            if (StringUtils.isNotBlank(auditMan)) {
                tCkOrders.setAuditMan(auditMan + "->" + user.getNickName());
            } else {
                tCkOrders.setAuditMan(user.getNickName());
            }
            tCkOrders.setAuditDate(new Date());
            //更新出库明细
            if ("false".equals(variables.get("result"))) {
                if (StringUtils.isNotBlank(comment)) {
                    if (StringUtils.isNotBlank(tCkOrders1.getRejectReason())) {
                        tCkOrders.setRejectReason(tCkOrders1.getRejectReason() + "|" + user.getNickName() + ":拒绝,原因:" + comment);
                    } else {
                        tCkOrders.setRejectReason(user.getNickName() + ":拒绝,原因:" + comment);
                    }
                } else {
                    if (StringUtils.isNotBlank(tCkOrders1.getRejectReason())) {
                        tCkOrders.setRejectReason(tCkOrders1.getRejectReason() + "|" + user.getNickName() + ":拒绝");
                    } else
                        tCkOrders.setRejectReason(user.getNickName() + ":拒绝");
                }
                tCkOrders.setIsAudit("3"); //拒绝
            } else {
                if (StringUtils.isNotBlank(comment)) {
                    if (StringUtils.isNotBlank(tCkOrders1.getRejectReason())) {
                        tCkOrders.setRejectReason(tCkOrders1.getRejectReason() + "|" + user.getNickName() + ":同意,意见:" + comment);
                    } else {
                        tCkOrders.setRejectReason(user.getNickName() + ":同意,意见:" + comment);
                    }
                } else {
                    if (StringUtils.isNotBlank(tCkOrders1.getRejectReason())) {
                        tCkOrders.setRejectReason(tCkOrders1.getRejectReason() + "|" + user.getNickName() + ":同意");
                    } else
                        tCkOrders.setRejectReason(user.getNickName() + ":同意");

                }
            }

            tCkOrdersService.updateTCkOrders(tCkOrders);

            taskService.complete(outBound1.getTaskId(), variables);

        }
        //更新下一个任务id
//        查询下一个审核人
        String auditName = StringUtils.EMPTY;
        if(userId.equals(outBound1.getDeptmanager())){
            auditName = outBound1.getManagerName();
        }else if(userId.equals(outBound1.getManagerName())){
            auditName = outBound1.getCrossDeptManager();
        }
        if(StringUtils.isBlank(auditName)){
            logger.info("处理完成，无需更新任务ID");
            return;
        }
        List<Task> nextTasks = taskService.createTaskQuery()
                .processInstanceId(processInstanceId)  // 根据流程实例 ID 查询
                .taskAssignee(auditName) //指定审核人
                .orderByTaskCreateTime().desc()  // 按任务创建时间排序
                .list();

        if (!nextTasks.isEmpty()) {
            Task nextTask = nextTasks.get(0);  // 获取下一个任务
            String nextTaskId = nextTask.getId();
           logger.info("下一个任务的 ID: {}" ,nextTaskId);
            OutBound outBound22 = new OutBound();
            outBound22.setfInstanceId(processInstanceId);
            List<OutBound> outBoundsss = outBoundMapper.selectOutBoundList(outBound22);
            if(!outBoundsss.isEmpty()){
                OutBound outBound33 = outBoundsss.get(0);
                OutBound outBound44 = new OutBound();
                outBound44.setId(outBound33.getId());
                outBound44.setTaskId(nextTaskId);
                outBound44.setUpdateTime(new Date());
                outBound44.setFinishName(userId);
                outBoundMapper.updateOutBound(outBound44);
            }
        }

    }

    //同意/拒绝任务

/**
     *
     * @param instanceId 钉钉实例ID
     * @param userId 审核人
     * @param result agree reject*/


    public void auditStatusToDd(String instanceId,String userId,String result){
        //1. 查询实例详情
        logger.info("查询实例获取实例信息：{}",userId);
       D_Instance dInstance = queryInstanceDetails(instanceId,userId);
       logger.info("获取实例获取实例信息：{}",dInstance);
       //2. 同步钉钉状态;
        if(dInstance != null) {
            sendToDd(dInstance, instanceId, result);
        }
    }

    private void sendToDd(D_Instance dInstance, String instanceId, String result) {
        logger.info("发起同步：=====》》》》{}",instanceId);
        com.aliyun.dingtalkworkflow_1_0.models.ExecuteProcessInstanceHeaders executeProcessInstanceHeaders = new com.aliyun.dingtalkworkflow_1_0.models.ExecuteProcessInstanceHeaders();
        executeProcessInstanceHeaders.xAcsDingtalkAccessToken = getToken();
        com.aliyun.dingtalkworkflow_1_0.models.ExecuteProcessInstanceRequest executeProcessInstanceRequest = new com.aliyun.dingtalkworkflow_1_0.models.ExecuteProcessInstanceRequest()
                .setResult(result)
                .setProcessInstanceId(instanceId)
                .setRemark("同步钉钉")
                .setTaskId(dInstance.getTaskId())
                .setActionerUserId(dInstance.getUserId());
        try {
            ExecuteProcessInstanceResponse response = workflowClient.executeProcessInstanceWithOptions(executeProcessInstanceRequest, executeProcessInstanceHeaders, new com.aliyun.teautil.models.RuntimeOptions());
            ExecuteProcessInstanceResponseBody body = response.getBody();
            if(body != null && body.success){
                logger.info("发送同步成功");
            }else{
                logger.info("发送同步失败");
            }
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                logger.error("同步钉钉 异常：{},{}",err.code,err.getMessage());
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                logger.error("同步钉钉 异常：{},{}",err.code,err.getMessage());
            }

        }

    }

    private D_Instance queryInstanceDetails(String instanceId, String auditId) {
        logger.info("auditId:{}",auditId);
        com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceHeaders getProcessInstanceHeaders = new com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceHeaders();
        getProcessInstanceHeaders.xAcsDingtalkAccessToken = getToken();
        com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceRequest getProcessInstanceRequest = new com.aliyun.dingtalkworkflow_1_0.models.GetProcessInstanceRequest()
                .setProcessInstanceId(instanceId);
        try {
            GetProcessInstanceResponse processInstanceWithOptions = workflowClient.getProcessInstanceWithOptions(getProcessInstanceRequest, getProcessInstanceHeaders, new RuntimeOptions());
            GetProcessInstanceResponseBody body = processInstanceWithOptions.getBody();
            GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResult result = body.result;

            List<GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultOperationRecords> operationRecords = result.getOperationRecords();
            GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultOperationRecords getProcessInstanceResponseBodyResultOperationRecords = operationRecords.get(0);
            String userId = getProcessInstanceResponseBodyResultOperationRecords.getUserId();
            logger.info("查询用户钉钉信息：{}",userId);
            D_Instance dInstance = new D_Instance();

            List<GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultTasks> tasks = result.getTasks();
            if(!"RUNNING".equals(result.getStatus())){
                logger.error("钉钉该实例已审核完成，不需要同步，请确认两边是否状态一致");
                throw new RuntimeException("钉钉该实例以审核完成，不需要同步，请确认两边是否状态一致");
            }
            for (int i = 0; i < tasks.size(); i++) {
                GetProcessInstanceResponseBody.GetProcessInstanceResponseBodyResultTasks getProcessInstanceResponseBodyResultTasks = tasks.get(i);
                String userId1 = getProcessInstanceResponseBodyResultTasks.getUserId();
                dInstance.setUserId(userId1);
                logger.info("userId1:{}",userId1);
                if(auditId.equals(userId1)){
                    String status = getProcessInstanceResponseBodyResultTasks.getStatus();
                    String result1 = getProcessInstanceResponseBodyResultTasks.getResult();
                    logger.info("status:{}",status);
                    logger.info("result1:{}",userId1);
                    if(("NEW".equals(status) || "RUNNING".equals(status) || "PAUSED".equals(status)) &&
                            (!"AGREE".equals(result1) && !"REFUSE".equals(result1))){
                        Long taskId = getProcessInstanceResponseBodyResultTasks.getTaskId();
                        dInstance.setTaskId(taskId);
                        return dInstance;
                    }
                }
            }
        } catch (TeaException err) {
            err.printStackTrace();
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                logger.error("查询实例 异常：{},{}",err.code,err.getMessage());
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                logger.error("查询实例 异常：{},{}",err.code,err.getMessage());
            }

        }
        return null;
    }
    public void cancelAudit(String instanceId){
        com.aliyun.dingtalkworkflow_1_0.models.TerminateProcessInstanceHeaders terminateProcessInstanceHeaders = new com.aliyun.dingtalkworkflow_1_0.models.TerminateProcessInstanceHeaders();
        terminateProcessInstanceHeaders.xAcsDingtalkAccessToken = getToken();
        com.aliyun.dingtalkworkflow_1_0.models.TerminateProcessInstanceRequest terminateProcessInstanceRequest = new com.aliyun.dingtalkworkflow_1_0.models.TerminateProcessInstanceRequest()
                .setProcessInstanceId(instanceId);
        try {
            workflowClient.terminateProcessInstanceWithOptions(terminateProcessInstanceRequest, terminateProcessInstanceHeaders, new com.aliyun.teautil.models.RuntimeOptions());
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                logger.error("撤销实例 异常：{},{}",err.code,err.getMessage());
            }

        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
                logger.error("撤销实例 异常：{},{}",err.code,err.getMessage());
            }

        }
    }
}

