HotelOrderController.java 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package com.chuanghai.ihotel.controller;
  2. import com.chuanghai.ihotel.anno.ParamCheck;
  3. import com.chuanghai.ihotel.anno.RepeatSubmit;
  4. import com.chuanghai.ihotel.anno.UserLoginCheck;
  5. import com.chuanghai.ihotel.aop.LoginCheckAspect;
  6. import com.chuanghai.ihotel.common.exception.BizCodeEnume;
  7. import com.chuanghai.ihotel.common.exception.RRException;
  8. import com.chuanghai.ihotel.common.utils.CommonResult;
  9. import com.chuanghai.ihotel.common.utils.PageParam;
  10. import com.chuanghai.ihotel.common.utils.PageUtils;
  11. import com.chuanghai.ihotel.constant.RedisKey;
  12. import com.chuanghai.ihotel.controller.request.ConfrimOrderRequest;
  13. import com.chuanghai.ihotel.controller.request.SubmitOrderRequest;
  14. import com.chuanghai.ihotel.entity.HotelOrderEntity;
  15. import com.chuanghai.ihotel.service.HotelOrderService;
  16. import com.chuanghai.ihotel.util.CommonUtil;
  17. import com.chuanghai.ihotel.vo.ConfirmOrderVO;
  18. import com.chuanghai.ihotel.vo.LoginUserVO;
  19. import com.chuanghai.ihotel.vo.OrderSubmitTokenVO;
  20. import com.chuanghai.ihotel.vo.OrderSubmitVO;
  21. import org.springframework.beans.factory.annotation.Autowired;
  22. import org.springframework.data.redis.core.StringRedisTemplate;
  23. import org.springframework.web.bind.annotation.DeleteMapping;
  24. import org.springframework.web.bind.annotation.GetMapping;
  25. import org.springframework.web.bind.annotation.PathVariable;
  26. import org.springframework.web.bind.annotation.PostMapping;
  27. import org.springframework.web.bind.annotation.PutMapping;
  28. import org.springframework.web.bind.annotation.RequestBody;
  29. import org.springframework.web.bind.annotation.RequestHeader;
  30. import org.springframework.web.bind.annotation.RequestMapping;
  31. import org.springframework.web.bind.annotation.RestController;
  32. import java.time.LocalDate;
  33. import java.time.LocalDateTime;
  34. import java.time.ZoneOffset;
  35. import java.time.temporal.ChronoUnit;
  36. import java.util.Arrays;
  37. import java.util.concurrent.TimeUnit;
  38. /**
  39. * 酒店订单
  40. *
  41. * @author codingliang
  42. * @email codingliang@gmail.com
  43. * @date 2022-07-27 10:02:04
  44. */
  45. @RestController
  46. @RequestMapping("hotelOrder")
  47. public class HotelOrderController {
  48. @Autowired
  49. private StringRedisTemplate redisTemplate;
  50. @Autowired
  51. private HotelOrderService hotelOrderService;
  52. /**
  53. * 获取请求令牌
  54. * @param userToken 用户token
  55. * @return
  56. */
  57. @UserLoginCheck
  58. @GetMapping("submit/token")
  59. public CommonResult<OrderSubmitTokenVO> getOrderToken(@RequestHeader("user_token") String userToken){
  60. LoginUserVO loginUserVO = LoginCheckAspect.threadLocal.get();
  61. String cardNumber = loginUserVO.getCardNumber();
  62. String token = CommonUtil.getStringNumRandom(32);
  63. String key = String.format(RedisKey.SUBMIT_ORDER_TOKEN_KEY_FOR_TOKEN, cardNumber, token);
  64. // 令牌有效时间是30分钟
  65. redisTemplate.opsForValue().set(key, String.valueOf(Thread.currentThread().getId()),30, TimeUnit.MINUTES);
  66. OrderSubmitTokenVO tokenVO = OrderSubmitTokenVO.builder()
  67. .submitToken(token)
  68. .expire(LocalDateTime.now().plusMinutes(30).toInstant(ZoneOffset.ofHours(8)).toEpochMilli())
  69. .build();
  70. return CommonResult.ok().setResult(tokenVO);
  71. }
  72. /**
  73. * 确认订单
  74. * @param request 预定参数
  75. * @return
  76. */
  77. @GetMapping("confirm/order")
  78. @ParamCheck
  79. public CommonResult<ConfirmOrderVO> confirmOrder(ConfrimOrderRequest request) {
  80. // 时间校验
  81. timeCheck(CommonUtil.localDateToTime(request.getStartTime(), "00:00:00"),
  82. CommonUtil.localDateToTime(request.getEndTime(), "00:00:00"));
  83. ConfirmOrderVO vo = hotelOrderService.confirmOrder(request);
  84. return CommonResult.ok().setResult(vo);
  85. }
  86. /**
  87. * 提交订单
  88. * @param userToken 用户卡号
  89. * @param requestToken 请求令牌,从【获取请求令牌】接口获取
  90. * @param request 请求参数
  91. * @return
  92. */
  93. @UserLoginCheck
  94. @ParamCheck(index = 3)
  95. @RepeatSubmit(limitType = RepeatSubmit.Type.TOKEN)
  96. @PostMapping("submit/order")
  97. public CommonResult<OrderSubmitVO> submitOrder(@RequestHeader("user_token") String userToken,
  98. @RequestHeader("request_token") String requestToken,
  99. @RequestBody SubmitOrderRequest request) {
  100. // 时间校验
  101. timeCheck(request.getEnableStartTime(), request.getEnableEndTime());
  102. OrderSubmitVO vo = hotelOrderService.submitOrder(request);
  103. return CommonResult.ok().setResult(vo);
  104. }
  105. /**
  106. * 订单列表
  107. */
  108. @GetMapping("/list")
  109. public CommonResult<PageUtils<HotelOrderEntity>> list(PageParam pageParam){
  110. PageUtils page = hotelOrderService.queryPage(pageParam);
  111. return CommonResult.ok().setResult(page);
  112. }
  113. /**
  114. * 信息
  115. */
  116. @GetMapping("/info/{id}")
  117. public CommonResult<HotelOrderEntity> info(@PathVariable("id") Long id){
  118. HotelOrderEntity hotelOrder = hotelOrderService.getById(id);
  119. return CommonResult.ok().setResult(hotelOrder);
  120. }
  121. /**
  122. * 修改
  123. */
  124. @PutMapping("/update")
  125. public CommonResult<String> update(@RequestBody HotelOrderEntity hotelOrder){
  126. boolean flag = hotelOrderService.updateById(hotelOrder);
  127. if (flag) {
  128. return CommonResult.ok();
  129. } else {
  130. return CommonResult.fail();
  131. }
  132. }
  133. /**
  134. * 删除订单
  135. */
  136. @DeleteMapping("/delete")
  137. public CommonResult<String> delete(@RequestBody Long[] ids){
  138. boolean flag = hotelOrderService.removeByIds(Arrays.asList(ids));
  139. if (flag) {
  140. return CommonResult.ok();
  141. } else {
  142. return CommonResult.fail();
  143. }
  144. }
  145. /**
  146. * 时间校验
  147. * @param startTime
  148. * @param endTime
  149. */
  150. private void timeCheck(LocalDateTime startTime, LocalDateTime endTime) {
  151. // 校验参数
  152. LocalDateTime currentTime = LocalDateTime.now();
  153. LocalDate currentDay = currentTime.toLocalDate();
  154. LocalDate startDay = startTime.toLocalDate();
  155. LocalDate endDay = endTime.toLocalDate();
  156. if (startDay.isBefore(currentDay)) {
  157. long between = ChronoUnit.DAYS.between(startDay, currentDay);
  158. if (between > 1) {
  159. throw new RRException(BizCodeEnume.PARAMETER_ERROR, "预定日期错误,不能预定以前的房源");
  160. }
  161. // 当天上午10点之前可以预定前一天的房源
  162. if (currentTime.getHour() >= 10) {
  163. throw new RRException(BizCodeEnume.PARAMETER_ERROR, "预定日期错误,10点之后不可预定前一天房源");
  164. }
  165. }
  166. if (startDay.isEqual(endDay)) {
  167. throw new RRException(BizCodeEnume.PARAMETER_ERROR, "入住时间和离店时间不能为同一天");
  168. }
  169. if (endTime.isBefore(startTime)) {
  170. throw new RRException(BizCodeEnume.PARAMETER_ERROR, "离店时间必须晚于入住时间");
  171. }
  172. if (ChronoUnit.DAYS.between(startDay, endDay) > 7) {
  173. throw new RRException(BizCodeEnume.PARAMETER_ERROR, "最多预定7天");
  174. }
  175. }
  176. }