# HotelKpiWconnectMonthlyReportServiceImpl.java

    package cloud.wconnect.workperformance.service.hotelkpi.impl;

    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.workperformance.entity.hotelkpi.HotelKpiWconnectMonthlyReport;
    import cloud.wconnect.workperformance.mapper.hotelkpi.HotelKpiWconnectMonthlyReportMapper;
    import cloud.wconnect.workperformance.pojo.bo.modelevent.monthlyreport.MonthlyReportEventDataBO;
    import cloud.wconnect.workperformance.pojo.bo.modelevent.monthlyreport.MonthlyReportEventValueBO;
    import cloud.wconnect.workperformance.service.hotelkpi.IHotelKpiWconnectMonthlyReportService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.google.common.collect.Lists;
    import org.apache.commons.collections4.CollectionUtils;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.Comparator;
    import java.util.List;

    /**
     * <p>
     * Hotel KPI - wconnect Monthly Report 服务实现类
     * </p>
     *
     * @author zc
     * @since 2025-09-08
     */
    @Service
    @DS("work_performance")
    public class HotelKpiWconnectMonthlyReportServiceImpl extends ServiceImpl<HotelKpiWconnectMonthlyReportMapper, HotelKpiWconnectMonthlyReport> implements IHotelKpiWconnectMonthlyReportService {

        /**
         * 保存数据
         *
         * @param propertyDTO 资产
         * @param type        数据类型
         * @param boList      数据
         * @author zc
         * @date 2025/9/8
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void saveData(PropertyDTO propertyDTO, int type, List<MonthlyReportEventDataBO> boList) {
            List<HotelKpiWconnectMonthlyReport> monthlyReportList = Lists.newArrayList();
            for (MonthlyReportEventDataBO bo : boList) {
                for (MonthlyReportEventValueBO valueBO : bo.getData()) {
                    HotelKpiWconnectMonthlyReport monthlyReport = new HotelKpiWconnectMonthlyReport();
                    monthlyReport.setPropertyId(propertyDTO.getId());
                    monthlyReport.setMonth(bo.getYearMonth());
                    monthlyReport.setType(type);
                    monthlyReport.setName(valueBO.getCategoryName());
                    monthlyReport.setActual(valueBO.getActual());
                    monthlyReport.setBudget(valueBO.getTarget());
                    monthlyReport.setLastYear(valueBO.getLy());

                    monthlyReportList.add(monthlyReport);
                }
            }
            if (CollectionUtils.isEmpty(monthlyReportList)) {
                return;
            }

            // 按唯一索引字段排序，避免死锁
            monthlyReportList.sort(Comparator.comparing(HotelKpiWconnectMonthlyReport::getPropertyId)
                    .thenComparing(HotelKpiWconnectMonthlyReport::getMonth)
                    .thenComparing(HotelKpiWconnectMonthlyReport::getType)
                    .thenComparing(HotelKpiWconnectMonthlyReport::getName));

            baseMapper.insertOrUpdateBatchByUnique(monthlyReportList);
        }

        /**
         * 根据时间范围获取数据
         *
         * @param propertyId 资产ID
         * @param type       类型
         * @param startDate  开始时间(yyyyMM)
         * @param endDate    结束时间(yyyyMM)
         * @return 数据
         * @author zc
         * @date 2025/9/8
         */
        @Override
        public List<HotelKpiWconnectMonthlyReport> listByDateRange(int propertyId, int type, long startDate, long endDate) {
            return list(new LambdaQueryWrapper<HotelKpiWconnectMonthlyReport>()
                    .eq(HotelKpiWconnectMonthlyReport::getPropertyId, propertyId)
                    .eq(HotelKpiWconnectMonthlyReport::getType, type)
                    .between(HotelKpiWconnectMonthlyReport::getMonth, startDate, endDate));
        }
    }