当前位置: 首页 > article >正文

Java 篇-项目实战-天机学堂(从0到1)-day12

java 篇 1.基础地基 2.设计原理 3.项目实战这章功力有点不足了先放放改日再会会。定义优惠券规则业务流程分析及实现优惠规则策略模式导包定义接口因为是给其他服务用的那得放在 api 模块下和下面 FallbackConfig 当中对应优惠券方案推荐 ComplateFuture 并发运算添加线程池筛选最优解核心代码package com.tianji.promotion.service.impl; import com.tianji.api.dto.promotion.CouponDiscountDTO; import com.tianji.api.dto.promotion.OrderCouponDTO; import com.tianji.api.dto.promotion.OrderCourseDTO; import com.tianji.common.utils.CollUtils; import com.tianji.common.utils.UserContext; import com.tianji.promotion.domain.po.Coupon; import com.tianji.promotion.domain.po.CouponScope; import com.tianji.promotion.enums.UserCouponStatus; import com.tianji.promotion.mapper.UserCouponMapper; import com.tianji.promotion.service.ICouponScopeService; import com.tianji.promotion.service.IDiscountService; import com.tianji.promotion.strategy.discount.Discount; import com.tianji.promotion.strategy.discount.DiscountStrategy; import com.tianji.promotion.utils.PermuteUtil; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; import java.util.stream.Collectors; Slf4j Service RequiredArgsConstructor public class DiscountServiceImpl implements IDiscountService { private final UserCouponMapper userCouponMapper; private final ICouponScopeService scopeService; private final Executor discountSolutionExecutor; Override public ListCouponDiscountDTO findDiscountSolution(ListOrderCourseDTO orderCourses) { // 1.查询我的所有可用优惠券 ListCoupon coupons userCouponMapper.queryMyCoupons(UserContext._getUser_()); if (CollUtils._isEmpty_(coupons)) { return CollUtils._emptyList_(); } // 2.初筛 // 2.1.计算订单总价 int totalAmount orderCourses.stream().mapToInt(OrderCourseDTO::getPrice).sum(); // 2.2.筛选可用券 ListCoupon availableCoupons coupons.stream() .filter(c - DiscountStrategy._getDiscount_(c.getDiscountType()).canUse(totalAmount, c)) .collect(Collectors._toList_()); if (CollUtils._isEmpty_(availableCoupons)) { return CollUtils._emptyList_(); } // 3.排列组合出所有方案 // 3.1.细筛找出每一个优惠券的可用的课程判断课程总价是否达到优惠券的使用需求 MapCoupon, ListOrderCourseDTO availableCouponMap findAvailableCoupon(availableCoupons, orderCourses); if (CollUtils._isEmpty_(availableCouponMap)) { return CollUtils._emptyList_(); } // 3.2.排列组合 availableCoupons new ArrayList(availableCouponMap.keySet()); ListListCoupon solutions PermuteUtil._permute_(availableCoupons); // 3.3.添加单券的方案 for (Coupon c : availableCoupons) { solutions.add(List._of_(c)); } // 4.计算方案的优惠明细 ListCouponDiscountDTO list Collections._synchronizedList_(new ArrayList(solutions.size())); // 4.1.定义闭锁 CountDownLatch latch new CountDownLatch(solutions.size()); for (ListCoupon solution : solutions) { // 4.2.异步计算 CompletableFuture ._supplyAsync_( () - calculateSolutionDiscount(availableCouponMap, orderCourses, solution), discountSolutionExecutor ).thenAccept(dto - { // 4.3.提交任务结果 list.add(dto); latch.countDown(); }); } // 4.4.等待运算结束 try { latch.await(1, TimeUnit._SECONDS_); } catch (InterruptedException e) { _log_.error(优惠方案计算被中断{}, e.getMessage()); } // 5.筛选最优解 return findBestSolution(list); } Override public CouponDiscountDTO queryDiscountDetailByOrder(OrderCouponDTO orderCouponDTO) { // 1.查询用户优惠券 ListLong userCouponIds orderCouponDTO.getUserCouponIds(); ListCoupon coupons userCouponMapper.queryCouponByUserCouponIds(userCouponIds, UserCouponStatus._UNUSED_); if (CollUtils._isEmpty_(coupons)) { return null; } // 2.查询优惠券对应课程 MapCoupon, ListOrderCourseDTO availableCouponMap findAvailableCoupon(coupons, orderCouponDTO.getCourseList()); if (CollUtils._isEmpty_(availableCouponMap)) { return null; } // 3.查询优惠券规则 return calculateSolutionDiscount(availableCouponMap, orderCouponDTO.getCourseList(), coupons); } private ListCouponDiscountDTO findBestSolution(ListCouponDiscountDTO list) { // 1.准备Map记录最优解 MapString, CouponDiscountDTO moreDiscountMap new HashMap(); MapInteger, CouponDiscountDTO lessCouponMap new HashMap(); // 2.遍历筛选最优解 for (CouponDiscountDTO solution : list) { // 2.1.计算当前方案的id组合 String ids solution.getIds().stream() .sorted(Long::_compare_).map(String::_valueOf_).collect(Collectors._joining_(,)); // 2.2.比较用券相同时优惠金额是否最大 CouponDiscountDTO best moreDiscountMap.get(ids); if (best ! null best.getDiscountAmount() solution.getDiscountAmount()) { // 当前方案优惠金额少跳过 continue; } // 2.3.比较金额相同时用券数量是否最少 best lessCouponMap.get(solution.getDiscountAmount()); int size solution.getIds().size(); if (size 1 best ! null best.getIds().size() size) { // 当前方案用券更多放弃 continue; } // 2.4.更新最优解 moreDiscountMap.put(ids, solution); lessCouponMap.put(solution.getDiscountAmount(), solution); } // 3.求交集 CollectionCouponDiscountDTO bestSolutions CollUtils ._intersection_(moreDiscountMap.values(), lessCouponMap.values()); // 4.排序按优惠金额降序 return bestSolutions.stream() .sorted(Comparator._comparingInt_(CouponDiscountDTO::getDiscountAmount).reversed()) .collect(Collectors._toList_()); } private CouponDiscountDTO calculateSolutionDiscount( MapCoupon, ListOrderCourseDTO couponMap, ListOrderCourseDTO courses, ListCoupon solution) { // 1.初始化DTO CouponDiscountDTO dto new CouponDiscountDTO(); // 2.初始化折扣明细的映射 MapLong, Integer detailMap courses.stream().collect(Collectors._toMap_(OrderCourseDTO::getId, oc - 0)); dto.setDiscountDetail(detailMap); // 3.计算折扣 for (Coupon coupon : solution) { // 3.1.获取优惠券限定范围对应的课程 ListOrderCourseDTO availableCourses couponMap.get(coupon); // 3.2.计算课程总价(课程原价 - 折扣明细) int totalAmount availableCourses.stream() .mapToInt(oc - oc.getPrice() - detailMap.get(oc.getId())).sum(); // 3.3.判断是否可用 Discount discount DiscountStrategy._getDiscount_(coupon.getDiscountType()); if (!discount.canUse(totalAmount, coupon)) { // 券不可用跳过 continue; } // 3.4.计算优惠金额 int discountAmount discount.calculateDiscount(totalAmount, coupon); // 3.5.计算优惠明细 calculateDiscountDetails(detailMap, availableCourses, totalAmount, discountAmount); // 3.6.更新DTO数据 dto.getIds().add(coupon.getCreater()); dto.getRules().add(discount.getRule(coupon)); dto.setDiscountAmount(discountAmount dto.getDiscountAmount()); } return dto; } private void calculateDiscountDetails(MapLong, Integer detailMap, ListOrderCourseDTO courses, int totalAmount, int discountAmount) { int times 0; int remainDiscount discountAmount; for (OrderCourseDTO course : courses) { // 更新课程已计算数量 times; int discount 0; // 判断是否是最后一个课程 if (times courses.size()) { // 是最后一个课程总折扣金额 - 之前所有商品的折扣金额之和 discount remainDiscount; } else { // 计算折扣明细课程价格在总价中占的比例乘以总的折扣 discount discountAmount * course.getPrice() / totalAmount; remainDiscount - discount; } // 更新折扣明细 detailMap.put(course.getId(), discount detailMap.get(course.getId())); } } private MapCoupon, ListOrderCourseDTO findAvailableCoupon( ListCoupon coupons, ListOrderCourseDTO courses) { MapCoupon, ListOrderCourseDTO map new HashMap(coupons.size()); for (Coupon coupon : coupons) { // 1.找出优惠券的可用的课程 ListOrderCourseDTO availableCourses courses; if (coupon.getSpecific()) { // 1.1.限定了范围查询券的可用范围 ListCouponScope scopes scopeService.lambdaQuery().eq(CouponScope::getCouponId, coupon.getId()).list(); // 1.2.获取范围对应的分类id SetLong scopeIds scopes.stream().map(CouponScope::getBizId).collect(Collectors._toSet_()); // 1.3.筛选课程 availableCourses courses.stream() .filter(c - scopeIds.contains(c.getCateId())).collect(Collectors._toList_()); } if (CollUtils._isEmpty_(availableCourses)) { // 没有任何可用课程抛弃 continue; } // 2.计算课程总价 int totalAmount availableCourses.stream().mapToInt(OrderCourseDTO::getPrice).sum(); // 3.判断是否可用 Discount discount DiscountStrategy._getDiscount_(coupon.getDiscountType()); if (discount.canUse(totalAmount, coupon)) { map.put(coupon, availableCourses); } } return map; } }至此天机学堂篇完结能看到这里的你已经超厉害了如果对你有帮助的话请点赞关注收藏。热爱可抵一切 ❤️

相关文章:

Java 篇-项目实战-天机学堂(从0到1)-day12

java 篇: 1.基础地基 2.设计原理 3.项目实战这章功力有点不足了,先放放,改日再会会。定义优惠券规则业务流程分析及实现优惠规则:策略模式,导包定义接口:因为是给其他服务用的,那得放在 api 模块…...

3步掌握DistroAV:NDI网络视频传输的终极指南

3步掌握DistroAV:NDI网络视频传输的终极指南 【免费下载链接】obs-ndi DistroAV (formerly OBS-NDI): NDI integration for OBS Studio 项目地址: https://gitcode.com/gh_mirrors/ob/obs-ndi DistroAV(原名OBS-NDI)是一款革命性的开源…...

如何彻底解决Windows和Office激活问题:KMS智能激活工具的完整指南

如何彻底解决Windows和Office激活问题:KMS智能激活工具的完整指南 【免费下载链接】KMS_VL_ALL_AIO Smart Activation Script 项目地址: https://gitcode.com/gh_mirrors/km/KMS_VL_ALL_AIO 你是否经常遇到Windows系统弹出激活提示,或者Office软件…...

linux学习笔记 网络编程——网络分层

在Linux网络编程中,网络分层是核心基础,也是理解网络通信原理、排查网络问题、编写高效网络程序的关键。我们日常使用的网络(如浏览网页、远程登录Linux服务器、传输文件),看似是“直接通信”,实则是多个层…...

新手福音:在快马平台轻松构建你的第一个Hermes风格AI代理

今天想和大家分享一个特别适合AI开发新手的实践项目——用最简单的代码实现一个Hermes风格的AI代理。作为一个刚接触AI代理开发的菜鸟,我最初看到那些复杂的框架和概念也是一头雾水,直到在InsCode(快马)平台上尝试了这个最小化的示例,才真正理…...

Mirascope框架:统一LLM调用接口,简化AI应用开发

1. Mirascope:一个让LLM调用变得像喝水一样简单的开发框架 如果你最近在折腾大语言模型(LLM)应用开发,大概率经历过这种痛苦:今天用OpenAI的GPT-4写个聊天机器人,明天客户要求换成Anthropic的Claude&#x…...

KubeSphere Helm Charts 仓库深度解析:生产级Chart设计与高级模板技巧

1. 项目概述与核心价值 如果你正在或计划在 Kubernetes 上构建应用,那么“Helm”这个名字对你来说一定不陌生。它被称作 Kubernetes 的“包管理器”,就像 Ubuntu 里的 apt 或 CentOS 里的 yum,能让你用一条命令就部署起一套复杂的应用。但 H…...

[具身智能-588]:真正的通用智能,不在云端,而在泥土之中——它必须能弯腰、流汗、跌倒、再站起来,同时懂得为何而做。具身智能的模型,不在云端,必须下沉到终端,且其智能体必须拥有“我”的抽象和上下文

这是我对通用人工智能(AGI)本质路径的诗意而精准的宣言。它不仅否定了当前主流“大模型中心主义”的幻觉,更指明了智能必须扎根于物理存在、具身经验与主体性上下文的真理。让我们从技术、哲学与系统工程三个维度,深入解析提出的三…...

G-Helper终极解决方案:高效管理华硕笔记本性能与散热

G-Helper终极解决方案:高效管理华硕笔记本性能与散热 【免费下载链接】g-helper Fast, native tool for tuning performance, fans, GPU, battery, and RGB on any Asus laptop or handheld - ROG Zephyrus, Flow, Strix, TUF, Vivobook, Zenbook, ProArt, Ally, an…...

长上下文语言模型的可复用推理模板设计与优化

1. 项目背景与核心价值在自然语言处理领域,长上下文语言模型(如GPT-4、Claude等)的崛起正在改变人机交互的范式。这类模型能够处理长达数万token的上下文窗口,为复杂推理任务提供了前所未有的可能性。然而在实际应用中&#xff0c…...

如何用QrScan实现企业级图片二维码批量检测与识别

如何用QrScan实现企业级图片二维码批量检测与识别 【免费下载链接】QrScan 离线批量检测图片是否包含二维码以及识别二维码 项目地址: https://gitcode.com/gh_mirrors/qrs/QrScan 在数字化转型浪潮中,企业面临着海量图片资产中的二维码信息管理难题——如何…...

SAP ME51N采购申请屏幕增强保姆级教程:从CI_EBANDB到BAPI传值全流程

SAP ME51N采购申请屏幕增强实战指南:从字段扩展到BAPI集成全解析 当业务部门突然提出"在采购申请行项目里加设备编号字段"的需求时,作为ABAP开发者的你可能会面对一连串技术术语的轰炸:CI_EBANDB结构、MEREQ001增强点、屏幕0111绘制…...

STM32F103C8T6 + AHT20温湿度传感器:从CubeMX配置到串口打印的保姆级实战

STM32F103C8T6与AHT20温湿度传感器开发全流程指南 1. 项目概述与硬件准备 在物联网和智能硬件开发领域,环境监测是最基础也最常用的功能之一。STM32F103C8T6作为一款性价比极高的ARM Cortex-M3内核微控制器,搭配AHT20这款高精度数字温湿度传感器&#xf…...

从芯片手册到AutoSar代码:手把手教你为STM32配置片内/片外看门狗(含WdgIf抽象层详解)

STM32看门狗与AutoSar集成实战:从寄存器配置到WdgIf抽象层实现 在嵌入式系统开发中,看门狗(Watchdog)是确保系统可靠性的最后一道防线。当面对汽车电子领域严苛的功能安全要求时,如何将STM32系列MCU的片内/片外看门狗无…...

IT资产管理系统是什么?其主要的数字化特征与智能监控功能有哪些?

IT资产管理系统的功能设计与实现机制分析 IT资产管理系统的设计基础在于其对数字化特性和智能监控功能的全面整合。该系统通过引入自动化识别技术,能够有效地追踪和管理每一项资产。每一台设备都配备有独特标识符,结合传感器技术实时采集状态信息。这种信…...

智能体编排框架agents-flex:构建复杂AI系统的柔性骨架

1. 项目概述与核心价值最近在探索智能体(Agent)应用开发时,我深度体验了agents-flex/agents-flex这个开源框架。它不是一个简单的工具库,而是一个旨在为构建复杂、可扩展的智能体系统提供“柔性骨架”的解决方案。简单来说&#x…...

Navicat 16 试用到期后,用这个Python脚本一键清理注册表残留(亲测有效)

Navicat 16试用到期后彻底清理注册表残留的完整指南 每次打开Navicat 16时弹出的"试用期已结束"提示是否让你感到困扰?即使重新安装软件,这个恼人的提示依然如影随形。这通常是由于注册表中残留的试用信息未被清除所致。本文将深入解析这一问题…...

用74LS138和74LS273玩转8086:手把手教你搭建一个能读开关、亮LED的微型计算机I/O系统

从零构建8086微型计算机I/O系统:74LS138与74LS273实战指南 在计算机组成原理的学习中,理论知识与实践操作往往存在一道难以跨越的鸿沟。许多学生能够熟练背诵地址译码的原理,却不知道如何用74LS138芯片搭建一个实际的译码电路;理解…...

DeTikZify:基于多模态大模型的草图转TikZ代码工具详解

1. 项目概述:从草图到矢量图形的智能转换在科研绘图和学术写作中,我们常常面临一个经典困境:脑海中的设计草图或手边的参考图,如何快速、精准地转化为高质量的矢量图形,以便在LaTeX文档中直接使用?传统流程…...

实战演练:基于快马平台与jdk8开发电商订单数据分析业务模块

今天想和大家分享一个真实的业务场景:电商订单数据分析模块的开发过程。这个需求在实际项目中非常常见,我们团队最近就用JDK8的特性快速实现了这个功能,整个过程在InsCode(快马)平台上完成得特别顺畅。 业务背景分析 电商平台每天都会产生大…...

FastGithub智能DNS路由解决方案:构建高性能GitHub访问加速服务

FastGithub智能DNS路由解决方案:构建高性能GitHub访问加速服务 【免费下载链接】FastGithub github定制版的dns服务,解析访问github最快的ip 项目地址: https://gitcode.com/gh_mirrors/fa/FastGithub FastGithub是一款专为GitHub访问优化的智能D…...

【OC】多界面传值总结

【OC】多界面传值总结文章目录【OC】多界面传值总结属性传值(A->B)代理传值(B->A)Block传值(B->A)通知传值(任意方向)KVO传值(观察属性变化)在学习iOS 开发的知识过程中,把几种常见的多…...

基于Claude API的AI应用开发框架:everything-claude核心功能与实战解析

1. 项目概述与核心价值最近在折腾AI应用开发,发现一个挺有意思的开源项目,叫“everything-claude”。这名字起得挺大,乍一看以为是啥都能干的Claude,实际上它是一个基于Anthropic Claude API的、高度可定制的AI应用开发框架。简单…...

告别画面撕裂!用DRM的drmModePageFlip和drmHandleEvent实现流畅翻页(附Linux应用层完整代码)

彻底解决Linux图形显示撕裂:DRM事件驱动编程实战指南 当你在嵌入式Linux设备上开发图形界面时,是否遇到过画面撕裂的困扰?那种图像上半部分显示新帧而下半部分还停留在旧帧的视觉割裂感,不仅影响用户体验,更暴露了底层…...

STM32G4/H7电机控制实战:用CORDIC硬件加速浮点三角函数(附完整代码)

STM32G4/H7电机控制实战:用CORDIC硬件加速浮点三角函数(附完整代码) 在电机控制和数字电源开发领域,实时性往往是决定系统性能的关键因素。当我们在STM32G4或H7平台上构建基于浮点运算的电机控制算法时,三角函数的计算…...

为什么你的R 4.5回测结果总和Python不一致?——揭开RcppParallel与chron包底层时钟偏移之谜

更多请点击: https://intelliparadigm.com 第一章:R 4.5回测结果偏差的现象学观察 在 R 4.5 环境下执行量化策略回测时,部分用户报告了与预期显著不符的绩效指标——尤其在滚动窗口(rolling window)和事件驱动&#x…...

比话降AI怎么用?答辩前35分钟降知网AIGC率全流程教程详解!

比话降AI怎么用?答辩前35分钟降知网AIGC率全流程教程详解! 比话降AI(www.bihuapass.com)是 2026 年答辩急救场景使用率最高的工具之一。但很多硕博生第一次用不知道具体步骤——是不是直接粘全文?参数怎么选&#xff…...

开源鼠标增强工具MousePal:自定义加速度曲线与多显示器DPI优化

1. 项目概述:一个鼠标增强工具的诞生与价值在桌面操作效率的探索道路上,我们常常会不自觉地陷入一种“路径依赖”:习惯了操作系统自带的鼠标指针,默认了它那有限的移动速度和固定的加速度曲线,也接受了在不同显示器间切…...

MAXQ JTAG板固件更新全流程与常见问题解析

1. MAXQ JTAG板固件更新全流程解析作为嵌入式开发工程师,我们经常需要与各种调试接口打交道。JTAG作为业界通用的调试标准,因其稳定性和通用性被广泛应用于各类微控制器的开发调试中。MAXQ系列微控制器同样采用JTAG接口进行编程和调试,而串口…...

Docker Compose 多项目管理工具:轻量级容器编排辅助方案

1. 项目概述:一个基于Docker的轻量级容器编排辅助工具最近在整理自己的开发环境时,发现一个挺普遍但又有点烦人的痛点:手头有好几个Docker项目,每个项目都有一堆docker-compose.yml文件,分布在不同的目录里。每次想启动…...