# CbJournalController.java

    package cloud.wconnect.finance.controller.chargeback;

    import cloud.wconnect.commonlib.annotation.ApiId;
    import cloud.wconnect.commonlib.component.SessionContext;
    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.exception.ForbiddenException;
    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.finance.entity.chargeback.CbJournalImportLog;
    import cloud.wconnect.finance.pojo.dto.chargeback.journal.ImportJournalDTO;
    import cloud.wconnect.finance.pojo.dto.chargeback.journal.JournalImportLogDTO;
    import cloud.wconnect.finance.pojo.query.chargeback.JournalImportLogQuery;
    import cloud.wconnect.finance.service.chargeback.ICbJournalImportLogService;
    import cloud.wconnect.finance.service.parsereport.chargeback.IJournalFileParse;
    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-22
     */
    @RestController
    @RequestMapping("/charge-back/journal")
    public class CbJournalController {

        @Autowired
        private SessionContext sessionContext;
        @Autowired
        private ICbJournalImportLogService cbJournalImportLogService;
        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private ApplicationContext applicationContext;
        @Autowired
        private I18nMessageUtils i18nMessageUtils;

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

        /**
         * 解决异常
         *
         * @param id        异常 id
         * @param property  资产标识
         * @param importDTO 选择条件
         * @return {}
         * @author yyt
         * @date 2023/9/8
         */
        @ApiId(581)
        @PutMapping("/{id:\\d+}/resolve")
        public Map resolveException(@PathVariable long id, String property, ImportJournalDTO importDTO) {
            int propertyId = sessionContext.getPropertyId(property);
            PropertyDTO propertyDTO = propertyI18nRedisService.get(propertyId);

            CbJournalImportLog importLog = cbJournalImportLogService.checkExist(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);

            int userId = sessionContext.getLoginUserId();

            MultipartFile file = importDTO.getFile();
            if (Objects.isNull(file)) {
                cbJournalImportLogService.updateLogStatus(id, ReportImportResultCons.IMPORT_RESULT_IGNORE, userId);
            } else {
                if (StringUtils.isBlank(importDTO.getSource())) {
                    throw new BadRequestException(CommonErrorI18nConstant.CANNOT_EMPTY,
                            i18nMessageUtils.getErrorParamMapNeedTranslate("source"),
                            BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "source cannot be blank");
                }
                //校验source是否符合预期
                checkSource(propertyDTO, importDTO.getSource());

                importDTO.setTheDate(importLog.getTheDate());

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

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

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

            return Collections.emptyMap();
        }

        /**
         * 手动导入报告
         *
         * @param property  资产标识
         * @param importDTO 选择条件
         * @return {}
         * @author yyt
         * @date 2023/9/8
         */
        @ApiId(582)
        @PostMapping("/file")
        public Map importJournalFile(String property, @Validated(Addition.class) ImportJournalDTO importDTO) {
            PropertyDTO propertyDTO = propertyI18nRedisService.get(sessionContext.getPropertyId(property));
            int userId = sessionContext.getLoginUserId();

            //校验source是否符合预期
            checkSource(propertyDTO, importDTO.getSource());

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

                    CbJournalImportLog importLog = bean.handleImportLog( propertyDTO, null, importDTO.getTheDate(), importDTO.getFile(), userId);

                    bean.handleFile(propertyDTO, importDTO.getFile(), importLog, userId);
                    return Collections.emptyMap();
                }
            }

            return Collections.emptyMap();
        }

        /**
         * 校验数据归属
         *
         * @param importLog  import Log
         * @param propertyId 资产 id
         * @author yyt
         * @date 2023/9/8
         */
        private void checkBelong(CbJournalImportLog 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 cbJournalImportLog;propertyId:" + propertyId + ",cbJournalImportLogPropertyId:" +
                        importLog.getPropertyId() + ",cbJournalImportLogId:" + 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());
            }
        }

    }