diff --git a/src/main/java/com/cultural/heritage/constant/MqConstant.java b/src/main/java/com/cultural/heritage/constant/MqConstant.java index dd66fdb..d2b0141 100644 --- a/src/main/java/com/cultural/heritage/constant/MqConstant.java +++ b/src/main/java/com/cultural/heritage/constant/MqConstant.java @@ -26,4 +26,8 @@ public interface MqConstant { String DELAY_ADVANCE_ROUTING_KEY = "advanceOrder.key"; + String DELAY_CLOTHES_RENT_ORDER_QUEUE = "clothesRentOrder.delay.queue"; + + String DELAY_CLOTHES_RENT_ORDER_ROUTING_KEY = "clothesRentOrder.delay.queue"; + } diff --git a/src/main/java/com/cultural/heritage/controller/order/ClothesOrderController.java b/src/main/java/com/cultural/heritage/controller/order/ClothesOrderController.java deleted file mode 100644 index df0411c..0000000 --- a/src/main/java/com/cultural/heritage/controller/order/ClothesOrderController.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.cultural.heritage.controller.order; - -public class ClothesOrderController { -} diff --git a/src/main/java/com/cultural/heritage/controller/order/ClothesRentOrderController.java b/src/main/java/com/cultural/heritage/controller/order/ClothesRentOrderController.java new file mode 100644 index 0000000..d7aa647 --- /dev/null +++ b/src/main/java/com/cultural/heritage/controller/order/ClothesRentOrderController.java @@ -0,0 +1,274 @@ +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; +import com.cultural.heritage.common.ErrorCode; +import com.cultural.heritage.common.ResultUtils; +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.clothesRentOrder.ClothesRentOrderAddRequest; +import com.cultural.heritage.model.dto.clothesRentOrder.ClothesRentOrderQueryRequest; +import com.cultural.heritage.model.dto.order.OrderStatusUpdateRequest; +import com.cultural.heritage.model.dto.snapshot.ClothesSnapshot; +import com.cultural.heritage.model.dto.snapshot.ContactsSnapshot; +import com.cultural.heritage.model.entity.*; +import com.cultural.heritage.model.vo.clothesRentOrder.ClothesRentOrderVO; +import com.cultural.heritage.service.address.ContactsService; +import com.cultural.heritage.service.clothes.ClothesService; +import com.cultural.heritage.service.common.CommonService; +import com.cultural.heritage.service.order.ClothesRentOrderService; +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; +import jakarta.servlet.http.HttpServletRequest; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; +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.math.BigDecimal; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +@RestController +@RequestMapping("/clothesRent") +@Slf4j +@Tag(name = "服装租赁订单管理模块") +public class ClothesRentOrderController { + + + + @Resource + private ClothesRentOrderService clothesRentOrderService; + + + @Resource + private ClothesService clothesService; + + + @Resource + private UserService userService; + + + @Resource + private ContactsService contactsService; + + + @Resource + private CommonService commonService; + + + + /** + * 小程序端用户创建服装租赁订单 + * @param clothesRentOrderAddRequest 服装租赁订单添加请求体 + * @return 订单id + */ + @PostMapping("/add") + @Operation(summary = "小程序端用户创建服装租赁订单", description = "参数:服装租赁订单添加请求体, 权限:所有人,方法名:addClothesRentOrder") + public BaseResponse addClothesRentOrder(@RequestBody ClothesRentOrderAddRequest clothesRentOrderAddRequest, HttpServletRequest request) { + if (clothesRentOrderAddRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + // 获取用户id + User loginUser = userService.getLoginUser(request); + Long userId = loginUser.getId(); + clothesRentOrderService.validClothesRentOrder(clothesRentOrderAddRequest); + // 获取服装信息 + Long clothesId = clothesRentOrderAddRequest.getClothesId(); + Clothes clothes = clothesService.getById(clothesId); + ThrowUtils.throwIf(clothes == null || clothes.getIsShelves() == 0, ErrorCode.OPERATION_ERROR, "服装已被下架或者不存在"); + ClothesSnapshot clothesSnapshot = commonService.copyProperties(clothes, ClothesSnapshot.class); + // 获取联系人信息 + Long contactsId = clothesRentOrderAddRequest.getContactsId(); + Contacts contacts = contactsService.getById(contactsId); + ThrowUtils.throwIf( contacts == null, ErrorCode.OPERATION_ERROR, "联系人信息不存在"); + ContactsSnapshot contactsSnapshot = commonService.copyProperties(contacts, ContactsSnapshot.class); + // 校验租赁天数 + Integer rentDays = clothesRentOrderAddRequest.getRentDays(); + ThrowUtils.throwIf(rentDays > clothes.getPeriod(), ErrorCode.OPERATION_ERROR, "超出当前服装的最大租赁天数"); + // 计算订单总金额 + BigDecimal price = clothes.getPrice(); + BigDecimal totalAmount = price.multiply(BigDecimal.valueOf(rentDays)); + // 生成订单号 + String orderNumber = OrderNumberUtils.generateOrderId(); + // 封装成服装租赁订单 + ClothesRentOrder clothesRentOrder = new ClothesRentOrder(); + clothesRentOrder.setUserId(userId); + clothesRentOrder.setOrderNumber(orderNumber); + clothesRentOrder.setOrderStatus(OrderStatusConstant.PENDING_PAYMENT); + clothesRentOrder.setClothesSnapshot(clothesSnapshot); + clothesRentOrder.setContactsSnapshot(contactsSnapshot); + clothesRentOrder.setRentDays(rentDays); + clothesRentOrder.setTotalAmount(totalAmount); + + boolean save = clothesRentOrderService.save(clothesRentOrder); + ThrowUtils.throwIf(!save, ErrorCode.OPERATION_ERROR, "订单创建失败"); + clothesRentOrderService.sendClothesRentOrderMessage(clothesRentOrder.getId()); + + return ResultUtils.success(clothesRentOrder.getId()); + + } + + + + + + /** + * 小程序端用户取消服装租赁订单 + * @param commonRequest 订单id + * @return 是否取消成功 + */ + @PostMapping ("/cancel/id") + @Operation(summary = "小程序端用户取消服装租赁订单", description = "参数:订单id,权限:所有人,方法名:cancelClothesRentOrderById") + public BaseResponse cancelClothesRentOrderById(@RequestBody CommonRequest commonRequest, HttpServletRequest request) { + if (commonRequest == null || commonRequest.getId() <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + Long id = commonRequest.getId(); + userService.getLoginUser(request); + ClothesRentOrder clothesRentOrder = clothesRentOrderService.getById(id); + ThrowUtils.throwIf(clothesRentOrder == null, ErrorCode.OPERATION_ERROR, "订单不存在"); + ThrowUtils.throwIf(!clothesRentOrder.getOrderStatus().equals(OrderStatusConstant.PENDING_PAYMENT), ErrorCode.SYSTEM_ERROR, "订单状态错误"); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", id).set("orderStatus", OrderStatusConstant.TRANSACTION_CLOSED); + boolean update = clothesRentOrderService.update(updateWrapper); + ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "订单状态更新失败"); + return ResultUtils.success(true); + } + + + + + + + + /** + * Web端管理员分页查询服装租赁订单 + * @param clothesRentOrderQueryRequest 服装租赁订单查询请求体 + * @return 服装租赁订单列表 + */ + @PostMapping("/list") + @Operation(summary = "Web端管理员分页查询写真预约订单", description = "参数:服装租赁订单查询请求体, 权限:管理员(admin, boss),方法名:listClothesRentOrderByPage") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public BaseResponse> listClothesRentOrderByPage(@RequestBody ClothesRentOrderQueryRequest clothesRentOrderQueryRequest) { + if (clothesRentOrderQueryRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + long current = clothesRentOrderQueryRequest.getCurrent(); + long pageSize = clothesRentOrderQueryRequest.getPageSize(); + QueryWrapper queryWrapper = clothesRentOrderService.getQueryWrapper(clothesRentOrderQueryRequest); + Page page = clothesRentOrderService.page(new Page<>(current, pageSize), queryWrapper); + // 封装成服装租赁订单VO + List clothesRentOrderList = page.getRecords(); + List clothesRentOrderVOS = commonService.convertList(clothesRentOrderList, ClothesRentOrderVO.class); + // 填充userName + List userList = commonService.findByFieldInTargetField(clothesRentOrderVOS, userService, ClothesRentOrderVO::getUserId, "id"); + Map map = new HashMap<>(); + for (User user : userList) { + map.put(user.getId(), user.getUserName()); + } + for (ClothesRentOrderVO clothesRentOrderVO : clothesRentOrderVOS) { + Long userId = clothesRentOrderVO.getUserId(); + String userName = map.get(userId); + clothesRentOrderVO.setUserName(userName); + } + Page voPage = new Page<>(); + voPage.setRecords(clothesRentOrderVOS); + voPage.setTotal(page.getTotal()); + voPage.setPages(page.getSize()); + voPage.setCurrent(page.getCurrent()); + voPage.setSize(page.getSize()); + return ResultUtils.success(voPage); + } + + + + + /** + * 小程序端用户查询服装租赁订单 + * @return 当前用户的订单列表 + */ + @PostMapping("/list/my") + @Operation(summary = "小程序端用户查询服装租赁订单", description = "参数:无, 权限:所有人,方法名:listMyClothesRentOrder") + public BaseResponse> listMyClothesRentOrder(HttpServletRequest request) { + User loginUser = userService.getLoginUser(request); + Long userId = loginUser.getId(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq("userId", userId); + List clothesRentOrderList = clothesRentOrderService.list(queryWrapper); + // 封装成写真预约订单VO + List clothesRentOrderVOS = commonService.convertList(clothesRentOrderList, ClothesRentOrderVO.class); + for (ClothesRentOrderVO clothesRentOrderVO : clothesRentOrderVOS) { + clothesRentOrderVO.setUserId(userId); + } + Collections.reverse(clothesRentOrderVOS); + return ResultUtils.success(clothesRentOrderVOS); + } + + + + + + /** + * 小程序端用户根据id删除服装租赁订单 + * @return 是否删除成功 + */ + @PostMapping("/delete") + @Operation(summary = "小程序端用户根据id删除服装租赁订单", description = "参数:无, 权限:所有人,方法名:delClothesRentOrderById") + public BaseResponse delClothesRentOrderById(@RequestBody CommonRequest commonRequest, HttpServletRequest request) { + if (commonRequest == null) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + userService.getLoginUser(request); + Long id = commonRequest.getId(); + ClothesRentOrder clothesRentOrder = clothesRentOrderService.getById(id); + ThrowUtils.throwIf(clothesRentOrder == null || !clothesRentOrder.getOrderStatus().equals(OrderStatusConstant.TRANSACTION_CLOSED), ErrorCode.OPERATION_ERROR, "订单不存在或状态错误"); + boolean result = clothesRentOrderService.removeById(id); + ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "订单删除失败"); + return ResultUtils.success(true); + } + + + + + + /** + * Web端管理员更新服装租赁订单状态 + * @param orderStatusUpdateRequest 订单状态更新请求体 + * @return 是否更新成功 + */ + @PostMapping("/update/orderStatus") + @Operation(summary = "Web端管理员更新服装租赁订单状态", description = "参数:订单状态更新请求体,权限:管理员(admin, boss),方法名:updateClothesRentOrderStatus") + @AuthCheck(mustRole = UserConstant.ADMIN_ROLE) + public BaseResponse updateClothesRentOrderStatus(@RequestBody OrderStatusUpdateRequest orderStatusUpdateRequest) { + if (orderStatusUpdateRequest == null || orderStatusUpdateRequest.getId() <= 0) { + throw new BusinessException(ErrorCode.PARAMS_ERROR); + } + Long id = orderStatusUpdateRequest.getId(); + String orderStatus = orderStatusUpdateRequest.getOrderStatus(); + ThrowUtils.throwIf(StringUtils.isBlank(orderStatus), ErrorCode.OPERATION_ERROR, "订单状态参数为空"); + UpdateWrapper updateWrapper = new UpdateWrapper<>(); + updateWrapper.eq("id", id); + updateWrapper.set("orderStatus", orderStatus); + boolean result = clothesRentOrderService.update(updateWrapper); + ThrowUtils.throwIf(!result, ErrorCode.OPERATION_ERROR, "订单状态不存在或订单状态更新失败"); + return ResultUtils.success(true); + } + + + +} diff --git a/src/main/java/com/cultural/heritage/listener/ClothesRentOrderStatusListener.java b/src/main/java/com/cultural/heritage/listener/ClothesRentOrderStatusListener.java new file mode 100644 index 0000000..f8ae17e --- /dev/null +++ b/src/main/java/com/cultural/heritage/listener/ClothesRentOrderStatusListener.java @@ -0,0 +1,69 @@ +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.ClothesRentOrder; +import com.cultural.heritage.service.order.ClothesRentOrderService; +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 ClothesRentOrderStatusListener { + + + @Resource + private ClothesRentOrderService clothesRentOrderService; + + + @Resource + private RabbitTemplate rabbitTemplate; + + + + @RabbitListener(bindings = @QueueBinding( + value = @Queue(MqConstant.DELAY_CLOTHES_RENT_ORDER_QUEUE), + exchange = @Exchange(name = MqConstant.DELAY_EXCHANGE, delayed = "true"), + key = MqConstant.DELAY_CLOTHES_RENT_ORDER_ROUTING_KEY + )) + public void listenDelayMessage(MultiDelayMessage msg) { + System.out.println("\n\n\n\n\nClothesRentOrderStatusListener.listenerDelayMessage msg-------------------------------->:" + msg); + // 1.获取消息中的订单id + Long orderId = msg.getData(); + // 2.查询订单,判断状态是否为待支付 + ClothesRentOrder clothesRentOrder = clothesRentOrderService.getById(orderId); + // 订单不存在或者订单已经支付 + if (clothesRentOrder == null || !clothesRentOrder.getOrderStatus().equals(OrderStatusConstant.PENDING_PAYMENT)) { + return ; + } + // 3.订单未支付,判断是否还有剩余延时时间 + if (msg.hasNextDelay()) { + // 有延迟时间,需要重发延迟消息,先获取延迟时间的int值 + // 发送延时消息 + int delayValue = msg.removeNextDelay().intValue(); + rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE, + MqConstant.DELAY_CLOTHES_RENT_ORDER_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 = clothesRentOrderService.update(updateWrapper); + ThrowUtils.throwIf(!update, ErrorCode.OPERATION_ERROR, "订单状态更新失败"); + + } + +} diff --git a/src/main/java/com/cultural/heritage/mapper/ClothesOrderMapper.java b/src/main/java/com/cultural/heritage/mapper/ClothesOrderMapper.java deleted file mode 100644 index 1a14af9..0000000 --- a/src/main/java/com/cultural/heritage/mapper/ClothesOrderMapper.java +++ /dev/null @@ -1,7 +0,0 @@ -package com.cultural.heritage.mapper; - -import com.baomidou.mybatisplus.core.mapper.BaseMapper; -import com.cultural.heritage.model.entity.ClothesOrder; - -public interface ClothesOrderMapper extends BaseMapper { -} diff --git a/src/main/java/com/cultural/heritage/mapper/ClothesRentOrderMapper.java b/src/main/java/com/cultural/heritage/mapper/ClothesRentOrderMapper.java new file mode 100644 index 0000000..d5f6eba --- /dev/null +++ b/src/main/java/com/cultural/heritage/mapper/ClothesRentOrderMapper.java @@ -0,0 +1,7 @@ +package com.cultural.heritage.mapper; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.cultural.heritage.model.entity.ClothesRentOrder; + +public interface ClothesRentOrderMapper extends BaseMapper { +} diff --git a/src/main/java/com/cultural/heritage/model/dto/clothesRentOrder/ClothesRentOrderAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/clothesRentOrder/ClothesRentOrderAddRequest.java new file mode 100644 index 0000000..b4c993a --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/dto/clothesRentOrder/ClothesRentOrderAddRequest.java @@ -0,0 +1,39 @@ +package com.cultural.heritage.model.dto.clothesRentOrder; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; + +@Data +@Schema(description = "服装租赁订单添加请求体", requiredProperties = {"clothesId", "contactsId", "rentDays"}) +public class ClothesRentOrderAddRequest implements Serializable { + + + /** + * 服装id + */ + @Schema(description = "服装id(id > 0)", example = "2") + private Long clothesId; + + + /** + * 联系人id + */ + @Schema(description = "联系人id(id > 0)", example = "3") + private Long contactsId; + + + /** + * 租赁天数 + */ + @Schema(description = "rentDays", example = "10") + private Integer rentDays; + + + + @Serial + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/com/cultural/heritage/model/dto/clothesRentOrder/ClothesRentOrderQueryRequest.java b/src/main/java/com/cultural/heritage/model/dto/clothesRentOrder/ClothesRentOrderQueryRequest.java new file mode 100644 index 0000000..e555591 --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/dto/clothesRentOrder/ClothesRentOrderQueryRequest.java @@ -0,0 +1,47 @@ +package com.cultural.heritage.model.dto.clothesRentOrder; + +import com.cultural.heritage.common.PageRequest; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; + +import java.io.Serial; +import java.io.Serializable; + +@EqualsAndHashCode(callSuper = true) +@Data +@Schema(description = "服装租赁订单查询请求体", requiredProperties = {"clothesId", "contactsId", "rentDays"}) +public class ClothesRentOrderQueryRequest extends PageRequest implements Serializable { + + + /** + * 订单号 + */ + @Schema(description = "订单号(id > 0)", example = "2432432432342") + private String orderNumber; + + + /** + * 订单状态 + */ + @Schema(description = "订单状态", example = "待支付") + private String orderStatus; + + + /** + * 联系人姓名 + */ + @Schema(description = "联系人姓名", example = "10") + private String name; + + + /** + * 联系人手机号 + */ + @Schema(description = "联系人手机号", example = "15888610253") + private String phone; + + + @Serial + private static final long serialVersionUID = 1L; +} diff --git a/src/main/java/com/cultural/heritage/model/dto/order/OrderAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/order/OrderAddRequest.java index 0e47816..e8dbb40 100644 --- a/src/main/java/com/cultural/heritage/model/dto/order/OrderAddRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/order/OrderAddRequest.java @@ -12,7 +12,7 @@ import java.math.BigDecimal; import java.util.List; @Data -@Schema(description = "订单添加请求体", requiredProperties = {"userId", "addressSnapshot", "contactsSnapshot", +@Schema(description = "订单添加请求体", requiredProperties = {"userName", "addressSnapshot", "contactsSnapshot", "couponSnapshot", "totalAmount", "orderStatus", "orderItemList"}) public class OrderAddRequest implements Serializable { @@ -67,6 +67,7 @@ public class OrderAddRequest implements Serializable { /** * 订单备注 */ + @Schema(description = "订单备注") private String note; /** diff --git a/src/main/java/com/cultural/heritage/model/dto/order/capital/OrderMainInfoAddRequest.java b/src/main/java/com/cultural/heritage/model/dto/order/capital/OrderMainInfoAddRequest.java index 865f214..5a2d4ee 100644 --- a/src/main/java/com/cultural/heritage/model/dto/order/capital/OrderMainInfoAddRequest.java +++ b/src/main/java/com/cultural/heritage/model/dto/order/capital/OrderMainInfoAddRequest.java @@ -9,7 +9,7 @@ import java.math.BigDecimal; import java.util.List; @Data -@Schema(description = "订单主要信息请求体", requiredProperties = {"userId", "userName", "orderNumber", "addressId", "contactsId", +@Schema(description = "订单主要信息请求体", requiredProperties = {"userName", "addressId", "contactsId", "couponId", "totalAmount", "orderStatus", "note", "orderItemMainInfoAddRequestList"}) public class OrderMainInfoAddRequest implements Serializable { diff --git a/src/main/java/com/cultural/heritage/model/dto/snapshot/ClothesSnapshot.java b/src/main/java/com/cultural/heritage/model/dto/snapshot/ClothesSnapshot.java new file mode 100644 index 0000000..9654739 --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/dto/snapshot/ClothesSnapshot.java @@ -0,0 +1,58 @@ +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", "categoryId", "price", "period", "image"}) +public class ClothesSnapshot implements Serializable { + + + /** + * 编号 + */ + @Schema(description = "服装编号", example = "1") + private Long id; + + /** + * 服装名称 + */ + @Schema(description = "服装名称", example = "夏季连衣裙") + private String name; + + /** + * 类别id + */ + @Schema(description = "服装类别ID", example = "2") + private Long categoryId; + + /** + * 价格/天 + */ + @Schema(description = "租赁价格(每一天)", example = "100.00") + private BigDecimal price; + + /** + * 最大租赁天数 + */ + @Schema(description = "最大租赁天数", example = "7") + private Integer period; + + /** + * 服装图片 + */ + @Schema(description = "服装图片URL", example = "http://example.com/images/dress.jpg") + private String image; + + + @Serial + private static final long serialVersionUID = 1L; + +} diff --git a/src/main/java/com/cultural/heritage/model/entity/ClothesOrder.java b/src/main/java/com/cultural/heritage/model/entity/ClothesOrder.java deleted file mode 100644 index 5e79516..0000000 --- a/src/main/java/com/cultural/heritage/model/entity/ClothesOrder.java +++ /dev/null @@ -1,4 +0,0 @@ -package com.cultural.heritage.model.entity; - -public class ClothesOrder { -} diff --git a/src/main/java/com/cultural/heritage/model/entity/ClothesRentOrder.java b/src/main/java/com/cultural/heritage/model/entity/ClothesRentOrder.java new file mode 100644 index 0000000..b9c585f --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/entity/ClothesRentOrder.java @@ -0,0 +1,85 @@ +package com.cultural.heritage.model.entity; + +import com.baomidou.mybatisplus.annotation.IdType; +import com.baomidou.mybatisplus.annotation.TableField; +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.ClothesSnapshot; +import com.cultural.heritage.model.dto.snapshot.ContactsSnapshot; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +/** + * 服装租赁订单表 + * @TableName clothes_order + */ +@Data +@TableName(value = "clothes_rent_order", autoResultMap = true) +public class ClothesRentOrder implements Serializable { + + /** + * 服装租赁订单id + */ + @TableId(type = IdType.AUTO) + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 订单编号 + */ + private String orderNumber; + + /** + * 订单状态 + */ + private String orderStatus; + + /** + * 服装信息快照 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private ClothesSnapshot clothesSnapshot; + + /** + * 联系人信息快照 + */ + @TableField(typeHandler = JacksonTypeHandler.class) + private ContactsSnapshot contactsSnapshot; + + /** + * 租赁天数 + */ + private Integer rentDays; + + /** + * 总价 + */ + private BigDecimal totalAmount; + + /** + * 创建时间 + */ + private Date createTime; + + /** + * 更新时间 + */ + private Date updateTime; + + /** + * 是否删除 + */ + private Integer isDelete; + + @Serial + private static final long serialVersionUID = 1L; +} diff --git a/src/main/java/com/cultural/heritage/model/vo/clothesRentOrder/ClothesRentOrderVO.java b/src/main/java/com/cultural/heritage/model/vo/clothesRentOrder/ClothesRentOrderVO.java new file mode 100644 index 0000000..c079e32 --- /dev/null +++ b/src/main/java/com/cultural/heritage/model/vo/clothesRentOrder/ClothesRentOrderVO.java @@ -0,0 +1,79 @@ +package com.cultural.heritage.model.vo.clothesRentOrder; + +import com.cultural.heritage.model.dto.snapshot.ClothesSnapshot; +import com.cultural.heritage.model.dto.snapshot.ContactsSnapshot; +import com.fasterxml.jackson.annotation.JsonFormat; +import lombok.Data; + +import java.io.Serial; +import java.io.Serializable; +import java.math.BigDecimal; +import java.util.Date; + +@Data +public class ClothesRentOrderVO implements Serializable { + + + /** + * 服装租赁订单id + */ + private Long id; + + /** + * 用户id + */ + private Long userId; + + /** + * 用户名 + */ + private String userName; + + /** + * 订单编号 + */ + private String orderNumber; + + /** + * 订单状态 + */ + private String orderStatus; + + /** + * 服装信息快照 + */ + private ClothesSnapshot clothesSnapshot; + + /** + * 联系人信息快照 + */ + private ContactsSnapshot contactsSnapshot; + + /** + * 租赁天数 + */ + private Integer rentDays; + + /** + * 总价 + */ + private BigDecimal totalAmount; + + /** + * 订单创建时间 + */ + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") + 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/service/order/ClothesRentOrderService.java b/src/main/java/com/cultural/heritage/service/order/ClothesRentOrderService.java new file mode 100644 index 0000000..222386e --- /dev/null +++ b/src/main/java/com/cultural/heritage/service/order/ClothesRentOrderService.java @@ -0,0 +1,29 @@ +package com.cultural.heritage.service.order; + +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; +import com.baomidou.mybatisplus.extension.service.IService; +import com.cultural.heritage.model.dto.clothesRentOrder.ClothesRentOrderAddRequest; +import com.cultural.heritage.model.dto.clothesRentOrder.ClothesRentOrderQueryRequest; +import com.cultural.heritage.model.entity.ClothesRentOrder; + +public interface ClothesRentOrderService extends IService { + + /** + * 获取查询条件 + */ + QueryWrapper getQueryWrapper(ClothesRentOrderQueryRequest clothesRentOrderQueryRequest); + + + + /** + * 校验服装租赁订单请求体 + */ + void validClothesRentOrder(ClothesRentOrderAddRequest clothesRentOrderAddRequest); + + + + /** + * 向消息队列中发送订单创建的消息 + */ + void sendClothesRentOrderMessage(Long orderId); +} diff --git a/src/main/java/com/cultural/heritage/service/order/impl/ClothesRentOrderServiceImpl.java b/src/main/java/com/cultural/heritage/service/order/impl/ClothesRentOrderServiceImpl.java new file mode 100644 index 0000000..e697502 --- /dev/null +++ b/src/main/java/com/cultural/heritage/service/order/impl/ClothesRentOrderServiceImpl.java @@ -0,0 +1,81 @@ +package com.cultural.heritage.service.order.impl; + +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.MqConstant; +import com.cultural.heritage.exception.ThrowUtils; +import com.cultural.heritage.mapper.ClothesRentOrderMapper; +import com.cultural.heritage.model.dto.clothesRentOrder.ClothesRentOrderQueryRequest; +import com.cultural.heritage.model.dto.clothesRentOrder.ClothesRentOrderAddRequest; +import com.cultural.heritage.model.entity.ClothesRentOrder; +import com.cultural.heritage.service.order.ClothesRentOrderService; +import com.cultural.heritage.utils.MultiDelayMessage; +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.util.ArrayList; +import java.util.List; + +@Service +public class ClothesRentOrderServiceImpl extends ServiceImpl implements ClothesRentOrderService { + + + @Resource + private RabbitTemplate rabbitTemplate; + + + /** + * 获取查询条件 + */ + @Override + public QueryWrapper getQueryWrapper(ClothesRentOrderQueryRequest clothesRentOrderQueryRequest) { + String orderNumber = clothesRentOrderQueryRequest.getOrderNumber(); + String orderStatus = clothesRentOrderQueryRequest.getOrderStatus(); + String name = clothesRentOrderQueryRequest.getName(); + String phone = clothesRentOrderQueryRequest.getPhone(); + QueryWrapper queryWrapper = new QueryWrapper<>(); + queryWrapper.eq(StringUtils.isNotBlank(orderNumber), "orderNumber", orderNumber); + queryWrapper.eq(StringUtils.isNotBlank(orderStatus), "orderStatus", orderStatus); + queryWrapper.like(StringUtils.isNotBlank(name), "JSON_UNQUOTE(JSON_EXTRACT(contactsSnapshot, '$.name'))", name); + queryWrapper.eq(StringUtils.isNotBlank(phone), "JSON_UNQUOTE(JSON_EXTRACT(contactsSnapshot, '$.phone'))", phone); + return queryWrapper; + } + + + /** + * 校验 + */ + @Override + public void validClothesRentOrder(ClothesRentOrderAddRequest clothesRentOrderAddRequest) { + Long clothesId = clothesRentOrderAddRequest.getClothesId(); + Long contactsId = clothesRentOrderAddRequest.getContactsId(); + Integer rentDays = clothesRentOrderAddRequest.getRentDays(); + ThrowUtils.throwIf(ObjectUtils.anyNull(clothesId, contactsId, rentDays), ErrorCode.PARAMS_ERROR); + } + + + + /** + * 向消息队列中发送订单创建的消息 + */ + @Override + public void sendClothesRentOrderMessage(Long orderId) { + // 复制 DELAY_MILLIS 到一个新的 ArrayList + List newDelayMillis = new ArrayList<>(MqConstant.DELAY_MILLIS); + // 延迟检查订单状态信息 + MultiDelayMessage msg = new MultiDelayMessage<>(orderId, newDelayMillis); + int delayValue = msg.removeNextDelay().intValue(); + rabbitTemplate.convertAndSend(MqConstant.DELAY_EXCHANGE, + MqConstant.DELAY_CLOTHES_RENT_ORDER_ROUTING_KEY, msg, message -> { + // 添加延迟消息属性 + message.getMessageProperties().setDelay(delayValue); + return message; + }); + } + + +} diff --git a/src/main/resources/mapper/ClothesOrder.xml b/src/main/resources/mapper/ClothesRentOrderMapper.xml similarity index 70% rename from src/main/resources/mapper/ClothesOrder.xml rename to src/main/resources/mapper/ClothesRentOrderMapper.xml index aa2f39b..91ea9f0 100644 --- a/src/main/resources/mapper/ClothesOrder.xml +++ b/src/main/resources/mapper/ClothesRentOrderMapper.xml @@ -2,6 +2,6 @@ - + \ No newline at end of file