# BudgetDatabaseSendEventServiceImpl.java

    package cloud.wconnect.rateshop.service.budgetdatabase.impl;

    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.MoudleEventSubjectEnum;
    import cloud.wconnect.commonlib.exception.InternalServerErrorException;
    import cloud.wconnect.commonlib.util.JsonUtils;
    import cloud.wconnect.commonlib.util.YearMonthUtils;
    import cloud.wconnect.rateshop.cons.budgetdatabase.FbClassificationEnum;
    import cloud.wconnect.rateshop.cons.budgetdatabase.RoomClassificationEnum;
    import cloud.wconnect.rateshop.entity.budgetdatabase.*;
    import cloud.wconnect.rateshop.pojo.bo.budgetdatabase.event.*;
    import cloud.wconnect.rateshop.service.budgetdatabase.*;
    import cloud.wconnect.sns.http.processor.Sender;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.google.common.collect.Lists;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.stereotype.Service;
    import software.amazon.awssdk.services.sns.model.PublishResponse;

    import java.lang.reflect.Field;
    import java.math.BigDecimal;
    import java.time.Month;
    import java.time.YearMonth;
    import java.util.Collections;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    import java.util.stream.Collectors;

    /**
     * @author yyt
     * 2025/8/25
     */
    @Slf4j
    @Service
    @DS("rate_shop")
    public class BudgetDatabaseSendEventServiceImpl implements IBudgetDatabaseSendEventService {

        @Autowired
        private ObjectMapper objectMapper;
        @Autowired
        private IBudgetDatabaseConfigRoomTabService budgetDatabaseConfigRoomTabService;
        @Autowired
        private IBudgetDatabaseConfigRoomTabItemService budgetDatabaseConfigRoomTabItemService;
        @Autowired
        private IBudgetDatabaseConfigFbTabService budgetDatabaseConfigFbTabService;
        @Autowired
        private IBudgetDatabaseConfigFbTabItemService budgetDatabaseConfigFbTabItemService;
        @Autowired
        private IBudgetDatabaseConfigOtherTabService budgetDatabaseConfigOtherTabService;
        @Autowired
        private IBudgetDatabaseConfigOtherTabItemService budgetDatabaseConfigOtherTabItemService;
        @Autowired
        private IBudgetDatabaseRoomRgiService budgetDatabaseRoomRgiService;
        @Autowired
        private IBudgetDatabaseRoomOtherService budgetDatabaseRoomOtherService;
        @Autowired
        private IBudgetDatabaseRoomService budgetDatabaseRoomService;
        @Autowired
        private IBudgetDatabaseFbRevenueService budgetDatabaseFbRevenueService;
        @Autowired
        private IBudgetDatabaseFbCoversService budgetDatabaseFbCoversService;
        @Autowired
        private IBudgetDatabaseOtherRevenueService budgetDatabaseOtherRevenueService;

        @Autowired
        @Qualifier("moduleEventSender")
        private Sender snsSender;

        /**
         * 发送 budget 变动事件
         *
         * @param propertyId 资产 id
         * @param year       年
         * @author yyt
         * @date 2025/8/25
         */
        @Override
        public void sendBudgetEvent(Integer propertyId, Integer year) {
            BudgetDatabaseBO budgetDatabaseBO = new BudgetDatabaseBO();
            budgetDatabaseBO.setPropertyId(propertyId);
            budgetDatabaseBO.setYear(year);
            budgetDatabaseBO.setRoom(packageRoom(propertyId, year));
            budgetDatabaseBO.setFb(packageFb(propertyId, year));
            budgetDatabaseBO.setOther(packageOther(propertyId, year));
            String msg = JsonUtils.convertObjToString(objectMapper, budgetDatabaseBO);
            PublishResponse response = snsSender.publish(MoudleEventSubjectEnum.BUDGET_DATABASE.getSubject(), msg);
            log.info("BudgetDatabase send budget data,msgId:{}, body:{}", response.messageId(), msg);
        }

        /**
         * 封装 room
         *
         * @param propertyId propertyId
         * @param year       year
         * @return room
         * @author yyt
         * @date 2025/9/6
         **/
        private List<BudgetDatabaseRoomTabBO> packageRoom(Integer propertyId, Integer year) {
            List<BudgetDatabaseConfigRoomTab> tabs = budgetDatabaseConfigRoomTabService.list(propertyId, year);
            if(CollectionUtils.isEmpty(tabs)) return Collections.emptyList();

            List<Integer> tabIds = tabs.stream().map(BudgetDatabaseConfigRoomTab::getId).collect(Collectors.toList());

            // 查询 指标
            Map<Integer, Map<Integer, List<BudgetDatabaseConfigRoomTabItem>>> roomItemsByTabId = budgetDatabaseConfigRoomTabItemService.listByTabIds(tabIds)
                    .stream().collect(Collectors.groupingBy(BudgetDatabaseConfigRoomTabItem::getRoomTabId,
                            Collectors.groupingBy(BudgetDatabaseConfigRoomTabItem::getClassification)));

            // 查询 rgi 数据
            Map<Integer, Map<Integer, BudgetDatabaseRoomRgi>> rgiByTabId = budgetDatabaseRoomRgiService.listByTabIds(tabIds)
                    .stream().collect(Collectors.groupingBy(BudgetDatabaseRoomRgi::getTabId,
                            Collectors.toMap(BudgetDatabaseRoomRgi::getYearMonth, v -> v)));

            // 查询 other 数据
            Map<Integer, Map<Integer, BudgetDatabaseRoomOther>> otherByTabId = budgetDatabaseRoomOtherService.listByTabIds(tabIds)
                    .stream().collect(Collectors.groupingBy(BudgetDatabaseRoomOther::getTabId,
                            Collectors.toMap(BudgetDatabaseRoomOther::getRoomId, v -> v)));

            // 查询 room 数据
            Map<Integer, Map<Integer, Map<Integer, List<BudgetDatabaseRoom>>>> roomsByTabId = budgetDatabaseRoomService.listByTabIds(tabIds)
                    .stream().collect(Collectors.groupingBy(BudgetDatabaseRoom::getTabId,
                            Collectors.groupingBy(BudgetDatabaseRoom::getYearMonth,
                                    Collectors.groupingBy(BudgetDatabaseRoom::getRoomId))));

            List<BudgetDatabaseRoomTabBO> bos = Lists.newArrayListWithExpectedSize(tabs.size());
            for (BudgetDatabaseConfigRoomTab tab : tabs) {
                BudgetDatabaseRoomTabBO bo = new BudgetDatabaseRoomTabBO();
                bo.setTab(tab.getName());
                bo.setOpen(tab.getParticipateCalculate());

                Integer tabId = tab.getId();

                bo.setRgi(packageRgi(year, rgiByTabId.getOrDefault(tabId, Collections.emptyMap())));

                Map<Integer, List<BudgetDatabaseConfigRoomTabItem>> roomItemsByClassification = roomItemsByTabId.getOrDefault(tabId, Collections.emptyMap());

                bo.setOther(packageOther(year, roomItemsByClassification.getOrDefault(RoomClassificationEnum.OTHER.getCode(), Collections.emptyList()),
                        otherByTabId.getOrDefault(tabId, Collections.emptyMap())));

                bo.setRoom(packageRoomRevenue(year, roomItemsByClassification.getOrDefault(RoomClassificationEnum.ROOM.getCode(), Collections.emptyList()),
                        roomsByTabId.getOrDefault(tabId, Collections.emptyMap())));

                bos.add(bo);
            }
            return bos;
        }

        /**
         * 封装 other
         *
         * @param otherItems otherItems
         * @param otherByItemId     others
         * @return other
         * @author yyt
         * @date 2025/11/17
         **/
        private List<BudgetDatabaseRoomOtherBO> packageOther(Integer year, List<BudgetDatabaseConfigRoomTabItem> otherItems, Map<Integer, BudgetDatabaseRoomOther> otherByItemId) {
            List<BudgetDatabaseRoomOtherBO> bos = Lists.newArrayListWithExpectedSize(otherItems.size());
            for (BudgetDatabaseConfigRoomTabItem otherItem : otherItems) {
                BudgetDatabaseRoomOtherBO bo = new BudgetDatabaseRoomOtherBO();
                bo.setName(otherItem.getName());

                BudgetDatabaseRoomOther other = otherByItemId.getOrDefault(otherItem.getId(), new BudgetDatabaseRoomOther());

                List<BudgetDatabaseValueBO> valueBOS = Lists.newArrayListWithExpectedSize(12);
                YearMonth startMonth = YearMonth.of(year, 1);
                YearMonth endMonth = YearMonth.of(year, 12);
                for (YearMonth currentYearMonth = startMonth; !currentYearMonth.isAfter(endMonth); currentYearMonth = currentYearMonth.plusMonths(1)) {
                    BudgetDatabaseValueBO valueBO = new BudgetDatabaseValueBO();
                    valueBO.setYearMonth(YearMonthUtils.parseYearMonthToLong(currentYearMonth));
                    // 月度字段名
                    String monthFieldName = getMonthFieldName(currentYearMonth.getMonth());
                    // 设置月度值
                    valueBO.setBudget(getMonthRevenueValue(other, monthFieldName));
                    valueBOS.add(valueBO);
                }
                bo.setData(valueBOS);
                bos.add(bo);
            }

            return bos;
        }

        /**
         * 封装 rgi
         *
         * @param year           year
         * @param rgiByYearMonth rgi
         * @return rgi
         * @author yyt
         * @date 2025/9/6
         **/
        private List<BudgetDatabaseValueBO> packageRgi(Integer year, Map<Integer, BudgetDatabaseRoomRgi> rgiByYearMonth) {
            List<BudgetDatabaseValueBO> valueBOS = Lists.newArrayListWithExpectedSize(12);
            YearMonth startMonth = YearMonth.of(year, 1);
            YearMonth endMonth = YearMonth.of(year, 12);
            for (YearMonth currentYearMonth = startMonth; !currentYearMonth.isAfter(endMonth); currentYearMonth = currentYearMonth.plusMonths(1)) {
                BudgetDatabaseValueBO valueBO = new BudgetDatabaseValueBO();
                valueBO.setYearMonth(YearMonthUtils.parseYearMonthToLong(currentYearMonth));
                int yearMonth = Integer.parseInt(YearMonthUtils.DATE_TIME_FORMATTER.format(currentYearMonth));
                valueBO.setBudget(rgiByYearMonth.getOrDefault(yearMonth, new BudgetDatabaseRoomRgi()).getBudgetRgi());
                valueBOS.add(valueBO);
            }
            return valueBOS;
        }

        /**
         * 封装 room revenue
         *
         * @param year                   year
         * @param roomItems              room item
         * @param roomRevenueByYearMonth room revenue
         * @return room revenue
         * @author yyt
         * @date 2025/9/6
         **/
        private List<BudgetDatabaseRoomBO> packageRoomRevenue(Integer year, List<BudgetDatabaseConfigRoomTabItem> roomItems,
                                                              Map<Integer, Map<Integer, List<BudgetDatabaseRoom>>> roomRevenueByYearMonth) {
            List<BudgetDatabaseRoomBO> bos = Lists.newArrayListWithExpectedSize(roomItems.size());
            for (BudgetDatabaseConfigRoomTabItem roomItem : roomItems) {
                BudgetDatabaseRoomBO bo = new BudgetDatabaseRoomBO();
                bo.setName(roomItem.getName());
                bo.setType(roomItem.getType());

                Integer roomId = roomItem.getId();

                List<BudgetDatabaseValueRoomBO> valueBOS = Lists.newArrayListWithExpectedSize(12);
                YearMonth startMonth = YearMonth.of(year, 1);
                YearMonth endMonth = YearMonth.of(year, 12);
                for (YearMonth currentYearMonth = startMonth; !currentYearMonth.isAfter(endMonth); currentYearMonth = currentYearMonth.plusMonths(1)) {
                    BudgetDatabaseValueRoomBO valueBO = new BudgetDatabaseValueRoomBO();
                    valueBO.setYearMonth(YearMonthUtils.parseYearMonthToLong(currentYearMonth));
                    int yearMonth = Integer.parseInt(YearMonthUtils.DATE_TIME_FORMATTER.format(currentYearMonth));

                    List<BudgetDatabaseRoom> currentMonthRoomRevenues = roomRevenueByYearMonth.getOrDefault(yearMonth, Collections.emptyMap())
                            .getOrDefault(roomId, Collections.emptyList());
                    List<Long> roomsList = currentMonthRoomRevenues.stream().map(BudgetDatabaseRoom::getBudgetRooms).filter(Objects::nonNull).toList();
                    valueBO.setRoomsBudget(CollectionUtils.isEmpty(roomsList) ? null : roomsList.stream().mapToLong(Long::longValue).sum());
                    List<BigDecimal> revenueList = currentMonthRoomRevenues.stream().map(BudgetDatabaseRoom::getBudgetRevenue).filter(Objects::nonNull).toList();
                    valueBO.setRevenueBudget(CollectionUtils.isEmpty(revenueList) ? null : revenueList.stream().reduce(BigDecimal.ZERO, BigDecimal::add));
                    valueBOS.add(valueBO);
                }
                bo.setData(valueBOS);
                bos.add(bo);
            }

            return bos;
        }

        /**
         * 封装 fb
         *
         * @param propertyId propertyId
         * @param year       year
         * @return fb
         * @author yyt
         * @date 2025/9/8
         **/
        private List<BudgetDatabaseFbTabBO> packageFb(Integer propertyId, Integer year) {
            List<BudgetDatabaseConfigFbTab> tabs = budgetDatabaseConfigFbTabService.list(propertyId, year);
            if(CollectionUtils.isEmpty(tabs)) return Collections.emptyList();

            List<Integer> tabIds = tabs.stream().map(BudgetDatabaseConfigFbTab::getId).collect(Collectors.toList());

            // 查询 指标
            Map<Integer, Map<Integer, List<BudgetDatabaseConfigFbTabItem>>> fbItemsByTabId = budgetDatabaseConfigFbTabItemService.listByTabIds(tabIds)
                    .stream().collect(Collectors.groupingBy(BudgetDatabaseConfigFbTabItem::getFbTabId,
                            Collectors.groupingBy(BudgetDatabaseConfigFbTabItem::getClassification)));

            // 查询 revenue 数据
            Map<Integer, Map<Integer, BudgetDatabaseFbRevenue>> revenueByTabId = budgetDatabaseFbRevenueService.listByTabIds(tabIds)
                    .stream().collect(Collectors.groupingBy(BudgetDatabaseFbRevenue::getTabId,
                            Collectors.toMap(BudgetDatabaseFbRevenue::getFbId, v -> v)));

            // 查询 covers 数据
            Map<Integer, Map<Integer, BudgetDatabaseFbCovers>> coversByTabId = budgetDatabaseFbCoversService.listByTabIds(tabIds)
                    .stream().collect(Collectors.groupingBy(BudgetDatabaseFbCovers::getTabId,
                            Collectors.toMap(BudgetDatabaseFbCovers::getFbId, v -> v)));

            List<BudgetDatabaseFbTabBO> bos = Lists.newArrayListWithExpectedSize(tabs.size());
            for (BudgetDatabaseConfigFbTab tab : tabs) {
                BudgetDatabaseFbTabBO bo = new BudgetDatabaseFbTabBO();
                bo.setTab(tab.getName());
                bo.setOpen(tab.getParticipateCalculate());

                Integer tabId = tab.getId();
                Map<Integer, List<BudgetDatabaseConfigFbTabItem>> fbItemsByClassification = fbItemsByTabId.getOrDefault(tabId, Collections.emptyMap());
                bo.setRevenue(packageFbRevenue(year, fbItemsByClassification.getOrDefault(FbClassificationEnum.REVENUE.getCode(), Collections.emptyList()),
                        revenueByTabId.getOrDefault(tab.getId(), Collections.emptyMap())));

                bo.setCovers(packageFbCovers(year, fbItemsByClassification.getOrDefault(FbClassificationEnum.COVERS.getCode(), Collections.emptyList()),
                        coversByTabId.getOrDefault(tab.getId(), Collections.emptyMap())));

                bos.add(bo);
            }

            return bos;
        }

        /**
         * 封装 fb revenue
         *
         * @param year           year
         * @param fbItems        fb item
         * @param revenueByFbId  fb revenue
         * @return fb revenue
         * @author yyt
         * @date 2025/11/17
         **/
        private List<BudgetDatabaseFbRevenueBO> packageFbRevenue(Integer year, List<BudgetDatabaseConfigFbTabItem> fbItems, Map<Integer, BudgetDatabaseFbRevenue> revenueByFbId) {
            List<BudgetDatabaseFbRevenueBO> bos = Lists.newArrayListWithExpectedSize(fbItems.size());
            for (BudgetDatabaseConfigFbTabItem fbItem : fbItems) {
                BudgetDatabaseFbRevenueBO bo = new BudgetDatabaseFbRevenueBO();
                bo.setName(fbItem.getName());
                bo.setType(fbItem.getType());

                BudgetDatabaseFbRevenue fb = revenueByFbId.getOrDefault(fbItem.getId(), new BudgetDatabaseFbRevenue());

                List<BudgetDatabaseValueBO> valueBOS = Lists.newArrayListWithExpectedSize(12);
                YearMonth startMonth = YearMonth.of(year, 1);
                YearMonth endMonth = YearMonth.of(year, 12);
                for (YearMonth currentYearMonth = startMonth; !currentYearMonth.isAfter(endMonth); currentYearMonth = currentYearMonth.plusMonths(1)) {
                    BudgetDatabaseValueBO valueBO = new BudgetDatabaseValueBO();
                    valueBO.setYearMonth(YearMonthUtils.parseYearMonthToLong(currentYearMonth));
                    // 月度字段名
                    String monthFieldName = getMonthFieldName(currentYearMonth.getMonth());
                    // 设置月度值
                    valueBO.setBudget(getMonthRevenueValue(fb, monthFieldName));
                    valueBOS.add(valueBO);
                }
                bo.setData(valueBOS);
                bos.add(bo);
            }
            return bos;
        }

        /**
         * 封装 fb covers
         *
         * @param year         year
         * @param fbItems      fb item
         * @param coversByFbId fb covers
         * @return fb covers
         * @author yyt
         * @date 2025/11/17
         **/
        private List<BudgetDatabaseFbCoversBO> packageFbCovers(Integer year, List<BudgetDatabaseConfigFbTabItem> fbItems, Map<Integer, BudgetDatabaseFbCovers> coversByFbId) {
            List<BudgetDatabaseFbCoversBO> bos = Lists.newArrayListWithExpectedSize(fbItems.size());
            for (BudgetDatabaseConfigFbTabItem fbItem : fbItems) {
                BudgetDatabaseFbCoversBO bo = new BudgetDatabaseFbCoversBO();
                bo.setName(fbItem.getName());
                bo.setType(fbItem.getType());

                BudgetDatabaseFbCovers fb = coversByFbId.getOrDefault(fbItem.getId(), new BudgetDatabaseFbCovers());

                List<BudgetDatabaseValueFbCoversBO> valueBOS = Lists.newArrayListWithExpectedSize(12);
                YearMonth startMonth = YearMonth.of(year, 1);
                YearMonth endMonth = YearMonth.of(year, 12);
                for (YearMonth currentYearMonth = startMonth; !currentYearMonth.isAfter(endMonth); currentYearMonth = currentYearMonth.plusMonths(1)) {
                    BudgetDatabaseValueFbCoversBO valueBO = new BudgetDatabaseValueFbCoversBO();
                    valueBO.setYearMonth(YearMonthUtils.parseYearMonthToLong(currentYearMonth));
                    // 月度字段名
                    String monthFieldName = getMonthFieldName(currentYearMonth.getMonth());
                    // 设置月度值
                    valueBO.setBudget(getMonthRoomValue(fb, monthFieldName));
                    valueBOS.add(valueBO);
                }
                bo.setData(valueBOS);
                bos.add(bo);
            }
            return bos;
        }

        /**
         * 封装 other
         *
         * @param propertyId propertyId
         * @param year       year
         * @return other
         * @author yyt
         * @date 2025/9/8
         **/
        private List<BudgetDatabaseOtherTabBO> packageOther(Integer propertyId, Integer year) {
            List<BudgetDatabaseConfigOtherTab> tabs = budgetDatabaseConfigOtherTabService.list(propertyId, year);
            if(CollectionUtils.isEmpty(tabs)) return Collections.emptyList();

            List<Integer> tabIds = tabs.stream().map(BudgetDatabaseConfigOtherTab::getId).collect(Collectors.toList());

            // 查询 指标
            Map<Integer, List<BudgetDatabaseConfigOtherTabItem>> fbItemsByTabId = budgetDatabaseConfigOtherTabItemService.listByTabIds(tabIds)
                    .stream().collect(Collectors.groupingBy(BudgetDatabaseConfigOtherTabItem::getOtherTabId));

            // 查询 revenue 数据
            Map<Integer, Map<Integer, BudgetDatabaseOtherRevenue>> revenueByTabId = budgetDatabaseOtherRevenueService.listByTabIds(tabIds)
                    .stream().collect(Collectors.groupingBy(BudgetDatabaseOtherRevenue::getTabId,
                            Collectors.toMap(BudgetDatabaseOtherRevenue::getOtherId, v -> v)));

            List<BudgetDatabaseOtherTabBO> bos = Lists.newArrayListWithExpectedSize(tabs.size());
            for (BudgetDatabaseConfigOtherTab tab : tabs) {
                BudgetDatabaseOtherTabBO bo = new BudgetDatabaseOtherTabBO();
                bo.setTab(tab.getName());
                bo.setOpen(tab.getParticipateCalculate());

                Map<Integer, BudgetDatabaseOtherRevenue> revenueByOtherId = revenueByTabId.getOrDefault(tab.getId(), Collections.emptyMap());

                List<BudgetDatabaseConfigOtherTabItem> otherItems = fbItemsByTabId.getOrDefault(tab.getId(), Collections.emptyList());
                List<BudgetDatabaseOtherBO> itemBOS = Lists.newArrayListWithExpectedSize(otherItems.size());
                for (BudgetDatabaseConfigOtherTabItem otherItem : otherItems) {
                    BudgetDatabaseOtherBO itemBO = new BudgetDatabaseOtherBO();
                    itemBO.setName(otherItem.getName());

                    BudgetDatabaseOtherRevenue other = revenueByOtherId.getOrDefault(otherItem.getId(), new BudgetDatabaseOtherRevenue());

                    List<BudgetDatabaseValueBO> valueBOS = Lists.newArrayListWithExpectedSize(12);
                    YearMonth startMonth = YearMonth.of(year, 1);
                    YearMonth endMonth = YearMonth.of(year, 12);
                    for (YearMonth currentYearMonth = startMonth; !currentYearMonth.isAfter(endMonth); currentYearMonth = currentYearMonth.plusMonths(1)) {
                        BudgetDatabaseValueBO valueBO = new BudgetDatabaseValueBO();
                        valueBO.setYearMonth(YearMonthUtils.parseYearMonthToLong(currentYearMonth));
                        // 月度字段名
                        String monthFieldName = getMonthFieldName(currentYearMonth.getMonth());
                        // 设置月度值
                        valueBO.setBudget(getMonthRevenueValue(other, monthFieldName));
                        valueBOS.add(valueBO);
                    }
                    itemBO.setData(valueBOS);
                    itemBOS.add(itemBO);
                }
                bo.setOther(itemBOS);
                bos.add(bo);
            }

            return bos;
        }

        /**
         * 获取月份字段名
         *
         * @param month 月份
         * @return 字段名
         * @author yyt
         * @date 2025/8/25
         **/
        private String getMonthFieldName(Month month) {
            return month.name().toLowerCase().substring(0, 1).toLowerCase() +
                    month.name().toLowerCase().substring(1).toLowerCase();
        }

        /**
         * 通过反射获取月份值
         *
         * @param obj       对象
         * @param fieldName 字段名
         * @return 月份值
         * @author yyt
         * @date 2025/8/25
         **/
        private BigDecimal getMonthRevenueValue(Object obj, String fieldName) {
            try {
                Field field = obj.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                return (BigDecimal) field.get(obj);
            } catch (Exception e) {
                throw new InternalServerErrorException(BaseErrorCodeEnum.SYSTEM_ERROR.getI18nCode(),
                        BaseErrorCodeEnum.SYSTEM_ERROR.getCode(), "get month revenue value error", e);
            }
        }

        /**
         * 通过反射获取月份值
         *
         * @param obj       对象
         * @param fieldName 字段名
         * @return 月份值
         * @author yyt
         * @date 2025/8/25
         **/
        private Long getMonthRoomValue(Object obj, String fieldName) {
            try {
                Field field = obj.getClass().getDeclaredField(fieldName);
                field.setAccessible(true);
                return (Long) field.get(obj);
            } catch (Exception e) {
                throw new InternalServerErrorException(BaseErrorCodeEnum.SYSTEM_ERROR.getI18nCode(),
                        BaseErrorCodeEnum.SYSTEM_ERROR.getCode(), "get month room value error", e);
            }
        }

    }