package github.benjamin.equipreservebackend.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import github.benjamin.equipreservebackend.constant.ReservationStatus; import github.benjamin.equipreservebackend.entity.Device; import github.benjamin.equipreservebackend.entity.Reservation; import github.benjamin.equipreservebackend.entity.Team; import github.benjamin.equipreservebackend.entity.User; import github.benjamin.equipreservebackend.mapper.DeviceMapper; import github.benjamin.equipreservebackend.mapper.ReservationMapper; import github.benjamin.equipreservebackend.mapper.TeamMapper; import github.benjamin.equipreservebackend.mapper.UserMapper; import github.benjamin.equipreservebackend.service.ReservationService; import github.benjamin.equipreservebackend.utils.PageUtil; import github.benjamin.equipreservebackend.vo.TimeRangeVO; import github.benjamin.equipreservebackend.vo.UserReservationVO; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import java.time.LocalDate; import java.time.LocalDateTime; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.function.Function; import java.util.stream.Collectors; @Service @RequiredArgsConstructor public class ReservationServiceImpl implements ReservationService { private final ReservationMapper reservationMapper; private final DeviceMapper deviceMapper; private final UserMapper userMapper; private final TeamMapper teamMapper; /** * 未来days天内有预约的设备显示为“有预约” */ @Value("${equip-reserve.device-days}") private Integer days; @Override public List getApprovedReservationsByDeviceIds(List devicesIds) { LocalDate now = LocalDate.now(); LocalDate endTime = now.plusDays(days); return reservationMapper.selectList(new LambdaQueryWrapper() .in(Reservation::getDeviceId, devicesIds) .eq(Reservation::getStatus, ReservationStatus.APPROVED) .between(Reservation::getStartTime, now, endTime)); } @Override public void addReservation(Reservation reservation) { User user = userMapper.selectById(reservation.getUserId()); Team team = teamMapper.selectById(user.getTeamId()); Device device = deviceMapper.selectById(reservation.getDeviceId()); reservation.setApplicantName(user.getName()); reservation.setApplicantTeam(team.getName()); reservation.setApplicantContact(user.getPhone()); reservation.setDeviceAdminId(device.getDeviceAdminId()); reservation.setStatus(String.valueOf(ReservationStatus.PENDING_LEADER)); reservationMapper.insert(reservation); } @Override public Page getUserReservationVO(Long userId, Page pageRequest) { Page reservations = reservationMapper.selectPage(pageRequest, new LambdaQueryWrapper() .eq(Reservation::getUserId, userId) .orderByDesc(Reservation::getCreatedTime)); // 获取设备名称 List deviceIds = reservations.getRecords().stream() .map(Reservation::getDeviceId) .distinct() .toList(); Map deviceNameMap = deviceMapper.selectList(new LambdaQueryWrapper() .in(Device::getId, deviceIds)) .stream() .collect(Collectors.toMap(Device::getId, Device::getName)); // 获取设备管理员信息 List deviceAdminIDs = reservations.getRecords().stream() .map(Reservation::getDeviceAdminId) .filter(Objects::nonNull) .distinct() .toList(); Page res = PageUtil.copyPage(reservations); List vos; if (deviceAdminIDs.isEmpty()) { vos = reservations.getRecords().stream() .map(reservation -> new UserReservationVO(reservation, deviceNameMap)) .toList(); } else { Map deviceAdminMap = userMapper.selectList(new LambdaQueryWrapper() .in(User::getId, deviceAdminIDs)) .stream() .collect(Collectors.toMap(User::getId, Function.identity())); vos = reservations.getRecords().stream() .map(reservation -> new UserReservationVO(reservation, deviceNameMap, deviceAdminMap)) .toList(); } res.setRecords(vos); return res; } @Override public List getUnavailableTimes(Long id) { List reservations = reservationMapper.selectList(new LambdaQueryWrapper() .eq(Reservation::getDeviceId, id) .eq(Reservation::getStatus, "APPROVED") .gt(Reservation::getEndTime, LocalDate.now())); return reservations.stream() .map(r -> new TimeRangeVO(r.getStartTime(), r.getEndTime())) .toList(); } }