# OooRoomController.java

    package cloud.wconnect.frontoffice.controller.oooroom;

    import cloud.wconnect.commonlib.annotation.ApiId;
    import cloud.wconnect.commonlib.component.SessionContext;
    import cloud.wconnect.commonlib.cons.*;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.exception.ForbiddenException;
    import cloud.wconnect.commonlib.pojo.bo.SymbolBO;
    import cloud.wconnect.commonlib.pojo.dto.ListPagedDTO;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.pojo.dto.group.Addition;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.commonlib.util.I18nMessageUtils;
    import cloud.wconnect.frontoffice.entity.oooroom.OooImportLog;
    import cloud.wconnect.frontoffice.entity.oooroom.OooRoom;
    import cloud.wconnect.frontoffice.pojo.dto.oooroom.ImportOutOfOrderDTO;
    import cloud.wconnect.frontoffice.pojo.dto.oooroom.OooImportLogDTO;
    import cloud.wconnect.frontoffice.pojo.dto.oooroom.OooRoomDTO;
    import cloud.wconnect.frontoffice.pojo.dto.oooroom.UpdateOooRoomDTO;
    import cloud.wconnect.frontoffice.pojo.query.oooroom.OooImportLogQuery;
    import cloud.wconnect.frontoffice.pojo.query.oooroom.OooRoomQuery;
    import cloud.wconnect.frontoffice.service.oooroom.IOooImportLogService;
    import cloud.wconnect.frontoffice.service.oooroom.IOooRoomService;
    import cloud.wconnect.frontoffice.service.oooroom.outoforder.IOutOfOrderFileParse;
    import com.google.common.collect.Lists;
    import jakarta.validation.Valid;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    import org.springframework.validation.annotation.Validated;
    import org.springframework.web.bind.annotation.*;
    import org.springframework.web.multipart.MultipartFile;

    import java.util.Collections;
    import java.util.Map;
    import java.util.Objects;

    /**
     * <p>
     * 前端控制器
     * </p>
     *
     * @author yyt
     * @since 2023-08-05
     */
    @RestController
    @RequestMapping("/ooo-room")
    public class OooRoomController {

        @Autowired
        private IOooRoomService oooRoomService;
        @Autowired
        private IOooImportLogService oooImportLogService;
        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private SessionContext sessionContext;
        @Autowired
        private ApplicationContext applicationContext;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;

        /**
         * 获取列表数据
         *
         * @param property 资产标识
         * @param query    查询条件
         * @return ooo room 数据
         * @author yyt
         * @date 2023/8/5
         */
        @ApiId(527)
        @GetMapping
        public ListPagedDTO<OooRoomDTO> listOooRoomDTO(String property, @Valid OooRoomQuery query) {
            Integer propertyId = sessionContext.getPropertyId(property);
            return oooRoomService.listOooRoomDTO(propertyId, query);
        }

        /**
         * 新增、编辑
         *
         * @param id               数据 id
         * @param property         资产标识
         * @param updateOooRoomDTO ooo 数据
         * @return {}
         * @author yyt
         * @date 2023/8/5
         */
        @ApiId(528)
        @PostMapping("/{id:\\d+}")
        public Map save(@PathVariable long id, String property, @Valid @RequestBody UpdateOooRoomDTO updateOooRoomDTO) {
            if (updateOooRoomDTO.getFromDate() > updateOooRoomDTO.getToDate()) {
                throw new BadRequestException(CommonErrorI18nConstant.START_DATE_CANNOT_GREATER_THAN_END_DATE,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the from date cannot be greater than to date");
            }

            PropertyDTO propertyDTO = propertyI18nRedisService.get(sessionContext.getPropertyId(property));
            if (id == BaseConstant.ZERO) {
                oooRoomService.handleSave(propertyDTO, updateOooRoomDTO, sessionContext.getLoginUserId());

            } else {
                OooRoom oooRoom = oooRoomService.checkExist(id);

                checkBelong(oooRoom, propertyDTO.getId());

                oooRoomService.handleUpdate(oooRoom, updateOooRoomDTO, sessionContext.getLoginUserId());
            }

            return Collections.emptyMap();
        }

        /**
         * 状态变更
         *
         * @param id       数据 id
         * @param property 资产标识
         * @return {}
         * @author yyt
         * @date 2023/8/7
         */
        @ApiId(529)
        @PutMapping("/{id:\\d+}/status")
        public Map close(@PathVariable long id, String property) {
            OooRoom oooRoom = oooRoomService.checkExist(id);
            checkBelong(oooRoom, sessionContext.getPropertyId(property));

            oooRoomService.close(oooRoom, sessionContext.getLoginUserId());

            return Collections.emptyMap();
        }

        /**
         * 删除
         *
         * @param id       数据 id
         * @param property 资产标识
         * @return {}
         * @author yyt
         * @date 2023/8/14
         */
        @ApiId(543)
        @DeleteMapping("/{id:\\d+}")
        public Map delete(@PathVariable long id, String property) {
            OooRoom oooRoom = oooRoomService.checkExist(id);
            checkBelong(oooRoom, sessionContext.getPropertyId(property));

            oooRoomService.delete(id);

            return Collections.emptyMap();
        }

        /**
         * 获取报告导入记录
         *
         * @param property 资产标识
         * @param query    查询条件
         * @return 报告导入记录
         * @author yyt
         * @date 2023/8/7
         */
        @ApiId(530)
        @GetMapping("/import-log")
        public ListPagedDTO<OooImportLogDTO> listImportLog(String property, @Valid OooImportLogQuery query) {
            return oooImportLogService.listImportLogDTO(sessionContext.getTenantSymbolBO().getId(), sessionContext.getPropertyId(property), query);
        }

        /**
         * 解决异常
         *
         * @param id                  异常 id
         * @param property            资产标识
         * @param importOutOfOrderDTO 解决异常DTO
         * @return {}
         * @author yyt
         * @date 2023/8/7
         */
        @ApiId(531)
        @PutMapping("/exception/{id:\\d+}")
        public Map resolveException(@PathVariable int id, String property,
                                    ImportOutOfOrderDTO importOutOfOrderDTO) {
            int propertyId = sessionContext.getPropertyId(property);

            OooImportLog importLog = oooImportLogService.checExist(id);
            if (!Lists.newArrayList(ReportImportResultCons.IMPORT_RESULT_FAIL, ReportImportResultCons.IMPORT_RESULT_MISSED)
                    .contains(importLog.getStatus())) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_INTEGRATION_ONLY_HANDLE_EXCEPTION,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the importLog status is error");
            }
            checkBelong(importLog, propertyId);

            MultipartFile file = importOutOfOrderDTO.getFile();
            if (Objects.isNull(file)) {
                oooImportLogService.updateStatus(id, ReportImportResultCons.IMPORT_RESULT_IGNORE, sessionContext.getLoginUserId());
            } else {
                if (StringUtils.isBlank(importOutOfOrderDTO.getSource())) {
                    throw new BadRequestException(CommonErrorI18nConstant.CANNOT_EMPTY,
                            i18nMessageUtils.getErrorParamMapNeedTranslate("source"),
                            BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "source cannot be blank");
                }
                SymbolBO tenant = sessionContext.getTenantSymbolBO();
                PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
                //校验source是否符合预期
                checkSource(propertyDTO, importOutOfOrderDTO.getSource());

                int userId = sessionContext.getLoginUserId();
                importOutOfOrderDTO.setTheDate(importLog.getTheDate());

                Map<String, IOutOfOrderFileParse> beans = applicationContext.getBeansOfType(IOutOfOrderFileParse.class);
                for (IOutOfOrderFileParse bean : beans.values()) {
                    if (bean.supports(importOutOfOrderDTO.getSource())) {
                        bean.checkFile(propertyDTO, file);

                        bean.handleImportLog(tenant, propertyDTO, importLog, importOutOfOrderDTO.getTheDate(), file, userId);

                        bean.handleFile(tenant, propertyDTO, file, importLog, userId);
                        return Collections.emptyMap();
                    }
                }
            }
            return Collections.emptyMap();
        }

        /**
         * 手动导入报告
         *
         * @param property            资产标识
         * @param importOutOfOrderDTO 选择条件
         * @return {}
         * @author yyt
         * @date 2023/8/7
         */
        @ApiId(532)
        @PostMapping("/out-of-order/file")
        public Map importOutOfOrderFile(String property, @Validated(Addition.class) ImportOutOfOrderDTO importOutOfOrderDTO) {
            SymbolBO tenant = sessionContext.getTenantSymbolBO();
            int propertyId = sessionContext.getPropertyId(property);
            int userId = sessionContext.getLoginUserId();

            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);
            checkSource(propertyDTO, importOutOfOrderDTO.getSource());

            Map<String, IOutOfOrderFileParse> beans = applicationContext.getBeansOfType(IOutOfOrderFileParse.class);
            for (IOutOfOrderFileParse bean : beans.values()) {
                if (bean.supports(importOutOfOrderDTO.getSource())) {
                    bean.checkFile(propertyDTO, importOutOfOrderDTO.getFile());

                    OooImportLog importLog = bean.handleImportLog(tenant, propertyDTO, null,
                            importOutOfOrderDTO.getTheDate(), importOutOfOrderDTO.getFile(), userId);

                    bean.handleFile(tenant, propertyDTO, importOutOfOrderDTO.getFile(), importLog, userId);

                    return Collections.emptyMap();
                }
            }

            return Collections.emptyMap();
        }

        /**
         * 校验数据归属
         *
         * @param oooRoom    ooo 数据
         * @param propertyId 资产 id
         * @author yyt
         * @date 2023/8/5
         */
        private void checkBelong(OooRoom oooRoom, Integer propertyId) {
            if (!oooRoom.getPropertyId().equals(propertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property id parameter is different from " +
                        "the property id of the oooRoom;propertyId:" + propertyId + ",oooRoomPropertyId:" +
                        oooRoom.getPropertyId() + ",oooRoomId:" + oooRoom.getId());
            }
        }

        /**
         * 校验数据归属
         *
         * @param importLog  import Log
         * @param propertyId 资产 id
         * @author yyt
         * @date 2023/8/5
         */
        private void checkBelong(OooImportLog importLog, Integer propertyId) {
            if (!importLog.getPropertyId().equals(propertyId)) {
                throw new ForbiddenException(BaseErrorCodeEnum.DATA_FORBIDDEN.getI18nCode(),
                        BaseErrorCodeEnum.DATA_FORBIDDEN.getCode(), "the property id parameter is different from " +
                        "the property id of the oooImportLog;propertyId:" + propertyId + ",oooImportLogPropertyId:" +
                        importLog.getPropertyId() + ",oooImportLogId:" + importLog.getId());
            }
        }

        /**
         * 校验source是否符合预期
         *
         * @param propertyDTO 资产DTO
         * @param source      来源
         * @return void
         * @author lichen
         * @date 2025/7/28
         */
        private void checkSource(PropertyDTO propertyDTO, String source) {
            String pmsType = propertyDTO.getPmsType();
            //校验source是否符合预期
            if (!Lists.newArrayList(pmsType, SystemPlatformEnum.OTHER.getDesc()).contains(source)) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_INTEGRATION_SOURCE_SYSTEM_NOT_SUPPORTED,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "The source must be in:" + pmsType + "|" + SystemPlatformEnum.OTHER.getDesc());
            }
        }

    }