package com.ningdatech.pmapi.user.manage;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ningdatech.basic.exception.BizException;
import com.ningdatech.basic.model.GenericResult;
import com.ningdatech.basic.model.PageVo;
import com.ningdatech.pmapi.common.constant.RegionConst;
import com.ningdatech.pmapi.common.helper.RegionCacheHelper;
import com.ningdatech.pmapi.common.helper.UserInfoHelper;
import com.ningdatech.pmapi.common.util.BizUtils;
import com.ningdatech.pmapi.common.util.StrUtils;
import com.ningdatech.pmapi.ding.constants.DingOrganizationContant;
import com.ningdatech.pmapi.organization.model.entity.DingEmployeeInfo;
import com.ningdatech.pmapi.organization.model.entity.DingOrganization;
import com.ningdatech.pmapi.organization.service.IDingEmployeeInfoService;
import com.ningdatech.pmapi.organization.service.IDingOrganizationService;
import com.ningdatech.pmapi.sys.model.entity.Role;
import com.ningdatech.pmapi.sys.model.entity.UserRole;
import com.ningdatech.pmapi.sys.service.IRoleService;
import com.ningdatech.pmapi.sys.service.IUserRoleService;
import com.ningdatech.pmapi.user.constant.UserAvailableEnum;
import com.ningdatech.pmapi.user.entity.UserInfo;
import com.ningdatech.pmapi.user.model.po.ReqUserDetailEditPO;
import com.ningdatech.pmapi.user.model.po.ReqUserDetailPO;
import com.ningdatech.pmapi.user.model.po.ReqUserDisableOrEnablePO;
import com.ningdatech.pmapi.user.model.po.ReqUserInfoListPO;
import com.ningdatech.pmapi.user.model.vo.ResUserDetailVO;
import com.ningdatech.pmapi.user.model.vo.ResUserInfoListVO;
import com.ningdatech.pmapi.user.model.vo.UserRoleVO;
import com.ningdatech.pmapi.user.security.auth.model.UserFullInfoDTO;
import com.ningdatech.pmapi.user.service.IUserInfoService;
import com.ningdatech.pmapi.user.util.LoginUserUtil;
import com.ningdatech.zwdd.ZwddIntegrationProperties;
import com.ningdatech.zwdd.client.ZwddClient;
import com.wflow.workflow.bean.dto.ProcessInstanceUserDto;
import lombok.RequiredArgsConstructor;
import org.springframework.aop.framework.AopContext;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * @author liuxinxin
 * @date 2023/2/13 上午9:09
 */
@Component
@RequiredArgsConstructor
public class UserInfoManage {

    private final UserAuthManage userAuthManage;
    private final IUserInfoService iUserInfoService;
    private final IRoleService iRoleService;
    private final IDingOrganizationService iDingOrganizationService;
    private final IDingEmployeeInfoService iDingEmployeeInfoService;
    private final IUserRoleService iUserRoleService;
    private final UserInfoHelper userInfoHelper;
    private final RegionCacheHelper regionCacheHelper;

    private final ZwddIntegrationProperties zwddIntegrationProperties;

    private final ZwddClient zwddClient;

    public PageVo<ResUserInfoListVO> list(ReqUserInfoListPO req) {
        PageVo<ResUserInfoListVO> pageVo = new PageVo<>();

        String phoneNo = req.getPhoneNo();
        String orgCode = req.getOrgCode();
        String name = req.getName();
        String orgName = req.getOrgName();
        Long regionId = req.getRegionId();

        List<Long> userIdList = getRoleCompliantUserIdList(req.getUserRoleList());
        if (userIdList != null && userIdList.size() == 0) {
            pageVo.setRecords(new ArrayList<>());
            pageVo.setTotal(0L);
            return pageVo;
        }

        LambdaQueryWrapper<UserInfo> wrapper = Wrappers.lambdaQuery(UserInfo.class)
                .like(StringUtils.isNotBlank(phoneNo), UserInfo::getMobile, phoneNo)
                .like(StringUtils.isNotBlank(name), UserInfo::getRealName, name)
                .in(Objects.nonNull(userIdList), UserInfo::getId, userIdList)
                .eq(Objects.nonNull(regionId), UserInfo::getRegionCode, regionId)
                .like(StringUtils.isNotBlank(orgName), UserInfo::getEmpPosUnitName, orgName)
                .eq(StringUtils.isNotBlank(orgCode), UserInfo::getEmpPosUnitCode, orgCode)
                .orderByDesc(UserInfo::getUpdateOn);

        Page<UserInfo> page = iUserInfoService.page(new Page<>(req.getPageNumber(), req.getPageSize()), wrapper);
        List<UserInfo> records = page.getRecords();
        long total = page.getTotal();
        List<ResUserInfoListVO> result = new ArrayList<>();
        if (records != null && records.size() > 0) {
            List<String> employeeCodeList = records.stream().map(UserInfo::getEmployeeCode)
                    .distinct().collect(Collectors.toList());

            List<DingEmployeeInfo> employeeInfoList = iDingEmployeeInfoService.getEmployeeList(employeeCodeList);
            Map<String, DingOrganization> empCodeOrgMap = iDingOrganizationService.getEmpCodeOrgMap(employeeInfoList);

            records.forEach(r -> {
                ResUserInfoListVO item = new ResUserInfoListVO();
                item.setName(r.getRealName());
                String employeeCode = r.getEmployeeCode();
                if (StringUtils.isNotBlank(employeeCode)) {
                    DingOrganization dingOrganization = empCodeOrgMap.get(employeeCode);
                    if (Objects.nonNull(dingOrganization)) {
                        item.setOrgName(dingOrganization.getOrganizationName());
                        item.setOrgCode(dingOrganization.getOrganizationCode());
                        String regionCode = dingOrganization.getDivisionCode();
                        item.setRegionCode(regionCode);
                        if (Objects.nonNull(regionCode)) {
                            item.setRegionName(regionCacheHelper.getDisplayName(regionCode, RegionConst.RL_COUNTY));
                        }
                    }

                }
                userStatusAssembler(item, r);
                item.setUpdateTime(r.getUpdateOn());
                item.setEmployeeCode(r.getEmployeeCode());
                item.setUserRoleList(getUserRoleVOList(item.getUserId()));
                result.add(item);
            });
        }
        pageVo.setTotal(total);
        pageVo.setRecords(result);
        return pageVo;
    }

    private List<String> getCompliantOrgEmpCodeList(String orgName, String orgCode) {
        if (StringUtils.isBlank(orgName) && StringUtils.isBlank(orgCode)) {
            return null;
        }
        List<String> compliantOrgCodeList = new ArrayList<>();

        // 查重符合筛选条件的组织列表
        if (StringUtils.isNotBlank(orgName)) {
            List<DingOrganization> dingOrganizationList = iDingOrganizationService.list(Wrappers.lambdaQuery(DingOrganization.class)
                    .like(DingOrganization::getOrganizationName, orgName)
                    .eq(DingOrganization::getTypeCode, DingOrganizationContant.UNIT_TYPE)
            );

            List<String> compliantOrgNameCodeList = dingOrganizationList.stream()
                    .map(DingOrganization::getOrganizationCode)
                    .collect(Collectors.toList());
            if (CollUtil.isEmpty(compliantOrgNameCodeList)) {
                return new ArrayList<>();
            }

            // 取交集
            List<String> tempCompliantOrgCodeList = new ArrayList<>();
            for (String compliantOrgNameCode : compliantOrgNameCodeList) {
                if (compliantOrgCodeList.contains(compliantOrgNameCode)) {
                    tempCompliantOrgCodeList.add(compliantOrgNameCode);
                }
            }
            compliantOrgCodeList = tempCompliantOrgCodeList;
            if (CollUtil.isEmpty(compliantOrgCodeList)) {
                return new ArrayList<>();
            }
        }

        if (StringUtils.isNotBlank(orgCode)) {
            compliantOrgCodeList.add(orgCode);
        }
        if (CollUtil.isEmpty(compliantOrgCodeList)) {
            return new ArrayList<>();
        }

        // 查重符合筛选条件的用户code列表
        List<DingEmployeeInfo> dingEmployeeInfoList = iDingEmployeeInfoService.list(Wrappers.lambdaQuery(DingEmployeeInfo.class)
                .in(DingEmployeeInfo::getEmpPosUnitCode, compliantOrgCodeList));

        List<String> compliantOrgEmpCodeList = dingEmployeeInfoList.stream()
                .map(DingEmployeeInfo::getEmployeeCode).distinct().collect(Collectors.toList());
//        if (compliantOrgEmpCodeList.size() > 500) {
//            throw new BizException("搜索结果过多请缩小搜索范围");
//        }
        return compliantOrgEmpCodeList;
    }

    /**
     * 获取符合查询条件的 用户 userId
     *
     * @param userRoleList
     */
    private List<Long> getRoleCompliantUserIdList(List<UserRoleVO> userRoleList) {
        if (CollUtil.isNotEmpty(userRoleList)) {
            userRoleList = userRoleList.stream().filter(r -> Objects.nonNull(r.getId())).collect(Collectors.toList());
        }
        if (CollUtil.isEmpty(userRoleList)) {
            return null;
        }
        List<Long> roleIdList = userRoleList.stream().map(UserRoleVO::getId).collect(Collectors.toList());

        List<Long> compliantUserIdList = iUserRoleService.list(Wrappers.lambdaQuery(UserRole.class)
                .in(UserRole::getRoleId, roleIdList)).stream().map(UserRole::getUserId).distinct().collect(Collectors.toList());
        if (CollUtil.isEmpty(compliantUserIdList)) {
            return new ArrayList<>();
        }
        return iUserInfoService.list(Wrappers.lambdaQuery(UserInfo.class)
                        .in(UserInfo::getId, compliantUserIdList))
                .stream().map(UserInfo::getId).collect(Collectors.toList());

    }

    /**
     * 装配用户状态 及 userId
     *
     * @param resListVO
     * @param userInfo
     */
    private void userStatusAssembler(ResUserInfoListVO resListVO, UserInfo userInfo) {
        if (Objects.nonNull(userInfo)) {
            resListVO.setPhoneNo(userInfo.getMobile());
            if (StringUtils.isNotBlank(userInfo.getAvailable())
                    && UserAvailableEnum.ENABLE.name().equals(userInfo.getAvailable())) {
                resListVO.setStatus(UserAvailableEnum.ENABLE.name());
            } else {
                resListVO.setStatus(UserAvailableEnum.DISABLE.name());
            }
            resListVO.setUserId(userInfo.getId());
        } else {
            resListVO.setStatus(UserAvailableEnum.DISABLE.name());
        }
    }


    private List<UserRoleVO> getUserRoleVOList(Long userId) {
        List<UserRoleVO> userRoleInfoList = new ArrayList<>();
        if (Objects.isNull(userId)) {
            return userRoleInfoList;
        }
        List<UserRole> userRoleList = iUserRoleService.list(Wrappers.lambdaQuery(UserRole.class)
                .eq(UserRole::getUserId, userId).orderByAsc(UserRole::getCreateOn));
        if (CollUtil.isNotEmpty(userRoleList)) {
            List<Long> roleIdList = userRoleList.stream().map(UserRole::getRoleId).collect(Collectors.toList());
            List<Role> roleList = iRoleService.listByIds(roleIdList);
            roleList.forEach(r -> {
                UserRoleVO userRoleVO = new UserRoleVO();
                userRoleVO.setId(r.getId());
                userRoleVO.setName(r.getName());
                userRoleVO.setCreateOn(r.getCreateOn());
                userRoleInfoList.add(userRoleVO);
            });
        }
        return userRoleInfoList;
    }

    @Transactional(rollbackFor = Exception.class)
    public void disableOrEnable(ReqUserDisableOrEnablePO req) {
        Long userId;
        if (req.getUserId() != null) {
            userId = req.getUserId();
        } else if (StrUtils.isNotBlank(req.getEmployeeCode())) {
            UserInfoManage proxy = (UserInfoManage) AopContext.currentProxy();
            userId = proxy.generateUserId(req.getEmployeeCode());
        } else {
            throw BizException.wrap("用户参数缺失");
        }
        UserInfo userInfo = iUserInfoService.getById(userId);
        userInfo.setAvailable(req.getOperation());
        iUserInfoService.updateById(userInfo);
        if ("DISABLE".equals(userInfo.getAvailable())) {
            userAuthManage.kickOff(userId);
        }

    }

    public ResUserDetailVO userInfoDetail(ReqUserDetailPO reqUserDetailPO) {
        Long userId = reqUserDetailPO.getUserId();
        String employeeCode = reqUserDetailPO.getEmployeeCode();
        if (StringUtils.isBlank(employeeCode) && Objects.isNull(userId)) {
            throw new BizException("employeeCode and userId can't not be null");
        }
        if (Objects.isNull(userId)) {
            userId = generateUserId(reqUserDetailPO.getEmployeeCode());
        }

        UserInfo userInfo = iUserInfoService.getById(userId);
        if (Objects.isNull(userInfo)) {
            return null;
        }
        ResUserDetailVO resUserDetailVO = new ResUserDetailVO();
        resUserDetailVO.setRealName(userInfo.getRealName());
        resUserDetailVO.setUserId(userInfo.getId());
        resUserDetailVO.setPhoneNo(userInfo.getMobile());
        resUserDetailVO.setStatus(userInfo.getAvailable());

        // 装配用户角色信息列表
        List<UserRole> userRoleList = iUserRoleService.list(Wrappers.lambdaQuery(UserRole.class)
                .eq(UserRole::getUserId, userId));
        List<UserRoleVO> userRoleInfoList = new ArrayList<>();
        if (CollUtil.isNotEmpty(userRoleList)) {
            List<Long> roleIdList = userRoleList.stream().map(UserRole::getRoleId).collect(Collectors.toList());
            List<Role> roleList = iRoleService.list(Wrappers.lambdaQuery(Role.class).in(Role::getId, roleIdList));
            userRoleInfoList = roleList.stream().map(r -> {
                UserRoleVO userRoleVO = new UserRoleVO();
                userRoleVO.setId(r.getId());
                userRoleVO.setName(r.getName());
                return userRoleVO;
            }).collect(Collectors.toList());
        }
        resUserDetailVO.setUserRoleInfoList(userRoleInfoList);
        return resUserDetailVO;
    }

    @Transactional(rollbackFor = Exception.class)
    public void userInfoDetailEdit(ReqUserDetailEditPO reqUserDetailEditPO) {
        Long userId = reqUserDetailEditPO.getUserId();
        if (Objects.isNull(userId)) {
            String employeeCode = reqUserDetailEditPO.getEmployeeCode();
            if (StringUtils.isBlank(employeeCode)) {
                throw new IllegalArgumentException("employeeCode can't be null");
            }
            userId = generateUserId(employeeCode);
        }
        UserInfo userInfo = iUserInfoService.getById(userId);
        String oldUserStatus = userInfo.getAvailable();
        // 绑定用户手机号
        bandUserMobile(userInfo, reqUserDetailEditPO);

        userInfo.setAvailable(reqUserDetailEditPO.getStatus());
        userInfo.setUpdateOn(LocalDateTime.now());
        userInfo.setUpdateBy(LoginUserUtil.getUserId());
        iUserInfoService.updateById(userInfo);

        List<UserRoleVO> userRoleInfoList = reqUserDetailEditPO.getUserRoleInfoList();
        iUserRoleService.remove(Wrappers.lambdaQuery(UserRole.class).eq(UserRole::getUserId, userId));
        if (CollUtil.isNotEmpty(userRoleInfoList)) {
            Long finalUserId = userId;
            List<UserRole> userRoleList = userRoleInfoList.stream().map(r -> {
                UserRole saveRecord = new UserRole();
                saveRecord.setRoleId(r.getId());
                saveRecord.setUserId(finalUserId);
                return saveRecord;
            }).collect(Collectors.toList());
            iUserRoleService.saveBatch(userRoleList);
        }
        // 刷新用户权限 仅原状态为正常才需要刷新session
        if ("ENABLE".equals(oldUserStatus)) {
            if (oldUserStatus.equals(userInfo.getAvailable())) {
                userAuthManage.refreshSession(userId);
            } else {
                userAuthManage.kickOff(userId);
            }
        }
    }

    /**
     * 绑定用户手机号
     *
     * @param userInfo
     * @param reqUserDetailEditPO
     */
    @Transactional(rollbackFor = Exception.class)
    public void bandUserMobile(UserInfo userInfo, ReqUserDetailEditPO reqUserDetailEditPO) {
        String employeeCode = reqUserDetailEditPO.getEmployeeCode();
        String mobile = userInfo.getMobile();
        Long userId = userInfo.getId();
//        if (StringUtils.isBlank(mobile)) {
        // 校验手机号是否重复
        UserInfo repeatMobileUserInfo = iUserInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class)
                .eq(UserInfo::getMobile, reqUserDetailEditPO.getPhoneNo()).ne(UserInfo::getId, userId));
        if (Objects.nonNull(repeatMobileUserInfo)) {
            throw new BizException("该手机号码已被绑定，请问重复绑定");
        }

        String phoneNo = reqUserDetailEditPO.getPhoneNo();
        userInfo.setMobile(phoneNo);
        // 更新浙政钉相关数据
        if (StringUtils.isNotBlank(phoneNo)) {
            iDingEmployeeInfoService
                    .update(Wrappers.lambdaUpdate(DingEmployeeInfo.class)
                            .eq(DingEmployeeInfo::getMainJob, "true")
                            .eq(DingEmployeeInfo::getEmployeeCode, employeeCode)
                            .set(DingEmployeeInfo::getBindUserMobile, phoneNo));
            iUserInfoService.updateById(userInfo);
        }
//        }

    }

    @Transactional(rollbackFor = Exception.class)
    public Long generateUserId(String employeeCode) {
        UserInfo userInfo = iUserInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class)
                .eq(UserInfo::getEmployeeCode, employeeCode));
        if (Objects.isNull(userInfo)) {
            List<DingEmployeeInfo> dingEmployeeInfoList = iDingEmployeeInfoService
                    .list(Wrappers.lambdaQuery(DingEmployeeInfo.class)
                            .eq(DingEmployeeInfo::getEmployeeCode, employeeCode)
                            .eq(DingEmployeeInfo::getMainJob, "true"));
            if (CollUtil.isEmpty(dingEmployeeInfoList)) {
                throw new BizException("员工账号不存在");
            }
            DingEmployeeInfo dingEmployeeInfo = dingEmployeeInfoList.get(0);
            userInfo = UserInfo.builder()
                    .accountId(dingEmployeeInfo.getAccountId())
                    .username(dingEmployeeInfo.getEmployeeName())
                    .realName(dingEmployeeInfo.getEmployeeName())
                    .employeeCode(dingEmployeeInfo.getEmployeeCode())
                    .available(UserAvailableEnum.DISABLE.name())
                    .createBy(-1L)
                    .updateBy(-1L)
                    .createOn(LocalDateTime.now())
                    .updateOn(LocalDateTime.now())
                    .build();
            iUserInfoService.save(userInfo);
        }
        return userInfo.getId();
    }


    public ResUserDetailVO currentUserInfo() {
        Long userId = LoginUserUtil.getUserId();
        UserInfo userInfo = iUserInfoService.getById(userId);
        if (Objects.isNull(userInfo)) {
            return null;
        }
        ResUserDetailVO resUserDetailVO = new ResUserDetailVO();
        resUserDetailVO.setRealName(userInfo.getRealName());
        resUserDetailVO.setUserId(userInfo.getId());
        resUserDetailVO.setPhoneNo(userInfo.getMobile());
        resUserDetailVO.setStatus(userInfo.getAvailable());
        resUserDetailVO.setEmployeeCode(userInfo.getEmployeeCode());
        resUserDetailVO.setAvatar(makeAvatar(userInfo.getAvatar()));

        // 装配用户角色信息列表
        List<UserRole> userRoleList = iUserRoleService.list(Wrappers.lambdaQuery(UserRole.class)
                .eq(UserRole::getUserId, userId));
        List<UserRoleVO> userRoleInfoList = new ArrayList<>();
        if (CollUtil.isNotEmpty(userRoleList)) {
            List<Long> roleIdList = userRoleList.stream().map(UserRole::getRoleId).collect(Collectors.toList());
            List<Role> roleList = iRoleService.list(Wrappers.lambdaQuery(Role.class).in(Role::getId, roleIdList));
            userRoleInfoList = roleList.stream().map(r -> {
                UserRoleVO userRoleVO = new UserRoleVO();
                userRoleVO.setId(r.getId());
                userRoleVO.setName(r.getName());
                userRoleVO.setCode(r.getCode());
                return userRoleVO;
            }).collect(Collectors.toList());
        }
        resUserDetailVO.setUserRoleInfoList(userRoleInfoList);
        UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(userId);
        if (Objects.nonNull(userFullInfo)) {
            resUserDetailVO.setOrgCode(userFullInfo.getOrganizationCode());
            resUserDetailVO.setOrgName(userFullInfo.getOrganizationName());
            resUserDetailVO.setRegionCode(userFullInfo.getRegionCode());
            resUserDetailVO.setRegionLevel(userFullInfo.getRegionLevel());
            resUserDetailVO.setRegionName(regionCacheHelper.getRegionName(userFullInfo.getRegionCode()
                    , RegionConst.RL_COUNTY));
            resUserDetailVO.setEmpPosUnitCode(userFullInfo.getEmpPosUnitCode());
            resUserDetailVO.setEmpPosUnitName(userFullInfo.getEmpPosUnitName());
        }
        return resUserDetailVO;
    }

    //生成头像 链接
    private String makeAvatar(String avatar) {
        try {
            GenericResult<String> accessToken = zwddClient.getAccessToken();
            String token = accessToken.getData();
            String res = "https://" + zwddIntegrationProperties.getDomain() + "/media/download?" +
                    "access_token=" + token + "&media_id=" + avatar;
            return res;
        } catch (Exception e) {
        }
        return org.apache.commons.lang3.StringUtils.EMPTY;
    }

    public Map<String, ProcessInstanceUserDto> getUserMapByIds(Set<String> staterUsers) {
        List<UserInfo> userInfos = iUserInfoService.listByIds(staterUsers);
        return userInfos.stream().map(u -> {
            ProcessInstanceUserDto userInfo = new ProcessInstanceUserDto();
            userInfo.setUserId(u.getEmployeeCode());
            userInfo.setUserName(u.getRealName());
            // 根据 单位code获取单位名称
            UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(u.getId());
            if (Objects.nonNull(userFullInfo)) {
                userInfo.setOrgCode(userFullInfo.getEmpPosUnitCode());
                userInfo.setOrgName(userFullInfo.getEmpPosUnitName());
            }
            return userInfo;
        }).collect(Collectors.toMap((ProcessInstanceUserDto::getUserId), v -> v));
    }

    public Map<String, ProcessInstanceUserDto> getUserMapByEmployeeCode(Set<String> staterUsers) {
        if (CollUtil.isEmpty(staterUsers)) {
            return Collections.emptyMap();
        }
        List<UserInfo> userInfos = iUserInfoService.list(Wrappers.lambdaQuery(UserInfo.class)
                .in(UserInfo::getEmployeeCode, staterUsers));
        if (CollUtil.isEmpty(userInfos)) {
            return Collections.emptyMap();
        }
        return userInfos.stream().map(u -> {
            ProcessInstanceUserDto userInfo = new ProcessInstanceUserDto();
            userInfo.setUserId(u.getEmployeeCode());
            userInfo.setUserName(u.getRealName());
            // 根据 单位code获取单位名称
            UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(u.getId());
            if (Objects.nonNull(userFullInfo)) {
                userInfo.setOrgCode(userFullInfo.getEmpPosUnitCode());
                userInfo.setOrgName(userFullInfo.getEmpPosUnitName());
            }
            return userInfo;
        }).collect(Collectors.toMap((ProcessInstanceUserDto::getUserId), v -> v));
    }

    public ProcessInstanceUserDto getUserInfo(String userId) {
        UserInfo userInfo = iUserInfoService.getById(userId);
        ProcessInstanceUserDto processInstanceUserDto = new ProcessInstanceUserDto();
        processInstanceUserDto.setUserId(String.valueOf(userInfo.getId()));
        processInstanceUserDto.setUserName(userInfo.getRealName());
        // 根据 单位code获取单位名称
        UserFullInfoDTO userFullInfo = userInfoHelper.getUserFullInfo(userInfo.getId());
        if (Objects.nonNull(userFullInfo)) {
            processInstanceUserDto.setOrgCode(userFullInfo.getEmpPosUnitCode());
            processInstanceUserDto.setOrgName(userFullInfo.getEmpPosUnitName());
        }
        return processInstanceUserDto;
    }

    /**
     * 获取当前用户可控角色列表
     *
     * @return
     */
    public List<UserRoleVO> getControlledRoleList() {
        Long userId = LoginUserUtil.getUserId();
        // 装配用户角色信息列表
        List<UserRole> userRoleList = iUserRoleService.list(Wrappers.lambdaQuery(UserRole.class)
                .eq(UserRole::getUserId, userId));

        List<UserRoleVO> controlledRoleVOList = new ArrayList<>();
        List<Long> controlledRoleIdList = new ArrayList<>();
        if (CollUtil.isNotEmpty(userRoleList)) {
            List<Long> roleIdList = userRoleList.stream().map(UserRole::getRoleId).distinct().collect(Collectors.toList());

            List<Role> roleList = iRoleService.list(Wrappers.lambdaQuery(Role.class).in(Role::getId, roleIdList));

            for (Role role : roleList) {
                List<Long> manageRoleIdList = BizUtils.splitToLong(role.getManageRoleIds());
                if (CollUtil.isNotEmpty(manageRoleIdList)) {
                    controlledRoleIdList.addAll(manageRoleIdList);
                }
            }
            controlledRoleIdList = controlledRoleIdList.stream().distinct().collect(Collectors.toList());
            List<Role> controlledRoleList = iRoleService.list(Wrappers.lambdaQuery(Role.class).in(Role::getId, controlledRoleIdList));

            controlledRoleVOList = controlledRoleList.stream().map(r -> {
                UserRoleVO userRoleVO = new UserRoleVO();
                userRoleVO.setId(r.getId());
                userRoleVO.setName(r.getName());
                userRoleVO.setCode(r.getCode());
                return userRoleVO;
            }).collect(Collectors.toList());
        }
        return controlledRoleVOList;
    }

    /**
     * 根据用户名获取
     *
     * @param username /
     * @return /
     */
    public UserFullInfoDTO queryUserInfoInPasswordAuth(String username) {
        // TODO 目前账号密码登陆测试使用 强制用户登录 userId 1L
        UserInfo userInfo = iUserInfoService.getById(username);
        if (Objects.isNull(userInfo)) {
            return null;
        }
        // 返回用户全量信息
        return userInfoHelper.getUserFullInfo(userInfo);
    }

    /**
     * 根据手机号获取
     *
     * @param phoneNo /
     * @return /
     */
    public UserFullInfoDTO queryUserInfoInPhoneNoAuth(String phoneNo) {
        UserInfo userInfo = iUserInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class)
                .eq(UserInfo::getMobile, phoneNo));
        if (Objects.isNull(userInfo)) {
            return null;
        }
        // 返回用户全量信息
        return userInfoHelper.getUserFullInfo(userInfo);
    }

    /**
     * 根据accountId(浙政钉扫码登陆)
     *
     * @param accountId /
     * @return /
     */
    public UserFullInfoDTO queryUserInfoInAccountIdAuth(String accountId) {

        // 获取用户信息
        UserInfo userInfo = iUserInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class)
                .eq(UserInfo::getAccountId, accountId));
        if (Objects.isNull(userInfo)) {
            return null;
        }
        // 返回用户全量信息
        return userInfoHelper.getUserFullInfo(userInfo);
    }

    public UserFullInfoDTO getUserFullInfoByEmployeeCode(String employeeCode) {
        UserInfo userInfo = iUserInfoService.getOne(Wrappers.lambdaQuery(UserInfo.class)
                .eq(UserInfo::getEmployeeCode, employeeCode).last("limit 1"));
        if (Objects.isNull(userInfo)) {
            return null;
        }
        // 返回用户全量信息
        return userInfoHelper.getUserFullInfo(userInfo);
    }

}
