导航:
Java笔记汇总:
目录
仓库管理
0、预览
商家先在采购需求界面新增需求,新增时查询了商品、仓库等列表便于选择,然后根据需求新增采购单,采购完毕后将采购单和采购需求的状态字段设为“已完成”对应字典库的代码。
“仓库维护”界面展示仓库的名字、地址,“商品库存”界面展示sku和库存的关系,每个sku所在的每个仓库、以及该仓库下sku数量。
采购单维护-采购需求:
采购单维护-采购单:
仓库维护:
库存工作单:
商品库存:
1、数据表的说明
gulimall_wms数据库
表wms_ware_info
,表示仓库信息
表wms_ware_sku
,绑定仓库id和sku_id的关系
2、整合仓库服务
1、要整合仓库服务,首先把仓库服务注册到nacos中
2、配置网关
- id: ware_route uri: lb://gulimall-ware predicates: - Path=/api/ware/** filters: - RewritePath=/api/(?<segment>.*),/$\{segment}
3、配置后测试仓库维护
4、实现仓库模糊查询功能
点击查询,查看url
http://localhost:88/api/ware/wareinfo/list?t=1633696575331&page=1&limit=10&key=
WareInfoController.java
@RequestMapping("/list") //@RequiresPermissions("ware:wareinfo:list") public R list(@RequestParam Map<String, Object> params){ PageUtils page = wareInfoService.queryPageByCondition(params); return R.ok().put("page", page); }
WareInfoServiceImpl.java
@Override public PageUtils queryPageByCondition(Map<String, Object> params) { QueryWrapper<WareInfoEntity> wrapper = new QueryWrapper<>(); String key = (String) params.get("key"); if (!StringUtils.isNullOrEmpty(key)){ wrapper.eq("id", key).or().like("name", key).or().like("address", key).or().like("areacode", key); } IPage<WareInfoEntity> page = this.page( new Query<WareInfoEntity>().getPage(params), wrapper ); return new PageUtils(page); }
设置日志输出级别,方便查看sql语句
logging: level: com.xmh: debug
测试成功
3、查询库存的模糊查询
1、库存系统02,url:/ware/waresku/list
2、实现库存模糊查询功能,WareSkuServiceImpl.java
@Override public PageUtils queryPage(Map<String, Object> params) { QueryWrapper<WareSkuEntity> wrapper = new QueryWrapper<>(); String wareId = (String) params.get("wareId"); if (!StringUtils.isNullOrEmpty(wareId)){ wrapper.eq("ware_id", wareId); } String skuId = (String) params.get("skuId"); if (!StringUtils.isNullOrEmpty(skuId)){ wrapper.eq("sku_id", skuId); } IPage<WareSkuEntity> page = this.page( new Query<WareSkuEntity>().getPage(params), wrapper ); return new PageUtils(page); }
4、采购需求的模糊查询
1、库存系统03,url:/ware/purchasedetail/list
2、PurchaseDetailServiceImpl.java
@Override public PageUtils queryPage(Map<String, Object> params) { QueryWrapper<PurchaseDetailEntity> wrapper = new QueryWrapper<>(); String key = (String) params.get("key"); if (!StringUtils.isNullOrEmpty(key)){ wrapper.and(w -> { w.eq("sku_id", key).or().eq("purchase_id", key); }); } String status = (String) params.get("status"); if (!StringUtils.isNullOrEmpty(status)){ wrapper.eq("status", status); } String wareId = (String) params.get("wareId"); if (!StringUtils.isNullOrEmpty(wareId)){ wrapper.eq("ware_id", wareId); } IPage<PurchaseDetailEntity> page = this.page( new Query<PurchaseDetailEntity>().getPage(params), wrapper ); return new PageUtils(page); }
5、合并采购流程
1、采购逻辑,新建采购需求后还要可以提供合并采购单,比如一个仓库的东西可以合并到一起,让采购人员一趟采购完
新建采购需求后还要可以提供合并采购单,比如一个仓库的东西可以合并到一起,让采购人员一趟采购完
新建采购单,可以在采购单后面分配给员工,员工可以在系统管理->管理员列表中新建
6、查询未领取的采购单
1、库存系统05、url:/ware/purchase/unreceive/list
, 查询未领取的采购单
2、PurchaseController.java
@RequestMapping("/unreceive/list") //@RequiresPermissions("ware:purchase:list") public R unreceiveList(@RequestParam Map<String, Object> params){ PageUtils page = purchaseService.queryPageUnreceive(params); return R.ok().put("page", page); }
3、新建常量枚举类constant.WareConstant
public class WareConstant { /** 采购单状态枚举 */ public enum PurchaseStatusEnum{ CREATED(0,"新建"),ASSIGNED(1,"已分配"), RECEIVE(2,"已领取"),FINISH(3,"已完成"), HASERROR(4,"有异常"); private int code; private String msg; PurchaseStatusEnum(int code, String msg){ this.code = code; this.msg = msg; } public int getCode(){ return code; } public String getMsg(){ return msg; } } /** 采购需求枚举 */ public enum PurchaseDetailStatusEnum{ CREATED(0,"新建"),ASSIGNED(1,"已分配"), BUYING(2,"正在采购"),FINISH(3,"已完成"), HASERROR(4,"采购失败"); private int code; private String msg; PurchaseDetailStatusEnum(int code,String msg){ this.code = code; this.msg = msg; } public int getCode() { return code; } public String getMsg() { return msg; } } }
4、queryPageUnreceive.java
@Override public PageUtils queryPageUnreceive(Map<String, Object> params) { QueryWrapper<PurchaseEntity> wrapper = new QueryWrapper<>(); wrapper.eq("status", WareConstant.PurchaseStatusEnum.CREATED.getCode()).or().eq("status", WareConstant.PurchaseStatusEnum.ASSIGNED.getCode()); IPage<PurchaseEntity> page = this.page( new Query<PurchaseEntity>().getPage(params), wrapper ); return new PageUtils(page); }
5、测试成功
7、合并采购需求
1、库存系统04,url:/ware/purchase/merge
选择要合并的采购需求,然后合并到整单
如果不选择整单id,则自动创建新的采购单
2、新建MergerVo.java
@Data public class MergerVo { private Long purchaseId; //整单id private List<Long> items; //合并项集合 }
3、分配,就是修改【采购需求】里对应的【采购单id、采购需求状态】,即purchase_detail表
并且不能重复分配采购需求给不同的采购单
,如果还没去采购,或者采购失败,就可以修改
PurchaseController.java
@PostMapping("/merge") //@RequiresPermissions("ware:purchase:list") public R merge(@RequestBody MergeVo mergeVo){ purchaseService.mergePurchase(mergeVo); return R.ok(); }
PurchaseServiceImpl.java
@Autowired private PurchaseDetailService detailService; @Transactional @Override public void mergePurchase(MergeVo mergeVo) { Long purchaseId = mergeVo.getPurchaseId(); // 如果采购id为null 说明没选采购单 if (purchaseId == null){ //新建采购单 PurchaseEntity purchaseEntity = new PurchaseEntity(); purchaseEntity.setStatus(WareConstant.PurchaseStatusEnum.CREATED.getCode()); this.save(purchaseEntity); purchaseId = purchaseEntity.getId(); } //合并采购需求 List<Long> items = mergeVo.getItems(); Long finalPurchaseId = purchaseId; List<PurchaseDetailEntity> list = detailService.getBaseMapper().selectBatchIds(items).stream().filter(entity -> { //如果还没去采购,或者采购失败,就可以修改 return entity.getStatus() < WareConstant.PurchaseDetailStatusEnum.BUYING.getCode() || entity.getStatus() == WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode(); }).map(entity -> { //修改状态,以及采购单id entity.setStatus(WareConstant.PurchaseDetailStatusEnum.ASSIGNED.getCode()); entity.setPurchaseId(finalPurchaseId); return entity; }).collect(Collectors.toList()); detailService.updateBatchById(list); }
对采购单的创建时间、更新时间进行自动填充
在PurchaseEntity
中添加注解
/** * 创建日期 */ @TableField(fill = FieldFill.INSERT) private Date createTime; /** * 更新日期 */ @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime;
新建MyMetaObjectHandler
对注解进行处理
@Slf4j @Component // 一定不要忘记把处理器加到IOC容器中! public class MyMetaObjectHandler implements MetaObjectHandler { // 插入时的填充策略 @Override public void insertFill(MetaObject metaObject) { log.info("start insert fill....."); // setFieldValByName(String fieldName, Object fieldVal, MetaObject this.setFieldValByName("createTime",new Date(),metaObject); this.setFieldValByName("updateTime",new Date(),metaObject); } // 更新时的填充策略 @Override public void updateFill(MetaObject metaObject) { log.info("start update fill....."); this.setFieldValByName("updateTime",new Date(),metaObject); } }
在配置文件中对时间json进行格式化
jackson: date-format: yyyy-MM-dd HH:mm:ss
测试成功
8、领取采购单
采购单分配给了采购人员,采购人员在手机端领取采购单,此时的采购单应该为新建
或已分配
状态,在采购人员领取后采购单
的状态变为已领取
,采购需求
的状态变为正在采购
1、库存系统06、url:/ware/purchase/received
2、PurchaseController.java
/** * 领取采购单/ware/purchase/received */ @PostMapping("/received") //@RequiresPermissions("ware:purchase:list") public R received(@RequestBody List<Long> ids){ purchaseService.received(ids); return R.ok(); }
3、PurchaseServiceImpl.java
@Transactional @Override public void received(List<Long> ids) { // 没有采购需求直接返回,否则会破坏采购单 if (ids == null || ids.size() == 0) { return; } List<PurchaseEntity> list = this.getBaseMapper().selectBatchIds(ids).stream().filter(entity -> { //确保采购单的状态是新建或者已分配 return entity.getStatus() <= WareConstant.PurchaseStatusEnum.ASSIGNED.getCode(); }).map(entity -> { //修改采购单的状态为已领取 entity.setStatus(WareConstant.PurchaseStatusEnum.RECEIVE.getCode()); return entity; }).collect(Collectors.toList()); this.updateBatchById(list); //修改该采购单下的所有采购需求的状态为正在采购 UpdateWrapper<PurchaseDetailEntity> updateWrapper = new UpdateWrapper<>(); updateWrapper.in("purchase_id", ids); PurchaseDetailEntity purchaseDetailEntity = new PurchaseDetailEntity(); purchaseDetailEntity.setStatus(WareConstant.PurchaseDetailStatusEnum.BUYING.getCode()); detailService.update(purchaseDetailEntity, updateWrapper); }
4、用idea自带的HTTP Client发送post请求,模拟采购人员领取采购单,进行测试
POST http://localhost:88/api//ware/purchase/received Content-Type: application/json [3]
5、测试成功
9、完成采购
完成采购的步骤:
- 判断所有采购需求的状态,采购需求全部完成时,采购单状态才为完成
- 采购项完成的时候,增加库存(调用远程获取skuName)
- 加上分页插件
1、库存系统07,url:/ware/purchase/done
2、新建PurchaseItemDoneVo
,PurchaseDoneVo
@Data public class PurchaseItemDoneVo { private Long itemId; private Integer status; private String reason; }
@Data public class PurchaseDoneVo { private Long id; private List<PurchaseItemDoneVo> items; }
3、PurchaseController.java
/** * 完成采购 */ @PostMapping("/done") //@RequiresPermissions("ware:purchase:list") public R received(@RequestBody PurchaseDoneVo vo){ purchaseService.done(vo); return R.ok(); }
4、PurchaseServiceImpl.java
@Autowired private WareSkuService wareSkuService; @Autowired private ProductFeignService productFeignService; @Override public void done(PurchaseDoneVo vo) { //1、根据前端发过来的信息,更新采购需求的状态 List<PurchaseItemDoneVo> items = vo.getItems(); List<PurchaseDetailEntity> updateList = new ArrayList<>(); boolean flag = true; for (PurchaseItemDoneVo item : items){ Long detailId = item.getItemId(); PurchaseDetailEntity detailEntity = detailService.getById(detailId); detailEntity.setStatus(item.getStatus()); //采购需求失败 if (item.getStatus() == WareConstant.PurchaseDetailStatusEnum.HASERROR.getCode()){ flag = false; }else { //3、根据采购需求的状态,更新库存 // sku_id, sku_num, ware_id // sku_id, ware_id, stock sku_name(调用远程服务获取), stock_locked(先获取已经有的库存,再加上新购买的数量) String skuName = ""; try { R info = productFeignService.info(detailEntity.getSkuId()); if(info.getCode() == 0){ Map<String,Object> data=(Map<String,Object>)info.get("skuInfo"); skuName = (String) data.get("skuName"); } } catch (Exception e) { } //更新库存 wareSkuService.addStock(detailEntity.getSkuId(), detailEntity.getWareId(), skuName, detailEntity.getSkuNum()); } updateList.add(detailEntity); } //保存采购需求 detailService.updateBatchById(updateList); //2、根据采购需求的状态,更新采购单的状态 PurchaseEntity purchaseEntity = new PurchaseEntity(); purchaseEntity.setId(vo.getId()); purchaseEntity.setStatus(flag ? WareConstant.PurchaseStatusEnum.FINISH.getCode() : WareConstant.PurchaseStatusEnum.HASERROR.getCode()); this.updateById(purchaseEntity); }
5、新建feign.ProductFeignService
接口,用来远程获取skuName
ProductFeignService.java
@FeignClient("gulimall-product") public interface ProductFeignService { @RequestMapping("/product/skuinfo/info/{skuId}") R info(@PathVariable("skuId") Long skuId); }
6、主启动类加上注解@EnableFeignClients
7、WareSkuServiceImpl.java
实现入库操作
@Override public void addStock(Long skuId, Long wareId, String skuName, Integer skuNum) { WareSkuEntity wareSkuEntity = this.baseMapper.selectOne(new QueryWrapper<WareSkuEntity>().eq("sku_id", skuId).eq("ware_id", wareId)); if (wareSkuEntity == null){ //新增 wareSkuEntity = new WareSkuEntity(); wareSkuEntity.setStock(skuNum); }else { wareSkuEntity.setStock(wareSkuEntity.getStock() + skuNum); } wareSkuEntity.setSkuName(skuName); wareSkuEntity.setWareId(wareId); wareSkuEntity.setSkuId(skuId); this.saveOrUpdate(wareSkuEntity); }
8、添加分页插件,复制product服务中的即可
9、测试
POST http://localhost:88/api/ware/purchase/done Content-Type: application/json { "id": 7, "items": [ {"itemId":6,"status":3,"reason":"完成"}, {"itemId":7,"status":3,"reason":"完成"} ] }
测试成功
10、获取spu规格
1、商品系统22、url:/product/attr/base/listforspu/{spuId}
2、AttrController.java
@Autowired private ProductAttrValueService productAttrValueService; @GetMapping("/base/listforspu/{spuId}") public R baseListforspu(@PathVariable("spuId") Long spuId){ List<ProductAttrValueEntity> entityList = productAttrValueService.baseAttrlistForSpu(spuId); return R.ok().put("data", entityList); }
3、ProductAttrValueServiceImpl.java
@Override public List<ProductAttrValueEntity> baseAttrlistForSpu(Long spuId) { List<ProductAttrValueEntity> entities = this.baseMapper.selectList(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId)); return entities; }
测试,点击规格
如果此时出现400页面,向gulimall_admin中的sys_menu表中添加一条数据即可
11、修改商品规格
1、商品系统23,url:/product/attr/update/{spuId}
2、AttrController.java
@PostMapping("/update/{spuId}") public R updateSpuAttr(@PathVariable("spuId") Long spuId, @RequestBody List<ProductAttrValueEntity> entities){ productAttrValueService.updateSpuAttr(spuId, entities); return R.ok(); }
3、ProductAttrValueServiceImpl.java
因为修改的时候,有新增有修改有删除。 所以就先把spuId对应的所有属性都删了,再新增
@Override public void updateSpuAttr(Long spuId, List<ProductAttrValueEntity> entities) { //1、删除这个spuId对应的所有属性 this.baseMapper.delete(new QueryWrapper<ProductAttrValueEntity>().eq("spu_id", spuId)); //2、新增回去 for (ProductAttrValueEntity entity : entities){ entity.setSpuId(spuId); } this.saveBatch(entities); }