package cn.axzo.workflow.server.controller.web.manage;

import cn.axzo.maokai.api.client.OrganizationalNodeUserQueryApi;
import cn.axzo.maokai.api.vo.request.OrgNodeUserBriefInfoListReq;
import cn.axzo.maokai.api.vo.response.OrgNodeUserBriefInfoResp;
import cn.axzo.workflow.client.feign.manage.PrintAdminApi;
import cn.axzo.workflow.common.enums.VarTypeEnum;
import cn.axzo.workflow.common.exception.WorkflowEngineException;
import cn.axzo.workflow.common.model.dto.print.FieldAttributeDTO;
import cn.axzo.workflow.common.model.dto.print.PrintFieldDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintFieldQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.print.PrintTemplateConfigUpsertDTO;
import cn.axzo.workflow.common.model.request.bpmn.process.BpmnProcessInstanceLogQueryDTO;
import cn.axzo.workflow.common.model.request.bpmn.task.BpmnTaskDelegateAssigner;
import cn.axzo.workflow.common.model.request.category.CategoryGroupVarSearchDto;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessDefinitionVO;
import cn.axzo.workflow.common.model.response.bpmn.process.BpmnProcessInstanceLogVO;
import cn.axzo.workflow.common.model.response.category.CategoryGroupVarItemVo;
import cn.axzo.workflow.core.common.utils.BpmnMetaParserHelper;
import cn.axzo.workflow.core.engine.cmd.CustomGetFormInstanceLatestValuesCmd;
import cn.axzo.workflow.core.engine.cmd.CustomGetProcessInstanceVariablesCmd;
import cn.axzo.workflow.core.service.BpmnProcessDefinitionService;
import cn.axzo.workflow.core.service.BpmnProcessInstanceService;
import cn.axzo.workflow.core.service.BpmnProcessModelService;
import cn.axzo.workflow.core.service.CategoryGroupService;
import cn.axzo.workflow.server.common.annotation.ErrorReporter;
import cn.axzo.workflow.server.common.util.RpcExternalUtil;
import cn.axzo.workflow.server.controller.web.bpmn.BpmnProcessInstanceController;
import cn.azxo.framework.common.model.CommonResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.impl.interceptor.CommandExecutor;
import org.flowable.form.api.FormInfo;
import org.flowable.form.api.FormRepositoryService;
import org.flowable.form.model.FormContainer;
import org.flowable.form.model.FormField;
import org.flowable.form.model.FormFieldTypes;
import org.flowable.form.model.SimpleFormModel;
import org.flowable.spring.SpringProcessEngineConfiguration;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

import static cn.axzo.workflow.common.code.FormModelRespCode.FORM_MODEL_NOT_EXISTS;
import static cn.axzo.workflow.common.constant.FormConstants.FORM_FIELD_TYPE_IMAGE;
import static cn.axzo.workflow.common.constant.FormConstants.FORM_FIELD_TYPE_INPUT;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_DEFINITION_KEY;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_DEFINITION_KEY_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_END_TIME;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_END_TIME_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR_NAME;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR_NAME_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR_PHONE;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR_PHONE_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR_POSITION;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INITIATOR_POSITION_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INSTANCE_ID;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_INSTANCE_ID_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOGS;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOGS_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ACTIVITY_NAME;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ACTIVITY_NAME_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ADVICE;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_ADVICE_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_APPROVER_NAME;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_APPROVER_NAME_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_OPERATION_TIME;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_OPERATION_TIME_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_POSITION;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_POSITION_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_SIGNATURE;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_SIGNATURE_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_UNIT;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_LOG_UNIT_DESC;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_START_TIME;
import static cn.axzo.workflow.common.constant.VariableConstants.PRINT_VAR_PROCESS_START_TIME_DESC;
import static cn.axzo.workflow.common.enums.PrintFieldCategoryEnum.form;
import static cn.axzo.workflow.common.enums.PrintFieldCategoryEnum.sign;
import static cn.axzo.workflow.common.enums.PrintFieldCategoryEnum.signature;
import static cn.axzo.workflow.common.enums.PrintFieldCategoryEnum.system;
import static cn.azxo.framework.common.model.CommonResponse.success;

/**
 * 打印相关的控制器
 *
 * @author wangli
 * @since 2025-01-16 17:48
 */
@Slf4j
@RequestMapping({"/web/v1/api/print/admin", "/api/print/admin"})
@RestController
@ErrorReporter
@Validated
public class PrintAdminController implements PrintAdminApi {

    @Resource
    private FormRepositoryService formRepositoryService;
    @Resource
    private BpmnProcessDefinitionService processDefinitionService;
    @Resource
    private SpringProcessEngineConfiguration processEngineConfiguration;
    @Resource
    private OrganizationalNodeUserQueryApi organizationalNodeUserQueryApi;
    @Resource
    private BpmnProcessInstanceController bpmnProcessInstanceController;
    @Resource
    private BpmnProcessInstanceService bpmnProcessInstanceService;
    @Resource
    private CategoryGroupService categoryGroupService;
    @Resource
    private BpmnProcessModelService bpmnProcessModelService;

    /**
     * 查询指定流程实例是否能使用打印
     *
     * @param processInstanceId
     * @return
     */
    @Operation(summary = "查询指定流程实例是否能使用打印")
    @Override
    @GetMapping("/template/exists")
    public CommonResponse<Boolean> hasPrintTemplate(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId) {
        return CommonResponse.success(bpmnProcessInstanceService.hasPrintTemplate(processInstanceId, null));
    }

    /**
     * 打印模板配置内容
     *
     * @param dto
     * @return
     */
    @Operation(summary = "打印模板配置内容")
    @PostMapping("/template/upsert")
    @Override
    public CommonResponse<Void> printTemplateConfig(@Validated @RequestBody PrintTemplateConfigUpsertDTO dto) {
        log.info("操作打印模板配置内容: {}", JSON.toJSONString(dto));
        bpmnProcessModelService.printTemplateConfig(dto);
        return success();
    }
    /**
     * 获取打印模板中可打印的字段, 或者是 WPS 模板中可配置的变量字段
     *
     * @param dto
     * @return
     */
    @Operation(summary = "获取打印模板中可打印的字段, 或者是 WPS 模板中可配置的变量字段")
    @PostMapping("/fields")
    @Override
    public CommonResponse<List<PrintFieldDTO>> getPrintFields(@Validated @RequestBody PrintFieldQueryDTO dto) {
        List<PrintFieldDTO> printFields = new ArrayList<>();
        FormInfo formModel;
        try {
            formModel = formRepositoryService.getFormModelByKey(dto.getProcessDefinitionKey(), dto.getTenantId(), false);
            // 表单字段
            List<FormField> formFields = ((SimpleFormModel) formModel.getFormModel()).getFields();
            formFields.forEach(formField -> {
                FormContainer formContainer = (FormContainer) formField;
                printFields.addAll(formContainer.getFields().get(0).stream().map(field -> {
                            PrintFieldDTO printFieldDTO = new PrintFieldDTO()
                                    .setName(field.getName())
                                    .setCode(field.getId())
                                    .setFieldCategoryType(form)
                                    .setFieldFormType(field.getType());
                    switchAmount(field, printFieldDTO);
                    switchFormContainer(field, printFieldDTO);
                            return printFieldDTO;
                        }
                ).collect(Collectors.toList()));
            });
        } catch (FlowableObjectNotFoundException e) {
            log.warn("can't found form model");
            if (Objects.equals(Boolean.TRUE, dto.getThrowException())) {
                throw new WorkflowEngineException(FORM_MODEL_NOT_EXISTS);
            }
        }

        // 生成固定的系统字段
        printFields.addAll(generateSystemFields(dto.getProcessDefinitionKey(), dto.getTenantId()));

        // 生成业务对应的变量相应字段
        // generateDictVariables(printFields, dto.getProcessDefinitionKey());

        return success(printFields);
    }

    // 自定义组件类型的额外处理
    private static void switchFormContainer(FormField field, PrintFieldDTO printFieldDTO) {
        if (field instanceof FormContainer) {
            FormContainer container = (FormContainer) field;
            printFieldDTO.setAttributes(container.getFields().get(0)
                    .stream().map(subField -> new FieldAttributeDTO()
                            .setCode(subField.getId())
                            .setFieldFormType(subField.getType())
                            .setName(subField.getName()))
                    .collect(Collectors.toList()));
        }
    }

    // 金额组件类型的额外处理
    private static void switchAmount(FormField field, PrintFieldDTO printFieldDTO) {
        if (Objects.equals(field.getType(), FormFieldTypes.AMOUNT)) {
            List<FieldAttributeDTO> attributes = new ArrayList<>();
            attributes.add(new FieldAttributeDTO()
                    .setCode("standardNumerals")
                    .setName("小写")
                    .setFieldFormType(FORM_FIELD_TYPE_INPUT)
            );
            if (Boolean.parseBoolean(field.getParam("toUpper").toString())) {
                attributes.add(new FieldAttributeDTO()
                        .setCode("uppercaseNumerals")
                        .setName("大写")
                        .setFieldFormType(FORM_FIELD_TYPE_INPUT));
            }
            printFieldDTO.setAttributes(attributes);
        }
    }

    private List<PrintFieldDTO> generateDictVariables(List<PrintFieldDTO> printFields, String processDefinitionKey) {
        if (CollectionUtils.isEmpty(printFields)) {
            printFields = new ArrayList<>();
        }
        // 加载业务管理中自定义的业务变量
        List<CategoryGroupVarItemVo> categoryGroupVarItemVos = categoryGroupService.searchGroupAndVarList(CategoryGroupVarSearchDto.builder()
                .category(processDefinitionKey)
                .build());
        if (CollectionUtils.isEmpty(categoryGroupVarItemVos)) {
            return printFields;
        }

        printFields.addAll(categoryGroupVarItemVos.stream().map(i ->
                new PrintFieldDTO().setName(i.getGroupName()).setCode("group_" + i.getId()).setFieldCategoryType(sign)
                        .setAttributes(i.getVars().stream().map(j -> new FieldAttributeDTO()
                                        .setName(j.getName())
                                        .setCode(j.getCode())
                                        .setFieldFormType(mappingFormFieldType(j.getType())))
                                .collect(Collectors.toList())
                        )).collect(Collectors.toList()));
        return printFields;
    }

    private String mappingFormFieldType(VarTypeEnum varTypeEnum) {
        switch (varTypeEnum) {
            case TEXT:
                return FORM_FIELD_TYPE_INPUT;
            case PICTURE:
                return FORM_FIELD_TYPE_IMAGE;
            default:
                return "";
        }
    }

    private List<PrintFieldDTO> generateSystemFields(String processDefinitionKey, String tenantId) {
        List<PrintFieldDTO> printFields = new ArrayList<>();

        printFields.add(new PrintFieldDTO().setName(PRINT_VAR_PROCESS_DEFINITION_KEY_DESC).setCode(PRINT_VAR_PROCESS_DEFINITION_KEY).setFieldCategoryType(system).setFieldFormType("input"));
        printFields.add(new PrintFieldDTO().setName(PRINT_VAR_PROCESS_INSTANCE_ID_DESC).setCode(PRINT_VAR_PROCESS_INSTANCE_ID).setFieldCategoryType(system).setFieldFormType("input"));
        printFields.add(new PrintFieldDTO().setName(PRINT_VAR_PROCESS_START_TIME_DESC).setCode(PRINT_VAR_PROCESS_START_TIME).setFieldCategoryType(system).setFieldFormType("input"));
        printFields.add(new PrintFieldDTO().setName(PRINT_VAR_PROCESS_END_TIME_DESC).setCode(PRINT_VAR_PROCESS_END_TIME).setFieldCategoryType(system).setFieldFormType("input"));
        printFields.add(new PrintFieldDTO().setName(PRINT_VAR_PROCESS_INITIATOR_NAME_DESC).setCode(PRINT_VAR_PROCESS_INITIATOR_NAME).setFieldCategoryType(system).setFieldFormType("input"));
        printFields.add(new PrintFieldDTO().setName(PRINT_VAR_PROCESS_INITIATOR_POSITION_DESC).setCode(PRINT_VAR_PROCESS_INITIATOR_POSITION).setFieldCategoryType(system).setFieldFormType("input"));
        printFields.add(new PrintFieldDTO().setName(PRINT_VAR_PROCESS_INITIATOR_PHONE_DESC).setCode(PRINT_VAR_PROCESS_INITIATOR_PHONE).setFieldCategoryType(system).setFieldFormType("input"));
        printFields.add(new PrintFieldDTO().setName(PRINT_VAR_PROCESS_LOGS_DESC).setCode(PRINT_VAR_PROCESS_LOGS).setFieldCategoryType(system).setFieldFormType("table")
                .setAttributes(Lists.newArrayList(
                        new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_ACTIVITY_NAME).setName(PRINT_VAR_PROCESS_LOG_ACTIVITY_NAME_DESC),
                        new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_APPROVER_NAME).setName(PRINT_VAR_PROCESS_LOG_APPROVER_NAME_DESC),
                        new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_UNIT).setName(PRINT_VAR_PROCESS_LOG_UNIT_DESC),
                        new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_POSITION).setName(PRINT_VAR_PROCESS_LOG_POSITION_DESC),
                        new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_ADVICE).setName(PRINT_VAR_PROCESS_LOG_ADVICE_DESC),
                        new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_OPERATION_TIME).setName(PRINT_VAR_PROCESS_LOG_OPERATION_TIME_DESC),
                        new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_SIGNATURE).setName(PRINT_VAR_PROCESS_LOG_SIGNATURE_DESC)
                )));

        // 电子签名
        BpmnProcessDefinitionVO definition = processDefinitionService.getActiveProcessDefinitionByKey(processDefinitionKey, tenantId);
        printFields.addAll(processDefinitionService.findFlowElements(definition.getId())
                .stream()
                .filter(BpmnMetaParserHelper::getActivitySignature)
                .map(activity -> new PrintFieldDTO()
                        .setName(activity.getName())
                        .setCode(activity.getId())
                        .setFieldCategoryType(signature)
                        .setFieldFormType("signature")
                        .setAttributes(Lists.newArrayList(new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_SIGNATURE).setName(PRINT_VAR_PROCESS_LOG_SIGNATURE_DESC).setFieldFormType(FORM_FIELD_TYPE_INPUT),
                                new FieldAttributeDTO().setCode(PRINT_VAR_PROCESS_LOG_ADVICE).setName(PRINT_VAR_PROCESS_LOG_ADVICE_DESC).setFieldFormType(FORM_FIELD_TYPE_INPUT))))
                .collect(Collectors.toList())
        );

        return printFields;
    }

    /**
     * 获取指定流程下用于替换打印的相关变量
     *
     * @param processInstanceId
     * @return
     */
    @Operation(summary = "获取指定流程下用于替换打印的相关变量")
    @GetMapping("/field/variables")
    @Override
    public CommonResponse<Map<String, Object>> getPrintFieldVariables(@NotBlank(message = "流程实例不能为空") @RequestParam String processInstanceId) {
        Map<String, Object> result = new HashMap<>();
        CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
        byte[] formInstanceValue = commandExecutor.execute(new CustomGetFormInstanceLatestValuesCmd(processInstanceId));
        if (!ObjectUtils.isEmpty(formInstanceValue)) {
            JSONObject treeNode = JSON.parseObject(new String(formInstanceValue));
            result.putAll(treeNode.getJSONObject("values").getInnerMap());
        }

        // 生成系统字段的变量
        generateSystemFieldVariables(processInstanceId, result);

        // 将所有变量都转换成 JSON 对象返回
        convertValueToObject(result);
        return success(result);
    }

    private void convertValueToObject(Map<String, Object> result) {
        if (CollectionUtils.isEmpty(result)) {
            return;
        }

        result.forEach((key, value) -> {
            if (!(value instanceof String)) {
                return;
            }
            if (((String) value).startsWith("[")) {
                result.put(key, JSONArray.parseArray((String) value));
            } else if (((String) value).startsWith("{")) {
                result.put(key, JSONObject.parseObject((String) value));
            }
        });
    }

    private void generateSystemFieldVariables(String processInstanceId, Map<String, Object> result) {
        CommandExecutor commandExecutor = processEngineConfiguration.getCommandExecutor();
        Map<String, Object> variables = commandExecutor.execute(new CustomGetProcessInstanceVariablesCmd(processInstanceId));
        final SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
        // 解析发起人
        BpmnTaskDelegateAssigner initiator = BpmnTaskDelegateAssigner.toObjectCompatible(variables.getOrDefault(PRINT_VAR_PROCESS_INITIATOR, null));
        if (Objects.nonNull(initiator)) {
            Optional<OrgNodeUserBriefInfoResp> user = getUserInfo(initiator);
            variables.put(PRINT_VAR_PROCESS_INITIATOR_NAME, user.isPresent() ? user.get().getRealName() : "");
            variables.put(PRINT_VAR_PROCESS_INITIATOR_POSITION, user.isPresent() && Objects.nonNull(user.get().getJob()) ? user.get().getJob().getName() : "");
            variables.put(PRINT_VAR_PROCESS_INITIATOR_PHONE, user.isPresent() ? user.get().getProfile().getPhone() : "");
            variables.remove(PRINT_VAR_PROCESS_INITIATOR);
        }
        // 填充审批日志
        CommonResponse<BpmnProcessInstanceLogVO> processInstanceLogs = bpmnProcessInstanceController
                .getProcessInstanceLogs(BpmnProcessInstanceLogQueryDTO.builder()
                        .processInstanceId(processInstanceId)
                        .hasButton(false)
                        .encrypt(false)
                        .build());
        List<Map<String, Object>> taskLogs = new ArrayList<>();
        processInstanceLogs.getData().getTaskDetails().stream()
                .filter(e -> !e.isVirtual() && Objects.nonNull(e.getEndTime()))
                .forEach(taskLog -> {
                    Map<String, Object> taskLogMap = new HashMap<>();
                    taskLogMap.put(PRINT_VAR_PROCESS_LOG_ACTIVITY_NAME, taskLog.getName());
                    Optional<OrgNodeUserBriefInfoResp> user = getUserInfo(taskLog.getAssigneeSnapshot());
                    taskLogMap.put(PRINT_VAR_PROCESS_LOG_APPROVER_NAME, user.isPresent() ? user.get().getRealName() : "");
                    taskLogMap.put(PRINT_VAR_PROCESS_LOG_UNIT, user.isPresent() ? user.get().getOrganizationalUnitName() : "");
                    taskLogMap.put(PRINT_VAR_PROCESS_LOG_POSITION, user.isPresent() && Objects.nonNull(user.get().getJob()) ? user.get().getJob().getName() : "");
                    taskLogMap.put(PRINT_VAR_PROCESS_LOG_ADVICE, taskLog.getAdvice());
                    taskLogMap.put(PRINT_VAR_PROCESS_LOG_OPERATION_TIME, sdf.format(taskLog.getCreateTime()));
                    taskLogMap.put(PRINT_VAR_PROCESS_LOG_SIGNATURE, taskLog.getSignatureUrl());
                    taskLogs.add(taskLogMap);
                    variables.put(PRINT_VAR_PROCESS_LOGS, taskLogs);
                });
        result.putAll(variables);
    }

    private Optional<OrgNodeUserBriefInfoResp> getUserInfo(BpmnTaskDelegateAssigner assigner) {
        if (Objects.isNull(assigner)) {
            return Optional.empty();
        }
        OrgNodeUserBriefInfoListReq req = new OrgNodeUserBriefInfoListReq();
        if (StringUtils.hasText(assigner.getTenantId())) {
            req.setWorkspaceId(Long.valueOf(assigner.getTenantId()));
        }
        if (StringUtils.hasText(assigner.getOuId())) {
            req.setOuId(Long.valueOf(assigner.getOuId()));
        }
        if (StringUtils.hasText(assigner.getNodeId())) {
            req.setOrgNodeIds(Lists.newArrayList(Long.valueOf(assigner.getNodeId())));
        }
        if (StringUtils.hasText(assigner.getPersonId())) {
            req.setPersonIds(Lists.newArrayList(Long.valueOf(assigner.getPersonId())));
        }
        req.setNeedJob(true);
        req.setNeedUnit(true);
        req.setNeedProfile(true);
        req.setContainsExited(true);
        List<OrgNodeUserBriefInfoResp> users = RpcExternalUtil.rpcApiResultProcessor(() -> organizationalNodeUserQueryApi.listOrgNodeUsers(req),
                "查询审批人员组织信息", req);

        if (CollectionUtils.isEmpty(users)) {
            return Optional.empty();
        }

        return users.stream().sorted(Comparator.comparing(OrgNodeUserBriefInfoResp::getExited).reversed())
                .collect(Collectors.toList()).stream().findFirst();
    }
}
