package jnpf.cultivate.utils;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.fastjson.JSON;
import com.fantaibao.permission.handling.PermissionHandling;
import jnpf.authority.mapper.FtbPermissionRoleMapper;
import jnpf.authority.service.FtbPermissionOrganizeService;
import jnpf.authority.utils.PermissionsApplicableObject;
import jnpf.authority.utils.PermissionsUtils;
import jnpf.base.ActionResult;
import jnpf.base.UserInfo;
import jnpf.base.vo.PageListVO;
import jnpf.base.vo.PaginationVO;
import jnpf.config.ConfigValueUtil;
import jnpf.database.util.TenantDataSourceUtil;
import jnpf.exception.LoginException;
import jnpf.model.cultivate.vo.common.InnerPowerPositionVO;
import jnpf.model.cultivate.vo.common.InnerPowerUserVO;
import jnpf.permission.*;
import jnpf.permission.dto.v2.grades.QueryGradeListDTO;
import jnpf.permission.dto.v2.organzie.AuthOrganizeUserNodeDTO;
import jnpf.permission.dto.v2.organzie.QueryOrganizeListTargetTypesDTO;
import jnpf.permission.dto.v2.position.QueryBasePositionBatchDTO;
import jnpf.permission.dto.v2.position.QueryPagePositionDTO;
import jnpf.permission.dto.v2.position.QueryPositionListDetailGradesDTO;
import jnpf.permission.dto.v2.position.QueryPositionUserListDTO;
import jnpf.permission.dto.v2.user.QueryListUserDTO;
import jnpf.permission.dto.v2.user.QueryPageUserDTO;
import jnpf.permission.dto.v2.user.QueryUserBatchDTO;
import jnpf.permission.dto.v2.user.QueryUserBoundDTO;
import jnpf.permission.entity.UserCopyEntity;
import jnpf.permission.entity.UserEntity;
import jnpf.permission.eum.v2.OrganizeCategoryEnums;
import jnpf.permission.model.user.BatchGetUserCopyForm;
import jnpf.permission.model.user.UserInfoVO;
import jnpf.permission.vo.v2.grades.GradeVO;
import jnpf.permission.vo.v2.organzie.OrganizeGeneralDetailVO;
import jnpf.permission.vo.v2.organzie.OrganizeManagerFilterNodeVO;
import jnpf.permission.vo.v2.organzie.OrganizeManagerNodeVO;
import jnpf.permission.vo.v2.organzie.PositionIdBoundOrganizeInfoListVO;
import jnpf.permission.vo.v2.position.*;
import jnpf.permission.vo.v2.user.UserBoundVO;
import jnpf.permission.vo.v2.user.UserPageListVO;
import jnpf.permission.vo.v2.user.UserRelationBaseVO;
import jnpf.personnels.mapper.FtbPersonnelsStaffRosterMapper;
import jnpf.util.StringUtil;
import jnpf.util.UserProvider;
import jnpf.util.data.DataSourceContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

@Slf4j
@Component
public class UserApiV2Util {
    @Autowired
    private V2UserApi v2UserApi;

    @Autowired
    private UserApi userApi;

    @Autowired
    private V2PositionApi v2PositionApi;

    @Autowired
    private V2GradesApi v2GradesApi;

    @Autowired
    private V2OrganizeApi v2OrganizeApi;

    @Autowired
    private PermissionHandling permissionHandling;

    @Autowired
    @Lazy
    private PermissionsUtils permissionsUtils;

    @Autowired
    @Lazy
    private FtbPermissionOrganizeService ftbPermissionOrganizeService;

    @Autowired
    private FtbPersonnelsStaffRosterMapper rosterMapper;

    @Autowired
    private FtbPermissionRoleMapper ftbPermissionRoleMapper;

    @Autowired
    private ConfigValueUtil configValueUtil;

    /**
     * 去掉时间的 小时 分钟秒数 00:00:00
     *
     * @param time
     * @return
     */
    public static Date clearHourMinuteSecond(Date time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(time);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 添加时间 补齐 23:59:59
     *
     * @param time
     * @return
     */
    public static Date addHourMinuteSecond(Date time) {
        Calendar endCalendar = Calendar.getInstance();
        endCalendar.setTime(time);
        endCalendar.set(Calendar.HOUR_OF_DAY, 23);
        endCalendar.set(Calendar.MINUTE, 59);
        endCalendar.set(Calendar.SECOND, 59);
        endCalendar.set(Calendar.MILLISECOND, 999);
        return endCalendar.getTime();
    }


    /**
     * 查询当前登录用户有权限的岗位列表
     *
     * @param tenantId
     * @return
     */
    public InnerPowerPositionVO getPositionListForCurrUser(String tenantId) {
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        InnerPowerPositionVO vo = new InnerPowerPositionVO();
        InnerPowerUserVO innerPowerUserVO = getLoginManagerUserIdsForEncode();
        vo.setCode(innerPowerUserVO.getCode());
        if (innerPowerUserVO.getCode().equals(1)) {

            List<UserBoundVO> userPrimaryBoundBatchReturnList = getUserPrimaryBoundBatchReturnList(innerPowerUserVO.getUserIds(), tenantId);
            if (CollUtil.isEmpty(userPrimaryBoundBatchReturnList)) {
                vo.setIds(new ArrayList<>());
                return vo;
            }

            vo.setIds(uniqueStringList(userPrimaryBoundBatchReturnList.stream().map(UserBoundVO::getPositionId).collect(Collectors.toList())));

        } else if (innerPowerUserVO.getCode().equals(2)) {
            return vo;
        }
        return vo;
    }

    /**
     * 查询当前用户有权限的组织列表
     *
     * @param organizeCategoryEnums
     * @param tenantId
     * @return
     */
    public List<OrganizeGeneralDetailVO> getOrgListForCurrUser(List<OrganizeCategoryEnums> organizeCategoryEnums, String tenantId) {
        return ftbPermissionOrganizeService.authOrganizesByUserBound(organizeCategoryEnums, null, false, false);
    }

    public List<OrganizeManagerFilterNodeVO> getOrgListTreeForCurrUser(List<OrganizeCategoryEnums> organizeCategoryEnums) {
        return ftbPermissionOrganizeService.listOrganizeTreeUsersFilterNodeJson(organizeCategoryEnums, new ArrayList<>(), false, false, false);
    }

    /**
     * 获取当前登录用户是否有全部权限
     *
     * @return true表示有全部权限，false表示没有全部权限
     */
    public boolean hasAllPermission() {
        UserInfo userInfo = UserProvider.getUser();
        if (userInfo.getIsAdministrator()) {
            return true;
        }
        return false;
    }


    public List<String> getTopOrgList(List<OrganizeManagerFilterNodeVO> tree) {
        List<String> ret = new ArrayList<>();
        if (CollUtil.isEmpty(tree)) {
            return ret;
        }
        for (OrganizeManagerFilterNodeVO organizeManagerFilterNodeVO : tree) {
            List<String> topOrg1 = getTopOrg1(organizeManagerFilterNodeVO);
            if (CollUtil.isNotEmpty(topOrg1)) {
                ret.addAll(topOrg1);
            }
        }
        return ret;
    }

    private List<String> getTopOrg1(OrganizeManagerFilterNodeVO vo) {
        List<String> ids = new ArrayList<>();
        if (vo.getIsEnabled()) {
            ids.add(vo.getId());
            return ids;
        }
        List<OrganizeManagerFilterNodeVO> children = vo.getChildren();
        if (CollUtil.isEmpty(children)) {
            return null;
        }
        for (OrganizeManagerFilterNodeVO child : children) {
            List<String> topOrg = getTopOrg1(child);
            if (CollUtil.isNotEmpty(topOrg)) {
                ids.addAll(topOrg);
            }
        }
        return ids;

    }

    /**
     * 查询登录用户的数据权限，返回可以管理的用户列表
     *
     * @return 返回有权限的用户信息
     */

    public InnerPowerUserVO getLoginManagerUserIds() {
        return getLoginManagerUserIdsForEncode();
    }

    /**
     * 根据权限编码查询数据权限
     *
     * @return 返回有权限的用户信息
     */
    public InnerPowerUserVO getLoginManagerUserIdsForEncode() {
        InnerPowerUserVO vo = new InnerPowerUserVO();
        UserInfo userInfo = UserProvider.getUser();
        if (userInfo.getIsAdministrator()) {
            vo.setCode(0);
            return vo;
        }
        try {
            //往header中添加一个字段
            List<String> userIds = permissionHandling.getUserIdsByUserId(userInfo.getUserId());
            // 权限适用范围为全部
            if (userIds == null) {
                vo.setCode(0);
                return vo;
            }
            if (userIds.isEmpty()) {
                vo.setCode(2);
                return vo;
            }
            vo.setCode(1);
            vo.setUserIds(userIds);
        } catch (Exception e) {
            log.error("获取用户权限失败:", e);
            vo.setCode(2);
            return vo;
        }
        return vo;
    }


    /**
     * 根据权限编码查询数据权限配置类型 header 找那个自动取module
     *
     * @return 0-全部  1-所在组织和下级组织员工   2-所在组织员工  3-仅下属  4-指定组织  -1-无效权限信息
     */
    public Integer getPermissionModuleType() {
        UserInfo userInfo = UserProvider.getUser();
        if (userInfo.getIsAdministrator()) {
            return 0;
        }
        try {
            PermissionsApplicableObject res = permissionsUtils.obtainTheScopeOfUserPermissionsEnums(userInfo.getUserId());
            return Integer.valueOf(res.getPermissionsApplicableEnums().getValue());
        } catch (Exception e) {
            return -1;
        }
    }


    /**
     * 分页查询获取所有用户列表
     *
     * @param tenantId
     * @return
     */
    public PageListVO<UserBoundVO> listAllUserForPage(Long pageSize, Long currentPage, String keyWords, String tenantId) {
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        QueryPageUserDTO dto = new QueryPageUserDTO();
        dto.setTenantId(tenantId);
        if (pageSize == null || currentPage == 0) {
            dto.setPageSize(10L);
        } else {
            dto.setPageSize(pageSize);
        }
        if (currentPage == null || currentPage <= 1) {
            dto.setCurrentPage(1L);
        } else {
            dto.setCurrentPage(currentPage);
        }
        if (StringUtil.isNotEmpty(keyWords)) {
            dto.setKeyword(keyWords);
        }

        ActionResult<PageListVO<UserBoundVO>> pageListVOActionResult = v2UserApi.pagePost(dto);
        if (pageListVOActionResult == null) {
            return null;
        }
        return pageListVOActionResult.getData();
    }


    /**
     * 获取当前登录的用户ID
     *
     * @return
     */
    public String getCurrentLoginUserId() {
        return UserProvider.getUser().getUserId();
    }

    /**
     * 获取当前登录的用户ID
     *
     * @return 租户id
     */
    public String getCurrentLoginTenantId() {
        return UserProvider.getUser().getTenantId();
    }

    public PageListVO<UserBoundVO> pageListUserForWhere(QueryPageUserDTO dto) {

        ActionResult<PageListVO<UserBoundVO>> pageListVOActionResult = v2UserApi.pagePost(dto);
        if (pageListVOActionResult == null) {
            return null;
        }
        return pageListVOActionResult.getData();
    }

    /**
     * 获取当前登录用户是否有全部权限
     *
     * @return true表示继续，false表示不继续
     */
    public boolean checkIsContinue(List<String> list) {
        if (CollUtil.isEmpty(list)) {
            return true;
        }
        if (list.size() == 1 && "-1".equals(list.get(0))) {
            return false;
        }
        return true;
    }

    /**
     * 根据用户ids批量查询用户信息、组织、岗位、职级
     * 此方法适用于需要获取多个用户详细信息的场景，通过用户ID列表作为参数，
     * 返回一个映射，其中每个用户ID对应一个包含用户详细信息的UserPrimaryBoundVO对象
     *
     * @param userIds 用户ID列表，用于查询用户信息
     * @return 返回一个Map，键为用户ID，值为对应的UserPrimaryBoundVO对象
     */
    public Map<String, UserBoundVO> getUserPrimaryBoundBatch(List<String> userIds, String tenantId) {
        Map<String, UserBoundVO> map = new HashMap<>();
        if (CollUtil.isEmpty(userIds)) {
            return map;
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<UserBoundVO>> userPrimaryBoundBatch = v2UserApi.getUserPrimaryBoundBatch(userIds, tenantId);
        if (userPrimaryBoundBatch == null || CollUtil.isEmpty(userPrimaryBoundBatch.getData())) {
            return map;
        }
        for (UserBoundVO userPrimaryBoundVO : userPrimaryBoundBatch.getData()) {
            map.put(userPrimaryBoundVO.getId(), userPrimaryBoundVO);
        }
        return map;
    }

    public List<UserBoundVO> getAllUserList(String tenantId) {
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        QueryUserBatchDTO dto = new QueryUserBatchDTO();
        dto.setTenantId(tenantId);
        ActionResult<List<UserBoundVO>> listActionResult = v2UserApi.getUserInfoBatch(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    public List<UserBoundVO> getAllUserListPage(String tenantId) {
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        QueryUserBatchDTO dto = new QueryUserBatchDTO();
        dto.setTenantId(tenantId);
        ActionResult<List<UserBoundVO>> listActionResult = v2UserApi.getUserInfoBatch(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据用户名或者手机号查询用户
     *
     * @param userName
     * @param mobilePhone
     * @param tenantId
     * @return
     */

    public List<UserPageListVO> getUserForNameOrPhone(String userName, String mobilePhone, String tenantId) {
        QueryListUserDTO dto = new QueryListUserDTO();
        if (StringUtil.isEmpty(userName) && StringUtil.isEmpty(mobilePhone)) {
            return new ArrayList<>();
        }
        if (StringUtil.isNotEmpty(userName)) {
            dto.setUserName(userName);
        }
        if (StringUtil.isNotEmpty(mobilePhone)) {
            dto.setMobilePhone(mobilePhone);
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        dto.setTenantId(tenantId);
        ActionResult<List<UserPageListVO>> listActionResult = v2UserApi.listUser(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    public List<UserPageListVO> searchUser(QueryListUserDTO dto) {
        ActionResult<List<UserPageListVO>> listActionResult = v2UserApi.listUser(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据用户ids批量查询用户信息、组织、岗位、职级 返回list
     * 此方法适用于需要获取多个用户详细信息的场景，通过用户ID列表作为参数，
     * 返回一个映射，其中每个用户ID对应一个包含用户详细信息的UserPrimaryBoundVO对象
     *
     * @param userIds 用户ID列表，用于查询用户信息
     * @return 返回一个list
     */
    public List<UserBoundVO> getUserPrimaryBoundBatchReturnList(List<String> userIds, String tenantId) {
        if (CollUtil.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<UserBoundVO>> userPrimaryBoundBatch = v2UserApi.getUserPrimaryBoundBatch(userIds, tenantId);
        if (userPrimaryBoundBatch == null || CollUtil.isEmpty(userPrimaryBoundBatch.getData())) {
            return new ArrayList<>();
        }
        return userPrimaryBoundBatch.getData();
    }

    /**
     * 获取用户的主要绑定信息之一
     * 该方法用于调用API接口，获取指定用户的主要绑定信息，如果用户ID为空或API调用失败，将返回null
     *
     * @param userId 用户ID，用于查询用户的主要绑定信息
     * @return UserBoundVO 返回用户的绑定信息对象，如果没有找到或发生错误，则返回null
     */
    public UserBoundVO getUserPrimaryBoundOne(String userId, String tenantId) {

        if (StringUtil.isEmpty(userId)) {
            return null;
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<UserBoundVO>> userPrimaryBoundBatch = v2UserApi.getUserPrimaryBoundBatch(List.of(userId), tenantId);
        if (userPrimaryBoundBatch == null || CollUtil.isEmpty(userPrimaryBoundBatch.getData())) {
            return null;
        }
        return userPrimaryBoundBatch.getData().get(0);
    }

    /**
     * 根据用户ids批量查询用户信息、组织、岗位、职级
     * 与上一个方法不同的是，这个方法返回的映射中，每个用户ID对应的是一个UserPrimaryBoundVO对象列表
     * 这种设计是为了在将来可能的扩展性，比如一个用户可能属于多个组织或岗位的情况
     *
     * @param userIds 用户ID列表，用于查询用户信息
     * @return 返回一个Map，键为用户ID，值为一个列表，包含对应的UserPrimaryBoundVO对象
     */
    public Map<String, List<UserBoundVO>> getUserPrimaryBoundBatchCompatible(List<String> userIds, String tenantId) {
        Map<String, List<UserBoundVO>> map = new HashMap<>();
        if (CollUtil.isEmpty(userIds)) {
            return map;
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<UserBoundVO>> userPrimaryBoundBatch = v2UserApi.getUserPrimaryBoundBatch(userIds, tenantId);
        if (userPrimaryBoundBatch == null || CollUtil.isEmpty(userPrimaryBoundBatch.getData())) {
            return map;
        }
        for (UserBoundVO userPrimaryBoundVO : userPrimaryBoundBatch.getData()) {
            map.put(userPrimaryBoundVO.getId(), List.of(userPrimaryBoundVO));
        }
        return map;
    }


    /**
     * 根据用户ids批量查询用户信息、组织、岗位、职级
     * 与上一个方法不同的是，这个方法返回的映射中，每个用户ID对应的是一个UserPrimaryBoundVO对象列表
     * 这种设计是为了在将来可能的扩展性，比如一个用户可能属于多个组织或岗位的情况
     *
     * @param userIds 用户ID列表，用于查询用户信息
     * @return 返回一个Map，键为用户ID，值为一个列表，包含对应的UserPrimaryBoundVO对象
     */
    public Map<String, UserBoundVO> getUserPrimaryBoundBatchReturnMap(List<String> userIds, String tenantId) {
        Map<String, UserBoundVO> map = new HashMap<>();
        if (CollUtil.isEmpty(userIds)) {
            return map;
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<UserBoundVO>> userPrimaryBoundBatch = v2UserApi.getUserPrimaryBoundBatch(userIds, tenantId);
        if (userPrimaryBoundBatch == null || CollUtil.isEmpty(userPrimaryBoundBatch.getData())) {
            return map;
        }
        for (UserBoundVO userPrimaryBoundVO : userPrimaryBoundBatch.getData()) {
            map.put(userPrimaryBoundVO.getId(), userPrimaryBoundVO);
        }
        return map;
    }

    /**
     * 根据组织ID列表获取用户列表
     * <p>
     * 此方法旨在通过提供的组织ID列表，调用API接口以获取相关的用户列表
     * 它首先检查输入的组织ID列表是否为空，如果为空，则直接返回一个空的用户列表
     * 接着，它调用V2用户API中的方法来获取与指定组织ID相关的用户列表
     * 最后，检查API返回的结果是否为空，如果为空或不存在，则返回空用户列表；
     * 否则，返回获取到的用户列表
     *
     * @param orgIds 组织ID列表，用于查询用户信息
     * @return 用户列表，包含与指定组织ID相关的用户信息
     */
    public List<UserPageListVO> getUserListForOrgIds(List<String> orgIds, String tenantId) {
        List<UserPageListVO> userList = new ArrayList<>();
        if (CollUtil.isEmpty(orgIds)) {
            return userList;
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<UserPageListVO>> listActionResult = v2UserApi.listTargetOrganizes(orgIds, tenantId, null);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return userList;
        }
        return listActionResult.getData();
    }

    /**
     * 查询所有组织并返回树结构
     *
     * @param tenantId 租户ID
     * @return 组织树结构
     */
    public List<OrganizeManagerNodeVO> queryAllOrgReturnTree(String tenantId) {
        AuthOrganizeUserNodeDTO dto = new AuthOrganizeUserNodeDTO();
        dto.setHavaAuth(false);
        dto.setHaveUsers(false);
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        dto.setTenantId(tenantId);
        String s = v2OrganizeApi.listOrganizeTreeUsersJson(dto);

        if (StringUtil.isEmpty(s)) {
            return new ArrayList<>();
        }
        try {
            return JSON.parseArray(s, OrganizeManagerNodeVO.class);
        } catch (Exception e) {
            log.error("JSON.parseArray error", e);
        }
        return new ArrayList<>();
    }

    /**
     * 根据组织ID列表获取用户列表，并按组织ID分组返回Map
     *
     * @param orgIds   组织ID列表
     * @param tenantId 租户ID，如果为空则使用当前用户所属租户
     * @return 以组织ID为key，该组织下用户列表为value的Map
     */
    public Map<String, List<UserPageListVO>> getUserListForOrgIdsReturnMap(List<String> orgIds, String tenantId) {

        if (CollUtil.isEmpty(orgIds)) {
            return new HashMap<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<UserPageListVO>> listActionResult = v2UserApi.listTargetOrganizes(orgIds, tenantId, null);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new HashMap<>();
        }
        return listActionResult.getData().stream().collect(Collectors.groupingBy(UserPageListVO::getOrganizeId));
    }

    /**
     * 将用户列表转换为组织ID到用户数量的映射
     *
     * @param list 用户列表
     * @return 以组织ID为key，该组织下用户数量为value的Map
     */
    public Map<String, Long> convertUserCount(List<UserPageListVO> list) {

        // 如果用户列表为空，直接返回一个空的Map
        if (CollUtil.isEmpty(list)) {
            return new HashMap<>();
        }

        // 使用 stream 直接分组并统计数量
        // 这里通过组织ID进行分组，并计算每个组的数量，结果是一个Map，键是组织ID，值是用户数量
        return list.stream().collect(
                Collectors.groupingBy(
                        UserPageListVO::getOrganizeId,
                        HashMap::new,
                        Collectors.summingLong(v -> 1)
                )
        );
    }

    /**
     * 将用户列表转换为组织ID到用户ID列表的映射
     *
     * @param userList 用户列表
     * @return 以组织ID为key，该组织下用户ID列表为value的Map
     */
    public Map<String, List<String>> convertUserIdList(List<UserPageListVO> userList) {
        Map<String, List<String>> map = new HashMap<>();
        // 如果用户列表为空，直接返回一个空的Map
        if (CollUtil.isEmpty(userList)) {
            return map;
        }
        for (UserPageListVO userPageListVO : userList) {
            List<String> strings = map.get(userPageListVO.getOrganizeId());
            if (CollUtil.isEmpty(strings)) {
                strings = new ArrayList<>();
            }
            strings.add(userPageListVO.getId());
            map.put(userPageListVO.getOrganizeId(), strings);
        }
        return map;
    }

    /**
     * 根据组织id查询用户列表【是否查询下级组织的人员】
     *
     * @param orgIds            组织ID列表
     * @param haveOrganizeChild true-查询该组织及下级组织所有用户， false-只查询直接组织的用户
     * @param tenantId          租户ID，如果为空则使用当前用户所属租户
     * @return 组织下的用户列表
     */
    public List<UserBoundVO> listTargetOrganizesOrHaveChild(List<String> orgIds, Boolean haveOrganizeChild, String tenantId) {
        List<UserBoundVO> userList = new ArrayList<>();
        if (CollUtil.isEmpty(orgIds)) {
            return userList;
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<UserBoundVO>> listActionResult = v2UserApi.listTargetOrganizesOrHaveChild(orgIds, haveOrganizeChild, null, tenantId);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return userList;
        }
        return listActionResult.getData();
    }


    /**
     * 获取下属目标用户列表
     * <p>
     * 该方法旨在查询与给定用户ID关联的所有下属用户信息这些用户被视为目标用户，
     * 通常用于管理或数据展示场景中此方法首先检查输入的用户ID是否为空，
     * 如果为空则直接返回一个空的用户列表如果用户ID有效，它将调用一个API来获取用户列表，
     * 并在列表为空或获取失败时返回空列表
     *
     * @param userId 用户ID，用于查询其下属目标用户
     * @return 包含下属目标用户的列表如果输入无效或查询无结果，则返回空列表
     */
    public List<UserPageListVO> listUnderlingTargetUser(String userId, String tenantId) {
        List<UserPageListVO> userList = new ArrayList<>();
        if (StringUtil.isEmpty(userId)) {
            return userList;
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<UserPageListVO>> listActionResult = v2UserApi.listUnderlingTargetUser(userId, tenantId);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return userList;
        }
        return listActionResult.getData();
    }

    /**
     * 根据用户id查询直属领导
     *
     * @param userId   用户id
     * @param tenantId 租户ID，如果为空则使用当前用户所属租户
     * @return 用户的直属领导信息，如果未找到则返回null
     */
    public UserInfoVO getBossByUserId(String userId, String tenantId) {
        if (StringUtil.isEmpty(userId)) {
            return null;
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<UserBoundVO>> listActionResult = v2UserApi.getUserPrimaryBoundBatch(List.of(userId), tenantId);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return null;
        }
        UserBoundVO userBoundVO = listActionResult.getData().get(0);
        ActionResult<UserInfoVO> info = userApi.getInfo(userBoundVO.getLeaderId());
        if (info == null || info.getData() == null) {
            return null;
        }

        return info.getData();
    }

    /**
     * 根据用户id查询用户绑定信息（包含直属领导信息）
     *
     * @param userId   用户id
     * @param tenantId 租户ID，如果为空则使用当前用户所属租户
     * @return 用户绑定信息，包含直属领导信息，如果未找到则返回null
     */
    public UserBoundVO getBossByUserIdSimple(String userId, String tenantId) {
        if (StringUtil.isEmpty(userId)) {
            return null;
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<UserBoundVO>> listActionResult = v2UserApi.getUserPrimaryBoundBatch(List.of(userId), tenantId);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return null;
        }
        return listActionResult.getData().get(0);

    }

    /**
     * 根据岗位id查询用户列表
     * 此方法用于批量查询与给定岗位ID列表相关的用户信息
     * 它首先检查岗位ID列表是否为空，如果为空，则直接返回一个空列表
     * 然后，它构造一个查询条件对象，包括岗位ID和租户ID，然后调用API获取用户信息
     * 如果API调用结果为空或不包含数据，则返回一个空列表，否则返回查询到的用户列表
     *
     * @param positionIds 岗位ID列表，用于查询用户信息
     * @return 用户信息列表，如果查询失败或无数据，则返回空列表
     */
    public List<UserBoundVO> getUserListForPositions(List<String> positionIds, String tenantId) {
        if (StringUtil.isEmpty(positionIds)) {
            return new ArrayList<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        QueryUserBatchDTO dto = new QueryUserBatchDTO();
        dto.setPositionIds(positionIds);
        dto.setTenantId(tenantId);
        ActionResult<List<UserBoundVO>> listActionResult = v2UserApi.getUserInfoBatch(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据岗位名称查询用户列表
     *
     * @param positionName 岗位名称
     * @return 用户信息列表，如果查询失败或无数据，则返回空列表
     */
    public List<UserRelationBaseVO> getUserListForPositionName(String positionName, String tenantId) {
        if (StringUtil.isEmpty(positionName)) {
            return new ArrayList<>();
        }
        QueryUserBoundDTO dto = new QueryUserBoundDTO();
        dto.setPositionName(positionName);
        ActionResult<List<UserRelationBaseVO>> listActionResult = v2UserApi.listUserBound(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据组织id 和 岗位id 查询用户列表
     *
     * @param orgId      组织id
     * @param positionId 岗位id
     * @return 用户信息列表，如果查询失败或无数据，则返回空列表
     */
    public List<UserRelationBaseVO> getUserListForOrgIdAndPositionId(String orgId, String positionId, String tenantId) {

        QueryUserBoundDTO dto = new QueryUserBoundDTO();
        dto.setOrganizeId(orgId);
        dto.setPositionId(positionId);
        ActionResult<List<UserRelationBaseVO>> listActionResult = v2UserApi.listUserBound(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }


    /**
     * 根据岗位id查询岗位信息
     *
     * @param positionId 岗位id
     */
    public PositionVO infoPosition(String positionId, String tenantId) {
        if (StringUtil.isEmpty(positionId)) {
            return null;
        }
        ActionResult<PositionVO> positionVOActionResult = v2PositionApi.infoPosition(positionId);
        if (positionVOActionResult == null || positionVOActionResult.getData() == null) {
            return null;
        }
        return positionVOActionResult.getData();
    }

    /**
     * 根据组织id查询岗位信息列表
     *
     * @param orgIds   组织id集合
     * @param tenantId 租户id，如果为空则使用当前用户所属租户
     * @return 组织下的岗位信息列表
     */
    public List<PositionBaseInfoVO> listPositionBaseInfoByIds(List<String> orgIds, String tenantId) {
        if (CollUtil.isEmpty(orgIds)) {
            return new ArrayList<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        QueryBasePositionBatchDTO dto = new QueryBasePositionBatchDTO();
        dto.setOrganizeIds(orgIds);
        dto.setTenantId(tenantId);

        ActionResult<List<PositionBaseInfoVO>> listActionResult = v2PositionApi.listPositionBaseInfo(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据组织id查询岗位信息列表
     *
     * @param orgId    组织id
     * @param tenantId 租户id，如果为空则使用当前用户所属租户
     * @return 组织下的岗位信息列表
     */
    public List<PositionBaseInfoVO> listPositionBaseInfoById(String orgId, String tenantId) {
        if (StringUtil.isEmpty(orgId)) {
            return new ArrayList<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        QueryBasePositionBatchDTO dto = new QueryBasePositionBatchDTO();
        dto.setOrganizeIds(List.of(orgId));
        dto.setTenantId(tenantId);

        ActionResult<List<PositionBaseInfoVO>> listActionResult = v2PositionApi.listPositionBaseInfo(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据组织id查询岗位信息列表 返回map
     *
     * @param orgIds   组织id集合
     * @param tenantId 租户id，如果为空则使用当前用户所属租户
     * @return 以组织ID为key，岗位信息列表为value的Map
     */
    public Map<String, List<PositionBaseInfoVO>> listPositionBaseInfoByIdsReturnMap(List<String> orgIds, String tenantId) {
        if (CollUtil.isEmpty(orgIds)) {
            return new HashMap<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }

        Map<String, List<PositionBaseInfoVO>> map = new HashMap<>();
        for (String orgId : orgIds) {
            List<PositionBaseInfoVO> positionBaseInfoVOS = listPositionBaseInfoById(orgId, tenantId);
            map.put(orgId, positionBaseInfoVOS);
        }
        return map;
    }

    /**
     * 根据组织id查询岗位信息列表 返回 key=组织id  value-岗位id列表
     *
     * @param orgIds   组织id集合
     * @param tenantId 租户id
     * @return 返回组织id 为key，value 是岗位id列表
     */
    public Map<String, List<String>> listPositionBaseInfoByIdsReturnMapSimple(List<String> orgIds, String tenantId) {
        if (CollUtil.isEmpty(orgIds)) {
            return new HashMap<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        Map<String, List<PositionBoundOrganizeVO>> stringListMap = batchQueryPositionForOrgIdsReturnMap(orgIds, tenantId);
        if (stringListMap.isEmpty()) {
            return new HashMap<>();
        }
        Map<String, List<String>> map = new HashMap<>();
        for (String s : stringListMap.keySet()) {
            map.put(s, stringListMap.get(s).stream().map(PositionBoundOrganizeVO::getId).collect(Collectors.toList()));
        }
        return map;
    }

    /**
     * 根据岗位ids查询岗位信息
     *
     * @param positionIds 岗位id集合
     */
    public List<PositionVO> listPositionDetailInfoByIds(List<String> positionIds, String tenantId) {
        if (CollUtil.isEmpty(positionIds)) {
            return new ArrayList<>();
        }
        ActionResult<List<PositionVO>> listActionResult = v2PositionApi.listPositionDetailInfo(positionIds);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据岗位ids查询岗位信息
     *
     * @param positionIds 岗位id集合
     * @return map<岗位id ， 岗位信息>
     */
    public Map<String, PositionVO> listPositionDetailInfoByIdsReturnMap(List<String> positionIds, String tenantId) {
        Map<String, PositionVO> map = new HashMap<>();
        if (CollUtil.isEmpty(positionIds)) {
            return map;
        }
        ActionResult<List<PositionVO>> listActionResult = v2PositionApi.listPositionDetailInfo(positionIds);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return map;
        }
        return listActionResult.getData().stream().collect(Collectors.toMap(PositionVO::getId, item -> item));
    }

    /**
     * 根据岗位名称模糊匹配岗位列表
     *
     * @param positionName 岗位名称
     * @param tenantId     租户id，如果为空则使用当前用户所属租户
     * @return 匹配的岗位及职级信息列表
     */
    public List<PositionAndGradesVO> likeQueryPositionForPositionName(String positionName, String tenantId) {
        if (StringUtil.isEmpty(positionName)) {
            return new ArrayList<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        QueryPositionListDetailGradesDTO dto = new QueryPositionListDetailGradesDTO();
        dto.setLikePositionName(positionName);
        dto.setIsAll(false);
        dto.setTenantId(tenantId);
        ActionResult<List<PositionAndGradesVO>> listActionResult = v2PositionApi.listPositionDetailGradesConcreteInfo(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 分页查询岗位列表
     *
     * @param dto      查询岗位的分页参数
     * @param tenantId 租户id，如果为空则使用当前用户所属租户
     * @return 岗位列表的分页结果
     */
    public ActionResult<PageListVO<PositionAndGradesVO>> pageIncludingRankPositions(QueryPagePositionDTO dto, String tenantId) {
        return v2PositionApi.pageIncludingRankPositions(dto);
    }

    /**
     * 根据编码列表查询岗位信息列表
     *
     * @param positionEncodeLists 岗位编码列表
     * @param tenantId            租户id，如果为空则使用当前用户所属租户
     * @return 岗位信息列表
     */
    public List<PositionBaseInfoVO> listPositionBaseInfoByEncodes(List<String> positionEncodeLists, String tenantId) {
        if (StringUtil.isEmpty(positionEncodeLists)) {
            return new ArrayList<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }

        ActionResult<List<PositionBaseInfoVO>> listActionResult = v2PositionApi.listPositionBaseInfoByEncodes(positionEncodeLists, tenantId);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据组织编码列表查询组织信息列表
     *
     * @param OrgEncodeLists 组织编码列表
     * @param tenantId       租户id，如果为空则使用当前用户所属租户
     * @return 组织信息列表
     */
    public List<OrganizeGeneralDetailVO> organizesOrHaveChildByOrganizeEncodes(List<String> OrgEncodeLists, String tenantId) {
        if (StringUtil.isEmpty(OrgEncodeLists)) {
            return new ArrayList<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }

        ActionResult<List<OrganizeGeneralDetailVO>> listActionResult = v2OrganizeApi.organizesOrHaveChildByOrganizeEncodes(OrgEncodeLists, false, tenantId);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据组织ID列表批量查询岗位列表
     *
     * @param orgIds   组织ID列表
     * @param tenantId 租户ID，如果为空则使用当前用户所属租户
     * @return 组织id为key，岗位绑定组织信息列表为value的Map
     */
    public Map<String, List<PositionBoundOrganizeVO>> batchQueryPositionForOrgIdsReturnMap(List<String> orgIds, String tenantId) {
        if (StringUtil.isEmpty(orgIds)) {
            return new HashMap<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<PositionBoundOrganizeVO>> listActionResult = v2PositionApi.listPositionBoundInfoOrganizeIds(orgIds, tenantId);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new HashMap<>();
        }
        return listActionResult.getData().stream().collect(Collectors.groupingBy(PositionBoundOrganizeVO::getOrganizeId));
    }

    /**
     * 根据组织ID列表批量查询岗位绑定的组织信息
     *
     * @param orgIds   组织ID列表
     * @param tenantId 租户ID，如果为空则使用当前用户所属租户
     * @return 岗位绑定组织信息列表
     */
    public List<PositionBoundOrganizeVO> batchQueryPositionForOrgIdsReturnList(List<String> orgIds, String tenantId) {
        if (StringUtil.isEmpty(orgIds)) {
            return new ArrayList<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<PositionBoundOrganizeVO>> listActionResult = v2PositionApi.listPositionBoundInfoOrganizeIds(orgIds, tenantId);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据岗位id查询职级信息
     *
     * @param gradeId  职级id
     * @param tenantId 租户id
     * @return 指定岗位下的职级列表
     */
    public GradeVO infoGrade(String gradeId, String tenantId) {
        if (StringUtil.isEmpty(gradeId)) {
            return null;
        }
        ActionResult<GradeVO> result = v2GradesApi.infoGrade(gradeId);
        if (result == null || result.getData() == null) {
            return null;
        }
        return result.getData();
    }


    /**
     * 根据职级ids查询职级信息
     *
     * @param gradeIds 职级ids集合
     * @param tenantId 租户id
     * @return 职级信息列表
     */
    public List<GradeVO> listGradeByIds(List<String> gradeIds, String tenantId) {
        if (CollUtil.isEmpty(gradeIds)) {
            return new ArrayList<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<GradeVO>> listActionResult = v2GradesApi.listGradeByIds(gradeIds, tenantId);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据职级ids查询职级信息返回map
     *
     * @param gradeIds 职级ids集合
     * @param tenantId 租户id
     * @return 职级信息列表
     */
    public Map<String, GradeVO> listGradeByIdsReturnMap(List<String> gradeIds, String tenantId) {
        List<GradeVO> gradeVOS = listGradeByIds(gradeIds, tenantId);
        return gradeVOS.stream().collect(Collectors.toMap(GradeVO::getId, gradeVO -> gradeVO));
    }

    /**
     * 根据岗位名称查询所有岗位信息
     *
     * @param tenantId 租户id
     * @return 岗位信息列表
     */
    public List<PositionAndGradesVO> listAllPositionAndGradesByPositionName(String tenantId) {

        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        QueryPositionListDetailGradesDTO dto = new QueryPositionListDetailGradesDTO();
        dto.setIsAll(true);
        dto.setTenantId(tenantId);
        ActionResult<List<PositionAndGradesVO>> listActionResult = v2PositionApi.listPositionDetailGradesConcreteInfo(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据岗位ids 查询岗位 及岗位下的职级信息
     *
     * @param tenantId 租户id
     * @return 岗位信息列表
     */
    public List<PositionAndGradesVO> listPositionAndGradeByPositionIds(List<String> positionIds, String tenantId) {

        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        QueryPositionListDetailGradesDTO dto = new QueryPositionListDetailGradesDTO();
        dto.setIsAll(false);
        dto.setTenantId(tenantId);
        dto.setPositionIds(positionIds);
        ActionResult<List<PositionAndGradesVO>> listActionResult = v2PositionApi.listPositionDetailGradesConcreteInfo(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据岗位id查询岗位下的用户列表
     *
     * @param positionIds 岗位id集合
     * @param tenantId    租户id
     */
    public Map<String, PositionListUserVO> listPositionTreeUser(List<String> positionIds, String tenantId) {
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        Map<String, PositionListUserVO> map = new HashMap<>(); //岗位id的map
        QueryPositionUserListDTO dto = new QueryPositionUserListDTO();
        dto.setTenantId(tenantId);
        dto.setPositionIds(positionIds);
        ActionResult<List<PositionListUserVO>> listActionResult = v2PositionApi.listPositionTreeUser(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return map;
        }
        return listActionResult.getData().stream().collect(Collectors.toMap(PositionListUserVO::getId, item -> item));

    }

    /**
     * 根据组织id查询岗位和职级信息
     *
     * @param orgId    组织id
     * @param tenantId 租户id
     * @return 岗位列表
     */
    public List<PositionAndGradesVO> listPositionAndGradesByPositionNameForOrgIds(String orgId, String tenantId) {

        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        List<PositionBaseInfoVO> positionBaseInfoVOS = listPositionBaseInfoByIds(Collections.singletonList(orgId), tenantId);
        if (CollUtil.isEmpty(positionBaseInfoVOS)) {
            return new ArrayList<>();
        }
        QueryPositionListDetailGradesDTO dto = new QueryPositionListDetailGradesDTO();
        dto.setPositionIds(positionBaseInfoVOS.stream().map(PositionBaseInfoVO::getId).collect(Collectors.toList()));
        dto.setIsAll(false);
        dto.setTenantId(tenantId);
        ActionResult<List<PositionAndGradesVO>> listActionResult = v2PositionApi.listPositionDetailGradesConcreteInfo(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据岗位id查询职级信息
     *
     * @param positionId 岗位id
     * @param tenantId   租户id
     * @return 岗位下的职级列表
     */
    public List<GradeVO> listGrades(String positionId, String tenantId) {
        if (StringUtil.isEmpty(positionId)) {
            return new ArrayList<>();
        }

        QueryGradeListDTO req = new QueryGradeListDTO();
        req.setPositionId(positionId);
        ActionResult<List<GradeVO>> listActionResult = v2GradesApi.listGrades(req);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }


    /**
     * 根据组织id查询组织详细
     *
     * @param orgId    组织id
     * @param tenantId 租户id
     * @return 组织详情信息
     */
    public OrganizeGeneralDetailVO organizeInfoById(String orgId, String tenantId) {
        if (StringUtil.isEmpty(orgId)) {
            return null;
        }
        ActionResult<OrganizeGeneralDetailVO> listActionResult = v2OrganizeApi.organizeInfoById(null, orgId);
        if (listActionResult == null || listActionResult.getData() == null) {
            return null;
        }
        return listActionResult.getData();
    }

    /**
     * 根据组织id查询组织详细列表
     *
     * @param orgIds   组织id集合
     * @param tenantId 租户id
     * @return 组织详情列表
     */
    public List<OrganizeGeneralDetailVO> organizesByOrganizeIds(List<String> orgIds, String tenantId) {
        if (CollUtil.isEmpty(orgIds)) {
            return new ArrayList<>();
        }
        ActionResult<List<OrganizeGeneralDetailVO>> listActionResult = v2OrganizeApi.organizesByOrganizeIds(orgIds);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据组织id查询组织详细列表
     *
     * @param orgIds   组织id集合
     * @param tenantId 租户id
     * @return 以组织ID为键，组织详情为值的映射表
     */
    public Map<String, OrganizeGeneralDetailVO> organizesByOrganizeIdsReturenMap(List<String> orgIds, String tenantId) {
        if (CollUtil.isEmpty(orgIds)) {
            return new HashMap<>();
        }
        ActionResult<List<OrganizeGeneralDetailVO>> listActionResult = v2OrganizeApi.organizesByOrganizeIds(orgIds);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new HashMap<>();
        }
        return listActionResult.getData().stream().collect(Collectors.toMap(OrganizeGeneralDetailVO::getId, item -> item));
    }

    /**
     * 根据组织id查询组织详细列表
     *
     * @param orgIds            组织id集合
     * @param haveOrganizeChild 是否包含下级组织 true-包含 false-不包含
     * @param tenantId          租户id
     * @return 组织列表
     */
    public List<OrganizeGeneralDetailVO> organizesOrHaveChildByOrganizeIds(List<String> orgIds, Boolean haveOrganizeChild, String tenantId) {
        if (CollUtil.isEmpty(orgIds)) {
            return new ArrayList<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<OrganizeGeneralDetailVO>> listActionResult = v2OrganizeApi.organizesOrHaveChildByOrganizeIds(orgIds, haveOrganizeChild, tenantId);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }

    /**
     * 根据组织id查询直接下级组织列表
     *
     * @param orgIds            组织id集合
     * @param haveOrganizeChild 是否包含下级组织 true-包含 false-不包含
     * @param tenantId          租户id
     * @return 组织ids列表
     */
    public List<String> queryChildOrgForOrgIdsReturnOrgIds(List<String> orgIds, Boolean haveOrganizeChild, String tenantId) {
        if (CollUtil.isEmpty(orgIds)) {
            return new ArrayList<>();
        }
        if (StringUtil.isEmpty(tenantId)) {
            tenantId = getCurrentLoginTenantId();
        }
        ActionResult<List<OrganizeGeneralDetailVO>> listActionResult = v2OrganizeApi.organizesOrHaveChildByOrganizeIds(orgIds, haveOrganizeChild, tenantId);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData().stream().map(OrganizeGeneralDetailVO::getId).collect(Collectors.toList());
    }

    /**
     * 根据组织id查询 直接下级组织列表
     *
     * @param orgId    组织id
     * @param tenantId 租户id
     * @return 直接下级组织列表
     */
    public List<OrganizeGeneralDetailVO> organizeNextLevel(String orgId, String tenantId) {
        if (StringUtil.isEmpty(orgId)) {
            return new ArrayList<>();
        }
        ActionResult<List<OrganizeGeneralDetailVO>> listActionResult = v2OrganizeApi.organizeNextLevel(List.of(orgId));
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();

    }

    /**
     * 根据组织id查询 直接下级组织列表
     *
     * @param orgIds   组织id
     * @param tenantId 租户id
     * @return 直接下级组织列表
     */
    public List<OrganizeGeneralDetailVO> batchOrganizeNextLevel(List<String> orgIds, String tenantId) {
        if (CollUtil.isEmpty(orgIds)) {
            return new ArrayList<>();
        }
        ActionResult<List<OrganizeGeneralDetailVO>> listActionResult = v2OrganizeApi.organizeNextLevel(orgIds);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();

    }


    /**
     * 根据条件获取组织列表
     *
     * @param orgName  组织名称
     * @param orgIds   组织id
     * @param tenantId 租户id
     */
    public List<OrganizeGeneralDetailVO> getOrgListByWhere(String orgName, List<String> orgIds, List<OrganizeCategoryEnums> organizeCategoryEnums, String tenantId) {
        QueryOrganizeListTargetTypesDTO dto = new QueryOrganizeListTargetTypesDTO();

        if (StringUtil.isNotEmpty(orgName)) {
            dto.setOrganizeName(orgName);
        }
        if (CollUtil.isNotEmpty(orgIds)) {
            dto.setOrganizeIds(orgIds);
        }
        if (CollUtil.isNotEmpty(organizeCategoryEnums)) {
            dto.setOrganizeCategoryEnums(organizeCategoryEnums);
        } else {
            dto.setOrganizeCategoryEnums(List.of(OrganizeCategoryEnums.COMPANY, OrganizeCategoryEnums.DEPARTMENT, OrganizeCategoryEnums.STORE, OrganizeCategoryEnums.TEAM));
        }
        ActionResult<List<OrganizeGeneralDetailVO>> listActionResult = v2OrganizeApi.listOrganizeByTargetTypes(dto);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult.getData())) {
            return new ArrayList<>();
        }
        return listActionResult.getData();
    }


    /**
     * 根据岗位ids查询组织ids
     *
     * @param positionIds
     * @param tenantId    返回组织列表
     */
    public List<OrganizeGeneralDetailVO> organizeInfoListByPositionIds(List<String> positionIds, String tenantId) {
        if (StringUtil.isEmpty(positionIds)) {
            return new ArrayList<>();
        }
        List<OrganizeGeneralDetailVO> listActionResult = v2OrganizeApi.organizeInfoListByPositionIds(positionIds);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult)) {
            return new ArrayList<>();
        }
        return listActionResult;
    }

    /**
     * 根据岗位ids查询组织信息，返回 Map<岗位id, List<组织信息>>
     *
     * @param positionIds
     * @param tenantId
     * @return Map<岗位id, List < 组织信息>>
     */
    public Map<String, List<OrganizeGeneralDetailVO>> organizeInfoBoundListByPositionIds(List<String> positionIds, String tenantId) {
        if (StringUtil.isEmpty(positionIds)) {
            return new HashMap<>();
        }
        List<PositionIdBoundOrganizeInfoListVO> listActionResult = v2OrganizeApi.organizeInfoBoundListByPositionIds(positionIds);
        if (listActionResult == null || CollUtil.isEmpty(listActionResult)) {
            return new HashMap<>();
        }
        Map<String, List<OrganizeGeneralDetailVO>> map = new HashMap<>();
        for (PositionIdBoundOrganizeInfoListVO positionIdBoundOrganizeInfoListVO : listActionResult) {
            map.put(positionIdBoundOrganizeInfoListVO.getPositionId(), positionIdBoundOrganizeInfoListVO.getOrganizeGeneralDetailVOList());
        }
        return map;
    }


    /**
     * 对字符串列表进行去重处理
     *
     * @param list 待处理的字符串列表
     * @return 去除null值、空字符串和重复项后的新列表
     */
    public static List<String> uniqueStringList(List<String> list) {
        if (CollUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list.stream()
                .filter(Objects::nonNull) // 过滤掉 null 值
                .filter(str -> !str.isEmpty()) // 过滤掉空字符串
                .distinct() // 去重
                .collect(Collectors.toList()); // 收集为 List
    }

    /**
     * 获取两个List<String>的交集
     *
     * @param list1 第一个列表
     * @param list2 第二个列表
     * @return 交集列表
     */
    public static List<String> getIntersection(List<String> list1, List<String> list2) {
        if (CollUtil.isEmpty(list1) || CollUtil.isEmpty(list2)) {
            return new ArrayList<>();
        }

        Set<String> set2 = new HashSet<>(list2);
        return list1.stream()
                .filter(s -> s != null && set2.contains(s))
                .distinct()
                .collect(Collectors.toList());
    }


    /**
     * 根据用户ID列表查询用户信息
     *
     * @param userIds 用户ID列表
     * @return 以用户ID为键，用户实体为值的映射表
     */
    public Map<String, UserEntity> getUserNameForUserIds(List<String> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return new HashMap<>();
        }
        List<UserEntity> list = userApi.getUserName(userIds);
        if (CollUtil.isEmpty(list)) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(UserEntity::getId, Function.identity()));

    }


    /**
     * 根据用户ID列表查询用户姓名信息（离职+在职）
     *
     * @param userIds 用户Ids列表
     * @return 以用户ID为键，用户实体为值的映射表
     */
    public Map<String, UserEntity> getUserNameAndCopyForUserIds(List<String> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return new HashMap<>();
        }
        List<UserEntity> list = userApi.getUserNameAndCopy(userIds);
        if (CollUtil.isEmpty(list)) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(UserEntity::getId, Function.identity()));

    }

    /**
     * 根据用户ID列表查询用户姓名信息（仅离职）
     *
     * @param userIds 用户Ids列表
     * @return 以用户ID为键，用户实体为值的映射表
     */
    public Map<String, UserCopyEntity> getUserNameOnlyCopy(List<String> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return new HashMap<>();
        }
        BatchGetUserCopyForm form = new BatchGetUserCopyForm();
        form.setCopyUserIds(userIds);
        List<UserCopyEntity> list = userApi.batchGetUserCopyByIds(form);
        if (CollUtil.isEmpty(list)) {
            return new HashMap<>();
        }
        return list.stream().collect(Collectors.toMap(UserCopyEntity::getId, Function.identity()));

    }


    /**
     * 根据用户ID列表查询用户信息
     *
     * @param userIds 用户ID列表
     * @return 以用户ID为键，用户实体为值的映射表
     */
    public List<UserEntity> getUserNameForUserIdsReturnList(List<String> userIds, String tenantId) {
        if (CollUtil.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        List<UserEntity> list = userApi.getUserListNoData(userIds, tenantId);
        if (CollUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list;

    }


    /**
     * 批量查询用户姓名 返回列表
     *
     * @param userIds 用户ID列表
     * @return 用户实体列表
     */
    public List<UserEntity> getUserNameForUserIdsReturnList(List<String> userIds) {
        if (CollUtil.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        List<UserEntity> list = userApi.getUserName(userIds);
        if (CollUtil.isEmpty(list)) {
            return new ArrayList<>();
        }
        return list;

    }

    /**
     * 获取权限模块编码
     * 1、优先从参数获取  2、如果没有就从header中获取
     *
     * @return 权限模块编码
     */
    public String getPermissionModuleId() {

        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes == null) {
            throw new RuntimeException("请传入权限菜单id");
        }
        String module = attributes.getRequest().getHeader("module");
        if (StringUtil.isEmpty(module)) {
            throw new RuntimeException("请传入权限菜单id");
        }
        return module;
    }

    /**
     * 查询有权限的用户列表
     *
     * @return 如果为 空数据组 就是有全部权限
     */
    public List<String> getPermissionUserIds() {
        List<String> powerUserIds = new ArrayList<>();
        InnerPowerUserVO powerUserVO = getLoginManagerUserIdsForEncode();
        if (powerUserVO.getCode().equals(1)) {
            powerUserIds = powerUserVO.getUserIds();
        } else if (powerUserVO.getCode().equals(2)) {
            powerUserIds = new ArrayList<>(List.of("-1"));
        }
        return powerUserIds;
    }

    /**
     * 批量处理list
     *
     * @param list      数据
     * @param batchSize 批次大小
     * @param <T>
     * @return
     */
    public static <T> List<List<T>> batchList(List<T> list, int batchSize) {
        if (list == null || list.isEmpty() || batchSize <= 0) {
            return List.of();
        }

        return IntStream.range(0, (list.size() + batchSize - 1) / batchSize)
                .mapToObj(i -> list.subList(i * batchSize, Math.min((i + 1) * batchSize, list.size())))
                .collect(Collectors.toList());
    }

    /**
     * 查询当前用户有权限访问的组织列表
     *
     * @return 当前用户有权限访问的组织ID列表
     */
    public List<String> queryPowerOrgList() {
        // 获取用户指定模块的权限
        List<OrganizeGeneralDetailVO> organizeGeneralDetailVOS = ftbPermissionOrganizeService.authOrganizesByUserBound(null, null, false, false);
        if (CollUtil.isEmpty(organizeGeneralDetailVOS)) {
            // 当没有的时候，这个代表着没有权限
            return new ArrayList<>();
        }
        return organizeGeneralDetailVOS.stream().map(OrganizeGeneralDetailVO::getId).collect(Collectors.toList());
    }

    /**
     * 根据关键字匹配用户名或系统ID
     *
     * @param keywords 关键字，用于匹配用户名、手机号或系统工作ID
     * @return 匹配到的用户ID列表
     */
    public List<String> matchUserNameOrSystemId(String keywords) {
        QueryListUserDTO dto = new QueryListUserDTO();
        if (StringUtil.isEmpty(keywords)) {
            return new ArrayList<>();
        }
        if (StringUtil.isNotEmpty(keywords)) {
            dto.setUserName(keywords);
            dto.setSystemWorkerId(keywords);
            dto.setMobilePhone(keywords);
        }
        dto.setTenantId(getCurrentLoginTenantId());
        List<UserPageListVO> userForNameOrPhone = searchUser(dto);
        List<String> userIds = new ArrayList<>();
        if (CollUtil.isNotEmpty(userForNameOrPhone)) {
            userIds.addAll(userForNameOrPhone.stream().map(UserPageListVO::getId).collect(Collectors.toList()));
        }
        return userIds;
    }

    public List<String> matchSystemId(String keywords) {
        QueryListUserDTO dto = new QueryListUserDTO();
        if (StringUtil.isEmpty(keywords)) {
            return new ArrayList<>();
        }
        if (StringUtil.isNotEmpty(keywords)) {
            dto.setSystemWorkerId(keywords);
        }
        dto.setTenantId(getCurrentLoginTenantId());
        List<UserPageListVO> userForNameOrPhone = searchUser(dto);
        List<String> userIds = new ArrayList<>();
        if (CollUtil.isNotEmpty(userForNameOrPhone)) {
            userIds.addAll(userForNameOrPhone.stream().map(UserPageListVO::getId).collect(Collectors.toList()));
        }
        return userIds;
    }

    /**
     * 格式化百分比
     *
     * @param rate  lv
     * @param scale 保留几位小数
     * @return 返回百分比
     */
    public static String formatRate(BigDecimal rate, Integer scale) {
        if (ObjectUtils.isEmpty(rate) || rate.compareTo(BigDecimal.ZERO) == 0) {
            return "0%";
        }
        BigDecimal result = rate.multiply(BigDecimal.valueOf(100));
        return result.setScale(scale, RoundingMode.HALF_UP).toString().concat("%");
    }

    public static String dealWithRate(BigDecimal rate, String suffix) {
        if (ObjectUtils.isEmpty(rate) || rate.compareTo(BigDecimal.ZERO) == 0) {
            return "0" + suffix;
        }
        BigDecimal result = rate.multiply(BigDecimal.valueOf(100));
        return result.setScale(2, RoundingMode.HALF_UP).toString().concat(suffix);
    }


    /**
     * 根据userid查询培训模块有权限的人员列表
     *
     * @param userId   用户id
     * @param tenantId 租户id
     * @return
     */
    public List<String> getPowerUserIdsForTrain(String userId, String tenantId) {
        //判断是否是超级管理员
        List<UserEntity> userListNoData = userApi.getUserListNoData(List.of(userId), tenantId);
        if (CollUtil.isEmpty(userListNoData)) {
            return List.of("-1");
        }
        if (userListNoData.get(0).getIsAdministrator() == 1) {
            return new ArrayList<>();
        }
//        SystemEntity systemVO = systemApi.getSystemVONoToken(tenantId);
//        log.info("getModule返回的systemVO:{}", JSONUtil.toJsonStr(systemVO));
//        String systemId = systemVO.getId();
//        ModuleEntity moduleEntity = moduleApi.getFullNameOrEnCode("培训管理", " xunlian", tenantId, "App", systemId);
//        if (moduleEntity == null) {
//            return List.of("-1");
//        }
        String module = "461212890154671237";
        List<String> powerOrgList = permissionsUtils.obtainPersonnelUserIdDataPermissions(userId, module);
        if (powerOrgList == null) {
            return new ArrayList<>();
        }
        if (CollUtil.isEmpty(powerOrgList)) {
            return List.of("-1");
        }
        return powerOrgList;
    }

    /**
     * 查询用户的按钮权限列表
     *
     * @param userBoundVO 用户信息
     * @return 返回按钮权限列表
     */
    public List<String> queryUserBtnPermissionList(UserBoundVO userBoundVO) {
        if (userBoundVO == null) {
            return new ArrayList<>();
        }
        // 当前人员权限
        List<String> permissionIdentifications = ftbPermissionRoleMapper.permissionIdentifications(userBoundVO.getId());
        if (CollUtil.isEmpty(permissionIdentifications)) {
            permissionIdentifications = new ArrayList<>();
        }
        // 获取人员岗位并获取岗位权限
        String positionId = userBoundVO.getPositionId();
        if (StringUtil.isNotEmpty(positionId)) {
            List<String> jobPermissions = ftbPermissionRoleMapper.queryJobPermissions(positionId);
            if (CollUtil.isEmpty(jobPermissions)) {
                jobPermissions = new ArrayList<>();
            }
            permissionIdentifications = Stream.concat(permissionIdentifications.stream(), jobPermissions.stream())
                    .distinct()
                    .collect(Collectors.toList());
        }
        return permissionIdentifications;
    }

    /**
     * 判断container集合是否包含target集合中的所有元素
     *
     * @param container 容器集合
     * @param target    目标集合
     * @return 如果container包含target中的所有元素返回true，否则返回false
     */
    public static <T> boolean containsAll(Collection<T> container, Collection<T> target) {
        if (target == null || target.isEmpty()) {
            return true; // 空集合被认为是被任何集合包含的
        }

        if (container == null || container.isEmpty()) {
            return false; // 非空集合不能被空集合包含
        }

        return container.containsAll(target);
    }

    /**
     * 把组织树 转换成map 方便获取
     *
     * @param organizeManagerNodeVOS 组织树
     * @param map                    返回的map
     */
    public static void convertToOrgMap(List<OrganizeManagerNodeVO> organizeManagerNodeVOS, Map<String, OrganizeManagerNodeVO> map) {
        if (CollUtil.isEmpty(organizeManagerNodeVOS)) {
            return;
        }
        for (OrganizeManagerNodeVO organizeManagerNodeVO : organizeManagerNodeVOS) {
            map.put(organizeManagerNodeVO.getId(), organizeManagerNodeVO);
            if (CollUtil.isNotEmpty(organizeManagerNodeVO.getChildren())) {
                convertToOrgMap(organizeManagerNodeVO.getChildren(), map);
            }
        }
    }

    /**
     * 生成id
     *
     * @return id
     */
    public static String generateId() {
        return UUID.randomUUID().toString().replace("-", "");
    }


    /**
     * 手动构建分页数据
     *
     * @param returnList  返回数据
     * @param pageSize    分页大小
     * @param currentPage 当前页
     * @return 分页数据
     */
    public static <T> PageListVO<T> buildPage(List<T> returnList, long pageSize, long currentPage) {
        //构建分页返回数据
        PageListVO<T> pageInfo = new PageListVO<>();

        PaginationVO pagination = new PaginationVO();
        pagination.setCurrentPage(currentPage);
        pagination.setPageSize(pageSize);
        pagination.setTotal(returnList.size());
        pageInfo.setPagination(pagination);
        if (CollUtil.isEmpty(returnList)) {
            pageInfo.setList(new ArrayList<>());
        } else {
            List<List<T>> batchList = batchList(returnList, (int) pageSize);
            if (currentPage <= batchList.size()) {
                pageInfo.setList(batchList.get((int) (currentPage - 1)));
            } else {
                pageInfo.setList(new ArrayList<>());
            }
        }
        return pageInfo;
    }

    /**
     * 判断两个列表是否相等 （数量和大小）
     *
     * @param list1 集合1
     * @param list2 集合2
     * @return true 表示两个列表相等，false 表示不相等
     */
    public static boolean areListsEqual(List<String> list1, List<String> list2) {
        if (list1 == list2) {
            return true;
        }
        if (list1 == null || list2 == null || list1.size() != list2.size()) {
            return false;
        }

        // 创建副本以避免修改原始列表
        List<String> sortedList1 = new ArrayList<>(list1);
        List<String> sortedList2 = new ArrayList<>(list2);

        Collections.sort(sortedList1);
        Collections.sort(sortedList2);

        return sortedList1.equals(sortedList2);
    }

    /**
     * 切换租户
     *
     * @param tenantId 租户id
     */
    public void checkOutTenant(String tenantId) {
        if (configValueUtil.isMultiTenancy()) {
            // 判断是不是从外面直接请求
            if (StringUtil.isNotEmpty(tenantId)) {
                //切换成租户库
                try {
                    TenantDataSourceUtil.switchTenant(tenantId);
                } catch (LoginException e) {
                    throw new RuntimeException("切换租户失败");
                }
            } else {
                UserInfo userInfo = UserProvider.getUser();
                Assert.notNull(userInfo.getUserId(), "缺少租户信息");
                DataSourceContextHolder.setDatasource(userInfo.getTenantId(), userInfo.getTenantDbConnectionString(), userInfo.isAssignDataSource());
            }
        }
    }


    /**
     * 返回一个空的分页结果列表（泛型版本）
     *
     * @param currentPage 当前页面
     * @param pageSize    每页调试
     * @param <T>         分页列表中的数据类型
     * @return 空的分页结果列表
     */
    public static <T> PageListVO<T> returnEmptyListGeneric(Long currentPage, Long pageSize) {
        PageListVO<T> pageInfo = new PageListVO<>();
        PaginationVO pagination = new PaginationVO();
        pagination.setCurrentPage(currentPage);
        pagination.setPageSize(pageSize);
        pagination.setTotal(0);
        pageInfo.setList(new ArrayList<>());
        pageInfo.setPagination(pagination);
        return pageInfo;
    }
}
