# ReportImportLogServiceImpl.java

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

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.cons.ReportImportResultCons;
    import cloud.wconnect.commonlib.cons.SystemPlatformEnum;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.pojo.dto.ListPagedDTO;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.pojo.dto.scheduler.JobParameterDTO;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.TransactionUtils;
    import cloud.wconnect.rateshop.cons.rateshop.RateShopCons;
    import cloud.wconnect.rateshop.entity.rateshop.ReportImportLog;
    import cloud.wconnect.rateshop.mapper.rateshop.ReportImportLogMapper;
    import cloud.wconnect.rateshop.pojo.dto.rateshop.ReportImportDTO;
    import cloud.wconnect.rateshop.pojo.query.rateshop.RateShopImportLogQuery;
    import cloud.wconnect.rateshop.pojo.vo.rateshop.ReportImportLogVO;
    import cloud.wconnect.rateshop.service.rateshop.IReportImportLogService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
    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 java.util.HashSet;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    import java.util.stream.Stream;

    /**
     * <p>
     * 服务实现类
     * </p>
     *
     * @author lichen
     * @since 2023-12-04
     */
    @DS("rate_shop")
    @Service
    public class ReportImportLogServiceImpl extends ServiceImpl<ReportImportLogMapper, ReportImportLog> implements IReportImportLogService {

        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private BeanMapper beanMapper;

        /**
         * 保存进行中的记录
         *
         * @param propertyDTO     资产DTO
         * @param reportImportDTO 导入DTO
         * @param loginUserId     登录用户ID
         * @return cloud.wconnect.rateshop.entity.rateshop.ReportImportLog
         * @author lichen
         * @date 2023/12/4
         */
        @Override
        public ReportImportLog saveInProgress(PropertyDTO propertyDTO, ReportImportDTO reportImportDTO, int loginUserId) {
            ReportImportLog reportImportLog = new ReportImportLog();
            reportImportLog.setPropertyId(propertyDTO.getId());
            reportImportLog.setTheDate(DateTimeUtils.dateNowTimestamp(propertyDTO.getTimezone()));
            reportImportLog.setReportType(reportImportDTO.getReportType());
            reportImportLog.setStartDate(reportImportDTO.getStartDate());
            reportImportLog.setEndDate(reportImportDTO.getEndDate());
            reportImportLog.setCreatedBy(loginUserId);
            reportImportLog.setCreatedTime(DateTimeUtils.nowTimestamp());
            reportImportLog.setResolvedBy(0);
            reportImportLog.setResolvedTime(0L);
            reportImportLog.setStatus(ReportImportResultCons.IMPORT_IN_PROGRESS);

            save(reportImportLog);
            return reportImportLog;
        }

        /**
         * 根据日志id更新处理结果和解决人、解决时间
         *
         * @param id           日志ID
         * @param userId       用户ID
         * @param importResult 处理结果
         * @param key          S3 key
         * @author lichen
         * @date 2023/12/4
         */
        @Override
        public void updateLog(Long id, Integer userId, String key, boolean importResult) {
            ReportImportLog oriReportImportLog = getById(id);
            if (oriReportImportLog.getStatus() == ReportImportResultCons.IMPORT_RESULT_REPAIRING
                    && importResult) {
                oriReportImportLog.setResolvedBy(userId);
                oriReportImportLog.setResolvedTime(DateTimeUtils.nowTimestamp());
            }
            oriReportImportLog.setUrl(key);
            oriReportImportLog.setStatus(importResult ? ReportImportResultCons.IMPORT_RESULT_SUCCESS :
                    ReportImportResultCons.IMPORT_RESULT_FAIL);
            updateById(oriReportImportLog);
        }

        /**
         * 保存导入记录
         *
         * @param propertyDTO  资产DTO
         * @param dateRange    日期范围
         * @param key          S3 key
         * @param importResult 导入结果
         * @param reportType   报告类型
         * @param operatorId   操作人 id（0 表示系统）
         * @author zc
         * @date 2024/5/1
         */
        @Override
        public void save(PropertyDTO propertyDTO, Map<String, Long> dateRange, String key, int importResult, int reportType, int operatorId) {
            ReportImportLog reportImportLog = new ReportImportLog();
            reportImportLog.setPropertyId(propertyDTO.getId());
            reportImportLog.setTheDate(DateTimeUtils.dateNowTimestamp(propertyDTO.getTimezone()));
            reportImportLog.setReportType(reportType);
            reportImportLog.setStartDate(dateRange.get(JobParameterDTO.START_DATE));
            reportImportLog.setEndDate(dateRange.get(JobParameterDTO.END_DATE));
            reportImportLog.setUrl(key);
            reportImportLog.setCreatedBy(operatorId);
            reportImportLog.setCreatedTime(DateTimeUtils.nowTimestamp());
            reportImportLog.setResolvedBy(0);
            reportImportLog.setResolvedTime(0L);
            reportImportLog.setStatus(importResult);
            save(reportImportLog);
        }

        /**
         * 分页查询导入记录
         *
         * @param tenantId   租户id
         * @param propertyId 资产id
         * @param query      查询参数
         * @return cloud.wconnect.commonlib.pojo.dto.ListPagedDTO<cloud.wconnect.rateshop.pojo.vo.rateshop.ReportImportLogVO>
         * @author lichen
         * @date 2025/12/30
         */
        @Override
        public ListPagedDTO<ReportImportLogVO> pageList(Integer tenantId, int propertyId, RateShopImportLogQuery query) {
            long total;
            List<ReportImportLog> importLogs;
            LambdaQueryWrapper<ReportImportLog> condition = new QueryWrapper<ReportImportLog>().lambda()
                    .in(CollectionUtils.isNotEmpty(query.getReportTypes()), ReportImportLog::getReportType, query.getReportTypes())
                    .eq(ReportImportLog::getPropertyId, propertyId)
                    .in(CollectionUtils.isNotEmpty(query.getStatus()), ReportImportLog::getStatus, query.getStatus())
                    .and(Objects.nonNull(query.getStartOperationDate()) && Objects.nonNull(query.getEndOperationDate()),
                            wrapper -> wrapper.between(ReportImportLog::getCreatedTime,
                                            query.getStartOperationDate(), query.getEndOperationDate())
                                    .or().between(ReportImportLog::getResolvedTime,
                                            query.getStartOperationDate(), query.getEndOperationDate()))
                    .between(Objects.nonNull(query.getStartFromDataDate()) && Objects.nonNull(query.getStartToDataDate()),
                            ReportImportLog::getStartDate, query.getStartFromDataDate(), query.getStartToDataDate())
                    .between(Objects.nonNull(query.getEndFromDataDate()) && Objects.nonNull(query.getEndToDataDate()),
                            ReportImportLog::getEndDate, query.getEndFromDataDate(), query.getEndToDataDate());
            if (Objects.nonNull(query.getPage()) && Objects.nonNull(query.getSize())) {
                Page<ReportImportLog> page = page(new Page<>(query.getPage(), query.getSize()),
                        condition.orderByDesc(ReportImportLog::getId));
                total = page.getTotal();
                importLogs = page.getRecords();
            } else {
                importLogs = list(condition);
                total = importLogs.size();
            }

            //查询用户名称
            List<Integer> userIds = importLogs.stream().flatMap(item -> Stream.of(item.getCreatedBy(), item.getResolvedBy())).toList();
            Map<Integer, String> userId2Name = userInternalService.getNameMapByIds(tenantId, userIds);

            return new ListPagedDTO<>(total, beanMapper.mapList(importLogs, ReportImportLogVO.class,
                    item -> {
                        item.setCreatedByName(userId2Name.get(item.getCreatedBy()));
                        item.setResolvedByName(userId2Name.get(item.getResolvedBy()));
                    }));
        }

        /**
         * 校验报告类型是否符合预期
         *
         * @param pmsType    当前资产配置的PMS Type
         * @param reportType 报告类型
         * @author yyt
         * @date 2026/3/10
         **/
        @Override
        public void checkReportType(String pmsType, Integer reportType) {
          checkReportType(pmsType, Lists.newArrayList(reportType));
        }

        /**
         * 校验报告类型是否符合预期
         *
         * @param pmsType     当前资产配置的PMS Type
         * @param reportTypes 报告类型
         * @author yyt
         * @date 2026/3/10
         **/
        @Override
        public void checkReportType(String pmsType, List<Integer> reportTypes) {
            List<Integer> validReportTypes;
            if (SystemPlatformEnum.OPERA.getDesc().equals(pmsType)) {
                validReportTypes = RateShopCons.OPERA_PMS_REPORT_TYPE_LIST;
            } else if(SystemPlatformEnum.SHI_JI.getDesc().equals(pmsType)) {
                validReportTypes = RateShopCons.SHIJI_PMS_REPORT_TYPE_LIST;
            } else {
                validReportTypes = RateShopCons.PEP_PMS_REPORT_TYPE_LIST;
            }
            if (!new HashSet<>(validReportTypes).containsAll(reportTypes)) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_INTEGRATION_REPORT_TYPE_NOT_SUPPORTED,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "The reportType must be in:" + validReportTypes);
            }
        }

        /**
         * 修改导入状态
         *
         * @param importLog    导入记录
         * @param importResult 导入结果（true：导入成功，false：导入失败）
         * @param userId       操作人
         * @author yyt
         * @date 2026/3/10
         **/
        @Override
        public void updateImportStatus(ReportImportLog importLog, boolean importResult, int userId) {
            if (importResult) {
                importSuccess(importLog, userId);
            } else {
                importFail(importLog);
            }
        }

        /**
         * 导入成功
         *
         * @param importLog 导入记录
         * @param userId    操作人
         * @author yyt
         * @date 2026/3/10
         **/
        private void importSuccess(ReportImportLog importLog, int userId) {
            TransactionUtils.afterCommitSyncExecute(() -> {
                // 更新导入记录
                ReportImportLog updateLog = new ReportImportLog();
                updateLog.setId(importLog.getId());
                updateLog.setStatus(ReportImportResultCons.IMPORT_RESULT_SUCCESS);
                if (importLog.getStatus() == ReportImportResultCons.IMPORT_RESULT_REPAIRING) {
                    updateLog.setResolvedBy(userId).setResolvedTime(DateTimeUtils.nowTimestamp());
                }
                updateById(updateLog);
            });
        }

        /**
         * 导入失败
         *
         * @param importLog 导入记录
         * @author yyt
         * @date 2026/3/10
         **/
        private void importFail(ReportImportLog importLog) {
            TransactionUtils.afterCompletionRollbackSyncExecute(() -> {
                // 更新导入记录
                ReportImportLog updateLog = new ReportImportLog();
                updateLog.setId(importLog.getId());
                updateLog.setStatus(ReportImportResultCons.IMPORT_RESULT_FAIL);
                updateById(updateLog);
            });
        }

    }