From 5ecb19a07c10cad36666bab23f14245dc4c10174 Mon Sep 17 00:00:00 2001
From: KKSU <15274802129@163.com>
Date: Wed, 22 Jan 2025 15:02:18 +0800
Subject: [PATCH] refactor(mall): 重构订单发货逻辑

---
 src/test/java/cc/mrbird/febs/AgentTest.java                                |   16 ++++-
 src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallOrderService.java  |   27 +++++---
 src/main/java/cc/mrbird/febs/common/utils/ValidateEntityUtils.java         |  134 ++++++++++++++++++++++++++++++++++++++++++++
 src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallNewsServiceImpl.java |    2 
 4 files changed, 164 insertions(+), 15 deletions(-)

diff --git a/src/main/java/cc/mrbird/febs/common/utils/ValidateEntityUtils.java b/src/main/java/cc/mrbird/febs/common/utils/ValidateEntityUtils.java
new file mode 100644
index 0000000..1501a44
--- /dev/null
+++ b/src/main/java/cc/mrbird/febs/common/utils/ValidateEntityUtils.java
@@ -0,0 +1,134 @@
+package cc.mrbird.febs.common.utils;
+
+import cc.mrbird.febs.common.exception.FebsException;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
+
+import java.util.Objects;
+
+/**
+ * 实体验证工具类
+ */
+public class ValidateEntityUtils {
+
+    /**
+     * 确保指定列的值在数据库中是存在的,
+     *      该方法通过查询数据库来验证给定的列值是否存在如果不存在,则抛出异常
+     *
+     * @param valueToCheck 需要验证的列值
+     * @param columnExtractor 用于提取实体类中列值的函数式接口
+     * @param queryWrapperExtractor 用于构建查询条件并返回实体类的函数式接口
+     * @param errMsg 当列值无效时抛出的异常消息格式字符串
+     * @throws IllegalArgumentException 如果需要验证的值为null
+     * @throws FebsException 如果在数据库中找不到指定的列值或列值为null,或者在查询过程中发生异常
+     */
+    public static <T, R, V> void ensureColumnValid(
+            V valueToCheck,
+            SFunction<T, R> columnExtractor,
+            SFunction<LambdaQueryWrapper<T>, T> queryWrapperExtractor,
+            String errMsg) {
+        // 检查需要验证的值是否为null
+        if (valueToCheck == null) {
+            throw new IllegalArgumentException("The value to check cannot be null while ensureColumnValid column");
+        }
+
+        try {
+            // 创建LambdaQueryWrapper并配置查询条件
+            LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>();
+            wrapper.select(columnExtractor)
+                    .eq(columnExtractor, valueToCheck)
+                    .last("limit 1");
+
+            // 执行查询并获取结果实体
+            T entity = queryWrapperExtractor.apply(wrapper);
+            // 如果查询结果为空,则抛出异常
+            if (entity == null) {
+                throw new FebsException(StrUtil.format(errMsg, valueToCheck));
+            }
+
+            // 提取查询结果中的列值
+            R columnValue = columnExtractor.apply(entity);
+            // 如果列值为null,则抛出异常
+            if (columnValue == null) {
+                throw new FebsException(StrUtil.format(errMsg, valueToCheck));
+            }
+        } catch (Exception e) {
+            // 记录异常日志
+            throw new FebsException(e.getMessage());
+        }
+    }
+
+    /**
+     * 确保指定值在数据库中是唯一的
+     *      该方法通过查询数据库来验证给定的列值是否已经存在,如果存在,则抛出异常,以确保数据的唯一性
+     *
+     * @param valueToCheck 需要检查的值
+     * @param columnExtractor 用于提取实体类字段的函数式接口
+     * @param countWrapperExtractor 用于获取查询条件包装器中记录数的函数式接口
+     * @param errMsg 错误消息模板,当值不唯一时使用
+     * @param <T> 实体类类型
+     * @param <R> 字段类型
+     * @param <V> 需要检查的值的类型
+     * @throws IllegalArgumentException 如果需要检查的值为null,则抛出此异常
+     * @throws FebsException 如果值已存在或在检查过程中发生错误,则抛出此异常
+     */
+    public static <T, R, V> void ensureUnique(
+            V valueToCheck,
+            SFunction<T, R> columnExtractor,
+            SFunction<LambdaQueryWrapper<T>, Integer> countWrapperExtractor,
+            String errMsg) {
+        // 检查输入值是否为null,如果为null,则抛出IllegalArgumentException异常
+        if (valueToCheck == null) {
+            throw new IllegalArgumentException("The value to check cannot be null while ensureUnique column");
+        }
+        if (columnExtractor == null) {
+            throw new IllegalArgumentException("The columnExtractor cannot be null while ensureUnique column");
+        }
+        if (countWrapperExtractor == null) {
+            throw new IllegalArgumentException("The countWrapperExtractor cannot be null while ensureUnique column");
+        }
+
+        int count = 0;
+        try {
+            // 创建LambdaQueryWrapper对象,用于构建查询条件
+            LambdaQueryWrapper<T> wrapper = new LambdaQueryWrapper<>();
+            // 添加等于条件,检查的字段=需要检查的值
+            wrapper.eq(columnExtractor, valueToCheck);
+            // 执行查询并获取结果数量
+            count = countWrapperExtractor.apply(wrapper);
+
+        } catch (Exception e) {
+            // 记录异常日志
+            // 如果在检查过程中发生异常,抛出FebsException异常
+            throw new FebsException(StrUtil.format("An error occurred while ensuring unique column: {}", valueToCheck));
+        }
+
+        // 如果结果数量大于0,说明值已存在,抛出FebsException异常
+        if (count > 0) {
+            throw new FebsException(StrUtil.format(errMsg, valueToCheck));
+        }
+    }
+
+
+    /**
+     * 确保两个参数相等,如果不相等则抛出异常
+     *
+     * @param value1 第一个参数
+     * @param value2 第二个参数
+     * @param errMsg 当两个参数不相等时抛出的异常消息格式字符串
+     * @throws FebsException 如果两个参数不相等
+     */
+    public static <T> void ensureEqual(
+            T value1,
+            T value2,
+            String errMsg) {
+        // 使用 Objects.equals 处理 null 值,避免显式 null 检查
+        if (!Objects.equals(value1, value2)) {
+            // 延迟字符串格式化,只在需要抛出异常时进行
+            throw new FebsException(StrUtil.format(errMsg, value1, value2));
+        }
+    }
+
+
+}
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallOrderService.java b/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallOrderService.java
index 5134332..82a5090 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallOrderService.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/AdminMallOrderService.java
@@ -6,6 +6,7 @@
 import cc.mrbird.febs.common.enumerates.MoneyFlowTypeEnum;
 import cc.mrbird.febs.common.enumerates.OrderDeliveryStateEnum;
 import cc.mrbird.febs.common.enumerates.OrderStatusEnum;
+import cc.mrbird.febs.common.utils.ValidateEntityUtils;
 import cc.mrbird.febs.mall.dto.*;
 import cc.mrbird.febs.mall.entity.*;
 import cc.mrbird.febs.mall.mapper.*;
@@ -104,17 +105,21 @@
     @Override
     public FebsResponse deliverGoods(DeliverGoodsDto deliverGoodsDto) {
         MallOrderInfo mallOrderInfo = mallOrderInfoMapper.selectById(deliverGoodsDto.getId());
-        if(ObjectUtil.isEmpty(mallOrderInfo)){
-            return new FebsResponse().fail().message("订单不存在,刷新后重试");
-        }
-        Integer status = mallOrderInfo.getStatus();
-        if(2 != status){
-            return new FebsResponse().fail().message("订单不是待发货状态");
-        }
-        Integer deliveryType = mallOrderInfo.getDeliveryType();
-        if(2 != deliveryType){
-            return new FebsResponse().fail().message("订单的配送方式不是快递");
-        }
+        ValidateEntityUtils.ensureColumnValid(deliverGoodsDto.getId(), MallOrderInfo::getId, mallOrderInfoMapper::selectOne, "订单{}不存在");
+//        if(ObjectUtil.isEmpty(mallOrderInfo)){
+//            return new FebsResponse().fail().message("订单不存在,刷新后重试");
+//        }
+        ValidateEntityUtils.ensureEqual(mallOrderInfo.getStatus(), OrderStatusEnum.WAIT_SHIPPING.getValue(), "订单状态不是待发货状态");
+//        Integer status = mallOrderInfo.getStatus();
+//        if(2 != status){
+//            return new FebsResponse().fail().message("订单不是待发货状态");
+//        }
+
+        ValidateEntityUtils.ensureEqual(mallOrderInfo.getDeliveryType(), 2, "订单的配送方式不是快递");
+//        Integer deliveryType = mallOrderInfo.getDeliveryType();
+//        if(2 != deliveryType){
+//            return new FebsResponse().fail().message("订单的配送方式不是快递");
+//        }
 //        String expressNo = deliverGoodsDto.getExpressNo();
 //        if(StrUtil.isEmpty(expressNo)){
 //            return new FebsResponse().fail().message("请输入物流单号");
diff --git a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallNewsServiceImpl.java b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallNewsServiceImpl.java
index 1805515..62900eb 100644
--- a/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallNewsServiceImpl.java
+++ b/src/main/java/cc/mrbird/febs/mall/service/impl/ApiMallNewsServiceImpl.java
@@ -17,6 +17,8 @@
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
+import java.math.RoundingMode;
 import java.util.List;
 
 /**
diff --git a/src/test/java/cc/mrbird/febs/AgentTest.java b/src/test/java/cc/mrbird/febs/AgentTest.java
index 8b1c353..56de56c 100644
--- a/src/test/java/cc/mrbird/febs/AgentTest.java
+++ b/src/test/java/cc/mrbird/febs/AgentTest.java
@@ -1,5 +1,7 @@
 package cc.mrbird.febs;
 
+import cc.mrbird.febs.common.utils.ValidateEntityUtils;
+import cc.mrbird.febs.mall.mapper.MallMemberCouponMapper;
 import lombok.extern.slf4j.Slf4j;
 import org.junit.jupiter.api.Test;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -16,12 +18,18 @@
 public class AgentTest {
     @Resource
     RestTemplate restTemplate;
+    @Resource
+    MallMemberCouponMapper mallMemberCouponMapper;
     @Test
     public void getCouponAmountMap() {
-        // 使用未编码的经纬度字符串
-        String url = "https://revgeocode.search.hereapi.com/v1/revgeocode?at=48.2181679,16.3899064&lang=en-US&apiKey=21tSClSPVotUklhRA4GIgECwZ0S6MmJ73TJ8v8ojDuo";
-        String jsonStr = restTemplate.getForObject(url, String.class);
-        log.info("Response: {}", jsonStr);
+//        ValidateEntityUtils.ensureColumnValid(205L, MallMemberCoupon::getId, mallMemberCouponMapper::selectOne, "id{}不存在");
+//        ValidateEntityUtils.ensureUnique(205L, MallMemberCoupon::getId, mallMemberCouponMapper::selectCount, "id{}已存在");
+        ValidateEntityUtils.ensureEqual(205L, 206L, "{},{},值不相等");
+
+//        // 使用未编码的经纬度字符串
+//        String url = "https://revgeocode.search.hereapi.com/v1/revgeocode?at=48.2181679,16.3899064&lang=en-US&apiKey=21tSClSPVotUklhRA4GIgECwZ0S6MmJ73TJ8v8ojDuo";
+//        String jsonStr = restTemplate.getForObject(url, String.class);
+//        log.info("Response: {}", jsonStr);
     }
 
 

--
Gitblit v1.9.1