# PastReservationDayLogServiceImpl.java

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

    import cloud.wconnect.commonlib.component.BeanMapper;
    import cloud.wconnect.commonlib.cons.BaseErrorCodeEnum;
    import cloud.wconnect.commonlib.cons.CommonErrorI18nConstant;
    import cloud.wconnect.commonlib.cons.StatusCons;
    import cloud.wconnect.commonlib.exception.BadRequestException;
    import cloud.wconnect.commonlib.pojo.dto.ListPagedDTO;
    import cloud.wconnect.commonlib.pojo.dto.OperationLogBasicDTO;
    import cloud.wconnect.commonlib.service.UserInternalService;
    import cloud.wconnect.commonlib.util.DateTimeUtils;
    import cloud.wconnect.commonlib.util.JsonUtils;
    import cloud.wconnect.frontoffice.cons.pastreservation.ActionCons;
    import cloud.wconnect.frontoffice.cons.pastreservation.DayTypeEnum;
    import cloud.wconnect.frontoffice.entity.pastreservation.PastReservationConsecutiveDay;
    import cloud.wconnect.frontoffice.entity.pastreservation.PastReservationDayLog;
    import cloud.wconnect.frontoffice.entity.pastreservation.PastReservationIntervalDay;
    import cloud.wconnect.frontoffice.mapper.pastreservation.PastReservationDayLogMapper;
    import cloud.wconnect.frontoffice.pojo.dto.pastreservation.PastReservationConsecutiveDayDTO;
    import cloud.wconnect.frontoffice.pojo.dto.pastreservation.PastReservationDayConfigDTO;
    import cloud.wconnect.frontoffice.pojo.dto.pastreservation.PastReservationDayLogDTO;
    import cloud.wconnect.frontoffice.service.pastreservation.IPastReservationConsecutiveDayService;
    import cloud.wconnect.frontoffice.service.pastreservation.IPastReservationDayLogService;
    import cloud.wconnect.frontoffice.service.pastreservation.IPastReservationIntervalDayService;
    import com.baomidou.dynamic.datasource.annotation.DS;
    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 com.fasterxml.jackson.databind.ObjectMapper;
    import com.google.common.collect.Lists;
    import org.apache.commons.collections.CollectionUtils;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import jakarta.annotation.Resource;
    import java.util.List;
    import java.util.Map;
    import java.util.Objects;
    import java.util.stream.Collectors;

    /**
     * <p>
     * 间隔天数+连续天数操作记录 服务实现类
     * </p>
     *
     * @author yyt
     * @since 2024-10-01
     */
    @Service
    @DS("logbook")
    public class PastReservationDayLogServiceImpl extends ServiceImpl<PastReservationDayLogMapper, PastReservationDayLog> implements IPastReservationDayLogService {

        @Resource
        private IPastReservationIntervalDayService pastReservationIntervalDayService;
        @Resource
        private IPastReservationConsecutiveDayService pastReservationConsecutiveDayService;
        @Autowired
        private UserInternalService userInternalService;
        @Autowired
        private ObjectMapper objectMapper;
        @Autowired
        private BeanMapper beanMapper;

        /**
         * 插入进行中操作记录
         *
         * @param propertyId 资产 id
         * @param configDTO  配置信息
         * @param userId     操作人
         * @return log
         * @author yyt
         * @date 2024/10/2
         **/
        @Override
        @Transactional(rollbackFor = Exception.class)
        public List<PastReservationDayLog> saveLogs(Integer propertyId, PastReservationDayConfigDTO configDTO, int userId) {
            long now = DateTimeUtils.nowTimestamp();
            List<PastReservationDayLog> logs = Lists.newArrayListWithExpectedSize(4);

            // 1.修改间隔天数
            Integer updateIntervalDay = configDTO.getIntervalDay();
            PastReservationIntervalDay existIntervalDay = pastReservationIntervalDayService.getByPropertyId(propertyId);
            if (Objects.isNull(existIntervalDay)) {
                logs.add(new PastReservationDayLog().setPropertyId(propertyId).setAction(ActionCons.MODIFY_INTERVAL)
                        .setExpansionJson(JsonUtils.convertObjToString(objectMapper, new OperationLogBasicDTO(null, updateIntervalDay)))
                        .setStatus(StatusCons.IMPORT_IN_PROGRESS).setCreatedBy(userId).setCreatedTime(now));
            } else {
                if (!updateIntervalDay.equals(existIntervalDay.getDay())) {
                    logs.add(new PastReservationDayLog().setPropertyId(propertyId).setAction(ActionCons.MODIFY_INTERVAL)
                            .setExpansionJson(JsonUtils.convertObjToString(objectMapper, new OperationLogBasicDTO(existIntervalDay.getDay(), updateIntervalDay)))
                            .setStatus(StatusCons.IMPORT_IN_PROGRESS).setCreatedBy(userId).setCreatedTime(now));
                }
            }

            // 2.修改notice，3.修改alert，4.修改warning
            Map<Integer, Integer> existConsecutiveDayByType = pastReservationConsecutiveDayService.listByPropertyId(propertyId)
                    .stream().filter(item -> Objects.nonNull(item.getDay()))
                    .collect(Collectors.toMap(PastReservationConsecutiveDay::getType, PastReservationConsecutiveDay::getDay));

            Map<Integer, Integer> updateConsecutiveDayByType = configDTO.getConsecutiveDays().stream()
                    .filter(item -> Objects.nonNull(item.getDay()))
                    .collect(Collectors.toMap(PastReservationConsecutiveDayDTO::getType, PastReservationConsecutiveDayDTO::getDay));

            for (DayTypeEnum dayType : DayTypeEnum.values()) {
                int action = dayType.getCode() + 1;
                Integer originalConsecutiveDay = existConsecutiveDayByType.get(dayType.getCode());
                Integer updateConsecutiveDay = updateConsecutiveDayByType.get(dayType.getCode());
                if (Objects.nonNull(originalConsecutiveDay) || Objects.nonNull(updateConsecutiveDay)) {
                    if (Objects.nonNull(originalConsecutiveDay) && Objects.nonNull(updateConsecutiveDay)) {
                        if (!originalConsecutiveDay.equals(updateConsecutiveDay)) {
                            logs.add(new PastReservationDayLog().setPropertyId(propertyId).setAction(action)
                                    .setExpansionJson(JsonUtils.convertObjToString(objectMapper, new OperationLogBasicDTO(originalConsecutiveDay, updateConsecutiveDay)))
                                    .setStatus(StatusCons.IMPORT_IN_PROGRESS).setCreatedBy(userId).setCreatedTime(now));
                        }
                    } else {
                        logs.add(new PastReservationDayLog().setPropertyId(propertyId).setAction(action)
                                .setExpansionJson(JsonUtils.convertObjToString(objectMapper, new OperationLogBasicDTO(originalConsecutiveDay, updateConsecutiveDay)))
                                .setStatus(StatusCons.IMPORT_IN_PROGRESS).setCreatedBy(userId).setCreatedTime(now));
                    }
                }
            }

            if (CollectionUtils.isNotEmpty(logs)) {
                saveBatch(logs);
            }

            return logs;
        }

        /**
         * 不能有进行中的操作记录
         *
         * @param propertyId 资产 id
         * @author yyt
         * @date 2024/12/3
         **/
        @Override
        public void checkInProgress(Integer propertyId) {
            long count = count(new QueryWrapper<PastReservationDayLog>().lambda()
                    .eq(PastReservationDayLog::getPropertyId, propertyId)
                    .eq(PastReservationDayLog::getStatus, StatusCons.IMPORT_IN_PROGRESS));
            if (count > 0) {
                throw new BadRequestException(CommonErrorI18nConstant.DATA_IS_MODIFYING,
                        BaseErrorCodeEnum.DATA_VALIDATION_ERROR.getCode(), "the system is busy, please try again later.");
            }
        }

        /**
         * 分页查询数据
         *
         * @param propertyId 资产 id
         * @param page       页码
         * @param size       每页显示条数
         * @return 操作记录
         * @author yyt
         * @date 2024/12/3
         **/
        @Override
        public Page<PastReservationDayLog> listPage(Integer propertyId, int page, int size) {
            return page(new Page<>(page, size), new QueryWrapper<PastReservationDayLog>().lambda()
                    .eq(PastReservationDayLog::getPropertyId, propertyId)
                    .orderByDesc(PastReservationDayLog::getId));
        }

        /**
         * 获取操作记录
         *
         * @param tenantId   租户 id
         * @param propertyId 资产 id
         * @param page       页码
         * @param size       每页显示条数
         * @return 操作记录
         * @author yyt
         * @date 2026/1/19
         **/
        @Override
        public ListPagedDTO<PastReservationDayLogDTO> listLogDTO(int tenantId, int propertyId, int page, int size) {
            Page<PastReservationDayLog> pageDetail = listPage(propertyId, page, size);
            List<PastReservationDayLog> records = pageDetail.getRecords();
            if (CollectionUtils.isEmpty(records)) return new ListPagedDTO<>();

            Map<Integer, String> nameById = userInternalService.getNameMapByIds(tenantId,
                    records.stream().map(PastReservationDayLog::getCreatedBy).distinct().collect(Collectors.toList()));

            return new ListPagedDTO<>(pageDetail.getTotal(), beanMapper.mapList(records, PastReservationDayLogDTO.class,
                    item -> item.setCreatedName(nameById.get(item.getCreatedBy()))));
        }

    }