From 5a50114b595833332718cc323b5b7257634d2ba9 Mon Sep 17 00:00:00 2001 From: irving Date: Sat, 6 Sep 2025 23:20:44 -0400 Subject: [PATCH] Refactor order creation with Builder pattern and type-safe enums - Replace 20+ parameter method calls with Builder pattern in WxCustomController - Add RewardType and CommodityType enums with database compatibility - Update DTOs and service layer for enum conversion - Fix all test cases with proper enum usage - Ensure backward compatibility through service layer conversion --- .../order/module/constant/OrderConstant.java | 58 ++++++++ .../order/module/dto/CommodityInfo.java | 5 +- .../module/dto/OrderCreationRequest.java | 3 +- .../impl/PlayOrderInfoServiceImpl.java | 4 +- .../controller/WxCustomController.java | 126 +++++++++++++++++- .../service/OrderCreationRequestTest.java | 4 +- .../service/PlayOrderInfoServiceTest.java | 18 ++- 7 files changed, 203 insertions(+), 15 deletions(-) diff --git a/play-admin/src/main/java/com/starry/admin/modules/order/module/constant/OrderConstant.java b/play-admin/src/main/java/com/starry/admin/modules/order/module/constant/OrderConstant.java index 4ceeafd..f14b181 100644 --- a/play-admin/src/main/java/com/starry/admin/modules/order/module/constant/OrderConstant.java +++ b/play-admin/src/main/java/com/starry/admin/modules/order/module/constant/OrderConstant.java @@ -122,6 +122,64 @@ public class OrderConstant { } } + /** + * 打赏类型枚举 + */ + @Getter + public enum RewardType { + NOT_APPLICABLE("", "非打赏订单"), + BALANCE("0", "余额打赏"), + GIFT("1", "礼物打赏"); + + private final String code; + private final String description; + + RewardType(String code, String description) { + this.code = code; + this.description = description; + } + + public static RewardType fromCode(String code) { + // Handle null, empty string, or whitespace as NOT_APPLICABLE + if (code == null || code.trim().isEmpty()) { + return NOT_APPLICABLE; + } + + for (RewardType type : values()) { + if (code.equals(type.code)) { + return type; + } + } + throw new IllegalArgumentException("Unknown reward type code: " + code); + } + } + + /** + * 商品类型枚举 + */ + @Getter + public enum CommodityType { + GIFT("0", "礼物"), + SERVICE("1", "服务"); + + private final String code; + private final String description; + + CommodityType(String code, String description) { + this.code = code; + this.description = description; + } + + public static CommodityType fromCode(String code) { + for (CommodityType type : values()) { + if (type.code.equals(code)) { + return type; + } + } + throw new IllegalArgumentException("Unknown commodity type code: " + code); + } + } + // Legacy constants for backward compatibility - consider deprecating @Deprecated public final static String ORDER_STATUS_0 = "0"; diff --git a/play-admin/src/main/java/com/starry/admin/modules/order/module/dto/CommodityInfo.java b/play-admin/src/main/java/com/starry/admin/modules/order/module/dto/CommodityInfo.java index 1bc1ac0..88d296f 100644 --- a/play-admin/src/main/java/com/starry/admin/modules/order/module/dto/CommodityInfo.java +++ b/play-admin/src/main/java/com/starry/admin/modules/order/module/dto/CommodityInfo.java @@ -1,5 +1,6 @@ package com.starry.admin.modules.order.module.dto; +import com.starry.admin.modules.order.module.constant.OrderConstant; import java.math.BigDecimal; import lombok.Builder; import lombok.Data; @@ -18,9 +19,9 @@ public class CommodityInfo { private String commodityId; /** - * 商品类型[0:礼物,1:服务] + * 商品类型 */ - private String commodityType; + private OrderConstant.CommodityType commodityType; /** * 商品单价 diff --git a/play-admin/src/main/java/com/starry/admin/modules/order/module/dto/OrderCreationRequest.java b/play-admin/src/main/java/com/starry/admin/modules/order/module/dto/OrderCreationRequest.java index 21ea70f..3493fc7 100644 --- a/play-admin/src/main/java/com/starry/admin/modules/order/module/dto/OrderCreationRequest.java +++ b/play-admin/src/main/java/com/starry/admin/modules/order/module/dto/OrderCreationRequest.java @@ -1,6 +1,7 @@ package com.starry.admin.modules.order.module.dto; import com.starry.admin.modules.order.module.constant.OrderConstant; +import com.starry.admin.modules.order.module.constant.OrderConstant.RewardType; import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull; @@ -49,7 +50,7 @@ public class OrderCreationRequest { /** * 打赏类型(0:余额;1:礼物) */ - private String rewardType; + private RewardType rewardType; /** * 是否是首单 diff --git a/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/PlayOrderInfoServiceImpl.java b/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/PlayOrderInfoServiceImpl.java index 9ad7145..61ea3a5 100644 --- a/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/PlayOrderInfoServiceImpl.java +++ b/play-admin/src/main/java/com/starry/admin/modules/order/service/impl/PlayOrderInfoServiceImpl.java @@ -212,7 +212,7 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl(), vo.getRemark(), "", "", ""); + OrderCreationRequest orderRequest = OrderCreationRequest.builder() + .orderId(orderId) + .orderNo(playOrderInfoService.getOrderNo()) + .orderStatus(OrderConstant.OrderStatus.COMPLETED) + .orderType(OrderConstant.OrderType.NORMAL) + .placeType(OrderConstant.PlaceType.REWARD) + .rewardType(RewardType.BALANCE) + .isFirstOrder(true) + .commodityInfo(CommodityInfo.builder() + .commodityId("") + .commodityType(OrderConstant.CommodityType.GIFT) + .commodityPrice(BigDecimal.ZERO) + .serviceDuration("") + .commodityName("") + .commodityNumber("0") + .build()) + .paymentInfo(PaymentInfo.builder() + .orderMoney(new BigDecimal(vo.getMoney())) + .finalAmount(new BigDecimal(vo.getMoney())) + .discountAmount(BigDecimal.ZERO) + .couponIds(new ArrayList<>()) + .build()) + .purchaserBy(userId) + .acceptBy(vo.getClerkId()) + .weiChatCode(vo.getWeiChatCode()) + .remark(vo.getRemark()) + .build(); + playOrderInfoService.createOrderInfo(orderRequest); // 顾客减少余额 customUserInfoService.updateAccountBalanceById(customUserInfo.getId(), customUserInfo.getAccountBalance(), customUserInfo.getAccountBalance().subtract(new BigDecimal(vo.getMoney())), "1", "打赏", new BigDecimal(vo.getMoney()), BigDecimal.ZERO, orderId); return R.ok("成功"); @@ -247,7 +280,34 @@ public class WxCustomController { } String orderId = IdUtils.getUuid(); // 记录订单信息 - playOrderInfoService.createOrderInfo(orderId, playOrderInfoService.getOrderNo(), "3", "2", "2", "1", "1", giftInfo.getId(), "0", giftInfo.getPrice(), "", giftInfo.getName(), String.valueOf(vo.getGiftQuantity()), money, money, BigDecimal.ZERO, userId, vo.getClerkId(), vo.getWeiChatCode(), new ArrayList<>(), vo.getRemark(), "", "", ""); + OrderCreationRequest orderRequest = OrderCreationRequest.builder() + .orderId(orderId) + .orderNo(playOrderInfoService.getOrderNo()) + .orderStatus(OrderConstant.OrderStatus.COMPLETED) + .orderType(OrderConstant.OrderType.NORMAL) + .placeType(OrderConstant.PlaceType.REWARD) + .rewardType(RewardType.GIFT) + .isFirstOrder(true) + .commodityInfo(CommodityInfo.builder() + .commodityId(giftInfo.getId()) + .commodityType(OrderConstant.CommodityType.GIFT) + .commodityPrice(giftInfo.getPrice()) + .serviceDuration("") + .commodityName(giftInfo.getName()) + .commodityNumber(String.valueOf(vo.getGiftQuantity())) + .build()) + .paymentInfo(PaymentInfo.builder() + .orderMoney(money) + .finalAmount(money) + .discountAmount(BigDecimal.ZERO) + .couponIds(new ArrayList<>()) + .build()) + .purchaserBy(userId) + .acceptBy(vo.getClerkId()) + .weiChatCode(vo.getWeiChatCode()) + .remark(vo.getRemark()) + .build(); + playOrderInfoService.createOrderInfo(orderRequest); // 顾客减少余额 customUserInfoService.updateAccountBalanceById(customUserInfo.getId(), customUserInfo.getAccountBalance(), customUserInfo.getAccountBalance().subtract(money), "1", "赠送礼物", money, BigDecimal.ZERO, orderId); // 陪聊增加余额 @@ -329,7 +389,34 @@ public class WxCustomController { String orderId = IdUtils.getUuid(); String orderNo = playOrderInfoService.getOrderNo(); // 记录订单信息 - playOrderInfoService.createOrderInfo(orderId, orderNo, "0", "2", "0", "", "1", commodityInfo.getCommodityId(), "1", commodityInfo.getCommodityPrice(), commodityInfo.getServiceDuration(), commodityInfo.getCommodityName(), String.valueOf(vo.getCommodityQuantity()), money, money, BigDecimal.ZERO, customId, clerkUserInfo.getId(), vo.getWeiChatCode(), vo.getCouponIds(), vo.getRemark(), "", "", ""); + OrderCreationRequest orderRequest = OrderCreationRequest.builder() + .orderId(orderId) + .orderNo(orderNo) + .orderStatus(OrderConstant.OrderStatus.PENDING) + .orderType(OrderConstant.OrderType.NORMAL) + .placeType(OrderConstant.PlaceType.SPECIFIED) + .rewardType(RewardType.NOT_APPLICABLE) + .isFirstOrder(true) + .commodityInfo(CommodityInfo.builder() + .commodityId(commodityInfo.getCommodityId()) + .commodityType(OrderConstant.CommodityType.SERVICE) + .commodityPrice(commodityInfo.getCommodityPrice()) + .serviceDuration(commodityInfo.getServiceDuration()) + .commodityName(commodityInfo.getCommodityName()) + .commodityNumber(String.valueOf(vo.getCommodityQuantity())) + .build()) + .paymentInfo(PaymentInfo.builder() + .orderMoney(money) + .finalAmount(money) + .discountAmount(BigDecimal.ZERO) + .couponIds(vo.getCouponIds()) + .build()) + .purchaserBy(customId) + .acceptBy(clerkUserInfo.getId()) + .weiChatCode(vo.getWeiChatCode()) + .remark(vo.getRemark()) + .build(); + playOrderInfoService.createOrderInfo(orderRequest); // 顾客减少余额 customUserInfoService.updateAccountBalanceById(customUserInfo.getId(), customUserInfo.getAccountBalance(), customUserInfo.getAccountBalance().subtract(money), "1", "下单-指定单", money, BigDecimal.ZERO, orderId); // 发送通知给店员 @@ -357,7 +444,38 @@ public class WxCustomController { String orderId = IdUtils.getUuid(); String orderNo = playOrderInfoService.getOrderNo(); // 记录订单信息 - playOrderInfoService.createOrderInfo(orderId, orderNo, "0", "2", "1", "", "1", commodityInfo.getCommodityId(), "1", commodityInfo.getCommodityPrice(), commodityInfo.getServiceDuration(), commodityInfo.getCommodityName(), String.valueOf(vo.getCommodityQuantity()), money, money, BigDecimal.ZERO, customId, "", vo.getWeiChatCode(), vo.getCouponIds(), vo.getRemark(), vo.getSex(), vo.getLevelId(), vo.getExcludeHistory()); + OrderCreationRequest orderRequest = OrderCreationRequest.builder() + .orderId(orderId) + .orderNo(orderNo) + .orderStatus(OrderConstant.OrderStatus.PENDING) + .orderType(OrderConstant.OrderType.NORMAL) + .placeType(OrderConstant.PlaceType.RANDOM) + .rewardType(RewardType.NOT_APPLICABLE) + .isFirstOrder(true) + .commodityInfo(CommodityInfo.builder() + .commodityId(commodityInfo.getCommodityId()) + .commodityType(OrderConstant.CommodityType.SERVICE) + .commodityPrice(commodityInfo.getCommodityPrice()) + .serviceDuration(commodityInfo.getServiceDuration()) + .commodityName(commodityInfo.getCommodityName()) + .commodityNumber(String.valueOf(vo.getCommodityQuantity())) + .build()) + .paymentInfo(PaymentInfo.builder() + .orderMoney(money) + .finalAmount(money) + .discountAmount(BigDecimal.ZERO) + .couponIds(vo.getCouponIds()) + .build()) + .purchaserBy(customId) + .weiChatCode(vo.getWeiChatCode()) + .remark(vo.getRemark()) + .randomOrderRequirements(RandomOrderRequirements.builder() + .clerkGender(OrderConstant.Gender.fromCode(vo.getSex())) + .clerkLevelId(vo.getLevelId()) + .excludeHistory(vo.getExcludeHistory()) + .build()) + .build(); + playOrderInfoService.createOrderInfo(orderRequest); // 顾客减少余额 customUserInfoService.updateAccountBalanceById(customUserInfo.getId(), customUserInfo.getAccountBalance(), customUserInfo.getAccountBalance().subtract(money), "1", "下单-随机单", money, BigDecimal.ZERO, orderId); // 给全部店员发送通知 diff --git a/play-admin/src/test/java/com/starry/admin/modules/order/service/OrderCreationRequestTest.java b/play-admin/src/test/java/com/starry/admin/modules/order/service/OrderCreationRequestTest.java index 8c82cbc..cf0e03e 100644 --- a/play-admin/src/test/java/com/starry/admin/modules/order/service/OrderCreationRequestTest.java +++ b/play-admin/src/test/java/com/starry/admin/modules/order/service/OrderCreationRequestTest.java @@ -25,7 +25,7 @@ class OrderCreationRequestTest { // 构建商品信息 CommodityInfo commodityInfo = CommodityInfo.builder() .commodityId("commodity_001") - .commodityType("1") + .commodityType(OrderConstant.CommodityType.SERVICE) .commodityPrice(new BigDecimal("100.00")) .serviceDuration("60") .commodityName("陪聊服务") @@ -48,7 +48,7 @@ class OrderCreationRequestTest { .orderStatus(OrderConstant.OrderStatus.PENDING) .orderType(OrderConstant.OrderType.NORMAL) .placeType(OrderConstant.PlaceType.SPECIFIED) - .rewardType("0") + .rewardType(OrderConstant.RewardType.BALANCE) .isFirstOrder(true) .commodityInfo(commodityInfo) .paymentInfo(paymentInfo) diff --git a/play-admin/src/test/java/com/starry/admin/modules/order/service/PlayOrderInfoServiceTest.java b/play-admin/src/test/java/com/starry/admin/modules/order/service/PlayOrderInfoServiceTest.java index f6435cf..3f46aa2 100644 --- a/play-admin/src/test/java/com/starry/admin/modules/order/service/PlayOrderInfoServiceTest.java +++ b/play-admin/src/test/java/com/starry/admin/modules/order/service/PlayOrderInfoServiceTest.java @@ -77,11 +77,12 @@ class PlayOrderInfoServiceTest { .orderStatus(OrderConstant.OrderStatus.PENDING) .orderType(OrderConstant.OrderType.NORMAL) .placeType(OrderConstant.PlaceType.SPECIFIED) - .rewardType("0") + .rewardType(OrderConstant.RewardType.BALANCE) .isFirstOrder(true) .commodityInfo(CommodityInfo.builder() .commodityId("commodity_001") .commodityName("测试商品") + .commodityType(OrderConstant.CommodityType.SERVICE) .commodityPrice(BigDecimal.valueOf(100.00)) .serviceDuration("60") .commodityNumber("1") @@ -130,10 +131,12 @@ class PlayOrderInfoServiceTest { .orderStatus(OrderConstant.OrderStatus.PENDING) .orderType(OrderConstant.OrderType.NORMAL) .placeType(OrderConstant.PlaceType.RANDOM) + .rewardType(OrderConstant.RewardType.NOT_APPLICABLE) .isFirstOrder(false) .commodityInfo(CommodityInfo.builder() .commodityId("service_001") .commodityName("陪聊服务") + .commodityType(OrderConstant.CommodityType.SERVICE) .commodityPrice(BigDecimal.valueOf(50.00)) .serviceDuration("30") .build()) @@ -174,11 +177,12 @@ class PlayOrderInfoServiceTest { .orderStatus(OrderConstant.OrderStatus.PENDING) .orderType(OrderConstant.OrderType.NORMAL) .placeType(OrderConstant.PlaceType.REWARD) - .rewardType("1") + .rewardType(OrderConstant.RewardType.GIFT) .isFirstOrder(false) .commodityInfo(CommodityInfo.builder() .commodityId("gift_001") .commodityName("虚拟礼物") + .commodityType(OrderConstant.CommodityType.GIFT) .commodityPrice(BigDecimal.valueOf(20.00)) .build()) .paymentInfo(PaymentInfo.builder() @@ -218,10 +222,12 @@ class PlayOrderInfoServiceTest { .orderStatus(OrderConstant.OrderStatus.PENDING) .orderType(OrderConstant.OrderType.NORMAL) .placeType(OrderConstant.PlaceType.RANDOM) // 随机单但没有要求 + .rewardType(OrderConstant.RewardType.NOT_APPLICABLE) .isFirstOrder(false) .commodityInfo(CommodityInfo.builder() .commodityId("service_001") .commodityName("服务") + .commodityType(OrderConstant.CommodityType.SERVICE) .commodityPrice(BigDecimal.valueOf(50.00)) .build()) .paymentInfo(PaymentInfo.builder() @@ -257,10 +263,12 @@ class PlayOrderInfoServiceTest { .orderStatus(OrderConstant.OrderStatus.PENDING) .orderType(OrderConstant.OrderType.NORMAL) .placeType(OrderConstant.PlaceType.SPECIFIED) + .rewardType(OrderConstant.RewardType.NOT_APPLICABLE) .isFirstOrder(false) .commodityInfo(CommodityInfo.builder() .commodityId("commodity_002") .commodityName("优惠商品") + .commodityType(OrderConstant.CommodityType.SERVICE) .commodityPrice(BigDecimal.valueOf(200.00)) .build()) .paymentInfo(PaymentInfo.builder() @@ -311,11 +319,12 @@ class PlayOrderInfoServiceTest { .orderStatus(OrderConstant.OrderStatus.PENDING) .orderType(OrderConstant.OrderType.NORMAL) .placeType(OrderConstant.PlaceType.SPECIFIED) - .rewardType("0") + .rewardType(OrderConstant.RewardType.BALANCE) .isFirstOrder(true) .commodityInfo(CommodityInfo.builder() .commodityId("commodity_003") .commodityName("复杂商品") + .commodityType(OrderConstant.CommodityType.SERVICE) .commodityPrice(BigDecimal.valueOf(300.00)) .serviceDuration("120") .commodityNumber("1") @@ -378,11 +387,12 @@ class PlayOrderInfoServiceTest { .orderStatus(OrderConstant.OrderStatus.PENDING) .orderType(OrderConstant.OrderType.NORMAL) .placeType(OrderConstant.PlaceType.SPECIFIED) - .rewardType("0") + .rewardType(OrderConstant.RewardType.BALANCE) .isFirstOrder(true) // 首单 .commodityInfo(CommodityInfo.builder() .commodityId("commodity_revenue") .commodityName("收入测试商品") + .commodityType(OrderConstant.CommodityType.SERVICE) .commodityPrice(BigDecimal.valueOf(200.00)) .serviceDuration("90") .build())