|
|
@@ -0,0 +1,187 @@
|
|
|
+package shop.alien.store.service.impl;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
+import lombok.RequiredArgsConstructor;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.beans.BeanUtils;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.transaction.annotation.Transactional;
|
|
|
+import shop.alien.entity.store.UserReservation;
|
|
|
+import shop.alien.entity.store.UserReservationTable;
|
|
|
+import shop.alien.entity.store.dto.UserReservationDTO;
|
|
|
+import shop.alien.entity.store.vo.UserReservationVo;
|
|
|
+import shop.alien.mapper.UserReservationMapper;
|
|
|
+import shop.alien.mapper.UserReservationTableMapper;
|
|
|
+import shop.alien.store.service.UserReservationService;
|
|
|
+
|
|
|
+import java.util.Date;
|
|
|
+import java.util.List;
|
|
|
+import java.util.concurrent.ThreadLocalRandom;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 用户预约 服务实现类
|
|
|
+ *
|
|
|
+ * @author system
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Service
|
|
|
+@Transactional(rollbackFor = Exception.class)
|
|
|
+@RequiredArgsConstructor
|
|
|
+public class UserReservationServiceImpl extends ServiceImpl<UserReservationMapper, UserReservation> implements UserReservationService {
|
|
|
+
|
|
|
+ private final UserReservationTableMapper userReservationTableMapper;
|
|
|
+
|
|
|
+ private static final int STATUS_PENDING = 0;
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Integer add(UserReservationDTO dto) {
|
|
|
+ if (dto.getUserId() == null) {
|
|
|
+ throw new RuntimeException("用户ID不能为空");
|
|
|
+ }
|
|
|
+ if (dto.getStoreId() == null) {
|
|
|
+ throw new RuntimeException("门店ID不能为空");
|
|
|
+ }
|
|
|
+ if (dto.getReservationDate() == null) {
|
|
|
+ throw new RuntimeException("预约日期不能为空");
|
|
|
+ }
|
|
|
+ if (dto.getGuestCount() == null || dto.getGuestCount() < 1) {
|
|
|
+ throw new RuntimeException("预约人数至少为1");
|
|
|
+ }
|
|
|
+
|
|
|
+ UserReservation entity = new UserReservation();
|
|
|
+ BeanUtils.copyProperties(dto, entity, "id", "tableIds");
|
|
|
+ entity.setId(null);
|
|
|
+ entity.setReservationNo(generateReservationNo());
|
|
|
+ if (entity.getStatus() == null) {
|
|
|
+ entity.setStatus(STATUS_PENDING);
|
|
|
+ }
|
|
|
+ this.save(entity);
|
|
|
+
|
|
|
+ saveReservationTables(entity.getId(), dto.getTableIds());
|
|
|
+ return entity.getId();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean updateReservation(UserReservationDTO dto) {
|
|
|
+ if (dto.getId() == null) {
|
|
|
+ throw new RuntimeException("预约ID不能为空");
|
|
|
+ }
|
|
|
+ UserReservation existing = this.getById(dto.getId());
|
|
|
+ if (existing == null) {
|
|
|
+ throw new RuntimeException("预约不存在");
|
|
|
+ }
|
|
|
+
|
|
|
+ UserReservation entity = new UserReservation();
|
|
|
+ BeanUtils.copyProperties(dto, entity, "tableIds", "reservationNo");
|
|
|
+ entity.setReservationNo(null);
|
|
|
+ this.updateById(entity);
|
|
|
+
|
|
|
+ saveReservationTables(existing.getId(), dto.getTableIds());
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean removeReservation(Integer id) {
|
|
|
+ UserReservation one = this.getById(id);
|
|
|
+ if (one == null) {
|
|
|
+ throw new RuntimeException("预约不存在");
|
|
|
+ }
|
|
|
+ userReservationTableMapper.physicalDeleteByReservationId(id);
|
|
|
+ return this.removeById(id);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public UserReservationVo getDetail(Integer id) {
|
|
|
+ UserReservation one = this.getById(id);
|
|
|
+ if (one == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ UserReservationVo vo = new UserReservationVo();
|
|
|
+ BeanUtils.copyProperties(one, vo);
|
|
|
+ vo.setTableIds(listTableIdsByReservationId(id));
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public IPage<UserReservationVo> pageList(Integer userId, Integer storeId, Integer status,
|
|
|
+ Date dateFrom, Date dateTo,
|
|
|
+ Integer pageNum, Integer pageSize) {
|
|
|
+ int current = pageNum == null || pageNum <= 0 ? 1 : pageNum;
|
|
|
+ int size = pageSize == null || pageSize <= 0 ? 10 : pageSize;
|
|
|
+ Page<UserReservation> page = new Page<>(current, size);
|
|
|
+ LambdaQueryWrapper<UserReservation> wrapper = buildListWrapper(userId, storeId, status, dateFrom, dateTo);
|
|
|
+ wrapper.orderByDesc(UserReservation::getCreatedTime);
|
|
|
+ IPage<UserReservation> entityPage = this.page(page, wrapper);
|
|
|
+ return entityPage.convert(this::toVoWithTableIds);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<UserReservationVo> list(Integer userId, Integer storeId, Integer status) {
|
|
|
+ LambdaQueryWrapper<UserReservation> wrapper = buildListWrapper(userId, storeId, status, null, null);
|
|
|
+ wrapper.orderByDesc(UserReservation::getCreatedTime);
|
|
|
+ List<UserReservation> list = this.list(wrapper);
|
|
|
+ return list.stream().map(this::toVoWithTableIds).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ private LambdaQueryWrapper<UserReservation> buildListWrapper(Integer userId, Integer storeId, Integer status,
|
|
|
+ Date dateFrom, Date dateTo) {
|
|
|
+ LambdaQueryWrapper<UserReservation> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ if (userId != null) {
|
|
|
+ wrapper.eq(UserReservation::getUserId, userId);
|
|
|
+ }
|
|
|
+ if (storeId != null) {
|
|
|
+ wrapper.eq(UserReservation::getStoreId, storeId);
|
|
|
+ }
|
|
|
+ if (status != null) {
|
|
|
+ wrapper.eq(UserReservation::getStatus, status);
|
|
|
+ }
|
|
|
+ if (dateFrom != null) {
|
|
|
+ wrapper.ge(UserReservation::getReservationDate, dateFrom);
|
|
|
+ }
|
|
|
+ if (dateTo != null) {
|
|
|
+ wrapper.le(UserReservation::getReservationDate, dateTo);
|
|
|
+ }
|
|
|
+ return wrapper;
|
|
|
+ }
|
|
|
+
|
|
|
+ private UserReservationVo toVoWithTableIds(UserReservation entity) {
|
|
|
+ UserReservationVo vo = new UserReservationVo();
|
|
|
+ BeanUtils.copyProperties(entity, vo);
|
|
|
+ vo.setTableIds(listTableIdsByReservationId(entity.getId()));
|
|
|
+ return vo;
|
|
|
+ }
|
|
|
+
|
|
|
+ private List<Integer> listTableIdsByReservationId(Integer reservationId) {
|
|
|
+ LambdaQueryWrapper<UserReservationTable> wrapper = new LambdaQueryWrapper<>();
|
|
|
+ wrapper.eq(UserReservationTable::getReservationId, reservationId)
|
|
|
+ .orderByAsc(UserReservationTable::getSort)
|
|
|
+ .orderByAsc(UserReservationTable::getId);
|
|
|
+ List<UserReservationTable> list = userReservationTableMapper.selectList(wrapper);
|
|
|
+ return list.stream().map(UserReservationTable::getTableId).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 保存预约与桌号关联:先物理删除该预约下原有关联再插入
|
|
|
+ */
|
|
|
+ private void saveReservationTables(Integer reservationId, List<Integer> tableIds) {
|
|
|
+ userReservationTableMapper.physicalDeleteByReservationId(reservationId);
|
|
|
+ if (tableIds != null && !tableIds.isEmpty()) {
|
|
|
+ int sort = 0;
|
|
|
+ for (Integer tableId : tableIds) {
|
|
|
+ UserReservationTable rt = new UserReservationTable();
|
|
|
+ rt.setReservationId(reservationId);
|
|
|
+ rt.setTableId(tableId);
|
|
|
+ rt.setSort(sort++);
|
|
|
+ userReservationTableMapper.insert(rt);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String generateReservationNo() {
|
|
|
+ return "RV" + System.currentTimeMillis() + ThreadLocalRandom.current().nextInt(1000, 9999);
|
|
|
+ }
|
|
|
+}
|