郭子栋 преди 11 часа
родител
ревизия
570f022792

+ 8 - 0
nightFragrance-massage/src/main/java/com/ylx/order/controller/OrderController.java

@@ -2,6 +2,7 @@ package com.ylx.order.controller;
 
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.ylx.common.core.domain.R;
+import com.ylx.order.domain.dto.OrderCancleDTO;
 import com.ylx.order.domain.dto.OrderDateQueryDTO;
 import com.ylx.order.domain.dto.OrderDeleteDTO;
 import com.ylx.order.domain.dto.OrderSubmitDTO;
@@ -59,4 +60,11 @@ public class OrderController {
             @PathVariable @ApiParam(value = "订单ID", required = true, example = "1") Long orderId) {
         return R.ok(orderService.getOrderDetailById(orderId));
     }
+    @ApiOperation("用户取消订单")
+    @PostMapping("/cancel")
+    public R<?> cancelOrder(@RequestBody @Validated OrderCancleDTO dto) {
+        // 调用服务层取消订单,返回影响行数或订单信息
+        int result = orderService.cancelOrder(dto);
+        return result > 0 ? R.ok("订单已取消") : R.fail("订单取消失败");
+    }
 }

+ 26 - 0
nightFragrance-massage/src/main/java/com/ylx/order/domain/dto/OrderCancleDTO.java

@@ -0,0 +1,26 @@
+package com.ylx.order.domain.dto;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * 类描述:用户端取消订单
+ *
+ * @author Administrator
+ * @version 1.0
+ * @date 2026/6/8 10:26
+ */
+@Data
+public class OrderCancleDTO {
+
+    @NotNull(message = "订单ID不能为空")
+    @ApiModelProperty("主键ID")
+    private Long id;
+
+    @NotBlank(message = "取消原因不能为空")
+    @ApiModelProperty("取消原因")
+    private String cancelledReason;
+}

+ 8 - 0
nightFragrance-massage/src/main/java/com/ylx/order/service/TOrderService.java

@@ -9,6 +9,7 @@ import com.ylx.massage.domain.TWxUser;
 import com.ylx.massage.domain.vo.HomeBlock;
 import com.ylx.massage.domain.vo.OrderVerificationVo;
 import com.ylx.massage.domain.vo.TechnicianAvailabilityVo;
+import com.ylx.order.domain.dto.OrderCancleDTO;
 import com.ylx.order.domain.dto.OrderDateQueryDTO;
 import com.ylx.order.domain.dto.OrderSubmitDTO;
 import com.ylx.order.domain.dto.OrderUpdateStatusDTO;
@@ -184,4 +185,11 @@ public interface TOrderService extends IService<TOrder> {
      * @return 订单详情VO
      */
     OrderDetailVO getOrderDetailById(Long orderId);
+
+    /**
+     * 用户端取消订单
+     * @param dto 取消订单DTO
+     * @return 取消结果
+     */
+    int cancelOrder(OrderCancleDTO dto);
 }

+ 48 - 0
nightFragrance-massage/src/main/java/com/ylx/order/service/impl/TOrderServiceImpl.java

@@ -32,6 +32,7 @@ import com.ylx.massage.service.TWxUserService;
 import com.ylx.massage.utils.OrderNumberGenerator;
 import com.ylx.order.domain.OrderStatusFlow;
 import com.ylx.order.domain.TOrder;
+import com.ylx.order.domain.dto.OrderCancleDTO;
 import com.ylx.order.domain.dto.OrderDateQueryDTO;
 import com.ylx.order.domain.dto.OrderSubmitDTO;
 import com.ylx.order.domain.dto.OrderUpdateStatusDTO;
@@ -75,6 +76,9 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
     private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
     private final DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("M月d日");
     private final DateTimeFormatter timeFormatter = DateTimeFormatter.ofPattern("HH:mm");
+
+    /** 仅允许取消的状态:待付款(0) */
+    private static final List<Integer> ALLOWED_CANCEL_STATUS = Collections.singletonList(0);
     @Resource
     private ProjectService projectService;
     @Resource
@@ -752,4 +756,48 @@ public class TOrderServiceImpl extends ServiceImpl<TOrderMapper, TOrder> impleme
         }
         return vo;
     }
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int cancelOrder(OrderCancleDTO dto) {
+        // 1. 查询订单
+        TOrder order = this.baseMapper.selectById(dto.getId());
+        if (order == null) {
+            throw new IllegalArgumentException("订单不存在");
+        }
+
+        // 2. 权限校验:仅限订单所属用户取消
+        Long currentUserId = SecurityUtils.getUserId();
+        if (!order.getUserId().equals(currentUserId)) {
+            throw new RuntimeException("您无权操作此订单");
+        }
+
+        // 3. 状态校验:只有待付款(0)可以取消
+        if (!OrderStatusEnum.PENDING_PAYMENT.getCode().equals(order.getStatus())) {
+            throw new RuntimeException("只有待付款订单可以取消,当前状态无法取消");
+        }
+
+        // 4. 重复取消校验(可选)
+        if (OrderStatusEnum.CANCELLED.getCode().equals(order.getStatus())) {
+            throw new RuntimeException("订单已取消,请勿重复操作");
+        }
+
+        // 5. 执行取消更新
+        TOrder updateOrder = new TOrder();
+        updateOrder.setId(dto.getId());
+        updateOrder.setStatus(OrderStatusEnum.CANCELLED.getCode());
+        updateOrder.setCancelledReason(dto.getCancelledReason());
+        updateOrder.setCancelledTime(LocalDateTime.now());
+        updateOrder.setUpdateTime(new Date());
+
+        int rows = this.baseMapper.updateById(updateOrder);
+        if (rows <= 0) {
+            throw new RuntimeException("取消失败,请稍后重试");
+        }
+
+        // 6. 待付款订单取消无需退款(因为未支付),但如需记录日志等可留扩展
+        log.info("订单取消成功,订单ID:{},原因:{}", dto.getId(), dto.getCancelledReason());
+
+        return rows;
+    }
 }