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
}
这样我们的一个单体应用
就完成了,掌声!!!