169 lines
7.4 KiB
Java
169 lines
7.4 KiB
Java
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.Role;
|
|
import github.benjamin.equipreservebackend.entity.User;
|
|
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.*;
|
|
import lombok.RequiredArgsConstructor;
|
|
import org.springframework.beans.factory.annotation.Value;
|
|
import org.springframework.stereotype.Service;
|
|
|
|
import java.time.LocalDate;
|
|
import java.util.Collections;
|
|
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<Reservation> getApprovedReservationsByDeviceIds(List<Long> devicesIds) {
|
|
LocalDate now = LocalDate.now();
|
|
LocalDate endTime = now.plusDays(days);
|
|
return reservationMapper.selectList(new LambdaQueryWrapper<Reservation>()
|
|
.in(Reservation::getDeviceId, devicesIds)
|
|
.in(Reservation::getStatus, List.of(ReservationStatus.APPROVED, ReservationStatus.APPROVED_ASSIST))
|
|
.between(Reservation::getStartTime, now, endTime));
|
|
}
|
|
|
|
@Override
|
|
public void addReservation(Reservation reservation) {
|
|
User user = userMapper.selectById(reservation.getUserId());
|
|
Device device = deviceMapper.selectById(reservation.getDeviceId());
|
|
|
|
reservation.setDeviceAdminId(device.getDeviceAdminId());
|
|
reservation.setStatus(String.valueOf(ReservationStatus.PENDING_LEADER));
|
|
reservationMapper.insert(reservation);
|
|
}
|
|
|
|
@Override
|
|
public Page<UserReservationVO> getUserReservationVO(Long userId, Page<Reservation> pageRequest) {
|
|
Page<Reservation> reservations = reservationMapper.selectPage(pageRequest, new LambdaQueryWrapper<Reservation>()
|
|
.eq(Reservation::getUserId, userId)
|
|
.orderByDesc(Reservation::getCreatedTime));
|
|
Page<UserReservationVO> res = PageUtil.copyPage(reservations);
|
|
if (reservations.getRecords().isEmpty()) {
|
|
res.setTotal(0);
|
|
res.setRecords(Collections.EMPTY_LIST);
|
|
return res;
|
|
}
|
|
|
|
// 获取设备名称
|
|
List<Long> deviceIds = reservations.getRecords().stream()
|
|
.map(Reservation::getDeviceId)
|
|
.distinct()
|
|
.toList();
|
|
Map<Long, Device> deviceNameMap = deviceMapper.selectList(new LambdaQueryWrapper<Device>()
|
|
.in(Device::getId, deviceIds))
|
|
.stream()
|
|
.collect(Collectors.toMap(Device::getId, Function.identity()));
|
|
|
|
List<Long> teamIds = deviceNameMap.values().stream().map(Device::getTeamId).toList();
|
|
|
|
Map<Long, User> teamLeaderMap = userMapper.selectLeaderByTeamIds(teamIds);
|
|
|
|
// 获取设备管理员信息
|
|
List<Long> deviceAdminIDs = reservations.getRecords().stream()
|
|
.map(Reservation::getDeviceAdminId)
|
|
.filter(Objects::nonNull)
|
|
.distinct()
|
|
.toList();
|
|
|
|
List<UserReservationVO> vos;
|
|
Map<Long, User> deviceAdminMap = userMapper.selectList(new LambdaQueryWrapper<User>()
|
|
.in(User::getId, deviceAdminIDs))
|
|
.stream()
|
|
.collect(Collectors.toMap(User::getId, Function.identity()));
|
|
|
|
vos = reservations.getRecords().stream()
|
|
.map(reservation -> new UserReservationVO(reservation, deviceNameMap, deviceAdminMap, teamLeaderMap))
|
|
.toList();
|
|
res.setRecords(vos);
|
|
return res;
|
|
}
|
|
|
|
@Override
|
|
public List<TimeRangeVO> getUnavailableTimes(Long id) {
|
|
List<Reservation> reservations = reservationMapper.selectList(new LambdaQueryWrapper<Reservation>()
|
|
.eq(Reservation::getDeviceId, id)
|
|
.in(Reservation::getStatus, List.of(ReservationStatus.APPROVED, ReservationStatus.APPROVED_ASSIST))
|
|
.gt(Reservation::getEndTime, LocalDate.now()));
|
|
|
|
return reservations.stream()
|
|
.map(r -> new TimeRangeVO(r.getStartTime(), r.getEndTime()))
|
|
.toList();
|
|
}
|
|
|
|
@Override
|
|
public Page<ReservationVO> getReservationVO(Long userId, Integer page, Integer size) {
|
|
User user = userMapper.selectById(userId);
|
|
List<Device> devices = deviceMapper.selectList(new LambdaQueryWrapper<Device>()
|
|
.eq(Device::getTeamId, user.getTeamId())
|
|
.select());
|
|
List<Role> 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<Long> deviceIds = devices.stream().map(Device::getId).toList();
|
|
Map<Long, Device> deviceMap = devices.stream().collect(Collectors.toMap(Device::getId, Function.identity()));
|
|
Page<Reservation> reservationPage = reservationMapper.selectPage(new Page<>(page, size), new LambdaQueryWrapper<Reservation>()
|
|
.in(Reservation::getDeviceId, deviceIds)
|
|
.eq(Reservation::getStatus, status)
|
|
.orderByDesc(Reservation::getCreatedTime));
|
|
Page<ReservationVO> res = PageUtil.copyPage(reservationPage);
|
|
res.setRecords(reservationPage.getRecords().stream()
|
|
.map(r -> new ReservationVO(r, deviceMap.get(r.getDeviceId())))
|
|
.toList());
|
|
return res;
|
|
}
|
|
|
|
@Override
|
|
public List<ReservationStatsVO> getReservationStats(LocalDate start, LocalDate end) {
|
|
return reservationMapper.getReservationStats(start, end);
|
|
}
|
|
|
|
@Override
|
|
public List<DeviceDetailStatsVO> getDeviceDetailStats(Long deviceId, LocalDate start, LocalDate end) {
|
|
return reservationMapper.selectList(new LambdaQueryWrapper<Reservation>()
|
|
.eq(Reservation::getDeviceId, deviceId)
|
|
.in(Reservation::getStatus, List.of("APPROVED", "APPROVED_ASSIST"))
|
|
.ge(Reservation::getStartTime, start)
|
|
.le(Reservation::getEndTime, end)
|
|
.orderByAsc(Reservation::getApplicantName, Reservation::getStartTime)).stream().map(DeviceDetailStatsVO::new).toList();
|
|
}
|
|
}
|