package com.chuanghai.ihotel.controller; import com.chuanghai.ihotel.anno.AdminLoginCheck; import com.chuanghai.ihotel.anno.ParamCheck; import com.chuanghai.ihotel.anno.RepeatSubmit; import com.chuanghai.ihotel.anno.UserLoginCheck; import com.chuanghai.ihotel.aop.LoginCheckAspect; import com.chuanghai.ihotel.common.exception.BizCodeEnume; import com.chuanghai.ihotel.common.exception.RRException; import com.chuanghai.ihotel.common.utils.CommonResult; import com.chuanghai.ihotel.common.utils.PageParam; import com.chuanghai.ihotel.common.utils.PageUtils; import com.chuanghai.ihotel.constant.RedisKey; import com.chuanghai.ihotel.controller.request.ConfrimOrderRequest; import com.chuanghai.ihotel.controller.request.OrderQueryRequest; import com.chuanghai.ihotel.controller.request.SubmitOrderRequest; import com.chuanghai.ihotel.entity.HotelOrderEntity; import com.chuanghai.ihotel.service.HotelOrderService; import com.chuanghai.ihotel.util.CommonUtil; import com.chuanghai.ihotel.vo.ConfirmOrderVO; import com.chuanghai.ihotel.vo.LoginUserVO; import com.chuanghai.ihotel.vo.OrderBillHandleVO; import com.chuanghai.ihotel.vo.OrderSubmitTokenVO; import com.chuanghai.ihotel.vo.OrderSubmitVO; import com.chuanghai.ihotel.vo.UserOrderDetailVO; import com.chuanghai.ihotel.vo.UserOrderIndexVO; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDate; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.time.temporal.ChronoUnit; import java.util.concurrent.TimeUnit; /** * 酒店订单 * * @author codingliang * @email codingliang@gmail.com * @date 2022-07-27 10:02:04 */ @RestController @RequestMapping("hotelOrder") public class HotelOrderController { @Autowired private StringRedisTemplate redisTemplate; @Autowired private HotelOrderService hotelOrderService; /** * 获取请求令牌 * @param userToken 用户token * @return */ @UserLoginCheck @GetMapping("/user/submit/token") public CommonResult getOrderToken(@RequestHeader("user_token") String userToken){ LoginUserVO loginUserVO = LoginCheckAspect.threadLocal.get(); String cardNumber = loginUserVO.getCardNumber(); String token = CommonUtil.getStringNumRandom(32); String key = String.format(RedisKey.SUBMIT_ORDER_TOKEN_KEY_FOR_TOKEN, cardNumber, token); // 令牌有效时间是30分钟 redisTemplate.opsForValue().set(key, String.valueOf(Thread.currentThread().getId()),30, TimeUnit.MINUTES); OrderSubmitTokenVO tokenVO = OrderSubmitTokenVO.builder() .submitToken(token) .expire(LocalDateTime.now().plusMinutes(30).toInstant(ZoneOffset.ofHours(8)).toEpochMilli()) .build(); return CommonResult.ok().setResult(tokenVO); } /** * 确认订单 * @param request 预定参数 * @return */ @GetMapping("/user/order/confirm") @ParamCheck public CommonResult confirmOrder(ConfrimOrderRequest request) { // 时间校验 timeCheck(CommonUtil.localDateToTime(request.getStartTime(), "00:00:00"), CommonUtil.localDateToTime(request.getEndTime(), "00:00:00")); ConfirmOrderVO vo = hotelOrderService.confirmOrder(request); return CommonResult.ok().setResult(vo); } /** * 提交订单 * @param userToken 用户卡号 * @param requestToken 请求令牌,从【获取请求令牌】接口获取 * @param request 请求参数 * @return */ @UserLoginCheck @ParamCheck(index = 3) @RepeatSubmit(limitType = RepeatSubmit.Type.TOKEN) @PostMapping("user/order/submit") public CommonResult submitOrder(@RequestHeader("user_token") String userToken, @RequestHeader("request_token") String requestToken, @RequestBody SubmitOrderRequest request) { // 时间校验 timeCheck(request.getEnableStartTime(), request.getEnableEndTime()); OrderSubmitVO vo = hotelOrderService.submitOrder(request); return CommonResult.ok().setResult(vo); } /** * 订单列表【用户端】 * @param userToken 用户token * @param pageParam 分页参数 * @param request 查询参数 * @return */ @UserLoginCheck @GetMapping("/user/order/page") public CommonResult> userOrderPage(@RequestHeader("user_token") String userToken, PageParam pageParam, OrderQueryRequest request) { PageUtils page = hotelOrderService.userOrderPage(pageParam, request); return CommonResult.ok().setResult(page); } /** * 订单列表【管理端】 */ @AdminLoginCheck @GetMapping("/admin/order/page") public CommonResult> page(@RequestHeader("admin_token") String adminToken, PageParam pageParam, OrderQueryRequest request){ PageUtils page = hotelOrderService.queryPage(pageParam, request); return CommonResult.ok().setResult(page); } /** * 订单详情 【用户端】 * @param userToken 用户token * @param orderId 订单id * @return */ @UserLoginCheck @GetMapping("user/order/{orderId}") public CommonResult userOrderDetail(@RequestHeader("user_token") String userToken, @PathVariable("orderId") Long orderId) { UserOrderDetailVO detailVO = hotelOrderService.userOrderDetail(orderId); return CommonResult.ok().setResult(detailVO); } /** * 获取订单支付参数 * @param userToken 用户token * @param orderId 订单id * @return */ @UserLoginCheck @GetMapping("/user/order/pay/{orderId}") public CommonResult getOrderPayParam(@RequestHeader("user_token") String userToken, @PathVariable("orderId") Long orderId) { OrderSubmitVO vo = hotelOrderService.getOrderPayParam(orderId); return CommonResult.ok().setResult(vo); } /** * 删除订单【用户端】 * @param userToken 用户token * @param orderId 订单id * @return */ @UserLoginCheck @DeleteMapping("user/order/{orderId}") public CommonResult userDeleteOrder(@RequestHeader("user_token") String userToken, @PathVariable("orderId") Long orderId) { hotelOrderService.userDeleteOrder(orderId); return CommonResult.ok(); } /** * 取消订单 * @param userToken 用户token * @param orderId 订单id * @return */ @UserLoginCheck @PutMapping("user/order/cancel/{orderId}") public CommonResult userCancelOrder(@RequestHeader("user_token") String userToken, @PathVariable("orderId") Long orderId) { hotelOrderService.userCancelOrder(orderId); return CommonResult.ok(); } /** * 办理入住 * @param userToken 用户token * @param orderId 订单id * @return */ @UserLoginCheck @PutMapping("user/order/hold/{orderId}") public CommonResult userHoldOrder(@RequestHeader("user_token") String userToken, @PathVariable("orderId") Long orderId) { hotelOrderService.userHoldOrder(orderId); return CommonResult.ok(); } /** * 办理退房 * @param userToken 用户token * @param orderId 订单id * @return */ @UserLoginCheck @PutMapping("user/order/return/{orderId}") public CommonResult userReturnOrder(@RequestHeader("user_token") String userToken, @PathVariable("orderId") Long orderId) { OrderBillHandleVO orderBillHandleVO = hotelOrderService.userReturnOrder(orderId); return CommonResult.ok().setResult(orderBillHandleVO); } // 办理续住 /** * 信息 */ @GetMapping("/info/{id}") public CommonResult info(@PathVariable("id") Long id){ HotelOrderEntity hotelOrder = hotelOrderService.getById(id); return CommonResult.ok().setResult(hotelOrder); } /** * 时间校验 * @param startTime * @param endTime */ private void timeCheck(LocalDateTime startTime, LocalDateTime endTime) { // 校验参数 LocalDateTime currentTime = LocalDateTime.now(); LocalDate currentDay = currentTime.toLocalDate(); LocalDate startDay = startTime.toLocalDate(); LocalDate endDay = endTime.toLocalDate(); if (startDay.isBefore(currentDay)) { long between = ChronoUnit.DAYS.between(startDay, currentDay); if (between > 1) { throw new RRException(BizCodeEnume.PARAMETER_ERROR, "预定日期错误,不能预定以前的房源"); } // 当天上午10点之前可以预定前一天的房源 if (currentTime.getHour() >= 10) { throw new RRException(BizCodeEnume.PARAMETER_ERROR, "预定日期错误,10点之后不可预定前一天房源"); } } if (startDay.isEqual(endDay)) { throw new RRException(BizCodeEnume.PARAMETER_ERROR, "入住时间和离店时间不能为同一天"); } if (endTime.isBefore(startTime)) { throw new RRException(BizCodeEnume.PARAMETER_ERROR, "离店时间必须晚于入住时间"); } if (ChronoUnit.DAYS.between(startDay, endDay) > 7) { throw new RRException(BizCodeEnume.PARAMETER_ERROR, "最多预定7天"); } } }