# PastReservationGuestInHouseParseByShijiManualImport.java

    package cloud.wconnect.frontoffice.service.pastreservation.report.manualimport.guestinhouse;

    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.EventBodyParamEnum;
    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.EventBodyDTO;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.util.FileCheckUtils;
    import cloud.wconnect.commonlib.util.JsonUtils;
    import cloud.wconnect.commonlib.util.ShijiFileCheckUtils;
    import cloud.wconnect.commonlib.util.UploadUtils;
    import cloud.wconnect.frontoffice.cons.BusinessEnum;
    import cloud.wconnect.frontoffice.cons.EventSubjectEnum;
    import cloud.wconnect.frontoffice.cons.S3BucketFunctionCons;
    import cloud.wconnect.frontoffice.cons.pastreservation.PastReservationReportTypeCons;
    import cloud.wconnect.frontoffice.entity.pastreservation.PastReservationImportLog;
    import cloud.wconnect.frontoffice.service.AmazonS3Service;
    import cloud.wconnect.frontoffice.service.pastreservation.IPastReservationImportLogService;
    import cloud.wconnect.frontoffice.service.pastreservation.report.manualimport.IPastReservationReportParse;
    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 com.google.common.collect.Maps;
    import jakarta.annotation.Resource;
    import org.springframework.beans.factory.annotation.Autowired;
    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.Map;

    /**
     *  处理手动导入的Shiji [In-House Guest Report]
     */
    @Service
    @DS("logbook")
    public class PastReservationGuestInHouseParseByShijiManualImport implements IPastReservationReportParse {

        @Resource
        private IPastReservationImportLogService pastReservationImportLogService;
        @Autowired
        private AmazonS3Service amazonS3Service;
        @Autowired
        private ObjectMapper objectMapper;
        @Value("${aws-s3.third-party.key.past-reservation.guest-in-house}")
        private String guestInHouseS3key;
        @Value("${file-max-size.import-report.past-reservation}")
        private Long importReportFileMaxSize;
        @Autowired
        @Qualifier("3pSender")
        private Sender snsSender;

        /**
         * 判断支持的平台
         *
         * @param source     平台数据源
         * @param reportType 报告类型
         * @return boolean
         * @author lichen
         * @date 2025/7/31
         */
        @Override
        public boolean supports(String source, int reportType) {
            return SystemPlatformEnum.SHI_JI.getDesc().equals(source) && PastReservationReportTypeCons.GUEST_IN_HOUSE == reportType;
        }

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

            try (InputStream in = file.getInputStream()) {
                ShijiFileCheckUtils.checkInHouseGuestReportFile(in);
            } catch (BadRequestException e) {
                throw e;
            } catch (Exception e) {
                throw new ParseReportException(BaseErrorCodeEnum.SYSTEM_ERROR.getI18nCode(),
                        BaseErrorCodeEnum.SYSTEM_ERROR.getCode(), "parsing shiji [In-House Guest Report] file failed.", e);
            }
        }

        /**
         * 处理导入记录
         *
         * @param tenantBO    租户
         * @param propertyDTO 资产
         * @param file        文件
         * @param userId      操作人
         * @return cloud.wconnect.frontoffice.entity.pastreservation.PastReservationImportLog
         * @author lichen
         * @date 2025/7/31
         */
        @Override
        public PastReservationImportLog handleImportLog(SymbolBO tenantBO, PropertyDTO propertyDTO, MultipartFile file, int userId) {
            String key = toS3(tenantBO.getSymbol(), propertyDTO.getAbbr(), file);

            return pastReservationImportLogService.add(propertyDTO.getId(), PastReservationReportTypeCons.GUEST_IN_HOUSE,
                    ReportImportResultCons.IMPORT_IN_PROGRESS, key, userId);
        }

        /**
         * 上传文件至 s3
         *
         * @param tenantSymbol   租户标识
         * @param propertySymbol 资产标识
         * @param file           文件
         * @return java.lang.String
         * @author lichen
         * @date 2025/7/31
         */
        private String toS3(String tenantSymbol, String propertySymbol, MultipartFile file) {
            String key = tenantSymbol + "/" + propertySymbol + "/" + guestInHouseS3key +
                    UploadUtils.getRandomFileName(file.getOriginalFilename());
            try {
                // 上传文件
                amazonS3Service.uploadFile(S3BucketFunctionCons.PAST_RESERVATION_IMPORT_RECORD, file, key);
            } catch (Exception e) {
                throw new BadRequestException(BaseErrorCodeEnum.SYSTEM_ERROR.getI18nCode(),
                        BaseErrorCodeEnum.SYSTEM_ERROR.getCode(), "Uploading shiji [In-House Guest Report] file to s3 failure", e);
            }
            return key;
        }

        /**
         * 处理文件
         *
         * @param tenantBO    租户
         * @param propertyDTO 资产信息
         * @param file        文件
         * @param importLog   导入记录
         * @param userId      操作人
         * @return void
         * @author lichen
         * @date 2025/7/31
         */
        @Override
        public void handleFile(SymbolBO tenantBO, PropertyDTO propertyDTO, MultipartFile file, PastReservationImportLog importLog,
                               Integer userId) {
            try {
                // 设置事件体
                Map<String, Object> params = Maps.newHashMapWithExpectedSize(6);
                params.put(EventBodyParamEnum.TENANT_SYMBOL.getDesc(), tenantBO.getSymbol());
                params.put(EventBodyParamEnum.PROPERTY_ABBR.getDesc(), Lists.newArrayList(propertyDTO.getAbbr()));
                params.put(EventBodyParamEnum.SOURCE.getDesc(), SystemPlatformEnum.SHI_JI.getDesc());
                params.put(EventBodyParamEnum.UID.getDesc(), userId);
                params.put(EventBodyParamEnum.ID.getDesc(), importLog.getId());
                params.put(EventBodyParamEnum.ORIGINATE_FROM.getDesc(), BusinessEnum.PAST_RESERVATION.getBusiness());

                // 上传文件
                String key = tenantBO.getSymbol() + "/" + propertyDTO.getAbbr() + "/" + guestInHouseS3key +
                        UploadUtils.getRandomFileName(file.getOriginalFilename());
                amazonS3Service.uploadFile(file, key);

                snsSender.publish(EventSubjectEnum.GUEST_IN_HOUSE_INDIVIDUAL_SERVICE.getSubject(),
                        JsonUtils.convertObjToString(objectMapper, new EventBodyDTO(key, params)));
            } catch (Exception e) {
                throw new BadRequestException(BaseErrorCodeEnum.SYSTEM_ERROR.getI18nCode(),
                        BaseErrorCodeEnum.SYSTEM_ERROR.getCode(), "Import shiji [In-House Guest Report] report exception", e);
            }
        }

    }