# BookingAnalysisController.java

    package cloud.wconnect.rateshop.controller.booking;

    import cloud.wconnect.commonlib.annotation.ApiId;
    import cloud.wconnect.commonlib.component.SessionContext;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.exception.ForbiddenException;
    import cloud.wconnect.commonlib.util.I18nMessageUtils;
    import cloud.wconnect.commonlib.util.YearMonthUtils;
    import cloud.wconnect.rateshop.pojo.dto.booking.BookingWidgetDTO;
    import cloud.wconnect.rateshop.pojo.query.booking.BookingAnalysisQuery;
    import cloud.wconnect.rateshop.service.booking.IBookingAnalysisService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;

    import jakarta.annotation.Resource;
    import jakarta.validation.Valid;
    import java.time.YearMonth;
    import java.util.List;

    /**
     * <p>
     *  前端控制器
     * </p>
     *
     * @author yyt
     * @since 2024-07-22
     */
    @RestController
    @RequestMapping("/booking")
    public class BookingAnalysisController {

        @Resource
        private IBookingAnalysisService bookingAnalysisService;
        @Autowired
        private SessionContext sessionContext;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;

        /**
         * 1241 - 查询 Stay Length 数据
         *
         * @param query 查询条件
         * @return Stay Length 数据
         * @author yyt
         * @date 2024/7/23
         **/
        @ApiId(1241)
        @GetMapping("/stay-length")
        public List<BookingWidgetDTO> listStayLength(@Valid BookingAnalysisQuery query) {
            checkProperty(query.getPropertyIds());

            checkDateRange(query.getStartMonth(), query.getEndMonth());

            return bookingAnalysisService.listStayLength(query);
        }

        /**
         * 1242 - 查询 Quarterly Trends 数据
         *
         * @param query 查询条件
         * @return Quarterly Trends 数据
         * @author yyt
         * @date 2024/7/23
         **/
        @ApiId(1242)
        @GetMapping("/quarterly-trends")
        public List<BookingWidgetDTO> listQuarterlyTrends(@Valid BookingAnalysisQuery query) {
            checkProperty(query.getPropertyIds());

            checkDateRange(query.getStartMonth(), query.getEndMonth());

            return bookingAnalysisService.listQuarterlyTrends(query);
        }

        /**
         * 1243 - 查询 Monthly Trends 数据
         *
         * @param query 查询条件
         * @return Monthly Trends 数据
         * @author yyt
         * @date 2024/7/23
         **/
        @ApiId(1243)
        @GetMapping("/monthly-trends")
        public List<BookingWidgetDTO> listMonthlyTrends(@Valid BookingAnalysisQuery query) {
            checkProperty(query.getPropertyIds());

            checkDateRange(query.getStartMonth(), query.getEndMonth());

            return bookingAnalysisService.listMonthlyTrends(query);
        }

        /**
         * 1244 - 查询 Far-out vs. Close-in 数据
         *
         * @param query 查询条件
         * @return Far-out vs. Close-in 数据
         * @author yyt
         * @date 2024/7/23
         **/
        @ApiId(1244)
        @GetMapping("/advance")
        public List<BookingWidgetDTO> listAdvance(@Valid BookingAnalysisQuery query) {
            checkProperty(query.getPropertyIds());

            checkDateRange(query.getStartMonth(), query.getEndMonth());

            return bookingAnalysisService.listAdvance(query);
        }

        /**
         * 1245 - 查询 Day Of The Week Trends 数据
         *
         * @param query 查询条件
         * @return Day Of The Week Trends 数据
         * @author yyt
         * @date 2024/7/23
         **/
        @ApiId(1245)
        @GetMapping("/week")
        public List<BookingWidgetDTO> listWeek(@Valid BookingAnalysisQuery query) {
            checkProperty(query.getPropertyIds());

            checkDateRange(query.getStartMonth(), query.getEndMonth());

            return bookingAnalysisService.listWeek(query);
        }

        /**
         * 检查资产参数是否属于当前登录用户所属资产
         *
         * @param propertyIds 资产参数
         * @author yyt
         * @date 2024/7/23
         **/
        private void checkProperty(List<Integer> propertyIds) {
            if (propertyIds.stream().anyMatch(item -> !sessionContext.getPropertyIds().contains(item))) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "propertyIds parameter error");
            }
        }

        /**
         * 检查日期范围
         *
         * @param startMonth 开始月
         * @param endMonth   结束月
         * @author yyt
         * @date 2024/7/24
         **/
        private void checkDateRange(Integer startMonth, Integer endMonth) {
            // 最多 12 个月
            YearMonth startYearMonth = YearMonthUtils.getYearMonth(startMonth.toString());
            YearMonth endYearMonth = YearMonthUtils.getYearMonth(endMonth.toString());
            if (endYearMonth.isAfter(startYearMonth.plusMonths(11))) {
                throw new BadRequestException(CommonErrorI18nConstant.SELECT_DATE_LIMIT_MONTH,
                        i18nMessageUtils.getErrorParamMapNotNeedTranslate(12),
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "Select a maximum of 12 months");
            }
        }

    }