多模块
product-server 所有业务逻辑 controller、service……
product-client 对外暴露的接口、商品列表、扣库存。
product-common 公用的对象,既能被外部服务调用,也能被内部其他模块使用。
Ps:多模块最重要的难点就是 pom.xml 配置的问题。
All Pom.xml
4.0.0
com.imooc
product
0.0.1-SNAPSHOT
common
server
client
pom
product
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
2.0.0.M3
UTF-8
UTF-8
1.8
Finchley.M2
0.0.1-SNAPSHOT
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
com.imooc
product-common
${product-common.version}
org.springframework.cloud
spring-cloud-starter-openfeign
2.0.0.M3
spring-snapshots
Spring Snapshots
https://repo.spring.io/snapshot
true
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
spring-snapshots
Spring Snapshots
https://repo.spring.io/snapshot
true
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
Pom.xml
product
com.imooc
0.0.1-SNAPSHOT
4.0.0
product-server
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-data-jpa
mysql
mysql-connector-java
org.projectlombok
lombok
com.imooc
product-common
org.springframework.boot
spring-boot-maven-plugin
package com.imooc.product.controller;
import com.imooc.product.VO.ProductInfoVO;
import com.imooc.product.VO.ProductVO;
import com.imooc.product.VO.ResultVO;
import com.imooc.product.dataobject.ProductCategory;
import com.imooc.product.dataobject.ProductInfo;
import com.imooc.product.service.CategoryService;
import com.imooc.product.service.ProductService;
import com.imooc.product.utils.ResultVOUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import com.imooc.product.common.DecreaseStockInput;
import com.imooc.product.common.ProductInfoOutput;
/**
* 商品
*/
@RestController
@RequestMapping("/product")
public class ProductController {
@Autowired
private ProductService productService;
@Autowired
private CategoryService categoryService;
/**
* 1. 查询所有在架的商品
* 2. 获取类目type列表
* 3. 查询类目
* 4. 构造数据
*/
@GetMapping("/list")
public ResultVO list() {
//1. 查询所有在架的商品
List productInfoList = productService.findUpAll();
//2. 获取类目type列表
List categoryTypeList = productInfoList.stream()
.map(ProductInfo::getCategoryType)
.collect(Collectors.toList());
//3. 从数据库查询类目
List categoryList = categoryService.findByCategoryTypeIn(categoryTypeList);
//4. 构造数据
List productVOList = new ArrayList<>();
for (ProductCategory productCategory: categoryList) {
ProductVO productVO = new ProductVO();
productVO.setCategoryName(productCategory.getCategoryName());
productVO.setCategoryType(productCategory.getCategoryType());
List productInfoVOList = new ArrayList<>();
for (ProductInfo productInfo: productInfoList) {
if (productInfo.getCategoryType().equals(productCategory.getCategoryType())) {
ProductInfoVO productInfoVO = new ProductInfoVO();
BeanUtils.copyProperties(productInfo, productInfoVO);
productInfoVOList.add(productInfoVO);
}
}
productVO.setProductInfoVOList(productInfoVOList);
productVOList.add(productVO);
}
return ResultVOUtil.success(productVOList);
}
/**
* 获取商品列表(给订单服务用的)
* @param productIdList
* @return
*/
@PostMapping("/listForOrder")
public List listForOrder(@RequestBody List productIdList) {
return productService.findList(productIdList);
}
@PostMapping("/decreaseStock")
public void decreaseStock(@RequestBody List decreaseStockInputList) {
productService.decreaseStock(decreaseStockInputList);
}
}
package com.imooc.product;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
Pom.xml
product
com.imooc
0.0.1-SNAPSHOT
4.0.0
product-common
org.projectlombok
lombok
package com.imooc.product.common;
import lombok.Data;
/**
* 减库存入参
*/
@Data
public class DecreaseStockInput {
private String productId;
private Integer productQuantity;
public DecreaseStockInput() {
}
public DecreaseStockInput(String productId, Integer productQuantity) {
this.productId = productId;
this.productQuantity = productQuantity;
}
}
package com.imooc.product.common;
import lombok.Data;
import java.math.BigDecimal;
@Data
public class ProductInfoOutput {
private String productId;
/** 名字. */
private String productName;
/** 单价. */
private BigDecimal productPrice;
/** 库存. */
private Integer productStock;
/** 描述. */
private String productDescription;
/** 小图. */
private String productIcon;
/** 状态, 0正常1下架. */
private Integer productStatus;
/** 类目编号. */
private Integer categoryType;
}
Pom.xml
product
com.imooc
0.0.1-SNAPSHOT
4.0.0
product-client
org.springframework.cloud
spring-cloud-netflix-core
org.springframework
spring-web
com.imooc
product-common
package com.imooc.product.client;
import com.imooc.product.common.DecreaseStockInput;
import com.imooc.product.common.ProductInfoOutput;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import java.util.List;
@FeignClient(name = "product")
public interface ProductClient {
@PostMapping("/product/listForOrder")
List listForOrder(@RequestBody List productIdList);
@PostMapping("/product/decreaseStock")
void decreaseStock(@RequestBody List decreaseStockInputList);
}
All Pom.xml
4.0.0
com.imooc
order
0.0.1-SNAPSHOT
client
common
server
pom
order
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
2.0.0.M3
UTF-8
UTF-8
1.8
Finchley.M2
0.0.1-SNAPSHOT
0.0.1-SNAPSHOT
org.springframework.cloud
spring-cloud-dependencies
${spring-cloud.version}
pom
import
com.imooc
product-client
${product-client.version}
com.imooc
order-common
${order-common.version}
org.springframework.cloud
spring-cloud-starter-openfeign
2.0.0.M3
spring-snapshots
Spring Snapshots
https://repo.spring.io/snapshot
true
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
spring-snapshots
Spring Snapshots
https://repo.spring.io/snapshot
true
spring-milestones
Spring Milestones
https://repo.spring.io/milestone
false
pom.xml
order
com.imooc
0.0.1-SNAPSHOT
4.0.0
order-server
org.springframework.cloud
spring-cloud-starter-netflix-eureka-client
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-data-jpa
mysql
mysql-connector-java
org.projectlombok
lombok
com.google.code.gson
gson
org.springframework.cloud
spring-cloud-starter-feign
com.imooc
product-client
com.imooc
order-common
org.springframework.boot
spring-boot-maven-plugin
package com.imooc.order;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients(basePackages = "com.imooc.product.client")
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
}
package com.imooc.order.service.impl;
import com.imooc.order.dataobject.OrderDetail;
import com.imooc.order.dataobject.OrderMaster;
import com.imooc.order.dto.OrderDTO;
import com.imooc.order.enums.OrderStatusEnum;
import com.imooc.order.enums.PayStatusEnum;
import com.imooc.order.repository.OrderDetailRepository;
import com.imooc.order.repository.OrderMasterRepository;
import com.imooc.order.service.OrderService;
import com.imooc.order.utils.KeyUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.List;
import java.util.stream.Collectors;
import com.imooc.product.client.ProductClient;
import com.imooc.product.common.DecreaseStockInput;
import com.imooc.product.common.ProductInfoOutput;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderDetailRepository orderDetailRepository;
@Autowired
private OrderMasterRepository orderMasterRepository;
@Autowired
private ProductClient productClient;
@Override
public OrderDTO create(OrderDTO orderDTO) {
String orderId = KeyUtil.genUniqueKey();
//查询商品信息(调用商品服务)
List productIdList = orderDTO.getOrderDetailList().stream()
.map(OrderDetail::getProductId)
.collect(Collectors.toList());
List productInfoList = productClient.listForOrder(productIdList);
//计算总价
BigDecimal orderAmout = new BigDecimal(BigInteger.ZERO);
for (OrderDetail orderDetail: orderDTO.getOrderDetailList()) {
for (ProductInfoOutput productInfo: productInfoList) {
if (productInfo.getProductId().equals(orderDetail.getProductId())) {
//单价*数量
orderAmout = productInfo.getProductPrice()
.multiply(new BigDecimal(orderDetail.getProductQuantity()))
.add(orderAmout);
BeanUtils.copyProperties(productInfo, orderDetail);
orderDetail.setOrderId(orderId);
orderDetail.setDetailId(KeyUtil.genUniqueKey());
//订单详情入库
orderDetailRepository.save(orderDetail);
}
}
}
//扣库存(调用商品服务)
List decreaseStockInputList = orderDTO.getOrderDetailList().stream()
.map(e -> new DecreaseStockInput(e.getProductId(), e.getProductQuantity()))
.collect(Collectors.toList());
productClient.decreaseStock(decreaseStockInputList);
//订单入库
OrderMaster orderMaster = new OrderMaster();
orderDTO.setOrderId(orderId);
BeanUtils.copyProperties(orderDTO, orderMaster);
orderMaster.setOrderAmount(orderAmout);
orderMaster.setOrderStatus(OrderStatusEnum.NEW.getCode());
orderMaster.setPayStatus(PayStatusEnum.WAIT.getCode());
orderMasterRepository.save(orderMaster);
return orderDTO;
}
}
pom.xml
order
com.imooc
0.0.1-SNAPSHOT
4.0.0
order-common
org.projectlombok
lombok
pom.xml
order
com.imooc
0.0.1-SNAPSHOT
4.0.0
order-client