# AdjApproveLogServiceImpl.java

    package cloud.wconnect.frontoffice.service.adjustment.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.pojo.dto.UserDTO;
    import cloud.wconnect.commonlib.pojo.dto.internationalization.InternationalizationDateTimeDTO;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.InternationalizationUtils;
    import cloud.wconnect.frontoffice.cons.adjustment.AdjApprovalStatusEnum;
    import cloud.wconnect.frontoffice.cons.adjustment.AdjustmentStatusEnum;
    import cloud.wconnect.frontoffice.cons.adjustment.FlowStatusEnum;
    import cloud.wconnect.frontoffice.entity.adjustment.*;
    import cloud.wconnect.frontoffice.mapper.adjustment.AdjApproveLogMapper;
    import cloud.wconnect.frontoffice.pojo.vo.adjustment.AdjApproveLevelVO;
    import cloud.wconnect.frontoffice.pojo.vo.adjustment.AdjApproveUserVO;
    import cloud.wconnect.frontoffice.service.adjustment.IAdjApproveConfigService;
    import cloud.wconnect.frontoffice.service.adjustment.IAdjApproveLevelService;
    import cloud.wconnect.frontoffice.service.adjustment.IAdjApproveLogService;
    import cloud.wconnect.frontoffice.service.adjustment.IAdjOutOfOfficeConfigService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.google.common.collect.Lists;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Lazy;
    import org.springframework.stereotype.Service;

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

    import static java.util.stream.Collectors.groupingBy;
    import static java.util.stream.Collectors.toList;

    /**
     * <p>
     * Adjustment Requests 审批日志表 服务实现类
     * </p>
     *
     * @author lichen
     * @since 2023-03-30
     */
    @Service
    @DS("logbook")
    public class AdjApproveLogServiceImpl extends ServiceImpl<AdjApproveLogMapper, AdjApproveLog> implements IAdjApproveLogService {

        @Autowired
        private AdjApproveLogMapper adjApproveLogMapper;
        @Autowired
        @Lazy
        private IAdjApproveLevelService approveLevelService;
        @Autowired
        private BeanMapper beanMapper;
        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private IAdjApproveConfigService approveConfigService;
        @Autowired
        private IAdjOutOfOfficeConfigService adjOutOfOfficeConfigService;

        /**
         * 查询审批日志
         *
         * @param propertyId 资产Id
         * @param levelId    层级Id
         * @param batchIds   批次Id集合
         * @return java.util.Map<java.lang.Long, java.util.List < cloud.wconnect.frontoffice.entity.adjustment.AdjApproveLog>>
         * @author lichen
         * @date 2024/1/29
         */
        @Override
        public Map<Long, List<AdjApproveLog>> listByLevelIdAndBatchIds(Integer propertyId, Long levelId, List<Long> batchIds) {
            //查询待审核数据 在当前节点下对应的审核日志信息
            LambdaQueryWrapper<AdjApproveLog> approveLogQueryWrapper = new LambdaQueryWrapper<>();
            approveLogQueryWrapper.eq(AdjApproveLog::getPropertyId, propertyId);
            approveLogQueryWrapper.eq(AdjApproveLog::getLevelId, levelId);
            approveLogQueryWrapper.in(AdjApproveLog::getBatchId, batchIds);
            List<AdjApproveLog> approveLogList = list(approveLogQueryWrapper);
            //数据为空时，直接return
            if (CollectionUtils.isEmpty(approveLogList)) return Collections.emptyMap();
            //key = 业务数据id ; value = 审批日志集合
            return approveLogList.stream().collect(groupingBy(AdjApproveLog::getAdjId));
        }

        /**
         * @param adRequest adj数据
         * @return java.util.Set<java.lang.Integer>
         * @description 查询当前审批节点已审批的人集合
         * @author lichen
         * @date 2023/4/3 9:16
         */
        @Override
        public Set<Integer> getCurrentNodeAlreadyApprovalUser(AdRequest adRequest) {
            LambdaQueryWrapper<AdjApproveLog> approveLogQueryWrapper = new LambdaQueryWrapper<>();
            approveLogQueryWrapper.eq(AdjApproveLog::getPropertyId, adRequest.getPropertyId());
            approveLogQueryWrapper.eq(AdjApproveLog::getAdjId, adRequest.getId());
            approveLogQueryWrapper.eq(AdjApproveLog::getBatchId, adRequest.getBatchId());
            approveLogQueryWrapper.eq(AdjApproveLog::getApproveIndex, adRequest.getApproveIndex());
            List<AdjApproveLog> list = list(approveLogQueryWrapper);
            //数据为空时，直接return
            if (CollectionUtils.isEmpty(list)) return Collections.emptySet();
            //List<AdjApproveLog> 转化为审批人set集合
            return list.stream().map(AdjApproveLog::getApproveBy).collect(Collectors.toSet());
        }

        /**
         * 查询审批日志树
         *
         * @param adRequest   adj数据
         * @param propertyDTO 资产dto
         * @return java.util.List<cloud.wconnect.frontoffice.pojo.vo.adjustment.AdjApproveLevelVO>
         * @author lichen
         * @date 2023/9/8
         */
        @Override
        public List<AdjApproveLevelVO> listApproveRecord(AdRequest adRequest, PropertyDTO propertyDTO) {
            //查询审批层级
            List<AdjApproveLevel> levelList = approveLevelService.listByPropertyIdAndType(propertyDTO.getId(), adRequest.getRequestType());
            List<Long> levelIds = levelList.stream().map(AdjApproveLevel::getId).collect(toList());
            Map<Long, AdjApproveLevel> levelId2ApproveLevel = levelList.stream().collect(Collectors.toMap(AdjApproveLevel::getId, Function.identity()));

            //查询adj当前批次的审批日志
            List<AdjApproveLog> adjApproveLogs = adjApproveLogMapper.getLogsByBatchIdAndAdjId(propertyDTO.getId(), Lists.newArrayList(adRequest));
            List<Integer> approveByList = adjApproveLogs.stream().map(AdjApproveLog::getApproveBy).collect(toList());

            //查询审批层级人员
            List<AdjApproveConfig> adjApproveConfigs = approveConfigService.listByLevelIds(propertyDTO.getId(), levelIds);
            List<Integer> configApproveByList = adjApproveConfigs.stream().map(AdjApproveConfig::getUserId).toList();
            Map<Long, List<AdjApproveConfig>> levelId2ApproveConfigs = adjApproveConfigs.stream().collect(groupingBy(AdjApproveConfig::getLevelId));

            // 查询未审批人员对应的有效的补位配置
            Integer propertyId = propertyDTO.getId();
            List<AdjOutOfOfficeConfig> outOfOfficeConfigs = adjOutOfOfficeConfigService.listEffectiveConfigForApprover(propertyId, adRequest.getRequestType(),
                    levelId2ApproveConfigs.values().stream().flatMap(Collection::stream).map(AdjApproveConfig::getUserId).toList());
            Map<Integer, Integer> substitutePersonnelIdByApproveUserId = outOfOfficeConfigs
                    .stream().collect(Collectors.toMap(AdjOutOfOfficeConfig::getUpdatedBy, AdjOutOfOfficeConfig::getSubstitutePersonnelId));

            //查询用户信息
            List<Integer> userIds = Lists.newArrayList(approveByList);
            userIds.addAll(configApproveByList);
            userIds.addAll(outOfOfficeConfigs.stream().map(AdjOutOfOfficeConfig::getSubstitutePersonnelId).toList());
            Map<Integer, UserDTO> userId2UserDto = userInternalService.getUserMapByIds(propertyDTO.getTenantId(), userIds);

            Integer flowStatus = adRequest.getFlowStatus();//流程状态
            Integer status = adRequest.getStatus();//状态
            if (flowStatus == FlowStatusEnum.APPROVAL_COMPLETED.getFlowStatus()) {
                if(CollectionUtils.isEmpty(adjApproveLogs)) return Collections.emptyList();

                if (status == AdjustmentStatusEnum.VALID.getStatus()) {
                    if (CollectionUtils.isEmpty(adjApproveLogs)) return Collections.emptyList();
                    //adj状态等于有效 且 流程状态等于审批完成时，创建审批通过的日志树
                    return createApprovedLog(adjApproveLogs, levelId2ApproveLevel, userId2UserDto, propertyDTO);
                } else {
                    //adj状态等于无效 且 流程状态等于审批完成时，创建审批拒绝的日志树
                    return createRejectedLog(adjApproveLogs, levelId2ApproveLevel, userId2UserDto, propertyDTO);
                }
            } else if (flowStatus == FlowStatusEnum.APPROVAING.getFlowStatus()) {
                //流程状态等于审批中时，创建审批中的日志树
                return createApprovingLog(adRequest, adjApproveLogs, levelList, levelId2ApproveLevel, levelId2ApproveConfigs, userId2UserDto, propertyDTO, substitutePersonnelIdByApproveUserId);
            } else {
                //创建流程状态为Draft的审批日志树
                return createPendingLog(levelList, levelId2ApproveConfigs, userId2UserDto, substitutePersonnelIdByApproveUserId);
            }
        }

        /**
         * 查询调账数据当前审批节点的审批日志
         *
         * @param adRequest adj数据
         * @return java.util.List<cloud.wconnect.frontoffice.entity.adjustment.AdjApproveLog>
         * @author lichen
         * @date 2023/11/24
         */
        @Override
        public List<AdjApproveLog> listCurrentNodeApprovalLog(AdRequest adRequest) {
            return list(new LambdaQueryWrapper<AdjApproveLog>()
                    .eq(AdjApproveLog::getPropertyId, adRequest.getPropertyId())
                    .eq(AdjApproveLog::getAdjId, adRequest.getId())
                    .eq(AdjApproveLog::getBatchId, adRequest.getBatchId())
                    .eq(AdjApproveLog::getApproveIndex, adRequest.getApproveIndex()));
        }

        /**
         * 创建待送审的审批树
         *
         * @param levelList                            审批层级集合
         * @param levelId2ApproveConfigs               审批配置集合
         * @param userId2UserDto                       用户集合
         * @param substitutePersonnelIdByApproveUserId 补位人员
         * @return java.util.List<cloud.wconnect.frontoffice.pojo.vo.adjustment.AdjApproveLevelVO>
         * @author lichen
         * @date 2023/9/9
         */
        private List<AdjApproveLevelVO> createPendingLog(List<AdjApproveLevel> levelList, Map<Long, List<AdjApproveConfig>> levelId2ApproveConfigs, Map<Integer, UserDTO> userId2UserDto,
                                                         Map<Integer, Integer> substitutePersonnelIdByApproveUserId) {
            return beanMapper.mapList(levelList, AdjApproveLevelVO.class, (entity, vo) -> {
                //设置为未开始审批
                vo.setApproveStatus(AdjApprovalStatusEnum.NOT_START_APPROVAL.getStatus());
                //设置审批配置人员
                List<AdjApproveUserVO> adjApproveUserVOS = convertApproveConfigToApproveUserLog(levelId2ApproveConfigs.get(entity.getId()), userId2UserDto, BaseConstant.ZERO);
                // 设置补位人员
                List<Integer> substitutePersonnelIdsForCurrentLevel = adjApproveUserVOS.stream()
                        .filter(item -> substitutePersonnelIdByApproveUserId.containsKey(item.getUserId()))
                        .map(item -> substitutePersonnelIdByApproveUserId.get(item.getUserId()))
                        .distinct().toList();
                adjApproveUserVOS.addAll(convertApproveConfigToApproveUserLog(substitutePersonnelIdsForCurrentLevel, userId2UserDto, BaseConstant.ZERO));
                vo.setUsers(adjApproveUserVOS);
            });
        }

        /**
         * 创建审批中的审批树
         *
         * @param adRequest                            adj数据
         * @param adjApproveLogs                       审批日志集合
         * @param levelList                            审批层级集合
         * @param levelId2ApproveLevel                 审批层级集合
         * @param levelId2ApproveConfigs               审批配置集合
         * @param userId2UserDto                       用户集合
         * @param propertyDTO                          资产DTO
         * @param substitutePersonnelIdByApproveUserId 补位人员
         * @return java.util.List<cloud.wconnect.frontoffice.pojo.vo.adjustment.AdjApproveLevelVO>
         * @author lichen
         * @date 2023/9/8
         */
        private List<AdjApproveLevelVO> createApprovingLog(AdRequest adRequest, List<AdjApproveLog> adjApproveLogs, List<AdjApproveLevel> levelList,
                                                           Map<Long, AdjApproveLevel> levelId2ApproveLevel, Map<Long, List<AdjApproveConfig>> levelId2ApproveConfigs,
                                                           Map<Integer, UserDTO> userId2UserDto, PropertyDTO propertyDTO,
                                                           Map<Integer, Integer> substitutePersonnelIdByApproveUserId) {
            List<AdjApproveLevelVO> levelVOList = Lists.newArrayListWithCapacity(levelList.size());

            //当前审批索引
            Integer currentApproveIndex = adRequest.getApproveIndex();
            //当前审批层级
            AdjApproveLevel currentApproveLevel = levelList.stream()
                    .filter(item -> item.getApproveIndex().equals(currentApproveIndex)).findFirst().get();

            /**
             * 过滤出小于当前审批索引的审批日志
             * 这部分审批日志已经审批通过，生成审批通过的树
             */
            List<AdjApproveLog> approvedLogs = adjApproveLogs.stream().filter(log -> log.getApproveIndex() < currentApproveIndex).collect(toList());
            List<AdjApproveLevelVO> approvedLogVOList = createApprovedLog(approvedLogs, levelId2ApproveLevel, userId2UserDto, propertyDTO);

            /**
             * 当前审批层级的人包括:审批日志中的人 + 未审批的人
             */
            List<AdjApproveUserVO> approveingUserVOS = Lists.newArrayList();
            //过滤出等于当前审批索引的审批日志
            List<AdjApproveLog> approveingLogs = adjApproveLogs.stream().filter(log -> log.getApproveIndex().equals(currentApproveIndex)).collect(toList());
            List<Integer> currentApproveLevelalreadyApproveUser = approveingLogs.stream().map(AdjApproveLog::getApproveBy).toList();//已经审批过的人
            approveingUserVOS.addAll(convert(approveingLogs, userId2UserDto, propertyDTO));
            //当前审批层级未审批的人
            List<AdjApproveConfig> currentApproveLevelUnApprover = levelId2ApproveConfigs.get(currentApproveLevel.getId())
                    .stream().filter(item -> !currentApproveLevelalreadyApproveUser.contains(item.getUserId()))
                    .collect(toList());

            // 看看是否补位人员已经审批过，若补位人员已审批过，则当前审批人无需审批，若补位人员未审批过，则当前审批人+补位人员都显示出来
            List<Integer> substitutePersonnelIds = Lists.newArrayListWithExpectedSize(currentApproveLevelUnApprover.size());
            currentApproveLevelUnApprover = currentApproveLevelUnApprover.stream().filter(item -> {
                // 过滤补位人员也未审批过的
                Integer substitutePersonnelId = substitutePersonnelIdByApproveUserId.get(item.getUserId());
                if (Objects.nonNull(substitutePersonnelId)) {
                    if(currentApproveLevelalreadyApproveUser.contains(substitutePersonnelId)){
                        // 补位人员审批过，不用添加此审批人
                        return false;
                    } else {
                        // 补位人员未审批过且未添加过，需要添加此审批人
                        if (!substitutePersonnelIds.contains(substitutePersonnelId)) {
                            substitutePersonnelIds.add(substitutePersonnelId);
                        }
                        return true;
                    }
                } else {
                    return true;
                }
            }).toList();
            approveingUserVOS.addAll(convertApproveConfigToApproveUserLog(currentApproveLevelUnApprover, userId2UserDto, BaseConstant.ZERO));
            // 添加补位人员置审批层级中
            approveingUserVOS.addAll(convertApproveConfigToApproveUserLog(substitutePersonnelIds, userId2UserDto, BaseConstant.ZERO));
            //生成当前审批层级的vo
            AdjApproveLevelVO approveingLogVO = beanMapper.map(currentApproveLevel, AdjApproveLevelVO.class, vo -> {
                vo.setApproveStatus(AdjApprovalStatusEnum.APPROVING.getStatus());
                vo.setUsers(approveingUserVOS);
            });

            /**
             * 未审批的审批层级：大于当前审批索引的审批层级集合
             */
            List<AdjApproveLevel> unApproveLevelList = levelList.stream().filter(item -> item.getApproveIndex() > currentApproveIndex).collect(toList());
            List<AdjApproveLevelVO> unApproveLevelVOList = beanMapper.mapList(unApproveLevelList, AdjApproveLevelVO.class, (entity, vo) -> {
                vo.setApproveStatus(BaseConstant.ZERO);
                //获取审批配置人员
                List<AdjApproveConfig> adjApproveConfigs = levelId2ApproveConfigs.get(entity.getId());
                //设置审批配置人员
                List<AdjApproveUserVO> adjApproveUserVOS = convertApproveConfigToApproveUserLog(adjApproveConfigs, userId2UserDto, BaseConstant.ZERO);
                // 设置补位人员
                List<Integer> substitutePersonnelIdsForCurrentLevel = adjApproveUserVOS.stream()
                        .filter(item -> substitutePersonnelIdByApproveUserId.containsKey(item.getUserId()))
                        .map(item -> substitutePersonnelIdByApproveUserId.get(item.getUserId()))
                        .distinct().toList();
                adjApproveUserVOS.addAll(convertApproveConfigToApproveUserLog(substitutePersonnelIdsForCurrentLevel, userId2UserDto, BaseConstant.ZERO));
                vo.setUsers(adjApproveUserVOS);
            });

            levelVOList.addAll(approvedLogVOList);
            levelVOList.add(approveingLogVO);
            levelVOList.addAll(unApproveLevelVOList);
            levelVOList.sort(Comparator.comparing(AdjApproveLevelVO::getApproveIndex));
            return levelVOList;
        }

        /**
         * 把审批配置 转化成 审批人集合
         *
         * @param adjApproveConfigs 审批配置信息集合
         * @param userId2UserDto    用户集合
         * @param approveStatus     审批状态
         * @return java.util.Collection<? extends cloud.wconnect.frontoffice.pojo.vo.adjustment.AdjApproveUserVO>
         * @author lichen
         * @date 2023/9/8
         */
        private List<AdjApproveUserVO> convertApproveConfigToApproveUserLog(List<AdjApproveConfig> adjApproveConfigs, Map<Integer, UserDTO> userId2UserDto,
                                                                            Integer approveStatus) {
            return adjApproveConfigs.stream()
                    .map(approveConfig -> {
                        AdjApproveUserVO approveUserVO = new AdjApproveUserVO();
                        approveUserVO.setUserId(approveConfig.getUserId());
                        approveUserVO.setApproveStatus(approveStatus);
                        UserDTO userDTO = userId2UserDto.get(approveConfig.getUserId());
                        if (Objects.nonNull(userDTO)) {
                            approveUserVO.setName(userDTO.getName());
                            approveUserVO.setAccount(userDTO.getAccount());
                            approveUserVO.setEmail(userDTO.getEmail());
                            approveUserVO.setPhone(userDTO.getPhone());
                        }
                        return approveUserVO;
                    }).collect(toList());
        }

        /**
         * 把补位人员转化成审批人集合
         *
         * @param userIds        补位人员id集合
         * @param userId2UserDto 用户集合
         * @param approveStatus  审批状态
         * @return 审批人
         * @author yyt
         * @date 2026/3/18
         */
        private List<AdjApproveUserVO> convertApproveConfigToApproveUserLog(List<Integer> userIds, Map<Integer, UserDTO> userId2UserDto, int approveStatus) {
            return userIds.stream().map(userId -> {
                AdjApproveUserVO approveUserVO = new AdjApproveUserVO();
                approveUserVO.setUserId(userId);
                approveUserVO.setApproveStatus(approveStatus);
                UserDTO userDTO = userId2UserDto.get(userId);
                if (Objects.nonNull(userDTO)) {
                    approveUserVO.setName(userDTO.getName());
                    approveUserVO.setAccount(userDTO.getAccount());
                    approveUserVO.setEmail(userDTO.getEmail());
                    approveUserVO.setPhone(userDTO.getPhone());
                }
                return approveUserVO;
            }).collect(toList());
        }

        /**
         * 创建审批拒绝的审批树
         *
         * @param adjApproveLogs       adj数据的审批日志
         * @param levelId2ApproveLevel 最新的审批层级集合
         * @param userId2UserDto       用户集合
         * @param propertyDTO          资产DTO
         * @return java.util.List<cloud.wconnect.frontoffice.pojo.vo.adjustment.AdjApproveLevelVO>
         * @author lichen
         * @date 2023/9/8
         */
        private List<AdjApproveLevelVO> createRejectedLog(List<AdjApproveLog> adjApproveLogs, Map<Long, AdjApproveLevel> levelId2ApproveLevel,
                                                          Map<Integer, UserDTO> userId2UserDto, PropertyDTO propertyDTO) {
            /**
             * 审批日志中出现过的所有审批层级集合
             */
            List<AdjApproveLevel> levelList = adjApproveLogs.stream().map(log -> {
                //获取当前资产配置的最新审批层级
                AdjApproveLevel latestApproveLevel = levelId2ApproveLevel.get(log.getLevelId());
                if (Objects.nonNull(latestApproveLevel)) return latestApproveLevel;
                //审批层级被删除，生成审批层级对象
                return AdjApproveLevel.builder()
                        .id(log.getLevelId())
                        .approveIndex(log.getApproveIndex())
                        .propertyId(log.getPropertyId())
                        .build();
            }).distinct().sorted(Comparator.comparing(AdjApproveLevel::getApproveIndex)).collect(toList());

            //审批日志按照审批层级id分组。key=审批层级id value=审批人
            Map<Long, List<AdjApproveLog>> levelId2ApproveLog = adjApproveLogs.stream().collect(groupingBy(AdjApproveLog::getLevelId));

            /**
             * 查询出审批拒绝的层级
             */
            Optional<AdjApproveLog> optionalRejectedApproveLog = adjApproveLogs.stream()
                    .filter(log -> AdjApprovalStatusEnum.APPROVED.getStatus() != log.getApproveStatus()).findFirst();

            return beanMapper.mapList(levelList, AdjApproveLevelVO.class, (entity, vo) -> {
                if (optionalRejectedApproveLog.isPresent() && vo.getApproveIndex().equals(optionalRejectedApproveLog.get().getApproveIndex())) {
                    vo.setApproveStatus(AdjApprovalStatusEnum.REJECTED.getStatus());
                } else {
                    vo.setApproveStatus(AdjApprovalStatusEnum.APPROVED.getStatus());
                }
                vo.setUsers(convert(levelId2ApproveLog.get(entity.getId()), userId2UserDto, propertyDTO));
            });
        }

        /**
         * 创建审批通过的审批树
         *
         * @param adjApproveLogs       adj数据的审批日志
         * @param levelId2ApproveLevel 最新的审批层级集合
         * @param userId2UserDto       用户集合
         * @param propertyDTO          资产DTO
         * @return java.util.List<cloud.wconnect.frontoffice.pojo.vo.adjustment.AdjApproveLevelVO>
         * @author lichen
         * @date 2023/9/8
         */
        private List<AdjApproveLevelVO> createApprovedLog(List<AdjApproveLog> adjApproveLogs, Map<Long, AdjApproveLevel> levelId2ApproveLevel,
                                                          Map<Integer, UserDTO> userId2UserDto, PropertyDTO propertyDTO) {
            /**
             * 审批日志中出现过的所有审批层级集合
             */
            List<AdjApproveLevel> levelList = adjApproveLogs.stream().map(log -> {
                //获取当前资产配置的最新审批层级
                AdjApproveLevel latestApproveLevel = levelId2ApproveLevel.get(log.getLevelId());
                if (Objects.nonNull(latestApproveLevel)) return latestApproveLevel;
                //审批层级被删除，生成审批层级对象
                return AdjApproveLevel.builder()
                        .id(log.getLevelId())
                        .approveIndex(log.getApproveIndex())
                        .propertyId(log.getPropertyId())
                        .build();
            }).distinct().sorted(Comparator.comparing(AdjApproveLevel::getApproveIndex)).collect(toList());

            //审批日志按照审批层级id分组。key=审批层级id value=审批人
            Map<Long, List<AdjApproveLog>> levelId2ApproveLog = adjApproveLogs.stream().collect(groupingBy(AdjApproveLog::getLevelId));

            return beanMapper.mapList(levelList, AdjApproveLevelVO.class, (entity, vo) -> {
                vo.setApproveStatus(AdjApprovalStatusEnum.APPROVED.getStatus());
                vo.setUsers(convert(levelId2ApproveLog.get(entity.getId()), userId2UserDto, propertyDTO));
            });
        }

        /**
         * 把审批日志转化成VO
         *
         * @param logList        审批日志集合
         * @param userId2UserDto 用户集合
         * @param propertyDTO    资产DTO
         * @return java.util.List<cloud.wconnect.frontoffice.pojo.vo.adjustment.AdjApproveLogVO>
         * @author lichen
         * @date 2023/9/8
         */
        private List<AdjApproveUserVO> convert(List<AdjApproveLog> logList, Map<Integer, UserDTO> userId2UserDto, PropertyDTO propertyDTO) {
            InternationalizationDateTimeDTO internationalizationDateTimeDTO = propertyDTO.getInternationalization().getDateTime();
            String longDateFormate = internationalizationDateTimeDTO.getLongDate();
            String hourClock = internationalizationDateTimeDTO.getHourClock();

            //日期格式化
            return logList.stream().map(approveLog -> {
                AdjApproveUserVO approveUserVO = new AdjApproveUserVO();
                approveUserVO.setUserId(approveLog.getApproveBy());
                approveUserVO.setApproveStatus(approveLog.getApproveStatus());
                approveUserVO.setApproveOpinion(approveLog.getApproveOpinion());
                approveUserVO.setApproveTime(approveLog.getApproveTime());
                //设置审批时间
                approveUserVO.setApproveTimeStr(InternationalizationUtils.formatDateTime(approveLog.getApproveTime(),
                        longDateFormate, hourClock, propertyDTO.getTimezone(), propertyDTO.getLanguage()));
                UserDTO userDTO = userId2UserDto.get(approveLog.getApproveBy());
                if (Objects.nonNull(userDTO)) {
                    approveUserVO.setName(userDTO.getName());
                    approveUserVO.setAccount(userDTO.getAccount());
                    approveUserVO.setEmail(userDTO.getEmail());
                    approveUserVO.setPhone(userDTO.getPhone());
                }
                return approveUserVO;
            }).collect(toList());
        }

        /**
         * 批量查询审批记录
         *
         * @param propertyId 资产 id
         * @param adRequests ajd 数据
         * @return 审批记录
         * @author yyt
         * @date 2026/3/19
         */
        @Override
        public List<AdjApproveLog> listApproveRecord(Integer propertyId, List<AdRequest> adRequests) {
            return baseMapper.getLogsByBatchIdAndAdjId(propertyId, adRequests);
        }

    }