From 2b271e788297040282e034b564e6f6d4a2bc77e6 Mon Sep 17 00:00:00 2001 From: chen-xin-zhi <3588068430@qq.com> Date: Sun, 16 Feb 2025 10:08:02 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E4=BA=86=E5=86=99=E7=9C=9F?= =?UTF-8?q?=E9=A2=84=E7=BA=A6=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../heritage/constant/BookConstant.java | 11 -- .../heritage/constant/MqConstant.java | 5 + .../constant/OrderStatusConstant.java | 1 + .../book/PhotoCategoryController.java | 36 ++++- .../book/PhotoProductsController.java | 2 +- .../good/AppointmentDateController.java | 6 +- .../controller/good/GoodController.java | 4 +- .../AdvanceOrderController.java | 95 +++++++---- .../controller/wx/WeChatPayController.java | 102 ++++++++++-- .../listener/AdvanceOrderStatusListener.java | 70 +++++++++ .../listener/OrderStatusListener.java | 1 - .../advanceOrder/AdvanceOrderAddRequest.java | 33 ++-- .../AdvanceOrderQueryRequest.java | 11 +- .../AppointmentDateAddRequest.java | 2 +- .../AppointmentDateUpdateRequest.java | 2 +- .../AppointmentDateSingleAddRequest.java | 2 +- .../dto/snapshot/PhotoProductsSnapshot.java | 52 +++++++ .../TimePeriodAddRequest.java | 2 +- .../TimePeriodUpdateRequest.java | 2 +- .../single/TimePeriodSingleAddRequest.java | 2 +- .../single/TimePeriodSingleUpdateRequest.java | 2 +- .../heritage/model/entity/AdvanceOrder.java | 22 ++- .../model/vo/advanceorder/AdvanceOrderVO.java | 23 +-- .../vo/appointment/AppointmentDateVO.java | 2 +- .../vo/clothesinfo/ClothesInfoLabelVO.java | 45 ------ .../PhotoCategoryVO.java | 2 +- .../PhotoProductsVO.java | 2 +- .../TimePeriodVO.java | 2 +- .../service/book/AdvanceOrderService.java | 12 ++ .../book/impl/AdvanceOrderServiceImpl.java | 87 ++++++++--- .../heritage/service/wx/WeChatService.java | 29 +++- .../service/wx/impl/WeChatServiceImpl.java | 147 ++++++++++++++++-- 32 files changed, 614 insertions(+), 202 deletions(-) delete mode 100644 src/main/java/com/cultural/heritage/constant/BookConstant.java rename src/main/java/com/cultural/heritage/controller/{book => order}/AdvanceOrderController.java (64%) create mode 100644 src/main/java/com/cultural/heritage/listener/AdvanceOrderStatusListener.java create mode 100644 src/main/java/com/cultural/heritage/model/dto/snapshot/PhotoProductsSnapshot.java rename src/main/java/com/cultural/heritage/model/dto/{timeperiod => timePeriod}/TimePeriodAddRequest.java (93%) rename src/main/java/com/cultural/heritage/model/dto/{timeperiod => timePeriod}/TimePeriodUpdateRequest.java (95%) rename src/main/java/com/cultural/heritage/model/dto/{timeperiod => timePeriod}/single/TimePeriodSingleAddRequest.java (94%) rename src/main/java/com/cultural/heritage/model/dto/{timeperiod => timePeriod}/single/TimePeriodSingleUpdateRequest.java (93%) delete mode 100644 src/main/java/com/cultural/heritage/model/vo/clothesinfo/ClothesInfoLabelVO.java rename src/main/java/com/cultural/heritage/model/vo/{clothesgrade => photoCategory}/PhotoCategoryVO.java (85%) rename src/main/java/com/cultural/heritage/model/vo/{clothesinfo => photoProducts}/PhotoProductsVO.java (95%) rename src/main/java/com/cultural/heritage/model/vo/{timeperiod => timePeriod}/TimePeriodVO.java (90%) diff --git a/src/main/java/com/cultural/heritage/constant/BookConstant.java b/src/main/java/com/cultural/heritage/constant/BookConstant.java deleted file mode 100644 index a3af2f6..0000000 --- a/src/main/java/com/cultural/heritage/constant/BookConstant.java +++ /dev/null @@ -1,11 +0,0 @@ -package com.cultural.heritage.constant; - -public interface BookConstant { - - - String RENT_CLOTHES = "整套约拍"; - - - String OWN_CLOTHES = "自带服装"; - -} diff --git a/src/main/java/com/cultural/heritage/constant/MqConstant.java b/src/main/java/com/cultural/heritage/constant/MqConstant.java index d6c9bde..f3fd6f7 100644 --- a/src/main/java/com/cultural/heritage/constant/MqConstant.java +++ b/src/main/java/com/cultural/heritage/constant/MqConstant.java @@ -15,4 +15,9 @@ public interface MqConstant { String DELAY_USER_COUPON_QUEUE = "userCoupon.delay.queue"; String DELAY_USER_COUPON_ROUTING_KEY = "userCoupon.key"; + + String DELAY_ADVANCE_ORDER_QUEUE = "advanceOrder.delay.queue"; + + String DELAY_ADVANCE_ROUTING_KEY = "advanceOrder.key"; + } diff --git a/src/main/java/com/cultural/heritage/constant/OrderStatusConstant.java b/src/main/java/com/cultural/heritage/constant/OrderStatusConstant.java index 59a2819..91291c3 100644 --- a/src/main/java/com/cultural/heritage/constant/OrderStatusConstant.java +++ b/src/main/java/com/cultural/heritage/constant/OrderStatusConstant.java @@ -21,6 +21,7 @@ public interface OrderStatusConstant { String PAYMENT_REFUNDED = "已退款"; + String PENDING_CONSUME = "待消费"; } diff --git a/src/main/java/com/cultural/heritage/controller/book/PhotoCategoryController.java b/src/main/java/com/cultural/heritage/controller/book/PhotoCategoryController.java index d9276a0..74f6831 100644 --- a/src/main/java/com/cultural/heritage/controller/book/PhotoCategoryController.java +++ b/src/main/java/com/cultural/heritage/controller/book/PhotoCategoryController.java @@ -14,12 +14,17 @@ import com.cultural.heritage.model.dto.CommonRequest; import com.cultural.heritage.model.dto.CommonStringRequest; import com.cultural.heritage.model.dto.photoCategory.PhotoCategoryAddRequest; import com.cultural.heritage.model.dto.photoCategory.PhotoCategoryUpdateRequest; +import com.cultural.heritage.model.entity.BookingDate; +import com.cultural.heritage.model.entity.BookingTime; import com.cultural.heritage.model.entity.PhotoCategory; import com.cultural.heritage.model.entity.PhotoProducts; -import com.cultural.heritage.model.vo.clothesgrade.PhotoCategoryVO; -import com.cultural.heritage.model.vo.clothesinfo.PhotoProductsVO; +import com.cultural.heritage.model.vo.photoCategory.PhotoCategoryVO; +import com.cultural.heritage.model.vo.photoProducts.PhotoProductsVO; +import com.cultural.heritage.service.book.BookingDateService; +import com.cultural.heritage.service.book.BookingTimeService; import com.cultural.heritage.service.book.PhotoCategoryService; import com.cultural.heritage.service.book.PhotoProductsService; +import com.cultural.heritage.service.common.CommonService; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; @@ -48,6 +53,18 @@ public class PhotoCategoryController { private PhotoProductsService photoProductsService; + @Resource + private CommonService commonService; + + + @Resource + private BookingDateService bookingDateService; + + + @Resource + private BookingTimeService bookingTimeService; + + /** * Web端管理员添加写真类别 @@ -123,11 +140,24 @@ public class PhotoCategoryController { throw new BusinessException(ErrorCode.PARAMS_ERROR); } Long id = commonRequest.getId(); - // 删除写真类别之前,先删除该类别下所有产品 PhotoCategory photoCategory = photoCategoryService.getById(id); QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.eq("categoryName", photoCategory.getName()); List photoProductsList = photoProductsService.list(queryWrapper); + // 获取预约日期列表 + List bookingDateList = commonService.getItemsByIds(photoProductsList, bookingDateService, PhotoProducts::getId); + // 获取预约时间列表 + List bookingTimes = commonService.getItemsByIds(bookingDateList, bookingTimeService, BookingDate::getId); + + // 批量删除预约时间 + boolean removeTime = bookingTimeService.removeBatchByIds(bookingTimes); + ThrowUtils.throwIf(!removeTime, ErrorCode.OPERATION_ERROR, "预约时间删除失败"); + + // 批量删除预约日期 + boolean removeDate = bookingDateService.removeBatchByIds(bookingDateList); + ThrowUtils.throwIf(!removeDate, ErrorCode.OPERATION_ERROR, "预约日期批量删除失败"); + + // 删除该类别下所有写真产品 if (!photoProductsList.isEmpty()) { boolean remove = photoProductsService.removeBatchByIds(photoProductsList); ThrowUtils.throwIf(!remove, ErrorCode.OPERATION_ERROR, "写真产品批量删除失败"); diff --git a/src/main/java/com/cultural/heritage/controller/book/PhotoProductsController.java b/src/main/java/com/cultural/heritage/controller/book/PhotoProductsController.java index 12f3b07..a177fbc 100644 --- a/src/main/java/com/cultural/heritage/controller/book/PhotoProductsController.java +++ b/src/main/java/com/cultural/heritage/controller/book/PhotoProductsController.java @@ -25,7 +25,7 @@ import com.cultural.heritage.model.entity.BookingTime; import com.cultural.heritage.model.entity.PhotoProducts; import com.cultural.heritage.model.vo.bookingDate.BookingDateVO; import com.cultural.heritage.model.vo.bookingTime.BookingTimeVO; -import com.cultural.heritage.model.vo.clothesinfo.PhotoProductsVO; +import com.cultural.heritage.model.vo.photoProducts.PhotoProductsVO; import com.cultural.heritage.service.book.BookingDateService; import com.cultural.heritage.service.book.BookingTimeService; import com.cultural.heritage.service.book.PhotoCategoryService; diff --git a/src/main/java/com/cultural/heritage/controller/good/AppointmentDateController.java b/src/main/java/com/cultural/heritage/controller/good/AppointmentDateController.java index 0948459..9aebc21 100644 --- a/src/main/java/com/cultural/heritage/controller/good/AppointmentDateController.java +++ b/src/main/java/com/cultural/heritage/controller/good/AppointmentDateController.java @@ -12,9 +12,9 @@ import com.cultural.heritage.exception.BusinessException; import com.cultural.heritage.exception.ThrowUtils; import com.cultural.heritage.model.dto.CommonRequest; import com.cultural.heritage.model.dto.appointment.single.AppointmentDateSingleAddRequest; -import com.cultural.heritage.model.dto.timeperiod.TimePeriodAddRequest; -import com.cultural.heritage.model.dto.timeperiod.single.TimePeriodSingleAddRequest; -import com.cultural.heritage.model.dto.timeperiod.single.TimePeriodSingleUpdateRequest; +import com.cultural.heritage.model.dto.timePeriod.TimePeriodAddRequest; +import com.cultural.heritage.model.dto.timePeriod.single.TimePeriodSingleAddRequest; +import com.cultural.heritage.model.dto.timePeriod.single.TimePeriodSingleUpdateRequest; import com.cultural.heritage.model.entity.AppointmentDate; import com.cultural.heritage.model.entity.Good; import com.cultural.heritage.model.entity.PendingServiceGood; diff --git a/src/main/java/com/cultural/heritage/controller/good/GoodController.java b/src/main/java/com/cultural/heritage/controller/good/GoodController.java index 77b54b7..8e1bf59 100644 --- a/src/main/java/com/cultural/heritage/controller/good/GoodController.java +++ b/src/main/java/com/cultural/heritage/controller/good/GoodController.java @@ -24,14 +24,14 @@ import com.cultural.heritage.model.dto.good.service.ServiceGoodAddRequest; import com.cultural.heritage.model.dto.good.service.ServiceGoodQueryRequest; import com.cultural.heritage.model.dto.good.service.ServiceGoodSingleUpdateRequest; import com.cultural.heritage.model.dto.good.service.ServiceGoodUpdateRequest; -import com.cultural.heritage.model.dto.timeperiod.TimePeriodAddRequest; +import com.cultural.heritage.model.dto.timePeriod.TimePeriodAddRequest; import com.cultural.heritage.model.entity.*; import com.cultural.heritage.model.vo.appointment.AppointmentDateTimePeriodVO; import com.cultural.heritage.model.vo.appointment.AppointmentDateVO; import com.cultural.heritage.model.vo.good.GoodPageVO; import com.cultural.heritage.model.vo.good.ServiceGoodCardVO; import com.cultural.heritage.model.vo.good.ServiceGoodVO; -import com.cultural.heritage.model.vo.timeperiod.TimePeriodVO; +import com.cultural.heritage.model.vo.timePeriod.TimePeriodVO; import com.cultural.heritage.service.good.*; import com.cultural.heritage.service.order.PendingServiceGoodService; import com.cultural.heritage.service.user.UserService; diff --git a/src/main/java/com/cultural/heritage/controller/book/AdvanceOrderController.java b/src/main/java/com/cultural/heritage/controller/order/AdvanceOrderController.java similarity index 64% rename from src/main/java/com/cultural/heritage/controller/book/AdvanceOrderController.java rename to src/main/java/com/cultural/heritage/controller/order/AdvanceOrderController.java index 672907d..cd8e908 100644 --- a/src/main/java/com/cultural/heritage/controller/book/AdvanceOrderController.java +++ b/src/main/java/com/cultural/heritage/controller/order/AdvanceOrderController.java @@ -1,8 +1,7 @@ -package com.cultural.heritage.controller.book; +package com.cultural.heritage.controller.order; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; -import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.cultural.heritage.annotation.AuthCheck; import com.cultural.heritage.common.BaseResponse; @@ -12,17 +11,21 @@ import com.cultural.heritage.constant.OrderStatusConstant; import com.cultural.heritage.constant.UserConstant; import com.cultural.heritage.exception.BusinessException; import com.cultural.heritage.exception.ThrowUtils; +import com.cultural.heritage.model.dto.CommonRequest; import com.cultural.heritage.model.dto.advanceOrder.AdvanceOrderAddRequest; import com.cultural.heritage.model.dto.advanceOrder.AdvanceOrderQueryRequest; -import com.cultural.heritage.model.dto.order.OrderUpdateRequest; import com.cultural.heritage.model.dto.snapshot.ContactsSnapshot; +import com.cultural.heritage.model.dto.snapshot.PhotoProductsSnapshot; import com.cultural.heritage.model.entity.AdvanceOrder; import com.cultural.heritage.model.entity.Contacts; +import com.cultural.heritage.model.entity.PhotoProducts; import com.cultural.heritage.model.entity.User; import com.cultural.heritage.model.vo.advanceorder.AdvanceOrderVO; import com.cultural.heritage.service.address.ContactsService; import com.cultural.heritage.service.book.AdvanceOrderService; +import com.cultural.heritage.service.book.PhotoProductsService; import com.cultural.heritage.service.user.UserService; +import com.cultural.heritage.utils.OrderNumberUtils; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.annotation.Resource; @@ -34,6 +37,7 @@ import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +import java.math.BigDecimal; import java.util.List; @RestController @@ -55,40 +59,96 @@ public class AdvanceOrderController { private ContactsService contactsService; + @Resource + private PhotoProductsService photoProductsService; + + /** * 小程序端用户创建写真预约订单 * @param addAdvanceOrderRequest 写真预约订单添加请求体 - * @return 是否添加成功 + * @return 订单id */ @PostMapping("/add") @Operation(summary = "小程序端用户创建写真预约订单", description = "参数:写真预约订单添加请求体, 权限:所有人,方法名:addAdvanceOrder") - public BaseResponse addAdvanceOrder(@RequestBody AdvanceOrderAddRequest addAdvanceOrderRequest, HttpServletRequest request) { + public BaseResponse addAdvanceOrder(@RequestBody AdvanceOrderAddRequest addAdvanceOrderRequest, HttpServletRequest request) { if (addAdvanceOrderRequest == null) { throw new BusinessException(ErrorCode.PARAMS_ERROR); } // 获取用户id User loginUser = userService.getLoginUser(request); Long userId = loginUser.getId(); + // 校验当前订单时间是否被预约过或者已过期 + String specificDate = addAdvanceOrderRequest.getSpecificDate(); + String timePoint = addAdvanceOrderRequest.getTimePoint(); + advanceOrderService.validBookingTime(specificDate, timePoint); // 获取联系人信息 Long contactsId = addAdvanceOrderRequest.getContactsId(); Contacts contacts = contactsService.getById(contactsId); + ThrowUtils.throwIf(contacts == null, ErrorCode.OPERATION_ERROR, "联系人信息不存在"); ContactsSnapshot contactsSnapshot = new ContactsSnapshot(); BeanUtils.copyProperties(contacts, contactsSnapshot); - // 封装写真预约订单类 + // 获取写真产品信息 + Long photoProductId = addAdvanceOrderRequest.getPhotoProductId(); + PhotoProducts photoProducts = photoProductsService.getById(photoProductId); + ThrowUtils.throwIf(photoProducts == null, ErrorCode.OPERATION_ERROR, "当前写真产品不存在"); + PhotoProductsSnapshot photoProductsSnapshot = new PhotoProductsSnapshot(); + BeanUtils.copyProperties(photoProducts, photoProductsSnapshot); + // 计算订单总金额 + BigDecimal price = photoProducts.getPrice(); + Integer quantity = addAdvanceOrderRequest.getQuantity(); + BigDecimal totalAmount = price.multiply(BigDecimal.valueOf(quantity)); + // 生成订单编号 + String orderNumber = OrderNumberUtils.generateOrderId(); + // 封装写真预约订单 AdvanceOrder advanceOrder = new AdvanceOrder(); BeanUtils.copyProperties(addAdvanceOrderRequest, advanceOrder); advanceOrder.setUserId(userId); advanceOrder.setContactsSnapshot(contactsSnapshot); + advanceOrder.setPhotoProductsSnapshot(photoProductsSnapshot); + advanceOrder.setTotalAmount(totalAmount); + advanceOrder.setOrderNumber(orderNumber); // 校验 advanceOrderService.validAdvanceOrder(advanceOrder); boolean result = advanceOrderService.save(advanceOrder); - ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR); + ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "订单创建失败"); + // 向消息队列中发送订单创建的消息 + advanceOrderService.sendAdvanceOrderMessage(advanceOrder.getId()); + return ResultUtils.success(advanceOrder.getId()); + } + + + + + + /** + * 小程序端用户取消写真预约订单 + * @param commonRequest 订单id + * @return 是否取消成功 + */ + @PostMapping ("/cancel/id") + @Operation(summary = "小程序端用户取消写真预约订单", description = "参数:订单id,权限:所有人,方法名:cancelOrderById") + public BaseResponse cancelOrderById(@RequestBody CommonRequest commonRequest, HttpServletRequest request) { + if (commonRequest == null || commonRequest.getId() <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + Long id = commonRequest.getId(); + userService.getLoginUser(request); + AdvanceOrder advanceOrder = advanceOrderService.getById(id); + ThrowUtils.throwIf(advanceOrder == null, ErrorCode.OPERATION_ERROR, "订单不存在"); + ThrowUtils.throwIf(!advanceOrder.getOrderStatus().equals(OrderStatusConstant.PENDING_PAYMENT), ErrorCode.SYSTEM_ERROR, "订单状态错误"); + advanceOrder.setOrderStatus(OrderStatusConstant.TRANSACTION_CLOSED); + boolean update = advanceOrderService.updateById(advanceOrder); + ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "订单状态更新失败"); + return ResultUtils.success(true); } + + + /** * Web端管理员查询写真预约订单 * @param advanceOrderQueryRequest 写真预约订单查询请求体 @@ -146,27 +206,6 @@ public class AdvanceOrderController { } - /** - * Web端管理员更新订单状态 - * @param orderUpdateRequest 订单状态更新请求体 - * @return 是否更新成功 - */ - @PostMapping("/update") - @Operation(summary = "Web端管理员更新订单状态", description = "参数:订单状态更新请求体,权限:管理员(admin, boss), 方法名:updateAdvanceOrderStatus") - public BaseResponse updateAdvanceOrderStatus(@RequestBody OrderUpdateRequest orderUpdateRequest) { - if (orderUpdateRequest == null || orderUpdateRequest.getId() <= 0) { - throw new BusinessException(ErrorCode.PARAMS_ERROR); - } - Long id = orderUpdateRequest.getId(); - String trackingNumber = orderUpdateRequest.getTrackingNumber(); - UpdateWrapper updateWrapper = new UpdateWrapper<>(); - updateWrapper.eq("id", id); - updateWrapper.set("trackingNumber", trackingNumber); - updateWrapper.set("orderStatus", OrderStatusConstant.PENDING_DELIVERY); - boolean result = advanceOrderService.update(updateWrapper); - ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR); - return ResultUtils.success(true); - } diff --git a/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java b/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java index 419ba7c..5599ae2 100644 --- a/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java +++ b/src/main/java/com/cultural/heritage/controller/wx/WeChatPayController.java @@ -10,9 +10,11 @@ import com.cultural.heritage.constant.UserConstant; import com.cultural.heritage.exception.BusinessException; import com.cultural.heritage.exception.ThrowUtils; import com.cultural.heritage.model.dto.CommonRequest; +import com.cultural.heritage.model.entity.AdvanceOrder; import com.cultural.heritage.model.entity.Order; import com.cultural.heritage.model.entity.OrderItems; import com.cultural.heritage.model.entity.User; +import com.cultural.heritage.service.book.AdvanceOrderService; import com.cultural.heritage.service.order.OrderItemService; import com.cultural.heritage.service.order.OrderService; import com.cultural.heritage.service.user.UserService; @@ -27,7 +29,10 @@ import jakarta.annotation.Resource; import jakarta.servlet.http.HttpServletRequest; import lombok.extern.slf4j.Slf4j; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.*; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; import java.io.IOException; @@ -53,13 +58,16 @@ public class WeChatPayController { @Resource private OrderItemService orderItemService; + @Resource + private AdvanceOrderService advanceOrderService; + /** - * JSAPI 下单 + * JSAPI 下单(商品类) */ @PostMapping("/payment/create") - @Operation(summary = "JSAPI 下单", description = "参数:订单id, 权限:所有人, 方法名:createPayment") + @Operation(summary = "JSAPI 下单(商品类)", description = "参数:订单id, 权限:所有人, 方法名:createPayment") public BaseResponse createPayment(@RequestBody CommonRequest commonRequest, HttpServletRequest request) { User loginUser = userService.getLoginUser(request); String miniOpenId = loginUser.getMiniOpenId(); @@ -78,11 +86,11 @@ public class WeChatPayController { /** - * JSAPI 下单回调 + * JSAPI 下单回调(商品类) */ @PostMapping("/payment/callback") @Transactional(rollbackFor = Exception.class) - @Operation(summary = "JSAPI 下单回调", description = "参数:订单id, 权限:所有人, 方法名:callbackPayment") + @Operation(summary = "JSAPI 下单回调(商品类)", description = "参数:订单id, 权限:所有人, 方法名:callbackPayment") public synchronized BaseResponse callbackPayment(HttpServletRequest request) throws IOException { // 获取下单信息 Transaction transaction = weChatService.getTransactionInfo(request); @@ -96,11 +104,52 @@ public class WeChatPayController { /** - * Web端管理员全额退款 + * JSAPI 下单(写真预约类) + */ + @PostMapping("/payment/photo/create") + @Operation(summary = "JSAPI 下单(写真预约类)", description = "参数:订单id, 权限:所有人, 方法名:createPhotoProductsPayment") + public BaseResponse createPhotoProductsPayment(@RequestBody CommonRequest commonRequest, HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + String miniOpenId = loginUser.getMiniOpenId(); + ThrowUtils.throwIf(miniOpenId == null, ErrorCode.NOT_FOUND_ERROR, "不是小程序用户"); + Long orderId = commonRequest.getId(); + AdvanceOrder advanceOrder = advanceOrderService.getById(orderId); + ThrowUtils.throwIf(advanceOrder == null, ErrorCode.NOT_FOUND_ERROR, "订单不存在"); + ThrowUtils.throwIf(!advanceOrder.getOrderStatus().equals(OrderStatusConstant.PENDING_PAYMENT), ErrorCode.OPERATION_ERROR, "订单状态错误"); + if (!loginUser.getId().equals(advanceOrder.getUserId())) { + throw new BusinessException(ErrorCode.NO_AUTH_ERROR, "你不是该订单用户!"); + } + PrepayWithRequestPaymentResponse response = weChatService.createPhotoProductsPayment(String.valueOf(orderId), miniOpenId, advanceOrder.getTotalAmount()); + return ResultUtils.success(response); + } + + + + /** + * JSAPI 下单回调(写真预约类) + */ + @PostMapping("/payment/photo/callback") + @Transactional(rollbackFor = Exception.class) + @Operation(summary = "JSAPI 下单回调(写真预约类)", description = "参数:订单id, 权限:所有人, 方法名:callbackPhotoProductsPayment") + public synchronized BaseResponse callbackPhotoProductsPayment(HttpServletRequest request) throws IOException { + // 获取下单信息 + Transaction transaction = weChatService.getTransactionInfo(request); + System.out.println("下单信息:" + transaction); + // 支付回调 + boolean result = weChatService.paymentPhotoProductsCallback(transaction); + ThrowUtils.throwIf(!result, ErrorCode.SYSTEM_ERROR, "微信支付回调失败"); + return ResultUtils.success(true); + } + + + + + /** + * Web端管理员全额退款(商品类) * @param commonRequest 订单id */ @PostMapping("/refund/create") - @Operation(summary = "Web端管理员全额退款", description = "参数:订单id, 权限:web端管理员, 方法名:createRefund") + @Operation(summary = "Web端管理员全额退款(商品类)", description = "参数:订单id, 权限:web端管理员, 方法名:createRefund") @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) public BaseResponse createRefund(@RequestBody CommonRequest commonRequest) { if (commonRequest == null || commonRequest.getId() <= 0) { @@ -115,6 +164,24 @@ public class WeChatPayController { + /** + * Web端管理员全额退款(写真预约类) + * @param commonRequest 订单id + */ + @PostMapping("/refund/photo/create") + @Operation(summary = "Web端管理员全额退款(商品类)", description = "参数:订单id, 权限:web端管理员, 方法名:createPhotoProductsRefund") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public BaseResponse createPhotoProductsRefund(@RequestBody CommonRequest commonRequest) { + if (commonRequest == null || commonRequest.getId() <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + Long orderId = commonRequest.getId(); + AdvanceOrder advanceOrder = advanceOrderService.getById(orderId); + ThrowUtils.throwIf(advanceOrder == null, ErrorCode.NOT_FOUND_ERROR, "订单不存在"); + Refund refund = weChatService.refundPhotoProductsPayment(String.valueOf(orderId), advanceOrder.getTotalAmount()); + return ResultUtils.success(refund); + } + @@ -140,7 +207,6 @@ public class WeChatPayController { - /** * Web管理员剩余部分退款 * @param commonRequest 订单id @@ -165,10 +231,10 @@ public class WeChatPayController { /** - * 全额退款回调 + * 全额退款回调(商品类) */ @PostMapping("/refund/callback") - @Operation(summary = "全额退款回调", description = "参数:订单id, 权限:web端管理员, 方法名:callbackRefund") + @Operation(summary = "全额退款回调(商品类)", description = "参数:订单id, 权限:web端管理员, 方法名:callbackRefund") public BaseResponse callbackRefund(HttpServletRequest request) { // 获取退款信息 RefundNotification refundNotification = weChatService.getRefundInfo(request); @@ -179,6 +245,22 @@ public class WeChatPayController { } + /** + * 全额退款回调(写真预约类) + */ + @PostMapping("/refund/photo/callback") + @Operation(summary = "全额退款回调(写真预约类)", description = "参数:订单id, 权限:web端管理员, 方法名:callbackPhotoProductsRefund") + public BaseResponse callbackPhotoProductsRefund(HttpServletRequest request) { + // 获取退款信息 + RefundNotification refundNotification = weChatService.getRefundInfo(request); + // 退款回调 + boolean result = weChatService.refundPhotoProductsCallback(refundNotification); + ThrowUtils.throwIf(!result, ErrorCode.SYSTEM_ERROR, "退款回调失败"); + return ResultUtils.success(true); + } + + + /** * 部分退款回调 diff --git a/src/main/java/com/cultural/heritage/listener/AdvanceOrderStatusListener.java b/src/main/java/com/cultural/heritage/listener/AdvanceOrderStatusListener.java new file mode 100644 index 0000000..3194761 --- /dev/null +++ b/src/main/java/com/cultural/heritage/listener/AdvanceOrderStatusListener.java @@ -0,0 +1,70 @@ +package com.cultural.heritage.listener; + + +import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; +import com.cultural.heritage.common.ErrorCode; +import com.cultural.heritage.constant.MqConstant; +import com.cultural.heritage.constant.OrderStatusConstant; +import com.cultural.heritage.exception.ThrowUtils; +import com.cultural.heritage.model.entity.AdvanceOrder; +import com.cultural.heritage.service.book.AdvanceOrderService; +import com.cultural.heritage.utils.MultiDelayMessage; +import jakarta.annotation.Resource; +import org.springframework.amqp.rabbit.annotation.Exchange; +import org.springframework.amqp.rabbit.annotation.Queue; +import org.springframework.amqp.rabbit.annotation.QueueBinding; +import org.springframework.amqp.rabbit.annotation.RabbitListener; +import org.springframework.amqp.rabbit.core.RabbitTemplate; +import org.springframework.stereotype.Component; + +@Component +public class AdvanceOrderStatusListener { + + + @Resource + private AdvanceOrderService advanceOrderService; + + + @Resource + private RabbitTemplate rabbitTemplate; + + + + + @RabbitListener(bindings = @QueueBinding( + value = @Queue(MqConstant.DELAY_ADVANCE_ORDER_QUEUE), + exchange = @Exchange(name = MqConstant.DELAY_EXCHANGE, delayed = "true"), + key = MqConstant.DELAY_ADVANCE_ROUTING_KEY + )) + public void listenDelayMessage(MultiDelayMessage msg) { + System.out.println("\n\n\n\n\nAdvanceOrderStatusListener.listenerDelayMessage msg-------------------------------->:" + msg); + // 1.获取消息中的订单id + Long orderId = msg.getData(); + // 2.查询订单,判断状态是否为待支付 + AdvanceOrder advanceOrder = advanceOrderService.getById(orderId); + // 订单不存在或者订单已经支付 + if (advanceOrder == null || !advanceOrder.getOrderStatus().equals(OrderStatusConstant.PENDING_PAYMENT)) { + return ; + } + // 3.订单未支付,判断是否还有剩余延时时间 + if (msg.hasNextDelay()) { + // 有延迟时间,需要重发延迟消息,先获取延迟时间的int值 + // 发送延时消息 + int delayValue = msg.removeNextDelay().intValue(); + rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE, + MqConstant.DELAY_ADVANCE_ROUTING_KEY, msg, message -> { + // 添加延迟消息属性 + message.getMessageProperties().setDelay(delayValue); + return message; + }); + return ; + } + // 没有剩余延时时间,说明订单超时未支付,需取消订单 + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", orderId).set("orderStatus", OrderStatusConstant.TRANSACTION_CLOSED); + boolean update = advanceOrderService.update(updateWrapper); + ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "订单状态更新失败"); + + } + +} diff --git a/src/main/java/com/cultural/heritage/listener/OrderStatusListener.java b/src/main/java/com/cultural/heritage/listener/OrderStatusListener.java index 10cba14..de75fc5 100644 --- a/src/main/java/com/cultural/heritage/listener/OrderStatusListener.java +++ b/src/main/java/com/cultural/heritage/listener/OrderStatusListener.java @@ -69,7 +69,6 @@ public class OrderStatusListener { boolean update = orderService.update(updateWrapper); ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "订单状态更新失败"); - // 如果使用了优惠券,则退还优惠券 Long userCouponId = order.getCouponSnapshot().getId(); if (userCouponId != null) { diff --git a/src/main/java/com/cultural/heritage/model/dto/advanceOrder/AdvanceOrderAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/advanceOrder/AdvanceOrderAddRequest.java index 321977c..719322d 100644 --- a/src/main/java/com/cultural/heritage/model/dto/advanceOrder/AdvanceOrderAddRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/advanceOrder/AdvanceOrderAddRequest.java @@ -5,33 +5,18 @@ import lombok.Data; import java.io.Serial; import java.io.Serializable; -import java.math.BigDecimal; @Data -@Schema(description = "预约订单添加请求体", requiredProperties = {"type", "clothesType", "deposit", "contactsSnapshot", - "specificDate", "timeSlot", "isIndoors", "isMakeup", "isPhotography"}) +@Schema(description = "预约订单添加请求体", requiredProperties = {"photoProductId", "contactsId", + "specificDate", "timeSlot", "isIndoors", "isMakeup", "isPhotography", "quantity"}) public class AdvanceOrderAddRequest implements Serializable { /** - * 预约类别 + * 写真产品id */ - @Schema(description = "预约类别", example = "整套约拍") - private String type; - - - /** - * 服装类别名称 - */ - @Schema(description = "服装类别名称", example = "时尚精选") - private String clothesType; - - - /** - * 定金 - */ - @Schema(description = "定金", example = "100.00") - private BigDecimal deposit; + @Schema(description = "写真产品id", example = "3") + private Long photoProductId; /** @@ -52,7 +37,7 @@ public class AdvanceOrderAddRequest implements Serializable { * 预约时间段 */ @Schema(description = "预约时间段", example = "8:00-10:00") - private String timeSlot; + private String timePoint; /** @@ -83,6 +68,12 @@ public class AdvanceOrderAddRequest implements Serializable { private String orderStatus; + /** + * 购买数量 + */ + @Schema(description = "购买数量", example = "3") + private Integer quantity; + @Serial private static final long serialVersionUID = 1L; diff --git a/src/main/java/com/cultural/heritage/model/dto/advanceOrder/AdvanceOrderQueryRequest.java b/src/main/java/com/cultural/heritage/model/dto/advanceOrder/AdvanceOrderQueryRequest.java index 218efc8..cdf941b 100644 --- a/src/main/java/com/cultural/heritage/model/dto/advanceOrder/AdvanceOrderQueryRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/advanceOrder/AdvanceOrderQueryRequest.java @@ -22,25 +22,18 @@ public class AdvanceOrderQueryRequest extends PageRequest implements Serializabl private Long id; - /** - * 预约类别 - */ - @Schema(description = "预约类别", example = "整套约拍") - private String type; - - /** * 最小定金 */ @Schema(description = "最小定金", example = "80") - private BigDecimal minDeposit; + private BigDecimal minAmount; /** * 最大定金 */ @Schema(description = "最大定金", example = "200") - private BigDecimal maxDeposit; + private BigDecimal maxAmount; /** diff --git a/src/main/java/com/cultural/heritage/model/dto/appointment/AppointmentDateAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/appointment/AppointmentDateAddRequest.java index 72d4aaf..33c81a1 100644 --- a/src/main/java/com/cultural/heritage/model/dto/appointment/AppointmentDateAddRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/appointment/AppointmentDateAddRequest.java @@ -1,6 +1,6 @@ package com.cultural.heritage.model.dto.appointment; -import com.cultural.heritage.model.dto.timeperiod.TimePeriodAddRequest; +import com.cultural.heritage.model.dto.timePeriod.TimePeriodAddRequest; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/src/main/java/com/cultural/heritage/model/dto/appointment/AppointmentDateUpdateRequest.java b/src/main/java/com/cultural/heritage/model/dto/appointment/AppointmentDateUpdateRequest.java index 018b3ef..244a4f0 100644 --- a/src/main/java/com/cultural/heritage/model/dto/appointment/AppointmentDateUpdateRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/appointment/AppointmentDateUpdateRequest.java @@ -1,6 +1,6 @@ package com.cultural.heritage.model.dto.appointment; -import com.cultural.heritage.model.dto.timeperiod.TimePeriodUpdateRequest; +import com.cultural.heritage.model.dto.timePeriod.TimePeriodUpdateRequest; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/src/main/java/com/cultural/heritage/model/dto/appointment/single/AppointmentDateSingleAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/appointment/single/AppointmentDateSingleAddRequest.java index f05e99d..08284a6 100644 --- a/src/main/java/com/cultural/heritage/model/dto/appointment/single/AppointmentDateSingleAddRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/appointment/single/AppointmentDateSingleAddRequest.java @@ -1,6 +1,6 @@ package com.cultural.heritage.model.dto.appointment.single; -import com.cultural.heritage.model.dto.timeperiod.TimePeriodAddRequest; +import com.cultural.heritage.model.dto.timePeriod.TimePeriodAddRequest; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/src/main/java/com/cultural/heritage/model/dto/snapshot/PhotoProductsSnapshot.java b/src/main/java/com/cultural/heritage/model/dto/snapshot/PhotoProductsSnapshot.java new file mode 100644 index 0000000..790c3fd --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/dto/snapshot/PhotoProductsSnapshot.java @@ -0,0 +1,52 @@ +package com.cultural.heritage.model.dto.snapshot; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; + +@Data +@Schema(description = "写真产品更新请求体", requiredProperties = + {"id", "name", "introImg", "price", "categoryId"}) +public class PhotoProductsSnapshot implements Serializable { + + + /** + * 产品id + */ + @Schema(description = "产品id", example = "1") + private Long id; + + /** + * 产品名称 + */ + @Schema(description = "产品名称", example = "彩绣菊花纹刺绣长袍") + private String name; + + + /** + * 介绍图片 + */ + @Schema(description = "介绍图片", example = "https://www.xxx.jpg") + private String introImg; + + + /** + * 产品价格 + */ + @Schema(description = "产品价格", example = "100.00") + private BigDecimal price; + + + /** + * 写真类别名称 + */ + @Schema(description = "写真类别名称", example = "5") + private String categoryName; + + + @Serial + private static final long serialVersionUID = 1L; +} diff --git a/src/main/java/com/cultural/heritage/model/dto/timeperiod/TimePeriodAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/timePeriod/TimePeriodAddRequest.java similarity index 93% rename from src/main/java/com/cultural/heritage/model/dto/timeperiod/TimePeriodAddRequest.java rename to src/main/java/com/cultural/heritage/model/dto/timePeriod/TimePeriodAddRequest.java index c9328f1..8a3da68 100644 --- a/src/main/java/com/cultural/heritage/model/dto/timeperiod/TimePeriodAddRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/timePeriod/TimePeriodAddRequest.java @@ -1,4 +1,4 @@ -package com.cultural.heritage.model.dto.timeperiod; +package com.cultural.heritage.model.dto.timePeriod; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/src/main/java/com/cultural/heritage/model/dto/timeperiod/TimePeriodUpdateRequest.java b/src/main/java/com/cultural/heritage/model/dto/timePeriod/TimePeriodUpdateRequest.java similarity index 95% rename from src/main/java/com/cultural/heritage/model/dto/timeperiod/TimePeriodUpdateRequest.java rename to src/main/java/com/cultural/heritage/model/dto/timePeriod/TimePeriodUpdateRequest.java index 45c04a6..8417452 100644 --- a/src/main/java/com/cultural/heritage/model/dto/timeperiod/TimePeriodUpdateRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/timePeriod/TimePeriodUpdateRequest.java @@ -1,4 +1,4 @@ -package com.cultural.heritage.model.dto.timeperiod; +package com.cultural.heritage.model.dto.timePeriod; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/src/main/java/com/cultural/heritage/model/dto/timeperiod/single/TimePeriodSingleAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/timePeriod/single/TimePeriodSingleAddRequest.java similarity index 94% rename from src/main/java/com/cultural/heritage/model/dto/timeperiod/single/TimePeriodSingleAddRequest.java rename to src/main/java/com/cultural/heritage/model/dto/timePeriod/single/TimePeriodSingleAddRequest.java index 777b33d..7ddeb96 100644 --- a/src/main/java/com/cultural/heritage/model/dto/timeperiod/single/TimePeriodSingleAddRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/timePeriod/single/TimePeriodSingleAddRequest.java @@ -1,4 +1,4 @@ -package com.cultural.heritage.model.dto.timeperiod.single; +package com.cultural.heritage.model.dto.timePeriod.single; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/src/main/java/com/cultural/heritage/model/dto/timeperiod/single/TimePeriodSingleUpdateRequest.java b/src/main/java/com/cultural/heritage/model/dto/timePeriod/single/TimePeriodSingleUpdateRequest.java similarity index 93% rename from src/main/java/com/cultural/heritage/model/dto/timeperiod/single/TimePeriodSingleUpdateRequest.java rename to src/main/java/com/cultural/heritage/model/dto/timePeriod/single/TimePeriodSingleUpdateRequest.java index 93b9165..83897e1 100644 --- a/src/main/java/com/cultural/heritage/model/dto/timeperiod/single/TimePeriodSingleUpdateRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/timePeriod/single/TimePeriodSingleUpdateRequest.java @@ -1,4 +1,4 @@ -package com.cultural.heritage.model.dto.timeperiod.single; +package com.cultural.heritage.model.dto.timePeriod.single; import io.swagger.v3.oas.annotations.media.Schema; import lombok.Data; diff --git a/src/main/java/com/cultural/heritage/model/entity/AdvanceOrder.java b/src/main/java/com/cultural/heritage/model/entity/AdvanceOrder.java index 12e85cd..55a6f73 100644 --- a/src/main/java/com/cultural/heritage/model/entity/AdvanceOrder.java +++ b/src/main/java/com/cultural/heritage/model/entity/AdvanceOrder.java @@ -6,6 +6,7 @@ import com.baomidou.mybatisplus.annotation.TableId; import com.baomidou.mybatisplus.annotation.TableName; import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler; import com.cultural.heritage.model.dto.snapshot.ContactsSnapshot; +import com.cultural.heritage.model.dto.snapshot.PhotoProductsSnapshot; import lombok.Data; import java.io.Serial; @@ -29,21 +30,22 @@ public class AdvanceOrder implements Serializable { /** - * 预约类别 + * 订单号 */ - private String type; + private String orderNumber; /** - * 服装类别名称 + * 写真产品信息快照 */ - private String clothesType; + @TableField(typeHandler = JacksonTypeHandler.class) + private PhotoProductsSnapshot photoProductsSnapshot; /** * 定金 */ - private BigDecimal deposit; + private BigDecimal totalAmount; /** @@ -60,9 +62,9 @@ public class AdvanceOrder implements Serializable { /** - * 预约时间段 + * 预约时间点 */ - private String timeSlot; + private String timePoint; /** @@ -95,6 +97,12 @@ public class AdvanceOrder implements Serializable { private String orderStatus; + /** + * 购买数量 + */ + private Integer quantity; + + /** * 创建时间 */ diff --git a/src/main/java/com/cultural/heritage/model/vo/advanceorder/AdvanceOrderVO.java b/src/main/java/com/cultural/heritage/model/vo/advanceorder/AdvanceOrderVO.java index 9b16c03..06d03d9 100644 --- a/src/main/java/com/cultural/heritage/model/vo/advanceorder/AdvanceOrderVO.java +++ b/src/main/java/com/cultural/heritage/model/vo/advanceorder/AdvanceOrderVO.java @@ -1,6 +1,7 @@ package com.cultural.heritage.model.vo.advanceorder; import com.cultural.heritage.model.dto.snapshot.ContactsSnapshot; +import com.cultural.heritage.model.dto.snapshot.PhotoProductsSnapshot; import com.fasterxml.jackson.annotation.JsonFormat; import lombok.Data; @@ -19,22 +20,17 @@ public class AdvanceOrderVO implements Serializable { private Long id; - /** - * 预约类别 - */ - private String type; - /** - * 服装类别名称 + * 写真产品信息快照 */ - private String clothesType; + private PhotoProductsSnapshot photoProductsSnapshot; /** * 定金 */ - private BigDecimal deposit; + private BigDecimal totalAmount; /** @@ -50,9 +46,9 @@ public class AdvanceOrderVO implements Serializable { /** - * 预约时间段 + * 预约时间 */ - private String timeSlot; + private String timePoint; /** @@ -92,6 +88,13 @@ public class AdvanceOrderVO implements Serializable { private Date createTime; + /** + * 更新时间 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + private Date updateTime; + + @Serial private static final long serialVersionUID = 1L; diff --git a/src/main/java/com/cultural/heritage/model/vo/appointment/AppointmentDateVO.java b/src/main/java/com/cultural/heritage/model/vo/appointment/AppointmentDateVO.java index 020b3a4..844c5fe 100644 --- a/src/main/java/com/cultural/heritage/model/vo/appointment/AppointmentDateVO.java +++ b/src/main/java/com/cultural/heritage/model/vo/appointment/AppointmentDateVO.java @@ -1,6 +1,6 @@ package com.cultural.heritage.model.vo.appointment; -import com.cultural.heritage.model.vo.timeperiod.TimePeriodVO; +import com.cultural.heritage.model.vo.timePeriod.TimePeriodVO; import lombok.Data; import java.io.Serial; diff --git a/src/main/java/com/cultural/heritage/model/vo/clothesinfo/ClothesInfoLabelVO.java b/src/main/java/com/cultural/heritage/model/vo/clothesinfo/ClothesInfoLabelVO.java deleted file mode 100644 index 2985d15..0000000 --- a/src/main/java/com/cultural/heritage/model/vo/clothesinfo/ClothesInfoLabelVO.java +++ /dev/null @@ -1,45 +0,0 @@ -package com.cultural.heritage.model.vo.clothesinfo; - -import lombok.Data; - -import java.io.Serial; -import java.io.Serializable; -import java.math.BigDecimal; - -@Data -public class ClothesInfoLabelVO implements Serializable { - - /** - * 服装id - */ - private Long id; - - - /** - * 服装名称 - */ - private String name; - - - /** - * 服装图片 - */ - private String image; - - - /** - * 服装简介 - */ - private String intro; - - - /** - * 服装价格 - */ - private BigDecimal price; - - - - @Serial - private static final long serialVersionUID = 1L; -} diff --git a/src/main/java/com/cultural/heritage/model/vo/clothesgrade/PhotoCategoryVO.java b/src/main/java/com/cultural/heritage/model/vo/photoCategory/PhotoCategoryVO.java similarity index 85% rename from src/main/java/com/cultural/heritage/model/vo/clothesgrade/PhotoCategoryVO.java rename to src/main/java/com/cultural/heritage/model/vo/photoCategory/PhotoCategoryVO.java index 9d77fbe..b922abe 100644 --- a/src/main/java/com/cultural/heritage/model/vo/clothesgrade/PhotoCategoryVO.java +++ b/src/main/java/com/cultural/heritage/model/vo/photoCategory/PhotoCategoryVO.java @@ -1,4 +1,4 @@ -package com.cultural.heritage.model.vo.clothesgrade; +package com.cultural.heritage.model.vo.photoCategory; import lombok.Data; diff --git a/src/main/java/com/cultural/heritage/model/vo/clothesinfo/PhotoProductsVO.java b/src/main/java/com/cultural/heritage/model/vo/photoProducts/PhotoProductsVO.java similarity index 95% rename from src/main/java/com/cultural/heritage/model/vo/clothesinfo/PhotoProductsVO.java rename to src/main/java/com/cultural/heritage/model/vo/photoProducts/PhotoProductsVO.java index 72a3fe6..0d85925 100644 --- a/src/main/java/com/cultural/heritage/model/vo/clothesinfo/PhotoProductsVO.java +++ b/src/main/java/com/cultural/heritage/model/vo/photoProducts/PhotoProductsVO.java @@ -1,4 +1,4 @@ -package com.cultural.heritage.model.vo.clothesinfo; +package com.cultural.heritage.model.vo.photoProducts; import com.cultural.heritage.model.vo.bookingDate.BookingDateVO; import lombok.Data; diff --git a/src/main/java/com/cultural/heritage/model/vo/timeperiod/TimePeriodVO.java b/src/main/java/com/cultural/heritage/model/vo/timePeriod/TimePeriodVO.java similarity index 90% rename from src/main/java/com/cultural/heritage/model/vo/timeperiod/TimePeriodVO.java rename to src/main/java/com/cultural/heritage/model/vo/timePeriod/TimePeriodVO.java index 197af89..e28f451 100644 --- a/src/main/java/com/cultural/heritage/model/vo/timeperiod/TimePeriodVO.java +++ b/src/main/java/com/cultural/heritage/model/vo/timePeriod/TimePeriodVO.java @@ -1,4 +1,4 @@ -package com.cultural.heritage.model.vo.timeperiod; +package com.cultural.heritage.model.vo.timePeriod; import lombok.Data; diff --git a/src/main/java/com/cultural/heritage/service/book/AdvanceOrderService.java b/src/main/java/com/cultural/heritage/service/book/AdvanceOrderService.java index 7d9236f..293b83d 100644 --- a/src/main/java/com/cultural/heritage/service/book/AdvanceOrderService.java +++ b/src/main/java/com/cultural/heritage/service/book/AdvanceOrderService.java @@ -17,4 +17,16 @@ public interface AdvanceOrderService extends IService { * 获取查询条件 */ QueryWrapper getQueryWrapper(AdvanceOrderQueryRequest advanceOrderQueryRequest); + + + /** + * 向消息队列中发送订单创建的消息 + */ + void sendAdvanceOrderMessage(Long orderId); + + + /** + * 校验当前订单时间是否被预约过 + */ + void validBookingTime(String specificDate, String timePoint); } diff --git a/src/main/java/com/cultural/heritage/service/book/impl/AdvanceOrderServiceImpl.java b/src/main/java/com/cultural/heritage/service/book/impl/AdvanceOrderServiceImpl.java index c7cce69..3de8eb3 100644 --- a/src/main/java/com/cultural/heritage/service/book/impl/AdvanceOrderServiceImpl.java +++ b/src/main/java/com/cultural/heritage/service/book/impl/AdvanceOrderServiceImpl.java @@ -1,19 +1,27 @@ package com.cultural.heritage.service.book.impl; +import cn.hutool.core.date.DateTime; +import cn.hutool.core.date.DateUtil; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.cultural.heritage.common.ErrorCode; -import com.cultural.heritage.constant.BookConstant; import com.cultural.heritage.constant.CommonConstant; +import com.cultural.heritage.constant.MqConstant; +import com.cultural.heritage.constant.OrderStatusConstant; import com.cultural.heritage.exception.BusinessException; +import com.cultural.heritage.exception.ThrowUtils; import com.cultural.heritage.mapper.AdvanceOrderMapper; import com.cultural.heritage.model.dto.advanceOrder.AdvanceOrderQueryRequest; import com.cultural.heritage.model.dto.snapshot.ContactsSnapshot; +import com.cultural.heritage.model.dto.snapshot.PhotoProductsSnapshot; import com.cultural.heritage.model.entity.AdvanceOrder; import com.cultural.heritage.service.book.AdvanceOrderService; +import com.cultural.heritage.utils.MultiDelayMessage; import com.cultural.heritage.utils.SqlUtils; +import jakarta.annotation.Resource; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; +import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.stereotype.Service; import java.math.BigDecimal; @@ -22,43 +30,39 @@ import java.math.BigDecimal; public class AdvanceOrderServiceImpl extends ServiceImpl implements AdvanceOrderService { + @Resource + private RabbitTemplate rabbitTemplate; + + /** * 校验 */ @Override public void validAdvanceOrder(AdvanceOrder advanceOrder) { - String type = advanceOrder.getType(); - String clothesType = advanceOrder.getClothesType(); - BigDecimal deposit = advanceOrder.getDeposit(); + PhotoProductsSnapshot photoProductsSnapshot = advanceOrder.getPhotoProductsSnapshot(); + BigDecimal totalAmount = advanceOrder.getTotalAmount(); ContactsSnapshot contactsSnapshot = advanceOrder.getContactsSnapshot(); + String specificDate = advanceOrder.getSpecificDate(); - String timeSlot = advanceOrder.getTimeSlot(); + String timePoint = advanceOrder.getTimePoint(); Integer isIndoors = advanceOrder.getIsIndoors(); Integer isMakeup = advanceOrder.getIsMakeup(); Integer isPhotography = advanceOrder.getIsPhotography(); String orderStatus = advanceOrder.getOrderStatus(); Long userId = advanceOrder.getUserId(); - if (ObjectUtils.isEmpty(deposit) || deposit.compareTo(BigDecimal.ZERO) <= 0) { + if (ObjectUtils.isEmpty(totalAmount) || totalAmount.compareTo(BigDecimal.ZERO) <= 0) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "定金参数错误"); } - if (ObjectUtils.anyNull(contactsSnapshot, isIndoors, isMakeup, isPhotography, userId)) { + if (ObjectUtils.anyNull(contactsSnapshot, photoProductsSnapshot, isIndoors, isMakeup, isPhotography, userId)) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "存在参数为null"); } if (isIndoors != 0 && isIndoors != 1 || isMakeup != 0 && isMakeup != 1 || isPhotography != 0 && isPhotography != 1) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "布尔参数错误"); } - if (StringUtils.isAnyBlank(type, clothesType, specificDate, timeSlot, orderStatus)) { + if (StringUtils.isAnyBlank(specificDate, timePoint, orderStatus)) { throw new BusinessException(ErrorCode.PARAMS_ERROR, "存在参数为空"); } - if (!type.equals(BookConstant.RENT_CLOTHES) && !type.equals(BookConstant.OWN_CLOTHES)) { - throw new BusinessException(ErrorCode.PARAMS_ERROR, "预约类型参数错误"); - } - if (type.equals(BookConstant.RENT_CLOTHES)) { - if (isMakeup != 1 || isPhotography != 1) { - throw new BusinessException(ErrorCode.PARAMS_ERROR, "是否妆发或是否摄影参数错误"); - } - } } @@ -68,9 +72,8 @@ public class AdvanceOrderServiceImpl extends ServiceImpl getQueryWrapper(AdvanceOrderQueryRequest advanceOrderQueryRequest) { Long id = advanceOrderQueryRequest.getId(); - String type = advanceOrderQueryRequest.getType(); - BigDecimal minDeposit = advanceOrderQueryRequest.getMinDeposit(); - BigDecimal maxDeposit = advanceOrderQueryRequest.getMaxDeposit(); + BigDecimal minAmount = advanceOrderQueryRequest.getMinAmount(); + BigDecimal maxAmount = advanceOrderQueryRequest.getMaxAmount(); String startTime = advanceOrderQueryRequest.getStartTime(); String endTime = advanceOrderQueryRequest.getEndTime(); String orderStatus = advanceOrderQueryRequest.getOrderStatus(); @@ -81,9 +84,8 @@ public class AdvanceOrderServiceImpl extends ServiceImpl queryWrapper = new QueryWrapper<>(); queryWrapper.eq(id != null, "id", id); - queryWrapper.eq(StringUtils.isNotBlank(type), "type", type); - queryWrapper.ge(ObjectUtils.isNotEmpty(minDeposit), "deposit", minDeposit); - queryWrapper.le(ObjectUtils.isNotEmpty(maxDeposit), "deposit", maxDeposit); + queryWrapper.ge(ObjectUtils.isNotEmpty(minAmount), "totalAmount", minAmount); + queryWrapper.le(ObjectUtils.isNotEmpty(maxAmount), "totalAmount", maxAmount); queryWrapper.between(StringUtils.isNotBlank(startTime) && StringUtils.isNotBlank(endTime), "specificDate", startTime, endTime); queryWrapper.between(StringUtils.isNotBlank(createLeftTime) && StringUtils.isNotBlank(createRightTime), "createTime", createLeftTime, createRightTime); queryWrapper.eq(StringUtils.isNotBlank(orderStatus), "orderStatus", orderStatus); @@ -91,4 +93,45 @@ public class AdvanceOrderServiceImpl extends ServiceImpl msg = new MultiDelayMessage<>(orderId, + 10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L, 60000L, 60000L, 120000L, 300000L, 600000L, 600000L); + // 10000L, 10000L, 10000L, 15000L, 15000L, 30000L, 30000L, 60000L, 60000L, 120000L, 300000L, 600000L, 600000L + int delayValue = msg.removeNextDelay().intValue(); + rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE, + MqConstant.DELAY_ADVANCE_ROUTING_KEY, msg, message -> { + // 添加延迟消息属性 + message.getMessageProperties().setDelay(delayValue); + return message; + }); + } + + + + /** + * 校验当前订单时间是否被预约过 + */ + @Override + public void validBookingTime(String specificDate, String timePoint) { + String time = timePoint + ":00"; + DateTime targetTime = DateUtil.parse(time, "HH:mm:ss"); + DateTime now = DateUtil.date(); + DateTime currentTime = DateUtil.parse(now.toString("HH:mm:ss"), "HH:mm:ss"); + int result = currentTime.compareTo(targetTime); + ThrowUtils.throwIf(result >= 0, ErrorCode.OPERATION_ERROR, "当前预约时间已过期"); + + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("specificDate", specificDate); + queryWrapper.eq("timePoint", timePoint); + queryWrapper.eq("orderStatus", OrderStatusConstant.PENDING_CONSUME); + AdvanceOrder order = this.getOne(queryWrapper); + ThrowUtils.throwIf(order != null, ErrorCode.OPERATION_ERROR, "当前时间已约满"); + } } diff --git a/src/main/java/com/cultural/heritage/service/wx/WeChatService.java b/src/main/java/com/cultural/heritage/service/wx/WeChatService.java index 165847f..8fb6f28 100644 --- a/src/main/java/com/cultural/heritage/service/wx/WeChatService.java +++ b/src/main/java/com/cultural/heritage/service/wx/WeChatService.java @@ -16,25 +16,40 @@ import java.math.BigDecimal; public interface WeChatService { /** - * 微信支付 + * 微信支付(商品类) */ PrepayWithRequestPaymentResponse createPayment(String orderId, String miniOpenId, BigDecimal amount); + /** + * 微信支付(写真预约类) + */ + PrepayWithRequestPaymentResponse createPhotoProductsPayment(String orderId, String miniOpenId, BigDecimal amount); + /** * 获取支付回调信息 */ Transaction getTransactionInfo(HttpServletRequest request); /** - * 支付回调 + * 支付回调(商品类) */ boolean paymentCallback(Transaction transaction) throws IOException; /** - * 全额退款申请 + * 支付回调(写真预约类) + */ + boolean paymentPhotoProductsCallback(Transaction transaction) throws IOException; + + /** + * 全额退款申请(商品类) */ Refund refundPayment(String orderId, BigDecimal amount); + /** + * 全额退款申请(写真预约类) + */ + Refund refundPhotoProductsPayment(String orderId, BigDecimal amount); + /** * 部分退款申请 */ @@ -51,10 +66,15 @@ public interface WeChatService { RefundNotification getRefundInfo(HttpServletRequest request); /** - * 退款回调 + * 退款回调(商品类) */ boolean refundCallback(RefundNotification refundNotification); + /** + * (写真预约类) + */ + boolean refundPhotoProductsCallback(RefundNotification refundNotification); + /** * 部分退款回调 */ @@ -66,6 +86,7 @@ public interface WeChatService { */ boolean refundRestCallback(RefundNotification refundNotification); + // /** // * 发送订阅模板消息 // */ diff --git a/src/main/java/com/cultural/heritage/service/wx/impl/WeChatServiceImpl.java b/src/main/java/com/cultural/heritage/service/wx/impl/WeChatServiceImpl.java index 6212641..310df9e 100644 --- a/src/main/java/com/cultural/heritage/service/wx/impl/WeChatServiceImpl.java +++ b/src/main/java/com/cultural/heritage/service/wx/impl/WeChatServiceImpl.java @@ -13,10 +13,12 @@ import com.cultural.heritage.exception.ThrowUtils; import com.cultural.heritage.model.dto.snapshot.CouponSnapshot; import com.cultural.heritage.model.dto.snapshot.GoodSnapshot; import com.cultural.heritage.model.entity.*; -import com.cultural.heritage.service.common.CommonService; -import com.cultural.heritage.service.good.AppointmentDateService; +import com.cultural.heritage.service.book.AdvanceOrderService; import com.cultural.heritage.service.good.GoodService; -import com.cultural.heritage.service.order.*; +import com.cultural.heritage.service.order.OrderItemService; +import com.cultural.heritage.service.order.OrderService; +import com.cultural.heritage.service.order.PendingServiceOrderService; +import com.cultural.heritage.service.order.RefundRecordService; import com.cultural.heritage.service.wx.WeChatService; import com.cultural.heritage.utils.RefundUtils; import com.wechat.pay.java.core.notification.NotificationParser; @@ -70,17 +72,11 @@ public class WeChatServiceImpl implements WeChatService { @Resource private RefundRecordService refundRecordService; - @Resource - private AppointmentDateService appointmentDateService; - - @Resource - private PendingServiceGoodService pendingServiceGoodService; - @Resource private PendingServiceOrderService pendingServiceOrderService; @Resource - private CommonService commonService; + private AdvanceOrderService advanceOrderService; /** @@ -90,7 +86,7 @@ public class WeChatServiceImpl implements WeChatService { /** - * 微信支付 + * 微信支付(商品类) */ @Override @Transactional(rollbackFor = Exception.class) @@ -124,10 +120,42 @@ public class WeChatServiceImpl implements WeChatService { } + /** + * 微信支付(写真预约类) + */ + @Override + public PrepayWithRequestPaymentResponse createPhotoProductsPayment(String orderId, String miniOpenId, BigDecimal amount) { + // request.setXxx(val)设置所需参数,具体参数可见Request定义 + PrepayRequest request = new PrepayRequest(); + // 金额 + Amount WxAmount = new Amount(); + WxAmount.setTotal(amount.movePointRight(2).intValue()); + WxAmount.setCurrency("CNY"); + request.setAmount(WxAmount); + // 公众号id + request.setAppid(wxPayConfig.getAppId()); + // 商户号 + request.setMchid(wxPayConfig.getMerchantId()); + // 支付者信息 + Payer payer = new Payer(); + payer.setOpenid(miniOpenId); + request.setPayer(payer); + // 获取订单号 + AdvanceOrder advanceOrder = advanceOrderService.getById(orderId); + String orderNumber = advanceOrder.getOrderNumber(); + // 描述 + request.setDescription("订单号:" + orderNumber); + // 微信回调地址 + request.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/payment/photo/callback"); + // 商户订单号 + request.setOutTradeNo(orderNumber); + //返回数据,前端调起支付 + return wxPayConfig.getJsapiServiceExtension().prepayWithRequestPayment(request); + } /** - * 支付回调 + * 支付回调(商品类) */ @Override @Transactional(rollbackFor = Exception.class) @@ -152,10 +180,26 @@ public class WeChatServiceImpl implements WeChatService { } + /** + * 支付回调(写真预约类) + */ + @Override + public boolean paymentPhotoProductsCallback(Transaction transaction) { + System.out.println("---------------------------微信支付回调(开始)-------------------------------"); + // 获取订单信息 + String orderNumber = transaction.getOutTradeNo(); + AdvanceOrder advanceOrder = getAdvanceOrderInfoByOrderNumber(orderNumber); + + // 修改订单状态 + modifyAdvanceOrderStatus(advanceOrder, OrderStatusConstant.PENDING_CONSUME); + System.out.println("---------------------------微信支付回调(结束)-------------------------------"); + return true; + } + /** - * 全额退款 + * 全额退款(商品类) */ @Override public Refund refundPayment(String orderId, BigDecimal amount) { @@ -190,10 +234,43 @@ public class WeChatServiceImpl implements WeChatService { + /** + * 全额退款(写真预约类) + */ + @Override + public Refund refundPhotoProductsPayment(String orderId, BigDecimal amount) { + // 获取订单号 + AdvanceOrder advanceOrder = advanceOrderService.getById(orderId); + ThrowUtils.throwIf(advanceOrder == null, ErrorCode.OPERATION_ERROR, "该订单不存在"); + String orderNumber = advanceOrder.getOrderNumber(); + // 退款请求 + CreateRequest createRequest = new CreateRequest(); + // 商户订单号 + createRequest.setOutTradeNo(orderNumber); + // 商户退款单号 + String outRefundNo = RefundUtils.generateRefundNo(); + createRequest.setOutRefundNo(outRefundNo); + // 退款结果回调 + createRequest.setNotifyUrl(wxPayConfig.getNotifyUrl() + "/api/wechat/refund/photo/callback"); + // 退款金额 + AmountReq amountReq = new AmountReq(); + long refundAmount = amount.movePointRight(2).intValue(); + + amountReq.setRefund(refundAmount); + amountReq.setTotal(refundAmount); + amountReq.setCurrency("CNY"); + createRequest.setAmount(amountReq); + // 申请退款 + System.out.println("退款请求:" + createRequest); + Refund refund = wxPayConfig.getRefundService().create(createRequest); + System.out.println("退款申请结果:" + refund); + return refund; + } + /** - * 全额退款回调 + * 全额退款回调(商品类) */ @Override @Transactional(rollbackFor = Exception.class) @@ -224,6 +301,28 @@ public class WeChatServiceImpl implements WeChatService { + /** + * 全额退款回调(写真预约类) + */ + @Override + public boolean refundPhotoProductsCallback(RefundNotification refundNotification) { + System.out.println("---------------------------微信退款回调(开始)-------------------------------"); + // 获取订单信息 + String orderNumber = refundNotification.getOutTradeNo(); + AdvanceOrder advanceOrder = getAdvanceOrderInfoByOrderNumber(orderNumber); + + // 修改订单状态 + modifyAdvanceOrderStatus(advanceOrder, OrderStatusConstant.PAYMENT_REFUNDED); + + // 生成退款记录 + createRefundRecord(refundNotification); + System.out.println("---------------------------微信退款回调(结束)-------------------------------"); + return true; + } + + + + /** * 部分退款 */ @@ -518,6 +617,16 @@ public class WeChatServiceImpl implements WeChatService { } + /** + * 根据订单号获取写真预约类信息 + */ + private AdvanceOrder getAdvanceOrderInfoByOrderNumber(String orderNumber) { + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("orderNumber", orderNumber); + AdvanceOrder advanceOrder = advanceOrderService.getOne(queryWrapper); + ThrowUtils.throwIf(advanceOrder == null, ErrorCode.OPERATION_ERROR, "订单不存在"); + return advanceOrder; + } @@ -565,6 +674,16 @@ public class WeChatServiceImpl implements WeChatService { } + /** + * 修改写真预约订单状态 + */ + private void modifyAdvanceOrderStatus(AdvanceOrder advanceOrder, String orderStatus) { + advanceOrder.setOrderStatus(orderStatus); + advanceOrder.setUpdateTime(DateUtil.date()); + boolean update = advanceOrderService.updateById(advanceOrder); + ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "订单状态修改失败"); + } + /**