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.*; import github.benjamin.equipreservebackend.exception.ApiException; import github.benjamin.equipreservebackend.mapper.*; import github.benjamin.equipreservebackend.service.ReservationService; import github.benjamin.equipreservebackend.utils.PageUtil; import github.benjamin.equipreservebackend.vo.ReservationVO; 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.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; private final RoleMapper roleMapper; /** * 未来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; 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(); } @Override public Page getReservationVO(Long userId, Integer page, Integer size) { User user = userMapper.selectById(userId); List devices = deviceMapper.selectList(new LambdaQueryWrapper() .eq(Device::getTeamId, user.getTeamId()) .select()); List userRole = roleMapper.selectRoleByUserId(userId); ReservationStatus status; if (userRole.stream().anyMatch(r -> r.getCode().equals("LEADER"))) { status = ReservationStatus.PENDING_LEADER; } else if (userRole.stream().anyMatch(r -> r.getCode().equals("DEVICE_ADMIN"))) { status = ReservationStatus.PENDING_DEVICE_ADMIN; } else { throw new ApiException("用户角色不正确,请检查或联系开发人员"); } List deviceIds = devices.stream().map(Device::getId).toList(); Map deviceMap = devices.stream().collect(Collectors.toMap(Device::getId, Function.identity())); Page reservationPage = reservationMapper.selectPage(new Page<>(page, size), new LambdaQueryWrapper() .in(Reservation::getDeviceId, deviceIds) .eq(Reservation::getStatus, status) .orderByDesc(Reservation::getCreatedTime)); Page res = PageUtil.copyPage(reservationPage); res.setRecords(reservationPage.getRecords().stream() .map(r -> new ReservationVO(r, deviceMap.get(r.getDeviceId()))) .toList()); return res; } }