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
This commit is contained in:
irving
2025-09-06 23:20:44 -04:00
parent 295400b83e
commit 5a50114b59
7 changed files with 203 additions and 15 deletions

View File

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

View File

@@ -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;
/**
* 商品单价

View File

@@ -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;
/**
* 是否是首单

View File

@@ -212,7 +212,7 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
entity.setOrderStatus(request.getOrderStatus().getCode());
entity.setOrderType(request.getOrderType().getCode());
entity.setPlaceType(request.getPlaceType().getCode());
entity.setRewardType(request.getRewardType());
entity.setRewardType(request.getRewardType().getCode());
entity.setFirstOrder(request.getFirstOrderString());
// 固定默认值
@@ -225,7 +225,7 @@ public class PlayOrderInfoServiceImpl extends ServiceImpl<PlayOrderInfoMapper, P
// 商品信息
CommodityInfo commodityInfo = request.getCommodityInfo();
entity.setCommodityId(commodityInfo.getCommodityId());
entity.setCommodityType(commodityInfo.getCommodityType());
entity.setCommodityType(commodityInfo.getCommodityType().getCode());
entity.setCommodityPrice(commodityInfo.getCommodityPrice());
entity.setServiceDuration(commodityInfo.getServiceDuration());
entity.setCommodityName(commodityInfo.getCommodityName());

View File

@@ -19,6 +19,12 @@ import com.starry.admin.modules.custom.service.IPlayCustomFollowInfoService;
import com.starry.admin.modules.custom.service.IPlayCustomGiftInfoService;
import com.starry.admin.modules.custom.service.IPlayCustomLeaveMsgService;
import com.starry.admin.modules.custom.service.IPlayCustomUserInfoService;
import com.starry.admin.modules.order.module.constant.OrderConstant;
import com.starry.admin.modules.order.module.constant.OrderConstant.RewardType;
import com.starry.admin.modules.order.module.dto.CommodityInfo;
import com.starry.admin.modules.order.module.dto.OrderCreationRequest;
import com.starry.admin.modules.order.module.dto.PaymentInfo;
import com.starry.admin.modules.order.module.dto.RandomOrderRequirements;
import com.starry.admin.modules.order.module.entity.PlayOrderComplaintInfoEntity;
import com.starry.admin.modules.order.module.entity.PlayOrderEvaluateInfoEntity;
import com.starry.admin.modules.order.module.entity.PlayOrderInfoEntity;
@@ -224,7 +230,34 @@ public class WxCustomController {
}
String orderId = IdUtils.getUuid();
// 记录订单信息
playOrderInfoService.createOrderInfo(orderId, playOrderInfoService.getOrderNo(), "3", "2", "2", "0", "1", "", "0", BigDecimal.ZERO, "", "", "0", new BigDecimal(vo.getMoney()), new BigDecimal(vo.getMoney()), 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.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);
// 给全部店员发送通知

View File

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

View File

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