package cn.iocoder.yudao.module.system.service.biz;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.RandomUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.*;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.excel.BuildImportExcelVO;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.excel.BuildScreenExcel;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.excel.ScreenBuildBedInfoVO;
import cn.iocoder.yudao.module.system.controller.admin.nursing.vo.NursingPlanItemVO;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.*;
import cn.iocoder.yudao.module.system.dal.dataobject.dict.DictDataDO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.yudao.module.system.dal.mysql.biz.BedPlanRecordMapper;
import cn.iocoder.yudao.module.system.dal.mysql.biz.ElderlyChangeRecordMapper;
import cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.biz.StaffingPlanRecordMapper;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.StaffingPlanRecordDO;
import cn.iocoder.yudao.module.system.dal.mysql.biz.CheckInApplyMapper;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.CheckInApplyDO;
import cn.iocoder.yudao.module.system.dal.mysql.biz.*;
import cn.iocoder.yudao.module.system.dal.mysql.dict.DictDataMapper;
import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper;
import cn.iocoder.yudao.module.system.enums.BuildBusinessConstants;
import cn.iocoder.yudao.module.system.enums.ErrorCodeConstants;
import cn.iocoder.yudao.module.system.enums.common.BooleanEnum;
import com.alibaba.fastjson.JSON;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.regex.Pattern;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.BED_IS_USED;


/**
 * 楼栋 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
public class BuildServiceImpl implements BuildService {

    @Value("${spring.profiles.active}")
    private String activeProfile;

    @Resource
    private BuildMapper buildMapper;
    @Resource
    private BuildFloorMapper buildFloorMapper;
    @Resource
    private BuildRoomMapper buildRoomMapper;
    @Resource
    private BuildBedMapper buildBedMapper;
    @Resource
    private BedPlanRecordMapper bedPlanRecordMapper;
    @Resource
    private AdminUserMapper adminUserMapper;
    @Resource
    private StaffingPlanRecordMapper staffingPlanRecordMapper;
    @Resource
    private ElderlyChangeRecordMapper elderlyChangeRecordMapper;
    @Resource
    private CheckInApplyMapper checkInApplyMapper;
    @Resource
    private ElderlyInfoMapper elderlyInfoMapper;
    @Resource
    private TenantMapper tenantMapper;
    @Resource
    private NursingPlanMapper nursingPlanMapper;
    @Resource
    private NurseItemMapper nurseItemMapper;
    @Resource
    private NursingPlanItemMapper nursingPlanItemMapper;

    @Resource
    private DictDataMapper dictDataMapper;

    @Autowired
    private ElderlyOrderFoodMapper elderlyOrderFoodMapper;

    @Override
    public Long createBuild(BuildSaveReqVO createReqVO) {
        BuildDO buildDO = new BuildDO();
        BeanUtils.copyProperties(createReqVO, buildDO);
        buildMapper.insert(buildDO);

        List<BuildFloorDO> floorList = createReqVO.getFloorList();
        for (BuildFloorDO buildFloorDO : floorList) {
            buildFloorDO.setBuildId(buildDO.getId());
            buildFloorDO.setTenantId(createReqVO.getTenantId());
            buildFloorDO.setOrgType(Objects.isNull(buildDO.getOrgType()) ? null : buildDO.getOrgType());
            buildFloorMapper.insert(buildFloorDO);
        }
        return buildDO.getId();
    }

    @Override
    public List<BuildDO> getList(Integer orgType, Long[] tenantIds) {
        List<BuildDO> buildList = buildMapper.selectList(new LambdaQueryWrapperX<BuildDO>()
                .eqIfPresent(BuildDO::getOrgType, orgType)
                .inIfPresent(BuildDO::getTenantId, tenantIds)
                .orderByAsc(BuildDO::getSort));
        for (BuildDO buildDO : buildList) {
            List<BuildFloorDO> buildFloorList = buildFloorMapper.selectList(new LambdaQueryWrapperX<BuildFloorDO>().eq(BuildFloorDO::getBuildId, buildDO.getId()).orderByDesc(BuildFloorDO::getSort));
            buildDO.setFloorList(buildFloorList);
        }
        return buildList;
    }

    @Override
    public BuildDO getBuildById(Long id) {
        BuildDO buildDO = buildMapper.selectById(id);
        List<BuildFloorDO> buildFloorList = buildFloorMapper.selectList(new LambdaQueryWrapperX<BuildFloorDO>().eq(BuildFloorDO::getBuildId, buildDO.getId()).orderByAsc(BuildFloorDO::getSort));
        buildDO.setFloorList(buildFloorList);
        return buildDO;
    }

    @Override
    public void deleteBuildById(Long id) {
        buildMapper.deleteById(id);
        buildFloorMapper.delete(new LambdaQueryWrapperX<BuildFloorDO>().eq(BuildFloorDO::getBuildId, id));
    }

    @Override
    @Transactional
    public void editRoomInfo(BuildRoomDO room) {
        List<String> roomImageList = room.getRoomImageList();
        if (CollectionUtil.isNotEmpty(roomImageList)) {
            room.setRoomImage(JSON.toJSONString(roomImageList));
        }
        buildRoomMapper.updateById(room);

        List<BuildBedDO> bedList = room.getBedList();
        //需要删除的床位
        List<BuildBedDO> collect = room.getBedList().stream().filter(e -> e.getId() != null && e.getIsDelete().equals(true)).collect(Collectors.toList());
        for (BuildBedDO bedDO : collect) {
            buildBedMapper.deleteById(bedDO);
        }
        for (BuildBedDO bedDO : bedList) {
            if (bedDO.getId() != null) {
                buildBedMapper.updateById(bedDO);
            } else {
                BuildFloorDO buildFloor = buildFloorMapper.selectById(room.getFloorId());
                bedDO.setId(null);
                bedDO.setRoomId(room.getId());
                bedDO.setBuildId(buildFloor.getBuildId());
                bedDO.setFloorId(room.getFloorId());
                bedDO.setTenantId(room.getTenantId());
                buildBedMapper.insert(bedDO);
            }

        }
    }

    @Override
    public List<BuildRoomDO> getRoomByFloorId(Long floorId) {
        List<BuildRoomDO> buildRoomList = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>().eq(BuildRoomDO::getFloorId, floorId));
        for (BuildRoomDO buildRoomDO : buildRoomList) {
            if (StringUtils.isNotBlank(buildRoomDO.getRoomImage())) {
                buildRoomDO.setRoomImageList(JSON.parseArray(buildRoomDO.getRoomImage(), String.class));
            }
            List<BuildBedDO> bedList = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>().eq(BuildBedDO::getRoomId, buildRoomDO.getId()).orderByAsc(BuildBedDO::getSort));
            buildRoomDO.setBedList(bedList);
        }
        return buildRoomList;
    }

    @Override
    @Transactional
    public void editBuildInfo(BuildDO build) {
        buildMapper.updateById(build);
//        //校验床位是否有人使用，使用无法删除楼层
//        List<BuildFloorDO> buildFloorList = buildFloorMapper.selectList(new LambdaQueryWrapperX<BuildFloorDO>().eq(BuildFloorDO::getBuildId, build.getId()));
//        for (BuildFloorDO buildFloorDO : buildFloorList) {
//            List<BuildRoomDO> buildRooms = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>().eq(BuildRoomDO::getFloorId, buildFloorDO.getId()));
//            for (BuildRoomDO buildRoom : buildRooms) {
//                List<BuildBedDO> beds = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>().eq(BuildBedDO::getRoomId, buildRoom.getId()).eq(BuildBedDO::getStatus, BooleanEnum.TRUE.getValue()));
//                if (CollectionUtil.isNotEmpty(beds)) {
//                    throw exception(BED_IS_USED);
//                }
//                buildBedMapper.deleteBatchIds(beds.stream().map(BuildBedDO::getId).collect(Collectors.toList()));
//            }
//            buildRoomMapper.deleteBatchIds(buildRooms.stream().map(BuildRoomDO::getId).collect(Collectors.toList()));
//        }
//        buildFloorMapper.deleteBatchIds(buildFloorList.stream().map(BuildFloorDO::getId).collect(Collectors.toList()));

        List<BuildFloorDO> floorList = build.getFloorList();
        //删除
        List<BuildFloorDO> collect = floorList.stream().filter(e -> e.getId() != null && e.getIsDelete().equals(true)).collect(Collectors.toList());
        for (BuildFloorDO buildFloorDO : collect) {
            buildFloorMapper.deleteById(buildFloorDO);
        }
        //编辑
        for (BuildFloorDO buildFloorDO : floorList) {
            if (buildFloorDO.getId() != null) {
                buildFloorDO.setTenantId(build.getTenantId());
                buildFloorMapper.updateById(buildFloorDO);
            } else {
                buildFloorDO.setTenantId(build.getTenantId());
                buildFloorDO.setBuildId(build.getId());
                buildFloorMapper.insert(buildFloorDO);
            }
        }
    }

    @Override
    public void createRoom(BuildRoomDO room) {
        List<String> roomImageList = room.getRoomImageList();
        if (CollectionUtil.isNotEmpty(roomImageList)) {
            room.setRoomImage(JSON.toJSONString(roomImageList));
        }
        room.setCreateTime(new Date());
        room.setRoomCode(RandomUtil.randomNumbers(16));
        buildRoomMapper.insert(room);
        List<BuildBedDO> bedList = room.getBedList();
        for (BuildBedDO bed : bedList) {
            bed.setRoomId(room.getId());
            BuildFloorDO buildFloor = buildFloorMapper.selectById(room.getFloorId());
            bed.setFloorId(buildFloor.getId());
            bed.setBuildId(buildFloor.getBuildId());
            bed.setOrgType(buildFloor.getOrgType());
            bed.setTenantId(room.getTenantId());
            buildBedMapper.insert(bed);
        }
    }

    @Override
    public void deleteRoomById(Long roomId) {
        List<BuildBedDO> bedList = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>().eq(BuildBedDO::getRoomId, roomId).eq(BuildBedDO::getStatus, 1));
        if (CollectionUtil.isNotEmpty(bedList)) {
            throw exception(BED_IS_USED);
        }
        buildRoomMapper.deleteById(roomId);
        buildBedMapper.delete(new LambdaQueryWrapperX<BuildBedDO>().eq(BuildBedDO::getRoomId, roomId));
    }

    @Override
    public Map<String, Object> importBuildExcel(List<BuildImportExcelVO> list) {
        for (BuildImportExcelVO buildImportExcelVO : list) {
            //导入数据
            String buildName = buildImportExcelVO.getBuildName();
            BuildDO dbBuild = buildMapper.selectOne(new LambdaQueryWrapperX<BuildDO>().eq(BuildDO::getBuildName, buildName));
            //判断楼栋是否存在
            if (dbBuild == null) {
                //楼栋没有直接创建
                BuildDO buildDO = new BuildDO();
                buildDO.setBuildName(buildName);
                buildDO.setSort(1);
                buildMapper.insert(buildDO);

                BuildFloorDO floorDO = new BuildFloorDO();
                floorDO.setBuildId(buildDO.getId());
                floorDO.setFloorName(buildImportExcelVO.getFloorName());
                buildFloorMapper.insert(floorDO);

                //创建房间和床位
                createdBuildRoomAndBed(buildImportExcelVO, floorDO);

            } else {
                //查询楼层是否存在
                BuildFloorDO dbFloor = buildFloorMapper.selectOne(new LambdaQueryWrapperX<BuildFloorDO>()
                        .eq(BuildFloorDO::getFloorName, buildImportExcelVO.getFloorName())
                        .eq(BuildFloorDO::getBuildId, dbBuild.getId()));
                if (dbFloor == null) {
                    BuildFloorDO floorDO = new BuildFloorDO();
                    floorDO.setBuildId(dbBuild.getId());
                    floorDO.setFloorName(buildImportExcelVO.getFloorName());
                    buildFloorMapper.insert(floorDO);

                    //创建房间和床位
                    createdBuildRoomAndBed(buildImportExcelVO, floorDO);
                } else {
                    //判断房间是否存在
                    Optional<BuildRoomDO> optional = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>()
                            .eq(BuildRoomDO::getRoomName, buildImportExcelVO.getRoomName())
                            .eq(BuildRoomDO::getFloorId, dbFloor.getId())).stream().findFirst();


                    if (!optional.isPresent()) {
                        //创建房间和床位
                        createdBuildRoomAndBed(buildImportExcelVO, dbFloor);
                    } else {
                        BuildRoomDO dbRoom = optional.get();
                        //房间存在，直接创建床位
                        BuildBedDO bedDO = new BuildBedDO();
                        bedDO.setBedName(buildImportExcelVO.getBedName());
                        bedDO.setSort(1);
                        bedDO.setRoomId(dbRoom.getId());
                        bedDO.setFloorId(dbFloor.getId());
                        bedDO.setBuildId(dbFloor.getBuildId());
                        buildBedMapper.insert(bedDO);
                    }
                }
            }
        }
        Map<String, Object> map = new HashMap<>();
        map.put("successCount", list.size());
        map.put("failCount", 0);
        map.put("errorList", null);
        return map;
    }

    /**
     * 创建房间和床位
     *
     * @param buildImportExcelVO
     * @param floorDO
     */
    private void createdBuildRoomAndBed(BuildImportExcelVO buildImportExcelVO, BuildFloorDO floorDO) {
        BuildRoomDO roomDO = new BuildRoomDO();
        roomDO.setCreateTime(new Date());
        roomDO.setFloorId(floorDO.getId());
        roomDO.setRoomName(buildImportExcelVO.getRoomName());
        roomDO.setRoomUsage(buildImportExcelVO.getRoomUsage());
        roomDO.setOrientation(buildImportExcelVO.getOrientation());
        roomDO.setRoomSettings(buildImportExcelVO.getRoomSettings());
        roomDO.setRoomArea(buildImportExcelVO.getRoomArea());
        roomDO.setElderType(buildImportExcelVO.getElderType());
        roomDO.setUpdateBy(SecurityFrameworkUtils.getLoginUserNickname());
        roomDO.setRoomCode(RandomUtil.randomNumbers(16));
        buildRoomMapper.insert(roomDO);

        BuildBedDO bedDO = new BuildBedDO();
        bedDO.setBedName(buildImportExcelVO.getBedName());
        bedDO.setSort(1);
        bedDO.setFloorId(floorDO.getId());
        bedDO.setBuildId(floorDO.getBuildId());
        bedDO.setRoomId(roomDO.getId());
        buildBedMapper.insert(bedDO);

    }

    @Override
    public Map<String, Object> buildStatistic(Long buildId) {
        List<BuildFloorDO> buildFloorList = buildFloorMapper.selectList(new LambdaQueryWrapperX<BuildFloorDO>().eq(BuildFloorDO::getBuildId, buildId));

        int totalRoomCount = 0;  //总房间数量
        int totalBedCount = 0;   //总床位
        int daycareRoomCount = 0;  //托养房数量
        int activityRoomCount = 0;  //活动室数量
        for (BuildFloorDO buildFloorDO : buildFloorList) {
            List<BuildRoomDO> roomList = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>().eq(BuildRoomDO::getFloorId, buildFloorDO.getId()));
            for (BuildRoomDO roomDO : roomList) {
                List<BuildBedDO> bedList = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>().eq(BuildBedDO::getRoomId, roomDO.getId()));
                totalBedCount += bedList.size();
            }
            totalRoomCount += roomList.size();
            daycareRoomCount += (int) roomList.stream().filter(item -> item.getRoomUsage() != null && item.getRoomUsage().equals("1")).count();
            activityRoomCount += (int) roomList.stream().filter(item -> item.getRoomUsage() != null && item.getRoomUsage().equals("2")).count();

        }
        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("totalRoomCount", totalRoomCount);
        dataMap.put("totalBedCount", totalBedCount);
        dataMap.put("daycareRoomCount", daycareRoomCount);
        dataMap.put("activityRoomCount", activityRoomCount);
        return dataMap;
    }

    @Override
    public List<BuildBedVO> getBedList(String bedName, Integer status, Integer orgType, Long[] tenantIds) {
        return buildBedMapper.selectBedVOList(bedName, status, orgType, tenantIds);
    }

    @Override
    @TenantIgnore
    public BuildBedVO getBedInfoById(Long bedId) {
        BuildBedVO buildBedVO = new BuildBedVO();
        BuildBedDO bedDO = buildBedMapper.selectById(bedId);
        if (bedDO != null) {
            buildBedVO.setBuildBedId(bedDO.getId());
            buildBedVO.setBuildBedName(bedDO.getBedName());

            BuildRoomDO room = buildRoomMapper.selectById(bedDO.getRoomId());
            buildBedVO.setBuildRoomName(room.getRoomName());

            BuildFloorDO buildFloorDO = buildFloorMapper.selectById(room.getFloorId());
            buildBedVO.setBuildFloorName(buildFloorDO.getFloorName());
            BuildDO buildDO = buildMapper.selectById(buildFloorDO.getBuildId());
            buildBedVO.setBuildName(buildDO.getBuildName());
        }
        return buildBedVO;
    }

    @Override
    @TenantIgnore
    public String getFullBedName(Long elderId) {
        StringBuilder sb = new StringBuilder();
        ElderlyInfoDO elderlyInfo = elderlyInfoMapper.selectById(elderId);
        if (elderlyInfo != null) {
            String bedName = "";
            String roomName = "";
            String floorName = "";
            String buildName = "";

            Long bedId = elderlyInfo.getBedId();
            BuildBedDO bed = buildBedMapper.selectById(bedId);
            if (bed != null) {
                bedName = bed.getBedName();

                BuildRoomDO room = buildRoomMapper.selectById(bed.getRoomId());
                if (room != null) {
                    roomName = room.getRoomName();
                    BuildFloorDO buildFloor = buildFloorMapper.selectById(room.getFloorId());
                    if (buildFloor != null) {
                        floorName = buildFloor.getFloorName();
                        BuildDO build = buildMapper.selectById(buildFloor.getBuildId());
                        buildName = build.getBuildName();
                    }
                }
            }
            if (StringUtils.isNotBlank(buildName)) {
                sb.append(buildName);
                sb.append("-");
                sb.append(floorName);
                sb.append("-");
                sb.append(roomName);
                sb.append("-");
                sb.append(bedName);
            }
        }
        return sb.toString();
    }

    @Override
    public Map<String, Object> getBuildData(Long buildId) {
        List<BuildFloorDO> buildFloorList = buildFloorMapper.selectList(new LambdaQueryWrapperX<BuildFloorDO>().eq(BuildFloorDO::getBuildId, buildId));
        int totalRoomCount = 0;  //总房间数
        int totalBedCount = 0;   //总床位数
        int usedBedCount = 0;    //占用床位数
        int unusedBedCount = 0;  //空闲床位数
        int temporaryOccupationCount = 0; //临时占用数
        for (BuildFloorDO buildFloorDO : buildFloorList) {
            List<BuildRoomDO> roomList = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>().eq(BuildRoomDO::getFloorId, buildFloorDO.getId()));
            for (BuildRoomDO roomDO : roomList) {
                List<BuildBedDO> bedList = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>().eq(BuildBedDO::getRoomId, roomDO.getId()));
                totalBedCount += bedList.size();
                unusedBedCount += (int) bedList.stream().filter(e -> e.getStatus() == 0).count();
                usedBedCount += (int) bedList.stream().filter(e -> e.getStatus() == 1).count();
                // 添加对临时占用状态的统计（假设状态值为2）
                temporaryOccupationCount += (int) bedList.stream().filter(e -> e.getStatus() == 2).count();
            }
            totalRoomCount += roomList.size();
        }

        Map<String, Object> dataMap = new HashMap<>();
        dataMap.put("totalRoomCount", totalRoomCount);
        dataMap.put("totalBedCount", totalBedCount);
        dataMap.put("usedBedCount", usedBedCount);
        dataMap.put("unusedBedCount", unusedBedCount);
        dataMap.put("temporaryOccupationCount", temporaryOccupationCount);
        return dataMap;
    }

    @Override
    public BuildFloorDataRespVO getBuildFloorData(Long floodId) {
        int totalRoomCount;  //总房间数
        int totalBedCount = 0;   //总床位数
        int usedBedCount = 0;    //占用床位数
        int unusedBedCount = 0;  //空闲床位数
        int temporaryOccupationCount = 0; //临时占用数

        List<BuildRoomDO> roomList = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>().eq(BuildRoomDO::getFloorId, floodId));
        
        // 使用Map存储不同房间类型的统计信息，key为房间类型（如：2人间、4人间、6人间）
        Map<String, BuildFloorDataRespVO.RoomTypeStatistics> roomTypeStatisticsMap = new HashMap<>();

        for (BuildRoomDO roomDO : roomList) {
            List<BuildBedDO> bedList = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>().eq(BuildBedDO::getRoomId, roomDO.getId()));
            totalBedCount += bedList.size();
            unusedBedCount += (int) bedList.stream().filter(e -> e.getStatus() == 0).count();
            usedBedCount += (int) bedList.stream().filter(e -> e.getStatus() == 1).count();
            temporaryOccupationCount += (int) bedList.stream().filter(e -> e.getStatus() == 2).count();

            // 根据床位数确定房间类型（动态生成，如：2人间、4人间、6人间）
            int bedCount = bedList.size();
            if (bedCount > 0) {
                String roomType = bedCount + "人间";

                // 获取或创建该房间类型的统计对象
                BuildFloorDataRespVO.RoomTypeStatistics roomTypeStats = roomTypeStatisticsMap.computeIfAbsent(roomType, k -> {
                    BuildFloorDataRespVO.RoomTypeStatistics stats = new BuildFloorDataRespVO.RoomTypeStatistics();
                    stats.setRoomType(roomType);
                    stats.setLevel1Count(0);
                    stats.setLevel2Count(0);
                    stats.setLevel3Count(0);
                    stats.setLevel4Count(0);
                    return stats;
                });

                // 统计该房间中不同护理级别的数量
                for (BuildBedDO bed : bedList) {
                    // 查询该床位的入住长者信息
                    List<ElderlyInfoDO> elderlyInfoList = elderlyInfoMapper.selectList(new LambdaQueryWrapperX<ElderlyInfoDO>()
                            .eq(ElderlyInfoDO::getBedId, bed.getId())
                            .eq(ElderlyInfoDO::getInStatus, 1));
                    if(CollectionUtil.isEmpty(elderlyInfoList)){
                        continue;
                    }
                    ElderlyInfoDO elderlyInfo = elderlyInfoList.get(0);
                    if (elderlyInfo != null && StringUtils.isNotBlank(elderlyInfo.getNurseLevelName())) {
                        int level = extractNurseLevel(elderlyInfo.getNurseLevelName());
                        if (level == 1) {
                            roomTypeStats.setLevel1Count(roomTypeStats.getLevel1Count() + 1);
                        } else if (level == 2) {
                            roomTypeStats.setLevel2Count(roomTypeStats.getLevel2Count() + 1);
                        } else if (level == 3) {
                            roomTypeStats.setLevel3Count(roomTypeStats.getLevel3Count() + 1);
                        } else if (level == 4) {
                            roomTypeStats.setLevel4Count(roomTypeStats.getLevel4Count() + 1);
                        }
                    }
                }
            }
        }
        totalRoomCount = roomList.size();

        // 将Map转换为List，并按房间类型排序（按床位数排序）
        List<BuildFloorDataRespVO.RoomTypeStatistics> roomTypeStatisticsList = roomTypeStatisticsMap.values().stream()
                .sorted((a, b) -> {
                    int numA = extractNumberFromRoomType(a.getRoomType());
                    int numB = extractNumberFromRoomType(b.getRoomType());
                    return Integer.compare(numA, numB);
                })
                .collect(Collectors.toList());

        // 构建统计信息
        BuildFloorDataRespVO.Statistics statistics = new BuildFloorDataRespVO.Statistics();
        statistics.setRoomTypeStatisticsList(roomTypeStatisticsList);

        // 构建响应VO
        BuildFloorDataRespVO respVO = new BuildFloorDataRespVO();
        respVO.setTotalRoomCount(totalRoomCount);
        respVO.setTotalBedCount(totalBedCount);
        respVO.setUsedBedCount(usedBedCount);
        respVO.setUnusedBedCount(unusedBedCount);
        respVO.setTemporaryOccupationCount(temporaryOccupationCount);
        respVO.setStatistics(statistics);

        return respVO;
    }

    @Override
    public List<BuildRoomInfoVO> queryBuildRooms(BuildRoomQueryVO roomQueryVO) {
        LambdaQueryWrapperX<BuildRoomDO> queryWrapper = new LambdaQueryWrapperX<>();
        queryWrapper.eq(BuildRoomDO::getFloorId, roomQueryVO.getFloodId())
                .eqIfPresent(BuildRoomDO::getStatus, roomQueryVO.getStatus())
                .eqIfPresent(BuildRoomDO::getOrgType, roomQueryVO.getOrgType())
                .inIfPresent(BuildRoomDO::getTenantId, roomQueryVO.getTenantIds());

        if (ArrayUtil.isNotEmpty(roomQueryVO.getOrientationArray())) {
            queryWrapper.inIfPresent(BuildRoomDO::getOrientation, roomQueryVO.getOrientationArray());
        }
        if (ArrayUtil.isNotEmpty(roomQueryVO.getElderTypeArray())) {
            queryWrapper.inIfPresent(BuildRoomDO::getElderType, roomQueryVO.getElderTypeArray());
        }
        if (ArrayUtil.isNotEmpty(roomQueryVO.getRoomAreaArray())) {
            queryWrapper.inIfPresent(BuildRoomDO::getRoomArea, roomQueryVO.getRoomAreaArray());
        }
        if (ArrayUtil.isNotEmpty(roomQueryVO.getRoomSettingsArray())) {
            for (int i = 0; i < roomQueryVO.getRoomSettingsArray().size(); i++) {
                if (i == 0) {
                    queryWrapper.likeIfPresent(BuildRoomDO::getRoomSettings, roomQueryVO.getRoomSettingsArray().get(i));
                } else {
                    queryWrapper.or().like(BuildRoomDO::getRoomSettings, roomQueryVO.getRoomSettingsArray().get(i))
                            .eq(BuildRoomDO::getFloorId, roomQueryVO.getFloodId());
                }
            }
        }
        queryWrapper.orderByAsc(BuildRoomDO::getId);
        List<BuildRoomDO> buildRoomList = buildRoomMapper.selectList(queryWrapper);

        return buildRoomList.stream().map(e -> {
            BuildRoomInfoVO infoVO = new BuildRoomInfoVO();
            BeanUtils.copyProperties(e, infoVO);

            List<BuildBedDO> buildBedList = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>().eq(BuildBedDO::getRoomId, e.getId()));
            List<BuildBedInfoVO> collect = buildBedList.stream().map(i -> {
                BuildBedInfoVO buildBedInfoVO = new BuildBedInfoVO();
                BeanUtils.copyProperties(i, buildBedInfoVO);

                List<ElderlyInfoDO> elderlyInfoList = elderlyInfoMapper
                        .selectList(new LambdaQueryWrapperX<ElderlyInfoDO>()
                                .eq(ElderlyInfoDO::getBedId, i.getId())
                                .eq(ElderlyInfoDO::getInStatus, 1));
                Optional<ElderlyInfoDO> optional = elderlyInfoList.stream().findFirst();
                ElderlyInfoDO elderlyInfoDO = null;
                if (optional.isPresent()){
                     elderlyInfoDO = optional.get();
                }
                buildBedInfoVO.setElderName(elderlyInfoDO == null ? null : elderlyInfoDO.getElderName());
                buildBedInfoVO.setElderSex(elderlyInfoDO == null ? null : elderlyInfoDO.getElderSex());
                buildBedInfoVO.setNurseLevelName(elderlyInfoDO == null ? null : elderlyInfoDO.getNurseLevelName());
                buildBedInfoVO.setElderId(elderlyInfoDO == null ? null : elderlyInfoDO.getId());
                return buildBedInfoVO;
            }).collect(Collectors.toList());
            infoVO.setBedList(collect);
            return infoVO;
        }).collect(Collectors.toList());

    }

    @Override
    public void deleteBuildFloorById(Long id) {
        //查询是否有床位使用
        List<BuildRoomDO> buildRooms = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>().eq(BuildRoomDO::getFloorId, id));
        for (BuildRoomDO buildRoom : buildRooms) {
            List<BuildBedDO> beds = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>().eq(BuildBedDO::getRoomId, buildRoom.getId()).eq(BuildBedDO::getStatus, BooleanEnum.TRUE.getValue()));
            if (CollectionUtil.isNotEmpty(beds)) {
                throw exception(BED_IS_USED);
            }
        }
        buildFloorMapper.deleteById(id);
    }

    @Override
    public Boolean checkBedById(Long bedId) {
        BuildBedDO bed = buildBedMapper.selectById(bedId);
        if (bed != null && bed.getStatus().equals(BooleanEnum.TRUE.getValue())) {
            return true;
        }
        return false;
    }

    @Override
    public Boolean checkBuildFloorById(Long floorId) {
        List<BuildRoomDO> buildRooms = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>().eq(BuildRoomDO::getFloorId, floorId));
        for (BuildRoomDO buildRoom : buildRooms) {
            List<BuildBedDO> beds = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>().eq(BuildBedDO::getRoomId, buildRoom.getId()).eq(BuildBedDO::getStatus, BooleanEnum.TRUE.getValue()));
            if (CollectionUtil.isNotEmpty(beds)) {
                return true;
            }
        }
        return false;
    }

    @Override
    public List<BuildScreenExcel> exportScreenExcel(Long buildId) {
        BuildDO build = buildMapper.selectById(buildId);

        List<BuildFloorDO> buildFloorList = buildFloorMapper.selectList(new LambdaQueryWrapperX<BuildFloorDO>()
                .eq(BuildFloorDO::getBuildId, build.getId()).orderByAsc(BuildFloorDO::getSort));


        List<BuildRoomDO> collect = buildFloorList.stream().flatMap(f -> {
            List<BuildRoomDO> roomList = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>().eq(BuildRoomDO::getFloorId, f.getId()));
            return roomList.stream();
        }).collect(Collectors.toList());


        //组装数据
        List<BuildScreenExcel> dataList = new ArrayList<>();
        int i = 1;
        for (BuildRoomDO roomDO : collect) {
            BuildScreenExcel buildScreenExcel = new BuildScreenExcel();
            buildScreenExcel.setSerialNumber(i++);
            buildScreenExcel.setBuildName(build.getBuildName());
            buildScreenExcel.setRoomName(roomDO.getRoomName());
            buildScreenExcel.setFloorName(buildFloorMapper.selectById(roomDO.getFloorId()).getFloorName());
            if (activeProfile.equals("local")) {
                buildScreenExcel.setLinkUrl(String.format(BuildBusinessConstants.LINK_URL_TEST, "screen", roomDO.getRoomCode()));
            } else {
                buildScreenExcel.setLinkUrl(String.format(BuildBusinessConstants.LINK_URL, "screen", roomDO.getRoomCode()));
            }
            dataList.add(buildScreenExcel);
        }
        return dataList;
    }

    @Override
    public NurseScreenDataVO getNurseScreenDataByRoomCode(String roomCode) {
        BuildRoomDO room = buildRoomMapper.selectOne(new LambdaQueryWrapperX<BuildRoomDO>()
                .eq(BuildRoomDO::getRoomCode, roomCode));
        if (room == null) {
            throw exception(ErrorCodeConstants.COMMON_ERROR, "房间不存在");
        }
        TenantDO tenant = tenantMapper.selectById(room.getTenantId());

        NurseScreenDataVO data = new NurseScreenDataVO();
        data.setTenantName(tenant.getName());
        data.setRoom(room);

        List<ScreenBuildBedInfoVO> bedList = new ArrayList<>();
        List<BuildBedDO> buildBed = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>().eq(BuildBedDO::getRoomId, room.getId()));
        for (BuildBedDO bedDO : buildBed) {
            ScreenBuildBedInfoVO bedInfoVO = new ScreenBuildBedInfoVO();
            BeanUtils.copyProperties(bedDO, bedInfoVO);

            ElderlyInfoDO elderlyInfo = elderlyInfoMapper.selectOne(new LambdaQueryWrapperX<ElderlyInfoDO>()
                    .eq(ElderlyInfoDO::getBedId, bedDO.getId())
                    .eq(ElderlyInfoDO::getInStatus, 1));  //入住状态

            if (elderlyInfo != null) {
                bedInfoVO.setElderName(elderlyInfo.getElderName());
                bedInfoVO.setNurseLevelName(elderlyInfo.getNurseLevelName());
                bedInfoVO.setElderId(elderlyInfo.getId());
                bedInfoVO.setInHospitalStatus(elderlyInfo.getInHospitalStatus());
                bedInfoVO.setElderImage(StringUtils.isBlank(elderlyInfo.getElderImage()) ? null : elderlyInfo.getElderImage());

                //查询护理计划
                List<NursingPlanDO> nursingPlanList = nursingPlanMapper.selectList(new LambdaQueryWrapperX<NursingPlanDO>()
                        .eq(NursingPlanDO::getElderId, elderlyInfo.getId()));

                List<DictDataDO> nursingFrequencyTypeList = dictDataMapper.selectList(new LambdaQueryWrapperX<DictDataDO>()
                        .eq(DictDataDO::getDictType, "nursing_frequency_type"));

                Map<String, DictDataDO> dataMap = nursingFrequencyTypeList.stream().collect(Collectors.toMap(DictDataDO::getValue, i -> i));

                List<NursingPlanItemVO> items = new ArrayList<>();
                for (NursingPlanDO nursingPlan : nursingPlanList) {
                    if (LocalDate.now().isAfter(nursingPlan.getEffectiveDate()) || LocalDate.now().equals(nursingPlan.getEffectiveDate())) {
                        List<NursingPlanItemDO> nursingPlanItemList = nursingPlanItemMapper.selectList(new LambdaQueryWrapperX<NursingPlanItemDO>()
                                .eq(NursingPlanItemDO::getNursingPlanId, nursingPlan.getId())
                                .eq(NursingPlanItemDO::getIsDelete, 0));

                        List<Long> nurseItemIds = nursingPlanItemList.stream()
                                .map(NursingPlanItemDO::getNurseItemId)
                                .filter(Objects::nonNull)
                                .distinct()
                                .collect(Collectors.toList());
                        Map<Long, NurseItemDO> nurseItemMap = nurseItemIds.isEmpty() ? Collections.emptyMap()
                                : nurseItemMapper.selectBatchIds(nurseItemIds).stream()
                                .filter(Objects::nonNull)
                                .filter(i -> i.getId() != null)
                                .collect(Collectors.toMap(NurseItemDO::getId, i -> i, (a, b) -> a));

                        List<NursingPlanItemVO> collect = nursingPlanItemList.stream().map(item -> {
                            NursingPlanItemVO itemVO = new NursingPlanItemVO();
                            BeanUtils.copyProperties(item, itemVO);
                            itemVO.setDate(LocalDate.now());

                            NurseItemDO nurseItem = nurseItemMap.get(item.getNurseItemId());
                            if (nurseItem != null) {
                                itemVO.setFrequency(nurseItem.getFrequency());
                            }

                            DictDataDO dictDataDO = dataMap.get(String.valueOf(nurseItem == null ? null : nurseItem.getFrequencyType()));
                            if (dictDataDO != null) {
                                itemVO.setFrequencyTypeUnit(dictDataDO.getLabel());
                            }
                            return itemVO;
                        }).collect(Collectors.toList());
                        items.addAll(collect);
                    }
                }
                bedInfoVO.setNursingPlanItems(items);
            }
            bedList.add(bedInfoVO);
            //todo 护理员名称
        }
        data.setBedData(bedList);
        return data;
    }

    @Override
    public List<BuildRoomInfoVO> getElderListByFloorId(Long floorId) {
        List<BuildRoomDO> roomList = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>().eq(BuildRoomDO::getFloorId, floorId));
        return roomList.stream().map(item -> {
                    BuildRoomInfoVO infoVO = new BuildRoomInfoVO();
                    BeanUtils.copyProperties(item, infoVO);

                    List<BuildBedDO> buildBedList = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>()
                            .eq(BuildBedDO::getRoomId, item.getId()).orderByAsc(BuildBedDO::getSort));
                    List<BuildBedInfoVO> collect = buildBedList.stream().map(i -> {
                        BuildBedInfoVO buildBedInfoVO = new BuildBedInfoVO();
                        BeanUtils.copyProperties(i, buildBedInfoVO);

                        ElderlyInfoDO elderlyInfoDO = elderlyInfoMapper
                                .selectOne(new LambdaQueryWrapperX<ElderlyInfoDO>()
                                        .eq(ElderlyInfoDO::getBedId, i.getId())
                                        .eq(ElderlyInfoDO::getInStatus, 1));
                        buildBedInfoVO.setElderName(elderlyInfoDO == null ? null : elderlyInfoDO.getElderName());
                        buildBedInfoVO.setElderSex(elderlyInfoDO == null ? null : elderlyInfoDO.getElderSex());
                        buildBedInfoVO.setNurseLevelName(elderlyInfoDO == null ? null : elderlyInfoDO.getNurseLevelName());
                        buildBedInfoVO.setElderId(elderlyInfoDO == null ? null : elderlyInfoDO.getId());
                        return buildBedInfoVO;
                    }).collect(Collectors.toList());
                    infoVO.setBedList(collect);
                    return infoVO;
                }
        ).collect(Collectors.toList());

    }

    @Override
    public String getFullBedNameByBedId(Long bedId) {
        StringBuilder sb = new StringBuilder();
        String bedName = "";
        String roomName = "";
        String floorName = "";
        String buildName = "";

        BuildBedDO bed = buildBedMapper.selectById(bedId);
        if (bed != null) {
            bedName = bed.getBedName();

            BuildRoomDO room = buildRoomMapper.selectById(bed.getRoomId());
            if (room != null) {
                roomName = room.getRoomName();
                BuildFloorDO buildFloor = buildFloorMapper.selectById(room.getFloorId());
                if (buildFloor != null) {
                    floorName = buildFloor.getFloorName();
                    BuildDO build = buildMapper.selectById(buildFloor.getBuildId());
                    buildName = build.getBuildName();
                }
            }
        }
        if (StringUtils.isNotBlank(buildName)) {
            sb.append(buildName);
            sb.append("-");
            sb.append(floorName);
            sb.append("-");
            sb.append(roomName);
            sb.append("-");
            sb.append(bedName);
        }
        return sb.toString();
    }

    @Override
    public List<BuildRespVO> findAllBuild() {
        List<BuildDO> buildList = buildMapper.selectList();
        List<BuildRespVO> collect = buildList.stream().map(e -> {
            List<BuildFloorDO> buildFloorList = buildFloorMapper
                    .selectList(new LambdaQueryWrapperX<BuildFloorDO>()
                            .eq(BuildFloorDO::getBuildId, e.getId()));

            for (BuildFloorDO buildFloorDO : buildFloorList) {
                List<BuildRoomDO> buildRoomList = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>()
                        .eq(BuildRoomDO::getFloorId, buildFloorDO.getId()));

                for (BuildRoomDO roomDO : buildRoomList) {
                    List<BuildBedDO> buildBedList = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>()
                            .eq(BuildBedDO::getRoomId, roomDO.getId()));
                    roomDO.setBedList(buildBedList);
                }
                buildFloorDO.setRoomList(buildRoomList);
            }
            BuildRespVO respVO = new BuildRespVO();
            BeanUtils.copyProperties(e, respVO);
            respVO.setFloorList(buildFloorList);
            return respVO;
        }).collect(Collectors.toList());
        return collect;
    }

    @Override
    public List<BuildFloorTreeRespVO> getFloorTree(Long tenantId) {
        List<BuildDO> buildList = buildMapper.selectList(new LambdaQueryWrapperX<BuildDO>()
                .eq(BuildDO::getTenantId, tenantId)
                .orderByAsc(BuildDO::getSort));
        if (CollectionUtil.isEmpty(buildList)) {
            return Collections.emptyList();
        }
        List<Long> buildIds = buildList.stream().map(BuildDO::getId).collect(Collectors.toList());
        List<BuildFloorDO> floorList = buildFloorMapper.selectList(new LambdaQueryWrapperX<BuildFloorDO>()
                .in(BuildFloorDO::getBuildId, buildIds)
                .orderByAsc(BuildFloorDO::getSort));
        Map<Long, List<BuildFloorDO>> floorMap = floorList.stream()
                .collect(Collectors.groupingBy(BuildFloorDO::getBuildId, LinkedHashMap::new, Collectors.toList()));
        List<Long> floorIds = floorList.stream().map(BuildFloorDO::getId).collect(Collectors.toList());
        Map<Long, List<BuildRoomDO>> roomMap = Collections.emptyMap();
        if (CollectionUtil.isNotEmpty(floorIds)) {
            List<BuildRoomDO> roomList = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>()
                    .in(BuildRoomDO::getFloorId, floorIds)
                    .orderByAsc(BuildRoomDO::getId));
            roomMap = roomList.stream().collect(Collectors.groupingBy(BuildRoomDO::getFloorId, LinkedHashMap::new, Collectors.toList()));
        }
        List<Long> roomIds = roomMap.values().stream()
                .flatMap(Collection::stream)
                .map(BuildRoomDO::getId)
                .collect(Collectors.toList());
        Map<Long, List<ElderlyInfoDO>> elderlyByRoomId;
        Set<Long> orderedElderIdsToday;
        if (CollectionUtil.isNotEmpty(roomIds)) {
            List<ElderlyInfoDO> elderlyInfoList = elderlyInfoMapper.selectList(new LambdaQueryWrapperX<ElderlyInfoDO>()
                    .in(ElderlyInfoDO::getRoomId, roomIds)
                    .eq(ElderlyInfoDO::getInStatus, 1));
            elderlyByRoomId = elderlyInfoList.stream()
                    .collect(Collectors.groupingBy(ElderlyInfoDO::getRoomId, LinkedHashMap::new, Collectors.toList()));

            List<Long> elderIds = elderlyInfoList.stream().map(ElderlyInfoDO::getId).collect(Collectors.toList());
            if (CollectionUtil.isNotEmpty(elderIds)) {
                List<ElderlyOrderFoodDO> orderFoodList = elderlyOrderFoodMapper.selectList(new LambdaQueryWrapperX<ElderlyOrderFoodDO>()
                        .in(ElderlyOrderFoodDO::getElderId, elderIds)
                        .eq(ElderlyOrderFoodDO::getOrderFoodDate, LocalDate.now()));
                orderedElderIdsToday = orderFoodList.stream()
                        .map(ElderlyOrderFoodDO::getElderId)
                        .collect(Collectors.toSet());
            } else {
                orderedElderIdsToday = Collections.emptySet();
            }
        } else {
            orderedElderIdsToday = Collections.emptySet();
            elderlyByRoomId = Collections.emptyMap();
        }
        List<BuildFloorTreeRespVO> result = new ArrayList<>();
        for (BuildDO build : buildList) {
            BuildFloorTreeRespVO buildVO = new BuildFloorTreeRespVO();
            buildVO.setBuildingId(build.getId());
            buildVO.setBuildingName(build.getBuildName());
            List<BuildFloorTreeRespVO.FloorVO> floorVOList = new ArrayList<>();
            for (BuildFloorDO floor : floorMap.getOrDefault(build.getId(), Collections.emptyList())) {
                BuildFloorTreeRespVO.FloorVO floorVO = new BuildFloorTreeRespVO.FloorVO();
                floorVO.setFloorId(floor.getId());
                floorVO.setFloorName(floor.getFloorName());
                List<BuildFloorTreeRespVO.RoomVO> roomVOList = roomMap.getOrDefault(floor.getId(), Collections.emptyList())
                        .stream()
                        .map(room -> {
                            BuildFloorTreeRespVO.RoomVO roomVO = new BuildFloorTreeRespVO.RoomVO();
                            roomVO.setRoomId(room.getId());
                            roomVO.setRoomName(room.getRoomName());
                            handleIsFinishAndBedList(roomVO,
                                    elderlyByRoomId.getOrDefault(room.getId(), Collections.emptyList()),
                                    orderedElderIdsToday);
                            return roomVO;
                        }).collect(Collectors.toList());
                floorVO.setRoomList(roomVOList);
                floorVOList.add(floorVO);
            }
            buildVO.setFloorList(floorVOList);
            result.add(buildVO);
        }
        return result;
    }

    @Override
    public BuildFloorStatisticsRespVO getBuildFloorStatistics(Long[] tenantIds, String month) {
        BuildFloorStatisticsRespVO respVO = new BuildFloorStatisticsRespVO();
        List<BuildFloorStatisticsRespVO.BuildStatisticsVO> buildList = new ArrayList<>();

        // 获取所有楼栋
        List<BuildDO> builds = buildMapper.selectList(new LambdaQueryWrapperX<BuildDO>()
                .inIfPresent(BuildDO::getTenantId, tenantIds)
                .orderByAsc(BuildDO::getSort));

        Long tenantId = TenantContextHolder.getTenantId();

        // month 必传（格式 yyyy-MM），为空或格式不正确直接返回不查询
        if (StringUtils.isBlank(month) || !Pattern.matches("\\d{4}-\\d{2}", month)) {
            return respVO;
        }

        // 员工在职统计：按 month 月末（updateTime <= 月末）进行快照统计
        Date monthEnd = getMonthEndDate(month);
        List<AdminUserDO> users = adminUserMapper.selectList(new LambdaQueryWrapperX<AdminUserDO>()
                .eqIfPresent(AdminUserDO::getTenantId, tenantId)
                .leIfPresent(AdminUserDO::getUpdateTime, monthEnd));

        // workStatus 字典：0在职、1离职、2试用期、3转正、4缺岗
        int onDutyCount = 0;
        int probationCount = 0;
        int regularizedCount = 0;
        int vacantCount = 0;
        for (AdminUserDO u : users) {
            if (u.getWorkStatus() == null) {
                continue;
            }
            if (u.getWorkStatus() == 0) {
                onDutyCount++;
            } else if (u.getWorkStatus() == 2) {
                probationCount++;
            } else if (u.getWorkStatus() == 3) {
                regularizedCount++;
            } else if (u.getWorkStatus() == 4) {
                vacantCount++;
            }
        }

        // 编制计划：按 month 生效期（beginYearMonth <= month <= endYearMonth）取当月编制人数，命中 0/1 条
        StaffingPlanRecordDO staffingPlan = staffingPlanRecordMapper.selectOne(new LambdaQueryWrapperX<StaffingPlanRecordDO>()
                .eqIfPresent(StaffingPlanRecordDO::getTenantId, tenantId)
                .le(StaffingPlanRecordDO::getBeginYearMonth, month)
                .ge(StaffingPlanRecordDO::getEndYearMonth, month)
                .orderByDesc(StaffingPlanRecordDO::getId));
        int staffingCount = staffingPlan != null && staffingPlan.getStaffingCount() != null ? staffingPlan.getStaffingCount() : 0;

        BuildFloorStatisticsRespVO.StaffJobStatsVO staffStats = new BuildFloorStatisticsRespVO.StaffJobStatsVO();
        staffStats.setStaffingCount(staffingCount);
        staffStats.setOnDutyCount(onDutyCount);
        staffStats.setProbationCount(probationCount);
        staffStats.setRegularizedCount(regularizedCount);
        staffStats.setVacantCount(vacantCount);

        // ===== month 快照：全量在住长者 =====
        List<ElderlyInfoDO> allResidents = elderlyInfoMapper.selectList(new LambdaQueryWrapperX<ElderlyInfoDO>()
                .eqIfPresent(ElderlyInfoDO::getTenantId, tenantId)
                .leIfPresent(ElderlyInfoDO::getCheckInTime, monthEnd)
                .and(q -> q.isNull(ElderlyInfoDO::getCheckOutTime).or().gt(ElderlyInfoDO::getCheckOutTime, monthEnd)));

        Map<Long, Long> snapshotBedIdByElderId = new HashMap<>();
        Map<Long, String> snapshotNurseNameByElderId = new HashMap<>();
        Map<Long, List<ElderlyInfoDO>> residentsByFloorId = new HashMap<>();

        if (CollectionUtil.isNotEmpty(allResidents)) {
            List<Long> elderIds = allResidents.stream().map(ElderlyInfoDO::getId).collect(Collectors.toList());
            LocalDate monthEndLocalDate = DateUtils.of(monthEnd).toLocalDate();

            // 入住初始床位（当月有效入住申请）
            List<CheckInApplyDO> checkInApplyList = checkInApplyMapper.selectLastCheckInApplyByElderIds(elderIds, tenantId, monthEnd);
            Map<Long, Long> initialBedIdByElderId = checkInApplyList.stream()
                    .collect(Collectors.toMap(CheckInApplyDO::getElderlyId, CheckInApplyDO::getBedId, (a, b) -> a));

            // 当月末前最后一次床位变更（changeType=0）
            List<ElderlyChangeRecordDO> bedChangeList = elderlyChangeRecordMapper.selectLastBedRecordByElderIds(elderIds, tenantId, monthEndLocalDate);
            Map<Long, ElderlyChangeRecordDO> bedChangeMap = bedChangeList.stream()
                    .collect(Collectors.toMap(ElderlyChangeRecordDO::getElderlyId, r -> r, (a, b) -> {
                        if (a.getChangeDate() == null) return b;
                        if (b.getChangeDate() == null) return a;
                        return a.getChangeDate().isAfter(b.getChangeDate()) ? a : b;
                    }));

            // 当月末前最后一次护理变更（changeType=1）
            List<ElderlyChangeRecordDO> nurseChangeList = elderlyChangeRecordMapper.selectLastNurseRecordByElderIds(elderIds, tenantId, monthEndLocalDate);
            Map<Long, ElderlyChangeRecordDO> nurseChangeMap = nurseChangeList.stream()
                    .collect(Collectors.toMap(ElderlyChangeRecordDO::getElderlyId, r -> r, (a, b) -> {
                        if (a.getChangeDate() == null) return b;
                        if (b.getChangeDate() == null) return a;
                        return a.getChangeDate().isAfter(b.getChangeDate()) ? a : b;
                    }));

            // 构建快照 bedId / nurseName
            for (ElderlyInfoDO e : allResidents) {
                ElderlyChangeRecordDO bedR = bedChangeMap.get(e.getId());
                Long initialBedId = initialBedIdByElderId.get(e.getId());
                if (initialBedId == null) {
                    initialBedId = e.getBedId();
                }
                Long snapshotBedId = (bedR != null && bedR.getExpectId() != null) ? bedR.getExpectId() : initialBedId;
                snapshotBedIdByElderId.put(e.getId(), snapshotBedId);

                ElderlyChangeRecordDO nurseR = nurseChangeMap.get(e.getId());
                String nurseName = (nurseR != null && StringUtils.isNotBlank(nurseR.getExpectName())) ? nurseR.getExpectName() : e.getNurseLevelName();
                snapshotNurseNameByElderId.put(e.getId(), nurseName);
            }

            // 批量 bedId -> floorId 映射（使用床位表的 floorId）
            List<BuildBedDO> allBeds = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>()
                    .eqIfPresent(BuildBedDO::getTenantId, tenantId));
            Map<Long, Long> floorIdByBedId = allBeds.stream()
                    .collect(Collectors.toMap(BuildBedDO::getId, BuildBedDO::getFloorId, (a, b) -> a));

            // 按当月 floorId 分组
            for (ElderlyInfoDO e : allResidents) {
                Long bedId = snapshotBedIdByElderId.get(e.getId());
                Long floorId = bedId != null ? floorIdByBedId.get(bedId) : null;
                if (floorId == null) {
                    continue;
                }
                residentsByFloorId.computeIfAbsent(floorId, k -> new ArrayList<>()).add(e);
            }
        }

        for (BuildDO build : builds) {
            BuildFloorStatisticsRespVO.BuildStatisticsVO buildVO = new BuildFloorStatisticsRespVO.BuildStatisticsVO();
            buildVO.setBuildId(build.getId());
            buildVO.setBuildName(build.getBuildName());

            // 获取该楼栋的所有楼层
            List<BuildFloorDO> floors = buildFloorMapper.selectList(new LambdaQueryWrapperX<BuildFloorDO>()
                    .eq(BuildFloorDO::getBuildId, build.getId())
                    .orderByAsc(BuildFloorDO::getSort));

            List<BuildFloorStatisticsRespVO.FloorStatisticsVO> floorList = new ArrayList<>();

            // 统计每个楼层的数据
            for (BuildFloorDO floor : floors) {
                List<ElderlyInfoDO> floorResidents = residentsByFloorId.getOrDefault(floor.getId(), Collections.emptyList());
                BuildFloorStatisticsRespVO.FloorStatisticsVO floorVO = buildFloorStatistics(floor, month, floorResidents, snapshotBedIdByElderId, snapshotNurseNameByElderId);
                floorList.add(floorVO);
            }

            // 添加小计行
            BuildFloorStatisticsRespVO.FloorStatisticsVO subtotalVO = calculateSubtotal(floorList);
            // 员工在职统计：仅在顶层返回（与 buildList 同级），小计行不再返回
            floorList.add(subtotalVO);

            buildVO.setFloorList(floorList);
            buildList.add(buildVO);
        }

        respVO.setBuildList(buildList);
        respVO.setStaffStats(staffStats);
        return respVO;
    }

    @Override
    public List<CheckInWaitBedSimpleRespVO> getBedListByTenantIdAndKeyword(Long tenantId, String keyword) {
        if (tenantId == null) {
            return Collections.emptyList();
        }
        String trimmedKeyword = StringUtils.trimToNull(keyword);
        return buildBedMapper.selectWaitCheckInBedList(tenantId, trimmedKeyword);
    }

    /**
     * 统计单个楼层的数据
     */
    private BuildFloorStatisticsRespVO.FloorStatisticsVO buildFloorStatistics(BuildFloorDO floor, String month,
                                                                             List<ElderlyInfoDO> floorResidents,
                                                                             Map<Long, Long> snapshotBedIdByElderId,
                                                                             Map<Long, String> snapshotNurseNameByElderId) {
        BuildFloorStatisticsRespVO.FloorStatisticsVO floorVO = new BuildFloorStatisticsRespVO.FloorStatisticsVO();
        floorVO.setFloorId(floor.getId());
        floorVO.setFloorName(floor.getFloorName());
        floorVO.setFloorNumber(extractFloorNumber(floor.getFloorName()));
        floorVO.setIsSubtotal(false);

        // 获取该楼层的所有房间
        List<BuildRoomDO> rooms = buildRoomMapper.selectList(new LambdaQueryWrapperX<BuildRoomDO>()
                .eq(BuildRoomDO::getFloorId, floor.getId()));

        // 获取该楼层的所有床位
        List<BuildBedDO> beds = buildBedMapper.selectList(new LambdaQueryWrapperX<BuildBedDO>()
                .eq(BuildBedDO::getFloorId, floor.getId()));

        // 统计总床位信息
        floorVO.setDesignedBedCount(beds.size());
        floorVO.setBedType(determineBedType(floor, beds));

        // 统计各期床位数（来自 bed_plan_record 表）
        Long tenantId = TenantContextHolder.getTenantId();
        List<BedPlanRecordDO> planRecords = bedPlanRecordMapper.selectList(new LambdaQueryWrapperX<BedPlanRecordDO>()
                .eq(BedPlanRecordDO::getBuildId, floor.getBuildId())
                .eq(BedPlanRecordDO::getFloorId, floor.getId())
                .eqIfPresent(BedPlanRecordDO::getTenantId, tenantId)
                .le(BedPlanRecordDO::getBeginYearMonth, month)
                .ge(BedPlanRecordDO::getEndYearMonth, month));
        int phase1 = 0, phase2 = 0, phase3 = 0;
        for (BedPlanRecordDO r : planRecords) {
            if (r.getPlanSeq() == null || r.getBedCount() == null) {
                continue;
            }
            if (r.getPlanSeq() == 1) {
                phase1 += r.getBedCount();
            } else if (r.getPlanSeq() == 2) {
                phase2 += r.getBedCount();
            } else if (r.getPlanSeq() == 3) {
                phase3 += r.getBedCount();
            }
        }
        floorVO.setPhase1BedCount(phase1);
        floorVO.setPhase2BedCount(phase2);
        floorVO.setPhase3BedCount(phase3);

        // 在住人数：直接使用调用方按 month 快照分配到当前楼层的长者列表
        int residentCount = floorResidents != null ? floorResidents.size() : 0;
        floorVO.setResidentCount(residentCount);

        // 护理等级与床位快照：使用 getBuildFloorStatistics 顶层计算的快照结果
        Map<Long, String> nurseLevelNameByElderId = new HashMap<>();
        Map<Long, ElderlyInfoDO> elderlyBySnapshotBedId = new HashMap<>();

        if (CollectionUtil.isNotEmpty(floorResidents)) {
            for (ElderlyInfoDO e : floorResidents) {
                nurseLevelNameByElderId.put(e.getId(), snapshotNurseNameByElderId != null ? snapshotNurseNameByElderId.get(e.getId()) : null);
                Long snapshotBedId = snapshotBedIdByElderId != null ? snapshotBedIdByElderId.get(e.getId()) : null;
                if (snapshotBedId != null) {
                    elderlyBySnapshotBedId.put(snapshotBedId, e);
                }
            }
        }

        // 初始化房间类型统计（动态Map，根据床位数自动创建）
        Map<String, BuildFloorStatisticsRespVO.RoomTypeStatistics> roomTypeStatisticsMap = new HashMap<>();

        // 初始化等级统计
        int level1Count = 0, level2Count = 0, level3Count = 0, level4Count = 0;

        // 按房间统计长者类型
        for (BuildRoomDO room : rooms) {
            List<BuildBedDO> roomBeds = beds.stream()
                    .filter(bed -> bed.getRoomId().equals(room.getId()))
                    .collect(Collectors.toList());

            int bedCount = roomBeds.size();
            
            // 跳过床位数为0的房间
            if (bedCount == 0) {
                continue;
            }

            // 根据床位数动态创建房间类型（如：2人间、4人间、6人间等）
            String roomTypeKey = bedCount + "人间";
            BuildFloorStatisticsRespVO.RoomTypeStatistics roomTypeStats = roomTypeStatisticsMap.computeIfAbsent(roomTypeKey, k -> {
                BuildFloorStatisticsRespVO.RoomTypeStatistics stats = new BuildFloorStatisticsRespVO.RoomTypeStatistics();
                initRoomTypeStatistics(stats);
                return stats;
            });

            // 统计该房间的长者等级
            for (BuildBedDO bed : roomBeds) {
                ElderlyInfoDO elderly = elderlyBySnapshotBedId.get(bed.getId());

                if (elderly != null) {
                    String nurseLevelName = nurseLevelNameByElderId.get(elderly.getId());
                    if (StringUtils.isNotBlank(nurseLevelName)) {
                        int level = extractNurseLevel(nurseLevelName);
                        if (level == 1) {
                            roomTypeStats.setLevel1Count(roomTypeStats.getLevel1Count() + 1);
                            level1Count++;
                        } else if (level == 2) {
                            roomTypeStats.setLevel2Count(roomTypeStats.getLevel2Count() + 1);
                            level2Count++;
                        } else if (level == 3) {
                            roomTypeStats.setLevel3Count(roomTypeStats.getLevel3Count() + 1);
                            level3Count++;
                        } else if (level == 4) {
                            roomTypeStats.setLevel4Count(roomTypeStats.getLevel4Count() + 1);
                            level4Count++;
                        }
                    }
                }
            }
        }

        // 将Map转换为List，方便前端动态渲染
        List<BuildFloorStatisticsRespVO.RoomTypeStatisticsItem> roomTypeStatisticsList = roomTypeStatisticsMap.entrySet().stream()
                .map(entry -> {
                    BuildFloorStatisticsRespVO.RoomTypeStatisticsItem item = new BuildFloorStatisticsRespVO.RoomTypeStatisticsItem();
                    item.setRoomType(entry.getKey());
                    BuildFloorStatisticsRespVO.RoomTypeStatistics stats = entry.getValue();
                    item.setLevel1Count(stats.getLevel1Count());
                    item.setLevel2Count(stats.getLevel2Count());
                    item.setLevel3Count(stats.getLevel3Count());
                    item.setLevel4Count(stats.getLevel4Count());
                    return item;
                })
                .sorted((a, b) -> {
                    // 按房间类型排序（提取数字进行排序）
                    int numA = extractNumberFromRoomType(a.getRoomType());
                    int numB = extractNumberFromRoomType(b.getRoomType());
                    return Integer.compare(numA, numB);
                })
                .collect(Collectors.toList());
        floorVO.setRoomTypeStatistics(roomTypeStatisticsList);
        floorVO.setLevel1Count(level1Count);
        floorVO.setLevel2Count(level2Count);
        floorVO.setLevel3Count(level3Count);
        floorVO.setLevel4Count(level4Count);
        return floorVO;
    }

    /**
     * 计算小计行
     */
    private BuildFloorStatisticsRespVO.FloorStatisticsVO calculateSubtotal(List<BuildFloorStatisticsRespVO.FloorStatisticsVO> floorList) {
        BuildFloorStatisticsRespVO.FloorStatisticsVO subtotalVO = new BuildFloorStatisticsRespVO.FloorStatisticsVO();
        subtotalVO.setFloorName("小计");
        subtotalVO.setIsSubtotal(true);

        int totalDesignedBedCount = 0;
        int totalPhase1BedCount = 0;
        int totalPhase2BedCount = 0;
        int totalPhase3BedCount = 0;
        int totalResidentCount = 0;
        int totalLevel1Count = 0, totalLevel2Count = 0, totalLevel3Count = 0, totalLevel4Count = 0;

        // 动态汇总所有房间类型统计
        Map<String, BuildFloorStatisticsRespVO.RoomTypeStatistics> totalRoomTypeStatisticsMap = new HashMap<>();

        for (BuildFloorStatisticsRespVO.FloorStatisticsVO floorVO : floorList) {
            totalDesignedBedCount += floorVO.getDesignedBedCount() != null ? floorVO.getDesignedBedCount() : 0;
            totalPhase1BedCount += floorVO.getPhase1BedCount() != null ? floorVO.getPhase1BedCount() : 0;
            totalPhase2BedCount += floorVO.getPhase2BedCount() != null ? floorVO.getPhase2BedCount() : 0;
            totalPhase3BedCount += floorVO.getPhase3BedCount() != null ? floorVO.getPhase3BedCount() : 0;
            totalResidentCount += floorVO.getResidentCount() != null ? floorVO.getResidentCount() : 0;
            totalLevel1Count += floorVO.getLevel1Count() != null ? floorVO.getLevel1Count() : 0;
            totalLevel2Count += floorVO.getLevel2Count() != null ? floorVO.getLevel2Count() : 0;
            totalLevel3Count += floorVO.getLevel3Count() != null ? floorVO.getLevel3Count() : 0;
            totalLevel4Count += floorVO.getLevel4Count() != null ? floorVO.getLevel4Count() : 0;

            // 汇总每个房间类型的统计
            if (floorVO.getRoomTypeStatistics() != null) {
                for (BuildFloorStatisticsRespVO.RoomTypeStatisticsItem item : floorVO.getRoomTypeStatistics()) {
                    String roomTypeKey = item.getRoomType();
                    
                    BuildFloorStatisticsRespVO.RoomTypeStatistics totalRoomTypeStats = totalRoomTypeStatisticsMap.computeIfAbsent(roomTypeKey, k -> {
                        BuildFloorStatisticsRespVO.RoomTypeStatistics stats = new BuildFloorStatisticsRespVO.RoomTypeStatistics();
                        initRoomTypeStatistics(stats);
                        return stats;
                    });
                    
                    totalRoomTypeStats.setLevel1Count(totalRoomTypeStats.getLevel1Count() + (item.getLevel1Count() != null ? item.getLevel1Count() : 0));
                    totalRoomTypeStats.setLevel2Count(totalRoomTypeStats.getLevel2Count() + (item.getLevel2Count() != null ? item.getLevel2Count() : 0));
                    totalRoomTypeStats.setLevel3Count(totalRoomTypeStats.getLevel3Count() + (item.getLevel3Count() != null ? item.getLevel3Count() : 0));
                    totalRoomTypeStats.setLevel4Count(totalRoomTypeStats.getLevel4Count() + (item.getLevel4Count() != null ? item.getLevel4Count() : 0));
                }
            }
        }

        // 将Map转换为List，方便前端动态渲染
        List<BuildFloorStatisticsRespVO.RoomTypeStatisticsItem> totalRoomTypeStatisticsList = totalRoomTypeStatisticsMap.entrySet().stream()
                .map(entry -> {
                    BuildFloorStatisticsRespVO.RoomTypeStatisticsItem item = new BuildFloorStatisticsRespVO.RoomTypeStatisticsItem();
                    item.setRoomType(entry.getKey());
                    BuildFloorStatisticsRespVO.RoomTypeStatistics stats = entry.getValue();
                    item.setLevel1Count(stats.getLevel1Count());
                    item.setLevel2Count(stats.getLevel2Count());
                    item.setLevel3Count(stats.getLevel3Count());
                    item.setLevel4Count(stats.getLevel4Count());
                    return item;
                })
                .sorted((a, b) -> {
                    // 按房间类型排序（提取数字进行排序）
                    int numA = extractNumberFromRoomType(a.getRoomType());
                    int numB = extractNumberFromRoomType(b.getRoomType());
                    return Integer.compare(numA, numB);
                })
                .collect(Collectors.toList());

        subtotalVO.setDesignedBedCount(totalDesignedBedCount);
        subtotalVO.setPhase1BedCount(totalPhase1BedCount);
        subtotalVO.setPhase2BedCount(totalPhase2BedCount);
        subtotalVO.setPhase3BedCount(totalPhase3BedCount);
        subtotalVO.setResidentCount(totalResidentCount);
        subtotalVO.setLevel1Count(totalLevel1Count);
        subtotalVO.setLevel2Count(totalLevel2Count);
        subtotalVO.setLevel3Count(totalLevel3Count);
        subtotalVO.setLevel4Count(totalLevel4Count);
        subtotalVO.setRoomTypeStatistics(totalRoomTypeStatisticsList);
        subtotalVO.setBedType("/"); // 小计行的床位类型设为/

        return subtotalVO;
    }

    /**
     * 初始化房间类型统计
     */
    private void initRoomTypeStatistics(BuildFloorStatisticsRespVO.RoomTypeStatistics stats) {
        stats.setLevel1Count(0);
        stats.setLevel2Count(0);
        stats.setLevel3Count(0);
        stats.setLevel4Count(0);
    }

    /**
     * 从楼层名称中提取楼层号
     */
    private Integer extractFloorNumber(String floorName) {
        if (StringUtils.isBlank(floorName)) {
            return null;
        }
        // 尝试提取数字，例如"1层" -> 1, "2楼" -> 2
        String numberStr = floorName.replaceAll("[^0-9]", "");
        if (StringUtils.isNotBlank(numberStr)) {
            try {
                return Integer.parseInt(numberStr);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        return null;
    }

    /**
     * 确定床位类型（认知症/护理型）
     */
    private String determineBedType(BuildFloorDO floor, List<BuildBedDO> beds) {
        // 根据楼层或床位信息判断床位类型
        // 这里可以根据实际业务逻辑来确定
        // 暂时返回空字符串，需要根据实际业务逻辑确定
        if (CollectionUtil.isEmpty(beds)) {
            return "/";
        }
        // 可以根据楼层名称或其他规则判断
        // 例如：如果楼层名称包含"认知"，返回"认知症"，否则返回"护理型"
        if (floor.getFloorName() != null && floor.getFloorName().contains("认知")) {
            return "认知症";
        }
        return "护理型";
    }

    /**
     * 从房间类型中提取数字（用于排序）
     */
    private int extractNumberFromRoomType(String roomType) {
        if (StringUtils.isBlank(roomType)) {
            return 0;
        }
        // 提取数字，例如"2人间" -> 2
        String numberStr = roomType.replaceAll("[^0-9]", "");
        if (StringUtils.isNotBlank(numberStr)) {
            try {
                return Integer.parseInt(numberStr);
            } catch (NumberFormatException e) {
                return 0;
            }
        }
        return 0;
    }

    /**
     * 从护理等级名称中提取等级数字
     */
    private int extractNurseLevel(String nurseLevelName) {
        if (StringUtils.isBlank(nurseLevelName)) {
            return 0;
        }
        // 尝试提取数字，例如"一级" -> 1, "二级" -> 2
        if (nurseLevelName.contains("一级") || nurseLevelName.contains("1级")) {
            return 1;
        } else if (nurseLevelName.contains("二级") || nurseLevelName.contains("2级")) {
            return 2;
        } else if (nurseLevelName.contains("三级") || nurseLevelName.contains("3级")) {
            return 3;
        } else if (nurseLevelName.contains("四级") || nurseLevelName.contains("4级")) {
            return 4;
        }
        // 尝试提取纯数字
        String numberStr = nurseLevelName.replaceAll("[^0-9]", "");
        if (StringUtils.isNotBlank(numberStr)) {
            try {
                return Integer.parseInt(numberStr);
            } catch (NumberFormatException e) {
                return 0;
            }
        }
        return 0;
    }

    private Date getMonthEndDate(String month) {
        YearMonth ym = YearMonth.parse(month);
        return Date.from(ym.atEndOfMonth()
                .atTime(23, 59, 59, 999_000_000)
                .atZone(ZoneId.systemDefault())
                .toInstant());
    }

    private void handleIsFinishAndBedList(BuildFloorTreeRespVO.RoomVO roomVO,
                                           List<ElderlyInfoDO> elderlyInfoList,
                                           Set<Long> orderedElderIdsToday){
        List<BuildFloorTreeRespVO.BedVO> bedList = new ArrayList<>();
        boolean isFinish = true;
        for (ElderlyInfoDO elderlyInfoDO : elderlyInfoList) {
            BuildFloorTreeRespVO.BedVO bedVO = new BuildFloorTreeRespVO.BedVO();
            bedVO.setBedId(elderlyInfoDO.getBedId());
            bedVO.setBedName(elderlyInfoDO.getBedName());
            bedVO.setElderId(elderlyInfoDO.getId());
            bedVO.setElderName(elderlyInfoDO.getElderName());
            bedList.add(bedVO);
            if (!orderedElderIdsToday.contains(elderlyInfoDO.getId())) {
                isFinish = false;
            }
        }
        roomVO.setBedList(bedList);
        roomVO.setIsFinish(isFinish);
    }
}
