# SvaOperatingStatisticsOriginalServiceImpl.java

    package cloud.wconnect.workperformance.service.sva.operatingstatistics.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.workperformance.entity.sva.operatingstatistics.SvaOperatingStatisticsOriginal;
    import cloud.wconnect.workperformance.mapper.sva.operatingstatistics.SvaOperatingStatisticsOriginalMapper;
    import cloud.wconnect.workperformance.pojo.bo.sva.operatingstatistics.OperatingStatisticsListBO;
    import cloud.wconnect.workperformance.service.sva.operatingstatistics.ISvaOperatingStatisticsOriginalService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.google.common.collect.Lists;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

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

    /**
     * <p>
     * 酒店运营收入分析原始数据表 服务实现类
     * </p>
     *
     * @author lichen
     * @since 2026-04-13
     */
    @Service
    @DS("work_performance")
    public class SvaOperatingStatisticsOriginalServiceImpl extends ServiceImpl<SvaOperatingStatisticsOriginalMapper, SvaOperatingStatisticsOriginal> implements ISvaOperatingStatisticsOriginalService {

        @Autowired
        private BeanMapper beanMapper;

        /**
         * 按日期集合、指定数据源查询
         *
         * @param propertyId 资产id
         * @param dates      日期集合
         * @param dataType   数据源
         * @return java.util.List<cloud.wconnect.workperformance.entity.sva.operatingstatistics.SvaOperatingStatisticsOriginal>
         * @author lichen
         * @date 2026/4/13
         */
        @Override
        public List<SvaOperatingStatisticsOriginal> listByDatesAndDataType(Integer propertyId, List<Integer> dates, int dataType) {
            if (CollectionUtils.isEmpty(dates)) return Collections.emptyList();
            return list(new LambdaQueryWrapper<SvaOperatingStatisticsOriginal>()
                    .eq(SvaOperatingStatisticsOriginal::getPropertyId, propertyId)
                    .in(SvaOperatingStatisticsOriginal::getDate, dates)
                    .eq(SvaOperatingStatisticsOriginal::getDataType, dataType));
        }

        /**
         * 按唯一字段批量保存或更新
         *
         * @param batchList 批量数据
         * @author lichen
         * @date 2026/4/13
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void saveOrUpdateByUnique(List<SvaOperatingStatisticsOriginal> batchList) {
            if (CollectionUtils.isEmpty(batchList)) return;

            baseMapper.saveOrUpdateByUnique(batchList);
        }

        /**
         * 按日期集合查询
         *
         * @param propertyId 资产id
         * @param dates      日期集合
         * @return java.util.List<cloud.wconnect.workperformance.entity.sva.operatingstatistics.SvaOperatingStatisticsOriginal>
         * @author lichen
         * @date 2026/4/13
         */
        @Override
        public List<SvaOperatingStatisticsOriginal> listByDates(Integer propertyId, List<Integer> dates) {
            if (CollectionUtils.isEmpty(dates)) return Collections.emptyList();
            return list(new LambdaQueryWrapper<SvaOperatingStatisticsOriginal>()
                    .eq(SvaOperatingStatisticsOriginal::getPropertyId, propertyId)
                    .in(SvaOperatingStatisticsOriginal::getDate, dates));
        }

        /**
         * 处理非M3 API的Operating Statistics原始数据
         *
         * @param propertyDTO 资产
         * @param boList      报告数据 BO
         * @param operatorId  操作人 id
         * @param dates       日期集合
         * @param dataType    数据源 1:PDF 2:CSV 4:Other
         * @author lichen
         * @date 2025/11/21
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void handleOperatingStatisticsOriginByNonM3Api(PropertyDTO propertyDTO, List<OperatingStatisticsListBO> boList,
                                                              int operatorId, List<Integer> dates, Integer dataType) {
            // 按日期集合查询
            List<SvaOperatingStatisticsOriginal> existOriginalEntitys = listByDatesAndDataType(propertyDTO.getId(), dates, dataType);
            Map<Integer, SvaOperatingStatisticsOriginal> date2ExistOriginalEntitys = existOriginalEntitys.stream()
                    .collect(Collectors.toMap(SvaOperatingStatisticsOriginal::getDate, Function.identity()));

            // 资产对应的BO数据集合
            Map<Integer, OperatingStatisticsListBO> date2BO = boList.stream().collect(Collectors.toMap(
                    item -> Integer.valueOf(item.getTheDay().replace("-", "")),
                    Function.identity()));

            ArrayList<Long> updateNullIds = Lists.newArrayListWithCapacity(dates.size());
            ArrayList<SvaOperatingStatisticsOriginal> insertBatch = Lists.newArrayListWithCapacity(dates.size());
            ArrayList<SvaOperatingStatisticsOriginal> updateBatch = Lists.newArrayListWithCapacity(dates.size());

            long nowTimestamp = DateTimeUtils.nowTimestamp();

            for (Integer date : dates) {
                // 报告数据
                OperatingStatisticsListBO bo = date2BO.get(date);
                SvaOperatingStatisticsOriginal exist = date2ExistOriginalEntitys.get(date);

                if (Objects.isNull(bo)) {
                    if (Objects.nonNull(exist)) {
                        updateNullIds.add(exist.getId());
                    }else{
                        // 初始化一条指标都为null的数据
                        SvaOperatingStatisticsOriginal insertEntity = new SvaOperatingStatisticsOriginal();
                        insertEntity.setTenantId(propertyDTO.getTenantId());
                        insertEntity.setPropertyId(propertyDTO.getId());
                        insertEntity.setDate(date);
                        insertEntity.setDataType(dataType);
                        insertEntity.setCreateBy(operatorId);
                        insertEntity.setCreatedTime(nowTimestamp);
                        insertEntity.setLastUpdatedBy(operatorId);
                        insertEntity.setLastUpdatedTime(nowTimestamp);
                        insertBatch.add(insertEntity);
                    }
                } else {
                    if (Objects.isNull(exist)) {
                        SvaOperatingStatisticsOriginal insertEntity = beanMapper.map(bo, SvaOperatingStatisticsOriginal.class);
                        insertEntity.setTenantId(propertyDTO.getTenantId());
                        insertEntity.setPropertyId(propertyDTO.getId());
                        insertEntity.setDate(date);
                        insertEntity.setDataType(dataType);
                        insertEntity.setCreateBy(operatorId);
                        insertEntity.setCreatedTime(nowTimestamp);
                        insertEntity.setLastUpdatedBy(operatorId);
                        insertEntity.setLastUpdatedTime(nowTimestamp);
                        insertBatch.add(insertEntity);
                    } else {
                        // 修改
                        exist.setLastUpdatedBy(operatorId);
                        exist.setLastUpdatedTime(nowTimestamp);
                        exist.setRoomsRented(bo.getRoomsRented());
                        exist.setOccPercent(bo.getOccPercent());
                        exist.setAdr(bo.getAdr());
                        exist.setRevPar(bo.getRevPar());
                        exist.setRoomRev(bo.getRoomRev());
                        exist.setFoodRev(bo.getFoodRev());
                        exist.setBevRev(bo.getBevRev());
                        exist.setOtherRev(bo.getOtherRev());
                        exist.setTotalRev(bo.getTotalRev());
                        exist.setFb2Rev(bo.getFb2Rev());
                        updateBatch.add(exist);
                    }
                }
            }

            if (CollectionUtils.isNotEmpty(updateNullIds)) {
                // 指标数据都更新为null
                baseMapper.updateNullByIds(updateNullIds, operatorId, nowTimestamp);
            }
            saveBatch(insertBatch);
            updateBatchById(updateBatch);
        }
    }