商城订单使用优惠卷价格计算逻辑,举例计算

参考文档

代码应用时注意:

计算最后一个满减时,我们四舍五入,肯定会大于或小于最终满减金额。因此最后一个商品满减金额的算法为:总满减金额 - 前面所有商品满减的金额 = 最后一个商品满减金额

例1

一个商品,买了4件,单件价格50元;用了优惠卷满199-100;要退2个,求各商品实际支付价格和退款价格;

     1、计算商品总价,是否满足使用优惠卷
        50*4=200;   //满足
     2、计算使用优惠卷后的实际应付金额
        200-100=100;
     3、优惠卷满减的金额,应该按照商品价格分摊到各个商品
        (1)、得到每实际支付1元分摊的优惠金额
            公式1:满减金额 / 订单参与满减的总金额 = 每实际支付1元分摊的优惠金额
                  100 / 200 = 0.5;
        (2)、使用每1元分摊的优惠金额,计算出各个订单所分摊的优惠卷金额
            公式2:每实际支付1元分摊的优惠金额 * 单个订单的成交价 = 单个订单分摊的优惠卷金额
                  0.5 * 50 = 25;
            公式3:单个订单分摊的优惠卷金额 * 购买数量 = 优惠卷满减金额
                  25 * 4 = 100;
            公式4:商品价格 - 公式2求出的单个订单分摊的优惠卷金额 = 各商品实际支付金额
                  50 - 25 = 25;
            计算完成,进行验证,验证都成功即计算成功。
            1、优惠满减金额与公式3求出的满减金额是否正确  // true
            2、公式3求出的满减金额 + 序号2里的实际应付金额是否等于商品总价 // true
            3、各商品实际支付金额 * 购买数量 是否等于 商品总价 - 使用优惠卷后的金额
                x = 25 * 4 = 100元; 
                y = 200 - 100 = 100元;
                x === y; // true
         答:
            1、各商品实际支付价格25元:见公式4;
            2、退款价格50元:各商品实际支付金额 * 退款数量 = 退款价格
                           25 * 2 = 50;

例2

多个商品,商品a买了5件,价格为10元一件。商品b买了1个,价格为25一件。商品c买了3个,价格为15元件;用了优惠卷买99-40;需要退款:商品a退3个,b跟c全退

    1、计算商品总价,是否满足使用优惠卷
        (10*5)+(25*1)+(15*3)=120;   //满足
     2、计算使用优惠卷后的实际应付金额
        120-40=80;
     3、优惠卷满减的金额,应该按照商品价格分摊到各个商品
        (1)、得到每实际支付1元分摊的优惠金额
            公式1:满减金额 / 订单参与满减的总金额 = 每实际支付1元分摊的优惠金额
                  40 / 120 = 0.3333333333333333;
        (2)、使用每1元分摊的优惠金额,计算出各个订单所分摊的优惠卷金额
            公式2:每实际支付1元分摊的优惠金额 * 单个订单的成交价 = 单个订单分摊的优惠卷金额
                  商品a:0.3333333333333333 * 10 = 3.333333333333333;
                  商品b:0.3333333333333333 * 25 = 8.333333333333332;
                  商品c:0.3333333333333333 * 15 = 5;
            公式3:单个订单分摊的优惠卷金额 * 购买数量 = 优惠卷满减金额
                  商品a:3.333333333333333 * 5 = 16.666666666666664;
                  商品b:8.333333333333332 * 1 = 8.333333333333332;
                  商品c:5 * 3 = 15;
                  多商品需要相加:16.666666666666664 + 8.333333333333332 + 15 = 40元
            公式4:商品价格 - 公式2求出的单个订单分摊的优惠卷金额 = 各商品实际支付金额
                  商品a:10 - 3.333333333333333 = 6.666666666666667元;
                  商品b:25 - 8.333333333333332 = 16.666666666666668元;
                  商品c:15 - 5 = 10元;
            计算完成,进行验证,验证都成功即计算成功。
            1、优惠满减金额与公式3求出的满减金额是否正确  // true
            2、公式3求出的满减金额 + 序号2里的实际应付金额是否等于商品总价 // true
            3、各商品实际支付金额 * 购买数量 是否等于 商品总价 - 使用优惠卷后的金额
                x = (6.666666666666667*5) + (16.666666666666668*1) + (10*3) = 80元; 
                y = 120 - 40 = 80元;
                x === y; // true
         答:
            退款价格66.66666666666667元:各商品实际支付金额 * 退款数量 = 退款价格
                (6.666666666666667*3) + (16.666666666666668*1) + (10*3) = 66.66666666666667元

例3

多个商品,商品a买了2件,价格为99.99元一件。商品b买了1个,价格为69.3一件。商品c买了1个,价格为169元件;用了优惠卷买300-50;需要退款:各退一个

    1、计算商品总价,是否满足使用优惠卷
        (99.99*2)+(69.3*1)+(169*1)=438.28;   //满足
     2、计算使用优惠卷后的实际应付金额
        438.28-50=388.28;
     3、优惠卷满减的金额,应该按照商品价格分摊到各个商品
        (1)、得到每实际支付1元分摊的优惠金额
            公式1:满减金额 / 订单参与满减的总金额 = 每实际支付1元分摊的优惠金额
                  50 / 438.28 = 0.11408232180341335;
        (2)、使用每1元分摊的优惠金额,计算出各个订单所分摊的优惠卷金额
            公式2:每实际支付1元分摊的优惠金额 * 单个订单的成交价 = 单个订单分摊的优惠卷金额
                  商品a:0.11408232180341335 * 99.99 = 11.407091357123301;
                  商品b:0.11408232180341335 * 69.3 = 7.9059049009765445;
                  商品c:0.11408232180341335 * 169 = 19.279912384776857;
            公式3:单个订单分摊的优惠卷金额 * 购买数量 = 优惠卷满减金额
                  商品a:11.407091357123301 * 2 = 22.814182714246602;
                  商品b:7.9059049009765445 * 1 = 7.9059049009765445;
                  商品c:19.279912384776857 * 1 = 19.279912384776857;
                  多商品需要相加:22.814182714246602 + 7.9059049009765445 + 19.279912384776857 = 50元
            公式4:商品价格 - 公式2求出的单个订单分摊的优惠卷金额 = 各商品实际支付金额
                  商品a:99.99 - 11.407091357123301 = 88.58290864287669元;
                  商品b:69.3 - 7.9059049009765445 = 61.39409509902345元;
                  商品c:169 - 19.279912384776857 = 149.72008761522315元;
            计算完成,进行验证,验证都成功即计算成功。
            1、优惠满减金额与公式3求出的满减金额是否正确  // true
            2、公式3求出的满减金额 + 序号2里的实际应付金额是否等于商品总价 // true
            3、各商品实际支付金额 * 购买数量 是否等于 商品总价 - 使用优惠卷后的金额
                x = (88.58290864287669*2) + (61.39409509902345*1) + (149.72008761522315*1) = 388.28元; 
                y = 438.28 - 52 = 388.28元;
                x === y; // true
         答:
            退款价格66.66666666666667元:各商品实际支付金额 * 退款数量 = 退款价格
                (88.58290864287669*1) + (61.39409509902345*1) + (149.72008761522315*1) = 299.6970913571233元                

例4(简单版)

一个商品,商品a5个,价格55;用了优惠卷买99-40;

    1、计算商品总价,是否满足使用优惠卷
        (55*5)=275;   //满足
     2、计算使用优惠卷后的实际应付金额
        275-40=235;
     3、优惠卷满减的金额,应该按照商品价格分摊到各个商品
        (1)、得到每实际支付1元分摊的优惠金额
            公式1:满减金额 / 订单参与满减的总金额 = 每实际支付1元分摊的优惠金额
                  40 / 275 = 0.14545454545454545;
        (2)、使用每1元分摊的优惠金额,计算出各个订单所分摊的优惠卷金额
            公式2:每实际支付1元分摊的优惠金额 * 单个订单的成交价 = 单个订单分摊的优惠卷金额
                  商品a:0.14545454545454545 * 55 = 8;
            公式3:单个订单分摊的优惠卷金额 * 购买数量 = 优惠卷满减金额
                  商品a:8 * 5 = 40;
            公式4:商品价格 - 公式2求出的单个订单分摊的优惠卷金额 = 各商品实际支付金额
                  商品a:55 - 8 = 47元;
            计算完成,进行验证,验证都成功即计算成功。
            1、优惠满减金额与公式3求出的满减金额是否正确  // true
            2、公式3求出的满减金额 + 序号2里的实际应付金额是否等于商品总价 // true
            3、各商品实际支付金额 * 购买数量 是否等于 商品总价 - 使用优惠卷后的金额
                47 * 5 === 275 - 40; // true

<think>嗯,用户问的是让我举例说明领域驱动设计,也就是DDD。首先我需要回忆一下DDD的基本概念,确保自己理解正确。领域驱动设计是一种软件开发方法,重点在于将业务领域作为核心,通过领域模型来指导设计和开发。核心概念包括通用语言、限界上下文、实体、值对象、聚合根、领域事件、仓储和领域服务等等。 用户可能是一个开发者,或者是对软件设计方法感兴趣的人,想通过例子来理解DDD如何应用在实际项目中。他们可能已经听说过DDD,但不太清楚具体怎么操作,或者想看看实际案例。我需要找一个常见的业务场景,比如电商系统,这样更容易让用户有代入感。 接下来,我需要构建一个例子,比如在线商城订单处理流程。这个例子需要涵盖DDD的主要元素。首先,确定通用语言,也就是团队和领域专家共同定义术语,比如订单订单项、订单状态等。然后划分限界上下文,比如订单上下文、库存上下文、支付上下文,每个上下文有自己的模型和职责,避免耦合。 然后,设计实体和值对象。订单是一个实体,有唯一ID,而订单项可能作为值对象,因为它们的属性一旦创建就不会改变。聚合根可能是订单,因为它是整个聚合的入口点,负责维护一致性。比如,添加订单项时需要检查库存,这里可能需要调用库存上下文的领域服务,或者通过领域事件来处理库存扣减。 领域事件的应用,比如订单创建后触发OrderCreated事件,库存服务监听这个事件并扣减库存。这样各个上下文之间通过事件进行通信,保持松耦合。仓储部分,订单仓储负责持久化订单聚合根,而仓储接口定义在领域层,实现则在基础设施层,这样符合分层架构。 需要检查是否有遗漏的DDD概念,比如领域服务,可能在订单总金额计算时,如果逻辑复杂,可以放到领域服务中处理。或者,订单的状态转换,使用状态模式来管理,确保状态变更符合业务规则。 用户可能的深层需求是想了解如何将DDD应用到实际项目,避免理论上的空泛。所以例子需要具体,步骤清晰,展示如何从领域分析到设计实现的过程。同时,可能需要强调DDD的优势,比如应对复杂业务逻辑,提高代码可维护性,促进团队沟通等。 要注意避免技术细节过多,保持解释的易懂性。比如,在提到限界上下文时,可以说明每个上下文对应一个微服务或者模块,但不需要深入微服务的架构细节。重点放在模型的设计和交互上。 总结下来,例子需要涵盖通用语言、限界上下文、实体、值对象、聚合根、领域事件、仓储和领域服务,并且通过一个连贯的业务流程展示它们如何协作。同时,要确保例子贴近实际,让用户能够联想到自己可能遇到的场景,从而更好地理解DDD的应用。好的</think>!领域驱动设计(Domain-Driven Design,DDD)是一种以业务领域为核心的软件设计方法,通过将业务逻辑和领域知识直接映射到代码中,解决复杂系统的设计问题。以下通过一个**电商系统的订单处理流程**举例说明其核心概念: --- ### **场景描述** 假设我们要设计一个在线商城订单系统,核心功能是用户下单、库存扣减、支付和订单状态管理。 --- ### **DDD 核心概念与示例** #### 1. **通用语言(Ubiquitous Language)** - **定义**:开发团队与领域专家(如业务人员)共同定义一套明确的术语,消除沟通歧义。 - **示例**: - **订单(Order)**:用户购买商品的记录。 - **订单项(OrderItem)**:订单中的单个商品条目。 - **订单状态(OrderStatus)**:订单的生命周期状态(如“待支付”“已发货”)。 --- #### 2. **限界上下文(Bounded Context)** - **定义**:将系统划分为多个独立的业务边界,每个边界内使用一致的领域模型。 - **示例**: - **订单上下文**:负责订单创建、状态流转。 - **库存上下文**:管理商品库存扣减与恢复。 - **支付上下文**:处理支付流水和金额校验。 - **作用**:避免不同业务逻辑混杂(例如“订单中的商品”和“库存中的商品”可能是不同模型)。 --- #### 3. **实体(Entity)与值对象(Value Object)** - **实体**:通过唯一标识(ID)区分,如 `Order`: ```java class Order { String orderId; // 唯一标识 List<OrderItem> items; OrderStatus status; // 业务方法:修改订单状态 void markAsPaid() { ... } } ``` - **值对象**:无唯一标识,通过属性定义,如 `OrderItem`: ```java class OrderItem { String productId; int quantity; BigDecimal price; } ``` --- #### 4. **聚合根(Aggregate Root)** - **定义**:聚合是一组关联对象的集合,聚合根是外部访问的唯一入口。 - **示例**:`Order` 是聚合根,内部包含 `OrderItem`。外部只能通过 `Order` 的方法修改其状态或添加商品。 - **规则**:添加订单项时,聚合根需校验商品库存(调用库存领域服务)。 --- #### 5. **领域事件(Domain Event)** - **定义**:表示领域中发生的重要事件,用于解耦系统组件。 - **示例**:订单创建后触发 `OrderCreated` 事件,库存服务监听该事件并扣减库存: ```java // 事件定义 class OrderCreatedEvent { String orderId; List<ProductStockDTO> items; } // 订单服务发布事件 orderRepository.save(order); eventPublisher.publish(new OrderCreatedEvent(...)); // 库存服务监听事件 class InventoryHandler { void onOrderCreated(OrderCreatedEvent event) { inventoryService.reduceStock(event.getItems()); } } ``` -- #### 6. **仓储(Repository)** - **定义**:封装聚合根的持久化逻辑,隔离领域模型与数据库细节。 - **示例**: ```java interface OrderRepository { Order findById(String orderId); void save(Order order); } // 实现类(如 JPA、MySQL)在基础设施层编写。 ``` --- #### 7. **领域服务(Domain Service)** - **定义**:处理单个聚合根无法实现的复杂业务逻辑。 - **示例**:计算订单总金额时,若涉及优惠券、运费等跨实体逻辑: ```java class OrderCalculationService { BigDecimal calculateTotal(Order order, Coupon coupon) { // 计算商品总价、运费、优惠抵扣 } } ``` --- ### **DDD 的优势** 1. **聚焦业务逻辑**:代码直接反映业务术语和流程。 2. **高内聚低耦合**:通过限界上下文隔离不同业务域。 3. **适应复杂需求**:通过事件驱动、聚合根等模式应对业务规则变化。 --- 通过这样的设计,订单系统可以清晰地表达业务意图,同时保持灵活性和可维护性。实际项目中,DDD 需要团队与领域专家紧密协作,逐步迭代模型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值