springcloud之项目实战搭建单体
写在前面
在上篇文章 中我们介绍了项目的整体内容以及架构,本文就开始实现一个单体的版本,在之后的文章中,在使用springcloud相关组件将这个单体的版本一步步的拆分为微服务的版本,在开始之前再贴下组件图:

本文我们分别来实现这四个组件。
源码 。
1:优惠券模板服务
完成后结构如下图:

1.1:api
定义服务请求和相应需要用到的公共的beans,单独定义的好处是,如果需要用到的话,单独引用即可,不需要引入其他不需要的类。
首先来定义优惠券类型的枚举:
@Getter
@AllArgsConstructor
public enum CouponType {UNKNOWN("unknown", "0"),MONEY_OFF("满减券", "1"),DISCOUNT("打折", "2"),RANDOM_DISCOUNT("随机减", "3"),LONELY_NIGHT_MONEY_OFF("晚间双倍优惠券", "4");private String description;// 存在数据库里的最终codeprivate String code;public static CouponType convert(String code) {// .orElse(UNKNOWN) 避免有人使坏return Stream.of(values()).filter(bean -> bean.code.equalsIgnoreCase(code)).findFirst().orElse(UNKNOWN);}
}
然后定义优惠券模板类:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CouponTemplateInfo {private Long id;@NotNullprivate String name;// 优惠券描述@NotNullprivate String desc;// 优惠券类型@NotNullprivate String type;// 适用门店 - 若无则为全店通用券private Long shopId;/** 优惠券规则 */@NotNullprivate TemplateRule rule;private Boolean available;}
优惠券类:
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class CouponInfo {private Long id;private Long templateId;private Long userId;private Long shopId;private Integer status;private CouponTemplateInfo template;}
具体的参考源码。
1.2:dao
采用spring data jpa 约定由于配置,提高生产力!。dao继承JpaRepositry,拥有基础的增删改查功能:
/*** coupon_template 表的spring data jpa(构建在hibernate之上的db操作框架)接口* https://blog.csdn.net/wang0907/article/details/131550318*/
public interface CouponTemplateDaoextends JpaRepository<CouponTemplate, Long> {// 根据Shop ID查询出所有券模板List<CouponTemplate> findAllByShopId(Long shopId);// IN查询 + 分页支持的语法Page<CouponTemplate> findAllByIdIn(List<Long> Id, Pageable page);// 根据shop ID + 可用状态查询店铺有多少券模板Integer countByShopIdAndAvailable(Long shopId, Boolean available);// 将优惠券设置为不可用@Modifying@Query("update CouponTemplate c set c.available = 0 where c.id = :id")int makeCouponUnavailable(@Param("id") Long id);
}
1.3:controller
定义模板模块对外的接口:
@Slf4j
@RestController
@RequestMapping("/template")
public class CouponTemplateController {@Autowiredprivate CouponTemplateService couponTemplateService;// 创建优惠券@PostMapping("/addTemplate")public CouponTemplateInfo addTemplate(@Valid @RequestBody CouponTemplateInfo request) {log.info("Create coupon template: data={}", request);return couponTemplateService.createTemplate(request);}...
}
测试如下,则为成功:

2:优惠券计算模块

2.1:api
定义其他模块可能用到的pojo,具体参考源码。
2.2:calculator
具体计算模块,定义各种优惠券的计算服务,主要的技术点是采用了模板方法设计模式 ,类图如下:

具体参考源码。
测试如下,则为成功:

json:
{"products":[{"price":3000,"count":2,"shopId":3},{"price":1000,"count":4,"shopId":1}],"couponId":10,"couponInfos":[{"id":10,"templateId":2,"userId":null,"shopId":null,"template":{"name":"单店满减","desc":"满40减5","type":"1","available":true,"shopId":1,"rule":{"limitation":10,"discount":{"quota":500,"threshold":4000}}}}],"userId":1}
3:用户服务

在pom中需要引入template和calculator,这样我们就有了一个三合一的单体应用了(后面我们来一起改造它!!!)。
3.1:api
定义用到的pojo,具体看源码。
3.2:dao
具体看源码。
3.2:impl
定义接口,服务层代码,定义用户领券,删除券等操作,如下用户领券代码:
@PostMapping("requestCoupon")
public Coupon requestCoupon(@Valid @RequestBody RequestCoupon request) {return customerService.requestCoupon(request);
}
启动后测试领券:
{"userId": 1,"couponTemplateId": 2
}


优惠券试算:
{"products": [{"price": 3000,"count": 2,"shopId": 3},{"price": 1000,"count": 10,"shopId": 1}],"couponIDs": [1],"userId": 1
}

这样我们的一个单体应用就完成了,掌声!!!
4:平台组建
写在后面
参考文章列表
相关文章:
springcloud之项目实战搭建单体
写在前面 在上篇文章 中我们介绍了项目的整体内容以及架构,本文就开始实现一个单体的版本,在之后的文章中,在使用springcloud相关组件将这个单体的版本一步步的拆分为微服务的版本,在开始之前再贴下组件图: 本文我们分…...
Mac 点击桌面 出现黑边框 解决
1、桌面黑框效果 2、解决:设置为 仅在台前调度中...
深度学习(2)---循环神经网络(RNN)
文章目录 一、序列数据和语言模型1.1 序列数据1.2 语言模型 二、循环神经网络(RNN)2.1 概述2.2 门控循环单元(GRU)2.3 长短期记忆网络(LSTM) 一、序列数据和语言模型 1.1 序列数据 1. 在深度学习中,序列数据(Sequence data)是指具有前后顺序…...
[NOIP2010 提高组] 机器翻译
[NOIP2010 提高组] 机器翻译 题目背景 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章。 题目描述 这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换。对于每个英文单词…...
配置文件生成器-秒杀SSM的xml整合
配置文件生成器-秒杀SSM的xml整合 思路: 通过简单的配置,直接生成对应配置文件。 maven坐标 <dependencies><!-- 配置文件生成 --><dependency><groupId>org.freemarker</groupId><artifactId>freemarker<…...
小黑开始了拉歌训练,第一次进入部室馆,被通知要去当主持人心里有些紧张的leetcode之旅:337. 打家劫舍 III
小黑代码(小黑卡在了bug中,上午一步步探索做出,非常NB!!!) # Definition for a binary tree node. # class TreeNode: # def __init__(self, val0, leftNone, rightNone): # self.val val # self.left lef…...
flutter开发实战-inappwebview实现flutter与Javascript方法调用
flutter开发实战-inappwebview实现flutter与Javascript方法调用 在使用inappwebview时候,需要flutter端与JS进行交互,调用相应的方法,在inappwebview中的JavaScript Handlers。 一、JavaScript Handlers 要添加JavaScript Handlers&#…...
alsa pcm设备之硬件参数
硬件参数包含了stream描述比如格式,采样率,通道数,和ringbuffer 圆形缓存区大小等. 使用snd_pcm_hw_params_t ,ALSA pcm设备使用了参数重定义系统相关的硬件参数,应用程序首先选择全范围的配置, 然后应用程序设置单个参数,直到所有参数都是基本的(确定的). 格式 量化位數&#…...
websocket拦截
python实现websocket拦截 前言一、拦截的优缺点优点缺点二、实现方法1.环境配置2.代码三、总结现在的直播间都是走的websocket通信,想要获取websocket通信的内容就需要使用websocket拦截,大多数是使用中间人代理进行拦截,这里将会使用更简单的方式进行拦截。 前言 开发者工…...
深度强化学习之 PPO 算法
深度强化学习之 PPO 算法 强化学习原理学习策略 基于行为价值 & 基于行为概率策略梯度算法:计算状态下所有行为的概率演员 - 评论家算法:一半基于行为价值,一半基于行为概率DQN 算法(深度Q网络)Q-Learning&#x…...
iPhone升级iOS17出现无法连接互联网的错误提示怎么办?
最新的iOS 17系统已经发布了快一个月了,很多人都已升级体验更多全新功能,但有部分用户却在升级过程中遇到一些问题:如无法验证更新,iOS17验证失败,因为您不再连接到互联网、 iPhone无法检查更新等错误问题。明明网络稳…...
Spring:处理@Autowired和@Value注解的BeanPostProcessor
AutowiredAnnotationBeanPostProcessor,它实现了MergedBeanDefinitionPostProcessor,因此会调用postProcessMergedBeanDefinition方法。 它实现了InstantiationAwareBeanPostProcessor,因此在属性注入时会调用postProcessPropertyValues方法 如果Autowired注解按类型找到了大…...
极坐标系下的交换积分次序
极坐标系下的交换积分次序 我把极坐标系下的交换积分次序总结为动静与静动之间的转换,下面通过一个例子感受一下 ρ 1 、 ρ 1 cos θ \rho1、\rho1\cos\theta ρ1、ρ1cosθ ∫ 0 π / 2 d θ ∫ 1 1 cos θ f ( ρ cos θ , ρ sin θ ) ρ d…...
MySQL命令行中文乱码问题
MySQL命令行中文乱码问题: 命令行界面默认字符集是gbk,若字符集不匹配会中文乱码或无法插入中文。 解决办法:执行set names gbk; 验证: 执行命令show variables like ‘char%’;查看默认字符集。 创建数据库设置字符集utf8&…...
图论---图的遍历
在图论中,图的遍历一般有两种,分别为DFS(深度优先遍历)、BFS(广度优先遍历),以下是这两种遍历方式的模板: DFS(深度优先搜索) 代码框架: void …...
AM@无穷小和无穷大
文章目录 abstract本文符号说明无穷小无穷小和自变量变化过程无穷小和函数极限的关系定理👺证明 无穷大无穷大不是数极限无穷大的说法证明函数极限为无穷大 无穷大和无穷小见的关系定理无穷小无穷大的运算法则 abstract 无穷小和无穷大的概念和相关性质 本文符号说…...
玄子Share- IDEA 2023 SpringBoot 热部署
玄子Share- IDEA 2023 SpringBoot 热部署 修改 IDEA 部署设置 IDEA 勾选如下选项 新建 SpringBoot 项目 项目构建慢的将 Spring Initializr 服务器 URL 改为阿里云:https://start.aliyun.com/ 在这里直接勾选Spring Boot Devtools插件即可 测试 切出 IDEA 项目文…...
kafka集群工作机制
一、kafka在zookeeper上的元数据解释 kafka中的broker要选举Controller角色来管理整个kafka集群中的分区和副本状态。一个Topic下多个partition要选举Leader角色和客户端进行交互数据 Zookeeper客户端工具: prettyZoo。 下载地址:https://github.com/vr…...
JVM上篇之虚拟机与java虚拟机介绍
目录 虚拟机 java虚拟机 简介 特点 作用 位置 整体结构 类装载子系统 运行时数据区 java执行引擎 Java代码执行流程 jvm架构模型 基于栈式架构 基于寄存器架构 总结 jvm的生命周期 1.启动 2.执行 3.退出 JVM的发展历程 虚拟机 所谓虚拟机,指的…...
在公众号上怎么创建微信付费课程功能呢
微信付费课程功能是一项比较受欢迎的在线教育服务,可以帮助教育机构或个人更好地管理和销售课程资源,提高知识分享和变现的效率。下面将介绍如何创建微信付费课程功能。 一、了解微信付费课程功能 在创建微信付费课程功能之前,需要先了解微信…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
使用分级同态加密防御梯度泄漏
抽象 联邦学习 (FL) 支持跨分布式客户端进行协作模型训练,而无需共享原始数据,这使其成为在互联和自动驾驶汽车 (CAV) 等领域保护隐私的机器学习的一种很有前途的方法。然而,最近的研究表明&…...
相机从app启动流程
一、流程框架图 二、具体流程分析 1、得到cameralist和对应的静态信息 目录如下: 重点代码分析: 启动相机前,先要通过getCameraIdList获取camera的个数以及id,然后可以通过getCameraCharacteristics获取对应id camera的capabilities(静态信息)进行一些openCamera前的…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)
目录 一、👋🏻前言 二、😈sinx波动的基本原理 三、😈波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、🌊波动优化…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...
