# GuestInHouseParseByOpera.java

    package cloud.wconnect.frontoffice.service.clc.guestinhouse;

    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.ReportImportResultCons;
    import cloud.wconnect.commonlib.cons.SystemPlatformEnum;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.exception.ParseReportException;
    import cloud.wconnect.commonlib.pojo.bo.SymbolBO;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.FileCheckUtils;
    import cloud.wconnect.commonlib.util.UploadUtils;
    import cloud.wconnect.frontoffice.cons.S3BucketFunctionCons;
    import cloud.wconnect.frontoffice.entity.clc.ClcGuestInhImportLog;
    import cloud.wconnect.frontoffice.pojo.bo.clc.GuestInHouseBO;
    import cloud.wconnect.frontoffice.service.AmazonS3Service;
    import cloud.wconnect.frontoffice.service.clc.IClcGuestInhImportLogService;
    import cloud.wconnect.frontoffice.service.clc.IClcGuestInhService;
    import cloud.wconnect.frontoffice.service.clc.IClcHandleFileService;
    import cloud.wconnect.sns.http.processor.Sender;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.google.common.collect.Lists;
    import jakarta.annotation.Resource;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.stereotype.Service;
    import org.springframework.web.multipart.MultipartFile;

    import java.io.InputStream;
    import java.util.List;

    /**
     * @author yyt
     * 2023/7/31
     */
    @Service
    @DS("logbook")
    public class GuestInHouseParseByOpera implements IGuestInHouseParse{

        @Resource
        private IClcGuestInhService clcGuestInhService;
        @Resource
        private IClcGuestInhImportLogService clcGuestInhImportLogService;
        @Resource
        private IClcHandleFileService clcHandleFileService;
        @Resource
        private AmazonS3Service amazonS3Service;
        @Resource
        private ObjectMapper objectMapper;

        @Value("${aws-s3.third-party.key.clc.guest-in-house}")
        private String guestInHouseS3key;

        @Value("${file-max-size.import-report.clc}")
        private Long importReportFileMaxSize;

        private final Sender snsSender;

        public GuestInHouseParseByOpera(@Qualifier("3pSender") Sender snsSender) {
            this.snsSender = snsSender;
        }

        @Override
        public boolean supports(String source) {
            return SystemPlatformEnum.OPERA.getDesc().equals(source);
        }

        @Override
        public List<GuestInHouseBO> parsReport(InputStream inputStream, PropertyDTO propertyDTO) {
            return clcGuestInhService.parseReport(inputStream, propertyDTO);
        }

        /**
         * 检查文件
         *
         * @param propertyDTO 资产
         * @param file        文件
         * @author yyt
         * @date 2024/8/3
         **/
        @Override
        public void checkFile(PropertyDTO propertyDTO, MultipartFile file) {
            // 限制文件大小
            FileCheckUtils.checkFileSize(file, importReportFileMaxSize);
            // 校验文件格式
            UploadUtils.checkFileFormat(file, Lists.newArrayList("xml"));

            try (InputStream in = file.getInputStream()) {
                FileCheckUtils.checkGuestInHouseFile(in);
            } catch (BadRequestException e) {
                throw e;
            } catch (Exception e) {
                throw new ParseReportException(BaseErrorCodeEnum.SYSTEM_ERROR.getI18nCode(),
                        BaseErrorCodeEnum.SYSTEM_ERROR.getCode(), "parsing file failed.", e);
            }
        }

        /**
         * 处理导入记录
         *
         * @param tenantBO    租户
         * @param propertyDTO 资产
         * @param file        文件
         * @param userId      操作人
         * @return 导入记录
         * @author yyt
         * @date 2024/8/3
         **/
        @Override
        public ClcGuestInhImportLog handleImportLog(SymbolBO tenantBO, PropertyDTO propertyDTO, MultipartFile file, int userId) {
            String key = toS3(tenantBO.getSymbol(), propertyDTO.getAbbr(), file);
            ClcGuestInhImportLog importLog = new ClcGuestInhImportLog().setPropertyId(propertyDTO.getId())
                    .setStatus(ReportImportResultCons.IMPORT_IN_PROGRESS).setUrl(key)
                    .setCreatedBy(userId).setCreatedTime(DateTimeUtils.nowTimestamp());
            clcGuestInhImportLogService.save(importLog);
            return importLog;
        }

        /**
         * 上传文件至 s3
         *
         * @param tenantSymbol   租户标识
         * @param propertySymbol 资产标识
         * @param file           文件
         * @return 文件路径
         * @author yyt
         * @date 2024/8/3
         **/
        private String toS3(String tenantSymbol, String propertySymbol, MultipartFile file) {
            String key = tenantSymbol + "/" + propertySymbol + "/" + guestInHouseS3key +
                    UploadUtils.getRandomFileName(file.getOriginalFilename());
            try {
                // 上传文件
                amazonS3Service.uploadFile(S3BucketFunctionCons.CLC_IMPORT_RECORD, file, key);
            } catch (Exception e) {
                throw new BadRequestException(BaseErrorCodeEnum.SYSTEM_ERROR.getI18nCode(),
                        BaseErrorCodeEnum.SYSTEM_ERROR.getCode(), "Uploading to s3 failure", e);
            }
            return key;
        }

        /**
         * 处理文件
         *
         * @param tenantBO    租户
         * @param propertyDTO 资产信息
         * @param file        文件
         * @param importLog   导入记录
         * @param userId      操作人
         * @author yyt
         * @date 2024/8/3
         **/
        @Override
        public void handleFile(SymbolBO tenantBO, PropertyDTO propertyDTO, MultipartFile file, ClcGuestInhImportLog importLog,
                               Integer userId) {
            clcHandleFileService.sendGuestInHouseEvent(tenantBO, propertyDTO, file, SystemPlatformEnum.OPERA.getDesc(), importLog, userId);
        }

    }