# ClcSiteCrewFaxServiceImpl.java

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

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.BaseConstant;
    import cloud.wconnect.commonlib.pojo.dto.PropertyDTO;
    import cloud.wconnect.commonlib.redis.PropertyI18nRedisService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.frontoffice.entity.clc.ClcSiteCrewFax;
    import cloud.wconnect.frontoffice.mapper.clc.ClcSiteCrewFaxMapper;
    import cloud.wconnect.frontoffice.pojo.bo.clc.CrewFaxBO;
    import cloud.wconnect.frontoffice.pojo.dto.clc.ClcPropertyDTO;
    import cloud.wconnect.frontoffice.pojo.dto.clc.CrewFaxDTO;
    import cloud.wconnect.frontoffice.pojo.query.clc.CrewFaxQuery;
    import cloud.wconnect.frontoffice.service.clc.IClcSiteCrewFaxService;
    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 ClcSiteCrewFaxServiceImpl extends ServiceImpl<ClcSiteCrewFaxMapper, ClcSiteCrewFax> implements IClcSiteCrewFaxService {

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

        /**
         * 处理 crew fax
         *
         * @param propertyDTO 资产
         * @param crewFaxes   crew fax
         * @author yyt
         * @date 2023/7/31
         */
        @Override
        @Transactional(rollbackFor = Exception.class)
        public void handleCrewFax(PropertyDTO propertyDTO, List<CrewFaxBO> crewFaxes) {
            Integer propertyId = propertyDTO.getId();
            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(BaseConstant.DATE_FORMAT_YYYY_MM_DD);
            ZoneId zoneId = ZoneId.of(propertyDTO.getTimezone());
            long now = DateTimeUtils.nowTimestamp();
            saveBatch(crewFaxes.stream().map(item -> {
                ClcSiteCrewFax crewFax = new ClcSiteCrewFax();
                crewFax.setPropertyId(propertyId);
                crewFax.setFaxNumber(item.getFaxNumber());
                crewFax.setCompanyName(item.getCompanyName());
                crewFax.setCheckInDate(LocalDate.parse(item.getCheckInDate(), dateTimeFormatter).atStartOfDay(zoneId).toEpochSecond());
                crewFax.setCheckOutDate(LocalDate.parse(item.getCheckOutDate(), dateTimeFormatter).atStartOfDay(zoneId).toEpochSecond());
                crewFax.setRooms(item.getRooms());
                crewFax.setAttachments(item.getAttachments());
                crewFax.setCreatedTime(now);
                return crewFax;
            }).collect(Collectors.toList()));
        }

        /**
         * 查询 crew fax
         *
         * @param propertyIds 资产 id
         * @param query       查询条件
         * @return crew fax
         * @author yyt
         * @date 2024/11/19
         **/
        @Override
        public Map<Integer, List<ClcSiteCrewFax>> list(Collection<Integer> propertyIds, CrewFaxQuery query) {
            return list(new QueryWrapper<ClcSiteCrewFax>().lambda()
                    .in(ClcSiteCrewFax::getPropertyId, propertyIds)
                    .like(StringUtils.isNotEmpty(query.getFaxNumber()), ClcSiteCrewFax::getFaxNumber, query.getFaxNumber())
                    .between(Objects.nonNull(query.getExpectedStartFromDate()) && Objects.nonNull(query.getExpectedStartToDate()),
                            ClcSiteCrewFax::getCheckInDate, query.getExpectedStartFromDate(), query.getExpectedStartToDate())
                    .between(Objects.nonNull(query.getExpectedEndFromDate()) && Objects.nonNull(query.getExpectedEndToDate()),
                            ClcSiteCrewFax::getCheckOutDate, query.getExpectedEndFromDate(), query.getExpectedEndToDate())
                    .like(StringUtils.isNotEmpty(query.getCompanyName()), ClcSiteCrewFax::getCompanyName, query.getCompanyName()))
                    .stream().collect(Collectors.groupingBy(ClcSiteCrewFax::getPropertyId));
        }

        /**
         * 查询已存在的 Fax Number
         *
         * @param propertyId 资产 id
         * @param faxNumbers Fax Number
         * @return 已存在的 Fax Number
         * @author yyt
         * @date 2026/1/19
         **/
        @Override
        public List<String> listExistedFaxNumbers(Integer propertyId, List<String> faxNumbers) {
            return list(new QueryWrapper<ClcSiteCrewFax>().lambda()
                    .eq(ClcSiteCrewFax::getPropertyId, propertyId)
                    .in(ClcSiteCrewFax::getFaxNumber, faxNumbers))
                    .stream().map(ClcSiteCrewFax::getFaxNumber).collect(Collectors.toList());
        }

        /**
         * 查询 crew fax
         *
         * @param loginSelectPropertyId 当前登陆选择资产
         * @param propertyIds           登录用户所属资产
         * @param query                 查询条件
         * @return crew fax
         * @author yyt
         * @date 2026/2/12
         **/
        @Override
        public List<ClcPropertyDTO> listCrewFax(int loginSelectPropertyId, List<Integer> propertyIds, CrewFaxQuery query) {
            Map<Integer, String> propertyNameById = propertyI18nRedisService.list(propertyIds).stream()
                    .collect(Collectors.toMap(PropertyDTO::getId, PropertyDTO::getName));

            Map<Integer, List<ClcSiteCrewFax>> crewFaxesByPropertyId = list(propertyNameById.keySet(), query);

            List<ClcPropertyDTO> results = Lists.newArrayListWithExpectedSize(crewFaxesByPropertyId.size());
            crewFaxesByPropertyId.forEach((propertyId, crewFaxes) -> {
                ClcPropertyDTO clcPropertyDTO = new ClcPropertyDTO();
                clcPropertyDTO.setPropertyId(propertyId);
                clcPropertyDTO.setPropertyName(propertyNameById.get(propertyId));
                clcPropertyDTO.setList(beanMapper.mapList(crewFaxes, CrewFaxDTO.class));
                results.add(clcPropertyDTO);
            });

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

            return results;
        }

    }