package com.yunzhupaas.engine.controller;

import com.google.common.collect.ImmutableList;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import com.yunzhupaas.base.ActionResult;
import com.yunzhupaas.base.UserInfo;
import com.yunzhupaas.base.vo.PageListVO;
import com.yunzhupaas.base.vo.PaginationVO;
import com.yunzhupaas.constant.MsgCode;
import com.yunzhupaas.constant.PermissionConst;
import com.yunzhupaas.engine.entity.*;
import com.yunzhupaas.engine.enums.FlowNodeEnum;
import com.yunzhupaas.engine.enums.FlowRecordEnum;
import com.yunzhupaas.engine.enums.FlowTaskStatusEnum;
import com.yunzhupaas.engine.model.flowbefore.*;
import com.yunzhupaas.engine.model.flowcandidate.FlowCandidateUserModel;
import com.yunzhupaas.engine.model.flowcandidate.FlowCandidateVO;
import com.yunzhupaas.engine.model.flowcandidate.FlowRejectVO;
import com.yunzhupaas.engine.model.flowengine.FlowModel;
import com.yunzhupaas.engine.model.flowengine.shuntjson.childnode.ChildNode;
import com.yunzhupaas.engine.model.flowengine.shuntjson.nodejson.ChildNodeList;
import com.yunzhupaas.engine.model.flowengine.shuntjson.nodejson.ConditionList;
import com.yunzhupaas.engine.model.flowtask.FlowTaskListModel;
import com.yunzhupaas.engine.model.flowtask.PaginationFlowTask;
import com.yunzhupaas.engine.model.flowtask.TaskNodeModel;
import com.yunzhupaas.engine.model.flowtasknode.TaskNodeListModel;
import com.yunzhupaas.engine.service.*;
import com.yunzhupaas.engine.util.FlowJsonUtil;
import com.yunzhupaas.engine.util.FlowNature;
import com.yunzhupaas.engine.util.FlowTaskUtil;
import com.yunzhupaas.exception.WorkFlowException;
import com.yunzhupaas.permission.entity.UserEntity;
import com.yunzhupaas.permission.entity.UserRelationEntity;
import com.yunzhupaas.permission.model.user.UserIdListVo;
import com.yunzhupaas.permission.service.UserService;
import com.yunzhupaas.util.JsonUtil;
import com.yunzhupaas.util.ServiceAllUtil;
import com.yunzhupaas.util.StringUtil;
import com.yunzhupaas.util.UserProvider;
import com.yunzhupaas.util.visiual.YunzhupaasKeyConsts;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

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

/**
 * 待我审核
 *
 * @author 云筑产品开发平台组
 * @version V3.1.0
 * @copyright 深圳市乐程软件有限公司
 * @date 2023/09/27
 */
@Tag(name = "待我审核", description = "FlowBefore")
@RestController
@RequestMapping("/api/workflow1/Engine/FlowBefore")
public class FlowBeforeController {


    @Autowired
    private ServiceAllUtil serviceUtil;
    
    @Autowired
    private FlowTaskUtil flowTaskUtil;
    @Autowired
    private FlowTaskService flowTaskService;
    @Autowired
    private FlowTemplateJsonService flowTemplateJsonService;
    @Autowired
    private FlowTaskOperatorService flowTaskOperatorService;
    @Autowired
    private FlowTaskOperatorRecordService flowTaskOperatorRecordService;
    @Autowired
    private FlowTaskNodeService flowTaskNodeService;
    @Autowired
    private FlowTaskNewService flowTaskNewService;
    @Autowired
    private FlowOperatorUserService flowOperatorUserService;
    @Autowired
    private FlowTaskCirculateService flowTaskCirculateService;
    @Autowired
    private UserService userService;

    /**
     * 获取待我审核列表
     *
     * @param category           分类
     * @param paginationFlowTask 分页模型
     * @return
     */
    @Operation(summary = "获取待我审核列表(有带分页)，1-待办事宜，2-已办事宜，3-抄送事宜,4-批量审批")
    @GetMapping("/List/{category}")
    @Parameters({
            @Parameter(name = "category", description = "分类", required = true),
    })
    public ActionResult<PageListVO<FlowBeforeListVO>> list(@PathVariable("category") String category, PaginationFlowTask paginationFlowTask) {
        List<FlowTaskListModel> data = new ArrayList<>();
        paginationFlowTask.setDelegateType(true);
        if (FlowNature.WAIT.equals(category)) {
            data.addAll(flowTaskService.getWaitList(paginationFlowTask));
        } else if (FlowNature.TRIAL.equals(category)) {
            data.addAll(flowTaskService.getTrialList(paginationFlowTask));
        } else if (FlowNature.CIRCULATE.equals(category)) {
            data.addAll(flowTaskService.getCirculateList(paginationFlowTask));
        } else if (FlowNature.BATCH.equals(category)) {
            paginationFlowTask.setIsBatch(1);
            data.addAll(flowTaskService.getWaitList(paginationFlowTask));
        }
        List<FlowBeforeListVO> listVO = new LinkedList<>();
        List<UserEntity> userList = serviceUtil.getUserName(data.stream().map(FlowTaskListModel::getCreatorUserId).collect(Collectors.toList()));
        boolean isBatch = FlowNature.BATCH.equals(category);
        List<FlowTaskNodeEntity> taskNodeList = new ArrayList<>();
        List<String> taskNodeIdList = data.stream().map(FlowTaskListModel::getThisStepId).collect(Collectors.toList());
        if (isBatch) {
            taskNodeList.addAll(flowTaskNodeService.getList(taskNodeIdList, FlowTaskNodeEntity::getId, FlowTaskNodeEntity::getNodePropertyJson));
        }
        for (FlowTaskListModel task : data) {
            FlowBeforeListVO vo = JsonUtil.getJsonToBean(task, FlowBeforeListVO.class);
            //用户名称赋值
            UserEntity user = userList.stream().filter(t -> t.getId().equals(vo.getCreatorUserId())).findFirst().orElse(null);
            vo.setUserName(user != null ? user.getRealName() + "/" + user.getAccount() : "");
            FlowTaskNodeEntity taskNode = taskNodeList.stream().filter(t -> t.getId().equals(task.getThisStepId())).findFirst().orElse(null);
            if (isBatch && taskNode != null) {
                ChildNodeList childNode = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
                vo.setApproversProperties(JsonUtil.getObjectToString(childNode.getProperties()));
            }
            vo.setFlowVersion(StringUtil.isEmpty(vo.getFlowVersion()) ? "" : vo.getFlowVersion());
            listVO.add(vo);
        }
        PaginationVO paginationVO = JsonUtil.getJsonToBean(paginationFlowTask, PaginationVO.class);
        return ActionResult.page(listVO, paginationVO);
    }

    /**
     * 获取待我审批信息
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "获取待我审批信息")
    @GetMapping("/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
    })
    public ActionResult<FlowBeforeInfoVO> info(@PathVariable("id") String id, FlowModel flowModel) throws WorkFlowException {
        flowModel.setId(id);
        FlowBeforeInfoVO vo = flowTaskNewService.getBeforeInfo(flowModel);
        //处理当前默认值
        if (vo != null && vo.getFlowFormInfo() != null && StringUtil.isNotEmpty(vo.getFlowFormInfo().getPropertyJson()) && vo.getFlowFormInfo().getFormType() == 2) {
            UserInfo userInfo = UserProvider.getUser();
            Map<String, Integer> havaDefaultCurrentValue = new HashMap<>();
            vo.getFlowFormInfo().setPropertyJson(setDefaultCurrentValue(vo.getFlowFormInfo().getPropertyJson(), havaDefaultCurrentValue, userInfo));
        }
        return ActionResult.success(vo);
    }

    /**
     * 待我审核审核
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "待我审核审核")
    @PostMapping("/Audit/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult audit(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws WorkFlowException {
        flowModel.setId(id);
        flowTaskNewService.audit(flowModel);
        return ActionResult.success(MsgCode.WF001.get());
    }

    /**
     * 保存草稿
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "保存草稿")
    @PostMapping("/SaveAudit/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult saveAudit(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws WorkFlowException {
        FlowTaskOperatorEntity flowTaskOperatorEntity = flowTaskOperatorService.getInfo(id);
        if (flowTaskOperatorEntity != null) {
            Map<String, Object> formDataAll = flowModel.getFormData();
            flowTaskOperatorEntity.setDraftData(JsonUtil.getObjectToString(formDataAll));
            flowTaskOperatorService.update(flowTaskOperatorEntity);
            return ActionResult.success(MsgCode.SU002.get());
        }
        return ActionResult.fail(MsgCode.FA001.get());
    }

    /**
     * 审批汇总
     *
     * @param id       主键
     * @param category 类型
     * @param type     类型
     * @return
     */
    @Operation(summary = "审批汇总")
    @GetMapping("/RecordList/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
    })
    public ActionResult<List<FlowSummary>> recordList(@PathVariable("id") String id, String category, String type) {
        List<FlowSummary> flowSummaries = flowTaskNewService.recordList(id, category, type);
        return ActionResult.success(flowSummaries);
    }

    /**
     * 待我审核驳回
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "待我审核驳回")
    @PostMapping("/Reject/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult reject(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws WorkFlowException {
        flowModel.setId(id);
        flowTaskNewService.reject(flowModel);
        return ActionResult.success(MsgCode.WF002.get());
    }

    /**
     * 待我审核转办
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "待我审核转办")
    @PostMapping("/Transfer/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult transfer(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws WorkFlowException {
        flowModel.setId(id);
        flowTaskNewService.transfer(flowModel);
        return ActionResult.success(MsgCode.WF003.get());
    }

    /**
     * 待我审核转办
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "待我审核加签")
    @PostMapping("/freeApprover/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult freeApprover(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws WorkFlowException {
        flowModel.setId(id);
        flowTaskNewService.audit(flowModel);
        return ActionResult.success(MsgCode.WF004.get());
    }

    /**
     * 待我审核撤回审核
     * 注意：在撤销流程时要保证你的下一节点没有处理这条记录；如已处理则无法撤销流程。
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "待我审核撤回审核")
    @PostMapping("/Recall/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult recall(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws WorkFlowException {
        FlowTaskOperatorRecordEntity operatorRecord = flowTaskOperatorRecordService.getInfo(id);
        FlowTaskNodeEntity taskNode = flowTaskNodeService.getInfo(operatorRecord.getTaskNodeId(), FlowTaskNodeEntity::getId);
        //拒绝不撤回
        if (FlowNature.ProcessCompletion.equals(operatorRecord.getHandleStatus())) {
            throw new WorkFlowException(MsgCode.WF005.get());
        }
        if (taskNode == null) {
            return ActionResult.fail(MsgCode.WF006.get());
        }
        if (FlowRecordEnum.swerve.getCode().equals(operatorRecord.getHandleStatus())) {
            return ActionResult.fail(MsgCode.WF007.get());
        }
        if (FlowRecordEnum.revoke.getCode().equals(operatorRecord.getStatus())) {
            return ActionResult.fail(MsgCode.WF006.get());
        }
        if (taskNode != null && !FlowRecordEnum.revoke.getCode().equals(operatorRecord.getStatus())) {
            flowModel.setUserInfo(UserProvider.getUser());
            flowTaskNewService.recall(id, operatorRecord, flowModel);
        }
        return ActionResult.success(MsgCode.WF008.get());
    }

    /**
     * 待我审核终止审核
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "待我审核终止审核")
    @PostMapping("/Cancel/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult cancel(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws WorkFlowException {
        FlowTaskEntity entity = flowTaskService.getInfo(id, FlowTaskEntity::getFlowType);
        if (entity != null) {
            if (Objects.equals(entity.getFlowType(), 1)) {
                return ActionResult.fail(MsgCode.WF009.get());
            }
            flowModel.setUserInfo(UserProvider.getUser());
            List<String> idList = ImmutableList.of(id);
            flowTaskNewService.cancel(idList, flowModel);
            return ActionResult.success(MsgCode.SU005.get());
        }
        return ActionResult.fail(MsgCode.FA009.get());
    }

    /**
     * 指派人
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "指派人")
    @PostMapping("/Assign/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult assign(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws WorkFlowException {
        flowModel.setUserInfo(UserProvider.getUser());
        flowTaskNewService.assign(id, flowModel);
        return ActionResult.success(MsgCode.WF010.get());
    }

    /**
     * 获取候选人
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "获取候选人节点")
    @PostMapping("/Candidates/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult<FlowCandidateVO> candidates(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws WorkFlowException {
        flowModel.setUserInfo(UserProvider.getUser());
        FlowCandidateVO candidate = flowTaskNewService.candidates(id, flowModel, false);
        return ActionResult.success(candidate);
    }

    /**
     * 获取候选人
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "获取候选人")
    @PostMapping("/CandidateUser/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult<PageListVO<FlowCandidateUserModel>> candidateUser(@PathVariable("id") String id, @RequestBody FlowModel flowModel) throws WorkFlowException {
        flowModel.setUserInfo(UserProvider.getUser());
        List<FlowCandidateUserModel> candidate = flowTaskNewService.candidateUser(id, flowModel);
        PaginationVO paginationVO = JsonUtil.getJsonToBean(flowModel, PaginationVO.class);
        return ActionResult.page(candidate, paginationVO);
    }

    /**
     * 批量审批引擎
     *
     * @return
     */
    @Operation(summary = "批量审批引擎")
    @GetMapping("/BatchFlowSelector")
    public ActionResult<List<FlowBatchModel>> batchFlowSelector() {
        List<FlowBatchModel> batchFlowList = flowTaskService.batchFlowSelector();
        return ActionResult.success(batchFlowList);
    }

    /**
     * 拒绝下拉框
     *
     * @param id 主键
     * @return
     */
    @Operation(summary = "拒绝下拉框")
    @GetMapping("/RejectList/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
    })
    public ActionResult<FlowRejectVO> rejectList(@PathVariable("id") String id) throws WorkFlowException {
        FlowRejectVO vo = flowTaskNewService.rejectList(id, false);
        return ActionResult.success(vo);
    }

    /**
     * 引擎节点
     *
     * @param id 主键
     * @return
     * @throws WorkFlowException
     */
    @Operation(summary = "引擎节点")
    @GetMapping("/NodeSelector/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
    })
    public ActionResult<List<FlowBatchModel>> nodeSelector(@PathVariable("id") String id) throws WorkFlowException {
        FlowTemplateAllModel template = flowTaskUtil.templateJson(id);
        String templateJson = template.getTemplateJson().getFlowTemplateJson();
        List<FlowBatchModel> batchList = new ArrayList<>();
        ChildNode childNodeAll = JsonUtil.getJsonToBean(templateJson, ChildNode.class);
        //获取流程节点
        List<ChildNodeList> nodeListAll = new ArrayList<>();
        List<ConditionList> conditionListAll = new ArrayList<>();
        //递归获取条件数据和节点数据
        FlowJsonUtil.getTemplateAll(childNodeAll, nodeListAll, conditionListAll);
        List<String> type = ImmutableList.of(FlowNature.NodeSubFlow, FlowNature.NodeStart);
        for (ChildNodeList childNodeList : nodeListAll) {
            if (!type.contains(childNodeList.getCustom().getType())) {
                FlowBatchModel batchModel = new FlowBatchModel();
                batchModel.setFullName(childNodeList.getProperties().getTitle());
                batchModel.setId(childNodeList.getCustom().getNodeId());
                batchList.add(batchModel);
            }
        }
        return ActionResult.success(batchList);
    }

    /**
     * 流程批量类型下拉
     *
     * @param id 主键
     * @return
     * @throws WorkFlowException
     */
    @Operation(summary = "流程批量类型下拉")
    @GetMapping("/BatchFlowJsonList/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
    })
    public ActionResult<List<FlowBatchModel>> batchFlowJsonList(@PathVariable("id") String id) {
        List<String> taskIdList = flowTaskOperatorService.getBatchList().stream().map(FlowTaskOperatorEntity::getTaskId).collect(Collectors.toList());
        List<FlowTaskEntity> taskListAll = flowTaskService.getOrderStaList(taskIdList);
        List<String> flowIdList = taskListAll.stream().filter(t -> t.getTemplateId().equals(id)).map(FlowTaskEntity::getFlowId).collect(Collectors.toList());
        List<FlowTemplateJsonEntity> templateJsonList = flowTemplateJsonService.getTemplateJsonList(flowIdList);
        List<FlowBatchModel> listVO = new ArrayList<>();
        for (FlowTemplateJsonEntity entity : templateJsonList) {
            FlowBatchModel vo = JsonUtil.getJsonToBean(entity, FlowBatchModel.class);
            vo.setFullName(vo.getFullName() + "(v" + entity.getVersion() + ")");
            listVO.add(vo);
        }
        return ActionResult.success(listVO);
    }

    /**
     * 批量审批
     *
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "批量审批")
    @PostMapping("/BatchOperation")
    @Parameters({
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult batchOperation(@RequestBody FlowModel flowModel) throws WorkFlowException {
        flowModel.setUserInfo(UserProvider.getUser());
        flowTaskNewService.batch(flowModel);
        return ActionResult.success(MsgCode.WF011.get());
    }

    /**
     * 批量获取候选人
     *
     * @param flowId         流程主键
     * @param taskOperatorId 代办主键
     * @return
     * @throws WorkFlowException
     */
    @Operation(summary = "批量获取候选人")
    @GetMapping("/BatchCandidate")
    public ActionResult<FlowCandidateVO> batchCandidate(String flowId, String taskOperatorId) throws WorkFlowException {
        FlowModel flowModel = new FlowModel();
        flowModel.setUserInfo(UserProvider.getUser());
        flowModel.setFlowId(flowId);
        FlowCandidateVO candidate = flowTaskNewService.batchCandidates(flowId, taskOperatorId, flowModel);
        return ActionResult.success(candidate);
    }

    /**
     * 消息跳转工作流
     *
     * @param id 主键
     * @return
     */
    @Operation(summary = "消息跳转工作流")
    @GetMapping("/{id}/Info")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
    })
    public ActionResult taskOperatorId(@PathVariable("id") String id) throws WorkFlowException {
        FlowTaskOperatorEntity operator = flowTaskOperatorService.getInfo(id);
        FlowTaskEntity flowTask = flowTaskService.getInfo(operator.getTaskId());
        FlowModel flowModel = new FlowModel();
        flowModel.setUserInfo(UserProvider.getUser());
        flowTaskNewService.permissions(operator.getHandleId(), flowTask, operator, "", flowModel);
        Map<String, Object> map = new HashMap<>();
        if (!FlowNature.ProcessCompletion.equals(operator.getCompletion())) {
            map.put("isCheck", true);
        } else {
            map.put("isCheck", false);
        }
        return ActionResult.success(map);
    }

    /**
     * 节点下拉框
     *
     * @param id 主键
     * @return
     */
    @Operation(summary = "节点下拉框")
    @GetMapping("/Selector/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
    })
    public ActionResult<List<TaskNodeModel>> selector(@PathVariable("id") String id) {
        List<String> nodetype = ImmutableList.of(FlowNature.NodeStart, FlowNature.NodeSubFlow, FlowNature.EndRound);
        TaskNodeListModel nodeListModel = TaskNodeListModel.builder().id(id).state(FlowNodeEnum.Process.getCode()).build();
        List<FlowTaskNodeEntity> list = flowTaskNodeService.getList(nodeListModel,
                FlowTaskNodeEntity::getId, FlowTaskNodeEntity::getCandidates,
                FlowTaskNodeEntity::getCompletion, FlowTaskNodeEntity::getNodeType,
                FlowTaskNodeEntity::getNodeNext, FlowTaskNodeEntity::getNodeName,
                FlowTaskNodeEntity::getNodeCode, FlowTaskNodeEntity::getNodePropertyJson
        );
        flowTaskUtil.nodeList(list);
        list = list.stream().filter(t -> !nodetype.contains(t.getNodeType())).collect(Collectors.toList());
        List<TaskNodeModel> nodeList = JsonUtil.getJsonToList(list, TaskNodeModel.class);
        return ActionResult.success(nodeList);
    }

    /**
     * 变更或者复活
     *
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "变更或者复活")
    @PostMapping("/Change")
    @Parameters({
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult change(@RequestBody FlowModel flowModel) throws WorkFlowException {
        FlowTaskEntity info = flowTaskService.getInfo(flowModel.getTaskId());
        if (FlowTaskStatusEnum.Revoke.getCode().equals(info.getStatus()) || FlowTaskStatusEnum.Cancel.getCode().equals(info.getStatus()) || FlowTaskStatusEnum.Draft.getCode().equals(info.getStatus())) {
            throw new WorkFlowException(MsgCode.WF012.get());
        }
        flowModel.setUserInfo(UserProvider.getUser());
        flowTaskNewService.change(flowModel);
        String msg = flowModel.getResurgence() ? MsgCode.WF013.get() : MsgCode.WF014.get();
        return ActionResult.success(msg);
    }

    /**
     * 子流程数据
     *
     * @param id 主键
     * @return
     */
    @Operation(summary = "子流程数据")
    @GetMapping("/SubFlowInfo/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
    })
    public ActionResult<List<FlowBeforeInfoVO>> subFlowInfo(@PathVariable("id") String id) throws WorkFlowException {
        FlowTaskNodeEntity taskNode = flowTaskNodeService.getInfo(id, FlowTaskNodeEntity::getNodePropertyJson);
        List<FlowBeforeInfoVO> listVO = new ArrayList<>();
        if (taskNode != null) {
            ChildNodeList childNodeList = JsonUtil.getJsonToBean(taskNode.getNodePropertyJson(), ChildNodeList.class);
            List<String> flowTaskIdList = new ArrayList<>();
            flowTaskIdList.addAll(childNodeList.getCustom().getAsyncTaskList());
            flowTaskIdList.addAll(childNodeList.getCustom().getTaskId());
            for (String taskId : flowTaskIdList) {
                FlowModel flowModel = new FlowModel();
                flowModel.setId(taskId);
                FlowBeforeInfoVO vo = flowTaskNewService.getBeforeInfo(flowModel);
                listVO.add(vo);
            }
        }
        return ActionResult.success(listVO);
    }

    /**
     * 流程类型下拉
     *
     * @param id 主键值
     * @return
     */
    @Operation(summary = "流程类型下拉")
    @GetMapping("/Suspend/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
    })
    public ActionResult suspend(@PathVariable("id") String id) {
        List<FlowTaskEntity> childList = flowTaskService.getChildList(id, FlowTaskEntity::getId, FlowTaskEntity::getIsAsync);
        boolean isAsync = childList.stream().filter(t -> FlowNature.ChildAsync.equals(t.getIsAsync())).count() > 0;
        return ActionResult.success(isAsync);
    }

    /**
     * 流程挂起
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "流程挂起")
    @PostMapping("/Suspend/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult suspend(@PathVariable("id") String id, @RequestBody FlowModel flowModel) {
        flowModel.setUserInfo(UserProvider.getUser());
        flowTaskNewService.suspend(id, flowModel, true);
        return ActionResult.success(MsgCode.WF015.get());
    }

    /**
     * 流程恢复
     *
     * @param id        主键
     * @param flowModel 流程模型
     * @return
     */
    @Operation(summary = "流程恢复")
    @PostMapping("/Restore/{id}")
    @Parameters({
            @Parameter(name = "id", description = "主键", required = true),
            @Parameter(name = "flowModel", description = "流程模型", required = true),
    })
    public ActionResult restore(@PathVariable("id") String id, @RequestBody FlowModel flowModel) {
        flowModel.setUserInfo(UserProvider.getUser());
        flowModel.setSuspend(false);
        flowTaskNewService.suspend(id, flowModel, false);
        return ActionResult.success(MsgCode.WF016.get());
    }

    //递归处理默认当前配置
    private String setDefaultCurrentValue(String configJson, Map<String, Integer> havaDefaultCurrentValue, UserInfo userInfo) {
        if (StringUtil.isEmpty(configJson)) {
            return configJson;
        }
        Map<String, Object> configJsonMap = JsonUtil.stringToMap(configJson.trim());
        if (configJsonMap == null && configJsonMap.isEmpty()) {
            return configJson;
        }
        List<UserRelationEntity> userRelationList = serviceUtil.getListByUserIdAll(ImmutableList.of(userInfo.getUserId()));

        int isChange = 0;
        //处理字段
        Object fieldsObj = configJsonMap.get("fields");
        List<Map<String, Object>> fieldsList = null;
        if (fieldsObj != null) {
            fieldsList = (List<Map<String, Object>>) fieldsObj;
            if (fieldsList != null && !fieldsList.isEmpty()) {
                setDefaultCurrentValue(userRelationList, fieldsList, userInfo, "add");
                configJsonMap.put("fields", fieldsList);
                isChange = 1;
            }
        }

        if (isChange == 1) {
            return JsonUtil.getObjectToString(configJsonMap);
        } else {
            return configJson;
        }
    }

    private void setDefaultCurrentValue(List<UserRelationEntity> userRelationList, List<Map<String, Object>> itemList, UserInfo userInfo, String parseFlag) {
        for (int i = 0, len = itemList.size(); i < len; i++) {
            Map<String, Object> itemMap = itemList.get(i);
            if (itemMap == null || itemMap.isEmpty()) {
                continue;
            }
            Map<String, Object> configMap = (Map<String, Object>) itemMap.get("__config__");
            if (configMap == null || configMap.isEmpty()) {
                continue;
            }
            List<Map<String, Object>> childrenList = (List<Map<String, Object>>) configMap.get("children");
            if (childrenList != null && !childrenList.isEmpty()) {
                setDefaultCurrentValue(userRelationList, childrenList, userInfo, parseFlag);
                configMap = (Map<String, Object>) itemMap.get("__config__");
            }
            String yunzhupaasKey = (String) configMap.get("yunzhupaasKey");
            String defaultCurrent = String.valueOf(configMap.get("defaultCurrent"));
            if ("true".equals(defaultCurrent)) {
                Map<String, List<UserRelationEntity>> relationMap = userRelationList.stream().collect(Collectors.groupingBy(UserRelationEntity::getObjectType));
                Object data = "";
                switch (yunzhupaasKey) {
                    case YunzhupaasKeyConsts.COMSELECT:
                        data = new ArrayList() {{
                            add(userInfo.getOrganizeId());
                        }};
                        break;
                    case YunzhupaasKeyConsts.DEPSELECT:
                        data = userInfo.getDepartmentId();
                        break;
                    case YunzhupaasKeyConsts.POSSELECT:
                        data = userInfo.getPositionIds().length > 0 ? userInfo.getPositionIds()[0] : "";
                        break;
                    case YunzhupaasKeyConsts.USERSELECT:
                    case YunzhupaasKeyConsts.CUSTOMUSERSELECT:
                        data = YunzhupaasKeyConsts.CUSTOMUSERSELECT.equals(yunzhupaasKey) ? userInfo.getUserId() + "--" + PermissionConst.USER : userInfo.getUserId();
                        break;
                    case YunzhupaasKeyConsts.ROLESELECT:
                        List<UserRelationEntity> roleList = relationMap.get(PermissionConst.ROLE) != null ? relationMap.get(PermissionConst.ROLE) : new ArrayList<>();
                        data = roleList.size() > 0 ? roleList.get(0).getObjectId() : "";
                        break;
                    case YunzhupaasKeyConsts.GROUPSELECT:
                        List<UserRelationEntity> groupList = relationMap.get(PermissionConst.GROUP) != null ? relationMap.get(PermissionConst.GROUP) : new ArrayList<>();
                        data = groupList.size() > 0 ? groupList.get(0).getObjectId() : "";
                        break;
                    default:
                        break;
                }
                List<Object> list = new ArrayList<>();
                list.add(data);
                if ("search".equals(parseFlag)) {
                    String searchMultiple = String.valueOf(itemMap.get("searchMultiple"));
                    if ("true".equals(searchMultiple)) {
                        configMap.put("defaultValue", list);
                    } else {
                        configMap.put("defaultValue", data);
                    }
                } else {
                    String multiple = String.valueOf(itemMap.get("multiple"));
                    if ("true".equals(multiple)) {
                        configMap.put("defaultValue", list);
                    } else {
                        configMap.put("defaultValue", data);
                    }
                }
                itemMap.put("__config__", configMap);
                itemList.set(i, itemMap);
            }
        }
    }

    /**
     * 获取流程所关联的用户信息
     *
     * @param taskId 任务ID
     * @param flowTaskUserListModel 查询模型
     * @return
     */
    @Operation(summary = "获取流程所关联的用户信息")
    @Parameters({
            @Parameter(name = "taskId", description = "任务ID", required = true),
            @Parameter(name = "flowTaskUserListModel", description = "查询模型", required = true)
    })
    @GetMapping("/TaskUserList/{taskId}")
    public ActionResult getTaskUserList(@PathVariable("taskId") String taskId, FlowTaskUserListModel flowTaskUserListModel)  throws WorkFlowException  {
        FlowUserListModel flowUserListModel = flowTaskUtil.getTaskUserList(taskId);
        List<UserIdListVo> jsonToList = userService.getObjList(flowUserListModel.getAllUserIdList(), flowTaskUserListModel, null);
        PaginationVO paginationVO = JsonUtil.getJsonToBean(flowTaskUserListModel, PaginationVO.class);
        return ActionResult.page(jsonToList, paginationVO);
    }

}

