谷粒商城笔记合集
十四、仓储服务&仓库维护⚠️
14.1 后端开发:整合仓储服务⚠️
-
修改 网关服务 的路由配置并重启:application.yaml
spring: cloud: gateway: routes: - id: ware_route uri: lb://bilimall-ware predicates: - Path=/api/ware/** filters: - RewritePath=/api/?(?<segment>.*),/$\{segment}
-
修改 仓储服务 的配置文件:注册中心、配置中心、服务名、Mybatis等
spring: datasource: username: root password: bilimall url: jdbc:mysql://114.132.162.129:3306/bilimall_wms?useUnicode=true&characterEncoding=utf-8&useSSL=false driver-class-name: com.mysql.cj.jdbc.Driver cloud: nacos: discovery: server-addr: 114.132.162.129:8848 application: name: bilimall-ware jackson: date-format: yyyy-MM-dd HH:mm:ss mybatis-plus: # mapper文件扫描:不仅扫描我的类路径,还包括依赖的其他类路径 mapper-locations: classpath*:/mapper/**/*.xml global-config: db-config: id-type: auto # 数据库主键自增 server: port: 12000 logging: level: cn.lzwei: debug
-
修改 仓储服务 的主启动类:cn/lzwei/bilimall/ware/BilimallWareApplication.java
@EnableTransactionManagement @EnableFeignClients(basePackages = "cn.lzwei.bilimall.ware.feign") @EnableDiscoveryClient @MapperScan("cn.lzwei.bilimall.ware.dao") @SpringBootApplication public class BilimallWareApplication { public static void main(String[] args) { SpringApplication.run(BilimallWareApplication.class, args); } }
14.2 API:查询 仓库列表
-
WareInfoController:查询仓库列表
@RestController @RequestMapping("ware/wareinfo") public class WareInfoController { @Autowired private WareInfoService wareInfoService; /** * 查询仓库列表:模糊查询 */ @RequestMapping("/list") public R list(@RequestParam Map<String, Object> params){ PageUtils page = wareInfoService.queryPage(params); return R.ok().put("page", page); } }
-
WareInfoService:查询仓库列表
public interface WareInfoService extends IService<WareInfoEntity> { PageUtils queryPage(Map<String, Object> params); }
-
WareInfoServiceImpl:查询仓库列表
@Service("wareInfoService") public class WareInfoServiceImpl extends ServiceImpl<WareInfoDao, WareInfoEntity> implements WareInfoService { @Override public PageUtils queryPage(Map<String, Object> params) { QueryWrapper<WareInfoEntity> queryWrapper = new QueryWrapper<>(); String key = (String) params.get("key"); if(!StringUtils.isNullOrEmpty(key)){ queryWrapper.and(item->{ item.eq("id",key).or().like("name",key).or().like("areacode",key); }); } IPage<WareInfoEntity> page = this.page( new Query<WareInfoEntity>().getPage(params), queryWrapper ); return new PageUtils(page); } }
14.3 API:查询 商品库存
-
WareSkuController:查询商品库存列表
@RestController @RequestMapping("ware/waresku") public class WareSkuController { @Autowired private WareSkuService wareSkuService; /** * 查询商品库存列表:仓库、指定商品 */ @RequestMapping("/list") public R list(@RequestParam Map<String, Object> params){ PageUtils page = wareSkuService.queryPage(params); return R.ok().put("page", page); } }
-
WareSkuService:查询商品库存列表
public interface WareSkuService extends IService<WareSkuEntity> { /** * 查询商品库存列表:仓库、指定商品 */ PageUtils queryPage(Map<String, Object> params); }
-
WareSkuServiceImpl:查询商品库存列表
@Service("wareSkuService") public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService { /** * 查询商品库存列表:仓库、指定商品 */ @Override public PageUtils queryPage(Map<String, Object> params) { QueryWrapper<WareSkuEntity> queryWrapper = new QueryWrapper<>(); //1.仓库 String wareId = (String) params.get("wareId"); if(!StringUtils.isNullOrEmpty(wareId)){ queryWrapper.eq("ware_id",wareId); } //2.指定商品 String skuId = (String) params.get("skuId"); if(!StringUtils.isNullOrEmpty(skuId)){ queryWrapper.eq("sku_id",skuId); } IPage<WareSkuEntity> page = this.page( new Query<WareSkuEntity>().getPage(params), queryWrapper ); return new PageUtils(page); } }
14.4 API:查询 采购需求
-
PurchaseDetailController
@RestController @RequestMapping("ware/purchasedetail") public class PurchaseDetailController { @Autowired private PurchaseDetailService purchaseDetailService; /** * 查询采购需求列表:模糊查询、状态、指定仓库 */ @RequestMapping("/list") public R list(@RequestParam Map<String, Object> params){ PageUtils page = purchaseDetailService.queryPage(params); return R.ok().put("page", page); } }
-
PurchaseDetailService
public interface PurchaseDetailService extends IService<PurchaseDetailEntity> { /** * 查询采购需求列表:模糊查询、状态、指定仓库 */ PageUtils queryPage(Map<String, Object> params); }
-
PurchaseDetailServiceImpl
@Service("purchaseDetailService") public class PurchaseDetailServiceImpl extends ServiceImpl<PurchaseDetailDao, PurchaseDetailEntity> implements PurchaseDetailService { /** * 查询采购需求列表:模糊查询、状态、指定仓库 */ @Override public PageUtils queryPage(Map<String, Object> params) { QueryWrapper<PurchaseDetailEntity> queryWrapper = new QueryWrapper<>(); //1.模糊查询 String key = (String) params.get("key"); if (!StringUtils.isNullOrEmpty(key)){ queryWrapper.and(item->{ item.eq("purchase_id",key).or().eq("id",key).or().eq("sku_id",key); }); } //2.状态 String status = (String) params.get("status"); if (!StringUtils.isNullOrEmpty(status)){ queryWrapper.eq("status",status); } //3.指定仓库 String wareId = (String) params.get("wareId"); if (!StringUtils.isNullOrEmpty(wareId)){ queryWrapper.eq("ware_id",wareId); } IPage<PurchaseDetailEntity> page = this.page( new Query<PurchaseDetailEntity>().getPage(params), queryWrapper ); return new PageUtils(page); } }
14.5 API:新增 采购单
新增采购单,同时保存相关时间信息:PurchaseController
@RestController
@RequestMapping("ware/purchase")
public class PurchaseController {
@Autowired
private PurchaseService purchaseService;
/**
* 保存
*/
@RequestMapping("/save")
public R save(@RequestBody PurchaseEntity purchase){
purchase.setCreateTime(new Date());
purchase.setUpdateTime(new Date());
purchaseService.save(purchase);
return R.ok();
}
}
14.5 API:合并采购需求⚠️
14.5.1 查询 可被合并到的采购单
-
PurchaseController
@RestController @RequestMapping("ware/purchase") public class PurchaseController { @Autowired private PurchaseService purchaseService; /** * 获取采购单列表:状态为 新建、已分配 */ @GetMapping("/unreceive/list") public R unrecivePurchase(@RequestParam Map<String, Object> params){ PageUtils page=purchaseService.getUnrecivePurchase(params); return R.ok().put("page",page); } }
-
PurchaseService
public interface PurchaseService extends IService<PurchaseEntity> { /** * 获取采购单列表:状态为 新建、已分配 */ PageUtils getUnrecivePurchase(Map<String, Object> params); }
-
PurchaseServiceImpl
@Service("purchaseService") public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService { /** * 获取采购单列表:状态为 新建、已分配 */ @Override public PageUtils getUnrecivePurchase(Map<String, Object> params) { QueryWrapper<PurchaseEntity> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("status",0).or().eq("status",1); IPage<PurchaseEntity> page = this.page( new Query<PurchaseEntity>().getPage(params), queryWrapper ); return new PageUtils(page); } }
14.5.2 合并采购需求⚠️
-
在 公共服务 中创建 采购单、采购需求 状态的枚举常量类:cn/lzwei/common/constant/WareConstant.java
public class WareConstant { //采购单状态 public enum PurchaseType{ CREATE(0,"新建"),ASSIGNED(1,"已分配"), RECEIVED(2,"已领取"),FINISHED(3,"已完成"), HASEXECPTION(4,"有异常"); private Integer code; private String msg; PurchaseType(Integer code,String msg){ this.code=code; this.msg=msg; } public Integer getCode() { return code; } public String getMsg() { return msg; } } //采购需求状态 public enum PurchaseDetailType{ CREATE(0,"新建"),ASSIGNED(1,"已分配"), BUYING(2,"正在采购"),FINISHED(3,"已完成"), FAILED(4,"采购失败"); private Integer code; private String msg; PurchaseDetailType(Integer code,String msg){ this.code=code; this.msg=msg; } public Integer getCode() { return code; } public String getMsg() { return msg; } } }
-
在 仓储服务 中创建用来接收请求的VO:cn/lzwei/bilimall/ware/vo/MergePurchaseVo.java
@Data public class MergePurchaseVo { //采购单id private Long purchaseId; //采购需求列表 private List<Long> items; }
-
PurchaseController:合并采购需求
@RestController @RequestMapping("ware/purchase") public class PurchaseController { @Autowired private PurchaseService purchaseService; /** * 合并采购需求:1.指定采购单,更新对应的采购需求以及采购单信息;2.无指定采购单,创建采购单并更新采购需求以及采购单信息 */ @PostMapping("/merge") public R mergePurchase(@RequestBody MergePurchaseVo mergePurchaseVo){ purchaseService.mergePurchase(mergePurchaseVo); return R.ok(); } }
-
PurchaseService:合并采购需求
public interface PurchaseService extends IService<PurchaseEntity> { /** * 合并采购需求:1.指定采购单,更新对应的采购需求以及采购单信息;2.无指定采购单,创建采购单并更新采购需求以及采购单信息 */ void mergePurchase(MergePurchaseVo mergePurchaseVo); }
-
PurchaseServiceImpl:合并采购需求
@Service("purchaseService") public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService { @Resource PurchaseDetailService purchaseDetailService; /** * 合并采购需求:1.指定采购单,更新对应的采购需求以及采购单信息;2.无指定采购单,创建采购单并更新采购需求以及采购单信息 */ @Transactional @Override public void mergePurchase(MergePurchaseVo mergePurchaseVo) { //判断是否有指定采购单 Long purchaseId = mergePurchaseVo.getPurchaseId(); if(purchaseId==null){ //新建采购单 PurchaseEntity purchaseEntity = new PurchaseEntity(); purchaseEntity.setCreateTime(new Date()); purchaseEntity.setUpdateTime(new Date()); purchaseEntity.setStatus(WareConstant.PurchaseType.CREATE.getCode()); //新建状态 this.save(purchaseEntity); purchaseId=purchaseEntity.getId(); } //TODO 确认采购单状态是0、1才可以合并 //1.获取采购单集合 List<Long> items = mergePurchaseVo.getItems(); Long finalPurchaseId = purchaseId; List<PurchaseDetailEntity> purchaseDetailEntities = items.stream().map(item -> { PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity(); purchaseDetailEntity.setId(item); purchaseDetailEntity.setPurchaseId(finalPurchaseId); purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailType.ASSIGNED.getCode()); return purchaseDetailEntity; }).collect(Collectors.toList()); //2.更新采购需求上的采购单id和状态 purchaseDetailService.updateBatchById(purchaseDetailEntities); //3.修改采购单的更新时间 PurchaseEntity purchaseEntity = new PurchaseEntity(); purchaseEntity.setId(finalPurchaseId); purchaseEntity.setUpdateTime(new Date()); this.updateById(purchaseEntity); } }
14.6 API:模拟领取采购单💡
-
PurchaseController:模拟领取采购单
@RestController @RequestMapping("ware/purchase") public class PurchaseController { @Autowired private PurchaseService purchaseService; /** * 模拟领取采购单:需要验证采购单、采购需求的状态 */ @PostMapping("/received") public R receivedPurchase(@RequestBody List<Long> ids){ purchaseService.receivedPurchase(ids); return R.ok(); } }
-
PurchaseService:模拟领取采购单
public interface PurchaseService extends IService<PurchaseEntity> { /** * 模拟领取采购单:需要验证采购单、采购需求的状态 */ void receivedPurchase(List<Long> ids); }
-
PurchaseServiceImpl:模拟领取采购单
@Service("purchaseService") public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService { @Resource PurchaseDetailService purchaseDetailService; /** * 模拟领取采购单:需要验证采购单、采购需求的状态 */ @Transactional @Override public void receivedPurchase(List<Long> ids) { //1.验证采购单状态:只有新建、已分配的采购单可以被领取 List<PurchaseEntity> purchaseEntities = ids.stream().map(item -> { PurchaseEntity purchaseEntity = this.getById(item); return purchaseEntity; }).filter(item->{ Integer status = item.getStatus(); if(status==WareConstant.PurchaseType.CREATE.getCode() || status==WareConstant.PurchaseType.ASSIGNED.getCode()){ return true; } return false; }).map(item->{ //2.更新采购单状态、更新时间 item.setStatus(WareConstant.PurchaseType.RECEIVED.getCode()); item.setUpdateTime(new Date()); return item; }).collect(Collectors.toList()); this.updateBatchById(purchaseEntities); //遍历每一份采购单 for (PurchaseEntity purchaseEntity : purchaseEntities) { //3.获取采购单下的采购需求:状态必须为新建、已分配 Long id = purchaseEntity.getId(); List<PurchaseDetailEntity> purchaseDetailEntities = purchaseDetailService.listDetailByPurchaseId(id); List<PurchaseDetailEntity> collect = purchaseDetailEntities.stream().map(item -> { PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity(); purchaseDetailEntity.setId(item.getId()); purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailType.BUYING.getCode()); return purchaseDetailEntity; }).collect(Collectors.toList()); //4.更新采购需求的状态 purchaseDetailService.updateBatchById(collect); } } }
-
PurchaseDetailService:获取采购单下新建或已分配状态的采购需求
public interface PurchaseDetailService extends IService<PurchaseDetailEntity> { /** * 获取采购单下新建或已分配状态的采购需求:用于领取采购单 */ List<PurchaseDetailEntity> listDetailByPurchaseId(Long id); }
-
PurchaseDetailServiceImpl:获取采购单下新建或已分配状态的采购需求
@Service("purchaseDetailService") public class PurchaseDetailServiceImpl extends ServiceImpl<PurchaseDetailDao, PurchaseDetailEntity> implements PurchaseDetailService { /** * 获取采购单下新建或已分配状态的采购需求:用于领取采购单 */ @Override public List<PurchaseDetailEntity> listDetailByPurchaseId(Long id) { //获取采购单下新建或已分配状态的采购需求 QueryWrapper<PurchaseDetailEntity> queryWrapper = new QueryWrapper<PurchaseDetailEntity>() .eq("purchase_id", id) .and(item->{ item.eq("status",0).or().eq("status",1); } ); return this.list(queryWrapper); } }
14.7 API:模拟完成采购单⚠️
14.7.1 效果
采购完成前
模拟采购
采购完成后
14.7.2 商品服务开发
-
SkuInfoController.java:用于仓库服务远程调用查询商品名称
@RestController @RequestMapping("product/skuinfo") public class SkuInfoController { @Autowired private SkuInfoService skuInfoService; /** * 信息:将用于仓库服务远程调用查询商品名称 */ @RequestMapping("/info/{skuId}") public R info(@PathVariable("skuId") Long skuId){ SkuInfoEntity skuInfo = skuInfoService.getById(skuId); return R.ok().put("skuInfo", skuInfo); } }
14.7.3 库存服务开发
-
创建接收数据的采购单VO:cn/lzwei/bilimall/ware/vo/PurchaseDoneVo.java
@Data public class PurchaseDoneVo { //采购单id @NotNull private Long id; //采购需求列表完成状况 private List<PurchaseDetailsDoneVo> items; }
-
创建接收数据的采购需求VO:cn/lzwei/bilimall/ware/vo/PurchaseDetailsDoneVo.java
@Data public class PurchaseDetailsDoneVo { //采购需求id private Long itemId; //采购需求状态 private Integer status; //失败原因 private String reason; }
-
创建远程调用商品服务的接口:cn/lzwei/bilimall/ware/feign/ProductFeignService.java
@FeignClient(name = "bilimall-product") public interface ProductFeignService { //获取商品服务的sku信息 @RequestMapping("/product/skuinfo/info/{skuId}") R info(@PathVariable("skuId") Long skuId); }
-
PurchaseController:模拟完成采购:更新采购需求的状态 ——> 更新采购单状态 ——> 添加库存
@RestController @RequestMapping("ware/purchase") public class PurchaseController { @Autowired private PurchaseService purchaseService; /** * 模拟完成采购:更新采购需求的状态 ——> 更新采购单状态 ——> 添加库存 */ @PostMapping("/done") public R done(@Valid @RequestBody PurchaseDoneVo purchaseDoneVo){ purchaseService.done(purchaseDoneVo); return R.ok(); } }
-
PurchaseService:模拟完成采购:更新采购需求的状态 ——> 更新采购单状态 ——> 添加库存
public interface PurchaseService extends IService<PurchaseEntity> { /** * 模拟完成采购:更新采购需求的状态 ——> 更新采购单状态 ——> 添加库存 */ void done(PurchaseDoneVo purchaseDoneVo); }
-
PurchaseServiceImpl:模拟完成采购:更新采购需求的状态 ——> 更新采购单状态 ——> 添加库存
@Service("purchaseService") public class PurchaseServiceImpl extends ServiceImpl<PurchaseDao, PurchaseEntity> implements PurchaseService { @Resource PurchaseDetailService purchaseDetailService; @Resource WareSkuService wareSkuService; @Resource ProductFeignService productFeignService; /** * 模拟完成采购:更新采购需求的状态 ——> 更新采购单状态 ——> 添加库存 */ @Transactional @Override public void done(PurchaseDoneVo purchaseDoneVo) { //此采购单状态为新建、已分配、已领取时才可被完成 Long PurchaseId = purchaseDoneVo.getId(); PurchaseEntity purchase = this.getById(PurchaseId); Integer purchaseCanDone = purchase.getStatus(); if(purchaseCanDone==WareConstant.PurchaseType.CREATE.getCode() || purchaseCanDone==WareConstant.PurchaseType.ASSIGNED.getCode() || purchaseCanDone==WareConstant.PurchaseType.RECEIVED.getCode()){ //标志位:用于判断采购单状态 boolean purchaseStatus=true; //遍历采购需求列表 List<PurchaseDetailsDoneVo> items = purchaseDoneVo.getItems(); for (PurchaseDetailsDoneVo item : items) { //采购需求状态为新建、已分配、正在采购时才可被完成 Long itemId = item.getItemId(); PurchaseDetailEntity purchaseDetailEntity = purchaseDetailService.getById(itemId); Integer purchaseDetailCanDone = purchaseDetailEntity.getStatus(); if(purchaseDetailCanDone==WareConstant.PurchaseDetailType.CREATE.getCode() || purchaseDetailCanDone==WareConstant.PurchaseDetailType.ASSIGNED.getCode() || purchaseDetailCanDone==WareConstant.PurchaseDetailType.BUYING.getCode()){ //1.更新采购需求状态 Integer status = item.getStatus(); purchaseDetailEntity.setStatus(status); purchaseDetailService.updateById(purchaseDetailEntity); if(status==4){ //采购失败 purchaseStatus=false; }else{ //采购完成 //2.添加或者修改采购完成的商品库存:需要skuid、仓库id、库存、sku名字(调用远程服务) Long skuId = purchaseDetailEntity.getSkuId(); Long wareId = purchaseDetailEntity.getWareId(); Integer skuNum = purchaseDetailEntity.getSkuNum(); Map<String,Object> skuInfo = (Map<String, Object>) productFeignService.info(skuId).get("skuInfo"); String skuName= (String) skuInfo.get("skuName"); wareSkuService.addWare(skuId,wareId,skuNum,skuName); } } } //3.根据采购需求列表的状态更新采购单状态 PurchaseEntity purchaseEntity = new PurchaseEntity(); purchaseEntity.setId(PurchaseId); purchaseEntity.setStatus(purchaseStatus?WareConstant.PurchaseType.FINISHED.getCode():WareConstant.PurchaseType.HASEXECPTION.getCode()); purchaseEntity.setUpdateTime(new Date()); this.updateById(purchaseEntity); } } }
-
WareSkuService:添加或者修改采购完成的商品库存
public interface WareSkuService extends IService<WareSkuEntity> { /** * 添加或者修改采购完成的商品库存:需要skuid、仓库id、库存、sku名字(调用远程服务) */ void addWare(Long skuId, Long wareId, Integer skuNum, String skuName); }
-
WareSkuServiceImpl:添加或者修改采购完成的商品库存
@Service("wareSkuService") public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService { /** * 添加或者修改采购完成的商品库存:需要skuid、仓库id、库存、sku名字(调用远程服务) */ @Override public void addWare(Long skuId, Long wareId, Integer skuNum, String skuName) { //判断仓库是否存在该商品记录 QueryWrapper<WareSkuEntity> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("sku_id",skuId).eq("ware_id",wareId); List<WareSkuEntity> list = this.list(queryWrapper); if(list==null || list.size()==0){ //1.新增:不存在库存记录 WareSkuEntity wareSkuEntity = new WareSkuEntity(); wareSkuEntity.setSkuId(skuId); wareSkuEntity.setWareId(wareId); wareSkuEntity.setStock(skuNum); wareSkuEntity.setSkuName(skuName); this.save(wareSkuEntity); }else{ //2.修改:存在库存记录 baseMapper.updateSkuStock(skuId,wareId,skuNum); } } }
-
WareSkuDao.java:完成采购单,商品存在库存记录时更新库存
@Mapper public interface WareSkuDao extends BaseMapper<WareSkuEntity> { void updateSkuStock(@Param(value = "skuId") Long skuId,@Param(value = "wareId") Long wareId,@Param(value = "skuNum") Integer skuNum); }
-
WareSkuDao.xml:完成采购单,商品存在库存记录时更新库存
<mapper namespace="cn.lzwei.bilimall.ware.dao.WareSkuDao"> <update id="updateSkuStock"> UPDATE `wms_ware_sku` SET stock=stock+#{skuNum} WHERE sku_id=#{skuId} AND ware_id=#{wareId} </update> </mapper>