package com.chuanghai.ihotel.controller; 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.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.OrderSubmitTokenVO; import com.chuanghai.ihotel.vo.OrderSubmitVO; 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.Arrays; 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("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("confirm/order") @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("submit/order") 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); } /** * 订单列表 */ @GetMapping("/list") public CommonResult> list(PageParam pageParam){ PageUtils page = hotelOrderService.queryPage(pageParam); return CommonResult.ok().setResult(page); } /** * 信息 */ @GetMapping("/info/{id}") public CommonResult info(@PathVariable("id") Long id){ HotelOrderEntity hotelOrder = hotelOrderService.getById(id); return CommonResult.ok().setResult(hotelOrder); } /** * 修改 */ @PutMapping("/update") public CommonResult update(@RequestBody HotelOrderEntity hotelOrder){ boolean flag = hotelOrderService.updateById(hotelOrder); if (flag) { return CommonResult.ok(); } else { return CommonResult.fail(); } } /** * 删除订单 */ @DeleteMapping("/delete") public CommonResult delete(@RequestBody Long[] ids){ boolean flag = hotelOrderService.removeByIds(Arrays.asList(ids)); if (flag) { return CommonResult.ok(); } else { return CommonResult.fail(); } } /** * 时间校验 * @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天"); } } }