# AcOtaServiceImpl.java

    package cloud.wconnect.finance.service.api.impl;

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.exception.ListenerException;
    import cloud.wconnect.commonlib.pojo.dto.ListPagedDTO;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.finance.entity.api.AcOta;
    import cloud.wconnect.finance.mapper.api.AcOtaMapper;
    import cloud.wconnect.finance.pojo.bo.api.ota.AcOtaListBO;
    import cloud.wconnect.finance.pojo.dto.api.AcOtaDTO;
    import cloud.wconnect.finance.pojo.query.api.AcOtaQuery;
    import cloud.wconnect.finance.service.api.IAcOtaService;
    import cloud.wconnect.finance.service.api.acota.IApiOtaParseService;
    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 org.apache.commons.collections.CollectionUtils;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.context.ApplicationContext;
    import org.springframework.stereotype.Service;

    import jakarta.annotation.Resource;
    import java.io.InputStream;
    import java.util.Collection;
    import java.util.Collections;
    import java.util.List;
    import java.util.Objects;

    /**
     * <p>
     * ota 报告数据 服务实现类
     * </p>
     *
     * @author zc
     * @since 2023-08-04
     */
    @Service
    @DS("finance")
    public class AcOtaServiceImpl extends ServiceImpl<AcOtaMapper, AcOta> implements IAcOtaService {
        @Resource
        private BeanMapper beanMapper;
        @Resource
        private ApplicationContext applicationContext;

        /**
         * 根据 Api id 获取 OTA 数据
         *
         * @param id Api id
         * @return AcOta
         * @author zc
         * @date 2023/8/4
         */
        @Override
        public AcOta getByApiId(long id) {
            return getOne(new QueryWrapper<AcOta>().lambda()
                    .eq(AcOta::getApiId, id));
        }

        /**
         * 获取未匹配 Api 的 OTA 数据
         *
         * @param propertyId 资产 id
         * @param acOtaQuery 查询条件
         * @return AcOtaDTO 集合
         * @author zc
         * @date 2023/8/5
         */
        @Override
        public ListPagedDTO<AcOtaDTO> listUnbind(int propertyId, AcOtaQuery acOtaQuery) {
            LambdaQueryWrapper<AcOta> queryWrapper = new QueryWrapper<AcOta>().lambda()
                    .eq(AcOta::getPropertyId, propertyId)
                    .eq(AcOta::getBatchNo, acOtaQuery.getBatchNo())
                    .eq(AcOta::getApiId, BaseConstant.LONG_ZERO)
                    .ge(Objects.nonNull(acOtaQuery.getFromDate()),
                            AcOta::getArrivalDate, acOtaQuery.getFromDate())
                    .le(Objects.nonNull(acOtaQuery.getToDate()),
                            AcOta::getArrivalDate, acOtaQuery.getToDate())
                    .like(StringUtils.isNotBlank(acOtaQuery.getCrsNo()),
                            AcOta::getCrsNo, acOtaQuery.getCrsNo())
                    .and(StringUtils.isNotBlank(acOtaQuery.getName()),
                            query -> query
                                    .apply("LOWER(first_name) LIKE CONCAT('%', LOWER({0}), '%')",
                                            acOtaQuery.getName())
                                    .or()
                                    .apply("LOWER(last_name) LIKE CONCAT('%', LOWER({0}), '%')",
                                            acOtaQuery.getName()));
            Page<AcOta> page = page(new Page<>(acOtaQuery.getPage(), acOtaQuery.getSize()), queryWrapper);
            if (CollectionUtils.isEmpty(page.getRecords())) {
                return new ListPagedDTO<>();
            }

            return new ListPagedDTO<>(page.getTotal(), beanMapper.mapList(page.getRecords(), AcOtaDTO.class));
        }

        /**
         * 校验数据是否存在
         *
         * @param id ota id
         * @return AcOta
         * @author zc
         * @date 2023/8/5
         */
        @Override
        public AcOta checkExist(long id) {
            AcOta acOta = getById(id);
            if (Objects.isNull(acOta)) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_NOT_FOUND,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(),
                        "The acOta is not found by id; id: " + id);
            }
            return acOta;
        }

        /**
         * 根据 Api ids 获取 OTA 数据集合
         *
         * @param apiIds Api ids
         * @return AcOta 集合
         * @author zc
         * @date 2023/8/8
         */
        @Override
        public List<AcOta> listByApiIds(List<Long> apiIds) {
            if (CollectionUtils.isEmpty(apiIds)) {
                return Collections.emptyList();
            }
            return list(new QueryWrapper<AcOta>().lambda()
                    .in(AcOta::getApiId, apiIds));
        }

        /**
         * 解析报告
         *
         * @param propertyDTO 资产
         * @param source      数据源平台
         * @param in          文件
         * @return AcOtaListBO 集合
         * @author zc
         * @date 2023/8/9
         */
        @Override
        public List<AcOtaListBO> parseReport(PropertyDTO propertyDTO, String source, InputStream in) {
            Collection<IApiOtaParseService> parserList = applicationContext.getBeansOfType(IApiOtaParseService.class).values();
            for (IApiOtaParseService parser : parserList) {
                if (parser.supports(source)) {
                    return parser.parse(propertyDTO, in);
                }
            }
            throw new ListenerException("Not found report parser");
        }
    }