更新了写真预约模块

This commit is contained in:
chen-xin-zhi 2025-02-16 10:08:02 +08:00
parent 34c887e363
commit 2b271e7882
32 changed files with 614 additions and 202 deletions

View File

@ -1,11 +0,0 @@
package com.cultural.heritage.constant;
public interface BookConstant {
String RENT_CLOTHES = "整套约拍";
String OWN_CLOTHES = "自带服装";
}

View File

@ -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";
}

View File

@ -21,6 +21,7 @@ public interface OrderStatusConstant {
String PAYMENT_REFUNDED = "已退款";
String PENDING_CONSUME = "待消费";
}

View File

@ -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<PhotoProducts> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("categoryName", photoCategory.getName());
List<PhotoProducts> photoProductsList = photoProductsService.list(queryWrapper);
// 获取预约日期列表
List<BookingDate> bookingDateList = commonService.getItemsByIds(photoProductsList, bookingDateService, PhotoProducts::getId);
// 获取预约时间列表
List<BookingTime> 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, "写真产品批量删除失败");

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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<Boolean> addAdvanceOrder(@RequestBody AdvanceOrderAddRequest addAdvanceOrderRequest, HttpServletRequest request) {
public BaseResponse<Long> 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<Boolean> 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<Boolean> 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<AdvanceOrder> 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);
}

View File

@ -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<PrepayWithRequestPaymentResponse> 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<Boolean> 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<PrepayWithRequestPaymentResponse> 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<Boolean> 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<Refund> 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<Refund> 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<Boolean> 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<Boolean> callbackPhotoProductsRefund(HttpServletRequest request) {
// 获取退款信息
RefundNotification refundNotification = weChatService.getRefundInfo(request);
// 退款回调
boolean result = weChatService.refundPhotoProductsCallback(refundNotification);
ThrowUtils.throwIf(!result, ErrorCode.SYSTEM_ERROR, "退款回调失败");
return ResultUtils.success(true);
}
/**
* 部分退款回调

View File

@ -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<Long> 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<AdvanceOrder> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", orderId).set("orderStatus", OrderStatusConstant.TRANSACTION_CLOSED);
boolean update = advanceOrderService.update(updateWrapper);
ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "订单状态更新失败");
}
}

View File

@ -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) {

View File

@ -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;

View File

@ -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;
/**

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;
/**
* 创建时间
*/

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -1,4 +1,4 @@
package com.cultural.heritage.model.vo.clothesgrade;
package com.cultural.heritage.model.vo.photoCategory;
import lombok.Data;

View File

@ -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;

View File

@ -1,4 +1,4 @@
package com.cultural.heritage.model.vo.timeperiod;
package com.cultural.heritage.model.vo.timePeriod;
import lombok.Data;

View File

@ -17,4 +17,16 @@ public interface AdvanceOrderService extends IService<AdvanceOrder> {
* 获取查询条件
*/
QueryWrapper<AdvanceOrder> getQueryWrapper(AdvanceOrderQueryRequest advanceOrderQueryRequest);
/**
* 向消息队列中发送订单创建的消息
*/
void sendAdvanceOrderMessage(Long orderId);
/**
* 校验当前订单时间是否被预约过
*/
void validBookingTime(String specificDate, String timePoint);
}

View File

@ -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<AdvanceOrderMapper, AdvanceOrder> 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<AdvanceOrderMapper, Adv
@Override
public QueryWrapper<AdvanceOrder> 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<AdvanceOrderMapper, Adv
QueryWrapper<AdvanceOrder> 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<AdvanceOrderMapper, Adv
sortField);
return queryWrapper;
}
/**
* 向消息队列中发送订单创建的消息
*/
@Override
public void sendAdvanceOrderMessage(Long orderId) {
// 延迟检查订单状态信息
MultiDelayMessage<Long> 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<AdvanceOrder> 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, "当前时间已约满");
}
}

View File

@ -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);
// /**
// * 发送订阅模板消息
// */

View File

@ -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<AdvanceOrder> 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, "订单状态修改失败");
}
/**