谷粒商城笔记+踩坑(8)——仓库管理

导航:

谷粒商城笔记+踩坑汇总篇

目录

仓库管理

0、预览

1、数据表的说明

2、整合仓库服务

3、查询库存的模糊查询

4、采购需求的模糊查询

5、合并采购流程

6、查询未领取的采购单

7、合并采购需求

8、领取采购单

9、完成采购

10、获取spu规格

11、修改商品规格


仓库管理

0、预览

商家先在采购需求界面新增需求,新增时查询了商品、仓库等列表便于选择,然后根据需求新增采购单,采购完毕后将采购单和采购需求的状态字段设为“已完成”对应字典库的代码。

“仓库维护”界面展示仓库的名字、地址,“商品库存”界面展示sku和库存的关系,每个sku所在的每个仓库、以及该仓库下sku数量。

采购单维护-采购需求: 

采购单维护-采购单:  

仓库维护:

库存工作单:

商品库存:

1、数据表的说明

gulimall_wms数据库 

表wms_ware_info,表示仓库信息

image-20211008202953452

wms_ware_sku,绑定仓库id和sku_id的关系

2、整合仓库服务

1、要整合仓库服务,首先把仓库服务注册到nacos中

image-20211008203205685

2、配置网关

        - id: ware_route
          uri: lb://gulimall-ware
          predicates:
            - Path=/api/ware/**
          filters:
            - RewritePath=/api/(?<segment>.*),/$\{segment}

3、配置后测试仓库维护

image-20211008203531424

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

测试成功

image-20211008205923395

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、采购逻辑,新建采购需求后还要可以提供合并采购单,比如一个仓库的东西可以合并到一起,让采购人员一趟采购完

image-20211009140714639

新建采购需求后还要可以提供合并采购单,比如一个仓库的东西可以合并到一起,让采购人员一趟采购完

image-20211009142628012

新建采购单,可以在采购单后面分配给员工,员工可以在系统管理->管理员列表中新建

image-20211009142748552

6、查询未领取的采购单

1、库存系统05、url:/ware/purchase/unreceive/list, 查询未领取的采购单

image-20211009142933952

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、测试成功

image-20211009143734631

7、合并采购需求

1、库存系统04,url:/ware/purchase/merge

选择要合并的采购需求,然后合并到整单

image-20211009143734631

如果不选择整单id,则自动创建新的采购单

image-20211009144346072

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

测试成功

image-20211009153458666

image-20211009153506973

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、测试成功

image-20211009162502907

image-20211009162110249

image-20211009162117863

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":"完成"}
  ]
}

测试成功

image-20211009211738771

image-20211009211746310

image-20211009211756285

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;
}

测试,点击规格

image-20211010021657735

如果此时出现400页面,向gulimall_admin中的sys_menu表中添加一条数据即可

image-20211010021800755

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);
    }

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小海绵【vincewm】

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值