# HotelKpiM3DailyServiceImpl.java

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

    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.JsonUtils;
    import cloud.wconnect.workperformance.cons.S3BucketFunctionCons;
    import cloud.wconnect.workperformance.entity.hotelkpi.HotelKpiM3Daily;
    import cloud.wconnect.workperformance.mapper.hotelkpi.HotelKpiM3DailyMapper;
    import cloud.wconnect.workperformance.pojo.bo.hotelkpi.m3.HotelKpiM3FbDailyFlashBO;
    import cloud.wconnect.workperformance.pojo.dto.hotelkpi.m3.HotelKpiM3DailyDTO;
    import cloud.wconnect.workperformance.pojo.dto.hotelkpi.m3.HotelKpiM3DailyValueDTO;
    import cloud.wconnect.workperformance.service.AmazonS3Service;
    import cloud.wconnect.workperformance.service.hotelkpi.IHotelKpiM3DailyService;
    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.fasterxml.jackson.databind.ObjectMapper;
    import jakarta.annotation.Resource;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.commons.collections4.CollectionUtils;
    import org.springframework.stereotype.Service;

    import java.io.IOException;
    import java.io.InputStream;
    import java.time.LocalDate;
    import java.util.Collections;
    import java.util.List;

    /**
     * <p>
     * Hotel KPI M3 Daily Flash 服务实现类
     * </p>
     *
     * @author zc
     * @since 2025-09-08
     */
    @Slf4j
    @Service
    @DS("work_performance")
    public class HotelKpiM3DailyServiceImpl extends ServiceImpl<HotelKpiM3DailyMapper, HotelKpiM3Daily> implements IHotelKpiM3DailyService {

        @Resource
        private ObjectMapper objectMapper;
        @Resource
        private AmazonS3Service amazonS3Service;

        /**
         * 保存数据并返回数据日期
         *
         * @param propertyDTO  资产数据
         * @param nowLocalDate 当前时间
         * @param bo           报告数据
         * @param path         报告文件路径
         * @return 数据日期
         * @author zc
         * @date 2025/9/8
         */
        @Override
        public long saveData(PropertyDTO propertyDTO, LocalDate nowLocalDate, HotelKpiM3FbDailyFlashBO bo, String path) {
            // 上传报告，用于点击指标下载报告
            uploadReport(path);

            // 当天导入昨天的数据，转换为昨天日期
            long date = Long.parseLong(DateTimeUtils.localDateToStr(nowLocalDate.minusDays(1),
                    BaseConstant.DATE_FORMAT_YYYYMMDD));

            HotelKpiM3Daily entity = new HotelKpiM3Daily();
            entity.setPropertyId(propertyDTO.getId());
            entity.setDate(date);
            entity.setFileUrl(path);
            entity.setFbRevenue(JsonUtils.convertObjToString(objectMapper, bo.getFbRevenue()));
            entity.setBanquetRevenue(JsonUtils.convertObjToString(objectMapper, bo.getBanquetRevenue()));
            entity.setOtherRevenue(JsonUtils.convertObjToString(objectMapper, bo.getOtherRevenue()));

            baseMapper.insertOrUpdateByUnique(entity);

            return date;
        }

        /**
         * 根据日期范围获取数据
         *
         * @param propertyId 资产 id
         * @param startDate  开始日期(yyyyMMdd)
         * @param endDate    结束日期(yyyyMMdd)
         * @return HotelKpiM3DailyDTO 集合
         * @author zc
         * @date 2025/9/11
         */
        @Override
        public List<HotelKpiM3DailyDTO> listByDateRange(int propertyId, long startDate, long endDate) {
            List<HotelKpiM3Daily> list = list(new LambdaQueryWrapper<HotelKpiM3Daily>()
                    .eq(HotelKpiM3Daily::getPropertyId, propertyId)
                    .between(HotelKpiM3Daily::getDate, startDate, endDate));
            if (CollectionUtils.isEmpty(list)) {
                return Collections.emptyList();
            }
            return list.stream().map(item -> {
                HotelKpiM3DailyDTO dto = new HotelKpiM3DailyDTO();
                dto.setPropertyId(item.getPropertyId());
                dto.setDate(item.getDate());
                dto.setFileUrl(item.getFileUrl());
                dto.setFbRevenue(JsonUtils.convertStringToObject(objectMapper, item.getFbRevenue(),
                        HotelKpiM3DailyValueDTO.class));
                dto.setBanquetRevenue(JsonUtils.convertStringToObject(objectMapper, item.getBanquetRevenue(),
                        HotelKpiM3DailyValueDTO.class));
                dto.setOtherRevenue(JsonUtils.convertStringToObject(objectMapper, item.getOtherRevenue(),
                        HotelKpiM3DailyValueDTO.class));
                return dto;
            }).toList();
        }

        /**
         * 上传报告，用于点击指标下载报告
         *
         * @param fileUrl S3 路径
         * @author zc
         * @date 2025/8/22
         */
        private void uploadReport(String fileUrl) {
            try (InputStream in = amazonS3Service.getFile(fileUrl)) {
                amazonS3Service.uploadFile(S3BucketFunctionCons.HOTEL_KPI, in, fileUrl);
            } catch (IOException e) {
                log.error("HotelKpiStrWeekServiceImpl Upload M3 Daily report error. fileUrl: {}", fileUrl, e);
            }
        }
    }