谷粒商城笔记合集
十四、仓储服务&仓库维护⚠️
14.1 后端开发:整合仓储服务⚠️
-
修改 网关服务 的路由配置并重启:application.yaml
spring:cloud:gateway:routes:- id: ware_routeuri: lb://bilimall-warepredicates:- Path=/api/ware/**filters:- RewritePath=/api/?(?<segment>.*),/$\{segment}
-
修改 仓储服务 的配置文件:注册中心、配置中心、服务名、Mybatis等
spring:datasource:username: rootpassword: bilimallurl: jdbc:mysql://114.132.162.129:3306/bilimall_wms?useUnicode=true&characterEncoding=utf-8&useSSL=falsedriver-class-name: com.mysql.cj.jdbc.Drivercloud:nacos:discovery:server-addr: 114.132.162.129:8848application:name: bilimall-warejackson:date-format: yyyy-MM-dd HH:mm:ss mybatis-plus:# mapper文件扫描:不仅扫描我的类路径,还包括依赖的其他类路径mapper-locations: classpath*:/mapper/**/*.xmlglobal-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 {@Autowiredprivate 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 {@Overridepublic 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 {@Autowiredprivate 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 {/*** 查询商品库存列表:仓库、指定商品*/@Overridepublic 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 {@Autowiredprivate 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 {/*** 查询采购需求列表:模糊查询、状态、指定仓库*/@Overridepublic 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 {@Autowiredprivate 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 {@Autowiredprivate 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 {/*** 获取采购单列表:状态为 新建、已分配*/@Overridepublic 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 {//采购单idprivate Long purchaseId;//采购需求列表private List<Long> items; }
-
PurchaseController:合并采购需求
@RestController @RequestMapping("ware/purchase") public class PurchaseController {@Autowiredprivate 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 {@ResourcePurchaseDetailService purchaseDetailService;/*** 合并采购需求:1.指定采购单,更新对应的采购需求以及采购单信息;2.无指定采购单,创建采购单并更新采购需求以及采购单信息*/@Transactional@Overridepublic 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 {@Autowiredprivate 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 {@ResourcePurchaseDetailService purchaseDetailService;/*** 模拟领取采购单:需要验证采购单、采购需求的状态*/@Transactional@Overridepublic 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 {/*** 获取采购单下新建或已分配状态的采购需求:用于领取采购单*/@Overridepublic 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 {@Autowiredprivate 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@NotNullprivate Long id;//采购需求列表完成状况private List<PurchaseDetailsDoneVo> items; }
-
创建接收数据的采购需求VO:cn/lzwei/bilimall/ware/vo/PurchaseDetailsDoneVo.java
@Data public class PurchaseDetailsDoneVo {//采购需求idprivate 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 {@Autowiredprivate 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 {@ResourcePurchaseDetailService purchaseDetailService;@ResourceWareSkuService wareSkuService;@ResourceProductFeignService productFeignService;/*** 模拟完成采购:更新采购需求的状态 ——> 更新采购单状态 ——> 添加库存*/@Transactional@Overridepublic 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名字(调用远程服务)*/@Overridepublic 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>