# ClcCardDataServiceImpl.java

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

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.frontoffice.entity.clc.ClcCardData;
    import cloud.wconnect.frontoffice.mapper.clc.ClcCardDataMapper;
    import cloud.wconnect.frontoffice.pojo.bo.clc.CardDataBO;
    import cloud.wconnect.frontoffice.pojo.dto.clc.CardDataDTO;
    import cloud.wconnect.frontoffice.pojo.dto.clc.ClcPropertyDTO;
    import cloud.wconnect.frontoffice.pojo.query.clc.CardDataQuery;
    import cloud.wconnect.frontoffice.service.clc.IClcCardDataService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
    import com.google.common.collect.Lists;
    import org.apache.commons.lang3.StringUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.time.LocalDate;
    import java.time.ZoneId;
    import java.time.format.DateTimeFormatter;
    import java.util.*;
    import java.util.stream.Collectors;

    /**
     * <p>
     *  服务实现类
     * </p>
     *
     * @author yyt
     * @since 2023-07-24
     */
    @Service
    @DS("logbook")
    public class ClcCardDataServiceImpl extends ServiceImpl<ClcCardDataMapper, ClcCardData> implements IClcCardDataService {

        @Autowired
        private PropertyI18nRedisService propertyI18nRedisService;
        @Autowired
        private IClcHandleDataService clcHandleDataService;
        @Autowired
        private BeanMapper beanMapper;

        /**
         * 处理 card data
         *
         * @param property  资产信息
         * @param cardDatas card data
         * @author yyt
         * @date 2023/7/27
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void handleCardData(PropertyDTO property, List<CardDataBO> cardDatas) {
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
            Integer propertyId = property.getId();
            ZoneId zoneId = ZoneId.of(property.getTimezone());

            baseMapper.saveOrUpdateBatch(cardDatas.stream().map(item -> {
                ClcCardData cardData = new ClcCardData();
                cardData.setPropertyId(propertyId);
                cardData.setCustomer(item.getCustomer());
                cardData.setCardNumber(item.getCardNumber());
                cardData.setRoomNumber(item.getRoomNumber());
                cardData.setCheckInDate(LocalDate.parse(item.getCheckInDate(), dateTimeFormatter).atStartOfDay(zoneId).toEpochSecond());
                return cardData;
            }).sorted(Comparator.comparing(ClcCardData::getCardNumber).thenComparing(ClcCardData::getCustomer)).collect(Collectors.toList()));
        }

        /**
         * 查询数据
         *
         * @param propertyIds 资产 id
         * @param query       查询条件
         * @return card data
         * @author yyt
         * @date 2024/11/19
         **/
        @Override
        public Map<Integer, List<ClcCardData>> list(Collection<Integer> propertyIds, CardDataQuery query) {
            return list(new QueryWrapper<ClcCardData>().lambda()
                    .in(ClcCardData::getPropertyId, propertyIds)
                    .like(StringUtils.isNotEmpty(query.getGuestName()), ClcCardData::getCustomer, query.getGuestName())
                    .like(StringUtils.isNotEmpty(query.getRoomNumber()), ClcCardData::getRoomNumber, query.getRoomNumber())
                    .between(Objects.nonNull(query.getStartCheckInDate()) && Objects.nonNull(query.getEndCheckInDate()),
                            ClcCardData::getCheckInDate, query.getStartCheckInDate(), query.getEndCheckInDate()))
                    .stream().collect(Collectors.groupingBy(ClcCardData::getPropertyId));
        }

        /**
         * 获取 clc card 列表数据
         *
         * @param loginSelectPropertyId 当前登陆选择资产
         * @param propertyIds           登陆用户所属资产
         * @param query                 查询条件
         * @return clc card 列表数据
         * @author yyt
         * @date 2026/1/19
         */
        @Override
        public List<ClcPropertyDTO> listCardDataDTO(int loginSelectPropertyId, List<Integer> propertyIds, CardDataQuery query) {
            Map<Integer, String> propertyNameById = propertyI18nRedisService.list(propertyIds)
                    .stream().collect(Collectors.toMap(PropertyDTO::getId, PropertyDTO::getName));

            Map<Integer, List<ClcCardData>> cardDataByPropertyId = list(propertyNameById.keySet(), query);

            List<ClcPropertyDTO> results = Lists.newArrayListWithExpectedSize(cardDataByPropertyId.size());
            cardDataByPropertyId.forEach((propertyId, cardDatas) -> {
                ClcPropertyDTO clcPropertyDTO = new ClcPropertyDTO();
                clcPropertyDTO.setPropertyId(propertyId);
                clcPropertyDTO.setPropertyName(propertyNameById.get(propertyId));
                List<CardDataDTO> cardDataDTOList = beanMapper.mapList(cardDatas, CardDataDTO.class);
                // 名称排序
                cardDataDTOList.sort(Comparator.comparing(CardDataDTO::getCustomer));
                clcPropertyDTO.setList(cardDataDTOList);
                results.add(clcPropertyDTO);
            });

            // 处理数据排序
            clcHandleDataService.handleSort(loginSelectPropertyId, results);

            return results;
        }

    }